diff --git a/pyproject.toml b/pyproject.toml
index 73e78b5..c269d8d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -11,6 +11,7 @@ dependencies = [
"mkdocstrings-python>=1.9.1",
"mkdocs-macros-plugin",
"mkdocs-site-urls",
+ "mkdocs-literate-nav",
"importlib_resources",
"httpx",
"rich",
diff --git a/src/pulp_docs/data/mkdocs.yml b/src/pulp_docs/data/mkdocs.yml
index 7bcdbbd..13e80aa 100644
--- a/src/pulp_docs/data/mkdocs.yml
+++ b/src/pulp_docs/data/mkdocs.yml
@@ -45,6 +45,8 @@ plugins:
module_name: '../mkdocs_macros'
- tags:
tags_file: pulp-docs/docs/tags.md
+ - literate-nav:
+ nav_file: _SUMMARY.md
- mkdocstrings:
handlers:
python:
diff --git a/src/pulp_docs/navigation.py b/src/pulp_docs/navigation.py
index c0b62c6..652adff 100644
--- a/src/pulp_docs/navigation.py
+++ b/src/pulp_docs/navigation.py
@@ -57,93 +57,31 @@ def grouped_by_persona(tmpdir: Path, repos: Repos):
{content-type}
"""
f = AgregationUtils(tmpdir, repos)
- usage_section = [
- {"Overview": f.section_file("user/index.md")},
- {
- "Pulpcore": [
- f.section(
- Names.PULPCORE_TUTORIAL,
- f.get_children,
- "pulpcore/docs/user/tutorials",
- ),
- f.section(Names.LEARN, f.get_children, "pulpcore/docs/user/learn"),
- f.section(Names.GUIDES, f.get_children, "pulpcore/docs/user/guides"),
- ]
- },
- {
- "Plugins": f.repo_grouping(
- "{repo}/docs/user/{content}", repo_types=["content"]
- )
- },
- {"Extras": f.repo_grouping("{repo}/docs/user/{content}", repo_types=["other"])},
- ]
- admin_section = [
- {"Overview": f.section_file("admin/index.md")},
- {
- "Pulpcore": [
- f.section(
- Names.PULPCORE_TUTORIAL,
- f.get_children,
- "pulpcore/docs/admin/tutorials",
- ),
- f.section(Names.LEARN, f.get_children, "pulpcore/docs/admin/learn"),
- f.section(Names.GUIDES, f.get_children, "pulpcore/docs/admin/guides"),
- ]
- },
- f.section(
- "Plugins",
- f.repo_grouping,
- "{repo}/docs/admin/{content}",
- repo_types=["content"],
- hide_empty_section=False,
- ),
- f.section(
- "Extras",
- f.repo_grouping,
- "{repo}/docs/admin/{content}",
- repo_types=["other"],
- hide_empty_section=False,
- ),
- ]
- development_section = [
- {"Overview": f.section_file("dev/index.md")},
- {
- "Pulpcore": [
- f.section(
- Names.PULPCORE_TUTORIAL,
- f.get_children,
- "pulpcore/docs/dev/tutorials",
- ),
- f.section(Names.LEARN, f.get_children, "pulpcore/docs/dev/learn"),
- f.section(Names.GUIDES, f.get_children, "pulpcore/docs/dev/guides"),
- ]
- },
- {
- "Plugins": f.repo_grouping(
- "{repo}/docs/dev/{content}", repo_types=["content"]
- )
- },
- {"Extras": f.repo_grouping("{repo}/docs/dev/{content}", repo_types=["other"])},
- ]
+ SECTION_HOST = "pulp-docs"
+ CHANGES_PATH = "{repo}/changes/changelog.md"
+
+ # Manual section for each persona
+ manual_nav = {}
+ for section in ("user", "admin", "dev"):
+ TEMPLATE_STRING = "{repo}/docs/%s/{content}" % section
+ section_nav = [
+ {"Overview": f"{SECTION_HOST}/docs/sections/{section}/index.md"},
+ {"Core": f.repo_grouping(TEMPLATE_STRING, repo_types=["core"])},
+ {"Plugins": f.repo_grouping(TEMPLATE_STRING, repo_types=["content"])},
+ {"Extras": f.repo_grouping(TEMPLATE_STRING, repo_types=["other"])},
+ ]
+ manual_nav[section] = section_nav
+
+ # Custom help section
help_section = [
- {"Overview": f.section_file("help/index.md")},
- {"Community": f.get_children("pulp-docs/docs/sections/help/community")},
- {"More": f.get_children("pulp-docs/docs/sections/help/more")},
+ {"Overview": f"{SECTION_HOST}/docs/sections/help/index.md"},
+ {"Community": f"{SECTION_HOST}/docs/sections/help/community/"},
+ {"More": f"{SECTION_HOST}/docs/sections/help/more/"},
{
"Changelogs": [
- {"Pulpcore": "pulpcore/changes/changelog.md"},
- {
- "Plugins": sorted(
- f.repo_grouping(
- "{repo}/changes", repo_types=["content"]
- ).items()
- )
- },
- {
- "Extra": sorted(
- f.repo_grouping("{repo}/changes", repo_types=["other"]).items()
- )
- },
+ {"Core": f.changes_grouping(CHANGES_PATH, repo_types=["core"])},
+ {"Plugins": f.changes_grouping(CHANGES_PATH, repo_types=["content"])},
+ {"Extra": f.changes_grouping(CHANGES_PATH, repo_types=["other"])},
]
},
]
@@ -151,9 +89,9 @@ def grouped_by_persona(tmpdir: Path, repos: Repos):
# Main Section
navigation = [
{"Home": "index.md"},
- {"User Manual": usage_section},
- {"Admin Manual": admin_section},
- {"Developer Manual": development_section},
+ {"User Manual": manual_nav["user"]},
+ {"Admin Manual": manual_nav["admin"]},
+ {"Developer Manual": manual_nav["dev"]},
{"Help": help_section},
]
return navigation
diff --git a/src/pulp_docs/utils/aggregation.py b/src/pulp_docs/utils/aggregation.py
index c9f8f4c..2d30bfa 100644
--- a/src/pulp_docs/utils/aggregation.py
+++ b/src/pulp_docs/utils/aggregation.py
@@ -27,33 +27,6 @@ def section(self, name: str, fn: t.Callable, *args, **kwargs) -> dict:
return {name: section}
return {name: section} if section else {"": ""}
- def get_children(self, path: t.Union[str, Path]) -> t.List[str]:
- """
- Get all markdown files contained in @path recursively.
-
- Uses the dirname.title() as the subsection name if there are subdirs.
- """
- basepath = self.tmpdir / path if isinstance(path, str) else path
- if not basepath.exists():
- return []
-
- def _get_tree(_path):
- """Recursive scandir"""
- with os.scandir(_path) as it:
- children = []
- for entry in sorted(it, key=lambda x: x.name):
- if entry.is_file() and entry.name.endswith(".md"):
- filename = str(Path(entry.path).relative_to(self.tmpdir))
- children.append(filename)
- elif entry.is_dir():
- dir_title = self.normalize_title(entry.name)
- sub_section = {dir_title: _get_tree(entry)}
- children.append(sub_section)
- return children
-
- result = _get_tree(basepath)
- return result
-
def normalize_title(self, raw_title: str):
return raw_title.replace("_", " ").title()
@@ -89,57 +62,80 @@ def repo_grouping(
}
```
"""
- _nav = {}
- _expand_content_types = "{content}" in template_str
- # Selected a set of repos
- selected_repos = []
selected_content = content_types or [
"tutorials",
"guides",
"learn",
"reference",
]
- if not repo_types: # default case
- selected_repos = self.repos.all
- else:
- selected_repos.extend(self.repos.get_repos(repo_types=repo_types))
-
- # Dont expand content-types
- if not _expand_content_types:
- for repo in selected_repos:
- lookup_path = self._parse_template_str(template_str, repo.name)
- _repo_content = self.get_children(lookup_path)
+
+ selected_repos = self.repos.all
+ if repo_types:
+ selected_repos = self.repos.get_repos(repo_types=repo_types)
+
+ group_nav = []
+ for repo in selected_repos:
+ repo_nav = []
+ # Include index.md if present in staging_docs/{persona}/index.md
+ persona_basepath = self._parse_template_str(
+ template_str, repo.name, "placeholder"
+ ).parent
+ index_path = persona_basepath / "index.md"
+ if index_path.exists():
+ repo_nav.append({"Overview": str(index_path.relative_to(self.tmpdir))})
+
+ for content_type in selected_content:
+ # Get repo files from content-type and persona
+ lookup_path = self._parse_template_str(
+ template_str, repo.name, content_type
+ )
+ _repo_content = self._add_literate_nav_dir(lookup_path)
+
+ # Prevent rendering content-type section if there are no files
if _repo_content:
- _nav[repo.title] = (
- _repo_content if len(_repo_content) > 1 else _repo_content[0]
- )
- # Expand content-types
- else:
- for repo in selected_repos:
- repo_nav = {}
- # Include index.md if present in staging_docs/{persona}/index.md
- persona_basepath = self._parse_template_str(
- template_str, repo.name, "placeholder"
- ).parent
- index_path = persona_basepath / "index.md"
- if index_path.exists():
- repo_nav["Overview"] = str(index_path.relative_to(self.tmpdir))
-
- for content_type in selected_content:
- # Get repo files from content-type and persona
- lookup_path = self._parse_template_str(
- template_str, repo.name, content_type
- )
- _repo_content = self.get_children(lookup_path)
-
- # Prevent rendering content-type section if there are no files
- if _repo_content:
- content_type_name = Names.get(content_type)
- repo_nav[content_type_name] = _repo_content # type: ignore
- if repo_nav:
- _nav[repo.title] = repo_nav
- return _nav or ["#"]
+ content_type_title = Names.get(content_type)
+ repo_nav.append({content_type_title: _repo_content}) # type: ignore
+ if repo_nav:
+ group_nav.append({repo.title: repo_nav})
+ return group_nav or ["#"]
+
+ def changes_grouping(
+ self, changes_path_template: str, repo_types: t.Optional[t.List[str]] = None
+ ):
+ selected_repos = self.repos.all
+ if repo_types:
+ selected_repos = self.repos.get_repos(repo_types=repo_types)
+
+ group_nav = [
+ {repo.title: changes_path_template.format(repo=repo.name)}
+ for repo in selected_repos
+ ]
+ return group_nav or ["#"] # type: ignore
+
+ def _add_literate_nav_dir(self, lookup_path: Path) -> t.Optional[str]:
+ """
+ Take a path and return a path-str or None.
+
+ The path-str is expanded by mkdocs-literate-nav. E.g:
+
+ For "foo/bar/eggs/", it will:
+ 1. Try to find "foo/bar/eggs/_SUMMARY.md"
+ 2. If cant find, generate recursive nav for "foo/bar/eggs"
+
+ If the @lookup_path is non-existent, non-dir or doesnt contain .md, returns None.
+ """
+ if not lookup_path.exists():
+ return None
+
+ if not lookup_path.is_dir():
+ return None
+
+ if len(list(lookup_path.rglob("*.md"))) == 0:
+ return None
+
+ path_str = str(lookup_path.relative_to(self.tmpdir)) + "/"
+ return path_str
def _parse_template_str(
self, template_str: str, repo_name: str, content_type: t.Optional[str] = None
@@ -163,53 +159,3 @@ def _parse_template_str(
return self.tmpdir / template_str.format(**kwargs)
- def _pop_quickstart_from(self, pathlist: t.List[str]) -> t.Optional[str]:
- """Get quickstart.md file from filelist with case and variations tolerance"""
- for path in pathlist:
- if not isinstance(path, str):
- continue
-
- filename = path.split("/")[-1]
- if filename.lower() in ("quickstart.md", "quick-start.md"):
- pathlist.remove(path)
- return path
- return None
-
- def repo_reference_grouping(self):
- """
- Create reference section by aggregating some specific files.
-
- Group according to the pattern:
- {repo}/
- Readme.md
- Rest Api.md
- Code Api/
- Module A.md
- Module B.md
- Changelog.md
-
- """
- template_str = "{repo}/docs/reference"
- _nav = {}
- for repo in self.repos.all:
- lookup_path = self.tmpdir / template_str.format(repo=repo.name)
- _repo_content = self.get_children(lookup_path)
- reference_section = [
- {"REST API": f"{repo.name}/docs/rest_api.md"},
- {"Readme": f"{repo.name}/README.md"},
- {"Code API": _repo_content},
- {"Changelog": f"{repo.name}/CHANGELOG.md"},
- ]
- _nav[repo.title] = reference_section
- return _nav
-
- def section_file(self, section_and_filename: str):
- """Get a markdown file from the website section folder."""
- basepath = "pulp-docs/docs/sections"
- return f"{basepath}/{section_and_filename}"
-
- def section_children(self, section_name: str):
- """Get children markdown files from the website section folder."""
- basepath = "pulpcore/docs/sections"
- section = self.get_children(f"{basepath}/{section_name}")
- return section
diff --git a/staging_docs/dev/reference/markdown-cheatsheet.md b/staging_docs/dev/reference/markdown-cheatsheet.md
index d21eed6..fa034c0 100644
--- a/staging_docs/dev/reference/markdown-cheatsheet.md
+++ b/staging_docs/dev/reference/markdown-cheatsheet.md
@@ -4,147 +4,132 @@ There are basic markdown features recommended for use in Pulp.
### Internal links
-=== "Template"
+Adding absolute links is enabled by `mkdocs-site-urls`
+(learn more [here](https://github.com/octoprint/mkdocs-site-urls)).
+This is preferred over *relative* links because of our complex structure. See tradeoffs [here](https://github.com/pulp/pulp-docs/issues/2)
- ```markdown
- [My Link](site:{repo-name}/docs/{persona}/{content-type}/some-page.md).
- ```
-
-=== "Sample"
+```markdown
+# Template
+[My Link](site:{repo-name}/docs/{persona}/{content-type}/some-page.md).
- ```markdown
- [My Link](site:pulp-docs/docs/dev/reference/markdown-cheatsheet.md).
- ```
+# Example
+[My Link](site:pulp-docs/docs/dev/reference/markdown-cheatsheet.md).
-=== "Sample Rendered"
+# Rendered
+[My Link](http://127.0.0.1:8000/pulp-docs/docs/dev/reference/markdown-cheatsheet/).
+```
- ```markdown
- [My Link](http://127.0.0.1:8000/pulp-docs/docs/dev/reference/markdown-cheatsheet/).
- ```
+### Tabbed content
-- This is enabled by [mkdocs-site-urls](https://github.com/octoprint/mkdocs-site-urls) plugin.
-- This is preferred over *relative* links because of our complex structure. See tradeoffs [here](https://github.com/pulp/pulp-docs/issues/2)
+Having tabs for alternative content is enabled by mkdocs-material
+(learn more [here](https://squidfunk.github.io/mkdocs-material/reference/content-tabs/#usage)).
+It looks like this:
+!!! example
-### Codeblocks
+ === "Run"
+ ```bash
+ cat myfile.txt
+ ```
-=== "Raw"
+ === "Output"
- ````
- ```
-