summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/table.opm
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/optex/base/table.opm')
-rw-r--r--macros/luatex/optex/base/table.opm211
1 files changed, 211 insertions, 0 deletions
diff --git a/macros/luatex/optex/base/table.opm b/macros/luatex/optex/base/table.opm
new file mode 100644
index 0000000000..5fa252eeba
--- /dev/null
+++ b/macros/luatex/optex/base/table.opm
@@ -0,0 +1,211 @@
+%% This is part of OpTeX project, see http://petr.olsak.net/optex
+
+\_codedecl \table {Basic macros for OpTeX <2020-04-10>} % preloaded in format
+
+ \_doc -----------------------------
+ The result of the \`\table``{<declaration>}{<data>}` macro is inserted into
+ `\_tablebox`. You can change default value if you want by
+ `\let\_tablebox=\vtop` or `\let\_tablebox=\relax`.
+ \_cod -----------------------------
+
+\_let\_tablebox=\_vbox
+
+ \_doc -----------------------------
+ Categories (for example of `|` character) have to be normal when reading
+ `\table` parameters.
+ \_cod -----------------------------
+
+\_def\_table{\_tablebox\_bgroup \_catcodetable\_optexcatcodes \_tableA}
+\_public \table ;
+
+ \_doc -----------------------------
+ The \^`\tablinespace` is implemented by enlarging given \^`\tabstrut`
+ by desired dimension (height and depth too) and by setting
+ `\_lineskip=-2\_tablinespace`. Normal table rows (where no `\hrule` is
+ between them) have normal baseline distance.
+ \_cod -----------------------------
+
+\_def\_tableA#1{%
+ \_the\_thistable \_global\_thistable={}%
+ \_ea\_ifx\_ea^\_the\_tabstrut^\_setbox\_tstrutbox=\_null
+ \_else \_setbox\_tstrutbox=\_hbox{\_the\_tabstrut}%
+ \_setbox\_tstrutbox=\_hbox{\_vrule width0pt
+ height\_dimexpr\_ht\_tstrutbox+\_tablinespace
+ depth\_dimexpr\_dp\_tstrutbox+\_tablinespace}%
+ \_offinterlineskip
+ \_lineskip=-2\_tablinespace
+ \_fi
+ \_colnum=0 \_def\_tmpa{}\_tabdata={}\_scantabdata#1\_relax
+ \_the\_everytable \_tableB
+}
+\_def\_tableB#1{\_halign\_ea{\_the\_tabdata\_cr#1\_crcr}\_egroup}
+\_newbox\_tstrutbox % strut used in table rows
+\_newtoks\_tabdata % the \halign declaration line
+\_newcount\_colnum % number of columns
+
+ \_doc -----------------------------
+ The \`\_scantabdata` converts `\table`'s `<declaration>` to
+ `\halign` `<declaration>`.
+ The result is stored into \`\_tabdata` tokens list.
+ For example, the
+ following result is generated when `<declaration>=|cr||cl|`.
+ \begtt
+ tabdata: \_vrule\_the\_tabiteml\_hfil#\_unsskip\_hfil\_the\_tabitemr\_tabstrutA
+ &\_the\_tabiteml\_hfil#\_unsskip\_the\_tabitemr
+ \_vrule\_kern\_vvkern\_vrule\_tabstrutA
+ &\_the\_tabiteml\_hfil#\_unsskip\_hfil\_the\_tabitemr\_tabstrutA
+ &\_the\_tabiteml#\_unsskip\_hfil\_the\_tabitemr\_vrule\_tabstrutA
+ ddlinedata: &\_dditem &\_dditem\_vvitem &\_dditem &\_dditem
+ \endtt
+ The second result in the \`\_ddlinedata` macro is a teplate of one row of the table
+ used by \^`\crli` macro.
+ \_cod -----------------------------
+
+\_def\_scantabdata#1{\_let\_next=\_scantabdata
+ \_ifx\_relax#1\_let\_next=\_relax
+ \_else\_ifx|#1\_addtabvrule
+ \_else\_ifx(#1\_def\_next{\_scantabdataE}%
+ \_else\_isinlist{123456789}#1\_iftrue \_def\_next{\_scantabdataC#1}%
+ \_else \_ea\_ifx\_csname _tabdeclare#1\_endcsname \_relax
+ \_ea\_ifx\_csname _paramtabdeclare#1\_endcsname \_relax
+ \_opwarning{tab-declarator "#1" unknown, ignored}%
+ \_else
+ \_def\_next{\_ea\_scantabdataB\_csname _paramtabdeclare#1\_endcsname}\_fi
+ \_else \_def\_next{\_ea\_scantabdataA\_csname _tabdeclare#1\_endcsname}%
+ \_fi\_fi\_fi\_fi\_fi \_next
+}
+\_def\_scantabdataA#1{\_addtabitem \_ea\_addtabdata\_ea{#1\_tabstrutA}\_scantabdata}
+\_def\_scantabdataB#1#2{\_addtabitem\_ea\_addtabdata\_ea{#1{#2}\_tabstrutA}\_scantabdata}
+\_def\_scantabdataC {\_def\_tmpb{}\_afterassignment\_scantabdataD \_tmpnum=}
+\_def\_scantabdataD#1{\_loop \_ifnum\_tmpnum>0 \_advance\_tmpnum by-1 \_addto\_tmpb{#1}\_repeat
+ \_ea\_scantabdata\_tmpb}
+\_def\_scantabdataE#1){\_addtabdata{#1}\_scantabdata}
+
+\_def\_addtabitem{\_ifnum\_colnum>0 \_addtabdata{&}\_addto\_ddlinedata{&\_dditem}\_fi
+ \_advance\_colnum by1 \_let\_tmpa=\_relax}
+\_def\_addtabdata#1{\_tabdata\_ea{\_the\_tabdata#1}}
+\_def\_addtabvrule{%
+ \_ifx\_tmpa\_vrule \_addtabdata{\_kern\_vvkern}%
+ \_ifnum\_colnum=0 \_addto\_vvleft{\_vvitem}\_else\_addto\_ddlinedata{\_vvitem}\_fi
+ \_else \_ifnum\_colnum=0 \_addto\_vvleft{\_vvitemA}\_else\_addto\_ddlinedata{\_vvitemA}\_fi\_fi
+ \_let\_tmpa=\_vrule \_addtabdata{\_vrule}%
+}
+\_def\_tabstrutA{\_copy\_tstrutbox}
+\_def\_vvleft{}
+\_def\_ddlinedata{}
+
+ \_doc -----------------------------
+ The default \"declaration letters" `c`, `l`, `r` and `p` are declared.
+ by `\def\_tabdeclare<letter>{...}` for a non-parametric
+ letter and by `\def\_paramtabdeclare<letter>{...}` for a letter with a parameter.
+ The double hash `##` must be in the definition, it is replaced by a real table item data.
+ All items are put in group because of `\aftergroup` can be used (from
+ `\localcolors` for example).
+ You can declare more such \"declaration letters" if you want.
+ \_cod -----------------------------
+
+\_def\_tabdeclarec{{\_the\_tabiteml\_hfil##\_unsskip\_hfil\_the\_tabitemr}}
+\_def\_tabdeclarel{{\_the\_tabiteml\_relax##\_unsskip\_hfil\_the\_tabitemr}}
+\_def\_tabdeclarer{{\_the\_tabiteml\_hfil##\_unsskip\_the\_tabitemr}}
+\_def\_paramtabdeclarep#1{{\_the\_tabiteml
+ \_vtop{\_hsize=#1\_relax \_baselineskip=\_normalbaselineskip
+ \_lineskiplimit=0pt \_noindent##\_unsskip\_lower\_dp\_tstrutbox\_hbox{}}\_the\_tabitemr}}
+
+ \_doc -----------------------------
+ User puts optional spaces around the table item typically, i.\,e.\ he/she writes
+ `& text &` instead `&text&`. The left space is ignored by internal \TeX/ algorithm but
+ the right space must be removed by macros. This is a reason why we reccomend to
+ use \`\_unsskip` after each `##` in your definition of \"declaration letters".
+ This macro isn't only the primitive `\unskip` because we allow usage of plain \TeX/
+ `\hideskip` macro: `&\hideskip text\hideskip&`.
+ \_cod -----------------------------
+
+\_def\_unsskip{\_ifdim\_lastskip>0pt \_unskip\_fi}
+
+ \_doc -----------------------------
+ The family of `\_cr*` macros
+ \`\crl`, \`\crll`, \`\crli`, \`\crlli`, \`\crlp` and
+ \`\tskip` `<dimen>` is implemented here.
+ The \`\_zerotabrule` is used in order to suppress the negative `\lineskip`
+ declared by \^`\tablinespace`.
+ \_cod -----------------------------
+
+\_def\_crl{\_crcr\_noalign{\_hrule}}
+\_def\_crll{\_crcr\_noalign{\_hrule\_kern\_hhkern\_hrule}}
+\_def\_zerotabrule {\_noalign{\_hrule height0pt width0pt depth0pt}}
+
+\_def\_crli{\_crcr \_zerotabrule \_omit
+ \_gdef\_dditem{\_omit\_tablinefil}\_gdef\_vvitem{\_kern\_vvkern\_vrule}\_gdef\_vvitemA{\_vrule}%
+ \_vvleft\_tablinefil\_ddlinedata\_crcr \_zerotabrule}
+\_def\_crlli{\_crli\_noalign{\_kern\_hhkern}\_crli}
+\_def\_tablinefil{\_leaders\_hrule\_hfil}
+
+\_def\_crlp#1{\_crcr \_zerotabrule \_noalign{\_kern-\_drulewidth}%
+ \_omit \_xdef\_crlplist{#1}\_xdef\_crlplist{,\_expandafter}\_expandafter\_crlpA\_crlplist,\_end,%
+ \_global\_tmpnum=0 \_gdef\_dditem{\_omit\_crlpD}%
+ \_gdef\_vvitem{\_kern\_vvkern\_kern\_drulewidth}\_gdef\_vvitemA{\_kern\_drulewidth}%
+ \_vvleft\_crlpD\_ddlinedata \_global\_tmpnum=0 \_crcr \_zerotabrule}
+\_def\_crlpA#1,{\_ifx\_end#1\_else \_crlpB#1-\_end,\_expandafter\_crlpA\_fi}
+\_def\_crlpB#1#2-#3,{\_ifx\_end#3\_xdef\_crlplist{\_crlplist#1#2,}\_else\_crlpC#1#2-#3,\_fi}
+\_def\_crlpC#1-#2-#3,{\_tmpnum=#1\_relax
+ \_loop \_xdef\_crlplist{\_crlplist\_the\_tmpnum,}\_ifnum\_tmpnum<#2\_advance\_tmpnum by1 \_repeat}
+\_def\_crlpD{\_global\_advance\_tmpnum by1
+ \_edef\_tmpa{\_noexpand\_isinlist\_noexpand\_crlplist{,\_the\_tmpnum,}}%
+ \_tmpa\_iftrue \_kern-\_drulewidth \_tablinefil \_kern-\_drulewidth\_else\_hfil \_fi}
+
+\_def\_tskip{\_afterassignment\_tskipA \_tmpdim}
+\_def\_tskipA{\_gdef\_dditem{}\_gdef\_vvitem{}\_gdef\_vvitemA{}\_gdef\_tabstrutA{}%
+ \_vbox to\_tmpdim{}\_ddlinedata \_crcr
+ \_zerotabrule \_noalign{\_gdef\_tabstrutA{\_copy\_tstrutbox}}}
+
+\_public \crl \crll \crli \crlli \crlp \tskip ;
+
+ \_doc -----------------------------
+ The \`\mspan``[<declaration>]{<text>}` macro generates similar `\omit\span\omit\span`
+ sequence as plain \TeX/ macro `\multispan`. Moreover, it uses \^`\_scantabdata` to
+ convert `<declaration>` from `\table` syntax to `\halign` syntax.
+ \_cod -----------------------------
+
+\_def\_mspan{\_omit \_tabdata={\_tabstrutA}\_let\_tmpa=\_relax \_afterassignment\_mspanA \_mscount=}
+\_def\_mspanA[#1]#2{\_loop \_ifnum\_mscount>1 \_cs{_span}\_omit \_advance\_mscount-1 \_repeat
+ \_colnum=0 \_def\_tmpa{}\_tabdata={}\_scantabdata#1\_relax
+ \_setbox0=\_vbox{\_halign\_expandafter{\_the\_tabdata\_cr#2\_cr}\_global\_setbox8=\_lastbox}%
+ \_setbox0=\_hbox{\_unhbox8 \_unskip \_global\_setbox8=\_lastbox}%
+ \_unhbox8 \_ignorespaces}
+\_public \mspan ;
+
+ \_doc -----------------------------
+ The parameters of primitive `\vrule` and `\hrule` keeps the rule \"last wins".
+ If we re-define `\hrule` to `\_orihrule height1pt` then each usage
+ of redefined `\hrule` uses `1pt` height if this parameter isn't
+ overwriten by another following `height` parameter. This principle is used for
+ settings another default rule thickness than 0.4\,pt by the macro
+ \`\rulewidth`.
+ \_cod -----------------------------
+
+\_newdimen\_drulewidth \_drulewidth=0.4pt
+\_let\_orihrule=\_hrule \_let\_orivrule=\_vrule
+\_def\_rulewidth{\_afterassignment\_rulewidthA \_drulewidth}
+\_def\_rulewidthA{\_edef\_hrule{\_orihrule height\_drulewidth}%
+ \_edef\_vrule{\_orivrule width\_drulewidth}%
+ \_let\_rulewidth=\_drulewidth
+ \_public \vrule \hrule \rulewidth;}
+\_public \rulewidth ;
+
+ \_doc -----------------------------
+ The \`\frame``{<text>}` uses \"\code{\\vbox} in \code{\\vtop}" trick in order to keep the
+ baseline of the internal text at the same level as outer baseline.
+ User can write `\frame{abcxyz}` in normal paragraph line, for example
+ and gets the expected result: \frame{abcxyz}.
+ The internal margins are set by `\vvkern` and `\hhkern` parameters.
+ \_cod -----------------------------
+
+\_long\_def\_frame#1{%
+ \_hbox{\_vrule\_vtop{\_vbox{\_hrule\_kern\_vvkern
+ \_hbox{\_kern\_hhkern\_relax#1\_kern\_hhkern}%
+ }\_kern\_vvkern\_hrule}\_vrule}}
+\_public \frame ;
+
+\_endcode % -------------------------------------
+
+2020-04-10 second group for items in order to \localcolors