From 26fa657e4a92a260aa03ca73ceda4fdc6aa30f13 Mon Sep 17 00:00:00 2001 From: Tim Grelka Date: Sun, 8 Dec 2024 11:33:21 +0100 Subject: [PATCH] feat: render units with non-breaking space --- renderer/fifty_ohm_html_renderer.py | 49 ++++++++++++++++++++++++--- renderer/unit.py | 51 +++++++++++++++++++++++++++++ test/test_unit_token.py | 18 ++++++++++ 3 files changed, 114 insertions(+), 4 deletions(-) create mode 100644 renderer/unit.py create mode 100644 test/test_unit_token.py diff --git a/renderer/fifty_ohm_html_renderer.py b/renderer/fifty_ohm_html_renderer.py index fa6a6ab..ed2f077 100644 --- a/renderer/fifty_ohm_html_renderer.py +++ b/renderer/fifty_ohm_html_renderer.py @@ -1,12 +1,45 @@ from mistletoe import HtmlRenderer -from renderer.comment import Comment -from renderer.quote import Quote +from .comment import Comment +from .unit import Unit +from .quote import Quote + + +units = { + "A": "A", + "Ah": "Ah", + "A/mm²": "A/mm²", + "baud": "baud", + "Bit": "Bit", + "Bit/s": "Bit/s", + "dB": "dB", + "dBi": "dBi", + "dBm": "dBm", + "dBW": "dBW", + "F": "F", + "J": "J", + "Hz": "Hz", + "H": "H", + "cm": "cm", + "m": "m", + "m²": "m²", + "Ohm": "Ω", + "ppm": "ppm", + "pps": "pps", + "s": "s", + "V": "V", + "W": "W", + "Wh": "Wh", + "°": "°", + "%": "%", +} + +no_space_units = ["°", "%"] class FiftyOhmHtmlRenderer(HtmlRenderer): def __init__(self): - super().__init__(Comment, Quote) + super().__init__(Comment, Unit, Quote) def render_comment(): return None @@ -15,4 +48,12 @@ class FiftyOhmHtmlRenderer(HtmlRenderer): return f"„{self.render_inner(token)}“" def render_underline(self, token): - return f"{self.render_inner(token)}" \ No newline at end of file + return f"{self.render_inner(token)}" + + @staticmethod + def render_unit(token): + unit = token.prefix + units[token.unit] + if token.unit in no_space_units: + return f"{token.value}{unit}" + else: + return f"{token.value} {unit}" diff --git a/renderer/unit.py b/renderer/unit.py new file mode 100644 index 0000000..7364ff0 --- /dev/null +++ b/renderer/unit.py @@ -0,0 +1,51 @@ +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"([0-9,]+) ?(" + # 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 + [""]) + + ")(" + # Group all units together in a capture group. + + "|".join(units) + + r")(?!\w)" + ) + + def __init__(self, match): + self.value = match.group(1) + self.prefix = match.group(2) + self.unit = match.group(3) diff --git a/test/test_unit_token.py b/test/test_unit_token.py new file mode 100644 index 0000000..47c929e --- /dev/null +++ b/test/test_unit_token.py @@ -0,0 +1,18 @@ +import mistletoe + +from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer + +from .util import paragraph + + +def test_unit_html(): + assertions = { + "0,1 V": "0,1 V", + "33 A": "33 A", + "1 Ah": "1 Ah", + "100 mOhm": "100 mΩ", + "25 Ohm": "25 Ω", + } + + for input, output in assertions.items(): + assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)