diff options
Diffstat (limited to 'macros/optex/base/optex-tricks.opm')
-rw-r--r-- | macros/optex/base/optex-tricks.opm | 210 |
1 files changed, 199 insertions, 11 deletions
diff --git a/macros/optex/base/optex-tricks.opm b/macros/optex/base/optex-tricks.opm index 456a7472e1..c90b429a4f 100644 --- a/macros/optex/base/optex-tricks.opm +++ b/macros/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 |