A @table now renders to txt. What it needed settled how plain text sets a block off from the prose around it, which is by INDENTING it: that is the only structural device the medium has, where html and LaTeX have boxes, rules and space. An indented block is one that has already been laid out, and the target leaves its lines alone. A caption is placed above a table or a listing and below a figure, in every target rather than only in plain text. A figure is taken in at a glance, and the caption then names what the reader has already seen; a table is read, and a reader who meets the rows before the subject has to read them twice. Also fixed, all three of them silent: an indented paragraph was dropped from plain-text output rather than left as written; an @indent block was re-flowed, so the indentation of its later lines appeared as gaps in the middle of a line; and a table captioned with ":number false" lost the rule under its caption, while an unnumbered table wrongly consumed a number that a reader counting captions would then find missing. (from dev 8173c371bba6)
235 lines
10 KiB
Plaintext
235 lines
10 KiB
Plaintext
# Table argument types and klammer declaration
|
|
|
|
@@@argtype index_subsets |
|
|
one or more subsets in parentheses, attached to an index. Each subset is a
|
|
single index <n>, a closed range <n>-<m>, or an open range <n>- (from <n> to
|
|
the end). A negative index counts from the end (-1 is the last). Several
|
|
subsets are separated by commas, with no spaces.
|
|
Example: (1-4,6-9)
|
|
:pattern \((?^:-?\d+(?^:-(?^:-?\d+)?)?)(?^:,-?\d+(?^:-(?^:-?\d+)?)?)*\)
|
|
@@@
|
|
|
|
@@@argtype indexed_range |
|
|
an index with optional subsets, written with no spaces. The index part is a
|
|
single index <i>, a closed index range <i>-<j>, or an open index range <i>-
|
|
(from <i> to the last index). It may be followed by parenthesized subsets
|
|
(see the index_subsets type) restricting the extent in the other dimension.
|
|
All indices are zero-origin. A negative index counts from the end, as in
|
|
Python: -1 is the last index, -2 the second to last. Ranges are inclusive,
|
|
so "1--2" is index 1 through the second-to-last index. Examples:
|
|
|
|
3 index 3, full extent
|
|
2-5 indices 2 through 5, full extent
|
|
3(1-4,6-9) index 3, restricted to 1 through 4 and 6 through 9
|
|
2-5(0-2) indices 2 through 5, each restricted to 0 through 2
|
|
-1 the last index
|
|
1--2 index 1 through the second-to-last index
|
|
|
|
:pattern -?\d+(?^:-(?^:-?\d+)?)?(?^:'index_subsets')?
|
|
@@@
|
|
|
|
@@@argtype column_width |
|
|
width of the table columns. Each column is one of 'fit' (widest line of the
|
|
cells in that column), 'fill' (the remaining width of the table after the
|
|
other columns, but no more than the column's widest line -- the table stops
|
|
growing once nothing needs a line break), a fraction 0.0->1.0 (that
|
|
fraction of the total table width), or '*' (the remaining width,
|
|
unconditionally -- the table always spans the full width). Several 'fill'
|
|
columns divide the remaining width in proportion to their widest lines;
|
|
'fill' cannot be combined with a fraction or '*'. If there are fewer
|
|
positions than columns in the table, the last value is repeated. Extra
|
|
positions generate a warning.
|
|
:pattern (fill^|fit^|f^|0?\.\d+^|\*^|\s+)+
|
|
:python_cast (lambda s : s.split())
|
|
:default fit
|
|
@@@
|
|
|
|
@@@argtype cell_hpos |
|
|
horizontal formatting in a table cell. One of 'l', 'c' or 'r' for each
|
|
cell in a row. If there are fewer positions than cells in a row, the
|
|
last value is repeated. Extra positions generate a warning.
|
|
:pattern (l^|c^|r^|\s+)+
|
|
:python_cast (lambda s : s.split())
|
|
:default l
|
|
@@@
|
|
|
|
@@@argtype table_hline |
|
|
|
|
a table's horizontal lines, as one or more whitespace-separated items.
|
|
With N rows there are N+1 horizontal boundaries, numbered 0 to N from the
|
|
top; boundary i lies above row i, and boundary N is the bottom. An item
|
|
is either a boundary name or an indexed_range of boundary indices. The
|
|
names are 'top' (boundary 0), 'head' (boundary 1, under a header row),
|
|
'bottom' (boundary N), 'inner' (all boundaries between top and bottom),
|
|
'all' (every boundary), and 'none' (no lines). A name or index may be
|
|
followed by parenthesized subsets to draw only part of a line, given as
|
|
zero-origin column ranges. When ^:hline is given it replaces the default
|
|
lines (with a header, 'head' and 'bottom'); ^:hline none removes them.
|
|
Examples:
|
|
|
|
top bottom lines above and below the table
|
|
head(1-) a line under the header, from column 1 to the last
|
|
3(1-4,6-9) two partial lines at boundary 3
|
|
all every line
|
|
none no lines
|
|
|
|
:pattern ((?^:top^|head^|inner^|bottom^|all^|none)(?^:'index_subsets')?^|'indexed_range'^|\s+)+
|
|
:python_cast (lambda s : s.split())
|
|
:alone all
|
|
@@@
|
|
|
|
@@@argtype table_vline |
|
|
|
|
a table's vertical lines, as one or more whitespace-separated items.
|
|
With M columns there are M+1 vertical boundaries, numbered 0 to M from
|
|
the left; boundary i lies to the left of column i, and boundary M is the
|
|
right edge. An item is either a boundary name or an indexed_range of
|
|
boundary indices. The names are 'outer' (boundaries 0 and M), 'inner'
|
|
(all boundaries between them), 'all' (every boundary), and 'none' (no
|
|
lines). A name or index may be followed by parenthesized subsets to
|
|
draw only part of a line, given as zero-origin row ranges. Examples:
|
|
|
|
outer lines at the left and right edges
|
|
2(0-3) a line left of column 2, spanning rows 0 through 3
|
|
all every line
|
|
|
|
:pattern ((?^:outer^|inner^|all^|none)(?^:'index_subsets')?^|'indexed_range'^|\s+)+
|
|
:python_cast (lambda s : s.split())
|
|
:alone all
|
|
@@@
|
|
|
|
@@@argtype table_span |
|
|
|
|
a list of cell spans, each an indexed_range whose index selects the row
|
|
(for colspan) or the column (for rowspan), and whose parenthesized subset
|
|
gives the zero-origin range of cells to merge. An index range repeats
|
|
the same span; several subsets make several spans. Examples for colspan:
|
|
|
|
1(2-4) in row 1, merge columns 2 through 4
|
|
1(0-1,3-5) two merges in row 1
|
|
2-4(0-1) the same merge in rows 2 through 4
|
|
|
|
:pattern ('indexed_range'^|\s+)+
|
|
:python_cast (lambda s : s.split())
|
|
@@@
|
|
|
|
@@@argtype table_calc |
|
|
|
|
calculations that fill table cells with computed values, separated by
|
|
semicolons. Each calculation has the form
|
|
|
|
<target> = <operator> <operand> <operand> ...
|
|
|
|
where the operator is one of + - * / and each operand is a cell selection
|
|
or a number. A cell selection is an indexed_range read as <rows>(<columns>);
|
|
a range expands to all of its cells in row order, so "+ 1-2(3)" sums column 3
|
|
of rows 1 and 2. The SHAPE of the target chooses the operation: a single
|
|
cell <row>(<column>) folds the operands to one value, while a target that
|
|
ranges over rows (0-(2)) or columns (-1(0-)) runs the calculation once per
|
|
row or column (a "map"). See notes/calc_notation.md for the map forms,
|
|
relative operands, and broadcasting. A plain number is a constant
|
|
and always uses a period as its decimal mark. Operators fold from the
|
|
left ("- 1(0-2)" is a minus b minus c); with a single operand, - negates
|
|
and / gives the reciprocal. Calculations run in the order given, and each
|
|
reads the values earlier calculations have written, as displayed.
|
|
Negative indices count from the end (see indexed_range), which is handy
|
|
when a total sits in the last row: "-1(5) = + 1--2(5)" writes into the
|
|
last row of column 5 the sum of that column from row 1 through the row
|
|
above it. Example:
|
|
|
|
1(3) = * 1(1-2) ;
|
|
2(3) = * 2(1-2) ;
|
|
3(3) = + 1-2(3)
|
|
|
|
# Coarse structural check only -- "<target> = <op> <operand>..." groups
|
|
# separated by ";" -- so that a malformed target or operand reaches
|
|
# run_calc() in table.py, whose per-token validation gives a precise message
|
|
# (e.g. an infix "* a * b" reports that "*" is not a number or a cell
|
|
# selection) instead of this whole description being dumped. A token is any
|
|
# run of characters other than space, ";", or "=" ("^^" escapes the regex
|
|
# class negation "[^...]" so the Klammertext "^" is not consumed).
|
|
:pattern \s*([^^\s;=]+\s*=\s*[-+*/](\s+[^^\s;=]+)+\s*(;\s*^|\s*$))+
|
|
|
|
@@@
|
|
|
|
@@@argtype decimal_mark |
|
|
the character used as the decimal mark in numeric cell values, either
|
|
'period' (1,234.56) or 'comma' (1.234,56). Governs both the reading of
|
|
numbers from cells in table calculations and the formatting of
|
|
calculated values.
|
|
:pattern period^|comma
|
|
:default period
|
|
:alone comma
|
|
@@@
|
|
|
|
@@@argtype table_justify |
|
|
cell justification overrides, as one or more <cells> <position> pairs
|
|
separated by semicolons (the same list style as ^:calc). <cells> is an
|
|
indexed_range selecting cells; <position> is l, c, or r and overrides
|
|
the column justification given by ^:cell_hpos for those cells. A colspan
|
|
anchor's override justifies the whole merged cell. For example,
|
|
"-3--1(3) r" right-justifies the cells in column 3 of the last three
|
|
rows.
|
|
# Coarse check ("<cells> <position>" pairs); justify_overrides() in
|
|
# table.py validates the range and position.
|
|
:pattern \s*([^^\s;]+\s+[lcr]\s*(;\s*^|\s*$))+
|
|
@@@
|
|
|
|
@@@argtype table_format |
|
|
cell formatting, as one or more <cells> <function> pairs separated by
|
|
semicolons (the same list style as :calc). <cells> is an indexed_range
|
|
selecting the cells to format; <function> is a <module>.<function> Python
|
|
reference (the same form the eval klammer uses) to a function that takes the
|
|
cell's value and the target and returns the formatted text. The function
|
|
lives in a module the writer supplies (a currency style is specific to a
|
|
document, so the SKS ships none): for example, with a euro() function in
|
|
your own module, "0-(5) myformats.euro" formats every cell of column 5 as a
|
|
Euro amount. Runs after :calc, so it formats computed values; a cell whose
|
|
value is not a number is left unchanged, with a warning.
|
|
# Coarse check ("<cells> <function>" pairs); apply_formats() in table.py
|
|
# validates the range and calls the function.
|
|
:pattern \s*([^^\s;]+\s+[^^\s;]+\s*(;\s*^|\s*$))+
|
|
@@@
|
|
|
|
@@rowcolor.k c : Change the color of a table row to color *c* @@
|
|
@@rowcolor.tex :: \colorrow{*s*} @@
|
|
|
|
@@table.k rows.rest(2)
|
|
:id
|
|
@caption_args :caption_side top @
|
|
@hpos_args@
|
|
:header.bool true
|
|
:allow_break.bool false
|
|
:column_width.column_width
|
|
:hline.table_hline
|
|
:vline.table_vline
|
|
:grid.bool false
|
|
:cell_hpos.cell_hpos
|
|
:justify.table_justify
|
|
:header_style.style_code i
|
|
:style.style_code_list
|
|
:colspan.table_span
|
|
:rowspan.table_span
|
|
:calc.table_calc
|
|
:format.table_format
|
|
:decimal.decimal_mark
|
|
:leading.float 1.3
|
|
:colsep 4pt
|
|
:
|
|
A table of rows of cells. The cells of a row are separated by "|" and the
|
|
rows by "||", so the argument is two-dimensional; the first row is the
|
|
header unless ^:header is false.
|
|
|
|
Everything else is optional, and a table written with no options is a plain
|
|
grid of its cells. ^:column_width lays the columns out, ^:hline and ^:vline
|
|
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.
|
|
@@
|
|
|
|
@@table.html,tex,txt :: @eval table.Table(K) eval@ @@
|
|
|
|
@@tbl.k spec.figure_id : The caption title for a table @@
|
|
@@tbl.html,tex,txt :: @reference *spec* | Table @ @@
|