diff options
Diffstat (limited to 'macros/optex/base')
39 files changed, 910 insertions, 382 deletions
diff --git a/macros/optex/base/alloc.opm b/macros/optex/base/alloc.opm index ae77d3074e..d4f823fec4 100644 --- a/macros/optex/base/alloc.opm +++ b/macros/optex/base/alloc.opm @@ -121,10 +121,9 @@ \_doc ----------------------------- A few registers are initialized like in plain\TeX/. We absolutely don't support the `@`category dance, so `\z@skip` - `\z@`, `\p@` etc. are not defined in \OpTeX/. If you need such - control sequences then you can initialize them by `\load[plain-at]`. + `\z@`, `\p@` etc. are defined but not recommended in \OpTeX/. - Only the \`\_zo` and \`\_zoskip` (equivalents to `\z@` and `\z@skip`) + The \`\_zo` and \`\_zoskip` (equivalents to `\z@` and `\z@skip`) are declared here and used in some internal macros of \OpTeX/ for improving speed. \_cod ----------------------------- diff --git a/macros/optex/base/basic-macros.opm b/macros/optex/base/basic-macros.opm index 2e8c98d6e3..ae5c833140 100644 --- a/macros/optex/base/basic-macros.opm +++ b/macros/optex/base/basic-macros.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \sdef {Basic macros for OpTeX <2021-07-20>} % preloaded in format +\_codedecl \sdef {Basic macros for OpTeX <2022-11-22>} % preloaded in format \_doc ------------------------------ \`\bgroup`, \`\egroup`, \`\empty`, \`\space`, and \`\null` @@ -77,11 +77,15 @@ \_public \cs \trycs ; \_doc ------------------------------ - \`\addto` `\macro{<text>}` adds `<text>` to your `\macro`, which must be defined. + \`\addto` `\macro{<text>}` adds `<text>` to your `\macro`, which must be defined.\nl + \`\aheadto` `\macro{<text>}` defines `\macro` as `<text>` followed by the + original `\macro` body. \_cod ------------------------------ \_long\_def \_addto #1#2{\_ea\_def\_ea#1\_ea{#1#2}} -\_public \addto ; +\_long\_def \_aheadto #1#2{\_edef#1{\_unexpanded{#2}\_unexpanded\_ea{#1}}} + +\_public \addto \aheadto ; \_doc ----------------------------- \`\incr``<counter>` increases `<counter>` by one globally. @@ -112,6 +116,15 @@ \_def\_tracingall{\_tracingonline=1 \_loggingall} \_public \loggingall \tracingall ; + \_doc ------------------------ + The `\optexversion` and `\fmtname` are defined in the `optex.ini` file. + Maybe, somebody will need a private version of these macros. + We add \`\_banner` used in `\everyjob` and in \~`\docgen` + \_cod ------------------------ + +\_def\_banner {This is OpTeX (Olsak's Plain TeX), version <\_optexversion>}% +\_private \optexversion \fmtname ; + \_doc ------------------------------ \`\_byehook` is used in the \^`\bye` macro. Write a warning if the user did not load a Unicode Font. @@ -129,6 +142,9 @@ \_endcode % ------------------------------------- +2022-11-22: \_banner definition moved here +2022-11-18: \ahead introduced +2022-10-29: \_fin introduced 2021-07-20: \_unresovedrefs removed from \_byehook 2021-07-18: \_byehook: checking `ref` file consistency added. 2021-05-16: \slet reimplemented (to allow \slet{foo}{undefined}). diff --git a/macros/optex/base/bib-simple.opm b/macros/optex/base/bib-simple.opm index fe1730ba67..3af9a1b927 100644 --- a/macros/optex/base/bib-simple.opm +++ b/macros/optex/base/bib-simple.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \_undefined {BIB style (simple) <2022-05-10>} % loaded on demand by \usebib +\_codedecl \_undefined {BIB style (simple) <2022-10-10>} % loaded on demand by \usebib \_ifx\_optexbibstyle\_undefined \_errmessage {This file can be read by: \_string\usebib/? (simple) bibfiles command only} @@ -36,6 +36,7 @@ } \_def\_preurl{\_hfil\_break} +\_def\_Inclause{In:~} % Non-standard fieldnames: @@ -56,9 +57,9 @@ \_setbibmark } \_sdef{_print:book}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% - \_bprintb [title] {{\_em##1}.\ }{\_bibwarning}% - \_bprinta [edition] {*~\_mtext{bib.edition}.\ }{}% + \_bprinta [!author] {*.\ }{\_bibwarning}% + \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% + \_bprinta [edition] {*\_mtext{bib.edition}\ }{}% \_bprinta [address] {*: }{\_bibwarning}% \_bprinta [publisher] {*, }{\_bibwarning}% \_bprinta [year] {*.\ }{\_bibwarning}% @@ -66,21 +67,21 @@ \_bprintb [url] {\_preurl\_url{##1}. }{}% } \_sdef{_print:article}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% - \_bprinta [title] {*.\ }{\_bibwarning}% - \_bprintb [journal] {{\_em##1}.\ }{\_bibwarning}% - \_bprinta [year] {*, }{}% + \_bprinta [!author] {*.\ }{\_bibwarning}% + \_bprinta [title] {*\:\ }{\_bibwarning}% + \_bprintb [journal] {{\_em##1}\:\ }{\_bibwarning}% + \_bprinta [year] {*\_bprintv[volume,number,pages]{,}{.} }{}% \_bprinta [volume] {* }{}% - \_bprinta [number] {(*), }{}% + \_bprinta [number] {(*)\_bprintv[pages]{,}{.} }{}% \_bprinta [pages] {*.\ }{}% \_bprintb [doi] {DOI~\_ulink[http://dx.doi.org/##1]{##1}.\ }{}% } \_sdef{_print:inbook}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% - \_bprintb [title] {{\_em##1.}\ }{\_bibwarning}% - In:~% + \_bprinta [!author] {*.\ }{\_bibwarning}% + \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% + \_Inclause \_bprinta [!editor] {*,~eds.\ }{}% - \_bprintb [booktitle] {{\_em##1}.\ }{\_bibwarning}% + \_bprintb [booktitle] {{\_em##1}\:\ }{\_bibwarning}% \_bprinta [address] {*: }{\_bibwarning}% \_bprinta [publisher] {*, }{\_bibwarning}% \_bprinta [year] {*.\ }{\_bibwarning}% @@ -92,12 +93,12 @@ \_slet{_print:inproceedings}{_print:inbook} \_sdef{_print:incolection}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% - \_bprintb [title] {{\_em##1}.\ }{\_bibwarning}% + \_bprinta [!author] {*.\ }{\_bibwarning}% + \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% \_bprinta [crossreff] {In~\_cite[*]. }{% \_bprinta [booktitle] {*. }{\_bibwarning}% \_bprinta [!editor] {*,~eds.\ }{\_bibwarning}% - \_bprinta [edition] {*~\_mtext{bib.edition}.\ }{\_bibwarning}% + \_bprinta [edition] {*\_mtext{bib.edition}\ }{\_bibwarning}% \_bprinta [address] {*: }{\_bibwarning}% \_bprinta [publisher] {*, }{\_bibwarning}% \_bprinta [year] {*.\ }{\_bibwarning}% @@ -105,9 +106,9 @@ \_bprintb [url] {\_preurl\_url{####1}. }{}}% } \_sdef{_print:conference}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% + \_bprinta [!author] {*.\ }{\_bibwarning}% \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% - \_bprinta [edition] {*~\_mtext{bib.edition}.\ }{}% + \_bprinta [edition] {*\_mtext{bib.edition}\ }{}% \_bprinta [address] {*: }{\_bibwarning}% \_bprinta [publisher] {*, }{\_bibwarning}% \_bprinta [year] {*.\ }{\_bibwarning}% @@ -115,7 +116,7 @@ \_bprintb [url] {\_preurl\_url{##1}. }{}% } \_sdef{_print:thesis}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% + \_bprinta [!author] {*.\ }{\_bibwarning}% \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% \_bprinta [type] {*,\ }{\_bibwarning}% \_bprinta [school] {*.\ }{}% @@ -124,31 +125,31 @@ \_bprintb [url] {\_preurl\_url{##1}. }{}% } \_sdef{_print:proceedings}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% + \_bprinta [!author] {*.\ }{\_bibwarning}% \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% \_bprinta [publisher] {*.\ }{% \_bprinta [organization] {*.\ }{\_bibwarning}}% } \_sdef{_print:techreport}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% + \_bprinta [!author] {*.\ }{\_bibwarning}% \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% \_mtext{bib.techreport}. \_bprinta [institution] {*.\ }{}% } \_sdef{_print:booklet}{% - \_bprinta [!author] {*\:\ }{\_bibwarning}% + \_bprinta [!author] {*.\ }{\_bibwarning}% \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% \_bprinta [howpublished] {*.\ }{\_bibwarning}% } \_sdef{_print:manual}{% - \_bprinta [!author] {*\:\ }{}% + \_bprinta [!author] {*.\ }{}% \_bprintb [title] {{\_em##1}\:\ }{\_bibwarning}% \_bprinta [year] {*.\ }{}% \_bprinta [institution] {*.\ }{}% \_bprintb [url] {\_preurl\_url{##1}. }{}% } \_sdef{_print:misc}{% - \_bprinta [!author] {*\:\ }{}% + \_bprinta [!author] {*.\ }{}% \_bprintb [title] {{\_em##1}\:\ }{}% \_bprinta [howpublished] {*.\ }{}% \_bprinta [institution] {*.\ }{}% diff --git a/macros/optex/base/cite-bib.opm b/macros/optex/base/cite-bib.opm index adef0eaef8..9dc32a2632 100644 --- a/macros/optex/base/cite-bib.opm +++ b/macros/optex/base/cite-bib.opm @@ -232,7 +232,7 @@ \_cod ----------------------------- \_def\_bib[#1]{\_def\_tmp{\_isnextchar={\_bibA[#1]}{\_bibmark={}\_bibB[#1]}}% - \_ea\_tmp\_romannumeral-`\.} % ignore optional space + \_nospaceafter\_tmp} % ignore optional space \_def\_bibA[#1]=#2{\_bibmark={#2}\_bibB[#1]} \_def\_bibB[#1]{\_par \_bibskip \_bibgl\_advance\_bibnum by1 diff --git a/macros/optex/base/doc.opm b/macros/optex/base/doc.opm index bde1dcc848..dc5d037e72 100644 --- a/macros/optex/base/doc.opm +++ b/macros/optex/base/doc.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \printdoc {Macros for documentation printing <2022-07-01>} % loaded on demand by \load[doc] +\_codedecl \printdoc {Macros for documentation printing <2022-11-21>} % loaded on demand by \load[doc] \_doc ----------------------------- General decalarations. @@ -11,8 +11,10 @@ \_let \mlinkcolor=\Red % main doc. points \_let \ulinkcolor=\Blue % user doc. points \_let \fnamecolor=\Brown % file names in listing headers -\_def \bgverbcolor {\_setcmykcolor{0 0 .3 .03}} % background for listings -\_hyperlinks \Green \Green +\_def \bgverbcolor {\_setcmykcolor{0 0 .3 .03}} % background for listings +\_def \outlinkcolor {\_setcmykcolor{1 0 1 .2}} % green for outerlinks +\_def \inlinkcolor {\_setcmykcolor{0 1 0 .1}} % magenta for internal links +\_hyperlinks \inlinkcolor \outlinkcolor \_enlang \_enquotes @@ -39,7 +41,7 @@ \_doc ----------------------------- The listing mode is implemented here. The \`\maxlines` is maximal lines of code printed in the listing mode. - The \`\_catcodedot` sets dot as letter in listngs (for package + The \code{\\catcode`\\.=11} sets dot as letter in listngs (for package documentation where `\.foo` sequeces exist). \_cod ----------------------------- @@ -52,7 +54,7 @@ \_typosize[8/10] \_let\_printverbline=\_printcodeline \_ttline=\_inputlineno - \_setverb \_catcodedot + \_setverb \_catcode`\.=11 \_ifnum\_ttline<0 \_let\_printverblinenum=\_relax \_else \_initverblinenum \_fi \_adef{ }{\ }\_adef\^^I{\t}\_parindent=\_ttindent \_parskip=0pt \_def\t{\_hskip \_dimexpr\_tabspaces em/2\_relax}% @@ -74,7 +76,6 @@ \_edef\_Doc{\_asp\_asp\_bslash _doc} \_bgroup \_lccode`~=`\^^I \_lowercase{\_egroup\_edef\_Doctab{\_noexpand~\_bslash _doc}} \_edef\_Endcode{\_noexpand\_empty\_bslash _endcode} -\_def\_catcodedot{\_catcode`\.=11 } \_doc ----------------------------- The scanner of the control sequences in the listing mode replaces all @@ -101,16 +102,16 @@ \_def\_processinput{% \_let\_start=\_relax \_ea\_replstring\_ea\_tmpb\_ea{\_aspace^^J}{^^J} - \_addto\_tmpb{\_end}% + \_addto\_tmpb{\_fin}% \_isinlist\_tmpb{\_start^^J}\_iftrue \_advance\_ttline by1\_fi \_replstring\_tmpb{\_start^^J}{\_start}% \_replstring\_tmpb{\_start}{}% - \_replstring\_tmpb{^^J\_end}{\_end}% - \_replstring\_tmpb{^^J\_end}{}% - \_replstring\_tmpb{\_end}{}% + \_replstring\_tmpb{^^J\_fin}{\_fin}% + \_replstring\_tmpb{^^J\_fin}{}% + \_replstring\_tmpb{\_fin}{}% \_ea\_prepareverbdata\_ea\_tmpb\_ea{\_tmpb^^J}% \_replthis{\_csstring\\}{\_noexpand\_makecs}% - \_ea\_printverb \_tmpb\_end + \_ea\_printverb \_tmpb\_fin \_par \_endgroup \_ttskip \_isnextchar\_par{}{\_noindent}% @@ -145,7 +146,7 @@ } \_everytt={\_let\_printverblinenum=\_relax} -\_long\_def\_endverbprinting#1\_end#2\_end{\_fi\_fi \_global\_maxlines=100000 +\_long\_def\_endverbprinting#1\_fin#2\_fin{\_fi\_fi \_global\_maxlines=100000 \_noindent\_typosize[8/]\_dots etc. (see {\_tt\fnamecolor\docfile})} \_doc ----------------------------- @@ -206,10 +207,9 @@ catcodes using the `\_afteroad` macro. \_cod ----------------------------- -\_def\_afterload{\_catcode`\<=13 \_catcode`\`=13 \_catcode`\.=11 - \_wlog {doc.opm: catcodes of < and ` activated, catcode of . is letter.}% +\_def\_afterload{\_catcode`\<=13 \_catcode`\`=13 + \_wlog {doc.opm: catcodes of < and ` activated.}% } -\_catcode`.=11 \_doc ----------------------------- The \code{<something>} will be print as <something>. @@ -219,7 +219,7 @@ \_catcode`\<=13 \_def<#1>{$\langle\hbox{\it#1\/}\rangle$} -\_everyintt{\_catcode`\<=13 } +\_everyintt{\_catcode`\<=13 \_catcode`\.=11 } \_doc ----------------------------- Main documentation points and hyperlinks to/from it. @@ -357,6 +357,8 @@ have the same meaning: `\optexdoclink` in this example. And \endinput +2022-11-21 magenta color for internal links instead green. +2022-11-13 \catcode`.=11: only local settings 2022-07-01 \_printii improved, colors declaration part added. 2021-05-15 \_endinput shifted after \_processinput when \_endcode is scanned. 2021-05-14 \_catcodedot, \_Doctab introduced. diff --git a/macros/optex/base/f-heros.opm b/macros/optex/base/f-heros.opm index 7848b7f9d2..2531573ca4 100644 --- a/macros/optex/base/f-heros.opm +++ b/macros/optex/base/f-heros.opm @@ -21,11 +21,8 @@ Modifiers:^^J \_ifmathloading \_loadmath {[FiraMath-Regular]} - \_addto\_normalmath{\_loadumathfamily 5 {xitsmath-regular}{} } - \_addto\_boldmath {\_loadumathfamily 5 {xitsmath-bold}{} } - \_addto\_frak{\_fam5 }\_addto\_cal{\_fam5 } \_public \frak \cal ; - \_normalmath - \_wterm{MATH-FONT(5): "[XITSMath-Regular/Bold]" -- used for \_string\cal, \_string\frak} + \_addUmathfont \_xits {[XITSMath-Regular]}{} {[XITSMath-Bold]}{} {} + \_addto\_frak{\_fam\_xits}\_addto\_cal{\_fam\_xits} \_public \frak \cal ; % \bf, \bi from FiraMath: \_let\_bsansvariables=\_bfvariables \_let\_bsansGreek=\_bfGreek @@ -34,14 +31,8 @@ Modifiers:^^J \_let\_bisansvariables=\_bivariables \_let\_bisansgreek=\_bigreek % \_resetmathchars <fam-number> <list of \Umathchardef csnames> ; - \_def\_resetmathchars #1{\_chardef\_mafam=#1\_relax \_xargs \_resetmathcharX} - \_def\_resetmathcharX#1{\_ea\_resetmathcharY - \_directlua{tex.print(string.format("\_pcent08X", \_the#1))}#1} - \_def\_resetmathcharY#1#2#3#4#5#6#7#8#9{% - \_Umathchardef #9\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8 - \_Umathcode "#4#5#6#7#8=\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8 } - \_resetmathchars 5 \bigtriangleup \bigblacktriangleup \blacktriangle - \vartriangle \smallblacktriangleright ; % ... etc. you can add more + \_mathchars \_xits {\bigtriangleup \bigblacktriangleup \blacktriangle + \vartriangle \smallblacktriangleright} % ... etc. you can add more \_fi \_endcode diff --git a/macros/optex/base/f-iwona.opm b/macros/optex/base/f-iwona.opm new file mode 100644 index 0000000000..702ac6a06a --- /dev/null +++ b/macros/optex/base/f-iwona.opm @@ -0,0 +1,26 @@ +%% This is part of the OpTeX project, see http://petr.olsak.net/optex + +\_famdecl [Iwona] \Iwona {Sans serif typeface derived from Kurier} + {\caps \cond \light \medium \bolder} {\rm \bf \it \bi} {} + {[Iwona-Regular]} + {\_def\_fontnamegen{[Iwona\_condV\_weightV-\_currV]:\_capsV\_fontfeatures}} + +\_wlog{\_detokenize{% +Modifiers:^^J + \caps ...... caps & small caps^^J + \cond ...... condensed variants^^J + \light ..... light (only \rm \it)^^J + \medium .... medium (only \rm \it)^^J + \bolder .... heavy (only \rm \it) +}} + +\_moddef \resetmod {\_fsetV caps={},cond={},weight={} \_fvars Regular Bold Italic BoldItalic } +\_moddef \caps {\_fsetV caps=+smcp;\_ffonum; } +\_moddef \nocaps {\_fsetV caps={} } +\_moddef \cond {\_fsetV cond=Cond } +\_moddef \light {\_fsetV weight=Light \_fvars Regular . Italic . } +\_moddef \medium {\_fsetV weight=Medium \_fvars Regular . Italic . } +\_moddef \bolder {\_fsetV weight=Heavy \_fvars Regular . Italic . } +\_moddef \nocond {\_fsetV cond={} } + +\_initfontfamily % new font family must be initialized diff --git a/macros/optex/base/f-kurier.opm b/macros/optex/base/f-kurier.opm new file mode 100644 index 0000000000..ca1a6e381e --- /dev/null +++ b/macros/optex/base/f-kurier.opm @@ -0,0 +1,26 @@ +%% This is part of the OpTeX project, see http://petr.olsak.net/optex + +\_famdecl [Kurier] \Kurier {Two element sans serif typeface} + {\caps \cond \light \medium \bolder} {\rm \bf \it \bi} {} + {[Kurier-Regular]} + {\_def\_fontnamegen{[Kurier\_condV\_weightV-\_currV]:\_capsV\_fontfeatures}} + +\_wlog{\_detokenize{% +Modifiers:^^J + \caps ...... caps & small caps^^J + \cond ...... condensed variants^^J + \light ..... light (only \rm \it)^^J + \medium .... medium (only \rm \it)^^J + \bolder .... heavy (only \rm \it) +}} + +\_moddef \resetmod {\_fsetV caps={},cond={},weight={} \_fvars Regular Bold Italic BoldItalic } +\_moddef \caps {\_fsetV caps=+smcp;\_ffonum; } +\_moddef \nocaps {\_fsetV caps={} } +\_moddef \cond {\_fsetV cond=Cond } +\_moddef \light {\_fsetV weight=Light \_fvars Regular . Italic . } +\_moddef \medium {\_fsetV weight=Medium \_fvars Regular . Italic . } +\_moddef \bolder {\_fsetV weight=Heavy \_fvars Regular . Italic . } +\_moddef \nocond {\_fsetV cond={} } + +\_initfontfamily % new font family must be initialized diff --git a/macros/optex/base/f-lato.opm b/macros/optex/base/f-lato.opm new file mode 100644 index 0000000000..bedb33a8a2 --- /dev/null +++ b/macros/optex/base/f-lato.opm @@ -0,0 +1,34 @@ +%% This is part of the OpTeX project, see http://petr.olsak.net/optex + +\_famdecl [Lato] \Lato {Geometric grotesk, many weights} + {\hair \thin \light \normal \book \bolder} {} {} + {[Lato-Regular]} + {\_def\_fontnamegen {[Lato-\_currV]:\_capsV\_fontfeatures}} + +\_wlog{\_detokenize{% +Modifier: \caps .... Old digits only (caps not provided)^^J% +Modifiers (face weight):^^J + \hair ...... \rm, \it = Hair, \bf, \bi = Normal^^J + \thin ...... \rm, \it = Thin, \bf, \bi = Medium^^J + \light ..... \rm, \it = Light, \bf, \bi = Semibold^^J + \normal .... \rm, \it = Normal, \bf, \bi = Bold^^J + \book ...... \rm, \it = Medium, \bf, \bi = Heavy^^J + \bolder .... \rm, \it = Semibold, \bf, \bi = Black^^J% +}} + +\_moddef \resetmod {\_fsetV caps={} \_fvars Regular Bold Italic BoldItalic } +\_moddef \caps {\_fsetV caps=+smcp;\_ffonum; } +\_moddef \hair {\_fvars Hairline Regular HairlineItalic Italic } +\_moddef \thin {\_fvars Thin Medium ThinItalic MediumItalic } +\_moddef \light {\_fvars Light Semibold LightItalic SemiboldItalic } +\_moddef \normal {\_fvars Regular Bold Italic BoldItalic } +\_moddef \book {\_fvars Medium Heavy MediumItalic HeavyItalic } +\_moddef \bolder {\_fvars Semibold Black SemiboldItalic BlackItalic } + +\_moddef \caps {\_fsetV caps=+smcp;\_ffonum; } +\_moddef \nocaps {\_fsetV caps={} } + +\_initfontfamily % new font family must be initialized + +\_endcode + diff --git a/macros/optex/base/fams-ini.opm b/macros/optex/base/fams-ini.opm index ad3ace24f3..505887f46e 100644 --- a/macros/optex/base/fams-ini.opm +++ b/macros/optex/base/fams-ini.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -% Version <2020-02-28>. Loaded in format and secondly on demand by \fontfam[catalog] +% Version <2022-10-18>. Loaded in format and secondly on demand by \fontfam[catalog] \_famtext {Special name for printing a catalog :} @@ -169,6 +169,23 @@ \caps, \caps\cond: {\rm\bf\it\bi} \caps\ttset: {\rm\bf} } +\_famfrom {Malgorzata Budyta, Janusz Marian Nowacki} +\_faminfo [Kurier] {Two element sans serif typeface} {f-kurier} + { -,\cond,\caps,\caps\cond: {\rm\it\bf\bi} + \light,\light\cond,\medium,\medium\cond,\bolder,\bolder\cond: {\rm\it} + } +\_faminfo [Iwona] {Sans serif typeface derived from Kurier} {f-iwona} + { -,\cond,\caps,\caps\cond: {\rm\it\bf\bi} + \light,\light\cond,\medium,\medium\cond,\bolder,\bolder\cond: {\rm\it} + } + +\_famfrom {tyPoland Lukasz Dziedzic} +\_faminfo [Lato] {Geometric grotesk, many weights} {f-lato} + { \hair: {\rm\it} \thin: {\rm\it} \light: {\rm\it} -: {\rm\it} + \book: {\rm\it} \bolder: {\rm\it} -: {\bf\bi} + \book: {\bf\bi} \bolder: {\bf\bi} + } + \_famfrom {Julieta Ulanovsky, http://www.zkysky.com.ar} \_faminfo [Montserrat] {Inspired from old posters in Montserat in Buenos Aires} {f-montserrat} { -,\caps,\alter: {\rm\bf\it\bi} \xlight,\elight,\light,-,\medium,\semibold: {\rm\it} diff --git a/macros/optex/base/fnotes.opm b/macros/optex/base/fnotes.opm index 661d54c33f..8f56ba1aea 100644 --- a/macros/optex/base/fnotes.opm +++ b/macros/optex/base/fnotes.opm @@ -132,8 +132,8 @@ as a box shifted down by `\parskip` and with `\vskip-\baselineskip` followed. \_cod ----------------------------- -\_def\_mnote #1#{\_ifx^#1^\_else \_mnoteC#1\_end \_fi \_mnoteD} -\_def\_mnoteC up#1\_end{\_mnoteskip=#1\_relax} % \mnote up<dimen> {<text>} syntax +\_def\_mnote #1#{\_ifx^#1^\_else \_mnoteC#1\_fin \_fi \_mnoteD} +\_def\_mnoteC up#1\_fin{\_mnoteskip=#1\_relax} % \mnote up<dimen> {<text>} syntax \_long\_def\_mnoteD#1{% \_ifvmode \_vskip\_parskip{\_mnoteA{#1}}\_nobreak\_vskip-\_baselineskip\_vskip-\_parskip \_else \_lower\_dp\_strutbox\_hbox{}\_vadjust{\_kern-\_dp\_strutbox \_mnoteA{#1}\_kern\_dp\_strutbox}% diff --git a/macros/optex/base/fonts-catalog.opm b/macros/optex/base/fonts-catalog.opm index cdd77359f1..347c94b145 100644 --- a/macros/optex/base/fonts-catalog.opm +++ b/macros/optex/base/fonts-catalog.opm @@ -47,7 +47,7 @@ } \_def\_dosamples #1:#2{\_ifx^#2^\_else \_def\_printvars{#2}% - \_ea\_dosamplesA\_romannumeral-`\.#1,,% + \_nospaceafter\_dosamplesA #1,,% \_ea\_dosamples\_fi } \_def\_dosamplesA#1,{% diff --git a/macros/optex/base/fonts-resize.opm b/macros/optex/base/fonts-resize.opm index e49303f377..34885d44bd 100644 --- a/macros/optex/base/fonts-resize.opm +++ b/macros/optex/base/fonts-resize.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \setfontsize {Font resizing macros <2022-02-22>} % preloaded in format +\_codedecl \setfontsize {Font resizing macros <2022-11-08>} % preloaded in format \_doc ----------------------------- \`\initunifonts` macro extends \LuaTeX's font capabilities, @@ -10,19 +10,22 @@ from \LaTeX's `luatexbase` namespace, we provide our own replacements. \^`\initunifonts` sets itself to relax because we don't want to do this work twice. + \`\ufont` is a shortcut of \^`\initunifonts`~`\font`. \_cod ----------------------------- -\_def\_initunifonts {% +\_protected\_def \_initunifonts {% \_directlua{% require('luaotfload-main') luaotfload.main() - optex_hook_into_luaotfload() + optex.hook_into_luaotfload() }% \_glet \_fmodtt=\_unifmodtt % use \_ttunifont for \tt \_glet \_initunifonts=\_relax % we need not to do this work twice \_glet \initunifonts=\_relax } -\_public \initunifonts ; +\_protected\_def \_ufont {\_initunifonts \_font} + +\_public \initunifonts \ufont ; \_doc ----------------------------- The \`\setfontsize` `{<size spec>}` saves the `<size spec>` to the \`\_sizespec` macro. @@ -74,7 +77,8 @@ Note, that the `\_xfontname` output is converted due to optical size data using `\_optfn`. \_cod ----------------------------- -\_def\_fontlet#1#2{\_ifx #2=\_ea\_fontlet \_ea#1\_else \_font #1{\_optfn{\_xfontname#2}}\_fi} +\_protected\_def \_fontlet #1#2{\_ifx #2=\_ea\_fontlet \_ea#1\_else + \_ea\_font \_ea#1\_expanded{{\_optfn{\_xfontname#2}}}\_fi} \_public \xfontname \fontlet ; \_doc ----------------------------- @@ -83,17 +87,21 @@ It changes the current font at the given <size spec>. \nl \`\resizethefont` is implemented by \^`\newcurrfontsize` using data from - the \^`\_sizespec` macro. + the \^`\_sizespec` macro.\nl + \`\sfont` has the same syntax like `\font` primitive, but declares a + macro which selects the font and sets its size properly dependent on the + current size. \_cod ----------------------------- -\_def \_newcurrfontsize #1{% \newcurrfontsize{at25pt} - \_ea\_def \_ea\_tmp \_ea{\_csname \_ea\_csstring \_the\_font \_endcsname}% - \_ea\_fontlet \_tmp \_font #1\_relax - \_ea\_fontloaded \_tmp - \_tmp +% \newcurrfontsize{at25pt} +\_def \_newcurrfontsize {\_ea\_newcurrfontsizeA \_csname \_ea\_csstring \_the\_font \_endcsname} +\_def \_newcurrfontsizeA #1#2{\_fontlet #1\_font #2\_relax \_fontloaded#1#1} +\_protected\_def \_resizethefont {\_newcurrfontsize\_sizespec} +\_protected\_def \_sfont #1{% + \_protected\_edef #1{\_csname _sfont:\_csstring#1\_endcsname \_resizethefont}% + \_initunifonts \_ea\_font \_csname _sfont:\_csstring#1\_endcsname } -\_protected\_def \_resizethefont{\_newcurrfontsize\_sizespec} -\_public \newcurrfontsize \resizethefont ; +\_public \newcurrfontsize \resizethefont \sfont ; \_doc ----------------------------- The \`\_regtfm` `<font id> <optical size data>` @@ -169,7 +177,8 @@ The <size spec> can be empty or `at<dimen>` or `scaled<scale factor>`. The \OpTeX/ starts with `\font` primitive which is able to read only `tfm` files. i.e.\ the `<font file name>.tfm` (and additional data for glyphs) must be correctly installed in your system. If you want to load -OpenType `otf` or `ttf` font files, use the declarator \^`\initunifonts`. +OpenType `otf` or `ttf` font files, use the declarator \^`\initunifonts` +before first `\font` primitive. This command adds additional features to the `\font` primitive which gives the extended syntax: \begtt \catcode`\<=13 @@ -193,8 +202,9 @@ The original syntax for `tfm` files is also available. Example: primitive from `luaotfload` package. More information is available in the `luaotfload-latex.pdf` file. -Note, that \^`\fontfam` does (among other things) \^`\initunifonts` -internally. You need not to specify it if \^`\fontfam` is used. +You can use \^`\ufont` macro which runs \^`\initunifonts` followed by `\font` +primitive. And \^`\fontfam` does (among other things) \^`\initunifonts` +too. You need not to specify \^`\initunifonts` if \^`\fontfam` or \^`\ufont` is used. It seems that you must decide about final size of the font before it is loaded by the `\font` primitive. It is not exactly true; \OpTeX/ offers @@ -245,8 +255,7 @@ The \^`\resizethefont` works with arbitrary current font, for example with the font loaded directly by `\font` primitive. For example: \begtt -\initunifonts -\font\tencrimson=[Crimson-Roman]:+onum % font Crimson-Regular at 10 pt is loaded +\ufont\tencrimson=[Crimson-Roman]:+onum % font Crimson-Regular at 10 pt is loaded \def\crimson{\tencrimson\resizethefont} % \crimson uses the font size on demand \crimson The 10 pt text is here. @@ -258,6 +267,26 @@ behaves like variant selector in the Font Selection System (section~\ref[fontsys It takes only information about size from the font context, but it is sufficient. You can use it in titles, footnotes, etc. The font size depending on surrounding size is automatically selected. +There is a shortcut \^`\sfont` with the same syntax like `\font` primitive, +it declares a macro which selects the font and does resizing depending on +the current size. So, the example above can be realized by +`\sfont\crimson=[Crimson-Roman]:+onum`. + +\secc The `\font`-like commands summary + +\begitems +* `\font` is \TeX/ primitive. When \OpTeX/ starts, then it accepts only + classical \TeX/ syntax and doesn't allow to load Unicode fonts. + Once \^`\initunifonts` (or \^`\fontfam`) is used, the `\font` primitive is + re-initialized: now it accepts extended syntax and it is able to load Unicode + OpenType fonts. +* \^`\ufont` is a shortcut of `\initunifonts \font`. I.e.\ it behaves like + `\font` and accepts extended syntax immediatelly. +* \^`\sfont` has syntax like extended `\font`. It declares a macro which + selects the given font and resizes it to the current size (given by + \^`\setfontsize`). In various part of document (text, footnotes, titles), the + size of this font is selected by the declared macro properly. +\enditems \secc[fontlet] The \code{\\fontlet} declarator @@ -288,13 +317,13 @@ able to choose right file if various optical sizes and corresponding file names are declared for the font by \^`\_regtfm` or \^`\_regoptsizes` command. The command \^`\setfontsize` sets the internal reuirements for optical size if the parameter is in the format `at<dimen>` or `mag<factor>`. -Then the command \^`\resizethefont` or variant selectors try to choose +Then the command \^`\resizethefont` or \^`\fontlet` or variant selectors try to choose the font suitable for the required optical size. For example \begtt \fontfam[lm] The text is printed in font [lmroman10-regular] at 10 pt. \setfontsize{at13pt}\rm - Now in the text is printed in [lmroman12-regular] at 13 pt. + Now, the text is printed in [lmroman12-regular] at 13 pt. \endtt See also section~\ref[optsizes]. @@ -322,6 +351,9 @@ Luaotfload documentation for more information. \_endinput +2022-11-08 \sfont introduced, \protected: \initunifont, \ufont, \fontlet +2022-11-07 \fontlet \a\a: bug fixed +2022-10-14 \ufont introduced 2022-02-22 Font Selection System reimplemented, \fontsel introduced 2021-05-02 better concept of doc, moving parts to fonts-select 2021-04-17 \_fontloaded, \_newfontloaded introduced diff --git a/macros/optex/base/fonts-select.opm b/macros/optex/base/fonts-select.opm index 33d331150b..7e00c9baea 100644 --- a/macros/optex/base/fonts-select.opm +++ b/macros/optex/base/fonts-select.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \fontfam {Fonts selection system <2022-02-22>} % preloaded in format +\_codedecl \fontfam {Fonts selection system <2022-12-01>} % preloaded in format \_doc ----------------------------- The main principle of the Font Selection System is: run one or more @@ -161,7 +161,7 @@ runs <what> only if the `\_<key>V` is defined as `<value-a>` or `<value-b>` or ... or `<value-z>`. \nl - \`\_prepcommalist` `ab,{},cd,\_end,` expands to `ab,,cd,` (auxiliary macro + \`\_prepcommalist` `ab,{},cd,\_fin,` expands to `ab,,cd,` (auxiliary macro used in `\_onlyif`).\nl \`\_ffonum` is a shortcut for oldstyle digits font features used in font family files. You can do `\let\_ffonum=\ignoreit` if you don't want @@ -184,10 +184,10 @@ \_ifx,#1\_else\_sdef{_#1V}{#2}\_ea\_ea\_ea\_fsetVa\_fi\_fi } \_def \_onlyif #1=#2:#3{% - \_edef\_act{\_noexpand\_isinlist{,\_prepcommalist #2,\_end,}{,\_cs{_#1V},}}\_act + \_edef\_act{\_noexpand\_isinlist{,\_prepcommalist #2,\_fin,}{,\_cs{_#1V},}}\_act \_iftrue #3\_fi } -\_def\_prepcommalist#1,{\_ifx\_end#1\_empty\_else #1,\_ea\_prepcommalist\_fi} +\_def\_prepcommalist#1,{\_ifx\_fin#1\_empty\_else #1,\_ea\_prepcommalist\_fi} \_def\_ffonum {+onum;+pnum} \_doc ----------------------------- @@ -258,7 +258,7 @@ They have precedence when \^`\fontsel` constructs the <font switch> name. \_cod ----------------------------- -\_def\_fontdef #1#2{\_begingroup +\_protected\_def \_fontdef #1#2{\_begingroup \_edef\_xfamv{\_csstring#1}\_let\_ttfamv\_xfamv #2% \_ea\_endgroup\_ea \_let\_ea #1\_the\_font } @@ -278,7 +278,7 @@ the same meaning. \_cod ----------------------------- -\_def\_famvardef#1#2{% +\_protected\_def \_famvardef #1#2{% \_sdef{_f:\_currfamily:\_csstring#1}% {{\_edef\_xfamv{\_csstring#1}\_let\_ttfamv\_xfamv #2\_ea}\_the\_font \_def\_currvar{#1}}% \_protected\_edef\_tmpa {% @@ -307,7 +307,7 @@ terminal and to the log file. \_cod ----------------------------- -\_def\_fontfam[#1]{% +\_protected\_def \_fontfam [#1]{% \_lowercase{\_edef\_famname{\_ea\_removespaces #1 {} }}% \_isfile {f-\_famname.opm}\_iftrue \_opinput {f-\_famname.opm}% \_else @@ -349,8 +349,9 @@ \`\_famtext` does nothing or prints the text on the terminal. \nl \`\_faminfo` `[<Family Name>] {<comments>} {<file-name>} {<mod-plus-vars>}` - does\nl `\_def \_famf:<familyname> {<file-name>}` or prints information on - the terminal. + does\nl `\_def \_famf:<familyname> {<file-name>}` (only if <file-name> differs + from `f-<familyname>`) or prints information on the terminal. The + <mod-plus-vars> data are used when printing the font catalog. \nl \`\_famalias` `[<Family Alias>]` does `\def \_famf:<familyalias> {<file-name>}` where `<file-name>` is stored from the previous `\_faminfo` command. Or @@ -364,8 +365,8 @@ \_def\_famtext #1{} \_def\_faminfo [#1]#2#3#4{% \_lowercase{\_edef\_tmp{\_ea\_removespaces #1 {} }}% - \_sdef{_famf:\_tmp}{#3}% - \_def\_famfile{#3}% + \_edef\_tmpa{f-\_tmp}\_def\_famfile{#3}% + \_unless\_ifx\_tmpa\_famfile \_sdef{_famf:\_tmp}{#3}\_fi } \_def\_famalias [#1]{% \_lowercase{\_edef\_tmpa{\_ea\_removespaces #1 {} }}% @@ -898,6 +899,8 @@ with Unicode fonts loaded by \^`\fontfam`. \endinput +2022-12-01 \faminfo saves f-<filename> to the format only when needed +2022-11-08 \protected: \fontdef, \famvardef, \fontfam 2022-02-22 Font Selection System reimplemented, \fontsel introduced 2021-09-24 \_unichars used in \initunifonts 2021-07-16 \initunifonts: optex_hook_into_luaotfload added. diff --git a/macros/optex/base/graphics.opm b/macros/optex/base/graphics.opm index b54b52c926..77e78cef23 100644 --- a/macros/optex/base/graphics.opm +++ b/macros/optex/base/graphics.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \inspic {Graphics <2022-03-05>} % preloaded in format +\_codedecl \inspic {Graphics <2022-11-05>} % preloaded in format \_doc ----------------------------- \`\inspic` accepts old syntax `\inspic <filename><space>` @@ -47,8 +47,8 @@ \_newtoks\_inkdefs \_inkdefs={% \_def\makeatletter#1\makeatother{}% - \_def\includegraphics[#1]#2{\_inkscanpage#1,page=,\_end \_inspic{\_the\_tmptoks}\_hss}% - \_def\_inkscanpage#1page=#2,#3\_end{\_ifx,#2,\_else\_def\_picparams{page#2}\_fi}% + \_def\includegraphics[#1]#2{\_inkscanpage#1,page=,\_fin \_inspic{\_the\_tmptoks}\_hss}% + \_def\_inkscanpage#1page=#2,#3\_fin{\_ifx,#2,\_else\_def\_picparams{page#2}\_fi}% \_def\put(#1,#2)#3{\_nointerlineskip\_vbox to\_zo{\_vss\_hbox to\_zo{\_kern#1\_picwidth \_pdfsave\_hbox to\_zo{#3}\_pdfrestore\_hss}\_kern#2\_picwidth}}% \_def\begin#1{\_csname _begin#1\_endcsname}% @@ -169,7 +169,7 @@ } \_def\_puttext{\_ea\_ea\_ea\_puttextA\_scantwodimens} -\_def\_puttextA#1#2#3{{\_setbox0=\_hbox{{#3}}\_dimen1=#1sp \_dimen2=#2sp \_puttextB}} +\_long\_def\_puttextA#1#2#3{{\_setbox0=\_hbox{{#3}}\_dimen1=#1sp \_dimen2=#2sp \_puttextB}} \_def\_puttextB{% \_ifvmode \_ifdim\_prevdepth>\_zo \_vskip-\_prevdepth \_relax \_fi @@ -383,7 +383,7 @@ \_ea \_shadowlayer \_fi }% \_pdfliteral{q /op1 gs 0 g 1 0 0 1 \_shadowmoveto\_space cm - \_ifx#1\_circlet 1 0 0 1 \_expr{\_bp{.5\_wd0}} \_expr{\_bp{(\_ht0-\_dp0)/2}} cm + \_ifx#1\_circlet 1 0 0 1 \_bp{.5\_wd0} \_bp{(\_ht0-\_dp0)/2} cm \_else 1 0 0 1 -\_shadowb\_space -\_shadowb\_space cm \_fi \_shadowlayer Q} }} @@ -447,6 +447,8 @@ the \^`\transformbox{<transformation>}{\copy\mypic}`. \_endinput +2022-11-05 \_doshadow: renduntant \_expr from \_expr{\_bp{...}} removed +2022-10-18 \_puttextA defined \long, bug fixed 2022-03-05: \_addextgstate, \pageresources, \addpageresources added 2022-03-03: \_coc introduced 2021-07-16: \inoval, \incircle are more simple, using attribitecolor features diff --git a/macros/optex/base/hi-syntax.opm b/macros/optex/base/hi-syntax.opm index 586cfed69e..c708be0563 100644 --- a/macros/optex/base/hi-syntax.opm +++ b/macros/optex/base/hi-syntax.opm @@ -23,15 +23,15 @@ \_def\_replfromto #1#2{\_edef\_tmpa{{#1}{#2}}\_ea\_replfromtoE\_tmpa} \_def\_replfromtoE#1#2#3{% #1=from #2=to #3=replacement \_def\_replfrom##1#1##2{\_addto\_tmpb{##1}% - \_ifx\_end##2\_ea\_replstop \_else \_afterfi{\_replto##2}\_fi}% + \_ifx\_fin##2\_ea\_replstop \_else \_afterfi{\_replto##2}\_fi}% \_def\_replto##1#2##2{% - \_ifx\_end##2\_afterfi{\_replfin##1}\_else + \_ifx\_fin##2\_afterfi{\_replfin##1}\_else \_addto\_tmpb{#3}% \_afterfi{\_replfrom##2}\_fi}% - \_def\_replfin##1#1\_end{\_addto\_tmpb{#3}\_replstop}% - \_edef\_tmpb{\_ea}\_ea\_replfrom\_tmpb#1\_end#2\_end\_end\_relax + \_def\_replfin##1#1\_fin{\_addto\_tmpb{#3}\_replstop}% + \_edef\_tmpb{\_ea}\_ea\_replfrom\_tmpb#1\_fin#2\_fin\_fin\_relax } -\_def\_replstop#1\_end\_relax{} +\_def\_replstop#1\_fin\_relax{} \_def\_finrepl{} \_doc ----------------------------- @@ -55,12 +55,12 @@ The \`\_xscan` macro replaces occurrences of `\x` by `\z` in the post-processing phase. The construct `\x <letter>{<text>}` expands to `\_xscan {<letter>}<text>^^J^`. - If `#3` is `\_end` then it signals that something wrong happens, the + If `#3` is `\_fin` then it signals that something wrong happens, the `<from>` was not terminated by legal `<to>` when `\replfromto` did work. We must to fix this by using the \`\_xscanR` macro. \_cod ----------------------------- -\_def\_xscan#1#2^^J#3{\_ifx\_end#3 \_ea\_xscanR\_fi +\_def\_xscan#1#2^^J#3{\_ifx\_fin#3 \_ea\_xscanR\_fi \z{#1}{#2}% \_ifx^#3\_else ^^J\_afterfi{\_xscan{#1}#3}\_fi} \_def\_xscanR#1\_fi#2^{^^J} @@ -86,8 +86,8 @@ \_def\_hisyntax#1{\_def\_prepareverbdata##1##2{% \_let\n=\_relax \_let\b=\_relax \_def\t{\n\_noexpand\t\n}\_let\_start=\_relax - \_adef{ }{\n\_noexpand\ \n}\_edef\_tmpb{\_start^^J##2\_end}% - \_replthis{^^J}{\n^^J\b\n}\_replthis{\b\n\_end}{\_end}% + \_adef{ }{\n\_noexpand\ \n}\_edef\_tmpb{\_start^^J##2\_fin}% + \_replthis{^^J}{\n^^J\b\n}\_replthis{\b\n\_fin}{\_fin}% \_let\x=\_relax \_let\y=\_relax \_let\z=\_relax \_let\t=\_relax \_hicomments % keeps comments declared by \commentchars \_endlinechar=`\^^M @@ -104,7 +104,7 @@ \_the\_hicolors % colors which have precedece \_else\_opwarning{Syntax "\_tmpa" undeclared (no file hisyntax-\_tmpa.opm)} \_fi\_fi - \_replthis{\_start\n^^J}{}\_replthis{^^J\_end}{^^J}% + \_replthis{\_start\n^^J}{}\_replthis{^^J\_fin}{^^J}% \_def\n{}\_def\b{}\_adef{ }{\_dsp}% \_bgroup \_lccode`\~=`\ \_lowercase{\_egroup\_def\ {\_noexpand~}}% \_def\w####1{####1}\_def\x####1####2{\_xscan{####1}####2^^J^}% diff --git a/macros/optex/base/hyperlinks.opm b/macros/optex/base/hyperlinks.opm index 4c2007cddb..7505436f16 100644 --- a/macros/optex/base/hyperlinks.opm +++ b/macros/optex/base/hyperlinks.opm @@ -136,10 +136,10 @@ \_replstring\_tmpb{[||]}{{gb|}}% \_replstring\_tmpb{ }{{ }}% \_replstring\_tmpb{://}{{://}}% - \_ea\_ulink \_ea[\_ea{\_tmpa}] {\_urlfont \_ea\_urlA\_tmpb\_end}% + \_ea\_ulink \_ea[\_ea{\_tmpa}] {\_urlfont \_ea\_urlA\_tmpb\_fin}% }} -\_def\_urlA#1{\_ifx\_end#1\_else \_urlC{}{#1}\_fi} -\_def\_urlB#1{\_ifx\_end#1\_else \_urlC{\_urlxskip}{#1}\_fi} +\_def\_urlA#1{\_ifx\_fin#1\_else \_urlC{}{#1}\_fi} +\_def\_urlB#1{\_ifx\_fin#1\_else \_urlC{\_urlxskip}{#1}\_fi} \_def\_urlC#1#2{% \_ifcsname _ur:#2\_endcsname \_lastnamedcs \_ea\_ea\_ea \_urlA \_else #1#2\_ea\_ea\_ea \_urlB \_fi diff --git a/macros/optex/base/if-macros.opm b/macros/optex/base/if-macros.opm index 8f6082a27a..9113b5f8be 100644 --- a/macros/optex/base/if-macros.opm +++ b/macros/optex/base/if-macros.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \newif {Special if-macros, is-macros and loops <2022-05-04>} % preloaded in format +\_codedecl \newif {Special if-macros, is-macros and loops <2022-12-02>} % preloaded in format \_doc ---------------------------- \secc Classical \code{\\newif} @@ -32,9 +32,12 @@ \_doc ---------------------------- \`\afterfi` `{<what to do>}<ignored>\fi` closes condition by `\fi` and processes <what to do>. Usage: - \begtt - \if<something> \afterfi{<result is true>} \else \afterfi{<resut is false>} \fi + \begtt \catcode`<=13 + \if<something> \afterfi{<result is true>} \else \afterfi{<result is false>} \fi \endtt + Nested `\if..\afterfi{\if..\afterfi{...}\fi}\fi` are possible. Another approach is mentioned + in \ulink[http://petr.olsak.net/optex/optex-tricks.html\#fiinif]{OpTeX trick 0098} + which also solves the `\fi` in `\if` problem. \_cod ---------------------------- \_long\_def \_afterfi#1#2\_fi{\_fi#1} @@ -302,9 +305,63 @@ \_public \isnextchar ; + \_doc ---------------------------- + \`\casesof` `<token> <list of cases>` implements something similar to + the `switch` command known from C language. It is expandable macro. The + <list of cases> is a list of arbitrary number of pairs in the format + `<token>`\,`{<what to do>}` which must be finalized by the pair + `\_finc {<what to do else>}`. The optional spaces after <token>s + and between listed cases are ignored. The usage of \^`\casesof` looks like: + \begtt \catcode`<=13 + \casesof <token> + <token-1> {<what to do if token=token-1>} + <token-2> {<what to do if token=token-2>} + ... + <token-n> {<what to do if token=token-n>} + \_finc {<what to do in other cases>} + \endtt + The meaning of tokens are compared by `\ifx` primitive. + The parts `<what to do>` can be finalized by a macro which can read more + data from the input stream as its parameters. + \_cod ---------------------------- + +\_long\_def \_casesof #1#2#3{\_ifx #2\_finc \_ea\_ignoresecond \_else \_ea\_usesecond \_fi + {#3}{\_ifx#1#2\_ea\_ignoresecond \_else \_ea\_usesecond \_fi {\_finc{#3}}{\_casesof#1}}% +} +\_long\_def \_finc #1#2\_finc#3{#1} + +\_public \casesof ; + + \_doc ----------------------------- + \`\xcasesof` `<list of pairs>` extends the features of the macro \^`\casesof`. + Each pair from the `<list of pairs>` is in the format + `{<if statement>}{<what to do>}`, only the last pair must have the different + format: `\_finc {<what to do else>}`. The `<if statement>` can be arbitrary + primitive `\if*` condition (optionally prefixed by `\unless`) and it must be closed + in its expansion. It means that `{\ifnum\mycount>0}` is bad, `{\ifnum\mycount>0 }` + is correct. Optional spaces between parameters are ignored. Example: + \begtt + \message {The \tmpnum has \xcasesof + {\ifnum\tmpnum>0 } {positive} + {\ifnum\tmpnum=0 } {equal to zero} + \_finc {negative} value} + \endtt + The \^`\xcasesof` macro works with principle: first true condition wins, + next conditions are not evaluated. + \_cod ----------------------------- + +\_long\_def \_xcasesof #1{\_xcasesofA #1\_finc} +\_long\_def \_xcasesofA #1#2\_finc #3{% + \_ifx #1\_finc \_ea\_ignoresecond\_else \_ea\_usesecond\_fi + {#3}{#1#2\_ea\_ignoresecond\_else \_ea\_usesecond\_fi {\_finc{#3}}{\_xcasesof}}% +} +\_public \xcasesof ; \_endcode +2022-12-02 \xcasesof: its first parameter is \long too. +2022-11-29 renamed to \casesof, \xcasesof. +2022-11-26 \casesby, \casesbyif introduced. 2022-05-04 \isinlist created expandable. 2022-03-30 \afterfi defined as \long. 2021-08-02 more robust \fornum: \fi moved by \afterfi diff --git a/macros/optex/base/lang-data.opm b/macros/optex/base/lang-data.opm index 6e11f8bd9a..e1b68e5dde 100644 --- a/macros/optex/base/lang-data.opm +++ b/macros/optex/base/lang-data.opm @@ -1,10 +1,10 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \_langdata {Language dependent data <2022-06-28>} % only en, cs preloaded in format +\_codedecl \_langdata {Language dependent data <2022-10-11>} % only en, cs preloaded in format \_langdata en {English} % ----------------------------------------------- \_langw en Chapter Table Figure Subject -\_langb en {, and } { et al.} { ed.} {cit.~} {Vol.~} {No.~} {pp.~} {~p.} {,~ed.} {,~eds.} +\_langb en {, and } { et al.} {\,ed.} {cit.~} {Vol.~} {No.~} {pp.~} {~p.} {,~ed.} {,~eds.} {Available from } {Available also from } {Bachelor's Thesis} {Master's Thesis} {Ph.D. Thesis} \_monthw en January February March April May June @@ -19,10 +19,10 @@ \_langdata cs {Czech} % ------------------------------------------------ % Chapter Table Figure Subject \_langw cs Kapitola Tabulka Obrázek Věc -% {, and } { et al.} { ed.} {cit.~} {Vol.~} {No.~} {pp.~} {~p.} {,~ed.} {,~eds.} +% {, and } { et al.} {\,ed.} {cit.~} {Vol.~} {No.~} {pp.~} {~p.} {,~ed.} {,~eds.} % {Available from } {Available also from } % {Bachelor's Thesis} {Master's Thesis} {Ph.D. Thesis} -\_langb cs { a } { a~kol.} { vyd.} {vid.~} {ročník~} {č.~} {s.~} {~s.} {,~editor} {,~editoři} +\_langb cs { a } { a~kol.} {\,vyd.} {vid.~} {ročník~} {č.~} {s.~} {~s.} {,~editor} {,~editoři} {Dostupné na } {Dostupné též na } {Bakalářská práce} {Diplomová práce} {Disertační práce} % January February March April May June @@ -31,6 +31,8 @@ července srpna září října listopadu prosince \_sdef{_mt:today:cs}{\_the\_day.~\_mtext{m\_the\_month} \_the\_year} % date format \_quotationmarks cs {„“‚‘} +\_preplangmore cs {\_frenchspacing \_postexhyphenchar=`\- + \_def\_langreset{\_postexhyphenchar=0 }} \_let \_sortingdatacs = \_sortingdatalatin \_let \_ignoredcharscs = \_ignoredcharsgeneric @@ -101,7 +103,12 @@ \_langw hu Fejezet Táblázat Ábra Téma \_quotationmarks hu {„”»«} %todo -\_let \_sortingdatahu = \_sortingdatalatin +\_def \_sortingdatahu {% + /,{ },-,&,@,% + aAáÁ,bB,cC,dD,eEéÉ,fF,gG,hH,iIíÍ,jJ,kK,lL,mM,nN,oOóÓ,öÖőŐ,% + pP,qQ,rR,sS,tT,uUúÚ,üÜűŰ,vV,wW,xX,yY,zZ,^^Z,% + 0,1,2,3,4,5,6,7,8,9,'% +} \_let \_ignoredcharshu = \_ignoredcharsgeneric \_def \_compoundcharshu {cs:c^^Z Cs:C^^Z CS:C^^Z dzz:d^^Z^^Z Dzz:D^^Z^^Z DZZ:D^^Z^^Z dz:d^^Z Dz:D^^Z DZ:D^^Z @@ -128,13 +135,15 @@ \_langdata sk {Slovak} % ------------------------------------------------ \_langw sk Kapitola Tabuľka Obrázok Vec -\_langb sk { a } { a~kol.} { vyd.} {vid.~} {ročník~} {č.~} {s.~} {~s.} {,~editor} {,~editori} +\_langb sk { a } { a~kol.} {\,vyd.} {vid.~} {ročník~} {č.~} {s.~} {~s.} {,~editor} {,~editori} {Dostupné na } {Dostupné tiež na } {Bakalárska práca} {Diplomová práca} {Dizertačná práca} \_monthw sk januára februára marca apríla mája júna júla augusta septembra októbra novembra decembra \_sdef{_mt:today:sk}{\_the\_day.~\_mtext{m\_the\_month} \_the\_year} % date format \_quotationmarks sk {„“‚‘} +\_preplangmore sk {\_frenchspacing \_postexhyphenchar=`\- + \_def\_langreset{\_postexhyphenchar=0 }} \_let \_sortingdatask = \_sortingdatalatin \_let \_ignoredcharssk = \_ignoredcharsgeneric @@ -150,6 +159,9 @@ \_endcode +2022-10-11: \postexhyphenchar setting added to cs and sk languages +2022-10-10: { ed.} changed to {\,ed.} +2022-08-31: \_sortingdatahu corrected 2022-06-28: Spanish, Polish, French, Swedish, Hungarian sorting rules added 2022-06-28: German sorting rules added 2022-02-19: concept finalized, but data still far of completness diff --git a/macros/optex/base/lang-decl.opm b/macros/optex/base/lang-decl.opm index 3b9f9e727d..d6b562ed45 100644 --- a/macros/optex/base/lang-decl.opm +++ b/macros/optex/base/lang-decl.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \langlist {Languages declaration <2022-02-19>} % preloaded in format +\_codedecl \langlist {Languages declaration <2022-10-11>} % preloaded in format \_doc ----------------------------- \`\_preplang` `<lang-id> <LongName> <lang-tag> <hyph-tag> <lr-hyph>` @@ -163,13 +163,22 @@ \_cod ----------------------------- \_def\_preplangmore #1 #2{\_ea \_gdef \_csname _langspecific:#1\_endcsname{#2}} -\_def\_langdefault{\_frenchspacing} \_preplangmore en {\_nonfrenchspacing} \_preplangmore enus {\_nonfrenchspacing} \_def\_langdefault {\_frenchspacing} \_doc ----------------------------- + The \`\_langreset` is processed before macros declared by \^`\_preplangmore` + or before \^`\_langdefault`. If you set something for + your language by \^`\_preplangmore` then use `\def\_langreset{<settings>}` + in this code too in order to return default values for all other languages. + See `cs` part of `lang-data.opm` file for an example. + \_cod ----------------------------- + +\_def\_langreset {} + + \_doc ----------------------------- The default `\language=0` is US-English with original hyphenation patterns preloaded in the format (see the end of section~\ref[plain]). We define `\_enlang` and \`\enlang` switches. @@ -236,7 +245,7 @@ \_cod ----------------------------- \_def\_uselang#1#2#3#4{\_language=#2\_lefthyphenmin=#3\_righthyphenmin=#4\_relax - \_trycs{_langspecific:#1}{\_langdefault}% + \_langreset \_def\_langreset{}\_trycs{_langspecific:#1}{\_langdefault}% } \_doc ----------------------------- @@ -310,5 +319,6 @@ \_endcode +2022-10-11 \_langreset introduced 2022-02-19 \_langinput moved here 2022-02-17 released, original file was hyphen-lan.opm diff --git a/macros/optex/base/languages.opm b/macros/optex/base/languages.opm index 4ae66ef1f4..1d7558444c 100644 --- a/macros/optex/base/languages.opm +++ b/macros/optex/base/languages.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \_mtext {Languages <2022-02-19>} % preloaded in format +\_codedecl \_mtext {Languages <2022-11-18>} % preloaded in format \_doc ----------------------------- Four words are generated by \OpTeX/ macros: \"Chapter", @@ -120,8 +120,8 @@ \_def\_qqA#1#2#3{\_bgroup\_setverb \_catcode`\ =10 \_isnextchar\_bgroup{\_catcode`\{=1 \_catcode`\}=2 #1#2#3}{#1#2#3}} -\_long\_def\_qqB#1#2#3"{\_egroup#1\_scantextokens{#3}#2} -\_long\_def\_qqC#1#2#3'{\_egroup#1\_scantextokens{#3}#2} +\_def\_qqB#1#2#3"{\_egroup#1\_scantextokens{#3}#2} +\_def\_qqC#1#2#3'{\_egroup#1\_scantextokens{#3}#2} \_def\_regquotes#1#2#3#4{\_bgroup \_lccode`~=`#2\_lowercase{\_egroup \_def#1##1~}{#3##1#4}} \_doc ----------------------------- @@ -139,6 +139,7 @@ \_endcode % ------------------------------------- +2022-11-18 \"..." are not \long now 2022-02-19 \quotes, \_quotationmarks introduced 2022-02-04 \_langinput, words-lan.opm introduced 2021-05-23 \_monthw: bug fix diff --git a/macros/optex/base/makeindex.opm b/macros/optex/base/makeindex.opm index ba50352559..36b4a48c08 100644 --- a/macros/optex/base/makeindex.opm +++ b/macros/optex/base/makeindex.opm @@ -285,7 +285,7 @@ \_addto\_iilist{#1#2,}% % dvojice skupin vyresena \_sortreturn{\_fif\_mergesort}% % \mergesort dalsi \_fi - \_ifx\_end#3% % neco,konec (#1#2=neco) + \_ifx\_fin#3% % neco,konec (#1#2=neco) \_ifx\_empty\_iilist % neco=kompletni setrideny seznam \_def\_iilist{#1#2}% \_sortreturn{\_fif\_fif\_gobbletoend}% % koncim @@ -303,7 +303,7 @@ \_relax % zarazka, na ktere se zastavi \sortreturn } \_def\_sortreturn#1#2\_fi\_relax{#1} \_def\_fif{\_fi} -\_def\_gobbletoend #1\_end{} +\_def\_gobbletoend #1\_fin{} \_doc ----------------------------- The \`\_dosorting` `\list` macro redefines `\list` as sorted `\list`. @@ -342,7 +342,7 @@ \_csname _secondpass\_sortinglang \_endcsname % activates \_reversewords if needed \_def \_act##1{\_addto #1{##1,}}% \_edef #1{\_ea}\_ea\_xargs \_ea\_act #1;% commas between items added, mergesort initialized - \_edef \_iilist{\_ea}\_ea\_mergesort #1\_end,\_end + \_edef \_iilist{\_ea}\_ea\_mergesort #1\_fin,\_fin \_ea\_endgroup \_ea\_def\_ea#1\_ea{\_iilist}% } diff --git a/macros/optex/base/math-preload.opm b/macros/optex/base/math-preload.opm index 9f73ef24d1..a3ac3e44b3 100644 --- a/macros/optex/base/math-preload.opm +++ b/macros/optex/base/math-preload.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \normalmath {Math fonts CM + AMS preloaded <2022-07-22>} % preloaded in format +\_codedecl \normalmath {Math fonts CM + AMS preloaded <2022-12-01>} % preloaded in format \_doc ------------------------------ We have two math macros \`\normalmath` for the normal shape of all math @@ -126,47 +126,49 @@ like `\_loadmathfamily` does it. But the second parameter is a `\<font-switch>` declared previously by the `\font` primitive. \nl + The `<number>` is saved by \^`\_loadmathfamily`, \^`\_setmathfamily` + to the \`\_mfam`. + \nl The font family is loaded at \`\_sizemtext`, \`\_sizemscript` and \`\_sizemsscript` sizes. These sizes are set by the \`\setmathsizes` `[<text-size>/<script-size>/<scriptscript-size>]` macro. These parameters are given in the \`\ptmunit` unit, it is set to 1\`\ptunit` and it is set to 1\,pt by default. \nl - \`\_corrmsize` `<factor><space>` can be used just before - `\_loadmathfamily` or `\_setmathfamily`. - The `<factor>` is decimal number, it denotes - scale-factor \"size of loaded math font in `\textstyle` : size of text font". - You can use it in `\_normalmath` or `\_boldmath` macros if you want to do a - corrections (for example due to different ex-height in text and math - font). The `\_corrmsize` is applied only to one following - `\_loadmathfamily` or `\_setmathfamily`. If it is missing - then the `<factor>` is 1 for such math family (i.e.\ no size corrections). + \`\_mfactor` sets scaling factor for given math fonts family + related to text font size. It does the setting `\_ptmunit=<factor>\_ptunit` where + the <factor> is defined by `\sdef{_mfactor:<family>}{<factor>}`. + For eample, you can set `\sdef{_mfactor:1}{0.95}` if you found that + this scaling of math family 1 gives better visual compatibility + with used text fonts. If not declared then scaling factor is~1. \_cod ----------------------------- -\_def\_corrmsize#1 {\_ptmunit=#1\_ptunit} % for corrections of sizes in diferent fonts - -\_def\_loadmathfamily #1 #2 {% +\_def\_loadmathfamily {\_afterassignment\_loadmathfamilyA \_chardef\_mfam} +\_def\_loadmathfamilyA #1 {\_mfactor \_edef\_optsizesave{\_the\_optsize}% - \_optsize=\_sizemtext \_font\_mF=\_optfn{#2} at\_optsize \_textfont#1=\_mF - \_optsize=\_sizemscript \_font\_mF=\_optfn{#2} at\_optsize \_scriptfont#1=\_mF - \_optsize=\_sizemsscript \_font\_mF=\_optfn{#2} at\_optsize \_scriptscriptfont#1=\_mF - \_optsize=\_optsizesave \_ptmunit=\_ptunit + \_optsize=\_sizemtext \_font\_mF \_optfn{#1} at\_optsize \_textfont\_mfam=\_mF + \_optsize=\_sizemscript \_font\_mF \_optfn{#1} at\_optsize \_scriptfont\_mfam=\_mF + \_optsize=\_sizemsscript \_font\_mF \_optfn{#1} at\_optsize \_scriptscriptfont\_mfam=\_mF + \_optsize=\_optsizesave } -\_def\_setmathfamily #1 #2{\_let\_mF=#2% +\_def\_setmathfamily {\_afterassignment\_setmathfamilyA \_chardef\_mfam} +\_def\_setmathfamilyA #1{\_mfactor \_let\_mF=#1% \_edef\_optsizesave{\_the\_optsize}% - \_optsize=\_sizemtext \_fontlet#2=#2 at\_optsize \_textfont#1=#2% - \_optsize=\_sizemscript \_fontlet#2=#2 at\_optsize \_scriptfont#1=#2% - \_optsize=\_sizemsscript \_fontlet#2=#2 at\_optsize \_scriptscriptfont#1=#2% - \_optsize=\_optsizesave \_ptmunit=\_ptunit \_let#2=\_mF + \_optsize=\_sizemtext \_fontlet#1#1at\_optsize \_textfont\_mfam=#1% + \_optsize=\_sizemscript \_fontlet#1#1at\_optsize \_scriptfont\_mfam=#1% + \_optsize=\_sizemsscript \_fontlet#1#1at\_optsize \_scriptscriptfont\_mfam=#1% + \_optsize=\_optsizesave \_let#1=\_mF } \_def\_setmathsizes[#1/#2/#3]{\_ptmunit=\_ptunit \_def\_sizemtext{#1\_ptmunit}\_def\_sizemscript{#2\_ptmunit}% \_def\_sizemsscript{#3\_ptmunit}% } +\_def\_mfactor{\_ptmunit=\_trycs{_mfactor:\_the\_mfam}{}\_ptunit} + \_newdimen\_ptunit \_ptunit=1pt \_newdimen\_ptmunit \_ptmunit=1\_ptunit -\_public \setmathsizes \ptunit \ptmunit ; +\_public \setmathsizes \ptunit ; \_doc ----------------------------- \`\_setmathparam``<luatex-param> {<factor>}` sets @@ -176,10 +178,14 @@ \_cod ----------------------------- \_def\_setmathparam#1#2{% - #1\_displaystyle =#2\_fontdimen6\_textfont1 - #1\_textstyle =#2\_fontdimen6\_textfont1 - #1\_scriptstyle =#2\_fontdimen6\_scriptfont1 - #1\_scriptscriptstyle =#2\_fontdimen6\_scriptscriptfont1 + #1\_displaystyle =#2\_fontdimen6\_textfont1 + #1\_crampeddisplaystyle =#2\_fontdimen6\_textfont1 + #1\_textstyle =#2\_fontdimen6\_textfont1 + #1\_crampedtextstyle =#2\_fontdimen6\_textfont1 + #1\_scriptstyle =#2\_fontdimen6\_scriptfont1 + #1\_crampedscriptstyle =#2\_fontdimen6\_scriptfont1 + #1\_scriptscriptstyle =#2\_fontdimen6\_scriptscriptfont1 + #1\_crampedscriptscriptstyle =#2\_fontdimen6\_scriptscriptfont1 } \_doc ----------------------------- @@ -243,6 +249,9 @@ For example \_endinput +2022-12-01 reading number by \_loadmathfamily, \_setmathfamily more robust +2022-11-16: \_corrmsize removed, \_mfactor introduced +2022-09-04: \crampedstyles setings added. 2022-07-22: \_setmathparam\_Umathspaceafterscript added. 2022-02-22: \rm, \it, etc moved to fonts-select, \_marm, \_mait etc. introduced 2020-05-06: \itfam, \ttfam removed, (Unicode math preferred) diff --git a/macros/optex/base/more-macros.opm b/macros/optex/base/more-macros.opm index f256458184..418e71b774 100644 --- a/macros/optex/base/more-macros.opm +++ b/macros/optex/base/more-macros.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \eoldef {OpTeX useful macros <2022-05-24>} % preloaded in format +\_codedecl \eoldef {OpTeX useful macros <2022-11-24>} % preloaded in format \_doc ----------------------------- We define \`\opinput` `{<file name>}` macro which @@ -89,7 +89,7 @@ loaded file is forgotten after the `\opinput`. \_cod ----------------------------- -\_def \_load [#1]{\_loadA #1,,,\_end} +\_def \_load [#1]{\_savemathsb \_loadA #1,,,\_end \_restoremathsb} \_def \_loadA #1#2,{\_ifx,#1 \_ea \_loadE \_else \_loadB{#1#2}\_ea\_loadA\_fi} \_def \_loadB #1{% \_ifcsname _load:#1\_endcsname \_else @@ -105,25 +105,29 @@ The declarator \`\optdef``\macro [<opt default>] <params>{<replacement text>}` defines the `\macro` with the optional parameter followed by normal parameters declared in `<params>`. The optional parameter must be used as the first - first parameter in brackets `[...]`. If it isn't used then <opt default> + parameter in brackets `[...]`. If it isn't used then <opt default> is taken into account. The `<replacement text>` can use `\the\opt` because optional parameter is saved to the \`\opt` tokens register. Note the difference from \LaTeX/ concept where the optional parameter is in `#1`. \OpTeX/ uses `#1` as the first normal parameter (if declared). - The \`\_nospaceafter` ignores the following optional space at expand + The \`\nospaceafter` ignores the following optional space at expand processor level using the negative `\romannumeral` trick. + The \`\nospacefuturelet` bahaves like `\futurelet` primitive, but it + ignores the following optional space and works at expand processor level. \_cod ----------------------------- +\_newtoks\_opt \_def\_optdef#1[#2]{% \_def#1{\_opt={#2}\_isnextchar[{\_cs{_oA:\_csstring#1}}{\_cs{_oB:\_csstring#1}}}% \_sdef{_oA:\_csstring#1}[##1]{\_opt={##1}\_cs{_oB:\_csstring#1\_nospaceafter}}% \_sdef{_oB:\_csstring#1\_nospaceafter}% } -\_def\_nospaceafter#1{\_ea#1\_romannumeral-`\.} -\_newtoks\_opt +\_def\_nospaceafter#1{\_ea#1\_romannumeral-`\.\_noexpand} +\_def\_nospacefuturelet#1#2{\_ea\_immediateassignment + \_ea\_futurelet\_ea#1\_ea#2\_romannumeral-`\.\_noexpand} -\_public \opt \optdef ; +\_public \opt \optdef \nospaceafter \nospacefuturelet ; \_doc ----------------------------- The declarator \`\eoldef``\macro #1{<replacement text>}` defines a `\macro` @@ -150,8 +154,8 @@ \_eoldef\_skiptoeol#1{} \_def\_bracedparam#1{\_ifcsname _\_csstring #1:M\_endcsname \_csname _\_csstring #1:M\_ea \_endcsname - \_else \_csname __in\_csstring #1:M\_ea \_endcsname \_fi -} + \_else \_csname _in\_csstring #1\_ea \_endcsname \_fi +} \_public \eoldef \skiptoeol \bracedparam ; \_doc ----------------------------- @@ -170,10 +174,10 @@ the next line continues. \_cod ----------------------------- -\_def\_scantoeol#1{\def\_tmp{#1}\_begingroup \_setscancatcodes \_scantoeolA} +\_def\_scantoeol#1{\_begingroup \_setscancatcodes \_scantoeolA #1} \_def\_setscancatcodes{\_setverb \_catcode`\^^M=12\_catcode`\^=7\_catcode`\ =10\_catcode`\^^J=14 } \_catcode`\^^M=12 % -\_def\_scantoeolA#1^^M{\_endgroup \_tmp{#1}}% +\_def\_scantoeolA#1#2^^M{\_endgroup #1{#2}}% \_normalcatcodes % \_public \scantoeol ; @@ -194,13 +198,20 @@ It finishes processing or appends the next part to `\_tmptoks` separated by <textB> and continues loop. The final part of the macro removes the last `?` from resulting `\_tmptoks` and defines a new version of the `\foo`. + + The \^`\replstring` macro is not expandable, but you can create your + expandable macro, for example: + \begtt + \def\replAB#1{\immediateassigned{\def\tmp{#1}\replstring\tmp{A}{B}}\the\_tmptoks} + \replAB {text A \and A} % expands to "text B \and B" + \endtt \_cod ----------------------------- \_newtoks\_tmptoks \_catcode`!=3 \_catcode`?=3 \_def\_replstring #1#2#3{% \replstring #1{stringA}{stringB} \_long\_def\_replacestringsA##1#2{\_tmptoks{##1}\_replacestringsB}% - \_long\_def\_replacestringsB##1#2{\_ifx!##1\_relax \_else \_toksapp\_tmptoks{#3##1}% + \_long\_def\_replacestringsB##1#2{\_ifx!##1\_relax \_else \_tmptoks\_ea{\_the\_tmptoks#3##1}% \_ea\_replacestringsB\_fi}% \_ea\_replacestringsA #1?#2!#2% \_long\_def\_replacestringsA##1?{\_tmptoks{##1}\_edef#1{\_the\_tmptoks}}% @@ -232,7 +243,22 @@ \_def\_removespaces #1 {\_isempty{#1}\_iffalse #1\_ea\_removespaces\_fi} \_ea\_def \_ea\_ignorept \_ea#\_ea1\_detokenize{pt}{#1} -\public \removespaces \ignorept ; +\_public \removespaces \ignorept ; + + \_doc ----------------------------- + If you do `\let\foo=a` then it is not simple to return from `\foo` to the original + character code of `a`. You can write \code{`a} but you cannot write \code{`\\foo}. + The macro \`\cstochar``<sequence>` solves this problem. If the sequence + is equal to a character then it expands to this character (always with + catcode 12). If it isn't equal to a character then it expands to nothing. + You can say \code{\\expanded{`\\cstochar\\foo}} if you want to extract + the character code. + \_cod ----------------------------- + +\_def\_cstochar#1{\_ea\_cstocharA\_meaning#1 {} {} \_fin} +\_def\_cstocharA#1 #2 #3 #4\_fin{\_isinlist{#1#2}-\_iffalse #3\_fi} + +\_public \cstochar ; \_doc ----------------------------- You can use expandable \`\bp``{<dimen>}` convertor from @@ -262,6 +288,53 @@ \_public \expr \bp ; \_doc ------------------ + You can write \^`\setpos``[<label>]` somewhere and the position of such + \^`\setpos``[<label>]` can be referenced by \^`\posx``[<label>]`, + \^`\posy``[<label>]` and \^`\pospg``[<label>]`. The first two macros + expand to $x$ and $y$ position measured from left-bottom corner of the page + (dimen values) and \^`\pospg[<label>]` expands to the <gpageno>, i.e.\ to + the page number counted from one at beginning of the document. + These values are available in the second (and more) \TeX/ run, because the + information is saved to `.ref` file and restored from it at the beginning of + the \TeX/ job. If these values are not known then mentioned macros expand to + 0sp, 0sp and 0. The following example implements `\linefrom[<label>]` and + `\lineto[<label>]` macros. The line connecting these two points is drawn + (after second \TeX/ run): + \begtt + \def\linefrom[#1]{\setpos[#1:f]\drawlinefromto[#1]} + \def\lineto [#1]{\setpos[#1:t]} + \def\drawlinefromto[#1]{\ifnum\pospg[#1:f]>0 \ifnum\pospg[#1:f]=\pospg[#1:t] + \pdfliteral{q 0 0 m 1 0 0 RG % << red color + \expr{\bp{\posx[#1:t]}-\bp{\posx[#1:f]}} + \expr{\bp{\posy[#1:t]}-\bp{\posy[#1:f]}} l S Q}\fi\fi + } + This is a text.\linefrom[A]\par + This is second paragraph with a text.\lineto[A] + Try to reverse from-to and watch the changes. + \endtt + The coordinates are saved to the `.ref` file in the format + \`\_Xpos``{<label>}{<x-pos>}{<y-pos>}`. The \^`\_Xpos` macro defines + `\_pos:<label>` as `{<x-pos>}{<y-pos>}{<total-pg>}{<rel-pg>}`. + We need to read only given parameter by `\_posi`, `\_posii` or `\_posiii` + auxiliary macros. The implementation of + \`\setpos`, \`\posx` and \`\posy` macros are based on `\padsavepos` + `\pdflastxpos` and `\pdflastypos` pdf\TeX/ primitives. The \`\pospg` + simply reads the data from the \~`\_currpage` macro. + \_cod ------------------ + +\_def\_Xpos#1#2#3{\_sxdef{_pos:#1}{{#2}{#3}\_currpage}} +\_def\_setpos[#1]{\_openref\_pdfsavepos + \_ewref\_Xpos{{#1}\_unexpanded{{\_the\_pdflastxpos}{\_the\_pdflastypos}}}} + +\_def\_posx [#1]{\_ea \_posi \_expanded {\_trycs{_pos:#1}{{0}{}{}{}}sp}} +\_def\_posy [#1]{\_ea \_posii \_expanded {\_trycs{_pos:#1}{{}{0}{}{}}sp}} +\_def\_pospg[#1]{\_ea \_posiii \_expanded {\_trycs{_pos:#1}{{}{}{0}{}}}} + +\_def\_posi #1#2#3#4{#1} \_def\_posii #1#2#3#4{#2} \_def\_posiii #1#2#3#4{#3} + +\_public \setpos \posx \posy \pospg ; + + \_doc ------------------ The pair {\`\_doc` ... \`\_cod`} is used for documenting macros and to printing the technical documentation of the \OpTeX/. The syntax is: {\begtt \catcode`\<=13 @@ -276,8 +349,28 @@ \_long\_def\_doc #1\_cod {\_skiptoeol} + \_doc ------------------ + \`\docgen` processes lines before `\_codedecl` because the version text + in the macro `\_<pkg>_version` can be defined here. The package + documentation can print it. \^`\docgen` prints banner to log because TeX doesn't do it + when command line doesn't begin with the main file name after parameters. + \_cod ------------------ + +\_def\_docgen #1 {\_ea \_docgenA \_input{#1.opm}} +\_long \_def\_docgenA #1\_codedecl#2\_endcode #3\_doc {#1\_wlog{\_banner}\_skiptoeol} + +\_public \docgen ; + \_endcode % ------------------------------------- +2022-11-24 \setpos, \posx, \posy moved from OpTeX trick here +2022-11-22 \docgen writes banner to log +2022-11-20 \docgen reads lines before \_codedecl in order to define pkg. version +2022-11-18 \cstochar introduced +2022-11-13 \docgen introduced, \bracedparam corrected, \scantoeol modified +2022-11-05 \replstring can be expandable using \immediateassigned: \toksapp replaced +2022-11-03 \nospacefuturelet added. +2022-10-27 \_savemathsb ...\_restoremathsb added to \load (eg. \load[xstring]) 2022-05-24 \optdef: used \csstring instead \string, bug fixed. 2021-04-25 \normalcatcodes: typo fixed 2021-04-22 \the\_currctable replaced by \the\_catcodetable, bug fixed. diff --git a/macros/optex/base/multicolumns.opm b/macros/optex/base/multicolumns.opm index 83ed0f9e10..d84aef69c6 100644 --- a/macros/optex/base/multicolumns.opm +++ b/macros/optex/base/multicolumns.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \begmulti {Balanced columns <2022-05-05>} % preloaded in format +\_codedecl \begmulti {Balanced columns <2022-11-26>} % preloaded in format \_doc ----------------------------- \`\_betweencolumns` or \`\_leftofcolumns` or \`\_rightofcolumns` include @@ -37,7 +37,9 @@ \_newcount\_mullines -\_def\_begmulti #1 {\_par\_bgroup\_wipeepar \_multiskip \_def\_Ncols{#1} +\_def\_begmulti #1 {\_par\_bgroup\_wipeepar + \_ifnum\_lastpenalty>10000 \_vskip4.5\_baselineskip\_penalty9999 \_vskip-4.5\_baselineskip \_fi + \_multiskip \_def\_Ncols{#1} \_setbox6=\_vbox\_bgroup\_bgroup \_let\_setxhsize=\_relax \_penalty-99 %% \hsize := column width = (\hsize+\colsep) / n - \colsep \_setbox0=\_hbox{\_leftofcolumns\_rightofcolumns}% @@ -142,6 +144,7 @@ \_endcode % ------------------------------------- +2022-11-26 \at least three lines in the beginning of \begmulti at the page 2022-05-05 `\_betweencolumns` etc. introduced. 2021-05-20 Colors inside \begmulti...\endmuti, bug fixed 2020-03-26 Introduced diff --git a/macros/optex/base/optex.ini b/macros/optex/base/optex.ini index 05e052f82b..4941ead57c 100644 --- a/macros/optex/base/optex.ini +++ b/macros/optex/base/optex.ini @@ -21,7 +21,7 @@ % OpTeX version -\def\optexversion{1.08 Aug 2022} +\def\optexversion{1.09 Dec 2022} \def\fmtname{OpTeX} \let\fmtversion=\optexversion @@ -60,7 +60,7 @@ \input fonts-select.opm % font selection system \input math-preload.opm % math fams CM + AMS preloaded \input math-macros.opm % basic macros for math plus mathchardefs -\input math-unicode.opm % macros for loading UnicodeMath fonts +\input unimath-macros.opm % macros for loading UnicodeMath fonts \input fonts-opmac.opm % font managing macros from OPmac \input output.opm % output routine \input margins.opm % macros for margins setting @@ -94,7 +94,7 @@ } \_everyjob = {% - \_message{This is OpTeX (Olsak's Plain TeX), version <\optexversion>^^J}% + \_message{\_banner^^J}% \_directlua{lua.bytecode[1]()}% load OpTeX's Lua code \_mathsbon % replaces \int_a^b to \int _a^b \_inputref % inputs \jobname.ref if exists diff --git a/macros/optex/base/optex.lua b/macros/optex/base/optex.lua index 3bec088b60..40915fd6d4 100644 --- a/macros/optex/base/optex.lua +++ b/macros/optex/base/optex.lua @@ -8,7 +8,8 @@ local fmt = string.format -- -- Define namespace where some \OpTeX/ functions will be added. -optex = optex or {} +local optex = _ENV.optex or {} +_ENV.optex = optex -- Error function used by following functions for critical errors. local function err(message) @@ -17,12 +18,14 @@ end -- -- For a `\chardef`'d, `\countdef`'d, etc., csname return corresponding register -- number. The responsibility of providing a `\XXdef`'d name is on the caller. -function registernumber(name) +local function registernumber(name) return token.create(name).index end +_ENV.registernumber = registernumber +optex.registernumber = registernumber -- -- MD5 hash of given file. -function mdfive(file) +function optex.mdfive(file) local fh = io.open(file, "rb") if fh then local data = fh:read("*a") @@ -32,7 +35,8 @@ function mdfive(file) end -- -- \medskip\secc[lua-alloc] Allocators^^M -alloc = alloc or {} +local alloc = _ENV.alloc or {} +_ENV.alloc = alloc -- -- An attribute allocator in Lua that cooperates with normal \OpTeX/ allocator. local attributes = {} @@ -51,17 +55,17 @@ end -- Allocator for Lua functions ("pseudoprimitives"). It passes variadic -- arguments (\"`...`") like `"global"` to `token.set_lua`. local function_table = lua.get_functions_table() -function define_lua_command(csname, fn, ...) +local function define_lua_command(csname, fn, ...) local luafnalloc = #function_table + 1 token.set_lua(csname, luafnalloc, ...) -- WARNING: needs LuaTeX 1.08 (2019) or newer function_table[luafnalloc] = fn end --- --- `provides_module` is needed by older version of luaotfload -provides_module = function() end +_ENV.define_lua_command = define_lua_command +optex.define_lua_command = define_lua_command -- -- \medskip\secc[callbacks] Callbacks^^M -callback = callback or {} +local callback = _ENV.callback or {} +_ENV.callback = callback -- -- Save `callback.register` function for internal use. local callback_register = callback.register @@ -388,17 +392,18 @@ end) -- -- Compatibility with \LaTeX/ through luatexbase namespace. Needed for -- luaotfload. -luatexbase = { +_ENV.luatexbase = { registernumber = registernumber, attributes = attributes, - provides_module = provides_module, + -- `provides_module` is needed by older version of luaotfload + provides_module = function() end, new_attribute = alloc.new_attribute, callback_descriptions = callback.callback_descriptions, create_callback = callback.create_callback, add_to_callback = callback.add_to_callback, remove_from_callback = callback.remove_from_callback, call_callback = callback.call_callback, - callbacktypes = {} + callbacktypes = {}, } -- -- `\tracingmacros` callback registered. @@ -441,6 +446,7 @@ local pdfdict_mt = { local function pdf_dict(t) return setmetatable(t or {}, pdfdict_mt) end +optex.pdf_dict = pdf_dict -- local resource_dict_objects = {} local page_resources = {} @@ -653,34 +659,67 @@ callback.add_to_callback("pre_shipout_filter", function(list) return tonode(list) end, "_colors") -- --- We also hook into `luaotfload`'s handling of color. Instead of the default --- behavior (inserting colorstack whatsits) we set our own attribute. The hook --- has to be registered {\em after} `luaotfload` is loaded. -function optex_hook_into_luaotfload() - if not luaotfload.set_colorhandler then - return -- old luaotfload, colored fonts will be broken +-- We also hook into `luaotfload`'s handling of color and transparency. Instead +-- of the default behavior (inserting colorstack whatsits) we set our own +-- attribute. On top of that, we take care of transparency resources ourselves. +-- +-- The hook has to be registered {\em after} `luaotfload` is loaded. +local setattribute = direct.set_attribute +local token_setmacro = token.set_macro +local color_count = registernumber("_colorcnt") +local tex_getcount, tex_setcount = tex.getcount, tex.setcount +-- +local function set_node_color(n, color) -- "1 0 0 rg" or "0 g", etc. + local attr = tonumber(token_getmacro("_color::"..color)) + if not attr then + attr = tex_getcount(color_count) + tex_setcount(color_count, attr + 1) + local strattr = tostring(attr) + token_setmacro("_color::"..color, strattr) + token_setmacro("_color:"..strattr, color) + token_setmacro("_color-s:"..strattr, string.upper(color)) end - local setattribute = direct.set_attribute - local token_setmacro = token.set_macro - local color_count = registernumber("_colorcnt") - local tex_getcount, tex_setcount = tex.getcount, tex.setcount - luaotfload.set_colorhandler(function(head, n, rgbcolor) -- rgbcolor = "1 0 0 rg" - local attr = tonumber(token_getmacro("_color::"..rgbcolor)) - if not attr then - attr = tex_getcount(color_count) - tex_setcount(color_count, attr + 1) - local strattr = tostring(attr) - token_setmacro("_color::"..rgbcolor, strattr) - token_setmacro("_color:"..strattr, rgbcolor) - -- no stroke color set - end - setattribute(n, color_attribute, attr) + setattribute(todirect(n), color_attribute, attr) +end +optex.set_node_color = set_node_color +-- +function optex.hook_into_luaotfload() + -- color support for luaotfload v3.13+, otherwise broken + pcall(luaotfload.set_colorhandler, function(head, n, rgbcolor) -- rgbcolor = "1 0 0 rg" + set_node_color(n, rgbcolor) return head, n end) + + -- transparency support for luaotfload v3.22+, otherwise broken + pcall(function() + luatexbase.add_to_callback("luaotfload.parse_transparent", function(input) -- from "00" to "FF" + -- in luaotfload: 0 = transparent, 255 = opaque + -- in optex: 0 = opaque, 255 = transparent + local alpha = tonumber(input, 16) + if not alpha then + tex.error("Invalid transparency specification passed to font") + return nil + elseif alpha == 255 then + return nil -- this allows luaotfload to skip calling us for opaque style + end + local transp = 255 - alpha + local transpv = fmt("%.3f", alpha / 255) + pdf.add_page_resource("ExtGState", fmt("tr%d", transp), pdf_dict{ca = transpv, CA = transpv}) + pdf.add_page_resource("ExtGState", "tr0", pdf_dict{ca = 1, CA = 1}) + return transp -- will be passed to the below function + end, "optex") + + luaotfload.set_transparenthandler(function(head, n, transp) + setattribute(n, transp_attribute, transp) + return head, n + end) + end) end -- History: - -- 2022-03-07 transparency in the colorize() function, current_tr added + -- 2022-08-25 expose some useful functions in `optex` namespace + -- 2022-08-24 luaotfload transparency with attributes added + -- 2022-03-07 transparency in the colorize() function, current_tr added -- 2022-03-05 resources management added -- 2021-07-16 support for colors via attributes added -- 2020-11-11 optex.lua released diff --git a/macros/optex/base/others.opm b/macros/optex/base/others.opm index 47bfe573fd..98df836f76 100644 --- a/macros/optex/base/others.opm +++ b/macros/optex/base/others.opm @@ -107,8 +107,8 @@ \_def\_lipsumtext[#1]{\_lipsumload\_cs{_lip:#1}} \_def\_lipsum[#1]{\_lipsumA #1.]{#1}} -\_def\_lipsumA #1.#2]#3{\_ifx^#2^\_lipsumB #1\_empty-\_empty\_end \_else \_lipsumdot[#1].\_fi} -\_def\_lipsumB #1-#2\_empty#3\_end{% +\_def\_lipsumA #1.#2]#3{\_ifx^#2^\_lipsumB #1\_empty-\_empty\_fin \_else \_lipsumdot[#1].\_fi} +\_def\_lipsumB #1-#2\_empty#3\_fin{% \_fornum #1..\_ifx^#2^#1\_else#2\_fi \_do {\_lipsumtext[##1]\_par}} \_def\_lipsumload{{% \_setbox0=\_vbox{\_tmpnum=0 % vertical mode during \input lipsum.ltd.tex @@ -118,8 +118,8 @@ \_opinput {lipsum.ltd.tex}% \_global\_let\_lipsumload=\_empty }}} -\_def\_lipsumdot[#1]{\_lipsumload \_ea\_ea\_ea \_lipsumdotA \_csname _lip:#1\_endcsname.\_end} -\_def\_lipsumdotA #1.#2\_end {#1} +\_def\_lipsumdot[#1]{\_lipsumload \_ea\_ea\_ea \_lipsumdotA \_csname _lip:#1\_endcsname.\_fin} +\_def\_lipsumdotA #1.#2\_fin {#1} \_public \lipsum \lipsumtext ; \_let \lorem=\lipsum diff --git a/macros/optex/base/output.opm b/macros/optex/base/output.opm index c74d99d371..095cfda4b3 100644 --- a/macros/optex/base/output.opm +++ b/macros/optex/base/output.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \nopagenumbers {Output routine <2021-03-07>} % preloaded in format +\_codedecl \nopagenumbers {Output routine <2022-10-20>} % preloaded in format \_doc ----------------------------- \`\_optexoutput` is the default output routine. You can create another...\nl @@ -86,7 +86,7 @@ \_def\_makeheadline {\_istoksempty \_headline \_iffalse \_vbox to\_zo{\_vss \_baselineskip=\_headlinedist \_lineskiplimit=-\_maxdimen - \_hbox to\_xhsize{\_the\_headline}\_hbox{}}\_nointerlineskip + \_hbox to\_xhsize{\_normalbaselines\_the\_headline}\_hbox{}}\_nointerlineskip \_fi } @@ -96,7 +96,7 @@ \_def\_makefootline{\_istoksempty \_footline \_iffalse \_baselineskip=\_footlinedist - \_lineskiplimit=-\_maxdimen \_hbox to\_xhsize{\_the\_footline} + \_lineskiplimit=-\_maxdimen \_hbox to\_xhsize{\_normalbaselines\_the\_footline} \_fi } @@ -258,6 +258,7 @@ The output routine \^`\_optexoutput` is similar as in plain \TeX. It does: \_endinput +2022-10-22 \_normalbaselines added to \makehead/foot/line 2022-03-07 \_resetattrs instead \_resetcolor 2021-07-16 output routine supports colors via attributes 2021-02-25 \_draftbox improved diff --git a/macros/optex/base/pdfuni-string.opm b/macros/optex/base/pdfuni-string.opm index 89a479895a..4e5a29e9db 100644 --- a/macros/optex/base/pdfuni-string.opm +++ b/macros/optex/base/pdfuni-string.opm @@ -51,8 +51,8 @@ \_escapechar=-1 \_edef#1{#1\_empty}% \_escapechar=`\\ - \_ea\_edef \_ea#1\_ea{\_ea\_removeoutmath #1$\_end$}% $x$ -> x - \_ea\_edef \_ea#1\_ea{\_ea\_removeoutbraces #1{\_end}}% {x} -> x + \_ea\_edef \_ea#1\_ea{\_ea\_removeoutmath #1$\_fin$}% $x$ -> x + \_ea\_edef \_ea#1\_ea{\_ea\_removeoutbraces #1{\_fin}}% {x} -> x \_edef#1{\_detokenize\_ea{#1}}% \_replstring#1{ }{{ }}% text text -> text{ }text \_catcode`\\=12 \_let\\=\_bslash @@ -69,8 +69,8 @@ } \_def\_removeoutbraces #1#{#1\_removeoutbracesA} -\_def\_removeoutbracesA #1{\_ifx\_end#1\_else #1\_ea\_removeoutbraces\_fi} -\_def\_removeoutmath #1$#2${#1\_ifx\_end#2\_else #2\_ea\_removeoutmath\_fi} +\_def\_removeoutbracesA #1{\_ifx\_fin#1\_else #1\_ea\_removeoutbraces\_fi} +\_def\_removeoutmath #1$#2${#1\_ifx\_fin#2\_else #2\_ea\_removeoutmath\_fi} \_doc ----------------------------- The \`\_prepinverb``<macro><separator>{<text>}`, @@ -83,9 +83,9 @@ \_def\_prepinverb#1#2#3{\_def#1{}% \_def\_dotmpb ##1#2##2{\_addto#1{\_scantextokens{\_unexpanded{##1}}}% - \_ifx\_end##2\_else\_ea\_dotmpbA\_ea##2\_fi}% + \_ifx\_fin##2\_else\_ea\_dotmpbA\_ea##2\_fi}% \_def\_dotmpbA ##1#2{\_addto#1{##1}\_dotmpb}% - \_dotmpb#3#2\_end + \_dotmpb#3#2\_fin } \_doc ----------------------------- diff --git a/macros/optex/base/plain-macros.opm b/macros/optex/base/plain-macros.opm index 6909abff09..6ae59108b5 100644 --- a/macros/optex/base/plain-macros.opm +++ b/macros/optex/base/plain-macros.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \magstep {Macros from plain TeX <2022-02-19>} % preloaded in format +\_codedecl \magstep {Macros from plain TeX <2022-10-11>} % preloaded in format \_doc ----------------------------- The \`\dospecials` works like in plain TeX but does nothing with `_`. @@ -200,7 +200,7 @@ \_chardef\AE="C6 \_chardef\OE="D7 \_chardef\O="D8 -\_chardef\i="11 \chardef\j="12 % dotless letters +\_chardef\i="19 \chardef\j="1A % dotless letters \_chardef\aa="E5 \_chardef\AA="C5 \_chardef\S="9F @@ -219,15 +219,19 @@ \_public \mathhexbox ; \_doc ----------------------------- - The \`\_unichars` macro is run in \^`\initunifonts`, + The \`\_unichars` macro is run in \~`\initunifonts`, Unicodes are used instead old plain \TeX/ settings. \_cod ----------------------------- -\def\_unichars{% characters with different codes in Unicode: +\def\_unichars{% Plain TeX character sequences with different codes in Unicode: \_chardef\ss=`ß - \_chardef\oe=`œ - \_chardef\OE=`Œ - \_chardef\S=`§ + \_chardef\ae=`æ \_chardef\AE=`Æ + \_chardef\oe=`œ \_chardef\OE=`Œ + \_chardef\o=`ø \_chardef\O=`Ø + \_chardef\aa=`å \_chardef\AA=`Å + \_chardef\l=`ł \_chardef\L=`Ł + \_chardef\i=`ı \_chardef\j=`ȷ + \_chardef\S=`§ \_chardef\P=`¶ \_chardef\dag`† \_chardef\ddag`‡ \_chardef\copyright`© @@ -365,6 +369,7 @@ \_endcode % ------------------------------------- +2022-10-11 ... \_unichars extended 2022-02-19 ... \input hyphen.tex moved here (format file is 80k smaller) 2021-09-24 ... \_unichars introduced 2021-04-09 ... \_public\showhyphens, bug fixed diff --git a/macros/optex/base/prefixed.opm b/macros/optex/base/prefixed.opm index d15ee4140d..a599e0ec85 100644 --- a/macros/optex/base/prefixed.opm +++ b/macros/optex/base/prefixed.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \public {Prefixing and code syntax <2021-08-16>} % preloaded in format +\_codedecl \public {Prefixing and code syntax <2022-11-25>} % preloaded in format \_doc --------- All \TeX/ primitives have alternative control sequence `\_hbox` `\_string`, ... @@ -21,15 +21,19 @@ private form of \`\_ea` because there is high probability that `\ea` will be redefined by the user. \nl - \`\public` `<sequence> <sequence> ... ;` does + \`\public` `\<sequence> \<sequence> ... ;` does `\let \<sequence> = \_<sequence>` for all sequences. \nl - \`\private` `<sequence> <sequence> ...;` does + \`\private` `\<sequence> \<sequence> ...;` does `\let \_<sequence> = \<sequence>` for all sequences. \nl - \`\_checkexists` `<where> <prefix><sequence>` prints error - if the control sequence propagated to - a new name space by `\public` etc. macros is not declared. + \`\newpublic``<do>\<sequence>` prints warning if `\<sequence>` + is declared already. Then runs `<do>\<sequence>`.\nl + \`\_checkexists` `<where> {<sequence-string>}` prints error + if the control sequence given by its name <sequence-string> + is not declared. This check is used in `\public`, `\private`, + `\_nspublic` and `\_nsprivate` macros in order to avoid mistakes + in names when declaring new control sequences. \nl \`\xargs` `<what> <sequence> <sequence> ... ;` does `<what><sequence>` for each sequences. @@ -42,62 +46,42 @@ \_def \_pkglabel{} \_def \_public {\_xargs \_publicA} \_def \_publicA #1{% - \_checkexists \public _#1% + \_checkexists \public {_\_csstring#1}% \_ea\_let \_ea#1\_csname _\_csstring #1\_endcsname } \_def \_private {\_xargs \_privateA} \_def \_privateA #1{% - \_checkexists \private {}#1% + \_checkexists \private {\_csstring #1}% \_ea\_let \_csname _\_csstring #1\_endcsname =#1% } -\_def\_checkexists #1#2#3{\_unless \_ifcsname #2\_csstring#3\_endcsname - \_errmessage {\_string#1: \_bslash#2\_csstring#3 must be declared}\_fi -} -\_public \public \private \xargs \ea ; - - \_doc ----------------------- - Each macro file should begin with \`\_codedecl` `\macro {<info>}`. - If the `\macro` is defined already then the `\endpinput` protects to read - such file more than once. Else the <info> is printed to the terminal - and the file is read.\nl - The {\`\_endcode`} is defined as `\endinput` in the `optex.ini` file. - \`\wterm` `{<text>}` prints the `<text>` to the terminal and to the `.log` file, - \`\wlog` `{<text>}` prints the `<text>` only to the `.log` file (as in plain \TeX) - \_cod ----------------------- - -\_def \_codedecl #1#2{% - \_ifx #1\_undefined \_wlog{#2}% - \_else \_ea \_endinput \_fi +\_def\_checkexists #1#2{\_unless \_ifcsname #2\_endcsname + \_errmessage {\_string#1: \_bslash#2 must be declared}\_fi } -\_def \_wterm {\_immediate \_write16 } -\_def \_wlog {\_immediate\_write-1 } % write on log file (only) - -\_public \wterm \wlog ; - - \_doc ------------------------ - The `\optexversion` and `\fmtname` are defined in the `optex.ini` file. - Maybe, somebody will need a private version of these macros. - \_cod ------------------------ - -\_private \optexversion \fmtname ; +\_def\_newpublic #1#2{\_unless\_ifx #2\_undefined + \_opwarning{\_string#2 is redefined% + \_ifx\_pkglabel\_empty \_else\_space by the \_ea\_ignoreit\_pkglabel\_space package\_fi}\_fi + #1#2% +} +\_public \public \private \newpublic \xargs \ea ; \_doc ----------------------------- - The `\_mathsbon` and `\_mathsboff` are defined in `math-macros.opm` file. - Now, we define the macros + We define the macros \`\_namespace` `{<pkg label>}`, \`\_resetnamespace` `{<pkg label>}`, \`\_endnamespace`, - \`\_nspublic` and \`\_nsprivate` + \`\_pkglabel`, \`\_nspublic`, and \`\_nsprivate` for package writers, see section~\ref[pkg-namespace].{\hbadness=2200\par} \_cod ----------------------------- \_def \_pkglabel{} \_def\_namespace #1{% - \_ifcsname namesp:#1\_endcsname \_errmessage + \_ifcsname _namesp:#1\_endcsname \_errmessage {The name space "#1" is used already, it cannot be used twice}% \_endinput - \_else \_resetnamespace{#1}\_fi + \_else + \_ea \_gdef \_csname _namesp:#1\_endcsname {}% + \_resetnamespace{#1}\_fi } \_def\_resetnamespace #1{% - \_ea \_gdef \_csname namesp:#1\_endcsname {}% + \_unless \_ifx \_pkglabel\_empty \_endnamespace \_fi \_gdef \_pkglabel{_#1}% \_directlua{ callback.add_to_callback("process_input_buffer", @@ -110,20 +94,60 @@ \_directlua{ callback.remove_from_callback("process_input_buffer", "_namespace") }% \_gdef \_pkglabel{}% } - \_def \_nspublic {\_xargs \_nspublicA} \_def \_nspublicA #1{% - \_checkexists \nspublic {\_pkglabel _}#1% - \_unless\_ifx #1\_undefined - \_opwarning{\_ea\_ignoreit\_pkglabel\_space redefines the meaning of \_string#1}\_fi - \_ea\_let \_ea#1\_csname \_pkglabel _\_csstring #1\_endcsname + \_checkexists \_nspublic {\_pkglabel _\_csstring #1}% + \_ea\_newpublic \_ea\_let \_ea#1\_csname \_pkglabel _\_csstring #1\_endcsname } \_def \_nsprivate {\_xargs \_nsprivateA} \_def \_nsprivateA #1{% - \_checkexists \nsprivate {}#1% + \_checkexists \_nsprivate {\_csstring #1}% \_ea\_let \_csname \_pkglabel _\_csstring #1\_endcsname =#1% } + \_doc ----------------------- + Each macro file should begin with \`\_codedecl` `\macro {<info>}`. + If the `\macro` is defined already then the `\endpinput` protects to read + such file more than once. Else the <info> is printed to the terminal + and the file is read. + The {\`\_endcode`} is defined as `\endinput` in the `optex.ini` file. + \`\wterm` `{<text>}` prints the `<text>` to the terminal and to the `.log` file, + \`\wlog` `{<text>}` prints the `<text>` only to the `.log` file (as in plain \TeX) + \_cod ----------------------- + +\_def \_codedecl #1#2{% + \_ifx #1\_undefined \_wlog{@:[\_basefilename\_currfile] #2}% + \_else \_ea \_endinput \_fi +} +\_def \_wterm {\_immediate \_write16 } +\_def \_wlog {\_immediate\_write-1 } % write on log file (only) + +\_public \wterm \wlog ; + + \_doc ----------------------------- + \`\currfile` returns the name of the current input file including its path.\nl + \`\basefilename``\currfile` returns base name of + the current file, without its path and extension.\nl + \`\_nofilepath` `<text>/<with>/<slashes>/\_fin` expands to the last segment + separated by slashes.\nl + \`\_nofileext` `<filename>.\_fin` expands to the file name without extension. + \_cod ----------------------------- + +\_def\_currfile{\_directlua{tex.print(status.filename)}} +\_def\_basefilename #1{\_ea\_nofileext\_expanded{\_ea\_ea\_ea\_nofilepath#1/\_fin}.\_fin} +\_def\_nofilepath #1/#2{\ifx#2\_fin #1\_else \_ea\_nofilepath \_ea#2\_fi} +\_def\_nofileext #1.#2\_fin{#1} + +\_public \currfile \basefilename ; + + \_doc ------------------------------ + We define \`\_fin` as a useless macro. Suppose that its meaning will be never + used for another control sequence. You can use `\_fin` as a final delimiter + of a list of tokens and your macro can ask `\ifx\_fin#1` in order to + decide that the list of tokens is finalized. + \_cod ------------------------------ + +\_protected\_long \_def \_fin \_fin {} \_endcode %---------------------------------------------------- @@ -216,25 +240,48 @@ features can be lost (printing percent character by `\%` for example). \secc Macro files syntax -Each segment of \OpTeX/ macros is stored in one file with `.opm` extension +Segments of \OpTeX/ macros or external macro packages +are stored in files with `.opm` extension (means OPtex Macros). Your local macros should be in a normal `*.tex` file. The code in macro files starts by \^`\_codedecl` and ends by \^`\_endcode`. The \^`\_endcode` is equivalent for `\endinput`, so documentation can follow. The \^`\_codedecl` has syntax: -\begtt -\_codedecl \sequence {Name <version>} +\begtt \catcode`<=13 \adef!{\string} +\_codedecl \sequence {<short title> !<<version>>} \endtt -If the mentioned `\sequence` is defined, then \^`\_codedecl` does the same as +If the mentioned `\sequence` is undefined then \^`\_codedecl` prints the message +\begtt \catcode`<=13 \adef!{\string} +@:[<file name>] <short title> !<<version>> +\endtt +to the log file and \TeX/ continues with reading the following macros. +If the `\sequence` is defined, then \^`\_codedecl` acts like `\endinput`: this protects from reading the file twice. We suppose, that `\sequence` is defined in the macro file. -It is possible to use the \^`\_doc` ... \^`\_cod` pair between the macro lines. -The documentation text should be here. It is ignored when macros are read -but it can be printed using `doc.opm` macros like in this documentation. - +It is possible to use the \^`\_doc` ... \^`\_cod` pair between the macro +definitions. The documentation text should be here. +It is ignored when macros are read. + +The \^`\_doc` ... \^`\_cod` parts can be printed after \^`\load[doc]` +using \~`\printdoc` macro, see section~\ref[doc]. +If you have created a documented macro file `pkgname.opm` then you can +put macros for creating your documentation between +first pair of \^`\_doc` ... \^`\_cod` used after \^`\_endcode`. +These macros should \^`\load[doc]` and must be finished by \^`\bye`. +Then you have code+documentation together in a single file and +user can generate the documentation of our package by +\^`\docgen` used at command line: +\begtt +optex -jobname pkgname-doc '\docgen pkgname' +\endtt +Example of a \^`\_doc` ... \^`\_cod` code used for creating the +documentation using \^`\docgen` can be found in the `math.opm` file. You can see +\ulink[https://petr.olsak.net/ftp/olsak/optex/math-doc.pdf]{its documentation}, especially +\ulink[https://petr.olsak.net/ftp/olsak/optex/math-doc.pdf\#ref:pkgtemplate] +{section about creating packages}. \secc[pkg-namespace] Name spaces for package writers @@ -255,12 +302,23 @@ The scope of the \^`\_namespace` command ends at the \^`\_endnamespace` command or when another \^`\_namespace` is used. This command checks if the same package label is not declared by the \^`\_namespace` twice. -The \^`\_nspublic` macro does `\let\foo = \_<pkg>_foo` when +\^`\_nspublic` `<list of sequences> ;` +does `\let\foo = \_<pkg>_foo` for each given sequence when \^`\_namespace{<pkg>}` is declared. Moreover, it prints a warning if `\foo` is defined already. The \^`\_nsprivate` macro does reverse operation to it without warnings. Example: you can define `\def\.macro{...}` and then set it to the user name space by `\_nspublic \macro;`. +It could happen that a package writer needs to declare a control sequence +(say `\foo`) directly without setting it in `\_<pkg>_foo` name space +followed by using \^`\_nspublic`. The \^`\newpublic` prefix should be used in this +case, for example `\_newpublic\_def\foo` or `\_newpublic\_chardef\foo` or +`\_newpublic{\_long\_def}\foo`. The \^`\newpublic``<do>\<sequence>` prints +a warning if the declared `\<sequence>` is defined already and then runs +`<do>\<sequence>`. The reason of the warning is the same as when +\^`\_nspublic` warns about doing re-declaration of control sequences already +declared. + Don't load other packages (which are using their own namespace) inside your namespace. Do load them before your \^`\_namespace`~`{<pkg>}` is initialized. Or close your namespace by \^`\_endnamespace` and open it again @@ -315,6 +373,10 @@ can look like. \endinput +2022-11-25 \_resetnamespace: moved \gdef\_namesp:#1 {} to \_namespace +2022-11-24 \newpublic introduced, \_checkexists with only two parameters. +2022-11-22 \currfile introduced and used in \_codedecl +2022-11-13 \_resetnamespace corrected 2021-08-16 \_wlog moved from basic macros, \_codedecl uses \_wlog only. 2021-04-25 \_checkexists introduced 2021-02-15 \_expandafter -> \_ea in \_codedecl diff --git a/macros/optex/base/ref-file.opm b/macros/optex/base/ref-file.opm index 7f9c619009..922150f9f5 100644 --- a/macros/optex/base/ref-file.opm +++ b/macros/optex/base/ref-file.opm @@ -29,7 +29,7 @@ printed. Try running `optex op-demo` twice to see the effect. \_cod -------------------------- -\_def\_mdfive#1{\_directlua{mdfive("#1")}} +\_def\_mdfive#1{\_directlua{optex.mdfive("#1")}} \_def\_prevrefhash{} \_doc -------------------------- diff --git a/macros/optex/base/references.opm b/macros/optex/base/references.opm index c26320b046..9da2bca30f 100644 --- a/macros/optex/base/references.opm +++ b/macros/optex/base/references.opm @@ -94,9 +94,9 @@ but the optional `@` in the `<given-text>` is replaced by the `<implicit-text>` first. \_cod ----------------------------- -\_def\_reftext #1#2{\_isatin #2@\_iffalse #2\_else\_reftextA{#1}#2\_end \_fi} -\_def\_reftextA #1#2@#3\_end {#2#1#3} -\_def\_isatin #1@#2\_iffalse {\_ifx\_end#2\_end} +\_def\_reftext #1#2{\_isatin #2@\_iffalse #2\_else\_reftextA{#1}#2\_fin \_fi} +\_def\_reftextA #1#2@#3\_fin {#2#1#3} +\_def\_isatin #1@#2\_iffalse {\_ifx\_fin#2\_fin} \_doc ----------------------------- Default \`\_printlabel` is empty macro (labels are not printed). diff --git a/macros/optex/base/sections.opm b/macros/optex/base/sections.opm index 9ff2c2d436..7d7a78232b 100644 --- a/macros/optex/base/sections.opm +++ b/macros/optex/base/sections.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \chap {Titles, chapters, sections, subsections <2022-08-02>} % preloaded in format +\_codedecl \chap {Titles, chapters, sections, subsections <2022-10-19>} % preloaded in format \_doc --------------------------- We are using scaled fonts for titles @@ -28,6 +28,7 @@ \_nobreak\_bigskip } \_def\_tit{\_scantoeol\_printtit} +\_let\_intit=\_printtit % used by \bracedparam \_public \tit ; @@ -332,9 +333,11 @@ The \`\caption``/<letter>` increases `\_<letter>num` counter, edefines \`\_thecapnum` as `\_the<letter>num` and defines \`\_thecaptitle` as language-dependent word using \^`\_mtext`, + declares default format by \^`\_captionformat``{<letter>}` and runs the `\_everycaption<letter>` tokens register. - The group opened by `\caption` is finalized by first `\_par` from - an empty line or from `\vskip` or from `\endinsert`. + The two groups opened by `\caption` are finalized by first `\_par` from + an empty line or from `\vskip`, `\cskip` or from `\endinsert`. + If a \code{\}} occurs first then `\_par` from `\aftergroup` is processed. The `\_printcaption<letter>` is called, it starts with printing of the caption.\nl The \`\cskip` macro inserts nonbreakable vertical space between the caption and @@ -348,8 +351,11 @@ \_else \_opwarning{Unknown caption /\_tmpa}\_fi \_edef\_thecapnum {\_csname _the\_tmpa num\_endcsname}% \_edef\_thecaptitle{\_mtext{\_tmpa}}% + \_ea\_captionformat\_ea{\_tmpa}% \_ea\_the \_csname _everycaption\_tmpa\_endcsname - \_def\_par{\_nbpar\_egroup}% + \_def\_par{\_ifhmode\_nbpar\_egroup\_egroup\_fi}% + \_ifx\par\_endgraf \_let\par=\_par \_fi + \_bgroup \_aftergroup\_par \_cs{_printcaption\_tmpa}% } \_def \_cskip {\_par\_nobreak\_medskip} % space between caption and the object @@ -359,12 +365,15 @@ \_doc ----------------------------- The \`\_printcaptiont` and \`\_printcaptionf` macros start in vertical mode. They switch to horizontal mode and use `\_wlabel\_thecapnum` (in order to - make reference and hyperlink destination) a they can use: + make reference and hyperlink destination). They can use: \begitems * \^`\_thecaptitle` ... expands to the word Table or Figure (depending on the current language). * \^`\_thecapnum` ... expands to `\the<letter>num` (caption number). \enditems + The macro \^`\_printcaptiont` (or `f`) is processed inside group and the + `\_par` can be run after this group. If you want to re-define formating + parameters for `\_par`, do this in the macro \^`\_captionformat`. The \`\_captionsep` inserts a separator between auto-generated caption number and the following caption text. Default separator is `\_enspace` but if the caption text starts with dot or colon, then @@ -375,7 +384,7 @@ \_def \_printcaptiont {% \_noindent \_wlabel\_thecapnum {\_bf\_thecaptitle~\_thecapnum}% - \_narrowlastlinecentered\_iindent \_futurelet\_next\_captionsep + \_futurelet\_next\_captionsep } \_def\_captionsep{\_ifx\_next.\_ea\_bfnext \_else\_ifx\_next:\_ea\_ea\_ea\_bfnext \_else \_enspace \_fi\_fi} @@ -392,11 +401,14 @@ \def\_theanum {\_othe\_chapnum.\_the\_secnum.\_the\_anum} \sdef{_mt:a:en}{Algorithm} \sdef{_mt:a:cs}{Algoritmus} % + your language... \endtt - The default format of `\caption` text is a paragraph in block narrower by + The format of the \^`\caption` text is given by the + \`\_captionformat``{<caption-letter>}` macro. + The default format for `t` and `f` is a paragraph in block narrower by `\_iindent` and with the last line is centered. This setting is done by the \`\_narrowlastlinecentered` macro. \_cod ----------------------------- +\_def\_captionformat#1{\_narrowlastlinecentered\_iindent} \_def\_narrowlastlinecentered#1{% \_leftskip=#1plus1fil \_rightskip=#1plus-1fil @@ -461,6 +473,7 @@ \_endcode % ------------------------------------- +2022-10-19 More robust \caption (two opened groups, \_printcaption introduced) 2022-08-02 Penalties in \_printsec, \_printsecc changed 2022-07-11 \_printchap: \_prevdepth=0pt added, see issue 100 2021-03-03 \_captionsep introduced, \_othe used in \_thetnum, \_thefnum. diff --git a/macros/optex/base/table.opm b/macros/optex/base/table.opm index 26131897fc..1866c0486d 100644 --- a/macros/optex/base/table.opm +++ b/macros/optex/base/table.opm @@ -22,12 +22,12 @@ \_cod ----------------------------- \_newifi \_ifpxto -\_def\_table#1#{\_tablebox\_bgroup \_tableW#1\_empty\_end +\_def\_table#1#{\_tablebox\_bgroup \_tableW#1\_empty\_fin \_bgroup \_catcodetable\_optexcatcodes \_tableA} -\_def\_tableW#1#2\_end{\_pxtofalse +\_def\_tableW#1#2\_fin{\_pxtofalse \_ifx#1\_empty \_def\_tablew{}\_else - \_ifx#1p \_def\_tablew{}\_tableWx#2\_end \_else \_def\_tablew{#1#2}\_fi\_fi} -\_def\_tableWx xto#1\_end{\_tmpdim=#1\_relax \_pxtotrue} + \_ifx#1p \_def\_tablew{}\_tableWx#2\_fin \_else \_def\_tablew{#1#2}\_fi\_fi} +\_def\_tableWx xto#1\_fin{\_tmpdim=#1\_relax \_pxtotrue} \_public \table ; \_doc ----------------------------- @@ -337,12 +337,12 @@ \_def\_tablinefil{\_leaders\_hrule\_hfil} \_def\_crlp#1{\_crcr \_zerotabrule \_noalign{\_kern-\_drulewidth}% - \_omit \_xdef\_crlplist{#1}\_xdef\_crlplist{,\_ea}\_ea\_crlpA\_crlplist,\_end,% + \_omit \_xdef\_crlplist{#1}\_xdef\_crlplist{,\_ea}\_ea\_crlpA\_crlplist,\_fin,% \_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,\_ea\_crlpA\_fi} -\_def\_crlpB#1#2-#3,{\_ifx\_end#3\_xdef\_crlplist{\_crlplist#1#2,}\_else\_crlpC#1#2-#3,\_fi} +\_def\_crlpA#1,{\_ifx\_fin#1\_else \_crlpB#1-\_fin,\_ea\_crlpA\_fi} +\_def\_crlpB#1#2-#3,{\_ifx\_fin#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{\_incr\_tmpnum \_edef\_tmpa{\_noexpand\_isinlist\_noexpand\_crlplist{,\_the\_tmpnum,}}% diff --git a/macros/optex/base/unimath-codes.opm b/macros/optex/base/unimath-codes.opm index 229ea4575d..418d0d28aa 100644 --- a/macros/optex/base/unimath-codes.opm +++ b/macros/optex/base/unimath-codes.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \_ncharrmA {Uni math codes <2022-07-20>} % preloaded on demand by \loadmath +\_codedecl \_ncharrmA {Uni math codes <2022-11-20>} % preloaded on demand by \loadmath \_doc ----------------------------- The control sequences for `\alpha`, `\beta` etc are redefined here. @@ -170,19 +170,30 @@ \_doc ----------------------------- Each math symbol has its declaration in the file `unicode-math-table.tex` which is copied to `unimath-table.opm`. The file has the following format: - {\vitt{unimath-table.opm}\verbinput (70-85) unimath-table.opm } - We have to read this information and convert it to the Unicode math codes. + {\vitt{unimath-table.opm}\verbinput (36-41) unimath-table.opm } + We have to read this information and set given control sequences to + the relevant Unicode characters using `\chardef`. We don't use `\mathchardef` + for them because the want to manage the matcodes (class, family, slot) + only at single place: at Unicode characters. Control sequeces declared here + are only pointers to these Unicode characters. Exceptions are delimiters and + math accents.\nl + If the character is delimiter then we declare \_d:<sequence> to be the + `\chardef` equivalent of the character and `\let<sequence>=<character>` + because `\left`, `\right` doesn't like `\chardef` equivalent of the + character although it has its own delcode. \_cod ----------------------------- \_begingroup % \input unimath-table.opm (it is a copy of unicode-math-table.tex): \_def\UnicodeMathSymbol #1#2#3#4{% - \_ifnum#1=\_Umathcodenum#1 % the code isn't set by mathclass.opm - \_Umathchardef#2=0 1 #1 \_Umathcode#1=0 1 #1 - \_else \_Umathcharnumdef#2=\_Umathcodenum#1 \_fi - \_ifx#3\_mathopen \_def#2{\_Udelimiter 4 1 #1 }\_fi - \_ifx#3\_mathclose \_def#2{\_Udelimiter 5 1 #1 }\_fi - \_ifx#3\_mathaccent \_def#2{\_Umathaccent fixed 7 1 #1 }\_fi + \_chardef#2=#1 % control sequence is only pointer to Unicode character + \_ifnum#1=\_Umathcodenum#1 \_Umathcode#1=0 1 #1 \_fi % it isn't set by mathclass.opm + \_ifx#3\_mathopen \_setdelimiter#2\_fi + \_ifx#3\_mathclose \_setdelimiter#2\_fi + \_ifx#3\mathfence \_setdelimiter#2\_fi + \_ifx#3\_mathaccent \_protected\_def#2{\_Umathaccent fixed 7 1 #1 }\_fi } + \_def\mathfence{F}% + \_def\_setdelimiter#1{\_expanded{\_let\_cs{_d:\_csstring#1}=#1\_let#1=\Uchar#1}} \_globaldefs=1 \_input unimath-table.opm \_endgroup @@ -203,10 +214,8 @@ % mathclas defines ! as Ord, plain.tex as Close \_Umathcode `! = 5 1 `! % keep plain.tex declaration -\_Umathchardef \mathexclam = 5 1 `! % mathclas defines ? as Punct, plain.tex as Close \_Umathcode `? = 5 1 `? % keep plain.tex declaration -\_Umathchardef \mathquestion = 5 1 `? \_Umathcode `* = 2 1 "02217 % equivalent to \ast, like in plain TeX @@ -222,22 +231,24 @@ \_public \sqrt \cuberoot \fourthroot ; -\_def\_intwithnolimits#1#2 {\_ifx#1\_relax \_else - \_ea\_let\_csname\_csstring#1op\_endcsname=#1% - \_ea\_def\_ea #1\_ea{\_csname\_csstring#1op\_endcsname \_nolimits}% - \_bgroup \_lccode`\~=#2 \_lowercase{\_egroup \_mathcode`~="8000 \_let ~=#1}% + \_doc ----------------------------- + We save the `\mathcode` of `\int` to `\_intop` using `\Umathchardef` and + declare Unicode character `\int` as math-active and define it + as `\_intop\_nolimits`. We define `\intop` as `\_intop` for users + (intergral with normal limits). + We do this with other int-like operators listed below too. + \_cod ----------------------------- + +\_def\_intwithnolimits#1{\_ifx#1\_relax \_else + \_ea\_Umathcharnumdef\_csname _\_csstring#1op\_endcsname=\_Umathcodenum#1% + \_ea\_def \_csname\_csstring#1op\_ea\_endcsname\_ea{\_csname _\_csstring#1op\_endcsname}% + \_bgroup \_lccode`\~=#1 \_lowercase{\_egroup + \_ea\_def\_ea~\_ea{\_csname _\_csstring#1op\_endcsname\_nolimits}\_mathcode`~="8000 }% \_ea \_intwithnolimits \_fi } -\_intwithnolimits \int "0222B \iint "0222C \iiint "0222D - \oint "0222E \oiint "0222F \oiiint "02230 - \intclockwise "02231 \varointclockwise "02232 \ointctrclockwise "02233 - \sumint "02A0B \iiiint "02A0C \intbar "02A0D \intBar "02A0E \fint "02A0F - \pointint "02A15 \sqint "02A16 \intlarhk "02A17 \intx "02A18 - \intcap "02A19 \intcup "02A1A \upint "02A1B \lowint "02A1C \_relax "0 - -\_protected\_def \vert {\_Udelimiter 0 1 "07C } -\_protected\_def \Vert {\_Udelimiter 0 1 "02016 } -\_protected\_def \Vvert {\_Udelimiter 0 1 "02980 } +\_intwithnolimits \int \iint \iiint \oint \oiint \oiiint + \intclockwise \varointclockwise \ointctrclockwise \sumint \iiiint \intbar \intBar \fint + \pointint \sqint \intlarhk \intx \intcap \intcup \upint \lowint \_relax \_protected\_def \_overbrace #1{\_mathop {\_Umathaccent 7 1 "023DE{#1}}\_limits} \_protected\_def \_underbrace #1{\_mathop {\_Umathaccent bottom 7 1 "023DF{#1}}\_limits} @@ -274,7 +285,6 @@ \_global\_Umathcode "22EF = 0 1 "22EF % mathclass says that it is Rel \_global\_Umathcode "002E = 0 1 "002E % mathclass says that dot is Punct -\_global\_Umathchardef \unicodecdots = 0 1 "22EF \_global\_Umathcode `/ = 0 1 `/ % mathclass says that / is Bin, Plain TeX says that it is Ord. @@ -451,6 +461,9 @@ for technical details about Unicode-math. \_endinput History: +2022-11-20 \mathfence's get delimiter code too +2022-11-18 Delimiters re-implemented +2022-11-17 \Umathchardef replaced by \chardef 2022-07-20 \Umathcode for copyright declared 2022-02-22 \rm, \bf etc. moved to font-select, \_marm, \_mabf etc. introduced 2022-02-08 several wide math accents added diff --git a/macros/optex/base/math-unicode.opm b/macros/optex/base/unimath-macros.opm index 22db1d095e..96f87a6a9b 100644 --- a/macros/optex/base/math-unicode.opm +++ b/macros/optex/base/unimath-macros.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \loadmath {Unicode Math fonts <2022-07-22>} % preloaded in format +\_codedecl \loadmath {Unicode Math fonts <2022-12-01>} % preloaded in format \_doc ----------------------------- \`\loadmath` `{<Unicode-math font>}` loads the given font. It does: @@ -66,16 +66,18 @@ math families (5, 6, 7, etc.) in the \^`\normalmath` macro. \nl The default value of \^`\_normalunimath` shows a combination of base Unicode-math - font with 8bit Math font at family 4. See definition of `\script` macro where + font at family 1 with 8bit Math font at family 4. See definition of `\script` macro where `\fam4` is used. \_cod ----------------------------- \_def\_normalunimath{% + \_setmathfamily 0 \_tenrm % font for non-math objects in math mode \_loadumathfamily 1 {\_unimathfont}{} % Base font \_loadmathfamily 4 rsfs % script \_setunimathdimens }% \_def\_boldunimath{% + \_setmathfamily 0 \_tenbf % font for non-math objects in math mode \_ifx\_unimathboldfont \_undefined \_loadumathfamily 1 {\_unimathfont}{embolden=1.7;} % Base faked bold \_else @@ -117,14 +119,10 @@ The `<font features>` are added to the default \`\_mfontfeatures` and to the size-dependent features `ssty=1` if script size is asked or `ssty=2` if scriptscriptsize is asked.\nl - \`\_mparams``<number>` inserts additional font feature `nomathparam` - if the <number> of the family is greater than 3. Lua\TeX/ sets math - parameters (thickness of fraction rules etc., see section 7.4 in Lua\TeX/ - documentation) repeatedly from loaded math - fonts if `nomathparam` is not given. We want to load these parameters only - from fonts at families 0--3 (and actually we are using only family 1 as main math font).\nl - The \^`\_corrmsize` `<factor><space>` can be used just before - `\_loadumathfamily`, see section~\ref[math-preload] for more information.\nl + \`\_mparams` can insert additional font features + dependig on the current `\_mfam`.\nl + The \^`\_mfactor` `<family><space>` sets scaling factor, + see section~\ref[math-preload] for more information.\nl The \`\_textmff`, \`\_scriptmff` and \`\_sscriptmff` are font features for text, script and sscript sizes respectively. They are locally re-defined in \^`\mathbox` macro. @@ -133,16 +131,16 @@ \_def\_umathname#1#2{"#1:\_mfontfeatures#2"} \_def\_mfontfeatures{mode=base;script=math;} -\_def\_loadumathfamily #1 #2#3 {% - \_font\_mF=\_umathname{#2}{\_textmff \_mparams{#1}#3} at\_sizemtext \_textfont #1=\_mF - \_font\_mF=\_umathname{#2}{\_scriptmff \_mparams{#1}#3} at\_sizemtext \_scriptfont #1=\_mF - \_font\_mF=\_umathname{#2}{\_sscriptmff\_mparams{#1}#3} at\_sizemtext \_scriptscriptfont#1=\_mF - \_ptmunit=\_ptunit +\_def\_loadumathfamily{\_afterassignment\_loadumathfamilyA \_chardef\_mfam} +\_def\_loadumathfamilyA #1#2 {\_mfactor + \_font\_mF \_umathname{#1}{\_textmff \_mparams #2} at\_sizemtext \_textfont \_mfam=\_mF + \_font\_mF \_umathname{#1}{\_scriptmff \_mparams #2} at\_sizemtext \_scriptfont \_mfam=\_mF + \_font\_mF \_umathname{#1}{\_sscriptmff\_mparams #2} at\_sizemtext \_scriptscriptfont\_mfam=\_mF } \_def\_textmff {ssty=0;mathsize=1;} \_def\_scriptmff {ssty=1;mathsize=2;} \_def\_sscriptmff{ssty=2;mathsize=3;} -\_def\_mparams#1{\_ifnum#1>3 nomathparam;\_fi} +\_def\_mparams{} \_doc ----------------------------- Unicode math font includes all typical math alphabets together, user needs not to @@ -210,6 +208,8 @@ \~`\normalmath` and \~`\boldmath` macros. Note that allocationos using \^`\newfam` starts from 43 because numbers 1--42 are reserved for direct usage without \^`\newfam`. + We use \^`\aheadto` here because we want to read the main family 1 as + last one (for definitive setting of math parameters). \_cod ----------------------------- \_def\_addUmathfont #1#2#3#4#5#6{% #1: fam (will be set), #2#3: normal font, #4#5: bold font @@ -217,11 +217,12 @@ \_else \_isfont{#2}\_iffalse \_opwarning{font #2 is unavailable}% \_else \_newfam#1\_relax - \_global\_addto\_normalmath{\_corrmsize#6 \_loadumathfamily #1 {#2}{#3} }% + \_sdef{_mfactor:\_the\_numexpr#1\_relax}{#6}% + \_global\_aheadto\_normalmath{\_loadumathfamily #1{#2}{#3} }% \_ifx\_relax#4\_relax - \_global\_addto\_boldmath{\_corrmsize#6 \_loadumathfamily #1 {#2}{embolden=1.7;} }% + \_global\_aheadto\_boldmath{\_loadumathfamily #1{#2}{embolden=1.7;} }% \_else - \_global\_addto\_boldmath{\_corrmsize#6 \_loadumathfamily #1 {#4}{#5} }% + \_global\_aheadto\_boldmath{\_loadumathfamily #1{#4}{#5} }% \_fi \_normalmath \_wterm{add-MATH-FONT: #1=\the#1, "#2", \ifx"#4"\else bold: "#4"\fi}% @@ -229,27 +230,58 @@ } \_doc ----------------------------- - \`\resetmathchars` `<fam> <list of sequences> ;` - saves <fam> to \`\_mafam` and applies \`\_resetmathcharsX` - to each sequence from <list of sequences>. + \`\mathchars` `<fam> {<list of sequences>}` + saves <fam> to \`\_mafam` and runs for each sequence from the <list of sequences> + the relevant code settings. The `\directlua` chunk prints the 8-digits hexadecimal code of the - sequence followed by the sequence itself. The digts are scanned by \`\_resetmathcharsY` - and new `\Umathchardef` and `\Umathcode` is declared. Note that the used + sequence followed by the sequence itself. The digts are scanned by \`\_mathcharsB` + and new `\Umathcode` is declared.\nl + If there exist \_d:<sequence> (i.e.\ it is delimiter) then `\Udelcode` is + redeclared too. Finally, in case of `\int`-like operators the + `\_intop` sequence is redeclared by `\Umathchardef`. Note that the used primitives have the syntax: \begtt \catcode`<=13 - \Umathchardef <sequence> <math class> <math family> <slot number> - \Umathcode <code> <math class> <math family> <slot number> + \Umathchardef <sequence> = <math class> <math family> <slot number> + \Umathcode <code> = <math class> <math family> <slot number> + \Udelcode <code> = <math family> <slot number> \endtt \_cod ----------------------------- -\_def\_resetmathchars #1{\_chardef\_mafam=#1\_relax \_xargs \_resetmathcharX} -\_def\_resetmathcharX#1{\_ea\_resetmathcharY - \_directlua{tex.print(string.format("\_pcent08X", \_the#1))}#1} -\_def\_resetmathcharY#1#2#3#4#5#6#7#8#9{% #9 is given \math-sequence - \_Umathchardef #9\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8 - \_Umathcode "#4#5#6#7#8=\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8 +\_def\_mathchars {\_afterassignment\_mathcharsA \_chardef\_mafam=} +\_def\_mathcharsA #1{\_foreach #1\_do{% + \_ifcsname _d:\_csstring##1\_endcsname \_ea \_mathcharsD \_csname _d:\_csstring##1\_endcsname + \_else \_mathcharsC ##1\_fi +}} +\_def\_mathcharsC #1{\_ea\_mathcharsB + \_directlua{tex.print(string.format("\_pcent08X", \_the\_Umathcode#1))}#1% } -\_public \addUmathfont \resetmathchars ; +\_def\_mathcharsB #1#2#3#4#5#6#7#8#9{% #9 is given \math-sequence + \_ifcsname _\_csstring#9op\_endcsname + \_ea \_Umathchardef \_csname _\_csstring#9op\_endcsname=1 \_mafam #9\_relax + \_else + \_Umathcode "#4#5#6#7#8=\_numexpr"#3/2\_relax \_mafam "#4#5#6#7#8 + \_fi +} +\_def\_mathcharsD #1{\_mathcharsC #1\_relax \_Udelcode #1=\_mafam #1\_relax} + + \_doc ----------------------------- + \`\mathcodes` `<fam> {<list of pairs>}` sets mathcodes of given + characters with explicit <class>es. Each pair can be `<class>{<list of chars>}` + and `<list of chars>` can include \`\Urange` `<from>-<to>`. + This is reason why we apply `\expanded` to the `<list of chars>` + before reading it by \^`\foreach`: the \^`\Urange` is expandable + and expands to the relevant list of characters. + \_cod ----------------------------- + +\_def\_mathcodes{\_afterassignment\_mathcodesA\_chardef\_mafam=} +\_def\_mathcodesA#1{% + \_foreach #1\_do ##1##2{% + \_ea\_foreach\_expanded{##2}\_do{\_Umathcode `####1=##1\_mafam`####1}% + }% +} +\_def\_Urange #1-#2{\_fornum `#1..`#2\_do{\_Uchar##1 }} + +\_public \addUmathfont \mathchars \mathcodes \Urange ; \_endcode @@ -286,31 +318,55 @@ Example: \addUmathfont \xits {[XITSMath-Regular]}{} {[XITSMath-Bold]}{} {} \endtt % -declares `latinmodern-math` as main math font (its bold variant is \"faked bold") -and the additional math font `\xits` is `XITSMath-Regular` for normal -printing and `XITSMath-Bold` for bold printing. +declares `latinmodern-math` as main math font (its bold variant is \"faked bold"). +The additional math font family `\xits` is declared in the example. It uses +`XITSMath-Regular` for normal printing and `XITSMath-Bold` for bold printing. -All characters used in math formula is printed from main math font by -default. But you can redeclare a list of characters for printing from -additional font by \^`\resetmathchars` `\famname <list of sequences> ;`. For +All characters used in math formula are printed from main math font by +default. But you can re-declare characters for printing from +additional font by \^`\mathchars` `\famname {<list of sequences>}`. For example: \begtt -\resetmathchars \xits \stareq \triangleq \veeeq \wedgeq ; +\mathchars \xits {\stareq \triangleq \veeeq \wedgeq} \endtt % sets the characters `\stareq`, `\triangleq`, `\veeeq`, `\wedgeq` from -the `\xits` additional font. You can see all possible sequences by -`\input print-unimath.opm`. -If you want to use whole math alphabet from additional math font, use -`\addto\selector{\fam\famname}`, for example `\addto\cal{\fam\xits}` +the `\xits` additional font. The <list of sequences> can include +control sequences from the `unicode-table.tex`, but no math +accents. These contol sequences can be printed by `\input print-unimath.opm`. + +The \^`\mathchars` macro keeps the class and slot of declared math objects +and re-declares only family of them. It is applied to all control +sequences given in the parameter. The relevant math codes are re-declared. + +Use `\addto\selector{\fam\famname}` if you want to print whole math alphabet +from an additional math font. For example `\addto\cal{\fam\xits}` declares all `\cal` characters from the `\xits` font loaded by \^`\addUmathfont`. +The \^`\mathcodes` macro provides comfortable settings of math codes of math +objects. Its syntax is \^`\mathcodes` `<family> {<list-of-pairs>}`. Each pair +in the <list-of-pairs> is `<class-number><character>` (separated by optional +space) or `<class-number>{<list-of-characters>}`. The <list-of-characters> +includes declared characters or \^`\Urange` `<from>-<to>` which is equal to the +list of characters beginning <from> and ending <to>, for example +`\Urange a-d` is equal to `abcd`. + +The \^`\mathcodes` macro declares mathcode of given characters internally by +\begtt \catcode`<=13 +\Umathcode `<character> = <class-number> <family> `<character> +\endtt + +The \^`\mathcodes` macro sets math codes of given Unicode characters. +The relevant control sequence from `unicode-table.tex` changes its +behavior too. For example, If you change math code of × then the +`\times` control sequence will behave like new declared ×. + \secc Unicode-math macros preloaded in the format -\printdoc math-unicode.opm +\printdoc unimath-macros.opm \secc[unimath-codes] Macros and codes set when `\loadmath` is processed firstly @@ -329,6 +385,11 @@ the section~\ref[math-macros]. \_endinput +2022-12-01 reading number by \_loadumathfamily more robust +2022-11-18 \mathchars improved, \Udelcodes are set too, \addUmathfont uses \ahead +2022-11-17 \Umathchardef replaced by \chardef +2022-11-16 \resetmathchars removed, \mathchars, \mathcodes introduced +2022-11-13 \_setfontfamily 0 added. 2022-07-22 \Umathspaceafterscript setting added. 2022-06-10 \addUmathfont and \resetmathchars added. 2021-08-16 \_loadumathfamily simplified, used mathsize= font feature. diff --git a/macros/optex/base/verbatim.opm b/macros/optex/base/verbatim.opm index 201dc66fd9..ac00369d33 100644 --- a/macros/optex/base/verbatim.opm +++ b/macros/optex/base/verbatim.opm @@ -138,7 +138,7 @@ } \_ea\_def\_ea\_startverb \_ea#\_ea1\_csstring\\endtt#2^^J{% \_prepareverbdata\_tmpb{#1^^J}% - \_ea\_printverb \_tmpb\_end + \_ea\_printverb \_tmpb\_fin \_par \_restoremathsb \_endgroup \_ttskip \_isnextchar\_par{}{\_noindent}% @@ -172,10 +172,10 @@ \_ifx\_printverblinenum\_relax \_else \_incr\_ttline \_fi \_testcommentchars #1\_relax\_relax\_relax \_iftrue - \_ifx\_end#2\_printcomments\_fi + \_ifx\_fin#2\_printcomments\_fi \_else \_ifx\_vcomments\_empty\_else \_printcomments \_def\_vcomments{}\_fi - \_ifx\_end#2% + \_ifx\_fin#2% \_bgroup \_adef{ }{}\_def\t{}% if the last line is emtpy, we don't print it \_ifcat&\_egroup \_ifx\_printverblinenum\_relax \_else \_decr\_ttline \_fi \_else\_egroup \_printverbline{#1}\_fi @@ -183,7 +183,7 @@ \_printverbline{#1}% \_fi \_fi - \_unless\_ifx\_end#2\_afterfi{\_printverb#2}\_fi + \_unless\_ifx\_fin#2\_afterfi{\_printverb#2}\_fi } \_def\_printverbline#1{\_putttpenalty \_indent \_printverblinenum \_kern\_ttshift #1\_par} \_def\_initverblinenum{\_tenrm \_thefontscale[700]\_ea\_let\_ea\_sevenrm\_the\_font} @@ -274,7 +274,7 @@ \_repeat \_ea\_prepareverbdata \_ea \_tmpb\_ea{\_tmpb^^J}% \_catcode`\ =10 \_catcode`\%=9 % used in \commentchars comments - \_ea\_printverb \_tmpb\_end + \_ea\_printverb \_tmpb\_fin \_ttlinesave \_par \_restoremathsb \_endgroup |