diff --git a/renderer/document.py b/renderer/document.py
new file mode 100644
index 0000000..71cad24
--- /dev/null
+++ b/renderer/document.py
@@ -0,0 +1,7 @@
+import mistletoe
+
+
+class Document(mistletoe.Document):
+ # margin_count = 0
+ # margin_anchor_count = 0
+ references = {}
diff --git a/renderer/fifty_ohm_html_renderer.py b/renderer/fifty_ohm_html_renderer.py
index 2a54114..d13f960 100644
--- a/renderer/fifty_ohm_html_renderer.py
+++ b/renderer/fifty_ohm_html_renderer.py
@@ -1,8 +1,9 @@
from jinja2 import Environment, FileSystemLoader
-from mistletoe import Document, HtmlRenderer
+from mistletoe import HtmlRenderer
from .comment import BlockComment
from .dash import Dash
+from .document import Document
from .formula import Formula
from .halfwidth_spaces import HalfwidthSpaces
from .include import Include
@@ -25,8 +26,14 @@ table_alignment = {"l": "left", "c": "center", "r": "right"}
class FiftyOhmHtmlRenderer(HtmlRenderer):
margin_anchor_id = 0
margin_id = 0
- section_url = "section.html"
- ref_id = 0
+
+ edition: str = None
+ chapter: str = None
+ section: str = None
+ section_url: str = None
+
+ # TODO: Add type
+ references = {}
def __init__(
self,
@@ -88,6 +95,12 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
# Single unified counter for all figure types (pictures, photos, tables)
self.figure_counter = 0
+ def get_reference_label(self, marker: str):
+ if marker in self.references:
+ return f"{self.edition}-{self.chapter}.{self.section}.{self.references[marker]}", True
+ else:
+ return marker, False
+
def render_dash(self, token):
return " – "
@@ -249,6 +262,7 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
return self.question_renderer(token.question_number)
def render_document(self, token: Document) -> str:
+ self.references.update(token.references)
self.footnotes.update(token.footnotes)
inner = self.render_inner(token, "\n")
return f"{inner}\n" if inner else ""
@@ -257,21 +271,20 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
# Filter out None values, so block tokens can return None to not be rendered.
return base.join(filter(lambda x: x is not None, [self.render(child) for child in token.children]))
- @staticmethod
- def render_picture_helper(id, ref, text, number, alt_text):
- return f"""
-
-
- Abbildung {number}: {text}
-
- """
+ def render_picture_helper(self, id, marker, text, label, alt_text):
+ return (
+ f'\n'
+ f'
\n'
+ f" Abbildung {self.get_reference_label(marker)}: {text}\n"
+ "\n"
+ )
def render_picture(self, token):
alt_text = ""
if self.picture_handler is not None:
alt_text = self.picture_handler(token.id)
- return self.render_picture_helper(token.id, token.ref, token.text, token.number, alt_text)
+ return self.render_picture_helper(token.id, token.marker, token.text, token.label, alt_text)
@staticmethod
def render_photo_helper(id, ref, text, number, alt_text):
diff --git a/renderer/picture.py b/renderer/picture.py
index 0477185..b645126 100644
--- a/renderer/picture.py
+++ b/renderer/picture.py
@@ -1,19 +1,33 @@
import re
-from mistletoe.span_token import SpanToken
+from mistletoe.block_tokenizer import FileWrapper
+
+from renderer.referenced_token import ReferencedToken
-class Picture(SpanToken):
+class Picture(ReferencedToken):
"""
Span token for pictures.
Example: [picture:727:amplitude_periode_halbwellen:Positive und negative Halbwellen einer Sinusschwingung]
"""
- parse_inner = False
- pattern = re.compile(r"\[picture:(\d+):(.+):(.+)\]")
+ pattern = re.compile(r"^\[picture:(?P\d+):(?P[^:\]]+):(?P[^:\]]+)\]$")
- def __init__(self, match_object):
- self.id = match_object.group(1)
- self.ref = match_object.group(2)
- self.text = match_object.group(3)
- self.number = "TODO"
+ @classmethod
+ def start(cls, line: str):
+ return cls.pattern.match(line.strip()) is not None
+
+ @classmethod
+ def check_interrupts_paragraph(cls, lines: FileWrapper):
+ return cls.pattern.match(lines.peek())
+
+ @classmethod
+ def read(cls, lines: FileWrapper):
+ match = cls.pattern.match(next(lines))
+ return match.group("id"), match.group("marker"), match.group("text")
+
+ def __init__(self, match):
+ id, marker, text = match
+ super().__init__(marker)
+ self.id = id
+ self.text = text
diff --git a/renderer/referenced_token.py b/renderer/referenced_token.py
new file mode 100644
index 0000000..1f07b46
--- /dev/null
+++ b/renderer/referenced_token.py
@@ -0,0 +1,17 @@
+import mistletoe.token
+from mistletoe.block_token import BlockToken
+
+
+class ReferencedToken(BlockToken):
+ line_number: int = -1
+ marker: str = None
+ label: str = None
+
+ def __init__(self, marker: str):
+ self.marker = marker
+
+ if marker not in mistletoe.token._root_node.references:
+ self.label = len(mistletoe.token._root_node.references) + 1
+ mistletoe.token._root_node.references[marker] = self.label
+ else:
+ self.label = mistletoe._root_node.references[marker]
diff --git a/test/test_picture.py b/test/test_picture.py
index d9bb240..70b3bc3 100644
--- a/test/test_picture.py
+++ b/test/test_picture.py
@@ -1,19 +1,18 @@
import mistletoe
import pytest
+from renderer.document import Document
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
-from test.util import paragraph
@pytest.mark.html
def test_picture_html():
- assertions = {
- "[picture:0:abc:Text]": FiftyOhmHtmlRenderer.render_picture_helper("0", "abc", "Text", "TODO", ""),
- }
+ assertions = {"[picture:0:abc:Text]": ("0", "abc", "Text", "A-5.7.1", "")}
- for assertion in assertions:
- assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
+ with FiftyOhmHtmlRenderer(edition="A", chapter="5", section="7") as renderer:
+ for assertion in assertions:
+ assert renderer.render(Document(assertion)) == renderer.render_picture_helper(*assertions[assertion]) + "\n"
@pytest.mark.latex