Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion WRITING_DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ You can specify what group of files this .scad file is a part of with the `// Fi
This affects the ordering of files in Table of Contents and CheatSheet files. This doesn't generate any output text otherwise.


FileTitle Block
---------------

You can give a file a display title that is shown instead of its source filename in generated page headings, tables of contents, sidebars, and cheat sheets:

// FileTitle: Basic Shapes

The filename from the `File` or `LibFile` block is still used for output files and link targets.


FileSummary Block
-----------------

Expand Down Expand Up @@ -1142,4 +1152,3 @@ You can also use the DefineHeader block in the config file to make custom block
DefineHeader(Table;Headers=^Anchor Name|Position): Extra Anchors



14 changes: 11 additions & 3 deletions openscad_docsgen/blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,13 +351,19 @@ def __init__(self, title, subtitle, body, origin):
self.includes = []
self.common_code = []
self.footnotes = []
self.file_title = ""
self.summary = ""
self.group = ""

@property
def display_title(self):
return self.file_title if self.file_title else self.subtitle

def get_data(self):
d = super().get_data()
d["includes"] = self.includes
d["commoncode"] = self.common_code
d["filetitle"] = self.file_title
d["group"] = self.group
d["summary"] = self.summary
d["footnotes"] = [
Expand Down Expand Up @@ -387,7 +393,7 @@ def get_tocfile_lines(self, controller, target, n=1, currfile=""):
sect for sect in self.children
if isinstance(sect, SectionBlock)
]
link = self.get_link(target, label=self.subtitle, currfile=currfile)
link = self.get_link(target, label=self.display_title, currfile=currfile)
out = []
out.extend(target.header("{}. {}".format(n, link), lev=target.SECTION, esc=False))
if self.summary:
Expand Down Expand Up @@ -419,12 +425,14 @@ def get_cheatsheet_lines(self, controller, target):
lines.extend(child.get_cheatsheet_lines(controller, target))
out = []
if lines:
out.extend(target.header("{}: {}".format(self.title, self.subtitle), lev=target.SUBSECTION))
title = self.file_title if self.file_title else str(self)
out.extend(target.header(title, lev=target.SUBSECTION))
out.extend(lines)
return out

def get_file_lines(self, controller, target):
out = target.header(str(self), lev=target.FILE)
title = self.file_title if self.file_title else str(self)
out = target.header(title, lev=target.FILE)
out.extend(target.markdown_block(self.get_markdown_body(controller, target)))
for child in self.children:
if not isinstance(child, SectionBlock):
Expand Down
14 changes: 11 additions & 3 deletions openscad_docsgen/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ def _parse_block(self, lines, line_num=0, src_file=None):
raise DocsGenException(title, "Must provide a subtitle when declaring block:")
self._check_filenode(title, origin)
self.curr_file_block.summary = subtitle.strip()
elif title == "FileTitle":
if body:
raise DocsGenException(title, "Body not supported, while declaring block:")
if not subtitle:
raise DocsGenException(title, "Must provide a subtitle when declaring block:")
self._check_filenode(title, origin)
self.curr_file_block.file_title = subtitle.strip()
elif title == "FileGroup":
if not subtitle:
raise DocsGenException(title, "Must provide a subtitle when declaring block:")
Expand Down Expand Up @@ -799,8 +806,9 @@ def write_toc_file(self):
if fblock.group != group:
continue
file = fblock.subtitle
anch = target.header_link("{}. {}".format(fnum+1, file))
link = target.get_link(file, anchor=anch, literalize=False)
title = fblock.display_title
anch = target.header_link("{}. {}".format(fnum+1, title))
link = target.get_link(title, anchor=anch, literalize=False)
filelink = target.get_link("docs", file=file, literalize=False)
tags = {tag: text for tag, text, origin in fblock.footnotes}
marks = target.mouseover_tags(tags, "#file-footnotes")
Expand Down Expand Up @@ -1053,7 +1061,7 @@ def write_sidebar_file(self):
if fblock.group != group:
continue
file = fblock.subtitle
link = target.get_link(file, file=file, literalize=False)
link = target.get_link(fblock.display_title, file=file, literalize=False)
for mark, note, origin in fblock.footnotes:
try:
if mark not in footmarks:
Expand Down
29 changes: 29 additions & 0 deletions tests/test_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,35 @@ def test_generic_block_get_data():
assert d["line"] == 5


# --- FileBlock ---

def test_file_block_uses_filename_as_default_display_title():
block = FileBlock("LibFile", "mylib.scad", [], make_origin("mylib.scad"))
assert block.display_title == "mylib.scad"


def test_file_block_uses_explicit_display_title():
block = FileBlock("LibFile", "mylib.scad", [], make_origin("mylib.scad"))
block.file_title = "Core Shapes"
SectionBlock("Section", "Basics", [], make_origin("mylib.scad"), parent=block)
assert block.display_title == "Core Shapes"
assert block.get_data()["filetitle"] == "Core Shapes"


def test_file_block_heading_uses_explicit_display_title():
block = FileBlock("LibFile", "mylib.scad", [], make_origin("mylib.scad"))
block.file_title = "Core Shapes"
lines = block.get_file_lines(make_controller(), make_target())
assert lines[0] == "# Core Shapes"
assert "mylib.scad" not in lines[0]


def test_file_block_heading_keeps_legacy_title_by_default():
block = FileBlock("LibFile", "mylib.scad", [], make_origin("mylib.scad"))
lines = block.get_file_lines(make_controller(), make_target())
assert lines[0] == "# LibFile: mylib.scad"


def test_sort_children_back_blocks_last():
parent = GenericBlock("Parent", "p", [], make_origin())
c_example = GenericBlock("Example", "e", [], make_origin(), parent=parent)
Expand Down
47 changes: 46 additions & 1 deletion tests/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,19 @@ def test_header_pat_constant():

def make_parser(tmp_path):
target = Target_Wiki(docs_dir=str(tmp_path))
opts = types.SimpleNamespace(target=target, strict=False, quiet=True)
opts = types.SimpleNamespace(
target=target,
strict=False,
quiet=True,
gen_toc=True,
gen_index=False,
gen_topics=False,
gen_glossary=False,
gen_cheat=False,
sidebar_header=[],
sidebar_middle=[],
sidebar_footer=[],
)
return DocsGenParser(opts)


Expand Down Expand Up @@ -143,6 +155,39 @@ def test_parse_libfile_creates_file_block(tmp_path, monkeypatch):
assert parser.file_blocks[0].subtitle == "test.scad"


# --- Integration: parse FileTitle block ---

FILE_TITLE_SCAD = """\
// LibFile: test.scad
// FileTitle: Core Shapes
"""


def test_parse_file_title_sets_display_title(tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
parser = make_parser(tmp_path)
parser.parse_lines(FILE_TITLE_SCAD.splitlines(), src_file="test.scad")
assert parser.file_blocks[0].file_title == "Core Shapes"
assert parser.file_blocks[0].display_title == "Core Shapes"


def test_file_title_is_used_in_toc_and_sidebar(tmp_path, monkeypatch):
monkeypatch.chdir(tmp_path)
parser = make_parser(tmp_path)
parser.parse_lines(FILE_TITLE_SCAD.splitlines(), src_file="test.scad")

parser.write_toc_file()
parser.write_sidebar_file()

toc = (tmp_path / "TOC.md").read_text()
sidebar = (tmp_path / "_Sidebar.md").read_text()
assert "[Core Shapes](#1-core-shapes)" in toc
assert "## 1. [Core Shapes](test.scad)" in toc
assert "[Core Shapes](test.scad)" in sidebar
assert "[test.scad]" not in toc
assert "[test.scad]" not in sidebar


# --- Integration: parse Section ---

SECTION_SCAD = """\
Expand Down