summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2023-05-05 14:41:18 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2023-05-08 14:34:56 +0200
commite38207f81d0da414e07d982ab17699e109d3f2e2 (patch)
treefe83b7aa28bdb5feb88fd35a56af94f4c7380dcb
parentsphinxcontent: Add SphinxContent.latex_tiny() (diff)
downloadrtems-central-e38207f81d0da414e07d982ab17699e109d3f2e2.tar.bz2
sphinxcontent: Rework label handling
Rename get_label() in make_label(). Add a label stack to SphinxContent.
-rw-r--r--rtemsspec/interfacedoc.py15
-rw-r--r--rtemsspec/membench.py13
-rw-r--r--rtemsspec/specdoc.py13
-rw-r--r--rtemsspec/sphinxcontent.py66
-rw-r--r--rtemsspec/tests/test_content_sphinx.py46
-rw-r--r--rtemsspec/tests/test_membench.py2
6 files changed, 85 insertions, 70 deletions
diff --git a/rtemsspec/interfacedoc.py b/rtemsspec/interfacedoc.py
index 335c4e85..f7da0adf 100644
--- a/rtemsspec/interfacedoc.py
+++ b/rtemsspec/interfacedoc.py
@@ -32,7 +32,7 @@ from typing import Any, Dict, List, Tuple
from rtemsspec.content import CContent, get_value_compound, \
get_value_forward_declaration, get_value_unspecified_type
-from rtemsspec.sphinxcontent import get_label, get_reference, sanitize_name, \
+from rtemsspec.sphinxcontent import make_label, get_reference, sanitize_name, \
SphinxContent, SphinxInterfaceMapper
from rtemsspec.items import Item, ItemCache, ItemGetValueContext, ItemMapper
@@ -40,7 +40,7 @@ ItemMap = Dict[str, Item]
def _get_reference(name: str) -> str:
- return get_reference(get_label(f"Interface {name}"))
+ return get_reference(make_label(f"Interface {name}"))
def _get_code_param(ctx: ItemGetValueContext) -> Any:
@@ -67,9 +67,10 @@ def _generate_introduction(target: str, group: Item, group_uids: List[str],
content = SphinxContent()
content.register_license_and_copyrights_of_item(group)
content.add_automatically_generated_warning()
- group_name = group["name"]
content.add(f".. Generated from spec:{group.uid}")
- with content.section("Introduction", get_label(group_name)):
+ group_name = group["name"]
+ content.push_label(make_label(group_name))
+ with content.section("Introduction"):
# This needs to be in front of the list since comment blocks have an
# effect on the list layout in the HTML output
content.add(".. The following list was generated from:")
@@ -180,7 +181,8 @@ def _generate_directives(target: str, group: Item, group_uids: List[str],
content.register_license_and_copyrights_of_item(group)
content.add_automatically_generated_warning()
group_name = group["name"]
- with content.section("Directives", get_label(group_name)):
+ content.push_label(make_label(group_name))
+ with content.section("Directives"):
content.wrap([
f"This section details the directives of the {group_name}.",
"A subsection is dedicated to each of this manager's directives",
@@ -197,7 +199,8 @@ def _generate_directives(target: str, group: Item, group_uids: List[str],
content.add("\\clearpage")
directive = f"{name}()"
content.add_index_entries([directive] + item["index-entries"])
- with content.section(directive, "Interface"):
+ with content.section(directive,
+ label=make_label(f"Interface {directive}")):
_generate_directive(content, mapper, code_mapper, item,
enabled)
content.add_licence_and_copyrights()
diff --git a/rtemsspec/membench.py b/rtemsspec/membench.py
index d7a554b5..993d17c9 100644
--- a/rtemsspec/membench.py
+++ b/rtemsspec/membench.py
@@ -32,7 +32,7 @@ import re
from typing import Dict, List, Tuple
from rtemsspec.items import Item, ItemMapper
-from rtemsspec.sphinxcontent import get_label, get_reference, SphinxContent
+from rtemsspec.sphinxcontent import make_label, get_reference, SphinxContent
from rtemsspec.util import run_command
_SECTION = re.compile(
@@ -118,8 +118,8 @@ def _get_sections(item: Item, path: str) -> Dict[str, Tuple[int, int]]:
return sections
-def _get_label(item: Item) -> str:
- return get_label(f"MemBenchmark {item.uid[1:]}")
+def _make_label(item: Item) -> str:
+ return make_label(f"MemBenchmark {item.uid[1:]}")
def _generate_table(content: SphinxContent, items: List[Item],
@@ -127,7 +127,7 @@ def _generate_table(content: SphinxContent, items: List[Item],
rows: List[Tuple[str, ...]] = []
for index, item in enumerate(items):
sections = _get_sections(item, path)
- name = (get_reference(_get_label(item), item.uid), )
+ name = (get_reference(_make_label(item), item.uid), )
if index == 0:
keys = ("spec", ) + tuple(sections.keys())
base = {key: info[1] - info[0] for key, info in sections.items()}
@@ -141,7 +141,8 @@ def _generate_table(content: SphinxContent, items: List[Item],
section = f"Benchmarks Based on: {pivot.spec}"
with content.section(section):
content.wrap(f"""The following memory benchmarks are based on the
-memory benchmark defined by {get_reference(_get_label(pivot), pivot.spec)}.""")
+memory benchmark defined by
+{get_reference(_make_label(pivot), pivot.spec)}.""")
content.add_simple_table(rows)
@@ -149,7 +150,7 @@ def _generate_paragraphs(content: SphinxContent, items: List[Item],
mapper: ItemMapper) -> None:
for item in items:
section = f"Benchmark: {item.spec}"
- with content.section(section, label=_get_label(item)):
+ with content.section(section, label=_make_label(item)):
content.wrap(mapper.substitute(item["test-brief"], item))
content.wrap(mapper.substitute(item["test-description"], item))
diff --git a/rtemsspec/specdoc.py b/rtemsspec/specdoc.py
index 658da477..cbab0574 100644
--- a/rtemsspec/specdoc.py
+++ b/rtemsspec/specdoc.py
@@ -27,7 +27,7 @@
import re
from typing import Any, Dict, Iterator, List, Optional, Pattern, Set, Tuple
-from rtemsspec.sphinxcontent import get_reference, get_label, \
+from rtemsspec.sphinxcontent import get_reference, make_label, \
SphinxContent, SphinxMapper
from rtemsspec.items import Item, ItemCache, ItemGetValueContext
from rtemsspec.specverify import NAME
@@ -275,7 +275,7 @@ class _Documenter:
def _get_ref_specification_type(self, ctx: ItemGetValueContext) -> Any:
return get_reference(self._label_prefix +
- get_label(ctx.value[ctx.key]))
+ make_label(ctx.value[ctx.key]))
def _substitute(self, text: str) -> str:
if text:
@@ -284,7 +284,7 @@ class _Documenter:
def get_section_reference(self) -> str:
""" Returns the section reference. """
- return get_reference(self._label_prefix + get_label(self.section))
+ return get_reference(self._label_prefix + make_label(self.section))
def get_a_section_reference(self) -> str:
""" Returns a section reference. """
@@ -440,7 +440,9 @@ class _Documenter:
if self.get_list_element_type():
return
content.register_license_and_copyrights_of_item(self._item)
- with content.section(self.section, self._label_prefix):
+ with content.section(
+ self.section,
+ label=f"{self._label_prefix}{make_label(self.section)}"):
last = content.lines[-1]
self._add_description(content)
if len(self._info_map) == 1:
@@ -560,8 +562,9 @@ def document(config: dict, item_cache: ItemCache) -> None:
for documenter in documenter_map.values():
documenter.resolve_used_by()
documenter_names = set(documenter_map)
- content.section_label_prefix = config["section-label-prefix"]
+ content.push_label(config["section-label-prefix"])
with content.section(config["section-name"]):
+ content.push_label(config["section-label-prefix"])
with content.section(config["hierarchy-subsection-name"]):
content.add(config["hierarchy-text"])
root_documenter.hierarchy(content, ignore)
diff --git a/rtemsspec/sphinxcontent.py b/rtemsspec/sphinxcontent.py
index abec5553..42cf6430 100644
--- a/rtemsspec/sphinxcontent.py
+++ b/rtemsspec/sphinxcontent.py
@@ -45,7 +45,7 @@ def get_reference(label: str, name: Optional[str] = None) -> str:
return f":ref:`{label}`"
-def get_label(name: str) -> str:
+def make_label(name: str) -> str:
""" Returns the label for the specified name. """
return to_camel_case(name.strip())
@@ -77,7 +77,36 @@ class SphinxContent(Content):
super().__init__("CC-BY-SA-4.0", True)
self._tab = " "
self._section_level = section_level
- self.section_label_prefix = "Section"
+ self._label_stack = [""]
+
+ @property
+ def label(self) -> str:
+ """ This is the top of the label stack. """
+ return self._label_stack[-1]
+
+ def get_label(self, label_tail: str = "") -> str:
+ """
+ Returns the concatenation of the top of the label stack and the label
+ tail.
+ """
+ return f"{self.label}{label_tail}"
+
+ def push_label(self, label: str) -> None:
+ """ Pushes the label to the label stack. """
+ self._label_stack.append(label)
+
+ def push_label_tail(self, label_tail: str) -> str:
+ """
+ Makes a label from the concatenation of the top of the label stack and
+ the label tail. Pushes this label to the label stack and returns it.
+ """
+ label = self.get_label(label_tail)
+ self.push_label(label)
+ return label
+
+ def pop_label(self) -> None:
+ """ Pops the top from the label stack. """
+ self._label_stack.pop()
def add_label(self, label: str) -> None:
""" Adds a label. """
@@ -88,20 +117,6 @@ class SphinxContent(Content):
name = name.strip()
self.add([name, _HEADER_LEVELS[level] * len(name)])
- def add_header_with_label(self,
- name: str,
- level: int = 2,
- label_prefix: Optional[str] = None,
- label: Optional[str] = None) -> str:
- """ Adds a header with label. """
- if label is None:
- if label_prefix is None:
- label_prefix = self.section_label_prefix
- label = label_prefix + get_label(name)
- self.add_label(label)
- self.add_header(name, level)
- return label
-
def add_rubric(self, name: str) -> None:
""" Adds a rubric. """
self.add(f".. rubric:: {name}")
@@ -175,25 +190,32 @@ class SphinxContent(Content):
def open_section(self,
name: str,
- label_prefix: Optional[str] = None,
+ label_tail: Optional[str] = None,
label: Optional[str] = None) -> str:
""" Opens a section. """
- label = self.add_header_with_label(name, self._section_level,
- label_prefix, label)
+ if label is None:
+ if label_tail is None:
+ label_tail = make_label(name)
+ label = self.push_label_tail(label_tail)
+ else:
+ self.push_label(label)
+ self.add_label(label)
+ self.add_header(name, self._section_level)
self._section_level += 1
return label
def close_section(self) -> None:
""" Closes a section. """
self._section_level -= 1
+ self.pop_label()
@contextmanager
def section(self,
name: str,
- label_prefix: Optional[str] = None,
+ label_tail: Optional[str] = None,
label: Optional[str] = None) -> Iterator[str]:
""" Opens a section context. """
- yield self.open_section(name, label_prefix, label)
+ yield self.open_section(name, label_tail, label)
self.close_section()
def open_latex_tiny(self, size: str = "tiny") -> None:
@@ -427,7 +449,7 @@ class SphinxInterfaceMapper(SphinxMapper):
name = ctx.value[ctx.key]
for group in ctx.item.parents("interface-ingroup"):
if group.uid in self._group_uids:
- return get_reference(get_label(f"Interface {name}"))
+ return get_reference(make_label(f"Interface {name}"))
return f":c:func:`{name}`"
def _get_group(self, ctx: ItemGetValueContext) -> Any:
diff --git a/rtemsspec/tests/test_content_sphinx.py b/rtemsspec/tests/test_content_sphinx.py
index 59903283..07724c30 100644
--- a/rtemsspec/tests/test_content_sphinx.py
+++ b/rtemsspec/tests/test_content_sphinx.py
@@ -26,7 +26,7 @@
import pytest
-from rtemsspec.sphinxcontent import get_reference, get_label, \
+from rtemsspec.sphinxcontent import get_reference, make_label, \
SphinxContent, SphinxMapper
from rtemsspec.items import Item, ItemCache, ItemMapper
from rtemsspec.tests.util import create_item_cache_config_and_copy_spec
@@ -76,36 +76,13 @@ yz
"""
-def test_add_header_with_label():
- content = SphinxContent()
- label = content.add_header_with_label("x", 1)
- assert label == "SectionX"
- assert str(content) == """.. _SectionX:
-
-x
-*
-"""
- label = content.add_header_with_label("yz w", 2)
- assert label == "SectionYzW"
- assert str(content) == """.. _SectionX:
-
-x
-*
-
-.. _SectionYzW:
-
-yz w
-====
-"""
-
-
def test_get_reference():
assert get_reference("a") == ":ref:`a`"
assert get_reference("a", "b") == ":ref:`b <a>`"
-def test_get_label():
- assert get_label("ab cd") == "AbCd"
+def test_make_label():
+ assert make_label("ab cd") == "AbCd"
def test_section():
@@ -114,19 +91,28 @@ def test_section():
content.add(label)
with content.section("ef gh") as label2:
content.add(label2)
- assert str(content) == """.. _SectionAbCd:
+ with content.section("ij kl", "mn") as label2:
+ content.add(label2)
+ assert str(content) == """.. _AbCd:
ab cd
=====
-SectionAbCd
+AbCd
-.. _SectionEfGh:
+.. _AbCdEfGh:
ef gh
-----
-SectionEfGh
+AbCdEfGh
+
+.. _AbCdEfGhmn:
+
+ij kl
+^^^^^
+
+AbCdEfGhmn
"""
diff --git a/rtemsspec/tests/test_membench.py b/rtemsspec/tests/test_membench.py
index 3bc5ecb5..ffbe2aea 100644
--- a/rtemsspec/tests/test_membench.py
+++ b/rtemsspec/tests/test_membench.py
@@ -49,7 +49,7 @@ def test_membench(tmpdir, monkeypatch):
root = item_cache["/r0"]
content = SphinxContent()
generate(content, root, ItemMapper(root), ["/r0"], "path")
- assert str(content) == """.. _SectionBenchmarksBasedOnSpecT0:
+ assert str(content) == """.. _BenchmarksBasedOnSpecT0:
Benchmarks Based on: spec:/t0
=============================