diff options
Diffstat (limited to 'Master/texmf-dist/tex/optex')
22 files changed, 670 insertions, 80 deletions
diff --git a/Master/texmf-dist/tex/optex/base/basic-macros.opm b/Master/texmf-dist/tex/optex/base/basic-macros.opm index f2047cadf0f..7dfda46a764 100644 --- a/Master/texmf-dist/tex/optex/base/basic-macros.opm +++ b/Master/texmf-dist/tex/optex/base/basic-macros.opm @@ -117,10 +117,11 @@ more logging information to the log file and the terminal. \_cod ------------------------------ -\_def\_loggingall{\_tracingcommands=3 \_tracingstats=2 \_tracingpages=1 +\_def\_loggingall{ + \_tracingstats=2 \_tracingpages=1 \_tracingoutput=1 \_tracingmacros=3 % \_tracinglostchars=2 is already set - \_tracingparagraphs=1 \_tracingrestores=1 \_tracingscantokens=1 - \_tracingifs=1 \_tracinggroups=1 \_tracingassigns=1 } + \_tracingparagraphs=1 \_tracingscantokens=1 \_tracingifs=1 \_tracinggroups=1 + \_tracingcommands=3 \_tracingrestores=1 \_tracingassigns=1 } \_def\_tracingall{\_tracingonline=1 \_loggingall} \_public \loggingall \tracingall ; diff --git a/Master/texmf-dist/tex/optex/base/fonts-opmac.opm b/Master/texmf-dist/tex/optex/base/fonts-opmac.opm index ca4d38b4ce1..646a0257b9d 100644 --- a/Master/texmf-dist/tex/optex/base/fonts-opmac.opm +++ b/Master/texmf-dist/tex/optex/base/fonts-opmac.opm @@ -212,7 +212,7 @@ \_def \_rmfixed {% used in default \footline {\_ifdim\_mainfosize=0pt \_mainfosize=10pt \_fi \_fontdef\_tenrm{\_setfontsize{at\mainfosize}\_resetmod\_rm}% - \_global\_let\_rmfixed=\_tenrm}% next use will be font switch only + \_glet\_rmfixed=\_tenrm}% next use will be font switch only \_rmfixed } \_let \rmfixed = \_tenrm % user can redefine it diff --git a/Master/texmf-dist/tex/optex/base/hi-syntax.opm b/Master/texmf-dist/tex/optex/base/hi-syntax.opm index 7e5b77b8264..2f477c8f319 100644 --- a/Master/texmf-dist/tex/optex/base/hi-syntax.opm +++ b/Master/texmf-dist/tex/optex/base/hi-syntax.opm @@ -144,7 +144,7 @@ file name must include it in lowercase letters. For example, the file \printdoc hisyntax-c.opm -\OpTeX/ provides `hisyntax-{c,lua,python,tex,html}.opm` files. +\OpTeX/ provides `hisyntax-{c,lua,python,tex,html,kt}.opm` files. You can take inspiration from these files and declare more languages. Users can re-declare default colors by \^`\hicolors``={<list of color declarations>}`. diff --git a/Master/texmf-dist/tex/optex/base/hisytnax-kt.opm b/Master/texmf-dist/tex/optex/base/hisytnax-kt.opm new file mode 100644 index 00000000000..8a9d2dffac3 --- /dev/null +++ b/Master/texmf-dist/tex/optex/base/hisytnax-kt.opm @@ -0,0 +1,122 @@ +%% This is part of the OpTeX project, see http://petr.olsak.net/optex +%% Author: Vojtěch Hořánek, <https://github.com/vojta-horanek/hisyntax-kt> + +\_codedecl \_hisyntaxkt {Syntax highlighting for Kotlin sources <2024-05-18>} + +\_newtoks \_hisyntaxkt \_newtoks \_hicolorskt + +\_global\_hicolorskt={ % colors for Kotlin language + \_hicolor C \Grey % Comments + \_hicolor D \Green % Documentation comments + \_hicolor W \Yellow % Warnings + \_hicolor S \Green % Strings + \_hicolor K \Blue % Keywords + \_hicolor F \Blue % Std. functions + \_hicolor A \Yellow % Annotations + \_hicolor N \Cyan % Numbers + \_hicolor T \Brown % Templates + \_hicolor I \Grey % Imports + \_hicolor O \Magenta % Others +} + +\_global\_hisyntaxkt={% + \_the\_hicolorskt + \_let\c=\_relax \_let\e=\_relax \_let\o=\_relax + % comments + \_replthis {FIXME} {\z W{FIXME}}% FIXME in comment + \_replthis {TODO} {\z W{TODO}}% TODO in comment + \_replfromto {/**}{*/} {\x D{/**#1*/}}% /**...*/ documentation + \_replfromto {/*}{*/} {\x C{/*#1*/}}% /*...*/ multi-line + \_replfromto {//}{^^J} {\z C{//#1}^^J}% //... single-line + % strings + \_replfromto {\_csstring\$\_csstring\{}{\_csstring\}}% string template expression ${tmp} + {\z T{\_csstring\$\_csstring\{#1\_csstring\}}}% + \_replfromto {\_csstring\$}{\n} {\x T{\_csstring\$#1}}% string template $tmp + \_replthis {\_string\"} {{\_string\"}}% \" string escape + \_replfromto {"}{"} {\x S{"#1"}}% "..." string + % characters + \_replthis {\_string\'} {{\_string\'}}% \' char escape + \_replfromto {'}{'} {\x S{'#1'}}% '.' character + % others + \_replfromto {\n@}{\n} {\z A{@#1}}% annotations + \_replfromto {package}{^^J} {\z K{package}\z I{#1}^^J}% package... + \_replfromto {import}{^^J} {\z K{import}\z I{#1}^^J}% import... + \_replfromto {return@}{\n} {\z K{return}\z O{@#1}}% return@... + \_replfromto {continue@}{\n} {\z K{continue}\z O{@#1}}% continue@... + \_replfromto {break@}{\n} {\z K{break}\z O{@#1}}% break@... + % Special characters + \_replthis{;}{\z C{;}} % semi-collon + \_replthis{?:}{\n\o?:\n} % elvis operator + \_edef\_tmpa {()\_string{\_string}+-*/=[]<>,:\_pcent\_string&|!}% non-letters + \_ea \_foreach \_tmpa + \_do {\_replthis{#1}{\n\o#1\n}} + % + \_foreach % keywords + {as}{as?}{break}{class}{continue}{do}{else}{false}{for}{fun}% + {if}{in}{!in}{interface}{is}{!is}{null}{object}{package}% + {return}{super}{this}{throw}{true}{try}{typealias}{typeof}% + {val}{var}{when}{while}{by}{catch}{constructor}{dynamic}% + {finally}{get}{import}{init}{set}{value}{class}{where}% + {abstract}{actual}{annotation}{companion}{const}{crossinline}% + {data}{enum}{expect}{external}{final}{infix}{inline}{inner}% + {internal}{lateinit}{noinline}{open}{operator}{out}{override}% + {private}{protected}{public}{reified}{sealed}{suspend}{tailrec}% + {vararg}{it}{equals}{compareTo}{get()}{get}{set}{set(value)}% + \_do {\_replthis{\n#1\n}{\z K{#1}}} + % + \_foreach % standard library extension functions + {all}{also}{any}{apply}{asIterable}{asSequence}{associate}% + {associateBy}{associateByTo}{associateTo}{associateWith}% + {associateWithTo}{average}{chunked}{contains}{count}{distinct}% + {distinctBy}{drop}{dropLast}{dropLastWhile}{dropWhile}{elementAt}% + {elementAtOrElse}{elementAtOrNull}{filter}{filterIndexed}% + {filterIndexedTo}{filterIsInstance}{filterIsInstanceTo}{filterNot}% + {filterNotNull}{filterNotNullTo}{filterNotTo}{filterTo}{find}% + {findLast}{first}{firstNotNullOf}{firstNotNullOfOrNull}% + {firstOrNull}{flatMap}{flatMapIndexed}{flatMapIndexedTo}% + {flatMapTo}{fold}{foldIndexed}{foldRight}{foldRightIndexed}% + {forEach}{forEachIndexed}{getOrElse}{getOrNull}{groupBy}% + {groupByTo}{groupingBy}{indexOf}{indexOfFirst}{indexOfLast}% + {intersect}{iterator}{joinTo}{joinToString}{last}{lastIndexOf}% + {lastOrNull}{let}{map}{mapIndexed}{mapIndexedNotNull}% + {mapIndexedNotNullTo}{mapIndexedTo}{mapNotNull}{mapNotNullTo}% + {mapTo}{max}{maxBy}{maxByOrNull}{maxOf}{maxOfOrNull}{maxOfWith}% + {maxOfWithOrNull}{maxOrNull}{maxWith}{maxWithOrNull}{min}{minBy}% + {minByOrNull}{minOf}{minOfOrNull}{minOfWith}{minOfWithOrNull}% + {minOrNull}{minus}{minusElement}{minWith}{minWithOrNull}{none}% + {onEach}{onEachIndexed}{partition}{plus}{plusElement}{random}% + {randomOrNull}{reduce}{reduceIndexed}{reduceIndexedOrNull}% + {reduceOrNull}{reduceRight}{reduceRightIndexed}% + {reduceRightIndexedOrNull}{reduceRightOrNull}{repeat}% + {requireNoNulls}{reverse}{reversed}{runningFold}% + {runningFoldIndexed}{runningReduce}{runningReduceIndexed}{scan}% + {scanIndexed}{shuffle}{single}{singleOrNull}{slice}{sortBy}% + {sortByDescending}{sortDescending}{sorted}{sortedBy}% + {sortedByDescending}{sortedDescending}{sortedWith}{subtract}{sum}% + {sumBy}{sumByDouble}{sumOf}{take}{takeIf}{takeLast}% + {takeLastWhile}{takeUnless}{takeWhile}{toBooleanArray}% + {toByteArray}{toCharArray}{toCollection}{toDoubleArray}% + {toFloatArray}{toHashSet}{toIntArray}{toList}{toLongArray}% + {toMutableList}{toMutableSet}{toSet}{toShortArray}{union}% + {windowed}{withIndex}{zip}{zipWithNext}{contract}% + \_do {\_replthis{.#1\n}{.\z F{#1}}% + \_replthis{\n#1\n}{\z F{#1}}}% invoke operators ( and { begin with \n + % + \_replthis{.}{\n.\n} % numbers + \_foreach 0123456789 + \_do {\_replfromto{\n#1}{\n}{\c#1##1\e}} + \_replthis{\e.\c}{.} + \_replthis{\e.\n}{.\e} + \_replthis{\n.\c}{\c.} + \_replthis{e\e\o+\c}{e+}\_replthis{e\e\o-\c}{e-} + \_replthis{E\e\o+\c}{E+}\_replthis{E\e\o-\c}{E-} + \_def\c#1\e{\z N{#1}} + \_def\o#1{\z O{#1}} % others +} + +\_endcode %------------------------------------------------ + + +\endinput + +2024-05-18: First version diff --git a/Master/texmf-dist/tex/optex/base/if-macros.opm b/Master/texmf-dist/tex/optex/base/if-macros.opm index eae011ae260..25af86fe303 100644 --- a/Master/texmf-dist/tex/optex/base/if-macros.opm +++ b/Master/texmf-dist/tex/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 <2023-12-07>} % preloaded in format +\_codedecl \newif {Special if-macros, is-macros and loops <2024-02-19>} % preloaded in format \_doc ---------------------------- \secc Classical \code{\\newif} @@ -189,7 +189,7 @@ \_public \foreachdef ; \_doc ---------------------------- - \secc Is-macros + \secc Is-macros and selection of cases There are a collection of macros \^`\isempty`, \^`\istoksempty`, \^`\isequal`, \^`\ismacro`, \^`\isdefined`, \^`\isinlist`, \^`\isfile` and \^`\isfont` @@ -339,14 +339,22 @@ \`\qcasesof` `{<string>} <list of cases>` behaves like \^`\casesof` but it compares phrases with the given <string> using \^`\isequal`. The <list of cases> includes pairs - `{<phrase>} {<what to do if string=phrase>}` finalized by a - pair `\_finc {<what to do else>}`. + `{<phrases>} {<what to do if string=phrase>}` finalized by a + pair `\_finc {<what to do else>}`. The `<phrases>` is a single + phrase or phrases separated by `|` which means \"or". For example + the pair `{ab|cde|f} {<code>}` runs <code> if the given <string> is `ab` or `cde` or~`f`. + The usage of `\qcasesof` can be found in + \ulink[http://petr.olsak.net/optex/optex-tricks.html\#thedimen]{OpTeX trick 0132}. \_cod ----------------------------- \_long\_def \_qcasesof #1#2#3{\_ifx\_finc#2\_ea\_ignoresecond \_else \_ea\_usesecond \_fi - {#3}{\_isequal{#1}{#2}\_iftrue \_ea\_ignoresecond \_else \_ea\_usesecond \_fi - {\_finc{#3}}{\_qcasesof{#1}}}% + {#3}{\_qcasesofA{#1}#2|\_qcasesofA|{\_finc{#3}}{\_qcasesof{#1}}}% } +\_long\_def\_qcasesofA#1#2|{\_ifx\_qcasesofA#2\_ea\_usesecond \_else + \_isequal{#1}{#2}\_iftrue \_qcasesofB \_fi \_afterfi{\_qcasesofA{#1}}\_fi +} +\_long\_def\_qcasesofB #1\_qcasesofA|#2#3{\_fi\_fi#2} + \_public \qcasesof ; \_doc ----------------------------- @@ -376,7 +384,8 @@ \_endcode -2023-12-07 \_testparam define \long (big fixed) +2024-02-19 \qcasesof reimplemented, it supports | for more phrases. +2023-12-07 \_testparam define \long (big fixed). 2023-10-17 \qcasesof introduced, \xcasesof reimplemented. 2023-01-16 \isnextchar created expandable. 2022-12-02 \xcasesof: its first parameter is \long too. diff --git a/Master/texmf-dist/tex/optex/base/luatex-ini.opm b/Master/texmf-dist/tex/optex/base/luatex-ini.opm index 1deeca2b807..8c7723d7121 100644 --- a/Master/texmf-dist/tex/optex/base/luatex-ini.opm +++ b/Master/texmf-dist/tex/optex/base/luatex-ini.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \pdfprimitive {LuaTeX initialization code <2020-02-21>} % preloaded in format +\_codedecl \pdfprimitive {LuaTeX initialization code <2024-02-29>} % preloaded in format \_let\_pdfpagewidth \pagewidth \_let\_pdfpageheight \pageheight @@ -79,6 +79,8 @@ \_protected\_def \_pdfmapline {\_pdfextension mapline } \_protected\_def \_pdftrailer {\_pdfextension trailer } \_protected\_def \_pdfglyphtounicode {\_pdfextension glyphtounicode } +\_protected\_def \_pdfrunninglinkoff {\_pdfextension linkstate 1 } +\_protected\_def \_pdfrunninglinkon {\_pdfextension linkstate 0 } \_protected\_edef\_pdfcompresslevel {\_pdfvariable compresslevel} \_protected\_edef\_pdfobjcompresslevel {\_pdfvariable objcompresslevel} @@ -115,7 +117,8 @@ \pdfsetmatrix \pdfsave \pdfrestore \pdfobj \pdfrefobj \pdfannot \pdfstartlink \pdfendlink \pdfoutline \pdfdest \pdfthread \pdfstartthread \pdfendthread \pdfinfo \pdfcatalog \pdfnames \pdfincludechars \pdffontattr - \pdfmapfile \pdfmapline \pdftrailer \pdfglyphtounicode \pdfcompresslevel + \pdfmapfile \pdfmapline \pdftrailer \pdfglyphtounicode + \pdfcompresslevel \pdfrunninglinkoff \pdfrunninglinkon \pdfobjcompresslevel \pdfdecimaldigits \pdfgamma \pdfimageresolution \pdfimageapplygamma \pdfimagegamma \pdfimagehicolor \pdfimageaddfilename \pdfpkresolution \pdfinclusioncopyfonts \pdfinclusionerrorlevel @@ -132,3 +135,8 @@ \_endcode Common pdf\TeX/ primitives equivalents are declared here. Initial values are set. + +\_endinput + +2024-02-29 \pdfrunninglinkoff \pdfrunninglinkon added +2020-02-21 released diff --git a/Master/texmf-dist/tex/optex/base/margins.opm b/Master/texmf-dist/tex/optex/base/margins.opm index c77926f9ad1..c7751ccb064 100644 --- a/Master/texmf-dist/tex/optex/base/margins.opm +++ b/Master/texmf-dist/tex/optex/base/margins.opm @@ -105,7 +105,7 @@ The `\_numprint` is `\_useit` by default (i.e.\ do nothing special) because we have left-to-right mode as default. But a user can define \begtt - \_def\_numprint#1{{\textdir TLT #1}} + \_def\_numprint#1{{\_textdir TLT #1}} \endtt if the document is set to right-to-left mode. \_cod ----------------------------- diff --git a/Master/texmf-dist/tex/optex/base/math-macros.opm b/Master/texmf-dist/tex/optex/base/math-macros.opm index fa4317f25ae..9d0887ee0fb 100644 --- a/Master/texmf-dist/tex/optex/base/math-macros.opm +++ b/Master/texmf-dist/tex/optex/base/math-macros.opm @@ -1,6 +1,6 @@ % This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \sin {Math macros plus mathchardefs <2023-05-24>} % preloaded in format +\_codedecl \sin {Math macros plus mathchardefs <2024-06-02>} % preloaded in format \_doc ----------------------------- The category code of the character `_` remains as the letter (11) and the mathcode @@ -33,18 +33,18 @@ \_newifi\_ifmathsb \_mathsbfalse \_def \_mathsbon {% - \_directlua{ + \_ifmathsb \_else \_directlua{ callback.add_to_callback("process_input_buffer", function (str) local num str, num = string.gsub(str.." ", \_gsubrule) if num>0 then str = string.gsub(str, \_gsubrule) end % \phi_i\rho_j -> \phi _i\rho _j return str - end, "_mathsb") }% + end, "_mathsb") }\_fi \_global\_mathsbtrue } \_def \_mathsboff {% - \_directlua{ callback.remove_from_callback("process_input_buffer", "_mathsb") }% + \_ifmathsb \_directlua{ callback.remove_from_callback("process_input_buffer", "_mathsb") }\_fi \_global \_mathsbfalse } \_edef\_gsubrule{"(\_nbb[a-zA-Z]+)_([a-zA-Z]?[^_a-zA-Z])", "\_pcent 1 _\_pcent 2"} @@ -707,7 +707,7 @@ impossible to use `\eqno` or `\leqno` or \^`\eqmark`. \OpTeX/ offers - `\dislaylines to<dimen>{<formula>\cr<formula>\cr...<formula>}` + `\displaylines to<dimen>{<formula>\cr<formula>\cr...<formula>}` as an alternative case of usage `\displaylines`. See section 4.3 in the \ulink[http://petr.olsak.net/ftp/olsak/optex/optex-math.pdf] {Typesetting Math with \OpTeX/}. @@ -1110,6 +1110,7 @@ \_endcode %--------------------------------------------------- +2024-06-02 don't apply \mathsbon twice 2023-05-24 \matsbon: "local num" added 2023-05-22 \mathsbon: \alpha_i\beta_j -> \alpha _i\beta _j (bug fixed) 2023-04-15 \bbig introduced diff --git a/Master/texmf-dist/tex/optex/base/more-macros.opm b/Master/texmf-dist/tex/optex/base/more-macros.opm index 3f4916a9c3d..7e1d1e2b94a 100644 --- a/Master/texmf-dist/tex/optex/base/more-macros.opm +++ b/Master/texmf-dist/tex/optex/base/more-macros.opm @@ -216,13 +216,19 @@ \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 + + There exists another limitation of the \^`\replstring` macro, see + \ulink[http://petr.olsak.net/optex/optex-tricks.html\#xreplstring]{\OpTeX/ trick 0136}. + The expandable \^`\xreplstring` macro is defined by Lua code here. + And \ulink[http://petr.olsak.net/optex/optex-tricks.html\#replmacro]{\OpTeX/ trick 0137} + defines \^`\replmacro` which enables more general modifications of macros by regular expressions. \_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 \_tmptoks\_ea{\_the\_tmptoks#3##1}% + \_long\_def\_replacestringsB##1#2{\_ifx!##1\_relax \_else \_toksapp\_tmptoks{#3##1}% \_ea\_replacestringsB\_fi}% \_ea\_replacestringsA #1?#2!#2% \_long\_def\_replacestringsA##1?{\_tmptoks{##1}\_edef#1{\_the\_tmptoks}}% @@ -294,8 +300,9 @@ by optional syntax `\bp[<digits>]{<dimen>}` and `\expr[<digits>]{<expression>}`. Default is \`\_decdigits`. - The usage of prefixed versions \`\_expr` or \`\_bp` is more recommended - because a user can re-define the control sequences `\expr` or `\bp`. + The usage of prefixed versions `\_expr` or `\_bp` is more recommended + for macro programmers because a user can re-define the control sequences + `\expr` or `\bp`. \_cod ----------------------------- \_def\_decdigits{3} % digits after decimal point in \_bp and \_expr outputs. diff --git a/Master/texmf-dist/tex/optex/base/optex-tricks.opm b/Master/texmf-dist/tex/optex/base/optex-tricks.opm index 456a7472e1c..c90b429a4fc 100644 --- a/Master/texmf-dist/tex/optex/base/optex-tricks.opm +++ b/Master/texmf-dist/tex/optex/base/optex-tricks.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \_undefined {OpTeX tricks ready to autoload <2024-02-13>} % chunks loaded on demand +\_codedecl \_undefined {OpTeX tricks ready to autoload <2024-05-07>} % chunks loaded on demand % Selected OpTeX tricks are here, they are auto-loaded if the macro is used first % namespace: optextrick @@ -59,6 +59,25 @@ \_nspublic \hours \minutes \seconds \weekday \Othe ; +\_trick 0132 \thedimen ; +%%%%%%%%%%%% + +\_sdef {_thedimen:pt}{1} +\_sdef {_thedimen:cm}{28.4527559} +\_sdef {_thedimen:mm}{2.84527559} +\_sdef {_thedimen:in}{72.27} +\_sdef {_thedimen:sp}{(1/65536)} +\_sdef {_thedimen:pc}{12} +\_sdef {_thedimen:bp}{1.00375} +\_sdef {_thedimen:dd}{1.070008643} +\_sdef {_thedimen:cc}{12.8401037} +\_sdef {_thedimen:em}{(\number\fontdimen6\font/65536)} +\_sdef {_thedimen:ex}{(\number\fontdimen5\font/65536)} + +\_def\thedimen #1#2#3{\_nnum{\_expr[5]{% + \_number\_dimexpr#1\_relax / 65536 / \_trycs{_thedimen:#2#3}{5000000000}}}#2#3} + + \_trick 0063 \showpglists ; %%%%%%%%%%%% @@ -81,6 +100,52 @@ \_fi } +\_trick 0133 \shownodes ; +%%%%%%%%%%%% + +\_def\shownodes#1{% + \_ifcat\_noexpand#1\_relax \_def\.tmp{#1}\_tmpnum=#1\_ea\.shownodesA + \_else \_def\.tmp{}\_afterfi{\_afterassignment\.shownodesA \_tmpnum=#1}\_fi +} +\_def\.shownodesA{% + \_wterm{==== Box \_the\_tmpnum\_space (\_ea\_string\.tmp):}% + \_directlua{ + local nodetree = require("nodetree") + nodetree.print(tex.box[\_the\_tmpnum]) +}} + + +\_trick 0134 \rebox \leftfill \rightfill \lrfill ; +%%%%%%%%%%%% + +\_def\rebox{\_directlua{ + local nod = tex.box[token.scan_int()] % read head node of the given box + if not(nod==nil) and nod.id==1 then % given box must be \vbox + for n in node.traverse(nod.head) do + if n.id==0 then % i.e. hlist (\hbox) + local nn = node.hpack (n.head) % calculate its natural width + n.width = nn.width % save natural width + nn.head = nil node.free (nn) % remove created box node + end + end + local nn = node.vpack (nod.head) % calculate main vlist (\vbox) width + nod.width = nn.width % save this width to nod.width + nn.head = nil node.free (nn) % remove created box node + for n in node.traverse(nod.head) do + if n.id==0 then + local nn = node.hpack (n.head, nod.width, "exactly") % \hbox to nod.width + n.width = nn.width % save changed hlist (\hbox) parameters + n.glue_order = nn.glue_order n.glue_set = nn.glue_set n.glue_sign = nn.glue_sign + nn.head = nil node.free (nn) % remove created box node + end + end + end +}} +\_def\leftfill {\_leftskip=0pt plus1fill \_parindent=0pt } +\_def\rightfill{\_rightskip=0pt plus1fill \_parindent=0pt } +\_def\lrfill{\_leftskip=0pt plus1fill \_rightskip=\_leftskip \_parindent=0pt } + + \_trick 0101 \runsystem ; %%%%%%%%%%%% @@ -94,8 +159,8 @@ \_nspublic \exitstatus ; -\_trick 105 \directoutput ; -%%%%%%%%%%% +\_trick 0105 \directoutput ; +%%%%%%%%%%%% \_newbox\.outbox \_def\directoutput{\_begingroup \_afterassignment\.directoutputA \_setbox\.outbox=} @@ -109,6 +174,107 @@ \_endgroup } +\_trick 0135 \directchar ; +%%%%%%%%%%%% + +\_protected\_def\directchar{\_ifmmode \_ea\_Uchar\_else \_quitvmode \_ea\.directcharA\_fi} +\_def\.directcharA{\_directlua{ + local n = node.new(29, 256) + n.font = font.current() + n.char = token.scan_int() + node.write(n) +}} + +\_trick 0137 \replmacro ; +%%%%%%%%%%%% + +\_def\replmacro #1{\_ea\.replmacroA\_ea#1\_meaning#1\_relax} +\_def\.replmacroA #1#2:#3->#4\_relax#5#6#7#8{% + {\_let\\=\_nbb \_edef\"{\_string\"}% + \_xargs\.replmacroB \{\}\$\&\#\^\~;\_ea + }\_ea\.replmacroC\_ea#1\_directlua{ + local prefixes="\_luaescapestring{#2}" + local params="\_luaescapestring{#3}" + local body="\_luaescapestring{#4}" + prefixes = string.gsub(prefixes,"macro","") + \_ifx;#5;\_else prefixes = string.gsub(prefixes,#5)\_fi + \_ifx;#6;\_else params = string.gsub(params,#6)\_fi + \_ifx;#7;\_else body = string.gsub(body,#7)\_fi + \_ifx;#8;\_else body = string.gsub(body,#8)\_fi + tex.sprint("{"..prefixes.."}{"..params.."}{"..body.."}") + }% +} +\_def\.replmacroB #1{\_edef#1{\_csstring#1}} +\_def\.replmacroC #1#2#3#4{\_useit#2\_def#1#3{#4}} + + +\_trick 0136 \xreplstring ; +%%%%%%%%%%%% + +\_directlua{% +local scan_toks = token.scan_toks +local put_next = token.put_next +local create = token.create +local lbrace = create(string.byte('{')) +local rbrace = create(string.byte('}')) +define_lua_command('xreplstring', function() + local macro_name = create(token.scan_csname()) + put_next(create'_expandafter', + lbrace,macro_name,rbrace) + local macro_body = scan_toks(false,false) + local nested = token.scan_keyword('nested') + local find = scan_toks(false,false) + local replace = scan_toks(false,false) + local find_length = \_csstring\#find + local replace_length = \_csstring\#replace + local range = \_csstring\#macro_body - find_length + 1 + local i = 1 + local nested_level = 0 + while i <= range do + if not nested then + if macro_body[i].tok == lbrace.tok then + nested_level = nested_level + 1 + elseif macro_body[i].tok == rbrace.tok then + nested_level = nested_level - 1 + end + end + if nested_level > 0 then i = i+1 else + for j = 0, find_length - 1 do + if not nested then + if macro_body[i + j].tok == lbrace.tok then + nested_level = nested_level + 1 + i = i+j+1 + break + end + end + if (macro_body[i + j].tok \_csstring\~= find[j+1].tok) then + i = i+1 + break + else + if j == find_length - 1 then + for t = 0, find_length - 1 do + table.remove(macro_body,i) + end + for t = 0, replace_length - 1 do + table.insert(macro_body,i+t,replace[t+1]) + end + range = \_csstring\#macro_body - find_length + 1 + i = i+replace_length + break + end + end + end + end + end + put_next(rbrace) + put_next(macro_body) + put_next(create'_def',macro_name,lbrace) + if macro_name.protected then + put_next(create'_protected') + end +end,'global') % we want to keep the meanig after group +} + \_trick 0078 \algol ; %%%%%%%%%%%% @@ -175,6 +341,22 @@ } \_def\ignoreinspic{\_let\_inspicB=\.inspicBnew} +\_trick 0040 \tdnum ; +%%%%%%%%%%%% + +\_def\tdnum #1 {\_isinlist{#1}{.}\_iftrue \_ea\.tdnumG \_else \_ea\.tdnumH \_fi #1\_end} +\_def\.tdnumG #1.#2\_end {\.tdnumH#1\_end \.decdot \.tdnumB #2\_empty\_empty\_empty} +\_def\.tdnumH#1\_end{\.tdnumA #1\_empty\_empty\_empty #1\_empty} +\_def\.tdnumA #1#2#3{\_xcasesof + {\_ifx #1\_empty} {\.tdnumB} + {\_ifx #2\_empty} {\.tdnumB{}} + {\_ifx #3\_empty} {\_ea\.tdnumB\_ignoreit} + \_finc {\.tdnumA} +} +\_def\.tdnumB #1#2#3#4{#1#2#3\_ifx#4\_empty\_else \.numsep \_ea\.tdnumB\_ea#4\_fi} +\_def\.numsep{\,} +\_def\.decdot{.} + \_trick 0047 \style m \keepstyle ; %%%%%%%%%%%% @@ -755,17 +937,17 @@ \_trick 0130 \onlyifnew ; %%%%%%%%%%%% -\_def \onlyifnew#1#2{\_begingroup% +\_def \onlyifnew#1#2{\_begingroup \_edef\.tmpA{\_csstring #2}% \_edef\.tmpB{\_string #2}% - \_ea\_ifcsname\.tmpA\_endcsname% + \_ea\_ifcsname\.tmpA\_endcsname \_ifx\.tmpA\.tmpB% #2 has no backslash - \_def\.onlyifnewA{#1{_optextrick_onlyifnewB}}\_else% - \_def\.onlyifnewA{#1\_optextrick_onlyifnewB}\_fi% - \_else% - \_ifx\.tmpA\.tmpB% - \_def\.onlyifnewA{#1{#2}}\_else% - \_def\.onlyifnewA{#1#2}\_fi% + \_def\.onlyifnewA{#1{_optextrick_onlyifnewB}}\_else + \_def\.onlyifnewA{#1\_optextrick_onlyifnewB}\_fi + \_else + \_ifx\.tmpA\.tmpB + \_def\.onlyifnewA{#1{#2}}\_else + \_def\.onlyifnewA{#1#2}\_fi \_fi\_ea\_endgroup\.onlyifnewA} %%%%%%%%%%%% @@ -773,6 +955,12 @@ \_endcode +2024-05-07 \replmacro added +2024-05-02 \xreplstring added +2024-04-15 \directchar added +2024-03-21 \rebox added +2024-03-19 \shownodes added +2024-03-09 \thedimen added 2024-02-13 \onlyifnew added 2024-02-12 \pgforeground added 2023-11-15 \correctvsize added diff --git a/Master/texmf-dist/tex/optex/base/optex.ini b/Master/texmf-dist/tex/optex/base/optex.ini index a659f43dc8b..0c037d6f4c6 100644 --- a/Master/texmf-dist/tex/optex/base/optex.ini +++ b/Master/texmf-dist/tex/optex/base/optex.ini @@ -21,7 +21,7 @@ % OpTeX version -\def\optexversion{1.14 Feb 2024} +\def\optexversion{1.15 Jun 2024} \def\fmtname{OpTeX} \let\fmtversion=\optexversion diff --git a/Master/texmf-dist/tex/optex/base/optex.lua b/Master/texmf-dist/tex/optex/base/optex.lua index c6ea56d7946..71834a56aa9 100644 --- a/Master/texmf-dist/tex/optex/base/optex.lua +++ b/Master/texmf-dist/tex/optex/base/optex.lua @@ -12,7 +12,8 @@ local optex = _ENV.optex or {} _ENV.optex = optex -- Error function used by following functions for critical errors. -local function err(message) +local function err(...) + local message = fmt(...) error("\nerror: "..message.."\n") end -- @@ -192,11 +193,11 @@ local valid_callback_types = { -- `call_callback`. A default function is only needed by "exclusive" callbacks. function callback.create_callback(name, cbtype, default) if callback_types[name] then - err("cannot create callback '"..name.."' - it already exists") + err("cannot create callback '%s' - it already exists", name) elseif not valid_callback_types[cbtype] then - err("cannot create callback '"..name.. "' with invalid callback type '"..cbtype.."'") + err("cannot create callback '%s' with invalid callback type '%s'", name, cbtype) elseif ctype == "exclusive" and not default then - err("unable to create exclusive callback '"..name.."', default function is required") + err("unable to create exclusive callback '%s', default function is required", name) end callback_types[name] = cbtype @@ -227,7 +228,21 @@ function callback.add_to_callback(name, fn, description) return call_callback(name, ...) end) else - err("cannot add to callback '"..name.."' - no such callback exists") + err("cannot add '%s' to callback '%s' - no such callback exists", description, name) + end + + if not description or description == "" then + err("missing description when adding a callback to '%s'", name) + end + + for _, desc in ipairs(callback_description[name] or {}) do + if desc == description then + err("for callback '%s' there already is '%s' added", name, description) + end + end + + if type(fn) ~= "function" then + err("expected Lua function to be added as '%s' for callback '%s'", description, name) end -- add function to callback list for this callback @@ -251,6 +266,10 @@ function callback.remove_from_callback(name, description) end end + if not index then + err("can't remove '%s' from callback '%s': not found", description, name) + end + table.remove(descriptions, index) local fn = table.remove(callback_functions[name], index) @@ -293,7 +312,7 @@ function callback.call_callback(name, ...) local functions = callback_functions[name] or {default_functions[name]} if cbtype == nil then - err("cannot call callback '"..name.."' - no such callback exists") + err("cannot call callback '%s' - no such callback exists", name) elseif cbtype == "exclusive" then -- only one function, atleast default function is guaranteed by -- create_callback @@ -483,7 +502,7 @@ callback.add_to_callback("finish_pdffile", function() local obj = resource_dict_objects[type] pdf.immediateobj(obj, tostring(dict)) end -end) +end, "_pageresources") -- -- \medskip\secc[lua-colors] Handling of colors and transparency using attributes^^M -- @@ -716,7 +735,16 @@ function optex.hook_into_luaotfload() end) end +-- \`\_beglocalcontrol` `<tokens>` `\_endlocalcontrol` runs `<tokens>` fully at +-- expand processor level despite the fact that `<tokens>` processes unexpandable commands. + +define_lua_command("_beglocalcontrol", function() + return tex.runtoks(token.get_next, true) +end) + -- History: + -- 2024-06-02 more checking in add_to_callback and remove_from_callback + -- 2024-02-18 \_beglocalcontrol 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 diff --git a/Master/texmf-dist/tex/optex/base/others.opm b/Master/texmf-dist/tex/optex/base/others.opm index 9b7e3a7ead8..b7ad0556fc4 100644 --- a/Master/texmf-dist/tex/optex/base/others.opm +++ b/Master/texmf-dist/tex/optex/base/others.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \uv {Miscenaleous <2023-12-23>} % preloaded in format +\_codedecl \uv {Miscenaleous <2024-06-27>} % preloaded in format \_doc ---------------------------- \`\useOpTeX` and \`\useoptex` are declared as `\relax`. @@ -94,9 +94,8 @@ First usage of `\lipsum` reads the \LaTeX/ file `lipsum.ltd.tex` by \`\_lipsumload` and prints the selected paragraph(s). Next usages of `\lipsum` - prints the selected paragraph(s) from memory. This second and more - usages of `\lipsum` are fully expandable. If you want to have all - printings of `\lipsum` expandable, use dummy `\lipsum[0]` first. + prints the selected paragraph(s) from memory. + `\lipsum` is fully expandable. `\lipsum` adds `\_par` after each printed paragraph. If you don't need such `\_par` here, use \`\lipsumtext``[<number>]` or `\lipsum[<number>.]` @@ -111,14 +110,15 @@ \_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{{% - \_setbox\_nonebox=\_vbox{\_tmpnum=0 % vertical mode during \input lipsum.ltd.tex +\_def\_lipsumload{\_beglocalcontrol + {\_setbox\_nonebox=\_vpack{\_tmpnum=0 % vertical mode during \input lipsum.ltd.tex \_def\ProvidesFile##1[##2]{}% \_def\SetLipsumLanguage##1{}% \_def\NewLipsumPar{\_incr\_tmpnum \_sxdef{_lip:\_the\_tmpnum}}% \_opinput {lipsum.ltd.tex}% - \_global\_let\_lipsumload=\_empty - }}} + \_glet\_lipsumload=\_empty + }}% + \_endlocalcontrol} \_def\_lipsumdot[#1]{\_lipsumload \_ea\_ea\_ea \_lipsumdotA \_csname _lip:#1\_endcsname.\_fin} \_def\_lipsumdotA #1.#2\_fin {#1} @@ -145,25 +145,29 @@ the `<cs-name>`. \_cod ----------------------------- -\_def\_regtrick#1{\_ifx#1\_undefined\_def#1{\_loadtrick#1#1}\_else\_badtrick\_fi} -\_def\_loadtrick#1{\_resetnamespace{optextrick}\_setctable\_optexcatcodes +\_def\_regtrick#1{\_ifx#1\_undefined\_def#1{\_loadtrickD#1}\_else\_badtrick\_fi} +\_def\_loadtrickD#1{\_loadtrick#1#1} +\_def\_loadtrick#1{\_beglocalcontrol + \_resetnamespace{optextrick}\_setctable\_optexcatcodes \_savecatcodetable\_tmpcatcodes \_catcodetable\_tmpcatcodes \_long\_def\_loadtrickA ##1\_trick##2#1##3;{##1}% \_wlog{Loading trick macros for \_string#1}% - \_setbox\_nonebox=\_vbox{\_globaldefs=1 \_ea\_loadtrickA \_input {optex-tricks.opm}}% + \_setbox\_nonebox=\_vpack{\_globaldefs=1 \_ea\_loadtrickA \_input {optex-tricks.opm}}% \_restorectable \_endnamespace + \_endlocalcontrol } \_def\_trick #1;{\_endinput} \_public \loadtrick ; \_xargs \_regtrick \begfile \createfile \beglua \begLUA \logginglua - \sethours \setminutes \setseconds \setweekday \showpglists \runsystem + \sethours \setminutes \setseconds \setweekday \showpglists \shownodes \runsystem \directoutput \algol \scaleto \scaletof \ttlineref \easylist \keepstyle \fcread \shadedframe \roundframe \cancel \ignoreinspic \keystroke \colortab \crx \crtop \crbot \crmid \longtable \vcent \vbot \tnote \tabnodes \tablebefore \framedblocks \twoblocks \pstart \settabs \import \incrpp \ispageodd \iniseccc \seccc \makeLOF \makeLOT \captionF \captionT \correctvsize \pgforeground - \onlyifnew ; + \onlyifnew \thedimen \rebox \leftfill \rightfill \lrfill \directchar + \xreplstring \replmacro \tdnum ; \_sdef{_item:m}{\_loadtrick{\style m}\_cs{_item:m}} \_doc ----------------------------- @@ -240,6 +244,10 @@ \_endcode +2024-06-27 \_loadtrickD introduced in order to save format size. +2024-03-11 \_lipsumload+\_loadtrick: \vpack used instead \vbox. +2024-03-04 \_beglocalcontrol used in \_lipsumload. +2024-02-18 \_beglocalcontrol used in \_loadtrik. 2023-12-23 \_nonebox instead box 0 introduced. 2023-10-17 \_loadtrick introduced. 2022-05-04 \lipsum[<num>]. changed to \lipsum[<num>.] to keep macro expandable. diff --git a/Master/texmf-dist/tex/optex/base/output.opm b/Master/texmf-dist/tex/optex/base/output.opm index 5e4765766d1..e5bca3157e2 100644 --- a/Master/texmf-dist/tex/optex/base/output.opm +++ b/Master/texmf-dist/tex/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 <2023-04-28>} % preloaded in format +\_codedecl \nopagenumbers {Output routine <2024-02-29>} % preloaded in format \_doc ----------------------------- \`\_optexoutput` is the default output routine. You can create another @@ -55,7 +55,7 @@ \_cod ----------------------------- \_newdimen \_xhsize \_xhsize=\_hsize -\_def\_setxhsize {\_global\_xhsize=\_hsize \_global\_let\_setxhsize=\_relax} +\_def\_setxhsize {\_global\_xhsize=\_hsize \_glet\_setxhsize=\_relax} \_doc ----------------------------- \`\gpageno` counts pages from one in the whole document @@ -78,7 +78,7 @@ \_resetattrs \_istoksempty \_pgbackground \_iffalse \_backgroundbox{\_the\_pgbackground}\_nointerlineskip \_fi - \_makeheadline + \_pdfrunninglinkoff \_makeheadline \_pdfrunninglinkon \_vbox to\_vsize {\_boxmaxdepth=\_maxdepth \_pagecontents}% \pagebody in plainTeX \_makefootline}% } @@ -116,8 +116,8 @@ \_ifvoid\_topins \_else \_unvbox\_topins\_fi \_dimen0=\_dp255 \_unvbox255 % open up \box255 \_ifvoid\_footins \_else % footnote info is present - \_vskip\_skip\_footins - \_footnoterule \_unvbox\_footins\_fi + \_pdfrunninglinkoff \_vskip\_skip\_footins + \_footnoterule \_unvbox\_footins \_pdfrunninglinkon \_fi \_kern-\_dimen0 \_vskip \_pgbottomskip } \_def \_pagedest {{\_def\_destheight{25pt}\_dest[pg:\_the\_gpageno]}} @@ -215,7 +215,7 @@ \_def \_draft {\_pgbackground={\_draftbox{\_draftfont DRAFT}}% \_fontdef\_draftfont{\_setfontsize{at10pt}\_bf}% - \_global\_let\_draftfont=\_draftfont + \_glet\_draftfont=\_draftfont } \_def \_draftbox #1{\_setbox0=\_hbox{\_setgreycolor{.8}#1}% \_kern.5\_vsize \_kern\_voffset \_kern4.5\_wd0 @@ -264,6 +264,7 @@ The output routine \^`\_optexoutput` is similar as in plain \TeX. It does: \_endinput +2024-02-29 \_pdfrunninglinkoff, \_pdfrunninglinkon used 2022-04-28 \_optexshipout introduced 2022-10-22 \_normalbaselines added to \makehead/foot/line 2022-03-07 \_resetattrs instead \_resetcolor diff --git a/Master/texmf-dist/tex/optex/base/parameters.opm b/Master/texmf-dist/tex/optex/base/parameters.opm index 05abe422757..c53508d3c1c 100644 --- a/Master/texmf-dist/tex/optex/base/parameters.opm +++ b/Master/texmf-dist/tex/optex/base/parameters.opm @@ -64,8 +64,10 @@ node will not be ignored. \_cod ----------------------------- +\_ifx\_matheqdirmode\_undefined \_else \_matheqdirmode=1 \_breakafterdirmode=1 +\_fi \_doc ----------------------------- \secc Plain \TeX/ registers @@ -629,7 +631,8 @@ a register then \OpTeX/ macros still work without change. \_endinput History: -2023-09-19 ... \matheqdirmode and \breakafterdirmode set (relevant when RTR typesetting) +2024-04-30 ... \matheqdirmode set only if it is defined (LuaTeX 1.15 and newer). +2023-09-19 ... \matheqdirmode and \breakafterdirmode set (relevant when RTL typesetting) 2021-04-13 ... \bibpart added 2021-04-07 ... \biboptions added, bug from iso690 fixed 2020-04-04 ... \tabspaces added diff --git a/Master/texmf-dist/tex/optex/base/plain-macros.opm b/Master/texmf-dist/tex/optex/base/plain-macros.opm index f3aa8c53347..a4fc792a929 100644 --- a/Master/texmf-dist/tex/optex/base/plain-macros.opm +++ b/Master/texmf-dist/tex/optex/base/plain-macros.opm @@ -54,9 +54,9 @@ % since this allows, for example, `\let\_par=\cr \obeylines \halign{...' {\_catcode`\^^M=13 % these lines must end with % \_gdef\_obeylines{\_catcode`\^^M=13\_let^^M\_par}% - \_global\_let^^M=\_par} % this is in case ^^M appears in a \write + \_glet^^M=\_par} % this is in case ^^M appears in a \write \_def\_obeyspaces{\_catcode`\ =13 } -{\_obeyspaces\_global\_let =\_space} +{\_obeyspaces\_glet =\_space} \_public \obeylines \obeyspaces ; \_doc ----------------------------- @@ -210,7 +210,7 @@ \_def\l{\_errmessage{\_usedirectly ł}} \_def\L{\_errmessage{\_usedirectly Ł}} %\def\_{\_ifmmode \kern.06em \vbox{\hrule width.3em}\else _\fi} % obsolete -\_def\_{\_hbox{_}} +\_protected\_def\_{\_relax \_ifmmode \_hbox{_}\_else _\_fi} \_def\dag{\_errmessage{\_usedirectly †}} \_def\ddag{\_errmessage{\_usedirectly ‡}} \_def\copyright{\_errmessage{\_usedirectly ©}} @@ -375,6 +375,7 @@ \_endcode % ------------------------------------- +2024-04-28 ... \_ corrected 2022-10-11 ... \_unichars extended 2022-02-19 ... \input hyphen.tex moved here (format file is 80k smaller) 2021-09-24 ... \_unichars introduced diff --git a/Master/texmf-dist/tex/optex/base/references.opm b/Master/texmf-dist/tex/optex/base/references.opm index cf43bb4049a..ab5968b9e9e 100644 --- a/Master/texmf-dist/tex/optex/base/references.opm +++ b/Master/texmf-dist/tex/optex/base/references.opm @@ -35,7 +35,7 @@ `\_wref\_Xlabel{<label>}{<text>}`. \_cod ---------------------------- -\_def\_label[#1]{\_isempty{#1}\_iftrue \_global\_let \_lastlabel=\_undefined +\_def\_label[#1]{\_isempty{#1}\_iftrue \_glet \_lastlabel=\_undefined \_else \_isdefined{l0:#1}% \_iftrue \_slideshook\_opwarning{Duplicated label [#1], ignored}\_else \_xdef\_lastlabel{#1}\_fi \_fi \_ignorespaces @@ -47,7 +47,7 @@ \_printlabel\_lastlabel \_ewref \_Xlabel {{\_lastlabel}{#1}}% \_sxdef{_lab:\_lastlabel}{#1}\_sxdef{l0:\_lastlabel}{}% - \_global\_let\_lastlabel=\_undefined + \_glet\_lastlabel=\_undefined \_fi } \_public \label \wlabel ; diff --git a/Master/texmf-dist/tex/optex/base/table.opm b/Master/texmf-dist/tex/optex/base/table.opm index 433ad412679..8da087386ab 100644 --- a/Master/texmf-dist/tex/optex/base/table.opm +++ b/Master/texmf-dist/tex/optex/base/table.opm @@ -195,8 +195,8 @@ \_def\_addtabitemx{\_ifnum\_colnum>0 \_addtabdata{&}\_addto\_ddlinedata{&\_dditem}\_fi \_advance\_colnum by1 \_let\_tmpa=\_relax - \_ifnum\_colnum>1 \_ea\_addtabdata\_ea{\_ea\_colnum\_the\_colnum\_relax}\_fi} -\_def\_addtabdata#1{\_tabdata\_ea{\_the\_tabdata#1}} + \_ifnum\_colnum>1 \_etoksapp\_tabdata{\_colnum\_the\_colnum\_relax}\_fi} +\_def\_addtabdata{\_toksapp\_tabdata} \_doc ----------------------------- This code converts `||` or `|` from `\table` <declaration> to the <converted declaration>. diff --git a/Master/texmf-dist/tex/optex/base/usebib.opm b/Master/texmf-dist/tex/optex/base/usebib.opm index cb38eea7e84..dcacbb0ebcd 100644 --- a/Master/texmf-dist/tex/optex/base/usebib.opm +++ b/Master/texmf-dist/tex/optex/base/usebib.opm @@ -1,6 +1,6 @@ %% This is part of the OpTeX project, see http://petr.olsak.net/optex -\_codedecl \readbibs {Reading bib databases <2023-06-25>} % loaded on demand by \usebib +\_codedecl \readbibs {Reading bib databases <2024-02-18>} % loaded on demand by \usebib \_doc ----------------------------- First, we implement the scanner of `.bib` files. Unfortunately, the format of @@ -16,7 +16,10 @@ \_def\_readbibs #1{% \_ifcsname _be:\_bibp*\_endcsname \_def\_citelist{}\_fi % \_citelist will be created \_begingroup - \_everyeof{@{}}\_foreach#1,\_do##1,{\_ea\_nextat\_input{##1.bib}}% + \_everyeof{@{}}\_foreach#1,\_do##1,{% + \_isfile{##1.bib}\_iftrue \_ea\_nextat\_input{##1.bib} + \_else \_opwarning{\_string\usebib: Missing ##1.bib file} + \_fi}% \_endgroup } \_public \readbibs ; @@ -448,17 +451,24 @@ If an entry with the same label is declared in `local.bib` and in `global.bib` too then the first wins. So, you can set exceptions in your `local.bib` file for your document. -The `bib-<style>.opm` declares entry types (like `@BOOK`, `@ARTICLE`) and declares +The `bib-<style>.opm` file declares entry types (like `@BOOK`, `@ARTICLE`) and declares their mandatory and optional fields (like `author`, `title`). When a mandatory field is missing in an entry in the `.bib` file then a warning is printed on the terminal about it. You can suppress such warnings by command \^`\nobibwarning`~`[<bib-labels>]`, where <bib-labels> is a comma-separated list of labels (without spaces) where missing mandatory fields will be no warned. -Old `.bib` files may use the obscure notation for accents like `{\"o}`. -Recommendation: convert such old files to Unicode encoding. If you are -unable to do this then you can set \^`\bibtexhook={`\^`\oldaccents}`. +Users may redefine declarations and the formatting rules given by the macros +from the style~file. Such a re-definition have to be included in the +\^`\bibtexhook` token list, because the \^`\usebib` macro opens group, reads +the macros from the style~file, then executes \^`\bibtexhook` (it is empty +by default), then reads data from the `.bib` files, then prints the desired +records and finally, it closes the group. +For example, \^`\bibtexhook={`\^`\oldaccents}` can be set if +your old `.bib` files use an obscure notation for accents like `{\"o}`. +Recommendation: converting such old `.bib` files to Unicode encoding is much +more conceptual solution of this problem. \secc Notes for bib-style writers @@ -665,6 +675,7 @@ author/editor data field. You can read them by History: -------- +2024-02-18: missing .bib files checked, doc improved 2023-06-25: \_fieldalias introduced 2023-06-07: bug fix (\_namecount declaration) 2023-06-06: \_slet{_bes:#1}{_relax}: bugfix when label not found and sorting diff --git a/Master/texmf-dist/tex/optex/base/verbatim.opm b/Master/texmf-dist/tex/optex/base/verbatim.opm index ac00369d337..3f486f83339 100644 --- a/Master/texmf-dist/tex/optex/base/verbatim.opm +++ b/Master/texmf-dist/tex/optex/base/verbatim.opm @@ -208,7 +208,7 @@ \_def\_tmpb{#1}% cmds used in local group \_ifx\_vifilename\_tmpa \_else \_openin\_vifile={#3}% - \_global\_viline=0 \_global\_let\_vifilename=\_tmpa + \_global\_viline=0 \_glet\_vifilename=\_tmpa \_ifeof\_vifile \_opwarning{\_string\verbinput: file "#3" unable to read} \_ea\_ea\_ea\_skiptorelax diff --git a/Master/texmf-dist/tex/optex/pkg/math.opm b/Master/texmf-dist/tex/optex/pkg/math.opm index 88bc81c627c..e3a9556eee4 100644 --- a/Master/texmf-dist/tex/optex/pkg/math.opm +++ b/Master/texmf-dist/tex/optex/pkg/math.opm @@ -3,7 +3,7 @@ % This file can serve as an template for other package files % See end of the file for more information -\_def\_math_version {0.11, 2023-04-15} +\_def\_math_version {0.15, 2024-04-28} \_codedecl \replacemissingchars {Doing math more comfortably <\_math_version>} \_namespace{math} @@ -21,12 +21,16 @@ \_nokvx {\_opwarning{\_the\_kvdict: unknown option "##1", ignored}}% \_kvx {vert} {\.smartvert}% sets | as math active, to do better |x| or ||x|| \_kvx {dots} {\.smartdots}% \dots behaves like \ldots or \cdots + \_kvx {interval} {\_let\_=\.interval}% enables \_<0,1) + \_kvx {rmsbsp} {\.rmsbsp}% activates x_[text] and x^[text] \_kvx {bfserif} {\.bfserif}% \bf, \bi select fonts with serifs + \_kvx {flexipa} {\.flexipa}% flexible partial symbol \_kvx {mstyle} {\.mstyle{##1}}% sets mstyle=TeX or ISO or french or upright \_kvx {bstyle} {\.bstyle{##1}}% sets bstyle=TeX or ISO or upright or OpTeX \_kvx {rmchars} {\.rmchars{##1}}% does \.rmchars{<list>} \_kvx {vargreek} {\.vargreek{##1}}% does \.vargreek{<list>} \_kvx {text} {\.dotext{##1}}% does \.dotext{<list>} + \_kvx {enablefic}{\.enablefic}% enables final italic correction \_readkv{#1}% \.restorekvdict } @@ -124,6 +128,23 @@ \_nspublic \smartdots ; \_doc + The macro \`\.interval` reads following tokens until the `)` or `>` is found in the input + queue and replaces \code{<} to `\langle` and `>` to rangle. The reading and replacing + process saves the tokens to the `\intevalL` macro only and finaly this macro is launched. + \_cod + +\_def\.interval{\_def\.intervalL{}\.intervalA} +\_def\.intervalA{\_nospacefuturelet\.next\.intervalB} +\_def\.intervalB{\_ifx\.next\_bgroup \_ea\.intervalC \_else \_ea\.intervalD \_fi} +\_def\.intervalC#1{\_addto\.intervalL{{#1}}\.intervalA} +\_def\.intervalD#1{\_casesof #1 + < {\_addto\.intervalL{\langle}\.intervalA} + > {\_addto\.intervalL{\rangle}\.intervalL} + ) {\_addto\.intervalL{)}\.intervalL} + \_finc {\_addto\.intervalL{#1}\.intervalA}% +} + + \_doc \`\smartvert` sets `|` as math-active character and declares it equal to `\.autovert` macro. This macro checks two variants: there is single `|` or there is double `||`. It runs \`\.autovertA` or @@ -142,6 +163,22 @@ \_nspublic \smartvert ; \_doc + \`\rmsbsp` activates `^` and `_` so they check the next character. + If it is `[` then `\mathbox` is used for subscript or superscript, else + normal behavior of subscript or superscript is kept. + \_cod + +\_def\.rmsbsp{% + \_adef ^{\_isnextchar[{\.rmsp}{\_sp}} + \_adef _{\_isnextchar[{\.rmsb}{\_sb}} + \_def\.rmsp[##1]{\_sp{\_mathbox{##1}}} + \_def\.rmsb[##1]{\_sb{\_mathbox{##1}}} + \_catcode `\^=12 \_catcode`\_=11 + \_mathcode`_="8000 \_mathcode`^="8000 +} +\_nspublic \rmsbsp ; + + \_doc The control sequences \`\N`, \`\Z`, \`\Q`, \`\R`, \`\C` \`\sgn`, \`\argmin`, \`\argmax`, \`\grad`, \`\rank`, \`\tr`, \`\diag`, \`\Span`, \`\Rng`, \`\Null`, \`\Ker`, \`\Res`, \`\tg`, \`\cotg`, \`\arctg`, \`\arccotg`, @@ -247,6 +284,43 @@ \_nspublic \bfserif ; \_doc + \`\flexipa` (or \`\flexiblepartial`) runs + \~`\partialsymbolvars` `{it}`\,`{rm}`\,`{bfsans}`\,`{it}`\,`{bfitsans}`. + The \`\partialsymbolvars` macro adds two tokens `\.partialvar \m<var>partial` + to `\_mit`, `\_marm`, `\_mabf`, `\_mait`, `\_mabi` macros. + The \`\.partialvar` macro sets appropriate + `\_Umathcode` of the `\.partialchar` to the code given by the parameter + `\m<var>partial`. Five macros + \`\mbfpartial`, \`\mitpartial`, \`\mbfitpartial`, \`\mbfsanspartial`, \`\mbfitsanspartial` + are declared in the macro file `unimath-table.opm`. + The math character \`\mrmpartial` (for upright variant) is declared here. + \_cod + +\_chardef\.partialchar="2202 +\_Umathchardef\.mrmpartial=0 1 \.partialchar +\_def\.partialvar #1{\_Umathcode \.partialchar 0 1 + \_ifx#1\.mrmpartial \.partialchar \_else\_ea`#1 \_fi +} +\_def\.inadd#1#2{\_ea\.inaddA#1{#2}#1} +\_def\.inaddA\_inmath#1#2#3{\_protected\_def#3{\_inmath{#1#2}}} + +\_def\.partialsymbolvars #1#2#3#4#5{% + \_ifx\_ncharrmA\_undefined \_opwarning{\_string\flexipa: Unicode math must be loaded first}% + \_else + \_def\.tmp{\_ea\_addto \_ea\_mit \_ea {\_ea\.partialvar \_csname m#1partial\_endcsname}}% + \_ifx\_mit\mit \.tmp \_let\mit=\_mit \_else \.tmp \_fi + \_ea\.inadd \_ea\_marm \_ea {\_ea\.partialvar \_csname m#2partial\_endcsname}% + \_ea\.inadd \_ea\_mabf \_ea {\_ea\.partialvar \_csname m#3partial\_endcsname}% + \_ea\.inadd \_ea\_mait \_ea {\_ea\.partialvar \_csname m#4partial\_endcsname}% + \_ea\.inadd \_ea\_mabi \_ea {\_ea\.partialvar \_csname m#5partial\_endcsname}% + \_mit + \_fi +} +\_def\.flexipa{\.partialsymbolvars {it}{rm}{bfsans}{it}{bfitsans}} +\_newpublic \_let \flexiblepartial=\.flexipa +\_nspublic \flexipa \partialsymbolvars \mrmpartial ; + + \_doc The options `mstyle`, resp. `bstyle` run \`\.mstyle`, resp. \`\.bstyle` and these macros set required shapes of math variables. This can be done only when Unicode-math is loaded already. This is a reason why @@ -436,6 +510,40 @@ \_nspublic \mathclap \mathrlap \mathllap ; + \_doc + \`\enablefic` enables final italic correction. The relevant lua function is + registered to `mlist_to_hlist` callback and \`\finalitalcorr` is set to one. + \_cod + +\_newcount \.finalitalcorr +\_directlua{ + function math.final_ital_corr(head, style) + if style=="text" and tex.count.\_pkglabel _finalitalcorr>0 then + for n in node.traverse(head) do + if n.next == nil and n.id == 29 then % last is glyph + local k = font.fonts[n.font].characters[n.char].italic + if not(k==nil) and (k>0) then + local kn = node.new("kern") + kn.kern = k kn.subtype = 3 + node.insert_after(head, n, kn) % kern node is inserted + end + end + end + end + return head + end +} +\_def\.enablefic {\_directlua{ % math.final_ital_corr is registered to mlist_to_hlist + luatexbase.add_to_callback("mlist_to_hlist", + function(head, style, penalties) + head = node.mlist_to_hlist(head, style, penalties) + return math.final_ital_corr(head, style) + end, "italcorr after math") + } + \.finalitalcorr=1 +} +\_nspublic \enablefic \finalitalcorr ; + \_endnamespace \_endcode @@ -451,6 +559,7 @@ The following macros are defined in this package: gives better controlling of sizes of parentheses. * \~`\smartdots` declares `\dots` macro more intelligent. \~`\smartvert` declares \"`|`" for better spacing. +* \~`\rmsbsp` activates roman subscripts and superscripts in `[...]`. * There are many common math macros for sets or for operators, for example \~`\R` or \~`\sgn`. * \~`\eqsystem` enables to write systems of equations comfortably, @@ -458,6 +567,7 @@ The following macros are defined in this package: \~`\subeqmark` prints the given suffix as a part of the equation mark. * \~`\scriptspaces` sets more spaces around rel, bin in script and scripscript styles. * \~`\bfserif` sets `\bf` and `\bi` for math typesetting as for bold-serif, bold-italic-serif. +* \~`\flexipa` enables flexible partial symbol. * \~`\rmchars` sets selected characters printed as `\rm`, \~`\vargreek` sets Greek leters to their variants. * \~`\textvariables`, \~`\textdigits`, \~`\textmoremath` @@ -465,22 +575,28 @@ The following macros are defined in this package: (variables, digits, more characters). * \~`\replacemissingchars` allows to re-declare all characters missing in math font for printing them from additional math font. +* \~`\enablefic` enables final italic correction of inline-math lists. \enditems -Eight options are provided by the `math` package. You can set them by +Following options are provided by the `math` package. You can set them by \^`\mathset``{<options>}` after `\load[math]`, for example `\mathset{dots, vert, vargreek={\epsilon,\rho}}`. The options are: \begitems * `dots` sets more inteligent `\dots`, the same as \~`\smartdots`. +* `interval` sets `\_` as prefix of intervals, see section~\ref[interval]. * `vert` sets more inteligent `|`, the same as \~`\smartvert`. +* `rmsbsp` sets roman sub/supscripts in `[...]`, the same as \~`\rmsbsp`. * `bfserif` sets bold-serif, bold-italic-serif, the same as \~`\bfserif`. +* `flexipa` enables flexible partial symbol, the same as \~`\flexipa`. * `mstyle=<style>`, `bstyle=<style>` are math styles explained in section~\ref[mstyle]. * `rmchars={<list>}` sets `\rm` for selected characters, the same as \~`\rmchars`, see section~\ref[rmchars]. * `vargreek={<list>}` sets variants for Greek letetters, the same as \~`\vargreek`, see section~\ref[rmchars]. * `text={<list>}` sets \~`\textvariables`, \~`\textdigits`, or \~`\textmoremath`, - see section~\ref[textvars]. + see section~\ref[textvars], +* `enablefic` enables final italic correction of inline-math lists, does + \~`\enablefic`. \enditems This package is not definitive. I plan to add more features in new versions @@ -545,6 +661,28 @@ You can try this after the \^`\smartdots` declaration: `$a_1 + a_2 + \dots + a_n$ ` prints $a_1 + a_2 + \dots + a_n$, +\sec[interval] Creating intervals more comfortable + +Several math books uses `\langle`, `\rangle` for denoting the interval boundary +if the boundary number is element of the interval too. For example `$\langle 0,1)$` +is printed as $\langle 0,1)$ and it +means an interval from zero to one, zero is element of the interval but one +isn't. The \TeX/ source of such math books looks badly because we cannot mark +them like \code{$<0,1)$} because it prints $\string<0,1)$ but we want $\langle 0,1)$. + +This package creates the \^`\.interval` macro which can be set to be equal to `\_` +(using the `interval` option). Then `\_` can be used just before the interval +as a prefix. The \code{<} or `>` are automatically replaced by `\langle`, `\rangle` +if `\_` is prefixed. So, you can write \code{$\\_<0,1)$} or `$\_(0,1>$` or \code{$\\_<0,1>$} +or `$\_(0,1)$` in order to get $\langle0,1)$ or $(0,1\rangle$ or $\langle0,1\rangle$ +or $(0,1)$. The source with such intervals looks better. + +Note that `interval` option does `\let\_=`\^`\.interval`, so the original +meaning of the `\_` control sequence (from plain \TeX/) is re-defined. +The `\_` control sequence can be used for this purpose because +the next token is `(` or \code{<}, i.e. it is non-letter. + + \sec Using vertical bars with better spacing The character \"`|`" is declared with Ord class by default in Plain \TeX/, @@ -567,6 +705,12 @@ $$ $$ +\sec Roman subscript and superscript in `[...]` + +When you declare \^`\rmsbsp`, then you can write `x_[text]` or `x^[text]` +and it is equivalent to `x_{\mathbox{text}}` or `x^{\mathbox{text}}`. + + \sec Basic and typical macros for sets, functions etc. These typical macros are defined in `math.opm`: @@ -758,6 +902,34 @@ sign must follow and then the `{<list>}` with syntax mentioned above. For exampl `\mathset{vargreek={\epsilon,\rho}}`. +\sec[flexipa] Flexible partial symbol $\partial$ + +Classical \TeX/ with Computer Modern fonts uses slanted `\partial` symbol +$\mitpartial$. On the other hand, default setting of Unicode math gives +upright `\partial` $\rm\partial$ but six variants of this symbol are provided: +roman (upright) \^`\mrmpartial` $\mrmpartial$, bold \^`\mbfpartial` $\mbfpartial$, +italic \^`\mitpartial` $\mitpartial$, bold italic \^`\mbfitpartial` $\mbfitpartial$, +bold sans serif \^`\mbfsanspartial` $\mbfsanspartial$, bold italic sans serif +\^`\mbfitsanspartial` $\mbfitsanspartial$. + +When you declare \^`\flexipa` or \^`\flexiblepartial` or use the `flexipa` +package option, then the `\partial` symbols get italic variant as default +and behaves like others Greek symbols: it changes its variant according to +the `\rm`, `\it`, `\bf`, `\bi` selectors in math mode. You can declare what +variant of the `\partial` character will be shown at what selector. This can +be done by the \^`\partialsymbolvars`~`<default> <rm> <bf> <it> <bi>` macro. +Each of these five parameters can be `{rm}` or `{bf}` or `{it}` or `{bfit}` +or `{bfsans}` or `{bfitsans}`. For example the third parameter declares +what variant of the partial symbol is printed when `\bf` selector is used +in math mode. The `\flexipa` macro runs the following default setting: +\begtt +\partialsymbolvars {it} {rm} {bfsans} {it} {bfitsans} +\endtt +It means that default is italic variant and when `\rm` is selected then roman +(upright) variant is printed, when `\bf` is selected then bold sans serif +variant is printed etc. + + \sec[textvars] Variables and digits from currently used text font When Unicode math font is loaded then all variables and digits are printed @@ -815,6 +987,31 @@ then you can load a next additional math font using another \o`\addUmathfont` an by previous steps are replaced. +\sec Final italic correction + +Classical \TeX/ adds italic correction after each Ord atom with a single +letter from math italic font including the last one in inline-math. \LuaTeX/ +and \OpTeX/ does the same only when classical `tfm` math fonts are used. When +you switch to Unicode math, the italic correction of the last glyph of the +inline-math list is lost, unfortunately. Try this: + +\begtt +$T$' the italic correction after $T$ is inserted (classical fonts) + +\fontfam[lm] +$T$' the italic correction after $T$ isn't inserted (Unicode fonts) +\bye +\endtt + +This package provides the \^`\enablefic` command which enables the classical TeX +feature: the final italic correction of the inline-math list is automatically added. + +When \^`\enablefic` (or `enablefic` option) is declared then you can control +the behavior of this feature by the \^`\finalitalcorr` register: if it is positive +then the feature is activated and if it is zero, the feature is deactivated. +The \^`\enablefic` macro sets \^`\finalitalcorr``=1`. + + \sec Miscelaneous commands I created various commands at the requests of users. They asked me to create @@ -901,6 +1098,7 @@ The user can read this warning and declare the macro after `\load[<pkg>]` in this case. \_doc + % optex -jobname math-doc '\docgen math' \load [doc,math] \def\opurl{http://petr.olsak.net/ftp/olsak/optex/optex-doc.pdf} \def\tnurl{http://petr.olsak.net/ftp/olsak/optex/tex-nutshell.pdf} @@ -931,6 +1129,10 @@ The user can read this warning and declare the macro after \endinput +0.15 2024-04-28 \_ as interval prefix added. +0.14 2024-03-18 \flexipa introduced. +0.13 2024-03-06 \enablefic introduced. +0.12 2024-03-02 \rmsbsp introduced. 0.11 2023-04-15: \bbigp introduced. 0.10 2023-03-12: \mathclap etc. introduced. 0.09 2023-03-11: mstyle, bstyle options introduced. diff --git a/Master/texmf-dist/tex/optex/pkg/mte.opm b/Master/texmf-dist/tex/optex/pkg/mte.opm index 5352d5dd782..c3d304610c1 100644 --- a/Master/texmf-dist/tex/optex/pkg/mte.opm +++ b/Master/texmf-dist/tex/optex/pkg/mte.opm @@ -457,7 +457,7 @@ \.initexpansion % luacode, ex table initialized \_protrudechars=2 \_adjustspacing=2 - \_def\.features{protrusion=p\.var;expansion=ex}% pr/pi and ex tables used + \_def\.features{protrusion=p\.var;expansion=ex;}% pr/pi and ex tables used \_reloading \_currvar } \_def\.disablemte {% |