Skip to content

Commit 7c07936

Browse files
committed
cleaner docs.yml
1 parent 14f3d46 commit 7c07936

File tree

2 files changed

+94
-18
lines changed

2 files changed

+94
-18
lines changed

src/autodoc2/cli.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,13 @@ def _warn(msg: str, type_: WarningSubtypes) -> None:
276276
content = "\n".join(
277277
render_class(db, config, warn=_warn).render_item(mod_name)
278278
)
279-
out_path = output / (mod_name + render_class.EXTENSION)
279+
280+
# Use hyphens in filenames for Fern renderer to match slugs
281+
if renderer == "fern":
282+
filename = mod_name.replace('.', '-').replace('_', '-')
283+
out_path = output / (filename + render_class.EXTENSION)
284+
else:
285+
out_path = output / (mod_name + render_class.EXTENSION)
280286
paths.append(out_path)
281287
if out_path.exists() and out_path.read_text("utf8") == content:
282288
# Don't write the file if it hasn't changed

src/autodoc2/render/fern_.py

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ def render_item(self, full_name: str) -> t.Iterable[str]:
3131
if type_ in ("package", "module"):
3232
yield "---"
3333
yield "layout: overview"
34+
slug = self._generate_slug(full_name)
35+
yield f"slug: {slug}"
3436
yield "---"
3537
yield ""
3638

@@ -137,35 +139,25 @@ def render_package(self, item: ItemData) -> t.Iterable[str]:
137139
yield ""
138140
for child in children_by_type["package"]:
139141
name = child["full_name"].split(".")[-1]
140-
# Create simple relative link using just the child name
141-
link_path = name
142+
# Create slug-based link using full dotted name
143+
slug = self._generate_slug(child["full_name"])
142144
doc_summary = child.get('doc', '').split('\n')[0][:80] if child.get('doc') else ""
143145
if len(child.get('doc', '')) > 80:
144146
doc_summary += "..."
145-
yield f"- **[`{name}`]({link_path})** - {doc_summary}" if doc_summary else f"- **[`{name}`]({link_path})**"
147+
yield f"- **[`{name}`]({slug})** - {doc_summary}" if doc_summary else f"- **[`{name}`]({slug})**"
146148
yield ""
147149

148150
if has_submodules:
149151
yield "## Submodules"
150152
yield ""
151153
for child in children_by_type["module"]:
152154
name = child["full_name"].split(".")[-1]
153-
# Replace underscores with dashes in display text for better readability
154-
display_name = name.replace('_', '-')
155-
156-
# Create contextual link based on current page
157-
current_parts = item["full_name"].split(".")
158-
if len(current_parts) == 1:
159-
# On root page - use simple name
160-
link_path = display_name
161-
else:
162-
# On subpackage page - use full filename (convert dots and underscores to dashes)
163-
link_path = child["full_name"].replace('.', '-').replace('_', '-')
164-
155+
# Create slug-based link using full dotted name
156+
slug = self._generate_slug(child["full_name"])
165157
doc_summary = child.get('doc', '').split('\n')[0][:80] if child.get('doc') else ""
166158
if len(child.get('doc', '')) > 80:
167159
doc_summary += "..."
168-
yield f"- **[`{display_name}`]({link_path})** - {doc_summary}" if doc_summary else f"- **[`{display_name}`]({link_path})**"
160+
yield f"- **[`{name}`]({slug})** - {doc_summary}" if doc_summary else f"- **[`{name}`]({slug})**"
169161
yield ""
170162

171163
# Show Module Contents summary if we have actual content (not just submodules)
@@ -711,4 +703,82 @@ def replace_tag(match):
711703
escaped_tag = tag.replace('{', '\\{').replace('}', '\\}')
712704
escaped_content = escaped_content.replace(placeholder, f'`{escaped_tag}`')
713705

714-
return escaped_content
706+
return escaped_content
707+
708+
def _generate_slug(self, full_name: str) -> str:
709+
"""Generate slug from full dotted name: nemo_curator.utils.grouping → nemo-curator-utils-grouping"""
710+
return full_name.replace('.', '-').replace('_', '-')
711+
712+
def generate_navigation_yaml(self) -> str:
713+
"""Generate navigation YAML for Fern docs.yml following sphinx autodoc2 toctree logic."""
714+
import yaml
715+
716+
# Find root packages (no dots in name)
717+
root_packages = []
718+
for item in self._db.get_by_type("package"):
719+
full_name = item["full_name"]
720+
if "." not in full_name: # Root packages only
721+
root_packages.append(item)
722+
723+
if not root_packages:
724+
return ""
725+
726+
# Build navigation structure recursively
727+
nav_contents = []
728+
for root_pkg in sorted(root_packages, key=lambda x: x["full_name"]):
729+
nav_item = self._build_nav_item_recursive(root_pkg)
730+
if nav_item:
731+
nav_contents.append(nav_item)
732+
733+
# Create the final navigation structure
734+
navigation = {
735+
"navigation": [
736+
{
737+
"section": "API Reference",
738+
"skip-slug": True,
739+
"contents": nav_contents
740+
}
741+
]
742+
}
743+
744+
return yaml.dump(navigation, default_flow_style=False, sort_keys=False, allow_unicode=True)
745+
746+
def _build_nav_item_recursive(self, item: ItemData) -> dict[str, t.Any] | None:
747+
"""Build navigation item recursively following sphinx autodoc2 toctree logic."""
748+
full_name = item["full_name"]
749+
slug = self._generate_slug(full_name)
750+
751+
# Get children (same logic as sphinx toctrees)
752+
subpackages = list(self.get_children(item, {"package"}))
753+
submodules = list(self.get_children(item, {"module"}))
754+
755+
if subpackages or submodules:
756+
# This has children - make it a section with skip-slug
757+
section_item = {
758+
"section": full_name.split(".")[-1], # Use short name for section
759+
"skip-slug": True,
760+
"path": f"{slug}.md",
761+
"contents": []
762+
}
763+
764+
# Add subpackages recursively (maxdepth: 3 like sphinx)
765+
for child in sorted(subpackages, key=lambda x: x["full_name"]):
766+
child_nav = self._build_nav_item_recursive(child)
767+
if child_nav:
768+
section_item["contents"].append(child_nav)
769+
770+
# Add submodules as pages (maxdepth: 1 like sphinx)
771+
for child in sorted(submodules, key=lambda x: x["full_name"]):
772+
child_slug = self._generate_slug(child["full_name"])
773+
section_item["contents"].append({
774+
"page": child["full_name"].split(".")[-1], # Use short name
775+
"path": f"{child_slug}.md"
776+
})
777+
778+
return section_item
779+
else:
780+
# Leaf item - just a page
781+
return {
782+
"page": full_name.split(".")[-1], # Use short name
783+
"path": f"{slug}.md"
784+
}

0 commit comments

Comments
 (0)