diff --git a/renderer/__init__.py b/renderer/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/renderer/__main__.py b/renderer/__main__.py
deleted file mode 100644
index b8a5ddf..0000000
--- a/renderer/__main__.py
+++ /dev/null
@@ -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))
diff --git a/renderer/fifty_ohm_html_renderer.py b/renderer/fifty_ohm_html_renderer.py
index be23907..b568b0c 100644
--- a/renderer/fifty_ohm_html_renderer.py
+++ b/renderer/fifty_ohm_html_renderer.py
@@ -10,6 +10,7 @@ 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):
@@ -24,6 +25,7 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
BlockComment,
SpanComment,
Quote,
+ Unit,
Underline,
Tag,
HalfwidthSpaces,
@@ -50,6 +52,31 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
def render_underline(self, token):
return f"{self.render_inner(token)}"
+ @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} {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''
diff --git a/renderer/unit.py b/renderer/unit.py
new file mode 100644
index 0000000..4a6b9f0
--- /dev/null
+++ b/renderer/unit.py
@@ -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[0-9,]+) ?(?P"
+ # 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"
+ # 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")
diff --git a/test/test_unit.py b/test/test_unit.py
new file mode 100644
index 0000000..eb736cd
--- /dev/null
+++ b/test/test_unit.py
@@ -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 V",
+ "0,12 V": "0,12 V",
+ "0,75 kW": "0,75 kW",
+ "33 A": "33 A",
+ "1 Ah": "1 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 Ω",
+ "100 mOhm": "100 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)
diff --git a/test/util.py b/test/util.py
index f30aa79..a86b9eb 100644
--- a/test/util.py
+++ b/test/util.py
@@ -1,2 +1,2 @@
-def paragraph(text) :
- return f'{text}
\n'
\ No newline at end of file
+def paragraph(text):
+ return f"{text}
\n"