From c70b2e466bbb07e976f8684d56ae4e5398169e7d Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Sat, 22 Mar 2014 15:31:00 +0100 Subject: beta 2014.03.22 15:31 --- .../lexers/data/scite-context-data-context.lua | 4 +- .../scite/lexers/data/scite-context-data-tex.lua | 4 +- .../data/scite/lexers/scite-context-lexer-lua.lua | 45 +- .../data/scite/lexers/scite-context-lexer-tex.lua | 5 +- context/data/scite/lexers/scite-context-lexer.lua | 29 +- .../scite/scite-context-data-context.properties | 336 +++++----- .../data/scite/scite-context-data-tex.properties | 223 ++++--- doc/context/manuals/allkind/mkiv-publications.tex | 2 + doc/context/scripts/mkiv/context.html | 3 + doc/context/scripts/mkiv/context.man | 6 + doc/context/scripts/mkiv/context.xml | 10 +- doc/context/scripts/mkiv/mtx-context.html | 3 + doc/context/scripts/mkiv/mtx-context.man | 6 + doc/context/scripts/mkiv/mtx-context.xml | 10 +- metapost/context/fonts/bidi-symbols.tex | 2 +- scripts/context/lua/mtx-context.lua | 5 +- scripts/context/lua/mtx-context.xml | 10 +- scripts/context/lua/mtxrun.lua | 247 ++++--- scripts/context/stubs/install/first-setup.bat | 0 scripts/context/stubs/mswin/mtxrun.lua | 247 ++++--- scripts/context/stubs/setup/setuptex.bat | 0 scripts/context/stubs/unix/mtxrun | 247 ++++--- scripts/context/stubs/win64/mtxrun.lua | 247 ++++--- tex/context/base/anch-pos.lua | 66 +- tex/context/base/attr-lay.mkiv | 3 +- tex/context/base/back-exp.lua | 4 +- tex/context/base/back-ini.lua | 8 + tex/context/base/back-ini.mkiv | 11 +- tex/context/base/back-pdf.lua | 2 +- tex/context/base/back-pdf.mkiv | 2 +- tex/context/base/bibl-tra.lua | 10 +- tex/context/base/buff-imp-lua.lua | 2 +- tex/context/base/buff-ini.lua | 31 +- tex/context/base/buff-ver.lua | 64 +- tex/context/base/buff-ver.mkiv | 21 +- tex/context/base/catc-ctx.mkiv | 34 + tex/context/base/catc-ini.lua | 4 + tex/context/base/catc-ini.mkiv | 2 +- tex/context/base/catc-xml.mkiv | 21 +- tex/context/base/char-ini.lua | 3 + tex/context/base/char-ini.mkiv | 44 +- tex/context/base/cldf-ini.lua | 714 ++++++++++++++++----- tex/context/base/cldf-ini.mkiv | 9 + tex/context/base/cldf-ver.lua | 22 +- tex/context/base/colo-ini.lua | 47 +- tex/context/base/cont-new.mkiv | 2 +- tex/context/base/context-version.pdf | Bin 4096 -> 4082 bytes tex/context/base/context.mkiv | 6 +- tex/context/base/core-con.lua | 8 +- tex/context/base/core-env.mkiv | 18 +- tex/context/base/core-uti.lua | 61 +- tex/context/base/core-uti.mkiv | 16 +- tex/context/base/data-exp.lua | 4 +- tex/context/base/data-ini.lua | 2 +- tex/context/base/data-met.lua | 2 +- tex/context/base/data-res.lua | 8 +- tex/context/base/file-ini.lua | 22 +- tex/context/base/file-job.mkvi | 18 +- tex/context/base/file-mod.mkvi | 2 +- tex/context/base/file-res.lua | 2 +- tex/context/base/font-chk.lua | 2 +- tex/context/base/font-ctx.lua | 711 ++++++++++---------- tex/context/base/font-fea.mkvi | 10 +- tex/context/base/font-fil.mkvi | 4 +- tex/context/base/font-gds.lua | 2 +- tex/context/base/font-ini.mkvi | 86 ++- tex/context/base/font-lib.mkvi | 10 +- tex/context/base/font-mis.lua | 2 +- tex/context/base/font-odv.lua | 106 +-- tex/context/base/font-ota.lua | 3 + tex/context/base/font-otb.lua | 83 ++- tex/context/base/font-otc.lua | 7 + tex/context/base/font-otd.lua | 26 +- tex/context/base/font-otf.lua | 133 ++-- tex/context/base/font-otn.lua | 182 +++--- tex/context/base/font-otp.lua | 22 + tex/context/base/font-otx.lua | 93 ++- tex/context/base/font-sel.lua | 70 +- tex/context/base/font-sel.mkvi | 25 +- tex/context/base/font-set.mkvi | 29 +- tex/context/base/font-syn.lua | 10 +- tex/context/base/font-var.mkvi | 3 + tex/context/base/l-dir.lua | 7 +- tex/context/base/l-io.lua | 2 +- tex/context/base/l-os.lua | 20 +- tex/context/base/l-table.lua | 38 +- tex/context/base/l-unicode.lua | 9 +- tex/context/base/lang-def.mkiv | 4 + tex/context/base/lang-ini.mkiv | 4 +- tex/context/base/lang-lab.mkiv | 2 +- tex/context/base/lang-rep.lua | 2 +- tex/context/base/lpdf-ano.lua | 655 +++++++++++++------ tex/context/base/lpdf-col.lua | 90 +-- tex/context/base/lpdf-fld.lua | 191 ++++-- tex/context/base/lpdf-fmt.lua | 4 +- tex/context/base/lpdf-grp.lua | 2 +- tex/context/base/lpdf-ini.lua | 349 +++++----- tex/context/base/lpdf-mis.lua | 80 +-- tex/context/base/lpdf-mov.lua | 5 +- tex/context/base/lpdf-nod.lua | 118 ++-- tex/context/base/lpdf-ren.lua | 76 +-- tex/context/base/lpdf-swf.lua | 4 +- tex/context/base/lpdf-tag.lua | 147 ++--- tex/context/base/lpdf-u3d.lua | 6 +- tex/context/base/lpdf-wid.lua | 35 +- tex/context/base/luat-cbk.lua | 2 +- tex/context/base/luat-cnf.lua | 11 +- tex/context/base/luat-cod.lua | 5 +- tex/context/base/luat-ini.lua | 6 +- tex/context/base/luat-ini.mkiv | 71 +- tex/context/base/luat-run.lua | 76 ++- tex/context/base/luat-sto.lua | 121 ++-- tex/context/base/lxml-lpt.lua | 55 +- tex/context/base/lxml-tex.lua | 159 +++-- tex/context/base/m-spreadsheet.lua | 4 +- tex/context/base/math-dir.lua | 1 + tex/context/base/math-fbk.lua | 6 +- tex/context/base/math-fen.mkiv | 1 + tex/context/base/math-frc.mkiv | 2 +- tex/context/base/math-ini.lua | 24 +- tex/context/base/math-ini.mkiv | 33 +- tex/context/base/math-noa.lua | 5 +- tex/context/base/math-rad.mkvi | 4 +- tex/context/base/meta-fnt.lua | 4 +- tex/context/base/meta-pdf.lua | 4 +- tex/context/base/meta-tex.mkiv | 4 +- tex/context/base/mlib-pdf.lua | 56 +- tex/context/base/mlib-pps.lua | 44 +- tex/context/base/mult-aux.lua | 2 +- tex/context/base/mult-aux.mkiv | 292 ++++++++- tex/context/base/mult-def.lua | 6 +- tex/context/base/mult-def.mkiv | 6 + tex/context/base/mult-ini.lua | 6 +- tex/context/base/mult-low.lua | 9 +- tex/context/base/mult-nl.mkii | 4 +- tex/context/base/mult-prm.lua | 9 +- tex/context/base/node-aux.lua | 45 ++ tex/context/base/node-fin.lua | 3 +- tex/context/base/node-ini.mkiv | 6 +- tex/context/base/node-inj.lua | 20 +- tex/context/base/node-met.lua | 2 +- tex/context/base/node-nut.lua | 52 ++ tex/context/base/node-ref.lua | 71 +- tex/context/base/node-res.lua | 91 ++- tex/context/base/pack-com.mkiv | 4 +- tex/context/base/pack-mis.mkvi | 2 +- tex/context/base/pack-mrl.mkiv | 4 +- tex/context/base/pack-rul.lua | 2 - tex/context/base/page-flt.lua | 79 +-- tex/context/base/page-imp.mkiv | 2 +- tex/context/base/page-mix.lua | 121 +++- tex/context/base/page-mix.mkiv | 6 +- tex/context/base/page-mul.mkiv | 2 +- tex/context/base/page-txt.mkvi | 12 +- tex/context/base/pdfr-def.mkii | 2 +- tex/context/base/phys-dim.lua | 67 +- tex/context/base/publ-dat.lua | 10 +- tex/context/base/publ-ini.mkiv | 2 +- tex/context/base/s-abr-01.tex | 1 + tex/context/base/s-inf-03.mkiv | 1 - tex/context/base/scrn-but.mkvi | 4 +- tex/context/base/scrn-wid.mkvi | 2 +- tex/context/base/sort-ini.lua | 2 +- tex/context/base/spac-chr.lua | 2 + tex/context/base/spac-hor.mkiv | 57 +- tex/context/base/spac-ver.lua | 58 +- tex/context/base/spac-ver.mkiv | 18 +- tex/context/base/status-files.pdf | Bin 24795 -> 24618 bytes tex/context/base/status-lua.pdf | Bin 226993 -> 241486 bytes tex/context/base/strc-blk.lua | 2 +- tex/context/base/strc-con.mkvi | 5 +- tex/context/base/strc-des.mkvi | 4 +- tex/context/base/strc-doc.lua | 54 +- tex/context/base/strc-doc.mkiv | 3 +- tex/context/base/strc-enu.mkvi | 2 +- tex/context/base/strc-ini.lua | 73 ++- tex/context/base/strc-itm.mkvi | 2 +- tex/context/base/strc-lst.lua | 18 +- tex/context/base/strc-lst.mkvi | 8 +- tex/context/base/strc-mar.lua | 3 + tex/context/base/strc-not.mkvi | 11 +- tex/context/base/strc-num.lua | 9 +- tex/context/base/strc-num.mkiv | 16 +- tex/context/base/strc-pag.lua | 21 +- tex/context/base/strc-pag.mkiv | 6 +- tex/context/base/strc-ref.lua | 116 ++-- tex/context/base/strc-ref.mkvi | 3 +- tex/context/base/strc-reg.lua | 602 +++++++++++------ tex/context/base/strc-reg.mkiv | 250 +++++--- tex/context/base/strc-rsc.lua | 4 +- tex/context/base/strc-sec.mkiv | 74 ++- tex/context/base/strc-syn.lua | 35 +- tex/context/base/strc-syn.mkiv | 337 ++++++---- tex/context/base/syst-aux.lua | 5 +- tex/context/base/syst-aux.mkiv | 6 + tex/context/base/syst-con.lua | 44 +- tex/context/base/syst-lua.lua | 44 +- tex/context/base/tabl-tbl.lua | 20 +- tex/context/base/tabl-tbl.mkiv | 6 +- tex/context/base/tabl-xtb.lua | 1 - tex/context/base/tabl-xtb.mkvi | 16 +- tex/context/base/task-ini.lua | 7 + tex/context/base/trac-deb.lua | 109 ++-- tex/context/base/trac-inf.lua | 29 +- tex/context/base/trac-vis.lua | 8 +- tex/context/base/type-imp-ebgaramond.mkiv | 45 ++ tex/context/base/type-imp-latinmodern.mkiv | 5 +- tex/context/base/type-ini.mkvi | 12 +- tex/context/base/typo-brk.lua | 3 +- tex/context/base/typo-cln.lua | 1 + tex/context/base/typo-dha.lua | 5 +- tex/context/base/typo-dir.lua | 120 +--- tex/context/base/typo-drp.lua | 3 +- tex/context/base/typo-dua.lua | 2 +- tex/context/base/typo-dub.lua | 7 +- tex/context/base/typo-fln.lua | 5 +- tex/context/base/typo-fln.mkiv | 2 +- tex/context/base/typo-itc.lua | 1 + tex/context/base/typo-krn.mkiv | 2 +- tex/context/base/typo-mar.lua | 52 +- tex/context/base/typo-mar.mkiv | 8 +- tex/context/base/typo-prc.lua | 15 +- tex/context/base/typo-rep.lua | 2 +- tex/context/base/typo-spa.lua | 1 - tex/context/base/typo-tal.lua | 4 +- tex/context/base/typo-txt.mkvi | 2 +- tex/context/base/util-env.lua | 2 +- tex/context/base/util-prs.lua | 4 +- tex/context/base/util-str.lua | 125 +++- tex/context/base/util-tab.lua | 25 +- tex/context/interface/cont-nl.xml | 4 +- tex/context/interface/keys-nl.xml | 4 +- tex/context/sample/cervantes-es.tex | 6 + tex/context/sample/quevedo-es.tex | 19 + tex/generic/context/luatex/luatex-fonts-inj.lua | 11 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 275 +++++--- tex/generic/context/luatex/luatex-fonts-otn.lua | 24 +- 237 files changed, 7046 insertions(+), 3940 deletions(-) mode change 100755 => 100644 scripts/context/stubs/install/first-setup.bat mode change 100755 => 100644 scripts/context/stubs/setup/setuptex.bat create mode 100644 tex/context/base/type-imp-ebgaramond.mkiv create mode 100644 tex/context/sample/cervantes-es.tex create mode 100644 tex/context/sample/quevedo-es.tex diff --git a/context/data/scite/lexers/data/scite-context-data-context.lua b/context/data/scite/lexers/data/scite-context-data-context.lua index 0d577c8da..720eb1d22 100644 --- a/context/data/scite/lexers/data/scite-context-data-context.lua +++ b/context/data/scite/lexers/data/scite-context-data-context.lua @@ -1,4 +1,4 @@ return { - ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "etexversion", "pdftexversion", "xetexversion", "xetexrevision", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifmodeelse", "doifnotmode", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "setupdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "breakablethinspace", "nobreakspace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj" }, - ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "doifelsecommandhandler", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "scratchdimen", "globalscratchdimen", "scratchskip", "globalscratchskip", "scratchmuskip", "globalscratchmuskip", "scratchtoks", "globalscratchtoks", "scratchbox", "globalscratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifinsetelse", "doifnextcharelse", "doifnextoptionalelse", "doifnextbgroupelse", "doifnextparenthesiselse", "doiffastoptionalcheckelse", "doifundefinedelse", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifdimensionelse", "doifnumberelse", "doifnumber", "doifnotnumber", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifinstringelse", "doifassignmentelse", "docheckassignment", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "strut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "begstrut", "endstrut", "lineheight", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expdoifelse", "expdoif", "expdoifnot", "expdoifcommonelse", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "carryoverpar", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "lefttoright", "righttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath" }, + ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "etexversion", "pdftexversion", "xetexversion", "xetexrevision", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "ctdcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifmodeelse", "doifnotmode", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "setupdocument", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule", "setupmodule", "currentmoduleparameter", "moduleparameter", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "globalenablemode", "globaldisablemode", "globalpreventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile", "luastringsep", "!!bs", "!!es", "lefttorightmark", "righttoleftmark", "breakablethinspace", "nobreakspace", "narrownobreakspace", "zerowidthnobreakspace", "ideographicspace", "ideographichalffillspace", "twoperemspace", "threeperemspace", "fourperemspace", "fiveperemspace", "sixperemspace", "figurespace", "punctuationspace", "hairspace", "zerowidthspace", "zerowidthnonjoiner", "zerowidthjoiner", "zwnj", "zwj" }, + ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "startcontextdefinitioncode", "stopcontextdefinitioncode", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "doifelsecommandhandler", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "begcsname", "strippedcsname", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "filledhboxb", "filledhboxr", "filledhboxg", "filledhboxc", "filledhboxm", "filledhboxy", "filledhboxk", "scratchcounter", "globalscratchcounter", "scratchdimen", "globalscratchdimen", "scratchskip", "globalscratchskip", "scratchmuskip", "globalscratchmuskip", "scratchtoks", "globalscratchtoks", "scratchbox", "globalscratchbox", "normalbaselineskip", "normallineskip", "normallineskiplimit", "availablehsize", "localhsize", "setlocalhsize", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchunicode", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifinsetelse", "doifnextcharelse", "doifnextoptionalelse", "doifnextoptionalcselse", "doiffastoptionalcheckelse", "doifnextbgroupelse", "doifnextbgroupcselse", "doifnextparenthesiselse", "doifundefinedelse", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifdimensionelse", "doifnumberelse", "doifnumber", "doifnotnumber", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifinstringelse", "doifassignmentelse", "docheckassignment", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "obeyspaces", "obeylines", "obeyedspace", "obeyedline", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "wait", "writestatus", "define", "defineexpandable", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "measured", "installcorenamespace", "getvalue", "getuvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "checked", "unique", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "dowith", "newconstant", "setnewconstant", "setconstant", "setconstantvalue", "newconditional", "settrue", "setfalse", "settruevalue", "setfalsevalue", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "leftorright", "strut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "begstrut", "endstrut", "lineheight", "ordordspacing", "ordopspacing", "ordbinspacing", "ordrelspacing", "ordopenspacing", "ordclosespacing", "ordpunctspacing", "ordinnerspacing", "opordspacing", "opopspacing", "opbinspacing", "oprelspacing", "opopenspacing", "opclosespacing", "oppunctspacing", "opinnerspacing", "binordspacing", "binopspacing", "binbinspacing", "binrelspacing", "binopenspacing", "binclosespacing", "binpunctspacing", "bininnerspacing", "relordspacing", "relopspacing", "relbinspacing", "relrelspacing", "relopenspacing", "relclosespacing", "relpunctspacing", "relinnerspacing", "openordspacing", "openopspacing", "openbinspacing", "openrelspacing", "openopenspacing", "openclosespacing", "openpunctspacing", "openinnerspacing", "closeordspacing", "closeopspacing", "closebinspacing", "closerelspacing", "closeopenspacing", "closeclosespacing", "closepunctspacing", "closeinnerspacing", "punctordspacing", "punctopspacing", "punctbinspacing", "punctrelspacing", "punctopenspacing", "punctclosespacing", "punctpunctspacing", "punctinnerspacing", "innerordspacing", "inneropspacing", "innerbinspacing", "innerrelspacing", "inneropenspacing", "innerclosespacing", "innerpunctspacing", "innerinnerspacing", "normalreqno", "startimath", "stopimath", "normalstartimath", "normalstopimath", "startdmath", "stopdmath", "normalstartdmath", "normalstopdmath", "uncramped", "cramped", "triggermathstyle", "mathstylefont", "mathsmallstylefont", "mathstyleface", "mathsmallstyleface", "mathstylecommand", "mathpalette", "mathstylehbox", "mathstylevbox", "mathstylevcenter", "mathstylevcenteredhbox", "mathstylevcenteredvbox", "mathtext", "setmathsmalltextbox", "setmathtextbox", "triggerdisplaystyle", "triggertextstyle", "triggerscriptstyle", "triggerscriptscriptstyle", "triggeruncrampedstyle", "triggercrampedstyle", "triggersmallstyle", "triggeruncrampedsmallstyle", "triggercrampedsmallstyle", "triggerbigstyle", "triggeruncrampedbigstyle", "triggercrampedbigstyle", "luaexpr", "expdoifelse", "expdoif", "expdoifnot", "expdoifcommonelse", "expdoifinsetelse", "ctxdirectlua", "ctxlatelua", "ctxsprint", "ctxwrite", "ctxcommand", "ctxdirectcommand", "ctxlatecommand", "ctxreport", "ctxlua", "luacode", "lateluacode", "directluacode", "registerctxluafile", "ctxloadluafile", "luaversion", "luamajorversion", "luaminorversion", "ctxluacode", "luaconditional", "luaexpanded", "startluaparameterset", "stopluaparameterset", "luaparameterset", "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction", "stopctxfunction", "ctxfunction", "startctxfunctiondefinition", "stopctxfunctiondefinition", "carryoverpar", "assumelongusagecs", "Umathbotaccent", "righttolefthbox", "lefttorighthbox", "righttoleftvbox", "lefttorightvbox", "righttoleftvtop", "lefttorightvtop", "rtlhbox", "ltrhbox", "rtlvbox", "ltrvbox", "rtlvtop", "ltrvtop", "autodirhbox", "autodirvbox", "autodirvtop", "lefttoright", "righttoleft", "synchronizelayoutdirection", "synchronizedisplaydirection", "synchronizeinlinedirection", "lesshyphens", "morehyphens", "nohyphens", "dohyphens", "Ucheckedstartdisplaymath", "Ucheckedstopdisplaymath" }, } \ No newline at end of file diff --git a/context/data/scite/lexers/data/scite-context-data-tex.lua b/context/data/scite/lexers/data/scite-context-data-tex.lua index 7d710740c..415b74128 100644 --- a/context/data/scite/lexers/data/scite-context-data-tex.lua +++ b/context/data/scite/lexers/data/scite-context-data-tex.lua @@ -1,9 +1,9 @@ return { ["aleph"]={ "AlephVersion", "Alephminorversion", "Alephrevision", "Alephversion", "Omegaminorversion", "Omegarevision", "Omegaversion", "boxdir", "pagebottomoffset", "pagerightoffset" }, ["etex"]={ "botmarks", "clubpenalties", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "detokenize", "dimexpr", "displaywidowpenalties", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "everyeof", "firstmarks", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "ifcsname", "ifdefined", "iffontchar", "interactionmode", "interlinepenalties", "lastlinefit", "lastnodetype", "marks", "muexpr", "mutoglue", "numexpr", "pagediscards", "parshapedimen", "parshapeindent", "parshapelength", "predisplaydirection", "protected", "readline", "savinghyphcodes", "savingvdiscards", "scantokens", "showgroups", "showifs", "showtokens", "splitbotmarks", "splitdiscards", "splitfirstmarks", "topmarks", "tracingassigns", "tracinggroups", "tracingifs", "tracingnesting", "tracingscantokens", "unexpanded", "unless", "widowpenalties" }, - ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathchardef", "Umathcharnum", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Uoverdelimiter", "Uradical", "Uroot", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "alignmark", "aligntab", "attribute", "attributedef", "catcodetable", "clearmarks", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "fontid", "formatname", "gleaders", "ifabsdim", "ifabsnum", "ifprimitive", "initcatcodetable", "latelua", "luaescapestring", "luastartup", "luatexdatestamp", "luatexrevision", "luatexversion", "mathstyle", "nokerns", "noligs", "outputbox", "pageleftoffset", "pagetopoffset", "postexhyphenchar", "posthyphenchar", "preexhyphenchar", "prehyphenchar", "primitive", "savecatcodetable", "scantextokens", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressoutererror", "synctex" }, + ["luatex"]={ "Uchar", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathchardef", "Umathcharnum", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Uoverdelimiter", "Uradical", "Uroot", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "alignmark", "aligntab", "attribute", "attributedef", "catcodetable", "clearmarks", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "fontid", "formatname", "gleaders", "ifabsdim", "ifabsnum", "ifprimitive", "initcatcodetable", "latelua", "luaescapestring", "luastartup", "luatexdatestamp", "luatexrevision", "luatexversion", "luafunction", "mathstyle", "nokerns", "noligs", "outputbox", "pageleftoffset", "pagetopoffset", "postexhyphenchar", "posthyphenchar", "preexhyphenchar", "prehyphenchar", "primitive", "savecatcodetable", "scantextokens", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressoutererror", "synctex" }, ["omega"]={ "OmegaVersion", "bodydir", "chardp", "charht", "charit", "charwd", "leftghost", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "mathdir", "odelcode", "odelimiter", "omathaccent", "omathchar", "omathchardef", "omathcode", "oradical", "pagedir", "pageheight", "pagewidth", "pardir", "rightghost", "textdir" }, ["pdftex"]={ "efcode", "expanded", "ifincsname", "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "leftmarginkern", "letterspacefont", "lpcode", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagecolordepth", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfoptionpdfminorversion", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformname", "pdfxformresources", "pdfximage", "pdfximagebbox", "quitvmode", "rightmarginkern", "rpcode", "tagcode" }, - ["tex"]={ "-", "/", "AlephVersion", "Alephminorversion", "Alephrevision", "Alephversion", "OmegaVersion", "Omegaminorversion", "Omegarevision", "Omegaversion", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathchardef", "Umathcharnum", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Uoverdelimiter", "Uradical", "Uroot", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "alignmark", "aligntab", "atop", "atopwithdelims", "attribute", "attributedef", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "bodydir", "botmark", "botmarks", "box", "boxdir", "boxmaxdepth", "brokenpenalty", "catcode", "catcodetable", "char", "chardef", "chardp", "charht", "charit", "charwd", "cleaders", "clearmarks", "closein", "closeout", "clubpenalties", "clubpenalty", "copy", "count", "countdef", "cr", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "crcr", "csname", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "detokenize", "dimen", "dimendef", "dimexpr", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalties", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "edef", "efcode", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyeof", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "expanded", "fam", "fi", "finalhyphendemerits", "firstmark", "firstmarks", "floatingpenalty", "font", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "fontdimen", "fontid", "fontname", "formatname", "futurelet", "gdef", "gleaders", "global", "globaldefs", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifabsdim", "ifabsnum", "ifcase", "ifcat", "ifcsname", "ifdefined", "ifdim", "ifeof", "iffalse", "iffontchar", "ifhbox", "ifhmode", "ifincsname", "ifinner", "ifmmode", "ifnum", "ifodd", "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "ifprimitive", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "immediate", "indent", "initcatcodetable", "input", "inputlineno", "insert", "insertpenalties", "interactionmode", "interlinepenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastlinefit", "lastnodetype", "lastpenalty", "lastskip", "latelua", "lccode", "leaders", "left", "leftghost", "lefthyphenmin", "leftmarginkern", "leftskip", "leqno", "let", "letterspacefont", "limits", "linepenalty", "lineskip", "lineskiplimit", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "long", "looseness", "lower", "lowercase", "lpcode", "luaescapestring", "luastartup", "luatexdatestamp", "luatexrevision", "luatexversion", "mag", "mark", "marks", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathdir", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathstyle", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "muexpr", "multiply", "muskip", "muskipdef", "mutoglue", "newlinechar", "noalign", "noboundary", "noexpand", "noindent", "nokerns", "noligs", "nolimits", "nolocaldirs", "nolocalwhatsits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "numexpr", "odelcode", "odelimiter", "omathaccent", "omathchar", "omathchardef", "omathcode", "omit", "openin", "openout", "or", "oradical", "outer", "output", "outputbox", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagebottomoffset", "pagedepth", "pagedir", "pagediscards", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageheight", "pageleftoffset", "pagerightoffset", "pageshrink", "pagestretch", "pagetopoffset", "pagetotal", "pagewidth", "par", "pardir", "parfillskip", "parindent", "parshape", "parshapedimen", "parshapeindent", "parshapelength", "parskip", "patterns", "pausing", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagecolordepth", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfoptionpdfminorversion", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformname", "pdfxformresources", "pdfximage", "pdfximagebbox", "penalty", "postdisplaypenalty", "postexhyphenchar", "posthyphenchar", "predisplaydirection", "predisplaypenalty", "predisplaysize", "preexhyphenchar", "prehyphenchar", "pretolerance", "prevdepth", "prevgraf", "primitive", "protected", "quitvmode", "radical", "raise", "read", "readline", "relax", "relpenalty", "right", "rightghost", "righthyphenmin", "rightmarginkern", "rightskip", "romannumeral", "rpcode", "savecatcodetable", "savinghyphcodes", "savingvdiscards", "scantextokens", "scantokens", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showgroups", "showifs", "showlists", "showthe", "showtokens", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "special", "splitbotmark", "splitbotmarks", "splitdiscards", "splitfirstmark", "splitfirstmarks", "splitmaxdepth", "splittopskip", "string", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressoutererror", "synctex", "tabskip", "tagcode", "textdir", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topmarks", "topskip", "tracingassigns", "tracingcommands", "tracinggroups", "tracingifs", "tracinglostchars", "tracingmacros", "tracingnesting", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingscantokens", "tracingstats", "uccode", "uchyph", "underline", "unexpanded", "unhbox", "unhcopy", "unkern", "unless", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalties", "widowpenalty", "write", "xdef", "xleaders", "xspaceskip", "year" }, + ["tex"]={ "-", "/", "AlephVersion", "Alephminorversion", "Alephrevision", "Alephversion", "OmegaVersion", "Omegaminorversion", "Omegarevision", "Omegaversion", "Udelcode", "Udelcodenum", "Udelimiter", "Udelimiterover", "Udelimiterunder", "Umathaccent", "Umathaxis", "Umathbinbinspacing", "Umathbinclosespacing", "Umathbininnerspacing", "Umathbinopenspacing", "Umathbinopspacing", "Umathbinordspacing", "Umathbinpunctspacing", "Umathbinrelspacing", "Umathchar", "Umathchardef", "Umathcharnum", "Umathclosebinspacing", "Umathcloseclosespacing", "Umathcloseinnerspacing", "Umathcloseopenspacing", "Umathcloseopspacing", "Umathcloseordspacing", "Umathclosepunctspacing", "Umathcloserelspacing", "Umathcode", "Umathcodenum", "Umathconnectoroverlapmin", "Umathfractiondelsize", "Umathfractiondenomdown", "Umathfractiondenomvgap", "Umathfractionnumup", "Umathfractionnumvgap", "Umathfractionrule", "Umathinnerbinspacing", "Umathinnerclosespacing", "Umathinnerinnerspacing", "Umathinneropenspacing", "Umathinneropspacing", "Umathinnerordspacing", "Umathinnerpunctspacing", "Umathinnerrelspacing", "Umathlimitabovebgap", "Umathlimitabovekern", "Umathlimitabovevgap", "Umathlimitbelowbgap", "Umathlimitbelowkern", "Umathlimitbelowvgap", "Umathopbinspacing", "Umathopclosespacing", "Umathopenbinspacing", "Umathopenclosespacing", "Umathopeninnerspacing", "Umathopenopenspacing", "Umathopenopspacing", "Umathopenordspacing", "Umathopenpunctspacing", "Umathopenrelspacing", "Umathoperatorsize", "Umathopinnerspacing", "Umathopopenspacing", "Umathopopspacing", "Umathopordspacing", "Umathoppunctspacing", "Umathoprelspacing", "Umathordbinspacing", "Umathordclosespacing", "Umathordinnerspacing", "Umathordopenspacing", "Umathordopspacing", "Umathordordspacing", "Umathordpunctspacing", "Umathordrelspacing", "Umathoverbarkern", "Umathoverbarrule", "Umathoverbarvgap", "Umathoverdelimiterbgap", "Umathoverdelimitervgap", "Umathpunctbinspacing", "Umathpunctclosespacing", "Umathpunctinnerspacing", "Umathpunctopenspacing", "Umathpunctopspacing", "Umathpunctordspacing", "Umathpunctpunctspacing", "Umathpunctrelspacing", "Umathquad", "Umathradicaldegreeafter", "Umathradicaldegreebefore", "Umathradicaldegreeraise", "Umathradicalkern", "Umathradicalrule", "Umathradicalvgap", "Umathrelbinspacing", "Umathrelclosespacing", "Umathrelinnerspacing", "Umathrelopenspacing", "Umathrelopspacing", "Umathrelordspacing", "Umathrelpunctspacing", "Umathrelrelspacing", "Umathspaceafterscript", "Umathstackdenomdown", "Umathstacknumup", "Umathstackvgap", "Umathsubshiftdown", "Umathsubshiftdrop", "Umathsubsupshiftdown", "Umathsubsupvgap", "Umathsubtopmax", "Umathsupbottommin", "Umathsupshiftdrop", "Umathsupshiftup", "Umathsupsubbottommax", "Umathunderbarkern", "Umathunderbarrule", "Umathunderbarvgap", "Umathunderdelimiterbgap", "Umathunderdelimitervgap", "Uoverdelimiter", "Uradical", "Uroot", "Ustack", "Ustartdisplaymath", "Ustartmath", "Ustopdisplaymath", "Ustopmath", "Usubscript", "Usuperscript", "Uunderdelimiter", "above", "abovedisplayshortskip", "abovedisplayskip", "abovewithdelims", "accent", "adjdemerits", "advance", "afterassignment", "aftergroup", "alignmark", "aligntab", "atop", "atopwithdelims", "attribute", "attributedef", "badness", "baselineskip", "batchmode", "begingroup", "belowdisplayshortskip", "belowdisplayskip", "binoppenalty", "bodydir", "botmark", "botmarks", "box", "boxdir", "boxmaxdepth", "brokenpenalty", "catcode", "catcodetable", "char", "chardef", "cleaders", "clearmarks", "closein", "closeout", "clubpenalties", "clubpenalty", "copy", "count", "countdef", "cr", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", "crcr", "csname", "currentgrouplevel", "currentgrouptype", "currentifbranch", "currentiflevel", "currentiftype", "day", "deadcycles", "def", "defaulthyphenchar", "defaultskewchar", "delcode", "delimiter", "delimiterfactor", "delimitershortfall", "detokenize", "dimen", "dimendef", "dimexpr", "directlua", "discretionary", "displayindent", "displaylimits", "displaystyle", "displaywidowpenalties", "displaywidowpenalty", "displaywidth", "divide", "doublehyphendemerits", "dp", "dump", "eTeXVersion", "eTeXminorversion", "eTeXrevision", "eTeXversion", "edef", "efcode", "else", "emergencystretch", "end", "endcsname", "endgroup", "endinput", "endlinechar", "eqno", "errhelp", "errmessage", "errorcontextlines", "errorstopmode", "escapechar", "everycr", "everydisplay", "everyeof", "everyhbox", "everyjob", "everymath", "everypar", "everyvbox", "exhyphenchar", "exhyphenpenalty", "expandafter", "expanded", "fam", "fi", "finalhyphendemerits", "firstmark", "firstmarks", "floatingpenalty", "font", "fontchardp", "fontcharht", "fontcharic", "fontcharwd", "fontdimen", "fontid", "fontname", "formatname", "futurelet", "gdef", "gleaders", "global", "globaldefs", "glueexpr", "glueshrink", "glueshrinkorder", "gluestretch", "gluestretchorder", "gluetomu", "halign", "hangafter", "hangindent", "hbadness", "hbox", "hfil", "hfill", "hfilneg", "hfuzz", "hoffset", "holdinginserts", "hrule", "hsize", "hskip", "hss", "ht", "hyphenation", "hyphenchar", "hyphenpenalty", "if", "ifabsdim", "ifabsnum", "ifcase", "ifcat", "ifcsname", "ifdefined", "ifdim", "ifeof", "iffalse", "iffontchar", "ifhbox", "ifhmode", "ifincsname", "ifinner", "ifmmode", "ifnum", "ifodd", "ifpdfabsdim", "ifpdfabsnum", "ifpdfprimitive", "ifprimitive", "iftrue", "ifvbox", "ifvmode", "ifvoid", "ifx", "ignorespaces", "immediate", "indent", "initcatcodetable", "input", "inputlineno", "insert", "insertpenalties", "interactionmode", "interlinepenalties", "interlinepenalty", "jobname", "kern", "language", "lastbox", "lastkern", "lastlinefit", "lastnodetype", "lastpenalty", "lastskip", "latelua", "lccode", "leaders", "left", "leftghost", "lefthyphenmin", "leftmarginkern", "leftskip", "leqno", "let", "letterspacefont", "limits", "linepenalty", "lineskip", "lineskiplimit", "localbrokenpenalty", "localinterlinepenalty", "localleftbox", "localrightbox", "long", "looseness", "lower", "lowercase", "lpcode", "luaescapestring", "luastartup", "luatexdatestamp", "luatexrevision", "luatexversion", "mag", "mark", "marks", "mathaccent", "mathbin", "mathchar", "mathchardef", "mathchoice", "mathclose", "mathcode", "mathdir", "mathinner", "mathop", "mathopen", "mathord", "mathpunct", "mathrel", "mathstyle", "mathsurround", "maxdeadcycles", "maxdepth", "meaning", "medmuskip", "message", "middle", "mkern", "month", "moveleft", "moveright", "mskip", "muexpr", "multiply", "muskip", "muskipdef", "mutoglue", "newlinechar", "noalign", "noboundary", "noexpand", "noindent", "nokerns", "noligs", "nolimits", "nolocaldirs", "nolocalwhatsits", "nonscript", "nonstopmode", "nulldelimiterspace", "nullfont", "number", "numexpr", "odelcode", "odelimiter", "omathaccent", "omathchar", "omathchardef", "omathcode", "omit", "openin", "openout", "or", "oradical", "outer", "output", "outputbox", "outputpenalty", "over", "overfullrule", "overline", "overwithdelims", "pagebottomoffset", "pagedepth", "pagedir", "pagediscards", "pagefilllstretch", "pagefillstretch", "pagefilstretch", "pagegoal", "pageheight", "pageleftoffset", "pagerightoffset", "pageshrink", "pagestretch", "pagetopoffset", "pagetotal", "pagewidth", "par", "pardir", "parfillskip", "parindent", "parshape", "parshapedimen", "parshapeindent", "parshapelength", "parskip", "patterns", "pausing", "pdfadjustspacing", "pdfannot", "pdfcatalog", "pdfcolorstack", "pdfcolorstackinit", "pdfcompresslevel", "pdfcopyfont", "pdfcreationdate", "pdfdecimaldigits", "pdfdest", "pdfdestmargin", "pdfdraftmode", "pdfeachlinedepth", "pdfeachlineheight", "pdfendlink", "pdfendthread", "pdffirstlineheight", "pdffontattr", "pdffontexpand", "pdffontname", "pdffontobjnum", "pdffontsize", "pdfgamma", "pdfgentounicode", "pdfglyphtounicode", "pdfhorigin", "pdfignoreddimen", "pdfimageapplygamma", "pdfimagegamma", "pdfimagehicolor", "pdfimageresolution", "pdfincludechars", "pdfinclusioncopyfonts", "pdfinclusionerrorlevel", "pdfinfo", "pdfinsertht", "pdflastannot", "pdflastlinedepth", "pdflastlink", "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagecolordepth", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmapfile", "pdfmapline", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", "pdfoptionpdfminorversion", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkmode", "pdfpkresolution", "pdfprimitive", "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", "pdfrefobj", "pdfrefxform", "pdfrefximage", "pdfreplacefont", "pdfrestore", "pdfretval", "pdfsave", "pdfsavepos", "pdfsetmatrix", "pdfsetrandomseed", "pdfstartlink", "pdfstartthread", "pdftexbanner", "pdftexrevision", "pdftexversion", "pdfthread", "pdfthreadmargin", "pdftracingfonts", "pdftrailer", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformname", "pdfxformresources", "pdfximage", "pdfximagebbox", "penalty", "postdisplaypenalty", "postexhyphenchar", "posthyphenchar", "predisplaydirection", "predisplaypenalty", "predisplaysize", "preexhyphenchar", "prehyphenchar", "pretolerance", "prevdepth", "prevgraf", "primitive", "protected", "quitvmode", "radical", "raise", "read", "readline", "relax", "relpenalty", "right", "rightghost", "righthyphenmin", "rightmarginkern", "rightskip", "romannumeral", "rpcode", "savecatcodetable", "savinghyphcodes", "savingvdiscards", "scantextokens", "scantokens", "scriptfont", "scriptscriptfont", "scriptscriptstyle", "scriptspace", "scriptstyle", "scrollmode", "setbox", "setlanguage", "sfcode", "shipout", "show", "showbox", "showboxbreadth", "showboxdepth", "showgroups", "showifs", "showlists", "showthe", "showtokens", "skewchar", "skip", "skipdef", "spacefactor", "spaceskip", "span", "special", "splitbotmark", "splitbotmarks", "splitdiscards", "splitfirstmark", "splitfirstmarks", "splitmaxdepth", "splittopskip", "string", "suppressfontnotfounderror", "suppressifcsnameerror", "suppresslongerror", "suppressoutererror", "synctex", "tabskip", "tagcode", "textdir", "textfont", "textstyle", "the", "thickmuskip", "thinmuskip", "time", "toks", "toksdef", "tolerance", "topmark", "topmarks", "topskip", "tracingassigns", "tracingcommands", "tracinggroups", "tracingifs", "tracinglostchars", "tracingmacros", "tracingnesting", "tracingonline", "tracingoutput", "tracingpages", "tracingparagraphs", "tracingrestores", "tracingscantokens", "tracingstats", "uccode", "uchyph", "underline", "unexpanded", "unhbox", "unhcopy", "unkern", "unless", "unpenalty", "unskip", "unvbox", "unvcopy", "uppercase", "vadjust", "valign", "vbadness", "vbox", "vcenter", "vfil", "vfill", "vfilneg", "vfuzz", "voffset", "vrule", "vsize", "vskip", "vsplit", "vss", "vtop", "wd", "widowpenalties", "widowpenalty", "write", "xdef", "xleaders", "xspaceskip", "year" }, ["xetex"]={ "XeTeXversion" }, } \ No newline at end of file diff --git a/context/data/scite/lexers/scite-context-lexer-lua.lua b/context/data/scite/lexers/scite-context-lexer-lua.lua index 4c276b1bb..54c480ab3 100644 --- a/context/data/scite/lexers/scite-context-lexer-lua.lua +++ b/context/data/scite/lexers/scite-context-lexer-lua.lua @@ -11,8 +11,8 @@ local info = { if not lexer._CONTEXTEXTENSIONS then require("scite-context-lexer") end local lexer = lexer -local token, style, colors, exact_match, no_style = lexer.token, lexer.style, lexer.colors, lexer.exact_match, lexer.style_nothing -local P, R, S, C, Cg, Cb, Cs, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cg, lpeg.Cb, lpeg.Cs, lpeg.Cmt +local token, style, colors, exact_match, just_match, no_style = lexer.token, lexer.style, lexer.colors, lexer.exact_match, lexer.just_match, lexer.style_nothing +local P, R, S, C, Cg, Cb, Cs, Cmt, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cg, lpeg.Cb, lpeg.Cs, lpeg.Cmt, lpeg.Cp local match, find = string.match, string.find local setmetatable = setmetatable @@ -29,6 +29,9 @@ local directives = { } -- communication channel -- this will be extended +-- we could combine some in a hash that returns the class that then makes the token +-- this can save time on large files + local keywords = { 'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', -- 'goto', 'if', 'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', @@ -54,6 +57,12 @@ local constants = { 'NaN', } +-- local tokenmappings = { } +-- +-- for i=1,#keywords do tokenmappings[keywords [i]] = "keyword" } +-- for i=1,#functions do tokenmappings[functions[i]] = "function" } +-- for i=1,#constants do tokenmappings[constants[i]] = "constant" } + local internals = { -- __ 'add', 'call', 'concat', 'div', 'eq', 'gc', 'index', 'le', 'lt', 'metatable', 'mode', 'mul', 'newindex', @@ -67,7 +76,9 @@ local depricated = { } local csnames = { -- todo: option + "commands", "context", + "ctx", "metafun", "metapost", } @@ -154,16 +165,18 @@ local number = token("number", lexer.float + integer) -- officially 127-255 are ok but not utf so useless -local validword = R("AZ","az","__") * R("AZ","az","__","09")^0 +----- validword = R("AZ","az","__") * R("AZ","az","__","09")^0 local utf8character = P(1) * R("\128\191")^1 local validword = (R("AZ","az","__") + utf8character) * (R("AZ","az","__","09") + utf8character)^0 +local validsuffix = (R("AZ","az") + utf8character) * (R("AZ","az","__","09") + utf8character)^0 local identifier = token("default",validword) ----- operator = token("special", P('..') + P('~=') + S('+-*/%^#=<>;:,.{}[]()')) -- maybe split off {}[]() ----- operator = token("special", S('+-*/%^#=<>;:,{}[]()') + P('..') + P('.') + P('~=') ) -- maybe split off {}[]() -local operator = token("special", S('+-*/%^#=<>;:,{}[]().') + P('~=') ) -- no ^1 because of nested lexers +----- operator = token("special", S('+-*/%^#=<>;:,{}[]().') + P('~=') ) -- no ^1 because of nested lexers +local operator = token("special", S('+-*/%^#=<>;:,{}[]().|~')) -- no ^1 because of nested lexers local structure = token("special", S('{}[]()')) @@ -182,8 +195,7 @@ local p_functions = exact_match(functions) local p_constants = exact_match(constants) local p_internals = P("__") * exact_match(internals) -local p_csnames = exact_match(csnames) - +local p_csnames = just_match(csnames) local keyword = token("keyword", p_keywords) local builtin = token("plain", p_functions) local constant = token("data", p_constants) @@ -191,8 +203,10 @@ local internal = token("data", p_internals) local csname = token("user", p_csnames) * ( optionalspace * hasargument - + ( optionalspace * token("special", S(".:")) * optionalspace * token("user", validword) )^1 + + ( optionalspace * token("special", S(".:")) * optionalspace * token("user", validword ) )^1 + + token("user", P("_") * validsuffix) ) + local identifier = token("default", validword) * ( optionalspace * token("special", S(".:")) * optionalspace * ( token("warning", p_keywords) + @@ -200,13 +214,24 @@ local identifier = token("default", validword) token("default", validword ) ) )^0 +-- local t = { } for k, v in next, tokenmappings do t[#t+1] = k end t = table.concat(t) +-- -- local experimental = (S(t)^1) / function(s) return tokenmappings[s] end * Cp() +-- +-- local experimental = Cmt(S(t)^1, function(_,i,s) +-- local t = tokenmappings[s] +-- if t then +-- return true, t, i +-- end +-- end) + lualexer._rules = { { 'whitespace', spacing }, - { 'keyword', keyword }, + { 'keyword', keyword }, -- can be combined -- { 'structure', structure }, - { 'function', builtin }, + { 'function', builtin }, -- can be combined + { 'constant', constant }, -- can be combined + -- { 'experimental', experimental }, -- works but better split { 'csname', csname }, - { 'constant', constant }, { 'goto', gotokeyword }, { 'identifier', identifier }, { 'string', string }, diff --git a/context/data/scite/lexers/scite-context-lexer-tex.lua b/context/data/scite/lexers/scite-context-lexer-tex.lua index a509fadab..55072cde8 100644 --- a/context/data/scite/lexers/scite-context-lexer-tex.lua +++ b/context/data/scite/lexers/scite-context-lexer-tex.lua @@ -390,10 +390,11 @@ contextlexer._reset_parser = function() end local luaenvironment = P("lua") * (P("setups") + P("code") + P(true)) + + P("ctxfunction") * (P("definition") + P(true)) local inlinelua = P("\\") * ( - P("ctx") * ( P("lua") + P("command") + P("late") * (P("lua") + P("command")) ) - + P("cld") * ( P("command") + P("context") ) + P("ctx") * (P("lua") + P("command") + P("late") * (P("lua") + P("command")) + P("function")) + + P("cld") * (P("command") + P("context")) + P("luaexpr") + (P("direct") + P("late")) * P("lua") ) diff --git a/context/data/scite/lexers/scite-context-lexer.lua b/context/data/scite/lexers/scite-context-lexer.lua index 5c7f40e7d..7c4f7b077 100644 --- a/context/data/scite/lexers/scite-context-lexer.lua +++ b/context/data/scite/lexers/scite-context-lexer.lua @@ -271,16 +271,28 @@ function context.exact_match(words,word_chars,case_insensitive) end if case_insensitive then local list = { } - for i=1,#words do - list[lower(words[i])] = true + if #words == 0 then + for k, v in next, words do + list[lower(k)] = v + end + else + for i=1,#words do + list[lower(words[i])] = true + end end return Cmt(pattern^1, function(_,i,s) return list[lower(s)] -- and i or nil end) else local list = { } - for i=1,#words do - list[words[i]] = true + if #words == 0 then + for k, v in next, words do + list[k] = v + end + else + for i=1,#words do + list[words[i]] = true + end end return Cmt(pattern^1, function(_,i,s) return list[s] -- and i or nil @@ -288,6 +300,14 @@ function context.exact_match(words,word_chars,case_insensitive) end end +function context.just_match(words) + local p = P(words[1]) + for i=2,#words do + p = p + P(words[i]) + end + return p +end + -- spell checking (we can only load lua files) -- -- return { @@ -752,6 +772,7 @@ lexers.fold = context.fold lexers.lex = context.lex lexers.token = context.token lexers.exact_match = context.exact_match +lexers.just_match = context.just_match -- helper .. alas ... the lexer's lua instance is rather crippled .. not even -- math is part of it diff --git a/context/data/scite/scite-context-data-context.properties b/context/data/scite/scite-context-data-context.properties index fbd958f8a..a526dfbe3 100644 --- a/context/data/scite/scite-context-data-context.properties +++ b/context/data/scite/scite-context-data-context.properties @@ -16,176 +16,178 @@ egroup endline conditionaltrue conditionalfalse attributeunsetvalue \ uprotationangle rightrotationangle downrotationangle leftrotationangle inicatcodes \ ctxcatcodes texcatcodes notcatcodes txtcatcodes vrbcatcodes \ prtcatcodes nilcatcodes luacatcodes tpacatcodes tpbcatcodes \ -xmlcatcodes escapecatcode begingroupcatcode endgroupcatcode mathshiftcatcode \ -alignmentcatcode endoflinecatcode parametercatcode superscriptcatcode subscriptcatcode \ -ignorecatcode spacecatcode lettercatcode othercatcode activecatcode \ -commentcatcode invalidcatcode tabasciicode newlineasciicode formfeedasciicode \ -endoflineasciicode endoffileasciicode spaceasciicode hashasciicode dollarasciicode \ -commentasciicode ampersandasciicode colonasciicode backslashasciicode circumflexasciicode \ -underscoreasciicode leftbraceasciicode barasciicode rightbraceasciicode tildeasciicode \ -delasciicode lessthanasciicode morethanasciicode doublecommentsignal atsignasciicode \ -exclamationmarkasciicode questionmarkasciicode doublequoteasciicode singlequoteasciicode forwardslashasciicode \ -primeasciicode activemathcharcode activetabtoken activeformfeedtoken activeendoflinetoken \ -batchmodecode nonstopmodecode scrollmodecode errorstopmodecode bottomlevelgroupcode \ -simplegroupcode hboxgroupcode adjustedhboxgroupcode vboxgroupcode vtopgroupcode \ -aligngroupcode noaligngroupcode outputgroupcode mathgroupcode discretionarygroupcode \ -insertgroupcode vcentergroupcode mathchoicegroupcode semisimplegroupcode mathshiftgroupcode \ -mathleftgroupcode vadjustgroupcode charnodecode hlistnodecode vlistnodecode \ -rulenodecode insertnodecode marknodecode adjustnodecode ligaturenodecode \ -discretionarynodecode whatsitnodecode mathnodecode gluenodecode kernnodecode \ -penaltynodecode unsetnodecode mathsnodecode charifcode catifcode \ -numifcode dimifcode oddifcode vmodeifcode hmodeifcode \ -mmodeifcode innerifcode voidifcode hboxifcode vboxifcode \ -xifcode eofifcode trueifcode falseifcode caseifcode \ -definedifcode csnameifcode fontcharifcode fontslantperpoint fontinterwordspace \ -fontinterwordstretch fontinterwordshrink fontexheight fontemwidth fontextraspace \ -slantperpoint interwordspace interwordstretch interwordshrink exheight \ -emwidth extraspace mathsupdisplay mathsupnormal mathsupcramped \ -mathsubnormal mathsubcombined mathaxisheight startmode stopmode \ -startnotmode stopnotmode startmodeset stopmodeset doifmode \ -doifmodeelse doifnotmode startallmodes stopallmodes startnotallmodes \ -stopnotallmodes doifallmodes doifallmodeselse doifnotallmodes startenvironment \ -stopenvironment environment startcomponent stopcomponent component \ -startproduct stopproduct product startproject stopproject \ -project starttext stoptext startnotext stopnotext \ -startdocument stopdocument documentvariable setupdocument startmodule \ -stopmodule usemodule usetexmodule useluamodule setupmodule \ -currentmoduleparameter moduleparameter startTEXpage stopTEXpage enablemode \ -disablemode preventmode globalenablemode globaldisablemode globalpreventmode \ -pushmode popmode typescriptone typescripttwo typescriptthree \ -mathsizesuffix mathordcode mathopcode mathbincode mathrelcode \ -mathopencode mathclosecode mathpunctcode mathalphacode mathinnercode \ -mathnothingcode mathlimopcode mathnolopcode mathboxcode mathchoicecode \ -mathaccentcode mathradicalcode constantnumber constantnumberargument constantdimen \ -constantdimenargument constantemptyargument continueifinputfile luastringsep !!bs \ -!!es lefttorightmark righttoleftmark breakablethinspace nobreakspace \ -narrownobreakspace zerowidthnobreakspace ideographicspace ideographichalffillspace twoperemspace \ -threeperemspace fourperemspace fiveperemspace sixperemspace figurespace \ -punctuationspace hairspace zerowidthspace zerowidthnonjoiner zerowidthjoiner \ -zwnj zwj +xmlcatcodes ctdcatcodes escapecatcode begingroupcatcode endgroupcatcode \ +mathshiftcatcode alignmentcatcode endoflinecatcode parametercatcode superscriptcatcode \ +subscriptcatcode ignorecatcode spacecatcode lettercatcode othercatcode \ +activecatcode commentcatcode invalidcatcode tabasciicode newlineasciicode \ +formfeedasciicode endoflineasciicode endoffileasciicode spaceasciicode hashasciicode \ +dollarasciicode commentasciicode ampersandasciicode colonasciicode backslashasciicode \ +circumflexasciicode underscoreasciicode leftbraceasciicode barasciicode rightbraceasciicode \ +tildeasciicode delasciicode lessthanasciicode morethanasciicode doublecommentsignal \ +atsignasciicode exclamationmarkasciicode questionmarkasciicode doublequoteasciicode singlequoteasciicode \ +forwardslashasciicode primeasciicode activemathcharcode activetabtoken activeformfeedtoken \ +activeendoflinetoken batchmodecode nonstopmodecode scrollmodecode errorstopmodecode \ +bottomlevelgroupcode simplegroupcode hboxgroupcode adjustedhboxgroupcode vboxgroupcode \ +vtopgroupcode aligngroupcode noaligngroupcode outputgroupcode mathgroupcode \ +discretionarygroupcode insertgroupcode vcentergroupcode mathchoicegroupcode semisimplegroupcode \ +mathshiftgroupcode mathleftgroupcode vadjustgroupcode charnodecode hlistnodecode \ +vlistnodecode rulenodecode insertnodecode marknodecode adjustnodecode \ +ligaturenodecode discretionarynodecode whatsitnodecode mathnodecode gluenodecode \ +kernnodecode penaltynodecode unsetnodecode mathsnodecode charifcode \ +catifcode numifcode dimifcode oddifcode vmodeifcode \ +hmodeifcode mmodeifcode innerifcode voidifcode hboxifcode \ +vboxifcode xifcode eofifcode trueifcode falseifcode \ +caseifcode definedifcode csnameifcode fontcharifcode fontslantperpoint \ +fontinterwordspace fontinterwordstretch fontinterwordshrink fontexheight fontemwidth \ +fontextraspace slantperpoint interwordspace interwordstretch interwordshrink \ +exheight emwidth extraspace mathsupdisplay mathsupnormal \ +mathsupcramped mathsubnormal mathsubcombined mathaxisheight startmode \ +stopmode startnotmode stopnotmode startmodeset stopmodeset \ +doifmode doifmodeelse doifnotmode startallmodes stopallmodes \ +startnotallmodes stopnotallmodes doifallmodes doifallmodeselse doifnotallmodes \ +startenvironment stopenvironment environment startcomponent stopcomponent \ +component startproduct stopproduct product startproject \ +stopproject project starttext stoptext startnotext \ +stopnotext startdocument stopdocument documentvariable setupdocument \ +startmodule stopmodule usemodule usetexmodule useluamodule \ +setupmodule currentmoduleparameter moduleparameter startTEXpage stopTEXpage \ +enablemode disablemode preventmode globalenablemode globaldisablemode \ +globalpreventmode pushmode popmode typescriptone typescripttwo \ +typescriptthree mathsizesuffix mathordcode mathopcode mathbincode \ +mathrelcode mathopencode mathclosecode mathpunctcode mathalphacode \ +mathinnercode mathnothingcode mathlimopcode mathnolopcode mathboxcode \ +mathchoicecode mathaccentcode mathradicalcode constantnumber constantnumberargument \ +constantdimen constantdimenargument constantemptyargument continueifinputfile luastringsep \ +!!bs !!es lefttorightmark righttoleftmark breakablethinspace \ +nobreakspace narrownobreakspace zerowidthnobreakspace ideographicspace ideographichalffillspace \ +twoperemspace threeperemspace fourperemspace fiveperemspace sixperemspace \ +figurespace punctuationspace hairspace zerowidthspace zerowidthnonjoiner \ +zerowidthjoiner zwnj zwj keywordclass.context.helpers=\ startsetups stopsetups startxmlsetups stopxmlsetups \ startluasetups stopluasetups starttexsetups stoptexsetups startrawsetups \ stoprawsetups startlocalsetups stoplocalsetups starttexdefinition stoptexdefinition \ -starttexcode stoptexcode startcontextcode stopcontextcode doifsetupselse \ -doifsetups doifnotsetups setup setups texsetup \ -xmlsetup luasetup directsetup doifelsecommandhandler doifnotcommandhandler \ -doifcommandhandler newmode setmode resetmode newsystemmode \ -setsystemmode resetsystemmode pushsystemmode popsystemmode booleanmodevalue \ -newcount newdimen newskip newmuskip newbox \ -newtoks newread newwrite newmarks newinsert \ -newattribute newif newlanguage newfamily newfam \ -newhelp then begcsname strippedcsname firstargumentfalse \ -firstargumenttrue secondargumentfalse secondargumenttrue thirdargumentfalse thirdargumenttrue \ -fourthargumentfalse fourthargumenttrue fifthargumentfalse fifthsargumenttrue sixthargumentfalse \ -sixtsargumenttrue doglobal dodoglobal redoglobal resetglobal \ -donothing dontcomplain forgetall donetrue donefalse \ -htdp unvoidbox hfilll vfilll mathbox \ -mathlimop mathnolop mathnothing mathalpha currentcatcodetable \ -defaultcatcodetable catcodetablename newcatcodetable startcatcodetable stopcatcodetable \ -startextendcatcodetable stopextendcatcodetable pushcatcodetable popcatcodetable restorecatcodes \ -setcatcodetable letcatcodecommand defcatcodecommand uedcatcodecommand hglue \ -vglue hfillneg vfillneg hfilllneg vfilllneg \ -ruledhss ruledhfil ruledhfill ruledhfilneg ruledhfillneg \ -normalhfillneg ruledvss ruledvfil ruledvfill ruledvfilneg \ -ruledvfillneg normalvfillneg ruledhbox ruledvbox ruledvtop \ -ruledvcenter ruledmbox ruledhskip ruledvskip ruledkern \ -ruledmskip ruledmkern ruledhglue ruledvglue normalhglue \ -normalvglue ruledpenalty filledhboxb filledhboxr filledhboxg \ -filledhboxc filledhboxm filledhboxy filledhboxk scratchcounter \ -globalscratchcounter scratchdimen globalscratchdimen scratchskip globalscratchskip \ -scratchmuskip globalscratchmuskip scratchtoks globalscratchtoks scratchbox \ -globalscratchbox normalbaselineskip normallineskip normallineskiplimit availablehsize \ -localhsize setlocalhsize nextbox dowithnextbox dowithnextboxcs \ -dowithnextboxcontent dowithnextboxcontentcs scratchwidth scratchheight scratchdepth \ -scratchoffset scratchdistance scratchhsize scratchvsize scratchxoffset \ -scratchyoffset scratchhoffset scratchvoffset scratchxposition scratchyposition \ -scratchtopoffset scratchbottomoffset scratchleftoffset scratchrightoffset scratchcounterone \ -scratchcountertwo scratchcounterthree scratchdimenone scratchdimentwo scratchdimenthree \ -scratchskipone scratchskiptwo scratchskipthree scratchmuskipone scratchmuskiptwo \ -scratchmuskipthree scratchtoksone scratchtokstwo scratchtoksthree scratchboxone \ -scratchboxtwo scratchboxthree scratchnx scratchny scratchmx \ -scratchmy scratchunicode scratchleftskip scratchrightskip scratchtopskip \ -scratchbottomskip doif doifnot doifelse doifinset \ -doifnotinset doifinsetelse doifnextcharelse doifnextoptionalelse doifnextbgroupelse \ -doifnextparenthesiselse doiffastoptionalcheckelse doifundefinedelse doifdefinedelse doifundefined \ -doifdefined doifelsevalue doifvalue doifnotvalue doifnothing \ -doifsomething doifelsenothing doifsomethingelse doifvaluenothing doifvaluesomething \ -doifelsevaluenothing doifdimensionelse doifnumberelse doifnumber doifnotnumber \ -doifcommonelse doifcommon doifnotcommon doifinstring doifnotinstring \ -doifinstringelse doifassignmentelse docheckassignment tracingall tracingnone \ -loggingall removetoks appendtoks prependtoks appendtotoks \ -prependtotoks to endgraf endpar everyendpar \ -reseteverypar finishpar empty null space \ -quad enspace obeyspaces obeylines obeyedspace \ -obeyedline normalspace executeifdefined singleexpandafter doubleexpandafter \ -tripleexpandafter dontleavehmode removelastspace removeunwantedspaces keepunwantedspaces \ -wait writestatus define defineexpandable redefine \ -setmeasure setemeasure setgmeasure setxmeasure definemeasure \ -freezemeasure measure measured installcorenamespace getvalue \ -getuvalue setvalue setevalue setgvalue setxvalue \ -letvalue letgvalue resetvalue undefinevalue ignorevalue \ -setuvalue setuevalue setugvalue setuxvalue globallet \ -glet udef ugdef uedef uxdef \ -checked unique getparameters geteparameters getgparameters \ -getxparameters forgetparameters copyparameters getdummyparameters dummyparameter \ -directdummyparameter setdummyparameter letdummyparameter usedummystyleandcolor usedummystyleparameter \ -usedummycolorparameter processcommalist processcommacommand quitcommalist quitprevcommalist \ -processaction processallactions processfirstactioninset processallactionsinset unexpanded \ -expanded startexpanded stopexpanded protected protect \ -unprotect firstofoneargument firstoftwoarguments secondoftwoarguments firstofthreearguments \ -secondofthreearguments thirdofthreearguments firstoffourarguments secondoffourarguments thirdoffourarguments \ -fourthoffourarguments firstoffivearguments secondoffivearguments thirdoffivearguments fourthoffivearguments \ -fifthoffivearguments firstofsixarguments secondofsixarguments thirdofsixarguments fourthofsixarguments \ -fifthofsixarguments sixthofsixarguments firstofoneunexpanded gobbleoneargument gobbletwoarguments \ -gobblethreearguments gobblefourarguments gobblefivearguments gobblesixarguments gobblesevenarguments \ -gobbleeightarguments gobbleninearguments gobbletenarguments gobbleoneoptional gobbletwooptionals \ -gobblethreeoptionals gobblefouroptionals gobblefiveoptionals dorecurse doloop \ -exitloop dostepwiserecurse recurselevel recursedepth dofastloopcs \ -dowith newconstant setnewconstant setconstant setconstantvalue \ -newconditional settrue setfalse settruevalue setfalsevalue \ -newmacro setnewmacro newfraction newsignal dosingleempty \ -dodoubleempty dotripleempty doquadrupleempty doquintupleempty dosixtupleempty \ -doseventupleempty dosingleargument dodoubleargument dotripleargument doquadrupleargument \ -doquintupleargument dosixtupleargument doseventupleargument dosinglegroupempty dodoublegroupempty \ -dotriplegroupempty doquadruplegroupempty doquintuplegroupempty permitspacesbetweengroups dontpermitspacesbetweengroups \ -nopdfcompression maximumpdfcompression normalpdfcompression modulonumber dividenumber \ -getfirstcharacter doiffirstcharelse startnointerference stopnointerference twodigits \ -threedigits leftorright strut setstrut strutbox \ -strutht strutdp strutwd struthtdp begstrut \ -endstrut lineheight ordordspacing ordopspacing ordbinspacing \ -ordrelspacing ordopenspacing ordclosespacing ordpunctspacing ordinnerspacing \ -opordspacing opopspacing opbinspacing oprelspacing opopenspacing \ -opclosespacing oppunctspacing opinnerspacing binordspacing binopspacing \ -binbinspacing binrelspacing binopenspacing binclosespacing binpunctspacing \ -bininnerspacing relordspacing relopspacing relbinspacing relrelspacing \ -relopenspacing relclosespacing relpunctspacing relinnerspacing openordspacing \ -openopspacing openbinspacing openrelspacing openopenspacing openclosespacing \ -openpunctspacing openinnerspacing closeordspacing closeopspacing closebinspacing \ -closerelspacing closeopenspacing closeclosespacing closepunctspacing closeinnerspacing \ -punctordspacing punctopspacing punctbinspacing punctrelspacing punctopenspacing \ -punctclosespacing punctpunctspacing punctinnerspacing innerordspacing inneropspacing \ -innerbinspacing innerrelspacing inneropenspacing innerclosespacing innerpunctspacing \ -innerinnerspacing normalreqno startimath stopimath normalstartimath \ -normalstopimath startdmath stopdmath normalstartdmath normalstopdmath \ -uncramped cramped triggermathstyle mathstylefont mathsmallstylefont \ -mathstyleface mathsmallstyleface mathstylecommand mathpalette mathstylehbox \ -mathstylevbox mathstylevcenter mathstylevcenteredhbox mathstylevcenteredvbox mathtext \ -setmathsmalltextbox setmathtextbox triggerdisplaystyle triggertextstyle triggerscriptstyle \ -triggerscriptscriptstyle triggeruncrampedstyle triggercrampedstyle triggersmallstyle triggeruncrampedsmallstyle \ -triggercrampedsmallstyle triggerbigstyle triggeruncrampedbigstyle triggercrampedbigstyle luaexpr \ -expdoifelse expdoif expdoifnot expdoifcommonelse expdoifinsetelse \ -ctxdirectlua ctxlatelua ctxsprint ctxwrite ctxcommand \ -ctxdirectcommand ctxlatecommand ctxreport ctxlua luacode \ -lateluacode directluacode registerctxluafile ctxloadluafile luaversion \ -luamajorversion luaminorversion ctxluacode luaconditional luaexpanded \ -startluaparameterset stopluaparameterset luaparameterset definenamedlua obeylualines \ -obeyluatokens startluacode stopluacode startlua stoplua \ -carryoverpar assumelongusagecs Umathbotaccent righttolefthbox lefttorighthbox \ -righttoleftvbox lefttorightvbox righttoleftvtop lefttorightvtop rtlhbox \ -ltrhbox rtlvbox ltrvbox rtlvtop ltrvtop \ -autodirhbox autodirvbox autodirvtop lefttoright righttoleft \ -synchronizelayoutdirection synchronizedisplaydirection synchronizeinlinedirection lesshyphens morehyphens \ -nohyphens dohyphens Ucheckedstartdisplaymath Ucheckedstopdisplaymath +starttexcode stoptexcode startcontextcode stopcontextcode startcontextdefinitioncode \ +stopcontextdefinitioncode doifsetupselse doifsetups doifnotsetups setup \ +setups texsetup xmlsetup luasetup directsetup \ +doifelsecommandhandler doifnotcommandhandler doifcommandhandler newmode setmode \ +resetmode newsystemmode setsystemmode resetsystemmode pushsystemmode \ +popsystemmode booleanmodevalue newcount newdimen newskip \ +newmuskip newbox newtoks newread newwrite \ +newmarks newinsert newattribute newif newlanguage \ +newfamily newfam newhelp then begcsname \ +strippedcsname firstargumentfalse firstargumenttrue secondargumentfalse secondargumenttrue \ +thirdargumentfalse thirdargumenttrue fourthargumentfalse fourthargumenttrue fifthargumentfalse \ +fifthsargumenttrue sixthargumentfalse sixtsargumenttrue doglobal dodoglobal \ +redoglobal resetglobal donothing dontcomplain forgetall \ +donetrue donefalse htdp unvoidbox hfilll \ +vfilll mathbox mathlimop mathnolop mathnothing \ +mathalpha currentcatcodetable defaultcatcodetable catcodetablename newcatcodetable \ +startcatcodetable stopcatcodetable startextendcatcodetable stopextendcatcodetable pushcatcodetable \ +popcatcodetable restorecatcodes setcatcodetable letcatcodecommand defcatcodecommand \ +uedcatcodecommand hglue vglue hfillneg vfillneg \ +hfilllneg vfilllneg ruledhss ruledhfil ruledhfill \ +ruledhfilneg ruledhfillneg normalhfillneg ruledvss ruledvfil \ +ruledvfill ruledvfilneg ruledvfillneg normalvfillneg ruledhbox \ +ruledvbox ruledvtop ruledvcenter ruledmbox ruledhskip \ +ruledvskip ruledkern ruledmskip ruledmkern ruledhglue \ +ruledvglue normalhglue normalvglue ruledpenalty filledhboxb \ +filledhboxr filledhboxg filledhboxc filledhboxm filledhboxy \ +filledhboxk scratchcounter globalscratchcounter scratchdimen globalscratchdimen \ +scratchskip globalscratchskip scratchmuskip globalscratchmuskip scratchtoks \ +globalscratchtoks scratchbox globalscratchbox normalbaselineskip normallineskip \ +normallineskiplimit availablehsize localhsize setlocalhsize nextbox \ +dowithnextbox dowithnextboxcs dowithnextboxcontent dowithnextboxcontentcs scratchwidth \ +scratchheight scratchdepth scratchoffset scratchdistance scratchhsize \ +scratchvsize scratchxoffset scratchyoffset scratchhoffset scratchvoffset \ +scratchxposition scratchyposition scratchtopoffset scratchbottomoffset scratchleftoffset \ +scratchrightoffset scratchcounterone scratchcountertwo scratchcounterthree scratchdimenone \ +scratchdimentwo scratchdimenthree scratchskipone scratchskiptwo scratchskipthree \ +scratchmuskipone scratchmuskiptwo scratchmuskipthree scratchtoksone scratchtokstwo \ +scratchtoksthree scratchboxone scratchboxtwo scratchboxthree scratchnx \ +scratchny scratchmx scratchmy scratchunicode scratchleftskip \ +scratchrightskip scratchtopskip scratchbottomskip doif doifnot \ +doifelse doifinset doifnotinset doifinsetelse doifnextcharelse \ +doifnextoptionalelse doifnextoptionalcselse doiffastoptionalcheckelse doifnextbgroupelse doifnextbgroupcselse \ +doifnextparenthesiselse doifundefinedelse doifdefinedelse doifundefined doifdefined \ +doifelsevalue doifvalue doifnotvalue doifnothing doifsomething \ +doifelsenothing doifsomethingelse doifvaluenothing doifvaluesomething doifelsevaluenothing \ +doifdimensionelse doifnumberelse doifnumber doifnotnumber doifcommonelse \ +doifcommon doifnotcommon doifinstring doifnotinstring doifinstringelse \ +doifassignmentelse docheckassignment tracingall tracingnone loggingall \ +removetoks appendtoks prependtoks appendtotoks prependtotoks \ +to endgraf endpar everyendpar reseteverypar \ +finishpar empty null space quad \ +enspace obeyspaces obeylines obeyedspace obeyedline \ +normalspace executeifdefined singleexpandafter doubleexpandafter tripleexpandafter \ +dontleavehmode removelastspace removeunwantedspaces keepunwantedspaces wait \ +writestatus define defineexpandable redefine setmeasure \ +setemeasure setgmeasure setxmeasure definemeasure freezemeasure \ +measure measured installcorenamespace getvalue getuvalue \ +setvalue setevalue setgvalue setxvalue letvalue \ +letgvalue resetvalue undefinevalue ignorevalue setuvalue \ +setuevalue setugvalue setuxvalue globallet glet \ +udef ugdef uedef uxdef checked \ +unique getparameters geteparameters getgparameters getxparameters \ +forgetparameters copyparameters getdummyparameters dummyparameter directdummyparameter \ +setdummyparameter letdummyparameter usedummystyleandcolor usedummystyleparameter usedummycolorparameter \ +processcommalist processcommacommand quitcommalist quitprevcommalist processaction \ +processallactions processfirstactioninset processallactionsinset unexpanded expanded \ +startexpanded stopexpanded protected protect unprotect \ +firstofoneargument firstoftwoarguments secondoftwoarguments firstofthreearguments secondofthreearguments \ +thirdofthreearguments firstoffourarguments secondoffourarguments thirdoffourarguments fourthoffourarguments \ +firstoffivearguments secondoffivearguments thirdoffivearguments fourthoffivearguments fifthoffivearguments \ +firstofsixarguments secondofsixarguments thirdofsixarguments fourthofsixarguments fifthofsixarguments \ +sixthofsixarguments firstofoneunexpanded gobbleoneargument gobbletwoarguments gobblethreearguments \ +gobblefourarguments gobblefivearguments gobblesixarguments gobblesevenarguments gobbleeightarguments \ +gobbleninearguments gobbletenarguments gobbleoneoptional gobbletwooptionals gobblethreeoptionals \ +gobblefouroptionals gobblefiveoptionals dorecurse doloop exitloop \ +dostepwiserecurse recurselevel recursedepth dofastloopcs dowith \ +newconstant setnewconstant setconstant setconstantvalue newconditional \ +settrue setfalse settruevalue setfalsevalue newmacro \ +setnewmacro newfraction newsignal dosingleempty dodoubleempty \ +dotripleempty doquadrupleempty doquintupleempty dosixtupleempty doseventupleempty \ +dosingleargument dodoubleargument dotripleargument doquadrupleargument doquintupleargument \ +dosixtupleargument doseventupleargument dosinglegroupempty dodoublegroupempty dotriplegroupempty \ +doquadruplegroupempty doquintuplegroupempty permitspacesbetweengroups dontpermitspacesbetweengroups nopdfcompression \ +maximumpdfcompression normalpdfcompression modulonumber dividenumber getfirstcharacter \ +doiffirstcharelse startnointerference stopnointerference twodigits threedigits \ +leftorright strut setstrut strutbox strutht \ +strutdp strutwd struthtdp begstrut endstrut \ +lineheight ordordspacing ordopspacing ordbinspacing ordrelspacing \ +ordopenspacing ordclosespacing ordpunctspacing ordinnerspacing opordspacing \ +opopspacing opbinspacing oprelspacing opopenspacing opclosespacing \ +oppunctspacing opinnerspacing binordspacing binopspacing binbinspacing \ +binrelspacing binopenspacing binclosespacing binpunctspacing bininnerspacing \ +relordspacing relopspacing relbinspacing relrelspacing relopenspacing \ +relclosespacing relpunctspacing relinnerspacing openordspacing openopspacing \ +openbinspacing openrelspacing openopenspacing openclosespacing openpunctspacing \ +openinnerspacing closeordspacing closeopspacing closebinspacing closerelspacing \ +closeopenspacing closeclosespacing closepunctspacing closeinnerspacing punctordspacing \ +punctopspacing punctbinspacing punctrelspacing punctopenspacing punctclosespacing \ +punctpunctspacing punctinnerspacing innerordspacing inneropspacing innerbinspacing \ +innerrelspacing inneropenspacing innerclosespacing innerpunctspacing innerinnerspacing \ +normalreqno startimath stopimath normalstartimath normalstopimath \ +startdmath stopdmath normalstartdmath normalstopdmath uncramped \ +cramped triggermathstyle mathstylefont mathsmallstylefont mathstyleface \ +mathsmallstyleface mathstylecommand mathpalette mathstylehbox mathstylevbox \ +mathstylevcenter mathstylevcenteredhbox mathstylevcenteredvbox mathtext setmathsmalltextbox \ +setmathtextbox triggerdisplaystyle triggertextstyle triggerscriptstyle triggerscriptscriptstyle \ +triggeruncrampedstyle triggercrampedstyle triggersmallstyle triggeruncrampedsmallstyle triggercrampedsmallstyle \ +triggerbigstyle triggeruncrampedbigstyle triggercrampedbigstyle luaexpr expdoifelse \ +expdoif expdoifnot expdoifcommonelse expdoifinsetelse ctxdirectlua \ +ctxlatelua ctxsprint ctxwrite ctxcommand ctxdirectcommand \ +ctxlatecommand ctxreport ctxlua luacode lateluacode \ +directluacode registerctxluafile ctxloadluafile luaversion luamajorversion \ +luaminorversion ctxluacode luaconditional luaexpanded startluaparameterset \ +stopluaparameterset luaparameterset definenamedlua obeylualines obeyluatokens \ +startluacode stopluacode startlua stoplua startctxfunction \ +stopctxfunction ctxfunction startctxfunctiondefinition stopctxfunctiondefinition carryoverpar \ +assumelongusagecs Umathbotaccent righttolefthbox lefttorighthbox righttoleftvbox \ +lefttorightvbox righttoleftvtop lefttorightvtop rtlhbox ltrhbox \ +rtlvbox ltrvbox rtlvtop ltrvtop autodirhbox \ +autodirvbox autodirvtop lefttoright righttoleft synchronizelayoutdirection \ +synchronizedisplaydirection synchronizeinlinedirection lesshyphens morehyphens nohyphens \ +dohyphens Ucheckedstartdisplaymath Ucheckedstopdisplaymath diff --git a/context/data/scite/scite-context-data-tex.properties b/context/data/scite/scite-context-data-tex.properties index 195125433..d1780794d 100644 --- a/context/data/scite/scite-context-data-tex.properties +++ b/context/data/scite/scite-context-data-tex.properties @@ -50,10 +50,10 @@ attribute attributedef catcodetable clearmarks crampeddisplaystyle \ crampedscriptscriptstyle crampedscriptstyle crampedtextstyle fontid formatname \ gleaders ifabsdim ifabsnum ifprimitive initcatcodetable \ latelua luaescapestring luastartup luatexdatestamp luatexrevision \ -luatexversion mathstyle nokerns noligs outputbox \ -pageleftoffset pagetopoffset postexhyphenchar posthyphenchar preexhyphenchar \ -prehyphenchar primitive savecatcodetable scantextokens suppressfontnotfounderror \ -suppressifcsnameerror suppresslongerror suppressoutererror synctex +luatexversion luafunction mathstyle nokerns noligs \ +outputbox pageleftoffset pagetopoffset postexhyphenchar posthyphenchar \ +preexhyphenchar prehyphenchar primitive savecatcodetable scantextokens \ +suppressfontnotfounderror suppressifcsnameerror suppresslongerror suppressoutererror synctex keywordclass.tex.omega=\ OmegaVersion bodydir chardp charht \ @@ -124,114 +124,113 @@ attribute attributedef badness baselineskip batchmode \ begingroup belowdisplayshortskip belowdisplayskip binoppenalty bodydir \ botmark botmarks box boxdir boxmaxdepth \ brokenpenalty catcode catcodetable char chardef \ -chardp charht charit charwd cleaders \ -clearmarks closein closeout clubpenalties clubpenalty \ -copy count countdef cr crampeddisplaystyle \ -crampedscriptscriptstyle crampedscriptstyle crampedtextstyle crcr csname \ -currentgrouplevel currentgrouptype currentifbranch currentiflevel currentiftype \ -day deadcycles def defaulthyphenchar defaultskewchar \ -delcode delimiter delimiterfactor delimitershortfall detokenize \ -dimen dimendef dimexpr directlua discretionary \ -displayindent displaylimits displaystyle displaywidowpenalties displaywidowpenalty \ -displaywidth divide doublehyphendemerits dp dump \ -eTeXVersion eTeXminorversion eTeXrevision eTeXversion edef \ -efcode else emergencystretch end endcsname \ -endgroup endinput endlinechar eqno errhelp \ -errmessage errorcontextlines errorstopmode escapechar everycr \ -everydisplay everyeof everyhbox everyjob everymath \ -everypar everyvbox exhyphenchar exhyphenpenalty expandafter \ -expanded fam fi finalhyphendemerits firstmark \ -firstmarks floatingpenalty font fontchardp fontcharht \ -fontcharic fontcharwd fontdimen fontid fontname \ -formatname futurelet gdef gleaders global \ -globaldefs glueexpr glueshrink glueshrinkorder gluestretch \ -gluestretchorder gluetomu halign hangafter hangindent \ -hbadness hbox hfil hfill hfilneg \ -hfuzz hoffset holdinginserts hrule hsize \ -hskip hss ht hyphenation hyphenchar \ -hyphenpenalty if ifabsdim ifabsnum ifcase \ -ifcat ifcsname ifdefined ifdim ifeof \ -iffalse iffontchar ifhbox ifhmode ifincsname \ -ifinner ifmmode ifnum ifodd ifpdfabsdim \ -ifpdfabsnum ifpdfprimitive ifprimitive iftrue ifvbox \ -ifvmode ifvoid ifx ignorespaces immediate \ -indent initcatcodetable input inputlineno insert \ -insertpenalties interactionmode interlinepenalties interlinepenalty jobname \ -kern language lastbox lastkern lastlinefit \ -lastnodetype lastpenalty lastskip latelua lccode \ -leaders left leftghost lefthyphenmin leftmarginkern \ -leftskip leqno let letterspacefont limits \ -linepenalty lineskip lineskiplimit localbrokenpenalty localinterlinepenalty \ -localleftbox localrightbox long looseness lower \ -lowercase lpcode luaescapestring luastartup luatexdatestamp \ -luatexrevision luatexversion mag mark marks \ -mathaccent mathbin mathchar mathchardef mathchoice \ -mathclose mathcode mathdir mathinner mathop \ -mathopen mathord mathpunct mathrel mathstyle \ -mathsurround maxdeadcycles maxdepth meaning medmuskip \ -message middle mkern month moveleft \ -moveright mskip muexpr multiply muskip \ -muskipdef mutoglue newlinechar noalign noboundary \ -noexpand noindent nokerns noligs nolimits \ -nolocaldirs nolocalwhatsits nonscript nonstopmode nulldelimiterspace \ -nullfont number numexpr odelcode odelimiter \ -omathaccent omathchar omathchardef omathcode omit \ -openin openout or oradical outer \ -output outputbox outputpenalty over overfullrule \ -overline overwithdelims pagebottomoffset pagedepth pagedir \ -pagediscards pagefilllstretch pagefillstretch pagefilstretch pagegoal \ -pageheight pageleftoffset pagerightoffset pageshrink pagestretch \ -pagetopoffset pagetotal pagewidth par pardir \ -parfillskip parindent parshape parshapedimen parshapeindent \ -parshapelength parskip patterns pausing pdfadjustspacing \ -pdfannot pdfcatalog pdfcolorstack pdfcolorstackinit pdfcompresslevel \ -pdfcopyfont pdfcreationdate pdfdecimaldigits pdfdest pdfdestmargin \ -pdfdraftmode pdfeachlinedepth pdfeachlineheight pdfendlink pdfendthread \ -pdffirstlineheight pdffontattr pdffontexpand pdffontname pdffontobjnum \ -pdffontsize pdfgamma pdfgentounicode pdfglyphtounicode pdfhorigin \ -pdfignoreddimen pdfimageapplygamma pdfimagegamma pdfimagehicolor pdfimageresolution \ -pdfincludechars pdfinclusioncopyfonts pdfinclusionerrorlevel pdfinfo pdfinsertht \ -pdflastannot pdflastlinedepth pdflastlink pdflastobj pdflastxform \ -pdflastximage pdflastximagecolordepth pdflastximagepages pdflastxpos pdflastypos \ -pdflinkmargin pdfliteral pdfmapfile pdfmapline pdfminorversion \ -pdfnames pdfnoligatures pdfnormaldeviate pdfobj pdfobjcompresslevel \ -pdfoptionpdfminorversion pdfoutline pdfoutput pdfpageattr pdfpagebox \ -pdfpageheight pdfpageref pdfpageresources pdfpagesattr pdfpagewidth \ -pdfpkmode pdfpkresolution pdfprimitive pdfprotrudechars pdfpxdimen \ -pdfrandomseed pdfrefobj pdfrefxform pdfrefximage pdfreplacefont \ -pdfrestore pdfretval pdfsave pdfsavepos pdfsetmatrix \ -pdfsetrandomseed pdfstartlink pdfstartthread pdftexbanner pdftexrevision \ -pdftexversion pdfthread pdfthreadmargin pdftracingfonts pdftrailer \ -pdfuniformdeviate pdfuniqueresname pdfvorigin pdfxform pdfxformattr \ -pdfxformname pdfxformresources pdfximage pdfximagebbox penalty \ -postdisplaypenalty postexhyphenchar posthyphenchar predisplaydirection predisplaypenalty \ -predisplaysize preexhyphenchar prehyphenchar pretolerance prevdepth \ -prevgraf primitive protected quitvmode radical \ -raise read readline relax relpenalty \ -right rightghost righthyphenmin rightmarginkern rightskip \ -romannumeral rpcode savecatcodetable savinghyphcodes savingvdiscards \ -scantextokens scantokens scriptfont scriptscriptfont scriptscriptstyle \ -scriptspace scriptstyle scrollmode setbox setlanguage \ -sfcode shipout show showbox showboxbreadth \ -showboxdepth showgroups showifs showlists showthe \ -showtokens skewchar skip skipdef spacefactor \ -spaceskip span special splitbotmark splitbotmarks \ -splitdiscards splitfirstmark splitfirstmarks splitmaxdepth splittopskip \ -string suppressfontnotfounderror suppressifcsnameerror suppresslongerror suppressoutererror \ -synctex tabskip tagcode textdir textfont \ -textstyle the thickmuskip thinmuskip time \ -toks toksdef tolerance topmark topmarks \ -topskip tracingassigns tracingcommands tracinggroups tracingifs \ -tracinglostchars tracingmacros tracingnesting tracingonline tracingoutput \ -tracingpages tracingparagraphs tracingrestores tracingscantokens tracingstats \ -uccode uchyph underline unexpanded unhbox \ -unhcopy unkern unless unpenalty unskip \ -unvbox unvcopy uppercase vadjust valign \ -vbadness vbox vcenter vfil vfill \ -vfilneg vfuzz voffset vrule vsize \ -vskip vsplit vss vtop wd \ -widowpenalties widowpenalty write xdef xleaders \ -xspaceskip year +cleaders clearmarks closein closeout clubpenalties \ +clubpenalty copy count countdef cr \ +crampeddisplaystyle crampedscriptscriptstyle crampedscriptstyle crampedtextstyle crcr \ +csname currentgrouplevel currentgrouptype currentifbranch currentiflevel \ +currentiftype day deadcycles def defaulthyphenchar \ +defaultskewchar delcode delimiter delimiterfactor delimitershortfall \ +detokenize dimen dimendef dimexpr directlua \ +discretionary displayindent displaylimits displaystyle displaywidowpenalties \ +displaywidowpenalty displaywidth divide doublehyphendemerits dp \ +dump eTeXVersion eTeXminorversion eTeXrevision eTeXversion \ +edef efcode else emergencystretch end \ +endcsname endgroup endinput endlinechar eqno \ +errhelp errmessage errorcontextlines errorstopmode escapechar \ +everycr everydisplay everyeof everyhbox everyjob \ +everymath everypar everyvbox exhyphenchar exhyphenpenalty \ +expandafter expanded fam fi finalhyphendemerits \ +firstmark firstmarks floatingpenalty font fontchardp \ +fontcharht fontcharic fontcharwd fontdimen fontid \ +fontname formatname futurelet gdef gleaders \ +global globaldefs glueexpr glueshrink glueshrinkorder \ +gluestretch gluestretchorder gluetomu halign hangafter \ +hangindent hbadness hbox hfil hfill \ +hfilneg hfuzz hoffset holdinginserts hrule \ +hsize hskip hss ht hyphenation \ +hyphenchar hyphenpenalty if ifabsdim ifabsnum \ +ifcase ifcat ifcsname ifdefined ifdim \ +ifeof iffalse iffontchar ifhbox ifhmode \ +ifincsname ifinner ifmmode ifnum ifodd \ +ifpdfabsdim ifpdfabsnum ifpdfprimitive ifprimitive iftrue \ +ifvbox ifvmode ifvoid ifx ignorespaces \ +immediate indent initcatcodetable input inputlineno \ +insert insertpenalties interactionmode interlinepenalties interlinepenalty \ +jobname kern language lastbox lastkern \ +lastlinefit lastnodetype lastpenalty lastskip latelua \ +lccode leaders left leftghost lefthyphenmin \ +leftmarginkern leftskip leqno let letterspacefont \ +limits linepenalty lineskip lineskiplimit localbrokenpenalty \ +localinterlinepenalty localleftbox localrightbox long looseness \ +lower lowercase lpcode luaescapestring luastartup \ +luatexdatestamp luatexrevision luatexversion mag mark \ +marks mathaccent mathbin mathchar mathchardef \ +mathchoice mathclose mathcode mathdir mathinner \ +mathop mathopen mathord mathpunct mathrel \ +mathstyle mathsurround maxdeadcycles maxdepth meaning \ +medmuskip message middle mkern month \ +moveleft moveright mskip muexpr multiply \ +muskip muskipdef mutoglue newlinechar noalign \ +noboundary noexpand noindent nokerns noligs \ +nolimits nolocaldirs nolocalwhatsits nonscript nonstopmode \ +nulldelimiterspace nullfont number numexpr odelcode \ +odelimiter omathaccent omathchar omathchardef omathcode \ +omit openin openout or oradical \ +outer output outputbox outputpenalty over \ +overfullrule overline overwithdelims pagebottomoffset pagedepth \ +pagedir pagediscards pagefilllstretch pagefillstretch pagefilstretch \ +pagegoal pageheight pageleftoffset pagerightoffset pageshrink \ +pagestretch pagetopoffset pagetotal pagewidth par \ +pardir parfillskip parindent parshape parshapedimen \ +parshapeindent parshapelength parskip patterns pausing \ +pdfadjustspacing pdfannot pdfcatalog pdfcolorstack pdfcolorstackinit \ +pdfcompresslevel pdfcopyfont pdfcreationdate pdfdecimaldigits pdfdest \ +pdfdestmargin pdfdraftmode pdfeachlinedepth pdfeachlineheight pdfendlink \ +pdfendthread pdffirstlineheight pdffontattr pdffontexpand pdffontname \ +pdffontobjnum pdffontsize pdfgamma pdfgentounicode pdfglyphtounicode \ +pdfhorigin pdfignoreddimen pdfimageapplygamma pdfimagegamma pdfimagehicolor \ +pdfimageresolution pdfincludechars pdfinclusioncopyfonts pdfinclusionerrorlevel pdfinfo \ +pdfinsertht pdflastannot pdflastlinedepth pdflastlink pdflastobj \ +pdflastxform pdflastximage pdflastximagecolordepth pdflastximagepages pdflastxpos \ +pdflastypos pdflinkmargin pdfliteral pdfmapfile pdfmapline \ +pdfminorversion pdfnames pdfnoligatures pdfnormaldeviate pdfobj \ +pdfobjcompresslevel pdfoptionpdfminorversion pdfoutline pdfoutput pdfpageattr \ +pdfpagebox pdfpageheight pdfpageref pdfpageresources pdfpagesattr \ +pdfpagewidth pdfpkmode pdfpkresolution pdfprimitive pdfprotrudechars \ +pdfpxdimen pdfrandomseed pdfrefobj pdfrefxform pdfrefximage \ +pdfreplacefont pdfrestore pdfretval pdfsave pdfsavepos \ +pdfsetmatrix pdfsetrandomseed pdfstartlink pdfstartthread pdftexbanner \ +pdftexrevision pdftexversion pdfthread pdfthreadmargin pdftracingfonts \ +pdftrailer pdfuniformdeviate pdfuniqueresname pdfvorigin pdfxform \ +pdfxformattr pdfxformname pdfxformresources pdfximage pdfximagebbox \ +penalty postdisplaypenalty postexhyphenchar posthyphenchar predisplaydirection \ +predisplaypenalty predisplaysize preexhyphenchar prehyphenchar pretolerance \ +prevdepth prevgraf primitive protected quitvmode \ +radical raise read readline relax \ +relpenalty right rightghost righthyphenmin rightmarginkern \ +rightskip romannumeral rpcode savecatcodetable savinghyphcodes \ +savingvdiscards scantextokens scantokens scriptfont scriptscriptfont \ +scriptscriptstyle scriptspace scriptstyle scrollmode setbox \ +setlanguage sfcode shipout show showbox \ +showboxbreadth showboxdepth showgroups showifs showlists \ +showthe showtokens skewchar skip skipdef \ +spacefactor spaceskip span special splitbotmark \ +splitbotmarks splitdiscards splitfirstmark splitfirstmarks splitmaxdepth \ +splittopskip string suppressfontnotfounderror suppressifcsnameerror suppresslongerror \ +suppressoutererror synctex tabskip tagcode textdir \ +textfont textstyle the thickmuskip thinmuskip \ +time toks toksdef tolerance topmark \ +topmarks topskip tracingassigns tracingcommands tracinggroups \ +tracingifs tracinglostchars tracingmacros tracingnesting tracingonline \ +tracingoutput tracingpages tracingparagraphs tracingrestores tracingscantokens \ +tracingstats uccode uchyph underline unexpanded \ +unhbox unhcopy unkern unless unpenalty \ +unskip unvbox unvcopy uppercase vadjust \ +valign vbadness vbox vcenter vfil \ +vfill vfilneg vfuzz voffset vrule \ +vsize vskip vsplit vss vtop \ +wd widowpenalties widowpenalty write xdef \ +xleaders xspaceskip year keywordclass.tex.xetex=\ XeTeXversion diff --git a/doc/context/manuals/allkind/mkiv-publications.tex b/doc/context/manuals/allkind/mkiv-publications.tex index 3300a0f53..0a81467fc 100644 --- a/doc/context/manuals/allkind/mkiv-publications.tex +++ b/doc/context/manuals/allkind/mkiv-publications.tex @@ -17,6 +17,8 @@ % \showframe +% \usemodule[lua-checkheads] + \usemodule[abr-02] \usemodule[set-11] diff --git a/doc/context/scripts/mkiv/context.html b/doc/context/scripts/mkiv/context.html index d285af311..0833089aa 100644 --- a/doc/context/scripts/mkiv/context.html +++ b/doc/context/scripts/mkiv/context.html @@ -75,6 +75,9 @@ --jitonuse luajittex with jit turned on (in most cases not faster, even slower) --onceonly run once (no multipass data file is produced) + --runsprocess at most this many times + --forcedrunsprocess this many times (permits for optimization trial runs) + --batchmoderun without stopping and do not show messages on the console --nonstopmoderun without stopping --synctexrun with synctex enabled (optional value: zipped, unzipped, 1, -1) diff --git a/doc/context/scripts/mkiv/context.man b/doc/context/scripts/mkiv/context.man index ea12beb06..c1808f073 100644 --- a/doc/context/scripts/mkiv/context.man +++ b/doc/context/scripts/mkiv/context.man @@ -95,6 +95,12 @@ use luajittex with jit turned on (in most cases not faster, even slower) .B --once only run once (no multipass data file is produced) .TP +.B --runs +process at most this many times +.TP +.B --forcedruns +process this many times (permits for optimization trial runs) +.TP .B --batchmode run without stopping and do not show messages on the console .TP diff --git a/doc/context/scripts/mkiv/context.xml b/doc/context/scripts/mkiv/context.xml index a3812288f..af8d5cc20 100644 --- a/doc/context/scripts/mkiv/context.xml +++ b/doc/context/scripts/mkiv/context.xml @@ -108,6 +108,14 @@ only run once (no multipass data file is produced) + + process at most this many times + + + process this many times (permits for optimization trial runs) + + + run without stopping and do not show messages on the console @@ -117,7 +125,7 @@ run with synctex enabled (optional value: zipped, unzipped, 1, -1) - + generate file database etc. (as luatools does) diff --git a/doc/context/scripts/mkiv/mtx-context.html b/doc/context/scripts/mkiv/mtx-context.html index d285af311..0833089aa 100644 --- a/doc/context/scripts/mkiv/mtx-context.html +++ b/doc/context/scripts/mkiv/mtx-context.html @@ -75,6 +75,9 @@ --jitonuse luajittex with jit turned on (in most cases not faster, even slower) --onceonly run once (no multipass data file is produced) + --runsprocess at most this many times + --forcedrunsprocess this many times (permits for optimization trial runs) + --batchmoderun without stopping and do not show messages on the console --nonstopmoderun without stopping --synctexrun with synctex enabled (optional value: zipped, unzipped, 1, -1) diff --git a/doc/context/scripts/mkiv/mtx-context.man b/doc/context/scripts/mkiv/mtx-context.man index ea12beb06..c1808f073 100644 --- a/doc/context/scripts/mkiv/mtx-context.man +++ b/doc/context/scripts/mkiv/mtx-context.man @@ -95,6 +95,12 @@ use luajittex with jit turned on (in most cases not faster, even slower) .B --once only run once (no multipass data file is produced) .TP +.B --runs +process at most this many times +.TP +.B --forcedruns +process this many times (permits for optimization trial runs) +.TP .B --batchmode run without stopping and do not show messages on the console .TP diff --git a/doc/context/scripts/mkiv/mtx-context.xml b/doc/context/scripts/mkiv/mtx-context.xml index a3812288f..af8d5cc20 100644 --- a/doc/context/scripts/mkiv/mtx-context.xml +++ b/doc/context/scripts/mkiv/mtx-context.xml @@ -108,6 +108,14 @@ only run once (no multipass data file is produced) + + process at most this many times + + + process this many times (permits for optimization trial runs) + + + run without stopping and do not show messages on the console @@ -117,7 +125,7 @@ run with synctex enabled (optional value: zipped, unzipped, 1, -1) - + generate file database etc. (as luatools does) diff --git a/metapost/context/fonts/bidi-symbols.tex b/metapost/context/fonts/bidi-symbols.tex index 800e0e4ea..24f883b3d 100644 --- a/metapost/context/fonts/bidi-symbols.tex +++ b/metapost/context/fonts/bidi-symbols.tex @@ -1,4 +1,4 @@ -% \nopdfcompression +\nopdfcompression % At the ConTeXt 2013 meeting Taco suggested to add ActualText entries to the % shapes. It took us a bit of experimenting and the current implementation of diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index 90efb5225..b53110bb1 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -546,6 +546,7 @@ function scripts.context.run(ctxdata,filename) local a_arrange = getargument("arrange") local a_noarrange = getargument("noarrange") local a_jiton = getargument("jiton") + local a_jithash = getargument("jithash") local a_texformat = getargument("texformat") -- a_batchmode = (a_batchmode and "batchmode") or (a_nonstopmode and "nonstopmode") or nil @@ -582,7 +583,8 @@ function scripts.context.run(ctxdata,filename) formatfile, scriptfile = resolvers.locateformat(formatname) end -- - a_jiton = (a_jiton or toboolean(analysis.jiton,true)) and true or nil + a_jiton = (a_jiton or toboolean(analysis.jiton,true)) and true or nil + a_jithash = validstring(a_jithash or analysis.jithash) or nil -- if not formatfile or not scriptfile then report("warning: no format found, forcing remake (source driven)") @@ -665,6 +667,7 @@ function scripts.context.run(ctxdata,filename) ["lua"] = scriptfile, ["jobname"] = jobname, ["jiton"] = a_jiton, + ["jithash"] = a_jithash, } -- if a_synctex then diff --git a/scripts/context/lua/mtx-context.xml b/scripts/context/lua/mtx-context.xml index a3812288f..af8d5cc20 100644 --- a/scripts/context/lua/mtx-context.xml +++ b/scripts/context/lua/mtx-context.xml @@ -108,6 +108,14 @@ only run once (no multipass data file is produced) + + process at most this many times + + + process this many times (permits for optimization trial runs) + + + run without stopping and do not show messages on the console @@ -117,7 +125,7 @@ run with synctex enabled (optional value: zipped, unzipped, 1, -1) - + generate file database etc. (as luatools does) diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 3372831b3..a4c80acb8 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -1187,7 +1187,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-table"] = package.loaded["l-table"] or true --- original size: 31142, stripped down to: 20283 +-- original size: 31860, stripped down to: 20846 if not modules then modules={} end modules ['l-table']={ version=1.001, @@ -1265,6 +1265,36 @@ local function sortedkeys(tab) return {} end end +local function sortedhashonly(tab) + if tab then + local srt,s={},0 + for key,_ in next,tab do + if type(key)=="string" then + s=s+1 + srt[s]=key + end + end + sort(srt) + return srt + else + return {} + end +end +local function sortedindexonly(tab) + if tab then + local srt,s={},0 + for key,_ in next,tab do + if type(key)=="number" then + s=s+1 + srt[s]=key + end + end + sort(srt) + return srt + else + return {} + end +end local function sortedhashkeys(tab,cmp) if tab then local srt,s={},0 @@ -1290,6 +1320,8 @@ function table.allkeys(t) return sortedkeys(keys) end table.sortedkeys=sortedkeys +table.sortedhashonly=sortedhashonly +table.sortedindexonly=sortedindexonly table.sortedhashkeys=sortedhashkeys local function nothing() end local function sortedhash(t,cmp) @@ -2078,7 +2110,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-io"] = package.loaded["l-io"] or true --- original size: 8817, stripped down to: 6340 +-- original size: 8824, stripped down to: 6347 if not modules then modules={} end modules ['l-io']={ version=1.001, @@ -2092,7 +2124,7 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format local concat=table.concat local floor=math.floor local type=type -if string.find(os.getenv("PATH"),";") then +if string.find(os.getenv("PATH"),";",1,true) then io.fileseparator,io.pathseparator="\\",";" else io.fileseparator,io.pathseparator="/",":" @@ -2613,7 +2645,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-os"] = package.loaded["l-os"] or true --- original size: 16023, stripped down to: 9634 +-- original size: 16093, stripped down to: 9704 if not modules then modules={} end modules ['l-os']={ version=1.001, @@ -2703,7 +2735,7 @@ function os.resultof(command) end end if not io.fileseparator then - if find(os.getenv("PATH"),";") then + if find(os.getenv("PATH"),";",1,true) then io.fileseparator,io.pathseparator,os.type="\\",";",os.type or "mswin" else io.fileseparator,io.pathseparator,os.type="/",":",os.type or "unix" @@ -2763,7 +2795,7 @@ if platform~="" then elseif os.type=="windows" then function resolvers.platform(t,k) local platform,architecture="",os.getenv("PROCESSOR_ARCHITECTURE") or "" - if find(architecture,"AMD64") then + if find(architecture,"AMD64",1,true) then platform="win64" else platform="mswin" @@ -2775,9 +2807,9 @@ elseif os.type=="windows" then elseif name=="linux" then function resolvers.platform(t,k) local platform,architecture="",os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" - if find(architecture,"x86_64") then + if find(architecture,"x86_64",1,true) then platform="linux-64" - elseif find(architecture,"ppc") then + elseif find(architecture,"ppc",1,true) then platform="linux-ppc" else platform="linux" @@ -2791,9 +2823,9 @@ elseif name=="macosx" then local platform,architecture="",os.resultof("echo $HOSTTYPE") or "" if architecture=="" then platform="osx-intel" - elseif find(architecture,"i386") then + elseif find(architecture,"i386",1,true) then platform="osx-intel" - elseif find(architecture,"x86_64") then + elseif find(architecture,"x86_64",1,true) then platform="osx-64" else platform="osx-ppc" @@ -2805,7 +2837,7 @@ elseif name=="macosx" then elseif name=="sunos" then function resolvers.platform(t,k) local platform,architecture="",os.resultof("uname -m") or "" - if find(architecture,"sparc") then + if find(architecture,"sparc",1,true) then platform="solaris-sparc" else platform="solaris-intel" @@ -2817,7 +2849,7 @@ elseif name=="sunos" then elseif name=="freebsd" then function resolvers.platform(t,k) local platform,architecture="",os.resultof("uname -m") or "" - if find(architecture,"amd64") then + if find(architecture,"amd64",1,true) then platform="freebsd-amd64" else platform="freebsd" @@ -2829,7 +2861,7 @@ elseif name=="freebsd" then elseif name=="kfreebsd" then function resolvers.platform(t,k) local platform,architecture="",os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" - if find(architecture,"x86_64") then + if find(architecture,"x86_64",1,true) then platform="kfreebsd-amd64" else platform="kfreebsd-i386" @@ -2847,7 +2879,7 @@ else end end function resolvers.bits(t,k) - local bits=find(os.platform,"64") and 64 or 32 + local bits=find(os.platform,"64",1,true) and 64 or 32 os.bits=bits return bits end @@ -3735,7 +3767,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 14768, stripped down to: 9107 +-- original size: 14788, stripped down to: 9096 if not modules then modules={} end modules ['l-dir']={ version=1.001, @@ -3759,7 +3791,7 @@ local isfile=lfs.isfile local currentdir=lfs.currentdir local chdir=lfs.chdir local mkdir=lfs.mkdir -local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") +local onwindows=os.type=="windows" or find(os.getenv("PATH"),";",1,true) if not isdir then function isdir(name) local a=attributes(name) @@ -3861,7 +3893,7 @@ local function glob(str,t) local split=lpegmatch(pattern,str) if split then local root,path,base=split[1],split[2],split[3] - local recurse=find(base,"%*%*") + local recurse=find(base,"**",1,true) local start=root..path local result=lpegmatch(filter,start..base) globpattern(start,result,recurse,t) @@ -3887,7 +3919,7 @@ local function glob(str,t) local t=t or {} local action=action or function(name) t[#t+1]=name end local root,path,base=split[1],split[2],split[3] - local recurse=find(base,"%*%*") + local recurse=find(base,"**",1,true) local start=root..path local result=lpegmatch(filter,start..base) globpattern(start,result,recurse,action) @@ -3941,7 +3973,6 @@ if onwindows then else str="" for i=1,n do - local s=select(i,...) local s=select(i,...) if s=="" then elseif str=="" then @@ -4195,7 +4226,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-unicode"] = package.loaded["l-unicode"] or true --- original size: 33473, stripped down to: 14938 +-- original size: 33706, stripped down to: 14938 if not modules then modules={} end modules ['l-unicode']={ version=1.001, @@ -4840,7 +4871,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-str"] = package.loaded["util-str"] or true --- original size: 29502, stripped down to: 16632 +-- original size: 32843, stripped down to: 18226 if not modules then modules={} end modules ['util-str']={ version=1.001, @@ -4876,9 +4907,11 @@ end if not number then number={} end local stripper=patterns.stripzeros local function points(n) + n=tonumber(n) return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) end local function basepoints(n) + n=tonumber(n) return (not n or n==0) and "0bp" or lpegmatch(stripper,format("%.5fbp",n*(7200/7227)/65536)) end number.points=points @@ -4941,11 +4974,39 @@ local pattern=Carg(1)/function(t) function strings.tabtospace(str,tab) return lpegmatch(pattern,str,1,tab or 7) end -function strings.striplong(str) - str=gsub(str,"^%s*","") - str=gsub(str,"[\n\r]+ *","\n") - return str +local newline=patterns.newline +local endofstring=patterns.endofstring +local whitespace=patterns.whitespace +local spacer=patterns.spacer +local space=spacer^0 +local nospace=space/"" +local endofline=nospace*newline +local stripend=(whitespace^1*endofstring)/"" +local normalline=(nospace*((1-space*(newline+endofstring))^1)*nospace) +local stripempty=endofline^1/"" +local normalempty=endofline^1 +local singleempty=endofline*(endofline^0/"") +local doubleempty=endofline*endofline^-1*(endofline^0/"") +local stripstart=stripempty^0 +local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 ) +local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 ) +local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 ) +local p_retain_normal=Cs ((normalline+normalempty )^0 ) +local p_retain_collapse=Cs ((normalline+doubleempty )^0 ) +local p_retain_noempty=Cs ((normalline+singleempty )^0 ) +local striplinepatterns={ + ["prune"]=p_prune_normal, + ["prune and collapse"]=p_prune_collapse, + ["prune and no empty"]=p_prune_noempty, + ["retain"]=p_retain_normal, + ["retain and collapse"]=p_retain_collapse, + ["retain and no empty"]=p_retain_noempty, +} +strings.striplinepatterns=striplinepatterns +function strings.striplines(str,how) + return str and lpegmatch(how and striplinepatterns[how] or p_prune_collapse,str) or str end +strings.striplong=strings.striplines function strings.nice(str) str=gsub(str,"[:%-+_]+"," ") return str @@ -5111,7 +5172,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("format('%%i',a%s)",n) end end local format_d=format_i @@ -5123,6 +5184,10 @@ local format_f=function(f) n=n+1 return format("format('%%%sf',a%s)",f,n) end +local format_F=function(f) + n=n+1 + return format("((a%s == 0 and '0') or (a%s == 1 and '1') or format('%%%sf',a%s))",n,n,f,n) +end local format_g=function(f) n=n+1 return format("format('%%%sg',a%s)",f,n) @@ -5337,7 +5402,7 @@ local builder=Cs { "start", ( P("%")/""*( V("!") -+V("s")+V("q")+V("i")+V("d")+V("f")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") ++V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") +V("c")+V("C")+V("S") +V("Q") +V("N") @@ -5357,6 +5422,7 @@ local builder=Cs { "start", ["i"]=(prefix_any*P("i"))/format_i, ["d"]=(prefix_any*P("d"))/format_d, ["f"]=(prefix_any*P("f"))/format_f, + ["F"]=(prefix_any*P("F"))/format_F, ["g"]=(prefix_any*P("g"))/format_g, ["G"]=(prefix_any*P("G"))/format_G, ["e"]=(prefix_any*P("e"))/format_e, @@ -5404,7 +5470,7 @@ local function make(t,str) f=loadstripped(p)() else n=0 - p=lpegmatch(builder,str,1,"..",t._extensions_) + p=lpegmatch(builder,str,1,t._connector_,t._extensions_) if n>0 then p=format(template,preamble,t._preamble_,arguments[n],p) f=loadstripped(p,t._environment_)() @@ -5420,18 +5486,18 @@ local function use(t,fmt,...) end strings.formatters={} if _LUAVERSION<5.2 then - function strings.formatters.new() - local t={ _extensions_={},_preamble_=preamble,_environment_={},_type_="formatter" } + function strings.formatters.new(noconcat) + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } setmetatable(t,{ __index=make,__call=use }) return t end else - function strings.formatters.new() + function strings.formatters.new(noconcat) local e={} for k,v in next,environment do e[k]=v end - local t={ _extensions_={},_preamble_="",_environment_=e,_type_="formatter" } + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } setmetatable(t,{ __index=make,__call=use }) return t end @@ -5473,7 +5539,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23980, stripped down to: 16119 +-- original size: 23985, stripped down to: 16069 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5494,27 +5560,29 @@ local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs local formatters=string.formatters local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") -function tables.definetable(target,nofirst,nolast) - local composed,shortcut,t=nil,nil,{} +function utilities.tables.definetable(target,nofirst,nolast) + local composed,t=nil,{} local snippets=lpegmatch(splitter,target) for i=1,#snippets-(nolast and 1 or 0) do local name=snippets[i] if composed then - composed=shortcut.."."..name - shortcut=shortcut.."_"..name - t[#t+1]=formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) + composed=composed.."."..name + t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed) else composed=name - shortcut=name if not nofirst then t[#t+1]=formatters["%s = %s or { }"](composed,composed) end end end - if nolast then - composed=shortcut.."."..snippets[#snippets] + if composed then + if nolast then + composed=composed.."."..snippets[#snippets] + end + return concat(t,"\n"),composed + else + return "",target end - return concat(t,"\n"),composed end function tables.definedtable(...) local t=_G @@ -5541,7 +5609,7 @@ function tables.accesstable(target,root) end function tables.migratetable(target,v,root) local t=root or _G - local names=string.split(target,".") + local names=lpegmatch(splitter,target) for i=1,#names-1 do local name=names[i] t[name]=t[name] or {} @@ -6230,7 +6298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 19604, stripped down to: 13998 +-- original size: 19618, stripped down to: 14012 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6375,12 +6443,12 @@ function parsers.settings_to_array(str,strict) elseif not str or str=="" then return {} elseif strict then - if find(str,"{") then + if find(str,"{",1,true) then return lpegmatch(pattern,str) else return { str } end - elseif find(str,",") then + elseif find(str,",",1,true) then return lpegmatch(pattern,str) else return { str } @@ -7747,7 +7815,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6643, stripped down to: 5272 +-- original size: 7011, stripped down to: 5590 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7757,7 +7825,7 @@ if not modules then modules={} end modules ['trac-inf']={ license="see context related readme files" } local type,tonumber,select=type,tonumber,select -local format,lower=string.format,string.lower +local format,lower,find=string.format,string.lower,string.find local concat=table.concat local clock=os.gettimeofday or os.clock local setmetatableindex=table.setmetatableindex @@ -7848,10 +7916,8 @@ function statistics.show() if statistics.enable then local register=statistics.register register("used platform",function() - local mask=lua.mask or "ascii" - return format("%s, type: %s, binary subtree: %s, symbol mask: %s (%s)", - os.platform or "unknown",os.type or "unknown",environment.texos or "unknown", - mask,mask=="utf" and "τεχ" or "tex") + return format("%s, type: %s, binary subtree: %s", + os.platform or "unknown",os.type or "unknown",environment.texos or "unknown") end) register("luatex banner",function() return lower(status.banner) @@ -7864,14 +7930,23 @@ function statistics.show() return format("%s direct, %s indirect, %s total",total-indirect,indirect,total) end) if jit then - local status={ jit.status() } - if status[1] then - register("luajit status",function() - return concat(status," ",2) - end) + local jitstatus={ jit.status() } + if jitstatus[1] then + register("luajit options",concat(jitstatus," ",2)) end end - register("current memory usage",statistics.memused) + register("lua properties",function() + local list=status.list() + local hashchar=tonumber(list.luatex_hashchars) + local mask=lua.mask or "ascii" + return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + jit and "luajit" or "lua", + statistics.memused(), + list.luatex_hashtype or "default", + hashchar and 2^hashchar or "unknown", + mask, + mask=="utf" and "τεχ" or "tex") + end) register("runtime",statistics.runtime) logs.newline() for i=1,#statusinfo do @@ -8616,7 +8691,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8807, stripped down to: 5085 +-- original size: 8814, stripped down to: 5092 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8753,7 +8828,7 @@ function environment.reconstructcommandline(arg,noquote) a=resolvers.resolve(a) a=unquoted(a) a=gsub(a,'"','\\"') - if find(a," ") then + if find(a," ",1,true) then result[#result+1]=quoted(a) else result[#result+1]=a @@ -9955,7 +10030,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 48956, stripped down to: 30516 +-- original size: 48030, stripped down to: 30595 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -10936,8 +11011,13 @@ function xml.elements(root,pattern,reverse) local collected=applylpath(root,pattern) if not collected then return dummy - elseif reverse then - local c=#collected+1 + end + local n=#collected + if n==0 then + return dummy + end + if reverse then + local c=n+1 return function() if c>1 then c=c-1 @@ -10947,7 +11027,7 @@ function xml.elements(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c1 then c=c-1 @@ -10971,7 +11056,7 @@ function xml.collected(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c0 then p=format(template,preamble,t._preamble_,arguments[n],p) f=loadstripped(p,t._environment_)() @@ -5420,18 +5486,18 @@ local function use(t,fmt,...) end strings.formatters={} if _LUAVERSION<5.2 then - function strings.formatters.new() - local t={ _extensions_={},_preamble_=preamble,_environment_={},_type_="formatter" } + function strings.formatters.new(noconcat) + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } setmetatable(t,{ __index=make,__call=use }) return t end else - function strings.formatters.new() + function strings.formatters.new(noconcat) local e={} for k,v in next,environment do e[k]=v end - local t={ _extensions_={},_preamble_="",_environment_=e,_type_="formatter" } + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } setmetatable(t,{ __index=make,__call=use }) return t end @@ -5473,7 +5539,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23980, stripped down to: 16119 +-- original size: 23985, stripped down to: 16069 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5494,27 +5560,29 @@ local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs local formatters=string.formatters local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") -function tables.definetable(target,nofirst,nolast) - local composed,shortcut,t=nil,nil,{} +function utilities.tables.definetable(target,nofirst,nolast) + local composed,t=nil,{} local snippets=lpegmatch(splitter,target) for i=1,#snippets-(nolast and 1 or 0) do local name=snippets[i] if composed then - composed=shortcut.."."..name - shortcut=shortcut.."_"..name - t[#t+1]=formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) + composed=composed.."."..name + t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed) else composed=name - shortcut=name if not nofirst then t[#t+1]=formatters["%s = %s or { }"](composed,composed) end end end - if nolast then - composed=shortcut.."."..snippets[#snippets] + if composed then + if nolast then + composed=composed.."."..snippets[#snippets] + end + return concat(t,"\n"),composed + else + return "",target end - return concat(t,"\n"),composed end function tables.definedtable(...) local t=_G @@ -5541,7 +5609,7 @@ function tables.accesstable(target,root) end function tables.migratetable(target,v,root) local t=root or _G - local names=string.split(target,".") + local names=lpegmatch(splitter,target) for i=1,#names-1 do local name=names[i] t[name]=t[name] or {} @@ -6230,7 +6298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 19604, stripped down to: 13998 +-- original size: 19618, stripped down to: 14012 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6375,12 +6443,12 @@ function parsers.settings_to_array(str,strict) elseif not str or str=="" then return {} elseif strict then - if find(str,"{") then + if find(str,"{",1,true) then return lpegmatch(pattern,str) else return { str } end - elseif find(str,",") then + elseif find(str,",",1,true) then return lpegmatch(pattern,str) else return { str } @@ -7747,7 +7815,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6643, stripped down to: 5272 +-- original size: 7011, stripped down to: 5590 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7757,7 +7825,7 @@ if not modules then modules={} end modules ['trac-inf']={ license="see context related readme files" } local type,tonumber,select=type,tonumber,select -local format,lower=string.format,string.lower +local format,lower,find=string.format,string.lower,string.find local concat=table.concat local clock=os.gettimeofday or os.clock local setmetatableindex=table.setmetatableindex @@ -7848,10 +7916,8 @@ function statistics.show() if statistics.enable then local register=statistics.register register("used platform",function() - local mask=lua.mask or "ascii" - return format("%s, type: %s, binary subtree: %s, symbol mask: %s (%s)", - os.platform or "unknown",os.type or "unknown",environment.texos or "unknown", - mask,mask=="utf" and "τεχ" or "tex") + return format("%s, type: %s, binary subtree: %s", + os.platform or "unknown",os.type or "unknown",environment.texos or "unknown") end) register("luatex banner",function() return lower(status.banner) @@ -7864,14 +7930,23 @@ function statistics.show() return format("%s direct, %s indirect, %s total",total-indirect,indirect,total) end) if jit then - local status={ jit.status() } - if status[1] then - register("luajit status",function() - return concat(status," ",2) - end) + local jitstatus={ jit.status() } + if jitstatus[1] then + register("luajit options",concat(jitstatus," ",2)) end end - register("current memory usage",statistics.memused) + register("lua properties",function() + local list=status.list() + local hashchar=tonumber(list.luatex_hashchars) + local mask=lua.mask or "ascii" + return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + jit and "luajit" or "lua", + statistics.memused(), + list.luatex_hashtype or "default", + hashchar and 2^hashchar or "unknown", + mask, + mask=="utf" and "τεχ" or "tex") + end) register("runtime",statistics.runtime) logs.newline() for i=1,#statusinfo do @@ -8616,7 +8691,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8807, stripped down to: 5085 +-- original size: 8814, stripped down to: 5092 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8753,7 +8828,7 @@ function environment.reconstructcommandline(arg,noquote) a=resolvers.resolve(a) a=unquoted(a) a=gsub(a,'"','\\"') - if find(a," ") then + if find(a," ",1,true) then result[#result+1]=quoted(a) else result[#result+1]=a @@ -9955,7 +10030,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 48956, stripped down to: 30516 +-- original size: 48030, stripped down to: 30595 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -10936,8 +11011,13 @@ function xml.elements(root,pattern,reverse) local collected=applylpath(root,pattern) if not collected then return dummy - elseif reverse then - local c=#collected+1 + end + local n=#collected + if n==0 then + return dummy + end + if reverse then + local c=n+1 return function() if c>1 then c=c-1 @@ -10947,7 +11027,7 @@ function xml.elements(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c1 then c=c-1 @@ -10971,7 +11056,7 @@ function xml.collected(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c0 then p=format(template,preamble,t._preamble_,arguments[n],p) f=loadstripped(p,t._environment_)() @@ -5420,18 +5486,18 @@ local function use(t,fmt,...) end strings.formatters={} if _LUAVERSION<5.2 then - function strings.formatters.new() - local t={ _extensions_={},_preamble_=preamble,_environment_={},_type_="formatter" } + function strings.formatters.new(noconcat) + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } setmetatable(t,{ __index=make,__call=use }) return t end else - function strings.formatters.new() + function strings.formatters.new(noconcat) local e={} for k,v in next,environment do e[k]=v end - local t={ _extensions_={},_preamble_="",_environment_=e,_type_="formatter" } + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } setmetatable(t,{ __index=make,__call=use }) return t end @@ -5473,7 +5539,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23980, stripped down to: 16119 +-- original size: 23985, stripped down to: 16069 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5494,27 +5560,29 @@ local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs local formatters=string.formatters local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") -function tables.definetable(target,nofirst,nolast) - local composed,shortcut,t=nil,nil,{} +function utilities.tables.definetable(target,nofirst,nolast) + local composed,t=nil,{} local snippets=lpegmatch(splitter,target) for i=1,#snippets-(nolast and 1 or 0) do local name=snippets[i] if composed then - composed=shortcut.."."..name - shortcut=shortcut.."_"..name - t[#t+1]=formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) + composed=composed.."."..name + t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed) else composed=name - shortcut=name if not nofirst then t[#t+1]=formatters["%s = %s or { }"](composed,composed) end end end - if nolast then - composed=shortcut.."."..snippets[#snippets] + if composed then + if nolast then + composed=composed.."."..snippets[#snippets] + end + return concat(t,"\n"),composed + else + return "",target end - return concat(t,"\n"),composed end function tables.definedtable(...) local t=_G @@ -5541,7 +5609,7 @@ function tables.accesstable(target,root) end function tables.migratetable(target,v,root) local t=root or _G - local names=string.split(target,".") + local names=lpegmatch(splitter,target) for i=1,#names-1 do local name=names[i] t[name]=t[name] or {} @@ -6230,7 +6298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 19604, stripped down to: 13998 +-- original size: 19618, stripped down to: 14012 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6375,12 +6443,12 @@ function parsers.settings_to_array(str,strict) elseif not str or str=="" then return {} elseif strict then - if find(str,"{") then + if find(str,"{",1,true) then return lpegmatch(pattern,str) else return { str } end - elseif find(str,",") then + elseif find(str,",",1,true) then return lpegmatch(pattern,str) else return { str } @@ -7747,7 +7815,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6643, stripped down to: 5272 +-- original size: 7011, stripped down to: 5590 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7757,7 +7825,7 @@ if not modules then modules={} end modules ['trac-inf']={ license="see context related readme files" } local type,tonumber,select=type,tonumber,select -local format,lower=string.format,string.lower +local format,lower,find=string.format,string.lower,string.find local concat=table.concat local clock=os.gettimeofday or os.clock local setmetatableindex=table.setmetatableindex @@ -7848,10 +7916,8 @@ function statistics.show() if statistics.enable then local register=statistics.register register("used platform",function() - local mask=lua.mask or "ascii" - return format("%s, type: %s, binary subtree: %s, symbol mask: %s (%s)", - os.platform or "unknown",os.type or "unknown",environment.texos or "unknown", - mask,mask=="utf" and "τεχ" or "tex") + return format("%s, type: %s, binary subtree: %s", + os.platform or "unknown",os.type or "unknown",environment.texos or "unknown") end) register("luatex banner",function() return lower(status.banner) @@ -7864,14 +7930,23 @@ function statistics.show() return format("%s direct, %s indirect, %s total",total-indirect,indirect,total) end) if jit then - local status={ jit.status() } - if status[1] then - register("luajit status",function() - return concat(status," ",2) - end) + local jitstatus={ jit.status() } + if jitstatus[1] then + register("luajit options",concat(jitstatus," ",2)) end end - register("current memory usage",statistics.memused) + register("lua properties",function() + local list=status.list() + local hashchar=tonumber(list.luatex_hashchars) + local mask=lua.mask or "ascii" + return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + jit and "luajit" or "lua", + statistics.memused(), + list.luatex_hashtype or "default", + hashchar and 2^hashchar or "unknown", + mask, + mask=="utf" and "τεχ" or "tex") + end) register("runtime",statistics.runtime) logs.newline() for i=1,#statusinfo do @@ -8616,7 +8691,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8807, stripped down to: 5085 +-- original size: 8814, stripped down to: 5092 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8753,7 +8828,7 @@ function environment.reconstructcommandline(arg,noquote) a=resolvers.resolve(a) a=unquoted(a) a=gsub(a,'"','\\"') - if find(a," ") then + if find(a," ",1,true) then result[#result+1]=quoted(a) else result[#result+1]=a @@ -9955,7 +10030,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 48956, stripped down to: 30516 +-- original size: 48030, stripped down to: 30595 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -10936,8 +11011,13 @@ function xml.elements(root,pattern,reverse) local collected=applylpath(root,pattern) if not collected then return dummy - elseif reverse then - local c=#collected+1 + end + local n=#collected + if n==0 then + return dummy + end + if reverse then + local c=n+1 return function() if c>1 then c=c-1 @@ -10947,7 +11027,7 @@ function xml.elements(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c1 then c=c-1 @@ -10971,7 +11056,7 @@ function xml.collected(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c0 then p=format(template,preamble,t._preamble_,arguments[n],p) f=loadstripped(p,t._environment_)() @@ -5420,18 +5486,18 @@ local function use(t,fmt,...) end strings.formatters={} if _LUAVERSION<5.2 then - function strings.formatters.new() - local t={ _extensions_={},_preamble_=preamble,_environment_={},_type_="formatter" } + function strings.formatters.new(noconcat) + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } setmetatable(t,{ __index=make,__call=use }) return t end else - function strings.formatters.new() + function strings.formatters.new(noconcat) local e={} for k,v in next,environment do e[k]=v end - local t={ _extensions_={},_preamble_="",_environment_=e,_type_="formatter" } + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } setmetatable(t,{ __index=make,__call=use }) return t end @@ -5473,7 +5539,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23980, stripped down to: 16119 +-- original size: 23985, stripped down to: 16069 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5494,27 +5560,29 @@ local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs local formatters=string.formatters local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") -function tables.definetable(target,nofirst,nolast) - local composed,shortcut,t=nil,nil,{} +function utilities.tables.definetable(target,nofirst,nolast) + local composed,t=nil,{} local snippets=lpegmatch(splitter,target) for i=1,#snippets-(nolast and 1 or 0) do local name=snippets[i] if composed then - composed=shortcut.."."..name - shortcut=shortcut.."_"..name - t[#t+1]=formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) + composed=composed.."."..name + t[#t+1]=formatters["if not %s then %s = { } end"](composed,composed) else composed=name - shortcut=name if not nofirst then t[#t+1]=formatters["%s = %s or { }"](composed,composed) end end end - if nolast then - composed=shortcut.."."..snippets[#snippets] + if composed then + if nolast then + composed=composed.."."..snippets[#snippets] + end + return concat(t,"\n"),composed + else + return "",target end - return concat(t,"\n"),composed end function tables.definedtable(...) local t=_G @@ -5541,7 +5609,7 @@ function tables.accesstable(target,root) end function tables.migratetable(target,v,root) local t=root or _G - local names=string.split(target,".") + local names=lpegmatch(splitter,target) for i=1,#names-1 do local name=names[i] t[name]=t[name] or {} @@ -6230,7 +6298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 19604, stripped down to: 13998 +-- original size: 19618, stripped down to: 14012 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6375,12 +6443,12 @@ function parsers.settings_to_array(str,strict) elseif not str or str=="" then return {} elseif strict then - if find(str,"{") then + if find(str,"{",1,true) then return lpegmatch(pattern,str) else return { str } end - elseif find(str,",") then + elseif find(str,",",1,true) then return lpegmatch(pattern,str) else return { str } @@ -7747,7 +7815,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6643, stripped down to: 5272 +-- original size: 7011, stripped down to: 5590 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7757,7 +7825,7 @@ if not modules then modules={} end modules ['trac-inf']={ license="see context related readme files" } local type,tonumber,select=type,tonumber,select -local format,lower=string.format,string.lower +local format,lower,find=string.format,string.lower,string.find local concat=table.concat local clock=os.gettimeofday or os.clock local setmetatableindex=table.setmetatableindex @@ -7848,10 +7916,8 @@ function statistics.show() if statistics.enable then local register=statistics.register register("used platform",function() - local mask=lua.mask or "ascii" - return format("%s, type: %s, binary subtree: %s, symbol mask: %s (%s)", - os.platform or "unknown",os.type or "unknown",environment.texos or "unknown", - mask,mask=="utf" and "τεχ" or "tex") + return format("%s, type: %s, binary subtree: %s", + os.platform or "unknown",os.type or "unknown",environment.texos or "unknown") end) register("luatex banner",function() return lower(status.banner) @@ -7864,14 +7930,23 @@ function statistics.show() return format("%s direct, %s indirect, %s total",total-indirect,indirect,total) end) if jit then - local status={ jit.status() } - if status[1] then - register("luajit status",function() - return concat(status," ",2) - end) + local jitstatus={ jit.status() } + if jitstatus[1] then + register("luajit options",concat(jitstatus," ",2)) end end - register("current memory usage",statistics.memused) + register("lua properties",function() + local list=status.list() + local hashchar=tonumber(list.luatex_hashchars) + local mask=lua.mask or "ascii" + return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + jit and "luajit" or "lua", + statistics.memused(), + list.luatex_hashtype or "default", + hashchar and 2^hashchar or "unknown", + mask, + mask=="utf" and "τεχ" or "tex") + end) register("runtime",statistics.runtime) logs.newline() for i=1,#statusinfo do @@ -8616,7 +8691,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8807, stripped down to: 5085 +-- original size: 8814, stripped down to: 5092 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8753,7 +8828,7 @@ function environment.reconstructcommandline(arg,noquote) a=resolvers.resolve(a) a=unquoted(a) a=gsub(a,'"','\\"') - if find(a," ") then + if find(a," ",1,true) then result[#result+1]=quoted(a) else result[#result+1]=a @@ -9955,7 +10030,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-lpt"] = package.loaded["lxml-lpt"] or true --- original size: 48956, stripped down to: 30516 +-- original size: 48030, stripped down to: 30595 if not modules then modules={} end modules ['lxml-lpt']={ version=1.001, @@ -10936,8 +11011,13 @@ function xml.elements(root,pattern,reverse) local collected=applylpath(root,pattern) if not collected then return dummy - elseif reverse then - local c=#collected+1 + end + local n=#collected + if n==0 then + return dummy + end + if reverse then + local c=n+1 return function() if c>1 then c=c-1 @@ -10947,7 +11027,7 @@ function xml.elements(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c1 then c=c-1 @@ -10971,7 +11056,7 @@ function xml.collected(root,pattern,reverse) end end else - local n,c=#collected,0 + local c=0 return function() if c -- plus (extra) is obsolete but we will keep it for a while +-- context(new_latelua_node(f_enhance(tag))) +-- => +-- context.lateluafunction(function() f_enhance(tag) end) + -- maybe replace texsp by our own converter (stay at the lua end) -- eventually mp will have large numbers so we can use sp there too @@ -174,9 +178,12 @@ local nofpages = nil -- beware ... we're not sparse here as lua will reserve slots for the nilled +local getpos = function() getpos = backends.codeinjections.getpos return getpos () end +local gethpos = function() gethpos = backends.codeinjections.gethpos return gethpos() end +local getvpos = function() getvpos = backends.codeinjections.getvpos return getvpos() end + local function setdim(name,w,h,d,extra) -- will be used when we move to sp allover - local x = pdf.h - local y = pdf.v + local x, y = getpos() if x == 0 then x = nil end if y == 0 then y = nil end if w == 0 then w = nil end @@ -226,10 +233,13 @@ local function enhance(data) data.r = region end if data.x == true then - data.x = pdf.h - end - if data.y == true then - data.y = pdf.v + if data.y == true then + data.x, data.y = getpos() + else + data.x = gethpos() + end + elseif data.y == true then + data.y = getvpos() end if data.p == true then data.p = texgetcount("realpageno") @@ -289,7 +299,7 @@ commands.setpos = setall function jobpositions.b_col(tag) tobesaved[tag] = { r = true, - x = pdf.h, + x = gethpos(), w = 0, } insert(columns,tag) @@ -301,7 +311,7 @@ function jobpositions.e_col(tag) if not t then -- something's wrong else - t.w = pdf.h - t.x + t.w = gethpos() - t.x t.r = region end remove(columns) @@ -328,8 +338,7 @@ end function jobpositions.b_region(tag) local last = tobesaved[tag] - last.x = pdf.h - last.y = pdf.v + last.x, last.y = getpos() last.p = texgetcount("realpageno") insert(regions,tag) region = tag @@ -337,10 +346,11 @@ end function jobpositions.e_region(correct) local last = tobesaved[region] + local v = getvpos() if correct then - last.h = last.y - pdf.v + last.h = last.y - v end - last.y = pdf.v + last.y = v remove(regions) region = regions[#regions] end @@ -357,7 +367,7 @@ function jobpositions.markregionbox(n,tag,correct) tobesaved[tag] = { p = true, x = true, - y = pdf.v, -- true, + y = getvpos(), -- true, w = w ~= 0 and w or nil, h = h ~= 0 and h or nil, d = d ~= 0 and d or nil, @@ -748,7 +758,7 @@ function commands.MPx(id) if jpi then local x = jpi.x if x and x ~= true and x ~= 0 then - context("%.5fpt",x*pt) + context("%.5Fpt",x*pt) return end end @@ -760,7 +770,7 @@ function commands.MPy(id) if jpi then local y = jpi.y if y and y ~= true and y ~= 0 then - context("%.5fpt",y*pt) + context("%.5Fpt",y*pt) return end end @@ -772,7 +782,7 @@ function commands.MPw(id) if jpi then local w = jpi.w if w and w ~= 0 then - context("%.5fpt",w*pt) + context("%.5Fpt",w*pt) return end end @@ -784,7 +794,7 @@ function commands.MPh(id) if jpi then local h = jpi.h if h and h ~= 0 then - context("%.5fpt",h*pt) + context("%.5Fpt",h*pt) return end end @@ -796,7 +806,7 @@ function commands.MPd(id) if jpi then local d = jpi.d if d and d ~= 0 then - context("%.5fpt",d*pt) + context("%.5Fpt",d*pt) return end end @@ -806,7 +816,7 @@ end function commands.MPxy(id) local jpi = collected[id] if jpi then - context('(%.5fpt,%.5fpt)', + context('(%.5Fpt,%.5Fpt)', jpi.x*pt, jpi.y*pt ) @@ -818,7 +828,7 @@ end function commands.MPll(id) local jpi = collected[id] if jpi then - context('(%.5fpt,%.5fpt)', + context('(%.5Fpt,%.5Fpt)', jpi.x *pt, (jpi.y-jpi.d)*pt ) @@ -830,7 +840,7 @@ end function commands.MPlr(id) local jpi = collected[id] if jpi then - context('(%.5fpt,%.5fpt)', + context('(%.5Fpt,%.5Fpt)', (jpi.x + jpi.w)*pt, (jpi.y - jpi.d)*pt ) @@ -842,7 +852,7 @@ end function commands.MPur(id) local jpi = collected[id] if jpi then - context('(%.5fpt,%.5fpt)', + context('(%.5Fpt,%.5Fpt)', (jpi.x + jpi.w)*pt, (jpi.y + jpi.h)*pt ) @@ -854,7 +864,7 @@ end function commands.MPul(id) local jpi = collected[id] if jpi then - context('(%.5fpt,%.5fpt)', + context('(%.5Fpt,%.5Fpt)', jpi.x *pt, (jpi.y + jpi.h)*pt ) @@ -868,7 +878,7 @@ local function MPpos(id) if jpi then local p = jpi.p if p then - context("%s,%.5fpt,%.5fpt,%.5fpt,%.5fpt,%.5fpt", + context("%s,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt", p, jpi.x*pt, jpi.y*pt, @@ -926,7 +936,7 @@ local function MPpardata(n) t = collected[tag] end if t then - context("%.5fpt,%.5fpt,%.5fpt,%.5fpt,%s,%.5fpt", + context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%s,%.5Fpt", t.hs*pt, t.ls*pt, t.rs*pt, @@ -952,7 +962,7 @@ end function commands.MPls(id) local t = collected[id] if t then - context("%.5fpt",t.ls*pt) + context("%.5Fpt",t.ls*pt) else context("0pt") end @@ -961,7 +971,7 @@ end function commands.MPrs(id) local t = collected[id] if t then - context("%.5fpt",t.rs*pt) + context("%.5Fpt",t.rs*pt) else context("0pt") end @@ -994,7 +1004,7 @@ end function commands.MPxywhd(id) local t = collected[id] if t then - context("%.5fpt,%.5fpt,%.5fpt,%.5fpt,%.5fpt", + context("%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt,%.5Fpt", t.x*pt, t.y*pt, t.w*pt, diff --git a/tex/context/base/attr-lay.mkiv b/tex/context/base/attr-lay.mkiv index d4aae3060..6055c2a73 100644 --- a/tex/context/base/attr-lay.mkiv +++ b/tex/context/base/attr-lay.mkiv @@ -94,8 +94,7 @@ \let\layoutcomponentboxattribute \empty \unexpanded\def\showlayoutcomponents - {%\ctxlua{attributes.viewerlayers.enable()}% automatic - \let\setlayoutcomponentattribute \attr_layoutcomponent_set + {\let\setlayoutcomponentattribute \attr_layoutcomponent_set \let\resetlayoutcomponentattribute\attr_layoutcomponent_reset} \unexpanded\def\attr_layoutcomponent_cleanup diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua index d4133396b..79538eb72 100644 --- a/tex/context/base/back-exp.lua +++ b/tex/context/base/back-exp.lua @@ -609,8 +609,8 @@ function structurestags.setfigure(name,page,width,height) usedimages.image[detailedtag("image")] = { name = name, page = page, - width = number.todimen(width,"cm","%0.3fcm"), - height = number.todimen(height,"cm","%0.3fcm"), + width = number.todimen(width, "cm","%0.3Fcm"), + height = number.todimen(height,"cm","%0.3Fcm"), } end diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua index 6f58b3262..e2dabd91e 100644 --- a/tex/context/base/back-ini.lua +++ b/tex/context/base/back-ini.lua @@ -95,3 +95,11 @@ tables.vfspecials = allocate { startslant = comment, stopslant = comment, } + +-- we'd better have this return something (defaults) + +function codeinjections.getpos () return 0, 0 end +function codeinjections.gethpos () return 0 end +function codeinjections.getvpos () return 0 end +function codeinjections.hasmatrix() return false end +function codeinjections.getmatrix() return 1, 0, 0, 1, 0, 0 end diff --git a/tex/context/base/back-ini.mkiv b/tex/context/base/back-ini.mkiv index fc8759c14..de4ba6138 100644 --- a/tex/context/base/back-ini.mkiv +++ b/tex/context/base/back-ini.mkiv @@ -23,8 +23,9 @@ \unprotect -\ifdefined\everybackendshipout \else \newtoks\everybackendshipout \fi -\ifdefined\everylastbackendshipout \else \newtoks\everylastbackendshipout \fi +\ifdefined\everybackendshipout \else \newtoks\everybackendshipout \fi +\ifdefined\everylastbackendshipout \else \newtoks\everylastbackendshipout \fi +\ifdefined\everybackendlastinshipout \else \newtoks\everybackendlastinshipout \fi % e.g. finalize via latelua %D Right from the start \CONTEXT\ had a backend system based on %D runtime pluggable code. As most backend issues involved specials @@ -126,9 +127,9 @@ %D From now on, mapfile loading is also a special; we assume the %D more or less standard dvips syntax. -\let \doresetmapfilelist \donothing -\let \doloadmapfile \gobbletwoarguments % + - = | filename -\let \doloadmapline \gobbletwoarguments % + - = | fileline +%let \doresetmapfilelist \donothing +%let \doloadmapfile \gobbletwoarguments % + - = | filename +%let \doloadmapline \gobbletwoarguments % + - = | fileline %D \macros %D {jobsuffix} diff --git a/tex/context/base/back-pdf.lua b/tex/context/base/back-pdf.lua index f8a5dab6f..34a28e3f7 100644 --- a/tex/context/base/back-pdf.lua +++ b/tex/context/base/back-pdf.lua @@ -24,7 +24,7 @@ local context = context local sind, cosd = math.sind, math.cosd local insert, remove = table.insert, table.remove -local f_matrix = string.formatters["%0.8f %0.8f %0.8f %0.8f"] +local f_matrix = string.formatters["%0.8F %0.8F %0.8F %0.8F"] function commands.pdfrotation(a) -- todo: check for 1 and 0 and flush sparse diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv index 948a14138..5423a0df6 100644 --- a/tex/context/base/back-pdf.mkiv +++ b/tex/context/base/back-pdf.mkiv @@ -238,7 +238,7 @@ %D The following will move to the backend \LUA\ code: -\appendtoks \ctxlua{backends.codeinjections.finalizepage ()}\to \everybackendshipout % is immediate +%appendtoks \ctxlua{backends.codeinjections.finalizepage ()}\to \everybackendshipout % is immediate %appendtoks \ctxlua{backends.codeinjections.finalizedocument()}\to \everylastbackendshipout % is immediate %D Temporary hack, will be removed or improved or default. diff --git a/tex/context/base/bibl-tra.lua b/tex/context/base/bibl-tra.lua index 75dc3e86f..223554b4d 100644 --- a/tex/context/base/bibl-tra.lua +++ b/tex/context/base/bibl-tra.lua @@ -55,11 +55,11 @@ local ordered = { } local shorts = { } local mode = 0 -local template = utilities.strings.striplong([[ - \citation{*} - \bibstyle{cont-%s} - \bibdata{%s} -]]) +local template = [[ +\citation{*} +\bibstyle{cont-%s} +\bibdata{%s} +]] local bibtexbin = environment.arguments.mlbibtex and "mlbibcontext" or "bibtex" diff --git a/tex/context/base/buff-imp-lua.lua b/tex/context/base/buff-imp-lua.lua index 04e79afba..4396c1ab8 100644 --- a/tex/context/base/buff-imp-lua.lua +++ b/tex/context/base/buff-imp-lua.lua @@ -139,7 +139,7 @@ local comment = P("--") local name = (patterns.letter + patterns.underscore) * (patterns.letter + patterns.underscore + patterns.digit)^0 local boundary = S('()[]{}') -local special = S("-+/*^%=#") + P("..") +local special = S("-+/*^%=#~|<>") + P("..") -- The following longstring parser is taken from Roberto's documentation -- that can be found at http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html. diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua index 08416c9ad..1196b7890 100644 --- a/tex/context/base/buff-ini.lua +++ b/tex/context/base/buff-ini.lua @@ -143,37 +143,12 @@ local function collectcontent(name,separator) -- no print end local function loadcontent(name) -- no print - local names = getnames(name) - local nnames = #names - local ok = false - if nnames == 0 then - ok = load(getcontent("")) -- default buffer - elseif nnames == 1 then - ok = load(getcontent(names[1])) - else - -- lua 5.2 chunked load - local i = 0 - ok = load(function() - while true do - i = i + 1 - if i > nnames then - return nil - end - local c = getcontent(names[i]) - if c == "" then - -- would trigger end of load - else - return c - end - end - end) - end + local content = collectcontent(name,"\n") + local ok, err = load(content) if ok then return ok() - elseif nnames == 0 then - report_buffers("invalid lua code in default buffer") else - report_buffers("invalid lua code in buffer %a",concat(names,",")) + report_buffers("invalid lua code in buffer %a: %s",name,err or "unknown error") end end diff --git a/tex/context/base/buff-ver.lua b/tex/context/base/buff-ver.lua index 3300ac6cb..14914d42d 100644 --- a/tex/context/base/buff-ver.lua +++ b/tex/context/base/buff-ver.lua @@ -46,70 +46,70 @@ local v_all = variables.all -- beware, all macros have an argument: -local doinlineverbatimnewline = context.doinlineverbatimnewline -local doinlineverbatimbeginline = context.doinlineverbatimbeginline -local doinlineverbatimemptyline = context.doinlineverbatimemptyline -local doinlineverbatimstart = context.doinlineverbatimstart -local doinlineverbatimstop = context.doinlineverbatimstop - -local dodisplayverbatiminitialize = context.dodisplayverbatiminitialize -- the number of arguments might change over time -local dodisplayverbatimnewline = context.dodisplayverbatimnewline -local dodisplayverbatimbeginline = context.dodisplayverbatimbeginline -local dodisplayverbatimemptyline = context.dodisplayverbatimemptyline -local dodisplayverbatimstart = context.dodisplayverbatimstart -local dodisplayverbatimstop = context.dodisplayverbatimstop - -local verbatim = context.verbatim -local doverbatimspace = context.doverbatimspace +local ctx_inlineverbatimnewline = context.doinlineverbatimnewline +local ctx_inlineverbatimbeginline = context.doinlineverbatimbeginline +local ctx_inlineverbatimemptyline = context.doinlineverbatimemptyline +local ctx_inlineverbatimstart = context.doinlineverbatimstart +local ctx_inlineverbatimstop = context.doinlineverbatimstop + +local ctx_displayverbatiminitialize = context.dodisplayverbatiminitialize -- the number of arguments might change over time +local ctx_displayverbatimnewline = context.dodisplayverbatimnewline +local ctx_displayverbatimbeginline = context.dodisplayverbatimbeginline +local ctx_displayverbatimemptyline = context.dodisplayverbatimemptyline +local ctx_displayverbatimstart = context.dodisplayverbatimstart +local ctx_displayverbatimstop = context.dodisplayverbatimstop + +local ctx_verbatim = context.verbatim +local ctx_verbatimspace = context.doverbatimspace local CargOne = Carg(1) local function f_emptyline(s,settings) if settings and settings.nature == "inline" then - doinlineverbatimemptyline() + ctx_inlineverbatimemptyline() else - dodisplayverbatimemptyline() + ctx_displayverbatimemptyline() end end local function f_beginline(s,settings) if settings and settings.nature == "inline" then - doinlineverbatimbeginline() + ctx_inlineverbatimbeginline() else - dodisplayverbatimbeginline() + ctx_displayverbatimbeginline() end end local function f_newline(s,settings) if settings and settings.nature == "inline" then - doinlineverbatimnewline() + ctx_inlineverbatimnewline() else - dodisplayverbatimnewline() + ctx_displayverbatimnewline() end end local function f_start(s,settings) if settings and settings.nature == "inline" then - doinlineverbatimstart() + ctx_inlineverbatimstart() else - dodisplayverbatimstart() + ctx_displayverbatimstart() end end local function f_stop(s,settings) if settings and settings.nature == "inline" then - doinlineverbatimstop() + ctx_inlineverbatimstop() else - dodisplayverbatimstop() + ctx_displayverbatimstop() end end local function f_default(s) -- (s,settings) - verbatim(s) + ctx_verbatim(s) end local function f_space() -- (s,settings) - doverbatimspace() + ctx_verbatimspace() end local function f_signal() -- (s,settings) @@ -200,7 +200,7 @@ local function getvisualizer(method,nature) end end -local fallback = context.verbatim +local ctx_fallback = ctx_verbatim local function makepattern(visualizer,replacement,pattern) if not pattern then @@ -208,9 +208,9 @@ local function makepattern(visualizer,replacement,pattern) return patterns.alwaystrue else if type(visualizer) == "table" and type(replacement) == "string" then - replacement = visualizer[replacement] or fallback + replacement = visualizer[replacement] or ctx_fallback else - replacement = fallback + replacement = ctx_fallback end return (C(pattern) * CargOne) / replacement end @@ -506,7 +506,7 @@ local function visualize(content,settings) -- maybe also method in settings if trace_visualize then report_visualizers("visualize using method %a",method) end - fallback(content,1,settings) + ctx_fallback(content,1,settings) end end end @@ -711,7 +711,7 @@ commands.loadvisualizer = visualizers.load function commands.typebuffer(settings) local lines = getlines(settings.name) if lines then - dodisplayverbatiminitialize(#lines) + ctx_displayverbatiminitialize(#lines) local content, m = filter(lines,settings) if content and content ~= "" then -- content = decodecomment(content) diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv index 6c4fb6fc1..17dfd9d69 100644 --- a/tex/context/base/buff-ver.mkiv +++ b/tex/context/base/buff-ver.mkiv @@ -19,6 +19,8 @@ \unprotect +\startcontextdefinitioncode + \definesystemattribute[verbatimline][public] \appendtoksonce @@ -169,7 +171,11 @@ \appendtoks \setuevalue{\e!start\currenttyping}{\buff_verbatim_typing_start{\currenttyping}}% \setuevalue{\e!stop \currenttyping}{\buff_verbatim_typing_stop {\currenttyping}}% - \normalexpanded{\definelinenumbering[\currenttyping]}% + \ifx\currenttypingparent\empty + \normalexpanded{\definelinenumbering[\currenttyping]}% + \else + \normalexpanded{\definelinenumbering[\currenttyping][\currenttypingparent]}% + \fi \to \everydefinetyping \appendtoks @@ -261,7 +267,7 @@ {\dontleavehmode \bgroup \edef\currenttype{#1}% - \doifnextoptionalelse\buff_verbatim_type_yes\buff_verbatim_type_nop} + \doifnextoptionalcselse\buff_verbatim_type_yes\buff_verbatim_type_nop} \def\buff_verbatim_type_yes[#1]% {\setupcurrenttype[#1]% @@ -277,7 +283,7 @@ \edef\currenttype{#1}% \lettypeparameter\c!lines\v!hyphenated \let\specialobeyedspace\specialstretchedspace - \doifnextoptionalelse\buff_verbatim_type_yes\buff_verbatim_type_nop} + \doifnextoptionalcselse\buff_verbatim_type_yes\buff_verbatim_type_nop} \def\buff_verbatim_type_one {\ifx\next\bgroup @@ -696,8 +702,11 @@ \definetyping[\v!typing] -\setuptyping[\v!file] [\s!parent=\??typing\v!typing] % we don't want \start..\stop overload -\setuptyping[\v!buffer][\s!parent=\??typing\v!file] % we don't want \start..\stop overload +\setuptyping [\v!file] [\s!parent=\??typing \v!typing] % we don't want \start..\stop overload +\setuplinenumbering[\v!file] [\s!parent=\??linenumbering\v!typing] + +\setuptyping [\v!buffer][\s!parent=\??typing \v!file] % we don't want \start..\stop overload +\setuplinenumbering[\v!buffer][\s!parent=\??linenumbering\v!file] %D The setups for inline verbatim default to: @@ -910,4 +919,6 @@ \def\tex #1{\letterbackslash#1}% \to \everysimplifycommands +\stopcontextdefinitioncode + \protect \endinput diff --git a/tex/context/base/catc-ctx.mkiv b/tex/context/base/catc-ctx.mkiv index ddade7f52..5af8a5035 100644 --- a/tex/context/base/catc-ctx.mkiv +++ b/tex/context/base/catc-ctx.mkiv @@ -142,4 +142,38 @@ \normalprotected\def\stopcontextcode {\popcatcodetable} +% not visible, only for special cases + +\newcatcodetable \ctdcatcodes % context definitions + +\startcatcodetable \ctdcatcodes + \catcode\tabasciicode \ignorecatcode + \catcode\endoflineasciicode \ignorecatcode + \catcode\formfeedasciicode \ignorecatcode + \catcode\spaceasciicode \ignorecatcode + \catcode\endoffileasciicode \ignorecatcode + \catcode\circumflexasciicode \superscriptcatcode % candidate + \catcode\underscoreasciicode \lettercatcode + \catcode\ampersandasciicode \alignmentcatcode +% \catcode\colonasciicode \lettercatcode % candidate + \catcode\backslashasciicode \escapecatcode + \catcode\leftbraceasciicode \begingroupcatcode + \catcode\rightbraceasciicode \endgroupcatcode + \catcode\dollarasciicode \mathshiftcatcode + \catcode\hashasciicode \parametercatcode + \catcode\commentasciicode \commentcatcode + \catcode\atsignasciicode \lettercatcode + \catcode\exclamationmarkasciicode\lettercatcode + \catcode\questionmarkasciicode \lettercatcode + \catcode\tildeasciicode \activecatcode + \catcode\barasciicode \activecatcode +\stopcatcodetable + +\normalprotected\def\startcontextdefinitioncode + {\pushcatcodetable + \catcodetable\ctdcatcodes} + +\normalprotected\def\stopcontextdefinitioncode + {\popcatcodetable} + \endinput diff --git a/tex/context/base/catc-ini.lua b/tex/context/base/catc-ini.lua index d4f9b65af..9241f5a1b 100644 --- a/tex/context/base/catc-ini.lua +++ b/tex/context/base/catc-ini.lua @@ -39,3 +39,7 @@ end table.setmetatableindex(numbers,function(t,k) if type(k) == "number" then t[k] = k return k end end) table.setmetatableindex(names, function(t,k) if type(k) == "string" then t[k] = k return k end end) + +commands.registercatcodetable = catcodes.register +--------.definecatcodetable = characters.define -- not yet defined +--------.setcharactercodes = characters.setcodes -- not yet defined diff --git a/tex/context/base/catc-ini.mkiv b/tex/context/base/catc-ini.mkiv index 791ce31c4..d8247217c 100644 --- a/tex/context/base/catc-ini.mkiv +++ b/tex/context/base/catc-ini.mkiv @@ -108,7 +108,7 @@ \expandafter\xdef\csname\??catcodetablen\number\c_syst_catcodes_n\endcsname{\string#1}% logging \newconstant#1% #1\c_syst_catcodes_n - \ctxlua{catcodes.register("\expandafter\gobbleoneargument\string#1",\number#1)}} + \ctxcommand{registercatcodetable("\expandafter\gobbleoneargument\string#1",\number#1)}} \newtoks \everysetdefaultcatcodes diff --git a/tex/context/base/catc-xml.mkiv b/tex/context/base/catc-xml.mkiv index 5e7df11f5..a23a2fe0a 100644 --- a/tex/context/base/catc-xml.mkiv +++ b/tex/context/base/catc-xml.mkiv @@ -114,20 +114,11 @@ %D We register the catcodetables at the \LUA\ end where some further %D initializations take place. -\ctxlua { - characters.define( - { % letter catcodes - \number\xmlcatcodesn, - \number\xmlcatcodese, - \number\xmlcatcodesr, - }, - { % activate catcodes - \number\xmlcatcodesn, - \number\xmlcatcodese, - \number\xmlcatcodesr, - } - ) - catcodes.register("xmlcatcodes",\number\xmlcatcodes) -} +\ctxcommand{definecatcodetable( + {\number\xmlcatcodesn,\number\xmlcatcodese,\number\xmlcatcodesr},% letter catcodes + {\number\xmlcatcodesn,\number\xmlcatcodese,\number\xmlcatcodesr} % activate catcodes +)} + +\ctxcommand{registercatcodetable("xmlcatcodes",\number\xmlcatcodes)} \endinput diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua index ac47760f3..d6e8d18a9 100644 --- a/tex/context/base/char-ini.lua +++ b/tex/context/base/char-ini.lua @@ -1214,3 +1214,6 @@ end -- entities.amp = utfchar(characters.activeoffset + utfbyte("&")) -- entities.gt = utfchar(characters.activeoffset + utfbyte(">")) -- end + +commands.definecatcodetable = characters.define +commands.setcharactercodes = characters.setcodes diff --git a/tex/context/base/char-ini.mkiv b/tex/context/base/char-ini.mkiv index 113d26709..db52ae723 100644 --- a/tex/context/base/char-ini.mkiv +++ b/tex/context/base/char-ini.mkiv @@ -65,32 +65,30 @@ % \def\setcclcuc#1#2#3{\global\catcode#1=\lettercatcode\global\lccode#1=#2\global\uccode#1=#3\relax} % \def\setcclcucself#1{\global\catcode#1=\lettercatcode\global\lccode#1=#1\global\uccode#1=#1\relax } -\ctxlua{characters.setcodes()} +\ctxcommand{setcharactercodes()} % Is setting up vrb tpa and tpb needed? -\ctxlua { - characters.define( - { % letter catcodes - \number\texcatcodes, - \number\ctxcatcodes, - \number\notcatcodes, - %number\mthcatcodes, - \number\vrbcatcodes, - \number\prtcatcodes, - \number\tpacatcodes, - \number\tpbcatcodes, - \number\txtcatcodes, - }, - { % activate catcodes - \number\ctxcatcodes, - \number\notcatcodes, - \number\prtcatcodes, % new - } - ) -% catcodes.register("xmlcatcodes",\number\xmlcatcodes) -} +\ctxcommand{definecatcodetable( + { % letter catcodes + \number\texcatcodes, + \number\ctxcatcodes, + \number\notcatcodes, + %number\mthcatcodes, + \number\vrbcatcodes, + \number\prtcatcodes, + \number\tpacatcodes, + \number\tpbcatcodes, + \number\txtcatcodes, + }, + { % activate catcodes + \number\ctxcatcodes, + \number\notcatcodes, + \number\prtcatcodes, % new + } +)} -\def\chardescription#1{\ctxcommand{chardescription(\number#1)}} +\def\chardescription#1% + {\ctxcommand{chardescription(\number#1)}} \protect \endinput diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua index b29db4090..0a0f71266 100644 --- a/tex/context/base/cldf-ini.lua +++ b/tex/context/base/cldf-ini.lua @@ -23,6 +23,11 @@ if not modules then modules = { } end modules ['cldf-ini'] = { -- todo: context("%bold{total: }%s",total) -- todo: context.documentvariable("title") +-- during the crited project we ran into the situation that luajittex was 10-20 times +-- slower that luatex ... after 3 days of testing and probing we finally figured out that +-- the the differences between the lua and luajit hashers can lead to quite a slowdown +-- in some cases. + local tex = tex context = context or { } @@ -37,7 +42,6 @@ local formatters = string.formatters -- using formatteds is slower in this case local loaddata = io.loaddata local texsprint = tex.sprint -local textprint = tex.tprint local texprint = tex.print local texwrite = tex.write local texgetcount = tex.getcount @@ -64,72 +68,239 @@ local report_cld = logs.reporter("cld","stack") local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end) --- for tracing it's easier to have two stacks +-- In earlier experiments a function tables was referred to as lua.calls and the +-- primitive \luafunctions was \luacall. -local _stack_f_, _n_f_ = { }, 0 -local _stack_n_, _n_n_ = { }, 0 +local luafunctions = lua.get_functions_table and lua.get_functions_table() +local usedstack = nil +local showstackusage = false -local function _store_f_(ti) - _n_f_ = _n_f_ + 1 - _stack_f_[_n_f_] = ti - return _n_f_ -end +-- luafunctions = false -local function _store_n_(ti) - _n_n_ = _n_n_ + 1 - _stack_n_[_n_n_] = ti - return _n_n_ -end +trackers.register("context.stack",function(v) showstackusage = v end) -local function _flush_f_(n) - local sn = _stack_f_[n] - if not sn then - report_cld("data with id %a cannot be found on stack",n) - else - local tn = type(sn) - if tn == "function" then - if not sn() and texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! - _stack_f_[n] = nil - else - -- keep, beware, that way the stack can grow - end +local storefunction, flushfunction +local storenode, flushnode +local registerfunction, unregisterfunction, reservefunction, knownfunctions, callfunctiononce + +if luafunctions then + + local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting + + usedstack = function() + return nofused, noffreed + end + + flushfunction = function(slot,arg) + if arg() then + -- keep + elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + noffreed = noffreed + 1 + freed[noffreed] = slot + luafunctions[slot] = false else - if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! - writenode(sn) - _stack_f_[n] = nil - else - writenode(copynodelist(sn)) - -- keep, beware, that way the stack can grow - end + -- keep end end -end -local function _flush_n_(n) - local sn = _stack_n_[n] - if not sn then - report_cld("data with id %a cannot be found on stack",n) - elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! - writenode(sn) - _stack_n_[n] = nil - else - writenode(copynodelist(sn)) - -- keep, beware, that way the stack can grow + storefunction = function(arg) + local f = function(slot) flushfunction(slot,arg) end + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + luafunctions[n] = f + return n + else + nofused = nofused + 1 + luafunctions[nofused] = f + return nofused + end + end + + flushnode = function(slot,arg) + if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + writenode(arg) + noffreed = noffreed + 1 + freed[noffreed] = slot + luafunctions[slot] = false + else + writenode(copynodelist(arg)) + end + end + + storenode = function(arg) + local f = function(slot) flushnode(slot,arg) end + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + luafunctions[n] = f + return n + else + nofused = nofused + 1 + luafunctions[nofused] = f + return nofused + end + end + + registerfunction = function(f) + if type(f) == "string" then + f = loadstring(f) + end + if type(f) ~= "function" then + f = function() report_cld("invalid function %A",f) end + end + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + luafunctions[n] = f + return n + else + nofused = nofused + 1 + luafunctions[nofused] = f + return nofused + end + end + + unregisterfunction = function(slot) + if luafunctions[slot] then + noffreed = noffreed + 1 + freed[noffreed] = slot + luafunctions[slot] = false + else + report_cld("invalid function slot %A",slot) + end + end + + reservefunction = function() + if noffreed > 0 then + local n = freed[noffreed] + freed[noffreed] = nil + noffreed = noffreed - 1 + return n + else + nofused = nofused + 1 + return nofused + end end -end -function context.restart() - _stack_f_, _n_f_ = { }, 0 - _stack_n_, _n_n_ = { }, 0 + callfunctiononce = function(slot) + luafunctions[slot](slot) + noffreed = noffreed + 1 + freed[noffreed] = slot + luafunctions[slot] = false + end + + table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end) + + knownfunctions = luafunctions + +else + + local luafunctions, noffunctions = { }, 0 + local luanodes, nofnodes = { }, 0 + + usedstack = function() + return noffunctions + nofnodes, 0 + end + + flushfunction = function(n) + local sn = luafunctions[n] + if not sn then + report_cld("data with id %a cannot be found on stack",n) + elseif not sn() and texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + luafunctions[n] = nil + end + end + + storefunction = function(ti) + noffunctions = noffunctions + 1 + luafunctions[noffunctions] = ti + return noffunctions + end + + -- freefunction = function(n) + -- luafunctions[n] = nil + -- end + + flushnode = function(n) + local sn = luanodes[n] + if not sn then + report_cld("data with id %a cannot be found on stack",n) + elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + writenode(sn) + luanodes[n] = nil + else + writenode(copynodelist(sn)) + end + end + + storenode = function(ti) + nofnodes = nofnodes + 1 + luanodes[nofnodes] = ti + return nofnodes + end + + _cldf_ = flushfunction -- global + _cldn_ = flushnode -- global + -- _cldl_ = function(n) return luafunctions[n]() end -- luafunctions(n) + _cldl_ = luafunctions + + registerfunction = function(f) + if type(f) == "string" then + f = loadstring(f) + end + if type(f) ~= "function" then + f = function() report_cld("invalid function %A",f) end + end + noffunctions = noffunctions + 1 + luafunctions[noffunctions] = f + return noffunctions + end + + unregisterfunction = function(slot) + if luafunctions[slot] then + luafunctions[slot] = nil + else + report_cld("invalid function slot %A",slot) + end + end + + reservefunction = function() + noffunctions = noffunctions + 1 + return noffunctions + end + + callfunctiononce = function(slot) + luafunctions[slot](slot) + luafunctions[slot] = nil + end + + table.setmetatablecall(luafunctions,function(t,n) return luafunctions[n](n) end) + + knownfunctions = luafunctions + end -context._stack_f_ = _stack_f_ -context._store_f_ = _store_f_ -context._flush_f_ = _flush_f_ _cldf_ = _flush_f_ +context.registerfunction = registerfunction +context.unregisterfunction = unregisterfunction +context.reservefunction = reservefunction +context.knownfunctions = knownfunctions +context.callfunctiononce = callfunctiononce _cldo_ = callfunctiononce +context.storenode = storenode -- private helper + +function commands.ctxfunction(code) + context(registerfunction(code)) +end -context._stack_n_ = _stack_n_ -context._store_n_ = _store_n_ -context._flush_n_ = _flush_n_ _cldn_ = _flush_n_ +-- local f_cldo = formatters["_cldo_(%i)"] +-- local latelua_node = nodes.pool.latelua +-- +-- function context.lateluafunctionnnode(f) +-- return latelua_node(f_cldo(registerfunction(f))) +-- end -- Should we keep the catcodes with the function? @@ -359,98 +530,210 @@ end local containseol = patterns.containseol -local function writer(parent,command,first,...) -- already optimized before call - local t = { first, ... } - flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes - local direct = false - for i=1,#t do - local ti = t[i] - local typ = type(ti) - if direct then - if typ == "string" or typ == "number" then - flush(currentcatcodes,ti) - else -- node.write - report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ) - end - direct = false - elseif ti == nil then - -- nothing - elseif ti == "" then - flush(currentcatcodes,"{}") - elseif typ == "string" then - -- is processelines seen ? - if processlines and lpegmatch(containseol,ti) then - flush(currentcatcodes,"{") - local flushlines = parent.__flushlines or flushlines - flushlines(ti) - flush(currentcatcodes,"}") - elseif currentcatcodes == contentcatcodes then +local writer + +if luafunctions then + + writer = function (parent,command,first,...) -- already optimized before call + local t = { first, ... } + flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes + local direct = false + for i=1,#t do + local ti = t[i] + local typ = type(ti) + if direct then + if typ == "string" or typ == "number" then + flush(currentcatcodes,ti) + else -- node.write + report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ) + end + direct = false + elseif ti == nil then + -- nothing + elseif ti == "" then + flush(currentcatcodes,"{}") + elseif typ == "string" then + -- is processelines seen ? + if processlines and lpegmatch(containseol,ti) then + flush(currentcatcodes,"{") + local flushlines = parent.__flushlines or flushlines + flushlines(ti) + flush(currentcatcodes,"}") + elseif currentcatcodes == contentcatcodes then + flush(currentcatcodes,"{",ti,"}") + else + flush(currentcatcodes,"{") + flush(contentcatcodes,ti) + flush(currentcatcodes,"}") + end + elseif typ == "number" then + -- numbers never have funny catcodes flush(currentcatcodes,"{",ti,"}") - else - flush(currentcatcodes,"{") - flush(contentcatcodes,ti) - flush(currentcatcodes,"}") - end - elseif typ == "number" then - -- numbers never have funny catcodes - flush(currentcatcodes,"{",ti,"}") - elseif typ == "table" then - local tn = #ti - if tn == 0 then - local done = false - for k, v in next, ti do - if done then - if v == "" then - flush(currentcatcodes,",",k,'=') + elseif typ == "table" then + local tn = #ti + if tn == 0 then + local done = false + for k, v in next, ti do + if done then + if v == "" then + flush(currentcatcodes,",",k,'=') + else + flush(currentcatcodes,",",k,"={",v,"}") + end else - flush(currentcatcodes,",",k,"={",v,"}") + if v == "" then + flush(currentcatcodes,"[",k,"=") + else + flush(currentcatcodes,"[",k,"={",v,"}") + end + done = true end + end + if done then + flush(currentcatcodes,"]") + else + flush(currentcatcodes,"[]") + end + elseif tn == 1 then -- some 20% faster than the next loop + local tj = ti[1] + if type(tj) == "function" then + flush(currentcatcodes,"[\\cldl",storefunction(tj),"]") else - if v == "" then - flush(currentcatcodes,"[",k,"=") + flush(currentcatcodes,"[",tj,"]") + end + else -- is concat really faster than flushes here? probably needed anyway (print artifacts) + flush(currentcatcodes,"[") + for j=1,tn do + local tj = ti[j] + if type(tj) == "function" then + if j == tn then + flush(currentcatcodes,"\\cldl",storefunction(tj),"]") + else + flush(currentcatcodes,"\\cldl",storefunction(tj),",") + end else - flush(currentcatcodes,"[",k,"={",v,"}") + if j == tn then + flush(currentcatcodes,tj,"]") + else + flush(currentcatcodes,tj,",") + end end - done = true end end - if done then - flush(currentcatcodes,"]") + elseif typ == "function" then + flush(currentcatcodes,"{\\cldl ",storefunction(ti),"}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if ti then + flushdirect(currentcatcodes,"\r") else - flush(currentcatcodes,"[]") + direct = true + end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(ti) then -- slow + flush(currentcatcodes,"{\\cldl",storenode(ti),"}") + else + report_context("error: %a gets a weird argument %a",command,ti) + end + end + end + +else + + writer = function (parent,command,first,...) -- already optimized before call + local t = { first, ... } + flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes + local direct = false + for i=1,#t do + local ti = t[i] + local typ = type(ti) + if direct then + if typ == "string" or typ == "number" then + flush(currentcatcodes,ti) + else -- node.write + report_context("error: invalid use of direct in %a, only strings and numbers can be flushed directly, not %a",command,typ) end - elseif tn == 1 then -- some 20% faster than the next loop - local tj = ti[1] - if type(tj) == "function" then - flush(currentcatcodes,"[\\cldf{",_store_f_(tj),"}]") + direct = false + elseif ti == nil then + -- nothing + elseif ti == "" then + flush(currentcatcodes,"{}") + elseif typ == "string" then + -- is processelines seen ? + if processlines and lpegmatch(containseol,ti) then + flush(currentcatcodes,"{") + local flushlines = parent.__flushlines or flushlines + flushlines(ti) + flush(currentcatcodes,"}") + elseif currentcatcodes == contentcatcodes then + flush(currentcatcodes,"{",ti,"}") else - flush(currentcatcodes,"[",tj,"]") + flush(currentcatcodes,"{") + flush(contentcatcodes,ti) + flush(currentcatcodes,"}") end - else -- is concat really faster than flushes here? probably needed anyway (print artifacts) - for j=1,tn do - local tj = ti[j] + elseif typ == "number" then + -- numbers never have funny catcodes + flush(currentcatcodes,"{",ti,"}") + elseif typ == "table" then + local tn = #ti + if tn == 0 then + local done = false + for k, v in next, ti do + if done then + if v == "" then + flush(currentcatcodes,",",k,'=') + else + flush(currentcatcodes,",",k,"={",v,"}") + end + else + if v == "" then + flush(currentcatcodes,"[",k,"=") + else + flush(currentcatcodes,"[",k,"={",v,"}") + end + done = true + end + end + if done then + flush(currentcatcodes,"]") + else + flush(currentcatcodes,"[]") + end + elseif tn == 1 then -- some 20% faster than the next loop + local tj = ti[1] if type(tj) == "function" then - ti[j] = "\\cldf{" .. _store_f_(tj) .. "}" + flush(currentcatcodes,"[\\cldf{",storefunction(tj),"}]") + else + flush(currentcatcodes,"[",tj,"]") + end + else -- is concat really faster than flushes here? probably needed anyway (print artifacts) + for j=1,tn do + local tj = ti[j] + if type(tj) == "function" then + ti[j] = "\\cldf{" .. storefunction(tj) .. "}" + end end + flush(currentcatcodes,"[",concat(ti,","),"]") end - flush(currentcatcodes,"[",concat(ti,","),"]") - end - elseif typ == "function" then - flush(currentcatcodes,"{\\cldf{",_store_f_(ti),"}}") -- todo: ctx|prt|texcatcodes - elseif typ == "boolean" then - if ti then - flushdirect(currentcatcodes,"\r") + elseif typ == "function" then + flush(currentcatcodes,"{\\cldf{",storefunction(ti),"}}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if ti then + flushdirect(currentcatcodes,"\r") + else + direct = true + end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(ti) then -- slow + flush(currentcatcodes,"{\\cldn{",storenode(ti),"}}") else - direct = true + report_context("error: %a gets a weird argument %a",command,ti) end - elseif typ == "thread" then - report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(ti) then -- slow - flush(currentcatcodes,"{\\cldn{",_store_n_(ti),"}}") - else - report_context("error: %a gets a weird argument %a",command,ti) end end + end local generics = { } context.generics = generics @@ -507,70 +790,154 @@ end function context.constructcsonly(k) -- not much faster than the next but more mem efficient local c = "\\" .. tostring(generics[k] or k) - rawset(context, k, function() + local v = function() flush(prtcatcodes,c) - end) + end + rawset(context,k,v) + return v end function context.constructcs(k) local c = "\\" .. tostring(generics[k] or k) - rawset(context, k, function(first,...) + local v = function(first,...) if first == nil then flush(prtcatcodes,c) else return writer(context,c,first,...) end - end) + end + rawset(context,k,v) + return v end -local function caller(parent,f,a,...) - if not parent then - -- so we don't need to test in the calling (slower but often no issue) - elseif f ~= nil then - local typ = type(f) - if typ == "string" then - if a then - flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes - elseif processlines and lpegmatch(containseol,f) then - local flushlines = parent.__flushlines or flushlines - flushlines(f) - else - flush(contentcatcodes,f) - end - elseif typ == "number" then - if a then - flush(currentcatcodes,f,a,...) +-- local splitformatters = utilities.strings.formatters.new(true) -- not faster (yet) + +local caller + +if luafunctions then + + caller = function(parent,f,a,...) + if not parent then + -- so we don't need to test in the calling (slower but often no issue) + elseif f ~= nil then + local typ = type(f) + if typ == "string" then + if f == "" then + -- new, can save a bit sometimes + -- if trace_context then + -- report_context("empty argument to context()") + -- end + elseif a then + flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes + -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes + elseif processlines and lpegmatch(containseol,f) then + local flushlines = parent.__flushlines or flushlines + flushlines(f) + else + flush(contentcatcodes,f) + end + elseif typ == "number" then + if a then + flush(currentcatcodes,f,a,...) + else + flush(currentcatcodes,f) + end + elseif typ == "function" then + -- ignored: a ... + flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if f then + if a ~= nil then + local flushlines = parent.__flushlines or flushlines + flushlines(a) + else + flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise + end + else + if a ~= nil then + -- no command, same as context(a,...) + writer(parent,"",a,...) + else + -- ignored + end + end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(f) then -- slow + -- writenode(f) + flush(currentcatcodes,"\\cldl",storenode(f)," ") else - flush(currentcatcodes,f) + report_context("error: %a gets a weird argument %a","context",f) end - elseif typ == "function" then - -- ignored: a ... - flush(currentcatcodes,"{\\cldf{",_store_f_(f),"}}") -- todo: ctx|prt|texcatcodes - elseif typ == "boolean" then - if f then - if a ~= nil then + end + end + + function context.flushnode(n) + flush(currentcatcodes,"\\cldl",storenode(n)," ") + end + +else + + caller = function(parent,f,a,...) + if not parent then + -- so we don't need to test in the calling (slower but often no issue) + elseif f ~= nil then + local typ = type(f) + if typ == "string" then + if f == "" then + -- new, can save a bit sometimes + -- if trace_context then + -- report_context("empty argument to context()") + -- end + elseif a then + flush(contentcatcodes,formatters[f](a,...)) -- was currentcatcodes + -- flush(contentcatcodes,splitformatters[f](a,...)) -- was currentcatcodes + elseif processlines and lpegmatch(containseol,f) then local flushlines = parent.__flushlines or flushlines - flushlines(a) + flushlines(f) else - flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise + flush(contentcatcodes,f) end - else - if a ~= nil then - -- no command, same as context(a,...) - writer(parent,"",a,...) + elseif typ == "number" then + if a then + flush(currentcatcodes,f,a,...) + else + flush(currentcatcodes,f) + end + elseif typ == "function" then + -- ignored: a ... + flush(currentcatcodes,"{\\cldf{",storefunction(f),"}}") -- todo: ctx|prt|texcatcodes + elseif typ == "boolean" then + if f then + if a ~= nil then + local flushlines = parent.__flushlines or flushlines + flushlines(a) + else + flushdirect(currentcatcodes,"\n") -- no \r, else issues with \startlines ... use context.par() otherwise + end else - -- ignored + if a ~= nil then + -- no command, same as context(a,...) + writer(parent,"",a,...) + else + -- ignored + end end + elseif typ == "thread" then + report_context("coroutines not supported as we cannot yield across boundaries") + elseif isnode(f) then -- slow + -- writenode(f) + flush(currentcatcodes,"\\cldn{",storenode(f),"}") + else + report_context("error: %a gets a weird argument %a","context",f) end - elseif typ == "thread" then - report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(f) then -- slow - -- writenode(f) - flush(currentcatcodes,"\\cldn{",_store_n_(f),"}") - else - report_context("error: %a gets a weird argument %a","context",f) end end + + function context.flushnode(n) + flush(currentcatcodes,"\\cldn{",storenode(n),"}") + end + end local defaultcaller = caller @@ -642,8 +1009,12 @@ local visualizer = lpeg.replacer { } statistics.register("traced context", function() + local used, freed = usedstack() + local unreachable = used - freed if nofwriters > 0 or nofflushes > 0 then - return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,_n_f_) + return format("writers: %s, flushes: %s, maxstack: %s",nofwriters,nofflushes,used,freed,unreachable) + elseif showstackusage or unreachable > 0 then + return format("maxstack: %s, freed: %s, unreachable: %s",used,freed,unreachable) end end) @@ -1019,7 +1390,8 @@ local function caller(parent,f,a,...) end elseif typ == "function" then -- ignored: a ... - flush(currentcatcodes,mpdrawing,"{\\cldf{",store_(f),"}}") +-- flush(currentcatcodes,mpdrawing,"{\\cldf{",store_(f),"}}") + flush(currentcatcodes,mpdrawing,"{\\cldl",store_(f),"}") elseif typ == "boolean" then -- ignored: a ... if f then diff --git a/tex/context/base/cldf-ini.mkiv b/tex/context/base/cldf-ini.mkiv index 258409d7a..12ada1383 100644 --- a/tex/context/base/cldf-ini.mkiv +++ b/tex/context/base/cldf-ini.mkiv @@ -36,6 +36,15 @@ \def\cldf#1{\directlua{_cldf_(#1)}} % global (functions) \def\cldn#1{\directlua{_cldn_(#1)}} % global (nodes) +\ifx\luafunction\undefined + \def\luafunction#1{\directlua{_cldl_(#1)}} +\fi + +\let\cldl\luafunction + +% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode1=\activecatcode \global\let^^A=\cldf +% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode2=\activecatcode \global\let^^B=\cldn + \normalprotected\def\cldprocessfile#1{\directlua{context.runfile("#1")}} \def\cldloadfile #1{\directlua{context.loadfile("#1")}} \def\cldcontext #1{\directlua{context(#1)}} diff --git a/tex/context/base/cldf-ver.lua b/tex/context/base/cldf-ver.lua index b48fd253a..66432eb1c 100644 --- a/tex/context/base/cldf-ver.lua +++ b/tex/context/base/cldf-ver.lua @@ -56,16 +56,18 @@ function context.tocontext(first,...) end end -function context.tobuffer(name,str) - context.startbuffer { name } - context.pushcatcodes("verbatim") - local lines = (type(str) == "string" and find(str,"[\n\r]") and splitlines(str)) or str - for i=1,#lines do - context(lines[i] .. " ") - end - context.stopbuffer() - context.popcatcodes() -end +-- function context.tobuffer(name,str) +-- context.startbuffer { name } +-- context.pushcatcodes("verbatim") +-- local lines = (type(str) == "string" and find(str,"[\n\r]") and splitlines(str)) or str +-- for i=1,#lines do +-- context(lines[i] .. " ") +-- end +-- context.stopbuffer() +-- context.popcatcodes() +-- end + +context.tobuffer = buffers.assign -- (name,str,catcodes) function context.tolines(str) local lines = type(str) == "string" and splitlines(str) or str diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index 535ee71b8..94e9e6615 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -65,24 +65,37 @@ function colors.setlist(name) return table.sortedkeys(name and name ~= "" and colorsets[name] or colorsets.default or {}) end +local context_colordefagc = context.colordefagc +local context_colordefagt = context.colordefagt +local context_colordefalc = context.colordefalc +local context_colordefalt = context.colordefalt +local context_colordeffgc = context.colordeffgc +local context_colordeffgt = context.colordeffgt +local context_colordefflc = context.colordefflc +local context_colordefflt = context.colordefflt +local context_colordefrgc = context.colordefrgc +local context_colordefrgt = context.colordefrgt +local context_colordefrlc = context.colordefrlc +local context_colordefrlt = context.colordefrlt + local function definecolor(name, ca, global) if ca and ca > 0 then if global then if trace_define then report_colors("define global color %a with attribute %a",name,ca) end - context.colordefagc(name,ca) + context_colordefagc(name,ca) else if trace_define then report_colors("define local color %a with attribute %a",name,ca) end - context.colordefalc(name,ca) + context_colordefalc(name,ca) end else if global then - context.colordefrgc(name) + context_colordefrgc(name) else - context.colordefrlc(name) + context_colordefrlc(name) end end colorset[name] = true-- maybe we can store more @@ -94,18 +107,18 @@ local function inheritcolor(name, ca, global) if trace_define then report_colors("inherit global color %a with attribute %a",name,ca) end - context.colordeffgc(name,ca) -- some day we will set the macro directly + context_colordeffgc(name,ca) -- some day we will set the macro directly else if trace_define then report_colors("inherit local color %a with attribute %a",name,ca) end - context.colordefflc(name,ca) + context_colordefflc(name,ca) end else if global then - context.colordefrgc(name) + context_colordefrgc(name) else - context.colordefrlc(name) + context_colordefrlc(name) end end colorset[name] = true-- maybe we can store more @@ -117,18 +130,18 @@ local function definetransparent(name, ta, global) if trace_define then report_colors("define global transparency %a with attribute %a",name,ta) end - context.colordefagt(name,ta) + context_colordefagt(name,ta) else if trace_define then report_colors("define local transparency %a with attribute %a",name,ta) end - context.colordefalt(name,ta) + context_colordefalt(name,ta) end else if global then - context.colordefrgt(name) + context_colordefrgt(name) else - context.colordefrlt(name) + context_colordefrlt(name) end end end @@ -139,18 +152,18 @@ local function inherittransparent(name, ta, global) if trace_define then report_colors("inherit global transparency %a with attribute %a",name,ta) end - context.colordeffgt(name,ta) + context_colordeffgt(name,ta) else if trace_define then report_colors("inherit local transparency %a with attribute %a",name,ta) end - context.colordefflt(name,ta) + context_colordefflt(name,ta) end else if global then - context.colordefrgt(name) + context_colordefrgt(name) else - context.colordefrlt(name) + context_colordefrlt(name) end end end @@ -382,7 +395,7 @@ function colors.isblack(ca) -- maybe commands end function colors.definespotcolor(name,parent,str,global) - if parent == "" or find(parent,"=") then + if parent == "" or find(parent,"=",1,true) then colors.registerspotcolor(name, parent) elseif name ~= parent then local cp = attributes_list[a_color][parent] diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 733afc6d0..d764ff352 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2014.02.14 17:07} +\newcontextversion{2014.03.22 15:31} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index 275625528..4263371c0 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 8c67fbd50..d5a722525 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -28,7 +28,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2014.02.14 17:07} +\edef\contextversion{2014.03.22 15:31} \edef\contextkind {beta} %D For those who want to use this: @@ -234,7 +234,7 @@ \loadmarkfile{strc-xml} \loadmarkfile{strc-def} % might happen later \loadmkvifile{strc-ref} -\loadmarkfile{strc-reg} +%loadmarkfile{strc-reg} \loadmkvifile{strc-lev} % experiment \loadmarkfile{spac-ali} @@ -296,6 +296,8 @@ \loadmarkfile{pack-pos} \loadmkvifile{page-mak} +\loadmarkfile{strc-reg} % uses mixed columns + \loadmarkfile{page-lin} \loadmarkfile{page-par} \loadmarkfile{typo-pag} diff --git a/tex/context/base/core-con.lua b/tex/context/base/core-con.lua index dad24a7d4..73ca3e304 100644 --- a/tex/context/base/core-con.lua +++ b/tex/context/base/core-con.lua @@ -14,14 +14,13 @@ slower but look nicer this way.

Some code may move to a module in the language namespace.

--ldx]]-- -local command, context = commands, context - local floor, date, time, concat = math.floor, os.date, os.time, table.concat local lower, rep, match = string.lower, string.rep, string.match local utfchar, utfbyte = utf.char, utf.byte local tonumber, tostring = tonumber, tostring local context = context +local commands = commands local settings_to_array = utilities.parsers.settings_to_array local allocate = utilities.storage.allocate @@ -37,9 +36,8 @@ local languages = languages converters.number = tonumber converters.numbers = tonumber -function commands.number(n) context(n) end - -commands.numbers = commands.number +commands.number = context +commands.numbers = context -- to be reconsidered ... languages namespace here, might become local plus a register command diff --git a/tex/context/base/core-env.mkiv b/tex/context/base/core-env.mkiv index 1c92a371c..c7e02444a 100644 --- a/tex/context/base/core-env.mkiv +++ b/tex/context/base/core-env.mkiv @@ -273,7 +273,7 @@ \unexpanded\def\startmodeset {\pushmacro\c_syst_modes_set_done \setfalse\conditionalfalse - \doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit} + \doifnextoptionalcselse\syst_modes_set_start\syst_modes_set_quit} \def\syst_modes_set_start[#1]% {\edef\m_mode_case{#1}% @@ -293,10 +293,10 @@ \def\syst_modes_set_yes#1% {\settrue\c_syst_modes_set_done #1% - \doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit} + \doifnextoptionalcselse\syst_modes_set_start\syst_modes_set_quit} \def\syst_modes_set_nop#1% - {\doifnextoptionalelse\syst_modes_set_start\syst_modes_set_quit} + {\doifnextoptionalcselse\syst_modes_set_start\syst_modes_set_quit} \def\syst_modes_set_quit#1\stopmodeset {\popmacro\c_syst_modes_set_done} @@ -316,7 +316,7 @@ \expanded % will become obsolete {\def\expandafter\noexpand\csname\e!start\v!setups\endcsname - {\begingroup\noexpand\doifnextoptionalelse + {\begingroup\noexpand\doifnextoptionalcselse {\noexpand\dostartsetupsA\expandafter\noexpand\csname\e!stop\v!setups\endcsname} {\noexpand\dostartsetupsB\expandafter\noexpand\csname\e!stop\v!setups\endcsname}}} @@ -467,11 +467,11 @@ % Is doglobal still relevant? Maybe always global? Or never? Anyway, it will become obsolete. -\unexpanded\def\startluasetups {\begingroup\doifnextoptionalelse\syst_setups_start_lua_a\syst_setups_start_lua_b} -\unexpanded\def\startxmlsetups {\begingroup\doifnextoptionalelse\syst_setups_start_xml_a\syst_setups_start_xml_b} -\unexpanded\def\startrawsetups {\begingroup\doifnextoptionalelse\syst_setups_start_raw_a\syst_setups_start_raw_b} -\unexpanded\def\startlocalsetups{\begingroup\doifnextoptionalelse\syst_setups_start_loc_a\syst_setups_start_loc_b} -\unexpanded\def\startsetups {\begingroup\doifnextoptionalelse\syst_setups_start_tex_a\syst_setups_start_tex_b} +\unexpanded\def\startluasetups {\begingroup\doifnextoptionalcselse\syst_setups_start_lua_a\syst_setups_start_lua_b} +\unexpanded\def\startxmlsetups {\begingroup\doifnextoptionalcselse\syst_setups_start_xml_a\syst_setups_start_xml_b} +\unexpanded\def\startrawsetups {\begingroup\doifnextoptionalcselse\syst_setups_start_raw_a\syst_setups_start_raw_b} +\unexpanded\def\startlocalsetups{\begingroup\doifnextoptionalcselse\syst_setups_start_loc_a\syst_setups_start_loc_b} +\unexpanded\def\startsetups {\begingroup\doifnextoptionalcselse\syst_setups_start_tex_a\syst_setups_start_tex_b} \let\stopluasetups \relax \let\stopxmlsetups \relax diff --git a/tex/context/base/core-uti.lua b/tex/context/base/core-uti.lua index 71b80170c..1903ad823 100644 --- a/tex/context/base/core-uti.lua +++ b/tex/context/base/core-uti.lua @@ -36,7 +36,7 @@ local report_passes = logs.reporter("job","passes") job = job or { } local job = job -job.version = 1.24 +job.version = 1.25 job.packversion = 1.02 -- some day we will implement loading of other jobs and then we need @@ -51,7 +51,13 @@ directly access the variable using a call.

local savelist, comment = { }, { } function job.comment(key,value) - comment[key] = value + if type(key) == "table" then + for k, v in next, key do + comment[k] = v + end + else + comment[key] = value + end end job.comment("version",job.version) @@ -73,8 +79,8 @@ function job.initialize(loadname,savename) end) end -function job.register(collected, tobesaved, initializer, finalizer) - savelist[#savelist+1] = { collected, tobesaved, initializer, finalizer } +function job.register(collected, tobesaved, initializer, finalizer, serializer) + savelist[#savelist+1] = { collected, tobesaved, initializer, finalizer, serializer } end -- as an example we implement variables @@ -100,7 +106,7 @@ job.register('job.variables.checksums', 'job.variables.checksums', initializer) local rmethod, rvalue -local setxvalue = context.setxvalue +local ctx_setxvalue = context.setxvalue local function initializer() tobesaved = jobvariables.tobesaved @@ -116,7 +122,7 @@ local function initializer() end tobesaved.randomseed = rvalue for cs, value in next, collected do - setxvalue(cs,value) + ctx_setxvalue(cs,value) end end @@ -175,10 +181,12 @@ function job.save(filename) -- we could return a table but it can get pretty lar f:write("local utilitydata = { }\n\n") f:write(serialize(comment,"utilitydata.comment",true),"\n\n") for l=1,#savelist do - local list = savelist[l] - local target = format("utilitydata.%s",list[1]) - local data = list[2] - local finalizer = list[4] + -- f:write("do\n\n") -- no solution for the jit limitatione either + local list = savelist[l] + local target = format("utilitydata.%s",list[1]) + local data = list[2] + local finalizer = list[4] + local serializer = list[5] if type(data) == "string" then data = utilities.tables.accesstable(data) end @@ -189,11 +197,18 @@ function job.save(filename) -- we could return a table but it can get pretty lar packers.pack(data,jobpacker,true) end local definer, name = definetable(target,true,true) -- no first and no last - f:write(definer,"\n\n",serialize(data,name,true),"\n\n") + if serializer then + f:write(definer,"\n\n",serializer(data,name,true),"\n\n") + else + f:write(definer,"\n\n",serialize(data,name,true),"\n\n") + end + -- f:write("end\n\n") end if job.pack then packers.strip(jobpacker) + -- f:write("do\n\n") f:write(serialize(jobpacker,"utilitydata.job.packed",true),"\n\n") + -- f:write("end\n\n") end f:write("return utilitydata") f:close() @@ -214,8 +229,9 @@ local function load(filename) return data end else - os.remove(filename) -- probably a bad file - report_passes("removing stale job data file %a, restart job",filename) + os.remove(filename) -- probably a bad file (or luajit overflow as it cannot handle large tables well) + report_passes("removing stale job data file %a, restart job, message: %s%s",filename,tostring(data), + jit and " (try luatex instead of luajittex)" or "") os.exit(true) -- trigger second run end end @@ -323,16 +339,19 @@ function statistics.formatruntime(runtime) if shipped > 0 or pages > 0 then local persecond = shipped / runtime if pages == 0 then pages = shipped end -if jit then -local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine -local saved = used_wood_factor * runtime --- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f kg tree saved by using luajittex",runtime,pages,shipped,persecond,saved) - return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000) -else - return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond) -end + -- if jit then + -- local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine + -- local saved = used_wood_factor * runtime + -- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000) + -- else + return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond) + -- end else return format("%s seconds",runtime) end end end + + +commands.savevariable = job.variables.save +commands.setjobcomment = job.comment diff --git a/tex/context/base/core-uti.mkiv b/tex/context/base/core-uti.mkiv index 527b90445..5937240b9 100644 --- a/tex/context/base/core-uti.mkiv +++ b/tex/context/base/core-uti.mkiv @@ -18,21 +18,19 @@ \registerctxluafile{core-uti}{1.001} \def\savecurrentvalue#1#2% immediate, so not \unexpanded - {\ctxlua{job.variables.save("\strippedcsname#1","#2")}} + {\ctxcommand{savevariable("\strippedcsname#1","#2")}} \appendtoks - \ctxlua { - % job.comment("file","\jobname") - job.comment("file",tex.jobname) - job.comment("format","\contextformat") - job.comment("stamp","\contextversion") - job.comment("escape","\!!bs\space...\space\!!es") - }% + \ctxlua{job.comment{ + file = tex.jobname, + format = "\contextformat", + stamp = "\contextversion", + escape = "\!!bs\space...\space\!!es" + }}% \to \everystarttext \appendtoks \ctxlua { - % job.initialize("\jobname.tuc","\jobname.tua") job.initialize(tex.jobname .. ".tuc",tex.jobname .. ".tua") }% \to \everyjob diff --git a/tex/context/base/data-exp.lua b/tex/context/base/data-exp.lua index c67e97bb1..9534e73a0 100644 --- a/tex/context/base/data-exp.lua +++ b/tex/context/base/data-exp.lua @@ -123,7 +123,7 @@ local function splitpathexpr(str, newlist, validate) -- I couldn't resist lpeggi local old = str str = lpegmatch(l_rest, str) until old == str - until old == str -- or not find(str,"{") + until old == str -- or not find(str,"{",1,true) str = lpegmatch(stripper_1,str) if validate then for s in gmatch(str,"[^,]+") do @@ -191,7 +191,7 @@ function resolvers.cleanpath(str) -- tricky, maybe only simple paths report_expansions("no home dir set, ignoring dependent paths") end function resolvers.cleanpath(str) - if not str or find(str,"~") then + if not str or find(str,"~",1,true) then return "" -- special case else return lpegmatch(cleanup,str) diff --git a/tex/context/base/data-ini.lua b/tex/context/base/data-ini.lua index 201c6a2d7..bbd233ae7 100644 --- a/tex/context/base/data-ini.lua +++ b/tex/context/base/data-ini.lua @@ -217,7 +217,7 @@ end environment.texroot = file.collapsepath(texroot) -if profiler then +if type(profiler) == "table" and not jit then directives.register("system.profile",function() profiler.start("luatex-profile.log") end) diff --git a/tex/context/base/data-met.lua b/tex/context/base/data-met.lua index ee9de3fd9..67b9eb22b 100644 --- a/tex/context/base/data-met.lua +++ b/tex/context/base/data-met.lua @@ -38,7 +38,7 @@ local function splitmethod(filename) -- todo: filetype in specification -- filename = gsub(filename,"^%./",getcurrentdir().."/") -- we will merge dir.expandname and collapse some day - if not find(filename,"://") then + if not find(filename,"://",1,true) then return { scheme = "file", path = filename, original = filename, filename = filename } end local specification = url.hashed(filename) diff --git a/tex/context/base/data-res.lua b/tex/context/base/data-res.lua index 64c38f82c..8e2a4978a 100644 --- a/tex/context/base/data-res.lua +++ b/tex/context/base/data-res.lua @@ -359,7 +359,7 @@ local function identify_configuration_files() -- todo: environment.skipweirdcnfpaths directive if trace_locating then local fullpath = gsub(resolvers.resolve(collapsepath(filepath)),"//","/") - local weirdpath = find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c") + local weirdpath = find(fullpath,"/texmf.+/texmf") or not find(fullpath,"/web2c",1,true) report_resolving("looking for %a on %s path %a from specification %a",luacnfname,weirdpath and "weird" or "given",fullpath,filepath) end if lfs.isfile(realname) then @@ -1027,7 +1027,7 @@ local function find_direct(filename,allresults) end local function find_wildcard(filename,allresults) - if find(filename,'%*') then + if find(filename,'*',1,true) then if trace_locating then report_resolving("checking wildcard %a", filename) end @@ -1204,7 +1204,7 @@ local function find_intree(filename,filetype,wantedfiles,allresults) local scheme = url.hasscheme(pathname) if not scheme or scheme == "file" then local pname = gsub(pathname,"%.%*$",'') - if not find(pname,"%*") then + if not find(pname,"*",1,true) then if can_be_dir(pname) then -- quick root scan first for k=1,#wantedfiles do @@ -1510,7 +1510,7 @@ local function findwildcardfiles(filename,allresults,result) -- todo: remap: and local path = lower(lpegmatch(makewildcard,dirn) or dirn) local name = lower(lpegmatch(makewildcard,base) or base) local files, done = instance.files, false - if find(name,"%*") then + if find(name,"*",1,true) then local hashes = instance.hashes for k=1,#hashes do local hash = hashes[k] diff --git a/tex/context/base/file-ini.lua b/tex/context/base/file-ini.lua index 2bc742a1f..3314bb33d 100644 --- a/tex/context/base/file-ini.lua +++ b/tex/context/base/file-ini.lua @@ -11,27 +11,29 @@ if not modules then modules = { } end modules ['file-ini'] = { . These methods have counterparts at the end.

--ldx]]-- -resolvers.jobs = resolvers.jobs or { } +resolvers.jobs = resolvers.jobs or { } -local texsetcount = tex.setcount -local setvalue = context.setvalue +local texsetcount = tex.setcount + +local context_setvalue = context.setvalue +local commands_doifelse = commands.doifelse function commands.splitfilename(fullname) local t = file.nametotable(fullname) local path = t.path texsetcount("splitoffkind",(path == "" and 0) or (path == '.' and 1) or 2) - setvalue("splitofffull",fullname) - setvalue("splitoffpath",path) - setvalue("splitoffname",t.name) - setvalue("splitoffbase",t.base) - setvalue("splitofftype",t.suffix) + context_setvalue("splitofffull",fullname) + context_setvalue("splitoffpath",path) + context_setvalue("splitoffname",t.name) + context_setvalue("splitoffbase",t.base) + context_setvalue("splitofftype",t.suffix) end function commands.doifparentfileelse(n) - commands.doifelse(n == environment.jobname or n == environment.jobname .. '.tex' or n == environment.outputfilename) + commands_doifelse(n == environment.jobname or n == environment.jobname .. '.tex' or n == environment.outputfilename) end function commands.doiffileexistelse(name) local foundname = resolvers.findtexfile(name) - commands.doifelse(foundname and foundname ~= "") + commands_doifelse(foundname and foundname ~= "") end diff --git a/tex/context/base/file-job.mkvi b/tex/context/base/file-job.mkvi index fa395a32e..5f646ed28 100644 --- a/tex/context/base/file-job.mkvi +++ b/tex/context/base/file-job.mkvi @@ -129,20 +129,20 @@ \unexpanded\def\processfileonce#name{\ctxcommand{processfileonce("#name")}} \unexpanded\def\processfilenone#name{\ctxcommand{processfilenone("#name")}} -\unexpanded\def\project {\doifnextoptionalelse\useproject \syst_structure_arg_project} -\unexpanded\def\product {\doifnextoptionalelse\useproduct \syst_structure_arg_product} -\unexpanded\def\component {\doifnextoptionalelse\usecomponent \syst_structure_arg_component} -\unexpanded\def\environment{\doifnextoptionalelse\useenvironment\syst_structure_arg_environment} +\unexpanded\def\project {\doifnextoptionalcselse\useproject \syst_structure_arg_project} +\unexpanded\def\product {\doifnextoptionalcselse\useproduct \syst_structure_arg_product} +\unexpanded\def\component {\doifnextoptionalcselse\usecomponent \syst_structure_arg_component} +\unexpanded\def\environment{\doifnextoptionalcselse\useenvironment\syst_structure_arg_environment} \def\syst_structure_arg_project #name {\ctxcommand{useproject ("#name")}} \def\syst_structure_arg_product #name {\ctxcommand{useproduct ("#name")}} \def\syst_structure_arg_component #name {\ctxcommand{usecomponent ("#name")}} \def\syst_structure_arg_environment#name {\ctxcommand{useenvironment("#name")}} -\unexpanded\def\startproject {\doifnextoptionalelse\syst_structure_start_opt_project \syst_structure_start_arg_project } -\unexpanded\def\startproduct {\doifnextoptionalelse\syst_structure_start_opt_product \syst_structure_start_arg_product } -\unexpanded\def\startcomponent {\doifnextoptionalelse\syst_structure_start_opt_component \syst_structure_start_arg_component } -\unexpanded\def\startenvironment{\doifnextoptionalelse\syst_structure_start_opt_environment\syst_structure_start_arg_environment} +\unexpanded\def\startproject {\doifnextoptionalcselse\syst_structure_start_opt_project \syst_structure_start_arg_project } +\unexpanded\def\startproduct {\doifnextoptionalcselse\syst_structure_start_opt_product \syst_structure_start_arg_product } +\unexpanded\def\startcomponent {\doifnextoptionalcselse\syst_structure_start_opt_component \syst_structure_start_arg_component } +\unexpanded\def\startenvironment{\doifnextoptionalcselse\syst_structure_start_opt_environment\syst_structure_start_arg_environment} \def\syst_structure_start_arg_project #name {\ctxcommand{startproject ("#name")}} \def\syst_structure_start_arg_product #name {\ctxcommand{startproduct ("#name")}} @@ -216,7 +216,7 @@ % {\letvalue{\e!stop\v!localenvironment}\relax} % {\grabuntil{\e!stop\v!localenvironment}\gobbleoneargument}} % -% \setvalue{\v!localenvironment}{\doifnextoptionalelse\uselocalenvironment\redolocalenvironment} +% \setvalue{\v!localenvironment}{\doifnextoptionalcselse\uselocalenvironment\redolocalenvironment} % % \def\redolocalenvironment#1 {\uselocalenvironment[#1]} % \def\uselocalenvironment[#1]{\doexecutefileonce{#1}} diff --git a/tex/context/base/file-mod.mkvi b/tex/context/base/file-mod.mkvi index 00966a442..1591a69cc 100644 --- a/tex/context/base/file-mod.mkvi +++ b/tex/context/base/file-mod.mkvi @@ -107,7 +107,7 @@ \newtoks\everysetupmodule \unexpanded\def\startmodule - {\doifnextoptionalelse\syst_modules_start_yes\syst_modules_start_nop} + {\doifnextoptionalcselse\syst_modules_start_yes\syst_modules_start_nop} \def\syst_modules_start_yes[#name]% {\pushmacro\currentmodule diff --git a/tex/context/base/file-res.lua b/tex/context/base/file-res.lua index 8a50c0d58..9ae7a6b06 100644 --- a/tex/context/base/file-res.lua +++ b/tex/context/base/file-res.lua @@ -136,7 +136,7 @@ function getreadfilename(scheme,path,name) -- better do a split and then pass ta if hasscheme(name) or is_qualified_path(name) then fullname = name else - if not find(name,"%%") then + if not find(name,"%",1,true) then name = urlescape(name) -- if no % in names end fullname = ((path == "") and format("%s:///%s",scheme,name)) or format("%s:///%s/%s",scheme,path,name) diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua index 5d4f6059b..178ca71be 100644 --- a/tex/context/base/font-chk.lua +++ b/tex/context/base/font-chk.lua @@ -159,7 +159,7 @@ local variants = { { tag = "yellow", r = .6, g = .6, b = 0 }, } -local pdf_blob = "pdf: q %0.6f 0 0 %0.6f 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q" +local pdf_blob = "pdf: q %0.6F 0 0 %0.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q" local cache = { } -- saves some tables but not that impressive diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua index e251cc9c1..13b1ac6a8 100644 --- a/tex/context/base/font-ctx.lua +++ b/tex/context/base/font-ctx.lua @@ -61,11 +61,12 @@ local nuts = nodes.nuts local tonut = nuts.tonut local getfield = nuts.getfield -local getattr = nuts.getattr -local getfont = nuts.getfont - local setfield = nuts.setfield +local getattr = nuts.getattr local setattr = nuts.setattr +local getprop = nuts.getprop +local setprop = nuts.setprop +local getfont = nuts.getfont local texgetattribute = tex.getattribute local texsetattribute = tex.setattribute @@ -137,8 +138,17 @@ function fonts.helpers.name(tfmdata) return file.basename(type(tfmdata) == "number" and properties[tfmdata].name or tfmdata.properties.name) end -utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = fonts.helpers.name }) -utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]], { sequenced = table.sequenced }) +if _LUAVERSION < 5.2 then + + utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name") + utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced") + +else + + utilities.strings.formatters.add(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = fonts.helpers.name }) + utilities.strings.formatters.add(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced }) + +end -- ... like font-sfm or so @@ -155,47 +165,49 @@ local hashes = { } function constructors.trytosharefont(target,tfmdata) constructors.noffontsloaded = constructors.noffontsloaded + 1 if constructors.sharefonts then - local properties = target.properties - local fullname = target.fullname local fonthash = target.specification.hash - local sharedname = hashes[fonthash] - if sharedname then - -- this is ok for context as we know that only features can mess with font definitions - -- so a similar hash means that the fonts are similar too - if trace_defining then - report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash") - end - target.fullname = sharedname - properties.sharedwith = sharedname - constructors.nofsharedfonts = constructors.nofsharedfonts + 1 - constructors.nofsharedhashes = constructors.nofsharedhashes + 1 - else - -- the one takes more time (in the worst case of many cjk fonts) but it also saves - -- embedding time - local characters = target.characters - local n = 1 - local t = { target.psname } - local u = sortedkeys(characters) - for i=1,#u do - n = n + 1 ; t[n] = k - n = n + 1 ; t[n] = characters[u[i]].index or k - end - local checksum = md5.HEX(concat(t," ")) - local sharedname = shares[checksum] + if fonthash then + local properties = target.properties local fullname = target.fullname + local sharedname = hashes[fonthash] if sharedname then + -- this is ok for context as we know that only features can mess with font definitions + -- so a similar hash means that the fonts are similar too if trace_defining then - report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector") + report_defining("font %a uses backend resources of font %a (%s)",target.fullname,sharedname,"common hash") end - fullname = sharedname - properties.sharedwith= sharedname + target.fullname = sharedname + properties.sharedwith = sharedname constructors.nofsharedfonts = constructors.nofsharedfonts + 1 - constructors.nofsharedvectors = constructors.nofsharedvectors + 1 + constructors.nofsharedhashes = constructors.nofsharedhashes + 1 else - shares[checksum] = fullname + -- the one takes more time (in the worst case of many cjk fonts) but it also saves + -- embedding time + local characters = target.characters + local n = 1 + local t = { target.psname } + local u = sortedkeys(characters) + for i=1,#u do + n = n + 1 ; t[n] = k + n = n + 1 ; t[n] = characters[u[i]].index or k + end + local checksum = md5.HEX(concat(t," ")) + local sharedname = shares[checksum] + local fullname = target.fullname + if sharedname then + if trace_defining then + report_defining("font %a uses backend resources of font %a (%s)",fullname,sharedname,"common vector") + end + fullname = sharedname + properties.sharedwith= sharedname + constructors.nofsharedfonts = constructors.nofsharedfonts + 1 + constructors.nofsharedvectors = constructors.nofsharedvectors + 1 + else + shares[checksum] = fullname + end + target.fullname = fullname + hashes[fonthash] = fullname end - target.fullname = fullname - hashes[fonthash] = fullname end end end @@ -493,7 +505,7 @@ local function definecontext(name,t) -- can be shared end local function presetcontext(name,parent,features) -- will go to con and shared - if features == "" and find(parent,"=") then + if features == "" and find(parent,"=",1,true) then features = parent parent = "" end @@ -810,7 +822,7 @@ local function splitcontext(features) -- presetcontext creates dummy here local sf = setups[features] if not sf then local n -- number - if find(features,",") then + if find(features,",",a,true) then -- let's assume a combination which is not yet defined but just specified (as in math) n, sf = presetcontext(features,features,"") else @@ -827,13 +839,13 @@ end -- local setup = setups[features] -- if setup then -- return setup --- elseif find(features,",") then +-- elseif find(features,",",1,true) then -- -- This is not that efficient but handy anyway for quick and dirty tests -- -- beware, due to the way of caching setups you can get the wrong results -- -- when components change. A safeguard is to nil the cache. -- local merge = nil -- for feature in gmatch(features,"[^, ]+") do --- if find(feature,"=") then +-- if find(feature,"=",1,true) then -- local k, v = lpegmatch(splitter,feature) -- if k and v then -- if not merge then @@ -941,319 +953,327 @@ local getspecification = definers.getspecification -- we can make helper macros which saves parsing (but normaly not -- that many calls, e.g. in mk a couple of 100 and in metafun 3500) -local setdefaultfontname = context.fntsetdefname -local setsomefontname = context.fntsetsomename -local setemptyfontsize = context.fntsetnopsize -local setsomefontsize = context.fntsetsomesize -local letvaluerelax = context.letvaluerelax - -function commands.definefont_one(str) - statistics.starttiming(fonts) - if trace_defining then - report_defining("memory usage before: %s",statistics.memused()) - report_defining("start stage one: %s",str) - end - local fullname, size = lpegmatch(splitpattern,str) - local lookup, name, sub, method, detail = getspecification(fullname) - if not name then - report_defining("strange definition %a",str) - setdefaultfontname() - elseif name == "unknown" then - setdefaultfontname() - else - setsomefontname(name) - end - -- we can also use a count for the size - if size and size ~= "" then - local mode, size = lpegmatch(sizepattern,size) - if size and mode then - texsetcount("scaledfontmode",mode) - setsomefontsize(size) +do -- else too many locals + + local ctx_setdefaultfontname = context.fntsetdefname + local ctx_setsomefontname = context.fntsetsomename + local ctx_setemptyfontsize = context.fntsetnopsize + local ctx_setsomefontsize = context.fntsetsomesize + local ctx_letvaluerelax = context.letvaluerelax + + function commands.definefont_one(str) + statistics.starttiming(fonts) + if trace_defining then + report_defining("memory usage before: %s",statistics.memused()) + report_defining("start stage one: %s",str) + end + local fullname, size = lpegmatch(splitpattern,str) + local lookup, name, sub, method, detail = getspecification(fullname) + if not name then + report_defining("strange definition %a",str) + ctx_setdefaultfontname() + elseif name == "unknown" then + ctx_setdefaultfontname() + else + ctx_setsomefontname(name) + end + -- we can also use a count for the size + if size and size ~= "" then + local mode, size = lpegmatch(sizepattern,size) + if size and mode then + texsetcount("scaledfontmode",mode) + ctx_setsomefontsize(size) + else + texsetcount("scaledfontmode",0) + ctx_setemptyfontsize() + end + elseif true then + -- so we don't need to check in tex + texsetcount("scaledfontmode",2) + ctx_setemptyfontsize() else texsetcount("scaledfontmode",0) - setemptyfontsize() + ctx_setemptyfontsize() + end + specification = definers.makespecification(str,lookup,name,sub,method,detail,size) + if trace_defining then + report_defining("stop stage one") end - elseif true then - -- so we don't need to check in tex - texsetcount("scaledfontmode",2) - setemptyfontsize() - else - texsetcount("scaledfontmode",0) - setemptyfontsize() - end - specification = definers.makespecification(str,lookup,name,sub,method,detail,size) - if trace_defining then - report_defining("stop stage one") end -end -local n = 0 - --- we can also move rscale to here (more consistent) --- the argument list will become a table + local n = 0 -local function nice_cs(cs) - return (gsub(cs,".->", "")) -end + -- we can also move rscale to here (more consistent) + -- the argument list will become a table -function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks, - mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode) - if trace_defining then - report_defining("start stage two: %s (size %s)",str,size) - end - -- name is now resolved and size is scaled cf sa/mo - local lookup, name, sub, method, detail = getspecification(str or "") - -- new (todo: inheritancemode) - local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or "" - local designname = designsizefilename(name,designsize,size) - if designname and designname ~= "" then - if trace_defining or trace_designsize then - report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname) - end - -- we don't catch detail here - local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname) - if o_lookup and o_lookup ~= "" then lookup = o_lookup end - if o_method and o_method ~= "" then method = o_method end - if o_detail and o_detail ~= "" then detail = o_detail end - name = o_name - sub = o_sub - end - -- so far - -- some settings can have been overloaded - if lookup and lookup ~= "" then - specification.lookup = lookup - end - if relativeid and relativeid ~= "" then -- experimental hook - local id = tonumber(relativeid) or 0 - specification.relativeid = id > 0 and id + local function nice_cs(cs) + return (gsub(cs,".->", "")) end - -- - specification.name = name - specification.size = size - specification.sub = (sub and sub ~= "" and sub) or specification.sub - specification.mathsize = mathsize - specification.textsize = textsize - specification.goodies = goodies - specification.cs = cs - specification.global = global - specification.scalemode = scaledfontmode -- context specific - if detail and detail ~= "" then - specification.method = method or "*" - specification.detail = detail - elseif specification.detail and specification.detail ~= "" then - -- already set - elseif inheritancemode == 0 then - -- nothing - elseif inheritancemode == 1 then - -- fontonly - if fontfeatures and fontfeatures ~= "" then - specification.method = "*" - specification.detail = fontfeatures - end - if fontfallbacks and fontfallbacks ~= "" then - specification.fallbacks = fontfallbacks - end - elseif inheritancemode == 2 then - -- classonly - if classfeatures and classfeatures ~= "" then - specification.method = "*" - specification.detail = classfeatures - end - if classfallbacks and classfallbacks ~= "" then - specification.fallbacks = classfallbacks - end - elseif inheritancemode == 3 then - -- fontfirst - if fontfeatures and fontfeatures ~= "" then - specification.method = "*" - specification.detail = fontfeatures - elseif classfeatures and classfeatures ~= "" then - specification.method = "*" - specification.detail = classfeatures - end - if fontfallbacks and fontfallbacks ~= "" then - specification.fallbacks = fontfallbacks - elseif classfallbacks and classfallbacks ~= "" then - specification.fallbacks = classfallbacks - end - elseif inheritancemode == 4 then - -- classfirst - if classfeatures and classfeatures ~= "" then - specification.method = "*" - specification.detail = classfeatures - elseif fontfeatures and fontfeatures ~= "" then - specification.method = "*" - specification.detail = fontfeatures - end - if classfallbacks and classfallbacks ~= "" then - specification.fallbacks = classfallbacks - elseif fontfallbacks and fontfallbacks ~= "" then - specification.fallbacks = fontfallbacks - end - end - local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?) - -- - local lastfontid = 0 - if not tfmdata then - report_defining("unable to define %a as %a",name,nice_cs(cs)) - lastfontid = -1 - letvaluerelax(cs) -- otherwise the current definition takes the previous one - elseif type(tfmdata) == "number" then + + function commands.definefont_two(global,cs,str,size,inheritancemode,classfeatures,fontfeatures,classfallbacks,fontfallbacks, + mathsize,textsize,relativeid,classgoodies,goodies,classdesignsize,fontdesignsize,scaledfontmode) if trace_defining then - report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a", - name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize) + report_defining("start stage two: %s (size %s)",str,size) end - csnames[tfmdata] = specification.cs - texdefinefont(global,cs,tfmdata) - -- resolved (when designsize is used): - local size = fontdata[tfmdata].parameters.size or 0 - setsomefontsize(size .. "sp") - texsetcount("scaledfontsize",size) - lastfontid = tfmdata - else - -- setting the extra characters will move elsewhere - local characters = tfmdata.characters - local parameters = tfmdata.parameters - -- we use char0 as signal; cf the spec pdf can handle this (no char in slot) - characters[0] = nil - -- characters[0x00A0] = { width = parameters.space } - -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure - -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period - -- - constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference - local id = font.define(tfmdata) - csnames[id] = specification.cs - tfmdata.properties.id = id - definers.register(tfmdata,id) -- to be sure, normally already done - texdefinefont(global,cs,id) - constructors.cleanuptable(tfmdata) - constructors.finalize(tfmdata) - if trace_defining then - report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a", - name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks) + -- name is now resolved and size is scaled cf sa/mo + local lookup, name, sub, method, detail = getspecification(str or "") + -- new (todo: inheritancemode) + local designsize = fontdesignsize ~= "" and fontdesignsize or classdesignsize or "" + local designname = designsizefilename(name,designsize,size) + if designname and designname ~= "" then + if trace_defining or trace_designsize then + report_defining("remapping name %a, specification %a, size %a, designsize %a",name,designsize,size,designname) + end + -- we don't catch detail here + local o_lookup, o_name, o_sub, o_method, o_detail = getspecification(designname) + if o_lookup and o_lookup ~= "" then lookup = o_lookup end + if o_method and o_method ~= "" then method = o_method end + if o_detail and o_detail ~= "" then detail = o_detail end + name = o_name + sub = o_sub end - -- resolved (when designsize is used): - local size = tfmdata.parameters.size or 655360 - setsomefontsize(size .. "sp") - texsetcount("scaledfontsize",size) - lastfontid = id - end - if trace_defining then - report_defining("memory usage after: %s",statistics.memused()) - report_defining("stop stage two") - end - -- - texsetcount("global","lastfontid",lastfontid) - if not mathsize then - -- forget about it - elseif mathsize == 0 then - lastmathids[1] = lastfontid - else - lastmathids[mathsize] = lastfontid - end - -- - statistics.stoptiming(fonts) -end - -function definers.define(specification) - -- - local name = specification.name - if not name or name == "" then - return -1 - else - statistics.starttiming(fonts) - -- - -- following calls expect a few properties to be set: - -- - local lookup, name, sub, method, detail = getspecification(name or "") - -- - specification.name = (name ~= "" and name) or specification.name - -- - specification.lookup = specification.lookup or (lookup ~= "" and lookup) or "file" - specification.size = specification.size or 655260 - specification.sub = specification.sub or (sub ~= "" and sub) or "" - specification.method = specification.method or (method ~= "" and method) or "*" - specification.detail = specification.detail or (detail ~= "" and detail) or "" - -- - if type(specification.size) == "string" then - specification.size = texsp(specification.size) or 655260 + -- so far + -- some settings can have been overloaded + if lookup and lookup ~= "" then + specification.lookup = lookup + end + if relativeid and relativeid ~= "" then -- experimental hook + local id = tonumber(relativeid) or 0 + specification.relativeid = id > 0 and id end -- - specification.specification = "" -- not used - specification.resolved = "" - specification.forced = "" - specification.features = { } -- via detail, maybe some day - -- - -- we don't care about mathsize textsize goodies fallbacks - -- - local cs = specification.cs - if cs == "" then - cs = nil - specification.cs = nil - specification.global = false - elseif specification.global == nil then - specification.global = false + specification.name = name + specification.size = size + specification.sub = (sub and sub ~= "" and sub) or specification.sub + specification.mathsize = mathsize + specification.textsize = textsize + specification.goodies = goodies + specification.cs = cs + specification.global = global + specification.scalemode = scaledfontmode -- context specific + if detail and detail ~= "" then + specification.method = method or "*" + specification.detail = detail + elseif specification.detail and specification.detail ~= "" then + -- already set + elseif inheritancemode == 0 then + -- nothing + elseif inheritancemode == 1 then + -- fontonly + if fontfeatures and fontfeatures ~= "" then + specification.method = "*" + specification.detail = fontfeatures + end + if fontfallbacks and fontfallbacks ~= "" then + specification.fallbacks = fontfallbacks + end + elseif inheritancemode == 2 then + -- classonly + if classfeatures and classfeatures ~= "" then + specification.method = "*" + specification.detail = classfeatures + end + if classfallbacks and classfallbacks ~= "" then + specification.fallbacks = classfallbacks + end + elseif inheritancemode == 3 then + -- fontfirst + if fontfeatures and fontfeatures ~= "" then + specification.method = "*" + specification.detail = fontfeatures + elseif classfeatures and classfeatures ~= "" then + specification.method = "*" + specification.detail = classfeatures + end + if fontfallbacks and fontfallbacks ~= "" then + specification.fallbacks = fontfallbacks + elseif classfallbacks and classfallbacks ~= "" then + specification.fallbacks = classfallbacks + end + elseif inheritancemode == 4 then + -- classfirst + if classfeatures and classfeatures ~= "" then + specification.method = "*" + specification.detail = classfeatures + elseif fontfeatures and fontfeatures ~= "" then + specification.method = "*" + specification.detail = fontfeatures + end + if classfallbacks and classfallbacks ~= "" then + specification.fallbacks = classfallbacks + elseif fontfallbacks and fontfallbacks ~= "" then + specification.fallbacks = fontfallbacks + end end + local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?) -- - local tfmdata = definers.read(specification,specification.size) + local lastfontid = 0 if not tfmdata then - return -1, nil + report_defining("unable to define %a as %a",name,nice_cs(cs)) + lastfontid = -1 + ctx_letvaluerelax(cs) -- otherwise the current definition takes the previous one elseif type(tfmdata) == "number" then - if cs then - texdefinefont(specification.global,cs,tfmdata) - csnames[tfmdata] = cs + if trace_defining then + report_defining("reusing %s, id %a, target %a, features %a / %a, fallbacks %a / %a, goodies %a / %a, designsize %a / %a", + name,tfmdata,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,classgoodies,goodies,classdesignsize,fontdesignsize) end - return tfmdata, fontdata[tfmdata] + csnames[tfmdata] = specification.cs + texdefinefont(global,cs,tfmdata) + -- resolved (when designsize is used): + local size = fontdata[tfmdata].parameters.size or 0 + ctx_setsomefontsize(size .. "sp") + texsetcount("scaledfontsize",size) + lastfontid = tfmdata else + -- setting the extra characters will move elsewhere + local characters = tfmdata.characters + local parameters = tfmdata.parameters + -- we use char0 as signal; cf the spec pdf can handle this (no char in slot) + characters[0] = nil + -- characters[0x00A0] = { width = parameters.space } + -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure + -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period + -- constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference local id = font.define(tfmdata) + csnames[id] = specification.cs tfmdata.properties.id = id - definers.register(tfmdata,id) - if cs then - texdefinefont(specification.global,cs,id) - csnames[id] = cs - end + definers.register(tfmdata,id) -- to be sure, normally already done + texdefinefont(global,cs,id) constructors.cleanuptable(tfmdata) constructors.finalize(tfmdata) - return id, tfmdata + if trace_defining then + report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a", + name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks) + end + -- resolved (when designsize is used): + local size = tfmdata.parameters.size or 655360 + ctx_setsomefontsize(size .. "sp") + texsetcount("scaledfontsize",size) + lastfontid = id + end + if trace_defining then + report_defining("memory usage after: %s",statistics.memused()) + report_defining("stop stage two") end + -- + texsetcount("global","lastfontid",lastfontid) + if not mathsize then + -- forget about it + elseif mathsize == 0 then + lastmathids[1] = lastfontid + else + lastmathids[mathsize] = lastfontid + end + -- statistics.stoptiming(fonts) end + + function definers.define(specification) + -- + local name = specification.name + if not name or name == "" then + return -1 + else + statistics.starttiming(fonts) + -- + -- following calls expect a few properties to be set: + -- + local lookup, name, sub, method, detail = getspecification(name or "") + -- + specification.name = (name ~= "" and name) or specification.name + -- + specification.lookup = specification.lookup or (lookup ~= "" and lookup) or "file" + specification.size = specification.size or 655260 + specification.sub = specification.sub or (sub ~= "" and sub) or "" + specification.method = specification.method or (method ~= "" and method) or "*" + specification.detail = specification.detail or (detail ~= "" and detail) or "" + -- + if type(specification.size) == "string" then + specification.size = texsp(specification.size) or 655260 + end + -- + specification.specification = "" -- not used + specification.resolved = "" + specification.forced = "" + specification.features = { } -- via detail, maybe some day + -- + -- we don't care about mathsize textsize goodies fallbacks + -- + local cs = specification.cs + if cs == "" then + cs = nil + specification.cs = nil + specification.global = false + elseif specification.global == nil then + specification.global = false + end + -- + local tfmdata = definers.read(specification,specification.size) + if not tfmdata then + return -1, nil + elseif type(tfmdata) == "number" then + if cs then + texdefinefont(specification.global,cs,tfmdata) + csnames[tfmdata] = cs + end + return tfmdata, fontdata[tfmdata] + else + constructors.checkvirtualids(tfmdata) -- experiment, will become obsolete when slots can selfreference + local id = font.define(tfmdata) + tfmdata.properties.id = id + definers.register(tfmdata,id) + if cs then + texdefinefont(specification.global,cs,id) + csnames[id] = cs + end + constructors.cleanuptable(tfmdata) + constructors.finalize(tfmdata) + return id, tfmdata + end + statistics.stoptiming(fonts) + end + end + end -- local id, cs = fonts.definers.internal { } -- local id, cs = fonts.definers.internal { number = 2 } -- local id, cs = fonts.definers.internal { name = "dejavusans" } -local n = 0 - -function definers.internal(specification,cs) - specification = specification or { } - local name = specification.name - local size = specification.size and number.todimen(specification.size) or texgetdimen("bodyfontsize") - local number = tonumber(specification.number) - local id = nil - if number then - id = number - elseif name and name ~= "" then - local cs = cs or specification.cs - if not cs then - n = n + 1 -- beware ... there can be many and they are often used once - -- cs = formatters["internal font %s"](n) - cs = "internal font " .. n - else - specification.cs = cs +do + + local n = 0 + + function definers.internal(specification,cs) + specification = specification or { } + local name = specification.name + local size = specification.size and number.todimen(specification.size) or texgetdimen("bodyfontsize") + local number = tonumber(specification.number) + local id = nil + if number then + id = number + elseif name and name ~= "" then + local cs = cs or specification.cs + if not cs then + n = n + 1 -- beware ... there can be many and they are often used once + -- cs = formatters["internal font %s"](n) + cs = "internal font " .. n + else + specification.cs = cs + end + id = definers.define { + name = name, + size = size, + cs = cs, + } end - id = definers.define { - name = name, - size = size, - cs = cs, - } - end - if not id then - id = currentfont() + if not id then + id = currentfont() + end + return id, csnames[id] end - return id, csnames[id] + end local enable_auto_r_scale = false @@ -1519,6 +1539,11 @@ local Shapes = { mono = "Mono", } +local ctx_startfontclass = context.startfontclass +local ctx_stopfontclass = context.stopfontclass +local ctx_definefontsynonym = context.definefontsynonym +local ctx_dofastdefinetypeface = context.dofastdefinetypeface + function fonts.definetypeface(name,t) if type(name) == "table" then -- {name=abc,k=v,...} @@ -1546,14 +1571,14 @@ function fonts.definetypeface(name,t) local normalwidth = t.normalwidth or t.width or p.normalwidth or p.width or "normal" local boldwidth = t.boldwidth or t.width or p.boldwidth or p.width or "normal" Shape = Shapes[shape] or "Serif" - context.startfontclass { name } - context.definefontsynonym( { format("%s", Shape) }, { format("spec:%s-%s-regular-%s", fontname, normalweight, normalwidth) } ) - context.definefontsynonym( { format("%sBold", Shape) }, { format("spec:%s-%s-regular-%s", fontname, boldweight, boldwidth ) } ) - context.definefontsynonym( { format("%sBoldItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, boldweight, boldwidth ) } ) - context.definefontsynonym( { format("%sItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, normalweight, normalwidth) } ) - context.stopfontclass() + ctx_startfontclass { name } + ctx_definefontsynonym( { format("%s", Shape) }, { format("spec:%s-%s-regular-%s", fontname, normalweight, normalwidth) } ) + ctx_definefontsynonym( { format("%sBold", Shape) }, { format("spec:%s-%s-regular-%s", fontname, boldweight, boldwidth ) } ) + ctx_definefontsynonym( { format("%sBoldItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, boldweight, boldwidth ) } ) + ctx_definefontsynonym( { format("%sItalic", Shape) }, { format("spec:%s-%s-italic-%s", fontname, normalweight, normalwidth) } ) + ctx_stopfontclass() local settings = sequenced({ features= t.features },",") - context.dofastdefinetypeface(name, shortcut, shape, size, settings) + ctx_dofastdefinetypeface(name, shortcut, shape, size, settings) end function fonts.current() -- todo: also handle name @@ -1566,10 +1591,15 @@ end -- interfaces +local context_char = context.char +local context_getvalue = context.getvalue + +local commands_doifelse = commands.doifelse + function commands.fontchar(n) n = nametoslot(n) if n then - context.char(n) + context_char(n) end end @@ -1579,7 +1609,7 @@ function commands.doifelsecurrentfonthasfeature(name) -- can be made faster with f = f and f.rawdata f = f and f.resources f = f and f.features - commands.doifelse(f and (f.gpos[name] or f.gsub[name])) + commands_doifelse(f and (f.gpos[name] or f.gsub[name])) end local p, f = 1, formatters["%0.1fpt"] -- normally this value is changed only once @@ -1751,14 +1781,15 @@ end -- redefinition -local quads = hashes.quads -local xheights = hashes.xheights +-- local hashes = fonts.hashes +-- local emwidths = hashes.emwidths +-- local exheights = hashes.exheights setmetatableindex(dimenfactors, function(t,k) if k == "ex" then - return 1/xheights[currentfont()] + return 1/exheights[currentfont()] elseif k == "em" then - return 1/quads[currentfont()] + return 1/emwidths[currentfont()] elseif k == "pct" or k == "%" then return 1/(texget("hsize")/100) else @@ -1835,7 +1866,7 @@ end -- end function commands.setfontofid(id) - context.getvalue(csnames[id]) + context_getvalue(csnames[id]) end -- more interfacing: @@ -1911,7 +1942,6 @@ end -- a fontkern plug: - local copy_node = nuts.copy local kern = nuts.pool.register(nuts.pool.kern()) @@ -1967,7 +1997,7 @@ local function markstates(head) head = tonut(head) local model = getattr(head,a_colormodel) or 1 for glyph in traverse_by_id(glyph_code,head) do - local a = getattr(glyph,a_state) + local a = getprop(glyph,a_state) if a then local name = names[a] if name then @@ -2023,3 +2053,12 @@ function methods.nocolor(head,font,attr) end return head, true end + +function commands.purefontname(name) + if type(name) == "number" then + name = fonts.helpers.name(name) + end + if type(name) == "string" then + context(file.basename(name)) + end +end diff --git a/tex/context/base/font-fea.mkvi b/tex/context/base/font-fea.mkvi index 8d985b411..35a9a642a 100644 --- a/tex/context/base/font-fea.mkvi +++ b/tex/context/base/font-fea.mkvi @@ -143,11 +143,11 @@ % hashing at this end is slower -\unexpanded\def\addfeature {\doifnextoptionalelse\font_feature_add_yes \font_feature_add_nop } -\unexpanded\def\subtractfeature {\doifnextoptionalelse\font_feature_subtract_yes \font_feature_subtract_nop } -\unexpanded\def\replacefeature {\doifnextoptionalelse\font_feature_replace_yes \font_feature_replace_nop } -\unexpanded\def\resetandaddfeature{\doifnextoptionalelse\font_feature_reset_add_yes\font_feature_reset_add_nop} -\unexpanded\def\feature {\doifnextoptionalelse\font_feature_yes \font_feature_nop } +\unexpanded\def\addfeature {\doifnextoptionalcselse\font_feature_add_yes \font_feature_add_nop } +\unexpanded\def\subtractfeature {\doifnextoptionalcselse\font_feature_subtract_yes \font_feature_subtract_nop } +\unexpanded\def\replacefeature {\doifnextoptionalcselse\font_feature_replace_yes \font_feature_replace_nop } +\unexpanded\def\resetandaddfeature{\doifnextoptionalcselse\font_feature_reset_add_yes\font_feature_reset_add_nop} +\unexpanded\def\feature {\doifnextoptionalcselse\font_feature_yes \font_feature_nop } \unexpanded\def\font_feature_add_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_add} \unexpanded\def\font_feature_add_nop #feature{\edef\m_font_feature_asked{#feature}\font_feature_add} diff --git a/tex/context/base/font-fil.mkvi b/tex/context/base/font-fil.mkvi index dcb298619..158bcda71 100644 --- a/tex/context/base/font-fil.mkvi +++ b/tex/context/base/font-fil.mkvi @@ -89,11 +89,11 @@ \def\font_basics_define_font_synonym_nop {\expandafter\let\csname\??fontfile\m_font_name\endcsname\m_font_file - \doifnextoptionalelse\font_basics_define_font_synonym_nop_opt\font_basics_define_font_synonym_nop_nil} + \doifnextoptionalcselse\font_basics_define_font_synonym_nop_opt\font_basics_define_font_synonym_nop_nil} \def\font_basics_define_font_synonym_yes {\expandafter\let\csname\??fontfile\fontclass\m_font_name\endcsname\m_font_file - \doifnextoptionalelse\font_basics_define_font_synonym_yes_opt\font_basics_define_font_synonym_yes_nil} + \doifnextoptionalcselse\font_basics_define_font_synonym_yes_opt\font_basics_define_font_synonym_yes_nil} \def\font_basics_define_font_synonym_nop_opt[#specification]% {\let\p_features \undefined diff --git a/tex/context/base/font-gds.lua b/tex/context/base/font-gds.lua index e57f784a0..9e7cb841e 100644 --- a/tex/context/base/font-gds.lua +++ b/tex/context/base/font-gds.lua @@ -278,7 +278,7 @@ local function setcolorscheme(tfmdata,scheme) end elseif type(name) == "number" then reverse[name] = i - elseif find(name,":") then + elseif find(name,":",1,true) then local start, stop = splitup(name,":") start = tonumber(start) stop = tonumber(stop) diff --git a/tex/context/base/font-ini.mkvi b/tex/context/base/font-ini.mkvi index 521901e05..cc850b9af 100644 --- a/tex/context/base/font-ini.mkvi +++ b/tex/context/base/font-ini.mkvi @@ -363,7 +363,7 @@ \let\thedefinedfont\relax % not to be confused with \everydefinefont \unexpanded\def\definedfont - {\doifnextoptionalelse\font_basics_defined_font_yes\font_basics_defined_font_nop} + {\doifnextoptionalcselse\font_basics_defined_font_yes\font_basics_defined_font_nop} \def\font_basics_defined_font_yes[#specification]% {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly @@ -2082,7 +2082,7 @@ % \newtoks \everyswitchtobodyfont \unexpanded\def\setupbodyfont - {\doifnextoptionalelse\font_basics_setupbodyfont_yes\font_basics_setupbodyfont_nop} + {\doifnextoptionalcselse\font_basics_setupbodyfont_yes\font_basics_setupbodyfont_nop} \def\font_basics_setupbodyfont_nop {\restoreglobalbodyfont @@ -2175,7 +2175,8 @@ %D The next auxilliary macro is an alternative to \type %D {\fontname}. -\def\purefontname#font{\ctxlua{file.basename("\fontname#font"}} % will be function using id +\def\purefontname#font{\ctxcommand{purefontname("\fontname#font")}} +%def\purefontname#font{\ctxcommand{purefontname(\number\fontid#font)}} %D \macros %D {switchstyleonly} @@ -2190,7 +2191,7 @@ %D \stoptyping \unexpanded\def\switchstyleonly - {\doifnextoptionalelse\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg} + {\doifnextoptionalcselse\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg} \def\font_basics_switch_style_only_arg#name% stupid version {\font_helpers_set_current_font_style{\csname\??fontshortstyle\checkedstrippedcsname#name\endcsname}% @@ -2348,6 +2349,83 @@ \def\saveddefinedfontid {\number\fontid\font} \def\saveddefinedfontname{\fontname\font} +% yes or no: +% \let\font_basics_check_text_bodyfont_slow\font_basics_check_text_bodyfont +% +% \unexpanded\def\font_basics_check_text_bodyfont +% {\ifproductionrun +% % not per se \s!..'s +% \glet\font_basics_check_text_bodyfont \font_basics_check_text_bodyfont_slow +% \glet\font_basics_check_text_bodyfont_fast\relax +% \expandafter\font_basics_check_text_bodyfont +% \else +% \expandafter\font_basics_check_text_bodyfont_fast +% \fi} +% +% \def\font_basics_check_text_bodyfont_fast#style#alternative#size% size can be empty (checking needed as \bf is already defined) +% {\setugvalue{#style#size}% \rma +% {\let\fontstyle#style% +% \let\fontsize #size% +% \font_helpers_check_big_math_synchronization % double? better in everymath? +% \font_helpers_synchronize_font}% +% \setugvalue{#alternative#size}% \sla +% {\let\fontalternative#alternative% +% \let\fontsize #size% +% \font_helpers_check_big_math_synchronization % double? better in everymath? +% \font_helpers_synchronize_font}% +% \setugvalue{#style#alternative#size}% \rmsla +% {\let\fontstyle #style% +% \let\fontalternative#alternative% +% \let\fontsize #size% +% \font_helpers_check_big_math_synchronization % double? better in everymath? +% \font_helpers_synchronize_font}% +% \ifcsname\s!normal#style\endcsname % text/math check +% \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname +% \else +% \setugvalue{#style}% \rm +% {\let\fontstyle#style% +% \font_typescripts_inherit_check\fontstyle +% \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet +% \font_helpers_synchronize_font}% +% \fi +% \ifcsname\s!normal#alternative\endcsname % text/math check +% \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname +% \else +% \setugvalue{#alternative}% \sl +% {\let\fontalternative#alternative% +% \font_helpers_synchronize_font}% +% \fi +% \setugvalue{#style\s!x}% \rmx +% {\csname#style\endcsname\tx}% +% \setugvalue{#style\s!xx}% \rmxx +% {\csname#style\endcsname\txx}% +% \setugvalue{#alternative\s!x}% \slx +% {\font_helpers_check_nested_x_fontsize +% \ifmmode +% \scriptstyle +% \else +% \let\fontface4% +% \let\fontalternative#alternative% +% \font_helpers_synchronize_font +% \fi +% \currentxfontsize\plusone +% \let\tx\txx}% +% \setugvalue{#alternative\s!xx}% \slxx +% {\font_helpers_check_nested_x_fontsize +% \ifmmode +% \scriptscriptstyle +% \else +% \let\fontface5% +% \let\fontalternative#alternative% +% \font_helpers_synchronize_font +% \fi +% \currentxfontsize\plustwo +% \let\tx\empty +% \let\txx\empty}% +% \setugvalue{#style#alternative}% \rmsl +% {\let\fontstyle #style% +% \let\fontalternative#alternative% +% \font_helpers_synchronize_font}} \protect \endinput diff --git a/tex/context/base/font-lib.mkvi b/tex/context/base/font-lib.mkvi index a664d9b3a..92db44722 100644 --- a/tex/context/base/font-lib.mkvi +++ b/tex/context/base/font-lib.mkvi @@ -38,7 +38,15 @@ \registerctxluafile{font-ott}{1.001} % otf tables (first) \registerctxluafile{font-otf}{1.001} % otf main \registerctxluafile{font-otb}{1.001} % otf main base -\registerctxluafile{node-inj}{1.001} % we might split it off + +\ctxcommand{doifelse(nodes.properties)} { + \doiffileelse{font-inj.lua} + {\registerctxluafile{font-inj}{1.001}} + {\registerctxluafile{node-inj}{1.001}} +} { + \registerctxluafile{node-inj}{1.001} +} + %registerctxluafile{font-ota}{1.001} % otf analyzers \registerctxluafile{font-otx}{1.001} % otf analyzers \registerctxluafile{font-otn}{1.001} % otf main node diff --git a/tex/context/base/font-mis.lua b/tex/context/base/font-mis.lua index 63cae37f3..7385d6f31 100644 --- a/tex/context/base/font-mis.lua +++ b/tex/context/base/font-mis.lua @@ -22,7 +22,7 @@ local handlers = fonts.handlers handlers.otf = handlers.otf or { } local otf = handlers.otf -otf.version = otf.version or 2.751 +otf.version = otf.version or 2.755 otf.cache = otf.cache or containers.define("fonts", "otf", otf.version, true) function otf.loadcached(filename,format,sub) diff --git a/tex/context/base/font-odv.lua b/tex/context/base/font-odv.lua index d07c38d9a..079027ffe 100644 --- a/tex/context/base/font-odv.lua +++ b/tex/context/base/font-odv.lua @@ -118,8 +118,8 @@ local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getfield = nuts.getfield local setfield = nuts.setfield -local getattr = nuts.getattr -local setattr = nuts.setattr +local getprop = nuts.getprop +local setprop = nuts.setprop local insert_node_after = nuts.insert_after local copy_node = nuts.copy @@ -649,7 +649,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) current = start else current = getnext(n) - setattr(start,a_state,s_rphf) + setprop(start,a_state,s_rphf) end end @@ -682,9 +682,9 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) local nextcurrent = copy_node(current) setfield(tempcurrent,"next",nextcurrent) setfield(nextcurrent,"prev",tempcurrent) - setattr(tempcurrent,a_state,s_blwf) + setprop(tempcurrent,a_state,s_blwf) tempcurrent = processcharacters(tempcurrent,font) - setattr(tempcurrent,a_state,unsetvalue) + setprop(tempcurrent,a_state,unsetvalue) if getchar(next) == getchar(tempcurrent) then flush_list(tempcurrent) local n = copy_node(current) @@ -713,7 +713,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) while not basefound do -- find base consonant if consonant[getchar(current)] then - setattr(current,a_state,s_half) + setprop(current,a_state,s_half) if not firstcons then firstcons = current end @@ -722,7 +722,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) base = current elseif blwfcache[getchar(current)] then -- consonant has below-base (or post-base) form - setattr(current,a_state,s_blwf) + setprop(current,a_state,s_blwf) else base = current end @@ -802,15 +802,15 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) while current ~= stop do local next = getnext(current) if next ~= stop and halant[getchar(next)] and getchar(getnext(next)) == c_zwnj then - setattr(current,a_state,unsetvalue) + setprop(current,a_state,unsetvalue) end current = next end - if base ~= stop and getattr(base,a_state) then + if base ~= stop and getprop(base,a_state) then local next = getnext(base) if halant[getchar(next)] and not (next ~= stop and getchar(getnext(next)) == c_zwj) then - setattr(base,a_state,unsetvalue) + setprop(base,a_state,unsetvalue) end end @@ -906,7 +906,7 @@ local function deva_reorder(head,start,stop,font,attr,nbspaces) end bn = next end - if getattr(current,a_state) == s_rphf then + if getprop(current,a_state) == s_rphf then -- position Reph (Ra + H) after post-base 'matra' (if any) since these -- become marks on the 'matra', not on the base glyph if b ~= current then @@ -998,12 +998,12 @@ end function handlers.devanagari_reorder_matras(head,start,kind,lookupname,replacement) -- no leak local current = start -- we could cache attributes here local startfont = getfont(start) - local startattr = getattr(start,a_syllabe) + local startattr = getprop(start,a_syllabe) -- can be fast loop - while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and getattr(current,a_syllabe) == startattr do + while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and getprop(current,a_syllabe) == startattr do local next = getnext(current) - if halant[getchar(current)] and not getattr(current,a_state) then - if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getattr(next,a_syllabe) == startattr and zw_char[getchar(next)] then + if halant[getchar(current)] and not getprop(current,a_state) then + if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getprop(next,a_syllabe) == startattr and zw_char[getchar(next)] then current = next end local startnext = getnext(start) @@ -1054,11 +1054,11 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement local startnext = nil local startprev = nil local startfont = getfont(start) - local startattr = getattr(start,a_syllabe) - while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do --step 2 - if halant[getchar(current)] and not getattr(current,a_state) then + local startattr = getprop(start,a_syllabe) + while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do --step 2 + if halant[getchar(current)] and not getprop(current,a_state) then local next = getnext(current) - if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getattr(next,a_syllabe) == startattr and zw_char[getchar(next)] then + if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getprop(next,a_syllabe) == startattr and zw_char[getchar(next)] then current = next end startnext = getnext(start) @@ -1071,15 +1071,15 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement setfield(current,"next",start) setfield(start,"prev",current) start = startnext - startattr = getattr(start,a_syllabe) + startattr = getprop(start,a_syllabe) break end current = getnext(current) end if not startnext then current = getnext(start) - while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do --step 4 - if getattr(current,a_state) == s_pstf then --post-base + while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do --step 4 + if getprop(current,a_state) == s_pstf then --post-base startnext = getnext(start) head = remove_node(head,start) local prev = getprev(current) @@ -1088,7 +1088,7 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement setfield(start,"next",current) setfield(current,"prev",start) start = startnext - startattr = getattr(start,a_syllabe) + startattr = getprop(start,a_syllabe) break end current = getnext(current) @@ -1100,7 +1100,7 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement if not startnext then current = getnext(start) local c = nil - while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do --step 5 + while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do --step 5 if not c then local char = getchar(current) -- todo: combine in one @@ -1121,14 +1121,14 @@ function handlers.devanagari_reorder_reph(head,start,kind,lookupname,replacement setfield(c,"prev",start) -- end start = startnext - startattr = getattr(start,a_syllabe) + startattr = getprop(start,a_syllabe) end end -- leaks if not startnext then current = start local next = getnext(current) - while next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getattr(next,a_syllabe) == startattr do --step 6 + while next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == startfont and getprop(next,a_syllabe) == startattr do --step 6 current = next next = getnext(current) end @@ -1165,12 +1165,12 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start,k local startnext = nil local startprev = nil local startfont = getfont(start) - local startattr = getattr(start,a_syllabe) + local startattr = getprop(start,a_syllabe) -- can be fast for loop + caching state - while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do + while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do local next = getnext(current) - if halant[getchar(current)] and not getattr(current,a_state) then - if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getattr(next,a_syllabe) == startattr then + if halant[getchar(current)] and not getprop(current,a_state) then + if next and getid(next) == glyph_code and getsubtype(next) < 256 and getfont(next) == font and getprop(next,a_syllabe) == startattr then local char = getchar(next) if char == c_zwnj or char == c_zwj then current = next @@ -1192,9 +1192,9 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start,k end if not startnext then current = getnext(start) - startattr = getattr(start,a_syllabe) - while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getattr(current,a_syllabe) == startattr do - if not consonant[getchar(current)] and getattr(current,a_state) then --main + startattr = getprop(start,a_syllabe) + while current and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == startfont and getprop(current,a_syllabe) == startattr do + if not consonant[getchar(current)] and getprop(current,a_state) then --main startnext = getnext(start) removenode(start,start) local prev = getprev(current) @@ -1377,7 +1377,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa current = next current = getnext(current) elseif current == start then - setattr(current,a_state,s_rphf) + setprop(current,a_state,s_rphf) current = next else current = next @@ -1418,8 +1418,8 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local next = getnext(current) local n = locl[next] or getchar(next) if found[n] then - setattr(current,a_state,s_pref) - setattr(next,a_state,s_pref) + setprop(current,a_state,s_pref) + setprop(next,a_state,s_pref) current = next end end @@ -1440,7 +1440,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa if next ~= stop and getchar(getnext(next)) == c_zwnj then -- zwnj prevent creation of half current = next else - setattr(current,a_state,s_half) + setprop(current,a_state,s_half) if not halfpos then halfpos = current end @@ -1462,8 +1462,8 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local next = getnext(current) local n = locl[next] or getchar(next) if found[n] then - setattr(current,a_state,s_blwf) - setattr(next,a_state,s_blwf) + setprop(current,a_state,s_blwf) + setprop(next,a_state,s_blwf) current = next subpos = current end @@ -1482,8 +1482,8 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local next = getnext(current) local n = locl[next] or getchar(next) if found[n] then - setattr(current,a_state,s_pstf) - setattr(next,a_state,s_pstf) + setprop(current,a_state,s_pstf) + setprop(next,a_state,s_pstf) current = next postpos = current end @@ -1501,7 +1501,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local current, base, firstcons = start, nil, nil - if getattr(start,a_state) == s_rphf then + if getprop(start,a_state) == s_rphf then -- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants current = getnext(getnext(start)) end @@ -1532,13 +1532,13 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa local tmp = getnext(next) local changestop = next == stop setfield(next,"next",nil) - setattr(current,a_state,s_pref) + setprop(current,a_state,s_pref) current = processcharacters(current,font) - setattr(current,a_state,s_blwf) + setprop(current,a_state,s_blwf) current = processcharacters(current,font) - setattr(current,a_state,s_pstf) + setprop(current,a_state,s_pstf) current = processcharacters(current,font) - setattr(current,a_state,unsetvalue) + setprop(current,a_state,unsetvalue) if halant[getchar(current)] then setfield(getnext(current),"next",tmp) local nc = copy_node(current) @@ -1572,7 +1572,7 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa firstcons = current end -- check whether consonant has below-base or post-base form or is pre-base reordering Ra - local a = getattr(current,a_state) + local a = getprop(current,a_state) if not (a == s_pref or a == s_blwf or a == s_pstf) then base = current end @@ -1586,13 +1586,13 @@ local function dev2_reorder(head,start,stop,font,attr,nbspaces) -- maybe do a pa end if not base then - if getattr(start,a_state) == s_rphf then - setattr(start,a_state,unsetvalue) + if getprop(start,a_state) == s_rphf then + setprop(start,a_state,unsetvalue) end return head, stop, nbspaces else - if getattr(base,a_state) then - setattr(base,a_state,unsetvalue) + if getprop(base,a_state) then + setprop(base,a_state,unsetvalue) end basepos = base end @@ -2319,14 +2319,14 @@ function methods.dev2(head,font,attr) local c = syllablestart local n = getnext(syllableend) while c ~= n do - setattr(c,a_syllabe,syllabe) + setprop(c,a_syllabe,syllabe) c = getnext(c) end end if syllableend and syllablestart ~= syllableend then head, current, nbspaces = dev2_reorder(head,syllablestart,syllableend,font,attr,nbspaces) end - if not syllableend and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and not getattr(current,a_state) then + if not syllableend and getid(current) == glyph_code and getsubtype(current) < 256 and getfont(current) == font and not getprop(current,a_state) then local mark = mark_four[getchar(current)] if mark then head, current = inject_syntax_error(head,current,mark) diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua index 9af5a3347..8d60ddc0e 100644 --- a/tex/context/base/font-ota.lua +++ b/tex/context/base/font-ota.lua @@ -8,6 +8,9 @@ if not modules then modules = { } end modules ['font-ota'] = { -- this might become scrp-*.lua +-- [attr] : getprop or getattr +-- [attr] : setprop or setattr + local type = type if not trackers then trackers = { register = function() end } end diff --git a/tex/context/base/font-otb.lua b/tex/context/base/font-otb.lua index 2a7b821ea..946d552e4 100644 --- a/tex/context/base/font-otb.lua +++ b/tex/context/base/font-otb.lua @@ -594,8 +594,9 @@ basemethod = "independent" local function featuresinitializer(tfmdata,value) if true then -- value then - local t = trace_preparing and os.clock() - local features = tfmdata.shared.features + local starttime = trace_preparing and os.clock() + local features = tfmdata.shared.features + local fullname = trace_preparing and tfmdata.properties.fullname if features then applybasemethod("initializehashes",tfmdata) local collectlookups = otf.collectlookups @@ -605,34 +606,70 @@ local function featuresinitializer(tfmdata,value) local language = properties.language local basesubstitutions = rawdata.resources.features.gsub local basepositionings = rawdata.resources.features.gpos - if basesubstitutions then - for feature, data in next, basesubstitutions do - local value = features[feature] - if value then - local validlookups, lookuplist = collectlookups(rawdata,feature,script,language) - if validlookups then - applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - end - end - end - end - if basepositionings then - for feature, data in next, basepositionings do - local value = features[feature] - if value then - local validlookups, lookuplist = collectlookups(rawdata,feature,script,language) - if validlookups then - applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) - registerbasefeature(feature,value) + -- + -- if basesubstitutions then + -- for feature, data in next, basesubstitutions do + -- local value = features[feature] + -- if value then + -- local validlookups, lookuplist = collectlookups(rawdata,feature,script,language) + -- if validlookups then + -- applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) + -- registerbasefeature(feature,value) + -- end + -- end + -- end + -- end + -- if basepositionings then + -- for feature, data in next, basepositionings do + -- local value = features[feature] + -- if value then + -- local validlookups, lookuplist = collectlookups(rawdata,feature,script,language) + -- if validlookups then + -- applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) + -- registerbasefeature(feature,value) + -- end + -- end + -- end + -- end + -- + if basesubstitutions or basepositionings then + local sequences = tfmdata.resources.sequences + for s=1,#sequences do + local sequence = sequences[s] + local sfeatures = sequence.features + if sfeatures then + local order = sequence.order + if order then + for i=1,#order do -- + local feature = order[i] + if features[feature] then + local validlookups, lookuplist = collectlookups(rawdata,feature,script,language) + if not validlookups then + -- skip + elseif basesubstitutions and basesubstitutions[feature] then + if trace_preparing then + report_prepare("filtering base feature %a for %a",feature,fullname) + end + applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + elseif basepositionings and basepositionings[feature] then + if trace_preparing then + report_prepare("filtering base feature %a for %a",feature,fullname) + end + applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) + registerbasefeature(feature,value) + end + end + end end end end end + -- registerbasehash(tfmdata) end if trace_preparing then - report_prepare("preparation time is %0.3f seconds for %a",os.clock()-t,tfmdata.properties.fullname) + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) end end end diff --git a/tex/context/base/font-otc.lua b/tex/context/base/font-otc.lua index 3006e47ca..92775270d 100644 --- a/tex/context/base/font-otc.lua +++ b/tex/context/base/font-otc.lua @@ -70,6 +70,7 @@ local function addfeature(data,feature,specifications) local subtables = specification.subtables or { specification.data } or { } local featuretype = types[specification.type or "substitution"] local featureflags = specification.flags or noflags + local featureorder = specification.order or { feature } local added = false local featurename = format("ctx_%s_%s",feature,s) local st = { } @@ -138,6 +139,7 @@ local function addfeature(data,feature,specifications) features = { [feature] = askedfeatures }, flags = featureflags, name = featurename, + order = featureorder, subtables = st, type = featuretype, } @@ -204,6 +206,7 @@ local tlig_specification = { type = "ligature", features = everywhere, data = tlig, + order = { "tlig" }, flags = noflags, } @@ -226,6 +229,7 @@ local trep_specification = { type = "substitution", features = everywhere, data = trep, + order = { "trep" }, flags = noflags, } @@ -256,6 +260,7 @@ if characters.combined then type = "ligature", features = everywhere, data = tcom, + order = { "tcom" }, flags = noflags, initialize = initialize, } @@ -314,6 +319,7 @@ local anum_specification = { { type = "substitution", features = { arab = { urd = true, dflt = true } }, + order = { "anum" }, data = anum_arabic, flags = noflags, -- { }, valid = valid, @@ -321,6 +327,7 @@ local anum_specification = { { type = "substitution", features = { arab = { urd = true } }, + order = { "anum" }, data = anum_persian, flags = noflags, -- { }, valid = valid, diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua index 919da2379..e421111dd 100644 --- a/tex/context/base/font-otd.lua +++ b/tex/context/base/font-otd.lua @@ -129,10 +129,13 @@ local default = "dflt" -- what about analyze in local and not in font -local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic) +local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic,ra) local features = sequence.features if features then - for kind, scripts in next, features do + local order = sequence.order or { } + -- for kind, scripts in next, features do + for i=1,#order do -- + local kind = order[i] -- local e_e local a_e = a_enabled and a_enabled[kind] -- the value (location) if a_e ~= nil then @@ -141,6 +144,7 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr e_e = s_enabled and s_enabled[kind] -- the value (font) end if e_e then + local scripts = features[kind] -- local languages = scripts[script] or scripts[wildcard] if languages then -- local valid, what = false @@ -174,14 +178,14 @@ local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a", font,attr or 0,dynamic,kind,script,language,sequence.name,valid) end - return { valid, attribute, sequence.chain or 0, kind, sequence } + ra[#ra+1] = { valid, attribute, sequence.chain or 0, kind, sequence } end end end end - return false -- { valid, attribute, chain, "generic", sequence } -- false anyway, could be flag instead of table + -- { valid, attribute, chain, "generic", sequence } -- false anyway, could be flag instead of table else - return false -- { false, false, chain, false, sequence } -- indirect lookup, part of chain (todo: make this a separate table) + -- { false, false, chain, false, sequence } -- indirect lookup, part of chain (todo: make this a separate table) end end @@ -249,12 +253,16 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia -- return v -- end -- end) +-- for s=1,#sequences do +-- local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic) +-- if v then +-- ra[#ra+1] = v +-- end +-- end for s=1,#sequences do - local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic) - if v then - ra[#ra+1] = v - end + initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic,ra) end +-- table.save((jit and "tmc-" or "tma-")..font..".log",ra) -- bug in jit end return ra diff --git a/tex/context/base/font-otf.lua b/tex/context/base/font-otf.lua index eb28bc368..0a5d1cfea 100644 --- a/tex/context/base/font-otf.lua +++ b/tex/context/base/font-otf.lua @@ -48,7 +48,7 @@ local otf = fonts.handlers.otf otf.glists = { "gsub", "gpos" } -otf.version = 2.751 -- beware: also sync font-mis.lua +otf.version = 2.755 -- beware: also sync font-mis.lua otf.cache = containers.define("fonts", "otf", otf.version, true) local fontdata = fonts.hashes.identifiers @@ -687,15 +687,22 @@ actions["prepare glyphs"] = function(data,filename,raw) local glyph = cidglyphs[index] if glyph then local unicode = glyph.unicode +if unicode >= 0x00E000 and unicode <= 0x00F8FF then + unicode = -1 +elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFD then + unicode = -1 +elseif unicode >= 0x100000 and unicode <= 0x10FFFD then + unicode = -1 +end local name = glyph.name or cidnames[index] - if not unicode or unicode == -1 or unicode >= criterium then + if not unicode or unicode == -1 then -- or unicode >= criterium then unicode = cidunicodes[index] end if unicode and descriptions[unicode] then report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) unicode = -1 end - if not unicode or unicode == -1 or unicode >= criterium then + if not unicode or unicode == -1 then -- or unicode >= criterium then if not name then name = format("u%06X",private) end @@ -747,7 +754,7 @@ actions["prepare glyphs"] = function(data,filename,raw) if glyph then local unicode = glyph.unicode local name = glyph.name - if not unicode or unicode == -1 or unicode >= criterium then + if not unicode or unicode == -1 then -- or unicode >= criterium then unicode = private unicodes[name] = private if trace_private then @@ -809,6 +816,10 @@ end -- the next one is still messy but will get better when we have -- flattened map/enc tables in the font loader +-- the next one is not using a valid base for unicode privates +-- +-- PsuedoEncodeUnencoded(EncMap *map,struct ttfinfo *info) + actions["check encoding"] = function(data,filename,raw) local descriptions = data.descriptions local resources = data.resources @@ -825,6 +836,7 @@ actions["check encoding"] = function(data,filename,raw) -- local encname = lower(data.enc_name or raw.enc_name or mapdata.enc_name or "") local encname = lower(data.enc_name or mapdata.enc_name or "") local criterium = 0xFFFF -- for instance cambria has a lot of mess up there + local privateoffset = constructors.privateoffset -- end of messy @@ -832,81 +844,44 @@ actions["check encoding"] = function(data,filename,raw) if trace_loading then report_otf("checking embedded unicode map %a",encname) end - -- if false then - -- for unicode, index in next, unicodetoindex do -- altuni already covers this - -- if unicode <= criterium and not descriptions[unicode] then - -- local parent = indices[index] -- why nil? - -- if not parent then - -- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) - -- else - -- local parentdescription = descriptions[parent] - -- if parentdescription then - -- local altuni = parentdescription.altuni - -- if not altuni then - -- altuni = { { unicode = unicode } } - -- parentdescription.altuni = altuni - -- duplicates[parent] = { unicode } - -- else - -- local done = false - -- for i=1,#altuni do - -- if altuni[i].unicode == unicode then - -- done = true - -- break - -- end - -- end - -- if not done then - -- -- let's assume simple cjk reuse - -- insert(altuni,{ unicode = unicode }) - -- insert(duplicates[parent],unicode) - -- end - -- end - -- -- if trace_loading then - -- -- report_otf("weird, unicode %U points to nowhere with index %H",unicode,index) - -- -- end - -- else - -- report_otf("weird, unicode %U points to %U with index %H",unicode,index) - -- end - -- end - -- end - -- end - -- else - local hash = { } - for index, unicode in next, indices do -- indextounicode - hash[index] = descriptions[unicode] - end - local reported = { } - for unicode, index in next, unicodetoindex do - if not descriptions[unicode] then - local d = hash[index] + local reported = { } + -- we loop over the original unicode->index mapping but we + -- need to keep in mind that that one can have weird entries + -- so we need some extra checking + for maybeunicode, index in next, unicodetoindex do + if descriptions[maybeunicode] then + -- we ignore invalid unicodes (unicode = -1) (ff can map wrong to non private) + else + local unicode = indices[index] + if not unicode then + -- weird (cjk or so?) + elseif maybeunicode == unicode then + -- no need to add + elseif unicode > privateoffset then + -- we have a non-unicode + else + local d = descriptions[unicode] if d then - if d.unicode ~= unicode then - local c = d.copies - if c then - c[unicode] = true - else - d.copies = { [unicode] = true } - end + local c = d.copies + if c then + c[maybeunicode] = true + else + d.copies = { [maybeunicode] = true } end - elseif not reported[i] then + elseif index and not reported[index] then report_otf("missing index %i",index) - reported[i] = true + reported[index] = true end end end - for index, data in next, hash do -- indextounicode - data.copies = sortedkeys(data.copies) - end - for index, unicode in next, indices do -- indextounicode - local description = hash[index] - local copies = description.copies - if copies then - duplicates[unicode] = copies - description.copies = nil - else - report_otf("copies but no unicode parent %U",unicode) - end + end + for unicode, data in next, descriptions do + local d = data.copies + if d then + duplicates[unicode] = sortedkeys(d) + data.copies = nil end - -- end + end elseif properties.cidinfo then report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname) else @@ -939,6 +914,7 @@ actions["add duplicates"] = function(data,filename,raw) report_otf("ignoring excessive duplicates of %U (n=%s)",unicode,nofduplicates) end else + -- local validduplicates = { } for i=1,nofduplicates do local u = d[i] if not descriptions[u] then @@ -957,16 +933,18 @@ actions["add duplicates"] = function(data,filename,raw) end -- todo: lookups etc end - if u > 0 then + if u > 0 then -- and local duplicate = table.copy(description) -- else packing problem duplicate.comment = format("copy of U+%05X", unicode) descriptions[u] = duplicate + -- validduplicates[#validduplicates+1] = u if trace_loading then report_otf("duplicating %U to %U with index %H (%s kerns)",unicode,u,description.index,n) end end end end + -- duplicates[unicode] = #validduplicates > 0 and validduplicates or nil end end end @@ -1197,10 +1175,16 @@ actions["reorganize subtables"] = function(data,filename,raw) elseif features then -- scripts, tag, ismac local f = { } + local o = { } for i=1,#features do local df = features[i] local tag = strip(lower(df.tag)) - local ft = f[tag] if not ft then ft = {} f[tag] = ft end + local ft = f[tag] + if not ft then + ft = { } + f[tag] = ft + o[#o+1] = tag + end local dscripts = df.scripts for i=1,#dscripts do local d = dscripts[i] @@ -1220,6 +1204,7 @@ actions["reorganize subtables"] = function(data,filename,raw) subtables = subtables, markclass = markclass, features = f, + order = o, } else lookups[name] = { diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua index 75e95749c..540716b35 100644 --- a/tex/context/base/font-otn.lua +++ b/tex/context/base/font-otn.lua @@ -182,17 +182,18 @@ local tonode = nuts.tonode local tonut = nuts.tonut local getfield = nuts.getfield +local setfield = nuts.setfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getattr = nuts.getattr +local setattr = nuts.setattr +local getprop = nuts.getprop +local setprop = nuts.setprop local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar -local setfield = nuts.setfield -local setattr = nuts.setattr - local insert_node_after = nuts.insert_after local delete_node = nuts.delete local copy_node = nuts.copy @@ -234,13 +235,7 @@ local privateattribute = attributes.private -- of only some. local a_state = privateattribute('state') -local a_markbase = privateattribute('markbase') -local a_markmark = privateattribute('markmark') -local a_markdone = privateattribute('markdone') -- assigned at the injection end -local a_cursbase = privateattribute('cursbase') -local a_curscurs = privateattribute('curscurs') -local a_cursdone = privateattribute('cursdone') -local a_kernpair = privateattribute('kernpair') +local a_cursbase = privateattribute('cursbase') -- to be checked local a_ligacomp = privateattribute('ligacomp') -- assigned here (ideally it should be combined) local injections = nodes.injections @@ -249,9 +244,7 @@ local setcursive = injections.setcursive local setkern = injections.setkern local setpair = injections.setpair -local markonce = true local cursonce = true -local kernonce = true local fonthashes = fonts.hashes local fontdata = fonthashes.identifiers @@ -459,9 +452,9 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun baseindex = baseindex + componentindex componentindex = getcomponentindex(start) elseif not deletemarks then -- quite fishy - setattr(start,a_ligacomp,baseindex + (getattr(start,a_ligacomp) or componentindex)) + setprop(start,a_ligacomp,baseindex + (getprop(start,a_ligacomp) or componentindex)) if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getprop(start,a_ligacomp)) end head, current = insert_node_after(head,current,copy_node(start)) -- unlikely that mark has components elseif trace_marks then @@ -475,9 +468,9 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun while start and getid(start) == glyph_code do local char = getchar(start) if marks[char] then - setattr(start,a_ligacomp,baseindex + (getattr(start,a_ligacomp) or componentindex)) + setprop(start,a_ligacomp,baseindex + (getprop(start,a_ligacomp) or componentindex)) if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getprop(start,a_ligacomp)) end else break @@ -710,7 +703,7 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma = markanchors[anchor] if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -759,7 +752,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end end end - local index = getattr(start,a_ligacomp) + local index = getprop(start,a_ligacomp) local baseanchors = descriptions[basechar] if baseanchors then baseanchors = baseanchors.anchors @@ -773,7 +766,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ if ma then ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) -- index if trace_marks then logprocess("%s, anchor %s, index %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", pref(kind,lookupname),anchor,index,bound,gref(markchar),gref(basechar),index,dx,dy) @@ -809,10 +802,10 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence local markchar = getchar(start) if marks[markchar] then local base = getprev(start) -- [glyph] [basemark] [start=mark] - local slc = getattr(start,a_ligacomp) + local slc = getprop(start,a_ligacomp) if slc then -- a rather messy loop ... needs checking with husayni while base do - local blc = getattr(base,a_ligacomp) + local blc = getprop(base,a_ligacomp) if blc and blc ~= slc then base = getprev(base) else @@ -833,7 +826,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence if al[anchor] then local ma = markanchors[anchor] if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", pref(kind,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -861,7 +854,7 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence end function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) -- to be checked - local alreadydone = cursonce and getattr(start,a_cursbase) + local alreadydone = cursonce and getprop(start,a_cursbase) if not alreadydone then local done = false local startchar = getchar(start) @@ -1343,7 +1336,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext if al[anchor] then local ma = markanchors[anchor] if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to basechar %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) @@ -1399,7 +1392,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end end -- todo: like marks a ligatures hash - local index = getattr(start,a_ligacomp) + local index = getprop(start,a_ligacomp) local baseanchors = descriptions[basechar].anchors if baseanchors then local baseanchors = baseanchors['baselig'] @@ -1411,7 +1404,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon if ma then ba = ba[index] if ba then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma) -- index + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) if trace_marks then logprocess("%s, anchor %s, bound %s: anchoring mark %s to baselig %s at index %s => (%p,%p)", cref(kind,chainname,chainlookupname,lookupname),anchor,a or bound,gref(markchar),gref(basechar),index,dx,dy) @@ -1441,62 +1434,57 @@ end function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) local markchar = getchar(start) if marks[markchar] then - -- local alreadydone = markonce and getattr(start,a_markmark) - -- if not alreadydone then - -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark - local subtables = currentlookup.subtables - local lookupname = subtables[1] - local markanchors = lookuphash[lookupname] - if markanchors then - markanchors = markanchors[markchar] - end - if markanchors then - local base = getprev(start) -- [glyph] [basemark] [start=mark] - local slc = getattr(start,a_ligacomp) - if slc then -- a rather messy loop ... needs checking with husayni - while base do - local blc = getattr(base,a_ligacomp) - if blc and blc ~= slc then - base = getprev(base) - else - break - end + -- local markanchors = descriptions[markchar].anchors markanchors = markanchors and markanchors.mark + local subtables = currentlookup.subtables + local lookupname = subtables[1] + local markanchors = lookuphash[lookupname] + if markanchors then + markanchors = markanchors[markchar] + end + if markanchors then + local base = getprev(start) -- [glyph] [basemark] [start=mark] + local slc = getprop(start,a_ligacomp) + if slc then -- a rather messy loop ... needs checking with husayni + while base do + local blc = getprop(base,a_ligacomp) + if blc and blc ~= slc then + base = getprev(base) + else + break end end - if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then -- subtype test can go - local basechar = getchar(base) - local baseanchors = descriptions[basechar].anchors + end + if base and getid(base) == glyph_code and getfont(base) == currentfont and getsubtype(base)<256 then -- subtype test can go + local basechar = getchar(base) + local baseanchors = descriptions[basechar].anchors + if baseanchors then + baseanchors = baseanchors['basemark'] if baseanchors then - baseanchors = baseanchors['basemark'] - if baseanchors then - local al = anchorlookups[lookupname] - for anchor,ba in next, baseanchors do - if al[anchor] then - local ma = markanchors[anchor] - if ma then - local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,true) - if trace_marks then - logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", - cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) - end - return head, start, true + local al = anchorlookups[lookupname] + for anchor,ba in next, baseanchors do + if al[anchor] then + local ma = markanchors[anchor] + if ma then + local dx, dy, bound = setmark(start,base,tfmdata.parameters.factor,rlmode,ba,ma,characters[basechar]) + if trace_marks then + logprocess("%s, anchor %s, bound %s: anchoring mark %s to basemark %s => (%p,%p)", + cref(kind,chainname,chainlookupname,lookupname),anchor,bound,gref(markchar),gref(basechar),dx,dy) end + return head, start, true end end - if trace_bugs then - logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) - end + end + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and basemark %s",gref(kind,chainname,chainlookupname,lookupname),gref(markchar),gref(basechar)) end end - elseif trace_bugs then - logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) end elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + logwarning("%s: prev node is no mark",cref(kind,chainname,chainlookupname,lookupname)) end - -- elseif trace_marks and trace_details then - -- logprocess("%s, mark %s is already bound (n=%s), ignoring mark2mark",pref(kind,lookupname),gref(markchar),alreadydone) - -- end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(kind,chainname,chainlookupname,lookupname),gref(markchar)) + end elseif trace_bugs then logwarning("%s: mark %s is no mark",cref(kind,chainname,chainlookupname),gref(markchar)) end @@ -1504,7 +1492,7 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext end function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local alreadydone = cursonce and getattr(start,a_cursbase) + local alreadydone = cursonce and getprop(start,a_cursbase) if not alreadydone then local startchar = getchar(start) local subtables = currentlookup.subtables @@ -2065,9 +2053,12 @@ local autofeatures = fonts.analyzers.features -- was: constants local function initialize(sequence,script,language,enabled) local features = sequence.features if features then - for kind, scripts in next, features do + local order = features.order + for i=1,#order do -- + local kind = order[i] -- local valid = enabled[kind] if valid then + local scripts = features[kind] -- local languages = scripts[script] or scripts[wildcard] if languages and (languages[language] or languages[wildcard]) then return { valid, autofeatures[kind] or false, sequence.chain or 0, kind, sequence } @@ -2101,19 +2092,12 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context } rs[language] = rl local sequences = tfmdata.resources.sequences --- setmetatableindex(rl, function(t,k) --- if type(k) == "number" then --- local v = enabled and initialize(sequences[k],script,language,enabled) --- t[k] = v --- return v --- end --- end) -for s=1,#sequences do - local v = enabled and initialize(sequences[s],script,language,enabled) - if v then - rl[#rl+1] = v - end -end + for s=1,#sequences do + local v = enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1] = v + end + end end return rl end @@ -2141,7 +2125,7 @@ end -- attr = attr or false -- -- local a = getattr(start,0) --- if (a == attr and (not attribute or getattr(start,a_state) == attribute)) or (not attribute or getattr(start,a_state) == attribute) then +-- if (a == attr and (not attribute or getprop(start,a_state) == attribute)) or (not attribute or getprop(start,a_state) == attribute) then -- -- the action -- end @@ -2263,9 +2247,9 @@ local function featuresprocessor(head,font,attr) if id == glyph_code and getfont(start) == font and getsubtype(start) < 256 then local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or getattr(start,a_state) == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or getattr(start,a_state) == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then local lookupmatch = lookupcache[getchar(start)] @@ -2299,9 +2283,9 @@ local function featuresprocessor(head,font,attr) -- setfield(next,"prev",prev) local a = getattr(prev,0) if a then - a = (a == attr) and (not attribute or getattr(prev,a_state) == attribute) + a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) else - a = not attribute or getattr(prev,a_state) == attribute + a = not attribute or getprop(prev,a_state) == attribute end if a then local lookupmatch = lookupcache[getchar(prev)] @@ -2326,9 +2310,9 @@ local function featuresprocessor(head,font,attr) if getfont(start) == font and getsubtype(start) < 256 then local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or getattr(start,a_state) == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or getattr(start,a_state) == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then local lookupmatch = lookupcache[getchar(start)] @@ -2424,9 +2408,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then if id == glyph_code and getfont(start) == font and getsubtype(start) < 256 then local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or getattr(start,a_state) == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or getattr(start,a_state) == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then for i=1,ns do @@ -2472,9 +2456,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then -- setfield(next,"prev",prev) local a = getattr(prev,0) if a then - a = (a == attr) and (not attribute or getattr(prev,a_state) == attribute) + a = (a == attr) and (not attribute or getprop(prev,a_state) == attribute) else - a = not attribute or getattr(prev,a_state) == attribute + a = not attribute or getprop(prev,a_state) == attribute end if a then for i=1,ns do @@ -2507,9 +2491,9 @@ elseif typ == "gpos_single" or typ == "gpos_pair" then if getfont(start) == font and getsubtype(start) < 256 then local a = getattr(start,0) if a then - a = (a == attr) and (not attribute or getattr(start,a_state) == attribute) + a = (a == attr) and (not attribute or getprop(start,a_state) == attribute) else - a = not attribute or getattr(start,a_state) == attribute + a = not attribute or getprop(start,a_state) == attribute end if a then for i=1,ns do diff --git a/tex/context/base/font-otp.lua b/tex/context/base/font-otp.lua index 217bb7535..c80ee86ae 100644 --- a/tex/context/base/font-otp.lua +++ b/tex/context/base/font-otp.lua @@ -407,6 +407,14 @@ local function packdata(data) features[script] = pack_normal(feature) end end + local order = sequence.order + if order then + sequence.order = pack_indexed(order) + end + local markclass = sequence.markclass + if markclass then + sequence.markclass = pack_boolean(markclass) + end end end local lookups = resources.lookups @@ -825,6 +833,20 @@ local function unpackdata(data) end end end + local order = feature.order + if order then + local tv = tables[order] + if tv then + feature.order = tv + end + end + local markclass = feature.markclass + if markclass then + local tv = tables[markclass] + if tv then + feature.markclass = tv + end + end end end local lookups = resources.lookups diff --git a/tex/context/base/font-otx.lua b/tex/context/base/font-otx.lua index b7d2ae0bc..dc0469e39 100644 --- a/tex/context/base/font-otx.lua +++ b/tex/context/base/font-otx.lua @@ -37,13 +37,12 @@ local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid -local getattr = nuts.getattr +local getprop = nuts.getprop +local setprop = nuts.setprop local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar -local setattr = nuts.setattr - local traverse_id = nuts.traverse_id local traverse_node_list = nuts.traverse local end_of_math = nuts.end_of_math @@ -124,34 +123,34 @@ function analyzers.setstate(head,font) -- we can skip math if d then if d.class == "mark" then done = true - setattr(current,a_state,s_mark) + setprop(current,a_state,s_mark) elseif useunicodemarks and categories[char] == "mn" then done = true - setattr(current,a_state,s_mark) + setprop(current,a_state,s_mark) elseif n == 0 then first, last, n = current, current, 1 - setattr(current,a_state,s_init) + setprop(current,a_state,s_init) else last, n = current, n+1 - setattr(current,a_state,s_medi) + setprop(current,a_state,s_medi) end else -- finish if first and first == last then - setattr(last,a_state,s_isol) + setprop(last,a_state,s_isol) elseif last then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) end first, last, n = nil, nil, 0 end elseif id == disc_code then -- always in the middle - setattr(current,a_state,s_medi) + setprop(current,a_state,s_medi) last = current else -- finish if first and first == last then - setattr(last,a_state,s_isol) + setprop(last,a_state,s_isol) elseif last then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) end first, last, n = nil, nil, 0 if id == math_code then @@ -161,9 +160,9 @@ function analyzers.setstate(head,font) -- we can skip math current = getnext(current) end if first and first == last then - setattr(last,a_state,s_isol) + setprop(last,a_state,s_isol) elseif last then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) end return head, done end @@ -279,92 +278,92 @@ function methods.arab(head,font,attr) current = tonut(current) while current do local id = getid(current) - if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getattr(current,a_state) then + if id == glyph_code and getfont(current) == font and getsubtype(current)<256 and not getprop(current,a_state) then done = true local char = getchar(current) local classifier = classifiers[char] if not classifier then if last then if c_last == s_medi or c_last == s_fina then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) else warning(last,"fina") - setattr(last,a_state,s_error) + setprop(last,a_state,s_error) end first, last = nil, nil elseif first then if c_first == s_medi or c_first == s_fina then - setattr(first,a_state,s_isol) + setprop(first,a_state,s_isol) else warning(first,"isol") - setattr(first,a_state,s_error) + setprop(first,a_state,s_error) end first = nil end elseif classifier == s_mark then - setattr(current,a_state,s_mark) + setprop(current,a_state,s_mark) elseif classifier == s_isol then if last then if c_last == s_medi or c_last == s_fina then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) else warning(last,"fina") - setattr(last,a_state,s_error) + setprop(last,a_state,s_error) end first, last = nil, nil elseif first then if c_first == s_medi or c_first == s_fina then - setattr(first,a_state,s_isol) + setprop(first,a_state,s_isol) else warning(first,"isol") - setattr(first,a_state,s_error) + setprop(first,a_state,s_error) end first = nil end - setattr(current,a_state,s_isol) + setprop(current,a_state,s_isol) elseif classifier == s_medi then if first then last = current c_last = classifier - setattr(current,a_state,s_medi) + setprop(current,a_state,s_medi) else - setattr(current,a_state,s_init) + setprop(current,a_state,s_init) first = current c_first = classifier end elseif classifier == s_fina then if last then - if getattr(last,a_state) ~= s_init then - setattr(last,a_state,s_medi) + if getprop(last,a_state) ~= s_init then + setprop(last,a_state,s_medi) end - setattr(current,a_state,s_fina) + setprop(current,a_state,s_fina) first, last = nil, nil elseif first then - -- if getattr(first,a_state) ~= s_init then + -- if getprop(first,a_state) ~= s_init then -- -- needs checking - -- setattr(first,a_state,s_medi) + -- setprop(first,a_state,s_medi) -- end - setattr(current,a_state,s_fina) + setprop(current,a_state,s_fina) first = nil else - setattr(current,a_state,s_isol) + setprop(current,a_state,s_isol) end else -- classifier == s_rest - setattr(current,a_state,s_rest) + setprop(current,a_state,s_rest) if last then if c_last == s_medi or c_last == s_fina then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) else warning(last,"fina") - setattr(last,a_state,s_error) + setprop(last,a_state,s_error) end first, last = nil, nil elseif first then if c_first == s_medi or c_first == s_fina then - setattr(first,a_state,s_isol) + setprop(first,a_state,s_isol) else warning(first,"isol") - setattr(first,a_state,s_error) + setprop(first,a_state,s_error) end first = nil end @@ -372,18 +371,18 @@ function methods.arab(head,font,attr) else if last then if c_last == s_medi or c_last == s_fina then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) else warning(last,"fina") - setattr(last,a_state,s_error) + setprop(last,a_state,s_error) end first, last = nil, nil elseif first then if c_first == s_medi or c_first == s_fina then - setattr(first,a_state,s_isol) + setprop(first,a_state,s_isol) else warning(first,"isol") - setattr(first,a_state,s_error) + setprop(first,a_state,s_error) end first = nil end @@ -395,17 +394,17 @@ function methods.arab(head,font,attr) end if last then if c_last == s_medi or c_last == s_fina then - setattr(last,a_state,s_fina) + setprop(last,a_state,s_fina) else warning(last,"fina") - setattr(last,a_state,s_error) + setprop(last,a_state,s_error) end elseif first then if c_first == s_medi or c_first == s_fina then - setattr(first,a_state,s_isol) + setprop(first,a_state,s_isol) else warning(first,"isol") - setattr(first,a_state,s_error) + setprop(first,a_state,s_error) end end return head, done diff --git a/tex/context/base/font-sel.lua b/tex/context/base/font-sel.lua index 2881917eb..86300c2db 100644 --- a/tex/context/base/font-sel.lua +++ b/tex/context/base/font-sel.lua @@ -174,28 +174,58 @@ local names = { ["heavyitalic"] = { "heavyitalic" }, }, ["default"] = { -- weight, width, italic - ["thin"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = false }, - ["extralight"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = false }, - ["light"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = false }, - ["regular"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false }, - ["italic"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = true }, - ["medium"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = false }, - ["demibold"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = false }, - ["bold"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = false }, - ["bolditalic"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = true }, - ["smallcaps"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false }, - ["heavy"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = false }, - ["black"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = false }, + ["thin"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = false }, + ["thinitalic"] = { weight = { 100, 200, 300, 400, 500 }, width = 5, italic = true }, + ["extralight"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = false }, + ["extralightitalic"] = { weight = { 200, 100, 300, 400, 500 }, width = 5, italic = true }, + ["light"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = false }, + ["lightitalic"] = { weight = { 300, 200, 100, 400, 500 }, width = 5, italic = true }, + ["regular"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = false }, + ["italic"] = { weight = { 400, 500, 300, 200, 100 }, width = 5, italic = true }, + ["medium"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = false }, + ["mediumitalic"] = { weight = { 500, 400, 300, 200, 100 }, width = 5, italic = true }, + ["demibold"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = false }, + ["demibolditalic"] = { weight = { 600, 700, 800, 900 }, width = 5, italic = true }, + ["bold"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = false }, + ["bolditalic"] = { weight = { 700, 600, 800, 900 }, width = 5, italic = true }, + ["extrabold"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = false }, + ["extrabolditalic"] = { weight = { 800, 900, 700, 600 }, width = 5, italic = true }, + ["heavy"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = false }, + ["heavyitalic"] = { weight = { 900, 800, 700, 600 }, width = 5, italic = true }, } } -names.simplefonts.slanted = names.simplefonts.italic -names.simplefonts.boldslanted = names.simplefonts.bolditalic +-- simplefonts synonyms -names.default.normal = names.default.regular -names.default.slanted = names.default.italic -names.default.semibold = names.default.demibold -names.default.boldslanted = names.default.bolditalic +names.simplefonts.slanted = names.simplefonts.italic +names.simplefonts.boldslanted = names.simplefonts.bolditalic + +-- default synonyms + +names.default.ultralight = names.default.extralight +names.default.semibold = names.default.demibold +names.default.ultrabold = names.default.extrabold +names.default.black = names.default.heavy + +names.default.ultralightitalic = names.default.extralightitalic +names.default.semibolditalic = names.default.demibolditalic +names.default.ultrabolditalic = names.default.extrabolditalic +names.default.blackitalic = names.default.heavyitalic + +names.default.thinslanted = names.default.thinitalic +names.default.extralightslanted = names.default.extralightitalic +names.default.ultralightslanted = names.default.extralightitalic +names.default.lightslanted = names.default.lightitalic +names.default.slanted = names.default.italic +names.default.demiboldslanted = names.default.demibolditalic +names.default.semiboldslanted = names.default.demibolditalic +names.default.boldslanted = names.default.bolditalic +names.default.extraboldslanted = names.default.extrabolditalic +names.default.ultraboldslanted = names.default.extrabolditalic +names.default.heavyslanted = names.default.heavyitalic +names.default.blackslanted = names.default.heavyitalic + +names.default.smallcaps = names.default.regular local mathsettings = { ["asanamath"] = { @@ -494,7 +524,7 @@ local function definefontsynonym(data,alternative,index,fallback) end for _, entry in next, fontdata do local designsize = entry["designsize"] or 100 - if designsize == 100 or designsize == 120 or designsize == 0 or #fontdata == 1 then + if designsize == 100 or designsize == 110 or designsize == 120 or designsize == 0 or #fontdata == 1 then local filepath, filename = splitbase(entry["filename"]) registerdesignsizes( fontfile, "default", filename ) break @@ -600,7 +630,7 @@ local function definemathfontfallback(data,alternative,index) for _, entry in next, fontdata do local filename = entry["filename"] local designsize = entry["designsize"] or 100 - if designsize == 100 or designsize == 120 or designsize == 0 or #fontdata == 1 then + if designsize == 100 or designsize == 110 or designsize == 120 or designsize == 0 or #fontdata == 1 then context.definefontfallback( { fallback }, { formatters["file:%s*%s"](filename,features) }, { range }, { rscale = rscale, check = check, force = force, offset = offset } ) break end diff --git a/tex/context/base/font-sel.mkvi b/tex/context/base/font-sel.mkvi index 3d4dc6807..0b1d10c51 100644 --- a/tex/context/base/font-sel.mkvi +++ b/tex/context/base/font-sel.mkvi @@ -1,6 +1,6 @@ %D \module %D [ file=font-sel, -%D version=2013.10.19, +%D version=2014.03.10, %D title=\CONTEXT\ User Module, %D subtitle=Selectfont, %D author=Wolfgang Schuster, @@ -115,11 +115,18 @@ % unknown preset \fi} -\definefontfamilypreset [range:chinese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,bopomofo,bopomofoextended}] -\definefontfamilypreset [range:japanese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hiragana,katakana}] -\definefontfamilypreset [range:korean] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hangulcompatibilityjamo,hanguljamo,hanguljamoextendeda,hanguljamoextendedb,hangulsyllables}] -\definefontfamilypreset [range:cyrillic] [\c!range={cyrillic,cyrillicextendeda,cyrillicextendedb,cyrillicsupplement}] -\definefontfamilypreset [range:greek] [\c!range={greekandcoptic,greekextended,ancientgreeknumbers}] +%definefontfamilypreset [range:chinese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,bopomofo,bopomofoextended}] +%definefontfamilypreset [range:japanese] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hiragana,katakana}] +%definefontfamilypreset [range:korean] [\c!range={cjkcompatibilityforms,cjkcompatibilityideographs,cjkcompatibilityideographssupplement,cjkradicalssupplement,cjkstrokes,cjksymbolsandpunctuation,cjkunifiedideographs,cjkunifiedideographsextensiona,cjkunifiedideographsextensionb,halfwidthandfullwidthforms,verticalforms,hangulcompatibilityjamo,hanguljamo,hanguljamoextendeda,hanguljamoextendedb,hangulsyllables}] +%definefontfamilypreset [range:cyrillic] [\c!range={cyrillic,cyrillicextendeda,cyrillicextendedb,cyrillicsupplement}] +%definefontfamilypreset [range:greek] [\c!range={greekandcoptic,greekextended,ancientgreeknumbers}] + +\definefontfamilypreset [range:chinese] [\c!range={0x02E80-0x02EFF,0x03000-0x031EF,0x03300-0x09FFF,0x0F900-0x0FFEF,0x20000-0x2A6DF,0x2F800-0x2FA1F,0x03100-0x0312F,0x031A0-0x031BF}] +\definefontfamilypreset [range:japanese] [\c!range={0x02E80-0x02EFF,0x03000-0x031EF,0x03300-0x09FFF,0x0F900-0x0FFEF,0x20000-0x2A6DF,0x2F800-0x2FA1F,0x03040-0x0309F,0x030A0-0x030FF}] +\definefontfamilypreset [range:korean] [\c!range={0x02E80-0x02EFF,0x03000-0x031EF,0x03300-0x09FFF,0x0F900-0x0FFEF,0x20000-0x2A6DF,0x2F800-0x2FA1F,0x01100-0x011FF,0x03130-0x0318F,0x0A960-0x0D7FF}] +\definefontfamilypreset [range:cyrillic] [\c!range={0x00400-0x0052F,0x02DE0-0x02DFF,0x0A640-0x0A69F}] +\definefontfamilypreset [range:greek] [\c!range={0x00370-0x003FF,0x01F00-0x01FFF,0x10140-0x1018F}] +\definefontfamilypreset [range:hebrew] [\c!range={0x00590-0x005FF,0x0FB00-0x0FB4F}] \definefontfamilypreset [math:digitsnormal] [\c!range=digitsnormal] \definefontfamilypreset [math:digitsbold] [\c!range=digitsnormal,\c!offset=digitsbold,\s!tf=style:bold] @@ -219,13 +226,13 @@ %D \stoptyping %D %D When a document contains different languages and the global font lacks some characters -%D for one language, one could set a different font where these charcters are taken from. +%D for one language, one could set a different font where these characters are taken from. %D This fallback font (there can be more than one for a certain style) could be set with %D the \tex{definefallbackfamily} command which takes the same argument as %D the \tex{definefontfamily} command. %D %D \starttyping -%D \definefallbackfamily [mainface] [serif] [DejaVu Serif] [range=cyrillic,force=yes] +%D \definefallbackfamily [mainface] [serif] [DejaVu Serif] [range=cyrillic] %D \definefontfamily [mainface] [serif] [TeX Gyre Pagella] %D %D \setupbodyfont[mainface] @@ -364,4 +371,4 @@ \c!smallcapsfeatures=\s!smallcaps, \c!style=\s!rm] -\protect +\protect \ No newline at end of file diff --git a/tex/context/base/font-set.mkvi b/tex/context/base/font-set.mkvi index 0e2058c18..f94d6c86e 100644 --- a/tex/context/base/font-set.mkvi +++ b/tex/context/base/font-set.mkvi @@ -39,27 +39,36 @@ % \enablemode[lmmath] +\let\m_font_fallback_name\empty + \def\font_preloads_reset_nullfont % this is needed because some macro packages (tikz) misuse \nullfont {\dorecurse\plusseven{\fontdimen\recurselevel\nullfont\zeropoint}% keep en eye on this as: \ctxcommand{resetnullfont()}% in luatex 0.70 this will also do the previous \globallet\font_preloads_reset_nullfont\relax} +\def\font_preload_check_mode + {\doifmodeelse{lmmath} + {\def\m_font_fallback_name{modern-designsize-virtual}}% this will stay + {\def\m_font_fallback_name{modern-designsize}}% % this might become 'modern' + \glet\font_preload_check_mode\relax} + \def\font_preload_default_fonts {\font_preloads_reset - \doifmodeelse{lmmath} - {\setupbodyfont[modern-designsize-virtual,\fontstyle,\fontbody]}% this will stay - {\setupbodyfont[modern-designsize,\fontstyle,\fontbody]}% % this might become 'modern' - \showmessage\m!fonts6{fallback modern \fontstyle\normalspace\normalizedbodyfontsize}} + \font_preload_check_mode + \setupbodyfont[\m_font_fallback_name,\fontstyle,\fontbody]% + \showmessage\m!fonts6{fallback \m_font_fallback_name\space \fontstyle\normalspace\normalizedbodyfontsize}} \def\font_preload_default_fonts_mm - {\writestatus\m!fonts{preloading latin modern fonts (math)}% - \definetypeface[\fontclass][\s!mm][\s!math][modern][\s!default]% - \showmessage\m!fonts6{fallback modern mm \normalizedbodyfontsize}} + {\font_preload_check_mode + \writestatus\m!fonts{preloading \m_font_fallback_name\space (math)}% + \definetypeface[\fontclass][\s!mm][\s!math][\m_font_fallback_name][\s!default]% + \showmessage\m!fonts6{fallback \m_font_fallback_name\space mm \normalizedbodyfontsize}} \def\font_preload_default_fonts_tt - {\writestatus\m!fonts{preloading latin modern fonts (mono)}% - \definetypeface[\fontclass][\s!tt][\s!mono][modern][\s!default]% - \showmessage\m!fonts6{fallback modern tt \normalizedbodyfontsize}} + {\font_preload_check_mode + \writestatus\m!fonts{preloading \m_font_fallback_name\space (mono)}% + \definetypeface[\fontclass][\s!tt][\s!mono][\m_font_fallback_name][\s!default]% + \showmessage\m!fonts6{fallback \m_font_fallback_name\space tt \normalizedbodyfontsize}} \def\font_preloads_reset {\glet\font_preload_default_fonts \relax diff --git a/tex/context/base/font-syn.lua b/tex/context/base/font-syn.lua index 6296f088e..18ed46a2f 100644 --- a/tex/context/base/font-syn.lua +++ b/tex/context/base/font-syn.lua @@ -396,7 +396,7 @@ function filters.afm(name) if key and #key > 0 then hash[lower(key)] = value end - if find(line,"StartCharMetrics") then + if find(line,"StartCharMetrics",1,true) then break end end @@ -1801,7 +1801,7 @@ local lastlookups, lastpattern = { }, "" -- local lookups = specifications -- if name then -- lookups = families[name] --- elseif not find(pattern,"=") then +-- elseif not find(pattern,"=",1,true) then -- lookups = families[pattern] -- end -- if trace_names then @@ -1810,7 +1810,7 @@ local lastlookups, lastpattern = { }, "" -- if lookups then -- for key, value in gmatch(pattern,"([^=,]+)=([^=,]+)") do -- local t, n = { }, 0 --- if find(value,"*") then +-- if find(value,"*",1,true) then -- value = topattern(value) -- for i=1,#lookups do -- local s = lookups[i] @@ -1843,7 +1843,7 @@ local lastlookups, lastpattern = { }, "" local function look_them_up(lookups,specification) for key, value in next, specification do local t, n = { }, 0 - if find(value,"*") then + if find(value,"*",1,true) then value = topattern(value) for i=1,#lookups do local s = lookups[i] @@ -1906,7 +1906,7 @@ function names.lookup(pattern,name,reload) -- todo: find lastpattern = false lastlookups = lookups or { } elseif lastpattern ~= pattern then - local lookups = first_look(name or (not find(pattern,"=") and pattern),reload) + local lookups = first_look(name or (not find(pattern,"=",1,true) and pattern),reload) if lookups then if trace_names then report_names("starting with %s lookups for %a",#lookups,pattern) diff --git a/tex/context/base/font-var.mkvi b/tex/context/base/font-var.mkvi index e50c2bad4..fb60b711c 100644 --- a/tex/context/base/font-var.mkvi +++ b/tex/context/base/font-var.mkvi @@ -50,4 +50,7 @@ \let\fontsize \defaultfontsize \let\fontface \!!zerocount +% we can use an indirect mapping for fontclasses (map string onto numbers) and indeed this +% is somewhat more efficient but also makes the code messy ... maybe some day ... + \protect \endinput diff --git a/tex/context/base/l-dir.lua b/tex/context/base/l-dir.lua index b658b7c75..257212060 100644 --- a/tex/context/base/l-dir.lua +++ b/tex/context/base/l-dir.lua @@ -27,7 +27,7 @@ local currentdir = lfs.currentdir local chdir = lfs.chdir local mkdir = lfs.mkdir -local onwindows = os.type == "windows" or find(os.getenv("PATH"),";") +local onwindows = os.type == "windows" or find(os.getenv("PATH"),";",1,true) -- in case we load outside luatex @@ -189,7 +189,7 @@ local function glob(str,t) local split = lpegmatch(pattern,str) -- we could use the file splitter if split then local root, path, base = split[1], split[2], split[3] - local recurse = find(base,"%*%*") + local recurse = find(base,"**",1,true) -- find(base,"%*%*") local start = root .. path local result = lpegmatch(filter,start .. base) globpattern(start,result,recurse,t) @@ -215,7 +215,7 @@ local function glob(str,t) local t = t or { } local action = action or function(name) t[#t+1] = name end local root, path, base = split[1], split[2], split[3] - local recurse = find(base,"%*%*") + local recurse = find(base,"**",1,true) -- find(base,"%*%*") local start = root .. path local result = lpegmatch(filter,start .. base) globpattern(start,result,recurse,action) @@ -295,7 +295,6 @@ if onwindows then else str = "" for i=1,n do - local s = select(i,...) local s = select(i,...) if s == "" then -- skip diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua index 52f166af9..020e811bf 100644 --- a/tex/context/base/l-io.lua +++ b/tex/context/base/l-io.lua @@ -12,7 +12,7 @@ local concat = table.concat local floor = math.floor local type = type -if string.find(os.getenv("PATH"),";") then +if string.find(os.getenv("PATH"),";",1,true) then io.fileseparator, io.pathseparator = "\\", ";" else io.fileseparator, io.pathseparator = "/" , ":" diff --git a/tex/context/base/l-os.lua b/tex/context/base/l-os.lua index bfafa4f95..1dff79cd3 100644 --- a/tex/context/base/l-os.lua +++ b/tex/context/base/l-os.lua @@ -137,7 +137,7 @@ function os.resultof(command) end if not io.fileseparator then - if find(os.getenv("PATH"),";") then + if find(os.getenv("PATH"),";",1,true) then io.fileseparator, io.pathseparator, os.type = "\\", ";", os.type or "mswin" else io.fileseparator, io.pathseparator, os.type = "/" , ":", os.type or "unix" @@ -236,7 +236,7 @@ elseif os.type == "windows" then function resolvers.platform(t,k) local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" - if find(architecture,"AMD64") then + if find(architecture,"AMD64",1,true) then -- platform = "mswin-64" platform = "win64" else @@ -252,9 +252,9 @@ elseif name == "linux" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" - if find(architecture,"x86_64") then + if find(architecture,"x86_64",1,true) then platform = "linux-64" - elseif find(architecture,"ppc") then + elseif find(architecture,"ppc",1,true) then platform = "linux-ppc" else platform = "linux" @@ -285,9 +285,9 @@ elseif name == "macosx" then if architecture == "" then -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n") platform = "osx-intel" - elseif find(architecture,"i386") then + elseif find(architecture,"i386",1,true) then platform = "osx-intel" - elseif find(architecture,"x86_64") then + elseif find(architecture,"x86_64",1,true) then platform = "osx-64" else platform = "osx-ppc" @@ -301,7 +301,7 @@ elseif name == "sunos" then function resolvers.platform(t,k) local platform, architecture = "", os.resultof("uname -m") or "" - if find(architecture,"sparc") then + if find(architecture,"sparc",1,true) then platform = "solaris-sparc" else -- if architecture == 'i86pc' platform = "solaris-intel" @@ -315,7 +315,7 @@ elseif name == "freebsd" then function resolvers.platform(t,k) local platform, architecture = "", os.resultof("uname -m") or "" - if find(architecture,"amd64") then + if find(architecture,"amd64",1,true) then platform = "freebsd-amd64" else platform = "freebsd" @@ -330,7 +330,7 @@ elseif name == "kfreebsd" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or "" - if find(architecture,"x86_64") then + if find(architecture,"x86_64",1,true) then platform = "kfreebsd-amd64" else platform = "kfreebsd-i386" @@ -356,7 +356,7 @@ else end function resolvers.bits(t,k) - local bits = find(os.platform,"64") and 64 or 32 + local bits = find(os.platform,"64",1,true) and 64 or 32 os.bits = bits return bits end diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua index c318c57bb..d231830ed 100644 --- a/tex/context/base/l-table.lua +++ b/tex/context/base/l-table.lua @@ -88,6 +88,38 @@ local function sortedkeys(tab) end end +local function sortedhashonly(tab) + if tab then + local srt, s = { }, 0 + for key,_ in next, tab do + if type(key) == "string" then + s = s + 1 + srt[s] = key + end + end + sort(srt) + return srt + else + return { } + end +end + +local function sortedindexonly(tab) + if tab then + local srt, s = { }, 0 + for key,_ in next, tab do + if type(key) == "number" then + s = s + 1 + srt[s] = key + end + end + sort(srt) + return srt + else + return { } + end +end + local function sortedhashkeys(tab,cmp) -- fast one if tab then local srt, s = { }, 0 @@ -114,8 +146,10 @@ function table.allkeys(t) return sortedkeys(keys) end -table.sortedkeys = sortedkeys -table.sortedhashkeys = sortedhashkeys +table.sortedkeys = sortedkeys +table.sortedhashonly = sortedhashonly +table.sortedindexonly = sortedindexonly +table.sortedhashkeys = sortedhashkeys local function nothing() end diff --git a/tex/context/base/l-unicode.lua b/tex/context/base/l-unicode.lua index 6601a4c62..be61f3d73 100644 --- a/tex/context/base/l-unicode.lua +++ b/tex/context/base/l-unicode.lua @@ -6,7 +6,14 @@ if not modules then modules = { } end modules ['l-unicode'] = { license = "see context related readme files" } --- this module will be reorganized +-- in lua 5.3: + +-- utf8.char(···) : concatinated +-- utf8.charpatt : "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" +-- utf8.codes(s) : for p, c in utf8.codes(s) do body end +-- utf8.codepoint(s [, i [, j]]) +-- utf8.len(s [, i]) +-- utf8.offset(s, n [, i]) -- todo: utf.sub replacement (used in syst-aux) -- we put these in the utf namespace: diff --git a/tex/context/base/lang-def.mkiv b/tex/context/base/lang-def.mkiv index 18f572039..5c1d6de9c 100644 --- a/tex/context/base/lang-def.mkiv +++ b/tex/context/base/lang-def.mkiv @@ -634,6 +634,10 @@ \c!rightquotation=\upperrightdoubleninequote, \c!date={\v!year,\space,\v!month,\space,\v!day}] +\installlanguage[\s!pt-br][\c!default=\s!pt] % Brazil +\installlanguage[\s!es-es][\c!default=\s!es] % Spain +\installlanguage[\s!es-la][\c!default=\s!es] % Latin America + \installlanguage [\s!ro] [\c!spacing=\v!packed, diff --git a/tex/context/base/lang-ini.mkiv b/tex/context/base/lang-ini.mkiv index 17d00033b..4ed7839bd 100644 --- a/tex/context/base/lang-ini.mkiv +++ b/tex/context/base/lang-ini.mkiv @@ -479,7 +479,7 @@ \lang_basics_switch_asked} \unexpanded\def\language - {\doifnextoptionalelse\lang_basics_set_current\normallanguage} + {\doifnextoptionalcselse\lang_basics_set_current\normallanguage} \newcount\mainlanguagenumber @@ -505,7 +505,7 @@ \normallanguage\mainlanguagenumber \to \everybeforepagebody -%D New (see nomarking and nolist): +%D Used at all? \def\splitsequence#1#2% {\doifelse{#1}\v!no{#2}{\doifelse{#1}\v!yes{\languageparameter\c!limittext}{#1}}} diff --git a/tex/context/base/lang-lab.mkiv b/tex/context/base/lang-lab.mkiv index 14d9d8594..7dcaaecb4 100644 --- a/tex/context/base/lang-lab.mkiv +++ b/tex/context/base/lang-lab.mkiv @@ -180,7 +180,7 @@ \grabuntil{stop#1text}\lang_labels_text_prefix_start_indeed} \def\lang_labels_text_prefix_start_indeed#1% text (not special checking done here yet, only for long texts anyway) - {\expandafter\edef\csname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\ctxlua{context(string.strip(\!!bs#1\!!es))}}\empty}} + {\expandafter\edef\csname\??label\currenttextprefixclass:\currenttextprefixtag:\currenttextprefixname\endcsname{{\ctxcommand{strip(\!!bs#1\!!es)}}\empty}} \def\lang_labels_text_prefix_setup[#1][#2]% {\ifsecondargument diff --git a/tex/context/base/lang-rep.lua b/tex/context/base/lang-rep.lua index be74d597a..02eb59f48 100644 --- a/tex/context/base/lang-rep.lua +++ b/tex/context/base/lang-rep.lua @@ -90,7 +90,7 @@ local function add(root,word,replacement) -- for i=1,#newlist do -- newlist[i] = utfbyte(newlist[i]) -- end - local special = find(replacement,"{") + local special = find(replacement,"{",1,true) local newlist = lpegmatch(splitter,replacement) -- root[l].final = { diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua index 3f0e718b3..45b0e8e9c 100644 --- a/tex/context/base/lpdf-ano.lua +++ b/tex/context/base/lpdf-ano.lua @@ -10,46 +10,62 @@ if not modules then modules = { } end modules ['lpdf-ano'] = { -- todo: /AA << WC << ... >> >> : WillClose actions etc -local next, tostring = next, tostring -local rep, format = string.rep, string.format +-- internal references are indicated by a number (and turned into aut:) +-- we only flush internal destinations that are referred + +local next, tostring, tonumber, rawget = next, tostring, tonumber, rawget +local rep, format, find = string.rep, string.format, string.find +local min = math.min local lpegmatch = lpeg.match local formatters = string.formatters local backends, lpdf = backends, lpdf -local trace_references = false trackers.register("references.references", function(v) trace_references = v end) -local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end) -local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) +local trace_references = false trackers.register("references.references", function(v) trace_references = v end) +local trace_destinations = false trackers.register("references.destinations", function(v) trace_destinations = v end) +local trace_bookmarks = false trackers.register("references.bookmarks", function(v) trace_bookmarks = v end) -local report_reference = logs.reporter("backend","references") -local report_destination = logs.reporter("backend","destinations") -local report_bookmark = logs.reporter("backend","bookmarks") +local report_reference = logs.reporter("backend","references") +local report_destination = logs.reporter("backend","destinations") +local report_bookmark = logs.reporter("backend","bookmarks") local variables = interfaces.variables local constants = interfaces.constants +local factor = number.dimenfactors.bp + local settings_to_array = utilities.parsers.settings_to_array +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex + local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations +local getpos = codeinjections.getpos +local gethpos = codeinjections.gethpos +local getvpos = codeinjections.getvpos + local javascriptcode = interactions.javascripts.code local references = structures.references local bookmarks = structures.bookmarks +local flaginternals = references.flaginternals +local usedinternals = references.usedinternals + local runners = references.runners local specials = references.specials local handlers = references.handlers local executers = references.executers -local getinnermethod = references.getinnermethod local nodepool = nodes.pool -local pdfannotation_node = nodepool.pdfannotation -local pdfdestination_node = nodepool.pdfdestination -local latelua_node = nodepool.latelua +----- pdfannotation_node = nodepool.pdfannotation +----- pdfdestination_node = nodepool.pdfdestination +----- latelua_node = nodepool.latelua +local latelua_function_node = nodepool.lateluafunction -- still node ... todo local texgetcount = tex.getcount @@ -63,7 +79,12 @@ local pdfshareobjectreference = lpdf.shareobjectreference local pdfreserveobject = lpdf.reserveobject local pdfpagereference = lpdf.pagereference local pdfdelayedobject = lpdf.delayedobject -local pdfregisterannotation = lpdf.registerannotation +local pdfregisterannotation = lpdf.registerannotation -- forward definition (for the moment) +local pdfnull = lpdf.null +local pdfaddtocatalog = lpdf.addtocatalog +local pdfaddtonames = lpdf.addtonames +local pdfaddtopageattributes = lpdf.addtopageattributes +local pdfrectangle = lpdf.rectangle -- todo: 3dview @@ -81,28 +102,308 @@ local pdf_named = pdfconstant("Named") local pdf_border = pdfarray { 0, 0, 0 } -local cache = { } +-- the used and flag code here is somewhat messy in the sense +-- that it belongs in strc-ref but at the same time depends on +-- the backend so we keep it here -local function pagedestination(n) -- only cache fit - if n > 0 then - local pd = cache[n] - if not pd then - local a = pdfarray { - pdfreference(pdfpagereference(n)), - pdf_fit, - } - pd = pdfshareobjectreference(a) - cache[n] = pd +-- the caching is somewhat memory intense on the one hand but +-- it saves many small temporary tables so it might pay off + +local destinationviews = { } -- prevent messages + +local pagedestinations = allocate() +local pagereferences = allocate() -- annots are cached themselves + +setmetatableindex(pagedestinations, function(t,k) + k = tonumber(k) + local v = rawget(t,k) + if v then + -- report_reference("page number expected, got %s: %a",type(k),k) + return v + end + local v = k > 0 and pdfarray { + pdfreference(pdfpagereference(k)), + pdf_fit, + } or pdfnull() + t[k] = v + return v +end) + +setmetatableindex(pagereferences,function(t,k) + k = tonumber(k) + local v = rawget(t,k) + if v then + return v + end + local v = pdfdictionary { -- can be cached + S = pdf_goto, + D = pagedestinations[k], + } + t[k] = v + return v +end) + +lpdf.pagereferences = pagereferences -- table +lpdf.pagedestinations = pagedestinations -- table + +local defaultdestination = pdfarray { 0, pdf_fit } + +-- fit is default (see lpdf-nod) + +local destinations = { } -- to be used soon + +local function pdfregisterdestination(name,reference) + local d = destinations[name] + if d then + report_destination("ignoring duplicate destination %a with reference %a",name,reference) + else + destinations[name] = reference + end +end + +lpdf.registerdestination = pdfregisterdestination + +local maxslice = 32 -- could be made configureable ... 64 is also ok + +local function pdfnametree(destinations) + local slices = { } + local sorted = table.sortedkeys(destinations) + local size = #sorted + + if size <= 1.5*maxslice then + maxslice = size + end + + for i=1,size,maxslice do + local amount = min(i+maxslice-1,size) + local names = pdfarray { } + for j=i,amount do + local destination = sorted[j] + names[#names+1] = destination + names[#names+1] = pdfreference(destinations[destination]) + end + local first = sorted[i] + local last = sorted[amount] + local limits = pdfarray { + first, + last, + } + local d = pdfdictionary { + Names = names, + Limits = limits, + } + slices[#slices+1] = { + reference = pdfreference(pdfflushobject(d)), + limits = limits, + } + end + local function collectkids(slices,first,last) + local k = pdfarray() + local d = pdfdictionary { + Kids = k, + Limits = pdfarray { + slices[first].limits[1], + slices[last ].limits[2], + }, + } + for i=first,last do + k[#k+1] = slices[i].reference + end + return d + end + if #slices == 1 then + return slices[1].reference + else + while true do + if #slices > maxslice then + local temp = { } + local size = #slices + for i=1,size,maxslice do + local kids = collectkids(slices,i,min(i+maxslice-1,size)) + temp[#temp+1] = { + reference = pdfreference(pdfflushobject(kids)), + limits = kids.Limits, + } + end + slices = temp + else + return pdfreference(pdfflushobject(collectkids(slices,1,#slices))) + end end - return pd end end -lpdf.pagedestination = pagedestination +local function pdfdestinationspecification() + if next(destinations) then -- safeguard + local r = pdfnametree(destinations) +-- pdfaddtocatalog("Dests",r) + pdfaddtonames("Dests",r) + destinations = nil + end +end -local defaultdestination = pdfarray { 0, pdf_fit } +lpdf.nametree = pdfnametree +lpdf.destinationspecification = pdfdestinationspecification + +lpdf.registerdocumentfinalizer(pdfdestinationspecification,"collect destinations") + +-- todo + +local destinations = { } + +local f_xyz = formatters["<< /D [ %i 0 R /XYZ %0.3F %0.3F null ] >>"] +local f_fit = formatters["<< /D [ %i 0 R /Fit ] >>"] +local f_fitb = formatters["<< /D [ %i 0 R /FitB ] >>"] +local f_fith = formatters["<< /D [ %i 0 R /FitH %0.3F ] >>"] +local f_fitv = formatters["<< /D [ %i 0 R /FitV %0.3F ] >>"] +local f_fitbh = formatters["<< /D [ %i 0 R /FitBH %0.3F ] >>"] +local f_fitbv = formatters["<< /D [ %i 0 R /FitBV %0.3F ] >>"] +local f_fitr = formatters["<< /D [ %i 0 R /FitR [%0.3F %0.3F %0.3F %0.3F ] ] >>"] + +-- nicer is to create dictionaries and set properties but overkill +-- +-- local d_xyz = pdfdictionary { +-- D = pdfarray { +-- pdfreference(0), +-- pdfconstant("XYZ"), +-- 0, +-- 0, +-- pdfnull(), +-- } +-- } +-- +-- local function xyz(r,width,height,depth) -- same +-- local llx, lly = pdfrectangle(width,height,depth) +-- d_xyz.D[1][1] = r +-- d_xyz.D[3] = llx +-- d_xyz.D[4] = lly +-- return d_xyz() +-- end + +local destinationactions = { + xyz = function(r,width,height,depth) + local llx, lly = pdfrectangle(width,height,depth) + return f_xyz(r,llx,lly) + end, + fitr = function(r,width,height,depth) + return f_fitr(r,pdfrectangle(width,height,depth)) + end, + fith = function(r) return f_fith (r,getvpos*factor) end, + fitbh = function(r) return f_fitbh(r,getvpos*factor) end, + fitv = function(r) return f_fitv (r,gethpos*factor) end, + fitbv = function(r) return f_fitbv(r,gethpos*factor) end, + fit = f_fit, + fitb = f_fitb, +} + +local mapping = { + xyz = "xyz", [variables.standard] = "xyz", + fitr = "fitr", [variables.frame] = "fitr", + fith = "fith", [variables.width] = "fith", + fitbh = "fitbh", [variables.minwidth] = "fitbh", + fitv = "fitv", [variables.height] = "fitv", + fitbv = "fitbv", [variables.minheight] = "fitbv", + fit = "fit", [variables.fit] = "fit", + fitb = "fitb", +} + +local defaultaction = destinationactions.fit + +-- A complication is that we need to use named destinations when we have views so we +-- end up with a mix. A previous versions just output multiple destinations but not +-- that we noved all to here we can be more sparse. + +local pagedestinations = { } + +table.setmetatableindex(pagedestinations,function(t,k) + local v = pdfdelayedobject(f_fit(k)) + t[k] = v + return v +end) + +local function flushdestination(width,height,depth,names,view) + local r = pdfpagereference(texgetcount("realpageno")) + if view == "fit" then + r = pagedestinations[r] + else + local action = view and destinationactions[view] or defaultaction + r = pdfdelayedobject(action(r,width,height,depth)) + end + for n=1,#names do + local name = names[n] + if name then + pdfregisterdestination(name,r) + end + end +end + +function nodeinjections.destination(width,height,depth,names,view) + -- todo check if begin end node / was comment + if view then + view = mapping[view] or "fit" + else + view = "fit" + end + if trace_destinations then + report_destination("width %p, height %p, depth %p, names %|t, view %a",width,height,depth,names,view) + end + local noview = view ~= "fit" + local doview = false + for n=1,#names do + local name = names[n] + if not destinationviews[name] then + destinationviews[name] = not noview + if type(name) == "number" then + local u = usedinternals[name] + if u then + if not noview then + flaginternals[name] = view + end + if references.innermethod ~= "auto" or u ~= true then + names[n] = "aut:" .. name + doview = true + else + names[n] = false + end + else + names[n] = false + end + else + doview = true + end + end + end + if doview then + return latelua_function_node(function() flushdestination(width,height,depth,names,view) end) + end +end + +local function somedestination(destination,page) + if type(destination) == "number" then + flaginternals[destination] = true + if references.innermethod == "auto" and usedinternals[destination] == true then + return pagereferences[page] + else + return pdfdictionary { -- can be cached + S = pdf_goto, + D = "aut:" .. destination, + } + end + else + if references.innermethod == "auto" and destinationviews[destination] == true then + return pagereferences[page] -- we use a simple one but the destination is there + else + return pdfdictionary { -- can be cached + S = pdf_goto, + D = destination, + } + end + end +end + +-- annotations -local function link(url,filename,destination,page,actions) +local function pdflink(url,filename,destination,page,actions) if filename and filename ~= "" then if file.basename(filename) == tex.jobname then return false @@ -137,30 +438,12 @@ local function link(url,filename,destination,page,actions) NewWindow = (actions.newwindow and true) or nil, } elseif destination and destination ~= "" then - return pdfdictionary { -- can be cached - S = pdf_goto, - D = destination, - } - else - local p = tonumber(page) - if p and p > 0 then - return pdfdictionary { -- can be cached - S = pdf_goto, - D = pdfarray { - pdfreference(pdfpagereference(p)), - pdf_fit, - } - } - elseif trace_references then - report_reference("invalid page reference %a",page) - end + return somedestination(destination,page) end - return false + return pagereferences[page] -- we use a simple one but the destination is there end -lpdf.link = link - -function lpdf.launch(program,parameters) +local function pdflaunch(program,parameters) if program and program ~= "" then local d = pdfdictionary { S = pdf_launch, @@ -174,7 +457,7 @@ function lpdf.launch(program,parameters) end end -function lpdf.javascript(name,arguments) +local function pdfjavascript(name,arguments) local script = javascriptcode(name,arguments) -- make into object (hash) if script then return pdfdictionary { @@ -184,6 +467,10 @@ function lpdf.javascript(name,arguments) end end +lpdf.link = pdflink +lpdf.launch = pdflaunch +lpdf.javascript = pdfjavascript + local function pdfaction(actions) local nofactions = #actions if nofactions > 0 then @@ -231,144 +518,134 @@ function codeinjections.prerollreference(actions) -- share can become option end end -local function use_normal_annotations() - - local function reference(width,height,depth,prerolled) -- keep this one - if prerolled then - if trace_references then - report_reference("width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) - end - return pdfannotation_node(width,height,depth,prerolled) - end - end - - local function finishreference() - end - - return reference, finishreference - -end +-- local function use_normal_annotations() +-- +-- local function reference(width,height,depth,prerolled) -- keep this one +-- if prerolled then +-- if trace_references then +-- report_reference("width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) +-- end +-- return pdfannotation_node(width,height,depth,prerolled) +-- end +-- end +-- +-- local function finishreference() +-- end +-- +-- return reference, finishreference +-- +-- end -- eventually we can do this for special refs only -local hashed, nofunique, nofused = { }, 0, 0 - -local f_annot = formatters["<< /Type /Annot %s /Rect [%0.3f %0.3f %0.3f %0.3f] >>"] -local f_bpnf = formatters["_bpnf_(%s,%s,%s,'%s')"] +local hashed = { } +local nofunique = 0 +local nofused = 0 +local nofspecial = 0 +local share = true -local function use_shared_annotations() +local f_annot = formatters["<< /Type /Annot %s /Rect [%0.3F %0.3F %0.3F %0.3F] >>"] - local factor = number.dimenfactors.bp +directives.register("refences.sharelinks", function(v) share = v end) - local function finishreference(width,height,depth,prerolled) -- %0.2f looks okay enough (no scaling anyway) - local h, v = pdf.h, pdf.v - local llx, lly = h*factor, (v - depth)*factor - local urx, ury = (h + width)*factor, (v + height)*factor - local annot = f_annot(prerolled,llx,lly,urx,ury) - local n = hashed[annot] - if not n then - n = pdfdelayedobject(annot) - hashed[annot] = n - nofunique = nofunique + 1 - end - nofused = nofused + 1 - pdfregisterannotation(n) +table.setmetatableindex(hashed,function(t,k) + local v = pdfdelayedobject(k) + if share then + t[k] = v end + nofunique = nofunique + 1 + return v +end) + +local function finishreference(width,height,depth,prerolled) -- %0.2f looks okay enough (no scaling anyway) + local annot = hashed[f_annot(prerolled,pdfrectangle(width,height,depth))] + nofused = nofused + 1 + return pdfregisterannotation(annot) +end - _bpnf_ = finishreference - - local function reference(width,height,depth,prerolled) - if prerolled then - if trace_references then - report_reference("width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) - end - local luacode = f_bpnf(width,height,depth,prerolled) - return latelua_node(luacode) - end +local function finishannotation(width,height,depth,prerolled,r) + local annot = f_annot(prerolled,pdfrectangle(width,height,depth)) + if r then + pdfdelayedobject(annot,r) + else + r = pdfdelayedobject(annot) end + nofspecial = nofspecial + 1 + return pdfregisterannotation(r) +end - statistics.register("pdf annotations", function() - if nofused > 0 then - return format("%s embedded, %s unique",nofused,nofunique) - else - return nil +function nodeinjections.reference(width,height,depth,prerolled) + if prerolled then + if trace_references then + report_reference("link: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) end - end) - - - return reference, finishreference - + return latelua_function_node(function() finishreference(width,height,depth,prerolled) end) + end end -local lln = latelua_node() if node.has_field(lln,'string') then - - directives.register("refences.sharelinks", function(v) - if v then - nodeinjections.reference, codeinjections.finishreference = use_shared_annotations() - else - nodeinjections.reference, codeinjections.finishreference = use_normal_annotations() +function nodeinjections.annotation(width,height,depth,prerolled,r) + if prerolled then + if trace_references then + report_reference("special: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) end - end) + return latelua_function_node(function() finishannotation(width,height,depth,prerolled,r or false) end) + end +end - nodeinjections.reference, codeinjections.finishreference = use_shared_annotations() +-- beware, we register during a latelua sweep so we have to make sure that +-- we finalize after that (also in a latelua for the moment as we have no +-- callback yet) -else +local annotations = nil - nodeinjections.reference, codeinjections.finishreference = use_normal_annotations() +function lpdf.registerannotation(n) + if annotations then + annotations[#annotations+1] = pdfreference(n) + else + annotations = pdfarray { pdfreference(n) } -- no need to use lpdf.array cum suis + end +end -end node.free(lln) +pdfregisterannotation = lpdf.registerannotation --- -- -- -- --- -- -- -- +function lpdf.annotationspecification() + if annotations then + local r = pdfdelayedobject(tostring(annotations)) -- delayed so okay in latelua + pdfaddtopageattributes("Annots",pdfreference(r)) + annotations = nil + end +end -local done = { } -- prevent messages +lpdf.registerpagefinalizer(lpdf.annotationspecification,"finalize annotations") -function nodeinjections.destination(width,height,depth,name,view) - if not done[name] then - done[name] = true - if trace_destinations then - report_destination("width %p, height %p, depth %p, name %a, view %a",width,height,depth,name,view) - end - return pdfdestination_node(width,height,depth,name,view) -- can be begin/end node +statistics.register("pdf annotations", function() + if nofused > 0 or nofspecial > 0 then + return format("%s links (%s unique), %s special",nofused,nofunique,nofspecial) + else + return nil end -end +end) -- runners and specials --- runners["inner"] = function(var,actions) --- if getinnermethod() == "names" then --- local vi = var.i --- if vi then --- local vir = vi.references --- if vir then --- local internal = vir.internal --- if internal then --- var.inner = "aut:" .. internal --- end --- end --- end --- else --- var.inner = nil --- end --- local prefix = var.p --- local inner = var.inner --- if inner and prefix and prefix ~= "" then --- inner = prefix .. ":" .. inner -- might not always be ok --- end --- return link(nil,nil,inner,var.r,actions) --- end - runners["inner"] = function(var,actions) local internal = false - if getinnermethod() == "names" then + local method = references.innermethod + if method == "names" or method == "auto" then local vi = var.i if vi then local vir = vi.references if vir then -- todo: no need for it when we have a real reference - internal = vir.internal - if internal then - var.inner = "aut:" .. internal + local reference = vir.reference + if reference and reference ~= "" then + var.inner = reference + else + internal = vir.internal + if internal then + var.inner = internal + flaginternals[internal] = true + end end end end @@ -381,7 +658,7 @@ runners["inner"] = function(var,actions) -- no prefix with e.g. components inner = prefix .. ":" .. inner end - return link(nil,nil,inner,var.r,actions) + return pdflink(nil,nil,inner,var.r,actions) end runners["inner with arguments"] = function(var,actions) @@ -391,12 +668,12 @@ end runners["outer"] = function(var,actions) local file, url = references.checkedfileorurl(var.outer,var.outer) - return link(url,file,var.arguments,nil,actions) + return pdflink(url,file,var.arguments,nil,actions) end runners["outer with inner"] = function(var,actions) local file = references.checkedfile(var.outer) -- was var.f but fails ... why - return link(nil,file,var.inner,var.r,actions) + return pdflink(nil,file,var.inner,var.r,actions) end runners["special outer with operation"] = function(var,actions) @@ -443,12 +720,23 @@ function specials.internal(var,actions) -- better resolve in strc-ref if not v then -- error report_reference("no internal reference %a",i) - elseif getinnermethod() == "names" then - -- named - return link(nil,nil,"aut:"..i,v.references.realpage,actions) else - -- page - return link(nil,nil,nil,v.references.realpage,actions) + flaginternals[i] = true + local method = references.innermethod + if method == "names" then + -- named + return pdflink(nil,nil,i,v.references.realpage,actions) + elseif method == "auto" then + -- named + if usedinternals[i] == true then + return pdflink(nil,nil,nil,v.references.realpage,actions) + else + return pdflink(nil,nil,i,v.references.realpage,actions) + end + else + -- page + return pdflink(nil,nil,nil,v.references.realpage,actions) + end end end @@ -462,7 +750,7 @@ function specials.page(var,actions) local file = var.f if file then file = references.checkedfile(file) - return link(nil,file,nil,var.operation,actions) + return pdflink(nil,file,nil,var.operation,actions) else local p = var.r if not p then -- todo: call special from reference code @@ -476,7 +764,7 @@ function specials.page(var,actions) -- var.r = p -- end end - return link(nil,nil,nil,p or var.operation,actions) + return pdflink(nil,nil,nil,p or var.operation,actions) end end @@ -484,9 +772,9 @@ function specials.realpage(var,actions) local file = var.f if file then file = references.checkedfile(file) - return link(nil,file,nil,var.operation,actions) + return pdflink(nil,file,nil,var.operation,actions) else - return link(nil,nil,nil,var.operation,actions) + return pdflink(nil,nil,nil,var.operation,actions) end end @@ -494,7 +782,7 @@ function specials.userpage(var,actions) local file = var.f if file then file = references.checkedfile(file) - return link(nil,file,nil,var.operation,actions) + return pdflink(nil,file,nil,var.operation,actions) else local p = var.r if not p then -- todo: call special from reference code @@ -506,7 +794,7 @@ function specials.userpage(var,actions) -- var.r = p -- end end - return link(nil,nil,nil,p or var.operation,actions) + return pdflink(nil,nil,nil,p or var.operation,actions) end end @@ -514,7 +802,7 @@ function specials.deltapage(var,actions) local p = tonumber(var.operation) if p then p = references.checkedrealpage(p + texgetcount("realpageno")) - return link(nil,nil,nil,p,actions) + return pdflink(nil,nil,nil,p,actions) end end @@ -555,26 +843,26 @@ end function specials.url(var,actions) local url = references.checkedurl(var.operation) - return link(url,nil,var.arguments,nil,actions) + return pdflink(url,nil,var.arguments,nil,actions) end function specials.file(var,actions) local file = references.checkedfile(var.operation) - return link(nil,file,var.arguments,nil,actions) + return pdflink(nil,file,var.arguments,nil,actions) end function specials.fileorurl(var,actions) local file, url = references.checkedfileorurl(var.operation,var.operation) - return link(url,file,var.arguments,nil,actions) + return pdflink(url,file,var.arguments,nil,actions) end function specials.program(var,content) local program = references.checkedprogram(var.operation) - return lpdf.launch(program,var.arguments) + return pdflaunch(program,var.arguments) end function specials.javascript(var) - return lpdf.javascript(var.operation,var.arguments) + return pdfjavascript(var.operation,var.arguments) end specials.JS = specials.javascript @@ -698,11 +986,6 @@ function specials.action(var) end end ---~ entry.A = pdfdictionary { ---~ S = pdf_goto, ---~ D = .... ---~ } - local function build(levels,start,parent,method) local startlevel = levels[start][1] local i, n = start, 0 @@ -728,11 +1011,7 @@ local function build(levels,start,parent,method) Parent = parent, Prev = prev and pdfreference(prev), } - if method == "internal" then - entry.Dest = "aut:" .. reference.internal - else -- if method == "page" then - entry.Dest = pagedestination(reference.realpage) - end + entry.Dest = somedestination(reference.internal,reference.realpage) if not first then first, last = child, child end prev = child last = prev @@ -771,10 +1050,10 @@ function codeinjections.addbookmarks(levels,method) Count = m, } pdfflushobject(parent,dict) - lpdf.addtocatalog("Outlines",lpdf.reference(parent)) + pdfaddtocatalog("Outlines",lpdf.reference(parent)) end end -- this could also be hooked into the frontend finalizer -lpdf.registerdocumentfinalizer(function() bookmarks.place() end,1,"bookmarks") +lpdf.registerdocumentfinalizer(function() bookmarks.place() end,1,"bookmarks") -- hm, why indirect call diff --git a/tex/context/base/lpdf-col.lua b/tex/context/base/lpdf-col.lua index b358d0820..b2d508611 100644 --- a/tex/context/base/lpdf-col.lua +++ b/tex/context/base/lpdf-col.lua @@ -14,42 +14,48 @@ local formatters = string.formatters local backends, lpdf, nodes = backends, lpdf, nodes -local allocate = utilities.storage.allocate -local formatters = string.formatters - -local nodeinjections = backends.pdf.nodeinjections -local codeinjections = backends.pdf.codeinjections -local registrations = backends.pdf.registrations - -local nodepool = nodes.pool -local register = nodepool.register -local pdfliteral = nodepool.pdfliteral - -local pdfconstant = lpdf.constant -local pdfstring = lpdf.string -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfverbose = lpdf.verbose -local pdfflushobject = lpdf.flushobject -local pdfflushstreamobject = lpdf.flushstreamobject - -local colors = attributes.colors -local transparencies = attributes.transparencies -local registertransparancy = transparencies.register -local registercolor = colors.register -local colorsvalue = colors.value -local transparenciesvalue = transparencies.value -local forcedmodel = colors.forcedmodel - -local c_transparency = pdfconstant("Transparency") - -local f_gray = formatters["%.3f g %.3f G"] -local f_rgb = formatters["%.3f %.3f %.3f rg %.3f %.3f %.3f RG"] -local f_cmyk = formatters["%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K"] +local allocate = utilities.storage.allocate +local formatters = string.formatters + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations + +local nodepool = nodes.pool +local register = nodepool.register +local pdfliteral = nodepool.pdfliteral + +local pdfconstant = lpdf.constant +local pdfstring = lpdf.string +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfverbose = lpdf.verbose +local pdfflushobject = lpdf.flushobject +local pdfflushstreamobject = lpdf.flushstreamobject + +local pdfshareobjectreference = lpdf.shareobjectreference + +local addtopageattributes = lpdf.addtopageattributes +local adddocumentcolorspace = lpdf.adddocumentcolorspace +local adddocumentextgstate = lpdf.adddocumentextgstate + +local colors = attributes.colors +local transparencies = attributes.transparencies +local registertransparancy = transparencies.register +local registercolor = colors.register +local colorsvalue = colors.value +local transparenciesvalue = transparencies.value +local forcedmodel = colors.forcedmodel + +local c_transparency = pdfconstant("Transparency") + +local f_gray = formatters["%.3F g %.3F G"] +local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"] +local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"] local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"] local f_tr = formatters["Tr%s"] -local f_cm = formatters["q %f %f %f %f %f %f cm"] +local f_cm = formatters["q %F %F %F %F %F %F cm"] local f_effect = formatters["%s Tc %s w %s Tr"] local f_tr_gs = formatters["/Tr%s gs"] local f_num_1 = tostring @@ -95,7 +101,7 @@ local function addpagegroup() if currentgroupcolormodel then local g = transparencygroups[currentgroupcolormodel] if g then - lpdf.addtopageattributes("Group",g) + addtopageattributes("Group",g) end end end @@ -224,7 +230,7 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range, local mr = pdfreference(m) spotcolorhash[name] = m documentcolorspaces[name] = mr - lpdf.adddocumentcolorspace(name,mr) + adddocumentcolorspace(name,mr) else local cnames = pdfarray() local domain = pdfarray() @@ -280,13 +286,13 @@ local function registersomespotcolor(name,noffractions,names,p,colorspace,range, cnames, colorspace, pdfreference(calculation), - lpdf.shareobjectreference(tostring(channels)), -- optional but needed for shades + pdfshareobjectreference(tostring(channels)), -- optional but needed for shades } local m = pdfflushobject(array) local mr = pdfreference(m) spotcolorhash[name] = m documentcolorspaces[name] = mr - lpdf.adddocumentcolorspace(name,mr) + adddocumentcolorspace(name,mr) end end @@ -336,7 +342,7 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range end vector = pdfverbose { "<", concat(vector, " "), ">" } local n = pdfflushobject(pdfarray{ pdf_indexed, a, 255, vector }) - lpdf.adddocumentcolorspace(format("%s_indexed",name),pdfreference(n)) + adddocumentcolorspace(format("%s_indexed",name),pdfreference(n)) return n end @@ -455,7 +461,7 @@ function registrations.transparency(n,a,t) local mr = pdfreference(m) transparencyhash[0] = m documenttransparencies[0] = mr - lpdf.adddocumentextgstate("Tr0",mr) + adddocumentextgstate("Tr0",mr) done = true end if n > 0 and not transparencyhash[n] then @@ -470,7 +476,7 @@ function registrations.transparency(n,a,t) local mr = pdfreference(m) transparencyhash[n] = m documenttransparencies[n] = mr - lpdf.adddocumentextgstate(f_tr(n),mr) + adddocumentextgstate(f_tr(n),mr) end end @@ -689,7 +695,7 @@ end -- this will move to lpdf-spe.lua -local f_slant = formatters["pdf: q 1 0 %f 1 0 0 cm"] +local f_slant = formatters["pdf: q 1 0 %F 1 0 0 cm"] backends.pdf.tables.vfspecials = allocate { -- todo: distinguish between glyph and rule color diff --git a/tex/context/base/lpdf-fld.lua b/tex/context/base/lpdf-fld.lua index a9b9fd72d..fc5a11c43 100644 --- a/tex/context/base/lpdf-fld.lua +++ b/tex/context/base/lpdf-fld.lua @@ -55,7 +55,8 @@ if not modules then modules = { } end modules ['lpdf-fld'] = { -- for printing especially when highlighting (those colorfull foregrounds) is -- on. -local gmatch, lower, format = string.gmatch, string.lower, string.format +local tostring, next = tostring, next +local gmatch, lower, format, formatters = string.gmatch, string.lower, string.format, string.formatters local lpegmatch = lpeg.match local utfchar = utf.char local bpfactor, todimen = number.dimenfactors.bp, string.todimen @@ -92,14 +93,13 @@ local pdfflushobject = lpdf.flushobject local pdfshareobjectreference = lpdf.shareobjectreference local pdfshareobject = lpdf.shareobject local pdfreserveobject = lpdf.reserveobject -local pdfreserveannotation = lpdf.reserveannotation local pdfaction = lpdf.action -local hpack_node = node.hpack - -local nodepool = nodes.pool +local pdfcolor = lpdf.color +local pdfcolorvalues = lpdf.colorvalues +local pdflayerreference = lpdf.layerreference -local pdfannotation_node = nodepool.pdfannotation +local hpack_node = node.hpack local submitoutputformat = 0 -- 0=unknown 1=HTML 2=FDF 3=XML => not yet used, needs to be checked @@ -125,39 +125,39 @@ function codeinjections.setformsmethod(name) end local flag = { -- /Ff - ReadOnly = 1, -- 1 - Required = 2, -- 2 - NoExport = 4, -- 3 - MultiLine = 4096, -- 13 - Password = 8192, -- 14 - NoToggleToOff = 16384, -- 15 - Radio = 32768, -- 16 - PushButton = 65536, -- 17 - PopUp = 131072, -- 18 - Edit = 262144, -- 19 - Sort = 524288, -- 20 - FileSelect = 1048576, -- 21 - DoNotSpellCheck = 4194304, -- 23 - DoNotScroll = 8388608, -- 24 - Comb = 16777216, -- 25 - RichText = 33554432, -- 26 - RadiosInUnison = 33554432, -- 26 - CommitOnSelChange = 67108864, -- 27 + ReadOnly = 2^ 0, -- 1 + Required = 2^ 1, -- 2 + NoExport = 2^ 2, -- 3 + MultiLine = 2^12, -- 13 + Password = 2^13, -- 14 + NoToggleToOff = 2^14, -- 15 + Radio = 2^15, -- 16 + PushButton = 2^16, -- 17 + PopUp = 2^17, -- 18 + Edit = 2^18, -- 19 + Sort = 2^19, -- 20 + FileSelect = 2^20, -- 21 + DoNotSpellCheck = 2^22, -- 23 + DoNotScroll = 2^23, -- 24 + Comb = 2^24, -- 25 + RichText = 2^25, -- 26 + RadiosInUnison = 2^25, -- 26 + CommitOnSelChange = 2^26, -- 27 } local plus = { -- /F - Invisible = 1, -- 1 - Hidden = 2, -- 2 - Printable = 4, -- 3 - Print = 4, -- 3 - NoZoom = 8, -- 4 - NoRotate = 16, -- 5 - NoView = 32, -- 6 - ReadOnly = 64, -- 7 - Locked = 128, -- 8 - ToggleNoView = 256, -- 9 - LockedContents = 512, -- 10, - AutoView = 256, -- 288 (6+9) + Invisible = 2^0, -- 1 + Hidden = 2^1, -- 2 + Printable = 2^2, -- 3 + Print = 2^2, -- 3 + NoZoom = 2^3, -- 4 + NoRotate = 2^4, -- 5 + NoView = 2^5, -- 6 + ReadOnly = 2^6, -- 7 + Locked = 2^7, -- 8 + ToggleNoView = 2^8, -- 9 + LockedContents = 2^9, -- 10, + AutoView = 2^8, -- 6 + 9 ? } -- todo: check what is interfaced @@ -198,33 +198,82 @@ local function fieldplus(specification) -- /F return n end -local function checked(what) - local set, bug = references.identify("",what) - if not bug and #set > 0 then - local r, n = pdfaction(set) - return pdfshareobjectreference(r) - end -end +-- keep: +-- +-- local function checked(what) +-- local set, bug = references.identify("",what) +-- if not bug and #set > 0 then +-- local r, n = pdfaction(set) +-- return pdfshareobjectreference(r) +-- end +-- end +-- +-- local function fieldactions(specification) -- share actions +-- local d, a = { }, nil +-- a = specification.mousedown +-- or specification.clickin if a and a ~= "" then d.D = checked(a) end +-- a = specification.mouseup +-- or specification.clickout if a and a ~= "" then d.U = checked(a) end +-- a = specification.regionin if a and a ~= "" then d.E = checked(a) end -- Enter +-- a = specification.regionout if a and a ~= "" then d.X = checked(a) end -- eXit +-- a = specification.afterkey if a and a ~= "" then d.K = checked(a) end +-- a = specification.format if a and a ~= "" then d.F = checked(a) end +-- a = specification.validate if a and a ~= "" then d.V = checked(a) end +-- a = specification.calculate if a and a ~= "" then d.C = checked(a) end +-- a = specification.focusin if a and a ~= "" then d.Fo = checked(a) end +-- a = specification.focusout if a and a ~= "" then d.Bl = checked(a) end +-- a = specification.openpage if a and a ~= "" then d.PO = checked(a) end +-- a = specification.closepage if a and a ~= "" then d.PC = checked(a) end +-- -- a = specification.visiblepage if a and a ~= "" then d.PV = checked(a) end +-- -- a = specification.invisiblepage if a and a ~= "" then d.PI = checked(a) end +-- return next(d) and pdfdictionary(d) +-- end + +local mapping = { + mousedown = "D", clickin = "D", + mouseup = "U", clickout = "U", + regionin = "E", + regionout = "X", + afterkey = "K", + format = "F", + validate = "V", + calculate = "C", + focusin = "Fo", + focusout = "Bl", + openpage = "PO", + closepage = "PC", + -- visiblepage = "PV", + -- invisiblepage = "PI", +} local function fieldactions(specification) -- share actions - local d, a = { }, nil - a = specification.mousedown - or specification.clickin if a and a ~= "" then d.D = checked(a) end - a = specification.mouseup - or specification.clickout if a and a ~= "" then d.U = checked(a) end - a = specification.regionin if a and a ~= "" then d.E = checked(a) end -- Enter - a = specification.regionout if a and a ~= "" then d.X = checked(a) end -- eXit - a = specification.afterkey if a and a ~= "" then d.K = checked(a) end - a = specification.format if a and a ~= "" then d.F = checked(a) end - a = specification.validate if a and a ~= "" then d.V = checked(a) end - a = specification.calculate if a and a ~= "" then d.C = checked(a) end - a = specification.focusin if a and a ~= "" then d.Fo = checked(a) end - a = specification.focusout if a and a ~= "" then d.Bl = checked(a) end - a = specification.openpage if a and a ~= "" then d.PO = checked(a) end - a = specification.closepage if a and a ~= "" then d.PC = checked(a) end - -- a = specification.visiblepage if a and a ~= "" then d.PV = checked(a) end - -- a = specification.invisiblepage if a and a ~= "" then d.PI = checked(a) end - return next(d) and pdfdictionary(d) + local d = nil + for key, target in next, mapping do + local code = specification[key] + if code and code ~= "" then + -- local a = checked(code) + local set, bug = references.identify("",code) + if not bug and #set > 0 then + local a = pdfaction(set) -- r, n + if a then + local r = pdfshareobjectreference(a) + if d then + d[target] = r + else + d = pdfdictionary { [target] = r } + end + else + report_fields("invalid field action %a, case %s",code,2) + end + else + report_fields("invalid field action %a, case %s",code,1) + end + end + end + -- if d then + -- d = pdfshareobjectreference(d) -- not much overlap or maybe only some patterns + -- end + return d end -- fonts and color @@ -298,16 +347,16 @@ local function fieldsurrounding(specification) fontsize = todimen(fontsize) fontsize = fontsize and (bpfactor * fontsize) or 12 fontraise = 0.1 * fontsize -- todo: figure out what the natural one is and compensate for strutdp - local fontcode = format("%0.4f Tf %0.4f Ts",fontsize,fontraise) + local fontcode = formatters["%0.4f Tf %0.4f Ts"](fontsize,fontraise) -- we could test for colorvalue being 1 (black) and omit it then - local colorcode = lpdf.color(3,colorvalue) -- we force an rgb color space + local colorcode = pdfcolor(3,colorvalue) -- we force an rgb color space if trace_fields then report_fields("using font, style %a, alternative %a, size %p, tag %a, code %a",fontstyle,fontalternative,fontsize,tag,fontcode) report_fields("using color, value %a, code %a",colorvalue,colorcode) end local stream = pdfstream { pdfconstant(tag), - format("%s %s",fontcode,colorcode) + formatters["%s %s"](fontcode,colorcode) } usedfonts[tag] = a -- the name -- move up with "x.y Ts" @@ -579,8 +628,8 @@ local function fieldrendering(specification) local svalue = specification.fontsymbol if bvalue or fvalue or (svalue and svalue ~= "") then return pdfdictionary { - BG = bvalue and pdfarray { lpdf.colorvalues(3,bvalue) } or nil, -- or zero_bg, - BC = fvalue and pdfarray { lpdf.colorvalues(3,fvalue) } or nil, -- or zero_bc, + BG = bvalue and pdfarray { pdfcolorvalues(3,bvalue) } or nil, -- or zero_bg, + BC = fvalue and pdfarray { pdfcolorvalues(3,fvalue) } or nil, -- or zero_bc, CA = svalue and pdfstring (svalue) or nil, } end @@ -590,7 +639,7 @@ end local function fieldlayer(specification) -- we can move this in line local layer = specification.layer - return (layer and lpdf.layerreference(layer)) or nil + return (layer and pdflayerreference(layer)) or nil end -- defining @@ -611,7 +660,7 @@ local xfdftemplate = [[ function codeinjections.exportformdata(name) local result = { } for k, v in table.sortedhash(fields) do - result[#result+1] = format(" %s",v.name or k,v.default or "") + result[#result+1] = formatters[" %s"](v.name or k,v.default or "") end local base = file.basename(tex.jobname) local xfdf = format(xfdftemplate,base,table.concat(result,"\n")) @@ -912,7 +961,7 @@ local function save_parent(field,specification,d,hasopt) end local function save_kid(field,specification,d,optname) - local kn = pdfreserveannotation() + local kn = pdfreserveobject() field.kids[#field.kids+1] = pdfreference(kn) if optname then local opt = field.opt @@ -921,7 +970,7 @@ local function save_kid(field,specification,d,optname) end end local width, height, depth = specification.width or 0, specification.height or 0, specification.depth - local box = hpack_node(pdfannotation_node(width,height,depth,d(),kn)) + local box = hpack_node(nodeinjections.annotation(width,height,depth,d(),kn)) box.width, box.height, box.depth = width, height, depth -- redundant return box end @@ -969,6 +1018,8 @@ local function makelinechild(name,specification) if trace_fields then report_fields("using child text %a",name) end + -- we could save a little by not setting some key/value when it's the + -- same as parent but it would cost more memory to keep track of it local d = pdfdictionary { Subtype = pdf_widget, Parent = pdfreference(parent.pobj), diff --git a/tex/context/base/lpdf-fmt.lua b/tex/context/base/lpdf-fmt.lua index b444f03c3..568b801b4 100644 --- a/tex/context/base/lpdf-fmt.lua +++ b/tex/context/base/lpdf-fmt.lua @@ -349,7 +349,7 @@ local filenames = { } local function locatefile(filename) - local fullname = resolvers.findfile(filename,"icc") + local fullname = resolvers.findfile(filename,"icc",1,true) if not fullname or fullname == "" then fullname = resolvers.finders.byscheme("loc",filename) -- could be specific to the project end @@ -743,7 +743,7 @@ end function codeinjections.supportedformats() local t = { } for k, v in table.sortedhash(formats) do - if find(k,"pdf") then + if find(k,"pdf",1,true) then t[#t+1] = k end end diff --git a/tex/context/base/lpdf-grp.lua b/tex/context/base/lpdf-grp.lua index fed5e6a46..befe52c76 100644 --- a/tex/context/base/lpdf-grp.lua +++ b/tex/context/base/lpdf-grp.lua @@ -236,7 +236,7 @@ function img.package(image) -- see lpdf-u3d ** local height = boundingbox[4] local xform = img.scan { attr = resources(), - stream = format("%f 0 0 %f 0 0 cm /%s Do",width,height,imagetag), + stream = format("%F 0 0 %F 0 0 cm /%s Do",width,height,imagetag), bbox = { 0, 0, width/factor, height/factor }, } img.immediatewrite(xform) diff --git a/tex/context/base/lpdf-ini.lua b/tex/context/base/lpdf-ini.lua index 23fe6c177..34825698c 100644 --- a/tex/context/base/lpdf-ini.lua +++ b/tex/context/base/lpdf-ini.lua @@ -9,15 +9,28 @@ if not modules then modules = { } end modules ['lpdf-ini'] = { local setmetatable, getmetatable, type, next, tostring, tonumber, rawset = setmetatable, getmetatable, type, next, tostring, tonumber, rawset local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string.byte, string.format, string.gsub, table.concat, string.match, string.sub, string.gmatch local utfchar, utfvalues = utf.char, utf.values -local sind, cosd, floor = math.sind, math.cosd, math.floor +local sind, cosd, floor, max, min = math.sind, math.cosd, math.floor, math.max, math.min local lpegmatch, P, C, R, S, Cc, Cs = lpeg.match, lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs local formatters = string.formatters +-- pdf.mapfile pdf.mapline (todo: used in font-ctx.lua) +-- pdf.getpos pdf.gethpos pdf.getvpos +-- pdf.reserveobj pdf.immediateobj pdf.obj pdf.refobj +-- pdf.pageref +-- pdf.catalog pdf.info pdf.names pdf.trailer + +local backends = backends +local pdf = pdf +lpdf = lpdf or { } +local lpdf = lpdf + local pdfreserveobject = pdf.reserveobj local pdfimmediateobject = pdf.immediateobj local pdfdeferredobject = pdf.obj local pdfreferenceobject = pdf.refobj +local factor = number.dimenfactors.bp + local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end) @@ -26,8 +39,6 @@ local trace_detail = false trackers.register("backend.detail", function local report_objects = logs.reporter("backend","objects") local report_finalizing = logs.reporter("backend","finalizing") -local backends = backends - backends.pdf = backends.pdf or { comment = "backend for directly generating pdf output", nodeinjections = { }, @@ -36,8 +47,76 @@ backends.pdf = backends.pdf or { tables = { }, } -lpdf = lpdf or { } -local lpdf = lpdf +-- first some helpers + +local codeinjections = backends.pdf.codeinjections + +local pdfgetpos, pdfgethpos, pdfgetvpos, pdfhasmatrix, pdfgetmatrix + +if pdf.getpos then + pdfgetpos = pdf.getpos + pdfgethpos = pdf.gethpos + pdfgetvpos = pdf.getvpos + pdfgetmatrix = pdf.getmatrix + pdfhasmatrix = pdf.hasmatrix +else + if pdf.h then + function pdfgetpos () return pdf.h, pdf.v end + function pdfgethpos() return pdf.h end + function pdfgetvpos() return pdf.v end + end + function pdfhasmatrix() return false end + function pdfgetmatrix() return 1, 0, 0, 1, 0, 0 end +end + +codeinjections.getpos = pdfgetpos lpdf.getpos = pdfgetpos +codeinjections.gethpos = pdfgethpos lpdf.gethpos = pdfgethpos +codeinjections.getvpos = pdfgetvpos lpdf.getvpos = pdfgetvpos +codeinjections.hasmatrix = pdfhasmatrix lpdf.hasmatrix = pdfhasmatrix +codeinjections.getmatrix = pdfgetmatrix lpdf.getmatrix = pdfgetmatrix + +function lpdf.transform(llx,lly,urx,ury) + if pdfhasmatrix() then + local sx, rx, ry, sy = pdfgetmatrix() + local w, h = urx - llx, ury - lly + return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w + else + return llx, lly, urx, ury + end +end + +-- function lpdf.rectangle(width,height,depth) +-- local h, v = pdfgetpos() +-- local llx, lly, urx, ury +-- if pdfhasmatrix() then +-- local sx, rx, ry, sy = pdfgetmatrix() +-- llx = 0 +-- lly = -depth +-- -- llx = ry * depth +-- -- lly = -sx * depth +-- urx = sy * width - ry * height +-- ury = sx * height - rx * width +-- else +-- llx = 0 +-- lly = -depth +-- urx = width +-- ury = height +-- return (h+llx)*factor, (v+lly)*factor, (h+urx)*factor, (v+ury)*factor +-- end +-- end + +function lpdf.rectangle(width,height,depth) + local h, v = pdfgetpos() + if pdfhasmatrix() then + local sx, rx, ry, sy = pdfgetmatrix() + -- return (h+ry*depth)*factor, (v-sx*depth)*factor, (h+sy*width-ry*height)*factor, (v+sx*height-rx*width)*factor + return h *factor, (v- depth)*factor, (h+sy*width-ry*height)*factor, (v+sx*height-rx*width)*factor + else + return h *factor, (v- depth)*factor, (h+ width )*factor, (v+ height )*factor + end +end + +-- local function tosixteen(str) -- an lpeg might be faster (no table) if not str or str == "" then @@ -91,13 +170,13 @@ end lpdf.toeight = toeight ---~ local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/function(s) return format("#%02X",byte(s)) end + lpeg.P(1))^0) - ---~ local function cleaned(str) ---~ return (str and str ~= "" and lpegmatch(escaped,str)) or "" ---~ end - ---~ lpdf.cleaned = cleaned -- not public yet +-- local escaped = lpeg.Cs((lpeg.S("\0\t\n\r\f ()[]{}/%")/function(s) return format("#%02X",byte(s)) end + lpeg.P(1))^0) +-- +-- local function cleaned(str) +-- return (str and str ~= "" and lpegmatch(escaped,str)) or "" +-- end +-- +-- lpdf.cleaned = cleaned -- not public yet local function merge_t(a,b) local t = { } @@ -112,16 +191,16 @@ local f_dictionary = formatters["<< % t >>"] local f_key_array = formatters["/%s [ % t ]"] local f_array = formatters["[ % t ]"] +-- local f_key_value = formatters["/%s %s"] +-- local f_key_dictionary = formatters["/%s <<% t>>"] +-- local f_dictionary = formatters["<<% t>>"] +-- local f_key_array = formatters["/%s [% t]"] +-- local f_array = formatters["[% t]"] + local tostring_a, tostring_d tostring_d = function(t,contentonly,key) - if not next(t) then - if contentonly then - return "" - else - return "<< >>" - end - else + if next(t) then local r, rn = { }, 0 for k, v in next, t do rn = rn + 1 @@ -150,18 +229,16 @@ tostring_d = function(t,contentonly,key) else return f_dictionary(r) end + elseif contentonly then + return "" + else + return "<< >>" end end tostring_a = function(t,contentonly,key) local tn = #t - if tn == 0 then - if contentonly then - return "" - else - return "[ ]" - end - else + if tn ~= 0 then local r = { } for k=1,tn do local v = t[k] @@ -191,10 +268,14 @@ tostring_a = function(t,contentonly,key) else return f_array(r) end + elseif contentonly then + return "" + else + return "[ ]" end end -local tostring_x = function(t) return concat(t, " ") end +local tostring_x = function(t) return concat(t," ") end local tostring_s = function(t) return toeight(t[1]) end local tostring_u = function(t) return tosixteen(t[1]) end local tostring_n = function(t) return tostring(t[1]) end -- tostring not needed @@ -207,7 +288,7 @@ local tostring_r = function(t) local n = t[1] return n and n > 0 and (n .. " 0 R local tostring_v = function(t) local s = t[1] if type(s) == "table" then - return concat(s,"") + return concat(s) else return s end @@ -325,12 +406,27 @@ local function pdfboolean(b,default) end end -local function pdfreference(r) - return setmetatable({ r or 0 },mt_r) +local r_zero = setmetatable({ 0 },mt_r) + +local function pdfreference(r) -- maybe make a weak table + if r and r ~= 0 then + return setmetatable({ r },mt_r) + else + return r_zero + end end +local v_zero = setmetatable({ 0 },mt_v) +local v_empty = setmetatable({ "" },mt_v) + local function pdfverbose(t) -- maybe check for type - return setmetatable({ t or "" },mt_v) + if t == 0 then + return v_zero + elseif t == "" then + return v_empty + else + return setmetatable({ t },mt_v) + end end lpdf.stream = pdfstream -- THIS WILL PROBABLY CHANGE @@ -345,37 +441,19 @@ lpdf.boolean = pdfboolean lpdf.reference = pdfreference lpdf.verbose = pdfverbose --- n = pdf.obj(n, str) --- n = pdf.obj(n, "file", filename) --- n = pdf.obj(n, "stream", streamtext, attrtext) --- n = pdf.obj(n, "streamfile", filename, attrtext) - --- we only use immediate objects - --- todo: tracing - local names, cache = { }, { } function lpdf.reserveobject(name) - if name == "annot" then - -- catch misuse - return pdfreserveobject("annot") - else - local r = pdfreserveobject() - if name then - names[name] = r - if trace_objects then - report_objects("reserving number %a under name %a",r,name) - end - elseif trace_objects then - report_objects("reserving number %a",r) + local r = pdfreserveobject() -- we don't support "annot" + if name then + names[name] = r + if trace_objects then + report_objects("reserving number %a under name %a",r,name) end - return r + elseif trace_objects then + report_objects("reserving number %a",r) end -end - -function lpdf.reserveannotation() - return pdfreserveobject("annot") + return r end -- lpdf.immediateobject = pdfimmediateobject @@ -383,11 +461,29 @@ end -- lpdf.object = pdfdeferredobject -- lpdf.referenceobject = pdfreferenceobject -lpdf.pagereference = pdf.pageref or tex.pdfpageref -lpdf.registerannotation = pdf.registerannot +local pagereference = pdf.pageref or tex.pdfpageref +local nofpages = 0 + +function lpdf.pagereference(n) + if nofpages == 0 then + nofpages = structures.pages.nofpages + if nofpages == 0 then + nofpages = 1 + end + end + if n > nofpages then + return pagereference(nofpages) -- or 1, could be configureable + else + return pagereference(n) + end +end -function lpdf.delayedobject(data) -- we will get rid of this one - local n = pdfdeferredobject(data) +function lpdf.delayedobject(data,n) + if n then + pdfdeferredobject(n,data) + else + n = pdfdeferredobject(data) + end pdfreferenceobject(n) return n end @@ -484,57 +580,6 @@ function lpdf.shareobjectreference(content) end end ---~ local d = lpdf.dictionary() ---~ local e = lpdf.dictionary { ["e"] = "abc", x = lpdf.dictionary { ["f"] = "ABC" } } ---~ local f = lpdf.dictionary { ["f"] = "ABC" } ---~ local a = lpdf.array { lpdf.array { lpdf.string("xxx") } } - ---~ print(a) ---~ os.exit() - ---~ d["test"] = lpdf.string ("test") ---~ d["more"] = "more" ---~ d["bool"] = true ---~ d["numb"] = 1234 ---~ d["oeps"] = lpdf.dictionary { ["hans"] = "ton" } ---~ d["whow"] = lpdf.array { lpdf.string("ton") } - ---~ a[#a+1] = lpdf.string("xxx") ---~ a[#a+1] = lpdf.string("yyy") - ---~ d.what = a - ---~ print(e) - ---~ local d = lpdf.dictionary() ---~ d["abcd"] = { 1, 2, 3, "test" } ---~ print(d) ---~ print(d()) - ---~ local d = lpdf.array() ---~ d[#d+1] = 1 ---~ d[#d+1] = 2 ---~ d[#d+1] = 3 ---~ d[#d+1] = "test" ---~ print(d) - ---~ local d = lpdf.array() ---~ d[#d+1] = { 1, 2, 3, "test" } ---~ print(d) - ---~ local d = lpdf.array() ---~ d[#d+1] = { a=1, b=2, c=3, d="test" } ---~ print(d) - ---~ local s = lpdf.constant("xx") ---~ print(s) -- fails somehow ---~ print(s()) -- fails somehow - ---~ local s = lpdf.boolean(false) ---~ s.value = true ---~ print(s) ---~ print(s()) - -- three priority levels, default=2 local pagefinalizers, documentfinalizers = { { }, { }, { } }, { { }, { }, { } } @@ -606,8 +651,8 @@ end lpdf.registerpagefinalizer = registerpagefinalizer lpdf.registerdocumentfinalizer = registerdocumentfinalizer -function lpdf.finalizepage() - if not environment.initex then +function lpdf.finalizepage(shipout) + if shipout and not environment.initex then -- resetpageproperties() -- maybe better before run(pagefinalizers,"page") setpageproperties() @@ -625,9 +670,27 @@ function lpdf.finalizedocument() end end -backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- will go when we have hook +-- backends.pdf.codeinjections.finalizepage = lpdf.finalizepage -- no longer triggered at the tex end + +if not callbacks.register("finish_pdfpage", lpdf.finalizepage) then + + local find_tail = nodes.tail + local latelua_node = nodes.pool.latelua + + function backends.pdf.nodeinjections.finalizepage(head) + local t = find_tail(head.list) + if t then + local n = latelua_node("lpdf.finalizepage(true)") -- last in the shipout + t.next = n + n.prev = t + end + return head, true + end + + nodes.tasks.appendaction("shipouts","normalizers","backends.pdf.nodeinjections.finalizepage") + +end ---~ callbacks.register("finish_pdfpage", lpdf.finalizepage) callbacks.register("finish_pdffile", lpdf.finalizedocument) -- some minimal tracing, handy for checking the order @@ -718,7 +781,7 @@ registerpagefinalizer(checkshades,3,"shades") function lpdf.rotationcm(a) local s, c = sind(a), cosd(a) - return format("%0.6f %0.6f %0.6f %0.6f 0 0 cm",c,s,-s,c) + return format("%0.6F %0.6F %0.6F %0.6F 0 0 cm",c,s,-s,c) end -- ! -> universaltime @@ -795,29 +858,29 @@ end -- lpdf.addtoinfo("ConTeXt.Jobname", environment.jobname) -- lpdf.addtoinfo("ConTeXt.Url", "www.pragma-ade.com") -if not pdfreferenceobject then - - local delayed = { } - - local function flush() - local n = 0 - for k,v in next, delayed do - pdfimmediateobject(k,v) - n = n + 1 - end - if trace_objects then - report_objects("%s objects flushed",n) - end - delayed = { } - end - - lpdf.registerdocumentfinalizer(flush,3,"objects") -- so we need a final flush too - lpdf.registerpagefinalizer (flush,3,"objects") -- somehow this lags behind .. I need to look into that some day - - function lpdf.delayedobject(data) - local n = pdfreserveobject() - delayed[n] = data - return n - end - -end +-- if not pdfreferenceobject then +-- +-- local delayed = { } +-- +-- local function flush() +-- local n = 0 +-- for k,v in next, delayed do +-- pdfimmediateobject(k,v) +-- n = n + 1 +-- end +-- if trace_objects then +-- report_objects("%s objects flushed",n) +-- end +-- delayed = { } +-- end +-- +-- lpdf.registerdocumentfinalizer(flush,3,"objects") -- so we need a final flush too +-- lpdf.registerpagefinalizer (flush,3,"objects") -- somehow this lags behind .. I need to look into that some day +-- +-- function lpdf.delayedobject(data) +-- local n = pdfreserveobject() +-- delayed[n] = data +-- return n +-- end +-- +-- end diff --git a/tex/context/base/lpdf-mis.lua b/tex/context/base/lpdf-mis.lua index 43f6cb7e1..6efbd3882 100644 --- a/tex/context/base/lpdf-mis.lua +++ b/tex/context/base/lpdf-mis.lua @@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['lpdf-mis'] = { -- course there are a couple of more changes. local next, tostring = next, tostring -local format, gsub = string.format, string.gsub +local format, gsub, formatters = string.format, string.gsub, string.formatters local texset = tex.set local backends, lpdf, nodes = backends, lpdf, nodes @@ -41,6 +41,14 @@ local pdfverbose = lpdf.verbose local pdfstring = lpdf.string local pdfflushobject = lpdf.flushobject local pdfflushstreamobject = lpdf.flushstreamobject +local pdfaction = lpdf.action + +local formattedtimestamp = lpdf.pdftimestamp +local adddocumentextgstate = lpdf.adddocumentextgstate +local addtocatalog = lpdf.addtocatalog +local addtoinfo = lpdf.addtoinfo +local addtopageattributes = lpdf.addtopageattributes +local addtonames = lpdf.addtonames local variables = interfaces.variables local v_stop = variables.stop @@ -60,8 +68,8 @@ local function initializenegative() } local negative = pdfdictionary { Type = g, TR = pdfreference(pdfflushstreamobject("{ 1 exch sub }",d)) } local positive = pdfdictionary { Type = g, TR = pdfconstant("Identity") } - lpdf.adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative))) - lpdf.adddocumentextgstate("GSpositive", pdfreference(pdfflushobject(positive))) + adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative))) + adddocumentextgstate("GSpositive", pdfreference(pdfflushobject(positive))) initializenegative = nil end @@ -69,8 +77,8 @@ local function initializeoverprint() local g = pdfconstant("ExtGState") local knockout = pdfdictionary { Type = g, OP = false, OPM = 0 } local overprint = pdfdictionary { Type = g, OP = true, OPM = 1 } - lpdf.adddocumentextgstate("GSknockout", pdfreference(pdfflushobject(knockout))) - lpdf.adddocumentextgstate("GSoverprint", pdfreference(pdfflushobject(overprint))) + adddocumentextgstate("GSknockout", pdfreference(pdfflushobject(knockout))) + adddocumentextgstate("GSoverprint", pdfreference(pdfflushobject(overprint))) initializeoverprint = nil end @@ -92,8 +100,6 @@ function nodeinjections.negative() return copy_node(negative) end --- - -- function codeinjections.addtransparencygroup() -- -- png: /CS /DeviceRGB /I true -- local d = pdfdictionary { @@ -101,7 +107,7 @@ end -- I = true, -- K = true, -- } --- lpdf.registerpagefinalizer(function() lpdf.addtopageattributes("Group",d) end) -- hm +-- lpdf.registerpagefinalizer(function() addtopageattributes("Group",d) end) -- hm -- end -- actions (todo: store and update when changed) @@ -126,10 +132,10 @@ end local function flushdocumentactions() if opendocument then - lpdf.addtocatalog("OpenAction",lpdf.action(opendocument)) + addtocatalog("OpenAction",pdfaction(opendocument)) end if closedocument then - lpdf.addtocatalog("CloseAction",lpdf.action(closedocument)) + addtocatalog("CloseAction",pdfaction(closedocument)) end end @@ -137,12 +143,12 @@ local function flushpageactions() if openpage or closepage then local d = pdfdictionary() if openpage then - d.O = lpdf.action(openpage) + d.O = pdfaction(openpage) end if closepage then - d.C = lpdf.action(closepage) + d.C = pdfaction(closepage) end - lpdf.addtopageattributes("AA",d) + addtopageattributes("AA",d) end end @@ -169,37 +175,37 @@ local function setupidentity() if not title or title == "" then title = tex.jobname end - lpdf.addtoinfo("Title", pdfunicode(title), title) + addtoinfo("Title", pdfunicode(title), title) local subtitle = identity.subtitle or "" if subtitle ~= "" then - lpdf.addtoinfo("Subject", pdfunicode(subtitle), subtitle) + addtoinfo("Subject", pdfunicode(subtitle), subtitle) end local author = identity.author or "" if author ~= "" then - lpdf.addtoinfo("Author", pdfunicode(author), author) -- '/Author' in /Info, 'Creator' in XMP + addtoinfo("Author", pdfunicode(author), author) -- '/Author' in /Info, 'Creator' in XMP end local creator = identity.creator or "" if creator ~= "" then - lpdf.addtoinfo("Creator", pdfunicode(creator), creator) -- '/Creator' in /Info, 'CreatorTool' in XMP + addtoinfo("Creator", pdfunicode(creator), creator) -- '/Creator' in /Info, 'CreatorTool' in XMP end - lpdf.addtoinfo("CreationDate", pdfstring(lpdf.pdftimestamp(lpdf.timestamp()))) + local currenttimestamp = lpdf.timestamp() + addtoinfo("CreationDate", pdfstring(formattedtimestamp(currenttimestamp))) local date = identity.date or "" - local pdfdate = lpdf.pdftimestamp(date) + local pdfdate = formattedtimestamp(date) if pdfdate then - lpdf.addtoinfo("ModDate", pdfstring(pdfdate), date) + addtoinfo("ModDate", pdfstring(pdfdate), date) else -- users should enter the date in 2010-01-19T23:27:50+01:00 format -- and if not provided that way we use the creation time instead - date = lpdf.timestamp() - lpdf.addtoinfo("ModDate", pdfstring(lpdf.pdftimestamp(date)), date) + addtoinfo("ModDate", pdfstring(formattedtimestamp(currenttimestamp)), currenttimestamp) end local keywords = identity.keywords or "" if keywords ~= "" then keywords = gsub(keywords, "[%s,]+", " ") - lpdf.addtoinfo("Keywords",pdfunicode(keywords), keywords) + addtoinfo("Keywords",pdfunicode(keywords), keywords) end local id = lpdf.id() - lpdf.addtoinfo("ID", pdfstring(id), id) -- needed for pdf/x + addtoinfo("ID", pdfstring(id), id) -- needed for pdf/x done = true else -- no need for a message @@ -226,7 +232,7 @@ local function flushjavascripts() a[#a+1] = pdfstring(name) a[#a+1] = pdfreference(pdfflushobject(j)) end - lpdf.addtonames("JavaScript",pdfreference(pdfflushobject(pdfdictionary{ Names = a }))) + addtonames("JavaScript",pdfreference(pdfflushobject(pdfdictionary{ Names = a }))) end end @@ -285,16 +291,16 @@ local function documentspecification() layout = layout and pdfconstant(layout) fit = fit and pdfdictionary { FitWindow = true } if layout then - lpdf.addtocatalog("PageLayout",layout) + addtocatalog("PageLayout",layout) end if mode then - lpdf.addtocatalog("PageMode",mode) + addtocatalog("PageMode",mode) end if fit then - lpdf.addtocatalog("ViewerPreferences",fit) + addtocatalog("ViewerPreferences",fit) end - lpdf.addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP - lpdf.addtocatalog("Version", pdfconstant(format("1.%s",tex.pdfminorversion))) + addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP + addtocatalog("Version", pdfconstant(format("1.%s",tex.pdfminorversion))) end end @@ -303,7 +309,7 @@ end local factor = number.dimenfactors.bp local function boxvalue(n) -- we could share them - return pdfverbose(format("%0.4f",factor * n)) + return pdfverbose(formatters["%0.4F"](factor * n)) end local function pagespecification() @@ -314,10 +320,10 @@ local function pagespecification() boxvalue(width-leftoffset), boxvalue(pageheight-topoffset), } - lpdf.addtopageattributes("CropBox",box) -- mandate for rendering - lpdf.addtopageattributes("TrimBox",box) -- mandate for pdf/x - -- lpdf.addtopageattributes("BleedBox",box) - -- lpdf.addtopageattributes("ArtBox",box) + addtopageattributes("CropBox",box) -- mandate for rendering + addtopageattributes("TrimBox",box) -- mandate for pdf/x + -- addtopageattributes("BleedBox",box) + -- addtopageattributes("ArtBox",box) end lpdf.registerpagefinalizer(pagespecification,"page specification") @@ -365,7 +371,7 @@ local map = { -- end -- end -- end --- lpdf.addtocatalog("PageLabels", pdfdictionary { Nums = list }) +-- addtocatalog("PageLabels", pdfdictionary { Nums = list }) -- end local function featurecreep() @@ -416,7 +422,7 @@ local function featurecreep() stopped = false end end - lpdf.addtocatalog("PageLabels", pdfdictionary { Nums = list }) + addtocatalog("PageLabels", pdfdictionary { Nums = list }) end lpdf.registerdocumentfinalizer(featurecreep,"featurecreep") diff --git a/tex/context/base/lpdf-mov.lua b/tex/context/base/lpdf-mov.lua index 41db97e0c..fd3e89722 100644 --- a/tex/context/base/lpdf-mov.lua +++ b/tex/context/base/lpdf-mov.lua @@ -11,7 +11,6 @@ local format = string.format local lpdf = lpdf local nodeinjections = backends.pdf.nodeinjections -local pdfannotation_node = nodes.pool.pdfannotation local pdfconstant = lpdf.constant local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array @@ -38,7 +37,7 @@ function nodeinjections.insertmovie(specification) Movie = moviedict, A = controldict, } - write_node(pdfannotation_node(width,height,0,action())) -- test: context(...) + write_node(nodeinjections.annotation(width,height,0,action())) -- test: context(...) end function nodeinjections.insertsound(specification) @@ -58,6 +57,6 @@ function nodeinjections.insertsound(specification) Movie = sounddict, A = controldict, } - write_node(pdfannotation_node(0,0,0,action())) -- test: context(...) + write_node(nodeinjections.annotation(0,0,0,action())) -- test: context(...) end end diff --git a/tex/context/base/lpdf-nod.lua b/tex/context/base/lpdf-nod.lua index 68d7fca90..6295947d0 100644 --- a/tex/context/base/lpdf-nod.lua +++ b/tex/context/base/lpdf-nod.lua @@ -90,10 +90,10 @@ function nodepool.pdfsetmatrix(rx,sx,sy,ry,tx,ty) -- todo: tx ty if rx == 1 and ry == 1 then setfield(t,"data","1 0 0 1") else - setfield(t,"data",formatters["%0.6f 0 0 %0.6f"](rx,ry)) + setfield(t,"data",formatters["%0.6F 0 0 %0.6F"](rx,ry)) end else - setfield(t,"data",formatters["%0.6f %0.6f %0.6f %0.6f"](rx,sx,sy,ry)) + setfield(t,"data",formatters["%0.6F %0.6F %0.6F %0.6F"](rx,sx,sy,ry)) end end return t @@ -103,24 +103,28 @@ nodeinjections.save = nodepool.pdfsave nodeinjections.restore = nodepool.pdfrestore nodeinjections.transform = nodepool.pdfsetmatrix +-- the next one is implemented differently, using latelua + function nodepool.pdfannotation(w,h,d,data,n) - local t = copy_node(pdfannot) - if w and w ~= 0 then - setfield(t,"width",w) - end - if h and h ~= 0 then - setfield(t,"height",h) - end - if d and d ~= 0 then - setfield(t,"depth",d) - end - if n then - setfield(t,"objnum",n) - end - if data and data ~= "" then - setfield(t,"data",data) - end - return t + report("don't use node based annotations!") + os.exit() +-- local t = copy_node(pdfannot) +-- if w and w ~= 0 then +-- setfield(t,"width",w) +-- end +-- if h and h ~= 0 then +-- setfield(t,"height",h) +-- end +-- if d and d ~= 0 then +-- setfield(t,"depth",d) +-- end +-- if n then +-- setfield(t,"objnum",n) +-- end +-- if data and data ~= "" then +-- setfield(t,"data",data) +-- end +-- return t end -- (!) The next code in pdfdest.w is wrong: @@ -137,41 +141,43 @@ end -- so we need to force a matrix. function nodepool.pdfdestination(w,h,d,name,view,n) - local t = copy_node(pdfdest) - local hasdimensions = false - if w and w ~= 0 then - setfield(t,"width",w) - hasdimensions = true - end - if h and h ~= 0 then - setfield(t,"height",h) - hasdimensions = true - end - if d and d ~= 0 then - setfield(t,"depth",d) - hasdimensions = true - end - if n then - setfield(t,"objnum",n) - end - view = views[view] or view or 1 -- fit is default - setfield(t,"dest_id",name) - setfield(t,"dest_type",view) - if hasdimensions and view == 0 then -- xyz - -- see (!) s -> m -> t -> r - -- linked - local s = copy_node(pdfsave) - local m = copy_node(pdfsetmatrix) - local r = copy_node(pdfrestore) - setfield(m,"data","1 0 0 1") - setfield(s,"next",m) - setfield(m,"next",t) - setfield(t,"next",r) - setfield(m,"prev",s) - setfield(t,"prev",m) - setfield(r,"prev",t) - return s -- a list - else - return t - end + report("don't use node based destinations!") + os.exit() +-- local t = copy_node(pdfdest) +-- local hasdimensions = false +-- if w and w ~= 0 then +-- setfield(t,"width",w) +-- hasdimensions = true +-- end +-- if h and h ~= 0 then +-- setfield(t,"height",h) +-- hasdimensions = true +-- end +-- if d and d ~= 0 then +-- setfield(t,"depth",d) +-- hasdimensions = true +-- end +-- if n then +-- setfield(t,"objnum",n) +-- end +-- view = views[view] or view or 1 -- fit is default +-- setfield(t,"dest_id",name) +-- setfield(t,"dest_type",view) +-- if hasdimensions and view == 0 then -- xyz +-- -- see (!) s -> m -> t -> r +-- -- linked +-- local s = copy_node(pdfsave) +-- local m = copy_node(pdfsetmatrix) +-- local r = copy_node(pdfrestore) +-- setfield(m,"data","1 0 0 1") +-- setfield(s,"next",m) +-- setfield(m,"next",t) +-- setfield(t,"next",r) +-- setfield(m,"prev",s) +-- setfield(t,"prev",m) +-- setfield(r,"prev",t) +-- return s -- a list +-- else +-- return t +-- end end diff --git a/tex/context/base/lpdf-ren.lua b/tex/context/base/lpdf-ren.lua index 6af65f9de..37b706420 100644 --- a/tex/context/base/lpdf-ren.lua +++ b/tex/context/base/lpdf-ren.lua @@ -15,47 +15,51 @@ local settings_to_array = utilities.parsers.settings_to_array local backends, lpdf, nodes, node = backends, lpdf, nodes, node -local nodeinjections = backends.pdf.nodeinjections -local codeinjections = backends.pdf.codeinjections -local registrations = backends.pdf.registrations -local viewerlayers = attributes.viewerlayers +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections +local registrations = backends.pdf.registrations +local viewerlayers = attributes.viewerlayers -local references = structures.references +local references = structures.references -references.executers = references.executers or { } -local executers = references.executers +references.executers = references.executers or { } +local executers = references.executers -local variables = interfaces.variables +local variables = interfaces.variables -local v_no = variables.no -local v_yes = variables.yes -local v_start = variables.start -local v_stop = variables.stop -local v_reset = variables.reset -local v_auto = variables.auto -local v_random = variables.random +local v_no = variables.no +local v_yes = variables.yes +local v_start = variables.start +local v_stop = variables.stop +local v_reset = variables.reset +local v_auto = variables.auto +local v_random = variables.random -local pdfconstant = lpdf.constant -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfreference = lpdf.reference -local pdfflushobject = lpdf.flushobject -local pdfreserveobject = lpdf.reserveobject +local pdfconstant = lpdf.constant +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfreference = lpdf.reference +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject -local nodepool = nodes.pool -local register = nodepool.register -local pdfliteral = nodepool.pdfliteral +local addtopageattributes = lpdf.addtopageattributes +local addtopageresources = lpdf.addtopageresources +local addtocatalog = lpdf.addtocatalog -local pdf_ocg = pdfconstant("OCG") -local pdf_ocmd = pdfconstant("OCMD") -local pdf_off = pdfconstant("OFF") -local pdf_on = pdfconstant("ON") -local pdf_toggle = pdfconstant("Toggle") -local pdf_setocgstate = pdfconstant("SetOCGState") +local nodepool = nodes.pool +local register = nodepool.register +local pdfliteral = nodepool.pdfliteral -local copy_node = node.copy +local pdf_ocg = pdfconstant("OCG") +local pdf_ocmd = pdfconstant("OCMD") +local pdf_off = pdfconstant("OFF") +local pdf_on = pdfconstant("ON") +local pdf_toggle = pdfconstant("Toggle") +local pdf_setocgstate = pdfconstant("SetOCGState") -local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdf_off } } +local copy_node = node.copy + +local lpdf_usage = pdfdictionary { Print = pdfdictionary { PrintState = pdf_off } } -- We can have references to layers before they are places, for instance from -- hide and vide actions. This is why we need to be able to force usage of layers @@ -163,7 +167,7 @@ local function flushtextlayers() BaseState = pdf_on, }, } - lpdf.addtocatalog("OCProperties",d) + addtocatalog("OCProperties",d) textlayers = nil end end @@ -171,7 +175,7 @@ end local function flushpagelayers() -- we can share these if pagelayers then - lpdf.addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this + addtopageresources("Properties",pdfreference(pagelayersreference)) -- we could cache this end end @@ -342,8 +346,8 @@ function codeinjections.setpagetransition(specification) end delay = tonumber(delay) if delay and delay > 0 then - lpdf.addtopageattributes("Dur",delay) + addtopageattributes("Dur",delay) end - lpdf.addtopageattributes("Trans",d) + addtopageattributes("Trans",d) end end diff --git a/tex/context/base/lpdf-swf.lua b/tex/context/base/lpdf-swf.lua index 12c80036f..88cdcc4ec 100644 --- a/tex/context/base/lpdf-swf.lua +++ b/tex/context/base/lpdf-swf.lua @@ -28,8 +28,6 @@ local checkedkey = lpdf.checkedkey local codeinjections = backends.pdf.codeinjections local nodeinjections = backends.pdf.nodeinjections -local pdfannotation_node = nodes.pool.pdfannotation - local trace_swf = false trackers.register("backend.swf", function(v) trace_swf = v end) local report_swf = logs.reporter("backend","swf") @@ -302,5 +300,5 @@ function backends.pdf.nodeinjections.insertswf(spec) -- factor = spec.factor, -- label = spec.label, } - context(pdfannotation_node(spec.width,spec.height,0,annotation())) -- the context wrap is probably also needed elsewhere + context(nodeinjections.annotation(spec.width,spec.height,0,annotation())) -- the context wrap is probably also needed elsewhere end diff --git a/tex/context/base/lpdf-tag.lua b/tex/context/base/lpdf-tag.lua index afddec345..276816e80 100644 --- a/tex/context/base/lpdf-tag.lua +++ b/tex/context/base/lpdf-tag.lua @@ -15,75 +15,78 @@ local trace_tags = false trackers.register("structures.tags", function(v) trace local report_tags = logs.reporter("backend","tags") -local backends = backends -local lpdf = lpdf -local nodes = nodes - -local nodeinjections = backends.pdf.nodeinjections -local codeinjections = backends.pdf.codeinjections - -local tasks = nodes.tasks - -local pdfdictionary = lpdf.dictionary -local pdfarray = lpdf.array -local pdfboolean = lpdf.boolean -local pdfconstant = lpdf.constant -local pdfreference = lpdf.reference -local pdfunicode = lpdf.unicode -local pdfstring = lpdf.string -local pdfflushobject = lpdf.flushobject -local pdfreserveobject = lpdf.reserveobject -local pdfpagereference = lpdf.pagereference - -local texgetcount = tex.getcount - -local nodecodes = nodes.nodecodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glyph_code = nodecodes.glyph - -local a_tagged = attributes.private('tagged') -local a_image = attributes.private('image') - -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - -local nodepool = nuts.pool -local pdfliteral = nodepool.pdfliteral - -local getid = nuts.getid -local getattr = nuts.getattr -local getprev = nuts.getprev -local getnext = nuts.getnext -local getlist = nuts.getlist -local setfield = nuts.setfield - -local traverse_nodes = nuts.traverse -local tosequence = nuts.tosequence -local copy_node = nuts.copy -local slide_nodelist = nuts.slide -local insert_before = nuts.insert_before -local insert_after = nuts.insert_after - -local structure_stack = { } -local structure_kids = pdfarray() -local structure_ref = pdfreserveobject() -local parent_ref = pdfreserveobject() -local root = { pref = pdfreference(structure_ref), kids = structure_kids } -local tree = { } -local elements = { } -local names = pdfarray() -local taglist = structures.tags.taglist -local usedlabels = structures.tags.labels -local properties = structures.tags.properties -local usedmapping = { } - -local colonsplitter = lpeg.splitat(":") -local dashsplitter = lpeg.splitat("-") - -local add_ids = false -- true +local backends = backends +local lpdf = lpdf +local nodes = nodes + +local nodeinjections = backends.pdf.nodeinjections +local codeinjections = backends.pdf.codeinjections + +local tasks = nodes.tasks + +local pdfdictionary = lpdf.dictionary +local pdfarray = lpdf.array +local pdfboolean = lpdf.boolean +local pdfconstant = lpdf.constant +local pdfreference = lpdf.reference +local pdfunicode = lpdf.unicode +local pdfstring = lpdf.string +local pdfflushobject = lpdf.flushobject +local pdfreserveobject = lpdf.reserveobject +local pdfpagereference = lpdf.pagereference + +local addtocatalog = lpdf.addtocatalog +local addtopageattributes = lpdf.addtopageattributes + +local texgetcount = tex.getcount + +local nodecodes = nodes.nodecodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph + +local a_tagged = attributes.private('tagged') +local a_image = attributes.private('image') + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +local nodepool = nuts.pool +local pdfliteral = nodepool.pdfliteral + +local getid = nuts.getid +local getattr = nuts.getattr +local getprev = nuts.getprev +local getnext = nuts.getnext +local getlist = nuts.getlist +local setfield = nuts.setfield + +local traverse_nodes = nuts.traverse +local tosequence = nuts.tosequence +local copy_node = nuts.copy +local slide_nodelist = nuts.slide +local insert_before = nuts.insert_before +local insert_after = nuts.insert_after + +local structure_stack = { } +local structure_kids = pdfarray() +local structure_ref = pdfreserveobject() +local parent_ref = pdfreserveobject() +local root = { pref = pdfreference(structure_ref), kids = structure_kids } +local tree = { } +local elements = { } +local names = pdfarray() +local taglist = structures.tags.taglist +local usedlabels = structures.tags.labels +local properties = structures.tags.properties +local usedmapping = { } + +local colonsplitter = lpeg.splitat(":") +local dashsplitter = lpeg.splitat("-") + +local add_ids = false -- true -- function codeinjections.maptag(original,target,kind) -- mapping[original] = { target, kind or "inline" } @@ -124,14 +127,14 @@ local function finishstructure() RoleMap = rolemap, } pdfflushobject(structure_ref,structuretree) - lpdf.addtocatalog("StructTreeRoot",pdfreference(structure_ref)) + addtocatalog("StructTreeRoot",pdfreference(structure_ref)) -- local markinfo = pdfdictionary { Marked = pdfboolean(true), -- UserProperties = pdfboolean(true), -- Suspects = pdfboolean(true), } - lpdf.addtocatalog("MarkInfo",pdfreference(pdfflushobject(markinfo))) + addtocatalog("MarkInfo",pdfreference(pdfflushobject(markinfo))) -- for fulltag, element in next, elements do pdfflushobject(element.knum,element.kids) @@ -156,7 +159,7 @@ end local function finishpage() -- flush what can be flushed - lpdf.addtopageattributes("StructParents",pagenum-1) + addtopageattributes("StructParents",pagenum-1) end -- here we can flush and free elements that are finished diff --git a/tex/context/base/lpdf-u3d.lua b/tex/context/base/lpdf-u3d.lua index 33269486c..f1df1d18e 100644 --- a/tex/context/base/lpdf-u3d.lua +++ b/tex/context/base/lpdf-u3d.lua @@ -38,8 +38,6 @@ local pdfflushstreamfileobject = lpdf.flushstreamfileobject local checkedkey = lpdf.checkedkey local limited = lpdf.limited -local pdfannotation_node = nodes.pool.pdfannotation - local schemes = table.tohash { "Artwork", "None", "White", "Day", "Night", "Hard", "Primary", "Blue", "Red", "Cube", "CAD", "Headlamp", @@ -462,7 +460,7 @@ local function insert3d(spec) -- width, height, factor, display, controls, label }, ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") }, } - local pwd = pdfflushstreamobject(format("q /GS gs %f 0 0 %f 0 0 cm /IM Do Q",factor*width,factor*height),pw) + local pwd = pdfflushstreamobject(format("q /GS gs %F 0 0 %F 0 0 cm /IM Do Q",factor*width,factor*height),pw) annot.AP = pdfdictionary { N = pdfreference(pwd) } @@ -484,5 +482,5 @@ function nodeinjections.insertu3d(spec) controls = spec.controls, label = spec.label, } - node.write(pdfannotation_node(spec.width,spec.height,0,annotation())) + node.write(nodeinjections.annotation(spec.width,spec.height,0,annotation())) end diff --git a/tex/context/base/lpdf-wid.lua b/tex/context/base/lpdf-wid.lua index 11ac82a08..39f2f690c 100644 --- a/tex/context/base/lpdf-wid.lua +++ b/tex/context/base/lpdf-wid.lua @@ -46,14 +46,13 @@ local pdfcolorspec = lpdf.colorspec local pdfflushobject = lpdf.flushobject local pdfflushstreamobject = lpdf.flushstreamobject local pdfflushstreamfileobject = lpdf.flushstreamfileobject -local pdfreserveannotation = lpdf.reserveannotation local pdfreserveobject = lpdf.reserveobject local pdfpagereference = lpdf.pagereference local pdfshareobjectreference = lpdf.shareobjectreference +local pdfaction = lpdf.action -local nodepool = nodes.pool - -local pdfannotation_node = nodepool.pdfannotation +local pdftransparencyvalue = lpdf.transparencyvalue +local pdfcolorvalues = lpdf.colorvalues local hpack_node = node.hpack local write_node = node.write -- test context(...) instead @@ -170,12 +169,12 @@ end local function analyzecolor(colorvalue,colormodel) local cvalue = colorvalue and tonumber(colorvalue) local cmodel = colormodel and tonumber(colormodel) or 3 - return cvalue and pdfarray { lpdf.colorvalues(cmodel,cvalue) } or nil + return cvalue and pdfarray { pdfcolorvalues(cmodel,cvalue) } or nil end local function analyzetransparency(transparencyvalue) local tvalue = transparencyvalue and tonumber(transparencyvalue) - return tvalue and lpdf.transparencyvalue(tvalue) or nil + return tvalue and pdftransparencyvalue(tvalue) or nil end -- Attachments @@ -342,7 +341,7 @@ function nodeinjections.attachfile(specification) OC = analyzelayer(specification.layer), } local width, height, depth = specification.width or 0, specification.height or 0, specification.depth - local box = hpack_node(pdfannotation_node(width,height,depth,d())) + local box = hpack_node(nodeinjections.annotation(width,height,depth,d())) box.width, box.height, box.depth = width, height, depth return box end @@ -427,19 +426,19 @@ function nodeinjections.comment(specification) -- brrr: seems to be done twice local box if usepopupcomments then -- rather useless as we can hide/vide - local nd = pdfreserveannotation() - local nc = pdfreserveannotation() + local nd = pdfreserveobject() + local nc = pdfreserveobject() local c = pdfdictionary { Subtype = pdfconstant("Popup"), Parent = pdfreference(nd), } d.Popup = pdfreference(nc) box = hpack_node( - pdfannotation_node(0,0,0,d(),nd), - pdfannotation_node(width,height,depth,c(),nc) + nodeinjections.annotation(0,0,0,d(),nd), + nodeinjections.annotation(width,height,depth,c(),nc) ) else - box = hpack_node(pdfannotation_node(width,height,depth,d())) + box = hpack_node(nodeinjections.annotation(width,height,depth,d())) end box.width, box.height, box.depth = width, height, depth -- redundant return box @@ -484,7 +483,7 @@ end local ms, mu, mf = { }, { }, { } local function delayed(label) - local a = pdfreserveannotation() + local a = pdfreserveobject() mu[label] = a return pdfreference(a) end @@ -504,12 +503,12 @@ local function insertrenderingwindow(specification) local actions = nil if openpage or closepage then actions = pdfdictionary { - PO = (openpage and lpdf.action(openpage )) or nil, - PC = (closepage and lpdf.action(closepage)) or nil, + PO = (openpage and lpdfaction(openpage )) or nil, + PC = (closepage and lpdfaction(closepage)) or nil, } end local page = tonumber(specification.page) or texgetcount("realpageno") -- todo - local r = mu[label] or pdfreserveannotation() -- why the reserve here? + local r = mu[label] or pdfreserveobject() -- why the reserve here? local a = pdfdictionary { S = pdfconstant("Rendition"), R = mf[label], @@ -528,7 +527,7 @@ local function insertrenderingwindow(specification) if height == 0 or width == 0 then -- todo: sound needs no window end - write_node(pdfannotation_node(width,height,0,d(),r)) -- save ref + write_node(nodeinjections.annotation(width,height,0,d(),r)) -- save ref return pdfreference(r) end @@ -539,7 +538,7 @@ local function insertrendering(specification) local option = settings_to_hash(specification.option) if not mf[label] then local filename = specification.filename - local isurl = find(filename,"://") + local isurl = find(filename,"://",1,true) -- local start = pdfdictionary { -- Type = pdfconstant("MediaOffset"), -- S = pdfconstant("T"), -- time diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua index 4f044f9ac..8c224ad2c 100644 --- a/tex/context/base/luat-cbk.lua +++ b/tex/context/base/luat-cbk.lua @@ -118,7 +118,7 @@ end function callbacks.freeze(name,freeze) freeze = type(freeze) == "string" and freeze - if find(name,"%*") then + if find(name,"*",1,true) then local pattern = name for name, _ in next, list do if find(name,pattern) then diff --git a/tex/context/base/luat-cnf.lua b/tex/context/base/luat-cnf.lua index 4ad6cd69d..fba2b71d1 100644 --- a/tex/context/base/luat-cnf.lua +++ b/tex/context/base/luat-cnf.lua @@ -134,13 +134,14 @@ function texconfig.init() -- shortcut and helper + local bytecode = lua.bytecode + local function init(start) - local b = lua.bytecode local i = start local t = os.clock() - while b[i] do - b[i]() ; - b[i] = nil ; + while bytecode[i] do + bytecode[i]() ; + bytecode[i] = nil ; i = i + 1 -- collectgarbage('step') end @@ -159,6 +160,8 @@ function texconfig.init() end end + texconfig.init = function() end + end -- we provide a qualified path diff --git a/tex/context/base/luat-cod.lua b/tex/context/base/luat-cod.lua index 8b015477f..c16a3b110 100644 --- a/tex/context/base/luat-cod.lua +++ b/tex/context/base/luat-cod.lua @@ -51,6 +51,9 @@ function lua.registercode(filename,version) bytecode[n] = code lua.lastbytecode = n end + elseif environment.initex then + texio.write_nl("\nerror loading file: " .. filename .. " (aborting)") + os.exit() end end end @@ -85,7 +88,7 @@ local environment = environment -- no string.unquoted yet local sourcefile = gsub(arg and arg[1] or "","^\"(.*)\"$","%1") -local sourcepath = find(sourcefile,"/") and gsub(sourcefile,"/[^/]+$","") or "" +local sourcepath = find(sourcefile,"/",1,true) and gsub(sourcefile,"/[^/]+$","") or "" local targetpath = "." -- delayed (via metatable): diff --git a/tex/context/base/luat-ini.lua b/tex/context/base/luat-ini.lua index 587214b93..9303b614a 100644 --- a/tex/context/base/luat-ini.lua +++ b/tex/context/base/luat-ini.lua @@ -72,6 +72,8 @@ lua.messages = lua.messages or { } local messages = lua.messages storage.register("lua/numbers", numbers, "lua.numbers" ) storage.register("lua/messages", messages, "lua.messages") +local f_message = string.formatters["=[instance: %s]"] -- the = controls the lua error / see: lobject.c + local setfenv = setfenv or debug.setfenv -- < 5.2 if setfenv then @@ -183,7 +185,7 @@ elseif libraries then -- assume >= 5.2 messages[lnn] = message numbers[name] = lnn end - luanames[lnn] = message + luanames[lnn] = f_message(message) context(lnn) end @@ -198,7 +200,7 @@ else messages[lnn] = message numbers[name] = lnn end - luanames[lnn] = message + luanames[lnn] = f_message(message) context(lnn) end diff --git a/tex/context/base/luat-ini.mkiv b/tex/context/base/luat-ini.mkiv index a3a590311..7823ebd5a 100644 --- a/tex/context/base/luat-ini.mkiv +++ b/tex/context/base/luat-ini.mkiv @@ -120,23 +120,31 @@ \obeyluatokens \csname\??luacode#1\endcsname} +% \unexpanded\def\definenamedlua[#1]#2[#3]% no optional arg handling here yet / we could use numbers instead (more efficient) +% {\ifcsname\??luacode#1\endcsname \else +% \scratchcounter\ctxlua{lua.registername("#1","#3")}% +% \normalexpanded{\xdef\csname\??luacode#1\endcsname##1\csname\e!stop#1\v!code\endcsname}% +% {\noexpand\normalexpanded{\endgroup\noexpand\directlua\the\scratchcounter{_G=protect("#1\s!data")##1}}}% +% \expandafter\edef\csname\e!start#1\v!code\endcsname {\luat_start_named_lua_code{#1}}% +% \expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{_G=protect("#1\s!data")##1}}% +% \fi} + \unexpanded\def\definenamedlua[#1]#2[#3]% no optional arg handling here yet / we could use numbers instead (more efficient) {\ifcsname\??luacode#1\endcsname \else - \scratchcounter\ctxlua{lua.registername("#1","#3")}% + \expandafter\chardef\csname\??luacode:#1\endcsname\ctxlua{lua.registername("#1","#3")}% \normalexpanded{\xdef\csname\??luacode#1\endcsname##1\csname\e!stop#1\v!code\endcsname}% - %{\endgroup\noexpand\directlua\the\scratchcounter{local _ENV=protect("#1\s!data")##1}}% - {\noexpand\normalexpanded{\endgroup\noexpand\directlua\the\scratchcounter{local _ENV=protect("#1\s!data")##1}}}% + {\noexpand\normalexpanded{\endgroup\noexpand\directlua\csname\??luacode:#1\endcsname{_G=protect("#1\s!data")##1}}}% \expandafter\edef\csname\e!start#1\v!code\endcsname {\luat_start_named_lua_code{#1}}% - \expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\the\scratchcounter{local _ENV=protect("#1\s!data")##1}}% + \expandafter\edef\csname #1\v!code\endcsname##1{\noexpand\directlua\csname\??luacode:#1\endcsname{_G=protect("#1\s!data")##1}}% \fi} %D We predefine a few. % \definenamedlua[module][module instance] % not needed -\definenamedlua[user] [private user instance] -\definenamedlua[third] [third party module instance] -\definenamedlua[isolated][isolated instance] +\definenamedlua[user] [private user] +\definenamedlua[third] [third party module] +\definenamedlua[isolated][isolated] %D In practice this works out as follows: %D @@ -266,4 +274,53 @@ \def\luat_lua_code {\normalexpanded{\endgroup\noexpand\directlua\expandafter{\the\scratchtoks}}} % \zerocount is default +% \startctxfunction MyFunctionA +% context(" A1 ") +% \stopctxfunction +% +% \startctxfunctiondefinition MyFunctionB +% context(" B2 ") +% \stopctxfunctiondefinition +% +% \starttext +% \dorecurse{10000}{\ctxfunction{MyFunctionA}} \page +% \dorecurse{10000}{\MyFunctionB} \page +% \dorecurse{10000}{\ctxlua{context(" C3 ")}} \page +% \stoptext + +\installcorenamespace{ctxfunction} + +\normalprotected\def\startctxfunctiondefinition #1 % + {\begingroup \obeylualines \obeyluatokens \luat_start_lua_function_definition_indeed{#1}} + +% \def\luat_start_lua_function_definition_indeed#1#2\stopctxfunctiondefinition +% {\endgroup\expandafter\edef\csname#1\endcsname{\noexpand\luafunction\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax}} + +\installcorenamespace{luafunction} + +\def\luat_start_lua_function_definition_indeed#1#2\stopctxfunctiondefinition + {\endgroup + \expandafter\chardef\csname\??luafunction#1\endcsname\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax + \expandafter\edef\csname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}} + +% \unexpanded\def\setctxluafunction#1#2% experiment +% {\expandafter\chardef\csname#1\endcsname#2\relax} + +\unexpanded\def\setctxluafunction#1#2% experiment + {\expandafter\chardef\csname\??luafunction#1\endcsname#2\relax + \expandafter\edef\csname#1\endcsname{\noexpand\luafunction\csname\??luafunction#1\endcsname}} + +\let\stopctxfunctiondefinition\relax + +\normalprotected\def\startctxfunction #1 % + {\begingroup \obeylualines \obeyluatokens \luat_start_lua_function_indeed{#1}} + +\def\luat_start_lua_function_indeed#1#2\stopctxfunction + {\endgroup\expandafter\edef\csname\??ctxfunction#1\endcsname{\noexpand\luafunction\ctxcommand{ctxfunction(\!!bs#2\!!es)}\relax}} + +\let\stopctxfunction\relax + +\def\ctxfunction#1% + {\csname\??ctxfunction#1\endcsname} + \protect \endinput diff --git a/tex/context/base/luat-run.lua b/tex/context/base/luat-run.lua index 719a6f7c9..ab4b3463c 100644 --- a/tex/context/base/luat-run.lua +++ b/tex/context/base/luat-run.lua @@ -6,8 +6,8 @@ if not modules then modules = { } end modules ['luat-run'] = { license = "see context related readme files" } -local format = string.format -local insert = table.insert +local format, find = string.format, string.find +local insert, remove = table.insert, table.remove -- trace_job_status is also controlled by statistics.enable that is set via the directive system.nostatistics @@ -158,3 +158,75 @@ statistics.register("synctex tracing",function() return "synctex has been enabled (extra log file generated)" end end) + +-- filenames + +local types = { + "data", + "font map", + "image", + "font subset", + "full font", +} + +local report_open = logs.reporter("open source") +local report_close = logs.reporter("close source") +local report_load = logs.reporter("load resource") + +local register = callbacks.register + +local level = 0 +local total = 0 +local stack = { } +local all = true + +local function report_start(left,name) + if not left then + -- skip + elseif left ~= 1 then + if all then + report_load("%s > %s",types[left],name or "?") + end + elseif find(name,"virtual://") then + insert(stack,false) + else + insert(stack,name) + total = total + 1 + level = level + 1 + report_open("%i > %i > %s",level,total,name or "?") + end +end + +local function report_stop(right) + if level == 1 or not right or right == 1 then + local name = remove(stack) + if name then + report_close("%i > %i > %s",level,total,name or "?") + level = level - 1 + end + end +end + +local function report_none() +end + +register("start_file",report_start) +register("stop_file", report_stop) + +directives.register("system.reportfiles", function(v) + if v == "noresources" then + all = false + register("start_file",report_start) + register("stop_file", report_stop) + elseif toboolean(v) or v == "all" then + all = true + register("start_file",report_start) + register("stop_file", report_stop) + elseif v == "traditional" then + register("start_file",nil) + register("stop_file", nil) + else + register("start_file",report_none) + register("stop_file", report_none) + end +end) diff --git a/tex/context/base/luat-sto.lua b/tex/context/base/luat-sto.lua index 041050fb8..b04d655c2 100644 --- a/tex/context/base/luat-sto.lua +++ b/tex/context/base/luat-sto.lua @@ -13,6 +13,7 @@ local gmatch, format = string.gmatch, string.format local serialize, concat, sortedhash = table.serialize, table.concat, table.sortedhash local bytecode = lua.bytecode local strippedloadstring = utilities.lua.strippedloadstring +local formatters = string.formatters local trace_storage = false local report_storage = logs.reporter("system","storage") @@ -48,38 +49,71 @@ function storage.register(...) return t end -local n = 0 -local function dump() - local max = storage.max - for i=1,#data do - local d = data[i] - local message, original, target = d[1], d[2] ,d[3] - local c, code, name = 0, { }, nil - -- we have a nice definer for this - for str in gmatch(target,"([^%.]+)") do - if name then - name = name .. "." .. str +local n = 0 -- is that one used ? + +if environment.initex then + + -- local function dump() + -- local max = storage.max + -- for i=1,#data do + -- local d = data[i] + -- local message, original, target = d[1], d[2] ,d[3] + -- local c, code, name = 0, { }, nil + -- -- we have a nice definer for this + -- for str in gmatch(target,"([^%.]+)") do + -- if name then + -- name = name .. "." .. str + -- else + -- name = str + -- end + -- c = c + 1 ; code[c] = formatters["%s = %s or { }"](name,name) + -- end + -- max = max + 1 + -- if trace_storage then + -- c = c + 1 ; code[c] = formatters["print('restoring %s from slot %s')"](message,max) + -- end + -- c = c + 1 ; code[c] = serialize(original,name) + -- if trace_storage then + -- report_storage('saving %a in slot %a, size %s',message,max,#code[c]) + -- end + -- -- we don't need tracing in such tables + -- bytecode[max] = strippedloadstring(concat(code,"\n"),storage.strip,format("slot %s (%s)",max,name)) + -- collectgarbage("step") + -- end + -- storage.max = max + -- end + + local function dump() + local max = storage.max + local strip = storage.strip + for i=1,#data do + max = max + 1 + local tabledata = data[i] + local message = tabledata[1] + local original = tabledata[2] + local target = tabledata[3] + local definition = utilities.tables.definetable(target,false,true) + local comment = formatters["restoring %s from slot %s"](message,max) + if trace_storage then + comment = formatters["print('%s')"](comment) else - name = str + comment = formatters["-- %s"](comment) end - c = c + 1 ; code[c] = format("%s = %s or { }",name,name) - end - max = max + 1 - if trace_storage then - c = c + 1 ; code[c] = format("print('restoring %s from slot %s')",message,max) - end - c = c + 1 ; code[c] = serialize(original,name) - if trace_storage then - report_storage('saving %a in slot %a, size %s',message,max,#code[c]) + local dumped = serialize(original,target) + if trace_storage then + report_storage('saving %a in slot %a, size %s',message,max,#dumped) + end + -- we don't need tracing in such tables + dumped = concat({ definition, comment, dumped },"\n") + bytecode[max] = strippedloadstring(dumped,strip,formatters["slot %s (%s)"](max,name)) + collectgarbage("step") end - -- we don't need tracing in such tables - bytecode[max] = strippedloadstring(concat(code,"\n"),storage.strip,format("slot %s (%s)",max,name)) - collectgarbage("step") + storage.max = max end - storage.max = max -end -lua.registerfinalizer(dump,"dump storage") + lua.registerfinalizer(dump,"dump storage") + +end -- to be tested with otf caching: @@ -115,31 +149,14 @@ statistics.register("stored bytecode data", function() local tofmodules = storage.tofmodules or 0 local tofdumps = storage.toftables or 0 if environment.initex then - local luautilities = utilities.lua - local nofstrippedbytes = luautilities.nofstrippedbytes - local nofstrippedchunks = luautilities.nofstrippedchunks - if nofstrippedbytes > 0 then - return format("%s modules, %s tables, %s chunks, %s chunks stripped (%s bytes)", - nofmodules, - nofdumps, - nofmodules + nofdumps, - nofstrippedchunks, - nofstrippedbytes - ) - elseif nofstrippedchunks > 0 then - return format("%s modules, %s tables, %s chunks, %s chunks stripped", - nofmodules, - nofdumps, - nofmodules + nofdumps, - nofstrippedchunks - ) - else - return format("%s modules, %s tables, %s chunks", - nofmodules, - nofdumps, - nofmodules + nofdumps - ) - end + local luautilities = utilities.lua + return format("%s modules, %s tables, %s chunks, %s chunks stripped (%s bytes)", + nofmodules, + nofdumps, + nofmodules + nofdumps, + luautilities.nofstrippedchunks or 0, + luautilities.nofstrippedbytes or 0 + ) else return format("%s modules (%0.3f sec), %s tables (%0.3f sec), %s chunks (%0.3f sec)", nofmodules, tofmodules, diff --git a/tex/context/base/lxml-lpt.lua b/tex/context/base/lxml-lpt.lua index 51ab321b9..8567f2623 100644 --- a/tex/context/base/lxml-lpt.lua +++ b/tex/context/base/lxml-lpt.lua @@ -1039,37 +1039,6 @@ local function normal_apply(list,parsed,nofparsed,order) return collected end ---~ local function applylpath(list,pattern) ---~ -- we avoid an extra call ---~ local parsed = cache[pattern] ---~ if parsed then ---~ lpathcalls = lpathcalls + 1 ---~ lpathcached = lpathcached + 1 ---~ elseif type(pattern) == "table" then ---~ lpathcalls = lpathcalls + 1 ---~ parsed = pattern ---~ else ---~ parsed = lpath(pattern) or pattern ---~ end ---~ if not parsed then ---~ return ---~ end ---~ local nofparsed = #parsed ---~ if nofparsed == 0 then ---~ return -- something is wrong ---~ end ---~ local one = list[1] -- we could have a third argument: isroot and list or list[1] or whatever we like ... todo ---~ if not one then ---~ return -- something is wrong ---~ elseif not trace_lpath then ---~ return normal_apply(list,parsed,nofparsed,one.mi) ---~ elseif trace_lprofile then ---~ return profiled_apply(list,parsed,nofparsed,one.mi) ---~ else ---~ return traced_apply(list,parsed,nofparsed,one.mi) ---~ end ---~ end - local function applylpath(list,pattern) if not list then return @@ -1384,8 +1353,13 @@ function xml.elements(root,pattern,reverse) -- r, d, k local collected = applylpath(root,pattern) if not collected then return dummy - elseif reverse then - local c = #collected + 1 + end + local n = #collected + if n == 0 then + return dummy + end + if reverse then + local c = n + 1 return function() if c > 1 then c = c - 1 @@ -1395,7 +1369,7 @@ function xml.elements(root,pattern,reverse) -- r, d, k end end else - local n, c = #collected, 0 + local c = 0 return function() if c < n then c = c + 1 @@ -1411,8 +1385,13 @@ function xml.collected(root,pattern,reverse) -- e local collected = applylpath(root,pattern) if not collected then return dummy - elseif reverse then - local c = #collected + 1 + end + local n = #collected + if n == 0 then + return dummy + end + if reverse then + local c = n + 1 return function() if c > 1 then c = c - 1 @@ -1420,7 +1399,7 @@ function xml.collected(root,pattern,reverse) -- e end end else - local n, c = #collected, 0 + local c = 0 return function() if c < n then c = c + 1 @@ -1441,7 +1420,7 @@ end -- texy (see xfdf): -local function split(e) +local function split(e) -- todo: use helpers / lpeg local dt = e.dt if dt then for i=1,#dt do diff --git a/tex/context/base/lxml-tex.lua b/tex/context/base/lxml-tex.lua index 2cbdfc886..111b1445a 100644 --- a/tex/context/base/lxml-tex.lua +++ b/tex/context/base/lxml-tex.lua @@ -36,6 +36,7 @@ local xmlwithelements = xml.withelements local xmlserialize, xmlcollect, xmltext, xmltostring = xml.serialize, xml.collect, xml.text, xml.tostring local xmlapplylpath = xml.applylpath local xmlunprivatized, xmlprivatetoken, xmlprivatecodes = xml.unprivatized, xml.privatetoken, xml.privatecodes +local xmlstripelement = xml.stripelement local variables = (interfaces and interfaces.variables) or { } @@ -915,16 +916,18 @@ function lxml.setsetup(id,pattern,setup) end end end + elseif setup == "-" then + for c=1,nc do + collected[c].command = false + end + elseif setup == "+" then + for c=1,nc do + collected[c].command = true + end else for c=1,nc do local e = collected[c] - if setup == "-" then - e.command = false - elseif setup == "+" then - e.command = true - else - e.command = e.tg - end + e.command = e.tg end end elseif trace_setups then @@ -967,16 +970,18 @@ function lxml.setsetup(id,pattern,setup) end end end + elseif b == "-" then + for c=1,nc do + collected[c].command = false + end + elseif b == "+" then + for c=1,nc do + collected[c].command = true + end else for c=1,nc do local e = collected[c] - if b == "-" then - e.command = false - elseif b == "+" then - e.command = true - else - e.command = a .. e.tg - end + e.command = a .. e.tg end end elseif trace_setups then @@ -1186,7 +1191,7 @@ local function stripped(collected) -- tricky as we strip in place local nc = #collected if nc > 0 then for c=1,nc do - cprint(xml.stripelement(collected[c])) + cprint(xmlstripelement(collected[c])) end end end @@ -1311,10 +1316,11 @@ function texfinalizers.name(collected,n) c = collected[nc-n+1] end if c then - if c.ns == "" then + local ns = c.ns + if not ns or ns == "" then contextsprint(ctxcatcodes,c.tg) else - contextsprint(ctxcatcodes,c.ns,":",c.tg) + contextsprint(ctxcatcodes,ns,":",c.tg) end end end @@ -1327,11 +1333,11 @@ function texfinalizers.tags(collected,nonamespace) if nc > 0 then for c=1,nc do local e = collected[c] - local ns, tg = e.ns, e.tg - if nonamespace or ns == "" then - contextsprint(ctxcatcodes,tg) + local ns = e.ns + if nonamespace or (not ns or ns == "") then + contextsprint(ctxcatcodes,e.tg) else - contextsprint(ctxcatcodes,ns,":",tg) + contextsprint(ctxcatcodes,ns,":",e.tg) end end end @@ -1341,11 +1347,10 @@ end -- local function verbatim(id,before,after) - local root = getid(id) - if root then - if before then contextsprint(ctxcatcodes,before,"[",root.tg or "?","]") end - lxml.toverbatim(xmltostring(root.dt)) ---~ lxml.toverbatim(xml.totext(root.dt)) + local e = getid(id) + if e then + if before then contextsprint(ctxcatcodes,before,"[",e.tg or "?","]") end + lxml.toverbatim(xmltostring(e.dt)) -- lxml.toverbatim(xml.totext(e.dt)) if after then contextsprint(ctxcatcodes,after) end end end @@ -1451,66 +1456,112 @@ end lxml.index = lxml.position function lxml.pos(id) - local root = getid(id) - contextsprint(ctxcatcodes,(root and root.ni) or 0) -end + local e = getid(id) + contextsprint(ctxcatcodes,e and e.ni or 0) +end + +-- function lxml.att(id,a,default) +-- local root = getid(id) +-- if root then +-- local at = root.at +-- local str = (at and at[a]) or default +-- if str and str ~= "" then +-- contextsprint(notcatcodes,str) +-- end +-- elseif default then +-- contextsprint(notcatcodes,default) +-- end +-- end +-- +-- no need for an assignment so: function lxml.att(id,a,default) - local root = getid(id) - if root then - local at = root.at - local str = (at and at[a]) or default - if str and str ~= "" then - contextsprint(notcatcodes,str) + local e = getid(id) + if e then + local at = e.at + if at then + -- normally always true + local str = at[a] + if not str then + if default and default ~= "" then + contextsprint(notcatcodes,default) + end + elseif str ~= "" then + contextsprint(notcatcodes,str) + end + elseif default and default ~= "" then + contextsprint(notcatcodes,default) end - elseif default then + elseif default and default ~= "" then contextsprint(notcatcodes,default) end end function lxml.name(id) -- or remapped name? -> lxml.info, combine - local r = getid(id) - local ns = r.rn or r.ns or "" - if ns ~= "" then - contextsprint(ctxcatcodes,ns,":",r.tg) - else - contextsprint(ctxcatcodes,r.tg) + local e = getid(id) + if e then + local ns = e.rn or e.ns + if ns and ns ~= "" then + contextsprint(ctxcatcodes,ns,":",e.tg) + else + contextsprint(ctxcatcodes,e.tg) + end end end function lxml.match(id) -- or remapped name? -> lxml.info, combine - contextsprint(ctxcatcodes,getid(id).mi or 0) + local e = getid(id) + contextsprint(ctxcatcodes,e and e.mi or 0) end function lxml.tag(id) -- tag vs name -> also in l-xml tag->name - contextsprint(ctxcatcodes,getid(id).tg or "") + local e = getid(id) + if e then + local tg = e.tg + if tg and tg ~= "" then + contextsprint(ctxcatcodes,tg) + end + end end function lxml.namespace(id) -- or remapped name? - local root = getid(id) - contextsprint(ctxcatcodes,root.rn or root.ns or "") + local e = getid(id) + if e then + local ns = e.rn or e.ns + if ns and ns ~= "" then + contextsprint(ctxcatcodes,ns) + end + end end function lxml.flush(id) - id = getid(id) - local dt = id and id.dt - if dt then - xmlsprint(dt) + local e = getid(id) + if e then + local dt = e.dt + if dt then + xmlsprint(dt) + end end end function lxml.snippet(id,i) local e = getid(id) if e then - local edt = e.dt - if edt then - xmlsprint(edt[i]) + local dt = e.dt + if dt then + local dti = dt[i] + if dti then + xmlsprint(dti) + end end end end function lxml.direct(id) - xmlsprint(getid(id)) + local e = getid(id) + if e then + xmlsprint(e) + end end function lxml.command(id,pattern,cmd) diff --git a/tex/context/base/m-spreadsheet.lua b/tex/context/base/m-spreadsheet.lua index f329acf9a..1b3c5cb34 100644 --- a/tex/context/base/m-spreadsheet.lua +++ b/tex/context/base/m-spreadsheet.lua @@ -129,10 +129,10 @@ function datacell(a,b,...) end local function checktemplate(s) - if find(s,"%%") then + if find(s,"%",1,true) then -- normal template return s - elseif find(s,"@") then + elseif find(s,"@",1,true) then -- tex specific template return gsub(s,"@","%%") else diff --git a/tex/context/base/math-dir.lua b/tex/context/base/math-dir.lua index 525d07831..bcc5461e9 100644 --- a/tex/context/base/math-dir.lua +++ b/tex/context/base/math-dir.lua @@ -33,6 +33,7 @@ local getid = nuts.getid local getlist = nuts.getlist local setfield = nuts.setfield local getattr = nuts.getattr +local setattr = nuts.setattr local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after diff --git a/tex/context/base/math-fbk.lua b/tex/context/base/math-fbk.lua index f4bd1348a..70a8ae8d6 100644 --- a/tex/context/base/math-fbk.lua +++ b/tex/context/base/math-fbk.lua @@ -180,12 +180,12 @@ end -- virtualcharacters[0x208B] = 0x002B virtualcharacters[0x207A] = function(data) - data.replacement = 0x2212 + data.replacement = 0x002B return raised(data) end virtualcharacters[0x207B] = function(data) - data.replacement = 0x002B + data.replacement = 0x2212 return raised(data) end @@ -512,7 +512,7 @@ addextra(0xFE940, { category = "mn", description="SMALL ANNUITY SYMBOL", unicode local function actuarian(data) local characters = data.target.characters local parameters = data.target.parameters - local basechar = characters[0x0078] -- x (0x0058 X) + local basechar = characters[0x0078] -- x (0x0058 X) or 0x1D431 local linewidth = parameters.xheight / 10 local basewidth = basechar.width local baseheight = basechar.height diff --git a/tex/context/base/math-fen.mkiv b/tex/context/base/math-fen.mkiv index fe959cc1e..33afbf675 100644 --- a/tex/context/base/math-fen.mkiv +++ b/tex/context/base/math-fen.mkiv @@ -235,6 +235,7 @@ \expandafter\let\csname\??mathright\meaning ⟫\endcsname\Rdoubleangle \expandafter\let\csname\??mathright\meaning }\endcsname\Rbrace \expandafter\let\csname\??mathright\meaning |\endcsname\Rbar +\expandafter\let\csname\??mathright\meaning ‖\endcsname\Rdoublebar \expandafter\let\csname\??mathright\meaning ⦀\endcsname\Rtriplebar \expandafter\let\csname\??mathright\meaning /\endcsname\Rsolidus \expandafter\let\csname\??mathright\meaning .\endcsname\Rnothing diff --git a/tex/context/base/math-frc.mkiv b/tex/context/base/math-frc.mkiv index 65fa30942..f4f3f2b84 100644 --- a/tex/context/base/math-frc.mkiv +++ b/tex/context/base/math-frc.mkiv @@ -274,7 +274,7 @@ %D \getbuffer \unexpanded\def\cfrac - {\doifnextoptionalelse\math_cfrac_yes\math_cfrac_nop} + {\doifnextoptionalcselse\math_cfrac_yes\math_cfrac_nop} \def\math_cfrac_nop {\math_cfrac_indeed[cc]} \def\math_cfrac_yes[#1]{\math_cfrac_indeed[#1cc]} diff --git a/tex/context/base/math-ini.lua b/tex/context/base/math-ini.lua index 1351559a0..9772ce538 100644 --- a/tex/context/base/math-ini.lua +++ b/tex/context/base/math-ini.lua @@ -22,8 +22,8 @@ local floor = math.floor local context = context local commands = commands -local contextsprint = context.sprint -local contextfprint = context.fprint -- a bit inefficient +local context_sprint = context.sprint +----- context_fprint = context.fprint -- a bit inefficient local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) @@ -213,28 +213,28 @@ local f_char = formatters[ [[\Umathchardef\%s "%X "%X "%X ]] ] local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing if class == classes.accent then - contextsprint(f_accent(name,family,slot)) + context_sprint(f_accent(name,family,slot)) elseif class == classes.topaccent then - contextsprint(f_topaccent(name,family,slot)) + context_sprint(f_topaccent(name,family,slot)) elseif class == classes.botaccent then - contextsprint(f_botaccent(name,family,slot)) + context_sprint(f_botaccent(name,family,slot)) elseif class == classes.over then - contextsprint(f_over(name,family,slot)) + context_sprint(f_over(name,family,slot)) elseif class == classes.under then - contextsprint(f_under(name,family,slot)) + context_sprint(f_under(name,family,slot)) elseif class == open_class or class == close_class or class == middle_class then setdelcode("global",slot,{family,slot,0,0}) - contextsprint(f_fence(name,class,family,slot)) + context_sprint(f_fence(name,class,family,slot)) elseif class == classes.delimiter then setdelcode("global",slot,{family,slot,0,0}) - contextsprint(f_delimiter(name,family,slot)) + context_sprint(f_delimiter(name,family,slot)) elseif class == classes.radical then - contextsprint(f_radical(name,family,slot)) + context_sprint(f_radical(name,family,slot)) elseif class == classes.root then - contextsprint(f_root(name,family,slot)) + context_sprint(f_root(name,family,slot)) else -- beware, open/close and other specials should not end up here - contextsprint(f_char(name,class,family,slot)) + context_sprint(f_char(name,class,family,slot)) end end diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv index bf9f5278c..38069eba7 100644 --- a/tex/context/base/math-ini.mkiv +++ b/tex/context/base/math-ini.mkiv @@ -117,7 +117,7 @@ \installswitchcommandhandler \??mathematics {mathematics} \??mathematics \unexpanded\def\startmathematics % no grouping, if ever then also an optional second - {\doifnextoptionalelse\math_mathematics_start_yes\math_mathematics_start_nop} + {\doifnextoptionalcselse\math_mathematics_start_yes\math_mathematics_start_nop} \unexpanded\def\math_mathematics_start_yes[#1]% {\pushmacro\currentmathematics @@ -366,10 +366,39 @@ %D Let's define a few comands here: -\definemathcommand [mathstrut] {\vphantom{(}} +%definemathcommand [mathstrut] {\vphantom{(}} %definemathcommand [joinrel] {\mathrel{\mkern-3mu}} \definemathcommand [joinrel] [rel] {\mkern-3mu} +\chardef\c_math_strut"28 + +\unexpanded\def\math_strut_htdp#1% + {\s!height\fontcharht#1\c_math_strut + \s!depth \fontchardp#1\c_math_strut} + +\unexpanded\def\math_strut_normal + {\vrule + \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}% + \s!width \zeropoint + \relax} + +\unexpanded\def\math_strut_visual + {\hskip-.01\emwidth + \vrule + \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}% + \s!width .02\emwidth + \relax + \hskip-.01\emwidth} + +\unexpanded\def\showmathstruts % let's not overload \nath_strut_normal + {\let\math_strut\math_strut_visual} + +\let\math_strut\math_strut_normal + +% \unexpanded\def\mathstrut{\mathcodecommand{nothing}{\math_strut}} + +\definemathcommand [mathstrut] {\math_strut} + %D We could have a arg variant \unknown\ but not now. \unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits} diff --git a/tex/context/base/math-noa.lua b/tex/context/base/math-noa.lua index 4e25fe206..a7f0fcf55 100644 --- a/tex/context/base/math-noa.lua +++ b/tex/context/base/math-noa.lua @@ -60,15 +60,14 @@ local tonut = nuts.tonut local nutstring = nuts.tostring local getfield = nuts.getfield +local setfield = nuts.setfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid -local getattr = nuts.getattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar - -local setfield = nuts.setfield +local getattr = nuts.getattr local setattr = nuts.setattr local insert_node_after = nuts.insert_after diff --git a/tex/context/base/math-rad.mkvi b/tex/context/base/math-rad.mkvi index c6053071e..f27114b88 100644 --- a/tex/context/base/math-rad.mkvi +++ b/tex/context/base/math-rad.mkvi @@ -28,7 +28,7 @@ \def\root#1\of{\rootradical{#1}} % #2 -\unexpanded\def\sqrt{\doifnextoptionalelse\rootwithdegree\rootwithoutdegree} +\unexpanded\def\sqrt{\doifnextoptionalcselse\rootwithdegree\rootwithoutdegree} \def\styledrootradical#1#2% so that \text works ok ... \rootradical behaves somewhat weird {\normalexpanded{\rootradical{\normalunexpanded{#1}}{\noexpand\triggermathstyle{\normalmathstyle}\normalunexpanded{#2}}}} @@ -62,7 +62,7 @@ \unexpanded\def\math_radical_handle#tag% {\begingroup \edef\currentmathradical{#tag}% - \doifnextoptionalelse\math_radical_degree_yes\math_radical_degree_nop} + \doifnextoptionalcselse\math_radical_degree_yes\math_radical_degree_nop} \def\math_radical_alternative{\csname\??mathradicalalternative\mathradicalparameter\c!alternative\endcsname} diff --git a/tex/context/base/meta-fnt.lua b/tex/context/base/meta-fnt.lua index cf47f0c92..596d0f456 100644 --- a/tex/context/base/meta-fnt.lua +++ b/tex/context/base/meta-fnt.lua @@ -29,7 +29,7 @@ local characters, descriptions = { }, { } local factor, code, slot, width, height, depth, total, variants, bbox, llx, lly, urx, ury = 100, { }, 0, 0, 0, 0, 0, 0, true, 0, 0, 0, 0 -- The next variant of ActualText is what Taco and I could come up with --- eventually. As of September 2013 Acrobat copies okay, Summatra copies a +-- eventually. As of September 2013 Acrobat copies okay, Sumatra copies a -- question mark, pdftotext injects an extra space and Okular adds a -- newline plus space. @@ -79,7 +79,7 @@ local flusher = { if inline then characters[slot] = { commands = { - { "special", "pdf: " .. topdf(slot,code) }, + { "special", "pdf:" .. topdf(slot,code) }, } } else diff --git a/tex/context/base/meta-pdf.lua b/tex/context/base/meta-pdf.lua index 46e20ad31..512384450 100644 --- a/tex/context/base/meta-pdf.lua +++ b/tex/context/base/meta-pdf.lua @@ -38,8 +38,8 @@ local mptopdf = metapost.mptopdf mptopdf.nofconverted = 0 -local f_translate = formatters["1 0 0 0 1 %f %f cm"] -- no %s due to 1e-035 issues -local f_concat = formatters["%f %f %f %f %f %f cm"] -- no %s due to 1e-035 issues +local f_translate = formatters["1 0 0 0 1 %F %F cm"] -- no %s due to 1e-035 issues +local f_concat = formatters["%F %F %F %F %F %F cm"] -- no %s due to 1e-035 issues local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false diff --git a/tex/context/base/meta-tex.mkiv b/tex/context/base/meta-tex.mkiv index deac883c8..c690765fd 100644 --- a/tex/context/base/meta-tex.mkiv +++ b/tex/context/base/meta-tex.mkiv @@ -68,7 +68,7 @@ \unexpanded\def\definetextext[#1]% {\def\currenttextext{#1}% - \doifnextoptionalelse\meta_textext_define_one\meta_textext_define_zero} + \doifnextoptionalcselse\meta_textext_define_one\meta_textext_define_zero} \def\meta_textext_define_one {\setvalue{\??graphictexarguments1:\currenttextext}} \def\meta_textext_define_zero{\setvalue{\??graphictexarguments0:\currenttextext}} @@ -79,7 +79,7 @@ {textext.drt("\mpsometxt#1{\ctxlua{metapost.escaped(\!!bs#2\!!es)}}")} \unexpanded\def\mpsometxt % no _ catcode - {\doifnextoptionalelse\meta_some_txt_indeed_yes\meta_some_txt_indeed_nop} + {\doifnextoptionalcselse\meta_some_txt_indeed_yes\meta_some_txt_indeed_nop} \def\meta_some_txt_indeed_yes[#1]% {\def\currenttextext{#1}% diff --git a/tex/context/base/mlib-pdf.lua b/tex/context/base/mlib-pdf.lua index 6bb08bd1d..d25dde884 100644 --- a/tex/context/base/mlib-pdf.lua +++ b/tex/context/base/mlib-pdf.lua @@ -41,6 +41,18 @@ local experiment = true -- uses context(node) that already does delayed nod local savedliterals = nil -- needs checking local mpsliteral = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral)) -- pdfliteral.mode = 1 +local f_f = formatters["%F"] + +local f_m = formatters["%F %F m"] +local f_c = formatters["%F %F %F %F %F %F c"] +local f_l = formatters["%F %F l"] +local f_cm = formatters["%F %F %F %F %F %F cm"] +local f_M = formatters["%F M"] +local f_j = formatters["%i j"] +local f_J = formatters["%i J"] +local f_d = formatters["[%s] %F d"] +local f_w = formatters["%F w"] + local pdfliteral = function(s) local literal = copy_node(mpsliteral) literal.data = s @@ -119,7 +131,7 @@ end function pdfflusher.startfigure(n,llx,lly,urx,ury,message) savedliterals = nil metapost.n = metapost.n + 1 - context.startMPLIBtoPDF(llx,lly,urx,ury) + context.startMPLIBtoPDF(f_f(llx),f_f(lly),f_f(urx),f_f(ury)) if message then pdfflusher.comment(message) end end @@ -192,11 +204,11 @@ local function flushnormalpath(path, t, open) nt = nt + 1 pth = path[i] if not ith then - t[nt] = formatters["%f %f m"](pth.x_coord,pth.y_coord) + t[nt] = f_m(pth.x_coord,pth.y_coord) elseif curved(ith,pth) then - t[nt] = formatters["%f %f %f %f %f %f c"](ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) + t[nt] = f_c(ith.right_x,ith.right_y,pth.left_x,pth.left_y,pth.x_coord,pth.y_coord) else - t[nt] = formatters["%f %f l"](pth.x_coord,pth.y_coord) + t[nt] = f_l(pth.x_coord,pth.y_coord) end ith = pth end @@ -204,15 +216,15 @@ local function flushnormalpath(path, t, open) nt = nt + 1 local one = path[1] if curved(pth,one) then - t[nt] = formatters["%f %f %f %f %f %f c"](pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) + t[nt] = f_c(pth.right_x,pth.right_y,one.left_x,one.left_y,one.x_coord,one.y_coord ) else - t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord) + t[nt] = f_l(one.x_coord,one.y_coord) end elseif #path == 1 then -- special case .. draw point local one = path[1] nt = nt + 1 - t[nt] = formatters["%f %f l"](one.x_coord,one.y_coord) + t[nt] = f_l(one.x_coord,one.y_coord) end return t end @@ -226,18 +238,18 @@ local function flushconcatpath(path, t, open) nt = 0 end nt = nt + 1 - t[nt] = formatters["%f %f %f %f %f %f cm"](sx,rx,ry,sy,tx,ty) + t[nt] = f_cm(sx,rx,ry,sy,tx,ty) for i=1,#path do nt = nt + 1 pth = path[i] if not ith then - t[nt] = formatters["%f %f m"](mpconcat(pth.x_coord,pth.y_coord)) + t[nt] = f_m(mpconcat(pth.x_coord,pth.y_coord)) elseif curved(ith,pth) then local a, b = mpconcat(ith.right_x,ith.right_y) local c, d = mpconcat(pth.left_x,pth.left_y) - t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(pth.x_coord,pth.y_coord)) + t[nt] = f_c(a,b,c,d,mpconcat(pth.x_coord,pth.y_coord)) else - t[nt] = formatters["%f %f l"](mpconcat(pth.x_coord, pth.y_coord)) + t[nt] = f_l(mpconcat(pth.x_coord, pth.y_coord)) end ith = pth end @@ -247,15 +259,15 @@ local function flushconcatpath(path, t, open) if curved(pth,one) then local a, b = mpconcat(pth.right_x,pth.right_y) local c, d = mpconcat(one.left_x,one.left_y) - t[nt] = formatters["%f %f %f %f %f %f c"](a,b,c,d,mpconcat(one.x_coord, one.y_coord)) + t[nt] = f_c(a,b,c,d,mpconcat(one.x_coord, one.y_coord)) else - t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord)) + t[nt] = f_l(mpconcat(one.x_coord,one.y_coord)) end elseif #path == 1 then -- special case .. draw point nt = nt + 1 local one = path[1] - t[nt] = formatters["%f %f l"](mpconcat(one.x_coord,one.y_coord)) + t[nt] = f_l(mpconcat(one.x_coord,one.y_coord)) end return t end @@ -431,7 +443,7 @@ function metapost.flush(result,flusher,askedfig) elseif objecttype == "text" then t[#t+1] = "q" local ot = object.transform -- 3,4,5,6,1,2 - t[#t+1] = formatters["%f %f %f %f %f %f cm"](ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%f %f m %f %f %f %f 0 0 cm"](unpack(ot)) + t[#t+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%F %F m %F %F %F %F 0 0 cm"](unpack(ot)) flushfigure(t) -- flush accumulated literals t = { } textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) @@ -456,21 +468,21 @@ function metapost.flush(result,flusher,askedfig) local ml = object.miterlimit if ml and ml ~= miterlimit then miterlimit = ml - t[#t+1] = formatters["%f M"](ml) + t[#t+1] = f_M(ml) end local lj = object.linejoin if lj and lj ~= linejoin then linejoin = lj - t[#t+1] = formatters["%i j"](lj) + t[#t+1] = f_j(lj) end local lc = object.linecap if lc and lc ~= linecap then linecap = lc - t[#t+1] = formatters["%i J"](lc) + t[#t+1] = f_J(lc) end local dl = object.dash if dl then - local d = formatters["[%s] %f d"](concat(dl.dashes or {}," "),dl.offset) + local d = f_d(concat(dl.dashes or {}," "),dl.offset) if d ~= dashed then dashed = d t[#t+1] = dashed @@ -486,7 +498,7 @@ function metapost.flush(result,flusher,askedfig) if pen then if pen.type == 'elliptical' then transformed, penwidth = pen_characteristics(original) -- boolean, value - t[#t+1] = formatters["%f w"](penwidth) -- todo: only if changed + t[#t+1] = f_w(penwidth) -- todo: only if changed if objecttype == 'fill' then objecttype = 'both' end @@ -506,7 +518,7 @@ function metapost.flush(result,flusher,askedfig) if objecttype == "fill" then t[#t+1] = "h f" elseif objecttype == "outline" then - t[#t+1] = (open and "S") or "h S" + t[#t+1] = open and "S" or "h S" elseif objecttype == "both" then t[#t+1] = "h B" end @@ -527,7 +539,7 @@ function metapost.flush(result,flusher,askedfig) if objecttype == "fill" then t[#t+1] = "h f" elseif objecttype == "outline" then - t[#t+1] = (open and "S") or "h S" + t[#t+1] = open and "S" or "h S" elseif objecttype == "both" then t[#t+1] = "h B" end diff --git a/tex/context/base/mlib-pps.lua b/tex/context/base/mlib-pps.lua index 385fb3ece..c76dca245 100644 --- a/tex/context/base/mlib-pps.lua +++ b/tex/context/base/mlib-pps.lua @@ -18,6 +18,9 @@ local formatters = string.formatters local mplib, metapost, lpdf, context = mplib, metapost, lpdf, context +local context = context +local context_setvalue = context.setvalue + local texgetbox = tex.getbox local texsetbox = tex.setbox local copy_list = node.copy_list @@ -82,10 +85,13 @@ function metapost.setoutercolor(mode,colormodel,colorattribute,transparencyattri innertransparency = outertransparency -- not yet used end -local f_gray = formatters["%.3f g %.3f G"] -local f_rgb = formatters["%.3f %.3f %.3f rg %.3f %.3f %.3f RG"] -local f_cmyk = formatters["%.3f %.3f %.3f %.3f k %.3f %.3f %.3f %.3f K"] -local f_cm = formatters["q %f %f %f %f %f %f cm"] +local f_f = formatters["%F"] +local f_f3 = formatters["%.3F"] + +local f_gray = formatters["%.3F g %.3F G"] +local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"] +local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"] +local f_cm = formatters["q %F %F %F %F %F %F cm"] local f_shade = formatters["MpSh%s"] local function checked_color_pair(color,...) @@ -482,8 +488,8 @@ local factor = 65536*(7227/7200) function metapost.edefsxsy(wd,ht,dp) -- helper for figure local hd = ht + dp - context.setvalue("sx",wd ~= 0 and factor/wd or 0) - context.setvalue("sy",hd ~= 0 and factor/hd or 0) + context_setvalue("sx",wd ~= 0 and factor/wd or 0) + context_setvalue("sy",hd ~= 0 and factor/hd or 0) end local function sxsy(wd,ht,dp) -- helper for text @@ -887,21 +893,21 @@ local function tx_analyze(object,prescript) -- todo: hash content and reuse them -- no color elseif #c == 1 then if a and t then - s = formatters["\\directcolored[s=%f,a=%f,t=%f]%s"](c[1],a,t,s) + s = formatters["\\directcolored[s=%F,a=%F,t=%F]%s"](c[1],a,t,s) else - s = formatters["\\directcolored[s=%f]%s"](c[1],s) + s = formatters["\\directcolored[s=%F]%s"](c[1],s) end elseif #c == 3 then if a and t then - s = formatters["\\directcolored[r=%f,g=%f,b=%f,a=%f,t=%f]%s"](c[1],c[2],c[3],a,t,s) + s = formatters["\\directcolored[r=%F,g=%F,b=%F,a=%F,t=%F]%s"](c[1],c[2],c[3],a,t,s) else - s = formatters["\\directcolored[r=%f,g=%f,b=%f]%s"](c[1],c[2],c[3],s) + s = formatters["\\directcolored[r=%F,g=%F,b=%F]%s"](c[1],c[2],c[3],s) end elseif #c == 4 then if a and t then - s = formatters["\\directcolored[c=%f,m=%f,y=%f,k=%f,a=%f,t=%f]%s"](c[1],c[2],c[3],c[4],a,t,s) + s = formatters["\\directcolored[c=%F,m=%F,y=%F,k=%F,a=%F,t=%F]%s"](c[1],c[2],c[3],c[4],a,t,s) else - s = formatters["\\directcolored[c=%f,m=%f,y=%f,k=%f]%s"](c[1],c[2],c[3],c[4],s) + s = formatters["\\directcolored[c=%F,m=%F,y=%F,k=%F]%s"](c[1],c[2],c[3],c[4],s) end end context.MPLIBsettext(tx_last,s) @@ -956,12 +962,12 @@ local function tx_process(object,prescript,before,after) before[#before+1] = function() -- flush always happens, we can have a special flush function injected before context.MPLIBgettextscaledcm(n, - format("%f",sx), -- bah ... %s no longer checks - format("%f",rx), -- bah ... %s no longer checks - format("%f",ry), -- bah ... %s no longer checks - format("%f",sy), -- bah ... %s no longer checks - format("%f",tx), -- bah ... %s no longer checks - format("%f",ty), -- bah ... %s no longer checks + f_f(sx), -- bah ... %s no longer checks + f_f(rx), -- bah ... %s no longer checks + f_f(ry), -- bah ... %s no longer checks + f_f(sy), -- bah ... %s no longer checks + f_f(tx), -- bah ... %s no longer checks + f_f(ty), -- bah ... %s no longer checks sxsy(box.width,box.height,box.depth)) end else @@ -1136,7 +1142,7 @@ end -- color and transparency local value = Cs ( ( - (Carg(1) * C((1-P(","))^1)) / function(a,b) return format("%0.3f",a * tonumber(b)) end + (Carg(1) * C((1-P(","))^1)) / function(a,b) return f_f3(a * tonumber(b)) end + P(","))^1 ) diff --git a/tex/context/base/mult-aux.lua b/tex/context/base/mult-aux.lua index bdc626d4c..5a103213c 100644 --- a/tex/context/base/mult-aux.lua +++ b/tex/context/base/mult-aux.lua @@ -54,7 +54,7 @@ function namespaces.define(namespace,settings) if trace_namespaces then report_namespaces("namespace %a for %a uses parent %a",namespace,name,parent) end - if not find(parent,"\\") then + if not find(parent,"\\",1,true) then parent = "\\" .. prefix .. parent -- todo: check if defined end diff --git a/tex/context/base/mult-aux.mkiv b/tex/context/base/mult-aux.mkiv index 6c44a0ec9..1811f9592 100644 --- a/tex/context/base/mult-aux.mkiv +++ b/tex/context/base/mult-aux.mkiv @@ -106,10 +106,14 @@ \doubleexpandafter\gobbleoneargument \else \mult_interfaces_get_parameters_assign#1==\empty\_e_o_p_ - \doubleexpandafter\mult_interfaces_get_parameters_item + % \doubleexpandafter\mult_interfaces_get_parameters_item % saves skipping when at end \fi\fi#2} -\def\mult_interfaces_get_parameters_error#1#2#3% +\def\mult_interfaces_get_parameters_error#1#2% #3% + {\mult_interfaces_get_parameters_error_indeed{#1}{#2}% + \gobbleoneargument} + +\def\mult_interfaces_get_parameters_error_indeed#1#2% {\showassignerror{#2}{\the\inputlineno\space(#1)}} \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ @@ -118,9 +122,54 @@ \else\ifx#3\empty \doubleexpandafter\mult_interfaces_get_parameters_error \else - \doubleexpandafter\dosetvalue + \doubleexpandafter\mult_interfaces_def \fi\fi - \m_mult_interfaces_namespace{#1}{#2}} + \m_mult_interfaces_namespace{#1}{#2}% + \doubleexpandafter\mult_interfaces_get_parameters_item} + +\startinterface english + + % some 10% faster + + \let\mult_interfaces_get_parameters_error\undefined + + \def\mult_interfaces_get_parameters_error_one#1\csname#2#3\endcsname#4% + {\mult_interfaces_get_parameters_error_indeed{#2}{#3}\iftrue} + + \def\mult_interfaces_get_parameters_error_two#1\csname#2#3\endcsname#4% + {\mult_interfaces_get_parameters_error_indeed{#2}{#3}} + + \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ + {\ifx\empty#1\empty + \mult_interfaces_get_parameters_error_one + \else\ifx#3\empty + \mult_interfaces_get_parameters_error_two + \else + \expandafter\def\csname\m_mult_interfaces_namespace#1\endcsname{#2}% + \fi\fi + \doubleexpandafter\mult_interfaces_get_parameters_item} + + % interesting but not faster + % + % \def\mult_interfaces_get_parameters_error_one#1\m_mult_interfaces_namespace#2\fi\fi% + % {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi} + % + % \def\mult_interfaces_get_parameters_error_two#1\m_mult_interfaces_namespace#2\fi\fi% + % {\mult_interfaces_get_parameters_error_indeed\m_mult_interfaces_namespace{#2}\m_mult_interfaces_namespace\s!dummy\fi\fi} + % + % \def\mult_interfaces_get_parameters_assign#1=#2=#3#4\_e_o_p_ + % {\expandafter\def\csname + % \ifx\empty#1\empty + % \mult_interfaces_get_parameters_error_one + % \else\ifx#3\empty + % \mult_interfaces_get_parameters_error_two + % \else + % \m_mult_interfaces_namespace#1% + % \fi\fi + % \endcsname{#2} + % \doubleexpandafter\mult_interfaces_get_parameters_item} + +\stopinterface \newif\ifassignment @@ -132,6 +181,24 @@ % End of experimental code. +\unexpanded\def\mult_interfaces_let #1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +\unexpanded\def\mult_interfaces_lete#1#2{\expandafter\let \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname\empty} +\unexpanded\def\mult_interfaces_def #1#2{\expandafter\def \csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +\unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +\unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} +\unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1\ifcsname\k!prefix!#2\endcsname\csname\k!prefix!#2\endcsname\else#2\fi\endcsname} + +\startinterface english + + \unexpanded\def\mult_interfaces_let #1#2{\expandafter \let\csname#1#2\endcsname} + \unexpanded\def\mult_interfaces_lete#1#2{\expandafter \let\csname#1#2\endcsname\empty} + \unexpanded\def\mult_interfaces_def #1#2{\expandafter \def\csname#1#2\endcsname} + \unexpanded\def\mult_interfaces_edef#1#2{\expandafter\edef\csname#1#2\endcsname} + \unexpanded\def\mult_interfaces_gdef#1#2{\expandafter\gdef\csname#1#2\endcsname} + \unexpanded\def\mult_interfaces_xdef#1#2{\expandafter\xdef\csname#1#2\endcsname} + +\stopinterface + % the commented detokenized variant that backtracks ... needs testing usage first % % \let\whatever\relax @@ -207,14 +274,14 @@ % In \MKIV\ we can probably use the english variant for all other % languages too. -% todo: inline the \do*value +% todo: inline the def/let \unexpanded\def\mult_interfaces_install_parameter_set_handler#1#2#3#4#5#6% {\ifx#2\relax\let#2\empty\fi - \unexpanded\def#3{\dosetvalue {#1#2:}}% ##1 {##2} (braces are mandate) - \unexpanded\def#4{\dosetevalue{#1#2:}}% ##1 {##2} (braces are mandate) - \unexpanded\def#5{\doletvalue {#1#2:}}% ##1 ##2 - \unexpanded\def#6{\doletvalue {#1#2:}\empty}}% ##1 + \unexpanded\def#3{\mult_interfaces_def {#1#2:}}% ##1 {##2} (braces are mandate) + \unexpanded\def#4{\mult_interfaces_edef{#1#2:}}% ##1 {##2} (braces are mandate) + \unexpanded\def#5{\mult_interfaces_let {#1#2:}}% ##1 ##2 + \unexpanded\def#6{\mult_interfaces_lete{#1#2:}}}% ##1 \startinterface english @@ -548,10 +615,10 @@ \expandafter\noexpand\csname everysetup#2\endcsname}} \unexpanded\def\mult_interfaces_install_direct_parameter_set_handler#1#2#3#4#5% - {\unexpanded\def#2{\dosetvalue #1}% - \unexpanded\def#3{\dosetevalue#1}% - \unexpanded\def#4{\doletvalue #1}% - \unexpanded\def#5{\doletvalue #1\empty}}% + {\unexpanded\def#2{\mult_interfaces_def #1}% + \unexpanded\def#3{\mult_interfaces_edef#1}% + \unexpanded\def#4{\mult_interfaces_let #1}% + \unexpanded\def#5{\mult_interfaces_let #1\empty}}% \startinterface english @@ -694,9 +761,8 @@ \ctxcommand{registernamespace(\number\c_mult_interfaces_n_of_namespaces,"#1")}% \fi} -\def\mult_interfaces_get_parameters_error#1#2#3% redefined - {\ctxcommand{showassignerror("#1","#2","#3",\the\inputlineno)}% - \waitonfatalerror} +\def\mult_interfaces_get_parameters_error_indeed#1#2% + {\ctxcommand{showassignerror("#1","#2",\the\inputlineno)}} % no longer \waitonfatalerror % We install two core namespaces here, as we want nice error messages. Maybe % we will reserve the first 9. @@ -856,4 +922,198 @@ %D \edef\m_class_whatever{whatever} %D \stoptyping +% experiment: in principle this is faster but not that noticeable as we don't do that +% many assignments and mechanism that do are also slow; the advantage is mostly nicer +% in tracing + +\def\s!simple{simple} +\def\s!single{single} +\def\s!double{double} +\def\s!triple{triple} + +\unexpanded\def\syst_helpers_double_empty#1#2#3% + {\syst_helpers_argument_reset + \doifnextoptionalelse + {\syst_helpers_double_empty_one_yes_mult#2#3}% + {\syst_helpers_double_empty_one_nop_mult#1}} + +\def\syst_helpers_double_empty_one_yes_mult#1#2[#3]% + {\firstargumenttrue + \doifnextoptionalelse + {\secondargumenttrue#2[{#3}]}% + {\syst_helpers_double_empty_two_nop_mult#1{#3}}} + +\def\syst_helpers_double_empty_one_nop_mult% #1% + {\firstargumentfalse + \secondargumentfalse + }% #1} + +\def\syst_helpers_double_empty_two_nop_mult + {\secondargumentfalse + \if_next_blank_space_token + \expandafter\syst_helpers_double_empty_one_spaced_mult + \else + \expandafter\syst_helpers_double_empty_one_normal_mult + \fi} + +\def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] } +\def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]} + +\unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8% + {\ifx#3\relax\let#3\empty\fi + \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it + \newtoks#4% + \newtoks#7% + \edef\m_mult_interface_setup{\strippedcsname#2_}% + \unexpanded\edef#2{\syst_helpers_double_empty + \csname\m_mult_interface_setup\s!simple\endcsname + \csname\m_mult_interface_setup\s!single\endcsname + \csname\m_mult_interface_setup\s!double\endcsname}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]% + {\let#6#3% + \def#8####1% we will have a simple one as well + {\edef#3{####1}% + \mult_interfaces_get_parameters{#1#3:}[##2]% + \the#4}% + \processcommalist[##1]#8% + \let#3#6% + \the#7}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]% + {\let#6#3% + \let#3\empty + \mult_interfaces_get_parameters{#1:}[##1]% + \the#4% + \let#3#6% + \the#7}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname% + {\let#6#3% + \let#3\empty + \the#4% + \let#3#6% + \the#7}} + +\unexpanded\def\installsetuphandler#1#2% + {\normalexpanded + {\mult_interfaces_install_setup_handler + {\noexpand#1}% \??aa + \expandafter\noexpand\csname setup#2\endcsname + \expandafter\noexpand\csname current#2\endcsname + \expandafter\noexpand\csname everysetup#2\endcsname + \expandafter\noexpand\csname setupcurrent#2\endcsname + \expandafter\noexpand\csname saved_setup_current#2\endcsname + \expandafter\noexpand\csname everysetup#2root\endcsname + \expandafter\noexpand\csname nested_setup_current#2\endcsname}} + +\unexpanded\def\syst_helpers_triple_empty#1#2#3#4% + {\syst_helpers_argument_reset + \doifnextoptionalelse + {\syst_helpers_triple_empty_one_yes_mult#2#3#4}% + {\syst_helpers_triple_empty_one_nop_mult#1}} + +\def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]% + {\firstargumenttrue + \doifnextoptionalelse + {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}% + {\syst_helpers_triple_empty_two_nop_mult#1{#4}}} + +\def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]% + {\secondargumenttrue + \doifnextoptionalelse + {\thirdargumenttrue#2[{#3}][{#4}]}% + {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}} + +\def\syst_helpers_triple_empty_one_nop_mult % #1% + {\firstargumentfalse + \secondargumentfalse + \thirdargumentfalse + } % #1 + +\def\syst_helpers_triple_empty_two_nop_mult + {\secondargumentfalse + \thirdargumentfalse + \if_next_blank_space_token + \expandafter\syst_helpers_triple_empty_two_spaced_mult + \else + \expandafter\syst_helpers_triple_empty_two_normal_mult + \fi} + +\def\syst_helpers_triple_empty_three_nop_mult + {\thirdargumentfalse + \if_next_blank_space_token + \expandafter\syst_helpers_triple_empty_three_spaced_mult + \else + \expandafter\syst_helpers_triple_empty_three_normal_mult + \fi} + +\def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] } +\def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]} +\def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] } +\def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]} + +\unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8% + {\ifx#3\relax\let#3\empty\fi + \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% + \newtoks#4% + \edef\m_mult_interface_setup{\strippedcsname#2_}% + \unexpanded\edef#2{\syst_helpers_triple_empty + \csname\m_mult_interface_setup\s!simple\endcsname + \csname\m_mult_interface_setup\s!single\endcsname + \csname\m_mult_interface_setup\s!double\endcsname + \csname\m_mult_interface_setup\s!triple\endcsname}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]% + {\let#7#3% + \def#8####1% + {\edef#3{####1}% + \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}% + \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent + \the#4}% + \processcommalist[##1]#8% + \let#3#7}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]% + {\let#7#3% + \def#8####1% + {\edef#3{####1}% + #6% checks parent and sets if needed + \mult_interfaces_get_parameters{#1#3:}[##2]% + \the#4}% + \processcommalist[##1]#8% + \let#3#7}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]% + {\let#7#3% + \let#3\empty + \mult_interfaces_get_parameters{#1:}[##1]% + \the#4% + \let#3#7}% + \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname% + {\let#7#3% + \let#3\empty + \the#4% + \let#3#7}} + +\unexpanded\def\installautosetuphandler#1#2% + {\normalexpanded + {\mult_interfaces_install_auto_setup_handler + {\noexpand#1}% \??aa + \expandafter\noexpand\csname setup#2\endcsname + \expandafter\noexpand\csname current#2\endcsname + \expandafter\noexpand\csname everysetup#2\endcsname + \expandafter\noexpand\csname setupcurrent#2\endcsname + \expandafter\noexpand\csname check#2parent\endcsname + \expandafter\noexpand\csname saved_setup_current#2\endcsname + \expandafter\noexpand\csname nested_setup_current#2\endcsname}} + +% okay, we can also get rid of the #9, but thsi code looks pretty bad, while the previous is +% still okay given that we can also use #6 as setup1 (so in fact we can save some cs again and +% only use one extra) +% +% \global\advance\commalevel \plusone +% \expandafter\def\csname\??nextcommalevel\the\commalevel\endcsname####1,% +% {\edef#3{####1}% +% \mult_interfaces_get_parameters{#1#3:}[##2]% +% \the#5% +% \syst_helpers_do_process_comma_item}% +% \expandafter\syst_helpers_do_do_process_comma_item\gobbleoneargument\relax##1,]\relax +% % \syst_helpers_do_do_process_comma_item##1,]\relax +% \global\advance\commalevel \minusone + \protect diff --git a/tex/context/base/mult-def.lua b/tex/context/base/mult-def.lua index 65db8fd5e..fc2b932c2 100644 --- a/tex/context/base/mult-def.lua +++ b/tex/context/base/mult-def.lua @@ -3055,7 +3055,7 @@ return { ["pe"]="درج‌شماره‌صفحه", ["ro"]="punenumarpagina", }, - ["placereferencelist"]={ + ["placereferencelist"]={ -- not in mkiv ["cs"]="placereferencelist", ["de"]="placereferencelist", ["en"]="placereferencelist", @@ -9708,7 +9708,7 @@ return { ["en"]="reference", ["fr"]="reference", ["it"]="riferimento", - ["nl"]="verwijzing", + ["nl"]="referentie", ["pe"]="مرجع", ["ro"]="referinta", }, @@ -10917,7 +10917,7 @@ return { ["en"]="unknownreference", ["fr"]="referenceinconnue", ["it"]="riferimentoingoto", - ["nl"]="onbekendeverwijzing", + ["nl"]="onbekendereferentie", ["pe"]="مرجع‌ناشناس", ["ro"]="referintanecunoscuta", }, diff --git a/tex/context/base/mult-def.mkiv b/tex/context/base/mult-def.mkiv index 9206743f4..35b212710 100644 --- a/tex/context/base/mult-def.mkiv +++ b/tex/context/base/mult-def.mkiv @@ -64,6 +64,8 @@ \def\c!group {group} \def\c!groupsuffix {groupsuffix} +\def\c!referencemethod {referencemethod} % forward both + \def\v!dataset {dataset} \def\v!compressseparator{compressseparator} \def\v!notation {notation} @@ -117,6 +119,10 @@ \def\c!etaldisplay{etaldisplay} \def\c!etaltext {etaltext} +\ifdefined\v!simplelist\else \def\v!simplelist{simplelist} \fi +\ifdefined\v!sorting \else \def\v!sorting {sorting} \fi +\ifdefined\v!synonym \else \def\v!synonym {synonym} \fi + % stop todo \protect \endinput diff --git a/tex/context/base/mult-ini.lua b/tex/context/base/mult-ini.lua index e3ff904a6..08f1639d0 100644 --- a/tex/context/base/mult-ini.lua +++ b/tex/context/base/mult-ini.lua @@ -299,12 +299,12 @@ function commands.getmessage(category,tag,default) context(interfaces.getmessage(category,tag,default)) end -function commands.showassignerror(namespace,key,value,line) - local ns, instance = match(namespace,"^(%d+)[^%a]+(%a+)") +function commands.showassignerror(namespace,key,line) + local ns, instance = match(namespace,"^(%d+)[^%a]+(%a*)") if ns then namespace = corenamespaces[tonumber(ns)] or ns end - if instance then + if instance and instance ~= "" then context.writestatus("setup",formatters["error in line %a, namespace %a, instance %a, key %a"](line,namespace,instance,key)) else context.writestatus("setup",formatters["error in line %a, namespace %a, key %a"](line,namespace,key)) diff --git a/tex/context/base/mult-low.lua b/tex/context/base/mult-low.lua index 250b20c22..a5b8874d6 100644 --- a/tex/context/base/mult-low.lua +++ b/tex/context/base/mult-low.lua @@ -47,7 +47,7 @@ return { "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", - "xmlcatcodes", + "xmlcatcodes", "ctdcatcodes", -- "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", @@ -136,6 +136,7 @@ return { "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", + "startcontextdefinitioncode", "stopcontextdefinitioncode", -- "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "doifelsecommandhandler","doifnotcommandhandler","doifcommandhandler", @@ -219,7 +220,9 @@ return { -- "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifinsetelse", - "doifnextcharelse", "doifnextoptionalelse", "doifnextbgroupelse", "doifnextparenthesiselse", "doiffastoptionalcheckelse", + "doifnextcharelse", "doifnextoptionalelse", "doifnextoptionalcselse", "doiffastoptionalcheckelse", + "doifnextbgroupelse", "doifnextbgroupcselse", + "doifnextparenthesiselse", "doifundefinedelse", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifsomethingelse", @@ -353,6 +356,8 @@ return { "definenamedlua", "obeylualines", "obeyluatokens", "startluacode", "stopluacode", "startlua", "stoplua", + "startctxfunction","stopctxfunction","ctxfunction", + "startctxfunctiondefinition","stopctxfunctiondefinition", -- "carryoverpar", -- diff --git a/tex/context/base/mult-nl.mkii b/tex/context/base/mult-nl.mkii index a1f9742f1..015f58ff1 100644 --- a/tex/context/base/mult-nl.mkii +++ b/tex/context/base/mult-nl.mkii @@ -944,7 +944,7 @@ \setinterfaceconstant{reduction}{reductie} \setinterfaceconstant{ref}{ref} \setinterfaceconstant{refcommand}{refcommand} -\setinterfaceconstant{reference}{verwijzing} +\setinterfaceconstant{reference}{referentie} \setinterfaceconstant{referenceprefix}{referenceprefix} \setinterfaceconstant{referencing}{refereren} \setinterfaceconstant{region}{gebied} @@ -1094,7 +1094,7 @@ \setinterfaceconstant{totalnumber}{totalnumber} \setinterfaceconstant{type}{type} \setinterfaceconstant{unit}{eenheid} -\setinterfaceconstant{unknownreference}{onbekendeverwijzing} +\setinterfaceconstant{unknownreference}{onbekendereferentie} \setinterfaceconstant{urlalternative}{urlvariant} \setinterfaceconstant{urlspace}{urlspatie} \setinterfaceconstant{validate}{valideer} diff --git a/tex/context/base/mult-prm.lua b/tex/context/base/mult-prm.lua index e6fa4abcc..f0b850a5c 100644 --- a/tex/context/base/mult-prm.lua +++ b/tex/context/base/mult-prm.lua @@ -235,6 +235,7 @@ return { "luatexdatestamp", "luatexrevision", "luatexversion", + "luafunction", "mathstyle", "nokerns", "noligs", @@ -573,10 +574,10 @@ return { "catcodetable", "char", "chardef", - "chardp", - "charht", - "charit", - "charwd", +--"chardp", +--"charht", +--"charit", +--"charwd", "cleaders", "clearmarks", "closein", diff --git a/tex/context/base/node-aux.lua b/tex/context/base/node-aux.lua index 7f4b0342a..499116258 100644 --- a/tex/context/base/node-aux.lua +++ b/tex/context/base/node-aux.lua @@ -49,6 +49,7 @@ local copy_node_list = nuts.copy_list local find_tail = nuts.tail local insert_node_after = nuts.insert_after local isnode = nuts.is_node +local getbox = nuts.getbox local nodes_traverse_id = nodes.traverse_id local nodes_first_glyph = nodes.first_glyph @@ -61,8 +62,52 @@ local unsetvalue = attributes.unsetvalue local current_font = font.current +local texsetbox = tex.setbox + local report_error = logs.reporter("node-aux:error") +-- At some point we figured that copying before using was the safest bet +-- when dealing with boxes at the tex end. This is because tex also needs +-- to manage the grouping (i.e. savestack). However, there is an easy +-- solution that keeps the tex end happy as tex.setbox deals with this. The +-- overhead of one temporary list node is neglectable. +-- +-- function tex.takebox(id) +-- local box = tex.getbox(id) +-- if box then +-- local copy = node.copy(box) +-- local list = box.list +-- copy.list = list +-- box.list = nil +-- tex.setbox(id,nil) +-- return copy +-- end +-- end + +local function takebox(id) + local box = getbox(id) + if box then + local copy = copy_node(box) + local list = getlist(box) + setfield(copy,"list",list) + setfield(box,"list",nil) + texsetbox(id,nil) + return copy + end +end + +function nodes.takebox(id) + local b = takebox(id) + if b then + return tonode(b) + end +end + +nuts.takebox = takebox +tex.takebox = nodes.takebox -- sometimes more clear + +-- so far + local function repackhlist(list,...) local temp, b = hpack_nodes(list,...) list = getlist(temp) diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index 8476b47a6..250035f39 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -20,14 +20,13 @@ local tonode = nuts.tonode local tonut = nuts.tonut local getfield = nuts.getfield +local setfield = nuts.setfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getlist = nuts.getlist local getleader = nuts.getleader local getattr = nuts.getattr - -local setfield = nuts.setfield local setattr = nuts.setattr local copy_node = nuts.copy diff --git a/tex/context/base/node-ini.mkiv b/tex/context/base/node-ini.mkiv index e99653327..142f0d7ba 100644 --- a/tex/context/base/node-ini.mkiv +++ b/tex/context/base/node-ini.mkiv @@ -19,9 +19,7 @@ \registerctxluafile{node-ini}{1.001} \registerctxluafile{node-met}{1.001} - -\ctxlua{if nodes.gonuts then context.registerctxluafile("node-nut","1.001") end} - +\registerctxluafile{node-nut}{1.001} \registerctxluafile{node-res}{1.001} \registerctxluafile{node-dir}{1.001} \registerctxluafile{node-aux}{1.001} @@ -36,6 +34,8 @@ \registerctxluafile{node-acc}{1.001} % experimental %registerctxluafile{node-prp}{1.001} % makes no sense (yet) +\doiffileelse{node-ppt.lua}{\registerctxluafile{node-ppt}{1.001}}{} + \newcount\c_node_tracers_show_box % box number \unexpanded\def\shownextnodes{\afterassignment\node_tracers_show_next\c_node_tracers_show_box} diff --git a/tex/context/base/node-inj.lua b/tex/context/base/node-inj.lua index f30070e9e..b91646ffc 100644 --- a/tex/context/base/node-inj.lua +++ b/tex/context/base/node-inj.lua @@ -8,8 +8,7 @@ if not modules then modules = { } end modules ['node-inj'] = { -- This is very experimental (this will change when we have luatex > .50 and -- a few pending thingies are available. Also, Idris needs to make a few more --- test fonts. Btw, future versions of luatex will have extended glyph properties --- that can be of help. Some optimizations can go away when we have faster machines. +-- test fonts. Some optimizations can go away when we have faster machines. -- todo: ignore kerns between disc and glyph @@ -30,7 +29,6 @@ local injections = nodes.injections local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc local kern_code = nodecodes.kern local nuts = nodes.nuts @@ -58,7 +56,7 @@ local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local a_kernpair = attributes.private('kernpair') -local a_ligacomp = attributes.private('ligacomp') +----- a_ligacomp = attributes.private('ligacomp') local a_markbase = attributes.private('markbase') local a_markmark = attributes.private('markmark') local a_markdone = attributes.private('markdone') @@ -127,9 +125,9 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) end end -function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- ba=baseanchor, ma=markanchor - local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this - local bound = getattr(base,a_markbase) -- fails again we should pass it +function injections.setmark(start,base,factor,rlmode,ba,ma) -- ba=baseanchor, ma=markanchor + local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) + local bound = getattr(base,a_markbase) local index = 1 if bound then local mb = marks[bound] @@ -144,13 +142,12 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound) end end --- index = index or 1 index = index or 1 bound = #marks + 1 setattr(base,a_markbase,bound) setattr(start,a_markmark,bound) setattr(start,a_markdone,index) - marks[bound] = { [index] = { dx, dy, rlmode, baseismark } } + marks[bound] = { [index] = { dx, dy, rlmode } } return dx, dy, bound end @@ -354,7 +351,7 @@ function injections.handler(head,where,keep) end end if maxt > 0 then - local ny = getfield(n,"yoffset") + local ny = getfield(n,"yoffset") -- hm, n unset ? for i=maxt,1,-1 do ny = ny + d[i] local ti = t[i] @@ -516,8 +513,7 @@ function injections.handler(head,where,keep) -- if trace_injections then -- show_result(head) -- end -head = tonode(head) - return head, true + return tonode(head), true elseif not keep then kerns, cursives, marks = { }, { }, { } end diff --git a/tex/context/base/node-met.lua b/tex/context/base/node-met.lua index d52349b4a..335ce2a98 100644 --- a/tex/context/base/node-met.lua +++ b/tex/context/base/node-met.lua @@ -68,7 +68,7 @@ local nodes = nodes nodes.gonuts = gonuts -local nodecodes = nodes.codes +local nodecodes = nodes.nodecodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist diff --git a/tex/context/base/node-nut.lua b/tex/context/base/node-nut.lua index 4732b09eb..a2f4c93ff 100644 --- a/tex/context/base/node-nut.lua +++ b/tex/context/base/node-nut.lua @@ -648,3 +648,55 @@ nuts.untracedslide = untracedslide nuts.nestedtracedslide = nestedtracedslide -- nuts.slide = tracedslide + +-- this might move + +local propertydata = direct.get_properties_table and direct.get_properties_table() + +local getattr = nuts.getattr +local setattr = nuts.setattr + +if propertydata then + + nodes.properties = { + data = propertydata, + } + + direct.set_properties_mode(true,false) + -- direct.set_properties_mode(true,true) + + -- experimental code with respect to copying attributes has been removed + -- as it doesn't pay of (most attributes are only accessed once anyway) + + nuts.getprop = function(n,k) + local p = propertydata[n] + if p then + return p[k] + end + end + + nuts.setprop = function(n,k,v) + if v then + local p = propertydata[n] + if p then + p[k] = v + else + propertydata[n] = { [k] = v } + end + end + end + + nodes.setprop = nodes.setproperty + nodes.getprop = nodes.getproperty + +else + + -- for testing and simple cases + + nuts.getprop = getattr + nuts.setprop = setattr + + nodes.setprop = getattr + nodes.getprop = setattr + +end diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index 7cfbde849..5623dbb05 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -123,28 +123,27 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t if result and resolved then if head == first then if trace_backend then - report_area("head: %04i %s %s %s => w=%p, h=%p, d=%p, c=%s",reference,pardir or "---",txtdir or "----",tosequence(first,last,true),width,height,depth,resolved) + report_area("%s: %04i %s %s %s => w=%p, h=%p, d=%p, c=%S","head", + reference,pardir or "---",txtdir or "---",tosequence(first,last,true),width,height,depth,resolved) end setfield(result,"next",first) setfield(first,"prev",result) return result, last else if trace_backend then - report_area("middle: %04i %s %s => w=%p, h=%p, d=%p, c=%s",reference,pardir or "---",txtdir or "----",tosequence(first,last,true),width,height,depth,resolved) + report_area("%s: %04i %s %s %s => w=%p, h=%p, d=%p, c=%S","middle", + reference,pardir or "---",txtdir or "---",tosequence(first,last,true),width,height,depth,resolved) end local prev = getprev(first) if prev then - setfield(result,"next",first) - setfield(result,"prev",prev) setfield(prev,"next",result) - setfield(first,"prev",result) - else - setfield(result,"next",first) - setfield(first,"prev",result) - end - if first == getnext(head) then - setfield(head,"next",result) -- hm, weird + setfield(result,"prev",prev) end + setfield(result,"next",first) + setfield(first,"prev",result) +-- if first == getnext(head) then +-- setfield(head,"next",result) -- hm, weird +-- end return head, last end else @@ -195,7 +194,8 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) -- todo: only when width is ok if result and resolved then if trace_backend then - report_area("box: %04i %s %s: w=%p, h=%p, d=%p, c=%s",reference,pardir or "---",txtdir or "----",width,height,depth,resolved) + report_area("%s: %04i %s %s %s: w=%p, h=%p, d=%p, c=%S","box", + reference,pardir or "---",txtdir or "----","[]",width,height,depth,resolved) end if not first then setfield(current,"list",result) @@ -226,6 +226,10 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx txtdir = txtdir or "===" while current do local id = getid(current) +-- do +-- local r = getattr(current,attribute) +-- if r then print(attribute,r) end +-- end if id == hlist_code or id == vlist_code then local r = getattr(current,attribute) -- somehow reference is true so the following fails (second one not done) in @@ -297,7 +301,7 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) end local list = getlist(current) if list then - setfield(current,"list",inject_area(list,attribute,make,stack,done,current,pardir,txtdir)) + setfield(current,"list",(inject_area(list,attribute,make,stack,done,current,pardir,txtdir))) end elseif id == whatsit_code then local subtype = getsubtype(current) @@ -429,6 +433,7 @@ annot = tonut(annot) end if current then setfield(current,"next",annot) + setfield(annot,"prev",current) else result = annot end @@ -503,32 +508,28 @@ local function makedestination(width,height,depth,reference) step = 4*65536 width, height, depth = 5*step, 5*step, 0 end - for n=1,#name do - local rule = hpack_list(colorize(width,height,depth,3,reference,"destination")) - setfield(rule,"width",0) - if not result then - result, current = rule, rule - else - setfield(current,"next",rule) - setfield(rule,"prev",current) - current = rule - end - width, height = width - step, height - step + local rule = hpack_list(colorize(width,height,depth,3,reference,"destination")) + setfield(rule,"width",0) + if not result then + result, current = rule, rule + else + setfield(current,"next",rule) + setfield(rule,"prev",current) + current = rule end + width, height = width - step, height - step end nofdestinations = nofdestinations + 1 - for n=1,#name do - local annot = nodeinjections.destination(width,height,depth,name[n],view) - if annot then -annot = tonut(annot) -- obsolete soon - if not result then - result = annot - else - setfield(current,"next",annot) - setfield(annot,"prev",current) - end - current = find_node_tail(annot) + local annot = nodeinjections.destination(width,height,depth,name,view) + if annot then + annot = tonut(annot) -- obsolete soon + if result then + setfield(current,"next",annot) + setfield(annot,"prev",current) + else + result = annot end + current = find_node_tail(annot) end if result then -- some internal error diff --git a/tex/context/base/node-res.lua b/tex/context/base/node-res.lua index 968283745..0d45d1bd6 100644 --- a/tex/context/base/node-res.lua +++ b/tex/context/base/node-res.lua @@ -74,6 +74,9 @@ local copy_nut = nuts.copy local new_nut = nuts.new local free_nut = nuts.free +local copy_node = nodes.copy +local new_node = nodes.new + -- at some point we could have a dual set (the overhead of tonut is not much larger than -- metatable associations at the lua/c end esp if we also take assignments into account @@ -288,19 +291,85 @@ function nutpool.rule(width,height,depth,dir) -- w/h/d == nil will let them adap return n end --- if node.has_field(latelua,'string') then - function nutpool.latelua(code) - local n = copy_nut(latelua) - setfield(n,"string",code) +function nutpool.latelua(code) + local n = copy_nut(latelua) + setfield(n,"string",code) + return n +end + +if context and _cldo_ then + + -- a typical case where we have more nodes than nuts + + local context = context + + local f_cldo = string.formatters["_cldo_(%i)"] + local register = context.registerfunction + + local latelua_node = register_node(new_node("whatsit",whatsitcodes.latelua)) + local latelua_nut = register_nut (new_nut ("whatsit",whatsitcodes.latelua)) + + local setfield_node = nodes.setfield + local setfield_nut = nuts .setfield + + function nodepool.lateluafunction(f) + local n = copy_node(latelua_node) + setfield_node(n,"string",f_cldo(register(f))) return n end --- else --- function nutpool.latelua(code) --- local n = copy_nut(latelua) --- setfield(n,"data",code) --- return n --- end --- end + function nutpool.lateluafunction(f) + local n = copy_nut(latelua_nut) + setfield_nut(n,"string",f_cldo(register(f))) + return n + end + + -- when function in latelua: + + -- function nodepool.lateluafunction(f) + -- local n = copy_node(latelua_node) + -- setfield_node(n,"string",f) + -- return n + -- end + -- function nutpool.lateluafunction(f) + -- local n = copy_nut(latelua_nut) + -- setfield_nut(n,"string",f) + -- return n + -- end + + local latefunction = nodepool.lateluafunction + local flushnode = context.flushnode + + function context.lateluafunction(f) + flushnode(latefunction(f)) -- hm, quite some indirect calls + end + + -- when function in latelua: + + -- function context.lateluafunction(f) + -- local n = copy_node(latelua_node) + -- setfield_node(n,"string",f) + -- flushnode(n) + -- end + + -- local contextsprint = context.sprint + -- local ctxcatcodes = tex.ctxcatcodes + -- local storenode = context.storenode + + -- when 0.79 is out: + + -- function context.lateluafunction(f) + -- contextsprint(ctxcatcodes,"\\cldl",storenode(latefunction(f))," ") + -- end + + -- when function in latelua: + + -- function context.lateluafunction(f) + -- local n = copy_node(latelua_node) + -- setfield_node(n,"string",f) + -- contextsprint(ctxcatcodes,"\\cldl",storenode(n)," ") + -- end + +end function nutpool.leftmarginkern(glyph,width) local n = copy_nut(left_margin_kern) diff --git a/tex/context/base/pack-com.mkiv b/tex/context/base/pack-com.mkiv index 2c28d6b20..4ca77af1c 100644 --- a/tex/context/base/pack-com.mkiv +++ b/tex/context/base/pack-com.mkiv @@ -626,12 +626,12 @@ \unexpanded\def\placepairedbox[#1]% {\bgroup \edef\currentpairedbox{#1}% - \doifnextoptionalelse\pack_pairedboxes_place\pack_pairedboxes_place_indeed} + \doifnextoptionalcselse\pack_pairedboxes_place\pack_pairedboxes_place_indeed} \unexpanded\def\startplacepairedbox[#1]% {\bgroup \edef\currentpairedbox{#1}% - \doifnextoptionalelse\pack_pairedboxes_place\pack_pairedboxes_place_indeed} + \doifnextoptionalcselse\pack_pairedboxes_place\pack_pairedboxes_place_indeed} \unexpanded\def\stopplacepairedbox {} diff --git a/tex/context/base/pack-mis.mkvi b/tex/context/base/pack-mis.mkvi index 978cc120c..38fcc18e4 100644 --- a/tex/context/base/pack-mis.mkvi +++ b/tex/context/base/pack-mis.mkvi @@ -46,7 +46,7 @@ \unexpanded\def\pack_placement#tag% {\bgroup \edef\currentplacement{#tag}% - \doifnextoptionalelse\pack_placement_yes\pack_placement_nop} + \doifnextoptionalcselse\pack_placement_yes\pack_placement_nop} \def\pack_placement_yes[#settings]% {\setupcurrentplacement[#settings]% diff --git a/tex/context/base/pack-mrl.mkiv b/tex/context/base/pack-mrl.mkiv index 7c3f08825..3e81a4d69 100644 --- a/tex/context/base/pack-mrl.mkiv +++ b/tex/context/base/pack-mrl.mkiv @@ -40,7 +40,7 @@ \unexpanded\def\blackrule {\hbox\bgroup - \doifnextoptionalelse\pack_black_rule_pickup\pack_black_rule_indeed} + \doifnextoptionalcselse\pack_black_rule_pickup\pack_black_rule_indeed} \def\pack_black_rule_pickup[#1]% {\setupcurrentblackrules[#1]% @@ -96,7 +96,7 @@ \unexpanded\def\blackrules % probably never used {\hbox\bgroup - \doifnextoptionalelse\pack_black_rules_pickup\pack_black_rules_indeed} + \doifnextoptionalcselse\pack_black_rules_pickup\pack_black_rules_indeed} \def\pack_black_rules_pickup[#1]% {\setupcurrentblackrules[#1]% diff --git a/tex/context/base/pack-rul.lua b/tex/context/base/pack-rul.lua index c8ed0722b..5796da800 100644 --- a/tex/context/base/pack-rul.lua +++ b/tex/context/base/pack-rul.lua @@ -33,8 +33,6 @@ local getsubtype = nuts.getsubtype local getbox = nuts.getbox local hpack = nuts.hpack -local free = nuts.free -local copy = nuts.copy_list local traverse_id = nuts.traverse_id local node_dimensions = nuts.dimensions diff --git a/tex/context/base/page-flt.lua b/tex/context/base/page-flt.lua index 11aa2be21..7b1afc55c 100644 --- a/tex/context/base/page-flt.lua +++ b/tex/context/base/page-flt.lua @@ -21,20 +21,23 @@ local C, S, P, lpegmatch = lpeg.C, lpeg.S, lpeg.P, lpeg.match -- we use floatbox, floatwidth, floatheight -- text page leftpage rightpage (todo: top, bottom, margin, order) -local copy_node_list = node.copy_list +local copy_node_list = node.copy_list +local flush_node_list = node.flush_list +local copy_node = node.copy -local setdimen = tex.setdimen -local setcount = tex.setcount -local texgetbox = tex.getbox -local texsetbox = tex.setbox +local setdimen = tex.setdimen +local setcount = tex.setcount +local texgetbox = tex.getbox +local texsetbox = tex.setbox +local textakebox = nodes.takebox -floats = floats or { } -local floats = floats +floats = floats or { } +local floats = floats -local noffloats = 0 -local last = nil -local default = "text" -local pushed = { } +local noffloats = 0 +local last = nil +local default = "text" +local pushed = { } local function initialize() return { @@ -105,21 +108,20 @@ end function floats.save(which,data) which = which or default - local b = texgetbox("floatbox") + local b = textakebox("floatbox") if b then local stack = stacks[which] noffloats = noffloats + 1 - local w, h, d = b.width, b.height, b.depth local t = { n = noffloats, data = data or { }, - box = copy_node_list(b), + box = b, } - texsetbox("floatbox",nil) insert(stack,t) setcount("global","savednoffloats",#stacks[default]) if trace_floats then - report_floats("%s, category %a, number %a, slot %a, width %p, height %p, depth %p","saving",which,noffloats,#stack,w,h,d) + report_floats("%s, category %a, number %a, slot %a, width %p, height %p, depth %p","saving", + which,noffloats,#stack,b.width,b.height,b.depth) else interfaces.showmessage("floatblocks",2,noffloats) end @@ -132,14 +134,13 @@ function floats.resave(which) if last then which = which or default local stack = stacks[which] - local b = texgetbox("floatbox") - local w, h, d = b.width, b.height, b.depth - last.box = copy_node_list(b) - texsetbox("floatbox",nil) + local b = textakebox("floatbox") + last.box = b insert(stack,1,last) setcount("global","savednoffloats",#stacks[default]) if trace_floats then - report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","resaving",which,noffloats,#stack,w,h,d) + report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","resaving", + which,noffloats,#stack,b.width,b.height,b.depth) else interfaces.showmessage("floatblocks",2,noffloats) end @@ -153,9 +154,10 @@ function floats.flush(which,n,bylabel) local stack = stacks[which] local t, b, n = get(stack,n or 1,bylabel) if t then - local w, h, d = setdimensions(b) if trace_floats then - report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","flushing",which,t.n,n,w,h,d) + local w, h, d = setdimensions(b) -- ? + report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","flushing", + which,t.n,n,w,h,d) else interfaces.showmessage("floatblocks",3,t.n) end @@ -173,9 +175,10 @@ function floats.consult(which,n) local stack = stacks[which] local t, b, n = get(stack,n) if t then - local w, h, d = setdimensions(b) if trace_floats then - report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","consulting",which,t.n,n,w,h,d) + local w, h, d = setdimensions(b) + report_floats("%s, category %a, number %a, slot %a width %p, height %p, depth %p","consulting", + which,t.n,n,w,h,d) end return t, b, n else @@ -270,16 +273,16 @@ end -- interface -local context = context -local setvalue = context.setvalue +local context = context +local context_setvalue = context.setvalue -commands.flushfloat = floats.flush -commands.savefloat = floats.save -commands.resavefloat = floats.resave -commands.pushfloat = floats.push -commands.popfloat = floats.pop -commands.consultfloat = floats.consult -commands.collectfloat = floats.collect +commands.flushfloat = floats.flush +commands.savefloat = floats.save +commands.resavefloat = floats.resave +commands.pushfloat = floats.push +commands.popfloat = floats.pop +commands.consultfloat = floats.consult +commands.collectfloat = floats.collect function commands.getfloatvariable (...) local v = floats.getvariable(...) if v then context(v) end end function commands.checkedpagefloat (...) local v = floats.checkedpagefloat(...) if v then context(v) end end @@ -289,8 +292,8 @@ function commands.doifelsesavedfloat(...) commands.doifelse(floats.nofstacked(.. function commands.analysefloatmethod(str) -- currently only one method local method, label, row, column = floats.analysemethod(str) - setvalue("floatmethod",method or "") - setvalue("floatlabel", label or "") - setvalue("floatrow", row or "") - setvalue("floatcolumn",column or "") + context_setvalue("floatmethod",method or "") + context_setvalue("floatlabel", label or "") + context_setvalue("floatrow", row or "") + context_setvalue("floatcolumn",column or "") end diff --git a/tex/context/base/page-imp.mkiv b/tex/context/base/page-imp.mkiv index cfa535ab2..230ede570 100644 --- a/tex/context/base/page-imp.mkiv +++ b/tex/context/base/page-imp.mkiv @@ -41,7 +41,7 @@ \prependtoks \page_shipouts_flush_text_data \to \everylastshipout - + % Problem: we need to apply the finalizers to a to be shipped out page (as % we can have positioning involved). However, we can also add stuff in the % imposition, like cropmarks. Fortunately we do that with metapost so diff --git a/tex/context/base/page-mix.lua b/tex/context/base/page-mix.lua index 30a1fdccd..0fbaa4e30 100644 --- a/tex/context/base/page-mix.lua +++ b/tex/context/base/page-mix.lua @@ -295,18 +295,47 @@ local function setsplit(specification) -- a rather large function local rest = nil local lastlocked = nil local lastcurrent = nil + local lastcontent = nil local backtracked = false if trace_state then report_state("setting collector to column %s",column) end + local function unlock(penalty) + if lastlocked then + if trace_state then + report_state("penalty %s, unlocking in column %s",penalty or "-",column) + end + lastlocked = nil + end + lastcurrent = nil + lastcontent = nil + end + + local function lock(penalty,current) + if trace_state then + report_state("penalty %s, locking in column %s",penalty,column) + end + lastlocked = penalty + lastcurrent = current or lastcurrent + lastcontent = nil + end + local function backtrack(start) local current = start -- first skip over glue and penalty while current do local id = getid(current) - if id == glue_code or id == penalty_code then + if id == glue_code then + if trace_state then + report_state("backtracking over %s in column %s","glue",column) + end + current = getprev(current) + elseif id == penalty_code then + if trace_state then + report_state("backtracking over %s in column %s","penalty",column) + end current = getprev(current) else break @@ -315,13 +344,24 @@ local function setsplit(specification) -- a rather large function -- then skip over content while current do local id = getid(current) - if id == glue_code or id == penalty_code then + if id == glue_code then + if trace_state then + report_state("quitting at %s in column %s","glue",column) + end + break + elseif id == penalty_code then + if trace_state then + report_state("quitting at %s in column %s","penalty",column) + end break else current = getprev(current) end end if not current then + if trace_state then + report_state("no effective backtracking in column %s",column) + end current = start end return current @@ -338,7 +378,12 @@ local function setsplit(specification) -- a rather large function backtracked = true end lastcurrent = nil - lastlocked = nil + if lastlocked then + if trace_state then + report_state("unlocking in column %s",column) + end + lastlocked = nil + end end if head == lasthead then if trace_state then @@ -439,6 +484,9 @@ local function setsplit(specification) -- a rather large function else -- what else? ignore? treat as valid as usual? end + if lastcontent then + unlock() + end end local function process_kern(current,nxt) @@ -466,24 +514,27 @@ local function setsplit(specification) -- a rather large function local function process_rule(current,nxt) -- simple variant of h|vlist local advance = getfield(current,"height") -- + getfield(current,"depth") - local state, skipped = checked(advance+currentskips,"rule") - if trace_state then - report_state("%-7s > column %s, state %a, rule, advance %p, height %p","rule",column,state,advance,inserttotal,height) - if skipped ~= 0 then - report_state("%-7s > column %s, discarded %p","rule",column,skipped) + if advance ~= 0 then + local state, skipped = checked(advance,"rule") + if trace_state then + report_state("%-7s > column %s, state %a, rule, advance %p, height %p","rule",column,state,advance,inserttotal,height) + if skipped ~= 0 then + report_state("%-7s > column %s, discarded %p","rule",column,skipped) + end end + if state == "quit" then + return true + end + height = height + depth + skip + advance + -- if state == "next" then + -- height = height + nextskips + -- else + -- height = height + currentskips + -- end + depth = getfield(current,"depth") + skip = 0 end - if state == "quit" then - return true - end - height = height + depth + skip + advance - if state == "next" then - height = height + nextskips - else - height = height + currentskips - end - depth = getfield(current,"depth") - skip = 0 + lastcontent = current end -- okay, here we could do some badness like magic but we want something @@ -495,8 +546,7 @@ local function setsplit(specification) -- a rather large function local function process_penalty(current,nxt) local penalty = getfield(current,"penalty") if penalty == 0 then - lastlocked = nil - lastcurrent = nil + unlock(penalty) elseif penalty == forcedbreak then local needed = getattribute(current,a_checkedbreak) local proceed = not needed or needed == 0 @@ -508,8 +558,7 @@ local function setsplit(specification) -- a rather large function end end if proceed then - lastlocked = nil - lastcurrent = nil + unlock(penalty) local okay, skipped = gotonext() if okay then if trace_state then @@ -530,18 +579,15 @@ local function setsplit(specification) -- a rather large function end elseif penalty < 0 then -- we don't care too much - lastlocked = nil - lastcurrent = nil + unlock(penalty) elseif penalty >= 10000 then if not lastcurrent then - lastcurrent = current - lastlocked = penalty + lock(penalty,current) elseif penalty > lastlocked then - lastlocked = penalty + lock(penalty) end else - lastlocked = nil - lastcurrent = nil + unlock(penalty) end end @@ -582,8 +628,11 @@ local function setsplit(specification) -- a rather large function if trace_state then report_state("%-7s > column %s, height %p, depth %p, skip %p","line",column,height,depth,skip) end + lastcontent = current end +local kept = head + while current do local id = getid(current) @@ -633,14 +682,16 @@ local function setsplit(specification) -- a rather large function if not current then if trace_state then - report_state("nilling rest") + report_state("nothing left") end - rest = nil - elseif rest == lasthead then + -- needs well defined case + -- rest = nil + elseif rest == lasthead then if trace_state then - report_state("nilling rest as rest is lasthead") + report_state("rest equals lasthead") end - rest = nil + -- test case: x\index{AB} \index{AA}x \blank \placeindex + -- makes line disappear: rest = nil end if stripbottom then diff --git a/tex/context/base/page-mix.mkiv b/tex/context/base/page-mix.mkiv index d2bb38ca0..38b5d672f 100644 --- a/tex/context/base/page-mix.mkiv +++ b/tex/context/base/page-mix.mkiv @@ -75,7 +75,7 @@ \let\startmixedcolumns\relax % defined later \let\stopmixedcolumns \relax % defined later -\appendtoks +\appendtoks % could become an option \setuevalue{\e!start\currentmixedcolumns}{\startmixedcolumns[\currentmixedcolumns]}% \setuevalue{\e!stop \currentmixedcolumns}{\stopmixedcolumns}% \to \everydefinemixedcolumns @@ -500,7 +500,9 @@ \setvalue{\??mixedcolumnsstop\s!otr}% {\par \ifcase\c_page_mix_otr_nesting\or - \doif{\mixedcolumnsparameter\c!balance}\v!yes{\c_page_mix_routine\c_page_mix_routine_balance}% + \doifelse{\mixedcolumnsparameter\c!balance}\v!yes + {\c_page_mix_routine\c_page_mix_routine_balance}% + {\penalty-\plustenthousand}% weird hack, we need to trigger the otr sometimes (new per 20140306, see balancing-001.tex) \page_otr_trigger_output_routine \fi} diff --git a/tex/context/base/page-mul.mkiv b/tex/context/base/page-mul.mkiv index 73d84fe14..0063b3311 100644 --- a/tex/context/base/page-mul.mkiv +++ b/tex/context/base/page-mul.mkiv @@ -960,7 +960,7 @@ \ifnum\c_page_mul_balance_tries>\c_page_mul_balance_tries_max\relax \showmessage\m!columns7\empty \else - \showmessage\m!columns8{\the\c_page_mul_balance_tries\space}% + \showmessage\m!columns8{\the\c_page_mul_balance_tries}% \fi \egroup} diff --git a/tex/context/base/page-txt.mkvi b/tex/context/base/page-txt.mkvi index 240f0e00b..6d8d50028 100644 --- a/tex/context/base/page-txt.mkvi +++ b/tex/context/base/page-txt.mkvi @@ -440,12 +440,12 @@ \def\page_layouts_set_text_content[#vertical][#horizontal][#one][#two][#three]% header text middle text/text {\iffifthargument - \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\c!text:#one}\c!middletext}% + \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\v!text:#one}\c!middletext}% {\page_layouts_process_element_double \c!leftstyle \c!leftcolor \c!leftwidth {#two}% \c!rightstyle\c!rightcolor\c!rightwidth{#three}}% \else\iffourthargument - \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\c!text:#one}\c!middletext}% + \setvalue{\namedlayoutelementhash{#vertical:#horizontal}\executeifdefined{\??layouttextcontent\v!text:#one}\c!middletext}% {\page_layouts_process_element_double \c!leftstyle \c!leftcolor \c!leftwidth {#two}% \c!rightstyle\c!rightcolor\c!rightwidth{#two}}% @@ -462,16 +462,16 @@ \def\page_layouts_reset_text_content[#vertical][#horizontal][#tag]% header text middle {\edef\currentlayoutelement{#vertical:#horizontal}% \ifthirdargument - \letvalueempty{\layoutelementhash\executeifdefined{\??layouttextcontent\c!text:#tag}\c!middletext}% + \letvalueempty{\layoutelementhash\executeifdefined{\??layouttextcontent\v!text:#tag}\c!middletext}% \else\ifsecondargument \resetlayoutelementparameter\c!lefttext \resetlayoutelementparameter\c!middletext \resetlayoutelementparameter\c!righttext \fi\fi} -\letvalue{\??layouttextcontent\c!middle:\c!text}\c!middletext -\letvalue{\??layouttextcontent\c!left :\c!text}\c!lefttext -\letvalue{\??layouttextcontent\c!right :\c!text}\c!righttext +\letvalue{\??layouttextcontent\c!middle:\v!text}\c!middletext +\letvalue{\??layouttextcontent\c!left :\v!text}\c!lefttext +\letvalue{\??layouttextcontent\c!right :\v!text}\c!righttext %D The placement of a whole line is handled by the next two %D macros. These are hooked into the general purpose token diff --git a/tex/context/base/pdfr-def.mkii b/tex/context/base/pdfr-def.mkii index 7554bda9e..b3f67b93f 100644 --- a/tex/context/base/pdfr-def.mkii +++ b/tex/context/base/pdfr-def.mkii @@ -1,4 +1,4 @@ -% filename : pdfr-def.tex +% filename : pdfr-def.mkii % comment : generated by mtxrun --script chars --pdf % author : Hans Hagen, PRAGMA-ADE, Hasselt NL % copyright: PRAGMA ADE / ConTeXt Development Team diff --git a/tex/context/base/phys-dim.lua b/tex/context/base/phys-dim.lua index e40d1eabb..870cbd29b 100644 --- a/tex/context/base/phys-dim.lua +++ b/tex/context/base/phys-dim.lua @@ -39,6 +39,7 @@ if not modules then modules = { } end modules ['phys-dim'] = { -- RevPerSec = [[RPS]], -- RevPerMin = [[RPM]], +local rawset, next = rawset, next local V, P, S, R, C, Cc, Cs, matchlpeg = lpeg.V, lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.match local format, lower = string.format, string.lower local appendlpeg = lpeg.append @@ -506,20 +507,20 @@ local packaged_units = { -- rendering: -local unitsPUS = context.unitsPUS -local unitsPU = context.unitsPU -local unitsPS = context.unitsPS -local unitsP = context.unitsP -local unitsUS = context.unitsUS -local unitsU = context.unitsU -local unitsS = context.unitsS -local unitsO = context.unitsO -local unitsN = context.unitsN -local unitsC = context.unitsC -local unitsQ = context.unitsQ -local unitsNstart = context.unitsNstart -local unitsNstop = context.unitsNstop -local unitsNspace = context.unitsNspace +local ctx_unitsPUS = context.unitsPUS +local ctx_unitsPU = context.unitsPU +local ctx_unitsPS = context.unitsPS +local ctx_unitsP = context.unitsP +local ctx_unitsUS = context.unitsUS +local ctx_unitsU = context.unitsU +local ctx_unitsS = context.unitsS +local ctx_unitsO = context.unitsO +local ctx_unitsN = context.unitsN +local ctx_unitsC = context.unitsC +local ctx_unitsQ = context.unitsQ +local ctx_unitsNstart = context.unitsNstart +local ctx_unitsNstop = context.unitsNstop +local ctx_unitsNspace = context.unitsNspace local labels = languages.data.labels @@ -664,28 +665,28 @@ local function dimpus(p,u,s) if p ~= "" then if u ~= "" then if s ~= "" then - unitsPUS(p,u,s) + ctx_unitsPUS(p,u,s) else - unitsPU(p,u) + ctx_unitsPU(p,u) end elseif s ~= "" then - unitsPS(p,s) + ctx_unitsPS(p,s) else - unitsP(p) + ctx_unitsP(p) end else if u ~= "" then if s ~= "" then - unitsUS(u,s) + ctx_unitsUS(u,s) -- elseif c then - -- unitsC(u) + -- ctx_unitsC(u) else - unitsU(u) + ctx_unitsU(u) end elseif s ~= "" then - unitsS(s) + ctx_unitsS(s) else - unitsP(p) + ctx_unitsP(p) end end end @@ -699,7 +700,7 @@ local function dimop(o) report_units("operator %a",o) end if o then - unitsO(o) + ctx_unitsO(o) end end @@ -709,7 +710,7 @@ local function dimsym(s) end s = symbol_units[s] or s if s then - unitsC(s) + ctx_unitsC(s) end end @@ -719,7 +720,7 @@ local function dimpre(p) end p = packaged_units[p] or p if p then - unitsU(p) + ctx_unitsU(p) end end @@ -789,7 +790,7 @@ local function update_parsers() -- todo: don't remap utf sequences * (V("packaged") / dimpre) * V("somespace"), -- someunknown = V("somespace") - -- * (V("nospace")/unitsU) + -- * (V("nospace")/ctx_unitsU) -- * V("somespace"), -- combination = V("longprefix") * V("longunit") -- centi meter @@ -804,7 +805,7 @@ local function update_parsers() -- todo: don't remap utf sequences + (V("longsuffix") * V("combination")) / dimspu + (V("combination") * (V("shortsuffix") + V("nothing"))) / dimpus ) - * (V("qualifier") / unitsQ)^-1 + * (V("qualifier") / ctx_unitsQ)^-1 * V("somespace"), operator = V("somespace") * ((V("longoperator") + V("shortoperator")) / dimop) @@ -824,13 +825,13 @@ local function update_parsers() -- todo: don't remap utf sequences local number = Cs( P("$") * (1-P("$"))^1 * P("$") + P([[\m{]]) * (1-P("}"))^1 * P("}") + (1-R("az","AZ")-P(" "))^1 -- todo: catch { } -- not ok - ) / unitsN + ) / ctx_unitsN - local start = Cc(nil) / unitsNstart - local stop = Cc(nil) / unitsNstop - local space = Cc(nil) / unitsNspace + local start = Cc(nil) / ctx_unitsNstart + local stop = Cc(nil) / ctx_unitsNstop + local space = Cc(nil) / ctx_unitsNspace - -- todo: avoid \unitsNstart\unitsNstop (weird that it can happen .. now catched at tex end) + -- todo: avoid \ctx_unitsNstart\ctx_unitsNstop (weird that it can happen .. now catched at tex end) local p_c_combinedparser = P { "start", number = start * dleader * (p_c_dparser + number) * stop, diff --git a/tex/context/base/publ-dat.lua b/tex/context/base/publ-dat.lua index 8fce94822..b463064ca 100644 --- a/tex/context/base/publ-dat.lua +++ b/tex/context/base/publ-dat.lua @@ -382,9 +382,7 @@ end function loaders.lua(dataset,filename) -- if filename is a table we load that one dataset = datasets[dataset] - if type(dataset) == "table" then - dataset = datasets[dataset] - end + inspect(filename) local data = type(filename) == "table" and filename or table.load(filename) if data then local luadata = dataset.luadata @@ -401,13 +399,13 @@ function loaders.xml(dataset,filename) dataset = datasets[dataset] local luadata = dataset.luadata local root = xml.load(filename) - for entry in xmlcollected(root,"/bibtex/entry") do - local attributes = entry.at + for bibentry in xmlcollected(root,"/bibtex/entry") do + local attributes = bibentry.at local tag = attributes.tag local entry = { category = attributes.category } - for field in xmlcollected(entry,"/field") do + for field in xmlcollected(bibentry,"/field") do -- entry[field.at.name] = xmltext(field) entry[field.at.name] = field.dt[1] -- no cleaning yet end diff --git a/tex/context/base/publ-ini.mkiv b/tex/context/base/publ-ini.mkiv index 42226695c..adbf8f7fc 100644 --- a/tex/context/base/publ-ini.mkiv +++ b/tex/context/base/publ-ini.mkiv @@ -530,7 +530,7 @@ % \to \everysetupbtxlistplacement \unexpanded\def\btxflushauthor - {\doifnextoptionalelse\btx_flush_author_yes\btx_flush_author_nop} + {\doifnextoptionalcselse\btx_flush_author_yes\btx_flush_author_nop} \def\btx_flush_author_yes[#1]{\btx_flush_author{#1}} \def\btx_flush_author_nop {\btx_flush_author{\btxlistvariantparameter\c!author}} diff --git a/tex/context/base/s-abr-01.tex b/tex/context/base/s-abr-01.tex index e9ea6393b..733eebf7b 100644 --- a/tex/context/base/s-abr-01.tex +++ b/tex/context/base/s-abr-01.tex @@ -240,6 +240,7 @@ \logo [TABLE] {\TaBlE} \logo [TCPIP] {tcp/ip} \logo [TDS] {tds} % no sc te +\logo [TEI] {tei} % no sc te \logo [TETEX] {te\TeX} % no sc te \logo [TEX] {\TeX} \logo [TEXADRES] {\TeX adress} diff --git a/tex/context/base/s-inf-03.mkiv b/tex/context/base/s-inf-03.mkiv index fc654fef5..b6dada55a 100644 --- a/tex/context/base/s-inf-03.mkiv +++ b/tex/context/base/s-inf-03.mkiv @@ -352,7 +352,6 @@ for k, v in table.sortedpairs(_G) do end end - \stopluacode \stoptext diff --git a/tex/context/base/scrn-but.mkvi b/tex/context/base/scrn-but.mkvi index fd2da9e08..f8b236c52 100644 --- a/tex/context/base/scrn-but.mkvi +++ b/tex/context/base/scrn-but.mkvi @@ -217,12 +217,12 @@ {\global\settrue\c_scrn_button_skipped} \def\scrn_button_make_normal#currentparameter#inheritedframed#letparameter#setparameter#text% - {\ctxlua{structures.references.injectcurrentset(nil,nil)}% + {\ctxcommand{injectcurrentreference()}% \hbox attr \referenceattribute \lastreferenceattribute {#inheritedframed{\ignorespaces#text\removeunwantedspaces}}} \def\scrn_button_make_contrast#currentparameter#inheritedframed#letparameter#setparameter#text% - {\ctxlua{structures.references.injectcurrentset(nil,nil)}% + {\ctxcommand{injectcurrentreference()}% \hbox attr \referenceattribute \lastreferenceattribute {#setparameter\c!foregroundcolor{#currentparameter\c!contrastcolor}% #inheritedframed{\ignorespaces#text\removeunwantedspaces}}} diff --git a/tex/context/base/scrn-wid.mkvi b/tex/context/base/scrn-wid.mkvi index fad451651..8dcc7a86a 100644 --- a/tex/context/base/scrn-wid.mkvi +++ b/tex/context/base/scrn-wid.mkvi @@ -401,7 +401,7 @@ {\doifassignmentelse{#title} {\setupcurrentcomment[#title]} {\setupcurrentcomment[\c!title=#title,#settings]}% - \ctxlua{buffers.assign("\v!comment",\!!bs#text\!!es)}% todo: expansion control, but expanded by default (xml) + \ctxcommand{assignbuffer("\v!comment",\!!bs#text\!!es)}% todo: expansion control, but expanded by default (xml) \scrn_comment_inject \ignorespaces} diff --git a/tex/context/base/sort-ini.lua b/tex/context/base/sort-ini.lua index d279f1253..9ac020166 100644 --- a/tex/context/base/sort-ini.lua +++ b/tex/context/base/sort-ini.lua @@ -457,7 +457,7 @@ function sorters.strip(str) -- todo: only letters and such str = gsub(str,"\\[\"\'~^`]*","") -- \"e -- hm, too greedy str = gsub(str,"\\%S*","") -- the rest str = gsub(str,"%s","\001") -- can be option - str = gsub(str,"[%s%[%](){}%$\"\']*","") + str = gsub(str,"[%s%[%](){}%$\"\']*","") -- %s already done if digits == v_numbers then str = gsub(str,"(%d+)",numify) -- sort numbers properly end diff --git a/tex/context/base/spac-chr.lua b/tex/context/base/spac-chr.lua index 4122a64b6..1abba350a 100644 --- a/tex/context/base/spac-chr.lua +++ b/tex/context/base/spac-chr.lua @@ -14,6 +14,8 @@ local byte, lower = string.byte, string.lower -- to be redone: characters will become tagged spaces instead as then we keep track of -- spaceskip etc +-- todo: only setattr when export + local next = next trace_characters = false trackers.register("typesetters.characters", function(v) trace_characters = v end) diff --git a/tex/context/base/spac-hor.mkiv b/tex/context/base/spac-hor.mkiv index 4cd913290..92491ce32 100644 --- a/tex/context/base/spac-hor.mkiv +++ b/tex/context/base/spac-hor.mkiv @@ -32,7 +32,7 @@ {\doifoutervmode{\ifconditional\c_spac_indentation_indent_first\else\spac_indentation_variant_no\fi}} \unexpanded\def\setupindenting - {\doifnextoptionalelse\spac_indentation_setup_options\spac_indentation_setup_size} + {\doifnextoptionalcselse\spac_indentation_setup_options\spac_indentation_setup_size} \unexpanded\def\spac_indentation_setup_size {\assigndimension\v_spac_indentation_current\d_spac_indentation_par{1\emwidth}{1.5\emwidth}{2\emwidth}} @@ -64,24 +64,65 @@ \def\spac_indentation_set_everypar {\everypar{\checkindentation}} +% \def\spac_indentation_apply_step_one#1% +% {\ifcsname\??indentingmethod#1\endcsname +% % case two +% \else +% \edef\v_spac_indentation_current{#1}% single entry in list +% \let\normalindentation\v_spac_indentation_current +% \spac_indentation_setup_size +% \fi} +% +% \def\spac_indentation_apply_step_two#1% +% {\ifcsname\??indentingmethod#1\endcsname +% \csname\??indentingmethod#1\endcsname +% \else +% % case one +% \fi} + +% \defineindenting[whatever][yes,2cm] +% %defineindenting[whatever][yes,-2cm] +% +% \setupindenting[yes,-2em] \input ward \par +% \setupindenting[yes,2em] \input ward \par +% \setupindenting[whatever] \input ward \par + +\installcorenamespace {indentingpreset} + +\unexpanded\def\defineindenting + {\dodoubleargument\spac_indenting_define} + +\def\spac_indenting_define[#1][#2]% todo: mixes + {\setevalue{\??indentingpreset#1}{#2}} + +\def\spac_indentation_apply_step_one_nested#1% + {\expandafter\processcommacommand\expandafter[\csname\??indentingpreset#1\endcsname]\spac_indentation_apply_step_one} + +\def\spac_indentation_apply_step_two_nested#1% + {\expandafter\processcommacommand\expandafter[\csname\??indentingpreset#1\endcsname]\spac_indentation_apply_step_two} + \def\spac_indentation_apply_step_one#1% - {\ifcsname\??indentingmethod#1\endcsname + {\ifcsname\??indentingpreset#1\endcsname + \spac_indentation_apply_step_one_nested{#1}% + \else\ifcsname\??indentingmethod#1\endcsname % case two \else \edef\v_spac_indentation_current{#1}% single entry in list \let\normalindentation\v_spac_indentation_current \spac_indentation_setup_size - \fi} + \fi\fi} \def\spac_indentation_apply_step_two#1% - {\ifcsname\??indentingmethod#1\endcsname + {\ifcsname\??indentingpreset#1\endcsname + \spac_indentation_apply_step_two_nested{#1}% + \else\ifcsname\??indentingmethod#1\endcsname \csname\??indentingmethod#1\endcsname \else % case one - \fi} + \fi\fi} \unexpanded\def\indenting % kind of obsolete - {\doifnextoptionalelse\spac_indentation_setup_options\relax} + {\doifnextoptionalcselse\spac_indentation_setup_options\relax} % use \noindentation to suppress next indentation @@ -339,7 +380,7 @@ \installspacingmethod \v!broad {\nonfrenchspacing} % more depending on what punctuation \unexpanded\def\setupspacing - {\doifnextoptionalelse\spac_spacecodes_setup_yes\spac_spacecodes_setup_nop} + {\doifnextoptionalcselse\spac_spacecodes_setup_yes\spac_spacecodes_setup_nop} \def\spac_spacecodes_setup_yes[#1]% {\csname\??spacecodemethod#1\endcsname @@ -1059,7 +1100,7 @@ %D A rather unknown one: \unexpanded\def\widened % moved from cont-new - {\doifnextoptionalelse\spac_widened_yes\spac_widened_nop} + {\doifnextoptionalcselse\spac_widened_yes\spac_widened_nop} \def\spac_widened_yes[#1]#2{\hbox \s!spread #1{\hss#2\hss}} \def\spac_widened_nop #1{\hbox \s!spread \emwidth{\hss#1\hss}} diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index 7d78d6c12..21695a396 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -584,15 +584,15 @@ do -- todo: interface.variables -- This will change: just node.write and we can store the values in skips which -- then obeys grouping - local fixedblankskip = context.fixedblankskip - local flexibleblankskip = context.flexibleblankskip - local setblankcategory = context.setblankcategory - local setblankorder = context.setblankorder - local setblankpenalty = context.setblankpenalty - local setblankhandling = context.setblankhandling - local flushblankhandling = context.flushblankhandling - local addpredefinedblankskip = context.addpredefinedblankskip - local addaskedblankskip = context.addaskedblankskip + local ctx_fixedblankskip = context.fixedblankskip + local ctx_flexibleblankskip = context.flexibleblankskip + local ctx_setblankcategory = context.setblankcategory + local ctx_setblankorder = context.setblankorder + local ctx_setblankpenalty = context.setblankpenalty + ----- ctx_setblankhandling = context.setblankhandling + local ctx_flushblankhandling = context.flushblankhandling + local ctx_addpredefinedblankskip = context.addpredefinedblankskip + local ctx_addaskedblankskip = context.addaskedblankskip local function analyze(str,oldcategory) -- we could use shorter names for s in gmatch(str,"([^ ,]+)") do @@ -604,35 +604,35 @@ do -- todo: interface.variables if mk then category = analyze(mk,category) elseif keyword == k_fixed then - fixedblankskip() + ctx_fixedblankskip() elseif keyword == k_flexible then - flexibleblankskip() + ctx_flexibleblankskip() elseif keyword == k_category then local category = tonumber(detail) if category then - setblankcategory(category) + ctx_setblankcategory(category) if category ~= oldcategory then - flushblankhandling() + ctx_flushblankhandling() oldcategory = category end end elseif keyword == k_order and detail then local order = tonumber(detail) if order then - setblankorder(order) + ctx_setblankorder(order) end elseif keyword == k_penalty and detail then local penalty = tonumber(detail) if penalty then - setblankpenalty(penalty) + ctx_setblankpenalty(penalty) end else amount = tonumber(amount) or 1 local sk = skip[keyword] if sk then - addpredefinedblankskip(amount,keyword) + ctx_addpredefinedblankskip(amount,keyword) else -- no check - addaskedblankskip(amount,keyword) + ctx_addaskedblankskip(amount,keyword) end end end @@ -640,22 +640,22 @@ do -- todo: interface.variables return category end - local pushlogger = context.pushlogger - local startblankhandling = context.startblankhandling - local stopblankhandling = context.stopblankhandling - local poplogger = context.poplogger + local ctx_pushlogger = context.pushlogger + local ctx_startblankhandling = context.startblankhandling + local ctx_stopblankhandling = context.stopblankhandling + local ctx_poplogger = context.poplogger function vspacing.analyze(str) if trace_vspacing then - pushlogger(report_vspacing) - startblankhandling() + ctx_pushlogger(report_vspacing) + ctx_startblankhandling() analyze(str,1) - stopblankhandling() - poplogger() + ctx_stopblankhandling() + ctx_poplogger() else - startblankhandling() + ctx_startblankhandling() analyze(str,1) - stopblankhandling() + ctx_stopblankhandling() end end @@ -774,7 +774,8 @@ local splittopskip_code = skipcodes.splittopskip -- end local free_glue_node = free_node -local free_glue_spec = function() end -- free_node +local free_glue_spec = function() end +----- free_glue_spec = free_node -- can be enabled in in 0.73 (so for the moment we leak due to old luatex engine issues) function vspacing.snapbox(n,how) local sv = snapmethods[how] @@ -1403,3 +1404,4 @@ commands.vspacingdefine = vspacing.setmap commands.vspacingcollapse = vspacing.collapsevbox commands.vspacingsnap = vspacing.snapbox commands.resetprevdepth = vspacing.resetprevdepth +commands.definesnapmethod = vspacing.definesnapmethod diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv index afa722cfe..1f8bf2c79 100644 --- a/tex/context/base/spac-ver.mkiv +++ b/tex/context/base/spac-ver.mkiv @@ -152,10 +152,14 @@ \unexpanded\def\setupinterlinespace {\dodoubleempty\spac_linespacing_setup} +\ifdefined\setupinterlinespace_double \else + \let\setupinterlinespace_double\setup_interlinespace % for a while +\fi + \def\spac_linespacing_setup[#1][#2]% {\settrue\interlinespaceisset % reset has to be done when needed \ifsecondargument - \setup_interlinespace[#1][#2]% + \setupinterlinespace_double[#1][#2]% \else\iffirstargument \ifcsname\namedinterlinespacehash{#1}\s!parent\endcsname \edef\currentinterlinespace{#1}% @@ -330,7 +334,7 @@ \let\v_spac_whitespace_current\v!none \unexpanded\def\setupwhitespace - {\doifnextoptionalelse\spac_whitespace_setup_yes\spac_whitespace_setup_nop} + {\doifnextoptionalcselse\spac_whitespace_setup_yes\spac_whitespace_setup_nop} \def\spac_whitespace_setup_nop {\ifx\v_spac_whitespace_current\v!none\else @@ -1154,6 +1158,10 @@ \let\normaloffinterlineskip\offinterlineskip % knuth's original +\appendtoks + \ifvmode\ctxcommand{resetprevdepth()}\fi % a nasty hack (tested for a while now) +\to \everyafteroutput + %D My own one: \unexpanded\def\spac_helpers_push_interlineskip_yes @@ -1325,7 +1333,7 @@ \unexpanded\def\installsnapvalues#1#2% todo: a proper define {\edef\currentsnapper{#1:#2}% \ifcsname\??gridsnapperattributes\currentsnapper\endcsname \else - \setevalue{\??gridsnapperattributes\currentsnapper}{\ctxlua{builders.vspacing.definesnapmethod("#1","#2")}}% + \setevalue{\??gridsnapperattributes\currentsnapper}{\ctxcommand{definesnapmethod("#1","#2")}}% \fi \setevalue{\??gridsnappers#1}{\attribute\snapmethodattribute\csname\??gridsnapperattributes\currentsnapper\endcsname\space}} @@ -1751,7 +1759,7 @@ % The main spacer: \unexpanded\def\vspacing - {\doifnextoptionalelse\spac_vspacing_yes\spac_vspacing_nop} + {\doifnextoptionalcselse\spac_vspacing_yes\spac_vspacing_nop} \def\spac_vspacing_yes {\ifinpagebody % somewhat weird @@ -1807,7 +1815,7 @@ % these depend on bigskipamount cum suis so we'd better sync them \unexpanded\def\setupvspacing - {\doifnextoptionalelse\setupvspacing_yes\setupvspacing_nop} + {\doifnextoptionalcselse\setupvspacing_yes\setupvspacing_nop} \let\currentvspacing\s!default % hm, default, standard ... diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index ae09bb5ae..ae1fb5fec 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 8f1f3e5c8..ba896a1f9 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/strc-blk.lua b/tex/context/base/strc-blk.lua index 935b6c061..ce3304d59 100644 --- a/tex/context/base/strc-blk.lua +++ b/tex/context/base/strc-blk.lua @@ -78,7 +78,7 @@ end function blocks.select(state,name,tag,criterium) criterium = criterium or "text" - if find(tag,"=") then tag = "" end + if find(tag,"=",1,true) then tag = "" end local names = settings_to_set(name) local all = tag == "" local tags = not all and settings_to_set(tag) diff --git a/tex/context/base/strc-con.mkvi b/tex/context/base/strc-con.mkvi index 75519b8ce..1862b00a6 100644 --- a/tex/context/base/strc-con.mkvi +++ b/tex/context/base/strc-con.mkvi @@ -980,10 +980,11 @@ } }\relax % \writestatus{constructions}{registering \currentconstruction: \number\scratchcounter}% + \ctxcommand{setinternalreference("\referenceprefix","\currentconstructionreference",\nextinternalreference,"\interactionparameter\c!focus")}% \normalexpanded{% \endgroup \edef\noexpand\currentconstructionlistentry {\the\scratchcounter}% - \edef\noexpand\currentconstructionattribute {\ctxcommand {setinternalreference("\referenceprefix","\currentconstructionreference",\nextinternalreference,"\interactionparameter\c!focus")}}% + \edef\noexpand\currentconstructionattribute {\the\lastdestinationattribute}% \edef\noexpand\currentconstructionsynchronize{\ctxlatecommand{enhancelist(\the\scratchcounter)}}% }% \fi} @@ -993,7 +994,7 @@ % macros. \def\reinstateconstructionnumberentry#1% was xdef - {\edef\currentconstructionattribute {\ctxcommand {getinternalreference(#1)}}% + {\edef\currentconstructionattribute {\ctxcommand {getinternallistreference(#1)}}% \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}} \installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}} diff --git a/tex/context/base/strc-des.mkvi b/tex/context/base/strc-des.mkvi index 9c4d3fc6d..fa20d3cae 100644 --- a/tex/context/base/strc-des.mkvi +++ b/tex/context/base/strc-des.mkvi @@ -102,7 +102,7 @@ \unexpanded\def\strc_descriptions_start#1% {\begingroup \strc_constructions_initialize{#1}% - \doifnextoptionalelse\strc_descriptions_start_yes\strc_descriptions_start_nop} + \doifnextoptionalcselse\strc_descriptions_start_yes\strc_descriptions_start_nop} \unexpanded\def\strc_descriptions_start_yes[#1]% {\doifassignmentelse{#1}\strc_descriptions_start_yes_assignment\strc_descriptions_start_yes_reference[#1]} @@ -162,7 +162,7 @@ \unexpanded\def\strc_descriptions_command#1% {\begingroup \strc_constructions_initialize{#1}% - \doifnextoptionalelse\strc_descriptions_yes\strc_descriptions_nop} + \doifnextoptionalcselse\strc_descriptions_yes\strc_descriptions_nop} \unexpanded\def\strc_descriptions_yes {\ifconditional\c_strc_constructions_title_state diff --git a/tex/context/base/strc-doc.lua b/tex/context/base/strc-doc.lua index e3cbb02ed..38830a4e7 100644 --- a/tex/context/base/strc-doc.lua +++ b/tex/context/base/strc-doc.lua @@ -61,6 +61,10 @@ local strippedprocessor = processors.stripped local a_internal = attributes.private('internal') +local ctx_convertnumber = context.convertnumber +local ctx_sprint = context.sprint +local ctx_finalizeauto = context.finalizeautostructurelevel + -- -- -- document -- -- -- local data -- the current state @@ -239,7 +243,7 @@ end local saveset = { } -- experiment, see sections/tricky-001.tex -function sections.somelevel(given) +function sections.setentry(given) -- old number local numbers = data.numbers @@ -456,7 +460,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp local data = data.status[depth] local d if data then - if find(key,"%.") then + if find(key,".",1,true) then d = accesstable(key,data) else d = data.titledata @@ -468,7 +472,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp local metadata = data.metadata local catcodes = metadata and metadata.catcodes if catcodes then - context.sprint(catcodes,d) + ctx_sprint(catcodes,d) else context(d) end @@ -477,7 +481,7 @@ function sections.structuredata(depth,key,default,honorcatcodetable) -- todo: sp else local catcodes = catcodenumbers[honorcatcodetable] if catcodes then - context.sprint(catcodes,d) + ctx_sprint(catcodes,d) else context(d) end @@ -512,14 +516,20 @@ function sections.current() return data.status[data.depth] end -function sections.depthnumber(n) +local function depthnumber(n) local depth = data.depth if not n or n == 0 then n = depth elseif n < 0 then n = depth + n end - return context(data.numbers[n] or 0) + return data.numbers[n] or 0 +end + +sections.depthnumber = depthnumber + +function commands.depthnumber(n) + return context(depthnumber(n)) end function sections.autodepth(numbers) @@ -580,11 +590,11 @@ local function process(index,numbers,ownnumbers,criterium,separatorset,conversio if ownnumber ~= "" then applyprocessor(ownnumber) elseif conversion and conversion ~= "" then -- traditional (e.g. used in itemgroups) - context.convertnumber(conversion,number) + ctx_convertnumber(conversion,number) else local theconversion = sets.get("structure:conversions",block,conversionset,index,"numbers") local data = startapplyprocessor(theconversion) - context.convertnumber(data or "numbers",number) + ctx_convertnumber(data or "numbers",number) stopapplyprocessor() end end @@ -926,7 +936,7 @@ function commands.autonextstructurelevel(level) else for i=level,#levels do if levels[i] then - context.finalizeautostructurelevel() + ctx_finalizeauto() levels[i] = false end end @@ -937,7 +947,7 @@ end function commands.autofinishstructurelevels() for i=1,#levels do if levels[i] then - context.finalizeautostructurelevel() + ctx_finalizeauto() end end levels = { } @@ -945,8 +955,8 @@ end -- interface (some are actually already commands, like sections.fullnumber) -commands.structurenumber = function() sections.fullnumber() end -commands.structuretitle = function() sections.title () end +commands.structurenumber = sections.fullnumber +commands.structuretitle = sections.title commands.structurevariable = function(name) sections.structuredata(nil,name) end commands.structureuservariable = function(name) sections.userdata (nil,name) end @@ -954,15 +964,23 @@ commands.structurecatcodedget = function(name) sections.structured commands.structuregivencatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end commands.structureautocatcodedget = function(name,catcode) sections.structuredata(nil,name,nil,catcode) end -commands.namedstructurevariable = function(depth,name) sections.structuredata(depth,name) end -commands.namedstructureuservariable = function(depth,name) sections.userdata (depth,name) end +commands.namedstructurevariable = sections.structuredata +commands.namedstructureuservariable = sections.userdata --- +commands.setsectionlevel = sections.setlevel +commands.setsectionnumber = sections.setnumber +commands.getsectionnumber = sections.getnumber +commands.getfullsectionnumber = sections.fullnumber +commands.getstructuredata = sections.structuredata +commands.getcurrentsectionlevel = sections.getcurrentlevel -commands.setsectionblock = sections.setblock -commands.pushsectionblock = sections.pushblock -commands.popsectionblock = sections.popblock +commands.setsectionblock = sections.setblock +commands.pushsectionblock = sections.pushblock +commands.popsectionblock = sections.popblock +commands.registersection = sections.register +commands.setsectionentry = sections.setentry +commands.reportstructure = sections.reportstructure -- local byway = "^" .. v_by -- ugly but downward compatible diff --git a/tex/context/base/strc-doc.mkiv b/tex/context/base/strc-doc.mkiv index c8dfae1e4..98abfd611 100644 --- a/tex/context/base/strc-doc.mkiv +++ b/tex/context/base/strc-doc.mkiv @@ -20,7 +20,8 @@ %D This will move: \unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext - {\xdef\currentstructureattribute {\ctxlua {tex.write(structures.references.setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\interactionparameter\c!focus"))}}% + {\ctxcommand{setinternalreference("\currentstructurereferenceprefix","\currentstructurereference",\nextinternalreference,"\interactionparameter\c!focus")}% + \xdef\currentstructureattribute {\the\lastdestinationattribute}% \xdef\currentstructuresynchronize{\ctxlatecommand{enhancelist(#1)}}} \protect \endinput diff --git a/tex/context/base/strc-enu.mkvi b/tex/context/base/strc-enu.mkvi index e369bc2e1..0a01d2637 100644 --- a/tex/context/base/strc-enu.mkvi +++ b/tex/context/base/strc-enu.mkvi @@ -370,6 +370,6 @@ \fi} \unexpanded\def\strc_enumerations_skip_number_coupling[#tag]% e.g. for questions with no answer - {\ctxlua{structures.references.setnextorder("construction","#tag")}} + {\ctxcommand{setnextreferenceorder("construction","#tag")}} \protect \endinput diff --git a/tex/context/base/strc-ini.lua b/tex/context/base/strc-ini.lua index 09ed79288..a48679e6f 100644 --- a/tex/context/base/strc-ini.lua +++ b/tex/context/base/strc-ini.lua @@ -38,14 +38,19 @@ local txtcatcodes = catcodenumbers.txtcatcodes local context = context local commands = commands -local pushcatcodes = context.pushcatcodes -local popcatcodes = context.popcatcodes - local trace_processors = false local report_processors = logs.reporter("processors","structure") trackers.register("typesetters.processors", function(v) trace_processors = v end) +local xmlconvert = lxml.convert +local xmlstore = lxml.store + +local ctx_pushcatcodes = context.pushcatcodes +local ctx_popcatcodes = context.popcatcodes +local ctx_xmlsetup = context.xmlsetup +local ctx_xmlprocessbuffer = context.xmlprocessbuffer + -- -- -- namespace -- -- -- -- This is tricky: we have stored and initialized already some of @@ -151,11 +156,17 @@ local function simplify(d,nodefault) for k, v in next, d do local tv = type(v) if tv == "table" then - if next(v) then t[k] = simplify(v) end + if next(v) then + t[k] = simplify(v) + end elseif tv == "string" then - if v ~= "" and v ~= "default" then t[k] = v end + if v ~= "" and v ~= "default" then + t[k] = v + end elseif tv == "boolean" then - if v then t[k] = v end + if v then + t[k] = v + end else t[k] = v end @@ -168,6 +179,34 @@ local function simplify(d,nodefault) end end +-- we only care about the tuc file so this would do too: +-- +-- local function simplify(d,nodefault) +-- if d then +-- for k, v in next, d do +-- local tv = type(v) +-- if tv == "string" then +-- if v == "" or v == "default" then +-- d[k] = nil +-- end +-- elseif tv == "table" then +-- if next(v) then +-- simplify(v) +-- end +-- elseif tv == "boolean" then +-- if not v then +-- d[k] = nil +-- end +-- end +-- end +-- return d +-- elseif nodefault then +-- return nil +-- else +-- return { } +-- end +-- end + helpers.simplify = simplify function helpers.merged(...) @@ -211,19 +250,19 @@ function helpers.title(title,metadata) -- coding is xml is rather old and not th report_processors("putting xml data in buffer: %s",xmldata) report_processors("processing buffer with setup %a and tag %a",xmlsetup,tag) end - if experiment then - -- the question is: will this be forgotten ... better store in a via file - local xmltable = lxml.convert("temp",xmldata or "") - lxml.store("temp",xmltable) - context.xmlsetup("temp",xmlsetup or "") - else - context.xmlprocessbuffer("dummy",tag,xmlsetup or "") - end + if experiment then + -- the question is: will this be forgotten ... better store in a via file + local xmltable = xmlconvert("temp",xmldata or "") + xmlstore("temp",xmltable) + ctx_xmlsetup("temp",xmlsetup or "") + else + ctx_xmlprocessbuffer("dummy",tag,xmlsetup or "") + end elseif xmlsetup then -- title is reference to node (so \xmlraw should have been used) if trace_processors then report_processors("feeding xmlsetup %a using node %a",xmlsetup,title) end - context.xmlsetup(title,metadata.xmlsetup) + ctx_xmlsetup(title,metadata.xmlsetup) else local catcodes = metadata.catcodes if catcodes == notcatcodes or catcodes == xmlcatcodes then @@ -241,9 +280,9 @@ function helpers.title(title,metadata) -- coding is xml is rather old and not th -- doesn't work when a newline is in there \section{Test\ A} so we do -- it this way: -- - pushcatcodes(catcodes) + ctx_pushcatcodes(catcodes) context(title) - popcatcodes() + ctx_popcatcodes() end end else diff --git a/tex/context/base/strc-itm.mkvi b/tex/context/base/strc-itm.mkvi index 8259fa38d..9e11f2047 100644 --- a/tex/context/base/strc-itm.mkvi +++ b/tex/context/base/strc-itm.mkvi @@ -331,7 +331,7 @@ \def\strc_itemgroups_store_continue_state#options#settings% {\setxvalue{\??itemgroupoption \currentitemgroup}{\strc_itemgroups_process_options{#options}}% - \setgvalue{\??itemgroupsetting\currentitemgroup}{\setupcurrentitemgroup [#settings]}} + \setgvalue{\??itemgroupsetting\currentitemgroup}{\setupcurrentitemgroup[#settings]}} \def\strc_itemgroups_fetch_continue_state {\getvalue{\??itemgroupoption \currentitemgroup}% diff --git a/tex/context/base/strc-lst.lua b/tex/context/base/strc-lst.lua index d86368b6a..6ad491be2 100644 --- a/tex/context/base/strc-lst.lua +++ b/tex/context/base/strc-lst.lua @@ -16,7 +16,7 @@ if not modules then modules = { } end modules ['strc-lst'] = { -- move more to commands local format, gmatch, gsub = string.format, string.gmatch, string.gsub -local tonumber = tonumber +local tonumber, type = tonumber, type local concat, insert, remove = table.concat, table.insert, table.remove local lpegmatch = lpeg.match local simple_hash_to_string, settings_to_hash = utilities.parsers.simple_hash_to_string, utilities.parsers.settings_to_hash @@ -49,7 +49,7 @@ lists.collected = collected lists.tobesaved = tobesaved lists.enhancers = lists.enhancers or { } -lists.internals = allocate(lists.internals or { }) -- to be checked +-----.internals = allocate(lists.internals or { }) -- to be checked lists.ordered = allocate(lists.ordered or { }) -- to be checked lists.cached = cached lists.pushed = pushed @@ -88,6 +88,7 @@ local function initializer() local collected = lists.collected local internals = checked(references.internals) local ordered = lists.ordered + local usedinternals = references.usedinternals local blockdone = { } for i=1,#collected do local c = collected[i] @@ -99,6 +100,7 @@ local function initializer() local internal = r.internal if internal then internals[internal] = c + usedinternals[internal] = r.used end local block = r.block if block and not blockdone[block] then @@ -128,7 +130,17 @@ local function initializer() end end -job.register('structures.lists.collected', tobesaved, initializer) +local function finalizer() + local flaginternals = references.flaginternals + for i=1,#tobesaved do + local r = tobesaved[i].references + if r and flaginternals[r.internal] then + r.used = true + end + end +end + +job.register('structures.lists.collected', tobesaved, initializer, finalizer) local groupindices = table.setmetatableindex("table") diff --git a/tex/context/base/strc-lst.mkvi b/tex/context/base/strc-lst.mkvi index f78881221..0008f0602 100644 --- a/tex/context/base/strc-lst.mkvi +++ b/tex/context/base/strc-lst.mkvi @@ -147,8 +147,8 @@ \ifx\p_location\v!here % this branch injects nodes ! \expanded{\ctxlatecommand{enhancelist(\currentlistnumber)}}% - \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}% will change - \xdef\currentstructurelistattribute{\number\lastdestinationattribute}% + \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% will change + \xdef\currentstructurelistattribute{\the\lastdestinationattribute}% \dontleavehmode\hbox attr \destinationattribute \lastdestinationattribute{}% todo \else % and this one doesn't @@ -1050,7 +1050,7 @@ \listparameter\c!numbercommand\currentlistsymbol \listparameter\c!right \endgroup - \kern.5em + \kern.5\emwidth\relax \nobreak \fi \fi @@ -1069,7 +1069,7 @@ \ifconditional\c_lists_has_page \ifconditional\c_lists_show_page \nobreak - \hskip.75em\relax + \hskip.75\emwidth\relax \nobreak \strc_lists_set_reference_attribute\v!pagenumber \strc_lists_set_style_color\c!pagestyle\c!pagecolor\v!pagenumber diff --git a/tex/context/base/strc-mar.lua b/tex/context/base/strc-mar.lua index 258787d0a..9c6259de4 100644 --- a/tex/context/base/strc-mar.lua +++ b/tex/context/base/strc-mar.lua @@ -712,6 +712,9 @@ end -- interface +commands.markingtitle = marks.title +commands.markingnumber = marks.number + commands.definemarking = marks.define commands.relatemarking = marks.relate commands.setmarking = marks.set diff --git a/tex/context/base/strc-not.mkvi b/tex/context/base/strc-not.mkvi index a1aecf83a..b15285f8c 100644 --- a/tex/context/base/strc-not.mkvi +++ b/tex/context/base/strc-not.mkvi @@ -231,7 +231,7 @@ \ifnotesenabled \strc_counters_increment_sub\currentconstructionnumber\currentconstructionlevel \fi - \doifnextoptionalelse\strc_notations_command_yes\strc_notations_command_nop} + \doifnextoptionalcselse\strc_notations_command_yes\strc_notations_command_nop} \unexpanded\def\strc_notations_command_nop#title% {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference=,\c!title={#title},\c!bookmark=,\c!list=][]% @@ -265,7 +265,7 @@ % \normalexpanded % not that efficient but also not that frequently used (\normaldef for parser) % {\normaldef\noexpand\strc_pickup_yes[##1]##2\csname\e!stop#stoptag\endcsname{\strc_notations_command_yes[##1]{##2}}% % \normaldef\noexpand\strc_pickup_nop ##1\csname\e!stop#stoptag\endcsname{\strc_notations_command_nop {##1}}}% -% \doifnextoptionalelse\strc_pickup_yes\strc_pickup_nop} +% \doifnextoptionalcselse\strc_pickup_yes\strc_pickup_nop} \unexpanded\def\strc_notations_start#tag#stoptag% {\begingroup @@ -278,7 +278,7 @@ \normalexpanded % not that efficient but also not that frequently used (\normaldef for parser) {\def\noexpand\strc_pickup_yes[#one]#two\csname\e!stop#stoptag\endcsname{\strc_notations_command_yes[#one]{#two}}% \def\noexpand\strc_pickup_nop #one\csname\e!stop#stoptag\endcsname{\strc_notations_command_nop {#one}}}% - \doifnextoptionalelse\strc_pickup_yes\strc_pickup_nop} + \doifnextoptionalcselse\strc_pickup_yes\strc_pickup_nop} \unexpanded\def\strc_notations_start_yes[#reference]#title% {\strc_constructions_register[\c!label={\descriptionparameter\c!text},\c!reference={#reference},\c!title={#title},\c!bookmark=,\c!list=][]% @@ -460,7 +460,11 @@ \else\ifconditional\inlocalnotes % todo: per note class \global\settrue\postponednote \else +\ifconditional\c_strc_notes_delayed + % probably end notes +\else \handlenoteinsert\currentnote\currentnotenumber % either an insert or just delayed +\fi \fi\fi \endgroup \fi @@ -1242,6 +1246,7 @@ \appendtoks \doif{\noteparameter\c!scope}\v!page{\floatingpenalty\maxdimen}% experiment \penalty\currentnotepenalty + %\interlinepenalty\maxdimen % todo \forgetall \strc_notes_set_bodyfont \redoconvertfont % to undo \undo calls in in headings etc diff --git a/tex/context/base/strc-num.lua b/tex/context/base/strc-num.lua index 67e9b1734..e1fc60030 100644 --- a/tex/context/base/strc-num.lua +++ b/tex/context/base/strc-num.lua @@ -404,7 +404,7 @@ function counters.restart(name,n,newstart,noreset) if newstart then local d = allocate(name,n) d.start = newstart - if not noreset then + if not noreset then -- why / when needed ? reset(name,n) -- hm end end @@ -589,8 +589,13 @@ function commands.doifnotcounter (name) commands.doifnot (counterdata[name]) end function commands.incrementedcounter(...) context(counters.add(...)) end +-- the noreset is somewhat messy ... always false messes up e.g. itemize but true the pagenumbers +-- +-- if this fails i'll clean up this still somewhat experimental mechanism (but i need use cases) + function commands.checkcountersetup(name,level,start,state) - counters.restart(name,1,start,true) -- no reset + local noreset = true -- level > 0 -- was true + counters.restart(name,1,start,noreset) -- was true counters.setstate(name,state) counters.setlevel(name,level) sections.setchecker(name,level,counters.reset) diff --git a/tex/context/base/strc-num.mkiv b/tex/context/base/strc-num.mkiv index 2fa8b0e9a..b0e36ffba 100644 --- a/tex/context/base/strc-num.mkiv +++ b/tex/context/base/strc-num.mkiv @@ -17,6 +17,8 @@ \unprotect +\startcontextdefinitioncode + % work in progress % to be checked: can we use the command handler code here? % all settings will move to lua @@ -63,6 +65,11 @@ \appendtoks \ifx\currentcounter\empty \else + \edef\p_number{\counterparameter\c!number}% + \ifx\p_number\empty \else + \ctxcommand{setcounter("\counterparameter\s!name",1,\number\p_number)}% + \letcounterparameter\c!number\empty + \fi \edef\p_start{\counterparameter\c!start}% \setexpandedcounterparameter\c!start{\ifx\p_start\empty0\else\number\p_start\fi}% \strc_counters_check_setup @@ -351,7 +358,7 @@ {\begingroup \edef\currentcounter{#1}% \ifsecondargument\setupcurrentcounter[#2]\fi - \ctxlua{structures.sections.prefixedconverted( + \ctxcommand{prefixedconverted( "\counterparameter\s!name", { prefix = "\counterparameter\c!prefix", @@ -379,7 +386,7 @@ \endgroup} \def\directconvertedcounter#1#2% name, type - {\ctxlua{structures.sections.prefixedconverted( + {\ctxcommand{prefixedconverted( "\namedcounterparameter{#1}\s!name", { prefix = "\namedcounterparameter{#1}\c!prefix", @@ -609,7 +616,8 @@ userdata = \!!bs\detokenize{#9}\!!es % will be converted to table at the lua end } }}% - \xdef\m_strc_counters_last_registered_attribute {\ctxcommand {setinternalreference(nil,nil,\nextinternalreference)}}% + \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% + \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}% \xdef\m_strc_counters_last_registered_synchronize{\ctxlatecommand{enhancelist(\m_strc_counters_last_registered_index)}}% \else \glet\m_strc_counters_last_registered_index \relax @@ -764,4 +772,6 @@ % \fi % \to \everysetupcounter +\stopcontextdefinitioncode + \protect \endinput diff --git a/tex/context/base/strc-pag.lua b/tex/context/base/strc-pag.lua index fd0a367aa..c294a4645 100644 --- a/tex/context/base/strc-pag.lua +++ b/tex/context/base/strc-pag.lua @@ -34,6 +34,8 @@ local stopapplyprocessor = processors.stopapply local texsetcount = tex.setcount local texgetcount = tex.getcount +local ctx_convertnumber = context.convertnumber + -- storage local collected, tobesaved = allocate(), allocate() @@ -101,11 +103,11 @@ function counters.specials.userpage() end end -local f_convert = string.formatters["\\convertnumber{%s}{%s}"] - -local function convertnumber(str,n) - return f_convert(str or "numbers",n) -end +-- local f_convert = string.formatters["\\convertnumber{%s}{%s}"] +-- +-- local function convertnumber(str,n) +-- return f_convert(str or "numbers",n) +-- end function pages.number(realdata,pagespec) local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock() @@ -118,12 +120,12 @@ function pages.number(realdata,pagespec) applyprocessor(starter) end if conversion ~= "" then - context.convertnumber(conversion,userpage) + ctx_convertnumber(conversion,userpage) else if conversionset == "" then conversionset = "default" end local theconversion = sets.get("structure:conversions",block,conversionset,1,"numbers") -- to be checked: 1 local data = startapplyprocessor(theconversion) - context.convertnumber(data or "number",userpage) + ctx_convertnumber(data or "number",userpage) stopapplyprocessor() end if stopper ~= "" then @@ -318,3 +320,8 @@ function sections.prefixedconverted(name,prefixspec,numberspec) counters.converted(name,numberspec) end end + +-- + +commands.savepagedata = pages.save +commands.prefixedconverted = sections.prefixedconverted -- weird place diff --git a/tex/context/base/strc-pag.mkiv b/tex/context/base/strc-pag.mkiv index c4e9819ba..6eddc0fba 100644 --- a/tex/context/base/strc-pag.mkiv +++ b/tex/context/base/strc-pag.mkiv @@ -17,6 +17,8 @@ \unprotect +\startcontextdefinitioncode + % Allocation: \countdef\realpageno \zerocount \realpageno \plusone @@ -109,7 +111,7 @@ % invisible = \def\strc_pagenumbers_page_state_save % \normalexpanded? - {\ctxlua{structures.pages.save({ + {\ctxcommand{savepagedata({ prefix = "\namedcounterparameter\s!userpage\c!prefix", separatorset = "\namedcounterparameter\s!userpage\c!prefixseparatorset", conversion = "\namedcounterparameter\s!userpage\c!prefixconversion", @@ -462,4 +464,6 @@ \initializepagecounters +\stopcontextdefinitioncode + \protect \endinput diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua index 938af1ad7..9cf8382be 100644 --- a/tex/context/base/strc-ref.lua +++ b/tex/context/base/strc-ref.lua @@ -91,6 +91,8 @@ local tobesaved = allocate() local collected = allocate() local tobereferred = allocate() local referred = allocate() +local usedinternals = allocate() +local flaginternals = allocate() references.derived = derived references.specials = specials @@ -103,6 +105,8 @@ references.tobesaved = tobesaved references.collected = collected references.tobereferred = tobereferred references.referred = referred +references.usedinternals = usedinternals +references.flaginternals = flaginternals local splitreference = references.splitreference local splitprefix = references.splitcomponent -- replaces: references.splitprefix @@ -119,6 +123,7 @@ local finalizers = { } function references.registerinitializer(func) -- we could use a token register instead initializers[#initializers+1] = func end + function references.registerfinalizer(func) -- we could use a token register instead finalizers[#finalizers+1] = func end @@ -246,15 +251,20 @@ local function setnextorder(kind,name) texsetcount("global","locationorder",lastorder) end -references.setnextorder = setnextorder -function references.setnextinternal(kind,name) +local function setnextinternal(kind,name) setnextorder(kind,name) -- always incremented with internal local n = texgetcount("locationcount") + 1 texsetcount("global","locationcount",n) return n end +references.setnextorder = setnextorder +references.setnextinternal = setnextinternal + +commands.setnextreferenceorder = setnextorder +commands.setnextinternalreference = setnextinternal + function references.currentorder(kind,name) return orders[kind] and orders[kind][name] or lastorder end @@ -272,8 +282,6 @@ local function setcomponent(data) -- but for the moment we do it here (experiment) end -commands.setnextinternalreference = references.setnextinternal - function commands.currentreferenceorder(kind,name) context(references.currentorder(kind,name)) end @@ -448,9 +456,9 @@ function references.urls.define(name,url,file,description) end end -local pushcatcodes = context.pushcatcodes -local popcatcodes = context.popcatcodes -local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes" +local ctx_pushcatcodes = context.pushcatcodes +local ctx_popcatcodes = context.popcatcodes +local txtcatcodes = catcodes.numbers.txtcatcodes -- or just use "txtcatcodes" function references.urls.get(name) local u = urls[name] @@ -467,9 +475,9 @@ end function commands.geturl(name) local url = references.urls.get(name) if url and url ~= "" then - pushcatcodes(txtcatcodes) + ctx_pushcatcodes(txtcatcodes) context(url) - popcatcodes() + ctx_popcatcodes() end end @@ -685,8 +693,8 @@ local function resolve(prefix,reference,args,set) -- we start with prefix,refere if not set then set = { prefix = prefix, reference = reference } else - set.reference = set.reference or reference - set.prefix = set.prefix or prefix + if not set.reference then set.reference = reference end + if not set.prefix then set.prefix = prefix end end local r = settings_to_array(reference) for i=1,#r do @@ -760,8 +768,8 @@ function commands.setreferencearguments(k,v) references.currentset[k].arguments = v end -local expandreferenceoperation = context.expandreferenceoperation -local expandreferencearguments = context.expandreferencearguments +local ctx_expandreferenceoperation = context.expandreferenceoperation +local ctx_expandreferencearguments = context.expandreferencearguments function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex local currentset = references.currentset @@ -769,12 +777,12 @@ function references.expandcurrent() -- todo: two booleans: o_has_tex& a_has_tex for i=1,#currentset do local ci = currentset[i] local operation = ci.operation - if operation and find(operation,"\\") then -- if o_has_tex then - expandreferenceoperation(i,operation) + if operation and find(operation,"\\",1,true) then -- if o_has_tex then + ctx_expandreferenceoperation(i,operation) end local arguments = ci.arguments - if arguments and find(arguments,"\\") then -- if a_has_tex then - expandreferencearguments(i,arguments) + if arguments and find(arguments,"\\",1,true) then -- if a_has_tex then + ctx_expandreferencearguments(i,arguments) end end end @@ -1194,7 +1202,7 @@ local function identify_arguments(set,var,i) local s = specials[var.inner] if s then -- inner{argument} - var.kind = "special with arguments" + var.kind = "special operation with arguments" else var.error = "unknown inner or special" end @@ -1685,23 +1693,30 @@ end luatex.registerstopactions(references.reportproblems) -local innermethod = "names" +-- The auto method will try to avoid named internals in a clever way which +-- can make files smaller without sacrificing external references. Some of +-- the housekeeping happens the backend side. + +local innermethod = "auto" -- was "names" +local defaultinnermethod = defaultinnermethod +references.innermethod = innermethod -- don't mess with this one directly function references.setinnermethod(m) if m then - if m == "page" or m == "mixed" or m == "names" then + if m == "page" or m == "mixed" or m == "names" or m == "auto" then innermethod = m elseif m == true or m == v_yes then innermethod = "page" end end + references.innermethod = innermethod function references.setinnermethod() report_references("inner method is already set and frozen to %a",innermethod) end end function references.getinnermethod() - return innermethod or "names" + return innermethod or defaultinnermethod end directives.register("references.linkmethod", function(v) -- page mixed names @@ -1710,28 +1725,21 @@ end) -- this is inconsistent -function references.setinternalreference(prefix,tag,internal,view) -- needs checking - if innermethod == "page" then - return unsetvalue - else +local destinationattributes = { } + +local function setinternalreference(prefix,tag,internal,view) -- needs checking + local destination = unsetvalue + if innermethod ~= "page" then local t, tn = { }, 0 -- maybe add to current if tag then if prefix and prefix ~= "" then prefix = prefix .. ":" -- watch out, : here - -- for ref in gmatch(tag,"[^,]+") do - -- tn = tn + 1 - -- t[tn] = prefix .. ref - -- end local function action(ref) tn = tn + 1 t[tn] = prefix .. ref end process_settings(tag,action) else - -- for ref in gmatch(tag,"[^,]+") do - -- tn = tn + 1 - -- t[tn] = ref - -- end local function action(ref) tn = tn + 1 t[tn] = ref @@ -1739,36 +1747,48 @@ function references.setinternalreference(prefix,tag,internal,view) -- needs chec process_settings(tag,action) end end - if internal and innermethod == "names" then -- mixed or page + -- ugly .. later we decide to ignore it when we have a real one + -- but for testing we might want to see them all + if internal and (innermethod == "names" or innermethod == "auto") then -- mixed or page tn = tn + 1 - t[tn] = "aut:" .. internal + t[tn] = internal -- when number it's internal end - local destination = references.mark(t,nil,nil,view) -- returns an attribute - texsetcount("lastdestinationattribute",destination) - return destination + destination = references.mark(t,nil,nil,view) -- returns an attribute end + if internal then -- new + destinationattributes[internal] = destination + end + texsetcount("lastdestinationattribute",destination) + return destination +end + +local function getinternalreference(internal) + return destinationattributes[internal] or 0 end +references.setinternalreference = setinternalreference +references.getinternalreference = getinternalreference +commands.setinternalreference = setinternalreference +commands.getinternalreference = getinternalreference + function references.setandgetattribute(kind,prefix,tag,data,view) -- maybe do internal automatically here - local attr = references.set(kind,prefix,tag,data) and references.setinternalreference(prefix,tag,nil,view) or unsetvalue + local attr = references.set(kind,prefix,tag,data) and setinternalreference(prefix,tag,nil,view) or unsetvalue texsetcount("lastdestinationattribute",attr) return attr end commands.setreferenceattribute = references.setandgetattribute -function references.getinternalreference(n) -- n points into list (todo: registers) +function references.getinternallistreference(n) -- n points into list (todo: registers) local l = lists.collected[n] - return l and l.references.internal or n -end - -function commands.setinternalreference(prefix,tag,internal,view) -- needs checking - context(references.setinternalreference(prefix,tag,internal,view)) + local i = l and l.references.internal + return i and destinationattributes[i] or 0 end -function commands.getinternalreference(n) -- this will also be a texcount +function commands.getinternallistreference(n) -- this will also be a texcount local l = lists.collected[n] - context(l and l.references.internal or n) + local i = l and l.references.internal + context(i and destinationattributes[i] or 0) end -- @@ -2164,7 +2184,7 @@ runners["special operation with arguments"] = runners["special"] -- check the validity. function specials.internal(var,actions) - local v = references.internals[tonumber(var.operation)] + local v = internals[tonumber(var.operation)] local r = v and v.references.realpage if r then actions.realpage = r diff --git a/tex/context/base/strc-ref.mkvi b/tex/context/base/strc-ref.mkvi index 85c6a0729..4696c61da 100644 --- a/tex/context/base/strc-ref.mkvi +++ b/tex/context/base/strc-ref.mkvi @@ -947,11 +947,12 @@ \begingroup \let\crlf\space \let\\\space - \postponenotes + \postponenotes % might go \referencingparameter\c!left \doifreferencefoundelse{#label} {\goto{\limitatetext\currentreferencetitle{\referencingparameter\c!width}\unknown}[#label]}% not so efficient (dup lookup) {}% todo + \flushnotes % might go \referencingparameter\c!right \endgroup} diff --git a/tex/context/base/strc-reg.lua b/tex/context/base/strc-reg.lua index b0d8a8a25..bdb2e0d67 100644 --- a/tex/context/base/strc-reg.lua +++ b/tex/context/base/strc-reg.lua @@ -13,50 +13,95 @@ local utfchar = utf.char local lpegmatch = lpeg.match local allocate = utilities.storage.allocate -local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end) +local trace_registers = false trackers.register("structures.registers", function(v) trace_registers = v end) -local report_registers = logs.reporter("structure","registers") +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 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 mappings = sorters.mappings -local entries = sorters.entries -local replacements = sorters.replacements +local usedinternals = references.usedinternals -local processors = typesetters.processors -local splitprocessor = processors.split +local mappings = sorters.mappings +local entries = sorters.entries +local replacements = sorters.replacements -local texgetcount = tex.getcount +local processors = typesetters.processors +local splitprocessor = processors.split -local variables = interfaces.variables -local context = context -local commands = commands +local texgetcount = tex.getcount -local matchingtilldepth = sections.matchingtilldepth -local numberatdepth = sections.numberatdepth +local variables = interfaces.variables +local v_forward = variables.forward +local v_all = variables.all +local v_yes = variables.yes +local v_current = variables.current +local v_previous = variables.previous +local v_text = variables.text -local absmaxlevel = 5 -- \c_strc_registers_maxlevel +local context = context +local commands = commands + +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 texsetattribute = tex.setattribute + +local a_destination = attributes.private('destination') + +local absmaxlevel = 5 -- \c_strc_registers_maxlevel + +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_stopregisterseewords = context.stopregisterseewords +local ctx_startregisterseewords = context.startregisterseewords +local ctx_registerentry = context.registerentry +local ctx_registerseeword = context.registerseeword +local ctx_registerpagerange = context.registerpagerange +local ctx_registeronepage = context.registeronepage -- 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 = variables.all end - local data = documents.data - local numbers, depth = data.numbers, data.depth - local hash, result, nofresult, all, detail = { }, { }, 0, not names or names == "" or names == variables.all, nil + 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 == variables.all or criterium == variables.text then + if criterium == v_all or criterium == v_text then for i=1,#collected do local v = collected[i] if all then @@ -70,10 +115,11 @@ local function filtercollected(names,criterium,number,collected,prevmode) end end end - elseif criterium == variables.current then + elseif criterium == v_current then + local collectedsections = sections.collected for i=1,#collected do local v = collected[i] - local sectionnumber = sections.collected[v.references.section] + local sectionnumber = collectedsections[v.references.section] if sectionnumber then local cnumbers = sectionnumber.numbers if prevmode then @@ -108,10 +154,11 @@ local function filtercollected(names,criterium,number,collected,prevmode) end end end - elseif criterium == variables.previous then + elseif criterium == v_previous then + local collectedsections = sections.collected for i=1,#collected do local v = collected[i] - local sectionnumber = sections.collected[v.references.section] + local sectionnumber = collectedsections[v.references.section] if sectionnumber then local cnumbers = sectionnumber.numbers if (all or hash[v.metadata.name]) and #cnumbers >= depth then @@ -141,9 +188,9 @@ local function filtercollected(names,criterium,number,collected,prevmode) end elseif criterium == variables["local"] then if sections.autodepth(data.numbers) == 0 then - return filtercollected(names,variables.all,number,collected,prevmode) + return filtercollected(names,v_all,number,collected,prevmode) else - return filtercollected(names,variables.current,number,collected,prevmode) + return filtercollected(names,v_current,number,collected,prevmode) end else -- sectionname, number -- beware, this works ok for registers @@ -193,44 +240,77 @@ registers.filtercollected = filtercollected -- 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 - local internals = references.internals + setmetatableindex(tobesaved,checker) + setmetatableindex(collected,checker) + local usedinternals = references.usedinternals for name, list in next, collected do local entries = list.entries - 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 - internals[internal] = entry + 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 +end + +local function finalizer() + local flaginternals = references.flaginternals + 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 and flaginternals[r.internal] then + r.used = true end end end end end -job.register('structures.registers.collected', tobesaved, initializer) +job.register('structures.registers.collected', tobesaved, initializer, finalizer) + +setmetatableindex(tobesaved,checker) +setmetatableindex(collected,checker) -local function allocate(class) +local function defineregister(class,method) local d = tobesaved[class] - if not d then - d = { - metadata = { - language = 'en', - sorted = false, - class = class - }, - entries = { }, - } - tobesaved[class] = d - end - return d + if method == v_forward then + d.metadata.notsaved = true + end end -registers.define = allocate +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 +commands.defineregister = defineregister +commands.setregistermethod = defineregister local entrysplitter = lpeg.tsplitat('+') -- & obsolete in mkiv @@ -239,7 +319,6 @@ local tagged = { } local function preprocessentries(rawdata) local entries = rawdata.entries if entries then ---~ table.print(rawdata) local e, k = entries[1] or "", entries[2] or "" local et, kt, entryproc, pageproc if type(e) == "table" then @@ -255,14 +334,15 @@ local function preprocessentries(rawdata) kt = lpegmatch(entrysplitter,k) end entries = { } - for k=1,#et do - entries[k] = { et[k] or "", kt[k] or "" } - end + local ok = false for k=#et,1,-1 do - if entries[k][1] ~= "" then - break - else + local etk = et[k] + local ktk = kt[k] + if not ok and etk == "" then entries[k] = nil + else + entries[k] = { etk or "", ktk ~= "" and ktk or nil } + ok = true end end rawdata.list = entries @@ -277,44 +357,94 @@ local function preprocessentries(rawdata) end end -function registers.store(rawdata) -- metadata, references, entries - local data = allocate(rawdata.metadata.name).entries +local function storeregister(rawdata) -- metadata, references, entries local references = rawdata.references - references.realpage = references.realpage or 0 -- just to be sure as it can be refered to + local metadata = rawdata.metadata + -- checking + 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 + -- + 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] = true -- 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) - data[#data+1] = rawdata + entries[#entries+1] = rawdata local label = references.label - if label and label ~= "" then tagged[label] = #data end - context(#data) + if label and label ~= "" then + tagged[label] = #entries + else + references.label = nil + end + return #entries end -function registers.enhance(name,n) - local r = tobesaved[name].entries[n] - if r then - r.references.realpage = texgetcount("realpageno") +local function enhanceregister(name,n) + local data = tobesaved[name].metadata.notsaved and collected[name] or tobesaved[name] + local entry = data.entries[n] + if entry then + entry.references.realpage = texgetcount("realpageno") end end -function registers.extend(name,tag,rawdata) -- maybe do lastsection internally +local function extendregister(name,tag,rawdata) -- maybe do lastsection internally if type(tag) == "string" then tag = tagged[tag] end if tag then - local r = tobesaved[name].entries[tag] - if r then - local rr = r.references - rr.lastrealpage = texgetcount("realpageno") - rr.lastsection = sections.currentid() + 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 - for k,v in next, rawdata do - if not r[k] then - r[k] = v + 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 - local rk = r[k] - for kk,vv in next, v do + for kk, vv in next, v do if type(vv) == "table" then if next(vv) then rk[kk] = vv @@ -330,6 +460,19 @@ function registers.extend(name,tag,rawdata) -- maybe do lastsection internally end end +registers.store = storeregister +registers.enhance = enhanceregister +registers.extend = extendregister + +function commands.storeregister(rawdata) + local nofentries = storeregister(rawdata) + setinternalreference(nil,nil,rawdata.references.internal) + context(nofentries) +end + +commands.enhanceregister = enhanceregister +commands.extendregister = extendregister + -- sorting and rendering local compare = sorters.comparers.basic @@ -339,7 +482,8 @@ function registers.compare(a,b) if result ~= 0 then return result else - local ka, kb = a.metadata.kind, b.metadata.kind + local ka = a.metadata.kind + local kb = b.metadata.kind if ka == kb then local page_a, page_b = a.references.realpage, b.references.realpage if not page_a or not page_b then @@ -453,17 +597,19 @@ end function registers.prepare(data) -- data has 'list' table - local strip = sorters.strip + local strip = sorters.strip local splitter = sorters.splitters.utf - local result = data.result + local result = data.result if result then for i=1, #result do - local entry, split = result[i], { } - local list = entry.list + local entry = result[i] + local split = { } + local list = entry.list if list then for l=1,#list do - local ll = list[l] - local word, key = ll[1], ll[2] + local ll = list[l] + local word = ll[1] + local key = ll[2] if not key or key == "" then key = word end @@ -478,7 +624,11 @@ function registers.prepare(data) end function registers.sort(data,options) - sorters.sort(data.result,registers.compare) + -- if options.pagenumber == false then + -- sorters.sort(data.result,compare) + -- else + sorters.sort(data.result,registers.compare) + -- end end function registers.unique(data,options) @@ -487,7 +637,8 @@ function registers.unique(data,options) for k=1,#dataresult do local v = dataresult[k] if prev then - local pr, vr = prev.references, v.references + local vr = v.references + local pr = prev.references if not equal(prev.list,v.list) then -- ok elseif pr.realpage ~= vr.realpage then @@ -530,10 +681,11 @@ function registers.finalize(data,options) -- maps character to index (order) if trace_registers then report_registers("splitting at %a",tag) end - done, nofdone = { }, 0 + done = { } + nofdone = 0 nofsplit = nofsplit + 1 + lasttag = tag split[nofsplit] = { tag = tag, data = done } - lasttag = tag end nofdone = nofdone + 1 done[nofdone] = v @@ -541,7 +693,7 @@ function registers.finalize(data,options) -- maps character to index (order) data.result = split end -function registers.analyzed(class,options) +local function analyzeregister(class,options) local data = collected[class] if data and data.entries then options = options or { } @@ -558,9 +710,21 @@ function registers.analyzed(class,options) end end +registers.analyze = analyzeregister + +function registers.analyze(class,options) + context(analyzeregister(class,options)) +end + + -- 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 + +function commands.registeruserdata(index,name) local data = references.internals[tonumber(index)] data = data and data.userdata and data.userdata[name] if data then @@ -570,22 +734,26 @@ end -- todo: ownnumber +local h_prefixpage = helpers.prefixpage +local h_prefixlastpage = helpers.prefixlastpage +local h_title = helpers.title + local function pagerange(f_entry,t_entry,is_last,prefixspec,pagespec) local fer, ter = f_entry.references, t_entry.references - context.registerpagerange( + ctx_registerpagerange( f_entry.processors and f_entry.processors[2] or "", fer.internal or 0, fer.realpage or 0, function() - helpers.prefixpage(f_entry,prefixspec,pagespec) + h_prefixpage(f_entry,prefixspec,pagespec) end, ter.internal or 0, ter.lastrealpage or ter.realpage or 0, function() if is_last then - helpers.prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys + h_prefixlastpage(t_entry,prefixspec,pagespec) -- swaps page and realpage keys else - helpers.prefixpage (t_entry,prefixspec,pagespec) + h_prefixpage (t_entry,prefixspec,pagespec) end end ) @@ -593,11 +761,11 @@ end local function pagenumber(entry,prefixspec,pagespec) local er = entry.references - context.registeronepage( + ctx_registeronepage( entry.processors and entry.processors[2] or "", er.internal or 0, er.realpage or 0, - function() helpers.prefixpage(entry,prefixspec,pagespec) end + function() h_prefixpage(entry,prefixspec,pagespec) end ) end @@ -665,8 +833,9 @@ local function collapsepages(pages) end function registers.flush(data,options,prefixspec,pagespec) - local collapse_singles = options.compress == variables.yes - local collapse_ranges = options.compress == variables.all + local collapse_singles = options.compress == v_yes + local collapse_ranges = options.compress == v_all + local show_page_number = options.pagenumber ~= false -- true or false local result = data.result local maxlevel = 0 -- @@ -684,18 +853,19 @@ function registers.flush(data,options,prefixspec,pagespec) report_registers("limiting level to %a",maxlevel) end -- - context.startregisteroutput() -local done = { } + 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 + for i=1,maxlevel do + done[i] = false + end local data = sublist.data local d, n = 0, 0 - context.startregistersection(sublist.tag) + ctx_startregistersection(sublist.tag) for d=1,#data do local entry = data[d] if entry.metadata.kind == "see" then @@ -714,9 +884,9 @@ end d = d + 1 local entry = data[d] local e = { false, false, false } -for i=3,maxlevel do - e[i] = false -end + for i=3,maxlevel do + e[i] = false + end local metadata = entry.metadata local kind = metadata.kind local list = entry.list @@ -727,125 +897,135 @@ end if e[i] ~= done[i] then if e[i] and e[i] ~= "" then done[i] = e[i] -for j=i+1,maxlevel do - done[j] = false -end + for j=i+1,maxlevel do + done[j] = false + end + if started then + ctx_stopregisterentry() + started = false + end if n == i then - context.stopregisterentries() - context.startregisterentries(n) +-- ctx_stopregisterentries() +-- ctx_startregisterentries(n) else while n > i do n = n - 1 - context.stopregisterentries() + ctx_stopregisterentries() end while n < i do n = n + 1 - context.startregisterentries(n) + ctx_startregisterentries(n) end end - local internal = entry.references.internal or 0 - local seeparent = entry.references.seeparent or "" - local processor = entry.processors and entry.processors[1] or "" + local references = entry.references + local processors = entry.processors + local internal = references.internal or 0 + local seeparent = references.seeparent or "" + local processor = 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 - context.registerentry(processor,internal,seeparent,function() helpers.title(e[i],metadata) end) + ctx_registerentry(processor,internal,seeparent,function() h_title(e[i],metadata) end) else -- ? - context.registerentry(processor,internal,seeindex,e[i]) + ctx_registerentry(processor,internal,seeindex,e[i]) end else done[i] = false -for j=i+1,maxlevel do - done[j] = false -end + for j=i+1,maxlevel do + done[j] = false + end end end end if kind == 'entry' then - context.startregisterpages() - if collapse_singles or collapse_ranges then - -- 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 + if show_page_number then + ctx_startregisterpages() + if collapse_singles or collapse_ranges then + -- 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 - --~ 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 + 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 - 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) + 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 - pagenumber(first,prefixspec,pagespec) + pagerange(first,last,false,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 - else - while true do - if entry.references.lastrealpage then + elseif 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 + else + 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 - entry = next + 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 + ctx_stopregisterpages() end - context.stopregisterpages() elseif kind == 'see' then local t, nt = { }, 0 while true do @@ -864,38 +1044,46 @@ end end end end - context.startregisterseewords() + ctx_startregisterseewords() 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 "" - context.registerseeword(i,n,processor,0,seeindex,seetext) + ctx_registerseeword(i,n,processor,0,seeindex,seetext) end - context.stopregisterseewords() + ctx_stopregisterseewords() end end + if started then + ctx_stopregisterentry() + started = false + end while n > 0 do - context.stopregisterentries() + ctx_stopregisterentries() n = n - 1 end - context.stopregistersection() + ctx_stopregistersection() end - context.stopregisteroutput() + 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.analyze(class,options) - context(registers.analyzed(class,options)) -end - -function registers.process(class,...) - if registers.analyzed(class,...) > 0 then - registers.flush(collected[class],...) +local function processregister(class,...) + if analyzeregister(class,...) > 0 then + local data = collected[class] + registers.flush(data,...) end end +registers.process = processregister +commands.processregister = processregister diff --git a/tex/context/base/strc-reg.mkiv b/tex/context/base/strc-reg.mkiv index 2d28114c3..d072aca69 100644 --- a/tex/context/base/strc-reg.mkiv +++ b/tex/context/base/strc-reg.mkiv @@ -17,6 +17,8 @@ \unprotect +\startcontextdefinitioncode + % todo: tag:: becomes rendering % todo: language, character, linked, location % todo: fonts etc at sublevels (already defined) @@ -106,6 +108,14 @@ \c!entries=, \c!alternative=] + +\definemixedcolumns + [\v!register] + [\c!n=\registerparameter\c!n, + \c!balance=\registerparameter\c!balance, + \c!align=\registerparameter\c!align, + \c!tolerance=\registerparameter\c!tolerance] + %D \starttyping %D \setupregister[index][1][textcolor=darkred] %D \setupregister[index][2][textcolor=darkgreen,textstyle=bold] @@ -123,7 +133,8 @@ \appendtoks \ifconditional\c_strc_registers_defining \else % todo: dosingle ... \settrue\c_strc_registers_defining - \ctxlua{structures.registers.define('\currentregister')}% + \definemixedcolumns[\currentregister][\v!register]% first as otherwise it overloads start/stop + \ctxcommand{defineregister("\currentregister","\registerparameter\c!referencemethod")}% \normalexpanded{\presetheadtext[\currentregister=\Word{\currentregister}]}% \setuevalue{\currentregister}{\dodoubleempty\strc_registers_insert_entry[\currentregister]}% \setuevalue{\e!see\currentregister}{\dodoubleempty\strc_registers_insert_see[\currentregister]}% @@ -143,6 +154,10 @@ \fi \to \everydefineregister +\appendtoks + \ctxcommand{setregistermethod("\currentregister","\registerparameter\c!referencemethod")}% +\to \everysetupregister + %D Registering: \def\strc_registers_register_page_entry @@ -152,6 +167,52 @@ \expandafter\strc_registers_register_page_entry_indeed \fi} +\def\strc_registers_register_page_expand_xml_entries + {\xmlstartraw + \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% + \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% + \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% + \xmlstopraw + \globallet\currentregistercoding\s!xml} + +\def\strc_registers_register_page_expand_yes_entries + {\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% + \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% + \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% + \globallet\currentregistercoding\s!tex} + +\def\strc_registers_register_page_expand_nop_entries + {\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}% + \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}% + \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}% + \globallet\currentregistercoding\s!tex} + +\def\strc_registers_register_page_expand_xml + {\xmlstartraw + \xdef\currentregisterentries{\registerparameter\c!entries}% + \xmlstopraw + \globallet\currentregistercoding\s!xml} + +\def\strc_registers_register_page_expand_yes + {\xdef\currentregisterentries{\registerparameter\c!entries}% + \globallet\currentregistercoding\s!tex} + +\def\strc_registers_register_page_expand_nop + {\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% + \globallet\currentregistercoding\s!tex} + +\def\strc_registers_register_page_expand_xml_keys + {\xmlstartraw + \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% + \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% + \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% + \xmlstopraw} + +\def\strc_registers_register_page_expand_yes_keys + {\xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% + \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% + \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}} + \def\strc_registers_register_page_entry_indeed#1#2#3% register data userdata {\begingroup \edef\currentregister{#1}% @@ -165,75 +226,54 @@ \xdef\currentregisterxmlsetup {\registerparameter\c!xmlsetup}% \ifx\currentregisterentries\empty \ifx\currentregisterexpansion\s!xml - \xmlstartraw - \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% - \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% - \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% - \xmlstopraw - \globallet\currentregistercoding\s!xml + \strc_registers_register_page_expand_xml_entries + \else\ifx\currentregisterexpansion\v!yes + \strc_registers_register_page_expand_yes_entries \else - \ifx\currentregisterexpansion\v!yes - \xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% - \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% - \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% - \else - \xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}% - \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}% - \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}% - \fi - \globallet\currentregistercoding\s!tex - \fi + \strc_registers_register_page_expand_nop_entries + \fi\fi \else \ifx\currentregisterexpansion\s!xml - \xmlstartraw - \xdef\currentregisterentries{\registerparameter\c!entries}% - \xmlstopraw - \globallet\currentregistercoding\s!xml + \strc_registers_register_page_expand_xml + \else\ifx\currentregisterexpansion\v!yes + \strc_registers_register_page_expand_yes \else - \ifx\currentregisterexpansion\v!yes - \xdef\currentregisterentries{\registerparameter\c!entries}% - \else - \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% - \fi - \globallet\currentregistercoding\s!tex - \fi + \strc_registers_register_page_expand_nop + \fi\fi \fi \ifx\currentregisterkeys\empty \ifx\currentregistercoding\s!xml - \xmlstartraw - \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% - \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% - \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% - \xmlstopraw + \strc_registers_register_page_expand_xml_keys \else - \xdef\currentregisterkeysa{\registerparameter{\c!keys:1}}% - \xdef\currentregisterkeysb{\registerparameter{\c!keys:2}}% - \xdef\currentregisterkeysc{\registerparameter{\c!keys:3}}% + \strc_registers_register_page_expand_yes_keys \fi \fi \setnextinternalreference % we could consider storing register entries in a list which we % could then sort - \xdef\currentregisternumber{\ctxlua{ - structures.registers.store { % 'own' should not be in metadata + \xdef\currentregisternumber{\ctxcommand{storeregister{ % 'own' should not be in metadata metadata = { - kind = "entry", + % kind = "entry", name = "\currentregister", - level = structures.sections.currentlevel(), + % level = structures.sections.currentlevel(), coding = "\currentregistercoding", - catcodes = \the\catcodetable, + % catcodes = \the\catcodetable, \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi - xmlroot = \ifx\currentreferencecoding\s!xml "\xmldocument" \else nil \fi, % only useful when text + \ifx\currentreferencecoding\s!xml + xmlroot = "\xmldocument", % only useful when text + \fi \ifx\currentregisterxmlsetup\empty \else xmlsetup = "\currentregisterxmlsetup", \fi }, references = { - internal = \nextinternalreference, - section = structures.sections.currentid(), % hm, why then not also lastsection the same way + % internal = \nextinternalreference, + % section = structures.sections.currentid(), % hm, why then not also lastsection the same way + \ifx\currentregisterlabel\empty \else label = "\currentregisterlabel", + \fi }, % \ifx\currentregisterentries\empty \else entries = { @@ -253,11 +293,11 @@ userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) } }}% - \ctxlua{structures.references.setinternalreference(nil,nil,\nextinternalreference)}% + % \ctxcommand{setinternalreference(nil,nil,\nextinternalreference)}% in previous \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else - \xdef\currentregistersynchronize{\ctxlatelua{structures.registers.enhance("\currentregister",\currentregisternumber)}}% + \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}% \fi \currentregistersynchronize % here? % needs thinking ... bla\index{bla}. will break before the . but adding a @@ -296,7 +336,7 @@ \fi} \def\strc_registers_stop_entry[#1][#2]% - {\normalexpanded{\ctxlatelua{structures.registers.extend("#1","#2")}}} + {\normalexpanded{\ctxlatecommand{extendregister("#1","#2")}}} \def\setregisterentry {\dotripleempty\strc_registers_set_entry} \def\finishregisterentry{\dotripleempty\strc_registers_finish_entry} @@ -329,19 +369,19 @@ \fi % I hate this kind of mess ... but it's a user request. \ifx\currentregisterentries\empty - \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", { + \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", { metadata = { \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber \fi }, - userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = \!!bs\detokenize{#3}\!!es })% }}% \else - \normalexpanded{\ctxlua{structures.registers.extend("\currentregister","\currentregisterlabel", { + \normalexpanded{\ctxcommand{extendregister("\currentregister","\currentregisterlabel", { metadata = { - catcodes = \the\catcodetable, + % catcodes = \the\catcodetable, coding = "\currentregistercoding", \ifx\currentregisterownnumber\v!yes own = "\registerparameter\c!alternative", % can be used instead of pagenumber @@ -352,7 +392,7 @@ \!!bs\currentregisterentries\!!es, \!!bs\currentregisterkeys\!!es }, - userdata = structures.helpers.touserdata(\!!bs\detokenize{#3}\!!es) + userdata = \!!bs\detokenize{#3}\!!es }) }}% \fi @@ -374,7 +414,7 @@ % \placeregister[index][n=1] % \stoptext -% some overlap wit previous +% some overlap with previous \unexpanded\def\setstructurepageregister {\dotripleempty\strc_registers_set} @@ -421,16 +461,16 @@ \fi \setnextinternalreference % we could consider storing register entries in list - \edef\temp{\ctxlua{ structures.registers.store { + \edef\temp{\ctxcommand{storeregister{ metadata = { kind = "see", name = "\currentregister", - level = structures.sections.currentlevel(), - catcodes = \the\catcodetable, + % level = structures.sections.currentlevel(), + % catcodes = \the\catcodetable, }, references = { - internal = \nextinternalreference, - section = structures.sections.currentid(), + % internal = \nextinternalreference, + % section = structures.sections.currentid(), }, entries = { % we need a special one for xml, this is just a single one @@ -457,12 +497,13 @@ {\begingroup \edef\currentregister{#1}% \setupregister[\currentregister][#2]% - \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxlua{structures.registers.analyze('\currentregister',{ + \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\ctxcommand{analyzeregister('\currentregister',{ language = "\registerparameter\s!language", method = "\registerparameter\c!method", numberorder = "\registerparameter\c!numberorder", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", + pagenumber = \ifx\registerpageseparatorsymbol\empty false\else true\fi, })}}}% brrr \ifcase\utilityregisterlength\relax \resetsystemmode\v!register @@ -479,6 +520,27 @@ \unexpanded\def\placeregister {\dodoubleempty\strc_registers_place} +% \def\strc_registers_place[#1][#2]% +% {\iffirstargument +% \begingroup +% %\forgetall +% \edef\currentregister{#1}% +% \setupregister[\currentregister][#2]% +% \the\everyplaceregister +% \ifnum\registerparameter\c!n>\plusone +% \startcolumns +% [\c!n=\registerparameter\c!n, +% \c!balance=\registerparameter\c!balance, +% \c!align=\registerparameter\c!align, +% \c!tolerance=\registerparameter\c!tolerance]% +% \strc_registers_place_indeed +% \stopcolumns +% \else +% \strc_registers_place_indeed +% \fi +% \endgroup +% \fi} + \def\strc_registers_place[#1][#2]% {\iffirstargument \begingroup @@ -486,43 +548,36 @@ \edef\currentregister{#1}% \setupregister[\currentregister][#2]% \the\everyplaceregister - \ifnum\registerparameter\c!n>\plusone - \startcolumns - [\c!n=\registerparameter\c!n, - \c!balance=\registerparameter\c!balance, - \c!align=\registerparameter\c!align, - \c!tolerance=\registerparameter\c!tolerance]% - \strc_registers_place_indeed - \stopcolumns + \ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone + \startmixedcolumns[\currentregister] + \strc_registers_place_indeed + \stopmixedcolumns \else \strc_registers_place_indeed \fi \endgroup \fi} -\def\strc_registers_place_columns - {\startcolumns - [\c!n=\registerparameter\c!n, - \c!balance=\registerparameter\c!balance, - \c!align=\registerparameter\c!align, - \c!tolerance=\registerparameter\c!tolerance]% - \startpacked[\v!blank]% - \strc_registers_place_indeed - \stoppacked - \stopcolumns} - -\def\strc_registers_place_normal - {\startpacked[\v!blank]% - \strc_registers_place_indeed - \stoppacked} +% \def\strc_registers_place_columns +% {\startmixedcolumns[\currentregister] +% \startpacked[\v!blank]% +% \strc_registers_place_indeed +% \stoppacked +% \stopmixedcolumns} +% +% \def\strc_registers_place_normal +% {\startpacked[\v!blank]% +% \strc_registers_place_indeed +% \stoppacked} \def\strc_registers_place_indeed - {\ctxlua{structures.registers.process('\currentregister',{ + {\ctxcommand{processregister('\currentregister',{ language = "\registerparameter\s!language", method = "\registerparameter\c!method", numberorder = "\registerparameter\c!numberorder", compress = "\registerparameter\c!compress", criterium = "\registerparameter\c!criterium", + pagenumber = \ifx\registerpageseparatorsymbol\empty false\else true\fi, },{ separatorset = "\registerparameter\c!pageprefixseparatorset", conversionset = "\registerparameter\c!pageprefixconversionset", @@ -685,6 +740,9 @@ % \hangafter\plusone % \let\currentregister\savedcurrentregister} +\newdimen\d_strc_registers_hangindent +\newcount\c_strc_registers_hangafter + \unexpanded\def\startregisterentries#1% depth {\endgraf \begingroup @@ -696,8 +754,9 @@ \ifnum\scratchcounter>\plusone \advance\leftskip\d_strc_registers_distance\relax \fi - \hangindent\registerparameter\c!distance\relax - \hangafter\plusone + \d_strc_registers_hangindent\registerparameter\c!distance\relax + \c_strc_registers_hangafter \plusone +\blank[\v!samepage]% \let\currentregister\savedcurrentregister} \unexpanded\def\stopregisterentries @@ -705,6 +764,15 @@ \dostoptagged \endgroup} +\unexpanded\def\startregisterentry#1% todo: level + {\begingroup + \hangindent\d_strc_registers_hangindent + \hangafter \c_strc_registers_hangafter} + +\unexpanded\def\stopregisterentry + {\endgraf + \endgroup} + \unexpanded\def\startregistersection#1% title {\dostarttagged\t!registersection\empty \dostarttagged\t!registertag\empty @@ -745,7 +813,7 @@ \fi} \unexpanded\def\registeronepagerangeseparator - {|\endash|} + {|\endash|} % todo use \prewordbreak \def\withregisterpagecommand#1#2#3#4% {\def\currentregisterpageindex{#2}% @@ -846,7 +914,7 @@ % \placeregister[index][n=1,pagecommand=\MyRegisterPageCommand] % \stoptext -\def\registerpageuserdata #1#2{\ctxlua{structures.registers.userdata(#1,"#2")}} +\def\registerpageuserdata #1#2{\ctxcommand{registeruserdata(#1,"#2")}} \def\currentregisterpageuserdata {\registerpageuserdata\currentregisterpageindex} % {#1} % not yet ok : new internal handler names @@ -857,10 +925,10 @@ \installcorenamespace{registersymbol} \setvalue{\??registersymbol n}% - {\def\registerpageseparatorsymbol{, }} + {\def\registerpageseparatorsymbol{,\space}} \setvalue{\??registersymbol a}% - {\def\registerpageseparatorsymbol{, }} % now done via conversion + {\def\registerpageseparatorsymbol{,\space}} % now done via conversion \setvalue{\??registersymbol\v!none}% {\let\registerpageseparatorsymbol\empty @@ -904,4 +972,6 @@ [\v!index] % [\v!indices] +\stopcontextdefinitioncode + \protect \endinput diff --git a/tex/context/base/strc-rsc.lua b/tex/context/base/strc-rsc.lua index a90f577e3..e2105a4ef 100644 --- a/tex/context/base/strc-rsc.lua +++ b/tex/context/base/strc-rsc.lua @@ -67,11 +67,11 @@ local function splitreference(str) local t = lpegmatch(referencesplitter,str) if t then local a = t.arguments - if a and find(a,"\\") then + if a and find(a,"\\",1,true) then t.has_tex = true else local o = t.arguments - if o and find(o,"\\") then + if o and find(o,"\\",1,true) then t.has_tex = true end end diff --git a/tex/context/base/strc-sec.mkiv b/tex/context/base/strc-sec.mkiv index 2962e2c49..d55b80574 100644 --- a/tex/context/base/strc-sec.mkiv +++ b/tex/context/base/strc-sec.mkiv @@ -15,6 +15,8 @@ \unprotect +\startcontextdefinitioncode + \installcorenamespace{structure} \installdirectcommandhandler \??structure {structure} % unchecked, so we need to initialize used parameters @@ -130,9 +132,9 @@ \xdef\currentstructuremarking {\structureparameter\c!marking}% \xdef\currentstructurelist {\structureparameter\c!list}% \xmlstopraw -\iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll - \strc_sectioning_autobookmark\currentstructuretitle -\fi \fi \fi + \iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll + \strc_sectioning_autobookmark\currentstructuretitle + \fi \fi \fi \ifx\currentstructurelist\empty \globallet\currentstructurelist\currentstructuretitle \fi @@ -143,23 +145,23 @@ \xdef\currentstructurebookmark{\structureparameter\c!bookmark}% \xdef\currentstructuremarking {\structureparameter\c!marking}% \xdef\currentstructurelist {\structureparameter\c!list}% -\iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll - \strc_sectioning_autobookmark\currentstructuretitle -\fi \fi \fi + \iflocation \ifx\currentstructurebookmark\empty \ifconditional\c_strc_bookmarks_preroll + \strc_sectioning_autobookmark\currentstructuretitle + \fi \fi \fi \else \xdef\currentstructuretitle {\detokenizedstructureparameter\c!title}% \xdef\currentstructurebookmark{\detokenizedstructureparameter\c!bookmark}% \xdef\currentstructuremarking {\detokenizedstructureparameter\c!marking}% \xdef\currentstructurelist {\detokenizedstructureparameter\c!list}% \iflocation \ifx\currentstructurebookmark\empty -\ifconditional\c_strc_bookmarks_preroll - \strc_sectioning_autobookmark{\structureparameter\c!title}% -\else - \begingroup - \simplifycommands - \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}% - \endgroup -\fi + \ifconditional\c_strc_bookmarks_preroll + \strc_sectioning_autobookmark{\structureparameter\c!title}% + \else + \begingroup + \simplifycommands + \xdef\currentstructurebookmark{\detokenize\expandafter{\normalexpanded{\structureparameter\c!title}}}% + \endgroup + \fi \fi \fi \fi \ifx\currentstructurelist\empty @@ -170,8 +172,8 @@ \setnextinternalreference \storeinternalreference\currentstructurename\nextinternalreference % \strc_sectioning_set_reference_prefix - \xdef\currentstructurenumber{\ctxlua{ % todo: combine with next call, adapt marks accordingly - structures.sections.somelevel { + \ctxcommand{% todo: combine with next call, adapt marks accordingly + setsectionentry{ references = { internal = \nextinternalreference, block = "\currentsectionblock", @@ -218,7 +220,9 @@ numberdata = { % needed ? block = "\currentsectionblock", - hidenumber = \ifx\currentstructureshownumber\v!no true\else nil\fi, % titles + \ifx\currentstructureshownumber\v!no + hidenumber = true, % titles + \fi % so far separatorset = "\structureparameter\c!sectionseparatorset", conversion = "\structureparameter\c!sectionconversion", % for good old times sake @@ -231,14 +235,12 @@ }, userdata = \!!bs\detokenize{#3}\!!es % will be converted to table at the lua end } - }}% - % \xdef\currentstructurelistnumber{\ctxcommand{addtolist(structures.sections.current())}}% + }% \xdef\currentstructurelistnumber{\ctxcommand{currentsectiontolist()}}% % \currentstructuresynchronize has to be called someplace, since it introduces a node \setstructuresynchronization\currentstructurelistnumber \endgroup} -\let\currentstructurenumber \!!zerocount \let\currentsectioncountervalue \!!zerocount % redefined later \let\previoussectioncountervalue\!!zerocount % redefined later @@ -300,14 +302,14 @@ \newconditional\c_strc_rendering_continuous % not used (mkii ?) -\def\setstructurelevel #1#2{\ctxlua{structures.sections.setlevel("#1","#2")}} % name, level|parent -\def\getstructurelevel #1{\ctxlua{structures.sections.getcurrentlevel("#1")}}% name -\def\setstructurenumber #1#2{\ctxlua{structures.sections.setnumber(#1,"#2")}} % level, number (+/-) -\def\getstructurenumber #1{\ctxlua{structures.sections.getnumber(#1)}} % level -\def\getsomestructurenumber #1#2{\ctxlua{structures.sections.getnumber(#1,"#2")}} % level, what -\def\getfullstructurenumber #1{\ctxlua{structures.sections.fullnumber(#1)}} % level -\def\getsomefullstructurenumber#1#2{\ctxlua{structures.sections.fullnumber(#1,"#2")}} -\def\getspecificstructuretitle #1{\ctxlua{structures.sections.structuredata("#1","titledata.title",nil,"\headparameter\s!catcodes")}}% +\def\setstructurelevel #1#2{\ctxcommand{setsectionlevel("#1","#2")}} % name, level|parent +\def\getstructurelevel #1{\ctxcommand{getcurrentsectionlevel("#1")}}% name +\def\setstructurenumber #1#2{\ctxcommand{setsectionnumber(#1,"#2")}} % level, number (+/-) +\def\getstructurenumber #1{\ctxcommand{getsectionnumber(#1)}} % level +\def\getsomestructurenumber #1#2{\ctxcommand{getsectionnumber(#1,"#2")}} % level, what +\def\getfullstructurenumber #1{\ctxcommand{getfullsectionnumber(#1)}} % level +\def\getsomefullstructurenumber#1#2{\ctxcommand{getfullsectionnumber(#1,"#2")}} +\def\getspecificstructuretitle #1{\ctxcommand{getstructuredata("#1","titledata.title",nil,"\headparameter\s!catcodes")}}% % will be: % @@ -435,7 +437,7 @@ \edef\currentsectionheadcoupling{\sectionheadcoupling\currenthead}% \edef\currentsectionheadsection {\sectionheadsection \currentsectionheadcoupling}% \edef\currentsectionlevel {\sectionlevel \currentsectionheadsection}% - \ctxlua{structures.sections.register("\currenthead",{ + \ctxcommand{registersection("\currenthead",{ coupling = "\currentsectionheadcoupling", section = "\currentsectionheadsection", level = \currentsectionlevel, @@ -578,8 +580,8 @@ % head -> head -\def\sectionheadmarkingtitle #1#2{\ctxlua{structures.marks.title("#1","#2")}} -\def\sectionheadmarkingnumber#1#2{\ctxlua{structures.marks.number("#1","#2")}} +\def\sectionheadmarkingtitle #1#2{\ctxcommand{markingtitle("#1","#2")}} +\def\sectionheadmarkingnumber#1#2{\ctxcommand{markingnumber("#1","#2")}} \def\sectionheadcoupling#1{\namedheadparameter{#1}\c!coupling} \def\sectionheadsection #1{\namedheadparameter{#1}\c!section} @@ -763,7 +765,7 @@ \unexpanded\def\placeheadtext {\dosingleempty\strc_sectioning_place_head_text } % use with care \unexpanded\def\placeheadnumber{\dosingleempty\strc_sectioning_place_head_number} % use with care -\unexpanded\def\strc_sectioning_report{\ctxlua{structures.sections.reportstructure()}} +\unexpanded\def\strc_sectioning_report{\ctxcommand{reportstructure()}} \ifdefined\strc_rendering_initialize_style_and_color \else @@ -1039,8 +1041,8 @@ #1% \fi} -\def\currentsectioncountervalue {\ctxlua{structures.sections.depthnumber(\thenamedheadlevel\currenthead)}} -\def\previoussectioncountervalue{\ctxlua{structures.sections.depthnumber(\thenamedheadlevel\currenthead-1)}} +\def\currentsectioncountervalue {\ctxcommand{depthnumber(\thenamedheadlevel\currenthead)}} +\def\previoussectioncountervalue{\ctxcommand{depthnumber(\thenamedheadlevel\currenthead-1)}} \def\strc_sectioning_handle_page_nop {\edef\p_continue{\headparameter\c!continue}% @@ -1119,7 +1121,7 @@ \let\sectioncountervalue\structurevalue -\def\currentheadtext{obsolete, use marks} +\def\currentheadtext{obsolete,\space use marks} % list references, will be redone in lua when we need it @@ -1154,4 +1156,6 @@ \finalizeautostructurelevels \to \everystoptext +\stopcontextdefinitioncode + \protect \endinput diff --git a/tex/context/base/strc-syn.lua b/tex/context/base/strc-syn.lua index ca4b3ac18..604365b2d 100644 --- a/tex/context/base/strc-syn.lua +++ b/tex/context/base/strc-syn.lua @@ -12,6 +12,9 @@ local allocate = utilities.storage.allocate -- interface to tex end +local context = context +local sorters = sorters + local structures = structures local synonyms = structures.synonyms local tags = structures.tags @@ -19,6 +22,10 @@ local tags = structures.tags local collected = allocate() local tobesaved = allocate() +local firstofsplit = sorters.firstofsplit +local strip = sorters.strip +local splitter = sorters.splitters.utf + synonyms.collected = collected synonyms.tobesaved = tobesaved @@ -114,8 +121,6 @@ function synonyms.filter(data,options) end function synonyms.prepare(data) - local strip = sorters.strip - local splitter = sorters.splitters.utf local result = data.result if result then for i=1, #result do @@ -123,7 +128,7 @@ function synonyms.prepare(data) local rd = r.definition if rd then local rt = rd.tag - local sortkey = (rt and rt ~= "" and rt) or rd.synonym + local sortkey = rt and rt ~= "" and rt or rd.synonym r.split = splitter(strip(sortkey)) end end @@ -140,13 +145,17 @@ function synonyms.finalize(data,options) local split = { } for k=1,#result do local v = result[k] - local entry, tag = sorters.firstofsplit(v) + local entry, tag = firstofsplit(v) local s = split[entry] -- keeps track of change + local d if not s then - s = { tag = tag, data = { } } + d = { } + s = { tag = tag, data = d } split[entry] = s + else + d = s.data end - s.data[#s.data+1] = v + d[#d+1] = v end data.result = split end @@ -154,24 +163,21 @@ end -- for now, maybe at some point we will do a multipass or so -- maybe pass the settings differently +local ctx_synonymentry = context.synonymentry + function synonyms.flush(data,options) local kind = data.metadata.kind -- hack, will be done better - -- context[format("\\start%soutput",kind)]() local result = data.result local sorted = table.sortedkeys(result) for k=1,#sorted do local letter = sorted[k] local sublist = result[letter] local data = sublist.data - -- context[format("\\start%ssection",kind)](sublist.tag) for d=1,#data do local entry = data[d].definition - -- context[format("\\%sentry",kind)](d,entry.tag,entry.synonym,entry.meaning or "") - context("\\%sentry{%s}{%s}{%s}{%s}",kind,d,entry.tag,entry.synonym,entry.meaning or "") + ctx_synonymentry(d,entry.tag,entry.synonym,entry.meaning or "") end - -- context[format("\\stop%ssection",kind)]() end - -- context[format("\\stop%soutput",kind)]() data.result = nil data.metadata.sorted = false end @@ -196,3 +202,8 @@ function synonyms.process(class,options) end end +commands.registersynonym = synonyms.register +commands.registerusedsynonym = synonyms.registerused +commands.synonymmeaning = synonyms.meaning +commands.synonymname = synonyms.synonym +commands.processsynonyms = synonyms.process diff --git a/tex/context/base/strc-syn.mkiv b/tex/context/base/strc-syn.mkiv index e0087d450..73aca18e6 100644 --- a/tex/context/base/strc-syn.mkiv +++ b/tex/context/base/strc-syn.mkiv @@ -20,20 +20,6 @@ \unprotect -\ifdefined\dotagsynonym \else \let\dotagsynonym\relax \fi -\ifdefined\dotagsorting \else \let\dotagsorting\relax \fi - -% general help, can be shared - -% simplifiedcommands -> flag in lua -% -% expansion -% criterium -> when start, then flag in list -% command-> wanneer? -% state -> flagging enabled -% conversion ? -% todo: register xml mode etc - % split but common in lua \def\preprocessexpansion#1#2#3#4% @@ -51,13 +37,93 @@ \globallet#3\s!tex \fi} -\installcorenamespace{synonym} +%D We now use a simple list variant: + +\installcorenamespace {simplelist} + +\installcommandhandler \??simplelist {simplelist} \??simplelist + +\let\setupsimplelists\setupsimplelist + +\setupsimplelists[% + %c!title=, + %c!text=, + % + %c!style=, + %c!color=, + %c!command=, + %c!align=, + % + %c!headstyle=, + %c!headcolor=, + %c!headalign=, + % + %c!titlestyle=, + %c!titlecolor=, + %c!titlecommand=, + %c!titleleft=, + %c!titleright=, + % + %c!closesymbol=, + %c!closecommand=, + % + \c!alternative=\v!left, + \c!display=\v!yes, + \c!width=7\emwidth, + \c!distance=\emwidth, + \c!titledistance=.5\emwidth, + %c!hang=, + %c!sample=, + \c!margin=\v!no, + \c!before=\blank, + \c!inbetween=\blank, + \c!after=\blank, + %c!indentnext=, + %c!indenting=, + % + \c!expansion=\v!no, + %c!xmlsetup=, + %s!catcodes=, + \s!language=\currentmainlanguage, +] + +\appendtoks + \setfalse\c_strc_constructions_define_commands + \ifx\currentsimplelistparent\empty + \defineconstruction[\currentsimplelist][\s!handler=\v!simplelist,\c!level=1]% + \else + \defineconstruction[\currentsimplelist][\currentsimplelistparent][\s!handler=\v!simplelist,\c!level=1]% + \fi + \settrue\c_strc_constructions_define_commands +\to \everydefinesimplelist + +\setuvalue{\??constructioninitializer\v!simplelist}% + {\let\currentsimplelist \currentconstruction + \let\constructionparameter \simplelistparameter + \let\detokenizedconstructionparameter\detokenizedsimplelistparameter + \let\letconstructionparameter \letsimplelistparameter + \let\useconstructionstyleandcolor \usesimpleliststyleandcolor + \let\setupcurrentconstruction \setupcurrentsimplelist} + +\setuvalue{\??constructionfinalizer\v!simplelist}% + {} + +\setuvalue{\??constructiontexthandler\v!simplelist}% + {\begingroup + \useconstructionstyleandcolor\c!headstyle\c!headcolor + \the\everyconstruction + \constructionparameter\c!headcommand + {\strut + \currentsimplelistentry}% + \endgroup} -\installsimplecommandhandler \??synonym {synonym} \??synonym +% And we build on top of this. -\let\setupsynonyms\setupsynonym +\ifdefined\dotagsynonym \else \let\dotagsynonym\relax \fi +\ifdefined\dotagsorting \else \let\dotagsorting\relax \fi -\setupsynonyms +\definesimplelist + [\v!synonym] [\c!state=\v!start, %\c!synonymstyle=, %\c!textstyle=, @@ -75,50 +141,62 @@ %\c!after=, \c!indentnext=\v!no, %\c!expansion=, - \c!method=, - \s!language=\currentmainlanguage] + \c!method=] + +\let\setupsynonyms\setupsimplelist \unexpanded\def\definesynonyms - {\doquadrupleempty\dodefinesynonyms} + {\doquadrupleempty\strc_synonyms_define} -\def\dodefinesynonyms[#1][#2][#3][#4]% name plural \meaning \use +\def\strc_synonyms_define[#1][#2][#3][#4]% name plural \meaning \use {\edef\currentsynonym{#1}% \iffourthargument - \unexpanded\def#4##1{\doinsertsynonym{#1}{##1}}% name tag + \unexpanded\def#4##1{\strc_synonyms_insert{#1}{##1}}% name tag \ifthirdargument - \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning + \unexpanded\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning \fi \setuvalue{#1}{\definesynonym[\v!no][#1]}% \name \else \ifthirdargument - \unexpanded\def#3##1{\doinsertsynonymmeaning{#1}{##1}}% \meaning + \unexpanded\def#3##1{\strc_synonyms_insert_meaning{#1}{##1}}% \meaning \fi \setuvalue{#1}{\definesynonym[\v!yes][#1]}% \name \fi - \checksynonymparent - \setupcurrentsynonym[\s!single={#1},\s!multi={#2}]% + % +% \checksynonymparent +% \setupcurrentsynonym[\s!single={#1},\s!multi={#2}]% + \setfalse\c_strc_constructions_define_commands + \definesimplelist + [\currentsynonym]% + [\v!sorting] + [\s!single={#1},% + \s!multi={#2}]% + \settrue\c_strc_constructions_define_commands + % \presetheadtext[#2=\Word{#2}]% changes the \if...argument + % \setvalue{\e!setup #2\e!endsetup}{\setupsynonym[#1]}% obsolete definition \setvalue{\e!place \e!listof#2}{\placelistofsynonyms[#1]}% accepts extra argument \setvalue{\e!complete\e!listof#2}{\completelistofsynonyms[#1]}} \unexpanded\def\definesynonym - {\dotripleempty\dodefinesynonym} + {\dotripleempty\strc_synonyms_define_entry} -\def\dodefinesynonym[#1][#2][#3]#4#5% +\def\strc_synonyms_define_entry[#1][#2][#3]#4#5% {\begingroup \edef\currentsynonym{#2}% \edef\currentsynonymtag{#3}% + \let\currentsimplelist\currentsimplelist \ifx\currentsynonymtag\empty \edef\currentsynonymtag{#4}% \fi \ifx\currentsynonymtag\empty % todo: error message \else - \edef\currentsynonymexpansion{\synonymparameter\c!expansion}% + \edef\currentsynonymexpansion{\simplelistparameter\c!expansion}% \preprocessexpansion\currentsynonymexpansion\currentsynonymtext \currentsynonymcoding{#4}% \preprocessexpansion\currentsynonymexpansion\currentsynonymmeaning\currentsynonymcoding{#5}% - \ctxlua{structures.synonyms.register("\currentsynonym", "synonym", { + \ctxcommand{registersynonym("\currentsynonym", "synonym", { metadata = { catcodes = \the\catcodetable, coding = "\currentsynonymcoding", @@ -131,91 +209,77 @@ used = false, } })}% - \doif{#1}\v!yes{\setuxvalue\currentsynonymtag{\noexpand\doinsertsynonym{\currentsynonym}{\currentsynonymtag}}}% + \doif{#1}\v!yes{\setuxvalue\currentsynonymtag{\strc_synonyms_insert{\currentsynonym}{\currentsynonymtag}}}% \fi \endgroup} \unexpanded\def\registersynonym - {\dodoubleargument\doregistersynonym} + {\dodoubleargument\strc_synonyms_register} -\def\doregistersynonym[#1][#2]% - {\ctxlua{structures.synonyms.registerused("#1","#2")}} +\def\strc_synonyms_register[#1][#2]% + {\ctxcommand{registerusedsynonym("#1","#2")}} -\unexpanded\def\doinsertsynonymmeaning#1#2% name tag +\unexpanded\def\strc_synonyms_insert_meaning#1#2% name tag {\begingroup - \def\currentsynonym{#1}% - \usesynonymstyleandcolor\c!textstyle\c!textcolor - \synonymparameter\c!textcommand{\ctxlua{structures.synonyms.meaning("#1","#2")}}% + \def\currentsimplelist{#1}% + \usesimpleliststyleandcolor\c!textstyle\c!textcolor + \simplelistparameter\c!textcommand{\ctxcommand{synonymmeaning("#1","#2")}}% \endgroup} -\unexpanded\def\doinsertsynonym#1#2% name tag +\unexpanded\def\strc_synonyms_insert#1#2% name tag {\begingroup - \def\currentsynonym{#1}% + \edef\currentsimplelist{#1}% + \let\currentsynonym\currentsimplelist % for a while \def\currentsynonymtag{#2}% \dostarttagged\t!synonym\currentsynonym \dotagsynonym - \usesynonymstyleandcolor\c!synonymstyle\c!synonymcolor - \synonymparameter\c!synonymcommand{\ctxlua{structures.synonyms.synonym("#1","#2")}}% + \usesimpleliststyleandcolor\c!synonymstyle\c!synonymcolor + \simplelistparameter\c!synonymcommand{\ctxcommand{synonymname("#1","#2")}}% \dostoptagged - \normalexpanded{\endgroup\synonymparameter\c!next}} + \normalexpanded{\endgroup\simplelistparameter\c!next}} \unexpanded\def\placelistofsynonyms - {\dodoubleempty\doplacelistofsynonyms} + {\dodoubleempty\strc_synonyms_place_list} -\def\doplacelistofsynonyms[#1][#2]% +\def\strc_synonyms_place_list[#1][#2]% {\begingroup - \def\currentsynonym{#1}% - \definedescription % todo, per class - [syndef] - [\c!location=\synonymparameter\c!location, - \c!width=\synonymparameter\c!width, - \c!distance=\synonymparameter\c!distance, - \c!sample=\synonymparameter\c!sample, - \c!hang=\synonymparameter\c!hang, - \c!align=\synonymparameter\c!align, - \c!before=\synonymparameter\c!before, - \c!inbetween=\synonymparameter\c!inbetween, - \c!after=\synonymparameter\c!after, - \c!indentnext=\synonymparameter\c!indentnext, - \c!headstyle=\synonymparameter\c!textstyle, - \c!headcolor=\synonymparameter\c!textcolor, - \c!style=, - \c!color=. - #2]% + \edef\currentsimplelist{#1}% + \strc_constructions_initialize{#1}% + \setupcurrentsimplelist[#2]% + \let\synonymentry\strc_synonym_normal \startpacked - \ctxlua{structures.synonyms.process('#1',{ - criterium = "\synonymparameter\c!criterium", - language = "\synonymparameter\s!language", - method = "\synonymparameter\c!method", + \ctxcommand{processsynonyms('#1',{ + criterium = "\simplelistparameter\c!criterium", + language = "\simplelistparameter\s!language", + method = "\simplelistparameter\c!method", })}% \stoppacked \endgroup} \def\completelistofsynonyms - {\dodoubleempty\docompletelistofsynonyms} + {\dodoubleempty\strc_synonyms_complete_list} -\def\docompletelistofsynonyms[#1][#2]% - {\edef\currentsynonym{#1}% - \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\synonymparameter\s!multi}},\c!reference=#1]}% - \doplacelistofsynonyms[#1][#2]% +\def\strc_synonyms_complete_list[#1][#2]% + {\begingroup + \edef\currentsimplelist{#1}% + \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\simplelistparameter\s!multi}},\c!reference=#1]}% + \strc_synonyms_place_list[#1][#2]% \page - \stopnamedsection} - -\let\startsynonymoutput \relax -\let\stopsynonymoutput \relax -\let\startsynonymsection\gobbleoneargument -\let\stopsynonymsection \relax + \stopnamedsection + \endgroup} -\unexpanded\def\synonymentry#1#2#3#4% - {\syndef{#3}#4\par} +\unexpanded\def\strc_synonym_normal#1#2#3#4% + {\begingroup + \def\currentsimplelistentry{#3}% + \csname\??constructionstarthandler\v!construction\endcsname + #4% + \csname\??constructionstophandler\v!construction\endcsname + \endgroup} %D Sorting (a simplified version of synonym). -\installcorenamespace{sorting} - -\installsimplecommandhandler \??sorting {sorting} \??sorting - -\setupsorting +\definesimplelist + [\v!sorting] [\c!state=\v!start, %\c!command=, % we test for defined ! %\c!criterium=, @@ -223,48 +287,57 @@ %\c!before=, \c!after=\endgraf, %\c!expansion=, - \c!method=, - \s!language=\currentmainlanguage] + \c!method=] + +\let\setupsorting\setupsimplelist \unexpanded\def\definesorting - {\dotripleempty\dodefinesorting} + {\dotripleempty\strc_sorting_define} % if #3=\relax or \v!none, then no command but still protected -\def\dodefinesorting[#1][#2][#3]% +\def\strc_sorting_define[#1][#2][#3]% {\edef\currentsorting{#1}% \ifthirdargument \doifnot{#3}\v!none {\ifx#3\relax \else - \unexpanded\def#3##1{\doinsertsort{#1}{##1}}% + \unexpanded\def#3##1{\strc_sorting_insert{#1}{##1}}% \fi}% \setuvalue{#1}{\definesort[\v!no][#1]}% \else \setuvalue{#1}{\definesort[\v!yes][#1]}% \fi - \checksortingparent - \setupcurrentsorting[\s!multi={#2}]% + \setfalse\c_strc_constructions_define_commands + \definesimplelist + [\currentsorting]% + [\v!sorting] + [\s!single={#1},% + \s!multi={#2}]% + \settrue\c_strc_constructions_define_commands + % \presetheadtext[#2=\Word{#2}]% after \ifthirdargument -) + % \setvalue{\e!setup #2\e!endsetup}{\setupsorting[#1]}% obsolete definition \setvalue{\e!place \e!listof#2}{\placelistofsorts[#1]}% \setvalue{\e!complete\e!listof#2}{\completelistofsorts[#1]}} \unexpanded\def\definesort - {\dotripleempty\dodefinesort} + {\dotripleempty\strc_sorting_define_entry} -\def\dodefinesort[#1][#2][#3]#4% +\def\strc_sorting_define_entry[#1][#2][#3]#4% {\begingroup \edef\currentsorting{#2}% \edef\currentsortingtag{#3}% + \let\currentsimplelist\currentsimplelist \ifx\currentsortingtag\empty \edef\currentsortingtag{#4}% \fi \ifx\currentsortingtag\empty % todo: error message \else - \edef\currentsortingexpansion{\sortingparameter\c!expansion}% + \edef\currentsortingexpansion{\simplelistparameter\c!expansion}% \preprocessexpansion\currentsortingexpansion\currentsortingtext\currentsortingcoding{#4}% - \ctxlua{structures.synonyms.register("\currentsorting", "sorting", { + \ctxcommand{registersynonym("\currentsorting", "sorting", { metadata = { catcodes = \the\catcodetable, coding = "\currentsortingcoding", @@ -276,67 +349,77 @@ % used = false, } })}% - \doif{#1}\v!yes{\setuxvalue\currentsortingtag{\noexpand\doinsertsort{\currentsorting}{\currentsortingtag}}}% + \doif{#1}\v!yes{\setuxvalue\currentsortingtag{\strc_sorting_insert{\currentsorting}{\currentsortingtag}}}% \fi \endgroup} -\unexpanded\def\doinsertsort#1#2% name tag +\unexpanded\def\strc_sorting_insert#1#2% name tag {\begingroup % no kap currently, of .. we need to map cap onto WORD \edef\currentsorting{#1}% \def\currentsortingtag{#2}% + \let\currentsimplelist\currentsorting \dostarttagged\t!sorting\currentsorting \dotagsorting - \usesortingstyleandcolor\c!style\c!color - \ctxlua{structures.synonyms.synonym("#1","#2")}% + \usesimpleliststyleandcolor\c!style\c!color + \ctxcommand{synonymname("#1","#2")}% \dostoptagged - \normalexpanded{\endgroup\sortingparameter\c!next}} + \normalexpanded{\endgroup\simplelistparameter\c!next}} \unexpanded\def\registersort - {\dodoubleargument\doregistersort} + {\dodoubleargument\strc_sorting_register} -\def\doregistersort[#1][#2]% - {\ctxlua{structures.synonyms.registerused("#1","#2")}} +\def\strc_sorting_register[#1][#2]% + {\ctxcommand{registerusedsynonym("#1","#2")}} % before after % % maybe just 'commandset' and then combine \unexpanded\def\placelistofsorts - {\dodoubleempty\doplacelistofsorts} + {\dodoubleempty\strc_sorting_place_list} -\def\doplacelistofsorts[#1][#2]% NOG EEN RUWE VERSIE MAKEN ZONDER WITRUIMTE ETC ETC +\def\strc_sorting_place_list[#1][#2]% {\begingroup - \def\currentsorting{#1}% - \setupcurrentsorting[#2]% + \edef\currentsimplelist{#1}% + \strc_constructions_initialize{#1}% + \setupcurrentsimplelist[#2]% + \edef\p_simplelist_command{\simplelistparameter\c!command}% + \ifx\p_simplelist_command\empty + \let\synonymentry\strc_sorting_normal + \else + \let\synonymentry\strc_sorting_command + \fi \startpacked - \ctxlua{structures.synonyms.process('#1',{ - criterium = "\sortingparameter\c!criterium", - language = "\sortingparameter\s!language", - method = "\sortingparameter\c!method", + \ctxcommand{processsynonyms('#1',{ + criterium = "\simplelistparameter\c!criterium", + language = "\simplelistparameter\s!language", + method = "\simplelistparameter\c!method", })}% \stoppacked \endgroup} \unexpanded\def\completelistofsorts - {\dodoubleempty\docompletelistofsorts} + {\dodoubleempty\strc_sorting_complete_list} -\def\docompletelistofsorts[#1][#2]% - {\edef\currentsorting{#1}% - \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\sortingparameter\s!multi}},\c!reference=#1]}% - \doplacelistofsorts[#1][#2]% +\def\strc_sorting_complete_list[#1][#2]% + {\begingroup + \edef\currentsimplelist{#1}% + \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\simplelistparameter\s!multi}},\c!reference=#1]}% + \strc_sorting_place_list[#1][#2]% \page - \stopnamedsection} + \stopnamedsection + \endgroup} -\let\startsortingoutput \relax -\let\stopsortingoutput \relax -\let\startsortingsection\gobbleoneargument -\let\stopsortingsection \relax +\def\strc_sorting_command#1#2#3#4% #4 is meaning but empty here + {\p_simplelist_command{#1}{#2}{#3}} -\def\sortingentry#1#2#3#4% #4 is meaning but empty here - {\doifelsenothing{\sortingparameter\c!command} - {\begingroup\usesortingstyleandcolor\c!style\c!color#3\endgroup\par} % todo - {\sortingparameter\c!command{#1}{#2}{#3}}} +\def\strc_sorting_normal#1#2#3#4% #4 is meaning but empty here + {\begingroup + \usesimpleliststyleandcolor\c!style\c!color + #3% + \endgroup + \par} %D Presets. diff --git a/tex/context/base/syst-aux.lua b/tex/context/base/syst-aux.lua index 6b5e18d16..de15428f9 100644 --- a/tex/context/base/syst-aux.lua +++ b/tex/context/base/syst-aux.lua @@ -78,7 +78,7 @@ end -- end -- end -local pattern = (C((1-P("%"))^1) * Carg(1)) /function(n,d) return format("%.0fsp",d * tonumber(n)/100) end * P("%") * P(-1) +local pattern = (C((1-P("%"))^1) * Carg(1)) /function(n,d) return format("%.0fsp",d * tonumber(n)/100) end * P("%") * P(-1) -- .0 ? -- commands.percentageof("10%",65536*10) @@ -109,7 +109,8 @@ function commands.thetexdefinition(str) context(lpegmatch(pattern,str)) end -local upper, lower = utf.upper, utf.lower +local upper, lower, strip = utf.upper, utf.lower, string.strip function commands.upper(s) context(upper(s)) end function commands.lower(s) context(lower(s)) end +function commands.strip(s) context(strip(s)) end diff --git a/tex/context/base/syst-aux.mkiv b/tex/context/base/syst-aux.mkiv index c7be461a3..876044240 100644 --- a/tex/context/base/syst-aux.mkiv +++ b/tex/context/base/syst-aux.mkiv @@ -346,6 +346,12 @@ \let\if_next_blank_space_token\iffalse \futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character} +\unexpanded\def\doifnextbgroupcselse#1#2% + {\let\m_syst_action_yes#1% + \let\m_syst_action_nop#2% + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character} + \def\syst_helpers_inspect_next_bgroup_character {\ifx\nexttoken\blankspace \expandafter\syst_helpers_reinspect_next_bgroup_character diff --git a/tex/context/base/syst-con.lua b/tex/context/base/syst-con.lua index 48f02da3a..dfbd49051 100644 --- a/tex/context/base/syst-con.lua +++ b/tex/context/base/syst-con.lua @@ -6,29 +6,39 @@ if not modules then modules = { } end modules ['syst-con'] = { license = "see context related readme files" } -converters = converters or { } +local tonumber = tonumber +local utfchar = utf.char +local gsub, format = string.gsub, string.format + +converters = converters or { } +local converters = converters + +local context = context +local comands = commands + +local formatters = string,formatters --[[ldx--

For raw 8 bit characters, the offset is 0x110000 (bottom of plane 18) at the top of 's char range but outside the unicode range.

--ldx]]-- -local tonumber = tonumber -local utfchar = utf.char -local gsub, format = string.gsub, string.format +function converters.hexstringtonumber(n) tonumber(n,16) end +function converters.octstringtonumber(n) tonumber(n, 8) end -function converters.hexstringtonumber(n) tonumber(n,16) end -function converters.octstringtonumber(n) tonumber(n, 8) end function converters.rawcharacter (n) utfchar(0x110000+n) end -function converters.lchexnumber (n) format("%x" ,n) end -function converters.uchexnumber (n) format("%X" ,n) end -function converters.lchexnumbers (n) format("%02x",n) end -function converters.uchexnumbers (n) format("%02X",n) end -function converters.octnumber (n) format("%03o",n) end + +converters.lchexnumber = formatters["%x" ] +converters.uchexnumber = formatters["%X" ] +converters.lchexnumbers = formatters["%02x"] +converters.uchexnumbers = formatters["%02X"] +converters.octnumber = formatters["%03o"] function commands.hexstringtonumber(n) context(tonumber(n,16)) end function commands.octstringtonumber(n) context(tonumber(n, 8)) end + function commands.rawcharacter (n) context(utfchar(0x110000+n)) end + function commands.lchexnumber (n) context("%x" ,n) end function commands.uchexnumber (n) context("%X" ,n) end function commands.lchexnumbers (n) context("%02x",n) end @@ -53,10 +63,10 @@ local cos, sin, tan = math.cos, math.sin, math.tan -- function commands.cos (n) context(cos (n)) end -- function commands.tan (n) context(tan (n)) end -function commands.sind(n) context("%0.6f",sind(n)) end -function commands.cosd(n) context("%0.6f",cosd(n)) end -function commands.tand(n) context("%0.6f",tand(n)) end +function commands.sind(n) context("%0.6F",sind(n)) end +function commands.cosd(n) context("%0.6F",cosd(n)) end +function commands.tand(n) context("%0.6F",tand(n)) end -function commands.sin (n) context("%0.6f",sin (n)) end -function commands.cos (n) context("%0.6f",cos (n)) end -function commands.tan (n) context("%0.6f",tan (n)) end +function commands.sin (n) context("%0.6F",sin (n)) end +function commands.cos (n) context("%0.6F",cos (n)) end +function commands.tan (n) context("%0.6F",tan (n)) end diff --git a/tex/context/base/syst-lua.lua b/tex/context/base/syst-lua.lua index e47041444..cd7dcc062 100644 --- a/tex/context/base/syst-lua.lua +++ b/tex/context/base/syst-lua.lua @@ -17,37 +17,37 @@ local context = context function commands.writestatus(...) logs.status(...) end -- overloaded later -local firstoftwoarguments = context.firstoftwoarguments -- context.constructcsonly("firstoftwoarguments" ) -local secondoftwoarguments = context.secondoftwoarguments -- context.constructcsonly("secondoftwoarguments") -local firstofoneargument = context.firstofoneargument -- context.constructcsonly("firstofoneargument" ) -local gobbleoneargument = context.gobbleoneargument -- context.constructcsonly("gobbleoneargument" ) +local ctx_firstoftwoarguments = context.firstoftwoarguments -- context.constructcsonly("firstoftwoarguments" ) +local ctx_secondoftwoarguments = context.secondoftwoarguments -- context.constructcsonly("secondoftwoarguments") +local ctx_firstofoneargument = context.firstofoneargument -- context.constructcsonly("firstofoneargument" ) +local ctx_gobbleoneargument = context.gobbleoneargument -- context.constructcsonly("gobbleoneargument" ) --- contextsprint(prtcatcodes,[[\ui_fo]]) -- firstofonearguments --- contextsprint(prtcatcodes,[[\ui_go]]) -- gobbleonearguments --- contextsprint(prtcatcodes,[[\ui_ft]]) -- firstoftwoarguments --- contextsprint(prtcatcodes,[[\ui_st]]) -- secondoftwoarguments +-- contextsprint(prtcatcodes,[[\ui_fo]]) -- ctx_firstofonearguments +-- contextsprint(prtcatcodes,[[\ui_go]]) -- ctx_gobbleonearguments +-- contextsprint(prtcatcodes,[[\ui_ft]]) -- ctx_firstoftwoarguments +-- contextsprint(prtcatcodes,[[\ui_st]]) -- ctx_secondoftwoarguments function commands.doifelse(b) if b then - firstoftwoarguments() + ctx_firstoftwoarguments() else - secondoftwoarguments() + ctx_secondoftwoarguments() end end function commands.doif(b) if b then - firstofoneargument() + ctx_firstofoneargument() else - gobbleoneargument() + ctx_gobbleoneargument() end end function commands.doifnot(b) if b then - gobbleoneargument() + ctx_gobbleoneargument() else - firstofoneargument() + ctx_firstofoneargument() end end @@ -59,9 +59,9 @@ end function commands.doifelsespaces(str) if find(str,"^ +$") then - firstoftwoarguments() + ctx_firstoftwoarguments() else - secondoftwoarguments() + ctx_secondoftwoarguments() end end @@ -84,12 +84,12 @@ function commands.doifcommonelse(a,b) -- often the same test for i=1,na do for j=1,nb do if ha[i] == hb[j] then - firstoftwoarguments() + ctx_firstoftwoarguments() return end end end - secondoftwoarguments() + ctx_secondoftwoarguments() end function commands.doifinsetelse(a,b) @@ -97,20 +97,20 @@ function commands.doifinsetelse(a,b) if not hb then hb = lpegmatch(s,b) h[b] = hb end for i=1,#hb do if a == hb[i] then - firstoftwoarguments() + ctx_firstoftwoarguments() return end end - secondoftwoarguments() + ctx_secondoftwoarguments() end local pattern = lpeg.patterns.validdimen function commands.doifdimenstringelse(str) if lpegmatch(pattern,str) then - firstoftwoarguments() + ctx_firstoftwoarguments() else - secondoftwoarguments() + ctx_secondoftwoarguments() end end diff --git a/tex/context/base/tabl-tbl.lua b/tex/context/base/tabl-tbl.lua index 21564a472..b088a1008 100644 --- a/tex/context/base/tabl-tbl.lua +++ b/tex/context/base/tabl-tbl.lua @@ -9,21 +9,25 @@ if not modules then modules = { } end modules ['tabl-tbl'] = { -- A couple of hacks ... easier to do in Lua than in regular TeX. More will -- follow. -local context, commands = context, commands - local tonumber = tonumber local gsub, rep, sub, find = string.gsub, string.rep, string.sub, string.find local P, C, Cc, Ct, lpegmatch = lpeg.P, lpeg.C, lpeg.Cc, lpeg.Ct, lpeg.match +local context = context +local commands = commands + local texsetcount = tex.setcount -local separator = P("|") -local nested = lpeg.patterns.nested -local pattern = Ct((separator * (C(nested) + Cc("")) * C((1-separator)^0))^0) +local separator = P("|") +local nested = lpeg.patterns.nested +local pattern = Ct((separator * (C(nested) + Cc("")) * C((1-separator)^0))^0) + +local ctx_settabulatelastentry = context.settabulatelastentry +local ctx_settabulateentry = context.settabulateentry function commands.presettabulate(preamble) preamble = gsub(preamble,"~","d") -- let's get rid of ~ mess here - if find(preamble,"%*") then + if find(preamble,"*",1,true) then -- todo: lpeg but not now preamble = gsub(preamble, "%*(%b{})(%b{})", function(n,p) return rep(sub(p,2,-2),tonumber(sub(n,2,-2)) or 1) @@ -35,7 +39,7 @@ function commands.presettabulate(preamble) texsetcount("global","c_tabl_tabulate_has_rule_spec_first", t[1] == "" and 0 or 1) texsetcount("global","c_tabl_tabulate_has_rule_spec_last", t[m+1] == "" and 0 or 1) for i=1,m,2 do - context.settabulateentry(t[i],t[i+1]) + ctx_settabulateentry(t[i],t[i+1]) end - context.settabulatelastentry(t[m+1]) + ctx_settabulatelastentry(t[m+1]) end diff --git a/tex/context/base/tabl-tbl.mkiv b/tex/context/base/tabl-tbl.mkiv index 82d1be893..1aeaa2e56 100644 --- a/tex/context/base/tabl-tbl.mkiv +++ b/tex/context/base/tabl-tbl.mkiv @@ -1076,8 +1076,8 @@ \tabulatenoalign{\kern-\lineheight}% \fi} -\setuvalue{\e!start\v!tabulatehead}{\doifnextoptionalelse\tabl_tabulate_start_head_yes\tabl_tabulate_start_head_nop} -\setuvalue{\e!start\v!tabulatetail}{\doifnextoptionalelse\tabl_tabulate_start_foot_yes\tabl_tabulate_start_foot_nop} +\setuvalue{\e!start\v!tabulatehead}{\doifnextoptionalcselse\tabl_tabulate_start_head_yes\tabl_tabulate_start_head_nop} +\setuvalue{\e!start\v!tabulatetail}{\doifnextoptionalcselse\tabl_tabulate_start_foot_yes\tabl_tabulate_start_foot_nop} \let\m_tabl_tabulate_data\empty @@ -1097,7 +1097,7 @@ % {\bgroup % \edef\currenttabulationparent{#1}% % \let\currenttabulation\currenttabulationparent -% \doifnextoptionalelse\tabl_start_defined_yes\tabl_start_defined_nop} +% \doifnextoptionalcselse\tabl_start_defined_yes\tabl_start_defined_nop} % % \def\tabl_start_defined_yes[#1]% % {\edef\currenttabulation{\currenttabulation:#1}% diff --git a/tex/context/base/tabl-xtb.lua b/tex/context/base/tabl-xtb.lua index 653eb6e08..d18719a89 100644 --- a/tex/context/base/tabl-xtb.lua +++ b/tex/context/base/tabl-xtb.lua @@ -41,7 +41,6 @@ local format = string.format local concat = table.concat local points = number.points -local context = context local context_beginvbox = context.beginvbox local context_endvbox = context.endvbox local context_blank = context.blank diff --git a/tex/context/base/tabl-xtb.mkvi b/tex/context/base/tabl-xtb.mkvi index 556bec5ce..cca56dbee 100644 --- a/tex/context/base/tabl-xtb.mkvi +++ b/tex/context/base/tabl-xtb.mkvi @@ -402,7 +402,7 @@ \unexpanded\def\startxrow {\begingroup - \doifnextoptionalelse\tabl_x_start_row_yes\tabl_x_start_row_nop} + \doifnextoptionalcselse\tabl_x_start_row_yes\tabl_x_start_row_nop} \unexpanded\def\tabl_x_start_row_reflow_width_yes[#settings]% {\setupcurrentxtable[#settings]% @@ -435,7 +435,7 @@ \endgroup} \unexpanded\def\startxcell - {\doifnextoptionalelse\tabl_x_start_cell_yes\tabl_x_start_cell_nop} + {\doifnextoptionalcselse\tabl_x_start_cell_yes\tabl_x_start_cell_nop} \unexpanded\def\stopxcell {\tabl_x_stop_cell} @@ -677,7 +677,7 @@ \unexpanded\def\startxgroup {\begingroup - \doifnextoptionalelse\tabl_x_start_group_delayed_one\relax} + \doifnextoptionalcselse\tabl_x_start_group_delayed_one\relax} \unexpanded\def\stopxgroup {\endgroup} @@ -695,7 +695,7 @@ \chaintocurrentxtable{#tag}% \fi \edef\currentxtable{#tag}% - \doifnextoptionalelse\setupcurrentxtable\relax} + \doifnextoptionalcselse\setupcurrentxtable\relax} \let\startxrowgroup \startxgroup \let\stopxrowgroup \stopxgroup @@ -706,7 +706,7 @@ \unexpanded\def\startxcell {\begingroup - \doifnextoptionalelse\tabl_x_start_cell_delayed_one\tabl_x_start_cell_nop} + \doifnextoptionalcselse\tabl_x_start_cell_delayed_one\tabl_x_start_cell_nop} \unexpanded\def\tabl_x_start_cell_delayed_one[#tag]% % {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname @@ -721,7 +721,7 @@ \chaintocurrentxtable{#tag}% \fi \edef\currentxtable{#tag}% - \doifnextoptionalelse\tabl_x_start_cell_yes\tabl_x_start_cell_nop} + \doifnextoptionalcselse\tabl_x_start_cell_yes\tabl_x_start_cell_nop} \unexpanded\def\stopxcell {\tabl_x_stop_cell @@ -731,7 +731,7 @@ \unexpanded\def\startxrow {\begingroup - \doifnextoptionalelse\tabl_x_start_row_delayed_one\tabl_x_start_row_nop} + \doifnextoptionalcselse\tabl_x_start_row_delayed_one\tabl_x_start_row_nop} \unexpanded\def\tabl_x_start_row_delayed_one[#tag]% % {\ifcsname\namedxtablehash{#tag}\s!parent\endcsname @@ -746,7 +746,7 @@ \chaintocurrentxtable{#tag}% \fi \edef\currentxtable{#tag}% - \doifnextoptionalelse\tabl_x_start_row_yes\tabl_x_start_row_nop} + \doifnextoptionalcselse\tabl_x_start_row_yes\tabl_x_start_row_nop} \unexpanded\def\stopxrow {\tabl_x_stop_row diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua index fa9b0cf10..ff1d36486 100644 --- a/tex/context/base/task-ini.lua +++ b/tex/context/base/task-ini.lua @@ -18,11 +18,13 @@ if not modules then modules = { } end modules ['task-ini'] = { -- not apply the font handler, we can remove all checks for subtypes 255 local tasks = nodes.tasks +local prependaction = tasks.prependaction local appendaction = tasks.appendaction local disableaction = tasks.disableaction local freezegroup = tasks.freezegroup local freezecallbacks = callbacks.freeze + appendaction("processors", "normalizers", "typesetters.characters.handler") -- always on appendaction("processors", "normalizers", "fonts.collections.process") -- disabled appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled @@ -120,6 +122,11 @@ appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler") appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler") appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler") +-- rather special (this might get hardcoded): + +-- prependaction("processors", "before", "nodes.properties.attach") +-- appendaction ("shipouts", "normalizers", "nodes.properties.delayed") + -- speedup: only kick in when used disableaction("processors", "languages.replacements.handler") diff --git a/tex/context/base/trac-deb.lua b/tex/context/base/trac-deb.lua index 4cc48c4a5..cd8f803d4 100644 --- a/tex/context/base/trac-deb.lua +++ b/tex/context/base/trac-deb.lua @@ -9,27 +9,30 @@ if not modules then modules = { } end modules ['trac-deb'] = { local lpeg, status = lpeg, status local lpegmatch = lpeg.match -local format, concat, match = string.format, table.concat, string.match +local format, concat, match, find = string.format, table.concat, string.match, string.find local tonumber, tostring = tonumber, tostring -- maybe tracers -> tracers.tex (and tracers.lua for current debugger) -local report_system = logs.reporter("system","tex") +local report_tex = logs.reporter("tex error") +local report_lua = logs.reporter("lua error") +local report_nl = logs.newline +local report_str = logs.writer -tracers = tracers or { } -local tracers = tracers +tracers = tracers or { } +local tracers = tracers -tracers.lists = { } -local lists = tracers.lists +tracers.lists = { } +local lists = tracers.lists -tracers.strings = { } -local strings = tracers.strings +tracers.strings = { } +local strings = tracers.strings -local texgetdimen = tex.getdimen -local texgettoks = tex.gettoks -local texgetcount = tex.getcount +local texgetdimen = tex.getdimen +local texgettoks = tex.gettoks +local texgetcount = tex.getcount -strings.undefined = "undefined" +strings.undefined = "undefined" lists.scratch = { 0, 2, 4, 6, 8 @@ -96,7 +99,9 @@ function tracers.knownlist(name) return l and #l > 0 end -function tracers.showlines(filename,linenumber,offset,errorstr) +local savedluaerror = nil + +function tracers.showlines(filename,linenumber,offset,luaerrorline) local data = io.loaddata(filename) if not data or data == "" then local hash = url.hashed(filename) @@ -109,35 +114,18 @@ function tracers.showlines(filename,linenumber,offset,errorstr) end local lines = data and string.splitlines(data) if lines and #lines > 0 then - -- This does not work completely as we cannot access the last Lua error using - -- table.print(status.list()). This is on the agenda. Eventually we will - -- have a sequence of checks here (tex, lua, mp) at this end. - -- - -- Actually, in 0.75+ the lua error message is even weirder as you can - -- get: - -- - -- LuaTeX error [string "\directlua "]:3: unexpected symbol near '1' ... - -- - -- \endgroup \directlua { - -- - -- So there is some work to be done in the LuaTeX engine. - -- - local what, where = match(errorstr,[[LuaTeX error
:(%d+)]]) - or match(errorstr,[[LuaTeX error %[string "\\(.-lua) "%]:(%d+)]]) -- buglet - if where then + if luaerrorline and luaerrorline > 0 then -- lua error: linenumber points to last line local start = "\\startluacode" local stop = "\\stopluacode" - local where = tonumber(where) - if lines[linenumber] == start then - local n = linenumber - for i=n,1,-1 do - if lines[i] == start then - local n = i + where - if n <= linenumber then - linenumber = n - end + local n = linenumber + for i=n,1,-1 do + if find(lines[i],start) then + n = i + luaerrorline - 1 + if n <= linenumber then + linenumber = n end + break end end end @@ -160,29 +148,46 @@ function tracers.showlines(filename,linenumber,offset,errorstr) end function tracers.printerror(offset) - local inputstack = resolvers.inputstack - local filename = inputstack[#inputstack] or status.filename - local linenumber = tonumber(status.linenumber) or 0 + local inputstack = resolvers.inputstack + local filename = inputstack[#inputstack] or status.filename + local linenumber = tonumber(status.linenumber) or 0 + local lasttexerror = status.lasterrorstring or "?" + local lastluaerror = status.lastluaerrorstring or lasttexerror + local luaerrorline = match(lastluaerror,[[%[.-lua%].-:.-(%d+)]]) -- this will work ok in >=0.79 + local report = luaerrorline and report_lua or report_tex if not filename then - report_system("error not related to input file: %s ...",status.lasterrorstring) + report("error not related to input file: %s ...",lasttexerror) elseif type(filename) == "number" then - report_system("error on line %s of filehandle %s: %s ...",linenumber,filename,status.lasterrorstring) + report("error on line %s of filehandle %s: %s ...",linenumber,lasttexerror) else - -- currently we still get the error message printed to the log/console so we - -- add a bit of spacing around our variant - texio.write_nl("\n") - local errorstr = status.lasterrorstring or "?" - -- inspect(status.list()) - report_system("error on line %s in file %s: %s ...\n",linenumber,filename,errorstr) -- lua error? - texio.write_nl(tracers.showlines(filename,linenumber,offset,errorstr),"\n") + report_nl() + if luaerrorline then + report("error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror) + else + report("error on line %s in file %s: %s",linenumber,filename,lasttexerror) + if tex.show_context then + report_nl() + tex.show_context() + end + end + report_nl() + report_str(tracers.showlines(filename,linenumber,offset,tonumber(luaerrorline))) + report_nl() end end +local nop = function() end + directives.register("system.errorcontext", function(v) + local register = callback.register if v then - callback.register('show_error_hook', function() tracers.printerror(v) end) + register('show_error_message', nop) + register('show_error_hook', function() tracers.printerror(v) end) + register('show_lua_error_hook', nop) else - callback.register('show_error_hook', nil) + register('show_error_message', nil) + register('show_error_hook', nil) + register('show_lua_error_hook', nil) end end) diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua index 067cff27c..034726ffc 100644 --- a/tex/context/base/trac-inf.lua +++ b/tex/context/base/trac-inf.lua @@ -12,7 +12,7 @@ if not modules then modules = { } end modules ['trac-inf'] = { -- and rawget. local type, tonumber, select = type, tonumber, select -local format, lower = string.format, string.lower +local format, lower, find = string.format, string.lower, string.find local concat = table.concat local clock = os.gettimeofday or os.clock -- should go in environment @@ -123,10 +123,8 @@ function statistics.show() -- this code will move local register = statistics.register register("used platform", function() - local mask = lua.mask or "ascii" - return format("%s, type: %s, binary subtree: %s, symbol mask: %s (%s)", - os.platform or "unknown",os.type or "unknown", environment.texos or "unknown", - mask,mask == "utf" and "τεχ" or "tex") + return format("%s, type: %s, binary subtree: %s", + os.platform or "unknown",os.type or "unknown", environment.texos or "unknown") end) register("luatex banner", function() return lower(status.banner) @@ -139,16 +137,25 @@ function statistics.show() return format("%s direct, %s indirect, %s total", total-indirect, indirect, total) end) if jit then - local status = { jit.status() } - if status[1] then - register("luajit status", function() - return concat(status," ",2) - end) + local jitstatus = { jit.status() } + if jitstatus[1] then + register("luajit options", concat(jitstatus," ",2)) end end -- so far -- collectgarbage("collect") - register("current memory usage",statistics.memused) + register("lua properties",function() + local list = status.list() + local hashchar = tonumber(list.luatex_hashchars) + local mask = lua.mask or "ascii" + return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + jit and "luajit" or "lua", + statistics.memused(), + list.luatex_hashtype or "default", + hashchar and 2^hashchar or "unknown", + mask, + mask == "utf" and "τεχ" or "tex") + end) register("runtime",statistics.runtime) logs.newline() -- initial newline for i=1,#statusinfo do diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua index 420e9a00d..7460955eb 100644 --- a/tex/context/base/trac-vis.lua +++ b/tex/context/base/trac-vis.lua @@ -439,7 +439,7 @@ local function ruledbox(head,current,vertical,layer,what,simple,previous) local ht = getfield(current,"height") local dp = getfield(current,"depth") local next = getnext(current) - local prev = previous -- getprev(current) ... prev can be wrong in math mode + local prev = previous -- getprev(current) ... prev can be wrong in math mode < 0.78.3 setfield(current,"next",nil) setfield(current,"prev",nil) local linewidth = emwidth/10 @@ -860,7 +860,7 @@ local function cleanup() nk, k_cache = freed(k_cache) nw, w_cache = freed(w_cache) nb, b_cache = freed(b_cache) - -- report_visualize("cache: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",nf,ng,np,nk,nw,nb) + -- report_visualize("cache cleanup: %s fontkerns, %s skips, %s penalties, %s kerns, %s whatsits, %s boxes",nf,ng,np,nk,nw,nb) end local function handler(head) @@ -931,9 +931,11 @@ function commands.markfonts(n) visualizers.markfonts(n) end +luatex.registerstopactions(cleanup) + statistics.register("visualization time",function() if enabled then - cleanup() -- in case we don't don't do it each time + -- cleanup() -- in case we don't don't do it each time return format("%s seconds",statistics.elapsedtime(visualizers)) end end) diff --git a/tex/context/base/type-imp-ebgaramond.mkiv b/tex/context/base/type-imp-ebgaramond.mkiv new file mode 100644 index 000000000..838654d49 --- /dev/null +++ b/tex/context/base/type-imp-ebgaramond.mkiv @@ -0,0 +1,45 @@ +%D \module +%D [ file=type-imp-ebgaramond, +%D version=2013.06.22, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=EB Garamond, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. + +\definefontfeature + [eb-garamond-normal] + [default] + [mode=node,ccmp=yes,calt=yes, + liga=yes,dlig=yes,hlig=yes, + kern=yes,mark=yes,mkmk=yes, + onum=yes,pnum=yes,salt=yes, + script=latn] + +\definefontfeature + [eb-garamond-smallcaps] + [eb-garamond-normal] + [smcp=yes,c2sc=yes] + +\starttypescriptcollection[ebgaramond] + + \starttypescript [serif] [ebgaramond] + \loadfontgoodies[ebgaramond] + \setups[font:fallback:serif] + \definefontsynonym [Serif] [file:ebgaramond-regular] [features=eb-garamond-normal] + \definefontsynonym [SerifItalic] [file:ebgaramond-italic] [features=eb-garamond-normal] + \definefontsynonym [SerifBold] [file:ebgaramond-bold] [features=eb-garamond-normal] + \definefontsynonym [SerifCaps] [Serif] [features=eb-garamond-smallcaps] + \stoptypescript + + \starttypescript[ebgaramond] + \definetypeface [ebgaramond] [rm] [serif] [ebgaramond] [default] [designsize=auto] + \definetypeface [ebgaramond] [tt] [mono] [dejavu] [default] + \definetypeface [ebgaramond] [mm] [math] [bonum] [default] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/base/type-imp-latinmodern.mkiv b/tex/context/base/type-imp-latinmodern.mkiv index afe2c6417..fe4b669bd 100644 --- a/tex/context/base/type-imp-latinmodern.mkiv +++ b/tex/context/base/type-imp-latinmodern.mkiv @@ -71,11 +71,14 @@ \starttypescript [\s!math] [modern,latin-modern-designsize,latin-modern] [\s!name] \loadfontgoodies[lm] - \loadfontgoodies[lm-math] \definefontsynonym [\s!MathRoman] [LMMathRoman-Regular] \definefontsynonym [\s!MathRomanBold] [LMMathRoman-Bold] \stoptypescript + \starttypescript [\s!math] [latin-modern-designsize] [\s!name] + \loadfontgoodies[lm-math] + \stoptypescript + \starttypescript [\s!serif] [modern-variable,latin-modern-variable-designsize,latin-modern-variable] [\s!name] \loadfontgoodies[lm] \definefontsynonym [\s!Serif] [LMTypewriterVarWd-Regular] [\s!features=\s!default] diff --git a/tex/context/base/type-ini.mkvi b/tex/context/base/type-ini.mkvi index a4d576d80..faa9c667c 100644 --- a/tex/context/base/type-ini.mkvi +++ b/tex/context/base/type-ini.mkvi @@ -299,7 +299,7 @@ \let\typescripttwo \m_font_typescripts_two \let\typescriptthree\m_font_typescripts_three \let\m_font_typescripts_match\empty - \doifnextoptionalelse\font_typescripts_start_process_one\font_typescripts_start_process_all} + \doifnextoptionalcselse\font_typescripts_start_process_one\font_typescripts_start_process_all} \def\font_typescripts_start_process_all % could be a \let {\ifconditional\c_font_typescripts_first_pass @@ -333,10 +333,10 @@ {\font_typescripts_check\m_font_typescripts_three\typescriptthree\font_typescripts_start_process_again_three} \def\font_typescripts_start_process_again_one - {\doifnextoptionalelse\font_typescripts_start_process_two\font_typescripts_start_process_yes} + {\doifnextoptionalcselse\font_typescripts_start_process_two\font_typescripts_start_process_yes} \def\font_typescripts_start_process_again_two - {\doifnextoptionalelse\font_typescripts_start_process_three\font_typescripts_start_process_yes} + {\doifnextoptionalcselse\font_typescripts_start_process_three\font_typescripts_start_process_yes} \let\font_typescripts_start_process_again_three\font_typescripts_start_process_yes @@ -389,9 +389,9 @@ \unexpanded\def\forgetmapfiles {\ctxlua{fonts.mappings.reset()}} -\prependtoks - \loadmapfile[mkiv-base.map]% can't we preload this one? -\to \everystarttext +% \prependtoks +% \loadmapfile[mkiv-base.map]% can't we preload this one? +% \to \everystarttext %D A handy shortcut: diff --git a/tex/context/base/typo-brk.lua b/tex/context/base/typo-brk.lua index be11da9c3..14151af43 100644 --- a/tex/context/base/typo-brk.lua +++ b/tex/context/base/typo-brk.lua @@ -32,9 +32,8 @@ local getchar = nuts.getchar local getfont = nuts.getfont local getid = nuts.getid local getfield = nuts.getfield -local getattr = nuts.getattr - local setfield = nuts.setfield +local getattr = nuts.getattr local setattr = nuts.setattr local copy_node = nuts.copy diff --git a/tex/context/base/typo-cln.lua b/tex/context/base/typo-cln.lua index b7e337662..8b1ac7876 100644 --- a/tex/context/base/typo-cln.lua +++ b/tex/context/base/typo-cln.lua @@ -34,6 +34,7 @@ local tonut = nuts.tonut local setfield = nuts.setfield local getchar = nuts.getchar local getattr = nuts.getattr +local setattr = nuts.setattr local traverse_id = nuts.traverse_id diff --git a/tex/context/base/typo-dha.lua b/tex/context/base/typo-dha.lua index 15e345ff8..3410c2dfc 100644 --- a/tex/context/base/typo-dha.lua +++ b/tex/context/base/typo-dha.lua @@ -65,13 +65,14 @@ local getfield = nuts.getfield local setfield = nuts.setfield local getattr = nuts.getattr local setattr = nuts.setattr +local getprop = nuts.getprop +local setprop = nuts.setprop local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local remove_node = nuts.remove local end_of_math = nuts.end_of_math - local nodepool = nuts.pool local nodecodes = nodes.nodecodes @@ -240,7 +241,7 @@ local function process(start) end elseif lro or override < 0 then if direction == "r" or direction == "al" then - setattr(current,a_state,s_isol) + setprop(current,a_state,s_isol) direction = "l" reversed = true end diff --git a/tex/context/base/typo-dir.lua b/tex/context/base/typo-dir.lua index fbca0f024..e7d3c686c 100644 --- a/tex/context/base/typo-dir.lua +++ b/tex/context/base/typo-dir.lua @@ -33,99 +33,41 @@ local formatters = string.formatters local nodes, node = nodes, node -local trace_textdirections = false trackers.register("typesetters.directions.text", function(v) trace_textdirections = v end) -local trace_mathdirections = false trackers.register("typesetters.directions.math", function(v) trace_mathdirections = v end) -local trace_directions = false trackers.register("typesetters.directions", function(v) trace_textdirections = v trace_mathdirections = v end) +local trace_textdirections = false trackers.register("typesetters.directions.text", function(v) trace_textdirections = v end) +local trace_mathdirections = false trackers.register("typesetters.directions.math", function(v) trace_mathdirections = v end) +local trace_directions = false trackers.register("typesetters.directions", function(v) trace_textdirections = v trace_mathdirections = v end) local report_textdirections = logs.reporter("typesetting","text directions") local report_mathdirections = logs.reporter("typesetting","math directions") -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode -local nutstring = nuts.tostring - -local getnext = nuts.getnext -local getprev = nuts.getprev -local getfont = nuts.getfont -local getchar = nuts.getchar -local getid = nuts.getid -local getsubtype = nuts.getsubtype -local getlist = nuts.getlist -local getfield = nuts.getfield -local setfield = nuts.setfield -local getattr = nuts.getattr -local setattr = nuts.setattr - -local hasbit = number.hasbit - -local traverse_id = nuts.traverse_id -local insert_node_before = nuts.insert_before -local insert_node_after = nuts.insert_after -local remove_node = nuts.remove -local end_of_math = nuts.end_of_math - -local texsetattribute = tex.setattribute -local texsetcount = tex.setcount -local unsetvalue = attributes.unsetvalue - -local nodecodes = nodes.nodecodes -local whatcodes = nodes.whatcodes -local mathcodes = nodes.mathcodes - -local tasks = nodes.tasks -local tracers = nodes.tracers -local setcolor = tracers.colors.set -local resetcolor = tracers.colors.reset - -local glyph_code = nodecodes.glyph -local whatsit_code = nodecodes.whatsit -local math_code = nodecodes.math -local penalty_code = nodecodes.penalty -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist - -local localpar_code = whatcodes.localpar -local dir_code = whatcodes.dir - -local nodepool = nuts.pool - -local new_textdir = nodepool.textdir - -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local fontchar = fonthashes.characters - -local chardirections = characters.directions -local charmirrors = characters.mirrors -local charclasses = characters.textclasses - -local directions = typesetters.directions or { } -typesetters.directions = directions - -local a_state = attributes.private('state') -local a_directions = attributes.private('directions') -local a_mathbidi = attributes.private('mathbidi') - -local strip = false - -local s_isol = fonts.analyzers.states.isol - -local variables = interfaces.variables -local v_global = variables["global"] -local v_local = variables["local"] -local v_on = variables.on -local v_yes = variables.yes - -local m_enabled = 2^6 -- 64 -local m_global = 2^7 -local m_fences = 2^8 - -local handlers = { } -local methods = { } -local lastmethod = 0 +local hasbit = number.hasbit + +local texsetattribute = tex.setattribute +local unsetvalue = attributes.unsetvalue + +local tasks = nodes.tasks +local tracers = nodes.tracers +local setcolor = tracers.colors.set +local resetcolor = tracers.colors.reset + +local directions = typesetters.directions or { } +typesetters.directions = directions + +local a_directions = attributes.private('directions') + +local variables = interfaces.variables +local v_global = variables["global"] +local v_local = variables["local"] +local v_on = variables.on +local v_yes = variables.yes + +local m_enabled = 2^6 -- 64 +local m_global = 2^7 +local m_fences = 2^8 + +local handlers = { } +local methods = { } +local lastmethod = 0 local function installhandler(name,handler) local method = methods[name] diff --git a/tex/context/base/typo-drp.lua b/tex/context/base/typo-drp.lua index 3a87d94b3..9151100b6 100644 --- a/tex/context/base/typo-drp.lua +++ b/tex/context/base/typo-drp.lua @@ -32,9 +32,8 @@ local getchar = nuts.getchar local getid = nuts.getid local getsubtype = nuts.getsubtype local getfield = nuts.getfield -local getattr = nuts.getattr - local setfield = nuts.setfield +local getattr = nuts.getattr local setattr = nuts.setattr local hpack_nodes = nuts.hpack diff --git a/tex/context/base/typo-dua.lua b/tex/context/base/typo-dua.lua index 91a27a30e..7dfd7e81c 100644 --- a/tex/context/base/typo-dua.lua +++ b/tex/context/base/typo-dua.lua @@ -106,7 +106,7 @@ local maximum_stack = 60 -- probably spec but not needed local directions = typesetters.directions local setcolor = directions.setcolor -local a_directions = attributes.private('directions') +----- a_directions = attributes.private('directions') local remove_controls = true directives.register("typesetters.directions.one.removecontrols",function(v) remove_controls = v end) diff --git a/tex/context/base/typo-dub.lua b/tex/context/base/typo-dub.lua index 4dc0f21fb..3d48f657e 100644 --- a/tex/context/base/typo-dub.lua +++ b/tex/context/base/typo-dub.lua @@ -65,6 +65,7 @@ local getid = nuts.getid local getsubtype = nuts.getsubtype local getlist = nuts.getlist local getattr = nuts.getattr +local setattr = nuts.setattr local getfield = nuts.getfield local setfield = nuts.setfield @@ -97,11 +98,11 @@ local getfences = directions.getfences local a_directions = attributes.private('directions') local a_textbidi = attributes.private('textbidi') -local a_state = attributes.private('state') +----- a_state = attributes.private('state') -local s_isol = fonts.analyzers.states.isol +----- s_isol = fonts.analyzers.states.isol --- current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo +----- current[a_state] = s_isol -- maybe better have a special bidi attr value -> override (9) -> todo local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end) ----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end) diff --git a/tex/context/base/typo-fln.lua b/tex/context/base/typo-fln.lua index 7ce41cd81..884a4c829 100644 --- a/tex/context/base/typo-fln.lua +++ b/tex/context/base/typo-fln.lua @@ -30,12 +30,11 @@ local tonode = nuts.tonode local getnext = nuts.getnext local getid = nuts.getid local getfield = nuts.getfield +local setfield = nuts.setfield local getlist = nuts.getlist local getattr = nuts.getattr -local getbox = nuts.getbox - -local setfield = nuts.setfield local setattr = nuts.setattr +local getbox = nuts.getbox local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph diff --git a/tex/context/base/typo-fln.mkiv b/tex/context/base/typo-fln.mkiv index d8651b459..c092fc922 100644 --- a/tex/context/base/typo-fln.mkiv +++ b/tex/context/base/typo-fln.mkiv @@ -79,7 +79,7 @@ \begingroup \edef\currentfirstline{#1}% \usefirstlinestyleandcolor\c!style\c!color - \ctxlua{commands.setfirstline { + \ctxcommand{setfirstline { alternative = "\firstlineparameter\c!alternative", ma = \the\attribute\colormodelattribute, ca = \the\attribute\colorattribute, diff --git a/tex/context/base/typo-itc.lua b/tex/context/base/typo-itc.lua index db94c5c54..7373c0321 100644 --- a/tex/context/base/typo-itc.lua +++ b/tex/context/base/typo-itc.lua @@ -37,6 +37,7 @@ local getid = nuts.getid local getfont = nuts.getfont local getchar = nuts.getchar local getattr = nuts.getattr +local setattr = nuts.setattr local insert_node_after = nuts.insert_after local delete_node = nuts.delete diff --git a/tex/context/base/typo-krn.mkiv b/tex/context/base/typo-krn.mkiv index 3522c02fc..92689f07b 100644 --- a/tex/context/base/typo-krn.mkiv +++ b/tex/context/base/typo-krn.mkiv @@ -70,7 +70,7 @@ % \definecharacterkerning [\v!letterspacing ] [\v!kerncharacters] [\c!features=letterspacing] % % \unexpanded\def\kerncharacters -% {\doifnextoptionalelse\typo_kerning_apply_yes\typo_kerning_apply_nop} +% {\doifnextoptionalcselse\typo_kerning_apply_yes\typo_kerning_apply_nop} % % \def\typo_kerning_apply_yes[#1]% % {\groupedcommand{\typo_kerning_apply_yes_indeed{#1}}\donothing} diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua index 4bfc107ad..4ea6b1e1d 100644 --- a/tex/context/base/typo-mar.lua +++ b/tex/context/base/typo-mar.lua @@ -76,6 +76,7 @@ if not modules then modules = { } end modules ['typo-mar'] = { local format, validstring = string.format, string.valid local insert, remove = table.insert, table.remove local setmetatable, next = setmetatable, next +local formatters = string.formatters local attributes, nodes, node, variables = attributes, nodes, node, variables @@ -170,6 +171,8 @@ local new_stretch = nodepool.stretch local new_usernumber = nodepool.usernumber local new_latelua = nodepool.latelua +local lateluafunction = nodepool.lateluafunction + local texgetcount = tex.getcount local texgetdimen = tex.getdimen local texget = tex.get @@ -179,13 +182,15 @@ local points = number.points local isleftpage = layouts.status.isleftpage local registertogether = builders.paragraphs.registertogether -- tonode -local jobpositions = job.positions -local getposition = jobpositions.position - local a_margindata = attributes.private("margindata") local inline_mark = nodepool.userids["margins.inline"] +local jobpositions = job.positions +local getposition = jobpositions.get +local setposition = jobpositions.set +local getreserved = jobpositions.getreserved + local margins = { } typesetters.margins = margins @@ -368,6 +373,16 @@ end local status, nofstatus = { }, 0 +local f_anchor = formatters["_plib_.set('md:h',%i,{x=true,c=true})"] +local function setanchor(h_anchor) + return new_latelua(f_anchor(h_anchor)) +end + +-- local t_anchor = { x = true, c = true } +-- local function setanchor(h_anchor) +-- return lateluafunction(function() setposition("md:h",h_anchor,t_anchor) end) +-- end + local function realign(current,candidate) local location = candidate.location local margin = candidate.margin @@ -436,10 +451,10 @@ local function realign(current,candidate) if inline or anchor ~= v_text or candidate.psubtype == alignment_code then -- the alignment_code check catches margintexts ste before a tabulate h_anchors = h_anchors + 1 - anchornode = new_latelua(format("_plib_.set('md:h',%i,{x=true,c=true})",h_anchors)) - local blob = jobpositions.get('md:h', h_anchors) + anchornode = setanchor(h_anchors) + local blob = getposition('md:h',h_anchors) if blob then - local reference = jobpositions.getreserved(anchor,blob.c) + local reference = getreserved(anchor,blob.c) if reference then if location == v_left then move_x = (reference.x or 0) - (blob.x or 0) @@ -494,25 +509,36 @@ end -- resetstacked() -function margins.ha(tag) -- maybe l/r keys ipv left/right keys +local function ha(tag) -- maybe l/r keys ipv left/right keys local p = cache[tag] p.p = true p.y = true - jobpositions.set('md:v',tag,p) + setposition('md:v',tag,p) cache[tag] = nil end -local function markovershoot(current) +margins.ha = ha + +local f_anchor = formatters["typesetters.margins.ha(%s)"] +local function setanchor(v_anchor) + return new_latelua(f_anchor(v_anchor)) +end + +-- local function setanchor(v_anchor) -- freezes the global here +-- return lateluafunction(function() ha(v_anchor) end) +-- end + +local function markovershoot(current) -- todo: alleen als offset > line v_anchors = v_anchors + 1 cache[v_anchors] = stacked - local anchor = new_latelua(format("typesetters.margins.ha(%s)",v_anchors)) -- todo: alleen als offset > line + local anchor = setanchor(v_anchors) local list = hpack_nodes(linked_nodes(anchor,getlist(current))) setfield(current,"list",list) end local function getovershoot(location) - local p = jobpositions.get("md:v",v_anchors) - local c = jobpositions.get("md:v",v_anchors+1) + local p = getposition("md:v",v_anchors) + local c = getposition("md:v",v_anchors+1) if p and c and p.p and p.p == c.p then local distance = p.y - c.y local offset = p[location] or 0 @@ -901,3 +927,5 @@ statistics.register("margin data", function() return nil end end) + +commands.savemargindata = margins.save diff --git a/tex/context/base/typo-mar.mkiv b/tex/context/base/typo-mar.mkiv index 595cf3756..2b89f5777 100644 --- a/tex/context/base/typo-mar.mkiv +++ b/tex/context/base/typo-mar.mkiv @@ -258,11 +258,13 @@ \fi \ifdone \anch_positions_initialize % we use positions at the lua end - \ctxlua{typesetters.margins.save{ + \ctxcommand{savemargindata{ location = "\margindataparameter\c!location", method = "\margindataparameter\c!method", category = "\margindataparameter\c!category", name = "\margindataparameter\c!name", + scope = "\margindataparameter\c!scope", + number = \number\nextbox, margin = "\margindataparameter\c!margin", % local normal margin edge distance = \number\dimexpr\margindataparameter\c!distance, hoffset = \number\dimexpr\margindataparameter\c!hoffset, @@ -286,14 +288,12 @@ % \ifzeropt\leftskip \else % rightskip = \number\rightskip, % \fi - scope = "\margindataparameter\c!scope", align = "\margindataparameter\c!align", line = \number\margindataparameter\c!line, stack = "\margindataparameter\c!stack", - number = \number\nextbox, }}% \else - \ctxlua{typesetters.margins.save{ + \ctxcommand{savemargindata{ location = "\margindataparameter\c!location", method = "\margindataparameter\c!method", category = "\margindataparameter\c!category", diff --git a/tex/context/base/typo-prc.lua b/tex/context/base/typo-prc.lua index a6c27ede6..959cabbb8 100644 --- a/tex/context/base/typo-prc.lua +++ b/tex/context/base/typo-prc.lua @@ -14,13 +14,16 @@ local lpegmatch, patterns, P, C, Cs = lpeg.match, lpeg.patterns, lpeg.P, lpeg.C, -- processors: syntax: processor->data ... not ok yet -typesetters.processors = typesetters.processors or { } -local processors = typesetters.processors +typesetters.processors = typesetters.processors or { } +local processors = typesetters.processors local trace_processors = false local report_processors = logs.reporter("processors") local registered = { } +context_applyprocessor = context.applyprocessor +context_firstofoneargument = context.firstofoneargument + trackers.register("typesetters.processors", function(v) trace_processors = v end) function processors.register(p) @@ -55,7 +58,7 @@ function processors.apply(p,s) if trace_processors then report_processors("applying %s processor %a, argument: %s","known",p,s) end - context.applyprocessor(p,s) + context_applyprocessor(p,s) elseif s then if trace_processors then report_processors("applying %s processor %a, argument: %s","unknown",p,s) @@ -78,21 +81,21 @@ function processors.startapply(p,s) if trace_processors then report_processors("start applying %s processor %a","known",p) end - context.applyprocessor(p) + context_applyprocessor(p) context("{") return s elseif p then if trace_processors then report_processors("start applying %s processor %a","unknown",p) end - context.firstofoneargument() + context_firstofoneargument() context("{") return s else if trace_processors then report_processors("start applying %s processor","ignored") end - context.firstofoneargument() + context_firstofoneargument() context("{") return str end diff --git a/tex/context/base/typo-rep.lua b/tex/context/base/typo-rep.lua index 95b801e2e..15e3f9746 100644 --- a/tex/context/base/typo-rep.lua +++ b/tex/context/base/typo-rep.lua @@ -27,8 +27,8 @@ local tonode = nuts.tonode local getnext = nuts.getnext local getchar = nuts.getchar local getid = nuts.getid -local getattr = nuts.getid +local getattr = nuts.getattr local setattr = nuts.setattr local delete_node = nuts.delete diff --git a/tex/context/base/typo-spa.lua b/tex/context/base/typo-spa.lua index 5cf9ab837..eb84eb7d7 100644 --- a/tex/context/base/typo-spa.lua +++ b/tex/context/base/typo-spa.lua @@ -36,7 +36,6 @@ local getchar = nuts.getchar local getid = nuts.getid local getfont = nuts.getfont local getattr = nuts.getattr - local setattr = nuts.setattr local insert_node_before = nuts.insert_before diff --git a/tex/context/base/typo-tal.lua b/tex/context/base/typo-tal.lua index debcedfd3..3a2d80e51 100644 --- a/tex/context/base/typo-tal.lua +++ b/tex/context/base/typo-tal.lua @@ -29,11 +29,11 @@ local getprev = nuts.getprev local getid = nuts.getid local getfont = nuts.getfont local getchar = nuts.getchar -local getattr = nuts.getattr local getfield = nuts.getfield +local setfield = nuts.setfield +local getattr = nuts.getattr local setattr = nuts.setattr -local setfield = nuts.setfield local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after diff --git a/tex/context/base/typo-txt.mkvi b/tex/context/base/typo-txt.mkvi index 57f4e5f42..fa79a4f6b 100644 --- a/tex/context/base/typo-txt.mkvi +++ b/tex/context/base/typo-txt.mkvi @@ -17,7 +17,7 @@ \unprotect -\registerctxluafile{typo-txt}{1.001} +% registerctxluafile{typo-txt}{1.001} %D \macros %D {normalizefontheight,normalizefontwidth,normalizedfontsize} diff --git a/tex/context/base/util-env.lua b/tex/context/base/util-env.lua index 0a708ea43..e96a464b0 100644 --- a/tex/context/base/util-env.lua +++ b/tex/context/base/util-env.lua @@ -197,7 +197,7 @@ function environment.reconstructcommandline(arg,noquote) a = resolvers.resolve(a) a = unquoted(a) a = gsub(a,'"','\\"') -- tricky - if find(a," ") then + if find(a," ",1,true) then result[#result+1] = quoted(a) else result[#result+1] = a diff --git a/tex/context/base/util-prs.lua b/tex/context/base/util-prs.lua index e5b35a727..2cede919b 100644 --- a/tex/context/base/util-prs.lua +++ b/tex/context/base/util-prs.lua @@ -179,12 +179,12 @@ function parsers.settings_to_array(str,strict) elseif not str or str == "" then return { } elseif strict then - if find(str,"{") then + if find(str,"{",1,true) then return lpegmatch(pattern,str) else return { str } end - elseif find(str,",") then + elseif find(str,",",1,true) then return lpegmatch(pattern,str) else return { str } diff --git a/tex/context/base/util-str.lua b/tex/context/base/util-str.lua index 4ecaed7d3..52c48badd 100644 --- a/tex/context/base/util-str.lua +++ b/tex/context/base/util-str.lua @@ -47,10 +47,12 @@ if not number then number = { } end -- temp hack for luatex-fonts local stripper = patterns.stripzeros local function points(n) + n = tonumber(n) return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) end local function basepoints(n) + n = tonumber(n) return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) end @@ -152,17 +154,105 @@ end -- print(strings.tabtospace(t[k])) -- end -function strings.striplong(str) -- strips all leading spaces - str = gsub(str,"^%s*","") - str = gsub(str,"[\n\r]+ *","\n") - return str +-- todo: lpeg + +-- function strings.striplong(str) -- strips all leading spaces +-- str = gsub(str,"^%s*","") +-- str = gsub(str,"[\n\r]+ *","\n") +-- return str +-- end + +local newline = patterns.newline +local endofstring = patterns.endofstring +local whitespace = patterns.whitespace +local spacer = patterns.spacer + +local space = spacer^0 +local nospace = space/"" +local endofline = nospace * newline + +local stripend = (whitespace^1 * endofstring)/"" + +local normalline = (nospace * ((1-space*(newline+endofstring))^1) * nospace) + +local stripempty = endofline^1/"" +local normalempty = endofline^1 +local singleempty = endofline * (endofline^0/"") +local doubleempty = endofline * endofline^-1 * (endofline^0/"") + +local stripstart = stripempty^0 + +local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 ) +local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 ) +local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 ) +local p_retain_normal = Cs ( ( normalline + normalempty )^0 ) +local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 ) +local p_retain_noempty = Cs ( ( normalline + singleempty )^0 ) + +-- function striplines(str,prune,collapse,noempty) +-- if prune then +-- if noempty then +-- return lpegmatch(p_prune_noempty,str) or str +-- elseif collapse then +-- return lpegmatch(p_prune_collapse,str) or str +-- else +-- return lpegmatch(p_prune_normal,str) or str +-- end +-- else +-- if noempty then +-- return lpegmatch(p_retain_noempty,str) or str +-- elseif collapse then +-- return lpegmatch(p_retain_collapse,str) or str +-- else +-- return lpegmatch(p_retain_normal,str) or str +-- end +-- end +-- end + +local striplinepatterns = { + ["prune"] = p_prune_normal, + ["prune and collapse"] = p_prune_collapse, -- default + ["prune and no empty"] = p_prune_noempty, + ["retain"] = p_retain_normal, + ["retain and collapse"] = p_retain_collapse, + ["retain and no empty"] = p_retain_noempty, +} + +strings.striplinepatterns = striplinepatterns + +function strings.striplines(str,how) + return str and lpegmatch(how and striplinepatterns[how] or p_prune_collapse,str) or str end --- local template = string.striplong([[ +strings.striplong = strings.striplines -- for old times sake + +-- local str = table.concat( { +-- " ", +-- " aap", +-- " noot mies", +-- " ", +-- " ", +-- " zus wim jet", +-- "zus wim jet", +-- " zus wim jet", +-- " ", +-- }, "\n") + +-- local str = table.concat( { +-- " aaaa", +-- " bb", +-- " cccccc", +-- }, "\n") + +-- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do +-- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k)) +-- end + +-- inspect(strings.striplong([[ -- aaaa -- bb -- cccccc --- ]]) +-- ]])) function strings.nice(str) str = gsub(str,"[:%-+_]+"," ") -- maybe more @@ -418,7 +508,7 @@ local format_i = function(f) if f and f ~= "" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("format('%%i',a%s)",n) -- why not just tostring() end end @@ -434,6 +524,11 @@ local format_f = function(f) return format("format('%%%sf',a%s)",f,n) end +local format_F = function(f) + n = n + 1 + return format("((a%s == 0 and '0') or (a%s == 1 and '1') or format('%%%sf',a%s))",n,n,f,n) +end + local format_g = function(f) n = n + 1 return format("format('%%%sg',a%s)",f,n) @@ -707,7 +802,7 @@ local builder = Cs { "start", V("!") -- new + V("s") + V("q") + V("i") + V("d") - + V("f") + V("g") + V("G") + V("e") + V("E") + + V("f") + V("F") + V("g") + V("G") + V("e") + V("E") + V("x") + V("X") + V("o") -- + V("c") @@ -742,6 +837,7 @@ local builder = Cs { "start", ["i"] = (prefix_any * P("i")) / format_i, -- %i => regular %i (integer) ["d"] = (prefix_any * P("d")) / format_d, -- %d => regular %d (integer) ["f"] = (prefix_any * P("f")) / format_f, -- %f => regular %f (float) + ["F"] = (prefix_any * P("F")) / format_F, -- %F => regular %f (float) but 0/1 check ["g"] = (prefix_any * P("g")) / format_g, -- %g => regular %g (float) ["G"] = (prefix_any * P("G")) / format_G, -- %G => regular %G (float) ["e"] = (prefix_any * P("e")) / format_e, -- %e => regular %e (float) @@ -816,7 +912,8 @@ local function make(t,str) f = loadstripped(p)() else n = 0 - p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n + -- p = lpegmatch(builder,str,1,"..",t._extensions_) -- after this we know n + p = lpegmatch(builder,str,1,t._connector_,t._extensions_) -- after this we know n if n > 0 then p = format(template,preamble,t._preamble_,arguments[n],p) -- print("builder 2 >",p) @@ -875,22 +972,24 @@ strings.formatters = { } -- table (metatable) in which case we could better keep a count and -- clear that table when a threshold is reached +-- _connector_ is an experiment + if _LUAVERSION < 5.2 then - function strings.formatters.new() - local t = { _extensions_ = { }, _preamble_ = preamble, _environment_ = { }, _type_ = "formatter" } + function strings.formatters.new(noconcat) + local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = preamble, _environment_ = { } } setmetatable(t, { __index = make, __call = use }) return t end else - function strings.formatters.new() + function strings.formatters.new(noconcat) local e = { } -- better make a copy as we can overload for k, v in next, environment do e[k] = v end - local t = { _extensions_ = { }, _preamble_ = "", _environment_ = e, _type_ = "formatter" } + local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = "", _environment_ = e } setmetatable(t, { __index = make, __call = use }) return t end diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua index d235520c4..f9e9b318d 100644 --- a/tex/context/base/util-tab.lua +++ b/tex/context/base/util-tab.lua @@ -21,27 +21,29 @@ local utftoeight = utf.toeight local splitter = lpeg.tsplitat(".") -function tables.definetable(target,nofirst,nolast) -- defines undefined tables - local composed, shortcut, t = nil, nil, { } +function utilities.tables.definetable(target,nofirst,nolast) -- defines undefined tables + local composed, t = nil, { } local snippets = lpegmatch(splitter,target) for i=1,#snippets - (nolast and 1 or 0) do local name = snippets[i] if composed then - composed = shortcut .. "." .. name - shortcut = shortcut .. "_" .. name - t[#t+1] = formatters["local %s = %s if not %s then %s = { } %s = %s end"](shortcut,composed,shortcut,shortcut,composed,shortcut) + composed = composed .. "." .. name + t[#t+1] = formatters["if not %s then %s = { } end"](composed,composed) else composed = name - shortcut = name if not nofirst then t[#t+1] = formatters["%s = %s or { }"](composed,composed) end end end - if nolast then - composed = shortcut .. "." .. snippets[#snippets] + if composed then + if nolast then + composed = composed .. "." .. snippets[#snippets] + end + return concat(t,"\n"), composed -- could be shortcut + else + return "", target end - return concat(t,"\n"), composed end -- local t = tables.definedtable("a","b","c","d") @@ -73,7 +75,7 @@ end function tables.migratetable(target,v,root) local t = root or _G - local names = string.split(target,".") + local names = lpegmatch(splitter,target) for i=1,#names-1 do local name = names[i] t[name] = t[name] or { } @@ -493,7 +495,8 @@ end -- The next version is somewhat faster, although in practice one will seldom -- serialize a lot using this one. Often the above variants are more efficient. --- If we would really need this a lot, we could hash q keys. +-- If we would really need this a lot, we could hash q keys, or just not used +-- indented code. -- char-def.lua : 0.53 -> 0.38 -- husayni.tma : 0.28 -> 0.19 diff --git a/tex/context/interface/cont-nl.xml b/tex/context/interface/cont-nl.xml index 685033f81..4bfad3798 100644 --- a/tex/context/interface/cont-nl.xml +++ b/tex/context/interface/cont-nl.xml @@ -6525,7 +6525,7 @@ - + @@ -8996,7 +8996,7 @@ - + diff --git a/tex/context/interface/keys-nl.xml b/tex/context/interface/keys-nl.xml index 21536214a..c87088a09 100644 --- a/tex/context/interface/keys-nl.xml +++ b/tex/context/interface/keys-nl.xml @@ -950,7 +950,7 @@ - + @@ -1100,7 +1100,7 @@ - + diff --git a/tex/context/sample/cervantes-es.tex b/tex/context/sample/cervantes-es.tex new file mode 100644 index 000000000..153797023 --- /dev/null +++ b/tex/context/sample/cervantes-es.tex @@ -0,0 +1,6 @@ +En un lugar de la Mancha, de cuyo nombre no quiero acordar-me, no ha +mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga +antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que +carnero, salpicón las más noches, duelos y quebrantos los sábados, +lantejas los viernes, algún palomino de añadidura los domingos, +consumían las tres partes de su hacienda. diff --git a/tex/context/sample/quevedo-es.tex b/tex/context/sample/quevedo-es.tex new file mode 100644 index 000000000..166b0328f --- /dev/null +++ b/tex/context/sample/quevedo-es.tex @@ -0,0 +1,19 @@ +\startlines +Un soneto me manda hacer Violante +que en mi vida me he visto en tanto aprieto; +catorce versos dicen que es soneto; +burla burlando van los tres delante. + +Yo pensé que no hallara consonante, +y estoy a la mitad de otro cuarteto; +mas si me veo en el primer terceto, +no hay cosa en los cuartetos que me espante. + +Por el primer terceto voy entrando, +y parece que entré con pie derecho, +pues fin con este verso le voy dando. + +Ya estoy en el segundo, y aun sospecho +que voy los trece versos acabando; +contad si son catorce, y está hecho. +\stoplines diff --git a/tex/generic/context/luatex/luatex-fonts-inj.lua b/tex/generic/context/luatex/luatex-fonts-inj.lua index ae48150a6..5e6c07070 100644 --- a/tex/generic/context/luatex/luatex-fonts-inj.lua +++ b/tex/generic/context/luatex/luatex-fonts-inj.lua @@ -11,8 +11,6 @@ if not modules then modules = { } end modules ['node-inj'] = { -- test fonts. Btw, future versions of luatex will have extended glyph properties -- that can be of help. Some optimizations can go away when we have faster machines. --- todo: make a special one for context - local next = next local utfchar = utf.char @@ -108,9 +106,9 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) end end -function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- ba=baseanchor, ma=markanchor - local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) -- the index argument is no longer used but when this - local bound = base[a_markbase] -- fails again we should pass it +function injections.setmark(start,base,factor,rlmode,ba,ma) -- ba=baseanchor, ma=markanchor + local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) + local bound = base[a_markbase] local index = 1 if bound then local mb = marks[bound] @@ -125,13 +123,12 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) -- report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) end end --- index = index or 1 index = index or 1 bound = #marks + 1 base[a_markbase] = bound start[a_markmark] = bound start[a_markdone] = index - marks[bound] = { [index] = { dx, dy, rlmode, baseismark } } + marks[bound] = { [index] = { dx, dy, rlmode } } return dx, dy, bound end diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 3f408b96f..655aedf5e 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 : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 02/14/14 17:07:59 +-- merge date : 03/22/14 15:31:38 do -- begin closure to overcome local limits and interference @@ -901,6 +901,36 @@ local function sortedkeys(tab) return {} end end +local function sortedhashonly(tab) + if tab then + local srt,s={},0 + for key,_ in next,tab do + if type(key)=="string" then + s=s+1 + srt[s]=key + end + end + sort(srt) + return srt + else + return {} + end +end +local function sortedindexonly(tab) + if tab then + local srt,s={},0 + for key,_ in next,tab do + if type(key)=="number" then + s=s+1 + srt[s]=key + end + end + sort(srt) + return srt + else + return {} + end +end local function sortedhashkeys(tab,cmp) if tab then local srt,s={},0 @@ -926,6 +956,8 @@ function table.allkeys(t) return sortedkeys(keys) end table.sortedkeys=sortedkeys +table.sortedhashonly=sortedhashonly +table.sortedindexonly=sortedindexonly table.sortedhashkeys=sortedhashkeys local function nothing() end local function sortedhash(t,cmp) @@ -1723,7 +1755,7 @@ local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format local concat=table.concat local floor=math.floor local type=type -if string.find(os.getenv("PATH"),";") then +if string.find(os.getenv("PATH"),";",1,true) then io.fileseparator,io.pathseparator="\\",";" else io.fileseparator,io.pathseparator="/",":" @@ -2542,9 +2574,11 @@ end if not number then number={} end local stripper=patterns.stripzeros local function points(n) + n=tonumber(n) return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) end local function basepoints(n) + n=tonumber(n) return (not n or n==0) and "0bp" or lpegmatch(stripper,format("%.5fbp",n*(7200/7227)/65536)) end number.points=points @@ -2607,11 +2641,39 @@ local pattern=Carg(1)/function(t) function strings.tabtospace(str,tab) return lpegmatch(pattern,str,1,tab or 7) end -function strings.striplong(str) - str=gsub(str,"^%s*","") - str=gsub(str,"[\n\r]+ *","\n") - return str +local newline=patterns.newline +local endofstring=patterns.endofstring +local whitespace=patterns.whitespace +local spacer=patterns.spacer +local space=spacer^0 +local nospace=space/"" +local endofline=nospace*newline +local stripend=(whitespace^1*endofstring)/"" +local normalline=(nospace*((1-space*(newline+endofstring))^1)*nospace) +local stripempty=endofline^1/"" +local normalempty=endofline^1 +local singleempty=endofline*(endofline^0/"") +local doubleempty=endofline*endofline^-1*(endofline^0/"") +local stripstart=stripempty^0 +local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 ) +local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 ) +local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 ) +local p_retain_normal=Cs ((normalline+normalempty )^0 ) +local p_retain_collapse=Cs ((normalline+doubleempty )^0 ) +local p_retain_noempty=Cs ((normalline+singleempty )^0 ) +local striplinepatterns={ + ["prune"]=p_prune_normal, + ["prune and collapse"]=p_prune_collapse, + ["prune and no empty"]=p_prune_noempty, + ["retain"]=p_retain_normal, + ["retain and collapse"]=p_retain_collapse, + ["retain and no empty"]=p_retain_noempty, +} +strings.striplinepatterns=striplinepatterns +function strings.striplines(str,how) + return str and lpegmatch(how and striplinepatterns[how] or p_prune_collapse,str) or str end +strings.striplong=strings.striplines function strings.nice(str) str=gsub(str,"[:%-+_]+"," ") return str @@ -2777,7 +2839,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("format('%%i',a%s)",n) end end local format_d=format_i @@ -2789,6 +2851,10 @@ local format_f=function(f) n=n+1 return format("format('%%%sf',a%s)",f,n) end +local format_F=function(f) + n=n+1 + return format("((a%s == 0 and '0') or (a%s == 1 and '1') or format('%%%sf',a%s))",n,n,f,n) +end local format_g=function(f) n=n+1 return format("format('%%%sg',a%s)",f,n) @@ -3003,7 +3069,7 @@ local builder=Cs { "start", ( P("%")/""*( V("!") -+V("s")+V("q")+V("i")+V("d")+V("f")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") ++V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") +V("c")+V("C")+V("S") +V("Q") +V("N") @@ -3023,6 +3089,7 @@ local builder=Cs { "start", ["i"]=(prefix_any*P("i"))/format_i, ["d"]=(prefix_any*P("d"))/format_d, ["f"]=(prefix_any*P("f"))/format_f, + ["F"]=(prefix_any*P("F"))/format_F, ["g"]=(prefix_any*P("g"))/format_g, ["G"]=(prefix_any*P("G"))/format_G, ["e"]=(prefix_any*P("e"))/format_e, @@ -3070,7 +3137,7 @@ local function make(t,str) f=loadstripped(p)() else n=0 - p=lpegmatch(builder,str,1,"..",t._extensions_) + p=lpegmatch(builder,str,1,t._connector_,t._extensions_) if n>0 then p=format(template,preamble,t._preamble_,arguments[n],p) f=loadstripped(p,t._environment_)() @@ -3086,18 +3153,18 @@ local function use(t,fmt,...) end strings.formatters={} if _LUAVERSION<5.2 then - function strings.formatters.new() - local t={ _extensions_={},_preamble_=preamble,_environment_={},_type_="formatter" } + function strings.formatters.new(noconcat) + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } setmetatable(t,{ __index=make,__call=use }) return t end else - function strings.formatters.new() + function strings.formatters.new(noconcat) local e={} for k,v in next,environment do e[k]=v end - local t={ _extensions_={},_preamble_="",_environment_=e,_type_="formatter" } + local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } setmetatable(t,{ __index=make,__call=use }) return t end @@ -6504,7 +6571,7 @@ local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf otf.glists={ "gsub","gpos" } -otf.version=2.751 +otf.version=2.755 otf.cache=containers.define("fonts","otf",otf.version,true) local fontdata=fonts.hashes.identifiers local chardata=characters and characters.data @@ -7047,15 +7114,22 @@ actions["prepare glyphs"]=function(data,filename,raw) local glyph=cidglyphs[index] if glyph then local unicode=glyph.unicode +if unicode>=0x00E000 and unicode<=0x00F8FF then + unicode=-1 +elseif unicode>=0x0F0000 and unicode<=0x0FFFFD then + unicode=-1 +elseif unicode>=0x100000 and unicode<=0x10FFFD then + unicode=-1 +end local name=glyph.name or cidnames[index] - if not unicode or unicode==-1 or unicode>=criterium then + if not unicode or unicode==-1 then unicode=cidunicodes[index] end if unicode and descriptions[unicode] then report_otf("preventing glyph %a at index %H to overload unicode %U",name or "noname",index,unicode) unicode=-1 end - if not unicode or unicode==-1 or unicode>=criterium then + if not unicode or unicode==-1 then if not name then name=format("u%06X",private) end @@ -7101,7 +7175,7 @@ actions["prepare glyphs"]=function(data,filename,raw) if glyph then local unicode=glyph.unicode local name=glyph.name - if not unicode or unicode==-1 or unicode>=criterium then + if not unicode or unicode==-1 then unicode=private unicodes[name]=private if trace_private then @@ -7156,47 +7230,43 @@ actions["check encoding"]=function(data,filename,raw) local unicodetoindex=mapdata and mapdata.map or {} local indextounicode=mapdata and mapdata.backmap or {} local encname=lower(data.enc_name or mapdata.enc_name or "") - local criterium=0xFFFF + local criterium=0xFFFF + local privateoffset=constructors.privateoffset if find(encname,"unicode") then if trace_loading then report_otf("checking embedded unicode map %a",encname) end - local hash={} - for index,unicode in next,indices do - hash[index]=descriptions[unicode] - end - local reported={} - for unicode,index in next,unicodetoindex do - if not descriptions[unicode] then - local d=hash[index] + local reported={} + for maybeunicode,index in next,unicodetoindex do + if descriptions[maybeunicode] then + else + local unicode=indices[index] + if not unicode then + elseif maybeunicode==unicode then + elseif unicode>privateoffset then + else + local d=descriptions[unicode] if d then - if d.unicode~=unicode then - local c=d.copies - if c then - c[unicode]=true - else - d.copies={ [unicode]=true } - end + local c=d.copies + if c then + c[maybeunicode]=true + else + d.copies={ [maybeunicode]=true } end - elseif not reported[i] then + elseif index and not reported[index] then report_otf("missing index %i",index) - reported[i]=true + reported[index]=true end end end - for index,data in next,hash do - data.copies=sortedkeys(data.copies) - end - for index,unicode in next,indices do - local description=hash[index] - local copies=description.copies - if copies then - duplicates[unicode]=copies - description.copies=nil - else - report_otf("copies but no unicode parent %U",unicode) - end + end + for unicode,data in next,descriptions do + local d=data.copies + if d then + duplicates[unicode]=sortedkeys(d) + data.copies=nil end + end elseif properties.cidinfo then report_otf("warning: no unicode map, used cidmap %a",properties.cidinfo.usedname) else @@ -7238,7 +7308,7 @@ actions["add duplicates"]=function(data,filename,raw) end end end - if u>0 then + if u>0 then local duplicate=table.copy(description) duplicate.comment=format("copy of U+%05X",unicode) descriptions[u]=duplicate @@ -7440,10 +7510,16 @@ actions["reorganize subtables"]=function(data,filename,raw) report_otf("skipping weird lookup number %s",k) elseif features then local f={} + local o={} for i=1,#features do local df=features[i] local tag=strip(lower(df.tag)) - local ft=f[tag] if not ft then ft={} f[tag]=ft end + local ft=f[tag] + if not ft then + ft={} + f[tag]=ft + o[#o+1]=tag + end local dscripts=df.scripts for i=1,#dscripts do local d=dscripts[i] @@ -7463,6 +7539,7 @@ actions["reorganize subtables"]=function(data,filename,raw) subtables=subtables, markclass=markclass, features=f, + order=o, } else lookups[name]={ @@ -8908,8 +8985,9 @@ basemethods.shared={ basemethod="independent" local function featuresinitializer(tfmdata,value) if true then - local t=trace_preparing and os.clock() + local starttime=trace_preparing and os.clock() local features=tfmdata.shared.features + local fullname=trace_preparing and tfmdata.properties.fullname if features then applybasemethod("initializehashes",tfmdata) local collectlookups=otf.collectlookups @@ -8919,26 +8997,34 @@ local function featuresinitializer(tfmdata,value) local language=properties.language local basesubstitutions=rawdata.resources.features.gsub local basepositionings=rawdata.resources.features.gpos - if basesubstitutions then - for feature,data in next,basesubstitutions do - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if validlookups then - applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - end - end - end - end - if basepositionings then - for feature,data in next,basepositionings do - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if validlookups then - applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) - registerbasefeature(feature,value) + if basesubstitutions or basepositionings then + local sequences=tfmdata.resources.sequences + for s=1,#sequences do + local sequence=sequences[s] + local sfeatures=sequence.features + if sfeatures then + local order=sequence.order + if order then + for i=1,#order do + local feature=order[i] + if features[feature] then + local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) + if not validlookups then + elseif basesubstitutions and basesubstitutions[feature] then + if trace_preparing then + report_prepare("filtering base feature %a for %a",feature,fullname) + end + applybasemethod("preparesubstitutions",tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + elseif basepositionings and basepositionings[feature] then + if trace_preparing then + report_prepare("filtering base feature %a for %a",feature,fullname) + end + applybasemethod("preparepositionings",tfmdata,feature,features[feature],validlookups,lookuplist) + registerbasefeature(feature,value) + end + end + end end end end @@ -8946,7 +9032,7 @@ local function featuresinitializer(tfmdata,value) registerbasehash(tfmdata) end if trace_preparing then - report_prepare("preparation time is %0.3f seconds for %a",os.clock()-t,tfmdata.properties.fullname) + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) end end end @@ -9042,9 +9128,9 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) return 0,0 end end -function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) - local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) - local bound=base[a_markbase] +function injections.setmark(start,base,factor,rlmode,ba,ma) + local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) + local bound=base[a_markbase] local index=1 if bound then local mb=marks[bound] @@ -9063,7 +9149,7 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,index,baseismark) base[a_markbase]=bound start[a_markmark]=bound start[a_markdone]=index - marks[bound]={ [index]={ dx,dy,rlmode,baseismark } } + marks[bound]={ [index]={ dx,dy,rlmode } } return dx,dy,bound end local function dir(n) @@ -11413,9 +11499,12 @@ local autofeatures=fonts.analyzers.features local function initialize(sequence,script,language,enabled) local features=sequence.features if features then - for kind,scripts in next,features do + local order=features.order + for i=1,#order do + local kind=order[i] local valid=enabled[kind] if valid then + local scripts=features[kind] local languages=scripts[script] or scripts[wildcard] if languages and (languages[language] or languages[wildcard]) then return { valid,autofeatures[kind] or false,sequence.chain or 0,kind,sequence } @@ -11447,12 +11536,12 @@ function otf.dataset(tfmdata,font) } rs[language]=rl local sequences=tfmdata.resources.sequences -for s=1,#sequences do - local v=enabled and initialize(sequences[s],script,language,enabled) - if v then - rl[#rl+1]=v - end -end + for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1]=v + end + end end return rl end @@ -12479,6 +12568,14 @@ local function packdata(data) features[script]=pack_normal(feature) end end + local order=sequence.order + if order then + sequence.order=pack_indexed(order) + end + local markclass=sequence.markclass + if markclass then + sequence.markclass=pack_boolean(markclass) + end end end local lookups=resources.lookups @@ -12891,6 +12988,20 @@ local function unpackdata(data) end end end + local order=feature.order + if order then + local tv=tables[order] + if tv then + feature.order=tv + end + end + local markclass=feature.markclass + if markclass then + local tv=tables[markclass] + if tv then + feature.markclass=tv + end + end end end local lookups=resources.lookups diff --git a/tex/generic/context/luatex/luatex-fonts-otn.lua b/tex/generic/context/luatex/luatex-fonts-otn.lua index c57be5f02..9d3253f2c 100644 --- a/tex/generic/context/luatex/luatex-fonts-otn.lua +++ b/tex/generic/context/luatex/luatex-fonts-otn.lua @@ -2038,9 +2038,12 @@ local autofeatures = fonts.analyzers.features -- was: constants local function initialize(sequence,script,language,enabled) local features = sequence.features if features then - for kind, scripts in next, features do + local order = features.order + for i=1,#order do + local kind = order[i] -- local valid = enabled[kind] if valid then + local scripts = features[kind] -- local languages = scripts[script] or scripts[wildcard] if languages and (languages[language] or languages[wildcard]) then return { valid, autofeatures[kind] or false, sequence.chain or 0, kind, sequence } @@ -2074,19 +2077,12 @@ function otf.dataset(tfmdata,font) -- generic variant, overloaded in context } rs[language] = rl local sequences = tfmdata.resources.sequences --- setmetatableindex(rl, function(t,k) --- if type(k) == "number" then --- local v = enabled and initialize(sequences[k],script,language,enabled) --- t[k] = v --- return v --- end --- end) -for s=1,#sequences do - local v = enabled and initialize(sequences[s],script,language,enabled) - if v then - rl[#rl+1] = v - end -end + for s=1,#sequences do + local v = enabled and initialize(sequences[s],script,language,enabled) + if v then + rl[#rl+1] = v + end + end end return rl end -- cgit v1.2.3