@link :section links to a section by its heading, with an alone value (from dev 831455f36fcd)
A section link names the TEXT of a heading: :section alone means the current file, a value names the file of the same @document that has it. Resolved by @document at assembly in html and tex; errors for a missing file, a missing title, a doubled title and a link outside a @document. The Markdown converter reads a Markdown anchor as a section link to the heading its slug names. Also from dev: the converter's four silent defects fixed and --chapter (9ae2c4cd), and the engine's alone-value error text. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
32aa47d41c
commit
f4dcdf3ffd
15 files changed
+594
-114
No files matched your search
@@ -1,8 +1,19 @@
|
||||
|
||||
// In-text links to a section on another (or the same) page of a book:
|
||||
// <a class="pagelink" data-page="BASENAME" data-id="ID">, which @document
|
||||
// emits for @link ... :section @ (document_html.cpp, resolve_section_links).
|
||||
// go_to_section() swaps in the embedded page and scrolls to the id, and
|
||||
// calls this again for the links of the page it just showed. Each anchor
|
||||
// is bound once: a page shown twice is the same nodes bound twice otherwise.
|
||||
function set_link_listeners() {
|
||||
Array.from(document.getElementsByClassName("pagelink")).forEach(
|
||||
function (elt) {
|
||||
if (elt.getAttribute("data-bound")) {
|
||||
return;
|
||||
}
|
||||
elt.setAttribute("data-bound", "true");
|
||||
elt.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
let basename = elt.getAttribute("data-page");
|
||||
let id = elt.getAttribute("data-id");
|
||||
go_to_section(elt, basename, id);
|
||||
@@ -10,3 +21,4 @@ function set_link_listeners() {
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener("load", set_link_listeners);
|
||||
+27
-3
@@ -1,15 +1,39 @@
|
||||
@@@argtype section_link |
|
||||
treat the link target as a section title, not an id.
|
||||
|
||||
If ^:section is present but does not have a value, the section title is in
|
||||
the current file.
|
||||
|
||||
If ^:section has a value, then it is the basename (no directory; no
|
||||
extension) of the file in the same document that contains the section with
|
||||
that title.
|
||||
:pattern [A-Za-z0-9_.-]+
|
||||
:default false
|
||||
:alone true
|
||||
@@@
|
||||
|
||||
@@link.k target
|
||||
:text
|
||||
:footnote.bool false
|
||||
:section.bool false
|
||||
:section.section_link
|
||||
:nq.bool false
|
||||
:basename # xxx -- Deprecated?
|
||||
:code # xxx
|
||||
:phrase # xxx
|
||||
:dox # xxx
|
||||
:doxanchor # xxx
|
||||
:id # xxx
|
||||
: Links within documents and to external URLs.
|
||||
:
|
||||
|
||||
Links within documents and to external URLs.
|
||||
|
||||
With ^:section the target is a section title, matched with klammer markup
|
||||
removed and whitespace collapsed to one space. Written alone, ^:section
|
||||
means the section is in the current file; written with a value, the value is
|
||||
the basename of the file of the same ^@document that has the section. A
|
||||
section link is resolved when ^@document assembles its files, so one outside
|
||||
a ^@document is an error, as is a title the file does not have, or has more
|
||||
than once (give one heading an ^:id and link to that).
|
||||
|
||||
@@
|
||||
|
||||
@@link.html,tex,txt :: @eval link.Link(K) eval@ @@
|
||||
|
||||
+28
-12
@@ -6,8 +6,25 @@ import klammer_base
|
||||
import urllib
|
||||
import kutil
|
||||
|
||||
def html_link(target, link_text, is_section, no_quotation_marks):
|
||||
# [__link__target__text__]
|
||||
# :section (argtype section_link, Andy 2026-10-12) is absent ("false"),
|
||||
# written alone ("true": the section is in the current file) or written
|
||||
# with a basename (the file that has the section). A section link is
|
||||
# resolved by @document when it assembles its files (sks/document/
|
||||
# section_link.h), from this marker: the heading's text and the file, ""
|
||||
# meaning the current one, separated by KTSL because either may contain an
|
||||
# underscore.
|
||||
def section_file(section):
|
||||
"""The file a :section value names: "" for the current file, None when
|
||||
the link is not a section link at all."""
|
||||
s = str(section)
|
||||
if s in ("", "false", "False"):
|
||||
return None
|
||||
return "" if s in ("true", "True") else s
|
||||
|
||||
def section_marker(title, file):
|
||||
return f"__seclink__{title}__KTSL__{file}__"
|
||||
|
||||
def html_link(target, link_text, is_section, no_quotation_marks, file=""):
|
||||
if not link_text:
|
||||
if is_section:
|
||||
link_text = target if no_quotation_marks else f"“{target}”"
|
||||
@@ -16,14 +33,11 @@ def html_link(target, link_text, is_section, no_quotation_marks):
|
||||
link_text = re.sub('/', '/<wbr/>', target)
|
||||
link_text = re.sub('/<wbr/>/<wbr/>', '//', link_text)
|
||||
link_text = f'<tt>{link_text}</tt>'
|
||||
target = f"[{target}]" if is_section else target
|
||||
#result = f"[__link__{target}__{link_text}__]"
|
||||
#return result
|
||||
|
||||
if target.startswith("http") or ".html" in target:
|
||||
if is_section:
|
||||
url = section_marker(target, file)
|
||||
elif target.startswith("http") or ".html" in target:
|
||||
url = target
|
||||
elif is_section:
|
||||
url = f"__sectionlink__{target}__"
|
||||
else:
|
||||
url = f"^#{target}"
|
||||
result = f'<a href="{url}">{link_text}</a>'
|
||||
@@ -38,7 +52,7 @@ def add_latex_footnote_if_necessary(url, link_text):
|
||||
result += f'\\footnote{{\\\rule{{0pt}}{{12pt}}\\texttt{{{escaped_url}}}}}'
|
||||
return result
|
||||
|
||||
def latex_link(target, link_text, is_section, no_quotation_marks, add_footnote):
|
||||
def latex_link(target, link_text, is_section, no_quotation_marks, add_footnote, file=""):
|
||||
if target.startswith("http"):
|
||||
if link_text and link_text != "URL":
|
||||
result = f"#/ \\href{{{target}}}{{{link_text}}} #/"
|
||||
@@ -48,7 +62,7 @@ def latex_link(target, link_text, is_section, no_quotation_marks, add_footnote):
|
||||
elif is_section:
|
||||
if not link_text:
|
||||
link_text = target if no_quotation_marks else f"``{target}''"
|
||||
result = f"\\hyperlink{{__seclink__{target}__}}{{{link_text}}}"
|
||||
result = f"\\hyperlink{{{section_marker(target, file)}}}{{{link_text}}}"
|
||||
else:
|
||||
result = f"\\hyperlink{{{target}}}{{{link_text}}}"
|
||||
# if add_footnote:
|
||||
@@ -63,10 +77,12 @@ class Link(klammer_base.Klammer_base):
|
||||
# self.show("Link")
|
||||
|
||||
def html(self):
|
||||
return html_link(self.target, self.text, self.section, self.nq)
|
||||
file = section_file(self.section)
|
||||
return html_link(self.target, self.text, file is not None, self.nq, file or "")
|
||||
|
||||
def tex(self):
|
||||
return latex_link(self.target, self.text, self.section, self.nq, self.footnote)
|
||||
file = section_file(self.section)
|
||||
return latex_link(self.target, self.text, file is not None, self.nq, self.footnote, file or "")
|
||||
|
||||
def txt(self):
|
||||
text = f'{self.text} ' if self.text else ''
|
||||
|
||||
Reference in new issue
Block a user