summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/context/presentations/context/2020/context-2020-luametatex.tex2
-rw-r--r--doc/context/sources/general/manuals/luametafun/luametafun.tex1
-rw-r--r--doc/context/sources/general/manuals/luametatex/luametatex.tex7
-rw-r--r--metapost/context/base/mpxl/mp-apos.mpxl27
-rw-r--r--metapost/context/base/mpxl/mp-luas.mpxl69
-rw-r--r--metapost/context/base/mpxl/mp-mlib.mpxl161
-rw-r--r--metapost/context/base/mpxl/mp-xbox.mpxl37
-rw-r--r--scripts/context/lua/mtx-context.lua4
-rw-r--r--scripts/context/lua/mtx-fonts.lua2
-rw-r--r--scripts/context/lua/mtxrun.lua37
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua37
-rw-r--r--scripts/context/stubs/unix/mtxrun37
-rw-r--r--scripts/context/stubs/win64/mtxrun.lua37
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkii/mult-ro.mkii1
-rw-r--r--tex/context/base/mkiv/back-exp.lua6
-rw-r--r--tex/context/base/mkiv/buff-ini.lua10
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/data-tmp.lua2
-rw-r--r--tex/context/base/mkiv/font-cft.lua2
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-ocm.lua12
-rw-r--r--tex/context/base/mkiv/font-osd.lua18
-rw-r--r--tex/context/base/mkiv/font-otl.lua5
-rw-r--r--tex/context/base/mkiv/font-oto.lua72
-rw-r--r--tex/context/base/mkiv/font-otr.lua68
-rw-r--r--tex/context/base/mkiv/font-ots.lua57
-rw-r--r--tex/context/base/mkiv/font-oup.lua109
-rw-r--r--tex/context/base/mkiv/font-ttf.lua10
-rw-r--r--tex/context/base/mkiv/good-gen.lua12
-rw-r--r--tex/context/base/mkiv/l-dir.lua12
-rw-r--r--tex/context/base/mkiv/l-io.lua3
-rw-r--r--tex/context/base/mkiv/l-lpeg.lua12
-rw-r--r--tex/context/base/mkiv/lpdf-wid.lua27
-rw-r--r--tex/context/base/mkiv/math-ini.lua14
-rw-r--r--tex/context/base/mkiv/math-map.lua6
-rw-r--r--tex/context/base/mkiv/mlib-mpf.lua25
-rw-r--r--tex/context/base/mkiv/mult-def.lua4
-rw-r--r--tex/context/base/mkiv/mult-fun.lua13
-rw-r--r--tex/context/base/mkiv/mult-low.lua2
-rw-r--r--tex/context/base/mkiv/page-mix.lua9
-rw-r--r--tex/context/base/mkiv/publ-dat.lua8
-rw-r--r--tex/context/base/mkiv/publ-fnd.lua4
-rw-r--r--tex/context/base/mkiv/spac-ver.lua26
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin24938 -> 24885 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin250485 -> 250312 bytes
-rw-r--r--tex/context/base/mkiv/strc-syn.lua22
-rw-r--r--tex/context/base/mkiv/util-prs.lua8
-rw-r--r--tex/context/base/mkiv/util-tab.lua14
-rw-r--r--tex/context/base/mkxl/anch-bar.mkxl4
-rw-r--r--tex/context/base/mkxl/anch-bck.mklx16
-rw-r--r--tex/context/base/mkxl/anch-pgr.mkxl4
-rw-r--r--tex/context/base/mkxl/anch-pos.lmt1381
-rw-r--r--tex/context/base/mkxl/anch-pos.mkxl57
-rw-r--r--tex/context/base/mkxl/anch-snc.lmt44
-rw-r--r--tex/context/base/mkxl/anch-snc.mkxl8
-rw-r--r--tex/context/base/mkxl/back-exp.lmt6
-rw-r--r--tex/context/base/mkxl/buff-ini.mkxl11
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/cont-run.lmt8
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/core-sys.mkxl4
-rw-r--r--tex/context/base/mkxl/core-uti.lmt90
-rw-r--r--tex/context/base/mkxl/driv-shp.lmt2
-rw-r--r--tex/context/base/mkxl/file-job.lmt18
-rw-r--r--tex/context/base/mkxl/font-def.lmt1
-rw-r--r--tex/context/base/mkxl/font-lib.mklx2
-rw-r--r--tex/context/base/mkxl/font-ogr.lmt14
-rw-r--r--tex/context/base/mkxl/font-otd.lmt284
-rw-r--r--tex/context/base/mkxl/font-ots.lmt346
-rw-r--r--tex/context/base/mkxl/font-set.mklx2
-rw-r--r--tex/context/base/mkxl/lpdf-emb.lmt25
-rw-r--r--tex/context/base/mkxl/lpdf-lmt.lmt1
-rw-r--r--tex/context/base/mkxl/lpdf-wid.lmt27
-rw-r--r--tex/context/base/mkxl/luat-lib.mkxl2
-rw-r--r--tex/context/base/mkxl/lxml-ini.mkxl17
-rw-r--r--tex/context/base/mkxl/math-ini.lmt14
-rw-r--r--tex/context/base/mkxl/math-map.lmt6
-rw-r--r--tex/context/base/mkxl/math-rad.mklx10
-rw-r--r--tex/context/base/mkxl/meta-ini.mkxl6
-rw-r--r--tex/context/base/mkxl/mlib-ctx.lmt28
-rw-r--r--tex/context/base/mkxl/mlib-lmp.lmt509
-rw-r--r--tex/context/base/mkxl/mlib-lua.lmt38
-rw-r--r--tex/context/base/mkxl/mlib-mpf.lmt495
-rw-r--r--tex/context/base/mkxl/mlib-pos.lmt4
-rw-r--r--tex/context/base/mkxl/mlib-run.lmt43
-rw-r--r--tex/context/base/mkxl/mlib-scn.lmt9
-rw-r--r--tex/context/base/mkxl/mult-sys.mkxl2
-rw-r--r--tex/context/base/mkxl/node-nut.lmt1
-rw-r--r--tex/context/base/mkxl/pack-rul.mkxl4
-rw-r--r--tex/context/base/mkxl/page-box.mklx36
-rw-r--r--tex/context/base/mkxl/page-lay.mkxl181
-rw-r--r--tex/context/base/mkxl/page-otr.mklx37
-rw-r--r--tex/context/base/mkxl/scrn-wid.mklx6
-rw-r--r--tex/context/base/mkxl/spac-hor.mkxl4
-rw-r--r--tex/context/base/mkxl/spac-ver.lmt26
-rw-r--r--tex/context/base/mkxl/strc-des.mklx9
-rw-r--r--tex/context/base/mkxl/strc-enu.mklx29
-rw-r--r--tex/context/base/mkxl/strc-ref.mklx8
-rw-r--r--tex/context/base/mkxl/strc-reg.lmt18
-rw-r--r--tex/context/base/mkxl/supp-box.mkxl1
-rw-r--r--tex/context/base/mkxl/syst-aux.lmt4
-rw-r--r--tex/context/base/mkxl/syst-ini.mkxl4
-rw-r--r--tex/context/base/mkxl/tabl-ntb.mkxl4
-rw-r--r--tex/context/base/mkxl/tabl-tab.mkxl5
-rw-r--r--tex/context/base/mkxl/tabl-tbl.mkxl6
-rw-r--r--tex/context/base/mkxl/tabl-xtb.mklx4
-rw-r--r--tex/context/base/mkxl/util-pck.lmt176
-rw-r--r--tex/context/interface/mkii/keys-ro.xml1
-rw-r--r--tex/context/modules/mkiv/s-fonts-emoji.mkiv65
-rw-r--r--tex/context/modules/mkiv/s-fonts-features.lua22
-rw-r--r--tex/context/modules/mkiv/s-fonts-tables.lua20
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua294
115 files changed, 3434 insertions, 2134 deletions
diff --git a/doc/context/presentations/context/2020/context-2020-luametatex.tex b/doc/context/presentations/context/2020/context-2020-luametatex.tex
index 10b57660e..ae2b72713 100644
--- a/doc/context/presentations/context/2020/context-2020-luametatex.tex
+++ b/doc/context/presentations/context/2020/context-2020-luametatex.tex
@@ -526,4 +526,6 @@ documents that come with the distribution.
\stopitemize
+\stoptitle
+
\stopdocument
diff --git a/doc/context/sources/general/manuals/luametafun/luametafun.tex b/doc/context/sources/general/manuals/luametafun/luametafun.tex
index 785fd03df..a90e265f1 100644
--- a/doc/context/sources/general/manuals/luametafun/luametafun.tex
+++ b/doc/context/sources/general/manuals/luametafun/luametafun.tex
@@ -36,6 +36,7 @@
\component luametafun-fonts
\component luametafun-color
\component luametafun-groups
+ \component luametafun-extensions
\component luametafun-interface
\stopbodymatter
diff --git a/doc/context/sources/general/manuals/luametatex/luametatex.tex b/doc/context/sources/general/manuals/luametatex/luametatex.tex
index bd4029a57..3c02391ce 100644
--- a/doc/context/sources/general/manuals/luametatex/luametatex.tex
+++ b/doc/context/sources/general/manuals/luametatex/luametatex.tex
@@ -55,6 +55,10 @@
% rpi 64 : 26.0 (overclocked)
% amd 10 fitlet : 28.2
+% 20210812 : 298 pages
+%
+% mingw : 9.7
+
% But speed can differ a bit per compilation (upto .5 seconds maybe due to how
% compiled code is organized which might influence caching. Who knows ... (or
% cares). For instance at 20200407 I measured 10.9 seconds after some new low level
@@ -63,7 +67,8 @@
% took 10.5 seconds, that is, we were at exactly 24 pages per second but after
% switching to gcc9 it dropped again. In december 2020, with IPO enabled I crossed
% the 26 pps barrier and went below 10 seconds but that was also after some further
-% cleanup in \LMTX.
+% cleanup in \LMTX. Mid August 2021 I measured over 30 pps but not all is due to
+% the engine I guess.
% msvc 1899k (2% slower than mingw)
% msvc /GL 2297k (similar to mingw)
diff --git a/metapost/context/base/mpxl/mp-apos.mpxl b/metapost/context/base/mpxl/mp-apos.mpxl
index 65d3e86fb..3070d3a8a 100644
--- a/metapost/context/base/mpxl/mp-apos.mpxl
+++ b/metapost/context/base/mpxl/mp-apos.mpxl
@@ -179,16 +179,17 @@ newscriptindex mfid_getmultipars ; mfid_getmultipars := scriptindex "getmultipar
def getposboxes (expr tags, anchor) = runscript mfid_getposboxes tags anchor ; enddef ;
def getmultipars(expr tags, anchor) = runscript mfid_getmultipars tags anchor ; enddef ;
-newscriptindex mfid_getpospage ; mfid_getpospage := scriptindex "getpospage" ; vardef getpospage (expr n) = runscript mfid_getpospage n enddef ;
-newscriptindex mfid_getposparagraph ; mfid_getposparagraph := scriptindex "getposparagraph" ; vardef getposparagraph (expr n) = runscript mfid_getposparagraph n enddef ;
-newscriptindex mfid_getposcolumn ; mfid_getposcolumn := scriptindex "getposcolumn" ; vardef getposcolumn (expr n) = runscript mfid_getposcolumn n enddef ;
-newscriptindex mfid_getposregion ; mfid_getposregion := scriptindex "getposregion" ; vardef getposregion (expr n) = runscript mfid_getposregion n enddef ;
+newscriptindex mfid_getpospage ; mfid_getpospage := scriptindex "getpospage" ; vardef getpospage (expr n) = runscript mfid_getpospage n enddef ;
+newscriptindex mfid_getposparagraph ; mfid_getposparagraph := scriptindex "getposparagraph" ; vardef getposparagraph(expr n) = runscript mfid_getposparagraph n enddef ;
+newscriptindex mfid_getposcolumn ; mfid_getposcolumn := scriptindex "getposcolumn" ; vardef getposcolumn (expr n) = runscript mfid_getposcolumn n enddef ;
+newscriptindex mfid_getposregion ; mfid_getposregion := scriptindex "getposregion" ; vardef getposregion (expr n) = runscript mfid_getposregion n enddef ;
-newscriptindex mfid_getposx ; mfid_getposx := scriptindex "getposx" ; vardef getposx (expr n) = runscript mfid_getposx n enddef ;
-newscriptindex mfid_getposy ; mfid_getposy := scriptindex "getposy" ; vardef getposy (expr n) = runscript mfid_getposy n enddef ;
-newscriptindex mfid_getposwidth ; mfid_getposwidth := scriptindex "getposwidth" ; vardef getposwidth (expr n) = runscript mfid_getposwidth n enddef ;
-newscriptindex mfid_getposheight ; mfid_getposheight := scriptindex "getposheight" ; vardef getposheight (expr n) = runscript mfid_getposheight n enddef ;
-newscriptindex mfid_getposdepth ; mfid_getposdepth := scriptindex "getposdepth" ; vardef getposdepth (expr n) = runscript mfid_getposdepth n enddef ;
+newscriptindex mfid_getposx ; mfid_getposx := scriptindex "getposx" ; vardef getposx(expr n) = runscript mfid_getposx n enddef ;
+newscriptindex mfid_getposy ; mfid_getposy := scriptindex "getposy" ; vardef getposy(expr n) = runscript mfid_getposy n enddef ;
+
+newscriptindex mfid_getposwidth ; mfid_getposwidth := scriptindex "getposwidth" ; vardef getposwidth (expr n) = runscript mfid_getposwidth n enddef ;
+newscriptindex mfid_getposheight ; mfid_getposheight := scriptindex "getposheight" ; vardef getposheight(expr n) = runscript mfid_getposheight n enddef ;
+newscriptindex mfid_getposdepth ; mfid_getposdepth := scriptindex "getposdepth" ; vardef getposdepth (expr n) = runscript mfid_getposdepth n enddef ;
newscriptindex mfid_getposleftskip ; mfid_getposleftskip := scriptindex "getposleftskip" ; vardef getposleftskip (expr n) = runscript mfid_getposleftskip n enddef ;
newscriptindex mfid_getposrightskip ; mfid_getposrightskip := scriptindex "getposrightskip" ; vardef getposrightskip (expr n) = runscript mfid_getposrightskip n enddef ;
@@ -203,9 +204,15 @@ newscriptindex mfid_getposlowerleft ; mfid_getposlowerleft := scriptindex "get
newscriptindex mfid_getposupperright ; mfid_getposupperright := scriptindex "getposupperright" ; vardef getposupperright(expr n) = runscript mfid_getposupperright n enddef ;
newscriptindex mfid_getposlowerright ; mfid_getposlowerright := scriptindex "getposlowerright" ; vardef getposlowerright(expr n) = runscript mfid_getposlowerright n enddef ;
+newscriptindex mfid_getposllx ; mfid_getposllx := scriptindex "getposllx" ; vardef getposllx(expr n) = runscript mfid_getposllx n enddef ;
+newscriptindex mfid_getposlly ; mfid_getposlly := scriptindex "getposlly" ; vardef getposlly(expr n) = runscript mfid_getposlly n enddef ;
+newscriptindex mfid_getposurx ; mfid_getposurx := scriptindex "getposurx" ; vardef getposurx(expr n) = runscript mfid_getposurx n enddef ;
+newscriptindex mfid_getposury ; mfid_getposury := scriptindex "getposury" ; vardef getposury(expr n) = runscript mfid_getposury n enddef ;
+
permanent
getposboxes, getmultipars,
getpospage, getposparagraph, getposcolumn, getposregion,
getposx, getposy, getposwidth, getposheight, getposdepth,
getposleftskip, getposrightskip, getposhsize, getposparindent, getposhangindent, getposhangafter,
- getposxy, getposupperleft, getposlowerleft, getposupperright, getposlowerright ;
+ getposxy, getposupperleft, getposlowerleft, getposupperright, getposlowerright,
+ getposllx, getposlly, getposurx, getposury ;
diff --git a/metapost/context/base/mpxl/mp-luas.mpxl b/metapost/context/base/mpxl/mp-luas.mpxl
index 00e7876a8..24a2fc8fe 100644
--- a/metapost/context/base/mpxl/mp-luas.mpxl
+++ b/metapost/context/base/mpxl/mp-luas.mpxl
@@ -138,18 +138,30 @@ permanent resolvedcolor ;
% Modes:
-vardef texmode (expr s) = lua.mp("mode", s) enddef ;
-vardef systemmode(expr s) = lua.mp("systemmode",s) enddef ;
+newscriptindex mfid_mode ; mfid_mode := scriptindex "mode" ;
+newscriptindex mfid_systemmode ; mfid_systemmode := scriptindex "systemmode" ;
+
+vardef texmode (expr s) = runscript mfid_mode s enddef ;
+vardef systemmode (expr s) = runscript mfid_systemmode s enddef ;
+
+% let processingmode = systemmode ;
permanent texmode, systemmode ;
% A few helpers
-vardef isarray suffix a = lua.mp.isarray (str a) enddef ;
-vardef prefix suffix a = lua.mp.prefix (str a) enddef ;
-vardef dimension suffix a = lua.mp.dimension(str a) enddef ;
+newscriptindex mfid_isarray ; mfid_isarray := scriptindex "isarray" ;
+newscriptindex mfid_prefix ; mfid_prefix := scriptindex "prefix" ;
+newscriptindex mfid_dimension ; mfid_dimension := scriptindex "dimension" ;
+newscriptindex mfid_isobject ; mfid_isobject := scriptindex "isobject" ;
+
+vardef isarray suffix a = runscript mfid_isarray (str a) enddef ;
+vardef prefix suffix a = runscript mfid_prefix (str a) enddef ;
+vardef dimension suffix a = runscript mfid_dimension(str a) enddef ;
-permanent isarray, prefix, dimension ;
+vardef isobject expr p = if picture p : runscript mfid_isobject prescriptpart p else : false fi enddef ;
+
+permanent isarray, prefix, dimension, isobject ;
% More access
@@ -175,17 +187,31 @@ permanent
setmacro, setdimen, setcount, settoks,
setglobalmacro, setglobaldimen, setglobalcount, setglobaltoks ;
-% todo: mfid_
-
-vardef positionpath (expr name) = lua.mp.positionpath (name) enddef ;
-vardef positioncurve (expr name) = lua.mp.positioncurve (name) enddef ;
-vardef positionxy (expr name) = lua.mp.positionxy (name) enddef ;
-vardef positionpxy (expr name) = lua.mp.positionpxy (name) enddef ;
-vardef positionwhd (expr name) = lua.mp.positionwhd (name) enddef ;
-vardef positionpage (expr name) = lua.mp.positionpage (name) enddef ;
-vardef positionregion(expr name) = lua.mp.positionregion(name) enddef ;
-vardef positionbox (expr name) = lua.mp.positionbox (name) enddef ;
-vardef positionanchor = lua.mp.positionanchor() enddef ;
+newscriptindex mfid_positionpath ; mfid_positionpath := scriptindex("positionpath") ;
+newscriptindex mfid_positioncurve ; mfid_positioncurve := scriptindex("positioncurve") ;
+newscriptindex mfid_positionxy ; mfid_positionxy := scriptindex("positionxy") ;
+newscriptindex mfid_positionx ; mfid_positionx := scriptindex("positionx") ;
+newscriptindex mfid_positiony ; mfid_positiony := scriptindex("positiony") ;
+newscriptindex mfid_positionpar ; mfid_positionpar := scriptindex("positionpar") ;
+newscriptindex mfid_positionwhd ; mfid_positionwhd := scriptindex("positionwhd") ;
+newscriptindex mfid_positionpage ; mfid_positionpage := scriptindex("positionpage") ;
+newscriptindex mfid_positionregion ; mfid_positionregion := scriptindex("positionregion") ;
+newscriptindex mfid_positionbox ; mfid_positionbox := scriptindex("positionbox") ;
+newscriptindex mfid_positionanchor ; mfid_positionanchor := scriptindex("positionanchor") ;
+
+vardef positionpath (expr name) = runscript mfid_positionpath name enddef ;
+vardef positioncurve (expr name) = runscript mfid_positioncurve name enddef ;
+vardef positionxy (expr name) = runscript mfid_positionxy name enddef ;
+vardef positionx (expr name) = runscript mfid_positionx name enddef ;
+vardef positiony (expr name) = runscript mfid_positiony name enddef ;
+vardef positionpar (expr name) = runscript mfid_positionpar name enddef ;
+vardef positionwhd (expr name) = runscript mfid_positionwhd name enddef ;
+vardef positionpage (expr name) = runscript mfid_positionpage name enddef ;
+vardef positioncolumn (expr name) = runscript mfid_positioncolumn name enddef ;
+vardef positionparagraph(expr name) = runscript mfid_positionparagraph name enddef ;
+vardef positionregion (expr name) = runscript mfid_positionregion name enddef ;
+vardef positionbox (expr name) = runscript mfid_positionbox name enddef ;
+vardef positionanchor = runscript mfid_positionanchor enddef ;
vardef positioninregion =
currentpicture := currentpicture shifted - positionxy(positionanchor) ;
@@ -195,8 +221,9 @@ vardef positionatanchor(expr name) =
currentpicture := currentpicture shifted - positionxy(name) ;
enddef ;
-permanent positionpath, positioncurve, positionxy, positionpxy, positionwhd, positionpage,
- positionregion, positionbox, positionanchor, positioninregion, positionatanchor ;
+permanent positionpath, positioncurve, positionxy, positionwhd,
+ positionpage, positionregion, positioncolumn, positionparagraph,
+ positionbox, positionanchor, positioninregion, positionatanchor ;
let wdpart = redpart ;
let htpart = greenpart ;
@@ -204,8 +231,8 @@ let dppart = bluepart ;
permanent wdpart, htpart, dppart;
-vardef texvar(expr name) = lua.mp.texvar(name) enddef ;
-vardef texstr(expr name) = lua.mp.texstr(name) enddef ;
+newscriptindex mfid_texvar ; mfid_texvar := scriptindex "texvar" ; vardef texvar(expr s) = runscript mfid_texvar s enddef ;
+newscriptindex mfid_texstr ; mfid_texstr := scriptindex "texstr" ; vardef texstr(expr s) = runscript mfid_texstr s enddef ;
newscriptindex mfid_path_lengthof ; mfid_path_lengthof := scriptindex "pathlengthof" ;
newscriptindex mfid_path_pointof ; mfid_path_pointof := scriptindex "pathpointof" ;
diff --git a/metapost/context/base/mpxl/mp-mlib.mpxl b/metapost/context/base/mpxl/mp-mlib.mpxl
index 35854a987..65146081e 100644
--- a/metapost/context/base/mpxl/mp-mlib.mpxl
+++ b/metapost/context/base/mpxl/mp-mlib.mpxl
@@ -17,19 +17,6 @@ newinternal boolean metafun_loaded_mlib ; metafun_loaded_mlib := true ; immutabl
% numeric LUATEXFUNCTIONALITY ; LUATEXFUNCTIONALITY := runscript("mp.print(LUATEXFUNCTIONALITY or (status and status.development_id) or 6346)") ;
-%D Objects:
-
-vardef isobject expr p =
- if picture p :
- % lua.mp.isobject(prescriptpart p)
- runscript("mp.isobject(" & prescriptpart p & ")")
- else :
- false
- fi
-enddef ;
-
-permanent isobject ;
-
%D Color and transparency
%D
%D Separable:
@@ -146,12 +133,11 @@ newinternal textextoffset ; textextoffset := 0 ;
permanent textextoffset ;
-%%%%%%% mfun_tt_w[], mfun_tt_h[], mfun_tt_d[] ; % we can consider using colors (less hash space)
-color mfun_tt_b ;
-numeric mfun_tt_n ; mfun_tt_n := 0 ;
-picture mfun_tt_p ; mfun_tt_p := nullpicture ;
-picture mfun_tt_o ; mfun_tt_o := nullpicture ;
-picture mfun_tt_c ; mfun_tt_c := nullpicture ;
+rgbcolor mfun_tt_r ;
+numeric mfun_tt_n ; mfun_tt_n := 0 ;
+picture mfun_tt_p ; mfun_tt_p := nullpicture ;
+picture mfun_tt_o ; mfun_tt_o := nullpicture ;
+picture mfun_tt_c ; mfun_tt_c := nullpicture ;
if unknown mfun_trial_run :
boolean mfun_trial_run ;
@@ -213,8 +199,9 @@ immutable inicatcoderegime, texcatcoderegime, luacatcoderegime, notcatcoderegime
permanent catcoderegime ;
-newscriptindex mfid_sometextext ; mfid_sometextext := scriptindex "sometextext" ;
-newscriptindex mfid_madetextext ; mfid_madetextext := scriptindex "madetextext" ;
+newscriptindex mfid_sometextext ; mfid_sometextext := scriptindex "sometextext" ;
+newscriptindex mfid_madetextext ; mfid_madetextext := scriptindex "madetextext" ;
+newscriptindex mfid_boxdimensions ; mfid_boxdimensions := scriptindex "boxdimensions" ;
vardef rawtextext(expr s) =
if s = "" :
@@ -254,6 +241,10 @@ vardef rawmadetext =
mfun_tt_c
enddef ;
+% \setbox\scratchbox\hbox{!!!!!!!!!!!!!}
+% \putboxincache{one}{a}\scratchbox
+% \startMPcode draw rawtexbox("one","a") ; \stopMPcode
+
vardef validtexbox(expr category, name) =
if category == "" :
false
@@ -269,11 +260,12 @@ enddef ;
vardef rawtexbox(expr category, name) =
mfun_tt_c := nullpicture ;
if validtexbox(category,name) :
- mfun_tt_b := lua.mp.mf_tb_dimensions(category, name) ;
+ % mfun_tt_r := lua.mp.mf_tb_dimensions(category, name) ;
+ mfun_tt_r := runscript mfid_boxdimensions category name ;
addto mfun_tt_c doublepath unitsquare
- xscaled wdpart mfun_tt_b
- yscaled (htpart mfun_tt_b + dppart mfun_tt_b)
- shifted (0,- dppart mfun_tt_b)
+ xscaled wdpart mfun_tt_r
+ yscaled (htpart mfun_tt_r + dppart mfun_tt_r)
+ shifted (0,- dppart mfun_tt_r)
withprescript "mf_object=box"
withprescript "bx_category=" & if numeric category : decimal fi category
withprescript "bx_name=" & if numeric name : decimal fi name ;
@@ -1671,102 +1663,20 @@ permanent tostring, topair, quote, quotation ;
% but running lua is fast enough so we can gain on string construction in metapost
% which is also not that efficient.
-vardef mfun_key_to_lua(expr k) =
- if numeric k : decimal k else : "'" & k & "'" fi
-enddef ;
-
-vardef mfun_point_to_lua(expr k,p,i) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
- decimal xpart (point i of p) & "," &
- decimal ypart (point i of p) & "," &
- decimal xpart (precontrol i of p) & "," &
- decimal ypart (precontrol i of p) & "," &
- decimal xpart (postcontrol i of p) & "," &
- decimal ypart (postcontrol i of p)
- & "})" ) ;
-enddef ;
-
-vardef mfun_transform_to_lua(expr k,t) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
- decimal xxpart t & "," & % rx
- decimal xypart t & "," & % sx
- decimal yxpart t & "," & % sy
- decimal yypart t & "," & % ry
- decimal xpart t & "," & % tx
- decimal ypart t % ty
- & "})" ) ;
-enddef ;
-
-vardef mfun_numeric_to_lua(expr k,n) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & "," & decimal n & ")" ) ;
-enddef ;
-
-vardef mfun_pair_to_lua(expr k,p) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
- decimal xpart p & "," &
- decimal ypart p
- & "})" ) ;
-enddef ;
-
-vardef mfun_rgbcolor_to_lua(expr k,c) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
- decimal redpart c & "," &
- decimal greenpart c & "," &
- decimal bluepart c
- & "})" ) ;
-enddef ;
-
-vardef mfun_cmykcolor_to_lua(expr k,c) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",{" &
- decimal cyanpart c & "," &
- decimal magentapart c & "," &
- decimal yellowpart c & "," &
- decimal blackpart c
- & "})" ) ;
-enddef ;
-
-vardef mfun_path_to_lua(expr k,p) =
- runscript("metapost.pushvariable(" & mfun_key_to_lua(k) & ")") ;
- for i=0 upto length(p) :
- mfun_point_to_lua(i+1,p,i) ;
- endfor ;
- runscript("metapost.popvariable()") ;
-enddef ;
-
-vardef mfun_boolean_to_lua(expr k,b) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & if b : ",true)" else : ",false)" fi ) ;
-enddef ;
-
-vardef mfun_string_to_lua(expr k,s) =
- runscript( "metapost.setvariable(" & mfun_key_to_lua(k) & ",[==[" & s & "]==])" ) ;
-enddef ;
+newscriptindex mfid_passvariable ; mfid_passvariable := scriptindex("passvariable") ;
+newscriptindex mfid_pushvariable ; mfid_pushvariable := scriptindex("pushvariable") ;
+newscriptindex mfid_popvariable ; mfid_popvariable := scriptindex("popvariable") ;
-def passvariable(expr key, value) =
- if numeric value : mfun_numeric_to_lua (key,value) ;
- elseif pair value : mfun_pair_to_lua (key,value) ;
- elseif string value : mfun_string_to_lua (key,value) ;
- elseif boolean value : mfun_boolean_to_lua (key,value) ;
- elseif path value : mfun_path_to_lua (key,value) ;
- elseif rgbcolor value : mfun_rgbcolor_to_lua (key,value) ;
- elseif cmykcolor value : mfun_cmykcolor_to_lua(key,value) ;
- elseif transform value : mfun_transform_to_lua(key,value) ;
- fi ;
-enddef ;
+def passvariable (expr key, value) = runscript mfid_passvariable key value ; enddef ;
+def startpassingvariable(expr key) = runscript mfid_pushvariable key ; enddef ;
+def stoppassingvariable = runscript mfid_popvariable ; enddef ;
def passarrayvariable(expr key)(suffix values)(expr first, last, stp) =
- runscript("metapost.pushvariable(" & mfun_key_to_lua(key) & ")") ;
+ startpassingvariable(key) ;
for i=first step stp until last :
passvariable(i, values[i]) ;
endfor
- runscript("metapost.popvariable()") ;
-enddef ;
-
-def startpassingvariable(expr k) =
- runscript("metapost.pushvariable(" & mfun_key_to_lua(k) & ")") ;
-enddef ;
-
-def stoppassingvariable =
- runscript("metapost.popvariable()") ;
+ stoppassingvariable ;
enddef ;
permanent passvariable, passarrayvariable, startpassingvariable, stoppassingvariable ;
@@ -1844,7 +1754,6 @@ permanent format, formatted ;
% def strfmt = format enddef ; % old
% def varfmt = formatted enddef ; % old
-
% def fmttext = lua.mp.formatted enddef ;
% new
@@ -1894,6 +1803,18 @@ permanent comment, report ;
% todo: use mfid_* cum suis
+newscriptindex mfid_hash_new ; mfid_hash_new := scriptindex("lmt_hash_new") ;
+newscriptindex mfid_hash_dispose ; mfid_hash_dispose := scriptindex("lmt_hash_dispose") ;
+newscriptindex mfid_hash_in ; mfid_hash_in := scriptindex("lmt_hash_in") ;
+newscriptindex mfid_hash_from ; mfid_hash_from := scriptindex("lmt_hash_from") ;
+newscriptindex mfid_hash_to ; mfid_hash_to := scriptindex("lmt_hash_to") ;
+
+def newhash = runscript mfid_hash_new enddef ;
+def disposehash (expr n) = runscript mfid_hash_dispose n enddef ;
+def inhash (expr n, key) = runscript mfid_hash_in n key enddef ;
+def fromhash (expr n, key) = runscript mfid_hash_from n key enddef ;
+def tohash (expr n, key, value) = runscript mfid_hash_to n key value enddef ;
+
vardef uniquelist(suffix list) =
% this can be optimized by passing all values at once and returning
% a result but for now this is ok .. we need an undef foo
@@ -1905,20 +1826,20 @@ vardef uniquelist(suffix list) =
i := 1 ;
j := 0 ;
fi ;
- h := lua.mp.newhash() ;
+ h := runscript mfid_hash_new ;
forever :
exitif unknown list[i] ;
- if not lua.mp.inhash(h,list[i]) :
+ if not (runscript mfid_hash_in h list[i]) :
j := j + 1 ;
list[j] := list[i] ;
- lua.mp.tohash(h,list[i]) ;
+ runscript mfid_hash_to h list[i] ;
fi ;
i := i + 1 ;
endfor ;
for n = j+1 step 1 until i-1 :
dispose(list[n])
endfor ;
- lua.mp.disposehash(h) ;
+ runscript mfid_hash_dispose h ;
enddef ;
permanent uniquelist ;
diff --git a/metapost/context/base/mpxl/mp-xbox.mpxl b/metapost/context/base/mpxl/mp-xbox.mpxl
index 2b8b94c27..08589cb93 100644
--- a/metapost/context/base/mpxl/mp-xbox.mpxl
+++ b/metapost/context/base/mpxl/mp-xbox.mpxl
@@ -5,6 +5,14 @@
% copyright : Public domain
% patched : Hans Hagen
%
+% author : Karl Berry
+% version : $Id: rboxes.mp,v 1.2 2004/09/19 21:47:11 karl Exp $
+% copyright : Public domain
+% patched : Hans Hagen
+%
+% The code is the same but I've added a boxes_ namespace for some so that we don't
+% clash with metafun.
+
% The code is the same but I've added s boxes_ namespace for soem so that we don't
% clash with metafun. Loading and initialization is now under metafun control.
@@ -13,7 +21,8 @@ if known metafun_loaded_xbox : endinput ; fi ;
newinternal boolean metafun_loaded_xbox ; metafun_loaded_xbox := true ; immutable metafun_loaded_xbox ;
% Find the length of the prefix of string s for which cond is true for each character
-% c of the prefix.
+% c of the prefix. Loading and initialization is now under metafun control. Only the
+% mpxl variant will be adapted. When needed this file will be adapted.
vardef boxes_str_prefix (expr s) (text cond) =
save i_, c; string c; i_ = 0;
@@ -295,3 +304,29 @@ if makingfigure :
boxes_init_all;
fi ;
+% Rectangular boxes with rounded corners
+
+newinternal rbox_radius ; rbox_radius := 8bp ;
+
+vardef rboxit@#(text tt) =
+ boxes_begin("boxes_the_rounded","boxes_size",@#,tt) ;
+ boxes_generic_declare (pair) _n.sw, _n.s, _n.se, _n.e, _n.ne, _n.n, _n.nw, _n.w ;
+ 0 = xpart(@#nw - @#sw) = ypart(@#se - @#sw) ;
+ 0 = xpart(@#ne - @#se) = ypart(@#ne - @#nw) ;
+ @#w = .5[@#nw,@#sw] ;
+ @#s = .5[@#sw,@#se] ;
+ @#e = .5[@#ne,@#se] ;
+ @#n = .5[@#ne,@#nw] ;
+ @#ne - @#c = @#c - @#sw = (@#dx,@#dy) + .5*(urcorner boxes_pic@# - llcorner boxes_pic@#) ;
+ boxes_end(boxes_clear,@#) ;
+enddef;
+
+def boxes_the_rounded(suffix $) =
+ save _r ; _r = min(rbox_radius, .5*ypart($.n-$.s), .5*xpart($.e-$.w));
+ $.sw + (_r,0) {right} .. {right} $.se - (_r,0) ..
+ $.se + (0,_r) {up} .. {up} $.ne - (0,_r) ..
+ $.ne - (_r,0) {left} .. {left} $.nw + (_r,0) ..
+ $.nw - (0,_r) {down} .. {down} $.sw + (0,_r) ..
+ cycle
+enddef;
+
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index 505f63b17..ba4178650 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -713,8 +713,8 @@ function scripts.context.run(ctxdata,filename)
local basename = filebasename(filename) -- use splitter
local pathname = filepathpart(filename)
--
- if not filesuffix(filename) then
- filename = addsuffix(filename,"tex")
+ if filesuffix(filename) == "" then
+ filename = fileaddsuffix(filename,"tex")
end
--
if pathname == "" and not a_global and filename ~= usedfiles.nop then
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 62212a10e..1d8f37b67 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -16,7 +16,7 @@ local lower = string.lower
local concat = table.concat
local write_nl = (logs and logs.writer) or (texio and texio.write_nl) or print
-local otlversion = 3.118
+local otlversion = 3.119
local helpinfo = [[
<?xml version="1.0"?>
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index dcfc43f5f..a4df7e1a1 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -1201,7 +1201,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38747, stripped down to: 19489
+-- original size: 38742, stripped down to: 19489
if not modules then modules={} end modules ['l-lpeg']={
version=1.001,
@@ -3285,7 +3285,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11951, stripped down to: 6430
+-- original size: 11988, stripped down to: 6430
if not modules then modules={} end modules ['l-io']={
version=1.001,
@@ -5110,7 +5110,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18253, stripped down to: 10816
+-- original size: 18217, stripped down to: 10792
if not modules then modules={} end modules ['l-dir']={
version=1.001,
@@ -5300,15 +5300,15 @@ local separator,pattern
if onwindows then
local slash=S("/\\")/"/"
pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
+ (Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ Cs(((1-S("*?/\\"))^0*slash)^0),
+ Cs(P(1)^0)
}
else
pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
+ (C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ C(((1-S("*?/"))^0*P("/"))^0),
+ C(P(1)^0)
}
end
local filter=Cs ((
@@ -7467,7 +7467,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 32815, stripped down to: 18257
+-- original size: 33089, stripped down to: 18163
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7794,9 +7794,6 @@ if JITSUPPORTED then
return concat(fastserialize(t,true))
end
else
- local f_v=formatters["[%q]=%q,"]
- local f_t=formatters["[%q]="]
- local f_q=formatters["%q,"]
function table.fastserialize(t,prefix)
local r={ type(prefix)=="string" and prefix or "return" }
local m=1
@@ -9236,7 +9233,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 24692, stripped down to: 16432
+-- original size: 24819, stripped down to: 16424
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -9285,8 +9282,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ ((escape*(left+right))+(1-(left+right))+V(2))^0,
+ left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -21547,7 +21544,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16409, stripped down to: 11591
+-- original size: 16456, stripped down to: 11636
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21593,7 +21590,7 @@ local readables={}
local usedreadables={}
local compilelua=luautilities.compile
local luasuffixes=luautilities.suffixes
-caches.base=caches.base or "luatex-cache"
+caches.base=caches.base or (LUATEXENGINE and LUATEXENGINE.."-cache") or "luatex-cache"
caches.more=caches.more or "context"
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local direct_cache=false
@@ -25935,8 +25932,8 @@ end -- of closure
-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1026528
--- stripped bytes : 402906
+-- original bytes : 1026972
+-- stripped bytes : 403431
-- end library merge
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index dcfc43f5f..a4df7e1a1 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -1201,7 +1201,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38747, stripped down to: 19489
+-- original size: 38742, stripped down to: 19489
if not modules then modules={} end modules ['l-lpeg']={
version=1.001,
@@ -3285,7 +3285,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11951, stripped down to: 6430
+-- original size: 11988, stripped down to: 6430
if not modules then modules={} end modules ['l-io']={
version=1.001,
@@ -5110,7 +5110,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18253, stripped down to: 10816
+-- original size: 18217, stripped down to: 10792
if not modules then modules={} end modules ['l-dir']={
version=1.001,
@@ -5300,15 +5300,15 @@ local separator,pattern
if onwindows then
local slash=S("/\\")/"/"
pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
+ (Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ Cs(((1-S("*?/\\"))^0*slash)^0),
+ Cs(P(1)^0)
}
else
pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
+ (C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ C(((1-S("*?/"))^0*P("/"))^0),
+ C(P(1)^0)
}
end
local filter=Cs ((
@@ -7467,7 +7467,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 32815, stripped down to: 18257
+-- original size: 33089, stripped down to: 18163
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7794,9 +7794,6 @@ if JITSUPPORTED then
return concat(fastserialize(t,true))
end
else
- local f_v=formatters["[%q]=%q,"]
- local f_t=formatters["[%q]="]
- local f_q=formatters["%q,"]
function table.fastserialize(t,prefix)
local r={ type(prefix)=="string" and prefix or "return" }
local m=1
@@ -9236,7 +9233,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 24692, stripped down to: 16432
+-- original size: 24819, stripped down to: 16424
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -9285,8 +9282,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ ((escape*(left+right))+(1-(left+right))+V(2))^0,
+ left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -21547,7 +21544,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16409, stripped down to: 11591
+-- original size: 16456, stripped down to: 11636
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21593,7 +21590,7 @@ local readables={}
local usedreadables={}
local compilelua=luautilities.compile
local luasuffixes=luautilities.suffixes
-caches.base=caches.base or "luatex-cache"
+caches.base=caches.base or (LUATEXENGINE and LUATEXENGINE.."-cache") or "luatex-cache"
caches.more=caches.more or "context"
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local direct_cache=false
@@ -25935,8 +25932,8 @@ end -- of closure
-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1026528
--- stripped bytes : 402906
+-- original bytes : 1026972
+-- stripped bytes : 403431
-- end library merge
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index dcfc43f5f..a4df7e1a1 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -1201,7 +1201,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38747, stripped down to: 19489
+-- original size: 38742, stripped down to: 19489
if not modules then modules={} end modules ['l-lpeg']={
version=1.001,
@@ -3285,7 +3285,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11951, stripped down to: 6430
+-- original size: 11988, stripped down to: 6430
if not modules then modules={} end modules ['l-io']={
version=1.001,
@@ -5110,7 +5110,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18253, stripped down to: 10816
+-- original size: 18217, stripped down to: 10792
if not modules then modules={} end modules ['l-dir']={
version=1.001,
@@ -5300,15 +5300,15 @@ local separator,pattern
if onwindows then
local slash=S("/\\")/"/"
pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
+ (Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ Cs(((1-S("*?/\\"))^0*slash)^0),
+ Cs(P(1)^0)
}
else
pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
+ (C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ C(((1-S("*?/"))^0*P("/"))^0),
+ C(P(1)^0)
}
end
local filter=Cs ((
@@ -7467,7 +7467,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 32815, stripped down to: 18257
+-- original size: 33089, stripped down to: 18163
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7794,9 +7794,6 @@ if JITSUPPORTED then
return concat(fastserialize(t,true))
end
else
- local f_v=formatters["[%q]=%q,"]
- local f_t=formatters["[%q]="]
- local f_q=formatters["%q,"]
function table.fastserialize(t,prefix)
local r={ type(prefix)=="string" and prefix or "return" }
local m=1
@@ -9236,7 +9233,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 24692, stripped down to: 16432
+-- original size: 24819, stripped down to: 16424
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -9285,8 +9282,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ ((escape*(left+right))+(1-(left+right))+V(2))^0,
+ left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -21547,7 +21544,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16409, stripped down to: 11591
+-- original size: 16456, stripped down to: 11636
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21593,7 +21590,7 @@ local readables={}
local usedreadables={}
local compilelua=luautilities.compile
local luasuffixes=luautilities.suffixes
-caches.base=caches.base or "luatex-cache"
+caches.base=caches.base or (LUATEXENGINE and LUATEXENGINE.."-cache") or "luatex-cache"
caches.more=caches.more or "context"
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local direct_cache=false
@@ -25935,8 +25932,8 @@ end -- of closure
-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1026528
--- stripped bytes : 402906
+-- original bytes : 1026972
+-- stripped bytes : 403431
-- end library merge
diff --git a/scripts/context/stubs/win64/mtxrun.lua b/scripts/context/stubs/win64/mtxrun.lua
index dcfc43f5f..a4df7e1a1 100644
--- a/scripts/context/stubs/win64/mtxrun.lua
+++ b/scripts/context/stubs/win64/mtxrun.lua
@@ -1201,7 +1201,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true
--- original size: 38747, stripped down to: 19489
+-- original size: 38742, stripped down to: 19489
if not modules then modules={} end modules ['l-lpeg']={
version=1.001,
@@ -3285,7 +3285,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-io"] = package.loaded["l-io"] or true
--- original size: 11951, stripped down to: 6430
+-- original size: 11988, stripped down to: 6430
if not modules then modules={} end modules ['l-io']={
version=1.001,
@@ -5110,7 +5110,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["l-dir"] = package.loaded["l-dir"] or true
--- original size: 18253, stripped down to: 10816
+-- original size: 18217, stripped down to: 10792
if not modules then modules={} end modules ['l-dir']={
version=1.001,
@@ -5300,15 +5300,15 @@ local separator,pattern
if onwindows then
local slash=S("/\\")/"/"
pattern={
- [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
- [2]=Cs(((1-S("*?/\\"))^0*slash)^0),
- [3]=Cs(P(1)^0)
+ (Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3),
+ Cs(((1-S("*?/\\"))^0*slash)^0),
+ Cs(P(1)^0)
}
else
pattern={
- [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
- [2]=C(((1-S("*?/"))^0*P("/"))^0),
- [3]=C(P(1)^0)
+ (C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3),
+ C(((1-S("*?/"))^0*P("/"))^0),
+ C(P(1)^0)
}
end
local filter=Cs ((
@@ -7467,7 +7467,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-tab"] = package.loaded["util-tab"] or true
--- original size: 32815, stripped down to: 18257
+-- original size: 33089, stripped down to: 18163
if not modules then modules={} end modules ['util-tab']={
version=1.001,
@@ -7794,9 +7794,6 @@ if JITSUPPORTED then
return concat(fastserialize(t,true))
end
else
- local f_v=formatters["[%q]=%q,"]
- local f_t=formatters["[%q]="]
- local f_q=formatters["%q,"]
function table.fastserialize(t,prefix)
local r={ type(prefix)=="string" and prefix or "return" }
local m=1
@@ -9236,7 +9233,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["util-prs"] = package.loaded["util-prs"] or true
--- original size: 24692, stripped down to: 16432
+-- original size: 24819, stripped down to: 16424
if not modules then modules={} end modules ['util-prs']={
version=1.001,
@@ -9285,8 +9282,8 @@ local noparent=1-(lparent+rparent)
local nobracket=1-(lbracket+rbracket)
local escape,left,right=P("\\"),P('{'),P('}')
lpegpatterns.balanced=P {
- [1]=((escape*(left+right))+(1-(left+right))+V(2))^0,
- [2]=left*V(1)*right
+ ((escape*(left+right))+(1-(left+right))+V(2))^0,
+ left*V(1)*right
}
local nestedbraces=P { lbrace*(nobrace+V(1))^0*rbrace }
local nestedparents=P { lparent*(noparent+V(1))^0*rparent }
@@ -21547,7 +21544,7 @@ do -- create closure to overcome 200 locals limit
package.loaded["data-tmp"] = package.loaded["data-tmp"] or true
--- original size: 16409, stripped down to: 11591
+-- original size: 16456, stripped down to: 11636
if not modules then modules={} end modules ['data-tmp']={
version=1.100,
@@ -21593,7 +21590,7 @@ local readables={}
local usedreadables={}
local compilelua=luautilities.compile
local luasuffixes=luautilities.suffixes
-caches.base=caches.base or "luatex-cache"
+caches.base=caches.base or (LUATEXENGINE and LUATEXENGINE.."-cache") or "luatex-cache"
caches.more=caches.more or "context"
caches.defaults={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" }
local direct_cache=false
@@ -25935,8 +25932,8 @@ end -- of closure
-- used libraries : l-bit32.lua l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-sha.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua util-soc-imp-reset.lua util-soc-imp-socket.lua util-soc-imp-copas.lua util-soc-imp-ltn12.lua util-soc-imp-mime.lua util-soc-imp-url.lua util-soc-imp-headers.lua util-soc-imp-tp.lua util-soc-imp-http.lua util-soc-imp-ftp.lua util-soc-imp-smtp.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua util-zip.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua libs-ini.lua luat-sta.lua luat-fmt.lua
-- skipped libraries : -
--- original bytes : 1026528
--- stripped bytes : 402906
+-- original bytes : 1026972
+-- stripped bytes : 403431
-- end library merge
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index aee36ce61..25e2ed4d7 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2021.08.10 12:37}
+\newcontextversion{2021.08.19 19:40}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index ec8a50d33..7d3289b97 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.08.10 12:37}
+\edef\contextversion{2021.08.19 19:40}
%D For those who want to use this:
diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii
index 50a9ea08f..9aede3730 100644
--- a/tex/context/base/mkii/mult-ro.mkii
+++ b/tex/context/base/mkii/mult-ro.mkii
@@ -151,6 +151,7 @@
\setinterfacevariable{commands}{comenzi}
\setinterfacevariable{comment}{comentariu}
\setinterfacevariable{component}{componenta}
+\setinterfacevariable{compress}{compress}
\setinterfacevariable{compressseparator}{compressseparator}
\setinterfacevariable{compressstopper}{compressstopper}
\setinterfacevariable{concept}{concept}
diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua
index 51c32ec1d..4f29e09d6 100644
--- a/tex/context/base/mkiv/back-exp.lua
+++ b/tex/context/base/mkiv/back-exp.lua
@@ -325,9 +325,9 @@ local styletemplate = [[
local numbertoallign = {
[0] = "justify", ["0"] = "justify", [variables.normal ] = "justify",
- [1] = "right", ["1"] = "right", [variables.flushright] = "right",
- [2] = "center", ["2"] = "center", [variables.middle ] = "center",
- [3] = "left", ["3"] = "left", [variables.flushleft ] = "left",
+ "right", ["1"] = "right", [variables.flushright] = "right",
+ "center", ["2"] = "center", [variables.middle ] = "center",
+ "left", ["3"] = "left", [variables.flushleft ] = "left",
}
function wrapups.allusedstyles(filename)
diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua
index 8a8ec67c7..6c844342a 100644
--- a/tex/context/base/mkiv/buff-ini.lua
+++ b/tex/context/base/mkiv/buff-ini.lua
@@ -121,6 +121,11 @@ local function exists(name)
return cache[name]
end
+local function getcontent(name)
+ local buffer = name and cache[name]
+ return buffer and buffer.data or ""
+end
+
local function empty(name)
if find(getcontent(name),"%S") then
return false
@@ -129,11 +134,6 @@ local function empty(name)
end
end
-local function getcontent(name)
- local buffer = name and cache[name]
- return buffer and buffer.data or ""
-end
-
local function getlines(name)
local buffer = name and cache[name]
return buffer and splitlines(buffer.data)
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index 61325b615..da7aa9dc0 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.08.10 12:37}
+\newcontextversion{2021.08.19 19:40}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 74e3cea56..d837240b4 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2021.08.10 12:37}
+\edef\contextversion{2021.08.19 19:40}
%D Kind of special:
diff --git a/tex/context/base/mkiv/data-tmp.lua b/tex/context/base/mkiv/data-tmp.lua
index 9a8a586cd..1948f1ea5 100644
--- a/tex/context/base/mkiv/data-tmp.lua
+++ b/tex/context/base/mkiv/data-tmp.lua
@@ -74,7 +74,7 @@ local usedreadables = { }
local compilelua = luautilities.compile
local luasuffixes = luautilities.suffixes
-caches.base = caches.base or "luatex-cache" -- can be local
+caches.base = caches.base or (LUATEXENGINE and LUATEXENGINE .. "-cache") or "luatex-cache" -- can be local
caches.more = caches.more or "context" -- can be local
caches.defaults = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" }
diff --git a/tex/context/base/mkiv/font-cft.lua b/tex/context/base/mkiv/font-cft.lua
index cf6c232a6..267c63f7a 100644
--- a/tex/context/base/mkiv/font-cft.lua
+++ b/tex/context/base/mkiv/font-cft.lua
@@ -439,7 +439,7 @@ do
},
colorschemes = {
default = {
- [1] = { t_string },
+ { t_string },
}
},
files = {
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index a72f1bf42..9bb8d4cc1 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.118
+ otf.version = otf.version or 3.119
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-ocm.lua b/tex/context/base/mkiv/font-ocm.lua
index ef0b02a14..e54799b23 100644
--- a/tex/context/base/mkiv/font-ocm.lua
+++ b/tex/context/base/mkiv/font-ocm.lua
@@ -40,16 +40,16 @@ callback.register("provide_charproc_data",function(action,f,...)
end)
local defaults = {
- [1] = function() return 0, 0 end,
- [2] = function() return 0, 0 end,
- [3] = function() return 0.001, "" end,
+ function() return 0, 0 end,
+ function() return 0, 0 end,
+ function() return 0.001, "" end,
}
local function registeractions(t)
return {
- [1] = t.preroll or defaults[1],
- [2] = t.collect or defaults[2],
- [3] = t.wrapup or defaults[3],
+ t.preroll or defaults[1],
+ t.collect or defaults[2],
+ t.wrapup or defaults[3],
}
end
diff --git a/tex/context/base/mkiv/font-osd.lua b/tex/context/base/mkiv/font-osd.lua
index a9ea878c0..b4e753182 100644
--- a/tex/context/base/mkiv/font-osd.lua
+++ b/tex/context/base/mkiv/font-osd.lua
@@ -630,7 +630,8 @@ local function initializedevanagi(tfmdata)
local h = coverage[k]
if h then
for k, v in next, h do
- found = v and v.ligature
+ -- found = v and v.ligature
+ found = v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found] = true
break
@@ -647,7 +648,8 @@ local function initializedevanagi(tfmdata)
end
else
for k, v in next, r do
- found = v and v.ligature
+ -- found = v and v.ligature
+ found = v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found] = true
break
@@ -696,7 +698,8 @@ local function initializedevanagi(tfmdata)
for k, v in next, halant do
local h = r[k]
if h then
- reph = h.ligature or false
+ -- reph = h.ligature or false
+ reph = tonumber(h) or h.ligature or false
break
end
end
@@ -713,7 +716,8 @@ local function initializedevanagi(tfmdata)
for k, v in next, halant do
local h = r[k]
if h then
- reph = h.ligature or false
+ -- reph = h.ligature or false
+ reph = tonumber(h) or h.ligature or false
break
end
end
@@ -757,7 +761,8 @@ local function initializedevanagi(tfmdata)
local h = coverage[k]
if h then
for k, v in next, h do
- found = v and v.ligature
+ -- found = v and v.ligature
+ found = v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found] = true
break
@@ -774,7 +779,8 @@ local function initializedevanagi(tfmdata)
end
else
for k, v in next, h do
- found = v and v.ligature
+ -- found = v and v.ligature
+ found = v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found] = true
break
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index 74f209b0a..ae2dda4f3 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.118 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.119 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
@@ -218,6 +218,9 @@ function otf.load(filename,sub,instance)
if cleanup == 0 then
checkmemory(used,threshold,tracememory)
end
+ if context then
+ otfreaders.condense(data)
+ end
otfreaders.pack(data)
report_otf("loading done")
report_otf("saving %a in cache",filename)
diff --git a/tex/context/base/mkiv/font-oto.lua b/tex/context/base/mkiv/font-oto.lua
index 6f5f2fb41..0f667bcc2 100644
--- a/tex/context/base/mkiv/font-oto.lua
+++ b/tex/context/base/mkiv/font-oto.lua
@@ -170,7 +170,7 @@ end
local function makefake(tfmdata,name,present)
local private = getprivate(tfmdata)
local character = { intermediate = true, ligatures = { } }
- resources.unicodes[name] = private
+ tfmdata.resources.unicodes[name] = private
tfmdata.characters[private] = character
tfmdata.descriptions[private] = { name = name }
present[name] = private
@@ -178,43 +178,55 @@ local function makefake(tfmdata,name,present)
end
local function make_1(present,tree,name)
- for k, v in next, tree do
- if k == "ligature" then
- present[name] = v
+ if tonumber(tree) then
+ present[name] = v
+ else
+ for k, v in next, tree do
+ if k == "ligature" then
+ present[name] = v
+ else
+ make_1(present,v,name .. "_" .. k)
+ end
+ end
+ end
+end
+
+local function make_3(present,tfmdata,characters,tree,name,preceding,unicode,done,v)
+ local character = characters[preceding]
+ if not character then
+ if trace_baseinit then
+ report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
+ end
+ character = makefake(tfmdata,name,present)
+ end
+ local ligatures = character.ligatures
+ if ligatures then
+ ligatures[unicode] = { char = v }
+ else
+ character.ligatures = { [unicode] = { char = v } }
+ end
+ if done then
+ local d = done[name]
+ if not d then
+ done[name] = { "dummy", v }
else
- make_1(present,v,name .. "_" .. k)
+ d[#d+1] = v
end
end
end
local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
- for k, v in next, tree do
- if k == "ligature" then
- local character = characters[preceding]
- if not character then
- if trace_baseinit then
- report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
- end
- character = makefake(tfmdata,name,present)
- end
- local ligatures = character.ligatures
- if ligatures then
- ligatures[unicode] = { char = v }
+ if tonumber(tree) then
+ make_3(present,tfmdata,characters,tree,name,preceding,unicode,done,tree)
+ else
+ for k, v in next, tree do
+ if k == "ligature" then
+ make_3(present,tfmdata,characters,tree,name,preceding,unicode,done,v)
else
- character.ligatures = { [unicode] = { char = v } }
+ local code = present[name] or unicode
+ local name = name .. "_" .. k
+ make_2(present,tfmdata,characters,v,name,code,k,done)
end
- if done then
- local d = done[name]
- if not d then
- done[name] = { "dummy", v }
- else
- d[#d+1] = v
- end
- end
- else
- local code = present[name] or unicode
- local name = name .. "_" .. k
- make_2(present,tfmdata,characters,v,name,code,k,done)
end
end
end
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index 2f8934508..3b5edebc4 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -682,15 +682,15 @@ local weights = {
}
local widths = {
- [1] = "ultracondensed",
- [2] = "extracondensed",
- [3] = "condensed",
- [4] = "semicondensed",
- [5] = "normal",
- [6] = "semiexpanded",
- [7] = "expanded",
- [8] = "extraexpanded",
- [9] = "ultraexpanded",
+ "ultracondensed",
+ "extracondensed",
+ "condensed",
+ "semicondensed",
+ "normal",
+ "semiexpanded",
+ "expanded",
+ "extraexpanded",
+ "ultraexpanded",
}
setmetatableindex(weights, function(t,k)
@@ -703,31 +703,31 @@ setmetatableindex(widths,function(t,k)
return "normal"
end)
-local panoseweights = {
- [ 0] = "normal",
- [ 1] = "normal",
- [ 2] = "verylight",
- [ 3] = "light",
- [ 4] = "thin",
- [ 5] = "book",
- [ 6] = "medium",
- [ 7] = "demi",
- [ 8] = "bold",
- [ 9] = "heavy",
- [10] = "black",
+local panoseweights = { [0] =
+ "normal",
+ "normal",
+ "verylight",
+ "light",
+ "thin",
+ "book",
+ "medium",
+ "demi",
+ "bold",
+ "heavy",
+ "black",
}
-local panosewidths = {
- [ 0] = "normal",
- [ 1] = "normal",
- [ 2] = "normal",
- [ 3] = "normal",
- [ 4] = "normal",
- [ 5] = "expanded",
- [ 6] = "condensed",
- [ 7] = "veryexpanded",
- [ 8] = "verycondensed",
- [ 9] = "monospaced",
+local panosewidths = { [0] =
+ "normal",
+ "normal",
+ "normal",
+ "normal",
+ "normal",
+ "expanded",
+ "condensed",
+ "veryexpanded",
+ "verycondensed",
+ "monospaced",
}
-- We implement a reader per table.
@@ -2522,6 +2522,10 @@ function readers.compact(fontdata)
report("the %a helper is not yet implemented","compact")
end
+function readers.condense(fontdata)
+ report("the %a helper is not yet implemented","condense")
+end
+
-- plug in
local extenders = { }
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 30d79c407..8e8be6f95 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -763,7 +763,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
while current do
local char = ischar(current,currentfont)
if char then
- local lg = ligature[char]
+ local lg = not tonumber(ligature) and ligature[char]
if lg then
stop = current
ligature = lg
@@ -776,14 +776,14 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
end
end
if stop then
- local lig = ligature.ligature
- if lig then
+ local ligature = tonumber(ligature) or ligature.ligature
+ if ligature then
if trace_ligatures then
local stopchar = getchar(stop)
- head, start = markstoligature(head,start,stop,lig)
+ head, start = markstoligature(head,start,stop,ligature)
logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
else
- head, start = markstoligature(head,start,stop,lig)
+ head, start = markstoligature(head,start,stop,ligature)
end
return head, start, true, false
else
@@ -799,7 +799,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
if skiphash and skiphash[char] then
current = getnext(current)
else
- local lg = ligature[char]
+ local lg = not tonumber(ligature) and ligature[char]
if lg then
if marks[char] then
hasmarks = true
@@ -833,20 +833,20 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
local match
if replace then
local char = ischar(replace,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match = true
end
end
if not match and pre then
local char = ischar(pre,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match = true
end
end
if not match and not pre or not replace then
local n = getnext(discfound)
local char = ischar(n,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match = true
end
end
@@ -890,24 +890,26 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
return head, start, true, true
end
end
- local lig = ligature.ligature
- if lig then
+ local ligature = tonumber(ligature) or ligature.ligature
+ if ligature then
if stop then
if trace_ligatures then
local stopchar = getchar(stop)
- -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
- logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ -- head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(ligature))
+ -- we can have a rare case of multiple disc in a lig but that makes no sense language wise but if really
+ -- needed we could backtrack if we're in a disc node
else
- -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ -- head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
end
else
-- weird but happens (in some arabic font)
resetinjection(start)
- setchar(start,lig)
+ setchar(start,ligature)
if trace_ligatures then
- logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(ligature))
end
end
return head, start, true, false
@@ -1484,7 +1486,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
current = getnext(current)
-- end
else
- local lg = ligatures[schar]
+ local lg = not tonumber(ligatures) and ligatures[schar]
if lg then
ligatures = lg
last = current
@@ -1503,7 +1505,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
end
end
end
- local ligature = ligatures.ligature
+ local ligature = tonumber(ligatures) or ligatures.ligature
if ligature then
if chainindex then
stop = last
@@ -1978,7 +1980,9 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
local chainproc = chainprocs[chainkind]
if chainproc then
local ok
- head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash)
+ -- HH: chainindex 1 added here (for KAI to check too), there are weird ligatures e.g.
+ -- char + mark -> char where mark has to disappear
+ head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,1)
if ok then
done = true
end
@@ -2471,6 +2475,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local ck = contexts[k]
local seq = ck[3]
local f = ck[4] -- first current
+local last = start
if not startchar or not seq[f][startchar] then
-- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
goto next
@@ -2481,7 +2486,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
else
local l = ck[5] -- last current
local current = start
- local last = start
+-- local last = start
-- current match
@@ -3409,7 +3414,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
while s do
local char = ischar(s,font)
if char then
- local lg = lookupmatch[char]
+ local lg = not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d = 1
@@ -3439,7 +3444,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
break
end
end
- if l and l.ligature then -- so we test for ligature
+ if l and (tonumber(l) or l.ligature) then -- so we test for ligature
lastd = d
end
-- why not: if not l then break elseif l.ligature then return d end
@@ -3580,7 +3585,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
while s do
local char = ischar(s)
if char then
- local lg = lookupmatch[char]
+ local lg = not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d = 1
@@ -3610,7 +3615,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
break
end
end
- if l and l.ligature then
+ if l and (tonumber(l) or l.ligature) then
lastd = d
end
end
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index 4e70bf936..4c3d562c2 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -44,6 +44,9 @@ directives.register("otf.checksofthyphen",function(v)
check_soft_hyphen = v -- only for testing
end)
+-- After (!) the unicodes have been resolved we compact ligature tables so before that happens
+-- we don't need to check for numbers.
+
local function replaced(list,index,replacement)
if type(list) == "number" then
return replacement
@@ -1043,6 +1046,10 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n
local function traverse(p,k,v)
if k == "ligature" then
collected[v] = { unpack(l) }
+ elseif tonumber(v) then
+ insert(l,k)
+ collected[v] = { unpack(l) }
+ remove(l)
else
insert(l,k)
for k, vv in next, v do
@@ -1230,7 +1237,6 @@ local function tabstr_flat(t)
end
local function tabstr_mixed(t) -- indexed
- local s = { }
local n = #t
if n == 0 then
return ""
@@ -1244,6 +1250,7 @@ local function tabstr_mixed(t) -- indexed
return tostring(k) -- number or string
end
else
+ local s = { }
for i=1,n do
local k = t[i]
if k == true then
@@ -1353,6 +1360,21 @@ function readers.pack(data)
end
end
+ -- local function pack_indexed(v) -- less code
+ -- local tag = concat(v," ")
+ -- local ht = h[tag]
+ -- if ht then
+ -- c[ht] = c[ht] + 1
+ -- else
+ -- ht = nt + 1
+ -- t[ht] = v
+ -- c[ht] = 1
+ -- h[tag] = ht
+ -- nt = ht
+ -- end
+ -- return ht
+ -- end
+
local function pack_mixed(v)
local tag = tabstr_mixed(v)
local ht = h[tag]
@@ -2801,6 +2823,91 @@ function readers.compact(data)
end
end
+if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then
+
+ local done = 0
+
+ local function condense_1(k,v,t)
+ if type(v) == "table" then
+ local u = false
+ local l = false
+ for k, v in next, v do
+ if k == "ligature" then
+ l = v
+ if u then
+ break
+ end
+ elseif u then
+ break
+ else
+ u = true
+ end
+ end
+ if l and not u then
+ t[k] = l
+ done = done + 1
+ end
+ if u then
+ for k, vv in next, v do
+ if k ~= "ligature" then
+ condense_1(k,vv,v)
+ end
+ end
+ end
+ end
+ end
+
+ local function condensesteps_1(lookup)
+ done = 0
+ if lookup.type == "gsub_ligature" then
+ local steps = lookup.steps
+ if steps then
+ for i=1,#steps do
+ local step = steps[i]
+ local coverage = step.coverage
+ if coverage then
+ for k, v in next, coverage do
+ if condense_1(k,v,coverage) then
+ coverage[k] = v.ligature
+ done = done + 1
+ end
+ end
+ end
+ end
+ end
+ end
+ return done
+ end
+
+ function readers.condense(data)
+ if not data or data.condensed then
+ return
+ else
+ data.condensed = true
+ end
+ local resources = data.resources
+ local condensed = 0
+ local function condense(what)
+ local lookups = resources[what]
+ if lookups then
+ for i=1,#lookups do
+ condensed = condensed + condensesteps_1(lookups[i])
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
+ end
+ end
+ condense("sequences")
+ condense("sublookups")
+ if trace_optimizations then
+ if condensed > 0 then
+ report_optimizations("%i ligatures condensed",condensed)
+ end
+ end
+ end
+
+end
+
local function mergesteps(t,k)
if k == "merged" then
local merged = { }
diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua
index d8abed329..fc987d74c 100644
--- a/tex/context/base/mkiv/font-ttf.lua
+++ b/tex/context/base/mkiv/font-ttf.lua
@@ -269,6 +269,16 @@ local function applyaxis(glyph,shape,deltas,dowidth)
else
local n1 = dpoints[d1]
local n3 = dpoints[d3]
+ -- Some day I need to figure out these extra points but
+ -- I'll wait till the standard is more clear and fonts
+ -- become better (ntg-context: fraunces.ttf > abcdef).
+ if n1 > nofpoints then
+ n1 = nofpoints
+ end
+ if n3 > nofpoints then
+ n3 = nofpoints
+ end
+ --
local p1 = points[n1]
local p3 = points[n3]
local p1x = p1[1]
diff --git a/tex/context/base/mkiv/good-gen.lua b/tex/context/base/mkiv/good-gen.lua
index cee6b3172..1747727c1 100644
--- a/tex/context/base/mkiv/good-gen.lua
+++ b/tex/context/base/mkiv/good-gen.lua
@@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['good-gen'] = {
local type, next = type, next
local lower = string.lower
-
+local filesuffix, replacesuffix = file.suffix, file.replacesuffix
local fonts = fonts
----- trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end)
@@ -134,6 +134,16 @@ function fontgoodies.filenames.resolve(name)
return fn
end
end
+ elseif filesuffix(name) == "any" then
+ -- This is a bit weird place but it's a kind of fallback option in case
+ -- we can't resolve due to a name conflict.
+ local sequence = fonts.readers.sequence
+ for i=1,#sequence do
+ local fn = replacesuffix(name,sequence[i])
+ if findfile(fn) ~= "" then
+ return fn
+ end
+ end
else
-- no lookup, just use the regular mechanism
end
diff --git a/tex/context/base/mkiv/l-dir.lua b/tex/context/base/mkiv/l-dir.lua
index 325039cb1..ac8e2f4e8 100644
--- a/tex/context/base/mkiv/l-dir.lua
+++ b/tex/context/base/mkiv/l-dir.lua
@@ -230,18 +230,18 @@ if onwindows then -- we could sanitize here
-- pattern = Ct {
pattern = {
- [1] = (Cs(P(".") + slash^1) + Cs(R("az","AZ") * P(":") * slash^0) + Cc("./")) * V(2) * V(3),
- [2] = Cs(((1-S("*?/\\"))^0 * slash)^0),
- [3] = Cs(P(1)^0)
+ (Cs(P(".") + slash^1) + Cs(R("az","AZ") * P(":") * slash^0) + Cc("./")) * V(2) * V(3),
+ Cs(((1-S("*?/\\"))^0 * slash)^0),
+ Cs(P(1)^0)
}
else -- assume unix
-- pattern = Ct {
pattern = {
- [1] = (C(P(".") + P("/")^1) + Cc("./")) * V(2) * V(3),
- [2] = C(((1-S("*?/"))^0 * P("/"))^0),
- [3] = C(P(1)^0)
+ (C(P(".") + P("/")^1) + Cc("./")) * V(2) * V(3),
+ C(((1-S("*?/"))^0 * P("/"))^0),
+ C(P(1)^0)
}
end
diff --git a/tex/context/base/mkiv/l-io.lua b/tex/context/base/mkiv/l-io.lua
index f72995abd..6bf7a97bd 100644
--- a/tex/context/base/mkiv/l-io.lua
+++ b/tex/context/base/mkiv/l-io.lua
@@ -291,7 +291,8 @@ end
io.noflines = noflines
--- inlined is faster ... beware, better use util-fil
+-- inlined is faster ... beware, better use util-fil so these are obsolete
+-- and will go
local nextchar = {
[ 4] = function(f)
diff --git a/tex/context/base/mkiv/l-lpeg.lua b/tex/context/base/mkiv/l-lpeg.lua
index 77e5cf12d..5f3bea08c 100644
--- a/tex/context/base/mkiv/l-lpeg.lua
+++ b/tex/context/base/mkiv/l-lpeg.lua
@@ -665,12 +665,12 @@ end
-- lpeg.print(lpeg.P("a","b","c"))
-- lpeg.print(lpeg.S("a","b","c"))
--- print(lpeg.counter("äáàa",lpeg.P("á") + lpeg.P("à")))
--- print(lpeg.counter("äáàa",lpeg.UP("áà")))
--- print(lpeg.counter("äáàa",lpeg.US("àá")))
--- print(lpeg.counter("äáàa",lpeg.UR("aá")))
--- print(lpeg.counter("äáàa",lpeg.UR("àá")))
--- print(lpeg.counter("äáàa",lpeg.UR(0x0000,0xFFFF)))
+-- print(lpeg.counter(lpeg.P("á") + lpeg.P("à"))("äáàa"))
+-- print(lpeg.counter(lpeg.UP("áà"))("äáàa"))
+-- print(lpeg.counter(lpeg.US("àá"))("äáàa"))
+-- print(lpeg.counter(lpeg.UR("aá"))("äáàa"))
+-- print(lpeg.counter(lpeg.UR("àá"))("äáàa"))
+-- print(lpeg.counter(lpeg.UR(0x0000,0xFFFF)))
function lpeg.is_lpeg(p)
return p and lpegtype(p) == "pattern"
diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua
index 1e91ecd56..e856ddaf4 100644
--- a/tex/context/base/mkiv/lpdf-wid.lua
+++ b/tex/context/base/mkiv/lpdf-wid.lua
@@ -25,7 +25,7 @@ if not modules then modules = { } end modules ['lpdf-wid'] = {
-- html5 media in pdf then.
--
-- See mail by Michal Vlasák to the mailing list that discusses current support in
--- viewers and also mentions a few fixes wrt embedding media.
+-- viewers and also mentions (and submitted) a few fixes wrt embedding media.
local tonumber, next = tonumber, next
local gmatch, gsub, find, lower = string.gmatch, string.gsub, string.find, string.lower
@@ -60,6 +60,7 @@ local v_auto = variables.auto
local v_embed = variables.embed
local v_max = variables.max
local v_yes = variables.yes
+local v_compress = variables.compress
local pdfconstant = lpdf.constant
local pdfnull = lpdf.null
@@ -649,6 +650,7 @@ local function insertrenderingwindow(specification)
Subtype = pdfconstant("Screen"),
P = pdfreference(pdfpagereference(page)),
A = a, -- needed in order to make the annotation clickable (i.e. don't bark)
+ T = pdfunicode(label), -- for JS
Border = bs,
C = bc,
AA = actions,
@@ -662,7 +664,7 @@ end
-- some dictionaries can have a MH (must honor) or BE (best effort) capsule
local function insertrendering(specification)
- local label = specification.label
+ local label = specification.label
local option = settings_to_hash(specification.option)
if not mf[label] then
local filename = specification.filename
@@ -693,7 +695,7 @@ local function insertrendering(specification)
-- }
-- }
local parameters = pdfdictionary {
- Type = pdfconstant(MediaPermissions),
+ Type = pdfconstant("MediaPermissions"),
TF = pdfstring("TEMPALWAYS"), -- TEMPNEVER TEMPEXTRACT TEMPACCESS TEMPALWAYS / needed for acrobat/wmp
}
local descriptor = pdfdictionary {
@@ -707,7 +709,7 @@ local function insertrendering(specification)
descriptor = codeinjections.embedfile {
file = filename,
mimetype = mimetype, -- yes or no
- compress = false,
+ compress = option[v_compress] or false,
forcereference = true,
}
end
@@ -723,7 +725,7 @@ local function insertrendering(specification)
local rendition = pdfdictionary {
Type = pdfconstant("Rendition"),
S = pdfconstant("MR"),
- N = label,
+ N = pdfunicode(label),
C = pdfreference(pdfflushobject(clip)),
}
mf[label] = pdfreference(pdfflushobject(rendition))
@@ -761,6 +763,21 @@ function codeinjections.processrendering(label)
end
end
+-- needed mapping for access from JS
+
+local function flushrenderings()
+ if next(mf) then
+ local r = pdfarray()
+ for label, reference in sortedhash(mf) do
+ r[#r+1] = pdfunicode(label)
+ r[#r+1] = reference -- already a reference
+ end
+ lpdf.addtonames("Renditions",pdfreference(pdfflushobject(pdfdictionary{ Names = r })))
+ end
+end
+
+lpdf.registerdocumentfinalizer(flushrenderings,"renderings")
+
function codeinjections.insertrenderingwindow(specification)
local label = specification.label
codeinjections.processrendering(label)
diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua
index 19bf86802..2a8129ca7 100644
--- a/tex/context/base/mkiv/math-ini.lua
+++ b/tex/context/base/mkiv/math-ini.lua
@@ -120,13 +120,13 @@ local accents = allocate {
local codes = allocate {
ordinary = 0, [0] = "ordinary",
- largeoperator = 1, [1] = "largeoperator",
- binaryoperator = 2, [2] = "binaryoperator",
- relation = 3, [3] = "relation",
- openingsymbol = 4, [4] = "openingsymbol",
- closingsymbol = 5, [5] = "closingsymbol",
- punctuation = 6, [6] = "punctuation",
- variable = 7, [7] = "variable",
+ largeoperator = 1, "largeoperator",
+ binaryoperator = 2, "binaryoperator",
+ relation = 3, "relation",
+ openingsymbol = 4, "openingsymbol",
+ closingsymbol = 5, "closingsymbol",
+ punctuation = 6, "punctuation",
+ variable = 7, "variable",
}
local extensibles = allocate {
diff --git a/tex/context/base/mkiv/math-map.lua b/tex/context/base/mkiv/math-map.lua
index 97860b923..5f93b43fc 100644
--- a/tex/context/base/mkiv/math-map.lua
+++ b/tex/context/base/mkiv/math-map.lua
@@ -689,9 +689,9 @@ local issygreek = regular_tf.symbols
local isgreek = merged(islcgreek,isucgreek,issygreek)
local greekremapping = {
- [1] = { what = "unchanged" }, -- upright
- [2] = { what = "upright", it = "tf", bi = "bf" }, -- upright
- [3] = { what = "italic", tf = "it", bf = "bi" }, -- italic
+ { what = "unchanged" }, -- upright
+ { what = "upright", it = "tf", bi = "bf" }, -- upright
+ { what = "italic", tf = "it", bf = "bi" }, -- italic
}
local usedremap = { }
diff --git a/tex/context/base/mkiv/mlib-mpf.lua b/tex/context/base/mkiv/mlib-mpf.lua
index 7452c0111..7e2a01ffb 100644
--- a/tex/context/base/mkiv/mlib-mpf.lua
+++ b/tex/context/base/mkiv/mlib-mpf.lua
@@ -247,7 +247,7 @@ do
-- writers
- local function mpp(value)
+ local function rawmpp(value)
n = n + 1
local t = type(value)
if t == "number" then
@@ -268,13 +268,13 @@ do
local function mpprint(first,second,...)
if second == nil then
if first ~= nil then
- mpp(first)
+ rawmpp(first)
end
else
for i=1,select("#",first,second,...) do
local value = (select(i,first,second,...))
if value ~= nil then
- mpp(value)
+ rawmpp(value)
end
end
end
@@ -653,6 +653,25 @@ do
for k, v in next, aux do mp[k] = v end
+ -- mp.print = table.setmetatablecall(aux, function(t,...)
+ -- mpprint(...)
+ -- end)
+
+ mp.print = table.setmetatablecall(aux, function(t,first,second,...)
+ if second == nil then
+ if first ~= nil then
+ rawmpp(first)
+ end
+ else
+ for i=1,select("#",first,second,...) do
+ local value = (select(i,first,second,...))
+ if value ~= nil then
+ rawmpp(value)
+ end
+ end
+ end
+ end)
+
end
do
diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua
index af7804506..a06deffe5 100644
--- a/tex/context/base/mkiv/mult-def.lua
+++ b/tex/context/base/mkiv/mult-def.lua
@@ -15390,6 +15390,10 @@ return {
["pe"]="eight",
["ro"]="eight",
},
+ ["compress"]={
+ ["en"]="compress",
+ ["nl"]="comprimeer",
+ },
["embed"]={
["en"]="embed",
["fr"]="integrer",
diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua
index 50ced6ead..9f6c8456c 100644
--- a/tex/context/base/mkiv/mult-fun.lua
+++ b/tex/context/base/mkiv/mult-fun.lua
@@ -189,10 +189,17 @@ return {
"setmacro", "setdimen", "setcount", "settoks",
"setglobalmacro", "setglobaldimen", "setglobalcount", "setglobaltoks",
--
- "positionpath", "positioncurve", "positionxy", "positionpxy",
- "positionwhd", "positionpage", "positionregion", "positionbox",
+ "positionpath", "positioncurve", "positionxy", "positionparagraph", "positioncolumn",
+ "positionwhd", "positionpage", "positionregion", "positionbox", "positionx", "positiony",
"positionanchor", "positioninregion", "positionatanchor",
--
+ "getposboxesv, getmultipars",
+ "getpospage", "getposparagraph", "getposcolumn", "getposregion",
+ "getposx", "getposy", "getposwidth", "getposheight", "getposdepth",
+ "getposleftskip", "getposrightskip", "getposhsize", "getposparindent", "getposhangindent", "getposhangafter",
+ "getposxy", "getposupperleft", "getposlowerleft", "getposupperright", "getposlowerright".
+ "getposllx", "getposlly", "getposurx", "getposury" ;
+ --
"wdpart", "htpart", "dppart",
--
"texvar", "texstr",
@@ -201,7 +208,7 @@ return {
--
"utfnum", "utflen", "utfsub",
--
- "newhash", "disposehash", "inhash", "tohash",
+ "newhash", "disposehash", "inhash", "tohash", "fromhash",
--
"isarray", "prefix", "isobject",
--
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index 5985faf73..59320507a 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -357,7 +357,7 @@ return {
--
"quitcondition", "truecondition", "falsecondition",
--
- "tracingall", "tracingnone", "loggingall",
+ "tracingall", "tracingnone", "loggingall", "tracingcatcodes",
"showluatokens",
--
"aliasmacro",
diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua
index 374ba8866..7828b7e56 100644
--- a/tex/context/base/mkiv/page-mix.lua
+++ b/tex/context/base/mkiv/page-mix.lua
@@ -59,7 +59,7 @@ local getnext = nuts.getnext
local getprev = nuts.getprev
local getid = nuts.getid
local getlist = nuts.getlist
-local getindex = nuts.getindex
+local getindex = nuts.getindex or nuts.getsubtype -- luatex catch
local getbox = nuts.getbox
local getattr = nuts.getattr
local getwhd = nuts.getwhd
@@ -79,6 +79,8 @@ local new_glue = nodepool.glue
local points = number.points
+local setinsertcontent = tex.setinsertcontent or tex.setbox
+
local settings_to_hash = utilities.parsers.settings_to_hash
local variables = interfaces.variables
@@ -986,9 +988,8 @@ local function getsplit(result,n)
for i=1,#list-1 do
setdepth(list[i],0)
end
- local b = vpack(l) -- multiple arguments, todo: fastvpack
--- setbox("global",c,b) -- when we wrap in a box
- tex.setinsertcontent(c,tonode(b)) -- when we wrap in a box
+ local b = vpack(l) -- multiple arguments, todo: fastvpack
+ setinsertcontent(c,tonode(b)) -- when we wrap in a box
r.inserts[c] = nil
end
diff --git a/tex/context/base/mkiv/publ-dat.lua b/tex/context/base/mkiv/publ-dat.lua
index f09e97a8d..382f70471 100644
--- a/tex/context/base/mkiv/publ-dat.lua
+++ b/tex/context/base/mkiv/publ-dat.lua
@@ -632,13 +632,13 @@ do
local r_value = reference * Carg(1) / resolve
local balanced = P {
- [1] = ((escape * (left+right)) + (collapsed + r_value + 1 - (left+right))^1 + V(2))^0,
- [2] = left * V(1) * right,
+ ((escape * (left+right)) + (collapsed + r_value + 1 - (left+right))^1 + V(2))^0,
+ left * V(1) * right,
}
-- local unbalanced = P {
- -- [1] = left * V(2) * right,
- -- [2] = ((escape * (left+right)) + (collapsed + 1 - (left+right))^1 + V(1))^0,
+ -- left * V(2) * right,
+ -- ((escape * (left+right)) + (collapsed + 1 - (left+right))^1 + V(1))^0,
-- }
local unbalanced = (left/"") * balanced * (right/"") * P(-1)
diff --git a/tex/context/base/mkiv/publ-fnd.lua b/tex/context/base/mkiv/publ-fnd.lua
index 32d0c11be..5ba173365 100644
--- a/tex/context/base/mkiv/publ-fnd.lua
+++ b/tex/context/base/mkiv/publ-fnd.lua
@@ -147,8 +147,8 @@ local p_expression = P("match")/"" * Cs(p_compare)
) / test_key_value
local pattern = Cs {
- [1] = V(2) * (p_combine * V(2))^0,
- [2] = p_expression,
+ V(2) * (p_combine * V(2))^0,
+ p_expression,
}
-- -- -- -- -- -- -- -- -- -- -- -- --
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua
index 5ab8196c8..efc157a2b 100644
--- a/tex/context/base/mkiv/spac-ver.lua
+++ b/tex/context/base/mkiv/spac-ver.lua
@@ -710,19 +710,19 @@ local function snap_topskip(current,method)
return w, 0
end
-local categories = {
- [0] = "discard",
- [1] = "largest",
- [2] = "force",
- [3] = "penalty",
- [4] = "add",
- [5] = "disable",
- [6] = "nowhite",
- [7] = "goback",
- [8] = "packed",
- [9] = "overlay",
- [10] = "enable",
- [11] = "notopskip",
+local categories = { [0] =
+ "discard",
+ "largest",
+ "force",
+ "penalty",
+ "add",
+ "disable",
+ "nowhite",
+ "goback",
+ "packed",
+ "overlay",
+ "enable",
+ "notopskip",
}
categories = allocate(table.swapped(categories,categories))
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 67e5b7a47..61569f5d1 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 42d1b8d7b..163af8eee 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/strc-syn.lua b/tex/context/base/mkiv/strc-syn.lua
index 6b50da4ac..f8b78b940 100644
--- a/tex/context/base/mkiv/strc-syn.lua
+++ b/tex/context/base/mkiv/strc-syn.lua
@@ -86,12 +86,12 @@ function synonyms.register(class,kind,spec)
local tag = definition.tag or ""
data.metadata.kind = kind -- runtime, not saved in format (yet)
if not hash[tag] then
- if definition.used == nil then
- definition.used = false
- end
- if definition.shown == nil then
- definition.shown = false
- end
+-- if definition.used == nil then
+-- definition.used = false
+-- end
+-- if definition.shown == nil then
+-- definition.shown = false
+-- end
local entries = data.entries
entries[#entries+1] = spec
hash[tag] = spec
@@ -121,24 +121,26 @@ end
function synonyms.isused(class,tag)
local data = tobesaved[class]
local okay = data.hash[tag]
- return okay and okay.definition.used
+ return okay and okay.definition.used or false
end
function synonyms.isshown(class,tag)
local data = tobesaved[class]
local okay = data.hash[tag]
- return okay and okay.definition.shown
+ return okay and okay.definition.shown or false
end
function synonyms.resetused(class)
for tag, data in next, tobesaved[class].hash do
- data.definition.used = false
+-- data.definition.used = false
+ data.definition.used = nil
end
end
function synonyms.resetshown(class)
for tag, data in next, tobesaved[class].hash do
- data.definition.shown = false
+-- data.definition.shown = false
+ data.definition.shown = nil
end
end
diff --git a/tex/context/base/mkiv/util-prs.lua b/tex/context/base/mkiv/util-prs.lua
index 7e2bf0110..6fcc66082 100644
--- a/tex/context/base/mkiv/util-prs.lua
+++ b/tex/context/base/mkiv/util-prs.lua
@@ -55,9 +55,13 @@ local nobracket = 1 - (lbracket + rbracket)
local escape, left, right = P("\\"), P('{'), P('}')
+-- lpegpatterns.balanced = P {
+-- [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
+-- [2] = left * V(1) * right
+-- }
lpegpatterns.balanced = P {
- [1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
- [2] = left * V(1) * right
+ ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
+ left * V(1) * right
}
local nestedbraces = P { lbrace * (nobrace + V(1))^0 * rbrace }
diff --git a/tex/context/base/mkiv/util-tab.lua b/tex/context/base/mkiv/util-tab.lua
index 9f7112eb9..a92b47b3f 100644
--- a/tex/context/base/mkiv/util-tab.lua
+++ b/tex/context/base/mkiv/util-tab.lua
@@ -417,9 +417,9 @@ if JITSUPPORTED then
else
- local f_v = formatters["[%q]=%q,"]
- local f_t = formatters["[%q]="]
- local f_q = formatters["%q,"]
+ -- local f_v = formatters["[%q]=%q,"]
+ -- local f_t = formatters["[%q]="]
+ -- local f_q = formatters["%q,"]
function table.fastserialize(t,prefix) -- todo, move local function out
local r = { type(prefix) == "string" and prefix or "return" }
@@ -720,6 +720,7 @@ local function serialize(root,name,specification)
local t -- = { }
local n = 1
+ -- local m = 0 -- no gain
local unknown = false
local function do_serialize(root,name,depth,level,indexed)
@@ -850,6 +851,12 @@ local function serialize(root,name,specification)
n = n + 1 t[n] = f_key_str_value_str(depth,tostring(k),tostring(v))
end
end
+ -- if n > 100000 then -- no gain
+ -- local k = m + 1
+ -- t[k] = concat(t,"\n",k,n)
+ -- n = k
+ -- m = k
+ -- end
end
end
if level > 0 then
@@ -898,6 +905,7 @@ local function serialize(root,name,specification)
n = n + 1
t[n] = f_table_finish()
return concat(t,"\n")
+ -- return concat(t,"\n",1,n) -- no gain
end
table.serialize = serialize
diff --git a/tex/context/base/mkxl/anch-bar.mkxl b/tex/context/base/mkxl/anch-bar.mkxl
index 71cc7f163..9fa9d6bf2 100644
--- a/tex/context/base/mkxl/anch-bar.mkxl
+++ b/tex/context/base/mkxl/anch-bar.mkxl
@@ -15,8 +15,6 @@
\unprotect
-%D This can be done better now ...
-
%D We will implement a sidebar mechanism using the functionality from \type
%D {core-pos}.
%D
@@ -54,6 +52,8 @@
%D \input tufte
%D \stopsidebar
%D \stoptyping
+%D
+%D This can be done better now ... maybe also by using the syncpos features.
\installcorenamespace{sidebar}
diff --git a/tex/context/base/mkxl/anch-bck.mklx b/tex/context/base/mkxl/anch-bck.mklx
index 740ed693b..5c9382a7b 100644
--- a/tex/context/base/mkxl/anch-bck.mklx
+++ b/tex/context/base/mkxl/anch-bck.mklx
@@ -97,9 +97,9 @@
\installcommandhandler \??textbackground {textbackground} \??textbackground
\appendtoks
- \frozen\instance\setuevalue{\currenttextbackground}{\groupedcommand{\starttextbackground[\currenttextbackground]}{\stoptextbackground}}%
- \frozen\instance\setuevalue{\e!start\currenttextbackground}{\starttextbackground[\currenttextbackground]}%
- \frozen\instance\setuevalue{\e!stop \currenttextbackground}{\stoptextbackground}%
+ \frozen\instance\protected\edefcsname \currenttextbackground\endcsname{\groupedcommand{\starttextbackground[\currenttextbackground]}{\stoptextbackground}}%
+ \frozen\instance\protected\edefcsname\e!start\currenttextbackground\endcsname{\starttextbackground[\currenttextbackground]}%
+ \frozen\instance\protected\edefcsname\e!stop \currenttextbackground\endcsname{\stoptextbackground}%
\to \everydefinetextbackground
\newconstant \c_anch_backgrounds_pos_state
@@ -134,9 +134,11 @@
\ifparameter#settings\or
\setupcurrenttextbackground[#settings]%
\fi
- \doifelse{\textbackgroundparameter\c!state}\v!start
+ \ifcstok{\textbackgroundparameter\c!state}\v!start
\anch_backgrounds_text_preset_yes
+ \else
\anch_backgrounds_text_preset_nop
+ \fi
\anch_backgrounds_text_start_indeed}
\def\anch_backgrounds_text_level_start
@@ -292,10 +294,8 @@
\kern\textbackgroundskip\nobreak
\fi
\fi
- \dosetleftskipadaption{\textbackgroundparameter\c!leftoffset}%
- \advance\leftskip\leftskipadaption
- \dosetleftskipadaption{\textbackgroundparameter\c!rightoffset}%
- \advance\rightskip\leftskipadaption
+ \doadaptleftskip {\textbackgroundparameter\c!leftoffset}%
+ \doadaptrightskip{\textbackgroundparameter\c!rightoffset}%
% new
\dosetraggedcommand{\textbackgroundparameter\c!align}%
\raggedcommand
diff --git a/tex/context/base/mkxl/anch-pgr.mkxl b/tex/context/base/mkxl/anch-pgr.mkxl
index 3c4dcf680..4ffedbfc3 100644
--- a/tex/context/base/mkxl/anch-pgr.mkxl
+++ b/tex/context/base/mkxl/anch-pgr.mkxl
@@ -245,7 +245,7 @@
{\dopositionaction{\currentpositionoverlay::\MPanchoridentifier}\hss}%
\ht\scratchbox\d_overlay_height
\dp\scratchbox\zeropoint
- \anch_mark_tagged_box\scratchbox\MPanchorid % needs an hbox
+ \anch_mark_tagged_box\scratchbox\MPanchorid\zerocount % needs an hbox
\box\scratchbox
\vfill}}
@@ -427,7 +427,7 @@
\def\anch_positions_meta_graphic_cleanup_range#1#2#3#4% pos tag setups
{\ifnum\MPp{#2}<\realpageno \else
- \noexpand \anch_positions_meta_graphic_handle_range_indeed{#1}{#2}{#3}{#4}%
+ \noexpand\anch_positions_meta_graphic_handle_range_indeed{#1}{#2}{#3}{#4}%
\fi}
\appendtoks
diff --git a/tex/context/base/mkxl/anch-pos.lmt b/tex/context/base/mkxl/anch-pos.lmt
index 94eb443c6..5e53406da 100644
--- a/tex/context/base/mkxl/anch-pos.lmt
+++ b/tex/context/base/mkxl/anch-pos.lmt
@@ -6,33 +6,46 @@ if not modules then modules = { } end modules ['anch-pos'] = {
license = "see context related readme files"
}
---[[ldx--
-<p>We save positional information in the main utility table. Not only
-can we store much more information in <l n='lua'/> but it's also
-more efficient.</p>
---ldx]]--
-
--- plus (extra) is obsolete but we will keep it for a while
+-- We save positional information in the main utility table. Not only can we store
+-- much more information in Lua but it's also more efficient. In the meantime these
+-- files have become quite large. In some cases that get noticed by a hickup in the
+-- start and/or finish, but that is the price we pay for progress.
+--
+-- This was the last module that got rid of directly setting scanners, with a little
+-- performance degradation but not that noticeable. It is also a module that has been
+-- on the (partial) redo list for a while.
--
--- 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
+-- We can gain a little when we group positions but then we still have to deal with
+-- regions and cells so we either end up with lots of extra small tables pointing to
+-- them and/or assembling/disassembling. I played with that and rejected the idea
+-- until I ran into a test case where we had 50.000 one line paragraphs in an eight
+-- columns setup, and there we save 25 M on a 75 M tuc file. So, I played a bit more
+-- and we can have a solution that is of similar performance for regular documents
+-- (in spite of the extra overhead) but also works ok for the large files. In normal
+-- documents it is never a problem, but there are always exceptions to the normal and
+-- often these are also cases where positions are not really used but end up in the
+-- tuc file anyway.
--
--- this is one of the first modules using scanners and we need to replace it by
--- implement and friends
+-- Currently (because we never had split tags) we do splitting at access time, which
+-- is sort of inefficient but still ok. Much of this mechanism comes from MkII where
+-- TeX was the bottleneck.
--
--- we could have namespaces, like p, page, region, columnarea, textarea but then
--- we need virtual table accessors as well as have tag/id accessors ... we don't
--- save much here (at least not now)
+-- By grouping we need to set more metatable so in the end that is also overhead
+-- but on the average we're okay because excessive serialization also comes at a price
+-- and this way we also delay some activities till the moment it is realy used (which
+-- is not always the case with positional information. We will make this transition
+-- stepwise so till we're done there will be inefficiencies and overhead.
--
--- This was the last module that got rid of directly setting scanners, with a little
--- performance degradation but not that noticeable.
+-- The pure hash based variant combined with filtering is in anch-pos.lua and previous
+-- lmt versions! That is the reference.
-local tostring, next, setmetatable, tonumber = tostring, next, setmetatable, tonumber
-local sort = table.sort
+local tostring, next, setmetatable, tonumber, rawget, rawset = tostring, next, setmetatable, tonumber, rawget, rawset
+local sort, sortedhash = table.sort, table.sortedhash
local format, gmatch = string.format, string.gmatch
-local lpegmatch = lpeg.match
+local P, R, C, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.C, lpeg.Cc, lpeg.match
local insert, remove = table.insert, table.remove
local allocate = utilities.storage.allocate
+local setmetatableindex, setmetatablenewindex = table.setmetatableindex, table.setmetatablenewindex
local report = logs.reporter("positions")
@@ -55,11 +68,11 @@ local texsetcount = tex.setcount
local texget = tex.get
local texsp = tex.sp
----- texsp = string.todimen -- because we cache this is much faster but no rounding
-
-local setmetatableindex = table.setmetatableindex
-local setmetatablenewindex = table.setmetatablenewindex
+local texgetnest = tex.getnest
+local texgetparstate = tex.getparstate
local nuts = nodes.nuts
+local tonut = nodes.tonut
local setlink = nuts.setlink
local getlist = nuts.getlist
@@ -67,8 +80,12 @@ local setlist = nuts.setlist
local getbox = nuts.getbox
local getid = nuts.getid
local getwhd = nuts.getwhd
+local setprop = nuts.setprop
+
+local getparstate = nuts.getparstate
local hlist_code = nodes.nodecodes.hlist
+local par_code = nodes.nodecodes.par
local find_tail = nuts.tail
----- hpack = nuts.hpack
@@ -85,6 +102,7 @@ local formatters = string.formatters
local collected = allocate()
local tobesaved = allocate()
+local positionsused = false
local jobpositions = {
collected = collected,
@@ -109,138 +127,707 @@ local default = { -- not r and paragraphs etc
hs = 0, -- hsize
pi = 0, -- parindent
ps = false, -- parshape
- dir = 0,
+ dir = 0, -- obsolete
+ r2l = false, -- righttoleft
}
}
local f_b_tag = formatters["b:%s"]
local f_e_tag = formatters["e:%s"]
local f_p_tag = formatters["p:%s"]
-local f_w_tag = formatters["w:%s"]
+----- f_w_tag = formatters["w:%s"]
local f_region = formatters["region:%s"]
local f_tag_three = formatters["%s:%s:%s"]
local f_tag_two = formatters["%s:%s"]
-local nofregular = 0
-local nofspecial = 0
-local splitter = lpeg.splitat(":",true)
-
-local pagedata = { }
-local columndata = setmetatableindex("table") -- per page
-local freedata = setmetatableindex("table") -- per page
-
-local function initializer()
- tobesaved = jobpositions.tobesaved
- collected = jobpositions.collected
- for tag, data in next, collected do
- local prefix, rest = lpegmatch(splitter,tag)
- if prefix == "p" then
- nofregular = nofregular + 1
- elseif prefix == "page" then
- nofregular = nofregular + 1
- pagedata[tonumber(rest) or 0] = data
- elseif prefix == "free" then
- nofspecial = nofspecial + 1
- local t = freedata[data.p or 0]
- t[#t+1] = data
- elseif prefix == "columnarea" then
- columndata[data.p or 0][data.c or 0] = data
- end
- setmetatable(data,default)
- end
- --
- local pages = structures.pages.collected
- if pages then
- local last = nil
- for p=1,#pages do
- local region = "page:" .. p
- local data = pagedata[p]
- local free = freedata[p]
- if free then
- sort(free,function(a,b) return b.y < a.y end) -- order matters !
- end
- if data then
- last = data
- last.free = free
- elseif last then
- local t = setmetatableindex({ free = free, p = p },last)
- if not collected[region] then
- collected[region] = t
+-- Because positions are set with a delay we cannot yet make the tree -- so that
+-- is a finalizer step. But, we already have a dual split.
+
+-- local treemode = false
+local treemode = true
+
+local function checkshapes(s)
+ for p, data in next, s do
+ local n = #data
+ if n > 1 then
+ local d1 = data[1]
+ local ph = d1[2]
+ local pd = d1[3]
+ local xl = d1[4]
+ local xr = d1[5]
+ for i=2,n do
+ local di = data[i]
+ local h = di[2]
+ local d = di[3]
+ local l = di[4]
+ local r = di[5]
+ if r == xr then
+ di[5] = nil
+ if l == xl then
+ di[4] = nil
+ if d == pd then
+ di[3] = nil
+ if h == ph then
+ di[2] = nil
+ else
+ ph = h
+ end
+ else
+ pd, ph = d, h
+ end
+ else
+ ph, pd, xl = h, d, l
+ end
else
- -- something is wrong
+ ph, pd, xl, xr = h, d, l, r
end
- pagedata[p] = t
end
end
end
- jobpositions.pagedata = pagedata
end
-function jobpositions.used()
- return next(collected) -- we can safe it
-end
+local columndata = { }
+local freedata = { } -- we can make these weak
+local syncdata = { } -- we can make these weak
+local columndone = false
-function jobpositions.getfree(page)
- return freedata[page]
-end
+if treemode then
--- we can gain a little when we group positions but then we still have to
--- deal with regions and cells so we either end up with lots of extra small
--- tables pointing to them and/or assembling/disassembling so in the end
--- it makes no sense to do it (now) and still have such a mix
---
--- proof of concept code removed ... see archive
-
-local function finalizer()
- -- We make the (possible extensive) shape lists sparse working
- -- from the end. We could also drop entries here that have l and
- -- r the same which saves testing later on.
- for k, v in next, tobesaved do
- local s = v.s
- if s then
- for p, data in next, s do
- local n = #data
- if n > 1 then
- local ph = data[1][2]
- local pd = data[1][3]
- local xl = data[1][4]
- local xr = data[1][5]
- for i=2,n do
- local di = data[i]
- local h = di[2]
- local d = di[3]
- local l = di[4]
- local r = di[5]
- if r == xr then
- di[5] = nil
- if l == xl then
- di[4] = nil
- if d == pd then
- di[3] = nil
- if h == ph then
- di[2] = nil
- else
- ph = h
+ -- At some point we can install extra ones. I actually was halfway making a more
+ -- general installer but we have quite some distinct handling down here and it
+ -- became messy. So I rolled that back. Also, users and modules will quite likely
+ -- stay in the "user" namespace.
+
+ -- syncpos : indirect access via helper, todo after we switch: direct setters
+ -- free : indirect access via helper, todo after we switch: direct setters
+ -- columnarea : indirect access via helper, todo after we switch: direct setters
+
+ -- todo: keep track of total and check that against # (sanity check)
+
+ local prefix_number = { "text", "textarea", "page", "p", "free", "columnarea" }
+ local prefix_label_number = { "syncpos" }
+ local prefix_number_rest = { "region", "b", "e" }
+
+ -- no need to split: syncpos free columnarea (textarea?)
+
+ local function splitter_pattern()
+ local p_number = R("09")^1/tonumber
+ local p_colon = P(":")
+ local p_label = C(P(1 - p_colon)^0)
+ local p_rest = C(P(1)^0)
+ return
+ C(lpeg.utfchartabletopattern(prefix_number )) * p_colon * p_number * P(-1)
+ + C(lpeg.utfchartabletopattern(prefix_label_number)) * p_colon * (p_number + p_label) * p_colon * p_number * P(-1)
+ + C(lpeg.utfchartabletopattern(prefix_number_rest )) * p_colon * (p_number + p_rest)
+ + Cc("user") * p_rest
+ end
+
+ -- In the end these metatable entries are not more efficient than copying
+ -- but it's all about making sure that the tuc file doesn't explode.
+
+ columndata = { }
+ columndone = false
+
+ local deltapacking = true -- so we can see the difference
+
+ local function checkcommondata(v,common)
+ if common then
+ local i = v.i
+ local t = common[i]
+ if t then
+ local m = t.mt
+ if not m then
+ setmetatable(t,default)
+ m = { __index = t }
+ t.mt = m
+ end
+ setmetatable(v,m)
+ return
+ end
+ end
+ setmetatable(v,default)
+ end
+
+ local function initializer()
+ tobesaved = jobpositions.tobesaved
+ collected = jobpositions.collected
+ --
+ local p_splitter = splitter_pattern()
+ --
+ local list = nil
+ --
+ local shared = setmetatableindex(rawget(collected,"shared"),"table")
+ local x_y_w_h_list = shared.x_y_w_h
+ local y_w_h_d_list = shared.y_w_h_d
+ local x_h_d_list = shared.x_h_d
+ local x_h_d_hs_list = shared.x_h_d_hs
+ --
+ columndata = setmetatableindex(function(t,k)
+ setmetatableindex(t,"table")
+ list = rawget(collected,"columnarea")
+ if list then
+ -- for tag, data in next, list do
+ for i=1,#list do
+ local data = list[i]
+ columndata[data.p or 0][data.c or 0] = data
+ checkcommondata(data,y_w_h_d_list)
+ end
+ end
+ columndone = true
+ return t[k]
+ end)
+ --
+ -- todo: use a raw collected and a weak proxy
+ --
+ setmetatableindex(collected,function(t,k)
+ local prefix, one, two = lpegmatch(p_splitter,k)
+ local list = rawget(t,prefix)
+ if list and type(list) == "table" then
+ v = list[one] or false
+ if v then
+ if prefix == "p" then
+ if deltapacking and type(v) == "number" then
+ for i=one,1,-1 do
+ local l = list[i]
+ if type(l) ~= "number" then
+ if not getmetatable(l) then
+ checkcommondata(l,x_h_d_hs_list)
end
- else
- pd, ph = d, h
+ v = setmetatable({ y = v }, { __index = l })
+ list[one] = v
+ break
+ end
+ end
+ else
+ checkcommondata(v,x_h_d_hs_list)
+ end
+ elseif prefix == "text" or prefix == "textarea" then
+ if type(v) == "number" then
+ for i=one,1,-1 do
+ local l = list[i]
+ if type(l) ~= "number" then
+ if not getmetatable(l) then
+ checkcommondata(l,x_y_w_h_list)
+ end
+ v = setmetatable({ p = p }, { __index = l })
+ list[one] = v
+ break
end
- else
- ph, pd, xl = h, d, l
end
else
- ph, pd, xl, xr = h, d, l, r
+ checkcommondata(v,x_y_w_h_list)
+ end
+ elseif prefix == "columnarea" then
+ if not columndone then
+ checkcommondata(v,y_w_h_d_list)
+ end
+ elseif prefix == "syncpos" then
+ -- will become an error
+ if two then
+ -- v = syncdata[one][two] or { }
+ v = v[two] or { }
+ else
+ v = { }
+ end
+ -- for j=1,#v do
+ -- checkcommondata(v[j],x_h_d_list)
+ -- end
+ elseif prefix == "free" then
+ -- will become an error
+ elseif prefix == "page" then
+ checkcommondata(v)
+ else
+ checkcommondata(v)
+ end
+ else
+ if prefix == "page" then
+ for i=one,1,-1 do
+ local data = list[i]
+ if data then
+ v = setmetatableindex({ free = free or false, p = p },last)
+ list[one] = v
+ break
+ end
+ end
+ end
+ end
+ t[k] = v
+ return v
+ else
+ t[k] = false
+ return false
+ end
+ end)
+ --
+ setmetatableindex(tobesaved,function(t,k)
+ local prefix, one, two = lpegmatch(p_splitter,k)
+ local v = rawget(t,prefix)
+ if v and type(v) == "table" then
+ v = v[one]
+ if v and two then
+ v = v[two]
+ end
+ return v -- or default
+ else
+ -- return default
+ end
+ end)
+ --
+ setmetatablenewindex(tobesaved,function(t,k,v)
+ local prefix, one, two = lpegmatch(p_splitter,k)
+ local p = rawget(t,prefix)
+ if not p then
+ p = { }
+ rawset(t,prefix,p)
+ end
+ if type(one) == "number" then -- maybe Cc(0 1 2)
+ if #p < one then
+ for i=#p+1,one-1 do
+ p[i] = { } -- false
+ end
+ end
+ end
+ if two then
+ local pone = p[one]
+ if not pone then
+ pone = { }
+ p[one] = pone
+ end
+ if type(two) == "number" then -- maybe Cc(0 1 2)
+ if #pone < two then
+ for i=#pone+1,two-1 do
+ pone[i] = { } -- false
+ end
+ end
+ end
+ pone[two] = v
+ else
+ p[one] = v
+ end
+ end)
+ --
+ syncdata = setmetatableindex(function(t,category)
+ -- p's and y's are not shared so no need to resolve
+ local list = rawget(collected,"syncpos")
+ local tc = list and rawget(list,category)
+ if tc then
+ sort(tc,function(a,b)
+ local ap = a.p
+ local bp = b.p
+ if ap == bp then
+ return b.y < a.y
+ else
+ return ap < bp
+ end
+ end)
+ tc.start = 1
+ for i=1,#tc do
+ checkcommondata(tc[i],x_h_d_list)
+ end
+ else
+ tc = { }
+ end
+ t[category] = tc
+ return tc
+ end)
+ --
+ for k, v in next, collected do
+ if k ~= "shared" and next(v) then
+ positionsused = true
+ break
+ end
+ end
+ end
+
+ function jobpositions.used()
+ return positionsused
+ end
+
+ local function finalizer()
+
+ -- We make the (possible extensive) shape lists sparse working from the end. We
+ -- could also drop entries here that have l and r the same which saves testing
+ -- later on.
+
+ local nofpositions = 0
+ local nofpartials = 0
+ local nofdeltas = 0
+ --
+ local x_y_w_h_size = 0
+ local x_y_w_h_list = { }
+ local x_y_w_h_hash = setmetatableindex(function(t,x)
+ local y = setmetatableindex(function(t,y)
+ local w = setmetatableindex(function(t,w)
+ local h = setmetatableindex(function(t,h)
+ x_y_w_h_size = x_y_w_h_size + 1
+ t[h] = x_y_w_h_size
+ x_y_w_h_list[x_y_w_h_size] = { x = x, y = y, w = w, h = h }
+ return x_y_w_h_size
+ end)
+ t[w] = h
+ return h
+ end)
+ t[y] = w
+ return w
+ end)
+ t[x] = y
+ return y
+ end)
+ --
+ local y_w_h_d_size = 0
+ local y_w_h_d_list = { }
+ local y_w_h_d_hash = setmetatableindex(function(t,y)
+ local w = setmetatableindex(function(t,w)
+ local h = setmetatableindex(function(t,h)
+ local d = setmetatableindex(function(t,d)
+ y_w_h_d_size = y_w_h_d_size + 1
+ t[d] = y_w_h_d_size
+ y_w_h_d_list[y_w_h_d_size] = { y = y, w = w, h = h, d = d }
+ return y_w_h_d_size
+ end)
+ t[h] = d
+ return d
+ end)
+ t[w] = h
+ return h
+ end)
+ t[y] = w
+ return w
+ end)
+ --
+ local x_h_d_size = 0
+ local x_h_d_list = { }
+ local x_h_d_hash = setmetatableindex(function(t,x)
+ local h = setmetatableindex(function(t,h)
+ local d = setmetatableindex(function(t,d)
+ x_h_d_size = x_h_d_size + 1
+ t[d] = x_h_d_size
+ x_h_d_list[x_h_d_size] = { x = x, h = h, d = d }
+ return x_h_d_size
+ end)
+ t[h] = d
+ return d
+ end)
+ t[x] = h
+ return h
+ end)
+ --
+ local x_h_d_hs_size = 0
+ local x_h_d_hs_list = { }
+ local x_h_d_hs_hash = setmetatableindex(function(t,x)
+ local h = setmetatableindex(function(t,h)
+ local d = setmetatableindex(function(t,d)
+ local hs = setmetatableindex(function(t,hs)
+ x_h_d_hs_size = x_h_d_hs_size + 1
+ t[hs] = x_h_d_hs_size
+ x_h_d_hs_list[x_h_d_hs_size] = { x = x, h = h, d = d, hs = hs }
+ return x_h_d_hs_size
+ end)
+ t[d] = hs
+ return hs
+ end)
+ t[h] = d
+ return d
+ end)
+ t[x] = h
+ return h
+ end)
+ --
+ rawset(tobesaved,"shared", {
+ x_y_w_h = x_y_w_h_list,
+ y_w_h_d = y_w_h_d_list,
+ x_h_d = x_h_d_list,
+ x_h_d_hs = x_h_d_hs_list,
+ })
+ --
+ -- If fonts can use crazy and hard to grasp packing tricks so can we. The "i" field
+ -- refers to a shared set of values. In addition we pack some sequences.
+ --
+ -- how about free
+ --
+ for k, v in sortedhash(tobesaved) do
+ if k == "p" then
+ -- numeric
+ local n = #v
+ for i=1,n do
+ local t = v[i]
+ local hsh = x_h_d_hs_hash[t.x or 0][t.h or 0][t.d or 0][t.hs or 0]
+ t.x = nil
+ t.h = nil
+ t.d = nil
+ t.hs = nil -- not in syncpos
+ t.i = hsh
+ local s = t.s
+ if s then
+ checkshapes(s)
+ end
+ end
+ if deltapacking then
+ -- delta packing (y)
+ local last
+ local current
+ for i=1,n do
+ current = v[i]
+ if last then
+ for k, v in next, last do
+ if k ~= "y" and v ~= current[k] then
+ goto DIFFERENT
+ end
+ end
+ for k, v in next, current do
+ if k ~= "y" and v ~= last[k] then
+ goto DIFFERENT
+ end
+ end
+ v[i] = current.y or 0
+ nofdeltas = nofdeltas + 1
+ goto CONTINUE
+ end
+ ::DIFFERENT::
+ last = current
+ ::CONTINUE::
+ end
+ end
+ --
+ nofpositions = nofpositions + n
+ nofpartials = nofpartials + n
+ elseif k == "syncpos" then
+ -- hash
+ for k, t in next, v do
+ -- numeric
+ local n = #t
+ for j=1,n do
+ local t = t[j]
+ local hsh = x_h_d_hash[t.x or 0][t.h or 0][t.d or 0]
+ t.x = nil
+ t.h = nil
+ t.d = nil
+ t.i = hsh
+ end
+ nofpositions = nofpositions + n
+ nofpartials = nofpartials + n
+ end
+ elseif k == "text" or k == "textarea" then
+ -- numeric
+ local n = #v
+ for i=1,n do
+ local t = v[i]
+ local hsh = x_y_w_h_hash[t.x or 0][t.y or 0][t.w or 0][t.h or 0]
+ t.x = nil
+ t.y = nil
+ t.w = nil
+ t.h = nil
+ t.i = hsh
+ end
+ nofpositions = nofpositions + n
+ nofpartials = nofpartials + n
+ if deltapacking then
+ -- delta packing (p)
+ local last
+ local current
+ for i=1,n do
+ current = v[i]
+ if last then
+ for k, v in next, last do
+ if k ~= "p" and v ~= current[k] then
+ goto DIFFERENT
+ end
+ end
+ for k, v in next, current do
+ if k ~= "p" and v ~= last[k] then
+ goto DIFFERENT
+ end
+ end
+ v[i] = current.p or 0
+ nofdeltas = nofdeltas + 1
+ goto CONTINUE
end
+ ::DIFFERENT::
+ last = current
+ ::CONTINUE::
end
end
+ elseif k == "columnarea" then
+ -- numeric
+ local n = #v
+ for i=1,n do
+ local t = v[i]
+ local hsh = y_w_h_d_hash[t.y or 0][t.w or 0][t.h or 0][t.d or 0]
+ t.y = nil
+ t.w = nil
+ t.h = nil
+ t.d = nil
+ t.i = hsh
+ end
+ nofpositions = nofpositions + n
+ nofpartials = nofpartials + n
+ else -- probably only b has shapes
+ for k, t in next, v do -- no need to sort
+ local s = t.s
+ if s then
+ checkshapes(s)
+ end
+ nofpositions = nofpositions + 1
+ end
end
end
+
+ statistics.register("positions", function()
+ if nofpositions > 0 then
+ return format("%s collected, %i deltas, %i shared partials, %i partial entries",
+ nofpositions, nofdeltas, nofpartials,
+ x_y_w_h_size + y_w_h_d_size + x_h_d_size + x_h_d_hs_size
+ )
+ else
+ return nil
+ end
+ end)
+
end
+
+ freedata = setmetatableindex(function(t,page)
+ local list = rawget(collected,"free")
+ local free = { }
+ if list then
+ local size = 0
+ for i=1,#list do
+ local l = list[i]
+ if l.p == page then
+ size = size + 1
+ free[size] = l
+ checkcommondata(l)
+ end
+ end
+ sort(free,function(a,b) return b.y < a.y end) -- order matters !
+ end
+ t[page] = free
+ return free
+ end)
+
+ job.register('job.positions.collected', tobesaved, initializer, finalizer)
+
+else
+
+ columndata = setmetatableindex("table") -- per page
+ freedata = setmetatableindex("table") -- per page
+
+ local function initializer()
+ tobesaved = jobpositions.tobesaved
+ collected = jobpositions.collected
+ --
+ local pagedata = { }
+ local p_splitter = lpeg.splitat(":",true)
+
+ for tag, data in next, collected do
+ local prefix, rest = lpegmatch(p_splitter,tag)
+ if prefix == "page" then
+ pagedata[tonumber(rest) or 0] = data
+ elseif prefix == "free" then
+ local t = freedata[data.p or 0]
+ t[#t+1] = data
+ elseif prefix == "columnarea" then
+ columndata[data.p or 0][data.c or 0] = data
+ end
+ setmetatable(data,default)
+ end
+ local pages = structures.pages.collected
+ if pages then
+ local last = nil
+ for p=1,#pages do
+ local region = "page:" .. p
+ local data = pagedata[p]
+ local free = freedata[p]
+ if free then
+ sort(free,function(a,b) return b.y < a.y end) -- order matters !
+ end
+ if data then
+ last = data
+ last.free = free
+ elseif last then
+ local t = setmetatableindex({ free = free, p = p },last)
+ if not collected[region] then
+ collected[region] = t
+ else
+ -- something is wrong
+ end
+ pagedata[p] = t
+ end
+ end
+ end
+ jobpositions.pagedata = pagedata -- never used
+
+ end
+
+ local function finalizer()
+
+ -- We make the (possible extensive) shape lists sparse working from the end. We
+ -- could also drop entries here that have l and r the same which saves testing
+ -- later on.
+
+ local nofpositions = 0
+
+ for k, v in next, tobesaved do
+ local s = v.s
+ if s then
+ checkshapes(s)
+ end
+ nofpositions = nofpositions + 1
+ end
+
+ statistics.register("positions", function()
+ if nofpositions > 0 then
+ return format("%s collected",nofpositions)
+ else
+ return nil
+ end
+ end)
+
+ end
+
+ local p_number = lpeg.patterns.cardinal/tonumber
+ local p_tag = P("syncpos:") * p_number * P(":") * p_number
+
+ syncdata = setmetatableindex(function(t,category)
+ setmetatable(t,nil)
+ for tag, pos in next, collected do
+ local c, n = lpegmatch(p_tag,tag)
+ if c then
+ local tc = t[c]
+ if tc then
+ tc[n] = pos
+ else
+ t[c] = { [n] = pos }
+ end
+ end
+ end
+ for k, list in next, t do
+ sort(list,function(a,b)
+ local ap = a.p
+ local bp = b.p
+ if ap == bp then
+ return b.y < a.y
+ else
+ return ap < bp
+ end
+ end)
+ list.start = 1
+ end
+ return t[category]
+ end)
+
+ job.register('job.positions.collected', tobesaved, initializer, finalizer)
+
+end
+
+function jobpositions.getfree(page)
+ return freedata[page]
end
-job.register('job.positions.collected', tobesaved, initializer, finalizer)
+function jobpositions.getsync(category)
+ return syncdata[category] or { }
+end
local regions = { }
local nofregions = 0
@@ -491,7 +1078,6 @@ local function e_region(specification)
local last = tobesaved[region]
if last then
local y = getvpos()
- local x, y = getpos()
if specification.correct then
local h = (last.y or 0) - y
last.h = h ~= 0 and h or nil
@@ -507,13 +1093,22 @@ jobpositions.e_region = e_region
local lastregion
-local function setregionbox(n,tag,k,lo,ro,to,bo,column) -- kind
+local function setregionbox(n,tag,index,k,lo,ro,to,bo,column) -- kind
if not tag or tag == "" then
nofregions = nofregions + 1
- tag = f_region(nofregions)
+ tag = "region"
+ index = nofregions
+ elseif index ~= 0 then
+ -- So we can cheat and pass a zero index and enforce tag as is needed in
+ -- cases where we fallback on automated region tagging (framed).
+ tag = tag .. ":" .. index
end
local box = getbox(n)
local w, h, d = getwhd(box)
+ -- We could set directly but then we also need to check for gaps but as this
+ -- is direct is is unlikely that we get a gap. We then also need to intecept
+ -- these auto regions (comning from framed). Too messy and the split in the
+ -- setter is fast enough.
tobesaved[tag] = {
-- p = texgetcount("realpageno"), -- we copy them
x = 0,
@@ -532,8 +1127,18 @@ local function setregionbox(n,tag,k,lo,ro,to,bo,column) -- kind
return tag, box
end
-local function markregionbox(n,tag,correct,...) -- correct needs checking
- local tag, box = setregionbox(n,tag,...)
+-- we can have a finalizer property that we catch in the backend but that demands
+-- a check for property for each list .. what is the impact
+
+-- textarea operates *inside* a box so experiments with pre/post hooks in the
+-- backend driver didn't work out (because a box can be larger)
+--
+-- it also gives no gain to split prefix and number here because in the end we
+-- push and pop tags as strings, but it save a little on expansion so we do it
+-- in the interface
+
+local function markregionbox(n,tag,index,correct,...) -- correct needs checking
+ local tag, box = setregionbox(n,tag,index,...)
-- todo: check if tostring is needed with formatter
local push = new_latelua { action = b_region, tag = tag }
local pop = new_latelua { action = e_region, correct = correct }
@@ -577,195 +1182,290 @@ function jobpositions.settobesaved(name,tag,data)
end
end
-local nofparagraphs = 0
+do
-implement {
- name = "parpos",
- actions = function()
- nofparagraphs = nofparagraphs + 1
- texsetcount("global","c_anch_positions_paragraph",nofparagraphs)
- local box = getbox("strutbox")
- local w, h, d = getwhd(box)
- local t = {
- p = true,
- c = true,
- r = true,
- x = true,
- y = true,
- h = h,
- d = d,
- hs = texget("hsize"), -- never 0
- }
- local leftskip = texget("leftskip",false)
- local rightskip = texget("rightskip",false)
- local hangindent = texget("hangindent")
- local hangafter = texget("hangafter")
- local parindent = texget("parindent")
- local parshape = texget("parshape")
- if leftskip ~= 0 then
- t.ls = leftskip
- end
- if rightskip ~= 0 then
- t.rs = rightskip
- end
- if hangindent ~= 0 then
- t.hi = hangindent
+ local nofparagraphs = 0
+
+ local function enhancepar_1(data)
+ if data then
+ local par = data.par -- we can pass twice when we copy
+ local state = par and getparstate(data.par,true)
+ if state then
+ local x, y = getpos()
+ if x ~= 0 then
+ data.x = x
+ end
+ if y ~= 0 then
+ data.y = y
+ end
+ data.p = texgetcount("realpageno") -- we should use a variable set in otr
+ if column then
+ data.c = column
+ end
+ if region then
+ data.r = region
+ end
+ --
+ data.par = nil
+ local leftskip = state.leftskip
+ local rightskip = state.rightskip
+ local hangindent = state.hangindent
+ local hangafter = state.hangafter
+ local parindent = state.parindent
+ local parshape = state.parshape
+ if hangafter ~= 0 and hangafter ~= 1 then
+ data.ha = hangafter
+ end
+ if hangindent ~= 0 then
+ data.hi = hangindent
+ end
+ data.hs = state.hsize
+ if leftskip ~= 0 then
+ data.ls = leftskip
+ end
+ if parindent ~= 0 then
+ data.pi = parindent
+ end
+ if rightskip ~= 0 then
+ data.rs = rightskip
+ end
+ if parshape and #parshape > 0 then
+ data.ps = parshape
+ end
+ end
end
- if hangafter ~= 1 and hangafter ~= 0 then -- can not be zero .. so it needs to be 1 if zero
- t.ha = hangafter
+ return data
+ end
+
+ local function enhancepar_2(data)
+ if data then
+ local x, y = getpos()
+ if x ~= 0 then
+ data.x = x
+ end
+ if y ~= 0 then
+ data.y = y
+ end
+ data.p = texgetcount("realpageno") -- we should use a variable set in otr
+ if column then
+ data.c = column
+ end
+ if region then
+ data.r = region
+ end
end
- if parindent ~= 0 then
- t.pi = parindent
+ return data
+ end
+
+ implement {
+ name = "parpos",
+ actions = function()
+ nofparagraphs = nofparagraphs + 1
+ texsetcount("global","c_anch_positions_paragraph",nofparagraphs)
+ local name = f_p_tag(nofparagraphs)
+ local box = getbox("strutbox")
+ local w, h, d = getwhd(box)
+ --
+ local top = texgetnest("top","head")
+ local nxt = top.next
+ if nxt then
+ nxt = tonut(nxt)
+ end
+ local data
+ if nxt and getid(nxt) == par_code then -- todo: check node type
+ local t = {
+ h = h,
+ d = d,
+ par = nxt,
+ }
+ tobesaved[name] = t
+ ctx_latelua { action = enhancepar_1, specification = t }
+ else
+ -- This is kind of weird but it happens in tables (rows) so we probably
+ -- need less.
+ local state = texgetparstate()
+ local leftskip = state.leftskip
+ local rightskip = state.rightskip
+ local hangindent = state.hangindent
+ local hangafter = state.hangafter
+ local parindent = state.parindent
+ local parshape = state.parshape
+ local t = {
+ p = true,
+ c = true,
+ r = true,
+ x = true,
+ y = true,
+ h = h,
+ d = d,
+ hs = state.hsize, -- never 0
+ }
+ if leftskip ~= 0 then
+ t.ls = leftskip
+ end
+ if rightskip ~= 0 then
+ t.rs = rightskip
+ end
+ if hangindent ~= 0 then
+ t.hi = hangindent
+ end
+ if hangafter ~= 1 and hangafter ~= 0 then -- can not be zero .. so it needs to be 1 if zero
+ t.ha = hangafter
+ end
+ if parindent ~= 0 then
+ t.pi = parindent
+ end
+ if parshape and #parshape > 0 then
+ t.ps = parshape
+ end
+ tobesaved[name] = t
+ ctx_latelua { action = enhancepar_2, specification = t }
+ end
end
- if parshape and #parshape > 0 then
- t.ps = parshape
+ }
+
+ implement {
+ name = "dosetposition",
+ arguments = "argument",
+ public = true,
+ protected = true,
+ actions = function(name)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetinteger("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
end
- local name = f_p_tag(nofparagraphs)
- tobesaved[name] = t
- ctx_latelua { action = enhance, specification = t }
- end
-}
+ }
-implement {
- name = "dosetposition",
- arguments = "argument",
- public = true,
- protected = true,
- actions = function(name)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetinteger("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
- end
-}
+ implement {
+ name = "dosetpositionwhd",
+ arguments = { "argument", "dimenargument", "dimenargument", "dimenargument" },
+ public = true,
+ protected = true,
+ actions = function(name,w,h,d)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ w = w ~= 0 and w or nil,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetinteger("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+ }
-implement {
- name = "dosetpositionwhd",
- arguments = { "argument", "dimenargument", "dimenargument", "dimenargument" },
- public = true,
- protected = true,
- actions = function(name,w,h,d)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- w = w ~= 0 and w or nil,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetinteger("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
- end
-}
+ implement {
+ name = "dosetpositionbox",
+ arguments = { "argument", "integerargument" },
+ public = true,
+ protected = true,
+ actions = function(name,n)
+ local box = getbox(n)
+ local w, h, d = getwhd(box)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ w = w ~= 0 and w or nil,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetinteger("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+ }
-implement {
- name = "dosetpositionbox",
- arguments = { "argument", "integerargument" },
- public = true,
- protected = true,
- actions = function(name,n)
- local box = getbox(n)
- local w, h, d = getwhd(box)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- w = w ~= 0 and w or nil,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetinteger("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
- end
-}
+ implement {
+ name = "dosetpositionplus",
+ arguments = { "argument", "dimenargument", "dimenargument", "dimenargument" },
+ public = true,
+ protected = true,
+ actions = function(name,w,h,d)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ w = w ~= 0 and w or nil,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ e = scanstring(),
+ r2l = texgetinteger("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+ }
-implement {
- name = "dosetpositionplus",
- arguments = { "argument", "dimenargument", "dimenargument", "dimenargument" },
- public = true,
- protected = true,
- actions = function(name,w,h,d)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- w = w ~= 0 and w or nil,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- e = scanstring(),
- r2l = texgetinteger("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
- end
-}
+ implement {
+ name = "dosetpositionstrut",
+ arguments = "argument",
+ public = true,
+ protected = true,
+ actions = function(name)
+ local box = getbox("strutbox")
+ local w, h, d = getwhd(box)
+ local spec = {
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetinteger("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+ }
-implement {
- name = "dosetpositionstrut",
- arguments = "argument",
- public = true,
- protected = true,
- actions = function(name)
- local box = getbox("strutbox")
- local w, h, d = getwhd(box)
- local spec = {
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetinteger("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
- end
-}
+ implement {
+ name = "dosetpositionstrutkind",
+ arguments = { "argument", "integerargument" },
+ public = true,
+ protected = true,
+ actions = function(name,kind)
+ local box = getbox("strutbox")
+ local w, h, d = getwhd(box)
+ local spec = {
+ k = kind,
+ p = true,
+ c = column,
+ r = true,
+ x = true,
+ y = true,
+ h = h ~= 0 and h or nil,
+ d = d ~= 0 and d or nil,
+ n = nofparagraphs > 0 and nofparagraphs or nil,
+ r2l = texgetinteger("inlinelefttoright") == 1 or nil,
+ }
+ tobesaved[name] = spec
+ ctx_latelua { action = enhance, specification = spec }
+ end
+ }
-implement {
- name = "dosetpositionstrutkind",
- arguments = { "argument", "integerargument" },
- public = true,
- protected = true,
- actions = function(name,kind)
- local box = getbox("strutbox")
- local w, h, d = getwhd(box)
- local spec = {
- k = kind,
- p = true,
- c = column,
- r = true,
- x = true,
- y = true,
- h = h ~= 0 and h or nil,
- d = d ~= 0 and d or nil,
- n = nofparagraphs > 0 and nofparagraphs or nil,
- r2l = texgetinteger("inlinelefttoright") == 1 or nil,
- }
- tobesaved[name] = spec
- ctx_latelua { action = enhance, specification = spec }
- end
-}
+end
function jobpositions.getreserved(tag,n)
if tag == v_column then
@@ -1384,18 +2084,18 @@ implement {
actions = MPpardata
}
-implement {
- name = "MPposset",
- arguments = "argument",
- public = true,
- actions = function(name)
- local b = f_b_tag(name)
- local e = f_e_tag(name)
- local w = f_w_tag(name)
- local p = f_p_tag(getparagraph(b))
- MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p)
- end
-}
+-- implement {
+-- name = "MPposset",
+-- arguments = "argument",
+-- public = true,
+-- actions = function(name)
+-- local b = f_b_tag(name)
+-- local e = f_e_tag(name)
+-- local w = f_w_tag(name)
+-- local p = f_p_tag(getparagraph(b))
+-- MPpos(b) context(",") MPpos(e) context(",") MPpos(w) context(",") MPpos(p) context(",") MPpardata(p)
+-- end
+-- }
implement {
name = "MPls",
@@ -1451,7 +2151,7 @@ implement {
implement {
name = "MPrest",
- arguments = { "argument", "argument" },
+ arguments = "2 arguments",
public = true,
actions = function(name,default)
local jpi = collected[name]
@@ -1515,7 +2215,7 @@ implement {
implement {
name = "doifelseoverlapping",
- arguments = { "argument", "argument" },
+ arguments = "2 arguments",
public = true,
protected = true,
actions = function(one,two)
@@ -1548,53 +2248,53 @@ implement {
public = true,
protected = true,
actions = function()
- doifelse(next(collected))
+ doifelse(positionsused)
end
}
implement {
name = "markregionbox",
- arguments = "integer",
+ arguments = { "integer", "integer" },
actions = markregionbox
}
implement {
name = "setregionbox",
- arguments = "integer",
+ arguments = { "integer", "integer" },
actions = setregionbox
}
implement {
name = "markregionboxtagged",
- arguments = { "integer", "string" },
+ arguments = { "integer", "string", "integer" },
actions = markregionbox
}
implement {
name = "markregionboxtaggedn",
- arguments = { "integer", "string", "integer" },
- actions = function(box,tag,n)
- markregionbox(box,tag,nil,nil,nil,nil,nil,nil,n)
+ arguments = { "integer", "string", "integer", "integer" },
+ actions = function(box,tag,index,n)
+ markregionbox(box,tag,index,nil,nil,nil,nil,nil,nil,n)
end
}
implement {
name = "setregionboxtagged",
- arguments = { "integer", "string" },
+ arguments = { "integer", "string", "integer" },
actions = setregionbox
}
implement {
name = "markregionboxcorrected",
- arguments = { "integer", "string", true },
+ arguments = { "integer", "string", "integer", true },
actions = markregionbox
}
implement {
name = "markregionboxtaggedkind",
- arguments = { "integer", "string", "integer", "dimen", "dimen", "dimen", "dimen" },
- actions = function(box,tag,n,d1,d2,d3,d4)
- markregionbox(box,tag,nil,n,d1,d2,d3,d4)
+ arguments = { "integer", "string", "integer", "integer", "dimen", "dimen", "dimen", "dimen" },
+ actions = function(box,tag,index,n,d1,d2,d3,d4)
+ markregionbox(box,tag,index,nil,n,d1,d2,d3,d4)
end
}
@@ -1607,27 +2307,6 @@ implement {
end
}
--- statistics (at least for the moment, when testing)
-
--- statistics.register("positions", function()
--- local total = nofregular + nofusedregions + nofmissingregions
--- if total > 0 then
--- return format("%s collected, %s regulars, %s regions, %s unresolved regions",
--- total, nofregular, nofusedregions, nofmissingregions)
--- else
--- return nil
--- end
--- end)
-
-statistics.register("positions", function()
- local total = nofregular + nofspecial
- if total > 0 then
- return format("%s collected, %s regular, %s special",total,nofregular,nofspecial)
- else
- return nil
- end
-end)
-
-- We support the low level positional commands too:
local newsavepos = nodes.pool.savepos
diff --git a/tex/context/base/mkxl/anch-pos.mkxl b/tex/context/base/mkxl/anch-pos.mkxl
index 2bf7fab6f..70197e93e 100644
--- a/tex/context/base/mkxl/anch-pos.mkxl
+++ b/tex/context/base/mkxl/anch-pos.mkxl
@@ -164,7 +164,7 @@
{\anch_positions_initialize
\hbox % \hpack
{\edef\currentposition{#1}%
- \dosetpositionwhd\currentposition{#2}{#3}{#4}% already \the\dimexpr
+ \dosetpositionwhd\currentposition{#2}{#3}{#4}%
\anch_positions_trace_left
\dopositionaction\currentposition
\hss}}
@@ -184,7 +184,8 @@
\def\anch_positions_set_box_finish#1%
{\anch_positions_initialize
- \hbox to \wd\nextbox % \hpack
+ %\hbox to \wd\nextbox
+ \hpack to \wd\nextbox
{\edef\currentposition{#1}%
\dosetpositionbox\currentposition\nextbox
\anch_positions_trace_left
@@ -244,7 +245,7 @@
{\anch_positions_initialize
\hbox % \hpack
{\edef\currentposition{#1}%
- \dosetpositionplus\currentposition{#2}{#3}{#4}{#5}% already \the\dimexpr
+ \dosetpositionplus\currentposition{#2}{#3}{#4}{#5}%
\anch_positions_trace_right
\dopositionaction\currentposition
\hss}}
@@ -288,12 +289,15 @@
% Is this really always needed? We use \enabletextarearegistration for page areas so why
% not also for this.
+%
+% At some point we can switch to dedicated markers because there are not
+% that many variants: text, page, textarea, columnarea, free.
\protected\def\anch_mark_column_box#1#2% box n
{\global\advance\c_anch_column\plusone
- \clf_markregionboxtaggedn#1{columnarea:\the\c_anch_column}#2\relax} % extra height
+ \clf_markregionboxtaggedn#1{columnarea}\c_anch_column#2\relax} % extra height
-\protected\def\anch_mark_region_box
+\protected\def\anch_mark_region_box % auto region:index
{\iftrialtypesetting
\expandafter\gobbleoneargument
\orelse\ifpositioning
@@ -308,38 +312,45 @@
\protected\def\anch_mark_flow_box#1% will be extended / renamed
{\hpack\bgroup
\global\advance\c_anch_text\plusone
- \clf_markregionboxtagged#1{textarea:\the\c_anch_text}%
+ \clf_markregionboxtagged#1{textarea}\c_anch_text % will become flow:
\box#1%
\egroup}
-\protected\def\anch_mark_tagged_box#1#2%
- {\clf_markregionboxtagged#1{#2}}
+\protected\def\anch_mark_tagged_box#1#2#3%
+ {\clf_markregionboxtagged#1{#2}#3\relax}
\protected\def\anch_mark_flow_only#1% will be extended / renamed
{\global\advance\c_anch_text\plusone
- \clf_markregionboxcorrected#1{textarea:\the\c_anch_text}}
+ \clf_markregionboxcorrected#1{textarea}\c_anch_text}% will become flow:
\protected\def\anch_make_page_box#1% maybe like text
- {\clf_setregionboxtagged#1{page:\the\realpageno}}
+ {\clf_setregionboxtagged#1{page}\realpageno}
\protected\def\anch_mark_text_box#1%
- {\clf_markregionboxtagged#1{text:\the\realpageno}} % needs an hbox
+ {\clf_markregionboxtagged#1{text}\realpageno} % needs an hbox
-\newcount\c_anch_free
-
-\protected\def\anch_mark_tagged_box_free#1#2#3#4#5#6% only needed when positions
+\protected\def\anch_mark_tagged_box_free
{\ifpositioning
- \global\advance\c_anch_free\plusone % could be done at the lua end
- \clf_markregionboxtaggedkind
- #1%
- {free:\number\c_anch_free}%
- #2\space % kind
- #3\space % leftoffset
- #4\space % rightoffset
- #5\space % topoffset
- #6\relax % bottomoffset
+ \expandafter\anch_mark_tagged_box_free_yes
+ \else
+ \expandafter\gobblesixarguments
\fi}
+\newcount\c_anch_free
+
+\protected\def\anch_mark_tagged_box_free_yes#1#2#3#4#5#6% only needed when positions
+ {\global\advance\c_anch_free\plusone % could be done at the lua end
+ \clf_markregionboxtaggedkind
+ #1%
+ {free}%
+ \c_anch_free
+ #2% kind % single token value
+ #3% leftoffset % single token value
+ #4% rightoffset % single token value
+ #5% topoffset % single token value
+ #6% bottomoffset % single token value
+ \relax}
+
% \reservedautoregiontag % define at lua end
%D We can copy a position with:
diff --git a/tex/context/base/mkxl/anch-snc.lmt b/tex/context/base/mkxl/anch-snc.lmt
index 57789a5a0..c97be2b39 100644
--- a/tex/context/base/mkxl/anch-snc.lmt
+++ b/tex/context/base/mkxl/anch-snc.lmt
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['anch-snc'] = {
license = "see context related readme files"
}
-local tonumber, next, setmetatable = tonumber, next, setmetatable
+local tonumber, next, setmetatable, rawget = tonumber, next, setmetatable, rawget
local concat, sort, remove, copy = table.concat, table.sort, table.remove, table.copy
local match, find = string.match, string.find
local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
@@ -17,9 +17,10 @@ graphics = graphics or { }
local synchronizers = { }
graphics.synchronizers = synchronizers
+local jobpositions = job.positions
+
local p_number = lpegpatterns.cardinal/tonumber
local p_space = lpegpatterns.whitespace^0
-local p_tag = P("syncpos:") * p_number * P(":") * p_number
local p_option = p_number * ((P(",") * p_space * P("reset") * Cc(true)) + Cc(false)) -- for now
local list = { }
@@ -31,39 +32,10 @@ local kinds = {
below = 5,
}
-local allentries = setmetatableindex(function(t,category)
- setmetatable(t,nil)
- for tag, pos in next, job.positions.collected do
- local c, n = lpegmatch(p_tag,tag)
- if c then
- local tc = t[c]
- if tc then
- tc[n] = pos
- else
- t[c] = { [n] = pos }
- end
- end
- end
- for k, list in next, t do
- sort(list,function(a,b)
- local ap = a.p
- local bp = b.p
- if ap == bp then
- return b.y < a.y
- else
- return ap < bp
- end
- end)
- list.start = 1
- end
- setmetatableindex(t,"table")
- return t[category]
-end)
-
local lastdone = { }
function synchronizers.collect(category,realpage,region)
- local all = allentries[category]
+ local all = jobpositions.getsync(category)
local m = 0
local n = #all
list = { }
@@ -78,7 +50,7 @@ function synchronizers.collect(category,realpage,region)
local r = pos.r
if r == region then
if not done then
- local region = job.positions.collected[r]
+ local region = jobpositions.collected[r]
list.region = region
list.page = region
rtop = (region.y or 0) + (region.h or 0)
@@ -106,8 +78,8 @@ function synchronizers.collect(category,realpage,region)
local p = pos.p
if p == realpage then
if not done then
- local region = job.positions.collected[pos.r]
- local page = job.positions.collected["page:"..realpage] or region
+ local region = jobpositions.collected[pos.r]
+ local page = jobpositions.collected["page:"..realpage] or region
list.region = region
list.page = page
rtop = (region.y or 0) + (region.h or 0)
@@ -224,6 +196,8 @@ function synchronizers.collapse()
return n
end
+-- These operate on the currently set list:
+
function synchronizers.getsize () return #list end
function synchronizers.gettop (n) return list[n].top end
function synchronizers.getbottom(n) return list[n].bottom end
diff --git a/tex/context/base/mkxl/anch-snc.mkxl b/tex/context/base/mkxl/anch-snc.mkxl
index 436305634..dcf2c86cb 100644
--- a/tex/context/base/mkxl/anch-snc.mkxl
+++ b/tex/context/base/mkxl/anch-snc.mkxl
@@ -125,10 +125,12 @@
%D \stoptext
%D \stoptyping
+%D We could actually use par positions but in \LMTX\ we have syncpos entries
+%D somewhat optimized.
+
\unprotect
-\ifdefined\??syncposcounter \else \installcorenamespace{syncposcounter} \fi
-\ifdefined\s!syncpos \else \def\s!syncpos {syncpos} \fi
+\installcorenamespace{syncposcounter}
\let\c_sync_n\relax
@@ -137,7 +139,7 @@
\expandafter\newcount\csname\??syncposcounter:#1\endcsname
\fi}
-\permanent\tolerant\protected\def\syncposition[#1]#*[#2]% we could actually use par positions
+\permanent\tolerant\protected\def\syncposition[#1]#*[#2]%
{\dontleavehmode
\ifcsname\??syncposcounter:#1\endcsname
\let\c_sync_n\lastnamedcs
diff --git a/tex/context/base/mkxl/back-exp.lmt b/tex/context/base/mkxl/back-exp.lmt
index a465cee92..de1a1830e 100644
--- a/tex/context/base/mkxl/back-exp.lmt
+++ b/tex/context/base/mkxl/back-exp.lmt
@@ -334,9 +334,9 @@ local styletemplate <const> = [[
local numbertoallign = {
[0] = "justify", ["0"] = "justify", [variables.normal ] = "justify",
- [1] = "right", ["1"] = "right", [variables.flushright] = "right",
- [2] = "center", ["2"] = "center", [variables.middle ] = "center",
- [3] = "left", ["3"] = "left", [variables.flushleft ] = "left",
+ "right", ["1"] = "right", [variables.flushright] = "right",
+ "center", ["2"] = "center", [variables.middle ] = "center",
+ "left", ["3"] = "left", [variables.flushleft ] = "left",
}
function wrapups.allusedstyles(filename)
diff --git a/tex/context/base/mkxl/buff-ini.mkxl b/tex/context/base/mkxl/buff-ini.mkxl
index a91e3272b..ed16bd6e3 100644
--- a/tex/context/base/mkxl/buff-ini.mkxl
+++ b/tex/context/base/mkxl/buff-ini.mkxl
@@ -115,7 +115,8 @@
\setupbuffer
[\c!before=,
- \c!after=]
+ \c!after=,
+ \c!define=\v!yes]
\newcount\c_buff_n_of_defined
@@ -125,8 +126,12 @@
\global\advance\c_buff_n_of_defined\plusone
\setexpandedbufferparameter\c!number{\number\c_buff_n_of_defined}%
\edef\currentdefinedbuffer{def-\number\c_buff_n_of_defined}%
- \frozen\instance\setuevalue{\e!start\currentbuffer}{\buff_start_defined{\currentbuffer}{\currentdefinedbuffer}{\e!start\currentbuffer}{\e!stop\currentbuffer}}%
- \frozen\instance\setuevalue{\e!get \currentbuffer}{\buff_get_stored {\currentbuffer}{\currentdefinedbuffer}}%
+ \ifcstok{\bufferparameter\c!define}\v!yes
+ \frozen\instance\protected\edefcsname\e!start\currentbuffer\endcsname
+ {\buff_start_defined{\currentbuffer}{\currentdefinedbuffer}{\e!start\currentbuffer}{\e!stop\currentbuffer}}%
+ \frozen\instance\protected\edefcsname\e!get \currentbuffer\endcsname
+ {\buff_get_stored {\currentbuffer}{\currentdefinedbuffer}}%
+ \fi
\to \everydefinebuffer
\protected\def\buff_start_defined
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 74d3aa873..7b5f090d9 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2021.08.10 12:37}
+\newcontextversion{2021.08.19 19:40}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/cont-run.lmt b/tex/context/base/mkxl/cont-run.lmt
index a256a4104..448992b4b 100644
--- a/tex/context/base/mkxl/cont-run.lmt
+++ b/tex/context/base/mkxl/cont-run.lmt
@@ -219,6 +219,14 @@ local function processjob()
environment.lmtxmode = CONTEXTLMTXMODE -- should be true
+ -- directives
+ -- silent
+ -- batchmode
+
+if arguments.directives then
+ directives.enable(arguments.directives)
+end
+
if arguments.nosynctex then
luatex.synctex.setup {
state = interfaces.variables.never,
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 91ec43d30..978808ec5 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2021.08.10 12:37}
+\immutable\edef\contextversion{2021.08.19 19:40}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/core-sys.mkxl b/tex/context/base/mkxl/core-sys.mkxl
index a0bd9debd..b8bd7905e 100644
--- a/tex/context/base/mkxl/core-sys.mkxl
+++ b/tex/context/base/mkxl/core-sys.mkxl
@@ -257,7 +257,8 @@
\appendtoks
\ifcstok{\highlightparameter\c!define}\v!yes
- \frozen\instance\setuevalue\currenthighlight{\typo_highlights_indeed{\currenthighlight}}%
+ \frozen\instance\protected\edefcsname\currenthighlight\endcsname
+ {\typo_highlights_indeed{\currenthighlight}}%
\fi
\to \everydefinehighlight
@@ -291,6 +292,7 @@
\aliased\let\directhighlight\typo_highlights_indeed
+%D Defining commands (rather old):
\permanent\protected\def\defineexpandable
{\integerdef\c_syst_parameter_catcode\catcode\hashasciicode
diff --git a/tex/context/base/mkxl/core-uti.lmt b/tex/context/base/mkxl/core-uti.lmt
index 1bb50060d..de514df30 100644
--- a/tex/context/base/mkxl/core-uti.lmt
+++ b/tex/context/base/mkxl/core-uti.lmt
@@ -19,7 +19,7 @@ saves much runtime but at the cost of more memory usage.</p>
local math = math
local format, match = string.format, string.match
-local next, type, tostring, tonumber = next, type, tostring, tonumber
+local next, type, tostring, tonumber, setmetatable = next, type, tostring, tonumber, setmetatable
local concat = table.concat
local definetable = utilities.tables.definetable
@@ -43,7 +43,7 @@ local report_passes = logs.reporter("job","passes")
job = job or { }
local job = job
-job.version = 1.32
+job.version = 1.33
job.packversion = 1.02
-- some day we will implement loading of other jobs and then we need
@@ -209,6 +209,67 @@ local skiplist = {
"positions",
}
+-- I'm not that impressed by the savings. It's some 5 percent on the luametatex
+-- manual and probably some more on the m4 files (if so I might enable it).
+
+local deltapacking = false
+-- local deltapacking = true
+
+local function packnumberdata(tobesaved)
+ if deltapacking and tobesaved[1] then
+ local last
+ local current
+ for i=1,#tobesaved do
+ current = tobesaved[i]
+ if last then
+ if last.numbers and last.block then
+ for k, v in next, last do
+ if k ~= "numbers" and v ~= current[k] then
+ goto DIFFERENT
+ end
+ end
+ for k, v in next, current do
+ if k ~= "numbers" and v ~= last[k] then
+ goto DIFFERENT
+ end
+ end
+ tobesaved[i] = {
+ numbers = current.numbers,
+ }
+ goto CONTINUE
+ else
+ current = nil
+ end
+ end
+ ::DIFFERENT::
+ last = current
+ ::CONTINUE::
+ end
+ end
+end
+
+local function unpacknumberdata(collected)
+ if deltapacking and collected[1] then
+ local key = "numbers"
+ local last = collected[1]
+ local meta = false
+ for i=2,#collected do
+ local c = collected[i]
+ if c.block then
+ last = c
+ meta = false
+ elseif c.numbers then
+ if not meta then
+ meta = { __index = last }
+ end
+ setmetatable(c, meta)
+ end
+ end
+ end
+end
+
+-- -- --
+
-- not ok as we can have arbitrary keys in userdata and dataset so some day we
-- might need a bit more granularity, like skippers
@@ -253,6 +314,7 @@ function job.save(filename) -- we could return a table but it can get pretty lar
end
if job.pack then
packers.strip(jobpacker)
+packnumberdata(jobpacker.index)
-- f:write("do\n\n")
f:write(serialize(jobpacker,"utilitydata.job.packed",true),"\n\n")
-- f:write("end\n\n")
@@ -265,7 +327,6 @@ end
local function load(filename)
if lfs.isfile(filename) then
-
local function dofile(filename)
local result = loadstring(io.loaddata(filename))
if result then
@@ -274,7 +335,6 @@ local function load(filename)
return nil
end
end
-
local okay, data = pcall(dofile,filename)
if okay and type(data) == "table" then
local jobversion = job.version
@@ -299,28 +359,26 @@ function job.load(filename)
local utilitydata = load(filename)
if utilitydata then
local jobpacker = utilitydata.job.packed
- local handlers = { }
+unpacknumberdata(jobpacker.index)
for i=1,#savelist do
- local list = savelist[i]
- local target = list[1]
- local initializer = list[3]
- local result = accesstable(target,utilitydata)
+ local list = savelist[i]
+ local target = list[1]
+ local result = accesstable(target,utilitydata)
if result then
local done = packers.unpack(result,jobpacker,true)
if done then
migratetable(target,mark(result))
- if type(initializer) == "function" then
- handlers[#handlers+1] = { initializer, result }
- end
else
report_passes("pack version mismatch")
end
end
end
- -- so we have all tables available (unpacked)
- for i=1,#handlers do
- local handler = handlers[i]
- handler[1](handler[2])
+ end
+ for i=1,#savelist do
+ local list = savelist[i]
+ local initializer = list[3]
+ if type(initializer) == "function" then
+ initializer(utilitydata and accesstable(list[1],utilitydata) or nil)
end
end
statistics.stoptiming(_load_)
diff --git a/tex/context/base/mkxl/driv-shp.lmt b/tex/context/base/mkxl/driv-shp.lmt
index 65221abf5..d84ecbcbc 100644
--- a/tex/context/base/mkxl/driv-shp.lmt
+++ b/tex/context/base/mkxl/driv-shp.lmt
@@ -148,7 +148,6 @@ local flush_character do
local vfinjectors = fonts.helpers.vfinjectors
local function flush_vf_packet(current,pos_h,pos_v,pos_r,font,char,data,factor,vfcommands,sx,sy)
-
if nesting > 100 then
return
elseif nesting == 0 then
@@ -194,7 +193,6 @@ local flush_character do
end
local refactored = 1000000
-
for i=1,#vfcommands do
local packet = vfcommands[i]
local command = packet[1]
diff --git a/tex/context/base/mkxl/file-job.lmt b/tex/context/base/mkxl/file-job.lmt
index dac6f6d9a..84186a2d0 100644
--- a/tex/context/base/mkxl/file-job.lmt
+++ b/tex/context/base/mkxl/file-job.lmt
@@ -550,7 +550,9 @@ end
local function poptree()
top = remove(treestack)
- -- inspect(top)
+ if #top[#top].branches == 0 then
+ top[#top].branches = nil -- saves space in tuc
+ end
end
do
@@ -558,10 +560,15 @@ do
local function log_tree(report,top,depth)
report("%s%s: %s",depth,top.type,top.name)
local branches = top.branches
- if #branches > 0 then
- depth = depth .. " "
- for i=1,#branches do
- log_tree(report,branches[i],depth)
+ if branches then
+ local n = #branches
+ if n > 0 then
+ depth = depth .. " "
+ for i=1,n do
+ log_tree(report,branches[i],depth)
+ end
+ else
+ top.brances = nil -- saves space in tuc
end
end
end
@@ -1046,6 +1053,7 @@ function document.setcommandline() -- has to happen at the tex end in order to e
-- in the new mtx=context approach we always pass a stub file so we need to
-- to trick the files table which actually only has one entry in a tex job
+
if arguments.timing then
context.usemodule { "timing" }
end
diff --git a/tex/context/base/mkxl/font-def.lmt b/tex/context/base/mkxl/font-def.lmt
index 614f98036..d71132180 100644
--- a/tex/context/base/mkxl/font-def.lmt
+++ b/tex/context/base/mkxl/font-def.lmt
@@ -183,6 +183,7 @@ function resolvers.file(specification)
specification.forcedname = name
specification.name = removesuffix(name)
else
+ -- maybe when no suffix and not found, then still run over suffixes
specification.name = name -- can be resolved
end
end
diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx
index d865da949..9985df105 100644
--- a/tex/context/base/mkxl/font-lib.mklx
+++ b/tex/context/base/mkxl/font-lib.mklx
@@ -46,7 +46,7 @@
\registerctxluafile{font-ota}{autosuffix}
% \registerctxluafile{font-ots-pre-scale}{autosuffix,optimize}
\registerctxluafile{font-ots}{autosuffix,optimize}
-\registerctxluafile{font-otd}{optimize}
+\registerctxluafile{font-otd}{autosuffix,optimize}
\registerctxluafile{font-otc}{}
\registerctxluafile{font-oth}{}
\registerctxluafile{font-osd}{}
diff --git a/tex/context/base/mkxl/font-ogr.lmt b/tex/context/base/mkxl/font-ogr.lmt
index ef0af904c..87166b36d 100644
--- a/tex/context/base/mkxl/font-ogr.lmt
+++ b/tex/context/base/mkxl/font-ogr.lmt
@@ -36,6 +36,9 @@ otf.pngenabled = true
-- what here and what in backend ...
+local report_fonts = logs.reporter("backend","fonts")
+local trace_fonts trackers.register("backend.fonts",function(v) trace_fonts = v end)
+
do
-- This is a prelude to something better but I'm still experimenting. We should delay more.
@@ -59,7 +62,8 @@ do
local t_properties = t_tfmdata.properties
local d_tfmdata = setmetatableindex({ },t_tfmdata)
local d_properties = setmetatableindex({ },t_properties)
- d_properties.basefontname = "ContextRuntimeFont" .. droppedin
+ local d_basefontname = "ContextRuntimeFont" .. droppedin
+ d_properties.basefontname = d_basefontname
d_tfmdata.properties = d_properties
local d_characters = { } -- setmetatableindex({ },t_characters) -- hm, index vs unicode
local d_descriptions = { } -- setmetatableindex({ },t_descriptions) -- hm, index vs unicode
@@ -75,6 +79,9 @@ do
d_properties.indexdata = { indexdata, ... } -- can take quite some memory
local slot = #fonts + 1
fonts[slot] = { id = droppedin }
+ if trace_fonts then
+ report_fonts("registering dropin %a using method %a",d_basefontname,method)
+ end
return slot, droppedin, d_tfmdata, d_properties
end
@@ -84,9 +91,10 @@ do
if method and shapes then
local characters = tfmdata.characters
local descriptions = tfmdata.descriptions
- local droppedin, tfmdrop, dropchars, dropdescs, colrshapes
+ local droppedin, tfmdrop, dropchars, dropdescs, colrshapes, props
local idx = 255
local slot = 0
+ -- sorted ?
for k, v in next, characters do
local index = v.index
if index then
@@ -97,7 +105,7 @@ do
if idx >= 255 then
idx = 1
colrshapes = setmetatableindex({ },shapes)
- slot, droppedin, tfmdrop = dropins.provide(method,tfmdata,colrshapes)
+ slot, droppedin, tfmdrop, props = dropins.provide(method,tfmdata,colrshapes)
dropchars = tfmdrop.characters
dropdescs = tfmdrop.descriptions
else
diff --git a/tex/context/base/mkxl/font-otd.lmt b/tex/context/base/mkxl/font-otd.lmt
new file mode 100644
index 000000000..3f1b212db
--- /dev/null
+++ b/tex/context/base/mkxl/font-otd.lmt
@@ -0,0 +1,284 @@
+if not modules then modules = { } end modules ['font-otd'] = {
+ version = 1.001,
+ optimize = true,
+ comment = "companion to font-ini.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+local type = type
+local match = string.match
+local sequenced = table.sequenced
+
+local trace_dynamics = false trackers.register("otf.dynamics", function(v) trace_dynamics = v end)
+local trace_applied = false trackers.register("otf.applied", function(v) trace_applied = v end)
+
+local report_otf = logs.reporter("fonts","otf loading")
+local report_process = logs.reporter("fonts","otf process")
+
+local allocate = utilities.storage.allocate
+
+local fonts = fonts
+local otf = fonts.handlers.otf
+local hashes = fonts.hashes
+local definers = fonts.definers
+local constructors = fonts.constructors
+local specifiers = fonts.specifiers
+
+local fontidentifiers = hashes.identifiers
+local fontresources = hashes.resources
+local fontproperties = hashes.properties
+local fontdynamics = hashes.dynamics
+
+local contextsetups = specifiers.contextsetups
+local contextnumbers = specifiers.contextnumbers
+local contextmerged = specifiers.contextmerged
+
+local setmetatableindex = table.setmetatableindex
+
+local a_to_script = { }
+local a_to_language = { }
+
+-- we can have a scripts hash in fonts.hashes
+
+function otf.setdynamics(font,attribute)
+ -- local features = contextsetups[contextnumbers[attribute]] -- can be moved to caller
+ local features = contextsetups[attribute]
+ if features then
+ local dynamics = fontdynamics[font]
+ dynamic = contextmerged[attribute] or 0
+ local script, language
+ if dynamic == 2 then -- merge
+ language = features.language or fontproperties[font].language or "dflt"
+ script = features.script or fontproperties[font].script or "dflt"
+ else -- if dynamic == 1 then -- replace
+ language = features.language or "dflt"
+ script = features.script or "dflt"
+ end
+ if script == "auto" then
+ -- checkedscript and resources are defined later so we cannot shortcut them -- todo: make installer
+ script = definers.checkedscript(fontidentifiers[font],fontresources[font],features)
+ end
+ local ds = dynamics[script] -- can be metatable magic (less testing)
+-- or dynamics.dflt
+ if not ds then
+ ds = { }
+ dynamics[script] = ds
+ end
+ local dsl = ds[language]
+-- or ds.dflt
+ if not dsl then
+ dsl = { }
+ ds[language] = dsl
+ end
+ local dsla = dsl[attribute]
+ if not dsla then
+ local tfmdata = fontidentifiers[font]
+ a_to_script [attribute] = script
+ a_to_language[attribute] = language
+ -- we need to save some values .. quite messy
+ local properties = tfmdata.properties
+ local shared = tfmdata.shared
+ local s_script = properties.script
+ local s_language = properties.language
+ local s_mode = properties.mode
+ local s_features = shared.features
+ properties.mode = "node"
+ properties.language = language
+ properties.script = script
+ properties.dynamics = true -- handy for tracing
+ shared.features = { }
+ -- end of save
+ local set = constructors.checkedfeatures("otf",features)
+ set.mode = "node" -- really needed
+ dsla = otf.setfeatures(tfmdata,set)
+ if trace_dynamics then
+ report_otf("setting dynamics %s: attribute %a, script %a, language %a, set %a",contextnumbers[attribute],attribute,script,language,set)
+ end
+ -- we need to restore some values
+ properties.script = s_script
+ properties.language = s_language
+ properties.mode = s_mode
+ shared.features = s_features
+ -- end of restore
+ dynamics[script][language][attribute] = dsla -- cache
+ elseif trace_dynamics then
+ -- report_otf("using dynamics %s: attribute %a, script %a, language %a",contextnumbers[attribute],attribute,script,language)
+ end
+ return dsla
+ end
+end
+
+function otf.scriptandlanguage(tfmdata,attr)
+ local properties = tfmdata.properties
+ if attr and attr > 0 then
+ return a_to_script[attr] or properties.script or "dflt", a_to_language[attr] or properties.language or "dflt"
+ else
+ return properties.script or "dflt", properties.language or "dflt"
+ end
+end
+
+-- we reimplement the dataset resolver
+
+local autofeatures = fonts.analyzers.features
+local featuretypes = otf.tables.featuretypes
+local defaultscript = otf.features.checkeddefaultscript
+local defaultlanguage = otf.features.checkeddefaultlanguage
+
+local resolved = { } -- we only resolve a font,script,language,attribute pair once
+local wildcard = "*"
+
+-- what about analyze in local and not in font
+
+-- needs checking: some added features can pass twice
+
+local P, C, Cc, lpegmatch = lpeg.P, lpeg.C, lpeg.Cc, lpeg.match
+
+local pattern = P("always") * (P(-1) * Cc(true) + P(":") * C((1-P(-1))^1))
+
+local function initialize(sequence,script,language,s_enabled,a_enabled,font,attr,dynamic,ra,autoscript,autolanguage)
+ local features = sequence.features
+ if features then
+ local order = sequence.order
+ if order then
+ local featuretype = featuretypes[sequence.type or "unknown"]
+ local lookupdone = false
+ 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
+ e_e = a_e
+ else
+ e_e = s_enabled and s_enabled[kind] -- the value (font)
+ end
+ if e_e then
+ local usedattribute, usedscript, usedlanguage, usedlookup
+ local valid = type(e_e) == "string" and lpegmatch(pattern,e_e)
+ if valid then
+ -- we have hit always
+ usedattribute = autofeatures[kind] or false
+ usedlanguage = "*"
+ usedscript = "*"
+ usedlookup = { valid, usedattribute, sequence, kind }
+ else
+ -- we already checked for e_e
+ local scripts = features[kind] --
+ local languages = scripts[script] or scripts[wildcard]
+ if not languages and autoscript then
+ langages = defaultscript(featuretype,autoscript,scripts)
+ end
+ if languages then
+ -- we need detailed control over default because we want to trace
+ -- only first attribute match check, so we assume simple fina's
+ -- local valid = false
+ if languages[language] then
+ valid = e_e
+ elseif languages[wildcard] then
+ valid = e_e
+ elseif autolanguage and defaultlanguage(featuretype,autolanguage,languages) then
+ valid = e_e
+ end
+ end
+ if valid then
+ usedattribute = autofeatures[kind] or false
+ usedlanguage = script
+ usedscript = language
+ usedlookup = { valid, usedattribute, sequence, kind }
+ end
+ end
+ if not usedlookup then
+ -- go on
+ elseif lookupdone then
+ if trace_applied then
+ report_process(
+ "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a, nofsteps %a, lookup already set by %a",
+ font,attr or 0,dynamic,kind,usedscript,usedlanguage,sequence.name,valid,sequence.nofsteps,ra[#ra][4])
+ end
+ else
+ ra[#ra+1] = usedlookup
+ if trace_applied then
+ report_process(
+ "font %s, dynamic %a (%a), feature %a, script %a, language %a, lookup %a, value %a, nofsteps %a",
+ font,attr or 0,dynamic,kind,usedscript,usedlanguage,sequence.name,valid,sequence.nofsteps)
+ else
+ return -- no need to look further
+ end
+ lookupdone = true
+ end
+ end
+ end
+ end
+ end
+end
+
+-- there is some fuzzy language/script state stuff in properties (temporary)
+
+function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in special parbuilder)
+
+ local script, language, s_enabled, a_enabled, dynamic
+
+ if attr and attr ~= 0 then
+ dynamic = contextmerged[attr] or 0
+ -- local features = contextsetups[contextnumbers[attr]] -- could be a direct list
+ local features = contextsetups[attr]
+ a_enabled = features -- location based
+ if dynamic == 1 then -- or dynamic == -1 then
+ -- replace
+ language = features.language or "dflt"
+ script = features.script or "dflt"
+ elseif dynamic == 2 then -- or dynamic == -2 then
+ -- merge
+ local properties = tfmdata.properties
+ s_enabled = tfmdata.shared.features -- font based
+ language = features.language or properties.language or "dflt"
+ script = features.script or properties.script or "dflt"
+ else
+ -- error
+ local properties = tfmdata.properties
+ language = properties.language or "dflt"
+ script = properties.script or "dflt"
+ end
+ else
+ local properties = tfmdata.properties
+ language = properties.language or "dflt"
+ script = properties.script or "dflt"
+ s_enabled = tfmdata.shared.features -- can be made local to the resolver
+ dynamic = 0
+ end
+
+ local res = resolved[font]
+ if not res then
+ res = { }
+ resolved[font] = res
+ end
+ local rs = res[script]
+ if not rs then
+ rs = { }
+ res[script] = rs
+ end
+ local rl = rs[language]
+ if not rl then
+ rl = { }
+ rs[language] = rl
+ end
+ local ra = rl[attr]
+ if ra == nil then -- attr can be false
+ ra = {
+ -- indexed but we can also add specific data by key in:
+ }
+ rl[attr] = ra
+ local sequences = tfmdata.shared.reorderedsequences or tfmdata.resources.sequences
+ if sequences then
+ local autoscript = (s_enabled and s_enabled.autoscript ) or (a_enabled and a_enabled.autoscript )
+ local autolanguage = (s_enabled and s_enabled.autolanguage) or (a_enabled and a_enabled.autolanguage)
+ for s=1,#sequences do
+ -- just return nil or ra step
+ initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic,ra,autoscript,autolanguage)
+ end
+ end
+ end
+ return ra
+
+end
diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt
index b8fbc9702..ca6490fc0 100644
--- a/tex/context/base/mkxl/font-ots.lmt
+++ b/tex/context/base/mkxl/font-ots.lmt
@@ -210,8 +210,7 @@ local getscales = nuts.getscales
---------------------------------------------------------------------------------------
-- Beware: In ConTeXt components no longer are real components. We only keep track of
--- their positions because some complex ligatures might need that. For the moment we
--- use an x_ prefix because for now generic follows the other approach.
+-- their positions because some complex ligatures might need that.
local components = nuts.components
local copynocomponents = components.copynocomponents
@@ -244,9 +243,6 @@ local setmetatableindex = table.setmetatableindex
local nextnode = nuts.traversers.node
------ zwnj = 0x200C
------ zwj = 0x200D
-
local nodecodes = nodes.nodecodes
local glyphcodes = nodes.glyphcodes
@@ -261,7 +257,7 @@ local lefttoright_code = nodes.dirvalues.lefttoright
local righttoleft_code = nodes.dirvalues.righttoleft
local discretionarydisc_code = nodes.disccodes.discretionary
-local ligatureglyph_code = glyphcodes.ligature
+----- ligatureglyph_code = glyphcodes.ligature
local injections = nodes.injections
local setmark = injections.setmark
@@ -378,7 +374,7 @@ local function cref(dataset,sequence,index)
return "no valid dataset"
end
local merged = sequence.merged and "merged " or ""
- if index then
+ if index and index > 1 then
return formatters["feature %a, type %a, %schain lookup %a, index %a"](
dataset[4],sequence.type,merged,sequence.name,index)
else
@@ -484,7 +480,7 @@ local function markstoligature(head,start,stop,char)
end
resetinjection(base)
setchar(base,char)
- setsubtype(base,ligatureglyph_code)
+ -- setsubtype(base,ligatureglyph_code)
setcomponents(base,start)
setlink(prev,base,next)
flushcomponents(start)
@@ -536,7 +532,7 @@ local function inhibited(start,stop)
end
local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head
- if start == stop and getchar(start) == char then
+ if start == stop and getchar(start) == char and not hasmarks then
resetinjection(start)
setchar(start,char)
return head, start
@@ -556,7 +552,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
resetinjection(base)
setchar(base,char)
setoptions(base,getoptions(start) | getoptions(stop)) -- maybe only lig options
- setsubtype(base,ligatureglyph_code)
+ -- setsubtype(base,ligatureglyph_code)
setcomponents(base,comp)
setlink(prev,base,next)
if not discfound then
@@ -790,7 +786,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
while current do
local nxt, char = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
if char and not hasglyphoption(current,no_left_ligature_code) then
- local lg = ligature[char]
+ local lg = not tonumber(ligature) and ligature[char]
if lg then
stop = current
ligature = lg
@@ -803,14 +799,14 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
end
end
if stop then
- local lig = ligature.ligature
- if lig then
+ local ligature = tonumber(ligature) or ligature.ligature
+ if ligature then
if trace_ligatures then
local stopchar = getchar(stop)
- head, start = markstoligature(head,start,stop,lig)
+ head, start = markstoligature(head,start,stop,ligature)
logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
else
- head, start = markstoligature(head,start,stop,lig)
+ head, start = markstoligature(head,start,stop,ligature)
end
return head, start, true, false
else
@@ -828,7 +824,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
elseif hasglyphoption(current,no_left_ligature_code) then
break
else
- local lg = ligature[char]
+ local lg = not tonumber(ligature) and ligature[char]
if lg then
if marks[char] then
hasmarks = true
@@ -856,7 +852,9 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
--
-- Challenge for Kai (latinmodern): \hyphenation{fii-f-f-iif} fiiffiif
--
- if discfound then
+ if tonumber(ligature) then
+ -- we're already done (endpoint reached)
+ elseif discfound then
-- todo: check for no right ligature
-- don't assume marks in a disc and we don't run over a disc (for now)
local pre, post, replace = getdisc(discfound)
@@ -920,27 +918,28 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
start = discfound
return head, start, true, true
end
+ ligature = ligature.ligature
end
- local lig = ligature.ligature
- if lig then
+ -- local ligature = tonumber(ligature) or ligature.ligature
+ if ligature then
if stop then
if trace_ligatures then
local stopchar = getchar(stop)
- -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
- logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ -- head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(ligature))
-- we can have a rare case of multiple disc in a lig but that makes no sense language wise but if really
-- needed we could backtrack if we're in a disc node
else
- -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks)
- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ -- head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks)
+ head, start = toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
end
else
-- weird but happens (in some arabic font)
resetinjection(start)
- setchar(start,lig)
+ setchar(start,ligature)
if trace_ligatures then
- logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(ligature))
end
end
return head, start, true, false
@@ -1502,19 +1501,19 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
local last = stop
local nofreplacements = 1
while current do
- local nxt, schar, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
- if schar then
-if current and hasglyphoption(current,no_left_ligature_code) then
- break
-end
- if skiphash and skiphash[schar] then -- marks
+ local nxt, char, id = isnextchar(current,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
+ if char then
+ if current and hasglyphoption(current,no_left_ligature_code) then
+ break
+ end
+ if skiphash and skiphash[char] then -- marks
-- if current == stop then -- maybe add this
-- break
-- else
current = nxt
-- end
else
- local lg = ligatures[schar]
+ local lg = not tonumber(ligatures) and ligatures[char]
if lg then
ligatures = lg
last = current
@@ -1544,7 +1543,8 @@ end
break
end
end
- local ligature = ligatures.ligature
+ -- we can avoid the tonumber as already done but messy
+ local ligature = tonumber(ligatures) or ligatures.ligature
if ligature then
if chainindex then
stop = last
@@ -2001,7 +2001,6 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
local size = ck[5] - ck[4] + 1
local chainlookups = ck[6]
local done = false
-
-- current match
if chainlookups then
-- Lookups can be like { 1, false, 3 } or { false, 2 } or basically anything and
@@ -2012,7 +2011,6 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
-- if nofchainlookups > size then
-- -- bad rules
-- end
-
local chainlookup = chainlookups[1]
for j=1,#chainlookup do
local chainstep = chainlookup[j]
@@ -2020,6 +2018,9 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
local chainproc = chainprocs[chainkind]
if chainproc then
local ok
+ -- HH: chainindex 1 added here (for KAI to check too), there are weird ligatures e.g.
+ -- char + mark -> char where mark has to disappear
+ -- head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,1)
head, start, ok = chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash)
if ok then
done = true
@@ -2515,6 +2516,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local ck = contexts[k]
local seq = ck[3]
local f = ck[4] -- first current
+local last = start
if not startchar or not seq[f][startchar] then
-- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
goto next
@@ -2525,7 +2527,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
else
local l = ck[5] -- last current
local current = start
- local last = start
+-- local last = start
if l > f then
-- before/current/after | before/current | current/after
@@ -3443,7 +3445,7 @@ local function t_run_single(start,stop,lookupcache)
while s do
local nxt, char = isnextchar(s,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
if char then
- local lg = lookupmatch[char]
+ local lg = not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d = 1
@@ -3473,7 +3475,7 @@ local function t_run_single(start,stop,lookupcache)
break
end
end
- if l and l.ligature then -- so we test for ligature
+ if l and (tonumber(l) or l.ligature) then -- so we test for ligature
lastd = d
end
end
@@ -3587,7 +3589,7 @@ local function t_run_multiple(start,stop,steps,nofsteps)
while s do
local nxt, char = isnextchar(s,currentfont,currentdynamic,currentscale,currentxscale,currentyscale)
if char then
- local lg = lookupmatch[char]
+ local lg = not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d = 1
@@ -3617,7 +3619,7 @@ local function t_run_multiple(start,stop,steps,nofsteps)
break
end
end
- if l and l.ligature then
+ if l and (tonumber(l) or l.ligature) then
lastd = d
end
end
@@ -3728,7 +3730,14 @@ do
-- about 15% on arabtype .. then moving the a test also saves a bit (even when
-- often a is not set at all so that one is a bit debatable
- local otfdataset = nil -- todo: make an installer
+ -- local otfdataset = nil
+ local otfdataset
+
+ otfdataset = function(...)
+ -- delayed alias
+ otfdataset = otf.dataset
+ return otfdataset(...)
+ end
local getfastdisc = { __index = function(t,k)
local v = usesfont(k,currentfont)
@@ -3752,9 +3761,6 @@ do
if nesting == 1 then
currentfont = font
currentdynamic = dynamic
--- currentscale = false
--- currentxscale = false
--- currentyscale = false
currentscale = 1000
currentxscale = 1000
currentyscale = 1000
@@ -3768,11 +3774,11 @@ do
factor = getthreshold(font)
checkmarks = tfmdata.properties.checkmarks
- if not otfdataset then
- otfdataset = otf.dataset
- end
+ -- if not otfdataset then
+ -- otfdataset = otf.dataset
+ -- end
- discs = fastdisc and n and n > 1 and setmetatable({},getfastdisc) -- maybe inline
+ discs = fastdisc and n and n > 1 and setmetatable({},getfastdisc)
spaces = setmetatable({},getfastspace)
elseif currentfont ~= font then
@@ -3806,7 +3812,7 @@ do
-- We don't goto the next node when a disc node is created so that we can then treat
-- the pre, post and replace. It's a bit of a hack but works out ok for most cases.
- for s=1,#datasets do
+ for s=1,#datasets do -- todo: datasets.n
local dataset = datasets[s]
local state = dataset[2]
local sequence = dataset[3] -- sequences[s] -- also dataset[5]
@@ -4194,8 +4200,8 @@ registerotffeature {
}
}
--- Moved here (up) a bit. This doesn't really belong in generic so it will
--- move to a context module some day.
+-- Moved here (up) a bit. This doesn't really belong in generic so it will move to a
+-- context module some day.
local function markinitializer(tfmdata,value)
local properties = tfmdata.properties
@@ -4223,239 +4229,3 @@ registerotffeature {
-- Also see (!!).
otf.handlers = handlers
-
-if context then
- return
-else
- -- todo: move the following code someplace else
-end
-
-local setspacekerns = nodes.injections.setspacekerns if not setspacekerns then os.exit() end
-
-local tag = "kern"
-
--- if fontfeatures then
-
--- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,dynamic)
--- local features = fontfeatures[font]
--- local enabled = features and features.spacekern and features[tag]
--- if enabled then
--- setspacekerns(font,sequence)
--- end
--- return head, enabled
--- end
-
--- else -- generic (no hashes)
-
- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,dynamic)
- local shared = fontdata[font].shared
- local features = shared and shared.features
- local enabled = features and features.spacekern and features[tag]
- if enabled then
- setspacekerns(font,sequence)
- end
- return head, enabled
- end
-
--- end
-
--- There are fonts out there that change the space but we don't do that kind of
--- things in TeX.
-
-local function hasspacekerns(data)
- local resources = data.resources
- local sequences = resources.sequences
- local validgpos = resources.features.gpos
- if validgpos and sequences then
- for i=1,#sequences do
- local sequence = sequences[i]
- local steps = sequence.steps
- if steps and sequence.features[tag] then
- local kind = sequence.type
- if kind == "gpos_pair" or kind == "gpos_single" then
- for i=1,#steps do
- local step = steps[i]
- local coverage = step.coverage
- local rules = step.rules
- if rules then
- -- not now: analyze (simple) rules
- elseif not coverage then
- -- nothing to do
- elseif kind == "gpos_single" then
- -- maybe a message that we ignore
- elseif kind == "gpos_pair" then
- local format = step.format
- if format == "move" or format == "kern" then
- local kerns = coverage[32]
- if kerns then
- return true
- end
- for k, v in next, coverage do
- if v[32] then
- return true
- end
- end
- elseif format == "pair" then
- local kerns = coverage[32]
- if kerns then
- for k, v in next, kerns do
- local one = v[1]
- if one and one ~= true then
- return true
- end
- end
- end
- for k, v in next, coverage do
- local kern = v[32]
- if kern then
- local one = kern[1]
- if one and one ~= true then
- return true
- end
- end
- end
- end
- end
- end
- end
- end
- end
- end
- return false
-end
-
-otf.readers.registerextender {
- name = "spacekerns",
- action = function(data)
- data.properties.hasspacekerns = hasspacekerns(data)
- end
-}
-
-local function spaceinitializer(tfmdata,value) -- dynamic
- local resources = tfmdata.resources
- local spacekerns = resources and resources.spacekerns
- if value and spacekerns == nil then
- local rawdata = tfmdata.shared and tfmdata.shared.rawdata
- local properties = rawdata.properties
- if properties and properties.hasspacekerns then
- local sequences = resources.sequences
- local validgpos = resources.features.gpos
- if validgpos and sequences then
- local left = { }
- local right = { }
- local last = 0
- local feat = nil
- for i=1,#sequences do
- local sequence = sequences[i]
- local steps = sequence.steps
- if steps then
- -- we don't support space kerns in other features
- local kern = sequence.features[tag]
- if kern then
- local kind = sequence.type
- if kind == "gpos_pair" or kind == "gpos_single" then
- if feat then
- for script, languages in next, kern do
- local f = feat[script]
- if f then
- for l in next, languages do
- f[l] = true
- end
- else
- feat[script] = languages
- end
- end
- else
- feat = kern
- end
- for i=1,#steps do
- local step = steps[i]
- local coverage = step.coverage
- local rules = step.rules
- if rules then
- -- not now: analyze (simple) rules
- elseif not coverage then
- -- nothing to do
- elseif kind == "gpos_single" then
- -- makes no sense in TeX
- elseif kind == "gpos_pair" then
- local format = step.format
- if format == "move" or format == "kern" then
- local kerns = coverage[32]
- if kerns then
- for k, v in next, kerns do
- right[k] = v
- end
- end
- for k, v in next, coverage do
- local kern = v[32]
- if kern then
- left[k] = kern
- end
- end
- elseif format == "pair" then
- local kerns = coverage[32]
- if kerns then
- for k, v in next, kerns do
- local one = v[1]
- if one and one ~= true then
- right[k] = one[3]
- end
- end
- end
- for k, v in next, coverage do
- local kern = v[32]
- if kern then
- local one = kern[1]
- if one and one ~= true then
- left[k] = one[3]
- end
- end
- end
- end
- end
- end
- last = i
- end
- else
- -- no steps ... needed for old one ... we could use the basekerns
- -- instead
- end
- end
- end
- left = next(left) and left or false
- right = next(right) and right or false
- if left or right then
- spacekerns = {
- left = left,
- right = right,
- }
- if last > 0 then
- local triggersequence = {
- -- no steps, see (!!)
- features = { [tag] = feat or { dflt = { dflt = true, } } },
- flags = noflags,
- name = "trigger_space_kerns",
- order = { tag },
- type = "trigger_space_kerns",
- left = left,
- right = right,
- }
- insert(sequences,last,triggersequence)
- end
- end
- end
- end
- resources.spacekerns = spacekerns
- end
- return spacekerns
-end
-
-registerotffeature {
- name = "spacekern",
- description = "space kern injection",
- default = true,
- initializers = {
- node = spaceinitializer,
- },
-}
diff --git a/tex/context/base/mkxl/font-set.mklx b/tex/context/base/mkxl/font-set.mklx
index fd6a2f1ff..98e2e96e1 100644
--- a/tex/context/base/mkxl/font-set.mklx
+++ b/tex/context/base/mkxl/font-set.mklx
@@ -88,7 +88,7 @@
{\glet\font_preload_default_fonts_tt\relax
\glet\font_preload_default_fonts_mm\relax
\glet\font_preloads_third_stage \relax
-% \glet\font_preloads_fourth_stage \relax
+ \glet\font_preloads_fourth_stage \relax
}
\def\font_preloads_zero_stage_indeed
diff --git a/tex/context/base/mkxl/lpdf-emb.lmt b/tex/context/base/mkxl/lpdf-emb.lmt
index c715c7b77..926455bb8 100644
--- a/tex/context/base/mkxl/lpdf-emb.lmt
+++ b/tex/context/base/mkxl/lpdf-emb.lmt
@@ -2101,6 +2101,7 @@ function lpdf.flushfonts()
local hash = getstreamhash(fontid)
if hash then
local parent = mainfonts[hash]
+-- print("before",fontid,hash,parent)
if not parent then
local fontdata = usedfonts[fontid]
local rawdata = fontdata.shared and fontdata.shared.rawdata
@@ -2145,6 +2146,7 @@ function lpdf.flushfonts()
noffonts = noffonts + 1
end
end
+-- print("after ",fontid,hash,parent)
if parent then
local indices = parent.indices
for k, v in next, used do
@@ -2159,21 +2161,23 @@ function lpdf.flushfonts()
for hash, details in sortedhash(mainfonts) do
local filename = details.filename
if next(details.indices) then
- if trace_fonts then
- report_fonts("embedding %a hashed as %a",filename,hash)
- end
local properties = details.properties
local bitmap = properties.usedbitmap
local method = properties.method -- will be pk | pdf | svg | ...
+ if trace_fonts then
+ if method then
+ report_fonts("embedding %a hashed as %a using method %a",filename,hash,method)
+ else
+ report_fonts("embedding %a hashed as %a",filename,hash)
+ end
+ end
if bitmap or method then
local format = "type3"
local writer = mainwriters[format]
- if writer then
- if trace_fonts then
- report_fonts("using main writer %a",format)
- end
- writer(details)
+ if trace_fonts then
+ report_fonts("using main writer %a",format)
end
+ writer(details)
else
local format = properties.format
local writer = mainwriters[format]
@@ -2285,7 +2289,10 @@ function lpdf.flushfonts()
-- report_fonts("no indices for %a",filename)
end
if trace_fonts then
- report_fonts("embedded indices: % t",table.sortedkeys(details.indices))
+ local indices = details.indices
+ if indices and next(indices) then
+ report_fonts("embedded indices: % t",table.sortedkeys(details.indices))
+ end
end
mainfonts[details.hash] = false -- done
end
diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt
index 826c1ce21..8d3fc7fde 100644
--- a/tex/context/base/mkxl/lpdf-lmt.lmt
+++ b/tex/context/base/mkxl/lpdf-lmt.lmt
@@ -3028,6 +3028,7 @@ do
--
statistics.register("result saved in file", function()
local outputfilename = environment.outputfilename or environment.jobname or tex.jobname or "<unset>"
+ outputfilename = string.gsub(outputfilename,"^%./+","") -- todo: make/use a helper
return string.format("%s.%s, compresslevel %s, objectcompresslevel %s",outputfilename,"pdf",lpdf.getcompression())
end)
--
diff --git a/tex/context/base/mkxl/lpdf-wid.lmt b/tex/context/base/mkxl/lpdf-wid.lmt
index fcc7b9c99..87cfcccd1 100644
--- a/tex/context/base/mkxl/lpdf-wid.lmt
+++ b/tex/context/base/mkxl/lpdf-wid.lmt
@@ -25,7 +25,7 @@ if not modules then modules = { } end modules ['lpdf-wid'] = {
-- html5 media in pdf then.
--
-- See mail by Michal Vlasák to the mailing list that discusses current support in
--- viewers and also mentions a few fixes wrt embedding media.
+-- viewers and also mentions (and submitted) a few fixes wrt embedding media.
local tonumber, next = tonumber, next
local gmatch, gsub, find, lower = string.gmatch, string.gsub, string.find, string.lower
@@ -60,6 +60,7 @@ local v_auto = variables.auto
local v_embed = variables.embed
local v_max = variables.max
local v_yes = variables.yes
+local v_compress = variables.compress
local pdfconstant = lpdf.constant
local pdfnull = lpdf.null
@@ -649,6 +650,7 @@ local function insertrenderingwindow(specification)
Subtype = pdfconstant("Screen"),
P = pdfreference(pdfpagereference(page)),
A = a, -- needed in order to make the annotation clickable (i.e. don't bark)
+ T = pdfunicode(label), -- for JS
Border = bs,
C = bc,
AA = actions,
@@ -662,7 +664,7 @@ end
-- some dictionaries can have a MH (must honor) or BE (best effort) capsule
local function insertrendering(specification)
- local label = specification.label
+ local label = specification.label
local option = settings_to_hash(specification.option)
if not mf[label] then
local filename = specification.filename
@@ -693,7 +695,7 @@ local function insertrendering(specification)
-- }
-- }
local parameters = pdfdictionary {
- Type = pdfconstant(MediaPermissions),
+ Type = pdfconstant("MediaPermissions"),
TF = pdfstring("TEMPALWAYS"), -- TEMPNEVER TEMPEXTRACT TEMPACCESS TEMPALWAYS / needed for acrobat/wmp
}
local descriptor = pdfdictionary {
@@ -707,7 +709,7 @@ local function insertrendering(specification)
descriptor = codeinjections.embedfile {
file = filename,
mimetype = mimetype, -- yes or no
- compress = false,
+ compress = option[v_compress] or false,
forcereference = true,
}
end
@@ -723,7 +725,7 @@ local function insertrendering(specification)
local rendition = pdfdictionary {
Type = pdfconstant("Rendition"),
S = pdfconstant("MR"),
- N = label,
+ N = pdfunicode(label),
C = pdfreference(pdfflushobject(clip)),
}
mf[label] = pdfreference(pdfflushobject(rendition))
@@ -761,6 +763,21 @@ function codeinjections.processrendering(label)
end
end
+-- needed mapping for access from JS
+
+local function flushrenderings()
+ if next(mf) then
+ local r = pdfarray()
+ for label, reference in sortedhash(mf) do
+ r[#r+1] = pdfunicode(label)
+ r[#r+1] = reference -- already a reference
+ end
+ lpdf.addtonames("Renditions",pdfreference(pdfflushobject(pdfdictionary{ Names = r })))
+ end
+end
+
+lpdf.registerdocumentfinalizer(flushrenderings,"renderings")
+
function codeinjections.insertrenderingwindow(specification)
local label = specification.label
codeinjections.processrendering(label)
diff --git a/tex/context/base/mkxl/luat-lib.mkxl b/tex/context/base/mkxl/luat-lib.mkxl
index d26c90af5..7ad29e29e 100644
--- a/tex/context/base/mkxl/luat-lib.mkxl
+++ b/tex/context/base/mkxl/luat-lib.mkxl
@@ -18,7 +18,7 @@
\registerctxluafile{util-fil}{autosuffix}
\registerctxluafile{util-sac}{autosuffix}
\registerctxluafile{util-sto}{} % could also be done in trac-deb.mkiv
-\registerctxluafile{util-pck}{}
+\registerctxluafile{util-pck}{autosuffix}
\registerctxluafile{util-prs}{}
\registerctxluafile{util-fmt}{}
\registerctxluafile{util-dim}{}
diff --git a/tex/context/base/mkxl/lxml-ini.mkxl b/tex/context/base/mkxl/lxml-ini.mkxl
index b18d8053b..be249c1f3 100644
--- a/tex/context/base/mkxl/lxml-ini.mkxl
+++ b/tex/context/base/mkxl/lxml-ini.mkxl
@@ -195,6 +195,23 @@
%xmlpopdocument
\endgroup}
+% This still doesn't solve a problem with weird grouping (start inside xml and
+% end outside, so one has to do proper grouping inside xml mode).
+%
+% \def\lxml_process#1#2#3#4#5% flag \loader id name what initializersetup
+% {%\begingroup
+% \pushmacro\xmldocument
+% \edef\xmldocument{#3}% #2 can be \xmldocument and set as such
+% #2{#3}{#4}%
+% \pushcatcodetable
+% \setcatcodetable\notcatcodes
+% \doifelsenothing{#5}%
+% {\xmlsetup{#3}{xml:process}}%
+% {\xmlsetup{#3}{#5}}%
+% \popcatcodetable
+% \popmacro\xmldocument
+% }%\endgroup}
+
\permanent\protected\def\xmlprocessfile {\lxml_process\plusone \xmlload}
\permanent\protected\def\xmlprocessdata {\lxml_process\zerocount\xmlloaddata}
\permanent\protected\def\xmlprocessbuffer{\lxml_process\zerocount\xmlloadbuffer}
diff --git a/tex/context/base/mkxl/math-ini.lmt b/tex/context/base/mkxl/math-ini.lmt
index 857f21013..e31b14af3 100644
--- a/tex/context/base/mkxl/math-ini.lmt
+++ b/tex/context/base/mkxl/math-ini.lmt
@@ -120,13 +120,13 @@ local accents = allocate {
local codes = allocate {
ordinary = 0, [0] = "ordinary",
- largeoperator = 1, [1] = "largeoperator",
- binaryoperator = 2, [2] = "binaryoperator",
- relation = 3, [3] = "relation",
- openingsymbol = 4, [4] = "openingsymbol",
- closingsymbol = 5, [5] = "closingsymbol",
- punctuation = 6, [6] = "punctuation",
- variable = 7, [7] = "variable",
+ largeoperator = 1, "largeoperator",
+ binaryoperator = 2, "binaryoperator",
+ relation = 3, "relation",
+ openingsymbol = 4, "openingsymbol",
+ closingsymbol = 5, "closingsymbol",
+ punctuation = 6, "punctuation",
+ variable = 7, "variable",
}
local extensibles = allocate {
diff --git a/tex/context/base/mkxl/math-map.lmt b/tex/context/base/mkxl/math-map.lmt
index 783b9db74..304cbe592 100644
--- a/tex/context/base/mkxl/math-map.lmt
+++ b/tex/context/base/mkxl/math-map.lmt
@@ -688,9 +688,9 @@ local issygreek = regular_tf.symbols
local isgreek = merged(islcgreek,isucgreek,issygreek)
local greekremapping = {
- [1] = { what = "unchanged" }, -- upright
- [2] = { what = "upright", it = "tf", bi = "bf" }, -- upright
- [3] = { what = "italic", tf = "it", bf = "bi" }, -- italic
+ { what = "unchanged" }, -- upright
+ { what = "upright", it = "tf", bi = "bf" }, -- upright
+ { what = "italic", tf = "it", bf = "bi" }, -- italic
}
local usedremap = { }
diff --git a/tex/context/base/mkxl/math-rad.mklx b/tex/context/base/mkxl/math-rad.mklx
index 8906efdc8..c5445f8f1 100644
--- a/tex/context/base/mkxl/math-rad.mklx
+++ b/tex/context/base/mkxl/math-rad.mklx
@@ -110,12 +110,14 @@
\def\m_math_no_degree{{}}
+% style width [options: left middle right]
+
\def\math_radical_alternative{\csname\??mathradicalalternative\mathradicalparameter\c!alternative\endcsname}
-\setvalue{\??mathradicalalternative\v!default}% #body%
+\defcsname\??mathradicalalternative\v!default\endcsname % #body%
{\rootradical{\currentmathradicaldegree}} % {#body}}
-\setvalue{\??mathradicalalternative\v!normal}#body%
+\defcsname\??mathradicalalternative\v!normal\endcsname#body%
{\edef\p_color{\mathradicalparameter\c!color}%
\ifempty\p_color
\styledrootradical{\currentmathradicaldegree}{#body}% {} really needed as \rootradical expands first
@@ -150,7 +152,7 @@
% todo: spacing .. this is just an experiment (article driven)
-\setvalue{\??mathradicalalternative\v!mp}#body% we could use dowithnextbox
+\defcsname\??mathradicalalternative\v!mp\endcsname#body% we could use dowithnextbox
{\begingroup
\scratchoffset\mathradicalparameter\c!mpoffset
\setbox\nextbox\mathstylehbox{#body}%
@@ -213,7 +215,7 @@
\csname\??mathornamentalternative\mathornamentparameter\c!alternative\endcsname{#body}%
\endgroup}
-\setvalue{\??mathornamentalternative\v!mp}#body% we could use dowithnextbox
+\defcsname\??mathornamentalternative\v!mp\endcsname#body% we could use dowithnextbox
{\begingroup
\scratchoffset\mathornamentparameter\c!mpoffset
\setbox\nextbox\mathstylehbox{#body}%
diff --git a/tex/context/base/mkxl/meta-ini.mkxl b/tex/context/base/mkxl/meta-ini.mkxl
index 8abd1339a..b30f4826f 100644
--- a/tex/context/base/mkxl/meta-ini.mkxl
+++ b/tex/context/base/mkxl/meta-ini.mkxl
@@ -514,7 +514,8 @@
\meta_mpvar_default
\orelse\ifchkdim\m_meta_current_variable\or
\todimension\m_meta_current_variable\space\space
- \orelse\ifchknum\m_meta_current_variable\or
+ % \orelse\ifchknum\m_meta_current_variable\or % we need to catch 1>2
+ \orunless\iftok{\ifchknum\m_meta_current_variable\or\tointeger\m_meta_current_variable\fi}\emptytoks
\tointeger\m_meta_current_variable\space\space
\orelse\ifcsname\??colorattribute\currentcolorprefix\m_meta_current_variable\endcsname
\MPcolor\m_meta_current_variable\space
@@ -532,7 +533,8 @@
\meta_mpvar_default
\orelse\ifchkdim\m_meta_current_variable\or
\todimension\m_meta_current_variable\space\space
- \orelse\ifchknum\m_meta_current_variable\or
+ % \orelse\ifchknum\m_meta_current_variable\or % we need to catch 1>2
+ \orunless\iftok{\ifchknum\m_meta_current_variable\or\tointeger\m_meta_current_variable\fi}\emptytoks
\tointeger\m_meta_current_variable\space\space
\orelse\ifcsname\??colorattribute\currentcolorprefix\m_meta_current_variable\endcsname
\MPcolor\m_meta_current_variable\space
diff --git a/tex/context/base/mkxl/mlib-ctx.lmt b/tex/context/base/mkxl/mlib-ctx.lmt
index 13dba92cd..64225e308 100644
--- a/tex/context/base/mkxl/mlib-ctx.lmt
+++ b/tex/context/base/mkxl/mlib-ctx.lmt
@@ -118,15 +118,15 @@ implement {
arguments = "string",
actions = function(name)
local value = metapost.variables[name]
- if value ~= nil then
- local tvalue = type(value)
- if tvalue == "table" then
- context(concat(value," "))
- elseif tvalue == "number" or tvalue == "boolean" then
- context(tostring(value))
- elseif tvalue == "string" then
- context(value)
- end
+ local tvalue = type(value)
+ if tvalue == "nil" then
+ context("0")
+ elseif tvalue == "table" then
+ context(concat(value," "))
+ elseif tvalue == "number" or tvalue == "boolean" then
+ context(tostring(value))
+ elseif tvalue == "string" then
+ context(value)
end
end
}
@@ -362,16 +362,6 @@ function mptex.reset()
end
implement {
- name = "mppushvariables",
- actions = metapost.pushvariables,
-}
-
-implement {
- name = "mppopvariables",
- actions = metapost.popvariables,
-}
-
-implement {
name = "mptexset",
arguments = "string",
actions = mptex.set
diff --git a/tex/context/base/mkxl/mlib-lmp.lmt b/tex/context/base/mkxl/mlib-lmp.lmt
index e4944c92e..1614f0951 100644
--- a/tex/context/base/mkxl/mlib-lmp.lmt
+++ b/tex/context/base/mkxl/mlib-lmp.lmt
@@ -8,7 +8,9 @@ if not modules then modules = { } end modules ['mlib-lmp'] = {
-- path relates stuff ... todo: use a stack (or numeric index to list)
-local type = type
+local type, tonumber, tostring = type, tonumber, tostring
+local find, match = string.find, string.match
+local insert, remove = table.insert, table.remove
local aux = mp.aux
local mpnumeric = aux.numeric
@@ -18,60 +20,86 @@ local registerdirect = metapost.registerdirect
local registerscript = metapost.registerscript
local scan = mp.scan
+local skip = mp.skip
local get = mp.get
+local inject = mp.inject
+
local scannumber = scan.number
local scanstring = scan.string
+local scaninteger = scan.integer
+local scannumeric = scan.numeric
+local scanwhatever = scan.whatever
local scanpath = scan.path
local scanproperty = scan.property
+
local gethashentry = get.hashentry
-local p = nil
-local n = 0
+local bpfactor = number.dimenfactors.bp
-registerscript("pathreset", function()
- p = nil
- n = 0
-end)
+local injectwhatever = inject.whatever
+local injectboolean = inject.boolean
+local injectnumeric = inject.numeric
+local injectstring = inject.string
+local injectpair = inject.pair
-registerscript("pathlengthof", function()
- p = scanpath()
- n = p and #p or 1
- mpnumeric(n)
-end)
+local injectwhd = inject.whd -- scaled
+local injectxy = inject.xy
+local injectpt = inject.pt
-registerscript("pathpointof", function()
- local i = scannumber()
- if i > 0 and i <= n then
- local pi = p[i]
- mppair(pi[1],pi[2])
- end
-end)
+local report = logs.reporter("metapost", "log")
+local report_message = logs.reporter("metapost")
-registerscript("pathleftof", function()
- local i = scannumber()
- if i > 0 and i <= n then
- local pi = p[i]
- mppair(pi[5],pi[6])
- end
-end)
+local codes = metapost.codes
+local types = metapost.types
+local procodes = mplib.propertycodes
-registerscript("pathrightof", function()
- local i = scannumber()
- if i > 0 and i <= n then
- local pn
- if i == 1 then
- pn = p[2] or p[1]
- else
- pn = p[i+1] or p[1]
+local implement = interfaces.implement
+
+do
+
+ local p = nil
+ local n = 0
+
+ registerscript("pathreset", function()
+ p = nil
+ n = 0
+ end)
+
+ registerdirect("pathlengthof", function()
+ p = scanpath()
+ return p and #p or 1
+ end)
+
+ registerdirect("pathpointof", function()
+ local i = scannumber()
+ if i > 0 and i <= n then
+ local pi = p[i]
+ injectpair(pi[1],pi[2])
end
- mppair(pn[3],pn[4])
- end
-end)
+ end)
-local report = logs.reporter("metapost", "log")
-local codes = metapost.codes
-local types = metapost.types
-local procodes = mplib.propertycodes
+ registerdirect("pathleftof", function()
+ local i = scannumber()
+ if i > 0 and i <= n then
+ local pi = p[i]
+ injectpair(pi[5],pi[6])
+ end
+ end)
+
+ registerdirect("pathrightof", function()
+ local i = scannumber()
+ if i > 0 and i <= n then
+ local pn
+ if i == 1 then
+ pn = p[2] or p[1]
+ else
+ pn = p[i+1] or p[1]
+ end
+ injectpair(pn[3],pn[4])
+ end
+ end)
+
+end
registerscript("showproperty", function()
local k, s, p, d = scanproperty()
@@ -92,9 +120,6 @@ end)
-- local getmacro = tokens.getters.macro
-- local mpgnamespace = getmacro("??graphicvariable")
--- local scanmpstring = mp.scan.string
--- local injectnumeric = mp.inject.numeric
--- local injectstring = mp.inject.string
-- registerscript("mpv_numeric", function() injectnumeric (getmacro(mpgnamespace .. getmacro("currentmpcategory") .. ":" .. scanmpstring())) end)
-- registerscript("mpv_dimension", function() return getmacro(mpgnamespace .. getmacro("currentmpcategory") .. ":" .. scanmpstring()) end)
@@ -103,46 +128,380 @@ end)
-- registerscript("mpvar", function() return getmacro(mpgnamespace .. getmacro("currentmpcategory") .. ":" .. scanmpstring(), true) end) -- Isn't it already edef'd?
-- registerscript("mpvar", function() return getmacro(metapost.namespace .. scanmpstring(), true) end) -- Isn't it already edef'd?
-local scanstring = mp.scan.string
-local expandtex = mp.expandtex
+do
+
+ local expandtex = mp.expandtex
+
+ local tokenvalues = tokens.values
+ local dimension_value = tokenvalues.dimension
+ local integer_value = tokenvalues.integer
+ local boolean_value = tokenvalues.boolean
+ local string_value = tokenvalues.string
+ local unknown_value = tokenvalues.none
+
+ registerdirect("mpvard", function()
+ if not expandtex(dimension_value,"mpcategoryparameter",true,scanstring()) then
+ injectnumeric(0)
+ end
+ end)
+
+ registerdirect("mpvarn", function()
+ if not expandtex(integer_value,"mpcategoryparameter",true,scanstring()) then
+ injectnumeric(0)
+ end
+ end)
+
+ registerdirect("mpvars", function()
+ if not expandtex(string_value,"mpcategoryparameter",true,scanstring()) then
+ injectstring("")
+ end
+ end)
+
+ registerdirect("mpvarb", function()
+ if not expandtex(boolean_value,"mpcategoryparameter",true,scanstring()) then
+ injectboolean(false)
+ end
+ end)
+
+ registerdirect("mpvar", function()
+ if not expandtex(unknown_value,"mpcategoryparameter",true,scanstring()) then
+ injectnumeric(0)
+ end
+ end)
-local injectnumeric = mp.inject.numeric
-local injectstring = mp.inject.string
-local injectboolean = mp.inject.boolean
+ --
-local tokenvalues = tokens.values
-local dimension_value = tokenvalues.dimension
-local integer_value = tokenvalues.integer
-local boolean_value = tokenvalues.boolean
-local string_value = tokenvalues.string
-local unknown_value = tokenvalues.none
+ local mpprint = mp.print
+ local mpquoted = mp.quoted
+ local getmacro = tokens.getters.macro
-registerdirect("mpvard", function()
- if not expandtex(dimension_value,"mpcategoryparameter",true,scanstring()) then
- injectnumeric(0)
+ registerscript("texvar", function() mpprint (getmacro(metapost.namespace .. scanstring())) end)
+ registerscript("texstr", function() mpquoted(getmacro(metapost.namespace .. scanstring())) end)
+
+end
+
+do
+
+ registerscript("textextanchor", function()
+ local x, y = match(scanstring(),"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg
+ if x and y then
+ x = tonumber(x)
+ y = tonumber(y)
+ end
+ injectpair(x or 0,y or 0)
+ end)
+
+end
+
+do
+
+ local mpnamedcolor = attributes.colors.mpnamedcolor
+ local mpprint = mp.aux.print
+
+ mp.mf_named_color = function(str)
+ mpprint(mpnamedcolor(str))
end
-end)
-registerdirect("mpvarn", function()
- if not expandtex(integer_value,"mpcategoryparameter",true,scanstring()) then
- injectnumeric(0)
+ -- todo: we can inject but currently we always get a string back so then
+ -- we need to deal with it upstream in the color module ... not now
+
+ registerscript("namedcolor",function() mpprint(mpnamedcolor(scanstring())) end)
+
+end
+
+do
+
+ local hashes = table.setmetatableindex("table")
+
+ registerdirect("lmt_hash_new", function()
+ -- local name = scanstring()
+ local name = scanwhatever()
+ hashes[name] = { }
+ end)
+
+ registerdirect("lmt_hash_dispose", function()
+ -- local name = scanstring()
+ local name = scanwhatever()
+ hashes[name] = nil
+ end)
+
+ registerdirect("lmt_hash_in", function()
+ -- local name = scanstring()
+ local name = scanwhatever()
+ -- local key = scanstring()
+ local key = scanwhatever()
+ local hash = hashes[name]
+ injectwhatever(hash and hash[key] and true or false)
+ end)
+
+ registerdirect("lmt_hash_to", function()
+ -- local name = scanstring()
+ local name = scanwhatever()
+ -- local key = scanstring()
+ local key = scanwhatever()
+ local value = scanwhatever()
+ local hash = hashes[name]
+ if hash then
+ hash[key] = value
+ end
+ end)
+
+ registerdirect("lmt_hash_from", function()
+ -- local name = scanstring()
+ local name = scanwhatever()
+ -- local key = scanstring()
+ local key = scanwhatever()
+ local hash = hashes[name]
+ injectwhatever(hash and hash[key] or false)
+ end)
+
+ interfaces.implement {
+ name = "MPfromhash",
+ arguments = "2 strings",
+ actions = function(name,key)
+ local hash = hashes[name] or hashes[tonumber(name)] or hashes[tostring(name)]
+ if hash then
+ local v = hash[key]
+ if v then
+ context(v)
+ end
+ end
+ end
+ }
+
+end
+
+do
+
+ local bpfactor = number.dimenfactors.bp
+ local nbdimensions = nodes.boxes.dimensions
+
+ registerdirect("boxdimensions", function()
+ local category = scanstring()
+ local index = scanwhatever()
+ injectwhd(nbdimensions(category,index))
+ end)
+
+end
+
+do
+
+ local skiptoken = skip.token
+
+ local comma_code = codes.comma
+
+ local getmacro = tokens.getters.macro
+ local setmacro = tokens.setters.macro
+
+ local getdimen = tex.getdimen
+ local getcount = tex.getcount
+ local gettoks = tex.gettoks
+ local setdimen = tex.setdimen
+ local setcount = tex.setcount
+ local settoks = tex.settoks
+
+ -- more helpers
+
+ registerdirect("getmacro", function() return getmacro(scanstring()) end)
+ registerdirect("getcount", function() return getcount(scanwhatever()) end)
+ registerdirect("gettoks", function() return gettoks (scanwhatever()) end)
+ registerdirect("getdimen", function() return getdimen(scanwhatever()) * bpfactor end)
+
+ registerscript("setmacro", function() setmacro(scanstring(),scanstring()) end)
+ registerscript("setdimen", function() setdimen(scanwhatever(),scannumeric()/bpfactor) end)
+ registerscript("setcount", function() setcount(scanwhatever(),scannumeric()) end)
+ registerscript("settoks", function() settoks (scanwhatever(),scanstring()) end)
+
+ registerscript("setglobalmacro", function() setmacro(scanstring(),scanstring(),"global") end)
+ registerscript("setglobaldimen", function() setdimen("global",scanwhatever(),scannumeric()/bpfactor) end)
+ registerscript("setglobalcount", function() setcount("global",scanwhatever(),scaninteger()) end)
+ registerscript("setglobaltoks", function() settoks ("global",scanwhatever(),scanstring()) end)
+
+ local utfnum = utf.byte
+ local utflen = utf.len
+ local utfsub = utf.sub
+
+ registerdirect("utfnum", function() return utfnum(scanstring()) end)
+ registerdirect("utflen", function() return utflen(scanstring()) end)
+
+ registerdirect("utfsub", function() -- we have an optional third argument so we explicitly scan a text argument
+ return utfsub(scanstring(),skiptoken(comma_code) and scannumeric(),skiptoken(comma_code) and scannumeric())
+ end)
+
+ local setlogging = metapost.setlogging
+
+ registerscript("message", function()
+ setlogging(false)
+ local str = scanstring()
+ setlogging(true)
+ report_message("message : %s",str)
+ end)
+
+end
+
+-- position fun
+
+do
+
+ local mpprint = mp.print
+ local mpfprint = mp.fprint
+
+ local jobpositions = job.positions
+ local getwhd = jobpositions.whd
+ local getxy = jobpositions.xy
+ local getposition = jobpositions.position
+ local getpage = jobpositions.page
+ local getparagraph = jobpositions.paragraph
+ local getregion = jobpositions.region
+ local getcolumn = jobpositions.column
+ local getmacro = tokens.getters.macro
+
+ registerscript("positionpath", function()
+ local w, h, d = getwhd(scanstring())
+ if w then
+ mpfprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",0,-d,w,-d,w,h,0,h)
+ else
+ mpprint("(origin--cycle)")
+ end
+ end)
+
+ registerscript("positioncurve", function()
+ local w, h, d = getwhd(scanstring())
+ if w then
+ mpfprint("((%p,%p)..(%p,%p)..(%p,%p)..(%p,%p)..cycle)",0,-d,w,-d,w,h,0,h)
+ else
+ mpprint("(origin--cycle)")
+ end
+ end)
+
+ registerscript("positionbox", function()
+ local p, x, y, w, h, d = getposition(scanstring())
+ if p then
+ mpfprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",x,y-d,x+w,y-d,x+w,y+h,x,y+h)
+ else
+ mpprint("(%p,%p)--cycle",x or 0,y or 0)
+ end
+ end)
+
+ registerdirect("positionpage", function() return getpage (scanstring()) or 0 end)
+ registerdirect("positioncolumn", function() return getcolumn (scanstring()) or 0 end)
+ registerdirect("positionparagraph", function() return getparagraph(scanstring()) or 0 end)
+ registerdirect("positionregion", function() return getregion (scanstring()) or "unknown" end)
+ registerdirect("positionanchor", function() return getmacro ("MPanchorid") end)
+ registerdirect("positionwhd", function() injectwhd(getwhd(scanstring())) end)
+ registerdirect("positionxy", function() injectxy (getxy (scanstring())) end)
+ registerdirect("positionx", function() injectpt (getx (scanstring())) end)
+ registerdirect("positiony", function() injectpt (gety (scanstring())) end)
+
+end
+
+do
+
+ local modes = tex.modes
+ local systemmodes = tex.systemmodes
+
+ registerdirect("mode", function() injectboolean(modes [scanstring()] and true or false) end)
+ registerdirect("systemmode", function() injectboolean(systemmodes[scanstring()] and true or false) end)
+
+end
+
+-- for alan's nodes:
+
+do
+
+ local lpegmatch, lpegpatterns, P = lpeg.match, lpeg.patterns, lpeg.P
+
+ -- todo: scansuffix / why no return boolean (first one)
+
+ registerdirect("isarray", function()
+ injectboolean(find(scanstring(),"%d") and true or false)
+ end)
+
+ registerdirect("prefix", function()
+ local str = scanstring()
+ return match(str,"^(.-)[%d%[]") or str
+ end)
+
+ local dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer)
+
+ registerdirect("dimension", function() return dimension(scanstring()) end)
+
+ -- todo : share with mlib-pps.lua metapost,isobject
+
+ -- registerdirect("isobject", function()
+ -- injectboolean(find(scanstring(),"mf_object="))
+ -- end
+
+ local p1 = P("mf_object=")
+ local p2 = lpegpatterns.eol * p1
+ local pattern = (1-p2)^0 * p2 + p1
+
+ registerdirect("isobject", function()
+ local str = scanstring()
+ injectboolean(pattern and str ~= "" and lpegmatch(pattern,str))
+ end)
+
+end
+
+-- key/values (moved here, old mechanism)
+
+do
+
+ local stack, top = { }, nil
+
+ local function setvariable(k,v)
+ if top then
+ top[k] = v
+ else
+ metapost.variables[k] = v
+ end
end
-end)
-registerdirect("mpvars", function()
- if not expandtex(string_value,"mpcategoryparameter",true,scanstring()) then
- injectstring("")
+ local function pushvariable(k)
+ local t = { }
+ if top then
+ insert(stack,top)
+ top[k] = t
+ else
+ metapost.variables[k] = t
+ end
+ top = t
end
-end)
-registerdirect("mpvarb", function()
- if not expandtex(boolean_value,"mpcategoryparameter",true,scanstring()) then
- injectboolean(false)
+ local function popvariable()
+ top = remove(stack)
end
-end)
-registerdirect("mpvar", function()
- if not expandtex(unknown_value,"mpcategoryparameter",true,scanstring()) then
- injectnumeric(0)
+ registerscript("passvariable", function() setvariable (scanstring(), scanwhatever()) end)
+ registerscript("pushvariable", function() pushvariable(scanstring()) end)
+ registerscript("popvariable", function() popvariable () end)
+
+ local stack = { }
+
+ local function pushvariables()
+ insert(stack,metapost.variables)
+ metapost.variables = { }
end
-end)
+
+ local function popvariables()
+ metapost.variables = remove(stack) or metapost.variables
+ end
+
+ metapost.setvariable = setvariable
+ metapost.pushvariable = pushvariable
+ metapost.popvariable = popvariable
+ metapost.pushvariables = pushvariables
+ metapost.popvariables = popvariables
+
+ implement {
+ name = "mppushvariables",
+ actions = pushvariables,
+ }
+
+ implement {
+ name = "mppopvariables",
+ actions = popvariables,
+ }
+
+end
+
diff --git a/tex/context/base/mkxl/mlib-lua.lmt b/tex/context/base/mkxl/mlib-lua.lmt
index ceca9668a..e40954456 100644
--- a/tex/context/base/mkxl/mlib-lua.lmt
+++ b/tex/context/base/mkxl/mlib-lua.lmt
@@ -16,8 +16,6 @@ local report = logs.reporter("metapost","instance")
local codes = mplib.getcodes()
local types = mplib.gettypes()
--- for k,v in next, mplib do if type(v) == "function" then local f = v mplib[k] = function(...) print(k) return v(...) end end end
-
table.hashed(codes)
table.hashed(types)
@@ -29,6 +27,7 @@ local skip = mp.skip
local get = mp.get
local inject = mp.inject
+local bpfactor = number.dimenfactors.bp
local currentmpx = nil
local stack = { }
@@ -106,6 +105,12 @@ inject.whatever = function(...) if trace then reporti("whatever")
inject.triplet = inject.color
inject.quadruplet = inject.cmykcolor
+-- these can be optimized for zero:
+
+inject.whd = function(w,h,d) injectcolor (currentmpx,(w or 0)*bpfactor,(h or 0)*bpfactor,(d or 0)*bpfactor) end
+inject.xy = function(x,y) injectpair (currentmpx,(x or 0)*bpfactor,(y or 0)*bpfactor) end
+inject.pt = function(n) injectnumeric(currentmpx,(x or 0)*bpfactor) end
+
local function same(p,n)
local f = p[1]
local l = p[n]
@@ -122,35 +127,6 @@ local function same(p,n)
return false
end
--- local p = mp.scan.path()
--- mp.inject.path(p,true,true)
-
--- function inject.path(p,close,connector)
--- local curled = false
--- local n = #p
--- if p.close or p.cycle then
--- close = true
--- end
--- if p.curled then
--- curled = true
--- end
--- if n > 1 then
--- -- [ ../true | --/false | nil/auto ]
--- if connector == nil or connector == "auto" then
--- connector = #p[1] > 2
--- end
--- if connector == false or connector == "--" then
--- curled = true
--- elseif connector == true or connector == ".." then
--- if close and not same(p,n) then
--- p[n+1] = p[1]
--- end
--- end
--- end
--- if trace then reporti("path") end
--- return injectpath(currentmpx,p,close,curled)
--- end
-
function inject.path(p,close,connector)
local closed = false
local curled = false
diff --git a/tex/context/base/mkxl/mlib-mpf.lmt b/tex/context/base/mkxl/mlib-mpf.lmt
index 086bfb0ea..7c359fe96 100644
--- a/tex/context/base/mkxl/mlib-mpf.lmt
+++ b/tex/context/base/mkxl/mlib-mpf.lmt
@@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['mlib-mpf'] = {
-- moved from mlib-lua:
local type, tostring, tonumber, select, loadstring = type, tostring, tonumber, select, loadstring
-local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch
+local find, gsub = string.find, string.gsub
local concat = table.concat
local formatters = string.formatters
@@ -31,8 +31,6 @@ local set = mp.set
local get = mp.get
local aux = mp.aux
local scan = mp.scan
-local skip = mp.skip
-local inject = mp.inject
do
@@ -41,7 +39,7 @@ do
local f_integer = formatters["%i"]
local f_numeric = formatters["%F"]
- -- no %n as that can produce -e notation and that is not so nice for scaled butmaybe we
+ -- no %n as that can produce -e notation and that is not so nice for scaled but maybe we
-- should then switch between ... i.e. make a push/pop for the formatters here ... not now.
local f_integer = formatters["%i"]
@@ -127,31 +125,9 @@ do
local buffer = gbuffer
local n = 0
- local function mpdirect1(a)
+ local function mpdirect(a)
n = n + 1 buffer[n] = a
end
- local function mpdirect2(a,b)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- end
- local function mpdirect3(a,b,c)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- n = n + 1 buffer[n] = c
- end
- local function mpdirect4(a,b,c,d)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- n = n + 1 buffer[n] = c
- n = n + 1 buffer[n] = d
- end
- local function mpdirect5(a,b,c,d,e)
- n = n + 1 buffer[n] = a
- n = n + 1 buffer[n] = b
- n = n + 1 buffer[n] = c
- n = n + 1 buffer[n] = d
- n = n + 1 buffer[n] = e
- end
local function mpflush(separator)
buffer[1] = concat(buffer,separator or "",1,n)
@@ -299,7 +275,7 @@ do
-- writers
- local function mpp(value)
+ local function rawmpp(value)
n = n + 1
local t = type(value)
if t == "number" then
@@ -320,13 +296,13 @@ do
local function mpprint(first,second,...)
if second == nil then
if first ~= nil then
- mpp(first)
+ rawmpp(first)
end
else
for i=1,select("#",first,second,...) do
local value = (select(i,first,second,...))
if value ~= nil then
- mpp(value)
+ rawmpp(value)
end
end
end
@@ -404,7 +380,7 @@ do
if type(x) == "table" then
buffer[n] = f_pair(x[1],x[2])
else
- buffer[n] = f_pair(x,y)
+ buffer[n] = f_pair(x,y or x)
end
end
@@ -413,7 +389,7 @@ do
if type(x) == "table" then
buffer[n] = f_pair_pt(x[1],x[2])
else
- buffer[n] = f_pair_pt(x,y)
+ buffer[n] = f_pair_pt(x,y or x)
end
end
@@ -605,11 +581,7 @@ do
end
end
- aux.direct = mpdirect1
- aux.direct1 = mpdirect1
- aux.direct2 = mpdirect2
- aux.direct3 = mpdirect3
- aux.direct4 = mpdirect4
+ aux.direct = mpdirect
aux.flush = mpflush
aux.print = mpprint
@@ -705,12 +677,29 @@ do
for k, v in next, aux do mp[k] = v end
+ -- mp.print = table.setmetatablecall(aux, function(t,...)
+ -- mpprint(...)
+ -- end)
+
+ mp.print = table.setmetatablecall(aux, function(t,first,second,...)
+ if second == nil then
+ if first ~= nil then
+ rawmpp(first)
+ end
+ else
+ for i=1,select("#",first,second,...) do
+ local value = (select(i,first,second,...))
+ if value ~= nil then
+ rawmpp(value)
+ end
+ end
+ end
+ end)
+
end
do
- -- Another experimental feature:
-
local mpnumeric = mp.numeric
local scanstring = scan.string
local scriptindex = metapost.scriptindex
@@ -729,27 +718,6 @@ do
end
--- the next will move to mlib-lmp.lua
-
-do
-
- local mpnamedcolor = attributes.colors.mpnamedcolor
- local mpprint = aux.print
- local scanstring = scan.string
-
- mp.mf_named_color = function(str)
- mpprint(mpnamedcolor(str))
- end
-
- -- todo: we can inject but currently we always get a string back so then
- -- we need to deal with it upstream in the color module ... not now
-
- metapost.registerscript("namedcolor",function()
- mpprint(mpnamedcolor(scanstring()))
- end)
-
-end
-
function mp.n(t) -- used ?
return type(t) == "table" and #t or 0
end
@@ -839,407 +807,14 @@ end
-- texts:
-do
-
- local mptriplet = mp.triplet
-
- local bpfactor = number.dimenfactors.bp
- local textexts = nil
- local mptriplet = mp.triplet
- local nbdimensions = nodes.boxes.dimensions
-
- function mp.mf_tt_initialize(tt)
- textexts = tt
- end
-
- function mp.mf_tt_dimensions(n)
- local box = textexts and textexts[n]
- if box then
- -- could be made faster with nuts but not critical
- mptriplet(box.width*bpfactor,box.height*bpfactor,box.depth*bpfactor)
- else
- mptriplet(0,0,0)
- end
- end
-
- function mp.mf_tb_dimensions(category,name)
- local w, h, d = nbdimensions(category,name)
- mptriplet(w*bpfactor,h*bpfactor,d*bpfactor)
- end
-
- -- todo: scan ( ... )
-
- function mp.report(a,b,c,...)
- if c then
- report_message("%s : %s",a,formatters[(gsub(b,"@","%%"))](c,...))
- elseif b then
- report_message("%s : %s",a,b)
- elseif a then
- report_message("message : %s",a)
- end
- end
-
-end
-
-do
-
- local mpprint = aux.print
- local modes = tex.modes
- local systemmodes = tex.systemmodes
-
- function mp.mode(s)
- mpprint(modes[s] and true or false)
- end
-
- function mp.systemmode(s)
- mpprint(systemmodes[s] and true or false)
- end
-
- mp.processingmode = mp.mode
-
-end
-
--- for alan's nodes:
-
-do
-
- local mpprint = aux.print
- local mpquoted = aux.quoted
-
- function mp.isarray(str)
- mpprint(find(str,"%d") and true or false)
- end
-
- function mp.prefix(str)
- mpquoted(match(str,"^(.-)[%d%[]") or str)
- end
-
- -- function mp.dimension(str)
- -- local n = 0
- -- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg
- -- n = n + 1
- -- end
- -- mpprint(n)
- -- end
-
- mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint)
-
- -- faster and okay as we don't have many variables but probably only
- -- basename makes sense and even then it's not called that often
-
- -- local hash = table.setmetatableindex(function(t,k)
- -- local v = find(k,"%d") and true or false
- -- t[k] = v
- -- return v
- -- end)
- --
- -- function mp.isarray(str)
- -- mpprint(hash[str])
- -- end
- --
- -- local hash = table.setmetatableindex(function(t,k)
- -- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"'
- -- t[k] = v
- -- return v
- -- end)
- --
- -- function mp.prefix(str)
- -- mpprint(hash[str])
- -- end
-
-end
-
-do
-
- local scanstring = scan.string
- local scannumeric = scan.numeric
- local scaninteger = scan.integer
- local skiptoken = skip.token
-
- ----- injectstring = inject.string
- ----- injectnumeric = inject.numeric
-
- local registerdirect = metapost.registerdirect
- local registerscript = metapost.registerscript
-
- local comma_code = metapost.codes.comma
-
- local getmacro = tokens.getters.macro
- local setmacro = tokens.setters.macro
-
- local getdimen = tex.getdimen
- local getcount = tex.getcount
- local gettoks = tex.gettoks
- local setdimen = tex.setdimen
- local setcount = tex.setcount
- local settoks = tex.settoks
-
- local bpfactor = number.dimenfactors.bp
-
- -- more helpers
-
- -- registerscript("getmacro", function() injectstring (getmacro(scanstring())) end)
- -- registerscript("getcount", function() injectnumeric(getcount(scanstring())) end)
- -- registerscript("gettoks", function() injectstring (gettoks (scanstring())) end)
- -- registerscript("getdimen", function() injectnumeric(getdimen(scanstring()) * bpfactor) end)
-
- registerdirect("getmacro", function() return getmacro(scanstring()) end)
- registerdirect("getcount", function() return getcount(scanstring()) end)
- registerdirect("gettoks", function() return gettoks (scanstring()) end)
- registerdirect("getdimen", function() return getdimen(scanstring()) * bpfactor end)
-
- registerscript("setmacro", function() setmacro(scanstring(),scanstring()) end)
- registerscript("setdimen", function() setdimen(scanstring(),scannumeric()/bpfactor) end)
- registerscript("setcount", function() setcount(scanstring(),scannumeric()) end)
- registerscript("settoks", function() settoks (scanstring(),scanstring()) end)
-
- registerscript("setglobalmacro", function() setmacro(scanstring(),scanstring(),"global") end)
- registerscript("setglobaldimen", function() setdimen("global",scanstring(),scannumeric()/bpfactor) end)
- registerscript("setglobalcount", function() setcount("global",scanstring(),scaninteger()) end)
- registerscript("setglobaltoks", function() settoks ("global",scanstring(),scanstring()) end)
-
- local utfnum = utf.byte
- local utflen = utf.len
- local utfsub = utf.sub
-
- -- registerscript("utfnum", function() injectnumeric(utfnum(scanstring())) end)
- -- registerscript("utflen", function() injectnumeric(utflen(scanstring())) end)
- --
- -- registerscript("utfsub", function() -- we have an optional third argument so we explicitly scan a text argument
- -- injectstring(utfsub(scanstring(),skiptoken(comma_code) and scannumeric(),skiptoken(comma_code) and scannumeric()))
- -- end)
-
- registerdirect("utfnum", function() return utfnum(scanstring()) end)
- registerdirect("utflen", function() return utflen(scanstring()) end)
-
- registerdirect("utfsub", function() -- we have an optional third argument so we explicitly scan a text argument
- utfsub(scanstring(),skiptoken(comma_code) and scannumeric(),skiptoken(comma_code) and scannumeric())
- end)
-
- local setlogging = metapost.setlogging
-
- registerscript("message", function()
- setlogging(false)
- local str = scanstring()
- setlogging(true)
- report_message("message : %s",str)
- end)
-
-end
-
--- position fun
-
-do
-
- local mpprint = mp.print
- local mpfprint = mp.fprint
- local mpquoted = mp.quoted
- local jobpositions = job.positions
- local getwhd = jobpositions.whd
- local getxy = jobpositions.xy
- local getposition = jobpositions.position
- local getpage = jobpositions.page
- local getregion = jobpositions.region
- local getmacro = tokens.getters.macro
-
- function mp.positionpath(name)
- local w, h, d = getwhd(name)
- if w then
- mpfprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",0,-d,w,-d,w,h,0,h)
- else
- mpprint("(origin--cycle)")
- end
- end
-
- function mp.positioncurve(name)
- local w, h, d = getwhd(name)
- if w then
- mpfprint("((%p,%p)..(%p,%p)..(%p,%p)..(%p,%p)..cycle)",0,-d,w,-d,w,h,0,h)
- else
- mpprint("(origin--cycle)")
- end
- end
-
- function mp.positionbox(name)
- local p, x, y, w, h, d = getposition(name)
- if p then
- mpfprint("((%p,%p)--(%p,%p)--(%p,%p)--(%p,%p)--cycle)",x,y-d,x+w,y-d,x+w,y+h,x,y+h)
- else
- mpprint("(%p,%p)",x,y)
- end
- end
-
- function mp.positionxy(name)
- local x, y = getxy(name)
- if x then
- mpfprint("(%p,%p)",x,y)
- else
- mpprint("origin")
- end
- end
-
- function mp.positionpage(name)
- mpfprint("%i",getpage(name) or 0)
- end
-
- function mp.positionregion(name)
- local r = getregion(name)
- if r then
- mpquoted(r)
- else
- mpquoted("unknown")
- end
- end
-
- function mp.positionwhd(name)
- local w, h, d = getwhd(name)
- if w then
- mpfprint("(%p,%p,%p)",w,h,d)
- else
- mpprint("(0,0,0)")
- end
- end
-
- function mp.positionpxy(name)
- local p, x, y = getposition(name)
- if p then
- mpfprint("(%p,%p,%p)",p,x,y)
- else
- mpprint("(0,0,0)")
- end
- end
-
- function mp.positionanchor()
- mpquoted(getmacro("MPanchorid"))
- end
-
-end
-
-do
-
- -- local mppair = mp.pair
- --
- -- function mp.textextanchor(s)
- -- local x, y = match(s,"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg
- -- if x and y then
- -- x = tonumber(x)
- -- y = tonumber(y)
- -- end
- -- mppair(x or 0,y or 0)
- -- end
-
- local injectpair = inject.pair
- local scanstring = scan.string
-
- metapost.registerscript("textextanchor", function()
- local x, y = match(scanstring(),"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg
- if x and y then
- x = tonumber(x)
- y = tonumber(y)
- end
- injectpair(x or 0,y or 0)
- end)
-
-end
-
-do
-
- local mpprint = mp.print
- local mpquoted = mp.quoted
- local getmacro = tokens.getters.macro
-
- function mp.texvar(name)
- mpprint(getmacro(metapost.namespace .. name))
- end
-
- function mp.texstr(name)
- mpquoted(getmacro(metapost.namespace .. name))
- end
-
-end
-
-do
-
- local mpprint = aux.print
- local mpvprint = aux.vprint
-
- local hashes = { }
-
- function mp.newhash(name)
- if name then
- hashes[name] = { }
- else
- for i=1,#hashes+1 do
- if not hashes[i] then
- hashes[i] = { }
- mpvprint(i)
- return
- end
- end
- end
- end
-
- function mp.disposehash(n)
- if tonumber(n) then
- hashes[n] = false
- else
- hashes[n] = nil
- end
+function mp.report(a,b,c,...)
+ if c then
+ report_message("%s : %s",a,formatters[(gsub(b,"@","%%"))](c,...))
+ elseif b then
+ report_message("%s : %s",a,b)
+ elseif a then
+ report_message("message : %s",a)
end
-
- function mp.inhash(n,key)
- local h = hashes[n]
- mpvprint(h and h[key] and true or false)
- end
-
- function mp.tohash(n,key,value)
- local h = hashes[n]
- if h then
- if value == nil then
- h[key] = true
- else
- h[key] = value
- end
- end
- end
-
- function mp.fromhash(n,key)
- local h = hashes[n]
- mpvprint(h and h[key] or false)
- end
-
- interfaces.implement {
- name = "MPfromhash",
- arguments = "2 strings",
- actions = function(name,key)
- local h = hashes[name] or hashes[tonumber(name)]
- if h then
- local v = h[key] or h[tonumber(key)]
- if v then
- context(v)
- end
- end
- end
- }
-
-end
-
-do
-
- -- a bit overkill: just a find(str,"mf_object=") can be enough
- --
- -- todo : share with mlib-pps.lua metapost,isobject
-
- local mpboolean = aux.boolean
-
- local p1 = P("mf_object=")
- local p2 = lpegpatterns.eol * p1
- local pattern = (1-p2)^0 * p2 + p1
-
- function mp.isobject(str)
- mpboolean(pattern and str ~= "" and lpegmatch(pattern,str))
- end
-
end
function mp.flatten(t)
diff --git a/tex/context/base/mkxl/mlib-pos.lmt b/tex/context/base/mkxl/mlib-pos.lmt
index 5ea0e1a1e..fd54d7b5f 100644
--- a/tex/context/base/mkxl/mlib-pos.lmt
+++ b/tex/context/base/mkxl/mlib-pos.lmt
@@ -57,3 +57,7 @@ registerdirect("getposupperleft", function() local x, y = upperleft (scanstring
registerdirect("getposlowerleft", function() local x, y = lowerleft (scanstring()) t[1] = x * factor t[2] = y * factor return t end)
registerdirect("getposupperright", function() local x, y = upperright(scanstring()) t[1] = x * factor t[2] = y * factor return t end)
registerdirect("getposlowerright", function() local x, y = lowerright(scanstring()) t[1] = x * factor t[2] = y * factor return t end)
+registerdirect("getposllx", function() local x, y = lowerleft (scanstring()) return x * factor end)
+registerdirect("getposlly", function() local x, y = lowerleft (scanstring()) return y * factor end)
+registerdirect("getposurx", function() local x, y = upperright(scanstring()) return x * factor end)
+registerdirect("getposury", function() local x, y = upperright(scanstring()) return y * factor end)
diff --git a/tex/context/base/mkxl/mlib-run.lmt b/tex/context/base/mkxl/mlib-run.lmt
index 3e950a2d9..bf3d5434a 100644
--- a/tex/context/base/mkxl/mlib-run.lmt
+++ b/tex/context/base/mkxl/mlib-run.lmt
@@ -379,49 +379,6 @@ function metapost.reset(mpx)
end
end
--- key/values
-
-do
-
- local stack, top = { }, nil
-
- function metapost.setvariable(k,v)
- if top then
- top[k] = v
- else
- metapost.variables[k] = v
- end
- end
-
- function metapost.pushvariable(k)
- local t = { }
- if top then
- insert(stack,top)
- top[k] = t
- else
- metapost.variables[k] = t
- end
- top = t
- end
-
- function metapost.popvariable()
- top = remove(stack)
- end
-
- local stack = { }
-
- function metapost.pushvariables()
- insert(stack,metapost.variables)
- metapost.variables = { }
- end
-
- function metapost.popvariables()
- metapost.variables = remove(stack) or metapost.variables
- end
-
-end
-
-
if not metapost.process then
function metapost.process(specification)
diff --git a/tex/context/base/mkxl/mlib-scn.lmt b/tex/context/base/mkxl/mlib-scn.lmt
index 56fdce0fb..d92ef1385 100644
--- a/tex/context/base/mkxl/mlib-scn.lmt
+++ b/tex/context/base/mkxl/mlib-scn.lmt
@@ -165,6 +165,15 @@ end)
scanners.typescanners = typescanners
scanners.tokenscanners = tokenscanners
+scanners.whatever = function()
+ local kind = scantoken(true)
+ if kind == leftdelimiter_code or kind == tag_code or kind == capsule_code then
+ return (typescanners[scanexpression(true)] or scanexpression)()
+ else
+ return tokenscanners[kind]()
+ end
+end
+
-- a key like 'color' has code 'declare'
local function scanparameters(fenced)
diff --git a/tex/context/base/mkxl/mult-sys.mkxl b/tex/context/base/mkxl/mult-sys.mkxl
index 2941a7b08..6b8379753 100644
--- a/tex/context/base/mkxl/mult-sys.mkxl
+++ b/tex/context/base/mkxl/mult-sys.mkxl
@@ -399,6 +399,8 @@
\definesystemconstant {ymove}
\definesystemconstant {yoffset}
+\definesystemconstant {syncpos}
+
%D As the name of their define command states, the next set of constants is used in
%D the message macro's.
diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt
index b5a371d5e..7970c1fe5 100644
--- a/tex/context/base/mkxl/node-nut.lmt
+++ b/tex/context/base/mkxl/node-nut.lmt
@@ -150,6 +150,7 @@ local nuts = {
insertbefore = d_insertbefore,
appendaftertail = direct.appendaftertail,
prependbeforehead = direct.prependbeforehead,
+ getparstate = direct.getparstate,
isdirect = isdirect,
isnode = isnode,
isnut = isdirect,
diff --git a/tex/context/base/mkxl/pack-rul.mkxl b/tex/context/base/mkxl/pack-rul.mkxl
index 42b472aa2..96872647a 100644
--- a/tex/context/base/mkxl/pack-rul.mkxl
+++ b/tex/context/base/mkxl/pack-rul.mkxl
@@ -558,8 +558,8 @@
\edef\m_overlay_region{\reservedautoregiontag}%
\fi}
-\def\pack_framed_add_region % experiment
- {\anch_mark_tagged_box\b_framed_normal\m_overlay_region}
+\def\pack_framed_add_region % experiment, zerocount forces the given region
+ {\anch_mark_tagged_box\b_framed_normal\m_overlay_region\zerocount}
\def\pack_framed_add_background
{\ifconditional\c_pack_reanchor
diff --git a/tex/context/base/mkxl/page-box.mklx b/tex/context/base/mkxl/page-box.mklx
index c8ceeb828..c962b831a 100644
--- a/tex/context/base/mkxl/page-box.mklx
+++ b/tex/context/base/mkxl/page-box.mklx
@@ -59,15 +59,6 @@
\v_page_target_bottom_fill
\v_page_target_bottom}}
-\def\page_boxes_apply_offset % #box
- {\unless\ifzeropt\topoffset
- \expandafter\page_boxes_apply_offset_indeed
- \orelse\ifzeropt\backoffset
- \expandafter\gobbleoneargument
- \else
- \expandafter\page_boxes_apply_offset_indeed
- \fi}
-
\def\page_boxes_apply_offset_indeed#box%
{\scratchwidth \wd#box%
\scratchheight\ht#box%
@@ -75,12 +66,28 @@
\setbox#box\vpack
{\offinterlineskip
\vskip\topoffset
- \hskip\doifbothsides\backoffset\backoffset{-\backoffset}%
+ %\hskip\doifbothsides\backoffset\backoffset{-\backoffset}%
+ \hskip\doifbothsides++-\backoffset
\box#box}%
\wd#box\scratchwidth
\ht#box\scratchheight
\dp#box\scratchdepth}
+% a variant (no gain so we stay mkiv compatible):
+%
+% \def\page_boxes_apply_offset_indeed#box% this needs testing in real situations
+% {\boxxoffset#box\dimexpr\boxxoffset#box\doifbothsides++-\backoffset\relax
+% \boxyoffset#box\dimexpr\boxyoffset#box-\topoffset\relax}
+
+\def\page_boxes_apply_offset % #box
+ {\unless\ifzeropt\topoffset
+ \expandafter\page_boxes_apply_offset_indeed
+ \orunless\ifzeropt\backoffset
+ \expandafter\page_boxes_apply_offset_indeed
+ \else
+ \expandafter\gobbleoneargument
+ \fi}
+
\def\page_boxes_apply_replicate
{\ifnum\layoutparameter\c!nx>\plusone
\expandafter\page_boxes_apply_replicate_indeed
@@ -251,6 +258,15 @@
\box#1}%
\dp#1\zeropoint}
+% a variant (no gain so we stay mkiv compatible):
+%
+% \def\page_boxes_apply_offsets#1%
+% {\scratchhoffset\doifbothsides\backspace\backspace{\dimexpr\paperwidth-\backspace-\makeupwidth\relax}%
+% \boxxoffset#1\dimexpr\boxxoffset#1+\scratchhoffset\relax
+% \boxyoffset#1\dimexpr\boxyoffset#1-\topspace\relax
+% \wd#1\dimexpr\paperwidth+\scratchhoffset\relax
+% \ht#1\dimexpr\paperheight+\topspace\relax}
+
%D This is rather specialized:
\newconditional\c_page_areas_enabled
diff --git a/tex/context/base/mkxl/page-lay.mkxl b/tex/context/base/mkxl/page-lay.mkxl
index a4f4666e2..835a3ca4b 100644
--- a/tex/context/base/mkxl/page-lay.mkxl
+++ b/tex/context/base/mkxl/page-lay.mkxl
@@ -469,35 +469,58 @@
\global\c_page_target_print_orientation\uprotationangle
\global\c_page_target_print_reverse \uprotationangle}
-\letvalue{\??layoutpaper\v!reset}\page_paper_reset_paper
-\letvalue{\??layoutprint\v!reset}\page_paper_reset_print
-
-\setvalue{\??layoutpaper\v!landscape }{\global\settrue\c_page_target_paper_landscape}
-\setvalue{\??layoutpaper\v!mirrored }{\global\settrue\c_page_target_paper_mirror}
-\setvalue{\??layoutpaper\v!negative }{\global\settrue\c_page_target_paper_negate}
-\setvalue{\??layoutpaper\v!rotated }{\global\c_page_target_paper_orientation\rightrotationangle
- \global\c_page_target_paper_reverse \leftrotationangle}
-\setvalue{\??layoutpaper\number\rightrotationangle}{\global\c_page_target_paper_orientation\rightrotationangle
- \global\c_page_target_paper_reverse \leftrotationangle}
-\setvalue{\??layoutpaper\number\downrotationangle }{\global\c_page_target_paper_orientation\downrotationangle
- \global\c_page_target_paper_reverse \zerocount}
-\setvalue{\??layoutpaper\number\leftrotationangle }{\global\c_page_target_paper_orientation\leftrotationangle
- \global\c_page_target_paper_reverse \rightrotationangle}
-
-\setvalue{\??layoutprint\v!landscape }{\global\settrue\c_page_target_print_landscape}
-\setvalue{\??layoutprint\v!mirrored }{\global\settrue\c_page_target_print_mirror}
-\setvalue{\??layoutprint\v!negative }{\global\settrue\c_page_target_print_negate}
-\setvalue{\??layoutprint\v!rotated }{\global\c_page_target_print_orientation\rightrotationangle
- \global\c_page_target_print_reverse \leftrotationangle}
-\setvalue{\??layoutprint\number\rightrotationangle}{\global\c_page_target_print_orientation\rightrotationangle
- \global\c_page_target_print_reverse \leftrotationangle}
-\setvalue{\??layoutprint\number\downrotationangle }{\global\c_page_target_print_orientation\downrotationangle
- \global\c_page_target_print_reverse \zerocount}
-\setvalue{\??layoutprint\number\leftrotationangle }{\global\c_page_target_print_orientation\leftrotationangle
- \global\c_page_target_print_reverse \rightrotationangle}
-
-%def\page_paper_handle_page_option #1{\ifcsname\??layoutpaper#1\endcsname\csname\??layoutpaper#1\endcsname\fi}
-%def\page_paper_handle_print_option#1{\ifcsname\??layoutprint#1\endcsname\csname\??layoutprint#1\endcsname\fi}
+\letcsname\??layoutpaper\v!reset\endcsname\page_paper_reset_paper
+\letcsname\??layoutprint\v!reset\endcsname\page_paper_reset_print
+
+\defcsname\??layoutpaper\v!landscape\endcsname
+ {\global\settrue\c_page_target_paper_landscape}
+
+\defcsname\??layoutpaper\v!mirrored\endcsname
+ {\global\settrue\c_page_target_paper_mirror}
+
+\defcsname\??layoutpaper\v!negative\endcsname
+ {\global\settrue\c_page_target_paper_negate}
+
+\defcsname\??layoutpaper\v!rotated\endcsname
+ {\global\c_page_target_paper_orientation\rightrotationangle
+ \global\c_page_target_paper_reverse \leftrotationangle}
+
+\defcsname\??layoutpaper\number\rightrotationangle\endcsname
+ {\global\c_page_target_paper_orientation\rightrotationangle
+ \global\c_page_target_paper_reverse \leftrotationangle}
+
+\defcsname\??layoutpaper\number\downrotationangle\endcsname
+ {\global\c_page_target_paper_orientation\downrotationangle
+ \global\c_page_target_paper_reverse \zerocount}
+
+\defcsname\??layoutpaper\number\leftrotationangle\endcsname
+ {\global\c_page_target_paper_orientation\leftrotationangle
+ \global\c_page_target_paper_reverse \rightrotationangle}
+
+\defcsname\??layoutprint\v!landscape\endcsname
+ {\global\settrue\c_page_target_print_landscape}
+
+\defcsname\??layoutprint\v!mirrored\endcsname
+ {\global\settrue\c_page_target_print_mirror}
+
+\defcsname\??layoutprint\v!negative\endcsname
+ {\global\settrue\c_page_target_print_negate}
+
+\defcsname\??layoutprint\v!rotated\endcsname
+ {\global\c_page_target_print_orientation\rightrotationangle
+ \global\c_page_target_print_reverse \leftrotationangle}
+
+\defcsname\??layoutprint\number\rightrotationangle\endcsname
+ {\global\c_page_target_print_orientation\rightrotationangle
+ \global\c_page_target_print_reverse \leftrotationangle}
+
+\defcsname\??layoutprint\number\downrotationangle \endcsname
+ {\global\c_page_target_print_orientation\downrotationangle
+ \global\c_page_target_print_reverse \zerocount}
+
+\defcsname\??layoutprint\number\leftrotationangle \endcsname
+ {\global\c_page_target_print_orientation\leftrotationangle
+ \global\c_page_target_print_reverse \rightrotationangle}
\def\page_paper_handle_page_option #1{\begincsname\??layoutpaper#1\endcsname}
\def\page_paper_handle_print_option#1{\begincsname\??layoutprint#1\endcsname}
@@ -847,13 +870,6 @@
\installlayoutmethod\v!default{\page_layouts_check_default}
\installlayoutmethod\v!normal {\page_layouts_check_default}
-% \def\page_layouts_check_next
-% {\csname\??layoutmethod\ifcsname\??layoutmethod\layoutparameter\c!method\endcsname
-% \layoutparameter\c!method
-% \else
-% \v!normal
-% \fi\endcsname}
-
\permanent\protected\def\page_layouts_check_next
{\ifcsname\??layoutmethod\layoutparameter\c!method\endcsname
\lastnamedcs
@@ -907,41 +923,55 @@
{\setfalse\c_page_layouts_location_is_set
\setfalse\c_page_layouts_location_is_middle
\let\v_page_target_left_fill \relax
- \let\v_page_target_right_fill \hss % ? \relax
+ \let\v_page_target_right_fill \hss % ? \relax
\let\v_page_target_top_fill \relax
\let\v_page_target_bottom_fill\vss} % \relax}
-\setvalue{\??layoutlocation\v!right }{\settrue\c_page_layouts_location_is_set
- \setfalse\c_page_layouts_location_is_middle
- \let\v_page_target_left_fill \hss
- \let\v_page_target_right_fill \relax}
-\setvalue{\??layoutlocation\v!left }{\settrue\c_page_layouts_location_is_set
- \setfalse\c_page_layouts_location_is_middle
- \let\v_page_target_left_fill \relax
- \let\v_page_target_right_fill \hss}
-\setvalue{\??layoutlocation\v!bottom }{\settrue\c_page_layouts_location_is_set
- \setfalse\c_page_layouts_location_is_middle
- \let\v_page_target_top_fill \vss
- \let\v_page_target_bottom_fill\relax}
-\setvalue{\??layoutlocation\v!top }{\settrue\c_page_layouts_location_is_set
- \setfalse\c_page_layouts_location_is_middle
- \let\v_page_target_top_fill \relax
- \let\v_page_target_bottom_fill\vss}
-\setvalue{\??layoutlocation\v!middle }{\settrue\c_page_layouts_location_is_set
- \settrue\c_page_layouts_location_is_middle
- \let\v_page_target_left_fill \hss
- \let\v_page_target_right_fill \hss
- \let\v_page_target_top_fill \vss
- \let\v_page_target_bottom_fill\vss}
-\setvalue{\??layoutlocation\empty }{\setfalse\c_page_layouts_location_is_set % default also signal to scrn_
- \setfalse\c_page_layouts_location_is_middle
- \let\v_page_target_right_fill \hss
- \let\v_page_target_bottom_fill\hss}
-\setvalue{\??layoutlocation\v!doublesided}{\settrue \c_page_target_print_doublesided}
-\setvalue{\??layoutlocation\v!singlesided}{\setfalse\c_page_target_print_doublesided}
+\defcsname\??layoutlocation\v!right\endcsname
+ {\settrue\c_page_layouts_location_is_set
+ \setfalse\c_page_layouts_location_is_middle
+ \let\v_page_target_left_fill \hss
+ \let\v_page_target_right_fill\relax}
+
+\defcsname\??layoutlocation\v!left\endcsname
+ {\settrue\c_page_layouts_location_is_set
+ \setfalse\c_page_layouts_location_is_middle
+ \let\v_page_target_left_fill \relax
+ \let\v_page_target_right_fill\hss}
+
+\defcsname\??layoutlocation\v!bottom\endcsname
+ {\settrue\c_page_layouts_location_is_set
+ \setfalse\c_page_layouts_location_is_middle
+ \let\v_page_target_top_fill \vss
+ \let\v_page_target_bottom_fill\relax}
+
+\defcsname\??layoutlocation\v!top\endcsname
+ {\settrue\c_page_layouts_location_is_set
+ \setfalse\c_page_layouts_location_is_middle
+ \let\v_page_target_top_fill \relax
+ \let\v_page_target_bottom_fill\vss}
+
+\defcsname\??layoutlocation\v!middle\endcsname
+ {\settrue\c_page_layouts_location_is_set
+ \settrue\c_page_layouts_location_is_middle
+ \let\v_page_target_left_fill \hss
+ \let\v_page_target_right_fill \hss
+ \let\v_page_target_top_fill \vss
+ \let\v_page_target_bottom_fill\vss}
+
+\defcsname\??layoutlocation\empty\endcsname
+ {\setfalse\c_page_layouts_location_is_set % default also signal to scrn_
+ \setfalse\c_page_layouts_location_is_middle
+ \let\v_page_target_right_fill \hss
+ \let\v_page_target_bottom_fill\hss}
+
+\defcsname\??layoutlocation\v!doublesided\endcsname
+ {\settrue\c_page_target_print_doublesided}
+
+\defcsname\??layoutlocation\v!singlesided\endcsname
+ {\setfalse\c_page_target_print_doublesided}
\def\page_target_check_centering_indeed#1%
- % {\ifcsname\??layoutlocation#1\endcsname\csname\??layoutlocation#1\endcsname\fi}
{\begincsname\??layoutlocation#1\endcsname}
\protected\def\page_target_check_centering
@@ -967,13 +997,6 @@
\installlayoutalternative\v!default{\page_boxes_construct_content_default}
\installlayoutalternative\v!normal {\page_boxes_construct_content_default}
-% \def\page_boxes_construct_content % targetbox flusher box
-% {\csname\??layoutalternative\ifcsname\??layoutalternative\layoutparameter\c!alternative\endcsname
-% \layoutparameter\c!alternative
-% \else
-% \v!normal
-% \fi\endcsname}
-
\def\page_boxes_construct_content % targetbox flusher box
{\ifcsname\??layoutalternative\layoutparameter\c!alternative\endcsname
\expandafter\lastnamedcs
@@ -1031,9 +1054,9 @@
\global\d_page_adapts_height\footerheight
\fi
\fi
-%
+ %
\global\d_page_adapts_delta-\dimexpr\adaptlayoutparameter\c!top\relax
-%
+ %
\global\advance\textheight \d_page_adapts_height
\global\advance\footerheight-\d_page_adapts_height
\showmessage\m!layouts1{\the\dimexpr\d_page_adapts_height,\the\realpageno}%
@@ -1044,14 +1067,6 @@
\glet\page_adapts_push\relax
\glet\page_adapts_pop\page_adapts_pop_indeed}
-% \def\page_adapts_check
-% {\csname\??pageadaptations\the\ifcsname\??pageadaptations\the\realpageno\endcsname\realpageno\else\zerocount\fi\endcsname}
-%
-% \def\page_adapts_reset
-% {\ifcsname\??pageadaptations\the\realpageno\endcsname
-% \global\undefinevalue{\??pageadaptations\the\realpageno}%
-% \fi}
-
\def\page_adapts_check
{\begincsname\??pageadaptations\the\realpageno\endcsname}
diff --git a/tex/context/base/mkxl/page-otr.mklx b/tex/context/base/mkxl/page-otr.mklx
index b24fa62e3..adca25eb5 100644
--- a/tex/context/base/mkxl/page-otr.mklx
+++ b/tex/context/base/mkxl/page-otr.mklx
@@ -86,10 +86,9 @@
\let\page_otr_specifics_preset\page_otr_specifics_preset_traced
\to \t_page_otr_tracers
-%D We have a couple of output routines and the default one is
-%D the single column routine. Then there is a multicolumn variant
-%D that can be used mixed, and a columnset variant that is more
-%D exclusive.
+%D We have a couple of output routines and the default one is the single column
+%D routine. Then there is a multicolumn variant that can be used mixed, and a
+%D columnset variant that is more exclusive.
\installcorenamespace{otrtriggers}
@@ -176,26 +175,6 @@
#content\relax
\the\everyafteroutput}}
-% Just as fuzzy (and in 'one' we are okay with \aftergroup anyway):
-%
-% \ifdefined\everybeforeoutputgroup \else \newtoks\everybeforeoutputgroup \fi
-% \ifdefined\everyafteroutputgroup \else \newtoks\everyafteroutputgroup \fi
-%
-% \def\page_otr_set_engine_output_routine#content%
-% {\the\everybeforeoutputgroup
-% \global\output
-% {\inotrtrue
-% \the\everybeforeoutput
-% #content\relax
-% \the\everyafteroutput
-% \aftergroup\the\aftergroup\everyafteroutputgroup}}
-%
-% \appendtoks
-% \ifnum\c_page_postponed_mode=\plusone
-% \page_postponed_blocks_flush % and then not in \page_otr_construct_and_shipout
-% \fi
-% \to \everyafteroutputgroup
-
\page_otr_set_engine_output_routine\page_otr_triggered_output_routine
\installoutputroutine\synchronizeoutput % use \triggerpagebuilder instead
@@ -261,16 +240,14 @@
\penalty\c_page_otr_super_penalty
\resetpagebreak}
-%D For those who've read the plain \TEX\ book, we provide the next
-%D macro:
+%D For those who've read the plain \TEX\ book, we provide the next macro:
\permanent\protected\def\bye
{\writestatus\m!system{Sorry, you're not done yet, so no goodbye!}}
-%D We define a few constants because that (1) provides some checking
-%D and (2) is handier when aligning definitions (checks nicer). Most
-%D routines will use ard codes names but sometimes we want to adapt,
-%D which is why we have these:
+%D We define a few constants because that (1) provides some checking and (2) is
+%D handier when aligning definitions (checks nicer). Most routines will use ard
+%D codes names but sometimes we want to adapt, which is why we have these:
\definesystemconstant{page_otr_command_routine}
\definesystemconstant{page_otr_command_package_contents}
diff --git a/tex/context/base/mkxl/scrn-wid.mklx b/tex/context/base/mkxl/scrn-wid.mklx
index 724bdb807..b35047d94 100644
--- a/tex/context/base/mkxl/scrn-wid.mklx
+++ b/tex/context/base/mkxl/scrn-wid.mklx
@@ -652,6 +652,12 @@
\let\m_scrn_rendering_page\!!zerocount
+%D \starttyping
+%D \definerenderingwindow[soundplace][width=0pt, height=0pt]
+%D \useexternalrendering[mainsound][audio/mp3][sound.mp3][embed=yes]
+%D \placerenderingwindow[soundplace][mainsound]
+%D \stoptyping
+
\installcorenamespace{renderingwindow}
\installframedcommandhandler \??renderingwindow {renderingwindow} \??renderingwindow
diff --git a/tex/context/base/mkxl/spac-hor.mkxl b/tex/context/base/mkxl/spac-hor.mkxl
index 0a378d500..95be0a352 100644
--- a/tex/context/base/mkxl/spac-hor.mkxl
+++ b/tex/context/base/mkxl/spac-hor.mkxl
@@ -810,8 +810,8 @@
\permanent\protected\def\dosetleftskipadaption #1{\leftskipadaption \ifcsname\??skipadaptionleft #1\endcsname\lastnamedcs\else#1\fi\relax}
\permanent\protected\def\dosetrightskipadaption#1{\rightskipadaption\ifcsname\??skipadaptionright#1\endcsname\lastnamedcs\else#1\fi\relax}
-\permanent\protected\def\doadaptleftskip #1{\normalexpanded{\dosetleftskipadaption {#1}}\permanent\advance\leftskip \leftskipadaption }
-\permanent\protected\def\doadaptrightskip#1{\normalexpanded{\dosetrightskipadaption{#1}}\permanent\advance\rightskip\rightskipadaption}
+\permanent\protected\def\doadaptleftskip #1{\normalexpanded{\dosetleftskipadaption {#1}}\frozen\advance\leftskip \leftskipadaption }
+\permanent\protected\def\doadaptrightskip#1{\normalexpanded{\dosetrightskipadaption{#1}}\frozen\advance\rightskip\rightskipadaption}
\permanent\protected\def\forgetbothskips
{\leftskip\zeropoint
diff --git a/tex/context/base/mkxl/spac-ver.lmt b/tex/context/base/mkxl/spac-ver.lmt
index 1af5096fb..cae0f1d78 100644
--- a/tex/context/base/mkxl/spac-ver.lmt
+++ b/tex/context/base/mkxl/spac-ver.lmt
@@ -687,19 +687,19 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut]
return h, d, ch, cd, lines, extra
end
-local categories = {
- [0] = "discard",
- [1] = "largest",
- [2] = "force",
- [3] = "penalty",
- [4] = "add",
- [5] = "disable",
- [6] = "nowhite",
- [7] = "goback",
- [8] = "packed",
- [9] = "overlay",
- [10] = "enable",
- [11] = "notopskip",
+local categories = { [0] =
+ "discard",
+ "largest",
+ "force",
+ "penalty",
+ "add",
+ "disable",
+ "nowhite",
+ "goback",
+ "packed",
+ "overlay",
+ "enable",
+ "notopskip",
}
categories = allocate(table.swapped(categories,categories))
diff --git a/tex/context/base/mkxl/strc-des.mklx b/tex/context/base/mkxl/strc-des.mklx
index 835c6807e..9f9119466 100644
--- a/tex/context/base/mkxl/strc-des.mklx
+++ b/tex/context/base/mkxl/strc-des.mklx
@@ -58,6 +58,7 @@
%\s!catcodes=,
\c!title=\v!yes,
%\c!text=,
+ \c!define=\v!yes,
]
\appendtoks
@@ -67,9 +68,11 @@
\defineconstruction[\currentdescription][\s!handler=\v!description,\c!level=1]%
\fi
% We can combine these but in tracing (or errors) using a different caller is nicer.
- \frozen\protected\instance\edefcsname \currentdescription\endcsname{\nameddescription[\currentdescription]}%
- \frozen\protected\instance\edefcsname\e!start\currentdescription\endcsname{\startnameddescription[\currentdescription]}%
- \frozen\protected\instance \defcsname \e!stop\currentdescription\endcsname{\stopnameddescription}%
+ \ifcstok{\descriptionparameter\c!define}\v!yes
+ \frozen\protected\instance\edefcsname \currentdescription\endcsname{\nameddescription[\currentdescription]}%
+ \frozen\protected\instance\edefcsname\e!start\currentdescription\endcsname{\startnameddescription[\currentdescription]}%
+ \frozen\protected\instance \defcsname \e!stop\currentdescription\endcsname{\stopnameddescription}%
+ \fi
\to \everydefinedescription
\let\p_strc_constructions_title \empty
diff --git a/tex/context/base/mkxl/strc-enu.mklx b/tex/context/base/mkxl/strc-enu.mklx
index a6ba99ce7..fd98b11f3 100644
--- a/tex/context/base/mkxl/strc-enu.mklx
+++ b/tex/context/base/mkxl/strc-enu.mklx
@@ -120,7 +120,8 @@
\c!number=\v!yes, % else description
\c!start=0,
\c!state=\v!start,
- \c!levels=4]
+ \c!levels=4,
+ \c!define=\v!yes]
% to be considered:
%
@@ -129,17 +130,21 @@
% with push/pop (also at definition time)
\protected\def\strc_define_commands_enumeration#tag#level#parent%
- {\doifelsenothing{#parent}
- {\normalexpanded{\defineconstruction[#tag][\s!handler=\v!enumeration,\c!level=#level]}%
- \edefcsname\??enumeration#tag:\s!parent\endcsname{\??enumeration}}%
- {\normalexpanded{\defineconstruction[#tag][#parent][\s!handler=\v!enumeration,\c!level=#level]}%
- \edefcsname\??enumeration#tag:\s!parent\endcsname{\??enumeration#parent}}%
- \frozen\protected\instance\edefcsname\e!next #tag\endcsname{\strc_enumerations_next{#tag}{\number#level}}% obsolete
- \frozen\protected\instance\edefcsname\c!reset#tag\endcsname{\strc_enumerations_reset{#tag}{\number#level}}% obsolete
- %frozen\protected\instance\edefcsname\c!set #tag\endcsname{\strc_enumerations_set{#tag}{\number#level}}% obsolete
- \frozen\protected\instance\edefcsname #tag\endcsname{\namedenumeration[#tag]}%
- \frozen\protected\instance\edefcsname\e!start#tag\endcsname{\startnamedenumeration[#tag]}%
- \frozen\protected\instance \defcsname\e!stop #tag\endcsname{\stopnamedenumeration}}
+ {\iftok{#parent}\emptytoks
+ \normalexpanded{\defineconstruction[#tag][\s!handler=\v!enumeration,\c!level=#level]}%
+ \edefcsname\??enumeration#tag:\s!parent\endcsname{\??enumeration}%
+ \else
+ \normalexpanded{\defineconstruction[#tag][#parent][\s!handler=\v!enumeration,\c!level=#level]}%
+ \edefcsname\??enumeration#tag:\s!parent\endcsname{\??enumeration#parent}%
+ \fi
+ \ifcstok{\enumerationparameter\c!define}\v!yes
+ \frozen\protected\instance\edefcsname\e!next #tag\endcsname{\strc_enumerations_next{#tag}{\number#level}}% obsolete
+ \frozen\protected\instance\edefcsname\c!reset#tag\endcsname{\strc_enumerations_reset{#tag}{\number#level}}% obsolete
+ %frozen\protected\instance\edefcsname\c!set #tag\endcsname{\strc_enumerations_set{#tag}{\number#level}}% obsolete
+ \frozen\protected\instance\edefcsname #tag\endcsname{\namedenumeration[#tag]}%
+ \frozen\protected\instance\edefcsname\e!start#tag\endcsname{\startnamedenumeration[#tag]}%
+ \frozen\protected\instance \defcsname\e!stop #tag\endcsname{\stopnamedenumeration}%
+ \fi}
\let\m_strc_enumeration_sub\empty
diff --git a/tex/context/base/mkxl/strc-ref.mklx b/tex/context/base/mkxl/strc-ref.mklx
index ad62a52e5..1f0491cf1 100644
--- a/tex/context/base/mkxl/strc-ref.mklx
+++ b/tex/context/base/mkxl/strc-ref.mklx
@@ -1234,20 +1234,20 @@
\doifelsesometoks\rightreferencetoks\rightofreferencecontent\donothing
\the\rightreferencetoks}
-\letvalue{\??referencinginteraction\v!all}\strc_references_interaction_all
+\letcsname\??referencinginteraction\v!all\endcsname\strc_references_interaction_all
-\setvalue{\??referencinginteraction\v!label}%
+\defcsname\??referencinginteraction\v!label\endcsname
{\leftofreference
\the\leftreferencetoks
\the\rightreferencetoks
\rightofreference}
-\setvalue{\??referencinginteraction\v!text}%
+\defcsname\??referencinginteraction\v!text\endcsname
{\leftofreference
\currentreferencecontent
\rightofreference}
-\setvalue{\??referencinginteraction\v!symbol}%
+\defcsname\??referencinginteraction\v!symbol\endcsname
{\referencesymbol}
\permanent\def\referencesequence
diff --git a/tex/context/base/mkxl/strc-reg.lmt b/tex/context/base/mkxl/strc-reg.lmt
index 6e26f6f37..ccb43bc28 100644
--- a/tex/context/base/mkxl/strc-reg.lmt
+++ b/tex/context/base/mkxl/strc-reg.lmt
@@ -497,7 +497,22 @@ local function preprocessentries(rawdata)
if not ok and etk == "" then
entries[k] = nil
else
- entries[k] = { etk or "", ktk ~= "" and ktk or false, ptk ~= "" and ptk or false }
+ if not etk then
+ etk = ""
+ end
+ -- we save some space by pruning
+ if ptk == "" then
+ ptk = nil
+ end
+ -- we save even more space by pruning
+ if ktk == "" then
+ if ptk then
+ ktk = false
+ else
+ ktk = nil
+ end
+ end
+ entries[k] = { etk, ktk, ptk }
ok = true
end
end
@@ -563,6 +578,7 @@ local function storeregister(rawdata) -- metadata, references, entries
--
local data = notsaved and collected[name] or tobesaved[name]
local entries = data.entries
+ --
internalreferences[internal] = rawdata
preprocessentries(rawdata)
entries[#entries+1] = rawdata
diff --git a/tex/context/base/mkxl/supp-box.mkxl b/tex/context/base/mkxl/supp-box.mkxl
index 796c3663a..87660df49 100644
--- a/tex/context/base/mkxl/supp-box.mkxl
+++ b/tex/context/base/mkxl/supp-box.mkxl
@@ -2437,6 +2437,7 @@
%D \getboxfromcache{foo}{\recurselevel}\zerocount
%D \fi
%D }
+%D % \startMPcode draw rawtexbox("category","name") ; \stopMPcode
%D \resetboxesincache{foo}
%D \stoptyping
diff --git a/tex/context/base/mkxl/syst-aux.lmt b/tex/context/base/mkxl/syst-aux.lmt
index 726fd4d32..eeb1c5aac 100644
--- a/tex/context/base/mkxl/syst-aux.lmt
+++ b/tex/context/base/mkxl/syst-aux.lmt
@@ -648,14 +648,14 @@ implement {
-- name = "hascommonargumentcondition",
-- actions = hascommonargumentcondition,
-- arguments = "2 strings",
--- arguments = { "argument", "argument" },
+-- arguments = "2 arguments",
-- }
implement {
name = "doifelseinset",
actions = doifelseinset,
arguments = "2 strings",
--- arguments = { "argument", "argument" },
+-- arguments = "2 arguments",
}
implement {
diff --git a/tex/context/base/mkxl/syst-ini.mkxl b/tex/context/base/mkxl/syst-ini.mkxl
index 1f58b42a1..f9b40c963 100644
--- a/tex/context/base/mkxl/syst-ini.mkxl
+++ b/tex/context/base/mkxl/syst-ini.mkxl
@@ -1389,10 +1389,12 @@
\permanent\protected\def\newlocaltoks #1{\setnewlocaltoks #1\emptytoks }
\permanent\protected\def\newlocalbox #1{\setnewlocalbox #1\emptybox }
-%D Let's be detailed: grouplevel:inputlevel:
+%D Let's be detailed: grouplevel:inputlevel:catcodetable (bits 1 2 4)
\tracinglevels\plusthree
+\permanent\protected\def\tracingcatcodes{\tracinglevels\plusseven}
+
%D We just report duplicate patterns being ignored:
\tracinghyphenation\plusone
diff --git a/tex/context/base/mkxl/tabl-ntb.mkxl b/tex/context/base/mkxl/tabl-ntb.mkxl
index 418164daa..67fc39a89 100644
--- a/tex/context/base/mkxl/tabl-ntb.mkxl
+++ b/tex/context/base/mkxl/tabl-ntb.mkxl
@@ -1437,14 +1437,14 @@
{\global\advance\c_tabl_ntb_col\plusone
\kern\d_tabl_ntb_columndistance}
-\setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2%
+\defcsname\??naturaltablecell\the\c_tabl_ntb_none\endcsname#1#2%
{\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
\ifnum\scratchcounter>\zerocount
\etoksapp\t_tabl_ntb_row
{\tabl_ntb_span{\the\scratchcounter}}%
\fi}
-\setvalue{\??naturaltablecell\the\c_tabl_ntb_cell}#1#2%
+\defcsname\??naturaltablecell\the\c_tabl_ntb_cell\endcsname#1#2%
{\toksapp\t_tabl_ntb_row{\tabl_ntb_pass #1 #2 }% space delimited -> less tokens
\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax
\ifnum\scratchcounter>\zerocount
diff --git a/tex/context/base/mkxl/tabl-tab.mkxl b/tex/context/base/mkxl/tabl-tab.mkxl
index e63492984..95d263ecd 100644
--- a/tex/context/base/mkxl/tabl-tab.mkxl
+++ b/tex/context/base/mkxl/tabl-tab.mkxl
@@ -1429,7 +1429,7 @@
\tolerant\def\tabl_table_define_template[#1]#*[#2]#*[#3]#*[#4]%
{\ifarguments\or\else
- \setgvalue{\??tabletemplate#1}{\tabl_table_use_template{#2}{#3}{#4}}%
+ \gdefcsname\??tabletemplate#1\endcsname{\tabl_table_use_template{#2}{#3}{#4}}%
\fi
\egroup}
@@ -1657,9 +1657,6 @@
\newconditional\hassometablehead
\newconditional\hassometabletail
-% \def\tabl_table_set_head[#1][#2]#3\end{\setvalue{\??tablehead#1}{\noalign{\global\settrue\hassometablehead}#3}}
-% \def\tabl_table_set_tail[#1][#2]#3\end{\setvalue{\??tabletail#1}{\noalign{\global\settrue\hassometabletail}#3}}
-
\permanent\protected\def\settablehead{\dodoubleempty\tabl_table_set_head} % todo: use pickup
\permanent\protected\def\settabletail{\dodoubleempty\tabl_table_set_tail} % todo: use pickup
diff --git a/tex/context/base/mkxl/tabl-tbl.mkxl b/tex/context/base/mkxl/tabl-tbl.mkxl
index e22fb946c..c48c384f2 100644
--- a/tex/context/base/mkxl/tabl-tbl.mkxl
+++ b/tex/context/base/mkxl/tabl-tbl.mkxl
@@ -700,9 +700,9 @@
%
% \installcorenamespace{tabulatewidth}
%
-% \setvalue{\??tabulatewidth\v!fit }{\c_tabl_tabulate_modus\plusthree}
-% \setvalue{\??tabulatewidth\v!fixed}{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_nopbreak}
-% \setvalue{\??tabulatewidth\v!auto }{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_reshape}
+% \defcsname\??tabulatewidth\v!fit \endcsname{\c_tabl_tabulate_modus\plusthree}
+% \defcsname\??tabulatewidth\v!fixed\endcsname{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_nopbreak}
+% \defcsname\??tabulatewidth\v!auto \endcsname{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_reshape}
%
% \def\tabl_tabulate_set_width_step#1%
% {\ifcsname\??tabulatewidth#1\endcsname
diff --git a/tex/context/base/mkxl/tabl-xtb.mklx b/tex/context/base/mkxl/tabl-xtb.mklx
index ba144c322..5aad01884 100644
--- a/tex/context/base/mkxl/tabl-xtb.mklx
+++ b/tex/context/base/mkxl/tabl-xtb.mklx
@@ -209,8 +209,8 @@
%D We can also define xtables.
\appendtoks
- \permanent\setuevalue{\e!start\currentxtable}{\tabl_x_start_named[\currentxtable]}%
- \permanent\setuevalue{\e!stop \currentxtable}{\tabl_x_stop_named}%
+ \permanent\protected\edefcsname\e!start\currentxtable\endcsname{\tabl_x_start_named[\currentxtable]}%
+ \permanent\protected\edefcsname\e!stop \currentxtable\endcsname{\tabl_x_stop_named}%
\to \everydefinextable
\protected\def\tabl_x_start_named[#tag]#spacer[#settings]%
diff --git a/tex/context/base/mkxl/util-pck.lmt b/tex/context/base/mkxl/util-pck.lmt
new file mode 100644
index 000000000..fff2d280a
--- /dev/null
+++ b/tex/context/base/mkxl/util-pck.lmt
@@ -0,0 +1,176 @@
+if not modules then modules = { } end modules ['util-pck'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- moved from core-uti
+
+local next, tostring, type = next, tostring, type
+local sort, concat = table.sort, table.concat
+local format = string.format
+local sortedhashkeys, sortedkeys, tohash = table.sortedhashkeys, table.sortedkeys, table.tohash
+
+utilities = utilities or { }
+utilities.packers = utilities.packers or { }
+local packers = utilities.packers
+packers.version = 1.01
+
+-- local fmt_kv <const> = "%s=%q"
+-- local fmt_kt <const> = "%s={%q}"
+
+-- local function hashed(t)
+-- local s, ns = { }, 0
+-- for k, v in next, t do
+-- ns = ns + 1
+-- if type(v) == "table" then
+-- s[ns] = format(fmt_kt,k,hashed(v))
+-- else
+-- s[ns] = format(fmt_kv,k,v)
+-- end
+-- end
+-- sort(s)
+-- return concat(s,",")
+-- end
+
+local function hashed(t) --local function tabstr_normal(t)
+ local s = { }
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ if type(v) == "table" then
+ s[n] = k .. ">" .. hashed(v)
+ elseif v == true then
+ s[n] = k .. "+" -- "=true"
+ elseif v then
+ s[n] = k .. "=" .. v
+ else
+ s[n] = k .. "-" -- "=false"
+ end
+ end
+ if n == 0 then
+ return ""
+ elseif n == 1 then
+ return s[1]
+ else
+ sort(s) -- costly but needed (occasional wrong hit otherwise)
+ return concat(s,",")
+ end
+end
+
+local function simplehashed(t)
+ local s = { }
+ local n = 0
+ for k, v in next, t do
+ n = n + 1
+ -- s[n] = format(fmt_kv,k,v)
+ s[n] = k .. "=" .. v
+ end
+ sort(s)
+ return concat(s,",")
+end
+
+packers.hashed = hashed
+packers.simplehashed = simplehashed
+
+-- In luatex < 0.74 (lua 5.1) a next chain was the same for each run so no sort was needed,
+-- but in the latest greatest versions (lua 5.2) we really need to sort the keys in order
+-- not to get endless runs due to a difference in tuc files.
+
+local function pack(t,keys,skip,hash,index)
+ if t then
+ local sk = #t > 0 and sortedkeys(t) or sortedhashkeys(t)
+ for i=1,#sk do
+ local k = sk[i]
+ if not skip or not skip[k] then
+ local v = t[k]
+ if type(v) == "table" then
+ pack(v,keys,skip,hash,index)
+ if keys[k] then
+ local h = hashed(v)
+ local i = hash[h]
+ if not i then
+ i = #index + 1
+ index[i] = v
+ hash[h] = i
+ end
+ t[k] = i
+ end
+ end
+ end
+ end
+ end
+end
+
+local function unpack(t,keys,skip,index)
+ if t then
+ for k, v in next, t do
+ if keys[k] and type(v) == "number" then
+ local iv = index[v]
+ if iv then
+ v = iv
+ t[k] = v
+ end
+ end
+ if type(v) == "table" and (not skip or not skip[k]) then
+ unpack(v,keys,skip,index)
+ end
+ end
+ end
+end
+
+function packers.new(keys,version,skip)
+ return {
+ version = version or packers.version,
+ keys = tohash(keys),
+ skip = tohash(skip),
+ hash = { },
+ index = { },
+ }
+end
+
+function packers.pack(t,p,shared)
+ if shared then
+ pack(t,p.keys,p.skip,p.hash,p.index)
+ elseif not t.packer then
+ pack(t,p.keys,p.skip,p.hash,p.index)
+ if #p.index > 0 then
+ t.packer = {
+ version = p.version or packers.version,
+ keys = p.keys,
+ skip = p.skip,
+ index = p.index,
+ }
+ end
+ p.hash = { }
+ p.index = { }
+ end
+end
+
+function packers.unpack(t,p,shared)
+ if shared then
+ if p then
+ unpack(t,p.keys,p.skip,p.index)
+ end
+ else
+ local tp = t.packer
+ if tp then
+ if tp.version == (p and p.version or packers.version) then
+ unpack(t,tp.keys,tp.skip,tp.index)
+ else
+ return false
+ end
+ t.packer = nil
+ end
+ end
+ return true
+end
+
+function packers.strip(p)
+ p.hash = nil
+end
+
+-- We could have a packer.serialize where we first flush the shared table
+-- and then use inline a reference . This saves an unpack.
diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml
index e53fbb198..158a8b8ac 100644
--- a/tex/context/interface/mkii/keys-ro.xml
+++ b/tex/context/interface/mkii/keys-ro.xml
@@ -154,6 +154,7 @@
<cd:variable name='commands' value='comenzi'/>
<cd:variable name='comment' value='comentariu'/>
<cd:variable name='component' value='componenta'/>
+ <cd:variable name='compress' value='compress'/>
<cd:variable name='compressseparator' value='compressseparator'/>
<cd:variable name='compressstopper' value='compressstopper'/>
<cd:variable name='concept' value='concept'/>
diff --git a/tex/context/modules/mkiv/s-fonts-emoji.mkiv b/tex/context/modules/mkiv/s-fonts-emoji.mkiv
index 1f303d569..096b90263 100644
--- a/tex/context/modules/mkiv/s-fonts-emoji.mkiv
+++ b/tex/context/modules/mkiv/s-fonts-emoji.mkiv
@@ -293,39 +293,64 @@ end
\start
-\definedfont[seguiemj*seguiemj-cl]
+\definedfont[file:seguiemj.any*default,seguiemj-cl]
-\ShowEmojiSnippets
- [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+% \ShowEmojiSnippets
+% [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
-\ShowEmojiSnippetsOverlay
- [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+% \ShowEmojiSnippetsOverlay
+% [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
-\ShowEmojiGlyphs
- [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
+% \ShowEmojiGlyphs
+% [family man light skin tone woman dark skin tone girl medium skin tone boy medium skin tone]
-\page
+% \page
-\ShowEmoji[^man]
+% \ShowEmoji[^man]
-\page
+% \ShowEmoji[backhand index pointing down]
+% \ShowEmoji[backhand index pointing up]
-\definecolor[emoji-base][r=.4]
-\definecolor[emoji-gray][s=.5,t=.5,a=1]
+\startTEXpage
+[\char8205\char128104]=\char988828\par
+[\char8205\char128105]=\char988851\par
+[\char8205\char983484]=\char988834\par
+[\char8205\char983485]=\char988835\par
+[\char8205\char983486]=\char988836\par
+[\char8205\char983487]=\char988837\par
+[\char8205\char983488]=\char988838\par
+[\char8205\char983495]=\char988858\par
+[\char8205\char983496]=\char988859\par
+[\char8205\char983497]=\char988860\par
+[\char8205\char983498]=\char988861\par
+[\char8205\char983499]=\char988862\par
+\stopTEXpage
-\definefontcolorpalette
- [emoji-gray]
- [emoji-base,emoji-gray]
-\definefontfeature[seguiemj-cl][ccmp=yes,dist=yes,colr=emoji-gray]
-\definedfont[seguiemj*seguiemj-cl]
-\ShowEmoji
-\page
-\ShowEmojiPalettes[1]
+
+
+% \page
+
+% \definecolor[emoji-base][r=.4]
+% \definecolor[emoji-gray][s=.5,t=.5,a=1]
+
+% \definefontcolorpalette
+% [emoji-gray]
+% [emoji-base,emoji-gray]
+
+% \definefontfeature[seguiemj-cl][ccmp=yes,dist=yes,colr=emoji-gray]
+
+% \definedfont[seguiemj*seguiemj-cl]
+
+% \ShowEmoji
+
+% \page
+
+% \ShowEmojiPalettes[1]
\stop
diff --git a/tex/context/modules/mkiv/s-fonts-features.lua b/tex/context/modules/mkiv/s-fonts-features.lua
index 34268c171..eb64e4c8f 100644
--- a/tex/context/modules/mkiv/s-fonts-features.lua
+++ b/tex/context/modules/mkiv/s-fonts-features.lua
@@ -200,6 +200,8 @@ function moduledata.fonts.features.showfeatureset(specification)
end
end
+-- The next one looks a bit like the collector in font-oup.lua.
+
local function collectligatures(tfmdata)
local sequences = tfmdata.resources.sequences
@@ -207,18 +209,28 @@ local function collectligatures(tfmdata)
return
end
+ -- Mostly the same as s-fonts-tables so we should make a helper.
+
local series = { }
local stack = { }
local max = 0
+ local function add(v)
+ local n = #stack
+ if n > max then
+ max = n
+ end
+ series[#series+1] = { v, unpack(stack) }
+ end
+
local function make(tree)
for k, v in sortedhash(tree) do
if k == "ligature" then
- local n = #stack
- if n > max then
- max = n
- end
- series[#series+1] = { v, unpack(stack) }
+ add(v)
+ elseif tonumber(v) then
+ insert(stack,k)
+ add(v)
+ remove(stack)
else
insert(stack,k)
make(v)
diff --git a/tex/context/modules/mkiv/s-fonts-tables.lua b/tex/context/modules/mkiv/s-fonts-tables.lua
index c9aa7b801..65725594b 100644
--- a/tex/context/modules/mkiv/s-fonts-tables.lua
+++ b/tex/context/modules/mkiv/s-fonts-tables.lua
@@ -678,18 +678,28 @@ end
local function collectligatures(steps)
+ -- Mostly the same as s-fonts-features so we should make a helper.
+
local series = { }
local stack = { }
local max = 0
+ local function add(v)
+ local n = #stack
+ if n > max then
+ max = n
+ end
+ series[#series+1] = { v, unpack(stack) }
+ end
+
local function make(tree)
for k, v in sortedhash(tree) do
if k == "ligature" then
- local n = #stack
- if n > max then
- max = n
- end
- series[#series+1] = { v, unpack(stack) }
+ add(v)
+ elseif tonumber(v) then
+ insert(stack,k)
+ add(v)
+ remove(stack)
else
insert(stack,k)
make(v)
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index d874bda0f..e764e950c 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2021-08-10 12:37
+-- merge date : 2021-08-19 19:40
do -- begin closure to overcome local limits and interference
@@ -11298,15 +11298,15 @@ local weights={
[900]="black",
}
local widths={
- [1]="ultracondensed",
- [2]="extracondensed",
- [3]="condensed",
- [4]="semicondensed",
- [5]="normal",
- [6]="semiexpanded",
- [7]="expanded",
- [8]="extraexpanded",
- [9]="ultraexpanded",
+ "ultracondensed",
+ "extracondensed",
+ "condensed",
+ "semicondensed",
+ "normal",
+ "semiexpanded",
+ "expanded",
+ "extraexpanded",
+ "ultraexpanded",
}
setmetatableindex(weights,function(t,k)
local r=floor((k+50)/100)*100
@@ -11316,30 +11316,28 @@ end)
setmetatableindex(widths,function(t,k)
return "normal"
end)
-local panoseweights={
- [ 0]="normal",
- [ 1]="normal",
- [ 2]="verylight",
- [ 3]="light",
- [ 4]="thin",
- [ 5]="book",
- [ 6]="medium",
- [ 7]="demi",
- [ 8]="bold",
- [ 9]="heavy",
- [10]="black",
+local panoseweights={ [0]="normal",
+ "normal",
+ "verylight",
+ "light",
+ "thin",
+ "book",
+ "medium",
+ "demi",
+ "bold",
+ "heavy",
+ "black",
}
-local panosewidths={
- [ 0]="normal",
- [ 1]="normal",
- [ 2]="normal",
- [ 3]="normal",
- [ 4]="normal",
- [ 5]="expanded",
- [ 6]="condensed",
- [ 7]="veryexpanded",
- [ 8]="verycondensed",
- [ 9]="monospaced",
+local panosewidths={ [0]="normal",
+ "normal",
+ "normal",
+ "normal",
+ "normal",
+ "expanded",
+ "condensed",
+ "veryexpanded",
+ "verycondensed",
+ "monospaced",
}
local helpers={}
readers.helpers=helpers
@@ -12883,6 +12881,9 @@ end
function readers.compact(fontdata)
report("the %a helper is not yet implemented","compact")
end
+function readers.condense(fontdata)
+ report("the %a helper is not yet implemented","condense")
+end
local extenders={}
function readers.registerextender(extender)
extenders[#extenders+1]=extender
@@ -15333,6 +15334,12 @@ local function applyaxis(glyph,shape,deltas,dowidth)
else
local n1=dpoints[d1]
local n3=dpoints[d3]
+ if n1>nofpoints then
+ n1=nofpoints
+ end
+ if n3>nofpoints then
+ n3=nofpoints
+ end
local p1=points[n1]
local p3=points[n3]
local p1x=p1[1]
@@ -20926,7 +20933,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.118
+otf.version=3.119
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
@@ -21061,6 +21068,9 @@ function otf.load(filename,sub,instance)
if cleanup==0 then
checkmemory(used,threshold,tracememory)
end
+ if context then
+ otfreaders.condense(data)
+ end
otfreaders.pack(data)
report_otf("loading done")
report_otf("saving %a in cache",filename)
@@ -21746,49 +21756,60 @@ end
local function makefake(tfmdata,name,present)
local private=getprivate(tfmdata)
local character={ intermediate=true,ligatures={} }
- resources.unicodes[name]=private
+ tfmdata.resources.unicodes[name]=private
tfmdata.characters[private]=character
tfmdata.descriptions[private]={ name=name }
present[name]=private
return character
end
local function make_1(present,tree,name)
- for k,v in next,tree do
- if k=="ligature" then
- present[name]=v
+ if tonumber(tree) then
+ present[name]=v
+ else
+ for k,v in next,tree do
+ if k=="ligature" then
+ present[name]=v
+ else
+ make_1(present,v,name.."_"..k)
+ end
+ end
+ end
+end
+local function make_3(present,tfmdata,characters,tree,name,preceding,unicode,done,v)
+ local character=characters[preceding]
+ if not character then
+ if trace_baseinit then
+ report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
+ end
+ character=makefake(tfmdata,name,present)
+ end
+ local ligatures=character.ligatures
+ if ligatures then
+ ligatures[unicode]={ char=v }
+ else
+ character.ligatures={ [unicode]={ char=v } }
+ end
+ if done then
+ local d=done[name]
+ if not d then
+ done[name]={ "dummy",v }
else
- make_1(present,v,name.."_"..k)
+ d[#d+1]=v
end
end
end
local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done)
- for k,v in next,tree do
- if k=="ligature" then
- local character=characters[preceding]
- if not character then
- if trace_baseinit then
- report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding)
- end
- character=makefake(tfmdata,name,present)
- end
- local ligatures=character.ligatures
- if ligatures then
- ligatures[unicode]={ char=v }
+ if tonumber(tree) then
+ make_3(present,tfmdata,characters,tree,name,preceding,unicode,done,tree)
+ else
+ for k,v in next,tree do
+ if k=="ligature" then
+ make_3(present,tfmdata,characters,tree,name,preceding,unicode,done,v)
else
- character.ligatures={ [unicode]={ char=v } }
+ local code=present[name] or unicode
+ local name=name.."_"..k
+ make_2(present,tfmdata,characters,v,name,code,k,done)
end
- if done then
- local d=done[name]
- if not d then
- done[name]={ "dummy",v }
- else
- d[#d+1]=v
- end
- end
- else
- local code=present[name] or unicode
- local name=name.."_"..k
- make_2(present,tfmdata,characters,v,name,code,k,done)
end
end
end
@@ -24514,6 +24535,10 @@ function readers.getcomponents(fontdata)
local function traverse(p,k,v)
if k=="ligature" then
collected[v]={ unpack(l) }
+ elseif tonumber(v) then
+ insert(l,k)
+ collected[v]={ unpack(l) }
+ remove(l)
else
insert(l,k)
for k,vv in next,v do
@@ -24674,7 +24699,6 @@ local function tabstr_flat(t)
end
end
local function tabstr_mixed(t)
- local s={}
local n=#t
if n==0 then
return ""
@@ -24688,6 +24712,7 @@ local function tabstr_mixed(t)
return tostring(k)
end
else
+ local s={}
for i=1,n do
local k=t[i]
if k==true then
@@ -26011,6 +26036,85 @@ function readers.compact(data)
end
end
end
+if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then
+ local done=0
+ local function condense_1(k,v,t)
+ if type(v)=="table" then
+ local u=false
+ local l=false
+ for k,v in next,v do
+ if k=="ligature" then
+ l=v
+ if u then
+ break
+ end
+ elseif u then
+ break
+ else
+ u=true
+ end
+ end
+ if l and not u then
+ t[k]=l
+ done=done+1
+ end
+ if u then
+ for k,vv in next,v do
+ if k~="ligature" then
+ condense_1(k,vv,v)
+ end
+ end
+ end
+ end
+ end
+ local function condensesteps_1(lookup)
+ done=0
+ if lookup.type=="gsub_ligature" then
+ local steps=lookup.steps
+ if steps then
+ for i=1,#steps do
+ local step=steps[i]
+ local coverage=step.coverage
+ if coverage then
+ for k,v in next,coverage do
+ if condense_1(k,v,coverage) then
+ coverage[k]=v.ligature
+ done=done+1
+ end
+ end
+ end
+ end
+ end
+ end
+ return done
+ end
+ function readers.condense(data)
+ if not data or data.condensed then
+ return
+ else
+ data.condensed=true
+ end
+ local resources=data.resources
+ local condensed=0
+ local function condense(what)
+ local lookups=resources[what]
+ if lookups then
+ for i=1,#lookups do
+ condensed=condensed+condensesteps_1(lookups[i])
+ end
+ elseif trace_optimizations then
+ report_optimizations("no lookups in %a",what)
+ end
+ end
+ condense("sequences")
+ condense("sublookups")
+ if trace_optimizations then
+ if condensed>0 then
+ report_optimizations("%i ligatures condensed",condensed)
+ end
+ end
+ end
+end
local function mergesteps(t,k)
if k=="merged" then
local merged={}
@@ -27263,7 +27367,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
while current do
local char=ischar(current,currentfont)
if char then
- local lg=ligature[char]
+ local lg=not tonumber(ligature) and ligature[char]
if lg then
stop=current
ligature=lg
@@ -27276,14 +27380,14 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
end
end
if stop then
- local lig=ligature.ligature
- if lig then
+ local ligature=tonumber(ligature) or ligature.ligature
+ if ligature then
if trace_ligatures then
local stopchar=getchar(stop)
- head,start=markstoligature(head,start,stop,lig)
+ head,start=markstoligature(head,start,stop,ligature)
logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start)))
else
- head,start=markstoligature(head,start,stop,lig)
+ head,start=markstoligature(head,start,stop,ligature)
end
return head,start,true,false
else
@@ -27298,7 +27402,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
if skiphash and skiphash[char] then
current=getnext(current)
else
- local lg=ligature[char]
+ local lg=not tonumber(ligature) and ligature[char]
if lg then
if marks[char] then
hasmarks=true
@@ -27324,20 +27428,20 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
local match
if replace then
local char=ischar(replace,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match=true
end
end
if not match and pre then
local char=ischar(pre,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match=true
end
end
if not match and not pre or not replace then
local n=getnext(discfound)
local char=ischar(n,currentfont)
- if char and ligature[char] then
+ if char and (not tonumber(ligature) and ligature[char]) then
match=true
end
end
@@ -27380,21 +27484,21 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
return head,start,true,true
end
end
- local lig=ligature.ligature
- if lig then
+ local ligature=tonumber(ligature) or ligature.ligature
+ if ligature then
if stop then
if trace_ligatures then
local stopchar=getchar(stop)
- head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
- logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig))
+ head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
+ logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(ligature))
else
- head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks)
+ head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,false,hasmarks)
end
else
resetinjection(start)
- setchar(start,lig)
+ setchar(start,ligature)
if trace_ligatures then
- logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig))
+ logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(ligature))
end
end
return head,start,true,false
@@ -27868,7 +27972,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
if skiphash and skiphash[schar] then
current=getnext(current)
else
- local lg=ligatures[schar]
+ local lg=not tonumber(ligatures) and ligatures[schar]
if lg then
ligatures=lg
last=current
@@ -27887,7 +27991,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
end
end
end
- local ligature=ligatures.ligature
+ local ligature=tonumber(ligatures) or ligatures.ligature
if ligature then
if chainindex then
stop=last
@@ -28299,7 +28403,7 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
local chainproc=chainprocs[chainkind]
if chainproc then
local ok
- head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash)
+ head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,1)
if ok then
done=true
end
@@ -28716,6 +28820,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local ck=contexts[k]
local seq=ck[3]
local f=ck[4]
+local last=start
if not startchar or not seq[f][startchar] then
goto next
end
@@ -28724,7 +28829,6 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
else
local l=ck[5]
local current=start
- local last=start
if l>f then
local discfound
local n=f+1
@@ -29508,7 +29612,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
while s do
local char=ischar(s,font)
if char then
- local lg=lookupmatch[char]
+ local lg=not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d=1
@@ -29538,7 +29642,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
break
end
end
- if l and l.ligature then
+ if l and (tonumber(l) or l.ligature) then
lastd=d
end
else
@@ -29663,7 +29767,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
while s do
local char=ischar(s)
if char then
- local lg=lookupmatch[char]
+ local lg=not tonumber(lookupmatch) and lookupmatch[char]
if lg then
if sstop then
d=1
@@ -29693,7 +29797,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
break
end
end
- if l and l.ligature then
+ if l and (tonumber(l) or l.ligature) then
lastd=d
end
end
@@ -31665,7 +31769,7 @@ local function initializedevanagi(tfmdata)
local h=coverage[k]
if h then
for k,v in next,h do
- found=v and v.ligature
+ found=v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found]=true
break
@@ -31682,7 +31786,7 @@ local function initializedevanagi(tfmdata)
end
else
for k,v in next,r do
- found=v and v.ligature
+ found=v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found]=true
break
@@ -31730,7 +31834,7 @@ local function initializedevanagi(tfmdata)
for k,v in next,halant do
local h=r[k]
if h then
- reph=h.ligature or false
+ reph=tonumber(h) or h.ligature or false
break
end
end
@@ -31747,7 +31851,7 @@ local function initializedevanagi(tfmdata)
for k,v in next,halant do
local h=r[k]
if h then
- reph=h.ligature or false
+ reph=tonumber(h) or h.ligature or false
break
end
end
@@ -31791,7 +31895,7 @@ local function initializedevanagi(tfmdata)
local h=coverage[k]
if h then
for k,v in next,h do
- found=v and v.ligature
+ found=v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found]=true
break
@@ -31808,7 +31912,7 @@ local function initializedevanagi(tfmdata)
end
else
for k,v in next,h do
- found=v and v.ligature
+ found=v and (tonumber(v) or v.ligature)
if found then
pre_base_reordering_consonants[found]=true
break