diff --git a/renderer/fifty_ohm_latex_renderer.py b/renderer/fifty_ohm_latex_renderer.py new file mode 100644 index 0000000..5e55998 --- /dev/null +++ b/renderer/fifty_ohm_latex_renderer.py @@ -0,0 +1,97 @@ +from mistletoe.latex_renderer import LaTeXRenderer + +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.tag import Tag +from renderer.underline import Underline + + +class FiftyOhmLaTeXRenderer(LaTeXRenderer): + + def __init__(self): + super().__init__( + Dash, + BlockComment, + SpanComment, + Quote, + Underline, + Tag, + HalfwidthSpaces, + NonbreakingSpaces, + NonbreakingSpacesDots, + ) + + def render_document(self, token): + self.footnotes.update(token.footnotes) + return self.render_inner(token) + + def render_dash(self, token): + return " -- " + + def render_block_comment(self, token): + return "" # TODO propagate comments to the LaTeX document + + def render_span_comment(self, token): + return "" # TODO propagate comments to the LaTeX document + + def render_quote(self, token): + return fr"\enquote{{{self.render_inner(token)}}}" + + def render_emphasis(self, token): + return fr"\emph{{{self.render_inner(token)}}}" + + def render_underline(self, token): + return fr"\underline{{{self.render_inner(token)}}}" + + def render_thematic_break(self, token): + return "" + + def render_tag(self, token): # noqa: C901 + + tagtype = None + + match token.tagtype: + case "danger": + tagtype = "MarginDanger" + case "warning": + tagtype = "MarginWarning" + case "attention": + tagtype = "MarginAttention" + case "tip": + tagtype = "MarginTip" + case "webtip": + tagtype = "WebTip" + case "unit": + tagtype = "MarginUnit" + case "indepth": + tagtype = "MarginInDepth" + case "webindepth": + tagtype = "MarginWebInDepth" + case "webmargin": + tagtype = "WebMargin" + case "fullwidth": + tagtype = "FullWidth" + case "latexonly": + return self.render_inner(token) + case "webonly": + return "" + case _: + tagtype = "Margin" + + return fr"\{tagtype}{{{self.render_inner(token)}}}" + + 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]}" \ No newline at end of file diff --git a/renderer/tag.py b/renderer/tag.py index 82dd528..749a1bb 100644 --- a/renderer/tag.py +++ b/renderer/tag.py @@ -6,20 +6,23 @@ captures = [ "margin", "indepth", "webmargin", + "warning", + "attention", "tip", "webtip", "webindepth", + "fullwidth", "unit", "danger", "webonly", "latexonly", ] -class Tag(BlockToken): +class Tag(BlockToken): @staticmethod def start(line): - return re.match(r"^\s*<("+"|".join(captures)+r")+>", line) + return re.match(r"^\s*<(" + "|".join(captures) + r")+>", line) @classmethod def read(cls, lines): @@ -31,9 +34,9 @@ class Tag(BlockToken): for line in lines: if line.startswith(f"{tagtype}>"): break - else : + else: child_lines.append(line) return tagtype, tokenize(child_lines) def __init__(self, match): - self.tagtype, self.children = match \ No newline at end of file + self.tagtype, self.children = match diff --git a/test/test_comment.py b/test/test_comment.py index 9abf3ce..c8ee2db 100644 --- a/test/test_comment.py +++ b/test/test_comment.py @@ -1,13 +1,10 @@ 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 +from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer -def test_comment_html(capsys) : +def test_comment_html() : assertions = { "%Comment\nBar" : "
Bar
\n", @@ -18,3 +15,15 @@ def test_comment_html(capsys) : for assertion in assertions: assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion] + +def test_comment_latex() : + + assertions = { + "%Comment\nBar" : "\nBar\n", + # TODO: This test is not working as expected. The comment should be removed + #"%Comment\n" : "a", + "Foo\n%Comment\nBar" : "\nFoo\nBar\n", + } + + for assertion in assertions: + assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion] diff --git a/test/test_dash.py b/test/test_dash.py index 2289b0c..7fa363e 100644 --- a/test/test_dash.py +++ b/test/test_dash.py @@ -1,6 +1,7 @@ import mistletoe from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer +from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer from test.util import paragraph @@ -12,3 +13,12 @@ def test_dash_html() : for assertion in assertions: assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion]) + +def test_dash_latex() : + + assertions = { + "Foo - Bar" : "\nFoo -- Bar\n", + } + + for assertion in assertions: + assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion] diff --git a/test/test_halfwidth_spaces.py b/test/test_halfwidth_spaces.py index 1d3c4f9..56a0d46 100644 --- a/test/test_halfwidth_spaces.py +++ b/test/test_halfwidth_spaces.py @@ -1,15 +1,19 @@ import mistletoe from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer +from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer from test.util import paragraph 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. B. ein Test. D. h. hier sollten d. h. Spaces ersetzt worden sein.", - "Dies ist z. B. ein Test. D. h. hier sollten d. h. Spaces ersetzt worden sein." : "Dies ist z. B. ein Test. D. h. hier sollten d. h. Spaces ersetzt worden sein.", - "Z. B. die D.B. wird auch ersetzt, aber das macht nix." : "Z. B. die D. B. wird auch ersetzt, aber das macht nix." - } - - for key, value in assertions.items(): - assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value) + input = "Dies ist z.B. ein Test. D.h. hier sollten d.h. Spaces ersetzt worden sein." + target = "Dies ist z. B. ein Test. D. h. hier sollten d. h. Spaces ersetzt worden sein." + + assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target) + + +def test_halfwidth_space_latex(): + input = "Dies ist z.B. ein Test. D.h. hier sollten d.h. Spaces ersetzt worden sein." + target = "\nDies ist z.\,B. ein Test. D.\,h. hier sollten d.\,h. Spaces ersetzt worden sein.\n" + + assert mistletoe.markdown(input, FiftyOhmLaTeXRenderer) == target diff --git a/test/test_nonbreaking_spaces.py b/test/test_nonbreaking_spaces.py index 88fb8cb..814662e 100644 --- a/test/test_nonbreaking_spaces.py +++ b/test/test_nonbreaking_spaces.py @@ -1,8 +1,10 @@ import mistletoe from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer +from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer 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 § 2 vielleicht aber auch § 3." @@ -33,4 +35,33 @@ def test_class_html(): assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target) +def test_paragraph_latex(): + input = "Der Test befindet sich unter §2 vielleicht aber auch § 3." + target = "\nDer Test befindet sich unter §~2 vielleicht aber auch §~3.\n" + + assert mistletoe.markdown(input, FiftyOhmLaTeXRenderer) == target + +def test_three_points_latex(): + assertions = { + "Heute hatte ich ... zum Mittagessen." : "\nHeute hatte ich~...~zum Mittagessen.\n", + "Niemals hätte ich gedacht, dass...ich ...nicht kann." : "\nNiemals hätte ich gedacht, dass...ich~...nicht kann.\n", + "Oh nein ...ein Pinguin." : "\nOh nein~...ein Pinguin.\n", + "Haha .. . Hahaha" : "\nHaha .. . Hahaha\n" + } + + for key, value in assertions.items(): + assert mistletoe.markdown(key, FiftyOhmLaTeXRenderer) == value + +def test_absatz_latex(): + input = "Der Test befindet sich unter Abs.2 vielleicht aber auch Abs. 3." + target = "\nDer Test befindet sich unter Abs.~2 vielleicht aber auch Abs.~3.\n" + + assert mistletoe.markdown(input, FiftyOhmLaTeXRenderer) == target + +def test_class_latex(): + input = "Ich lerne für Klasse A, Klasse E und Klasse N." + target = "\nIch lerne für Klasse~A, Klasse~E und Klasse~N.\n" + + assert mistletoe.markdown(input, FiftyOhmLaTeXRenderer) == target + diff --git a/test/test_quote.py b/test/test_quote.py index e660c7b..deb119a 100644 --- a/test/test_quote.py +++ b/test/test_quote.py @@ -1,6 +1,7 @@ import mistletoe from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer +from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer from test.util import paragraph @@ -17,3 +18,17 @@ def test_quote_html() : for assertion in assertions: assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion]) + +def test_quote_latex() : + + assertions = { + '"quote"' : '\n\enquote{quote}\n', + '" quote "' : '\n\enquote{ quote }\n', + '"quote" "' : '\n\enquote{quote} "\n', + '"quo te1" filltext "qu ot e2"' : '\n\enquote{quo te1} filltext \enquote{qu ot e2}\n', + '"quo *te1*" filltext "qu ot e2"' : '\n\enquote{quo \emph{te1}} filltext \enquote{qu ot e2}\n', + '""' : '\n""\n', + } + + for assertion in assertions: + assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion] diff --git a/test/test_tag.py b/test/test_tag.py index e8c282f..ca7eb26 100644 --- a/test/test_tag.py +++ b/test/test_tag.py @@ -1,6 +1,8 @@ import mistletoe from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer +from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer + def test_thematic_break_html() : @@ -39,4 +41,45 @@ def test_thematic_break_and_tag_html() : } for assertion in assertions: - assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion] \ No newline at end of file + assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion] + +def test_thematic_break_latex() : + assertions = { + "---" : '', + "---\n---" : '', + } + + for assertion in assertions: + assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion] + +def test_tag_latex() : + + assertions = { + "