pytex-preprocessor 0.1.1__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/PKG-INFO +1 -1
  2. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/pyproject.toml +1 -1
  3. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/voting.py +5 -2
  4. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_preprocessor.egg-info/PKG-INFO +1 -1
  5. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/convert.py +32 -16
  6. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/document.py +3 -3
  7. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/README.md +0 -0
  8. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/setup.cfg +0 -0
  9. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/__init__.py +0 -0
  10. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/__init__.py +0 -0
  11. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/biblatex.py +0 -0
  12. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/builtin.py +0 -0
  13. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/captions.py +0 -0
  14. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/cleveref.py +0 -0
  15. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/colors.py +0 -0
  16. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/conditionals.py +0 -0
  17. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/counters.py +0 -0
  18. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/definitions.py +0 -0
  19. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/floats.py +0 -0
  20. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/font.py +0 -0
  21. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/fontawesome.py +0 -0
  22. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/fontspec.py +0 -0
  23. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/geometry.py +0 -0
  24. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/glossaries.py +0 -0
  25. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/graphics.py +0 -0
  26. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/hooks.py +0 -0
  27. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/hyperref.py +0 -0
  28. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/lengths.py +0 -0
  29. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/listings.py +0 -0
  30. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/mdframed.py +0 -0
  31. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/picture.py +0 -0
  32. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/setspace.py +0 -0
  33. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/commands/tables.py +0 -0
  34. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/helpers/__init__.py +0 -0
  35. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/helpers/coerce.py +0 -0
  36. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/helpers/parenting.py +0 -0
  37. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/helpers/sanitize.py +0 -0
  38. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/helpers/with_package.py +0 -0
  39. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/interface/__init__.py +0 -0
  40. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/interface/control_sequence.py +0 -0
  41. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/interface/package.py +0 -0
  42. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/interface/tex.py +0 -0
  43. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/__init__.py +0 -0
  44. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/color.py +0 -0
  45. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/concat.py +0 -0
  46. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/control_sequence.py +0 -0
  47. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/document.py +0 -0
  48. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/document_class.py +0 -0
  49. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/empty.py +0 -0
  50. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/environment.py +0 -0
  51. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/image.py +0 -0
  52. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/include.py +0 -0
  53. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/length.py +0 -0
  54. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/math.py +0 -0
  55. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/package.py +0 -0
  56. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/model/raw.py +0 -0
  57. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/packages.py +0 -0
  58. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex/registry.py +0 -0
  59. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_builder/__init__.py +0 -0
  60. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_builder/build.py +0 -0
  61. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_builder/console.py +0 -0
  62. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_builder/render.py +0 -0
  63. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_builder/tectonic.py +0 -0
  64. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/__init__.py +0 -0
  65. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Bold.ttf +0 -0
  66. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-BoldItalic.ttf +0 -0
  67. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Book.ttf +0 -0
  68. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-BookItalic.ttf +0 -0
  69. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Medium.ttf +0 -0
  70. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-MediumItalic.ttf +0 -0
  71. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Strong.ttf +0 -0
  72. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-Thin.ttf +0 -0
  73. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Blender/Blender-ThinItalic.ttf +0 -0
  74. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Black.ttf +0 -0
  75. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Bold.ttf +0 -0
  76. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-BoldItalic.ttf +0 -0
  77. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Italic.ttf +0 -0
  78. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Medium.ttf +0 -0
  79. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/DIN/DIN-Regular.ttf +0 -0
  80. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/fonts/Times New Roman.ttf +0 -0
  81. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/ASTA.svg +0 -0
  82. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/DUMMY.png +0 -0
  83. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/DUMMY_FOOT.png +0 -0
  84. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/ECHO.svg +0 -0
  85. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/HSRT.pdf +0 -0
  86. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/INF.pdf +0 -0
  87. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/STUPA.pdf +0 -0
  88. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/assets/logos/Skyline.pdf +0 -0
  89. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/boxes.py +0 -0
  90. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/citations.py +0 -0
  91. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/cleveref_names.py +0 -0
  92. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/colors.py +0 -0
  93. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/document.py +0 -0
  94. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/fonts.py +0 -0
  95. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/glossary.py +0 -0
  96. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/hyperref_config.py +0 -0
  97. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/listings.py +0 -0
  98. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/logos.py +0 -0
  99. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/pagebreak.py +0 -0
  100. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/pagesetup.py +0 -0
  101. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/tex/pagesetup.tex +0 -0
  102. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/titlepage.py +0 -0
  103. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/variants.py +0 -0
  104. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/watermark.py +0 -0
  105. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_hsrtreport/wordcount.py +0 -0
  106. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_koma/__init__.py +0 -0
  107. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_koma/commands.py +0 -0
  108. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_koma/document.py +0 -0
  109. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_markdown/__init__.py +0 -0
  110. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_markdown/convert.py +0 -0
  111. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_markdown/escape.py +0 -0
  112. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_preprocessor.egg-info/SOURCES.txt +0 -0
  113. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_preprocessor.egg-info/dependency_links.txt +0 -0
  114. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_preprocessor.egg-info/entry_points.txt +0 -0
  115. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_preprocessor.egg-info/requires.txt +0 -0
  116. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_preprocessor.egg-info/top_level.txt +0 -0
  117. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/__init__.py +0 -0
  118. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/entries.py +0 -0
  119. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/frontmatter.py +0 -0
  120. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/header.py +0 -0
  121. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/shortcodes.py +0 -0
  122. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_protocol/signatures.py +0 -0
  123. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_tikz/__init__.py +0 -0
  124. {pytex_preprocessor-0.1.1 → pytex_preprocessor-0.1.3}/src/pytex_tikz/tikz.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytex-preprocessor
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Type-safe LaTeX document generation with Python
5
5
  Author-email: Frederik Beimgraben <frederik@beimgraben.net>
