Add chapter headers

This commit is contained in:
mark committed 2026-09-28 22:39:57 -04:00
1 parent 48daaf7ce3
commit e087ba9933
3 files changed
+31 -11

No files matched your search

+16 -2
View File
@@ -3,17 +3,31 @@
"Times New Roman", serif; "Times New Roman", serif;
} }
/* Both of these are links to their own id. They keep the text colour they
had as plain numbers, since an underlined blue verse number in the middle
of a sentence reads as part of the text. */
.v,
.chapter-number a {
color: var(--bs-secondary-color);
text-decoration: none;
}
.v:hover,
.chapter-number a:hover {
color: var(--bs-emphasis-color);
}
.v { .v {
font-size: .7em; font-size: .7em;
font-weight: 700; font-weight: 700;
vertical-align: super; vertical-align: super;
line-height: 0; line-height: 0;
margin-right: .15em; margin-right: .15em;
color: var(--bs-secondary-color);
user-select: none; user-select: none;
} }
.v:focus-visible { .v:focus-visible,
.chapter-number a:focus-visible {
outline: 2px solid var(--bs-primary); outline: 2px solid var(--bs-primary);
outline-offset: 2px; outline-offset: 2px;
border-radius: 2px; border-radius: 2px;
+4 -5
View File
@@ -46,15 +46,14 @@
<main class="container-xl my-4"> <main class="container-xl my-4">
<div class="row justify-content-center"> <div class="row justify-content-center">
{# A verse number is a link to itself, so the browser handles the jump and
the address bar; this only adds the dialog on top. Enter comes free
with the link, which is why there is no key handler here. #}
<div id="content" class="col-12 col-xl-8" hx-history-elt <div id="content" class="col-12 col-xl-8" hx-history-elt
hx-on:click="var verse = event.target.closest('.v[id]'); hx-on:click="var verse = event.target.closest('.v[id]');
if (verse) htmx.ajax('GET', 'api/verse?at=' + verse.id, if (verse) htmx.ajax('GET', 'api/verse?at=' + verse.id,
{ target: '#verse-dialog .modal-content', { target: '#verse-dialog .modal-content',
swap: 'innerHTML' });" swap: 'innerHTML' });">
hx-on:keydown="if (event.key !== 'Enter' &amp;&amp; event.key !== ' ') return;
if (!event.target.matches('.v[id]')) return;
event.preventDefault();
event.target.click();">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</div> </div>
+11 -4
View File
@@ -460,11 +460,16 @@ def render_inline(nodes, book, chapter, out):
out.append(esc(node["v"])) out.append(esc(node["v"]))
elif kind == "verse": elif kind == "verse":
label = esc(node["label"]) label = esc(node["label"])
out.append('<span class="v" id="%s" role="button" tabindex="0" ' vid = verse_id(chapter, node["label"])
# A link to itself: the click both puts the verse in the address
# bar, which is what the options dialog offers to copy, and opens
# that dialog. Being a real link is also what gives it the
# keyboard and context menu a reader expects.
out.append('<a class="v" id="%s" href="#%s" '
# A non-breaking space keeps the number on the same # A non-breaking space keeps the number on the same
# line as the word it introduces, as the source does. # line as the word it introduces, as the source does.
'aria-label="Verse %s, options">%s</span>&#160;' 'aria-label="Verse %s, options">%s</a>&#160;'
% (verse_id(chapter, node["label"]), label, label)) % (vid, vid, label, label))
elif kind == "noteref": elif kind == "noteref":
n = node["id"].replace("FN", "") n = node["id"].replace("FN", "")
out.append('<a class="noteref" id="fnref%s_%s" href="#fn%s_%s">' out.append('<a class="noteref" id="fnref%s_%s" href="#fn%s_%s">'
@@ -531,7 +536,9 @@ def render_chapter(chapter, book, out):
num = chapter["number"] num = chapter["number"]
out.append(' <section class="chapter" id="ch%d" data-chapter="%d">\n' out.append(' <section class="chapter" id="ch%d" data-chapter="%d">\n'
% (num, num)) % (num, num))
out.append(' <h2 class="chapter-number">%d</h2>\n' % num) out.append(' <h2 class="chapter-number">'
'<a href="#ch%d" aria-label="Chapter %d">%d</a></h2>\n'
% (num, num, num))
group = None group = None