mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-13 02:53:38 +00:00
191 lines
6.8 KiB
Python
191 lines
6.8 KiB
Python
import collections
|
|
import datetime
|
|
import hashlib
|
|
import logging
|
|
import os
|
|
|
|
import mkdocs.structure.nav
|
|
|
|
import util
|
|
|
|
|
|
def find_first_header(content):
|
|
for line in content.split("\n"):
|
|
if line.startswith("#"):
|
|
no_hash = line.lstrip("#")
|
|
return no_hash.split("{", 1)[0].strip()
|
|
|
|
|
|
def build_nav_entry(root, args):
|
|
if root.endswith("images"):
|
|
return None, None, None
|
|
result_items = []
|
|
index_meta, index_content = util.read_md_file(os.path.join(root, "index.md"))
|
|
current_title = index_meta.get("toc_folder_title", index_meta.get("toc_title"))
|
|
current_title = current_title or index_meta.get(
|
|
"title", find_first_header(index_content)
|
|
)
|
|
for filename in os.listdir(root):
|
|
path = os.path.join(root, filename)
|
|
if os.path.isdir(path):
|
|
prio, title, payload = build_nav_entry(path, args)
|
|
if title and payload:
|
|
result_items.append((prio, title, payload))
|
|
elif filename.endswith(".md"):
|
|
path = os.path.join(root, filename)
|
|
|
|
meta = ""
|
|
content = ""
|
|
|
|
try:
|
|
meta, content = util.read_md_file(path)
|
|
except:
|
|
print("Error in file: {}".format(path))
|
|
raise
|
|
|
|
path = path.split("/", 2)[-1]
|
|
title = meta.get("toc_title", find_first_header(content))
|
|
if title:
|
|
title = title.strip().rstrip(".")
|
|
else:
|
|
title = meta.get("toc_folder_title", "hidden")
|
|
prio = meta.get("toc_priority", 9999)
|
|
logging.debug(f"Nav entry: {prio}, {title}, {path}")
|
|
if meta.get("toc_hidden") or not content.strip():
|
|
title = "hidden"
|
|
if title == "hidden":
|
|
title = "hidden-" + hashlib.sha1(content.encode("utf-8")).hexdigest()
|
|
if args.nav_limit and len(result_items) >= args.nav_limit:
|
|
break
|
|
result_items.append((prio, title, path))
|
|
result_items = sorted(result_items, key=lambda x: (x[0], x[1]))
|
|
result = collections.OrderedDict([(item[1], item[2]) for item in result_items])
|
|
if index_meta.get("toc_hidden_folder"):
|
|
current_title += "|hidden-folder"
|
|
return index_meta.get("toc_priority", 10000), current_title, result
|
|
|
|
|
|
def build_docs_nav(lang, args):
|
|
docs_dir = os.path.join(args.docs_dir, lang)
|
|
_, _, nav = build_nav_entry(docs_dir, args)
|
|
result = []
|
|
index_key = None
|
|
for key, value in list(nav.items()):
|
|
if key and value:
|
|
if value == "index.md":
|
|
index_key = key
|
|
continue
|
|
result.append({key: value})
|
|
if args.nav_limit and len(result) >= args.nav_limit:
|
|
break
|
|
if index_key:
|
|
key = list(result[0].keys())[0]
|
|
result[0][key][index_key] = "index.md"
|
|
result[0][key].move_to_end(index_key, last=False)
|
|
return result
|
|
|
|
|
|
def build_blog_nav(lang, args):
|
|
blog_dir = os.path.join(args.blog_dir, lang)
|
|
years = sorted(os.listdir(blog_dir), reverse=True)
|
|
result_nav = [{"hidden": "index.md"}]
|
|
post_meta = collections.OrderedDict()
|
|
for year in years:
|
|
year_dir = os.path.join(blog_dir, year)
|
|
if not os.path.isdir(year_dir):
|
|
continue
|
|
result_nav.append({year: collections.OrderedDict()})
|
|
posts = []
|
|
post_meta_items = []
|
|
for post in os.listdir(year_dir):
|
|
post_path = os.path.join(year_dir, post)
|
|
if not post.endswith(".md"):
|
|
raise RuntimeError(
|
|
f"Unexpected non-md file in posts folder: {post_path}"
|
|
)
|
|
meta, _ = util.read_md_file(post_path)
|
|
post_date = meta["date"]
|
|
post_title = meta["title"]
|
|
if datetime.date.fromisoformat(post_date) > datetime.date.today():
|
|
continue
|
|
posts.append(
|
|
(
|
|
post_date,
|
|
post_title,
|
|
os.path.join(year, post),
|
|
)
|
|
)
|
|
if post_title in post_meta:
|
|
raise RuntimeError(f"Duplicate post title: {post_title}")
|
|
if not post_date.startswith(f"{year}-"):
|
|
raise RuntimeError(
|
|
f"Post date {post_date} doesn't match the folder year {year}: {post_title}"
|
|
)
|
|
post_url_part = post.replace(".md", "")
|
|
post_meta_items.append(
|
|
(
|
|
post_date,
|
|
{
|
|
"date": post_date,
|
|
"title": post_title,
|
|
"image": meta.get("image"),
|
|
"url": f"/blog/{lang}/{year}/{post_url_part}/",
|
|
},
|
|
)
|
|
)
|
|
for _, title, path in sorted(posts, reverse=True):
|
|
result_nav[-1][year][title] = path
|
|
for _, post_meta_item in sorted(
|
|
post_meta_items, reverse=True, key=lambda item: item[0]
|
|
):
|
|
post_meta[post_meta_item["title"]] = post_meta_item
|
|
return result_nav, post_meta
|
|
|
|
|
|
def _custom_get_navigation(files, config):
|
|
nav_config = config["nav"] or mkdocs.structure.nav.nest_paths(
|
|
f.src_path for f in files.documentation_pages()
|
|
)
|
|
items = mkdocs.structure.nav._data_to_navigation(nav_config, files, config)
|
|
if not isinstance(items, list):
|
|
items = [items]
|
|
|
|
pages = mkdocs.structure.nav._get_by_type(items, mkdocs.structure.nav.Page)
|
|
|
|
mkdocs.structure.nav._add_previous_and_next_links(pages)
|
|
mkdocs.structure.nav._add_parent_links(items)
|
|
|
|
missing_from_config = [
|
|
file for file in files.documentation_pages() if file.page is None
|
|
]
|
|
if missing_from_config:
|
|
files._files = [
|
|
file for file in files._files if file not in missing_from_config
|
|
]
|
|
|
|
links = mkdocs.structure.nav._get_by_type(items, mkdocs.structure.nav.Link)
|
|
for link in links:
|
|
scheme, netloc, path, params, query, fragment = mkdocs.structure.nav.urlparse(
|
|
link.url
|
|
)
|
|
if scheme or netloc:
|
|
mkdocs.structure.nav.log.debug(
|
|
"An external link to '{}' is included in "
|
|
"the 'nav' configuration.".format(link.url)
|
|
)
|
|
elif link.url.startswith("/"):
|
|
mkdocs.structure.nav.log.debug(
|
|
"An absolute path to '{}' is included in the 'nav' configuration, "
|
|
"which presumably points to an external resource.".format(link.url)
|
|
)
|
|
else:
|
|
msg = (
|
|
"A relative path to '{}' is included in the 'nav' configuration, "
|
|
"which is not found in the documentation files".format(link.url)
|
|
)
|
|
mkdocs.structure.nav.log.warning(msg)
|
|
return mkdocs.structure.nav.Navigation(items, pages)
|
|
|
|
|
|
mkdocs.structure.nav.get_navigation = _custom_get_navigation
|