Pull request #20: Feature/latex
Merge in FRAG/50ohm.de from feature/latex to main * commit 'f0a131994cccf0b4beeaf7da2057ec5ae0ad359b': feature: add latex renderer feature: add latex underline feature: add latex tag feature: add latex quote feature: add latex spaces feature: add latex dash feature: add latex comment bugfix: add missing tag names
This commit is contained in:
committed by
Tim Grelka DA2TG
commit
db02ee3ff4
@@ -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]}"
|
||||
+7
-4
@@ -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
|
||||
self.tagtype, self.children = match
|
||||
|
||||
+14
-5
@@ -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" : "<p>Bar</p>\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]
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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]
|
||||
|
||||
+44
-1
@@ -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]
|
||||
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 = {
|
||||
"<margin>\nFoo\n</margin>" : "\Margin{\nFoo\n}",
|
||||
"<danger>\nFoo\n</danger>" : "\MarginDanger{\nFoo\n}",
|
||||
"<warning>\nFoo\n</warning>" : "\MarginWarning{\nFoo\n}",
|
||||
"<attention>\nFoo\n</attention>" : "\MarginAttention{\nFoo\n}",
|
||||
"<tip>\nFoo\n</tip>" : "\MarginTip{\nFoo\n}",
|
||||
"<webtip>\nFoo\n</webtip>" : "\WebTip{\nFoo\n}",
|
||||
"<unit>\nFoo\n</unit>" : "\MarginUnit{\nFoo\n}",
|
||||
"<indepth>\nFoo\n</indepth>" : "\MarginInDepth{\nFoo\n}",
|
||||
"<webindepth>\nFoo\n</webindepth>" : "\MarginWebInDepth{\nFoo\n}",
|
||||
"<webmargin>\nFoo\n</webmargin>" : "\WebMargin{\nFoo\n}",
|
||||
"<fullwidth>\nFoo\n</fullwidth>" : "\FullWidth{\nFoo\n}",
|
||||
"<latexonly>\nFoo\n</latexonly>" : "\nFoo\n",
|
||||
"<webonly>\nFoo\n</webonly>" : "",
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion]
|
||||
|
||||
def test_thematic_break_and_tag_latex() :
|
||||
|
||||
assertions = {
|
||||
"---\n<margin>\nFoo\n</margin>" : "\Margin{\nFoo\n}",
|
||||
"---\n<margin>\nFoo\n</margin>\n<margin>\nFoo\n</margin>" : "\Margin{\nFoo\n}\Margin{\nFoo\n}",
|
||||
"---\n<margin>\nFoo\n</margin>\n---\n<margin>\nFoo\n</margin>" : "\Margin{\nFoo\n}\Margin{\nFoo\n}",
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion]
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -14,3 +15,14 @@ def test_underline_html() :
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
|
||||
def test_underline_latex() :
|
||||
|
||||
assertions = {
|
||||
"<u>Text</u>" : "\n\\underline{Text}\n",
|
||||
"<u> Text Text </u>" : "\n\\underline{ Text Text }\n",
|
||||
"<u> Text *Text* </u>" : "\n\\underline{ Text \emph{Text} }\n",
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == assertions[assertion]
|
||||
|
||||
Reference in New Issue
Block a user