Merge branch 'main' into feature/unit-html-renderer

This commit is contained in:
Tim Grelka
2024-12-08 15:59:52 +01:00
15 changed files with 263 additions and 13 deletions
+11
View File
@@ -0,0 +1,11 @@
kind: pipeline
type: docker
name: default
steps:
- name: 50ohm.de
image: ghcr.io/astral-sh/uv:python3.12-bookworm
environment:
commands:
- uv pip install --system --break-system-packages --requirements requirements.txt
- cd test && pytest --junitxml=./test-reports/junit.xml
+11 -1
View File
@@ -1,7 +1,17 @@
import re
from mistletoe.block_token import BlockToken
from mistletoe.span_token import SpanToken
class Comment(BlockToken):
class SpanComment(SpanToken):
"""
Coment span token (% Eiersalat).
Identifies a comment in text.
"""
pattern = re.compile(r'(%.*\n?)')
class BlockComment(BlockToken):
@staticmethod
def start(line):
return line.startswith("%")
+11
View File
@@ -0,0 +1,11 @@
import re
from mistletoe.span_token import SpanToken
class Dash(SpanToken):
"""
Dash span token ( - ).
Identifies a dash in a text.
"""
pattern = re.compile(r'(\s-\s)')
+49 -10
View File
@@ -2,11 +2,15 @@ import textwrap
from mistletoe import HtmlRenderer
from .comment import Comment
from .quote import Quote
from .tag import Tag
from .underline import Underline
from .unit import Unit
from renderer.comment import BlockComment, SpanComment
from renderer.dash import Dash
from renderer.halfwidth_spaces import HalfwidthSpaces
from renderer.nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots
from renderer.quote import Quote
from renderer.references import References
from renderer.tag import Tag
from renderer.underline import Underline
from renderer.unit import Unit
units = {
"A": "A",
@@ -26,7 +30,6 @@ units = {
"cm": "cm",
"m": "m",
"m²": "m²",
"Ohm": "Ω",
"ppm": "ppm",
"pps": "pps",
"s": "s",
@@ -43,12 +46,35 @@ no_space_units = ["°", "%"]
class FiftyOhmHtmlRenderer(HtmlRenderer):
margin_anchor_id = 0
margin_id = 0
section_url = "section.html"
ref_id = 0
def __init__(self):
super().__init__(Comment, Unit, Quote, Underline, Tag)
super().__init__(
Dash,
BlockComment,
SpanComment,
Quote,
Unit,
Underline,
Tag,
HalfwidthSpaces,
NonbreakingSpaces,
NonbreakingSpacesDots,
HalfwidthSpaces,
NonbreakingSpaces,
NonbreakingSpacesDots,
References,
)
def render_comment():
return None
def render_dash(self, token):
return " – "
def render_block_comment(self, token):
return ""
def render_span_comment(self, token):
return ""
def render_quote(self, token):
return f"„{self.render_inner(token)}“"
@@ -104,7 +130,7 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
if token.tagtype == "webmargin":
type = "margin"
elif token.tagtype == "webtip":
elif token.tagtype == "webtipp":
type = "tipp"
elif token.tagtype == "webindepth":
type = "indepth"
@@ -114,3 +140,16 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
return self.render_tag_helper(
type, self.render_inner(token), self.margin_id, self.margin_anchor_id
)
def render_halfwidth_spaces(self, token):
return f"{token.first}. {token.second}."
def render_nonbreaking_spaces(self, token):
return f"{token.first} {token.second}"
def render_nonbreaking_spaces_dots(self, token):
lookup = {"": "", " ": " "}
return f"{lookup[token.first]}{token.second}{lookup[token.third]}"
def render_references(self, token):
return f'<a href="{self.section_url}#ref_{token.first}" onclick="highlightRef(\'{token.first}\');">{self.ref_id}</a>'
+18
View File
@@ -0,0 +1,18 @@
import re
from mistletoe.span_token import SpanToken
class HalfwidthSpaces(SpanToken):
"""
Insert halfwidth space into span token (Z. B.)
Identifies "z.B.", "d.h." and "D.h." with and without space in between.
"""
pattern = re.compile(r"\b(z|d|D)\.(B|h)\.")
def __init__(self, match_object):
self.first = match_object.group(1)
self.second = match_object.group(2)
+30
View File
@@ -0,0 +1,30 @@
import re
from mistletoe.span_token import SpanToken
class NonbreakingSpaces(SpanToken):
"""
Insert unbreakable space into span token (§ 3)
Identifies "§$number", "Abs.$number", "Klasse [A,E,N]" w/ and w\ space between.
"""
pattern = re.compile(r"(§|Abs\.|Klasse)\s?(\d|[NEA])")
def __init__(self, match_object):
self.first = match_object.group(1)
self.second = match_object.group(2)
class NonbreakingSpacesDots(SpanToken):
"""
Insert unbreakable space before and after "..." if there is a space
Identifies "..." with leading and/or trailing space
"""
pattern = re.compile(r"(\s?)(\.\.\.)(\s?)")
def __init__(self, match_object):
self.first = match_object.group(1)
self.second = match_object.group(2)
self.third = match_object.group(3)
+15
View File
@@ -0,0 +1,15 @@
import re
from mistletoe.span_token import SpanToken
class References(SpanToken):
"""
Resolve references for html
Identifies "[ref:$]"
"""
pattern = re.compile(r"\[ref\:(\S+)\]")
def __init__(self, match_object):
self.first = match_object.group(1)
+13 -1
View File
@@ -2,12 +2,24 @@ import re
from mistletoe.block_token import BlockToken, tokenize
captures = [
"margin",
"indepth",
"webmargin",
"tipp",
"webtipp",
"webindepth",
"unit",
"danger",
"webonly",
"latexonly",
]
class Tag(BlockToken):
@staticmethod
def start(line):
return re.match(r"^\s*<[^>]+>", line)
return re.match(r"^\s*<("+"|".join(captures)+r")+>", line)
@classmethod
def read(cls, lines):
+7
View File
@@ -0,0 +1,7 @@
coverage==7.6.9
iniconfig==2.0.0
mistletoe==1.4.0
packaging==24.2
pluggy==1.5.0
pytest==8.3.4
pytest-cov==6.0.0
+20
View File
@@ -0,0 +1,20 @@
import mistletoe
import pytest
from mistletoe.ast_renderer import AstRenderer
from renderer.comment import BlockComment, SpanComment
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from test.util import paragraph
def test_comment_html(capsys) :
assertions = {
"%Comment\nBar" : "<p>Bar</p>\n",
# TODO: This test is not working as expected. The comment should be removed
#"%Comment\n" : "a",
"Foo\n%Comment\nBar" : "<p>Foo\nBar</p>\n",
}
for assertion in assertions:
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
+14
View File
@@ -0,0 +1,14 @@
import mistletoe
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from test.util import paragraph
def test_dash_html() :
assertions = {
"Foo - Bar" : "Foo &ndash; Bar",
}
for assertion in assertions:
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
+10
View File
@@ -0,0 +1,10 @@
import mistletoe
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from test.util import paragraph
def test_halfwidth_space_html():
input = "Dies ist z.B. ein Test. D.h. hier sollten d.h. Spaces ersetzt worden sein."
target = "Dies ist z.&#8239;B. ein Test. D.&#8239;h. hier sollten d.&#8239;h. Spaces ersetzt worden sein."
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
+36
View File
@@ -0,0 +1,36 @@
import mistletoe
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from test.util import paragraph
def test_paragraph_html():
input = "Der Test befindet sich unter §2 vielleicht aber auch § 3."
target = "Der Test befindet sich unter §&#160;2 vielleicht aber auch §&#160;3."
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
def test_three_points_html():
assertions = {
"Heute hatte ich ... zum Mittagessen." : "Heute hatte ich&#160;...&#160;zum Mittagessen.",
"Niemals hätte ich gedacht, dass...ich ...nicht kann." : "Niemals hätte ich gedacht, dass...ich&#160;...nicht kann.",
"Oh nein ...ein Pinguin." : "Oh nein&#160;...ein Pinguin.",
"Haha .. . Hahaha" : "Haha .. . Hahaha"
}
for key, value in assertions.items():
assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value)
def test_absatz_html():
input = "Der Test befindet sich unter Abs.2 vielleicht aber auch Abs. 3."
target = "Der Test befindet sich unter Abs.&#160;2 vielleicht aber auch Abs.&#160;3."
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
def test_class_html():
input = "Ich lerne für Klasse A, Klasse E und Klasse N."
target = "Ich lerne für Klasse&#160;A, Klasse&#160;E und Klasse&#160;N."
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
+17
View File
@@ -0,0 +1,17 @@
import mistletoe
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from test.util import paragraph
def test_references_html():
# Right now this tests only the default values.
# The correct behavior can be tested when the information is added to the renderer class
assertions = {
"[ref:e_oszilloskop_bildschirmfoto_sinus]": '<a href="section.html#ref_e_oszilloskop_bildschirmfoto_sinus" onclick="highlightRef(\'e_oszilloskop_bildschirmfoto_sinus\');">0</a>',
"[ref:n_rst_r]": '<a href="section.html#ref_n_rst_r" onclick="highlightRef(\'n_rst_r\');">0</a>',
"[ref:Uuuuuh]": '<a href="section.html#ref_Uuuuuh" onclick="highlightRef(\'Uuuuuh\');">0</a>', # Test the default parameters
}
for key, value in assertions.items():
assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value)
+1 -1
View File
@@ -18,7 +18,7 @@ def test_tag_html() :
"<indepth>\nFoo\n</indepth>" : FiftyOhmHtmlRenderer.render_tag_helper("indepth","<p>Foo</p>",1,0)+'\n',
"<webmargin>\nFoo\n</webmargin>" : FiftyOhmHtmlRenderer.render_tag_helper("margin","<p>Foo</p>",1,0)+'\n',
"<tipp>\nFoo\n</tipp>" : FiftyOhmHtmlRenderer.render_tag_helper("tipp","<p>Foo</p>",1,0)+'\n',
"<webtipp>\nFoo\n</webtipp>" : FiftyOhmHtmlRenderer.render_tag_helper("webtipp","<p>Foo</p>",1,0)+'\n',
"<webtipp>\nFoo\n</webtipp>" : FiftyOhmHtmlRenderer.render_tag_helper("tipp","<p>Foo</p>",1,0)+'\n',
"<webindepth>\nFoo\n</webindepth>" : FiftyOhmHtmlRenderer.render_tag_helper("indepth","<p>Foo</p>",1,0)+'\n',
"<unit>\nFoo\n</unit>" : FiftyOhmHtmlRenderer.render_tag_helper("unit","<p>Foo</p>",1,0)+'\n',
"<danger>\nFoo\n</danger>" : FiftyOhmHtmlRenderer.render_tag_helper("danger","<p>Foo</p>",1,0)+'\n',