diff options
Diffstat (limited to 'tex')
41 files changed, 2031 insertions, 211 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 86a342700..aee36ce61 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2021.08.07 22:49} +\newcontextversion{2021.08.10 12:37} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 0fe42e4a1..ec8a50d33 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2021.08.07 22:49} +\edef\contextversion{2021.08.10 12:37} %D For those who want to use this: diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii index 0390fcdbc..861f90c55 100644 --- a/tex/context/base/mkii/mult-fr.mkii +++ b/tex/context/base/mkii/mult-fr.mkii @@ -79,6 +79,7 @@ \setinterfacevariable{anchor}{ancre} \setinterfacevariable{and}{et} \setinterfacevariable{answerarea}{zonereponse} +\setinterfacevariable{append}{append} \setinterfacevariable{appendices}{annexes} \setinterfacevariable{appendix}{annexe} \setinterfacevariable{april}{avril} @@ -207,6 +208,8 @@ \setinterfacevariable{fixed}{fixe} \setinterfacevariable{flexible}{flexible} \setinterfacevariable{float}{flottant} +\setinterfacevariable{flushbackward}{flushbackward} +\setinterfacevariable{flushforward}{flushforward} \setinterfacevariable{flushinner}{alignerinterieur} \setinterfacevariable{flushleft}{alignergauche} \setinterfacevariable{flushouter}{alignerexterieur} @@ -434,6 +437,7 @@ \setinterfacevariable{postscript}{postscript} \setinterfacevariable{precedingpage}{pageantecedent} \setinterfacevariable{preference}{preference} +\setinterfacevariable{prepend}{prepend} \setinterfacevariable{preview}{apercu} \setinterfacevariable{previous}{precedent} \setinterfacevariable{previousevenpage}{pagepaireprecedente} @@ -1365,6 +1369,8 @@ \setinterfaceelement{load}{charger} \setinterfaceelement{local}{local} \setinterfaceelement{makeup}{composition} +\setinterfaceelement{namednotation}{namednotation} +\setinterfaceelement{namedtyping}{namedtyping} \setinterfaceelement{next}{suivant} \setinterfaceelement{place}{placer} \setinterfaceelement{previous}{precedent} @@ -1533,6 +1539,7 @@ \setinterfacecommand{definereferencelist}{définirlistereference} \setinterfacecommand{defineregister}{définirregistre} \setinterfacecommand{definerule}{définirtrait} +\setinterfacecommand{definesavebuffer}{startsavebuffer} \setinterfacecommand{definesection}{définirsection} \setinterfacecommand{definesectionblock}{définirblocsection} \setinterfacecommand{definesorting}{définirtri} @@ -1709,6 +1716,9 @@ \setinterfacecommand{moveformula}{deplacerformule} \setinterfacecommand{moveongrid}{deplacersurgrille} \setinterfacecommand{movesidefloat}{deplacerflottantcote} +\setinterfacecommand{namedconstruction}{namedconstruction} +\setinterfacecommand{nameddescription}{nameddescription} +\setinterfacecommand{namedenumeration}{namedenumeration} \setinterfacecommand{navigating}{navigation} \setinterfacecommand{nodimension}{sansdimension} \setinterfacecommand{noheaderandfooterlines}{sansentêtenipdp} @@ -2080,6 +2090,13 @@ \setinterfacecommand{startmakeup}{débutcomposition} \setinterfacecommand{startmarginblock}{débutblocmarge} \setinterfacecommand{startmarginrule}{débuttraitmarge} +\setinterfacecommand{startnamedconstruction}{startnamedconstruction} +\setinterfacecommand{startnameddescription}{startnameddescription} +\setinterfacecommand{startnamedenumeration}{startnamedenumeration} +\setinterfacecommand{startnamedmatrix}{startnamedmatrix} +\setinterfacecommand{startnamedsection}{startnamedsection} +\setinterfacecommand{startnamedsubformulas}{startnamedsubformulas} +\setinterfacecommand{startnamedtyping}{startnamedtyping} \setinterfacecommand{startnarrower}{débutplusetroit} \setinterfacecommand{startopposite}{débutopposition} \setinterfacecommand{startoverlay}{débutsuperposition} @@ -2123,6 +2140,13 @@ \setinterfacecommand{stopmakeup}{fincomposition} \setinterfacecommand{stopmarginblock}{finblocmarge} \setinterfacecommand{stopmarginrule}{fintraitmarge} +\setinterfacecommand{stopnamedconstruction}{stopnamedconstruction} +\setinterfacecommand{stopnameddescription}{stopnameddescription} +\setinterfacecommand{stopnamedenumeration}{stopnamedenumeration} +\setinterfacecommand{stopnamedmatrix}{stopnamedmatrix} +\setinterfacecommand{stopnamedsection}{stopnamedsection} +\setinterfacecommand{stopnamedsubformulas}{stopnamedsubformulas} +\setinterfacecommand{stopnamedtyping}{stopnamedtyping} \setinterfacecommand{stopnarrower}{finplusetroit} \setinterfacecommand{stopopposite}{finopposition} \setinterfacecommand{stopoverlay}{finsuperposition} diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index b3b71009e..61325b615 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.08.07 22:49} +\newcontextversion{2021.08.10 12:37} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index fb5f34e21..74e3cea56 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -45,7 +45,7 @@ %D {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2021.08.07 22:49} +\edef\contextversion{2021.08.10 12:37} %D Kind of special: diff --git a/tex/context/base/mkiv/core-con.lua b/tex/context/base/mkiv/core-con.lua index 244ede469..ac185e80b 100644 --- a/tex/context/base/mkiv/core-con.lua +++ b/tex/context/base/mkiv/core-con.lua @@ -1152,6 +1152,8 @@ local ordinals = { french = function(n) if n == 1 then return "er" + else + return "e" end end, } diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index 8b01d92b7..8ae4d755b 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -707,6 +707,7 @@ do local y = 0 local width = false local lsb = 0 +local result = { } local r = 0 local stems = 0 local globalbias = 0 @@ -2128,7 +2129,6 @@ do end process(tab) - if hack then return x, y end @@ -2151,6 +2151,7 @@ do r = r + 1 result[r] = c_endchar local stream = concat(result) +result = nil -- if trace_charstrings then -- report("vdata: %s",stream) -- end @@ -2177,6 +2178,7 @@ do name = charset and charset[index] or nil, -- sidebearing = 0, } +result = nil else glyphs[index] = { boundingbox = boundingbox, diff --git a/tex/context/base/mkiv/font-lig.lua b/tex/context/base/mkiv/font-lig.lua index 1aed9fc5b..b753b881d 100644 --- a/tex/context/base/mkiv/font-lig.lua +++ b/tex/context/base/mkiv/font-lig.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['font-lig'] = { license = "see context related readme files", } --- This module is not loaded but generated a file for plain TeX as a substitute +-- This module is not loaded but generates a file for plain TeX as a substitute -- for collapsing the input: "luatex-fonts-lig.lua" with "collapse=yes". local next = next diff --git a/tex/context/base/mkiv/grph-fil.lua b/tex/context/base/mkiv/grph-fil.lua index 1044d29d9..2cf2a54cc 100644 --- a/tex/context/base/mkiv/grph-fil.lua +++ b/tex/context/base/mkiv/grph-fil.lua @@ -90,7 +90,21 @@ local function analyzed(name) } end -function jobfiles.run(action) +function jobfiles.run(name,action) + local kind = type(name) + if kind == "string" then + local usedname = addsuffix(name,inputsuffix) + action = { + filename = usedname, + action = action, + resultfile = replacesuffix(usedname,resultsuffix), + } + elseif kind == "table" then + action = name + else + report_run("invalid specification for jobfiles.run") + return + end local filename = action.filename local result = action.result local oldchecksum = collected[filename] @@ -121,7 +135,17 @@ function jobfiles.run(action) end end if tobedone then - runner(action) + kind = type(action) + if kind == "function" then + action(filename) + elseif kind == "string" and action ~= "" then + -- can be anything but we assume it gets checked by the sandbox + os.execute(action) + elseif kind == "table" then + runner(action) + else + report_run("processing file, no action given for processing %a",name) + end elseif trace_run then report_run("processing file, no changes in %a, not processed",name) end diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index d8db74701..5985faf73 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -28,6 +28,8 @@ return { -- "emptytoks", "empty", "undefined", -- + "prerollrun", + -- "voidbox", "emptybox", "emptyvbox", "emptyhbox", -- "bigskipamount", "medskipamount", "smallskipamount", diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 52574e768..408c1d651 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -367,9 +367,9 @@ return { "ifcmpnum", "ifcondition", "ifcstok", + "ifdimexpression", "ifdimval", "ifempty", - "ifexpression", "ifflags", "ifhastok", "ifhastoks", @@ -378,6 +378,7 @@ return { "ifinsert", "ifmathparameter", "ifmathstyle", + "ifnumexpression", "ifnumval", "ifparameter", "ifparameters", @@ -416,7 +417,6 @@ return { "letprotected", "lettonothing", "linedirection", - "linepar", "localbrokenpenalty", "localcontrol", "localcontrolled", @@ -471,6 +471,7 @@ return { "overloaded", "overloadmode", "parametercount", + "parametermark", "parattribute", "pardirection", "permanent", diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 654c04404..67e5b7a47 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex de0ad44a4..42d1b8d7b 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua index 67146d80f..471b76296 100644 --- a/tex/context/base/mkiv/util-str.lua +++ b/tex/context/base/mkiv/util-str.lua @@ -624,22 +624,24 @@ return function(%s) return %s end -- We only use fast serialize in controlled cases. --- local pattern = Cs(Cc('"') * ( --- (1-S('"\\\n\r'))^1 --- + P('"') / '\\"' --- + P('\\') / '\\\\' --- + P('\n') / '\\n' --- + P('\r') / '\\r' --- )^0 * Cc('"')) - local pattern = Cs(Cc('"') * ( (1-S('"\\\n\r'))^1 - + P('"') / '\\034' - + P('\\') / '\\092' - + P('\n') / '\\013' - + P('\r') / '\\010' + + P('"') / '\\"' + + P('\\') / '\\\\' + + P('\n') / '\\n' + + P('\r') / '\\r' )^0 * Cc('"')) +-- -- I need to do more experiments with this: +-- +-- local pattern = Cs(Cc('"') * ( +-- (1-S('"\\\n\r'))^1 +-- + P('"') / '\\034' +-- + P('\\') / '\\092' +-- + P('\n') / '\\013' +-- + P('\r') / '\\010' +-- )^0 * Cc('"')) + patterns.escapedquotes = pattern function string.escapedquotes(s) diff --git a/tex/context/base/mkxl/back-exp.lmt b/tex/context/base/mkxl/back-exp.lmt index 01a885471..a465cee92 100644 --- a/tex/context/base/mkxl/back-exp.lmt +++ b/tex/context/base/mkxl/back-exp.lmt @@ -100,12 +100,12 @@ local overloads = fonts.mappings.overloads -- todo: more locals (and optimize) -local exportversion = "0.35" -local mathmlns = "http://www.w3.org/1998/Math/MathML" -local contextns = "http://www.contextgarden.net/context/export" -- whatever suits -local cssnamespaceurl = "@namespace context url('%namespace%') ;" -local cssnamespace = "context|" ------ cssnamespacenop = "/* no namespace */" +local exportversion <const> = "0.35" +local mathmlns <const> = "http://www.w3.org/1998/Math/MathML" +local contextns <const> = "http://www.contextgarden.net/context/export" -- whatever suits +local cssnamespaceurl <const> = "@namespace context url('%namespace%') ;" +local cssnamespace <const> = "context|" +----- cssnamespacenop <const> = "/* no namespace */" local usecssnamespace = false @@ -296,7 +296,7 @@ structurestags.backend = { destinationhash = destinationhash, } -local namespacetemplate = [[ +local namespacetemplate <const> = [[ /* %what% for file %filename% */ %cssnamespaceurl% @@ -312,7 +312,7 @@ do -- /* text-justify : inter-word ; */ -- /* text-align : justify ; */ -local documenttemplate = [[ +local documenttemplate <const> = [[ document, %namespace%div.document { font-size : %size% !important ; @@ -321,7 +321,7 @@ document, hyphens : %hyphens% !important ; }]] -local styletemplate = [[ +local styletemplate <const> = [[ %element%[detail="%detail%"], %namespace%div.%element%.%detail% { display : inline ; @@ -409,7 +409,7 @@ end do -local imagetemplate = [[ +local imagetemplate <const> = [[ %element%[id="%id%"], %namespace%div.%element%[id="%id%"] { display : block ; background-image : url('%url%') ; @@ -1983,7 +1983,7 @@ local cssheadlink = [[ return concat(result), concat(extras) end -local elementtemplate = [[ +local elementtemplate <const> = [[ /* element="%element%" detail="%detail%" chain="%chain%" */ %element%, @@ -1991,7 +1991,7 @@ local elementtemplate = [[ display: %display% ; }]] -local detailtemplate = [[ +local detailtemplate <const> = [[ /* element="%element%" detail="%detail%" chain="%chain%" */ %element%[detail=%detail%], @@ -2001,7 +2001,7 @@ local detailtemplate = [[ -- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd" > -local htmltemplate = [[ +local htmltemplate <const> = [[ %preamble% <html xmlns="http://www.w3.org/1999/xhtml" xmlns:math="http://www.w3.org/1998/Math/MathML"> diff --git a/tex/context/base/mkxl/catc-def.mkxl b/tex/context/base/mkxl/catc-def.mkxl index a7d48714a..896dd35d3 100644 --- a/tex/context/base/mkxl/catc-def.mkxl +++ b/tex/context/base/mkxl/catc-def.mkxl @@ -17,6 +17,9 @@ %D days of \LUATEX) was dropped when I realized that there is not common ground to %D cover between formats. It is simply not worth the trouble. +%D Maybe we also need a copy of \type {\ctxcatcodes} so that we can always go back +%D to the unpatched regime. + \ifdefined\nilcatcodes \else \newcatcodetable \nilcatcodes \fi \ifdefined\texcatcodes \else \newcatcodetable \texcatcodes \fi \ifdefined\luacatcodes \else \newcatcodetable \luacatcodes \fi diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl index c9a545148..74d3aa873 100644 --- a/tex/context/base/mkxl/cont-new.mkxl +++ b/tex/context/base/mkxl/cont-new.mkxl @@ -13,7 +13,7 @@ % \normalend % uncomment this to get the real base runtime -\newcontextversion{2021.08.07 22:49} +\newcontextversion{2021.08.10 12:37} %D This file is loaded at runtime, thereby providing an excellent place for hacks, %D patches, extensions and new features. There can be local overloads in cont-loc diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl index 8c2bcc2aa..91ec43d30 100644 --- a/tex/context/base/mkxl/context.mkxl +++ b/tex/context/base/mkxl/context.mkxl @@ -29,7 +29,7 @@ %D {YYYY.MM.DD HH:MM} format. \immutable\edef\contextformat {\jobname} -\immutable\edef\contextversion{2021.08.07 22:49} +\immutable\edef\contextversion{2021.08.10 12:37} %overloadmode 1 % check frozen / warning %overloadmode 2 % check frozen / error @@ -121,7 +121,7 @@ %D This needs more checking for clashes: %D %D \starttyping -%D \doifelsefileexists{l-macro-imp-codes-luametatex.lua}{\registerctxluafile{l-macro-imp-codes-luametatex}{}}{} +% \doifelsefileexists{l-macro-imp-codes-luametatex.lua}{\registerctxluafile{l-macro-imp-codes-luametatex}{}}{} %D \stoptyping \loadmkxlfile{supp-dir} diff --git a/tex/context/base/mkxl/core-sys.mkxl b/tex/context/base/mkxl/core-sys.mkxl index 832098315..a0bd9debd 100644 --- a/tex/context/base/mkxl/core-sys.mkxl +++ b/tex/context/base/mkxl/core-sys.mkxl @@ -291,13 +291,18 @@ \aliased\let\directhighlight\typo_highlights_indeed + \permanent\protected\def\defineexpandable - {\doifelsenextoptional + {\integerdef\c_syst_parameter_catcode\catcode\hashasciicode + \catcode\hashasciicode\parametercatcode% + \doifelsenextoptional {\syst_basics_define_yes\def}% {\syst_basics_define_nop\def}} \permanent\protected\def\define - {\doifelsenextoptional + {\integerdef\c_syst_parameter_catcode\catcode\hashasciicode + \catcode\hashasciicode\parametercatcode% + \doifelsenextoptional {\syst_basics_define_yes{\protected\def}}% {\syst_basics_define_nop{\protected\def}}} @@ -316,13 +321,15 @@ #1#3##1##2##3##4##5##6##7{#4}\or #1#3##1##2##3##4##5##6##7##8{#4}\or #1#3##1##2##3##4##5##6##7##8##9{#4}\else - #1#3{#4}\fi} + #1#3{#4}\fi + \catcode\hashasciicode\c_syst_parameter_catcode} \protected\def\syst_basics_define_nop#1#2#3% {\ifdefined#2% \showmessage\m!system4{\string#2}% \fi - #1#2{#3}} + #1#2{#3}% + \catcode\hashasciicode\c_syst_parameter_catcode} \aliased\let\redefine\define diff --git a/tex/context/base/mkxl/grph-inc.lmt b/tex/context/base/mkxl/grph-inc.lmt index 6700a1171..0b83718f8 100644 --- a/tex/context/base/mkxl/grph-inc.lmt +++ b/tex/context/base/mkxl/grph-inc.lmt @@ -305,8 +305,8 @@ local converters = allocate() figures.converters = converters local identifiers = allocate() figures.identifiers = identifiers local programs = allocate() figures.programs = programs -local defaultformat = "pdf" -local defaultprefix = "m_k_i_v_" +local defaultformat <const> = "pdf" +local defaultprefix <const> = "m_k_i_v_" figures.localpaths = allocate { ".", "..", "../.." diff --git a/tex/context/base/mkxl/lpdf-emb.lmt b/tex/context/base/mkxl/lpdf-emb.lmt index daa7e41a1..c715c7b77 100644 --- a/tex/context/base/mkxl/lpdf-emb.lmt +++ b/tex/context/base/mkxl/lpdf-emb.lmt @@ -133,7 +133,7 @@ do local tounicode = fonts.mappings.tounicode -local tounicode_template = [[ +local tounicode_template <const> = [[ %%!PS-Adobe-3.0 Resource-CMap %%%%DocumentNeededResources: ProcSet (CIDInit) %%%%IncludeResource: ProcSet (CIDInit) @@ -448,7 +448,7 @@ do "fullname", "postscriptname", } - local template = [[ + local template <const> = [[ <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?> <x:xmpmeta xmlns:x="adobe:ns:meta/"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> diff --git a/tex/context/base/mkxl/lpdf-fld.lmt b/tex/context/base/mkxl/lpdf-fld.lmt index fd671b747..13ebd6c44 100644 --- a/tex/context/base/mkxl/lpdf-fld.lmt +++ b/tex/context/base/mkxl/lpdf-fld.lmt @@ -674,7 +674,7 @@ end local fields, radios, clones, fieldsets, calculationset = { }, { }, { }, { }, nil -local xfdftemplate = [[ +local xfdftemplate <const> = [[ <?xml version='1.0' encoding='UTF-8'?> <xfdf xmlns='http://ns.adobe.com/xfdf/'> diff --git a/tex/context/base/mkxl/lpdf-ini.lmt b/tex/context/base/mkxl/lpdf-ini.lmt index 35ed22222..ce679c08e 100644 --- a/tex/context/base/mkxl/lpdf-ini.lmt +++ b/tex/context/base/mkxl/lpdf-ini.lmt @@ -1221,11 +1221,12 @@ do local f_actual_text_p = formatters["BT /Span << /ActualText <feff%s> >> BDC %s EMC ET"] local f_actual_text_b = formatters["BT /Span << /ActualText <feff%s> >> BDC"] - local s_actual_text_e = "EMC ET" local f_actual_text_b_not = formatters["/Span << /ActualText <feff%s> >> BDC"] - local s_actual_text_e_not = "EMC" local f_actual_text = formatters["/Span <</ActualText %s >> BDC"] + local s_actual_text_e <const> = "EMC ET" + local s_actual_text_e_not <const> = "EMC" + local context = context local pdfdirect = nodes.pool.directliteral -- we can use nuts.write deep down local tounicode = fonts.mappings.tounicode diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt index f722a61e0..826c1ce21 100644 --- a/tex/context/base/mkxl/lpdf-lmt.lmt +++ b/tex/context/base/mkxl/lpdf-lmt.lmt @@ -815,9 +815,9 @@ do local nodeproperties = nodes.properties.data - local s_matrix_0 = "1 0 0 1 0 0 cm" - local f_matrix_2 = formatters["%.6N 0 0 %.6N 0 0 cm"] - local f_matrix_4 = formatters["%.6N %.6N %.6N %.6N 0 0 cm"] + local s_matrix_0 <const> = "1 0 0 1 0 0 cm" + local f_matrix_2 = formatters["%.6N 0 0 %.6N 0 0 cm"] + local f_matrix_4 = formatters["%.6N %.6N %.6N %.6N 0 0 cm"] local flushsetmatrix = function(current,pos_h,pos_v) local p = nodeproperties[current] @@ -1013,8 +1013,8 @@ local flushimage do local f_im = formatters["/Im%d Do"] local f_gr = formatters["/Gp%d Do"] - local s_b = "q" - local s_e = "Q" + local s_b <const> = "q" + local s_e <const> = "Q" local f_v = formatters["[] 0 d 0 J %.6N w 0 0 m %.6N 0 l S"] local f_h = formatters["[] 0 d 0 J %.6N w 0 0 m 0 %.6N l S"] @@ -1939,8 +1939,8 @@ local f_stream_b_d_u = formatters["%i 0 obj\010<< %s /Length %i >>\010stream\010 local f_stream_b_d_c = formatters["%i 0 obj\010<< %s /Filter /FlateDecode /Length %i >>\010stream\010"] local f_stream_b_d_r = formatters["%i 0 obj\010<< %s >>\010stream\010"] ------ s_object_e = "\010endobj\010" -local s_stream_e = "\010endstream\010endobj\010" +----- s_object_e <const> = "\010endobj\010" +local s_stream_e <const> = "\010endstream\010endobj\010" do @@ -2466,6 +2466,9 @@ local openfile, closefile do local close = false local update = false + -- local banner <const> = "%\xCC\xD5\xC1\xD4\xC5\xD8\xD0\xC4\xC6\010" -- LUATEXPDF (+128) + local banner <const> = "%\xC3\xCF\xCE\xD4\xC5\xD8\xD4\xD0\xC4\xC6\010" -- CONTEXTPDF (+128) + -- local removefile = os.remove openfile = function(filename) @@ -2512,12 +2515,10 @@ local openfile, closefile do f:write(s) end end - local v = f_pdf_tag(majorversion,minorversion) - -- local b = "%\xCC\xD5\xC1\xD4\xC5\xD8\xD0\xC4\xC6\010" -- LUATEXPDF (+128) - local b = "%\xC3\xCF\xCE\xD4\xC5\xD8\xD4\xD0\xC4\xC6\010" -- CONTEXTPDF (+128) - flush(f,v) - flush(f,b) - offset = offset + #v + #b + local version = f_pdf_tag(majorversion,minorversion) + flush(f,version) + flush(f,banner) + offset = offset + #version + #banner end closefile = function(abort) diff --git a/tex/context/base/mkxl/lpdf-xmp.lmt b/tex/context/base/mkxl/lpdf-xmp.lmt index 776bdff4f..deeb1e135 100644 --- a/tex/context/base/mkxl/lpdf-xmp.lmt +++ b/tex/context/base/mkxl/lpdf-xmp.lmt @@ -241,10 +241,11 @@ local function flushxmpinfo() local documentid = "no unique document id here" local instanceid = "no unique instance id here" - local metadata = pdfgetmetadata() - local time = metadata.time - local producer = metadata.producer - local creator = metadata.creator + + local metadata = pdfgetmetadata() + local time = metadata.time + local producer = metadata.producer + local creator = metadata.creator if included.id ~= "fake" then documentid = "uuid:" .. os.uuid() diff --git a/tex/context/base/mkxl/mlib-pps.lmt b/tex/context/base/mkxl/mlib-pps.lmt index 19535b070..bad738bc1 100644 --- a/tex/context/base/mkxl/mlib-pps.lmt +++ b/tex/context/base/mkxl/mlib-pps.lmt @@ -117,7 +117,8 @@ local f_scn = formatters["%.3N"] local f_shade = formatters["MpSh%s"] local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"] -local s_cm_e = "Q" + +local s_cm_e <const> = "Q" local function checked_color_pair(color,...) if not color then @@ -529,9 +530,9 @@ metapost.sxsy = sxsy -- for stock mp we need to declare the booleans first -local do_begin_fig = "; beginfig(1) ; " -local do_end_fig = "; endfig ;" -local do_safeguard = ";" +local do_begin_fig <const> = "; beginfig(1) ; " +local do_end_fig <const> = "; endfig ;" +local do_safeguard <const> = ";" function metapost.preparetextextsdata() local textexts = top.textexts diff --git a/tex/context/base/mkxl/mlib-svg.lmt b/tex/context/base/mkxl/mlib-svg.lmt index 862bd1cad..945cafbab 100644 --- a/tex/context/base/mkxl/mlib-svg.lmt +++ b/tex/context/base/mkxl/mlib-svg.lmt @@ -142,9 +142,8 @@ local trace_fonts = false trackers.register("metapost.svg.fonts", function(v) -- This is just an experiment. Todo: reset hash etc. Also implement an option handler. -local s_draw_image_start = "draw image (" -local s_draw_image_stop = ") ;" - +local s_draw_image_start <const> = "draw image (" +local s_draw_image_stop <const> = ") ;" local ignoredopacity = 1 @@ -1207,34 +1206,34 @@ end -- todo: viewbox helper -local s_wrapped_start = s_draw_image_start -local f_wrapped_stop = formatters[") shifted (0,%N) scaled %N ;"] +local s_wrapped_start <const> = "draw image (" +local f_wrapped_stop = formatters[") shifted (0,%N) scaled %N ;"] local handletransform, handleviewbox do local sind = math.sind - -- local f_rotatedaround = formatters["svg_p := svg_p rotatedaround((%N,%N),%N) ;"] - -- local f_rotated = formatters["svg_p := svg_p rotated(%N) ;"] - -- local f_shifted = formatters["svg_p := svg_p shifted(%N,%N) ;"] - -- local f_slanted_x = formatters["svg_p := svg_p xslanted(%N) ;"] - -- local f_slanted_y = formatters["svg_p := svg_p yslanted(%N) ;"] - -- local f_scaled = formatters["svg_p := svg_p scaled(%N) ;"] - -- local f_xyscaled = formatters["svg_p := svg_p xyscaled(%N,%N) ;"] - -- local f_matrix = formatters["svg_p := svg_p transformed bymatrix(%N,%N,%N,%N,%N,%N) ;"] - -- local s_transform_start = "draw image ( begingroup ; save svg_p ; picture svg_p ; svg_p := image ( " - -- local f_transform_stop = formatters[" ; ) ; %s ; draw svg_p ; endgroup ; ) ; "] - - local f_rotatedaround = formatters["rotatedaround((%N,%N),%N) "] - local f_rotated = formatters["rotated(%N) "] - local f_shifted = formatters["shifted(%N,%N) "] - local f_slanted_x = formatters["xslanted(%N) "] - local f_slanted_y = formatters["yslanted(%N) "] - local f_scaled = formatters["scaled(%N) "] - local f_xyscaled = formatters["xyscaled(%N,%N) "] - local f_matrix = formatters["transformed bymatrix(%N,%N,%N,%N,%N,%N) "] - local s_transform_start = "draw image ( " - local f_transform_stop = formatters[") %s ; "] + -- local f_rotatedaround = formatters["svg_p := svg_p rotatedaround((%N,%N),%N) ;"] + -- local f_rotated = formatters["svg_p := svg_p rotated(%N) ;"] + -- local f_shifted = formatters["svg_p := svg_p shifted(%N,%N) ;"] + -- local f_slanted_x = formatters["svg_p := svg_p xslanted(%N) ;"] + -- local f_slanted_y = formatters["svg_p := svg_p yslanted(%N) ;"] + -- local f_scaled = formatters["svg_p := svg_p scaled(%N) ;"] + -- local f_xyscaled = formatters["svg_p := svg_p xyscaled(%N,%N) ;"] + -- local f_matrix = formatters["svg_p := svg_p transformed bymatrix(%N,%N,%N,%N,%N,%N) ;"] + -- local s_transform_start <const> = "draw image ( begingroup ; save svg_p ; picture svg_p ; svg_p := image ( " + -- local f_transform_stop = formatters[" ; ) ; %s ; draw svg_p ; endgroup ; ) ; "] + + local f_rotatedaround = formatters["rotatedaround((%N,%N),%N) "] + local f_rotated = formatters["rotated(%N) "] + local f_shifted = formatters["shifted(%N,%N) "] + local f_slanted_x = formatters["xslanted(%N) "] + local f_slanted_y = formatters["yslanted(%N) "] + local f_scaled = formatters["scaled(%N) "] + local f_xyscaled = formatters["xyscaled(%N,%N) "] + local f_matrix = formatters["transformed bymatrix(%N,%N,%N,%N,%N,%N) "] + local s_transform_start <const> = "draw image ( " + local f_transform_stop = formatters[") %s ; "] local transforms = { } local noftransforms = 0 @@ -1690,18 +1689,17 @@ do -- todo: clip = [ auto | rect(llx,lly,urx,ury) ] - local s_rotation_start = "draw image ( " - local f_rotation_stop = formatters[") rotatedaround((0,0),-angle((%N,%N))) ;"] - local f_rotation_angle = formatters[") rotatedaround((0,0),-%N) ;"] + local s_rotation_start <const> = "draw image ( " + local f_rotation_stop = formatters[") rotatedaround((0,0),-angle((%N,%N))) ;"] + local f_rotation_angle = formatters[") rotatedaround((0,0),-%N) ;"] - local s_offset_start = "draw image ( " - local f_offset_stop = formatters[") shifted (%N,%N) ;"] - local s_size_start = "draw image ( " - local f_size_stop = formatters[") xysized (%N,%N) ;"] + local s_offset_start <const> = "draw image ( " + local f_offset_stop = formatters[") shifted (%N,%N) ;"] + local s_size_start <const> = "draw image ( " + local f_size_stop = formatters[") xysized (%N,%N) ;"] local handleoffset, handlesize do - handleoffset = function(at) local x = asnumber_vx(rawget(at,"x")) local y = asnumber_vy(rawget(at,"y")) @@ -2018,9 +2016,9 @@ local fraction = offset and asnumber_p(offset) return p, d, c, o end - local s_opacity_start = s_draw_image_start - local f_opacity_content = formatters["setgroup currentpicture to boundingbox currentpicture withopacity %N;"] - local s_opacity_stop = s_draw_image_stop + local s_opacity_start <const> = "draw image (" + local f_opacity_content = formatters["setgroup currentpicture to boundingbox currentpicture withopacity %N;"] + local s_opacity_stop <const> = ") ;" local function sharedopacity(at) local o = at["opacity"] @@ -2073,11 +2071,11 @@ local fraction = offset and asnumber_p(offset) local viewport do - local s_viewport_start = s_draw_image_start - local s_viewport_stop = s_draw_image_stop - local f_viewport_shift = formatters["currentpicture := currentpicture shifted (%N,%N);"] - local f_viewport_scale = formatters["currentpicture := currentpicture xysized (%N,%N);"] - local f_viewport_clip = formatters["clip currentpicture to (unitsquare xyscaled (%N,%N));"] + local s_viewport_start <const> = "draw image (" + local s_viewport_stop <const> = ") ;" + local f_viewport_shift = formatters["currentpicture := currentpicture shifted (%N,%N);"] + local f_viewport_scale = formatters["currentpicture := currentpicture xysized (%N,%N);"] + local f_viewport_clip = formatters["clip currentpicture to (unitsquare xyscaled (%N,%N));"] viewport = function(x,y,w,h,noclip,scale) r = r + 1 ; result[r] = s_viewport_start @@ -2189,25 +2187,25 @@ setmetatableindex(res.at,at) end end - local f_no_draw = formatters[' nodraw (%s)'] - local f_do_draw = formatters[' draw (%s)'] - local f_no_fill_c = formatters[' nofill closedcurve(%s)'] - local f_do_fill_c = formatters[' fill closedcurve(%s)'] - local f_eo_fill_c = formatters[' eofill closedcurve(%s)'] - local f_no_fill_l = formatters[' nofill closedlines(%s)'] - local f_do_fill_l = formatters[' fill closedlines(%s)'] - local f_eo_fill_l = formatters[' eofill closedlines(%s)'] - local f_closed_draw = formatters[' draw closedcurve(%s)'] - local f_do_fill = f_do_fill_c - local f_eo_fill = f_eo_fill_c - local f_no_fill = f_no_fill_c - local s_clip_start = 'save p ; picture p ; p := image (' - local f_clip_stop_c = formatters[') ; clip p to closedcurve(%s) %s ; draw p ;'] - local f_clip_stop_l = formatters[') ; clip p to closedlines(%s) %s ; draw p ;'] - local f_clip_stop = f_clip_stop_c - local f_eoclip_stop_c = formatters[') ; eoclip p to closedcurve(%s) %s ; draw p ;'] - local f_eoclip_stop_l = formatters[') ; eoclip p to closedlines(%s) %s ; draw p ;'] - local f_eoclip_stop = f_eoclip_stop_c + local f_no_draw = formatters[' nodraw (%s)'] + local f_do_draw = formatters[' draw (%s)'] + local f_no_fill_c = formatters[' nofill closedcurve(%s)'] + local f_do_fill_c = formatters[' fill closedcurve(%s)'] + local f_eo_fill_c = formatters[' eofill closedcurve(%s)'] + local f_no_fill_l = formatters[' nofill closedlines(%s)'] + local f_do_fill_l = formatters[' fill closedlines(%s)'] + local f_eo_fill_l = formatters[' eofill closedlines(%s)'] + local f_closed_draw = formatters[' draw closedcurve(%s)'] + local f_do_fill = f_do_fill_c + local f_eo_fill = f_eo_fill_c + local f_no_fill = f_no_fill_c + local s_clip_start <const> = 'save p ; picture p ; p := image (' + local f_clip_stop_c = formatters[') ; clip p to closedcurve(%s) %s ; draw p ;'] + local f_clip_stop_l = formatters[') ; clip p to closedlines(%s) %s ; draw p ;'] + local f_clip_stop = f_clip_stop_c + local f_eoclip_stop_c = formatters[') ; eoclip p to closedcurve(%s) %s ; draw p ;'] + local f_eoclip_stop_l = formatters[') ; eoclip p to closedlines(%s) %s ; draw p ;'] + local f_eoclip_stop = f_eoclip_stop_c -- could be shared and then beginobject | endobject @@ -2258,8 +2256,8 @@ setmetatableindex(res.at,at) local f_linejoin = formatters[" interim linejoin := %s ;"] local f_miterlimit = formatters[" interim miterlimit := %s ;"] - local s_begingroup = "begingroup;" - local s_endgroup = "endgroup;" + local s_begingroup <const> = "begingroup;" + local s_endgroup <const> = "endgroup;" local linecaps = { butt = "butt", square = "squared", round = "rounded" } local linejoins = { miter = "mitered", bevel = "beveled", round = "rounded" } @@ -2658,8 +2656,8 @@ setmetatableindex(res.at,at) function handlers.polyline(c) poly(c, ")") end function handlers.polygon (c) poly(c,"--cycle)") end - local s_image_start = s_draw_image_start - local s_image_stop = s_draw_image_stop + local s_image_start <const> = "draw image (" + local s_image_stop <const> = ") ;" function handlers.path(c) local at = c.at @@ -2926,21 +2924,21 @@ setmetatableindex(res.at,at) do - local s_start = "\\svgstart " - local s_stop = "\\svgstop " - local f_set = formatters["\\svgset{%N}{%N}"] -- we need a period - local f_color_c = formatters["\\svgcolorc{%.3N}{%.3N}{%.3N}{"] - local f_color_o = formatters["\\svgcoloro{%.3N}{"] - local f_color_b = formatters["\\svgcolorb{%.3N}{%.3N}{%.3N}{%.3N}{"] - local f_poscode = formatters["\\svgpcode{%N}{%N}{%s}"] - local f_poschar = formatters["\\svgpchar{%N}{%N}{%s}"] - local f_posspace = formatters["\\svgpspace{%N}{%N}"] - local f_code = formatters["\\svgcode{%s}"] - local f_char = formatters["\\svgchar{%s}"] - local s_space = "\\svgspace " - local f_size = formatters["\\svgsize{%0.6f}"] -- we need a period - local f_font = formatters["\\svgfont{%s}{%s}{%s}"] - local f_hashed = formatters["\\svghashed{%s}"] + local s_start <const> = "\\svgstart " + local s_stop <const> = "\\svgstop " + local f_set = formatters["\\svgset{%N}{%N}"] -- we need a period + local f_color_c = formatters["\\svgcolorc{%.3N}{%.3N}{%.3N}{"] + local f_color_o = formatters["\\svgcoloro{%.3N}{"] + local f_color_b = formatters["\\svgcolorb{%.3N}{%.3N}{%.3N}{%.3N}{"] + local f_poscode = formatters["\\svgpcode{%N}{%N}{%s}"] + local f_poschar = formatters["\\svgpchar{%N}{%N}{%s}"] + local f_posspace = formatters["\\svgpspace{%N}{%N}"] + local f_code = formatters["\\svgcode{%s}"] + local f_char = formatters["\\svgchar{%s}"] + local s_space <const> = "\\svgspace " + local f_size = formatters["\\svgsize{%0.6f}"] -- we need a period + local f_font = formatters["\\svgfont{%s}{%s}{%s}"] + local f_hashed = formatters["\\svghashed{%s}"] ----- p_texescape = lpegpatterns.texescape diff --git a/tex/context/base/mkxl/node-fin.lmt b/tex/context/base/mkxl/node-fin.lmt index a7086b5b1..2e744a48a 100644 --- a/tex/context/base/mkxl/node-fin.lmt +++ b/tex/context/base/mkxl/node-fin.lmt @@ -79,7 +79,7 @@ nodes.plugindata = nil -- inheritance: -0x7FFFFFFF -- we can best use nil and skip ! -local template = [[ +local template <const> = [[ local plugin = nodes.plugindata local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming diff --git a/tex/context/base/mkxl/node-syn.lmt b/tex/context/base/mkxl/node-syn.lmt index df3abe3db..dfa1a19e8 100644 --- a/tex/context/base/mkxl/node-syn.lmt +++ b/tex/context/base/mkxl/node-syn.lmt @@ -180,19 +180,19 @@ local foundintree = resolvers.foundintree local getpagedimensions = layouts.getpagedimensions -local eol = "\010" +local eol <const> = "\010" ----- f_glue = formatters["g%i,%i:%i,%i\010"] ----- f_glyph = formatters["x%i,%i:%i,%i\010"] ----- f_kern = formatters["k%i,%i:%i,%i:%i\010"] ----- f_rule = formatters["r%i,%i:%i,%i:%i,%i,%i\010"] ----- f_form = formatters["f%i,%i,%i\010"] -local z_hlist = "[0,0:0,0:0,0,0\010" -local z_vlist = "(0,0:0,0:0,0,0\010" ------ z_xform = "<0,0:0,0,0\010" -- or so -local s_hlist = "]\010" -local s_vlist = ")\010" ------ s_xform = ">\010" +local z_hlist <const> = "[0,0:0,0:0,0,0\010" +local z_vlist <const> = "(0,0:0,0:0,0,0\010" +----- z_xform <const> = "<0,0:0,0,0\010" -- or so +local s_hlist <const> = "]\010" +local s_vlist <const> = ")\010" +----- s_xform <const> = ">\010" local f_hlist_1 = formatters["h%i,%i:%i,%i:%i,%i,%i\010"] local f_hlist_2 = formatters["h%i,%i:%i,%s:%i,%i,%i\010"] local f_vlist_1 = formatters["v%i,%i:%i,%i:%i,%i,%i\010"] diff --git a/tex/context/base/mkxl/pack-rul.mkxl b/tex/context/base/mkxl/pack-rul.mkxl index f1d8cbf31..42b472aa2 100644 --- a/tex/context/base/mkxl/pack-rul.mkxl +++ b/tex/context/base/mkxl/pack-rul.mkxl @@ -2763,12 +2763,12 @@ {\bgroup \edef\currentframedtext{#1} \doifelseassignment{#2} - {\pack_framed_text_start_continue\empty{#2}} - {\pack_framed_text_start_continue{#2}{#3}}} + {\pack_framed_text_start_indeed\empty{#2}} + {\pack_framed_text_start_indeed{#2}{#3}}} -% todo: sort out first/lastline ht/dp +% todo: sort out first/lastline ht/dp . . will be a more advanced mechanism some day (soon) -\def\pack_framed_text_start_continue#1#2% +\def\pack_framed_text_start_indeed#1#2% {\setupframedtexts[\currentframedtext][#2]% \doifsomething{#1}{\setframedtextparameter\c!location{#1}}% does not listen to #3 \setfalse\c_framed_text_location_none @@ -2790,7 +2790,7 @@ \else \bgroup \fi - \vskip-\strutdp % brrr why is this needed ... needs to be sorted out, see testcase 1 + % no longer: \vskip-\strutdp % brrr why is this needed ... needs to be sorted out, see testcase 1 \doinhibitblank \useindentingparameter\framedtextparameter \useframedtextstyleandcolor\c!style\c!color @@ -2903,7 +2903,7 @@ \blank[\v!disable]% \enforced\let\\\endgraf \useframedtextstyleandcolor\c!style\c!color - \vskip-\strutdp % brrr why is this needed ... needs to be sorted out, see testcase 1 + % no longer: \vskip-\strutdp % brrr why is this needed ... needs to be sorted out, see testcase 1 \framedtextparameter\c!inner \ifx\p_framed_text_strut\v!no \let\pack_framed_strut\relax diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt index 76d1ce9db..1af5096fb 100644 --- a/tex/context/base/mkxl/spac-ver.lmt +++ b/tex/context/base/mkxl/spac-ver.lmt @@ -751,9 +751,10 @@ do local k_fixed = variables.fixed local k_flexible = variables.flexible - local k_category = "category" - local k_penalty = "penalty" - local k_order = "order" + + local k_category <const> = "category" + local k_penalty <const> = "penalty" + local k_order <const> = "order" function vspacing.setmap(from,to) map[from] = to diff --git a/tex/context/base/mkxl/strc-ref.mklx b/tex/context/base/mkxl/strc-ref.mklx index 3b21ca07a..ad62a52e5 100644 --- a/tex/context/base/mkxl/strc-ref.mklx +++ b/tex/context/base/mkxl/strc-ref.mklx @@ -816,6 +816,10 @@ \newcount\locationorder \newbox \locationbox +\appendtoks + \locationfalse +\to \everypreroll + \permanent\def\nextinternalreference {\the\locationcount} \permanent\def\nextinternalorderreference{\the\locationorder} diff --git a/tex/context/base/mkxl/strc-reg.lmt b/tex/context/base/mkxl/strc-reg.lmt new file mode 100644 index 000000000..6e26f6f37 --- /dev/null +++ b/tex/context/base/mkxl/strc-reg.lmt @@ -0,0 +1,1668 @@ +if not modules then modules = { } end modules ['strc-reg'] = { + version = 1.001, + comment = "companion to strc-reg.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next, type, tonumber, rawget = next, type, tonumber, rawget +local char, format, gmatch = string.char, string.format, string.gmatch +local equal, concat, remove = table.are_equal, table.concat, table.remove +local lpegmatch, P, C, Ct = lpeg.match, lpeg.P, lpeg.C, lpeg.Ct +local allocate = utilities.storage.allocate + +local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end) + +local report_registers = logs.reporter("structure","registers") + +local structures = structures +local registers = structures.registers +local helpers = structures.helpers +local sections = structures.sections +local documents = structures.documents +local pages = structures.pages +local references = structures.references + +local usedinternals = references.usedinternals + +local mappings = sorters.mappings +local entries = sorters.entries +local replacements = sorters.replacements + +local processors = typesetters.processors +local splitprocessor = processors.split + +local texgetcount = tex.getcount + +local variables = interfaces.variables +local v_forward = variables.forward +local v_all = variables.all +local v_no = variables.no +local v_yes = variables.yes +local v_packed = variables.packed +local v_current = variables.current +local v_previous = variables.previous +local v_first = variables.first +local v_last = variables.last +local v_text = variables.text +local v_section = variables.section + +local context = context +local ctx_latelua = context.latelua + +local implement = interfaces.implement + +local matchingtilldepth = sections.matchingtilldepth +local numberatdepth = sections.numberatdepth +local currentlevel = sections.currentlevel +local currentid = sections.currentid + +local touserdata = helpers.touserdata + +local internalreferences = references.internals +local setinternalreference = references.setinternalreference + +local setmetatableindex = table.setmetatableindex + +local absmaxlevel = 5 -- \c_strc_registers_maxlevel + +local h_prefixpage = helpers.prefixpage +local h_prefixlastpage = helpers.prefixlastpage +local h_title = helpers.title +local h_prefix = helpers.prefix + +local ctx_startregisteroutput = context.startregisteroutput +local ctx_stopregisteroutput = context.stopregisteroutput +local ctx_startregistersection = context.startregistersection +local ctx_stopregistersection = context.stopregistersection +local ctx_startregisterentries = context.startregisterentries +local ctx_stopregisterentries = context.stopregisterentries +local ctx_startregisterentry = context.startregisterentry +local ctx_stopregisterentry = context.stopregisterentry +local ctx_startregisterpages = context.startregisterpages +local ctx_stopregisterpages = context.stopregisterpages +local ctx_startregisterseewords = context.startregisterseewords +local ctx_stopregisterseewords = context.stopregisterseewords + +local ctx_registerentry = context.registerentry +local ctx_registerseeword = context.registerseeword +local ctx_registerpagerange = context.registerpagerange +local ctx_registeronepage = context.registeronepage +local ctx_registersection = context.registersection +local ctx_registerpacked = context.registerpacked + +-- possible export, but ugly code (overloads) +-- +-- local output, section, entries, nofentries, pages, words, rawtext +-- +-- h_title = function(a,b) rawtext = a end +-- +-- local function ctx_startregisteroutput() +-- output = { } +-- section = nil +-- entries = nil +-- nofentries = nil +-- pages = nil +-- words = nil +-- rawtext = nil +-- end +-- local function ctx_stopregisteroutput() +-- inspect(output) +-- output = nil +-- section = nil +-- entries = nil +-- nofentries = nil +-- pages = nil +-- words = nil +-- rawtext = nil +-- end +-- local function ctx_startregistersection(tag) +-- section = { } +-- output[#output+1] = { +-- section = section, +-- tag = tag, +-- } +-- end +-- local function ctx_stopregistersection() +-- end +-- local function ctx_startregisterentries(n) +-- entries = { } +-- nofentries = 0 +-- section[#section+1] = entries +-- end +-- local function ctx_stopregisterentries() +-- end +-- local function ctx_startregisterentry(n) -- or subentries (nested?) +-- nofentries = nofentries + 1 +-- entry = { } +-- entries[nofentries] = entry +-- end +-- local function ctx_stopregisterentry() +-- nofentries = nofentries - 1 +-- entry = entries[nofentries] +-- end +-- local function ctx_startregisterpages() +-- pages = { } +-- entry.pages = pages +-- end +-- local function ctx_stopregisterpages() +-- end +-- local function ctx_startregisterseewords() +-- words = { } +-- entry.words = words +-- end +-- local function ctx_stopregisterseewords() +-- end +-- local function ctx_registerentry(processor,internal,seeparent,text) +-- text() +-- entry.text = { +-- processor = processor, +-- internal = internal, +-- seeparent = seeparent, +-- text = rawtext, +-- } +-- end +-- local function ctx_registerseeword(i,n,processor,internal,seeindex,seetext) +-- seetext() +-- entry.words[i] = { +-- processor = processor, +-- internal = internal, +-- seeparent = seeparent, +-- seetext = rawtext, +-- } +-- end +-- local function ctx_registerpagerange(fprocessor,finternal,frealpage,lprocessor,linternal,lrealpage) +-- pages[#pages+1] = { +-- first = { +-- processor = fprocessor, +-- internal = finternal, +-- realpage = frealpage, +-- }, +-- last = { +-- processor = lprocessor, +-- internal = linternal, +-- realpage = lrealpage, +-- }, +-- } +-- end +-- local function ctx_registeronepage(processor,internal,realpage) +-- pages[#pages+1] = { +-- processor = processor, +-- internal = internal, +-- realpage = realpage, +-- } +-- end + +-- some day we will share registers and lists (although there are some conceptual +-- differences in the application of keywords) + +local function filtercollected(names,criterium,number,collected,prevmode) + if not criterium or criterium == "" then + criterium = v_all + end + local data = documents.data + local numbers = data.numbers + local depth = data.depth + local hash = { } + local result = { } + local nofresult = 0 + local all = not names or names == "" or names == v_all + local detail = nil + if not all then + for s in gmatch(names,"[^, ]+") do + hash[s] = true + end + end + if criterium == v_all or criterium == v_text then + for i=1,#collected do + local v = collected[i] + if all then + nofresult = nofresult + 1 + result[nofresult] = v + else + local vmn = v.metadata and v.metadata.name + if hash[vmn] then + nofresult = nofresult + 1 + result[nofresult] = v + end + end + end + elseif criterium == v_current then + local collectedsections = sections.collected + for i=1,#collected do + local v = collected[i] + local sectionnumber = collectedsections[v.references.section] + if sectionnumber then + local cnumbers = sectionnumber.numbers + if prevmode then + if (all or hash[v.metadata.name]) and #cnumbers >= depth then -- is the = ok for lists as well? + local ok = true + for d=1,depth do + if not (cnumbers[d] == numbers[d]) then -- no zero test + ok = false + break + end + end + if ok then + nofresult = nofresult + 1 + result[nofresult] = v + end + end + else + if (all or hash[v.metadata.name]) and #cnumbers > depth then + local ok = true + for d=1,depth do + local cnd = cnumbers[d] + if not (cnd == 0 or cnd == numbers[d]) then + ok = false + break + end + end + if ok then + nofresult = nofresult + 1 + result[nofresult] = v + end + end + end + end + end + elseif criterium == v_previous then + local collectedsections = sections.collected + for i=1,#collected do + local v = collected[i] + local sectionnumber = collectedsections[v.references.section] + if sectionnumber then + local cnumbers = sectionnumber.numbers + if (all or hash[v.metadata.name]) and #cnumbers >= depth then + local ok = true + if prevmode then + for d=1,depth do + if not (cnumbers[d] == numbers[d]) then + ok = false + break + end + end + else + for d=1,depth do + local cnd = cnumbers[d] + if not (cnd == 0 or cnd == numbers[d]) then + ok = false + break + end + end + end + if ok then + nofresult = nofresult + 1 + result[nofresult] = v + end + end + end + end + elseif criterium == variables["local"] then + if sections.autodepth(data.numbers) == 0 then + return filtercollected(names,v_all,number,collected,prevmode) + else + return filtercollected(names,v_current,number,collected,prevmode) + end + else -- sectionname, number + -- beware, this works ok for registers + -- to be redone with reference instead + local depth = sections.getlevel(criterium) + local number = tonumber(number) or numberatdepth(depth) or 0 + if trace_registers then + detail = format("depth: %s, number: %s, numbers: %s, startset: %s",depth,number,concat(sections.numbers(),".",1,depth),#collected) + end + if number > 0 then + for i=1,#collected do + local v = collected[i] + local r = v.references + if r then + local sectionnumber = sections.collected[r.section] + if sectionnumber then + local metadata = v.metadata + local cnumbers = sectionnumber.numbers + if cnumbers then + if (all or hash[metadata.name or false]) and #cnumbers >= depth and matchingtilldepth(depth,cnumbers) then + nofresult = nofresult + 1 + result[nofresult] = v + end + end + end + end + end + end + end + if trace_registers then + if detail then + report_registers("criterium %a, detail %a, found %a",criterium,detail,#result) + else + report_registers("criterium %a, detail %a, found %a",criterium,nil,#result) + end + end + return result +end + +local tobesaved = allocate() +local collected = allocate() + +registers.collected = collected +registers.tobesaved = tobesaved +registers.filtercollected = filtercollected + +-- we follow a different strategy than by lists, where we have a global +-- result table; we might do that here as well but since sorting code is +-- older we delay that decision + +-- maybe store the specification in the format (although we predefine only +-- saved registers) + +local function checker(t,k) + local v = { + metadata = { + language = 'en', + sorted = false, + class = class, + }, + entries = { }, + } + t[k] = v + return v +end + +local function initializer() + tobesaved = registers.tobesaved + collected = registers.collected + setmetatableindex(tobesaved,checker) + setmetatableindex(collected,checker) + local usedinternals = references.usedinternals + for name, list in next, collected do + local entries = list.entries + if not list.metadata.notsaved then + for e=1,#entries do + local entry = entries[e] + local r = entry.references + if r then + local internal = r and r.internal + if internal then + internalreferences[internal] = entry + usedinternals[internal] = r.used + end + end + end + end + end + -- references.sortedinternals = sortedkeys(internalreferences) -- todo: when we need it more than once +end + +local function finalizer() + local flaginternals = references.flaginternals + local usedviews = references.usedviews + for k, v in next, tobesaved do + local entries = v.entries + if entries then + for i=1,#entries do + local r = entries[i].references + if r then + local i = r.internal + local f = flaginternals[i] + if f then + r.used = usedviews[i] or true + end + end + end + end + end +end + +job.register('structures.registers.collected', tobesaved, initializer, finalizer) + +setmetatableindex(tobesaved,checker) +setmetatableindex(collected,checker) + +local function defineregister(class,method) + local d = tobesaved[class] + if method == v_forward then + d.metadata.notsaved = true + end +end + +registers.define = defineregister -- 4 times is somewhat over the top but we want consistency +registers.setmethod = defineregister -- and we might have a difference some day + +implement { + name = "defineregister", + actions = defineregister, + arguments = "2 strings", +} + +implement { + name = "setregistermethod", + actions = defineregister, -- duplicate use + arguments = "2 strings", +} + + +local p_s = P("+") +local p_e = P("&") * (1-P(";"))^0 * P(";") +local p_r = C((p_e + (1-p_s))^0) + +local entrysplitter_xml = Ct(p_r * (p_s * p_r)^0) -- bah +local entrysplitter_tex = lpeg.tsplitat('+') -- & obsolete in mkiv + +local tagged = { } + +-- this whole splitting is an inheritance of mkii + +local function preprocessentries(rawdata) + local entries = rawdata.entries + if entries then + local processors = rawdata.processors + local et = entries.entries + local kt = entries.keys + local pt = entries.processors + local entryproc = processors and processors.entry + local pageproc = processors and processors.page + local coding = rawdata.metadata.coding + if entryproc == "" then + entryproc = nil + end + if pageproc == "" then + pageproc = nil + end + if not et then + local p, e = splitprocessor(entries.entry or "") + if p then + entryproc = p + end + et = lpegmatch(coding == "xml" and entrysplitter_xml or entrysplitter_tex,e) + end + if not kt then + local p, k = splitprocessor(entries.key or "") + if p then + pageproc = p + end + kt = lpegmatch(coding == "xml" and entrysplitter_xml or entrysplitter_tex,k) + end + if not pt then + pt = { } + end + -- + entries = { } + local ok = false + for k=#et,1,-1 do + local etk = et[k] + local ktk = kt[k] + local ptk = pt[k] + if not ok and etk == "" then + entries[k] = nil + else + entries[k] = { etk or "", ktk ~= "" and ktk or false, ptk ~= "" and ptk or false } + ok = true + end + end + rawdata.list = entries + if pageproc or entryproc then + rawdata.processors = { entryproc, pageproc } -- old way: indexed .. will be keys + end + rawdata.entries = nil + end + local seeword = rawdata.seeword + if seeword then + seeword.processor, seeword.text = splitprocessor(seeword.text or "") + end +end + +local function storeregister(rawdata) -- metadata, references, entries + local references = rawdata.references + local metadata = rawdata.metadata + -- checking + if not metadata then + metadata = { } + rawdata.metadata = metadata + end + -- + if not metadata.kind then + metadata.kind = "entry" + end + -- + -- + if not metadata.catcodes then + metadata.catcodes = tex.catcodetable -- get + end + -- + local name = metadata.name + local notsaved = tobesaved[name].metadata.notsaved + -- + if not references then + references = { } + rawdata.references = references + end + -- + local internal = references.internal + if not internal then + internal = texgetcount("locationcount") -- we assume that it has been set + references.internal = internal + end + -- + if notsaved then + usedinternals[internal] = references.used -- todo view (we assume that forward references index entries are used) + end + -- + if not references.realpage then + references.realpage = 0 -- just to be sure as it can be refered to + end + -- + local userdata = rawdata.userdata + if userdata then + rawdata.userdata = touserdata(userdata) + end + -- + references.section = currentid() + metadata.level = currentlevel() + -- + local data = notsaved and collected[name] or tobesaved[name] + local entries = data.entries + internalreferences[internal] = rawdata + preprocessentries(rawdata) + entries[#entries+1] = rawdata + local label = references.label + if label and label ~= "" then + tagged[label] = #entries + else + references.label = nil + end + return #entries +end + +local function enhanceregister(specification) + local name = specification.name + local n = specification.n + local saved = tobesaved[name] + local data = saved.metadata.notsaved and collected[name] or saved + local entry = data.entries[n] + if entry then + entry.references.realpage = texgetcount("realpageno") + end +end + +-- This can become extendregister(specification)! + +local function extendregister(name,tag,rawdata) -- maybe do lastsection internally + if type(tag) == "string" then + tag = tagged[tag] + end + if tag then + local data = tobesaved[name].metadata.notsaved and collected[name] or tobesaved[name] + local entry = data.entries[tag] + if entry then + local references = entry.references + references.lastrealpage = texgetcount("realpageno") + references.lastsection = currentid() + if rawdata then + local userdata = rawdata.userdata + if userdata then + rawdata.userdata = touserdata(userdata) + end + if rawdata.entries then + preprocessentries(rawdata) + end + local metadata = rawdata.metadata + if metadata and not metadata.catcodes then + metadata.catcodes = tex.catcodetable -- get + end + for k, v in next, rawdata do + local rk = references[k] + if not rk then + references[k] = v + else + for kk, vv in next, v do + if type(vv) == "table" then + if next(vv) then + rk[kk] = vv + end + elseif vv ~= "" then + rk[kk] = vv + end + end + end + end + end + end + end +end + +registers.store = storeregister +registers.enhance = enhanceregister +registers.extend = extendregister + +function registers.get(tag,n) + local list = tobesaved[tag] + return list and list.entries[n] +end + +implement { + name = "enhanceregister", + arguments = { "string", "integer" }, + actions = function(name,n) + enhanceregister { name = name, n = n } -- todo: move to scanner + end, +} + +implement { + name = "deferredenhanceregister", + arguments = { "string", "integer" }, + protected = true, + actions = function(name,n) + ctx_latelua { action = enhanceregister, name = name, n = n } + end, +} + +implement { + name = "extendregister", + actions = extendregister, + arguments = "2 strings", +} + +implement { + name = "storeregister", + -- actions = function(rawdata) + -- local nofentries = storeregister(rawdata) + -- setinternalreference { internal = rawdata.references.internal } + -- context(nofentries) + -- end, + actions = { storeregister, context }, + arguments = { + { + { "metadata", { + { "kind" }, + { "name" }, + { "coding" }, + { "level", "integer" }, + { "catcodes", "integer" }, + { "own" }, + { "xmlroot" }, + { "xmlsetup" }, + } + }, + { "entries", { + { "entries", "list" }, + { "keys", "list" }, + { "processors", "list" }, + { "entry" }, + { "key" }, + { "processor" }, + } + }, + { "references", { + { "internal", "integer" }, + { "section", "integer" }, + { "view" }, + { "label" }, + } + }, + { "seeword", { + { "text" }, + } + }, + { "processors", { + { "entry" }, + { "key" }, + { "page" }, + } + }, + { "userdata" }, + } + } +} + +-- sorting and rendering + +local compare = sorters.comparers.basic + +function registers.compare(a,b) + local result = compare(a,b) + if result ~= 0 then + return result + else + local ka = a.metadata.kind + local kb = b.metadata.kind + if ka == kb then + local ra = a.references + local rb = b.references + local pa = ra.realpage + local pb = rb.realpage + if not pa or not pb then + return 0 + elseif pa < pb then + return -1 + elseif pa > pb then + return 1 + else + -- new, we need to pick the right one of multiple and + -- we want to prevent oscillation in the tuc file so: + local ia = ra.internal + local ib = rb.internal + if not ia or not ib then + return 0 + elseif ia < ib then + return -1 + elseif ia > ib then + return 1 + else + return 0 + end + end + elseif ka == "see" then + return 1 + elseif kb == "see" then + return -1 + end + end + return 0 +end + +function registers.filter(data,options) + data.result = registers.filtercollected(nil,options.criterium,options.number,data.entries,true) +end + +local seeindex = 0 + +-- meerdere loops, seewords, dan words, anders seewords + +-- todo: split seeword + +local function crosslinkseewords(result,check) -- all words + -- collect all seewords + local seewords = { } + for i=1,#result do + local data = result[i] + local seeword = data.seeword + if seeword then + local seetext = seeword.text + if seetext and not seewords[seetext] then + seeindex = seeindex + 1 + seewords[seetext] = seeindex + if trace_registers then + report_registers("see word %03i: %s",seeindex,seetext) + end + end + end + end + + -- mark seeparents + + -- local seeparents = { } + -- for i=1,#result do + -- local data = result[i] + -- local word = data.list[1] + -- local okay = word and word[1] + -- if okay then + -- local seeindex = seewords[okay] + -- if seeindex then + -- seeparents[okay] = data + -- data.references.seeparent = seeindex + -- if trace_registers then + -- report_registers("see parent %03i: %s",seeindex,okay) + -- end + -- end + -- end + -- end + + local entries = { } + local keywords = { } + local seeparents = { } + for i=1,#result do + local data = result[i] + local word = data.list + local size = #word + if data.seeword then + -- beware: a seeword has an extra entry for sorting purposes + size = size - 1 + end + for i=1,size do + local w = word[i] + local e = w[1] + local k = w[2] or e + entries [i] = e + keywords[i] = k + end + -- first try the keys + local okay, seeindex + for n=size,1,-1 do + okay = concat(keywords,"+",1,n) + seeindex = seewords[okay] + -- first try the entries + if seeindex then + break + end + okay = concat(entries,"+",1,n) + seeindex = seewords[okay] + if seeindex then + break + end + end + if seeindex then + seeparents[okay] = data + data.references.seeparent = seeindex + if trace_registers then + report_registers("see parent %03i: %s",seeindex,okay) + end + end + end + + -- mark seewords and extend sort list + for i=1,#result do + local data = result[i] + local seeword = data.seeword + if seeword then + local text = seeword.text + if text then + local seeparent = seeparents[text] + if seeparent then + local seeindex = seewords[text] + data.references.seeindex = seeindex + if trace_registers then + report_registers("see crosslink %03i: %s",seeindex,text) + end + seeword.valid = true + elseif check then + report_registers("invalid crosslink : %s, %s",text,"ignored") + seeword.valid = false + else + report_registers("invalid crosslink : %s, %s",text,"passed") + seeword.valid = true + end + end + end + end +end + +local function removeemptyentries(result) + local i, n, m = 1, #result, 0 + while i <= n do + local entry = result[i] + if #entry.list == 0 or #entry.split == 0 then + remove(result,i) + n = n - 1 + m = m + 1 + else + i = i + 1 + end + end + if m > 0 then + report_registers("%s empty entries removed in register",m) + end +end + +function registers.prepare(data,options) + -- data has 'list' table + local strip = sorters.strip + local splitter = sorters.splitters.utf + local result = data.result + if result then + local seeprefix = char(0) + for i=1, #result do + local entry = result[i] + local split = { } + local list = entry.list + if list then + if entry.seeword then + -- we can have multiple seewords, only two levels supported + list[#list+1] = { seeprefix .. strip(entry.seeword.text) } + end + for l=1,#list do + local ll = list[l] + local word = ll[1] + local key = ll[2] + if not key or key == "" then + key = word + end + split[l] = splitter(strip(key)) + end + end + entry.split = split + end + removeemptyentries(result) + crosslinkseewords(result,options.check ~= v_no) + end +end + +function registers.sort(data,options) + -- if options.pagenumber == false then + -- sorters.sort(data.result,compare) + -- else + sorters.sort(data.result,registers.compare) + -- end +end + +function registers.unique(data,options) + local result = { } + local nofresult = 0 + local prev = nil + local dataresult = data.result + local bysection = options.pagemethod == v_section -- normally page + for k=1,#dataresult do + local v = dataresult[k] + if prev then + local vr = v.references + local pr = prev.references + if not equal(prev.list,v.list) then + -- ok + elseif bysection and vr.section == pr.section then + v = nil + -- ok + elseif pr.realpage ~= vr.realpage then + -- ok + else + local pl = pr.lastrealpage + local vl = vr.lastrealpage + if pl or vl then + if not vl then + -- ok + elseif not pl then + -- ok + elseif pl ~= vl then + -- ok + else + v = nil + end + else + v = nil + end + end + end + if v then + nofresult = nofresult + 1 + result[nofresult] = v + prev = v + end + end + data.result = result +end + +function registers.finalize(data,options) -- maps character to index (order) + local result = data.result + data.metadata.nofsorted = #result + local split = { } + local nofsplit = 0 + local lasttag = nil + local done = nil + local nofdone = 0 + local firstofsplit = sorters.firstofsplit + for k=1,#result do + local v = result[k] + local entry, tag = firstofsplit(v) + if tag ~= lasttag then + if trace_registers then + report_registers("splitting at %a",tag) + end + done = { } + nofdone = 0 + nofsplit = nofsplit + 1 + lasttag = tag + split[nofsplit] = { tag = tag, data = done } + end + nofdone = nofdone + 1 + done[nofdone] = v + end + data.result = split +end + +-- local function analyzeregister(class,options) +-- local data = collected[class] +-- if data and data.entries then +-- options = options or { } +-- sorters.setlanguage(options.language,options.method,options.numberorder) +-- registers.filter(data,options) -- filter entries into results (criteria) +-- registers.prepare(data,options) -- adds split table parallel to list table +-- registers.sort(data,options) -- sorts results +-- registers.unique(data,options) -- get rid of duplicates +-- registers.finalize(data,options) -- split result in ranges +-- data.metadata.sorted = true +-- return data.metadata.nofsorted or 0 +-- else +-- return 0 +-- end +-- end + +local function analyzeregister(class,options) + local data = rawget(collected,class) + if not data then + local list = utilities.parsers.settings_to_array(class) + local entries = { } + local metadata = false + for i=1,#list do + local l = list[i] + local d = collected[l] + local e = d.entries + for i=1,#e do + entries[#entries+1] = e[i] + end + if not metadata then + metadata = d.metadata + end + end + data = { + metadata = metadata or { }, + entries = entries, + } + collected[class] = data + end + if data and data.entries then + options = options or { } + sorters.setlanguage(options.language,options.method,options.numberorder) + registers.filter(data,options) -- filter entries into results (criteria) + registers.prepare(data,options) -- adds split table parallel to list table + registers.sort(data,options) -- sorts results + registers.unique(data,options) -- get rid of duplicates + registers.finalize(data,options) -- split result in ranges + data.metadata.sorted = true + return data.metadata.nofsorted or 0 + else + return 0 + end +end + +registers.analyze = analyzeregister + +implement { + name = "analyzeregister", + actions = { analyzeregister, context }, + arguments = { + "string", + { + { "language" }, + { "method" }, + { "numberorder" }, + { "compress" }, + { "criterium" }, + { "pagenumber", "boolean" }, + } + } +} + +-- todo take conversion from index + +function registers.userdata(index,name) + local data = references.internals[tonumber(index)] + return data and data.userdata and data.userdata[name] or nil +end + +implement { + name = "registeruserdata", + actions = { registers.userdata, context }, + arguments = { "integer", "string" } +} + +-- todo: ownnumber + +local function pagerange(f_entry,t_entry,is_last,prefixspec,pagespec) + local fer = f_entry.references + local ter = t_entry.references + ctx_registerpagerange( + f_entry.metadata.name or "", + f_entry.processors and f_entry.processors[2] or "", + fer.internal or 0, + fer.realpage or 0, + function() + h_prefixpage(f_entry,prefixspec,pagespec) + end, + ter.internal or 0, + ter.lastrealpage or ter.realpage or 0, + function() + if is_last then + h_prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys + else + h_prefixpage (t_entry,prefixspec,pagespec) + end + end + ) +end + +local function pagenumber(entry,prefixspec,pagespec) + local er = entry.references + ctx_registeronepage( + entry.metadata.name or "", + entry.processors and entry.processors[2] or "", + er.internal or 0, + er.realpage or 0, + function() h_prefixpage(entry,prefixspec,pagespec) end + ) +end + +local function packed(f_entry,t_entry) + local fer = f_entry.references + local ter = t_entry.references + ctx_registerpacked( + fer.internal or 0, + ter.internal or 0 + ) +end + +local function collapsedpage(pages) + for i=2,#pages do + local first = pages[i-1] + local second = pages[i] + local first_first = first[1] + local first_last = first[2] + local second_first = second[1] + local second_last = second[2] + local first_last_pn = first_last .references.realpage + local second_first_pn = second_first.references.realpage + local second_last_pn = second_last .references.realpage + local first_last_last = first_last .references.lastrealpage + local second_first_last = second_first.references.lastrealpage + if first_last_last then + first_last_pn = first_last_last + if second_first == second_last and second_first_pn <= first_last_pn then + -- 2=8, 5 -> 12=8 + remove(pages,i) + return true + elseif second_first == second_last and second_first_pn > first_last_pn then + -- 2=8, 9 -> 2-9 + pages[i-1] = { first_first, second_last } + remove(pages,i) + return true + elseif second_last_pn < first_last_pn then + -- 2=8, 3-4 -> 2=8 + remove(pages,i) + return true + elseif first_last_pn < second_last_pn then + -- 2=8, 3-9 -> 2-9 + pages[i-1] = { first_first, second_last } + remove(pages,i) + return true + elseif first_last_pn + 1 == second_first_pn and second_last_pn > first_last_pn then + -- 2=8, 9-11 -> 2-11 + pages[i-1] = { first_first, second_last } + remove(pages,i) + return true + elseif second_first.references.lastrealpage then + -- 2=8, 9=11 -> 2-11 + pages[i-1] = { first_first, second_last } + remove(pages,i) + return true + end + elseif second_first_last then + second_first_pn = second_first_last + if first_last_pn == second_first_pn then + -- 2-4, 5=9 -> 2-9 + pages[i-1] = { first_first, second_last } + remove(pages,i) + return true + end + elseif first_last_pn == second_first_pn then + -- 2-3, 3-4 -> 2-4 + pages[i-1] = { first_last, second_last } + remove(pages,i) + return true + end + end + return false +end + +local function collapsepages(pages) + while collapsedpage(pages) do end + return #pages +end + +-- todo: create an intermediate structure and flush that + +function registers.flush(data,options,prefixspec,pagespec) + local compress = options.compress + local collapse_singles = compress == v_yes + local collapse_ranges = compress == v_all + local collapse_packed = compress == v_packed + local show_page_number = options.pagenumber ~= false -- true or false + local bysection = options.pagemethod == v_section + local result = data.result + local maxlevel = 0 + -- + for i=1,#result do + local data = result[i].data + for d=1,#data do + local m = #data[d].list + if m > maxlevel then + maxlevel = m + end + end + end + if maxlevel > absmaxlevel then + maxlevel = absmaxlevel + report_registers("limiting level to %a",maxlevel) + end + -- + ctx_startregisteroutput() + local done = { } + local started = false + for i=1,#result do + -- ranges need checking ! + local sublist = result[i] + -- local done = { false, false, false, false } + for i=1,maxlevel do + done[i] = false + end + local data = sublist.data + local d = 0 + local n = 0 + ctx_startregistersection(sublist.tag) + for d=1,#data do + local entry = data[d] + if entry.metadata.kind == "see" then + local list = entry.list + if #list > 1 then + list[#list] = nil + else + -- we have an \seeindex{Foo}{Bar} without Foo being defined anywhere .. somehow this message is wrong + -- report_registers("invalid see entry in register %a, reference %a",entry.metadata.name,list[1][1]) + end + end + end + -- ok, this is tricky: we use e[i] delayed so we need it to be local + -- but we don't want to allocate too many entries so there we go + + while d < #data do + d = d + 1 + local entry = data[d] +-- inspect(entry) + local metadata = entry.metadata + local kind = metadata.kind + local list = entry.list + local e = { false, false, false } + for i=3,maxlevel do + e[i] = false + end + for i=1,maxlevel do + local li = list[i] + if list[i] then + e[i] = li[1] + end + if e[i] == done[i] then + -- skip + elseif not e[i] then + -- see ends up here + -- can't happen any more + done[i] = false + for j=i+1,maxlevel do + done[j] = false + end + elseif e[i] == "" then + done[i] = false + for j=i+1,maxlevel do + done[j] = false + end + else + done[i] = e[i] + for j=i+1,maxlevel do + done[j] = false + end + if started then + ctx_stopregisterentry() + started = false + end + if n == i then + -- ctx_stopregisterentries() + -- ctx_startregisterentries(n) + else + while n > i do + n = n - 1 + ctx_stopregisterentries() + end + while n < i do + n = n + 1 + ctx_startregisterentries(n) + end + end + local references = entry.references + local processors = entry.processors + local internal = references.internal or 0 + local seeparent = references.seeparent or "" + local processor = (li and li[3]) or (processors and processors[1]) or "" + -- so, we need to keep e as is (local), or we need local title = e[i] ... which might be + -- more of a problem + ctx_startregisterentry(0) -- will become a counter + started = true + if metadata then + ctx_registerentry(metadata.name or "",processor,internal,seeparent,function() h_title(e[i],metadata) end) + else + -- can this happen? + ctx_registerentry("",processor,internal,seeindex,e[i]) + end + end + end + + local function case_1() + -- we collapse ranges and keep existing ranges as they are + -- so we get prebuilt as well as built ranges + local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0 + while dd < #data do + dd = dd + 1 + local next = data[dd] + if next and next.metadata.kind == "see" then + dd = dd - 1 + break + else + local el, nl = entry.list, next.list + if not equal(el,nl) then + dd = dd - 1 + --~ first = nil + break + elseif next.references.lastrealpage then + nofpages = nofpages + 1 + pages[nofpages] = first and { first, last or first } or { entry, entry } + nofpages = nofpages + 1 + pages[nofpages] = { next, next } + first, last, prev = nil, nil, nil + elseif not first then + first, prev = next, next + elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ? + last, prev = next, next + else + nofpages = nofpages + 1 + pages[nofpages] = { first, last or first } + first, last, prev = next, nil, next + end + end + end + if first then + nofpages = nofpages + 1 + pages[nofpages] = { first, last or first } + end + if collapse_ranges and nofpages > 1 then + nofpages = collapsepages(pages) + end + if nofpages > 0 then -- or 0 + d = dd + for p=1,nofpages do + local first, last = pages[p][1], pages[p][2] + if first == last then + if first.references.lastrealpage then + pagerange(first,first,true,prefixspec,pagespec) + else + pagenumber(first,prefixspec,pagespec) + end + elseif last.references.lastrealpage then + pagerange(first,last,true,prefixspec,pagespec) + else + pagerange(first,last,false,prefixspec,pagespec) + end + end + elseif entry.references.lastrealpage then + pagerange(entry,entry,true,prefixspec,pagespec) + else + pagenumber(entry,prefixspec,pagespec) + end + end + + local function case_2() + local first = nil + local last = nil + while true do + if not first then + first = entry + end + last = entry + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next + end + end + end + packed(first,last) -- returns internals + end + + local function case_3() + while true do + if entry.references.lastrealpage then + pagerange(entry,entry,true,prefixspec,pagespec) + else + pagenumber(entry,prefixspec,pagespec) + end + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next + end + end + end + end + + local function case_4() + local t = { } + local nt = 0 + while true do + if entry.seeword and entry.seeword.valid then + nt = nt + 1 + t[nt] = entry + end + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind ~= "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next + end + end + end + for i=1,nt do + local entry = t[i] + local seeword = entry.seeword + local seetext = seeword.text or "" + local processor = seeword.processor or (entry.processors and entry.processors[1]) or "" + local seeindex = entry.references.seeindex or "" + ctx_registerseeword( + metadata.name or "", + i, + nt, + processor, + 0, + seeindex, + function() h_title(seetext,metadata) end + ) + end + end + + local function case_5() + local first = d + while true do + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next + end + end + end + local last = d + local n = last - first + 1 + local i = 0 + local name = metadata.name or "" + local processor = entry.processors and entry.processors[1] or "" + for e=first,last do + local d = data[e] + local sectionindex = d.references.internal or 0 + i = i + 1 + ctx_registersection( + name, + i, + n, + processor, + 0, + sectionindex, + function() h_prefix(d,prefixspec,true) end + ) + end + end + + if kind == "entry" then + if show_page_number then + ctx_startregisterpages() + if bysection then + case_5() + elseif collapse_singles or collapse_ranges then + case_1() + elseif collapse_packed then + case_2() + else + case_3() + end + ctx_stopregisterpages() + end + elseif kind == "see" then + ctx_startregisterseewords() + case_4() + ctx_stopregisterseewords() + end + + end + + if started then + ctx_stopregisterentry() + started = false + end + while n > 0 do + ctx_stopregisterentries() + n = n - 1 + end + ctx_stopregistersection() + end + ctx_stopregisteroutput() + -- for now, maybe at some point we will do a multipass or so + data.result = nil + data.metadata.sorted = false + -- temp hack for luajittex : + local entries = data.entries + for i=1,#entries do + entries[i].split = nil + end + -- collectgarbage("collect") +end + +function registers.process(class,...) + if analyzeregister(class,...) > 0 then + local data = collected[class] + registers.flush(data,...) + end +end + +implement { + name = "processregister", + actions = registers.process, + arguments = { + "string", + { + { "language" }, + { "method" }, + { "numberorder" }, + { "compress" }, + { "criterium" }, + { "check" }, + { "pagemethod" }, + { "pagenumber", "boolean" }, + }, + { + { "separatorset" }, + { "conversionset" }, + { "starter" }, + { "stopper" }, + { "set" }, + { "segments" }, + { "connector" }, + }, + { + { "prefix" }, + { "separatorset" }, + { "conversionset" }, + { "starter" }, + { "stopper" }, + { "segments" }, + } + } +} + +-- linked registers + +function registers.findinternal(tag,where,n) + -- local collected = registers.collected + local current = collected[tag] + if not current then + return 0 + end + local entries = current.entries + if not entries then + return 0 + end + local entry = entries[n] + if not entry then + return 0 + end + local list = entry.list + local size = #list + -- + local start, stop, step + if where == v_previous then + start = n - 1 + stop = 1 + step = -1 + elseif where == v_first then + start = 1 + stop = #entries + step = 1 + elseif where == v_last then + start = #entries + stop = 1 + step = -1 + else + start = n + 1 + stop = #entries + step = 1 + end + -- + for i=start,stop,step do + local r = entries[i] + local l = r.list + local s = #l + if s == size then + local ok = true + for i=1,size do + if list[i][1] ~= l[i][1] then + ok = false + break + end + end + if ok then + return r.references.internal or 0 + end + end + end + return 0 +end + +interfaces.implement { + name = "findregisterinternal", + arguments = { "string", "string", "integer" }, + actions = { registers.findinternal, context }, +} diff --git a/tex/context/base/mkxl/strc-reg.mkxl b/tex/context/base/mkxl/strc-reg.mkxl index 16226c5fc..17d8b6e78 100644 --- a/tex/context/base/mkxl/strc-reg.mkxl +++ b/tex/context/base/mkxl/strc-reg.mkxl @@ -13,7 +13,7 @@ \writestatus{loading}{ConTeXt Structure Macros / Registers} -\registerctxluafile{strc-reg}{} +\registerctxluafile{strc-reg}{autosuffix} \unprotect @@ -207,6 +207,8 @@ \def\strc_registers_register_page_entry {\iftrialtypesetting \expandafter\gobblethreearguments + \orelse\ifconditional\prerollrun + \expandafter\gobblethreearguments \else \expandafter\strc_registers_register_page_entry_indeed \fi} @@ -441,16 +443,16 @@ \fi} \def\strc_registers_insert_entry_nop_par#1#2% - {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}} + {\ifprerolling\else\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}\fi} \def\strc_registers_insert_entry_yes_par#1#2#3% - {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}} + {\ifprerolling\else\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}\fi} \def\strc_registers_insert_entry_nop_txt#1#2% - {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}} + {\ifprerolling\else\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}\fi} \def\strc_registers_insert_entry_yes_txt#1#2#3% - {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}} + {\ifprerolling\else\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}\fi} %D This is one of the few commands where a stop has arguments. @@ -846,6 +848,17 @@ \newconstant\c_strc_registers_page_state % 0=nothing 1=page 2=see \newdimen \d_strc_registers_distance +\newcount \c_strc_register_level + +\def\strc_registers_update_text_properties + {\ifx\m_current_register\currentregister\else + \useregisterstyleandcolor\c!textstyle\c!textcolor + \fi} + +\def\strc_registers_update_page_properties + {\ifx\m_current_register\currentregister\else + \useregisterstyleandcolor\c!pagestyle\c!pagecolor + \fi} \permanent\protected\def\startregisteroutput {\endgraf @@ -877,13 +890,13 @@ \permanent\protected\def\startregisterentries#1% depth {\endgraf \begingroup - \scratchcounter\ifnum#1>\c_strc_registers_maxlevel\c_strc_registers_maxlevel\else#1\fi\relax + \c_strc_register_level\ifnum#1>\c_strc_registers_maxlevel\c_strc_registers_maxlevel\else#1\fi\relax \dostarttagged\t!registerentries\empty % \let\savedcurrentregister\currentregister \pushmacro\currentregister - \edef\currentregister{\currentregister:\number\scratchcounter}% + \edef\currentregister{\currentregister:\number\c_strc_register_level}% \usenestedregisterstyleandcolor\c!textstyle\c!textcolor - \ifnum\scratchcounter>\plusone + \ifnum\c_strc_register_level>\plusone \advance\leftskip\d_strc_registers_distance\relax \fi \d_strc_registers_hangindent\registerparameter\c!distance\relax @@ -978,6 +991,8 @@ \fi \fi} +\let\m_current_register\empty + \permanent\protected\def\pushcurrentregister#1% {\let\m_current_register\currentregister \edef\currentregister{#1}} @@ -987,6 +1002,7 @@ \permanent\protected\def\registeronepage#1#2#3#4#5% #1:class #2:processor content {\pushcurrentregister{#1}% + \strc_registers_update_page_properties \edef\p_pagenumber{\registerparameter\c!pagenumber}% \ifx\p_pagenumber\v!no\else \registerpageseparator @@ -1011,6 +1027,7 @@ \permanent\protected\def\registerpagerange#1#2#3#4#5#6#7#8% #1:class #2:processor content, content todo: -- configurable {\pushcurrentregister{#1}% + \strc_registers_update_page_properties \edef\p_pagenumber{\registerparameter\c!pagenumber}% \ifx\p_pagenumber\v!no\else \registerpageseparator @@ -1037,6 +1054,7 @@ \permanent\protected\def\defaultregisterentry#1#2#3#4#5% #1:class #2:processor #3:internal #4:seeindex #5:word {\pushcurrentregister{#1}% + \strc_registers_update_text_properties \def\currentregisterpageindex{#3}% \iflocation \def\currentregisterseeindex{#4}% diff --git a/tex/context/base/mkxl/supp-box.mkxl b/tex/context/base/mkxl/supp-box.mkxl index 52f54e327..796c3663a 100644 --- a/tex/context/base/mkxl/supp-box.mkxl +++ b/tex/context/base/mkxl/supp-box.mkxl @@ -2681,7 +2681,12 @@ {\beginlocalcontrol\begingroup \dowithnextboxcs\syst_boxes_contenttostring\hbox} -\newtoks\everypreroll +\newtoks \everypreroll +\newif \ifprerolling + +\appendtoks + \prerollingtrue +\to \everypreroll \let\prerolltostring\firstofoneargument % we need to bypass initializations diff --git a/tex/context/base/mkxl/syst-aux.mkxl b/tex/context/base/mkxl/syst-aux.mkxl index 2cca77390..873debedf 100644 --- a/tex/context/base/mkxl/syst-aux.mkxl +++ b/tex/context/base/mkxl/syst-aux.mkxl @@ -2915,7 +2915,7 @@ {\enforced\let\redoglobal\syst_helpers_redo_global \enforced\let\dodoglobal\syst_helpers_dodo_global} -%D Whatever (will be overtoaded): +%D Whatever (will be overloaded): \protected\def\define#1% {\ifdefined#1% @@ -2961,22 +2961,30 @@ % % [\test] +%D When okay the parameter hack will also go into \MKIV. + +\integerdef\c_syst_parameter_catcode\parametercatcode + \bgroup \obeylines \permanent\protected\gdef\starttexdefinition% - {\bgroup% + {\integerdef\c_syst_parameter_catcode\catcode\hashasciicode% + \catcode\hashasciicode\parametercatcode% + \bgroup% \obeylines% \syst_helpers_start_tex_definition} \gdef\syst_helpers_start_tex_definition#1 - {\catcode\endoflineasciicode\ignorecatcode% + {%catcodetable\ctxcatcodes% can be adapted + \catcode\endoflineasciicode\ignorecatcode% \clf_texdefinition_one{#1}} \permanent\protected\glettonothing\stoptexdefinition \permanent\gdef\dostarttexdefinition#1\stoptexdefinition% {\egroup% - \clf_texdefinition_two{#1}} + \clf_texdefinition_two{#1}% + \catcode\hashasciicode\c_syst_parameter_catcode} \egroup diff --git a/tex/context/base/mkxl/toks-ini.lmt b/tex/context/base/mkxl/toks-ini.lmt index 3e9ff362b..e4bf7626f 100644 --- a/tex/context/base/mkxl/toks-ini.lmt +++ b/tex/context/base/mkxl/toks-ini.lmt @@ -293,7 +293,7 @@ end tokens.cache = table.setmetatableindex(function(t,k) if not isdefined(k) then - setmacro(k,"","global") + setmacro(k,"","global") -- So we default to nothing! Maybe some message as option? end local v = createtoken(k) t[k] = v diff --git a/tex/context/base/mkxl/toks-scn.lmt b/tex/context/base/mkxl/toks-scn.lmt index ca95985b0..621eb063c 100644 --- a/tex/context/base/mkxl/toks-scn.lmt +++ b/tex/context/base/mkxl/toks-scn.lmt @@ -287,43 +287,43 @@ tokens.converters = { -- the gain is only some 10 percent but if we don't have keywords with numbers it might -- make sense in the end, some day. -local f_if = formatters[ " if scankeywordcs('%s') then data['%s'] = scan%s()"] -local f_elseif = formatters[" elseif scankeywordcs('%s') then data['%s'] = scan%s()"] +local f_if = formatters[ " if scankeywordcs('%s') then data['%s'] = scan%s()"] +local f_elseif = formatters[" elseif scankeywordcs('%s') then data['%s'] = scan%s()"] ------ f_if_x = formatters[ " if not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"] ------ f_elseif_x = formatters[" elseif not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"] +----- f_if_x = formatters[ " if not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"] +----- f_elseif_x = formatters[" elseif not data['%s'] and scankeywordcs('%s') then data['%s'] = scan%s()"] ------ f_if = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = scan%s()"] ------ f_elseif = formatters[" elseif key == '%s' then data['%s'] = scan%s()"] +----- f_if = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = scan%s()"] +----- f_elseif = formatters[" elseif key == '%s' then data['%s'] = scan%s()"] -local f_local = formatters["local scan%s = scanners.%s"] -local f_scan = formatters["scan%s()"] -local f_shortcut = formatters["local %s = scanners.converters.%s"] +local f_local = formatters["local scan%s = scanners.%s"] +local f_scan = formatters["scan%s()"] +local f_shortcut = formatters["local %s = scanners.converters.%s"] -local f_if_c = formatters[ " if scankeywordcs('%s') then data['%s'] = %s(scan%s())"] -local f_elseif_c = formatters[" elseif scankeywordcs('%s') then data['%s'] = %s(scan%s())"] -local f_scan_c = formatters["%s(scan%s())"] +local f_if_c = formatters[ " if scankeywordcs('%s') then data['%s'] = %s(scan%s())"] +local f_elseif_c = formatters[" elseif scankeywordcs('%s') then data['%s'] = %s(scan%s())"] +local f_scan_c = formatters["%s(scan%s())"] -- see above ------ f_if_c = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = %s(scan%s())"] ------ f_elseif_c = formatters[" elseif k == '%s' then data['%s'] = %s(scan%s())"] +----- f_if_c = formatters[" local key = scanletters() if key == '' then break elseif key == '%s' then data['%s'] = %s(scan%s())"] +----- f_elseif_c = formatters[" elseif k == '%s' then data['%s'] = %s(scan%s())"] -local f_any = formatters[" else local key = scanword(true) if key then data[key] = scan%s() else break end end"] -local f_any_c = formatters[" else local key = scanword(true) if key then data[key] = %s(scan%s()) else break end end"] -local s_done = " else break end" +local f_any = formatters[" else local key = scanword(true) if key then data[key] = scan%s() else break end end"] +local f_any_c = formatters[" else local key = scanword(true) if key then data[key] = %s(scan%s()) else break end end"] +local s_done <const> = " else break end" -local f_any_all = formatters[" local key = scanword(true) if key then data[key] = scan%s() else break end"] -local f_any_all_c= formatters[" local key = scanword(true) if key then data[key] = %s(scan%s()) else break end"] +local f_any_all = formatters[" local key = scanword(true) if key then data[key] = scan%s() else break end"] +local f_any_all_c = formatters[" local key = scanword(true) if key then data[key] = %s(scan%s()) else break end"] -local f_table = formatters["%\nt\nreturn function()\n local data = { }\n%s\n return %s\nend\n"] -local f_sequence = formatters["%\nt\n%\nt\n%\nt\nreturn function()\n return %s\nend\n"] -local f_singular = formatters["%\nt\n%\nt\n\nreturn function(%s)\n return %s\nend\n"] -local f_simple = formatters["%\nt\nreturn function()\n return %s\nend\n"] -local f_string = formatters["%q"] -local f_action_f = formatters["action%s(%s)"] -local f_action_s = formatters["local action%s = tokens._action[%s]"] -local f_nested = formatters["local function scan%s()\n local data = { }\n%s\n return data\nend\n"] +local f_table = formatters["%\nt\nreturn function()\n local data = { }\n%s\n return %s\nend\n"] +local f_sequence = formatters["%\nt\n%\nt\n%\nt\nreturn function()\n return %s\nend\n"] +local f_singular = formatters["%\nt\n%\nt\n\nreturn function(%s)\n return %s\nend\n"] +local f_simple = formatters["%\nt\nreturn function()\n return %s\nend\n"] +local f_string = formatters["%q"] +local f_action_f = formatters["action%s(%s)"] +local f_action_s = formatters["local action%s = tokens._action[%s]"] +local f_nested = formatters["local function scan%s()\n local data = { }\n%s\n return data\nend\n"] local f_check = formatters[ [[ local wrapped = scanopen() diff --git a/tex/context/base/mkxl/util-deb.lmt b/tex/context/base/mkxl/util-deb.lmt index 0021b93b9..71a43ea17 100644 --- a/tex/context/base/mkxl/util-deb.lmt +++ b/tex/context/base/mkxl/util-deb.lmt @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['util-deb'] = { -- bound to a variable, like node.new, node.copy etc (contrary to for instance -- node.has_attribute which is bound to a has_attribute local variable in mkiv) -local type, next, tostring, tonumber = type, next, tostring, tonumber +local type, next, tostring, tonumber, xpcall, print = type, next, tostring, tonumber, xpcall, print local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub local insert, remove, sort = table.insert, table.remove, table.sort local setmetatableindex = table.setmetatableindex @@ -369,3 +369,23 @@ debugger.showtraceback = showtraceback -- debug.showtraceback = showtraceback -- showtraceback() + +if luac then + + local show, dump = luac.print, string.dump + + function luac.inspect(v) + if type(v) == "function" then + local ok, str = xpcall(dump,function() end,v) + if ok then + v = str + end + end + if type(v) == "string" then + show(v,true) + else + print(v) + end + end + +end diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml index beaf78112..c337aa5be 100644 --- a/tex/context/interface/mkii/keys-fr.xml +++ b/tex/context/interface/mkii/keys-fr.xml @@ -82,6 +82,7 @@ <cd:variable name='anchor' value='ancre'/> <cd:variable name='and' value='et'/> <cd:variable name='answerarea' value='zonereponse'/> + <cd:variable name='append' value='append'/> <cd:variable name='appendices' value='annexes'/> <cd:variable name='appendix' value='annexe'/> <cd:variable name='april' value='avril'/> @@ -210,6 +211,8 @@ <cd:variable name='fixed' value='fixe'/> <cd:variable name='flexible' value='flexible'/> <cd:variable name='float' value='flottant'/> + <cd:variable name='flushbackward' value='flushbackward'/> + <cd:variable name='flushforward' value='flushforward'/> <cd:variable name='flushinner' value='alignerinterieur'/> <cd:variable name='flushleft' value='alignergauche'/> <cd:variable name='flushouter' value='alignerexterieur'/> @@ -437,6 +440,7 @@ <cd:variable name='postscript' value='postscript'/> <cd:variable name='precedingpage' value='pageantecedent'/> <cd:variable name='preference' value='preference'/> + <cd:variable name='prepend' value='prepend'/> <cd:variable name='preview' value='apercu'/> <cd:variable name='previous' value='precedent'/> <cd:variable name='previousevenpage' value='pagepaireprecedente'/> @@ -1374,6 +1378,8 @@ <cd:element name='load' value='charger'/> <cd:element name='local' value='local'/> <cd:element name='makeup' value='composition'/> + <cd:element name='namednotation' value='namednotation'/> + <cd:element name='namedtyping' value='namedtyping'/> <cd:element name='next' value='suivant'/> <cd:element name='place' value='placer'/> <cd:element name='previous' value='precedent'/> @@ -1545,6 +1551,7 @@ <cd:command name='definereferencelist' value='définirlistereference'/> <cd:command name='defineregister' value='définirregistre'/> <cd:command name='definerule' value='définirtrait'/> + <cd:command name='definesavebuffer' value='startsavebuffer'/> <cd:command name='definesection' value='définirsection'/> <cd:command name='definesectionblock' value='définirblocsection'/> <cd:command name='definesorting' value='définirtri'/> @@ -1721,6 +1728,9 @@ <cd:command name='moveformula' value='deplacerformule'/> <cd:command name='moveongrid' value='deplacersurgrille'/> <cd:command name='movesidefloat' value='deplacerflottantcote'/> + <cd:command name='namedconstruction' value='namedconstruction'/> + <cd:command name='nameddescription' value='nameddescription'/> + <cd:command name='namedenumeration' value='namedenumeration'/> <cd:command name='navigating' value='navigation'/> <cd:command name='nodimension' value='sansdimension'/> <cd:command name='noheaderandfooterlines' value='sansentêtenipdp'/> @@ -2092,6 +2102,13 @@ <cd:command name='startmakeup' value='débutcomposition'/> <cd:command name='startmarginblock' value='débutblocmarge'/> <cd:command name='startmarginrule' value='débuttraitmarge'/> + <cd:command name='startnamedconstruction' value='startnamedconstruction'/> + <cd:command name='startnameddescription' value='startnameddescription'/> + <cd:command name='startnamedenumeration' value='startnamedenumeration'/> + <cd:command name='startnamedmatrix' value='startnamedmatrix'/> + <cd:command name='startnamedsection' value='startnamedsection'/> + <cd:command name='startnamedsubformulas' value='startnamedsubformulas'/> + <cd:command name='startnamedtyping' value='startnamedtyping'/> <cd:command name='startnarrower' value='débutplusetroit'/> <cd:command name='startopposite' value='débutopposition'/> <cd:command name='startoverlay' value='débutsuperposition'/> @@ -2135,6 +2152,13 @@ <cd:command name='stopmakeup' value='fincomposition'/> <cd:command name='stopmarginblock' value='finblocmarge'/> <cd:command name='stopmarginrule' value='fintraitmarge'/> + <cd:command name='stopnamedconstruction' value='stopnamedconstruction'/> + <cd:command name='stopnameddescription' value='stopnameddescription'/> + <cd:command name='stopnamedenumeration' value='stopnamedenumeration'/> + <cd:command name='stopnamedmatrix' value='stopnamedmatrix'/> + <cd:command name='stopnamedsection' value='stopnamedsection'/> + <cd:command name='stopnamedsubformulas' value='stopnamedsubformulas'/> + <cd:command name='stopnamedtyping' value='stopnamedtyping'/> <cd:command name='stopnarrower' value='finplusetroit'/> <cd:command name='stopopposite' value='finopposition'/> <cd:command name='stopoverlay' value='finsuperposition'/> diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 8985f55de..d874bda0f 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 2021-08-07 22:49 +-- merge date : 2021-08-10 12:37 do -- begin closure to overcome local limits and interference @@ -3474,7 +3474,7 @@ local template=[[ return function(%s) return %s end ]] local pattern=Cs(Cc('"')*( - (1-S('"\\\n\r'))^1+P('"')/'\\034'+P('\\')/'\\092'+P('\n')/'\\013'+P('\r')/'\\010' + (1-S('"\\\n\r'))^1+P('"')/'\\"'+P('\\')/'\\\\'+P('\n')/'\\n'+P('\r')/'\\r' )^0*Cc('"')) patterns.escapedquotes=pattern function string.escapedquotes(s) @@ -13423,6 +13423,7 @@ do local y=0 local width=false local lsb=0 +local result={} local r=0 local stems=0 local globalbias=0 @@ -14633,6 +14634,7 @@ do r=r+1 result[r]=c_endchar local stream=concat(result) +result=nil if glyph then glyph.stream=stream else @@ -14654,6 +14656,7 @@ do width=width, name=charset and charset[index] or nil, } +result=nil else glyphs[index]={ boundingbox=boundingbox, |