") elif kind == "ref": out.append('' % ref_href(node, book, chapter)) render_inline(node.get("c", []), book, chapter, out) out.append("") elif kind in INLINE_TAGS: tag, cls = INLINE_TAGS[kind] out.append('<%s class="%s">' % (tag, cls)) render_inline(node.get("c", []), book, chapter, out) out.append("%s>" % tag) else: # unknown node type: keep the words, drop the wrapper render_inline(node.get("c", []), book, chapter, out) def render_block(block, book, chapter, out): btype = block["type"] tag = BLOCK_TAGS.get(btype, "p") classes = [block["style"]] attrs = "" if "indent" in block: attrs += ' data-indent="%d"' % block["indent"] if btype == "line": classes.append("line") out.append(" <%s class=\"%s\"%s>" % (tag, " ".join(classes), attrs)) render_inline(block.get("content", []), book, chapter, out) out.append("%s>\n" % tag) # Footnote callers arrive from the source as * † ‡ § ✡. The star is the only # one of them a browser may decide is an emoji: no serif font carries a glyph # for U+2721, so the fallback chain reaches the colour emoji font and drops a # purple tile into the middle of a verse. U+FE0E is the standardised way to ask # for the text glyph of the same character -- the symbol, not the emoji. There # is no separate text codepoint to switch to; this is the only lever. TEXT_PRESENTATION = "\ufe0e" EMOJI_CAPABLE = "\u2721" def caller(marker): """A footnote marker, asked to render as text rather than as an emoji.""" return "".join(c + TEXT_PRESENTATION if c in EMOJI_CAPABLE else c for c in (marker or "*")) def render_notes(notes, chapter, book, out): if not notes: return out.append('
Notes
\n') out.append("- \n")
for note in notes:
n = (note["id"] or "").replace("FN", "")
out.append('
- ' % (chapter, n, note["kind"])) out.append('%s ' % esc(caller(note.get("marker")))) if note.get("ref"): out.append('%s ' % (chapter, n, esc(note["ref"]))) out.append('') render_inline(note["content"], book, chapter, out) out.append(" \n") out.append("
%d
\n' % num) group = None # "poetry" | "list" | None def close_group(): nonlocal group if group == "poetry": out.append("- \n')
group = want
render_block(block, book, num, out)
close_group()
render_notes(chapter["notes"], num, book, out)
out.append(" \n")
def render_book(book, translation, out_dir):
code, name = book["code"], book["name"]
out = []
title = "%s — %s" % (name, translation["name"])
# A fragment: the title the shell will use, then one root element whose
# data-template names the template that wraps it.
out.append("
- %s ' '%d \n' % (book["code"], esc(book["name"]), len(book["chapters"]))) out.append("
%s
\n- \n" % esc(label))
for book in group:
out.append('