6
6
  Requires-Python: >=3.13
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pytex-preprocessor"
7
- version = "0.1.1"
7
+ version = "0.1.3"
8
8
  authors = [
9
9
  { name="Frederik Beimgraben", email="frederik@beimgraben.net" },
10
10
  ]
@@ -9,7 +9,7 @@ from pytex.interface.package import PackageProtocol
9
9
  from pytex.interface.tex import TeX
10
10
  from pytex.model.concat import Concat
11
11
  from pytex.model.package import DefinePackage
12
- from pytex.packages import FONTAWESOME, MDFRAMED, XCOLOR
12
+ from pytex.packages import CALC, FONTAWESOME, MDFRAMED, XCOLOR
13
13
  from pytex.registry import Registry
14
14
 
15
15
  from .boxes import ColoredBox, CustomBox
@@ -56,7 +56,10 @@ class VotingResults(TeX):
56
56
  @property
57
57
  @override
58
58
  def requires(self) -> frozenset[PackageProtocol]:
59
- return frozenset({MDFRAMED, XCOLOR, FONTAWESOME, MULTICOL})
59
+ # CALC is needed because the nested ColoredBox/CustomBox use infix
60
+ # length arithmetic; they are built inside `.rendered`, so their own
61
+ # `requires` (which include CALC) never reach the package collector.
62
+ return frozenset({MDFRAMED, XCOLOR, FONTAWESOME, MULTICOL, CALC})
60
63
 
61
64
  @property
62
65
  @override
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytex-preprocessor
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Type-safe LaTeX document generation with Python
5
5
  Author-email: Frederik Beimgraben <frederik@beimgraben.net>
6
6
  Requires-Python: >=3.13
@@ -24,7 +24,7 @@ from .shortcodes import expand_inline_shortcodes
24
24
  from .signatures import SignatureLines
25
25
 
26
26
  if TYPE_CHECKING:
27
- from collections.abc import Callable, Mapping
27
+ from collections.abc import Callable, Iterator, Mapping
28
28
 
29
29
  from pytex.interface.tex import TeX
30
30
 
@@ -66,19 +66,27 @@ def _children(node: object) -> list[object]:
66
66
  return cast("list[object]", children) if isinstance(children, list) else []
67
67
 
68
68
 
