Skip to content

Commit f3ff112

Browse files
authored
feat: Add index-topmatter config option for custom YAML frontmatter (#412)
* feat: Add index-topmatter config option for custom YAML frontmatter * tests: remove full topmatter test * refactor: Generalize dash-to-underscore conversion for all config keys * Update quartodoc/autosummary.py * Update quartodoc/autosummary.py
1 parent d743a7c commit f3ff112

File tree

2 files changed

+99
-2
lines changed

2 files changed

+99
-2
lines changed

quartodoc/autosummary.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,11 @@ class Builder:
480480
parser:
481481
Docstring parser to use. This correspond to different docstring styles,
482482
and can be one of "google", "sphinx", and "numpy". Defaults to "numpy".
483+
index_topmatter : dict, optional
484+
Custom YAML frontmatter for the API index page. When provided, this
485+
completely overrides the `title` configuration. Set to an empty dict
486+
to generate an empty frontmatter block. Default is None, which falls
487+
back to using the `title` parameter.
483488
484489
"""
485490

@@ -530,6 +535,7 @@ def __init__(
530535
dynamic: bool | None = None,
531536
parser="numpy",
532537
render_interlinks: bool = False,
538+
index_topmatter: "dict[str, Any] | None" = None,
533539
_fast_inventory=False,
534540
):
535541
self.layout = self.load_layout(
@@ -559,6 +565,8 @@ def __init__(
559565
if out_index is not None:
560566
self.out_index = out_index
561567

568+
self.index_topmatter = index_topmatter
569+
562570
self.rewrite_all_pages = rewrite_all_pages
563571
self.source_dir = str(Path(source_dir).absolute()) if source_dir else None
564572
self.dynamic = dynamic
@@ -646,9 +654,15 @@ def write_index(self, blueprint: layout.Layout):
646654
content = self.renderer.summarize(blueprint)
647655
_log.info(f"Writing index to directory: {self.dir}")
648656

649-
if self.title is not None:
657+
# handle index topmatter
658+
if self.index_topmatter is not None:
659+
# index_topmatter overrides title
660+
meta = [Meta(self.index_topmatter)]
661+
elif self.title is not None:
662+
# Fall back to title-only frontmatter
650663
meta = [Meta({"title": self.title})]
651664
else:
665+
# No frontmatter at all
652666
meta = []
653667

654668
final = str(Blocks([*meta, content]))
@@ -806,8 +820,15 @@ def from_quarto_config(cls, quarto_cfg: "str | dict") -> Builder:
806820

807821
_fast_inventory = quarto_cfg.get("interlinks", {}).get("fast", False)
808822

823+
# Convert dash to underscore for all config keys (YAML uses dashes, Python uses underscores)
824+
config_args = {}
825+
for k, v in cfg.items():
826+
if k != "style":
827+
# Replace dashes with underscores for Python parameter names
828+
config_args[k.replace("-", "_")] = v
829+
809830
return cls_builder(
810-
**{k: v for k, v in cfg.items() if k != "style"},
831+
**config_args,
811832
_fast_inventory=_fast_inventory,
812833
)
813834

quartodoc/tests/test_builder.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,79 @@ def test_builder_no_title_no_topmatter(tmp_path):
149149

150150
index = (Path(tmp_path) / "index.qmd").read_text()
151151
assert not index.startswith("---")
152+
153+
154+
def test_builder_index_topmatter_custom(tmp_path):
155+
"""Test that index_topmatter allows custom frontmatter."""
156+
cfg = yaml.safe_load(
157+
"""
158+
quartodoc:
159+
package: quartodoc.tests.example
160+
title: "This will be ignored"
161+
index-topmatter:
162+
title: "Custom API Reference"
163+
description: "API documentation for my package"
164+
author: "Test Author"
165+
date: "2024-01-01"
166+
sections:
167+
- title: first section
168+
contents: [a_func]
169+
"""
170+
)
171+
172+
builder = Builder.from_quarto_config(cfg)
173+
builder.dir = str(tmp_path)
174+
bp = blueprint(builder.layout)
175+
builder.write_index(bp)
176+
177+
index = (Path(tmp_path) / "index.qmd").read_text()
178+
assert index.startswith("---")
179+
assert "title: Custom API Reference" in index
180+
assert "description: API documentation for my package" in index
181+
assert "author: Test Author" in index
182+
assert "This will be ignored" not in index # Original title not used
183+
184+
185+
def test_builder_index_topmatter_empty(tmp_path):
186+
"""Test that empty index_topmatter generates empty frontmatter."""
187+
cfg = yaml.safe_load(
188+
"""
189+
quartodoc:
190+
package: quartodoc.tests.example
191+
title: "Will be ignored"
192+
index-topmatter: {}
193+
sections:
194+
- title: first section
195+
contents: [a_func]
196+
"""
197+
)
198+
199+
builder = Builder.from_quarto_config(cfg)
200+
builder.dir = str(tmp_path)
201+
bp = blueprint(builder.layout)
202+
builder.write_index(bp)
203+
204+
index = (Path(tmp_path) / "index.qmd").read_text()
205+
assert index.startswith("---\n{}\n\n---") # Empty dict rendered as {} in YAML
206+
207+
208+
def test_builder_index_topmatter_fallback(tmp_path):
209+
"""Test that title is used when index_topmatter is not provided."""
210+
cfg = yaml.safe_load(
211+
"""
212+
quartodoc:
213+
package: quartodoc.tests.example
214+
title: "Function Reference"
215+
sections:
216+
- title: first section
217+
contents: [a_func]
218+
"""
219+
)
220+
221+
builder = Builder.from_quarto_config(cfg)
222+
builder.dir = str(tmp_path)
223+
bp = blueprint(builder.layout)
224+
builder.write_index(bp)
225+
226+
index = (Path(tmp_path) / "index.qmd").read_text()
227+
assert "title: Function Reference" in index

0 commit comments

Comments
 (0)