From c6e65df65e2730ccbc12241e001490436adb1c4b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sat, 21 Oct 2023 20:21:59 +0000 Subject: minim all (21oct23) git-svn-id: svn://tug.org/texlive/trunk@68612 c570f23f-e606-0410-a88d-b1316a301751 --- .../tex/luatex/minim-math/minim-math.lua | 12 +- .../tex/luatex/minim-math/minim-math.tex | 63 +++++--- .../texmf-dist/tex/luatex/minim-mp/minim-lamp.ini | 11 +- Master/texmf-dist/tex/luatex/minim-mp/minim-mp.ini | 2 +- Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua | 163 +++++++++++++++------ Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty | 59 ++++++++ Master/texmf-dist/tex/luatex/minim-mp/minim-mp.tex | 16 +- .../texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua | 48 ++++-- .../texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex | 141 ++++++++++++++---- Master/texmf-dist/tex/luatex/minim/minim-alloc.lua | 15 +- Master/texmf-dist/tex/luatex/minim/minim-alloc.tex | 16 +- Master/texmf-dist/tex/luatex/minim/minim-doc.sty | 2 +- Master/texmf-dist/tex/luatex/minim/minim.ini | 2 +- 13 files changed, 415 insertions(+), 135 deletions(-) create mode 100644 Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty (limited to 'Master/texmf-dist/tex/luatex') diff --git a/Master/texmf-dist/tex/luatex/minim-math/minim-math.lua b/Master/texmf-dist/tex/luatex/minim-math/minim-math.lua index a4540a92b23..2598094fdd6 100644 --- a/Master/texmf-dist/tex/luatex/minim-math/minim-math.lua +++ b/Master/texmf-dist/tex/luatex/minim-math/minim-math.lua @@ -431,10 +431,6 @@ local is_delimiter = , close = true } -local function tex_accent(class, num, char) - return '\\math:'..accents[class]..'{'..num..'}'..char -end - local function add_mathchar(code, char, class, cs, alphabet) if char:sub(0,1) == ' ' then -- accents can be given above a space (compare ' ́' with '́') @@ -448,13 +444,15 @@ local function add_mathchar(code, char, class, cs, alphabet) if is_delimiter[class] then tex.setdelcode(code, default_fam, code, 0, 0) end elseif class == 'radical' then if cs then - token.set_macro(cs, '\\math:radical{'..code..'}'..char) - tex.print('\\mathlet\\'..char..'\\'..cs) + tex.print(string.format('\\protected\\def\\%s{\\math:radical{%s}%s}', cs, code, char)) + tex.print(string.format('\\mathlet\\%s\\%s', char, cs)) end else -- TODO: in the future, allow accent characters by re-ordering them tex.setmathcode(code, 0, default_fam, 0) -- provisional - if cs then token.set_macro(cs, tex_accent(class, code, char)) end + if cs then + tex.print(string.format('\\protected\\def\\%s{\\math:%s{%s}%s}', cs, accents[class], code, char)) + end end add_to_alphabet(code, class) if alphabet then diff --git a/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex b/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex index d24a6693dcc..1a8f1157c11 100644 --- a/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex +++ b/Master/texmf-dist/tex/luatex/minim-math/minim-math.tex @@ -9,12 +9,23 @@ % \mathdef c {expansion} \protected\def\mathdef#1#2{% - \def\mathdef:tmp{#2}% - \mathlet{#1}\mathdef:tmp} -% \mathlet c \csname -\protected\def\mathlet#1#2{% + \protected\def\mathdef:tmp{#2}% \mathcode`#1="8000\relax - \letcharcode`#1=#2} + \letcharcode`#1=\mathdef:tmp} +% \mathlet c \csname +\let\mathlet = \mathdef + +% sensible defaults +\matheqdirmode = 1 % short skips also in rtl +\mathdisplayskipmode = 1 +% +% not set here, but maybe relevant: +% +% \mathsurroundskip = ... +% \mathitalicsmode = 1 +% \mathscriptboxmode = 2 +% \matheqnogapstep = 1000 % default value +% \predisplaygapfactor = 2000 % default value % 1 Global style transformations @@ -86,20 +97,20 @@ \newcount \accentfam \accentfam = 0 \newcount \extensiblefam \extensiblefam = 0 -\def\math:accent{\ifmmode% spec num char +\protected\def\math:accent{\ifmmode% spec num char \expandafter\math:mathaccent\else \expandafter\math:textaccent\fi} \def\math:mathaccent#1#2#3{\Umathaccent #1"0 \accentfam #2 } \def\math:textaccent#1#2#3#4{#4#3}% might be a normal combining accent -\def\math:stack#1#2#3{% spec num char +\protected\def\math:stack#1#2#3{% spec num char \withoptions[]{\math:stack:{#1}{#2}{#3}}} \def\math:stack:#1#2#3[#4]#5{% {\mathop{\math:accent{#1}{#2}{#3}{#5}}% \ifx\math:stack#4\math:stack\else \limits \ifx\math:stack#1\math:stack^\else_\fi{#4}\fi}} -\def\math:radical{\ifmmode% num char +\protected\def\math:radical{\ifmmode% num char \expandafter\math:mathradical\else \expandafter\math:textradical\fi} \def\math:mathradical#1#2{\Uradical\radicalfam #1 } @@ -255,6 +266,7 @@ \normalroots +\let\of=\relax \mathlet √ \sqrt \mathdef ∛ {\root3\of} \mathdef ∜ {\root4\of} @@ -529,23 +541,34 @@ % 1 Displayed equations -\newif\ifdisplay: -\newif\ifdisplay:nr -\newif\ifleftdisplays -\newtoks\setdisplaynr -\newtoks\display:specialnr -\display:specialnr{\the\setdisplaynr} - % \display \protected\def\display{\display:true} % \displaynr {nr} \protected\def\displaynr{\display:true\display:nrtrue \nextifcat\bgroup\display:specialnr\relax} +% \leftdisplaystrue +\newif\ifleftdisplays +% \setdisplaynr {...} +\newtoks\setdisplaynr +% \equationnumber +\newcount\equationnumber \equationnumber = 0 +\setdisplaynr{\global\advance\equationnumber1(\the\equationnumber)} + +\newif\ifdisplay: +\newif\ifdisplay:nr +\newtoks\display:specialnr +\display:specialnr{\the\setdisplaynr} + % \[ ... \] -\protected\def\[{\ifdisplay:\expandafter\startdisplay\else\Ustartmath\fi} -\protected\def\]{\global\expandafter\display:false +\protected\def\[#1\]{% + \ifdisplay:\expandafter\startdisplay\else\Ustartmath\fi + \tagging:tagformula{#1}#1\relax + \global\expandafter\display:false \ifdisplay:\expandafter\stopdisplay\else\Ustopmath\fi} +\protected\def\]{\errmessage{Unmatched \string\]}} +\ifdefined \tagging:tagformula \else + \let\tagging:tagformula=\ignore \fi \protected\def\startdisplay{% % if the display starts a paragraph, omit baselineskip @@ -553,6 +576,8 @@ \ifvmode \nointerlineskip \noindent \hbox to .5\hsize{\hss}\fi \Ustartdisplaymath + % compatibility with minim-pdf + \csname tagging:indisplaytrue\endcsname % for left-aligned equations, force manual placement \ifleftdisplays\muskip0mu\fi} \protected\def\stopdisplay{% @@ -565,10 +590,6 @@ \Ustopdisplaymath \ignorespaces} -% default equation numbering -\newcount\equationnumber \equationnumber = 0 -\setdisplaynr{\global\advance\eqnr1(\the\equationnumber)} - %  standard mappings diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-lamp.ini b/Master/texmf-dist/tex/luatex/minim-mp/minim-lamp.ini index 7900b3936ae..d6ba6a66378 100644 --- a/Master/texmf-dist/tex/luatex/minim-mp/minim-lamp.ini +++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-lamp.ini @@ -4,13 +4,20 @@ \input lualatex.ini +\catcode`\@=11 +% see minim-lamp.mp +\def\providebegindocument{% + \ifx\@onlypreamble\@notprerr + \else\expandafter\document\fi} +\catcode`\@=12 + \toksapp\everyjob{% \documentclass{article} - \input minim-mp + \usepackage{polyglossia, minim-mp} \message{This is the minim-latex metapost processor.}\relax \directlua {require('minim-mp').on_line = true}% \newmetapostinstance[jobname="\jobname", mathmode="scaled"]\MP - \runmetapost\MP{input "\jobname";}% + \runmetapost\MP{input "minim-lamp.mp"; input "\jobname";}% \directlua {require('minim-mp').shipout(\the\MP)}% \closemetapostinstance\MP \csname @fileswfalse\endcsname\end{document}} diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.ini b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.ini index e3312a0cb91..11387e00d12 100644 --- a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.ini +++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.ini @@ -1,7 +1,7 @@ \catcode`\{=1 \catcode`\}=2 \def\fmtname{minim-mp} -\def\fmtversion{2021/1.0} +\def\fmtversion{2023/1.3} \input minim.ini diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua index a247c494992..f1cfd493887 100644 --- a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua +++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.lua @@ -8,6 +8,16 @@ local M = {} -- 1 AUXILIARY FUNCTIONS +local GLUE_NODE = node.id 'glue' +local GLYPH_NODE = node.id 'glyph' +local KERN_NODE = node.id 'kern' +local WHATSIT_NODE = node.id 'whatsit' + +local function copy_table(from, to) + for k,v in pairs(from) do to[k] = v end + return to +end + -- 2 state metatable -- q Q store/restore graphics state @@ -338,7 +348,7 @@ function A.linestate (append, object) local res = { } if ml and ml ~= append.miterlimit then append.miterlimit = ml - table.insert(res, pdfnum('M', ml)) -- TODO is pdfnum here correct? + table.insert(res, pdfnum('M', ml)) end local lj = object.linejoin if lj and lj ~= append.linejoin then @@ -352,7 +362,7 @@ function A.linestate (append, object) end local dl = object.dash if dl then - local d = string.format('[%s] %i d', table.concat(dl.dashes or {},' '), dl.offset) + local d = string.format('[%s] %s', table.concat(dl.dashes or {},' '), pdfnum('d', dl.offset)) if d ~= append.dashed then append.dashed = d table.insert(res, d) @@ -691,13 +701,13 @@ local function definepattern(head, user, bbox) for n in node.traverse(head) do -- try if we can construct the content stream ourselves; otherwise, -- stuff the pattern template into an xform. - if n.id == 8 then + if n.id == WHATSIT_NODE then -- try if we can simply concatenate pdf statements - if n.subtype == 16 then -- literal + if n.subtype == node.subtype 'literal' then table.insert(literals, n.data) - elseif n.subtype == 30 then -- save + elseif n.subtype == node.subtype 'save' then table.insert(literals, 'q') - elseif n.subtype == 31 then -- restore + elseif n.subtype == node.subtype 'restore' then table.insert(literals, 'Q') else resources, pat.stream = make_pattern_xform(head, bb) @@ -807,8 +817,6 @@ M.instances = instances -- 2 small instance helper functions -local default_catcodes = alloc.registernumber('minim:mp:catcodes') - -- parameters: wd, ht+dp, dp local function make_transform(w, h, d) return string.format('identity xscaled %fpt yscaled %fpt shifted (0,-%fpt)', @@ -866,11 +874,27 @@ local function print_log (nr, res, why) i.status = res.status end -local function finder (name, mode, ftype) - if mode == 'w' then +local function new_file_finder() + -- HACK: The file finder is called twice for every file input by metapost. + -- Thus, in order for the file recorder to work properly, we only record + -- repeated files and hope for the best. + local last_found = false + local function record(name, record_fn) + if last_found and name == last_found then + record_fn(name) + last_found = false + else + last_found = name + end + end + return function(name, mode, ftype) + if mode == 'w' then + record(name, kpse.record_output_file) + else + name = kpse.find_file(name, ftype) + record(name, kpse.record_input_file) + end return name - else - return kpse.find_file(name,ftype) end end @@ -933,6 +957,12 @@ end -- 2 running lua scripts +-- There are two ways of running lua code with the runscript primitive. In the +-- normal case, the argument to runscript is executed as lua code. You can +-- bypass this mechanism by prepending the runscript argument with the name of +-- a lua function between double square brackets. Then, the remainder of the +-- string will be passed as an argument to that function.Q +-- -- Code run with runscript may return a value; we will try and convert it to -- a string that metapost can understand. -- @@ -940,16 +970,17 @@ end -- converted to a transformation. (The margin will be ignored for now, this may -- change in the future.) -local function default_env() - local env = { } - for k,v in pairs(_G) do - env[k] = v - end - return env +local function mkluastring(s) + return "'"..(s:gsub('\\', '\\\\'):gsub("'", "\\'")).."'" end local function runscript(code) + -- (possibly) pass directly to function + local fn, arg = code:match('^%[%[(.+)%]%](.*)') + if fn then code = 'return '..fn .. mkluastring(arg) end + -- execute the script local f, msg = load(code, current_instance.jobname, 't', current_instance.env) + -- interpret results if f then local result = f() if result == nil then @@ -980,6 +1011,36 @@ local function runscript(code) end end +-- The environment the scripts will be run in can be specified at instance +-- creation; its default value is a copy (at that time) of the global +-- environment. The runscript environment will then be extended with all +-- elements of the M.mp_functions table. + +local E = { } +M.mp_functions = E + +local function prepare_env(e) -- in M.open() + local env = e or copy_table(_G, { }) + return copy_table(E, env) +end + +function E.quote(val) + if type(val) ~= 'string' then return val end + local escaped = string.format('%s', val):gsub('"', '"&ditto&"') + return string.format('("%s")', escaped) +end + +function E.sp_to_pt(val) + return string.format('%.16fpt', val/65536) +end + +function E.quote_for_lua(s) + return E.quote(mkluastring(s)) +end + +E.rgb_to_gray = rgb_to_gray +E.enable_debugging = M.enable_debugging + -- 2 typesetting with tex -- The result of the maketext function is fed back into metapost; on that side, @@ -1001,7 +1062,7 @@ local function maketext(text, mode) if mode == 0 then -- btex or maketext local nr = alloc.new_box() table.insert(current_instance.boxes, nr) - local assignment = string.format('\\global\\setbox%s=\\hbox{%s}', nr, text) + local assignment = string.format('\\global\\setbox%s=\\hbox{\\the\\everymaketext %s}', nr, text) tex.runtoks(function() tex.print(current_instance.catcodes, assignment:explode('\n')) end) local box = tex.box[nr] return 'image ( fill unitsquare withprescript "TEXBOX:' ..nr..'";'.. @@ -1020,25 +1081,25 @@ local typeset_box = alloc.new_box('infont box') local function process_typeset(text, fnt, sep, fn) tex.runtoks(function() - tex.sprint(default_catcodes, string.format( + tex.sprint(current_instance.catcodes, string.format( '\\setbox%d=\\hbox{\\setfontid%d\\relax', typeset_box, getfontid(fnt))) - tex.sprint(-2, text); tex.sprint(default_catcodes, '}') + tex.sprint(-2, text); tex.sprint(current_instance.catcodes, '}') end) local res, x = { }, 0 for n in node.traverse(tex.box[typeset_box].list) do - if n.id == 29 then -- glyph + if n.id == GLYPH_NODE then fn(res, n, x) x = x + n.width - elseif n.id == 12 then -- glue + elseif n.id == GLUE_NODE then x = x + n.width - elseif n.id == 13 then -- kern + elseif n.id == KERN_NODE then x = x + n.kern end end return table.concat(res, sep) end -function M.infont(text, fnt) +function E.minim_infont(text, fnt) return process_typeset(text, fnt, '', function(res, n, x) table.insert(res, string.format( 'draw image ( fill unitsquare shifted (%fpt,0) withprescript "CHAR:%d %d %d %d";' @@ -1059,6 +1120,10 @@ function M.make_glyph(glyphname, fnt) end local fontid = getfontid(fnt) local thefont = font.getfont(fontid) + if not thefont then + alloc.err('Font not found: %s (id %s)', fnt, fontid) + return { }, 10 + end local fontname = thefont.psname local gid = luaotfload.aux.gid_of_name(fontid, glyphname) if not gid then @@ -1091,24 +1156,22 @@ function M.make_glyph(glyphname, fnt) return paths, thefont.size end -function M.get_named_glyph(name, fnt) - local res, contours, size = {}, M.make_glyph(name, fnt) - for _, c in ipairs(contours) do - table.insert(res, string.format( - '%s scaled %f', c, size/65536000)) - end - return table.concat(res, ', ') -end - local function get_glyphname(c_id) return luaotfload.aux.name_of_slot(c_id) end -function M.get_glyph(c_id, fnt) - return M.get_named_glyph(get_glyphname(c_id), fnt) +function E.get_glyph(c_id, fnt) + local name = (type(c_id) == 'string') and c_id or get_glyphname(c_id) + local contours, size = M.make_glyph(name, fnt) + local res = { } + for _, c in ipairs(contours) do + table.insert(res, string.format( + '%s scaled %f', c, size/65536/1000)) + end + return table.concat(res, ', ') end -function M.get_contours(text, fnt) +function E.get_contours(text, fnt) return process_typeset(text, fnt, ', ', function(res, n, x) local contours, size = M.make_glyph(get_glyphname(n.char), n.font) for _, c in ipairs(contours) do @@ -1119,6 +1182,9 @@ function M.get_contours(text, fnt) end) end +M.get_contours = E.get_contours + + -- 2 opening, running and and closing instances local function apply_default_instance_opts(t) @@ -1126,7 +1192,7 @@ local function apply_default_instance_opts(t) { ini_version = true , error_line = (texconfig.error_line or 79) - 5 , extensions = 1 - , find_file = finder + , find_file = new_file_finder() --, script_error = ... , job_name = t.jobname , math_mode = t.math or 'scaled' @@ -1168,7 +1234,8 @@ function M.run (nr, code) save_image_list(self, picts) end -M.init_code = { 'let dump=endinput;', 'input INIT;', 'input minim.mp;' } +M.init_code = { 'let dump=endinput;', 'input INIT;', 'input minim-mp.mp;', 'input minim.mp;' } +local maketext_catcodes = alloc.registernumber('minim:mp:catcodes:maketext') function M.open (t) local nr = #instances + 1 @@ -1184,10 +1251,11 @@ function M.open (t) , jobname = t.jobname , results = { first = nil, last = nil, by_name = {}, count = 0 } , status = 0 - , catcodes = t.catcodes or default_catcodes + , catcodes = t.catcodes or maketext_catcodes , boxes = { } -- allocated by maketext - , env = t.env or default_env() + , env = prepare_env(t.env) } + current_instance = instances[nr] print_log(nr, instance:execute(init), 'opening ') return nr end @@ -1274,14 +1342,23 @@ end local scan_int = token.scan_int local scan_string = token.scan_string +local code_catcodes = alloc.registernumber('minim:mp:catcodes:mpcode') +local function scan_codestring() + local cct = tex.catcodetable + tex.catcodetable = code_catcodes + local res = token.scan_string() + tex.catcodetable = cct + return res +end + alloc.luadef('closemetapostinstance', function() M.close(scan_int()) end) alloc.luadef('runmetapost', function() - M.run(scan_int(), scan_string()) + M.run(scan_int(), scan_codestring()) end, 'protected') alloc.luadef('runmetapostimage', function() local i = scan_int() - local code = 'beginfig(0)'..scan_string()..';endfig;' + local code = 'beginfig(0)'..scan_codestring()..';endfig;' M.run(i, code) node.write(M.get_image(i)) end, 'protected') diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty new file mode 100644 index 00000000000..ae0312b5609 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.sty @@ -0,0 +1,59 @@ + +\ProvidesPackage{minim-mp}[2023/03/03 Run MetaPost code from LaTeX] + +\input minim-mp + +\makeatletter + +\RequirePackage{environ} + +% work around latex’s \protect mechanism +\let\mnm@protect=\protect +\everymaketext{\let\protect=\mnm@protect} + +% the defaultfont is the current \normalfont +\def\mnm@setnormalfont{{\normalfont + \xdef\mnm@normalfont{\expandafter\csstring\the\font}}} + +% a one-off metapost environment +\newenvironment{metapost}[1][]{% + \begingroup \catcode`\#=12 + \let\mpcolor = \minimpcolor + \csname:metapost:\endcsname[#1]} + {\csname end:metapost:\endcsname \endgroup} +\NewEnviron{:metapost:}[1][]{% + \mnm@setnormalfont + \let\protect=\noexpand + \directmetapost[#1]{% + defaultfont:="\mnm@normalfont"; \BODY; }% + \let\protect=\mnm@protect} + +% separate metapost instances +\newcommand\newmetapostenvironment[2][]{% + \newmetapostinstance[#1]\mnm@tmp + \expandafter\let\csname #2@instance\endcsname\mnm@tmp + \newenvironment{#2}{% + \begingroup \catcode`\#=12 + \let\mpcolor = \minimpcolor + \csname:#2:\endcsname} + {\csname end:#2:\endcsname \endgroup}% + \NewEnviron{:#2:}{% + \mnm@setnormalfont + \let\protect=\noexpand + \runmetapostimage + \csname #2@instance\endcsname + {defaultfont:="\mnm@normalfont";\BODY;}% + \let\protect=\mnm@protect}} + +% \mpcolor support +\def\minimpcolor#1#{\dominimpcolor{#1}} +\def\dominimpcolor#1#2{% + \directlua{ tex.scantoks('mpcolorspectoks', 0, '#1{#2}') + tex.runtoks 'mpcolorruntoks' } + (\the\mpcolorvaltoks)} +\newtoks\mpcolorspectoks \newtoks\mpcolorruntoks \newtoks\mpcolorvaltoks +\mpcolorruntoks{\expandafter\extractcolorspec\the\mpcolorspectoks\mptmpcolor + \expandafter\mpcolorvaltoks\expandafter\@gobble\mptmpcolor} + +\makeatother + diff --git a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.tex b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.tex index ad84a4f19df..6d953346776 100644 --- a/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.tex +++ b/Master/texmf-dist/tex/luatex/minim-mp/minim-mp.tex @@ -9,9 +9,14 @@ \input minim-pdfresources % a default catcode table -\newcatcodetable \minim:mp:catcodes +\newcatcodetable \minim:mp:catcodes:maketext {\catcode`\:=12 \catcode`\@=12 - \savecatcodetable\csname minim:mp:catcodes\endcsname} + \savecatcodetable\csname minim:mp:catcodes:maketext\endcsname} +% and an empty catcode table for reading metapost code +\newcatcodetable \minim:mp:catcodes:mpcode +{\catcodetable\minim:initcatcodes + \catcode`\{=1 \catcode`\}=2 \catcode9=10 + \savecatcodetable\csname minim:mp:catcodes:mpcode\endcsname} \directlua { require('minim-mp') } @@ -30,9 +35,10 @@ % \boxnamedmpimage \instance box-nr {name} % \directmetapost [ options ] { code } -\protected\def\directmetapost{\withoptions[]\directmetapost:} +\protected\def\directmetapost{% + \begingroup\catcodetable\minim:mp:catcodes:mpcode + \withoptions[]\directmetapost:} \long\def\directmetapost:[#1]#2{% - \begingroup \newmetapostinstance[#1]\:mpinst: \runmetapost\:mpinst:{#2}% \loop \ifnum\remainingmpimages\:mpinst:>0\relax @@ -55,6 +61,8 @@ \newcount\GtoG \GtoG = 7152 \newcount\BtoG \BtoG = 0722 +\newtoks \everymaketext + \catcode`\: = \minimmploaded diff --git a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua index 72070366d3c..74d56eeaac2 100644 --- a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua +++ b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.lua @@ -7,6 +7,13 @@ alloc.remember('minim-pdf') -- 1 helper functions +local GLUE_NODE = node.id 'glue' +local GLYPH_NODE = node.id 'glyph' +local RULE_NODE = node.id 'rule' +local WHATSIT_NODE = node.id 'whatsit' +local USER_DEFINED = node.subtype 'user_defined' +local START_LINK = node.subtype 'pdf_start_link' + local function insert_formatted(t, ...) table.insert(t, string.format(...)) end @@ -23,6 +30,14 @@ local pdf_name = alloc.pdf_name local pdf_string = alloc.pdf_string local options_scanner = alloc.options_scanner +-- is this table empty? +local function is_empty(t) + for _, _ in pairs(t or {}) do + return false + end + return true +end + -- has this table just one element? local function singleton(t) local one = false @@ -55,9 +70,9 @@ local function full_traverse(head) end, { { } }, { next = head } end -local function pdf_err(n, msg) +local function pdf_err(n, msg, ...) local m = node.new('whatsit', 'pdf_literal') - m.mode, m.token = 2, '%% Warning: '..msg + m.mode, m.token = 2, '%% Warning: '..string.format(msg, ...) node.insert_after(n, n, m) end @@ -367,7 +382,7 @@ local function write_structure() end if #se.class > 1 then table.insert(res, ']') end end - if se.attributes then + if not is_empty(se.attributes) then table.insert(res, '/A') make_attributes(res, se.attributes) end @@ -574,6 +589,13 @@ alloc.luadef('tagging:attribute', function() token.scan_string(), token.scan_string(), token.scan_string()) end) +alloc.luadef('tagging:ignore:attribute', function() + -- if \tagging:enabled is false + token.scan_string() + token.scan_string() + token.scan_string() +end) + alloc.luadef('newattributeclass', function() local s = options_scanner():subtable('attr') attribute_classes[token.scan_string()] = s:scan().attr @@ -669,18 +691,18 @@ function M.mark_content_items(box) end -- traversing all nodes for n, b in full_traverse(box) do - local marker = n.id == 8 and n.subtype == 8 + local marker = n.id == WHATSIT_NODE and n.subtype == USER_DEFINED and n.user_id == marker_whatsit and n.value local stat = n[current_status] -- first we start with marking artifacts if marker and marker.what == 'art_start' then - insert_tags(b); + insert_tags(b) start_content(n, b) local a = string.format('/Artifact << /Type/%s >> BDC', marker.it) open_artifacts[stat], open, art = a, pdf_literal(a), stat elseif marker and marker.what == 'art_stop' then end_node = n - insert_tags(b); + insert_tags(b) if art then open_artifacts[art], art = nil, nil end elseif stat and stat >10 and stat ~=art then -- broken artifact insert_tags(b); @@ -688,14 +710,14 @@ function M.mark_content_items(box) local a = open_artifacts[stat] if not a then alloc.err('Encountered tail of unknown artifact (see pdf)') - pdf_err(n, 'unknown artifact (this should not be possible)') + pdf_err(n, 'unknown artifact nr. %d (this should not be possible)', stat) a = '/Artifact << /Type/Unknown >> BDC' end open, art = pdf_literal(a), stat elseif stat then -- inside artifact or tagging disabled end_node = n -- then attach links to Link elements - elseif n.id == 8 and n.subtype == 19 then -- pdf_start_link + elseif n.id == WHATSIT_NODE and n.subtype == START_LINK then local _se, _order = n[current_struct], n[current_order] local link = structure[_se] if link.struct == 'Link' then @@ -714,10 +736,10 @@ function M.mark_content_items(box) elseif marker and marker.what == 'mci_stop' then end_node = end_node and n; insert_tags(b) -- finally, see if we need to intervene between content nodes - elseif n.id == 2 or n.id == 29 -- rule, glyph or content marker + elseif n.id == RULE_NODE or n.id == GLYPH_NODE or marker and marker.what == 'content' then local _se, _order = n[current_struct], n[current_order] - if n.id == 2 and (n.width == 0 or n.height == 0 and n.depth == 0) then + if n.id == RULE_NODE and (n.width == 0 or n.height == 0 and n.depth == 0) then -- ignore invisible rules elseif not _se or not _order then -- unmarkable content should not be possible (but is) @@ -731,7 +753,7 @@ function M.mark_content_items(box) else -- nothing changed: continue current mci end_node = n end - elseif n.id == 12 and n.subtype > 2 and n.subtype < 8 then + elseif n.id == GLUE_NODE and n.subtype > 2 and n.subtype < 8 then -- parskip or displayskip always closes mci insert_tags(b) end @@ -963,8 +985,8 @@ function M.mark_spaces(head, gc) for g in node.traverse_id(12, head) do -- glue if g.prev and g.subtype == 13 or g.subtype == 14 then -- (x)spaceskip local p = g.prev - p[space_attr] = p.id == 29 and p.font - or g.next and g.next.id == 29 and g.next.font + p[space_attr] = p.id == GLYPH_NODE and p.font + or g.next and g.next.id == GLYPH_NODE and g.next.font or font.current() end end diff --git a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex index a8fe5aeea6e..d8b06255bab 100644 --- a/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex +++ b/Master/texmf-dist/tex/luatex/minim-pdf/minim-pdf.tex @@ -112,19 +112,24 @@ \protected\def\addstructuretype{\withoptions[]\addstructure:type} \def\addstructure:type[#1]{\struct:addalias{return {#1}}} -% \setalttext {...} and \setactualtext {...} +% \setalttext {...} \protected\def\setalttext{\iftagging:enabled - \expandafter\tagging:alt\fi} + \expandafter\tagging:alt\else + \expandafter\tagging:ignore\fi} +% \setactualtext {...} \protected\def\setactualtext{\iftagging:enabled - \expandafter\tagging:actual\fi} + \expandafter\tagging:actual\else + \expandafter\tagging:ignore\fi} % \tagattribute Owner Key /verbatim_value \protected\def\tagattribute{\iftagging:enabled - \expandafter\tagging:attribute\fi} + \expandafter\tagging:attribute\else + \expandafter\tagging:ignore:attribute\fi} % \settagid {name} \protected\def\settagid{\iftagging:enabled - \expandafter\tagging:tagid\fi} + \expandafter\tagging:tagid\else + \expandafter\tagging:ignore\fi} % \showstructure \newtoks\tagging:showtoks @@ -146,7 +151,8 @@ % 1 tagging tables -% \marktable \halign {\marktablerow\marktablecell#&\marktablecell#\cr +% \marktable \halign +% {\marktablerow\marktablecell#&\marktablecell#\cr % \marktableheader % Header & cells \cr % \marktablebody @@ -155,7 +161,7 @@ % ... & ... \cr ... } % % lots of variables and constants -\newcount\tagging:tablec +\newcount\tagging:tablec % global; only used for cel ids \newcount\tagging:tablerow \newcount\tagging:tablecol \newcount\tagging:tablecolspan \tagging:tablecolspan 1 @@ -166,11 +172,11 @@ % initialising variables \def\marktable{\startelement{Table}% \global\advance\tagging:tablec1 - \global\tagging:tablerow0 - \global\tagging:tablecol0 - \global\def\tagging:tablecolheaders{}% - \global\def\tagging:tablerowheaders{}% - \global\let\tagging:cell\tagging:TD} + \tagging:tablerow0 + \tagging:tablecol0 + \def\tagging:tablecolheaders{}% + \def\tagging:tablerowheaders{}% + \let\tagging:cell\tagging:TD} % the header \def\marktableheader{% \noalign{\global\let\tagging:cell\tagging:TH @@ -201,21 +207,78 @@ \continueelementfrom\tagging:row \startelement{\tagging:cell}% \tagging:assignheaders} -% table headers + +% spans +\def\markcolumnspan#1{% + \tagattribute Table ColSpan #1\relax + \tagging:tablecolspan#1\relax + % adjust the column number + \global\advance\tagging:tablecol\numexpr#1-1\relax} +\def\markrowspan#1{% + % note that the row number is not adjusted: \marktablerow must be present + % somewhere on every row to increment it. + \tagattribute Table RowSpan #1\relax + \tagging:tablerowspan#1\relax} + +% headers +\def\markcolumnhead{% + \tagging:setcelid + \tagattribute Table Scope /Column\relax + \tagging:i=1 \loop + \xdef\tagging:tablecolheaders{\tagging:tablecolheaders + {\the\numexpr\tagging:tablecol-\tagging:tablecolspan+\tagging:i}{\tagging:thecelid}}% + \advance\tagging:i1 \unless\ifnum\tagging:i>\tagging:tablecolspan\repeat} +\def\markrowhead{% + \tagging:setcelid + \tagattribute Table Scope /Row\relax + \tagging:i=0 \loop + \xdef\tagging:tablerowheaders{\tagging:tablerowheaders + {\the\numexpr\tagging:tablerow+\tagging:i}{\tagging:thecelid}}% + \advance\tagging:i1 \ifnum\tagging:i<\tagging:tablerowspan\repeat} +\def\tagging:setcelid{% + % assign an identifier to the cell structure element + \edef\tagging:thecelid{t\the\tagging:tablec r\the\tagging:tablerow c\the\tagging:tablecol}% + \expandafter\settagid\expandafter{\tagging:thecelid}} + +% assign cells to their headers \def\tagging:assignheaders{% - % TODO - } + \def\tagging:tmp{[}% + \expandafter\tagging:assignheaders:do\expandafter\tagging:tablecol + \tagging:tablecolheaders{}{}% + \expandafter\tagging:assignheaders:do\expandafter\tagging:tablerow + \tagging:tablerowheaders{}{}% + \ifx\tagging:tmp\tagging:noheaders\else + \tagattribute Table Headers {\tagging:tmp\space]}\fi} +\def\tagging:assignheaders:do#1#2#3{% + \ifx\tagging:noheaders#3\tagging:noheaders + \expandafter\tagging:assignheaders:done + \else + \ifnum#1=#2\relax + % no cell is its own header + \edef\tagging:cmp:a{\tagging:thecelid}% + \edef\tagging:cmp:b{#3}% + \unless\ifx\tagging:cmp:a\tagging:cmp:b + \edef\tagging:tmp{\tagging:tmp\space\pdfstring{#3}}% + \fi + \fi + \fi\tagging:assignheaders:do{#1}} +\def\tagging:noheaders{[}%] +\def\tagging:assignheaders:done#1#2{} +\def\tagging:thecelid{} % \automarktable \halign ... { ... } \def\automarktable#1#{\marktable \def\tagging:table{\tagging:mktrow{#1}}% \afterassignment\tagging:table - \let\tagging:tmp= } + \let\tagging:tmp= }% eats a bgroup \def\tagging:mktrow#1#2\cr{\iftrue - \tagging:mktcell{#1\bgroup\marktablerow\marktablecell#2}\fi + \tagging:mktcell{#1\bgroup % \halign ... + \marktablerow\marktablecell#2}\fi #3&\tagging:mktrow&\cr} \def\tagging:mktcell#1#2\fi#3&{\fi + % the next ifx is true on the last (artificial) template cell \ifx\tagging:mktrow#3\tagging:mkthdr{#1}\fi + % the next ifx detects a double && (repeated template) \ifx\tagging:mktrow#3\tagging:mktrow \tagging:mktcell{#1&}\else \tagging:mktcell{#1&\marktablecell#3}\fi} @@ -228,7 +291,7 @@ \def\marktableaslist#1#{\startelement{L}% \def\tagging:table{\tagging:mktlist{#1}}% \afterassignment\tagging:table - \let\tagging:tmp= } + \let\tagging:tmp= }% eats a bgroup \def\tagging:mktlist#1#2&{#1\bgroup \startelement{LI}\savecurrentelementto\tagging:li \startelement{Lbl}#2&\continueelementfrom\tagging:li @@ -254,6 +317,7 @@ \newif \iftagging:indisplay \newif \iftagging:toplevelmath \tagging:toplevelmathtrue \newif \iftagging:formulaenabled +\newif \iftagging:tagthisformula \tagging:tagthisformulatrue \let\startformulatagging = \tagging:formulaenabledtrue \let\stopformulatagging = \tagging:formulaenabledfalse \newcount \tagging:formulanr @@ -269,36 +333,51 @@ \def\tagging:startformula\fi\fi\fi#1${\tagging:makeformula{#1}{$}} \def\tagging:startdisplay\fi\fi\fi#1$${\tagging:makeformula{#1}{$$}} \def\tagging:makeformula#1#2{\fi\fi\fi - \global\advance\tagging:formulanr1\relax - \startelement attr Layout Placement \iftagging:indisplay/Block\else/Inline - % some html converters ignore Placement attributes - attr CSS-2.00 display (inline)\fi{Formula}% - \formulasource:set{#1}% + \tagging:tagformula{#1}% \scantextokens{#1}#2} +\def\tagging:tagformula#1{% + \iftagging:formulaenabled + \global\advance\tagging:formulanr1\relax + \startelement attr Layout Placement \iftagging:indisplay/Block\else/Inline + % some html converters ignore Placement attributes + attr CSS-2.00 display (inline)\fi{Formula}% + \formulasource:set{#1}\fi} \def\tagging:formulasource#1{% $\iftagging:indisplay$\fi \unexpanded{#1}% $\iftagging:indisplay$\fi} -% \includeformulasources {none|actualtext|attachment|both} -\def\includeformulasources#1{% - \expandafter\let - \expandafter\formulasource:set - \csname formulasource:#1\endcsname} -\def\formulasource:none#1{} +% \includeformulasources {alttext,actualtext,attachment} +\def\formulasource:set#1{% + \begingroup + % strip \setalttext, \setactualtext + \def\setalttext#1{}\def\setactualtext#1{}% + \xdef\formulasource:thesource{#1}% + \endgroup + \expandafter\splitcommalist + \expandafter\formulasource:do + \expandafter{\the\includeformulasources}} +\def\formulasource:do#1{% + \expandafter\expandafter \csname formulasource:#1\endcsname + \expandafter{\formulasource:thesource}} \def\formulasource:actualtext#1{% \setactualtext{\tagging:formulasource{#1}}} +\def\formulasource:alttext#1{% + \setalttext{\tagging:formulasource{#1}}} \def\formulasource:attachment#1{% \ifnum3=\pdfaconformancelevel \embedfile mimetype text/x-tex relation Source desc {Equation source} name {\formulafilename.tex} string {\tagging:formulasource{#1}}\fi} +\newtoks\includeformulasources +\includeformulasources{actualtext,attachment} + +% for compatibility with earlier versions (DO NOT USE) +\def\formulasource:none#1{} \def\formulasource:both#1{% \formulasource:actualtext{#1}% \formulasource:attachment{#1}} -\includeformulasources{both} - % 1 hyperlinks diff --git a/Master/texmf-dist/tex/luatex/minim/minim-alloc.lua b/Master/texmf-dist/tex/luatex/minim/minim-alloc.lua index 3775aafa437..ce53e5d4407 100644 --- a/Master/texmf-dist/tex/luatex/minim/minim-alloc.lua +++ b/Master/texmf-dist/tex/luatex/minim/minim-alloc.lua @@ -262,13 +262,14 @@ local function make_alloc_old(fname, globcount) end -- existing allocation counters -make_alloc_old ('count', 260 ) -make_alloc_old ('dimen', 261 ) -make_alloc_old ('skip', 262 ) -make_alloc_old ('muskip', 263 ) -make_alloc_old ('box', 264 ) -make_alloc_old ('toks', 265 ) -make_alloc_old ('marks', 266 ) +local globoffset = tex.count['alloc:globoffset'] +make_alloc_old ('count', globoffset + 0 ) +make_alloc_old ('dimen', globoffset + 1 ) +make_alloc_old ('skip', globoffset + 2 ) +make_alloc_old ('muskip', globoffset + 3 ) +make_alloc_old ('box', globoffset + 4 ) +make_alloc_old ('toks', globoffset + 5 ) +make_alloc_old ('marks', globoffset + 6 ) function M.luadef (csname, fn, ...) local nr = M.new_function(csname) diff --git a/Master/texmf-dist/tex/luatex/minim/minim-alloc.tex b/Master/texmf-dist/tex/luatex/minim/minim-alloc.tex index 4110301413e..1b3ca067958 100644 --- a/Master/texmf-dist/tex/luatex/minim/minim-alloc.tex +++ b/Master/texmf-dist/tex/luatex/minim/minim-alloc.tex @@ -85,7 +85,6 @@ \def\ProvidesFile#1{\begincsname minim:intercept:#1\endcsname \minim:providesfile{#1}} - % repair ltluatex, which, without apparent reason, resets all allocation % counters, even if they already exist \expandafter\def\csname minim:intercept:ltluatex.tex\endcsname @@ -109,8 +108,15 @@ % 1 allocation -% use global allocation (see etex.src) -\ifdefined \globcount +% used on the lua side by make_alloc_old +\newcount \alloc:globoffset +\alloc:globoffset = 260 + +\ifdefined \documentclass + % latex has no \globcount etc. + \alloc:globoffset = 10 +\else \ifdefined \globcount + % use global allocation (see etex.src) \let\newcount = \globcount \let\newdimen = \globdimen \let\newskip = \globskip @@ -118,7 +124,7 @@ \let\newbox = \globbox \let\newtoks = \globtoks \let\newmarks = \globmarks -\fi +\fi \fi % new allocation macros @@ -153,6 +159,8 @@ % those ourselves: \ifnum\csname e@alloc@ccodetable@count\endcsname = 0 \csname e@alloc@ccodetable@count\endcsname = 4 \fi +% an empty table +\newcatcodetable \minim:initcatcodes % set initial chunk name value \def\chardef:chunk#1#2{\chardef#1#2\directlua{lua.name[\the#2]='\csstring#1'}} diff --git a/Master/texmf-dist/tex/luatex/minim/minim-doc.sty b/Master/texmf-dist/tex/luatex/minim/minim-doc.sty index 5da6494c5e2..97b173beac0 100644 --- a/Master/texmf-dist/tex/luatex/minim/minim-doc.sty +++ b/Master/texmf-dist/tex/luatex/minim/minim-doc.sty @@ -59,7 +59,7 @@ \scriptfont 0 = \tenmaths \scriptscriptfont 0 = \tenmathss -\expandglyphsinfont \tenrm 40 25 5 +\expandglyphsinfont \tenrm 25 25 5 \protrudechars=2 \adjustspacing=2 \tenrm diff --git a/Master/texmf-dist/tex/luatex/minim/minim.ini b/Master/texmf-dist/tex/luatex/minim/minim.ini index 26aed3a2c58..e8017cc8f56 100644 --- a/Master/texmf-dist/tex/luatex/minim/minim.ini +++ b/Master/texmf-dist/tex/luatex/minim/minim.ini @@ -7,7 +7,7 @@ \input minim-plain \unless\ifdefined\fmtversion - \def\fmtversion{2021/1.0}\fi + \def\fmtversion{2023/1.3}\fi \suppressoutererror = 1 \input minim-etex -- cgit v1.2.3