69
- def _all_text(node: object) -> str:
70
- """Concatenate every literal text fragment beneath `node`."""
71
- text = _text(node)
72
- if text is not None:
73
- return text
74
- return "".join(_all_text(c) for c in _children(node))
75
-
76
-
77
69
  def _tally(text: str, key: str) -> int:
78
70
  match = _TALLY_RE[key].search(text)
79
71
  return int(match.group(1)) if match else 0
80
72
 
81
73
 
74
+ def _is_tally_line(line: str) -> bool:
75
+ """A line is the vote tally if it carries at least two of yes/no/abstain."""
76
+ return sum(1 for rx in _TALLY_RE.values() if rx.search(line)) >= 2
77
+
78
+
79
+ def _interleave(items: Iterator[TeX]) -> Iterator[TeX]:
80
+ """Yield `items` separated by LaTeX line breaks (for multi-line box bodies)."""
81
+ from pytex.model.raw import Raw
82
+
83
+ sep = Raw(r"\\")
84
+ for i, item in enumerate(items):
85
+ if i:
86
+ yield sep
87
+ yield item
88
+
89
+
82
90
  def _leaf_texts(node: object) -> list[str]:
83
91
  """Every leaf text fragment beneath `node`, in order (one per source line)."""
84
92
  text = _text(node)
@@ -124,7 +132,7 @@ class ProtocolConverter(MarkdownConverter):
124
132
  return super()._as_callout(kids)
125
133
  name, title, head_rest, rest_blocks = marker
126
134
  if name in _VOTE_MARKERS:
127
- return self._vote_callout(title, kids)
135
+ return self._vote_callout(kids)
128
136
  if name in _SIGNATURE_MARKERS:
129
137
  return self._signature_callout(kids)
130
138
  factory = _PROTOCOL_CALLOUTS.get(name)
@@ -174,13 +182,21 @@ class ProtocolConverter(MarkdownConverter):
174
182
  signers.append((role.strip(), person.strip()))
175
183
  return SignatureLines(*signers)
176
184
 
177
- def _vote_callout(self, title: str, kids: list[object]) -> TeX:
178
- text = " ".join(_all_text(k) for k in kids)
185
+ def _vote_callout(self, kids: list[object]) -> TeX:
186
+ # Per source line: the tally line feeds the counts, every other line is
187
+ # kept as the box body (otherwise descriptive text would be dropped).
188
+ lines = [frag for k in kids for frag in _leaf_texts(k)]
189
+ if lines:
190
+ lines[0] = CALLOUT_RE.sub("", lines[0], count=1)
191
+ stripped = [s.strip() for s in lines]
192
+ full = " ".join(stripped)
193
+ body_lines = [s for s in stripped if s and not _is_tally_line(s)]
194
+ body = Concat(*_interleave(self.inline_text(s) for s in body_lines))
179
195
  return Vote(
180
- yes=_tally(text, "yes"),
181
- no=_tally(text, "no"),
182
- abstain=_tally(text, "abstain"),
183
- body=self.inline_text(title) if title else "",
196
+ yes=_tally(full, "yes"),
197
+ no=_tally(full, "no"),
198
+ abstain=_tally(full, "abstain"),
199
+ body=body,
184
200
  )
185
201
 
186
202
  def inline_text(self, text: str) -> TeX:
@@ -135,9 +135,9 @@ def render_protocol(text: str, *, base_level: int = 0) -> HSRTReport:
135
135
  title=_title(meta),
136
136
  data_lines=_data_lines(meta),
137
137
  # Agenda items are top-level `#` headings -> \section. In scrbook a
138
- # chapterless section would number as "0.1"; flatten it to a plain
139
- # arabic counter so TOPs read 1, 2, 3, ...
140
- user_preamble=Raw(r"\renewcommand*{\thesection}{\arabic{section}}"),
138
+ # chapterless section would number as "0.1"; number them as agenda
139
+ # items instead, so headings read "TOP 1", "TOP 2", ...
140
+ user_preamble=Raw(r"\renewcommand*{\thesection}{TOP~\arabic{section}}"),
141
141
  body=Concat(converted, *tail),
142
142
  )
143
143