katom types from ref/ in groups, @table :leading in lines of text and :rulesep, @code under txt, one table style attribute, literal-klammer options (from dev 2e453744f5e9)
kdesc --katoms is Klammertext rendered from ref/, the types in titled groups, with --katoms full for the regex column. @table :leading L is L lines of the surrounding text in html as in pdf (default 1), and :rulesep spaces the horizontal rules. The html table has one style attribute, so :column_width fractions take effect again. @code and @source_listing render in plain text; captions are numbered per kind there, and a table needs no blank line around it. @c takes :nd, and an option-shaped word before a bar inside literal code is code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
63956c00e5
commit
217c0f3fc5
23 files changed
+625
-290
No files matched your search
+73
-7
@@ -5,11 +5,13 @@
|
||||
|
||||
import re
|
||||
import klammer_base
|
||||
import kutil
|
||||
import html_util
|
||||
import txt_util
|
||||
import phases
|
||||
from html_util import E
|
||||
import latex_util as L
|
||||
|
||||
|
||||
def escape_newlines(s):
|
||||
# A newline becomes the marker the html paragraph pass turns back into a
|
||||
# line break, so a verbatim source file keeps its lines. Used by Source.
|
||||
@@ -119,7 +121,13 @@ def tex_line(line):
|
||||
a monospace font, which LaTeX will not collapse -- so the code's
|
||||
indentation and internal alignment survive.
|
||||
"""
|
||||
return quote_specials(escape_latex(line)).replace(" ", "~")
|
||||
# An apostrophe is hidden as a marker: after a quoted caret it would
|
||||
# otherwise read back as "^" + "^'", the opening of a literal span, and
|
||||
# "@c \^' c@" -- the regex of that very katom -- failed the document
|
||||
# with a span that does not end. html_line hides it with the other
|
||||
# typographic characters; the marker decodes to the plain character.
|
||||
quoted = quote_specials(escape_latex(line)).replace("'", klammer_base.escape_ktesc("'"))
|
||||
return quoted.replace(" ", "~")
|
||||
|
||||
def widest_line(lines):
|
||||
r"""The line to measure the block's width with.
|
||||
@@ -325,12 +333,64 @@ class Code(klammer_base.Klammer_base):
|
||||
# As in tex: the caption goes through the shared helper, so it sits
|
||||
# in the same position container as the listing and moves with it.
|
||||
if self.number or self.caption:
|
||||
# A left-placed (or flowing) listing's caption is flush with it,
|
||||
# as in tex, where such a listing is unboxed and its caption a
|
||||
# paragraph on the same indent; a centred or right-placed one is
|
||||
# boxed there and its caption centred over the box, which is
|
||||
# the helper's default here too.
|
||||
align = "left" if self.hpos in ("left", "none") else None
|
||||
return html_util.add_caption(
|
||||
listing, "Listing", self.number, self.caption,
|
||||
self.caption_style, self.hpos, self.caption_side, True,
|
||||
self.caption_size, offset=self.offset)
|
||||
self.caption_size, offset=self.offset, caption_align=align)
|
||||
return html_util.hpos_container(listing, self.hpos, self.offset).str()
|
||||
|
||||
def txt_indent(self):
|
||||
# The block's indent in columns, by @table's rule: a left- or
|
||||
# right-placed block is inset by its :offset (0 = flush), ":hpos
|
||||
# none" flows with no indent, and "center" -- not attempted in plain
|
||||
# text -- keeps the block convention, Target_txt_indent.
|
||||
if self.hpos in ("left", "right"):
|
||||
return int(kutil.parse_width("txt", self.offset)[0])
|
||||
if self.hpos == "none":
|
||||
return 0
|
||||
return int(self.Target_txt_indent)
|
||||
|
||||
def txt(self):
|
||||
# The listing is LAID OUT here, line by line, and says so with the
|
||||
# verbatim marker (phases.txt_lay_out) so the justification pass
|
||||
# leaves it alone -- a blank line in the code included, which holds
|
||||
# a marker and therefore does not end the paragraph.
|
||||
#
|
||||
# Each line is prepared exactly as txt()'s inline sibling prepares a
|
||||
# fragment: the Klammertext specials QUOTED, because this result is
|
||||
# re-read as Klammertext (raw, a "#" removed the rest of its line and
|
||||
# a "code@" in a quoted source file closed the document's own span:
|
||||
# "A named end katom does not match"), and the typographic characters
|
||||
# hidden, so "--x" stays two hyphens. Spaces become the nbsp marker
|
||||
# AFTER that, not "~": hide_typographic has already hidden the
|
||||
# code's own tildes, and a "~" written here would be turned into a
|
||||
# space by the txt target's transform only as long as it survived.
|
||||
lines = self.text.strip("\n").split("\n")
|
||||
indent = txt_util.NBSP * self.txt_indent()
|
||||
def prepared(line):
|
||||
line = klammer_base.hide_typographic(quote_specials(line.rstrip()))
|
||||
return line.replace(" ", txt_util.NBSP)
|
||||
width = max(len(line.rstrip()) for line in lines)
|
||||
rule = indent + klammer_base.hide_typographic("-" * width)
|
||||
body = [indent + prepared(line) for line in lines]
|
||||
# A caption above the listing is ruled off by the caption pass, so
|
||||
# the listing draws its own top rule only when nothing does.
|
||||
captioned = self.number or self.caption
|
||||
caption_above = captioned and self.caption_side in ("top", "left")
|
||||
if not caption_above:
|
||||
body.insert(0, rule)
|
||||
body.append(rule)
|
||||
result = phases.txt_lay_out("\n".join(body))
|
||||
return txt_util.add_caption(
|
||||
result, "Listing", self.number, self.caption, self.caption_side,
|
||||
self.txt_indent())
|
||||
|
||||
|
||||
class Code_fragment(klammer_base.Klammer_base):
|
||||
def __init__(self, K):
|
||||
@@ -356,10 +416,13 @@ class Code_fragment(klammer_base.Klammer_base):
|
||||
# without a beginning) and the typographically active characters
|
||||
# hidden, so a "--" in code stays two hyphens.
|
||||
result = klammer_base.hide_typographic(quote_specials(self.code_text.strip()))
|
||||
# Surround code symbols with ‹ and ›, though there are conflicts in Swiss
|
||||
# German, Italian and some Scandinavian languages. Should be clear in
|
||||
# context, though.
|
||||
result = "\u2039" + result + "\u203A"
|
||||
|
||||
# If *nd* ("no delimiters) is false (the default), surround code symbols
|
||||
# with the characters ‹ and ›. There are conflicts in Swiss German,
|
||||
# Italian and some Scandinavian languages, but the meaning should be
|
||||
# clear in context.
|
||||
if not self.nd:
|
||||
result = "\u2039" + result + "\u203A"
|
||||
return result
|
||||
|
||||
def extract_marked_region(src, marker, filename):
|
||||
@@ -424,6 +487,9 @@ class Source(Code):
|
||||
# not exist until the file has been read. File content carries no
|
||||
# whitespace markers anyway, since those come from the katomizer.
|
||||
klammer_base.Klammer_base.__init__(self, K)
|
||||
# The filename arrives with the target's escapes as markers -- under
|
||||
# tex an underscore is one -- and a marker names no file.
|
||||
self.filename = klammer_base.unescape_ktesc(self.filename)
|
||||
try:
|
||||
with open(self.filename) as fp:
|
||||
text = fp.read()
|
||||
|
||||
Reference in new issue
Block a user