Merge branch 'main' into feature/morse-new

This commit is contained in:
Tim Grelka
2024-12-11 00:48:00 +01:00
13 changed files with 206 additions and 50 deletions
View File
-8
View File
@@ -1,8 +0,0 @@
import sys
import mistletoe
from fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
if __name__ == "__main__":
with open(sys.argv[1]) as fin, open(sys.argv[2], "w") as fout:
fout.write(mistletoe.markdown(fin, FiftyOhmHtmlRenderer))
+50 -24
View File
@@ -8,14 +8,17 @@ from renderer.halfwidth_spaces import HalfwidthSpaces
from renderer.morse import Morse
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
class FiftyOhmHtmlRenderer(HtmlRenderer):
margin_anchor_id = 0
margin_id = 0
section_url = "section.html"
ref_id = 0
def __init__(self):
super().__init__(
@@ -23,12 +26,14 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
BlockComment,
SpanComment,
Quote,
Unit,
Underline,
Morse,
Tag,
HalfwidthSpaces,
NonbreakingSpaces,
NonbreakingSpacesDots,
References,
)
def render_dash(self, token):
@@ -46,6 +51,31 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
def render_underline(self, token):
return f"<u>{self.render_inner(token)}</u>"
@classmethod
def render_unit(cls, token: Unit):
unit = token.prefix + cls.convert_unit_helper(token.unit)
if token.unit in ["°", "%"]:
# Special cases with no space between value and unit.
return f"{token.value}{unit}"
else:
# Default case is rendered with a narrow no-break space.
return f"{token.value}&#8239;{unit}"
units = {
"Ohm": "Ω",
}
@classmethod
def convert_unit_helper(cls, unit: str) -> str:
"""Converts human-typable units to their preferred representation.
:param str unit: The unit to convert
"""
if unit in cls.units.keys():
return cls.units[unit]
else:
return unit
def render_thematic_break(self, token):
self.margin_anchor_id += 1
return f'<a id="margin_{self.margin_anchor_id}"></a>'
@@ -58,14 +88,14 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
for symbol in char:
result += '<span class="morse_char">\n'
if symbol == 1:
result += '▄'
result += "▄"
elif symbol == 2:
result += '▄▄▄'
result += "▄▄▄"
elif symbol == 3:
result += '&nbsp;'
result += '</span>\n'
result += '</span>\n'
result += '</span>'
result += "&nbsp;"
result += "</span>\n"
result += "</span>\n"
result += "</span>"
return result
@@ -77,7 +107,7 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
def render_tag_helper(type, content, margin_id, margin_anchor_id):
"""This function is used to render the different types of tags. It is
used in the HtmlRenderer class and also in the test class"""
return textwrap.dedent(f'''\
return textwrap.dedent(f"""\
<div class="margin {type}" id="margin_for_{margin_id}">
{content}
</div>
@@ -97,33 +127,29 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
moveFunc();
}})();
</script>
''')
""")
def render_tag(self, token):
if(token.tagtype == "latexonly"):
if token.tagtype == "latexonly":
return ""
elif(token.tagtype == "webonly"):
elif token.tagtype == "webonly":
return self.render_inner(token)
self.margin_id += 1
if(token.tagtype == "webmargin"):
if token.tagtype == "webmargin":
type = "margin"
elif(token.tagtype == "webtipp"):
type = "tipp"
elif(token.tagtype == "webindepth"):
elif token.tagtype == "webtip":
type = "tip"
elif token.tagtype == "webindepth":
type = "indepth"
else:
type = token.tagtype
return self.render_tag_helper(
type,
self.render_inner(token),
self.margin_id,
self.margin_anchor_id
type, self.render_inner(token), self.margin_id, self.margin_anchor_id
)
def render_halfwidth_spaces(self, token):
return f"{token.first}.&#8239;{token.second}."
@@ -131,8 +157,8 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
return f"{token.first}&#160;{token.second}"
def render_nonbreaking_spaces_dots(self, token):
lookup = {
"" : "",
" " : "&#160;"
}
lookup = {"": "", " ": "&#160;"}
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>'
+1 -1
View File
@@ -8,7 +8,7 @@ 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)\.")
pattern = re.compile(r"\b(z|Z|d|D)\.\s?(B|h)\.")
def __init__(self, match_object):
self.first = match_object.group(1)
+1 -1
View File
@@ -6,7 +6,7 @@ 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.
Identifies "§$number", "Abs.$number", "Klasse [A,E,N]" w/ and without space between.
"""
pattern = re.compile(r"(§|Abs\.|Klasse)\s?(\d|[NEA])")
+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)
+2 -2
View File
@@ -6,8 +6,8 @@ captures = [
"margin",
"indepth",
"webmargin",
"tipp",
"webtipp",
"tip",
"webtip",
"webindepth",
"unit",
"danger",
+55
View File
@@ -0,0 +1,55 @@
import re
from mistletoe.span_token import SpanToken
class Unit(SpanToken):
units = [
"A",
"Ah",
"A/mm²",
"baud",
"Bit",
"Bit/s",
"dB",
"dBi",
"dBm",
"dBW",
"F",
"J",
"Hz",
"H",
"cm",
"m",
"m²",
"Ohm",
"ppm",
"pps",
"s",
"V",
"W",
"Wh",
"°",
"%",
]
prefixes = ["p", "n", "μ", "m", "k", "M", "G"]
pattern = re.compile(
r"(?P<value>[0-9,]+) ?(?P<prefix>"
# Group all prefixes together in a capture group
# Empty string at end of list is required so the group always exists in the resulting match
+ "|".join(prefixes + [""])
+ ")(?P<unit>"
# Group all units together in a capture group.
+ "|".join(units)
+ r")(?!\w)"
)
value: str
prefix: str
unit: str
def __init__(self, match: re.Match):
self.value = match.group("value")
self.prefix = match.group("prefix") or ""
self.unit = match.group("unit")
+9 -4
View File
@@ -3,8 +3,13 @@ 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)
def test_halfwidth_space_html():
assertions = {
"Dies ist z.B. ein Test. D.h. hier sollten d.h. Spaces ersetzt worden sein." : "Dies ist z.&#8239;B. ein Test. D.&#8239;h. hier sollten d.&#8239;h. Spaces ersetzt worden sein.",
"Dies ist z. B. ein Test. D. h. hier sollten d. h. Spaces ersetzt worden sein." : "Dies ist z.&#8239;B. ein Test. D.&#8239;h. hier sollten d.&#8239;h. Spaces ersetzt worden sein.",
"Z. B. die D.B. wird auch ersetzt, aber das macht nix." : "Z.&#8239;B. die D.&#8239;B. wird auch ersetzt, aber das macht nix."
}
for key, value in assertions.items():
assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value)
+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)
+3 -2
View File
@@ -2,6 +2,7 @@ import mistletoe
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
def test_thematic_break_html() :
assertions = {
"---" : '<a id="margin_1"></a>\n',
@@ -17,8 +18,8 @@ def test_tag_html() :
"<margin>\nFoo\n</margin>" : FiftyOhmHtmlRenderer.render_tag_helper("margin","<p>Foo</p>",1,0)+'\n',
"<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("tipp","<p>Foo</p>",1,0)+'\n',
"<tip>\nFoo\n</tip>" : FiftyOhmHtmlRenderer.render_tag_helper("tip","<p>Foo</p>",1,0)+'\n',
"<webtip>\nFoo\n</webtip>" : FiftyOhmHtmlRenderer.render_tag_helper("tip","<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',
+45
View File
@@ -0,0 +1,45 @@
import mistletoe
import pytest
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
from .util import paragraph
@pytest.mark.html
def test_basic_units_html():
"""Test basic units: Insert non-breaking, smaller space."""
assertions = {
"1 V": "1&#8239;V",
"0,12 V": "0,12&#8239;V",
"0,75 kW": "0,75&#8239;kW",
"33 A": "33&#8239;A",
"1 Ah": "1&#8239;Ah", # Ah can be a tricky case if the RegEx is wrong, as A might match before Ah, thus rendering the output with an "A" unit
}
for input, output in assertions.items():
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)
@pytest.mark.html
def test_translated_units_html():
"""Test translated units: Replace Ohm with Ω."""
assertions = {
"50 Ohm": "50&#8239;Ω",
"100 mOhm": "100&#8239;mΩ",
}
for input, output in assertions.items():
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)
@pytest.mark.html
def test_special_units_html():
"""Test special units: Don't put space before ° and %."""
assertions = {
"100%": "100%",
"42,24°": "42,24°",
}
for input, output in assertions.items():
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)
+1 -1
View File
@@ -1,2 +1,2 @@
def paragraph(text):
return f'<p>{text}</p>\n'
return f"<p>{text}</p>\n"