Merge remote-tracking branch 'origin/main' into feature--member-registration
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import mistletoe
|
||||
|
||||
|
||||
class Document(mistletoe.Document):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# references must exist before super().__init__ tokenizes the lines,
|
||||
# since ReferencedToken reads it from _root_node during tokenization.
|
||||
self.references: dict[str, str] = {}
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -1,22 +1,22 @@
|
||||
import re
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from mistletoe import Document, HtmlRenderer
|
||||
from mistletoe import HtmlRenderer
|
||||
|
||||
from .comment import BlockComment
|
||||
from .dash import Dash
|
||||
from .document import Document
|
||||
from .formula import Formula
|
||||
from .halfwidth_spaces import HalfwidthSpaces
|
||||
from .image import Image
|
||||
from .include import Include
|
||||
from .index import Index
|
||||
from .morse import Morse
|
||||
from .nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots
|
||||
from .photo import Photo
|
||||
from .picture import Picture
|
||||
from .qso import Qso
|
||||
from .question import Question
|
||||
from .quote import Quote
|
||||
from .references import References
|
||||
from .reference import Reference
|
||||
from .table import Table, TableBody, TableCell, TableHeader, TableRow
|
||||
from .tag import Tag
|
||||
from .underline import Underline
|
||||
@@ -28,8 +28,6 @@ table_alignment = {"l": "left", "c": "center", "r": "right"}
|
||||
class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
margin_anchor_id = 0
|
||||
margin_id = 0
|
||||
section_url = "section.html"
|
||||
ref_id = 0
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -55,10 +53,9 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
HalfwidthSpaces,
|
||||
NonbreakingSpaces,
|
||||
NonbreakingSpacesDots,
|
||||
References,
|
||||
Reference,
|
||||
Question,
|
||||
Picture,
|
||||
Photo,
|
||||
Image,
|
||||
Table,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
@@ -83,18 +80,22 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
self.section = section
|
||||
|
||||
# Set section URL if provided, otherwise use default
|
||||
if section_url is not None:
|
||||
self.section_url = section_url
|
||||
self.section_url = section_url if section_url is not None else "section.html"
|
||||
|
||||
# Figure map: stores ref -> hierarchical number mapping
|
||||
self.figure_map = {}
|
||||
|
||||
# Single unified counter for all figure types (pictures, photos, tables)
|
||||
self.figure_counter = 0
|
||||
self.references: dict[str, str] = {}
|
||||
|
||||
# Keep track of index ids already emitted in this document.
|
||||
self.index_anchor_ids = set()
|
||||
|
||||
def _format_reference_label(self, marker: str):
|
||||
if marker in self.references:
|
||||
label = self.references[marker]
|
||||
if self.edition and self.chapter and self.section:
|
||||
label = f"{self.edition}-{self.chapter}.{self.section}.{label}"
|
||||
return label
|
||||
else:
|
||||
return None
|
||||
|
||||
def render_dash(self, token):
|
||||
return " – "
|
||||
|
||||
@@ -209,53 +210,18 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
lookup = {"": "", " ": " "}
|
||||
return f"{lookup[token.first]}{token.second}{lookup[token.third]}"
|
||||
|
||||
def collect_figures(self, document):
|
||||
"""First pass: collect all figures and assign hierarchical numbers."""
|
||||
self.figure_counter = 0
|
||||
self.figure_map = {}
|
||||
|
||||
self._collect_figures_recursive(document)
|
||||
|
||||
def _collect_figures_recursive(self, token):
|
||||
"""Recursively traverse the document tree to collect figures."""
|
||||
if hasattr(token, "children") and token.children is not None:
|
||||
for child in token.children:
|
||||
# Check if this is a Picture, Photo, or Table token
|
||||
if isinstance(child, Picture | Photo | Table):
|
||||
# Get the reference ID (ref for Picture/Photo, name for Table)
|
||||
ref_id = getattr(child, "ref", None) or getattr(child, "name", None)
|
||||
|
||||
if ref_id: # Only number figures with a reference ID
|
||||
self.figure_counter += 1
|
||||
hierarchical_num = self._format_figure_number(self.figure_counter)
|
||||
self.figure_map[ref_id] = hierarchical_num
|
||||
child.number = hierarchical_num
|
||||
else:
|
||||
child.number = ""
|
||||
|
||||
# Recurse into children
|
||||
self._collect_figures_recursive(child)
|
||||
|
||||
def _format_figure_number(self, counter):
|
||||
"""Format the hierarchical figure number based on context."""
|
||||
if self.edition and self.chapter and self.section:
|
||||
return f"{self.edition}-{self.chapter}.{self.section}.{counter}"
|
||||
else:
|
||||
# Fallback for tests or when context is not provided
|
||||
return str(counter)
|
||||
|
||||
def render_references(self, token):
|
||||
def render_reference(self, token: Reference):
|
||||
# Look up the figure number from the map
|
||||
figure_num = self.figure_map.get(token.first, "?")
|
||||
label = self._format_reference_label(token.marker) or "?"
|
||||
return (
|
||||
f'<a href="{self.section_url}#ref_{token.first}"'
|
||||
f" onclick=\"highlightRef('{token.first}');\">{figure_num}</a>"
|
||||
f'<a href="{self.section_url}#ref_{token.marker}" onclick="highlightRef(\'{token.marker}\');">{label}</a>'
|
||||
)
|
||||
|
||||
def render_question(self, token):
|
||||
return self.question_renderer(token.question_number)
|
||||
|
||||
def render_document(self, token: Document) -> str:
|
||||
self.references.update(token.references)
|
||||
self.footnotes.update(token.footnotes)
|
||||
inner = self.render_inner(token, "\n")
|
||||
return f"{inner}\n" if inner else ""
|
||||
@@ -264,36 +230,38 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
# Filter out None values, so block tokens can return None to not be rendered.
|
||||
return base.join(filter(lambda x: x is not None, [self.render(child) for child in token.children]))
|
||||
|
||||
@staticmethod
|
||||
def render_picture_helper(id, ref, text, number, alt_text):
|
||||
return f"""
|
||||
<figure class="picture" id="ref_{ref}" name="{ref}">
|
||||
<img src="pictures/{id}.svg" alt="{alt_text}">
|
||||
<figcaption>Abbildung {number}: {text}</figcaption>
|
||||
</figure>
|
||||
"""
|
||||
|
||||
def render_picture(self, token):
|
||||
alt_text = ""
|
||||
if self.picture_handler is not None:
|
||||
alt_text = self.picture_handler(token.id)
|
||||
|
||||
return self.render_picture_helper(token.id, token.ref, token.text, token.number, alt_text)
|
||||
def render_picture_helper(self, id, marker, text, label, alt_text):
|
||||
return (
|
||||
f'<figure class="picture" id="ref_{marker}" name="{marker}">\n'
|
||||
f' <img src="pictures/{id}.svg" alt="{alt_text}">\n'
|
||||
f" <figcaption>Abbildung {label}: {text}</figcaption>\n"
|
||||
"</figure>\n"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def render_photo_helper(id, ref, text, number, alt_text):
|
||||
def render_photo_helper(id, ref, text, label, alt_text):
|
||||
return f"""
|
||||
<figure class="photo" id="ref_{ref}" name="{ref}">
|
||||
<img src="photos/{id}.png" alt="{alt_text}">
|
||||
<figcaption>Abbildung {number}: {text}</figcaption>
|
||||
<figcaption>Abbildung {label}: {text}</figcaption>
|
||||
</figure>
|
||||
"""
|
||||
|
||||
def render_photo(self, token):
|
||||
alt_text = ""
|
||||
if self.photo_handler is not None:
|
||||
alt_text = self.photo_handler(token.id) or alt_text
|
||||
return self.render_photo_helper(token.id, token.ref, token.text, token.number, alt_text)
|
||||
def render_image(self, token: Image):
|
||||
label = self._format_reference_label(token.marker) or "?"
|
||||
|
||||
# Only supported kinds are photo and picture
|
||||
if token.kind == "photo":
|
||||
alt_text = ""
|
||||
if self.photo_handler is not None:
|
||||
alt_text = self.photo_handler(token.id) or alt_text
|
||||
return self.render_photo_helper(token.id, token.marker, token.text, label, alt_text)
|
||||
if token.kind == "picture":
|
||||
alt_text = ""
|
||||
if self.picture_handler is not None:
|
||||
alt_text = self.picture_handler(token.id)
|
||||
return self.render_picture_helper(token.id, token.marker, token.text, label, alt_text)
|
||||
return ""
|
||||
|
||||
def render_table(self, token: Table):
|
||||
# Add id and name attributes if table has a name
|
||||
@@ -304,10 +272,11 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
|
||||
table = f'<table class="table table-hover"{table_attrs}>\n{self.render_inner(token)}'
|
||||
|
||||
if token.caption != "":
|
||||
# Include hierarchical number in caption if available
|
||||
# Include hierarchical number in caption if the table is named.
|
||||
caption_text = token.caption
|
||||
if hasattr(token, "number") and token.number:
|
||||
caption_text = f"Tabelle {token.number}: {token.caption}"
|
||||
label = self._format_reference_label(token.name)
|
||||
if label:
|
||||
caption_text = f"Tabelle {label}: {token.caption}"
|
||||
table += f"<caption>{caption_text}</caption>\n"
|
||||
|
||||
table += "</table>"
|
||||
|
||||
@@ -3,10 +3,9 @@ from mistletoe.latex_renderer import LaTeXRenderer
|
||||
from .comment import BlockComment
|
||||
from .dash import Dash
|
||||
from .halfwidth_spaces import HalfwidthSpaces
|
||||
from .image import Image
|
||||
from .index import Index
|
||||
from .nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots
|
||||
from .photo import Photo
|
||||
from .picture import Picture
|
||||
from .question import Question
|
||||
from .quote import Quote
|
||||
from .table import Table, TableBody, TableCell, TableHeader, TableRow
|
||||
@@ -26,8 +25,7 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
|
||||
NonbreakingSpaces,
|
||||
NonbreakingSpacesDots,
|
||||
Question,
|
||||
Picture,
|
||||
Photo,
|
||||
Image,
|
||||
Table,
|
||||
TableBody,
|
||||
TableRow,
|
||||
@@ -115,17 +113,18 @@ class FiftyOhmLaTeXRenderer(LaTeXRenderer):
|
||||
\captionof{{figure}}{{{text}}}
|
||||
\label{{{ref}}}"""
|
||||
|
||||
def render_picture(self, token):
|
||||
return self.render_picture_helper(token.id, token.ref, token.text, token.number)
|
||||
|
||||
@staticmethod
|
||||
def render_photo_helper(id, ref, text, number):
|
||||
return rf"""\includegraphics[width=1.0\linewidth]{{photo/{id}}}
|
||||
\captionof{{figure}}{{{text}}}
|
||||
\label{{{ref}}}"""
|
||||
|
||||
def render_photo(self, token):
|
||||
return self.render_photo_helper(token.id, token.ref, token.text, token.number)
|
||||
def render_image(self, token: Image):
|
||||
if token.kind == "photo":
|
||||
return self.render_photo_helper(token.id, token.marker, token.text, token.label)
|
||||
if token.kind == "picture":
|
||||
return self.render_picture_helper(token.id, token.marker, token.text, token.label)
|
||||
return ""
|
||||
|
||||
def render_table(self, token):
|
||||
table = "\\begin{DARCtabular}" + f"{self.render_inner(token)}" + "\\end{DARCtabular}"
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import re
|
||||
|
||||
from mistletoe.block_tokenizer import FileWrapper
|
||||
|
||||
from renderer.referenced_token import ReferencedToken
|
||||
|
||||
|
||||
class Image(ReferencedToken):
|
||||
"""
|
||||
Block token for pictures and photos.
|
||||
Examples:
|
||||
[picture:727:amplitude_periode_halbwellen:Positive und negative Halbwellen einer Sinusschwingung]
|
||||
[photo:123:n_wasserfalldiagramm_trx_collage:Ansichten verschiedener Transceiver]
|
||||
"""
|
||||
|
||||
pattern = re.compile(r"^\[(?P<kind>picture|photo):(?P<id>\d+):(?P<marker>[^:\]]+):(?P<text>[^:\]]+)\]$")
|
||||
|
||||
@classmethod
|
||||
def start(cls, line: str):
|
||||
return cls.pattern.match(line.strip()) is not None
|
||||
|
||||
@classmethod
|
||||
def check_interrupts_paragraph(cls, lines: FileWrapper):
|
||||
line = lines.peek()
|
||||
if line is not None:
|
||||
return cls.start(line)
|
||||
else:
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def read(cls, lines: FileWrapper):
|
||||
match = cls.pattern.match(next(lines).strip())
|
||||
return match.group("kind"), match.group("id"), match.group("marker"), match.group("text")
|
||||
|
||||
def __init__(self, match):
|
||||
kind, id, marker, text = match
|
||||
super().__init__(marker)
|
||||
self.kind = kind
|
||||
self.id = id
|
||||
self.text = text
|
||||
@@ -1,19 +0,0 @@
|
||||
import re
|
||||
|
||||
from mistletoe.span_token import SpanToken
|
||||
|
||||
|
||||
class Photo(SpanToken):
|
||||
"""
|
||||
Span token for photos.
|
||||
Example: [photo:123:n_wasserfalldiagramm_trx_collage:Ansichten verschiedener Transceiver]
|
||||
"""
|
||||
|
||||
parse_inner = False
|
||||
pattern = re.compile(r"\[photo:(\d+):([^:\]]+):([^:\]]+)\]")
|
||||
|
||||
def __init__(self, match_object):
|
||||
self.id = match_object.group(1)
|
||||
self.ref = match_object.group(2)
|
||||
self.text = match_object.group(3)
|
||||
self.number = "TODO"
|
||||
@@ -1,19 +0,0 @@
|
||||
import re
|
||||
|
||||
from mistletoe.span_token import SpanToken
|
||||
|
||||
|
||||
class Picture(SpanToken):
|
||||
"""
|
||||
Span token for pictures.
|
||||
Example: [picture:727:amplitude_periode_halbwellen:Positive und negative Halbwellen einer Sinusschwingung]
|
||||
"""
|
||||
|
||||
parse_inner = False
|
||||
pattern = re.compile(r"\[picture:(\d+):(.+):(.+)\]")
|
||||
|
||||
def __init__(self, match_object):
|
||||
self.id = match_object.group(1)
|
||||
self.ref = match_object.group(2)
|
||||
self.text = match_object.group(3)
|
||||
self.number = "TODO"
|
||||
@@ -3,7 +3,7 @@ import re
|
||||
from mistletoe.span_token import SpanToken
|
||||
|
||||
|
||||
class References(SpanToken):
|
||||
class Reference(SpanToken):
|
||||
"""
|
||||
Resolve references for html
|
||||
Identifies "[ref:$]"
|
||||
@@ -12,4 +12,4 @@ class References(SpanToken):
|
||||
pattern = re.compile(r"\[ref\:(\S+)\]")
|
||||
|
||||
def __init__(self, match_object):
|
||||
self.first = match_object.group(1)
|
||||
self.marker: str = match_object.group(1)
|
||||
@@ -0,0 +1,18 @@
|
||||
import mistletoe.token
|
||||
from mistletoe.block_token import BlockToken
|
||||
|
||||
|
||||
class ReferencedToken(BlockToken):
|
||||
def __init__(self, marker: str):
|
||||
if marker != "":
|
||||
self.marker = marker
|
||||
references = mistletoe.token._root_node.references
|
||||
if marker not in references:
|
||||
label = str(len(references) + 1)
|
||||
references[marker] = label
|
||||
else:
|
||||
label = references[marker]
|
||||
self.label = label
|
||||
else:
|
||||
self.marker = None
|
||||
self.label = None
|
||||
+8
-2
@@ -4,6 +4,8 @@ from enum import Enum
|
||||
from mistletoe import span_token
|
||||
from mistletoe.block_token import BlockToken
|
||||
|
||||
from renderer.referenced_token import ReferencedToken
|
||||
|
||||
|
||||
class CellAlignment(Enum):
|
||||
LEFT = "l"
|
||||
@@ -76,7 +78,7 @@ class TableBody(BlockToken):
|
||||
self.children, self.header = rows, header
|
||||
|
||||
|
||||
class Table(BlockToken):
|
||||
class Table(ReferencedToken):
|
||||
name: str
|
||||
caption: str
|
||||
header: list[TableHeader]
|
||||
@@ -115,4 +117,8 @@ class Table(BlockToken):
|
||||
return children, name, caption
|
||||
|
||||
def __init__(self, match):
|
||||
self.children, self.name, self.caption = match
|
||||
children, name, caption = match
|
||||
super().__init__(name)
|
||||
self.children = children
|
||||
self.name = name
|
||||
self.caption = caption
|
||||
|
||||
+40
-52
@@ -7,10 +7,10 @@ import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from mistletoe import Document
|
||||
from rich.progress import BarColumn, Progress, TaskProgressColumn, TextColumn, TimeRemainingColumn
|
||||
from tqdm import tqdm
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_html_slide_renderer import FiftyOhmHtmlSlideRenderer
|
||||
from renderer.index import Index
|
||||
@@ -222,12 +222,7 @@ class Build:
|
||||
section=section_num,
|
||||
section_url=section_filename,
|
||||
) as renderer:
|
||||
# First pass: collect all figures and assign hierarchical numbers
|
||||
doc = Document(section["content"])
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
# Second pass: render with hierarchical numbers
|
||||
section["content"] = renderer.render(doc)
|
||||
section["content"] = renderer.render(Document(section["content"]))
|
||||
|
||||
result = section_template.render(
|
||||
edition=edition,
|
||||
@@ -266,58 +261,51 @@ class Build:
|
||||
# Note: filename uses original edition (e.g., "N"), not modified edition with "S" (e.g., "NS")
|
||||
slide_filename = f"{edition}_slide_{chapter['ident']}.html"
|
||||
|
||||
with FiftyOhmHtmlSlideRenderer(
|
||||
question_renderer=self.__build_question_slide,
|
||||
picture_handler=self.__picture_handler,
|
||||
photo_handler=self.__photo_handler,
|
||||
include_handler=self.__include_handler,
|
||||
edition=edition,
|
||||
chapter=chapter_num,
|
||||
section="0", # Will be updated per section
|
||||
section_url=slide_filename,
|
||||
) as renderer:
|
||||
result = "<section>\n"
|
||||
result += f'<section data-background="#DAEEFA">\n<h1>{chapter["title"]}</h1>\n</section>\n'
|
||||
result += help_template.render()
|
||||
result += "</section>\n"
|
||||
result = "<section>\n"
|
||||
result += f'<section data-background="#DAEEFA">\n<h1>{chapter["title"]}</h1>\n</section>\n'
|
||||
result += help_template.render()
|
||||
result += "</section>\n"
|
||||
|
||||
section_counter = 0
|
||||
slides_task = progress.add_task("Rendering slides ...")
|
||||
for section in progress.track(sections, task_id=slides_task):
|
||||
progress.update(slides_task, description=f"Rendering slides of {section['title']}")
|
||||
section_counter = 0
|
||||
slides_task = progress.add_task("Rendering slides ...")
|
||||
for section in progress.track(sections, task_id=slides_task):
|
||||
progress.update(slides_task, description=f"Rendering slides of {section['title']}")
|
||||
|
||||
if section["slide"] is None:
|
||||
continue
|
||||
if section["slide"] is None:
|
||||
continue
|
||||
|
||||
section_counter += 1
|
||||
# Update section number for this section
|
||||
renderer.section = str(section_counter)
|
||||
# Reset figure counter for each section
|
||||
renderer.figure_counter = 0
|
||||
renderer.figure_map = {}
|
||||
section_counter += 1
|
||||
|
||||
if not section["slide"].startswith("---"):
|
||||
section["slide"] = "---\n" + section["slide"]
|
||||
if not section["slide"].startswith("---"):
|
||||
section["slide"] = "---\n" + section["slide"]
|
||||
|
||||
# First pass: collect figures
|
||||
doc = Document(section["slide"])
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
# Second pass: render with hierarchical numbers
|
||||
tmp = f'<section data-background="#DAEEFA">\n<h1>{section["title"]}</h1>\n</section>\n'
|
||||
tmp += renderer.render(doc)
|
||||
result += f"<section>{tmp}</section>\n"
|
||||
|
||||
progress.remove_task(slides_task)
|
||||
|
||||
result += next_template.render(
|
||||
# A fresh renderer per section keeps the figure counter and
|
||||
# reference map scoped to that section.
|
||||
with FiftyOhmHtmlSlideRenderer(
|
||||
question_renderer=self.__build_question_slide,
|
||||
picture_handler=self.__picture_handler,
|
||||
photo_handler=self.__photo_handler,
|
||||
include_handler=self.__include_handler,
|
||||
edition=edition,
|
||||
next_chapter=next_chapter,
|
||||
chapter=chapter,
|
||||
)
|
||||
chapter=chapter_num,
|
||||
section=str(section_counter),
|
||||
section_url=slide_filename,
|
||||
) as renderer:
|
||||
tmp = f'<section data-background="#DAEEFA">\n<h1>{section["title"]}</h1>\n</section>\n'
|
||||
tmp += renderer.render(Document(section["slide"]))
|
||||
|
||||
result = slide_template.render(content=result)
|
||||
file.write(result)
|
||||
result += f"<section>{tmp}</section>\n"
|
||||
|
||||
progress.remove_task(slides_task)
|
||||
|
||||
result += next_template.render(
|
||||
edition=edition,
|
||||
next_chapter=next_chapter,
|
||||
chapter=chapter,
|
||||
)
|
||||
|
||||
result = slide_template.render(content=result)
|
||||
file.write(result)
|
||||
|
||||
def __filter_shuffle_answers(self, seq):
|
||||
answers = []
|
||||
|
||||
+13
-13
@@ -108,8 +108,8 @@
|
||||
<h5>Mitglied werden</h5>
|
||||
<p>Der <a href="https://darc.de">DARC e. V.</a> unterstützt Dich auf deinem Weg zum Amateurfunkzeugnis und ist die größte Interessensvertretung der Funkamateure in Deutschland.</p>
|
||||
<div class="row row-cols-lg-2">
|
||||
<div class="col"><a href="https://www.darc.de/mitgliedschaft/mitglied-werden/" class="btn btn-outline-dark w-100">Mitglied werden</a></div>
|
||||
<div class="col"><a href="https://www.darc.de/mitgliedschaft/mitglied-werden/#c154065" class="btn btn-outline-dark w-100">Gastmitgliedschaft</a></div>
|
||||
<div class="col"><a href="https://antrag.darc.de/?typ=voll" class="btn btn-outline-dark w-100" target="_blank">Mitglied werden</a></div>
|
||||
<div class="col"><a href="https://antrag.darc.de/?typ=gast" class="btn btn-outline-dark w-100" target="_blank">Gastmitgliedschaft</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -121,9 +121,9 @@
|
||||
<h2>Videokurse</h2>
|
||||
<p>In Zusammenarbeit mit DL2YMR ist ein Videokurs für die Klasse N entstanden, der auf seinem YouTube-Kanal abrufbar ist. Weiterhin gibt es noch Vorlesungen für N+E sowie A. </p>
|
||||
<div class="d-grid gap-2 d-sm-flex flex-sm-wrap mb-5">
|
||||
<a href="https://www.youtube.com/playlist?list=PLDpWnjHk5ERbcgpLPUaU0iTsD-wrmfENk" class="btn btn-primary">Zum Videokurs Klasse N</a>
|
||||
<a href="https://www.youtube.com/playlist?list=PL_JZo16Mzs5XGeN5N81MwQ70dp7478VkM" class="btn btn-primary">Vorlesung Klasse N+E</a>
|
||||
<a href="https://www.youtube.com/playlist?list=PL_JZo16Mzs5XebdJhoIDLNp1MObBy7F5d" class="btn btn-primary">Vorlesung Klasse A</a>
|
||||
<a href="https://www.youtube.com/playlist?list=PLDpWnjHk5ERbcgpLPUaU0iTsD-wrmfENk" class="btn btn-outline-dark">Zum Videokurs Klasse N</a>
|
||||
<a href="https://www.youtube.com/playlist?list=PL_JZo16Mzs5XGeN5N81MwQ70dp7478VkM" class="btn btn-outline-dark">Vorlesung Klasse N+E</a>
|
||||
<a href="https://www.youtube.com/playlist?list=PL_JZo16Mzs5XebdJhoIDLNp1MObBy7F5d" class="btn btn-outline-dark">Vorlesung Klasse A</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature col">
|
||||
@@ -134,8 +134,8 @@
|
||||
<h2>Buch Klasse N</h2>
|
||||
<p>Die Lernhinhalte für die Klasse N gibt es auch als gedrucktes Buch. Es ist passend zum Online-Kurs ausgelegt.</p>
|
||||
<div class="d-grid gap-2 d-md-block mb-5">
|
||||
<a href="https://darcverlag.de/DARC-Amateurfunklehrgang-Klasse-N" class="btn btn-primary">Beim DARC-Verlag kaufen</a>
|
||||
<a href="https://www.amazon.de/dp/388692100X" class="btn btn-primary">Amazon</a>
|
||||
<a href="https://darcverlag.de/DARC-Amateurfunklehrgang-Klasse-N" class="btn btn-outline-dark">Beim DARC-Verlag kaufen</a>
|
||||
<a href="https://www.amazon.de/dp/388692100X" class="btn btn-outline-dark">Amazon</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature col">
|
||||
@@ -145,8 +145,8 @@
|
||||
<h2>Kurse</h2>
|
||||
<p>Einige unserer Ortsverbände bieten Präsenz- oder Onlinekurse mit erfahrenen Ausbildern an. Finde heraus, ob es einen für dich passenden Kurs bei dir in der Nähe gibt!</p>
|
||||
<div class="d-grid gap-2 d-md-block mb-5">
|
||||
<a href="kurse_vor_ort_karte.html" class="btn btn-primary">Präsenz</a>
|
||||
<a href="kurse_vor_ort_liste.html" class="btn btn-primary">Online</a>
|
||||
<a href="kurse_vor_ort_karte.html" class="btn btn-outline-dark">Präsenz</a>
|
||||
<a href="kurse_vor_ort_liste.html" class="btn btn-outline-dark">Online</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature col">
|
||||
@@ -156,7 +156,7 @@
|
||||
<h2>Ausbildungs­paten</h2>
|
||||
<p>Unsere Ausbildungspaten sind erfahrene Funkamateure, die dich gerne unterstützen. Sie können mit dir auch praktisch üben und nützliche Tipps für die Praxis geben.</p>
|
||||
<div class="d-grid gap-2 d-md-block mb-5">
|
||||
<a href="patenkarte.html" class="btn btn-primary">Zur Patenkarte</a>
|
||||
<a href="patenkarte.html" class="btn btn-outline-dark">Zur Patenkarte</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature col">
|
||||
@@ -166,7 +166,7 @@
|
||||
<h2>Fragenkatalog</h2>
|
||||
<p>Den Fragenkatalog mit den amtlichen Prüfungsfragen gibt es digital bei der <a href="https://50ohm.de/fk">Bundesnetzagentur</a>. Beim DARC-Verlag kann man auch eine gedruckte Version bestellen.</p>
|
||||
<div class="d-grid gap-2 d-md-block mb-5">
|
||||
<a href="https://darcverlag.de/Fragenkatalog-Klasse-N" class="btn btn-primary">Beim DARC-Verlag kaufen</a>
|
||||
<a href="https://darcverlag.de/Fragenkatalog-Klasse-N" class="btn btn-outline-dark">Beim DARC-Verlag kaufen</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feature col">
|
||||
@@ -176,8 +176,8 @@
|
||||
<h2>Trainings App</h2>
|
||||
<p>Zum Trainieren der Fragen gibt es die 50Ohm App. Sie ist passend zum Online-Kurs ausgelegt.</p>
|
||||
<div class="d-grid gap-2 d-md-block mb-5">
|
||||
<a href="https://play.google.com/store/apps/details?id=de.darc.fuenfizigohm" class="btn btn-primary">Android</a>
|
||||
<a href="https://apps.apple.com/de/app/50ohm/id6474642114" class="btn btn-primary">iOS</a>
|
||||
<a href="https://play.google.com/store/apps/details?id=de.darc.fuenfizigohm" class="btn btn-outline-dark">Android</a>
|
||||
<a href="https://apps.apple.com/de/app/50ohm/id6474642114" class="btn btn-outline-dark">iOS</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -16,7 +15,7 @@ def test_comment_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
|
||||
assert render_html(assertion) == assertions[assertion]
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -14,7 +13,7 @@ def test_dash_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
assert render_html(assertion) == paragraph(assertions[assertion])
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import pytest
|
||||
from mistletoe import Document
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from test.util import render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -14,6 +13,5 @@ def test_formula_html():
|
||||
r"Lorem Ipsum" + "\n" + r"$a \cdot b$": "<p>Lorem Ipsum</p>\n\n" + r"$$a \cdot b$$" + "\n\n",
|
||||
}
|
||||
|
||||
with FiftyOhmHtmlRenderer() as renderer:
|
||||
for assertion in assertions:
|
||||
assert renderer.render(Document(assertion)) == assertions[assertion]
|
||||
for assertion in assertions:
|
||||
assert render_html(assertion) == assertions[assertion]
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -11,7 +10,7 @@ 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. B. ein Test. D. h. hier sollten d. h. Spaces ersetzt worden sein."
|
||||
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
|
||||
assert render_html(input) == paragraph(target)
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_html_slide_renderer import FiftyOhmHtmlSlideRenderer
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
def test_hierarchical_picture_numbering():
|
||||
"""Test that pictures get hierarchical numbers in format edition-chapter.section.counter"""
|
||||
"""Pictures get hierarchical numbers in format edition-chapter.section.counter"""
|
||||
markdown_text = """
|
||||
[picture:123:pic1:First picture]
|
||||
|
||||
@@ -20,30 +20,26 @@ Reference to second: [ref:pic2]
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlRenderer(edition="E", chapter="2", section="3")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
doc = Document(markdown_text)
|
||||
|
||||
# First pass: collect figures
|
||||
renderer.collect_figures(doc)
|
||||
# Counter is assigned in document order during parsing.
|
||||
assert doc.references["pic1"] == "1"
|
||||
assert doc.references["pic2"] == "2"
|
||||
|
||||
# Verify figure map
|
||||
assert renderer.figure_map["pic1"] == "E-2.3.1"
|
||||
assert renderer.figure_map["pic2"] == "E-2.3.2"
|
||||
|
||||
# Second pass: render
|
||||
result = renderer.render(doc)
|
||||
|
||||
# Verify hierarchical numbers in output
|
||||
# Hierarchical numbers in the figure captions.
|
||||
assert "Abbildung E-2.3.1:" in result
|
||||
assert "Abbildung E-2.3.2:" in result
|
||||
|
||||
# Verify references are resolved
|
||||
# References are resolved to the same numbers.
|
||||
assert ">E-2.3.1</a>" in result
|
||||
assert ">E-2.3.2</a>" in result
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
def test_hierarchical_photo_numbering():
|
||||
"""Test that photos get hierarchical numbers"""
|
||||
"""Photos get hierarchical numbers from the shared counter"""
|
||||
markdown_text = """
|
||||
[photo:789:photo1:First photo]
|
||||
|
||||
@@ -53,12 +49,10 @@ Reference: [ref:photo1]
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlRenderer(edition="N", chapter="1", section="2")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
doc = Document(markdown_text)
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
assert renderer.figure_map["photo1"] == "N-1.2.1"
|
||||
assert renderer.figure_map["photo2"] == "N-1.2.2"
|
||||
assert doc.references["photo1"] == "1"
|
||||
assert doc.references["photo2"] == "2"
|
||||
|
||||
result = renderer.render(doc)
|
||||
|
||||
@@ -69,7 +63,7 @@ Reference: [ref:photo1]
|
||||
|
||||
@pytest.mark.html
|
||||
def test_hierarchical_table_numbering():
|
||||
"""Test that tables with names get hierarchical numbers"""
|
||||
"""Tables with names get hierarchical numbers from the shared counter"""
|
||||
markdown_text = """
|
||||
| Header 1 | Header 2 |
|
||||
| Data 1 | Data 2 |
|
||||
@@ -83,12 +77,10 @@ Reference: [ref:table1]
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlRenderer(edition="A", chapter="3", section="1")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
doc = Document(markdown_text)
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
assert renderer.figure_map["table1"] == "A-3.1.1"
|
||||
assert renderer.figure_map["table2"] == "A-3.1.2"
|
||||
assert doc.references["table1"] == "1"
|
||||
assert doc.references["table2"] == "2"
|
||||
|
||||
result = renderer.render(doc)
|
||||
|
||||
@@ -99,7 +91,7 @@ Reference: [ref:table1]
|
||||
|
||||
@pytest.mark.html
|
||||
def test_mixed_figure_types_share_counter():
|
||||
"""Test that pictures, photos, and tables share a single unified counter"""
|
||||
"""Pictures, photos, and tables share a single unified counter in document order"""
|
||||
markdown_text = """
|
||||
[picture:1:pic1:Picture one]
|
||||
|
||||
@@ -115,19 +107,16 @@ References: [ref:pic1], [ref:photo1], [ref:tab1], [ref:pic2]
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlRenderer(edition="E", chapter="5", section="2")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
doc = Document(markdown_text)
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
# All types share the same counter
|
||||
assert renderer.figure_map["pic1"] == "E-5.2.1"
|
||||
assert renderer.figure_map["photo1"] == "E-5.2.2"
|
||||
assert renderer.figure_map["tab1"] == "E-5.2.3"
|
||||
assert renderer.figure_map["pic2"] == "E-5.2.4"
|
||||
# All types share the same counter, assigned in document order.
|
||||
assert doc.references["pic1"] == "1"
|
||||
assert doc.references["photo1"] == "2"
|
||||
assert doc.references["tab1"] == "3"
|
||||
assert doc.references["pic2"] == "4"
|
||||
|
||||
result = renderer.render(doc)
|
||||
|
||||
# Verify all references are resolved with correct numbers
|
||||
assert "Abbildung E-5.2.1:" in result # pic1
|
||||
assert "Abbildung E-5.2.2:" in result # photo1
|
||||
assert "Tabelle E-5.2.3:" in result # tab1
|
||||
@@ -136,7 +125,7 @@ References: [ref:pic1], [ref:photo1], [ref:tab1], [ref:pic2]
|
||||
|
||||
@pytest.mark.slide
|
||||
def test_slide_renderer_adds_s_suffix():
|
||||
"""Test that slide renderer adds 'S' suffix to edition"""
|
||||
"""The slide renderer adds an 'S' suffix to the edition"""
|
||||
markdown_text = """
|
||||
[picture:1:pic1:Slide picture]
|
||||
|
||||
@@ -144,17 +133,11 @@ Reference: [ref:pic1]
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlSlideRenderer(edition="E", chapter="2", section="1")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
|
||||
# Verify edition has S suffix
|
||||
# Edition gains the S suffix.
|
||||
assert renderer.edition == "ES"
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
# Verify hierarchical number includes S
|
||||
assert renderer.figure_map["pic1"] == "ES-2.1.1"
|
||||
|
||||
result = renderer.render(doc)
|
||||
result = renderer.render(Document(markdown_text))
|
||||
|
||||
assert "Abbildung ES-2.1.1:" in result
|
||||
assert ">ES-2.1.1</a>" in result
|
||||
@@ -162,49 +145,38 @@ Reference: [ref:pic1]
|
||||
|
||||
@pytest.mark.html
|
||||
def test_fallback_numbering_without_context():
|
||||
"""Test that numbering falls back to simple counter when context is missing"""
|
||||
"""Numbering falls back to a simple counter when context is missing"""
|
||||
markdown_text = """
|
||||
[picture:1:pic1:Picture]
|
||||
|
||||
Reference: [ref:pic1]
|
||||
"""
|
||||
|
||||
# No edition/chapter/section provided
|
||||
# No edition/chapter/section provided.
|
||||
renderer = FiftyOhmHtmlRenderer()
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
# Should fall back to simple counter
|
||||
assert renderer.figure_map["pic1"] == "1"
|
||||
|
||||
result = renderer.render(doc)
|
||||
result = renderer.render(Document(markdown_text))
|
||||
|
||||
# Falls back to the bare counter.
|
||||
assert "Abbildung 1:" in result
|
||||
assert ">1</a>" in result
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
def test_unresolved_reference():
|
||||
"""Test that references to non-existent figures show '?'"""
|
||||
"""References to non-existent figures show '?'"""
|
||||
markdown_text = """
|
||||
Reference to non-existent: [ref:nonexistent]
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlRenderer(edition="E", chapter="1", section="1")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
result = renderer.render(Document(markdown_text))
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
|
||||
result = renderer.render(doc)
|
||||
|
||||
# Should show ? for unresolved reference
|
||||
assert ">?</a>" in result
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
def test_table_without_name_not_numbered():
|
||||
"""Test that tables without names are not numbered"""
|
||||
"""Tables without names are not numbered and do not consume a counter slot"""
|
||||
markdown_text = """
|
||||
| Header 1 | Header 2 |
|
||||
| Data 1 | Data 2 |
|
||||
@@ -213,10 +185,12 @@ def test_table_without_name_not_numbered():
|
||||
"""
|
||||
|
||||
renderer = FiftyOhmHtmlRenderer(edition="E", chapter="1", section="1")
|
||||
doc = mistletoe.Document(markdown_text)
|
||||
doc = Document(markdown_text)
|
||||
|
||||
renderer.collect_figures(doc)
|
||||
# Only the picture is registered.
|
||||
assert doc.references == {"pic1": "1"}
|
||||
|
||||
# Only the picture should be numbered
|
||||
assert renderer.figure_map["pic1"] == "E-1.1.1"
|
||||
assert renderer.figure_counter == 1
|
||||
result = renderer.render(doc)
|
||||
|
||||
assert "Abbildung E-1.1.1:" in result
|
||||
assert "Tabelle" not in result
|
||||
|
||||
+1
-1
@@ -2,9 +2,9 @@ import json
|
||||
|
||||
import pytest
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from mistletoe import Document
|
||||
|
||||
import src.config as config
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
|
||||
conf = config.Config()
|
||||
|
||||
@@ -3,9 +3,9 @@ import random
|
||||
|
||||
import pytest
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from mistletoe import Document
|
||||
|
||||
import src.config as config
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_slide_renderer import FiftyOhmHtmlSlideRenderer
|
||||
|
||||
conf = config.Config()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from mistletoe import Document
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
|
||||
|
||||
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -42,7 +41,7 @@ def test_index_html():
|
||||
}
|
||||
|
||||
for key, value in assertions.items():
|
||||
assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value)
|
||||
assert render_html(key) == paragraph(value)
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -17,4 +16,4 @@ def test_morse_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
assert render_html(assertion) == paragraph(assertions[assertion])
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -11,7 +10,7 @@ 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."
|
||||
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
|
||||
assert render_html(input) == paragraph(target)
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -24,7 +23,7 @@ def test_three_points_html():
|
||||
}
|
||||
|
||||
for key, value in assertions.items():
|
||||
assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value)
|
||||
assert render_html(key) == paragraph(value)
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -32,7 +31,7 @@ def test_absatz_html():
|
||||
input = "Der Test befindet sich unter Abs.2 vielleicht aber auch Abs. 3."
|
||||
target = "Der Test befindet sich unter Abs. 2 vielleicht aber auch Abs. 3."
|
||||
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
|
||||
assert render_html(input) == paragraph(target)
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -40,7 +39,7 @@ def test_class_html():
|
||||
input = "Ich lerne für Klasse A, Klasse E und Klasse N."
|
||||
target = "Ich lerne für Klasse A, Klasse E und Klasse N."
|
||||
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(target)
|
||||
assert render_html(input) == paragraph(target)
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
+8
-9
@@ -1,19 +1,17 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
def test_photo_html():
|
||||
assertions = {
|
||||
"[photo:123:abc:Text]": FiftyOhmHtmlRenderer.render_photo_helper("123", "abc", "Text", "TODO", ""),
|
||||
}
|
||||
assertions = {"[photo:123:abc:Text]": ("123", "abc", "Text", "A-5.7.1", "")}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
with FiftyOhmHtmlRenderer(edition="A", chapter="5", section="7") as renderer:
|
||||
for assertion in assertions:
|
||||
assert renderer.render(Document(assertion)) == renderer.render_photo_helper(*assertions[assertion]) + "\n"
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
@@ -22,5 +20,6 @@ def test_photo_latex():
|
||||
"[photo:123:abc:Text]": FiftyOhmLaTeXRenderer.render_photo_helper("123", "abc", "Text", "TODO"),
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == "\n" + assertions[assertion] + "\n"
|
||||
with FiftyOhmLaTeXRenderer() as renderer:
|
||||
for assertion in assertions:
|
||||
assert renderer.render(Document(assertion)) == assertions[assertion]
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
def test_picture_html():
|
||||
assertions = {
|
||||
"[picture:0:abc:Text]": FiftyOhmHtmlRenderer.render_picture_helper("0", "abc", "Text", "TODO", ""),
|
||||
}
|
||||
assertions = {"[picture:0:abc:Text]": ("0", "abc", "Text", "A-5.7.1", "")}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
with FiftyOhmHtmlRenderer(edition="A", chapter="5", section="7") as renderer:
|
||||
for assertion in assertions:
|
||||
assert renderer.render(Document(assertion)) == renderer.render_picture_helper(*assertions[assertion]) + "\n"
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
@@ -22,5 +20,6 @@ def test_picture_latex():
|
||||
"[picture:0:abc:Text]": FiftyOhmLaTeXRenderer.render_picture_helper("0", "abc", "Text", "TODO"),
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmLaTeXRenderer) == "\n" + assertions[assertion] + "\n"
|
||||
with FiftyOhmLaTeXRenderer() as renderer:
|
||||
for assertion in assertions:
|
||||
assert renderer.render(Document(assertion)) == assertions[assertion]
|
||||
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_html_slide_renderer import FiftyOhmHtmlSlideRenderer
|
||||
from test.util import render_html, render_slide
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -21,7 +20,7 @@ def test_qso_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
|
||||
assert render_html(assertion) == assertions[assertion]
|
||||
|
||||
|
||||
@pytest.mark.slide
|
||||
@@ -31,4 +30,4 @@ def test_qso_slide():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlSlideRenderer) == assertions[assertion]
|
||||
assert render_slide(assertion) == assertions[assertion]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
from mistletoe import Document
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
|
||||
+2
-3
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -18,7 +17,7 @@ def test_quote_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
assert render_html(assertion) == paragraph(assertions[assertion])
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -15,4 +13,4 @@ def test_references_html():
|
||||
}
|
||||
|
||||
for key, value in assertions.items():
|
||||
assert mistletoe.markdown(key, FiftyOhmHtmlRenderer) == paragraph(value)
|
||||
assert render_html(key) == paragraph(value)
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from mistletoe import Document
|
||||
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
|
||||
@@ -15,7 +15,7 @@ def test_table_html():
|
||||
"| l: a |\n| b |\n| c |": '<table class="table table-hover">\n<thead>\n<tr>\n<th style="text-align: left;">a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style="text-align: left;">b</td>\n</tr>\n<tr>\n<td style="text-align: left;">c</td>\n</tr>\n</tbody>\n</table>\n', # noqa: E501
|
||||
"| a |\n| b |\n| c |": '<table class="table table-hover">\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>b</td>\n</tr>\n<tr>\n<td>c</td>\n</tr>\n</tbody>\n</table>\n', # noqa: E501
|
||||
"| l: a |\n| *b* |": '<table class="table table-hover">\n<thead>\n<tr>\n<th style="text-align: left;">a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style="text-align: left;"><em>b</em></td>\n</tr>\n</tbody>\n</table>\n', # noqa: E501
|
||||
"| l: a |\n| b |\n[table:n_ab:A und B]": '<table class="table table-hover" id="ref_n_ab" name="n_ab">\n<thead>\n<tr>\n<th style="text-align: left;">a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style="text-align: left;">b</td>\n</tr>\n</tbody>\n<caption>A und B</caption>\n</table>\n', # noqa: E501
|
||||
"| l: a |\n| b |\n[table:n_ab:A und B]": '<table class="table table-hover" id="ref_n_ab" name="n_ab">\n<thead>\n<tr>\n<th style="text-align: left;">a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style="text-align: left;">b</td>\n</tr>\n</tbody>\n<caption>Tabelle 1: A und B</caption>\n</table>\n', # noqa: E501
|
||||
"| l: *a* |": '<table class="table table-hover">\n<thead>\n<tr>\n<th style="text-align: left;"><em>a</em></th>\n</tr>\n</thead>\n</table>\n', # noqa: E501
|
||||
"| l: a |\n| [morse:a] |": '<table class="table table-hover">\n<thead>\n<tr>\n<th style="text-align: left;">a</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style="text-align: left;"><span class="morse"><span class="morse_char">\n<span class="morse_symbol">\n▄</span>\n<span class="morse_symbol">\n▄▄▄</span>\n</span>\n</span></td>\n</tr>\n</tbody>\n</table>\n', # noqa: E501
|
||||
"| l: abc | r: abc | X: abc |\n| 123 | 456 | 789 | \n | 987 | 654 | 321 | ": '<table class="table table-hover">\n<thead>\n<tr>\n<th style="text-align: left;">abc</th>\n<th style="text-align: right;">abc</th>\n<th>abc</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td style="text-align: left;">123</td>\n<td style="text-align: right;">456</td>\n<td>789</td>\n</tr>\n<tr>\n<td style="text-align: left;">987</td>\n<td style="text-align: right;">654</td>\n<td>321</td>\n</tr>\n</tbody>\n</table>\n', # noqa: E501
|
||||
|
||||
+6
-7
@@ -2,9 +2,8 @@ import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_html_slide_renderer import FiftyOhmHtmlSlideRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html, render_slide
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -15,7 +14,7 @@ def test_thematic_break_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
|
||||
assert render_html(assertion) == assertions[assertion]
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -39,7 +38,7 @@ def test_tag_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
|
||||
assert render_html(assertion) == assertions[assertion]
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -61,7 +60,7 @@ def test_thematic_break_and_tag_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == assertions[assertion]
|
||||
assert render_html(assertion) == assertions[assertion]
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
@@ -119,7 +118,7 @@ def test_tag_slide():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlSlideRenderer) == assertions[assertion]
|
||||
assert render_slide(assertion) == assertions[assertion]
|
||||
|
||||
|
||||
@pytest.mark.slide
|
||||
@@ -133,4 +132,4 @@ def test_slide_break():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlSlideRenderer) == assertions[assertion]
|
||||
assert render_slide(assertion) == assertions[assertion]
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_latex_renderer import FiftyOhmLaTeXRenderer
|
||||
from test.util import paragraph
|
||||
from test.util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -15,7 +14,7 @@ def test_underline_html():
|
||||
}
|
||||
|
||||
for assertion in assertions:
|
||||
assert mistletoe.markdown(assertion, FiftyOhmHtmlRenderer) == paragraph(assertions[assertion])
|
||||
assert render_html(assertion) == paragraph(assertions[assertion])
|
||||
|
||||
|
||||
@pytest.mark.latex
|
||||
|
||||
+4
-7
@@ -1,9 +1,6 @@
|
||||
import mistletoe
|
||||
import pytest
|
||||
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
|
||||
from .util import paragraph
|
||||
from .util import paragraph, render_html
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -21,7 +18,7 @@ def test_basic_units_html():
|
||||
}
|
||||
|
||||
for input, output in assertions.items():
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)
|
||||
assert render_html(input) == paragraph(output)
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -33,7 +30,7 @@ def test_translated_units_html():
|
||||
}
|
||||
|
||||
for input, output in assertions.items():
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)
|
||||
assert render_html(input) == paragraph(output)
|
||||
|
||||
|
||||
@pytest.mark.html
|
||||
@@ -46,4 +43,4 @@ def test_special_units_html():
|
||||
}
|
||||
|
||||
for input, output in assertions.items():
|
||||
assert mistletoe.markdown(input, FiftyOhmHtmlRenderer) == paragraph(output)
|
||||
assert render_html(input) == paragraph(output)
|
||||
|
||||
@@ -1,2 +1,19 @@
|
||||
from renderer.document import Document
|
||||
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
|
||||
from renderer.fifty_ohm_html_slide_renderer import FiftyOhmHtmlSlideRenderer
|
||||
|
||||
|
||||
def paragraph(text):
|
||||
return f"<p>{text}</p>\n"
|
||||
|
||||
|
||||
def render_html(markdown):
|
||||
"""Render markdown with the HTML renderer through the project's Document."""
|
||||
with FiftyOhmHtmlRenderer() as renderer:
|
||||
return renderer.render(Document(markdown))
|
||||
|
||||
|
||||
def render_slide(markdown):
|
||||
"""Render markdown with the slide renderer through the project's Document."""
|
||||
with FiftyOhmHtmlSlideRenderer() as renderer:
|
||||
return renderer.render(Document(markdown))
|
||||
|
||||
Reference in New Issue
Block a user