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
@@ -58,8 +58,21 @@ td {
|
||||
--cell-border: 1px black solid;
|
||||
}
|
||||
|
||||
/* The space between a rule and the text on either side of it: a cell is
|
||||
padded on the side that CARRIES the rule, so a row with no rule is
|
||||
untouched, a partial :hline pads only the cells it crosses, and the
|
||||
table's outer rules are padded on the inner side alone. The amounts
|
||||
began as booktabs' defaults (0.4ex above a rule, 0.65ex below one) and
|
||||
were tuned by eye, 2026-09-20: half of the space below moved above, so
|
||||
0.725ex above and 0.325ex below, the total unchanged. The tex target's
|
||||
pair is in table.py (TEX_RULE_ABOVE/_BELOW) and differs on purpose -- a
|
||||
TeX row and an html row distribute their own height differently around
|
||||
the text. --rulesep is @table's :rulesep, a multiplier, set on the
|
||||
<table> by table.py. "ex" is the x-height as RENDERED
|
||||
(font-size-adjust), so the space tracks the visible type. */
|
||||
.Bt {
|
||||
border-top: var(--cell-border);
|
||||
padding-top: calc(var(--rulesep, 1) * 0.325ex);
|
||||
}
|
||||
|
||||
.Br {
|
||||
@@ -68,6 +81,7 @@ td {
|
||||
|
||||
.Bb {
|
||||
border-bottom: var(--cell-border);
|
||||
padding-bottom: calc(var(--rulesep, 1) * 0.725ex);
|
||||
}
|
||||
|
||||
.Bl {
|
||||
|
||||
+11
-1
@@ -213,7 +213,8 @@
|
||||
:calc.table_calc
|
||||
:format.table_format
|
||||
:decimal.decimal_mark
|
||||
:leading.float 1.3
|
||||
:leading.float 1.0
|
||||
:rulesep.float 1
|
||||
:colsep 4pt
|
||||
:
|
||||
A table of rows of cells. The cells of a row are separated by "|" and the
|
||||
@@ -226,6 +227,15 @@ draw lines, ^:colspan and ^:rowspan merge cells, ^:justify and ^:cell_hpos
|
||||
place text within them, ^:calc computes cells from other cells and ^:format
|
||||
formats them, and ^:hpos and ^:offset place the whole table in the text
|
||||
column.
|
||||
|
||||
^:leading is the height of a row in lines of the surrounding text, the same
|
||||
in html and pdf. ^:rulesep is the space between a horizontal line and the
|
||||
text on either side of it, as a multiple of the standard amount (slightly
|
||||
more below a line than above it); 0 sets the lines against the rows. The
|
||||
lines at the top and the bottom of the table are spaced on their inner side
|
||||
only. A table with vertical lines gets no such space in a pdf, where it
|
||||
would break them. Neither argument has a meaning in plain text, where a row
|
||||
is a line of characters and a horizontal line already has a line to itself.
|
||||
@@
|
||||
|
||||
@@table.html,tex,txt :: @eval table.Table(K) eval@ @@
|
||||
|
||||
+77
-29
@@ -575,23 +575,39 @@ class Table(klammer_base.Klammer_base):
|
||||
# would wrap it as a stray <p> inside the table.
|
||||
return E("colgroup").body(cols.strip(), newline=False).str(), layout, table_width
|
||||
|
||||
def html_style(self):
|
||||
# :leading and :colsep under html (2026-09-18; both were tex-only).
|
||||
# \arraystretch multiplies the row strut, which is \baselineskip,
|
||||
# 1.2 times the font size -- so :leading L is a 1.2 L em row, and
|
||||
# the html equivalent is that line-height on the table, inherited
|
||||
# by every cell. The cells' vertical padding went with it
|
||||
# (table.css): an html-only extra with no tex counterpart, which
|
||||
# kept a :leading 1 table 0.3rem looser per row than its pdf.
|
||||
# :colsep is a custom property the td rule reads for its horizontal
|
||||
# padding (padding does not inherit); the flush-edge classes still
|
||||
# zero the outer ones. Measured 2026-09-18: rows of :leading 1 and
|
||||
# :leading 2 in the ratio 1:2 in both targets.
|
||||
line_height = f"{1.2 * float(self.leading):.4g}"
|
||||
def html_style(self, layout=""):
|
||||
# The WHOLE style attribute of the <table>, written once: "layout" is
|
||||
# the width declarations the caller has worked out (max-width for a
|
||||
# fill table, table-layout/width for fractions). E.attr() appends,
|
||||
# so a second .attr("style", ...) made a second attribute, which a
|
||||
# browser discards -- from 2026-09-18, when this function arrived,
|
||||
# to 2026-09-20 every width declaration was lost that way.
|
||||
# :leading and :colsep under html. ":leading L" is L times the pitch
|
||||
# of a line of the surrounding TEXT, in every target. tex has that
|
||||
# by construction: \arraystretch multiplies the row strut, which is
|
||||
# the \baselineskip in force. The html counterpart of \baselineskip
|
||||
# is --text_line_height (font.css, 1.5), so the table's line-height
|
||||
# is L times that, inherited by every cell. It was 1.2 L from
|
||||
# 2026-09-18 to 09-20, LaTeX's ratio of \baselineskip to font size:
|
||||
# wrong in html, where font-size-adjust draws the type larger than
|
||||
# the nominal size line-height is computed from, so a :leading 1
|
||||
# table sat 16% tighter than the paragraphs around it (measured:
|
||||
# 20.2px rows beside 24px text, where the pdf had 14.2pt beside
|
||||
# 14.2pt). The fallback serves a fragment without the stylesheet.
|
||||
# The cells have no vertical padding (table.css): an html-only extra
|
||||
# with no tex counterpart. :colsep is a custom property the td rule
|
||||
# reads for its horizontal padding (padding does not inherit); the
|
||||
# flush-edge classes still zero the outer ones.
|
||||
line_height = f"calc({float(self.leading):.4g} * var(--text_line_height, 1.5))"
|
||||
# Hidden: the result is re-read and the html target's transforms
|
||||
# would turn the property's "--" into an en dash (font.py's trap).
|
||||
return klammer_base.hide_typographic(
|
||||
f"line-height: {line_height}; --colsep: {self.colsep}")
|
||||
# :rulesep is a custom property too: the .Bt/.Bb rules (table.css)
|
||||
# read it for the padding on the side of a cell that carries a rule.
|
||||
style = (f"line-height: {line_height}; --colsep: {self.colsep}; "
|
||||
f"--rulesep: {float(self.rulesep):.4g}")
|
||||
if layout:
|
||||
style += "; " + layout.strip().rstrip(";")
|
||||
return klammer_base.hide_typographic(style)
|
||||
|
||||
def html(self):
|
||||
result = ""
|
||||
@@ -610,8 +626,10 @@ class Table(klammer_base.Klammer_base):
|
||||
# algorithm), matching the tex \ratio division. The max-width
|
||||
# cap goes on the caption wrapper when there is one (the table's
|
||||
# own percentage would be circular in a shrink-to-fit wrapper).
|
||||
result = E("table").body(result).attr("style", self.html_style())
|
||||
if self.number or self.caption:
|
||||
captioned = self.number or self.caption
|
||||
result = E("table").body(result).attr(
|
||||
"style", self.html_style("" if captioned else "max-width: 100%"))
|
||||
if captioned:
|
||||
result = html_util.add_caption(
|
||||
result, "Table", self.number, self.caption,
|
||||
self.caption_style, hpos=self.hpos,
|
||||
@@ -619,17 +637,19 @@ class Table(klammer_base.Klammer_base):
|
||||
font_size=self.caption_size, max_width="100%",
|
||||
offset=self.offset)
|
||||
else:
|
||||
result.attr("style", "max-width: 100%")
|
||||
result = html_util.hpos_container(result, self.hpos, self.offset).str()
|
||||
return result
|
||||
colgroup, layout, table_width = self.html_colgroup()
|
||||
result = E("table").body(colgroup + result).attr("style", self.html_style())
|
||||
if self.number or self.caption:
|
||||
captioned = self.number or self.caption
|
||||
table_layout = ""
|
||||
if table_width:
|
||||
table_layout = f"{layout}width: " + ("100%" if captioned else table_width)
|
||||
result = E("table").body(colgroup + result).attr(
|
||||
"style", self.html_style(table_layout))
|
||||
if captioned:
|
||||
# The caption wrapper carries the width (a percentage on the
|
||||
# shrink-to-fit wrapper itself would be circular) and the table
|
||||
# fills it -- which also makes the caption track the table.
|
||||
if table_width:
|
||||
result.attr("style", f"{layout}width: 100%")
|
||||
result = html_util.add_caption(
|
||||
result, "Table", self.number, self.caption, self.caption_style,
|
||||
hpos=self.hpos, side=self.caption_side,
|
||||
@@ -638,8 +658,6 @@ class Table(klammer_base.Klammer_base):
|
||||
else:
|
||||
# An uncaptioned table still gets the position container, so
|
||||
# html and tex agree on where the table sits.
|
||||
if table_width:
|
||||
result.attr("style", f"{layout}width: {table_width}")
|
||||
result = html_util.hpos_container(result, self.hpos, self.offset).str()
|
||||
return result
|
||||
|
||||
@@ -761,9 +779,32 @@ class Table(klammer_base.Klammer_base):
|
||||
# print("tex_column_spec:", "".join(parts))
|
||||
return "".join(parts)
|
||||
|
||||
TEX_RULE_ABOVE = 0.4 # ex; booktabs' \aboverulesep
|
||||
TEX_RULE_BELOW = 0.35 # 468 # ex; booktabs' \belowrulesep (0.65) less 20%, less 10%
|
||||
|
||||
def tex_rule_separations(self, top, bottom):
|
||||
# The space above and below a rule, as booktabs' \specialrule and
|
||||
# \cmidrule take them: :rulesep times TEX_RULE_ABOVE/_BELOW. They
|
||||
# began as booktabs' defaults (0.4ex above a rule, 0.65ex below) and
|
||||
# were tuned by eye, per target, 2026-09-20 (Andy): the amounts that
|
||||
# LOOK alike differ, because a TeX row carries its strut's depth
|
||||
# under the text and an html row its half-leading. The html pair is
|
||||
# in table.css (.Bt/.Bb). The table's outer rules are padded on the
|
||||
# INNER side only.
|
||||
rulesep = float(self.rulesep)
|
||||
above = "0pt" if top else f"{self.TEX_RULE_ABOVE * rulesep:.4g}ex"
|
||||
below = "0pt" if bottom else f"{self.TEX_RULE_BELOW * rulesep:.4g}ex"
|
||||
return above, below
|
||||
|
||||
def tex_hline(self, index):
|
||||
# Contiguous cell borders coalesce into single \cline runs; a
|
||||
# full-width line becomes \hline.
|
||||
# Contiguous cell borders coalesce into single rule runs. The rules
|
||||
# are booktabs' -- an \hline sits flush against the strut of the
|
||||
# rows on either side, and the only way to open space there is a
|
||||
# strut in every neighbouring row -- EXCEPT in a table with vertical
|
||||
# lines: a booktabs rule is set between rows, so it breaks every
|
||||
# vertical line it crosses (its author provides for none), and such
|
||||
# a table keeps \hline/\cline and gets no space at its rules.
|
||||
top = index == 0
|
||||
bottom = index == self.row_count
|
||||
if bottom:
|
||||
index -= 1
|
||||
@@ -773,7 +814,11 @@ class Table(klammer_base.Klammer_base):
|
||||
# No line through the interior of a merged (rowspan) cell.
|
||||
flags = [flag and (index, col_i) not in self.rowspan_covered
|
||||
for col_i, flag in enumerate(flags)]
|
||||
spaced = not self.s_vline.by_index and float(self.rulesep) > 0
|
||||
above, below = self.tex_rule_separations(top, bottom)
|
||||
if flags and all(flags):
|
||||
if spaced:
|
||||
return f"\\specialrule{{\\arrayrulewidth}}{{{above}}}{{{below}}}\n"
|
||||
return "\\hline\n"
|
||||
hline = ""
|
||||
start = None
|
||||
@@ -781,7 +826,10 @@ class Table(klammer_base.Klammer_base):
|
||||
if flag and start is None:
|
||||
start = i
|
||||
elif not flag and start is not None:
|
||||
hline += f"\\cline{{{start + 1}-{i}}} "
|
||||
if spaced:
|
||||
hline += f"\\cmidrule[\\arrayrulewidth]{{{start + 1}-{i}}} "
|
||||
else:
|
||||
hline += f"\\cline{{{start + 1}-{i}}} "
|
||||
start = None
|
||||
return hline.strip() + "\n"
|
||||
|
||||
@@ -1063,7 +1111,7 @@ class Table(klammer_base.Klammer_base):
|
||||
if len(rows) in self.s_hline.by_index:
|
||||
result += rule
|
||||
result = txt_util.add_caption(
|
||||
result, "Table", self.number, self.caption, self.caption_side, \
|
||||
int(self.Target_txt_indent))
|
||||
result, "Table", self.number, self.caption, self.caption_side,
|
||||
len(indent) // len(txt_util.NBSP))
|
||||
return result
|
||||
|
||||
Reference in new issue
Block a user