Pull request #40: Feature/include

Merge in FRAG/50ohm.de from feature/include to main

* commit 'c8343b7b01021caf874b04592fcc556db741c6b3':
  refactor: converted to block token
  feature: added ability to render includes
  feature: add include to acceptance test
  feature: ability to detect includes
  feature: add ability to download includes
This commit is contained in:
Prof.Dr. Matthias Jung DL9MJ
2025-06-24 22:04:42 +02:00
committed by Tim Grelka
8 changed files with 88 additions and 4 deletions
+1
View File
@@ -16,6 +16,7 @@ dl.download_edition("N")
dl.download_question_metadata()
dl.download_pictures()
dl.download_photos()
dl.download_includes()
dl.download_snippets()
dl.download_content()
+13 -1
View File
@@ -6,6 +6,7 @@ from mistletoe import Document, HtmlRenderer
from .comment import BlockComment
from .dash import Dash
from .halfwidth_spaces import HalfwidthSpaces
from .include import Include
from .morse import Morse
from .nonbreaking_spaces import NonbreakingSpaces, NonbreakingSpacesDots
from .photo import Photo
@@ -28,7 +29,13 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
section_url = "section.html"
ref_id = 0
def __init__(self, question_renderer=None, picture_handler=None, photo_handler=None):
def __init__(
self,
question_renderer=None,
picture_handler=None,
photo_handler=None,
include_handler=None
) :
super().__init__(
Dash,
BlockComment,
@@ -46,10 +53,12 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
Photo,
Table,
Qso,
Include
)
self.question_renderer = question_renderer
self.picture_handler = picture_handler
self.photo_handler = photo_handler
self.include_handler = include_handler
def render_dash(self, token):
return " – "
@@ -227,3 +236,6 @@ class FiftyOhmHtmlRenderer(HtmlRenderer):
table += "</table>"
return table
def render_include(self, token):
return self.include_handler(token.ident)
+24
View File
@@ -0,0 +1,24 @@
import re
from mistletoe.block_token import BlockToken
class Include(BlockToken):
"""
Block token ("[include:ident]").
Includes raw html or javascript code from a file with the given identifier.
"""
@staticmethod
def start(line):
return re.match(r"^\s*\[include:\s*[^\]]+\]", line)
@classmethod
def read(cls, lines):
re.compile(r'')
line = next(lines) # Consume the line with the include directive
ident = re.match(r"^\s*\[include:\s*([^\]]+)\]", line).group(1)
return ident
def __init__(self, match):
self.ident = match
+11 -1
View File
@@ -130,6 +130,11 @@ class Build:
result = self.__build_page(result, course_wrapper=True)
file.write(result)
def __include_handler(self, include):
with open("data/includes.json") as file:
includes = json.load(file)
return includes.get(include)
# cached
def __build_section(self, edition, edition_name, section, chapter, next_section=None, next_chapter=None):
section_template = self.env.get_template("section.html")
@@ -137,7 +142,12 @@ class Build:
next_chapter_template = self.env.get_template("next_chapter.html")
with open(f'build/{edition}_{section["ident"]}.html', 'w') as file:
with FiftyOhmHtmlRenderer(self.__build_question, self.__picture_handler, self.__photo_handler) as renderer:
with FiftyOhmHtmlRenderer(
self.__build_question,
self.__picture_handler,
self.__photo_handler,
self.__include_handler
) as renderer:
section["content"] = renderer.render(Document(section["content"]))
result = section_template.render(
+11 -1
View File
@@ -133,6 +133,16 @@ class Download:
delayed(build_picture)(picture) for picture in tqdm(pictures, desc="Build All Pictures")
)
def download_includes(self):
includes = self.api.get("items/include", params={"limit": -1})
result = {}
for include in tqdm(includes, desc="Downloading includes"):
result[include["ident"]] = include["content"]
with open("data/includes.json", "w") as f:
json.dump(result, f, indent=4)
def download_snippets(self):
snippets = {}
for snippet in tqdm(self.content_api.get("items/snippet"), desc="Downloading snippets"):
@@ -152,4 +162,4 @@ class Download:
)
with open("data/content.json", "w", encoding="utf-8") as file:
json.dump(contents, file, ensure_ascii=False, indent=4)
json.dump(contents, file, ensure_ascii=False, indent=4)
+2
View File
@@ -1,5 +1,7 @@
% Kommentar: DARC-DOWN-TEST
[include:test]
Das ist eine Item-Liste:
* Erster Eintrag
+8 -1
View File
@@ -69,12 +69,19 @@ def question_stub(input):
answer_pictures=answer_pictures,
)
def include_stub(include):
with open("data/includes.json") as file:
includes = json.load(file)
return includes.get(include)
def test_html(capsys):
with capsys.disabled():
with open("test/acceptanceTest.md") as file:
content = file.read()
with FiftyOhmHtmlRenderer(question_stub) as renderer:
with FiftyOhmHtmlRenderer(
question_renderer=question_stub,
include_handler=include_stub,
) as renderer:
output = renderer.render(Document(content))
with open("test/acceptanceTest.html", "w") as output_file:
pretty = BeautifulSoup(output, "html.parser").prettify()
+18
View File
@@ -0,0 +1,18 @@
import pytest
from mistletoe import Document
from renderer.fifty_ohm_html_renderer import FiftyOhmHtmlRenderer
@pytest.mark.html
def test_include_html():
assertions = {
'[include:ident]': "ident\n",
}
def test_function(input):
return f"{input}"
with FiftyOhmHtmlRenderer(include_handler=test_function) as renderer:
for assertion in assertions:
assert renderer.render(Document(assertion)) == assertions[assertion]