diff options
Diffstat (limited to 'macros/luatex/optex/table.opm')
-rw-r--r-- | macros/luatex/optex/table.opm | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/macros/luatex/optex/table.opm b/macros/luatex/optex/table.opm new file mode 100644 index 0000000000..3596275e48 --- /dev/null +++ b/macros/luatex/optex/table.opm @@ -0,0 +1,201 @@ +%% This is part of OpTeX project, see http://petr.olsak.net/optex + +\_codedecl \table {Basic macros for OpTeX <2020-03-12>} + + \_doc ----------------------------- + The result of `\table` is inserted into `\_tablebox`. You can change + default value if you want `\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 `\_tablinspace` is implemented by enlarging given `\tabstrut` + by desired dimension (height and depth too) and by setting + `\_lineskip=-2\_tablinspace`. So, 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` <declaration> to `\halign` <declaration>. + The result is stored into `\_tbdata` tokens list. For example, the `\_scandata` creates + following result 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 `\_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{\_toksapp\_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 defined here. + You can define more such leeters 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. + \_cod ----------------------------- + +\_def\_tabdeclarec{\_the\_tabiteml\_hfil##\_unsskip\_hfil\_the\_tabitemr} +\_def\_tabdeclarel{\_the\_tabiteml##\_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 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\_crcr}\_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.4pt. + \_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` uses \"`\vbox` in `\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 % ------------------------------------- + + |