Merge branch 'main' into feat/improve-reference-counting
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
import sys
|
||||
|
||||
from mistletoe import cli
|
||||
|
||||
|
||||
def main() -> None:
|
||||
cli.main(sys.argv[1:])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,3 +1,5 @@
|
||||
import re
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from mistletoe import HtmlRenderer
|
||||
|
||||
@@ -7,6 +9,7 @@ from .document import Document
|
||||
from .formula import Formula
|
||||
from .halfwidth_spaces import HalfwidthSpaces
|
||||
from .include import Include
|
||||
from .index import Index
|
||||
from .morse import Morse
|
||||
from .nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots
|
||||
from .photo import Photo
|
||||
@@ -71,6 +74,7 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
Qso,
|
||||
Include,
|
||||
Formula,
|
||||
Index,
|
||||
*extras,
|
||||
**kwargs,
|
||||
)
|
||||
@@ -95,6 +99,9 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
# Single unified counter for all figure types (pictures, photos, tables)
|
||||
self.figure_counter = 0
|
||||
|
||||
# Keep track of index ids already emitted in this document.
|
||||
self.index_anchor_ids = set()
|
||||
|
||||
def get_reference_label(self, marker: str):
|
||||
if marker in self.references:
|
||||
return f"{self.edition}-{self.chapter}.{self.section}.{self.references[marker]}", True
|
||||
@@ -290,7 +297,7 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
def render_photo_helper(id, ref, text, number, alt_text):
|
||||
return f"""
|
||||
<figure class="photo" id="ref_{ref}" name="{ref}">
|
||||
<img src="photos/{id}.jpg" alt="{alt_text}">
|
||||
<img src="photos/{id}.png" alt="{alt_text}">
|
||||
<figcaption>Abbildung {number}: {text}</figcaption>
|
||||
</figure>
|
||||
"""
|
||||
@@ -345,3 +352,25 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
|
||||
def render_formula(self, token):
|
||||
return f"\n$${token.formula}$$\n"
|
||||
|
||||
@staticmethod
|
||||
def _normalize_index_part(value: str) -> str:
|
||||
normalized = value.strip().lower()
|
||||
normalized = re.sub(r"\s+", "_", normalized)
|
||||
normalized = re.sub(r"[^\w]", "_", normalized)
|
||||
normalized = re.sub(r"_+", "_", normalized).strip("_")
|
||||
return normalized or "index"
|
||||
|
||||
def render_index(self, token):
|
||||
first = self._normalize_index_part(token.first)
|
||||
if token.second:
|
||||
second = self._normalize_index_part(token.second)
|
||||
span_id = f"index_{first}__{second}"
|
||||
else:
|
||||
span_id = f"index_{first}"
|
||||
|
||||
if span_id in self.index_anchor_ids:
|
||||
return ""
|
||||
|
||||
self.index_anchor_ids.add(span_id)
|
||||
return f'<span id="{span_id}" class="index-anchor" aria-hidden="true"></span>'
|
||||
|
||||
@@ -3,6 +3,7 @@ from mistletoe.latex_renderer import LaTeXRenderer
|
||||
from .comment import BlockComment
|
||||
from .dash import Dash
|
||||
from .halfwidth_spaces import HalfwidthSpaces
|
||||
from .index import Index
|
||||
from .nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots
|
||||
from .photo import Photo
|
||||
from .picture import Picture
|
||||
@@ -32,6 +33,7 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
|
||||
TableRow,
|
||||
TableHeader,
|
||||
TableCell,
|
||||
Index,
|
||||
)
|
||||
self.question_renderer = question_renderer
|
||||
|
||||
@@ -148,3 +150,9 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
|
||||
|
||||
def render_table_cell(self, token: TableCell):
|
||||
return self.render_inner(token)
|
||||
|
||||
def render_index(self, token):
|
||||
if token.second:
|
||||
return f"\\index{{{token.first}!{token.second}}}"
|
||||
else:
|
||||
return f"\\index{{{token.first}}}"
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import re
|
||||
|
||||
from mistletoe.span_token import SpanToken
|
||||
|
||||
|
||||
class Index(SpanToken):
|
||||
"""
|
||||
Resolve index commands
|
||||
Identifies "[index:term:subterm]" or "[index:term]"
|
||||
"""
|
||||
|
||||
pattern = re.compile(r"[ \t]*\[index:([^:\]\s](?:[^:\]\s]| )*)(?::([^:\]\s](?:[^:\]\s]| )*))?\]")
|
||||
|
||||
def __init__(self, match_object):
|
||||
self.first = match_object.group(1)
|
||||
self.second = match_object.group(2)
|
||||
@@ -8,12 +8,12 @@ class Question(BlockToken):
|
||||
def start(line):
|
||||
# Search for:
|
||||
# [question:123]
|
||||
return re.match(r"^\s*\[question:\d+\]", line)
|
||||
return re.match(r"^\s*\[question:[\w\d]+\]", line)
|
||||
|
||||
@classmethod
|
||||
def read(cls, lines):
|
||||
first_line = next(lines)
|
||||
question_number = re.match(r"^\s*\[question:(\d+)\]", first_line).group(1)
|
||||
question_number = re.match(r"^\s*\[question:([\w\d]+)\]", first_line).group(1)
|
||||
return question_number
|
||||
|
||||
@classmethod
|
||||
|
||||
Reference in New Issue
Block a user