fast fertig

This commit is contained in:
florian committed 2026-10-03 13:29:12 +02:00
1 parent d1e833e5db
commit 833f896887
9 files changed
+85 -21

No files matched your search

+33 -9
View File
@@ -265,10 +265,11 @@ def _slugify(s):
return s or "abschnitt"
def heading_nav(headings):
def heading_nav(headings, prefix=""):
"""Baut die Anker-Navigation als verschachtelte ul/li-Liste:
Eine Ueberschrift mit einem # mehr als die vorherige wird als
Unterpunkt eingerueckt.
Unterpunkt eingerueckt. prefix erlaubt Links auf eine andere Seite
(z.B. "index.html" -> href="index.html#anker").
headings: Liste von (level, anker, text).
"""
if not headings:
@@ -290,7 +291,7 @@ def heading_nav(headings):
parts.append("</li></ul>")
levels.pop()
parts.append("</li>")
parts.append('<li><a href="#%s">%s</a>' % (hid, _escape(text)))
parts.append('<li><a href="%s#%s">%s</a>' % (prefix, hid, _escape(text)))
parts.append("</li>")
while len(levels) > 1:
parts.append("</ul></li>")
@@ -354,7 +355,7 @@ def block_html(slug):
return ""
def render_page(raw, template, header_html="", footer_html=""):
def render_page(raw, template, header_html="", footer_html="", start_anker_html=""):
meta, body = parse_md(raw)
headings = []
html = md_to_html(body, headings)
@@ -363,10 +364,14 @@ def render_page(raw, template, header_html="", footer_html=""):
.replace("{{titel}}", _escape(meta.get("titel", "")))
.replace("{{beschreibung}}", _escape(meta.get("beschreibung", "")))
.replace("{{inhalt}}", html))
# {{anker-start}}: Navigation der Startseite, verlinkt auf index.html#anker
if "{{anker-start}}" in template:
page = page.replace("{{anker-start}}", start_anker_html)
if "{{anker}}" in template:
page = page.replace("{{anker}}", anker_html)
elif anker_html and "{{header}}" in template:
# Template ohne {{anker}}-Platzhalter: Anker ans Ende des Headers
elif (anker_html and "{{anker-start}}" not in template
and "{{header}}" in template):
# Template ganz ohne Anker-Platzhalter: eigene Anker ans Header-Ende
page = page.replace("{{header}}",
header_html + '\n<nav class="anker-nav">' + anker_html + "</nav>")
if "{{header}}" in template:
@@ -384,7 +389,17 @@ def render_page(raw, template, header_html="", footer_html=""):
return page, meta.get("titel", "")
def load_template():
def load_template(slug=None):
"""Template fuer eine Seite: templates/<slug>.html wenn vorhanden,
sonst default.html, sonst das erste gefundene Template."""
candidates = []
if slug:
candidates.append(os.path.join(TPL_DIR, slug + ".html"))
candidates.append(os.path.join(TPL_DIR, "default.html"))
for c in candidates:
if os.path.exists(c):
with open(c, encoding="utf-8") as fh:
return fh.read()
files = [f for f in os.listdir(TPL_DIR) if f.endswith(".html")]
if not files:
raise SystemExit("Kein Template in templates/ gefunden (z.B. default.html).")
@@ -394,7 +409,6 @@ def load_template():
def export_site():
"""Baut output/: pro MD-Datei eine HTML-Seite, CSS wird kopiert."""
template = load_template()
# Output leeren und neu aufbauen
if os.path.isdir(OUT_DIR):
shutil.rmtree(OUT_DIR)
@@ -412,9 +426,19 @@ def export_site():
footer_html = block_html(FOOTER_PAGE)
header_html = block_html(HEADER_PAGE)
# Anker-Navigation der Startseite (fuer Templates mit {{anker-start}},
# z.B. impressum: Links auf index.html#anker)
start_headings = []
if os.path.exists(md_path(START_PAGE)):
_, s_body = parse_md(load_page(START_PAGE))
md_to_html(s_body, start_headings)
start_anker = heading_nav(start_headings, prefix="index.html")
exported = []
for slug in list_pages():
page, _ = render_page(load_page(slug), template, header_html, footer_html)
template = load_template(slug)
page, _ = render_page(load_page(slug), template, header_html, footer_html,
start_anker)
# startseite.md wird zur index.html
out_name = "index.html" if slug == START_PAGE else slug + ".html"
with open(os.path.join(OUT_DIR, out_name), "w", encoding="utf-8") as fh: