From 69d2352af4b60929b37fc49f3bdb263977016244 Mon Sep 17 00:00:00 2001
From: Marius
Date: Fri, 19 Oct 2012 01:20:13 +0300
Subject: stable 2012.05.30 11:26
---
bibtex/bst/context/cont-ab.bst | 1 -
bibtex/bst/context/cont-au.bst | 1 -
bibtex/bst/context/cont-no.bst | 1 -
bibtex/bst/context/cont-ti.bst | 1 -
.../lexers/data/scite-context-data-context.lua | 4 +-
.../lexers/data/scite-context-data-metafun.lua | 2 +-
.../data/scite/lexers/scite-context-lexer-tex.lua | 12 +-
.../data/scite/lexers/scite-context-lexer-txt.lua | 38 +-
.../data/scite/lexers/scite-context-lexer-xml.lua | 17 +-
context/data/scite/lexers/scite-context-lexer.lua | 47 +-
.../scite/scite-context-data-context.properties | 237 +-
.../scite/scite-context-data-metafun.properties | 34 +-
context/data/scite/scite-context-readme.pdf | Bin 206760 -> 205340 bytes
context/data/scite/scite-context-readme.tex | 2 +-
context/data/scite/scite-context.properties | 16 +-
metapost/context/base/metafun.mpiv | 7 +-
metapost/context/base/mp-abck.mpiv | 2 +-
metapost/context/base/mp-apos.mpiv | 2 +-
metapost/context/base/mp-asnc.mpiv | 2 +-
metapost/context/base/mp-butt.mpiv | 2 +-
metapost/context/base/mp-char.mpiv | 2 +-
metapost/context/base/mp-chem.mpiv | 350 +-
metapost/context/base/mp-core.mpiv | 2 +-
metapost/context/base/mp-crop.mpiv | 14 +-
metapost/context/base/mp-figs.mpiv | 2 +-
metapost/context/base/mp-form.mpiv | 2 +-
metapost/context/base/mp-func.mpiv | 2 +-
metapost/context/base/mp-grap.mpiv | 202 -
metapost/context/base/mp-grid.mpiv | 2 +-
metapost/context/base/mp-grph.mpiv | 2 +-
metapost/context/base/mp-mlib.mpiv | 29 +-
metapost/context/base/mp-page.mpiv | 2 +-
metapost/context/base/mp-shap.mpiv | 2 +-
metapost/context/base/mp-step.mpiv | 2 +-
metapost/context/base/mp-text.mpiv | 2 +-
metapost/context/base/mp-tool.mpiv | 4 +-
scripts/context/lua/mtx-context.lua | 1518 ++--
scripts/context/lua/mtx-convert.lua | 4 +-
scripts/context/lua/mtx-epub.lua | 113 +-
scripts/context/lua/mtx-fcd.lua | 366 -
scripts/context/lua/mtx-flac.lua | 6 +
scripts/context/lua/mtx-fonts.lua | 4 +-
scripts/context/lua/mtx-grep.lua | 4 +-
scripts/context/lua/mtx-metapost.lua | 2 +-
scripts/context/lua/mtx-pdf.lua | 142 +-
scripts/context/lua/mtx-scite.lua | 25 +-
scripts/context/lua/mtx-server-ctx-help.lua | 215 +-
scripts/context/lua/mtx-server.lua | 41 +-
scripts/context/lua/mtx-tools.lua | 2 +-
scripts/context/lua/mtx-update.lua | 4 +-
scripts/context/lua/mtx-watch.lua | 11 +
scripts/context/lua/mtxrun.lua | 2679 +++----
scripts/context/ruby/fcd_start.rb | 472 ++
scripts/context/stubs/mswin/mtxrun.lua | 2679 +++----
scripts/context/stubs/unix/mtxrun | 2679 +++----
tex/context/base/anch-bar.mkiv | 150 +-
tex/context/base/anch-bck.mkvi | 14 +-
tex/context/base/anch-pgr.lua | 248 +-
tex/context/base/anch-pgr.mkiv | 120 +-
tex/context/base/anch-pos.lua | 18 +-
tex/context/base/anch-pos.mkiv | 8 +-
tex/context/base/anch-tab.mkiv | 186 +-
tex/context/base/attr-col.lua | 71 +-
tex/context/base/attr-eff.lua | 39 +-
tex/context/base/attr-eff.mkiv | 43 +-
tex/context/base/attr-ini.lua | 36 +-
tex/context/base/attr-ini.mkiv | 12 +-
tex/context/base/attr-lay.lua | 98 +-
tex/context/base/attr-lay.mkiv | 82 +-
tex/context/base/attr-neg.lua | 5 +-
tex/context/base/attr-neg.mkiv | 10 +-
tex/context/base/back-exp.lua | 24 +-
tex/context/base/back-exp.mkiv | 26 +-
tex/context/base/back-ini.lua | 4 +-
tex/context/base/back-ini.mkiv | 6 +-
tex/context/base/back-pdf.mkiv | 28 +-
tex/context/base/back-swf.mkiv | 14 +-
tex/context/base/back-u3d.mkiv | 7 +-
tex/context/base/bibl-bib.mkiv | 2 +-
tex/context/base/bibl-tra.lua | 4 +-
tex/context/base/bibl-tra.mkiv | 25 +-
tex/context/base/blob-ini.lua | 2 +-
tex/context/base/buff-ini.lua | 39 +-
tex/context/base/buff-ini.mkiv | 24 -
tex/context/base/buff-par.lua | 27 +-
tex/context/base/buff-par.mkiv | 151 +
tex/context/base/buff-par.mkvi | 131 -
tex/context/base/buff-ver.lua | 6 +-
tex/context/base/buff-ver.mkiv | 30 +-
tex/context/base/catc-ctx.mkiv | 11 +-
tex/context/base/catc-def.mkiv | 7 +-
tex/context/base/catc-ini.lua | 21 +-
tex/context/base/catc-ini.mkiv | 64 +-
tex/context/base/char-cjk.lua | 23 +-
tex/context/base/char-def.lua | 80 +-
tex/context/base/char-enc.lua | 41 +-
tex/context/base/char-ent.lua | 5 +-
tex/context/base/char-ini.lua | 86 +-
tex/context/base/char-map.lua | 3 +-
tex/context/base/char-utf.lua | 21 +-
tex/context/base/chem-ini.lua | 8 +-
tex/context/base/chem-str.lua | 134 +-
tex/context/base/chem-str.mkiv | 216 +-
tex/context/base/cldf-bas.lua | 52 +-
tex/context/base/cldf-com.lua | 4 +-
tex/context/base/cldf-ini.lua | 26 +-
tex/context/base/cldf-int.lua | 11 +-
tex/context/base/cldf-ver.lua | 6 +-
tex/context/base/colo-ext.mkiv | 10 +-
tex/context/base/colo-icc.lua | 2 +-
tex/context/base/colo-ini.lua | 124 +-
tex/context/base/colo-ini.mkiv | 34 +-
tex/context/base/colo-run.lua | 6 +-
tex/context/base/colo-run.mkiv | 28 +-
tex/context/base/cont-log.mkiv | 10 +-
tex/context/base/cont-new.mkii | 2 +-
tex/context/base/cont-new.mkiv | 497 +-
tex/context/base/cont-nop.mkiv | 22 -
tex/context/base/cont-yes.mkiv | 80 -
tex/context/base/context-base.lmx | 4 +-
tex/context/base/context-help.lmx | 1 -
tex/context/base/context-version.pdf | Bin 4141 -> 4128 bytes
tex/context/base/context-version.png | Bin 106781 -> 105721 bytes
tex/context/base/context.mkii | 2 +-
tex/context/base/context.mkiv | 57 +-
tex/context/base/context.rme | 7 +-
tex/context/base/context.todo | 6 +
tex/context/base/core-con.lua | 153 +-
tex/context/base/core-con.mkiv | 177 +-
tex/context/base/core-ctx.ctx | 23 -
tex/context/base/core-ctx.lua | 331 +-
tex/context/base/core-ctx.mkiv | 18 +-
tex/context/base/core-dat.lua | 60 +-
tex/context/base/core-def.mkiv | 126 +-
tex/context/base/core-env.lua | 7 +-
tex/context/base/core-env.mkiv | 115 +-
tex/context/base/core-fnt.mkiv | 158 +
tex/context/base/core-ini.mkiv | 228 +-
tex/context/base/core-mis.mkiv | 738 ++
tex/context/base/core-sys.lua | 90 +-
tex/context/base/core-sys.mkiv | 80 +-
tex/context/base/core-two.lua | 2 +-
tex/context/base/core-uti.lua | 22 +-
tex/context/base/core-var.mkiv | 239 +
tex/context/base/data-env.lua | 6 +-
tex/context/base/data-exp.lua | 8 +-
tex/context/base/data-ini.lua | 2 +-
tex/context/base/data-lua.lua | 263 +-
tex/context/base/data-pre.lua | 44 +-
tex/context/base/data-res.lua | 59 +-
tex/context/base/data-sch.lua | 68 +-
tex/context/base/data-tex.lua | 7 -
tex/context/base/data-vir.lua | 8 +-
tex/context/base/data-zip.lua | 16 +-
tex/context/base/enco-ini.mkiv | 111 +-
tex/context/base/file-ini.lua | 5 +-
tex/context/base/file-ini.mkvi | 20 +-
tex/context/base/file-job.lua | 348 +-
tex/context/base/file-job.mkvi | 25 +-
tex/context/base/file-lib.lua | 7 +-
tex/context/base/file-mod.lua | 16 +-
tex/context/base/file-res.lua | 6 +-
tex/context/base/file-syn.lua | 7 +-
tex/context/base/font-afk.lua | 200 -
tex/context/base/font-afm.lua | 372 +-
tex/context/base/font-age.lua | 1 -
tex/context/base/font-agl.lua | 2 +-
tex/context/base/font-aux.lua | 2 +-
tex/context/base/font-aux.mkvi | 26 -
tex/context/base/font-chk.lua | 2 +-
tex/context/base/font-chk.mkiv | 22 -
tex/context/base/font-cid.lua | 17 +-
tex/context/base/font-col.lua | 96 +-
tex/context/base/font-con.lua | 30 +-
tex/context/base/font-ctx.lua | 272 +-
tex/context/base/font-def.lua | 23 +-
tex/context/base/font-ext.lua | 38 +-
tex/context/base/font-fbk.lua | 23 +-
tex/context/base/font-gds.lua | 59 +-
tex/context/base/font-gds.mkiv | 83 +
tex/context/base/font-gds.mkvi | 83 -
tex/context/base/font-ini.lua | 24 +-
tex/context/base/font-ldr.lua | 4 +-
tex/context/base/font-lib.mkvi | 4 +-
tex/context/base/font-map.lua | 12 +-
tex/context/base/font-mat.mkvi | 1 -
tex/context/base/font-mis.lua | 2 +-
tex/context/base/font-ota.lua | 83 +-
tex/context/base/font-otb.lua | 37 +-
tex/context/base/font-otc.lua | 3 +-
tex/context/base/font-otd.lua | 31 +-
tex/context/base/font-otf.lua | 96 +-
tex/context/base/font-oti.lua | 13 +-
tex/context/base/font-otn.lua | 338 +-
tex/context/base/font-otp.lua | 53 +-
tex/context/base/font-ott.lua | 171 +-
tex/context/base/font-pat.lua | 14 +-
tex/context/base/font-pre.mkiv | 30 +-
tex/context/base/font-run.mkiv | 47 +-
tex/context/base/font-set.mkvi | 2 +-
tex/context/base/font-sol.lua | 898 ---
tex/context/base/font-sol.mkvi | 123 -
tex/context/base/font-sty.mkvi | 42 +-
tex/context/base/font-syn.lua | 11 +-
tex/context/base/font-tfm.lua | 15 +-
tex/context/base/font-tra.mkiv | 46 +-
tex/context/base/font-vf.lua | 3 +-
tex/context/base/grph-epd.lua | 1 +
tex/context/base/grph-epd.mkiv | 12 +-
tex/context/base/grph-fig.mkiv | 729 +-
tex/context/base/grph-fil.lua | 11 +-
tex/context/base/grph-inc.lua | 100 +-
tex/context/base/grph-inc.mkiv | 895 +--
tex/context/base/grph-raw.lua | 5 +-
tex/context/base/grph-raw.mkiv | 14 +-
tex/context/base/grph-swf.lua | 15 +-
tex/context/base/grph-trf.mkiv | 492 +-
tex/context/base/grph-u3d.lua | 8 +-
tex/context/base/java-ini.lua | 37 +-
tex/context/base/l-boolean.lua | 45 +-
tex/context/base/l-dir.lua | 18 -
tex/context/base/l-file.lua | 36 +-
tex/context/base/l-io.lua | 47 +-
tex/context/base/l-lpeg.lua | 228 +-
tex/context/base/l-md5.lua | 33 +-
tex/context/base/l-number.lua | 10 +-
tex/context/base/l-os.lua | 67 +-
tex/context/base/l-string.lua | 17 -
tex/context/base/l-table.lua | 131 +-
tex/context/base/l-unicode.lua | 356 +-
tex/context/base/l-url.lua | 124 +-
tex/context/base/lang-def.lua | 47 +-
tex/context/base/lang-def.mkiv | 34 +-
tex/context/base/lang-frd.mkiv | 141 -
tex/context/base/lang-frq.mkiv | 233 -
tex/context/base/lang-ini.lua | 91 +-
tex/context/base/lang-ini.mkiv | 31 +-
tex/context/base/lang-lab.lua | 67 +-
tex/context/base/lang-lab.mkiv | 70 +-
tex/context/base/lang-mis.mkiv | 31 -
tex/context/base/lang-txt.lua | 183 +-
tex/context/base/lang-url.lua | 7 +-
tex/context/base/lang-wrd.lua | 97 +-
tex/context/base/lpdf-ano.lua | 6 +-
tex/context/base/lpdf-col.lua | 8 +-
tex/context/base/lpdf-epa.lua | 6 +-
tex/context/base/lpdf-epd.lua | 24 +-
tex/context/base/lpdf-fmt.lua | 40 +-
tex/context/base/lpdf-nod.lua | 71 +-
tex/context/base/lpdf-ren.lua | 120 +-
tex/context/base/lpdf-u3d.lua | 2 +-
tex/context/base/luat-bwc.lua | 2 +-
tex/context/base/luat-cbk.lua | 29 +-
tex/context/base/luat-cnf.lua | 7 +-
tex/context/base/luat-cod.lua | 28 +-
tex/context/base/luat-cod.mkiv | 6 +
tex/context/base/luat-env.lua | 44 +-
tex/context/base/luat-fmt.lua | 1 +
tex/context/base/luat-ini.lua | 44 +-
tex/context/base/luat-ini.mkiv | 8 +-
tex/context/base/luat-lib.mkiv | 5 -
tex/context/base/luat-mac.lua | 92 +-
tex/context/base/luat-run.lua | 12 +-
tex/context/base/luat-soc.lua | 16 +-
tex/context/base/luat-sto.lua | 32 +-
tex/context/base/lxml-css.lua | 48 +-
tex/context/base/lxml-ctx.mkiv | 3 +
tex/context/base/lxml-ini.mkiv | 4 +-
tex/context/base/lxml-lpt.lua | 51 +-
tex/context/base/lxml-tab.lua | 42 +-
tex/context/base/lxml-tex.lua | 25 +-
tex/context/base/m-barcodes.mkiv | 8 +-
tex/context/base/m-chart.lua | 159 +-
tex/context/base/m-chart.mkii | 2 +-
tex/context/base/m-chart.mkvi | 154 +-
tex/context/base/m-database.mkiv | 7 +-
tex/context/base/m-graph.mkiv | 124 +-
tex/context/base/m-ipsum.mkiv | 198 -
tex/context/base/m-json.mkiv | 30 -
tex/context/base/m-morse.mkvi | 12 +-
tex/context/base/m-oldfun.mkiv | 714 --
tex/context/base/m-oldnum.mkiv | 416 --
tex/context/base/m-pstricks.lua | 8 +-
tex/context/base/m-spreadsheet.lua | 331 -
tex/context/base/m-spreadsheet.mkiv | 295 +-
tex/context/base/m-timing.mkiv | 10 +-
tex/context/base/m-translate.mkiv | 27 +-
tex/context/base/m-visual.mkiv | 581 +-
tex/context/base/math-act.lua | 2 -
tex/context/base/math-ali.mkiv | 101 +-
tex/context/base/math-arr.mkiv | 405 +-
tex/context/base/math-def.mkiv | 10 +-
tex/context/base/math-dim.lua | 6 +-
tex/context/base/math-ext.lua | 5 +-
tex/context/base/math-fbk.lua | 281 -
tex/context/base/math-for.mkiv | 15 +
tex/context/base/math-ini.lua | 141 +-
tex/context/base/math-ini.mkiv | 41 +-
tex/context/base/math-int.mkiv | 15 +-
tex/context/base/math-noa.lua | 219 +-
tex/context/base/math-ttv.lua | 799 ---
tex/context/base/math-vfu.lua | 785 ++-
tex/context/base/meta-grd.mkiv | 116 -
tex/context/base/meta-imp-dum.mkiv | 123 +-
tex/context/base/meta-ini.lua | 2 -
tex/context/base/meta-ini.mkiv | 67 +-
tex/context/base/meta-pag.mkiv | 10 +-
tex/context/base/meta-pdf.lua | 7 +-
tex/context/base/meta-pdh.mkiv | 2 +-
tex/context/base/meta-tex.lua | 2 +-
tex/context/base/mlib-ctx.lua | 2 -
tex/context/base/mlib-pdf.lua | 93 +-
tex/context/base/mlib-pdf.mkiv | 6 +-
tex/context/base/mlib-pps.mkiv | 16 +-
tex/context/base/mlib-run.lua | 261 +-
tex/context/base/mult-aux.lua | 2 +-
tex/context/base/mult-aux.mkiv | 180 +-
tex/context/base/mult-chk.lua | 5 +-
tex/context/base/mult-chk.mkiv | 14 +-
tex/context/base/mult-de.mkii | 8 -
tex/context/base/mult-def.lua | 45 +-
tex/context/base/mult-def.mkiv | 76 +-
tex/context/base/mult-dim.mkvi | 1 -
tex/context/base/mult-en.mkii | 8 -
tex/context/base/mult-fr.mkii | 8 -
tex/context/base/mult-fun.lua | 95 -
tex/context/base/mult-ini.lua | 122 +-
tex/context/base/mult-ini.mkiv | 72 +-
tex/context/base/mult-it.mkii | 8 -
tex/context/base/mult-low.lua | 50 +-
tex/context/base/mult-mes.lua | 3 +-
tex/context/base/mult-nl.mkii | 8 -
tex/context/base/mult-pe.mkii | 8 -
tex/context/base/mult-prm.mkiv | 15 -
tex/context/base/mult-ro.mkii | 8 -
tex/context/base/mult-sys.mkiv | 566 +-
tex/context/base/node-aux.lua | 44 +-
tex/context/base/node-dir.lua | 2 +-
tex/context/base/node-fin.lua | 591 +-
tex/context/base/node-ini.lua | 42 +-
tex/context/base/node-inj.lua | 31 +-
tex/context/base/node-par.lua | 118 +
tex/context/base/node-par.mkiv | 82 +
tex/context/base/node-ref.lua | 11 +-
tex/context/base/node-res.lua | 19 +-
tex/context/base/node-rul.lua | 32 +-
tex/context/base/node-rul.mkiv | 40 +-
tex/context/base/node-ser.lua | 27 +-
tex/context/base/node-spl.lua | 619 ++
tex/context/base/node-spl.mkiv | 114 +
tex/context/base/node-tra.lua | 90 +-
tex/context/base/node-tsk.lua | 4 +-
tex/context/base/node-typ.lua | 9 +-
tex/context/base/norm-ctx.mkiv | 8 +-
tex/context/base/pack-bar.mkiv | 97 +-
tex/context/base/pack-bck.mkvi | 2 +-
tex/context/base/pack-box.mkiv | 881 +--
tex/context/base/pack-com.mkiv | 14 +-
tex/context/base/pack-cut.mkiv | 163 -
tex/context/base/pack-mrl.mkiv | 920 +--
tex/context/base/pack-obj.lua | 25 +-
tex/context/base/pack-obj.mkiv | 143 +-
tex/context/base/pack-pos.mkiv | 189 +-
tex/context/base/pack-rul.mkiv | 1021 +--
tex/context/base/page-app.mkiv | 9 +-
tex/context/base/page-bck.mkiv | 394 +-
tex/context/base/page-brk.mkiv | 14 +-
tex/context/base/page-col.mkiv | 245 +-
tex/context/base/page-com.mkiv | 176 +-
tex/context/base/page-fac.mkiv | 48 +-
tex/context/base/page-flt.lua | 14 +-
tex/context/base/page-flt.mkiv | 214 +-
tex/context/base/page-flw.mkiv | 186 +-
tex/context/base/page-grd.mkiv | 6 +-
tex/context/base/page-imp.mkiv | 3 +-
tex/context/base/page-inf.mkiv | 6 +-
tex/context/base/page-ini.mkiv | 46 +-
tex/context/base/page-ins.lua | 97 -
tex/context/base/page-ins.mkiv | 197 +-
tex/context/base/page-lay.mkiv | 77 +-
tex/context/base/page-lin.lua | 9 -
tex/context/base/page-lin.mkiv | 597 +-
tex/context/base/page-mak.mkvi | 33 +-
tex/context/base/page-mbk.mkvi | 4 +-
tex/context/base/page-mis.lua | 77 +
tex/context/base/page-mis.mkiv | 95 +
tex/context/base/page-mix.lua | 642 --
tex/context/base/page-mix.mkiv | 771 --
tex/context/base/page-mul.mkiv | 2253 +++---
tex/context/base/page-not.mkiv | 20 +-
tex/context/base/page-one.mkiv | 259 +-
tex/context/base/page-otr.mkvi | 4 +-
tex/context/base/page-par.mkiv | 88 +-
tex/context/base/page-plg.mkiv | 110 +-
tex/context/base/page-pst.lua | 78 -
tex/context/base/page-pst.mkiv | 102 -
tex/context/base/page-run.mkiv | 8 +-
tex/context/base/page-sel.mkiv | 347 +
tex/context/base/page-sel.mkvi | 368 -
tex/context/base/page-set.mkiv | 598 +-
tex/context/base/page-sid.mkiv | 60 +-
tex/context/base/page-spr.mkiv | 90 +-
tex/context/base/page-str.mkiv | 39 +-
tex/context/base/page-txt.mkvi | 112 +-
tex/context/base/phys-dim.lua | 66 +-
tex/context/base/phys-dim.mkiv | 19 +-
tex/context/base/ppchtex.mkiv | 18 +-
tex/context/base/prop-ini.mkiv | 2 +-
tex/context/base/regi-ini.lua | 72 +-
tex/context/base/s-abr-01.tex | 554 +-
tex/context/base/s-art-01.mkiv | 4 -
tex/context/base/s-def-01.mkiv | 2 +-
tex/context/base/s-fnt-10.mkiv | 2 +-
tex/context/base/s-fnt-20.mkiv | 10 +-
tex/context/base/s-fnt-28.mkiv | 2 +-
tex/context/base/s-fnt-29.mkiv | 2 +-
tex/context/base/s-fnt-32.mkiv | 2 +-
tex/context/base/s-inf-01.mkvi | 2 +-
tex/context/base/s-inf-03.mkiv | 117 +-
tex/context/base/s-lan-04.mkiv | 2 +-
tex/context/base/s-mod.ctx | 1 +
tex/context/base/s-pre-60.mkiv | 134 +-
tex/context/base/s-pre-61.tex | 2 +-
tex/context/base/s-pre-62.tex | 2 +-
tex/context/base/s-pre-63.tex | 1 -
tex/context/base/s-pre-67.tex | 2 +-
tex/context/base/s-pre-69.mkiv | 2 +-
tex/context/base/scrn-fld.lua | 6 +-
tex/context/base/scrn-fld.mkvi | 10 +-
tex/context/base/scrn-ini.lua | 2 +-
tex/context/base/scrn-ini.mkvi | 14 +-
tex/context/base/scrn-pag.mkvi | 6 +
tex/context/base/scrn-ref.lua | 2 +-
tex/context/base/scrn-wid.lua | 12 +-
tex/context/base/scrn-wid.mkvi | 125 +-
tex/context/base/scrp-cjk.lua | 3 -
tex/context/base/scrp-ini.lua | 276 +-
tex/context/base/sort-ini.lua | 2 +-
tex/context/base/sort-lan.lua | 20 +-
tex/context/base/spac-ali.lua | 6 +-
tex/context/base/spac-ali.mkiv | 52 +-
tex/context/base/spac-cha.mkiv | 191 -
tex/context/base/spac-def.mkiv | 116 +-
tex/context/base/spac-grd.mkiv | 61 +-
tex/context/base/spac-hor.mkiv | 137 +-
tex/context/base/spac-par.mkiv | 7 -
tex/context/base/spac-ver.lua | 62 +-
tex/context/base/spac-ver.mkiv | 299 +-
tex/context/base/status-files.pdf | Bin 24604 -> 24413 bytes
tex/context/base/status-lua.pdf | Bin 195628 -> 180149 bytes
tex/context/base/status-mkiv.lua | 7384 ++++----------------
tex/context/base/status-mkiv.tex | 308 +-
tex/context/base/strc-bkm.mkiv | 150 +-
tex/context/base/strc-blk.lua | 7 +-
tex/context/base/strc-blk.mkiv | 96 +-
tex/context/base/strc-con.mkvi | 197 +-
tex/context/base/strc-def.mkiv | 59 +-
tex/context/base/strc-des.mkii | 2 +-
tex/context/base/strc-des.mkvi | 52 +-
tex/context/base/strc-doc.lua | 48 +-
tex/context/base/strc-doc.mkiv | 234 +-
tex/context/base/strc-enu.mkvi | 69 +-
tex/context/base/strc-flt.mkvi | 1060 ++-
tex/context/base/strc-ind.mkiv | 12 +-
tex/context/base/strc-ini.lua | 25 +-
tex/context/base/strc-itm.mkvi | 89 +-
tex/context/base/strc-lab.mkiv | 239 +-
tex/context/base/strc-lnt.mkvi | 127 +-
tex/context/base/strc-lst.lua | 3 +-
tex/context/base/strc-lst.mkvi | 31 +-
tex/context/base/strc-mar.lua | 11 +-
tex/context/base/strc-mat.mkiv | 487 +-
tex/context/base/strc-not.lua | 180 +-
tex/context/base/strc-not.mkvi | 627 +-
tex/context/base/strc-num.lua | 207 +-
tex/context/base/strc-num.mkiv | 62 +-
tex/context/base/strc-pag.lua | 12 -
tex/context/base/strc-pag.mkiv | 193 +-
tex/context/base/strc-ref.lua | 127 +-
tex/context/base/strc-ref.mkvi | 346 +-
tex/context/base/strc-reg.lua | 11 +-
tex/context/base/strc-reg.mkiv | 454 +-
tex/context/base/strc-ren.mkiv | 866 +--
tex/context/base/strc-sbe.mkiv | 102 +-
tex/context/base/strc-sec.mkiv | 828 +--
tex/context/base/strc-syn.lua | 2 +-
tex/context/base/strc-syn.mkiv | 4 +-
tex/context/base/strc-tag.lua | 1 -
tex/context/base/strc-tag.mkiv | 9 -
tex/context/base/supp-ali.mkiv | 173 +
tex/context/base/supp-box.lua | 12 +-
tex/context/base/supp-box.mkiv | 68 +-
tex/context/base/supp-fun.mkiv | 716 ++
tex/context/base/supp-mat.mkiv | 143 +-
tex/context/base/supp-num.mkiv | 416 ++
tex/context/base/supp-ran.lua | 28 +-
tex/context/base/supp-ran.mkiv | 4 +-
tex/context/base/supp-vis.mkiv | 185 +-
tex/context/base/symb-run.mkiv | 8 +-
tex/context/base/syst-aux.lua | 33 +-
tex/context/base/syst-aux.mkiv | 3650 +++++-----
tex/context/base/syst-fnt.mkiv | 2 +-
tex/context/base/syst-gen.mkii | 5 -
tex/context/base/syst-ini.mkiv | 338 +-
tex/context/base/syst-lua.lua | 52 +-
tex/context/base/syst-lua.mkiv | 7 -
tex/context/base/tabl-ltb.mkiv | 8 +-
tex/context/base/tabl-mis.mkiv | 288 -
tex/context/base/tabl-ntb.mkiv | 1912 +++--
tex/context/base/tabl-nte.mkiv | 67 +-
tex/context/base/tabl-pln.mkiv | 155 +-
tex/context/base/tabl-tab.mkiv | 174 +-
tex/context/base/tabl-tbl.lua | 6 +-
tex/context/base/tabl-tbl.mkiv | 129 +-
tex/context/base/tabl-tsp.mkiv | 470 +-
tex/context/base/tabl-xnt.mkvi | 2 +-
tex/context/base/tabl-xtb.lua | 5 +-
tex/context/base/tabl-xtb.mkvi | 108 +-
tex/context/base/task-ini.lua | 9 +-
tex/context/base/trac-ctx.lua | 36 -
tex/context/base/trac-ctx.mkiv | 28 -
tex/context/base/trac-deb.lua | 13 +-
tex/context/base/trac-deb.mkiv | 6 +-
tex/context/base/trac-fil.lua | 214 +-
tex/context/base/trac-inf.lua | 4 +-
tex/context/base/trac-lmx.lua | 606 +-
tex/context/base/trac-set.lua | 36 +-
tex/context/base/trac-tex.lua | 2 +-
tex/context/base/trac-tim.lua | 2 +-
tex/context/base/trac-vis.lua | 859 ---
tex/context/base/trac-vis.mkiv | 810 ++-
tex/context/base/type-imp-husayni.mkiv | 290 +-
tex/context/base/type-ini.lua | 17 +-
tex/context/base/type-ini.mkvi | 14 +-
tex/context/base/typo-bld.lua | 186 -
tex/context/base/typo-bld.mkiv | 64 -
tex/context/base/typo-brk.lua | 17 +-
tex/context/base/typo-brk.mkiv | 18 +-
tex/context/base/typo-cap.mkiv | 25 +-
tex/context/base/typo-del.mkiv | 31 +-
tex/context/base/typo-dir.lua | 10 +-
tex/context/base/typo-itm.mkiv | 273 -
tex/context/base/typo-krn.lua | 51 +-
tex/context/base/typo-krn.mkiv | 57 +-
tex/context/base/typo-mar.lua | 89 +-
tex/context/base/typo-mar.mkiv | 7 +-
tex/context/base/typo-scr.mkiv | 250 +-
tex/context/base/typo-spa.mkiv | 17 +-
tex/context/base/typo-txt.mkvi | 174 +-
tex/context/base/unic-ini.mkiv | 2 +-
tex/context/base/util-deb.lua | 3 +-
tex/context/base/util-dim.lua | 18 +-
tex/context/base/util-jsn.lua | 145 -
tex/context/base/util-lua.lua | 213 +-
tex/context/base/util-mrg.lua | 9 +-
tex/context/base/util-prs.lua | 73 +-
tex/context/base/util-sql-imp-client.lua | 253 -
tex/context/base/util-sql-imp-library.lua | 283 -
tex/context/base/util-sql-imp-swiglib.lua | 426 --
tex/context/base/util-sql-loggers.lua | 277 -
tex/context/base/util-sql-sessions.lua | 349 -
tex/context/base/util-sql-tickets.lua | 698 --
tex/context/base/util-sql-users.lua | 417 --
tex/context/base/util-sql.lua | 425 --
tex/context/base/util-sta.lua | 342 -
tex/context/base/util-str.lua | 7 +-
tex/context/base/util-tab.lua | 120 +-
tex/context/base/util-tpl.lua | 117 -
tex/context/base/x-asciimath.mkiv | 2 +-
tex/context/base/x-chemml.lua | 2 +-
tex/context/base/x-chemml.mkiv | 22 +-
tex/context/base/x-dir-05.mkiv | 4 +-
tex/context/base/x-mathml.lua | 24 +-
tex/context/base/x-mathml.mkiv | 2366 +++++++
tex/context/base/x-udhr.mkiv | 2 +-
tex/context/base/x-xfdf.mkiv | 72 -
tex/context/base/xtag-ini.mkii | 50 +-
tex/context/base/xtag-pre.mkii | 13 -
tex/context/fonts/demo.lfg | 29 +-
tex/context/fonts/husayni.lfg | 6 +-
tex/context/interface/keys-cs.xml | 8 -
tex/context/interface/keys-de.xml | 8 -
tex/context/interface/keys-en.xml | 8 -
tex/context/interface/keys-fr.xml | 8 -
tex/context/interface/keys-it.xml | 8 -
tex/context/interface/keys-nl.xml | 8 -
tex/context/interface/keys-pe.xml | 8 -
tex/context/interface/keys-ro.xml | 8 -
tex/context/sample/lorem.tex | 11 -
tex/context/test/pdf-x1a-2001.mkiv | 2 +-
tex/context/test/pdf-x1a-2003.mkiv | 2 +-
tex/context/test/pdf-x3-2002.mkiv | 2 +-
tex/context/test/pdf-x3-2003.mkiv | 2 +-
tex/context/test/pdf-x4.mkiv | 2 +-
tex/context/test/pdf-x4p.mkiv | 4 +-
tex/generic/context/luatex/luatex-basics-gen.lua | 4 +-
tex/generic/context/luatex/luatex-fonts-ext.lua | 16 +-
tex/generic/context/luatex/luatex-fonts-merged.lua | 1936 +++--
tex/generic/context/luatex/luatex-fonts.lua | 2 +-
tex/generic/context/luatex/luatex-mplib.tex | 11 +-
600 files changed, 33995 insertions(+), 54807 deletions(-)
delete mode 100644 metapost/context/base/mp-grap.mpiv
delete mode 100644 scripts/context/lua/mtx-fcd.lua
create mode 100644 scripts/context/ruby/fcd_start.rb
create mode 100644 tex/context/base/buff-par.mkiv
delete mode 100644 tex/context/base/buff-par.mkvi
delete mode 100644 tex/context/base/cont-nop.mkiv
delete mode 100644 tex/context/base/cont-yes.mkiv
create mode 100644 tex/context/base/context.todo
delete mode 100644 tex/context/base/core-ctx.ctx
create mode 100644 tex/context/base/core-fnt.mkiv
create mode 100644 tex/context/base/core-mis.mkiv
create mode 100644 tex/context/base/core-var.mkiv
delete mode 100644 tex/context/base/font-afk.lua
delete mode 100644 tex/context/base/font-aux.mkvi
delete mode 100644 tex/context/base/font-chk.mkiv
create mode 100644 tex/context/base/font-gds.mkiv
delete mode 100644 tex/context/base/font-gds.mkvi
delete mode 100644 tex/context/base/font-sol.lua
delete mode 100644 tex/context/base/font-sol.mkvi
delete mode 100644 tex/context/base/lang-frd.mkiv
delete mode 100644 tex/context/base/lang-frq.mkiv
delete mode 100644 tex/context/base/m-ipsum.mkiv
delete mode 100644 tex/context/base/m-json.mkiv
delete mode 100644 tex/context/base/m-oldfun.mkiv
delete mode 100644 tex/context/base/m-oldnum.mkiv
delete mode 100644 tex/context/base/m-spreadsheet.lua
delete mode 100644 tex/context/base/math-fbk.lua
delete mode 100644 tex/context/base/math-ttv.lua
delete mode 100644 tex/context/base/meta-grd.mkiv
delete mode 100644 tex/context/base/mult-fun.lua
create mode 100644 tex/context/base/node-par.lua
create mode 100644 tex/context/base/node-par.mkiv
create mode 100644 tex/context/base/node-spl.lua
create mode 100644 tex/context/base/node-spl.mkiv
delete mode 100644 tex/context/base/pack-cut.mkiv
delete mode 100644 tex/context/base/page-ins.lua
create mode 100644 tex/context/base/page-mis.lua
create mode 100644 tex/context/base/page-mis.mkiv
delete mode 100644 tex/context/base/page-mix.lua
delete mode 100644 tex/context/base/page-mix.mkiv
delete mode 100644 tex/context/base/page-pst.lua
delete mode 100644 tex/context/base/page-pst.mkiv
create mode 100644 tex/context/base/page-sel.mkiv
delete mode 100644 tex/context/base/page-sel.mkvi
delete mode 100644 tex/context/base/spac-cha.mkiv
create mode 100644 tex/context/base/supp-ali.mkiv
create mode 100644 tex/context/base/supp-fun.mkiv
create mode 100644 tex/context/base/supp-num.mkiv
delete mode 100644 tex/context/base/tabl-mis.mkiv
delete mode 100644 tex/context/base/trac-ctx.lua
delete mode 100644 tex/context/base/trac-ctx.mkiv
delete mode 100644 tex/context/base/trac-vis.lua
delete mode 100644 tex/context/base/typo-bld.lua
delete mode 100644 tex/context/base/typo-bld.mkiv
delete mode 100644 tex/context/base/typo-itm.mkiv
delete mode 100644 tex/context/base/util-jsn.lua
delete mode 100644 tex/context/base/util-sql-imp-client.lua
delete mode 100644 tex/context/base/util-sql-imp-library.lua
delete mode 100644 tex/context/base/util-sql-imp-swiglib.lua
delete mode 100644 tex/context/base/util-sql-loggers.lua
delete mode 100644 tex/context/base/util-sql-sessions.lua
delete mode 100644 tex/context/base/util-sql-tickets.lua
delete mode 100644 tex/context/base/util-sql-users.lua
delete mode 100644 tex/context/base/util-sql.lua
delete mode 100644 tex/context/base/util-sta.lua
delete mode 100644 tex/context/base/util-tpl.lua
create mode 100644 tex/context/base/x-mathml.mkiv
delete mode 100644 tex/context/base/x-xfdf.mkiv
delete mode 100644 tex/context/sample/lorem.tex
diff --git a/bibtex/bst/context/cont-ab.bst b/bibtex/bst/context/cont-ab.bst
index e09da7ca5..c524ff8ee 100644
--- a/bibtex/bst/context/cont-ab.bst
+++ b/bibtex/bst/context/cont-ab.bst
@@ -618,7 +618,6 @@ FUNCTION {misc}
format.t.title
format.key
"" "\city" address do.out
- "" "\day" day do.out
"" "\month" month do.out
"" "\pubname" publisher do.out
"" "\howpublished" howpublished do.out
diff --git a/bibtex/bst/context/cont-au.bst b/bibtex/bst/context/cont-au.bst
index d0b87186c..2eba98b0a 100644
--- a/bibtex/bst/context/cont-au.bst
+++ b/bibtex/bst/context/cont-au.bst
@@ -618,7 +618,6 @@ FUNCTION {misc}
format.t.title
format.key
"" "\city" address do.out
- "" "\day" day do.out
"" "\month" month do.out
"" "\pubname" publisher do.out
"" "\howpublished" howpublished do.out
diff --git a/bibtex/bst/context/cont-no.bst b/bibtex/bst/context/cont-no.bst
index 393d13db8..dbeb8a45d 100644
--- a/bibtex/bst/context/cont-no.bst
+++ b/bibtex/bst/context/cont-no.bst
@@ -618,7 +618,6 @@ FUNCTION {misc}
format.t.title
format.key
"" "\city" address do.out
- "" "\day" day do.out
"" "\month" month do.out
"" "\pubname" publisher do.out
"" "\howpublished" howpublished do.out
diff --git a/bibtex/bst/context/cont-ti.bst b/bibtex/bst/context/cont-ti.bst
index 34175a0ba..734cbb4b6 100644
--- a/bibtex/bst/context/cont-ti.bst
+++ b/bibtex/bst/context/cont-ti.bst
@@ -618,7 +618,6 @@ FUNCTION {misc}
format.t.title
format.key
"" "\city" address do.out
- "" "\day" day do.out
"" "\month" month do.out
"" "\pubname" publisher do.out
"" "\howpublished" howpublished do.out
diff --git a/context/data/scite/lexers/data/scite-context-data-context.lua b/context/data/scite/lexers/data/scite-context-data-context.lua
index 86a817b70..aa36277b7 100644
--- a/context/data/scite/lexers/data/scite-context-data-context.lua
+++ b/context/data/scite/lexers/data/scite-context-data-context.lua
@@ -1,4 +1,4 @@
return {
- ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "etexversion", "pdftexversion", "xetexversion", "xetexrevision", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifmodeelse", "doifnotmode", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "startmodule", "stopmodule", "usemodule", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile" },
- ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "startcontextcode", "stopcontextcode", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "doifelsecommandhandler", "doifnotcommandhandler", "doifcommandhandler", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", "fifthargumentfalse", "fifthsargumenttrue", "sixthargumentfalse", "sixtsargumenttrue", "doglobal", "dodoglobal", "redoglobal", "resetglobal", "donothing", "dontcomplain", "forgetall", "donetrue", "donefalse", "htdp", "unvoidbox", "hfilll", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "scratchcounter", "globalscratchcounter", "scratchdimen", "globalscratchdimen", "scratchskip", "globalscratchskip", "scratchmuskip", "globalscratchmuskip", "scratchtoks", "globalscratchtoks", "scratchbox", "globalscratchbox", "availablehsize", "localhsize", "setlocalhsize", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchxoffset", "scratchyoffset", "scratchhoffset", "scratchvoffset", "scratchxposition", "scratchyposition", "scratchtopoffset", "scratchbottomoffset", "scratchleftoffset", "scratchrightoffset", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchboxone", "scratchboxtwo", "scratchboxthree", "scratchnx", "scratchny", "scratchmx", "scratchmy", "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifinsetelse", "doifnextcharelse", "doifnextoptionalelse", "doifnextbgroupelse", "doifnextparenthesiselse", "doiffastoptionalcheckelse", "doifundefinedelse", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifdimensionelse", "doifnumberelse", "doifnumber", "doifnotnumber", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifinstringelse", "doifassignmentelse", "docheckassignment", "tracingall", "tracingnone", "loggingall", "removetoks", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "endpar", "everyendpar", "reseteverypar", "finishpar", "empty", "null", "space", "quad", "enspace", "obeyspaces", "obeylines", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", "wait", "writestatus", "define", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "freezemeasure", "measure", "getvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "udef", "ugdef", "uedef", "uxdef", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "getdummyparameters", "dummyparameter", "directdummyparameter", "setdummyparameter", "letdummyparameter", "usedummystyleandcolor", "usedummystyleparameter", "usedummycolorparameter", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "newconstant", "setnewconstant", "newconditional", "settrue", "setfalse", "setconstant", "newmacro", "setnewmacro", "newfraction", "newsignal", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "doquintupleargument", "dosixtupleargument", "doseventupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doiffirstcharelse", "startnointerference", "stopnointerference", "twodigits", "threedigits", "strut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "struthtdp", "begstrut", "endstrut", "lineheight" },
+ ["constants"]={ "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", "zeroskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", "endoflinetoken", "outputnewlinechar", "emptytoks", "empty", "undefined", "voidbox", "emptybox", "emptyvbox", "emptyhbox", "bigskipamount", "medskipamount", "smallskipamount", "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", "etexversion", "pdftexversion", "xetexversion", "xetexrevision", "activecatcode", "bgroup", "egroup", "endline", "conditionaltrue", "conditionalfalse", "attributeunsetvalue", "uprotationangle", "rightrotationangle", "downrotationangle", "leftrotationangle", "inicatcodes", "ctxcatcodes", "texcatcodes", "notcatcodes", "txtcatcodes", "vrbcatcodes", "prtcatcodes", "nilcatcodes", "luacatcodes", "tpacatcodes", "tpbcatcodes", "xmlcatcodes", "escapecatcode", "begingroupcatcode", "endgroupcatcode", "mathshiftcatcode", "alignmentcatcode", "endoflinecatcode", "parametercatcode", "superscriptcatcode", "subscriptcatcode", "ignorecatcode", "spacecatcode", "lettercatcode", "othercatcode", "activecatcode", "commentcatcode", "invalidcatcode", "tabasciicode", "newlineasciicode", "formfeedasciicode", "endoflineasciicode", "endoffileasciicode", "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", "primeasciicode", "activemathcharcode", "activetabtoken", "activeformfeedtoken", "activeendoflinetoken", "batchmodecode", "nonstopmodecode", "scrollmodecode", "errorstopmodecode", "bottomlevelgroupcode", "simplegroupcode", "hboxgroupcode", "adjustedhboxgroupcode", "vboxgroupcode", "vtopgroupcode", "aligngroupcode", "noaligngroupcode", "outputgroupcode", "mathgroupcode", "discretionarygroupcode", "insertgroupcode", "vcentergroupcode", "mathchoicegroupcode", "semisimplegroupcode", "mathshiftgroupcode", "mathleftgroupcode", "vadjustgroupcode", "charnodecode", "hlistnodecode", "vlistnodecode", "rulenodecode", "insertnodecode", "marknodecode", "adjustnodecode", "ligaturenodecode", "discretionarynodecode", "whatsitnodecode", "mathnodecode", "gluenodecode", "kernnodecode", "penaltynodecode", "unsetnodecode", "mathsnodecode", "charifcode", "catifcode", "numifcode", "dimifcode", "oddifcode", "vmodeifcode", "hmodeifcode", "mmodeifcode", "innerifcode", "voidifcode", "hboxifcode", "vboxifcode", "xifcode", "eofifcode", "trueifcode", "falseifcode", "caseifcode", "definedifcode", "csnameifcode", "fontcharifcode", "fontslantperpoint", "fontinterwordspace", "fontinterwordstretch", "fontinterwordshrink", "fontexheight", "fontemwidth", "fontextraspace", "slantperpoint", "interwordspace", "interwordstretch", "interwordshrink", "exheight", "emwidth", "extraspace", "mathsupdisplay", "mathsupnormal", "mathsupcramped", "mathsubnormal", "mathsubcombined", "mathaxisheight", "startmode", "stopmode", "startnotmode", "stopnotmode", "startmodeset", "stopmodeset", "doifmode", "doifmodeelse", "doifnotmode", "startallmodes", "stopallmodes", "startnotallmodes", "stopnotallmodes", "doifallmodes", "doifallmodeselse", "doifnotallmodes", "startenvironment", "stopenvironment", "environment", "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", "starttext", "stoptext", "startnotext", "stopnotext", "startdocument", "stopdocument", "documentvariable", "startmodule", "stopmodule", "usemodule", "startTEXpage", "stopTEXpage", "enablemode", "disablemode", "preventmode", "pushmode", "popmode", "typescriptone", "typescripttwo", "typescriptthree", "mathsizesuffix", "mathordcode", "mathopcode", "mathbincode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctcode", "mathalphacode", "mathinnercode", "mathnothingcode", "mathlimopcode", "mathnolopcode", "mathboxcode", "mathchoicecode", "mathaccentcode", "mathradicalcode", "constantnumber", "constantnumberargument", "constantdimen", "constantdimenargument", "constantemptyargument", "continueifinputfile" },
+ ["helpers"]={ "startsetups", "stopsetups", "startxmlsetups", "stopxmlsetups", "startluasetups", "stopluasetups", "starttexsetups", "stoptexsetups", "startrawsetups", "stoprawsetups", "startlocalsetups", "stoplocalsetups", "starttexdefinition", "stoptexdefinition", "starttexcode", "stoptexcode", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", "booleanmodevalue", "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", "newlanguage", "newfamily", "newfam", "newhelp", "then", "donothing", "dontcomplain", "donetrue", "donefalse", "htdp", "unvoidbox", "vfilll", "mathbox", "mathlimop", "mathnolop", "mathnothing", "mathalpha", "currentcatcodetable", "defaultcatcodetable", "catcodetablename", "newcatcodetable", "startcatcodetable", "stopcatcodetable", "startextendcatcodetable", "stopextendcatcodetable", "pushcatcodetable", "popcatcodetable", "restorecatcodes", "setcatcodetable", "letcatcodecommand", "defcatcodecommand", "uedcatcodecommand", "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", "ruledhglue", "ruledvglue", "normalhglue", "normalvglue", "ruledpenalty", "scratchcounter", "globalscratchcounter", "scratchdimen", "globalscratchdimen", "scratchskip", "globalscratchskip", "scratchmuskip", "globalscratchmuskip", "scratchtoks", "globalscratchtoks", "scratchbox", "globalscratchbox", "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", "scratchcounterone", "scratchcountertwo", "scratchcounterthree", "scratchdimenone", "scratchdimentwo", "scratchdimenthree", "scratchskipone", "scratchskiptwo", "scratchskipthree", "scratchmuskipone", "scratchmuskiptwo", "scratchmuskipthree", "scratchtoksone", "scratchtokstwo", "scratchtoksthree", "scratchboxone", "scratchboxtwo", "scratchboxthree", "doif", "doifnot", "doifelse", "doifinset", "doifnotinset", "doifinsetelse", "doifnextcharelse", "doifnextoptionalelse", "doifnextbgroupelse", "doifnextparenthesiselse", "doiffastoptionalcheckelse", "doifundefinedelse", "doifdefinedelse", "doifundefined", "doifdefined", "doifelsevalue", "doifvalue", "doifnotvalue", "doifnothing", "doifsomething", "doifelsenothing", "doifsomethingelse", "doifvaluenothing", "doifvaluesomething", "doifelsevaluenothing", "doifdimensionelse", "doifnumberelse", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifinstringelse", "doifassignmentelse", "tracingall", "tracingnone", "loggingall", "appendtoks", "prependtoks", "appendtotoks", "prependtotoks", "to", "endgraf", "empty", "null", "space", "quad", "enspace", "obeyspaces", "obeylines", "normalspace", "executeifdefined", "singleexpandafter", "doubleexpandafter", "tripleexpandafter", "dontleavehmode", "removelastspace", "removeunwantedspaces", "wait", "writestatus", "define", "redefine", "setmeasure", "setemeasure", "setgmeasure", "setxmeasure", "definemeasure", "measure", "getvalue", "setvalue", "setevalue", "setgvalue", "setxvalue", "letvalue", "letgvalue", "resetvalue", "undefinevalue", "ignorevalue", "setuvalue", "setuevalue", "setugvalue", "setuxvalue", "globallet", "glet", "getparameters", "geteparameters", "getgparameters", "getxparameters", "forgetparameters", "copyparameters", "processcommalist", "processcommacommand", "quitcommalist", "quitprevcommalist", "processaction", "processallactions", "processfirstactioninset", "processallactionsinset", "unexpanded", "expanded", "startexpanded", "stopexpanded", "protected", "protect", "unprotect", "firstofoneargument", "firstoftwoarguments", "secondoftwoarguments", "firstofthreearguments", "secondofthreearguments", "thirdofthreearguments", "firstoffourarguments", "secondoffourarguments", "thirdoffourarguments", "fourthoffourarguments", "firstoffivearguments", "secondoffivearguments", "thirdoffivearguments", "fourthoffivearguments", "fifthoffivearguments", "firstofsixarguments", "secondofsixarguments", "thirdofsixarguments", "fourthofsixarguments", "fifthofsixarguments", "sixthofsixarguments", "firstofoneunexpanded", "gobbleoneargument", "gobbletwoarguments", "gobblethreearguments", "gobblefourarguments", "gobblefivearguments", "gobblesixarguments", "gobblesevenarguments", "gobbleeightarguments", "gobbleninearguments", "gobbletenarguments", "gobbleoneoptional", "gobbletwooptionals", "gobblethreeoptionals", "gobblefouroptionals", "gobblefiveoptionals", "dorecurse", "doloop", "exitloop", "dostepwiserecurse", "recurselevel", "recursedepth", "dofastloopcs", "newconstant", "setnewconstant", "newconditional", "settrue", "setfalse", "setconstant", "newmacro", "setnewmacro", "newfraction", "dosingleempty", "dodoubleempty", "dotripleempty", "doquadrupleempty", "doquintupleempty", "dosixtupleempty", "doseventupleempty", "dosingleargument", "dodoubleargument", "dotripleargument", "doquadrupleargument", "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "modulonumber", "dividenumber", "getfirstcharacter", "doiffirstcharelse", "startnointerference", "stopnointerference", "strut", "setstrut", "strutbox", "strutht", "strutdp", "strutwd", "begstrut", "endstrut" },
}
\ No newline at end of file
diff --git a/context/data/scite/lexers/data/scite-context-data-metafun.lua b/context/data/scite/lexers/data/scite-context-data-metafun.lua
index eac24016c..749be7663 100644
--- a/context/data/scite/lexers/data/scite-context-data-metafun.lua
+++ b/context/data/scite/lexers/data/scite-context-data-metafun.lua
@@ -1,4 +1,4 @@
return {
- ["commands"]={ "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "acosh", "asinh", "sinh", "cosh", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "smoothed", "cornered", "superellipsed", "randomized", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withlinearshading", "withcircularshading", "withfromshadecolor", "withtoshadecolor", "withshading", "shadedinto", "withcircularshade", "withlinearshade", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "withmask", "figure", "register", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "textext", "thetextext", "rawtextext", "textextoffset", "verbatim", "thelabel", "label", "autoalign", "transparent", "withtransparency", "asgroup", "infont", "set_linear_vector", "linear_shade", "define_linear_shade", "define_circular_linear_shade", "define_sampled_linear_shade", "set_circular_vector", "circular_shade", "define_circular_shade", "define_circular_linear_shade", "define_sampled_circular_shade", "space", "CRLF", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedpath", "constructedpairs", "punkedfunction", "curvedfunction", "tightfunction", "punkedpath", "curvedpath", "tightpath", "punkedpairs", "curvedpairs", "tightpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "normalfill", "normaldraw", "visualizepaths", "naturalizepaths", "drawboundary", "drawwholepath", "visualizeddraw", "visualizedfill", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions" },
+ ["commands"]={ "sqr", "log", "ln", "exp", "inv", "pow", "pi", "radian", "tand", "cotd", "sin", "cos", "tan", "cot", "atan", "asin", "acos", "invsin", "invcos", "acosh", "asinh", "sinh", "cosh", "paired", "tripled", "unitcircle", "fulldiamond", "unitdiamond", "fullsquare", "llcircle", "lrcircle", "urcircle", "ulcircle", "tcircle", "bcircle", "lcircle", "rcircle", "lltriangle", "lrtriangle", "urtriangle", "ultriangle", "smoothed", "cornered", "superellipsed", "randomized", "squeezed", "enlonged", "shortened", "punked", "curved", "unspiked", "simplified", "blownup", "stretched", "enlarged", "leftenlarged", "topenlarged", "rightenlarged", "bottomenlarged", "crossed", "laddered", "randomshifted", "interpolated", "paralleled", "cutends", "peepholed", "llenlarged", "lrenlarged", "urenlarged", "ulenlarged", "llmoved", "lrmoved", "urmoved", "ulmoved", "rightarrow", "leftarrow", "centerarrow", "boundingbox", "innerboundingbox", "outerboundingbox", "pushboundingbox", "popboundingbox", "bottomboundary", "leftboundary", "topboundary", "rightboundary", "xsized", "ysized", "xysized", "sized", "xyscaled", "intersection_point", "intersection_found", "penpoint", "bbwidth", "bbheight", "withshade", "withlinearshading", "withcircularshading", "withfromshadecolor", "withtoshadecolor", "withshading", "shadedinto", "withcircularshade", "withlinearshade", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", "graphictext", "loadfigure", "externalfigure", "withmask", "figure", "register", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "textext", "thetextext", "rawtextext", "textextoffset", "verbatim", "thelabel", "label", "transparent", "withtransparency", "asgroup", "infont", "set_linear_vector", "linear_shade", "define_linear_shade", "define_circular_linear_shade", "define_sampled_linear_shade", "set_circular_vector", "circular_shade", "define_circular_shade", "define_circular_linear_shade", "define_sampled_circular_shade", "space", "CRLF", "grayscale", "greyscale", "withgray", "withgrey", "colorpart", "readfile", "clearxy", "unitvector", "center", "epsed", "anchored", "originpath", "infinite", "break", "xstretched", "ystretched", "snapped", "pathconnectors", "function", "constructedpath", "constructedpairs", "punkedfunction", "curvedfunction", "tightfunction", "punkedpath", "curvedpath", "tightpath", "punkedpairs", "curvedpairs", "tightpairs", "evenly", "oddly", "condition", "pushcurrentpicture", "popcurrentpicture", "arrowpath", "tensecircle", "roundedsquare", "colortype", "whitecolor", "blackcolor", "normalfill", "normaldraw", "visualizepaths", "naturalizepaths", "drawboundary", "drawwholepath", "visualizeddraw", "visualizedfill", "draworigin", "drawboundingbox", "drawpath", "drawpoint", "drawpoints", "drawcontrolpoints", "drawcontrollines", "drawpointlabels", "drawlineoptions", "drawpointoptions", "drawcontroloptions", "drawlabeloptions", "draworiginoptions", "drawboundoptions", "drawpathoptions", "resetdrawoptions" },
["internals"]={ "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", "textextoffset", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", "huetransparent", "saturationtransparent", "colortransparent", "luminositytransparent" },
}
\ No newline at end of file
diff --git a/context/data/scite/lexers/scite-context-lexer-tex.lua b/context/data/scite/lexers/scite-context-lexer-tex.lua
index f59624051..1ff68750f 100644
--- a/context/data/scite/lexers/scite-context-lexer-tex.lua
+++ b/context/data/scite/lexers/scite-context-lexer-tex.lua
@@ -128,13 +128,12 @@ local checkedword = context.checkedword
local styleofword = context.styleofword
local setwordlist = context.setwordlist
local validwords = false
-local validminimum = 3
-- % language=uk
local knownpreamble = Cmt(#P("% "), function(input,i,_) -- todo : utfbomb
if i < 10 then
- validwords, validminimum = false, 3
+ validwords = false
local s, e, word = find(input,'^(.+)[\n\r]',i) -- combine with match
if word then
local interface = match(word,"interface=([a-z]+)")
@@ -142,7 +141,7 @@ local knownpreamble = Cmt(#P("% "), function(input,i,_) -- todo : utfbomb
currentcommands = commands[interface] or commands.en or { }
end
local language = match(word,"language=([a-z]+)")
- validwords, validminimum = setwordlist(language)
+ validwords = language and setwordlist(language)
end
end
return false
@@ -225,7 +224,7 @@ local p_unit = P("pt") + P("bp") + P("sp") + P("mm") + P("cm") +
--
-- local p_word = Cmt(iwordpattern, function(_,i,s)
-- if validwords then
--- return checkedword(validwords,validminimum,s,i)
+-- return checkedword(validwords,s,i)
-- else
-- return true, { "text", i }
-- end
@@ -233,7 +232,7 @@ local p_unit = P("pt") + P("bp") + P("sp") + P("mm") + P("cm") +
--
-- So we use this one instead:
-local p_word = Ct( iwordpattern / function(s) return styleofword(validwords,validminimum,s) end * Cp() ) -- the function can be inlined
+local p_word = Ct( iwordpattern / function(s) return styleofword(validwords,s) end * Cp() ) -- the function can be inlined
----- p_text = (1 - p_grouping - p_special - p_extra - backslash - space + hspace)^1
@@ -390,8 +389,7 @@ local stoplua = P("\\stop") * Cmt(luaenvironment,stopdisplaylua)
local startluacode = token("embedded", startlua)
local stopluacode = #stoplua * token("embedded", stoplua)
-local metafuncall = ( P("reusable") + P("usable") + P("unique") + P("use") + P("reuse") ) * ("MPgraphic")
- + P("uniqueMPpagegraphic")
+local metafuncall = ( P("reusable") + P("usable") + P("unique") + P("use") ) * ("MPgraphic")
local metafunenvironment = metafuncall -- ( P("use") + P("reusable") + P("unique") ) * ("MPgraphic")
+ P("MP") * ( P("code")+ P("page") + P("inclusions") + P("initializations") + P("definitions") + P("extensions") + P("graphic") )
diff --git a/context/data/scite/lexers/scite-context-lexer-txt.lua b/context/data/scite/lexers/scite-context-lexer-txt.lua
index 4c4742d54..012167aeb 100644
--- a/context/data/scite/lexers/scite-context-lexer-txt.lua
+++ b/context/data/scite/lexers/scite-context-lexer-txt.lua
@@ -13,20 +13,19 @@ local token = lexer.token
local P, S, Cmt, Cp, Ct = lpeg.P, lpeg.S, lpeg.Cmt, lpeg.Cp, lpeg.Ct
local find, match = string.find, string.match
-local textlexer = { _NAME = "txt", _FILENAME = "scite-context-lexer-txt" }
-local whitespace = lexer.WHITESPACE
-local context = lexer.context
+local textlexer = { _NAME = "txt", _FILENAME = "scite-context-lexer-txt" }
+local whitespace = lexer.WHITESPACE
+local context = lexer.context
-local space = lexer.space
-local any = lexer.any
+local space = lexer.space
+local any = lexer.any
-local wordtoken = context.patterns.wordtoken
-local wordpattern = context.patterns.wordpattern
-local checkedword = context.checkedword
-local styleofword = context.styleofword
-local setwordlist = context.setwordlist
-local validwords = false
-local validminimum = 3
+local wordtoken = context.patterns.wordtoken
+local wordpattern = context.patterns.wordpattern
+local checkedword = context.checkedword
+local styleofword = context.styleofword
+local setwordlist = context.setwordlist
+local validwords = false
-- local styleset = context.newstyleset {
-- "default",
@@ -38,12 +37,12 @@ local validminimum = 3
local p_preamble = Cmt(#(S("#!-%") * P(" ")), function(input,i,_) -- todo: utf bomb
if i == 1 then -- < 10 then
- validwords, validminimum = false, 3
+ validwords = false
local s, e, line = find(input,'^[#!%-%%](.+)[\n\r]',i)
if line then
local language = match(line,"language=([a-z]+)")
if language then
- validwords, validminimum = setwordlist(language)
+ validwords = setwordlist(language)
end
end
end
@@ -53,8 +52,17 @@ end)
local t_preamble =
token("preamble", p_preamble)
+-- local t_word =
+-- Cmt(wordpattern, function(_,i,s)
+-- if validwords then
+-- return checkedword(validwords,s,i)
+-- else
+-- return true, { "text", i }
+-- end
+-- end)
+
local t_word =
- Ct( wordpattern / function(s) return styleofword(validwords,validminimum,s) end * Cp() ) -- the function can be inlined
+ Ct( wordpattern / function(s) return styleofword(validwords,s) end * Cp() ) -- the function can be inlined
local t_text =
token("default", wordtoken^1)
diff --git a/context/data/scite/lexers/scite-context-lexer-xml.lua b/context/data/scite/lexers/scite-context-lexer-xml.lua
index 62cbb2d2c..34636127f 100644
--- a/context/data/scite/lexers/scite-context-lexer-xml.lua
+++ b/context/data/scite/lexers/scite-context-lexer-xml.lua
@@ -71,7 +71,7 @@ local checkedword = context.checkedword
local styleofword = context.styleofword
local setwordlist = context.setwordlist
local validwords = false
-local validminimum = 3
+
--
--
@@ -79,20 +79,29 @@ local validminimum = 3
local p_preamble = Cmt(#P("]*%?>%s*<%?context%-directive%s+editor%s+language%s+(..)%s+%?>")
-- if not language then
-- language = match(input,'^<%?xml[^>]*language=[\"\'](..)[\"\'][^>]*%?>',i)
-- end
if language then
- validwords, validminimum = setwordlist(language)
+ validwords = setwordlist(language)
end
end
return false
end)
+-- local p_word =
+-- Cmt(iwordpattern, function(_,i,s)
+-- if validwords then
+-- return checkedword(validwords,s,i)
+-- else
+-- return true, { "text", i } -- or default
+-- end
+-- end)
+
local p_word =
- Ct( iwordpattern / function(s) return styleofword(validwords,validminimum,s) end * Cp() ) -- the function can be inlined
+ Ct( iwordpattern / function(s) return styleofword(validwords,s) end * Cp() ) -- the function can be inlined
local p_rest =
token("default", any)
diff --git a/context/data/scite/lexers/scite-context-lexer.lua b/context/data/scite/lexers/scite-context-lexer.lua
index 1c9f2cec0..2db37e26b 100644
--- a/context/data/scite/lexers/scite-context-lexer.lua
+++ b/context/data/scite/lexers/scite-context-lexer.lua
@@ -210,11 +210,8 @@ function context.exact_match(words,word_chars,case_insensitive)
end
-- spell checking (we can only load lua files)
---
+
-- return {
--- min = 3,
--- max = 40,
--- n = 12345,
-- words = {
-- ["someword"] = "someword",
-- ["anotherword"] = "Anotherword",
@@ -223,30 +220,42 @@ end
local lists = { }
+local splitter = (Cf(Ct("") * (Cg(C((1-S(" \t\n\r"))^1 * Cc(true))) + P(1))^1,rawset) )^0
+local splitter = (Cf(Ct("") * (Cg(C(R("az","AZ","\127\255")^1) * Cc(true)) + P(1))^1,rawset) )^0
+
+local function splitwords(words)
+ return lpegmatch(splitter,words)
+end
+
function context.setwordlist(tag,limit) -- returns hash (lowercase keys and original values)
if not tag or tag == "" then
- return false, 3
- end
- local list = lists[tag]
- if not list then
- list = context.loaddefinitions("spell-" .. tag)
+ return false
+ elseif lists[tag] ~= nil then
+ return lists[tag]
+ else
+ local list = context.loaddefinitions("spell-" .. tag)
if not list or type(list) ~= "table" then
- list = { words = false, min = 3 }
+ lists[tag] = false
+ return false
+ elseif type(list.words) == "string" then
+ list = splitwords(list.words) or false
+ lists[tag] = list
+ return list
else
- list.words = list.words or false
- list.min = list.min or 3
+ list = list.words or false
+ lists[tag] = list
+ return list
end
- lists[tag] = list
end
- return list.words, list.min
end
patterns.wordtoken = R("az","AZ","\127\255")
patterns.wordpattern = patterns.wordtoken^3 -- todo: if limit and #s < limit then
-function context.checkedword(validwords,validminimum,s,i) -- ,limit
- if not validwords then -- or #s < validminimum then
- return true, { "text", i } -- { "default", i }
+function context.checkedword(validwords,s,i) -- ,limit
+ if not validwords then
+ return true, { "text", i }
+-- return true, { "default", i }
else
-- keys are lower
local word = validwords[s]
@@ -269,8 +278,8 @@ function context.checkedword(validwords,validminimum,s,i) -- ,limit
end
end
-function context.styleofword(validwords,validminimum,s) -- ,limit
- if not validwords or #s < validminimum then
+function context.styleofword(validwords,s) -- ,limit
+ if not validwords then
return "text"
else
-- keys are lower
diff --git a/context/data/scite/scite-context-data-context.properties b/context/data/scite/scite-context-data-context.properties
index c6a0213cf..37a39e1e0 100644
--- a/context/data/scite/scite-context-data-context.properties
+++ b/context/data/scite/scite-context-data-context.properties
@@ -2,87 +2,72 @@ keywordclass.context.helpers=\
startsetups stopsetups startxmlsetups stopxmlsetups \
startluasetups stopluasetups starttexsetups stoptexsetups startrawsetups \
stoprawsetups startlocalsetups stoplocalsetups starttexdefinition stoptexdefinition \
-starttexcode stoptexcode startcontextcode stopcontextcode doifsetupselse \
-doifsetups doifnotsetups setup setups texsetup \
-xmlsetup luasetup directsetup doifelsecommandhandler doifnotcommandhandler \
-doifcommandhandler newmode setmode resetmode newsystemmode \
+starttexcode stoptexcode doifsetupselse doifsetups doifnotsetups \
+setup setups texsetup xmlsetup luasetup \
+directsetup newmode setmode resetmode newsystemmode \
setsystemmode resetsystemmode pushsystemmode popsystemmode booleanmodevalue \
newcount newdimen newskip newmuskip newbox \
newtoks newread newwrite newmarks newinsert \
newattribute newif newlanguage newfamily newfam \
-newhelp then firstargumentfalse firstargumenttrue secondargumentfalse \
-secondargumenttrue thirdargumentfalse thirdargumenttrue fourthargumentfalse fourthargumenttrue \
-fifthargumentfalse fifthsargumenttrue sixthargumentfalse sixtsargumenttrue doglobal \
-dodoglobal redoglobal resetglobal donothing dontcomplain \
-forgetall donetrue donefalse htdp unvoidbox \
-hfilll vfilll mathbox mathlimop mathnolop \
-mathnothing mathalpha currentcatcodetable defaultcatcodetable catcodetablename \
-newcatcodetable startcatcodetable stopcatcodetable startextendcatcodetable stopextendcatcodetable \
-pushcatcodetable popcatcodetable restorecatcodes setcatcodetable letcatcodecommand \
-defcatcodecommand uedcatcodecommand hglue vglue hfillneg \
-vfillneg hfilllneg vfilllneg ruledhss ruledhfil \
-ruledhfill ruledhfilneg ruledhfillneg normalhfillneg ruledvss \
-ruledvfil ruledvfill ruledvfilneg ruledvfillneg normalvfillneg \
-ruledhbox ruledvbox ruledvtop ruledvcenter ruledhskip \
-ruledvskip ruledkern ruledmskip ruledmkern ruledhglue \
-ruledvglue normalhglue normalvglue ruledpenalty scratchcounter \
-globalscratchcounter scratchdimen globalscratchdimen scratchskip globalscratchskip \
-scratchmuskip globalscratchmuskip scratchtoks globalscratchtoks scratchbox \
-globalscratchbox availablehsize localhsize setlocalhsize nextbox \
-dowithnextbox dowithnextboxcs dowithnextboxcontent dowithnextboxcontentcs scratchwidth \
-scratchheight scratchdepth scratchoffset scratchdistance scratchhsize \
-scratchvsize scratchxoffset scratchyoffset scratchhoffset scratchvoffset \
-scratchxposition scratchyposition scratchtopoffset scratchbottomoffset scratchleftoffset \
-scratchrightoffset scratchcounterone scratchcountertwo scratchcounterthree scratchdimenone \
-scratchdimentwo scratchdimenthree scratchskipone scratchskiptwo scratchskipthree \
-scratchmuskipone scratchmuskiptwo scratchmuskipthree scratchtoksone scratchtokstwo \
-scratchtoksthree scratchboxone scratchboxtwo scratchboxthree scratchnx \
-scratchny scratchmx scratchmy scratchleftskip scratchrightskip \
-scratchtopskip scratchbottomskip doif doifnot doifelse \
-doifinset doifnotinset doifinsetelse doifnextcharelse doifnextoptionalelse \
-doifnextbgroupelse doifnextparenthesiselse doiffastoptionalcheckelse doifundefinedelse doifdefinedelse \
-doifundefined doifdefined doifelsevalue doifvalue doifnotvalue \
-doifnothing doifsomething doifelsenothing doifsomethingelse doifvaluenothing \
-doifvaluesomething doifelsevaluenothing doifdimensionelse doifnumberelse doifnumber \
-doifnotnumber doifcommonelse doifcommon doifnotcommon doifinstring \
-doifnotinstring doifinstringelse doifassignmentelse docheckassignment tracingall \
-tracingnone loggingall removetoks appendtoks prependtoks \
-appendtotoks prependtotoks to endgraf endpar \
-everyendpar reseteverypar finishpar empty null \
-space quad enspace obeyspaces obeylines \
-normalspace executeifdefined singleexpandafter doubleexpandafter tripleexpandafter \
-dontleavehmode removelastspace removeunwantedspaces keepunwantedspaces wait \
-writestatus define redefine setmeasure setemeasure \
-setgmeasure setxmeasure definemeasure freezemeasure measure \
-getvalue setvalue setevalue setgvalue setxvalue \
-letvalue letgvalue resetvalue undefinevalue ignorevalue \
-setuvalue setuevalue setugvalue setuxvalue globallet \
-glet udef ugdef uedef uxdef \
-getparameters geteparameters getgparameters getxparameters forgetparameters \
-copyparameters getdummyparameters dummyparameter directdummyparameter setdummyparameter \
-letdummyparameter usedummystyleandcolor usedummystyleparameter usedummycolorparameter processcommalist \
-processcommacommand quitcommalist quitprevcommalist processaction processallactions \
-processfirstactioninset processallactionsinset unexpanded expanded startexpanded \
-stopexpanded protected protect unprotect firstofoneargument \
-firstoftwoarguments secondoftwoarguments firstofthreearguments secondofthreearguments thirdofthreearguments \
-firstoffourarguments secondoffourarguments thirdoffourarguments fourthoffourarguments firstoffivearguments \
-secondoffivearguments thirdoffivearguments fourthoffivearguments fifthoffivearguments firstofsixarguments \
-secondofsixarguments thirdofsixarguments fourthofsixarguments fifthofsixarguments sixthofsixarguments \
-firstofoneunexpanded gobbleoneargument gobbletwoarguments gobblethreearguments gobblefourarguments \
-gobblefivearguments gobblesixarguments gobblesevenarguments gobbleeightarguments gobbleninearguments \
-gobbletenarguments gobbleoneoptional gobbletwooptionals gobblethreeoptionals gobblefouroptionals \
-gobblefiveoptionals dorecurse doloop exitloop dostepwiserecurse \
-recurselevel recursedepth dofastloopcs newconstant setnewconstant \
-newconditional settrue setfalse setconstant newmacro \
-setnewmacro newfraction newsignal dosingleempty dodoubleempty \
-dotripleempty doquadrupleempty doquintupleempty dosixtupleempty doseventupleempty \
-dosingleargument dodoubleargument dotripleargument doquadrupleargument doquintupleargument \
-dosixtupleargument doseventupleargument dosinglegroupempty dodoublegroupempty dotriplegroupempty \
+newhelp then donothing dontcomplain donetrue \
+donefalse htdp unvoidbox vfilll mathbox \
+mathlimop mathnolop mathnothing mathalpha currentcatcodetable \
+defaultcatcodetable catcodetablename newcatcodetable startcatcodetable stopcatcodetable \
+startextendcatcodetable stopextendcatcodetable pushcatcodetable popcatcodetable restorecatcodes \
+setcatcodetable letcatcodecommand defcatcodecommand uedcatcodecommand hglue \
+vglue hfillneg vfillneg hfilllneg vfilllneg \
+ruledhss ruledhfil ruledhfill ruledhfilneg ruledhfillneg \
+normalhfillneg ruledvss ruledvfil ruledvfill ruledvfilneg \
+ruledvfillneg normalvfillneg ruledhbox ruledvbox ruledvtop \
+ruledvcenter ruledhskip ruledvskip ruledkern ruledmskip \
+ruledmkern ruledhglue ruledvglue normalhglue normalvglue \
+ruledpenalty scratchcounter globalscratchcounter scratchdimen globalscratchdimen \
+scratchskip globalscratchskip scratchmuskip globalscratchmuskip scratchtoks \
+globalscratchtoks scratchbox globalscratchbox nextbox dowithnextbox \
+dowithnextboxcs dowithnextboxcontent dowithnextboxcontentcs scratchwidth scratchheight \
+scratchdepth scratchoffset scratchdistance scratchhsize scratchvsize \
+scratchcounterone scratchcountertwo scratchcounterthree scratchdimenone scratchdimentwo \
+scratchdimenthree scratchskipone scratchskiptwo scratchskipthree scratchmuskipone \
+scratchmuskiptwo scratchmuskipthree scratchtoksone scratchtokstwo scratchtoksthree \
+scratchboxone scratchboxtwo scratchboxthree doif doifnot \
+doifelse doifinset doifnotinset doifinsetelse doifnextcharelse \
+doifnextoptionalelse doifnextbgroupelse doifnextparenthesiselse doiffastoptionalcheckelse doifundefinedelse \
+doifdefinedelse doifundefined doifdefined doifelsevalue doifvalue \
+doifnotvalue doifnothing doifsomething doifelsenothing doifsomethingelse \
+doifvaluenothing doifvaluesomething doifelsevaluenothing doifdimensionelse doifnumberelse \
+doifcommonelse doifcommon doifnotcommon doifinstring doifnotinstring \
+doifinstringelse doifassignmentelse tracingall tracingnone loggingall \
+appendtoks prependtoks appendtotoks prependtotoks to \
+endgraf empty null space quad \
+enspace obeyspaces obeylines normalspace executeifdefined \
+singleexpandafter doubleexpandafter tripleexpandafter dontleavehmode removelastspace \
+removeunwantedspaces wait writestatus define redefine \
+setmeasure setemeasure setgmeasure setxmeasure definemeasure \
+measure getvalue setvalue setevalue setgvalue \
+setxvalue letvalue letgvalue resetvalue undefinevalue \
+ignorevalue setuvalue setuevalue setugvalue setuxvalue \
+globallet glet getparameters geteparameters getgparameters \
+getxparameters forgetparameters copyparameters processcommalist processcommacommand \
+quitcommalist quitprevcommalist processaction processallactions processfirstactioninset \
+processallactionsinset unexpanded expanded startexpanded stopexpanded \
+protected protect unprotect firstofoneargument firstoftwoarguments \
+secondoftwoarguments firstofthreearguments secondofthreearguments thirdofthreearguments firstoffourarguments \
+secondoffourarguments thirdoffourarguments fourthoffourarguments firstoffivearguments secondoffivearguments \
+thirdoffivearguments fourthoffivearguments fifthoffivearguments firstofsixarguments secondofsixarguments \
+thirdofsixarguments fourthofsixarguments fifthofsixarguments sixthofsixarguments firstofoneunexpanded \
+gobbleoneargument gobbletwoarguments gobblethreearguments gobblefourarguments gobblefivearguments \
+gobblesixarguments gobblesevenarguments gobbleeightarguments gobbleninearguments gobbletenarguments \
+gobbleoneoptional gobbletwooptionals gobblethreeoptionals gobblefouroptionals gobblefiveoptionals \
+dorecurse doloop exitloop dostepwiserecurse recurselevel \
+recursedepth dofastloopcs newconstant setnewconstant newconditional \
+settrue setfalse setconstant newmacro setnewmacro \
+newfraction dosingleempty dodoubleempty dotripleempty doquadrupleempty \
+doquintupleempty dosixtupleempty doseventupleempty dosingleargument dodoubleargument \
+dotripleargument doquadrupleargument dosinglegroupempty dodoublegroupempty dotriplegroupempty \
doquadruplegroupempty doquintuplegroupempty nopdfcompression maximumpdfcompression normalpdfcompression \
modulonumber dividenumber getfirstcharacter doiffirstcharelse startnointerference \
-stopnointerference twodigits threedigits strut setstrut \
-strutbox strutht strutdp strutwd struthtdp \
-begstrut endstrut lineheight
+stopnointerference strut setstrut strutbox strutht \
+strutdp strutwd begstrut endstrut
keywordclass.context.constants=\
zerocount minusone minustwo plusone \
@@ -91,55 +76,55 @@ plusseven pluseight plusnine plusten plussixteen \
plushundred plusthousand plustenthousand plustwentythousand medcard \
maxcard zeropoint onepoint halfapoint onebasepoint \
maxdimen scaledpoint thousandpoint points halfpoint \
-zeroskip zeromuskip onemuskip pluscxxvii pluscxxviii \
-pluscclv pluscclvi normalpagebox endoflinetoken outputnewlinechar \
-emptytoks empty undefined voidbox emptybox \
-emptyvbox emptyhbox bigskipamount medskipamount smallskipamount \
-fmtname fmtversion texengine texenginename texengineversion \
-luatexengine pdftexengine xetexengine unknownengine etexversion \
-pdftexversion xetexversion xetexrevision activecatcode bgroup \
-egroup endline conditionaltrue conditionalfalse attributeunsetvalue \
-uprotationangle rightrotationangle downrotationangle leftrotationangle inicatcodes \
-ctxcatcodes texcatcodes notcatcodes txtcatcodes vrbcatcodes \
-prtcatcodes nilcatcodes luacatcodes tpacatcodes tpbcatcodes \
-xmlcatcodes escapecatcode begingroupcatcode endgroupcatcode mathshiftcatcode \
-alignmentcatcode endoflinecatcode parametercatcode superscriptcatcode subscriptcatcode \
-ignorecatcode spacecatcode lettercatcode othercatcode activecatcode \
-commentcatcode invalidcatcode tabasciicode newlineasciicode formfeedasciicode \
-endoflineasciicode endoffileasciicode spaceasciicode hashasciicode dollarasciicode \
-commentasciicode ampersandasciicode colonasciicode backslashasciicode circumflexasciicode \
-underscoreasciicode leftbraceasciicode barasciicode rightbraceasciicode tildeasciicode \
-delasciicode lessthanasciicode morethanasciicode doublecommentsignal atsignasciicode \
-exclamationmarkasciicode questionmarkasciicode doublequoteasciicode singlequoteasciicode forwardslashasciicode \
-primeasciicode activemathcharcode activetabtoken activeformfeedtoken activeendoflinetoken \
-batchmodecode nonstopmodecode scrollmodecode errorstopmodecode bottomlevelgroupcode \
-simplegroupcode hboxgroupcode adjustedhboxgroupcode vboxgroupcode vtopgroupcode \
-aligngroupcode noaligngroupcode outputgroupcode mathgroupcode discretionarygroupcode \
-insertgroupcode vcentergroupcode mathchoicegroupcode semisimplegroupcode mathshiftgroupcode \
-mathleftgroupcode vadjustgroupcode charnodecode hlistnodecode vlistnodecode \
-rulenodecode insertnodecode marknodecode adjustnodecode ligaturenodecode \
-discretionarynodecode whatsitnodecode mathnodecode gluenodecode kernnodecode \
-penaltynodecode unsetnodecode mathsnodecode charifcode catifcode \
-numifcode dimifcode oddifcode vmodeifcode hmodeifcode \
-mmodeifcode innerifcode voidifcode hboxifcode vboxifcode \
-xifcode eofifcode trueifcode falseifcode caseifcode \
-definedifcode csnameifcode fontcharifcode fontslantperpoint fontinterwordspace \
-fontinterwordstretch fontinterwordshrink fontexheight fontemwidth fontextraspace \
-slantperpoint interwordspace interwordstretch interwordshrink exheight \
-emwidth extraspace mathsupdisplay mathsupnormal mathsupcramped \
-mathsubnormal mathsubcombined mathaxisheight startmode stopmode \
-startnotmode stopnotmode startmodeset stopmodeset doifmode \
-doifmodeelse doifnotmode startallmodes stopallmodes startnotallmodes \
-stopnotallmodes doifallmodes doifallmodeselse doifnotallmodes startenvironment \
-stopenvironment environment startcomponent stopcomponent component \
-startproduct stopproduct product startproject stopproject \
-project starttext stoptext startnotext stopnotext \
-startdocument stopdocument documentvariable startmodule stopmodule \
-usemodule startTEXpage stopTEXpage enablemode disablemode \
-preventmode pushmode popmode typescriptone typescripttwo \
-typescriptthree mathsizesuffix mathordcode mathopcode mathbincode \
-mathrelcode mathopencode mathclosecode mathpunctcode mathalphacode \
-mathinnercode mathnothingcode mathlimopcode mathnolopcode mathboxcode \
-mathchoicecode mathaccentcode mathradicalcode constantnumber constantnumberargument \
-constantdimen constantdimenargument constantemptyargument continueifinputfile
+zeroskip pluscxxvii pluscxxviii pluscclv pluscclvi \
+normalpagebox endoflinetoken outputnewlinechar emptytoks empty \
+undefined voidbox emptybox emptyvbox emptyhbox \
+bigskipamount medskipamount smallskipamount fmtname fmtversion \
+texengine texenginename texengineversion luatexengine pdftexengine \
+xetexengine unknownengine etexversion pdftexversion xetexversion \
+xetexrevision activecatcode bgroup egroup endline \
+conditionaltrue conditionalfalse attributeunsetvalue uprotationangle rightrotationangle \
+downrotationangle leftrotationangle inicatcodes ctxcatcodes texcatcodes \
+notcatcodes txtcatcodes vrbcatcodes prtcatcodes nilcatcodes \
+luacatcodes tpacatcodes tpbcatcodes xmlcatcodes escapecatcode \
+begingroupcatcode endgroupcatcode mathshiftcatcode alignmentcatcode endoflinecatcode \
+parametercatcode superscriptcatcode subscriptcatcode ignorecatcode spacecatcode \
+lettercatcode othercatcode activecatcode commentcatcode invalidcatcode \
+tabasciicode newlineasciicode formfeedasciicode endoflineasciicode endoffileasciicode \
+spaceasciicode hashasciicode dollarasciicode commentasciicode ampersandasciicode \
+colonasciicode backslashasciicode circumflexasciicode underscoreasciicode leftbraceasciicode \
+barasciicode rightbraceasciicode tildeasciicode delasciicode lessthanasciicode \
+morethanasciicode doublecommentsignal atsignasciicode exclamationmarkasciicode questionmarkasciicode \
+doublequoteasciicode singlequoteasciicode forwardslashasciicode primeasciicode activemathcharcode \
+activetabtoken activeformfeedtoken activeendoflinetoken batchmodecode nonstopmodecode \
+scrollmodecode errorstopmodecode bottomlevelgroupcode simplegroupcode hboxgroupcode \
+adjustedhboxgroupcode vboxgroupcode vtopgroupcode aligngroupcode noaligngroupcode \
+outputgroupcode mathgroupcode discretionarygroupcode insertgroupcode vcentergroupcode \
+mathchoicegroupcode semisimplegroupcode mathshiftgroupcode mathleftgroupcode vadjustgroupcode \
+charnodecode hlistnodecode vlistnodecode rulenodecode insertnodecode \
+marknodecode adjustnodecode ligaturenodecode discretionarynodecode whatsitnodecode \
+mathnodecode gluenodecode kernnodecode penaltynodecode unsetnodecode \
+mathsnodecode charifcode catifcode numifcode dimifcode \
+oddifcode vmodeifcode hmodeifcode mmodeifcode innerifcode \
+voidifcode hboxifcode vboxifcode xifcode eofifcode \
+trueifcode falseifcode caseifcode definedifcode csnameifcode \
+fontcharifcode fontslantperpoint fontinterwordspace fontinterwordstretch fontinterwordshrink \
+fontexheight fontemwidth fontextraspace slantperpoint interwordspace \
+interwordstretch interwordshrink exheight emwidth extraspace \
+mathsupdisplay mathsupnormal mathsupcramped mathsubnormal mathsubcombined \
+mathaxisheight startmode stopmode startnotmode stopnotmode \
+startmodeset stopmodeset doifmode doifmodeelse doifnotmode \
+startallmodes stopallmodes startnotallmodes stopnotallmodes doifallmodes \
+doifallmodeselse doifnotallmodes startenvironment stopenvironment environment \
+startcomponent stopcomponent component startproduct stopproduct \
+product startproject stopproject project starttext \
+stoptext startnotext stopnotext startdocument stopdocument \
+documentvariable startmodule stopmodule usemodule startTEXpage \
+stopTEXpage enablemode disablemode preventmode pushmode \
+popmode typescriptone typescripttwo typescriptthree mathsizesuffix \
+mathordcode mathopcode mathbincode mathrelcode mathopencode \
+mathclosecode mathpunctcode mathalphacode mathinnercode mathnothingcode \
+mathlimopcode mathnolopcode mathboxcode mathchoicecode mathaccentcode \
+mathradicalcode constantnumber constantnumberargument constantdimen constantdimenargument \
+constantemptyargument continueifinputfile
diff --git a/context/data/scite/scite-context-data-metafun.properties b/context/data/scite/scite-context-data-metafun.properties
index 099f8119b..e0413b2dd 100644
--- a/context/data/scite/scite-context-data-metafun.properties
+++ b/context/data/scite/scite-context-data-metafun.properties
@@ -33,21 +33,21 @@ grayed greyed onlayer along graphictext \
loadfigure externalfigure withmask figure register \
bitmapimage colordecimals ddecimal dddecimal ddddecimal \
textext thetextext rawtextext textextoffset verbatim \
-thelabel label autoalign transparent withtransparency \
-asgroup infont set_linear_vector linear_shade define_linear_shade \
-define_circular_linear_shade define_sampled_linear_shade set_circular_vector circular_shade define_circular_shade \
-define_circular_linear_shade define_sampled_circular_shade space CRLF grayscale \
-greyscale withgray withgrey colorpart readfile \
-clearxy unitvector center epsed anchored \
-originpath infinite break xstretched ystretched \
-snapped pathconnectors function constructedpath constructedpairs \
-punkedfunction curvedfunction tightfunction punkedpath curvedpath \
-tightpath punkedpairs curvedpairs tightpairs evenly \
-oddly condition pushcurrentpicture popcurrentpicture arrowpath \
-tensecircle roundedsquare colortype whitecolor blackcolor \
-normalfill normaldraw visualizepaths naturalizepaths drawboundary \
-drawwholepath visualizeddraw visualizedfill draworigin drawboundingbox \
-drawpath drawpoint drawpoints drawcontrolpoints drawcontrollines \
-drawpointlabels drawlineoptions drawpointoptions drawcontroloptions drawlabeloptions \
-draworiginoptions drawboundoptions drawpathoptions resetdrawoptions
+thelabel label transparent withtransparency asgroup \
+infont set_linear_vector linear_shade define_linear_shade define_circular_linear_shade \
+define_sampled_linear_shade set_circular_vector circular_shade define_circular_shade define_circular_linear_shade \
+define_sampled_circular_shade space CRLF grayscale greyscale \
+withgray withgrey colorpart readfile clearxy \
+unitvector center epsed anchored originpath \
+infinite break xstretched ystretched snapped \
+pathconnectors function constructedpath constructedpairs punkedfunction \
+curvedfunction tightfunction punkedpath curvedpath tightpath \
+punkedpairs curvedpairs tightpairs evenly oddly \
+condition pushcurrentpicture popcurrentpicture arrowpath tensecircle \
+roundedsquare colortype whitecolor blackcolor normalfill \
+normaldraw visualizepaths naturalizepaths drawboundary drawwholepath \
+visualizeddraw visualizedfill draworigin drawboundingbox drawpath \
+drawpoint drawpoints drawcontrolpoints drawcontrollines drawpointlabels \
+drawlineoptions drawpointoptions drawcontroloptions drawlabeloptions draworiginoptions \
+drawboundoptions drawpathoptions resetdrawoptions
diff --git a/context/data/scite/scite-context-readme.pdf b/context/data/scite/scite-context-readme.pdf
index 5d5113528..32c9628b6 100644
Binary files a/context/data/scite/scite-context-readme.pdf and b/context/data/scite/scite-context-readme.pdf differ
diff --git a/context/data/scite/scite-context-readme.tex b/context/data/scite/scite-context-readme.tex
index f687c4fe1..6221d7cde 100644
--- a/context/data/scite/scite-context-readme.tex
+++ b/context/data/scite/scite-context-readme.tex
@@ -444,7 +444,7 @@ But probably better is to use the next directive just below the
usual \XML\ marker line:
\starttyping
-
+
\stoptyping
\subject{Interface selection}
diff --git a/context/data/scite/scite-context.properties b/context/data/scite/scite-context.properties
index 739967d3c..1a4f0f5e8 100644
--- a/context/data/scite/scite-context.properties
+++ b/context/data/scite/scite-context.properties
@@ -56,7 +56,7 @@ textwrapper.length=68
file.patterns.tex=
file.patterns.latex=
-file.patterns.context=*.tex;*.mkii;*.mkiv;*.mkvi;*.mkix;*.mkxi;
+file.patterns.context=*.tex;*.mkii;*.mkiv;*.mkvi;
open.suffix.$(file.patterns.context)=.tex
@@ -73,7 +73,7 @@ lexer.$(file.patterns.example)=xml
# Lua : patterns
-file.patterns.lua=*.lua;*.luc;*.cld;*.tuc;*.luj;*.lum;*.tma;*.lfg;*.luv;*.lui
+file.patterns.lua=*.lua;*.luc;*.cld;*.tuc;*.luj;*.lum;*.tma;*.lfg
open.suffix.$(file.patterns.lua)=.lua
@@ -140,8 +140,6 @@ if PLAT_GTK
# Commands: help info, e:\websites\www.pragma-ade.com\showcase.pdf / todo: manuals
command.help.$(file.patterns.context)=$(name.context.texshow) $(CurrentWord)
-command.help.$(file.patterns.context)=mtxrun --gethelp --url="http://localhost:31415/mtx-server-ctx-help.lua?command=%command%" --command="$(CurrentWord)"
-command.help.$(file.patterns.context)=mtxrun --gethelp --url="http://www.contextgarden.net/Command/%command%" --command="$(CurrentWord)"
command.help.$(file.patterns.example)=
command.help.$(file.patterns.metafun)=
@@ -171,9 +169,9 @@ command.compile.$(file.patterns.example)=$(name.example.xmlcheck) $(FileNameExt)
command.compile.*.fo=$(name.example.xmlcheck) $(FileNameExt)
command.build.$(file.patterns.context)=$(name.context.run) $(FileNameExt)
-command.build.$(file.patterns.metafun)=$(name.context.mtxrun) --script context $(name.flag.pdfopen) $(FileNameExt)
-command.build.$(file.patterns.example)=$(name.context.run) --forcexml $(FileNameExt)
-command.build.*.fo=$(name.context.run) $(name.flag.pdfopen) --forcexml --use=foxet $(FileNameExt)
+command.build.$(file.patterns.metafun)=$(name.metafun.mptopdf) $(FileNameExt)
+command.build.$(file.patterns.example)=$(name.context.run) --xml $(FileNameExt)
+command.build.*.fo=$(name.context.run) $(name.flag.pdfopen) --xml --use=foxet $(FileNameExt)
command.build.subsystem.$(file.patterns.context)=1
command.build.subsystem.$(file.patterns.metafun)=1
@@ -562,7 +560,7 @@ filter.metafun=MetaFun|$(file.patterns.metafun)|
lexer.$(file.patterns.metafun)=metapost
command.compile.$(file.patterns.metafun)=
-command.build.$(file.patterns.metafun)=$(name.context.mtxrun) --script context $(name.flag.pdfopen) $(FileNameExt)
+command.build.$(file.patterns.metafun)=context $(FileNameExt)
command.go.$(file.patterns.metafun)=gv $(FileName).1
command.0.$(file.patterns.metafun)=
@@ -666,5 +664,3 @@ fold.margin.colour=#CCCCCC
# testing
#~ cache.layout=
-
-find.command=mtxrun --script grep "$(find.what)" "$(find.files)"
diff --git a/metapost/context/base/metafun.mpiv b/metapost/context/base/metafun.mpiv
index 8247c121f..d600764a3 100644
--- a/metapost/context/base/metafun.mpiv
+++ b/metapost/context/base/metafun.mpiv
@@ -11,9 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D First we input John Hobby's metapost plain file. However, because we want to
-%D prevent dependency problems and in the end even may use a patched version,
-%D we prefer to use a copy.
+%D First we input John Hobby's metapost plain file. However,
+%D because we want to prevent dependency problems and in the
+%D end even may use a patched version, we prefer to use a
+%D copy.
input "mp-base.mpiv" ;
input "mp-tool.mpiv" ;
diff --git a/metapost/context/base/mp-abck.mpiv b/metapost/context/base/mp-abck.mpiv
index abd7d8848..02fab0337 100644
--- a/metapost/context/base/mp-abck.mpiv
+++ b/metapost/context/base/mp-abck.mpiv
@@ -5,7 +5,7 @@
%D subtitle=anchored background macros,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
diff --git a/metapost/context/base/mp-apos.mpiv b/metapost/context/base/mp-apos.mpiv
index 7b7737754..f92efc5fd 100644
--- a/metapost/context/base/mp-apos.mpiv
+++ b/metapost/context/base/mp-apos.mpiv
@@ -5,7 +5,7 @@
%D subtitle=anchored background macros,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
diff --git a/metapost/context/base/mp-asnc.mpiv b/metapost/context/base/mp-asnc.mpiv
index 2626e4d58..dfd88317c 100644
--- a/metapost/context/base/mp-asnc.mpiv
+++ b/metapost/context/base/mp-asnc.mpiv
@@ -5,7 +5,7 @@
%D subtitle=anchored background macros,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
diff --git a/metapost/context/base/mp-butt.mpiv b/metapost/context/base/mp-butt.mpiv
index 6f5b90a7e..df7e9e4fd 100644
--- a/metapost/context/base/mp-butt.mpiv
+++ b/metapost/context/base/mp-butt.mpiv
@@ -5,7 +5,7 @@
%D subtitle=buttons,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-char.mpiv b/metapost/context/base/mp-char.mpiv
index f604accd8..c293b7284 100644
--- a/metapost/context/base/mp-char.mpiv
+++ b/metapost/context/base/mp-char.mpiv
@@ -5,7 +5,7 @@
%D subtitle=charts,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-chem.mpiv b/metapost/context/base/mp-chem.mpiv
index 2b2d8e5bf..cb595f2c6 100644
--- a/metapost/context/base/mp-chem.mpiv
+++ b/metapost/context/base/mp-chem.mpiv
@@ -3,15 +3,15 @@
%D version=2009.05.13,
%D title=\CONTEXT\ \METAPOST\ graphics,
%D subtitle=chemicals,
-%D author=Hans Hagen \& Alan Braslau",
+%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright=\PRAGMA]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
%C details.
-%D This module is incomplete and experimental.
+%D This module in incomplete and experimental.
% either consistent setting or not
@@ -20,7 +20,7 @@ if known context_chem : endinput ; fi ;
boolean context_chem ; context_chem := true ;
numeric
- chem_width, chem_radical_min, chem_radical_max, chem_text_min, chem_text_max, chem_circle_radius,
+ chem_width, chem_radical_min, chem_radical_max, chem_text_max, chem_circle_radius,
chem_rotation, chem_adjacent, chem_stack, chem_substituent, chem_direction, chem_setting_scale,
chem_setting_offset, chem_text_offset, chem_picture_offset, chem_center_offset, chem_substituent_offset,
chem_setting_l, chem_setting_r, chem_setting_t, chem_setting_b ;
@@ -30,9 +30,6 @@ boolean
chem_setting_fixedwidth, chem_setting_fixedheight,
chem_doing_pb, chem_text_trace ;
-color
- chem_axis_color ;
-
path
chem_setting_bbox ;
@@ -41,26 +38,24 @@ pair
chem_adjacent_p, chem_substituent_p, chem_direction_p, chem_move_p ;
numeric
- chem_width[], chem_angle[], chem_dbl_offset[], chem_initialmov[] ;
+ chem_width[], chem_angle[], chem_start[], chem_initialrot[], chem_initialmov[] ;
pair
chem_stack_d[],
chem_b_zero[], chem_n_zero[],
- chem_r_max[],
+ chem_r_max[], chem_r_min[],
chem_r_zero[], chem_mr_zero[], chem_pr_zero[], chem_crz_zero[],
chem_rt_zero[], chem_rtt_zero[], chem_rbt_zero[],
- chem_zbt_zero[], chem_ztt_zero[],
chem_mid_zero[] ;
path
chem_b_path[], chem_bx_path[], chem_eb_path[], chem_sr_path[], chem_br_path[],
chem_sb_path[], chem_msb_path[], chem_psb_path[],
chem_s_path[], chem_ss_path[], chem_mss_path[], chem_pss_path[],
- chem_e_path[], chem_bb_path[], chem_oe_path[],
+ chem_e_path[], chem_sd_path[], chem_bb_path[], chem_oe_path[],
chem_bd_path[], chem_bw_path[],
chem_ddt_path[], chem_ddb_path[], chem_ldt_path[], chem_ldb_path[], chem_rdt_path[], chem_rdb_path[],
chem_dbl_path[], chem_dbr_path[],
- chem_tbl_path[], chem_tbr_path[],
chem_ad_path[], chem_au_path[],
chem_r_path[], chem_rl_path[], chem_rr_path[],
chem_rb_path[], chem_prb_path[], chem_mrb_path[],
@@ -71,23 +66,23 @@ path
chem_midt_path[], chem_midb_path[], chem_midst_path[], chem_midsb_path[] ;
chem_setting_scale := 1 ;
-chem_base_width := 40pt ; % Should this rather follow the font size?
-chem_text_offset := 3pt ; % ?
+chem_base_width := 40pt ;
+chem_text_offset := 3pt ;
chem_center_offset := 6pt ;
-chem_picture_offset := 10pt ; % Should this follow chem_base_width (thus the font size)?
-chem_substituent_offset := 10pt ; % Should this follow chem_base_width (thus the font size)?
+chem_picture_offset := 10pt ;
+chem_substituent_offset := 10pt ;
chem_radical_min := 1.25 ;
chem_radical_max := 1.50 ;
chem_text_min := 0.75 ;
-chem_text_max := 1.25 ;
+chem_text_max := 1.75 ;
chem_circle_radius := 0.80 ;
chem_circle_radius := 1.10 ;
-chem_rotation := 0 ;
+chem_rotation := 1 ;
chem_adjacent := 0 ;
chem_substituent := 0 ;
chem_direction := 0 ;
chem_stack_n := 0 ;
-chem_doing_pb := false ;
+chem_doing_pb := false ;
chem_shift := origin ;
chem_dot_factor := 4 ;
chem_text_trace := false ;
@@ -95,10 +90,8 @@ chem_bd_n := 4 ;
chem_bw_n := 4 ;
chem_bd_angle := 4 ;
chem_bb_angle := 4 ;
-chem_axis_color := blue ; % TODO: add "axiscolor=" option in lua...
vardef chem_start_structure(expr n, l, r, t, b, scale, axis, fixedwidth, fixedheight, offset) =
- % note that "n" is not used...
chem_setting_axis := axis ;
chem_setting_l := l * scale ;
chem_setting_r := r * scale ;
@@ -111,7 +104,7 @@ vardef chem_start_structure(expr n, l, r, t, b, scale, axis, fixedwidth, fixedhe
chem_setting_scale := scale ;
chem_init_all ;
fi ;
- chem_rotation := 0 ;
+ chem_rotation := 1 ;
chem_adjacent := 0 ;
chem_substituent := 0 ;
chem_direction := 0 ;
@@ -134,18 +127,17 @@ def chem_stop_structure =
chem_setting_bbox :=
(-chem_setting_l,-chem_setting_b) -- ( chem_setting_r,-chem_setting_b) --
( chem_setting_r, chem_setting_t) -- (-chem_setting_l, chem_setting_t) -- cycle ;
- if chem_setting_axis : % put it behind the picture
- picture chem_picture ; chem_picture := currentpicture ; currentpicture := nullpicture ;
+ % maybe put it behind the picture
+ if chem_setting_axis :
save stp ; stp := chem_base_width/ 2 * chem_setting_scale ;
- save siz ; siz := stp/5 ;
- draw (-chem_setting_l,0) -- (chem_setting_r,0) withcolor chem_axis_color ;
- draw (0,-chem_setting_b) -- (0,chem_setting_t) withcolor chem_axis_color ;
- for i = 0 step stp until chem_setting_r : draw (i,-siz) -- (i,siz) withcolor chem_axis_color ; endfor ;
- for i = 0 step -stp until -chem_setting_l : draw (i,-siz) -- (i,siz) withcolor chem_axis_color ; endfor ;
- for i = 0 step stp until chem_setting_t : draw (-siz,i) -- (siz,i) withcolor chem_axis_color ; endfor ;
- for i = 0 step -stp until -chem_setting_b : draw (-siz,i) -- (siz,i) withcolor chem_axis_color ; endfor ;
- % frame=on: draw chem_setting_bbox withcolor chem_axis_color ;
- addto currentpicture also chem_picture ;
+ save siz ; siz := chem_base_width/10 * chem_setting_scale ;
+ draw (-chem_setting_l,0) -- (chem_setting_r,0) withcolor blue ;
+ draw (0,-chem_setting_b) -- (0,chem_setting_t) withcolor blue ;
+ for i = 0 step stp until chem_setting_r : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ;
+ for i = 0 step -stp until -chem_setting_l : draw (i,-siz) -- (i,siz) withcolor blue ; endfor ;
+ for i = 0 step stp until chem_setting_t : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ;
+ for i = 0 step -stp until -chem_setting_b : draw (-siz,i) -- (siz,i) withcolor blue ; endfor ;
+ draw chem_setting_bbox withcolor blue ;
fi ;
setbounds currentpicture to chem_setting_bbox ;
enddef ;
@@ -154,8 +146,8 @@ def chem_start_component = enddef ;
def chem_stop_component = enddef ;
def chem_pb =
-% draw boundingbox currentpicture withpen pencircle scaled 1mm withcolor chem_axis_color ;
-% draw origin withpen pencircle scaled 2mm withcolor chem_axis_color ;
+% draw boundingbox currentpicture withpen pencircle scaled 1mm withcolor blue ;
+% draw origin withpen pencircle scaled 2mm withcolor blue ;
chem_doing_pb := true ;
enddef ;
@@ -182,7 +174,6 @@ vardef chem_do (expr p) =
fi
enddef ;
-% f_rom, t_o, r_ule, c_olor
vardef chem_b (expr n, f, t, r, c) =
chem_draw (n, chem_b_path[n], f, t, r, c) ;
enddef ;
@@ -230,8 +221,13 @@ vardef chem_eb (expr n, f, t, r, c) =
enddef ;
vardef chem_db (expr n, f, t, r, c) =
- chem_draw (n, chem_dbl_path [n], f, t, r, c) ;
- chem_draw (n, chem_dbr_path [n], f, t, r, c) ;
+ if n = 1 :
+ chem_draw (n, chem_msb_path [n], f, t, r, c) ;
+ chem_draw (n, chem_psb_path [n], f, t, r, c) ;
+ else :
+ chem_draw (n, chem_dbl_path [n], f, t, r, c) ;
+ chem_draw (n, chem_dbr_path [n], f, t, r, c) ;
+ fi ;
enddef ;
vardef chem_er (expr n, f, t, r, c) =
@@ -317,7 +313,7 @@ vardef chem_psr (expr n, f, t, r, c) =
enddef ;
vardef chem_c (expr n, f, t, r, c) =
- chem_draw (n, chem_c_path[n], f, f, r, c)
+ chem_draw (n, chem_c_path[n], f, t, r, c)
enddef ;
vardef chem_cc (expr n, f, t, r, c) =
@@ -325,7 +321,7 @@ vardef chem_cc (expr n, f, t, r, c) =
enddef ;
vardef chem_cd (expr n, f, t, r, c) =
- chem_dashed_connected (n, chem_c_path[n], f, f, r, c)
+ chem_dashed_connected (n, chem_c_path[n], f, t, r, c)
enddef ;
vardef chem_ccd (expr n, f, t, r, c) =
@@ -345,13 +341,13 @@ vardef chem_rbn (expr n, i, t) =
enddef ;
vardef chem_tb (expr n, f, t, r, c) = % one
- chem_draw (n, chem_tbl_path [n], f, t, r, c) ;
- chem_draw (n, chem_sb_path [n], f, t, r, c) ;
- chem_draw (n, chem_tbr_path [n], f, t, r, c) ;
+ chem_draw (n, chem_msb_path[n], f, t, r, c) ;
+ chem_draw (n, chem_sb_path [n], f, t, r, c) ;
+ chem_draw (n, chem_psb_path[n], f, t, r, c) ;
enddef ;
vardef chem_ep (expr n, f, t, r, c) = % one
- chem_draw (n, (subpath (.25,.75) of chem_e_path[n]), f, t, r, c) ;
+ chem_draw (n, chem_e_path[n], f, t, r, c) ;
enddef ;
vardef chem_es (expr n, f, t, r, c) = % one
@@ -359,8 +355,8 @@ vardef chem_es (expr n, f, t, r, c) = % one
enddef ;
vardef chem_ed (expr n, f, t, r, c) = % one
- chem_draw_dot (n, point .25 of chem_e_path[n], f, t, r, c) ;
- chem_draw_dot (n, point .75 of chem_e_path[n], f, t, r, c) ;
+ chem_draw_dot (n, point 0 of chem_e_path[n], f, t, r, c) ;
+ chem_draw_dot (n, point 1 of chem_e_path[n], f, t, r, c) ;
enddef ;
vardef chem_et (expr n, f, t, r, c) = % one
@@ -377,11 +373,11 @@ enddef ;
vardef chem_rdd (expr n, f, t, r, c) = % one
chem_draw (n, chem_ldt_path[n], f, t, r, c) ;
chem_draw (n, chem_ldb_path[n], f, t, r, c) ;
- chem_draw (n, chem_sb_path [n], f, t, r, c) ;
+ chem_draw (n, chem_psb_path[n], f, t, r, c) ;
enddef ;
vardef chem_ldd (expr n, f, t, r, c) = % one
- chem_draw (n, chem_sb_path [n], f, t, r, c) ;
+ chem_draw (n, chem_msb_path[n], f, t, r, c) ;
chem_draw (n, chem_rdt_path[n], f, t, r, c) ;
chem_draw (n, chem_rdb_path[n], f, t, r, c) ;
enddef ;
@@ -392,11 +388,10 @@ vardef chem_hb (expr n, f, t, r, c) = % one
chem_draw_dot (n, point 1 of chem_sb_path[n], f, t, r, c) ;
enddef ;
-vardef chem_bb (expr n, f, t, r, c) = % one and front
+vardef chem_bb (expr n, f, t, r, c) = % one
if n < 0 :
- if ((f = 1) and (t = -n)) : % ignore all but "BB"
- chem_fill (n, chem_bb_path[n], 1, 1, r, c) ;
- fi
+ chem_fill (n, chem_bb_path[n], 1, 1, r, c) ;
+ chem_b (n, f, t, r, c) ;
else :
chem_fill (n, chem_bb_path[n], f, t, r, c) ;
fi ;
@@ -433,9 +428,7 @@ vardef chem_z@#(expr n, p) (text t) =
enddef ;
vardef chem_cz@#(expr n, p) (text t) =
- if p = 0 :
- chem_text@#(t, chem_do(origin)) ;
- elseif n = 1 :
+ if n = 1 :
chem_c_text(t, chem_do(chem_crz_zero[n] rotated chem_ang(n,p))) ;
else :
chem_text@#(t, chem_do(chem_b_zero[n] rotated chem_ang(n,p))) ;
@@ -446,37 +439,12 @@ vardef chem_midz@#(expr n, p) (text t) =
chem_text@#(t, chem_do(chem_mid_zero[n] rotated chem_ang(n,p))) ;
enddef ;
-string mfun_auto_align[] ;
-mfun_auto_align[0] := "rt" ;
-mfun_auto_align[1] := "urt" ;
-mfun_auto_align[2] := "top" ;
-mfun_auto_align[3] := "ulft" ;
-mfun_auto_align[4] := "lft" ;
-mfun_auto_align[5] := "llft" ;
-mfun_auto_align[6] := "bot" ;
-mfun_auto_align[7] := "lrt" ;
-mfun_auto_align[8] := "rt" ;
-
-def autoalign(expr n) =
- scantokens mfun_auto_align[round((n mod 360)/45)]
-enddef ;
-
-% draw textext.autoalign(60) ("\strut oeps 1") ;
-% draw textext.autoalign(160)("\strut oeps 2") ;
-% draw textext.autoalign(260)("\strut oeps 3") ;
-% draw textext.autoalign(360)("\strut oeps 4") ;
-
-
vardef chem_rz@#(expr n, p) (text t) =
if n < 0 :
% quite special
chem_text@#(t, chem_do(chem_r_zero[n] shifted (chem_b_zero[n] rotated chem_ang(n,p)))) ;
else :
- if (length(str @#)>0) and (str @# = "auto") :
- chem_text.autoalign(chem_ang(n,p-.5)) (t, chem_do(chem_r_zero[n] rotated chem_ang(n,p))) ;
- else :
- chem_text@#(t, chem_do(chem_r_zero[n] rotated chem_ang(n,p))) ;
- fi
+ chem_text@#(t, chem_do(chem_r_zero[n] rotated chem_ang(n,p))) ;
fi ;
enddef ;
@@ -515,27 +483,35 @@ vardef chem_rbt@#(expr n, p) (text t) =
enddef ;
vardef chem_zt@#(expr n, p) (text t) =
- chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ;
+ if n = 1 :
+ chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ;
+ else :
+ chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ;
+ fi ;
enddef ;
vardef chem_zn@#(expr n, p) (text t) =
- chem_zt@#(n, p, t) ;
+ if n = 1 :
+ chem_text@#(t, chem_do(chem_rt_zero[n] rotated chem_ang(n,p))) ;
+ else :
+ chem_text@#(t, chem_do(chem_n_zero[n] rotated chem_ang(n,p))) ;
+ fi ;
enddef ;
vardef chem_zbt@#(expr n, p) (text t) =
- chem_text@#(t, chem_do(chem_zbt_zero[n] rotated chem_ang(n,p))) ;
+ chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ;
enddef ;
vardef chem_zbn@#(expr n, p) (text t) =
- chem_zbt@#(n, p, t) ;
+ chem_text@#(t, chem_do(chem_rtt_zero[n] rotated chem_ang(n,p))) ;
enddef ;
vardef chem_ztt@#(expr n, p) (text t) =
- chem_text@#(t, chem_do(chem_ztt_zero[n] rotated chem_ang(n,p))) ;
+ chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ;
enddef ;
vardef chem_ztn@#(expr n, p) (text t) =
- chem_ztt@#(n, p, t) ;
+ chem_text@#(t, chem_do(chem_rbt_zero[n] rotated chem_ang(n,p))) ;
enddef ;
vardef chem_symbol(expr t) =
@@ -569,13 +545,11 @@ vardef chem_c_text(expr txt, z) = % adapted copy of thelabel@
enddef ;
vardef chem_ang (expr n, d) =
- ((1 - d)*chem_angle[n] + if (n<0): -90 else: chem_rotation fi) % no ;
+ ((-1 * (d-1) * chem_angle[n]) + (-chem_rotation+1) * 90 + chem_start[n]) % no ;
enddef ;
vardef chem_rot (expr n, d) =
- if (d <> 0) :
- chem_rotation := chem_rotation + 180/(if (d=1): 8 else: abs(d) fi) ;
- fi
+ chem_rotation := d ;
enddef ;
vardef chem_adj (expr n, d) =
@@ -588,7 +562,7 @@ enddef ;
vardef chem_dir (expr n, d) =
if n = 1 :
- chem_direction_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d))/cosd(chem_angle[n])) ;
+ chem_direction_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+1))) ;
currentpicture := currentpicture shifted chem_direction_p ;
chem_shift := chem_shift + chem_direction_p ;
fi ;
@@ -599,21 +573,23 @@ vardef chem_mov (expr n, d) =
currentpicture := currentpicture shifted - chem_shift ;
chem_shift := origin ;
else :
- %chem_move_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+chem_initialmov[n]))) ;
- chem_move_p := -chem_b_zero[n] rotated chem_ang(n,d+chem_initialmov[n]) ;
+ chem_move_p := (origin - 2*center(chem_b_path[n] rotated chem_ang(n,d+chem_initialmov[n]))) ;
currentpicture := currentpicture shifted chem_move_p ;
chem_shift := chem_shift + chem_move_p ;
- %if (n = 3) or (n = 5) : chem_rot(n, -n) ; fi
fi ;
enddef ;
vardef chem_off (expr n, d) =
- pair o ; o := (-chem_setting_offset,0) rotated chem_ang(1,d+chem_initialmov[1]) ;
- currentpicture := currentpicture shifted o ;
- chem_shift := chem_shift + o ;
+ if (d = 1) or (d = 2) or (d = 8) : % positive
+ currentpicture := currentpicture shifted (-chem_setting_offset,0) ;
+ chem_shift := chem_shift + (-chem_setting_offset,0)
+ elseif (d = 4) or (d = 5) or (d = 6) : % negative
+ currentpicture := currentpicture shifted ( chem_setting_offset,0) ;
+ chem_shift := chem_shift + ( chem_setting_offset,0)
+ fi ;
enddef ;
-vardef chem_set (expr n, m) =
+vardef chem_set(expr n, m) =
if chem_adjacent > 0 :
chem_adjacent_d := xpart chem_b_zero[n] + xpart chem_b_zero[m] ;
if chem_adjacent = 1 : chem_adjacent_p := (-chem_adjacent_d, 0) ;
@@ -642,6 +618,7 @@ vardef chem_set (expr n, m) =
chem_shift := chem_shift + chem_substituent_p ;
chem_substituent := 0 ;
fi ;
+ chem_rotation := chem_initialrot[m] ;
enddef ;
vardef chem_draw (expr n, path_fragment, from_point, to_point, linewidth, linecolor) =
@@ -701,7 +678,7 @@ vardef chem_save =
chem_shift := origin ;
% chem_adjacent := 0 ;
% chem_substituent := 0 ;
-% chem_rotation := 0 ;
+% chem_rotation := 1 ;
currentpicture := nullpicture ;
enddef ;
@@ -716,16 +693,14 @@ vardef chem_restore =
fi ;
enddef ;
-def chem_init_some(expr n) =
- boolean front ; front := n < 0 ;
+def chem_init_some(expr n, ratio, start, initialrot, initialmov) =
+ chem_width [n] := ratio * chem_base_width * chem_setting_scale ;
chem_angle [n] := 360/abs(n) ;
- chem_initialmov[n] := 0 ;
- chem_width [n] := chem_setting_scale * (chem_base_width/2) / sind(chem_angle[n]/2) ;
- chem_dbl_offset[n] := chem_setting_scale * chem_base_width / 20 ;
- chem_b_path [n] := ((chem_width[n],0) rotated -(chem_angle[n]/2))--
- ((chem_width[n],0) rotated +(chem_angle[n]/2)) ;
- chem_b_zero [n] := point 1 of chem_b_path [n] ;
- chem_n_zero [n] := chem_text_min*chem_b_zero[n] ;
+ chem_start [n] := start ;
+ chem_initialrot[n] := initialrot ;
+ chem_initialmov[n] := initialmov ;
+ chem_b_zero [n] := (chem_width[n],0) rotated (chem_angle[n]/2) ;
+ chem_n_zero [n] := (chem_text_min*chem_width[n],0) rotated (chem_angle[n]/2) ;
chem_r_max [n] := chem_radical_max*chem_b_zero[n] ;
chem_r_path [n] := chem_b_zero[n] -- chem_r_max[n] ;
chem_mr_path [n] := chem_r_path [n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ;
@@ -734,120 +709,119 @@ def chem_init_some(expr n) =
chem_mr_zero [n] := point 1 of chem_mr_path[n] ;
chem_pr_zero [n] := point 1 of chem_pr_path[n] ;
chem_crz_zero [n] := point 1 of (chem_r_path[n] enlonged chem_center_offset) ;
- chem_ztt_zero [n] := chem_text_max*(center chem_b_path[n]) ;
- chem_zbt_zero [n] := chem_text_min*(center chem_b_path[n]) ;
- chem_au_path [n] := chem_b_path[n] paralleled ((1-chem_text_max)*(abs(center chem_b_path[n]))) ;
+ chem_au_path [n] := subpath (0.2,0.8) of (chem_r_max[n] -- (chem_r_max[n] rotated chem_angle[n])) ;
chem_ad_path [n] := reverse(chem_au_path[n]) ;
chem_rt_zero [n] := (((chem_radical_max+chem_radical_min)/2)*chem_width[n],0) rotated (chem_angle[n]/2) ;
chem_rtt_zero [n] := chem_rt_zero[n] rotated + 10 ;
chem_rbt_zero [n] := chem_rt_zero[n] rotated - 10 ;
- chem_bx_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; % ? NOT USED...
+ chem_b_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ;
+ chem_bx_path [n] := reverse(chem_b_zero[n] -- (chem_b_zero[n] rotated -chem_angle[n])) ; % ?
chem_sb_path [n] := subpath (0.25,0.75) of chem_b_path[n] ;
- chem_msb_path [n] := subpath (0.00,0.75) of chem_b_path[n] ;
- chem_psb_path [n] := subpath (0.25,1.00) of chem_b_path[n] ;
- chem_dbl_path [n] := chem_sb_path[n] paralleled - chem_dbl_offset[n] ;
- chem_dbr_path [n] := chem_sb_path[n] paralleled + chem_dbl_offset[n] ;
- chem_eb_path [n] := chem_sb_path[n] paralleled +2chem_dbl_offset[n] ;
- chem_c_path [n] := (fullcircle scaled 2)
- scaled (abs(center chem_b_path[n]) - 2chem_dbl_offset[n]) ;
- chem_cc_path [n] := (subpath (0,(length chem_c_path[n])*(1-1/n)) of chem_c_path[n])
- rotated chem_angle[n] ;
chem_s_path [n] := point 0 of chem_b_path[n] -- point 0 of (chem_b_path[n] rotated (2chem_angle[n])) ;
chem_ss_path [n] := subpath (0.25,0.75) of (chem_s_path[n]) ;
chem_pss_path [n] := subpath (0.00,0.75) of (chem_s_path[n]) ;
chem_mss_path [n] := subpath (0.25,1.00) of (chem_s_path[n]) ;
chem_mid_zero [n] := origin shifted (-.25chem_width[n],0) ;
- chem_midt_path[n] := chem_mid_zero[n] -- chem_b_zero[n] rotated (+chem_angle[n]*floor(n/4)) ;
- chem_midb_path[n] := chem_mid_zero[n] -- chem_b_zero[n] rotated (-chem_angle[n]*ceiling(n/4)) ;
- chem_midst_path [n] := subpath (0.25,1.00) of chem_midt_path [n] ;
- chem_midsb_path [n] := subpath (0.25,1.00) of chem_midb_path [n] ;
+ chem_midst_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated ( chem_angle[n] + chem_angle[n]/2) ;
+ chem_midsb_path[n] := chem_mid_zero[n] -- (chem_width[n],0) rotated (-chem_angle[n] - chem_angle[n]/2) ;
+ chem_midt_path [n] := subpath (0.25,1.00) of chem_midst_path [n] ;
+ chem_midb_path [n] := subpath (0.25,1.00) of chem_midsb_path [n] ;
+ chem_msb_path [n] := subpath (0.00,0.75) of chem_b_path[n] ;
+ chem_psb_path [n] := subpath (0.25,1.00) of chem_b_path[n] ;
+ chem_dbl_path [n] := chem_sb_path[n] shifted - (0.05[origin,center chem_sb_path[n]]) ; % parallel
+ chem_dbr_path [n] := chem_sb_path[n] shifted + (0.05[origin,center chem_sb_path[n]]) ;
+ chem_eb_path [n] := chem_sb_path[n] shifted - (0.25[origin,center chem_sb_path[n]]) ;
chem_sr_path [n] := chem_radical_min*chem_b_zero[n] -- chem_r_max[n] ;
- chem_rl_path [n] := chem_r_path[n] paralleled +chem_dbl_offset[n] ;
- chem_rr_path [n] := chem_r_path[n] paralleled -chem_dbl_offset[n] ;
- chem_srl_path [n] := chem_sr_path[n] paralleled +chem_dbl_offset[n] ;
- chem_srr_path [n] := chem_sr_path[n] paralleled -chem_dbl_offset[n] ;
+ chem_rl_path [n] := chem_r_path[n] paralleled (chem_base_width/20) ;
+ chem_rr_path [n] := chem_r_path[n] paralleled -(chem_base_width/20) ;
+ chem_srl_path [n] := chem_sr_path[n] paralleled (chem_base_width/20) ;
+ chem_srr_path [n] := chem_sr_path[n] paralleled -(chem_base_width/20) ;
chem_br_path [n] := point 1 of chem_sb_path[n] --
point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], -4) --
point 0 of chem_sb_path[n] rotatedaround(point 1 of chem_sb_path[n], 4) -- cycle ;
chem_rb_path [n] := chem_b_zero[n] -- chem_r_max[n] rotated -2 -- chem_r_max[n] -- chem_r_max[n] rotated 2 -- cycle ;
- chem_mrb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n],+(180-chem_angle[n])/2) ;
+ chem_mrb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ;
chem_prb_path [n] := chem_rb_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ;
- chem_msr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n],+(180-chem_angle[n])/2) ;
+ chem_msr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n], (180-chem_angle[n])/2) ;
chem_psr_path [n] := chem_sr_path[n] rotatedaround(chem_b_zero[n],-(180-chem_angle[n])/2) ;
-
- if (front) :
- chem_bb_path [n] := chem_b_path[n] rotated -chem_angle[n] --
- chem_b_path[n] --
- chem_b_path[n] rotated +chem_angle[n] --
- (reverse(chem_b_path[n])) % shortened (.5chem_dbl_offset[n])))
- paralleled chem_dbl_offset[n] --
- cycle ;
- chem_mr_path [n] := origin -- origin shifted (0,-.25chem_base_width) ;
- chem_pr_path [n] := origin -- origin shifted (0,+.25chem_base_width) ;
- chem_mr_zero [n] := point 1 of chem_mr_path[n] ;
- chem_pr_zero [n] := point 1 of chem_pr_path[n] ;
- chem_r_path [n] := chem_mr_zero[n] -- chem_pr_zero[n] ;
- fi
+ % not yet ok:
+% chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (1.25*chem_circle_radius*chem_width[n]));
+% chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (1.25*chem_circle_radius*chem_width[n]));
+ chem_c_path [n] := subpath (30/45, -30/45) of (fullcircle scaled (chem_width[n]));
+ chem_cc_path [n] := subpath (30/45,8-30/45) of (fullcircle rotated 90 scaled (chem_width[n]));
enddef ;
-def chem_init_three = chem_init_some(3) ; enddef ;
-def chem_init_four = chem_init_some(4) ; enddef ;
-def chem_init_five = chem_init_some(5) ; enddef ;
-def chem_init_six = chem_init_some(6) ; enddef ;
-def chem_init_eight = chem_init_some(8) ; enddef ;
-def chem_init_five_front = chem_init_some(-5) ; enddef ;
-def chem_init_six_front = chem_init_some(-6) ; enddef ;
+def chem_init_three = chem_init_some(3,30/52 ,-60,1,2) ; enddef ; % 60
+def chem_init_four = chem_init_some(4,30/42.5, 0,1,0) ; enddef ; % 45
+def chem_init_five = chem_init_some(5,30/35 , 0,1,0) ; enddef ; % 36
+def chem_init_six = chem_init_some(6, 1 , 0,1,0) ; enddef ; % 30
+def chem_init_eight = chem_init_some(8,30/22.5, 0,1,0) ; enddef ; % 22.5
% bb R -R R Z -RZ +RZ
+def chem_init_some_front(expr n, ratio, start, initialrot, initialmov) =
+ chem_init_some(n, ratio, start, initialrot, initialmov) ;
+ chem_bb_path [n] := chem_b_path[n] rotated -chem_angle[n] -- chem_b_path[n] -- chem_b_path[n] rotated chem_angle[n] --
+ (reverse(chem_b_path[n] shortened (chem_base_width/20))) paralleled (chem_base_width/20) --
+ cycle ;
+ chem_r_max [n] := chem_radical_max*chem_b_zero[n] ;
+ chem_mr_path [n] := origin -- origin shifted (0,-.25chem_base_width) ;
+ chem_pr_path [n] := origin -- origin shifted (0, .25*chem_base_width) ;
+ chem_r_path [n] := point 1 of chem_mr_path[n] -- point 1 of chem_pr_path[n] ;
+ chem_mr_zero [n] := point 1 of chem_mr_path[n] ;
+ chem_pr_zero [n] := point 1 of chem_pr_path[n] ;
+enddef ;
+
+def chem_init_five_front = chem_init_some_front(-5,30/35,0,2,0) ; enddef ; % 36
+def chem_init_six_front = chem_init_some_front(-6, 1 ,0,2,0) ; enddef ; % 30
+
vardef chem_init_one =
+ chem_width [1] := .75 * chem_base_width * chem_setting_scale ;
chem_angle [1] := 360/8 ;
- chem_initialmov[1] := 0 ;
- chem_width [1] := chem_setting_scale * chem_base_width ;
- chem_dbl_offset[1] := chem_width[1] / 20 ;
- chem_b_path [1] := origin -- (chem_width[1],0) ;
- chem_b_zero [1] := point 1 of chem_b_path[1] ;
+ chem_start [1] := 0 ;
+ chem_initialrot[1] := 1 ;
+ chem_initialmov[1] := 1 ;
+ chem_b_zero [1] := (1.75*chem_width[1],0) ;
+ chem_r_min [1] := chem_radical_min*chem_b_zero[1] ;
chem_r_max [1] := chem_radical_max*chem_b_zero[1] ;
- chem_r_path [1] := (center chem_b_path[1]) -- (chem_radical_min*chem_b_zero[1]) ;
- chem_r_zero [1] := point 1 of chem_r_path[1] ;
- chem_crz_zero [1] := chem_r_zero[1] enlonged chem_center_offset ; % ???
- chem_e_path [1] := ((1,-.5) -- (1,+.5)) scaled (.25chem_width[1]) ;
- chem_sb_path [1] := subpath (0.25,0.75) of chem_b_path[1] ;
- chem_msb_path [1] := subpath (0, 0.75) of chem_b_path[1] ;
- chem_psb_path [1] := subpath (0.25,1) of chem_b_path[1] ;
- chem_ddt_path [1] := subpath (0, 0.4) of chem_sb_path[1] ;
- chem_ddb_path [1] := subpath (0.6, 1) of chem_sb_path[1] ;
- chem_dbl_path [1] := chem_sb_path[1] paralleled -1chem_dbl_offset[1] ;
- chem_dbr_path [1] := chem_sb_path[1] paralleled +1chem_dbl_offset[1] ;
- chem_tbl_path [1] := chem_sb_path[1] paralleled -2chem_dbl_offset[1] ;
- chem_tbr_path [1] := chem_sb_path[1] paralleled +2chem_dbl_offset[1] ;
- chem_ldt_path [1] := chem_ddt_path[1] paralleled -2chem_dbl_offset[1] ;
- chem_ldb_path [1] := chem_ddb_path[1] paralleled -2chem_dbl_offset[1] ;
- chem_rdt_path [1] := chem_ddt_path[1] paralleled +2chem_dbl_offset[1] ;
- chem_rdb_path [1] := chem_ddb_path[1] paralleled +2chem_dbl_offset[1] ;
- chem_n_zero [1] := center chem_b_path[1] ;
- chem_ztt_zero [1] := chem_n_zero[1] rotated +.5chem_angle[1] ;
- chem_zbt_zero [1] := chem_n_zero[1] rotated -.5chem_angle[1] ;
+ chem_r_path [1] := (.5*chem_width[1],0) -- (1.25*chem_width[1],0) ;
+ chem_r_zero [1] := point 1 of chem_r_path [1] ;
+ chem_b_path [1] := chem_r_path[1] rotated + (chem_angle[1]) ; % used for move here
+ chem_b_zero [1] := chem_r_zero[1] ;
+ chem_crz_zero [1] := chem_r_zero[1] enlonged chem_center_offset ;
+ chem_e_path [1] := (.5*chem_width[1],-.25*chem_width[1]) -- (.5*chem_width[1],.25*chem_width[1]) ;
+ chem_sb_path [1] := chem_r_path [1] ;
+ chem_msb_path [1] := chem_r_path [1] shifted (0,-.1chem_width[1]) ;
+ chem_psb_path [1] := chem_r_path [1] shifted (0, .1chem_width[1]) ;
+ chem_ddt_path [1] := subpath(0,.4) of chem_r_path [1] ;
+ chem_ddb_path [1] := subpath(.6,1) of chem_r_path [1] ;
+ chem_ldt_path [1] := chem_ddt_path [1] shifted (0,-.1chem_width[1]) ; % parallel
+ chem_ldb_path [1] := chem_ddb_path [1] shifted (0,-.1chem_width[1]) ;
+ chem_rdt_path [1] := chem_ddt_path [1] shifted (0, .1chem_width[1]) ;
+ chem_rdb_path [1] := chem_ddb_path [1] shifted (0, .1chem_width[1]) ;
save pr ; pair pr[] ;
- pr0 := point 0 of chem_sb_path[1] ;
- pr1 := point 1 of chem_sb_path[1] ;
- chem_bb_path [1] := pr0 -- (pr1 rotatedaround(pr0,-chem_bb_angle)) --
- (pr1 rotatedaround(pr0,+chem_bb_angle)) -- cycle ;
+ pr0 := point 0 of chem_r_path[1] ;
+ pr1 := point 1 of chem_r_path[1] ;
+ chem_bb_path [1] := pr0 -- (pr1 rotatedaround(pr0,-chem_bb_angle)) -- (pr1 rotatedaround(pr0,chem_bb_angle)) -- cycle ;
chem_oe_path [1] := ((-20,0)--(10,0){up}..(20,10)..(30,0)..(40,-10)..(50.0,0)..(60,10)..(70,0)..(80,-10)..{up}(90,0)--(120,0))
- xsized (abs(pr1-pr0)) shifted pr0 ;
+ xsized (.75*chem_width[1]) shifted pr0 ;
+ chem_rt_zero [1] := point .5 of chem_r_path[1] ;
+ chem_rtt_zero [1] := chem_rt_zero[1] rotated + (chem_angle[1]/2) ;
+ chem_rbt_zero [1] := chem_rt_zero[1] rotated - (chem_angle[1]/2) ;
+ % added by Alan Braslau (adapted to use shared variables):
save p ; pair p[] ;
p0 := pr1 rotatedaround(pr0, -chem_bd_angle) ;
p1 := pr1 rotatedaround(pr0, +chem_bd_angle) ;
- p2 := p0 shifted -pr1 ;
- p3 := p1 shifted -pr1 ;
+ p2 := p0 shifted - pr1 ;
+ p3 := p1 shifted - pr1 ;
chem_bd_path [1] :=
p0 -- p1 for i=chem_bd_n downto 0 :
- -- p2 shifted (i/chem_bd_n)[pr1,pr0]
- -- p3 shifted (i/chem_bd_n)[pr1,pr0]
+ -- p2 shifted (i/chem_bd_n)[pr1,pr0]
+ -- p3 shifted (i/chem_bd_n)[pr1,pr0]
endfor ;
chem_bw_path [1] :=
for i=0 upto chem_bw_n - 1 :
- ((i) /chem_bw_n)[pr0,pr1] .. ((i+.25)/chem_bw_n)[pr0,pr1] shifted +p2 ..
+ ((i) /chem_bw_n)[pr0,pr1] .. ((i+.25)/chem_bw_n)[pr0,pr1] shifted p2 ..
((i+.50)/chem_bw_n)[pr0,pr1] .. ((i+.75)/chem_bw_n)[pr0,pr1] shifted -p2 ..
endfor pr1 ;
enddef ;
diff --git a/metapost/context/base/mp-core.mpiv b/metapost/context/base/mp-core.mpiv
index 3dba4a004..1934e3040 100644
--- a/metapost/context/base/mp-core.mpiv
+++ b/metapost/context/base/mp-core.mpiv
@@ -5,7 +5,7 @@
%D subtitle=background macros,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
diff --git a/metapost/context/base/mp-crop.mpiv b/metapost/context/base/mp-crop.mpiv
index 00bcdcb44..6360757e5 100644
--- a/metapost/context/base/mp-crop.mpiv
+++ b/metapost/context/base/mp-crop.mpiv
@@ -5,7 +5,7 @@
%D subtitle=Cropmarks,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
@@ -15,20 +15,20 @@ if known context_crop : endinput ; fi ;
boolean context_crop ; context_crop := true ;
-vardef crop_marks_lines (expr box, len, offset, nx, ny) =
- save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ;
+vardef crop_marks_lines (expr box, length, offset, nx, ny) =
+ save p ; picture p ; save w, h, x, y ; numeric w, h, x, y ;
p := image (
x := if nx = 0 : 1 else : nx - 1 fi ;
y := if ny = 0 : 1 else : ny - 1 fi ;
w := bbwidth (box) / x ;
h := bbheight(box) / y ;
for i=0 upto y :
- draw ((llcorner box) -- (llcorner box) shifted (-len,0)) shifted (-offset,i*h) ;
- draw ((lrcorner box) -- (lrcorner box) shifted ( len,0)) shifted ( offset,i*h) ;
+ draw ((llcorner box) -- (llcorner box) shifted (-length,0)) shifted (-offset,i*h) ;
+ draw ((lrcorner box) -- (lrcorner box) shifted ( length,0)) shifted ( offset,i*h) ;
endfor ;
for i=0 upto x :
- draw ((llcorner box) -- (llcorner box) shifted (0,-len)) shifted (i*w,-offset) ;
- draw ((ulcorner box) -- (ulcorner box) shifted (0, len)) shifted (i*w, offset) ;
+ draw ((llcorner box) -- (llcorner box) shifted (0,-length)) shifted (i*w,-offset) ;
+ draw ((ulcorner box) -- (ulcorner box) shifted (0, length)) shifted (i*w, offset) ;
endfor ;
) ;
setbounds p to box ;
diff --git a/metapost/context/base/mp-figs.mpiv b/metapost/context/base/mp-figs.mpiv
index aac7c5ad2..c65808f6d 100644
--- a/metapost/context/base/mp-figs.mpiv
+++ b/metapost/context/base/mp-figs.mpiv
@@ -5,7 +5,7 @@
%D subtitle=figures,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-form.mpiv b/metapost/context/base/mp-form.mpiv
index b58792e1a..d0519b4f2 100644
--- a/metapost/context/base/mp-form.mpiv
+++ b/metapost/context/base/mp-form.mpiv
@@ -5,7 +5,7 @@
%D subtitle=form support,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-func.mpiv b/metapost/context/base/mp-func.mpiv
index 58df711f2..1d289b606 100644
--- a/metapost/context/base/mp-func.mpiv
+++ b/metapost/context/base/mp-func.mpiv
@@ -5,7 +5,7 @@
%D subtitle=function hacks,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-grap.mpiv b/metapost/context/base/mp-grap.mpiv
deleted file mode 100644
index 68d95c9eb..000000000
--- a/metapost/context/base/mp-grap.mpiv
+++ /dev/null
@@ -1,202 +0,0 @@
-%D \module
-%D [ file=mp-grap.mpiv,
-%D version=2012.10.16, % 2008.09.08 and earlier,
-%D title=\CONTEXT\ \METAPOST\ graphics,
-%D subtitle=graph packagesupport,
-%D author=Hans Hagen \& Alan Braslau,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
-%C details.
-
-if known context_grap : endinput ; fi ;
-
-boolean context_grap ; context_grap := true ;
-
-input graph.mp ;
-
-vardef roundd(expr x, d) =
- if abs d > 4 :
- if d > 0 :
- x
- else :
- 0
- fi
- elseif d > 0 :
- save i ; i = floor x ;
- i + round(Ten_to[d]*(x-i))/Ten_to[d]
- else :
- round(x/Ten_to[-d])*Ten_to[-d]
- fi
-enddef ;
-
-Ten_to0 = 1 ;
-Ten_to1 = 10 ;
-Ten_to2 = 100 ;
-Ten_to3 = 1000 ;
-Ten_to4 = 10000 ;
-
-def sFe_base = enddef ;
-
-if unknown Fe_plus :
- picture Fe_plus ; Fe_plus := textext("+") ; % btex + etex ;
-fi ;
-
-vardef format (expr f,x) = dofmt_.Feform_(f,x) enddef ;
-vardef Mformat (expr f,x) = dofmt_.Meform (f,x) enddef ;
-vardef formatstr (expr f,x) = dofmt_.Feform_(f,x) enddef ;
-vardef Mformatstr(expr f,x) = dofmt_.Meform(f,x) enddef ;
-
-vardef escaped_format(expr s) =
- "" for n=1 upto length(s) : &
- if ASCII substring (n,n+1) of s = 37 :
- "@"
- else :
- substring (n,n+1) of s
- fi
- endfor
-enddef ;
-
-vardef dofmt_@#(expr f, x) =
- % textext("\MPgraphformat{" & escaped_format(f) & "}{" & (if string x : x else: decimal x fi) & "}")
- textext(mfun_format_number(escaped_format(f),x))
-enddef ;
-
-% We redefine autogrid from graph.mp adding the possibility of differing X and Y
-% formats. Autoform is defined in graph.mp (by default "%g").
-%
-% string Autoform_X ; Autoform_X := "@.0e" ;
-% string Autoform_Y ; Autoform_Y := "@.0e" ;
-
-vardef autogrid(suffix tx, ty) text w =
- Gneedgr_ := false ;
- if str tx <> "" :
- for x=auto.x :
- tx (
- if string Autoform_X :
- if Autoform_X <> "" :
- Autoform_X
- else :
- Autoform
- fi
- else :
- Autoform
- fi,
- x) w ;
- endfor
- fi ;
- if str ty <> "" :
- for y=auto.y :
- ty (
- if string Autoform_Y :
- if Autoform_Y <> "" :
- Autoform_Y
- else :
- Autoform
- fi
- else :
- Autoform
- fi,
- y) w ;
- endfor
- fi ;
-enddef ;
-
-% A couple of extensions:
-
-% Define a vector function sym returning a picture: 10 different shapes,
-% unfilled outline, interior filled with different shades of the background.
-% Thus, overlapping points on a plot are more clearly distinguishable.
-
-% grap_symsize := fontsize defaultfont ; % can be redefined
-%
-% dynamic version:
-
-vardef grap_symsize =
- fontsize defaultfont
-enddef ;
-
-path grap_sym[] ; % (internal) symbol path
-
-grap_sym[0] := (0,0) ; % point
-grap_sym[1] := fullcircle ; % circle
-grap_sym[2] := (up -- down) scaled .5 ; % vertical bar
-
-for i = 3 upto 9 : % polygons
- grap_sym[i] := for j = 0 upto i-1 :
- (up scaled .5) rotated (j*360/i) --
- endfor cycle ;
-endfor
-
-grap_sym[12] := grap_sym[2] rotated +90 ; % horizontal line
-grap_sym[22] := grap_sym[2] rotated +45 ; % backslash
-grap_sym[32] := grap_sym[2] rotated -45 ; % slash
-grap_sym[13] := grap_sym[3] rotated 180 ; % down triangle
-grap_sym[23] := grap_sym[3] rotated -90 ; % right triangle
-grap_sym[33] := grap_sym[3] rotated +90 ; % left triangle
-grap_sym[14] := grap_sym[4] rotated +45 ; % square
-grap_sym[15] := grap_sym[5] rotated 180 ; % down pentagon
-grap_sym[16] := grap_sym[6] rotated +90 ; % turned hexagon
-grap_sym[17] := grap_sym[7] rotated 180 ;
-grap_sym[18] := grap_sym[8] rotated +22.5 ;
-
-numeric l ;
-
-for j = 5 upto 9 :
- l := length(grap_sym[j]) ;
- pair p[] ;
- for i = 0 upto l :
- p[i] = whatever [point i of grap_sym[j],
- point (i+2 mod l) of grap_sym[j]] ;
- p[i] = whatever [point (i+1 mod l) of grap_sym[j],
- point (i+l-1 mod l) of grap_sym[j]] ;
- endfor
- grap_sym[20+j] := for i = 0 upto l : point i of grap_sym[j]--p[i]--endfor cycle ;
-endfor
-
-path s ; s := grap_sym[4] ;
-path q ; q := s scaled .25 ;
-numeric l ; l := length(s) ;
-
-pair p[] ;
-
-grap_sym[24] := for i = 0 upto l-1 :
- hide(
- p[i] = whatever [point i of s, point (i+1 mod l) of s] ;
- p[i] = whatever [point i of q, point (i-1+l mod l) of q] ;
- p[i+l] = whatever [point i of s, point (i+1 mod l) of s] ;
- p[i+l] = whatever [point i+1 of q, point (i+2 mod l) of q] ;
- )
- point i of q -- p[i] -- p[i+l] --
-endfor cycle ;
-
-grap_sym[34] := grap_sym[24] rotated 45 ;
-
- % usage: gdraw p plot plotsymbol(1,red,1) ; % a filled red circle
- % usage: gdraw p plot plotsymbol(4,blue,0) ; % a blue square
- % usage: gdraw p plot plotsymbol(14,green,0.5) ; % a 50% filled green diamond
-
-def plotsymbol(expr n,c,f) = % (number,color,color|number)
- if known grap_sym[n] :
- image(
- path p ; p := grap_sym[n] scaled grap_symsize ;
- undraw p withpen currentpen scaled 2 ;
- if cycle p : fill p withcolor
- if color f and known f :
- f
- elseif numeric f and known f and color c and known c :
- f[background,c]
- elseif numeric f and known f :
- f[background,black]
- else :
- background
- fi ;
- fi
- draw p if color c and known c : withcolor c fi ;
- )
- else :
- nullpicture
- fi
-enddef ;
diff --git a/metapost/context/base/mp-grid.mpiv b/metapost/context/base/mp-grid.mpiv
index b9243b1b9..cc5c2b76e 100644
--- a/metapost/context/base/mp-grid.mpiv
+++ b/metapost/context/base/mp-grid.mpiv
@@ -5,7 +5,7 @@
%D subtitle=grid support,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-grph.mpiv b/metapost/context/base/mp-grph.mpiv
index 30c49e6e0..a8868033b 100644
--- a/metapost/context/base/mp-grph.mpiv
+++ b/metapost/context/base/mp-grph.mpiv
@@ -5,7 +5,7 @@
%D subtitle=graphic text support,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-mlib.mpiv b/metapost/context/base/mp-mlib.mpiv
index b8fabbfb9..71985cef8 100644
--- a/metapost/context/base/mp-mlib.mpiv
+++ b/metapost/context/base/mp-mlib.mpiv
@@ -5,7 +5,7 @@
%D subtitle=plugins,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
@@ -255,7 +255,7 @@ vardef thetextext@#(expr p,z) =
fi
enddef ;
-vardef textext@#(expr p) = % no draw here
+vardef textext@#(expr p) = % no draw hers
thetextext@#(p,origin)
enddef ;
@@ -614,28 +614,3 @@ primarydef t asgroup s = % s = isolated|knockout
wrappedpicture
endgroup
enddef ;
-
-% Also experimental
-
-string mfun_auto_align[] ;
-
-mfun_auto_align[0] := "rt" ;
-mfun_auto_align[1] := "urt" ;
-mfun_auto_align[2] := "top" ;
-mfun_auto_align[3] := "ulft" ;
-mfun_auto_align[4] := "lft" ;
-mfun_auto_align[5] := "llft" ;
-mfun_auto_align[6] := "bot" ;
-mfun_auto_align[7] := "lrt" ;
-mfun_auto_align[8] := "rt" ;
-
-def autoalign(expr n) =
- scantokens mfun_auto_align[round((n mod 360)/45)]
-enddef ;
-
-% draw textext.autoalign(60) ("\strut oeps 1") ;
-% draw textext.autoalign(160)("\strut oeps 2") ;
-% draw textext.autoalign(260)("\strut oeps 3") ;
-% draw textext.autoalign(360)("\strut oeps 4") ;
-
-
diff --git a/metapost/context/base/mp-page.mpiv b/metapost/context/base/mp-page.mpiv
index c8e3c6237..96f617257 100644
--- a/metapost/context/base/mp-page.mpiv
+++ b/metapost/context/base/mp-page.mpiv
@@ -5,7 +5,7 @@
%D subtitle=page enhancements,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
diff --git a/metapost/context/base/mp-shap.mpiv b/metapost/context/base/mp-shap.mpiv
index 713656510..b62e636d5 100644
--- a/metapost/context/base/mp-shap.mpiv
+++ b/metapost/context/base/mp-shap.mpiv
@@ -5,7 +5,7 @@
%D subtitle=shapes,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-step.mpiv b/metapost/context/base/mp-step.mpiv
index f7a7ba5de..654ef443d 100644
--- a/metapost/context/base/mp-step.mpiv
+++ b/metapost/context/base/mp-step.mpiv
@@ -5,7 +5,7 @@
%D subtitle=steps,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-text.mpiv b/metapost/context/base/mp-text.mpiv
index b68e8412a..d5630f68e 100644
--- a/metapost/context/base/mp-text.mpiv
+++ b/metapost/context/base/mp-text.mpiv
@@ -5,7 +5,7 @@
%D subtitle=text support,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See licen-en.pdf for
diff --git a/metapost/context/base/mp-tool.mpiv b/metapost/context/base/mp-tool.mpiv
index cdf0e02a9..764863b65 100644
--- a/metapost/context/base/mp-tool.mpiv
+++ b/metapost/context/base/mp-tool.mpiv
@@ -5,14 +5,12 @@
%D subtitle=auxiliary macros,
%D author=Hans Hagen,
%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%D copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-% def loadfile(expr name) = scantokens("input " & name & ";") enddef ;
-
if known context_tool : endinput ; fi ;
boolean context_tool ; context_tool := true ;
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index f33363a0d..e07ecdfc7 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -6,18 +6,11 @@ if not modules then modules = { } end modules ['mtx-context'] = {
license = "see context related readme files"
}
--- todo: more local functions
--- todo: pass jobticket/ctxdata table around
-
local format, gmatch, match, gsub, find = string.format, string.gmatch, string.match, string.gsub, string.find
-local quote, validstring = string.quote, string.valid
+local quote = string.quote
local concat = table.concat
-local settings_to_array = utilities.parsers.settings_to_array
-local appendtable = table.append
-local lpegpatterns, lpegmatch, Cs, P = lpeg.patterns, lpeg.match, lpeg.Cs, lpeg.P
-local getargument = environment.getargument or environment.argument
-local setargument = environment.setargument
+local getargument = environment.argument
local basicinfo = [[
--run process (one or more) files (default action)
@@ -42,10 +35,8 @@ local basicinfo = [[
--noconsole disable logging to the console (logfile only)
--purgeresult purge result file before run
---forcexml force xml stub
+--forcexml force xml stub (optional flag: --mkii)
--forcecld force cld (context lua document) stub
---forcelua force lua stub (like texlua)
---forcemp force mp stub
--arrange run extra imposition pass, given that the style sets up imposition
--noarrange ignore imposition specifications in the style
@@ -59,16 +50,23 @@ local basicinfo = [[
--version report installed context version
--global assume given file present elsewhere
---nofile use dummy file as jobname
--expert expert options
]]
+-- filter=list is kind of obsolete
+-- color is obsolete for mkiv, always on
+-- separation is obsolete for mkiv, no longer available
+-- output is currently obsolete for mkiv
+-- setuppath=list must check
+-- modefile=name must check
+-- input=name load the given inputfile (must check)
+
local expertinfo = [[
expert options:
--touch update context version number (remake needed afterwards, also provide --expert)
---nostatistics omit runtime statistics at the end of the run
+--nostats omit runtime statistics at the end of the run
--update update context from website (not to be confused with contextgarden)
--profile profile job (use: mtxrun --script profile --analyze)
--timing generate timing and statistics overview
@@ -82,14 +80,13 @@ special options:
--pdftex process file with texexec using pdftex
--xetex process file with texexec using xetex
---mkii process file with texexec
--pipe don't check for file and enter scroll mode (--dummyfile=whatever.tmp)
]]
local application = logs.application {
name = "mtx-context",
- banner = "ConTeXt Process Management 0.60",
+ banner = "ConTeXt Process Management 0.52",
helpinfo = {
basic = basicinfo,
extra = extrainfo,
@@ -97,105 +94,159 @@ local application = logs.application {
}
}
--- local luatexflags = {
--- ["8bit"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["default-translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["translate-file"] = true, -- ignored, input is assumed to be in UTF-8 encoding
--- ["etex"] = true, -- ignored, the etex extensions are always active
---
--- ["credits"] = true, -- display credits and exit
--- ["debug-format"] = true, -- enable format debugging
--- ["disable-write18"] = true, -- disable \write18{SHELL COMMAND}
--- ["draftmode"] = true, -- switch on draft mode (generates no output PDF)
--- ["enable-write18"] = true, -- enable \write18{SHELL COMMAND}
--- ["file-line-error"] = true, -- enable file:line:error style messages
--- ["file-line-error-style"] = true, -- aliases of --file-line-error
--- ["no-file-line-error"] = true, -- disable file:line:error style messages
--- ["no-file-line-error-style"] = true, -- aliases of --no-file-line-error
--- ["fmt"] = true, -- load the format file FORMAT
--- ["halt-on-error"] = true, -- stop processing at the first error
--- ["help"] = true, -- display help and exit
--- ["ini"] = true, -- be iniluatex, for dumping formats
--- ["interaction"] = true, -- set interaction mode (STRING=batchmode/nonstopmode/scrollmode/errorstopmode)
--- ["jobname"] = true, -- set the job name to STRING
--- ["kpathsea-debug"] = true, -- set path searching debugging flags according to the bits of NUMBER
--- ["lua"] = true, -- load and execute a lua initialization script
--- ["mktex"] = true, -- enable mktexFMT generation (FMT=tex/tfm)
--- ["no-mktex"] = true, -- disable mktexFMT generation (FMT=tex/tfm)
--- ["nosocket"] = true, -- disable the lua socket library
--- ["output-comment"] = true, -- use STRING for DVI file comment instead of date (no effect for PDF)
--- ["output-directory"] = true, -- use existing DIR as the directory to write files in
--- ["output-format"] = true, -- use FORMAT for job output; FORMAT is 'dvi' or 'pdf'
--- ["parse-first-line"] = true, -- enable parsing of the first line of the input file
--- ["no-parse-first-line"] = true, -- disable parsing of the first line of the input file
--- ["progname"] = true, -- set the program name to STRING
--- ["recorder"] = true, -- enable filename recorder
--- ["safer"] = true, -- disable easily exploitable lua commands
--- ["shell-escape"] = true, -- enable \write18{SHELL COMMAND}
--- ["no-shell-escape"] = true, -- disable \write18{SHELL COMMAND}
--- ["shell-restricted"] = true, -- restrict \write18 to a list of commands given in texmf.cnf
--- ["synctex"] = true, -- enable synctex
--- ["version"] = true, -- display version and exit
--- ["luaonly"] = true, -- run a lua file, then exit
--- ["luaconly"] = true, -- byte-compile a lua file, then exit
--- }
-
local report = application.report
scripts = scripts or { }
scripts.context = scripts.context or { }
--- constants
+-- a demo cld file:
+--
+-- context.starttext()
+-- context.chapter("Hello There")
+-- context.readfile("tufte","","not found")
+-- context.stoptext()
-local usedfiles = {
- nop = "cont-nop.mkiv",
- yes = "cont-yes.mkiv",
-}
+-- l-file / todo
-local usedsuffixes = {
- before = {
- "tuc"
- },
- after = {
- "pdf", "tuc", "log"
- },
- keep = {
- "log"
- },
-}
+function file.needsupdate(oldfile,newfile)
+ return true
+end
+function file.syncmtimes(oldfile,newfile)
+end
-local formatofinterface = {
- en = "cont-en",
- uk = "cont-uk",
- de = "cont-de",
- fr = "cont-fr",
- nl = "cont-nl",
- cs = "cont-cs",
- it = "cont-it",
- ro = "cont-ro",
- pe = "cont-pe",
-}
+-- l-io
-local defaultformats = {
- "cont-en",
- "cont-nl",
-}
+function io.copydata(fromfile,tofile)
+ io.savedata(tofile,io.loaddata(fromfile) or "")
+end
--- process information
+-- ctx (will become util-ctx)
+
+local ctxrunner = { }
+
+function ctxrunner.filtered(str,method)
+ str = tostring(str)
+ if method == 'name' then str = file.removesuffix(file.basename(str))
+ elseif method == 'path' then str = file.dirname(str)
+ elseif method == 'suffix' then str = file.extname(str)
+ elseif method == 'nosuffix' then str = file.removesuffix(str)
+ elseif method == 'nopath' then str = file.basename(str)
+ elseif method == 'base' then str = file.basename(str)
+-- elseif method == 'full' then
+-- elseif method == 'complete' then
+-- elseif method == 'expand' then -- str = file.expandpath(str)
+ end
+ return str:gsub("\\","/")
+end
-local ctxrunner = { } -- namespace will go
+function ctxrunner.substitute(e,str)
+ local attributes = e.at
+ if str and attributes then
+ if attributes['method'] then
+ str = ctxrunner.filtered(str,attributes['method'])
+ end
+ if str == "" and attributes['default'] then
+ str = attributes['default']
+ end
+ end
+ return str
+end
-local ctx_locations = { '..', '../..' }
+function ctxrunner.reflag(flags)
+ local t = { }
+ for _, flag in next, flags do
+ local key, value = match(flag,"^(.-)=(.+)$")
+ if key and value then
+ t[key] = value
+ else
+ t[flag] = true
+ end
+ end
+ return t
+end
+
+function ctxrunner.substitute(str)
+ return str
+end
+
+function ctxrunner.justtext(str)
+ str = xml.unescaped(tostring(str))
+ str = xml.cleansed(str)
+ str = str:gsub("\\+",'/')
+ str = str:gsub("%s+",' ')
+ return str
+end
function ctxrunner.new()
return {
- ctxname = "",
- jobname = "",
- flags = { },
+ ctxname = "",
+ jobname = "",
+ xmldata = nil,
+ suffix = "prep",
+ locations = { '..', '../..' },
+ variables = { },
+ messages = { },
+ environments = { },
+ modules = { },
+ filters = { },
+ flags = { },
+ modes = { },
+ prepfiles = { },
+ paths = { },
}
end
-function ctxrunner.checkfile(ctxdata,ctxname,defaultname)
+function ctxrunner.savelog(ctxdata,ctlname)
+ local function yn(b)
+ if b then return 'yes' else return 'no' end
+ end
+ if not ctlname or ctlname == "" or ctlname == ctxdata.jobname then
+ if ctxdata.jobname then
+ ctlname = file.replacesuffix(ctxdata.jobname,'ctl')
+ elseif ctxdata.ctxname then
+ ctlname = file.replacesuffix(ctxdata.ctxname,'ctl')
+ else
+ report("invalid ctl name: %s",ctlname or "?")
+ return
+ end
+ end
+ local prepfiles = ctxdata.prepfiles
+ if prepfiles and next(prepfiles) then
+ report("saving logdata in: %s",ctlname)
+ f = io.open(ctlname,'w')
+ if f then
+ f:write("\n\n")
+ f:write(format("\n",yn(ctxdata.runlocal)))
+ local sorted = table.sortedkeys(prepfiles)
+ for i=1,#sorted do
+ local name = sorted[i]
+ f:write(format("\t%s\n",yn(prepfiles[name]),name))
+ end
+ f:write("\n")
+ f:close()
+ end
+ else
+ report("nothing prepared, no ctl file saved")
+ os.remove(ctlname)
+ end
+end
+
+function ctxrunner.register_path(ctxdata,path)
+ -- test if exists
+ ctxdata.paths[ctxdata.paths+1] = path
+end
+
+function ctxrunner.trace(ctxdata)
+ print(table.serialize(ctxdata.messages))
+ print(table.serialize(ctxdata.flags))
+ print(table.serialize(ctxdata.environments))
+ print(table.serialize(ctxdata.modules))
+ print(table.serialize(ctxdata.filters))
+ print(table.serialize(ctxdata.modes))
+ print(xml.tostring(ctxdata.xmldata))
+end
+
+function ctxrunner.manipulate(ctxdata,ctxname,defaultname)
if not ctxdata.jobname or ctxdata.jobname == "" then
return
@@ -218,14 +269,13 @@ function ctxrunner.checkfile(ctxdata,ctxname,defaultname)
local usedname = ctxdata.ctxname
local found = lfs.isfile(usedname)
- -- no further test if qualified path
+ -- no futher test if qualified path
if not found then
- for _, path in next, ctx_locations do
+ for _, path in next, ctxdata.locations do
local fullname = file.join(path,ctxdata.ctxname)
if lfs.isfile(fullname) then
- usedname = fullname
- found = true
+ usedname, found = fullname, true
break
end
end
@@ -233,70 +283,194 @@ function ctxrunner.checkfile(ctxdata,ctxname,defaultname)
if not found then
usedname = resolvers.findfile(ctxdata.ctxname,"tex")
- found = usedname ~= ""
+ found = usedname ~= ""
end
if not found and defaultname and defaultname ~= "" and lfs.isfile(defaultname) then
- usedname = defaultname
- found = true
+ usedname, found = defaultname, true
end
if not found then
return
end
- local xmldata = xml.load(usedname)
+ ctxdata.xmldata = xml.load(usedname)
- if not xmldata then
+ if not ctxdata.xmldata then
return
else
-- test for valid, can be text file
end
- local ctxpaths = table.append({'.', file.dirname(ctxdata.ctxname)}, ctx_locations)
+ xml.include(ctxdata.xmldata,'ctx:include','name', table.append({'.', file.dirname(ctxdata.ctxname)},ctxdata.locations))
- xml.include(xmldata,'ctx:include','name', ctxpaths)
+ ctxdata.variables['job'] = ctxdata.jobname
- local flags = ctxdata.flags
+ ctxdata.flags = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:flags/ctx:flag",true)
+ ctxdata.environments = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:environment",true)
+ ctxdata.modules = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:module",true)
+ ctxdata.filters = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:filter",true)
+ ctxdata.modes = xml.collect_texts(ctxdata.xmldata,"/ctx:job/ctx:process/ctx:resources/ctx:mode",true)
+ ctxdata.messages = xml.collect_texts(ctxdata.xmldata,"ctx:message",true)
- for e in xml.collected(xmldata,"/ctx:job/ctx:flags/ctx:flag") do
- local flag = xml.text(e) or ""
- local key, value = match(flag,"^(.-)=(.+)$")
- if key and value then
- flags[key] = value
- else
- flags[flag] = true
- end
+ ctxdata.flags = ctxrunner.reflag(ctxdata.flags)
+
+ local messages = ctxdata.messages
+ for i=1,#messages do
+ report("ctx comment: %s", xml.tostring(messages[i]))
end
-end
+ for r, d, k in xml.elements(ctxdata.xmldata,"ctx:value[@name='job']") do
+ d[k] = ctxdata.variables['job'] or ""
+ end
-function ctxrunner.checkflags(ctxdata)
- if ctxdata then
- for k,v in next, ctxdata.flags do
- if getargument(k) == nil then
- setargument(k,v)
+ local commands = { }
+ for e in xml.collected(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:processors/ctx:processor") do
+ commands[e.at and e.at['name'] or "unknown"] = e
+ end
+
+ local suffix = xml.filter(ctxdata.xmldata,"/ctx:job/ctx:preprocess/attribute('suffix')") or ctxdata.suffix
+ local runlocal = xml.filter(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:processors/attribute('local')")
+
+ runlocal = toboolean(runlocal)
+
+ for files in xml.collected(ctxdata.xmldata,"/ctx:job/ctx:preprocess/ctx:files") do
+ for pattern in xml.collected(files,"ctx:file") do
+
+ preprocessor = pattern.at['processor'] or ""
+
+ if preprocessor ~= "" then
+
+ ctxdata.variables['old'] = ctxdata.jobname
+ for r, d, k in xml.elements(ctxdata.xmldata,"ctx:value") do
+ local ek = d[k]
+ local ekat = ek.at['name']
+ if ekat == 'old' then
+ d[k] = ctxrunner.substitute(ctxdata.variables[ekat] or "")
+ end
+ end
+
+ pattern = ctxrunner.justtext(xml.tostring(pattern))
+
+ local oldfiles = dir.glob(pattern)
+
+ local pluspath = false
+ if #oldfiles == 0 then
+ -- message: no files match pattern
+ local paths = ctxdata.paths
+ for i=1,#paths do
+ local p = paths[i]
+ local oldfiles = dir.glob(path.join(p,pattern))
+ if #oldfiles > 0 then
+ pluspath = true
+ break
+ end
+ end
+ end
+ if #oldfiles == 0 then
+ -- message: no old files
+ else
+ for i=1,#oldfiles do
+ local oldfile = oldfiles[i]
+ local newfile = oldfile .. "." .. suffix -- addsuffix will add one only
+ if ctxdata.runlocal then
+ newfile = file.basename(newfile)
+ end
+ if oldfile ~= newfile and file.needsupdate(oldfile,newfile) then
+ -- message: oldfile needs preprocessing
+ -- os.remove(newfile)
+ local splitted = preprocessor:split(',')
+ for i=1,#splitted do
+ local pp = splitted[i]
+ local command = commands[pp]
+ if command then
+ command = xml.copy(command)
+ local suf = (command.at and command.at['suffix']) or ctxdata.suffix
+ if suf then
+ newfile = oldfile .. "." .. suf
+ end
+ if ctxdata.runlocal then
+ newfile = file.basename(newfile)
+ end
+ for r, d, k in xml.elements(command,"ctx:old") do
+ d[k] = ctxrunner.substitute(oldfile)
+ end
+ for r, d, k in xml.elements(command,"ctx:new") do
+ d[k] = ctxrunner.substitute(newfile)
+ end
+ ctxdata.variables['old'] = oldfile
+ ctxdata.variables['new'] = newfile
+ for r, d, k in xml.elements(command,"ctx:value") do
+ local ek = d[k]
+ local ekat = ek.at and ek.at['name']
+ if ekat then
+ d[k] = ctxrunner.substitute(ctxdata.variables[ekat] or "")
+ end
+ end
+ -- potential optimization: when mtxrun run internal
+ command = xml.content(command)
+ command = ctxrunner.justtext(command)
+ report("command: %s",command)
+ local result = os.spawn(command) or 0
+ -- somehow we get the wrong return value
+ if result > 0 then
+ report("error, return code: %s",result)
+ end
+ if ctxdata.runlocal then
+ oldfile = file.basename(oldfile)
+ end
+ end
+ end
+ if lfs.isfile(newfile) then
+ file.syncmtimes(oldfile,newfile)
+ ctxdata.prepfiles[oldfile] = true
+ else
+ report("error, check target location of new file: %s", newfile)
+ ctxdata.prepfiles[oldfile] = false
+ end
+ else
+ report("old file needs no preprocessing")
+ ctxdata.prepfiles[oldfile] = lfs.isfile(newfile)
+ end
+ end
+ end
end
end
end
+
+ ctxrunner.savelog(ctxdata)
+
end
--- multipass control
+function ctxrunner.preppedfile(ctxdata,filename)
+ if ctxdata.prepfiles[file.basename(filename)] then
+ return filename .. ".prep"
+ else
+ return filename
+ end
+end
-local multipass_suffixes = { ".tuc" }
-local multipass_nofruns = 8 -- or 7 to test oscillation
+-- rest
+
+scripts.context.multipass = {
+-- suffixes = { ".tuo", ".tuc" },
+ suffixes = { ".tuc" },
+ nofruns = 8,
+-- nofruns = 7, -- test oscillation
+}
-local function multipass_hashfiles(jobname)
+function scripts.context.multipass.hashfiles(jobname)
local hash = { }
- for i=1,#multipass_suffixes do
- local suffix = multipass_suffixes[i]
+ local suffixes = scripts.context.multipass.suffixes
+ for i=1,#suffixes do
+ local suffix = suffixes[i]
local full = jobname .. suffix
hash[full] = md5.hex(io.loaddata(full) or "unknown")
end
return hash
end
-local function multipass_changed(oldhash, newhash)
+function scripts.context.multipass.changed(oldhash, newhash)
for k,v in next, oldhash do
if v ~= newhash[k] then
return true
@@ -305,7 +479,126 @@ local function multipass_changed(oldhash, newhash)
return false
end
-local function multipass_copyluafile(jobname)
+function scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,currentrun,finalrun,once)
+ -- take jobname from ctx
+ jobname = file.removesuffix(jobname)
+ local f = io.open(jobname..".top","w")
+ if f then
+ local function someflag(flag)
+ return (ctxdata and ctxdata.flags[flag]) or getargument(flag)
+ end
+ local function setvalue(flag,template,hash,default)
+ local a = someflag(flag) or default
+ if a and a ~= "" then
+ if hash then
+ if hash[a] then
+ f:write(format(template,a),"\n")
+ end
+ else
+ f:write(format(template,a),"\n")
+ end
+ end
+ end
+ local function setvalues(flag,template,plural)
+ if type(flag) == "table" then
+ for k, v in next, flag do
+ f:write(format(template,v),"\n")
+ end
+ else
+ local a = someflag(flag) or (plural and someflag(flag.."s"))
+ if a and a ~= "" then
+ for v in gmatch(a,"%s*([^,]+)") do
+ f:write(format(template,v),"\n")
+ end
+ end
+ end
+ end
+ local function setfixed(flag,template,...)
+ if someflag(flag) then
+ f:write(format(template,...),"\n")
+ end
+ end
+ local function setalways(template,...)
+ f:write(format(template,...),"\n")
+ end
+ --
+ -- This might change ... we can just pass the relevant flags directly.
+ --
+ setalways("%% runtime options files (command line driven)")
+ --
+ setalways("\\unprotect")
+ --
+ setalways("%% feedback and basic job control")
+ --
+ -- Option file, we can pass more on the commandline some day soon. Actually we
+ -- should use directives and trackers.
+ --
+ setfixed ("timing" , "\\usemodule[timing]")
+ setfixed ("batchmode" , "\\batchmode")
+ setfixed ("batch" , "\\batchmode")
+ setfixed ("nonstopmode" , "\\nonstopmode")
+ setfixed ("nonstop" , "\\nonstopmode")
+ -- setfixed ("tracefiles" , "\\tracefilestrue")
+ setfixed ("nostats" , "\\nomkivstatistics")
+ setfixed ("paranoid" , "\\def\\maxreadlevel{1}")
+ --
+ setalways("%% handy for special styles")
+ --
+ setalways("\\startluacode")
+ setalways("document = document or { }")
+ setalways(table.serialize(environment.arguments, "document.arguments"))
+ setalways(table.serialize(environment.files, "document.files"))
+ setalways("\\stopluacode")
+ --
+ setalways("%% process info")
+ --
+ setalways( "\\setupsystem[inputfile=%s]",getargument("input") or environment.files[1] or "\\jobname")
+ setvalue ("result" , "\\setupsystem[file=%s]")
+ setalways( "\\setupsystem[\\c!n=%s,\\c!m=%s]", kindofrun or 0, currentrun or 0)
+ setvalues("path" , "\\usepath[%s]")
+ setvalue ("setuppath" , "\\setupsystem[\\c!directory={%s}]")
+ setvalue ("randomseed" , "\\setupsystem[\\c!random=%s]")
+ setvalue ("arguments" , "\\setupenv[%s]")
+ if once then
+ setalways("\\enabledirectives[system.runonce]")
+ end
+ setalways("%% modes")
+ setvalues("modefile" , "\\readlocfile{%s}{}{}")
+ setvalues("mode" , "\\enablemode[%s]", true)
+ if ctxdata then
+ setvalues(ctxdata.modes, "\\enablemode[%s]")
+ end
+ --
+ setalways("%% options (not that important)")
+ --
+ setalways("\\startsetups *runtime:options")
+ setfixed ("color" , "\\setupcolors[\\c!state=\\v!start]")
+ setvalue ("separation" , "\\setupcolors[\\c!split=%s]")
+ setfixed ("noarrange" , "\\setuparranging[\\v!disable]")
+ if getargument('arrange') and not finalrun then
+ setalways( "\\setuparranging[\\v!disable]")
+ end
+ setalways("\\stopsetups")
+ --
+ setalways("%% styles and modules")
+ --
+ setalways("\\startsetups *runtime:modules")
+ setvalues("usemodule" , "\\usemodule[%s]", true)
+ setvalues("environment" , "\\environment %s ", true)
+ if ctxdata then
+ setvalues(ctxdata.modules, "\\usemodule[%s]")
+ setvalues(ctxdata.environments, "\\environment %s ")
+ end
+ setalways("\\stopsetups")
+ --
+ setalways("%% done")
+ --
+ setalways("\\protect \\endinput")
+ f:close()
+ end
+end
+
+function scripts.context.multipass.copyluafile(jobname) -- obsolete
local tuaname, tucname = jobname..".tua", jobname..".tuc"
if lfs.isfile(tuaname) then
os.remove(tucname)
@@ -313,54 +606,120 @@ local function multipass_copyluafile(jobname)
end
end
---
+scripts.context.cldsuffixes = table.tohash {
+ "cld",
+}
+
+scripts.context.xmlsuffixes = table.tohash {
+ "xml",
+}
+
+scripts.context.luasuffixes = table.tohash {
+ "lua",
+}
+
+scripts.context.beforesuffixes = {
+ "tuo", "tuc"
+}
+scripts.context.aftersuffixes = {
+ "pdf", "tuo", "tuc", "log"
+}
+
+scripts.context.errorsuffixes = {
+ "log"
+}
+
+scripts.context.interfaces = {
+ en = "cont-en",
+ uk = "cont-uk",
+ de = "cont-de",
+ fr = "cont-fr",
+ nl = "cont-nl",
+ cs = "cont-cs",
+ it = "cont-it",
+ ro = "cont-ro",
+ pe = "cont-pe",
+}
+
+scripts.context.defaultformats = {
+ "cont-en",
+ "cont-nl",
+-- "mptopdf", -- todo: mak emkiv variant
+-- "metatex", -- will show up soon
+-- "metafun", -- todo: mp formats
+-- "plain"
+}
+
+local lpegpatterns, Cs, P = lpeg.patterns, lpeg.Cs, lpeg.P
local pattern = lpegpatterns.utfbom^-1 * (P("%% ") + P("% ")) * Cs((1-lpegpatterns.newline)^1)
-local function preamble_analyze(filename) -- only files on current path
- local t = { }
- local line = io.loadlines(file.addsuffix(filename,"tex"))
- if line then
- local preamble = lpegmatch(pattern,line)
+local function analyze(filename) -- only files on current path
+ local f = io.open(file.addsuffix(filename,"tex"))
+ if f then
+ local t = { }
+ local line = f:read("*line") or ""
+ local preamble = lpeg.match(pattern,line)
if preamble then
for key, value in gmatch(preamble,"(%S+)%s*=%s*(%S+)") do
t[key] = value
end
t.type = "tex"
- elseif find(line,"^&1', file.replacesuffix(name,"pdf")))
+--~ end
+--~ function scripts.context.closepdf(name)
+--~ os.spawn(format('pdfclose --file "%s" 2>&1', file.replacesuffix(name,"pdf")))
+--~ end
-local function pdf_open(name,method)
+local pdfview -- delayed loading
+
+function scripts.context.openpdf(name,method)
pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
pdfview.setmethod(method)
report(pdfview.status())
pdfview.open(file.replacesuffix(name,"pdf"))
end
-local function pdf_close(name,method)
+function scripts.context.closepdf(name,method)
pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex"))
pdfview.setmethod(method)
pdfview.close(file.replacesuffix(name,"pdf"))
end
--- result file handling
-
-local function result_push_purge(oldbase,newbase)
- for _, suffix in next, usedsuffixes.after do
+local function push_result_purge(oldbase,newbase)
+ for _, suffix in next, scripts.context.aftersuffixes do
local oldname = file.addsuffix(oldbase,suffix)
local newname = file.addsuffix(newbase,suffix)
os.remove(newname)
@@ -368,8 +727,8 @@ local function result_push_purge(oldbase,newbase)
end
end
-local function result_push_keep(oldbase,newbase)
- for _, suffix in next, usedsuffixes.before do
+local function push_result_keep(oldbase,newbase)
+ for _, suffix in next, scripts.context.beforesuffixes do
local oldname = file.addsuffix(oldbase,suffix)
local newname = file.addsuffix(newbase,suffix)
local tmpname = "keep-"..oldname
@@ -380,8 +739,8 @@ local function result_push_keep(oldbase,newbase)
end
end
-local function result_save_error(oldbase,newbase)
- for _, suffix in next, usedsuffixes.keep do
+local function save_result_error(oldbase,newbase)
+ for _, suffix in next, scripts.context.errorsuffixes do
local oldname = file.addsuffix(oldbase,suffix)
local newname = file.addsuffix(newbase,suffix)
os.remove(newname) -- to be sure
@@ -389,8 +748,8 @@ local function result_save_error(oldbase,newbase)
end
end
-local function result_save_purge(oldbase,newbase)
- for _, suffix in next, usedsuffixes.after do
+local function save_result_purge(oldbase,newbase)
+ for _, suffix in next, scripts.context.aftersuffixes do
local oldname = file.addsuffix(oldbase,suffix)
local newname = file.addsuffix(newbase,suffix)
os.remove(newname) -- to be sure
@@ -398,8 +757,8 @@ local function result_save_purge(oldbase,newbase)
end
end
-local function result_save_keep(oldbase,newbase)
- for _, suffix in next, usedsuffixes.after do
+local function save_result_keep(oldbase,newbase)
+ for _, suffix in next, scripts.context.aftersuffixes do
local oldname = file.addsuffix(oldbase,suffix)
local newname = file.addsuffix(newbase,suffix)
local tmpname = "keep-"..oldname
@@ -409,339 +768,313 @@ local function result_save_keep(oldbase,newbase)
end
end
--- executing luatex
-
-local function flags_to_string(flags,prefix) -- context flags get prepended by c:
- local t = { }
- for k, v in table.sortedhash(flags) do
- if prefix then
- k = format("c:%s",k)
- end
- if not v or v == "" or v == '""' then
- -- no need to flag false
- elseif v == true then
- t[#t+1] = format('--%s',k)
- elseif type(v) == "string" then
- t[#t+1] = format('--%s=%s',k,quote(v))
- else
- t[#t+1] = format('--%s=%s',k,tostring(v))
- end
- end
- return concat(t," ")
-end
-
-local function luatex_command(l_flags,c_flags,filename)
- return format('luatex %s %s "%s"',
- flags_to_string(l_flags),
- flags_to_string(c_flags,true),
- filename
- )
-end
-
-local function run_texexec(filename,a_purge,a_purgeall)
- if false then
- -- we need to write a top etc too and run mp etc so it's not worth the
- -- trouble, so it will take a while before the next is finished
- --
- -- context --extra=texutil --convert myfile
- else
- local texexec = resolvers.findfile("texexec.rb") or ""
- if texexec ~= "" then
- os.setenv("RUBYOPT","")
- local options = environment.reconstructcommandline(environment.arguments_after)
- options = gsub(options,"--purge","")
- options = gsub(options,"--purgeall","")
- local command = format("ruby %s %s",texexec,options)
- if a_purge then
- os.execute(command)
- scripts.context.purge_job(filename,false,true)
- elseif a_purgeall then
- os.execute(command)
- scripts.context.purge_job(filename,true,true)
- else
- os.exec(command)
- end
- end
- end
-end
-
---
-
function scripts.context.run(ctxdata,filename)
- --
- local a_nofile = getargument("nofile")
- --
- local files = environment.files or { }
- --
- local filelist, mainfile
- --
- if filename then
- -- the given forced name is processed, the filelist is passed to context
- mainfile = filename
- filelist = { filename }
- -- files = files
- elseif a_nofile then
- -- the list of given files is processed using the dummy file
- mainfile = usedfiles.nop
- filelist = { usedfiles.nop }
- -- files = { }
- elseif #files > 0 then
- -- the list of given files is processed using the stub file
- mainfile = usedfiles.yes
- filelist = files
- files = { }
- else
- return
- end
- --
- local interface = validstring(getargument("interface")) or "en"
- local formatname = formatofinterface[interface] or "cont-en"
- local formatfile, scriptfile = resolvers.locateformat(formatname)
- if not formatfile or not scriptfile then
- report("warning: no format found, forcing remake (commandline driven)")
- scripts.context.make(formatname)
- formatfile, scriptfile = resolvers.locateformat(formatname)
- end
- if formatfile and scriptfile then
- -- okay
- elseif formatname then
- report("error, no format found with name: %s, aborting",formatname)
- return
- else
- report("error, no format found (provide formatname or interface)")
- return
+ -- filename overloads environment.files
+ local files = (filename and { filename }) or environment.files
+ if ctxdata then
+ -- todo: interface
+ for k,v in next, ctxdata.flags do
+ environment.setargument(k,v)
+ end
end
- --
- local a_mkii = getargument("mkii") or getargument("pdftex") or getargument("xetex")
- local a_purge = getargument("purge")
- local a_purgeall = getargument("purgeall")
- local a_purgeresult = getargument("purgeresult")
- local a_global = getargument("global")
- local a_timing = getargument("timing")
- local a_batchmode = getargument("batchmode")
- local a_nonstopmode = getargument("nonstopmode")
- local a_once = getargument("once")
- local a_synctex = getargument("synctex")
- local a_backend = getargument("backend")
- local a_arrange = getargument("arrange")
- local a_noarrange = getargument("noarrange")
- --
- for i=1,#filelist do
+ if #files > 0 then
--
- local filename = filelist[i]
- local basename = file.basename(filename)
- local pathname = file.dirname(filename)
- local jobname = file.removesuffix(basename)
- local ctxname = ctxdata and ctxdata.ctxname
+ local interface = getargument("interface")
+ -- todo: getargument("interface","en")
+ interface = (type(interface) == "string" and interface) or "en"
--
- if pathname == "" and not a_global and filename ~= usedfiles.nop then
- filename = "./" .. filename
+ local formatname = scripts.context.interfaces[interface] or "cont-en"
+ local formatfile, scriptfile = resolvers.locateformat(formatname)
+ -- this catches the command line
+ if not formatfile or not scriptfile then
+ report("warning: no format found, forcing remake (commandline driven)")
+ scripts.context.make(formatname)
+ formatfile, scriptfile = resolvers.locateformat(formatname)
end
--
- local analysis = preamble_analyze(filename)
- --
- if a_mkii or analysis.engine == 'pdftex' or analysis.engine == 'xetex' then
- run_texexec(filename,a_purge,a_purgeall)
- else
- if analysis.interface and analysis.interface ~= interface then
- formatname = formatofinterface[analysis.interface] or formatname
- formatfile, scriptfile = resolvers.locateformat(formatname)
- end
- if not formatfile or not scriptfile then
- report("warning: no format found, forcing remake (source driven)")
- scripts.context.make(formatname)
- formatfile, scriptfile = resolvers.locateformat(formatname)
- end
- if formatfile and scriptfile then
- --
- local suffix = validstring(getargument("suffix"))
- local resultname = validstring(getargument("result"))
- if suffix then
- resultname = file.removesuffix(jobname) .. suffix
+ if formatfile and scriptfile then
+ for i=1,#files do
+ local filename = files[i]
+ local basename, pathname = file.basename(filename), file.dirname(filename)
+ local jobname = file.removesuffix(basename)
+ if pathname == "" and not getargument("global") then
+ filename = "./" .. filename
end
- local oldbase = ""
- local newbase = ""
- if resultname then
- oldbase = file.removesuffix(jobname)
- newbase = file.removesuffix(resultname)
- if oldbase ~= newbase then
- if a_purgeresult then
- result_push_purge(oldbase,newbase)
- else
- result_push_keep(oldbase,newbase)
- end
+ -- look at the first line
+ local a = analyze(filename)
+ if a and (a.engine == 'pdftex' or a.engine == 'xetex' or getargument("pdftex") or getargument("xetex")) then
+ if false then
+ -- we need to write a top etc too and run mp etc so it's not worth the
+ -- trouble, so it will take a while before the next is finished
+ --
+ -- context --extra=texutil --convert myfile
else
- resultname = nil
+ local texexec = resolvers.findfile("texexec.rb") or ""
+ if texexec ~= "" then
+ os.setenv("RUBYOPT","")
+ local options = environment.reconstructcommandline(environment.arguments_after)
+ options = gsub(options,"--purge","")
+ options = gsub(options,"--purgeall","")
+ local command = format("ruby %s %s",texexec,options)
+ if getargument("purge") then
+ os.execute(command)
+ scripts.context.purge_job(filename,false,true)
+ elseif getargument("purgeall") then
+ os.execute(command)
+ scripts.context.purge_job(filename,true,true)
+ else
+ os.exec(command)
+ end
+ end
end
- end
- --
- local pdfview = getargument("autopdf") or getargument("closepdf")
- if pdfview then
- pdf_close(filename,pdfview)
- if resultname then
- pdf_close(resultname,pdfview)
+ else
+ if a and a.interface and a.interface ~= interface then
+ formatname = scripts.context.interfaces[a.interface] or formatname
+ formatfile, scriptfile = resolvers.locateformat(formatname)
end
- end
- --
- local okay = statistics.checkfmtstatus(formatfile)
- if okay ~= true then
- report("warning: %s, forcing remake",tostring(okay))
- scripts.context.make(formatname)
- end
- --
- local oldhash = multipass_hashfiles(jobname)
- local newhash = { }
- local maxnofruns = once and 1 or multipass_nofruns
- --
- local c_flags = {
- directives = validstring(environment.directives), -- gets passed via mtxrun
- trackers = validstring(environment.trackers), -- gets passed via mtxrun
- experiments = validstring(environment.experiments), -- gets passed via mtxrun
- --
- result = validstring(resultname),
- input = validstring(getargument("input") or filename), -- alternative input
- fulljobname = validstring(filename),
- files = concat(files,","),
- ctx = validstring(ctxname),
- }
- --
- for k, v in next, environment.arguments do
- if c_flags[k] == nil then
- c_flags[k] = v
+ -- this catches the command line
+ if not formatfile or not scriptfile then
+ report("warning: no format found, forcing remake (source driven)")
+ scripts.context.make(formatname)
+ formatfile, scriptfile = resolvers.locateformat(formatname)
end
- end
- --
- local l_flags = {
- ["interaction"] = (a_batchmode and "batchmode") or (a_nonstopmode and "nonstopmode") or nil,
- ["synctex"] = a_synctex and 1 or nil,
- ["no-parse-first-line"] = true,
- -- ["no-mktex"] = true,
- -- ["file-line-error-style"] = true,
- ["fmt"] = formatfile,
- ["lua"] = scriptfile,
- ["jobname"] = jobname,
- }
- --
- if a_synctex then
- report("warning: synctex is enabled") -- can add upto 5% runtime
- end
- --
- -- kindofrun: 1:first run, 2:successive run, 3:once, 4:last of maxruns
- --
- for currentrun=1,maxnofruns do
- --
- c_flags.final = false
- c_flags.kindofrun = (a_once and 3) or (currentrun==1 and 1) or (currentrun==maxnofruns and 4) or 2
- c_flags.currentrun = currentrun
- c_flags.noarrange = a_noarrange or a_arrange or nil
- --
- local command = luatex_command(l_flags,c_flags,mainfile)
- --
- report("run %s: %s",i,command)
- print("") -- cleaner, else continuation on same line
- local returncode, errorstring = os.spawn(command)
- if not returncode then
- report("fatal error: no return code, message: %s",errorstring or "?")
- if resultname then
- result_save_error(oldbase,newbase)
+ if formatfile and scriptfile then
+ -- we default to mkiv xml !
+ -- the --prep argument might become automatic (and noprep)
+ local suffix = file.extname(filename) or "?"
+ if scripts.context.xmlsuffixes[suffix] or getargument("forcexml") then
+ if getargument("mkii") then
+ filename = makestub(true,"\\processXMLfilegrouped{%s}",filename)
+ else
+ filename = makestub(true,"\\xmlprocess{\\xmldocument}{%s}{}",filename)
+ end
+ elseif scripts.context.cldsuffixes[suffix] or getargument("forcecld") then
+ -- self contained cld files need to have a starttext/stoptext (less fontloading)
+ filename = makestub(false,"\\ctxlua{context.runfile('%s')}",filename)
+ elseif scripts.context.luasuffixes[suffix] or getargument("forcelua") then
+ filename = makestub(true,"\\ctxlua{dofile('%s')}",filename)
+ elseif getargument("prep") then
+ -- we need to keep the original jobname
+ filename = makestub(true,"\\readfile{%s}{}{}",filename,ctxrunner.preppedfile(ctxdata,filename))
end
- os.exit(1)
- break
- elseif returncode == 0 then
- multipass_copyluafile(jobname)
- newhash = multipass_hashfiles(jobname)
- if multipass_changed(oldhash,newhash) then
- oldhash = newhash
+ --
+ -- todo: also other stubs
+ --
+ local suffix, resultname = getargument("suffix"), getargument("result")
+ if type(suffix) == "string" then
+ resultname = file.removesuffix(jobname) .. suffix
+ end
+ local oldbase, newbase = "", ""
+ if type(resultname) == "string" then
+ oldbase = file.removesuffix(jobname)
+ newbase = file.removesuffix(resultname)
+ if oldbase ~= newbase then
+ if getargument("purgeresult") then
+ push_result_purge(oldbase,newbase)
+ else
+ push_result_keep(oldbase,newbase)
+ end
+ else
+ resultname = nil
+ end
else
- break
+ resultname = nil
end
- else
- report("fatal error: return code: %s",returncode or "?")
+ --
+ local pdfview = getargument("autopdf") or getargument("closepdf")
+ if pdfview then
+ scripts.context.closepdf(filename,pdfview)
+ if resultname then
+ scripts.context.closepdf(resultname,pdfview)
+ end
+ end
+ --
+ local okay = statistics.checkfmtstatus(formatfile)
+ if okay ~= true then
+ report("warning: %s, forcing remake",tostring(okay))
+ scripts.context.make(formatname)
+ end
+ --
+ local flags = { }
+ if getargument("batchmode") or getargument("batch") then
+ flags[#flags+1] = "--interaction=batchmode"
+ end
+ if getargument("synctex") then
+ -- this should become a directive
+ report("warning: synctex is enabled") -- can add upto 5% runtime
+ flags[#flags+1] = "--synctex=1"
+ end
+ flags[#flags+1] = "--fmt=" .. quote(formatfile)
+ flags[#flags+1] = "--lua=" .. quote(scriptfile)
+ --
+ -- We pass these directly.
+ --
+
+--~ local silent = getargument("silent")
+--~ local noconsole = getargument("noconsole")
+--~ local directives = getargument("directives")
+--~ local trackers = getargument("trackers")
+--~ if silent == true then
+--~ silent = "*"
+--~ end
+--~ if type(silent) == "string" then
+--~ if type(directives) == "string" then
+--~ directives = format("%s,logs.blocked={%s}",directives,silent)
+--~ else
+--~ directives = format("logs.blocked={%s}",silent)
+--~ end
+--~ end
+--~ if noconsole then
+--~ if type(directives) == "string" then
+--~ directives = format("%s,logs.target=file",directives)
+--~ else
+--~ directives = format("logs.target=file")
+--~ end
+--~ end
+
+ local directives = environment.directives
+ local trackers = environment.trackers
+ local experiments = environment.experiments
+
+ --
+ if type(directives) == "string" then
+ flags[#flags+1] = format('--directives="%s"',directives)
+ end
+ if type(trackers) == "string" then
+ flags[#flags+1] = format('--trackers="%s"',trackers)
+ end
+ --
+ local backend = getargument("backend")
+ if type(backend) ~= "string" then
+ backend = "pdf"
+ end
+ flags[#flags+1] = format('--backend="%s"',backend)
+ --
+ local command = format("luatex %s %s \\stoptext", concat(flags," "), quote(filename))
+ local oldhash, newhash = scripts.context.multipass.hashfiles(jobname), { }
+ local once = getargument("once")
+ local maxnofruns = (once and 1) or scripts.context.multipass.nofruns
+ local arrange = getargument("arrange")
+ for i=1,maxnofruns do
+ -- 1:first run, 2:successive run, 3:once, 4:last of maxruns
+ local kindofrun = (once and 3) or (i==1 and 1) or (i==maxnofruns and 4) or 2
+ scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,false,once) -- kindofrun, currentrun, final
+ report("run %s: %s",i,command)
+--~ print("\n") -- cleaner, else continuation on same line
+ print("") -- cleaner, else continuation on same line
+ local returncode, errorstring = os.spawn(command)
+ --~ if returncode == 3 then
+ --~ scripts.context.make(formatname)
+ --~ returncode, errorstring = os.spawn(command)
+ --~ if returncode == 3 then
+ --~ report("ks: return code 3, message: %s",errorstring or "?")
+ --~ os.exit(1)
+ --~ end
+ --~ end
+ if not returncode then
+ report("fatal error: no return code, message: %s",errorstring or "?")
+ if resultname then
+ save_result_error(oldbase,newbase)
+ end
+ os.exit(1)
+ break
+ elseif returncode > 0 then
+ report("fatal error: return code: %s",returncode or "?")
+ if resultname then
+ save_result_error(oldbase,newbase)
+ end
+ os.exit(returncode)
+ break
+ else
+ scripts.context.multipass.copyluafile(jobname)
+ -- scripts.context.multipass.copytuifile(jobname)
+ newhash = scripts.context.multipass.hashfiles(jobname)
+ if scripts.context.multipass.changed(oldhash,newhash) then
+ oldhash = newhash
+ else
+ break
+ end
+ end
+ end
+ --
+ if arrange then
+ local kindofrun = 3
+ scripts.context.multipass.makeoptionfile(jobname,ctxdata,kindofrun,i,true) -- kindofrun, currentrun, final
+ report("arrange run: %s",command)
+ local returncode, errorstring = os.spawn(command)
+ if not returncode then
+ report("fatal error: no return code, message: %s",errorstring or "?")
+ os.exit(1)
+ elseif returncode > 0 then
+ report("fatal error: return code: %s",returncode or "?")
+ os.exit(returncode)
+ end
+ end
+ --
+ if getargument("purge") then
+ scripts.context.purge_job(jobname)
+ elseif getargument("purgeall") then
+ scripts.context.purge_job(jobname,true)
+ end
+ --
+ os.remove(jobname..".top")
+ --
if resultname then
- result_save_error(oldbase,newbase)
+ if getargument("purgeresult") then
+ -- so, if there is no result then we don't get the old one, but
+ -- related files (log etc) are still there for tracing purposes
+ save_result_purge(oldbase,newbase)
+ else
+ save_result_keep(oldbase,newbase)
+ end
+ report("result renamed to: %s",newbase)
+ end
+ --
+ if getargument("purge") then
+ scripts.context.purge_job(resultname)
+ elseif getargument("purgeall") then
+ scripts.context.purge_job(resultname,true)
+ end
+ --
+ local pdfview = getargument("autopdf")
+ if pdfview then
+ scripts.context.openpdf(resultname or filename,pdfview)
+ end
+ --
+ if getargument("timing") then
+ report()
+ report("you can process (timing) statistics with:",jobname)
+ report()
+ report("context --extra=timing '%s'",jobname)
+ report("mtxrun --script timing --xhtml [--launch --remove] '%s'",jobname)
+ report()
end
- os.exit(1) -- (returncode)
- break
- end
- --
- end
- --
- if a_arrange then
- --
- c_flags.final = true
- c_flags.kindofrun = 3
- c_flags.currentrun = c_flags.currentrun + 1
- c_flags.noarrange = nil
- --
- local command = luatex_command(l_flags,c_flags,mainfile)
- --
- report("arrange run: %s",command)
- local returncode, errorstring = os.spawn(command)
- if not returncode then
- report("fatal error: no return code, message: %s",errorstring or "?")
- os.exit(1)
- elseif returncode > 0 then
- report("fatal error: return code: %s",returncode or "?")
- os.exit(returncode)
- end
- --
- end
- --
- if a_purge then
- scripts.context.purge_job(jobname)
- elseif a_purgeall then
- scripts.context.purge_job(jobname,true)
- end
- --
- if resultname then
- if a_purgeresult then
- -- so, if there is no result then we don't get the old one, but
- -- related files (log etc) are still there for tracing purposes
- result_save_purge(oldbase,newbase)
else
- result_save_keep(oldbase,newbase)
+ if formatname then
+ report("error, no format found with name: %s, skipping",formatname)
+ else
+ report("error, no format found (provide formatname or interface)")
+ end
+ break
end
- report("result renamed to: %s",newbase)
- end
- --
- if purge then
- scripts.context.purge_job(resultname)
- elseif purgeall then
- scripts.context.purge_job(resultname,true)
- end
- --
- local pdfview = getargument("autopdf")
- if pdfview then
- pdf_open(resultname or jobname,pdfview)
- end
- --
- if a_timing then
- report()
- report("you can process (timing) statistics with:",jobname)
- report()
- report("context --extra=timing '%s'",jobname)
- report("mtxrun --script timing --xhtml [--launch --remove] '%s'",jobname)
- report()
end
+ end
+ else
+ if formatname then
+ report("error, no format found with name: %s, aborting",formatname)
else
- if formatname then
- report("error, no format found with name: %s, skipping",formatname)
- else
- report("error, no format found (provide formatname or interface)")
- end
- break
+ report("error, no format found (provide formatname or interface)")
end
end
end
- --
end
-function scripts.context.pipe() -- still used?
+function scripts.context.pipe()
-- context --pipe
-- context --pipe --purge --dummyfile=whatever.tmp
local interface = getargument("interface")
interface = (type(interface) == "string" and interface) or "en"
- local formatname = formatofinterface[interface] or "cont-en"
+ local formatname = scripts.context.interfaces[interface] or "cont-en"
local formatfile, scriptfile = resolvers.locateformat(formatname)
if not formatfile or not scriptfile then
report("warning: no format found, forcing remake (commandline driven)")
@@ -754,16 +1087,11 @@ function scripts.context.pipe() -- still used?
report("warning: %s, forcing remake",tostring(okay))
scripts.context.make(formatname)
end
- local l_flags = {
- interaction = "scrollmode",
- fmt = formatfile,
- lua = scriptfile,
- }
- local c_flags = {
- backend = "pdf",
- final = false,
- kindofrun = 3,
- currentrun = 1,
+ local flags = {
+ "--interaction=scrollmode",
+ "--fmt=" .. quote(formatfile),
+ "--lua=" .. quote(scriptfile),
+ "--backend=pdf",
}
local filename = getargument("dummyfile") or ""
if filename == "" then
@@ -772,9 +1100,10 @@ function scripts.context.pipe() -- still used?
else
filename = file.addsuffix(filename,"tmp")
io.savedata(filename,"\\relax")
+ scripts.context.multipass.makeoptionfile(filename,{ flags = flags },3,1,false) -- kindofrun, currentrun, final
report("entering scrollmode using '%s' with optionfile, end job with \\end",filename)
end
- local command = luatex_command(l_flags,c_flags,filename)
+ local command = format("luatex %s %s", concat(flags," "), quote(filename))
os.spawn(command)
if getargument("purge") then
scripts.context.purge_job(filename)
@@ -794,9 +1123,11 @@ end
local make_mkiv_format = environment.make_format
local function make_mkii_format(name,engine)
- local command = format("mtxrun texexec.rb --make --%s %s",name,engine)
- report("running command: %s",command)
- os.spawn(command)
+ if getargument(engine) then
+ local command = format("mtxrun texexec.rb --make --%s %s",name,engine)
+ report("running command: %s",command)
+ os.spawn(command)
+ end
end
function scripts.context.generate()
@@ -809,17 +1140,14 @@ function scripts.context.make(name)
if not getargument("fast") then -- as in texexec
scripts.context.generate()
end
- local list = (name and { name }) or (environment.files[1] and environment.files) or defaultformats
- local engine = getargument("engine") or "luatex"
+ local list = (name and { name }) or (environment.files[1] and environment.files) or scripts.context.defaultformats
for i=1,#list do
local name = list[i]
- name = formatofinterface[name] or name or ""
- if name == "" then
- -- nothing
- elseif engine == "luatex" then
+ name = scripts.context.interfaces[name] or name or ""
+ if name ~= "" then
make_mkiv_format(name)
- elseif engine == "pdftex" or engine == "xetex" then
- make_mkii_format(name,engine)
+ make_mkii_format(name,"pdftex")
+ make_mkii_format(name,"xetex")
end
end
end
@@ -827,77 +1155,68 @@ end
function scripts.context.ctx()
local ctxdata = ctxrunner.new()
ctxdata.jobname = environment.files[1]
- ctxrunner.checkfile(ctxdata,getargument("ctx"))
- ctxrunner.checkflags(ctxdata)
+ ctxrunner.manipulate(ctxdata,getargument("ctx"))
scripts.context.run(ctxdata)
end
function scripts.context.autoctx()
local ctxdata = nil
- local files = environment.files
+ local files = (filename and { filename }) or environment.files
local firstfile = #files > 0 and files[1]
- if firstfile then
- local suffix = file.suffix(firstfile)
- if suffix == "xml" then
- local chunk = io.loadchunk(firstfile) -- 1024
- if chunk then
- local ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>")
- if ctxname then
- ctxdata = ctxrunner.new()
- ctxdata.jobname = firstfile
- ctxrunner.checkfile(ctxdata,ctxname)
- ctxrunner.checkflags(ctxdata)
- end
+ if firstfile and file.extname(firstfile) == "xml" then
+ local f = io.open(firstfile)
+ if f then
+ local chunk = f:read(512) or ""
+ f:close()
+ local ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>")
+ if ctxname then
+ ctxdata = ctxrunner.new()
+ ctxdata.jobname = firstfile
+ ctxrunner.manipulate(ctxdata,ctxname)
end
- elseif suffix == "tex" then
- -- maybe but we scan the preamble later too
end
end
scripts.context.run(ctxdata)
end
--- no longer ok as mlib-run misses something:
+local template = [[
+\starttext
+ \directMPgraphic{%s}{input "%s"}
+\stoptext
+]]
--- local template = [[
--- \starttext
--- \directMPgraphic{%s}{input "%s"}
--- \stoptext
--- ]]
---
--- local loaded = false
---
--- function scripts.context.metapost()
--- local filename = environment.files[1] or ""
--- if not loaded then
--- dofile(resolvers.findfile("mlib-run.lua"))
--- loaded = true
--- commands = commands or { }
--- commands.writestatus = report -- no longer needed
--- end
--- local formatname = getargument("format") or "metafun"
--- if formatname == "" or type(formatname) == "boolean" then
--- formatname = "metafun"
--- end
--- if getargument("pdf") then
--- local basename = file.removesuffix(filename)
--- local resultname = getargument("result") or basename
--- local jobname = "mtx-context-metapost"
--- local tempname = file.addsuffix(jobname,"tex")
--- io.savedata(tempname,format(template,"metafun",filename))
--- environment.files[1] = tempname
--- setargument("result",resultname)
--- setargument("once",true)
--- scripts.context.run()
--- scripts.context.purge_job(jobname,true)
--- scripts.context.purge_job(resultname,true)
--- elseif getargument("svg") then
--- metapost.directrun(formatname,filename,"svg")
--- else
--- metapost.directrun(formatname,filename,"mps")
--- end
--- end
-
--- --
+local loaded = false
+
+function scripts.context.metapost()
+ local filename = environment.files[1] or ""
+ if not loaded then
+ dofile(resolvers.findfile("mlib-run.lua"))
+ loaded = true
+ commands = commands or { }
+ commands.writestatus = report -- no longer needed
+ end
+ local formatname = getargument("format") or "metafun"
+ if formatname == "" or type(formatname) == "boolean" then
+ formatname = "metafun"
+ end
+ if getargument("pdf") then
+ local basename = file.removesuffix(filename)
+ local resultname = getargument("result") or basename
+ local jobname = "mtx-context-metapost"
+ local tempname = file.addsuffix(jobname,"tex")
+ io.savedata(tempname,format(template,"metafun",filename))
+ environment.files[1] = tempname
+ environment.setargument("result",resultname)
+ environment.setargument("once",true)
+ scripts.context.run()
+ scripts.context.purge_job(jobname,true)
+ scripts.context.purge_job(resultname,true)
+ elseif getargument("svg") then
+ metapost.directrun(formatname,filename,"svg")
+ else
+ metapost.directrun(formatname,filename,"mps")
+ end
+end
function scripts.context.version()
local name = resolvers.findfile("context.mkiv")
@@ -919,8 +1238,6 @@ function scripts.context.version()
end
end
--- purging files
-
local generic_files = {
"texexec.tex", "texexec.tui", "texexec.tuo",
"texexec.tuc", "texexec.tua",
@@ -945,6 +1262,7 @@ local persistent_runfiles = {
}
local special_runfiles = {
+--~ "-mpgraph*", "-mprun*", "-temp-*" -- hm, wasn't this escaped?
"-mpgraph", "-mprun", "-temp-"
}
@@ -960,6 +1278,9 @@ local function purge_file(dfile,cfile)
end
end
+local function remove_special_files(pattern)
+end
+
function scripts.context.purge_job(jobname,all,mkiitoo)
if jobname and jobname ~= "" then
jobname = file.basename(jobname)
@@ -997,7 +1318,7 @@ function scripts.context.purge(all,pattern,mkiitoo)
local deleted = { }
for i=1,#files do
local name = files[i]
- local suffix = file.suffix(name)
+ local suffix = file.extname(name)
local basename = file.basename(name)
if obsolete[suffix] or temporary[suffix] or persistent[suffix] or generic[basename] then
deleted[#deleted+1] = purge_file(name)
@@ -1014,14 +1335,12 @@ function scripts.context.purge(all,pattern,mkiitoo)
end
end
--- touching files (signals regeneration of formats)
-
local function touch(name,pattern)
local name = resolvers.findfile(name)
local olddata = io.loaddata(name)
if olddata then
local oldversion, newversion = "", os.date("%Y.%m.%d %H:%M")
- local newdata, ok = gsub(olddata,pattern,function(pre,mid,post)
+ local newdata, ok = olddata:gsub(pattern,function(pre,mid,post)
oldversion = mid
return pre .. newversion .. post
end)
@@ -1055,29 +1374,25 @@ function scripts.context.touch()
touchfiles("mkii")
touchfiles("mkiv")
touchfiles("mkvi")
- touchfiles("mkix")
- touchfiles("mkxi")
- else
- report("touching needs --expert")
end
end
-- modules
local labels = { "title", "comment", "status" }
-local cards = { "*.mkvi", "*.mkiv", "*.mkxi", "*.mkix", "*.tex" }
+local cards = { "*.mkvi", "*.mkiv", "*.tex" }
function scripts.context.modules(pattern)
local list = { }
local found = resolvers.findfile("context.mkiv")
if not pattern or pattern == "" then
-- official files in the tree
- for i=1,#cards do
- resolvers.findwildcardfiles(cards[i],list)
+ for _, card in ipairs(cards) do
+ resolvers.findwildcardfiles(card,list)
end
-- my dev path
- for i=1,#cards do
- dir.glob(file.join(file.dirname(found),cards[i]),list)
+ for _, card in ipairs(cards) do
+ dir.glob(file.join(file.dirname(found),card),list)
end
else
resolvers.findwildcardfiles(pattern,list)
@@ -1090,7 +1405,7 @@ function scripts.context.modules(pattern)
if not done[base] then
done[base] = true
local suffix = file.suffix(base)
- if suffix == "tex" or suffix == "mkiv" or suffix == "mkvi" or suffix == "mkix" or suffix == "mkxi" then
+ if suffix == "tex" or suffix == "mkiv" or suffix == "mkvi" then
local prefix = match(base,"^([xmst])%-")
if prefix then
v = resolvers.findfile(base) -- so that files on my dev path are seen
@@ -1147,28 +1462,30 @@ end
function scripts.context.extra()
local extra = getargument("extra")
- if type(extra) ~= "string" then
- scripts.context.extras()
- elseif getargument("help") then
- scripts.context.extras(extra)
- else
- local fullextra = extra
- if not find(fullextra,"mtx%-context%-") then
- fullextra = "mtx-context-" .. extra
- end
- local foundextra = resolvers.findfile(fullextra)
- if foundextra == "" then
- scripts.context.extras()
- return
+ if type(extra) == "string" then
+ if getargument("help") then
+ scripts.context.extras(extra)
else
- report("processing extra: %s", foundextra)
- end
- setargument("purgeall",true)
- local result = getargument("result") or ""
- if result == "" then
- setargument("result","context-extra")
+ local fullextra = extra
+ if not find(fullextra,"mtx%-context%-") then
+ fullextra = "mtx-context-" .. extra
+ end
+ local foundextra = resolvers.findfile(fullextra)
+ if foundextra == "" then
+ scripts.context.extras()
+ return
+ else
+ report("processing extra: %s", foundextra)
+ end
+ environment.setargument("purgeall",true)
+ local result = environment.setargument("result") or ""
+ if result == "" then
+ environment.setargument("result","context-extra")
+ end
+ scripts.context.run(nil,foundextra)
end
- scripts.context.run(nil,foundextra)
+ else
+ scripts.context.extras()
end
end
@@ -1176,27 +1493,25 @@ end
function scripts.context.trackers()
environment.files = { resolvers.findfile("m-trackers.mkiv") }
- multipass_nofruns = 1
- setargument("purgeall",true)
+ scripts.context.multipass.nofruns = 1
+ environment.setargument("purgeall",true)
scripts.context.run()
end
function scripts.context.directives()
environment.files = { resolvers.findfile("m-directives.mkiv") }
- multipass_nofruns = 1
- setargument("purgeall",true)
+ scripts.context.multipass.nofruns = 1
+ environment.setargument("purgeall",true)
scripts.context.run()
end
function scripts.context.logcategories()
environment.files = { resolvers.findfile("m-logcategories.mkiv") }
- multipass_nofruns = 1
- setargument("purgeall",true)
+ scripts.context.multipass.nofruns = 1
+ environment.setargument("purgeall",true)
scripts.context.run()
end
--- updating (often one will use mtx-update instead)
-
function scripts.context.timed(action)
statistics.timed(action)
end
@@ -1233,7 +1548,7 @@ function scripts.context.update()
local function is_okay(basetree)
for _, tree in next, validtrees do
local pattern = gsub(tree,"%-","%%-")
- if find(basetree,pattern) then
+ if basetree:find(pattern) then
return tree
end
end
@@ -1299,7 +1614,7 @@ function scripts.context.update()
end
for k in zipfile:files() do
local filename = k.filename
- if find(filename,"/$") then
+ if filename:find("/$") then
lfs.mkdir(filename)
else
local data = zip.loaddata(zipfile,filename)
@@ -1337,23 +1652,6 @@ function scripts.context.update()
end
end
--- getting it done
-
-if getargument("nostats") then
- setargument("nostatistics",true)
- setargument("nostat",nil)
-end
-
-if getargument("batch") then
- setargument("batchmode",true)
- setargument("batch",nil)
-end
-
-if getargument("nonstop") then
- setargument("nonstopmode",true)
- setargument("nonstop",nil)
-end
-
do
local silent = getargument("silent")
@@ -1366,9 +1664,9 @@ do
end
if getargument("once") then
- multipass_nofruns = 1
+ scripts.context.multipass.nofruns = 1
elseif getargument("runs") then
- multipass_nofruns = tonumber(getargument("runs")) or nil
+ scripts.context.multipass.nofruns = tonumber(getargument("runs")) or nil
end
if getargument("profile") then
@@ -1376,6 +1674,7 @@ if getargument("profile") then
end
if getargument("run") then
+-- scripts.context.timed(scripts.context.run)
scripts.context.timed(scripts.context.autoctx)
elseif getargument("make") then
scripts.context.timed(function() scripts.context.make() end)
@@ -1383,8 +1682,8 @@ elseif getargument("generate") then
scripts.context.timed(function() scripts.context.generate() end)
elseif getargument("ctx") then
scripts.context.timed(scripts.context.ctx)
--- elseif getargument("mp") or getargument("metapost") then
--- scripts.context.timed(scripts.context.metapost)
+elseif getargument("mp") or getargument("metapost") then
+ scripts.context.timed(scripts.context.metapost)
elseif getargument("version") then
application.identify()
scripts.context.version()
@@ -1412,7 +1711,10 @@ elseif getargument("showdirectives") or getargument("directives") == true then
scripts.context.directives()
elseif getargument("showlogcategories") then
scripts.context.logcategories()
-elseif environment.files[1] or getargument("nofile") then
+elseif getargument("track") and type(getargument("track")) == "boolean" then -- for old times sake, will go
+ scripts.context.trackers()
+elseif environment.files[1] then
+-- scripts.context.timed(scripts.context.run)
scripts.context.timed(scripts.context.autoctx)
elseif getargument("pipe") then
scripts.context.timed(scripts.context.pipe)
diff --git a/scripts/context/lua/mtx-convert.lua b/scripts/context/lua/mtx-convert.lua
index 04ff38aad..b4e6e010b 100644
--- a/scripts/context/lua/mtx-convert.lua
+++ b/scripts/context/lua/mtx-convert.lua
@@ -83,7 +83,7 @@ function converters.convertpath(inputpath,outputpath)
inputpath = inputpath or "."
outputpath = outputpath or "."
for name in lfs.dir(inputpath) do
- local suffix = file.suffix(name)
+ local suffix = file.extname(name)
if find(name,"%.$") then
-- skip . and ..
elseif converters[suffix] then
@@ -102,7 +102,7 @@ function converters.convertpath(inputpath,outputpath)
end
function converters.convertfile(oldname)
- local suffix = file.suffix(oldname)
+ local suffix = file.extname(oldname)
if converters[suffix] then
local newname = file.replacesuffix(oldname,"pdf")
if oldname == newname then
diff --git a/scripts/context/lua/mtx-epub.lua b/scripts/context/lua/mtx-epub.lua
index 28a37fec2..7d1c15774 100644
--- a/scripts/context/lua/mtx-epub.lua
+++ b/scripts/context/lua/mtx-epub.lua
@@ -11,8 +11,8 @@ if not modules then modules = { } end modules ['mtx-epub'] = {
-- really an id but has some special property). Then there is this ncx suffix
-- thing. Somehow it give the impression of a reversed engineered application
-- format so it will probably take a few cycles to let it become a real
--- clean standard. Thanks to Adam Reviczky, Luigi Scarso and Andy Thomas for
--- helping to figure out all the puzzling details.
+-- clean standard. Thanks to Adam Reviczky for helping to figure out all these
+-- puzzling details.
-- This is preliminary code. At some point we will deal with images as well but
-- first we need a decent strategy to export them. More information will be
@@ -31,7 +31,7 @@ mtxrun --script epub --make mydocument
local application = logs.application {
name = "mtx-epub",
- banner = "ConTeXt EPUB Helpers 0.12",
+ banner = "ConTeXt EPUB Helpers 0.11",
helpinfo = helpinfo,
}
@@ -43,27 +43,26 @@ scripts.epub = scripts.epub or { }
local mimetype = "application/epub+zip"
local container = [[
-
+
-
+
]]
local package = [[
-
+
- %s
- %s
- urn:uuid:%s
- %s
+ My Title
+ en
+ urn:uuid:%s
+ MySelf%s
-
@@ -71,14 +70,13 @@ local package = [[
-
]]
-local item = [[ ]]
+local item = [[ ]]
local toc = [[
@@ -110,23 +108,6 @@ local toc = [[
]]
-local coverxhtml = [[
-
-
-
-
-
-
- cover.xhtml
-
-
-
-
-
-
-
-]]
-
-- We need to figure out what is permitted. Numbers only seem to give
-- problems is some applications as do names with dashes. Also the
-- optional toc is supposed to be there and although id's are by
@@ -136,7 +117,7 @@ local coverxhtml = [[
local function dumbid(filename)
-- return (string.gsub(os.uuid(),"%-%","")) -- to be tested
- return file.nameonly(filename) .. "-" .. file.suffix(filename)
+ return file.nameonly(filename) .. "-" .. file.extname(filename)
end
local mimetypes = {
@@ -147,7 +128,6 @@ local mimetypes = {
png = "image/png",
jpg = "image/jpeg",
ncx = "application/x-dtbncx+xml",
- gif = "image/gif",
-- default = "text/plain",
}
@@ -214,21 +194,9 @@ function scripts.epub.make()
local files = specification.files or { file.addsuffix(filename,"xhtml") }
local images = specification.images or { }
local root = specification.root or files[1]
- local language = specification.language or "en"
- local creator = specification.author or "My Self"
- local title = specification.title or "My Title"
- local firstpage = specification.firstpage or ""
- local lastpage = specification.lastpage or ""
-- identifier = gsub(identifier,"[^a-zA-z0-9]","")
- if firstpage ~= "" then
- images[firstpage] = firstpage
- end
- if lastpage ~= "" then
- images[lastpage] = lastpage
- end
-
identifier = "BookId" -- weird requirement
local epubname = name
@@ -236,12 +204,11 @@ function scripts.epub.make()
local epubfile = file.replacesuffix(name,"epub")
local epubroot = file.replacesuffix(name,"opf")
local epubtoc = "toc.ncx"
- local epubcover = "cover.xhtml"
application.report("creating paths in tree %s",epubpath)
lfs.mkdir(epubpath)
lfs.mkdir(file.join(epubpath,"META-INF"))
- lfs.mkdir(file.join(epubpath,"OEBPS"))
+ lfs.mkdir(file.join(epubpath,"OPS"))
local used = { }
@@ -250,14 +217,13 @@ function scripts.epub.make()
local mime = mimetypes[suffix]
if mime then
local idmaker = idmakers[suffix] or idmakers.default
- local target = file.join(epubpath,"OEBPS",filename)
+ local target = file.join(epubpath,"OPS",filename)
file.copy(filename,target)
application.report("copying %s to %s",filename,target)
used[#used+1] = format(item,idmaker(filename),filename,mime)
end
end
- copyone("cover.xhtml")
copyone("toc.ncx")
local function copythem(files)
@@ -275,7 +241,7 @@ function scripts.epub.make()
for k, v in table.sortedpairs(images) do
theimages[#theimages+1] = k
- if not lfs.isfile(k) and file.suffix(k) == "svg" and file.suffix(v) == "pdf" then
+ if not lfs.isfile(k) and file.extname(k) == "svg" and file.extname(v) == "pdf" then
local command = format("inkscape --export-plain-svg=%s %s",k,v)
application.report("running command '%s'\n\n",command)
os.execute(command)
@@ -284,52 +250,33 @@ function scripts.epub.make()
copythem(theimages)
- local idmaker = idmakers[file.suffix(root)] or idmakers.default
-
- container = format(container,
- epubroot
- )
- package = format(package,
- identifier,
- title,
- language,
- identifier,
- os.uuid(),
- creator,
- os.date("!%Y-%m-%dT%H:%M:%SZ"),
- idmaker(firstpage),
- concat(used,"\n"),
- idmaker(root)
- )
- toc = format(toc,
- identifier,
- title,
- root
- )
- coverxhtml = format(coverxhtml,
- firstpage
- )
+ local idmaker = idmakers[file.extname(root)] or idmakers.default
+
+ container = format(container,epubroot)
+ package = format(package,identifier,identifier,os.uuid(),os.date("!%Y-%m-%dT%H:%M:%SZ"),concat(used,"\n"),idmaker(root))
+ toc = format(toc,identifier,"title",root)
io.savedata(file.join(epubpath,"mimetype"),mimetype)
io.savedata(file.join(epubpath,"META-INF","container.xml"),container)
- io.savedata(file.join(epubpath,"OEBPS",epubroot),package)
- io.savedata(file.join(epubpath,"OEBPS",epubtoc),toc)
- io.savedata(file.join(epubpath,"OEBPS",epubcover),coverxhtml)
+ io.savedata(file.join(epubpath,"OPS",epubroot),package)
+ io.savedata(file.join(epubpath,"OPS",epubtoc),toc)
application.report("creating archive\n\n")
+ local done = false
+ local list = { }
+
lfs.chdir(epubpath)
os.remove(epubfile)
- local done = false
-
for i=1,#zippers do
local zipper = zippers[i]
if os.execute(format(zipper.uncompressed,epubfile,"mimetype")) then
os.execute(format(zipper.compressed,epubfile,"META-INF"))
- os.execute(format(zipper.compressed,epubfile,"OEBPS"))
+ os.execute(format(zipper.compressed,epubfile,"OPS"))
done = zipper.name
- break
+ else
+ list[#list+1] = zipper.name
end
end
@@ -338,10 +285,6 @@ function scripts.epub.make()
if done then
application.report("epub archive made using %s: %s",done,file.join(epubpath,epubfile))
else
- local list = { }
- for i=1,#zippers do
- list[#list+1] = zipper.name
- end
application.report("no epub archive made, install one of: %s",concat(list," "))
end
diff --git a/scripts/context/lua/mtx-fcd.lua b/scripts/context/lua/mtx-fcd.lua
deleted file mode 100644
index d7e1d17a7..000000000
--- a/scripts/context/lua/mtx-fcd.lua
+++ /dev/null
@@ -1,366 +0,0 @@
-if not modules then modules = { } end modules ['mtx-fcd'] = {
- version = 1.002,
- comment = "companion to mtxrun.lua",
- author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
- comment = "based on the ruby version from 2005",
-}
-
--- This is a kind of variant of the good old ncd (norton change directory) program. This
--- script uses the same indirect cmd trick as Erwin Waterlander's wcd program.
---
--- The program is called via the stubs fcd.cmd or fcd.sh. On unix one should probably source
--- the file: ". fcd args" in order to make the chdir persistent.
---
--- You need to create a stub with:
---
--- mtxrun --script fcd --stub > fcd.cmd
--- mtxrun --script fcd --stub > fcd.sh
---
--- The stub starts this script and afterwards runs the created directory change script as
--- part if the same run, so that indeed we change.
-
-local helpinfo = [[
---clear clear the cache
---clear --history [entry] clear the history
---scan clear the cache and add given path(s)
---add add given path(s)
---find file given path (can be substring)
---find --nohistory file given path (can be substring) but don't use history
---stub print platform stub file
---list show roots of cached dirs
---list --history show history of chosen dirs
---help show this help
-
-usage:
-
- fcd --scan t:\
- fcd --add f:\project
- fcd [--find] whatever
- fcd --list
-]]
-
-local application = logs.application {
- name = "mtx-fcd",
- banner = "Fast Directory Change",
- helpinfo = helpinfo,
-}
-
-local report = application.report
-local writeln = print -- texio.write_nl
-
-local find, char, byte, lower, gsub, format = string.find, string.char, string.byte, string.lower, string.gsub, string.format
-
-local mswinstub = [[@echo off
-
-rem this is: fcd.cmd
-
-@echo off
-
-if not exist "%HOME%" goto homepath
-
-:home
-
-mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
-
-if exist "%HOME%\mtx-fcd-goto.cmd" call "%HOME%\mtx-fcd-goto.cmd"
-
-goto end
-
-:homepath
-
-if not exist "%HOMEDRIVE%\%HOMEPATH%" goto end
-
-mtxrun --script mtx-fcd.lua %1 %2 %3 %4 %5 %6 %7 %8 %9
-
-if exist "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd" call "%HOMEDRIVE%\%HOMEPATH%\mtx-fcd-goto.cmd"
-
-goto end
-
-:end
-]]
-
-local unixstub = [[#!/usr/bin/env sh
-
-# this is: fcd.sh
-
-# mv fcd.sh fcd
-# chmod fcd 755
-# . fcd [args]
-
-ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
-
-if test -f "$HOME/fcd_stage.sh" ; then
- . $HOME/fcd_stage.sh ;
-fi;
-
-]]
-
-local gotofile
-local datafile
-local stubfile
-local stubdata
-local stubdummy
-local stubchdir
-
-if os.platform == 'mswin' then
- gotofile = 'mtx-fcd-goto.cmd'
- datafile = 'mtx-fcd-data.lua'
- stubfile = 'fcd.cmd'
- stubdata = mswinstub
- stubdummy = 'rem no dir to change to'
- stubchdir = 'cd /d "%s"'
-else
- gotofile = 'mtx-fcd-goto.sh'
- datafile = 'mtx-fcd-data.lua'
- stubfile = 'fcd.sh'
- stubdata = unixstub
- stubdummy = '# no dir to change to'
- stubchdir = '# cd "%s"'
-end
-
-local homedir = os.env["HOME"] or "" -- no longer TMP etc
-
-if homedir == "" then
- homedir = format("%s/%s",os.env["HOMEDRIVE"] or "",os.env["HOMEPATH"] or "")
-end
-
-if homedir == "/" or not lfs.isdir(homedir) then
- os.exit()
-end
-
-local datafile = file.join(homedir,datafile)
-local gotofile = file.join(homedir,gotofile)
-local hash = nil
-local found = { }
-local pattern = ""
-local version = modules['mtx-fcd'].version
-
-io.savedata(gotofile,stubdummy)
-
-if not lfs.isfile(gotofile) then
- -- write error
- os.exit()
-end
-
-local function fcd_clear(onlyhistory,what)
- if onlyhistory and hash and hash.history then
- if what and what ~= "" then
- hash.history[what] = nil
- else
- hash.history = { }
- end
- else
- hash = {
- name = "fcd cache",
- comment = "generated by mtx-fcd.lua",
- created = os.date(),
- version = version,
- paths = { },
- history = { },
- }
- end
-end
-
-local function fcd_changeto(dir)
- if dir and dir ~= "" then
- io.savedata(gotofile,format(stubchdir,dir))
- end
-end
-
-local function fcd_load(forcecreate)
- if lfs.isfile(datafile) then
- hash = dofile(datafile)
- end
- if not hash or hash.version ~= version then
- if forcecache then
- fcd_clear()
- else
- writeln("empty dir cache")
- fcd_clear()
- os.exit()
- end
- end
-end
-
-local function fcd_save()
- if hash then
- io.savedata(datafile,table.serialize(hash,true))
- end
-end
-
-local function fcd_list(onlyhistory)
- if hash then
- writeln("")
- if onlyhistory then
- if next(hash.history) then
- for k, v in table.sortedhash(hash.history) do
- writeln(format("%s => %s",k,v))
- end
- else
- writeln("no history")
- end
- else
- local paths = hash.paths
- if #paths > 0 then
- for i=1,#paths do
- local path = paths[i]
- writeln(format("%4i %s",#path[2],path[1]))
- end
- else
- writeln("empty cache")
- end
- end
- end
-end
-
-local function fcd_find()
- found = { }
- pattern = environment.files[1] or ""
- if pattern ~= "" then
- pattern = string.escapedpattern(pattern)
- local paths = hash.paths
- for i=1,#paths do
- local paths = paths[i][2]
- for i=1,#paths do
- local path = paths[i]
- if find(path,pattern) then
- found[#found+1] = path
- end
- end
- end
- end
-end
-
-local function fcd_choose(new)
- if pattern == "" then
- writeln(format("staying in dir %q",(gsub(lfs.currentdir(),"\\","/"))))
- return
- end
- if #found == 0 then
- writeln(format("dir %q not found",pattern))
- return
- end
- local okay = #found == 1 and found[1] or (not new and hash.history[pattern])
- if okay then
- writeln(format("changing to %q",okay))
- fcd_changeto(okay)
- return
- end
- local offset = 0
- while true do
- if not found[offset] then
- offset = 0
- end
- io.write("\n")
- for i=1,26 do
- local v = found[i+offset]
- if v then
- writeln(format("%s %3i %s",char(i+96),offset+i,v))
- else
- break
- end
- end
- offset = offset + 26
- if found[offset+1] then
- io.write("\n[press enter for more or select letter]\n\n>> ")
- else
- io.write("\n[select letter]\n\n>> ")
- end
- local answer = lower(io.read() or "")
- if not answer or answer == 'quit' then
- break
- elseif #answer > 0 then
- local choice = tonumber(answer)
- if not choice then
- if answer >= "a" and answer <= "z" then
- choice = byte(answer) - 96 + offset - 26
- end
- end
- local newdir = found[choice]
- if newdir then
- hash.history[pattern] = newdir
- writeln(format("changing to %q",newdir))
- fcd_changeto(newdir)
- fcd_save()
- return
- end
- else
- -- try again
- end
- end
-end
-
-local function globdirs(path,dirs)
- local dirs = dirs or { }
- for name in lfs.dir(path) do
- if not find(name,"%.$") then
- local fullname = path .. "/" .. name
- if lfs.isdir(fullname) and not find(fullname,"/%.") then
- dirs[#dirs+1] = fullname
- globdirs(fullname,dirs)
- end
- end
- end
- return dirs
-end
-
-local function fcd_scan()
- if hash then
- local paths = hash.paths
- for i=1,#environment.files do
- local name = environment.files[i]
- local name = gsub(name,"\\","/")
- local name = gsub(name,"/$","")
- local list = globdirs(name)
- local done = false
- for i=1,#paths do
- if paths[i][1] == name then
- paths[i][2] = list
- done = true
- break
- end
- end
- if not done then
- paths[#paths+1] = { name, list }
- end
- end
- end
-end
-
-local argument = environment.argument
-
-if argument("clear") then
- if argument("history") then
- fcd_load()
- fcd_clear(true)
- else
- fcd_clear()
- end
- fcd_save()
-elseif argument("scan") then
- fcd_clear()
- fcd_scan()
- fcd_save()
-elseif argument("add") then
- fcd_load(true)
- fcd_scan()
- fcd_save()
-elseif argument("stub") then
- writeln(stubdata)
-elseif argument("list") then
- fcd_load()
- if argument("history") then
- fcd_list(true)
- else
- fcd_list()
- end
-elseif argument("help") then
- application.help()
-else -- also argument("find")
- fcd_load()
- fcd_find()
- fcd_choose(argument("nohistory"))
-end
-
diff --git a/scripts/context/lua/mtx-flac.lua b/scripts/context/lua/mtx-flac.lua
index cb73a6592..37f985654 100644
--- a/scripts/context/lua/mtx-flac.lua
+++ b/scripts/context/lua/mtx-flac.lua
@@ -6,6 +6,12 @@ if not modules then modules = { } end modules ['mtx-flac'] = {
license = "see context related readme files"
}
+-- Written with Within Temptation's "The Unforgiven" in loopmode on
+-- the speakers. The following code is also used for my occasional music
+-- repository cleanup session using the code below.
+
+-- this can become l-flac.lua
+
local sub, match, byte, lower = string.sub, string.match, string.byte, string.lower
local readstring, readnumber = io.readstring, io.readnumber
local concat = table.concat
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 31ee18ce9..c5b458c14 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -126,7 +126,7 @@ function fonts.names.simple()
end
report("saving names in '%s'",name)
io.savedata(name,table.serialize(simplified,true))
- local data = io.loaddata(resolvers.findfile("luatex-fonts-syn.lua","tex")) or ""
+ local data = io.loaddata(resolvers.findfile("font-dum.lua","tex"))
local dummy = string.match(data,"fonts%.names%.version%s*=%s*([%d%.]+)")
if tonumber(dummy) ~= simpleversion then
report("warning: version number %s in 'font-dum' does not match database version number %s",dummy or "?",simpleversion)
@@ -367,7 +367,7 @@ function scripts.fonts.save()
if name and name ~= "" then
local filename = resolvers.findfile(name) -- maybe also search for opentype
if filename and filename ~= "" then
- local suffix = string.lower(file.suffix(filename))
+ local suffix = string.lower(file.extname(filename))
if suffix == 'ttf' or suffix == 'otf' or suffix == 'ttc' or suffix == "dfont" then
local fontinfo = fontloader.info(filename)
if fontinfo then
diff --git a/scripts/context/lua/mtx-grep.lua b/scripts/context/lua/mtx-grep.lua
index 98a97279d..3cbc1421a 100644
--- a/scripts/context/lua/mtx-grep.lua
+++ b/scripts/context/lua/mtx-grep.lua
@@ -60,7 +60,7 @@ function scripts.grep.find(pattern, files, offset)
if m > 0 then
nofmatches = nofmatches + m
nofmatchedfiles = nofmatchedfiles + 1
- write_nl(format("%5i %s",m,name))
+ write_nl(format("%s: %s",name,m))
io.flush()
end
else
@@ -127,7 +127,7 @@ function scripts.grep.find(pattern, files, offset)
if count and m > 0 then
nofmatches = nofmatches + m
nofmatchedfiles = nofmatchedfiles + 1
- write_nl(format("%5i %s",m,name))
+ write_nl(format("%s: %s",name,m))
io.flush()
end
end
diff --git a/scripts/context/lua/mtx-metapost.lua b/scripts/context/lua/mtx-metapost.lua
index 44cf8205d..3b9ed6ff1 100644
--- a/scripts/context/lua/mtx-metapost.lua
+++ b/scripts/context/lua/mtx-metapost.lua
@@ -49,7 +49,7 @@ local tempname = "mptopdf-temp.tex"
local function do_convert(filename)
if find(filename,".%d+$") or find(filename,"%.mps$") then
io.savedata(tempname,format(template,filename))
- local resultname = format("%s-%s.pdf",file.nameonly(filename),file.suffix(filename))
+ local resultname = format("%s-%s.pdf",file.nameonly(filename),file.extname(filename))
local result = os.execute(format([[context --once --batch --purge --result=%s "%s"]],resultname,tempname))
return lfs.isfile(resultname) and resultname
end
diff --git a/scripts/context/lua/mtx-pdf.lua b/scripts/context/lua/mtx-pdf.lua
index f37ee006a..5654b8bc4 100644
--- a/scripts/context/lua/mtx-pdf.lua
+++ b/scripts/context/lua/mtx-pdf.lua
@@ -6,21 +6,14 @@ if not modules then modules = { } end modules ['mtx-pdf'] = {
license = "see context related readme files"
}
-local tonumber = tonumber
-local format, gmatch = string.format, string.gmatch
-local utfchar = utf.char
-local concat = table.concat
-local setmetatableindex, sortedhash, sortedkeys = table.setmetatableindex, table.sortedhash, table.sortedkeys
-
local helpinfo = [[
--info show some info about the given file
--metadata show metadata xml blob
---fonts show used fonts (--detail)
]]
local application = logs.application {
name = "mtx-pdf",
- banner = "ConTeXt PDF Helpers 0.10",
+ banner = "ConTeXt PDF Helpers 0.01",
helpinfo = helpinfo,
}
@@ -46,8 +39,9 @@ local function loadpdffile(filename)
end
end
-function scripts.pdf.info(filename)
- local pdffile = loadpdffile(filename)
+function scripts.pdf.info()
+ local filename = environment.files[1]
+ local pdffile = loadpdffile(filename)
if pdffile then
local catalog = pdffile.Catalog
local info = pdffile.Info
@@ -79,8 +73,9 @@ function scripts.pdf.info(filename)
end
end
-function scripts.pdf.metadata(filename)
- local pdffile = loadpdffile(filename)
+function scripts.pdf.metadata()
+ local filename = environment.files[1]
+ local pdffile = loadpdffile(filename)
if pdffile then
local catalog = pdffile.Catalog
local metadata = catalog.Metadata
@@ -92,127 +87,10 @@ function scripts.pdf.metadata(filename)
end
end
-local function getfonts(pdffile)
- local usedfonts = { }
- for i=1,pdffile.pages.n do
- local page = pdffile.pages[i]
- local fontlist = page.Resources.Font
- for k, v in next, lpdf.epdf.expand(fontlist) do
- usedfonts[k] = lpdf.epdf.expand(v)
- end
- end
- return usedfonts
-end
-
-local function getunicodes(font)
- local cid = font.ToUnicode
- if cid then
- cid = cid()
- local counts = { }
- -- for s in gmatch(cid,"begincodespacerange%s*(.-)%s*endcodespacerange") do
- -- for a, b in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
- -- print(a,b)
- -- end
- -- end
- setmetatableindex(counts, function(t,k) t[k] = 0 return 0 end)
- for s in gmatch(cid,"beginbfrange%s*(.-)%s*endbfrange") do
- for first, last, offset in gmatch(s,"<([^>]+)>%s+<([^>]+)>%s+<([^>]+)>") do
- first = tonumber(first,16)
- last = tonumber(last,16)
- offset = tonumber(offset,16)
- offset = offset - first
- for i=first,last do
- local c = i + offset
- counts[c] = counts[c] + 1
- end
- end
- end
- for s in gmatch(cid,"beginbfchar%s*(.-)%s*endbfchar") do
- for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do
- for n in gmatch(new,"....") do
- local c = tonumber(n,16)
- counts[c] = counts[c] + 1
- end
- end
- end
- return counts
- end
-end
-
-function scripts.pdf.fonts(filename)
- local pdffile = loadpdffile(filename)
- if pdffile then
- local usedfonts = getfonts(pdffile)
- local found = { }
- for k, v in table.sortedhash(usedfonts) do
- local counts = getunicodes(v)
- local codes = { }
- local chars = { }
- local freqs = { }
- if counts then
- codes = sortedkeys(counts)
- for i=1,#codes do
- local k = codes[i]
- local c = utfchar(k)
- chars[i] = c
- freqs[i] = format("U+%05X %s %s",k,counts[k] > 1 and "+" or " ", c)
- end
- for i=1,#codes do
- codes[i] = format("U+%05X",codes[i])
- end
- end
- found[k] = {
- basefont = v.BaseFont or "no basefont",
- encoding = v.Encoding or "no encoding",
- subtype = v.Subtype or "no subtype",
- unicode = v.ToUnicode and "unicode" or "no unicode",
- chars = chars,
- codes = codes,
- freqs = freqs,
- }
- end
-
- if environment.argument("detail") then
- for k, v in sortedhash(found) do
- report("id : %s",k)
- report("basefont : %s",v.basefont)
- report("encoding : %s",v.encoding)
- report("subtype : %s",v.subtype)
- report("unicode : %s",v.unicode)
- report("characters : %s", concat(v.chars," "))
- report("codepoints : %s", concat(v.codes," "))
- report("")
- end
- else
- local results = { { "id", "basefont", "encoding", "subtype", "unicode", "characters" } }
- for k, v in sortedhash(found) do
- results[#results+1] = { k, v.basefont, v.encoding, v.subtype, v.unicode, concat(v.chars," ") }
- end
- utilities.formatters.formatcolumns(results)
- report(results[1])
- report("")
- for i=2,#results do
- report(results[i])
- end
- report("")
- end
- end
-end
-
--- scripts.pdf.info("e:/tmp/oeps.pdf")
--- scripts.pdf.metadata("e:/tmp/oeps.pdf")
--- scripts.pdf.fonts("e:/tmp/oeps.pdf")
-
-local filename = environment.files[1] or ""
-
-if filename == "" then
- application.help()
-elseif environment.argument("info") then
- scripts.pdf.info(filename)
+if environment.argument("info") then
+ scripts.pdf.info()
elseif environment.argument("metadata") then
- scripts.pdf.metadata(filename)
-elseif environment.argument("fonts") then
- scripts.pdf.fonts(filename)
+ scripts.pdf.metadata()
else
application.help()
end
diff --git a/scripts/context/lua/mtx-scite.lua b/scripts/context/lua/mtx-scite.lua
index 3369c5f3b..116555e79 100644
--- a/scripts/context/lua/mtx-scite.lua
+++ b/scripts/context/lua/mtx-scite.lua
@@ -199,31 +199,14 @@ function scripts.scite.words()
if lfs.isfile(txtname) then
report("loading %s",txtname)
local olddata = io.loaddata(txtname) or ""
- local words = splitwords(olddata)
- local min, max, n = 100, 1, 0
- for k, v in next, words do
- local l = #k
- if l < min then
- min = l
- end
- if l > max then
- max = l
- end
- n = n + 1
- end
- if min > max then
- min = max
- end
local newdata = {
- words = words,
+ words = splitwords(olddata),
+ -- words = olddata,
source = oldname,
- min = min,
- max = max,
- n = n,
}
- report("saving %q, %s words, %s shortest, %s longest",luaname,n,min,max)
+ report("saving %s",luaname)
io.savedata(luaname,table.serialize(newdata,true))
- report("compiling %q",lucname)
+ report("compiling %s",lucname)
os.execute(format("luac -s -o %s %s",lucname,luaname))
else
report("no data file %s",txtname)
diff --git a/scripts/context/lua/mtx-server-ctx-help.lua b/scripts/context/lua/mtx-server-ctx-help.lua
index 39a73dc4e..a212e1369 100644
--- a/scripts/context/lua/mtx-server-ctx-help.lua
+++ b/scripts/context/lua/mtx-server-ctx-help.lua
@@ -15,7 +15,7 @@ dofile(resolvers.findfile("trac-lmx.lua","tex"))
-- problem ... serialize parent stack
-local format, match, gsub, find = string.format, string.match, string.gsub, string.find
+local format = string.format
local concat = table.concat
local report = logs.reporter("ctx-help")
@@ -282,48 +282,18 @@ document.setups.translations = document.setups.translations or {
}
document.setups.formats = {
- open_command = {
- tex = [[\%s]],
- lua = [[context.%s (]],
- },
- close_command = {
- tex = [[]],
- lua = [[ )]],
- },
- connector = {
- tex = [[]],
- lua = [[, ]],
- },
- href_in_list = {
- tex = [[%s]],
- lua = [[%s]],
- },
- href_as_command = {
- tex = [[\%s]],
- lua = [[context.%s]],
- },
- modes = {
- tex = [[lua mode]],
- lua = [[tex mode]],
- },
- optional_single = {
- tex = "[optional string %s]",
- lua = "{optional string %s}",
- },
- optional_list = {
- tex = "[optional list %s]",
- lua = "{optional table %s}" ,
- } ,
- mandate_single = {
- tex = "[mandate string %s]",
- lua = "{mandate string %s}",
- },
- mandate_list = {
- tex = "[mandate list %s]",
- lua = "{mandate list %s}",
- },
+ open_command = { [[\%s]], [[context.%s (]] },
+ close_command = { [[]], [[ )]] },
+ connector = { [[]], [[, ]] },
+ href_in_list = { [[%s]], [[%s]] },
+ href_as_command = { [[\%s]], [[context.%s]] },
interface = [[%s]],
source = [[%s]],
+ modes = { [[lua mode]], [[tex mode]] },
+ optional_single = { "[optional string %s]", "{optional string %s}" },
+ optional_list = { "[optional list %s]", "{optional table %s}" } ,
+ mandate_single = { "[mandate string %s]", "{mandate string %s}" },
+ mandate_list = { "[mandate list %s]", "{mandate list %s}" },
parameter = [[
%s
%s
%s
]],
parameters = [[
%s
]],
listing = [[
%s]],
@@ -345,7 +315,7 @@ end
local function translated(e,int)
local attributes = e.at
local s = attributes.type or "?"
- local tag = match(s,"^cd:(.*)$")
+ local tag = s:match("^cd:(.*)$")
if attributes.default == "yes" then
return format(document.setups.formats.default,tag or "?")
elseif tag then
@@ -359,7 +329,7 @@ document.setups.loaded = document.setups.loaded or { }
document.setups.current = { }
document.setups.showsources = true
-document.setups.mode = "tex"
+document.setups.mode = 1
function document.setups.load(filename)
filename = resolvers.findfile(filename) or ""
@@ -432,7 +402,7 @@ end
function document.setups.show(name)
local current = document.setups.current
if current.root then
- local name = gsub(name,"[<>]","")
+ local name = name:gsub("[<>]","")
local setup = xml.first(current.root,"cd:command[@name='" .. name .. "']")
current.used[#current.used+1] = setup
xml.sprint(setup)
@@ -482,12 +452,12 @@ function document.setups.collect(name,int,lastmode)
category = attributes.category or "",
}
if document.setups.showsources then
- data.source = (attributes.file and format(formats.source,attributes.file,lastmode,attributes.file)) or ""
+ data.source = (attributes.file and formats.source:format(attributes.file,lastmode,attributes.file)) or ""
else
data.source = attributes.file or ""
end
local n, sequence, tags = 0, { }, { }
- sequence[#sequence+1] = format(formats.open_command[lastmode],document.setups.csname(command,int))
+ sequence[#sequence+1] = formats.open_command[lastmode]:format(document.setups.csname(command,int))
local arguments, tag = { }, ""
for r, d, k in xml.elements(command,"(cd:keywords|cd:assignments)") do
n = n + 1
@@ -500,15 +470,15 @@ function document.setups.collect(name,int,lastmode)
end
if attributes.optional == 'yes' then
if attributes.list == 'yes' then
- tag = format(formats.optional_list[lastmode],n)
+ tag = formats.optional_list[lastmode]:format(n)
else
- tag = format(formats.optional_single[lastmode],n)
+ tag = formats.optional_single[lastmode]:format(n)
end
else
if attributes.list == 'yes' then
- tag = format(formats.mandate_list[lastmode],n)
+ tag = formats.mandate_list[lastmode]:format(n)
else
- tag = format(formats.mandate_single[lastmode],n)
+ tag = formats.mandate_single[lastmode]:format(n)
end
end
sequence[#sequence+1] = tag
@@ -536,7 +506,7 @@ function document.setups.collect(name,int,lastmode)
right[#right+1] = translated(d[k],int)
end
end
- parameters[#parameters+1] = format(formats.parameter,left,"",concat(right, ", "))
+ parameters[#parameters+1] = formats.parameter:format(left,"",concat(right, ", "))
else
local what = tags[n]
for r, d, k in xml.elements(d[k],"(cd:parameter|cd:inherit)") do
@@ -544,11 +514,11 @@ function document.setups.collect(name,int,lastmode)
local left, right = d[k].at.name or "?", { }
if tag == "inherit" then
local name = d[k].at.name or "?"
- local goto = format(document.setups.formats.href_as_command[lastmode],name,lastmode,name)
- if #parameters > 0 and not find(parameters[#parameters]," ") then
- parameters[#parameters+1] = format(formats.parameter," ","","")
+ local goto = document.setups.formats.href_as_command[lastmode]:format(name,lastmode,name)
+ if #parameters > 0 and not parameters[#parameters]:find(" ") then
+ parameters[#parameters+1] = formats.parameter:format(" ","","")
end
- parameters[#parameters+1] = format(formats.parameter,what,format(formats.special,translate("inherits",int)),goto)
+ parameters[#parameters+1] = formats.parameter:format(what,formats.special:format(translate("inherits",int)),goto)
else
for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do
local tag = d[k].tg
@@ -564,15 +534,15 @@ function document.setups.collect(name,int,lastmode)
right[#right+1] = translated(d[k],int)
end
end
- parameters[#parameters+1] = format(formats.parameter,what,left,concat(right, ", "))
+ parameters[#parameters+1] = formats.parameter:format(what,left,concat(right, ", "))
end
what = ""
end
end
- parameters[#parameters+1] = format(formats.parameter," ","","")
+ parameters[#parameters+1] = formats.parameter:format(" ","","")
end
data.parameters = parameters or { }
- data.mode = formats.modes[lastmode or "tex"]
+ data.mode = formats.modes[lastmode or 1]
return data
else
return nil
@@ -596,7 +566,7 @@ local interfaces = {
romanian = 'ro',
}
-local lastinterface, lastcommand, lastsource, lastmode = "en", "", "", "tex"
+local lastinterface, lastcommand, lastsource, lastmode = "en", "", "", 1
local variables = {
['color-background-main-left'] = '#3F3F3F',
@@ -614,87 +584,78 @@ local function doit(configuration,filename,hashed)
local formats = document.setups.formats
- local start = os.clock()
- local detail = hashed.queries
+ local start = os.clock()
- if detail then
+ local detail = url.query(hashed.query or "")
- lastinterface = detail.interface or lastinterface
- lastcommand = detail.command or lastcommand
- lastsource = detail.source or lastsource
- lastmode = detail.mode or lastmode or "tex"
+ lastinterface = detail.interface or lastinterface
+ lastcommand = detail.command or lastcommand
+ lastsource = detail.source or lastsource
+ lastmode = tonumber(detail.mode or lastmode) or 1
- lastcommand = gsub(lastcommand,"%s*^\\*(.+)%s*","%1")
+ if lastinterface then
+ report("checking interface: %s",lastinterface)
+ document.setups.load(format("cont-%s.xml",lastinterface))
+ end
- if lastinterface then
- report("checking interface: %s",lastinterface)
- document.setups.load(format("cont-%s.xml",lastinterface))
- end
+ local div = document.setups.div[lastinterface]
+ local span = document.setups.span[lastinterface]
- local div = document.setups.div [lastinterface]
- local span = document.setups.span[lastinterface]
+ local result = { content = "error" }
- local names, refs, ints = document.setups.names(lastinterface), { }, { }
- for k=1,#names do
- local v = names[k]
- refs[k] = format(formats.href_in_list[lastmode],v[1],lastmode,v[2])
- end
- if lastmode ~= "lua" then
- local sorted = table.sortedkeys(interfaces)
- for k=1,#sorted do
- local v = sorted[k]
- ints[k] = format(formats.interface,interfaces[v],lastmode,v)
- end
+ local names, refs, ints = document.setups.names(lastinterface), { }, { }
+ for k=1,#names do
+ local v = names[k]
+ refs[k] = formats.href_in_list[lastmode]:format(v[1],lastmode,v[2])
+ end
+ if lastmode ~= 2 then
+ local sorted = table.sortedkeys(interfaces)
+ for k=1,#sorted do
+ local v = sorted[k]
+ ints[k] = formats.interface:format(interfaces[v],lastmode,v)
end
+ end
- local n = concat(refs," ")
- local i = concat(ints,"
")
+ local n = concat(refs," ")
+ local i = concat(ints,"
")
- if div then
- variables.names = format(div,n)
- variables.interfaces = format(div,i)
- else
- variables.names = n
- variables.interfaces = i
- end
+ if div then
+ variables.names = div:format(n)
+ variables.interfaces = div:format(i)
+ else
+ variables.names = n
+ variables.interfaces = i
+ end
- -- first we need to add information about mkii/mkiv
-
- variables.maintitle = "no definition"
- variables.maintext = ""
- variables.extra = ""
-
- if document.setups.showsources and lastsource and lastsource ~= "" then
- -- todo: mkii, mkiv, tex (can be different)
- local data = io.loaddata(resolvers.findfile(lastsource))
- variables.maintitle = lastsource
- variables.maintext = format(formats.listing,data)
- lastsource = ""
- elseif lastcommand and lastcommand ~= "" then
- local data = document.setups.collect(lastcommand,lastinterface,lastmode)
- if data then
- local what, extra = { "environment", "category", "source", "mode" }, { }
- for k=1,#what do
- local v = what[k]
- if data[v] and data[v] ~= "" then
- lmx.set(v, data[v])
- extra[#extra+1] = v .. ": " .. data[v]
- end
+ -- first we need to add information about mkii/mkiv
+
+ variables.maintitle = "no definition"
+ variables.maintext = ""
+ variables.extra = ""
+
+ if document.setups.showsources and lastsource and lastsource ~= "" then
+ -- todo: mkii, mkiv, tex (can be different)
+ local data = io.loaddata(resolvers.findfile(lastsource))
+ variables.maintitle = lastsource
+ variables.maintext = formats.listing:format(data)
+ lastsource = ""
+ elseif lastcommand and lastcommand ~= "" then
+ local data = document.setups.collect(lastcommand,lastinterface,lastmode)
+ if data then
+ local what, extra = { "environment", "category", "source", "mode" }, { }
+ for k=1,#what do
+ local v = what[k]
+ if data[v] and data[v] ~= "" then
+ lmx.set(v, data[v])
+ extra[#extra+1] = v .. ": " .. data[v]
end
- variables.maintitle = data.sequence
- variables.maintext = format(formats.parameters,concat(data.parameters))
- variables.extra = concat(extra," ")
- else
- variables.maintext = "select command"
end
+ variables.maintitle = data.sequence
+ variables.maintext = formats.parameters:format(concat(data.parameters))
+ variables.extra = concat(extra," ")
+ else
+ variables.maintext = "select command"
end
-
- else
-
- variables.maintitle = "no definition"
- variables.maintext = "some error"
- variables.extra = ""
-
end
local content = lmx.convert('context-help.lmx',false,variables)
diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua
index d6e8ac902..068d51111 100644
--- a/scripts/context/lua/mtx-server.lua
+++ b/scripts/context/lua/mtx-server.lua
@@ -30,7 +30,7 @@ dofile(resolvers.findfile("l-url.lua","tex"))
dofile(resolvers.findfile("luat-soc.lua","tex"))
local socket = socket or require("socket")
-local http = http or require("socket.http") -- not needed
+local http = socket or require("socket.http")
local format = string.format
-- The following two lists are taken from webrick (ruby) and
@@ -231,7 +231,6 @@ function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) --
end
if result then
if type(result) == "function" then
- report("running script: %s",filename)
result = result(configuration,filename,hashed) -- second argument will become query
end
if result and type(result) == "string" then
@@ -243,7 +242,7 @@ function handlers.lua(client,configuration,filename,suffix,iscontent,hashed) --
local action = handlers[suffix] or handlers.generic
action(client,configuration,result.content,suffix,true) -- content
elseif result.filename then
- local suffix = file.suffix(result.filename) or "text/html"
+ local suffix = file.extname(result.filename) or "text/html"
local action = handlers[suffix] or handlers.generic
action(client,configuration,result.filename,suffix,false) -- filename
else
@@ -302,50 +301,40 @@ function scripts.webserver.run(configuration)
report("scripts subpath: %s",configuration.scripts)
report("context services: http://localhost:%s/mtx-server-ctx-startup.lua",configuration.port)
local server = assert(socket.bind("*", configuration.port))
- local script = configuration.script
- while true do -- blocking
+-- local reading = { server }
+ while true do -- no multiple clients
local start = os.clock()
+-- local input = socket.select(reading)
+-- local client = input:accept()
local client = server:accept()
client:settimeout(configuration.timeout or 60)
local request, e = client:receive()
+-- local request, e = client:receive("*a") -- doesn't work well (so no post)
if e then
errormessage(client,configuration,404)
else
local from = client:getpeername()
report("request from: %s",tostring(from))
- report("request data: %s",tostring(request))
- local fullurl = string.match(request,"GET (.+) HTTP/.*$") or "" -- todo: more clever / post
+ local fullurl = request:match("GET (.+) HTTP/.*$") or "" -- todo: more clever / post
if fullurl == "" then
- report("no url")
errormessage(client,configuration,404)
else
- report("requested url: %s",fullurl)
- fullurl = socket.url.unescape(fullurl) -- still needed?
+ fullurl = socket.url.unescape(fullurl)
local hashed = url.hashed(fullurl)
local query = url.query(hashed.query)
- local filename = hashed.path -- hm, not query?
- if script then
- filename = script
- report("forced script: %s",filename)
- local suffix = file.suffix(filename)
- local action = handlers[suffix] or handlers.generic
- if action then
- report("performing action: %s",filename)
- action(client,configuration,filename,suffix,false,hashed) -- filename and no content
- else
- errormessage(client,configuration,404)
- end
- elseif filename then
+ local filename = hashed.path
+-- table.print(hashed)
+ if filename then
filename = socket.url.unescape(filename)
report("requested action: %s",filename)
- if string.find(filename,"%.%.") then
+ if filename:find("%.%.") then
filename = nil -- invalid path
end
if filename == nil or filename == "" or filename == "/" then
filename = configuration.index
report("invalid filename, forcing: %s",filename)
end
- local suffix = file.suffix(filename)
+ local suffix = file.extname(filename)
local action = handlers[suffix] or handlers.generic
if action then
report("performing action: %s",filename)
@@ -369,7 +358,6 @@ if environment.argument("auto") then
port = environment.argument("port"),
root = environment.argument("root") or file.dirname(path) or ".",
scripts = environment.argument("scripts") or file.dirname(path) or ".",
- script = environment.argument("script"),
}
elseif environment.argument("start") then
scripts.webserver.run {
@@ -377,7 +365,6 @@ elseif environment.argument("start") then
root = environment.argument("root") or ".", -- "e:/websites/www.pragma-ade.com",
index = environment.argument("index"),
scripts = environment.argument("scripts"),
- script = environment.argument("script"),
}
else
application.help()
diff --git a/scripts/context/lua/mtx-tools.lua b/scripts/context/lua/mtx-tools.lua
index c1aaf9e5d..45961a639 100644
--- a/scripts/context/lua/mtx-tools.lua
+++ b/scripts/context/lua/mtx-tools.lua
@@ -102,7 +102,7 @@ end
function scripts.tools.dirtoxml()
- local join, removesuffix, suffixonly, date = file.join, file.removesuffix, file.suffixonly, os.date
+ local join, removesuffix, extname, date = file.join, file.removesuffix, file.extname, os.date
local xmlns = "http://www.pragma-ade.com/rlg/xmldir.rng"
local timestamp = "%Y-%m-%d %H:%M"
diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua
index b5f34d615..037de8650 100644
--- a/scripts/context/lua/mtx-update.lua
+++ b/scripts/context/lua/mtx-update.lua
@@ -421,9 +421,9 @@ function scripts.update.synchronize()
if platform == 'mswin' then
bin = gsub(bin,"([a-zA-Z]):/", "/cygdrive/%1/")
texroot = gsub(texroot,"([a-zA-Z]):/", "/cygdrive/%1/")
- command = format([[%s -t "%s/texmf-context/scripts/context/lua/%s.lua" "%s/texmf-mswin/bin/"]], bin, texroot, script, texroot)
+ command = format("%s -t %s/texmf-context/scripts/context/lua/%s.lua %s/texmf-mswin/bin/", bin, texroot, script, texroot)
else
- command = format([[%s -tgo --chmod=a+x '%s/texmf-context/scripts/context/lua/%s.lua' '%s/texmf-%s/bin/%s']], bin, texroot, script, texroot, platform, script)
+ command = format("%s -tgo --chmod=a+x %s/texmf-context/scripts/context/lua/%s.lua %s/texmf-%s/bin/%s", bin, texroot, script, texroot, platform, script)
end
report("updating %s for %s: %s", script, platform, command)
scripts.update.run(command)
diff --git a/scripts/context/lua/mtx-watch.lua b/scripts/context/lua/mtx-watch.lua
index 31ed95f7b..36a3176c4 100644
--- a/scripts/context/lua/mtx-watch.lua
+++ b/scripts/context/lua/mtx-watch.lua
@@ -227,6 +227,17 @@ function scripts.watch.watch()
end
end
local n, start = 0, time()
+--~ local function wait()
+--~ io.flush()
+--~ if not done then
+--~ n = n + 1
+--~ if n >= 10 then
+--~ report("run time: %i seconds, memory usage: %0.3g MB", difftime(time(),start), (status.luastate_bytes/1024)/1000)
+--~ n = 0
+--~ end
+--~ os.sleep(delay)
+--~ end
+--~ end
local wtime = 0
local function wait()
io.flush()
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index e6bbbe2b5..108f2a8a1 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -8,11 +8,6 @@ if not modules then modules = { } end modules ['mtxrun'] = {
license = "see context related readme files"
}
--- if not lpeg then require("lpeg") end
--- if not md5 then require("md5") end
--- if not lfs then require("lfs") end
--- if not texconfig then texconfig = { } end
-
-- one can make a stub:
--
-- #!/bin/sh
@@ -155,28 +150,11 @@ function string.topattern(str,lowercase,strict)
end
end
-
-function string.valid(str,default)
- return (type(str) == "string" and str ~= "" and str) or default or nil
-end
-
-- obsolete names:
string.quote = string.quoted
string.unquote = string.unquoted
--- handy fallback
-
-string.itself = function(s) return s end
-
--- also handy (see utf variant)
-
-local pattern = Ct(C(1)^0)
-
-function string.totable(str)
- return lpegmatch(pattern,str)
-end
-
end -- of closure
@@ -190,8 +168,7 @@ if not modules then modules = { } end modules ['l-table'] = {
license = "see context related readme files"
}
-local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs
-local table, string = table, string
+local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
@@ -202,8 +179,6 @@ local getinfo = debug.getinfo
-- impact on ConTeXt was not that large; the remaining ipairs already
-- have been replaced. In a similar fashion we also hardly used pairs.
--
--- Hm, actually ipairs was retained, but we no longer use it anyway.
---
-- Just in case, we provide the fallbacks as discussed in Programming
-- in Lua (http://www.lua.org/pil/7.3.html):
@@ -263,16 +238,12 @@ function table.strip(tab)
end
function table.keys(t)
- if t then
- local keys, k = { }, 0
- for key, _ in next, t do
- k = k + 1
- keys[k] = key
- end
- return keys
- else
- return { }
+ local keys, k = { }, 0
+ for key, _ in next, t do
+ k = k + 1
+ keys[k] = key
end
+ return keys
end
local function compare(a,b)
@@ -285,49 +256,41 @@ local function compare(a,b)
end
local function sortedkeys(tab)
- if tab then
- local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
- for key,_ in next, tab do
- s = s + 1
- srt[s] = key
- if category == 3 then
- -- no further check
+ local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
+ for key,_ in next, tab do
+ s = s + 1
+ srt[s] = key
+ if category == 3 then
+ -- no further check
+ else
+ local tkey = type(key)
+ if tkey == "string" then
+ category = (category == 2 and 3) or 1
+ elseif tkey == "number" then
+ category = (category == 1 and 3) or 2
else
- local tkey = type(key)
- if tkey == "string" then
- category = (category == 2 and 3) or 1
- elseif tkey == "number" then
- category = (category == 1 and 3) or 2
- else
- category = 3
- end
+ category = 3
end
end
- if category == 0 or category == 3 then
- sort(srt,compare)
- else
- sort(srt)
- end
- return srt
+ end
+ if category == 0 or category == 3 then
+ sort(srt,compare)
else
- return { }
+ sort(srt)
end
+ return srt
end
local function sortedhashkeys(tab) -- fast one
- if tab then
- local srt, s = { }, 0
- for key,_ in next, tab do
- if key then
- s= s + 1
- srt[s] = key
- end
+ local srt, s = { }, 0
+ for key,_ in next, tab do
+ if key then
+ s= s + 1
+ srt[s] = key
end
- sort(srt)
- return srt
- else
- return { }
end
+ sort(srt)
+ return srt
end
table.sortedkeys = sortedkeys
@@ -352,7 +315,7 @@ end
table.sortedhash = sortedhash
table.sortedpairs = sortedhash
-function table.append(t,list)
+function table.append(t, list)
local n = #t
for i=1,#list do
n = n + 1
@@ -587,26 +550,12 @@ local function do_serialize(root,name,depth,level,indexed)
end
-- we could check for k (index) being number (cardinal)
if root and next(root) then
- -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
- -- if compact then
- -- -- NOT: for k=1,#root do (we need to quit at nil)
- -- for k,v in ipairs(root) do -- can we use next?
- -- if not first then first = k end
- -- last = last + 1
- -- end
- -- end
- local first, last = nil, 0
+ local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
if compact then
- last = #root
- for k=1,last do
--- if not root[k] then
- if root[k] == nil then
- last = k - 1
- break
- end
- end
- if last > 0 then
- first = 1
+ -- NOT: for k=1,#root do (we need to quit at nil)
+ for k,v in ipairs(root) do -- can we use next?
+ if not first then first = k end
+ last = last + 1
end
end
local sk = sortedkeys(root)
@@ -1078,27 +1027,23 @@ function table.reversed(t)
end
end
-function table.sequenced(t,sep) -- hash only
- if t then
- local s, n = { }, 0
- for k, v in sortedhash(t) do
- if simple then
- if v == true then
- n = n + 1
- s[n] = k
- elseif v and v~= "" then
- n = n + 1
- s[n] = k .. "=" .. tostring(v)
- end
- else
+function table.sequenced(t,sep,simple) -- hash only
+ local s, n = { }, 0
+ for k, v in sortedhash(t) do
+ if simple then
+ if v == true then
+ n = n + 1
+ s[n] = k
+ elseif v and v~= "" then
n = n + 1
s[n] = k .. "=" .. tostring(v)
end
+ else
+ n = n + 1
+ s[n] = k .. "=" .. tostring(v)
end
- return concat(s, sep or " | ")
- else
- return ""
end
+ return concat(s, sep or " | ")
end
function table.print(t,...)
@@ -1179,8 +1124,6 @@ local lpeg = require("lpeg")
-- tracing (only used when we encounter a problem in integration of lpeg in luatex)
--- some code will move to unicode and string
-
local report = texio and texio.write_nl or print
-- local lpmatch = lpeg.match
@@ -1217,8 +1160,8 @@ local report = texio and texio.write_nl or print
-- function lpeg.Cmt (l) local p = lpcmt (l) report("LPEG Cmt =") lpprint(l) return p end
-- function lpeg.Carg (l) local p = lpcarg(l) report("LPEG Carg =") lpprint(l) return p end
-local type, next = type, next
-local byte, char, gmatch, format = string.byte, string.char, string.gmatch, string.format
+local type = type
+local byte, char, gmatch = string.byte, string.char, string.gmatch
-- Beware, we predefine a bunch of patterns here and one reason for doing so
-- is that we get consistent behaviour in some of the visualizers.
@@ -1226,8 +1169,9 @@ local byte, char, gmatch, format = string.byte, string.char, string.gmatch, stri
lpeg.patterns = lpeg.patterns or { } -- so that we can share
local patterns = lpeg.patterns
-local P, R, S, V, Ct, C, Cs, Cc, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp
-local lpegtype, lpegmatch = lpeg.type, lpeg.match
+local P, R, S, V, match = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match
+local Ct, C, Cs, Cc = lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local lpegtype = lpeg.type
local utfcharacters = string.utfcharacters
local utfgmatch = unicode and unicode.utf8.gmatch
@@ -1278,10 +1222,6 @@ patterns.utf8char = utf8char
patterns.validutf8 = validutf8char
patterns.validutf8char = validutf8char
-local eol = S("\n\r")
-local spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
-local whitespace = eol + spacer
-
patterns.digit = digit
patterns.sign = sign
patterns.cardinal = sign^0 * digit^1
@@ -1301,16 +1241,16 @@ patterns.letter = patterns.lowercase + patterns.uppercase
patterns.space = space
patterns.tab = P("\t")
patterns.spaceortab = patterns.space + patterns.tab
-patterns.eol = eol
-patterns.spacer = spacer
-patterns.whitespace = whitespace
+patterns.eol = S("\n\r")
+patterns.spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
patterns.newline = newline
patterns.emptyline = newline^1
-patterns.nonspacer = 1 - spacer
-patterns.nonwhitespace = 1 - whitespace
+patterns.nonspacer = 1 - patterns.spacer
+patterns.whitespace = patterns.eol + patterns.spacer
+patterns.nonwhitespace = 1 - patterns.whitespace
patterns.equal = P("=")
patterns.comma = P(",")
-patterns.commaspacer = P(",") * spacer^0
+patterns.commaspacer = P(",") * patterns.spacer^0
patterns.period = P(".")
patterns.colon = P(":")
patterns.semicolon = P(";")
@@ -1325,10 +1265,6 @@ patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"")
patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble
patterns.unspacer = ((patterns.spacer^1)/"")^0
-patterns.singlequoted = squote * patterns.nosquote * squote
-patterns.doublequoted = dquote * patterns.nodquote * dquote
-patterns.quoted = patterns.doublequoted + patterns.singlequoted
-
patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
patterns.beginline = #(1-newline)
@@ -1339,17 +1275,8 @@ patterns.beginline = #(1-newline)
-- print(string.unquoted('"test"'))
-- print(string.unquoted('"test"'))
-local function anywhere(pattern) --slightly adapted from website
- return P { P(pattern) + 1 * V(1) }
-end
-
-lpeg.anywhere = anywhere
-
-function lpeg.instringchecker(p)
- p = anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+function lpeg.anywhere(pattern) --slightly adapted from website
+ return P { P(pattern) + 1 * V(1) } -- why so complex?
end
function lpeg.splitter(pattern, action)
@@ -1398,7 +1325,7 @@ function string.splitup(str,separator)
if not separator then
separator = ","
end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ return match(splitters_m[separator] or splitat(separator),str)
end
@@ -1410,20 +1337,16 @@ function lpeg.split(separator,str)
c = tsplitat(separator)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
function string.split(str,separator)
- if separator then
- local c = cache[separator]
- if not c then
- c = tsplitat(separator)
- cache[separator] = c
- end
- return lpegmatch(c,str)
- else
- return { str }
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
end
+ return match(c,str)
end
local spacing = patterns.spacer^0 * newline -- sort of strip
@@ -1439,7 +1362,7 @@ local linesplitter = tsplitat(newline)
patterns.linesplitter = linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return match(linesplitter,str)
end
local utflinesplitter = utfbom^-1 * tsplitat(newline)
@@ -1447,58 +1370,7 @@ local utflinesplitter = utfbom^-1 * tsplitat(newline)
patterns.utflinesplitter = utflinesplitter
function string.utfsplitlines(str)
- return lpegmatch(utflinesplitter,str or "")
-end
-
-local utfcharsplitter_ows = utfbom^-1 * Ct(C(utf8char)^0)
-local utfcharsplitter_iws = utfbom^-1 * Ct((whitespace^1 + C(utf8char))^0)
-
-function string.utfsplit(str,ignorewhitespace) -- new
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
-end
-
--- inspect(string.utfsplit("a b c d"))
--- inspect(string.utfsplit("a b c d",true))
-
--- -- alternative 1: 0.77
---
--- local utfcharcounter = utfbom^-1 * Cs((utf8char/'!')^0)
---
--- function string.utflength(str)
--- return #lpegmatch(utfcharcounter,str or "")
--- end
---
--- -- alternative 2: 1.70
---
--- local n = 0
---
--- local utfcharcounter = utfbom^-1 * (utf8char/function() n = n + 1 end)^0 -- slow
---
--- function string.utflength(str)
--- n = 0
--- lpegmatch(utfcharcounter,str or "")
--- return n
--- end
---
--- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047)
-
-local n = 0
-
-local utfcharcounter = utfbom^-1 * Cs ( (
- Cp() * (lpeg.patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end
- + Cp() * (lpeg.patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end
- + Cp() * (lpeg.patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end
- + Cp() * (lpeg.patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end
-)^0 )
-
-function string.utflength(str)
- n = 0
- lpegmatch(utfcharcounter,str or "")
- return n
+ return match(utflinesplitter,str or "")
end
@@ -1512,7 +1384,7 @@ function lpeg.checkedsplit(separator,str)
c = Ct(separator^0 * other * (separator^1 * other)^0)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
function string.checkedsplit(str,separator)
@@ -1523,7 +1395,7 @@ function string.checkedsplit(str,separator)
c = Ct(separator^0 * other * (separator^1 * other)^0)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
@@ -1568,11 +1440,11 @@ function lpeg.keeper(str)
end
function lpeg.frontstripper(str) -- or pattern (yet undocumented)
- return (P(str) + P(true)) * Cs(anything^0)
+ return (P(str) + P(true)) * Cs(P(1)^0)
end
function lpeg.endstripper(str) -- or pattern (yet undocumented)
- return Cs((1 - P(str) * endofstring)^0)
+ return Cs((1 - P(str) * P(-1))^0)
end
-- Just for fun I looked at the used bytecode and
@@ -1581,22 +1453,8 @@ end
function lpeg.replacer(one,two)
if type(one) == "table" then
local no = #one
- local p
- if no == 0 then
- for k, v in next, one do
- local pp = P(k) / v
- if p then
- p = p + pp
- else
- p = pp
- end
- end
- return Cs((p + 1)^0)
- elseif no == 1 then
- local o = one[1]
- one, two = P(o[1]), o[2]
- return Cs(((1-one)^1 + one/two)^0)
- else
+ if no > 0 then
+ local p
for i=1,no do
local o = one[i]
local pp = P(o[1]) / o[2]
@@ -1609,16 +1467,11 @@ function lpeg.replacer(one,two)
return Cs((p + 1)^0)
end
else
- one = P(one)
two = two or ""
- return Cs(((1-one)^1 + one/two)^0)
+ return Cs((P(one)/two + 1)^0)
end
end
--- print(lpeg.match(lpeg.replacer("e","a"),"test test"))
--- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test"))
--- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test"))
-
local splitters_f, splitters_s = { }, { }
function lpeg.firstofsplit(separator) -- always return value
@@ -1653,7 +1506,7 @@ local nany = utf8char/""
function lpeg.counter(pattern)
pattern = Cs((P(pattern)/" " + nany)^0)
return function(str)
- return #lpegmatch(pattern,str)
+ return #match(pattern,str)
end
end
@@ -1667,7 +1520,7 @@ if utfgmatch then
end
return n
else -- 4 times slower but still faster than / function
- return #lpegmatch(Cs((P(what)/" " + nany)^0),str)
+ return #match(Cs((P(what)/" " + nany)^0),str)
end
end
@@ -1682,9 +1535,9 @@ else
p = Cs((P(what)/" " + nany)^0)
cache[p] = p
end
- return #lpegmatch(p,str)
+ return #match(p,str)
else -- 4 times slower but still faster than / function
- return #lpegmatch(Cs((P(what)/" " + nany)^0),str)
+ return #match(Cs((P(what)/" " + nany)^0),str)
end
end
@@ -1711,7 +1564,7 @@ local p = Cs((S("-.+*%()[]") / patterns_escapes + anything)^0)
local s = Cs((S("-.+*%()[]") / simple_escapes + anything)^0)
function string.escapedpattern(str,simple)
- return lpegmatch(simple and s or p,str)
+ return match(simple and s or p,str)
end
-- utf extensies
@@ -1758,7 +1611,7 @@ else
p = P(uc)
end
end
- lpegmatch((utf8char/f)^0,str)
+ match((utf8char/f)^0,str)
return p
end
@@ -1774,7 +1627,7 @@ function lpeg.UR(str,more)
first = str
last = more or first
else
- first, last = lpegmatch(range,str)
+ first, last = match(range,str)
if not last then
return P(str)
end
@@ -1801,15 +1654,11 @@ end
-function lpeg.is_lpeg(p)
- return p and lpegtype(p) == "pattern"
-end
-
-function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assume proper order
+function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then")
if type(list) ~= "table" then
list = { list, ... }
end
- -- table.sort(list) -- longest match first
+ -- sort(list) -- longest match first
local p = P(list[1])
for l=2,#list do
p = p + P(list[l])
@@ -1817,6 +1666,10 @@ function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assu
return p
end
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p) == "pattern"
+end
+
-- For the moment here, but it might move to utilities. Beware, we need to
-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
-- loop back from the end cq. prepend.
@@ -1974,24 +1827,6 @@ end
-- utfchar(0x205F), -- math thinspace
-- } )
--- handy from within tex:
-
-local lpegmatch = lpeg.match
-
-local replacer = lpeg.replacer("@","%%") -- Watch the escaped % in lpeg!
-
-function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
-end
-
--- strips leading and trailing spaces and collapsed all other spaces
-
-local pattern = Cs(whitespace^0/"" * ((whitespace^1 * P(-1) / "") + (whitespace^1/" ") + P(1))^0)
-
-function string.collapsespaces(str)
- return lpegmatch(pattern,str)
-end
-
end -- of closure
@@ -2016,14 +1851,14 @@ else
io.fileseparator, io.pathseparator = "/" , ":"
end
-function io.loaddata(filename,textmode) -- return nil if empty
+function io.loaddata(filename,textmode)
local f = io.open(filename,(textmode and 'r') or 'rb')
if f then
local data = f:read('*all')
f:close()
- if #data > 0 then
- return data
- end
+ return data
+ else
+ return nil
end
end
@@ -2045,45 +1880,6 @@ function io.savedata(filename,data,joiner)
end
end
-function io.loadlines(filename,n) -- return nil if empty
- local f = io.open(filename,'r')
- if f then
- if n then
- local lines = { }
- for i=1,n do
- local line = f:read("*lines")
- if line then
- lines[#lines+1] = line
- else
- break
- end
- end
- f:close()
- lines = concat(lines,"\n")
- if #lines > 0 then
- return lines
- end
- else
- local line = f:read("*line") or ""
- assert(f:close())
- if #line > 0 then
- return line
- end
- end
- end
-end
-
-function io.loadchunk(filename,n)
- local f = io.open(filename,'rb')
- if f then
- local data = f:read(n or 1024)
- f:close()
- if #data > 0 then
- return data
- end
- end
-end
-
function io.exists(filename)
local f = io.open(filename)
if f == nil then
@@ -2311,7 +2107,7 @@ if not modules then modules = { } end modules ['l-number'] = {
-- this module will be replaced when we have the bit library
-local tostring, tonumber = tostring, tonumber
+local tostring = tostring
local format, floor, match, rep = string.format, math.floor, string.match, string.rep
local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
@@ -2374,11 +2170,11 @@ function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ...
end
function number.setbit(x, p)
- return (x % (p + p) >= p) and x or x + p
+ return hasbit(x, p) and x or x + p
end
function number.clearbit(x, p)
- return (x % (p + p) >= p) and x - p or x
+ return hasbit(x, p) and x - p or x
end
@@ -2412,10 +2208,6 @@ function number.tobitstring(n,m)
end
-function number.valid(str,default)
- return tonumber(str) or default or nil
-end
-
end -- of closure
@@ -2527,28 +2319,17 @@ if not modules then modules = { } end modules ['l-os'] = {
-- os.name : windows | msdos | linux | macosx | solaris | .. | generic (new)
-- os.platform : extended os.name with architecture
--- os.sleep() => socket.sleep()
--- math.randomseed(tonumber(string.sub(string.reverse(tostring(math.floor(socket.gettime()*10000))),1,6)))
-
-- maybe build io.flush in os.execute
local os = os
-local date, time = os.date, os.time
local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch
local concat = table.concat
-local random, ceil, randomseed = math.random, math.ceil, math.randomseed
-local rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring = rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring
+local random, ceil = math.random, math.ceil
+local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber
-- The following code permits traversing the environment table, at least
-- in luatex. Internally all environment names are uppercase.
--- The randomseed in Lua is not that random, although this depends on the operating system as well
--- as the binary (Luatex is normally okay). But to be sure we set the seed anyway.
-
-math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-
-randomseed(math.initialseed)
-
if not os.__getenv__ then
os.__getenv__ = os.getenv
@@ -2652,14 +2433,12 @@ else
os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' }
end
-local launchers = {
- windows = "start %s",
- macosx = "open %s",
- unix = "$BROWSER %s &> /dev/null &",
-}
-
function os.launch(str)
- os.execute(format(launchers[os.name] or launchers.unix,str))
+ if os.type == "windows" then
+ os.execute("start " .. str) -- os.spawn ?
+ else
+ os.execute(str .. " &") -- os.spawn ?
+ end
end
if not os.times then
@@ -2870,7 +2649,7 @@ end
local d
function os.timezone(delta)
- d = d or tonumber(tonumber(date("%H")-date("!%H")))
+ d = d or tonumber(tonumber(os.date("%H")-os.date("!%H")))
if delta then
if d > 0 then
return format("+%02i:00",d)
@@ -2882,44 +2661,6 @@ function os.timezone(delta)
end
end
-local timeformat = format("%%s%s",os.timezone(true))
-local dateformat = "!%Y-%m-%d %H:%M:%S"
-
-function os.fulltime(t,default)
- t = tonumber(t) or 0
- if t > 0 then
- -- valid time
- elseif default then
- return default
- else
- t = nil
- end
- return format(timeformat,date(dateformat,t))
-end
-
-local dateformat = "%Y-%m-%d %H:%M:%S"
-
-function os.localtime(t,default)
- t = tonumber(t) or 0
- if t > 0 then
- -- valid time
- elseif default then
- return default
- else
- t = nil
- end
- return date(dateformat,t)
-end
-
-function os.converttime(t,default)
- local t = tonumber(t)
- if t and t > 0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
-end
-
local memory = { }
local function which(filename)
@@ -2994,7 +2735,7 @@ local function nameonly(name)
return (gsub(match(name,"^.+[/\\](.-)$") or name,"%.[%a%d]+$",""))
end
-local function suffixonly(name,default)
+local function extname(name,default)
return match(name,"^.+%.([^/\\]-)$") or default or ""
end
@@ -3003,16 +2744,11 @@ local function splitname(name)
return n or name, s or ""
end
-file.basename = basename
-
-file.pathpart = dirname
-file.dirname = dirname
-
-file.nameonly = nameonly
-
-file.suffixonly = suffixonly
-file.extname = suffixonly -- obsolete
-file.suffix = suffixonly
+file.basename = basename
+file.dirname = dirname
+file.nameonly = nameonly
+file.extname = extname
+file.suffix = extname
function file.removesuffix(filename)
return (gsub(filename,"%.[%a%d]+$",""))
@@ -3128,11 +2864,6 @@ end
file.isreadable = file.is_readable -- depricated
file.iswritable = file.is_writable -- depricated
-function file.size(name)
- local a = attributes(name)
- return a and a.size or 0
-end
-
-- todo: lpeg \\ / .. does not save much
local checkedsplit = string.checkedsplit
@@ -3270,7 +3001,6 @@ local drive = C(R("az","AZ")) * P(":")
local path = C(((1-slash)^0 * slash)^0)
local suffix = period * C(P(1-period)^0 * P(-1))
local base = C((1-suffix)^0)
-local rest = C(P(1)^0)
drive = drive + Cc("")
path = path + Cc("")
@@ -3279,8 +3009,7 @@ suffix = suffix + Cc("")
local pattern_a = drive * path * base * suffix
local pattern_b = path * base * suffix
-local pattern_c = C(drive * path) * C(base * suffix) -- trick: two extra captures
-local pattern_d = path * rest
+local pattern_c = C(drive * path) * C(base * suffix)
function file.splitname(str,splitdrive)
if splitdrive then
@@ -3290,10 +3019,6 @@ function file.splitname(str,splitdrive)
end
end
-function file.splitbase(str)
- return lpegmatch(pattern_d,str) -- returns path, base+suffix
-end
-
function file.nametotable(str,splitdrive) -- returns table
local path, drive, subpath, name, base, suffix = lpegmatch(pattern_c,str)
if splitdrive then
@@ -3315,8 +3040,6 @@ function file.nametotable(str,splitdrive) -- returns table
end
end
--- print(file.splitbase("a/b/c.txt"))
-
-- function test(t) for k, v in next, t do print(v, "=>", file.splitname(v)) end end
--
-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
@@ -3358,30 +3081,15 @@ if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
-function file.needsupdating(oldname,newname,threshold) -- size modification access change
- local oldtime = lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime = lfs.attributes(newname,"modification")
- if not newtime then
- return true -- no new file, so no updating needed
- elseif newtime >= oldtime then
- return false -- new file definitely needs updating
- elseif oldtime - newtime < (threshold or 1) then
- return false -- new file is probably still okay
- else
- return true -- new file has to be updated
- end
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
+ local oldtime = lfs.attributes(oldname, modification)
+ local newtime = lfs.attributes(newname, modification)
+ if newtime >= oldtime then
+ return false
+ elseif oldtime - newtime < (threshold or 1) then
+ return false
else
- return false -- no old file, so no updating needed
- end
-end
-
-file.needs_updating = file.needsupdating
-
-function file.syncmtimes(oldname,newname)
- local oldtime = lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
+ return true
end
end
@@ -3403,7 +3111,7 @@ function file.loadchecksum(name)
return nil
end
-function file.savechecksum(name,checksum)
+function file.savechecksum(name, checksum)
if not checksum then checksum = file.checksum(name) end
if checksum then
io.savedata(name .. ".md5",checksum)
@@ -3428,7 +3136,7 @@ if not modules then modules = { } end modules ['l-url'] = {
local char, gmatch, gsub, format, byte, find = string.char, string.gmatch, string.gsub, string.format, string.byte, string.find
local concat = table.concat
local tonumber, type = tonumber, type
-local P, C, R, S, Cs, Cc, Ct, Cf, Cg, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cf, lpeg.Cg, lpeg.V
+local P, C, R, S, Cs, Cc, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct
local lpegmatch, lpegpatterns, replacer = lpeg.match, lpeg.patterns, lpeg.replacer
-- from wikipedia:
@@ -3461,19 +3169,15 @@ local endofstring = P(-1)
local hexdigit = R("09","AF","af")
local plus = P("+")
local nothing = Cc("")
-local escapedchar = (percent * C(hexdigit * hexdigit)) / tochar
-local escaped = (plus / " ") + escapedchar
+local escaped = (plus / " ") + (percent * C(hexdigit * hexdigit) / tochar)
-- we assume schemes with more than 1 character (in order to avoid problems with windows disks)
-- we also assume that when we have a scheme, we also have an authority
---
--- maybe we should already split the query (better for unescaping as = & can be part of a value
local schemestr = Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr = Cs((escaped+(1- slash-qmark-hash))^0)
local pathstr = Cs((escaped+(1- qmark-hash))^0)
------ querystr = Cs((escaped+(1- hash))^0)
-local querystr = Cs(( (1- hash))^0)
+local querystr = Cs((escaped+(1- hash))^0)
local fragmentstr = Cs((escaped+(1- endofstring))^0)
local scheme = schemestr * colon + nothing
@@ -3488,20 +3192,11 @@ local parser = Ct(validurl)
lpegpatterns.url = validurl
lpegpatterns.urlsplitter = parser
-local escapes = { }
+local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end
-setmetatable(escapes, { __index = function(t,k)
- local v = format("%%%02X",byte(k))
- t[k] = v
- return v
-end })
+local escaper = Cs((R("09","AZ","az") + S("-./_") + P(1) / escapes)^0)
-local escaper = Cs((R("09","AZ","az")^1 + P(" ")/"%%20" + S("-./_")^1 + P(1) / escapes)^0) -- space happens most
-local unescaper = Cs((escapedchar + 1)^0)
-
-lpegpatterns.urlunescaped = escapedchar
-lpegpatterns.urlescaper = escaper
-lpegpatterns.urlunescaper = unescaper
+lpegpatterns.urlescaper = escaper
-- todo: reconsider Ct as we can as well have five return values (saves a table)
-- so we can have two parsers, one with and one without
@@ -3513,12 +3208,8 @@ end
local isscheme = schemestr * colon * slash * slash -- this test also assumes authority
local function hasscheme(str)
- if str then
- local scheme = lpegmatch(isscheme,str) -- at least one character
- return scheme ~= "" and scheme or false
- else
- return false
- end
+ local scheme = lpegmatch(isscheme,str) -- at least one character
+ return scheme ~= "" and scheme or false
end
@@ -3537,32 +3228,10 @@ local rootbased = P("/")
local barswapper = replacer("|",":")
local backslashswapper = replacer("\\","/")
--- queries:
-
-local equal = P("=")
-local amp = P("&")
-local key = Cs(((escapedchar+1)-equal )^0)
-local value = Cs(((escapedchar+1)-amp -endofstring)^0)
-
-local splitquery = Cf ( Ct("") * P { "sequence",
- sequence = V("pair") * (amp * V("pair"))^0,
- pair = Cg(key * equal * value),
-}, rawset)
-
--- hasher
-
local function hashed(str) -- not yet ok (/test?test)
- if str == "" then
- return {
- scheme = "invalid",
- original = str,
- }
- end
local s = split(str)
- local rawscheme = s[1]
- local rawquery = s[4]
- local somescheme = rawscheme ~= ""
- local somequery = rawquery ~= ""
+ local somescheme = s[1] ~= ""
+ local somequery = s[4] ~= ""
if not somescheme and not somequery then
s = {
scheme = "file",
@@ -3578,17 +3247,14 @@ local function hashed(str) -- not yet ok (/test?test)
local authority, path, filename = s[2], s[3]
if authority == "" then
filename = path
- elseif path == "" then
- filename = ""
else
filename = authority .. "/" .. path
end
s = {
- scheme = rawscheme,
+ scheme = s[1],
authority = authority,
path = path,
- query = lpegmatch(unescaper,rawquery), -- unescaped, but possible conflict with & and =
- queries = lpegmatch(splitquery,rawquery), -- split first and then unescaped
+ query = s[4],
fragment = s[5],
original = str,
noscheme = false,
@@ -3598,8 +3264,6 @@ local function hashed(str) -- not yet ok (/test?test)
return s
end
--- inspect(hashed("template://test"))
-
-- Here we assume:
--
-- files: /// = relative
@@ -3642,61 +3306,20 @@ function url.construct(hash) -- dodo: we need to escape !
return lpegmatch(escaper,concat(fullurl))
end
-function url.filename(filename) -- why no lpeg here ?
+function url.filename(filename)
local t = hashed(filename)
return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename
end
-local function escapestring(str)
- return lpegmatch(escaper,str)
-end
-
-url.escape = escapestring
-
--- function url.query(str) -- separator could be an option
--- if type(str) == "string" then
--- local t = { }
--- for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
--- t[k] = v
--- end
--- return t
--- else
--- return str
--- end
--- end
-
function url.query(str)
if type(str) == "string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
-end
-
-function url.toquery(data)
- local td = type(data)
- if td == "string" then
- return #str and escape(data) or nil -- beware of double escaping
- elseif td == "table" then
- if next(data) then
- local t = { }
- for k, v in next, data do
- t[#t+1] = format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
+ local t = { }
+ for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
+ t[k] = v
end
+ return t
else
- -- nil is a signal that no query
- end
-end
-
--- /test/ | /test | test/ | test => test
-
-function url.barepath(path)
- if not path or path == "" then
- return ""
- else
- return (gsub(path,"^/?(.-)/?$","%1"))
+ return str
end
end
@@ -3709,7 +3332,6 @@ end
-
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -3741,24 +3363,6 @@ local isdir = lfs.isdir
local isfile = lfs.isfile
local currentdir = lfs.currentdir
--- in case we load outside luatex
-
-if not isdir then
- function isdir(name)
- local a = attributes(name)
- return a and a.mode == "directory"
- end
- lfs.isdir = isdir
-end
-
-if not isfile then
- function isfile(name)
- local a = attributes(name)
- return a and a.mode == "file"
- end
- lfs.isfile = isfile
-end
-
-- handy
function dir.current()
@@ -4134,49 +3738,28 @@ function boolean.tonumber(b)
end
function toboolean(str,tolerant)
- if str == nil then
- return false
- elseif str == false then
- return false
- elseif str == true then
- return true
+ if tolerant then
+ local tstr = type(str)
+ if tstr == "string" then
+ return str == "true" or str == "yes" or str == "on" or str == "1" or str == "t"
+ elseif tstr == "number" then
+ return tonumber(str) ~= 0
+ elseif tstr == "nil" then
+ return false
+ else
+ return str
+ end
elseif str == "true" then
return true
elseif str == "false" then
return false
- elseif not tolerant then
- return false
- elseif str == 0 then
- return false
- elseif (tonumber(str) or 0) > 0 then
- return true
else
- return str == "yes" or str == "on" or str == "t"
+ return str
end
end
string.toboolean = toboolean
-function string.booleanstring(str)
- if str == nil then
- return false
- elseif str == false then
- return false
- elseif str == true then
- return true
- elseif str == "true" then
- return true
- elseif str == "false" then
- return false
- elseif str == 0 then
- return false
- elseif (tonumber(str) or 0) > 0 then
- return true
- else
- return str == "yes" or str == "on" or str == "t"
- end
-end
-
function string.is_boolean(str,default)
if type(str) == "string" then
if str == "true" or str == "yes" or str == "on" or str == "t" then
@@ -4201,229 +3784,57 @@ if not modules then modules = { } end modules ['l-unicode'] = {
license = "see context related readme files"
}
--- this module will be reorganized
-
--- todo: utf.sub replacement (used in syst-aux)
-
-local concat = table.concat
-local type = type
-local P, C, R, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Ct
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
-local utftype = patterns.utftype
-local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
-local utfsplitlines = string.utfsplitlines
-
if not unicode then
- unicode = { }
-
-end
-
-local unicode = unicode
-
-utf = utf or unicode.utf8
-
-if not utf then
-
- utf8 = { }
- unicode.utf8 = utf8
- utf = utf8
-
-end
-
-if not utf.char then
+ unicode = { utf8 = { } }
local floor, char = math.floor, string.char
- function utf.char(n)
+ function unicode.utf8.utfchar(n)
if n < 0x80 then
- -- 0aaaaaaa : 0x80
return char(n)
elseif n < 0x800 then
- -- 110bbbaa : 0xC0 : n >> 6
- -- 10aaaaaa : 0x80 : n & 0x3F
return char(
0xC0 + floor(n/0x40),
0x80 + (n % 0x40)
)
elseif n < 0x10000 then
- -- 1110bbbb : 0xE0 : n >> 12
- -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
- -- 10aaaaaa : 0x80 : n & 0x3F
return char(
0xE0 + floor(n/0x1000),
0x80 + (floor(n/0x40) % 0x40),
0x80 + (n % 0x40)
)
- elseif n < 0x200000 then
- -- 11110ccc : 0xF0 : n >> 18
- -- 10ccbbbb : 0x80 : (n >> 12) & 0x3F
- -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
- -- 10aaaaaa : 0x80 : n & 0x3F
- -- dddd : ccccc - 1
+ elseif n < 0x40000 then
return char(
- 0xF0 + floor(n/0x40000),
- 0x80 + (floor(n/0x1000) % 0x40),
+ 0xF0 + floor(n/0x40000),
+ 0x80 + floor(n/0x1000),
0x80 + (floor(n/0x40) % 0x40),
0x80 + (n % 0x40)
)
else
- return ""
+ -- return char(
+ -- 0xF1 + floor(n/0x1000000),
+ -- 0x80 + floor(n/0x40000),
+ -- 0x80 + floor(n/0x1000),
+ -- 0x80 + (floor(n/0x40) % 0x40),
+ -- 0x80 + (n % 0x40)
+ -- )
+ return "?"
end
end
end
-if not utf.byte then
-
- local utf8byte = patterns.utf8byte
-
- function utf.byte(c)
- return lpegmatch(utf8byte,c)
- end
-
-end
-
-local utfchar, utfbyte = utf.char, utf.byte
-
--- As we want to get rid of the (unmaintained) utf library we implement our own
--- variants (in due time an independent module):
-
-function unicode.filetype(data)
- return data and lpegmatch(utftype,data) or "unknown"
-end
-
-local toentities = Cs (
- (
- patterns.utf8one
- + (
- patterns.utf8two
- + patterns.utf8three
- + patterns.utf8four
- ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("%X;",b) end end
- )^0
-)
-
-patterns.toentities = toentities
-
-function utf.toentities(str)
- return lpegmatch(toentities,str)
-end
-
-
-
-
-local one = P(1)
-local two = C(1) * C(1)
-local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
-
--- actually one of them is already utf ... sort of useless this one
-
--- function utf.char(n)
--- if n < 0x80 then
--- return char(n)
--- elseif n < 0x800 then
--- return char(
--- 0xC0 + floor(n/0x40),
--- 0x80 + (n % 0x40)
--- )
--- elseif n < 0x10000 then
--- return char(
--- 0xE0 + floor(n/0x1000),
--- 0x80 + (floor(n/0x40) % 0x40),
--- 0x80 + (n % 0x40)
--- )
--- elseif n < 0x40000 then
--- return char(
--- 0xF0 + floor(n/0x40000),
--- 0x80 + floor(n/0x1000),
--- 0x80 + (floor(n/0x40) % 0x40),
--- 0x80 + (n % 0x40)
--- )
--- else
--- -- return char(
--- -- 0xF1 + floor(n/0x1000000),
--- -- 0x80 + floor(n/0x40000),
--- -- 0x80 + floor(n/0x1000),
--- -- 0x80 + (floor(n/0x40) % 0x40),
--- -- 0x80 + (n % 0x40)
--- -- )
--- return "?"
--- end
--- end
---
--- merge into:
-
-local pattern = P("\254\255") * Cs( (
- four / function(a,b,c,d)
- local ab = 0xFF * byte(a) + byte(b)
- local cd = 0xFF * byte(c) + byte(d)
- return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
- end
- + two / function(a,b)
- return utfchar(byte(a)*256 + byte(b))
- end
- + one
- )^1 )
- + P("\255\254") * Cs( (
- four / function(b,a,d,c)
- local ab = 0xFF * byte(a) + byte(b)
- local cd = 0xFF * byte(c) + byte(d)
- return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
- end
- + two / function(b,a)
- return utfchar(byte(a)*256 + byte(b))
- end
- + one
- )^1 )
-
-function string.toutf(s)
- return lpegmatch(pattern,s) or s -- todo: utf32
-end
-
-local validatedutf = Cs (
- (
- patterns.utf8one
- + patterns.utf8two
- + patterns.utf8three
- + patterns.utf8four
- + P(1) / "�"
- )^0
-)
-
-patterns.validatedutf = validatedutf
-
-function string.validutf(str)
- return lpegmatch(validatedutf,str)
-end
-
-
-utf.length = string.utflength
-utf.split = string.utfsplit
-utf.splitines = string.utfsplitlines
-utf.valid = string.validutf
-
-if not utf.len then
- utf.len = utf.length
-end
-
--- a replacement for simple gsubs:
+local unicode = unicode
-local utf8char = patterns.utf8char
+utf = utf or unicode.utf8
-function utf.remapper(mapping)
- local pattern = Cs((utf8char/mapping)^0)
- return function(str)
- if not str or str == "" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end, pattern
-end
+local concat = table.concat
+local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub
+local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
+local type = type
--- local remap = utf.remapper { a = 'd', b = "c", c = "b", d = "a" }
--- print(remap("abcd 1234 abcd"))
+local utfsplitlines = string.utfsplitlines
-- 0 EF BB BF UTF-8
-- 1 FF FE UTF-16-little-endian
@@ -4616,22 +4027,11 @@ local function big(c)
end
end
--- function unicode.utf8_to_utf16(str,littleendian)
--- if littleendian then
--- return char(255,254) .. utfgsub(str,".",little)
--- else
--- return char(254,255) .. utfgsub(str,".",big)
--- end
--- end
-
-local _, l_remap = utf.remapper(little)
-local _, b_remap = utf.remapper(big)
-
function unicode.utf8_to_utf16(str,littleendian)
if littleendian then
- return char(255,254) .. lpegmatch(l_remap,str)
+ return char(255,254) .. utfgsub(str,".",little)
else
- return char(254,255) .. lpegmatch(b_remap,str)
+ return char(254,255) .. utfgsub(str,".",big)
end
end
@@ -4652,12 +4052,84 @@ function unicode.xstring(s)
return format("0x%05X",type(s) == "number" and s or utfbyte(s))
end
---
-local pattern = Ct(C(patterns.utf8char)^0)
+local lpegmatch = lpeg.match
+local patterns = lpeg.patterns
+local utftype = patterns.utftype
+
+function unicode.filetype(data)
+ return data and lpegmatch(utftype,data) or "unknown"
+end
-function utf.totable(str)
- return lpegmatch(pattern,str)
+local toentities = lpeg.Cs (
+ (
+ patterns.utf8one
+ + (
+ patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("%X;",b) end end
+ )^0
+)
+
+patterns.toentities = toentities
+
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+
+
+
+
+local P, C, R, Cs = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs
+
+local one = P(1)
+local two = C(1) * C(1)
+local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
+
+-- actually one of them is already utf ... sort of useless this one
+
+local pattern = P("\254\255") * Cs( (
+ four / function(a,b,c,d)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(a,b)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+ + P("\255\254") * Cs( (
+ four / function(b,a,d,c)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(b,a)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+
+function string.toutf(s)
+ return lpegmatch(pattern,s) or s -- todo: utf32
+end
+
+local validatedutf = Cs (
+ (
+ patterns.utf8one
+ + patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ + P(1) / "�"
+ )^0
+)
+
+patterns.validatedutf = validatedutf
+
+function string.validutf(str)
+ return lpegmatch(validatedutf,str)
end
@@ -4717,11 +4189,10 @@ utilities = utilities or {}
utilities.tables = utilities.tables or { }
local tables = utilities.tables
-local format, gmatch, rep, gsub = string.format, string.gmatch, string.rep, string.gsub
+local format, gmatch, rep = string.format, string.gmatch, string.rep
local concat, insert, remove = table.concat, table.insert, table.remove
local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
-local type, next, rawset, tonumber, loadstring = type, next, rawset, tonumber, loadstring
-local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs
+local type, next, rawset, tonumber = type, next, rawset, tonumber
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -4875,121 +4346,6 @@ function tables.encapsulate(core,capsule,protect)
end
end
-local function serialize(t,r,outer) -- no mixes
- r[#r+1] = "{"
- local n = #t
- if n > 0 then
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = format("%q,",v)
- elseif tv == "number" then
- r[#r+1] = format("%s,",v)
- elseif tv == "table" then
- serialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = format("%s,",tostring(v))
- end
- end
- else
- for k, v in next, t do
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = format("[%q]=%q,",k,v)
- elseif tv == "number" then
- r[#r+1] = format("[%q]=%s,",k,v)
- elseif tv == "table" then
- r[#r+1] = format("[%q]=",k)
- serialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = format("[%q]=%s,",k,tostring(v))
- end
- end
- end
- if outer then
- r[#r+1] = "}"
- else
- r[#r+1] = "},"
- end
- return r
-end
-
-function table.fastserialize(t,prefix)
- return concat(serialize(t,{ prefix or "return" },true))
-end
-
-function table.deserialize(str)
- if not str or str == "" then
- return
- end
- local code = loadstring(str)
- if not code then
- return
- end
- code = code()
- if not code then
- return
- end
- return code
-end
-
--- inspect(table.fastserialize { a = 1, b = { 4, { 5, 6 } }, c = { d = 7, e = 'f"g\nh' } })
-
-function table.load(filename)
- if filename then
- local t = io.loaddata(filename)
- if t and t ~= "" then
- t = loadstring(t)
- if type(t) == "function" then
- t = t()
- if type(t) == "table" then
- return t
- end
- end
- end
- end
-end
-
-local function slowdrop(t)
- local r = { }
- local l = { }
- for i=1,#t do
- local ti = t[i]
- local j = 0
- for k, v in next, ti do
- j = j + 1
- l[j] = format("%s=%q",k,v)
- end
- r[i] = format(" {%s},\n",concat(l))
- end
- return format("return {\n%s}",concat(r))
-end
-
-local function fastdrop(t)
- local r = { "return {\n" }
- for i=1,#t do
- local ti = t[i]
- r[#r+1] = " {"
- for k, v in next, ti do
- r[#r+1] = format("%s=%q",k,v)
- end
- r[#r+1] = "},\n"
- end
- r[#r+1] = "}"
- return concat(r)
-end
-
-function table.drop(t,slow)
- if #t == 0 then
- return "return { }"
- elseif slow == true then
- return slowdrop(t) -- less memory
- else
- return fastdrop(t) -- some 15% faster
- end
-end
-
end -- of closure
@@ -5164,10 +4520,11 @@ local concat = table.concat
local type, next = type, next
utilities = utilities or {}
-local merger = utilities.merger or { }
-utilities.merger = merger
+utilities.merger = utilities.merger or { } -- maybe mergers
utilities.report = logs and logs.reporter("system") or print
+local merger = utilities.merger
+
merger.strip_comment = true
local m_begin_merge = "begin library merge"
@@ -5213,11 +4570,9 @@ end
local function self_save(name, data)
if data ~= "" then
if merger.strip_comment then
+ -- saves some 20K
local n = #data
- -- saves some 20K .. scite comments
data = gsub(data,"%-%-~[^\n\r]*[\r\n]","")
- -- saves some 20K .. ldx comments
- data = gsub(data,"%-%-%[%[ldx%-%-.-%-%-ldx%]%]%-%-","")
utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data)
end
io.savedata(name,data)
@@ -5298,208 +4653,36 @@ if not modules then modules = { } end modules ['util-lua'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment = "the strip code is written by Peter Cawley",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-local rep, sub, byte, dump, format = string.rep, string.sub, string.byte, string.dump, string.format
-local loadstring, loadfile, type = loadstring, loadfile, type
-
-utilities = utilities or {}
-utilities.lua = utilities.lua or { }
-local luautilities = utilities.lua
-
-utilities.report = logs and logs.reporter("system") or print -- can be overloaded later
-
-local tracestripping = false
-local forcestupidcompile = true -- use internal bytecode compiler
-luautilities.stripcode = true -- support stripping when asked for
-luautilities.alwaysstripcode = false -- saves 1 meg on 7 meg compressed format file (2012.08.12)
-luautilities.nofstrippedchunks = 0
-luautilities.nofstrippedbytes = 0
-
--- The next function was posted by Peter Cawley on the lua list and strips line
--- number information etc. from the bytecode data blob. We only apply this trick
--- when we store data tables. Stripping makes the compressed format file about
--- 1MB smaller (and uncompressed we save at least 6MB).
---
--- You can consider this feature an experiment, so it might disappear. There is
--- no noticeable gain in runtime although the memory footprint should be somewhat
--- smaller (and the file system has a bit less to deal with).
---
--- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ...
-
-local function strip_code_pc(dump,name)
- local before = #dump
- local version, format, endian, int, size, ins, num = byte(dump,5,11)
- local subint
- if endian == 1 then
- subint = function(dump, i, l)
- local val = 0
- for n = l, 1, -1 do
- val = val * 256 + byte(dump,i + n - 1)
- end
- return val, i + l
- end
- else
- subint = function(dump, i, l)
- local val = 0
- for n = 1, l, 1 do
- val = val * 256 + byte(dump,i + n - 1)
- end
- return val, i + l
- end
- end
- local strip_function
- strip_function = function(dump)
- local count, offset = subint(dump, 1, size)
- local stripped, dirty = rep("\0", size), offset + count
- offset = offset + count + int * 2 + 4
- offset = offset + int + subint(dump, offset, int) * ins
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- local t
- t, offset = subint(dump, offset, 1)
- if t == 1 then
- offset = offset + 1
- elseif t == 4 then
- offset = offset + size + subint(dump, offset, size)
- elseif t == 3 then
- offset = offset + num
- end
- end
- count, offset = subint(dump, offset, int)
- stripped = stripped .. sub(dump,dirty, offset - 1)
- for n = 1, count do
- local proto, off = strip_function(sub(dump,offset, -1))
- stripped, offset = stripped .. proto, offset + off - 1
- end
- offset = offset + subint(dump, offset, int) * int + int
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size + int * 2
- end
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size
- end
- stripped = stripped .. rep("\0", int * 3)
- return stripped, offset
- end
- dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1))
- local after = #dump
- local delta = before-after
- if tracestripping then
- utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta)
- end
- luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1
- luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta
- return dump, delta
-end
-
--- ... end of borrowed code.
-
-local function strippedbytecode(code,forcestrip,name)
- if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then
- return strip_code_pc(code,name)
- else
- return code, 0
- end
-end
-
-luautilities.stripbytecode = strip_code_pc
-luautilities.strippedbytecode = strippedbytecode
-
-local function fatalerror(name)
- utilities.report(format("fatal error in %q",name or "unknown"))
-end
-
--- quite subtle ... doing this wrong incidentally can give more bytes
-
-
-function luautilities.loadedluacode(fullname,forcestrip,name)
- -- quite subtle ... doing this wrong incidentally can give more bytes
- name = name or fullname
- local code = loadfile(fullname)
- if code then
- code()
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip) == "function" then
- forcestrip = forcestrip(fullname)
- end
- if forcestrip then
- local code, n = strip_code_pc(dump(code,name))
- return loadstring(code), n
- elseif luautilities.alwaysstripcode then
- return loadstring(strip_code_pc(dump(code),name))
- else
- return code, 0
- end
- elseif luautilities.alwaysstripcode then
- return loadstring(strip_code_pc(dump(code),name))
- else
- return code, 0
- end
-end
-
-function luautilities.strippedloadstring(code,forcestrip,name) -- not executed
- local n = 0
- if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then
- code = loadstring(code)
- if not code then
- fatalerror(name)
- end
- code, n = strip_code_pc(dump(code),name)
- end
- return loadstring(code), n
-end
+utilities = utilities or {}
+utilities.lua = utilities.lua or { }
+utilities.report = logs and logs.reporter("system") or print
-local function stupidcompile(luafile,lucfile,strip)
- local code = io.loaddata(luafile)
- local n = 0
- if code and code ~= "" then
- code = loadstring(code)
- if not code then
- fatalerror()
- end
- code = dump(code)
- if strip then
- code, n = strippedbytecode(code,true,luafile) -- last one is reported
- end
- if code and code ~= "" then
- io.savedata(lucfile,code)
+local function stupidcompile(luafile,lucfile)
+ local data = io.loaddata(luafile)
+ if data and data ~= "" then
+ data = string.dump(data)
+ if data and data ~= "" then
+ io.savedata(lucfile,data)
end
end
- return n
end
-local luac_normal = "texluac -o %q %q"
-local luac_strip = "texluac -s -o %q %q"
-
-function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
+function utilities.lua.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
utilities.report("lua: compiling %s into %s",luafile,lucfile)
os.remove(lucfile)
- local done = false
+ local command = "-o " .. string.quoted(lucfile) .. " " .. string.quoted(luafile)
if strip ~= false then
- strip = true
- end
- if forcestupidcompile then
- fallback = true
- elseif strip then
- done = os.spawn(format(luac_strip, lucfile,luafile)) == 0
- else
- done = os.spawn(format(luac_normal,lucfile,luafile)) == 0
+ command = "-s " .. command
end
+ local done = os.spawn("texluac " .. command) == 0 -- or os.spawn("luac " .. command) == 0
if not done and fallback then
- local n = stupidcompile(luafile,lucfile,strip)
- if n > 0 then
- utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n)
- else
- utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile)
- end
- cleanup = false -- better see how bad it is
+ utilities.report("lua: dumping %s into %s (unstripped)",luafile,lucfile)
+ stupidcompile(luafile,lucfile) -- maybe use the stripper we have elsewhere
+ cleanup = false -- better see how worse it is
end
if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
utilities.report("lua: removing %s",luafile)
@@ -5514,6 +4697,7 @@ end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -5526,10 +4710,8 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
-local lpeg, table, string = lpeg, table, string
-
-local P, R, V, S, C, Ct, Cs, Carg, Cc = lpeg.P, lpeg.R, lpeg.V, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cc
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local P, R, V, C, Ct, Cs, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg
+local lpegmatch = lpeg.match
local concat, format, gmatch, find = table.concat, string.format, string.gmatch, string.find
local tostring, type, next = tostring, type, next
@@ -5541,39 +4723,29 @@ parsers.patterns = parsers.patterns or { }
local setmetatableindex = table.setmetatableindex
local sortedhash = table.sortedhash
--- we share some patterns
-
-local space = P(' ')
-local equal = P("=")
-local comma = P(",")
-local lbrace = P("{")
-local rbrace = P("}")
-local period = S(".")
-local punctuation = S(".,:;")
-local spacer = patterns.spacer
-local whitespace = patterns.whitespace
-local newline = patterns.newline
-local anything = patterns.anything
-local endofstring = patterns.endofstring
-
-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
-patterns.balanced = P {
+lpeg.patterns.balanced = P {
[1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
[2] = left * V(1) * right
}
+local space = P(' ')
+local equal = P("=")
+local comma = P(",")
+local lbrace = P("{")
+local rbrace = P("}")
local nobrace = 1 - (lbrace+rbrace)
local nested = P { lbrace * (nobrace + V(1))^0 * rbrace }
local spaces = space^0
local argument = Cs((lbrace/"") * ((nobrace + nested)^0) * (rbrace/""))
-local content = (1-endofstring)^0
+local content = (1-P(-1))^0
-patterns.nested = nested -- no capture
-patterns.argument = argument -- argument after e.g. =
-patterns.content = content -- rest after e.g =
+lpeg.patterns.nested = nested -- no capture
+lpeg.patterns.argument = argument -- argument after e.g. =
+lpeg.patterns.content = content -- rest after e.g =
local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0)
@@ -5592,6 +4764,10 @@ local function set(key,value)
hash[key] = value
end
+local function set(key,value)
+ hash[key] = value
+end
+
local pattern_a_s = (pattern_a/set)^1
local pattern_b_s = (pattern_b/set)^1
local pattern_c_s = (pattern_c/set)^1
@@ -5642,7 +4818,7 @@ end
local separator = comma * space^0
local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0)
-local pattern = spaces * Ct(value*(separator*value)^0)
+local pattern = Ct(value*(separator*value)^0)
-- "aap, {noot}, mies" : outer {} removes, leading spaces ignored
@@ -5766,37 +4942,6 @@ function parsers.listitem(str)
return gmatch(str,"[^, ]+")
end
---
-local digit = R("09")
-
-local pattern = Cs { "start",
- start = V("one") + V("two") + V("three"),
- rest = (Cc(",") * V("thousand"))^0 * (P(".") + endofstring) * anything^0,
- thousand = digit * digit * digit,
- one = digit * V("rest"),
- two = digit * digit * V("rest"),
- three = V("thousand") * V("rest"),
-}
-
-patterns.splitthousands = pattern -- maybe better in the parsers namespace ?
-
-function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
-end
-
--- print(parsers.splitthousands("11111111111.11"))
-
-local optionalwhitespace = whitespace^0
-
-patterns.words = Ct((Cs((1-punctuation-whitespace)^1) + anything)^1)
-patterns.sentences = Ct((optionalwhitespace * Cs((1-period)^0 * period))^1)
-patterns.paragraphs = Ct((optionalwhitespace * Cs((whitespace^1*endofstring/"" + 1 - (spacer^0*newline*newline))^1))^1)
-
--- local str = " Word1 word2. \n Word3 word4. \n\n Word5 word6.\n "
--- inspect(lpegmatch(patterns.paragraphs,str))
--- inspect(lpegmatch(patterns.sentences,str))
--- inspect(lpegmatch(patterns.words,str))
-
end -- of closure
@@ -5898,7 +5043,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['util-deb'] = {
+if not modules then modules = { } end modules ['util.deb'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -6010,7 +5155,6 @@ function inspect(i) -- global function
else
print(tostring(i))
end
- return i -- so that we can inline the inspect
end
-- from the lua book:
@@ -6050,7 +5194,7 @@ if not modules then modules = { } end modules ['trac-inf'] = {
local format, lower = string.format, string.lower
local clock = os.gettimeofday or os.clock -- should go in environment
-local write_nl = texio and texio.write_nl or print
+local write_nl = texio.write_nl
statistics = statistics or { }
local statistics = statistics
@@ -6133,7 +5277,7 @@ statistics.elapsedtime = elapsedtime
statistics.elapsedindeed = elapsedindeed
statistics.elapsedseconds = elapsedseconds
--- general function .. we might split this module
+-- general function
function statistics.register(tag,fnc)
if statistics.enable and type(fnc) == "function" then
@@ -6243,8 +5387,6 @@ if not modules then modules = { } end modules ['trac-set'] = { -- might become u
license = "see context related readme files"
}
--- maybe this should be util-set.lua
-
local type, next, tostring = type, next, tostring
local concat = table.concat
local format, find, lower, gsub, escapedpattern = string.format, string.find, string.lower, string.gsub, string.escapedpattern
@@ -6444,7 +5586,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- t.report("%-50s modules: %2i default: %6s value: %6s",name,modules,default,value)
+ t.report("%-30s modules: %2i default: %6s value: %6s",name,modules,default,value)
end
end
t.report()
@@ -6536,31 +5678,17 @@ end)
-- experiment
-if environment then
+local flags = environment and environment.engineflags
- -- The engineflags are known earlier than environment.arguments but maybe we
- -- need to handle them both as the later are parsed differently. The c: prefix
- -- is used by mtx-context to isolate the flags from those that concern luatex.
-
- local engineflags = environment.engineflags
-
- if engineflags then
- if trackers then
- local list = engineflags["c:trackers"] or engineflags["trackers"]
- if type(list) == "string" then
- setters.initialize("flags","trackers",settings_to_hash(list))
- -- t_enable(list)
- end
- end
- if directives then
- local list = engineflags["c:directives"] or engineflags["directives"]
- if type(list) == "string" then
- setters.initialize("flags","directives", settings_to_hash(list))
- -- d_enable(list)
- end
- end
+if flags then
+ if trackers and flags.trackers then
+ setters.initialize("flags","trackers", settings_to_hash(flags.trackers))
+ -- t_enable(flags.trackers)
+ end
+ if directives and flags.directives then
+ setters.initialize("flags","directives", settings_to_hash(flags.directives))
+ -- d_enable(flags.directives)
end
-
end
-- here
@@ -6613,7 +5741,10 @@ local next, type = next, type
local setmetatableindex = table.setmetatableindex
-
+--[[ldx--
+
This is a prelude to a more extensive logging module. We no longer
+provide based logging a sparsing is relatively easy anyway.
+--ldx]]--
logs = logs or { }
local logs = logs
@@ -7429,8 +6560,7 @@ local allocate, mark = utilities.storage.allocate, utilities.storage.mark
local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find
local unquoted, quoted = string.unquoted, string.quoted
-local concat, insert, remove = table.concat, table.insert, table.remove
-local loadedluacode = utilities.lua.loadedluacode
+local concat = table.concat
-- precautions
@@ -7448,28 +6578,8 @@ if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaon
for k=3,#arg do
arg[k-2] = arg[k]
end
- remove(arg) -- last
- remove(arg) -- pre-last
-end
-
--- This is an ugly hack but it permits symlinking a script (say 'context') to 'mtxrun' as in:
---
--- ln -s /opt/minimals/tex/texmf-linux-64/bin/mtxrun context
---
--- The special mapping hack is needed because 'luatools' boils down to 'mtxrun --script base'
--- but it's unlikely that there will be more of this
-
-do
-
- local originalzero = file.basename(arg[0])
- local specialmapping = { luatools == "base" }
-
- if originalzero ~= "mtxrun" and originalzero ~= "mtxrun.lua" then
- arg[0] = specialmapping[originalzero] or originalzero
- insert(arg,0,"--script")
- insert(arg,0,"mtxrun")
- end
-
+ arg[#arg] = nil -- last
+ arg[#arg] = nil -- pre-last
end
-- environment
@@ -7509,8 +6619,6 @@ local mt = {
setmetatable(environment,mt)
--- context specific arguments (in order not to confuse the engine)
-
function environment.initializearguments(arg)
local arguments, files = { }, { }
environment.arguments, environment.files, environment.sortedflags = arguments, files, nil
@@ -7519,12 +6627,10 @@ function environment.initializearguments(arg)
if index > 0 then
local flag, value = match(argument,"^%-+(.-)=(.-)$")
if flag then
- flag = gsub(flag,"^c:","")
arguments[flag] = unquoted(value or "")
else
flag = match(argument,"^%-+(.+)")
if flag then
- flag = gsub(flag,"^c:","")
arguments[flag] = true
else
files[#files+1] = argument
@@ -7544,7 +6650,7 @@ end
-- tricky: too many hits when we support partials unless we add
-- a registration of arguments so from now on we have 'partial'
-function environment.getargument(name,partial)
+function environment.argument(name,partial)
local arguments, sortedflags = environment.arguments, environment.sortedflags
if arguments[name] then
return arguments[name]
@@ -7567,8 +6673,6 @@ function environment.getargument(name,partial)
return nil
end
-environment.argument = environment.getargument
-
function environment.splitarguments(separator) -- rather special, cut-off before separator
local done, before, after = false, { }, { }
local originalarguments = environment.originalarguments
@@ -7654,7 +6758,7 @@ function environment.texfile(filename)
return resolvers.findfile(filename,'tex')
end
-function environment.luafile(filename) -- needs checking
+function environment.luafile(filename)
local resolved = resolvers.findfile(filename,'tex') or ""
if resolved ~= "" then
return resolved
@@ -7666,16 +6770,13 @@ function environment.luafile(filename) -- needs checking
return resolvers.findfile(filename,'luatexlibs') or ""
end
-local function checkstrip(filename)
- local modu = modules[file.nameonly(filename)]
- return modu and modu.dataonly
-end
+environment.loadedluacode = loadfile -- can be overloaded
function environment.luafilechunk(filename,silent) -- used for loading lua bytecode in the format
filename = file.replacesuffix(filename, "lua")
local fullname = environment.luafile(filename)
if fullname and fullname ~= "" then
- local data = loadedluacode(fullname,checkstrip,filename)
+ local data = environment.loadedluacode(fullname)
if trace_locating then
report_lua("loading file %s%s", fullname, not data and " failed" or "")
elseif not silent then
@@ -7773,7 +6874,21 @@ local trace_entities = false trackers.register("xml.entities", function(v) trac
local report_xml = logs and logs.reporter("xml","core") or function(...) print(format(...)) end
+--[[ldx--
+
The parser used here is inspired by the variant discussed in the lua book, but
+handles comment and processing instructions, has a different structure, provides
+parent access; a first version used different trickery but was less optimized to we
+went this route. First we had a find based parser, now we have an based one.
+The find based parser can be found in l-xml-edu.lua along with other older code.
+
Beware, the interface may change. For instance at, ns, tg, dt may get more
+verbose names. Once the code is stable we will also remove some tracing and
+optimize the code.
+
+
I might even decide to reimplement the parser using the latest trickery
+as the current variant was written when showed up and it's easier now to
+build tables in one go.
+--ldx]]--
xml = xml or { }
local xml = xml
@@ -7783,25 +6898,46 @@ local utf = unicode.utf8
local concat, remove, insert = table.concat, table.remove, table.insert
local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber
local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub
-local utfchar = utf.char
+local utfchar, utffind, utfgsub = utf.char, utf.find, utf.gsub
local lpegmatch = lpeg.match
local P, S, R, C, V, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.C, lpeg.Cs
-
+--[[ldx--
+
First a hack to enable namespace resolving. A namespace is characterized by
+a . The following function associates a namespace prefix with a
+pattern. We use , which in this case is more than twice as fast as a
+find based solution where we loop over an array of patterns. Less code and
+much cleaner.
+--ldx]]--
xml.xmlns = xml.xmlns or { }
local check = P(false)
local parse = check
+--[[ldx--
+
The next function associates a namespace prefix with an . This
+normally happens independent of parsing.
+
+xml.registerns("mml","mathml")
+
+--ldx]]--
function xml.registerns(namespace, pattern) -- pattern can be an lpeg
check = check + C(P(lower(pattern))) / namespace
parse = P { P(check) + 1 * V(1) }
end
+--[[ldx--
+
The next function also registers a namespace, but this time we map a
+given namespace prefix onto a registered one, using the given
+. This used for attributes like xmlns:m.
+
+xml.checkns("m","http://www.w3.org/mathml")
+
+--ldx]]--
function xml.checkns(namespace,url)
local ns = lpegmatch(parse,lower(url))
@@ -7810,15 +6946,66 @@ function xml.checkns(namespace,url)
end
end
+--[[ldx--
+
Next we provide a way to turn an into a registered
+namespace. This used for the xmlns attribute.
+
+resolvedns = xml.resolvens("http://www.w3.org/mathml")
+
+
+This returns mml.
+--ldx]]--
function xml.resolvens(url)
return lpegmatch(parse,lower(url)) or ""
end
-
-
-
+--[[ldx--
+
A namespace in an element can be remapped onto the registered
+one efficiently by using the xml.xmlns table.
+--ldx]]--
+
+--[[ldx--
+
This version uses . We follow the same approach as before, stack and top and
+such. This version is about twice as fast which is mostly due to the fact that
+we don't have to prepare the stream for cdata, doctype etc etc. This variant is
+is dedicated to Luigi Scarso, who challenged me with 40 megabyte files that
+took 12.5 seconds to load (1.5 for file io and the rest for tree building). With
+the implementation we got that down to less 7.3 seconds. Loading the 14
+ interface definition files (2.6 meg) went down from 1.05 seconds to 0.55.
+
+
Next comes the parser. The rather messy doctype definition comes in many
+disguises so it is no surprice that later on have to dedicate quite some
+ code to it.
+
+
+
+
+
+
+
+
+
+
+
The code may look a bit complex but this is mostly due to the fact that we
+resolve namespaces and attach metatables. There is only one public function:
+
+
+local x = xml.convert(somestring)
+
+
+
An optional second boolean argument tells this function not to create a root
+element.
+
+
Valid entities are:
+
+
+
+
+
+
+--ldx]]--
-- not just one big nested table capture (lpeg overflow)
@@ -8033,7 +7220,15 @@ local privates_n = {
-- keeps track of defined ones
}
-local escaped = utf.remapper(privates_u)
+local function escaped(s)
+ if s == "" then
+ return ""
+ else -- if utffind(s,privates_u) then
+ return (utfgsub(s,".",privates_u))
+ -- else
+ -- return s
+ end
+end
local function unescaped(s)
local p = privates_n[s]
@@ -8048,7 +7243,13 @@ local function unescaped(s)
return p
end
-local unprivatized = utf.remapper(privates_p)
+local function unprivatized(s,resolve)
+ if s == "" then
+ return ""
+ else
+ return (utfgsub(s,".",privates_p))
+ end
+end
xml.privatetoken = unescaped
xml.unprivatized = unprivatized
@@ -8388,12 +7589,7 @@ local function _xmlconvert_(data, settings)
else
errorhandler = errorhandler or xml.errorhandler
if errorhandler then
- local currentresource = settings.currentresource
- if currentresource and currentresource ~= "" then
- xml.errorhandler(format("load error in [%s]: %s",currentresource,errorstr))
- else
- xml.errorhandler(format("load error: %s",errorstr))
- end
+ xml.errorhandler(format("load error: %s",errorstr))
end
end
else
@@ -8438,7 +7634,7 @@ function xmlconvert(data,settings)
if ok then
return result
else
- return _xmlconvert_("",settings)
+ return _xmlconvert_("")
end
end
@@ -8459,7 +7655,10 @@ function xml.inheritedconvert(data,xmldata) -- xmldata is parent
return xc
end
-
+--[[ldx--
+
Packaging data in an xml like table is done with the following
+function. Maybe it will go away (when not used).
+--ldx]]--
function xml.is_valid(root)
return root and root.dt and root.dt[1] and type(root.dt[1]) == "table" and not root.dt[1].er
@@ -8478,7 +7677,11 @@ end
xml.errorhandler = report_xml
-
+--[[ldx--
+
We cannot load an from a filehandle so we need to load
+the whole file first. The function accepts a string representing
+a filename or a file handle.
+--ldx]]--
function xml.load(filename,settings)
local data = ""
@@ -8492,17 +7695,13 @@ function xml.load(filename,settings)
elseif filename then -- filehandle
data = filename:read("*all")
end
- if settings then
- settings.currentresource = filename
- local result = xmlconvert(data,settings)
- settings.currentresource = nil
- return result
- else
- return xmlconvert(data,{ currentresource = filename })
- end
+ return xmlconvert(data,settings)
end
-
+--[[ldx--
+
When we inject new elements, we need to convert strings to
+valid trees, which is what the next function does.
+--ldx]]--
local no_root = { no_root = true }
@@ -8515,7 +7714,11 @@ function xml.toxml(data)
end
end
-
+--[[ldx--
+
For copying a tree we use a dedicated function instead of the
+generic table copier. Since we know what we're dealing with we
+can speed up things a bit. The second argument is not to be used!
+--ldx]]--
local function copy(old,tables)
if old then
@@ -8539,7 +7742,13 @@ end
xml.copy = copy
-
+--[[ldx--
+
In serializing the tree or parts of the tree is a major
+actitivity which is why the following function is pretty optimized resulting
+in a few more lines of code than needed. The variant that uses the formatting
+function for all components is about 15% slower than the concatinating
+alternative.
+--ldx]]--
-- todo: add when not present
@@ -8552,12 +7761,15 @@ function xml.checkbom(root) -- can be made faster
return
end
end
- insert(dt, 1, { special = true, ns = "", tg = "@pi@", dt = { "xml version='1.0' standalone='yes'" } } )
+ insert(dt, 1, { special=true, ns="", tg="@pi@", dt = { "xml version='1.0' standalone='yes'"} } )
insert(dt, 2, "\n" )
end
end
-
+--[[ldx--
+
At the cost of some 25% runtime overhead you can first convert the tree to a string
+and then handle the lot.
How you deal with saving data depends on your preferences. For a 40 MB database
+file the timing on a 2.3 Core Duo are as follows (time in seconds):
+
+
+1.3 : load data from file to string
+6.1 : convert string into tree
+5.3 : saving in file using xmlsave
+6.8 : converting to string using xml.tostring
+3.6 : saving converted string in file
+
+
Beware, these were timing with the old routine but measurements will not be that
+much different I guess.
+--ldx]]--
-- maybe this will move to lxml-xml
@@ -8828,7 +8054,10 @@ xml.newhandlers = newhandlers
xml.serialize = serialize
xml.tostring = xmltostring
-
+--[[ldx--
+
The next function operated on the content only and needs a handle function
+that accepts a string.
+--ldx]]--
local function xmlstring(e,handle)
if not handle or (e.special and e.tg ~= "@rt@") then
@@ -8847,7 +8076,9 @@ end
xml.string = xmlstring
-
+--[[ldx--
+
A few helpers:
+--ldx]]--
function xml.settings(e)
@@ -8891,7 +8122,11 @@ function xml.name(root)
end
end
-
+--[[ldx--
+
The next helper erases an element but keeps the table as it is,
+and since empty strings are not serialized (effectively) it does
+not harm. Copying the table would take more time. Usage:
+--ldx]]--
function xml.erase(dt,k)
if dt then
@@ -8903,7 +8138,13 @@ function xml.erase(dt,k)
end
end
+--[[ldx--
+
The next helper assigns a tree (or string). Usage:
+
+dt[k] = xml.assign(root) or xml.assign(dt,k,root)
+
+--ldx]]--
function xml.assign(dt,k,root)
if dt and k then
@@ -8916,14 +8157,20 @@ end
-- the following helpers may move
-
+--[[ldx--
+
The next helper assigns a tree (or string). Usage:
+
+xml.tocdata(e)
+xml.tocdata(e,"error")
+
+--ldx]]--
function xml.tocdata(e,wrapper) -- a few more in the aux module
local whatever = type(e) == "table" and xmltostring(e.dt) or e or ""
if wrapper then
whatever = format("<%s>%s%s>",wrapper,whatever,wrapper)
end
- local t = { special = true, ns = "", tg = "@cd@", at = { }, rn = "", dt = { whatever }, __p__ = e }
+ local t = { special = true, ns = "", tg = "@cd@", at = {}, rn = "", dt = { whatever }, __p__ = e }
setmetatable(t,getmetatable(e))
e.dt = { t }
end
@@ -8978,7 +8225,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['lxml-lpt'] = {
+if not modules then modules = { } end modules ['lxml-pth'] = {
version = 1.001,
comment = "this module is the basis for the lxml-* ones",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -8999,9 +8246,28 @@ local setmetatableindex = table.setmetatableindex
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
-
-
-
+--[[ldx--
+
This module can be used stand alone but also inside in
+which case it hooks into the tracker code. Therefore we provide a few
+functions that set the tracers. Here we overload a previously defined
+function.
+
If I can get in the mood I will make a variant that is XSLT compliant
+but I wonder if it makes sense.
+--ldx]]--
+
+--[[ldx--
+
Expecially the lpath code is experimental, we will support some of xpath, but
+only things that make sense for us; as compensation it is possible to hook in your
+own functions. Apart from preprocessing content for we also need
+this module for process management, like handling and
+files.
+
+
+a/b/c /*/c
+a/b/c/first() a/b/c/last() a/b/c/index(n) a/b/c/index(-n)
+a/b/c/text() a/b/c/text(1) a/b/c/text(-1) a/b/c/text(n)
+
+--ldx]]--
local trace_lpath = false if trackers then trackers.register("xml.path", function(v) trace_lpath = v end) end
local trace_lparse = false if trackers then trackers.register("xml.parse", function(v) trace_lparse = v end) end
@@ -9009,7 +8275,11 @@ local trace_lprofile = false if trackers then trackers.register("xml.profile",
local report_lpath = logs.reporter("xml","lpath")
-
+--[[ldx--
+
We've now arrived at an interesting part: accessing the tree using a subset
+of and since we're not compatible we call it . We
+will explain more about its usage in other documents.
+--ldx]]--
local xml = xml
@@ -9461,23 +8731,14 @@ local lp_builtin = P (
-- for the moment we keep namespaces with attributes
local lp_attribute = (P("@") + P("attribute::")) / "" * Cc("(ll.at and ll.at['") * ((R("az","AZ") + S("-_:"))^1) * Cc("'])")
-
--- lp_fastpos_p = (P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end
--- lp_fastpos_n = (P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end
-
-lp_fastpos_p = P("+")^0 * R("09")^1 * P(-1) / "l==%0"
-lp_fastpos_n = P("-") * R("09")^1 * P(-1) / "(%0<0 and (#list+%0==l))"
-
+local lp_fastpos_p = ((P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end)
+local lp_fastpos_n = ((P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end)
local lp_fastpos = lp_fastpos_n + lp_fastpos_p
-
local lp_reserved = C("and") + C("or") + C("not") + C("div") + C("mod") + C("true") + C("false")
--- local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
--- return t .. "("
--- end
-
--- local lp_lua_function = (R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / "%0("
-local lp_lua_function = Cs((R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(")) / "%0"
+local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
+ return t .. "("
+end
local lp_function = C(R("az","AZ","__")^1) * P("(") / function(t) -- todo: better . handling
if expressions[t] then
@@ -9993,7 +9254,9 @@ end
xml.applylpath = applylpath -- takes a table as first argment, which is what xml.filter will do
-
+--[[ldx--
+
This is the main filter function. It returns whatever is asked for.
+--ldx]]--
function xml.filter(root,pattern) -- no longer funny attribute handling here
return applylpath(root,pattern)
@@ -10091,12 +9354,12 @@ xml.selection = selection -- new method, simple handle
-- generic function finalizer (independant namespace)
-local function dofunction(collected,fnc,...)
+local function dofunction(collected,fnc)
if collected then
local f = functions[fnc]
if f then
for c=1,#collected do
- f(collected[c],...)
+ f(collected[c])
end
else
report_lpath("unknown function '%s'",fnc)
@@ -10197,7 +9460,21 @@ expressions.tag = function(e,n) -- only tg
end
end
+--[[ldx--
+
Often using an iterators looks nicer in the code than passing handler
+functions. The book describes how to use coroutines for that
+purpose (). This permits
+code like:
+
+for r, d, k in xml.elements(xml.load('text.xml'),"title") do
+ print(d[k]) -- old method
+end
+for e in xml.collected(xml.load('text.xml'),"title") do
+ print(e) -- new one
+end
+
+--ldx]]--
local wrap, yield = coroutine.wrap, coroutine.yield
@@ -10238,32 +9515,6 @@ function xml.inspect(collection,pattern)
end
end
--- texy (see xfdf):
-
-local function split(e)
- local dt = e.dt
- if dt then
- for i=1,#dt do
- local dti = dt[i]
- if type(dti) == "string" then
- dti = gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti = gsub(dti,"[\n\r]+","\n\n")
- dt[i] = dti
- else
- split(dti)
- end
- end
- end
- return e
-end
-
-function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
-end
-
end -- of closure
@@ -10288,7 +9539,13 @@ local P, S, R, C, V, Cc, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, l
lpegpatterns.xml = lpegpatterns.xml or { }
local xmlpatterns = lpegpatterns.xml
-
+--[[ldx--
+
The following helper functions best belong to the lxml-ini
+module. Some are here because we need then in the mk
+document and other manuals, others came up when playing with
+this module. Since this module is also used in we've
+put them here instead of loading mode modules there then needed.
+--ldx]]--
local function xmlgsub(t,old,new) -- will be replaced
local dt = t.dt
@@ -10474,7 +9731,9 @@ function xml.processattributes(root,pattern,handle)
return collected
end
-
+--[[ldx--
+
The following functions collect elements and texts.
+--ldx]]--
-- are these still needed -> lxml-cmp.lua
@@ -10513,7 +9772,9 @@ function xml.collect_tags(root, pattern, nonamespace)
end
end
-
+--[[ldx--
+
We've now arrived at the functions that manipulate the tree.
+--ldx]]--
local no_root = { no_root = true }
@@ -10899,7 +10160,9 @@ function xml.remapname(root, pattern, newtg, newns, newrn)
end
end
-
+--[[ldx--
+
Helper (for q2p).
+--ldx]]--
function xml.cdatatotext(e)
local dt = e.dt
@@ -10996,7 +10259,9 @@ end
-- xml.addentitiesdoctype(x,"hexadecimal")
-- print(x)
-
+--[[ldx--
+
Here are a few synonyms.
+--ldx]]--
xml.all = xml.each
xml.insert = xml.insertafter
@@ -11587,7 +10852,7 @@ local gsub, find, gmatch, char = string.gsub, string.find, string.gmatch, string
local concat = table.concat
local next, type = next, type
-local filedirname, filebasename, filejoin = file.dirname, file.basename, file.join
+local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -11937,14 +11202,12 @@ local function splitpathexpr(str, newlist, validate) -- I couldn't resist lpeggi
for s in gmatch(str,"[^,]+") do
s = validate(s)
if s then
- n = n + 1
- t[n] = s
+ n = n + 1 ; t[n] = s
end
end
else
for s in gmatch(str,"[^,]+") do
- n = n + 1
- t[n] = s
+ n = n + 1 ; t[n] = s
end
end
if trace_expansions then
@@ -11958,7 +11221,7 @@ end
-- We could make the previous one public.
local function validate(s)
- s = collapsepath(s) -- already keeps the trailing / and //
+ s = collapsepath(s) -- already keeps the //
return s ~= "" and not find(s,"^!*unset/*$") and s
end
@@ -12296,7 +11559,7 @@ local resolvers = resolvers
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
-local suffixonly = file.suffixonly
+local fileextname = file.extname
local formats = allocate()
local suffixes = allocate()
@@ -12551,7 +11814,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[suffixonly(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
+ return suffixmap[fileextname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
@@ -12563,7 +11826,7 @@ function resolvers.variableofformatorsuffix(str)
if v then
return v
end
- v = suffixmap[suffixonly(str)]
+ v = suffixmap[fileextname(str)]
if v then
return formats[v]
end
@@ -12584,7 +11847,21 @@ if not modules then modules = { } end modules ['data-tmp'] = {
license = "see context related readme files"
}
+--[[ldx--
+
This module deals with caching data. It sets up the paths and
+implements loaders and savers for tables. Best is to set the
+following variable. When not set, the usual paths will be
+checked. Personally I prefer the (users) temporary path.
Currently we do no locking when we write files. This is no real
+problem because most caching involves fonts and the chance of them
+being written at the same time is small. We also need to extend
+luatools with a recache feature.
+--ldx]]--
local format, lower, gsub, concat = string.format, string.lower, string.gsub, table.concat
local serialize, serializetofile = table.serialize, table.tofile
@@ -13119,12 +12396,11 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local filedirname = file.dirname
local filebasename = file.basename
-local suffixonly = file.suffixonly
+local fileextname = file.extname
local filejoin = file.join
local collapsepath = file.collapsepath
local joinpath = file.joinpath
local allocate = utilities.storage.allocate
-local settings_to_array = utilities.parsers.settings_to_array
local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
@@ -13148,7 +12424,7 @@ resolvers.cacheversion = '1.0.1'
resolvers.configbanner = ''
resolvers.homedir = environment.homedir
resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" }
-resolvers.luacnfname = "texmfcnf.lua"
+resolvers.luacnfname = 'texmfcnf.lua'
resolvers.luacnfstate = "unknown"
-- The web2c tex binaries as well as kpse have built in paths for the configuration
@@ -13420,7 +12696,7 @@ end
local function identify_configuration_files()
local specification = instance.specification
if #specification == 0 then
- local cnfspec = getenv("TEXMFCNF")
+ local cnfspec = getenv('TEXMFCNF')
if cnfspec == "" then
cnfspec = resolvers.luacnfspec
resolvers.luacnfstate = "default"
@@ -13508,7 +12784,7 @@ local function load_configuration_files()
-- we push the value into the main environment (osenv) so
-- that it takes precedence over the default one and therefore
-- also over following definitions
- resolvers.setenv("TEXMFCNF",cnfspec) -- resolves prefixes
+ resolvers.setenv('TEXMFCNF',cnfspec) -- resolves prefixes
-- we now identify and load the specified configuration files
instance.specification = { }
identify_configuration_files()
@@ -13556,11 +12832,10 @@ end
local function locate_file_databases()
-- todo: cache:// and tree:// (runtime)
- local texmfpaths = resolvers.expandedpathlist("TEXMF")
+ local texmfpaths = resolvers.expandedpathlist('TEXMF')
if #texmfpaths > 0 then
for i=1,#texmfpaths do
local path = collapsepath(texmfpaths[i])
- path = gsub(path,"/+$","") -- in case $HOME expands to something with a trailing /
local stripped = lpegmatch(inhibitstripper,path) -- the !! thing
if stripped ~= "" then
local runtime = stripped == path
@@ -13689,9 +12964,9 @@ function resolvers.prependhash(type,name,cache)
end
function resolvers.extendtexmfvariable(specification) -- crap, we could better prepend the hash
- local t = resolvers.splitpath(getenv("TEXMF")) -- okay?
+ local t = resolvers.splitpath(getenv('TEXMF'))
insert(t,1,specification)
- local newspec = concat(t,",") -- not ;
+ local newspec = concat(t,";")
if instance.environment["TEXMF"] then
instance.environment["TEXMF"] = newspec
elseif instance.variables["TEXMF"] then
@@ -13766,19 +13041,14 @@ function resolvers.resetextrapath()
end
function resolvers.registerextrapath(paths,subpaths)
- paths = settings_to_array(paths)
- subpaths = settings_to_array(subpaths)
local ep = instance.extra_paths or { }
local oldn = #ep
local newn = oldn
- local nofpaths = #paths
- local nofsubpaths = #subpaths
- if nofpaths > 0 then
- if nofsubpaths > 0 then
- for i=1,nofpaths do
- local p = paths[i]
- for j=1,nofsubpaths do
- local s = subpaths[j]
+ if paths and paths ~= "" then
+ if subpaths and subpaths ~= "" then
+ for p in gmatch(paths,"[^,]+") do
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
local ps = p .. "/" .. s
if not done[ps] then
newn = newn + 1
@@ -13788,8 +13058,7 @@ function resolvers.registerextrapath(paths,subpaths)
end
end
else
- for i=1,nofpaths do
- local p = paths[i]
+ for p in gmatch(paths,"[^,]+") do
if not done[p] then
newn = newn + 1
ep[newn] = resolvers.cleanpath(p)
@@ -13797,10 +13066,10 @@ function resolvers.registerextrapath(paths,subpaths)
end
end
end
- elseif nofsubpaths > 0 then
+ elseif subpaths and subpaths ~= "" then
for i=1,oldn do
- for j=1,nofsubpaths do
- local s = subpaths[j]
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
local ps = ep[i] .. "/" .. s
if not done[ps] then
newn = newn + 1
@@ -13878,21 +13147,18 @@ function resolvers.expandedpathlist(str)
return { }
elseif instance.savelists then
str = lpegmatch(dollarstripper,str)
- local lists = instance.lists
- local lst = lists[str]
- if not lst then
- local l = made_list(instance,resolvers.splitpath(resolvers.expansion(str)))
- lst = expandedpathfromlist(l)
- lists[str] = lst
- end
- return lst
+ if not instance.lists[str] then -- cached
+ local lst = made_list(instance,resolvers.splitpath(resolvers.expansion(str)))
+ instance.lists[str] = expandedpathfromlist(lst)
+ end
+ return instance.lists[str]
else
local lst = resolvers.splitpath(resolvers.expansion(str))
return made_list(instance,expandedpathfromlist(lst))
end
end
-function resolvers.expandedpathlistfromvariable(str) -- brrr / could also have cleaner ^!! /$ //
+function resolvers.expandedpathlistfromvariable(str) -- brrr
str = lpegmatch(dollarstripper,str)
local tmp = resolvers.variableofformatorsuffix(str)
return resolvers.expandedpathlist(tmp ~= "" and tmp or str)
@@ -14049,7 +13315,7 @@ local preparetreepattern = Cs((P(".")/"%%." + P("-")/"%%-" + P(1))^0 * Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype, wantedfiles, ext = '', { }, suffixonly(filename)
+ local filetype, wantedfiles, ext = '', { }, fileextname(filename)
-- too tricky as filename can be bla.1.2.3:
--
-- if not suffixmap[ext] then
@@ -14127,7 +13393,7 @@ local function find_qualified(filename,allresults) -- this one will be split too
if trace_detail then
report_resolving("locating qualified file '%s'", filename)
end
- local forcedname, suffix = "", suffixonly(filename)
+ local forcedname, suffix = "", fileextname(filename)
if suffix == "" then -- why
local format_suffixes = askedformat == "" and resolvers.defaultsuffixes or suffixes[askedformat]
if format_suffixes then
@@ -14797,8 +14063,6 @@ local gsub = string.gsub
local cleanpath, findgivenfile, expansion = resolvers.cleanpath, resolvers.findgivenfile, resolvers.expansion
local getenv = resolvers.getenv -- we can probably also use resolvers.expansion
local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
-local joinpath, basename, dirname = file.join, file.basename, file.dirname
-local getmetatable, rawset, type = getmetatable, rawset, type
-- getenv = function(...) return resolvers.getenv(...) end -- needs checking (definitions changes later on)
@@ -14840,43 +14104,28 @@ end
prefixes.filename = function(str)
local fullname = findgivenfile(str) or ""
- return cleanpath(basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
+ return cleanpath(file.basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
end
prefixes.pathname = function(str)
local fullname = findgivenfile(str) or ""
- return cleanpath(dirname((fullname ~= "" and fullname) or str))
+ return cleanpath(file.dirname((fullname ~= "" and fullname) or str))
end
prefixes.selfautoloc = function(str)
- return cleanpath(joinpath(getenv('SELFAUTOLOC'),str))
+ return cleanpath(file.join(getenv('SELFAUTOLOC'),str))
end
prefixes.selfautoparent = function(str)
- return cleanpath(joinpath(getenv('SELFAUTOPARENT'),str))
+ return cleanpath(file.join(getenv('SELFAUTOPARENT'),str))
end
prefixes.selfautodir = function(str)
- return cleanpath(joinpath(getenv('SELFAUTODIR'),str))
+ return cleanpath(file.join(getenv('SELFAUTODIR'),str))
end
prefixes.home = function(str)
- return cleanpath(joinpath(getenv('HOME'),str))
-end
-
-local function toppath()
- local pathname = dirname(inputstack[#inputstack] or "")
- if pathname == "" then
- return "."
- else
- return pathname
- end
-end
-
-resolvers.toppath = toppath
-
-prefixes.toppath = function(str)
- return cleanpath(joinpath(toppath(),str))
+ return cleanpath(file.join(getenv('HOME'),str))
end
prefixes.env = prefixes.environment
@@ -14912,8 +14161,6 @@ function resolvers.resetresolve(str)
resolved, abstract = { }, { }
end
--- todo: use an lpeg (see data-lua for !! / stripper)
-
local function resolve(str) -- use schemes, this one is then for the commandline only
if type(str) == "table" then
local t = { }
@@ -14939,7 +14186,7 @@ end
resolvers.resolve = resolve
resolvers.unresolve = unresolve
-if type(os.uname) == "function" then
+if os.uname then
for k, v in next, os.uname() do
if not prefixes[k] then
@@ -14951,17 +14198,11 @@ end
if os.type == "unix" then
- -- We need to distringuish between a prefix and something else : so we
- -- have a special repath variant for linux. Also, when a new prefix is
- -- defined, we need to remake the matcher.
-
local pattern
local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
local colon = P(":")
+ local p
for k, v in table.sortedpairs(prefixes) do
if p then
p = P(k) + p
@@ -14970,6 +14211,9 @@ if os.type == "unix" then
end
end
pattern = Cs((p * colon + colon/";" + P(1))^0)
+ if t then
+ t[k] = v
+ end
end
makepattern()
@@ -15180,7 +14424,18 @@ local trace_cache = false trackers.register("resolvers.cache", functi
local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
+--[[ldx--
+
Once we found ourselves defining similar cache constructs
+several times, containers were introduced. Containers are used
+to collect tables in memory and reuse them when possible based
+on (unique) hashes (to be provided by the calling function).
+
+
Caching to disk is disabled by default. Version numbers are
+stored in the saved table which makes it possible to change the
+table structures without bothering about the disk cache.
+
Examples of usage can be found in the font related code.
+--ldx]]--
containers = containers or { }
local containers = containers
@@ -15415,7 +14670,11 @@ local trace_locating = false trackers.register("resolvers.locating", function(v
local report_zip = logs.reporter("resolvers","zip")
-
+-- zip:///oeps.zip?name=bla/bla.tex
+-- zip:///oeps.zip?tree=tex/texmf-local
+-- zip:///texmf.zip?tree=/tex/texmf
+-- zip:///texmf.zip?tree=/tex/texmf-local
+-- zip:///texmf-mine.zip?tree=/tex/texmf-projects
local resolvers = resolvers
@@ -15740,7 +14999,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['data-sch'] = {
+if not modules then modules = { } end modules ['data-crl'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -15748,199 +15007,60 @@ if not modules then modules = { } end modules ['data-sch'] = {
license = "see context related readme files"
}
-local loadstring = loadstring
-local gsub, concat, format = string.gsub, table.concat, string.format
-local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
-
-local trace_schemes = false trackers.register("resolvers.schemes",function(v) trace_schemes = v end)
-local report_schemes = logs.reporter("resolvers","schemes")
-
-local http = require("socket.http")
-local ltn12 = require("ltn12")
+-- this one is replaced by data-sch.lua --
-local resolvers = resolvers
-local schemes = resolvers.schemes or { }
-resolvers.schemes = schemes
-
-local cleaners = { }
-schemes.cleaners = cleaners
-
-local threshold = 24 * 60 * 60
-
-directives.register("schemes.threshold", function(v) threshold = tonumber(v) or threshold end)
-
-function cleaners.none(specification)
- return specification.original
-end
-
-function cleaners.strip(specification)
- return (gsub(specification.original,"[^%a%d%.]+","-")) -- so we keep periods
-end
-
-function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
-end
-
-local cleaner = cleaners.strip
+local gsub = string.gsub
-directives.register("schemes.cleanmethod", function(v) cleaner = cleaners[v] or cleaners.strip end)
+local resolvers = resolvers
-function resolvers.schemes.cleanname(specification)
- local hash = cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %s to %s",specification.original,hash)
- end
- return hash
-end
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
-local cached, loaded, reused, thresholds, handlers = { }, { }, { }, { }, { }
+resolvers.curl = resolvers.curl or { }
+local curl = resolvers.curl
-local function runcurl(name,cachename) -- we use sockets instead or the curl library when possible
- local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name
- os.spawn(command)
-end
+local cached = { }
-local function fetch(specification)
+local function runcurl(specification)
local original = specification.original
- local scheme = specification.scheme
- local cleanname = schemes.cleanname(specification)
- local cachename = caches.setfirstwritablefile(cleanname,"schemes")
+ -- local scheme = specification.scheme
+ local cleanname = gsub(original,"[^%a%d%.]+","-")
+ local cachename = caches.setfirstwritablefile(cleanname,"curl")
if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification) > (thresholds[protocol] or threshold)) then
+ if not io.exists(cachename) then
cached[original] = cachename
- local handler = handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching '%s', protocol '%s', method 'built-in'",original,scheme)
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching '%s', protocol '%s', method 'curl'",original,scheme)
- end
- logs.flush()
- runcurl(original,cachename)
- end
+ local command = "curl --silent --create-dirs --output " .. cachename .. " " .. original
+ os.spawn(command)
end
if io.exists(cachename) then
cached[original] = cachename
- if trace_schemes then
- report_schemes("using cached '%s', protocol '%s', cachename '%s'",original,scheme,cachename)
- end
else
cached[original] = ""
- if trace_schemes then
- report_schemes("using missing '%s', protocol '%s'",original,scheme)
- end
end
- loaded[scheme] = loaded[scheme] + 1
- statistics.stoptiming(schemes)
- else
- if trace_schemes then
- report_schemes("reusing '%s', protocol '%s'",original,scheme)
- end
- reused[scheme] = reused[scheme] + 1
end
return cached[original]
end
+-- old code: we could be cleaner using specification (see schemes)
+
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",runcurl(specification),filetype)
end
local opener = openers.file
local loader = loaders.file
-local function install(scheme,handler,newthreshold)
- handlers [scheme] = handler
- loaded [scheme] = 0
- reused [scheme] = 0
- finders [scheme] = finder
- openers [scheme] = opener
- loaders [scheme] = loader
- thresholds[scheme] = newthreshold or threshold
+local function install(scheme)
+ finders[scheme] = finder
+ openers[scheme] = opener
+ loaders[scheme] = loader
end
-schemes.install = install
-
-local function http_handler(specification,cachename)
- local tempname = cachename .. ".tmp"
- local f = io.open(tempname,"wb")
- local status, message = http.request {
- url = specification.original,
- sink = ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
-end
+resolvers.curl.install = install
-install('http',http_handler)
-install('https') -- see pod
+install('http')
+install('https')
install('ftp')
-statistics.register("scheme handling time", function()
- local l, r, nl, nr = { }, { }, 0, 0
- for k, v in table.sortedhash(loaded) do
- if v > 0 then
- nl = nl + 1
- l[nl] = k .. ":" .. v
- end
- end
- for k, v in table.sortedhash(reused) do
- if v > 0 then
- nr = nr + 1
- r[nr] = k .. ":" .. v
- end
- end
- local n = nl + nr
- if n > 0 then
- l = nl > 0 and concat(l) or "none"
- r = nr > 0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes), n, threshold, l, r)
- else
- return nil
- end
-end)
-
--- We provide a few more helpers:
-
------ http = require("socket.http")
-local httprequest = http.request
-local toquery = url.toquery
-
--- local function httprequest(url)
--- return os.resultof(format("curl --silent %q", url))
--- end
-
-local function fetchstring(url,data)
- local q = data and toquery(data)
- if q then
- url = url .. "?" .. q
- end
- local reply = httprequest(url)
- return reply -- just one argument
-end
-
-schemes.fetchstring = fetchstring
-
-function schemes.fetchtable(url,data)
- local reply = fetchstring(url,data)
- if reply then
- local s = loadstring("return " .. reply)
- if s then
- return s()
- end
- end
-end
-
end -- of closure
@@ -15954,199 +15074,170 @@ if not modules then modules = { } end modules ['data-lua'] = {
license = "see context related readme files"
}
--- We overload the regular loader. We do so because we operate mostly in
--- tds and use our own loader code. Alternatively we could use a more
--- extensive definition of package.path and package.cpath but even then
--- we're not done. Also, we now have better tracing.
---
--- -- local mylib = require("libtest")
--- -- local mysql = require("luasql.mysql")
-
-local concat = table.concat
-
-local trace_libraries = false
+-- some loading stuff ... we might move this one to slot 2 depending
+-- on the developments (the loaders must not trigger kpse); we could
+-- of course use a more extensive lib path spec
-trackers.register("resolvers.libraries", function(v) trace_libraries = v end)
-trackers.register("resolvers.locating", function(v) trace_libraries = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local report_libraries = logs.reporter("resolvers","libraries")
local gsub, insert = string.gsub, table.insert
-local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
local unpack = unpack or table.unpack
-local is_readable = file.is_readable
local resolvers, package = resolvers, package
-local libsuffixes = { 'tex', 'lua' }
-local clibsuffixes = { 'lib' }
-local libformats = { 'TEXINPUTS', 'LUAINPUTS' }
-local clibformats = { 'CLUAINPUTS' }
-
-local libpaths = nil
-local clibpaths = nil
-local libhash = { }
-local clibhash = { }
-local libextras = { }
-local clibextras = { }
-
-local pattern = Cs(P("!")^0 / "" * (P("/") * P(-1) / "/" + P("/")^1 / "/" + 1)^0)
-
-local function cleanpath(path) --hm, don't we have a helper for this?
- return resolvers.resolve(lpegmatch(pattern,path))
-end
-
-local function getlibpaths()
- if not libpaths then
- libpaths = { }
- for i=1,#libformats do
- local paths = resolvers.expandedpathlistfromvariable(libformats[i])
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not libhash[path] then
- libpaths[#libpaths+1] = path
- libhash[path] = true
- end
- end
- end
+local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs'
+local clibformats = { 'lib' }
+
+local _path_, libpaths, _cpath_, clibpaths
+
+function package.libpaths()
+ if not _path_ or package.path ~= _path_ then
+ _path_ = package.path
+ libpaths = file.splitpath(_path_,";")
end
return libpaths
end
-local function getclibpaths()
- if not clibpaths then
- clibpaths = { }
- for i=1,#clibformats do
- local paths = resolvers.expandedpathlistfromvariable(clibformats[i])
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not clibhash[path] then
- clibpaths[#clibpaths+1] = path
- clibhash[path] = true
- end
- end
- end
+function package.clibpaths()
+ if not _cpath_ or package.cpath ~= _cpath_ then
+ _cpath_ = package.cpath
+ clibpaths = file.splitpath(_cpath_,";")
end
return clibpaths
end
-package.libpaths = getlibpaths
-package.clibpaths = getclibpaths
-
-function package.extralibpath(...)
- local paths = { ... }
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not libhash[path] then
- if trace_libraries then
- report_libraries("! extra lua path '%s'",path)
- end
- libextras[#libextras+1] = path
- libpaths[#libpaths +1] = path
- end
+local function thepath(...)
+ local t = { ... } t[#t+1] = "?.lua"
+ local path = file.join(unpack(t))
+ if trace_locating then
+ report_libraries("! appending '%s' to 'package.path'",path)
end
+ return path
end
-function package.extraclibpath(...)
- local paths = { ... }
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not clibhash[path] then
- if trace_libraries then
- report_libraries("! extra lib path '%s'",path)
- end
- clibextras[#clibextras+1] = path
- clibpaths[#clibpaths +1] = path
- end
- end
-end
+local p_libpaths, a_libpaths = { }, { }
-if not package.loaders[-2] then
- -- use package-path and package-cpath
- package.loaders[-2] = package.loaders[2]
+function package.appendtolibpath(...)
+ insert(a_libpath,thepath(...))
end
-local function loadedaslib(resolved,rawname)
- return package.loadlib(resolved,"luaopen_" .. gsub(rawname,"%.","_"))
+function package.prependtolibpath(...)
+ insert(p_libpaths,1,thepath(...))
end
-local function loadedbylua(name)
- if trace_libraries then
- report_libraries("! locating %q using normal loader",name)
+-- beware, we need to return a loadfile result !
+
+local function loaded(libpaths,name,simple)
+ for i=1,#libpaths do -- package.path, might become option
+ local libpath = libpaths[i]
+ local resolved = gsub(libpath,"%?",simple)
+ if trace_locating then -- more detail
+ report_libraries("! checking for '%s' on 'package.path': '%s' => '%s'",simple,libpath,resolved)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'package.path': '%s'",name,resolved)
+ end
+ return loadfile(resolved)
+ end
end
- local resolved = package.loaders[-2](name)
end
-local function loadedbyformat(name,rawname,suffixes,islib)
- if trace_libraries then
- report_libraries("! locating %q as %q using formats %q",rawname,name,concat(suffixes))
+package.loaders[2] = function(name) -- was [#package.loaders+1]
+ if file.suffix(name) == "" then
+ name = file.addsuffix(name,"lua") -- maybe a list
+ if trace_locating then -- mode detail
+ report_libraries("! locating '%s' with forced suffix",name)
+ end
+ else
+ if trace_locating then -- mode detail
+ report_libraries("! locating '%s'",name)
+ end
end
- for i=1,#suffixes do -- so we use findfile and not a lookup loop
- local format = suffixes[i]
+ for i=1,#libformats do
+ local format = libformats[i]
local resolved = resolvers.findfile(name,format) or ""
- if trace_libraries then
- report_libraries("! checking for %q' using format %q",name,format)
+ if trace_locating then -- mode detail
+ report_libraries("! checking for '%s' using 'libformat path': '%s'",name,format)
end
if resolved ~= "" then
- if trace_libraries then
- report_libraries("! lib %q located on %q",name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
+ if trace_locating then
+ report_libraries("! lib '%s' located via environment: '%s'",name,resolved)
end
+ return loadfile(resolved)
end
end
-end
-
-local function loadedbypath(name,rawname,paths,islib,what)
- if trace_libraries then
- report_libraries("! locating %q as %q on %q paths",rawname,name,what)
+ -- libpaths
+ local libpaths, clibpaths = package.libpaths(), package.clibpaths()
+ local simple = gsub(name,"%.lua$","")
+ local simple = gsub(simple,"%.","/")
+ local resolved = loaded(p_libpaths,name,simple) or loaded(libpaths,name,simple) or loaded(a_libpaths,name,simple)
+ if resolved then
+ return resolved
end
- for p=1,#paths do
- local path = paths[p]
- local resolved = file.join(path,name)
- if trace_libraries then -- mode detail
- report_libraries("! checking for %q using %q path %q",name,what,path)
- end
- if is_readable(resolved) then
- if trace_libraries then
- report_libraries("! lib %q located on %q",name,resolved)
+ --
+ local libname = file.addsuffix(simple,os.libsuffix)
+ for i=1,#clibformats do
+ -- better have a dedicated loop
+ local format = clibformats[i]
+ local paths = resolvers.expandedpathlistfromvariable(format)
+ for p=1,#paths do
+ local path = paths[p]
+ local resolved = file.join(path,libname)
+ if trace_locating then -- mode detail
+ report_libraries("! checking for '%s' using 'clibformat path': '%s'",libname,path)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'clibformat': '%s'",libname,resolved)
+ end
+ return package.loadlib(resolved,name)
end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
+ end
+ end
+ for i=1,#clibpaths do -- package.path, might become option
+ local libpath = clibpaths[i]
+ local resolved = gsub(libpath,"?",simple)
+ if trace_locating then -- more detail
+ report_libraries("! checking for '%s' on 'package.cpath': '%s'",simple,libpath)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'package.cpath': '%s'",name,resolved)
end
+ return package.loadlib(resolved,name)
end
end
-end
-
-local function notloaded(name)
- if trace_libraries then
- report_libraries("? unable to locate library %q",name)
+ -- just in case the distribution is messed up
+ if trace_loading then -- more detail
+ report_libraries("! checking for '%s' using 'luatexlibs': '%s'",name)
+ end
+ local resolved = resolvers.findfile(file.basename(name),'luatexlibs') or ""
+ if resolved ~= "" then
+ if trace_locating then
+ report_libraries("! lib '%s' located by basename via environment: '%s'",name,resolved)
+ end
+ return loadfile(resolved)
+ end
+ if trace_locating then
+ report_libraries('? unable to locate lib: %s',name)
end
+-- return "unable to locate " .. name
end
-package.loaders[2] = function(name)
- local thename = gsub(name,"%.","/")
- local luaname = file.addsuffix(thename,"lua")
- local libname = file.addsuffix(thename,os.libsuffix)
- return
- loadedbyformat(luaname,name,libsuffixes, false)
- or loadedbyformat(libname,name,clibsuffixes, true)
- or loadedbypath (luaname,name,getlibpaths (),false,"lua")
- or loadedbypath (luaname,name,getclibpaths(),false,"lua")
- or loadedbypath (libname,name,getclibpaths(),true, "lib")
- or loadedbylua (name)
- or notloaded (name)
-end
+resolvers.loadlualib = require
--- package.loaders[3] = nil
--- package.loaders[4] = nil
+-- -- -- --
-resolvers.loadlualib = require
+package.obsolete = package.obsolete or { }
+
+package.append_libpath = appendtolibpath -- will become obsolete
+package.prepend_libpath = prependtolibpath -- will become obsolete
+
+package.obsolete.append_libpath = appendtolibpath -- will become obsolete
+package.obsolete.prepend_libpath = prependtolibpath -- will become obsolete
end -- of closure
@@ -16616,6 +15707,7 @@ function environment.make_format(name)
end
function environment.run_format(name,data,more)
+ -- hm, rather old code here; we can now use the file.whatever functions
if name and name ~= "" then
local barename = file.removesuffix(name)
local fmtname = caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats")
@@ -16644,129 +15736,6 @@ function environment.run_format(name,data,more)
end
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-if not modules then modules = { } end modules ['util-tpl'] = {
- 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"
-}
-
--- This is experimental code. Coming from dos and windows, I've always used %whatever%
--- as template variables so let's stick to it. After all, it's easy to parse and stands
--- out well. A double %% is turned into a regular %.
-
-utilities.templates = utilities.templates or { }
-local templates = utilities.templates
-
-local trace_template = false trackers.register("templates.trace",function(v) trace_template = v end)
-local report_template = logs.reporter("template")
-
-local format = string.format
-local P, C, Cs, Carg, lpegmatch = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Carg, lpeg.match
-
--- todo: make installable template.new
-
-local replacer
-
-local function replacekey(k,t,recursive)
- local v = t[k]
- if not v then
- if trace_template then
- report_template("unknown key %q",k)
- end
- return ""
- else
- if trace_template then
- report_template("setting key %q to value %q",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t)
- else
- return v
- end
- end
-end
-
-local sqlescape = lpeg.replacer {
- { "'", "''" },
- { "\\", "\\\\" },
- { "\r\n", "\\n" },
- { "\r", "\\n" },
- -- { "\t", "\\t" },
-}
-
-local escapers = {
- lua = function(s)
- return format("%q",s)
- end,
- sql = function(s)
- return lpegmatch(sqlescape,s)
- end,
-}
-
-local function replacekeyunquoted(s,t,how,recurse) -- ".. \" "
- local escaper = how and escapers[how] or escapers.lua
- return escaper(replacekey(s,t,recurse))
-end
-
-local single = P("%") -- test %test% test : resolves test
-local double = P("%%") -- test 10%% test : %% becomes %
-local lquoted = P("%[") -- test %[test]" test : resolves test with escaped "'s
-local rquoted = P("]%") --
-
-local escape = double / '%%'
-local nosingle = single / ''
-local nodouble = double / ''
-local nolquoted = lquoted / ''
-local norquoted = rquoted / ''
-
-local key = nosingle * (C((1-nosingle)^1 * Carg(1) * Carg(2) * Carg(3))/replacekey) * nosingle
-local unquoted = nolquoted * ((C((1 - norquoted)^1) * Carg(1) * Carg(2) * Carg(3))/replacekeyunquoted) * norquoted
-local any = P(1)
-
- replacer = Cs((unquoted + escape + key + any)^0)
-
-local function replace(str,mapping,how,recurse)
- if mapping then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
-end
-
--- print(replace("test '%[x]%' test",{ x = [[a 'x' a]] }))
--- print(replace("test '%[x]%' test",{ x = [[a 'x' a]] },'sql'))
-
-templates.replace = replace
-
-function templates.load(filename,mapping,how,recurse)
- local data = io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
-end
-
-function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping = t
- end
- for k, v in next, t do
- t[k] = replace(v,mapping,how,recurse)
- end
- return t
-end
-
--- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" }))
--- inspect(utilities.templates.resolve({ one = "%two%", two = "two", three = "%three%" }))
-
-
end -- of closure
-- end library merge
@@ -16827,7 +15796,7 @@ own.libs = { -- order can be made better
-- 'data-bin.lua',
'data-zip.lua',
'data-tre.lua',
- 'data-sch.lua',
+ 'data-crl.lua',
'data-lua.lua',
'data-aux.lua', -- updater
'data-tmf.lua',
@@ -16835,8 +15804,6 @@ own.libs = { -- order can be made better
'luat-sta.lua',
'luat-fmt.lua',
-
- 'util-tpl.lua',
}
-- We need this hack till luatex is fixed.
@@ -16857,7 +15824,7 @@ own.path = gsub(match(own.name,"^(.+)[\\/].-$") or ".","\\","/")
local ownpath, owntree = own.path, environment and environment.ownpath or own.path
-own.list = { -- predictable paths
+own.list = {
'.',
ownpath ,
ownpath .. "/../sources", -- HH's development path
@@ -16881,7 +15848,7 @@ local function locate_libs()
local filename = pth .. "/" .. lib
local found = lfs.isfile(filename)
if found then
- package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require (probably obsolete)
+ package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require
return pth
end
end
@@ -17013,7 +15980,6 @@ local helpinfo = [[
--var-value report value of variable
--find-file report file location
--find-path report path of file
---show-package-path report package paths
--pattern=str filter variables
]]
@@ -17127,8 +16093,7 @@ function runners.execute_script(fullname,internal,nosplit)
elseif state == 'skip' then
return true
elseif state == "run" then
- local path, name, suffix = file.splitname(fullname)
- local result = ""
+ local path, name, suffix, result = file.dirname(fullname), file.basename(fullname), file.extname(fullname), ""
if path ~= "" then
result = fullname
elseif name then
@@ -17139,7 +16104,7 @@ function runners.execute_script(fullname,internal,nosplit)
name = gsub(name,"^script:","")
if suffix == "" and runners.registered[name] and runners.registered[name][1] then
name = runners.registered[name][1]
- suffix = file.suffix(name)
+ suffix = file.extname(name)
end
if suffix == "" then
-- loop over known suffixes
@@ -17166,7 +16131,7 @@ function runners.execute_script(fullname,internal,nosplit)
environment.ownscript = result
dofile(result)
else
- local binary = runners.applications[file.suffix(result)]
+ local binary = runners.applications[file.extname(result)]
result = string.quoted(string.unquoted(result))
-- if string.match(result,' ') and not string.match(result,"^\".*\"$") then
-- result = '"' .. result .. '"'
@@ -17359,7 +16324,7 @@ function resolvers.launch(str)
-- maybe we also need to test on mtxrun.launcher.suffix environment
-- variable or on windows consult the assoc and ftype vars and such
local launchers = runners.launchers[os.platform] if launchers then
- local suffix = file.suffix(str) if suffix then
+ local suffix = file.extname(str) if suffix then
local runner = launchers[suffix] if runner then
str = runner .. " " .. str
end
@@ -17418,7 +16383,7 @@ function runners.find_mtx_script(filename)
end
filename = file.addsuffix(filename,"lua")
local basename = file.removesuffix(file.basename(filename))
- local suffix = file.suffix(filename)
+ local suffix = file.extname(filename)
-- qualified path, raw name
local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename
if fullname and fullname ~= "" then
@@ -17473,7 +16438,7 @@ function runners.execute_ctx_script(filename,...)
runners.register_arguments(...)
local arguments = environment.arguments_after
local fullname = runners.find_mtx_script(filename) or ""
- if file.suffix(fullname) == "cld" then
+ if file.extname(fullname) == "cld" then
-- handy in editors where we force --autopdf
report("running cld script: %s",filename)
table.insert(arguments,1,fullname)
@@ -17581,21 +16546,6 @@ function runners.timed(action)
statistics.timed(action)
end
-function runners.associate(filename)
- os.launch(filename)
-end
-
-function runners.gethelp(filename)
- local url = environment.argument("url")
- if url and url ~= "" then
- local command = string.gsub(environment.argument("command") or "unknown","^%s*\\*(.-)%s*$","%1")
- url = utilities.templates.replace(url,{ command = command })
- os.launch(url)
- else
- report("no --url given")
- end
-end
-
-- this is a bit dirty ... first we store the first filename and next we
-- split the arguments so that we only see the ones meant for this script
-- ... later we will use the second half
@@ -17698,18 +16648,7 @@ else
end
-if e_argument("script") or e_argument("scripts") then
-
- -- run a script by loading it (using libs), pass args
-
- runners.loadbase()
- if is_mkii_stub then
- ok = runners.execute_script(filename,false,true)
- else
- ok = runners.execute_ctx_script(filename)
- end
-
-elseif e_argument("selfmerge") then
+if e_argument("selfmerge") then
-- embed used libraries
@@ -17732,19 +16671,6 @@ elseif e_argument("selfupdate") then
trackers.enable("resolvers.locating")
resolvers.updatescript(own.name,"mtxrun")
-elseif e_argument("show-package-path") or e_argument("show-package-paths") then
-
- local l = package.libpaths()
- local c = package.clibpaths()
-
- for i=1,#l do
- report("package lib path %s: %s",i,l[i])
- end
-
- for i=1,#c do
- report("package clib path %s: %s",i,c[i])
- end
-
elseif e_argument("ctxlua") or e_argument("internal") then
-- run a script by loading it (using libs)
@@ -17752,6 +16678,17 @@ elseif e_argument("ctxlua") or e_argument("internal") then
runners.loadbase()
ok = runners.execute_script(filename,true)
+elseif e_argument("script") or e_argument("scripts") then
+
+ -- run a script by loading it (using libs), pass args
+
+ runners.loadbase()
+ if is_mkii_stub then
+ ok = runners.execute_script(filename,false,true)
+ else
+ ok = runners.execute_ctx_script(filename)
+ end
+
elseif e_argument("execute") then
-- execute script
@@ -17778,14 +16715,6 @@ elseif e_argument("launch") then
runners.loadbase()
runners.launch_file(filename)
-elseif e_argument("associate") then
-
- runners.associate(filename)
-
-elseif e_argument("gethelp") then
-
- runners.gethelp()
-
elseif e_argument("makestubs") then
-- make stubs (depricated)
@@ -17877,7 +16806,7 @@ elseif e_argument("find-path") then
elseif e_argument("expand-braces") then
- -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename)
+ -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename
resolvers.load("nofiles")
runners.register_arguments(filename)
diff --git a/scripts/context/ruby/fcd_start.rb b/scripts/context/ruby/fcd_start.rb
new file mode 100644
index 000000000..b1fa42a2a
--- /dev/null
+++ b/scripts/context/ruby/fcd_start.rb
@@ -0,0 +1,472 @@
+# Hans Hagen / PRAGMA ADE / 2005 / www.pragma-ade.com
+#
+# Fast Change Dir
+#
+# This is a kind of variant of the good old ncd
+# program. This script uses the same indirect cmd
+# trick as Erwin Waterlander's wcd program.
+#
+# === windows: fcd.cmd ===
+#
+# @echo off
+# ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9
+# if exist "%HOME%/fcd_stage.cmd" call %HOME%/fcd_stage.cmd
+#
+# === linux: fcd (fcd.sh) ===
+#
+# !/usr/bin/env sh
+# ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9
+# if test -f "$HOME/fcd_stage.sh" ; then
+# . $HOME/fcd_stage.sh ;
+# fi;
+#
+# ===
+#
+# On linux, one should source the file: ". fcd args" in order
+# to make the chdir persistent.
+#
+# You can create a stub with:
+#
+# ruby fcd_start.rb --stub --verbose
+#
+# usage:
+#
+# fcd --make t:\
+# fcd --add f:\project
+# fcd [--find] whatever
+# fcd [--find] whatever c (c being a list entry)
+# fcd [--find] whatever . (last choice with this pattern)
+# fcd --list
+
+# todo: HOMEDRIVE\HOMEPATH
+
+require 'rbconfig'
+
+class FastCD
+
+ @@rootpath = nil
+
+ ['HOME','TEMP','TMP','TMPDIR'].each do |key|
+ if ENV[key] then
+ if FileTest.directory?(ENV[key]) then
+ @@rootpath = ENV[key]
+ break
+ end
+ end
+ end
+
+ exit unless @@rootpath
+
+ @@mswindows = Config::CONFIG['host_os'] =~ /mswin/
+ @@maxlength = 26
+
+ require 'Win32API' if @@mswindows
+
+ if @@mswindows then
+ @@stubcode = [
+ '@echo off',
+ '',
+ 'if not exist "%HOME%" goto temp',
+ '',
+ ':home',
+ '',
+ 'ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9',
+ '',
+ 'if exist "%HOME%\fcd_stage.cmd" call %HOME%\fcd_stage.cmd',
+ 'goto end',
+ '',
+ ':temp',
+ '',
+ 'ruby -S fcd_start.rb %1 %2 %3 %4 %5 %6 %7 %8 %9',
+ '',
+ 'if exist "%TEMP%\fcd_stage.cmd" call %TEMP%\fcd_stage.cmd',
+ 'goto end',
+ '',
+ ':end'
+ ].join("\n")
+ else
+ @@stubcode = [
+ '#!/usr/bin/env sh',
+ '',
+ 'ruby -S fcd_start.rb $1 $2 $3 $4 $5 $6 $7 $8 $9',
+ '',
+ 'if test -f "$HOME/fcd_stage.sh" ; then',
+ ' . $HOME/fcd_stage.sh ;',
+ 'fi;'
+ ].join("\n")
+ end
+
+ @@selfpath = File.dirname($0)
+ @@datafile = File.join(@@rootpath,'fcd_state.dat')
+ @@histfile = File.join(@@rootpath,'fcd_state.his')
+ @@cdirfile = File.join(@@rootpath,if @@mswindows then 'fcd_stage.cmd' else 'fcd_stage.sh' end)
+ @@stubfile = File.join(@@selfpath,if @@mswindows then 'fcd.cmd' else 'fcd' end)
+
+ def initialize(verbose=false)
+ @list = Array.new
+ @hist = Hash.new
+ @result = Array.new
+ @pattern = ''
+ @result = ''
+ @verbose = verbose
+ if f = File.open(@@cdirfile,'w') then
+ f << "#{if @@mswindows then 'rem' else '#' end} no dir to change to"
+ f.close
+ else
+ report("unable to create stub #{@@cdirfile}")
+ end
+ end
+
+ def filename(name)
+ File.join(@@root,name)
+ end
+
+ def report(str,verbose=@verbose)
+ puts(">> #{str}") if verbose
+ end
+
+ def flush(str,verbose=@verbose)
+ print(str) if verbose
+ end
+
+ def clear
+ if FileTest.file?(@@histfile)
+ begin
+ File.delete(@@histfile)
+ rescue
+ report("error in deleting history file '#{@histfile}'")
+ else
+ report("history file '#{@histfile}' is deleted")
+ end
+ else
+ report("no history file '#{@histfile}'")
+ end
+ end
+
+ def scan(dir='.')
+ begin
+ [dir].flatten.sort.uniq.each do |dir|
+ begin
+ Dir.chdir(dir)
+ report("scanning '#{dir}'")
+ # flush(">> ")
+ Dir.glob("**/*").each do |d|
+ if FileTest.directory?(d) then
+ @list << File.expand_path(d)
+ # flush(".")
+ end
+ end
+ # flush("\n")
+ @list = @list.sort.uniq
+ report("#{@list.size} entries found")
+ rescue
+ report("unknown directory '#{dir}'")
+ end
+ end
+ rescue
+ report("invalid dir specification ")
+ end
+ end
+
+ def save
+ begin
+ if f = File.open(@@datafile,'w') then
+ @list.each do |l|
+ f.puts(l)
+ end
+ f.close
+ report("#{@list.size} status bytes saved in #{@@datafile}")
+ else
+ report("unable to save status in #{@@datafile}")
+ end
+ rescue
+ report("error in saving status in #{@@datafile}")
+ end
+ end
+
+ def remember
+ if @hist[@pattern] == @result then
+ # no need to save result
+ else
+ begin
+ if f = File.open(@@histfile,'w') then
+ @hist[@pattern] = @result
+ @hist.keys.each do |k|
+ f.puts("#{k} #{@hist[k]}")
+ end
+ f.close
+ report("#{@hist.size} history entries saved in #{@@histfile}")
+ else
+ report("unable to save history in #{@@histfile}")
+ end
+ rescue
+ report("error in saving history in #{@@histfile}")
+ end
+ end
+ end
+
+ def load
+ begin
+ @list = IO.read(@@datafile).split("\n")
+ report("#{@list.length} status bytes loaded from #{@@datafile}")
+ rescue
+ report("error in loading status from #{@@datafile}")
+ end
+ begin
+ IO.readlines(@@histfile).each do |line|
+ if line =~ /^(.*?)\s+(.*)$/i then
+ @hist[$1] = $2
+ end
+ end
+ report("#{@hist.length} history entries loaded from #{@@histfile}")
+ rescue
+ report("error in loading history from #{@@histfile}")
+ end
+ end
+
+ def show
+ begin
+ puts("directories:")
+ puts("\n")
+ if @list.length > 0 then
+ @list.each do |l|
+ puts(l)
+ end
+ else
+ puts("no entries")
+ end
+ puts("\n")
+ puts("history:")
+ puts("\n")
+ if @hist.length > 0 then
+ @hist.keys.sort.each do |h|
+ puts("#{h} >> #{@hist[h]}")
+ end
+ else
+ puts("no entries")
+ end
+ rescue
+ end
+ end
+
+ def find(pattern=nil)
+ begin
+ if pattern = [pattern].flatten.first then
+ if pattern.length > 0 and @pattern = pattern then
+ @result = @list.grep(/\/#{@pattern}$/i)
+ if @result.length == 0 then
+ @result = @list.grep(/\/#{@pattern}[^\/]*$/i)
+ end
+ end
+ else
+ puts(Dir.pwd.gsub(/\\/o, '/'))
+ end
+ rescue
+ puts("some error")
+ end
+ end
+
+ def chdir(dir)
+ begin
+ if dir then
+ if f = File.open(@@cdirfile,'w') then
+ if @@mswindows then
+ f.puts("cd /d #{dir.gsub('/','\\')}")
+ else
+ f.puts("cd #{dir.gsub("\\",'/')}")
+ end
+ f.close
+ end
+ @result = dir
+ report("changing to #{dir}",true)
+ else
+ report("not changing dir")
+ end
+ rescue
+ end
+ end
+
+ def choose(args=[])
+ offset = 97
+ unless @pattern.empty? then
+ begin
+ case @result.size
+ when 0 then
+ report("dir '#{@pattern}' not found",true)
+ when 1 then
+ chdir(@result[0])
+ else
+ list = @result.dup
+ begin
+ if answer = args[1] then # assignment & test
+ if answer == '.' and @hist.key?(@pattern) then
+ if FileTest.directory?(@hist[@pattern]) then
+ print("last choice ")
+ chdir(@hist[@pattern])
+ return
+ end
+ else
+ index = answer[0] - offset
+ if dir = list[index] then
+ chdir(dir)
+ return
+ end
+ end
+ end
+ rescue
+ puts("some error")
+ end
+ loop do
+ print("\n")
+ list.each_index do |i|
+begin
+ if i < @@maxlength then
+ # puts("#{(i+?a).chr} #{list[i]}")
+ puts("#{(i+offset).chr} #{list[i]}")
+ else
+ puts("\n there are #{list.length-@@maxlength} entries more")
+ break
+ end
+rescue
+ puts("some error")
+end
+ end
+ print("\n>> ")
+ if answer = wait then
+ if answer >= offset and answer <= offset+25 then
+ index = answer - offset
+ if dir = list[index] then
+ print("#{answer.chr} ")
+ chdir(dir)
+ elsif @hist.key?(@pattern) and FileTest.directory?(@hist[@pattern]) then
+ print("last choice ")
+ chdir(@hist[@pattern])
+ else
+ print("quit\n")
+ end
+ break
+ elsif list.length >= @@maxlength then
+ @@maxlength.times do |i| list.shift end
+ print("next set")
+ print("\n")
+ elsif @hist.key?(@pattern) and FileTest.directory?(@hist[@pattern]) then
+ print("last choice ")
+ chdir(@hist[@pattern])
+ break
+ else
+ print("quit\n")
+ break
+ end
+ end
+ end
+ end
+ rescue
+ report($!)
+ end
+ end
+ end
+
+ def wait
+ begin
+ $stdout.flush
+ return getc
+ rescue
+ return nil
+ end
+ end
+
+ def getc
+ begin
+ if @@mswindows then
+ ch = Win32API.new('crtdll','_getch',[],'L').call
+ else
+ system('stty raw -echo')
+ ch = $stdin.getc
+ system('stty -raw echo')
+ end
+ rescue
+ ch = nil
+ end
+ return ch
+ end
+
+ def check
+ unless FileTest.file?(@@stubfile) then
+ report("creating stub #{@@stubfile}")
+ begin
+ if f = File.open(@@stubfile,'w') then
+ f.puts(@@stubcode)
+ f.close
+ end
+ rescue
+ report("unable to create stub #{@@stubfile}")
+ else
+ unless @mswindows then
+ begin
+ File.chmod(0755,@@stubfile)
+ rescue
+ report("unable to change protections on #{@@stubfile}")
+ end
+ end
+ end
+ else
+ report("stub #{@@stubfile} already present")
+ end
+ end
+
+end
+
+$stdout.sync = true
+
+verbose, action, args = false, :find, Array.new
+
+usage = "fcd [--add|clear|find|list|make|show|stub] [--verbose] [pattern]"
+version = "1.0.2"
+
+def quit(message)
+ puts(message)
+ exit
+end
+
+ARGV.each do |a|
+ case a
+ when '-a', '--add' then action = :add
+ when '-c', '--clear' then action = :clear
+ when '-f', '--find' then action = :find
+ when '-l', '--list' then action = :show
+ when '-m', '--make' then action = :make
+ when '-s', '--show' then action = :show
+ when '--stub' then action = :stub
+ when '-v', '--verbose' then verbose = true
+ when '--version' then quit("version: #{version}")
+ when '-h', '--help' then quit("usage: #{usage}")
+ when /^\-\-.*/ then quit("error: unknown switch #{a}, try --help")
+ else args << a
+ end
+end
+
+fcd = FastCD.new(verbose)
+fcd.report("Fast Change Dir / version #{version}")
+
+case action
+ when :make then
+ fcd.clear
+ fcd.scan(args)
+ fcd.save
+ when :clear then
+ fcd.clear
+ when :add then
+ fcd.load
+ fcd.scan(args)
+ fcd.save
+ when :show then
+ fcd.load
+ fcd.show
+ when :find then
+ fcd.load
+ fcd.find(args)
+ fcd.choose(args)
+ fcd.remember
+ when :stub
+ fcd.check
+end
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index e6bbbe2b5..108f2a8a1 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -8,11 +8,6 @@ if not modules then modules = { } end modules ['mtxrun'] = {
license = "see context related readme files"
}
--- if not lpeg then require("lpeg") end
--- if not md5 then require("md5") end
--- if not lfs then require("lfs") end
--- if not texconfig then texconfig = { } end
-
-- one can make a stub:
--
-- #!/bin/sh
@@ -155,28 +150,11 @@ function string.topattern(str,lowercase,strict)
end
end
-
-function string.valid(str,default)
- return (type(str) == "string" and str ~= "" and str) or default or nil
-end
-
-- obsolete names:
string.quote = string.quoted
string.unquote = string.unquoted
--- handy fallback
-
-string.itself = function(s) return s end
-
--- also handy (see utf variant)
-
-local pattern = Ct(C(1)^0)
-
-function string.totable(str)
- return lpegmatch(pattern,str)
-end
-
end -- of closure
@@ -190,8 +168,7 @@ if not modules then modules = { } end modules ['l-table'] = {
license = "see context related readme files"
}
-local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs
-local table, string = table, string
+local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
@@ -202,8 +179,6 @@ local getinfo = debug.getinfo
-- impact on ConTeXt was not that large; the remaining ipairs already
-- have been replaced. In a similar fashion we also hardly used pairs.
--
--- Hm, actually ipairs was retained, but we no longer use it anyway.
---
-- Just in case, we provide the fallbacks as discussed in Programming
-- in Lua (http://www.lua.org/pil/7.3.html):
@@ -263,16 +238,12 @@ function table.strip(tab)
end
function table.keys(t)
- if t then
- local keys, k = { }, 0
- for key, _ in next, t do
- k = k + 1
- keys[k] = key
- end
- return keys
- else
- return { }
+ local keys, k = { }, 0
+ for key, _ in next, t do
+ k = k + 1
+ keys[k] = key
end
+ return keys
end
local function compare(a,b)
@@ -285,49 +256,41 @@ local function compare(a,b)
end
local function sortedkeys(tab)
- if tab then
- local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
- for key,_ in next, tab do
- s = s + 1
- srt[s] = key
- if category == 3 then
- -- no further check
+ local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
+ for key,_ in next, tab do
+ s = s + 1
+ srt[s] = key
+ if category == 3 then
+ -- no further check
+ else
+ local tkey = type(key)
+ if tkey == "string" then
+ category = (category == 2 and 3) or 1
+ elseif tkey == "number" then
+ category = (category == 1 and 3) or 2
else
- local tkey = type(key)
- if tkey == "string" then
- category = (category == 2 and 3) or 1
- elseif tkey == "number" then
- category = (category == 1 and 3) or 2
- else
- category = 3
- end
+ category = 3
end
end
- if category == 0 or category == 3 then
- sort(srt,compare)
- else
- sort(srt)
- end
- return srt
+ end
+ if category == 0 or category == 3 then
+ sort(srt,compare)
else
- return { }
+ sort(srt)
end
+ return srt
end
local function sortedhashkeys(tab) -- fast one
- if tab then
- local srt, s = { }, 0
- for key,_ in next, tab do
- if key then
- s= s + 1
- srt[s] = key
- end
+ local srt, s = { }, 0
+ for key,_ in next, tab do
+ if key then
+ s= s + 1
+ srt[s] = key
end
- sort(srt)
- return srt
- else
- return { }
end
+ sort(srt)
+ return srt
end
table.sortedkeys = sortedkeys
@@ -352,7 +315,7 @@ end
table.sortedhash = sortedhash
table.sortedpairs = sortedhash
-function table.append(t,list)
+function table.append(t, list)
local n = #t
for i=1,#list do
n = n + 1
@@ -587,26 +550,12 @@ local function do_serialize(root,name,depth,level,indexed)
end
-- we could check for k (index) being number (cardinal)
if root and next(root) then
- -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
- -- if compact then
- -- -- NOT: for k=1,#root do (we need to quit at nil)
- -- for k,v in ipairs(root) do -- can we use next?
- -- if not first then first = k end
- -- last = last + 1
- -- end
- -- end
- local first, last = nil, 0
+ local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
if compact then
- last = #root
- for k=1,last do
--- if not root[k] then
- if root[k] == nil then
- last = k - 1
- break
- end
- end
- if last > 0 then
- first = 1
+ -- NOT: for k=1,#root do (we need to quit at nil)
+ for k,v in ipairs(root) do -- can we use next?
+ if not first then first = k end
+ last = last + 1
end
end
local sk = sortedkeys(root)
@@ -1078,27 +1027,23 @@ function table.reversed(t)
end
end
-function table.sequenced(t,sep) -- hash only
- if t then
- local s, n = { }, 0
- for k, v in sortedhash(t) do
- if simple then
- if v == true then
- n = n + 1
- s[n] = k
- elseif v and v~= "" then
- n = n + 1
- s[n] = k .. "=" .. tostring(v)
- end
- else
+function table.sequenced(t,sep,simple) -- hash only
+ local s, n = { }, 0
+ for k, v in sortedhash(t) do
+ if simple then
+ if v == true then
+ n = n + 1
+ s[n] = k
+ elseif v and v~= "" then
n = n + 1
s[n] = k .. "=" .. tostring(v)
end
+ else
+ n = n + 1
+ s[n] = k .. "=" .. tostring(v)
end
- return concat(s, sep or " | ")
- else
- return ""
end
+ return concat(s, sep or " | ")
end
function table.print(t,...)
@@ -1179,8 +1124,6 @@ local lpeg = require("lpeg")
-- tracing (only used when we encounter a problem in integration of lpeg in luatex)
--- some code will move to unicode and string
-
local report = texio and texio.write_nl or print
-- local lpmatch = lpeg.match
@@ -1217,8 +1160,8 @@ local report = texio and texio.write_nl or print
-- function lpeg.Cmt (l) local p = lpcmt (l) report("LPEG Cmt =") lpprint(l) return p end
-- function lpeg.Carg (l) local p = lpcarg(l) report("LPEG Carg =") lpprint(l) return p end
-local type, next = type, next
-local byte, char, gmatch, format = string.byte, string.char, string.gmatch, string.format
+local type = type
+local byte, char, gmatch = string.byte, string.char, string.gmatch
-- Beware, we predefine a bunch of patterns here and one reason for doing so
-- is that we get consistent behaviour in some of the visualizers.
@@ -1226,8 +1169,9 @@ local byte, char, gmatch, format = string.byte, string.char, string.gmatch, stri
lpeg.patterns = lpeg.patterns or { } -- so that we can share
local patterns = lpeg.patterns
-local P, R, S, V, Ct, C, Cs, Cc, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp
-local lpegtype, lpegmatch = lpeg.type, lpeg.match
+local P, R, S, V, match = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match
+local Ct, C, Cs, Cc = lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local lpegtype = lpeg.type
local utfcharacters = string.utfcharacters
local utfgmatch = unicode and unicode.utf8.gmatch
@@ -1278,10 +1222,6 @@ patterns.utf8char = utf8char
patterns.validutf8 = validutf8char
patterns.validutf8char = validutf8char
-local eol = S("\n\r")
-local spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
-local whitespace = eol + spacer
-
patterns.digit = digit
patterns.sign = sign
patterns.cardinal = sign^0 * digit^1
@@ -1301,16 +1241,16 @@ patterns.letter = patterns.lowercase + patterns.uppercase
patterns.space = space
patterns.tab = P("\t")
patterns.spaceortab = patterns.space + patterns.tab
-patterns.eol = eol
-patterns.spacer = spacer
-patterns.whitespace = whitespace
+patterns.eol = S("\n\r")
+patterns.spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
patterns.newline = newline
patterns.emptyline = newline^1
-patterns.nonspacer = 1 - spacer
-patterns.nonwhitespace = 1 - whitespace
+patterns.nonspacer = 1 - patterns.spacer
+patterns.whitespace = patterns.eol + patterns.spacer
+patterns.nonwhitespace = 1 - patterns.whitespace
patterns.equal = P("=")
patterns.comma = P(",")
-patterns.commaspacer = P(",") * spacer^0
+patterns.commaspacer = P(",") * patterns.spacer^0
patterns.period = P(".")
patterns.colon = P(":")
patterns.semicolon = P(";")
@@ -1325,10 +1265,6 @@ patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"")
patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble
patterns.unspacer = ((patterns.spacer^1)/"")^0
-patterns.singlequoted = squote * patterns.nosquote * squote
-patterns.doublequoted = dquote * patterns.nodquote * dquote
-patterns.quoted = patterns.doublequoted + patterns.singlequoted
-
patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
patterns.beginline = #(1-newline)
@@ -1339,17 +1275,8 @@ patterns.beginline = #(1-newline)
-- print(string.unquoted('"test"'))
-- print(string.unquoted('"test"'))
-local function anywhere(pattern) --slightly adapted from website
- return P { P(pattern) + 1 * V(1) }
-end
-
-lpeg.anywhere = anywhere
-
-function lpeg.instringchecker(p)
- p = anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+function lpeg.anywhere(pattern) --slightly adapted from website
+ return P { P(pattern) + 1 * V(1) } -- why so complex?
end
function lpeg.splitter(pattern, action)
@@ -1398,7 +1325,7 @@ function string.splitup(str,separator)
if not separator then
separator = ","
end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ return match(splitters_m[separator] or splitat(separator),str)
end
@@ -1410,20 +1337,16 @@ function lpeg.split(separator,str)
c = tsplitat(separator)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
function string.split(str,separator)
- if separator then
- local c = cache[separator]
- if not c then
- c = tsplitat(separator)
- cache[separator] = c
- end
- return lpegmatch(c,str)
- else
- return { str }
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
end
+ return match(c,str)
end
local spacing = patterns.spacer^0 * newline -- sort of strip
@@ -1439,7 +1362,7 @@ local linesplitter = tsplitat(newline)
patterns.linesplitter = linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return match(linesplitter,str)
end
local utflinesplitter = utfbom^-1 * tsplitat(newline)
@@ -1447,58 +1370,7 @@ local utflinesplitter = utfbom^-1 * tsplitat(newline)
patterns.utflinesplitter = utflinesplitter
function string.utfsplitlines(str)
- return lpegmatch(utflinesplitter,str or "")
-end
-
-local utfcharsplitter_ows = utfbom^-1 * Ct(C(utf8char)^0)
-local utfcharsplitter_iws = utfbom^-1 * Ct((whitespace^1 + C(utf8char))^0)
-
-function string.utfsplit(str,ignorewhitespace) -- new
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
-end
-
--- inspect(string.utfsplit("a b c d"))
--- inspect(string.utfsplit("a b c d",true))
-
--- -- alternative 1: 0.77
---
--- local utfcharcounter = utfbom^-1 * Cs((utf8char/'!')^0)
---
--- function string.utflength(str)
--- return #lpegmatch(utfcharcounter,str or "")
--- end
---
--- -- alternative 2: 1.70
---
--- local n = 0
---
--- local utfcharcounter = utfbom^-1 * (utf8char/function() n = n + 1 end)^0 -- slow
---
--- function string.utflength(str)
--- n = 0
--- lpegmatch(utfcharcounter,str or "")
--- return n
--- end
---
--- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047)
-
-local n = 0
-
-local utfcharcounter = utfbom^-1 * Cs ( (
- Cp() * (lpeg.patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end
- + Cp() * (lpeg.patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end
- + Cp() * (lpeg.patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end
- + Cp() * (lpeg.patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end
-)^0 )
-
-function string.utflength(str)
- n = 0
- lpegmatch(utfcharcounter,str or "")
- return n
+ return match(utflinesplitter,str or "")
end
@@ -1512,7 +1384,7 @@ function lpeg.checkedsplit(separator,str)
c = Ct(separator^0 * other * (separator^1 * other)^0)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
function string.checkedsplit(str,separator)
@@ -1523,7 +1395,7 @@ function string.checkedsplit(str,separator)
c = Ct(separator^0 * other * (separator^1 * other)^0)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
@@ -1568,11 +1440,11 @@ function lpeg.keeper(str)
end
function lpeg.frontstripper(str) -- or pattern (yet undocumented)
- return (P(str) + P(true)) * Cs(anything^0)
+ return (P(str) + P(true)) * Cs(P(1)^0)
end
function lpeg.endstripper(str) -- or pattern (yet undocumented)
- return Cs((1 - P(str) * endofstring)^0)
+ return Cs((1 - P(str) * P(-1))^0)
end
-- Just for fun I looked at the used bytecode and
@@ -1581,22 +1453,8 @@ end
function lpeg.replacer(one,two)
if type(one) == "table" then
local no = #one
- local p
- if no == 0 then
- for k, v in next, one do
- local pp = P(k) / v
- if p then
- p = p + pp
- else
- p = pp
- end
- end
- return Cs((p + 1)^0)
- elseif no == 1 then
- local o = one[1]
- one, two = P(o[1]), o[2]
- return Cs(((1-one)^1 + one/two)^0)
- else
+ if no > 0 then
+ local p
for i=1,no do
local o = one[i]
local pp = P(o[1]) / o[2]
@@ -1609,16 +1467,11 @@ function lpeg.replacer(one,two)
return Cs((p + 1)^0)
end
else
- one = P(one)
two = two or ""
- return Cs(((1-one)^1 + one/two)^0)
+ return Cs((P(one)/two + 1)^0)
end
end
--- print(lpeg.match(lpeg.replacer("e","a"),"test test"))
--- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test"))
--- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test"))
-
local splitters_f, splitters_s = { }, { }
function lpeg.firstofsplit(separator) -- always return value
@@ -1653,7 +1506,7 @@ local nany = utf8char/""
function lpeg.counter(pattern)
pattern = Cs((P(pattern)/" " + nany)^0)
return function(str)
- return #lpegmatch(pattern,str)
+ return #match(pattern,str)
end
end
@@ -1667,7 +1520,7 @@ if utfgmatch then
end
return n
else -- 4 times slower but still faster than / function
- return #lpegmatch(Cs((P(what)/" " + nany)^0),str)
+ return #match(Cs((P(what)/" " + nany)^0),str)
end
end
@@ -1682,9 +1535,9 @@ else
p = Cs((P(what)/" " + nany)^0)
cache[p] = p
end
- return #lpegmatch(p,str)
+ return #match(p,str)
else -- 4 times slower but still faster than / function
- return #lpegmatch(Cs((P(what)/" " + nany)^0),str)
+ return #match(Cs((P(what)/" " + nany)^0),str)
end
end
@@ -1711,7 +1564,7 @@ local p = Cs((S("-.+*%()[]") / patterns_escapes + anything)^0)
local s = Cs((S("-.+*%()[]") / simple_escapes + anything)^0)
function string.escapedpattern(str,simple)
- return lpegmatch(simple and s or p,str)
+ return match(simple and s or p,str)
end
-- utf extensies
@@ -1758,7 +1611,7 @@ else
p = P(uc)
end
end
- lpegmatch((utf8char/f)^0,str)
+ match((utf8char/f)^0,str)
return p
end
@@ -1774,7 +1627,7 @@ function lpeg.UR(str,more)
first = str
last = more or first
else
- first, last = lpegmatch(range,str)
+ first, last = match(range,str)
if not last then
return P(str)
end
@@ -1801,15 +1654,11 @@ end
-function lpeg.is_lpeg(p)
- return p and lpegtype(p) == "pattern"
-end
-
-function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assume proper order
+function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then")
if type(list) ~= "table" then
list = { list, ... }
end
- -- table.sort(list) -- longest match first
+ -- sort(list) -- longest match first
local p = P(list[1])
for l=2,#list do
p = p + P(list[l])
@@ -1817,6 +1666,10 @@ function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assu
return p
end
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p) == "pattern"
+end
+
-- For the moment here, but it might move to utilities. Beware, we need to
-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
-- loop back from the end cq. prepend.
@@ -1974,24 +1827,6 @@ end
-- utfchar(0x205F), -- math thinspace
-- } )
--- handy from within tex:
-
-local lpegmatch = lpeg.match
-
-local replacer = lpeg.replacer("@","%%") -- Watch the escaped % in lpeg!
-
-function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
-end
-
--- strips leading and trailing spaces and collapsed all other spaces
-
-local pattern = Cs(whitespace^0/"" * ((whitespace^1 * P(-1) / "") + (whitespace^1/" ") + P(1))^0)
-
-function string.collapsespaces(str)
- return lpegmatch(pattern,str)
-end
-
end -- of closure
@@ -2016,14 +1851,14 @@ else
io.fileseparator, io.pathseparator = "/" , ":"
end
-function io.loaddata(filename,textmode) -- return nil if empty
+function io.loaddata(filename,textmode)
local f = io.open(filename,(textmode and 'r') or 'rb')
if f then
local data = f:read('*all')
f:close()
- if #data > 0 then
- return data
- end
+ return data
+ else
+ return nil
end
end
@@ -2045,45 +1880,6 @@ function io.savedata(filename,data,joiner)
end
end
-function io.loadlines(filename,n) -- return nil if empty
- local f = io.open(filename,'r')
- if f then
- if n then
- local lines = { }
- for i=1,n do
- local line = f:read("*lines")
- if line then
- lines[#lines+1] = line
- else
- break
- end
- end
- f:close()
- lines = concat(lines,"\n")
- if #lines > 0 then
- return lines
- end
- else
- local line = f:read("*line") or ""
- assert(f:close())
- if #line > 0 then
- return line
- end
- end
- end
-end
-
-function io.loadchunk(filename,n)
- local f = io.open(filename,'rb')
- if f then
- local data = f:read(n or 1024)
- f:close()
- if #data > 0 then
- return data
- end
- end
-end
-
function io.exists(filename)
local f = io.open(filename)
if f == nil then
@@ -2311,7 +2107,7 @@ if not modules then modules = { } end modules ['l-number'] = {
-- this module will be replaced when we have the bit library
-local tostring, tonumber = tostring, tonumber
+local tostring = tostring
local format, floor, match, rep = string.format, math.floor, string.match, string.rep
local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
@@ -2374,11 +2170,11 @@ function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ...
end
function number.setbit(x, p)
- return (x % (p + p) >= p) and x or x + p
+ return hasbit(x, p) and x or x + p
end
function number.clearbit(x, p)
- return (x % (p + p) >= p) and x - p or x
+ return hasbit(x, p) and x - p or x
end
@@ -2412,10 +2208,6 @@ function number.tobitstring(n,m)
end
-function number.valid(str,default)
- return tonumber(str) or default or nil
-end
-
end -- of closure
@@ -2527,28 +2319,17 @@ if not modules then modules = { } end modules ['l-os'] = {
-- os.name : windows | msdos | linux | macosx | solaris | .. | generic (new)
-- os.platform : extended os.name with architecture
--- os.sleep() => socket.sleep()
--- math.randomseed(tonumber(string.sub(string.reverse(tostring(math.floor(socket.gettime()*10000))),1,6)))
-
-- maybe build io.flush in os.execute
local os = os
-local date, time = os.date, os.time
local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch
local concat = table.concat
-local random, ceil, randomseed = math.random, math.ceil, math.randomseed
-local rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring = rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring
+local random, ceil = math.random, math.ceil
+local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber
-- The following code permits traversing the environment table, at least
-- in luatex. Internally all environment names are uppercase.
--- The randomseed in Lua is not that random, although this depends on the operating system as well
--- as the binary (Luatex is normally okay). But to be sure we set the seed anyway.
-
-math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-
-randomseed(math.initialseed)
-
if not os.__getenv__ then
os.__getenv__ = os.getenv
@@ -2652,14 +2433,12 @@ else
os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' }
end
-local launchers = {
- windows = "start %s",
- macosx = "open %s",
- unix = "$BROWSER %s &> /dev/null &",
-}
-
function os.launch(str)
- os.execute(format(launchers[os.name] or launchers.unix,str))
+ if os.type == "windows" then
+ os.execute("start " .. str) -- os.spawn ?
+ else
+ os.execute(str .. " &") -- os.spawn ?
+ end
end
if not os.times then
@@ -2870,7 +2649,7 @@ end
local d
function os.timezone(delta)
- d = d or tonumber(tonumber(date("%H")-date("!%H")))
+ d = d or tonumber(tonumber(os.date("%H")-os.date("!%H")))
if delta then
if d > 0 then
return format("+%02i:00",d)
@@ -2882,44 +2661,6 @@ function os.timezone(delta)
end
end
-local timeformat = format("%%s%s",os.timezone(true))
-local dateformat = "!%Y-%m-%d %H:%M:%S"
-
-function os.fulltime(t,default)
- t = tonumber(t) or 0
- if t > 0 then
- -- valid time
- elseif default then
- return default
- else
- t = nil
- end
- return format(timeformat,date(dateformat,t))
-end
-
-local dateformat = "%Y-%m-%d %H:%M:%S"
-
-function os.localtime(t,default)
- t = tonumber(t) or 0
- if t > 0 then
- -- valid time
- elseif default then
- return default
- else
- t = nil
- end
- return date(dateformat,t)
-end
-
-function os.converttime(t,default)
- local t = tonumber(t)
- if t and t > 0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
-end
-
local memory = { }
local function which(filename)
@@ -2994,7 +2735,7 @@ local function nameonly(name)
return (gsub(match(name,"^.+[/\\](.-)$") or name,"%.[%a%d]+$",""))
end
-local function suffixonly(name,default)
+local function extname(name,default)
return match(name,"^.+%.([^/\\]-)$") or default or ""
end
@@ -3003,16 +2744,11 @@ local function splitname(name)
return n or name, s or ""
end
-file.basename = basename
-
-file.pathpart = dirname
-file.dirname = dirname
-
-file.nameonly = nameonly
-
-file.suffixonly = suffixonly
-file.extname = suffixonly -- obsolete
-file.suffix = suffixonly
+file.basename = basename
+file.dirname = dirname
+file.nameonly = nameonly
+file.extname = extname
+file.suffix = extname
function file.removesuffix(filename)
return (gsub(filename,"%.[%a%d]+$",""))
@@ -3128,11 +2864,6 @@ end
file.isreadable = file.is_readable -- depricated
file.iswritable = file.is_writable -- depricated
-function file.size(name)
- local a = attributes(name)
- return a and a.size or 0
-end
-
-- todo: lpeg \\ / .. does not save much
local checkedsplit = string.checkedsplit
@@ -3270,7 +3001,6 @@ local drive = C(R("az","AZ")) * P(":")
local path = C(((1-slash)^0 * slash)^0)
local suffix = period * C(P(1-period)^0 * P(-1))
local base = C((1-suffix)^0)
-local rest = C(P(1)^0)
drive = drive + Cc("")
path = path + Cc("")
@@ -3279,8 +3009,7 @@ suffix = suffix + Cc("")
local pattern_a = drive * path * base * suffix
local pattern_b = path * base * suffix
-local pattern_c = C(drive * path) * C(base * suffix) -- trick: two extra captures
-local pattern_d = path * rest
+local pattern_c = C(drive * path) * C(base * suffix)
function file.splitname(str,splitdrive)
if splitdrive then
@@ -3290,10 +3019,6 @@ function file.splitname(str,splitdrive)
end
end
-function file.splitbase(str)
- return lpegmatch(pattern_d,str) -- returns path, base+suffix
-end
-
function file.nametotable(str,splitdrive) -- returns table
local path, drive, subpath, name, base, suffix = lpegmatch(pattern_c,str)
if splitdrive then
@@ -3315,8 +3040,6 @@ function file.nametotable(str,splitdrive) -- returns table
end
end
--- print(file.splitbase("a/b/c.txt"))
-
-- function test(t) for k, v in next, t do print(v, "=>", file.splitname(v)) end end
--
-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
@@ -3358,30 +3081,15 @@ if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
-function file.needsupdating(oldname,newname,threshold) -- size modification access change
- local oldtime = lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime = lfs.attributes(newname,"modification")
- if not newtime then
- return true -- no new file, so no updating needed
- elseif newtime >= oldtime then
- return false -- new file definitely needs updating
- elseif oldtime - newtime < (threshold or 1) then
- return false -- new file is probably still okay
- else
- return true -- new file has to be updated
- end
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
+ local oldtime = lfs.attributes(oldname, modification)
+ local newtime = lfs.attributes(newname, modification)
+ if newtime >= oldtime then
+ return false
+ elseif oldtime - newtime < (threshold or 1) then
+ return false
else
- return false -- no old file, so no updating needed
- end
-end
-
-file.needs_updating = file.needsupdating
-
-function file.syncmtimes(oldname,newname)
- local oldtime = lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
+ return true
end
end
@@ -3403,7 +3111,7 @@ function file.loadchecksum(name)
return nil
end
-function file.savechecksum(name,checksum)
+function file.savechecksum(name, checksum)
if not checksum then checksum = file.checksum(name) end
if checksum then
io.savedata(name .. ".md5",checksum)
@@ -3428,7 +3136,7 @@ if not modules then modules = { } end modules ['l-url'] = {
local char, gmatch, gsub, format, byte, find = string.char, string.gmatch, string.gsub, string.format, string.byte, string.find
local concat = table.concat
local tonumber, type = tonumber, type
-local P, C, R, S, Cs, Cc, Ct, Cf, Cg, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cf, lpeg.Cg, lpeg.V
+local P, C, R, S, Cs, Cc, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct
local lpegmatch, lpegpatterns, replacer = lpeg.match, lpeg.patterns, lpeg.replacer
-- from wikipedia:
@@ -3461,19 +3169,15 @@ local endofstring = P(-1)
local hexdigit = R("09","AF","af")
local plus = P("+")
local nothing = Cc("")
-local escapedchar = (percent * C(hexdigit * hexdigit)) / tochar
-local escaped = (plus / " ") + escapedchar
+local escaped = (plus / " ") + (percent * C(hexdigit * hexdigit) / tochar)
-- we assume schemes with more than 1 character (in order to avoid problems with windows disks)
-- we also assume that when we have a scheme, we also have an authority
---
--- maybe we should already split the query (better for unescaping as = & can be part of a value
local schemestr = Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr = Cs((escaped+(1- slash-qmark-hash))^0)
local pathstr = Cs((escaped+(1- qmark-hash))^0)
------ querystr = Cs((escaped+(1- hash))^0)
-local querystr = Cs(( (1- hash))^0)
+local querystr = Cs((escaped+(1- hash))^0)
local fragmentstr = Cs((escaped+(1- endofstring))^0)
local scheme = schemestr * colon + nothing
@@ -3488,20 +3192,11 @@ local parser = Ct(validurl)
lpegpatterns.url = validurl
lpegpatterns.urlsplitter = parser
-local escapes = { }
+local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end
-setmetatable(escapes, { __index = function(t,k)
- local v = format("%%%02X",byte(k))
- t[k] = v
- return v
-end })
+local escaper = Cs((R("09","AZ","az") + S("-./_") + P(1) / escapes)^0)
-local escaper = Cs((R("09","AZ","az")^1 + P(" ")/"%%20" + S("-./_")^1 + P(1) / escapes)^0) -- space happens most
-local unescaper = Cs((escapedchar + 1)^0)
-
-lpegpatterns.urlunescaped = escapedchar
-lpegpatterns.urlescaper = escaper
-lpegpatterns.urlunescaper = unescaper
+lpegpatterns.urlescaper = escaper
-- todo: reconsider Ct as we can as well have five return values (saves a table)
-- so we can have two parsers, one with and one without
@@ -3513,12 +3208,8 @@ end
local isscheme = schemestr * colon * slash * slash -- this test also assumes authority
local function hasscheme(str)
- if str then
- local scheme = lpegmatch(isscheme,str) -- at least one character
- return scheme ~= "" and scheme or false
- else
- return false
- end
+ local scheme = lpegmatch(isscheme,str) -- at least one character
+ return scheme ~= "" and scheme or false
end
@@ -3537,32 +3228,10 @@ local rootbased = P("/")
local barswapper = replacer("|",":")
local backslashswapper = replacer("\\","/")
--- queries:
-
-local equal = P("=")
-local amp = P("&")
-local key = Cs(((escapedchar+1)-equal )^0)
-local value = Cs(((escapedchar+1)-amp -endofstring)^0)
-
-local splitquery = Cf ( Ct("") * P { "sequence",
- sequence = V("pair") * (amp * V("pair"))^0,
- pair = Cg(key * equal * value),
-}, rawset)
-
--- hasher
-
local function hashed(str) -- not yet ok (/test?test)
- if str == "" then
- return {
- scheme = "invalid",
- original = str,
- }
- end
local s = split(str)
- local rawscheme = s[1]
- local rawquery = s[4]
- local somescheme = rawscheme ~= ""
- local somequery = rawquery ~= ""
+ local somescheme = s[1] ~= ""
+ local somequery = s[4] ~= ""
if not somescheme and not somequery then
s = {
scheme = "file",
@@ -3578,17 +3247,14 @@ local function hashed(str) -- not yet ok (/test?test)
local authority, path, filename = s[2], s[3]
if authority == "" then
filename = path
- elseif path == "" then
- filename = ""
else
filename = authority .. "/" .. path
end
s = {
- scheme = rawscheme,
+ scheme = s[1],
authority = authority,
path = path,
- query = lpegmatch(unescaper,rawquery), -- unescaped, but possible conflict with & and =
- queries = lpegmatch(splitquery,rawquery), -- split first and then unescaped
+ query = s[4],
fragment = s[5],
original = str,
noscheme = false,
@@ -3598,8 +3264,6 @@ local function hashed(str) -- not yet ok (/test?test)
return s
end
--- inspect(hashed("template://test"))
-
-- Here we assume:
--
-- files: /// = relative
@@ -3642,61 +3306,20 @@ function url.construct(hash) -- dodo: we need to escape !
return lpegmatch(escaper,concat(fullurl))
end
-function url.filename(filename) -- why no lpeg here ?
+function url.filename(filename)
local t = hashed(filename)
return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename
end
-local function escapestring(str)
- return lpegmatch(escaper,str)
-end
-
-url.escape = escapestring
-
--- function url.query(str) -- separator could be an option
--- if type(str) == "string" then
--- local t = { }
--- for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
--- t[k] = v
--- end
--- return t
--- else
--- return str
--- end
--- end
-
function url.query(str)
if type(str) == "string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
-end
-
-function url.toquery(data)
- local td = type(data)
- if td == "string" then
- return #str and escape(data) or nil -- beware of double escaping
- elseif td == "table" then
- if next(data) then
- local t = { }
- for k, v in next, data do
- t[#t+1] = format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
+ local t = { }
+ for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
+ t[k] = v
end
+ return t
else
- -- nil is a signal that no query
- end
-end
-
--- /test/ | /test | test/ | test => test
-
-function url.barepath(path)
- if not path or path == "" then
- return ""
- else
- return (gsub(path,"^/?(.-)/?$","%1"))
+ return str
end
end
@@ -3709,7 +3332,6 @@ end
-
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -3741,24 +3363,6 @@ local isdir = lfs.isdir
local isfile = lfs.isfile
local currentdir = lfs.currentdir
--- in case we load outside luatex
-
-if not isdir then
- function isdir(name)
- local a = attributes(name)
- return a and a.mode == "directory"
- end
- lfs.isdir = isdir
-end
-
-if not isfile then
- function isfile(name)
- local a = attributes(name)
- return a and a.mode == "file"
- end
- lfs.isfile = isfile
-end
-
-- handy
function dir.current()
@@ -4134,49 +3738,28 @@ function boolean.tonumber(b)
end
function toboolean(str,tolerant)
- if str == nil then
- return false
- elseif str == false then
- return false
- elseif str == true then
- return true
+ if tolerant then
+ local tstr = type(str)
+ if tstr == "string" then
+ return str == "true" or str == "yes" or str == "on" or str == "1" or str == "t"
+ elseif tstr == "number" then
+ return tonumber(str) ~= 0
+ elseif tstr == "nil" then
+ return false
+ else
+ return str
+ end
elseif str == "true" then
return true
elseif str == "false" then
return false
- elseif not tolerant then
- return false
- elseif str == 0 then
- return false
- elseif (tonumber(str) or 0) > 0 then
- return true
else
- return str == "yes" or str == "on" or str == "t"
+ return str
end
end
string.toboolean = toboolean
-function string.booleanstring(str)
- if str == nil then
- return false
- elseif str == false then
- return false
- elseif str == true then
- return true
- elseif str == "true" then
- return true
- elseif str == "false" then
- return false
- elseif str == 0 then
- return false
- elseif (tonumber(str) or 0) > 0 then
- return true
- else
- return str == "yes" or str == "on" or str == "t"
- end
-end
-
function string.is_boolean(str,default)
if type(str) == "string" then
if str == "true" or str == "yes" or str == "on" or str == "t" then
@@ -4201,229 +3784,57 @@ if not modules then modules = { } end modules ['l-unicode'] = {
license = "see context related readme files"
}
--- this module will be reorganized
-
--- todo: utf.sub replacement (used in syst-aux)
-
-local concat = table.concat
-local type = type
-local P, C, R, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Ct
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
-local utftype = patterns.utftype
-local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
-local utfsplitlines = string.utfsplitlines
-
if not unicode then
- unicode = { }
-
-end
-
-local unicode = unicode
-
-utf = utf or unicode.utf8
-
-if not utf then
-
- utf8 = { }
- unicode.utf8 = utf8
- utf = utf8
-
-end
-
-if not utf.char then
+ unicode = { utf8 = { } }
local floor, char = math.floor, string.char
- function utf.char(n)
+ function unicode.utf8.utfchar(n)
if n < 0x80 then
- -- 0aaaaaaa : 0x80
return char(n)
elseif n < 0x800 then
- -- 110bbbaa : 0xC0 : n >> 6
- -- 10aaaaaa : 0x80 : n & 0x3F
return char(
0xC0 + floor(n/0x40),
0x80 + (n % 0x40)
)
elseif n < 0x10000 then
- -- 1110bbbb : 0xE0 : n >> 12
- -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
- -- 10aaaaaa : 0x80 : n & 0x3F
return char(
0xE0 + floor(n/0x1000),
0x80 + (floor(n/0x40) % 0x40),
0x80 + (n % 0x40)
)
- elseif n < 0x200000 then
- -- 11110ccc : 0xF0 : n >> 18
- -- 10ccbbbb : 0x80 : (n >> 12) & 0x3F
- -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
- -- 10aaaaaa : 0x80 : n & 0x3F
- -- dddd : ccccc - 1
+ elseif n < 0x40000 then
return char(
- 0xF0 + floor(n/0x40000),
- 0x80 + (floor(n/0x1000) % 0x40),
+ 0xF0 + floor(n/0x40000),
+ 0x80 + floor(n/0x1000),
0x80 + (floor(n/0x40) % 0x40),
0x80 + (n % 0x40)
)
else
- return ""
+ -- return char(
+ -- 0xF1 + floor(n/0x1000000),
+ -- 0x80 + floor(n/0x40000),
+ -- 0x80 + floor(n/0x1000),
+ -- 0x80 + (floor(n/0x40) % 0x40),
+ -- 0x80 + (n % 0x40)
+ -- )
+ return "?"
end
end
end
-if not utf.byte then
-
- local utf8byte = patterns.utf8byte
-
- function utf.byte(c)
- return lpegmatch(utf8byte,c)
- end
-
-end
-
-local utfchar, utfbyte = utf.char, utf.byte
-
--- As we want to get rid of the (unmaintained) utf library we implement our own
--- variants (in due time an independent module):
-
-function unicode.filetype(data)
- return data and lpegmatch(utftype,data) or "unknown"
-end
-
-local toentities = Cs (
- (
- patterns.utf8one
- + (
- patterns.utf8two
- + patterns.utf8three
- + patterns.utf8four
- ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("%X;",b) end end
- )^0
-)
-
-patterns.toentities = toentities
-
-function utf.toentities(str)
- return lpegmatch(toentities,str)
-end
-
-
-
-
-local one = P(1)
-local two = C(1) * C(1)
-local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
-
--- actually one of them is already utf ... sort of useless this one
-
--- function utf.char(n)
--- if n < 0x80 then
--- return char(n)
--- elseif n < 0x800 then
--- return char(
--- 0xC0 + floor(n/0x40),
--- 0x80 + (n % 0x40)
--- )
--- elseif n < 0x10000 then
--- return char(
--- 0xE0 + floor(n/0x1000),
--- 0x80 + (floor(n/0x40) % 0x40),
--- 0x80 + (n % 0x40)
--- )
--- elseif n < 0x40000 then
--- return char(
--- 0xF0 + floor(n/0x40000),
--- 0x80 + floor(n/0x1000),
--- 0x80 + (floor(n/0x40) % 0x40),
--- 0x80 + (n % 0x40)
--- )
--- else
--- -- return char(
--- -- 0xF1 + floor(n/0x1000000),
--- -- 0x80 + floor(n/0x40000),
--- -- 0x80 + floor(n/0x1000),
--- -- 0x80 + (floor(n/0x40) % 0x40),
--- -- 0x80 + (n % 0x40)
--- -- )
--- return "?"
--- end
--- end
---
--- merge into:
-
-local pattern = P("\254\255") * Cs( (
- four / function(a,b,c,d)
- local ab = 0xFF * byte(a) + byte(b)
- local cd = 0xFF * byte(c) + byte(d)
- return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
- end
- + two / function(a,b)
- return utfchar(byte(a)*256 + byte(b))
- end
- + one
- )^1 )
- + P("\255\254") * Cs( (
- four / function(b,a,d,c)
- local ab = 0xFF * byte(a) + byte(b)
- local cd = 0xFF * byte(c) + byte(d)
- return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
- end
- + two / function(b,a)
- return utfchar(byte(a)*256 + byte(b))
- end
- + one
- )^1 )
-
-function string.toutf(s)
- return lpegmatch(pattern,s) or s -- todo: utf32
-end
-
-local validatedutf = Cs (
- (
- patterns.utf8one
- + patterns.utf8two
- + patterns.utf8three
- + patterns.utf8four
- + P(1) / "�"
- )^0
-)
-
-patterns.validatedutf = validatedutf
-
-function string.validutf(str)
- return lpegmatch(validatedutf,str)
-end
-
-
-utf.length = string.utflength
-utf.split = string.utfsplit
-utf.splitines = string.utfsplitlines
-utf.valid = string.validutf
-
-if not utf.len then
- utf.len = utf.length
-end
-
--- a replacement for simple gsubs:
+local unicode = unicode
-local utf8char = patterns.utf8char
+utf = utf or unicode.utf8
-function utf.remapper(mapping)
- local pattern = Cs((utf8char/mapping)^0)
- return function(str)
- if not str or str == "" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end, pattern
-end
+local concat = table.concat
+local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub
+local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
+local type = type
--- local remap = utf.remapper { a = 'd', b = "c", c = "b", d = "a" }
--- print(remap("abcd 1234 abcd"))
+local utfsplitlines = string.utfsplitlines
-- 0 EF BB BF UTF-8
-- 1 FF FE UTF-16-little-endian
@@ -4616,22 +4027,11 @@ local function big(c)
end
end
--- function unicode.utf8_to_utf16(str,littleendian)
--- if littleendian then
--- return char(255,254) .. utfgsub(str,".",little)
--- else
--- return char(254,255) .. utfgsub(str,".",big)
--- end
--- end
-
-local _, l_remap = utf.remapper(little)
-local _, b_remap = utf.remapper(big)
-
function unicode.utf8_to_utf16(str,littleendian)
if littleendian then
- return char(255,254) .. lpegmatch(l_remap,str)
+ return char(255,254) .. utfgsub(str,".",little)
else
- return char(254,255) .. lpegmatch(b_remap,str)
+ return char(254,255) .. utfgsub(str,".",big)
end
end
@@ -4652,12 +4052,84 @@ function unicode.xstring(s)
return format("0x%05X",type(s) == "number" and s or utfbyte(s))
end
---
-local pattern = Ct(C(patterns.utf8char)^0)
+local lpegmatch = lpeg.match
+local patterns = lpeg.patterns
+local utftype = patterns.utftype
+
+function unicode.filetype(data)
+ return data and lpegmatch(utftype,data) or "unknown"
+end
-function utf.totable(str)
- return lpegmatch(pattern,str)
+local toentities = lpeg.Cs (
+ (
+ patterns.utf8one
+ + (
+ patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("%X;",b) end end
+ )^0
+)
+
+patterns.toentities = toentities
+
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+
+
+
+
+local P, C, R, Cs = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs
+
+local one = P(1)
+local two = C(1) * C(1)
+local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
+
+-- actually one of them is already utf ... sort of useless this one
+
+local pattern = P("\254\255") * Cs( (
+ four / function(a,b,c,d)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(a,b)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+ + P("\255\254") * Cs( (
+ four / function(b,a,d,c)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(b,a)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+
+function string.toutf(s)
+ return lpegmatch(pattern,s) or s -- todo: utf32
+end
+
+local validatedutf = Cs (
+ (
+ patterns.utf8one
+ + patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ + P(1) / "�"
+ )^0
+)
+
+patterns.validatedutf = validatedutf
+
+function string.validutf(str)
+ return lpegmatch(validatedutf,str)
end
@@ -4717,11 +4189,10 @@ utilities = utilities or {}
utilities.tables = utilities.tables or { }
local tables = utilities.tables
-local format, gmatch, rep, gsub = string.format, string.gmatch, string.rep, string.gsub
+local format, gmatch, rep = string.format, string.gmatch, string.rep
local concat, insert, remove = table.concat, table.insert, table.remove
local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
-local type, next, rawset, tonumber, loadstring = type, next, rawset, tonumber, loadstring
-local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs
+local type, next, rawset, tonumber = type, next, rawset, tonumber
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -4875,121 +4346,6 @@ function tables.encapsulate(core,capsule,protect)
end
end
-local function serialize(t,r,outer) -- no mixes
- r[#r+1] = "{"
- local n = #t
- if n > 0 then
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = format("%q,",v)
- elseif tv == "number" then
- r[#r+1] = format("%s,",v)
- elseif tv == "table" then
- serialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = format("%s,",tostring(v))
- end
- end
- else
- for k, v in next, t do
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = format("[%q]=%q,",k,v)
- elseif tv == "number" then
- r[#r+1] = format("[%q]=%s,",k,v)
- elseif tv == "table" then
- r[#r+1] = format("[%q]=",k)
- serialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = format("[%q]=%s,",k,tostring(v))
- end
- end
- end
- if outer then
- r[#r+1] = "}"
- else
- r[#r+1] = "},"
- end
- return r
-end
-
-function table.fastserialize(t,prefix)
- return concat(serialize(t,{ prefix or "return" },true))
-end
-
-function table.deserialize(str)
- if not str or str == "" then
- return
- end
- local code = loadstring(str)
- if not code then
- return
- end
- code = code()
- if not code then
- return
- end
- return code
-end
-
--- inspect(table.fastserialize { a = 1, b = { 4, { 5, 6 } }, c = { d = 7, e = 'f"g\nh' } })
-
-function table.load(filename)
- if filename then
- local t = io.loaddata(filename)
- if t and t ~= "" then
- t = loadstring(t)
- if type(t) == "function" then
- t = t()
- if type(t) == "table" then
- return t
- end
- end
- end
- end
-end
-
-local function slowdrop(t)
- local r = { }
- local l = { }
- for i=1,#t do
- local ti = t[i]
- local j = 0
- for k, v in next, ti do
- j = j + 1
- l[j] = format("%s=%q",k,v)
- end
- r[i] = format(" {%s},\n",concat(l))
- end
- return format("return {\n%s}",concat(r))
-end
-
-local function fastdrop(t)
- local r = { "return {\n" }
- for i=1,#t do
- local ti = t[i]
- r[#r+1] = " {"
- for k, v in next, ti do
- r[#r+1] = format("%s=%q",k,v)
- end
- r[#r+1] = "},\n"
- end
- r[#r+1] = "}"
- return concat(r)
-end
-
-function table.drop(t,slow)
- if #t == 0 then
- return "return { }"
- elseif slow == true then
- return slowdrop(t) -- less memory
- else
- return fastdrop(t) -- some 15% faster
- end
-end
-
end -- of closure
@@ -5164,10 +4520,11 @@ local concat = table.concat
local type, next = type, next
utilities = utilities or {}
-local merger = utilities.merger or { }
-utilities.merger = merger
+utilities.merger = utilities.merger or { } -- maybe mergers
utilities.report = logs and logs.reporter("system") or print
+local merger = utilities.merger
+
merger.strip_comment = true
local m_begin_merge = "begin library merge"
@@ -5213,11 +4570,9 @@ end
local function self_save(name, data)
if data ~= "" then
if merger.strip_comment then
+ -- saves some 20K
local n = #data
- -- saves some 20K .. scite comments
data = gsub(data,"%-%-~[^\n\r]*[\r\n]","")
- -- saves some 20K .. ldx comments
- data = gsub(data,"%-%-%[%[ldx%-%-.-%-%-ldx%]%]%-%-","")
utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data)
end
io.savedata(name,data)
@@ -5298,208 +4653,36 @@ if not modules then modules = { } end modules ['util-lua'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment = "the strip code is written by Peter Cawley",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-local rep, sub, byte, dump, format = string.rep, string.sub, string.byte, string.dump, string.format
-local loadstring, loadfile, type = loadstring, loadfile, type
-
-utilities = utilities or {}
-utilities.lua = utilities.lua or { }
-local luautilities = utilities.lua
-
-utilities.report = logs and logs.reporter("system") or print -- can be overloaded later
-
-local tracestripping = false
-local forcestupidcompile = true -- use internal bytecode compiler
-luautilities.stripcode = true -- support stripping when asked for
-luautilities.alwaysstripcode = false -- saves 1 meg on 7 meg compressed format file (2012.08.12)
-luautilities.nofstrippedchunks = 0
-luautilities.nofstrippedbytes = 0
-
--- The next function was posted by Peter Cawley on the lua list and strips line
--- number information etc. from the bytecode data blob. We only apply this trick
--- when we store data tables. Stripping makes the compressed format file about
--- 1MB smaller (and uncompressed we save at least 6MB).
---
--- You can consider this feature an experiment, so it might disappear. There is
--- no noticeable gain in runtime although the memory footprint should be somewhat
--- smaller (and the file system has a bit less to deal with).
---
--- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ...
-
-local function strip_code_pc(dump,name)
- local before = #dump
- local version, format, endian, int, size, ins, num = byte(dump,5,11)
- local subint
- if endian == 1 then
- subint = function(dump, i, l)
- local val = 0
- for n = l, 1, -1 do
- val = val * 256 + byte(dump,i + n - 1)
- end
- return val, i + l
- end
- else
- subint = function(dump, i, l)
- local val = 0
- for n = 1, l, 1 do
- val = val * 256 + byte(dump,i + n - 1)
- end
- return val, i + l
- end
- end
- local strip_function
- strip_function = function(dump)
- local count, offset = subint(dump, 1, size)
- local stripped, dirty = rep("\0", size), offset + count
- offset = offset + count + int * 2 + 4
- offset = offset + int + subint(dump, offset, int) * ins
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- local t
- t, offset = subint(dump, offset, 1)
- if t == 1 then
- offset = offset + 1
- elseif t == 4 then
- offset = offset + size + subint(dump, offset, size)
- elseif t == 3 then
- offset = offset + num
- end
- end
- count, offset = subint(dump, offset, int)
- stripped = stripped .. sub(dump,dirty, offset - 1)
- for n = 1, count do
- local proto, off = strip_function(sub(dump,offset, -1))
- stripped, offset = stripped .. proto, offset + off - 1
- end
- offset = offset + subint(dump, offset, int) * int + int
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size + int * 2
- end
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size
- end
- stripped = stripped .. rep("\0", int * 3)
- return stripped, offset
- end
- dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1))
- local after = #dump
- local delta = before-after
- if tracestripping then
- utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta)
- end
- luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1
- luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta
- return dump, delta
-end
-
--- ... end of borrowed code.
-
-local function strippedbytecode(code,forcestrip,name)
- if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then
- return strip_code_pc(code,name)
- else
- return code, 0
- end
-end
-
-luautilities.stripbytecode = strip_code_pc
-luautilities.strippedbytecode = strippedbytecode
-
-local function fatalerror(name)
- utilities.report(format("fatal error in %q",name or "unknown"))
-end
-
--- quite subtle ... doing this wrong incidentally can give more bytes
-
-
-function luautilities.loadedluacode(fullname,forcestrip,name)
- -- quite subtle ... doing this wrong incidentally can give more bytes
- name = name or fullname
- local code = loadfile(fullname)
- if code then
- code()
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip) == "function" then
- forcestrip = forcestrip(fullname)
- end
- if forcestrip then
- local code, n = strip_code_pc(dump(code,name))
- return loadstring(code), n
- elseif luautilities.alwaysstripcode then
- return loadstring(strip_code_pc(dump(code),name))
- else
- return code, 0
- end
- elseif luautilities.alwaysstripcode then
- return loadstring(strip_code_pc(dump(code),name))
- else
- return code, 0
- end
-end
-
-function luautilities.strippedloadstring(code,forcestrip,name) -- not executed
- local n = 0
- if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then
- code = loadstring(code)
- if not code then
- fatalerror(name)
- end
- code, n = strip_code_pc(dump(code),name)
- end
- return loadstring(code), n
-end
+utilities = utilities or {}
+utilities.lua = utilities.lua or { }
+utilities.report = logs and logs.reporter("system") or print
-local function stupidcompile(luafile,lucfile,strip)
- local code = io.loaddata(luafile)
- local n = 0
- if code and code ~= "" then
- code = loadstring(code)
- if not code then
- fatalerror()
- end
- code = dump(code)
- if strip then
- code, n = strippedbytecode(code,true,luafile) -- last one is reported
- end
- if code and code ~= "" then
- io.savedata(lucfile,code)
+local function stupidcompile(luafile,lucfile)
+ local data = io.loaddata(luafile)
+ if data and data ~= "" then
+ data = string.dump(data)
+ if data and data ~= "" then
+ io.savedata(lucfile,data)
end
end
- return n
end
-local luac_normal = "texluac -o %q %q"
-local luac_strip = "texluac -s -o %q %q"
-
-function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
+function utilities.lua.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
utilities.report("lua: compiling %s into %s",luafile,lucfile)
os.remove(lucfile)
- local done = false
+ local command = "-o " .. string.quoted(lucfile) .. " " .. string.quoted(luafile)
if strip ~= false then
- strip = true
- end
- if forcestupidcompile then
- fallback = true
- elseif strip then
- done = os.spawn(format(luac_strip, lucfile,luafile)) == 0
- else
- done = os.spawn(format(luac_normal,lucfile,luafile)) == 0
+ command = "-s " .. command
end
+ local done = os.spawn("texluac " .. command) == 0 -- or os.spawn("luac " .. command) == 0
if not done and fallback then
- local n = stupidcompile(luafile,lucfile,strip)
- if n > 0 then
- utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n)
- else
- utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile)
- end
- cleanup = false -- better see how bad it is
+ utilities.report("lua: dumping %s into %s (unstripped)",luafile,lucfile)
+ stupidcompile(luafile,lucfile) -- maybe use the stripper we have elsewhere
+ cleanup = false -- better see how worse it is
end
if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
utilities.report("lua: removing %s",luafile)
@@ -5514,6 +4697,7 @@ end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -5526,10 +4710,8 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
-local lpeg, table, string = lpeg, table, string
-
-local P, R, V, S, C, Ct, Cs, Carg, Cc = lpeg.P, lpeg.R, lpeg.V, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cc
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local P, R, V, C, Ct, Cs, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg
+local lpegmatch = lpeg.match
local concat, format, gmatch, find = table.concat, string.format, string.gmatch, string.find
local tostring, type, next = tostring, type, next
@@ -5541,39 +4723,29 @@ parsers.patterns = parsers.patterns or { }
local setmetatableindex = table.setmetatableindex
local sortedhash = table.sortedhash
--- we share some patterns
-
-local space = P(' ')
-local equal = P("=")
-local comma = P(",")
-local lbrace = P("{")
-local rbrace = P("}")
-local period = S(".")
-local punctuation = S(".,:;")
-local spacer = patterns.spacer
-local whitespace = patterns.whitespace
-local newline = patterns.newline
-local anything = patterns.anything
-local endofstring = patterns.endofstring
-
-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
-patterns.balanced = P {
+lpeg.patterns.balanced = P {
[1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
[2] = left * V(1) * right
}
+local space = P(' ')
+local equal = P("=")
+local comma = P(",")
+local lbrace = P("{")
+local rbrace = P("}")
local nobrace = 1 - (lbrace+rbrace)
local nested = P { lbrace * (nobrace + V(1))^0 * rbrace }
local spaces = space^0
local argument = Cs((lbrace/"") * ((nobrace + nested)^0) * (rbrace/""))
-local content = (1-endofstring)^0
+local content = (1-P(-1))^0
-patterns.nested = nested -- no capture
-patterns.argument = argument -- argument after e.g. =
-patterns.content = content -- rest after e.g =
+lpeg.patterns.nested = nested -- no capture
+lpeg.patterns.argument = argument -- argument after e.g. =
+lpeg.patterns.content = content -- rest after e.g =
local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0)
@@ -5592,6 +4764,10 @@ local function set(key,value)
hash[key] = value
end
+local function set(key,value)
+ hash[key] = value
+end
+
local pattern_a_s = (pattern_a/set)^1
local pattern_b_s = (pattern_b/set)^1
local pattern_c_s = (pattern_c/set)^1
@@ -5642,7 +4818,7 @@ end
local separator = comma * space^0
local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0)
-local pattern = spaces * Ct(value*(separator*value)^0)
+local pattern = Ct(value*(separator*value)^0)
-- "aap, {noot}, mies" : outer {} removes, leading spaces ignored
@@ -5766,37 +4942,6 @@ function parsers.listitem(str)
return gmatch(str,"[^, ]+")
end
---
-local digit = R("09")
-
-local pattern = Cs { "start",
- start = V("one") + V("two") + V("three"),
- rest = (Cc(",") * V("thousand"))^0 * (P(".") + endofstring) * anything^0,
- thousand = digit * digit * digit,
- one = digit * V("rest"),
- two = digit * digit * V("rest"),
- three = V("thousand") * V("rest"),
-}
-
-patterns.splitthousands = pattern -- maybe better in the parsers namespace ?
-
-function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
-end
-
--- print(parsers.splitthousands("11111111111.11"))
-
-local optionalwhitespace = whitespace^0
-
-patterns.words = Ct((Cs((1-punctuation-whitespace)^1) + anything)^1)
-patterns.sentences = Ct((optionalwhitespace * Cs((1-period)^0 * period))^1)
-patterns.paragraphs = Ct((optionalwhitespace * Cs((whitespace^1*endofstring/"" + 1 - (spacer^0*newline*newline))^1))^1)
-
--- local str = " Word1 word2. \n Word3 word4. \n\n Word5 word6.\n "
--- inspect(lpegmatch(patterns.paragraphs,str))
--- inspect(lpegmatch(patterns.sentences,str))
--- inspect(lpegmatch(patterns.words,str))
-
end -- of closure
@@ -5898,7 +5043,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['util-deb'] = {
+if not modules then modules = { } end modules ['util.deb'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -6010,7 +5155,6 @@ function inspect(i) -- global function
else
print(tostring(i))
end
- return i -- so that we can inline the inspect
end
-- from the lua book:
@@ -6050,7 +5194,7 @@ if not modules then modules = { } end modules ['trac-inf'] = {
local format, lower = string.format, string.lower
local clock = os.gettimeofday or os.clock -- should go in environment
-local write_nl = texio and texio.write_nl or print
+local write_nl = texio.write_nl
statistics = statistics or { }
local statistics = statistics
@@ -6133,7 +5277,7 @@ statistics.elapsedtime = elapsedtime
statistics.elapsedindeed = elapsedindeed
statistics.elapsedseconds = elapsedseconds
--- general function .. we might split this module
+-- general function
function statistics.register(tag,fnc)
if statistics.enable and type(fnc) == "function" then
@@ -6243,8 +5387,6 @@ if not modules then modules = { } end modules ['trac-set'] = { -- might become u
license = "see context related readme files"
}
--- maybe this should be util-set.lua
-
local type, next, tostring = type, next, tostring
local concat = table.concat
local format, find, lower, gsub, escapedpattern = string.format, string.find, string.lower, string.gsub, string.escapedpattern
@@ -6444,7 +5586,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- t.report("%-50s modules: %2i default: %6s value: %6s",name,modules,default,value)
+ t.report("%-30s modules: %2i default: %6s value: %6s",name,modules,default,value)
end
end
t.report()
@@ -6536,31 +5678,17 @@ end)
-- experiment
-if environment then
+local flags = environment and environment.engineflags
- -- The engineflags are known earlier than environment.arguments but maybe we
- -- need to handle them both as the later are parsed differently. The c: prefix
- -- is used by mtx-context to isolate the flags from those that concern luatex.
-
- local engineflags = environment.engineflags
-
- if engineflags then
- if trackers then
- local list = engineflags["c:trackers"] or engineflags["trackers"]
- if type(list) == "string" then
- setters.initialize("flags","trackers",settings_to_hash(list))
- -- t_enable(list)
- end
- end
- if directives then
- local list = engineflags["c:directives"] or engineflags["directives"]
- if type(list) == "string" then
- setters.initialize("flags","directives", settings_to_hash(list))
- -- d_enable(list)
- end
- end
+if flags then
+ if trackers and flags.trackers then
+ setters.initialize("flags","trackers", settings_to_hash(flags.trackers))
+ -- t_enable(flags.trackers)
+ end
+ if directives and flags.directives then
+ setters.initialize("flags","directives", settings_to_hash(flags.directives))
+ -- d_enable(flags.directives)
end
-
end
-- here
@@ -6613,7 +5741,10 @@ local next, type = next, type
local setmetatableindex = table.setmetatableindex
-
+--[[ldx--
+
This is a prelude to a more extensive logging module. We no longer
+provide based logging a sparsing is relatively easy anyway.
+--ldx]]--
logs = logs or { }
local logs = logs
@@ -7429,8 +6560,7 @@ local allocate, mark = utilities.storage.allocate, utilities.storage.mark
local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find
local unquoted, quoted = string.unquoted, string.quoted
-local concat, insert, remove = table.concat, table.insert, table.remove
-local loadedluacode = utilities.lua.loadedluacode
+local concat = table.concat
-- precautions
@@ -7448,28 +6578,8 @@ if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaon
for k=3,#arg do
arg[k-2] = arg[k]
end
- remove(arg) -- last
- remove(arg) -- pre-last
-end
-
--- This is an ugly hack but it permits symlinking a script (say 'context') to 'mtxrun' as in:
---
--- ln -s /opt/minimals/tex/texmf-linux-64/bin/mtxrun context
---
--- The special mapping hack is needed because 'luatools' boils down to 'mtxrun --script base'
--- but it's unlikely that there will be more of this
-
-do
-
- local originalzero = file.basename(arg[0])
- local specialmapping = { luatools == "base" }
-
- if originalzero ~= "mtxrun" and originalzero ~= "mtxrun.lua" then
- arg[0] = specialmapping[originalzero] or originalzero
- insert(arg,0,"--script")
- insert(arg,0,"mtxrun")
- end
-
+ arg[#arg] = nil -- last
+ arg[#arg] = nil -- pre-last
end
-- environment
@@ -7509,8 +6619,6 @@ local mt = {
setmetatable(environment,mt)
--- context specific arguments (in order not to confuse the engine)
-
function environment.initializearguments(arg)
local arguments, files = { }, { }
environment.arguments, environment.files, environment.sortedflags = arguments, files, nil
@@ -7519,12 +6627,10 @@ function environment.initializearguments(arg)
if index > 0 then
local flag, value = match(argument,"^%-+(.-)=(.-)$")
if flag then
- flag = gsub(flag,"^c:","")
arguments[flag] = unquoted(value or "")
else
flag = match(argument,"^%-+(.+)")
if flag then
- flag = gsub(flag,"^c:","")
arguments[flag] = true
else
files[#files+1] = argument
@@ -7544,7 +6650,7 @@ end
-- tricky: too many hits when we support partials unless we add
-- a registration of arguments so from now on we have 'partial'
-function environment.getargument(name,partial)
+function environment.argument(name,partial)
local arguments, sortedflags = environment.arguments, environment.sortedflags
if arguments[name] then
return arguments[name]
@@ -7567,8 +6673,6 @@ function environment.getargument(name,partial)
return nil
end
-environment.argument = environment.getargument
-
function environment.splitarguments(separator) -- rather special, cut-off before separator
local done, before, after = false, { }, { }
local originalarguments = environment.originalarguments
@@ -7654,7 +6758,7 @@ function environment.texfile(filename)
return resolvers.findfile(filename,'tex')
end
-function environment.luafile(filename) -- needs checking
+function environment.luafile(filename)
local resolved = resolvers.findfile(filename,'tex') or ""
if resolved ~= "" then
return resolved
@@ -7666,16 +6770,13 @@ function environment.luafile(filename) -- needs checking
return resolvers.findfile(filename,'luatexlibs') or ""
end
-local function checkstrip(filename)
- local modu = modules[file.nameonly(filename)]
- return modu and modu.dataonly
-end
+environment.loadedluacode = loadfile -- can be overloaded
function environment.luafilechunk(filename,silent) -- used for loading lua bytecode in the format
filename = file.replacesuffix(filename, "lua")
local fullname = environment.luafile(filename)
if fullname and fullname ~= "" then
- local data = loadedluacode(fullname,checkstrip,filename)
+ local data = environment.loadedluacode(fullname)
if trace_locating then
report_lua("loading file %s%s", fullname, not data and " failed" or "")
elseif not silent then
@@ -7773,7 +6874,21 @@ local trace_entities = false trackers.register("xml.entities", function(v) trac
local report_xml = logs and logs.reporter("xml","core") or function(...) print(format(...)) end
+--[[ldx--
+
The parser used here is inspired by the variant discussed in the lua book, but
+handles comment and processing instructions, has a different structure, provides
+parent access; a first version used different trickery but was less optimized to we
+went this route. First we had a find based parser, now we have an based one.
+The find based parser can be found in l-xml-edu.lua along with other older code.
+
Beware, the interface may change. For instance at, ns, tg, dt may get more
+verbose names. Once the code is stable we will also remove some tracing and
+optimize the code.
+
+
I might even decide to reimplement the parser using the latest trickery
+as the current variant was written when showed up and it's easier now to
+build tables in one go.
+--ldx]]--
xml = xml or { }
local xml = xml
@@ -7783,25 +6898,46 @@ local utf = unicode.utf8
local concat, remove, insert = table.concat, table.remove, table.insert
local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber
local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub
-local utfchar = utf.char
+local utfchar, utffind, utfgsub = utf.char, utf.find, utf.gsub
local lpegmatch = lpeg.match
local P, S, R, C, V, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.C, lpeg.Cs
-
+--[[ldx--
+
First a hack to enable namespace resolving. A namespace is characterized by
+a . The following function associates a namespace prefix with a
+pattern. We use , which in this case is more than twice as fast as a
+find based solution where we loop over an array of patterns. Less code and
+much cleaner.
+--ldx]]--
xml.xmlns = xml.xmlns or { }
local check = P(false)
local parse = check
+--[[ldx--
+
The next function associates a namespace prefix with an . This
+normally happens independent of parsing.
+
+xml.registerns("mml","mathml")
+
+--ldx]]--
function xml.registerns(namespace, pattern) -- pattern can be an lpeg
check = check + C(P(lower(pattern))) / namespace
parse = P { P(check) + 1 * V(1) }
end
+--[[ldx--
+
The next function also registers a namespace, but this time we map a
+given namespace prefix onto a registered one, using the given
+. This used for attributes like xmlns:m.
+
+xml.checkns("m","http://www.w3.org/mathml")
+
+--ldx]]--
function xml.checkns(namespace,url)
local ns = lpegmatch(parse,lower(url))
@@ -7810,15 +6946,66 @@ function xml.checkns(namespace,url)
end
end
+--[[ldx--
+
Next we provide a way to turn an into a registered
+namespace. This used for the xmlns attribute.
+
+resolvedns = xml.resolvens("http://www.w3.org/mathml")
+
+
+This returns mml.
+--ldx]]--
function xml.resolvens(url)
return lpegmatch(parse,lower(url)) or ""
end
-
-
-
+--[[ldx--
+
A namespace in an element can be remapped onto the registered
+one efficiently by using the xml.xmlns table.
+--ldx]]--
+
+--[[ldx--
+
This version uses . We follow the same approach as before, stack and top and
+such. This version is about twice as fast which is mostly due to the fact that
+we don't have to prepare the stream for cdata, doctype etc etc. This variant is
+is dedicated to Luigi Scarso, who challenged me with 40 megabyte files that
+took 12.5 seconds to load (1.5 for file io and the rest for tree building). With
+the implementation we got that down to less 7.3 seconds. Loading the 14
+ interface definition files (2.6 meg) went down from 1.05 seconds to 0.55.
+
+
Next comes the parser. The rather messy doctype definition comes in many
+disguises so it is no surprice that later on have to dedicate quite some
+ code to it.
+
+
+
+
+
+
+
+
+
+
+
The code may look a bit complex but this is mostly due to the fact that we
+resolve namespaces and attach metatables. There is only one public function:
+
+
+local x = xml.convert(somestring)
+
+
+
An optional second boolean argument tells this function not to create a root
+element.
+
+
Valid entities are:
+
+
+
+
+
+
+--ldx]]--
-- not just one big nested table capture (lpeg overflow)
@@ -8033,7 +7220,15 @@ local privates_n = {
-- keeps track of defined ones
}
-local escaped = utf.remapper(privates_u)
+local function escaped(s)
+ if s == "" then
+ return ""
+ else -- if utffind(s,privates_u) then
+ return (utfgsub(s,".",privates_u))
+ -- else
+ -- return s
+ end
+end
local function unescaped(s)
local p = privates_n[s]
@@ -8048,7 +7243,13 @@ local function unescaped(s)
return p
end
-local unprivatized = utf.remapper(privates_p)
+local function unprivatized(s,resolve)
+ if s == "" then
+ return ""
+ else
+ return (utfgsub(s,".",privates_p))
+ end
+end
xml.privatetoken = unescaped
xml.unprivatized = unprivatized
@@ -8388,12 +7589,7 @@ local function _xmlconvert_(data, settings)
else
errorhandler = errorhandler or xml.errorhandler
if errorhandler then
- local currentresource = settings.currentresource
- if currentresource and currentresource ~= "" then
- xml.errorhandler(format("load error in [%s]: %s",currentresource,errorstr))
- else
- xml.errorhandler(format("load error: %s",errorstr))
- end
+ xml.errorhandler(format("load error: %s",errorstr))
end
end
else
@@ -8438,7 +7634,7 @@ function xmlconvert(data,settings)
if ok then
return result
else
- return _xmlconvert_("",settings)
+ return _xmlconvert_("")
end
end
@@ -8459,7 +7655,10 @@ function xml.inheritedconvert(data,xmldata) -- xmldata is parent
return xc
end
-
+--[[ldx--
+
Packaging data in an xml like table is done with the following
+function. Maybe it will go away (when not used).
+--ldx]]--
function xml.is_valid(root)
return root and root.dt and root.dt[1] and type(root.dt[1]) == "table" and not root.dt[1].er
@@ -8478,7 +7677,11 @@ end
xml.errorhandler = report_xml
-
+--[[ldx--
+
We cannot load an from a filehandle so we need to load
+the whole file first. The function accepts a string representing
+a filename or a file handle.
+--ldx]]--
function xml.load(filename,settings)
local data = ""
@@ -8492,17 +7695,13 @@ function xml.load(filename,settings)
elseif filename then -- filehandle
data = filename:read("*all")
end
- if settings then
- settings.currentresource = filename
- local result = xmlconvert(data,settings)
- settings.currentresource = nil
- return result
- else
- return xmlconvert(data,{ currentresource = filename })
- end
+ return xmlconvert(data,settings)
end
-
+--[[ldx--
+
When we inject new elements, we need to convert strings to
+valid trees, which is what the next function does.
+--ldx]]--
local no_root = { no_root = true }
@@ -8515,7 +7714,11 @@ function xml.toxml(data)
end
end
-
+--[[ldx--
+
For copying a tree we use a dedicated function instead of the
+generic table copier. Since we know what we're dealing with we
+can speed up things a bit. The second argument is not to be used!
+--ldx]]--
local function copy(old,tables)
if old then
@@ -8539,7 +7742,13 @@ end
xml.copy = copy
-
+--[[ldx--
+
In serializing the tree or parts of the tree is a major
+actitivity which is why the following function is pretty optimized resulting
+in a few more lines of code than needed. The variant that uses the formatting
+function for all components is about 15% slower than the concatinating
+alternative.
+--ldx]]--
-- todo: add when not present
@@ -8552,12 +7761,15 @@ function xml.checkbom(root) -- can be made faster
return
end
end
- insert(dt, 1, { special = true, ns = "", tg = "@pi@", dt = { "xml version='1.0' standalone='yes'" } } )
+ insert(dt, 1, { special=true, ns="", tg="@pi@", dt = { "xml version='1.0' standalone='yes'"} } )
insert(dt, 2, "\n" )
end
end
-
+--[[ldx--
+
At the cost of some 25% runtime overhead you can first convert the tree to a string
+and then handle the lot.
How you deal with saving data depends on your preferences. For a 40 MB database
+file the timing on a 2.3 Core Duo are as follows (time in seconds):
+
+
+1.3 : load data from file to string
+6.1 : convert string into tree
+5.3 : saving in file using xmlsave
+6.8 : converting to string using xml.tostring
+3.6 : saving converted string in file
+
+
Beware, these were timing with the old routine but measurements will not be that
+much different I guess.
+--ldx]]--
-- maybe this will move to lxml-xml
@@ -8828,7 +8054,10 @@ xml.newhandlers = newhandlers
xml.serialize = serialize
xml.tostring = xmltostring
-
+--[[ldx--
+
The next function operated on the content only and needs a handle function
+that accepts a string.
+--ldx]]--
local function xmlstring(e,handle)
if not handle or (e.special and e.tg ~= "@rt@") then
@@ -8847,7 +8076,9 @@ end
xml.string = xmlstring
-
+--[[ldx--
+
A few helpers:
+--ldx]]--
function xml.settings(e)
@@ -8891,7 +8122,11 @@ function xml.name(root)
end
end
-
+--[[ldx--
+
The next helper erases an element but keeps the table as it is,
+and since empty strings are not serialized (effectively) it does
+not harm. Copying the table would take more time. Usage:
+--ldx]]--
function xml.erase(dt,k)
if dt then
@@ -8903,7 +8138,13 @@ function xml.erase(dt,k)
end
end
+--[[ldx--
+
The next helper assigns a tree (or string). Usage:
+
+dt[k] = xml.assign(root) or xml.assign(dt,k,root)
+
+--ldx]]--
function xml.assign(dt,k,root)
if dt and k then
@@ -8916,14 +8157,20 @@ end
-- the following helpers may move
-
+--[[ldx--
+
The next helper assigns a tree (or string). Usage:
+
+xml.tocdata(e)
+xml.tocdata(e,"error")
+
+--ldx]]--
function xml.tocdata(e,wrapper) -- a few more in the aux module
local whatever = type(e) == "table" and xmltostring(e.dt) or e or ""
if wrapper then
whatever = format("<%s>%s%s>",wrapper,whatever,wrapper)
end
- local t = { special = true, ns = "", tg = "@cd@", at = { }, rn = "", dt = { whatever }, __p__ = e }
+ local t = { special = true, ns = "", tg = "@cd@", at = {}, rn = "", dt = { whatever }, __p__ = e }
setmetatable(t,getmetatable(e))
e.dt = { t }
end
@@ -8978,7 +8225,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['lxml-lpt'] = {
+if not modules then modules = { } end modules ['lxml-pth'] = {
version = 1.001,
comment = "this module is the basis for the lxml-* ones",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -8999,9 +8246,28 @@ local setmetatableindex = table.setmetatableindex
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
-
-
-
+--[[ldx--
+
This module can be used stand alone but also inside in
+which case it hooks into the tracker code. Therefore we provide a few
+functions that set the tracers. Here we overload a previously defined
+function.
+
If I can get in the mood I will make a variant that is XSLT compliant
+but I wonder if it makes sense.
+--ldx]]--
+
+--[[ldx--
+
Expecially the lpath code is experimental, we will support some of xpath, but
+only things that make sense for us; as compensation it is possible to hook in your
+own functions. Apart from preprocessing content for we also need
+this module for process management, like handling and
+files.
+
+
+a/b/c /*/c
+a/b/c/first() a/b/c/last() a/b/c/index(n) a/b/c/index(-n)
+a/b/c/text() a/b/c/text(1) a/b/c/text(-1) a/b/c/text(n)
+
+--ldx]]--
local trace_lpath = false if trackers then trackers.register("xml.path", function(v) trace_lpath = v end) end
local trace_lparse = false if trackers then trackers.register("xml.parse", function(v) trace_lparse = v end) end
@@ -9009,7 +8275,11 @@ local trace_lprofile = false if trackers then trackers.register("xml.profile",
local report_lpath = logs.reporter("xml","lpath")
-
+--[[ldx--
+
We've now arrived at an interesting part: accessing the tree using a subset
+of and since we're not compatible we call it . We
+will explain more about its usage in other documents.
+--ldx]]--
local xml = xml
@@ -9461,23 +8731,14 @@ local lp_builtin = P (
-- for the moment we keep namespaces with attributes
local lp_attribute = (P("@") + P("attribute::")) / "" * Cc("(ll.at and ll.at['") * ((R("az","AZ") + S("-_:"))^1) * Cc("'])")
-
--- lp_fastpos_p = (P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end
--- lp_fastpos_n = (P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end
-
-lp_fastpos_p = P("+")^0 * R("09")^1 * P(-1) / "l==%0"
-lp_fastpos_n = P("-") * R("09")^1 * P(-1) / "(%0<0 and (#list+%0==l))"
-
+local lp_fastpos_p = ((P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end)
+local lp_fastpos_n = ((P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end)
local lp_fastpos = lp_fastpos_n + lp_fastpos_p
-
local lp_reserved = C("and") + C("or") + C("not") + C("div") + C("mod") + C("true") + C("false")
--- local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
--- return t .. "("
--- end
-
--- local lp_lua_function = (R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / "%0("
-local lp_lua_function = Cs((R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(")) / "%0"
+local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
+ return t .. "("
+end
local lp_function = C(R("az","AZ","__")^1) * P("(") / function(t) -- todo: better . handling
if expressions[t] then
@@ -9993,7 +9254,9 @@ end
xml.applylpath = applylpath -- takes a table as first argment, which is what xml.filter will do
-
+--[[ldx--
+
This is the main filter function. It returns whatever is asked for.
+--ldx]]--
function xml.filter(root,pattern) -- no longer funny attribute handling here
return applylpath(root,pattern)
@@ -10091,12 +9354,12 @@ xml.selection = selection -- new method, simple handle
-- generic function finalizer (independant namespace)
-local function dofunction(collected,fnc,...)
+local function dofunction(collected,fnc)
if collected then
local f = functions[fnc]
if f then
for c=1,#collected do
- f(collected[c],...)
+ f(collected[c])
end
else
report_lpath("unknown function '%s'",fnc)
@@ -10197,7 +9460,21 @@ expressions.tag = function(e,n) -- only tg
end
end
+--[[ldx--
+
Often using an iterators looks nicer in the code than passing handler
+functions. The book describes how to use coroutines for that
+purpose (). This permits
+code like:
+
+for r, d, k in xml.elements(xml.load('text.xml'),"title") do
+ print(d[k]) -- old method
+end
+for e in xml.collected(xml.load('text.xml'),"title") do
+ print(e) -- new one
+end
+
+--ldx]]--
local wrap, yield = coroutine.wrap, coroutine.yield
@@ -10238,32 +9515,6 @@ function xml.inspect(collection,pattern)
end
end
--- texy (see xfdf):
-
-local function split(e)
- local dt = e.dt
- if dt then
- for i=1,#dt do
- local dti = dt[i]
- if type(dti) == "string" then
- dti = gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti = gsub(dti,"[\n\r]+","\n\n")
- dt[i] = dti
- else
- split(dti)
- end
- end
- end
- return e
-end
-
-function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
-end
-
end -- of closure
@@ -10288,7 +9539,13 @@ local P, S, R, C, V, Cc, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, l
lpegpatterns.xml = lpegpatterns.xml or { }
local xmlpatterns = lpegpatterns.xml
-
+--[[ldx--
+
The following helper functions best belong to the lxml-ini
+module. Some are here because we need then in the mk
+document and other manuals, others came up when playing with
+this module. Since this module is also used in we've
+put them here instead of loading mode modules there then needed.
+--ldx]]--
local function xmlgsub(t,old,new) -- will be replaced
local dt = t.dt
@@ -10474,7 +9731,9 @@ function xml.processattributes(root,pattern,handle)
return collected
end
-
+--[[ldx--
+
The following functions collect elements and texts.
+--ldx]]--
-- are these still needed -> lxml-cmp.lua
@@ -10513,7 +9772,9 @@ function xml.collect_tags(root, pattern, nonamespace)
end
end
-
+--[[ldx--
+
We've now arrived at the functions that manipulate the tree.
+--ldx]]--
local no_root = { no_root = true }
@@ -10899,7 +10160,9 @@ function xml.remapname(root, pattern, newtg, newns, newrn)
end
end
-
+--[[ldx--
+
Helper (for q2p).
+--ldx]]--
function xml.cdatatotext(e)
local dt = e.dt
@@ -10996,7 +10259,9 @@ end
-- xml.addentitiesdoctype(x,"hexadecimal")
-- print(x)
-
+--[[ldx--
+
Here are a few synonyms.
+--ldx]]--
xml.all = xml.each
xml.insert = xml.insertafter
@@ -11587,7 +10852,7 @@ local gsub, find, gmatch, char = string.gsub, string.find, string.gmatch, string
local concat = table.concat
local next, type = next, type
-local filedirname, filebasename, filejoin = file.dirname, file.basename, file.join
+local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -11937,14 +11202,12 @@ local function splitpathexpr(str, newlist, validate) -- I couldn't resist lpeggi
for s in gmatch(str,"[^,]+") do
s = validate(s)
if s then
- n = n + 1
- t[n] = s
+ n = n + 1 ; t[n] = s
end
end
else
for s in gmatch(str,"[^,]+") do
- n = n + 1
- t[n] = s
+ n = n + 1 ; t[n] = s
end
end
if trace_expansions then
@@ -11958,7 +11221,7 @@ end
-- We could make the previous one public.
local function validate(s)
- s = collapsepath(s) -- already keeps the trailing / and //
+ s = collapsepath(s) -- already keeps the //
return s ~= "" and not find(s,"^!*unset/*$") and s
end
@@ -12296,7 +11559,7 @@ local resolvers = resolvers
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
-local suffixonly = file.suffixonly
+local fileextname = file.extname
local formats = allocate()
local suffixes = allocate()
@@ -12551,7 +11814,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[suffixonly(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
+ return suffixmap[fileextname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
@@ -12563,7 +11826,7 @@ function resolvers.variableofformatorsuffix(str)
if v then
return v
end
- v = suffixmap[suffixonly(str)]
+ v = suffixmap[fileextname(str)]
if v then
return formats[v]
end
@@ -12584,7 +11847,21 @@ if not modules then modules = { } end modules ['data-tmp'] = {
license = "see context related readme files"
}
+--[[ldx--
+
This module deals with caching data. It sets up the paths and
+implements loaders and savers for tables. Best is to set the
+following variable. When not set, the usual paths will be
+checked. Personally I prefer the (users) temporary path.
Currently we do no locking when we write files. This is no real
+problem because most caching involves fonts and the chance of them
+being written at the same time is small. We also need to extend
+luatools with a recache feature.
+--ldx]]--
local format, lower, gsub, concat = string.format, string.lower, string.gsub, table.concat
local serialize, serializetofile = table.serialize, table.tofile
@@ -13119,12 +12396,11 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local filedirname = file.dirname
local filebasename = file.basename
-local suffixonly = file.suffixonly
+local fileextname = file.extname
local filejoin = file.join
local collapsepath = file.collapsepath
local joinpath = file.joinpath
local allocate = utilities.storage.allocate
-local settings_to_array = utilities.parsers.settings_to_array
local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
@@ -13148,7 +12424,7 @@ resolvers.cacheversion = '1.0.1'
resolvers.configbanner = ''
resolvers.homedir = environment.homedir
resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" }
-resolvers.luacnfname = "texmfcnf.lua"
+resolvers.luacnfname = 'texmfcnf.lua'
resolvers.luacnfstate = "unknown"
-- The web2c tex binaries as well as kpse have built in paths for the configuration
@@ -13420,7 +12696,7 @@ end
local function identify_configuration_files()
local specification = instance.specification
if #specification == 0 then
- local cnfspec = getenv("TEXMFCNF")
+ local cnfspec = getenv('TEXMFCNF')
if cnfspec == "" then
cnfspec = resolvers.luacnfspec
resolvers.luacnfstate = "default"
@@ -13508,7 +12784,7 @@ local function load_configuration_files()
-- we push the value into the main environment (osenv) so
-- that it takes precedence over the default one and therefore
-- also over following definitions
- resolvers.setenv("TEXMFCNF",cnfspec) -- resolves prefixes
+ resolvers.setenv('TEXMFCNF',cnfspec) -- resolves prefixes
-- we now identify and load the specified configuration files
instance.specification = { }
identify_configuration_files()
@@ -13556,11 +12832,10 @@ end
local function locate_file_databases()
-- todo: cache:// and tree:// (runtime)
- local texmfpaths = resolvers.expandedpathlist("TEXMF")
+ local texmfpaths = resolvers.expandedpathlist('TEXMF')
if #texmfpaths > 0 then
for i=1,#texmfpaths do
local path = collapsepath(texmfpaths[i])
- path = gsub(path,"/+$","") -- in case $HOME expands to something with a trailing /
local stripped = lpegmatch(inhibitstripper,path) -- the !! thing
if stripped ~= "" then
local runtime = stripped == path
@@ -13689,9 +12964,9 @@ function resolvers.prependhash(type,name,cache)
end
function resolvers.extendtexmfvariable(specification) -- crap, we could better prepend the hash
- local t = resolvers.splitpath(getenv("TEXMF")) -- okay?
+ local t = resolvers.splitpath(getenv('TEXMF'))
insert(t,1,specification)
- local newspec = concat(t,",") -- not ;
+ local newspec = concat(t,";")
if instance.environment["TEXMF"] then
instance.environment["TEXMF"] = newspec
elseif instance.variables["TEXMF"] then
@@ -13766,19 +13041,14 @@ function resolvers.resetextrapath()
end
function resolvers.registerextrapath(paths,subpaths)
- paths = settings_to_array(paths)
- subpaths = settings_to_array(subpaths)
local ep = instance.extra_paths or { }
local oldn = #ep
local newn = oldn
- local nofpaths = #paths
- local nofsubpaths = #subpaths
- if nofpaths > 0 then
- if nofsubpaths > 0 then
- for i=1,nofpaths do
- local p = paths[i]
- for j=1,nofsubpaths do
- local s = subpaths[j]
+ if paths and paths ~= "" then
+ if subpaths and subpaths ~= "" then
+ for p in gmatch(paths,"[^,]+") do
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
local ps = p .. "/" .. s
if not done[ps] then
newn = newn + 1
@@ -13788,8 +13058,7 @@ function resolvers.registerextrapath(paths,subpaths)
end
end
else
- for i=1,nofpaths do
- local p = paths[i]
+ for p in gmatch(paths,"[^,]+") do
if not done[p] then
newn = newn + 1
ep[newn] = resolvers.cleanpath(p)
@@ -13797,10 +13066,10 @@ function resolvers.registerextrapath(paths,subpaths)
end
end
end
- elseif nofsubpaths > 0 then
+ elseif subpaths and subpaths ~= "" then
for i=1,oldn do
- for j=1,nofsubpaths do
- local s = subpaths[j]
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
local ps = ep[i] .. "/" .. s
if not done[ps] then
newn = newn + 1
@@ -13878,21 +13147,18 @@ function resolvers.expandedpathlist(str)
return { }
elseif instance.savelists then
str = lpegmatch(dollarstripper,str)
- local lists = instance.lists
- local lst = lists[str]
- if not lst then
- local l = made_list(instance,resolvers.splitpath(resolvers.expansion(str)))
- lst = expandedpathfromlist(l)
- lists[str] = lst
- end
- return lst
+ if not instance.lists[str] then -- cached
+ local lst = made_list(instance,resolvers.splitpath(resolvers.expansion(str)))
+ instance.lists[str] = expandedpathfromlist(lst)
+ end
+ return instance.lists[str]
else
local lst = resolvers.splitpath(resolvers.expansion(str))
return made_list(instance,expandedpathfromlist(lst))
end
end
-function resolvers.expandedpathlistfromvariable(str) -- brrr / could also have cleaner ^!! /$ //
+function resolvers.expandedpathlistfromvariable(str) -- brrr
str = lpegmatch(dollarstripper,str)
local tmp = resolvers.variableofformatorsuffix(str)
return resolvers.expandedpathlist(tmp ~= "" and tmp or str)
@@ -14049,7 +13315,7 @@ local preparetreepattern = Cs((P(".")/"%%." + P("-")/"%%-" + P(1))^0 * Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype, wantedfiles, ext = '', { }, suffixonly(filename)
+ local filetype, wantedfiles, ext = '', { }, fileextname(filename)
-- too tricky as filename can be bla.1.2.3:
--
-- if not suffixmap[ext] then
@@ -14127,7 +13393,7 @@ local function find_qualified(filename,allresults) -- this one will be split too
if trace_detail then
report_resolving("locating qualified file '%s'", filename)
end
- local forcedname, suffix = "", suffixonly(filename)
+ local forcedname, suffix = "", fileextname(filename)
if suffix == "" then -- why
local format_suffixes = askedformat == "" and resolvers.defaultsuffixes or suffixes[askedformat]
if format_suffixes then
@@ -14797,8 +14063,6 @@ local gsub = string.gsub
local cleanpath, findgivenfile, expansion = resolvers.cleanpath, resolvers.findgivenfile, resolvers.expansion
local getenv = resolvers.getenv -- we can probably also use resolvers.expansion
local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
-local joinpath, basename, dirname = file.join, file.basename, file.dirname
-local getmetatable, rawset, type = getmetatable, rawset, type
-- getenv = function(...) return resolvers.getenv(...) end -- needs checking (definitions changes later on)
@@ -14840,43 +14104,28 @@ end
prefixes.filename = function(str)
local fullname = findgivenfile(str) or ""
- return cleanpath(basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
+ return cleanpath(file.basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
end
prefixes.pathname = function(str)
local fullname = findgivenfile(str) or ""
- return cleanpath(dirname((fullname ~= "" and fullname) or str))
+ return cleanpath(file.dirname((fullname ~= "" and fullname) or str))
end
prefixes.selfautoloc = function(str)
- return cleanpath(joinpath(getenv('SELFAUTOLOC'),str))
+ return cleanpath(file.join(getenv('SELFAUTOLOC'),str))
end
prefixes.selfautoparent = function(str)
- return cleanpath(joinpath(getenv('SELFAUTOPARENT'),str))
+ return cleanpath(file.join(getenv('SELFAUTOPARENT'),str))
end
prefixes.selfautodir = function(str)
- return cleanpath(joinpath(getenv('SELFAUTODIR'),str))
+ return cleanpath(file.join(getenv('SELFAUTODIR'),str))
end
prefixes.home = function(str)
- return cleanpath(joinpath(getenv('HOME'),str))
-end
-
-local function toppath()
- local pathname = dirname(inputstack[#inputstack] or "")
- if pathname == "" then
- return "."
- else
- return pathname
- end
-end
-
-resolvers.toppath = toppath
-
-prefixes.toppath = function(str)
- return cleanpath(joinpath(toppath(),str))
+ return cleanpath(file.join(getenv('HOME'),str))
end
prefixes.env = prefixes.environment
@@ -14912,8 +14161,6 @@ function resolvers.resetresolve(str)
resolved, abstract = { }, { }
end
--- todo: use an lpeg (see data-lua for !! / stripper)
-
local function resolve(str) -- use schemes, this one is then for the commandline only
if type(str) == "table" then
local t = { }
@@ -14939,7 +14186,7 @@ end
resolvers.resolve = resolve
resolvers.unresolve = unresolve
-if type(os.uname) == "function" then
+if os.uname then
for k, v in next, os.uname() do
if not prefixes[k] then
@@ -14951,17 +14198,11 @@ end
if os.type == "unix" then
- -- We need to distringuish between a prefix and something else : so we
- -- have a special repath variant for linux. Also, when a new prefix is
- -- defined, we need to remake the matcher.
-
local pattern
local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
local colon = P(":")
+ local p
for k, v in table.sortedpairs(prefixes) do
if p then
p = P(k) + p
@@ -14970,6 +14211,9 @@ if os.type == "unix" then
end
end
pattern = Cs((p * colon + colon/";" + P(1))^0)
+ if t then
+ t[k] = v
+ end
end
makepattern()
@@ -15180,7 +14424,18 @@ local trace_cache = false trackers.register("resolvers.cache", functi
local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
+--[[ldx--
+
Once we found ourselves defining similar cache constructs
+several times, containers were introduced. Containers are used
+to collect tables in memory and reuse them when possible based
+on (unique) hashes (to be provided by the calling function).
+
+
Caching to disk is disabled by default. Version numbers are
+stored in the saved table which makes it possible to change the
+table structures without bothering about the disk cache.
+
Examples of usage can be found in the font related code.
+--ldx]]--
containers = containers or { }
local containers = containers
@@ -15415,7 +14670,11 @@ local trace_locating = false trackers.register("resolvers.locating", function(v
local report_zip = logs.reporter("resolvers","zip")
-
+-- zip:///oeps.zip?name=bla/bla.tex
+-- zip:///oeps.zip?tree=tex/texmf-local
+-- zip:///texmf.zip?tree=/tex/texmf
+-- zip:///texmf.zip?tree=/tex/texmf-local
+-- zip:///texmf-mine.zip?tree=/tex/texmf-projects
local resolvers = resolvers
@@ -15740,7 +14999,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['data-sch'] = {
+if not modules then modules = { } end modules ['data-crl'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -15748,199 +15007,60 @@ if not modules then modules = { } end modules ['data-sch'] = {
license = "see context related readme files"
}
-local loadstring = loadstring
-local gsub, concat, format = string.gsub, table.concat, string.format
-local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
-
-local trace_schemes = false trackers.register("resolvers.schemes",function(v) trace_schemes = v end)
-local report_schemes = logs.reporter("resolvers","schemes")
-
-local http = require("socket.http")
-local ltn12 = require("ltn12")
+-- this one is replaced by data-sch.lua --
-local resolvers = resolvers
-local schemes = resolvers.schemes or { }
-resolvers.schemes = schemes
-
-local cleaners = { }
-schemes.cleaners = cleaners
-
-local threshold = 24 * 60 * 60
-
-directives.register("schemes.threshold", function(v) threshold = tonumber(v) or threshold end)
-
-function cleaners.none(specification)
- return specification.original
-end
-
-function cleaners.strip(specification)
- return (gsub(specification.original,"[^%a%d%.]+","-")) -- so we keep periods
-end
-
-function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
-end
-
-local cleaner = cleaners.strip
+local gsub = string.gsub
-directives.register("schemes.cleanmethod", function(v) cleaner = cleaners[v] or cleaners.strip end)
+local resolvers = resolvers
-function resolvers.schemes.cleanname(specification)
- local hash = cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %s to %s",specification.original,hash)
- end
- return hash
-end
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
-local cached, loaded, reused, thresholds, handlers = { }, { }, { }, { }, { }
+resolvers.curl = resolvers.curl or { }
+local curl = resolvers.curl
-local function runcurl(name,cachename) -- we use sockets instead or the curl library when possible
- local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name
- os.spawn(command)
-end
+local cached = { }
-local function fetch(specification)
+local function runcurl(specification)
local original = specification.original
- local scheme = specification.scheme
- local cleanname = schemes.cleanname(specification)
- local cachename = caches.setfirstwritablefile(cleanname,"schemes")
+ -- local scheme = specification.scheme
+ local cleanname = gsub(original,"[^%a%d%.]+","-")
+ local cachename = caches.setfirstwritablefile(cleanname,"curl")
if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification) > (thresholds[protocol] or threshold)) then
+ if not io.exists(cachename) then
cached[original] = cachename
- local handler = handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching '%s', protocol '%s', method 'built-in'",original,scheme)
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching '%s', protocol '%s', method 'curl'",original,scheme)
- end
- logs.flush()
- runcurl(original,cachename)
- end
+ local command = "curl --silent --create-dirs --output " .. cachename .. " " .. original
+ os.spawn(command)
end
if io.exists(cachename) then
cached[original] = cachename
- if trace_schemes then
- report_schemes("using cached '%s', protocol '%s', cachename '%s'",original,scheme,cachename)
- end
else
cached[original] = ""
- if trace_schemes then
- report_schemes("using missing '%s', protocol '%s'",original,scheme)
- end
end
- loaded[scheme] = loaded[scheme] + 1
- statistics.stoptiming(schemes)
- else
- if trace_schemes then
- report_schemes("reusing '%s', protocol '%s'",original,scheme)
- end
- reused[scheme] = reused[scheme] + 1
end
return cached[original]
end
+-- old code: we could be cleaner using specification (see schemes)
+
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",runcurl(specification),filetype)
end
local opener = openers.file
local loader = loaders.file
-local function install(scheme,handler,newthreshold)
- handlers [scheme] = handler
- loaded [scheme] = 0
- reused [scheme] = 0
- finders [scheme] = finder
- openers [scheme] = opener
- loaders [scheme] = loader
- thresholds[scheme] = newthreshold or threshold
+local function install(scheme)
+ finders[scheme] = finder
+ openers[scheme] = opener
+ loaders[scheme] = loader
end
-schemes.install = install
-
-local function http_handler(specification,cachename)
- local tempname = cachename .. ".tmp"
- local f = io.open(tempname,"wb")
- local status, message = http.request {
- url = specification.original,
- sink = ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
-end
+resolvers.curl.install = install
-install('http',http_handler)
-install('https') -- see pod
+install('http')
+install('https')
install('ftp')
-statistics.register("scheme handling time", function()
- local l, r, nl, nr = { }, { }, 0, 0
- for k, v in table.sortedhash(loaded) do
- if v > 0 then
- nl = nl + 1
- l[nl] = k .. ":" .. v
- end
- end
- for k, v in table.sortedhash(reused) do
- if v > 0 then
- nr = nr + 1
- r[nr] = k .. ":" .. v
- end
- end
- local n = nl + nr
- if n > 0 then
- l = nl > 0 and concat(l) or "none"
- r = nr > 0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes), n, threshold, l, r)
- else
- return nil
- end
-end)
-
--- We provide a few more helpers:
-
------ http = require("socket.http")
-local httprequest = http.request
-local toquery = url.toquery
-
--- local function httprequest(url)
--- return os.resultof(format("curl --silent %q", url))
--- end
-
-local function fetchstring(url,data)
- local q = data and toquery(data)
- if q then
- url = url .. "?" .. q
- end
- local reply = httprequest(url)
- return reply -- just one argument
-end
-
-schemes.fetchstring = fetchstring
-
-function schemes.fetchtable(url,data)
- local reply = fetchstring(url,data)
- if reply then
- local s = loadstring("return " .. reply)
- if s then
- return s()
- end
- end
-end
-
end -- of closure
@@ -15954,199 +15074,170 @@ if not modules then modules = { } end modules ['data-lua'] = {
license = "see context related readme files"
}
--- We overload the regular loader. We do so because we operate mostly in
--- tds and use our own loader code. Alternatively we could use a more
--- extensive definition of package.path and package.cpath but even then
--- we're not done. Also, we now have better tracing.
---
--- -- local mylib = require("libtest")
--- -- local mysql = require("luasql.mysql")
-
-local concat = table.concat
-
-local trace_libraries = false
+-- some loading stuff ... we might move this one to slot 2 depending
+-- on the developments (the loaders must not trigger kpse); we could
+-- of course use a more extensive lib path spec
-trackers.register("resolvers.libraries", function(v) trace_libraries = v end)
-trackers.register("resolvers.locating", function(v) trace_libraries = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local report_libraries = logs.reporter("resolvers","libraries")
local gsub, insert = string.gsub, table.insert
-local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
local unpack = unpack or table.unpack
-local is_readable = file.is_readable
local resolvers, package = resolvers, package
-local libsuffixes = { 'tex', 'lua' }
-local clibsuffixes = { 'lib' }
-local libformats = { 'TEXINPUTS', 'LUAINPUTS' }
-local clibformats = { 'CLUAINPUTS' }
-
-local libpaths = nil
-local clibpaths = nil
-local libhash = { }
-local clibhash = { }
-local libextras = { }
-local clibextras = { }
-
-local pattern = Cs(P("!")^0 / "" * (P("/") * P(-1) / "/" + P("/")^1 / "/" + 1)^0)
-
-local function cleanpath(path) --hm, don't we have a helper for this?
- return resolvers.resolve(lpegmatch(pattern,path))
-end
-
-local function getlibpaths()
- if not libpaths then
- libpaths = { }
- for i=1,#libformats do
- local paths = resolvers.expandedpathlistfromvariable(libformats[i])
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not libhash[path] then
- libpaths[#libpaths+1] = path
- libhash[path] = true
- end
- end
- end
+local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs'
+local clibformats = { 'lib' }
+
+local _path_, libpaths, _cpath_, clibpaths
+
+function package.libpaths()
+ if not _path_ or package.path ~= _path_ then
+ _path_ = package.path
+ libpaths = file.splitpath(_path_,";")
end
return libpaths
end
-local function getclibpaths()
- if not clibpaths then
- clibpaths = { }
- for i=1,#clibformats do
- local paths = resolvers.expandedpathlistfromvariable(clibformats[i])
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not clibhash[path] then
- clibpaths[#clibpaths+1] = path
- clibhash[path] = true
- end
- end
- end
+function package.clibpaths()
+ if not _cpath_ or package.cpath ~= _cpath_ then
+ _cpath_ = package.cpath
+ clibpaths = file.splitpath(_cpath_,";")
end
return clibpaths
end
-package.libpaths = getlibpaths
-package.clibpaths = getclibpaths
-
-function package.extralibpath(...)
- local paths = { ... }
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not libhash[path] then
- if trace_libraries then
- report_libraries("! extra lua path '%s'",path)
- end
- libextras[#libextras+1] = path
- libpaths[#libpaths +1] = path
- end
+local function thepath(...)
+ local t = { ... } t[#t+1] = "?.lua"
+ local path = file.join(unpack(t))
+ if trace_locating then
+ report_libraries("! appending '%s' to 'package.path'",path)
end
+ return path
end
-function package.extraclibpath(...)
- local paths = { ... }
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not clibhash[path] then
- if trace_libraries then
- report_libraries("! extra lib path '%s'",path)
- end
- clibextras[#clibextras+1] = path
- clibpaths[#clibpaths +1] = path
- end
- end
-end
+local p_libpaths, a_libpaths = { }, { }
-if not package.loaders[-2] then
- -- use package-path and package-cpath
- package.loaders[-2] = package.loaders[2]
+function package.appendtolibpath(...)
+ insert(a_libpath,thepath(...))
end
-local function loadedaslib(resolved,rawname)
- return package.loadlib(resolved,"luaopen_" .. gsub(rawname,"%.","_"))
+function package.prependtolibpath(...)
+ insert(p_libpaths,1,thepath(...))
end
-local function loadedbylua(name)
- if trace_libraries then
- report_libraries("! locating %q using normal loader",name)
+-- beware, we need to return a loadfile result !
+
+local function loaded(libpaths,name,simple)
+ for i=1,#libpaths do -- package.path, might become option
+ local libpath = libpaths[i]
+ local resolved = gsub(libpath,"%?",simple)
+ if trace_locating then -- more detail
+ report_libraries("! checking for '%s' on 'package.path': '%s' => '%s'",simple,libpath,resolved)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'package.path': '%s'",name,resolved)
+ end
+ return loadfile(resolved)
+ end
end
- local resolved = package.loaders[-2](name)
end
-local function loadedbyformat(name,rawname,suffixes,islib)
- if trace_libraries then
- report_libraries("! locating %q as %q using formats %q",rawname,name,concat(suffixes))
+package.loaders[2] = function(name) -- was [#package.loaders+1]
+ if file.suffix(name) == "" then
+ name = file.addsuffix(name,"lua") -- maybe a list
+ if trace_locating then -- mode detail
+ report_libraries("! locating '%s' with forced suffix",name)
+ end
+ else
+ if trace_locating then -- mode detail
+ report_libraries("! locating '%s'",name)
+ end
end
- for i=1,#suffixes do -- so we use findfile and not a lookup loop
- local format = suffixes[i]
+ for i=1,#libformats do
+ local format = libformats[i]
local resolved = resolvers.findfile(name,format) or ""
- if trace_libraries then
- report_libraries("! checking for %q' using format %q",name,format)
+ if trace_locating then -- mode detail
+ report_libraries("! checking for '%s' using 'libformat path': '%s'",name,format)
end
if resolved ~= "" then
- if trace_libraries then
- report_libraries("! lib %q located on %q",name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
+ if trace_locating then
+ report_libraries("! lib '%s' located via environment: '%s'",name,resolved)
end
+ return loadfile(resolved)
end
end
-end
-
-local function loadedbypath(name,rawname,paths,islib,what)
- if trace_libraries then
- report_libraries("! locating %q as %q on %q paths",rawname,name,what)
+ -- libpaths
+ local libpaths, clibpaths = package.libpaths(), package.clibpaths()
+ local simple = gsub(name,"%.lua$","")
+ local simple = gsub(simple,"%.","/")
+ local resolved = loaded(p_libpaths,name,simple) or loaded(libpaths,name,simple) or loaded(a_libpaths,name,simple)
+ if resolved then
+ return resolved
end
- for p=1,#paths do
- local path = paths[p]
- local resolved = file.join(path,name)
- if trace_libraries then -- mode detail
- report_libraries("! checking for %q using %q path %q",name,what,path)
- end
- if is_readable(resolved) then
- if trace_libraries then
- report_libraries("! lib %q located on %q",name,resolved)
+ --
+ local libname = file.addsuffix(simple,os.libsuffix)
+ for i=1,#clibformats do
+ -- better have a dedicated loop
+ local format = clibformats[i]
+ local paths = resolvers.expandedpathlistfromvariable(format)
+ for p=1,#paths do
+ local path = paths[p]
+ local resolved = file.join(path,libname)
+ if trace_locating then -- mode detail
+ report_libraries("! checking for '%s' using 'clibformat path': '%s'",libname,path)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'clibformat': '%s'",libname,resolved)
+ end
+ return package.loadlib(resolved,name)
end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
+ end
+ end
+ for i=1,#clibpaths do -- package.path, might become option
+ local libpath = clibpaths[i]
+ local resolved = gsub(libpath,"?",simple)
+ if trace_locating then -- more detail
+ report_libraries("! checking for '%s' on 'package.cpath': '%s'",simple,libpath)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'package.cpath': '%s'",name,resolved)
end
+ return package.loadlib(resolved,name)
end
end
-end
-
-local function notloaded(name)
- if trace_libraries then
- report_libraries("? unable to locate library %q",name)
+ -- just in case the distribution is messed up
+ if trace_loading then -- more detail
+ report_libraries("! checking for '%s' using 'luatexlibs': '%s'",name)
+ end
+ local resolved = resolvers.findfile(file.basename(name),'luatexlibs') or ""
+ if resolved ~= "" then
+ if trace_locating then
+ report_libraries("! lib '%s' located by basename via environment: '%s'",name,resolved)
+ end
+ return loadfile(resolved)
+ end
+ if trace_locating then
+ report_libraries('? unable to locate lib: %s',name)
end
+-- return "unable to locate " .. name
end
-package.loaders[2] = function(name)
- local thename = gsub(name,"%.","/")
- local luaname = file.addsuffix(thename,"lua")
- local libname = file.addsuffix(thename,os.libsuffix)
- return
- loadedbyformat(luaname,name,libsuffixes, false)
- or loadedbyformat(libname,name,clibsuffixes, true)
- or loadedbypath (luaname,name,getlibpaths (),false,"lua")
- or loadedbypath (luaname,name,getclibpaths(),false,"lua")
- or loadedbypath (libname,name,getclibpaths(),true, "lib")
- or loadedbylua (name)
- or notloaded (name)
-end
+resolvers.loadlualib = require
--- package.loaders[3] = nil
--- package.loaders[4] = nil
+-- -- -- --
-resolvers.loadlualib = require
+package.obsolete = package.obsolete or { }
+
+package.append_libpath = appendtolibpath -- will become obsolete
+package.prepend_libpath = prependtolibpath -- will become obsolete
+
+package.obsolete.append_libpath = appendtolibpath -- will become obsolete
+package.obsolete.prepend_libpath = prependtolibpath -- will become obsolete
end -- of closure
@@ -16616,6 +15707,7 @@ function environment.make_format(name)
end
function environment.run_format(name,data,more)
+ -- hm, rather old code here; we can now use the file.whatever functions
if name and name ~= "" then
local barename = file.removesuffix(name)
local fmtname = caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats")
@@ -16644,129 +15736,6 @@ function environment.run_format(name,data,more)
end
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-if not modules then modules = { } end modules ['util-tpl'] = {
- 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"
-}
-
--- This is experimental code. Coming from dos and windows, I've always used %whatever%
--- as template variables so let's stick to it. After all, it's easy to parse and stands
--- out well. A double %% is turned into a regular %.
-
-utilities.templates = utilities.templates or { }
-local templates = utilities.templates
-
-local trace_template = false trackers.register("templates.trace",function(v) trace_template = v end)
-local report_template = logs.reporter("template")
-
-local format = string.format
-local P, C, Cs, Carg, lpegmatch = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Carg, lpeg.match
-
--- todo: make installable template.new
-
-local replacer
-
-local function replacekey(k,t,recursive)
- local v = t[k]
- if not v then
- if trace_template then
- report_template("unknown key %q",k)
- end
- return ""
- else
- if trace_template then
- report_template("setting key %q to value %q",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t)
- else
- return v
- end
- end
-end
-
-local sqlescape = lpeg.replacer {
- { "'", "''" },
- { "\\", "\\\\" },
- { "\r\n", "\\n" },
- { "\r", "\\n" },
- -- { "\t", "\\t" },
-}
-
-local escapers = {
- lua = function(s)
- return format("%q",s)
- end,
- sql = function(s)
- return lpegmatch(sqlescape,s)
- end,
-}
-
-local function replacekeyunquoted(s,t,how,recurse) -- ".. \" "
- local escaper = how and escapers[how] or escapers.lua
- return escaper(replacekey(s,t,recurse))
-end
-
-local single = P("%") -- test %test% test : resolves test
-local double = P("%%") -- test 10%% test : %% becomes %
-local lquoted = P("%[") -- test %[test]" test : resolves test with escaped "'s
-local rquoted = P("]%") --
-
-local escape = double / '%%'
-local nosingle = single / ''
-local nodouble = double / ''
-local nolquoted = lquoted / ''
-local norquoted = rquoted / ''
-
-local key = nosingle * (C((1-nosingle)^1 * Carg(1) * Carg(2) * Carg(3))/replacekey) * nosingle
-local unquoted = nolquoted * ((C((1 - norquoted)^1) * Carg(1) * Carg(2) * Carg(3))/replacekeyunquoted) * norquoted
-local any = P(1)
-
- replacer = Cs((unquoted + escape + key + any)^0)
-
-local function replace(str,mapping,how,recurse)
- if mapping then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
-end
-
--- print(replace("test '%[x]%' test",{ x = [[a 'x' a]] }))
--- print(replace("test '%[x]%' test",{ x = [[a 'x' a]] },'sql'))
-
-templates.replace = replace
-
-function templates.load(filename,mapping,how,recurse)
- local data = io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
-end
-
-function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping = t
- end
- for k, v in next, t do
- t[k] = replace(v,mapping,how,recurse)
- end
- return t
-end
-
--- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" }))
--- inspect(utilities.templates.resolve({ one = "%two%", two = "two", three = "%three%" }))
-
-
end -- of closure
-- end library merge
@@ -16827,7 +15796,7 @@ own.libs = { -- order can be made better
-- 'data-bin.lua',
'data-zip.lua',
'data-tre.lua',
- 'data-sch.lua',
+ 'data-crl.lua',
'data-lua.lua',
'data-aux.lua', -- updater
'data-tmf.lua',
@@ -16835,8 +15804,6 @@ own.libs = { -- order can be made better
'luat-sta.lua',
'luat-fmt.lua',
-
- 'util-tpl.lua',
}
-- We need this hack till luatex is fixed.
@@ -16857,7 +15824,7 @@ own.path = gsub(match(own.name,"^(.+)[\\/].-$") or ".","\\","/")
local ownpath, owntree = own.path, environment and environment.ownpath or own.path
-own.list = { -- predictable paths
+own.list = {
'.',
ownpath ,
ownpath .. "/../sources", -- HH's development path
@@ -16881,7 +15848,7 @@ local function locate_libs()
local filename = pth .. "/" .. lib
local found = lfs.isfile(filename)
if found then
- package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require (probably obsolete)
+ package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require
return pth
end
end
@@ -17013,7 +15980,6 @@ local helpinfo = [[
--var-value report value of variable
--find-file report file location
--find-path report path of file
---show-package-path report package paths
--pattern=str filter variables
]]
@@ -17127,8 +16093,7 @@ function runners.execute_script(fullname,internal,nosplit)
elseif state == 'skip' then
return true
elseif state == "run" then
- local path, name, suffix = file.splitname(fullname)
- local result = ""
+ local path, name, suffix, result = file.dirname(fullname), file.basename(fullname), file.extname(fullname), ""
if path ~= "" then
result = fullname
elseif name then
@@ -17139,7 +16104,7 @@ function runners.execute_script(fullname,internal,nosplit)
name = gsub(name,"^script:","")
if suffix == "" and runners.registered[name] and runners.registered[name][1] then
name = runners.registered[name][1]
- suffix = file.suffix(name)
+ suffix = file.extname(name)
end
if suffix == "" then
-- loop over known suffixes
@@ -17166,7 +16131,7 @@ function runners.execute_script(fullname,internal,nosplit)
environment.ownscript = result
dofile(result)
else
- local binary = runners.applications[file.suffix(result)]
+ local binary = runners.applications[file.extname(result)]
result = string.quoted(string.unquoted(result))
-- if string.match(result,' ') and not string.match(result,"^\".*\"$") then
-- result = '"' .. result .. '"'
@@ -17359,7 +16324,7 @@ function resolvers.launch(str)
-- maybe we also need to test on mtxrun.launcher.suffix environment
-- variable or on windows consult the assoc and ftype vars and such
local launchers = runners.launchers[os.platform] if launchers then
- local suffix = file.suffix(str) if suffix then
+ local suffix = file.extname(str) if suffix then
local runner = launchers[suffix] if runner then
str = runner .. " " .. str
end
@@ -17418,7 +16383,7 @@ function runners.find_mtx_script(filename)
end
filename = file.addsuffix(filename,"lua")
local basename = file.removesuffix(file.basename(filename))
- local suffix = file.suffix(filename)
+ local suffix = file.extname(filename)
-- qualified path, raw name
local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename
if fullname and fullname ~= "" then
@@ -17473,7 +16438,7 @@ function runners.execute_ctx_script(filename,...)
runners.register_arguments(...)
local arguments = environment.arguments_after
local fullname = runners.find_mtx_script(filename) or ""
- if file.suffix(fullname) == "cld" then
+ if file.extname(fullname) == "cld" then
-- handy in editors where we force --autopdf
report("running cld script: %s",filename)
table.insert(arguments,1,fullname)
@@ -17581,21 +16546,6 @@ function runners.timed(action)
statistics.timed(action)
end
-function runners.associate(filename)
- os.launch(filename)
-end
-
-function runners.gethelp(filename)
- local url = environment.argument("url")
- if url and url ~= "" then
- local command = string.gsub(environment.argument("command") or "unknown","^%s*\\*(.-)%s*$","%1")
- url = utilities.templates.replace(url,{ command = command })
- os.launch(url)
- else
- report("no --url given")
- end
-end
-
-- this is a bit dirty ... first we store the first filename and next we
-- split the arguments so that we only see the ones meant for this script
-- ... later we will use the second half
@@ -17698,18 +16648,7 @@ else
end
-if e_argument("script") or e_argument("scripts") then
-
- -- run a script by loading it (using libs), pass args
-
- runners.loadbase()
- if is_mkii_stub then
- ok = runners.execute_script(filename,false,true)
- else
- ok = runners.execute_ctx_script(filename)
- end
-
-elseif e_argument("selfmerge") then
+if e_argument("selfmerge") then
-- embed used libraries
@@ -17732,19 +16671,6 @@ elseif e_argument("selfupdate") then
trackers.enable("resolvers.locating")
resolvers.updatescript(own.name,"mtxrun")
-elseif e_argument("show-package-path") or e_argument("show-package-paths") then
-
- local l = package.libpaths()
- local c = package.clibpaths()
-
- for i=1,#l do
- report("package lib path %s: %s",i,l[i])
- end
-
- for i=1,#c do
- report("package clib path %s: %s",i,c[i])
- end
-
elseif e_argument("ctxlua") or e_argument("internal") then
-- run a script by loading it (using libs)
@@ -17752,6 +16678,17 @@ elseif e_argument("ctxlua") or e_argument("internal") then
runners.loadbase()
ok = runners.execute_script(filename,true)
+elseif e_argument("script") or e_argument("scripts") then
+
+ -- run a script by loading it (using libs), pass args
+
+ runners.loadbase()
+ if is_mkii_stub then
+ ok = runners.execute_script(filename,false,true)
+ else
+ ok = runners.execute_ctx_script(filename)
+ end
+
elseif e_argument("execute") then
-- execute script
@@ -17778,14 +16715,6 @@ elseif e_argument("launch") then
runners.loadbase()
runners.launch_file(filename)
-elseif e_argument("associate") then
-
- runners.associate(filename)
-
-elseif e_argument("gethelp") then
-
- runners.gethelp()
-
elseif e_argument("makestubs") then
-- make stubs (depricated)
@@ -17877,7 +16806,7 @@ elseif e_argument("find-path") then
elseif e_argument("expand-braces") then
- -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename)
+ -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename
resolvers.load("nofiles")
runners.register_arguments(filename)
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index e6bbbe2b5..108f2a8a1 100644
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -8,11 +8,6 @@ if not modules then modules = { } end modules ['mtxrun'] = {
license = "see context related readme files"
}
--- if not lpeg then require("lpeg") end
--- if not md5 then require("md5") end
--- if not lfs then require("lfs") end
--- if not texconfig then texconfig = { } end
-
-- one can make a stub:
--
-- #!/bin/sh
@@ -155,28 +150,11 @@ function string.topattern(str,lowercase,strict)
end
end
-
-function string.valid(str,default)
- return (type(str) == "string" and str ~= "" and str) or default or nil
-end
-
-- obsolete names:
string.quote = string.quoted
string.unquote = string.unquoted
--- handy fallback
-
-string.itself = function(s) return s end
-
--- also handy (see utf variant)
-
-local pattern = Ct(C(1)^0)
-
-function string.totable(str)
- return lpegmatch(pattern,str)
-end
-
end -- of closure
@@ -190,8 +168,7 @@ if not modules then modules = { } end modules ['l-table'] = {
license = "see context related readme files"
}
-local type, next, tostring, tonumber, ipairs = type, next, tostring, tonumber, ipairs
-local table, string = table, string
+local type, next, tostring, tonumber, ipairs, table, string = type, next, tostring, tonumber, ipairs, table, string
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
@@ -202,8 +179,6 @@ local getinfo = debug.getinfo
-- impact on ConTeXt was not that large; the remaining ipairs already
-- have been replaced. In a similar fashion we also hardly used pairs.
--
--- Hm, actually ipairs was retained, but we no longer use it anyway.
---
-- Just in case, we provide the fallbacks as discussed in Programming
-- in Lua (http://www.lua.org/pil/7.3.html):
@@ -263,16 +238,12 @@ function table.strip(tab)
end
function table.keys(t)
- if t then
- local keys, k = { }, 0
- for key, _ in next, t do
- k = k + 1
- keys[k] = key
- end
- return keys
- else
- return { }
+ local keys, k = { }, 0
+ for key, _ in next, t do
+ k = k + 1
+ keys[k] = key
end
+ return keys
end
local function compare(a,b)
@@ -285,49 +256,41 @@ local function compare(a,b)
end
local function sortedkeys(tab)
- if tab then
- local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
- for key,_ in next, tab do
- s = s + 1
- srt[s] = key
- if category == 3 then
- -- no further check
+ local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed
+ for key,_ in next, tab do
+ s = s + 1
+ srt[s] = key
+ if category == 3 then
+ -- no further check
+ else
+ local tkey = type(key)
+ if tkey == "string" then
+ category = (category == 2 and 3) or 1
+ elseif tkey == "number" then
+ category = (category == 1 and 3) or 2
else
- local tkey = type(key)
- if tkey == "string" then
- category = (category == 2 and 3) or 1
- elseif tkey == "number" then
- category = (category == 1 and 3) or 2
- else
- category = 3
- end
+ category = 3
end
end
- if category == 0 or category == 3 then
- sort(srt,compare)
- else
- sort(srt)
- end
- return srt
+ end
+ if category == 0 or category == 3 then
+ sort(srt,compare)
else
- return { }
+ sort(srt)
end
+ return srt
end
local function sortedhashkeys(tab) -- fast one
- if tab then
- local srt, s = { }, 0
- for key,_ in next, tab do
- if key then
- s= s + 1
- srt[s] = key
- end
+ local srt, s = { }, 0
+ for key,_ in next, tab do
+ if key then
+ s= s + 1
+ srt[s] = key
end
- sort(srt)
- return srt
- else
- return { }
end
+ sort(srt)
+ return srt
end
table.sortedkeys = sortedkeys
@@ -352,7 +315,7 @@ end
table.sortedhash = sortedhash
table.sortedpairs = sortedhash
-function table.append(t,list)
+function table.append(t, list)
local n = #t
for i=1,#list do
n = n + 1
@@ -587,26 +550,12 @@ local function do_serialize(root,name,depth,level,indexed)
end
-- we could check for k (index) being number (cardinal)
if root and next(root) then
- -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
- -- if compact then
- -- -- NOT: for k=1,#root do (we need to quit at nil)
- -- for k,v in ipairs(root) do -- can we use next?
- -- if not first then first = k end
- -- last = last + 1
- -- end
- -- end
- local first, last = nil, 0
+ local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
if compact then
- last = #root
- for k=1,last do
--- if not root[k] then
- if root[k] == nil then
- last = k - 1
- break
- end
- end
- if last > 0 then
- first = 1
+ -- NOT: for k=1,#root do (we need to quit at nil)
+ for k,v in ipairs(root) do -- can we use next?
+ if not first then first = k end
+ last = last + 1
end
end
local sk = sortedkeys(root)
@@ -1078,27 +1027,23 @@ function table.reversed(t)
end
end
-function table.sequenced(t,sep) -- hash only
- if t then
- local s, n = { }, 0
- for k, v in sortedhash(t) do
- if simple then
- if v == true then
- n = n + 1
- s[n] = k
- elseif v and v~= "" then
- n = n + 1
- s[n] = k .. "=" .. tostring(v)
- end
- else
+function table.sequenced(t,sep,simple) -- hash only
+ local s, n = { }, 0
+ for k, v in sortedhash(t) do
+ if simple then
+ if v == true then
+ n = n + 1
+ s[n] = k
+ elseif v and v~= "" then
n = n + 1
s[n] = k .. "=" .. tostring(v)
end
+ else
+ n = n + 1
+ s[n] = k .. "=" .. tostring(v)
end
- return concat(s, sep or " | ")
- else
- return ""
end
+ return concat(s, sep or " | ")
end
function table.print(t,...)
@@ -1179,8 +1124,6 @@ local lpeg = require("lpeg")
-- tracing (only used when we encounter a problem in integration of lpeg in luatex)
--- some code will move to unicode and string
-
local report = texio and texio.write_nl or print
-- local lpmatch = lpeg.match
@@ -1217,8 +1160,8 @@ local report = texio and texio.write_nl or print
-- function lpeg.Cmt (l) local p = lpcmt (l) report("LPEG Cmt =") lpprint(l) return p end
-- function lpeg.Carg (l) local p = lpcarg(l) report("LPEG Carg =") lpprint(l) return p end
-local type, next = type, next
-local byte, char, gmatch, format = string.byte, string.char, string.gmatch, string.format
+local type = type
+local byte, char, gmatch = string.byte, string.char, string.gmatch
-- Beware, we predefine a bunch of patterns here and one reason for doing so
-- is that we get consistent behaviour in some of the visualizers.
@@ -1226,8 +1169,9 @@ local byte, char, gmatch, format = string.byte, string.char, string.gmatch, stri
lpeg.patterns = lpeg.patterns or { } -- so that we can share
local patterns = lpeg.patterns
-local P, R, S, V, Ct, C, Cs, Cc, Cp = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Cp
-local lpegtype, lpegmatch = lpeg.type, lpeg.match
+local P, R, S, V, match = lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.match
+local Ct, C, Cs, Cc = lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local lpegtype = lpeg.type
local utfcharacters = string.utfcharacters
local utfgmatch = unicode and unicode.utf8.gmatch
@@ -1278,10 +1222,6 @@ patterns.utf8char = utf8char
patterns.validutf8 = validutf8char
patterns.validutf8char = validutf8char
-local eol = S("\n\r")
-local spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
-local whitespace = eol + spacer
-
patterns.digit = digit
patterns.sign = sign
patterns.cardinal = sign^0 * digit^1
@@ -1301,16 +1241,16 @@ patterns.letter = patterns.lowercase + patterns.uppercase
patterns.space = space
patterns.tab = P("\t")
patterns.spaceortab = patterns.space + patterns.tab
-patterns.eol = eol
-patterns.spacer = spacer
-patterns.whitespace = whitespace
+patterns.eol = S("\n\r")
+patterns.spacer = S(" \t\f\v") -- + char(0xc2, 0xa0) if we want utf (cf mail roberto)
patterns.newline = newline
patterns.emptyline = newline^1
-patterns.nonspacer = 1 - spacer
-patterns.nonwhitespace = 1 - whitespace
+patterns.nonspacer = 1 - patterns.spacer
+patterns.whitespace = patterns.eol + patterns.spacer
+patterns.nonwhitespace = 1 - patterns.whitespace
patterns.equal = P("=")
patterns.comma = P(",")
-patterns.commaspacer = P(",") * spacer^0
+patterns.commaspacer = P(",") * patterns.spacer^0
patterns.period = P(".")
patterns.colon = P(":")
patterns.semicolon = P(";")
@@ -1325,10 +1265,6 @@ patterns.undouble = (dquote/"") * patterns.nodquote * (dquote/"")
patterns.unquoted = patterns.undouble + patterns.unsingle -- more often undouble
patterns.unspacer = ((patterns.spacer^1)/"")^0
-patterns.singlequoted = squote * patterns.nosquote * squote
-patterns.doublequoted = dquote * patterns.nodquote * dquote
-patterns.quoted = patterns.doublequoted + patterns.singlequoted
-
patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
patterns.beginline = #(1-newline)
@@ -1339,17 +1275,8 @@ patterns.beginline = #(1-newline)
-- print(string.unquoted('"test"'))
-- print(string.unquoted('"test"'))
-local function anywhere(pattern) --slightly adapted from website
- return P { P(pattern) + 1 * V(1) }
-end
-
-lpeg.anywhere = anywhere
-
-function lpeg.instringchecker(p)
- p = anywhere(p)
- return function(str)
- return lpegmatch(p,str) and true or false
- end
+function lpeg.anywhere(pattern) --slightly adapted from website
+ return P { P(pattern) + 1 * V(1) } -- why so complex?
end
function lpeg.splitter(pattern, action)
@@ -1398,7 +1325,7 @@ function string.splitup(str,separator)
if not separator then
separator = ","
end
- return lpegmatch(splitters_m[separator] or splitat(separator),str)
+ return match(splitters_m[separator] or splitat(separator),str)
end
@@ -1410,20 +1337,16 @@ function lpeg.split(separator,str)
c = tsplitat(separator)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
function string.split(str,separator)
- if separator then
- local c = cache[separator]
- if not c then
- c = tsplitat(separator)
- cache[separator] = c
- end
- return lpegmatch(c,str)
- else
- return { str }
+ local c = cache[separator]
+ if not c then
+ c = tsplitat(separator)
+ cache[separator] = c
end
+ return match(c,str)
end
local spacing = patterns.spacer^0 * newline -- sort of strip
@@ -1439,7 +1362,7 @@ local linesplitter = tsplitat(newline)
patterns.linesplitter = linesplitter
function string.splitlines(str)
- return lpegmatch(linesplitter,str)
+ return match(linesplitter,str)
end
local utflinesplitter = utfbom^-1 * tsplitat(newline)
@@ -1447,58 +1370,7 @@ local utflinesplitter = utfbom^-1 * tsplitat(newline)
patterns.utflinesplitter = utflinesplitter
function string.utfsplitlines(str)
- return lpegmatch(utflinesplitter,str or "")
-end
-
-local utfcharsplitter_ows = utfbom^-1 * Ct(C(utf8char)^0)
-local utfcharsplitter_iws = utfbom^-1 * Ct((whitespace^1 + C(utf8char))^0)
-
-function string.utfsplit(str,ignorewhitespace) -- new
- if ignorewhitespace then
- return lpegmatch(utfcharsplitter_iws,str or "")
- else
- return lpegmatch(utfcharsplitter_ows,str or "")
- end
-end
-
--- inspect(string.utfsplit("a b c d"))
--- inspect(string.utfsplit("a b c d",true))
-
--- -- alternative 1: 0.77
---
--- local utfcharcounter = utfbom^-1 * Cs((utf8char/'!')^0)
---
--- function string.utflength(str)
--- return #lpegmatch(utfcharcounter,str or "")
--- end
---
--- -- alternative 2: 1.70
---
--- local n = 0
---
--- local utfcharcounter = utfbom^-1 * (utf8char/function() n = n + 1 end)^0 -- slow
---
--- function string.utflength(str)
--- n = 0
--- lpegmatch(utfcharcounter,str or "")
--- return n
--- end
---
--- -- alternative 3: 0.24 (native unicode.utf8.len: 0.047)
-
-local n = 0
-
-local utfcharcounter = utfbom^-1 * Cs ( (
- Cp() * (lpeg.patterns.utf8one )^1 * Cp() / function(f,t) n = n + t - f end
- + Cp() * (lpeg.patterns.utf8two )^1 * Cp() / function(f,t) n = n + (t - f)/2 end
- + Cp() * (lpeg.patterns.utf8three)^1 * Cp() / function(f,t) n = n + (t - f)/3 end
- + Cp() * (lpeg.patterns.utf8four )^1 * Cp() / function(f,t) n = n + (t - f)/4 end
-)^0 )
-
-function string.utflength(str)
- n = 0
- lpegmatch(utfcharcounter,str or "")
- return n
+ return match(utflinesplitter,str or "")
end
@@ -1512,7 +1384,7 @@ function lpeg.checkedsplit(separator,str)
c = Ct(separator^0 * other * (separator^1 * other)^0)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
function string.checkedsplit(str,separator)
@@ -1523,7 +1395,7 @@ function string.checkedsplit(str,separator)
c = Ct(separator^0 * other * (separator^1 * other)^0)
cache[separator] = c
end
- return lpegmatch(c,str)
+ return match(c,str)
end
@@ -1568,11 +1440,11 @@ function lpeg.keeper(str)
end
function lpeg.frontstripper(str) -- or pattern (yet undocumented)
- return (P(str) + P(true)) * Cs(anything^0)
+ return (P(str) + P(true)) * Cs(P(1)^0)
end
function lpeg.endstripper(str) -- or pattern (yet undocumented)
- return Cs((1 - P(str) * endofstring)^0)
+ return Cs((1 - P(str) * P(-1))^0)
end
-- Just for fun I looked at the used bytecode and
@@ -1581,22 +1453,8 @@ end
function lpeg.replacer(one,two)
if type(one) == "table" then
local no = #one
- local p
- if no == 0 then
- for k, v in next, one do
- local pp = P(k) / v
- if p then
- p = p + pp
- else
- p = pp
- end
- end
- return Cs((p + 1)^0)
- elseif no == 1 then
- local o = one[1]
- one, two = P(o[1]), o[2]
- return Cs(((1-one)^1 + one/two)^0)
- else
+ if no > 0 then
+ local p
for i=1,no do
local o = one[i]
local pp = P(o[1]) / o[2]
@@ -1609,16 +1467,11 @@ function lpeg.replacer(one,two)
return Cs((p + 1)^0)
end
else
- one = P(one)
two = two or ""
- return Cs(((1-one)^1 + one/two)^0)
+ return Cs((P(one)/two + 1)^0)
end
end
--- print(lpeg.match(lpeg.replacer("e","a"),"test test"))
--- print(lpeg.match(lpeg.replacer{{"e","a"}},"test test"))
--- print(lpeg.match(lpeg.replacer({ e = "a", t = "x" }),"test test"))
-
local splitters_f, splitters_s = { }, { }
function lpeg.firstofsplit(separator) -- always return value
@@ -1653,7 +1506,7 @@ local nany = utf8char/""
function lpeg.counter(pattern)
pattern = Cs((P(pattern)/" " + nany)^0)
return function(str)
- return #lpegmatch(pattern,str)
+ return #match(pattern,str)
end
end
@@ -1667,7 +1520,7 @@ if utfgmatch then
end
return n
else -- 4 times slower but still faster than / function
- return #lpegmatch(Cs((P(what)/" " + nany)^0),str)
+ return #match(Cs((P(what)/" " + nany)^0),str)
end
end
@@ -1682,9 +1535,9 @@ else
p = Cs((P(what)/" " + nany)^0)
cache[p] = p
end
- return #lpegmatch(p,str)
+ return #match(p,str)
else -- 4 times slower but still faster than / function
- return #lpegmatch(Cs((P(what)/" " + nany)^0),str)
+ return #match(Cs((P(what)/" " + nany)^0),str)
end
end
@@ -1711,7 +1564,7 @@ local p = Cs((S("-.+*%()[]") / patterns_escapes + anything)^0)
local s = Cs((S("-.+*%()[]") / simple_escapes + anything)^0)
function string.escapedpattern(str,simple)
- return lpegmatch(simple and s or p,str)
+ return match(simple and s or p,str)
end
-- utf extensies
@@ -1758,7 +1611,7 @@ else
p = P(uc)
end
end
- lpegmatch((utf8char/f)^0,str)
+ match((utf8char/f)^0,str)
return p
end
@@ -1774,7 +1627,7 @@ function lpeg.UR(str,more)
first = str
last = more or first
else
- first, last = lpegmatch(range,str)
+ first, last = match(range,str)
if not last then
return P(str)
end
@@ -1801,15 +1654,11 @@ end
-function lpeg.is_lpeg(p)
- return p and lpegtype(p) == "pattern"
-end
-
-function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assume proper order
+function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then")
if type(list) ~= "table" then
list = { list, ... }
end
- -- table.sort(list) -- longest match first
+ -- sort(list) -- longest match first
local p = P(list[1])
for l=2,#list do
p = p + P(list[l])
@@ -1817,6 +1666,10 @@ function lpeg.oneof(list,...) -- lpeg.oneof("elseif","else","if","then") -- assu
return p
end
+function lpeg.is_lpeg(p)
+ return p and lpegtype(p) == "pattern"
+end
+
-- For the moment here, but it might move to utilities. Beware, we need to
-- have the longest keyword first, so 'aaa' comes beforte 'aa' which is why we
-- loop back from the end cq. prepend.
@@ -1974,24 +1827,6 @@ end
-- utfchar(0x205F), -- math thinspace
-- } )
--- handy from within tex:
-
-local lpegmatch = lpeg.match
-
-local replacer = lpeg.replacer("@","%%") -- Watch the escaped % in lpeg!
-
-function string.tformat(fmt,...)
- return format(lpegmatch(replacer,fmt),...)
-end
-
--- strips leading and trailing spaces and collapsed all other spaces
-
-local pattern = Cs(whitespace^0/"" * ((whitespace^1 * P(-1) / "") + (whitespace^1/" ") + P(1))^0)
-
-function string.collapsespaces(str)
- return lpegmatch(pattern,str)
-end
-
end -- of closure
@@ -2016,14 +1851,14 @@ else
io.fileseparator, io.pathseparator = "/" , ":"
end
-function io.loaddata(filename,textmode) -- return nil if empty
+function io.loaddata(filename,textmode)
local f = io.open(filename,(textmode and 'r') or 'rb')
if f then
local data = f:read('*all')
f:close()
- if #data > 0 then
- return data
- end
+ return data
+ else
+ return nil
end
end
@@ -2045,45 +1880,6 @@ function io.savedata(filename,data,joiner)
end
end
-function io.loadlines(filename,n) -- return nil if empty
- local f = io.open(filename,'r')
- if f then
- if n then
- local lines = { }
- for i=1,n do
- local line = f:read("*lines")
- if line then
- lines[#lines+1] = line
- else
- break
- end
- end
- f:close()
- lines = concat(lines,"\n")
- if #lines > 0 then
- return lines
- end
- else
- local line = f:read("*line") or ""
- assert(f:close())
- if #line > 0 then
- return line
- end
- end
- end
-end
-
-function io.loadchunk(filename,n)
- local f = io.open(filename,'rb')
- if f then
- local data = f:read(n or 1024)
- f:close()
- if #data > 0 then
- return data
- end
- end
-end
-
function io.exists(filename)
local f = io.open(filename)
if f == nil then
@@ -2311,7 +2107,7 @@ if not modules then modules = { } end modules ['l-number'] = {
-- this module will be replaced when we have the bit library
-local tostring, tonumber = tostring, tonumber
+local tostring = tostring
local format, floor, match, rep = string.format, math.floor, string.match, string.rep
local concat, insert = table.concat, table.insert
local lpegmatch = lpeg.match
@@ -2374,11 +2170,11 @@ function number.hasbit(x, p) -- typical call: if hasbit(x, bit(3)) then ...
end
function number.setbit(x, p)
- return (x % (p + p) >= p) and x or x + p
+ return hasbit(x, p) and x or x + p
end
function number.clearbit(x, p)
- return (x % (p + p) >= p) and x - p or x
+ return hasbit(x, p) and x - p or x
end
@@ -2412,10 +2208,6 @@ function number.tobitstring(n,m)
end
-function number.valid(str,default)
- return tonumber(str) or default or nil
-end
-
end -- of closure
@@ -2527,28 +2319,17 @@ if not modules then modules = { } end modules ['l-os'] = {
-- os.name : windows | msdos | linux | macosx | solaris | .. | generic (new)
-- os.platform : extended os.name with architecture
--- os.sleep() => socket.sleep()
--- math.randomseed(tonumber(string.sub(string.reverse(tostring(math.floor(socket.gettime()*10000))),1,6)))
-
-- maybe build io.flush in os.execute
local os = os
-local date, time = os.date, os.time
local find, format, gsub, upper, gmatch = string.find, string.format, string.gsub, string.upper, string.gmatch
local concat = table.concat
-local random, ceil, randomseed = math.random, math.ceil, math.randomseed
-local rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring = rawget, rawset, type, getmetatable, setmetatable, tonumber, tostring
+local random, ceil = math.random, math.ceil
+local rawget, rawset, type, getmetatable, setmetatable, tonumber = rawget, rawset, type, getmetatable, setmetatable, tonumber
-- The following code permits traversing the environment table, at least
-- in luatex. Internally all environment names are uppercase.
--- The randomseed in Lua is not that random, although this depends on the operating system as well
--- as the binary (Luatex is normally okay). But to be sure we set the seed anyway.
-
-math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6))
-
-randomseed(math.initialseed)
-
if not os.__getenv__ then
os.__getenv__ = os.getenv
@@ -2652,14 +2433,12 @@ else
os.libsuffix, os.binsuffix, os.binsuffixes = 'so', '', { '' }
end
-local launchers = {
- windows = "start %s",
- macosx = "open %s",
- unix = "$BROWSER %s &> /dev/null &",
-}
-
function os.launch(str)
- os.execute(format(launchers[os.name] or launchers.unix,str))
+ if os.type == "windows" then
+ os.execute("start " .. str) -- os.spawn ?
+ else
+ os.execute(str .. " &") -- os.spawn ?
+ end
end
if not os.times then
@@ -2870,7 +2649,7 @@ end
local d
function os.timezone(delta)
- d = d or tonumber(tonumber(date("%H")-date("!%H")))
+ d = d or tonumber(tonumber(os.date("%H")-os.date("!%H")))
if delta then
if d > 0 then
return format("+%02i:00",d)
@@ -2882,44 +2661,6 @@ function os.timezone(delta)
end
end
-local timeformat = format("%%s%s",os.timezone(true))
-local dateformat = "!%Y-%m-%d %H:%M:%S"
-
-function os.fulltime(t,default)
- t = tonumber(t) or 0
- if t > 0 then
- -- valid time
- elseif default then
- return default
- else
- t = nil
- end
- return format(timeformat,date(dateformat,t))
-end
-
-local dateformat = "%Y-%m-%d %H:%M:%S"
-
-function os.localtime(t,default)
- t = tonumber(t) or 0
- if t > 0 then
- -- valid time
- elseif default then
- return default
- else
- t = nil
- end
- return date(dateformat,t)
-end
-
-function os.converttime(t,default)
- local t = tonumber(t)
- if t and t > 0 then
- return date(dateformat,t)
- else
- return default or "-"
- end
-end
-
local memory = { }
local function which(filename)
@@ -2994,7 +2735,7 @@ local function nameonly(name)
return (gsub(match(name,"^.+[/\\](.-)$") or name,"%.[%a%d]+$",""))
end
-local function suffixonly(name,default)
+local function extname(name,default)
return match(name,"^.+%.([^/\\]-)$") or default or ""
end
@@ -3003,16 +2744,11 @@ local function splitname(name)
return n or name, s or ""
end
-file.basename = basename
-
-file.pathpart = dirname
-file.dirname = dirname
-
-file.nameonly = nameonly
-
-file.suffixonly = suffixonly
-file.extname = suffixonly -- obsolete
-file.suffix = suffixonly
+file.basename = basename
+file.dirname = dirname
+file.nameonly = nameonly
+file.extname = extname
+file.suffix = extname
function file.removesuffix(filename)
return (gsub(filename,"%.[%a%d]+$",""))
@@ -3128,11 +2864,6 @@ end
file.isreadable = file.is_readable -- depricated
file.iswritable = file.is_writable -- depricated
-function file.size(name)
- local a = attributes(name)
- return a and a.size or 0
-end
-
-- todo: lpeg \\ / .. does not save much
local checkedsplit = string.checkedsplit
@@ -3270,7 +3001,6 @@ local drive = C(R("az","AZ")) * P(":")
local path = C(((1-slash)^0 * slash)^0)
local suffix = period * C(P(1-period)^0 * P(-1))
local base = C((1-suffix)^0)
-local rest = C(P(1)^0)
drive = drive + Cc("")
path = path + Cc("")
@@ -3279,8 +3009,7 @@ suffix = suffix + Cc("")
local pattern_a = drive * path * base * suffix
local pattern_b = path * base * suffix
-local pattern_c = C(drive * path) * C(base * suffix) -- trick: two extra captures
-local pattern_d = path * rest
+local pattern_c = C(drive * path) * C(base * suffix)
function file.splitname(str,splitdrive)
if splitdrive then
@@ -3290,10 +3019,6 @@ function file.splitname(str,splitdrive)
end
end
-function file.splitbase(str)
- return lpegmatch(pattern_d,str) -- returns path, base+suffix
-end
-
function file.nametotable(str,splitdrive) -- returns table
local path, drive, subpath, name, base, suffix = lpegmatch(pattern_c,str)
if splitdrive then
@@ -3315,8 +3040,6 @@ function file.nametotable(str,splitdrive) -- returns table
end
end
--- print(file.splitbase("a/b/c.txt"))
-
-- function test(t) for k, v in next, t do print(v, "=>", file.splitname(v)) end end
--
-- test { "c:", "c:/aa", "c:/aa/bb", "c:/aa/bb/cc", "c:/aa/bb/cc.dd", "c:/aa/bb/cc.dd.ee" }
@@ -3358,30 +3081,15 @@ if not md5.hex then function md5.hex(str) return convert(str,"%02x") end end
if not md5.dec then function md5.dec(str) return convert(str,"%03i") end end
-function file.needsupdating(oldname,newname,threshold) -- size modification access change
- local oldtime = lfs.attributes(oldname,"modification")
- if oldtime then
- local newtime = lfs.attributes(newname,"modification")
- if not newtime then
- return true -- no new file, so no updating needed
- elseif newtime >= oldtime then
- return false -- new file definitely needs updating
- elseif oldtime - newtime < (threshold or 1) then
- return false -- new file is probably still okay
- else
- return true -- new file has to be updated
- end
+function file.needs_updating(oldname,newname,threshold) -- size modification access change
+ local oldtime = lfs.attributes(oldname, modification)
+ local newtime = lfs.attributes(newname, modification)
+ if newtime >= oldtime then
+ return false
+ elseif oldtime - newtime < (threshold or 1) then
+ return false
else
- return false -- no old file, so no updating needed
- end
-end
-
-file.needs_updating = file.needsupdating
-
-function file.syncmtimes(oldname,newname)
- local oldtime = lfs.attributes(oldname,"modification")
- if oldtime and lfs.isfile(newname) then
- lfs.touch(newname,oldtime,oldtime)
+ return true
end
end
@@ -3403,7 +3111,7 @@ function file.loadchecksum(name)
return nil
end
-function file.savechecksum(name,checksum)
+function file.savechecksum(name, checksum)
if not checksum then checksum = file.checksum(name) end
if checksum then
io.savedata(name .. ".md5",checksum)
@@ -3428,7 +3136,7 @@ if not modules then modules = { } end modules ['l-url'] = {
local char, gmatch, gsub, format, byte, find = string.char, string.gmatch, string.gsub, string.format, string.byte, string.find
local concat = table.concat
local tonumber, type = tonumber, type
-local P, C, R, S, Cs, Cc, Ct, Cf, Cg, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Cf, lpeg.Cg, lpeg.V
+local P, C, R, S, Cs, Cc, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cs, lpeg.Cc, lpeg.Ct
local lpegmatch, lpegpatterns, replacer = lpeg.match, lpeg.patterns, lpeg.replacer
-- from wikipedia:
@@ -3461,19 +3169,15 @@ local endofstring = P(-1)
local hexdigit = R("09","AF","af")
local plus = P("+")
local nothing = Cc("")
-local escapedchar = (percent * C(hexdigit * hexdigit)) / tochar
-local escaped = (plus / " ") + escapedchar
+local escaped = (plus / " ") + (percent * C(hexdigit * hexdigit) / tochar)
-- we assume schemes with more than 1 character (in order to avoid problems with windows disks)
-- we also assume that when we have a scheme, we also have an authority
---
--- maybe we should already split the query (better for unescaping as = & can be part of a value
local schemestr = Cs((escaped+(1-colon-slash-qmark-hash))^2)
local authoritystr = Cs((escaped+(1- slash-qmark-hash))^0)
local pathstr = Cs((escaped+(1- qmark-hash))^0)
------ querystr = Cs((escaped+(1- hash))^0)
-local querystr = Cs(( (1- hash))^0)
+local querystr = Cs((escaped+(1- hash))^0)
local fragmentstr = Cs((escaped+(1- endofstring))^0)
local scheme = schemestr * colon + nothing
@@ -3488,20 +3192,11 @@ local parser = Ct(validurl)
lpegpatterns.url = validurl
lpegpatterns.urlsplitter = parser
-local escapes = { }
+local escapes = { } ; for i=0,255 do escapes[i] = format("%%%02X",i) end
-setmetatable(escapes, { __index = function(t,k)
- local v = format("%%%02X",byte(k))
- t[k] = v
- return v
-end })
+local escaper = Cs((R("09","AZ","az") + S("-./_") + P(1) / escapes)^0)
-local escaper = Cs((R("09","AZ","az")^1 + P(" ")/"%%20" + S("-./_")^1 + P(1) / escapes)^0) -- space happens most
-local unescaper = Cs((escapedchar + 1)^0)
-
-lpegpatterns.urlunescaped = escapedchar
-lpegpatterns.urlescaper = escaper
-lpegpatterns.urlunescaper = unescaper
+lpegpatterns.urlescaper = escaper
-- todo: reconsider Ct as we can as well have five return values (saves a table)
-- so we can have two parsers, one with and one without
@@ -3513,12 +3208,8 @@ end
local isscheme = schemestr * colon * slash * slash -- this test also assumes authority
local function hasscheme(str)
- if str then
- local scheme = lpegmatch(isscheme,str) -- at least one character
- return scheme ~= "" and scheme or false
- else
- return false
- end
+ local scheme = lpegmatch(isscheme,str) -- at least one character
+ return scheme ~= "" and scheme or false
end
@@ -3537,32 +3228,10 @@ local rootbased = P("/")
local barswapper = replacer("|",":")
local backslashswapper = replacer("\\","/")
--- queries:
-
-local equal = P("=")
-local amp = P("&")
-local key = Cs(((escapedchar+1)-equal )^0)
-local value = Cs(((escapedchar+1)-amp -endofstring)^0)
-
-local splitquery = Cf ( Ct("") * P { "sequence",
- sequence = V("pair") * (amp * V("pair"))^0,
- pair = Cg(key * equal * value),
-}, rawset)
-
--- hasher
-
local function hashed(str) -- not yet ok (/test?test)
- if str == "" then
- return {
- scheme = "invalid",
- original = str,
- }
- end
local s = split(str)
- local rawscheme = s[1]
- local rawquery = s[4]
- local somescheme = rawscheme ~= ""
- local somequery = rawquery ~= ""
+ local somescheme = s[1] ~= ""
+ local somequery = s[4] ~= ""
if not somescheme and not somequery then
s = {
scheme = "file",
@@ -3578,17 +3247,14 @@ local function hashed(str) -- not yet ok (/test?test)
local authority, path, filename = s[2], s[3]
if authority == "" then
filename = path
- elseif path == "" then
- filename = ""
else
filename = authority .. "/" .. path
end
s = {
- scheme = rawscheme,
+ scheme = s[1],
authority = authority,
path = path,
- query = lpegmatch(unescaper,rawquery), -- unescaped, but possible conflict with & and =
- queries = lpegmatch(splitquery,rawquery), -- split first and then unescaped
+ query = s[4],
fragment = s[5],
original = str,
noscheme = false,
@@ -3598,8 +3264,6 @@ local function hashed(str) -- not yet ok (/test?test)
return s
end
--- inspect(hashed("template://test"))
-
-- Here we assume:
--
-- files: /// = relative
@@ -3642,61 +3306,20 @@ function url.construct(hash) -- dodo: we need to escape !
return lpegmatch(escaper,concat(fullurl))
end
-function url.filename(filename) -- why no lpeg here ?
+function url.filename(filename)
local t = hashed(filename)
return (t.scheme == "file" and (gsub(t.path,"^/([a-zA-Z])([:|])/)","%1:"))) or filename
end
-local function escapestring(str)
- return lpegmatch(escaper,str)
-end
-
-url.escape = escapestring
-
--- function url.query(str) -- separator could be an option
--- if type(str) == "string" then
--- local t = { }
--- for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
--- t[k] = v
--- end
--- return t
--- else
--- return str
--- end
--- end
-
function url.query(str)
if type(str) == "string" then
- return lpegmatch(splitquery,str) or ""
- else
- return str
- end
-end
-
-function url.toquery(data)
- local td = type(data)
- if td == "string" then
- return #str and escape(data) or nil -- beware of double escaping
- elseif td == "table" then
- if next(data) then
- local t = { }
- for k, v in next, data do
- t[#t+1] = format("%s=%s",k,escapestring(v))
- end
- return concat(t,"&")
+ local t = { }
+ for k, v in gmatch(str,"([^&=]*)=([^&=]*)") do
+ t[k] = v
end
+ return t
else
- -- nil is a signal that no query
- end
-end
-
--- /test/ | /test | test/ | test => test
-
-function url.barepath(path)
- if not path or path == "" then
- return ""
- else
- return (gsub(path,"^/?(.-)/?$","%1"))
+ return str
end
end
@@ -3709,7 +3332,6 @@ end
-
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -3741,24 +3363,6 @@ local isdir = lfs.isdir
local isfile = lfs.isfile
local currentdir = lfs.currentdir
--- in case we load outside luatex
-
-if not isdir then
- function isdir(name)
- local a = attributes(name)
- return a and a.mode == "directory"
- end
- lfs.isdir = isdir
-end
-
-if not isfile then
- function isfile(name)
- local a = attributes(name)
- return a and a.mode == "file"
- end
- lfs.isfile = isfile
-end
-
-- handy
function dir.current()
@@ -4134,49 +3738,28 @@ function boolean.tonumber(b)
end
function toboolean(str,tolerant)
- if str == nil then
- return false
- elseif str == false then
- return false
- elseif str == true then
- return true
+ if tolerant then
+ local tstr = type(str)
+ if tstr == "string" then
+ return str == "true" or str == "yes" or str == "on" or str == "1" or str == "t"
+ elseif tstr == "number" then
+ return tonumber(str) ~= 0
+ elseif tstr == "nil" then
+ return false
+ else
+ return str
+ end
elseif str == "true" then
return true
elseif str == "false" then
return false
- elseif not tolerant then
- return false
- elseif str == 0 then
- return false
- elseif (tonumber(str) or 0) > 0 then
- return true
else
- return str == "yes" or str == "on" or str == "t"
+ return str
end
end
string.toboolean = toboolean
-function string.booleanstring(str)
- if str == nil then
- return false
- elseif str == false then
- return false
- elseif str == true then
- return true
- elseif str == "true" then
- return true
- elseif str == "false" then
- return false
- elseif str == 0 then
- return false
- elseif (tonumber(str) or 0) > 0 then
- return true
- else
- return str == "yes" or str == "on" or str == "t"
- end
-end
-
function string.is_boolean(str,default)
if type(str) == "string" then
if str == "true" or str == "yes" or str == "on" or str == "t" then
@@ -4201,229 +3784,57 @@ if not modules then modules = { } end modules ['l-unicode'] = {
license = "see context related readme files"
}
--- this module will be reorganized
-
--- todo: utf.sub replacement (used in syst-aux)
-
-local concat = table.concat
-local type = type
-local P, C, R, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs, lpeg.Ct
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
-local utftype = patterns.utftype
-local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
-local utfsplitlines = string.utfsplitlines
-
if not unicode then
- unicode = { }
-
-end
-
-local unicode = unicode
-
-utf = utf or unicode.utf8
-
-if not utf then
-
- utf8 = { }
- unicode.utf8 = utf8
- utf = utf8
-
-end
-
-if not utf.char then
+ unicode = { utf8 = { } }
local floor, char = math.floor, string.char
- function utf.char(n)
+ function unicode.utf8.utfchar(n)
if n < 0x80 then
- -- 0aaaaaaa : 0x80
return char(n)
elseif n < 0x800 then
- -- 110bbbaa : 0xC0 : n >> 6
- -- 10aaaaaa : 0x80 : n & 0x3F
return char(
0xC0 + floor(n/0x40),
0x80 + (n % 0x40)
)
elseif n < 0x10000 then
- -- 1110bbbb : 0xE0 : n >> 12
- -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
- -- 10aaaaaa : 0x80 : n & 0x3F
return char(
0xE0 + floor(n/0x1000),
0x80 + (floor(n/0x40) % 0x40),
0x80 + (n % 0x40)
)
- elseif n < 0x200000 then
- -- 11110ccc : 0xF0 : n >> 18
- -- 10ccbbbb : 0x80 : (n >> 12) & 0x3F
- -- 10bbbbaa : 0x80 : (n >> 6) & 0x3F
- -- 10aaaaaa : 0x80 : n & 0x3F
- -- dddd : ccccc - 1
+ elseif n < 0x40000 then
return char(
- 0xF0 + floor(n/0x40000),
- 0x80 + (floor(n/0x1000) % 0x40),
+ 0xF0 + floor(n/0x40000),
+ 0x80 + floor(n/0x1000),
0x80 + (floor(n/0x40) % 0x40),
0x80 + (n % 0x40)
)
else
- return ""
+ -- return char(
+ -- 0xF1 + floor(n/0x1000000),
+ -- 0x80 + floor(n/0x40000),
+ -- 0x80 + floor(n/0x1000),
+ -- 0x80 + (floor(n/0x40) % 0x40),
+ -- 0x80 + (n % 0x40)
+ -- )
+ return "?"
end
end
end
-if not utf.byte then
-
- local utf8byte = patterns.utf8byte
-
- function utf.byte(c)
- return lpegmatch(utf8byte,c)
- end
-
-end
-
-local utfchar, utfbyte = utf.char, utf.byte
-
--- As we want to get rid of the (unmaintained) utf library we implement our own
--- variants (in due time an independent module):
-
-function unicode.filetype(data)
- return data and lpegmatch(utftype,data) or "unknown"
-end
-
-local toentities = Cs (
- (
- patterns.utf8one
- + (
- patterns.utf8two
- + patterns.utf8three
- + patterns.utf8four
- ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("%X;",b) end end
- )^0
-)
-
-patterns.toentities = toentities
-
-function utf.toentities(str)
- return lpegmatch(toentities,str)
-end
-
-
-
-
-local one = P(1)
-local two = C(1) * C(1)
-local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
-
--- actually one of them is already utf ... sort of useless this one
-
--- function utf.char(n)
--- if n < 0x80 then
--- return char(n)
--- elseif n < 0x800 then
--- return char(
--- 0xC0 + floor(n/0x40),
--- 0x80 + (n % 0x40)
--- )
--- elseif n < 0x10000 then
--- return char(
--- 0xE0 + floor(n/0x1000),
--- 0x80 + (floor(n/0x40) % 0x40),
--- 0x80 + (n % 0x40)
--- )
--- elseif n < 0x40000 then
--- return char(
--- 0xF0 + floor(n/0x40000),
--- 0x80 + floor(n/0x1000),
--- 0x80 + (floor(n/0x40) % 0x40),
--- 0x80 + (n % 0x40)
--- )
--- else
--- -- return char(
--- -- 0xF1 + floor(n/0x1000000),
--- -- 0x80 + floor(n/0x40000),
--- -- 0x80 + floor(n/0x1000),
--- -- 0x80 + (floor(n/0x40) % 0x40),
--- -- 0x80 + (n % 0x40)
--- -- )
--- return "?"
--- end
--- end
---
--- merge into:
-
-local pattern = P("\254\255") * Cs( (
- four / function(a,b,c,d)
- local ab = 0xFF * byte(a) + byte(b)
- local cd = 0xFF * byte(c) + byte(d)
- return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
- end
- + two / function(a,b)
- return utfchar(byte(a)*256 + byte(b))
- end
- + one
- )^1 )
- + P("\255\254") * Cs( (
- four / function(b,a,d,c)
- local ab = 0xFF * byte(a) + byte(b)
- local cd = 0xFF * byte(c) + byte(d)
- return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
- end
- + two / function(b,a)
- return utfchar(byte(a)*256 + byte(b))
- end
- + one
- )^1 )
-
-function string.toutf(s)
- return lpegmatch(pattern,s) or s -- todo: utf32
-end
-
-local validatedutf = Cs (
- (
- patterns.utf8one
- + patterns.utf8two
- + patterns.utf8three
- + patterns.utf8four
- + P(1) / "�"
- )^0
-)
-
-patterns.validatedutf = validatedutf
-
-function string.validutf(str)
- return lpegmatch(validatedutf,str)
-end
-
-
-utf.length = string.utflength
-utf.split = string.utfsplit
-utf.splitines = string.utfsplitlines
-utf.valid = string.validutf
-
-if not utf.len then
- utf.len = utf.length
-end
-
--- a replacement for simple gsubs:
+local unicode = unicode
-local utf8char = patterns.utf8char
+utf = utf or unicode.utf8
-function utf.remapper(mapping)
- local pattern = Cs((utf8char/mapping)^0)
- return function(str)
- if not str or str == "" then
- return ""
- else
- return lpegmatch(pattern,str)
- end
- end, pattern
-end
+local concat = table.concat
+local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub
+local char, byte, find, bytepairs, utfvalues, format = string.char, string.byte, string.find, string.bytepairs, string.utfvalues, string.format
+local type = type
--- local remap = utf.remapper { a = 'd', b = "c", c = "b", d = "a" }
--- print(remap("abcd 1234 abcd"))
+local utfsplitlines = string.utfsplitlines
-- 0 EF BB BF UTF-8
-- 1 FF FE UTF-16-little-endian
@@ -4616,22 +4027,11 @@ local function big(c)
end
end
--- function unicode.utf8_to_utf16(str,littleendian)
--- if littleendian then
--- return char(255,254) .. utfgsub(str,".",little)
--- else
--- return char(254,255) .. utfgsub(str,".",big)
--- end
--- end
-
-local _, l_remap = utf.remapper(little)
-local _, b_remap = utf.remapper(big)
-
function unicode.utf8_to_utf16(str,littleendian)
if littleendian then
- return char(255,254) .. lpegmatch(l_remap,str)
+ return char(255,254) .. utfgsub(str,".",little)
else
- return char(254,255) .. lpegmatch(b_remap,str)
+ return char(254,255) .. utfgsub(str,".",big)
end
end
@@ -4652,12 +4052,84 @@ function unicode.xstring(s)
return format("0x%05X",type(s) == "number" and s or utfbyte(s))
end
---
-local pattern = Ct(C(patterns.utf8char)^0)
+local lpegmatch = lpeg.match
+local patterns = lpeg.patterns
+local utftype = patterns.utftype
+
+function unicode.filetype(data)
+ return data and lpegmatch(utftype,data) or "unknown"
+end
-function utf.totable(str)
- return lpegmatch(pattern,str)
+local toentities = lpeg.Cs (
+ (
+ patterns.utf8one
+ + (
+ patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ ) / function(s) local b = utfbyte(s) if b < 127 then return s else return format("%X;",b) end end
+ )^0
+)
+
+patterns.toentities = toentities
+
+function utf.toentities(str)
+ return lpegmatch(toentities,str)
+end
+
+
+
+
+local P, C, R, Cs = lpeg.P, lpeg.C, lpeg.R, lpeg.Cs
+
+local one = P(1)
+local two = C(1) * C(1)
+local four = C(R(utfchar(0xD8),utfchar(0xFF))) * C(1) * C(1) * C(1)
+
+-- actually one of them is already utf ... sort of useless this one
+
+local pattern = P("\254\255") * Cs( (
+ four / function(a,b,c,d)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(a,b)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+ + P("\255\254") * Cs( (
+ four / function(b,a,d,c)
+ local ab = 0xFF * byte(a) + byte(b)
+ local cd = 0xFF * byte(c) + byte(d)
+ return utfchar((ab-0xD800)*0x400 + (cd-0xDC00) + 0x10000)
+ end
+ + two / function(b,a)
+ return utfchar(byte(a)*256 + byte(b))
+ end
+ + one
+ )^1 )
+
+function string.toutf(s)
+ return lpegmatch(pattern,s) or s -- todo: utf32
+end
+
+local validatedutf = Cs (
+ (
+ patterns.utf8one
+ + patterns.utf8two
+ + patterns.utf8three
+ + patterns.utf8four
+ + P(1) / "�"
+ )^0
+)
+
+patterns.validatedutf = validatedutf
+
+function string.validutf(str)
+ return lpegmatch(validatedutf,str)
end
@@ -4717,11 +4189,10 @@ utilities = utilities or {}
utilities.tables = utilities.tables or { }
local tables = utilities.tables
-local format, gmatch, rep, gsub = string.format, string.gmatch, string.rep, string.gsub
+local format, gmatch, rep = string.format, string.gmatch, string.rep
local concat, insert, remove = table.concat, table.insert, table.remove
local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
-local type, next, rawset, tonumber, loadstring = type, next, rawset, tonumber, loadstring
-local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs
+local type, next, rawset, tonumber = type, next, rawset, tonumber
function tables.definetable(target) -- defines undefined tables
local composed, t, n = nil, { }, 0
@@ -4875,121 +4346,6 @@ function tables.encapsulate(core,capsule,protect)
end
end
-local function serialize(t,r,outer) -- no mixes
- r[#r+1] = "{"
- local n = #t
- if n > 0 then
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = format("%q,",v)
- elseif tv == "number" then
- r[#r+1] = format("%s,",v)
- elseif tv == "table" then
- serialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = format("%s,",tostring(v))
- end
- end
- else
- for k, v in next, t do
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = format("[%q]=%q,",k,v)
- elseif tv == "number" then
- r[#r+1] = format("[%q]=%s,",k,v)
- elseif tv == "table" then
- r[#r+1] = format("[%q]=",k)
- serialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = format("[%q]=%s,",k,tostring(v))
- end
- end
- end
- if outer then
- r[#r+1] = "}"
- else
- r[#r+1] = "},"
- end
- return r
-end
-
-function table.fastserialize(t,prefix)
- return concat(serialize(t,{ prefix or "return" },true))
-end
-
-function table.deserialize(str)
- if not str or str == "" then
- return
- end
- local code = loadstring(str)
- if not code then
- return
- end
- code = code()
- if not code then
- return
- end
- return code
-end
-
--- inspect(table.fastserialize { a = 1, b = { 4, { 5, 6 } }, c = { d = 7, e = 'f"g\nh' } })
-
-function table.load(filename)
- if filename then
- local t = io.loaddata(filename)
- if t and t ~= "" then
- t = loadstring(t)
- if type(t) == "function" then
- t = t()
- if type(t) == "table" then
- return t
- end
- end
- end
- end
-end
-
-local function slowdrop(t)
- local r = { }
- local l = { }
- for i=1,#t do
- local ti = t[i]
- local j = 0
- for k, v in next, ti do
- j = j + 1
- l[j] = format("%s=%q",k,v)
- end
- r[i] = format(" {%s},\n",concat(l))
- end
- return format("return {\n%s}",concat(r))
-end
-
-local function fastdrop(t)
- local r = { "return {\n" }
- for i=1,#t do
- local ti = t[i]
- r[#r+1] = " {"
- for k, v in next, ti do
- r[#r+1] = format("%s=%q",k,v)
- end
- r[#r+1] = "},\n"
- end
- r[#r+1] = "}"
- return concat(r)
-end
-
-function table.drop(t,slow)
- if #t == 0 then
- return "return { }"
- elseif slow == true then
- return slowdrop(t) -- less memory
- else
- return fastdrop(t) -- some 15% faster
- end
-end
-
end -- of closure
@@ -5164,10 +4520,11 @@ local concat = table.concat
local type, next = type, next
utilities = utilities or {}
-local merger = utilities.merger or { }
-utilities.merger = merger
+utilities.merger = utilities.merger or { } -- maybe mergers
utilities.report = logs and logs.reporter("system") or print
+local merger = utilities.merger
+
merger.strip_comment = true
local m_begin_merge = "begin library merge"
@@ -5213,11 +4570,9 @@ end
local function self_save(name, data)
if data ~= "" then
if merger.strip_comment then
+ -- saves some 20K
local n = #data
- -- saves some 20K .. scite comments
data = gsub(data,"%-%-~[^\n\r]*[\r\n]","")
- -- saves some 20K .. ldx comments
- data = gsub(data,"%-%-%[%[ldx%-%-.-%-%-ldx%]%]%-%-","")
utilities.report("merge: %s bytes of comment stripped, %s bytes of code left",n-#data,#data)
end
io.savedata(name,data)
@@ -5298,208 +4653,36 @@ if not modules then modules = { } end modules ['util-lua'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
- comment = "the strip code is written by Peter Cawley",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
-local rep, sub, byte, dump, format = string.rep, string.sub, string.byte, string.dump, string.format
-local loadstring, loadfile, type = loadstring, loadfile, type
-
-utilities = utilities or {}
-utilities.lua = utilities.lua or { }
-local luautilities = utilities.lua
-
-utilities.report = logs and logs.reporter("system") or print -- can be overloaded later
-
-local tracestripping = false
-local forcestupidcompile = true -- use internal bytecode compiler
-luautilities.stripcode = true -- support stripping when asked for
-luautilities.alwaysstripcode = false -- saves 1 meg on 7 meg compressed format file (2012.08.12)
-luautilities.nofstrippedchunks = 0
-luautilities.nofstrippedbytes = 0
-
--- The next function was posted by Peter Cawley on the lua list and strips line
--- number information etc. from the bytecode data blob. We only apply this trick
--- when we store data tables. Stripping makes the compressed format file about
--- 1MB smaller (and uncompressed we save at least 6MB).
---
--- You can consider this feature an experiment, so it might disappear. There is
--- no noticeable gain in runtime although the memory footprint should be somewhat
--- smaller (and the file system has a bit less to deal with).
---
--- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ...
-
-local function strip_code_pc(dump,name)
- local before = #dump
- local version, format, endian, int, size, ins, num = byte(dump,5,11)
- local subint
- if endian == 1 then
- subint = function(dump, i, l)
- local val = 0
- for n = l, 1, -1 do
- val = val * 256 + byte(dump,i + n - 1)
- end
- return val, i + l
- end
- else
- subint = function(dump, i, l)
- local val = 0
- for n = 1, l, 1 do
- val = val * 256 + byte(dump,i + n - 1)
- end
- return val, i + l
- end
- end
- local strip_function
- strip_function = function(dump)
- local count, offset = subint(dump, 1, size)
- local stripped, dirty = rep("\0", size), offset + count
- offset = offset + count + int * 2 + 4
- offset = offset + int + subint(dump, offset, int) * ins
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- local t
- t, offset = subint(dump, offset, 1)
- if t == 1 then
- offset = offset + 1
- elseif t == 4 then
- offset = offset + size + subint(dump, offset, size)
- elseif t == 3 then
- offset = offset + num
- end
- end
- count, offset = subint(dump, offset, int)
- stripped = stripped .. sub(dump,dirty, offset - 1)
- for n = 1, count do
- local proto, off = strip_function(sub(dump,offset, -1))
- stripped, offset = stripped .. proto, offset + off - 1
- end
- offset = offset + subint(dump, offset, int) * int + int
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size + int * 2
- end
- count, offset = subint(dump, offset, int)
- for n = 1, count do
- offset = offset + subint(dump, offset, size) + size
- end
- stripped = stripped .. rep("\0", int * 3)
- return stripped, offset
- end
- dump = sub(dump,1,12) .. strip_function(sub(dump,13,-1))
- local after = #dump
- local delta = before-after
- if tracestripping then
- utilities.report("stripped bytecode: %s, before %s, after %s, delta %s",name or "unknown",before,after,delta)
- end
- luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1
- luautilities.nofstrippedbytes = luautilities.nofstrippedbytes + delta
- return dump, delta
-end
-
--- ... end of borrowed code.
-
-local function strippedbytecode(code,forcestrip,name)
- if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then
- return strip_code_pc(code,name)
- else
- return code, 0
- end
-end
-
-luautilities.stripbytecode = strip_code_pc
-luautilities.strippedbytecode = strippedbytecode
-
-local function fatalerror(name)
- utilities.report(format("fatal error in %q",name or "unknown"))
-end
-
--- quite subtle ... doing this wrong incidentally can give more bytes
-
-
-function luautilities.loadedluacode(fullname,forcestrip,name)
- -- quite subtle ... doing this wrong incidentally can give more bytes
- name = name or fullname
- local code = loadfile(fullname)
- if code then
- code()
- end
- if forcestrip and luautilities.stripcode then
- if type(forcestrip) == "function" then
- forcestrip = forcestrip(fullname)
- end
- if forcestrip then
- local code, n = strip_code_pc(dump(code,name))
- return loadstring(code), n
- elseif luautilities.alwaysstripcode then
- return loadstring(strip_code_pc(dump(code),name))
- else
- return code, 0
- end
- elseif luautilities.alwaysstripcode then
- return loadstring(strip_code_pc(dump(code),name))
- else
- return code, 0
- end
-end
-
-function luautilities.strippedloadstring(code,forcestrip,name) -- not executed
- local n = 0
- if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then
- code = loadstring(code)
- if not code then
- fatalerror(name)
- end
- code, n = strip_code_pc(dump(code),name)
- end
- return loadstring(code), n
-end
+utilities = utilities or {}
+utilities.lua = utilities.lua or { }
+utilities.report = logs and logs.reporter("system") or print
-local function stupidcompile(luafile,lucfile,strip)
- local code = io.loaddata(luafile)
- local n = 0
- if code and code ~= "" then
- code = loadstring(code)
- if not code then
- fatalerror()
- end
- code = dump(code)
- if strip then
- code, n = strippedbytecode(code,true,luafile) -- last one is reported
- end
- if code and code ~= "" then
- io.savedata(lucfile,code)
+local function stupidcompile(luafile,lucfile)
+ local data = io.loaddata(luafile)
+ if data and data ~= "" then
+ data = string.dump(data)
+ if data and data ~= "" then
+ io.savedata(lucfile,data)
end
end
- return n
end
-local luac_normal = "texluac -o %q %q"
-local luac_strip = "texluac -s -o %q %q"
-
-function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
+function utilities.lua.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
utilities.report("lua: compiling %s into %s",luafile,lucfile)
os.remove(lucfile)
- local done = false
+ local command = "-o " .. string.quoted(lucfile) .. " " .. string.quoted(luafile)
if strip ~= false then
- strip = true
- end
- if forcestupidcompile then
- fallback = true
- elseif strip then
- done = os.spawn(format(luac_strip, lucfile,luafile)) == 0
- else
- done = os.spawn(format(luac_normal,lucfile,luafile)) == 0
+ command = "-s " .. command
end
+ local done = os.spawn("texluac " .. command) == 0 -- or os.spawn("luac " .. command) == 0
if not done and fallback then
- local n = stupidcompile(luafile,lucfile,strip)
- if n > 0 then
- utilities.report("lua: %s dumped into %s (%i bytes stripped)",luafile,lucfile,n)
- else
- utilities.report("lua: %s dumped into %s (unstripped)",luafile,lucfile)
- end
- cleanup = false -- better see how bad it is
+ utilities.report("lua: dumping %s into %s (unstripped)",luafile,lucfile)
+ stupidcompile(luafile,lucfile) -- maybe use the stripper we have elsewhere
+ cleanup = false -- better see how worse it is
end
if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
utilities.report("lua: removing %s",luafile)
@@ -5514,6 +4697,7 @@ end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -5526,10 +4710,8 @@ if not modules then modules = { } end modules ['util-prs'] = {
license = "see context related readme files"
}
-local lpeg, table, string = lpeg, table, string
-
-local P, R, V, S, C, Ct, Cs, Carg, Cc = lpeg.P, lpeg.R, lpeg.V, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cc
-local lpegmatch, patterns = lpeg.match, lpeg.patterns
+local P, R, V, C, Ct, Cs, Carg = lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg
+local lpegmatch = lpeg.match
local concat, format, gmatch, find = table.concat, string.format, string.gmatch, string.find
local tostring, type, next = tostring, type, next
@@ -5541,39 +4723,29 @@ parsers.patterns = parsers.patterns or { }
local setmetatableindex = table.setmetatableindex
local sortedhash = table.sortedhash
--- we share some patterns
-
-local space = P(' ')
-local equal = P("=")
-local comma = P(",")
-local lbrace = P("{")
-local rbrace = P("}")
-local period = S(".")
-local punctuation = S(".,:;")
-local spacer = patterns.spacer
-local whitespace = patterns.whitespace
-local newline = patterns.newline
-local anything = patterns.anything
-local endofstring = patterns.endofstring
-
-- we could use a Cf Cg construct
local escape, left, right = P("\\"), P('{'), P('}')
-patterns.balanced = P {
+lpeg.patterns.balanced = P {
[1] = ((escape * (left+right)) + (1 - (left+right)) + V(2))^0,
[2] = left * V(1) * right
}
+local space = P(' ')
+local equal = P("=")
+local comma = P(",")
+local lbrace = P("{")
+local rbrace = P("}")
local nobrace = 1 - (lbrace+rbrace)
local nested = P { lbrace * (nobrace + V(1))^0 * rbrace }
local spaces = space^0
local argument = Cs((lbrace/"") * ((nobrace + nested)^0) * (rbrace/""))
-local content = (1-endofstring)^0
+local content = (1-P(-1))^0
-patterns.nested = nested -- no capture
-patterns.argument = argument -- argument after e.g. =
-patterns.content = content -- rest after e.g =
+lpeg.patterns.nested = nested -- no capture
+lpeg.patterns.argument = argument -- argument after e.g. =
+lpeg.patterns.content = content -- rest after e.g =
local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0)
@@ -5592,6 +4764,10 @@ local function set(key,value)
hash[key] = value
end
+local function set(key,value)
+ hash[key] = value
+end
+
local pattern_a_s = (pattern_a/set)^1
local pattern_b_s = (pattern_b/set)^1
local pattern_c_s = (pattern_c/set)^1
@@ -5642,7 +4818,7 @@ end
local separator = comma * space^0
local value = P(lbrace * C((nobrace + nested)^0) * rbrace) + C((nested + (1-comma))^0)
-local pattern = spaces * Ct(value*(separator*value)^0)
+local pattern = Ct(value*(separator*value)^0)
-- "aap, {noot}, mies" : outer {} removes, leading spaces ignored
@@ -5766,37 +4942,6 @@ function parsers.listitem(str)
return gmatch(str,"[^, ]+")
end
---
-local digit = R("09")
-
-local pattern = Cs { "start",
- start = V("one") + V("two") + V("three"),
- rest = (Cc(",") * V("thousand"))^0 * (P(".") + endofstring) * anything^0,
- thousand = digit * digit * digit,
- one = digit * V("rest"),
- two = digit * digit * V("rest"),
- three = V("thousand") * V("rest"),
-}
-
-patterns.splitthousands = pattern -- maybe better in the parsers namespace ?
-
-function parsers.splitthousands(str)
- return lpegmatch(pattern,str) or str
-end
-
--- print(parsers.splitthousands("11111111111.11"))
-
-local optionalwhitespace = whitespace^0
-
-patterns.words = Ct((Cs((1-punctuation-whitespace)^1) + anything)^1)
-patterns.sentences = Ct((optionalwhitespace * Cs((1-period)^0 * period))^1)
-patterns.paragraphs = Ct((optionalwhitespace * Cs((whitespace^1*endofstring/"" + 1 - (spacer^0*newline*newline))^1))^1)
-
--- local str = " Word1 word2. \n Word3 word4. \n\n Word5 word6.\n "
--- inspect(lpegmatch(patterns.paragraphs,str))
--- inspect(lpegmatch(patterns.sentences,str))
--- inspect(lpegmatch(patterns.words,str))
-
end -- of closure
@@ -5898,7 +5043,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['util-deb'] = {
+if not modules then modules = { } end modules ['util.deb'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -6010,7 +5155,6 @@ function inspect(i) -- global function
else
print(tostring(i))
end
- return i -- so that we can inline the inspect
end
-- from the lua book:
@@ -6050,7 +5194,7 @@ if not modules then modules = { } end modules ['trac-inf'] = {
local format, lower = string.format, string.lower
local clock = os.gettimeofday or os.clock -- should go in environment
-local write_nl = texio and texio.write_nl or print
+local write_nl = texio.write_nl
statistics = statistics or { }
local statistics = statistics
@@ -6133,7 +5277,7 @@ statistics.elapsedtime = elapsedtime
statistics.elapsedindeed = elapsedindeed
statistics.elapsedseconds = elapsedseconds
--- general function .. we might split this module
+-- general function
function statistics.register(tag,fnc)
if statistics.enable and type(fnc) == "function" then
@@ -6243,8 +5387,6 @@ if not modules then modules = { } end modules ['trac-set'] = { -- might become u
license = "see context related readme files"
}
--- maybe this should be util-set.lua
-
local type, next, tostring = type, next, tostring
local concat = table.concat
local format, find, lower, gsub, escapedpattern = string.format, string.find, string.lower, string.gsub, string.escapedpattern
@@ -6444,7 +5586,7 @@ function setters.show(t)
local value, default, modules = functions.value, functions.default, #functions
value = value == nil and "unset" or tostring(value)
default = default == nil and "unset" or tostring(default)
- t.report("%-50s modules: %2i default: %6s value: %6s",name,modules,default,value)
+ t.report("%-30s modules: %2i default: %6s value: %6s",name,modules,default,value)
end
end
t.report()
@@ -6536,31 +5678,17 @@ end)
-- experiment
-if environment then
+local flags = environment and environment.engineflags
- -- The engineflags are known earlier than environment.arguments but maybe we
- -- need to handle them both as the later are parsed differently. The c: prefix
- -- is used by mtx-context to isolate the flags from those that concern luatex.
-
- local engineflags = environment.engineflags
-
- if engineflags then
- if trackers then
- local list = engineflags["c:trackers"] or engineflags["trackers"]
- if type(list) == "string" then
- setters.initialize("flags","trackers",settings_to_hash(list))
- -- t_enable(list)
- end
- end
- if directives then
- local list = engineflags["c:directives"] or engineflags["directives"]
- if type(list) == "string" then
- setters.initialize("flags","directives", settings_to_hash(list))
- -- d_enable(list)
- end
- end
+if flags then
+ if trackers and flags.trackers then
+ setters.initialize("flags","trackers", settings_to_hash(flags.trackers))
+ -- t_enable(flags.trackers)
+ end
+ if directives and flags.directives then
+ setters.initialize("flags","directives", settings_to_hash(flags.directives))
+ -- d_enable(flags.directives)
end
-
end
-- here
@@ -6613,7 +5741,10 @@ local next, type = next, type
local setmetatableindex = table.setmetatableindex
-
+--[[ldx--
+
This is a prelude to a more extensive logging module. We no longer
+provide based logging a sparsing is relatively easy anyway.
+--ldx]]--
logs = logs or { }
local logs = logs
@@ -7429,8 +6560,7 @@ local allocate, mark = utilities.storage.allocate, utilities.storage.mark
local format, sub, match, gsub, find = string.format, string.sub, string.match, string.gsub, string.find
local unquoted, quoted = string.unquoted, string.quoted
-local concat, insert, remove = table.concat, table.insert, table.remove
-local loadedluacode = utilities.lua.loadedluacode
+local concat = table.concat
-- precautions
@@ -7448,28 +6578,8 @@ if arg and (arg[0] == 'luatex' or arg[0] == 'luatex.exe') and arg[1] == "--luaon
for k=3,#arg do
arg[k-2] = arg[k]
end
- remove(arg) -- last
- remove(arg) -- pre-last
-end
-
--- This is an ugly hack but it permits symlinking a script (say 'context') to 'mtxrun' as in:
---
--- ln -s /opt/minimals/tex/texmf-linux-64/bin/mtxrun context
---
--- The special mapping hack is needed because 'luatools' boils down to 'mtxrun --script base'
--- but it's unlikely that there will be more of this
-
-do
-
- local originalzero = file.basename(arg[0])
- local specialmapping = { luatools == "base" }
-
- if originalzero ~= "mtxrun" and originalzero ~= "mtxrun.lua" then
- arg[0] = specialmapping[originalzero] or originalzero
- insert(arg,0,"--script")
- insert(arg,0,"mtxrun")
- end
-
+ arg[#arg] = nil -- last
+ arg[#arg] = nil -- pre-last
end
-- environment
@@ -7509,8 +6619,6 @@ local mt = {
setmetatable(environment,mt)
--- context specific arguments (in order not to confuse the engine)
-
function environment.initializearguments(arg)
local arguments, files = { }, { }
environment.arguments, environment.files, environment.sortedflags = arguments, files, nil
@@ -7519,12 +6627,10 @@ function environment.initializearguments(arg)
if index > 0 then
local flag, value = match(argument,"^%-+(.-)=(.-)$")
if flag then
- flag = gsub(flag,"^c:","")
arguments[flag] = unquoted(value or "")
else
flag = match(argument,"^%-+(.+)")
if flag then
- flag = gsub(flag,"^c:","")
arguments[flag] = true
else
files[#files+1] = argument
@@ -7544,7 +6650,7 @@ end
-- tricky: too many hits when we support partials unless we add
-- a registration of arguments so from now on we have 'partial'
-function environment.getargument(name,partial)
+function environment.argument(name,partial)
local arguments, sortedflags = environment.arguments, environment.sortedflags
if arguments[name] then
return arguments[name]
@@ -7567,8 +6673,6 @@ function environment.getargument(name,partial)
return nil
end
-environment.argument = environment.getargument
-
function environment.splitarguments(separator) -- rather special, cut-off before separator
local done, before, after = false, { }, { }
local originalarguments = environment.originalarguments
@@ -7654,7 +6758,7 @@ function environment.texfile(filename)
return resolvers.findfile(filename,'tex')
end
-function environment.luafile(filename) -- needs checking
+function environment.luafile(filename)
local resolved = resolvers.findfile(filename,'tex') or ""
if resolved ~= "" then
return resolved
@@ -7666,16 +6770,13 @@ function environment.luafile(filename) -- needs checking
return resolvers.findfile(filename,'luatexlibs') or ""
end
-local function checkstrip(filename)
- local modu = modules[file.nameonly(filename)]
- return modu and modu.dataonly
-end
+environment.loadedluacode = loadfile -- can be overloaded
function environment.luafilechunk(filename,silent) -- used for loading lua bytecode in the format
filename = file.replacesuffix(filename, "lua")
local fullname = environment.luafile(filename)
if fullname and fullname ~= "" then
- local data = loadedluacode(fullname,checkstrip,filename)
+ local data = environment.loadedluacode(fullname)
if trace_locating then
report_lua("loading file %s%s", fullname, not data and " failed" or "")
elseif not silent then
@@ -7773,7 +6874,21 @@ local trace_entities = false trackers.register("xml.entities", function(v) trac
local report_xml = logs and logs.reporter("xml","core") or function(...) print(format(...)) end
+--[[ldx--
+
The parser used here is inspired by the variant discussed in the lua book, but
+handles comment and processing instructions, has a different structure, provides
+parent access; a first version used different trickery but was less optimized to we
+went this route. First we had a find based parser, now we have an based one.
+The find based parser can be found in l-xml-edu.lua along with other older code.
+
Beware, the interface may change. For instance at, ns, tg, dt may get more
+verbose names. Once the code is stable we will also remove some tracing and
+optimize the code.
+
+
I might even decide to reimplement the parser using the latest trickery
+as the current variant was written when showed up and it's easier now to
+build tables in one go.
+--ldx]]--
xml = xml or { }
local xml = xml
@@ -7783,25 +6898,46 @@ local utf = unicode.utf8
local concat, remove, insert = table.concat, table.remove, table.insert
local type, next, setmetatable, getmetatable, tonumber = type, next, setmetatable, getmetatable, tonumber
local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub
-local utfchar = utf.char
+local utfchar, utffind, utfgsub = utf.char, utf.find, utf.gsub
local lpegmatch = lpeg.match
local P, S, R, C, V, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.C, lpeg.Cs
-
+--[[ldx--
+
First a hack to enable namespace resolving. A namespace is characterized by
+a . The following function associates a namespace prefix with a
+pattern. We use , which in this case is more than twice as fast as a
+find based solution where we loop over an array of patterns. Less code and
+much cleaner.
+--ldx]]--
xml.xmlns = xml.xmlns or { }
local check = P(false)
local parse = check
+--[[ldx--
+
The next function associates a namespace prefix with an . This
+normally happens independent of parsing.
+
+xml.registerns("mml","mathml")
+
+--ldx]]--
function xml.registerns(namespace, pattern) -- pattern can be an lpeg
check = check + C(P(lower(pattern))) / namespace
parse = P { P(check) + 1 * V(1) }
end
+--[[ldx--
+
The next function also registers a namespace, but this time we map a
+given namespace prefix onto a registered one, using the given
+. This used for attributes like xmlns:m.
+
+xml.checkns("m","http://www.w3.org/mathml")
+
+--ldx]]--
function xml.checkns(namespace,url)
local ns = lpegmatch(parse,lower(url))
@@ -7810,15 +6946,66 @@ function xml.checkns(namespace,url)
end
end
+--[[ldx--
+
Next we provide a way to turn an into a registered
+namespace. This used for the xmlns attribute.
+
+resolvedns = xml.resolvens("http://www.w3.org/mathml")
+
+
+This returns mml.
+--ldx]]--
function xml.resolvens(url)
return lpegmatch(parse,lower(url)) or ""
end
-
-
-
+--[[ldx--
+
A namespace in an element can be remapped onto the registered
+one efficiently by using the xml.xmlns table.
+--ldx]]--
+
+--[[ldx--
+
This version uses . We follow the same approach as before, stack and top and
+such. This version is about twice as fast which is mostly due to the fact that
+we don't have to prepare the stream for cdata, doctype etc etc. This variant is
+is dedicated to Luigi Scarso, who challenged me with 40 megabyte files that
+took 12.5 seconds to load (1.5 for file io and the rest for tree building). With
+the implementation we got that down to less 7.3 seconds. Loading the 14
+ interface definition files (2.6 meg) went down from 1.05 seconds to 0.55.
+
+
Next comes the parser. The rather messy doctype definition comes in many
+disguises so it is no surprice that later on have to dedicate quite some
+ code to it.
+
+
+
+
+
+
+
+
+
+
+
The code may look a bit complex but this is mostly due to the fact that we
+resolve namespaces and attach metatables. There is only one public function:
+
+
+local x = xml.convert(somestring)
+
+
+
An optional second boolean argument tells this function not to create a root
+element.
+
+
Valid entities are:
+
+
+
+
+
+
+--ldx]]--
-- not just one big nested table capture (lpeg overflow)
@@ -8033,7 +7220,15 @@ local privates_n = {
-- keeps track of defined ones
}
-local escaped = utf.remapper(privates_u)
+local function escaped(s)
+ if s == "" then
+ return ""
+ else -- if utffind(s,privates_u) then
+ return (utfgsub(s,".",privates_u))
+ -- else
+ -- return s
+ end
+end
local function unescaped(s)
local p = privates_n[s]
@@ -8048,7 +7243,13 @@ local function unescaped(s)
return p
end
-local unprivatized = utf.remapper(privates_p)
+local function unprivatized(s,resolve)
+ if s == "" then
+ return ""
+ else
+ return (utfgsub(s,".",privates_p))
+ end
+end
xml.privatetoken = unescaped
xml.unprivatized = unprivatized
@@ -8388,12 +7589,7 @@ local function _xmlconvert_(data, settings)
else
errorhandler = errorhandler or xml.errorhandler
if errorhandler then
- local currentresource = settings.currentresource
- if currentresource and currentresource ~= "" then
- xml.errorhandler(format("load error in [%s]: %s",currentresource,errorstr))
- else
- xml.errorhandler(format("load error: %s",errorstr))
- end
+ xml.errorhandler(format("load error: %s",errorstr))
end
end
else
@@ -8438,7 +7634,7 @@ function xmlconvert(data,settings)
if ok then
return result
else
- return _xmlconvert_("",settings)
+ return _xmlconvert_("")
end
end
@@ -8459,7 +7655,10 @@ function xml.inheritedconvert(data,xmldata) -- xmldata is parent
return xc
end
-
+--[[ldx--
+
Packaging data in an xml like table is done with the following
+function. Maybe it will go away (when not used).
+--ldx]]--
function xml.is_valid(root)
return root and root.dt and root.dt[1] and type(root.dt[1]) == "table" and not root.dt[1].er
@@ -8478,7 +7677,11 @@ end
xml.errorhandler = report_xml
-
+--[[ldx--
+
We cannot load an from a filehandle so we need to load
+the whole file first. The function accepts a string representing
+a filename or a file handle.
+--ldx]]--
function xml.load(filename,settings)
local data = ""
@@ -8492,17 +7695,13 @@ function xml.load(filename,settings)
elseif filename then -- filehandle
data = filename:read("*all")
end
- if settings then
- settings.currentresource = filename
- local result = xmlconvert(data,settings)
- settings.currentresource = nil
- return result
- else
- return xmlconvert(data,{ currentresource = filename })
- end
+ return xmlconvert(data,settings)
end
-
+--[[ldx--
+
When we inject new elements, we need to convert strings to
+valid trees, which is what the next function does.
+--ldx]]--
local no_root = { no_root = true }
@@ -8515,7 +7714,11 @@ function xml.toxml(data)
end
end
-
+--[[ldx--
+
For copying a tree we use a dedicated function instead of the
+generic table copier. Since we know what we're dealing with we
+can speed up things a bit. The second argument is not to be used!
+--ldx]]--
local function copy(old,tables)
if old then
@@ -8539,7 +7742,13 @@ end
xml.copy = copy
-
+--[[ldx--
+
In serializing the tree or parts of the tree is a major
+actitivity which is why the following function is pretty optimized resulting
+in a few more lines of code than needed. The variant that uses the formatting
+function for all components is about 15% slower than the concatinating
+alternative.
+--ldx]]--
-- todo: add when not present
@@ -8552,12 +7761,15 @@ function xml.checkbom(root) -- can be made faster
return
end
end
- insert(dt, 1, { special = true, ns = "", tg = "@pi@", dt = { "xml version='1.0' standalone='yes'" } } )
+ insert(dt, 1, { special=true, ns="", tg="@pi@", dt = { "xml version='1.0' standalone='yes'"} } )
insert(dt, 2, "\n" )
end
end
-
+--[[ldx--
+
At the cost of some 25% runtime overhead you can first convert the tree to a string
+and then handle the lot.
How you deal with saving data depends on your preferences. For a 40 MB database
+file the timing on a 2.3 Core Duo are as follows (time in seconds):
+
+
+1.3 : load data from file to string
+6.1 : convert string into tree
+5.3 : saving in file using xmlsave
+6.8 : converting to string using xml.tostring
+3.6 : saving converted string in file
+
+
Beware, these were timing with the old routine but measurements will not be that
+much different I guess.
+--ldx]]--
-- maybe this will move to lxml-xml
@@ -8828,7 +8054,10 @@ xml.newhandlers = newhandlers
xml.serialize = serialize
xml.tostring = xmltostring
-
+--[[ldx--
+
The next function operated on the content only and needs a handle function
+that accepts a string.
+--ldx]]--
local function xmlstring(e,handle)
if not handle or (e.special and e.tg ~= "@rt@") then
@@ -8847,7 +8076,9 @@ end
xml.string = xmlstring
-
+--[[ldx--
+
A few helpers:
+--ldx]]--
function xml.settings(e)
@@ -8891,7 +8122,11 @@ function xml.name(root)
end
end
-
+--[[ldx--
+
The next helper erases an element but keeps the table as it is,
+and since empty strings are not serialized (effectively) it does
+not harm. Copying the table would take more time. Usage:
+--ldx]]--
function xml.erase(dt,k)
if dt then
@@ -8903,7 +8138,13 @@ function xml.erase(dt,k)
end
end
+--[[ldx--
+
The next helper assigns a tree (or string). Usage:
+
+dt[k] = xml.assign(root) or xml.assign(dt,k,root)
+
+--ldx]]--
function xml.assign(dt,k,root)
if dt and k then
@@ -8916,14 +8157,20 @@ end
-- the following helpers may move
-
+--[[ldx--
+
The next helper assigns a tree (or string). Usage:
+
+xml.tocdata(e)
+xml.tocdata(e,"error")
+
+--ldx]]--
function xml.tocdata(e,wrapper) -- a few more in the aux module
local whatever = type(e) == "table" and xmltostring(e.dt) or e or ""
if wrapper then
whatever = format("<%s>%s%s>",wrapper,whatever,wrapper)
end
- local t = { special = true, ns = "", tg = "@cd@", at = { }, rn = "", dt = { whatever }, __p__ = e }
+ local t = { special = true, ns = "", tg = "@cd@", at = {}, rn = "", dt = { whatever }, __p__ = e }
setmetatable(t,getmetatable(e))
e.dt = { t }
end
@@ -8978,7 +8225,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['lxml-lpt'] = {
+if not modules then modules = { } end modules ['lxml-pth'] = {
version = 1.001,
comment = "this module is the basis for the lxml-* ones",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -8999,9 +8246,28 @@ local setmetatableindex = table.setmetatableindex
-- beware, this is not xpath ... e.g. position is different (currently) and
-- we have reverse-sibling as reversed preceding sibling
-
-
-
+--[[ldx--
+
This module can be used stand alone but also inside in
+which case it hooks into the tracker code. Therefore we provide a few
+functions that set the tracers. Here we overload a previously defined
+function.
+
If I can get in the mood I will make a variant that is XSLT compliant
+but I wonder if it makes sense.
+--ldx]]--
+
+--[[ldx--
+
Expecially the lpath code is experimental, we will support some of xpath, but
+only things that make sense for us; as compensation it is possible to hook in your
+own functions. Apart from preprocessing content for we also need
+this module for process management, like handling and
+files.
+
+
+a/b/c /*/c
+a/b/c/first() a/b/c/last() a/b/c/index(n) a/b/c/index(-n)
+a/b/c/text() a/b/c/text(1) a/b/c/text(-1) a/b/c/text(n)
+
+--ldx]]--
local trace_lpath = false if trackers then trackers.register("xml.path", function(v) trace_lpath = v end) end
local trace_lparse = false if trackers then trackers.register("xml.parse", function(v) trace_lparse = v end) end
@@ -9009,7 +8275,11 @@ local trace_lprofile = false if trackers then trackers.register("xml.profile",
local report_lpath = logs.reporter("xml","lpath")
-
+--[[ldx--
+
We've now arrived at an interesting part: accessing the tree using a subset
+of and since we're not compatible we call it . We
+will explain more about its usage in other documents.
+--ldx]]--
local xml = xml
@@ -9461,23 +8731,14 @@ local lp_builtin = P (
-- for the moment we keep namespaces with attributes
local lp_attribute = (P("@") + P("attribute::")) / "" * Cc("(ll.at and ll.at['") * ((R("az","AZ") + S("-_:"))^1) * Cc("'])")
-
--- lp_fastpos_p = (P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end
--- lp_fastpos_n = (P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end
-
-lp_fastpos_p = P("+")^0 * R("09")^1 * P(-1) / "l==%0"
-lp_fastpos_n = P("-") * R("09")^1 * P(-1) / "(%0<0 and (#list+%0==l))"
-
+local lp_fastpos_p = ((P("+")^0 * R("09")^1 * P(-1)) / function(s) return "l==" .. s end)
+local lp_fastpos_n = ((P("-") * R("09")^1 * P(-1)) / function(s) return "(" .. s .. "<0 and (#list+".. s .. "==l))" end)
local lp_fastpos = lp_fastpos_n + lp_fastpos_p
-
local lp_reserved = C("and") + C("or") + C("not") + C("div") + C("mod") + C("true") + C("false")
--- local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
--- return t .. "("
--- end
-
--- local lp_lua_function = (R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / "%0("
-local lp_lua_function = Cs((R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(")) / "%0"
+local lp_lua_function = C(R("az","AZ","__")^1 * (P(".") * R("az","AZ","__")^1)^1) * ("(") / function(t) -- todo: better . handling
+ return t .. "("
+end
local lp_function = C(R("az","AZ","__")^1) * P("(") / function(t) -- todo: better . handling
if expressions[t] then
@@ -9993,7 +9254,9 @@ end
xml.applylpath = applylpath -- takes a table as first argment, which is what xml.filter will do
-
+--[[ldx--
+
This is the main filter function. It returns whatever is asked for.
+--ldx]]--
function xml.filter(root,pattern) -- no longer funny attribute handling here
return applylpath(root,pattern)
@@ -10091,12 +9354,12 @@ xml.selection = selection -- new method, simple handle
-- generic function finalizer (independant namespace)
-local function dofunction(collected,fnc,...)
+local function dofunction(collected,fnc)
if collected then
local f = functions[fnc]
if f then
for c=1,#collected do
- f(collected[c],...)
+ f(collected[c])
end
else
report_lpath("unknown function '%s'",fnc)
@@ -10197,7 +9460,21 @@ expressions.tag = function(e,n) -- only tg
end
end
+--[[ldx--
+
Often using an iterators looks nicer in the code than passing handler
+functions. The book describes how to use coroutines for that
+purpose (). This permits
+code like:
+
+for r, d, k in xml.elements(xml.load('text.xml'),"title") do
+ print(d[k]) -- old method
+end
+for e in xml.collected(xml.load('text.xml'),"title") do
+ print(e) -- new one
+end
+
+--ldx]]--
local wrap, yield = coroutine.wrap, coroutine.yield
@@ -10238,32 +9515,6 @@ function xml.inspect(collection,pattern)
end
end
--- texy (see xfdf):
-
-local function split(e)
- local dt = e.dt
- if dt then
- for i=1,#dt do
- local dti = dt[i]
- if type(dti) == "string" then
- dti = gsub(dti,"^[\n\r]*(.-)[\n\r]*","%1")
- dti = gsub(dti,"[\n\r]+","\n\n")
- dt[i] = dti
- else
- split(dti)
- end
- end
- end
- return e
-end
-
-function xml.finalizers.paragraphs(c)
- for i=1,#c do
- split(c[i])
- end
- return c
-end
-
end -- of closure
@@ -10288,7 +9539,13 @@ local P, S, R, C, V, Cc, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.V, lpeg.Cc, l
lpegpatterns.xml = lpegpatterns.xml or { }
local xmlpatterns = lpegpatterns.xml
-
+--[[ldx--
+
The following helper functions best belong to the lxml-ini
+module. Some are here because we need then in the mk
+document and other manuals, others came up when playing with
+this module. Since this module is also used in we've
+put them here instead of loading mode modules there then needed.
+--ldx]]--
local function xmlgsub(t,old,new) -- will be replaced
local dt = t.dt
@@ -10474,7 +9731,9 @@ function xml.processattributes(root,pattern,handle)
return collected
end
-
+--[[ldx--
+
The following functions collect elements and texts.
+--ldx]]--
-- are these still needed -> lxml-cmp.lua
@@ -10513,7 +9772,9 @@ function xml.collect_tags(root, pattern, nonamespace)
end
end
-
+--[[ldx--
+
We've now arrived at the functions that manipulate the tree.
+--ldx]]--
local no_root = { no_root = true }
@@ -10899,7 +10160,9 @@ function xml.remapname(root, pattern, newtg, newns, newrn)
end
end
-
+--[[ldx--
+
Helper (for q2p).
+--ldx]]--
function xml.cdatatotext(e)
local dt = e.dt
@@ -10996,7 +10259,9 @@ end
-- xml.addentitiesdoctype(x,"hexadecimal")
-- print(x)
-
+--[[ldx--
+
Here are a few synonyms.
+--ldx]]--
xml.all = xml.each
xml.insert = xml.insertafter
@@ -11587,7 +10852,7 @@ local gsub, find, gmatch, char = string.gsub, string.find, string.gmatch, string
local concat = table.concat
local next, type = next, type
-local filedirname, filebasename, filejoin = file.dirname, file.basename, file.join
+local filedirname, filebasename, fileextname, filejoin = file.dirname, file.basename, file.extname, file.join
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local trace_detail = false trackers.register("resolvers.details", function(v) trace_detail = v end)
@@ -11937,14 +11202,12 @@ local function splitpathexpr(str, newlist, validate) -- I couldn't resist lpeggi
for s in gmatch(str,"[^,]+") do
s = validate(s)
if s then
- n = n + 1
- t[n] = s
+ n = n + 1 ; t[n] = s
end
end
else
for s in gmatch(str,"[^,]+") do
- n = n + 1
- t[n] = s
+ n = n + 1 ; t[n] = s
end
end
if trace_expansions then
@@ -11958,7 +11221,7 @@ end
-- We could make the previous one public.
local function validate(s)
- s = collapsepath(s) -- already keeps the trailing / and //
+ s = collapsepath(s) -- already keeps the //
return s ~= "" and not find(s,"^!*unset/*$") and s
end
@@ -12296,7 +11559,7 @@ local resolvers = resolvers
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
-local suffixonly = file.suffixonly
+local fileextname = file.extname
local formats = allocate()
local suffixes = allocate()
@@ -12551,7 +11814,7 @@ function resolvers.formatofvariable(str)
end
function resolvers.formatofsuffix(str) -- of file
- return suffixmap[suffixonly(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
+ return suffixmap[fileextname(str)] or 'tex' -- so many map onto tex (like mkiv, cld etc)
end
function resolvers.variableofformat(str)
@@ -12563,7 +11826,7 @@ function resolvers.variableofformatorsuffix(str)
if v then
return v
end
- v = suffixmap[suffixonly(str)]
+ v = suffixmap[fileextname(str)]
if v then
return formats[v]
end
@@ -12584,7 +11847,21 @@ if not modules then modules = { } end modules ['data-tmp'] = {
license = "see context related readme files"
}
+--[[ldx--
+
This module deals with caching data. It sets up the paths and
+implements loaders and savers for tables. Best is to set the
+following variable. When not set, the usual paths will be
+checked. Personally I prefer the (users) temporary path.
Currently we do no locking when we write files. This is no real
+problem because most caching involves fonts and the chance of them
+being written at the same time is small. We also need to extend
+luatools with a recache feature.
+--ldx]]--
local format, lower, gsub, concat = string.format, string.lower, string.gsub, table.concat
local serialize, serializetofile = table.serialize, table.tofile
@@ -13119,12 +12396,11 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns
local filedirname = file.dirname
local filebasename = file.basename
-local suffixonly = file.suffixonly
+local fileextname = file.extname
local filejoin = file.join
local collapsepath = file.collapsepath
local joinpath = file.joinpath
local allocate = utilities.storage.allocate
-local settings_to_array = utilities.parsers.settings_to_array
local setmetatableindex = table.setmetatableindex
local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
@@ -13148,7 +12424,7 @@ resolvers.cacheversion = '1.0.1'
resolvers.configbanner = ''
resolvers.homedir = environment.homedir
resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" }
-resolvers.luacnfname = "texmfcnf.lua"
+resolvers.luacnfname = 'texmfcnf.lua'
resolvers.luacnfstate = "unknown"
-- The web2c tex binaries as well as kpse have built in paths for the configuration
@@ -13420,7 +12696,7 @@ end
local function identify_configuration_files()
local specification = instance.specification
if #specification == 0 then
- local cnfspec = getenv("TEXMFCNF")
+ local cnfspec = getenv('TEXMFCNF')
if cnfspec == "" then
cnfspec = resolvers.luacnfspec
resolvers.luacnfstate = "default"
@@ -13508,7 +12784,7 @@ local function load_configuration_files()
-- we push the value into the main environment (osenv) so
-- that it takes precedence over the default one and therefore
-- also over following definitions
- resolvers.setenv("TEXMFCNF",cnfspec) -- resolves prefixes
+ resolvers.setenv('TEXMFCNF',cnfspec) -- resolves prefixes
-- we now identify and load the specified configuration files
instance.specification = { }
identify_configuration_files()
@@ -13556,11 +12832,10 @@ end
local function locate_file_databases()
-- todo: cache:// and tree:// (runtime)
- local texmfpaths = resolvers.expandedpathlist("TEXMF")
+ local texmfpaths = resolvers.expandedpathlist('TEXMF')
if #texmfpaths > 0 then
for i=1,#texmfpaths do
local path = collapsepath(texmfpaths[i])
- path = gsub(path,"/+$","") -- in case $HOME expands to something with a trailing /
local stripped = lpegmatch(inhibitstripper,path) -- the !! thing
if stripped ~= "" then
local runtime = stripped == path
@@ -13689,9 +12964,9 @@ function resolvers.prependhash(type,name,cache)
end
function resolvers.extendtexmfvariable(specification) -- crap, we could better prepend the hash
- local t = resolvers.splitpath(getenv("TEXMF")) -- okay?
+ local t = resolvers.splitpath(getenv('TEXMF'))
insert(t,1,specification)
- local newspec = concat(t,",") -- not ;
+ local newspec = concat(t,";")
if instance.environment["TEXMF"] then
instance.environment["TEXMF"] = newspec
elseif instance.variables["TEXMF"] then
@@ -13766,19 +13041,14 @@ function resolvers.resetextrapath()
end
function resolvers.registerextrapath(paths,subpaths)
- paths = settings_to_array(paths)
- subpaths = settings_to_array(subpaths)
local ep = instance.extra_paths or { }
local oldn = #ep
local newn = oldn
- local nofpaths = #paths
- local nofsubpaths = #subpaths
- if nofpaths > 0 then
- if nofsubpaths > 0 then
- for i=1,nofpaths do
- local p = paths[i]
- for j=1,nofsubpaths do
- local s = subpaths[j]
+ if paths and paths ~= "" then
+ if subpaths and subpaths ~= "" then
+ for p in gmatch(paths,"[^,]+") do
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
local ps = p .. "/" .. s
if not done[ps] then
newn = newn + 1
@@ -13788,8 +13058,7 @@ function resolvers.registerextrapath(paths,subpaths)
end
end
else
- for i=1,nofpaths do
- local p = paths[i]
+ for p in gmatch(paths,"[^,]+") do
if not done[p] then
newn = newn + 1
ep[newn] = resolvers.cleanpath(p)
@@ -13797,10 +13066,10 @@ function resolvers.registerextrapath(paths,subpaths)
end
end
end
- elseif nofsubpaths > 0 then
+ elseif subpaths and subpaths ~= "" then
for i=1,oldn do
- for j=1,nofsubpaths do
- local s = subpaths[j]
+ -- we gmatch each step again, not that fast, but used seldom
+ for s in gmatch(subpaths,"[^,]+") do
local ps = ep[i] .. "/" .. s
if not done[ps] then
newn = newn + 1
@@ -13878,21 +13147,18 @@ function resolvers.expandedpathlist(str)
return { }
elseif instance.savelists then
str = lpegmatch(dollarstripper,str)
- local lists = instance.lists
- local lst = lists[str]
- if not lst then
- local l = made_list(instance,resolvers.splitpath(resolvers.expansion(str)))
- lst = expandedpathfromlist(l)
- lists[str] = lst
- end
- return lst
+ if not instance.lists[str] then -- cached
+ local lst = made_list(instance,resolvers.splitpath(resolvers.expansion(str)))
+ instance.lists[str] = expandedpathfromlist(lst)
+ end
+ return instance.lists[str]
else
local lst = resolvers.splitpath(resolvers.expansion(str))
return made_list(instance,expandedpathfromlist(lst))
end
end
-function resolvers.expandedpathlistfromvariable(str) -- brrr / could also have cleaner ^!! /$ //
+function resolvers.expandedpathlistfromvariable(str) -- brrr
str = lpegmatch(dollarstripper,str)
local tmp = resolvers.variableofformatorsuffix(str)
return resolvers.expandedpathlist(tmp ~= "" and tmp or str)
@@ -14049,7 +13315,7 @@ local preparetreepattern = Cs((P(".")/"%%." + P("-")/"%%-" + P(1))^0 * Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype, wantedfiles, ext = '', { }, suffixonly(filename)
+ local filetype, wantedfiles, ext = '', { }, fileextname(filename)
-- too tricky as filename can be bla.1.2.3:
--
-- if not suffixmap[ext] then
@@ -14127,7 +13393,7 @@ local function find_qualified(filename,allresults) -- this one will be split too
if trace_detail then
report_resolving("locating qualified file '%s'", filename)
end
- local forcedname, suffix = "", suffixonly(filename)
+ local forcedname, suffix = "", fileextname(filename)
if suffix == "" then -- why
local format_suffixes = askedformat == "" and resolvers.defaultsuffixes or suffixes[askedformat]
if format_suffixes then
@@ -14797,8 +14063,6 @@ local gsub = string.gsub
local cleanpath, findgivenfile, expansion = resolvers.cleanpath, resolvers.findgivenfile, resolvers.expansion
local getenv = resolvers.getenv -- we can probably also use resolvers.expansion
local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
-local joinpath, basename, dirname = file.join, file.basename, file.dirname
-local getmetatable, rawset, type = getmetatable, rawset, type
-- getenv = function(...) return resolvers.getenv(...) end -- needs checking (definitions changes later on)
@@ -14840,43 +14104,28 @@ end
prefixes.filename = function(str)
local fullname = findgivenfile(str) or ""
- return cleanpath(basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
+ return cleanpath(file.basename((fullname ~= "" and fullname) or str)) -- no cleanpath needed here
end
prefixes.pathname = function(str)
local fullname = findgivenfile(str) or ""
- return cleanpath(dirname((fullname ~= "" and fullname) or str))
+ return cleanpath(file.dirname((fullname ~= "" and fullname) or str))
end
prefixes.selfautoloc = function(str)
- return cleanpath(joinpath(getenv('SELFAUTOLOC'),str))
+ return cleanpath(file.join(getenv('SELFAUTOLOC'),str))
end
prefixes.selfautoparent = function(str)
- return cleanpath(joinpath(getenv('SELFAUTOPARENT'),str))
+ return cleanpath(file.join(getenv('SELFAUTOPARENT'),str))
end
prefixes.selfautodir = function(str)
- return cleanpath(joinpath(getenv('SELFAUTODIR'),str))
+ return cleanpath(file.join(getenv('SELFAUTODIR'),str))
end
prefixes.home = function(str)
- return cleanpath(joinpath(getenv('HOME'),str))
-end
-
-local function toppath()
- local pathname = dirname(inputstack[#inputstack] or "")
- if pathname == "" then
- return "."
- else
- return pathname
- end
-end
-
-resolvers.toppath = toppath
-
-prefixes.toppath = function(str)
- return cleanpath(joinpath(toppath(),str))
+ return cleanpath(file.join(getenv('HOME'),str))
end
prefixes.env = prefixes.environment
@@ -14912,8 +14161,6 @@ function resolvers.resetresolve(str)
resolved, abstract = { }, { }
end
--- todo: use an lpeg (see data-lua for !! / stripper)
-
local function resolve(str) -- use schemes, this one is then for the commandline only
if type(str) == "table" then
local t = { }
@@ -14939,7 +14186,7 @@ end
resolvers.resolve = resolve
resolvers.unresolve = unresolve
-if type(os.uname) == "function" then
+if os.uname then
for k, v in next, os.uname() do
if not prefixes[k] then
@@ -14951,17 +14198,11 @@ end
if os.type == "unix" then
- -- We need to distringuish between a prefix and something else : so we
- -- have a special repath variant for linux. Also, when a new prefix is
- -- defined, we need to remake the matcher.
-
local pattern
local function makepattern(t,k,v)
- if t then
- rawset(t,k,v)
- end
local colon = P(":")
+ local p
for k, v in table.sortedpairs(prefixes) do
if p then
p = P(k) + p
@@ -14970,6 +14211,9 @@ if os.type == "unix" then
end
end
pattern = Cs((p * colon + colon/";" + P(1))^0)
+ if t then
+ t[k] = v
+ end
end
makepattern()
@@ -15180,7 +14424,18 @@ local trace_cache = false trackers.register("resolvers.cache", functi
local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
+--[[ldx--
+
Once we found ourselves defining similar cache constructs
+several times, containers were introduced. Containers are used
+to collect tables in memory and reuse them when possible based
+on (unique) hashes (to be provided by the calling function).
+
+
Caching to disk is disabled by default. Version numbers are
+stored in the saved table which makes it possible to change the
+table structures without bothering about the disk cache.
+
Examples of usage can be found in the font related code.
+--ldx]]--
containers = containers or { }
local containers = containers
@@ -15415,7 +14670,11 @@ local trace_locating = false trackers.register("resolvers.locating", function(v
local report_zip = logs.reporter("resolvers","zip")
-
+-- zip:///oeps.zip?name=bla/bla.tex
+-- zip:///oeps.zip?tree=tex/texmf-local
+-- zip:///texmf.zip?tree=/tex/texmf
+-- zip:///texmf.zip?tree=/tex/texmf-local
+-- zip:///texmf-mine.zip?tree=/tex/texmf-projects
local resolvers = resolvers
@@ -15740,7 +14999,7 @@ end -- of closure
do -- create closure to overcome 200 locals limit
-if not modules then modules = { } end modules ['data-sch'] = {
+if not modules then modules = { } end modules ['data-crl'] = {
version = 1.001,
comment = "companion to luat-lib.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -15748,199 +15007,60 @@ if not modules then modules = { } end modules ['data-sch'] = {
license = "see context related readme files"
}
-local loadstring = loadstring
-local gsub, concat, format = string.gsub, table.concat, string.format
-local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
-
-local trace_schemes = false trackers.register("resolvers.schemes",function(v) trace_schemes = v end)
-local report_schemes = logs.reporter("resolvers","schemes")
-
-local http = require("socket.http")
-local ltn12 = require("ltn12")
+-- this one is replaced by data-sch.lua --
-local resolvers = resolvers
-local schemes = resolvers.schemes or { }
-resolvers.schemes = schemes
-
-local cleaners = { }
-schemes.cleaners = cleaners
-
-local threshold = 24 * 60 * 60
-
-directives.register("schemes.threshold", function(v) threshold = tonumber(v) or threshold end)
-
-function cleaners.none(specification)
- return specification.original
-end
-
-function cleaners.strip(specification)
- return (gsub(specification.original,"[^%a%d%.]+","-")) -- so we keep periods
-end
-
-function cleaners.md5(specification)
- return file.addsuffix(md5.hex(specification.original),file.suffix(specification.path))
-end
-
-local cleaner = cleaners.strip
+local gsub = string.gsub
-directives.register("schemes.cleanmethod", function(v) cleaner = cleaners[v] or cleaners.strip end)
+local resolvers = resolvers
-function resolvers.schemes.cleanname(specification)
- local hash = cleaner(specification)
- if trace_schemes then
- report_schemes("hashing %s to %s",specification.original,hash)
- end
- return hash
-end
+local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders
-local cached, loaded, reused, thresholds, handlers = { }, { }, { }, { }, { }
+resolvers.curl = resolvers.curl or { }
+local curl = resolvers.curl
-local function runcurl(name,cachename) -- we use sockets instead or the curl library when possible
- local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name
- os.spawn(command)
-end
+local cached = { }
-local function fetch(specification)
+local function runcurl(specification)
local original = specification.original
- local scheme = specification.scheme
- local cleanname = schemes.cleanname(specification)
- local cachename = caches.setfirstwritablefile(cleanname,"schemes")
+ -- local scheme = specification.scheme
+ local cleanname = gsub(original,"[^%a%d%.]+","-")
+ local cachename = caches.setfirstwritablefile(cleanname,"curl")
if not cached[original] then
- statistics.starttiming(schemes)
- if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification) > (thresholds[protocol] or threshold)) then
+ if not io.exists(cachename) then
cached[original] = cachename
- local handler = handlers[scheme]
- if handler then
- if trace_schemes then
- report_schemes("fetching '%s', protocol '%s', method 'built-in'",original,scheme)
- end
- logs.flush()
- handler(specification,cachename)
- else
- if trace_schemes then
- report_schemes("fetching '%s', protocol '%s', method 'curl'",original,scheme)
- end
- logs.flush()
- runcurl(original,cachename)
- end
+ local command = "curl --silent --create-dirs --output " .. cachename .. " " .. original
+ os.spawn(command)
end
if io.exists(cachename) then
cached[original] = cachename
- if trace_schemes then
- report_schemes("using cached '%s', protocol '%s', cachename '%s'",original,scheme,cachename)
- end
else
cached[original] = ""
- if trace_schemes then
- report_schemes("using missing '%s', protocol '%s'",original,scheme)
- end
end
- loaded[scheme] = loaded[scheme] + 1
- statistics.stoptiming(schemes)
- else
- if trace_schemes then
- report_schemes("reusing '%s', protocol '%s'",original,scheme)
- end
- reused[scheme] = reused[scheme] + 1
end
return cached[original]
end
+-- old code: we could be cleaner using specification (see schemes)
+
local function finder(specification,filetype)
- return resolvers.methodhandler("finders",fetch(specification),filetype)
+ return resolvers.methodhandler("finders",runcurl(specification),filetype)
end
local opener = openers.file
local loader = loaders.file
-local function install(scheme,handler,newthreshold)
- handlers [scheme] = handler
- loaded [scheme] = 0
- reused [scheme] = 0
- finders [scheme] = finder
- openers [scheme] = opener
- loaders [scheme] = loader
- thresholds[scheme] = newthreshold or threshold
+local function install(scheme)
+ finders[scheme] = finder
+ openers[scheme] = opener
+ loaders[scheme] = loader
end
-schemes.install = install
-
-local function http_handler(specification,cachename)
- local tempname = cachename .. ".tmp"
- local f = io.open(tempname,"wb")
- local status, message = http.request {
- url = specification.original,
- sink = ltn12.sink.file(f)
- }
- if not status then
- os.remove(tempname)
- else
- os.remove(cachename)
- os.rename(tempname,cachename)
- end
- return cachename
-end
+resolvers.curl.install = install
-install('http',http_handler)
-install('https') -- see pod
+install('http')
+install('https')
install('ftp')
-statistics.register("scheme handling time", function()
- local l, r, nl, nr = { }, { }, 0, 0
- for k, v in table.sortedhash(loaded) do
- if v > 0 then
- nl = nl + 1
- l[nl] = k .. ":" .. v
- end
- end
- for k, v in table.sortedhash(reused) do
- if v > 0 then
- nr = nr + 1
- r[nr] = k .. ":" .. v
- end
- end
- local n = nl + nr
- if n > 0 then
- l = nl > 0 and concat(l) or "none"
- r = nr > 0 and concat(r) or "none"
- return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s",
- statistics.elapsedtime(schemes), n, threshold, l, r)
- else
- return nil
- end
-end)
-
--- We provide a few more helpers:
-
------ http = require("socket.http")
-local httprequest = http.request
-local toquery = url.toquery
-
--- local function httprequest(url)
--- return os.resultof(format("curl --silent %q", url))
--- end
-
-local function fetchstring(url,data)
- local q = data and toquery(data)
- if q then
- url = url .. "?" .. q
- end
- local reply = httprequest(url)
- return reply -- just one argument
-end
-
-schemes.fetchstring = fetchstring
-
-function schemes.fetchtable(url,data)
- local reply = fetchstring(url,data)
- if reply then
- local s = loadstring("return " .. reply)
- if s then
- return s()
- end
- end
-end
-
end -- of closure
@@ -15954,199 +15074,170 @@ if not modules then modules = { } end modules ['data-lua'] = {
license = "see context related readme files"
}
--- We overload the regular loader. We do so because we operate mostly in
--- tds and use our own loader code. Alternatively we could use a more
--- extensive definition of package.path and package.cpath but even then
--- we're not done. Also, we now have better tracing.
---
--- -- local mylib = require("libtest")
--- -- local mysql = require("luasql.mysql")
-
-local concat = table.concat
-
-local trace_libraries = false
+-- some loading stuff ... we might move this one to slot 2 depending
+-- on the developments (the loaders must not trigger kpse); we could
+-- of course use a more extensive lib path spec
-trackers.register("resolvers.libraries", function(v) trace_libraries = v end)
-trackers.register("resolvers.locating", function(v) trace_libraries = v end)
+local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
local report_libraries = logs.reporter("resolvers","libraries")
local gsub, insert = string.gsub, table.insert
-local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
local unpack = unpack or table.unpack
-local is_readable = file.is_readable
local resolvers, package = resolvers, package
-local libsuffixes = { 'tex', 'lua' }
-local clibsuffixes = { 'lib' }
-local libformats = { 'TEXINPUTS', 'LUAINPUTS' }
-local clibformats = { 'CLUAINPUTS' }
-
-local libpaths = nil
-local clibpaths = nil
-local libhash = { }
-local clibhash = { }
-local libextras = { }
-local clibextras = { }
-
-local pattern = Cs(P("!")^0 / "" * (P("/") * P(-1) / "/" + P("/")^1 / "/" + 1)^0)
-
-local function cleanpath(path) --hm, don't we have a helper for this?
- return resolvers.resolve(lpegmatch(pattern,path))
-end
-
-local function getlibpaths()
- if not libpaths then
- libpaths = { }
- for i=1,#libformats do
- local paths = resolvers.expandedpathlistfromvariable(libformats[i])
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not libhash[path] then
- libpaths[#libpaths+1] = path
- libhash[path] = true
- end
- end
- end
+local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs'
+local clibformats = { 'lib' }
+
+local _path_, libpaths, _cpath_, clibpaths
+
+function package.libpaths()
+ if not _path_ or package.path ~= _path_ then
+ _path_ = package.path
+ libpaths = file.splitpath(_path_,";")
end
return libpaths
end
-local function getclibpaths()
- if not clibpaths then
- clibpaths = { }
- for i=1,#clibformats do
- local paths = resolvers.expandedpathlistfromvariable(clibformats[i])
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not clibhash[path] then
- clibpaths[#clibpaths+1] = path
- clibhash[path] = true
- end
- end
- end
+function package.clibpaths()
+ if not _cpath_ or package.cpath ~= _cpath_ then
+ _cpath_ = package.cpath
+ clibpaths = file.splitpath(_cpath_,";")
end
return clibpaths
end
-package.libpaths = getlibpaths
-package.clibpaths = getclibpaths
-
-function package.extralibpath(...)
- local paths = { ... }
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not libhash[path] then
- if trace_libraries then
- report_libraries("! extra lua path '%s'",path)
- end
- libextras[#libextras+1] = path
- libpaths[#libpaths +1] = path
- end
+local function thepath(...)
+ local t = { ... } t[#t+1] = "?.lua"
+ local path = file.join(unpack(t))
+ if trace_locating then
+ report_libraries("! appending '%s' to 'package.path'",path)
end
+ return path
end
-function package.extraclibpath(...)
- local paths = { ... }
- for i=1,#paths do
- local path = cleanpath(paths[i])
- if not clibhash[path] then
- if trace_libraries then
- report_libraries("! extra lib path '%s'",path)
- end
- clibextras[#clibextras+1] = path
- clibpaths[#clibpaths +1] = path
- end
- end
-end
+local p_libpaths, a_libpaths = { }, { }
-if not package.loaders[-2] then
- -- use package-path and package-cpath
- package.loaders[-2] = package.loaders[2]
+function package.appendtolibpath(...)
+ insert(a_libpath,thepath(...))
end
-local function loadedaslib(resolved,rawname)
- return package.loadlib(resolved,"luaopen_" .. gsub(rawname,"%.","_"))
+function package.prependtolibpath(...)
+ insert(p_libpaths,1,thepath(...))
end
-local function loadedbylua(name)
- if trace_libraries then
- report_libraries("! locating %q using normal loader",name)
+-- beware, we need to return a loadfile result !
+
+local function loaded(libpaths,name,simple)
+ for i=1,#libpaths do -- package.path, might become option
+ local libpath = libpaths[i]
+ local resolved = gsub(libpath,"%?",simple)
+ if trace_locating then -- more detail
+ report_libraries("! checking for '%s' on 'package.path': '%s' => '%s'",simple,libpath,resolved)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'package.path': '%s'",name,resolved)
+ end
+ return loadfile(resolved)
+ end
end
- local resolved = package.loaders[-2](name)
end
-local function loadedbyformat(name,rawname,suffixes,islib)
- if trace_libraries then
- report_libraries("! locating %q as %q using formats %q",rawname,name,concat(suffixes))
+package.loaders[2] = function(name) -- was [#package.loaders+1]
+ if file.suffix(name) == "" then
+ name = file.addsuffix(name,"lua") -- maybe a list
+ if trace_locating then -- mode detail
+ report_libraries("! locating '%s' with forced suffix",name)
+ end
+ else
+ if trace_locating then -- mode detail
+ report_libraries("! locating '%s'",name)
+ end
end
- for i=1,#suffixes do -- so we use findfile and not a lookup loop
- local format = suffixes[i]
+ for i=1,#libformats do
+ local format = libformats[i]
local resolved = resolvers.findfile(name,format) or ""
- if trace_libraries then
- report_libraries("! checking for %q' using format %q",name,format)
+ if trace_locating then -- mode detail
+ report_libraries("! checking for '%s' using 'libformat path': '%s'",name,format)
end
if resolved ~= "" then
- if trace_libraries then
- report_libraries("! lib %q located on %q",name,resolved)
- end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
+ if trace_locating then
+ report_libraries("! lib '%s' located via environment: '%s'",name,resolved)
end
+ return loadfile(resolved)
end
end
-end
-
-local function loadedbypath(name,rawname,paths,islib,what)
- if trace_libraries then
- report_libraries("! locating %q as %q on %q paths",rawname,name,what)
+ -- libpaths
+ local libpaths, clibpaths = package.libpaths(), package.clibpaths()
+ local simple = gsub(name,"%.lua$","")
+ local simple = gsub(simple,"%.","/")
+ local resolved = loaded(p_libpaths,name,simple) or loaded(libpaths,name,simple) or loaded(a_libpaths,name,simple)
+ if resolved then
+ return resolved
end
- for p=1,#paths do
- local path = paths[p]
- local resolved = file.join(path,name)
- if trace_libraries then -- mode detail
- report_libraries("! checking for %q using %q path %q",name,what,path)
- end
- if is_readable(resolved) then
- if trace_libraries then
- report_libraries("! lib %q located on %q",name,resolved)
+ --
+ local libname = file.addsuffix(simple,os.libsuffix)
+ for i=1,#clibformats do
+ -- better have a dedicated loop
+ local format = clibformats[i]
+ local paths = resolvers.expandedpathlistfromvariable(format)
+ for p=1,#paths do
+ local path = paths[p]
+ local resolved = file.join(path,libname)
+ if trace_locating then -- mode detail
+ report_libraries("! checking for '%s' using 'clibformat path': '%s'",libname,path)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'clibformat': '%s'",libname,resolved)
+ end
+ return package.loadlib(resolved,name)
end
- if islib then
- return loadedaslib(resolved,rawname)
- else
- return loadfile(resolved)
+ end
+ end
+ for i=1,#clibpaths do -- package.path, might become option
+ local libpath = clibpaths[i]
+ local resolved = gsub(libpath,"?",simple)
+ if trace_locating then -- more detail
+ report_libraries("! checking for '%s' on 'package.cpath': '%s'",simple,libpath)
+ end
+ if file.is_readable(resolved) then
+ if trace_locating then
+ report_libraries("! lib '%s' located via 'package.cpath': '%s'",name,resolved)
end
+ return package.loadlib(resolved,name)
end
end
-end
-
-local function notloaded(name)
- if trace_libraries then
- report_libraries("? unable to locate library %q",name)
+ -- just in case the distribution is messed up
+ if trace_loading then -- more detail
+ report_libraries("! checking for '%s' using 'luatexlibs': '%s'",name)
+ end
+ local resolved = resolvers.findfile(file.basename(name),'luatexlibs') or ""
+ if resolved ~= "" then
+ if trace_locating then
+ report_libraries("! lib '%s' located by basename via environment: '%s'",name,resolved)
+ end
+ return loadfile(resolved)
+ end
+ if trace_locating then
+ report_libraries('? unable to locate lib: %s',name)
end
+-- return "unable to locate " .. name
end
-package.loaders[2] = function(name)
- local thename = gsub(name,"%.","/")
- local luaname = file.addsuffix(thename,"lua")
- local libname = file.addsuffix(thename,os.libsuffix)
- return
- loadedbyformat(luaname,name,libsuffixes, false)
- or loadedbyformat(libname,name,clibsuffixes, true)
- or loadedbypath (luaname,name,getlibpaths (),false,"lua")
- or loadedbypath (luaname,name,getclibpaths(),false,"lua")
- or loadedbypath (libname,name,getclibpaths(),true, "lib")
- or loadedbylua (name)
- or notloaded (name)
-end
+resolvers.loadlualib = require
--- package.loaders[3] = nil
--- package.loaders[4] = nil
+-- -- -- --
-resolvers.loadlualib = require
+package.obsolete = package.obsolete or { }
+
+package.append_libpath = appendtolibpath -- will become obsolete
+package.prepend_libpath = prependtolibpath -- will become obsolete
+
+package.obsolete.append_libpath = appendtolibpath -- will become obsolete
+package.obsolete.prepend_libpath = prependtolibpath -- will become obsolete
end -- of closure
@@ -16616,6 +15707,7 @@ function environment.make_format(name)
end
function environment.run_format(name,data,more)
+ -- hm, rather old code here; we can now use the file.whatever functions
if name and name ~= "" then
local barename = file.removesuffix(name)
local fmtname = caches.getfirstreadablefile(file.addsuffix(barename,"fmt"),"formats")
@@ -16644,129 +15736,6 @@ function environment.run_format(name,data,more)
end
-end -- of closure
-
-do -- create closure to overcome 200 locals limit
-
-if not modules then modules = { } end modules ['util-tpl'] = {
- 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"
-}
-
--- This is experimental code. Coming from dos and windows, I've always used %whatever%
--- as template variables so let's stick to it. After all, it's easy to parse and stands
--- out well. A double %% is turned into a regular %.
-
-utilities.templates = utilities.templates or { }
-local templates = utilities.templates
-
-local trace_template = false trackers.register("templates.trace",function(v) trace_template = v end)
-local report_template = logs.reporter("template")
-
-local format = string.format
-local P, C, Cs, Carg, lpegmatch = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Carg, lpeg.match
-
--- todo: make installable template.new
-
-local replacer
-
-local function replacekey(k,t,recursive)
- local v = t[k]
- if not v then
- if trace_template then
- report_template("unknown key %q",k)
- end
- return ""
- else
- if trace_template then
- report_template("setting key %q to value %q",k,v)
- end
- if recursive then
- return lpegmatch(replacer,v,1,t)
- else
- return v
- end
- end
-end
-
-local sqlescape = lpeg.replacer {
- { "'", "''" },
- { "\\", "\\\\" },
- { "\r\n", "\\n" },
- { "\r", "\\n" },
- -- { "\t", "\\t" },
-}
-
-local escapers = {
- lua = function(s)
- return format("%q",s)
- end,
- sql = function(s)
- return lpegmatch(sqlescape,s)
- end,
-}
-
-local function replacekeyunquoted(s,t,how,recurse) -- ".. \" "
- local escaper = how and escapers[how] or escapers.lua
- return escaper(replacekey(s,t,recurse))
-end
-
-local single = P("%") -- test %test% test : resolves test
-local double = P("%%") -- test 10%% test : %% becomes %
-local lquoted = P("%[") -- test %[test]" test : resolves test with escaped "'s
-local rquoted = P("]%") --
-
-local escape = double / '%%'
-local nosingle = single / ''
-local nodouble = double / ''
-local nolquoted = lquoted / ''
-local norquoted = rquoted / ''
-
-local key = nosingle * (C((1-nosingle)^1 * Carg(1) * Carg(2) * Carg(3))/replacekey) * nosingle
-local unquoted = nolquoted * ((C((1 - norquoted)^1) * Carg(1) * Carg(2) * Carg(3))/replacekeyunquoted) * norquoted
-local any = P(1)
-
- replacer = Cs((unquoted + escape + key + any)^0)
-
-local function replace(str,mapping,how,recurse)
- if mapping then
- return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
- else
- return str
- end
-end
-
--- print(replace("test '%[x]%' test",{ x = [[a 'x' a]] }))
--- print(replace("test '%[x]%' test",{ x = [[a 'x' a]] },'sql'))
-
-templates.replace = replace
-
-function templates.load(filename,mapping,how,recurse)
- local data = io.loaddata(filename) or ""
- if mapping and next(mapping) then
- return replace(data,mapping,how,recurse)
- else
- return data
- end
-end
-
-function templates.resolve(t,mapping,how,recurse)
- if not mapping then
- mapping = t
- end
- for k, v in next, t do
- t[k] = replace(v,mapping,how,recurse)
- end
- return t
-end
-
--- inspect(utilities.templates.replace("test %one% test", { one = "%two%", two = "two" }))
--- inspect(utilities.templates.resolve({ one = "%two%", two = "two", three = "%three%" }))
-
-
end -- of closure
-- end library merge
@@ -16827,7 +15796,7 @@ own.libs = { -- order can be made better
-- 'data-bin.lua',
'data-zip.lua',
'data-tre.lua',
- 'data-sch.lua',
+ 'data-crl.lua',
'data-lua.lua',
'data-aux.lua', -- updater
'data-tmf.lua',
@@ -16835,8 +15804,6 @@ own.libs = { -- order can be made better
'luat-sta.lua',
'luat-fmt.lua',
-
- 'util-tpl.lua',
}
-- We need this hack till luatex is fixed.
@@ -16857,7 +15824,7 @@ own.path = gsub(match(own.name,"^(.+)[\\/].-$") or ".","\\","/")
local ownpath, owntree = own.path, environment and environment.ownpath or own.path
-own.list = { -- predictable paths
+own.list = {
'.',
ownpath ,
ownpath .. "/../sources", -- HH's development path
@@ -16881,7 +15848,7 @@ local function locate_libs()
local filename = pth .. "/" .. lib
local found = lfs.isfile(filename)
if found then
- package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require (probably obsolete)
+ package.path = package.path .. ";" .. pth .. "/?.lua" -- in case l-* does a require
return pth
end
end
@@ -17013,7 +15980,6 @@ local helpinfo = [[
--var-value report value of variable
--find-file report file location
--find-path report path of file
---show-package-path report package paths
--pattern=str filter variables
]]
@@ -17127,8 +16093,7 @@ function runners.execute_script(fullname,internal,nosplit)
elseif state == 'skip' then
return true
elseif state == "run" then
- local path, name, suffix = file.splitname(fullname)
- local result = ""
+ local path, name, suffix, result = file.dirname(fullname), file.basename(fullname), file.extname(fullname), ""
if path ~= "" then
result = fullname
elseif name then
@@ -17139,7 +16104,7 @@ function runners.execute_script(fullname,internal,nosplit)
name = gsub(name,"^script:","")
if suffix == "" and runners.registered[name] and runners.registered[name][1] then
name = runners.registered[name][1]
- suffix = file.suffix(name)
+ suffix = file.extname(name)
end
if suffix == "" then
-- loop over known suffixes
@@ -17166,7 +16131,7 @@ function runners.execute_script(fullname,internal,nosplit)
environment.ownscript = result
dofile(result)
else
- local binary = runners.applications[file.suffix(result)]
+ local binary = runners.applications[file.extname(result)]
result = string.quoted(string.unquoted(result))
-- if string.match(result,' ') and not string.match(result,"^\".*\"$") then
-- result = '"' .. result .. '"'
@@ -17359,7 +16324,7 @@ function resolvers.launch(str)
-- maybe we also need to test on mtxrun.launcher.suffix environment
-- variable or on windows consult the assoc and ftype vars and such
local launchers = runners.launchers[os.platform] if launchers then
- local suffix = file.suffix(str) if suffix then
+ local suffix = file.extname(str) if suffix then
local runner = launchers[suffix] if runner then
str = runner .. " " .. str
end
@@ -17418,7 +16383,7 @@ function runners.find_mtx_script(filename)
end
filename = file.addsuffix(filename,"lua")
local basename = file.removesuffix(file.basename(filename))
- local suffix = file.suffix(filename)
+ local suffix = file.extname(filename)
-- qualified path, raw name
local fullname = file.is_qualified_path(filename) and io.exists(filename) and filename
if fullname and fullname ~= "" then
@@ -17473,7 +16438,7 @@ function runners.execute_ctx_script(filename,...)
runners.register_arguments(...)
local arguments = environment.arguments_after
local fullname = runners.find_mtx_script(filename) or ""
- if file.suffix(fullname) == "cld" then
+ if file.extname(fullname) == "cld" then
-- handy in editors where we force --autopdf
report("running cld script: %s",filename)
table.insert(arguments,1,fullname)
@@ -17581,21 +16546,6 @@ function runners.timed(action)
statistics.timed(action)
end
-function runners.associate(filename)
- os.launch(filename)
-end
-
-function runners.gethelp(filename)
- local url = environment.argument("url")
- if url and url ~= "" then
- local command = string.gsub(environment.argument("command") or "unknown","^%s*\\*(.-)%s*$","%1")
- url = utilities.templates.replace(url,{ command = command })
- os.launch(url)
- else
- report("no --url given")
- end
-end
-
-- this is a bit dirty ... first we store the first filename and next we
-- split the arguments so that we only see the ones meant for this script
-- ... later we will use the second half
@@ -17698,18 +16648,7 @@ else
end
-if e_argument("script") or e_argument("scripts") then
-
- -- run a script by loading it (using libs), pass args
-
- runners.loadbase()
- if is_mkii_stub then
- ok = runners.execute_script(filename,false,true)
- else
- ok = runners.execute_ctx_script(filename)
- end
-
-elseif e_argument("selfmerge") then
+if e_argument("selfmerge") then
-- embed used libraries
@@ -17732,19 +16671,6 @@ elseif e_argument("selfupdate") then
trackers.enable("resolvers.locating")
resolvers.updatescript(own.name,"mtxrun")
-elseif e_argument("show-package-path") or e_argument("show-package-paths") then
-
- local l = package.libpaths()
- local c = package.clibpaths()
-
- for i=1,#l do
- report("package lib path %s: %s",i,l[i])
- end
-
- for i=1,#c do
- report("package clib path %s: %s",i,c[i])
- end
-
elseif e_argument("ctxlua") or e_argument("internal") then
-- run a script by loading it (using libs)
@@ -17752,6 +16678,17 @@ elseif e_argument("ctxlua") or e_argument("internal") then
runners.loadbase()
ok = runners.execute_script(filename,true)
+elseif e_argument("script") or e_argument("scripts") then
+
+ -- run a script by loading it (using libs), pass args
+
+ runners.loadbase()
+ if is_mkii_stub then
+ ok = runners.execute_script(filename,false,true)
+ else
+ ok = runners.execute_ctx_script(filename)
+ end
+
elseif e_argument("execute") then
-- execute script
@@ -17778,14 +16715,6 @@ elseif e_argument("launch") then
runners.loadbase()
runners.launch_file(filename)
-elseif e_argument("associate") then
-
- runners.associate(filename)
-
-elseif e_argument("gethelp") then
-
- runners.gethelp()
-
elseif e_argument("makestubs") then
-- make stubs (depricated)
@@ -17877,7 +16806,7 @@ elseif e_argument("find-path") then
elseif e_argument("expand-braces") then
- -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename)
+ -- luatools: runners.execute_ctx_script("mtx-base","--expand-braces",filename
resolvers.load("nofiles")
runners.register_arguments(filename)
diff --git a/tex/context/base/anch-bar.mkiv b/tex/context/base/anch-bar.mkiv
index c7c6190be..9f9770fb6 100644
--- a/tex/context/base/anch-bar.mkiv
+++ b/tex/context/base/anch-bar.mkiv
@@ -58,9 +58,7 @@
\installcommandhandler \??sidebar {sidebar} \??sidebar
\newcount\c_anch_sidebars_n
-\newcount\c_anch_sidebars_current % local
-\newdimen\d_anch_sidebars_distance
-\newcount\c_anch_sidebars_level
+\newdimen\c_anch_sidebars_distance
% \setupMPvariables
% [mpos:sidebar]
@@ -69,60 +67,24 @@
% distance=5pt]
\setupsidebar
- [\c!rulethickness=\dimexpr\bodyfontsize/6\relax, % 2pt default
+ [\c!rulethickness=2pt,
\c!rulecolor=\s!black,
\c!alternative=0,
- \c!topoffset=\zeropoint,
- \c!bottomoffset=\zeropoint,
- \c!distance=.5\bodyfontsize,
- \c!level=,
- \c!leftmargindistance=\zeropoint]
+ \c!topoffset=0pt,
+ \c!bottomoffset=0pt,
+ \c!distance=.5\bodyfontsize]
\let\setupsidebars\setupsidebar
\unexpanded\def\startsidebar
{\dosingleempty\anch_sidebars_start}
-\unexpanded\def\startsidebar
- {\dodoubleempty\anch_sidebars_start}
-
-\def\anch_sidebars_start[#1][#2]%
+\def\anch_sidebars_start[#1]%
{\bgroup
+ \def\currentsidebar{#1}%
\dontleavehmode
- \advance\c_anch_sidebars_level\plusone
\global\advance\c_anch_sidebars_n\plusone
- \c_anch_sidebars_current\c_anch_sidebars_n\relax % relax needed
- \doifassignmentelse{#1}
- {\edef\currentsidebar{\the\c_anch_sidebars_level}%
- \checksidebarparent
- \setupcurrentsidebar[#1]}
- {\def\currentsidebar{#1}%
- \setupcurrentsidebar[#2]}%
- \scratchdistance\sidebarparameter\c!distance\relax
- \edef\m_level{\sidebarparameter\c!level}%
- \ifx\m_level\empty
- \ifnum\c_anch_sidebars_level=\plusone
- \scratchdimen\sidebarparameter\c!leftmargindistance\relax
- \ifdim\scratchdimen=\zeropoint
- \advance\d_anch_sidebars_distance\scratchdistance\relax
- \else
- \d_anch_sidebars_distance\scratchdimen
- \fi
- \else
- \advance\d_anch_sidebars_distance\scratchdistance\relax
- \fi
- \else
- \ifnum\m_level=\plusone
- \scratchdimen\sidebarparameter\c!leftmargindistance\relax
- \ifdim\scratchdimen=\zeropoint
- \advance\d_anch_sidebars_distance\scratchdistance\relax
- \else
- \d_anch_sidebars_distance\scratchdimen
- \fi
- \else
- \d_anch_sidebars_distance\dimexpr\scratchdimen+\numexpr\m_level-\plusone\relax\dimexpr\scratchdistance\relax\relax
- \fi
- \fi
+ \advance\c_anch_sidebars_distance\sidebarparameter\c!distance
\startpositionoverlay{text-1}%
\normalexpanded{\setMPpositiongraphicrange % maybe expand in definition
{b:sidebar:\the\c_anch_sidebars_n}%
@@ -132,17 +94,15 @@
linewidth=\sidebarparameter\c!rulethickness,
linecolor=\sidebarparameter\c!rulecolor,
alternative=\sidebarparameter\c!alternative,
- topoffset=\the\dimexpr\sidebarparameter\c!topoffset,
- bottomoffset=\the\dimexpr\sidebarparameter\c!bottomoffset,
- distance=\the\d_anch_sidebars_distance}%
- }%
+ topoffset=\sidebarparameter\c!topoffset,
+ bottomoffset=\sidebarparameter\c!bottomoffset,
+ distance=\the\c_anch_sidebars_distance}}%
\stoppositionoverlay
- \bpos{sidebar:\the\c_anch_sidebars_current}%
- \ignorespaces}
+ \bpos{sidebar:\the\c_anch_sidebars_n}}
\unexpanded\def\stopsidebar
{\removelastspace
- \epos{sidebar:\the\c_anch_sidebars_current}
+ \epos{sidebar:\the\c_anch_sidebars_n}
\carryoverpar\egroup}
%D Let's keep this nice and simple (okay, we could pass the 6 variables in
@@ -161,73 +121,49 @@
\MPpositiongraphic{mpos:sidebar}{}%
\stopMPpositionmethod
-%D We now reimplement the \MKII\ margin rules handler in a more
-%D modern way.
-%D
-%D \setupmarginrules
-%D [rulecolor=darkred,
-%D rulethickness=2pt]
+%D We now reimplement the margin rules handler defined in
+%D \type {core-rul}:
%D
-%D \setupmarginrules % sidebar
-%D [2]
-%D [rulecolor=darkblue]
+%D \setupmarginrules[level=5]
%D
%D \startmarginrule[1]
-%D \input ward
-%D \startmarginrule[2]
-%D \input ward
-%D \startmarginrule[3]
-%D \input ward
-%D \startmarginrule[level=6,rulecolor=darkgreen]
-%D \input ward
-%D \stopmarginrule
-%D \input ward
-%D \stopmarginrule
-%D \input ward
-%D \stopmarginrule
-%D \input ward
+%D First we set the level at~5. Next we typeset this first
+%D paragraph as a level~1 one. As expected no rule show up.
%D \stopmarginrule
%D
-%D Compared to the old mechanism we now can pass settings too.
+%D \startmarginrule[5]
+%D The second paragraph is a level~5 one. As we can see here,
+%D the marginal rule gets a width according to its level.
+%D \stopmarginrule
+%D
+%D \startmarginrule[8]
+%D It will of course be no surprise that this third paragraph
+%D has a even thicker margin rule. This behavior can be
+%D overruled by specifying the width explictly.
+%D \stopmarginrule
\definesidebar
[\v!margin]
- [\c!leftmargindistance=\dimexpr\leftmargindistance+\sidebarparameter\c!rulethickness/2\relax]
+ [\c!rulethickness=\@@karulethickness,
+ \c!distance=\dimexpr\leftmargindistance-\@@karulethickness/2\relax]
-\dorecurse{5}{\definesidebar[\v!margin:#1][\v!margin]} % let's be nice and predefine 5 levels
+\definecomplexorsimple\startmarginrule
-\unexpanded\def\setupmarginrule
- {\dodoubleargument\anch_marginrules_setup}
+\def\simplestartmarginrule
+ {\complexstartmarginrule[1]}
-\def\anch_marginrules_setup[#1][#2]%
- {\ifsecondargument
- \setupsidebar[\v!margin:#1][#2]%
- \else
- \setupsidebar[\v!margin][#1]%
- \fi}
-
-\let\setupmarginrules\setupmarginrule
-
-\unexpanded\def\startmarginrule
- {\dosingleempty\anch_marginrules_start}
-
-\unexpanded\def\startmarginrule
- {\dosingleempty\anch_marginrules_start}
-
-\def\anch_marginrules_start[#1]% pretty inefficient checking
- {\edef\m_anch_marginrules_kind{#1}%
- \ifx\m_anch_marginrules_kind\empty
- \anch_sidebars_start[\v!margin][]%
+\def\complexstartmarginrule[#1]%
+ {\bgroup
+ \ifnum#1<\@@kalevel\relax
+ \let\stopmarginrule\egroup
\else
- \doifassignmentelse\m_anch_marginrules_kind
- {\anch_sidebars_start[\v!margin][#1]}%
- {\anch_marginrules_check{#1}%
- \anch_sidebars_start[\v!margin:#1][\c!level=#1]}%
+ \def\@@kadefaultwidth{#1}%
+ \let\stopmarginrule\dostopmarginrule
+ \normalexpanded{\startsidebar[\v!margin]}% why expanded
\fi}
-\def\anch_marginrules_check#1%
- {\doifnotcommandhandler\??sidebar{\v!margin:#1}{\definesidebar[\v!margin:#1][\v!margin]}}
-
-\let\stopmarginrule\stopsidebar
+\def\dostopmarginrule
+ {\stopsidebar
+ \egroup}
\protect \endinput
diff --git a/tex/context/base/anch-bck.mkvi b/tex/context/base/anch-bck.mkvi
index 79e42dc0a..8ec056468 100644
--- a/tex/context/base/anch-bck.mkvi
+++ b/tex/context/base/anch-bck.mkvi
@@ -276,7 +276,7 @@
\kern\textbackgroundskip\nobreak
\fi \fi
\nobreak
- \vskip-\dimexpr\lineheight+\parskip\relax % problem: we loose the hangindent
+ \vskip-\dimexpr\lineheight+\parskip\relax
\nobreak
\endgroup
\begingroup
@@ -298,7 +298,7 @@
\endgraf % new
\textbackgroundparameter\c!after}
-\unexpanded\def\checkpositionoverlays % overloads \relax in anch-pgr
+\unexpanded\def\checkpositionoverlays
{\ifproductionrun
\enabletextarearegistration
\enablehiddenbackground
@@ -307,7 +307,7 @@
\setuptextbackground
[\c!mp=mpos:region:draw,
- \c!method=mpos:region, % mpos:regionshape
+ \c!method=mpos:region,
\c!state=\v!start,
\c!location=\v!text,
\c!leftoffset=\!!zeropoint, % 1em,
@@ -397,14 +397,6 @@
\includeMPgraphic{mpos:region:anchor} ;
\stopMPpositiongraphic
-\startMPpositiongraphic{mpos:regionshape}{fillcolor,filloffset,linecolor,gridcolor,linewidth,gridwidth,gridshift,lineradius,lineoffset}
- \includeMPgraphic{mpos:region:setup} ;
- \includeMPgraphic{mpos:region:extra} ;
- \MPgetmultishapes{\MPvar{self}}{\MPanchorid} ;
- \includeMPgraphic{\MPvar{mp}} ;
- \includeMPgraphic{mpos:region:anchor} ;
-\stopMPpositiongraphic
-
\startMPpositionmethod{mpos:region}
\MPpositiongraphic{mpos:region}{}%
\stopMPpositionmethod
diff --git a/tex/context/base/anch-pgr.lua b/tex/context/base/anch-pgr.lua
index aba61794b..bf4dcbe02 100644
--- a/tex/context/base/anch-pgr.lua
+++ b/tex/context/base/anch-pgr.lua
@@ -8,8 +8,6 @@ if not modules then modules = { } end modules ['anch-pgr'] = {
-- todo: we need to clean up lists (of previous pages)
-local commands, context = commands, context
-
local format = string.format
local abs = math.abs
local concat, sort = table.concat, table.sort
@@ -49,48 +47,34 @@ end
local eps = 2
-local function add(t,x,y,last,direction)
+local function add(t,x,y,last)
local n = #t
if n == 0 then
t[n+1] = { x, y }
+ elseif n == 1 then
+ local tn = t[1]
+ if abs(tn[1]-x) <= eps or abs(tn[2]-y) <= eps then
+ t[n+1] = { x, y }
+ end
else
+ local tm = t[n-1]
local tn = t[n]
local lx = tn[1]
local ly = tn[2]
- if x == lx and y == ly then
- -- quick skip
- elseif n == 1 then
--- if abs(lx-x) <= eps or abs(ly-y) <= eps then
- if abs(lx-x) > eps or abs(ly-y) > eps then
- t[n+1] = { x, y }
+ if abs(lx-tm[1]) <= eps and abs(lx-x) <= eps then
+ if abs(ly-y) > eps then
+ tn[2] = y
end
- else
- local tm = t[n-1]
- local px = tm[1]
- local py = tm[2]
-if (direction == "down" and y > ly) or (direction == "up" and y < ly) then
- -- move back from too much hang
-else
- if abs(lx-px) <= eps and abs(lx-x) <= eps then
- if abs(ly-y) > eps then
- tn[2] = y
- end
- elseif abs(ly-py) <= eps and abs(ly-y) <= eps then
- if abs(lx-x) > eps then
- tn[1] = x
- end
- elseif not last then
- t[n+1] = { x, y }
+ elseif abs(ly-tm[2]) <= eps and abs(ly-y) <= eps then
+ if abs(lx-x) > eps then
+ tn[1] = x
end
-end
+ elseif not last then
+ t[n+1] = { x, y }
end
end
end
--- local function add(t,x,y,last)
--- t[#t+1] = { x, y }
--- end
-
local function finish(t)
local n = #t
if n > 1 then
@@ -125,103 +109,105 @@ end
-- todo: mark regions and free paragraphs in collected
-local function shapes(r,rx,ry,rw,rh,rd,lytop,lybot,rytop,rybot,obeyhang)
+local function shapes(r,rx,ry,rw,rh,rd,lytop,lybot,rytop,rybot)
-- we assume that we only hang per page and not cross pages
-- which makes sense as hanging is only uses in special cases
--
-- we can remove data as soon as a page is done so we could
-- remember per page and discard areas after each shipout
local leftshape, rightshape
- leftshape = { { rx, rh } } -- spikes get removed so we can start at the edge
- rightshape = { { rw, rh } } -- even if we hang next
- local paragraphs = r.paragraphs
- local extending = false
- if paragraphs then
- for i=1,#paragraphs do
- local p = paragraphs[i]
- local ha = p.ha
- if obeyhang and ha and ha ~= 0 then
- local py = p.y
- local ph = p.h
- local pd = p.d
- local hi = p.hi
- local hang = ha * (ph + pd)
- local py_ph = py + ph
- -- ha < 0 hi < 0 : right top
- -- ha < 0 hi > 0 : left top
- if ha < 0 then
- if hi < 0 then -- right
- add(rightshape,rw, py_ph,"up")
- add(rightshape,rw + hi,py_ph,"up")
- add(rightshape,rw + hi,py_ph + hang,"up")
- add(rightshape,rw, py_ph + hang,"up")
- else
- -- left
- add(leftshape,rx,py_ph,"down")
- add(leftshape,rx + hi,py_ph,"down")
- add(leftshape,rx + hi,py_ph + hang,"down")
- add(leftshape,rx,py_ph + hang,"down")
- end
- else
- -- maybe some day
- end
- extending = true -- false
- else -- we need to clip to the next par
- local ps = p.ps
- if ps then
+-- leftshape = r.leftshape
+-- rightshape = r.rightshape
+-- if not leftshape then
+ leftshape = { { rx, rh } }
+ rightshape = { { rw, rh } }
+ local paragraphs = r.paragraphs
+ local extending = false
+ if paragraphs then
+ for i=1,#paragraphs do
+ local p = paragraphs[i]
+ local ha = p.ha
+ if ha and ha ~= 0 then
local py = p.y
local ph = p.h
local pd = p.d
- local step = ph + pd
- local size = #ps * step
+ local hi = p.hi
+ local hang = ha * (ph + pd)
local py_ph = py + ph
- add(leftshape,rx,py_ph,"up")
- add(rightshape,rw,py_ph,"down")
- for i=1,#ps do
- local p = ps[i]
- local l = p[1]
- local w = p[2]
- add(leftshape,rx + l, py_ph,"up")
- add(rightshape,rx + l + w, py_ph,"down")
- py_ph = py_ph - step
- add(leftshape,rx + l, py_ph,"up")
- add(rightshape,rx + l + w, py_ph,"down")
+ -- ha < 0 hi < 0 : right top
+ -- ha < 0 hi > 0 : left top
+ if ha < 0 then
+ if hi < 0 then -- right
+ add(rightshape,rw , py_ph)
+ add(rightshape,rw + hi, py_ph)
+ add(rightshape,rw + hi, py_ph + hang)
+ add(rightshape,rw , py_ph + hang)
+ else
+ -- left
+ add(leftshape,rx, py_ph)
+ add(leftshape,rx + hi, py_ph)
+ add(leftshape,rx + hi, py_ph + hang)
+ add(leftshape,rx, py_ph + hang)
+ end
+ end
+extending = false
+ else -- we need to clip to the next par
+ local ps = p.ps
+ if ps then
+ local py = p.y
+ local ph = p.h
+ local pd = p.d
+ local step = ph + pd
+ local size = #ps * step
+ local py_ph = py + ph
+ add(leftshape,rx,py_ph)
+ add(rightshape,rw,py_ph)
+ for i=1,#ps do
+ local p = ps[i]
+ local l = p[1]
+ local w = p[2]
+ add(leftshape,rx + l, py_ph)
+ add(rightshape,rx + l + w, py_ph)
+ py_ph = py_ph - step
+ add(leftshape,rx + l, py_ph)
+ add(rightshape,rx + l + w, py_ph)
+ end
+ extending = true
+-- add(left,rx,py_ph)
+-- add(right,rw,py_ph)
+ else
+ if extending then
+ local py = p.y
+ local ph = p.h
+ local pd = p.d
+ local py_ph = py + ph
+ local py_pd = py - pd
+ add(leftshape,leftshape[#leftshape][1],py_ph)
+ add(rightshape,rightshape[#rightshape][1],py_ph)
+ add(leftshape,rx,py_ph)
+ add(rightshape,rw,py_ph)
+extending = false
+ end
end
- extending = true
- elseif extending then
- local py = p.y
- local ph = p.h
- local pd = p.d
- local py_ph = py + ph
- local py_pd = py - pd
- add(leftshape,leftshape[#leftshape][1],py_ph,"up")
- add(rightshape,rightshape[#rightshape][1],py_ph,"down")
- add(leftshape,rx,py_ph,"up") -- shouldn't this be py_pd
- add(rightshape,rw,py_ph,"down") -- shouldn't this be py_pd
- extending = false
end
end
end
- end
- -- we can have a simple variant when no paragraphs
- if extending then
- -- not ok
- leftshape[#leftshape][2] = rd
- rightshape[#rightshape][2] = rw
- else
- add(leftshape,rx,rd,"up")
- add(rightshape,rw,rd,"down")
- end
+ -- we can have a simple variant when no paragraphs
+ if extending then
+ -- not ok
+ leftshape[#leftshape][2] = rd
+ rightshape[#rightshape][2] = rw
+ else
+ add(leftshape,rx,rd)
+ add(rightshape,rw,rd)
+ end
+-- r.leftshape = leftshape
+-- r.rightshape = rightshape
+-- end
return clip(leftshape,lytop,lybot), clip(rightshape,rytop,rybot)
end
--- local function shapes(r,rx,ry,rw,rh,rd,lytop,lybot,rytop,rybot,obeyhang)
--- local leftshape = { { rx, rh }, { rx, rd } }
--- local rightshape = { { rw, rh }, { rw, rd } }
--- return clip(leftshape,lytop,lybot), clip(rightshape,rytop,rybot)
--- end
-
-local function singlepart(b,e,r,left,right,obeyhang)
+local function singlepart(b,e,r,left,right)
local bx, by = b.x, b.y
local ex, ey = e.x, e.y
local rx, ry = r.x, r.y
@@ -252,7 +238,7 @@ local function singlepart(b,e,r,left,right,obeyhang)
}
else
area = { }
- local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,ed,bh,eh,obeyhang)
+ local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,ed,bh,eh)
add(area,bx,bh-ry)
for i=1,#rightshapes do
local ri = rightshapes[i]
@@ -279,7 +265,7 @@ local function singlepart(b,e,r,left,right,obeyhang)
}
end
-local function firstpart(b,r,left,right,obeyhang)
+local function firstpart(b,r,left,right)
local bx, by = b.x, b.y
local rx, ry = r.x, r.y
local rw = rx + r.w
@@ -292,7 +278,7 @@ local function firstpart(b,r,left,right,obeyhang)
local bh = by + b.h
local bd = by - b.d
local area = { }
- local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,rd,bh,rd,obeyhang)
+ local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,bd,rd,bh,rd)
add(area,bx,bh-ry)
for i=1,#rightshapes do
local ri = rightshapes[i]
@@ -316,7 +302,7 @@ local function firstpart(b,r,left,right,obeyhang)
}
end
-local function middlepart(r,left,right,obeyhang)
+local function middlepart(r,left,right)
local rx, ry = r.x, r.y
local rw = rx + r.w
local rh = ry + r.h
@@ -326,7 +312,7 @@ local function middlepart(r,left,right,obeyhang)
rw = rw - right
end
local area = { }
- local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,rd,rh,rd,obeyhang)
+ local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,rd,rh,rd)
for i=#leftshapes,1,-1 do
local li = leftshapes[i]
add(area,li[1],li[2]-ry)
@@ -347,7 +333,7 @@ local function middlepart(r,left,right,obeyhang)
}
end
-local function lastpart(e,r,left,right,obeyhang)
+local function lastpart(e,r,left,right)
local ex, ey = e.x, e.y
local rx, ry = r.x, r.y
local rw = rx + r.w
@@ -361,7 +347,7 @@ local function lastpart(e,r,left,right,obeyhang)
local ed = ey - e.d
local area = { }
-- two cases: till end and halfway e line
- local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,ed,rh,eh,obeyhang)
+ local leftshapes, rightshapes = shapes(r,rx,ry,rw,rh,rd,rh,ed,rh,eh)
for i=1,#rightshapes do
local ri = rightshapes[i]
add(area,ri[1],ri[2]-ry)
@@ -389,7 +375,7 @@ local backgrounds = { }
graphics.backgrounds = backgrounds
-local function calculatemultipar(tag,obeyhang)
+local function calculatemultipar(tag)
local collected = jobpositions.collected
local b = collected[format("b:%s",tag)]
local e = collected[format("e:%s",tag)]
@@ -443,13 +429,13 @@ local function calculatemultipar(tag,obeyhang)
--
if bindex == eindex then
return {
- list = { [b.p] = { singlepart(b,e,collected[br],left,right,obeyhang) } },
+ list = { [b.p] = { singlepart(b,e,collected[br],left,right) } },
bpos = b,
epos = e,
}
else
local list = {
- [b.p] = { firstpart(b,collected[br],left,right,obeyhang) },
+ [b.p] = { firstpart(b,collected[br],left,right) },
}
for i=bindex+1,eindex-1 do
br = format("%s:%s",btag,i)
@@ -460,18 +446,18 @@ local function calculatemultipar(tag,obeyhang)
local p = r.p
local pp = list[p]
if pp then
- pp[#pp+1] = middlepart(r,left,right,obeyhang)
+ pp[#pp+1] = middlepart(r,left,right)
else
- list[p] = { middlepart(r,left,right,obeyhang) }
+ list[p] = { middlepart(r,left,right) }
end
end
end
local p = e.p
local pp = list[p]
if pp then
- pp[#pp+1] = lastpart(e,collected[er],left,right,obeyhang)
+ pp[#pp+1] = lastpart(e,collected[er],left,right)
else
- list[p] = { lastpart(e,collected[er],left,right,obeyhang) }
+ list[p] = { lastpart(e,collected[er],left,right) }
end
return {
list = list,
@@ -551,10 +537,10 @@ local template_d = [[
setbounds currentpicture to multibox ;
]]
-function backgrounds.fetchmultipar(n,anchor,page,obeyhang)
+function backgrounds.fetchmultipar(n,anchor,page)
local data = pbg[n]
if not data then
- data = calculatemultipar(n,obeyhang)
+ data = calculatemultipar(n)
pbg[n] = data -- can be replaced by register
-- register(data.list,n,anchor)
end
@@ -604,10 +590,6 @@ function commands.fetchmultipar(n,anchor,page)
context(backgrounds.fetchmultipar(n,anchor,page))
end
-function commands.fetchmultishape(n,anchor,page)
- context(backgrounds.fetchmultipar(n,anchor,page,true))
-end
-
local template_a = [[
path posboxes[], posregions[] ;
numeric pospages[] ;
@@ -660,10 +642,10 @@ end
local doifelse = commands.doifelse
-function commands.doifelsemultipar(n,page,obeyhang)
+function commands.doifelsemultipar(n,page)
local data = pbg[n]
if not data then
- data = calculatemultipar(n,obeyhang)
+ data = calculatemultipar(n)
pbg[n] = data
end
if page then
diff --git a/tex/context/base/anch-pgr.mkiv b/tex/context/base/anch-pgr.mkiv
index 01ef25dc4..a417d26e3 100644
--- a/tex/context/base/anch-pgr.mkiv
+++ b/tex/context/base/anch-pgr.mkiv
@@ -33,7 +33,7 @@
\installcorenamespace{positionaction}
\installcorenamespace{positioncleanup}
-\unexpanded\def\anch_positions_set_action#1%
+\unexpanded\def\dosetpositionaction#1%
{\expandafter\gdef\csname\??positionaction#1\endcsname} % nicely gobbles spaces
\unexpanded\def\doifpositionaction#1%
@@ -111,7 +111,7 @@
{\begingroup
\edef\currentpositionanchor
{\ifx\currentpositionoverlay\empty#3\else\currentpositionoverlay::\MPanchoridentifier\fi}%
- \normalexpanded{\anch_positions_set_action{\currentpositionanchor}{\noexpand\getvalue{\??positioncleanup\currentpositionanchor}}}%
+ \normalexpanded{\dosetpositionaction{\currentpositionanchor}{\noexpand\getvalue{\??positioncleanup\currentpositionanchor}}}%
\let#1\relax
\ifcsname\??positioncleanup\currentpositionanchor\endcsname
\setxvalue{\??positioncleanup\currentpositionanchor}%
@@ -140,6 +140,9 @@
\fi
\fi\fi}
+% \def\anch_positions_register_page_indeed#1%
+% {\setbox#1\hbox{\hpos\pageanchor{\box#1}}}
+
\def\anch_positions_register_page_indeed#1% maybe like text
{\ifvbox#1\setbox#1\hbox{\box#1}\fi
\anch_make_page_box{#1}}
@@ -215,6 +218,7 @@
%D \typebuffer[graphic]
\def\MPanchoridentifier{mpa} % {mp-anchor}
+%def\MPoverlayposprefix{MO::} % not used
%D The rest of the definitions concerning such overlays may
%D look complicated,
@@ -233,8 +237,8 @@
\def\textbackgroundoverlay#1{\v!text#1}
\def\MPanchornumber {\the\realpageno}
-\unexpanded\def\positionoverlay % the test prevents too many redundant positions
- {\ifpositioning % in (not used) text* position layers
+\def\positionoverlay % the test prevents too many redundant positions
+ {\ifpositioning % in (not used) text* position layers
\expandafter\anch_positions_overlay_indeed
\else % also \iftrialtypesetting test here?
\expandafter\gobbleoneargument
@@ -265,7 +269,7 @@
\box\scratchbox
\vfill}}
-\unexpanded\def\positionregionoverlay % shares regions
+\def\positionregionoverlay % shares regions
{\ifpositioning
\expandafter\anch_positions_region_overlay_indeed
\else % also \iftrialtypesetting test here?
@@ -304,15 +308,9 @@
\expandafter\anch_positions_overlay_start_yes
\fi}
-\let\stoppositionoverlay\relax
-
\def\anch_positions_overlay_start_nop#1\stoppositionoverlay
{}
-\ifdefined\checkpositionoverlays \else \let\checkpositionoverlays\relax \fi
-
-\let\currentpositionoverlay\empty
-
\def\anch_positions_overlay_start_yes#1%
{\checkpositionoverlays
\edef\currentpositionoverlay{#1}}
@@ -320,11 +318,9 @@
\unexpanded\def\stoppositionoverlay
{\let\currentpositionoverlay\empty}
-% needs checking if still needed
-%
% \def\resetpositionoverlay#1%
-% {\anch_positions_set_action{#1::\MPanchoridentifier::}{}}
-%
+% {\dosetpositionaction{#1::\MPanchoridentifier::}{}}
+
% \def\handlepositionboxes#1#2#3%
% {\handlepositionaction\dohandlepositionboxes\with{#1}{#2}{#3}\on{#2}}
%
@@ -336,15 +332,15 @@
% \appendtoks
% \let\dohandlepositionboxes\doinsertpositionboxes % was handle ?
% \to \everyinsertpositionaction
-%
-% \def\docleanpositionboxes#1#2#3% pos tag setups
-% {\ifnum\MPp{#1}<\realpageno \else
-% \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert
-% \fi}
-%
-% \appendtoks
-% \let\dohandlepositionboxes\docleanpositionboxes
-% \to \everycleanpositionaction
+
+\def\docleanpositionboxes#1#2#3% pos tag setups
+ {\ifnum\MPp{#1}<\realpageno \else
+ \noexpand \dohandlepositionboxes{#1}{#2}{#3}% reinsert
+ \fi}
+
+\appendtoks
+ \let\dohandlepositionboxes\docleanpositionboxes
+\to \everycleanpositionaction
%D A position graphic is a normal (non||reused) \METAPOST\
%D graphic, used immediately, with zero dimensions, so that a
@@ -354,7 +350,7 @@
\installcorenamespace{positionmethod}
%installcorenamespace{graphicvariable}
-\newbox\b_anch_positions_graphic
+\newbox\positiongraphicbox
\def\startMPpositiongraphic % id setups
{\dodoublegroupempty\anch_positions_meta_graphic_start}
@@ -365,11 +361,11 @@
\let\stopMPpositiongraphic\relax
\def\anch_positions_meta_graphic_prepare
- {\ifcsname\??graphicvariable\currentmpvariableclass:self\endcsname \else
- \letvalue{\??graphicvariable\currentmpvariableclass:self}\currentposition
+ {\ifcsname\??gv\currentmpvariableclass:self\endcsname \else
+ \letvalue{\??gv\currentmpvariableclass:self}\currentposition
\fi
- \ifcsname\??graphicvariable\currentmpvariableclass:from\endcsname \else
- \letvalue{\??graphicvariable\currentmpvariableclass:from}\currentposition
+ \ifcsname\??gv\currentmpvariableclass:from\endcsname \else
+ \letvalue{\??gv\currentmpvariableclass:from}\currentposition
\fi}
\def\anch_positions_meta_graphic_use#1#2#3%
@@ -379,7 +375,7 @@
\startMPcode#3\stopMPcode
\endgroup}
-\unexpanded\def\MPpositiongraphic
+\def\MPpositiongraphic
{\dodoublegroupempty\anch_positions_meta_graphic_direct}
\def\anch_positions_meta_graphic_direct#1% tag setups
@@ -406,9 +402,9 @@
\anch_positions_meta_graphic_prepare
\obeyMPboxorigin % do we also set the size ? when needed this must be done in mp ... might change
\def\anch_positions_meta_graphic_direct{\anch_positions_meta_graphic_nested{#3}}% takes two extra arguments
- \setbox\b_anch_positions_graphic\hbox{\ignorespaces\csname#1#2\endcsname\removelastspace}%
- \smashbox\b_anch_positions_graphic
- \box\b_anch_positions_graphic
+ \setbox\positiongraphicbox\hbox{\ignorespaces\csname#1#2\endcsname\removelastspace}%
+ \smashbox\positiongraphicbox
+ \box\positiongraphicbox
\endgroup}
\def\anch_positions_meta_graphic_nested#1#2#3% nesting used in prikkels / pascal (might go away)
@@ -426,77 +422,77 @@
%D Simple one position graphics.
-\unexpanded\def\setMPpositiongraphic
- {\dotriplegroupempty\anch_positions_meta_graphic_set}
+\def\setMPpositiongraphic
+ {\dotriplegroupempty\dosetMPpositiongraphic}
-\def\anch_positions_meta_graphic_set#1#2#3% pos tag vars
+\def\dosetMPpositiongraphic#1#2#3% pos tag vars
{\ifx\currentpositionoverlay\empty
- \anch_positions_set_action{#1}{\MPpositiongraphic{#2}{#3}}%
+ \dosetpositionaction{#1}{\MPpositiongraphic{#2}{#3}}%
\else % silly can be one
- \anch_positions_meta_graphic_handle{#1}{#2}{#3}%
+ \handlepositiongraphics{#1}{#2}{#3}%
\fi}
-\def\anch_positions_meta_graphic_handle#1#2#3% combine with boxes
- {\handlepositionaction\anch_positions_meta_graphic_handle_indeed\with{#1}{#2}{#3}\on{#2}}
+\def\handlepositiongraphics#1#2#3% combine with boxes
+ {\handlepositionaction\dohandleMPpositiongraphic\with{#1}{#2}{#3}\on{#2}}
-\def\anch_positions_meta_graphic_insert#1#2#3% pos tag setups
+\def\doinsertMPpositiongraphic#1#2#3% pos tag setups
{\ifnum\MPp{#1}=\realpageno\relax % extra saveguard
\def\currentposition{#1}\MPpositiongraphic{#2}{#3}%
\fi}
\appendtoks
- \let\anch_positions_meta_graphic_handle_indeed\anch_positions_meta_graphic_insert
+ \let\dohandleMPpositiongraphic\doinsertMPpositiongraphic
\to \everyinsertpositionaction
-\def\anch_positions_meta_graphic_cleanup#1#2#3% pos tag setups
+\def\docleanMPpositiongraphic#1#2#3% pos tag setups
{\ifnum\MPp{#1}<\realpageno \else
- \noexpand\anch_positions_meta_graphic_handle_indeed{#1}{#2}{#3}%
+ \noexpand\dohandleMPpositiongraphic{#1}{#2}{#3}%
\fi}
\appendtoks
- \let\anch_positions_meta_graphic_handle_indeed\anch_positions_meta_graphic_cleanup
+ \let\dohandleMPpositiongraphic\docleanMPpositiongraphic
\to \everycleanpositionaction
%D Graphics that span two positions (beware, does not cross pages).
\unexpanded\def\setMPpositiongraphicrange
- {\doquadruplegroupempty\anch_positions_meta_graphic_set_range}
+ {\doquadruplegroupempty\dosetMPpositiongraphicrange}
-\def\anch_positions_meta_graphic_set_range#1#2#3#4% bpos epos tag vars
+\def\dosetMPpositiongraphicrange#1#2#3#4% bpos epos tag vars
{\ifx\currentpositionoverlay\empty
- \anch_positions_set_action{#1}{\MPpositiongraphic{#3}{#4}}%
+ \dosetpositionaction{#1}{\MPpositiongraphic{#3}{#4}}%
\else
- \anch_positions_meta_graphic_handle_range{#1}{#2}{#3}{#4}%
+ \handlepositiongraphicsrange{#1}{#2}{#3}{#4}%
\fi}
-\def\anch_positions_meta_graphic_handle_range#1#2#3#4%
- {\handlepositionaction\anch_positions_meta_graphic_handle_range_indeed\with{#1}{#2}{#3}{#4}\on{#2}}
+\def\handlepositiongraphicsrange#1#2#3#4%
+ {\handlepositionaction\dohandleMPpositiongraphicrange\with{#1}{#2}{#3}{#4}\on{#2}}
-\def\anch_positions_meta_graphic_insert_range#1#2#3#4% pos pos tag setups
+\def\doinsertMPpositiongraphicrange#1#2#3#4% pos pos tag setups
{\ctxcommand{doifelserangeonpage("#1","#2",\number\realpageno)}%
- {\def\currentposition{#1}%
+ {%\writestatus{YES}{#1/#2 => #3}%
+ \def\currentposition{#1}%
\MPpositiongraphic{#3}{#4}}%
- {}}
+ {}}%\writestatus{NOP}{#1/#2 = #3}}}
\appendtoks
- \let\anch_positions_meta_graphic_handle_range_indeed\anch_positions_meta_graphic_insert_range
+ \let\dohandleMPpositiongraphicrange\doinsertMPpositiongraphicrange
\to \everyinsertpositionaction
-\def\anch_positions_meta_graphic_cleanup_range#1#2#3#4% pos tag setups
+\def\docleanMPpositiongraphicrange#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 \dohandleMPpositiongraphicrange{#1}{#2}{#3}{#4}%
\fi}
\appendtoks
- \let\anch_positions_meta_graphic_handle_range_indeed\anch_positions_meta_graphic_cleanup_range
+ \let\dohandleMPpositiongraphicrange\docleanMPpositiongraphicrange
\to \everycleanpositionaction
-\let\anch_positions_meta_graphic_handle_range_indeed\gobblefourarguments
+\let\dohandleMPpositiongraphicrange\gobblefourarguments
% Helpers:
-\def\MPgetposboxes #1#2{\ctxcommand{fetchposboxes("#1","#2",\the\realpageno)}}
-\def\MPgetmultipars #1#2{\ctxcommand{fetchmultipar("#1","#2",\the\realpageno)}}
-\def\MPgetmultishapes#1#2{\ctxcommand{fetchmultishape("#1","#2",\the\realpageno)}}
+\def\MPgetposboxes #1#2{\ctxcommand{fetchposboxes("#1","#2",\the\realpageno)}}
+\def\MPgetmultipars#1#2{\ctxcommand{fetchmultipar("#1","#2",\the\realpageno)}}
\protect \endinput
diff --git a/tex/context/base/anch-pos.lua b/tex/context/base/anch-pos.lua
index 6fa916291..5d01a6e46 100644
--- a/tex/context/base/anch-pos.lua
+++ b/tex/context/base/anch-pos.lua
@@ -17,8 +17,6 @@ more efficient.
-- 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
-local commands, context = commands, context
-
local tostring, next, rawget, setmetatable = tostring, next, rawget, setmetatable
local concat, sort = table.concat, table.sort
local format, gmatch, match = string.format, string.gmatch, string.match
@@ -971,35 +969,35 @@ function commands.MPxywhd(id)
end
end
-local doif, doifelse = commands.doif, commands.doifelse
+-- is testcase already defined? if so, then local
function commands.doifpositionelse(name)
- doifelse(collected[name])
+ commands.doifelse(collected[name])
end
function commands.doifposition(name)
- doif(collected[name])
+ commands.doif(collected[name])
end
function commands.doifpositiononpage(name,page) -- probably always realpageno
local c = collected[name]
- doifelse(c and c.p == page)
+ commands.testcase(c and c.p == page)
end
function commands.doifoverlappingelse(one,two,overlappingmargin)
- doifelse(overlapping(one,two,overlappingmargin))
+ commands.testcase(overlapping(one,two,overlappingmargin))
end
function commands.doifpositionsonsamepageelse(list,page)
- doifelse(onsamepage(list))
+ commands.testcase(onsamepage(list))
end
function commands.doifpositionsonthispageelse(list)
- doifelse(onsamepage(list,tostring(tex.count.realpageno)))
+ commands.testcase(onsamepage(list,tostring(tex.count.realpageno)))
end
function commands.doifelsepositionsused()
- doifelse(next(collected))
+ commands.testcase(next(collected))
end
commands.markcolumnbox = jobpositions.markcolumnbox
diff --git a/tex/context/base/anch-pos.mkiv b/tex/context/base/anch-pos.mkiv
index 7ecaa296e..2e13eeba2 100644
--- a/tex/context/base/anch-pos.mkiv
+++ b/tex/context/base/anch-pos.mkiv
@@ -361,9 +361,9 @@
\startcolor[blue]%
\llap{\infofont\number\c_anch_positions_paragraph}%
\vrule
- \s!width 4\onepoint
- \s!height2\onepoint
- \s!depth 2\onepoint
+ \!!width 4\onepoint
+ \!!height2\onepoint
+ \!!depth 2\onepoint
\stopcolor
\hss}}
@@ -377,7 +377,7 @@
{\smashedhbox
{#1{\infofont#2#3}%
\kern-\onepoint
- \vrule\s!width2\onepoint\s!height\halfapoint\s!depth\halfapoint}}
+ \vrule\!!width2\onepoint\!!height\halfapoint\!!depth\halfapoint}}
\unexpanded\def\anch_positions_trace_left_indeed
{\anch_positions_trace\llap\darkmagenta{\currentposition>}}
diff --git a/tex/context/base/anch-tab.mkiv b/tex/context/base/anch-tab.mkiv
index 2fb6938a2..4bdaa2ef9 100644
--- a/tex/context/base/anch-tab.mkiv
+++ b/tex/context/base/anch-tab.mkiv
@@ -13,9 +13,6 @@
\writestatus{loading}{ConTeXt Anchoring Macros / Table Extensions}
-%D This is just a playground and functionality might change or even
-%D dissappear in favour of better solutions.
-
\unprotect
\newcount\c_anch_tabs
@@ -60,22 +57,23 @@
\global\advance\c_anch_tabs\plusone
\to \everytabulate
-%D Beware, the following code is somewhat weird and experimental and might be
-%D dropped or become a loadable module.
+%D Beware, the following code is somewhat weird and experimental
+%D and might be dropped or become a loadable module.
%D \macros
%D {GFC, GTC, GSC}
%D
-%D The next macros extend tables and tabulation with backgrounds and position
-%D related features. Areas are specified with symbolic names, and symbolic
-%D references to the graphics involved. Each table has its own namespace.
+%D The next macros extend tables and tabulation with
+%D backgrounds and position related features. Areas are
+%D specified with symbolic names, and symbolic references to
+%D the graphics involved. Each table has its own namespace.
\newconditional\tablehaspositions
-\newcount \noftabpositions
-\newtoks \posXCtoks
+\newcount\noftabpositions
+\newtoks \posXCtoks
-\def\anch_tabulate_bpos{\bpos}
-\def\anch_tabulate_epos{\epos}
+\def\dotablebpos{\bpos}
+\def\dotableepos{\epos}
\installcorenamespace{positiontables}
@@ -87,80 +85,74 @@
\let\tabulatepos\tablepos
-\unexpanded\def\tbXC {\dosingleempty\anch_tables_XC }
-\unexpanded\def\tbGSC{\dosingleempty\anch_tables_GSC}
-\unexpanded\def\tbGFC{\dosingleempty\anch_tables_GFC}
-\unexpanded\def\tbGTC{\dosingleempty\anch_tables_GTC}
-
-\def\anch_table_check_state
- {\iftrialtypesetting
- \global\settrue\tablehaspositions
- \firstargumentfalse
- \fi}
-
-\def\anch_tables_XC [#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_XC [#1]\else\expandafter\fi\NC}
-\def\anch_tables_GSC[#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_GSC[#1]\else\expandafter\NC\fi}
-\def\anch_tables_GFC[#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_GFC[#1]\else\expandafter\NC\fi}
-\def\anch_tables_GTC[#1]{\anch_table_check_state\iffirstargument\anch_tables_indeed_GTC[#1]\else\expandafter\NC\fi}
-
-\def\anch_tables_indeed_XC[#1]%
- {{\let\NC\relax\processcommalist[#1]\anch_tables_step_XC}}
+\def\dodododoGSC[#1:#2]%
+ {\remappositionframed{#2}{\tbPOSprefix#1}%
+ \dotablebpos{\tbPOSprefix#1}%
+ \doglobal\appendtoks\@EA\dotableepos\@EA{\tbPOSprefix#1}\to\posXCtoks}
-\def\anch_tables_step_XC#1%
- {\anch_tables_step_indeed_XC[#1]}
+\def\dododoGSC[#1:#2:#3]%
+ {\doglobal\appendtoks\dodododoGSC[#1:#2]\to\posXCtoks\NC}
-\def\anch_tables_step_indeed_XC[#1#2]%
- {\if#1>\anch_tables_indeed_GFC [#2:#2]\else
- \if#1+\anch_tables_indeed_GFC [#2:#2]\else
- \if#1<\anch_tables_indeed_GTC [#2:#2]\else
- \if#1-\anch_tables_indeed_GTC [#2:#2]\else
- \if#1=\anch_tables_indeed_GSC [#2:#2]\else
- \anch_tables_indeed_GSC[#1#2:#1#2]\fi\fi\fi\fi\fi}
+\def\dodoGSC[#1]%
+ {\def\docommand##1{\dododoGSC[##1:##1]}%
+ \processcommalist[#1]\docommand}
-\def\anch_tables_indeed_GSC[#1]%
- {\processcommalist[#1]\anch_tables_step_GSC}
+\def\dodododoGFC[#1:#2:#3]%
+ {\remappositionframed{#2}{\tbPOSprefix#1}%
+ \dotablebpos{\tbPOSprefix#1}}
-\def\anch_tables_step_GSC#1%
- {\anch_tables_append_GSC[#1:#1]}
+\def\dododoGFC[#1]%
+ {\def\docommand##1{\dodododoGFC[##1:##1]}%
+ \processcommalist[#1]\docommand}
-\def\anch_tables_append_GSC[#1:#2:#3]%
- {\doglobal\appendtoks\anch_tables_process_GSC[#1:#2]\to\posXCtoks\NC}
+\def\dodoGFC[#1]%
+ {\doglobal\appendtoks\dododoGFC[#1]\to\posXCtoks\NC}
-\def\anch_tables_process_GSC[#1:#2]%
- {\remappositionframed{#2}{\tbPOSprefix#1}%
- \anch_tabulate_bpos{\tbPOSprefix#1}%
- \doglobal\appendtoks\@EA\anch_tabulate_epos\@EA{\tbPOSprefix#1}\to\posXCtoks}
+\def\dododododoGTC[#1:#2]%
+ {\dotableepos{\tbPOSprefix#1}}
-\def\anch_tables_indeed_GFC[#1]%
- {\doglobal\appendtoks\anch_tables_delayed_GFC[#1]\to\posXCtoks\NC}
+\def\dodododoGTC[#1]%
+ {\def\docommand##1{\dododododoGTC[##1:##1]}%
+ \processcommalist[#1]\docommand}
-\def\anch_tables_delayed_GFC[#1]%
- {\processcommalist[#1]\anch_tables_step_GFC}
+\def\dododoGTC[#1]%
+ {\doglobal\appendtoks\dodododoGTC[#1]\to\posXCtoks}
-\def\anch_tables_step_GFC#1%
- {\anch_tables_process_GFC[#1:#1]}
+\def\dodoGTC[#1]%
+ {\doglobal\appendtoks\dododoGTC[#1]\to\posXCtoks\NC}
-\def\anch_tables_process_GFC[#1:#2:#3]%
- {\remappositionframed{#2}{\tbPOSprefix#1}%
- \anch_tabulate_bpos{\tbPOSprefix#1}}
+\def\dodododoXC[#1#2]%
+ {\if#1>\dodoGFC [#2:#2]\else
+ \if#1+\dodoGFC [#2:#2]\else
+ \if#1<\dodoGTC [#2:#2]\else
+ \if#1-\dodoGTC [#2:#2]\else
+ \if#1=\dodoGSC [#2:#2]\else
+ \dodoGSC[#1#2:#1#2]\fi\fi\fi\fi\fi}
-\def\anch_tables_indeed_GTC[#1]%
- {\doglobal\appendtoks\anch_tables_delayed_GTC[#1]\to\posXCtoks\NC}
+\def\dododoXC#1%
+ {\dodododoXC[#1]}
-\def\anch_tables_delayed_GTC[#1]%
- {\doglobal\appendtoks\anch_tables_process_GTC[#1]\to\posXCtoks}
+\def\dodoXC[#1]%
+ {{\let\NC\relax\processcommalist[#1]\dododoXC}}
-\def\anch_tables_process_GTC[#1]%
- {\processcommalist[#1]\anch_tables_step_GTC}
+\def\@@checktablepositionstate
+ {\iftrialtypesetting
+ \global\settrue\tablehaspositions
+ \firstargumentfalse
+ \fi}
-\def\anch_tables_step_GTC#1%
- {\anch_tables_step_indeed_GTC[#1:#1]}
+\def\doGSC[#1]{\@@checktablepositionstate\iffirstargument\dodoGSC[#1]\else\expandafter\NC\fi}
+\def\doGFC[#1]{\@@checktablepositionstate\iffirstargument\dodoGFC[#1]\else\expandafter\NC\fi}
+\def\doGTC[#1]{\@@checktablepositionstate\iffirstargument\dodoGTC[#1]\else\expandafter\NC\fi}
+\def\doXC [#1]{\@@checktablepositionstate\iffirstargument\dodoXC [#1]\else\expandafter\fi\NC}
-\def\anch_tables_step_indeed_GTC[#1:#2]%
- {\anch_tabulate_epos{\tbPOSprefix#1}}
+\def\tbGSC{\dosingleempty\doGSC}
+\def\tbGFC{\dosingleempty\doGFC}
+\def\tbGTC{\dosingleempty\doGTC}
+\def\tbXC {\dosingleempty\doXC }
-%D The amount of code to support tables and tabulation is rather
-%D minimalistic.
+%D The amount of code to support tables and tabulation is
+%D rather minimalistic.
\let\tabulatepos\tablepos
@@ -195,30 +187,31 @@
% We need to handle paragraphs as well.
-\let\anch_tabulate_flush_epos\relax
+\let\doflushtabulateepos\relax
-\def\anch_tabulate_bpos_indeed
+\def\dotabulatebpos
{\bpos}
-\def\anch_tabulate_epos_indeed#1%
+\def\dotabulateepos#1%
{\ifvoid\b_tabl_tabulate_current\c_tabl_tabulate_column
\epos{#1}%
- \glet\anch_tabulate_flush_epos\relax
+ \glet\doflushtabulateepos\relax
\else
- \gdef\anch_tabulate_flush_epos{\epos{#1}}%
+ \gdef\doflushtabulateepos{\epos{#1}}%
\fi}
\def\flushtabulatesplitbox
{\box\b_tabl_tabulate
- \iftrialtypesetting\else\ifconditional\tablehaspositions\anch_tabulate_flush_epos\fi\fi}
+ \iftrialtypesetting\else\ifconditional\tablehaspositions\doflushtabulateepos\fi\fi}
\appendtoks
- \let\anch_tabulate_bpos\anch_tabulate_bpos_indeed % ?
- \let\anch_tabulate_epos\anch_tabulate_epos_indeed % ?
- \glet\anch_tabulate_flush_epos\relax
+ \let\dotablebpos\dotabulatebpos % ?
+ \let\dotableepos\dotabulateepos % ?
+ \glet\doflushtabulateepos\relax
\to \everytabulate
-%D In order to prevent potential clashes with abbreviations, postpone the mapping.
+%D In order to prevent potential clashes with abbreviations,
+%D postpone the mapping.
\appendtoks
\let\GSC\tbGSC
@@ -230,8 +223,8 @@
%D \macros
%D {definepositionframed}
%D
-%D The next example show how to provide backgrounds to table cells. First we define
-%D some framed backgrounds.
+%D The next example show how to provide backgrounds to table
+%D cells. First we define some framed backgrounds.
%D
%D \startbuffer
%D \definepositionframed[x][background=color,backgroundcolor=red]
@@ -251,7 +244,8 @@
%D \stoptabulate
%D \stopbuffer
%D
-%D The table itself defines three areas (a, b and~c) using these frames.
+%D The table itself defines three areas (a, b and~c) using
+%D these frames.
%D
%D \typebuffer
%D % \getbuffer
@@ -276,8 +270,9 @@
\let\XC \tbXC
\to \everytable
-%D In the previous example, we could have provided an overlay to the framed definition.
-%D A more direct approach is demonstrated below:
+%D In the previous example, we could have provided an overlay to
+%D the framed definition. A more direct approach is demonstrated
+%D below:
%D
%D \startbuffer
%D \def\cw#1{\color[white]{#1}}
@@ -296,7 +291,8 @@
%D
%D \typebuffer \getbuffer
%D
-%D The definition of the table looks about the same as the previous one:
+%D The definition of the table looks about the same as the
+%D previous one:
%D
%D \startbuffer
%D \starttable[|c|c|c|]
@@ -351,26 +347,22 @@
% \definepositionframed[y][background=color,fillcolor=green]
% \definepositionframed[z][background=color,fillcolor=blue]
-\unexpanded\def\remappositionframed#1#2% from to
+\def\remappositionframed#1#2% from to
{\copyposition{b:#1}{b:#2}%
\copyposition{e:#1}{e:#2}%
- \anch_positions_set_action{b:#2}{\dopositionaction{b:#1}}}
+ \dosetpositionaction{b:#2}{\dopositionaction{b:#1}}}
\unexpanded\def\definepositionframed
- {\dodoubleargument\anch_framed_define}
+ {\dodoubleargument\dodefinepositionframed}
-\def\anch_framed_define[#1][#2]%
- {\anch_positions_set_action{b:#1}{\anch_framed_handle[#1][#2]}}
-
-\unexpanded\def\anch_framed_handle
- {\bgroup
- \anch_framed_indeed}
+\def\dodefinepositionframed[#1][#2]%
+ {\dosetpositionaction{b:#1}{\dopositionframed[#1][#2]}}
\unexpanded\def\positionframed
{\bgroup
- \dodoubleempty\anch_framed_indeed}
+ \dodoubleempty\dopositionframed}
-\def\anch_framed_indeed[#1][#2]%
+\def\dopositionframed[#1][#2]%
{\setbox\scratchbox\hbox
{\scratchwidth \dimexpr\MPx{e:#1}-\MPx{b:#1}\relax
\scratchdepth \dimexpr\MPy{b:#1}-\MPy{e:#1}+\MPd{e:#1}\relax
diff --git a/tex/context/base/attr-col.lua b/tex/context/base/attr-col.lua
index 18182ba85..c592d1dc1 100644
--- a/tex/context/base/attr-col.lua
+++ b/tex/context/base/attr-col.lua
@@ -15,11 +15,8 @@ if not modules then modules = { } end modules ['attr-col'] = {
local type = type
local format = string.format
local concat = table.concat
-local min, max, floor = math.min, math.max, math.floor
-local attributes, nodes, utilities, logs, backends, storage = attributes, nodes, utilities, logs, backends, storage
-local commands, context, interfaces = commands, context, interfaces
-local tex = tex
+local attributes, nodes = attributes, nodes
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
@@ -34,13 +31,11 @@ local report_transparencies = logs.reporter("transparencies","support")
-- nb: attributes: color etc is much slower than normal (marks + literals) but ...
-- nb. too many "0 g"s
-local states = attributes.states
-local tasks = nodes.tasks
-local nodeinjections = backends.nodeinjections
-local registrations = backends.registrations
-local unsetvalue = attributes.unsetvalue
-
-local registerstorage = storage.register
+local states = attributes.states
+local tasks = nodes.tasks
+local nodeinjections = backends.nodeinjections
+local registrations = backends.registrations
+local unsetvalue = attributes.unsetvalue
-- We can distinguish between rules and glyphs but it's not worth the trouble. A
-- first implementation did that and while it saves a bit for glyphs and rules, it
@@ -68,7 +63,7 @@ local registerstorage = storage.register
-- colors.strings[color] = "return colors." .. colorspace .. "(" .. concat({...},",") .. ")"
-- end
--
--- registerstorage("attributes/colors/data", colors.strings, "attributes.colors.data") -- evaluated
+-- storage.register("attributes/colors/data", colors.strings, "attributes.colors.data") -- evaluated
--
-- We assume that only processcolors are defined in the format.
@@ -88,17 +83,9 @@ colors.default = 1
colors.main = nil
colors.triggering = true
colors.supported = true
-colors.model = "all"
-
-local data = colors.data
-local values = colors.values
-local registered = colors.registered
-local numbers = attributes.numbers
-local list = attributes.list
-
-registerstorage("attributes/colors/values", values, "attributes.colors.values")
-registerstorage("attributes/colors/registered", registered, "attributes.colors.registered")
+storage.register("attributes/colors/values", colors.values, "attributes.colors.values")
+storage.register("attributes/colors/registered", colors.registered, "attributes.colors.registered")
local templates = {
rgb = "r:%s:%s:%s",
@@ -117,6 +104,17 @@ local models = {
cmyk = 4,
}
+colors.model = "all"
+
+local data = colors.data
+local values = colors.values
+local registered = colors.registered
+
+local numbers = attributes.numbers
+local list = attributes.list
+
+local min, max, floor = math.min, math.max, math.floor
+
local function rgbtocmyk(r,g,b) -- we could reduce
return 1-r, 1-g, 1-b, 0
end
@@ -127,9 +125,9 @@ end
local function rgbtogray(r,g,b)
if colors.weightgray then
- return .30*r + .59*g + .11*b
+ return .30*r+.59*g+.11*b
else
- return r/3 + g/3 + b/3
+ return r/3+g/3+b/3
end
end
@@ -137,17 +135,6 @@ local function cmyktogray(c,m,y,k)
return rgbtogray(cmyktorgb(c,m,y,k))
end
--- not critical so not needed:
---
--- local function cmyktogray(c,m,y,k)
--- local r, g, b = 1.0 - min(1.0,c+k), 1.0 - min(1.0,m+k), 1.0 - min(1.0,y+k)
--- if colors.weightgray then
--- return .30*r + .59*g + .11*b
--- else
--- return r/3 + g/3 + b/3
--- end
--- end
-
-- http://en.wikipedia.org/wiki/HSI_color_space
-- http://nl.wikipedia.org/wiki/HSV_(kleurruimte)
@@ -376,15 +363,15 @@ transparencies.triggering = true
transparencies.attribute = a_transparency
transparencies.supported = true
-local registered = transparencies.registered -- we could use a 2 dimensional table instead
-local data = transparencies.data
-local values = transparencies.values
-local template = "%s:%s"
+storage.register("attributes/transparencies/registered", transparencies.registered, "attributes.transparencies.registered")
+storage.register("attributes/transparencies/values", transparencies.values, "attributes.transparencies.values")
-registerstorage("attributes/transparencies/registered", registered, "attributes.transparencies.registered")
-registerstorage("attributes/transparencies/values", values, "attributes.transparencies.values")
+local registered = transparencies.registered -- we could use a 2 dimensional table instead
+local data = transparencies.data
+local values = transparencies.values
+local template = "%s:%s"
-local function inject_transparency(...)
+local function inject_transparency (...)
inject_transparency = nodeinjections.transparency
return inject_transparency(...)
end
diff --git a/tex/context/base/attr-eff.lua b/tex/context/base/attr-eff.lua
index 60e0c08ac..023d1c51b 100644
--- a/tex/context/base/attr-eff.lua
+++ b/tex/context/base/attr-eff.lua
@@ -8,9 +8,7 @@ if not modules then modules = { } end modules ['attr-eff'] = {
local format = string.format
-local commands, interfaces = commands, interfaces
-local attributes, nodes, backends, utilities = attributes, nodes, backends, utilities
-local tex = tex
+local attributes, nodes = attributes, nodes
local states = attributes.states
local tasks = nodes.tasks
@@ -19,9 +17,6 @@ local settexattribute = tex.setattribute
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
-local variables = interfaces.variables
-local v_normal = variables.normal
-
attributes.effects = attributes.effects or { }
local effects = attributes.effects
@@ -32,14 +27,14 @@ effects.values = effects.values or { }
effects.registered = effects.registered or { }
effects.attribute = a_effect
-local data = effects.data
-local registered = effects.registered
-local values = effects.values
+storage.register("attributes/effects/registered", effects.registered, "attributes.effects.registered")
+storage.register("attributes/effects/values", effects.values, "attributes.effects.values")
-local template = "%s:%s:%s"
+local template = "%s:%s:%s"
-storage.register("attributes/effects/registered", registered, "attributes.effects.registered")
-storage.register("attributes/effects/values", values, "attributes.effects.values")
+local data = effects.data
+local registered = effects.registered
+local values = effects.values
-- valid effects: normal inner outer both hidden (stretch,rulethickness,effect)
@@ -71,22 +66,12 @@ effects.handler = nodes.installattributehandler {
processor = states.process,
}
-local function register(specification)
- local alternative, stretch, rulethickness
- if specification then
- alternative = specification.alternative or v_normal
- stretch = specification.stretch or 0
- rulethickness = specification.rulethickness or 0
- else
- alternative = v_normal
- stretch = 0
- rulethickness = 0
- end
- local stamp = format(template,alternative,stretch,rulethickness)
+local function register(effect,stretch,rulethickness)
+ local stamp = format(template,effect,stretch,rulethickness)
local n = registered[stamp]
if not n then
n = #values + 1
- values[n] = { alternative, stretch, rulethickness }
+ values[n] = { effect, stretch, rulethickness }
registered[stamp] = n
end
return n
@@ -103,10 +88,10 @@ effects.enable = enable
local enabled = false
-function commands.triggereffect(specification)
+function commands.triggereffect(effect,stretch,rulethickness)
if not enabled then
enable()
enabled = true
end
- settexattribute(a_effect,register(specification))
+ settexattribute(a_effect,register(effect,stretch,rulethickness))
end
diff --git a/tex/context/base/attr-eff.mkiv b/tex/context/base/attr-eff.mkiv
index 43f575a7a..c5c94537c 100644
--- a/tex/context/base/attr-eff.mkiv
+++ b/tex/context/base/attr-eff.mkiv
@@ -17,39 +17,38 @@
\unprotect
-\installcorenamespace{effect}
+\gdef\dotriggereffect#1#2#3%
+ {\ctxcommand{triggereffect('#1',#2,\number\dimexpr#3\relax)}}
-\installcommandhandler \??effect {effect} \??effect
+\unexpanded\def\setupeffect
+ {\dodoubleargument\dosetupeffect}
-\setupeffect
- [\c!method=\v!none,
- \c!stretch=\zerocount,
- \c!rulethickness=\zeropoint,
- \c!alternative=\v!normal]
+\def\dosetupeffect[#1][#2]%
+ {\getparameters[\??et#1][#2]}
-\appendtoks
- \edef\p_method{\effectparameter\c!method}%
- \ifx\p_method\v!method
- \setuxvalue{\e!start\currenteffect}{\starteffect[#1]}%
- \setuxvalue{\e!stop \currenteffect}{\stopeffect}%
- \fi
-\to \everydefineeffect
+\unexpanded\def\defineeffect
+ {\dodoubleargument\dodefineeffect}
+
+\def\dodefineeffect[#1][#2]%
+ {\getparameters[\??et#1][\c!method=\v!none,\c!stretch=0,\c!rulethickness=\zeropoint,\c!alternative=\v!normal,#2]%
+ \doif{\getvalue{\??et#1\c!method}}\v!command
+ {\setugvalue{\e!start#1}{\starteffect[#1]}%
+ \setugvalue{\e!stop #1}{\stopeffect}}}
+
+% yes or no grouped
\unexpanded\def\starteffect[#1]%
- {\ctxcommand{triggereffect{
- alternative = "\namedeffectparameter{#1}\c!alternative",
- stretch = \number\namedeffectparameter{#1}\c!stretch,
- rulethickness = \number\dimexpr\namedeffectparameter{#1}\c!rulethickness\relax
- }}}
+ {\dotriggereffect
+ {\csname\??et#1\c!alternative \endcsname}%
+ {\csname\??et#1\c!stretch \endcsname}%
+ {\csname\??et#1\c!rulethickness\endcsname}}
\unexpanded\def\stopeffect % can be special
- {\ctxcommand{triggereffect()}} % v!normal 0 0
+ {\dotriggereffect\v!normal0\zeropoint}
\unexpanded\def\effect[#1]%
{\groupedcommand{\starteffect[#1]}{\stopeffect}}
-% yes or no grouped
-
\defineeffect [\v!inner] [\c!alternative=\v!inner,\c!rulethickness=.25pt]
\defineeffect [\v!outer] [\c!alternative=\v!outer,\c!rulethickness=.25pt]
\defineeffect [\v!both] [\c!alternative=\v!both, \c!rulethickness=.25pt]
diff --git a/tex/context/base/attr-ini.lua b/tex/context/base/attr-ini.lua
index 5a3bafce3..f3714fcb4 100644
--- a/tex/context/base/attr-ini.lua
+++ b/tex/context/base/attr-ini.lua
@@ -6,8 +6,6 @@ if not modules then modules = { } end modules ['attr-ini'] = {
license = "see context related readme files"
}
-local commands, context, nodes, storage = commands, context, nodes, storage
-
local next, type = next, type
--[[ldx--
@@ -15,10 +13,11 @@ local next, type = next, type
symbolic names later on.
--ldx]]--
-attributes = attributes or { }
-local attributes = attributes
+attributes = attributes or { }
+
+local attributes, nodes = attributes, nodes
-local sharedstorage = storage.shared
+-- todo: local and then gobals ... first loaded anyway
attributes.names = attributes.names or { }
attributes.numbers = attributes.numbers or { }
@@ -27,14 +26,15 @@ attributes.states = attributes.states or { }
attributes.handlers = attributes.handlers or { }
attributes.unsetvalue = -0x7FFFFFFF
-local names = attributes.names
-local numbers = attributes.numbers
-local list = attributes.list
+local names, numbers, list = attributes.names, attributes.numbers, attributes.list
storage.register("attributes/names", names, "attributes.names")
storage.register("attributes/numbers", numbers, "attributes.numbers")
storage.register("attributes/list", list, "attributes.list")
+names [0] = "fontdynamic"
+numbers["fontdynamic"] = 0
+
function attributes.define(name,number) -- at the tex end
if not numbers[name] then
numbers[name] = number
@@ -43,19 +43,13 @@ function attributes.define(name,number) -- at the tex end
end
end
---[[ldx--
-
We reserve this one as we really want it to be always set (faster).
We can use the attributes in the range 127-255 (outside user space). These
are only used when no attribute is set at the \TEX\ end which normally
happens in .
--ldx]]--
-sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 127
+storage.shared.attributes_last_private = storage.shared.attributes_last_private or 127
-- to be considered (so that we can use an array access):
--
@@ -63,10 +57,10 @@ sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or
--
-- setmetatable(private, {
-- __index = function(t,name)
--- local number = sharedstorage.attributes_last_private
+-- local number = storage.shared.attributes_last_private or 127
-- if number < 1023 then -- tex.count.minallocatedattribute - 1
-- number = number + 1
--- sharedstorage.attributes_last_private = number
+-- storage.shared.attributes_last_private = number
-- end
-- numbers[name], names[number], list[number] = number, name, { }
-- private[name] = number
@@ -80,12 +74,12 @@ sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or
function attributes.private(name) -- at the lua end (hidden from user)
local number = numbers[name]
if not number then
- local last = sharedstorage.attributes_last_private
+ local last = storage.shared.attributes_last_private or 127
if last < 1023 then -- tex.count.minallocatedattribute - 1
last = last + 1
- sharedstorage.attributes_last_private = last
+ storage.shared.attributes_last_private = last
else
- report_attribute("no more room for private attributes")
+ report_attribute("no more room for private attributes") -- fatal
os.exit()
end
number = last
@@ -94,7 +88,7 @@ function attributes.private(name) -- at the lua end (hidden from user)
return number
end
--- tracers
+-- new (actually a tracer)
local report_attribute = logs.reporter("attributes")
diff --git a/tex/context/base/attr-ini.mkiv b/tex/context/base/attr-ini.mkiv
index 8a41dd427..a1550b4be 100644
--- a/tex/context/base/attr-ini.mkiv
+++ b/tex/context/base/attr-ini.mkiv
@@ -14,8 +14,8 @@
\writestatus{loading}{ConTeXt Attribute Macros / Initialization}
%D Although it's still somewhat experimental, here we introduce code
-%D related to attributes. Housekeeping will move completely to \LUA\
-%D and \type {\newattribute} will go away.
+%D related to attributes. Housekeeping will move completely to Lua
+%D and \newattribute will go away.
\unprotect
@@ -27,16 +27,14 @@
\unexpanded\def\pushattribute#1%
{\global\advance\csname\??attributestack\string#1\endcsname\plusone
- \expandafter\xdef\csname\??attributestack\string#1:\number\csname\??attributestack\string#1\endcsname\endcsname{\number\attribute#1}}
+ \global\expandafter\mathchardef\csname\??attributestack\string#1:\number\csname\??attributestack\string#1\endcsname\endcsname\attribute#1}
\unexpanded\def\popattribute#1%
- {\attribute#1\csname\??attributestack\string#1:\number\csname\??attributestack\string#1\endcsname\endcsname\relax
+ {\attribute#1\csname\??attributestack\string#1:\number\csname\??attributestack\string#1\endcsname\endcsname
\global\advance\csname\??attributestack\string#1\endcsname\minusone}
\unexpanded\def\installattributestack#1%
- {\ifcsname\??attributestack\string#1\endcsname \else
- \expandafter\newcount\csname\??attributestack\string#1\endcsname
- \fi}
+ {\expandafter\newcount\csname\??attributestack\string#1\endcsname}
\newtoks \attributesresetlist
diff --git a/tex/context/base/attr-lay.lua b/tex/context/base/attr-lay.lua
index 5e5e81ff1..bcdc541f7 100644
--- a/tex/context/base/attr-lay.lua
+++ b/tex/context/base/attr-lay.lua
@@ -10,15 +10,9 @@ if not modules then modules = { } end modules ['attr-lay'] = {
-- but when we need it stacked layers might show up too; the next function based
-- approach can be replaced by static (metatable driven) resolvers
--- maybe use backends.registrations here too
-
local type = type
local format = string.format
-local insert, remove, concat = table.insert, table.remove, table.concat
-
-local attributes, nodes, utilities, logs, backends = attributes, nodes, utilities, logs, backends
-local commands, context, interfaces = commands, context, interfaces
-local tex = tex
+local insert, remove = table.insert, table.remove
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
@@ -32,6 +26,8 @@ local report_viewerlayers = logs.reporter("viewerlayers")
-- nb. too many "0 g"s
-- nb: more local tables
+local attributes, nodes = attributes, nodes
+
attributes.viewerlayers = attributes.viewerlayers or { }
local viewerlayers = attributes.viewerlayers
@@ -61,42 +57,22 @@ local texgetattribute = tex.getattribute
local texsettokenlist = tex.settoks
local unsetvalue = attributes.unsetvalue
-local nodepool = nodes.pool
-
-local data = viewerlayers.data
-local values = viewerlayers.values
-local listwise = viewerlayers.listwise
-local registered = viewerlayers.registered
-local scopes = viewerlayers.scopes
-
-local template = "%s"
+storage.register("attributes/viewerlayers/registered", viewerlayers.registered, "attributes.viewerlayers.registered")
+storage.register("attributes/viewerlayers/values", viewerlayers.values, "attributes.viewerlayers.values")
+storage.register("attributes/viewerlayers/scopes", viewerlayers.scopes, "attributes.viewerlayers.scopes")
-storage.register("attributes/viewerlayers/registered", registered, "attributes.viewerlayers.registered")
-storage.register("attributes/viewerlayers/values", values, "attributes.viewerlayers.values")
-storage.register("attributes/viewerlayers/scopes", scopes, "attributes.viewerlayers.scopes")
-
-local layerstacker = utilities.stacker.new("layers") -- experiment
-
-layerstacker.mode = "stack"
-layerstacker.unset = attributes.unsetvalue
-
-viewerlayers.resolve_begin = layerstacker.resolve_begin
-viewerlayers.resolve_step = layerstacker.resolve_step
-viewerlayers.resolve_end = layerstacker.resolve_end
-
-function commands.cleanuplayers()
- layerstacker.clean()
- -- todo
-end
+local data = viewerlayers.data
+local values = viewerlayers.values
+local listwise = viewerlayers.listwise
+local registered = viewerlayers.registered
+local scopes = viewerlayers.scopes
+local template = "%s"
-- stacked
-local function startlayer(...) startlayer = nodeinjections.startlayer return startlayer(...) end
-local function stoplayer (...) stoplayer = nodeinjections.stoplayer return stoplayer (...) end
-
local function extender(viewerlayers,key)
if viewerlayers.supported and key == "none" then
- local d = stoplayer()
+ local d = nodeinjections.stoplayer()
viewerlayers.none = d
return d
end
@@ -106,7 +82,7 @@ local function reviver(data,n)
if viewerlayers.supported then
local v = values[n]
if v then
- local d = startlayer(v)
+ local d = nodeinjections.startlayer(v)
data[n] = d
return d
else
@@ -115,14 +91,8 @@ local function reviver(data,n)
end
end
-setmetatableindex(viewerlayers,extender)
-setmetatableindex(viewerlayers.data,reviver)
-
--- !!!! TEST CODE !!!!
-
-layerstacker.start = function(...) local f = nodeinjections.startstackedlayer layerstacker.start = f return f(...) end
-layerstacker.stop = function(...) local f = nodeinjections.stopstackedlayer layerstacker.stop = f return f(...) end
-layerstacker.change = function(...) local f = nodeinjections.changestackedlayer layerstacker.change = f return f(...) end
+setmetatableindex(viewerlayers, extender)
+setmetatableindex(viewerlayers.data, reviver)
local function initializer(...)
return states.initialize(...)
@@ -133,8 +103,7 @@ attributes.viewerlayers.handler = nodes.installattributehandler {
namespace = viewerlayers,
initializer = initializer,
finalizer = states.finalize,
- -- processor = states.stacked,
- processor = states.stacker,
+ processor = states.stacked,
}
local stack, enabled, global = { }, false, false
@@ -180,16 +149,12 @@ function viewerlayers.setfeatures(hasorder)
viewerlayers.hasorder = hasorder
end
-local usestacker = true -- new, experimental
-
function viewerlayers.start(name)
- local a
- if usestacker then
- a = layerstacker.push(register(name) or unsetvalue)
- else
- insert(stack,texgetattribute(a_viewerlayer))
- a = register(name) or unsetvalue
- end
+-- if not enabled then
+-- viewerlayers.enable(true)
+-- end
+ insert(stack,texgetattribute(a_viewerlayer))
+ local a = register(name) or unsetvalue
if global or scopes[name] == v_global then
scopes[a] = v_global -- messy but we don't know the attributes yet
texsetattribute("global",a_viewerlayer,a)
@@ -200,21 +165,14 @@ function viewerlayers.start(name)
end
function viewerlayers.stop()
- local a
- if usestacker then
- a = layerstacker.pop()
- else
- a = remove(stack)
- end
- if not a then
- -- error
- elseif a >= 0 then
+ local a = remove(stack)
+ if a >= 0 then
if global or scopes[a] == v_global then
texsetattribute("global",a_viewerlayer,a)
else
texsetattribute(a_viewerlayer,a)
end
- texsettokenlist("currentviewerlayertoks",values[a] or "")
+ texsettokenlist("currentviewerlayertoks",values[a])
else
if global or scopes[a] == v_global then
texsetattribute("global",a_viewerlayer,unsetvalue)
@@ -239,9 +197,9 @@ function viewerlayers.define(settings)
end
end
-commands.defineviewerlayer = viewerlayers.define
-commands.startviewerlayer = viewerlayers.start
-commands.stopviewerlayer = viewerlayers.stop
+commands.defineviewerlayer = viewerlayers.define
+commands.startviewerlayer = viewerlayers.start
+commands.stopviewerlayer = viewerlayers.stop
function commands.definedviewerlayer(settings)
viewerlayers.define(settings)
diff --git a/tex/context/base/attr-lay.mkiv b/tex/context/base/attr-lay.mkiv
index 9c9c3318e..67cd204e2 100644
--- a/tex/context/base/attr-lay.mkiv
+++ b/tex/context/base/attr-lay.mkiv
@@ -13,51 +13,51 @@
\writestatus{loading}{ConTeXt Attribute Macros / Viewerlayers}
-%D Currently there is a limitation in mixed inline usage. This has to do with the fact
-%D that we have a stacked model but cannot determine where to revert to (as we can
-%D have AABBCCAA ranges). Maybe I'll solve that one day. It only affects nested inline
-%D layers and these make not much sense anyway. We'd have to store the complete nesting
-%D stack in the attribute in order to be able to cross pages and that demands a new
-%D mechanism.
-
\unprotect
\registerctxluafile{attr-lay}{1.001}
% needs to work over stopitemize grouping etc
-\installcorenamespace{viewerlayer}
-
-\installcommandhandler \??viewerlayer {viewerlayer} \??viewerlayer
+% \def\registerviewerlayer#1#2% global !
+% {\setxvalue{\??ql:#1}{\global\attribute\viewerlayerattribute\ctxlua{tex.write(attributes.viewerlayers.register('#2'))} }}
+%
+% \setevalue{\??ql:}{\global\attribute\viewerlayerattribute\attributeunsetvalue}
-\setupviewerlayer
+\getparameters
+ [\??lr]
[\c!state=\v!start,
\c!title=,
\c!printable=\v!yes,
\c!scope=\v!local, % maybe global but needs checking with layout
\c!method=\v!none]
-\appendtoks
- \ctxcommand{defineviewerlayer{
- tag = "\currentviewerlayer",
- title = "\viewerlayerparameter\c!title",
- visible = "\viewerlayerparameter\c!state",
- editable = "\v!yes",
- printable = "\viewerlayerparameter\c!printable",
- scope = "\viewerlayerparameter\c!scope"
- }}%
- \doif{\viewerlayerparameter\c!method}\v!command
- {\setuxvalue{\e!start#1}{\startviewerlayer[\currentviewerlayer]}%
- \setuxvalue{\e!stop #1}{\stopviewerlayer}}%
-\to \everydefineviewerlayer
-
-\unexpanded\def\startviewerlayer[#1]{\ctxcommand{startviewerlayer("#1")}} % not grouped
-\unexpanded\def\stopviewerlayer {\ctxcommand{stopviewerlayer()}} % not grouped
+\def\defineviewerlayer
+ {\dodoubleargument\dodefineviewerlayer}
+
+\def\dodefineviewerlayer[#1][#2]% document wide properties
+ {\begingroup
+ \getparameters[\??lr][#2]%
+ \ctxcommand{defineviewerlayer{
+ tag = "#1",
+ title = "\@@lrtitle",
+ visible = "\@@lrstate",
+ editable = "\v!yes",
+ printable = "\@@lrprintable",
+ scope = "\@@lrscope"
+ }}%
+ \doif\@@lrmethod\v!command
+ {\setugvalue{\e!start#1}{\startviewerlayer[#1]}%
+ \setugvalue{\e!stop #1}{\stopviewerlayer }}%
+ \endgroup}
+
+\unexpanded\def\startviewerlayer[#1]{\ctxcommand{startviewerlayer("#1")}} % not grouped
+\unexpanded\def\stopviewerlayer {\ctxcommand{stopviewerlayer()}} % not grouped
\unexpanded\def\viewerlayer [#1]{\groupedcommand{\startviewerlayer[#1]}{\stopviewerlayer}} % grouped
% some day we will keep this at the lua end as the info is only needed there
-\newtoks\currentviewerlayertoks % soon we can set macros at the lua end
+\let\currentviewerlayer\empty \newtoks\currentviewerlayertoks % soon we can set macros at the lua end
\def\currentviewerlayer{\the\currentviewerlayertoks}
@@ -67,9 +67,7 @@
% layout components are implemented rather directly (speed)
-\installcorenamespace{layoutcomponentattribute}
-
-\def\attr_layoutcomponent_initialize#1%
+\def\doinitializelayoutcomponent#1%
{\edef\layoutcomponentboxattribute{\ctxcommand{definedviewerlayer{%
tag = "#1",
title = utilities.strings.nice("#1"), % only here as in steps we have step:
@@ -78,28 +76,24 @@
printable = "\v!yes"
}}}%
\edef\layoutcomponentboxattribute{attr \viewerlayerattribute \layoutcomponentboxattribute\relax}%
- \expandafter\glet\csname\??layoutcomponentattribute#1\endcsname\layoutcomponentboxattribute}
+ \expandafter\glet\csname\??lr:a:#1\endcsname\layoutcomponentboxattribute}
-\def\attr_layoutcomponent_set#1% make this faster
- {\expandafter\let\expandafter\layoutcomponentboxattribute\csname\??layoutcomponentattribute#1\endcsname
+\def\dosetlayoutcomponentattribute#1% make this faster
+ {\expandafter\let\expandafter\layoutcomponentboxattribute\csname\??lr:a:#1\endcsname
\ifx\layoutcomponentboxattribute\relax
- \attr_layoutcomponent_initialize{#1}% get rid of { }
+ \doinitializelayoutcomponent{#1}% get rid of { }
\fi}
-\def\attr_layoutcomponent_reset
+\def\doresetlayoutcomponentattribute
{\let\layoutcomponentboxattribute\empty}
\let\setlayoutcomponentattribute \gobbleoneargument
\let\resetlayoutcomponentattribute\relax
\let\layoutcomponentboxattribute \empty
-\unexpanded\def\showlayoutcomponents
- {%\ctxlua{attributes.viewerlayers.enable()}% automatic
- \let\setlayoutcomponentattribute \attr_layoutcomponent_set
- \let\resetlayoutcomponentattribute\attr_layoutcomponent_reset}
-
-\appendtoks
- \ctxcommand{cleanuplayers()}%
-\to \everyshipout
+\def\showlayoutcomponents
+ {\ctxlua{attributes.viewerlayers.enable()}% will go
+ \let\setlayoutcomponentattribute \dosetlayoutcomponentattribute
+ \let\resetlayoutcomponentattribute\doresetlayoutcomponentattribute}
\protect \endinput
diff --git a/tex/context/base/attr-neg.lua b/tex/context/base/attr-neg.lua
index c32cec956..4d89cb49b 100644
--- a/tex/context/base/attr-neg.lua
+++ b/tex/context/base/attr-neg.lua
@@ -11,9 +11,8 @@ if not modules then modules = { } end modules ['attr-neg'] = {
local format = string.format
-local attributes, nodes, utilities, logs, backends = attributes, nodes, utilities, logs, backends
-local commands, context, interfaces = commands, context, interfaces
-local tex = tex
+
+local attributes, nodes = attributes, nodes
local states = attributes.states
local tasks = nodes.tasks
diff --git a/tex/context/base/attr-neg.mkiv b/tex/context/base/attr-neg.mkiv
index 102b220ba..0fc5070f1 100644
--- a/tex/context/base/attr-neg.mkiv
+++ b/tex/context/base/attr-neg.mkiv
@@ -19,12 +19,12 @@
% positive and negative are preregistered
-\unexpanded\def\startnegative{\attr_trigger_negative\v!negative}
-\unexpanded\def\stopnegative {\attr_trigger_negative\v!positive}
+\def\dotriggernegative#1{\ctxcommand{triggernegative('#1')}}
-\unexpanded\def\startpositive{\attr_trigger_negative\v!positive}
-\unexpanded\def\stoppositive {\attr_trigger_negative\v!negative}
+\unexpanded\def\startnegative{\dotriggernegative\v!negative}
+\unexpanded\def\stopnegative {\dotriggernegative\v!positive}
-\def\attr_trigger_negative#1{\ctxcommand{triggernegative('#1')}}
+\unexpanded\def\startpositive{\dotriggernegative\v!positive}
+\unexpanded\def\stoppositive {\dotriggernegative\v!negative}
\protect \endinput
diff --git a/tex/context/base/back-exp.lua b/tex/context/base/back-exp.lua
index 46ce4f96c..3ce40a6c5 100644
--- a/tex/context/base/back-exp.lua
+++ b/tex/context/base/back-exp.lua
@@ -20,9 +20,8 @@ if not modules then modules = { } end modules ['back-exp'] = {
local next, type = next, type
local format, match, concat, rep, sub, gsub, gmatch, find = string.format, string.match, table.concat, string.rep, string.sub, string.gsub, string.gmatch, string.find
-local validstring = string.valid
local lpegmatch = lpeg.match
-local utfchar, utfbyte = utf.char, utf.byte
+local utfchar, utfbyte, utfsub, utfgsub = utf.char, utf.byte, utf.sub, utf.gsub
local insert, remove = table.insert, table.remove
local topoints = number.topoints
local utfvalues = string.utfvalues
@@ -155,8 +154,6 @@ local somespace = { [0x20] = true, [" "] = true } -- for testing
local entities = { ["&"] = "&", [">"] = ">", ["<"] = "<" }
local attribentities = { ["&"] = "&", [">"] = ">", ["<"] = "<", ['"'] = "quot;" }
-local entityremapper = utf.remapper(entities)
-
local alignmapping = {
flushright = "right",
middle = "center",
@@ -303,7 +300,7 @@ local usedstyles = { }
local documenttemplate = [[
document {
- font-size : %s !important ;
+ font-size : %s !important ;
max-width : %s !important ;
text-align : %s !important ;
hyphens : %s !important ;
@@ -385,7 +382,7 @@ local function allusedimages(xmlfile)
for element, details in sortedhash(usedimages) do
for detail, data in sortedhash(details) do
local name = data.name
- if file.suffix(name) == "pdf" then
+ if file.extname(name) == "pdf" then
-- temp hack .. we will have a remapper
name = file.replacesuffix(name,"svg")
end
@@ -400,7 +397,7 @@ local function uniqueusedimages()
for element, details in next, usedimages do
for detail, data in next, details do
local name = data.name
- if file.suffix(name) == "pdf" then
+ if file.extname(name) == "pdf" then
unique[file.replacesuffix(name,"svg")] = name
else
unique[name] = name
@@ -1354,7 +1351,7 @@ local function begintag(result,element,nature,depth,di,skip)
end
result[#result+1] = format("%s\n",spaces[depth])
for k, v in table.sortedpairs(metadata) do
- v = entityremapper(v)
+ v = utfgsub(v,".",entities)
result[#result+1] = format("%s%s\n",spaces[depth+1],k,v)
end
result[#result+1] = format("%s\n",spaces[depth])
@@ -1412,7 +1409,7 @@ local function flushtree(result,data,nature,depth)
-- whatever
elseif di.content then
-- already has breaks
- local content = entityremapper(di.content)
+ local content = utfgsub(di.content,".",entities)
if i == nofdata and sub(content,-1) == "\n" then -- move check
-- can be an end of line in par but can also be the last line
if trace_spacing then
@@ -2365,21 +2362,12 @@ local function stopexport(v)
report_export("saving xhtml variant in '%s",xhtmlfile)
local xmltree = cleanxhtmltree(xml.convert(results))
xml.save(xmltree,xhtmlfile)
- -- looking at identity is somewhat redundant as we also inherit from interaction
- -- at the tex end
- local identity = interactions.general.getidentity()
local specification = {
name = file.removesuffix(v),
identifier = os.uuid(),
images = uniqueusedimages(),
root = xhtmlfile,
files = files,
- language = languagenames[tex.count.mainlanguagenumber],
- title = validstring(finetuning.title) or validstring(identity.title),
- subtitle = validstring(finetuning.subtitle) or validstring(identity.subtitle),
- author = validstring(finetuning.author) or validstring(identity.author),
- firstpage = validstring(finetuning.firstpage),
- lastpage = validstring(finetuning.lastpage),
}
report_export("saving specification in '%s' (mtxrun --script epub --make %s)",specificationfilename,specificationfilename)
io.savedata(specificationfilename,table.serialize(specification,true))
diff --git a/tex/context/base/back-exp.mkiv b/tex/context/base/back-exp.mkiv
index 9e65633d4..871d08b19 100644
--- a/tex/context/base/back-exp.mkiv
+++ b/tex/context/base/back-exp.mkiv
@@ -132,11 +132,6 @@
[\c!align=\number\raggedstatus,
\c!bodyfont=\bodyfontsize,
\c!width=\textwidth,
- \c!title={\directinteractionparameter\c!title},
- \c!subtitle={\directinteractionparameter\c!subtitle},
- \c!author={\directinteractionparameter\c!author},
- % \c!firstpage=, % imagename
- % \c!lastpage=, % imagename
\c!hyphen=\v!no]
\def\dosynchronizeexport
@@ -146,21 +141,12 @@
bodyfont = \number\dimexpr\exportparameter\c!bodyfont,
width = \number\dimexpr\exportparameter\c!width,
hyphen = "\exportparameter\c!hyphen",
- title = \!!bs\exportparameter\c!title\!!es,
- subtitle = \!!bs\exportparameter\c!subtitle\!!es,
- author = \!!bs\exportparameter\c!author\!!es,
- firstpage = "\exportparameter\c!firstpage",
- lastpage = "\exportparameter\c!lastpage",
}}}
\appendtoks
- \doifsomething{\backendparameter\c!export}\dosynchronizeexport
+ \doifsomething{\backendparameter\c!export}{\dosynchronizeexport}%
\to \everystarttext
-\appendtoks
- \doifsomething{\backendparameter\c!export}\dosynchronizeexport % in case it is done inside \starttext
-\to \everysetupdocument
-
\appendtoks
\doifsomething{\backendparameter\c!xhtml}
{\enabledirectives[backend.export.xhtml=\backendparameter\c!xhtml]}%
@@ -169,11 +155,11 @@
\to \everysetupbackend
\appendtoks
- \doifelsenothing{\backendparameter\c!export}
- {\resetsystemmode\v!export}
- {\setuptagging[\c!state=\v!start]%
- \enabledirectives[backend.export=\backendparameter\c!export]%
- \setsystemmode\v!export}%
+ \doifsomething{\backendparameter\c!export}
+ {\setuptagging
+ [\c!state=\v!start]%
+ \enabledirectives
+ [backend.export=\backendparameter\c!export]}%
\to \everysetupbackend
\protect \endinput
diff --git a/tex/context/base/back-ini.lua b/tex/context/base/back-ini.lua
index f76b85438..0c02e201a 100644
--- a/tex/context/base/back-ini.lua
+++ b/tex/context/base/back-ini.lua
@@ -93,9 +93,9 @@ tables.vfspecials = allocate {
stopslant = comment,
}
--- experimental code --
+-- -- experimental code --
-function commands.pdfrotation(a) -- somewhat weird here
+function commands.pdfrotation(a)
local s, c = sind(a), cosd(a)
context("%s %s %s %s",c,s,-s,c)
end
diff --git a/tex/context/base/back-ini.mkiv b/tex/context/base/back-ini.mkiv
index fc8759c14..8ece8f6e1 100644
--- a/tex/context/base/back-ini.mkiv
+++ b/tex/context/base/back-ini.mkiv
@@ -61,13 +61,13 @@
\let \dotransformnextbox\gobblesixarguments % and pass last box
%D \macros
-%D {back_ovalbox}
+%D {doovalbox}
%D
%D When we look at the implementation, this is a complicated
%D one. There are seven arguments.
%D
%D \starttyping
-%D \back_ovalbox {w} {h} {d} {linewidth} {radius} {stroke} {fill} {variant}
+%D \doovalbox {w} {h} {d} {linewidth} {radius} {stroke} {fill} {variant}
%D \stoptyping
%D
%D This command has to return a \type{\vbox} which can be used
@@ -75,7 +75,7 @@
%D degrees, the stroke and fill are~\type{1} (true) of~\type{0}
%D (false).
-\let\back_ovalbox \gobbleeightarguments
+\let \doovalbox \gobbleeightarguments
%D \macros
%D {dostartclipping,dostopclipping}
diff --git a/tex/context/base/back-pdf.mkiv b/tex/context/base/back-pdf.mkiv
index 7e910f07f..9e441e224 100644
--- a/tex/context/base/back-pdf.mkiv
+++ b/tex/context/base/back-pdf.mkiv
@@ -68,17 +68,16 @@
{\ctxcommand{setxmpfile("\backendparameter{xmpfile}")}}%
\to \everysetupbackend
-% \doifsomething{\backendparameter\c!format} .. at the lua end
-
\appendtoks
- \ctxcommand{setformat {
+ \doifsomething{\backendparameter\c!format}
+ {\ctxcommand{setformat {
format = "\backendparameter\c!format",
level = "\backendparameter\c!level",
option = "\backendparameter\c!option",
profile = "\backendparameter\c!profile",
intent = "\backendparameter\c!intent",
file = "\backendparameter\c!file",
- }}%
+ }}}%
\to \everysetupbackend
%D For the moment we keep these.
@@ -221,12 +220,12 @@
\newbox\objectbox
-\unexpanded\def\dostartobject#1#2#3#4#5% needs to be \unexpanded
+\def\dostartobject#1#2#3#4#5%
{\bgroup
\setbox\objectbox\vbox\bgroup
\def\back_object_stop{\egroup\back_object_register{#1}{#2}}}
-\unexpanded\def\dostopobject % needs to be \unexpanded
+\def\dostopobject
{\back_object_stop
\egroup}
@@ -238,6 +237,9 @@
\immediate\pdfxform resources {\pdfbackendcurrentresources}\objectbox
\dosetobjectreference{#1}{#2}{\the\pdflastxform}}
+\def\doresetobjects
+ {}
+
\let\m_back_object_reference\empty
\def\doinsertobject#1#2%
@@ -261,7 +263,7 @@
% for the moment here
%D \macros
-%D {back_ovalbox}
+%D {doovalbox}
%D
%D Drawing frames with round corners is inherited from the
%D main module.
@@ -274,7 +276,7 @@
% \def\back_oval_calculate#1#2#3%
% {\PointsToBigPoints{\dimexpr#2+#3\relax}#1}
-\unexpanded\def\back_ovalbox#1#2#3#4#5#6#7#8%
+\unexpanded\def\doovalbox#1#2#3#4#5#6#7#8%
{\forcecolorhack
\bgroup
% \scratchdimen#4%
@@ -304,16 +306,16 @@
\PointsToBigPoints{\dimexpr #2-\scratchdimen}\yymax
\PointsToBigPoints{\dimexpr-#3+\scratchdimen}\yymin
%
- \edef\dostroke{\number#6}%
- \edef\dofill{\number#7}%
- \edef\mode{\number#8}%
+ \edef\dostroke{#6}%
+ \edef\dofill{#7}%
+ \edef\mode{\number#8 \space}%
% no \ifcase, else \relax in pdfcode
\setbox\scratchbox\hbox
{\ifnum\dostroke\dofill>\zerocount
\pdfliteral
{q
\stroke\space w
- \ifcase\mode\space
+ \ifcase\mode
\xxmin\space \ymin \space m
\xxmax\space \ymin \space l
\xmax \space \ymin \space \xmax \space \yymin\space y
@@ -493,7 +495,7 @@
\xmin \space \ymin \space \xmin \space \yymin\space y
\or % 28
\fi
- \ifnum\mode>8\space
+ \ifnum\mode>8
S
\else
\ifnum\dostroke=\plusone S \fi
diff --git a/tex/context/base/back-swf.mkiv b/tex/context/base/back-swf.mkiv
index 09745e0f9..1d225b550 100644
--- a/tex/context/base/back-swf.mkiv
+++ b/tex/context/base/back-swf.mkiv
@@ -11,12 +11,12 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D This is only a placeholder that demonstrates the usage of swf resources.
-%D There is no need to include this file into the format. The module was
-%D tested by Luigi and Willi and based on their suggestions the functionality
-%D was improved.
-%D
+% This is only a placeholder that demonstrates the usage of swf
+% resources.
+
%D \starttyping
+%D \starttext
+%D
%D \enabletrackers[graphics.locating]
%D \enabletrackers[backend.swf]
%D
@@ -41,6 +41,8 @@
%D \stopTEXpage
%D \stoptyping
+\stoptext
+
\endinput
\starttext
@@ -70,6 +72,8 @@
},
\stopluaparameterset
+\starttext
+
% preview=swf:myset:display:1
% controls=swf:myset:controls:1
% resources=swf:myset:resources:1
diff --git a/tex/context/base/back-u3d.mkiv b/tex/context/base/back-u3d.mkiv
index 89d26ee41..dfe8a90c2 100644
--- a/tex/context/base/back-u3d.mkiv
+++ b/tex/context/base/back-u3d.mkiv
@@ -11,9 +11,10 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D This is only a placeholder that demonstrates the usage of u3d resources. The
-%D user interface is rather messy an might be improved. The files and setup is
-%D derived from an example by Michael Vidiassov.
+% This is only a placeholder that demonstrates the usage of u3d
+% resources. The user interface is rather messy an might be
+% improved. The files and setup is derived from an example by
+% Michael Vidiassov.
\endinput
diff --git a/tex/context/base/bibl-bib.mkiv b/tex/context/base/bibl-bib.mkiv
index 7ca6799cf..56007d21c 100644
--- a/tex/context/base/bibl-bib.mkiv
+++ b/tex/context/base/bibl-bib.mkiv
@@ -626,7 +626,7 @@
\doifelse{\bibtexpublicationsparameter\c!method}\v!local
{\ctxlua{bibtex.hacks.reset(1)}}% function can take method
{\ctxlua{bibtex.hacks.reset(2)}}%
- \strc_lists_place_current
+ \doplacestructurelist
{\currentbibtexsession}
{\currentbibtexcriterium}
{\namedlistparameter\currentbibtexsession\c!number}%
diff --git a/tex/context/base/bibl-tra.lua b/tex/context/base/bibl-tra.lua
index ca6403c44..6341898ee 100644
--- a/tex/context/base/bibl-tra.lua
+++ b/tex/context/base/bibl-tra.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['bibl-tra'] = {
+if not modules then modules = { } end modules ['bibl-bib'] = {
version = 1.001,
comment = "this module is the basis for the lxml-* ones",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -115,7 +115,7 @@ function hacks.registerplaced(str)
end
function hacks.doifalreadyplaced(str)
- commands.doifelse(used[str])
+ commands.testcase(used[str])
end
-- we ask for :tag but when we can't find it we go back
diff --git a/tex/context/base/bibl-tra.mkiv b/tex/context/base/bibl-tra.mkiv
index 08d8eb6fe..3531703ad 100644
--- a/tex/context/base/bibl-tra.mkiv
+++ b/tex/context/base/bibl-tra.mkiv
@@ -755,7 +755,7 @@
\ctxlua{bibtex.hacks.filterall()}}
{\doif{\listparameter\c!criterium}\v!cite
{\setuplist[pubs][\c!criterium=\v!here]}%
- \strc_lists_place_current
+ \doplacestructurelist
{pubs}%
{\listparameter\c!criterium}%
{\listparameter\c!number}%
@@ -1244,7 +1244,7 @@
%D \type{\ixbibauthoryearref} stores the data in the macros
%D \type{\currentbibauthor} and \type{\currentbibyear}.
-\def\doifbibinteractionelse
+\def\ifbibinteractionelse
{\iflocation
\edef\test{\bibalternative\c!interaction}%
\ifx\test\v!stop
@@ -1256,11 +1256,20 @@
\@EA\secondoftwoarguments
\fi}
+\def\ifbibinteractionelse
+ {\iflocation
+ \doifelse{\bibalternative\c!interaction}\v!stop
+ {\@EA\secondoftwoarguments}
+ {\@EA\firstoftwoarguments}%
+ \else
+ \@EA\secondoftwoarguments
+ \fi}
+
\def\bibmaybeinteractive#1#2%
{\ifbibcitecompress
#2%
\else
- \doifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}%
+ \ifbibinteractionelse{\gotobiblink{#2}[#1]}{#2}%
\fi}
\def\bibauthoryearref[#1]%
@@ -1351,7 +1360,7 @@
\gotobiblink{#1}[#1]}
\def\bibgotoDOI#1#2%
- {\doifbibinteractionelse
+ {\ifbibinteractionelse
{\useURL[bibfooDoi#1][#2]%
\useURL[bibfoo#1][http://dx.doi.org/#2]%
\goto{\url[bibfooDoi#1]}[url(bibfoo#1)]}
@@ -1374,7 +1383,7 @@
\bibalternative\v!right}
\def\bibgotoURL#1#2%
- {\doifbibinteractionelse
+ {\ifbibinteractionelse
{\useURL[bibfoo#1][#2]\goto{\url[bibfoo#1]}[url(bibfoo#1)]}
{\hyphenatedurl{#2}}}
@@ -1402,7 +1411,7 @@
\def\dobibpageref#1%
{\bibinsertrefsep
- \doifbibinteractionelse
+ \ifbibinteractionelse
{\atbiblink[#1]}
{{\referencingfalse\at[#1]}}}
@@ -1475,6 +1484,8 @@
%D And some defaults are loaded from bibl-apa:
+\def\c!monthconversion{monthconversion} % todo
+
\setuppublications
[\c!monthconversion=,
\c!alternative=apa,
@@ -1491,6 +1502,4 @@
% \appendtoks \preloadbiblist \to \everysetuppublications
% \appendtoks \preloadbiblist \to \everystarttext
-\let\ifbibinteractionelse\doifbibinteractionelse
-
\protect \endinput
diff --git a/tex/context/base/blob-ini.lua b/tex/context/base/blob-ini.lua
index 4debaf94c..b97485b1b 100644
--- a/tex/context/base/blob-ini.lua
+++ b/tex/context/base/blob-ini.lua
@@ -74,7 +74,7 @@ function blobs.dispose(t)
end
end
-function blobs.append(t,str) -- compare concat and link
+function blobs.append(t,str) -- will be link nodes.link
local typ = type(str)
local dummy = nil
if typ == "number" then
diff --git a/tex/context/base/buff-ini.lua b/tex/context/base/buff-ini.lua
index 11d7cc9f6..7098679ca 100644
--- a/tex/context/base/buff-ini.lua
+++ b/tex/context/base/buff-ini.lua
@@ -13,23 +13,21 @@ local trace_visualize = false trackers.register("buffers.visualize", function(v
local report_buffers = logs.reporter("buffers","usage")
local report_grabbing = logs.reporter("buffers","grabbing")
-local context, commands = context, commands
-
local concat = table.concat
local type, next = type, next
local sub, format, match, find = string.sub, string.format, string.match, string.find
-local count, splitlines, validstring = string.count, string.splitlines, string.valid
+local count, splitlines = string.count, string.splitlines
-local variables = interfaces.variables
+local variables = interfaces.variables
local settings_to_array = utilities.parsers.settings_to_array
-local catcodenumbers = catcodes.numbers
+local ctxcatcodes = tex.ctxcatcodes
+local txtcatcodes = tex.txtcatcodes
-local ctxcatcodes = catcodenumbers.ctxcatcodes
-local txtcatcodes = catcodenumbers.txtcatcodes
+buffers = { }
-buffers = buffers or { }
local buffers = buffers
+local context = context
local cache = { }
@@ -102,17 +100,14 @@ commands.assignbuffer = assign
local P, patterns, lpegmatch = lpeg.P, lpeg.patterns, lpeg.match
-local anything = patterns.anything
-local alwaysmatched = patterns.alwaysmatched
-
local function countnesting(b,e)
local n
local g = P(b) / function() n = n + 1 end
+ P(e) / function() n = n - 1 end
- + anything
- local p = alwaysmatched / function() n = 0 end
+ + patterns.anything
+ local p = patterns.alwaysmatched / function() n = 0 end
* g^0
- * alwaysmatched / function() return n end
+ * patterns.alwaysmatched / function() return n end
return p
end
@@ -155,10 +150,12 @@ function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes) -- maybe
else
if continue then
dn = dn .. sub(bufferdata,2,-2) -- no \r, \n is more generic
- elseif dn == "" then
- dn = sub(bufferdata,2,-2)
else
- dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic
+ if dn == "" then
+ dn = sub(bufferdata,2,-2)
+ else
+ dn = dn .. "\n" .. sub(bufferdata,2,-2) -- no \r, \n is more generic
+ end
end
local last = sub(dn,-1)
if last == "\n" or last == "\r" then -- \n is unlikely as \r is the endlinechar
@@ -187,7 +184,7 @@ function commands.grabbuffer(name,begintag,endtag,bufferdata,catcodes) -- maybe
end
end
assign(name,dn,catcodes)
- commands.doifelse(more)
+ commands.testcase(more)
end
-- The optional prefix hack is there for the typesetbuffer feature and
@@ -235,12 +232,12 @@ end
function commands.getbuffer(name)
local str = getcontent(name)
if str ~= "" then
- context.viafile(str,format("buffer.%s",validstring(name,"noname")))
+ context.viafile(str)
end
end
function commands.getbuffermkvi(name) -- rather direct !
- context.viafile(resolvers.macros.preprocessed(getcontent(name)),format("buffer.%s.mkiv",validstring(name,"noname")))
+ context.viafile(resolvers.macros.preprocessed(getcontent(name)))
end
function commands.gettexbuffer(name)
@@ -268,7 +265,7 @@ function commands.getbufferctxlua(name)
end
function commands.doifelsebuffer(name)
- commands.doifelse(exists(name))
+ commands.testcase(exists(name))
end
-- This only used for mp buffers and is a kludge. Don't change the
diff --git a/tex/context/base/buff-ini.mkiv b/tex/context/base/buff-ini.mkiv
index 5f9d1d1e6..239a274c0 100644
--- a/tex/context/base/buff-ini.mkiv
+++ b/tex/context/base/buff-ini.mkiv
@@ -199,28 +199,4 @@
\def\getbufferdata[#1]{\buff_get_stored_indeed{#1}}
-%D This is a weird one, moved from cont-new. Do we really need it? If not
-%D it will go away.
-
-\bgroup \permitcircumflexescape
-
-\obeylines % don't remove %'s !
-
-\gdef\collapsedspace#1%
- {\ifx#1^^M%
- \expandafter\collapsedspace
- \else
- \space
- \expandafter#1%
- \fi}
-
-\unexpanded\gdef\collapsespaces
- {\prependtoksonce\relax\to\everyeof%
- \ignorelines%
- \ignoretabs%
- \let\obeyedspace\collapsedspace%
- \obeyspaces}
-
-\egroup
-
\protect \endinput
diff --git a/tex/context/base/buff-par.lua b/tex/context/base/buff-par.lua
index 29742f497..2015b0bc0 100644
--- a/tex/context/base/buff-par.lua
+++ b/tex/context/base/buff-par.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['buff-par'] = {
+if not modules then modules = { } end modules ['buff-ini'] = {
version = 1.001,
comment = "companion to buff-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -6,26 +6,21 @@ if not modules then modules = { } end modules ['buff-par'] = {
license = "see context related readme files"
}
-local context, commands = context, commands
-
-local insert, remove, find, gmatch = table.insert, table.remove, string.find, string.gmatch
-local strip, format = string.strip, string.format
-
-local trace_parallel = false trackers.register("buffers.parallel", function(v) trace_parallel = v end)
+local trace_parallel = false trackers.register("buffers.parallel", function(v) trace_parallel = v end)
local report_parallel = logs.reporter("buffers","parallel")
-local variables = interfaces.variables
+local insert, remove, find, gmatch = table.insert, table.remove, string.find, string.gmatch
+local strip, format = string.strip, string.format
-local parallel = buffers.parallel or { }
-buffers.parallel = parallel
+local variables = interfaces.variables
-local settings_to_array = utilities.parsers.settings_to_array
+buffers.parallel = { } local parallel = buffers.parallel
-local data = { }
+local data = { }
function parallel.define(category,tags)
- local tags = settings_to_array(tags)
+ local tags = utilities.parsers.settings_to_array(tags)
local entries = { }
data[category] = {
tags = tags,
@@ -43,7 +38,7 @@ function parallel.reset(category,tags)
if not tags or tags == "" or tags == variables.all then
tags = table.keys(entries)
else
- tags = settings_to_array(tags)
+ tags = utilities.parsers.settings_to_array(tags)
end
for i=1,#tags do
entries[tags[i]] = {
@@ -81,7 +76,7 @@ function parallel.save(category,tag,content)
end
-- maybe no strip
-- use lpeg
- if find(content,"%s*%[") then
+ if find(content,"^%s*%[") then
local done = false
for label, content in gmatch(content,"%s*%[(.-)%]%s*([^%[]+)") do
if done then
@@ -180,5 +175,5 @@ commands.placeparallel = parallel.place
commands.resetparallel = parallel.reset
function commands.doifelseparallel(category,tags)
- commands.doifelse(parallel.hassomecontent(category,tags))
+ commands.testcase(parallel.hassomecontent(category,tags))
end
diff --git a/tex/context/base/buff-par.mkiv b/tex/context/base/buff-par.mkiv
new file mode 100644
index 000000000..7d35676bd
--- /dev/null
+++ b/tex/context/base/buff-par.mkiv
@@ -0,0 +1,151 @@
+%D \module
+%D [ file=buff-par,
+%D version=2010.12.05,
+%D title=\CONTEXT\ Buffer Macros,
+%D subtitle=Parallel,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+\writestatus{loading}{ConTeXt Buffer Macros / Parallel}
+
+\registerctxluafile{buff-par}{1.001}
+
+%D This module is developped for Thomas Schmitz as part of
+%D a project.
+
+\unprotect
+
+\letvalue{\??px:}\empty
+
+\def\parallelparameter#1%
+ {\csname\??px:%
+ \ifcsname\??px:\currentparallel:\currentparallelinstance:#1\endcsname
+ \currentparallel:\currentparallelinstance:#1%
+ \else\ifcsname\??px:\currentparallel:#1\endcsname
+ \currentparallel:#1%
+ \else\ifcsname\??px:#1\endcsname
+ #1%
+ \fi\fi\fi
+ \endcsname}
+
+\unexpanded\def\defineparallel
+ {\dodoubleargument\dodefineparallel}
+
+\def\dodefineparallel[#1][#2]%
+ {\ctxcommand{defineparallel("#1","#2")}%
+ \processcommalist[#2]\dododefineparallel
+ \setuvalue{\e!start#1}{\dostartparallelset{#1}}%
+ \setuvalue{\e!stop #1}{\dostopparallelset}}
+
+\def\dododefineparallel#1%
+ {\definebuffer[#1]%%
+ \setuvalue{\e!stop#1}{\dowithparallel{#1}}}
+
+\def\dostartparallelset#1%
+ {\def\currentparallel{#1}%
+ \ctxcommand{nextparallel("\currentparallel")}}
+
+\def\dostopparallelset#1%
+ {}
+
+\def\dowithparallel#1% defined moet ook aan de lua kant kunnen
+ {\ctxcommand{saveparallel("\currentparallel","#1",buffers.raw("\thedefinedbuffer{#1}"))}}
+
+\unexpanded\def\placeparallel
+ {\dotripleempty\doplaceparallel}
+
+\def\doplaceparallel[#1][#2][#3]%
+ {\begingroup
+ \def\currentparallel{#1}%
+ \ctxcommand{placeparallel("\currentparallel","#2","#3")}%
+ \endgroup}
+
+% was: \parallelparameter\c!command}
+
+\def\doflushparallel#1#2#3#4#5% {instance}{status}{line}{label}{content}
+ {\begingroup
+ \def\currentparallelinstance{#1}%
+ \def\currentparallelnumber {#2}%
+ \def\currentparallelline {#3}%
+ \def\currentparallellabel {#4}%
+ \def\currentparallelcontent {#5}%
+ \ifcase#2\relax
+ \expandafter\noflushparalleldefault
+ \or
+ \expandafter\doflushparalleldefault
+ \fi
+ \endgroup}
+
+\def\noflushparalleldefault{}
+\def\doflushparalleldefault{\directsetup{\parallelparameter\c!setups}}
+
+\startsetups parallel:place:default
+ \hangafter\plusone
+ \hangindent4em
+ \dontleavehmode
+ \hbox to 3em \bgroup
+ \hss
+ \bf
+ \doifsomething \currentparallellabel {
+ \textreference[\currentparallellabel]{\currentparallelline}
+ }
+ \currentparallelline
+ \quad
+ \egroup
+ \currentparallelcontent
+ \par
+\stopsetups
+
+\unexpanded\def\setupparallel
+ {\dotripleempty\dosetupparallel}
+
+\def\dosetupparallel[#1][#2][#3]%
+ {\ifthirdargument
+ \getparameters[\??px:#1:#2:][#3]%
+ \else\ifsecondargument
+ \getparameters[\??px:#1:][#2]%
+ \else
+ \getparameters[\??px:][#1]% maybe no : here
+ \fi\fi}
+
+\setupparallel
+% [\c!command=\doflushparalleldefault]
+ [\c!setups=parallel:place:default]
+
+\def\doifelseparallel#1#2%
+ {\cldcontext{commands.doifelseparallel("#1","#2")}}
+
+\def\resetparallel
+ {\dodoubleempty\doresetparallel}
+
+\def\resetparallel[#1][#2]%
+ {\ctxcommand{resetparallel("#1","#2"))}}
+
+% default
+
+% \def\doflushparalleldefault#1#2#3#4% todo: setups instead
+% {\ifcase#1\or
+% \begingroup
+% \hangafter1
+% \hangindent4em
+% \dontleavehmode
+% \hbox to 3em{\hss\bf\doifsomething{#3}{\textreference[#3]{#2}}#2\quad}#4\par
+% \endgroup
+% \fi}
+
+\protect \endinput
+
+% \def\dododefineparallel#1%
+% {\setuvalue{\e!stop #1}{}%
+% \setuvalue{\e!start#1}{\dostartparallel{#1}}}
+%
+% \def\dostartparallel#1%
+% {\grabuntil{\e!stop#1}{\dododostartparallel{#1}}}
+%
+% \def\dododostartparallel#1#2%
+% {\ctxcommand{saveparallel("\currentparallel","#1",\!!bs\detokenize{#2}\!!es)}}
diff --git a/tex/context/base/buff-par.mkvi b/tex/context/base/buff-par.mkvi
deleted file mode 100644
index 404fa8ef3..000000000
--- a/tex/context/base/buff-par.mkvi
+++ /dev/null
@@ -1,131 +0,0 @@
-%D \module
-%D [ file=buff-par,
-%D version=2010.12.05,
-%D title=\CONTEXT\ Buffer Macros,
-%D subtitle=Parallel,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-\writestatus{loading}{ConTeXt Buffer Macros / Parallel}
-
-\registerctxluafile{buff-par}{1.001}
-
-%D This module is developped for Thomas Schmitz as part of a project. There is
-%D no documentation yet.
-%D
-%D \starttyping
-%D \defineparallel[main][one,two]
-%D
-%D \startmain
-%D \startone
-%D first 1
-%D [reference] first 2
-%D first 3
-%D \stopone
-%D \starttwo
-%D second 1
-%D \stoptwo
-%D \stopmain
-%D
-%D \placeparallel[main][one,two][criterium=all]
-
-%D criterium=all start= n=
-
-\unprotect
-
-\installcorenamespace{parallel}
-
-\installcommandhandler \??parallel {parallel} \??parallel
-
-\setupparallel
- [\c!setups=parallel:place:default]
-
-\let\buff_parallel_define_saved\defineparallel
-
-\unexpanded\def\defineparallel
- {\dodoubleargument\buff_parallel_define}
-
-\def\buff_parallel_define[#name][#instances]%
- {\buff_parallel_define_saved[#name]
- \ctxcommand{defineparallel("#name","#instances")}%
- \processcommalist[#instances]\buff_parallel_define_instance
- \setuevalue{\e!start#name}{\buff_parallel_start{#name}}%
- \setuevalue{\e!stop #name}{\buff_parallel_stop}}
-
-\def\buff_parallel_define_instance#instance%
- {\normalexpanded{\buff_parallel_define_saved[#instance][\currentparallel]}%
- \definebuffer[#instance]%
- \setuevalue{\e!stop#instance}{\buff_parallel_save{#instance}}}
-
-\unexpanded\def\buff_parallel_start#name%
- {\pushmacro\currentparallel
- \edef\currentparallel{#name}%
- \ctxcommand{nextparallel("\currentparallel")}}
-
-\unexpanded\def\buff_parallel_stop
- {\popmacro\currentparallel}
-
-\unexpanded\def\buff_parallel_save#instance% defined moet ook aan de lua kant kunnen
- {\ctxcommand{saveparallel("\currentparallel","#instance",buffers.raw("\thedefinedbuffer{#instance}"))}}
-
-\unexpanded\def\placeparallel
- {\dotripleempty\buff_parallel_place}
-
-\def\buff_parallel_place[#name][#instance][#settings]%
- {\begingroup
- \edef\currentparallel{#name}%
- \ctxcommand{placeparallel("\currentparallel","#instance","#settings")}% -- todo: pass options as k/v
- \endgroup}
-
-\def\doflushparallel#instance#status#line#label#content% called at lua end
- {\begingroup
- \def\currentparallelinstance{#instance}%
- \def\currentparallelnumber {#status}%
- \def\currentparallelline {#line}%
- \def\currentparallellabel {#label}%
- \def\currentparallelcontent {#content}%
- \ifcase#status\relax
- \expandafter\buff_parallel_flush_nop
- \or
- \expandafter\buff_parallel_flush_yes
- \fi
- \endgroup}
-
-\def\buff_parallel_flush_nop
- {}
-
-\def\buff_parallel_flush_yes
- {\directsetup{\namedparallelparameter\currentparallelinstance\c!setups}}
-
-\unexpanded\def\doifelseparallel#name#instance%
- {\ctxcommand{doifelseparallel("#name","#instance")}}
-
-\unexpanded\def\resetparallel
- {\dodoubleempty\buff_parallel_reset}
-
-\def\buff_parallel_reset[#name][#instance]%
- {\ctxcommand{resetparallel("#name","#instance"))}}
-
-\startsetups parallel:place:default
- \hangafter\plusone
- \hangindent4em
- \dontleavehmode
- \hbox to 3em \bgroup
- \hss
- \bf
- \doifsomething \currentparallellabel {
- \textreference[\currentparallellabel]{\currentparallelline}
- }
- \currentparallelline
- \quad
- \egroup
- \currentparallelcontent
- \par
-\stopsetups
-
-\protect \endinput
diff --git a/tex/context/base/buff-ver.lua b/tex/context/base/buff-ver.lua
index 5748d9298..004d89858 100644
--- a/tex/context/base/buff-ver.lua
+++ b/tex/context/base/buff-ver.lua
@@ -18,8 +18,6 @@ local concat = table.concat
local C, P, R, S, V, Carg, Cc, Cs = lpeg.C, lpeg.P, lpeg.R, lpeg.S, lpeg.V, lpeg.Carg, lpeg.Cc, lpeg.Cs
local patterns, lpegmatch, is_lpeg = lpeg.patterns, lpeg.match, lpeg.is_lpeg
-local context, commands = context, commands
-
local trace_visualize = false trackers.register("buffers.visualize", function(v) trace_visualize = v end)
local report_visualizers = logs.reporter("buffers","visualizers")
@@ -32,6 +30,7 @@ visualizers.specifications = specifications
local tabtospace = utilities.strings.tabtospace
local variables = interfaces.variables
local settings_to_array = utilities.parsers.settings_to_array
+local verbatim = context.verbatim
local variables = interfaces.variables
local findfile = resolvers.findfile
local addsuffix = file.addsuffix
@@ -53,7 +52,6 @@ local dodisplayverbatimemptyline = context.dodisplayverbatimemptyline
local dodisplayverbatimstart = context.dodisplayverbatimstart
local dodisplayverbatimstop = context.dodisplayverbatimstop
-local verbatim = context.verbatim
local doverbatimspace = context.doverbatimspace
local CargOne = Carg(1)
@@ -690,7 +688,7 @@ local getlines = buffers.getlines
-- interface
function commands.doifelsevisualizer(name)
- commands.doifelse(specifications[lower(name)])
+ commands.testcase(specifications[lower(name)])
end
commands.loadvisualizer = visualizers.load
diff --git a/tex/context/base/buff-ver.mkiv b/tex/context/base/buff-ver.mkiv
index d18883faf..5336c4458 100644
--- a/tex/context/base/buff-ver.mkiv
+++ b/tex/context/base/buff-ver.mkiv
@@ -70,22 +70,21 @@
\csname\??typingspace\typeparameter\c!space\endcsname
\relax\the\everyinitializeverbatim\relax}
-\unexpanded\def\doinitializeverbatim % for use elsewhere .. temp hack (see lxml-ini)
- {\buff_verbatim_initialize_type_one
- \buff_verbatim_initialize_type_two}
-
\let\buff_verbatim_set_line_margin\relax
\def\buff_verbatim_set_line_margin_indeed
- {\hskip\doifoddpageelse{\typingparameter\c!oddmargin}{\typingparameter\c!evenmargin}\relax}
+ {\getpagestatus
+ \hskip\ifrightpage\typingparameter\c!oddmargin\else\typingparameter\c!evenmargin\fi\relax}
\def\buff_verbatim_check_margins
{\scratchskip\typingparameter\c!oddmargin\relax
- \ifzeropt\scratchskip \else
+ \ifzeropt\scratchskip
+ \else
\let\buff_verbatim_set_line_margin\buff_verbatim_set_line_margin_indeed
\fi
\scratchskip\typingparameter\c!evenmargin\relax
- \ifzeropt\scratchskip \else
+ \ifzeropt\scratchskip
+ \else
\let\buff_verbatim_set_line_margin\buff_verbatim_set_line_margin_indeed
\fi
\ifx\buff_verbatim_set_line_margin\relax
@@ -332,7 +331,7 @@
\unexpanded\def\specialfixedspace {\kern\interwordspace\relax}
\unexpanded\def\specialobeyedspace {\hskip\interwordspace\relax} % better than spaceskip
-\unexpanded\def\specialstretchedspace{\hskip.5\interwordspace\s!plus.125\interwordstretch\relax} % more but not less
+\unexpanded\def\specialstretchedspace{\hskip.5\interwordspace\!!plus.125\interwordstretch\relax} % more but not less
\unexpanded\def\specialcontrolspace {\hskip\zeropoint\hbox{\normalcontrolspace}\hskip\zeropoint\relax}
\unexpanded\def\obeyhyphens
@@ -370,7 +369,7 @@
\let\inlinemathmarker \textdollar
\def\displaymathmarker{\textdollar\textdollar}
-\def\buff_verbatim_special_type#1#2#% # gobbles spaces
+\def\buff_verbatim_special_type#1#2%
{\dontleavehmode\bgroup
\buff_verbatim_initialize_type_one
\catcode\leftbraceasciicode \begingroupcatcode
@@ -391,8 +390,6 @@
\unexpanded\def\astype{\bgroup\usetypestyleandcolor\c!style\c!color\let\nexttoken}
-\unexpanded\def\asciistr#1{\dontleavehmode{\verbatimfont\detokenize{#1}}} % use in some old styles
-
%D The basic display verbatim commands are defined in an indirect way. As we
%D will see, they are a specific case of a more general mechanism.
@@ -644,9 +641,9 @@
\c!text=\v!no,
\c!style=\tt,
\c!indentnext=\v!yes,
- \c!margin=\zeropoint,
- \c!evenmargin=\zeropoint,
- \c!oddmargin=\zeropoint,
+ \c!margin=\!!zeropoint,
+ \c!evenmargin=\!!zeropoint,
+ \c!oddmargin=\!!zeropoint,
\c!blank=\v!line,
%\c!escape=, % yes | no | {START,STOP} | default when yes: {BTEX,ETEX}
\c!numbering=\v!no,
@@ -839,9 +836,4 @@
% \usevisualizerstyleandcolor\c!style\c!color
% \let\next}
-\appendtoks
- \def\type#1{\letterbackslash\checkedstrippedcsname#1}% or maybe detokenize
- \def\tex #1{\letterbackslash#1}%
-\to \everysimplifycommands
-
\protect \endinput
diff --git a/tex/context/base/catc-ctx.mkiv b/tex/context/base/catc-ctx.mkiv
index ddade7f52..bd5c16d69 100644
--- a/tex/context/base/catc-ctx.mkiv
+++ b/tex/context/base/catc-ctx.mkiv
@@ -128,18 +128,11 @@
% for the moment here:
-\normalprotected\def\starttexcode
+\def\starttexcode
{\pushcatcodetable
\catcodetable\prtcatcodes}
-\normalprotected\def\stoptexcode
- {\popcatcodetable}
-
-\normalprotected\def\startcontextcode
- {\pushcatcodetable
- \catcodetable\ctxcatcodes}
-
-\normalprotected\def\stopcontextcode
+\def\stoptexcode
{\popcatcodetable}
\endinput
diff --git a/tex/context/base/catc-def.mkiv b/tex/context/base/catc-def.mkiv
index cfbaed171..26e8cb11e 100644
--- a/tex/context/base/catc-def.mkiv
+++ b/tex/context/base/catc-def.mkiv
@@ -123,7 +123,7 @@
%D shortcuts to their character representation.
\chardef \^ = \circumflexasciicode
-\chardef \_ = \underscoreasciicode
+\chardef \_ = \underscoreasciicode % but way too wide in lm, so ... until that's fixed:
\chardef \& = \ampersandasciicode
\chardef \% = \commentasciicode
\chardef \# = \hashasciicode
@@ -133,9 +133,8 @@
\chardef \\ = \backslashasciicode
\chardef \| = \barasciicode
-% way too wide in lm, so one can also use:
-%
-% \def\_{\dontleavehmode \kern.06em \vbox{\hrule width.3em}} % this will become a \chardef
+%def\_{\leavevmode \kern.06em \vbox{\hrule width.3em}}
+\def\_{\dontleavehmode \kern.06em \vbox{\hrule width.3em}} % this will become a \chardef
%D From now on we can use the protection mechanisms.
diff --git a/tex/context/base/catc-ini.lua b/tex/context/base/catc-ini.lua
index d4f9b65af..b2c793a6a 100644
--- a/tex/context/base/catc-ini.lua
+++ b/tex/context/base/catc-ini.lua
@@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['catc-ini'] = {
license = "see context related readme files"
}
+-- todo: everywhere replace tex.ctxcatcodes -> catcodes.numbers.ctxcatcodes
+
catcodes = catcodes or { }
catcodes.numbers = catcodes.numbers or { }
catcodes.names = catcodes.names or { }
@@ -13,29 +15,26 @@ catcodes.names = catcodes.names or { }
storage.register("catcodes/numbers", catcodes.numbers, "catcodes.numbers")
storage.register("catcodes/names", catcodes.names, "catcodes.names")
-local numbers = catcodes.numbers
-local names = catcodes.names
-
-- this only happens at initime
function catcodes.register(name,number)
- numbers[name] = number
- local cnn = names[number]
+ catcodes.numbers[name] = number
+ local cnn = catcodes.names[number]
if cnn then
cnn[#cnn+1] = name
else
- names[number] = { name }
+ catcodes.names[number] = { name }
end
- tex[name] = number -- downward compatible
+ tex[name] = number
end
-- this only happens at runtime
-for k, v in next, numbers do
- tex[k] = v -- downward compatible
+for k, v in next, catcodes.numbers do
+ tex[k] = v
end
-- nasty
-table.setmetatableindex(numbers,function(t,k) if type(k) == "number" then t[k] = k return k end end)
-table.setmetatableindex(names, function(t,k) if type(k) == "string" then t[k] = k return k end end)
+table.setmetatableindex(catcodes.numbers,function(t,k) if type(k) == "number" then t[k] = k return k end end)
+table.setmetatableindex(catcodes.names, function(t,k) if type(k) == "string" then t[k] = k return k end end)
diff --git a/tex/context/base/catc-ini.mkiv b/tex/context/base/catc-ini.mkiv
index 791ce31c4..26c3ceee9 100644
--- a/tex/context/base/catc-ini.mkiv
+++ b/tex/context/base/catc-ini.mkiv
@@ -87,17 +87,6 @@
\xdef\outputnewlinechar{^^J}%
\endgroup}
-%D We predefine some prefixes ahead of syst-aux and mult-sys. We reserve 8 slots
-%D for catcodes.
-
-\def\??catcodelet {1>>} % let : \let
-\def\??catcodedef {2>>} % def : \def
-\def\??catcodeued {3>>} % ued : \unexpanded\def
-\def\??catcodeget {4>>} % \meaning
-
-\def\??catcodetablet{5>>}
-\def\??catcodetablen{6>>}
-
\newcount\c_syst_catcodes_n \c_syst_catcodes_n\zerocount % 0 = signal, so advance before allocate
\newcount\c_syst_catcodes_a
\newcount\c_syst_catcodes_b
@@ -105,7 +94,7 @@
\normalprotected\def\newcatcodetable#1% we could move the cctdefcounter to lua
{\global\advance\c_syst_catcodes_n\plusone
- \expandafter\xdef\csname\??catcodetablen\number\c_syst_catcodes_n\endcsname{\string#1}% logging
+ \expandafter\xdef\csname\??qm:n:\number\c_syst_catcodes_n\endcsname{\string#1}% logging
\newconstant#1%
#1\c_syst_catcodes_n
\ctxlua{catcodes.register("\expandafter\gobbleoneargument\string#1",\number#1)}}
@@ -162,7 +151,12 @@
\setnewconstant\c_syst_catcodes_hack\tildeasciicode
%D Once a catcode is assigned, the next assignments will happen
-%D faster.
+%D faster. We predefine some prefixes ahead of mult-sys.
+
+\def\??ql{@@ql} % let : \let
+\def\??qd{@@qd} % def : \def
+\def\??qu{@@qu} % ued : \unexpanded\def
+\def\??qm{@@qm} % \meaning
\def\letcatcodecommand{\afterassignment\syst_catcodes_let_a\c_syst_catcodes_a}
\def\defcatcodecommand{\afterassignment\syst_catcodes_def_a\c_syst_catcodes_a}
@@ -173,46 +167,46 @@
\def\syst_catcodes_ued_a{\afterassignment\syst_catcodes_ued_b\c_syst_catcodes_b}
\def\syst_catcodes_let_b % each time
- {\ifcsname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
- \csname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
+ {\ifcsname\??ql:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
+ \csname\??ql:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
\else
\expandafter\syst_catcodes_let_c
\fi}
\def\syst_catcodes_def_b % each time
- {\ifcsname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
- \csname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
+ {\ifcsname\??qd:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
+ \csname\??qd:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
\else
\expandafter\syst_catcodes_def_c
\fi}
\def\syst_catcodes_ued_b % each time
- {\ifcsname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
- \csname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
+ {\ifcsname\??qu:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname
+ \csname\??qu:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
\else
\expandafter\syst_catcodes_ued_c
\fi}
\def\syst_catcodes_let_c % only first time
- {\expandafter\gdef\csname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname\expandafter
- {\expandafter\let\csname\??catcodeget\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}%
+ {\expandafter\gdef\csname\??ql:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname\expandafter
+ {\expandafter\let\csname\??qm:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}%
\syst_catcodes_reinstate_unexpanded
- \csname\??catcodelet\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
+ \csname\??ql:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
\def\syst_catcodes_def_c % only first time (we could use \normalexpanded here)
- {\expandafter\gdef\csname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
+ {\expandafter\gdef\csname\??qd:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
\expandafter##\expandafter1\expandafter
- {\expandafter\def\csname\??catcodeget\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname{##1}}%
+ {\expandafter\def\csname\??qm:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname{##1}}%
\syst_catcodes_reinstate_normal
- \csname\??catcodedef\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
+ \csname\??qd:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
\def\syst_catcodes_ued_c % only first time
- {\expandafter\gdef\csname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
+ {\expandafter\gdef\csname\??qu:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\expandafter\endcsname
\expandafter##\expandafter1\expandafter
- {\expandafter\normalprotected\expandafter\def\csname\??catcodeget\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname{##1}}%
+ {\expandafter\normalprotected\expandafter\def\csname\??qm:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname{##1}}%
\syst_catcodes_reinstate_unexpanded
- \csname\??catcodeued\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
+ \csname\??qu:\number\c_syst_catcodes_a:\number\c_syst_catcodes_b\endcsname}
\def\reinstatecatcodecommand{\afterassignment\syst_catcodes_reinstate_normal\c_syst_catcodes_b}
@@ -233,8 +227,8 @@
\newconstant\defaultcatcodetable
\def\catcodecommand#1%
- {\csname\??catcodeget\number
- \ifcsname\??catcodeget\number\currentcatcodetable:\number#1\endcsname
+ {\csname\??qm:\number
+ \ifcsname\??qm:\number\currentcatcodetable:\number#1\endcsname
\currentcatcodetable \else \defaultcatcodetable
\fi
:\number#1\endcsname}
@@ -257,13 +251,13 @@
\normalprotected\def\pushcatcodetable
{\advance\c_syst_catcodes_level\plusone
\syst_catcodes_trace_push
- \expandafter\chardef\csname\??catcodetablet\number\c_syst_catcodes_level\endcsname\currentcatcodetable}
+ \expandafter\chardef\csname\??qm:t:\number\c_syst_catcodes_level\endcsname\currentcatcodetable}
\normalprotected\def\popcatcodetable
{\ifcase\c_syst_catcodes_level
\syst_catcodes_trace_nesting_error
\else
- \expandafter\catcodetable\csname\??catcodetablet\number\c_syst_catcodes_level\endcsname
+ \expandafter\catcodetable\csname\??qm:t:\number\c_syst_catcodes_level\endcsname
\syst_catcodes_trace_pop
\advance\c_syst_catcodes_level\minusone
\fi}
@@ -275,7 +269,7 @@
\normalprotected\def\restorecatcodes % takes previous level
{\ifnum\c_syst_catcodes_level>\plusone
- \expandafter\catcodetable\csname\??catcodetablet\number\numexpr\c_syst_catcodes_level-1\relax\endcsname
+ \expandafter\catcodetable\csname\??qm:t:\number\numexpr\c_syst_catcodes_level-1\relax\endcsname
\fi}
% \newtoks\everycatcodetable
@@ -300,14 +294,14 @@
\def\syst_catcodes_prev
{\ifnum\numexpr\c_syst_catcodes_level-1\relax>\zerocount
- \csname\??catcodetablen\number\csname\??catcodetablet\number\numexpr\c_syst_catcodes_level-1\relax\endcsname\endcsname
+ \csname\??qm:n:\number\csname\??qm:t:\number\numexpr\c_syst_catcodes_level-1\relax\endcsname\endcsname
\else
-%
\fi}
\def\catcodetablename
{\ifnum\currentcatcodetable>\zerocount
- \csname\??catcodetablen\number\currentcatcodetable\endcsname
+ \csname\??qm:n:\number\currentcatcodetable\endcsname
\else
-%
\fi}
diff --git a/tex/context/base/char-cjk.lua b/tex/context/base/char-cjk.lua
index 3d7de1423..b077f4a3e 100644
--- a/tex/context/base/char-cjk.lua
+++ b/tex/context/base/char-cjk.lua
@@ -12,8 +12,7 @@ local floor = math.floor
local format = string.format
local utfchar = utf.char
-local ranges = characters.ranges
-local allocate = utilities.storage.allocate
+local ranges = characters.ranges
-- Hangul Syllable
@@ -210,7 +209,7 @@ local remapped = { -- this might be merged into char-def.lua
[0x11C2] = 0x314E, -- H
}
-characters.hangul = allocate {
+characters.hangul = {
decomposed = decomposed,
description = description,
leadconsonant = leadconsonant,
@@ -227,6 +226,24 @@ local hangul_syllable_basetable = {
linebreak = "h2",
}
+--~ local hangul_syllable_metatable = {
+--~ __index = function(t,k)
+--~ local u = t.unicodeslot
+--~ if k == "fscode" then
+--~ -- no need to cache this as we normally use fscodes
+--~ return leadconsonant(u)
+--~ elseif k == "shcode" then
+--~ return { decomposed(u) }
+--~ elseif k == "specials" then
+--~ return { "char", decomposed(u) }
+--~ elseif k == "description" then
+--~ return description(u)
+--~ else
+--~ return hangul_syllable_basetable[k]
+--~ end
+--~ end
+--~ }
+
local hangul_syllable_metatable = {
__index = function(t,k)
local u = t.unicodeslot
diff --git a/tex/context/base/char-def.lua b/tex/context/base/char-def.lua
index 6c73cf008..804468c2d 100644
--- a/tex/context/base/char-def.lua
+++ b/tex/context/base/char-def.lua
@@ -3,8 +3,7 @@ if not modules then modules = { } end modules ['char-def'] = {
comment = "companion to char-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
- dataonly = true,
+ license = "see context related readme files"
}
--[[
@@ -56833,16 +56832,6 @@ characters.data={
description="OVERLINE",
direction="on",
linebreak="al",
- mathspec={
- {
- class="topaccent",
- name="overbar",
- },
- {
- class="botaccent",
- name="underbar",
- },
- },
specials={ "compat", 0x0020, 0x0305 },
unicodeslot=0x203E,
},
@@ -57255,8 +57244,6 @@ characters.data={
description="SUPERSCRIPT PLUS SIGN",
direction="es",
linebreak="al",
- mathclass="binary",
- mathname ="positivesign",
specials={ "super", 0x002B },
unicodeslot=0x207A,
},
@@ -57265,8 +57252,6 @@ characters.data={
description="SUPERSCRIPT MINUS",
direction="es",
linebreak="al",
- mathclass="binary",
- mathname ="negativesign",
specials={ "super", 0x2212 },
unicodeslot=0x207B,
},
@@ -58684,7 +58669,7 @@ characters.data={
description="TURNED AMPERSAND",
direction="on",
linebreak="al",
- mathclass="binary",
+ mathclass="bin",
mathname="upand",
unicodeslot=0x214B,
},
@@ -60902,11 +60887,11 @@ characters.data={
linebreak="ai",
mathspec={
{
- class="binary",
+ class="bin",
name="vee",
},
{
- class="binary",
+ class="bin",
name="lor",
},
},
@@ -60947,16 +60932,15 @@ characters.data={
description="INTEGRAL",
direction="on",
linebreak="ai",
- mathclass="limop",
mathspec={
- {
- class="limop",
- name="int",
- },
{
class="nothing",
name="intop",
},
+ {
+ class="limop",
+ name="int",
+ },
},
unicodeslot=0x222B,
},
@@ -60967,16 +60951,15 @@ characters.data={
description="DOUBLE INTEGRAL",
direction="on",
linebreak="ai",
- mathclass="limop",
mathspec={
- {
- class="limop",
- name="iint",
- },
{
class="nothing",
name="iintop",
},
+ {
+ class="limop",
+ name="iint",
+ },
},
specials={ "compat", 0x222B, 0x222B },
unicodeslot=0x222C,
@@ -60986,16 +60969,15 @@ characters.data={
description="TRIPLE INTEGRAL",
direction="on",
linebreak="al",
- mathclass="limop",
mathspec={
- {
- class="limop",
- name="iiint",
- },
{
class="nothing",
name="iiintop",
},
+ {
+ class="limop",
+ name="iiint",
+ },
},
specials={ "compat", 0x222B, 0x222B, 0x222B },
unicodeslot=0x222D,
@@ -62420,7 +62402,7 @@ characters.data={
description="NORMAL SUBGROUP OF",
direction="on",
linebreak="al",
- mathclass="binary",
+ mathclass="bin",
mirror=0x22B3,
unicodeslot=0x22B2,
},
@@ -62430,7 +62412,7 @@ characters.data={
description="CONTAINS AS NORMAL SUBGROUP",
direction="on",
linebreak="al",
- mathclass="binary",
+ mathclass="bin",
mirror=0x22B2,
unicodeslot=0x22B3,
},
@@ -68406,8 +68388,6 @@ characters.data={
description="BLACK UP-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="binary",
- mathname="blacktriangle",
unicodeslot=0x25B2,
},
[0x25B3]={
@@ -68452,7 +68432,7 @@ characters.data={
description="BLACK RIGHT-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="binary",
+ mathclass="bin",
mathname="blacktriangleright",
unicodeslot=0x25B6,
},
@@ -68463,7 +68443,7 @@ characters.data={
description="WHITE RIGHT-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="binary",
+ mathclass="bin",
mathname="triangleright",
unicodeslot=0x25B7,
},
@@ -68472,6 +68452,8 @@ characters.data={
description="BLACK RIGHT-POINTING SMALL TRIANGLE",
direction="on",
linebreak="al",
+ mathclass="bin",
+ mathname="blacktriangleleft",
unicodeslot=0x25B8,
},
[0x25B9]={
@@ -68504,8 +68486,6 @@ characters.data={
description="BLACK DOWN-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="binary",
- mathname="blacktriangledown",
unicodeslot=0x25BC,
},
[0x25BD]={
@@ -68515,16 +68495,8 @@ characters.data={
description="WHITE DOWN-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathspec={
- {
- class="binary",
- name="triangledown",
- },
- {
- class="binary",
- name="bigtriangledown",
- },
- },
+ mathclass="binary",
+ mathname="bigtriangledown",
unicodeslot=0x25BD,
},
[0x25BE]={
@@ -68549,8 +68521,6 @@ characters.data={
description="BLACK LEFT-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="binary",
- mathname="blacktriangleleft",
unicodeslot=0x25C0,
},
[0x25C1]={
@@ -68560,7 +68530,7 @@ characters.data={
description="WHITE LEFT-POINTING TRIANGLE",
direction="on",
linebreak="ai",
- mathclass="binary",
+ mathclass="bin",
mathname="triangleleft",
unicodeslot=0x25C1,
},
diff --git a/tex/context/base/char-enc.lua b/tex/context/base/char-enc.lua
index 048837eec..ef6805e54 100644
--- a/tex/context/base/char-enc.lua
+++ b/tex/context/base/char-enc.lua
@@ -1,10 +1,9 @@
-if not modules then modules = { } end modules ['char-enc'] = {
+if not modules then modules = { } end modules ['char-syn'] = {
version = 1.001,
comment = "companion to char-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
- -- dataonly = true,
}
-- Thanks to tex4ht for these mappings.
@@ -145,25 +144,25 @@ characters.synonyms = allocate { -- afm mess
Yen = 0x00A5,
}
--- if not characters.enccodes then
---
--- local enccodes = { } characters.enccodes = enccodes
---
--- for unicode, data in next, characters.data do
--- local encname = data.adobename or data.contextname
--- if encname then
--- enccodes[encname] = unicode
--- end
--- end
---
--- for name, unicode in next, characters.synonyms do
--- if not enccodes[name] then enccodes[name] = unicode end
--- end
---
---
--- end
---
--- storage.register("characters.enccodes", characters.enccodes, "characters.enccodes")
+--~ if not characters.enccodes then
+--~
+--~ local enccodes = { } characters.enccodes = enccodes
+--~
+--~ for unicode, data in next, characters.data do
+--~ local encname = data.adobename or data.contextname
+--~ if encname then
+--~ enccodes[encname] = unicode
+--~ end
+--~ end
+--~
+--~ for name, unicode in next, characters.synonyms do
+--~ if not enccodes[name] then enccodes[name] = unicode end
+--~ end
+--~
+--~
+--~ end
+--~
+--~ storage.register("characters.enccodes", characters.enccodes, "characters.enccodes")
-- As this table is seldom used, we can delay its definition. Beware, this means
-- that table.print would not work on this file unless it is accessed once. This
diff --git a/tex/context/base/char-ent.lua b/tex/context/base/char-ent.lua
index ef55be7e4..d2ac22bbf 100644
--- a/tex/context/base/char-ent.lua
+++ b/tex/context/base/char-ent.lua
@@ -1,14 +1,15 @@
-if not modules then modules = { } end modules ['char-ent'] = {
+if not modules then modules = { } end modules ['math-ent'] = {
version = 1.001,
comment = "companion to math-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "derived from the mathml 2.0 specification",
- dataonly = true,
}
-- http://www.w3.org/2003/entities/2007/w3centities-f.ent
-- http://www.w3.org/2003/entities/2007/htmlmathml-f.ent
+-- this might go into char-def
+
local entities = utilities.storage.allocate {
["AElig"] = "Æ", -- U+000C6
["AMP"] = "&", -- U+00026
diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua
index 778035ff4..244b8d2a7 100644
--- a/tex/context/base/char-ini.lua
+++ b/tex/context/base/char-ini.lua
@@ -11,9 +11,10 @@ if not modules then modules = { } end modules ['char-ini'] = {
-- we can remove the tag range starting at 0xE0000 (special applications)
local tex = tex
+local utf = unicode.utf8
local utfchar, utfbyte, utfvalues = utf.char, utf.byte, string.utfvalues
-local ustring, utf = unicode.ustring, unicode.utf8
+local ustring = unicode.ustring
local concat, unpack, tohash = table.concat, table.unpack, table.tohash
local next, tonumber, type, rawget, rawset = next, tonumber, type, rawget, rawset
local format, lower, gsub, match, gmatch = string.format, string.lower, string.gsub, string.match, string.match, string.gmatch
@@ -27,8 +28,8 @@ local texsetsfcode = tex.setsfcode
local texsetcatcode = tex.setcatcode
local contextsprint = context.sprint
-local ctxcatcodes = catcodes.numbers.ctxcatcodes
-local texcatcodes = catcodes.numbers.texcatcodes
+local ctxcatcodes = tex.ctxcatcodes
+local texcatcodes = tex.texcatcodes
local setmetatableindex = table.setmetatableindex
@@ -47,6 +48,7 @@ loaded!
characters = characters or { }
local characters = characters
+
local data = characters.data
if data then
@@ -453,39 +455,28 @@ table we derive a few more.
if not characters.fallbacks then
- characters.fallbacks = { } -- not than many
+ -- we could the definition by using a metatable
+
+ characters.fallbacks = { }
+ characters.directions = { }
- local fallbacks = characters.fallbacks
+ local fallbacks = characters.fallbacks
+ local directions = characters.directions
- for k, d in next, data do
- local specials = d.specials
- if specials and specials[1] == "compat" and specials[2] == 0x0020 then
+ for k,v in next, data do
+ local specials = v.specials
+ if specials and specials[1] == "compat" and specials[2] == 0x0020 and specials[3] then
local s = specials[3]
- if s then
- fallbacks[k] = s
- fallbacks[s] = k
- end
+ fallbacks[k] = s
+ fallbacks[s] = k
end
+ directions[k] = v.direction
end
end
-storage.register("characters/fallbacks", characters.fallbacks, "characters.fallbacks") -- accents and such
-
-characters.directions = { }
-
-setmetatableindex(characters.directions,function(t,k)
- local d = data[k]
- if d then
- local v = d.direction
- if v then
- t[k] = v
- return v
- end
- end
- t[k] = false -- maybe 'l'
- return v
-end)
+storage.register("characters/fallbacks", characters.fallbacks, "characters.fallbacks") -- accents and such
+storage.register("characters/directions", characters.directions, "characters.directions")
--[[ldx--
The context namespace is used to store methods and data
@@ -497,7 +488,7 @@ which is rather specific to .
use the table. After all, we have this information available anyway.
--ldx]]--
-function characters.makeactive(n,name) --
+function characters.makeactive(n,name) -- let ?
contextsprint(ctxcatcodes,format("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name))
-- context("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name)
end
@@ -512,7 +503,7 @@ function tex.uprint(c,n)
end
end
-local forbidden = tohash { -- at least now
+local temphack = tohash {
0x00A0,
0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x200B, 0x200C, 0x200D,
0x202F,
@@ -548,10 +539,12 @@ function characters.define(tobelettered, tobeactivated) -- catcodetables
else
contextsprint(ctxcatcodes,format("\\def\\%s{%s}",contextname,utfchar(u))) -- has no s
end
- elseif is_command[category] and not forbidden[u] then
+ elseif is_command[category] then
+if not temphack[u] then
contextsprint("{\\catcode",u,"=13\\unexpanded\\gdef ",utfchar(u),"{\\"..contextname,"}}")
a = a + 1
activated[a] = u
+end
end
end
end
@@ -639,17 +632,15 @@ function characters.setcodes()
end
else
local lc, uc = chr.lccode, chr.uccode
- if not lc then
- chr.lccode, lc = code, code
- elseif type(lc) == "table" then
+ if not lc then chr.lccode, lc = code, code end
+ if not uc then chr.uccode, uc = code, code end
+ texsetcatcode(code,11) -- letter
+ if type(lc) == "table" then
lc = code
end
- if not uc then
- chr.uccode, uc = code, code
- elseif type(uc) == "table" then
+ if type(uc) == "table" then
uc = code
end
- texsetcatcode(code,11) -- letter
texsetlccode(code,lc,uc)
if cc == "lu" then
texsetsfcode(code,999)
@@ -824,7 +815,8 @@ function characters.unicodechar(asked)
if n then
return n
elseif type(asked) == "string" then
- return descriptions[asked] or descriptions[gsub(asked," ","")]
+ asked = gsub(asked," ","")
+ return descriptions[asked]
end
end
@@ -890,21 +882,17 @@ end
function characters.uccode(n) return uccodes[n] end -- obsolete
function characters.lccode(n) return lccodes[n] end -- obsolete
-function characters.safechar(n)
+function characters.flush(n,direct)
local c = data[n]
if c and c.contextname then
- return "\\" .. c.contextname
+ c = "\\" .. c.contextname
else
- return utfchar(n)
+ c = utfchar(n)
end
-end
-
-function commands.safechar(n)
- local c = data[n]
- if c and c.contextname then
- contextsprint("\\" .. c.contextname) -- context[c.contextname]()
+ if direct then
+ return c
else
- contextsprint(utfchar(n))
+ contextsprint(c)
end
end
diff --git a/tex/context/base/char-map.lua b/tex/context/base/char-map.lua
index 749da5289..376ebf343 100644
--- a/tex/context/base/char-map.lua
+++ b/tex/context/base/char-map.lua
@@ -3,8 +3,7 @@ if not modules then modules = { } end modules ['char-map'] = {
comment = "companion to char-ini.mkiv",
author = "Hans Hagen & Arthur Reutenauer",
copyright = "PRAGMA ADE / ConTeXt Development Team",
- license = "see context related readme files",
- dataonly = true,
+ license = "see context related readme files"
}
-- not yet used
diff --git a/tex/context/base/char-utf.lua b/tex/context/base/char-utf.lua
index 52fdfc0d0..a411c2d82 100644
--- a/tex/context/base/char-utf.lua
+++ b/tex/context/base/char-utf.lua
@@ -19,7 +19,7 @@ in special kinds of output (for instance ).
over a string.
--ldx]]--
-local utfchar, utfbyte = utf.char, utf.byte
+local utfchar, utfbyte, utfgsub = utf.char, utf.byte, utf.gsub
local concat, gmatch, gsub, find = table.concat, string.gmatch, string.gsub, string.find
local utfcharacters, utfvalues = string.utfcharacters, string.utfvalues
local allocate = utilities.storage.allocate
@@ -76,7 +76,6 @@ local decomposed = allocate {
["ﬖ"] = "վն",
["ﬗ"] = "մխ",
}
-
characters.decomposed = decomposed
local function initialize() -- maybe only 'mn'
@@ -210,13 +209,9 @@ end
private.set = set
--- function private.escape (str) return gsub(str,"(.)", escapes) end
--- function private.replace(str) return utfgsub(str,"(.)", low ) end
--- function private.revert (str) return utfgsub(str,"(.)", high ) end
-
-private.escape = utf.remapper(escapes)
-private.replace = utf.remapper(low)
-private.revert = utf.remapper(high)
+function private.escape (str) return gsub(str,"(.)", escapes) end
+function private.replace(str) return utfgsub(str,"(.)", low ) end
+function private.revert (str) return utfgsub(str,"(.)", high ) end
for ch in gmatch(special,".") do set(ch) end
@@ -486,14 +481,6 @@ if sequencers then
sequencers.enableaction(textfileactions,"characters.filters.utf.decompose")
end
- directives.register("filters.utf.collapse", function(v)
- sequencers[v and "enableaction" or "disableaction"](textfileactions,"characters.filters.utf.collapse")
- end)
-
- directives.register("filters.utf.decompose", function(v)
- sequencers[v and "enableaction" or "disableaction"](textfileactions,"characters.filters.utf.decompose")
- end)
-
end
--[[ldx--
diff --git a/tex/context/base/chem-ini.lua b/tex/context/base/chem-ini.lua
index 192953ec9..4d47982a2 100644
--- a/tex/context/base/chem-ini.lua
+++ b/tex/context/base/chem-ini.lua
@@ -17,8 +17,8 @@ local report_chemistry = logs.reporter("chemistry")
local context = context
-chemistry = chemistry or { }
-local chemistry = chemistry
+chemicals = chemicals or { }
+local chemicals = chemicals
--[[
The next code is an adaptation of code from Wolfgang Schuster
@@ -62,9 +62,9 @@ local high = Cc("\\high{%s}") * superscript * content
local justtext = (1 - somescript)^1
local parser = Cs((csname + lowhigh + highlow + low + high + sign + any)^0)
-chemistry.moleculeparser = parser -- can be used to avoid functioncall
+chemicals.moleculeparser = parser -- can be used to avoid functioncall
-function chemistry.molecule(str)
+function chemicals.molecule(str)
return lpegmatch(parser,str)
end
diff --git a/tex/context/base/chem-str.lua b/tex/context/base/chem-str.lua
index db1849c5a..fb325ccea 100644
--- a/tex/context/base/chem-str.lua
+++ b/tex/context/base/chem-str.lua
@@ -1,15 +1,12 @@
if not modules then modules = { } end modules ['chem-str'] = {
version = 1.001,
comment = "companion to chem-str.mkiv",
- author = "Hans Hagen and Alan Braslau",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
copyright = "PRAGMA ADE / ConTeXt Development Team",
license = "see context related readme files"
}
--- The original \PPCHTEX\ code was written in pure \TEX\, although later we made
--- the move from \PICTEX\ to \METAPOST\. The current implementation is a mix between
--- \TEX\, \LUA\ and \METAPOST. Although the first objective is to get a compatible
--- but better implementation, later versions might provide more,
+-- This module in incomplete and experimental.
-- We can push snippets into an mp instance.
@@ -29,12 +26,12 @@ local P, R, S, C, Cs, Ct, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct,
local variables = interfaces.variables
local context = context
-chemistry = chemistry or { }
-local chemistry = chemistry
+chemicals = chemicals or { }
+local chemicals = chemicals
-chemistry.instance = "metafun" -- "ppchtex"
-chemistry.format = "metafun"
-chemistry.structures = 0
+chemicals.instance = "metafun" -- "ppchtex"
+chemicals.format = "metafun"
+chemicals.structures = 0
local remapper = {
["+"] = "p",
@@ -55,9 +52,7 @@ local common_keys = {
mid = "fixed", mids = "fixed", midz = "text",
z = "text", rz = "text", mrz = "text", prz = "text", crz = "text",
rt = "text", rtt = "text", rbt = "text", zt = "text", zn = "number",
- zbt = "text", zbn = "number", ztt = "text", ztn = "number",
- mov = "transform", rot = "transform", adj = "transform", sub = "transform",
- off = "transform",
+ mov = "transform", rot = "transform", adj = "transform", dir = "transform", sub = "transform",
}
local front_keys = {
@@ -65,11 +60,9 @@ local front_keys = {
sb = "line", msb = "line", psb = "line",
r = "line", pr = "line", mr = "line",
z = "text", mrz = "text", prz = "text",
- zt = "text", zn = "number",
}
local one_keys = {
- b = "line", msb = "line", psb = "line",
sb = "line", db = "line", tb = "line",
ep = "line", es = "line", ed = "line", et = "line",
sd = "line", ldd = "line", rdd = "line",
@@ -88,16 +81,15 @@ local syntax = {
one = {
n = 1, max = 8, keys = one_keys,
align = {
- -- z = { { "r", "r_b", "b", "l_b", "l", "l_t", "t", "r_t" } },
- -- z = { { "r", "r", "b", "l", "l", "l", "t", "r" } },
+ z = { { "r", "r_b", "b", "l_b", "l", "l_t", "t", "r_t" } },
+--~ z = { { "r", "r", "b", "l", "l", "l", "t", "r" } },
}
},
three = {
n = 3, max = 3, keys = common_keys,
align = {
mrz = { { "r","b","l" }, { "b","l","t" }, { "l","t","r" }, { "t","r","b" } },
- rz = { { "auto","auto","auto" }, { "auto","auto","auto" }, { "auto","auto","auto" }, { "auto","auto","auto" } },
- -- rz = { { "r_t","r_b","l" }, { "r_b","l_b","t" }, { "l_b","l_t","r" }, { "l_t","r_t","b" } },
+ rz = { { "r","l_b","l_t" }, { "b","l_t","r_t" }, { "l","r_t","r_b" }, { "t","r_b","l_b" } },
prz = { { "r","l","t" }, { "b","t","r" }, { "l","r","b" }, { "t","b","l" } },
}
},
@@ -105,8 +97,7 @@ local syntax = {
n = 4, max = 4, keys = common_keys,
align = {
mrz = { { "t","r","b","l" }, { "r","b","l","t" }, { "b","l","t","r" }, { "l","t","r","b" } },
- rz = { { "auto","auto","auto","auto" }, { "auto","auto","auto","auto" }, { "auto","auto","auto","auto" }, { "auto","auto","auto","auto" } },
- -- rz = { { "r_t","r_b","l_b","l_t" }, { "r_b","l_b","l_t","r_t" }, { "l_b","l_t","r_t","r_b" }, { "l_t","r_t","r_b","l_b" } },
+ rz = { { "r_t","r_b","l_b","l_t" }, { "r_b","l_b","l_t","r_t" }, { "l_b","l_t","r_t","r_b" }, { "l_t","r_t","r_b","l_b" } },
prz = { { "r","b","l","t" }, { "b","l","t","r" }, { "l","t","r","b" }, { "t","r","b","l" } },
}
},
@@ -114,8 +105,7 @@ local syntax = {
n = 5, max = 5, keys = common_keys,
align = {
mrz = { { "t","r","b","b","l" }, { "r","b","l","l","t" }, { "b","l","t","r","r" }, { "l","t","r","r","b" } },
- rz = { { "auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto" } },
- -- rz = { { "r","r","b","l","t" }, { "b","b","l","t","r" }, { "l","l","t","r","b" }, { "t","t","r","b","l" } },
+ rz = { { "r","r","b","l","t" }, { "b","b","l","t","r" }, { "l","l","t","r","b" }, { "t","t","r","b","l" } },
prz = { { "r","b","l","t","t" }, { "b","l","t","r","r" }, { "l","t","r","b","b" }, { "t","r","b","l","l" } },
}
},
@@ -123,8 +113,7 @@ local syntax = {
n = 6, max = 6, keys = common_keys,
align = {
mrz = { { "t","t","r","b","b","l" }, { "r","b","b","l","t","t" }, { "b","b","l","t","t","r" }, { "l","t","t","r","b","b" } },
- rz = { { "auto","auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto","auto" } },
- -- rz = { { "r","r","b","l","l","t" }, { "b","b","l","t","t","r" }, { "l","l","t","r","r","b" }, { "t","t","r","b","b","l" } },
+ rz = { { "r","r","b","l","l","t" }, { "b","b","l","t","t","r" }, { "l","l","t","r","r","b" }, { "t","t","r","b","b","l" } },
prz = { { "r","b","l","l","t","r" }, { "b","l","t","t","r","b" }, { "l","t","r","r","b","l" }, { "t","r","b","b","l","t" } },
}
},
@@ -132,8 +121,7 @@ local syntax = {
n = 8, max = 8, keys = common_keys,
align = { -- todo
mrz = { { "t","r","r","b","b","l","l","t" }, { "r","b","b","l","l","t","t","r" }, { "b","l","l","t","t","r","r","b" }, { "l","t","t","r","r","b","b","l" } },
- rz = { { "auto","auto","auto","auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto","auto","auto","auto" }, { "auto","auto","auto","auto","auto","auto","auto","auto" } },
- -- rz = { { "r","r","b","b","l","l","t","t" }, { "b","b","l","l","t","t","r","r" }, { "l","l","t","t","r","r","b","b" }, { "t","t","r","r","b","b","l","l" } },
+ rz = { { "r","r","b","b","l","l","t","t" }, { "b","b","l","l","t","t","r","r" }, { "l","l","t","t","r","r","b","b" }, { "t","t","r","r","b","b","l","l" } },
prz = { { "r","b","b","l","l","t","t","r" }, { "b","l","l","t","t","r","r","b" }, { "l","t","t","r","r","b","b","l" }, { "t","r","r","b","b","l","l","t" } },
}
},
@@ -159,11 +147,11 @@ local syntax = {
local definitions = { }
-function chemistry.undefine(name)
+function chemicals.undefine(name)
definitions[lower(name)] = nil
end
-function chemistry.define(name,spec,text)
+function chemicals.define(name,spec,text)
name = lower(name)
local dn = definitions[name]
if not dn then dn = { } definitions[name] = dn end
@@ -174,7 +162,7 @@ function chemistry.define(name,spec,text)
end
local metacode, variant, keys, bonds, max, txt, textsize, rot, pstack
-local molecule = chemistry.molecule -- or use lpegmatch(chemistry.moleculeparser,...)
+local molecule = chemicals.molecule -- or use lpegmatch(chemicals.moleculeparser,...)
local function fetch(txt)
local st = stack[txt]
@@ -208,46 +196,35 @@ local text = (equal * C(P(1)^0)) + Cc(false)
local pattern =
(amount + Cc(1)) *
- Cs(operation/lower) *
- Cs(special/lower) * (
--- operation *
--- special * (
+ operation *
+ special * (
range * Cc(false) * text +
Cc(false) * Cc(false) * set * text +
single * Cc(false) * Cc(false) * text +
Cc(false) * Cc(false) * Cc(false) * text
)
--- local n, operation, index, upto, set, text = lpegmatch(pattern,"RZ1357")
+--~ local n, operation, index, upto, set, text = lpegmatch(pattern,"RZ1357")
--- print(lpegmatch(pattern,"RZ=x")) -- 1 RZ false false false x
--- print(lpegmatch(pattern,"RZ1=x")) -- 1 RZ 1 false false x
--- print(lpegmatch(pattern,"RZ1..3=x")) -- 1 RZ 1 3 false x
--- print(lpegmatch(pattern,"RZ13=x")) -- 1 RZ false false table x
+--~ print(lpegmatch(pattern,"RZ=x")) 1 RZ false false false x
+--~ print(lpegmatch(pattern,"RZ1=x")) 1 RZ 1 false false x
+--~ print(lpegmatch(pattern,"RZ1..3=x")) 1 RZ 1 3 false x
+--~ print(lpegmatch(pattern,"RZ13=x")) 1 RZ false false table x
local function process(spec,text,n,rulethickness,rulecolor,offset)
insert(stack,{ spec=spec, text=text, n=n })
local txt = #stack
local m = #metacode
for i=1,#spec do
- local step = spec[i]
- local s = lower(step)
+ local s = spec[i]
local d = definitions[s]
if d then
- if trace_structure then
- report_chemistry("%s => definition: %s",step,s)
- end
for i=1,#d do
local di = d[i]
process(di.spec,di.text,1,rulethickness,rulecolor)
end
else
- local rep, operation, special, index, upto, set, text = lpegmatch(pattern,step)
- if trace_structure then
- local set = set and concat(set," ") or "-"
- report_chemistry("%s => rep: %s, operation: %s, special: %s, index: %s, upto: %s, set: %s, text: %s",
- step,rep or "-",operation or "-",special and special ~= "" or "-",index or "-",upto or "-",set or "-",text or "-")
- end
+ local rep, operation, special, index, upto, set, text = lpegmatch(pattern,s)
if operation == "pb" then
insert(pstack,variant)
m = m + 1 ; metacode[m] = syntax.pb.direct
@@ -362,8 +339,7 @@ local function process(spec,text,n,rulethickness,rulecolor,offset)
if not t then txt, t = fetch(txt) end
if t then
t = molecule(processor_tostring(t))
- m = m + 1 ; metacode[m] = format('chem_%s(%s,%s,"\\chemicaltext{%s}");',operation,bonds,index,t)
- -- m = m + 1 ; metacode[m] = format('chem_%s_zero("\\chemicaltext{%s}");',operation,t)
+ m = m + 1 ; metacode[m] = format('chem_%s_zero("\\chemicaltext{%s}");',operation,t)
end
elseif index then
local t = text
@@ -412,8 +388,8 @@ end
--
-- rulethickness in points
-function chemistry.start(settings)
- chemistry.structures = chemistry.structures + 1
+function chemicals.start(settings)
+ chemicals.structures = chemicals.structures + 1
local textsize, rulethickness, rulecolor = settings.size, settings.rulethickness, settings.rulecolor
local width, height, scale, offset = settings.width or 0, settings.height or 0, settings.scale or "medium", settings.offset or 0
local l, r, t, b = settings.left or 0, settings.right or 0, settings.top or 0, settings.bottom or 0
@@ -469,73 +445,63 @@ function chemistry.start(settings)
scale = 0.75 * scale/625
--
metacode[#metacode+1] = format("chem_start_structure(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ;",
- chemistry.structures,
+ chemicals.structures,
l/25, r/25, t/25, b/25, scale,
tostring(settings.axis == variables.on), tostring(width), tostring(height), tostring(offset)
)
--
- -- variant, keys, bonds, stack, rot, pstack = "six", { }, 6, { }, 1, { }
- variant, keys, bonds, stack, rot, pstack = "one", { }, 1, { }, 1, { }
+ variant, keys, bonds, stack, rot, pstack = "six", { }, 6, { }, 1, { }
end
-function chemistry.stop()
+function chemicals.stop()
metacode[#metacode+1] = "chem_stop_structure ;"
--
local mpcode = concat(metacode,"\n")
if trace_structure then
report_chemistry("metapost code:\n%s", mpcode)
end
- metapost.graphic(chemistry.instance,chemistry.format,mpcode)
+ metapost.graphic(chemicals.instance,chemicals.format,mpcode)
metacode = nil
end
-function chemistry.component(spec,text,settings)
+function chemicals.component(spec,text,settings)
rulethickness, rulecolor, offset = settings.rulethickness, settings.rulecolor
--- local spec = settings_to_array(lower(spec))
- local spec = settings_to_array(spec)
+ local spec = settings_to_array(lower(spec))
local text = settings_to_array(text)
metacode[#metacode+1] = "chem_start_component ;"
process(spec,text,1,rulethickness,rulecolor)
metacode[#metacode+1] = "chem_stop_component ;"
end
-statistics.register("chemical formulas", function()
- if chemistry.structures > 0 then
- return format("%s chemical structure formulas",chemistry.structures) -- no timing needed, part of metapost
- end
-end)
-
--- interfaces
-
-commands.undefinechemical = chemistry.undefine
-commands.definechemical = chemistry.define
-commands.startchemical = chemistry.start
-commands.stopchemical = chemistry.stop
-commands.chemicalcomponent = chemistry.component
-
--- todo: top / bottom
-
local inline = {
["single"] = "\\chemicalsinglebond", ["-"] = "\\chemicalsinglebond",
- ["double"] = "\\chemicaldoublebond", ["--"] = "\\chemicaldoublebond", -- also =? and unicode triple?
+ ["double"] = "\\chemicaldoublebond", ["--"] = "\\chemicaldoublebond",
["triple"] = "\\chemicaltriplebond", ["---"] = "\\chemicaltriplebond",
["gives"] = "\\chemicalgives", ["->"] = "\\chemicalgives",
["equilibrium"] = "\\chemicalequilibrium", ["<->"] = "\\chemicalequilibrium",
["mesomeric"] = "\\chemicalmesomeric", ["<>"] = "\\chemicalmesomeric",
- ["plus"] = "\\chemicalplus", ["+"] = "\\chemicalplus",
- ["minus"] = "\\chemicalminus",
- ["space"] = "\\chemicalspace",
+ ["plus"] = "\\chemicalsplus", ["+"] = "\\chemicalsplus",
+ ["minus"] = "\\chemicalsminus",
+ ["space"] = "\\chemicalsspace",
}
-function commands.inlinechemical(spec)
+-- todo: top / bottom
+
+function chemicals.inline(spec)
local spec = settings_to_array(spec)
for i=1,#spec do
local s = spec[i]
local inl = inline[lower(s)]
if inl then
- context(inl) -- could be a fast context.sprint
+ context(inl)
else
context.chemicalinline(molecule(s))
end
end
end
+
+statistics.register("chemical formulas", function()
+ if chemicals.structures > 0 then
+ return format("%s chemical structure formulas",chemicals.structures) -- no timing needed, part of metapost
+ end
+end)
diff --git a/tex/context/base/chem-str.mkiv b/tex/context/base/chem-str.mkiv
index c4b03dd1e..1d60a293e 100644
--- a/tex/context/base/chem-str.mkiv
+++ b/tex/context/base/chem-str.mkiv
@@ -2,7 +2,7 @@
%D [ file=chem-ini,
%D version=2009.05.13,
%D subtitle=Chemistry,
-%D author=Hans Hagen \& Alan Braslau,
+%D author=Hans Hagen,
%D date=\currentdate,
%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
@@ -10,10 +10,8 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-%D The original \PPCHTEX\ code was written in pure \TEX\, although later we made
-%D the move from \PICTEX\ to \METAPOST\. The current implementation is a mix between
-%D \TEX\, \LUA\ and \METAPOST. Although the first objective is to get a compatible
-%D but better implementation, later versions might provide more,
+%D This module in incomplete and experimental. Eventually this code
+%D will replace \PPCHTEX.
\writestatus{loading}{ConTeXt Chemistry Macros / Structure}
@@ -28,24 +26,24 @@
% Here we use chemicalformula instead, so no longer a mix:
%
% \startchemicalformula
-% \chemical{2H_2}{top}{bottom}
+% \chemical{H_2}{top}{bottom}
% \chemical{PLUS}{top}{bottom}
-% \chemical{O_2}{top}{bottom}
+% \chemical{O}{top}{bottom}
% \chemical{GIVES}{top}{bottom}
-% \chemical{2H_2O}{top}{bottom}
+% \chemical{H_2O}{top}{bottom}
% \stopchemicalformula
%
% \startchemicalformula
-% \chemical{2H_2}
+% \chemical{H_2}
% \chemical{PLUS}
-% \chemical{O_2}
+% \chemical{O}
% \chemical{GIVES}
-% \chemical{2H_2O}
+% \chemical{H_2O}
% \stopchemicalformula
%
% The inline variant has only one argument:
%
-% \chemical{2H_2,PLUS,O_2,GIVES,2H_2O}
+% \chemical{H_2,PLUS,O,GIVES,H_2O}
% todo: seven | eight | frontsix | fontfive | carbon | newmans | chair
@@ -60,17 +58,11 @@
\let\setupchemicals\setupchemical
-%D We use a dedicated framed macro instead of inheriting one. This is both
-%D a historical and practical reason (like shared keys with different meaning
-%D that could clash, e.g.\ align).
-
-\defineframed
- [\??chemicalframed]
- [\c!align=\v!normal,
- \c!strut=\v!no]
-
\unexpanded\def\setupchemicalframed
- {\setupframed[\??chemicalframed]}
+ {\dosingleempty\dosetupchemicalframed}
+
+\def\dosetupchemicalframed
+ {\getparameters[\??chemicalframed]}
\unexpanded\def\definechemical % is global (so we don't use the commandhandler)
{\dosingleargument\chem_define}
@@ -79,7 +71,7 @@
{\startnointerference
\edef\currentdefinedchemical{#1}%
\let\chemical\chem_chemical_nested
- \ctxcommand{undefinechemical("#1")}%
+ \ctxlua{chemicals.undefine("#1")}%
#2% flush
\stopnointerference}
@@ -87,7 +79,7 @@
{\dodoubleempty\chem_chemical_nested_indeed}
\def\chem_chemical_nested_indeed[#1][#2]%
- {\ctxcommand{definechemical("\currentdefinedchemical",\!!bs#1\!!es,\!!bs\detokenize{#2}\!!es)}}
+ {\ctxlua{chemicals.define("\currentdefinedchemical",\!!bs#1\!!es,\!!bs\detokenize{#2}\!!es)}}
% chemical symbols
@@ -98,15 +90,20 @@
{\setvalue{\??chemicalsymbol#1}{#2}}
\unexpanded\def\chemicalsymbol[#1]%
- {\csname\??chemicalsymbol\ifcsname\??chemicalsymbol#1\endcsname#1\else\s!unknown\fi\endcsname}
+ {\csname\??chemicalsymbol\ifcsname\??chemicalsymbol#1\endcsname\s!unknown\else#1\fi\endcsname}
-\definechemicalsymbol[\s!unknown][] % \char"FFFD empty
+\definechemicalsymbol[\s!unknown][] % empty
% size (small medium big)
\edef\chemicaltoplocation{t}
\edef\chemicalbotlocation{b}
+% \unexpanded\def\chemicaltext#1% in ppchtex we had a more clever alignment
+% {\usechemicalstyleandcolor\c!style\c!color
+% \strut
+% #1} % maybe also \setstrut
+
\unexpanded\def\chemicaltext#1%
{\mathematics
{\usechemicalstyleandcolor\c!style\c!color
@@ -150,7 +147,7 @@
\fi\fi
\the\everystructurechemical
\setbox\b_chem_result\hbox\bgroup
- \ctxcommand{startchemical {
+ \ctxlua{chemicals.start {
width = "\chemicalparameter\c!width",
height = "\chemicalparameter\c!height",
left = \chemicalparameter\c!left,
@@ -165,7 +162,7 @@
\unexpanded\def\stopchemical
{\stopnointerference
- \ctxcommand{stopchemical()}%
+ \ctxlua{chemicals.stop()}%
\egroup
\d_chem_width \wd\b_chem_result
\d_chem_height\ht\b_chem_result
@@ -174,16 +171,15 @@
\doifelsenothing{\chemicalparameter\c!frame}\chem_framed_nop\chem_framed_yes
\egroup}
-\unexpanded\def\chem_framed_yes
- {\localframedwithsettings
+\def\chem_framed_yes
+ {\localframed%
[\??chemicalframed]%
- [\c!frame=\chemicalparameter\c!frame]%
- {\vbox{\box\b_chem_result\vss}}} % remove depth
+ [\c!frame=\chemicalparameter\c!frame,\c!align=\v!normal,\c!strut=\v!no]{\vbox{\box\b_chem_result\vss}}} % remove depth
-\unexpanded\def\chem_framed_nop
- {\directlocalframed
+\def\chem_framed_nop
+ {\localframed%
[\??chemicalframed]%
- {\vbox{\box\b_chem_result\vss}}} % remove depth
+ [\c!align=\v!normal,\c!strut=\v!no]{\vbox{\box\b_chem_result\vss}}} % remove depth
\let\startstructurechemical\startchemical
\let\stopstructurechemical \stopchemical
@@ -204,14 +200,14 @@
\def\strc_chem_indeed_three[#1][#2][#3]%
{\writestatus\m!chemicals{hyperlinked chemicals not yet supported}% todo reference, for the moment ignored
- \ctxcommand{chemicalcomponent(\!!bs#2\!!es, \!!bs\detokenize{#3}\!!es, { % maybe also pass first two args this way
+ \ctxlua{chemicals.component(\!!bs#2\!!es, \!!bs\detokenize{#3}\!!es, { % maybe also pass first two args this way
rulethickness = "\the\dimexpr\chemicalparameter\c!rulethickness\relax", % todo: scaled points
rulecolor = "\MPcolor{\chemicalparameter\c!rulecolor}" % we can precalculate this for speedup
} ) }%
\ignorespaces}
\def\strc_chem_indeed_two[#1][#2]%
- {\ctxcommand{chemicalcomponent(\!!bs#1\!!es,\!!bs\detokenize{#2}\!!es, { % maybe also pass first two args this way
+ {\ctxlua{chemicals.component(\!!bs#1\!!es,\!!bs\detokenize{#2}\!!es, { % maybe also pass first two args this way
rulethickness = "\the\dimexpr\chemicalparameter\c!rulethickness\relax", % todo: scaled points
rulecolor = "\MPcolor{\chemicalparameter\c!rulecolor}" % we can precalculate this for speedup
} ) }%
@@ -293,8 +289,8 @@
\def\chem_arrow_construct#1#2#3%
{\enspace
\mathematics{#1%
- {\strut\hbox \s!spread 2\emwidth{\hss\ctxcommand{inlinechemical(\!!bs#3\!!es)}\hss}}% {\strut\hbox \s!spread 2em{\hss#3\hss}}}%
- {\strut\hbox \s!spread 2\emwidth{\hss\ctxcommand{inlinechemical(\!!bs#2\!!es)}\hss}}}% {\strut\hbox \s!spread 2em{\hss#2\hss}}%
+ {\strut\hbox \!!spread 2\emwidth{\hss\ctxlua{chemicals.inline(\!!bs#2\!!es)}\hss}}% {\strut\hbox \!!spread 2em{\hss#2\hss}}%
+ {\strut\hbox \!!spread 2\emwidth{\hss\ctxlua{chemicals.inline(\!!bs#3\!!es)}\hss}}}% {\strut\hbox \!!spread 2em{\hss#3\hss}}}%
\enspace}
% special macros (probably needs some more work)
@@ -432,9 +428,9 @@
\usechemicalstyleandcolor\c!style\c!color
\ifthirdargument
\ifsecondargument
- \halign{\aligntab\hss\alignmark\alignmark\hss\cr#2\cr\molecule{#1}\cr#3\cr}%
+ \halign{&\hss##\hss\cr#2\cr\molecule{#1}\cr#3\cr}%
\else
- \halign{\aligntab\hss\alignmark\alignmark\hss \cr\molecule{#1}\cr#2\cr}%
+ \halign{&\hss##\hss\cr\molecule{#1}\cr#2\cr}%
\fi
\else
\hbox{\molecule{#1}}%
@@ -444,30 +440,30 @@
\unexpanded\def\inlinechemical#1%
{\dontleavehmode
- \hbox{\usechemicalstyleandcolor\c!style\c!color\ctxcommand{inlinechemical(\!!bs#1\!!es)}}}
+ \hbox{\usechemicalstyleandcolor\c!style\c!color\ctxlua{chemicals.inline(\!!bs#1\!!es)}}}
\unexpanded\def\chemicalbondrule
- {\hbox{\vrule\s!height.75\exheight\s!depth-\dimexpr.75\exheight-\linewidth\relax\s!width\emwidth\relax}}
+ {\hbox{\vrule\!!height.75ex\!!depth-\dimexpr.75ex-\linewidth\relax\!!width1em\relax}}
\definechemicalsymbol[i:space] [\enspace\quad\enspace]
\definechemicalsymbol[i:plus] [\enspace\mathematics{+}\enspace]
\definechemicalsymbol[i:minus] [\enspace\mathematics{-}\enspace]
\definechemicalsymbol[i:gives] [\enspace\mathematics{\xrightarrow{}{}}\enspace]
-\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightoverleftarrow{}{}}\enspace]
+\definechemicalsymbol[i:equilibrium] [\enspace\mathematics{\xrightpverleftarrow{}{}}\enspace]
\definechemicalsymbol[i:mesomeric] [\enspace\mathematics{\xleftrightarrow{}{}}\enspace]
\definechemicalsymbol[i:single] [\chemicalbondrule]
-\definechemicalsymbol[i:double] [\hbox{\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
-\definechemicalsymbol[i:triple] [\hbox{\chemicalbondrule\hskip-1em\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
+\definechemicalsymbol[i:tripple] [\hbox{\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
+\definechemicalsymbol[i:double] [\hbox{\chemicalbondrule\hskip-1em\lower.5ex\chemicalbondrule\hskip-1em\raise.5ex\chemicalbondrule}]
\unexpanded\def\chemicalsinglebond {\chemicalsymbol[i:single]}
-\unexpanded\def\chemicaldoublebond {\chemicalsymbol[i:double]}
-\unexpanded\def\chemicaltriplebond {\chemicalsymbol[i:triple]}
+\unexpanded\def\chemicaldoublebond {\chemicalsymbol[i:tripple]}
+\unexpanded\def\chemicaltriplebond {\chemicalsymbol[i:double]}
\unexpanded\def\chemicalgives {\chemicalsymbol[i:gives]}
\unexpanded\def\chemicalmesomeric {\chemicalsymbol[i:mesomeric]}
\unexpanded\def\chemicalequilibrium{\chemicalsymbol[i:equilibrium]}
-\unexpanded\def\chemicalplus {\chemicalsymbol[i:plus]}
-\unexpanded\def\chemicalminus {\chemicalsymbol[i:minus]}
-\unexpanded\def\chemicalspace {\chemicalsymbol[i:space]}
+\unexpanded\def\chemicalsplus {\chemicalsymbol[i:plus]}
+\unexpanded\def\chemicalsminus {\chemicalsymbol[i:minus]}
+\unexpanded\def\chemicalsspace {\chemicalsymbol[i:space]}
\unexpanded\def\chemicalinline #1{#1}
% display
@@ -495,133 +491,61 @@
\setfalse\c_chem_has_bot}
\unexpanded\def\stopchemicalformula
- {\tabskip\emwidth\relax
+ {\tabskip1em\relax
\nointerlineskip
\ifconditional\c_chem_has_top
\ifconditional\c_chem_has_bot
- \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_top\cr\the\t_chem_mid\cr\the\t_chem_bot\cr}%
+ \halign{&\hss\usechemicalstyleandcolor\c!style\c!color##\hss\cr\the\t_chem_top\cr\the\t_chem_mid\cr\the\t_chem_bot\cr}%
\else
- \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_top\cr\the\t_chem_mid\cr}%
+ \halign{&\hss\usechemicalstyleandcolor\c!style\c!color##\hss\cr\the\t_chem_top\cr\the\t_chem_mid\cr}%
\fi
\else
\ifconditional\c_chem_has_bot
- \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_mid\cr\the\t_chem_bot\cr}%
+ \halign{&\hss\usechemicalstyleandcolor\c!style\c!color##\hss\cr\the\t_chem_mid\cr\the\t_chem_bot\cr}%
\else
- \halign{\aligntab\hss\usechemicalstyleandcolor\c!style\c!color\alignmark\alignmark\hss\cr\the\t_chem_mid\cr}%
+ \halign{&\hss\usechemicalstyleandcolor\c!style\c!color##\hss\cr\the\t_chem_mid\cr}%
\fi
\fi
\egroup}
-% for the moment we have a special set
-
-\definechemicalsymbol[d:space] [\enspace\quad\enspace]
-\definechemicalsymbol[d:plus] [\enspace+\enspace]
-\definechemicalsymbol[d:minus] [\enspace-\enspace]
-\definechemicalsymbol[d:gives] [\rightarrowfill] % \chem_arrow_construct\xrightarrow
-\definechemicalsymbol[d:equilibrium] [\rightoverleftarrowfill] % \chem_arrow_construct\xrightoverleftarrow
-\definechemicalsymbol[d:mesomeric] [\leftarrowfill] % \chem_arrow_construct\xleftrightarrow
-\definechemicalsymbol[d:opencomplex] [\mathematics{\Bigg[}] % not yet ok
-\definechemicalsymbol[d:closecomplex][\mathematics{\Bigg]}] % not yet ok
-
-\definechemicalsymbol[d:SPACE] [{\chemicalsymbol[d:space]}]
-\definechemicalsymbol[d:PLUS] [{\chemicalsymbol[d:plus]}]
-\definechemicalsymbol[d:MINUS] [{\chemicalsymbol[d:minus]}]
-\definechemicalsymbol[d:GIVES] [{\chemicalsymbol[d:gives]}]
-\definechemicalsymbol[d:EQUILIBRIUM] [{\chemicalsymbol[d:equilibrium]}]
-\definechemicalsymbol[d:MESOMERIC] [{\chemicalsymbol[d:mesomeric]}]
-\definechemicalsymbol[d:OPENCOMPLEX] [{\chemicalsymbol[d:opencomplex]}]
-\definechemicalsymbol[d:CLOSECOMPLEX][{\chemicalsymbol[d:closecomplex]}]
-
\unexpanded\def\formulachemical
{\relax\dotriplegroupempty\chem_formula}
-% \def\chem_formula#1#2#3% we could do hboxes and measure
-% {\ifcsname\??chemicalsymbol\detokenize{#1}\endcsname
-% \t_chem_mid\expandafter{\the\t_chem_mid\chem_formula_mid{#1}{#2}{#3}}%
-% \else
-% \ifthirdargument
-% \doifelsenothing{#2}\chem_formula_top_nop{\chem_formula_top_yes{#2}}%
-% \doifelsenothing{#3}\chem_formula_bot_nop{\chem_formula_bot_yes{#3}}%
-% \else\ifsecondargument
-% \chem_formula_top_nop
-% \doifelsenothing{#2}\chem_formula_bot_nop{\chem_formula_bot_yes{#2}}%
-% \else
-% \chem_formula_top_nop
-% \chem_formula_bot_nop
-% \fi\fi
-% \t_chem_mid\expandafter{\the\t_chem_mid\molecule{#1}\aligntab}%
-% \fi}
-
\def\chem_formula#1#2#3% we could do hboxes and measure
- {\ifthirdargument
- \doifelsenothing{#2}\chem_formula_top_nop{\chem_formula_top_yes{#2}}%
- \doifelsenothing{#3}\chem_formula_bot_nop{\chem_formula_bot_yes{#3}}%
- \else\ifsecondargument
- \chem_formula_top_nop
- \doifelsenothing{#2}\chem_formula_bot_nop{\chem_formula_bot_yes{#2}}%
+ {\ifcsname\??chemicalsymbol\detokenize{#1}\endcsname
+ \t_chem_mid\expandafter{\the\t_chem_mid\chem_formula_mid{#1}{#2}{#3}}%
\else
- \chem_formula_top_nop
- \chem_formula_bot_nop
- \fi\fi
- \ifcsname\??chemicalsymbol d:\detokenize{#1}\endcsname
- \t_chem_mid\expandafter{\the\t_chem_mid\chemicalsymbol[d:#1]\aligntab}%
- \else
- \t_chem_mid\expandafter{\the\t_chem_mid\molecule{#1}\aligntab}%
+ \ifthirdargument
+ \doifelsenothing{#2}\chem_formula_top_nop{\chem_formula_top_yes{#2}}%
+ \doifelsenothing{#3}\chem_formula_bot_nop{\chem_formula_bot_yes{#3}}%
+ \else\ifsecondargument
+ \chem_formula_top_nop
+ \doifelsenothing{#2}\chem_formula_bot_nop{\chem_formula_bot_yes{#2}}%
+ \else
+ \chem_formula_top_nop
+ \chem_formula_bot_nop
+ \fi\fi
+ \t_chem_mid\expandafter{\the\t_chem_mid\molecule{#1}&}%
\fi}
\def\chem_formula_mid#1%
{\csname\??chemicalsymbol\detokenize{#1}\endcsname}
-\def\chem_formula_top_nop {\t_chem_top\expandafter{\the\t_chem_top\aligntab}}
-\def\chem_formula_bot_nop {\t_chem_bot\expandafter{\the\t_chem_bot\aligntab}}
-\def\chem_formula_top_yes#1{\t_chem_top\expandafter{\the\t_chem_top\chem_formula_top_indeed{#1}\aligntab}\settrue\c_chem_has_top}
-\def\chem_formula_bot_yes#1{\t_chem_bot\expandafter{\the\t_chem_bot\chem_formula_bot_indeed{#1}\aligntab}\settrue\c_chem_has_bot}
+\def\chem_formula_top_nop {\t_chem_top\expandafter{\the\t_chem_top&}}
+\def\chem_formula_bot_nop {\t_chem_bot\expandafter{\the\t_chem_bot&}}
+\def\chem_formula_top_yes#1{\t_chem_top\expandafter{\the\t_chem_top\chem_formula_top_indeed{#1}&}\settrue\c_chem_has_top}
+\def\chem_formula_bot_yes#1{\t_chem_bot\expandafter{\the\t_chem_bot\chem_formula_bot_indeed{#1}&}\settrue\c_chem_has_bot}
\def\chem_formula_top_indeed#1{\strut#1}
\def\chem_formula_bot_indeed#1{\strut#1}
-% Experimental: defaults might change.
-
-\definefloat
- [\v!chemical]
- [\v!chemicals]
-
-\setuplabeltext
- [\v!chemical=]
-
-\setupfloat
- [\v!chemical]
- [\c!location=\v!here,
- \c!inner=\hsize.8\textwidth\dontleavehmode, % brr
- \c!align={\v!flushleft,\v!lohi}]
-
-\setupcaption
- [\v!chemical]
- [\c!location=\v!right,
- \c!distance=\zeropoint,
- \c!width=.2\textwidth,
- \c!align=\v!flushright]
-
-% Can be used as for displayed math: \startplaceformula... to display a chemical formula
-% or a chemical structure:
-%
-% \startplacechemical
-% \startchemicalformula
-% \chemical{2H_2}
-% \chemical{PLUS}
-% \chemical{O_2}
-% \chemical{GIVES}
-% \chemical{2H_2O}
-% \stopchemicalformula
-% \stopplacechemical
-
% gone: state option resolution offset (now frame offset) alternative
\setupchemicalframed
[\c!align=\v!normal,
\c!strut=\v!no,
\c!offset=\v!overlay,
- \c!frame=\v!off]
+ \c!frame=off]
\setupchemical
[\c!frame=,
diff --git a/tex/context/base/cldf-bas.lua b/tex/context/base/cldf-bas.lua
index 9cf8dcd4a..30a9265bc 100644
--- a/tex/context/base/cldf-bas.lua
+++ b/tex/context/base/cldf-bas.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['cldf-bas'] = {
+if not modules then modules = { } end modules ['cldf-ini'] = {
version = 1.001,
comment = "companion to cldf-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -22,8 +22,6 @@ if not modules then modules = { } end modules ['cldf-bas'] = {
-- flush(ctxcatcodes,"}")
-- end
--- maybe use context.generics
-
local type = type
local format = string.format
local utfchar = utf.char
@@ -34,16 +32,13 @@ local generics = context.generics
local variables = interfaces.variables
local new_rule = nodes.pool.rule
-local texcount = tex.count
function context.char(k) -- used as escape too, so don't change to utf
if type(k) == "table" then
- local n = #k
- if n == 1 then
- context([[\char%s\relax]],k[1])
- elseif n > 0 then
- context([[\char%s\relax]],concat(k,[[\relax\char]]))
- end
+ -- for i=1,#k do
+ -- context(format([[\char%s\relax]],k[i]))
+ -- end
+ context([[\char%s\relax]],concat(k,[[\relax\char]]))
elseif k then
context([[\char%s\relax]],k)
end
@@ -103,22 +98,22 @@ context.vrule = context.hrule
-- not yet used ... but will get variant at the tex end as well
-function context.sethboxregister(n) context([[\setbox %s\hbox]],n) end
-function context.setvboxregister(n) context([[\setbox %s\vbox]],n) end
+function context.sethboxregister (n) context("\\setbox %s\\hbox",n) end
+function context.setvboxregister (n) context("\\setbox %s\\vbox",n) end
function context.starthboxregister(n)
if type(n) == "number" then
- context([[\setbox%s\hbox{]],n)
+ context("\\setbox%s\\hbox\\bgroup",n)
else
- context([[\setbox\%s\hbox{]],n)
+ context("\\setbox\\%s\\hbox\\bgroup",n)
end
end
function context.startvboxregister(n)
if type(n) == "number" then
- context([[\setbox%s\vbox{]],n)
+ context("\\setbox%s\\vbox\\bgroup",n)
else
- context([[\setbox\%s\vbox{]],n)
+ context("\\setbox\\%s\\vbox\\bgroup",n)
end
end
@@ -127,36 +122,19 @@ context.stopvboxregister = context.egroup
function context.flushboxregister(n)
if type(n) == "number" then
- context([[\box%s ]],n)
+ context("\\box%s ",n)
else
- context([[\box\%s]],n)
+ context("\\box\\%s",n)
end
end
function context.beginvbox()
- context([[\vbox{]]) -- we can do \bvbox ... \evbox (less tokens)
+ context("\\vbox\\bgroup") -- we can do \bvbox ... \evbox (less tokens)
end
function context.beginhbox()
- context([[\hbox{]]) -- todo: use fast one
+ context("\\hbox\\bgroup") -- todo: use fast one
end
context.endvbox = context.egroup
context.endhbox = context.egroup
-
-local function allocate(name,what,cmd)
- local a = format("c_syst_last_allocated_%s",what)
- local n = texcount[a] + 1
- if n <= texcount.c_syst_max_allocated_register then
- texcount[a] = n
- end
- context("\\global\\expandafter\\%sdef\\csname %s\\endcsname %s\\relax",cmd or what,name,n)
- return n
-end
-
-function context.newdimen (name) return allocate(name,"dimen") end
-function context.newskip (name) return allocate(name,"skip") end
-function context.newcount (name) return allocate(name,"count") end
-function context.newmuskip(name) return allocate(name,"muskip") end
-function context.newtoks (name) return allocate(name,"toks") end
-function context.newbox (name) return allocate(name,"box","mathchar") end
diff --git a/tex/context/base/cldf-com.lua b/tex/context/base/cldf-com.lua
index d9062594e..bacbbeafd 100644
--- a/tex/context/base/cldf-com.lua
+++ b/tex/context/base/cldf-com.lua
@@ -11,8 +11,8 @@ local context = context
local generics = context.generics -- needs documentation
local variables = interfaces.variables
-generics.starttabulate = "starttabulate" -- "start" .. variables.tabulate -- todo: e!start
-generics.stoptabulate = "stoptabulate" -- "stop" .. variables.tabulate -- todo: e!stop
+generics.starttabulate = "start" .. variables.tabulate -- todo: e!start
+generics.stoptabulate = "stop" .. variables.tabulate -- todo: e!stop
local NC, NR = context.NC, context.NR
diff --git a/tex/context/base/cldf-ini.lua b/tex/context/base/cldf-ini.lua
index ad5f14855..ed86c2923 100644
--- a/tex/context/base/cldf-ini.lua
+++ b/tex/context/base/cldf-ini.lua
@@ -25,7 +25,7 @@ local tex = tex
context = context or { }
local context = context
-local format, find, gmatch, gsub, validstring = string.format, string.find, string.gmatch, string.gsub, string.valid
+local format, find, gmatch, gsub = string.format, string.find, string.gmatch, string.gsub
local next, type, tostring, tonumber, setmetatable = next, type, tostring, tonumber, setmetatable
local insert, remove, concat = table.insert, table.remove, table.concat
local lpegmatch, lpegC, lpegS, lpegP, lpegCc = lpeg.match, lpeg.C, lpeg.S, lpeg.P, lpeg.Cc
@@ -40,14 +40,12 @@ local isnode = node.is_node -- after 0.65 just node.type
local writenode = node.write
local copynodelist = node.copy_list
-local catcodenumbers = catcodes.numbers
-
-local ctxcatcodes = catcodenumbers.ctxcatcodes
-local prtcatcodes = catcodenumbers.prtcatcodes
-local texcatcodes = catcodenumbers.texcatcodes
-local txtcatcodes = catcodenumbers.txtcatcodes
-local vrbcatcodes = catcodenumbers.vrbcatcodes
-local xmlcatcodes = catcodenumbers.xmlcatcodes
+local ctxcatcodes = tex.ctxcatcodes
+local prtcatcodes = tex.prtcatcodes
+local texcatcodes = tex.texcatcodes
+local txtcatcodes = tex.txtcatcodes
+local vrbcatcodes = tex.vrbcatcodes
+local xmlcatcodes = tex.xmlcatcodes
local flush = texsprint
local flushdirect = texprint
@@ -346,9 +344,9 @@ end
local methodhandler = resolvers.methodhandler
-function context.viafile(data,tag)
+function context.viafile(data)
if data and data ~= "" then
- local filename = resolvers.savers.byscheme("virtual",validstring(tag,"viafile"),data)
+ local filename = resolvers.savers.byscheme("virtual","viafile",data)
-- context.startregime { "utf" }
context.input(filename)
-- context.stopregime()
@@ -412,11 +410,7 @@ local function writer(parent,command,first,...) -- already optimized before call
done = true
end
end
- if done then
- flush(currentcatcodes,"]")
- else
- flush(currentcatcodes,"[]")
- end
+ flush(currentcatcodes,"]")
elseif tn == 1 then -- some 20% faster than the next loop
local tj = ti[1]
if type(tj) == "function" then
diff --git a/tex/context/base/cldf-int.lua b/tex/context/base/cldf-int.lua
index 6cbfd666f..55db9fa0b 100644
--- a/tex/context/base/cldf-int.lua
+++ b/tex/context/base/cldf-int.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['cldf-int'] = {
+if not modules then modules = { } end modules ['mult-clm'] = {
version = 1.001,
comment = "companion to mult-clm.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -14,12 +14,9 @@ if not modules then modules = { } end modules ['cldf-int'] = {
local format, insert, remove, concat = string.format, table.insert, table.remove, table.concat
local unpack = unpack or table.unpack
-local catcodenumbers = catcodes.numbers
-
-local ctxcatcodes = catcodenumbers.ctxcatcodes
-local vrbcatcodes = catcodenumbers.vrbcatcodes
-
-local contextsprint = context.sprint
+local contextsprint = context.sprint
+local ctxcatcodes = tex.ctxcatcodes
+local vrbcatcodes = tex.vrbcatcodes
local trace_define = false trackers.register("context.define", function(v) trace_define = v end)
diff --git a/tex/context/base/cldf-ver.lua b/tex/context/base/cldf-ver.lua
index b48fd253a..237078157 100644
--- a/tex/context/base/cldf-ver.lua
+++ b/tex/context/base/cldf-ver.lua
@@ -6,10 +6,6 @@ if not modules then modules = { } end modules ['cldf-ver'] = {
license = "see context related readme files"
}
--- We have better verbatim: context.verbatim so that needs to be looked
--- into. We can also directly store in buffers although this variant works
--- better when used mixed with other code (synchronization issue).
-
local concat, tohandle = table.concat, table.tohandle
local find, splitlines = string.find, string.splitlines
local tostring, type = tostring, type
@@ -45,7 +41,7 @@ table .tocontext = t_tocontext
string .tocontext = s_tocontext
boolean.tocontext = b_tocontext
-function context.tocontext(first,...)
+function tocontext(first,...)
local t = type(first)
if t == "string" then
s_tocontext(first,...)
diff --git a/tex/context/base/colo-ext.mkiv b/tex/context/base/colo-ext.mkiv
index 8878da485..af6c3830e 100644
--- a/tex/context/base/colo-ext.mkiv
+++ b/tex/context/base/colo-ext.mkiv
@@ -29,10 +29,18 @@
%D
%D will negate the colors in box zero.
+% \unexpanded\def\negatecolorbox#1%
+% {\setbox#1\hbox
+% {\startnegative % might change
+% \startcolor[\s!white]\vrule\!!height\ht#1\!!depth\dp#1\!!width\wd#1\stopcolor
+% \hskip-\wd#1%
+% \box#1%
+% \stopnegative}}
+
\unexpanded\def\negatecolorbox#1%
{\setbox#1\hbox
{\startnegative % might change
- % \startcolor[\s!white]\vrule\s!height\ht#1\s!depth\dp#1\s!width\wd#1\stopcolor
+% \startcolor[\s!white]\vrule\!!height\ht#1\!!depth\dp#1\!!width\wd#1\stopcolor
\blackrule[\c!color=\s!white,\c!height=\ht#1,\c!depth=\dp#1,\c!width=\wd#1]%
\hskip-\wd#1%
\box#1%
diff --git a/tex/context/base/colo-icc.lua b/tex/context/base/colo-icc.lua
index 4ab28eb68..904d42143 100644
--- a/tex/context/base/colo-icc.lua
+++ b/tex/context/base/colo-icc.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['colo-icc'] = {
+if not modules then modules = { } end modules ['colo-ini'] = {
version = 1.000,
comment = "companion to colo-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua
index e08f3d387..747e2116f 100644
--- a/tex/context/base/colo-ini.lua
+++ b/tex/context/base/colo-ini.lua
@@ -16,8 +16,7 @@ local trace_define = false trackers.register("colors.define",function(v) trace_
local report_colors = logs.reporter("colors","defining")
-local attributes, backends, storage = attributes, backends, storage
-local context, commands = context, commands
+local attributes, context, commands = attributes, context, commands
local settings_to_hash_strict = utilities.parsers.settings_to_hash_strict
@@ -667,51 +666,83 @@ function colors.defineintermediatecolor(name,fraction,c_one,c_two,a_one,a_two,sp
end
end
-local function f(i,colors,fraction)
- local otf = 0
- for c=1,#colors do
- otf = otf + (tonumber(fraction[c]) or 1) * colors[c][i]
- end
- if otf > 1 then
- otf = 1
+--~ local function f(one,two,i,fraction_one,fraction_two)
+--~ local otf = fraction_one * one[i] + fraction_two * two[i]
+--~ if otf > 1 then
+--~ otf = 1
+--~ end
+--~ return otf
+--~ end
+
+--~ function colors.defineduocolor(name,fraction_one,c_one,fraction_two,c_two,global,freeze)
+--~ local one, two = colorvalues[c_one], colorvalues[c_two]
+--~ if one and two then
+--~ fraction_one = tonumber(fraction_one) or 1
+--~ fraction_two = tonumber(fraction_two) or 1
+--~ local csone, cstwo = one[1], two[1]
+--~ local ca
+--~ if csone == 2 then
+--~ ca = register_color(name,'gray',f(one,two,2,fraction_one,fraction_two))
+--~ elseif csone == 3 then
+--~ ca = register_color(name,'rgb', f(one,two,3,fraction_one,fraction_two),
+--~ f(one,two,4,fraction_one,fraction_two),
+--~ f(one,two,5,fraction_one,fraction_two))
+--~ elseif csone == 4 then
+--~ ca = register_color(name,'cmyk',f(one,two,6,fraction_one,fraction_two),
+--~ f(one,two,7,fraction_one,fraction_two),
+--~ f(one,two,8,fraction_one,fraction_two),
+--~ f(one,two,9,fraction_one,fraction_two))
+--~ else
+--~ ca = register_color(name,'gray',f(one,two,2,fraction_one,fraction_two))
+--~ end
+--~ definecolor(name,ca,global,freeze)
+--~ end
+--~ end
+
+ local function f(i,colors,fraction)
+ local otf = 0
+ for c=1,#colors do
+ otf = otf + (tonumber(fraction[c]) or 1) * colors[c][i]
+ end
+ if otf > 1 then
+ otf = 1
+ end
+ return otf
end
- return otf
-end
-function colors.definemixcolor(name,fractions,cs,global,freeze)
- local values = { }
- for i=1,#cs do -- do fraction in here
- local v = colorvalues[cs[i]]
- if not v then
- return
+ function colors.definemixcolor(name,fractions,cs,global,freeze)
+ local values = { }
+ for i=1,#cs do -- do fraction in here
+ local v = colorvalues[cs[i]]
+ if not v then
+ return
+ end
+ values[i] = v
end
- values[i] = v
- end
- local csone = values[1][1]
- local ca
- if csone == 2 then
- ca = register_color(name,'gray',f(2,values,fractions))
- elseif csone == 3 then
- ca = register_color(name,'rgb', f(3,values,fractions),
- f(4,values,fractions),
- f(5,values,fractions))
- elseif csone == 4 then
- ca = register_color(name,'cmyk',f(6,values,fractions),
- f(7,values,fractions),
- f(8,values,fractions),
- f(9,values,fractions))
- else
- ca = register_color(name,'gray',f(2,values,fractions))
+ local csone = values[1][1]
+ local ca
+ if csone == 2 then
+ ca = register_color(name,'gray',f(2,values,fractions))
+ elseif csone == 3 then
+ ca = register_color(name,'rgb', f(3,values,fractions),
+ f(4,values,fractions),
+ f(5,values,fractions))
+ elseif csone == 4 then
+ ca = register_color(name,'cmyk',f(6,values,fractions),
+ f(7,values,fractions),
+ f(8,values,fractions),
+ f(9,values,fractions))
+ else
+ ca = register_color(name,'gray',f(2,values,fractions))
+ end
+ definecolor(name,ca,global,freeze)
end
- definecolor(name,ca,global,freeze)
-end
-- for the moment downward compatible
local patterns = { "colo-imp-%s.mkiv", "colo-imp-%s.tex", "colo-%s.mkiv", "colo-%s.tex" }
local function action(name,foundname)
- -- could be one command
context.startreadingfile()
context.startcolorset { name }
context.input(foundname)
@@ -846,22 +877,3 @@ end
-- context.popcatcodes()
-- end
--- handy
-
-local models = storage.allocate { "all", "gray", "rgb", "cmyk", "spot" }
-
-colors.models = models -- check for usage elsewhere
-
-function colors.spec(name)
- local l = attributes_list[a_color]
- local t = colorvalues[l[name]] or colorvalues[l.black]
- return {
- model = models[t[1]] or models[1],
- s = t[2],
- r = t[3], g = t[4], b = t[5],
- c = t[6], m = t[7], y = t[8], k = t[9],
- }
-end
-
--- inspect(attributes.colors.spec("red"))
--- inspect(attributes.colors.spec("red socks"))
diff --git a/tex/context/base/colo-ini.mkiv b/tex/context/base/colo-ini.mkiv
index 629f2b96a..5721bb513 100644
--- a/tex/context/base/colo-ini.mkiv
+++ b/tex/context/base/colo-ini.mkiv
@@ -242,8 +242,8 @@
\setfalse\c_colo_convert_gray
\getvalue{\??colorconversions\directcolorsparameter\c!conversion}% could be a nice \ifcsname
% too often:
- \ifconditional\c_colo_rgb_supported \colo_helpers_show_message\m!colors{10}\v!rgb \fi
- \ifconditional\c_colo_cmyk_supported\colo_helpers_show_message\m!colors{10}\v!cmyk\fi
+ \ifconditional\c_colo_rgb_supported \colo_helpers_show_message\m!colors9\v!rgb \fi
+ \ifconditional\c_colo_cmyk_supported\colo_helpers_show_message\m!colors9\v!cmyk\fi
\colo_helpers_set_current_model
\ifproductionrun
\edef\p_pagecolormodel{\directcolorsparameter\c!pagecolormodel}%
@@ -357,26 +357,16 @@
\normalexpanded{\colo_palets_define[#1][\csname\??colorpaletspecification#2\endcsname]}%
\fi}}
-% \def\colo_palets_define_one#1#2% get rid of { } in #2
-% {\colo_palets_define_two{#1}[#2]}%
-
-\def\colo_palets_define_one#1#2% get rid of { }
- {\doifassignmentelse{#2} % catch empty entries
- {\colo_palets_define_two{#1}[#2]}
- {\colo_palets_define_three{#1}{#2}}}
+\def\colo_palets_define_one#1#2% get rid of { } in #2
+ {\colo_palets_define_two{#1}[#2]}%
\def\colo_palets_define_two#1[#2=#3]%
{\edef\m_colo_palets_tmp{\ifx\m_colo_palets_tmp\empty\else\m_colo_palets_tmp,\fi#2}%
\colo_palets_define_set{#1}{#2}{#3}}%
-\def\colo_palets_define_three#1#2%
- {\ifcsname\??colorpaletspecification#2\endcsname
- \processcommacommand[\csname\??colorpaletspecification#2\endcsname]{\colo_palets_define_one{#1}}%
- \fi}
-
\let\paletsize\!!zerocount
-\unexpanded\def\getpaletsize[#1]% only works for valid k=v definitions
+\def\getpaletsize[#1]%
{\getcommacommandsize[\csname\??colorpaletspecification#1\endcsname]%
\edef\paletsize{\number\commalistsize}}
@@ -812,19 +802,9 @@
\def\defaulttextcolor {black}
\def\s!themaintextcolor{themaintextcolor}
-\unexpanded\def\inheritmaintextcolor
- {\ifx\maintextcolor\empty\else\colo_helpers_activate\maintextcolor\fi}
-
-\unexpanded\def\onlyinheritmaintextcolor
- {\ifx\maintextcolor\empty
- \deactivatecolor
- \else
- \colo_helpers_activate\maintextcolor
- \fi}
-
\appendtoks
\deactivatecolor % public?
- \inheritmaintextcolor
+ \ifx\maintextcolor\empty\else\colo_helpers_activate\maintextcolor\fi
\to \everybeforeoutput
\def\colo_helpers_switch_to_maintextcolor#1%
@@ -981,7 +961,7 @@
% ignores in attribute handler
%
-% \def\forcecolorhack{\vrule\s!width\zeropoint\s!height\zeropoint\s!depth\zeropoint}
+% \def\forcecolorhack{\vrule\!!width\zeropoint\!!height\zeropoint\!!depth\zeropoint}
% \normal added else fails in metafun manual (leaders do a hard scan)
diff --git a/tex/context/base/colo-run.lua b/tex/context/base/colo-run.lua
index 27f7c6b12..4f1916d5a 100644
--- a/tex/context/base/colo-run.lua
+++ b/tex/context/base/colo-run.lua
@@ -6,10 +6,8 @@ if not modules then modules = { } end modules ['colo-run'] = {
license = "see context related readme files"
}
--- For historic reasons the core has a couple of tracing features. Nowadays
--- these would end up in modules.
-
-local colors, commands, context, utilities = colors, commands, context, utilities
+-- For historic reasons the core has a couple of tracing
+-- features. Nowadays these would end up in modules.
local colors= attributes.colors
diff --git a/tex/context/base/colo-run.mkiv b/tex/context/base/colo-run.mkiv
index 5084fdd35..c330accf3 100644
--- a/tex/context/base/colo-run.mkiv
+++ b/tex/context/base/colo-run.mkiv
@@ -42,9 +42,9 @@
%D Palets
\unexpanded\gdef\showpalet
- {\dodoubleargument\colo_show_palet}
+ {\dodoubleargument\doshowpalet}
-\gdef\colo_show_palet[#1][#2]%
+\gdef\doshowpalet[#1][#2]%
{\ifcsname\??colorpalet#1\endcsname
\doifinsetelse\v!vertical{#2} \colo_palets_show_vertical \colo_palets_show_horizontal [#1][#2]%
\fi}
@@ -59,8 +59,8 @@
\tabskip\zeropoint
\def\colo_palets_show_palet##1%
{\doifinsetelse\v!number{#2}{##1\hskip.5em}{}&
- \color[##1]{\vrule\s!width3em\s!height\strutht\s!depth\strutdp}%
- \graycolor[##1]{\vrule\s!width3em\s!height\strutht\s!depth\strutdp}&
+ \color[##1]{\vrule\!!width3em\!!height\strutht\!!depth\strutdp}%
+ \graycolor[##1]{\vrule\!!width3em\!!height\strutht\!!depth\strutdp}&
\doifinset\v!value{#2}{\hskip.5em\colorvalue{##1}}\crcr}
\halign
{\hss##&\hss##\hss#\cr
@@ -92,11 +92,11 @@
\colo_palets_process[#1]\colo_palets_show_palet}\cr
\doifinset\v!name{#2}{#1\hskip.5em}%
\def\colo_palets_show_palet##1%
- {&\strut\color[##1]{\vrule\s!width\!!widtha\s!height\strutht\s!depth\zeropoint}}%
+ {&\strut\color[##1]{\vrule\!!width\!!widtha\!!height\strutht\!!depth\zeropoint}}%
\colo_palets_process[#1]\colo_palets_show_palet\crcr
\noalign{\vskip-\strutdepth}%
\def\colo_palets_show_palet##1%
- {&\graycolor[##1]{\vrule\s!width\!!widtha\s!height\zeropoint\s!depth\strutdp}}%
+ {&\graycolor[##1]{\vrule\!!width\!!widtha\!!height\zeropoint\!!depth\strutdp}}%
\colo_palets_process[#1]\colo_palets_show_palet\crcr
\doifinset\v!value{#2}
{\def\colo_palets_show_palet##1%
@@ -137,13 +137,13 @@
\def\colo_palets_compare##1%
{\hbox
{\setbox0\hbox
- {#1[##1]{\vrule\s!width\hsize\s!height3ex}}%
+ {#1[##1]{\vrule\!!width\hsize\!!height3ex}}%
\wd0\zeropoint
\box0
\hbox to \hsize
{\def\colo_palets_compare####1%
{\hbox to \!!widtha
- {\hss#1[####1]{\vrule\s!width.5\!!widtha\s!height2.25ex\s!depth-.75ex}\hss}}%
+ {\hss#1[####1]{\vrule\!!width.5\!!widtha\!!height2.25ex\!!depth-.75ex}\hss}}%
\processcommacommand[\getvalue{\??colorpalet#2}]\colo_palets_compare}}
\endgraf}
\processcommacommand[\getvalue{\??colorpalet#2}]\colo_palets_compare}}
@@ -171,8 +171,8 @@
{\halign
{\hss####\hss\cr
\doifinset\v!number{#2}{\strut##1}\cr
- \color[#1:##1]{\vrule\s!width4em\s!height\strutht\s!depth\zeropoint}\cr
- \graycolor[#1:##1]{\vrule\s!width4em\s!height\zeropoint\s!depth\strutdp}\cr
+ \color[#1:##1]{\vrule\!!width4em\!!height\strutht\!!depth\zeropoint}\cr
+ \graycolor[#1:##1]{\vrule\!!width4em\!!height\zeropoint\!!depth\strutdp}\cr
\doifinset\v!value{#2}{\colorvalue{#1:##1}\strut}\crcr}}}}%
\hbox
{\doifinset\v!name{#2}
@@ -195,8 +195,8 @@
\def\colo_groups_show_group##1%
{\doifcolor{#1:##1}
{\doifinset\v!number{#2}{##1\hskip.5em}&
- \color[#1:##1]{\vrule\s!width2.5em\s!height\strutht\s!depth\strutdp}%
- \graycolor[#1:##1]{\vrule\s!width2.5em\s!height\strutht\s!depth\strutdp}&
+ \color[#1:##1]{\vrule\!!width2.5em\!!height\strutht\!!depth\strutdp}%
+ \graycolor[#1:##1]{\vrule\!!width2.5em\!!height\strutht\!!depth\strutdp}&
\doifinset\v!value{#2}{\hskip.5em\colorvalue{#1:##1}}\crcr}}%
\halign
{\hss##&\hss##\hss#\hss\cr
@@ -228,11 +228,11 @@
\def\colo_groups_compare_step#1#2#3%
{\hbox to \hsize
{\setbox0\hbox
- {#1[#2:#3]{\vrule\s!width\hsize\s!height3ex}}%
+ {#1[#2:#3]{\vrule\!!width\hsize\!!height3ex}}%
\wd0\zeropoint
\box0
\hbox to \hsize
- {\hss\dorecurse\!!counta{#1[#2:\recurselevel]{\vrule\s!width.5\!!widtha\s!height2.25ex\s!depth-.75ex}\hss}}}
+ {\hss\dorecurse\!!counta{#1[#2:\recurselevel]{\vrule\!!width.5\!!widtha\!!height2.25ex\!!depth-.75ex}\hss}}}
\endgraf}
\protect \endinput
diff --git a/tex/context/base/cont-log.mkiv b/tex/context/base/cont-log.mkiv
index 5d4133143..67647920d 100644
--- a/tex/context/base/cont-log.mkiv
+++ b/tex/context/base/cont-log.mkiv
@@ -118,7 +118,7 @@
\logofont}
\def\syst_logos_meta_hyphen % there is no hyphenchar in this font
- {\discretionary{\vrule\s!height.33em\s!depth-.27em\s!width.33em}{}{}}
+ {\discretionary{\vrule\!!height.33em\!!depth-.27em\!!width.33em}{}{}}
\unexpanded\def\MetaFont
{\dontleavehmode
@@ -270,12 +270,4 @@
\unexpanded\def\MPII{MpII}
\unexpanded\def\MPIV{MpIV}
-\appendtoks
- \def\ConTeXt {ConTeXt}%
- \def\MetaPost{MetaPost}%
- \def\MetaFont{MetaFont}%
- \def\MetaFun {MetaFun}%
- \def\TeX {TeX}%
-\to \everysimplifycommands
-
\protect \endinput
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index 2a2e12ba8..b4958762f 100644
--- a/tex/context/base/cont-new.mkii
+++ b/tex/context/base/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2012.10.17 22:49}
+\newcontextversion{2012.05.30 11:26}
%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/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 9f3d8cbc2..5a28f8e29 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,60 +11,515 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2012.10.17 22:49}
+\newcontextversion{2012.05.30 11:26}
-%D This file is loaded at runtime, thereby providing an excellent place for
-%D hacks, patches, extensions and new features.
+%D This file is loaded at runtime, thereby providing an
+%D excellent place for hacks, patches, extensions and new
+%D features.
\unprotect
\writestatus\m!system{beware: some patches loaded from cont-new.mkiv}
-%D Maybe:
+\def\dividedsize#1#2#3% size gap n
+ {\dimexpr
+ \ifnum\dimexpr#1\relax>\plusone
+ (\dimexpr#1\relax-\numexpr#3-1\relax\dimexpr#2\relax)/#3\else#1%
+ \fi
+ \relax}
+
+\def\singlewidened #1{\hbox spread 1em{\hss#1\hss}}
+\def\complexwidened[#1]#2{\hbox spread #1{\hss#2\hss}}
-\unexpanded\def\tightvbox{\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\vbox}
-\unexpanded\def\tightvtop{\dowithnextbox{\ht\nextbox\zeropoint\box\nextbox}\vtop}
+\definecomplexorsimple\widened
+
+\let\active\activecatcode % for a while (tikz)
+
+% todo
+%
+% \def\definelocation{\dodoubleargument\dodefinelocation}
+% \def\dodefinelocation[#1][#2]{\setvalue{loc:#1}{#2}}
+%
+% \definelocation[lt] [\v!left\v!top]
+% \definelocation[tl] [\v!left\v!top]
+% \definelocation[\v!top\v!left][\v!left\v!top]
+%
+% \def\getlocation#1{\executeifdefined{loc:#1}{#1}}
+
+% \let\cs\getvalue % no, we want \cs to be czech
+
+% experimental so this may change
-%D Needs some work:
+\def\startdescriptions
+ {\dosingleempty\dostartdescriptions}
-\unexpanded\def\startgridcorrection
- {\dosingleempty\spac_grid_correction_start}
+\def\dostartdescriptions[#1]%
+ {\begingroup
+ \def\item{\getvalue{#1}}%
+ \let\dostoppairdescription \donothing
+ \let\@@description \dostartpairdescription
+ \let\@@startsomedescription\dostartsomedescription}
-\def\spac_grid_correction_start[#1]%
+\def\stopdescriptions
+ {\dostoppairdescription
+ \endgroup}
+
+\def\dostartpairdescription[#1][#2]%
+ {\dostoppairdescription
+ \def\dostoppairdescription{\@@stopdescription{#1}}%
+ \bgroup
+ \def\currentdescription{#1}%
+ \doifelse{\descriptionparameter{\s!do\c!state}}\v!start
+ {\@@makedescription{#1}[#2]{}}
+ {\@@makedescription{#1}[#2]}}
+
+\def\dostartsomedescription% #1[#2]#3%
+ {\bgroup
+ \@@makedescription} % {#1}[#2]{#3}}
+
+% \starttext
+%
+% \definedescription[test]
+%
+% \startdescriptions
+% \test{Foo} Bar bar bar
+% \test{Foo} Bar bar bar
+% \test{Foo} Bar bar bar
+% \stopdescriptions
+%
+% \startdescriptions[test]
+% \item{Foo} Bar bar bar
+% \item{Foo} Bar bar bar
+% \item{Foo} Bar bar bar
+% \stopdescriptions
+%
+% \startdescriptions
+% \starttest{Foo} Bar bar bar \stoptest
+% \starttest{Foo} Bar bar bar \stoptest
+% \starttest{Foo} Bar bar bar \stoptest
+% \stopdescriptions
+%
+% \startdescriptions[test]
+% \item{Foo} Bar bar bar
+% \item{Foo} Bar bar bar
+% \item{Foo} Bar bar bar
+% \stopdescriptions
+%
+% \stoptext
+
+% this will be activated when
+%
+% \newinsert\thispageinsert % <- installinsertion
+%
+% \def\flushatthispage
+% {\bgroup
+% \dowithnextbox{\insert\thispageinsert{\box\nextbox}\egroup}%
+% \hbox}
+%
+% \appendtoks
+% \ifvoid\thispageinsert\else\hbox{\smashedbox\thispageinsert}\fi
+% \to \everyshipout
+
+% \definemarkedpage[nobackgrounds]
+% \markpage[nobackgrounds]
+% \doifmarkedpageelse{nobackgrounds}
+
+% Just a simple and fast hanger, for usage in macros.
+
+\def\setuphanging
+ {\dodoubleempty\getparameters[\??ha]}
+
+\setuphanging
+ [\c!distance=.5em]
+
+\def\starthanging
+ {\noindent\bgroup
+ \dowithnextbox
+ {\setbox\nextbox\hbox{\flushnextbox\hskip\@@hadistance}%
+ \hangindent\nextboxwd
+ \hangafter\plusone
+ \flushnextbox\ignorespaces}
+ \hbox}
+
+\def\stophanging
+ {\endgraf
+ \egroup}
+
+% experimental
+
+\def\stophangaround
+ {\endgraf
+ \egroup}
+
+\def\starthangaround
+ {\noindent\bgroup
+ \dowithnextbox
+ {\ifdim\nextboxht>\strutht\setbox\nextbox\tbox{\flushnextbox}\fi
+ \setbox\nextbox\hbox{\flushnextbox\hskip\@@hadistance}%
+ \getboxheight\scratchdimen\of\box\nextbox
+ \getnoflines\scratchdimen
+ \nextboxht\strutht
+ \nextboxdp\strutdp
+ \hangindent\nextboxwd
+ \hangafter-\noflines
+ \llap{\flushnextbox}\ignorespaces}
+ \hbox}
+
+\def\modevalue#1#2#3%
+ {\@EA\ifx\csname\@mode@\systemmodeprefix#1\endcsname\endcsname\enabledmode#2\else#2\fi}
+
+\def\systemmodevalue#1%
+ {\modevalue{\systemmodeprefix#1}}
+
+% new, still to be improved
+%
+% \dorecurse{10}
+% {\input thuan
+% \placefigure{}{\framed[height=1.5cm]{test}}
+% \placefloatplaceholder}
+
+\def\placefloatplaceholder
+ {\ifroomforfloat \else
+ \scratchdimen\pagegoal
+ \advance\scratchdimen-\pagetotal
+ \advance\scratchdimen-3\lineheight
+ \ifdim\scratchdimen>\zeropoint
+ \startlinecorrection[blank]
+ \mhbox{\inframed{\labeltexts{placeholder}{\lastcaptiontag}}}%
+ \stoplinecorrection
+ \else
+ \allowbreak
+ \fi
+ \fi}
+
+\setuplabeltext
+ [placeholder={, moved}]
+
+% move to support module, and then use context(...)
+
+\startluacode
+ function commands.percentageof(str,dim)
+ local n = str:match("^(.*)%%$")
+ context.sprint(tex.ctxcatcodes,(n and (tonumber(n)/100)*dim .. "sp") or str)
+ end
+\stopluacode
+
+\gdef\setpercentdimen#1#2%
+ {#1=\ctxcommand{percentageof("#2",\number#1)}\relax}
+
+% \scratchdimen=100pt \setpercentdimen\scratchdimen{10\letterpercent} \the\scratchdimen
+% \scratchdimen=100pt \setpercentdimen\scratchdimen{5pt} \the\scratchdimen
+
+\bgroup \permitcircumflexescape
+
+\obeylines % don't remove %'s !
+
+\gdef\collapsedspace#1%
+ {\ifx#1^^M%
+ \expandafter\collapsedspace
+ \else
+ \space
+ \expandafter#1%
+ \fi}
+
+\gdef\collapsespaces
+ {\prependtoksonce\relax\to\everyeof%
+ \ignorelines%
+ \ignoretabs%
+ \let\obeyedspace\collapsedspace%
+ \obeyspaces}
+
+\egroup
+
+\def\inlinedbox
+ {\bgroup
+ \dowithnextbox
+ {\scratchdimen\nextboxht
+ \advance\scratchdimen\nextboxdp
+ \advance\scratchdimen-\lineheight
+ \divide\scratchdimen\plustwo
+ \advance\scratchdimen\strutdepth
+ \setbox\nextbox\hbox{\lower\scratchdimen\flushnextbox}%
+ \nextboxht\strutht
+ \nextboxdp\strutdp
+ \flushnextbox
+ \egroup}%
+ \hbox}
+
+\def\dimenratio#1#2% etex only
+ {\withoutpt\the\dimexpr2\dimexpr(#1)/\dimexpr(#2)/32768\relax\relax}
+
+\def\doxprecurse#1#2%
+ {\ifnum#1=\zerocount % no \ifcase
+ \expandafter\gobblethreearguments
+ \else
+ #2\expandafter\expandafter\expandafter\doxprecurse\expandafter
+ \fi\expandafter{\the\numexpr#1-1\relax}{#2}}
+
+\def\buttonframed{\dodoubleempty\localframed[\??bt]} % goodie
+
+\unexpanded\def\asciistr#1{\dontleavehmode{\defconvertedargument\ascii{#1}\verbatimfont\ascii}}
+
+\def\shapefill{\vskip\zeropoint\!!plus\lineheight\!!minus\lineheight\relax}
+
+% \ruledhbox
+% {\startignorespaces
+% \def\oeps{a}
+% \startignorespaces
+% \def\oeps{a}
+% \stopignorespaces
+% \def\oeps{a}
+% \stopignorespaces
+% \oeps}
+
+\newsignal\boissignal
+\newcount \boislevel
+
+\long\def\startignorespaces
+ {\advance\boislevel\plusone
+ \ifcase\boislevel\or \ifhmode
+ \hskip\boissignal
+ \fi \fi
+ \ignorespaces}
+
+\long\def\stopignorespaces
+ {\ifcase\boislevel\or \ifhmode
+ \doloop
+ {\ifdim\lastskip=\zeropoint
+ \exitloop
+ \else\ifdim\lastskip=\boissignal
+ \unskip
+ \exitloop
+ \else
+ \unskip
+ \fi\fi}%
+ \fi \fi
+ \advance\boislevel\minusone}
+
+\def\minimalhbox#1#%
+ {\dowithnextbox
+ {\bgroup
+ \setbox\scratchbox\hbox#1{\hss}%
+ \ifdim\nextboxwd<\wd\scratchbox\nextboxwd\wd\scratchbox\fi
+ \flushnextbox
+ \egroup}
+ \hbox}
+
+\def\gobbleuntilempty#1\empty{}
+
+\def\dodimchoice#1#2#3%
+ {\ifdim#1#2%
+ #3\@EA\gobbleuntilempty
+ \else
+ \@EA\dodimchoice
+ \fi{#1}}
+
+\def\donumchoice#1#2#3%
+ {\ifnum#1#2%
+ #3\@EA\gobbleuntilempty
+ \else
+ \@EA\dodimchoice
+ \fi{#1}}
+
+\def\dimchoice#1#2{\dodimchoice{#1}#2{=#1}{#1}\empty}
+\def\numchoice#1#2{\donumchoice{#1}#2{=#1}{#1}\empty}
+
+% \the\dimexpr(\dimchoice {7pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}})
+% \the\dimexpr(\dimchoice{11pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}})
+% \the\dimexpr(\dimchoice{14pt}{{<10pt}{8pt}{<12pt}{9pt}{<15pt}{10pt}{=11pt}{12pt}})
+
+\def\tabulaterule % to be redone, not correct
+ {\dotabulaterule
+ {\hrule\!!height.5\scratchdimen\!!depth.5\scratchdimen\relax
+ \doifvalue{\??tt\currenttabulate\c!distance}\v!grid
+ {\kern-\scratchdimen}}} % experimental tm-prikkels
+% so far
+
+% between alignment lines certain rules apply, and even a
+% simple test can mess up a table, which is why we have a
+% special test facility
+%
+% \ruledvbox
+% {\starttabulate[|l|p|]
+% \NC 1test \NC test \NC \NR
+% \tableifelse{\doifelse{a}{a}}{\NC Xtest \NC test \NC \NR}{}%
+% \stoptabulate}
+
+\long\def\tableifelse#1%
+ {\tablenoalign
+ {#1%
+ {\aftergroup \firstoftwoarguments}%
+ {\aftergroup\secondoftwoarguments}}}
+
+\long \def\tableiftextelse#1{\tableifelse{\doiftextelse{#1}}}
+
+\def\tightvbox{\dowithnextbox{\nextboxdp\zeropoint\flushnextbox}\vbox}
+\def\tightvtop{\dowithnextbox{\nextboxht\zeropoint\flushnextbox}\vtop}
+
+% what is this stupid macro meant for:
+
+\def\hyphenationpoint
+ {\hskip\zeropoint}
+
+\def\hyphenated#1%
+ {\bgroup
+ \!!counta\zerocount
+ \def\hyphenated##1{\advance\!!counta\plusone}%
+ \handletokens#1\with\hyphenated
+ \!!countb\plusone
+ \def\hyphenated##1%
+ {##1%
+ \advance\!!countb\plusone\relax
+ \ifnum\!!countb>2 \ifnum\!!countb<\!!counta
+ \hyphenationpoint
+ \fi\fi}%
+ \handletokens#1\with\hyphenated
+ \egroup}
+
+\def\obeysupersubletters
+ {\let\super\normalsuper
+ \let\suber\normalsuber
+ \let\normalsuper\letterhat
+ \let\normalsuber\letterunderscore
+ \enablesupersub}
+
+\def\obeysupersubmath
+ {\let\normalsuper\letterhat
+ \let\normalsuber\letterunderscore
+ \enablesupersub}
+
+\def\startgridcorrection
+ {\dosingleempty\dostartgridcorrection}
+
+\def\dostartgridcorrection[#1]%
{\ifgridsnapping
\snaptogrid[#1]\vbox\bgroup
\else
\startbaselinecorrection
\fi}
-\unexpanded\def\stopgridcorrection
+\def\stopgridcorrection
{\ifgridsnapping
\egroup
\else
\stopbaselinecorrection
\fi}
-
-\unexpanded\def\checkgridsnapping
+
+\def\checkgridsnapping
{\lineskip\ifgridsnapping\zeropoint\else\normallineskip\fi}
+
+\def\startplaatsen
+ {\dosingleempty\dostartplaatsen}
-%D Probably obsolete:
+\def\dostartplaatsen[#1]% tzt n*links etc
+ {\endgraf
+ \noindent\bgroup
+ \setlocalhsize
+ \hbox to \localhsize\bgroup
+ \doifnot{#1}\v!left\hss
+ \def\stopplaatsen
+ {\unskip\unskip\unskip
+ \doifnot{#1}\v!right\hss
+ \egroup
+ \egroup
+ \endgraf}%
+ \gobblespacetokens}
-\unexpanded\def\startcolumnmakeup % don't change
+% \startplaatsen[links] bla \stopplaatsen
+
+\def\startcolumnmakeup % don't change
{\bgroup
- \getrawnoflines\textheight % raw as we cna have topskip
- \setbox\scratchbox\vbox to \dimexpr\noflines\lineheight-\lineheight+\topskip\relax
- \bgroup
- \forgetall}
+ \getrawnoflines\textheight % teksthoogte kan topskip hebben, dus raw
+ \scratchdimen\noflines\lineheight
+ \advance\scratchdimen-\lineheight
+ \advance\scratchdimen\topskip
+ \setbox\scratchbox
+ \ifcase\showgridstate\vbox\else\ruledvbox\fi to \scratchdimen\bgroup
+ \forgetall} % ! don't change
-\unexpanded\def\stopcolumnmakeup
+\def\stopcolumnmakeup
{\egroup
\dp\scratchbox\zeropoint
\wd\scratchbox\textwidth
\box\scratchbox
\egroup
\page_otr_command_synchronize_hsize}
+
+\long\def\startexternalfigure
+ {\dotripleempty\dostartexternalfigure}
+
+\long\def\dostartexternalfigure[#1][#2][#3]#4\stopexternalfigure
+ {\gdef\figuredescription{#4}%
+ \externalfigure[#1][#2][#3]%
+ \globallet\figuredescription\empty}
+
+\let\figuredescription\empty
+
+% incomplete, will be a special case of float placement
+
+\def\startfixed{\dosingleempty\dostartfixed}
+
+\def\dostartfixed[#1]%
+ {\expanded{\dowithnextbox{\noexpand\dodofixed{\ifhmode0\else1\fi}{#1}}}%
+ \vbox\bgroup
+ \setlocalhsize}
+
+\def\stopfixed
+ {\egroup}
+
+\def\dodofixed#1#2%
+ {\ifcase#1\relax
+ \processaction
+ [#2]
+ [ \v!high=>\bbox {\flushnextbox},
+ \v!low=>\tbox {\flushnextbox},
+ \v!middle=>\vcenter{\flushnextbox},
+ \v!lohi=>\vcenter{\flushnextbox},
+ \s!unknown=>\tbox {\flushnextbox},
+ \s!default=>\tbox {\flushnextbox}]%
+ \else
+ \startbaselinecorrection
+ \noindent\flushnextbox
+ \stopbaselinecorrection
+ \fi}
+
+% \startitemize
+%
+% \item \externalfigure[koe][height=2cm]
+% \item \externalfigure[koe][height=2cm]
+% \item \externalfigure[koe][height=2cm]
+% \item \externalfigure[koe][height=2cm]
+%
+% \page
+%
+% \item \startfixed \externalfigure[koe][height=2cm]\stopfixed
+% \item \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed
+% \item \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed
+% \item \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed
+%
+% \page
+%
+% \item test \startfixed \externalfigure[koe][height=2cm]\stopfixed
+% \item test \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed
+% \item test \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed
+% \item test \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed
+%
+% \page
+%
+% \item test \par \startfixed \externalfigure[koe][height=2cm]\stopfixed
+% \item test \par \startfixed[high]\externalfigure[koe][height=2cm]\stopfixed
+% \item test \par \startfixed[low] \externalfigure[koe][height=2cm]\stopfixed
+% \item test \par \startfixed[lohi]\externalfigure[koe][height=2cm]\stopfixed
+%
+% \stopitemize
+
+\def\obeyfollowingtoken{{}} % end \cs scanning
+
+% potential new defaults:
+%
+% \setbreakpoints[compound]
-%D Till we fixed all styles:
+% till we fixed all styles:
\let\\=\crlf
diff --git a/tex/context/base/cont-nop.mkiv b/tex/context/base/cont-nop.mkiv
deleted file mode 100644
index c8188503e..000000000
--- a/tex/context/base/cont-nop.mkiv
+++ /dev/null
@@ -1,22 +0,0 @@
-%D \module
-%D [ file=cont-nop,
-%D version=2012.06.01,
-%D title=\CONTEXT\ Miscellaneous Macros,
-%D subtitle=Startup Dummy,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-\unprotect
-
-\writestatus\m!system{loading dummy replacement for jobname}
-
-\protect
-
-\finishjob
-
-\endinput
diff --git a/tex/context/base/cont-yes.mkiv b/tex/context/base/cont-yes.mkiv
deleted file mode 100644
index 2a032fc0b..000000000
--- a/tex/context/base/cont-yes.mkiv
+++ /dev/null
@@ -1,80 +0,0 @@
-%D \module
-%D [ file=cont-yes,
-%D version=2012.06.01,
-%D title=\CONTEXT\ Miscellaneous Macros,
-%D subtitle=Startup Stub,
-%D author=Hans Hagen,
-%D date=\currentdate,
-%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
-%C
-%C This module is part of the \CONTEXT\ macro||package and is
-%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
-%C details.
-
-% At some point I will reconsider the \starttext .. \stoptext
-% wraping as we can assume proper styling. It's a left-over from
-% mkii that we need to get rid of.
-
-\startluacode
-
- -- When a style is loaded there is a good change that we never enter
- -- this code.
-
- environment.initializefilenames()
-
- local arguments = environment.arguments
- local suffix = environment.suffix
- local filename = environment.filename
-
- if suffix == "xml" or arguments.forcexml then
-
- -- Maybe we should move the preamble parsing here as it
- -- can be part of (any) loaded (sub) file. The \starttext
- -- wrapping might go away.
-
- context.starttext()
- context.xmlprocess("main",filename,"")
- context.stoptext()
-
- elseif suffix == "cld" or arguments.forcecld then
-
- context.runfile(filename)
-
- elseif suffix == "lua" or arguments.forcelua then
-
- -- The wrapping might go away. Why is is it there in the
- -- first place.
-
- context.starttext()
- context.ctxlua(string.format('dofile("%s")',filename))
- context.stoptext()
-
- elseif suffix == "mp" or arguments.forcemp then
-
- context.starttext()
- context.processMPfigurefile(filename)
- context.stoptext()
-
- -- elseif suffix == "prep" then
- --
- -- -- Why do we wrap here. Because it can be xml? Let's get rid
- -- -- of prepping in general.
- --
- -- context.starttext()
- -- context.input(filename)
- -- context.stoptext()
-
- else
-
- -- We have a regular tex file so no \starttext yet as we can
- -- load fonts.
-
- context.input(filename)
-
- end
-
- context.finishjob()
-
-\stopluacode
-
-\endinput
diff --git a/tex/context/base/context-base.lmx b/tex/context/base/context-base.lmx
index 2b093c3e1..09817463b 100644
--- a/tex/context/base/context-base.lmx
+++ b/tex/context/base/context-base.lmx
@@ -19,9 +19,7 @@
+
diff --git a/tex/context/base/context-help.lmx b/tex/context/base/context-help.lmx
index 939b70cb6..5401fb65d 100644
--- a/tex/context/base/context-help.lmx
+++ b/tex/context/base/context-help.lmx
@@ -19,7 +19,6 @@