Width and height argtypes, kdesc --argtypes from ref/, txt @define/@left_right/@columns, kdiag --check value validation (from dev d6993110e9b3)

Also: the klammertext argtype (descriptions kept as source), txt table
wrapping and :hpos/:offset, @c between ‹ ›, txt section headings, the
ktext newline-only trim, capitalize(), and the argtype test suite.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ackandClaude Fable 5.1 committed 2026-09-16 16:59:49 +02:00
1 parent 9b0d0d7897
commit 0ead40f272
39 files changed
+734 -158

No files matched your search

+2 -2
View File
@@ -223,11 +223,11 @@ def hpos_container(element, hpos, offset=None):
# coded, and only in html.)
styles = []
if hpos not in ("left", "center", "right", "none"):
length, _, _ = kutil.parse_length("html", hpos, 1)
length, _, _ = kutil.parse_width("html", hpos)
styles.append(f"margin-left: {length}")
hpos = "indent"
if offset and offset not in ("0", "0pt") and hpos in ("left", "right", "indent"):
length, _, _ = kutil.parse_length("html", offset, 1)
length, _, _ = kutil.parse_width("html", offset)
side = "right" if hpos == "right" else "left"
styles.append(f"padding-{side}: {length}")
result = E("div").cls("hpos_" + hpos).body(element)
+3 -3
View File
@@ -81,9 +81,9 @@ def minipage(content, width="\\textwidth", vertical="c", center=True, vmargin=""
def offset_length(offset):
r"""An :offset as a LaTeX length, or "0pt" when there is none."""
if not offset or offset in ("0", "0pt"):
if not offset or offset in ("0", "0pt", "0.0"):
return "0pt"
return kutil.parse_length("tex", offset, 1)[0]
return kutil.parse_width("tex", offset)[0]
def offset_space(offset):
r"""An :offset as an \hspace*, or "" when there is none."""
@@ -111,7 +111,7 @@ def caption_wrapper(element, hpos, bottom_margin=0, offset=None):
return minipage("\\hfill" + element + inset, vmargin=vmargin, center=False)
if hpos == "none":
return element
length, _, _ = kutil.parse_length("tex", hpos, 1)
length, _, _ = kutil.parse_width("tex", hpos)
return minipage(f"\\hspace*{{{length}}}" + element + "\\hfill",
vmargin=vmargin, center=False)
+23 -2
View File
@@ -25,6 +25,26 @@ def txt_vspace_marker():
def txt_nbsp_marker():
return "__KTEXTNBSP__"
# A ZERO-WIDTH mark that says "this line is already laid out" (2026-09-16).
# The justification pass takes a paragraph beginning with a space or the
# nbsp marker as verbatim, and until now that was the only way a block
# could say so -- which broke the moment a block was flush left: a @table
# with :hpos left :offset 0 (what @columns emits) began with its first
# cell, so its rows were re-flowed into one line. A block that lays itself
# out puts this at the start of every line (txt_lay_out); it is nothing to
# txt_visible_length and is removed at the end of txt_justify_blocks.
def txt_verbatim_marker():
return "__KTEXTVERBATIM__"
def txt_lay_out(text):
"""text with every line marked as already laid out."""
mark = txt_verbatim_marker()
return "\n".join(mark + line for line in text.split("\n"))
def txt_is_laid_out(par):
"""True for a paragraph the justification pass must leave alone."""
return par.startswith((" ", txt_nbsp_marker(), txt_verbatim_marker()))
# The type-style markers, emitted by @b.txt, @i.txt, @u.txt and @ri.txt
# (sks/font/font.k) around their text. Plain text has no bold, but a
# terminal does: the txt target STRIPS these in its last phase
@@ -68,7 +88,7 @@ def txt_visible_length(s):
"""How many columns s occupies once its markers resolve: a KTESC
marker is one glyph, an nbsp marker one space, a style marker nothing.
len() is the wrong measure for anything laid out (see txt_util)."""
s = _STYLE_MARKER_RGX.sub("", s)
s = _STYLE_MARKER_RGX.sub("", s).replace(txt_verbatim_marker(), "")
return len(klammer_base.unescape_ktesc(s).replace(txt_nbsp_marker(), " "))
def txt_wrap(text, width, subsequent_indent=""):
@@ -159,7 +179,7 @@ def txt_justify_blocks(text, K):
# branch that had nothing to do also did not copy the text through.
# An indented paragraph vanished from the output with no error.
nbsp = txt_nbsp_marker()
if par and par[0] != ' ' and not par.startswith(nbsp):
if par and not txt_is_laid_out(par):
label = re.match("(?:" + re.escape(nbsp) + r")*\[\d+\] ", par)
par = "\n".join(txt_wrap(
par, int(K.Target_txt_width),
@@ -167,6 +187,7 @@ def txt_justify_blocks(text, K):
result += par + "\n\n"
result = re.sub(" *" + txt_vspace_marker() + " *", "\n", result)
result = re.sub(r"\n? *" + txt_nl_marker() + r" *\n?", "\n", result)
result = result.replace(txt_verbatim_marker(), "")
result = result.replace(txt_nbsp_marker(), " ")
return result
+2 -2
View File
@@ -38,7 +38,7 @@ of this: neither the transforms nor the quoting reach it.
@@@state Target_txt_indent
:desc Width of indentation in the plain text target (txt)
:value 3
:value 2
@@@
# The txt target is not fully implemented in the SKS yet.
@@ -59,7 +59,7 @@ of this: neither the transforms nor the quoting reach it.
--- -- |
`` " |
'' " |
` ` |
` ' |
' ' |
~ __KTEXTNBSP__
:after_apply