From 7b271baae19db1528fbe6621bdf50af89a5a336b Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Fri, 22 Feb 2019 20:29:46 +0100 Subject: 2019-02-22 19:43:00 --- tex/context/base/mkii/cont-new.mkii | 2 +- tex/context/base/mkii/context.mkii | 2 +- tex/context/base/mkii/core-sys.mkii | 12 +- tex/context/base/mkii/enco-agr.mkii | 3 +- tex/context/base/mkii/enco-def.mkii | 1 + tex/context/base/mkii/enco-uc.mkii | 2 + tex/context/base/mkii/mult-cs.mkii | 10 +- tex/context/base/mkii/mult-de.mkii | 8 +- tex/context/base/mkii/mult-en.mkii | 7 +- tex/context/base/mkii/mult-fr.mkii | 7 +- tex/context/base/mkii/mult-it.mkii | 8 +- tex/context/base/mkii/mult-nl.mkii | 12 +- tex/context/base/mkii/mult-pe.mkii | 7 +- tex/context/base/mkii/mult-ro.mkii | 8 +- tex/context/base/mkii/strc-reg.mkii | 4 +- tex/context/base/mkii/syst-rtp.mkiv | 18 - tex/context/base/mkii/unic-003.mkii | 4 +- tex/context/base/mkii/xetx-chr.mkii | 1 + tex/context/base/mkiv/anch-bck.mkvi | 24 +- tex/context/base/mkiv/anch-pgr.lua | 140 +- tex/context/base/mkiv/anch-pgr.mkiv | 14 +- tex/context/base/mkiv/anch-pos.lua | 166 +- tex/context/base/mkiv/anch-pos.mkiv | 18 +- tex/context/base/mkiv/anch-snc.lua | 271 + tex/context/base/mkiv/anch-snc.mkiv | 272 +- tex/context/base/mkiv/anch-tab.mkiv | 17 +- tex/context/base/mkiv/attr-col.lua | 48 +- tex/context/base/mkiv/attr-ini.lua | 5 +- tex/context/base/mkiv/attr-ini.mkiv | 36 +- tex/context/base/mkiv/back-exp.lua | 936 +- tex/context/base/mkiv/back-exp.mkiv | 28 +- tex/context/base/mkiv/back-ini.lua | 221 +- tex/context/base/mkiv/back-ini.mkiv | 116 +- tex/context/base/mkiv/back-pdf.lua | 301 +- tex/context/base/mkiv/back-pdf.mkiv | 188 +- tex/context/base/mkiv/back-pdp.lua | 453 + tex/context/base/mkiv/back-res.lua | 44 + tex/context/base/mkiv/back-swf.mkiv | 101 +- tex/context/base/mkiv/bibl-bib.mkiv | 6 +- tex/context/base/mkiv/bibl-tra.mkiv | 2 +- tex/context/base/mkiv/buff-imp-default.mkiv | 10 +- tex/context/base/mkiv/buff-ini.lua | 25 +- tex/context/base/mkiv/buff-ini.mkiv | 46 +- tex/context/base/mkiv/buff-ver.lua | 23 +- tex/context/base/mkiv/buff-ver.mkiv | 19 +- tex/context/base/mkiv/catc-ini.mkiv | 161 +- tex/context/base/mkiv/char-act.mkiv | 47 +- tex/context/base/mkiv/char-def.lua | 5239 +- tex/context/base/mkiv/char-emj.lua | 2566 +- tex/context/base/mkiv/char-ini.lua | 60 +- tex/context/base/mkiv/char-ini.mkiv | 16 +- tex/context/base/mkiv/char-tex.lua | 33 +- tex/context/base/mkiv/char-utf.lua | 13 +- tex/context/base/mkiv/chem-str.lua | 4 - tex/context/base/mkiv/chem-str.mkiv | 12 +- tex/context/base/mkiv/cldf-bas.lua | 155 +- tex/context/base/mkiv/cldf-ini.lua | 658 +- tex/context/base/mkiv/cldf-ini.mkiv | 8 +- tex/context/base/mkiv/cldf-int.lua | 5 +- tex/context/base/mkiv/cldf-scn.lua | 7 +- tex/context/base/mkiv/cldf-ver.lua | 87 +- tex/context/base/mkiv/colo-imp-crayola.mkiv | 10 +- tex/context/base/mkiv/colo-imp-svg.mkiv | 164 + tex/context/base/mkiv/colo-ini.lua | 66 +- tex/context/base/mkiv/colo-ini.mkiv | 19 +- tex/context/base/mkiv/colo-run.lua | 2 +- tex/context/base/mkiv/cont-log.mkiv | 40 +- tex/context/base/mkiv/cont-new.mkiv | 18 +- tex/context/base/mkiv/cont-run.lua | 48 +- tex/context/base/mkiv/cont-run.mkiv | 20 +- tex/context/base/mkiv/context.mkiv | 62 +- tex/context/base/mkiv/core-con.lua | 393 +- tex/context/base/mkiv/core-con.mkiv | 212 +- tex/context/base/mkiv/core-dat.lua | 62 +- tex/context/base/mkiv/core-dat.mkiv | 33 +- tex/context/base/mkiv/core-def.mkiv | 2 +- tex/context/base/mkiv/core-env.lua | 67 +- tex/context/base/mkiv/core-env.mkiv | 46 +- tex/context/base/mkiv/core-lmt.lua | 34 + tex/context/base/mkiv/core-lmt.mkiv | 32 + tex/context/base/mkiv/core-sys.lua | 8 +- tex/context/base/mkiv/core-two.lua | 93 +- tex/context/base/mkiv/core-two.mkiv | 8 +- tex/context/base/mkiv/core-uti.lua | 23 +- tex/context/base/mkiv/data-aux.lua | 2 +- tex/context/base/mkiv/data-pre.lua | 26 +- tex/context/base/mkiv/data-res.lua | 6 +- tex/context/base/mkiv/data-tex.lua | 8 +- tex/context/base/mkiv/data-tre.lua | 5 +- tex/context/base/mkiv/data-use.lua | 6 +- tex/context/base/mkiv/data-zip.lua | 10 +- tex/context/base/mkiv/driv-ini.lua | 194 + tex/context/base/mkiv/driv-ini.mkiv | 25 + tex/context/base/mkiv/export-example.css | 37 +- tex/context/base/mkiv/file-job.lua | 3 - tex/context/base/mkiv/file-job.mkvi | 19 +- tex/context/base/mkiv/file-mod.mkvi | 32 +- tex/context/base/mkiv/font-aux.lua | 1 + tex/context/base/mkiv/font-cff.lua | 554 +- tex/context/base/mkiv/font-cft.lua | 10 + tex/context/base/mkiv/font-chk.lua | 94 +- tex/context/base/mkiv/font-col.lua | 191 +- tex/context/base/mkiv/font-col.mkvi | 5 + tex/context/base/mkiv/font-con.lua | 179 +- tex/context/base/mkiv/font-ctx.lua | 585 +- tex/context/base/mkiv/font-def.lua | 120 +- tex/context/base/mkiv/font-dsp.lua | 736 +- tex/context/base/mkiv/font-emp.mkvi | 22 +- tex/context/base/mkiv/font-enh.lua | 16 +- tex/context/base/mkiv/font-ext.lua | 1856 - tex/context/base/mkiv/font-fbk.lua | 272 +- tex/context/base/mkiv/font-fea.mkvi | 10 +- tex/context/base/mkiv/font-fil.mkvi | 33 +- tex/context/base/mkiv/font-gbn.lua | 262 - tex/context/base/mkiv/font-gds.mkvi | 2 +- tex/context/base/mkiv/font-hsh.lua | 101 +- tex/context/base/mkiv/font-imp-dimensions.lua | 115 + tex/context/base/mkiv/font-imp-effects.lua | 414 + tex/context/base/mkiv/font-imp-italics.lua | 147 + tex/context/base/mkiv/font-imp-ligatures.lua | 136 + tex/context/base/mkiv/font-imp-math.lua | 81 + tex/context/base/mkiv/font-imp-notused.lua | 168 + tex/context/base/mkiv/font-imp-properties.lua | 130 + tex/context/base/mkiv/font-imp-quality.lua | 527 + tex/context/base/mkiv/font-imp-reorder.lua | 174 + tex/context/base/mkiv/font-imp-tex.lua | 144 + tex/context/base/mkiv/font-imp-tracing.lua | 281 + tex/context/base/mkiv/font-imp-unicode.lua | 82 + tex/context/base/mkiv/font-ini.lua | 47 +- tex/context/base/mkiv/font-ini.mkvi | 99 +- tex/context/base/mkiv/font-lib.mkvi | 43 +- tex/context/base/mkiv/font-map.lua | 160 +- tex/context/base/mkiv/font-mat.mkvi | 30 +- tex/context/base/mkiv/font-mis.lua | 14 +- tex/context/base/mkiv/font-mps.lua | 131 +- tex/context/base/mkiv/font-nod.lua | 187 +- tex/context/base/mkiv/font-ocl.lua | 349 +- tex/context/base/mkiv/font-one.lua | 15 +- tex/context/base/mkiv/font-onr.lua | 79 +- tex/context/base/mkiv/font-osd.lua | 121 +- tex/context/base/mkiv/font-ota.lua | 10 +- tex/context/base/mkiv/font-otc.lua | 322 +- tex/context/base/mkiv/font-otj.lua | 110 +- tex/context/base/mkiv/font-otl.lua | 41 +- tex/context/base/mkiv/font-oto.lua | 69 +- tex/context/base/mkiv/font-otr.lua | 275 +- tex/context/base/mkiv/font-ots.lua | 500 +- tex/context/base/mkiv/font-ott.lua | 50 +- tex/context/base/mkiv/font-oup.lua | 644 +- tex/context/base/mkiv/font-pre.mkiv | 49 +- tex/context/base/mkiv/font-prv.lua | 78 + tex/context/base/mkiv/font-sel.lua | 149 +- tex/context/base/mkiv/font-set.mkvi | 6 +- tex/context/base/mkiv/font-shp.lua | 128 +- tex/context/base/mkiv/font-sol.lua | 128 +- tex/context/base/mkiv/font-sty.mkvi | 25 +- tex/context/base/mkiv/font-sym.mkvi | 2 +- tex/context/base/mkiv/font-syn.lua | 5 +- tex/context/base/mkiv/font-tfm.lua | 448 +- tex/context/base/mkiv/font-tra.mkiv | 2 +- tex/context/base/mkiv/font-ttf.lua | 465 +- tex/context/base/mkiv/font-var.mkvi | 2 + tex/context/base/mkiv/font-vfc.lua | 123 + tex/context/base/mkiv/font-vir.lua | 23 +- tex/context/base/mkiv/font-web.lua | 20 +- tex/context/base/mkiv/font-xtx.lua | 97 - tex/context/base/mkiv/good-ctx.lua | 84 +- tex/context/base/mkiv/grph-epd.lua | 20 +- tex/context/base/mkiv/grph-inc.lua | 286 +- tex/context/base/mkiv/grph-inc.mkiv | 101 +- tex/context/base/mkiv/grph-mem.lua | 164 +- tex/context/base/mkiv/grph-pat.lua | 4 +- tex/context/base/mkiv/grph-rul.lua | 149 +- tex/context/base/mkiv/grph-swf.lua | 3 +- tex/context/base/mkiv/grph-trf.mkiv | 39 +- tex/context/base/mkiv/java-imp-exa.mkiv | 395 - tex/context/base/mkiv/java-imp-example.mkiv | 398 + tex/context/base/mkiv/java-imp-fields.mkiv | 648 + tex/context/base/mkiv/java-imp-fil.mkiv | 52 - tex/context/base/mkiv/java-imp-fld.mkiv | 625 - tex/context/base/mkiv/java-imp-highlight.mkiv | 34 + tex/context/base/mkiv/java-imp-print.mkiv | 52 + tex/context/base/mkiv/java-imp-rhh.mkiv | 34 - tex/context/base/mkiv/java-imp-steps.mkiv | 123 + tex/context/base/mkiv/java-imp-stp.mkiv | 123 - tex/context/base/mkiv/java-imp-videoplayer.mkiv | 82 + tex/context/base/mkiv/java-imp-vplayer.mkiv | 105 + tex/context/base/mkiv/java-ini.lua | 8 +- tex/context/base/mkiv/java-ini.mkiv | 17 +- tex/context/base/mkiv/l-bit32.lua | 10 +- tex/context/base/mkiv/l-dir.lua | 82 +- tex/context/base/mkiv/l-file.lua | 38 +- tex/context/base/mkiv/l-lpeg.lua | 195 +- tex/context/base/mkiv/l-lua.lua | 40 +- tex/context/base/mkiv/l-macro-imp-optimize.lua | 29 +- tex/context/base/mkiv/l-macro.lua | 95 +- tex/context/base/mkiv/l-number.lua | 23 +- tex/context/base/mkiv/l-os.lua | 132 +- tex/context/base/mkiv/l-package.lua | 4 + tex/context/base/mkiv/l-sandbox.lua | 3 + tex/context/base/mkiv/l-sha.lua | 27 + tex/context/base/mkiv/l-table.lua | 132 +- tex/context/base/mkiv/l-unicode.lua | 228 +- tex/context/base/mkiv/lang-def.lua | 9 + tex/context/base/mkiv/lang-def.mkiv | 44 +- tex/context/base/mkiv/lang-dis.lua | 107 +- tex/context/base/mkiv/lang-exp.lua | 36 +- tex/context/base/mkiv/lang-hyp.lua | 68 +- tex/context/base/mkiv/lang-hyp.mkiv | 9 +- tex/context/base/mkiv/lang-ini.mkiv | 270 +- tex/context/base/mkiv/lang-lab.mkiv | 12 +- tex/context/base/mkiv/lang-mis.mkiv | 156 +- tex/context/base/mkiv/lang-rep.lua | 7 +- tex/context/base/mkiv/lang-spa.mkiv | 18 +- tex/context/base/mkiv/lang-txt.lua | 102 +- tex/context/base/mkiv/lang-url.lua | 22 +- tex/context/base/mkiv/lang-wrd.lua | 16 +- tex/context/base/mkiv/lpdf-ano.lua | 276 +- tex/context/base/mkiv/lpdf-aux.lua | 152 + tex/context/base/mkiv/lpdf-col.lua | 47 +- tex/context/base/mkiv/lpdf-epa.lua | 783 +- tex/context/base/mkiv/lpdf-epd.lua | 518 +- tex/context/base/mkiv/lpdf-fld.lua | 180 +- tex/context/base/mkiv/lpdf-fmt.lua | 21 +- tex/context/base/mkiv/lpdf-fnt.lua | 202 + tex/context/base/mkiv/lpdf-grp.lua | 72 +- tex/context/base/mkiv/lpdf-ini.lua | 1297 +- tex/context/base/mkiv/lpdf-mis.lua | 126 +- tex/context/base/mkiv/lpdf-nod.lua | 214 +- tex/context/base/mkiv/lpdf-pda.xml | 85 +- tex/context/base/mkiv/lpdf-pde.lua | 1157 + tex/context/base/mkiv/lpdf-pdx.xml | 1 + tex/context/base/mkiv/lpdf-pua.xml | 41 +- tex/context/base/mkiv/lpdf-ren.lua | 12 +- tex/context/base/mkiv/lpdf-res.lua | 26 +- tex/context/base/mkiv/lpdf-swf.lua | 46 +- tex/context/base/mkiv/lpdf-tag.lua | 244 +- tex/context/base/mkiv/lpdf-u3d.lua | 26 +- tex/context/base/mkiv/lpdf-wid.lua | 40 +- tex/context/base/mkiv/lpdf-xmp.lua | 75 +- tex/context/base/mkiv/luat-bas.mkiv | 2 + tex/context/base/mkiv/luat-cbk.lua | 6 + tex/context/base/mkiv/luat-cnf.lua | 4 +- tex/context/base/mkiv/luat-cod.lua | 64 +- tex/context/base/mkiv/luat-env.lua | 24 +- tex/context/base/mkiv/luat-fio.lua | 4 + tex/context/base/mkiv/luat-fmt.lua | 14 +- tex/context/base/mkiv/luat-ini.lua | 16 +- tex/context/base/mkiv/luat-ini.mkiv | 127 +- tex/context/base/mkiv/luat-lib.mkiv | 16 +- tex/context/base/mkiv/luat-run.lua | 111 +- tex/context/base/mkiv/luat-soc.lua | 11 - tex/context/base/mkiv/luat-soc.mkiv | 52 + tex/context/base/mkiv/luat-sto.lua | 2 +- tex/context/base/mkiv/luat-usr.lua | 3 - tex/context/base/mkiv/luat-usr.mkiv | 4 +- tex/context/base/mkiv/lxml-aux.lua | 25 +- tex/context/base/mkiv/lxml-css.lua | 137 +- tex/context/base/mkiv/lxml-inf.lua | 3 +- tex/context/base/mkiv/lxml-ini.mkiv | 21 +- tex/context/base/mkiv/lxml-lpt.lua | 276 +- tex/context/base/mkiv/lxml-tex.lua | 426 +- tex/context/base/mkiv/m-fonts-plugins.mkiv | 5 +- tex/context/base/mkiv/math-act.lua | 44 +- tex/context/base/mkiv/math-ali.mkiv | 29 +- tex/context/base/mkiv/math-arr.mkiv | 57 +- tex/context/base/mkiv/math-dim.lua | 3 +- tex/context/base/mkiv/math-dir.lua | 30 +- tex/context/base/mkiv/math-ext.lua | 27 +- tex/context/base/mkiv/math-fbk.lua | 201 +- tex/context/base/mkiv/math-fen.mkiv | 120 +- tex/context/base/mkiv/math-frc.lua | 4 +- tex/context/base/mkiv/math-frc.mkiv | 42 +- tex/context/base/mkiv/math-inc.lua | 87 + tex/context/base/mkiv/math-inc.mkiv | 69 + tex/context/base/mkiv/math-ini.lua | 9 +- tex/context/base/mkiv/math-ini.mkiv | 146 +- tex/context/base/mkiv/math-noa.lua | 742 +- tex/context/base/mkiv/math-pln.mkiv | 2 +- tex/context/base/mkiv/math-spa.lua | 37 +- tex/context/base/mkiv/math-stc.mkvi | 14 +- tex/context/base/mkiv/math-tag.lua | 437 +- tex/context/base/mkiv/math-vfu.lua | 344 +- tex/context/base/mkiv/meta-blb.lua | 322 + tex/context/base/mkiv/meta-blb.mkiv | 56 + tex/context/base/mkiv/meta-fnt.lua | 24 +- tex/context/base/mkiv/meta-imp-dum.mkiv | 4 +- tex/context/base/mkiv/meta-imp-mat.mkiv | 38 +- tex/context/base/mkiv/meta-imp-txt.mkiv | 76 +- tex/context/base/mkiv/meta-ini.lua | 8 +- tex/context/base/mkiv/meta-ini.mkiv | 57 +- tex/context/base/mkiv/meta-nod.lua | 81 + tex/context/base/mkiv/meta-nod.mkiv | 31 +- tex/context/base/mkiv/meta-pdf.lua | 76 +- tex/context/base/mkiv/meta-pdh.mkiv | 24 +- tex/context/base/mkiv/meta-tex.lua | 6 +- tex/context/base/mkiv/metatex.tex | 30 - tex/context/base/mkiv/mlib-ctx.lua | 87 +- tex/context/base/mkiv/mlib-int.lua | 191 +- tex/context/base/mkiv/mlib-lua.lua | 1175 +- tex/context/base/mkiv/mlib-pdf.lua | 598 +- tex/context/base/mkiv/mlib-pdf.mkiv | 30 +- tex/context/base/mkiv/mlib-pps.lua | 1151 +- tex/context/base/mkiv/mlib-pps.mkiv | 35 +- tex/context/base/mkiv/mlib-run.lua | 279 +- tex/context/base/mkiv/mtx-context-domotica.tex | 31 +- tex/context/base/mkiv/mtx-context-fonts.tex | 98 + tex/context/base/mkiv/mtx-context-listing.tex | 4 +- tex/context/base/mkiv/mtx-context-xml.tex | 5 + tex/context/base/mkiv/mult-aux.mkiv | 562 +- tex/context/base/mkiv/mult-def.lua | 33 +- tex/context/base/mkiv/mult-fun.lua | 34 +- tex/context/base/mkiv/mult-ini.lua | 16 + tex/context/base/mkiv/mult-ini.mkiv | 15 +- tex/context/base/mkiv/mult-low.lua | 58 +- tex/context/base/mkiv/mult-prm.lua | 32 +- tex/context/base/mkiv/mult-prm.mkiv | 3 +- tex/context/base/mkiv/mult-sys.mkiv | 2 + tex/context/base/mkiv/node-acc.lua | 72 +- tex/context/base/mkiv/node-aux.lua | 198 +- tex/context/base/mkiv/node-bck.lua | 378 +- tex/context/base/mkiv/node-bck.mkiv | 21 +- tex/context/base/mkiv/node-dir.lua | 359 +- tex/context/base/mkiv/node-fin.lua | 472 +- tex/context/base/mkiv/node-fin.mkiv | 4 +- tex/context/base/mkiv/node-fnt.lua | 545 +- tex/context/base/mkiv/node-ini.lua | 146 +- tex/context/base/mkiv/node-ini.mkiv | 4 +- tex/context/base/mkiv/node-ltp.lua | 3261 +- tex/context/base/mkiv/node-met.lua | 172 +- tex/context/base/mkiv/node-mig.lua | 6 +- tex/context/base/mkiv/node-nut.lua | 327 +- tex/context/base/mkiv/node-par.lua | 48 + tex/context/base/mkiv/node-ppt.lua | 173 +- tex/context/base/mkiv/node-pro.lua | 137 +- tex/context/base/mkiv/node-ref.lua | 291 +- tex/context/base/mkiv/node-res.lua | 329 +- tex/context/base/mkiv/node-rul.lua | 374 +- tex/context/base/mkiv/node-rul.mkiv | 39 +- tex/context/base/mkiv/node-scn.lua | 31 +- tex/context/base/mkiv/node-ser.lua | 8 +- tex/context/base/mkiv/node-shp.lua | 86 +- tex/context/base/mkiv/node-syn.lua | 109 +- tex/context/base/mkiv/node-tex.lua | 45 +- tex/context/base/mkiv/node-tra.lua | 256 +- tex/context/base/mkiv/node-tsk.lua | 609 +- tex/context/base/mkiv/node-tst.lua | 10 +- tex/context/base/mkiv/pack-bar.mkiv | 6 +- tex/context/base/mkiv/pack-bck.mkvi | 48 +- tex/context/base/mkiv/pack-box.mkiv | 1 + tex/context/base/mkiv/pack-com.mkiv | 18 +- tex/context/base/mkiv/pack-cut.mkiv | 78 +- tex/context/base/mkiv/pack-lyr.mkiv | 86 +- tex/context/base/mkiv/pack-mrl.mkiv | 83 +- tex/context/base/mkiv/pack-obj.lua | 43 +- tex/context/base/mkiv/pack-obj.mkiv | 14 +- tex/context/base/mkiv/pack-rul.lua | 159 +- tex/context/base/mkiv/pack-rul.mkiv | 190 +- tex/context/base/mkiv/page-bck.mkiv | 2 +- tex/context/base/mkiv/page-box.mkvi | 23 +- tex/context/base/mkiv/page-cst.lua | 161 +- tex/context/base/mkiv/page-cst.mkiv | 5 +- tex/context/base/mkiv/page-ffl.mkiv | 39 +- tex/context/base/mkiv/page-flt.mkiv | 10 +- tex/context/base/mkiv/page-imp.mkiv | 92 +- tex/context/base/mkiv/page-inf.mkiv | 8 +- tex/context/base/mkiv/page-ini.lua | 43 +- tex/context/base/mkiv/page-ini.mkiv | 7 +- tex/context/base/mkiv/page-inj.mkvi | 2 +- tex/context/base/mkiv/page-lay.mkiv | 157 +- tex/context/base/mkiv/page-lin.lua | 44 +- tex/context/base/mkiv/page-lin.mkvi | 10 +- tex/context/base/mkiv/page-mix.lua | 19 - tex/context/base/mkiv/page-mix.mkiv | 27 +- tex/context/base/mkiv/page-mul.mkiv | 36 +- tex/context/base/mkiv/page-one.mkiv | 63 +- tex/context/base/mkiv/page-otr.mkvi | 14 +- tex/context/base/mkiv/page-pcl.mkiv | 79 +- tex/context/base/mkiv/page-run.mkiv | 7 +- tex/context/base/mkiv/page-sel.mkvi | 4 +- tex/context/base/mkiv/page-set.mkiv | 67 +- tex/context/base/mkiv/page-sid.mkiv | 153 +- tex/context/base/mkiv/page-smp.mkiv | 59 + tex/context/base/mkiv/page-spr.mkiv | 35 +- tex/context/base/mkiv/page-str.lua | 73 +- tex/context/base/mkiv/page-str.mkiv | 2 +- tex/context/base/mkiv/page-txt.mkvi | 33 +- tex/context/base/mkiv/publ-aut.lua | 48 +- tex/context/base/mkiv/publ-dat.lua | 123 +- tex/context/base/mkiv/publ-imp-apa.mkvi | 87 +- tex/context/base/mkiv/publ-imp-cite.mkvi | 3 - tex/context/base/mkiv/publ-inc.lua | 26 + tex/context/base/mkiv/publ-inc.mkiv | 63 + tex/context/base/mkiv/publ-ini.lua | 43 +- tex/context/base/mkiv/publ-ini.mkiv | 75 +- tex/context/base/mkiv/scrn-bar.mkvi | 2 +- tex/context/base/mkiv/scrn-but.mkvi | 19 +- tex/context/base/mkiv/scrn-fld.mkvi | 106 +- tex/context/base/mkiv/scrn-ini.mkvi | 2 +- tex/context/base/mkiv/scrn-pag.mkvi | 20 +- tex/context/base/mkiv/scrn-ref.mkvi | 18 +- tex/context/base/mkiv/scrn-wid.mkvi | 97 +- tex/context/base/mkiv/scrp-cjk.lua | 107 +- tex/context/base/mkiv/scrp-eth.lua | 86 +- tex/context/base/mkiv/scrp-ini.lua | 247 +- tex/context/base/mkiv/scrp-ini.mkiv | 23 +- tex/context/base/mkiv/scrp-tib.lua | 81 + tex/context/base/mkiv/sort-ini.lua | 29 +- tex/context/base/mkiv/sort-lan.lua | 46 +- tex/context/base/mkiv/spac-adj.lua | 67 - tex/context/base/mkiv/spac-adj.mkiv | 51 - tex/context/base/mkiv/spac-ali.lua | 16 +- tex/context/base/mkiv/spac-ali.mkiv | 134 +- tex/context/base/mkiv/spac-chr.lua | 100 +- tex/context/base/mkiv/spac-chr.mkiv | 2 +- tex/context/base/mkiv/spac-flr.mkiv | 34 +- tex/context/base/mkiv/spac-grd.mkiv | 4 +- tex/context/base/mkiv/spac-hor.mkiv | 56 +- tex/context/base/mkiv/spac-lin.mkiv | 4 +- tex/context/base/mkiv/spac-pag.mkiv | 5 +- tex/context/base/mkiv/spac-par.mkiv | 14 +- tex/context/base/mkiv/spac-prf.lua | 27 +- tex/context/base/mkiv/spac-ver.lua | 421 +- tex/context/base/mkiv/spac-ver.mkiv | 186 +- tex/context/base/mkiv/status-files.pdf | Bin 26054 -> 26589 bytes tex/context/base/mkiv/status-lua.pdf | Bin 255106 -> 268348 bytes tex/context/base/mkiv/strc-blk.lua | 92 +- tex/context/base/mkiv/strc-blk.mkiv | 128 +- tex/context/base/mkiv/strc-con.mkvi | 18 +- tex/context/base/mkiv/strc-def.mkiv | 11 + tex/context/base/mkiv/strc-doc.lua | 138 +- tex/context/base/mkiv/strc-doc.mkiv | 27 +- tex/context/base/mkiv/strc-flt.lua | 34 + tex/context/base/mkiv/strc-flt.mkvi | 312 +- tex/context/base/mkiv/strc-itm.mkvi | 4 +- tex/context/base/mkiv/strc-lnt.mkvi | 6 +- tex/context/base/mkiv/strc-lst.lua | 37 +- tex/context/base/mkiv/strc-lst.mkvi | 17 +- tex/context/base/mkiv/strc-mar.lua | 180 +- tex/context/base/mkiv/strc-mat.mkiv | 16 +- tex/context/base/mkiv/strc-not.lua | 39 +- tex/context/base/mkiv/strc-not.mkvi | 55 +- tex/context/base/mkiv/strc-num.lua | 27 +- tex/context/base/mkiv/strc-num.mkiv | 16 +- tex/context/base/mkiv/strc-pag.lua | 16 +- tex/context/base/mkiv/strc-pag.mkiv | 29 +- tex/context/base/mkiv/strc-ref.lua | 102 +- tex/context/base/mkiv/strc-ref.mkvi | 502 +- tex/context/base/mkiv/strc-reg.lua | 407 +- tex/context/base/mkiv/strc-reg.mkiv | 232 +- tex/context/base/mkiv/strc-ren.mkiv | 46 +- tex/context/base/mkiv/strc-sbe.mkiv | 4 +- tex/context/base/mkiv/strc-sec.mkiv | 107 +- tex/context/base/mkiv/strc-syn.mkiv | 4 +- tex/context/base/mkiv/strc-tag.lua | 106 +- tex/context/base/mkiv/strc-tag.mkiv | 108 +- tex/context/base/mkiv/strc-usr.lua | 29 + tex/context/base/mkiv/strc-usr.mkiv | 180 + tex/context/base/mkiv/supp-box.lua | 236 +- tex/context/base/mkiv/supp-box.mkiv | 182 +- tex/context/base/mkiv/supp-dir.mkiv | 56 +- tex/context/base/mkiv/supp-mat.mkiv | 2 +- tex/context/base/mkiv/symb-emj.lua | 27 +- tex/context/base/mkiv/symb-imp-fontawesome.mkiv | 1505 +- tex/context/base/mkiv/symb-imp-mis.mkiv | 23 +- tex/context/base/mkiv/symb-imp-mvs.mkiv | 18 +- tex/context/base/mkiv/symb-ini.mkiv | 76 +- tex/context/base/mkiv/symb-run.mkiv | 62 +- tex/context/base/mkiv/syst-aux.lua | 133 +- tex/context/base/mkiv/syst-aux.mkiv | 1521 +- tex/context/base/mkiv/syst-cmp.lua | 8 + tex/context/base/mkiv/syst-cmp.mkiv | 22 + tex/context/base/mkiv/syst-ini.mkiv | 643 +- tex/context/base/mkiv/syst-lua.lua | 11 +- tex/context/base/mkiv/syst-lua.mkiv | 36 + tex/context/base/mkiv/syst-rtp.mkiv | 18 + tex/context/base/mkiv/tabl-com.mkiv | 64 +- tex/context/base/mkiv/tabl-ltb.mkiv | 8 +- tex/context/base/mkiv/tabl-ntb.mkiv | 100 +- tex/context/base/mkiv/tabl-tab.mkiv | 38 +- tex/context/base/mkiv/tabl-tbl.mkiv | 463 +- tex/context/base/mkiv/tabl-tsp.mkiv | 29 + tex/context/base/mkiv/tabl-xtb.lua | 13 +- tex/context/base/mkiv/tabl-xtb.mkvi | 149 +- tex/context/base/mkiv/task-ini.lua | 345 +- tex/context/base/mkiv/toks-aux.mkiv | 51 + tex/context/base/mkiv/toks-ini.lua | 115 +- tex/context/base/mkiv/toks-ini.mkiv | 5 - tex/context/base/mkiv/toks-scn.lua | 70 +- tex/context/base/mkiv/toks-scn.mkiv | 22 + tex/context/base/mkiv/trac-deb.lua | 41 +- tex/context/base/mkiv/trac-inf.lua | 42 +- tex/context/base/mkiv/trac-jus.lua | 10 +- tex/context/base/mkiv/trac-log.lua | 63 +- tex/context/base/mkiv/trac-par.lua | 29 +- tex/context/base/mkiv/trac-set.lua | 17 + tex/context/base/mkiv/trac-vis.lua | 366 +- tex/context/base/mkiv/trac-vis.mkiv | 7 +- tex/context/base/mkiv/type-ini.mkvi | 90 +- tex/context/base/mkiv/type-set.mkiv | 2 + tex/context/base/mkiv/typo-bld.lua | 61 +- tex/context/base/mkiv/typo-brk.lua | 30 +- tex/context/base/mkiv/typo-cap.lua | 173 +- tex/context/base/mkiv/typo-cap.mkiv | 62 +- tex/context/base/mkiv/typo-chr.lua | 205 +- tex/context/base/mkiv/typo-chr.mkiv | 19 + tex/context/base/mkiv/typo-cln.lua | 12 +- tex/context/base/mkiv/typo-del.mkiv | 118 +- tex/context/base/mkiv/typo-dha.lua | 58 +- tex/context/base/mkiv/typo-dig.lua | 20 +- tex/context/base/mkiv/typo-dir.lua | 17 +- tex/context/base/mkiv/typo-dir.mkiv | 190 +- tex/context/base/mkiv/typo-drp.lua | 45 +- tex/context/base/mkiv/typo-drp.mkiv | 2 +- tex/context/base/mkiv/typo-dua.lua | 144 +- tex/context/base/mkiv/typo-dub.lua | 271 +- tex/context/base/mkiv/typo-duc.lua | 278 +- tex/context/base/mkiv/typo-fkr.lua | 17 +- tex/context/base/mkiv/typo-fln.lua | 64 +- tex/context/base/mkiv/typo-fln.mkiv | 2 +- tex/context/base/mkiv/typo-itc.lua | 69 +- tex/context/base/mkiv/typo-krn.lua | 314 +- tex/context/base/mkiv/typo-lin.lua | 93 +- tex/context/base/mkiv/typo-mar.lua | 83 +- tex/context/base/mkiv/typo-mar.mkiv | 12 + tex/context/base/mkiv/typo-pag.lua | 5 +- tex/context/base/mkiv/typo-par.mkiv | 2 +- tex/context/base/mkiv/typo-pnc.lua | 21 +- tex/context/base/mkiv/typo-rep.lua | 10 +- tex/context/base/mkiv/typo-rub.lua | 42 +- tex/context/base/mkiv/typo-rub.mkiv | 9 + tex/context/base/mkiv/typo-scr.mkiv | 6 +- tex/context/base/mkiv/typo-spa.lua | 12 +- tex/context/base/mkiv/typo-sus.lua | 9 +- tex/context/base/mkiv/typo-tal.lua | 37 +- tex/context/base/mkiv/typo-wrp.lua | 85 +- tex/context/base/mkiv/typo-wrp.mkiv | 9 +- tex/context/base/mkiv/util-deb.lua | 83 +- tex/context/base/mkiv/util-env.lua | 45 +- tex/context/base/mkiv/util-evo.lua | 109 +- tex/context/base/mkiv/util-fil.lua | 66 +- tex/context/base/mkiv/util-fmt.lua | 11 +- tex/context/base/mkiv/util-jsn.lua | 95 +- tex/context/base/mkiv/util-lib.lua | 62 +- tex/context/base/mkiv/util-lua.lua | 7 +- tex/context/base/mkiv/util-mrg.lua | 1 + tex/context/base/mkiv/util-prs.lua | 35 +- tex/context/base/mkiv/util-sac.lua | 113 +- tex/context/base/mkiv/util-seq.lua | 370 +- tex/context/base/mkiv/util-sha.lua | 35 +- tex/context/base/mkiv/util-soc-imp-copas.lua | 931 + tex/context/base/mkiv/util-soc-imp-ftp.lua | 402 + tex/context/base/mkiv/util-soc-imp-headers.lua | 145 + tex/context/base/mkiv/util-soc-imp-http.lua | 436 + tex/context/base/mkiv/util-soc-imp-ltn12.lua | 387 + tex/context/base/mkiv/util-soc-imp-mime.lua | 104 + tex/context/base/mkiv/util-soc-imp-reset.lua | 13 + tex/context/base/mkiv/util-soc-imp-smtp.lua | 267 + tex/context/base/mkiv/util-soc-imp-socket.lua | 193 + tex/context/base/mkiv/util-soc-imp-tp.lua | 144 + tex/context/base/mkiv/util-soc-imp-url.lua | 268 + tex/context/base/mkiv/util-soc.lua | 32 + tex/context/base/mkiv/util-sql-imp-ffi.lua | 590 +- tex/context/base/mkiv/util-sql-imp-library.lua | 8 +- tex/context/base/mkiv/util-sql-imp-sqlite.lua | 13 +- tex/context/base/mkiv/util-sql-logins.lua | 12 +- tex/context/base/mkiv/util-sql-users.lua | 10 +- tex/context/base/mkiv/util-sta.lua | 14 +- tex/context/base/mkiv/util-sto.lua | 13 + tex/context/base/mkiv/util-str.lua | 526 +- tex/context/base/mkiv/util-tab.lua | 54 +- tex/context/base/mkiv/util-you.lua | 1 - tex/context/fonts/mkiv/type-imp-cambria.mkiv | 11 +- tex/context/fonts/mkiv/type-imp-dejavu.mkiv | 5 +- tex/context/fonts/mkiv/type-imp-firacode.mkiv | 54 + tex/context/fonts/mkiv/type-imp-latinmodern.mkiv | 4 +- tex/context/fonts/mkiv/type-imp-lato.mkiv | 3 +- .../fonts/mkiv/type-imp-lucida-typeone.mkiv | 2 + tex/context/fonts/mkiv/type-imp-modernlatin.mkiv | 56 +- tex/context/fonts/mkiv/type-imp-opendyslexic.mkiv | 7 +- tex/context/fonts/mkiv/type-imp-plex.mkiv | 370 + tex/context/fonts/mkiv/type-imp-source.mkiv | 48 +- tex/context/fonts/mkiv/type-imp-texgyre.mkiv | 17 +- tex/context/interface/mkii/keys-cs.xml | 10 +- tex/context/interface/mkii/keys-de.xml | 8 +- tex/context/interface/mkii/keys-en.xml | 7 +- tex/context/interface/mkii/keys-fr.xml | 7 +- tex/context/interface/mkii/keys-it.xml | 8 +- tex/context/interface/mkii/keys-nl.xml | 12 +- tex/context/interface/mkii/keys-pe.xml | 7 +- tex/context/interface/mkii/keys-ro.xml | 8 +- tex/context/interface/mkiv/context-en.xml | 1416 +- tex/context/interface/mkiv/i-attribute.xml | 2 + tex/context/interface/mkiv/i-backend.xml | 26 +- tex/context/interface/mkiv/i-block.xml | 25 +- tex/context/interface/mkiv/i-boxes.xml | 15 +- tex/context/interface/mkiv/i-buffer.xml | 8 +- tex/context/interface/mkiv/i-character.xml | 8 +- tex/context/interface/mkiv/i-characteralign.xml | 51 + tex/context/interface/mkiv/i-color.xml | 4 +- tex/context/interface/mkiv/i-columns.xml | 8 +- tex/context/interface/mkiv/i-commandhandler.xml | 12 + tex/context/interface/mkiv/i-common-keyword.xml | 17 + tex/context/interface/mkiv/i-common-value.xml | 87 + tex/context/interface/mkiv/i-context.pdf | Bin 846220 -> 865671 bytes tex/context/interface/mkiv/i-context.xml | 6 +- tex/context/interface/mkiv/i-contextname.xml | 2353 + tex/context/interface/mkiv/i-delimitedtext.xml | 5 +- tex/context/interface/mkiv/i-description.xml | 5 + tex/context/interface/mkiv/i-document.xml | 30 + tex/context/interface/mkiv/i-effect.xml | 2 +- tex/context/interface/mkiv/i-enumeration.xml | 5 + tex/context/interface/mkiv/i-file.xml | 2 +- tex/context/interface/mkiv/i-filler.xml | 16 +- tex/context/interface/mkiv/i-fittingpage.xml | 2 +- tex/context/interface/mkiv/i-floats.xml | 222 +- tex/context/interface/mkiv/i-fonts.xml | 36 +- tex/context/interface/mkiv/i-formula.xml | 3 + tex/context/interface/mkiv/i-framed.xml | 17 + tex/context/interface/mkiv/i-graphics.xml | 22 + tex/context/interface/mkiv/i-grid.xml | 9 +- tex/context/interface/mkiv/i-hspace.xml | 7 +- tex/context/interface/mkiv/i-interactionscreen.xml | 1 + tex/context/interface/mkiv/i-kerning.xml | 32 + tex/context/interface/mkiv/i-label.xml | 5 + tex/context/interface/mkiv/i-language.xml | 10 + tex/context/interface/mkiv/i-layout.xml | 5 +- tex/context/interface/mkiv/i-linefiller.xml | 105 + tex/context/interface/mkiv/i-list.xml | 64 +- tex/context/interface/mkiv/i-math.xml | 14 +- tex/context/interface/mkiv/i-mathfence.xml | 3 + tex/context/interface/mkiv/i-mathmatrix.xml | 9 + tex/context/interface/mkiv/i-mathname.xml | 1091 + tex/context/interface/mkiv/i-narrow.xml | 6 +- tex/context/interface/mkiv/i-note.xml | 6 + tex/context/interface/mkiv/i-pagecolumns.xml | 90 + tex/context/interface/mkiv/i-pagegrid.xml | 325 +- tex/context/interface/mkiv/i-pagemarks.xml | 18 +- tex/context/interface/mkiv/i-pagestate.xml | 41 +- tex/context/interface/mkiv/i-readme.pdf | Bin 61029 -> 61161 bytes tex/context/interface/mkiv/i-register.xml | 24 +- tex/context/interface/mkiv/i-ruby.xml | 1 + tex/context/interface/mkiv/i-scale.xml | 3 + tex/context/interface/mkiv/i-script.xml | 22 +- tex/context/interface/mkiv/i-section.xml | 2 +- tex/context/interface/mkiv/i-setups.xml | 9 +- tex/context/interface/mkiv/i-startstop.xml | 30 +- tex/context/interface/mkiv/i-strut.xml | 2 + tex/context/interface/mkiv/i-symbol.xml | 5 + tex/context/interface/mkiv/i-system.xml | 53 +- tex/context/interface/mkiv/i-tabulation.xml | 23 +- tex/context/interface/mkiv/i-tagging.xml | 10 +- tex/context/interface/mkiv/i-texts.xml | 79 +- tex/context/interface/mkiv/i-token.xml | 31 + tex/context/interface/mkiv/i-unit.xml | 12 + tex/context/interface/mkiv/i-userdata.xml | 85 + tex/context/interface/mkiv/i-verbatim.xml | 4 +- tex/context/interface/mkiv/i-visualizer.xml | 20 +- tex/context/interface/mkiv/i-vspace.xml | 109 +- tex/context/interface/mkiv/i-whitespace.xml | 6 +- tex/context/interface/mkiv/i-xml.xml | 28 + tex/context/interface/mkiv/i-xtable.xml | 48 +- .../modules/common/s-abbreviations-logos.tex | 3 + tex/context/modules/mkiv/m-asymptote.lua | 2 +- tex/context/modules/mkiv/m-asymptote.mkiv | 58 +- tex/context/modules/mkiv/m-chart.lua | 17 +- tex/context/modules/mkiv/m-chart.mkvi | 7 +- tex/context/modules/mkiv/m-format.mkiv | 4 +- tex/context/modules/mkiv/m-matrix.mkiv | 153 +- tex/context/modules/mkiv/m-maybe.mkiv | 57 + tex/context/modules/mkiv/m-old-columnsets.mkiv | 7 + tex/context/modules/mkiv/m-old-multicolumns.mkiv | 7 + tex/context/modules/mkiv/m-oldfun.mkiv | 4 +- tex/context/modules/mkiv/m-oldnum.mkiv | 25 +- tex/context/modules/mkiv/m-punk.mkiv | 27 +- tex/context/modules/mkiv/m-scite.mkiv | 36 +- tex/context/modules/mkiv/m-units.mkiv | 14 +- tex/context/modules/mkiv/ppchtex.mkiv | 8 +- tex/context/modules/mkiv/s-article-basic.mkiv | 19 + tex/context/modules/mkiv/s-article-titlepage.mkiv | 65 + tex/context/modules/mkiv/s-article-titletop.mkiv | 68 + tex/context/modules/mkiv/s-cgj.mkiv | 714 + tex/context/modules/mkiv/s-evohome.mkiv | 16 +- tex/context/modules/mkiv/s-fonts-basics.mkiv | 2 +- tex/context/modules/mkiv/s-fonts-charts.mkiv | 70 +- tex/context/modules/mkiv/s-fonts-complete.mkiv | 119 +- tex/context/modules/mkiv/s-fonts-effects.mkiv | 59 + tex/context/modules/mkiv/s-fonts-features.lua | 173 +- tex/context/modules/mkiv/s-fonts-features.mkiv | 1 + tex/context/modules/mkiv/s-fonts-shapes.lua | 380 +- tex/context/modules/mkiv/s-fonts-shapes.mkiv | 21 +- tex/context/modules/mkiv/s-fonts-statistics.mkiv | 80 + tex/context/modules/mkiv/s-fonts-system.lua | 274 +- tex/context/modules/mkiv/s-fonts-system.mkiv | 17 +- tex/context/modules/mkiv/s-fonts-tables.lua | 655 +- tex/context/modules/mkiv/s-fonts-tables.mkiv | 22 +- tex/context/modules/mkiv/s-fonts-variable.mkiv | 30 +- .../modules/mkiv/s-languages-hyphenation.lua | 7 +- tex/context/modules/mkiv/s-languages-system.lua | 2 +- tex/context/modules/mkiv/s-maps.mkiv | 8 +- tex/context/modules/mkiv/s-present-dark.mkiv | 357 + tex/context/modules/mkiv/s-present-steps.mkiv | 177 + .../modules/mkiv/s-references-identify.mkiv | 69 + tex/context/modules/mkiv/s-xml-analyzers.lua | 6 + tex/context/modules/mkiv/s-youless.mkiv | 60 +- tex/context/modules/mkiv/x-asciimath.lua | 24 +- tex/context/modules/mkiv/x-mathml.mkiv | 2 +- tex/context/modules/mkiv/x-setups-basics.mkiv | 19 +- tex/context/modules/mkiv/x-setups-overview.mkiv | 9 +- tex/context/patterns/common/lang-agr.rme | 41 +- tex/context/patterns/common/lang-bg.rme | 935 +- tex/context/patterns/common/lang-de.rme | 65 +- tex/context/patterns/common/lang-deo.rme | 65 +- tex/context/patterns/common/lang-fr.rme | 9 +- tex/context/patterns/common/lang-la.rme | 96 +- tex/context/patterns/common/lang-th.rme | 35 +- tex/context/patterns/mkii/lang-agr.pat | 72 +- tex/context/patterns/mkii/lang-bg.pat | 8508 ++- tex/context/patterns/mkii/lang-de.pat | 22403 +++++-- tex/context/patterns/mkii/lang-deo.pat | 21973 +++++-- tex/context/patterns/mkii/lang-fr.pat | 4 + tex/context/patterns/mkii/lang-la.pat | 1 + tex/context/patterns/mkii/lang-th.pat | 321 +- tex/context/patterns/mkiv/lang-agr.lua | 47 +- tex/context/patterns/mkiv/lang-bg.lua | 943 +- tex/context/patterns/mkiv/lang-de.lua | 71 +- tex/context/patterns/mkiv/lang-deo.lua | 71 +- tex/context/patterns/mkiv/lang-fr.lua | 15 +- tex/context/patterns/mkiv/lang-la.lua | 102 +- tex/context/patterns/mkiv/lang-th.lua | 41 +- tex/context/sample/common/aesop-de.tex | 25 - tex/context/sample/common/cervantes-es.tex | 6 - tex/context/sample/common/khatt-ar.tex | 4 - tex/context/sample/common/khatt-en.tex | 4 - tex/context/sample/common/quevedo-es.tex | 19 - tex/context/sample/third/aesop-de.tex | 25 + tex/context/sample/third/cervantes-es.tex | 6 + tex/context/sample/third/khatt-ar.tex | 4 + tex/context/sample/third/khatt-en.tex | 4 + tex/context/sample/third/quevedo-es.tex | 19 + tex/generic/context/luatex/luatex-basics-gen.lua | 259 +- tex/generic/context/luatex/luatex-basics-nod.lua | 317 +- tex/generic/context/luatex/luatex-core.lua | 72 +- tex/generic/context/luatex/luatex-fonts-def.lua | 98 + tex/generic/context/luatex/luatex-fonts-enc.lua | 3 +- tex/generic/context/luatex/luatex-fonts-ext.lua | 251 +- tex/generic/context/luatex/luatex-fonts-gbn.lua | 300 + tex/generic/context/luatex/luatex-fonts-lig.lua | 2 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 59846 ++++++++++--------- tex/generic/context/luatex/luatex-fonts-mis.lua | 5 +- tex/generic/context/luatex/luatex-fonts-syn.lua | 7 +- tex/generic/context/luatex/luatex-fonts.lua | 127 +- tex/generic/context/luatex/luatex-languages.lua | 15 +- tex/generic/context/luatex/luatex-mplib.lua | 6 +- tex/generic/context/luatex/luatex-pdf.tex | 6 + tex/generic/context/luatex/luatex-swiglib.lua | 2 +- tex/generic/context/luatex/luatex-test.tex | 14 +- 757 files changed, 133863 insertions(+), 72997 deletions(-) delete mode 100644 tex/context/base/mkii/syst-rtp.mkiv create mode 100644 tex/context/base/mkiv/anch-snc.lua create mode 100644 tex/context/base/mkiv/back-pdp.lua create mode 100644 tex/context/base/mkiv/back-res.lua create mode 100644 tex/context/base/mkiv/colo-imp-svg.mkiv create mode 100644 tex/context/base/mkiv/core-lmt.lua create mode 100644 tex/context/base/mkiv/core-lmt.mkiv create mode 100644 tex/context/base/mkiv/driv-ini.lua create mode 100644 tex/context/base/mkiv/driv-ini.mkiv delete mode 100644 tex/context/base/mkiv/font-ext.lua delete mode 100644 tex/context/base/mkiv/font-gbn.lua create mode 100644 tex/context/base/mkiv/font-imp-dimensions.lua create mode 100644 tex/context/base/mkiv/font-imp-effects.lua create mode 100644 tex/context/base/mkiv/font-imp-italics.lua create mode 100644 tex/context/base/mkiv/font-imp-ligatures.lua create mode 100644 tex/context/base/mkiv/font-imp-math.lua create mode 100644 tex/context/base/mkiv/font-imp-notused.lua create mode 100644 tex/context/base/mkiv/font-imp-properties.lua create mode 100644 tex/context/base/mkiv/font-imp-quality.lua create mode 100644 tex/context/base/mkiv/font-imp-reorder.lua create mode 100644 tex/context/base/mkiv/font-imp-tex.lua create mode 100644 tex/context/base/mkiv/font-imp-tracing.lua create mode 100644 tex/context/base/mkiv/font-imp-unicode.lua create mode 100644 tex/context/base/mkiv/font-prv.lua create mode 100644 tex/context/base/mkiv/font-vfc.lua delete mode 100644 tex/context/base/mkiv/font-xtx.lua delete mode 100644 tex/context/base/mkiv/java-imp-exa.mkiv create mode 100644 tex/context/base/mkiv/java-imp-example.mkiv create mode 100644 tex/context/base/mkiv/java-imp-fields.mkiv delete mode 100644 tex/context/base/mkiv/java-imp-fil.mkiv delete mode 100644 tex/context/base/mkiv/java-imp-fld.mkiv create mode 100644 tex/context/base/mkiv/java-imp-highlight.mkiv create mode 100644 tex/context/base/mkiv/java-imp-print.mkiv delete mode 100644 tex/context/base/mkiv/java-imp-rhh.mkiv create mode 100644 tex/context/base/mkiv/java-imp-steps.mkiv delete mode 100644 tex/context/base/mkiv/java-imp-stp.mkiv create mode 100644 tex/context/base/mkiv/java-imp-videoplayer.mkiv create mode 100644 tex/context/base/mkiv/java-imp-vplayer.mkiv create mode 100644 tex/context/base/mkiv/l-sha.lua create mode 100644 tex/context/base/mkiv/lpdf-aux.lua create mode 100644 tex/context/base/mkiv/lpdf-fnt.lua create mode 100644 tex/context/base/mkiv/lpdf-pde.lua delete mode 100644 tex/context/base/mkiv/luat-soc.lua create mode 100644 tex/context/base/mkiv/luat-soc.mkiv create mode 100644 tex/context/base/mkiv/math-inc.lua create mode 100644 tex/context/base/mkiv/math-inc.mkiv create mode 100644 tex/context/base/mkiv/meta-blb.lua create mode 100644 tex/context/base/mkiv/meta-blb.mkiv create mode 100644 tex/context/base/mkiv/meta-nod.lua delete mode 100644 tex/context/base/mkiv/metatex.tex create mode 100644 tex/context/base/mkiv/mtx-context-fonts.tex create mode 100644 tex/context/base/mkiv/node-par.lua create mode 100644 tex/context/base/mkiv/page-smp.mkiv create mode 100644 tex/context/base/mkiv/publ-inc.lua create mode 100644 tex/context/base/mkiv/publ-inc.mkiv create mode 100644 tex/context/base/mkiv/scrp-tib.lua delete mode 100644 tex/context/base/mkiv/spac-adj.lua delete mode 100644 tex/context/base/mkiv/spac-adj.mkiv create mode 100644 tex/context/base/mkiv/strc-usr.lua create mode 100644 tex/context/base/mkiv/strc-usr.mkiv create mode 100644 tex/context/base/mkiv/syst-cmp.lua create mode 100644 tex/context/base/mkiv/syst-cmp.mkiv create mode 100644 tex/context/base/mkiv/syst-rtp.mkiv create mode 100644 tex/context/base/mkiv/toks-aux.mkiv create mode 100644 tex/context/base/mkiv/toks-scn.mkiv create mode 100644 tex/context/base/mkiv/util-soc-imp-copas.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-ftp.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-headers.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-http.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-ltn12.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-mime.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-reset.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-smtp.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-socket.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-tp.lua create mode 100644 tex/context/base/mkiv/util-soc-imp-url.lua create mode 100644 tex/context/fonts/mkiv/type-imp-firacode.mkiv create mode 100644 tex/context/fonts/mkiv/type-imp-plex.mkiv create mode 100644 tex/context/interface/mkiv/i-contextname.xml create mode 100644 tex/context/interface/mkiv/i-linefiller.xml create mode 100644 tex/context/interface/mkiv/i-mathname.xml create mode 100644 tex/context/interface/mkiv/i-pagecolumns.xml create mode 100644 tex/context/interface/mkiv/i-userdata.xml create mode 100644 tex/context/modules/mkiv/m-maybe.mkiv create mode 100644 tex/context/modules/mkiv/m-old-columnsets.mkiv create mode 100644 tex/context/modules/mkiv/m-old-multicolumns.mkiv create mode 100644 tex/context/modules/mkiv/s-article-titlepage.mkiv create mode 100644 tex/context/modules/mkiv/s-article-titletop.mkiv create mode 100644 tex/context/modules/mkiv/s-cgj.mkiv create mode 100644 tex/context/modules/mkiv/s-fonts-effects.mkiv create mode 100644 tex/context/modules/mkiv/s-fonts-statistics.mkiv create mode 100644 tex/context/modules/mkiv/s-present-dark.mkiv create mode 100644 tex/context/modules/mkiv/s-present-steps.mkiv create mode 100644 tex/context/modules/mkiv/s-references-identify.mkiv delete mode 100644 tex/context/sample/common/aesop-de.tex delete mode 100644 tex/context/sample/common/cervantes-es.tex delete mode 100644 tex/context/sample/common/khatt-ar.tex delete mode 100644 tex/context/sample/common/khatt-en.tex delete mode 100644 tex/context/sample/common/quevedo-es.tex create mode 100644 tex/context/sample/third/aesop-de.tex create mode 100644 tex/context/sample/third/cervantes-es.tex create mode 100644 tex/context/sample/third/khatt-ar.tex create mode 100644 tex/context/sample/third/khatt-en.tex create mode 100644 tex/context/sample/third/quevedo-es.tex create mode 100644 tex/generic/context/luatex/luatex-fonts-def.lua create mode 100644 tex/generic/context/luatex/luatex-fonts-gbn.lua (limited to 'tex') diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii index 494992502..a688bc4b4 100644 --- a/tex/context/base/mkii/cont-new.mkii +++ b/tex/context/base/mkii/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.04.04 00:51} +\newcontextversion{2019.02.22 19:35} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii index 293866194..398b6e894 100644 --- a/tex/context/base/mkii/context.mkii +++ b/tex/context/base/mkii/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2018.04.04 00:51} +\edef\contextversion{2019.02.22 19:35} %D For those who want to use this: diff --git a/tex/context/base/mkii/core-sys.mkii b/tex/context/base/mkii/core-sys.mkii index 54778eeed..5aa669d2c 100644 --- a/tex/context/base/mkii/core-sys.mkii +++ b/tex/context/base/mkii/core-sys.mkii @@ -167,7 +167,7 @@ \def\stoplocal {\dostopglobaldefs} \def\startglobal {\dostartglobaldefs<+} \def\stopglobal {\dostopglobaldefs} - + \def\complexstart[#1]{\bgroup\getvalue{\e!start#1}} \def\complexstop [#1]{\getvalue{\e!stop #1}\egroup} @@ -215,7 +215,7 @@ \def\setupstartstop {\dodoubleargument\dosetupstartstop} - + % \docommand kan niet worden gebruikt omdat deze macro % soms lokaal wordt gebruikt @@ -275,7 +275,7 @@ \def\docommand##1{\setbox0\hbox{\getvalue{\string##1}##1}}% \processcommalist[#1]\docommand \egroup} - + \newif\ifforcefileexpansion % handy for document level overload %D The next implementation is about 4 times as faster than a @@ -374,7 +374,7 @@ \let\unicodechar\numbertoutf \edef\ascii{#1}% \expandafter\endgroup\expandafter\edef\expandafter#2\expandafter{\ascii}} - + % \setvalue{statevalue\v!stop }{0} % \setvalue{statevalue\v!start }{1} % \setvalue{statevalue\v!normaal}{2} @@ -385,12 +385,12 @@ % {\chardef\currentstate=0\getvalue{statevalue\getvalue{#1\c!state}\relax} % % \ifcase\currentstate ... - + \def\redo{\dorepeat} % [n*10], kind of obsolete % obsolete, use \dorecurse instead % % \def\herhaler {\repeater} % \def\herhaalmetcommando {\dorepeatwithcommand} - + \protect \endinput diff --git a/tex/context/base/mkii/enco-agr.mkii b/tex/context/base/mkii/enco-agr.mkii index 1dbb9b577..9d821cca1 100644 --- a/tex/context/base/mkii/enco-agr.mkii +++ b/tex/context/base/mkii/enco-agr.mkii @@ -17,6 +17,7 @@ \definecasemaps 91 to 255 lc 0 uc 0 \definecaseself 4 % apostrofe + \definecaseself 5 % greekbetaalt \stopmapping @@ -26,7 +27,7 @@ \definecharacter endash 2 \definecharacter emdash 3 \definecharacter apostrophe 4 -\definecharacter greekaltbeta 5 +\definecharacter greekbetaalt 5 \definecharacter epih 6 \definecharacter textbraceleft 8 diff --git a/tex/context/base/mkii/enco-def.mkii b/tex/context/base/mkii/enco-def.mkii index 20c885d4d..53a3e9a98 100644 --- a/tex/context/base/mkii/enco-def.mkii +++ b/tex/context/base/mkii/enco-def.mkii @@ -505,6 +505,7 @@ \definecharacter greekalpha {\alpha} \definecharacter greekbeta {\beta} +\definecharacter greekbetaalt {\beta} \definecharacter greekgamma {\gamma} \definecharacter greekdelta {\delta} \definecharacter greekepsilon {\varepsilon} diff --git a/tex/context/base/mkii/enco-uc.mkii b/tex/context/base/mkii/enco-uc.mkii index 0be22318a..f39260b16 100644 --- a/tex/context/base/mkii/enco-uc.mkii +++ b/tex/context/base/mkii/enco-uc.mkii @@ -505,6 +505,8 @@ \definecharacter greekupsilondialytikatonos {\uchar3{176}} % new: + +\definecharacter greekbetaalt {\uchar3{208}} \definecharacter greekthetaalt {\uchar3{209}} \definecharacter greekphialt {\uchar3{213}} \definecharacter greekpialt {\uchar3{214}} diff --git a/tex/context/base/mkii/mult-cs.mkii b/tex/context/base/mkii/mult-cs.mkii index 9a4cc112b..4ab875e4d 100644 --- a/tex/context/base/mkii/mult-cs.mkii +++ b/tex/context/base/mkii/mult-cs.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{barevne} \setinterfacevariable{column}{column} \setinterfacevariable{columns}{sloupce} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positiv} \setinterfacevariable{postponing}{odlozit} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{nastaveni} \setinterfacevariable{preview}{nahled} \setinterfacevariable{previous}{predchozi} @@ -586,6 +587,7 @@ \setinterfacevariable{understrike}{understrike} \setinterfacevariable{understrikes}{understrikes} \setinterfacevariable{unframed}{unframed} +\setinterfacevariable{unicode}{unicode} \setinterfacevariable{unit}{jednotka} \setinterfacevariable{units}{jednotky} \setinterfacevariable{unknown}{neznamy} @@ -853,7 +855,7 @@ \setinterfaceconstant{headseparator}{headseparator} \setinterfaceconstant{headstyle}{stylhlavicky} \setinterfaceconstant{height}{vyska} -\setinterfaceconstant{hfactor}{vfaktor} +\setinterfaceconstant{hfactor}{hfaktor} \setinterfaceconstant{hfil}{hfil} \setinterfaceconstant{hidenumber}{hidenumber} \setinterfaceconstant{hoffset}{hoffset} @@ -1027,6 +1029,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{outermargin} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{vlastnicislo} \setinterfaceconstant{page}{stranka} \setinterfaceconstant{pageboundaries}{hranicestranky} @@ -1240,6 +1243,7 @@ \setinterfaceconstant{textstyle}{styltextu} \setinterfaceconstant{textwidth}{sirkatextu} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{titul} \setinterfaceconstant{titlecolor}{barvatitulek} \setinterfaceconstant{titlecommand}{titlecommand} @@ -1268,12 +1272,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{urlalternativa} \setinterfaceconstant{urlspace}{prostorurl} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{validovat} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{vprikaz} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{offsethlavicky} +\setinterfaceconstant{vfactor}{vfaktor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/mult-de.mkii b/tex/context/base/mkii/mult-de.mkii index a5269ff3f..46a239304 100644 --- a/tex/context/base/mkii/mult-de.mkii +++ b/tex/context/base/mkii/mult-de.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{farbe} \setinterfacevariable{column}{column} \setinterfacevariable{columns}{spalten} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positiv} \setinterfacevariable{postponing}{verschieben} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{einstellung} \setinterfacevariable{preview}{vorschau} \setinterfacevariable{previous}{vorig} @@ -586,6 +587,7 @@ \setinterfacevariable{understrike}{understrike} \setinterfacevariable{understrikes}{understrikes} \setinterfacevariable{unframed}{unframed} +\setinterfacevariable{unicode}{unicode} \setinterfacevariable{unit}{einheit} \setinterfacevariable{units}{einheiten} \setinterfacevariable{unknown}{unbekannt} @@ -1027,6 +1029,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{outermargin} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{eigenenummer} \setinterfaceconstant{page}{seite} \setinterfaceconstant{pageboundaries}{seitenbegrenzung} @@ -1240,6 +1243,7 @@ \setinterfaceconstant{textstyle}{textstil} \setinterfaceconstant{textwidth}{textbreite} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{titel} \setinterfaceconstant{titlecolor}{titelfarbe} \setinterfaceconstant{titlecommand}{titlecommand} @@ -1268,12 +1272,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{urlalternative} \setinterfaceconstant{urlspace}{urlspatium} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{validieren} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{vbefehl} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{kopfoffset} +\setinterfaceconstant{vfactor}{vfaktor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/mult-en.mkii b/tex/context/base/mkii/mult-en.mkii index 5c233a0c4..faf268576 100644 --- a/tex/context/base/mkii/mult-en.mkii +++ b/tex/context/base/mkii/mult-en.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{color} \setinterfacevariable{column}{column} \setinterfacevariable{columns}{columns} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positive} \setinterfacevariable{postponing}{postponing} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{preference} \setinterfacevariable{preview}{preview} \setinterfacevariable{previous}{previous} @@ -1027,6 +1028,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{outermargin} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{ownnumber} \setinterfaceconstant{page}{page} \setinterfaceconstant{pageboundaries}{pageboundaries} @@ -1240,6 +1242,7 @@ \setinterfaceconstant{textstyle}{textstyle} \setinterfaceconstant{textwidth}{textwidth} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{title} \setinterfaceconstant{titlecolor}{titlecolor} \setinterfaceconstant{titlecommand}{titlecommand} @@ -1268,12 +1271,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{urlalternative} \setinterfaceconstant{urlspace}{urlspace} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{validate} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{vcommand} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfactor}{vfactor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/mult-fr.mkii b/tex/context/base/mkii/mult-fr.mkii index 7cf1bc684..fe883d50f 100644 --- a/tex/context/base/mkii/mult-fr.mkii +++ b/tex/context/base/mkii/mult-fr.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{couleur} \setinterfacevariable{column}{colonne} \setinterfacevariable{columns}{colonnes} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positif} \setinterfacevariable{postponing}{postponing} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{preference} \setinterfacevariable{preview}{previsualisation} \setinterfacevariable{previous}{precedent} @@ -1027,6 +1028,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{margeexterieure} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{numeroproprio} \setinterfaceconstant{page}{page} \setinterfaceconstant{pageboundaries}{limitespage} @@ -1240,6 +1242,7 @@ \setinterfaceconstant{textstyle}{styletexte} \setinterfaceconstant{textwidth}{largeurtexte} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{titre} \setinterfaceconstant{titlecolor}{couleurtitre} \setinterfaceconstant{titlecommand}{titlecommand} @@ -1268,12 +1271,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{alternativeurl} \setinterfaceconstant{urlspace}{espaceurl} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{valider} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{vcommande} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfactor}{vfactor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/mult-it.mkii b/tex/context/base/mkii/mult-it.mkii index 38fb2de40..d83672d38 100644 --- a/tex/context/base/mkii/mult-it.mkii +++ b/tex/context/base/mkii/mult-it.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{colore} \setinterfacevariable{column}{colonna} \setinterfacevariable{columns}{colonne} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positivo} \setinterfacevariable{postponing}{posporre} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{preferenza} \setinterfacevariable{preview}{anteprima} \setinterfacevariable{previous}{precedente} @@ -586,6 +587,7 @@ \setinterfacevariable{understrike}{understrike} \setinterfacevariable{understrikes}{understrikes} \setinterfacevariable{unframed}{unframed} +\setinterfacevariable{unicode}{unicode} \setinterfacevariable{unit}{unita} \setinterfacevariable{units}{unita} \setinterfacevariable{unknown}{ignoto} @@ -1027,6 +1029,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{margineesterno} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{numeroproprio} \setinterfaceconstant{page}{pagina} \setinterfaceconstant{pageboundaries}{limitipagina} @@ -1240,6 +1243,7 @@ \setinterfaceconstant{textstyle}{stiletesto} \setinterfaceconstant{textwidth}{ampiezzatesto} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{titolo} \setinterfaceconstant{titlecolor}{coloretitolo} \setinterfaceconstant{titlecommand}{titlecommand} @@ -1268,12 +1272,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{alternativaurl} \setinterfaceconstant{urlspace}{spaziourl} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{verifica} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{vcomando} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfactor}{vfactor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/mult-nl.mkii b/tex/context/base/mkii/mult-nl.mkii index ba7c5a42c..884503363 100644 --- a/tex/context/base/mkii/mult-nl.mkii +++ b/tex/context/base/mkii/mult-nl.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemie} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{gesloten} \setinterfacevariable{color}{kleur} \setinterfacevariable{column}{kolom} \setinterfacevariable{columns}{kolommen} @@ -185,6 +186,7 @@ \setinterfacevariable{extremestretch}{extremestretch} \setinterfacevariable{fact}{gegeven} \setinterfacevariable{february}{februari} +\setinterfacevariable{field}{veld} \setinterfacevariable{figure}{figuur} \setinterfacevariable{figures}{figuren} \setinterfacevariable{file}{file} @@ -794,7 +796,7 @@ \setinterfaceconstant{family}{soort} \setinterfaceconstant{features}{features} \setinterfaceconstant{fences}{fences} -\setinterfaceconstant{field}{field} +\setinterfaceconstant{field}{veld} \setinterfaceconstant{fieldbackgroundcolor}{veldachtergrondkleur} \setinterfaceconstant{fieldframecolor}{veldkaderkleur} \setinterfaceconstant{fieldlayer}{veldlaag} @@ -849,6 +851,7 @@ \setinterfaceconstant{headerstate}{hoofdstatus} \setinterfaceconstant{headlabel}{koplabel} \setinterfaceconstant{headnumber}{kopnummer} +\setinterfaceconstant{headseparator}{kopscheider} \setinterfaceconstant{headstyle}{kopletter} \setinterfaceconstant{height}{hoogte} \setinterfaceconstant{hfactor}{hfactor} @@ -1025,6 +1028,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{buitenmarge} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{eigennummer} \setinterfaceconstant{page}{pagina} \setinterfaceconstant{pageboundaries}{paginaovergangen} @@ -1075,6 +1079,7 @@ \setinterfaceconstant{preview}{preview} \setinterfaceconstant{previous}{vorige} \setinterfaceconstant{previousnumber}{vorigenummer} +\setinterfaceconstant{print}{print} \setinterfaceconstant{printable}{printbaar} \setinterfaceconstant{process}{proces} \setinterfaceconstant{profile}{profile} @@ -1160,8 +1165,10 @@ \setinterfaceconstant{sidemethod}{zijmethode} \setinterfaceconstant{sidespaceafter}{zijnawit} \setinterfaceconstant{sidespacebefore}{zijvoorwit} +\setinterfaceconstant{sidespaceinbetween}{zijtussenwit} \setinterfaceconstant{sidethreshold}{sidethreshold} \setinterfaceconstant{sign}{teken} +\setinterfaceconstant{simplecommand}{simpelcommando} \setinterfaceconstant{size}{formaat} \setinterfaceconstant{slantedfeatures}{slantedfeatures} \setinterfaceconstant{slantedfont}{slantedfont} @@ -1235,6 +1242,7 @@ \setinterfaceconstant{textstyle}{tekstletter} \setinterfaceconstant{textwidth}{tekstbreedte} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{tijd} \setinterfaceconstant{title}{titel} \setinterfaceconstant{titlecolor}{titelkleur} \setinterfaceconstant{titlecommand}{titelcommando} @@ -1263,12 +1271,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{urlvariant} \setinterfaceconstant{urlspace}{urlspatie} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{valideer} \setinterfaceconstant{values}{waarden} \setinterfaceconstant{vcommand}{vcommando} \setinterfaceconstant{vcompact}{vcomprimeer} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{kopoffset} +\setinterfaceconstant{vfactor}{vfactor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/mult-pe.mkii b/tex/context/base/mkii/mult-pe.mkii index 534c239da..57cbe5600 100644 --- a/tex/context/base/mkii/mult-pe.mkii +++ b/tex/context/base/mkii/mult-pe.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{رنگ} \setinterfacevariable{column}{ستون} \setinterfacevariable{columns}{ستونها} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{مثبت} \setinterfacevariable{postponing}{تاخیر} \setinterfacevariable{postscript}{پست‌اسکریپت} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{ترجیح} \setinterfacevariable{preview}{پیش‌دید} \setinterfacevariable{previous}{قبلی} @@ -1027,6 +1028,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{حاشیه‌خارجی} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{شماره‌خود} \setinterfaceconstant{page}{صفحه} \setinterfaceconstant{pageboundaries}{مرزهای‌صفحه} @@ -1240,6 +1242,7 @@ \setinterfaceconstant{textstyle}{سبک‌متن} \setinterfaceconstant{textwidth}{عرض‌متن} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{عنوان} \setinterfaceconstant{titlecolor}{رنگ‌عنوان} \setinterfaceconstant{titlecommand}{فرمان‌عنوان} @@ -1268,12 +1271,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{urlalternative} \setinterfaceconstant{urlspace}{urlspace} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{تاییداعتبار} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{vcommand} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{آفست‌عم} +\setinterfaceconstant{vfactor}{vfactor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{آفست‌ع} diff --git a/tex/context/base/mkii/mult-ro.mkii b/tex/context/base/mkii/mult-ro.mkii index 46b61c882..786319956 100644 --- a/tex/context/base/mkii/mult-ro.mkii +++ b/tex/context/base/mkii/mult-ro.mkii @@ -137,6 +137,7 @@ \setinterfacevariable{chemicals}{chemicals} \setinterfacevariable{chemistry}{chemistry} \setinterfacevariable{cite}{cite} +\setinterfacevariable{closed}{closed} \setinterfacevariable{color}{culoare} \setinterfacevariable{column}{coloana} \setinterfacevariable{columns}{coloane} @@ -418,7 +419,7 @@ \setinterfacevariable{positive}{positiv} \setinterfacevariable{postponing}{postponing} \setinterfacevariable{postscript}{postscript} -\setinterfacevariable{precedingpage}{followingpage} +\setinterfacevariable{precedingpage}{precedingpage} \setinterfacevariable{preference}{preferinta} \setinterfacevariable{preview}{previzualizare} \setinterfacevariable{previous}{precedent} @@ -586,6 +587,7 @@ \setinterfacevariable{understrike}{understrike} \setinterfacevariable{understrikes}{understrikes} \setinterfacevariable{unframed}{unframed} +\setinterfacevariable{unicode}{unicode} \setinterfacevariable{unit}{unitate} \setinterfacevariable{units}{unitati} \setinterfacevariable{unknown}{necunoscut} @@ -1027,6 +1029,7 @@ \setinterfaceconstant{otherstext}{otherstext} \setinterfaceconstant{outermargin}{outermargin} \setinterfaceconstant{overprint}{overprint} +\setinterfaceconstant{ownerpassword}{ownerpassword} \setinterfaceconstant{ownnumber}{numarpropriu} \setinterfaceconstant{page}{pagina} \setinterfaceconstant{pageboundaries}{marginipagina} @@ -1240,6 +1243,7 @@ \setinterfaceconstant{textstyle}{stiltext} \setinterfaceconstant{textwidth}{latimetext} \setinterfaceconstant{threshold}{threshold} +\setinterfaceconstant{time}{time} \setinterfaceconstant{title}{titlu} \setinterfaceconstant{titlecolor}{culoaretitlu} \setinterfaceconstant{titlecommand}{titlecommand} @@ -1268,12 +1272,14 @@ \setinterfaceconstant{up}{up} \setinterfaceconstant{urlalternative}{urlalternativ} \setinterfaceconstant{urlspace}{spatiuurl} +\setinterfaceconstant{userpassword}{userpassword} \setinterfaceconstant{validate}{verifica} \setinterfaceconstant{values}{values} \setinterfaceconstant{vcommand}{comandav} \setinterfaceconstant{vcompact}{vcompact} \setinterfaceconstant{vector}{vector} \setinterfaceconstant{veroffset}{veroffset} +\setinterfaceconstant{vfactor}{vfactor} \setinterfaceconstant{vfil}{vfil} \setinterfaceconstant{viewerprefix}{viewerprefix} \setinterfaceconstant{voffset}{voffset} diff --git a/tex/context/base/mkii/strc-reg.mkii b/tex/context/base/mkii/strc-reg.mkii index 45be82525..a8d05fb78 100644 --- a/tex/context/base/mkii/strc-reg.mkii +++ b/tex/context/base/mkii/strc-reg.mkii @@ -18,7 +18,7 @@ % new: eigennummer=ja => eerste {} ipv pag nummer \unprotect - + %D Isolated but still indocumented. % Formaat tex-utility-input-file : @@ -1176,7 +1176,7 @@ \def\defineregister {\dodoubleargument\dodefineregister} - + \def\registerlengte{\utilityregisterlength} \def\utilityregisterlength{0} diff --git a/tex/context/base/mkii/syst-rtp.mkiv b/tex/context/base/mkii/syst-rtp.mkiv deleted file mode 100644 index 82c0778b4..000000000 --- a/tex/context/base/mkii/syst-rtp.mkiv +++ /dev/null @@ -1,18 +0,0 @@ -%D \module -%D [ file=syst-rtp, -%D version=2006.10.13, -%D title=\CONTEXT\ Core Macros, -%D subtitle=Run Time Processes, -%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 - -\let\executesystemcommand\clf_execute - -\protect \endinput diff --git a/tex/context/base/mkii/unic-003.mkii b/tex/context/base/mkii/unic-003.mkii index ad7d6df6a..91512ea54 100644 --- a/tex/context/base/mkii/unic-003.mkii +++ b/tex/context/base/mkii/unic-003.mkii @@ -100,9 +100,9 @@ \strippedcsname \greekupsilondialytika \or \strippedcsname \greekomicrontonos \or \strippedcsname \greekupsilontonos \or - \strippedcsname \greekomegatonos \or % was greeek! + \strippedcsname \greekomegatonos \or \strippedcsname \unknownchar \or - \strippedcsname \unknownchar \or % beta alt + \strippedcsname \greekbetaalt \or \strippedcsname \greekthetaalt \or \strippedcsname \unknownchar \or % upsilon hook \strippedcsname \unknownchar \or diff --git a/tex/context/base/mkii/xetx-chr.mkii b/tex/context/base/mkii/xetx-chr.mkii index ca9c4aaa4..66ae0d636 100644 --- a/tex/context/base/mkii/xetx-chr.mkii +++ b/tex/context/base/mkii/xetx-chr.mkii @@ -462,6 +462,7 @@ \def\greekomicrontonos {\char"003CC } % GREEK SMALL LETTER OMICRON WITH TONOS: ό \def\greekupsilontonos {\char"003CD } % GREEK SMALL LETTER UPSILON WITH TONOS: ύ \def\greekomegatonos {\char"003CE } % GREEK SMALL LETTER OMEGA WITH TONOS: ώ +\def\greekbetaalt {\char"003D0 } % GREEK BETA SYMBOL: ϐ \def\greekthetaalt {\char"003D1 } % GREEK THETA SYMBOL: ϑ \def\greekphialt {\char"003D5 } % GREEK PHI SYMBOL: ϕ \def\greekpialt {\char"003D6 } % GREEK PI SYMBOL: ϖ diff --git a/tex/context/base/mkiv/anch-bck.mkvi b/tex/context/base/mkiv/anch-bck.mkvi index 348ea0ad1..96dd0cdf5 100644 --- a/tex/context/base/mkiv/anch-bck.mkvi +++ b/tex/context/base/mkiv/anch-bck.mkvi @@ -47,7 +47,7 @@ \unexpanded\def\anch_backgrounds_text_initialize {\doifelsepositionsused\enableparpositions\donothing - \global\let\anch_backgrounds_text_initialize\relax} + \glet\anch_backgrounds_text_initialize\relax} \appendtoks \anch_backgrounds_text_initialize @@ -352,7 +352,7 @@ {\ifproductionrun \enabletextarearegistration \enablehiddenbackground - \global\let\checkpositionoverlays\relax + \glet\checkpositionoverlays\relax \fi} % shape handling @@ -453,55 +453,55 @@ \strc_floats_mark_as_free \plustwo \zeropoint - \d_page_sides_leftskip + \d_page_sides_rightoffset \d_page_sides_topskip \d_page_sides_bottomskip \or % leftedge \strc_floats_mark_as_free \plustwo \zeropoint - \d_page_sides_leftskip + \d_page_sides_rightoffset \d_page_sides_topskip \d_page_sides_bottomskip \or % leftmargin \strc_floats_mark_as_free \plustwo \zeropoint - \d_page_sides_leftskip + \d_page_sides_rightoffset \d_page_sides_topskip \d_page_sides_bottomskip \or % leftside \strc_floats_mark_as_free \plustwo - \d_page_sides_leftskip - \d_strc_floats_margin + \d_page_sides_leftskip % maybe too + \d_page_sides_margin \d_page_sides_topskip \d_page_sides_bottomskip \or % rightside \strc_floats_mark_as_free \plusthree - \d_strc_floats_margin - \d_page_sides_rightskip + \d_page_sides_margin + \d_page_sides_rightskip % maybe too \d_page_sides_topskip \d_page_sides_bottomskip \or % rightmargin \strc_floats_mark_as_free \plusthree - \d_page_sides_rightskip + \d_page_sides_leftoffset \zeropoint \d_page_sides_topskip \d_page_sides_bottomskip \or % rightedge \strc_floats_mark_as_free \plusthree - \d_page_sides_rightskip + \d_page_sides_leftoffset \zeropoint \d_page_sides_topskip \d_page_sides_bottomskip \or % cutspace \strc_floats_mark_as_free \plusthree - \d_page_sides_rightskip + \d_page_sides_leftoffset \zeropoint \d_page_sides_topskip \d_page_sides_bottomskip diff --git a/tex/context/base/mkiv/anch-pgr.lua b/tex/context/base/mkiv/anch-pgr.lua index ca5a5a8af..14afa3967 100644 --- a/tex/context/base/mkiv/anch-pgr.lua +++ b/tex/context/base/mkiv/anch-pgr.lua @@ -56,13 +56,10 @@ graphics.backgrounds = backgrounds -- -- -- local texsetattribute = tex.setattribute -local pdfgetpos = pdf.getpos -- why not a generic name ! local a_textbackground = attributes.private("textbackground") local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode local new_latelua = nuts.pool.latelua local new_rule = nuts.pool.rule @@ -82,11 +79,12 @@ local localpar_code = nodecodes.localpar local insert_before = nuts.insert_before local insert_after = nuts.insert_after -local processranges = nodes.processranges +local processranges = nuts.processranges local unsetvalue = attributes.unsetvalue local jobpositions = job.positions +local getpos = jobpositions.getpos local data = { } local realpage = 1 @@ -96,10 +94,17 @@ local enabled = false -- Freeing the data is somewhat tricky as we can have backgrounds spanning -- many pages but for an arbitrary background shape that is not so common. -local function check(a,index,depth,d,where,ht,dp) +local function check(specification) + local a = specification.attribute + local index = specification.index + local depth = specification.depth + local d = specification.data + local where = specification.where + local ht = specification.ht + local dp = specification.dp -- this is not yet r2l ready local w = d.shapes[realpage] - local x, y = pdfgetpos() + local x, y = getpos() if trace_ranges then report_shapes("attribute %i, index %i, depth %i, location %s, position (%p,%p)", a,index,depth,where,x,y) @@ -109,7 +114,7 @@ local function check(a,index,depth,d,where,ht,dp) n = n + 1 d.index = index d.depth = depth --- w[n] = { x, x, y, ht, dp } + -- w[n] = { x, x, y, ht, dp } w[n] = { y, ht, dp, x, x } else local wn = w[n] @@ -150,13 +155,13 @@ local function flush(head,f,l,a,parent,depth) local ix = index local ht = getheight(parent) local dp = getdepth(parent) - local ln = new_latelua(function() check(a,ix,depth,d,"l",ht,dp) end) - local rn = new_latelua(function() check(a,ix,depth,d,"r",ht,dp) end) + local ln = new_latelua { action = check, attribute = a, index = ix, depth = depth, data = d, where = "l", ht = ht, dp = dp } + local rn = new_latelua { action = check, attribute = a, index = ix, depth = depth, data = d, where = "r", ht = ht, dp = dp } if trace_ranges then ln = new_hlist(setlink(new_rule(65536,65536*4,0),new_kern(-65536),ln)) rn = new_hlist(setlink(new_rule(65536,0,65536*4),new_kern(-65536),rn)) end - if getid(f) == localpar_code then -- we need to clean this mess + if getid(f) == localpar_code and getsubtype(f) == 0 then -- we need to clean this mess insert_after(head,f,ln) else head, f = insert_before(head,f,ln) @@ -213,10 +218,8 @@ end nodes.handlers.textbackgrounds = function(head,where,parent) -- we have hlistdir and local dir -- todo enable action in register - head = tonut(head) index = index + 1 - local head, done = processranges(a_textbackground,flush,head,parent) - return tonode(head), done + return processranges(a_textbackground,flush,head,parent) end interfaces.implement { @@ -228,6 +231,8 @@ interfaces.implement { -- optimized already but we can assume a cycle i.e. prune the last point and then -- even less code .. we could merge some loops but his is more robust +-- use idiv here + local function topairs(t,n) local r = { } for i=1,n do @@ -237,7 +242,7 @@ local function topairs(t,n) return concat(r," ") end -local eps = 65536 / 4 -- 2 +local eps = 65536 / 4 local pps = eps local nps = - pps @@ -509,7 +514,8 @@ local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) -- use height of b and depth of e, maybe check for weird border -- cases here if fh then - local lsf, rsf = ls[1], rs[1] + local lsf = ls[1] + local rsf = rs[1] if lsf[2] < fh then lsf[2] = fh end @@ -518,7 +524,8 @@ local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) end end if fd then - local lsl, rsl = ls[n], rs[n] + local lsl = ls[n] + local rsl = rs[n] if lsl[2] > fd then lsl[2] = fd end @@ -535,12 +542,18 @@ local function shape(kind,b,p,realpage,xmin,xmax,ymin,ymax,fh,ld) end local function singlepart(b,e,p,realpage,r,left,right) - local bx, by = b.x, b.y - local ex, ey = e.x, e.y - local rx, ry = r.x, r.y - local bh, bd = by + b.h, by - b.d - local eh, ed = ey + e.h, ey - e.d - local rh, rd = ry + r.h, ry - r.d + local bx = b.x + local by = b.y + local ex = e.x + local ey = e.y + local rx = r.x + local ry = r.y + local bh = by + b.h + local bd = by - b.d + local eh = ey + e.h + local ed = ey - e.d + local rh = ry + r.h + local rd = ry - r.d local rw = rx + r.w if left then rx = rx + left @@ -593,10 +606,14 @@ local function singlepart(b,e,p,realpage,r,left,right) end local function firstpart(b,e,p,realpage,r,left,right) - local bx, by = b.x, b.y - local rx, ry = r.x, r.y - local bh, bd = by + b.h, by - b.d - local rh, rd = ry + r.h, ry - r.d + local bx = b.x + local by = b.y + local rx = r.x + local ry = r.y + local bh = by + b.h + local bd = by - b.d + local rh = ry + r.h + local rd = ry - r.d local rw = rx + r.w if left then rx = rx + left @@ -630,8 +647,10 @@ local function firstpart(b,e,p,realpage,r,left,right) end local function middlepart(b,e,p,realpage,r,left,right) - local rx, ry = r.x, r.y - local rh, rd = ry + r.h, ry - r.d + local rx = r.x + local ry = r.y + local rh = ry + r.h + local rd = ry - r.d local rw = rx + r.w if left then rx = rx + left @@ -654,10 +673,14 @@ local function middlepart(b,e,p,realpage,r,left,right) end local function lastpart(b,e,p,realpage,r,left,right) - local ex, ey = e.x, e.y - local rx, ry = r.x, r.y - local eh, ed = ey + e.h, ey - e.d - local rh, rd = ry + r.h, ry - r.d + local ex = e.x + local ey = e.y + local rx = r.x + local ry = r.y + local eh = ey + e.h + local ed = ey - e.d + local rh = ry + r.h + local rd = ry - r.d local rw = rx + r.w if left then rx = rx + left @@ -740,7 +763,7 @@ local function calculatemultipar(tag) local bp = b.p -- page if trace_shapes then report_shapes("tag %a, left %p, right %p, par %s, page %s, column %s", - left,right,bn or "-",bp or "-",bc or "-") + tag,left,right,bn or "-",bp or "-",bc or "-") end -- if bindex == eindex then @@ -844,8 +867,10 @@ local function freemultipar(pagedata,frees) -- ,k local areas = { } data.areas = areas - local f_1, n_1 = { }, 0 - local f_2, n_2 = { }, 0 + local f_1 = { } + local n_1 = 0 + local f_2 = { } + local n_2 = 0 for i=1,#frees do local f = frees[i] local k = f.k @@ -908,14 +933,18 @@ local function freemultipar(pagedata,frees) -- ,k -- we can collect the coordinates first local function check_two(area,frees) - local ul = area[1] - local ur = area[2] - local lr = area[3] - local ll = area[4] - local ulx, uly = ul[1], ul[2] - local urx, ury = ur[1], ur[2] - local lrx, lry = lr[1], lr[2] - local llx, lly = ll[1], ll[2] + local ul = area[1] + local ur = area[2] + local lr = area[3] + local ll = area[4] + local ulx = ul[1] + local uly = ul[2] + local urx = ur[1] + local ury = ur[2] + local lrx = lr[1] + local lry = lr[2] + local llx = ll[1] + local lly = ll[2] local temp = { } local n = 0 @@ -1108,12 +1137,16 @@ local function fetchmultipar(n,anchor,page) report_graphics("fetching %a at page %s using anchor %a containing %s multipars", n,page,anchor,nofmultipars) end - local x, y = a.x, a.y - local w, h, d = a.w, a.h, a.d - local bpos = data.bpos - local bh, bd = bpos.h, bpos.d - local result = { false } -- slot 1 will be set later - local n = 0 + local x = a.x + local y = a.y + local w = a.w + local h = a.h + local d = a.d + local bpos = data.bpos + local bh = bpos.h + local bd = bpos.d + local result = { false } -- slot 1 will be set later + local n = 0 for i=1,nofmultipars do local data = pagedata[i] local location = data.location @@ -1178,7 +1211,8 @@ implement { if type(tags) == "string" then tags = utilities.parsers.settings_to_array(tags) end - local list, nofboxes = { }, 0 + local list = { } + local nofboxes = 0 for i=1,#tags do local tag= tags[i] local c = collected[tag] @@ -1187,7 +1221,11 @@ implement { if r then r = collected[r] if r then - local rx, ry, rw, rh, rd = r.x, r.y, r.w, r.h, r.d + local rx = r.x + local ry = r.y + local rw = r.w + local rh = r.h + local rd = r.d local cx = c.x - rx local cy = c.y local cw = cx + c.w diff --git a/tex/context/base/mkiv/anch-pgr.mkiv b/tex/context/base/mkiv/anch-pgr.mkiv index e49d18b8f..7fa378cd1 100644 --- a/tex/context/base/mkiv/anch-pgr.mkiv +++ b/tex/context/base/mkiv/anch-pgr.mkiv @@ -66,7 +66,7 @@ \def\anch_positions_action_indeed_yes % we need a way to figure out if we have actions {\begingroup - \setbox\scratchbox\hbox + \setbox\scratchbox\hbox % \hpack {\anch_positions_trace_action_yes \the\everyinsertpositionaction \the\everypositionaction @@ -130,12 +130,12 @@ \else \c_anch_page_width \paperwidth \c_anch_page_height\paperheight - \anch_make_page_box{#1}% \ifvbox#1\setbox#1\hbox{\box#1}\fi + \anch_make_page_box{#1}% \ifvbox#1\setbox#1\hpack{\box#1}\fi \fi \else \c_anch_page_width \paperwidth \c_anch_page_height\paperheight - \anch_make_page_box{#1}% \ifvbox#1\setbox#1\hbox{\box#1}\fi + \anch_make_page_box{#1}% \ifvbox#1\setbox#1\hpack{\box#1}\fi \fi \fi\fi} @@ -157,7 +157,7 @@ \endgroup} \def\anch_positions_place_anchors_nop - {\vskip\textheight} + {\vkern\textheight} %D \macros %D {positionoverlay,startpositionoverlay} @@ -243,7 +243,7 @@ \let\MPanchor\MPoverlayanchor % no need to fetch it already, seldom used \the\everyinsertpositionaction \copyposition{\currentpositionoverlay::\MPanchoridentifier}\MPanchorid - \setbox\scratchbox\hbox to \d_overlay_width + \setbox\scratchbox\hbox to \d_overlay_width % \hpack {\dopositionaction{\currentpositionoverlay::\MPanchoridentifier}\hss}% \ht\scratchbox\d_overlay_height \dp\scratchbox\zeropoint @@ -275,7 +275,7 @@ \let\MPanchor\MPoverlayanchor % no need to fetch it already, seldom used \the\everyinsertpositionaction \copyposition{\currentpositionoverlay::\MPanchoridentifier}\MPanchorid - \setbox\scratchbox\hbox to \d_overlay_width + \setbox\scratchbox\hbox to \d_overlay_width % \hpack {\dopositionaction{\currentpositionoverlay::\MPanchoridentifier}\hss}% \ht\scratchbox\d_overlay_height \dp\scratchbox\zeropoint @@ -366,7 +366,7 @@ \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 + \setbox\b_anch_positions_graphic\hbox % \hpack {\ignorespaces\csname#1#2\endcsname\removelastspace}% \smashbox\b_anch_positions_graphic \box\b_anch_positions_graphic diff --git a/tex/context/base/mkiv/anch-pos.lua b/tex/context/base/mkiv/anch-pos.lua index e5f58c36c..ade992792 100644 --- a/tex/context/base/mkiv/anch-pos.lua +++ b/tex/context/base/mkiv/anch-pos.lua @@ -20,8 +20,12 @@ more efficient.

-- this is one of the first modules using scanners and we need to replace -- it by implement and friends +-- we could have namespaces, like p, page, region, columnarea, textarea but then +-- we need virtual table accessors as well as have tag/id accessors ... we don't +-- save much here (at least not now) + local tostring, next, rawget, rawset, setmetatable, tonumber = tostring, next, rawget, rawset, setmetatable, tonumber -local sort, sortedhash, sortedkeys = table.sort, table.sortedhash, table.sortedkeys +local sort = table.sort local format, gmatch = string.format, string.gmatch local rawget = rawget local lpegmatch = lpeg.match @@ -40,7 +44,8 @@ local scanners = interfaces.scanners local commands = commands local context = context -local ctxnode = context.nodes.flush + +local ctx_latelua = context.latelua local tex = tex local texgetcount = tex.getcount @@ -63,12 +68,12 @@ local getbox = nuts.getbox local getid = nuts.getid local getwhd = nuts.getwhd ------ hlist_code = nodes.listcodes.hlist +local hlist_code = nodes.nodecodes.hlist local find_tail = nuts.tail +local hpack = nuts.hpack local new_latelua = nuts.pool.latelua -local new_latelua_node = nodes.pool.latelua local variables = interfaces.variables local v_text = variables.text @@ -236,7 +241,6 @@ end -- t[#t+1] = data -- end -- --- -- -- local pages = structures.pages.collected -- if pages then -- local last = nil @@ -326,9 +330,19 @@ local nofpages = nil -- beware ... we're not sparse here as lua will reserve slots for the nilled -local getpos = function() getpos = backends.codeinjections.getpos return getpos () end -local gethpos = function() gethpos = backends.codeinjections.gethpos return gethpos() end -local getvpos = function() getvpos = backends.codeinjections.getvpos return getvpos() end +local getpos, gethpos, getvpos + +function jobpositions.registerhandlers(t) + getpos = t and t.getpos or function() return 0, 0 end + gethpos = t and t.gethpos or function() return 0 end + getvpos = t and t.getvpos or function() return 0 end +end + +function jobpositions.getpos () return getpos () end +function jobpositions.gethpos() return gethpos() end +function jobpositions.getvpos() return getvpos() end + +jobpositions.registerhandlers() local function setall(name,p,x,y,w,h,d,extra) tobesaved[name] = { @@ -386,9 +400,28 @@ end -- analyze some files (with lots if margindata) and then when one key optionally -- use that one instead of a table (so, a 3rd / 4th argument: key, e.g. "x") -local function set(name,index,val) -- ,key - local data = enhance(val or index) - if val then +local function set(name,index,value) -- ,key + local data = enhance(value or index) + if value then + container = tobesaved[name] + if not container then + tobesaved[name] = { + [index] = data + } + else + container[index] = data + end + else + tobesaved[name] = data + end +end + +local function setspec(specification) + local name = specification.name + local index = specification.index + local value = specification.value + local data = enhance(value or index) + if value then container = tobesaved[name] if not container then tobesaved[name] = { @@ -411,16 +444,11 @@ local function get(id,index) end end -------------.setdim = setdim -jobpositions.setall = setall -jobpositions.set = set -jobpositions.get = get - --- scanners.setpos = setall - --- trackers.enable("tokens.compi*") - --- something weird: the compiler fails us here +------------.setdim = setdim +jobpositions.setall = setall +jobpositions.set = set +jobpositions.setspec = setspec +jobpositions.get = get scanners.dosaveposition = compilescanner { actions = setall, -- name p x y @@ -442,7 +470,8 @@ scanners.dosavepositionplus = compilescanner { -- not much gain in keeping stack (inc/dec instead of insert/remove) -local function b_column(tag) +local function b_column(specification) + local tag = specification.tag local x = gethpos() tobesaved[tag] = { r = true, @@ -453,7 +482,7 @@ local function b_column(tag) column = tag end -local function e_column(tag) +local function e_column() local t = tobesaved[column] if not t then -- something's wrong @@ -479,7 +508,7 @@ scanners.bposcolumnregistered = function() -- tag local tag = scanstring() insert(columns,tag) column = tag - ctxnode(new_latelua_node(function() b_column(tag) end)) + ctx_latelua { action = b_column, tag = tag } end scanners.eposcolumn = function() @@ -488,38 +517,42 @@ scanners.eposcolumn = function() end scanners.eposcolumnregistered = function() - ctxnode(new_latelua_node(e_column)) + ctx_latelua { action = e_column } remove(columns) column = columns[#columns] end -- regions -local function b_region(tag) +local function b_region(specification) + local tag = specification.tag or specification local last = tobesaved[tag] local x, y = getpos() last.x = x ~= 0 and x or nil last.y = y ~= 0 and y or nil last.p = texgetcount("realpageno") - insert(regions,tag) + insert(regions,tag) -- todo: fast stack region = tag end -local function e_region(correct) +local function e_region(specification) local last = tobesaved[region] local y = getvpos() - if correct then + local x, y = getpos() + if specification.correct then local h = (last.y or 0) - y last.h = h ~= 0 and h or nil end last.y = y ~= 0 and y or nil - remove(regions) + remove(regions) -- todo: fast stack region = regions[#regions] end jobpositions.b_region = b_region jobpositions.e_region = e_region +local lastregion + local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind if not tag or tag == "" then nofregions = nofregions + 1 @@ -527,34 +560,34 @@ local function setregionbox(n,tag,k,lo,ro,to,bo) -- kind end local box = getbox(n) local w, h, d = getwhd(box) - local x, y = getpos() -- hm, makes no sense here tobesaved[tag] = { - -- p = texgetcount("realpageno"), -- we copy them - x = x ~= 0 and x or nil, -- was true - y = y ~= 0 and y or nil, - w = w ~= 0 and w or nil, - h = h ~= 0 and h or nil, - d = d ~= 0 and d or nil, - k = k ~= 0 and k or nil, + -- p = texgetcount("realpageno"), -- we copy them + x = 0, + y = 0, + w = w ~= 0 and w or nil, + h = h ~= 0 and h or nil, + d = d ~= 0 and d or nil, + k = k ~= 0 and k or nil, lo = lo ~= 0 and lo or nil, ro = ro ~= 0 and ro or nil, to = to ~= 0 and to or nil, bo = bo ~= 0 and bo or nil, } + lastregion = tag return tag, box end local function markregionbox(n,tag,correct,...) -- correct needs checking local tag, box = setregionbox(n,tag,...) -- todo: check if tostring is needed with formatter - local push = new_latelua(function() b_region(tag) end) - local pop = new_latelua(function() e_region(correct) end) + local push = new_latelua { action = b_region, tag = tag } + local pop = new_latelua { action = e_region, correct = correct } -- maybe we should construct a hbox first (needs experimenting) so that we can avoid some at the tex end local head = getlist(box) - -- no : + -- no, this fails with \framed[region=...] .. needs thinking -- if getid(box) ~= hlist_code then -- -- report("mark region box assumes a hlist, fix this for %a",tag) - -- head = nuts.hpack(head) + -- head = hpack(head) -- end if head then local tail = find_tail(head) @@ -584,7 +617,7 @@ end local nofparagraphs = 0 -scanners.parpos = function() -- todo: relate to localpar (so this is an intermediate variant) +scanners.parpos = function() nofparagraphs = nofparagraphs + 1 texsetcount("global","c_anch_positions_paragraph",nofparagraphs) local box = getbox("strutbox") @@ -623,14 +656,14 @@ scanners.parpos = function() -- todo: relate to localpar (so this is an intermed if parshape and #parshape > 0 then t.ps = parshape end - local tag = f_p_tag(nofparagraphs) - tobesaved[tag] = t - ctxnode(new_latelua_node(function() enhance(tobesaved[tag]) end)) + local name = f_p_tag(nofparagraphs) + tobesaved[name] = t + ctx_latelua { action = enhance, specification = t } end scanners.dosetposition = function() -- name local name = scanstring() - tobesaved[name] = { + local spec = { p = true, c = column, r = true, @@ -639,15 +672,15 @@ scanners.dosetposition = function() -- name n = nofparagraphs > 0 and nofparagraphs or nil, r2l = texgetcount("inlinelefttoright") == 1 or nil, } - ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctx_latelua { action = enhance, specification = spec } end scanners.dosetpositionwhd = function() -- name w h d extra local name = scanstring() - local w = scandimen() - local h = scandimen() - local d = scandimen() - tobesaved[name] = { + local w = scandimen() + local h = scandimen() + local d = scandimen() + local spec = { p = true, c = column, r = true, @@ -659,14 +692,14 @@ scanners.dosetpositionwhd = function() -- name w h d extra n = nofparagraphs > 0 and nofparagraphs or nil, r2l = texgetcount("inlinelefttoright") == 1 or nil, } - ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctx_latelua { action = enhance, specification = spec } end scanners.dosetpositionbox = function() -- name box local name = scanstring() local box = getbox(scaninteger()) local w, h, d = getwhd(box) - tobesaved[name] = { + local spec = { p = true, c = column, r = true, @@ -678,15 +711,15 @@ scanners.dosetpositionbox = function() -- name box n = nofparagraphs > 0 and nofparagraphs or nil, r2l = texgetcount("inlinelefttoright") == 1 or nil, } - ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctx_latelua { action = enhance, specification = spec } end scanners.dosetpositionplus = function() -- name w h d extra local name = scanstring() - local w = scandimen() - local h = scandimen() - local d = scandimen() - tobesaved[name] = { + local w = scandimen() + local h = scandimen() + local d = scandimen() + local spec = { p = true, c = column, r = true, @@ -699,14 +732,14 @@ scanners.dosetpositionplus = function() -- name w h d extra e = scanstring(), r2l = texgetcount("inlinelefttoright") == 1 or nil, } - ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctx_latelua { action = enhance, specification = spec } end scanners.dosetpositionstrut = function() -- name local name = scanstring() local box = getbox("strutbox") local w, h, d = getwhd(box) - tobesaved[name] = { + local spec = { p = true, c = column, r = true, @@ -717,7 +750,7 @@ scanners.dosetpositionstrut = function() -- name n = nofparagraphs > 0 and nofparagraphs or nil, r2l = texgetcount("inlinelefttoright") == 1 or nil, } - ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctx_latelua { action = enhance, specification = spec } end scanners.dosetpositionstrutkind = function() -- name @@ -725,7 +758,7 @@ scanners.dosetpositionstrutkind = function() -- name local kind = scaninteger() local box = getbox("strutbox") local w, h, d = getwhd(box) - tobesaved[name] = { + local spec = { k = kind, p = true, c = column, @@ -737,7 +770,7 @@ scanners.dosetpositionstrutkind = function() -- name n = nofparagraphs > 0 and nofparagraphs or nil, r2l = texgetcount("inlinelefttoright") == 1 or nil, } - ctxnode(new_latelua_node(function() enhance(tobesaved[name]) end)) + ctx_latelua { action = enhance, specification = spec } end function jobpositions.getreserved(tag,n) @@ -1377,6 +1410,11 @@ scanners.markregionboxtaggedkind = function() -- box tag kind scaninteger(),scandimen(),scandimen(),scandimen(),scandimen()) end +scanners.reservedautoregiontag = function() + nofregions = nofregions + 1 + context(f_region(nofregions)) +end + -- statistics (at least for the moment, when testing) -- statistics.register("positions", function() diff --git a/tex/context/base/mkiv/anch-pos.mkiv b/tex/context/base/mkiv/anch-pos.mkiv index ab199eb1e..fbebb5f17 100644 --- a/tex/context/base/mkiv/anch-pos.mkiv +++ b/tex/context/base/mkiv/anch-pos.mkiv @@ -155,7 +155,7 @@ \def\anch_positions_set_data_indeed#1#2#3#4% {\anch_positions_initialize - \hbox + \hbox % \hpack {\edef\currentposition{#1}% \dosetpositionwhd\currentposition{#2}{#3}{#4}% already \the\dimexpr \anch_positions_trace_left @@ -177,7 +177,7 @@ \def\anch_positions_set_box_finish#1% {\anch_positions_initialize - \hbox to \wd\nextbox + \hbox to \wd\nextbox % \hpack {\edef\currentposition{#1}% \dosetpositionbox\currentposition\nextbox \anch_positions_trace_left @@ -198,7 +198,7 @@ \def\anch_positions_set_strut_yes#1% {\anch_positions_initialize - \hbox to \zeropoint + \hbox to \zeropoint % \hpack {\edef\currentposition{#1}% \dosetpositionstrut\currentposition \anch_positions_trace_left @@ -215,7 +215,7 @@ \def\anch_positions_set_strut_kind_yes#1#2% {\anch_positions_initialize - \hbox to \zeropoint + \hbox to \zeropoint % \hpack {\edef\currentposition{#1}% \dosetpositionstrutkind\currentposition{#2}% \anch_positions_trace_left @@ -235,7 +235,7 @@ \def\anch_positions_set_plus_indeed#1#2#3#4#5% {\anch_positions_initialize - \hbox % just package + \hbox % \hpack {\edef\currentposition{#1}% \dosetpositionplus\currentposition{#2}{#3}{#4}{#5}% already \the\dimexpr \anch_positions_trace_right @@ -257,7 +257,7 @@ \def\anch_positions_set_plus_yes_finish#1#2% {\anch_positions_initialize - \hbox to \nextboxwd + \hbox to \nextboxwd % \hpack {\edef\currentposition{#1}% \dosetpositionplus\currentposition{\wd\nextbox}{\ht\nextbox}{\dp\nextbox}{#2}% \anch_positions_trace_right @@ -296,7 +296,7 @@ {\clf_markregionbox#1\relax} \unexpanded\def\anch_mark_flow_box#1% will be extended / renamed - {\hbox\bgroup + {\hpack\bgroup % \hpack \global\advance\c_anch_text\plusone \clf_markregionboxtagged#1{textarea:\the\c_anch_text}% \box#1% @@ -330,6 +330,8 @@ #6\relax % bottomoffset \fi} +\def\reservedautoregiontag{\clf_reservedautoregiontag} + %D We can copy a position with: %D %D \starttyping @@ -393,7 +395,7 @@ {\the\t_anch_positions_tracers} \unexpanded\def\enableparpositions % global - {\global\let\registerparoptions\doregisterparoptions + {\glet\registerparoptions\doregisterparoptions \global\positioningtrue} \let\disableparpositions\relax diff --git a/tex/context/base/mkiv/anch-snc.lua b/tex/context/base/mkiv/anch-snc.lua new file mode 100644 index 000000000..8006f3bd6 --- /dev/null +++ b/tex/context/base/mkiv/anch-snc.lua @@ -0,0 +1,271 @@ +if not modules then modules = { } end modules ['anch-snc'] = { + version = 1.001, + comment = "companion to anch-snc.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + + +function mp.xxOverlayRegion() + local r = tokens.getters.macro("m_overlay_region") + mp.quoted('"'.. r .. '"') +-- mp.print('"'.. r .. '"') +end + +-- use factors as in mlib-int.lua + +local tonumber, next, setmetatable = tonumber, next, setmetatable +local concat, sort, remove, copy = table.concat, table.sort, table.remove, table.copy +local match, find = string.match, string.find +local lpegmatch = lpeg.match + +local setmetatableindex = table.setmetatableindex + +local factor = number.dimenfactors.bp +local mpprint = mp.print +local mpnumeric = mp.numeric +local mppoints = mp.points +local texgetdimen = tex.getdimen + +local p_number = lpeg.patterns.cardinal/tonumber +local p_space = lpeg.patterns.whitespace^0 +local p_tag = lpeg.P("syncpos:") * p_number * lpeg.P(":") * p_number +local p_option = p_number -- for now + * ((lpeg.P(",") * p_space * lpeg.P("reset") * lpeg.Cc(true)) + lpeg.Cc(false)) + +local list = { } +local colors = setmetatableindex("table") + +local kinds = { + above = 1, + continue = 2, + nothing = 3, + normal = 4, + below = 5, +} + +local allentries = setmetatableindex(function(t,category) + setmetatable(t,nil) + for tag, pos in next, job.positions.collected do + local c, n = lpegmatch(p_tag,tag) + if c then + local tc = t[c] + if tc then + tc[n] = pos + else + t[c] = { [n] = pos } + end + end + end + for k, list in next, t do + sort(list,function(a,b) + local ap = a.p + local bp = b.p + if ap == bp then + return b.y < a.y + else + return ap < bp + end + end) + list.start = 1 + end + setmetatableindex(t,"table") + return t[category] +end) + +local lastdone = { } + +function mp.sync_collect(category,realpage,useregion) + local all = allentries[category] + local m = 0 + local n = #all + list = { } + if useregion then + -- successive can be optimized when we sort by region + local start = 1 + local done = false + local last, rtop, rbot + for i=start,n do + local pos = all[i] + local p = pos.p + local r = pos.r + if r == useregion then + if not done then + local region = job.positions.collected[r] + list.region = region + list.page = region + rtop = (region.y or 0) + (region.h or 0) + rbot = (region.y or 0) - (region.d or 0) + last = { kind = "nothing", top = rtop, bottom = 0, task = 0 } + m = m + 1 ; list[m] = last + done = true + end + local top = pos.y + pos.h + last.bottom = top + local task, reset = lpegmatch(p_option,pos.e) + last = { kind = "normal", top = top, bottom = 0, task = task } + m = m + 1 ; list[m] = last + end + end + if done then + last.bottom = rbot + end + else + local start = all.start or 1 + local done = false + local last, rtop, rbot, ptop, pbot + for i=start,n do + local pos = all[i] + local p = pos.p + if p == realpage then + if not done then + local region = job.positions.collected[pos.r] + local page = job.positions.collected["page:"..realpage] or region + list.region = region + list.page = page + rtop = (region.y or 0) + (region.h or 0) + rbot = (region.y or 0) - (region.d or 0) + ptop = (page .y or 0) + (page .h or 0) + pbot = (page .y or 0) - (page .d or 0) + last = { kind = "above", top = ptop, bottom = rtop, task = 0 } + m = m + 1 ; list[m] = last + if i > 1 then + local task, reset = lpegmatch(p_option,all[i-1].e) + last = { kind = "continue", top = rtop, bottom = 0, task = task } + m = m + 1 ; list[m] = last + else + last = { kind = "nothing", top = rtop, bottom = 0, task = 0 } + m = m + 1 ; list[m] = last + end + done = true + end + local top = pos.y + pos.h + last.bottom = top + local task, reset = lpegmatch(p_option,pos.e) + if reset then + local l = list[2] + l.kind = "nothing" + l.task = 0 + end + last = { kind = "normal", top = top, bottom = 0, task = task } + m = m + 1 ; list[m] = last + elseif p > realpage then + all.start = i -- tricky, only for page + break + end + end + if done then + last.bottom = rbot + last = { kind = "below", top = rbot, bottom = pbot, task = 0 } + m = m + 1 ; list[m] = last + lastdone[category] = { + { kind = "above", top = ptop, bottom = rtop, task = 0 }, + { kind = "continue", top = rtop, bottom = rbot, task = list[#list-1].task }, -- lasttask + { kind = "below", top = rbot, bottom = pbot, task = 0 }, + region = list.region, + page = list.page, + } + else + local l = lastdone[category] + if l then + list = copy(l) -- inefficient, mayb emetatable for region/page + m = 3 + end + end + end + mpnumeric(m) +end + +function mp.sync_extend() + local n = #list + if n > 0 then + for i=1,n do + local l = list[i] + local k = l.kind + if k == "nothing" then + local ll = list[i+1] + if ll and ll.kind == "normal" then + ll.top = l.top + remove(list,i) + n = #list + break + end + end + end + end + mpnumeric(n) +end + +function mp.sync_prune() + local n = #list + if n > 0 then + if list[1].kind == "above" then + remove(list,1) + end + if list[1].kind == "nothing" then + remove(list,1) + end + if list[#list].kind == "below" then + remove(list,#list) + end + n = #list + end + mpnumeric(n) +end + +function mp.sync_collapse() + local n = #list + if n > 0 then + local m = 0 + local p = nil + for i=1,n do + local l = list[i] + local t = l.task + if p == t then + list[m].bottom = l.bottom + else + m = m + 1 + list[m] = l + end + p = t + end + for i=n,m+1,-1 do + list[i] = nil + end + n = m + end + mpnumeric(n) +end + +function mp.sync_set_color(category,n,v) + colors[category][n] = v +end + +function mp.sync_get_color(category,n) + mpprint(colors[category][n]) +end + +-- function mp.sync_get_size () mpnumeric(#list) end +-- function mp.sync_get_top (n) mppoints (list[n].top) end +-- function mp.sync_get_bottom(n) mppoints (list[n].bottom) end +-- function mp.sync_get_kind (n) mpnumeric(kinds[list[n].kind]) end +-- function mp.sync_get_task (n) mpnumeric(list[n].task) end + +-- function mp.sync_get_x() mppoints(list.page.x or 0) end +-- function mp.sync_get_y() mppoints(list.page.y or 0) end +-- function mp.sync_get_w() mppoints(list.page.w or 0) end +-- function mp.sync_get_h() mppoints(list.page.h or 0) end +-- function mp.sync_get_d() mppoints(list.page.d or 0) end + +function mp.sync_get_size () mpnumeric(#list) end +function mp.sync_get_top (n) mpnumeric(list[n].top * factor) end +function mp.sync_get_bottom(n) mpnumeric(list[n].bottom * factor) end +function mp.sync_get_kind (n) mpnumeric(kinds[list[n].kind]) end +function mp.sync_get_task (n) mpnumeric(list[n].task) end + +function mp.sync_get_x() mpnumeric((list.page.x or 0)*factor) end +function mp.sync_get_y() mpnumeric((list.page.y or 0)*factor) end +function mp.sync_get_w() mpnumeric((list.page.w or 0)*factor) end +function mp.sync_get_h() mpnumeric((list.page.h or 0)*factor) end +function mp.sync_get_d() mpnumeric((list.page.d or 0)*factor) end diff --git a/tex/context/base/mkiv/anch-snc.mkiv b/tex/context/base/mkiv/anch-snc.mkiv index 3e99da8a6..5f0246155 100644 --- a/tex/context/base/mkiv/anch-snc.mkiv +++ b/tex/context/base/mkiv/anch-snc.mkiv @@ -1,6 +1,6 @@ %D \module %D [ file=anch-snc, -%D version=2003.12.01, +%D version=2003.12.01, % actually 1999 so real old %D title=\CONTEXT\ Anchoring Macros, %D subtitle=Synchronization, %D author=Hans Hagen, @@ -11,151 +11,42 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -% this can be optimized (will do when used again) +%D The original is in the mkii file. It does more at the \TEX\ end and +%D has some more magic. If we really need that I'll add it. After all, +%D in mkiv we can do things different. + +%D TODO: bleed : + left , minus right oro check if it touches page ... autobleed \writestatus{loading}{ConTeXt Anchoring Macros / Synchronization} +\registerctxluafile{anch-snc}{} + \unprotect -\ifx\s!num \undefined \def\s!num {num} \fi -\ifx\s!set \undefined \def\s!set {set} \fi -\ifx\s!reset \undefined \def\s!reset {reset} \fi -\ifx\s!preset \undefined \def\s!preset {preset} \fi -\ifx\s!syncpos\undefined \def\s!syncpos{syncpos} \fi +\ifx\??syncposcounter\undefined \installcorenamespace{syncposcounter} \fi +\ifx\s!syncpos \undefined \def\s!syncpos {syncpos} \fi + +\let\c_sync_n\relax \unexpanded\def\definesyncpositions[#1]% - {\ifcsname\s!num:\s!syncpos:#1\endcsname \else - \global\let\flushsyncpositions\doflushsyncpositions % only when used - \global\let\flushsyncresets \doflushsyncresets - \global\let\flushsyncpresets \doflushsyncpresets - \expandafter\newcount\csname\s!num:\s!syncpos:#1\endcsname - \doglobal\appendtoksonce\csname\s!reset :\s!syncpos:#1\endcsname\to\resetsyncpositions - \doglobal\appendtoksonce\csname\s!preset:\s!syncpos:#1\endcsname\to\presetsyncpositions -% to be tested: -% \doglobal\expandafter\appendtoksonce\csname\s!reset :\s!syncpos:#1\endcsname\to\resetsyncpositions -% \doglobal\expandafter\appendtoksonce\csname\s!preset:\s!syncpos:#1\endcsname\to\presetsyncpositions - \setgvalue{\s!syncpos:#1}{sync_n[#1] := 0 ;}% - \setgvalue{\s!set:\s!syncpos:#1}{\dosetsyncpositions{#1}}% + {\ifcsname\??syncposcounter:#1\endcsname \else + \expandafter\newcount\csname\??syncposcounter:#1\endcsname \fi} -\def\syncposition - {\dodoubleempty\dosyncposition} - -\def\dosyncposition[#1][#2]% - {\letgvalue{\s!reset :\s!syncpos:#1}\relax - \letgvalue{\s!preset:\s!syncpos:#1}\relax - \dontleavehmode - \dodosyncposition{#1}{#2}\s!set - \ignorespaces} - -\def\doifelselastsyncposition#1#2% - {\doifelse{\lastsyncclass\lastsyncposition}{#1#2}} - -\let\doiflastsyncpositionelse\doifelselastsyncposition +\unexpanded\def\syncposition + {\dodoubleempty\anch_sync_position} -\def\dodosyncposition#1#2#3% - {\letgvalue{\s!reset:\s!syncpos:#1}\relax - \letgvalue{\s!preset:\s!syncpos:#1}\relax - \ifcsname\s!syncpos:#1\endcsname - \global\advance\csname\s!num:\s!syncpos:#1\endcsname\plusone - \setsyncpositions{#1}% - % option: geen w/h, alleen p 0 0 0 data - \setpositionplus{\s!syncpos:#1:\the\csname\s!num:\s!syncpos:#1\endcsname}{#2}\hpack{\strut}% +\def\anch_sync_position[#1][#2]% we could actually use par positions + {\dontleavehmode + \ifcsname\??syncposcounter:#1\endcsname + \let\c_sync_n\lastnamedcs + \global\advance\c_sync_n\plusone + \enabletextarearegistration + \setpositionplus{\s!syncpos:#1:\the\c_sync_n}{#2}\hpack{\strut}% \else \strut - \fi} - -\def\setsyncpositions#1% - {\enabletextarearegistration - \getvalue {\s!set:\s!syncpos:#1}% - \letgvalue{\s!set:\s!syncpos:#1}\relax} - -\def\dosetsyncpositions#1% - {\startnointerference % removing out of sync can best be done in mp - \!!dimena\maxdimen - \!!counta\zerocount - \!!countc\zerocount - \doloop - {\doifelseposition{\s!syncpos:#1:\recurselevel} - {\!!dimenb\MPy{\s!syncpos:#1:\recurselevel}\relax - \!!countb\MPp{\s!syncpos:#1:\recurselevel}\relax - \ifnum\!!countb=\!!counta % same page - \ifdim\!!dimenb>\!!dimena - \donefalse % out of order nodes - \else - \donetrue % nodes in order - \fi - \else - \donetrue % different page - \fi - \ifdone - \!!counta\!!countb - \!!dimena\!!dimenb - \advance\!!countc\plusone - \edef\!!stringa{[#1][\the\!!countc]:=}% - \edef\!!stringc{\s!syncpos:#1:\the\!!countc}% - \edef\!!stringd{\MPplus\!!stringc{1}{0}}% - \setxvalue{\s!syncpos:#1}% - {\getsyncpositions{#1}% - sync_p \!!stringa \MPp \!!stringc ; - sync_xy\!!stringa \MPxy\!!stringc ; - sync_w \!!stringa \MPw \!!stringc ; - sync_h \!!stringa \MPh \!!stringc ; - sync_d \!!stringa \MPd \!!stringc ; - \ifx\!!stringd\empty \else sync_t \!!stringa \MPplus\!!stringc{1}{0} ; \fi}% - \fi} - {\setxvalue{\s!syncpos:#1}% - {\getsyncpositions{#1}% - sync_n[#1] := \the\!!countc ;} - \exitloop}}% - \stopnointerference} - -\def\getsyncpositions#1% - {\getvalue{\s!syncpos:#1}} - -\newtoks\resetsyncpositions -\newtoks\presetsyncpositions - -\def\resyncposition {\dodoubleargument\doresyncposition} -\def\presyncposition{\dodoubleargument\dopresyncposition} - -\def\dodoresyncposition #1#2{\dodosyncposition{#1}{#2}\s!reset} -\def\dodopresyncposition#1#2{\dodosyncposition{#1}{#2}\s!preset} - -\def\doresyncposition [#1][#2]{\setxvalue{\s!reset :\s!syncpos:#1}{\noexpand\dodoresyncposition{#1}{#2}}} -\def\dopresyncposition[#1][#2]{\setxvalue{\s!preset:\s!syncpos:#1}{\noexpand\dodopresyncposition{#1}{#2}}} - -\let\flushsyncpositions\relax - -\def\doflushsyncpositions % this order ! - {\begingroup - \the\presetsyncpositions - \the\resetsyncpositions - \endgroup} - -\def\flushsyncxxsets#1% - {\begingroup - \setbox\scratchbox\hbox{\the#1}% - \ifvoid\scratchbox\else - \prewordbreak - %\let\prewordbreak\relax % only once - \smashbox\scratchbox - \box\scratchbox \fi - \endgroup} - -\let\flushsyncresets \relax -\let\flushsyncpresets\relax - -\def\doflushsyncresets {\flushsyncxxsets\resetsyncpositions } -\def\doflushsyncpresets{\flushsyncxxsets\presetsyncpositions} - -% \appendtoks \flushsyncpositions \to \everypar -% \appendtoks \flushsyncpositions \to \everyheadstart - -% \explicitneverypar -> in grid snapper, eerst testen -% -% \appendtoks \flushsyncpositions \to \neverypar + \ignorespaces} \protect @@ -163,41 +54,106 @@ \starttext +% \setuppapersize[A4][A3] + +\setuplayout[location=middle] + \setupbodyfont[dejavu] \definesyncpositions[1] +\definesyncpositions[2] + +% \enabletrackers[metapost.lua] + +\startMPdefinitions + input "mp-asnc.mpiv" ; + + SetSyncColor(1,0,"magenta") ; + SetSyncColor(1,1,"red") ; + SetSyncColor(1,2,"green") ; + SetSyncColor(1,3,"blue") ; + SetSyncColor(1,4,"yellow") ; + + SetSyncColor(2,0,"magenta") ; + SetSyncColor(2,1,"red") ; + SetSyncColor(2,2,"green") ; + SetSyncColor(2,3,"blue") ; + SetSyncColor(2,4,"yellow") ; +\stopMPdefinitions + +\startuseMPgraphic{sync1} + StartPage ; + StartSync(1) ; + SyncHOffset := 0 ; + SyncWidth := BackSpace - LeftMarginDistance; + CollectSyncDataPage ; + % ExtendSyncPaths ; % to top of text area + PruneSyncPaths ; % clip top / bottom + CollapseSyncPaths ; + MakeSyncPaths ; + % DrawSyncPaths ; + FillSyncPaths ; + StopSync ; + clip currentpicture to Page ; + setbounds currentpicture to Page ; + StopPage ; +\stopuseMPgraphic -\startuseMPgraphic{sync} - StartPage ; - \getsyncpositions{1} ; - SyncThreshold := 2LineHeight ; - SyncLeftOffset := -.5LeftMarginDistance ; - % SetSyncThreshold(1,3,3LineHeight) ; - SyncWidth := - (BackSpace + SyncLeftOffset) ; - SetSyncColor(1,1,\MPcolor{red}) ; - SetSyncColor(1,2,\MPcolor{green}) ; - SetSyncColor(1,3,\MPcolor{blue}) ; - SetSyncColor(1,4,\MPcolor{yellow}) ; - PrepareSyncTasks(1,true,true,false) ; - for i = 1 upto NOfSyncPaths : - fill SyncPaths[i] - withcolor TheSyncColor(CurrentSyncClass,sync_t[CurrentSyncClass][SyncTasks[i]]) ; - endfor ; - setbounds currentpicture to Page ; - StopPage ; +\startuseMPgraphic{sync2} + StartSync(2) ; + SyncHOffset := -1cm ; + SyncWidth := 1cm ; + CollectSyncDataRegion(OverlayRegion) ; + ExtendSyncPaths ; % to top of text area + MakeSyncPaths ; + FillSyncPaths ; + StopSync ; + clip currentpicture to OverlayBox leftenlarged 1cm; + setbounds currentpicture to OverlayBox ; \stopuseMPgraphic -\defineoverlay[tempoverlay][\useMPgraphic{sync}] +\defineoverlay[tempoverlay1][\useMPgraphic{sync1}] +\defineoverlay[tempoverlay2][\useMPgraphic{sync2}] + +\setupbackgrounds[page][background=tempoverlay1] + +\framed[region=yes,background=tempoverlay2,width=14cm,align=normal]{ + \syncposition[2][1]\samplefile{ward}\endgraf + \syncposition[2][2]\samplefile{ward}\endgraf + \syncposition[2][3]\samplefile{ward}\endgraf +} + + +\vskip1cm \hskip1cm \framed[region=yes,background=tempoverlay2,width=16cm,align=normal]{ + \syncposition[2][1]\samplefile{ward}\endgraf + \syncposition[2][2]\samplefile{ward}\endgraf + \syncposition[2][3]\samplefile{ward}\endgraf +} + +\vskip1cm \hskip1cm \framed[region=yes,background=tempoverlay2,width=10cm,align=normal]{ + \syncposition[2][1]\samplefile{ward}\endgraf + \syncposition[2][2]\samplefile{ward}\endgraf + \syncposition[2][3]\samplefile{ward}\endgraf +} -\setupbackgrounds[page][background=tempoverlay] -\dorecurse {10} { +\dorecurse {100} { +% \dorecurse {1} { + \startchapter[title={Test #1}] + \syncposition[1][1,reset]\dorecurse{20}{\samplefile{ward}\endgraf} + \syncposition[1][2]\dorecurse {4}{\samplefile{ward}\endgraf} + \syncposition[1][3]\dorecurse {7}{\samplefile{ward}\endgraf} + \syncposition[1][4]\dorecurse {3}{\samplefile{ward}\endgraf} + \stopchapter +} +\dorecurse {100} { +% \dorecurse {1} { \startchapter[title={Test #1}] - \syncposition[1][1] \dorecurse{10}{\input ward \endgraf} - \syncposition[1][2] \dorecurse {4}{\input ward \endgraf} - \syncposition[1][3] \dorecurse {7}{\input ward \endgraf} - \syncposition[1][4] \dorecurse {3}{\input ward \endgraf} + \syncposition[1][1]\dorecurse{1}{\samplefile{ward}\endgraf} + \syncposition[1][2]\dorecurse{1}{\samplefile{ward}\endgraf} + \syncposition[1][3]\dorecurse{1}{\samplefile{ward}\endgraf} + \syncposition[1][4]\dorecurse{1}{\samplefile{ward}\endgraf} \stopchapter } diff --git a/tex/context/base/mkiv/anch-tab.mkiv b/tex/context/base/mkiv/anch-tab.mkiv index afa87c7b2..67afb22f7 100644 --- a/tex/context/base/mkiv/anch-tab.mkiv +++ b/tex/context/base/mkiv/anch-tab.mkiv @@ -84,8 +84,8 @@ \newcount \noftabpositions \newtoks \posXCtoks -\def\anch_tabulate_bpos{\bpos} -\def\anch_tabulate_epos{\epos} +\unexpanded\def\anch_tabulate_bpos{\bpos} +\unexpanded\def\anch_tabulate_epos{\epos} \installcorenamespace{positiontables} @@ -134,15 +134,18 @@ {\anch_tables_append_GSC[#1:#1]} \def\anch_tables_append_GSC[#1:#2:#3]% - {\doglobal\appendtoks\anch_tables_process_GSC[#1:#2]\to\posXCtoks\NC} +% {\doglobal\appendtoks\anch_tables_process_GSC[#1:#2]\to\posXCtoks\NC} + {\gtoksapp\posXCtoks{\anch_tables_process_GSC[#1:#2]}\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} + \doglobal\appendtoks\expandafter\anch_tabulate_epos\expandafter{\tbPOSprefix#1}\to\posXCtoks} +% \xtoksapp\posXCtoks{\anch_tabulate_epos{\tbPOSprefix#1}}} \def\anch_tables_indeed_GFC[#1]% {\doglobal\appendtoks\anch_tables_delayed_GFC[#1]\to\posXCtoks\NC} +% {\gtoksapp\posXCtoks{\anch_tables_delayed_GFC[#1]}\NC} \def\anch_tables_delayed_GFC[#1]% {\processcommalist[#1]\anch_tables_step_GFC} @@ -156,9 +159,11 @@ \def\anch_tables_indeed_GTC[#1]% {\doglobal\appendtoks\anch_tables_delayed_GTC[#1]\to\posXCtoks\NC} +% {\gtoksapp\posXCtoks{\anch_tables_delayed_GTC[#1]}\NC} \def\anch_tables_delayed_GTC[#1]% {\doglobal\appendtoks\anch_tables_process_GTC[#1]\to\posXCtoks} +% {\gtoksapp\posXCtoks{\anch_tables_process_GTC[#1]}\NC} \def\anch_tables_process_GTC[#1]% {\processcommalist[#1]\anch_tables_step_GTC} @@ -207,10 +212,10 @@ \let\anch_tabulate_flush_epos\relax -\def\anch_tabulate_bpos_indeed +\unexpanded\def\anch_tabulate_bpos_indeed {\bpos} -\def\anch_tabulate_epos_indeed#1% +\unexpanded\def\anch_tabulate_epos_indeed#1% {\ifvoid\b_tabl_tabulate_current\c_tabl_tabulate_column \epos{#1}% \glet\anch_tabulate_flush_epos\relax diff --git a/tex/context/base/mkiv/attr-col.lua b/tex/context/base/mkiv/attr-col.lua index 28e63b177..5ea72c7e3 100644 --- a/tex/context/base/mkiv/attr-col.lua +++ b/tex/context/base/mkiv/attr-col.lua @@ -114,12 +114,16 @@ local data = colors.data local values = colors.values local registered = colors.registered +local cmykrgbmode = 0 -- only for testing, already defined colors are not affected + local numbers = attributes.numbers local list = attributes.list registerstorage("attributes/colors/values", values, "attributes.colors.values") registerstorage("attributes/colors/registered", registered, "attributes.colors.registered") +directives.register("colors.cmykrgbmode", function(v) cmykrgbmode = tonumber(v) or 0 end) + local f_colors = { rgb = formatters["r:%s:%s:%s"], cmyk = formatters["c:%s:%s:%s:%s"], @@ -148,8 +152,11 @@ end local function cmyktorgb(c,m,y,k) if not c then return 0, 0, 0, 1 + elseif cmykrgbmode == 1 then + local d = 1.0 - k + return 1.0 - min(1.0,c*d+k), 1.0 - min(1.0,m*d+k), 1.0 - min(1.0,y*d+k) else - return 1.0 - min(1.0,c+k), 1.0 - min(1.0,m+k), 1.0 - min(1.0,y+k) + return 1.0 - min(1.0,c +k), 1.0 - min(1.0,m +k), 1.0 - min(1.0,y +k) end end @@ -295,7 +302,7 @@ function colors.spot(parent,f,d,p) local v = values[n] if v then -- the via cmyk hack is dirty, but it scales better - local c, m, y, k = p*v[6], p*v[7], p*v[8], p*v[8] + local c, m, y, k = p*v[6], p*v[7], p*v[8], p*v[9] local r, g, b = cmyktorgb(c,m,y,k) local s = cmyktogray(c,m,y,k) return { 5, s, r, g, b, c, m, y, k, parent, f, d, p } @@ -318,7 +325,7 @@ function colors.spot(parent,f,d,p) c = c + p*v[6] m = m + p*v[7] y = y + p*v[8] - k = k + p*v[8] + k = k + p*v[9] done = true end end @@ -361,10 +368,14 @@ local function reviver(data,n) local gray = graycolor(v[2]) d = { gray, gray, gray, gray } elseif model == 3 then - local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9]) + local gray = graycolor(v[2]) + local rgb = rgbcolor(v[3],v[4],v[5]) + local cmyk = cmykcolor(v[6],v[7],v[8],v[9]) d = { rgb, gray, rgb, cmyk } elseif model == 4 then - local gray, rgb, cmyk = graycolor(v[2]), rgbcolor(v[3],v[4],v[5]), cmykcolor(v[6],v[7],v[8],v[9]) + local gray = graycolor(v[2]) + local rgb = rgbcolor(v[3],v[4],v[5]) + local cmyk = cmykcolor(v[6],v[7],v[8],v[9]) d = { cmyk, gray, rgb, cmyk } elseif model == 5 then local spot = spotcolor(v[10],v[11],v[12],v[13]) @@ -406,10 +417,29 @@ function colors.setmodel(name,weightgray) weightgray = true end end - colors.model = name -- global, not useful that way - colors.default = models[name] or 1 -- global - colors.weightgray = weightgray -- global - return colors.default + local default = models[name] or 1 + + colors.model = name -- global, not useful that way + colors.default = default -- global + colors.weightgray = weightgray -- global + + -- avoid selective checking is no need for it + + local forced = colors.forced + + if forced == nil then + -- unset + colors.forced = default + elseif forced == false then + -- assumed mixed + elseif forced ~= default then + -- probably mixed + colors.forced = false + else + -- stil the same + end + + return default end function colors.register(name, colorspace, ...) -- passing 9 vars is faster (but not called that often) diff --git a/tex/context/base/mkiv/attr-ini.lua b/tex/context/base/mkiv/attr-ini.lua index 67faa9fc0..dd971afc1 100644 --- a/tex/context/base/mkiv/attr-ini.lua +++ b/tex/context/base/mkiv/attr-ini.lua @@ -62,7 +62,7 @@ ranges of numbers for them. Of course a the end a private attri accessible too, so a private attribute can have a public appearance.

--ldx]]-- -sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 127 -- very private (can become 15) +sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 15 -- very private sharedstorage.attributes_last_public = sharedstorage.attributes_last_public or 1024 -- less private function attributes.private(name) -- at the lua end (hidden from user) @@ -114,7 +114,8 @@ local function showlist(what,list) local a = list.next local i = 0 while a do - local number, value = a.number, a.value + local number = a.number + local value = a.value i = i + 1 report_attribute("%S %2i: attribute %3i, value %4i, name %a",what,i,number,value,names[number]) a = a.next diff --git a/tex/context/base/mkiv/attr-ini.mkiv b/tex/context/base/mkiv/attr-ini.mkiv index d537cebfa..3792b1c63 100644 --- a/tex/context/base/mkiv/attr-ini.mkiv +++ b/tex/context/base/mkiv/attr-ini.mkiv @@ -24,6 +24,7 @@ \installcorenamespace{attributecount} % the counter representing the attribute (attrdef'd) \installcorenamespace{attributeid} % the internal number \installcorenamespace{attributestack} % the attribute specific stack +\installcorenamespace{attributepickup} \unexpanded\def\pushattribute#1% {\global\advance\csname\??attributestack\string#1\endcsname\plusone @@ -40,12 +41,15 @@ \newtoks \t_attr_list_global \newtoks \t_attr_list_local +\newtoks \t_attr_list_pickup \newtoks \t_attr_list_nomath \ifdefined \s!global \else \def\s!global {global} \fi % for metatex % or hard check later \ifdefined \s!public \else \def\s!public {public} \fi % for metatex % or hard check later \ifdefined \s!private \else \def\s!private {private} \fi % for metatex % or hard check later \ifdefined \s!attribute \else \def\s!attribute{attribute} \fi % for metatex % or hard check later +\ifdefined \s!pickup \else \def\s!pickup {pickup} \fi % for metatex % or hard check later +\ifdefined \s!forget \else \def\s!forget {forget} \fi % for metatex % or hard check later \unexpanded\def\defineattribute {\dodoubleempty\attr_basics_define} \unexpanded\def\definesystemattribute{\dodoubleempty\attr_basics_define_system} @@ -53,6 +57,8 @@ \def\attr_basics_define {\attr_basics_define_indeed\s!public} \def\attr_basics_define_system{\attr_basics_define_indeed\s!private} + % here public means 'visible' so it's not to be confused with 'public' at the lua end + \def\attr_basics_define_indeed#1[#2][#3]% {\ifcsname\??attributecount#2\endcsname\else \scratchcounter\clf_defineattribute{#2}{#1}\relax @@ -62,15 +68,33 @@ \csname\??attributeid#2\endcsname\scratchcounter % some attributes are always global \doifelseinset\s!global{#3}% - {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_global}% - {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_local }% + {\etoksapp\t_attr_list_global{\csname\??attributecount#2\endcsname\attributeunsetvalue}}% + {\etoksapp\t_attr_list_local {\csname\??attributecount#2\endcsname\attributeunsetvalue}}% \doifinset\s!nomath{#3}% - {\appendetoks\csname\??attributecount#2\endcsname\attributeunsetvalue\to\t_attr_list_nomath}% - % here public means 'visible' so it's not to be confused with 'public' at the lua end + {\etoksapp\t_attr_list_nomath{\csname\??attributecount#2\endcsname\attributeunsetvalue}}% \doifinset\s!public{#3}% {\expandafter\let\csname#2\s!attribute\expandafter\endcsname\csname\??attributeid#2\endcsname}% + \doifinset\s!pickup{#3}% + {\expandafter\newconstant\csname\??attributepickup#2\endcsname + \csname\??attributepickup#2\endcsname\attributeunsetvalue + \etoksapp\t_attr_list_pickup{\csname\??attributecount#2\endcsname\csname\??attributepickup#2\endcsname}% + \ifcsname#2\s!attribute\endcsname + \expandafter\edef\csname\s!pickup#2\s!attribute\endcsname + {\csname\??attributepickup#2\endcsname\csname\??attributecount#2\endcsname}% + \expandafter\edef\csname\s!forget#2\s!attribute\endcsname + {\csname\??attributepickup#2\endcsname\attributeunsetvalue}% + \fi}% \fi} +\unexpanded\def\pickupattributes + {\the\t_attr_list_pickup\relax} + +% \unexpanded\def\pickupattribute#1% +% {\csname\??attributecount#1\endcsname\csname\??attributepickup#1\endcsname} + +% \unexpanded\def\pickupattributelater#1% +% {\csname\??attributepickup#1\endcsname\csname\??attributecount#1\endcsname} + \unexpanded\def\newattribute#1% {\attr_basics_define_indeed\s!public[\csstring#1][]% \expandafter\let\expandafter#1\csname\??attributeid\csstring#1\endcsname} @@ -84,8 +108,8 @@ \let\dompattribute\gobbletwoarguments -\unexpanded\def\resetglobalattributes{\the\t_attr_list_global} -\unexpanded\def\resetlocalattributes {\the\t_attr_list_local } +\unexpanded\def\resetglobalattributes{\the\t_attr_list_global\attribute\zerocount\zerocount} +\unexpanded\def\resetlocalattributes {\the\t_attr_list_local \attribute\zerocount\zerocount} \let\resetallattributes\resetlocalattributes diff --git a/tex/context/base/mkiv/back-exp.lua b/tex/context/base/mkiv/back-exp.lua index b18679fa2..f5035d3cf 100644 --- a/tex/context/base/mkiv/back-exp.lua +++ b/tex/context/base/mkiv/back-exp.lua @@ -37,7 +37,7 @@ local next, type, tonumber = next, type, tonumber local sub, gsub = string.sub, string.gsub local validstring = string.valid local lpegmatch = lpeg.match -local utfchar, utfvalues = utf.char, utf.values +local utfchar, utfvalues, utflen = utf.char, utf.values, utf.len local concat, insert, remove, merge, sort = table.concat, table.insert, table.remove, table.merge, table.sort local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys local formatters = string.formatters @@ -46,6 +46,7 @@ local replacetemplate = utilities.templates.replace local trace_export = false trackers.register ("export.trace", function(v) trace_export = v end) local trace_spacing = false trackers.register ("export.trace.spacing", function(v) trace_spacing = v end) +local trace_detail = false trackers.register ("export.trace.detail", function(v) trace_detail = v end) local less_state = false directives.register("export.lessstate", function(v) less_state = v end) local show_comment = true directives.register("export.comment", function(v) show_comment = v end) @@ -67,6 +68,7 @@ local attributes = attributes local variables = interfaces.variables local v_yes = variables.yes local v_no = variables.no +local v_xml = variables.xml local v_hidden = variables.hidden local implement = interfaces.implement @@ -82,56 +84,8 @@ local fontchar = fonts.hashes.characters local fontquads = fonts.hashes.quads local languagenames = languages.numbers -local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes -local listcodes = nodes.listcodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glyph_code = nodecodes.glyph -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local disc_code = nodecodes.disc - -local userskip_code = skipcodes.userskip -local rightskip_code = skipcodes.rightskip -local parfillskip_code = skipcodes.parfillskip -local spaceskip_code = skipcodes.spaceskip -local xspaceskip_code = skipcodes.xspaceskip - -local line_code = listcodes.line - local texgetcount = tex.getcount -local privateattribute = attributes.private -local a_characters = privateattribute('characters') -local a_exportstatus = privateattribute('exportstatus') -local a_tagged = privateattribute('tagged') -local a_taggedpar = privateattribute("taggedpar") -local a_image = privateattribute('image') -local a_reference = privateattribute('reference') -local a_textblock = privateattribute("textblock") - -local nuts = nodes.nuts -local tonut = nuts.tonut - -local getnext = nuts.getnext -local getsubtype = nuts.getsubtype -local getfont = nuts.getfont -local getdisc = nuts.getdisc -local getcomponents = nuts.getcomponents -local getlist = nuts.getlist -local getid = nuts.getid -local getattr = nuts.getattr -local setattr = nuts.setattr -- maybe use properties -local isglyph = nuts.isglyph -local getkern = nuts.getkern -local getwidth = nuts.getwidth - - -local traverse_id = nuts.traverse_id -local traverse_nodes = nuts.traverse - local references = structures.references local structurestags = structures.tags local taglist = structurestags.taglist @@ -167,7 +121,7 @@ local currentparagraph = nil local noftextblocks = 0 -local hyphencode = 0xAD +----- hyphencode = 0xAD local hyphen = utfchar(0xAD) -- todo: also emdash etc local tagsplitter = structurestags.patterns.splitter ----- colonsplitter = lpeg.splitat(":") @@ -554,6 +508,8 @@ do local fields = { "title", "subtitle", "author", "keywords", "url", "version" } + local ignoredelements = false + local function checkdocument(root) local data = root.data if data then @@ -580,6 +536,9 @@ do elseif tg == "ignore" then di.element = "" checkdocument(di) + elseif ignoredelements and ignoredelements[tg] then + di.element = "" + checkdocument(di) else checkdocument(di) -- new, else no noexport handling end @@ -609,6 +568,64 @@ do checkdocument(di) end + implement { + name = "ignoretagsinexport", + arguments = "string", + actions = function(list) + for tag in string.gmatch(list,"[a-z]+") do + if ignoredelements then + ignoredelements[tag] = true + else + ignoredelements = { [tag] = true } + end + end + end, + } + +end + +do + + local marginanchors = { } + local margincontent = { } + + implement { + name = "settagmargintext", + arguments = "integer", + actions = function(n) + marginanchors[locatedtag("margintext")] = n + end + } + + implement { + name = "settagmarginanchor", + arguments = "integer", + actions = function(n) + marginanchors[locatedtag("marginanchor")] = n + end + } + + function checks.margintext(di) + local i = marginanchors[di.fulltag] + margincontent[i] = di + end + + function checks.marginanchor(di) + local i = marginanchors[di.fulltag] + local d = margincontent[i] + -- + di.attribute = d.attribute + di.data = d.data + di.detail = d.detail + di.element = d.element + di.fulltag = d.fulltag + di.nature = d.nature + di.samepar = true + di.tg = d.tg + -- + d.skip = "ignore" + end + end do @@ -922,7 +939,8 @@ evaluators.special = function(di,var) end end -local referencehash = { } +local referencehash = { } +local destinationhash = { } do @@ -1040,10 +1058,37 @@ do end end + local function reference(di,element,n,fulltag) + local destination = destinationhash[fulltag] + if destination then + local d = structures.references.internals[destination] + if d then + addreference(di,d.references) + return true + else + return false + end + else + local data = di.data + if data then + for i=1,#data do + local di = data[i] + if di then + local fulltag = di.fulltag + if fulltag and reference(di,element,n,fulltag) then + return true + end + end + end + end + end + end + extras.adddestination = adddestination extras.addreference = addreference extras.link = link + extras.reference = reference end @@ -1243,22 +1288,21 @@ do } end if ndata == 0 then -root.skip = "comment" -- get rid of weird artefacts -root.nota = "weird" + root.skip = "comment" -- get rid of weird artefacts + root.nota = "weird" return elseif ndata == 1 then local d = data[1] if not d or d == "" then -root.skip = "comment" + root.skip = "comment" return elseif d.content then return else -- if ndata == 1 then local tg = d.tg --- if automathrows and roottg == "mrow" then -if automathrows and (roottg == "mrow" or roottg == "mtext") then + if automathrows and (roottg == "mrow" or roottg == "mtext") then -- maybe just always ! check spec first --- or we can have chesks.* for each as we then can flatten + -- or we can have chesks.* for each as we then can flatten if no_mrow[tg] then root.skip = "comment" end @@ -1670,10 +1714,10 @@ if automathrows and (roottg == "mrow" or roottg == "mtext") then end function checks.mrow(di) --- local d = di.data --- if d then --- checked(d) --- end + -- local d = di.data + -- if d then + -- checked(d) + -- end end -- we can move more checks here @@ -1758,6 +1802,25 @@ if automathrows and (roottg == "mrow" or roottg == "mtext") then end +do + + local registered = { } + + function structurestags.setformulacontent(n) + registered[locatedtag("formulacontent")] = { + n = n, + } + end + + function extras.formulacontent(di,element,n,fulltag) + local r = registered[fulltag] + if r then + setattribute(di,"n",r.n) + end + end + +end + do local registered = structures.sections.registered @@ -1861,7 +1924,7 @@ do end end - local function ignorebreaks(di,element,n,fulltag) + function extras.registerpages(di,element,n,fulltag) -- ignorebreaks local data = di.data for i=1,#data do local d = data[i] @@ -1871,7 +1934,7 @@ do end end - local function ignorespaces(di,element,n,fulltag) + function extras.registerseparator(di,element,n,fulltag) -- ignorespaces local data = di.data for i=1,#data do local d = data[i] @@ -1882,9 +1945,6 @@ do end end - extras.registerpages = ignorebreaks - extras.registerseparator = ignorespaces - end do @@ -1991,6 +2051,41 @@ do end +do + + local usedpublications = { } + local tagsindatasets = setmetatableindex("table") + local serialize = false + + function structurestags.setpublication(dataset,tag,rendering) + usedpublications[locatedtag("publication")] = { + dataset = dataset, + tag = tag, + rendering = rendering + } + tagsindatasets[dataset][tag] = true + if not serialize then + structures.tags.registerextradata("btx",function() + local t = { ""} + for dataset, used in sortedhash(tagsindatasets) do + t[#t+1] = publications.converttoxml(dataset,true,false,true,false,true,true) + end + t[#t+1] = "" + return concat(t,"\n") + end) + end + end + + function extras.publication(di,element,n,fulltag) + local hash = usedpublications[fulltag] + if hash then + setattribute(di,"dataset",hash.dataset) + setattribute(di,"tag",hash.tag) + end + end + +end + -- flusher do @@ -1998,7 +2093,7 @@ do local f_detail = formatters[' detail="%s"'] local f_chain = formatters[' chain="%s"'] local f_index = formatters[' n="%s"'] - local f_spacing = formatters['%s'] + local f_spacing = formatters['%s'] local f_empty_inline = formatters["<%s/>"] local f_empty_mixed = formatters["%w<%s/>\n"] @@ -2062,7 +2157,7 @@ do local depth = 0 local inline = 0 - local function emptytag(result,embedded,element,nature,di) -- currently only break but at some point + local function emptytag(result,element,nature,di) -- currently only break but at some point local a = di.attributes -- we might add detail etc if a then -- happens seldom if nature == "display" then @@ -2111,7 +2206,7 @@ do end end - local function begintag(result,embedded,element,nature,di,skip) + local function begintag(result,element,nature,di,skip) local index = di.n local fulltag = di.fulltag local specification = specifications[fulltag] or { } -- we can have a dummy @@ -2135,12 +2230,6 @@ do -- ignore else - -- if embedded then - -- if element == "math" then - -- embedded[f_tagid(element,index)] = #result+1 - -- end - -- end - local n = 0 local r = { } -- delay this if detail then @@ -2160,6 +2249,7 @@ do n = n + 1 r[n] = f_index(index) end + -- local extra = extras[element] if extra then extra(di,element,index,fulltag) @@ -2181,8 +2271,14 @@ do end local a = di.attributes if a then + if trace_spacing then + a.p = di.parnumber or 0 + end n = n + 1 r[n] = attributes(a) + elseif trace_spacing then + n = n + 1 + r[n] = attributes { p = di.parnumber or 0 } end if n == 0 then if nature == "inline" or inline > 0 then @@ -2249,7 +2345,7 @@ do end end - local function endtag(result,embedded,element,nature,di,skip) + local function endtag(result,element,nature,di,skip) if skip == "comment" then if show_comment then if nature == "display" and (inline == 0 or inline == 1) then @@ -2280,18 +2376,10 @@ do inline = inline - 1 result[#result+1] = f_end_inline(namespaced[element]) end - - -- if embedded then - -- if element == "math" then - -- local id = f_tagid(element,di.n) -- index) - -- local tx = concat(result,"",embedded[id],#result) - -- embedded[id] = "" .. "\n" .. tx - -- end - -- end end end - local function flushtree(result,embedded,data,nature) + local function flushtree(result,data,nature) local nofdata = #data for i=1,nofdata do local di = data[i] @@ -2323,23 +2411,23 @@ do if not element then -- skip elseif element == "break" then -- or element == "pagebreak" - emptytag(result,embedded,element,nature,di) + emptytag(result,element,nature,di) elseif element == "" or di.skip == "ignore" then -- skip else if di.before then - flushtree(result,embedded,di.before,nature) + flushtree(result,di.before,nature) end local natu = di.nature local skip = di.skip if di.breaknode then - emptytag(result,embedded,"break","display",di) + emptytag(result,"break","display",di) end - begintag(result,embedded,element,natu,di,skip) - flushtree(result,embedded,di.data,natu) - endtag(result,embedded,element,natu,di,skip) + begintag(result,element,natu,di,skip) + flushtree(result,di.data,natu) + endtag(result,element,natu,di,skip) if di.after then - flushtree(result,embedded,di.after,nature) + flushtree(result,di.after,nature) end end end @@ -2360,19 +2448,25 @@ do local di = data[i] if not di then -- skip + elseif di.skip == "ignore" then + -- skip (new) elseif di.content then - local parnumber = di.parnumber - if prevnature == "inline" and prevparnumber and prevparnumber ~= parnumber then - nofnewdata = nofnewdata + 1 - if trace_spacing then - newdata[nofnewdata] = makebreaknode { type = "a", p = prevparnumber, n = parnumber } - else - newdata[nofnewdata] = makebreaknode() + if di.samepar then + prevparnumber = false + else + local parnumber = di.parnumber + if prevnature == "inline" and prevparnumber and prevparnumber ~= parnumber then + nofnewdata = nofnewdata + 1 + if trace_spacing then + newdata[nofnewdata] = makebreaknode { type = "a", p = prevparnumber, n = parnumber } + else + newdata[nofnewdata] = makebreaknode() + end end + prevelement = nil + prevparnumber = parnumber end - prevelement = nil prevnature = "inline" - prevparnumber = parnumber nofnewdata = nofnewdata + 1 newdata[nofnewdata] = di elseif not di.collapsed then @@ -2383,39 +2477,51 @@ do end prevelement = element prevnature = "display" + nofnewdata = nofnewdata + 1 + newdata[nofnewdata] = di elseif element == "" or di.skip == "ignore" then -- skip + else + if di.samepar then + prevnature = "inline" + prevparnumber = false + else + local nature = di.nature + local parnumber = di.parnumber + if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then + nofnewdata = nofnewdata + 1 + if trace_spacing then + newdata[nofnewdata] = makebreaknode { type = "b", p = prevparnumber, n = parnumber } + else + newdata[nofnewdata] = makebreaknode() + end + end + prevnature = nature + prevparnumber = parnumber + end + prevelement = element + breaktree(di,tree,element) + nofnewdata = nofnewdata + 1 + newdata[nofnewdata] = di + end + else + if di.samepar then + prevnature = "inline" + prevparnumber = false else local nature = di.nature local parnumber = di.parnumber if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then nofnewdata = nofnewdata + 1 if trace_spacing then - newdata[nofnewdata] = makebreaknode { type = "b", p = prevparnumber, n = parnumber } + newdata[nofnewdata] = makebreaknode { type = "c", p = prevparnumber, n = parnumber } else newdata[nofnewdata] = makebreaknode() end end prevnature = nature prevparnumber = parnumber - prevelement = element - breaktree(di,tree,element) - end - nofnewdata = nofnewdata + 1 - newdata[nofnewdata] = di - else - local nature = di.nature - local parnumber = di.parnumber - if prevnature == "inline" and nature == "inline" and prevparnumber and prevparnumber ~= parnumber then - nofnewdata = nofnewdata + 1 - if trace_spacing then - newdata[nofnewdata] = makebreaknode { type = "c", p = prevparnumber, n = parnumber } - else - newdata[nofnewdata] = makebreaknode() - end end - prevnature = nature - prevparnumber = parnumber nofnewdata = nofnewdata + 1 newdata[nofnewdata] = di end @@ -2447,6 +2553,8 @@ do local cd = currentdata[j] if not cd or cd == "" then -- skip + elseif cd.skip == "ignore" then + -- skip elseif cd.content then if not currentpar then -- add space ? @@ -2593,9 +2701,9 @@ local function pop() currentdepth = currentdepth - 1 if trace_export then if top then - report_export("%w",currentdepth,top) + report_export("%w",currentdepth,tree.tg) else - report_export("",top) + report_export("",tree.tg) end end else @@ -2701,7 +2809,7 @@ local function pushcontent(oldparagraph,newparagraph) local nd = #td td[nd+1] = { parnumber = oldparagraph or currentparagraph, content = content } if trace_export then - report_export("%w",currentdepth,#content) + report_export("%w",currentdepth,utflen(content)) report_export("%w%s",currentdepth,(gsub(content,"\n","\\n"))) report_export("%w",currentdepth) end @@ -2746,27 +2854,119 @@ end -- inserts ? -local function collectresults(head,list,pat,pap) -- is last used (we also have currentattribute) - local p - for n in traverse_nodes(head) do - local c, id = isglyph(n) -- 14: image, 8: literal (mp) - if c then - local at = getattr(n,a_tagged) or pat - if not at then - -- we need to tag the pagebody stuff as being valid skippable - -- - -- report_export("skipping character: %C (no attribute)",n.char) +local collectresults do -- too many locals otherwise + + local nodecodes = nodes.nodecodes + local gluecodes = nodes.gluecodes + local listcodes = nodes.listcodes + local whatsitcodes = nodes.whatsitcodes + + local subtypes = nodes.subtypes + + local hlist_code = nodecodes.hlist + local vlist_code = nodecodes.vlist + local glyph_code = nodecodes.glyph + local glue_code = nodecodes.glue + local kern_code = nodecodes.kern + local disc_code = nodecodes.disc + local whatsit_code = nodecodes.whatsit + local localpar_code = nodecodes.localpar + + local userskip_code = gluecodes.userskip + local rightskip_code = gluecodes.rightskip + local parfillskip_code = gluecodes.parfillskip + local spaceskip_code = gluecodes.spaceskip + local xspaceskip_code = gluecodes.xspaceskip + + local linelist_code = listcodes.line + + local userdefinedwhatsit_code = whatsitcodes.userdefined + + local privateattribute = attributes.private + local a_image = privateattribute('image') + local a_reference = privateattribute('reference') + local a_destination = privateattribute('destination') + local a_characters = privateattribute('characters') + local a_exportstatus = privateattribute('exportstatus') + local a_tagged = privateattribute('tagged') + local a_taggedpar = privateattribute("taggedpar") + local a_textblock = privateattribute("textblock") + + local inline_mark = nodes.pool.userids["margins.inline"] + + local nuts = nodes.nuts + + local getnext = nuts.getnext + local getdisc = nuts.getdisc + local getlist = nuts.getlist + local getid = nuts.getid + local getattr = nuts.getattr + local setattr = nuts.setattr -- maybe use properties + local isglyph = nuts.isglyph + local getkern = nuts.getkern + local getwidth = nuts.getwidth + + local nexthlist = nuts.traversers.hlist + local nextnode = nuts.traversers.node + + local function addtomaybe(maybewrong,c,case) + if trace_export then + report_export("%w",currentdepth,c,case) + else + local s = formatters["%C"](c) + if maybewrong then + maybewrong[#maybewrong+1] = s else - -- we could add tonunicodes for ligatures (todo) - local components = getcomponents(n) - if components and (not characterdata[c] or overloads[c]) then -- we loose data - collectresults(components,nil,at) -- this assumes that components have the same attribute as the glyph ... we should be more tolerant (see math) + maybewrong = { s } + end + return maybewrong + end + end + + local function showmaybe(maybewrong) + if not trace_export then + report_export("fuzzy paragraph: % t",maybewrong) + end + end + + local function showdetail(n,id,subtype) + local a = getattr(n,a_tagged) + local t = taglist[a] + local c = nodecodes[id] + local s = subtypes[id][subtype] + if a and t then + report_export("node %a, subtype %a, tag %a, element %a, tree '% t'",c,s,a,t.tagname,t.taglist) + else + report_export("node %a, subtype %a, untagged",c,s) + end + end + + local function collectresults(head,list,pat,pap) -- is last used (we also have currentattribute) + local p + local localparagraph + local maybewrong + local pid + for n, id, subtype in nextnode, head do + if trace_detail then + showdetail(n,id,subtype) + end + if id == glyph_code then + local c, f = isglyph(n) + local at = getattr(n,a_tagged) or pat + if not at then + -- we need to tag the pagebody stuff as being valid skippable + -- + -- report_export("skipping character: %C (no attribute)",n.char) else if last ~= at then local tl = taglist[at] + local ap = getattr(n,a_taggedpar) or pap + if localparagraph and (not ap or ap < localparagraph) then + maybewrong = addtomaybe(maybewrong,c,1) + end pushcontent() - currentnesting = tl - currentparagraph = getattr(n,a_taggedpar) or pap + currentnesting = tl + currentparagraph = ap currentattribute = at last = at pushentry(currentnesting) @@ -2780,6 +2980,11 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c local t = tl.taglist referencehash[t[#t]] = r -- fulltag end + local d = getattr(n,a_destination) + if d then + local t = tl.taglist + destinationhash[t[#t]] = d -- fulltag + end -- elseif last then -- we can consider tagging the pars (lines) in the parbuilder but then we loose some @@ -2792,12 +2997,15 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c currentattribute = last currentparagraph = ap end + if localparagraph and (not ap or ap < localparagraph) then + maybewrong = addtomaybe(maybewrong,c,2) + end if trace_export then - report_export("%w",currentdepth,c,last) + report_export("%w",currentdepth,c,last) end else if trace_export then - report_export("%w",currentdepth,c,at) + report_export("%w",currentdepth,c,at) end end local s = getattr(n,a_exportstatus) @@ -2820,7 +3028,7 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c currentcontent[nofcurrentcontent] = " " end else - local fc = fontchar[getfont(n)] + local fc = fontchar[f] if fc then fc = fc and fc[c] if fc then @@ -2851,63 +3059,60 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c end end end - end - elseif id == disc_code then -- probably too late - local pre, post, replace = getdisc(n) - if keephyphens then - if pre and not getnext(pre) and isglyph(pre) == hyphencode then - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = hyphen + elseif id == disc_code then -- probably too late + local pre, post, replace = getdisc(n) + if keephyphens then + if pre and not getnext(pre) and isglyph(pre) == 0xAD then -- hyphencode then + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = hyphen + end end - end - if replace then - collectresults(replace,nil) - end - elseif id == glue_code then - -- we need to distinguish between hskips and vskips - local ca = getattr(n,a_characters) - if ca == 0 then - -- skip this one ... already converted special character (node-acc) - elseif ca then - local a = getattr(n,a_tagged) or pat - if a then - local c = specialspaces[ca] - if last ~= a then - local tl = taglist[a] - if trace_export then - report_export("%w",currentdepth,ca,a) - end - pushcontent() - currentnesting = tl - currentparagraph = getattr(n,a_taggedpar) or pap - currentattribute = a - last = a - pushentry(currentnesting) - -- no reference check (see above) - elseif last then - local ap = getattr(n,a_taggedpar) or pap - if ap ~= currentparagraph then - pushcontent(currentparagraph,ap) + if replace then + collectresults(replace,nil) + end + elseif id == glue_code then + -- we need to distinguish between hskips and vskips + local ca = getattr(n,a_characters) + if ca == 0 then + -- skip this one ... already converted special character (node-acc) + elseif ca then + local a = getattr(n,a_tagged) or pat + if a then + local c = specialspaces[ca] + if last ~= a then + local tl = taglist[a] + if trace_export then + report_export("%w",currentdepth,ca,a) + end + pushcontent() + currentnesting = tl + currentparagraph = getattr(n,a_taggedpar) or pap + currentattribute = a + last = a pushentry(currentnesting) - currentattribute = last - currentparagraph = ap - end - if trace_export then - report_export("%w",currentdepth,ca,last) + -- no reference check (see above) + elseif last then + local ap = getattr(n,a_taggedpar) or pap + if ap ~= currentparagraph then + pushcontent(currentparagraph,ap) + pushentry(currentnesting) + currentattribute = last + currentparagraph = ap + end + if trace_export then + report_export("%w",currentdepth,ca,last) + end end + -- if somespace[currentcontent[nofcurrentcontent]] then + -- if trace_export then + -- report_export("%w",currentdepth) + -- end + -- nofcurrentcontent = nofcurrentcontent - 1 + -- end + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = c end - -- if somespace[currentcontent[nofcurrentcontent]] then - -- if trace_export then - -- report_export("%w",currentdepth) - -- end - -- nofcurrentcontent = nofcurrentcontent - 1 - -- end - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = c - end - else - local subtype = getsubtype(n) - if subtype == userskip_code then + elseif subtype == userskip_code then if getwidth(n) > threshold then if last and not somespace[currentcontent[nofcurrentcontent]] then local a = getattr(n,a_tagged) or pat @@ -2965,6 +3170,8 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c if not keephyphens then nofcurrentcontent = nofcurrentcontent - 1 end + elseif pid == disc_code then + -- go on .. tricky: we should mark the glyhs as coming from a disc elseif not somespace[r] then local a = getattr(n,a_tagged) or pat if a == last then @@ -2988,101 +3195,134 @@ local function collectresults(head,list,pat,pap) -- is last used (we also have c end end elseif subtype == parfillskip_code then - -- deal with paragaph endings (crossings) elsewhere and we quit here + -- deal with paragraph endings (crossings) elsewhere and we quit here -- as we don't want the rightskip space addition + if maybewrong then + showmaybe(maybewrong) + end return end - end - elseif id == hlist_code or id == vlist_code then - local ai = getattr(n,a_image) - if ai then - local at = getattr(n,a_tagged) or pat - if nofcurrentcontent > 0 then - pushcontent() - pushentry(currentnesting) -- ?? - end - pushentry(taglist[at]) -- has an index, todo: flag empty element - if trace_export then - report_export("%w",currentdepth,kern) + end + nofcurrentcontent = nofcurrentcontent + 1 + currentcontent[nofcurrentcontent] = " " + end + elseif a then + -- e.g LOGOLOGO + if trace_export then + report_export("%w",currentdepth,limit,last,a) + end + last = a + pushcontent() if trace_export then - report_export("%w",currentdepth,kern) + report_export("%w",currentdepth,kern) end nofcurrentcontent = nofcurrentcontent + 1 currentcontent[nofcurrentcontent] = " " + currentnesting = taglist[last] + pushentry(currentnesting) + currentattribute = last end - elseif a then - -- e.g LOGOLOGO - if trace_export then - report_export("%w",currentdepth,limit,last,a) - end - last = a - pushcontent() - if trace_export then - report_export("%w",currentdepth,kern) - end - nofcurrentcontent = nofcurrentcontent + 1 - currentcontent[nofcurrentcontent] = " " - currentnesting = taglist[last] - pushentry(currentnesting) - currentattribute = last end end end + elseif id == whatsit_code then + if subtype == userdefinedwhatsit_code then + -- similar to images, see above + local at = getattr(n,a_tagged) + if nofcurrentcontent > 0 then + pushcontent() + pushentry(currentnesting) -- ?? + end + pushentry(taglist[at]) + if trace_export then + report_export("%w",currentdepth) + function nodes.handlers.export(head) -- hooks into the page builder + starttiming(treehash) + if trace_export then + report_export("%w",currentdepth) + end + -- continueexport() + restart = true + collectresults(head) + if trace_export then + report_export("%w",currentdepth) + end + stoptiming(treehash) + return head end - -- continueexport() - restart = true - collectresults(tonut(head)) - if trace_export then - report_export("%w",currentdepth) + + function nodes.handlers.checkparcounter(p) + setattr(p,a_taggedpar,texgetcount("tagparcounter") + 1) + return p end - stoptiming(treehash) - return head, true -end -function builders.paragraphs.tag(head) - noftextblocks = noftextblocks + 1 - for n in traverse_id(hlist_code,tonut(head)) do - local subtype = getsubtype(n) - if subtype == line_code then - setattr(n,a_textblock,noftextblocks) - elseif subtype == glue_code or subtype == kern_code then -- no need to set fontkerns - setattr(n,a_textblock,0) + function builders.paragraphs.tag(head) + noftextblocks = noftextblocks + 1 + for n, subtype in nexthlist, head do + if subtype == linelist_code then + setattr(n,a_textblock,noftextblocks) + elseif subtype == glue_code or subtype == kern_code then -- no need to set fontkerns + setattr(n,a_textblock,0) + end end + return false end - return false + end do @@ -3237,13 +3477,12 @@ local htmltemplate = [[ local function allcontent(tree,embed) local result = { } - local embedded = embed and { } - flushtree(result,embedded,tree.data,"display") -- we need to collect images + flushtree(result,tree.data,"display") -- we need to collect images result = concat(result) -- no need to lpeg .. fast enough result = gsub(result,"\n *\n","\n") result = gsub(result,"\n +([^< ])","\n%1") - return result, embedded + return result end -- local xhtmlpreamble = [[ @@ -3498,7 +3737,6 @@ local htmltemplate = [[ local basename = file.basename local embedfile = false directives.register("export.embed",function(v) embedfile = v end) - local embedmath = false function structurestags.finishexport() @@ -3508,12 +3746,18 @@ local htmltemplate = [[ return end + local onlyxml = finetuning.export == v_xml + starttiming(treehash) -- finishexport() -- report_export("") - report_export("exporting xml, xhtml and html files") + if onlyxml then + report_export("exporting xml, no other files") + else + report_export("exporting xml, xhtml, html and css files") + end report_export("") -- wrapups.collapsetree(tree) @@ -3541,7 +3785,7 @@ local htmltemplate = [[ -- ./jobname-export/styles/jobname-images.css -- ./jobname-export/styles/jobname-templates.css - if type(askedname) ~= "string" or askedname == v_yes or askedname == "" then + if type(askedname) ~= "string" or askedname == "" then askedname = tex.jobname end @@ -3609,6 +3853,74 @@ local htmltemplate = [[ stylefilebase, } + local cssextra = cssfile and table.unique(settings_to_array(cssfile)) or { } + + -- at this point we're ready for the content; the collector also does some + -- housekeeping and data collecting; at this point we still have an xml + -- representation that uses verbose element names and carries information in + -- attributes + + local data = tree.data + for i=1,#data do + if data[i].tg ~= "document" then + data[i] = { } + end + end + + local result = allcontent(tree,embedmath) -- embedfile is for testing + + -- ugly but so be it: + + local extradata = structures.tags.getextradata() + if extradata then + local t = { "" } + t[#t+1] = "" + for name, action in sortedhash(extradata) do + t[#t+1] = action() + end + t[#t+1] = "" + t[#t+1] = "" + -- we use a function because otherwise we can have a bad capture index + result = gsub(result,"",function() + return concat(t,"\n") + end) + end + + -- done with ugly + + if onlyxml then + + os.remove(defaultfilename) + os.remove(imagefilename) + os.remove(stylefilename) + os.remove(templatefilename) + + for i=1,#cssextra do + os.remove(joinfile(stylepath,basename(source))) + end + + -- os.remove(xmlfilename) + + os.remove(imagefilename) + os.remove(stylefilename) + os.remove(templatefilename) + os.remove(xhtmlfilename) + os.remove(specificationfilename) + os.remove(htmlfilename) + + result = concat { + wholepreamble(true), + "\n", + result, + } + + report_export("saving xml data in %a",xmlfilename) + io.savedata(xmlfilename,result) + + return + + end + local examplefilename = resolvers.find_file("export-example.css") if examplefilename then local data = io.loaddata(examplefilename) @@ -3621,9 +3933,8 @@ local htmltemplate = [[ end if cssfile then - local list = table.unique(settings_to_array(cssfile)) - for i=1,#list do - local source = addsuffix(list[i],"css") + for i=1,#cssextra do + local source = addsuffix(cssextra[i],"css") local target = joinfile(stylepath,basename(source)) cssfiles[#cssfiles+1] = source if not lfs.isfile(source) then @@ -3638,21 +3949,6 @@ local htmltemplate = [[ local x_styles, h_styles = allusedstylesheets(cssfiles,files,"styles") - -- at this point we're ready for the content; the collector also does some - -- housekeeping and data collecting; at this point we still have an xml - -- representation that uses verbose element names and carries information in - -- attributes - - - local data = tree.data - for i=1,#data do - if data[i].tg ~= "document" then - data[i] = { } - end - end - - local result, embedded = allcontent(tree,embedmath) -- embedfile is for testing - local attach = backends.nodeinjections.attachfile if embedfile and attach then @@ -3666,22 +3962,6 @@ local htmltemplate = [[ mimetype = "application/mathml+xml", } end - -- if embedmath and attach then - -- local refs = { } - -- for k, v in sortedhash(embedded) do - -- attach { - -- data = v, - -- file = basename(k), - -- name = addsuffix(k,"xml"), - -- registered = k, - -- reference = k, - -- title = "xml export snippet: " .. k, - -- method = v_hidden, - -- mimetype = "application/mathml+xml", - -- } - -- refs[k] = 0 - -- end - -- end result = concat { wholepreamble(true), @@ -3711,14 +3991,14 @@ local htmltemplate = [[ local xmltree = cleanxhtmltree(xml.convert(result)) --- local xmltree = xml.convert(result) --- for c in xml.collected(xmltree,"m:mtext[lastindex()=1]/m:mrow") do --- print(c) --- end --- for c in xml.collected(xmltree,"mtext/mrow") do --- print(c) --- end --- local xmltree = cleanxhtmltree(xmltree) + -- local xmltree = xml.convert(result) + -- for c in xml.collected(xmltree,"m:mtext[lastindex()=1]/m:mrow") do + -- print(c) + -- end + -- for c in xml.collected(xmltree,"mtext/mrow") do + -- print(c) + -- end + -- local xmltree = cleanxhtmltree(xmltree) xml.save(xmltree,xhtmlfilename) @@ -3727,8 +4007,8 @@ local htmltemplate = [[ -- looking at identity is somewhat redundant as we also inherit from interaction -- at the tex end - local identity = interactions.general.getidentity() - local metadata = structures.tags.getmetadata() + local identity = interactions.general.getidentity() + local metadata = structures.tags.getmetadata() local specification = { name = usedname, @@ -3791,19 +4071,15 @@ local htmltemplate = [[ stoptiming(treehash) end - local appendaction = nodes.tasks.appendaction local enableaction = nodes.tasks.enableaction function structurestags.initializeexport() if not exporting then report_export("enabling export to xml") - -- not yet known in task-ini - appendaction("shipouts","normalizers", "nodes.handlers.export") - -- enableaction("shipouts","nodes.handlers.export") + enableaction("shipouts","nodes.handlers.export") enableaction("shipouts","nodes.handlers.accessibility") enableaction("math", "noads.handlers.tags") - -- appendaction("finalizers","lists","builders.paragraphs.tag") - -- enableaction("finalizers","builders.paragraphs.tag") + enableaction("everypar","nodes.handlers.checkparcounter") luatex.registerstopactions(structurestags.finishexport) exporting = true end @@ -3846,6 +4122,7 @@ implement { { "svgstyle" }, { "cssfile" }, { "file" }, + { "export" }, } } } @@ -3860,7 +4137,6 @@ implement { actions = structurestags.initializeexport, } - implement { name = "settagitemgroup", actions = structurestags.setitemgroup, @@ -3879,6 +4155,12 @@ implement { arguments = "2 strings", } +implement { + name = "settagformulacontent", + actions = structurestags.setformulacontent, + arguments = "integer", +} + implement { name = "settagdelimitedsymbol", actions = structurestags.settagdelimitedsymbol, @@ -3962,3 +4244,9 @@ implement { actions = structurestags.setlist, arguments = "integer" } + +implement { + name = "settagpublication", + actions = structurestags.setpublication, + arguments = "2 strings" +} diff --git a/tex/context/base/mkiv/back-exp.mkiv b/tex/context/base/mkiv/back-exp.mkiv index ad5ba8371..03dbe709a 100644 --- a/tex/context/base/mkiv/back-exp.mkiv +++ b/tex/context/base/mkiv/back-exp.mkiv @@ -17,7 +17,7 @@ %D This is an experimental exporter and a logical follow up on tagging. The %D exporter assumes a properly tagged document. Some elements get a couple -%D of attributes becaus eitherwise rendering information would get lost. In +%D of attributes because otherwise rendering information would get lost. In %D general we assume that when the \XML\ is converted to \HTML\ some stylesheet %D is applied anyway. @@ -241,6 +241,27 @@ \let\specialcontrolspace \explicitcontrolspace \to \everyenableelements +\appendtoks + \unexpanded\def\dotagregisterformula#1% + {\iftrialtypesetting\else + \clf_settagformulacontent#1\relax + \fi}% +\to \everyenableelements + +\appendtoks + \unexpanded\def\dotagmarginanchor#1% + {\iftrialtypesetting\else\clf_settagmarginanchor#1\relax\fi}% + \unexpanded\def\dotagmargintext#1% + {\iftrialtypesetting\else\clf_settagmargintext#1\relax\fi}% +\to \everyenableelements + +\appendtoks + \unexpanded\def\dotagpublication#1#2% + {\iftrialtypesetting\else + \clf_settagpublication{#1}{#2}\relax + \fi}% +\to \everyenableelements + % The action: \setupbackend[export=yes] % or filename % maybe xhtml css settings will move to setupexport @@ -261,18 +282,18 @@ \c!author={\directinteractionparameter\c!author}, % \c!firstpage=, % imagename % \c!lastpage=, % imagename - \c!alternative=, % html, div \c!properties=\v!no, % no: ignore, yes: as attribute, otherwise: use as prefix \c!hyphen=\v!no, \c!svgstyle=, \c!cssfile=, - \c!file={\backendparameter\c!export}] % downward compatibility + \c!file=] \resetsystemmode\v!export \unexpanded\def\doinitializeexport {\edef\p_export{\backendparameter\c!export}% \ifx\p_export\empty \else + % yes | xml \setuptagging[\c!state=\v!start]% \clf_initializeexport \setsystemmode\v!export @@ -300,6 +321,7 @@ svgstyle {\exportparameter\c!svgstyle}% cssfile {\exportparameter\c!cssfile}% file {\exportparameter\c!file}% + export {\backendparameter\c!export}% \relax} \unexpanded\def\dostopexport diff --git a/tex/context/base/mkiv/back-ini.lua b/tex/context/base/mkiv/back-ini.lua index fd33d5ddc..b7af1529b 100644 --- a/tex/context/base/mkiv/back-ini.lua +++ b/tex/context/base/mkiv/back-ini.lua @@ -6,34 +6,46 @@ if not modules then modules = { } end modules ['back-ini'] = { license = "see context related readme files" } --- -- how to create a shortcut: --- --- local function something(...) --- something = backends.codeinjections.something --- return something(...) --- end - local next, type = next, type local format = string.format +local sind, cosd, abs = math.sind, math.cosd, math.abs +local insert, remove = table.insert, table.remove +local unpack = unpack backends = backends or { } local backends = backends local trace_backend = false trackers.register("backend.initializers", function(v) trace_finalizers = v end) + +local report = logs.reporter("backend") local report_backend = logs.reporter("backend","initializing") local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex local setaction = nodes.tasks.setaction -local function nothing() return nil end +local scanners = tokens.scanners +local scannumber = scanners.number +local scankeyword = scanners.keyword +local scancount = scanners.count +local scanstring = scanners.string -backends.nothing = nothing +local scanners = interfaces.scanners + +local implement = interfaces.implement -local nodeinjections = { } -local codeinjections = { } -local registrations = { } -local tables = allocate() +local texset = tex.set + +local nodeinjections = { } +local codeinjections = { } +local registrations = { } +local tables = allocate() + +local function nothing() + return nil +end + +backends.nothing = nothing local function donothing(t,k) t[k] = nothing @@ -60,6 +72,17 @@ backends.tables = { } setmetatableindex(backends.tables, tables backends.current = "unknown" +local lmtx_mode = nil + +local function lmtxmode() + if lmtx_mode == nil then + lmtx_mode = ((tonumber(CONTEXTLMTXMODE) or 0) > 0) and drivers and drivers.lmtxversion + end + return lmtx_mode +end + +codeinjections.lmtxmode = lmtxmode + function backends.install(what) if type(what) == "string" then local backend = backends[what] @@ -73,7 +96,8 @@ function backends.install(what) end backends.current = what for category, default in next, defaults do - local target, plugin = backends[category], backend[category] + local target = backends[category] + local plugin = backend [category] setmetatableindex(plugin, default) setmetatableindex(target, plugin) end @@ -86,7 +110,13 @@ end statistics.register("used backend", function() local bc = backends.current if bc ~= "unknown" then - return format("%s (%s)",bc,backends[bc].comment or "no comment") + local lmtx = lmtxmode() + local cmnt = backends[bc].comment or "no comment" + if lmtx then + return format("lmtx version %0.2f, %s (%s)",lmtx,bc,cmnt) + else + return format("%s (%s)",bc,cmnt) + end else return nil end @@ -103,14 +133,6 @@ tables.vfspecials = allocate { stopslant = comment, } --- we'd better have this return something (defaults) - -function codeinjections.getpos () return 0, 0 end -function codeinjections.gethpos () return 0 end -function codeinjections.getvpos () return 0 end -function codeinjections.hasmatrix() return false end -function codeinjections.getmatrix() return 1, 0, 0, 1, 0, 0 end - -- can best be here interfaces.implement { @@ -139,3 +161,156 @@ backends.included = included function backends.timestamp() return os.date("%Y-%m-%dT%X") .. os.timezone(true) end + +-- Also here: + +local paper_width = 0 +local paper_height = 0 + +function codeinjections.setpagedimensions(paperwidth,paperheight) + if paperwidth then + paper_width = paperwidth + end + if paperheight then + paper_height = paperheight + end + if not lmtxmode() then + texset("global","pageheight",paper_height) + texset("global","pagewidth", paper_width) + end + return paper_width, paper_height +end + +function codeinjections.getpagedimensions() + return paper_width, paper_height +end + +implement { + name = "shipoutoffset", + actions = function() + context(lmtxmode() and "0pt" or "-1in") -- the old tex offset + end +} + +-- could also be codeinjections + +function backends.noflatelua() + return status.late_callbacks or 0 +end + +-- + +local stack = { } +local restore = true -- false + +local nodepool = nodes.pool +local savenode = nodepool.save +local restorenode = nodepool.restore +local setmatrixnode = nodepool.setmatrix + +updaters.register("backend.update",function() + savenode = nodepool.save + restorenode = nodepool.restore + setmatrixnode = nodepool.setmatrix +end) + +local function stopsomething() + local top = remove(stack) + if top == false then + -- not wrapped + elseif top == true then + context(restorenode()) + elseif top then + context(setmatrixnode(unpack(top))) -- not really needed anymore + context(restorenode()) + else + -- nesting error + end +end + +local function startrotation() + local a = scannumber() + if a == 0 then + insert(stack,false) + else + local s, c = sind(a), cosd(a) + if abs(s) < 0.000001 then + s = 0 -- otherwise funny -0.00000 + end + if abs(c) < 0.000001 then + c = 0 -- otherwise funny -0.00000 + end + context(savenode()) + context(setmatrixnode(c,s,-s,c)) + insert(stack,restore and { c, -s, s, c } or true) + end +end + +implement { name = "startrotation", actions = startrotation } +implement { name = "stoprotation", actions = stopsomething } + +local function startscaling() -- at the tex end we use sx and sy instead of rx and ry + local rx, ry = 1, 1 + while true do + if scankeyword("rx") then + rx = scannumber() + elseif scankeyword("ry") then + ry = scannumber() + -- elseif scankeyword("revert") then + -- local top = stack[#stack] + -- if top then + -- rx = top[1] + -- ry = top[4] + -- else + -- rx = 1 + -- ry = 1 + -- end + else + break + end + end + if rx == 1 and ry == 1 then + insert(stack,false) + else + if rx == 0 then + rx = 0.0001 + end + if ry == 0 then + ry = 0.0001 + end + context(savenode()) + context(setmatrixnode(rx,0,0,ry)) + insert(stack,restore and { 1/rx, 0, 0, 1/ry } or true) + end +end + +implement { name = "startscaling", actions = startscaling } +implement { name = "stopscaling", actions = stopsomething } + +local function startmatrix() -- rx sx sy ry -- tx, ty + local rx, sx, sy, ry = 1, 0, 0, 1 + while true do + if scankeyword("rx") then rx = scannumber() + elseif scankeyword("ry") then ry = scannumber() + elseif scankeyword("sx") then sx = scannumber() + elseif scankeyword("sy") then sy = scannumber() + else break end + end + if rx == 1 and sx == 0 and sy == 0 and ry == 1 then + insert(stack,false) + else + context(savenode()) + context(setmatrixnode(rx,sx,sy,ry)) + insert(stack,store and { -rx, -sx, -sy, -ry } or true) + end +end + +implement { name = "startmatrix", actions = startmatrix } +implement { name = "stopmatrix", actions = stopsomething } + +local function startmirroring() + context(setmatrixnode(-1,0,0,1)) +end + +implement { name = "startmirroring", actions = startmirroring } +implement { name = "stopmirroring", actions = startmirroring } -- not: stopsomething diff --git a/tex/context/base/mkiv/back-ini.mkiv b/tex/context/base/mkiv/back-ini.mkiv index e810ecde5..8729403f8 100644 --- a/tex/context/base/mkiv/back-ini.mkiv +++ b/tex/context/base/mkiv/back-ini.mkiv @@ -16,10 +16,23 @@ \writestatus{loading}{ConTeXt Backend Macros / Initialization} +%D The exact page model depends on the backend so we just define some +%D variables that are used. A helper at the \LUA\ end will synchronize +%D with the internal variables. We store these in the format. + +% \newdimen\backendpageheight +% \newdimen\backendpagewidth +% \newdimen\backendinchoffset \backendinchoffset=1in + +%D Now we load the \LUA\ code: + \registerctxluafile{back-ini}{} +\registerctxluafile{back-res}{} -%D We currently have a curious mix between tex and lua backend -%D handling but eventually most will move to lua. +\doifelsefileexists{back-out.mkiv}{\loadmarkfile{back-out}}{} + +%D We currently have a curious mix between tex and lua backend handling but +%D eventually most will move to \LUA. \unprotect @@ -27,54 +40,84 @@ \ifdefined\everylastbackendshipout \else \newtoks\everylastbackendshipout \fi \ifdefined\everybackendlastinshipout \else \newtoks\everybackendlastinshipout \fi % e.g. finalize via latelua -%D Right from the start \CONTEXT\ had a backend system based on -%D runtime pluggable code. As most backend issues involved specials -%D and since postprocessors had not that much in common, we ended up -%D with a system where we could switch backend as well as output code -%D for multiple backends at the same time. +%D Right from the start \CONTEXT\ had a backend system based on runtime pluggable +%D code. As most backend issues involved specials and since postprocessors had not +%D that much in common, we ended up with a system where we could switch backend as +%D well as output code for multiple backends at the same time. %D -%D Because \LUATEX\ has the backend built in, and since some backend -%D issues have been moved to the frontend I decided to provide new -%D backend code for \MKIV, starting with what was actually used. +%D Because \LUATEX\ has the backend built in, and since some backend issues have +%D been moved to the frontend I decided to provide new backend code for \MKIV, +%D starting with what was actually used. %D -%D At this moment \DVI\ is no longer used for advanced document -%D output and we therefore dropped support for this format. Future -%D versions might support more backends again, but this has a low -%D priority. +%D At this moment \DVI\ is no longer used for advanced document output and we +%D therefore dropped support for this format. Future versions might support more +%D backends again, but this has a low priority. %D -%D Not everything here makes sense and the content of this file will -%D definitely change (or even go away). +%D Not everything here makes sense and the content of this file will definitely +%D change (or even go away). + +% rotation + +\unexpanded\def\dostartrotation#1% + {\forcecolorhack + \clf_startrotation#1\relax} % todo: implement without Q q + +\unexpanded\def\dostoprotation + {\clf_stoprotation + \forcecolorhack} + +% scaling + +\unexpanded\def\dostartscaling#1#2% + {\forcecolorhack + \clf_startscaling rx #1 ry #2\relax} -\let \dostartrotation \gobbleoneargument -\let \dostoprotation \donothing -\let \dostartscaling \gobbletwoarguments -\let \dostopscaling \donothing -\let \dostartmirroring \donothing -\let \dostopmirroring \donothing -\let \dotransformnextbox\gobblesixarguments % and pass last box +\unexpanded\def\dostopscaling + {\clf_stopscaling + \forcecolorhack} + +% mirroring + +\unexpanded\def\dostartmirroring + {\clf_startmirroring} + +\unexpanded\def\dostopmirroring + {\clf_stopmirroring} + +% transform + +\unexpanded\def\dotransformnextbox#1#2#3#4#5#6% + {\dowithnextbox{\dodotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}}} + +\unexpanded\def\dodotransformnextbox#1#2#3#4#5#6% + {\hpack + {\kern #5\onebasepoint + \raise#6\onebasepoint + \hpack + {\clf_startmatrix rx #1 sx #2 sy #3 ry #4\relax + \box\nextbox + \clf_stopmatrix}}} %D \macros %D {back_ovalbox} %D -%D When we look at the implementation, this is a complicated -%D one. There are seven arguments. +%D When we look at the implementation, this is a complicated one. There are seven +%D arguments. %D %D \starttyping %D \back_ovalbox {w} {h} {d} {linewidth} {radius} {stroke} {fill} {variant} %D \stoptyping %D -%D This command has to return a \type{\vbox} which can be used -%D to lay over another one (with text). The radius is in -%D degrees, the stroke and fill are~\type{1} (true) of~\type{0} -%D (false). +%D This command has to return a \type {\vbox} which can be used to lay over another +%D one (with text). The radius is in degrees, the stroke and fill are~\type {1} +%D (true) of~\type {0} (false). \let\back_ovalbox \gobbleeightarguments %D \macros %D {dostartclipping,dostopclipping} %D -%D Clipping is implemented in such a way that an arbitrary code -%D can be fed. +%D Clipping is implemented in such a way that an arbitrary code can be fed. %D %D \starttyping %D \dostartclipping {pathname} {width} {height} @@ -87,9 +130,8 @@ %D \macros %D {jobsuffix} %D -%D By default, \TEX\ produces \DVI\ files which can be -%D converted to other filetypes. Sometimes it is handy to -%D know what the target file will be. In other driver +%D By default, \TEX\ produces \DVI\ files which can be converted to other filetypes. +%D Sometimes it is handy to know what the target file will be. In other driver %D modules we wil set \type {\jobsuffix} to \type {pdf}. %D Backend configuration: @@ -113,6 +155,12 @@ \clf_setrealspaces{\backendparameter\c!space}% \to \everysetupbackend +\appendtoks + \ifdefined\clf_resetmapfile + \clf_resetmapfile + \fi +\to \everysetupbackend + %D For older styles: \let\setupoutput\gobbleoneoptional diff --git a/tex/context/base/mkiv/back-pdf.lua b/tex/context/base/mkiv/back-pdf.lua index f45783e51..8886967e0 100644 --- a/tex/context/base/mkiv/back-pdf.lua +++ b/tex/context/base/mkiv/back-pdf.lua @@ -6,302 +6,21 @@ if not modules then modules = { } end modules ['back-pdf'] = { license = "see context related readme files" } --- we could do \pdfmatrix sx <> sy <> etc +-- We hide the pdf table from users so that we can guarantee no interference with +-- the way we manage resources, info, etc. Users should use the \type {lpdf} +-- interface instead. If needed I will provide replacement functionality. -local sind, cosd = math.sind, math.cosd -local insert, remove = table.insert, table.remove - -local codeinjections = backends.pdf.codeinjections - -local context = context - -local scanners = tokens.scanners -local scannumber = scanners.number -local scankeyword = scanners.keyword -local scandimen = scanners.dimen -local scancount = scanners.count -local scanstring = scanners.string - -local scanners = interfaces.scanners -local implement = interfaces.implement - -local report = logs.reporter("backend") - -local outputfilename - -function codeinjections.getoutputfilename() - if not outputfilename then - outputfilename = file.addsuffix(tex.jobname,"pdf") - end - return outputfilename -end - -backends.install("pdf") - -local f_matrix = string.formatters["%F %F %F %F"] -- 0.8 is default - -scanners.pdfrotation = function() -- a - -- todo: check for 1 and 0 and flush sparse - local a = scannumber() - local s, c = sind(a), cosd(a) - context(f_matrix(c,s,-s,c)) -end - --- experimental code (somewhat weird here) .. todo: nodeinjections .. this will only work --- out well if we also calculate the accumulated cm and wrap inclusions / annotations in --- the accumulated ... it's a mess --- --- we could also do the save restore wrapping here + colorhack - -local pdfsave = nodes.pool.pdfsave -local pdfrestore = nodes.pool.pdfrestore -local pdfsetmatrix = nodes.pool.pdfsetmatrix - -local stack = { } -local restore = true -- false - -scanners.pdfstartrotation = function() - local a = scannumber() - if a == 0 then - insert(stack,false) - else - local s, c = sind(a), cosd(a) - context(pdfsave()) - context(pdfsetmatrix(c,s,-s,c)) - insert(stack,restore and { c, -s, s, c } or true) - end -end - -scanners.pdfstartscaling = function() -- at the tex end we use sx and sy instead of rx and ry - local rx, ry = 1, 1 - while true do - if scankeyword("rx") then - rx = scannumber() - elseif scankeyword("ry") then - ry = scannumber() - -- elseif scankeyword("revert") then - -- local top = stack[#stack] - -- if top then - -- rx = top[1] - -- ry = top[4] - -- else - -- rx = 1 - -- ry = 1 - -- end - else - break - end - end - if rx == 1 and ry == 1 then - insert(stack,false) - else - if rx == 0 then - rx = 0.0001 - end - if ry == 0 then - ry = 0.0001 - end - context(pdfsave()) - context(pdfsetmatrix(rx,0,0,ry)) - insert(stack,restore and { 1/rx, 0, 0, 1/ry } or true) - end -end - -scanners.pdfstartmatrix = function() -- rx sx sy ry -- tx, ty - local rx, sx, sy, ry = 1, 0, 0, 1 - while true do - if scankeyword("rx") then rx = scannumber() - elseif scankeyword("ry") then ry = scannumber() - elseif scankeyword("sx") then sx = scannumber() - elseif scankeyword("sy") then sy = scannumber() - else break end - end - if rx == 1 and sx == 0 and sy == 0 and ry == 1 then - insert(stack,false) - else - context(pdfsave()) - context(pdfsetmatrix(rx,sx,sy,ry)) - insert(stack,store and { -rx, -sx, -sy, -ry } or true) - end -end - -local function pdfstopsomething() - local top = remove(stack) - if top == false then - -- not wrapped - elseif top == true then - context(pdfrestore()) - elseif top then - context(pdfsetmatrix(unpack(top))) -- not really needed anymore - context(pdfrestore()) - else - -- nesting error - end -end - -scanners.pdfstoprotation = pdfstopsomething -scanners.pdfstopscaling = pdfstopsomething -scanners.pdfstopmatrix = pdfstopsomething - -scanners.pdfstartmirroring = function() - context(pdfsetmatrix(-1,0,0,1)) -end - -if environment.arguments.nocompression then - lpdf.setcompression(0,0,true) -end - -scanners.pdfstopmirroring = scanners.pdfstartmirroring - --- todo, change the above to implement too -- - -implement { - name = "setmapfile", - arguments = "string", - actions = pdf.mapfile -} - -implement { - name = "setmapline", - arguments = "string", - actions = pdf.mapline -} - -implement { +interfaces.implement { name = "setpdfcompression", arguments = { "integer", "integer" }, actions = lpdf.setcompression, } -local report = logs.reporter("backend","pdftex primitives") -local trace = false - -scanners.pdfannot = function() - if scankeyword("reserveobjectnum") then - report("\\pdfannot reserveobjectnum is not (yet) supported") - -- if trace then - -- report() - -- report("\\pdfannot: reserved number (not supported yet)") - -- report() - -- end - else - local width = false - local height = false - local depth = false - local data = false - local object = false - local attr = false - -- - if scankeyword("useobjnum") then - object = scancount() - report("\\pdfannot useobjectnum is not (yet) supported") - end - while true do - if scankeyword("width") then - width = scandimen() - elseif scankeyword("height") then - height = scandimen() - elseif scankeyword("depth") then - depth = scandimen() - else - break - end - end - if scankeyword("attr") then - attr = scanstring() - end - data = scanstring() - -- - -- less strict variant: - -- - -- while true do - -- if scankeyword("width") then - -- width = scandimen() - -- elseif scankeyword("height") then - -- height = scandimen() - -- elseif scankeyword("depth") then - -- depth = scandimen() - -- elseif scankeyword("useobjnum") then - -- object = scancount() - -- elseif scankeyword("attr") then - -- attr = scanstring() - -- else - -- data = scanstring() - -- break - -- end - -- end - -- - -- if trace then - -- report() - -- report("\\pdfannot:") - -- report() - -- report(" object: %s",object or " (not supported yet)") - -- report(" width : %p",width or "") - -- report(" height: %p",height or "") - -- report(" depth : %p",depth or "") - -- report(" attr : %s",attr or "") - -- report(" data : %s",data or "") - -- report() - -- end - context(backends.nodeinjections.annotation(width or 0,height or 0,depth or 0,data or "")) - end +if CONTEXTLMTXMODE == 0 then + updaters.apply("backend.update.pdf") + updaters.apply("backend.update.lpdf") + updaters.apply("backend.update.tex") + updaters.apply("backend.update") end -scanners.pdfdest = function() - local name = false - local zoom = false - local view = false - local width = false - local height = false - local depth = false - if scankeyword("num") then - report("\\pdfdest num is not (yet) supported") - elseif scankeyword("name") then - name = scanstring() - end - if scankeyword("xyz") then - view = "xyz" - if scankeyword("zoom") then - report("\\pdfdest zoom is ignored") - zoom = scancount() -- will be divided by 1000 in the backend - end - elseif scankeyword("fitbh") then - view = "fitbh" - elseif scankeyword("fitbv") then - view = "fitbv" - elseif scankeyword("fitb") then - view = "fitb" - elseif scankeyword("fith") then - view = "fith" - elseif scankeyword("fitv") then - view = "fitv" - elseif scankeyword("fitr") then - view = "fitr" - while true do - if scankeyword("width") then - width = scandimen() - elseif scankeyword("height") then - height = scandimen() - elseif scankeyword("depth") then - depth = scandimen() - else - break - end - end - elseif scankeyword("fit") then - view = "fit" - end - -- if trace then - -- report() - -- report("\\pdfdest:") - -- report() - -- report(" name : %s",name or "") - -- report(" view : %s",view or "") - -- report(" zoom : %s",zoom or " (not supported)") - -- report(" width : %p",width or "") - -- report(" height: %p",height or "") - -- report(" depth : %p",depth or "") - -- report() - -- end - context(backends.nodeinjections.destination(width or 0,height or 0,depth or 0,{ name or "" },view or "fit")) -end +backends.install("pdf") diff --git a/tex/context/base/mkiv/back-pdf.mkiv b/tex/context/base/mkiv/back-pdf.mkiv index 3b0dd7852..9e88ab193 100644 --- a/tex/context/base/mkiv/back-pdf.mkiv +++ b/tex/context/base/mkiv/back-pdf.mkiv @@ -11,11 +11,10 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -%D The less ther ei shere, the better. +%D The less there is here, the better. \writestatus{loading}{ConTeXt Backend Macros / PDF} -%registerctxluafile{lpdf-aux}{optimize} % common helpers \registerctxluafile{lpdf-ini}{optimize} \registerctxluafile{lpdf-nod}{} \registerctxluafile{lpdf-col}{} @@ -32,9 +31,22 @@ \registerctxluafile{lpdf-swf}{} % this will become a module \registerctxluafile{lpdf-tag}{} \registerctxluafile{lpdf-fmt}{} -\registerctxluafile{lpdf-epd}{} +\registerctxluafile{lpdf-pde}{} + +\ifcase\contextlmtxmode\else + \registerctxluafile{lpdf-img}{optimize} +\fi + \registerctxluafile{lpdf-epa}{} +\ifcase\contextlmtxmode\else + \registerctxluafile{lpdf-emb}{optimize} +\fi + +\registerctxluafile{back-pdp}{} + +\registerctxluafile{lpdf-fnt}{} + \registerctxluafile{back-pdf}{} % some code will move to lpdf-* \loadmarkfile{back-u3d} % this will become a module @@ -47,26 +59,53 @@ %D %D Here we initialize some internal quantities. We also protect them. -\outputmode\plusone \let\outputmode\relax \newcount\outputmode \outputmode\plusone +\ifdefined\outputmode + \outputmode\plusone + \let\outputmode\relax + \newcount\outputmode + \outputmode\plusone + \let\normaloutputmode\outputmode +\fi %D Because we do a lot in \LUA\ and don't want interferences, we nil most of the %D \PDFTEX\ primitives. Of course one can always use the \type {\pdfvariable}, %D \type {\pdfextension} and \type {\pdffeedback} primitives but it will probably %D have bad side effects. +%D For the moment we put these here as they are pdf related but they might move to +%D a better place. We overload the primitives with our own but use a bit of indirection +%D for the purpose of tracing. + +\unexpanded\def\saveboxresource {\clf_saveboxresource} +\unexpanded\def\lastsavedboxresourceindex {\numexpr\clf_lastsavedboxresourceindex\relax} +\unexpanded\def\useboxresource {\clf_useboxresource} + +\unexpanded\def\saveimageresource {\clf_saveimageresource} +\unexpanded\def\lastsavedimageresourceindex{\numexpr\clf_lastsavedimageresourceindex\relax} +\unexpanded\def\lastsavedimageresourcepages{\numexpr\clf_lastsavedimageresourcepages\relax} +\unexpanded\def\useimageresource {\clf_useimageresource} + +\unexpanded\def\savepos {\clf_savepos} + \def\lastxpos {\clf_lastxpos} + \def\lastypos {\clf_lastypos} + +\unexpanded\def\pdfextension {\clf_pdfextension} + \def\pdffeedback {\clf_pdffeedback} + %D These are no-ops and don't even intercept what comes next. Maybe some day %D I'll write a parser that maps onto \CONTEXT. \unexpanded\def\unsupportedpdfprimitive#1% - {\writestatus{error}{the primitive \string#1\space is not supported}} + {\writestatus{fatal error}{the primitive \string#1\space is not supported}% + \directlua{os.exit()}} \unexpanded\def\pdfcolorstack {\unsupportedpdfprimitive\pdfcolorstack} \unexpanded\def\pdfcolorstackinit{\unsupportedpdfprimitive\pdfcolorstackinit} -%unexpanded\def\pdfannot {\unsupportedpdfprimitive\pdfannot} +% pdfannot \unexpanded\def\pdfstartlink {\unsupportedpdfprimitive\pdfstartlink} \unexpanded\def\pdfendlink {\unsupportedpdfprimitive\pdfendlink} \unexpanded\def\pdfoutline {\unsupportedpdfprimitive\pdfoutline} -%unexpanded\def\pdfdest {\unsupportedpdfprimitive\pdfdest} +% pdfdest \unexpanded\def\pdfthread {\unsupportedpdfprimitive\pdfthread} \unexpanded\def\pdfstartthread {\unsupportedpdfprimitive\pdfstartthread} \unexpanded\def\pdfendthread {\unsupportedpdfprimitive\pdfendthread} @@ -97,23 +136,24 @@ %D But we still provide: -\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} -\unexpanded\def\maximumpdfcompression {\clf_setpdfcompression\plusnine \plusnine } -\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} +\unexpanded\def\nopdfcompression {\clf_setpdfcompression\zerocount\zerocount} +\unexpanded\def\onlypdfobjectcompression{\clf_setpdfcompression\zerocount\plusthree} +\unexpanded\def\maximumpdfcompression {\clf_setpdfcompression\plusnine \plusnine } +\unexpanded\def\normalpdfcompression {\clf_setpdfcompression\plusthree\plusthree} %D These might even become no-ops as we don't need them in \CONTEXT: -\unexpanded\def\pdfmapfile#1{\clf_setmapfile{#1}} -\unexpanded\def\pdfmapline#1{\clf_setmapline{#1}} +\unexpanded\def\pdfmapfile#1{} % obsolete +\unexpanded\def\pdfmapline#1{} % obsolete %D We don't support these directives, at least not this way. If they are needed %D by third party modules we can provide some interface. -% \pdfcreationdate +%pdfcreationdate \let\pdfdecimaldigits \relax \newcount\pdfdecimaldigits \let\pdfdestmargin \relax \newdimen\pdfdestmargin -% \pdffontname -% \pdffontobjnum +% pdffontname +% pdffontobjnum \let\pdffontsize \relax \newcount\pdffontsize \let\pdfgamma \relax \newcount\pdfgamma \let\pdfgentounicode \relax \newcount\pdfgentounicode @@ -128,21 +168,21 @@ \let\pdfinclusioncopyfonts \relax \newcount\pdfinclusioncopyfonts \let\pdfinclusionerrorlevel \relax \newcount\pdfinclusionerrorlevel \let\pdfinfoomitdate \relax \newcount\pdfinfoomitdate -% \pdflastannot -% \pdflastlink +% pdflastannot +% pdflastlink \let\pdflinkmargin \relax \newdimen\pdflinkmargin \let\pdfmajorversion \relax \newcount\pdfmajorversion \let\pdfminorversion \relax \newcount\pdfminorversion \let\pdfpagebox \relax \newcount\pdfpagebox -% \pdfpageref +% pdfpageref \let\pdfpkfixeddpi \relax \newcount\pdfpkfixeddpi \let\pdfpkmode \relax \newtoks \pdfpkmode \let\pdfpkresolution \relax \newcount\pdfpkresolution -% \pdfretval +% pdfretval \let\pdfsuppressoptionalinfo \relax \newcount\pdfsuppressoptionalinfo \let\pdfsuppressptexinfo \relax \newcount\pdfsuppressptexinfo -% \pdftexrevision -% \pdftexversion +% pdftexrevision +% pdftexversion \let\pdfthreadmargin \relax \newdimen\pdfthreadmargin \let\pdftrailerid \relax \newtoks \pdftrailerid \let\pdfuniqueresname \relax \newcount\pdfuniqueresname @@ -152,27 +192,33 @@ %D These are still accepted but are normally not needed. +\let\pdfxform \saveboxresource +\let\pdfximage \saveimageresource + \let\pdflastxform \lastsavedboxresourceindex \let\pdflastximage \lastsavedimageresourceindex -\let\pdflastximagepages \lastsavedimageresourcepages -\let\pdflastxpos \lastxpos -\let\pdflastypos \lastypos + \let\pdfrefxform \useboxresource \let\pdfrefximage \useimageresource + +\let\pdflastximagepages \lastsavedimageresourcepages + \let\pdfsavepos \savepos -\let\pdfxform \saveboxresource -\let\pdfximage \saveimageresource +\let\pdflastxpos \lastxpos +\let\pdflastypos \lastypos %D For the moment we keep these as they are but they will become \LUA\ calls %D eventually, after which we will nil the three \type {\pdf} interface primitives. -\normalprotected\def\pdfliteral {\pdfextension literal } -\normalprotected\def\pdfobj {\pdfextension obj } - \def\pdflastobj {\numexpr\pdffeedback lastobj\relax} +\normalprotected\def\pdfliteral {\clf_pdfliteral}% + +\normalprotected\def\pdfobj {\clf_pdfobj}% +\normalprotected\def\pdflastobj {\numexpr\clf_pdflastobj\relax}% + \normalprotected\def\pdfrefobj {\pdfextension refobj } -\normalprotected\def\pdfrestore {\pdfextension restore\relax} -\normalprotected\def\pdfsave {\pdfextension save\relax} -\normalprotected\def\pdfsetmatrix{\pdfextension setmatrix } +\normalprotected\def\pdfrestore {\clf_restore} +\normalprotected\def\pdfsave {\clf_save} +\normalprotected\def\pdfsetmatrix{\clf_setmatrix} %D This one can be consulted by users although the suffix is also a system mode. @@ -225,84 +271,6 @@ \def\pdfcolor #1{\clf_lpdf_color\numexpr\thecolorattribute{#1}\relax} \let\PDFcolor\pdfcolor -%D Transformations - -% rotation - -\unexpanded\def\dostartrotation#1% - {\forcecolorhack - \clf_pdfstartrotation#1\relax} % todo: implement without Q q - -\unexpanded\def\dostoprotation - {\clf_pdfstoprotation - \forcecolorhack} - -% scaling - -\unexpanded\def\dostartscaling#1#2% - {\forcecolorhack - \clf_pdfstartscaling rx #1 ry #2\relax} - -\unexpanded\def\dostopscaling - {\clf_pdfstopscaling - \forcecolorhack} - -% mirroring - -\unexpanded\def\dostartmirroring - {\clf_pdfstartmirroring} - -\unexpanded\def\dostopmirroring - {\clf_pdfstopmirroring} - -% transform - -\unexpanded\def\dotransformnextbox#1#2#3#4#5#6% - {\dowithnextbox{\dodotransformnextbox{#1}{#2}{#3}{#4}{#5}{#6}}} - -\unexpanded\def\dodotransformnextbox#1#2#3#4#5#6% - {\hpack - {\kern #5\onebasepoint - \raise#6\onebasepoint - \hpack - {\clf_pdfstartmatrix rx #1 sx #2 sy #3 ry #4\relax - \box\nextbox - \clf_pdfstopmatrix}}} - -% somehow the shift is not happening .. bug in luatex? -% -% \unexpanded\def\dodotransformnextbox#1#2#3#4#5#6% -% {\ctxcommand{pdftransformbox(\number\nextbox,#1,#2,#3,#4,\number\dimexpr#5\onebasepoint,\number\dimexpr#6\onebasepoint)}% -% \box\nextbox} -% -% \startluacode -% function commands.pdftransformbox(box,rx,sx,sy,ry,tx,ty) -% if rx == 1 and sx == 0 and sy == 0 and ry == 1 then -% if tx == 0 and ty == 0 then -% local b = nodes.hpack(nodes.concat { -% nodes.pool.kern(tx), -% nodes.takebox(box), -% }) -% b.shift = -ty -% tex.setbox(box,b) -% else -% -- no need to transform -% end -% else -% local b = nodes.hpack(nodes.concat { -% nodes.pool.kern(tx), -% nodes.pool.pdfsave(), -% nodes.pool.pdfsetmatrix(rx,sx,sy,ry), -% nodes.takebox(box), -% nodes.pool.pdfsetmatrix(-rx,-sx,-sy,-ry), -% nodes.pool.pdfrestore(), -% }) -% b.shift = -ty -% tex.setbox(box,b) -% end -% end -% \stopluacode - % clipping \unexpanded\def\dostartclipping#1#2#3% we can move this to lua and only set a box here diff --git a/tex/context/base/mkiv/back-pdp.lua b/tex/context/base/mkiv/back-pdp.lua new file mode 100644 index 000000000..7363cfcae --- /dev/null +++ b/tex/context/base/mkiv/back-pdp.lua @@ -0,0 +1,453 @@ +if not modules then modules = { } end modules ['back-pdp'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is temporary ... awaiting a better test .. basically we can +-- always use this: pdf primitives. + +local context = context + +local lpdfreserveobject = lpdf.reserveobject +local lpdfcompresslevel = lpdf.compresslevel +local lpdfobj = lpdf.obj +local lpdfpagereference = lpdf.pagereference +local lpdfxformname = lpdf.xformname + +local jobpositions = job.positions +local gethpos = jobpositions.gethpos +local getvpos = jobpositions.getvpos + +local tokenscanners = tokens.scanners +local scanword = tokenscanners.word +local scankeyword = tokenscanners.keyword +local scanstring = tokenscanners.string +local scaninteger = tokenscanners.integer +local scandimension = tokenscanners.dimension + +local trace = false trackers.register("commands", function(v) trace = v end) +local report = logs.reporter("command") + +local nodepool = nodes.pool +local newsavepos = nodepool.savepos +local newliteral = nodepool.literal +local newsave = nodepool.save +local newrestore = nodepool.restore +local newsetmatrix = nodepool.setmatrix + +local implement = interfaces.implement +local constants = interfaces.constants +local variables = interfaces.variables + +-- helper + +local function scanwhd() + local width, height, depth + while true do + if scankeyword("width") then + width = scandimension() + elseif scankeyword("height") then + height = scandimension() + elseif scankeyword("depth") then + depth = scandimension() + else + break + end + end + if width or height or depth then + return width or 0, height or 0, depth or 0 + else + -- we inherit + end +end + +-- positions + +local function savepos() + context(newsavepos()) +end + +local function lastxpos() + context(gethpos()) +end + +local function lastypos() + context(getvpos()) +end + +implement { name = "savepos", actions = savepos } +implement { name = "lastxpos", actions = lastxpos } +implement { name = "lastypos", actions = lastypos } + +-- literals + +local function pdfliteral() + context(newliteral(scanword() or "origin",scanstring())) +end + +implement { name = "pdfliteral", actions = pdfliteral } + +-- box resources + +local boxresources = tex.boxresources +local savebox = boxresources.save +local usebox = boxresources.use + +local lastindex = 0 + +local function saveboxresource() + local immediate = true + local kind = scankeyword("type") and scaninteger() or 0 + local attributes = scankeyword("attr") and scanstring() or nil + local resources = scankeyword("resources") and scanstring() or nil + local margin = scankeyword("margin") and scandimension() or 0 -- register + local boxnumber = scaninteger() + -- + lastindex = savebox(boxnumber,attributes,resources,immediate,kind,margin) + if trace then + report("\\saveboxresource: index %i",lastindex) + end +end + +local function lastsavedboxresourceindex() + if trace then + report("\\lastsaveboxresource: index %i",lastindex) + end + context("%i",lastindex) +end + +local function useboxresource() + local width, height, depth = scanwhd() + local index = scaninteger() + local node = usebox(index,width,height,depth) + if trace then + report("\\useboxresource: index %i",index) + end + context(node) +end + +implement { name = "saveboxresource", actions = saveboxresource } +implement { name = "lastsavedboxresourceindex", actions = lastsavedboxresourceindex } +implement { name = "useboxresource", actions = useboxresource } + +-- image resources (messy: will move) + +local imageresources = { } +local lastindex = 0 +local lastpages = 1 + +local function saveimageresource() + local width, height, depth = scanwhd() + local page = 1 + local immediate = true + local margin = 0 -- or dimension + local attributes = scankeyword("attr") and scanstring() or nil + if scankeyword("named") then + scanstring() -- ignored + elseif scankeyword("page") then + page = scaninteger() + end + local userpassword = scankeyword("userpassword") and scanstring() or nil + local ownerpassword = scankeyword("ownerpassword") and scanstring() or nil + local visiblefilename = scankeyword("visiblefilename") and scanstring() or nil + local colorspace = scankeyword("colorspace") and scaninteger() or nil + local pagebox = scanword() or nil + local filename = scanstring() +-- pcall + context.getfiguredimensions( { filename }, { + [constants.userpassword] = userpassword, + [constants.ownerpassword] = ownerpassword, + [constants.page] = page or 1, + [constants.size] = pagebox, + }) + context.relax() + lastindex = lastindex + 1 + lastpages = 1 + imageresources[lastindex] = { + filename = filename, + page = page or 1, + size = pagebox, + width = width, + height = height, + depth = depth, + attr = attributes, + -- margin = margin, + } +end + +local function lastsavedimageresourceindex() + context("%i",lastindex or 0) +end + +local function lastsavedimageresourcepages() + context("%i",lastpages or 0) -- todo +end + +local function useimageresource() + local width, height, depth = scanwhd() + if scankeyword("keepopen") then + -- ignored + end + local index = scaninteger() + local l = imageresources[index] + if l then + if not (width or height or depth) then + width = l.width + height = l.height + depth = l.depth + end +-- pcall + context.externalfigure( { l.filename }, { + [constants.userpassword] = l.userpassword, + [constants.ownerpassword] = l.ownerpassword, + [constants.width] = width and (width .. "sp") or nil, + [constants.height] = height and (height .. "sp") or nil, + [constants.page] = l.page or 1, + [constants.size] = pagebox, + }) + context.relax() + else + print("no image resource",index) + end +end + +implement { name = "saveimageresource", actions = saveimageresource } +implement { name = "lastsavedimageresourceindex", actions = lastsavedimageresourceindex } +implement { name = "lastsavedimageresourcepages", actions = lastsavedimageresourcepages } +implement { name = "useimageresource", actions = useimageresource } + +-- objects + +local lastobjnum = 0 + +local function pdfobj() + if scankeyword("reserveobjnum") then + lastobjnum = lpdfreserveobject() + if trace then + report("\\pdfobj reserveobjnum: object %i",lastobjnum) + end + else + local immediate = true + local objnum = scankeyword("useobjnum") and scaninteger() or lpdfreserveobject() + local uncompress = scankeyword("uncompressed") or lpdfcompresslevel() == 0 + local streamobject = scankeyword("stream") and true or false + local attributes = scankeyword("attr") and scanstring() + local fileobject = scankeyword("file") + local content = scanstring() + local object = { + immediate = immediate, + attr = attributes, + objnum = objnum, + type = streamobject and "stream" or nil, + compresslevel = uncompress and 0 or nil, + } + if fileobject then + object.filename = content + else + object.string = content + end + lpdfobj(object) + lastobjnum = objnum + if trace then + report("\\pdfobj: object %i",lastobjnum) + end + end +end + +local function pdflastobj() + context("%i",lastobjnum) + if trace then + report("\\lastobj: object %i",lastobjnum) + end +end + +local function pdfrefobj() + local objnum = scaninteger() + if trace then + report("\\refobj: object %i (todo)",objnum) + end +end + +implement { name = "pdfobj", actions = pdfobj } +implement { name = "pdflastobj", actions = pdflastobj } +implement { name = "pdfrefobj", actions = pdfrefobj } + +-- annotations + +local lastobjnum = 0 + +local function pdfannot() + if scankeyword("reserveobjnum") then + lastobjnum = lpdfreserveobject() + if trace then + report("\\pdfannot reserveobjnum: object %i",lastobjnum) + end + else + local width = false + local height = false + local depth = false + local data = false + local object = false + local attr = false + -- + if scankeyword("useobjnum") then + object = scancount() + report("\\pdfannot useobjectnum is not (yet) supported") + end + local width, height, depth = scanwhd() + if scankeyword("attr") then + attr = scanstring() + end + data = scanstring() + context(backends.nodeinjections.annotation(width or 0,height or 0,depth or 0,data or "")) + end +end + +implement { name = "pdfannot", actions = pdfannot } + +local function pdfdest() + local name = false + local zoom = false + local view = false + local width = false + local height = false + local depth = false + if scankeyword("num") then + report("\\pdfdest num is not (yet) supported") + elseif scankeyword("name") then + name = scanstring() + end + if scankeyword("xyz") then + view = "xyz" + if scankeyword("zoom") then + report("\\pdfdest zoom is ignored") + zoom = scancount() -- will be divided by 1000 in the backend + end + elseif scankeyword("fitbh") then + view = "fitbh" + elseif scankeyword("fitbv") then + view = "fitbv" + elseif scankeyword("fitb") then + view = "fitb" + elseif scankeyword("fith") then + view = "fith" + elseif scankeyword("fitv") then + view = "fitv" + elseif scankeyword("fitr") then + view = "fitr" + width, height, depth = scanwhd() + elseif scankeyword("fit") then + view = "fit" + end + context(backends.nodeinjections.destination(width or 0,height or 0,depth or 0,{ name or "" },view or "fit")) +end + +implement { name = "pdfdest", actions = pdfdest } + +-- management + + +local function pdfsave() + context(newsave()) +end + +local function pdfrestore() + context(newrestore()) +end + +local function pdfsetmatrix() + context(newsetmatrix(scanstring())) +end + + +-- extras + +local function pdfpageref() + context(lpdfpagereference()) +end + +local function pdfxformname() + context(lpdfxformname()) +end + +-- extensions: literal dest annot save restore setmatrix obj refobj colorstack +-- startlink endlink startthread endthread thread outline glyphtounicode fontattr +-- mapfile mapline includechars catalog info names trailer + +local extensions = { + literal = pdfliteral, + obj = pdfobj, + refobj = pdfrefobj, + dest = pdfdest, + annot = pdfannot, + save = pdfsave, + restore = pdfrestore, + setmatrix = pdfsetmatrix, +} + +local function pdfextension() + local w = scanword() + if w then + local e = extensions[w] + if e then + e() + else + report("\\pdfextension: unknown %a",w) + end + end +end + +implement { name = "pdfextension", actions = pdfextension } + +-- feedbacks: colorstackinit creationdate fontname fontobjnum fontsize lastannot +-- lastlink lastobj pageref retval revision version xformname + +local feedbacks = { + lastobj = pdflastobj, + pageref = pdfpageref, + xformname = pdfxformname, +} + +local function pdffeedback() + local w = scanword() + if w then + local f = feedbacks[w] + if f then + f() + else + report("\\pdffeedback: unknown %a",w) + end + end +end + +implement { name = "pdffeedback", actions = pdffeedback } + +-- variables: (integers:) compresslevel decimaldigits gamma gentounicode +-- ignoreunknownimages imageaddfilename imageapplygamma imagegamma imagehicolor +-- imageresolution inclusioncopyfonts inclusionerrorlevel majorversion minorversion +-- objcompresslevel omitcharset omitcidset pagebox pkfixeddpi pkresolution +-- recompress suppressoptionalinfo uniqueresname (dimensions:) destmargin horigin +-- linkmargin threadmargin vorigin xformmargin (tokenlists:) pageattr pageresources +-- pagesattr pkmode trailerid xformattr xformresources + +-- local variables = { +-- } +-- +-- local function pdfvariable() +-- local w = scanword() +-- if w then +-- local f = variables[w] +-- if f then +-- f() +-- else +-- print("invalid variable",w) +-- end +-- else +-- print("missing variable") +-- end +-- end + +--------- { name = "pdfvariable", actions = pdfvariable } diff --git a/tex/context/base/mkiv/back-res.lua b/tex/context/base/mkiv/back-res.lua new file mode 100644 index 000000000..be92c74a6 --- /dev/null +++ b/tex/context/base/mkiv/back-res.lua @@ -0,0 +1,44 @@ +if not modules then modules = { } end modules ['back-res'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- A box resource has an index. This happens to be an object number +-- due to the pdf backend but in fact it's an abstraction. This is why +-- we have explicit fetchers. The internal number (as in \Fm123) is yet +-- another number. + +local tex_saveboxresource = tex.saveboxresource +local tex_useboxresource = tex.useboxresource +local tex_getboxresourcebox = tex.getboxresourcebox +local tex_getboxresourcedimensions = tex.getboxresourcedimensions + +updaters.register("backend.update",function() + tex_saveboxresource = tex.saveboxresource + tex_useboxresource = tex.useboxresource + tex_getboxresourcebox = tex.getboxresourcebox + tex_getboxresourcedimensions = tex.getboxresourcedimensions +end) + +tex.boxresources = { + save = function(...) return tex_saveboxresource(...) end, + use = function(...) return tex_useboxresource(...) end, + getbox = function(...) return tex_getboxresourcebox(...) end, + getdimensions = function(...) return tex_getboxresourcedimensions(...) end, +} + +-- local tex_saveimageresource = tex.saveimageresource +-- local tex_useimageresource = tex.useimageresource +-- +-- updaters.register("backend.update",function() +-- tex_saveimageresource = tex.saveimageresource +-- tex_useimageresource = tex.useimageresource +-- end) +-- +-- tex.imageresources = { +-- save = function(...) return tex_saveimageresource(...) end, +-- use = function(...) return tex_useimageresource(...) end, +-- } diff --git a/tex/context/base/mkiv/back-swf.mkiv b/tex/context/base/mkiv/back-swf.mkiv index 0a53a8fd2..20a94266a 100644 --- a/tex/context/base/mkiv/back-swf.mkiv +++ b/tex/context/base/mkiv/back-swf.mkiv @@ -11,6 +11,9 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +%D The question is: should I still document this in interaction.tex or just +%D assume it's obsolete technology \unknown + %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 @@ -58,6 +61,8 @@ %D [file=test.mp4, %D label=foo] %D +%D \useJSscripts[vplayer] % or \useJSscripts[videoplayer] +%D %D \goto{START} [JS(StartShockwave{foo})] %D \goto{REWIND}[JS(RewindShockwave{foo})] %D \goto{PAUSE} [JS(PauseShockwave{foo})] @@ -84,100 +89,8 @@ \unprotect -\startluaparameterset[shockwave:display] - toolbar = true, - -- preview = "somefile", - open = "click", - close = "focus", -\stopluaparameterset - -% using vplayer9.swf from ctan: - -\useexternalfigure - [shockwave] - [vplayer9.swf] -% [arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file",source="\externalfigureparameter\v!file"}, - [\c!arguments=\luaparameterset{shockwave:arguments}{source="\externalfigureparameter\v!file",autoPlay=true}, - \c!resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}}, - \c!display=shockwave:display] - -\startJSpreamble shockwave used now - function StartShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - // ok - } else { - rm.activated = true ; - } - rm.callAS("rewind") ; - rm.callAS("playPause") ; - } - function StopShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("pause") ; - rm.callAS("rewind") ; - } - } - function RewindShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("rewind") ; - } - } - function PauseShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("playPause") ; - } - } -\stopJSpreamble - -% using videoplayer.swf from adobe or strobemediaplayback.swf from sourceforge: - -%\useexternalfigure -% [shockwave] -% [videoplayer.swf] -% [\c!arguments=\luaparameterset{shockwave:arguments}{source="\externalfigureparameter\v!file"}, -% \c!resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}}, -% \c!display=shockwave:display] - -\startJSpreamble shockwave used now - function StartShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("multimedia_play") ; - } else { - rm.activated = true ; - } - } - function StopShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("multimedia_pause") ; - rm.callAS("multimedia_rewind") ; - } - } - function RewindShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("multimedia_rewind") ; - } - } - function PauseShockwave(label) { - var rm = this.getAnnotsRichMedia(this.pageNum,label)[0] ; - if (rm.activated) { - rm.callAS("multimedia_pause") ; - } - } -\stopJSpreamble - -% \useexternalfigure -% [shockwave] -% [strobemediaplayback.swf] -% [arguments=\luaparameterset{shockwave:arguments}{src="\externalfigureparameter\v!file"}, -% resources=\luaparameterset{shockwave:resources}{files={"\externalfigureparameter\v!file"}}, -% display=shockwave:display] +%D The code has moved to the (explicitly loaded) \JAVASCRIPT\ modules. See there +%D for more info. \protect \endinput diff --git a/tex/context/base/mkiv/bibl-bib.mkiv b/tex/context/base/mkiv/bibl-bib.mkiv index 784c87a02..60291ee71 100644 --- a/tex/context/base/mkiv/bibl-bib.mkiv +++ b/tex/context/base/mkiv/bibl-bib.mkiv @@ -812,12 +812,12 @@ {\iflocation \edef\temp{\bibtexcitationparameter\c!interaction}% \ifx\temp\v!stop - \@EA@EA@EA\secondoftwoarguments + \doubleexpandafter\secondoftwoarguments \else - \@EA@EA@EA\firstoftwoarguments + \doubleexpandafter\firstoftwoarguments \fi \else - \@EA\secondoftwoarguments + \expandafter\secondoftwoarguments \fi} \let\doifbibtexinteractionelse\doifelsebibtexinteraction diff --git a/tex/context/base/mkiv/bibl-tra.mkiv b/tex/context/base/mkiv/bibl-tra.mkiv index 3ff07ead5..5389400f3 100644 --- a/tex/context/base/mkiv/bibl-tra.mkiv +++ b/tex/context/base/mkiv/bibl-tra.mkiv @@ -1500,7 +1500,7 @@ \c!numbercommand=\bibleftnumber] \unexpanded\def\preloadbiblist - {\globallet\preloadbiblist\relax + {\glet\preloadbiblist\relax \dousepublications\jobname} % \appendtoks \preloadbiblist \to \everysetuppublications diff --git a/tex/context/base/mkiv/buff-imp-default.mkiv b/tex/context/base/mkiv/buff-imp-default.mkiv index a4ad788bb..4da4ff0df 100644 --- a/tex/context/base/mkiv/buff-imp-default.mkiv +++ b/tex/context/base/mkiv/buff-imp-default.mkiv @@ -15,11 +15,11 @@ \unprotect -\definestartstop - [DefaultSnippet] - [\c!before=\blank, - \c!after=\blank, - \c!style=\tt] +\setupstartstop + [DefaultSnippet] + [\c!before={\typingparameter\c!before}, + \c!after={\typingparameter\c!after}, + \c!style={\typingparameter\c!style}] % Name % NamePrimitive diff --git a/tex/context/base/mkiv/buff-ini.lua b/tex/context/base/mkiv/buff-ini.lua index 1c7912773..bd3cf9d5a 100644 --- a/tex/context/base/mkiv/buff-ini.lua +++ b/tex/context/base/mkiv/buff-ini.lua @@ -167,7 +167,8 @@ local function collectcontent(name,separator) -- no print elseif nnames == 1 then return getcontent(names[1]) else - local t, n = { }, 0 + local t = { } + local n = 0 for i=1,nnames do local c = getcontent(names[i]) if c ~= "" then @@ -182,7 +183,7 @@ local function collectcontent(name,separator) -- no print end local function loadcontent(name) -- no print - local content = collectcontent(name,"\n") -- tex likes \n + local content = collectcontent(name,"\n") -- tex likes \n hm, elsewhere \r local ok, err = load(content) if ok then return ok() @@ -645,7 +646,10 @@ local function gettexbuffer(name) end end -buffers.run = runbuffer +buffers.get = getbuffer +buffers.getmkiv = getbuffermkiv +buffers.gettexbuffer = gettexbuffer +buffers.run = runbuffer implement { name = "getbufferctxlua", actions = loadcontent, arguments = "string" } implement { name = "getbuffer", actions = getbuffer, arguments = "string" } @@ -708,3 +712,18 @@ do end end + +-- moved here: + +function buffers.samplefile(name) + if not buffers.exists(name) then + buffers.assign(name,io.loaddata(resolvers.findfile(name))) + end + buffers.get(name) +end + +implement { + name = "samplefile", -- bad name, maybe rename to injectbuffercontent + actions = buffers.samplefile, + arguments = "string" +} diff --git a/tex/context/base/mkiv/buff-ini.mkiv b/tex/context/base/mkiv/buff-ini.mkiv index 1a5ce4591..145f0f392 100644 --- a/tex/context/base/mkiv/buff-ini.mkiv +++ b/tex/context/base/mkiv/buff-ini.mkiv @@ -44,8 +44,18 @@ % \def\buff_start_indeed#1#2#3#4#5% \donothing needed ! #5=undent) % {\normalexpanded{\buff_pickup{#2}{#3}{#4}{}{\buff_stop{#4}}\plusone}} +% \def\buff_start_indeed#1#2#3#4% +% {\normalexpanded{\buff_pickup{#2}{#3}{#4}{}{\buff_stop{#4}}\plusone}} + \def\buff_start_indeed#1#2#3#4% - {\normalexpanded{\buff_pickup{#2}{#3}{#4}{}{\buff_stop{#4}}\plusone}} + {\edef\p_strip{\namedbufferparameter{#1}\c!strip}% for aditya + \normalexpanded{\buff_pickup + {#2}% + {#3}% + {#4}% + {}% + {\buff_stop{#4}}% + \ifx\p_strip\v!no\zerocount\else\plusone\fi}} \unexpanded\def\grabbufferdata % was: \dostartbuffer {\begingroup % (4) @@ -155,7 +165,7 @@ \setexpandedbufferparameter\c!number{\number\c_buff_n_of_defined}% \edef\currentdefinedbuffer{def-\number\c_buff_n_of_defined}% \setuevalue{\e!start\currentbuffer}{\buff_start_defined{\currentbuffer}{\currentdefinedbuffer}{\e!start\currentbuffer}{\e!stop\currentbuffer}}% - \setuevalue{\e!get\currentbuffer }{\buff_get_stored{\currentbuffer}{\currentdefinedbuffer}}% + \setuevalue{\e!get \currentbuffer}{\buff_get_stored {\currentbuffer}{\currentdefinedbuffer}}% \to \everydefinebuffer \unexpanded\def\buff_start_defined @@ -169,16 +179,16 @@ {\dosingleempty\buff_get} \unexpanded\def\buff_get[#1]% [name] - {\namedbufferparameter\empty\c!before + {\namedbufferparameter\empty\c!before\relax \doifelsenothing{#1} {\buff_get_stored_indeed\empty} {\processcommalist[#1]\buff_get_stored_indeed}% - \namedbufferparameter\empty\c!after} + \namedbufferparameter\empty\c!after\relax} \unexpanded\def\buff_get_stored#1#2% - {\namedbufferparameter{#1}\c!before + {\namedbufferparameter{#1}\c!before\relax \buff_get_stored_indeed{#2}% - \namedbufferparameter{#1}\c!after} + \namedbufferparameter{#1}\c!after\relax} \unexpanded\def\buff_get_stored_indeed#1% {\clf_getbuffer{#1}} @@ -274,28 +284,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/mkiv/buff-ver.lua b/tex/context/base/mkiv/buff-ver.lua index d9178b1df..88605631d 100644 --- a/tex/context/base/mkiv/buff-ver.lua +++ b/tex/context/base/mkiv/buff-ver.lua @@ -43,6 +43,7 @@ local findfile = resolvers.findfile local addsuffix = file.addsuffix local v_yes = variables.yes +local v_no = variables.no local v_last = variables.last local v_all = variables.all local v_absolute = variables.absolute @@ -141,7 +142,8 @@ local functions = { __index = { local handlers = { } function visualizers.newhandler(name,data) - local tname, tdata = type(name), type(data) + local tname = type(name) + local tdata = type(data) if tname == "table" then -- (data) setmetatable(name,getmetatable(name) or functions) return name @@ -255,7 +257,7 @@ function visualizers.load(name) if trace_visualize then report_visualizers("loading visualizer %a",name) end - lua.registercode(luaname) + lua.registercode(luaname) -- only used here, end up in format context.input(texname) end if rawget(specifications,name) == nil then @@ -445,7 +447,7 @@ function visualizers.registerescapecommand(name,token,normalmethod,escapecommand end token = P(token) local notoken = hack((1 - token)^1) - local cstoken = name_pattern * space_pattern + local cstoken = Cs(name_pattern * (space_pattern/"")) escapepattern = ( (token / "") * (cstoken / (escapecommand or texcommand)) @@ -614,7 +616,12 @@ end local onlyspaces = S(" \t\f\n\r")^0 * P(-1) local function getstrip(lines,first,last) - local first, last = first or 1, last or #lines + if not first then + first = 1 + end + if not last then + last = #lines + end for i=first,last do local li = lines[i] if #li == 0 or lpegmatch(onlyspaces,li) then @@ -736,12 +743,14 @@ end local function filter(lines,settings) -- todo: inline or display in settings local strip = settings.strip - if strip and strip ~= "" then + -- if strip and strip == "" then + if strip ~= v_no and strip ~= false then lines = realign(lines,strip) end - local line, n = 0, 0 - local first, last, m = getstrip(lines) + local line = 0 + local n = 0 local range = settings.range + local first, last, m = getstrip(lines) if range then first, last = getrange(lines,first,last,range) first, last = getstrip(lines,first,last) diff --git a/tex/context/base/mkiv/buff-ver.mkiv b/tex/context/base/mkiv/buff-ver.mkiv index 558049dcc..7cf829b74 100644 --- a/tex/context/base/mkiv/buff-ver.mkiv +++ b/tex/context/base/mkiv/buff-ver.mkiv @@ -496,7 +496,7 @@ \def\buff_verbatim_typing_start_nop {\typingparameter\c!before - \startpacked[\v!blank] + \startpacked[\v!blank]% \buff_verbatim_setup_line_numbering \buff_verbatim_initialize_typing_one \buff_verbatim_setup_keep_together @@ -504,7 +504,7 @@ \def\buff_verbatim_typing_start_yes[#1]% {\typingparameter\c!before - \startpacked[\v!blank] + \startpacked[\v!blank]% \doifelseassignment{#1} {\setupcurrenttyping[#1]} {\doif\v!continue{#1}{\lettypingparameter\c!continue\v!yes}}% @@ -514,9 +514,16 @@ \normalexpanded{\buff_verbatim_type_block{\e!start\currenttyping}{\e!stop\currenttyping}}} \unexpanded\def\buff_verbatim_type_block#1#2% - {\buff_pickup{_typing_}{#1}{#2}{}{\buff_verbatim_type_block_verbatim_indeed{#1}{#2}}\plusone} % was dowithbuffer - -\def\buff_verbatim_type_block_verbatim_indeed#1#2% + {\edef\p_strip{\typingparameter\c!strip}% + \normalexpanded{\buff_pickup + {_typing_}% + {#1}% + {#2}% + {}% + {\buff_verbatim_type_block_verbatim_indeed{#1}{#2}}% + \ifx\p_strip\v!no\zerocount\else\plusone\fi}} + +\unexpanded\def\buff_verbatim_type_block_verbatim_indeed#1#2% {\buff_verbatim_initialize_typing_two \dostarttaggedchained\t!verbatimblock\currenttyping\??typing \beginofverbatimlines @@ -533,7 +540,7 @@ \dostoptagged \endofverbatimlines \dostoptagged - \csname#2\endcsname} + \begincsname#2\endcsname} \unexpanded\def\buff_verbatim_typing_stop#1% hm, currenttyping {\stoppacked diff --git a/tex/context/base/mkiv/catc-ini.mkiv b/tex/context/base/mkiv/catc-ini.mkiv index 471e4d1c8..215ec14e1 100644 --- a/tex/context/base/mkiv/catc-ini.mkiv +++ b/tex/context/base/mkiv/catc-ini.mkiv @@ -23,58 +23,110 @@ %D \MKII\ file. There is some overlap in code with \MKII\ but we take that %D for granted. Also, in \MKIV\ less active characters are used. -\setnewconstant\escapecatcode 0 -\setnewconstant\begingroupcatcode 1 -\setnewconstant\endgroupcatcode 2 -\setnewconstant\mathshiftcatcode 3 -\setnewconstant\alignmentcatcode 4 -\setnewconstant\endoflinecatcode 5 -\setnewconstant\parametercatcode 6 -\setnewconstant\superscriptcatcode 7 -\setnewconstant\subscriptcatcode 8 -\setnewconstant\ignorecatcode 9 -\setnewconstant\spacecatcode 10 -\setnewconstant\lettercatcode 11 -\setnewconstant\othercatcode 12 % finally obsolete: \let\other \othercatcode -\setnewconstant\activecatcode 13 % finally obsolete: \let\active\activecatcode -\setnewconstant\commentcatcode 14 -\setnewconstant\invalidcatcode 15 - -\setnewconstant\tabasciicode 9 -\setnewconstant\newlineasciicode 10 % don't confuse this one with \endoflineasciicode -\setnewconstant\formfeedasciicode 12 -\setnewconstant\endoflineasciicode 13 % somewhat messy but this can be the active \par -\setnewconstant\endoffileasciicode 26 -\setnewconstant\spaceasciicode 32 -\setnewconstant\exclamationmarkasciicode 33 % ! used in namespace protection -\setnewconstant\doublequoteasciicode 34 % " -\setnewconstant\hashasciicode 35 -\setnewconstant\dollarasciicode 36 -\setnewconstant\commentasciicode 37 -\setnewconstant\ampersandasciicode 38 -\setnewconstant\singlequoteasciicode 39 % ' -\setnewconstant\primeasciicode 39 % ' -\setnewconstant\hyphenasciicode 45 -\setnewconstant\forwardslashasciicode 47 % / -\setnewconstant\colonasciicode 58 -\setnewconstant\lessthanasciicode 60 % < used as alternative verbatim { -\setnewconstant\morethanasciicode 62 % > used as alternative verbatim } -\setnewconstant\questionmarkasciicode 63 % ? used in namespace protection -\setnewconstant\atsignasciicode 64 % @ used in namespace protection -\setnewconstant\backslashasciicode 92 % `\\ -\setnewconstant\circumflexasciicode 94 -\setnewconstant\underscoreasciicode 95 -\setnewconstant\leftbraceasciicode 123 % `\{ -\setnewconstant\barasciicode 124 % `\| -\setnewconstant\rightbraceasciicode 125 % `\} -\setnewconstant\tildeasciicode 126 % `\~ -\setnewconstant\delasciicode 127 +% \normalprotected\def\setnewconstantfromchar#1% +% {\expandafter\ifdefined\expandafter#1\expandafter +% \let\expandafter#1\expandafter\undefined\expandafter\fi\expandafter +% \newcount\expandafter#1\expandafter#1\the#1\relax} +% +% \normalprotected\def\setnewconstantfromchar#1% +% {\begingroup +% \scratchcounter#1% +% \edef\!!stringa{\meaning#1}% +% \chardef#1\scratchcounter +% \edef\!!stringb{\meaning#1}% +% \normalexpanded{\endgroup +% \ifx\!!stringa\!!stringb +% \let#1\noexpand\undefined +% \newcount#1% +% \fi +% #1\the\scratchcounter\relax}} +% +% \normalprotected\def\setnewconstantfromchar#1% +% {\begingroup +% \edef\!!stringa{\meaning#1}% +% \expandafter\chardef\expandafter#1\the#1% +% \edef\!!stringb{\meaning#1}% +% \normalexpanded{\endgroup +% \ifx\!!stringa\!!stringb +% \let#1\noexpand\undefined +% \newcount#1% +% \fi +% #1\the#1\relax}} +% +% \normalprotected\def\setnewconstantfromchar#1% +% {\scratchcounter#1\let#1\undefined\newcount#1#1\scratchcounter} + +\def\promote#1{\scratchcounter#1\let#1\undefined\newcount#1#1\scratchcounter} + +\promote\escapecatcode +\promote\begingroupcatcode +\promote\endgroupcatcode +\promote\mathshiftcatcode +\promote\alignmentcatcode +\promote\endoflinecatcode +\promote\parametercatcode +\promote\superscriptcatcode +\promote\subscriptcatcode +\promote\ignorecatcode +\promote\spacecatcode +\promote\lettercatcode +\promote\othercatcode +\promote\activecatcode +\promote\commentcatcode +\promote\invalidcatcode + +\promote\tabasciicode +\promote\newlineasciicode +\promote\formfeedasciicode +\promote\endoflineasciicode +\promote\endoffileasciicode +\promote\spaceasciicode +\promote\exclamationmarkasciicode +\promote\doublequoteasciicode +\promote\hashasciicode +\promote\dollarasciicode +\promote\commentasciicode +\promote\ampersandasciicode +\promote\singlequoteasciicode +\promote\primeasciicode +\promote\hyphenasciicode +\promote\forwardslashasciicode +\promote\colonasciicode +\promote\lessthanasciicode +\promote\morethanasciicode +\promote\questionmarkasciicode +\promote\atsignasciicode +\promote\backslashasciicode +\promote\circumflexasciicode +\promote\underscoreasciicode +\promote\leftbraceasciicode +\promote\barasciicode +\promote\rightbraceasciicode +\promote\tildeasciicode +\promote\delasciicode + +\let\promote\undefined + +% \begingroup +% +% \catcode\tabasciicode \activecatcode +% \catcode\formfeedasciicode \activecatcode +% \catcode\endoflineasciicode\activecatcode +% +% \letcharcode\tabasciicode \relax +% \letcharcode\newlineasciicode \relax +% \letcharcode\formfeedasciicode \relax +% \letcharcode\endoflineasciicode\relax +% +% \xdef\activetabtoken {\Uchar\tabasciicode } % \gdef\activetabtoken {^^I} +% \xdef\outputnewlinechar {\Uchar\newlineasciicode } % \gdef\outputnewlinechar {^^J} +% \xdef\activeformfeedtoken {\Uchar\formfeedasciicode } % \gdef\activeformfeedtoken {^^L} +% \xdef\activeendoflinetoken{\Uchar\endoflineasciicode} % \gdef\activeendoflinetoken{^^M} +% +% \endgroup \begingroup - \catcode \tabasciicode \activecatcode \gdef\activetabtoken {^^I} - \gdef\outputnewlinechar {^^J} - \catcode \formfeedasciicode \activecatcode \gdef\activeformfeedtoken {^^L} - \catcode \endoflineasciicode \activecatcode \gdef\activeendoflinetoken{^^M} + \letcharcode\newlineasciicode\relax \xdef\outputnewlinechar{\Uchar\newlineasciicode} \endgroup % \endlinechar = \endoflineasciicode % appended to input lines @@ -82,10 +134,17 @@ % rather special and used in writing to file: \let\par\outputnewlinechar +% \normalprotected\def\initializenewlinechar % operating system dependent +% {\begingroup +% \newlinechar\newlineasciicode +% \xdef\outputnewlinechar{^^J}% +% \endgroup} + \normalprotected\def\initializenewlinechar % operating system dependent {\begingroup + \letcharcode\newlineasciicode\relax \newlinechar\newlineasciicode - \xdef\outputnewlinechar{^^J}% + \xdef\outputnewlinechar{\Uchar\newlineasciicode}% \endgroup} %D We predefine some prefixes ahead of syst-aux and mult-sys. diff --git a/tex/context/base/mkiv/char-act.mkiv b/tex/context/base/mkiv/char-act.mkiv index 7d7268c8b..dd9a325f2 100644 --- a/tex/context/base/mkiv/char-act.mkiv +++ b/tex/context/base/mkiv/char-act.mkiv @@ -44,11 +44,14 @@ \unexpanded\def\controlspace{\hbox{\asciispacechar}} % rather tex, we need the unicode value \unexpanded\def\normalspaces{\catcode\spaceasciicode\spacecatcode} -\bgroup - \catcode\spaceasciicode\activecatcode - \unexpanded\gdef\obeyspaces{\catcode\spaceasciicode\activecatcode\def {\obeyedspace}} - \unexpanded\gdef\setcontrolspaces{\catcode\spaceasciicode\activecatcode\def {\controlspace}} -\egroup +% \bgroup +% \catcode\spaceasciicode\activecatcode +% \unexpanded\gdef\obeyspaces {\catcode\spaceasciicode\activecatcode\def {\obeyedspace }} +% \unexpanded\gdef\setcontrolspaces{\catcode\spaceasciicode\activecatcode\def {\controlspace}} +% \egroup + +%unexpanded\def\obeyspaces {\catcode\spaceasciicode\activecatcode\letcharcode\spaceasciicode\obeyedspace } +\unexpanded\def\setcontrolspaces{\catcode\spaceasciicode\activecatcode\letcharcode\spaceasciicode\controlspace} %D \macros %D {obeytabs, obeylines, obeypages,ignoretabs, ignorelines, ignorepages} @@ -59,20 +62,42 @@ %D \NEWPAGE\ character locally, we redefine the meaning of %D this (often already) active character. -\expandafter\def\activeformfeedtoken{\par} +% \expandafter\def\activeformfeedtoken{\par} + +\letcharcode\formfeedasciicode\par %D The following indirect definitions enable us to implement %D all kind of \type{\obeyed} handlers. -\unexpanded\def\obeytabs {\catcode\tabasciicode \activecatcode\expandafter\def\activetabtoken {\obeyedtab }} -\unexpanded\def\obeylines {\catcode\endoflineasciicode\activecatcode\expandafter\def\activeendoflinetoken{\obeyedline}} -\unexpanded\def\obeypages {\catcode\formfeedasciicode \activecatcode\expandafter\def\activeformfeedtoken {\obeyedpage}} +% \unexpanded\def\obeytabs {\catcode\tabasciicode \activecatcode\expandafter\def\activetabtoken {\obeyedtab }} +% \unexpanded\def\obeylines {\catcode\endoflineasciicode\activecatcode\expandafter\def\activeendoflinetoken{\obeyedline}} +% \unexpanded\def\obeypages {\catcode\formfeedasciicode \activecatcode\expandafter\def\activeformfeedtoken {\obeyedpage}} + +% \unexpanded\def\ignoretabs {\catcode\tabasciicode \activecatcode\expandafter\def\activetabtoken {\obeyedspace}} +% \unexpanded\def\ignorelines{\catcode\endoflineasciicode\activecatcode\expandafter\def\activeendoflinetoken{\obeyedspace}} +% \unexpanded\def\ignorepages{\catcode\formfeedasciicode \ignorecatcode} +% \unexpanded\def\ignoreeofs {\catcode\endoffileasciicode\ignorecatcode} + +% but ... as we don't want to freeze to \obeyedspace etc which can be set after \obeyspaces, we +% use an idirectness -\unexpanded\def\ignoretabs {\catcode\tabasciicode \activecatcode\expandafter\def\activetabtoken {\obeyedspace}} -\unexpanded\def\ignorelines{\catcode\endoflineasciicode\activecatcode\expandafter\def\activeendoflinetoken{\obeyedspace}} +\def\_obeyed_space_{\obeyedspace} +\def\_obeyed_tab_ {\obeyedtab} +\def\_obeyed_line_ {\obeyedline} +\def\_obeyed_page_ {\obeyedpage} + +\unexpanded\def\obeyspaces {\catcode\spaceasciicode \activecatcode\letcharcode\spaceasciicode \_obeyed_space_} +\unexpanded\def\obeytabs {\catcode\tabasciicode \activecatcode\letcharcode\tabasciicode \_obeyed_tab_} +\unexpanded\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\_obeyed_line_} +\unexpanded\def\obeypages {\catcode\formfeedasciicode \activecatcode\letcharcode\formfeedasciicode \_obeyed_page_} + +\unexpanded\def\ignoretabs {\catcode\tabasciicode \activecatcode\letcharcode\tabasciicode \_obeyed_space_} +\unexpanded\def\ignorelines{\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\_obeyed_space_} \unexpanded\def\ignorepages{\catcode\formfeedasciicode \ignorecatcode} \unexpanded\def\ignoreeofs {\catcode\endoffileasciicode\ignorecatcode} +\unexpanded\def\setcontrolspaces{\catcode\spaceasciicode\activecatcode\letcharcode\spaceasciicode\_control_space_} + %D \macros %D {naturaltextext} %D diff --git a/tex/context/base/mkiv/char-def.lua b/tex/context/base/mkiv/char-def.lua index fcbf01900..c17400a79 100644 --- a/tex/context/base/mkiv/char-def.lua +++ b/tex/context/base/mkiv/char-def.lua @@ -10232,6 +10232,7 @@ characters.data={ [0x3D0]={ adobename="betasymbolgreek", category="ll", + contextname="greekbetaalt", description="GREEK BETA SYMBOL", direction="l", linebreak="al", @@ -14164,6 +14165,13 @@ characters.data={ synonyms={ "armenian patiw" }, unicodeslot=0x55F, }, + [0x560]={ + category="ll", + description="ARMENIAN SMALL LETTER TURNED AYB", + direction="l", + linebreak="al", + unicodeslot=0x560, + }, [0x561]={ adobename="aybarmenian", category="ll", @@ -14515,6 +14523,13 @@ characters.data={ specials={ "compat", 0x565, 0x582 }, unicodeslot=0x587, }, + [0x588]={ + category="ll", + description="ARMENIAN SMALL LETTER YI WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0x588, + }, [0x589]={ adobename="periodarmenian", category="po", @@ -15283,6 +15298,13 @@ characters.data={ linebreak="hl", unicodeslot=0x5EA, }, + [0x5EF]={ + category="lo", + description="HEBREW YOD TRIANGLE", + direction="r", + linebreak="hl", + unicodeslot=0x5EF, + }, [0x5F0]={ adobename="vavvavhebrew", category="lo", @@ -17638,6 +17660,7 @@ characters.data={ unicodeslot=0x70D, }, [0x70F]={ + arabic="t", category="cf", description="SYRIAC ABBREVIATION MARK", direction="al", @@ -19362,6 +19385,28 @@ characters.data={ linebreak="al", unicodeslot=0x7FA, }, + [0x7FD]={ + category="mn", + combining=0xDC, + description="NKO DANTAYALAN", + direction="nsm", + linebreak="cm", + unicodeslot=0x7FD, + }, + [0x7FE]={ + category="sc", + description="NKO DOROME SIGN", + direction="r", + linebreak="pr", + unicodeslot=0x7FE, + }, + [0x7FF]={ + category="sc", + description="NKO TAMAN SIGN", + direction="r", + linebreak="pr", + unicodeslot=0x7FF, + }, [0x800]={ category="lo", description="SAMARITAN LETTER ALAF", @@ -20361,6 +20406,14 @@ characters.data={ linebreak="al", unicodeslot=0x8BD, }, + [0x8D3]={ + category="mn", + combining=0xDC, + description="ARABIC SMALL LOW WAW", + direction="nsm", + linebreak="cm", + unicodeslot=0x8D3, + }, [0x8D4]={ category="mn", combining=0xE6, @@ -21284,8 +21337,8 @@ characters.data={ description="DEVANAGARI SIGN NUKTA", direction="nsm", indic="o", - indicmark="b", indicclass="nukta", + indicmark="b", linebreak="cm", unicodeslot=0x93C, }, @@ -21522,8 +21575,8 @@ characters.data={ description="DEVANAGARI STRESS SIGN ANUDATTA", direction="nsm", indic="s", - indicmark="b", indicclass="anudatta", + indicmark="b", linebreak="cm", unicodeslot=0x952, }, @@ -22376,8 +22429,8 @@ characters.data={ description="BENGALI SIGN NUKTA", direction="nsm", indic="o", - indicmark="b", indicclass="nukta", + indicmark="b", linebreak="cm", unicodeslot=0x9BC, }, @@ -22823,6 +22876,14 @@ characters.data={ linebreak="al", unicodeslot=0x9FD, }, + [0x9FE]={ + category="mn", + combining=0xE6, + description="BENGALI SANDHI MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x9FE, + }, [0xA01]={ category="mn", description="GURMUKHI SIGN ADAK BINDI", @@ -23247,8 +23308,8 @@ characters.data={ description="GURMUKHI SIGN NUKTA", direction="nsm", indic="o", - indicmark="b", indicclass="nukta", + indicmark="b", linebreak="cm", unicodeslot=0xA3C, }, @@ -23565,6 +23626,13 @@ characters.data={ linebreak="cm", unicodeslot=0xA75, }, + [0xA76]={ + category="po", + description="GURMUKHI ABBREVIATION SIGN", + direction="l", + linebreak="al", + unicodeslot=0xA76, + }, [0xA81]={ adobename="candrabindugujarati", category="mn", @@ -24032,8 +24100,8 @@ characters.data={ description="GUJARATI SIGN NUKTA", direction="nsm", indic="o", - indicmark="b", indicclass="nukta", + indicmark="b", linebreak="cm", unicodeslot=0xABC, }, @@ -24807,8 +24875,8 @@ characters.data={ description="ORIYA SIGN NUKTA", direction="nsm", indic="o", - indicmark="b", indicclass="nukta", + indicmark="b", linebreak="cm", unicodeslot=0xB3C, }, @@ -25809,6 +25877,13 @@ characters.data={ linebreak="cm", unicodeslot=0xC03, }, + [0xC04]={ + category="mn", + description="TELUGU SIGN COMBINING ANUSVARA ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0xC04, + }, [0xC05]={ category="lo", description="TELUGU LETTER A", @@ -26175,9 +26250,9 @@ characters.data={ category="lo", description="TELUGU LETTER VA", direction="l", + indic="c", linebreak="al", unicodeslot=0xC35, - indic="c", }, [0xC36]={ category="lo", @@ -26614,6 +26689,13 @@ characters.data={ linebreak="cm", unicodeslot=0xC83, }, + [0xC84]={ + category="po", + description="KANNADA SIGN SIDDHAM", + direction="l", + linebreak="bb", + unicodeslot=0xC84, + }, [0xC85]={ category="lo", description="KANNADA LETTER A", @@ -27014,8 +27096,8 @@ characters.data={ description="KANNADA SIGN NUKTA", direction="nsm", indic="o", - indicmark="b", indicclass="nukta", + indicmark="b", linebreak="cm", unicodeslot=0xCBC, }, @@ -31643,6 +31725,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1000, variants={ @@ -31653,6 +31736,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1001, }, @@ -31660,6 +31744,7 @@ characters.data={ category="lo", description="MYANMAR LETTER GA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1002, variants={ @@ -31670,6 +31755,7 @@ characters.data={ category="lo", description="MYANMAR LETTER GHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1003, }, @@ -31677,6 +31763,7 @@ characters.data={ category="lo", description="MYANMAR LETTER NGA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1004, variants={ @@ -31687,6 +31774,7 @@ characters.data={ category="lo", description="MYANMAR LETTER CA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1005, }, @@ -31694,6 +31782,7 @@ characters.data={ category="lo", description="MYANMAR LETTER CHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1006, }, @@ -31701,6 +31790,7 @@ characters.data={ category="lo", description="MYANMAR LETTER JA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1007, }, @@ -31708,6 +31798,7 @@ characters.data={ category="lo", description="MYANMAR LETTER JHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1008, }, @@ -31715,6 +31806,7 @@ characters.data={ category="lo", description="MYANMAR LETTER NYA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1009, }, @@ -31722,6 +31814,7 @@ characters.data={ category="lo", description="MYANMAR LETTER NNYA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x100A, }, @@ -31729,6 +31822,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TTA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x100B, }, @@ -31736,6 +31830,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TTHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x100C, }, @@ -31743,6 +31838,7 @@ characters.data={ category="lo", description="MYANMAR LETTER DDA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x100D, }, @@ -31750,6 +31846,7 @@ characters.data={ category="lo", description="MYANMAR LETTER DDHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x100E, }, @@ -31757,6 +31854,7 @@ characters.data={ category="lo", description="MYANMAR LETTER NNA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x100F, }, @@ -31764,6 +31862,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1010, variants={ @@ -31774,6 +31873,7 @@ characters.data={ category="lo", description="MYANMAR LETTER THA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1011, variants={ @@ -31784,6 +31884,7 @@ characters.data={ category="lo", description="MYANMAR LETTER DA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1012, }, @@ -31791,6 +31892,7 @@ characters.data={ category="lo", description="MYANMAR LETTER DHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1013, }, @@ -31798,6 +31900,7 @@ characters.data={ category="lo", description="MYANMAR LETTER NA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1014, }, @@ -31805,6 +31908,7 @@ characters.data={ category="lo", description="MYANMAR LETTER PA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1015, variants={ @@ -31815,6 +31919,7 @@ characters.data={ category="lo", description="MYANMAR LETTER PHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1016, }, @@ -31822,6 +31927,7 @@ characters.data={ category="lo", description="MYANMAR LETTER BA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1017, }, @@ -31829,6 +31935,7 @@ characters.data={ category="lo", description="MYANMAR LETTER BHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1018, }, @@ -31836,6 +31943,7 @@ characters.data={ category="lo", description="MYANMAR LETTER MA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1019, variants={ @@ -31846,6 +31954,7 @@ characters.data={ category="lo", description="MYANMAR LETTER YA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x101A, variants={ @@ -31856,6 +31965,7 @@ characters.data={ category="lo", description="MYANMAR LETTER RA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x101B, }, @@ -31863,6 +31973,7 @@ characters.data={ category="lo", description="MYANMAR LETTER LA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x101C, variants={ @@ -31873,6 +31984,7 @@ characters.data={ category="lo", description="MYANMAR LETTER WA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x101D, variants={ @@ -31883,6 +31995,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x101E, }, @@ -31890,6 +32003,7 @@ characters.data={ category="lo", description="MYANMAR LETTER HA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x101F, }, @@ -31897,6 +32011,7 @@ characters.data={ category="lo", description="MYANMAR LETTER LLA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1020, }, @@ -31904,6 +32019,7 @@ characters.data={ category="lo", description="MYANMAR LETTER A", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1021, }, @@ -31911,6 +32027,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN A", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1022, variants={ @@ -31921,6 +32038,7 @@ characters.data={ category="lo", description="MYANMAR LETTER I", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1023, }, @@ -31928,6 +32046,7 @@ characters.data={ category="lo", description="MYANMAR LETTER II", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1024, }, @@ -31935,6 +32054,7 @@ characters.data={ category="lo", description="MYANMAR LETTER U", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1025, }, @@ -31942,6 +32062,7 @@ characters.data={ category="lo", description="MYANMAR LETTER UU", direction="l", + indic="i", linebreak="sa", specials={ "char", 0x1025, 0x102E }, unicodeslot=0x1026, @@ -31950,6 +32071,7 @@ characters.data={ category="lo", description="MYANMAR LETTER E", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1027, }, @@ -31957,6 +32079,7 @@ characters.data={ category="lo", description="MYANMAR LETTER MON E", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1028, }, @@ -31964,6 +32087,7 @@ characters.data={ category="lo", description="MYANMAR LETTER O", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1029, }, @@ -31971,6 +32095,7 @@ characters.data={ category="lo", description="MYANMAR LETTER AU", direction="l", + indic="i", linebreak="sa", unicodeslot=0x102A, }, @@ -31978,6 +32103,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN TALL AA", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x102B, }, @@ -31985,6 +32112,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN AA", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x102C, }, @@ -31992,6 +32121,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN I", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x102D, }, @@ -31999,6 +32130,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN II", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x102E, }, @@ -32006,6 +32139,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN U", direction="nsm", + indic="d", + indicmark="b", linebreak="sa", unicodeslot=0x102F, }, @@ -32013,6 +32148,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN UU", direction="nsm", + indic="d", + indicmark="b", linebreak="sa", unicodeslot=0x1030, }, @@ -32020,6 +32157,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN E", direction="l", + indic="d", + indicmark="l", linebreak="sa", unicodeslot=0x1031, variants={ @@ -32030,6 +32169,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN AI", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1032, }, @@ -32037,6 +32178,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN MON II", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1033, }, @@ -32044,6 +32187,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN MON O", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1034, }, @@ -32051,6 +32196,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN E ABOVE", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1035, }, @@ -32058,6 +32205,8 @@ characters.data={ category="mn", description="MYANMAR SIGN ANUSVARA", direction="nsm", + indic="m", + indicmark="t", linebreak="sa", unicodeslot=0x1036, }, @@ -32066,6 +32215,8 @@ characters.data={ combining=0x7, description="MYANMAR SIGN DOT BELOW", direction="nsm", + indic="s", + indicmark="b", linebreak="sa", unicodeslot=0x1037, }, @@ -32073,6 +32224,8 @@ characters.data={ category="mc", description="MYANMAR SIGN VISARGA", direction="l", + indic="m", + indicmark="r", linebreak="sa", unicodeslot=0x1038, }, @@ -32081,6 +32234,8 @@ characters.data={ combining=0x9, description="MYANMAR SIGN VIRAMA", direction="nsm", + indic="m", + indicmark="b", linebreak="sa", synonyms={ "myanmar killer" }, unicodeslot=0x1039, @@ -32090,6 +32245,8 @@ characters.data={ combining=0x9, description="MYANMAR SIGN ASAT", direction="nsm", + indic="m", + indicmark="t", linebreak="sa", unicodeslot=0x103A, }, @@ -32097,6 +32254,8 @@ characters.data={ category="mc", description="MYANMAR CONSONANT SIGN MEDIAL YA", direction="l", + indic="c", + indicmark="r", linebreak="sa", unicodeslot=0x103B, }, @@ -32104,6 +32263,7 @@ characters.data={ category="mc", description="MYANMAR CONSONANT SIGN MEDIAL RA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x103C, }, @@ -32111,6 +32271,8 @@ characters.data={ category="mn", description="MYANMAR CONSONANT SIGN MEDIAL WA", direction="nsm", + indic="c", + indicmark="b", linebreak="sa", unicodeslot=0x103D, }, @@ -32118,6 +32280,8 @@ characters.data={ category="mn", description="MYANMAR CONSONANT SIGN MEDIAL HA", direction="nsm", + indic="c", + indicmark="b", linebreak="sa", unicodeslot=0x103E, }, @@ -32125,6 +32289,7 @@ characters.data={ category="lo", description="MYANMAR LETTER GREAT SA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x103F, }, @@ -32132,6 +32297,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT ZERO", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1040, }, @@ -32139,6 +32305,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT ONE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1041, }, @@ -32146,6 +32313,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT TWO", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1042, }, @@ -32153,6 +32321,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT THREE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1043, }, @@ -32160,6 +32329,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT FOUR", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1044, }, @@ -32167,6 +32337,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT FIVE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1045, }, @@ -32174,6 +32345,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT SIX", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1046, }, @@ -32181,6 +32353,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT SEVEN", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1047, }, @@ -32188,6 +32361,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT EIGHT", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1048, }, @@ -32195,6 +32369,7 @@ characters.data={ category="nd", description="MYANMAR DIGIT NINE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1049, }, @@ -32202,6 +32377,7 @@ characters.data={ category="po", description="MYANMAR SIGN LITTLE SECTION", direction="l", + indic="o", linebreak="ba", unicodeslot=0x104A, }, @@ -32209,6 +32385,7 @@ characters.data={ category="po", description="MYANMAR SIGN SECTION", direction="l", + indic="o", linebreak="ba", unicodeslot=0x104B, }, @@ -32216,6 +32393,7 @@ characters.data={ category="po", description="MYANMAR SYMBOL LOCATIVE", direction="l", + indic="o", linebreak="al", unicodeslot=0x104C, }, @@ -32223,6 +32401,7 @@ characters.data={ category="po", description="MYANMAR SYMBOL COMPLETED", direction="l", + indic="o", linebreak="al", unicodeslot=0x104D, }, @@ -32230,6 +32409,7 @@ characters.data={ category="po", description="MYANMAR SYMBOL AFOREMENTIONED", direction="l", + indic="o", linebreak="al", unicodeslot=0x104E, }, @@ -32237,6 +32417,7 @@ characters.data={ category="po", description="MYANMAR SYMBOL GENITIVE", direction="l", + indic="o", linebreak="al", unicodeslot=0x104F, }, @@ -32244,6 +32425,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1050, }, @@ -32251,6 +32433,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SSA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1051, }, @@ -32258,6 +32441,7 @@ characters.data={ category="lo", description="MYANMAR LETTER VOCALIC R", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1052, }, @@ -32265,6 +32449,7 @@ characters.data={ category="lo", description="MYANMAR LETTER VOCALIC RR", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1053, }, @@ -32272,6 +32457,7 @@ characters.data={ category="lo", description="MYANMAR LETTER VOCALIC L", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1054, }, @@ -32279,6 +32465,7 @@ characters.data={ category="lo", description="MYANMAR LETTER VOCALIC LL", direction="l", + indic="i", linebreak="sa", unicodeslot=0x1055, }, @@ -32286,6 +32473,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN VOCALIC R", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x1056, }, @@ -32293,6 +32482,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN VOCALIC RR", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x1057, }, @@ -32300,6 +32491,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN VOCALIC L", direction="nsm", + indic="d", + indicmark="b", linebreak="sa", unicodeslot=0x1058, }, @@ -32307,6 +32500,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN VOCALIC LL", direction="nsm", + indic="d", + indicmark="b", linebreak="sa", unicodeslot=0x1059, }, @@ -32314,6 +32509,7 @@ characters.data={ category="lo", description="MYANMAR LETTER MON NGA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x105A, }, @@ -32321,6 +32517,7 @@ characters.data={ category="lo", description="MYANMAR LETTER MON JHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x105B, }, @@ -32328,6 +32525,7 @@ characters.data={ category="lo", description="MYANMAR LETTER MON BBA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x105C, }, @@ -32335,6 +32533,7 @@ characters.data={ category="lo", description="MYANMAR LETTER MON BBE", direction="l", + indic="c", linebreak="sa", unicodeslot=0x105D, }, @@ -32342,6 +32541,8 @@ characters.data={ category="mn", description="MYANMAR CONSONANT SIGN MON MEDIAL NA", direction="nsm", + indic="c", + indicmark="b", linebreak="sa", unicodeslot=0x105E, }, @@ -32349,6 +32550,8 @@ characters.data={ category="mn", description="MYANMAR CONSONANT SIGN MON MEDIAL MA", direction="nsm", + indic="c", + indicmark="b", linebreak="sa", unicodeslot=0x105F, }, @@ -32356,6 +32559,8 @@ characters.data={ category="mn", description="MYANMAR CONSONANT SIGN MON MEDIAL LA", direction="nsm", + indic="c", + indicmark="b", linebreak="sa", unicodeslot=0x1060, }, @@ -32363,6 +32568,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SGAW KAREN SHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1061, }, @@ -32370,6 +32576,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN SGAW KAREN EU", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x1062, }, @@ -32377,6 +32585,8 @@ characters.data={ category="mc", description="MYANMAR TONE MARK SGAW KAREN HATHI", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x1063, }, @@ -32384,6 +32594,8 @@ characters.data={ category="mc", description="MYANMAR TONE MARK SGAW KAREN KE PHO", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x1064, }, @@ -32391,6 +32603,7 @@ characters.data={ category="lo", description="MYANMAR LETTER WESTERN PWO KAREN THA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1065, }, @@ -32398,6 +32611,7 @@ characters.data={ category="lo", description="MYANMAR LETTER WESTERN PWO KAREN PWA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1066, }, @@ -32405,6 +32619,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN WESTERN PWO KAREN EU", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x1067, }, @@ -32412,6 +32628,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN WESTERN PWO KAREN UE", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x1068, }, @@ -32419,6 +32637,8 @@ characters.data={ category="mc", description="MYANMAR SIGN WESTERN PWO KAREN TONE-1", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x1069, }, @@ -32426,6 +32646,8 @@ characters.data={ category="mc", description="MYANMAR SIGN WESTERN PWO KAREN TONE-2", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x106A, }, @@ -32433,6 +32655,8 @@ characters.data={ category="mc", description="MYANMAR SIGN WESTERN PWO KAREN TONE-3", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x106B, }, @@ -32440,6 +32664,8 @@ characters.data={ category="mc", description="MYANMAR SIGN WESTERN PWO KAREN TONE-4", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x106C, }, @@ -32447,6 +32673,8 @@ characters.data={ category="mc", description="MYANMAR SIGN WESTERN PWO KAREN TONE-5", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x106D, }, @@ -32454,6 +32682,7 @@ characters.data={ category="lo", description="MYANMAR LETTER EASTERN PWO KAREN NNA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x106E, }, @@ -32461,6 +32690,7 @@ characters.data={ category="lo", description="MYANMAR LETTER EASTERN PWO KAREN YWA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x106F, }, @@ -32468,6 +32698,7 @@ characters.data={ category="lo", description="MYANMAR LETTER EASTERN PWO KAREN GHWA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1070, }, @@ -32475,6 +32706,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN GEBA KAREN I", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1071, }, @@ -32482,6 +32715,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN KAYAH OE", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1072, }, @@ -32489,6 +32724,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN KAYAH U", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1073, }, @@ -32496,6 +32733,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN KAYAH EE", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1074, }, @@ -32503,6 +32742,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN KA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1075, variants={ @@ -32513,6 +32753,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN KHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1076, }, @@ -32520,6 +32761,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN GA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1077, }, @@ -32527,6 +32769,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN CA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1078, variants={ @@ -32537,6 +32780,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN ZA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1079, }, @@ -32544,6 +32788,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN NYA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x107A, variants={ @@ -32554,6 +32799,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN DA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x107B, }, @@ -32561,6 +32807,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN NA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x107C, }, @@ -32568,6 +32815,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN PHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x107D, }, @@ -32575,6 +32823,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN FA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x107E, }, @@ -32582,6 +32831,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN BA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x107F, }, @@ -32589,6 +32839,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN THA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1080, variants={ @@ -32599,6 +32850,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN HA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x1081, }, @@ -32606,6 +32858,8 @@ characters.data={ category="mn", description="MYANMAR CONSONANT SIGN SHAN MEDIAL WA", direction="nsm", + indic="c", + indicmark="b", linebreak="sa", unicodeslot=0x1082, }, @@ -32613,6 +32867,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN SHAN AA", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x1083, }, @@ -32620,6 +32876,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN SHAN E", direction="l", + indic="d", + indicmark="l", linebreak="sa", unicodeslot=0x1084, }, @@ -32627,6 +32885,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN SHAN E ABOVE", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1085, }, @@ -32634,6 +32894,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN SHAN FINAL Y", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x1086, }, @@ -32641,6 +32903,8 @@ characters.data={ category="mc", description="MYANMAR SIGN SHAN TONE-2", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x1087, }, @@ -32648,6 +32912,8 @@ characters.data={ category="mc", description="MYANMAR SIGN SHAN TONE-3", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x1088, }, @@ -32655,6 +32921,8 @@ characters.data={ category="mc", description="MYANMAR SIGN SHAN TONE-5", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x1089, }, @@ -32662,6 +32930,8 @@ characters.data={ category="mc", description="MYANMAR SIGN SHAN TONE-6", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x108A, }, @@ -32669,6 +32939,8 @@ characters.data={ category="mc", description="MYANMAR SIGN SHAN COUNCIL TONE-2", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x108B, }, @@ -32676,6 +32948,8 @@ characters.data={ category="mc", description="MYANMAR SIGN SHAN COUNCIL TONE-3", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x108C, }, @@ -32684,6 +32958,8 @@ characters.data={ combining=0xDC, description="MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE", direction="nsm", + indic="s", + indicmark="b", linebreak="sa", unicodeslot=0x108D, }, @@ -32691,6 +32967,7 @@ characters.data={ category="lo", description="MYANMAR LETTER RUMAI PALAUNG FA", direction="l", + indic="c", linebreak="sa", unicodeslot=0x108E, }, @@ -32698,6 +32975,8 @@ characters.data={ category="mc", description="MYANMAR SIGN RUMAI PALAUNG TONE-5", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x108F, }, @@ -32705,6 +32984,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT ZERO", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1090, }, @@ -32712,6 +32992,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT ONE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1091, }, @@ -32719,6 +33000,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT TWO", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1092, }, @@ -32726,6 +33008,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT THREE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1093, }, @@ -32733,6 +33016,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT FOUR", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1094, }, @@ -32740,6 +33024,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT FIVE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1095, }, @@ -32747,6 +33032,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT SIX", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1096, }, @@ -32754,6 +33040,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT SEVEN", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1097, }, @@ -32761,6 +33048,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT EIGHT", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1098, }, @@ -32768,6 +33056,7 @@ characters.data={ category="nd", description="MYANMAR SHAN DIGIT NINE", direction="l", + indic="o", linebreak="nu", unicodeslot=0x1099, }, @@ -32775,6 +33064,8 @@ characters.data={ category="mc", description="MYANMAR SIGN KHAMTI TONE-1", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x109A, }, @@ -32782,6 +33073,8 @@ characters.data={ category="mc", description="MYANMAR SIGN KHAMTI TONE-3", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0x109B, }, @@ -32789,6 +33082,8 @@ characters.data={ category="mc", description="MYANMAR VOWEL SIGN AITON A", direction="l", + indic="d", + indicmark="r", linebreak="sa", unicodeslot=0x109C, }, @@ -32796,6 +33091,8 @@ characters.data={ category="mn", description="MYANMAR VOWEL SIGN AITON AI", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0x109D, }, @@ -32803,6 +33100,7 @@ characters.data={ category="so", description="MYANMAR SYMBOL SHAN ONE", direction="l", + indic="o", linebreak="sa", unicodeslot=0x109E, }, @@ -32810,6 +33108,7 @@ characters.data={ category="so", description="MYANMAR SYMBOL SHAN EXCLAMATION", direction="l", + indic="o", linebreak="sa", unicodeslot=0x109F, }, @@ -46377,6 +46676,14 @@ characters.data={ linebreak="al", unicodeslot=0x1877, }, + [0x1878]={ + arabic="d", + category="lo", + description="MONGOLIAN LETTER CHA WITH TWO DOTS", + direction="l", + linebreak="al", + unicodeslot=0x1878, + }, [0x1880]={ arabic="u", category="lo", @@ -52619,6 +52926,328 @@ characters.data={ linebreak="al", unicodeslot=0x1C88, }, + [0x1C90]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER AN", + direction="l", + linebreak="al", + unicodeslot=0x1C90, + }, + [0x1C91]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER BAN", + direction="l", + linebreak="al", + unicodeslot=0x1C91, + }, + [0x1C92]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER GAN", + direction="l", + linebreak="al", + unicodeslot=0x1C92, + }, + [0x1C93]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER DON", + direction="l", + linebreak="al", + unicodeslot=0x1C93, + }, + [0x1C94]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER EN", + direction="l", + linebreak="al", + unicodeslot=0x1C94, + }, + [0x1C95]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER VIN", + direction="l", + linebreak="al", + unicodeslot=0x1C95, + }, + [0x1C96]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER ZEN", + direction="l", + linebreak="al", + unicodeslot=0x1C96, + }, + [0x1C97]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER TAN", + direction="l", + linebreak="al", + unicodeslot=0x1C97, + }, + [0x1C98]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER IN", + direction="l", + linebreak="al", + unicodeslot=0x1C98, + }, + [0x1C99]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER KAN", + direction="l", + linebreak="al", + unicodeslot=0x1C99, + }, + [0x1C9A]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER LAS", + direction="l", + linebreak="al", + unicodeslot=0x1C9A, + }, + [0x1C9B]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER MAN", + direction="l", + linebreak="al", + unicodeslot=0x1C9B, + }, + [0x1C9C]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER NAR", + direction="l", + linebreak="al", + unicodeslot=0x1C9C, + }, + [0x1C9D]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER ON", + direction="l", + linebreak="al", + unicodeslot=0x1C9D, + }, + [0x1C9E]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER PAR", + direction="l", + linebreak="al", + unicodeslot=0x1C9E, + }, + [0x1C9F]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER ZHAR", + direction="l", + linebreak="al", + unicodeslot=0x1C9F, + }, + [0x1CA0]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER RAE", + direction="l", + linebreak="al", + unicodeslot=0x1CA0, + }, + [0x1CA1]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER SAN", + direction="l", + linebreak="al", + unicodeslot=0x1CA1, + }, + [0x1CA2]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER TAR", + direction="l", + linebreak="al", + unicodeslot=0x1CA2, + }, + [0x1CA3]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER UN", + direction="l", + linebreak="al", + unicodeslot=0x1CA3, + }, + [0x1CA4]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER PHAR", + direction="l", + linebreak="al", + unicodeslot=0x1CA4, + }, + [0x1CA5]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER KHAR", + direction="l", + linebreak="al", + unicodeslot=0x1CA5, + }, + [0x1CA6]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER GHAN", + direction="l", + linebreak="al", + unicodeslot=0x1CA6, + }, + [0x1CA7]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER QAR", + direction="l", + linebreak="al", + unicodeslot=0x1CA7, + }, + [0x1CA8]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER SHIN", + direction="l", + linebreak="al", + unicodeslot=0x1CA8, + }, + [0x1CA9]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER CHIN", + direction="l", + linebreak="al", + unicodeslot=0x1CA9, + }, + [0x1CAA]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER CAN", + direction="l", + linebreak="al", + unicodeslot=0x1CAA, + }, + [0x1CAB]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER JIL", + direction="l", + linebreak="al", + unicodeslot=0x1CAB, + }, + [0x1CAC]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER CIL", + direction="l", + linebreak="al", + unicodeslot=0x1CAC, + }, + [0x1CAD]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER CHAR", + direction="l", + linebreak="al", + unicodeslot=0x1CAD, + }, + [0x1CAE]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER XAN", + direction="l", + linebreak="al", + unicodeslot=0x1CAE, + }, + [0x1CAF]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER JHAN", + direction="l", + linebreak="al", + unicodeslot=0x1CAF, + }, + [0x1CB0]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER HAE", + direction="l", + linebreak="al", + unicodeslot=0x1CB0, + }, + [0x1CB1]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER HE", + direction="l", + linebreak="al", + unicodeslot=0x1CB1, + }, + [0x1CB2]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER HIE", + direction="l", + linebreak="al", + unicodeslot=0x1CB2, + }, + [0x1CB3]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER WE", + direction="l", + linebreak="al", + unicodeslot=0x1CB3, + }, + [0x1CB4]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER HAR", + direction="l", + linebreak="al", + unicodeslot=0x1CB4, + }, + [0x1CB5]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER HOE", + direction="l", + linebreak="al", + unicodeslot=0x1CB5, + }, + [0x1CB6]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER FI", + direction="l", + linebreak="al", + unicodeslot=0x1CB6, + }, + [0x1CB7]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER YN", + direction="l", + linebreak="al", + unicodeslot=0x1CB7, + }, + [0x1CB8]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER ELIFI", + direction="l", + linebreak="al", + unicodeslot=0x1CB8, + }, + [0x1CB9]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN", + direction="l", + linebreak="al", + unicodeslot=0x1CB9, + }, + [0x1CBA]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER AIN", + direction="l", + linebreak="al", + unicodeslot=0x1CBA, + }, + [0x1CBD]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER AEN", + direction="l", + linebreak="al", + unicodeslot=0x1CBD, + }, + [0x1CBE]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1CBE, + }, + [0x1CBF]={ + category="lu", + description="GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1CBF, + }, [0x1CC0]={ category="po", description="SUNDANESE PUNCTUATION BINDU SURYA", @@ -65371,6 +66000,7 @@ characters.data={ linebreak="ai", mathclass="ordinary", mathname="rightangle", + mirror=0x2BFE, unicodeslot=0x221F, }, [0x2220]={ @@ -65382,6 +66012,7 @@ characters.data={ linebreak="ai", mathclass="ordinary", mathname="angle", + mirror=0x29A3, unicodeslot=0x2220, }, [0x2221]={ @@ -65391,6 +66022,7 @@ characters.data={ linebreak="al", mathclass="ordinary", mathname="measuredangle", + mirror=0x299B, unicodeslot=0x2221, }, [0x2222]={ @@ -65400,6 +66032,7 @@ characters.data={ linebreak="al", mathclass="ordinary", mathname="sphericalangle", + mirror=0x29A0, synonyms={ "angle arc" }, unicodeslot=0x2222, }, @@ -65430,6 +66063,7 @@ characters.data={ name="nmid", }, }, + mirror=0x2AEE, specials={ "char", 0x2223, 0x338 }, unicodeslot=0x2224, }, @@ -65834,6 +66468,7 @@ characters.data={ name="cong", }, }, + mirror=0x224C, unicodeslot=0x2245, }, [0x2246]={ @@ -65909,6 +66544,7 @@ characters.data={ direction="on", linebreak="ai", mathclass="relation", + mirror=0x2245, unicodeslot=0x224C, }, [0x224D]={ @@ -67110,6 +67746,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="multimap", + mirror=0x27DC, unicodeslot=0x22B8, }, [0x22B9]={ @@ -73450,8 +74087,8 @@ characters.data={ }, [0x25CC]={ adobename="dottedcircle", - contextname="dottedcircle", category="so", + contextname="dottedcircle", description="DOTTED CIRCLE", direction="on", linebreak="al", @@ -77559,6 +78196,7 @@ characters.data={ description="LEFT MULTIMAP", direction="on", linebreak="al", + mirror=0x22B8, unicodeslot=0x27DC, }, [0x27DD]={ @@ -80944,6 +81582,7 @@ characters.data={ description="MEASURED ANGLE OPENING LEFT", direction="on", linebreak="al", + mirror=0x2221, unicodeslot=0x299B, }, [0x299C]={ @@ -80979,6 +81618,7 @@ characters.data={ description="SPHERICAL ANGLE OPENING LEFT", direction="on", linebreak="al", + mirror=0x2222, unicodeslot=0x29A0, }, [0x29A1]={ @@ -81000,6 +81640,7 @@ characters.data={ description="REVERSED ANGLE", direction="on", linebreak="al", + mirror=0x2220, unicodeslot=0x29A3, }, [0x29A4]={ @@ -81007,6 +81648,7 @@ characters.data={ description="ANGLE WITH UNDERBAR", direction="on", linebreak="al", + mirror=0x29A5, unicodeslot=0x29A4, }, [0x29A5]={ @@ -81014,6 +81656,7 @@ characters.data={ description="REVERSED ANGLE WITH UNDERBAR", direction="on", linebreak="al", + mirror=0x29A4, unicodeslot=0x29A5, }, [0x29A6]={ @@ -81035,6 +81678,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT", direction="on", linebreak="al", + mirror=0x29A9, unicodeslot=0x29A8, }, [0x29A9]={ @@ -81042,6 +81686,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT", direction="on", linebreak="al", + mirror=0x29A8, unicodeslot=0x29A9, }, [0x29AA]={ @@ -81049,6 +81694,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT", direction="on", linebreak="al", + mirror=0x29AB, unicodeslot=0x29AA, }, [0x29AB]={ @@ -81056,6 +81702,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT", direction="on", linebreak="al", + mirror=0x29AA, unicodeslot=0x29AB, }, [0x29AC]={ @@ -81063,6 +81710,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP", direction="on", linebreak="al", + mirror=0x29AD, unicodeslot=0x29AC, }, [0x29AD]={ @@ -81070,6 +81718,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP", direction="on", linebreak="al", + mirror=0x29AC, unicodeslot=0x29AD, }, [0x29AE]={ @@ -81077,6 +81726,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN", direction="on", linebreak="al", + mirror=0x29AF, unicodeslot=0x29AE, }, [0x29AF]={ @@ -81084,6 +81734,7 @@ characters.data={ description="MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN", direction="on", linebreak="al", + mirror=0x29AE, unicodeslot=0x29AF, }, [0x29B0]={ @@ -81502,6 +82153,7 @@ characters.data={ description="DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK", direction="on", linebreak="al", + mirror=0x29E9, unicodeslot=0x29E8, }, [0x29E9]={ @@ -81509,6 +82161,7 @@ characters.data={ description="DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK", direction="on", linebreak="al", + mirror=0x29E8, unicodeslot=0x29E9, }, [0x29EA]={ @@ -82608,6 +83261,7 @@ characters.data={ description="LESS-THAN WITH QUESTION MARK ABOVE", direction="on", linebreak="al", + mirror=0x2A7C, unicodeslot=0x2A7B, }, [0x2A7C]={ @@ -82615,6 +83269,7 @@ characters.data={ description="GREATER-THAN WITH QUESTION MARK ABOVE", direction="on", linebreak="al", + mirror=0x2A7B, unicodeslot=0x2A7C, }, [0x2A7D]={ @@ -82692,6 +83347,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="lessapprox", + mirror=0x2A86, unicodeslot=0x2A85, }, [0x2A86]={ @@ -82701,6 +83357,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="gtrapprox", + mirror=0x2A85, unicodeslot=0x2A86, }, [0x2A87]={ @@ -82710,6 +83367,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="lneq", + mirror=0x2A88, unicodeslot=0x2A87, }, [0x2A88]={ @@ -82719,6 +83377,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="rneq", + mirror=0x2A87, unicodeslot=0x2A88, }, [0x2A89]={ @@ -82728,6 +83387,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="lnapprox", + mirror=0x2A8A, unicodeslot=0x2A89, }, [0x2A8A]={ @@ -82737,6 +83397,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="gnapprox", + mirror=0x2A89, unicodeslot=0x2A8A, }, [0x2A8B]={ @@ -82766,6 +83427,7 @@ characters.data={ description="LESS-THAN ABOVE SIMILAR OR EQUAL", direction="on", linebreak="al", + mirror=0x2A8E, unicodeslot=0x2A8D, }, [0x2A8E]={ @@ -82773,6 +83435,7 @@ characters.data={ description="GREATER-THAN ABOVE SIMILAR OR EQUAL", direction="on", linebreak="al", + mirror=0x2A8D, unicodeslot=0x2A8E, }, [0x2A8F]={ @@ -82780,6 +83443,7 @@ characters.data={ description="LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN", direction="on", linebreak="al", + mirror=0x2A90, unicodeslot=0x2A8F, }, [0x2A90]={ @@ -82787,6 +83451,7 @@ characters.data={ description="GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN", direction="on", linebreak="al", + mirror=0x2A8F, unicodeslot=0x2A90, }, [0x2A91]={ @@ -82894,6 +83559,7 @@ characters.data={ description="SIMILAR OR LESS-THAN", direction="on", linebreak="al", + mirror=0x2A9E, unicodeslot=0x2A9D, variants={ [0xFE00]="with similar following the slant of the upper leg", @@ -82904,6 +83570,7 @@ characters.data={ description="SIMILAR OR GREATER-THAN", direction="on", linebreak="al", + mirror=0x2A9D, unicodeslot=0x2A9E, variants={ [0xFE00]="with similar following the slant of the upper leg", @@ -82914,6 +83581,7 @@ characters.data={ description="SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN", direction="on", linebreak="al", + mirror=0x2AA0, unicodeslot=0x2A9F, }, [0x2AA0]={ @@ -82921,6 +83589,7 @@ characters.data={ description="SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN", direction="on", linebreak="al", + mirror=0x2A9F, unicodeslot=0x2AA0, }, [0x2AA1]={ @@ -83065,6 +83734,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="precneq", + mirror=0x2AB2, unicodeslot=0x2AB1, }, [0x2AB2]={ @@ -83074,6 +83744,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="succneq", + mirror=0x2AB1, unicodeslot=0x2AB2, }, [0x2AB3]={ @@ -83103,6 +83774,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="precneqq", + mirror=0x2AB6, unicodeslot=0x2AB5, }, [0x2AB6]={ @@ -83112,6 +83784,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="succneqq", + mirror=0x2AB5, unicodeslot=0x2AB6, }, [0x2AB7]={ @@ -83121,6 +83794,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="precapprox", + mirror=0x2AB8, unicodeslot=0x2AB7, }, [0x2AB8]={ @@ -83130,6 +83804,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="succapprox", + mirror=0x2AB7, unicodeslot=0x2AB8, }, [0x2AB9]={ @@ -83139,6 +83814,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="precnapprox", + mirror=0x2ABA, unicodeslot=0x2AB9, }, [0x2ABA]={ @@ -83148,6 +83824,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="succnapprox", + mirror=0x2AB9, unicodeslot=0x2ABA, }, [0x2ABB]={ @@ -83255,6 +83932,7 @@ characters.data={ description="SUBSET OF ABOVE TILDE OPERATOR", direction="on", linebreak="al", + mirror=0x2AC8, unicodeslot=0x2AC7, }, [0x2AC8]={ @@ -83262,6 +83940,7 @@ characters.data={ description="SUPERSET OF ABOVE TILDE OPERATOR", direction="on", linebreak="al", + mirror=0x2AC7, unicodeslot=0x2AC8, }, [0x2AC9]={ @@ -83269,6 +83948,7 @@ characters.data={ description="SUBSET OF ABOVE ALMOST EQUAL TO", direction="on", linebreak="al", + mirror=0x2ACA, unicodeslot=0x2AC9, }, [0x2ACA]={ @@ -83276,6 +83956,7 @@ characters.data={ description="SUPERSET OF ABOVE ALMOST EQUAL TO", direction="on", linebreak="al", + mirror=0x2AC9, unicodeslot=0x2ACA, }, [0x2ACB]={ @@ -83285,6 +83966,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="subsetneqq", + mirror=0x2ACC, unicodeslot=0x2ACB, variants={ [0xFE00]="with stroke through bottom members", @@ -83297,6 +83979,7 @@ characters.data={ linebreak="al", mathclass="relation", mathname="supsetneqq", + mirror=0x2ACB, unicodeslot=0x2ACC, variants={ [0xFE00]="with stroke through bottom members", @@ -83559,6 +84242,7 @@ characters.data={ description="DOES NOT DIVIDE WITH REVERSED NEGATION SLASH", direction="on", linebreak="al", + mirror=0x2224, unicodeslot=0x2AEE, }, [0x2AEF]={ @@ -84998,6 +85682,27 @@ characters.data={ synonyms={ "escape" }, unicodeslot=0x2BB9, }, + [0x2BBA]={ + category="so", + description="OVERLAPPING WHITE SQUARES", + direction="on", + linebreak="al", + unicodeslot=0x2BBA, + }, + [0x2BBB]={ + category="so", + description="OVERLAPPING WHITE AND BLACK SQUARES", + direction="on", + linebreak="al", + unicodeslot=0x2BBB, + }, + [0x2BBC]={ + category="so", + description="OVERLAPPING BLACK SQUARES", + direction="on", + linebreak="al", + unicodeslot=0x2BBC, + }, [0x2BBD]={ category="so", description="BALLOT BOX WITH LIGHT X", @@ -85145,6 +85850,181 @@ characters.data={ linebreak="al", unicodeslot=0x2BD2, }, + [0x2BD3]={ + category="so", + description="PLUTO FORM TWO", + direction="on", + linebreak="al", + unicodeslot=0x2BD3, + }, + [0x2BD4]={ + category="so", + description="PLUTO FORM THREE", + direction="on", + linebreak="al", + unicodeslot=0x2BD4, + }, + [0x2BD5]={ + category="so", + description="PLUTO FORM FOUR", + direction="on", + linebreak="al", + unicodeslot=0x2BD5, + }, + [0x2BD6]={ + category="so", + description="PLUTO FORM FIVE", + direction="on", + linebreak="al", + unicodeslot=0x2BD6, + }, + [0x2BD7]={ + category="so", + description="TRANSPLUTO", + direction="on", + linebreak="al", + unicodeslot=0x2BD7, + }, + [0x2BD8]={ + category="so", + description="PROSERPINA", + direction="on", + linebreak="al", + unicodeslot=0x2BD8, + }, + [0x2BD9]={ + category="so", + description="ASTRAEA", + direction="on", + linebreak="al", + unicodeslot=0x2BD9, + }, + [0x2BDA]={ + category="so", + description="HYGIEA", + direction="on", + linebreak="al", + unicodeslot=0x2BDA, + }, + [0x2BDB]={ + category="so", + description="PHOLUS", + direction="on", + linebreak="al", + unicodeslot=0x2BDB, + }, + [0x2BDC]={ + category="so", + description="NESSUS", + direction="on", + linebreak="al", + unicodeslot=0x2BDC, + }, + [0x2BDD]={ + category="so", + description="WHITE MOON SELENA", + direction="on", + linebreak="al", + unicodeslot=0x2BDD, + }, + [0x2BDE]={ + category="so", + description="BLACK DIAMOND ON CROSS", + direction="on", + linebreak="al", + unicodeslot=0x2BDE, + }, + [0x2BDF]={ + category="so", + description="TRUE LIGHT MOON ARTA", + direction="on", + linebreak="al", + unicodeslot=0x2BDF, + }, + [0x2BE0]={ + category="so", + description="CUPIDO", + direction="on", + linebreak="al", + unicodeslot=0x2BE0, + }, + [0x2BE1]={ + category="so", + description="HADES", + direction="on", + linebreak="al", + unicodeslot=0x2BE1, + }, + [0x2BE2]={ + category="so", + description="ZEUS", + direction="on", + linebreak="al", + unicodeslot=0x2BE2, + }, + [0x2BE3]={ + category="so", + description="KRONOS", + direction="on", + linebreak="al", + unicodeslot=0x2BE3, + }, + [0x2BE4]={ + category="so", + description="APOLLON", + direction="on", + linebreak="al", + unicodeslot=0x2BE4, + }, + [0x2BE5]={ + category="so", + description="ADMETOS", + direction="on", + linebreak="al", + unicodeslot=0x2BE5, + }, + [0x2BE6]={ + category="so", + description="VULCANUS", + direction="on", + linebreak="al", + unicodeslot=0x2BE6, + }, + [0x2BE7]={ + category="so", + description="POSEIDON", + direction="on", + linebreak="al", + unicodeslot=0x2BE7, + }, + [0x2BE8]={ + category="so", + description="LEFT HALF BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2BE8, + }, + [0x2BE9]={ + category="so", + description="RIGHT HALF BLACK STAR", + direction="on", + linebreak="al", + unicodeslot=0x2BE9, + }, + [0x2BEA]={ + category="so", + description="STAR WITH LEFT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2BEA, + }, + [0x2BEB]={ + category="so", + description="STAR WITH RIGHT HALF BLACK", + direction="on", + linebreak="al", + unicodeslot=0x2BEB, + }, [0x2BEC]={ category="so", description="LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS", @@ -85173,6 +86053,112 @@ characters.data={ linebreak="al", unicodeslot=0x2BEF, }, + [0x2BF0]={ + category="so", + description="ERIS FORM ONE", + direction="on", + linebreak="al", + unicodeslot=0x2BF0, + }, + [0x2BF1]={ + category="so", + description="ERIS FORM TWO", + direction="on", + linebreak="al", + unicodeslot=0x2BF1, + }, + [0x2BF2]={ + category="so", + description="SEDNA", + direction="on", + linebreak="al", + unicodeslot=0x2BF2, + }, + [0x2BF3]={ + category="so", + description="RUSSIAN ASTROLOGICAL SYMBOL VIGINTILE", + direction="on", + linebreak="al", + unicodeslot=0x2BF3, + }, + [0x2BF4]={ + category="so", + description="RUSSIAN ASTROLOGICAL SYMBOL NOVILE", + direction="on", + linebreak="al", + unicodeslot=0x2BF4, + }, + [0x2BF5]={ + category="so", + description="RUSSIAN ASTROLOGICAL SYMBOL QUINTILE", + direction="on", + linebreak="al", + unicodeslot=0x2BF5, + }, + [0x2BF6]={ + category="so", + description="RUSSIAN ASTROLOGICAL SYMBOL BINOVILE", + direction="on", + linebreak="al", + unicodeslot=0x2BF6, + }, + [0x2BF7]={ + category="so", + description="RUSSIAN ASTROLOGICAL SYMBOL SENTAGON", + direction="on", + linebreak="al", + unicodeslot=0x2BF7, + }, + [0x2BF8]={ + category="so", + description="RUSSIAN ASTROLOGICAL SYMBOL TREDECILE", + direction="on", + linebreak="al", + unicodeslot=0x2BF8, + }, + [0x2BF9]={ + category="so", + description="EQUALS SIGN WITH INFINITY BELOW", + direction="on", + linebreak="al", + unicodeslot=0x2BF9, + }, + [0x2BFA]={ + category="so", + description="UNITED SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2BFA, + }, + [0x2BFB]={ + category="so", + description="SEPARATED SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2BFB, + }, + [0x2BFC]={ + category="so", + description="DOUBLED SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2BFC, + }, + [0x2BFD]={ + category="so", + description="PASSED SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x2BFD, + }, + [0x2BFE]={ + category="so", + description="REVERSED RIGHT ANGLE", + direction="on", + linebreak="al", + mirror=0x221F, + unicodeslot=0x2BFE, + }, [0x2C00]={ category="lu", description="GLAGOLITIC CAPITAL LETTER AZU", @@ -89226,6 +90212,41 @@ characters.data={ linebreak="ba", unicodeslot=0x2E49, }, + [0x2E4A]={ + category="po", + description="DOTTED SOLIDUS", + direction="on", + linebreak="ba", + unicodeslot=0x2E4A, + }, + [0x2E4B]={ + category="po", + description="TRIPLE DAGGER", + direction="on", + linebreak="al", + unicodeslot=0x2E4B, + }, + [0x2E4C]={ + category="po", + description="MEDIEVAL COMMA", + direction="on", + linebreak="ba", + unicodeslot=0x2E4C, + }, + [0x2E4D]={ + category="po", + description="PARAGRAPHUS MARK", + direction="on", + linebreak="al", + unicodeslot=0x2E4D, + }, + [0x2E4E]={ + category="po", + description="PUNCTUS ELEVATUS MARK", + direction="on", + linebreak="ba", + unicodeslot=0x2E4E, + }, [0x2E80]={ category="so", cjkwd="w", @@ -95434,6 +96455,14 @@ characters.data={ linebreak="id", unicodeslot=0x312E, }, + [0x312F]={ + category="lo", + cjkwd="w", + description="BOPOMOFO LETTER NN", + direction="l", + linebreak="id", + unicodeslot=0x312F, + }, [0x3131]={ adobename="kiyeokkorean", category="lo", @@ -117174,6 +118203,13 @@ characters.data={ linebreak="al", unicodeslot=0xA7AE, }, + [0xA7AF]={ + category="ll", + description="LATIN LETTER SMALL CAPITAL Q", + direction="l", + linebreak="al", + unicodeslot=0xA7AF, + }, [0xA7B0]={ category="lu", description="LATIN CAPITAL LETTER TURNED K", @@ -117230,6 +118266,20 @@ characters.data={ linebreak="al", unicodeslot=0xA7B7, }, + [0xA7B8]={ + category="lu", + description="LATIN CAPITAL LETTER U WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0xA7B8, + }, + [0xA7B9]={ + category="ll", + description="LATIN SMALL LETTER U WITH STROKE", + direction="l", + linebreak="al", + unicodeslot=0xA7B9, + }, [0xA7F7]={ category="lo", description="LATIN EPIGRAPHIC LETTER SIDEWAYS I", @@ -118975,6 +120025,20 @@ characters.data={ linebreak="al", unicodeslot=0xA8FD, }, + [0xA8FE]={ + category="lo", + description="DEVANAGARI LETTER AY", + direction="l", + linebreak="al", + unicodeslot=0xA8FE, + }, + [0xA8FF]={ + category="mn", + description="DEVANAGARI VOWEL SIGN AY", + direction="nsm", + linebreak="cm", + unicodeslot=0xA8FF, + }, [0xA900]={ category="nd", description="KAYAH LI DIGIT ZERO", @@ -120449,6 +121513,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN GHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E0, }, @@ -120456,6 +121521,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN CHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E1, }, @@ -120463,6 +121529,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN JHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E2, }, @@ -120470,6 +121537,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN NNA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E3, }, @@ -120477,6 +121545,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHAN BHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E4, }, @@ -120484,6 +121553,8 @@ characters.data={ category="mn", description="MYANMAR SIGN SHAN SAW", direction="nsm", + indic="d", + indicmark="t", linebreak="sa", unicodeslot=0xA9E5, }, @@ -120491,6 +121562,7 @@ characters.data={ category="lm", description="MYANMAR MODIFIER LETTER SHAN REDUPLICATION", direction="l", + indic="o", linebreak="sa", unicodeslot=0xA9E6, }, @@ -120498,6 +121570,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING NYA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E7, }, @@ -120505,6 +121578,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING FA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E8, }, @@ -120512,6 +121586,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING GA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9E9, }, @@ -120519,6 +121594,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING GHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9EA, }, @@ -120526,6 +121602,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING JA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9EB, }, @@ -120533,6 +121610,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING JHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9EC, }, @@ -120540,6 +121618,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING DDA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9ED, }, @@ -120547,6 +121626,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING DDHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9EE, }, @@ -120554,6 +121634,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING NNA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9EF, }, @@ -120561,6 +121642,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT ZERO", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F0, }, @@ -120568,6 +121650,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT ONE", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F1, }, @@ -120575,6 +121658,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT TWO", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F2, }, @@ -120582,6 +121666,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT THREE", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F3, }, @@ -120589,6 +121674,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT FOUR", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F4, }, @@ -120596,6 +121682,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT FIVE", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F5, }, @@ -120603,6 +121690,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT SIX", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F6, }, @@ -120610,6 +121698,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT SEVEN", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F7, }, @@ -120617,6 +121706,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT EIGHT", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F8, }, @@ -120624,6 +121714,7 @@ characters.data={ category="nd", description="MYANMAR TAI LAING DIGIT NINE", direction="l", + indic="o", linebreak="nu", unicodeslot=0xA9F9, }, @@ -120631,6 +121722,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING LLA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9FA, }, @@ -120638,6 +121730,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING DA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9FB, }, @@ -120645,6 +121738,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING DHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9FC, }, @@ -120652,6 +121746,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING BA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9FD, }, @@ -120659,6 +121754,7 @@ characters.data={ category="lo", description="MYANMAR LETTER TAI LAING BHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xA9FE, }, @@ -121247,6 +122343,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI GA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA60, variants={ @@ -121257,6 +122354,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI CA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA61, variants={ @@ -121267,6 +122365,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI CHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA62, variants={ @@ -121277,6 +122376,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI JA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA63, variants={ @@ -121287,6 +122387,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI JHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA64, variants={ @@ -121297,6 +122398,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI NYA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA65, variants={ @@ -121307,6 +122409,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI TTA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA66, variants={ @@ -121317,6 +122420,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI TTHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA67, }, @@ -121324,6 +122428,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI DDA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA68, }, @@ -121331,6 +122436,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI DDHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA69, }, @@ -121338,6 +122444,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI DHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA6A, }, @@ -121355,6 +122462,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI SA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA6C, variants={ @@ -121365,6 +122473,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI HA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA6D, }, @@ -121372,6 +122481,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI HHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA6E, }, @@ -121379,6 +122489,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI FA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA6F, variants={ @@ -121389,6 +122500,7 @@ characters.data={ category="lm", description="MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION", direction="l", + indic="o", linebreak="sa", unicodeslot=0xAA70, }, @@ -121396,6 +122508,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI XA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA71, }, @@ -121403,6 +122516,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI ZA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA72, }, @@ -121410,6 +122524,7 @@ characters.data={ category="lo", description="MYANMAR LETTER KHAMTI RA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA73, }, @@ -121417,6 +122532,7 @@ characters.data={ category="lo", description="MYANMAR LOGOGRAM KHAMTI OAY", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA74, }, @@ -121424,6 +122540,7 @@ characters.data={ category="lo", description="MYANMAR LOGOGRAM KHAMTI QN", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA75, }, @@ -121431,6 +122548,7 @@ characters.data={ category="lo", description="MYANMAR LOGOGRAM KHAMTI HM", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA76, }, @@ -121438,6 +122556,7 @@ characters.data={ category="so", description="MYANMAR SYMBOL AITON EXCLAMATION", direction="l", + indic="o", linebreak="sa", unicodeslot=0xAA77, }, @@ -121445,6 +122564,7 @@ characters.data={ category="so", description="MYANMAR SYMBOL AITON ONE", direction="l", + indic="o", linebreak="sa", unicodeslot=0xAA78, }, @@ -121452,6 +122572,7 @@ characters.data={ category="so", description="MYANMAR SYMBOL AITON TWO", direction="l", + indic="o", linebreak="sa", unicodeslot=0xAA79, }, @@ -121459,6 +122580,7 @@ characters.data={ category="lo", description="MYANMAR LETTER AITON RA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA7A, variants={ @@ -121469,6 +122591,8 @@ characters.data={ category="mc", description="MYANMAR SIGN PAO KAREN TONE", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0xAA7B, }, @@ -121476,6 +122600,8 @@ characters.data={ category="mn", description="MYANMAR SIGN TAI LAING TONE-2", direction="nsm", + indic="s", + indicmark="t", linebreak="sa", unicodeslot=0xAA7C, }, @@ -121483,6 +122609,8 @@ characters.data={ category="mc", description="MYANMAR SIGN TAI LAING TONE-5", direction="l", + indic="s", + indicmark="r", linebreak="sa", unicodeslot=0xAA7D, }, @@ -121490,6 +122618,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHWE PALAUNG CHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA7E, }, @@ -121497,6 +122626,7 @@ characters.data={ category="lo", description="MYANMAR LETTER SHWE PALAUNG SHA", direction="l", + indic="c", linebreak="sa", unicodeslot=0xAA7F, }, @@ -136230,6 +137360,9 @@ characters.data={ linebreak="id", specials={ "wide", 0x30 }, unicodeslot=0xFF10, + variants={ + [0xFE00]="short diagonal stroke form", + }, }, [0xFF11]={ adobename="onemonospace", @@ -150982,6 +152115,20 @@ characters.data={ linebreak="al", unicodeslot=0x10A33, }, + [0x10A34]={ + category="lo", + description="KHAROSHTHI LETTER TTTA", + direction="r", + linebreak="al", + unicodeslot=0x10A34, + }, + [0x10A35]={ + category="lo", + description="KHAROSHTHI LETTER VHA", + direction="r", + linebreak="al", + unicodeslot=0x10A35, + }, [0x10A38]={ category="mn", combining=0xE6, @@ -151070,6 +152217,13 @@ characters.data={ linebreak="al", unicodeslot=0x10A47, }, + [0x10A48]={ + category="no", + description="KHAROSHTHI FRACTION ONE HALF", + direction="r", + linebreak="al", + unicodeslot=0x10A48, + }, [0x10A50]={ category="po", description="KHAROSHTHI PUNCTUATION DOT", @@ -154318,6 +155472,396 @@ characters.data={ linebreak="al", unicodeslot=0x10CFF, }, + [0x10D00]={ + arabic="l", + category="lo", + description="HANIFI ROHINGYA LETTER A", + direction="al", + linebreak="al", + unicodeslot=0x10D00, + }, + [0x10D01]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER BA", + direction="al", + linebreak="al", + unicodeslot=0x10D01, + }, + [0x10D02]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER PA", + direction="al", + linebreak="al", + unicodeslot=0x10D02, + }, + [0x10D03]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER TA", + direction="al", + linebreak="al", + unicodeslot=0x10D03, + }, + [0x10D04]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER TTA", + direction="al", + linebreak="al", + unicodeslot=0x10D04, + }, + [0x10D05]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER JA", + direction="al", + linebreak="al", + unicodeslot=0x10D05, + }, + [0x10D06]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER CA", + direction="al", + linebreak="al", + unicodeslot=0x10D06, + }, + [0x10D07]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER HA", + direction="al", + linebreak="al", + unicodeslot=0x10D07, + }, + [0x10D08]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER KHA", + direction="al", + linebreak="al", + unicodeslot=0x10D08, + }, + [0x10D09]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER FA", + direction="al", + linebreak="al", + unicodeslot=0x10D09, + }, + [0x10D0A]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER DA", + direction="al", + linebreak="al", + unicodeslot=0x10D0A, + }, + [0x10D0B]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER DDA", + direction="al", + linebreak="al", + unicodeslot=0x10D0B, + }, + [0x10D0C]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER RA", + direction="al", + linebreak="al", + unicodeslot=0x10D0C, + }, + [0x10D0D]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER RRA", + direction="al", + linebreak="al", + unicodeslot=0x10D0D, + }, + [0x10D0E]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER ZA", + direction="al", + linebreak="al", + unicodeslot=0x10D0E, + }, + [0x10D0F]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER SA", + direction="al", + linebreak="al", + unicodeslot=0x10D0F, + }, + [0x10D10]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER SHA", + direction="al", + linebreak="al", + unicodeslot=0x10D10, + }, + [0x10D11]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER KA", + direction="al", + linebreak="al", + unicodeslot=0x10D11, + }, + [0x10D12]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER GA", + direction="al", + linebreak="al", + unicodeslot=0x10D12, + }, + [0x10D13]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER LA", + direction="al", + linebreak="al", + unicodeslot=0x10D13, + }, + [0x10D14]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER MA", + direction="al", + linebreak="al", + unicodeslot=0x10D14, + }, + [0x10D15]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER NA", + direction="al", + linebreak="al", + unicodeslot=0x10D15, + }, + [0x10D16]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER WA", + direction="al", + linebreak="al", + unicodeslot=0x10D16, + }, + [0x10D17]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER KINNA WA", + direction="al", + linebreak="al", + unicodeslot=0x10D17, + }, + [0x10D18]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER YA", + direction="al", + linebreak="al", + unicodeslot=0x10D18, + }, + [0x10D19]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER KINNA YA", + direction="al", + linebreak="al", + unicodeslot=0x10D19, + }, + [0x10D1A]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER NGA", + direction="al", + linebreak="al", + unicodeslot=0x10D1A, + }, + [0x10D1B]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER NYA", + direction="al", + linebreak="al", + unicodeslot=0x10D1B, + }, + [0x10D1C]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA LETTER VA", + direction="al", + linebreak="al", + unicodeslot=0x10D1C, + }, + [0x10D1D]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA VOWEL A", + direction="al", + linebreak="al", + unicodeslot=0x10D1D, + }, + [0x10D1E]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA VOWEL I", + direction="al", + linebreak="al", + unicodeslot=0x10D1E, + }, + [0x10D1F]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA VOWEL U", + direction="al", + linebreak="al", + unicodeslot=0x10D1F, + }, + [0x10D20]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA VOWEL E", + direction="al", + linebreak="al", + unicodeslot=0x10D20, + }, + [0x10D21]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA VOWEL O", + direction="al", + linebreak="al", + unicodeslot=0x10D21, + }, + [0x10D22]={ + arabic="r", + category="lo", + description="HANIFI ROHINGYA MARK SAKIN", + direction="al", + linebreak="al", + unicodeslot=0x10D22, + }, + [0x10D23]={ + arabic="d", + category="lo", + description="HANIFI ROHINGYA MARK NA KHONNA", + direction="al", + linebreak="al", + unicodeslot=0x10D23, + }, + [0x10D24]={ + category="mn", + combining=0xE6, + description="HANIFI ROHINGYA SIGN HARBAHAY", + direction="nsm", + linebreak="cm", + unicodeslot=0x10D24, + }, + [0x10D25]={ + category="mn", + combining=0xE6, + description="HANIFI ROHINGYA SIGN TAHALA", + direction="nsm", + linebreak="cm", + unicodeslot=0x10D25, + }, + [0x10D26]={ + category="mn", + combining=0xE6, + description="HANIFI ROHINGYA SIGN TANA", + direction="nsm", + linebreak="cm", + unicodeslot=0x10D26, + }, + [0x10D27]={ + category="mn", + combining=0xE6, + description="HANIFI ROHINGYA SIGN TASSI", + direction="nsm", + linebreak="cm", + unicodeslot=0x10D27, + }, + [0x10D30]={ + category="nd", + description="HANIFI ROHINGYA DIGIT ZERO", + direction="an", + linebreak="nu", + unicodeslot=0x10D30, + }, + [0x10D31]={ + category="nd", + description="HANIFI ROHINGYA DIGIT ONE", + direction="an", + linebreak="nu", + unicodeslot=0x10D31, + }, + [0x10D32]={ + category="nd", + description="HANIFI ROHINGYA DIGIT TWO", + direction="an", + linebreak="nu", + unicodeslot=0x10D32, + }, + [0x10D33]={ + category="nd", + description="HANIFI ROHINGYA DIGIT THREE", + direction="an", + linebreak="nu", + unicodeslot=0x10D33, + }, + [0x10D34]={ + category="nd", + description="HANIFI ROHINGYA DIGIT FOUR", + direction="an", + linebreak="nu", + unicodeslot=0x10D34, + }, + [0x10D35]={ + category="nd", + description="HANIFI ROHINGYA DIGIT FIVE", + direction="an", + linebreak="nu", + unicodeslot=0x10D35, + }, + [0x10D36]={ + category="nd", + description="HANIFI ROHINGYA DIGIT SIX", + direction="an", + linebreak="nu", + unicodeslot=0x10D36, + }, + [0x10D37]={ + category="nd", + description="HANIFI ROHINGYA DIGIT SEVEN", + direction="an", + linebreak="nu", + unicodeslot=0x10D37, + }, + [0x10D38]={ + category="nd", + description="HANIFI ROHINGYA DIGIT EIGHT", + direction="an", + linebreak="nu", + unicodeslot=0x10D38, + }, + [0x10D39]={ + category="nd", + description="HANIFI ROHINGYA DIGIT NINE", + direction="an", + linebreak="nu", + unicodeslot=0x10D39, + }, [0x10E60]={ category="no", description="RUMI DIGIT ONE", @@ -154535,6 +156079,617 @@ characters.data={ linebreak="al", unicodeslot=0x10E7E, }, + [0x10F00]={ + category="lo", + description="OLD SOGDIAN LETTER ALEPH", + direction="r", + linebreak="al", + unicodeslot=0x10F00, + }, + [0x10F01]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL ALEPH", + direction="r", + linebreak="al", + unicodeslot=0x10F01, + }, + [0x10F02]={ + category="lo", + description="OLD SOGDIAN LETTER BETH", + direction="r", + linebreak="al", + unicodeslot=0x10F02, + }, + [0x10F03]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL BETH", + direction="r", + linebreak="al", + unicodeslot=0x10F03, + }, + [0x10F04]={ + category="lo", + description="OLD SOGDIAN LETTER GIMEL", + direction="r", + linebreak="al", + unicodeslot=0x10F04, + }, + [0x10F05]={ + category="lo", + description="OLD SOGDIAN LETTER HE", + direction="r", + linebreak="al", + unicodeslot=0x10F05, + }, + [0x10F06]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL HE", + direction="r", + linebreak="al", + unicodeslot=0x10F06, + }, + [0x10F07]={ + category="lo", + description="OLD SOGDIAN LETTER WAW", + direction="r", + linebreak="al", + unicodeslot=0x10F07, + }, + [0x10F08]={ + category="lo", + description="OLD SOGDIAN LETTER ZAYIN", + direction="r", + linebreak="al", + unicodeslot=0x10F08, + }, + [0x10F09]={ + category="lo", + description="OLD SOGDIAN LETTER HETH", + direction="r", + linebreak="al", + unicodeslot=0x10F09, + }, + [0x10F0A]={ + category="lo", + description="OLD SOGDIAN LETTER YODH", + direction="r", + linebreak="al", + unicodeslot=0x10F0A, + }, + [0x10F0B]={ + category="lo", + description="OLD SOGDIAN LETTER KAPH", + direction="r", + linebreak="al", + unicodeslot=0x10F0B, + }, + [0x10F0C]={ + category="lo", + description="OLD SOGDIAN LETTER LAMEDH", + direction="r", + linebreak="al", + unicodeslot=0x10F0C, + }, + [0x10F0D]={ + category="lo", + description="OLD SOGDIAN LETTER MEM", + direction="r", + linebreak="al", + unicodeslot=0x10F0D, + }, + [0x10F0E]={ + category="lo", + description="OLD SOGDIAN LETTER NUN", + direction="r", + linebreak="al", + unicodeslot=0x10F0E, + }, + [0x10F0F]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL NUN", + direction="r", + linebreak="al", + unicodeslot=0x10F0F, + }, + [0x10F10]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL NUN WITH VERTICAL TAIL", + direction="r", + linebreak="al", + unicodeslot=0x10F10, + }, + [0x10F11]={ + category="lo", + description="OLD SOGDIAN LETTER SAMEKH", + direction="r", + linebreak="al", + unicodeslot=0x10F11, + }, + [0x10F12]={ + category="lo", + description="OLD SOGDIAN LETTER AYIN", + direction="r", + linebreak="al", + unicodeslot=0x10F12, + }, + [0x10F13]={ + category="lo", + description="OLD SOGDIAN LETTER ALTERNATE AYIN", + direction="r", + linebreak="al", + unicodeslot=0x10F13, + }, + [0x10F14]={ + category="lo", + description="OLD SOGDIAN LETTER PE", + direction="r", + linebreak="al", + unicodeslot=0x10F14, + }, + [0x10F15]={ + category="lo", + description="OLD SOGDIAN LETTER SADHE", + direction="r", + linebreak="al", + unicodeslot=0x10F15, + }, + [0x10F16]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL SADHE", + direction="r", + linebreak="al", + unicodeslot=0x10F16, + }, + [0x10F17]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL SADHE WITH VERTICAL TAIL", + direction="r", + linebreak="al", + unicodeslot=0x10F17, + }, + [0x10F18]={ + category="lo", + description="OLD SOGDIAN LETTER RESH-AYIN-DALETH", + direction="r", + linebreak="al", + unicodeslot=0x10F18, + }, + [0x10F19]={ + category="lo", + description="OLD SOGDIAN LETTER SHIN", + direction="r", + linebreak="al", + unicodeslot=0x10F19, + }, + [0x10F1A]={ + category="lo", + description="OLD SOGDIAN LETTER TAW", + direction="r", + linebreak="al", + unicodeslot=0x10F1A, + }, + [0x10F1B]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL TAW", + direction="r", + linebreak="al", + unicodeslot=0x10F1B, + }, + [0x10F1C]={ + category="lo", + description="OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL", + direction="r", + linebreak="al", + unicodeslot=0x10F1C, + }, + [0x10F1D]={ + category="no", + description="OLD SOGDIAN NUMBER ONE", + direction="r", + linebreak="al", + unicodeslot=0x10F1D, + }, + [0x10F1E]={ + category="no", + description="OLD SOGDIAN NUMBER TWO", + direction="r", + linebreak="al", + unicodeslot=0x10F1E, + }, + [0x10F1F]={ + category="no", + description="OLD SOGDIAN NUMBER THREE", + direction="r", + linebreak="al", + unicodeslot=0x10F1F, + }, + [0x10F20]={ + category="no", + description="OLD SOGDIAN NUMBER FOUR", + direction="r", + linebreak="al", + unicodeslot=0x10F20, + }, + [0x10F21]={ + category="no", + description="OLD SOGDIAN NUMBER FIVE", + direction="r", + linebreak="al", + unicodeslot=0x10F21, + }, + [0x10F22]={ + category="no", + description="OLD SOGDIAN NUMBER TEN", + direction="r", + linebreak="al", + unicodeslot=0x10F22, + }, + [0x10F23]={ + category="no", + description="OLD SOGDIAN NUMBER TWENTY", + direction="r", + linebreak="al", + unicodeslot=0x10F23, + }, + [0x10F24]={ + category="no", + description="OLD SOGDIAN NUMBER THIRTY", + direction="r", + linebreak="al", + unicodeslot=0x10F24, + }, + [0x10F25]={ + category="no", + description="OLD SOGDIAN NUMBER ONE HUNDRED", + direction="r", + linebreak="al", + unicodeslot=0x10F25, + }, + [0x10F26]={ + category="no", + description="OLD SOGDIAN FRACTION ONE HALF", + direction="r", + linebreak="al", + unicodeslot=0x10F26, + }, + [0x10F27]={ + category="lo", + description="OLD SOGDIAN LIGATURE AYIN-DALETH", + direction="r", + linebreak="al", + unicodeslot=0x10F27, + }, + [0x10F30]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER ALEPH", + direction="al", + linebreak="al", + unicodeslot=0x10F30, + }, + [0x10F31]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER BETH", + direction="al", + linebreak="al", + unicodeslot=0x10F31, + }, + [0x10F32]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER GIMEL", + direction="al", + linebreak="al", + unicodeslot=0x10F32, + }, + [0x10F33]={ + arabic="r", + category="lo", + description="SOGDIAN LETTER HE", + direction="al", + linebreak="al", + unicodeslot=0x10F33, + }, + [0x10F34]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER WAW", + direction="al", + linebreak="al", + unicodeslot=0x10F34, + }, + [0x10F35]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER ZAYIN", + direction="al", + linebreak="al", + unicodeslot=0x10F35, + }, + [0x10F36]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER HETH", + direction="al", + linebreak="al", + unicodeslot=0x10F36, + }, + [0x10F37]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER YODH", + direction="al", + linebreak="al", + unicodeslot=0x10F37, + }, + [0x10F38]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER KAPH", + direction="al", + linebreak="al", + unicodeslot=0x10F38, + }, + [0x10F39]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER LAMEDH", + direction="al", + linebreak="al", + unicodeslot=0x10F39, + }, + [0x10F3A]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER MEM", + direction="al", + linebreak="al", + unicodeslot=0x10F3A, + }, + [0x10F3B]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER NUN", + direction="al", + linebreak="al", + unicodeslot=0x10F3B, + }, + [0x10F3C]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER SAMEKH", + direction="al", + linebreak="al", + unicodeslot=0x10F3C, + }, + [0x10F3D]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER AYIN", + direction="al", + linebreak="al", + unicodeslot=0x10F3D, + }, + [0x10F3E]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER PE", + direction="al", + linebreak="al", + unicodeslot=0x10F3E, + }, + [0x10F3F]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER SADHE", + direction="al", + linebreak="al", + unicodeslot=0x10F3F, + }, + [0x10F40]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER RESH-AYIN", + direction="al", + linebreak="al", + unicodeslot=0x10F40, + }, + [0x10F41]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER SHIN", + direction="al", + linebreak="al", + unicodeslot=0x10F41, + }, + [0x10F42]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER TAW", + direction="al", + linebreak="al", + unicodeslot=0x10F42, + }, + [0x10F43]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER FETH", + direction="al", + linebreak="al", + unicodeslot=0x10F43, + }, + [0x10F44]={ + arabic="d", + category="lo", + description="SOGDIAN LETTER LESH", + direction="al", + linebreak="al", + unicodeslot=0x10F44, + }, + [0x10F45]={ + arabic="u", + category="lo", + description="SOGDIAN INDEPENDENT SHIN", + direction="al", + linebreak="al", + unicodeslot=0x10F45, + }, + [0x10F46]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING DOT BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F46, + }, + [0x10F47]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING TWO DOTS BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F47, + }, + [0x10F48]={ + category="mn", + combining=0xE6, + description="SOGDIAN COMBINING DOT ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F48, + }, + [0x10F49]={ + category="mn", + combining=0xE6, + description="SOGDIAN COMBINING TWO DOTS ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F49, + }, + [0x10F4A]={ + category="mn", + combining=0xE6, + description="SOGDIAN COMBINING CURVE ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F4A, + }, + [0x10F4B]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING CURVE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F4B, + }, + [0x10F4C]={ + category="mn", + combining=0xE6, + description="SOGDIAN COMBINING HOOK ABOVE", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F4C, + }, + [0x10F4D]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING HOOK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F4D, + }, + [0x10F4E]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING LONG HOOK BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F4E, + }, + [0x10F4F]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING RESH BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F4F, + }, + [0x10F50]={ + category="mn", + combining=0xDC, + description="SOGDIAN COMBINING STROKE BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x10F50, + }, + [0x10F51]={ + arabic="d", + category="no", + description="SOGDIAN NUMBER ONE", + direction="al", + linebreak="al", + unicodeslot=0x10F51, + }, + [0x10F52]={ + arabic="d", + category="no", + description="SOGDIAN NUMBER TEN", + direction="al", + linebreak="al", + unicodeslot=0x10F52, + }, + [0x10F53]={ + arabic="d", + category="no", + description="SOGDIAN NUMBER TWENTY", + direction="al", + linebreak="al", + unicodeslot=0x10F53, + }, + [0x10F54]={ + arabic="r", + category="no", + description="SOGDIAN NUMBER ONE HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x10F54, + }, + [0x10F55]={ + category="po", + description="SOGDIAN PUNCTUATION TWO VERTICAL BARS", + direction="al", + linebreak="al", + unicodeslot=0x10F55, + }, + [0x10F56]={ + category="po", + description="SOGDIAN PUNCTUATION TWO VERTICAL BARS WITH DOTS", + direction="al", + linebreak="al", + unicodeslot=0x10F56, + }, + [0x10F57]={ + category="po", + description="SOGDIAN PUNCTUATION CIRCLE WITH DOT", + direction="al", + linebreak="al", + unicodeslot=0x10F57, + }, + [0x10F58]={ + category="po", + description="SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS", + direction="al", + linebreak="al", + unicodeslot=0x10F58, + }, + [0x10F59]={ + category="po", + description="SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT", + direction="al", + linebreak="al", + unicodeslot=0x10F59, + }, [0x11000]={ category="mc", description="BRAHMI SIGN CANDRABINDU", @@ -155733,6 +157888,7 @@ characters.data={ unicodeslot=0x110BC, }, [0x110BD]={ + arabic="u", category="cf", description="KAITHI NUMBER SIGN", direction="l", @@ -155767,6 +157923,14 @@ characters.data={ linebreak="ba", unicodeslot=0x110C1, }, + [0x110CD]={ + arabic="u", + category="cf", + description="KAITHI NUMBER SIGN ABOVE", + direction="l", + linebreak="al", + unicodeslot=0x110CD, + }, [0x110D0]={ category="lo", description="SORA SOMPENG LETTER SAH", @@ -156488,6 +158652,27 @@ characters.data={ linebreak="ba", unicodeslot=0x11143, }, + [0x11144]={ + category="lo", + description="CHAKMA LETTER LHAA", + direction="l", + linebreak="al", + unicodeslot=0x11144, + }, + [0x11145]={ + category="mc", + description="CHAKMA VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x11145, + }, + [0x11146]={ + category="mc", + description="CHAKMA VOWEL SIGN EI", + direction="l", + linebreak="cm", + unicodeslot=0x11146, + }, [0x11150]={ category="lo", description="MAHAJANI LETTER A", @@ -157277,8 +159462,8 @@ characters.data={ [0x111C9]={ category="po", description="SHARADA SANDHI MARK", - direction="l", - linebreak="al", + direction="nsm", + linebreak="cm", unicodeslot=0x111C9, }, [0x111CA]={ @@ -159099,6 +161284,14 @@ characters.data={ linebreak="al", unicodeslot=0x11339, }, + [0x1133B]={ + category="mn", + combining=0x7, + description="COMBINING BINDU BELOW", + direction="nsm", + linebreak="cm", + unicodeslot=0x1133B, + }, [0x1133C]={ category="mn", combining=0x7, @@ -160006,6 +162199,14 @@ characters.data={ linebreak="al", unicodeslot=0x1145D, }, + [0x1145E]={ + category="mn", + combining=0xE6, + description="NEWA SANDHI MARK", + direction="nsm", + linebreak="cm", + unicodeslot=0x1145E, + }, [0x11480]={ category="lo", description="TIRHUTA ANJI", @@ -162524,6 +164725,13 @@ characters.data={ linebreak="sa", unicodeslot=0x11719, }, + [0x1171A]={ + category="lo", + description="AHOM LETTER ALTERNATE BA", + direction="l", + linebreak="sa", + unicodeslot=0x1171A, + }, [0x1171D]={ category="mn", description="AHOM CONSONANT SIGN MEDIAL LA", @@ -162742,6 +164950,428 @@ characters.data={ linebreak="sa", unicodeslot=0x1173F, }, + [0x11800]={ + category="lo", + description="DOGRA LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x11800, + }, + [0x11801]={ + category="lo", + description="DOGRA LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x11801, + }, + [0x11802]={ + category="lo", + description="DOGRA LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x11802, + }, + [0x11803]={ + category="lo", + description="DOGRA LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x11803, + }, + [0x11804]={ + category="lo", + description="DOGRA LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x11804, + }, + [0x11805]={ + category="lo", + description="DOGRA LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x11805, + }, + [0x11806]={ + category="lo", + description="DOGRA LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x11806, + }, + [0x11807]={ + category="lo", + description="DOGRA LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x11807, + }, + [0x11808]={ + category="lo", + description="DOGRA LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x11808, + }, + [0x11809]={ + category="lo", + description="DOGRA LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x11809, + }, + [0x1180A]={ + category="lo", + description="DOGRA LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x1180A, + }, + [0x1180B]={ + category="lo", + description="DOGRA LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x1180B, + }, + [0x1180C]={ + category="lo", + description="DOGRA LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x1180C, + }, + [0x1180D]={ + category="lo", + description="DOGRA LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x1180D, + }, + [0x1180E]={ + category="lo", + description="DOGRA LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x1180E, + }, + [0x1180F]={ + category="lo", + description="DOGRA LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x1180F, + }, + [0x11810]={ + category="lo", + description="DOGRA LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x11810, + }, + [0x11811]={ + category="lo", + description="DOGRA LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x11811, + }, + [0x11812]={ + category="lo", + description="DOGRA LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x11812, + }, + [0x11813]={ + category="lo", + description="DOGRA LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x11813, + }, + [0x11814]={ + category="lo", + description="DOGRA LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x11814, + }, + [0x11815]={ + category="lo", + description="DOGRA LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x11815, + }, + [0x11816]={ + category="lo", + description="DOGRA LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x11816, + }, + [0x11817]={ + category="lo", + description="DOGRA LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x11817, + }, + [0x11818]={ + category="lo", + description="DOGRA LETTER NNA", + direction="l", + linebreak="al", + unicodeslot=0x11818, + }, + [0x11819]={ + category="lo", + description="DOGRA LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x11819, + }, + [0x1181A]={ + category="lo", + description="DOGRA LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x1181A, + }, + [0x1181B]={ + category="lo", + description="DOGRA LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x1181B, + }, + [0x1181C]={ + category="lo", + description="DOGRA LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x1181C, + }, + [0x1181D]={ + category="lo", + description="DOGRA LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x1181D, + }, + [0x1181E]={ + category="lo", + description="DOGRA LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x1181E, + }, + [0x1181F]={ + category="lo", + description="DOGRA LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x1181F, + }, + [0x11820]={ + category="lo", + description="DOGRA LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x11820, + }, + [0x11821]={ + category="lo", + description="DOGRA LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x11821, + }, + [0x11822]={ + category="lo", + description="DOGRA LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x11822, + }, + [0x11823]={ + category="lo", + description="DOGRA LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x11823, + }, + [0x11824]={ + category="lo", + description="DOGRA LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x11824, + }, + [0x11825]={ + category="lo", + description="DOGRA LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x11825, + }, + [0x11826]={ + category="lo", + description="DOGRA LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x11826, + }, + [0x11827]={ + category="lo", + description="DOGRA LETTER SHA", + direction="l", + linebreak="al", + unicodeslot=0x11827, + }, + [0x11828]={ + category="lo", + description="DOGRA LETTER SSA", + direction="l", + linebreak="al", + unicodeslot=0x11828, + }, + [0x11829]={ + category="lo", + description="DOGRA LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x11829, + }, + [0x1182A]={ + category="lo", + description="DOGRA LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x1182A, + }, + [0x1182B]={ + category="lo", + description="DOGRA LETTER RRA", + direction="l", + linebreak="al", + unicodeslot=0x1182B, + }, + [0x1182C]={ + category="mc", + description="DOGRA VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x1182C, + }, + [0x1182D]={ + category="mc", + description="DOGRA VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x1182D, + }, + [0x1182E]={ + category="mc", + description="DOGRA VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x1182E, + }, + [0x1182F]={ + category="mn", + description="DOGRA VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x1182F, + }, + [0x11830]={ + category="mn", + description="DOGRA VOWEL SIGN UU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11830, + }, + [0x11831]={ + category="mn", + description="DOGRA VOWEL SIGN VOCALIC R", + direction="nsm", + linebreak="cm", + unicodeslot=0x11831, + }, + [0x11832]={ + category="mn", + description="DOGRA VOWEL SIGN VOCALIC RR", + direction="nsm", + linebreak="cm", + unicodeslot=0x11832, + }, + [0x11833]={ + category="mn", + description="DOGRA VOWEL SIGN E", + direction="nsm", + linebreak="cm", + unicodeslot=0x11833, + }, + [0x11834]={ + category="mn", + description="DOGRA VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x11834, + }, + [0x11835]={ + category="mn", + description="DOGRA VOWEL SIGN O", + direction="nsm", + linebreak="cm", + unicodeslot=0x11835, + }, + [0x11836]={ + category="mn", + description="DOGRA VOWEL SIGN AU", + direction="nsm", + linebreak="cm", + unicodeslot=0x11836, + }, + [0x11837]={ + category="mn", + description="DOGRA SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11837, + }, + [0x11838]={ + category="mc", + description="DOGRA SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x11838, + }, + [0x11839]={ + category="mn", + combining=0x9, + description="DOGRA SIGN VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11839, + }, + [0x1183A]={ + category="mn", + combining=0x7, + description="DOGRA SIGN NUKTA", + direction="nsm", + linebreak="cm", + unicodeslot=0x1183A, + }, + [0x1183B]={ + category="po", + description="DOGRA ABBREVIATION SIGN", + direction="l", + linebreak="al", + unicodeslot=0x1183B, + }, [0x118A0]={ category="lu", description="WARANG CITI CAPITAL LETTER NGAA", @@ -164362,6 +166992,13 @@ characters.data={ linebreak="ba", unicodeslot=0x11A9C, }, + [0x11A9D]={ + category="lo", + description="SOYOMBO MARK PLUTA", + direction="l", + linebreak="al", + unicodeslot=0x11A9D, + }, [0x11A9E]={ category="po", description="SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME", @@ -166480,6 +169117,623 @@ characters.data={ linebreak="nu", unicodeslot=0x11D59, }, + [0x11D60]={ + category="lo", + description="GUNJALA GONDI LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x11D60, + }, + [0x11D61]={ + category="lo", + description="GUNJALA GONDI LETTER AA", + direction="l", + linebreak="al", + unicodeslot=0x11D61, + }, + [0x11D62]={ + category="lo", + description="GUNJALA GONDI LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x11D62, + }, + [0x11D63]={ + category="lo", + description="GUNJALA GONDI LETTER II", + direction="l", + linebreak="al", + unicodeslot=0x11D63, + }, + [0x11D64]={ + category="lo", + description="GUNJALA GONDI LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x11D64, + }, + [0x11D65]={ + category="lo", + description="GUNJALA GONDI LETTER UU", + direction="l", + linebreak="al", + unicodeslot=0x11D65, + }, + [0x11D67]={ + category="lo", + description="GUNJALA GONDI LETTER EE", + direction="l", + linebreak="al", + unicodeslot=0x11D67, + }, + [0x11D68]={ + category="lo", + description="GUNJALA GONDI LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x11D68, + }, + [0x11D6A]={ + category="lo", + description="GUNJALA GONDI LETTER OO", + direction="l", + linebreak="al", + unicodeslot=0x11D6A, + }, + [0x11D6B]={ + category="lo", + description="GUNJALA GONDI LETTER AU", + direction="l", + linebreak="al", + unicodeslot=0x11D6B, + }, + [0x11D6C]={ + category="lo", + description="GUNJALA GONDI LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x11D6C, + }, + [0x11D6D]={ + category="lo", + description="GUNJALA GONDI LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x11D6D, + }, + [0x11D6E]={ + category="lo", + description="GUNJALA GONDI LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x11D6E, + }, + [0x11D6F]={ + category="lo", + description="GUNJALA GONDI LETTER BHA", + direction="l", + linebreak="al", + unicodeslot=0x11D6F, + }, + [0x11D70]={ + category="lo", + description="GUNJALA GONDI LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x11D70, + }, + [0x11D71]={ + category="lo", + description="GUNJALA GONDI LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x11D71, + }, + [0x11D72]={ + category="lo", + description="GUNJALA GONDI LETTER KHA", + direction="l", + linebreak="al", + unicodeslot=0x11D72, + }, + [0x11D73]={ + category="lo", + description="GUNJALA GONDI LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x11D73, + }, + [0x11D74]={ + category="lo", + description="GUNJALA GONDI LETTER THA", + direction="l", + linebreak="al", + unicodeslot=0x11D74, + }, + [0x11D75]={ + category="lo", + description="GUNJALA GONDI LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x11D75, + }, + [0x11D76]={ + category="lo", + description="GUNJALA GONDI LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x11D76, + }, + [0x11D77]={ + category="lo", + description="GUNJALA GONDI LETTER GHA", + direction="l", + linebreak="al", + unicodeslot=0x11D77, + }, + [0x11D78]={ + category="lo", + description="GUNJALA GONDI LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x11D78, + }, + [0x11D79]={ + category="lo", + description="GUNJALA GONDI LETTER DHA", + direction="l", + linebreak="al", + unicodeslot=0x11D79, + }, + [0x11D7A]={ + category="lo", + description="GUNJALA GONDI LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x11D7A, + }, + [0x11D7B]={ + category="lo", + description="GUNJALA GONDI LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x11D7B, + }, + [0x11D7C]={ + category="lo", + description="GUNJALA GONDI LETTER CHA", + direction="l", + linebreak="al", + unicodeslot=0x11D7C, + }, + [0x11D7D]={ + category="lo", + description="GUNJALA GONDI LETTER TTA", + direction="l", + linebreak="al", + unicodeslot=0x11D7D, + }, + [0x11D7E]={ + category="lo", + description="GUNJALA GONDI LETTER TTHA", + direction="l", + linebreak="al", + unicodeslot=0x11D7E, + }, + [0x11D7F]={ + category="lo", + description="GUNJALA GONDI LETTER LLA", + direction="l", + linebreak="al", + unicodeslot=0x11D7F, + }, + [0x11D80]={ + category="lo", + description="GUNJALA GONDI LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x11D80, + }, + [0x11D81]={ + category="lo", + description="GUNJALA GONDI LETTER JHA", + direction="l", + linebreak="al", + unicodeslot=0x11D81, + }, + [0x11D82]={ + category="lo", + description="GUNJALA GONDI LETTER DDA", + direction="l", + linebreak="al", + unicodeslot=0x11D82, + }, + [0x11D83]={ + category="lo", + description="GUNJALA GONDI LETTER DDHA", + direction="l", + linebreak="al", + unicodeslot=0x11D83, + }, + [0x11D84]={ + category="lo", + description="GUNJALA GONDI LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x11D84, + }, + [0x11D85]={ + category="lo", + description="GUNJALA GONDI LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x11D85, + }, + [0x11D86]={ + category="lo", + description="GUNJALA GONDI LETTER PHA", + direction="l", + linebreak="al", + unicodeslot=0x11D86, + }, + [0x11D87]={ + category="lo", + description="GUNJALA GONDI LETTER HA", + direction="l", + linebreak="al", + unicodeslot=0x11D87, + }, + [0x11D88]={ + category="lo", + description="GUNJALA GONDI LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x11D88, + }, + [0x11D89]={ + category="lo", + description="GUNJALA GONDI LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x11D89, + }, + [0x11D8A]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN AA", + direction="l", + linebreak="cm", + unicodeslot=0x11D8A, + }, + [0x11D8B]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN I", + direction="l", + linebreak="cm", + unicodeslot=0x11D8B, + }, + [0x11D8C]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN II", + direction="l", + linebreak="cm", + unicodeslot=0x11D8C, + }, + [0x11D8D]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN U", + direction="l", + linebreak="cm", + unicodeslot=0x11D8D, + }, + [0x11D8E]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN UU", + direction="l", + linebreak="cm", + unicodeslot=0x11D8E, + }, + [0x11D90]={ + category="mn", + description="GUNJALA GONDI VOWEL SIGN EE", + direction="nsm", + linebreak="cm", + unicodeslot=0x11D90, + }, + [0x11D91]={ + category="mn", + description="GUNJALA GONDI VOWEL SIGN AI", + direction="nsm", + linebreak="cm", + unicodeslot=0x11D91, + }, + [0x11D93]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN OO", + direction="l", + linebreak="cm", + unicodeslot=0x11D93, + }, + [0x11D94]={ + category="mc", + description="GUNJALA GONDI VOWEL SIGN AU", + direction="l", + linebreak="cm", + unicodeslot=0x11D94, + }, + [0x11D95]={ + category="mn", + description="GUNJALA GONDI SIGN ANUSVARA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11D95, + }, + [0x11D96]={ + category="mc", + description="GUNJALA GONDI SIGN VISARGA", + direction="l", + linebreak="cm", + unicodeslot=0x11D96, + }, + [0x11D97]={ + category="mn", + combining=0x9, + description="GUNJALA GONDI VIRAMA", + direction="nsm", + linebreak="cm", + unicodeslot=0x11D97, + }, + [0x11D98]={ + category="lo", + description="GUNJALA GONDI OM", + direction="l", + linebreak="al", + unicodeslot=0x11D98, + }, + [0x11DA0]={ + category="nd", + description="GUNJALA GONDI DIGIT ZERO", + direction="l", + linebreak="nu", + unicodeslot=0x11DA0, + }, + [0x11DA1]={ + category="nd", + description="GUNJALA GONDI DIGIT ONE", + direction="l", + linebreak="nu", + unicodeslot=0x11DA1, + }, + [0x11DA2]={ + category="nd", + description="GUNJALA GONDI DIGIT TWO", + direction="l", + linebreak="nu", + unicodeslot=0x11DA2, + }, + [0x11DA3]={ + category="nd", + description="GUNJALA GONDI DIGIT THREE", + direction="l", + linebreak="nu", + unicodeslot=0x11DA3, + }, + [0x11DA4]={ + category="nd", + description="GUNJALA GONDI DIGIT FOUR", + direction="l", + linebreak="nu", + unicodeslot=0x11DA4, + }, + [0x11DA5]={ + category="nd", + description="GUNJALA GONDI DIGIT FIVE", + direction="l", + linebreak="nu", + unicodeslot=0x11DA5, + }, + [0x11DA6]={ + category="nd", + description="GUNJALA GONDI DIGIT SIX", + direction="l", + linebreak="nu", + unicodeslot=0x11DA6, + }, + [0x11DA7]={ + category="nd", + description="GUNJALA GONDI DIGIT SEVEN", + direction="l", + linebreak="nu", + unicodeslot=0x11DA7, + }, + [0x11DA8]={ + category="nd", + description="GUNJALA GONDI DIGIT EIGHT", + direction="l", + linebreak="nu", + unicodeslot=0x11DA8, + }, + [0x11DA9]={ + category="nd", + description="GUNJALA GONDI DIGIT NINE", + direction="l", + linebreak="nu", + unicodeslot=0x11DA9, + }, + [0x11EE0]={ + category="lo", + description="MAKASAR LETTER KA", + direction="l", + linebreak="al", + unicodeslot=0x11EE0, + }, + [0x11EE1]={ + category="lo", + description="MAKASAR LETTER GA", + direction="l", + linebreak="al", + unicodeslot=0x11EE1, + }, + [0x11EE2]={ + category="lo", + description="MAKASAR LETTER NGA", + direction="l", + linebreak="al", + unicodeslot=0x11EE2, + }, + [0x11EE3]={ + category="lo", + description="MAKASAR LETTER PA", + direction="l", + linebreak="al", + unicodeslot=0x11EE3, + }, + [0x11EE4]={ + category="lo", + description="MAKASAR LETTER BA", + direction="l", + linebreak="al", + unicodeslot=0x11EE4, + }, + [0x11EE5]={ + category="lo", + description="MAKASAR LETTER MA", + direction="l", + linebreak="al", + unicodeslot=0x11EE5, + }, + [0x11EE6]={ + category="lo", + description="MAKASAR LETTER TA", + direction="l", + linebreak="al", + unicodeslot=0x11EE6, + }, + [0x11EE7]={ + category="lo", + description="MAKASAR LETTER DA", + direction="l", + linebreak="al", + unicodeslot=0x11EE7, + }, + [0x11EE8]={ + category="lo", + description="MAKASAR LETTER NA", + direction="l", + linebreak="al", + unicodeslot=0x11EE8, + }, + [0x11EE9]={ + category="lo", + description="MAKASAR LETTER CA", + direction="l", + linebreak="al", + unicodeslot=0x11EE9, + }, + [0x11EEA]={ + category="lo", + description="MAKASAR LETTER JA", + direction="l", + linebreak="al", + unicodeslot=0x11EEA, + }, + [0x11EEB]={ + category="lo", + description="MAKASAR LETTER NYA", + direction="l", + linebreak="al", + unicodeslot=0x11EEB, + }, + [0x11EEC]={ + category="lo", + description="MAKASAR LETTER YA", + direction="l", + linebreak="al", + unicodeslot=0x11EEC, + }, + [0x11EED]={ + category="lo", + description="MAKASAR LETTER RA", + direction="l", + linebreak="al", + unicodeslot=0x11EED, + }, + [0x11EEE]={ + category="lo", + description="MAKASAR LETTER LA", + direction="l", + linebreak="al", + unicodeslot=0x11EEE, + }, + [0x11EEF]={ + category="lo", + description="MAKASAR LETTER VA", + direction="l", + linebreak="al", + unicodeslot=0x11EEF, + }, + [0x11EF0]={ + category="lo", + description="MAKASAR LETTER SA", + direction="l", + linebreak="al", + unicodeslot=0x11EF0, + }, + [0x11EF1]={ + category="lo", + description="MAKASAR LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x11EF1, + }, + [0x11EF2]={ + category="lo", + description="MAKASAR ANGKA", + direction="l", + linebreak="al", + unicodeslot=0x11EF2, + }, + [0x11EF3]={ + category="mn", + description="MAKASAR VOWEL SIGN I", + direction="nsm", + linebreak="cm", + unicodeslot=0x11EF3, + }, + [0x11EF4]={ + category="mn", + description="MAKASAR VOWEL SIGN U", + direction="nsm", + linebreak="cm", + unicodeslot=0x11EF4, + }, + [0x11EF5]={ + category="mc", + description="MAKASAR VOWEL SIGN E", + direction="l", + linebreak="cm", + unicodeslot=0x11EF5, + }, + [0x11EF6]={ + category="mc", + description="MAKASAR VOWEL SIGN O", + direction="l", + linebreak="cm", + unicodeslot=0x11EF6, + }, + [0x11EF7]={ + category="po", + description="MAKASAR PASSIMBANG", + direction="l", + linebreak="al", + unicodeslot=0x11EF7, + }, + [0x11EF8]={ + category="po", + description="MAKASAR END OF SECTION", + direction="l", + linebreak="al", + unicodeslot=0x11EF8, + }, [0x12000]={ category="lo", description="CUNEIFORM SIGN A", @@ -192135,6 +195389,643 @@ characters.data={ linebreak="al", unicodeslot=0x16B8F, }, + [0x16E40]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER M", + direction="l", + linebreak="al", + unicodeslot=0x16E40, + }, + [0x16E41]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER S", + direction="l", + linebreak="al", + unicodeslot=0x16E41, + }, + [0x16E42]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER V", + direction="l", + linebreak="al", + unicodeslot=0x16E42, + }, + [0x16E43]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER W", + direction="l", + linebreak="al", + unicodeslot=0x16E43, + }, + [0x16E44]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER ATIU", + direction="l", + linebreak="al", + unicodeslot=0x16E44, + }, + [0x16E45]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER Z", + direction="l", + linebreak="al", + unicodeslot=0x16E45, + }, + [0x16E46]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER KP", + direction="l", + linebreak="al", + unicodeslot=0x16E46, + }, + [0x16E47]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER P", + direction="l", + linebreak="al", + unicodeslot=0x16E47, + }, + [0x16E48]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER T", + direction="l", + linebreak="al", + unicodeslot=0x16E48, + }, + [0x16E49]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER G", + direction="l", + linebreak="al", + unicodeslot=0x16E49, + }, + [0x16E4A]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER F", + direction="l", + linebreak="al", + unicodeslot=0x16E4A, + }, + [0x16E4B]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x16E4B, + }, + [0x16E4C]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER K", + direction="l", + linebreak="al", + unicodeslot=0x16E4C, + }, + [0x16E4D]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x16E4D, + }, + [0x16E4E]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER J", + direction="l", + linebreak="al", + unicodeslot=0x16E4E, + }, + [0x16E4F]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x16E4F, + }, + [0x16E50]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER B", + direction="l", + linebreak="al", + unicodeslot=0x16E50, + }, + [0x16E51]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER C", + direction="l", + linebreak="al", + unicodeslot=0x16E51, + }, + [0x16E52]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x16E52, + }, + [0x16E53]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER YU", + direction="l", + linebreak="al", + unicodeslot=0x16E53, + }, + [0x16E54]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER L", + direction="l", + linebreak="al", + unicodeslot=0x16E54, + }, + [0x16E55]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER Q", + direction="l", + linebreak="al", + unicodeslot=0x16E55, + }, + [0x16E56]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER HP", + direction="l", + linebreak="al", + unicodeslot=0x16E56, + }, + [0x16E57]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER NY", + direction="l", + linebreak="al", + unicodeslot=0x16E57, + }, + [0x16E58]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER X", + direction="l", + linebreak="al", + unicodeslot=0x16E58, + }, + [0x16E59]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER D", + direction="l", + linebreak="al", + unicodeslot=0x16E59, + }, + [0x16E5A]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER OE", + direction="l", + linebreak="al", + unicodeslot=0x16E5A, + }, + [0x16E5B]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER N", + direction="l", + linebreak="al", + unicodeslot=0x16E5B, + }, + [0x16E5C]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER R", + direction="l", + linebreak="al", + unicodeslot=0x16E5C, + }, + [0x16E5D]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x16E5D, + }, + [0x16E5E]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x16E5E, + }, + [0x16E5F]={ + category="lu", + description="MEDEFAIDRIN CAPITAL LETTER Y", + direction="l", + linebreak="al", + unicodeslot=0x16E5F, + }, + [0x16E60]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER M", + direction="l", + linebreak="al", + unicodeslot=0x16E60, + }, + [0x16E61]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER S", + direction="l", + linebreak="al", + unicodeslot=0x16E61, + }, + [0x16E62]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER V", + direction="l", + linebreak="al", + unicodeslot=0x16E62, + }, + [0x16E63]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER W", + direction="l", + linebreak="al", + unicodeslot=0x16E63, + }, + [0x16E64]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER ATIU", + direction="l", + linebreak="al", + unicodeslot=0x16E64, + }, + [0x16E65]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER Z", + direction="l", + linebreak="al", + unicodeslot=0x16E65, + }, + [0x16E66]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER KP", + direction="l", + linebreak="al", + unicodeslot=0x16E66, + }, + [0x16E67]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER P", + direction="l", + linebreak="al", + unicodeslot=0x16E67, + }, + [0x16E68]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER T", + direction="l", + linebreak="al", + unicodeslot=0x16E68, + }, + [0x16E69]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER G", + direction="l", + linebreak="al", + unicodeslot=0x16E69, + }, + [0x16E6A]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER F", + direction="l", + linebreak="al", + unicodeslot=0x16E6A, + }, + [0x16E6B]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER I", + direction="l", + linebreak="al", + unicodeslot=0x16E6B, + }, + [0x16E6C]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER K", + direction="l", + linebreak="al", + unicodeslot=0x16E6C, + }, + [0x16E6D]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER A", + direction="l", + linebreak="al", + unicodeslot=0x16E6D, + }, + [0x16E6E]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER J", + direction="l", + linebreak="al", + unicodeslot=0x16E6E, + }, + [0x16E6F]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER E", + direction="l", + linebreak="al", + unicodeslot=0x16E6F, + }, + [0x16E70]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER B", + direction="l", + linebreak="al", + unicodeslot=0x16E70, + }, + [0x16E71]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER C", + direction="l", + linebreak="al", + unicodeslot=0x16E71, + }, + [0x16E72]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER U", + direction="l", + linebreak="al", + unicodeslot=0x16E72, + }, + [0x16E73]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER YU", + direction="l", + linebreak="al", + unicodeslot=0x16E73, + }, + [0x16E74]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER L", + direction="l", + linebreak="al", + unicodeslot=0x16E74, + }, + [0x16E75]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER Q", + direction="l", + linebreak="al", + unicodeslot=0x16E75, + }, + [0x16E76]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER HP", + direction="l", + linebreak="al", + unicodeslot=0x16E76, + }, + [0x16E77]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER NY", + direction="l", + linebreak="al", + unicodeslot=0x16E77, + }, + [0x16E78]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER X", + direction="l", + linebreak="al", + unicodeslot=0x16E78, + }, + [0x16E79]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER D", + direction="l", + linebreak="al", + unicodeslot=0x16E79, + }, + [0x16E7A]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER OE", + direction="l", + linebreak="al", + unicodeslot=0x16E7A, + }, + [0x16E7B]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER N", + direction="l", + linebreak="al", + unicodeslot=0x16E7B, + }, + [0x16E7C]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER R", + direction="l", + linebreak="al", + unicodeslot=0x16E7C, + }, + [0x16E7D]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER O", + direction="l", + linebreak="al", + unicodeslot=0x16E7D, + }, + [0x16E7E]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER AI", + direction="l", + linebreak="al", + unicodeslot=0x16E7E, + }, + [0x16E7F]={ + category="ll", + description="MEDEFAIDRIN SMALL LETTER Y", + direction="l", + linebreak="al", + unicodeslot=0x16E7F, + }, + [0x16E80]={ + category="no", + description="MEDEFAIDRIN DIGIT ZERO", + direction="l", + linebreak="al", + unicodeslot=0x16E80, + }, + [0x16E81]={ + category="no", + description="MEDEFAIDRIN DIGIT ONE", + direction="l", + linebreak="al", + unicodeslot=0x16E81, + }, + [0x16E82]={ + category="no", + description="MEDEFAIDRIN DIGIT TWO", + direction="l", + linebreak="al", + unicodeslot=0x16E82, + }, + [0x16E83]={ + category="no", + description="MEDEFAIDRIN DIGIT THREE", + direction="l", + linebreak="al", + unicodeslot=0x16E83, + }, + [0x16E84]={ + category="no", + description="MEDEFAIDRIN DIGIT FOUR", + direction="l", + linebreak="al", + unicodeslot=0x16E84, + }, + [0x16E85]={ + category="no", + description="MEDEFAIDRIN DIGIT FIVE", + direction="l", + linebreak="al", + unicodeslot=0x16E85, + }, + [0x16E86]={ + category="no", + description="MEDEFAIDRIN DIGIT SIX", + direction="l", + linebreak="al", + unicodeslot=0x16E86, + }, + [0x16E87]={ + category="no", + description="MEDEFAIDRIN DIGIT SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x16E87, + }, + [0x16E88]={ + category="no", + description="MEDEFAIDRIN DIGIT EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x16E88, + }, + [0x16E89]={ + category="no", + description="MEDEFAIDRIN DIGIT NINE", + direction="l", + linebreak="al", + unicodeslot=0x16E89, + }, + [0x16E8A]={ + category="no", + description="MEDEFAIDRIN NUMBER TEN", + direction="l", + linebreak="al", + unicodeslot=0x16E8A, + }, + [0x16E8B]={ + category="no", + description="MEDEFAIDRIN NUMBER ELEVEN", + direction="l", + linebreak="al", + unicodeslot=0x16E8B, + }, + [0x16E8C]={ + category="no", + description="MEDEFAIDRIN NUMBER TWELVE", + direction="l", + linebreak="al", + unicodeslot=0x16E8C, + }, + [0x16E8D]={ + category="no", + description="MEDEFAIDRIN NUMBER THIRTEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E8D, + }, + [0x16E8E]={ + category="no", + description="MEDEFAIDRIN NUMBER FOURTEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E8E, + }, + [0x16E8F]={ + category="no", + description="MEDEFAIDRIN NUMBER FIFTEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E8F, + }, + [0x16E90]={ + category="no", + description="MEDEFAIDRIN NUMBER SIXTEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E90, + }, + [0x16E91]={ + category="no", + description="MEDEFAIDRIN NUMBER SEVENTEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E91, + }, + [0x16E92]={ + category="no", + description="MEDEFAIDRIN NUMBER EIGHTEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E92, + }, + [0x16E93]={ + category="no", + description="MEDEFAIDRIN NUMBER NINETEEN", + direction="l", + linebreak="al", + unicodeslot=0x16E93, + }, + [0x16E94]={ + category="no", + description="MEDEFAIDRIN DIGIT ONE ALTERNATE FORM", + direction="l", + linebreak="al", + unicodeslot=0x16E94, + }, + [0x16E95]={ + category="no", + description="MEDEFAIDRIN DIGIT TWO ALTERNATE FORM", + direction="l", + linebreak="al", + unicodeslot=0x16E95, + }, + [0x16E96]={ + category="no", + description="MEDEFAIDRIN DIGIT THREE ALTERNATE FORM", + direction="l", + linebreak="al", + unicodeslot=0x16E96, + }, + [0x16E97]={ + category="po", + description="MEDEFAIDRIN COMMA", + direction="l", + linebreak="ba", + unicodeslot=0x16E97, + }, + [0x16E98]={ + category="po", + description="MEDEFAIDRIN FULL STOP", + direction="l", + linebreak="ba", + unicodeslot=0x16E98, + }, + [0x16E99]={ + category="po", + description="MEDEFAIDRIN SYMBOL AIVA", + direction="l", + linebreak="al", + unicodeslot=0x16E99, + }, + [0x16E9A]={ + category="po", + description="MEDEFAIDRIN EXCLAMATION OH", + direction="l", + linebreak="al", + unicodeslot=0x16E9A, + }, [0x16F00]={ category="lo", description="MIAO LETTER PA", @@ -209493,6 +213384,146 @@ characters.data={ linebreak="al", unicodeslot=0x1D245, }, + [0x1D2E0]={ + category="no", + description="MAYAN NUMERAL ZERO", + direction="l", + linebreak="al", + unicodeslot=0x1D2E0, + }, + [0x1D2E1]={ + category="no", + description="MAYAN NUMERAL ONE", + direction="l", + linebreak="al", + unicodeslot=0x1D2E1, + }, + [0x1D2E2]={ + category="no", + description="MAYAN NUMERAL TWO", + direction="l", + linebreak="al", + unicodeslot=0x1D2E2, + }, + [0x1D2E3]={ + category="no", + description="MAYAN NUMERAL THREE", + direction="l", + linebreak="al", + unicodeslot=0x1D2E3, + }, + [0x1D2E4]={ + category="no", + description="MAYAN NUMERAL FOUR", + direction="l", + linebreak="al", + unicodeslot=0x1D2E4, + }, + [0x1D2E5]={ + category="no", + description="MAYAN NUMERAL FIVE", + direction="l", + linebreak="al", + unicodeslot=0x1D2E5, + }, + [0x1D2E6]={ + category="no", + description="MAYAN NUMERAL SIX", + direction="l", + linebreak="al", + unicodeslot=0x1D2E6, + }, + [0x1D2E7]={ + category="no", + description="MAYAN NUMERAL SEVEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2E7, + }, + [0x1D2E8]={ + category="no", + description="MAYAN NUMERAL EIGHT", + direction="l", + linebreak="al", + unicodeslot=0x1D2E8, + }, + [0x1D2E9]={ + category="no", + description="MAYAN NUMERAL NINE", + direction="l", + linebreak="al", + unicodeslot=0x1D2E9, + }, + [0x1D2EA]={ + category="no", + description="MAYAN NUMERAL TEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2EA, + }, + [0x1D2EB]={ + category="no", + description="MAYAN NUMERAL ELEVEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2EB, + }, + [0x1D2EC]={ + category="no", + description="MAYAN NUMERAL TWELVE", + direction="l", + linebreak="al", + unicodeslot=0x1D2EC, + }, + [0x1D2ED]={ + category="no", + description="MAYAN NUMERAL THIRTEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2ED, + }, + [0x1D2EE]={ + category="no", + description="MAYAN NUMERAL FOURTEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2EE, + }, + [0x1D2EF]={ + category="no", + description="MAYAN NUMERAL FIFTEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2EF, + }, + [0x1D2F0]={ + category="no", + description="MAYAN NUMERAL SIXTEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2F0, + }, + [0x1D2F1]={ + category="no", + description="MAYAN NUMERAL SEVENTEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2F1, + }, + [0x1D2F2]={ + category="no", + description="MAYAN NUMERAL EIGHTEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2F2, + }, + [0x1D2F3]={ + category="no", + description="MAYAN NUMERAL NINETEEN", + direction="l", + linebreak="al", + unicodeslot=0x1D2F3, + }, [0x1D300]={ category="so", description="MONOGRAM FOR EARTH", @@ -210228,6 +214259,55 @@ characters.data={ linebreak="al", unicodeslot=0x1D371, }, + [0x1D372]={ + category="no", + description="IDEOGRAPHIC TALLY MARK ONE", + direction="l", + linebreak="al", + unicodeslot=0x1D372, + }, + [0x1D373]={ + category="no", + description="IDEOGRAPHIC TALLY MARK TWO", + direction="l", + linebreak="al", + unicodeslot=0x1D373, + }, + [0x1D374]={ + category="no", + description="IDEOGRAPHIC TALLY MARK THREE", + direction="l", + linebreak="al", + unicodeslot=0x1D374, + }, + [0x1D375]={ + category="no", + description="IDEOGRAPHIC TALLY MARK FOUR", + direction="l", + linebreak="al", + unicodeslot=0x1D375, + }, + [0x1D376]={ + category="no", + description="IDEOGRAPHIC TALLY MARK FIVE", + direction="l", + linebreak="al", + unicodeslot=0x1D376, + }, + [0x1D377]={ + category="no", + description="TALLY MARK ONE", + direction="l", + linebreak="al", + unicodeslot=0x1D377, + }, + [0x1D378]={ + category="no", + description="TALLY MARK FIVE", + direction="l", + linebreak="al", + unicodeslot=0x1D378, + }, [0x1D400]={ category="lu", description="MATHEMATICAL BOLD CAPITAL A", @@ -226170,6 +230250,482 @@ characters.data={ linebreak="op", unicodeslot=0x1E95F, }, + [0x1EC71]={ + category="no", + description="INDIC SIYAQ NUMBER ONE", + direction="al", + linebreak="al", + unicodeslot=0x1EC71, + }, + [0x1EC72]={ + category="no", + description="INDIC SIYAQ NUMBER TWO", + direction="al", + linebreak="al", + unicodeslot=0x1EC72, + }, + [0x1EC73]={ + category="no", + description="INDIC SIYAQ NUMBER THREE", + direction="al", + linebreak="al", + unicodeslot=0x1EC73, + }, + [0x1EC74]={ + category="no", + description="INDIC SIYAQ NUMBER FOUR", + direction="al", + linebreak="al", + unicodeslot=0x1EC74, + }, + [0x1EC75]={ + category="no", + description="INDIC SIYAQ NUMBER FIVE", + direction="al", + linebreak="al", + unicodeslot=0x1EC75, + }, + [0x1EC76]={ + category="no", + description="INDIC SIYAQ NUMBER SIX", + direction="al", + linebreak="al", + unicodeslot=0x1EC76, + }, + [0x1EC77]={ + category="no", + description="INDIC SIYAQ NUMBER SEVEN", + direction="al", + linebreak="al", + unicodeslot=0x1EC77, + }, + [0x1EC78]={ + category="no", + description="INDIC SIYAQ NUMBER EIGHT", + direction="al", + linebreak="al", + unicodeslot=0x1EC78, + }, + [0x1EC79]={ + category="no", + description="INDIC SIYAQ NUMBER NINE", + direction="al", + linebreak="al", + unicodeslot=0x1EC79, + }, + [0x1EC7A]={ + category="no", + description="INDIC SIYAQ NUMBER TEN", + direction="al", + linebreak="al", + unicodeslot=0x1EC7A, + }, + [0x1EC7B]={ + category="no", + description="INDIC SIYAQ NUMBER TWENTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC7B, + }, + [0x1EC7C]={ + category="no", + description="INDIC SIYAQ NUMBER THIRTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC7C, + }, + [0x1EC7D]={ + category="no", + description="INDIC SIYAQ NUMBER FORTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC7D, + }, + [0x1EC7E]={ + category="no", + description="INDIC SIYAQ NUMBER FIFTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC7E, + }, + [0x1EC7F]={ + category="no", + description="INDIC SIYAQ NUMBER SIXTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC7F, + }, + [0x1EC80]={ + category="no", + description="INDIC SIYAQ NUMBER SEVENTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC80, + }, + [0x1EC81]={ + category="no", + description="INDIC SIYAQ NUMBER EIGHTY", + direction="al", + linebreak="al", + unicodeslot=0x1EC81, + }, + [0x1EC82]={ + category="no", + description="INDIC SIYAQ NUMBER NINETY", + direction="al", + linebreak="al", + unicodeslot=0x1EC82, + }, + [0x1EC83]={ + category="no", + description="INDIC SIYAQ NUMBER ONE HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC83, + }, + [0x1EC84]={ + category="no", + description="INDIC SIYAQ NUMBER TWO HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC84, + }, + [0x1EC85]={ + category="no", + description="INDIC SIYAQ NUMBER THREE HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC85, + }, + [0x1EC86]={ + category="no", + description="INDIC SIYAQ NUMBER FOUR HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC86, + }, + [0x1EC87]={ + category="no", + description="INDIC SIYAQ NUMBER FIVE HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC87, + }, + [0x1EC88]={ + category="no", + description="INDIC SIYAQ NUMBER SIX HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC88, + }, + [0x1EC89]={ + category="no", + description="INDIC SIYAQ NUMBER SEVEN HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC89, + }, + [0x1EC8A]={ + category="no", + description="INDIC SIYAQ NUMBER EIGHT HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC8A, + }, + [0x1EC8B]={ + category="no", + description="INDIC SIYAQ NUMBER NINE HUNDRED", + direction="al", + linebreak="al", + unicodeslot=0x1EC8B, + }, + [0x1EC8C]={ + category="no", + description="INDIC SIYAQ NUMBER ONE THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC8C, + }, + [0x1EC8D]={ + category="no", + description="INDIC SIYAQ NUMBER TWO THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC8D, + }, + [0x1EC8E]={ + category="no", + description="INDIC SIYAQ NUMBER THREE THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC8E, + }, + [0x1EC8F]={ + category="no", + description="INDIC SIYAQ NUMBER FOUR THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC8F, + }, + [0x1EC90]={ + category="no", + description="INDIC SIYAQ NUMBER FIVE THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC90, + }, + [0x1EC91]={ + category="no", + description="INDIC SIYAQ NUMBER SIX THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC91, + }, + [0x1EC92]={ + category="no", + description="INDIC SIYAQ NUMBER SEVEN THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC92, + }, + [0x1EC93]={ + category="no", + description="INDIC SIYAQ NUMBER EIGHT THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC93, + }, + [0x1EC94]={ + category="no", + description="INDIC SIYAQ NUMBER NINE THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC94, + }, + [0x1EC95]={ + category="no", + description="INDIC SIYAQ NUMBER TEN THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC95, + }, + [0x1EC96]={ + category="no", + description="INDIC SIYAQ NUMBER TWENTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC96, + }, + [0x1EC97]={ + category="no", + description="INDIC SIYAQ NUMBER THIRTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC97, + }, + [0x1EC98]={ + category="no", + description="INDIC SIYAQ NUMBER FORTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC98, + }, + [0x1EC99]={ + category="no", + description="INDIC SIYAQ NUMBER FIFTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC99, + }, + [0x1EC9A]={ + category="no", + description="INDIC SIYAQ NUMBER SIXTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC9A, + }, + [0x1EC9B]={ + category="no", + description="INDIC SIYAQ NUMBER SEVENTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC9B, + }, + [0x1EC9C]={ + category="no", + description="INDIC SIYAQ NUMBER EIGHTY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC9C, + }, + [0x1EC9D]={ + category="no", + description="INDIC SIYAQ NUMBER NINETY THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1EC9D, + }, + [0x1EC9E]={ + category="no", + description="INDIC SIYAQ NUMBER LAKH", + direction="al", + linebreak="al", + unicodeslot=0x1EC9E, + }, + [0x1EC9F]={ + category="no", + description="INDIC SIYAQ NUMBER LAKHAN", + direction="al", + linebreak="al", + unicodeslot=0x1EC9F, + }, + [0x1ECA0]={ + category="no", + description="INDIC SIYAQ LAKH MARK", + direction="al", + linebreak="al", + unicodeslot=0x1ECA0, + }, + [0x1ECA1]={ + category="no", + description="INDIC SIYAQ NUMBER KAROR", + direction="al", + linebreak="al", + unicodeslot=0x1ECA1, + }, + [0x1ECA2]={ + category="no", + description="INDIC SIYAQ NUMBER KARORAN", + direction="al", + linebreak="al", + unicodeslot=0x1ECA2, + }, + [0x1ECA3]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED ONE", + direction="al", + linebreak="al", + unicodeslot=0x1ECA3, + }, + [0x1ECA4]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED TWO", + direction="al", + linebreak="al", + unicodeslot=0x1ECA4, + }, + [0x1ECA5]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED THREE", + direction="al", + linebreak="al", + unicodeslot=0x1ECA5, + }, + [0x1ECA6]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED FOUR", + direction="al", + linebreak="al", + unicodeslot=0x1ECA6, + }, + [0x1ECA7]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED FIVE", + direction="al", + linebreak="al", + unicodeslot=0x1ECA7, + }, + [0x1ECA8]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED SIX", + direction="al", + linebreak="al", + unicodeslot=0x1ECA8, + }, + [0x1ECA9]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED SEVEN", + direction="al", + linebreak="al", + unicodeslot=0x1ECA9, + }, + [0x1ECAA]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED EIGHT", + direction="al", + linebreak="al", + unicodeslot=0x1ECAA, + }, + [0x1ECAB]={ + category="no", + description="INDIC SIYAQ NUMBER PREFIXED NINE", + direction="al", + linebreak="al", + unicodeslot=0x1ECAB, + }, + [0x1ECAC]={ + category="so", + description="INDIC SIYAQ PLACEHOLDER", + direction="al", + linebreak="po", + unicodeslot=0x1ECAC, + }, + [0x1ECAD]={ + category="no", + description="INDIC SIYAQ FRACTION ONE QUARTER", + direction="al", + linebreak="al", + unicodeslot=0x1ECAD, + }, + [0x1ECAE]={ + category="no", + description="INDIC SIYAQ FRACTION ONE HALF", + direction="al", + linebreak="al", + unicodeslot=0x1ECAE, + }, + [0x1ECAF]={ + category="no", + description="INDIC SIYAQ FRACTION THREE QUARTERS", + direction="al", + linebreak="al", + unicodeslot=0x1ECAF, + }, + [0x1ECB0]={ + category="sc", + description="INDIC SIYAQ RUPEE MARK", + direction="al", + linebreak="po", + unicodeslot=0x1ECB0, + }, + [0x1ECB1]={ + category="no", + description="INDIC SIYAQ NUMBER ALTERNATE ONE", + direction="al", + linebreak="al", + unicodeslot=0x1ECB1, + }, + [0x1ECB2]={ + category="no", + description="INDIC SIYAQ NUMBER ALTERNATE TWO", + direction="al", + linebreak="al", + unicodeslot=0x1ECB2, + }, + [0x1ECB3]={ + category="no", + description="INDIC SIYAQ NUMBER ALTERNATE TEN THOUSAND", + direction="al", + linebreak="al", + unicodeslot=0x1ECB3, + }, + [0x1ECB4]={ + category="no", + description="INDIC SIYAQ ALTERNATE LAKH MARK", + direction="al", + linebreak="al", + unicodeslot=0x1ECB4, + }, [0x1EE00]={ category="lo", comment="check math properties", @@ -229431,6 +233987,13 @@ characters.data={ specials={ "circle", 0x57, 0x5A }, unicodeslot=0x1F12E, }, + [0x1F12F]={ + category="so", + description="COPYLEFT SYMBOL", + direction="on", + linebreak="al", + unicodeslot=0x1F12F, + }, [0x1F130]={ category="so", cjkwd="a", @@ -239053,6 +243616,14 @@ characters.data={ linebreak="id", unicodeslot=0x1F6F8, }, + [0x1F6F9]={ + category="so", + cjkwd="w", + description="SKATEBOARD", + direction="on", + linebreak="id", + unicodeslot=0x1F6F9, + }, [0x1F700]={ category="so", description="ALCHEMICAL SYMBOL FOR QUINTESSENCE", @@ -240461,6 +245032,34 @@ characters.data={ linebreak="al", unicodeslot=0x1F7D4, }, + [0x1F7D5]={ + category="so", + description="CIRCLED TRIANGLE", + direction="on", + linebreak="id", + unicodeslot=0x1F7D5, + }, + [0x1F7D6]={ + category="so", + description="NEGATIVE CIRCLED TRIANGLE", + direction="on", + linebreak="id", + unicodeslot=0x1F7D6, + }, + [0x1F7D7]={ + category="so", + description="CIRCLED SQUARE", + direction="on", + linebreak="id", + unicodeslot=0x1F7D7, + }, + [0x1F7D8]={ + category="so", + description="NEGATIVE CIRCLED SQUARE", + direction="on", + linebreak="id", + unicodeslot=0x1F7D8, + }, [0x1F800]={ category="so", description="LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD", @@ -242067,6 +246666,30 @@ characters.data={ linebreak="id", unicodeslot=0x1F94C, }, + [0x1F94D]={ + category="so", + cjkwd="w", + description="LACROSSE STICK AND BALL", + direction="on", + linebreak="id", + unicodeslot=0x1F94D, + }, + [0x1F94E]={ + category="so", + cjkwd="w", + description="SOFTBALL", + direction="on", + linebreak="id", + unicodeslot=0x1F94E, + }, + [0x1F94F]={ + category="so", + cjkwd="w", + description="FLYING DISC", + direction="on", + linebreak="id", + unicodeslot=0x1F94F, + }, [0x1F950]={ category="so", cjkwd="w", @@ -242292,6 +246915,118 @@ characters.data={ linebreak="id", unicodeslot=0x1F96B, }, + [0x1F96C]={ + category="so", + cjkwd="w", + description="LEAFY GREEN", + direction="on", + linebreak="id", + unicodeslot=0x1F96C, + }, + [0x1F96D]={ + category="so", + cjkwd="w", + description="MANGO", + direction="on", + linebreak="id", + unicodeslot=0x1F96D, + }, + [0x1F96E]={ + category="so", + cjkwd="w", + description="MOON CAKE", + direction="on", + linebreak="id", + unicodeslot=0x1F96E, + }, + [0x1F96F]={ + category="so", + cjkwd="w", + description="BAGEL", + direction="on", + linebreak="id", + unicodeslot=0x1F96F, + }, + [0x1F970]={ + category="so", + cjkwd="w", + description="SMILING FACE WITH SMILING EYES AND THREE HEARTS", + direction="on", + linebreak="id", + unicodeslot=0x1F970, + }, + [0x1F973]={ + category="so", + cjkwd="w", + description="FACE WITH PARTY HORN AND PARTY HAT", + direction="on", + linebreak="id", + unicodeslot=0x1F973, + }, + [0x1F974]={ + category="so", + cjkwd="w", + description="FACE WITH UNEVEN EYES AND WAVY MOUTH", + direction="on", + linebreak="id", + unicodeslot=0x1F974, + }, + [0x1F975]={ + category="so", + cjkwd="w", + description="OVERHEATED FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F975, + }, + [0x1F976]={ + category="so", + cjkwd="w", + description="FREEZING FACE", + direction="on", + linebreak="id", + unicodeslot=0x1F976, + }, + [0x1F97A]={ + category="so", + cjkwd="w", + description="FACE WITH PLEADING EYES", + direction="on", + linebreak="id", + unicodeslot=0x1F97A, + }, + [0x1F97C]={ + category="so", + cjkwd="w", + description="LAB COAT", + direction="on", + linebreak="id", + unicodeslot=0x1F97C, + }, + [0x1F97D]={ + category="so", + cjkwd="w", + description="GOGGLES", + direction="on", + linebreak="id", + unicodeslot=0x1F97D, + }, + [0x1F97E]={ + category="so", + cjkwd="w", + description="HIKING BOOT", + direction="on", + linebreak="id", + unicodeslot=0x1F97E, + }, + [0x1F97F]={ + category="so", + cjkwd="w", + description="FLAT SHOE", + direction="on", + linebreak="id", + unicodeslot=0x1F97F, + }, [0x1F980]={ category="so", cjkwd="w", @@ -242485,6 +247220,174 @@ characters.data={ linebreak="id", unicodeslot=0x1F997, }, + [0x1F998]={ + category="so", + cjkwd="w", + description="KANGAROO", + direction="on", + linebreak="id", + unicodeslot=0x1F998, + }, + [0x1F999]={ + category="so", + cjkwd="w", + description="LLAMA", + direction="on", + linebreak="id", + unicodeslot=0x1F999, + }, + [0x1F99A]={ + category="so", + cjkwd="w", + description="PEACOCK", + direction="on", + linebreak="id", + unicodeslot=0x1F99A, + }, + [0x1F99B]={ + category="so", + cjkwd="w", + description="HIPPOPOTAMUS", + direction="on", + linebreak="id", + unicodeslot=0x1F99B, + }, + [0x1F99C]={ + category="so", + cjkwd="w", + description="PARROT", + direction="on", + linebreak="id", + unicodeslot=0x1F99C, + }, + [0x1F99D]={ + category="so", + cjkwd="w", + description="RACCOON", + direction="on", + linebreak="id", + unicodeslot=0x1F99D, + }, + [0x1F99E]={ + category="so", + cjkwd="w", + description="LOBSTER", + direction="on", + linebreak="id", + unicodeslot=0x1F99E, + }, + [0x1F99F]={ + category="so", + cjkwd="w", + description="MOSQUITO", + direction="on", + linebreak="id", + unicodeslot=0x1F99F, + }, + [0x1F9A0]={ + category="so", + cjkwd="w", + description="MICROBE", + direction="on", + linebreak="id", + unicodeslot=0x1F9A0, + }, + [0x1F9A1]={ + category="so", + cjkwd="w", + description="BADGER", + direction="on", + linebreak="id", + unicodeslot=0x1F9A1, + }, + [0x1F9A2]={ + category="so", + cjkwd="w", + description="SWAN", + direction="on", + linebreak="id", + unicodeslot=0x1F9A2, + }, + [0x1F9B0]={ + category="so", + cjkwd="w", + description="EMOJI COMPONENT RED HAIR", + direction="on", + linebreak="id", + unicodeslot=0x1F9B0, + }, + [0x1F9B1]={ + category="so", + cjkwd="w", + description="EMOJI COMPONENT CURLY HAIR", + direction="on", + linebreak="id", + unicodeslot=0x1F9B1, + }, + [0x1F9B2]={ + category="so", + cjkwd="w", + description="EMOJI COMPONENT BALD", + direction="on", + linebreak="id", + unicodeslot=0x1F9B2, + }, + [0x1F9B3]={ + category="so", + cjkwd="w", + description="EMOJI COMPONENT WHITE HAIR", + direction="on", + linebreak="id", + unicodeslot=0x1F9B3, + }, + [0x1F9B4]={ + category="so", + cjkwd="w", + description="BONE", + direction="on", + linebreak="id", + unicodeslot=0x1F9B4, + }, + [0x1F9B5]={ + category="so", + cjkwd="w", + description="LEG", + direction="on", + linebreak="eb", + unicodeslot=0x1F9B5, + }, + [0x1F9B6]={ + category="so", + cjkwd="w", + description="FOOT", + direction="on", + linebreak="eb", + unicodeslot=0x1F9B6, + }, + [0x1F9B7]={ + category="so", + cjkwd="w", + description="TOOTH", + direction="on", + linebreak="id", + unicodeslot=0x1F9B7, + }, + [0x1F9B8]={ + category="so", + cjkwd="w", + description="SUPERHERO", + direction="on", + linebreak="eb", + unicodeslot=0x1F9B8, + }, + [0x1F9B9]={ + category="so", + cjkwd="w", + description="SUPERVILLAIN", + direction="on", + linebreak="eb", + unicodeslot=0x1F9B9, + }, [0x1F9C0]={ category="so", cjkwd="w", @@ -242493,6 +247396,22 @@ characters.data={ linebreak="id", unicodeslot=0x1F9C0, }, + [0x1F9C1]={ + category="so", + cjkwd="w", + description="CUPCAKE", + direction="on", + linebreak="id", + unicodeslot=0x1F9C1, + }, + [0x1F9C2]={ + category="so", + cjkwd="w", + description="SALT SHAKER", + direction="on", + linebreak="id", + unicodeslot=0x1F9C2, + }, [0x1F9D0]={ category="so", cjkwd="w", @@ -242677,6 +247596,304 @@ characters.data={ linebreak="id", unicodeslot=0x1F9E6, }, + [0x1F9E7]={ + category="so", + cjkwd="w", + description="RED GIFT ENVELOPE", + direction="on", + linebreak="id", + unicodeslot=0x1F9E7, + }, + [0x1F9E8]={ + category="so", + cjkwd="w", + description="FIRECRACKER", + direction="on", + linebreak="id", + unicodeslot=0x1F9E8, + }, + [0x1F9E9]={ + category="so", + cjkwd="w", + description="JIGSAW PUZZLE PIECE", + direction="on", + linebreak="id", + unicodeslot=0x1F9E9, + }, + [0x1F9EA]={ + category="so", + cjkwd="w", + description="TEST TUBE", + direction="on", + linebreak="id", + unicodeslot=0x1F9EA, + }, + [0x1F9EB]={ + category="so", + cjkwd="w", + description="PETRI DISH", + direction="on", + linebreak="id", + unicodeslot=0x1F9EB, + }, + [0x1F9EC]={ + category="so", + cjkwd="w", + description="DNA DOUBLE HELIX", + direction="on", + linebreak="id", + unicodeslot=0x1F9EC, + }, + [0x1F9ED]={ + category="so", + cjkwd="w", + description="COMPASS", + direction="on", + linebreak="id", + unicodeslot=0x1F9ED, + }, + [0x1F9EE]={ + category="so", + cjkwd="w", + description="ABACUS", + direction="on", + linebreak="id", + unicodeslot=0x1F9EE, + }, + [0x1F9EF]={ + category="so", + cjkwd="w", + description="FIRE EXTINGUISHER", + direction="on", + linebreak="id", + unicodeslot=0x1F9EF, + }, + [0x1F9F0]={ + category="so", + cjkwd="w", + description="TOOLBOX", + direction="on", + linebreak="id", + unicodeslot=0x1F9F0, + }, + [0x1F9F1]={ + category="so", + cjkwd="w", + description="BRICK", + direction="on", + linebreak="id", + unicodeslot=0x1F9F1, + }, + [0x1F9F2]={ + category="so", + cjkwd="w", + description="MAGNET", + direction="on", + linebreak="id", + unicodeslot=0x1F9F2, + }, + [0x1F9F3]={ + category="so", + cjkwd="w", + description="LUGGAGE", + direction="on", + linebreak="id", + unicodeslot=0x1F9F3, + }, + [0x1F9F4]={ + category="so", + cjkwd="w", + description="LOTION BOTTLE", + direction="on", + linebreak="id", + unicodeslot=0x1F9F4, + }, + [0x1F9F5]={ + category="so", + cjkwd="w", + description="SPOOL OF THREAD", + direction="on", + linebreak="id", + unicodeslot=0x1F9F5, + }, + [0x1F9F6]={ + category="so", + cjkwd="w", + description="BALL OF YARN", + direction="on", + linebreak="id", + unicodeslot=0x1F9F6, + }, + [0x1F9F7]={ + category="so", + cjkwd="w", + description="SAFETY PIN", + direction="on", + linebreak="id", + unicodeslot=0x1F9F7, + }, + [0x1F9F8]={ + category="so", + cjkwd="w", + description="TEDDY BEAR", + direction="on", + linebreak="id", + unicodeslot=0x1F9F8, + }, + [0x1F9F9]={ + category="so", + cjkwd="w", + description="BROOM", + direction="on", + linebreak="id", + unicodeslot=0x1F9F9, + }, + [0x1F9FA]={ + category="so", + cjkwd="w", + description="BASKET", + direction="on", + linebreak="id", + unicodeslot=0x1F9FA, + }, + [0x1F9FB]={ + category="so", + cjkwd="w", + description="ROLL OF PAPER", + direction="on", + linebreak="id", + unicodeslot=0x1F9FB, + }, + [0x1F9FC]={ + category="so", + cjkwd="w", + description="BAR OF SOAP", + direction="on", + linebreak="id", + unicodeslot=0x1F9FC, + }, + [0x1F9FD]={ + category="so", + cjkwd="w", + description="SPONGE", + direction="on", + linebreak="id", + unicodeslot=0x1F9FD, + }, + [0x1F9FE]={ + category="so", + cjkwd="w", + description="RECEIPT", + direction="on", + linebreak="id", + unicodeslot=0x1F9FE, + }, + [0x1F9FF]={ + category="so", + cjkwd="w", + description="NAZAR AMULET", + direction="on", + linebreak="id", + unicodeslot=0x1F9FF, + }, + [0x1FA60]={ + category="so", + description="XIANGQI RED GENERAL", + direction="on", + linebreak="id", + unicodeslot=0x1FA60, + }, + [0x1FA61]={ + category="so", + description="XIANGQI RED MANDARIN", + direction="on", + linebreak="id", + unicodeslot=0x1FA61, + }, + [0x1FA62]={ + category="so", + description="XIANGQI RED ELEPHANT", + direction="on", + linebreak="id", + unicodeslot=0x1FA62, + }, + [0x1FA63]={ + category="so", + description="XIANGQI RED HORSE", + direction="on", + linebreak="id", + unicodeslot=0x1FA63, + }, + [0x1FA64]={ + category="so", + description="XIANGQI RED CHARIOT", + direction="on", + linebreak="id", + unicodeslot=0x1FA64, + }, + [0x1FA65]={ + category="so", + description="XIANGQI RED CANNON", + direction="on", + linebreak="id", + unicodeslot=0x1FA65, + }, + [0x1FA66]={ + category="so", + description="XIANGQI RED SOLDIER", + direction="on", + linebreak="id", + unicodeslot=0x1FA66, + }, + [0x1FA67]={ + category="so", + description="XIANGQI BLACK GENERAL", + direction="on", + linebreak="id", + unicodeslot=0x1FA67, + }, + [0x1FA68]={ + category="so", + description="XIANGQI BLACK MANDARIN", + direction="on", + linebreak="id", + unicodeslot=0x1FA68, + }, + [0x1FA69]={ + category="so", + description="XIANGQI BLACK ELEPHANT", + direction="on", + linebreak="id", + unicodeslot=0x1FA69, + }, + [0x1FA6A]={ + category="so", + description="XIANGQI BLACK HORSE", + direction="on", + linebreak="id", + unicodeslot=0x1FA6A, + }, + [0x1FA6B]={ + category="so", + description="XIANGQI BLACK CHARIOT", + direction="on", + linebreak="id", + unicodeslot=0x1FA6B, + }, + [0x1FA6C]={ + category="so", + description="XIANGQI BLACK CANNON", + direction="on", + linebreak="id", + unicodeslot=0x1FA6C, + }, + [0x1FA6D]={ + category="so", + description="XIANGQI BLACK SOLDIER", + direction="on", + linebreak="id", + unicodeslot=0x1FA6D, + }, [0x2F800]={ category="lo", cjkwd="w", diff --git a/tex/context/base/mkiv/char-emj.lua b/tex/context/base/mkiv/char-emj.lua index 718d3bc6e..b00e9ebf8 100644 --- a/tex/context/base/mkiv/char-emj.lua +++ b/tex/context/base/mkiv/char-emj.lua @@ -13,60 +13,42 @@ return { ["1st place medal"]={ 0x1F947 }, ["2nd place medal"]={ 0x1F948 }, ["3rd place medal"]={ 0x1F949 }, - ["a button (blood type)"]={ 0x1F170 }, + ["a button (blood type)"]={ 0x1F170, 0xFE0F }, ["ab button (blood type)"]={ 0x1F18E }, - ["admission tickets"]={ 0x1F39F }, - ["adult"]={ 0x1F9D1 }, - ["adult: dark skin tone"]={ 0x1F9D1, 0x1F3FF }, - ["adult: light skin tone"]={ 0x1F9D1, 0x1F3FB }, - ["adult: medium skin tone"]={ 0x1F9D1, 0x1F3FD }, - ["adult: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE }, - ["adult: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC }, + ["abacus"]={ 0x1F9EE }, + ["adhesive bandage"]={ 0x1FA79 }, + ["admission tickets"]={ 0x1F39F, 0xFE0F }, ["aerial tramway"]={ 0x1F6A1 }, - ["afghanistan"]={ 0x1F1E6, 0x1F1EB }, - ["airplane"]={ 0x2708 }, + ["airplane"]={ 0x2708, 0xFE0F }, ["airplane arrival"]={ 0x1F6EC }, ["airplane departure"]={ 0x1F6EB }, ["alarm clock"]={ 0x23F0 }, - ["albania"]={ 0x1F1E6, 0x1F1F1 }, - ["alembic"]={ 0x2697 }, - ["algeria"]={ 0x1F1E9, 0x1F1FF }, + ["alembic"]={ 0x2697, 0xFE0F }, ["alien"]={ 0x1F47D }, ["alien monster"]={ 0x1F47E }, ["ambulance"]={ 0x1F691 }, ["american football"]={ 0x1F3C8 }, - ["american samoa"]={ 0x1F1E6, 0x1F1F8 }, ["amphora"]={ 0x1F3FA }, ["anchor"]={ 0x2693 }, - ["andorra"]={ 0x1F1E6, 0x1F1E9 }, ["anger symbol"]={ 0x1F4A2 }, - ["angola"]={ 0x1F1E6, 0x1F1F4 }, ["angry face"]={ 0x1F620 }, ["angry face with horns"]={ 0x1F47F }, - ["anguilla"]={ 0x1F1E6, 0x1F1EE }, ["anguished face"]={ 0x1F627 }, ["ant"]={ 0x1F41C }, - ["antarctica"]={ 0x1F1E6, 0x1F1F6 }, ["antenna bars"]={ 0x1F4F6 }, - ["anticlockwise arrows button"]={ 0x1F504 }, - ["antigua & barbuda"]={ 0x1F1E6, 0x1F1EC }, + ["anxious face with sweat"]={ 0x1F630 }, ["aquarius"]={ 0x2652 }, - ["argentina"]={ 0x1F1E6, 0x1F1F7 }, ["aries"]={ 0x2648 }, - ["armenia"]={ 0x1F1E6, 0x1F1F2 }, ["articulated lorry"]={ 0x1F69B }, ["artist palette"]={ 0x1F3A8 }, - ["aruba"]={ 0x1F1E6, 0x1F1FC }, - ["ascension island"]={ 0x1F1E6, 0x1F1E8 }, ["astonished face"]={ 0x1F632 }, ["atm sign"]={ 0x1F3E7 }, - ["atom symbol"]={ 0x269B }, - ["australia"]={ 0x1F1E6, 0x1F1FA }, - ["austria"]={ 0x1F1E6, 0x1F1F9 }, + ["atom symbol"]={ 0x269B, 0xFE0F }, + ["auto rickshaw"]={ 0x1F6FA }, ["automobile"]={ 0x1F697 }, ["avocado"]={ 0x1F951 }, - ["azerbaijan"]={ 0x1F1E6, 0x1F1FF }, - ["b button (blood type)"]={ 0x1F171 }, + ["axe"]={ 0x1FA93 }, + ["b button (blood type)"]={ 0x1F171, 0xFE0F }, ["baby"]={ 0x1F476 }, ["baby angel"]={ 0x1F47C }, ["baby angel: dark skin tone"]={ 0x1F47C, 0x1F3FF }, @@ -107,97 +89,68 @@ return { ["backhand index pointing up: medium skin tone"]={ 0x1F446, 0x1F3FD }, ["backhand index pointing up: medium-dark skin tone"]={ 0x1F446, 0x1F3FE }, ["backhand index pointing up: medium-light skin tone"]={ 0x1F446, 0x1F3FC }, + ["backpack"]={ 0x1F392 }, ["bacon"]={ 0x1F953 }, + ["badger"]={ 0x1F9A1 }, ["badminton"]={ 0x1F3F8 }, + ["bagel"]={ 0x1F96F }, ["baggage claim"]={ 0x1F6C4 }, ["baguette bread"]={ 0x1F956 }, - ["bahamas"]={ 0x1F1E7, 0x1F1F8 }, - ["bahrain"]={ 0x1F1E7, 0x1F1ED }, - ["balance scale"]={ 0x2696 }, + ["balance scale"]={ 0x2696, 0xFE0F }, + ["ballet shoes"]={ 0x1FA70 }, ["balloon"]={ 0x1F388 }, - ["ballot box with ballot"]={ 0x1F5F3 }, - ["ballot box with check"]={ 0x2611 }, + ["ballot box with ballot"]={ 0x1F5F3, 0xFE0F }, ["banana"]={ 0x1F34C }, - ["bangladesh"]={ 0x1F1E7, 0x1F1E9 }, + ["banjo"]={ 0x1FA95 }, ["bank"]={ 0x1F3E6 }, ["bar chart"]={ 0x1F4CA }, - ["barbados"]={ 0x1F1E7, 0x1F1E7 }, ["barber pole"]={ 0x1F488 }, ["baseball"]={ 0x26BE }, + ["basket"]={ 0x1F9FA }, ["basketball"]={ 0x1F3C0 }, ["bat"]={ 0x1F987 }, ["bathtub"]={ 0x1F6C1 }, ["battery"]={ 0x1F50B }, - ["beach with umbrella"]={ 0x1F3D6 }, - ["bear face"]={ 0x1F43B }, - ["bearded person"]={ 0x1F9D4 }, - ["bearded person: dark skin tone"]={ 0x1F9D4, 0x1F3FF }, - ["bearded person: light skin tone"]={ 0x1F9D4, 0x1F3FB }, - ["bearded person: medium skin tone"]={ 0x1F9D4, 0x1F3FD }, - ["bearded person: medium-dark skin tone"]={ 0x1F9D4, 0x1F3FE }, - ["bearded person: medium-light skin tone"]={ 0x1F9D4, 0x1F3FC }, + ["beach with umbrella"]={ 0x1F3D6, 0xFE0F }, + ["beaming face with smiling eyes"]={ 0x1F601 }, + ["bear"]={ 0x1F43B }, ["beating heart"]={ 0x1F493 }, - ["bed"]={ 0x1F6CF }, + ["bed"]={ 0x1F6CF, 0xFE0F }, ["beer mug"]={ 0x1F37A }, - ["belarus"]={ 0x1F1E7, 0x1F1FE }, - ["belgium"]={ 0x1F1E7, 0x1F1EA }, - ["belize"]={ 0x1F1E7, 0x1F1FF }, ["bell"]={ 0x1F514 }, ["bell with slash"]={ 0x1F515 }, - ["bellhop bell"]={ 0x1F6CE }, - ["benin"]={ 0x1F1E7, 0x1F1EF }, + ["bellhop bell"]={ 0x1F6CE, 0xFE0F }, ["bento box"]={ 0x1F371 }, - ["bermuda"]={ 0x1F1E7, 0x1F1F2 }, - ["bhutan"]={ 0x1F1E7, 0x1F1F9 }, + ["beverage box"]={ 0x1F9C3 }, ["bicycle"]={ 0x1F6B2 }, ["bikini"]={ 0x1F459 }, ["billed cap"]={ 0x1F9E2 }, - ["biohazard"]={ 0x2623 }, + ["biohazard"]={ 0x2623, 0xFE0F }, ["bird"]={ 0x1F426 }, ["birthday cake"]={ 0x1F382 }, ["black circle"]={ 0x26AB }, ["black flag"]={ 0x1F3F4 }, ["black heart"]={ 0x1F5A4 }, ["black large square"]={ 0x2B1B }, - ["black medium square"]={ 0x25FC }, + ["black medium square"]={ 0x25FC, 0xFE0F }, ["black medium-small square"]={ 0x25FE }, - ["black nib"]={ 0x2712 }, - ["black small square"]={ 0x25AA }, + ["black nib"]={ 0x2712, 0xFE0F }, + ["black small square"]={ 0x25AA, 0xFE0F }, ["black square button"]={ 0x1F532 }, - ["blond-haired man"]={ 0x1F471, 0x200D, 0x2642 }, - ["blond-haired man: dark skin tone"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2642 }, - ["blond-haired man: light skin tone"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2642 }, - ["blond-haired man: medium skin tone"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2642 }, - ["blond-haired man: medium-dark skin tone"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2642 }, - ["blond-haired man: medium-light skin tone"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2642 }, - ["blond-haired person"]={ 0x1F471 }, - ["blond-haired person: dark skin tone"]={ 0x1F471, 0x1F3FF }, - ["blond-haired person: light skin tone"]={ 0x1F471, 0x1F3FB }, - ["blond-haired person: medium skin tone"]={ 0x1F471, 0x1F3FD }, - ["blond-haired person: medium-dark skin tone"]={ 0x1F471, 0x1F3FE }, - ["blond-haired person: medium-light skin tone"]={ 0x1F471, 0x1F3FC }, - ["blond-haired woman"]={ 0x1F471, 0x200D, 0x2640 }, - ["blond-haired woman: dark skin tone"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2640 }, - ["blond-haired woman: light skin tone"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2640 }, - ["blond-haired woman: medium skin tone"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2640 }, - ["blond-haired woman: medium-dark skin tone"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2640 }, - ["blond-haired woman: medium-light skin tone"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2640 }, ["blossom"]={ 0x1F33C }, ["blowfish"]={ 0x1F421 }, ["blue book"]={ 0x1F4D8 }, ["blue circle"]={ 0x1F535 }, ["blue heart"]={ 0x1F499 }, + ["blue square"]={ 0x1F7E6 }, ["boar"]={ 0x1F417 }, - ["bolivia"]={ 0x1F1E7, 0x1F1F4 }, ["bomb"]={ 0x1F4A3 }, + ["bone"]={ 0x1F9B4 }, ["bookmark"]={ 0x1F516 }, ["bookmark tabs"]={ 0x1F4D1 }, ["books"]={ 0x1F4DA }, - ["bosnia & herzegovina"]={ 0x1F1E7, 0x1F1E6 }, - ["botswana"]={ 0x1F1E7, 0x1F1FC }, ["bottle with popping cork"]={ 0x1F37E }, ["bouquet"]={ 0x1F490 }, - ["bouvet island"]={ 0x1F1E7, 0x1F1FB }, ["bow and arrow"]={ 0x1F3F9 }, ["bowl with spoon"]={ 0x1F963 }, ["bowling"]={ 0x1F3B3 }, @@ -209,7 +162,6 @@ return { ["boy: medium-dark skin tone"]={ 0x1F466, 0x1F3FE }, ["boy: medium-light skin tone"]={ 0x1F466, 0x1F3FC }, ["brain"]={ 0x1F9E0 }, - ["brazil"]={ 0x1F1E7, 0x1F1F7 }, ["bread"]={ 0x1F35E }, ["breast-feeding"]={ 0x1F931 }, ["breast-feeding: dark skin tone"]={ 0x1F931, 0x1F3FF }, @@ -217,6 +169,7 @@ return { ["breast-feeding: medium skin tone"]={ 0x1F931, 0x1F3FD }, ["breast-feeding: medium-dark skin tone"]={ 0x1F931, 0x1F3FE }, ["breast-feeding: medium-light skin tone"]={ 0x1F931, 0x1F3FC }, + ["brick"]={ 0x1F9F1 }, ["bride with veil"]={ 0x1F470 }, ["bride with veil: dark skin tone"]={ 0x1F470, 0x1F3FF }, ["bride with veil: light skin tone"]={ 0x1F470, 0x1F3FB }, @@ -226,21 +179,21 @@ return { ["bridge at night"]={ 0x1F309 }, ["briefcase"]={ 0x1F4BC }, ["bright button"]={ 0x1F506 }, - ["british indian ocean territory"]={ 0x1F1EE, 0x1F1F4 }, - ["british virgin islands"]={ 0x1F1FB, 0x1F1EC }, ["broccoli"]={ 0x1F966 }, ["broken heart"]={ 0x1F494 }, - ["brunei"]={ 0x1F1E7, 0x1F1F3 }, + ["broom"]={ 0x1F9F9 }, + ["brown circle"]={ 0x1F7E4 }, + ["brown heart"]={ 0x1F90E }, + ["brown square"]={ 0x1F7EB }, ["bug"]={ 0x1F41B }, - ["building construction"]={ 0x1F3D7 }, - ["bulgaria"]={ 0x1F1E7, 0x1F1EC }, - ["burkina faso"]={ 0x1F1E7, 0x1F1EB }, + ["building construction"]={ 0x1F3D7, 0xFE0F }, + ["bullet train"]={ 0x1F685 }, ["burrito"]={ 0x1F32F }, - ["burundi"]={ 0x1F1E7, 0x1F1EE }, ["bus"]={ 0x1F68C }, ["bus stop"]={ 0x1F68F }, ["bust in silhouette"]={ 0x1F464 }, ["busts in silhouette"]={ 0x1F465 }, + ["butter"]={ 0x1F9C8 }, ["butterfly"]={ 0x1F98B }, ["cactus"]={ 0x1F335 }, ["calendar"]={ 0x1F4C5 }, @@ -250,45 +203,40 @@ return { ["call me hand: medium skin tone"]={ 0x1F919, 0x1F3FD }, ["call me hand: medium-dark skin tone"]={ 0x1F919, 0x1F3FE }, ["call me hand: medium-light skin tone"]={ 0x1F919, 0x1F3FC }, - ["cambodia"]={ 0x1F1F0, 0x1F1ED }, ["camel"]={ 0x1F42A }, ["camera"]={ 0x1F4F7 }, ["camera with flash"]={ 0x1F4F8 }, - ["cameroon"]={ 0x1F1E8, 0x1F1F2 }, - ["camping"]={ 0x1F3D5 }, - ["canada"]={ 0x1F1E8, 0x1F1E6 }, - ["canary islands"]={ 0x1F1EE, 0x1F1E8 }, + ["camping"]={ 0x1F3D5, 0xFE0F }, ["cancer"]={ 0x264B }, - ["candle"]={ 0x1F56F }, + ["candle"]={ 0x1F56F, 0xFE0F }, ["candy"]={ 0x1F36C }, ["canned food"]={ 0x1F96B }, ["canoe"]={ 0x1F6F6 }, - ["cape verde"]={ 0x1F1E8, 0x1F1FB }, ["capricorn"]={ 0x2651 }, - ["card file box"]={ 0x1F5C3 }, + ["card file box"]={ 0x1F5C3, 0xFE0F }, ["card index"]={ 0x1F4C7 }, - ["card index dividers"]={ 0x1F5C2 }, - ["caribbean netherlands"]={ 0x1F1E7, 0x1F1F6 }, + ["card index dividers"]={ 0x1F5C2, 0xFE0F }, ["carousel horse"]={ 0x1F3A0 }, ["carp streamer"]={ 0x1F38F }, ["carrot"]={ 0x1F955 }, ["castle"]={ 0x1F3F0 }, ["cat"]={ 0x1F408 }, ["cat face"]={ 0x1F431 }, - ["cat face with tears of joy"]={ 0x1F639 }, - ["cat face with wry smile"]={ 0x1F63C }, - ["cayman islands"]={ 0x1F1F0, 0x1F1FE }, - ["central african republic"]={ 0x1F1E8, 0x1F1EB }, - ["ceuta & melilla"]={ 0x1F1EA, 0x1F1E6 }, - ["chad"]={ 0x1F1F9, 0x1F1E9 }, - ["chains"]={ 0x26D3 }, + ["cat with tears of joy"]={ 0x1F639 }, + ["cat with wry smile"]={ 0x1F63C }, + ["chains"]={ 0x26D3, 0xFE0F }, + ["chair"]={ 0x1FA91 }, ["chart decreasing"]={ 0x1F4C9 }, ["chart increasing"]={ 0x1F4C8 }, ["chart increasing with yen"]={ 0x1F4B9 }, + ["check box with check"]={ 0x2611, 0xFE0F }, + ["check mark"]={ 0x2714, 0xFE0F }, + ["check mark button"]={ 0x2705 }, ["cheese wedge"]={ 0x1F9C0 }, ["chequered flag"]={ 0x1F3C1 }, ["cherries"]={ 0x1F352 }, ["cherry blossom"]={ 0x1F338 }, + ["chess pawn"]={ 0x265F, 0xFE0F }, ["chestnut"]={ 0x1F330 }, ["chicken"]={ 0x1F414 }, ["child"]={ 0x1F9D2 }, @@ -298,22 +246,19 @@ return { ["child: medium-dark skin tone"]={ 0x1F9D2, 0x1F3FE }, ["child: medium-light skin tone"]={ 0x1F9D2, 0x1F3FC }, ["children crossing"]={ 0x1F6B8 }, - ["chile"]={ 0x1F1E8, 0x1F1F1 }, - ["china"]={ 0x1F1E8, 0x1F1F3 }, - ["chipmunk"]={ 0x1F43F }, + ["chipmunk"]={ 0x1F43F, 0xFE0F }, ["chocolate bar"]={ 0x1F36B }, ["chopsticks"]={ 0x1F962 }, - ["christmas island"]={ 0x1F1E8, 0x1F1FD }, ["christmas tree"]={ 0x1F384 }, ["church"]={ 0x26EA }, ["cigarette"]={ 0x1F6AC }, ["cinema"]={ 0x1F3A6 }, - ["circled m"]={ 0x24C2 }, + ["circled m"]={ 0x24C2, 0xFE0F }, ["circus tent"]={ 0x1F3AA }, - ["cityscape"]={ 0x1F3D9 }, + ["cityscape"]={ 0x1F3D9, 0xFE0F }, ["cityscape at dusk"]={ 0x1F306 }, ["cl button"]={ 0x1F191 }, - ["clamp"]={ 0x1F5DC }, + ["clamp"]={ 0x1F5DC, 0xFE0F }, ["clapper board"]={ 0x1F3AC }, ["clapping hands"]={ 0x1F44F }, ["clapping hands: dark skin tone"]={ 0x1F44F, 0x1F3FF }, @@ -321,40 +266,36 @@ return { ["clapping hands: medium skin tone"]={ 0x1F44F, 0x1F3FD }, ["clapping hands: medium-dark skin tone"]={ 0x1F44F, 0x1F3FE }, ["clapping hands: medium-light skin tone"]={ 0x1F44F, 0x1F3FC }, - ["classical building"]={ 0x1F3DB }, + ["classical building"]={ 0x1F3DB, 0xFE0F }, ["clinking beer mugs"]={ 0x1F37B }, ["clinking glasses"]={ 0x1F942 }, ["clipboard"]={ 0x1F4CB }, - ["clipperton island"]={ 0x1F1E8, 0x1F1F5 }, ["clockwise vertical arrows"]={ 0x1F503 }, ["closed book"]={ 0x1F4D5 }, ["closed mailbox with lowered flag"]={ 0x1F4EA }, ["closed mailbox with raised flag"]={ 0x1F4EB }, ["closed umbrella"]={ 0x1F302 }, - ["cloud"]={ 0x2601 }, - ["cloud with lightning"]={ 0x1F329 }, - ["cloud with lightning and rain"]={ 0x26C8 }, - ["cloud with rain"]={ 0x1F327 }, - ["cloud with snow"]={ 0x1F328 }, + ["cloud"]={ 0x2601, 0xFE0F }, + ["cloud with lightning"]={ 0x1F329, 0xFE0F }, + ["cloud with lightning and rain"]={ 0x26C8, 0xFE0F }, + ["cloud with rain"]={ 0x1F327, 0xFE0F }, + ["cloud with snow"]={ 0x1F328, 0xFE0F }, ["clown face"]={ 0x1F921 }, - ["club suit"]={ 0x2663 }, + ["club suit"]={ 0x2663, 0xFE0F }, ["clutch bag"]={ 0x1F45D }, ["coat"]={ 0x1F9E5 }, ["cocktail glass"]={ 0x1F378 }, ["coconut"]={ 0x1F965 }, - ["cocos (keeling) islands"]={ 0x1F1E8, 0x1F1E8 }, - ["coffin"]={ 0x26B0 }, + ["coffin"]={ 0x26B0, 0xFE0F }, + ["cold face"]={ 0x1F976 }, ["collision"]={ 0x1F4A5 }, - ["colombia"]={ 0x1F1E8, 0x1F1F4 }, - ["comet"]={ 0x2604 }, - ["comoros"]={ 0x1F1F0, 0x1F1F2 }, + ["comet"]={ 0x2604, 0xFE0F }, + ["compass"]={ 0x1F9ED }, ["computer disk"]={ 0x1F4BD }, - ["computer mouse"]={ 0x1F5B1 }, + ["computer mouse"]={ 0x1F5B1, 0xFE0F }, ["confetti ball"]={ 0x1F38A }, ["confounded face"]={ 0x1F616 }, ["confused face"]={ 0x1F615 }, - ["congo - brazzaville"]={ 0x1F1E8, 0x1F1EC }, - ["congo - kinshasa"]={ 0x1F1E8, 0x1F1E9 }, ["construction"]={ 0x1F6A7 }, ["construction worker"]={ 0x1F477 }, ["construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF }, @@ -362,30 +303,28 @@ return { ["construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD }, ["construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE }, ["construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC }, - ["control knobs"]={ 0x1F39B }, + ["control knobs"]={ 0x1F39B, 0xFE0F }, ["convenience store"]={ 0x1F3EA }, - ["cook islands"]={ 0x1F1E8, 0x1F1F0 }, ["cooked rice"]={ 0x1F35A }, ["cookie"]={ 0x1F36A }, ["cooking"]={ 0x1F373 }, ["cool button"]={ 0x1F192 }, - ["copyright"]={ 0xA9 }, - ["costa rica"]={ 0x1F1E8, 0x1F1F7 }, - ["couch and lamp"]={ 0x1F6CB }, + ["copyright"]={ 0xA9, 0xFE0F }, + ["couch and lamp"]={ 0x1F6CB, 0xFE0F }, + ["counterclockwise arrows button"]={ 0x1F504 }, ["couple with heart"]={ 0x1F491 }, - ["couple with heart: man, man"]={ 0x1F468, 0x200D, 0x2764, 0x200D, 0x1F468 }, - ["couple with heart: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F468 }, - ["couple with heart: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F469 }, + ["couple with heart: man, man"]={ 0x1F468, 0x200D, 0x2764, 0xFE0F, 0x200D, 0x1F468 }, + ["couple with heart: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0xFE0F, 0x200D, 0x1F468 }, + ["couple with heart: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0xFE0F, 0x200D, 0x1F469 }, ["cow"]={ 0x1F404 }, ["cow face"]={ 0x1F42E }, ["cowboy hat face"]={ 0x1F920 }, ["crab"]={ 0x1F980 }, - ["crayon"]={ 0x1F58D }, - ["crazy face"]={ 0x1F92A }, + ["crayon"]={ 0x1F58D, 0xFE0F }, ["credit card"]={ 0x1F4B3 }, ["crescent moon"]={ 0x1F319 }, - ["cricket"]={ 0x1F3CF }, - ["croatia"]={ 0x1F1ED, 0x1F1F7 }, + ["cricket"]={ 0x1F997 }, + ["cricket game"]={ 0x1F3CF }, ["crocodile"]={ 0x1F40A }, ["croissant"]={ 0x1F950 }, ["cross mark"]={ 0x274C }, @@ -397,15 +336,14 @@ return { ["crossed fingers: medium-dark skin tone"]={ 0x1F91E, 0x1F3FE }, ["crossed fingers: medium-light skin tone"]={ 0x1F91E, 0x1F3FC }, ["crossed flags"]={ 0x1F38C }, - ["crossed swords"]={ 0x2694 }, + ["crossed swords"]={ 0x2694, 0xFE0F }, ["crown"]={ 0x1F451 }, - ["crying cat face"]={ 0x1F63F }, + ["crying cat"]={ 0x1F63F }, ["crying face"]={ 0x1F622 }, ["crystal ball"]={ 0x1F52E }, - ["cuba"]={ 0x1F1E8, 0x1F1FA }, ["cucumber"]={ 0x1F952 }, ["cup with straw"]={ 0x1F964 }, - ["curaçao"]={ 0x1F1E8, 0x1F1FC }, + ["cupcake"]={ 0x1F9C1 }, ["curling stone"]={ 0x1F94C }, ["curly loop"]={ 0x27B0 }, ["currency exchange"]={ 0x1F4B1 }, @@ -414,57 +352,72 @@ return { ["customs"]={ 0x1F6C3 }, ["cut of meat"]={ 0x1F969 }, ["cyclone"]={ 0x1F300 }, - ["cyprus"]={ 0x1F1E8, 0x1F1FE }, - ["czechia"]={ 0x1F1E8, 0x1F1FF }, - ["côte d’ivoire"]={ 0x1F1E8, 0x1F1EE }, - ["dagger"]={ 0x1F5E1 }, + ["dagger"]={ 0x1F5E1, 0xFE0F }, ["dango"]={ 0x1F361 }, ["dashing away"]={ 0x1F4A8 }, + ["deaf man"]={ 0x1F9CF, 0x200D, 0x2642, 0xFE0F }, + ["deaf man: dark skin tone"]={ 0x1F9CF, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["deaf man: light skin tone"]={ 0x1F9CF, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["deaf man: medium skin tone"]={ 0x1F9CF, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["deaf man: medium-dark skin tone"]={ 0x1F9CF, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["deaf man: medium-light skin tone"]={ 0x1F9CF, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["deaf person"]={ 0x1F9CF }, + ["deaf person: dark skin tone"]={ 0x1F9CF, 0x1F3FF }, + ["deaf person: light skin tone"]={ 0x1F9CF, 0x1F3FB }, + ["deaf person: medium skin tone"]={ 0x1F9CF, 0x1F3FD }, + ["deaf person: medium-dark skin tone"]={ 0x1F9CF, 0x1F3FE }, + ["deaf person: medium-light skin tone"]={ 0x1F9CF, 0x1F3FC }, + ["deaf woman"]={ 0x1F9CF, 0x200D, 0x2640, 0xFE0F }, + ["deaf woman: dark skin tone"]={ 0x1F9CF, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["deaf woman: light skin tone"]={ 0x1F9CF, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["deaf woman: medium skin tone"]={ 0x1F9CF, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["deaf woman: medium-dark skin tone"]={ 0x1F9CF, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["deaf woman: medium-light skin tone"]={ 0x1F9CF, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["deciduous tree"]={ 0x1F333 }, ["deer"]={ 0x1F98C }, ["delivery truck"]={ 0x1F69A }, - ["denmark"]={ 0x1F1E9, 0x1F1F0 }, ["department store"]={ 0x1F3EC }, - ["derelict house"]={ 0x1F3DA }, - ["desert"]={ 0x1F3DC }, - ["desert island"]={ 0x1F3DD }, - ["desktop computer"]={ 0x1F5A5 }, - ["detective"]={ 0x1F575 }, + ["derelict house"]={ 0x1F3DA, 0xFE0F }, + ["desert"]={ 0x1F3DC, 0xFE0F }, + ["desert island"]={ 0x1F3DD, 0xFE0F }, + ["desktop computer"]={ 0x1F5A5, 0xFE0F }, + ["detective"]={ 0x1F575, 0xFE0F }, ["detective: dark skin tone"]={ 0x1F575, 0x1F3FF }, ["detective: light skin tone"]={ 0x1F575, 0x1F3FB }, ["detective: medium skin tone"]={ 0x1F575, 0x1F3FD }, ["detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE }, ["detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC }, - ["diamond suit"]={ 0x2666 }, + ["diamond suit"]={ 0x2666, 0xFE0F }, ["diamond with a dot"]={ 0x1F4A0 }, - ["diego garcia"]={ 0x1F1E9, 0x1F1EC }, ["dim button"]={ 0x1F505 }, ["direct hit"]={ 0x1F3AF }, - ["disappointed but relieved face"]={ 0x1F625 }, ["disappointed face"]={ 0x1F61E }, + ["diving mask"]={ 0x1F93F }, + ["division sign"]={ 0x2797 }, + ["diya lamp"]={ 0x1FA94 }, ["dizzy"]={ 0x1F4AB }, ["dizzy face"]={ 0x1F635 }, - ["djibouti"]={ 0x1F1E9, 0x1F1EF }, + ["dna"]={ 0x1F9EC }, ["dog"]={ 0x1F415 }, ["dog face"]={ 0x1F436 }, ["dollar banknote"]={ 0x1F4B5 }, ["dolphin"]={ 0x1F42C }, - ["dominica"]={ 0x1F1E9, 0x1F1F2 }, - ["dominican republic"]={ 0x1F1E9, 0x1F1F4 }, ["door"]={ 0x1F6AA }, ["dotted six-pointed star"]={ 0x1F52F }, ["double curly loop"]={ 0x27BF }, - ["double exclamation mark"]={ 0x203C }, + ["double exclamation mark"]={ 0x203C, 0xFE0F }, ["doughnut"]={ 0x1F369 }, - ["dove"]={ 0x1F54A }, - ["down arrow"]={ 0x2B07 }, - ["down button"]={ 0x1F53D }, - ["down-left arrow"]={ 0x2199 }, - ["down-right arrow"]={ 0x2198 }, + ["dove"]={ 0x1F54A, 0xFE0F }, + ["down arrow"]={ 0x2B07, 0xFE0F }, + ["down-left arrow"]={ 0x2199, 0xFE0F }, + ["down-right arrow"]={ 0x2198, 0xFE0F }, + ["downcast face with sweat"]={ 0x1F613 }, + ["downwards button"]={ 0x1F53D }, ["dragon"]={ 0x1F409 }, ["dragon face"]={ 0x1F432 }, ["dress"]={ 0x1F457 }, ["drooling face"]={ 0x1F924 }, + ["drop of blood"]={ 0x1FA78 }, ["droplet"]={ 0x1F4A7 }, ["drum"]={ 0x1F941 }, ["duck"]={ 0x1F986 }, @@ -474,21 +427,24 @@ return { ["eagle"]={ 0x1F985 }, ["ear"]={ 0x1F442 }, ["ear of corn"]={ 0x1F33D }, + ["ear with hearing aid"]={ 0x1F9BB }, + ["ear with hearing aid: dark skin tone"]={ 0x1F9BB, 0x1F3FF }, + ["ear with hearing aid: light skin tone"]={ 0x1F9BB, 0x1F3FB }, + ["ear with hearing aid: medium skin tone"]={ 0x1F9BB, 0x1F3FD }, + ["ear with hearing aid: medium-dark skin tone"]={ 0x1F9BB, 0x1F3FE }, + ["ear with hearing aid: medium-light skin tone"]={ 0x1F9BB, 0x1F3FC }, ["ear: dark skin tone"]={ 0x1F442, 0x1F3FF }, ["ear: light skin tone"]={ 0x1F442, 0x1F3FB }, ["ear: medium skin tone"]={ 0x1F442, 0x1F3FD }, ["ear: medium-dark skin tone"]={ 0x1F442, 0x1F3FE }, ["ear: medium-light skin tone"]={ 0x1F442, 0x1F3FC }, - ["ecuador"]={ 0x1F1EA, 0x1F1E8 }, ["egg"]={ 0x1F95A }, ["eggplant"]={ 0x1F346 }, - ["egypt"]={ 0x1F1EA, 0x1F1EC }, ["eight o’clock"]={ 0x1F557 }, - ["eight-pointed star"]={ 0x2734 }, - ["eight-spoked asterisk"]={ 0x2733 }, + ["eight-pointed star"]={ 0x2734, 0xFE0F }, + ["eight-spoked asterisk"]={ 0x2733, 0xFE0F }, ["eight-thirty"]={ 0x1F563 }, - ["eject button"]={ 0x23CF }, - ["el salvador"]={ 0x1F1F8, 0x1F1FB }, + ["eject button"]={ 0x23CF, 0xFE0F }, ["electric plug"]={ 0x1F50C }, ["elephant"]={ 0x1F418 }, ["eleven o’clock"]={ 0x1F55A }, @@ -500,44 +456,34 @@ return { ["elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE }, ["elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC }, ["end arrow"]={ 0x1F51A }, - ["england"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0065, 0xE006E, 0xE0067, 0xE007F }, - ["envelope"]={ 0x2709 }, + ["envelope"]={ 0x2709, 0xFE0F }, ["envelope with arrow"]={ 0x1F4E9 }, - ["equatorial guinea"]={ 0x1F1EC, 0x1F1F6 }, - ["eritrea"]={ 0x1F1EA, 0x1F1F7 }, - ["estonia"]={ 0x1F1EA, 0x1F1EA }, - ["ethiopia"]={ 0x1F1EA, 0x1F1F9 }, ["euro banknote"]={ 0x1F4B6 }, - ["european union"]={ 0x1F1EA, 0x1F1FA }, ["evergreen tree"]={ 0x1F332 }, ["ewe"]={ 0x1F411 }, ["exclamation mark"]={ 0x2757 }, - ["exclamation question mark"]={ 0x2049 }, + ["exclamation question mark"]={ 0x2049, 0xFE0F }, ["exploding head"]={ 0x1F92F }, ["expressionless face"]={ 0x1F611 }, - ["eye"]={ 0x1F441 }, - ["eye in speech bubble"]={ 0x1F441, 0x200D, 0x1F5E8 }, + ["eye"]={ 0x1F441, 0xFE0F }, + ["eye in speech bubble"]={ 0x1F441, 0xFE0F, 0x200D, 0x1F5E8, 0xFE0F }, ["eyes"]={ 0x1F440 }, ["face blowing a kiss"]={ 0x1F618 }, - ["face savouring delicious food"]={ 0x1F60B }, + ["face savoring food"]={ 0x1F60B }, ["face screaming in fear"]={ 0x1F631 }, ["face vomiting"]={ 0x1F92E }, - ["face with cold sweat"]={ 0x1F613 }, ["face with hand over mouth"]={ 0x1F92D }, ["face with head-bandage"]={ 0x1F915 }, ["face with medical mask"]={ 0x1F637 }, ["face with monocle"]={ 0x1F9D0 }, ["face with open mouth"]={ 0x1F62E }, - ["face with open mouth & cold sweat"]={ 0x1F630 }, ["face with raised eyebrow"]={ 0x1F928 }, ["face with rolling eyes"]={ 0x1F644 }, ["face with steam from nose"]={ 0x1F624 }, - ["face with stuck-out tongue"]={ 0x1F61B }, - ["face with stuck-out tongue & closed eyes"]={ 0x1F61D }, - ["face with stuck-out tongue & winking eye"]={ 0x1F61C }, - ["face with symbols over mouth"]={ 0x1F92C }, + ["face with symbols on mouth"]={ 0x1F92C }, ["face with tears of joy"]={ 0x1F602 }, ["face with thermometer"]={ 0x1F912 }, + ["face with tongue"]={ 0x1F61B }, ["face without mouth"]={ 0x1F636 }, ["factory"]={ 0x1F3ED }, ["fairy"]={ 0x1F9DA }, @@ -546,7 +492,7 @@ return { ["fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD }, ["fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE }, ["fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC }, - ["falkland islands"]={ 0x1F1EB, 0x1F1F0 }, + ["falafel"]={ 0x1F9C6 }, ["fallen leaf"]={ 0x1F342 }, ["family"]={ 0x1F46A }, ["family: man, boy"]={ 0x1F468, 0x200D, 0x1F466 }, @@ -574,36 +520,298 @@ return { ["family: woman, woman, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467 }, ["family: woman, woman, girl, boy"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F466 }, ["family: woman, woman, girl, girl"]={ 0x1F469, 0x200D, 0x1F469, 0x200D, 0x1F467, 0x200D, 0x1F467 }, - ["faroe islands"]={ 0x1F1EB, 0x1F1F4 }, ["fast down button"]={ 0x23EC }, ["fast reverse button"]={ 0x23EA }, ["fast up button"]={ 0x23EB }, ["fast-forward button"]={ 0x23E9 }, ["fax machine"]={ 0x1F4E0 }, ["fearful face"]={ 0x1F628 }, - ["female sign"]={ 0x2640 }, + ["female sign"]={ 0x2640, 0xFE0F }, ["ferris wheel"]={ 0x1F3A1 }, - ["ferry"]={ 0x26F4 }, + ["ferry"]={ 0x26F4, 0xFE0F }, ["field hockey"]={ 0x1F3D1 }, - ["fiji"]={ 0x1F1EB, 0x1F1EF }, - ["file cabinet"]={ 0x1F5C4 }, + ["file cabinet"]={ 0x1F5C4, 0xFE0F }, ["file folder"]={ 0x1F4C1 }, - ["film frames"]={ 0x1F39E }, - ["film projector"]={ 0x1F4FD }, - ["finland"]={ 0x1F1EB, 0x1F1EE }, + ["film frames"]={ 0x1F39E, 0xFE0F }, + ["film projector"]={ 0x1F4FD, 0xFE0F }, ["fire"]={ 0x1F525 }, ["fire engine"]={ 0x1F692 }, + ["fire extinguisher"]={ 0x1F9EF }, + ["firecracker"]={ 0x1F9E8 }, ["fireworks"]={ 0x1F386 }, ["first quarter moon"]={ 0x1F313 }, - ["first quarter moon with face"]={ 0x1F31B }, + ["first quarter moon face"]={ 0x1F31B }, ["fish"]={ 0x1F41F }, ["fish cake with swirl"]={ 0x1F365 }, ["fishing pole"]={ 0x1F3A3 }, ["five o’clock"]={ 0x1F554 }, ["five-thirty"]={ 0x1F560 }, ["flag in hole"]={ 0x26F3 }, + ["flag: afghanistan"]={ 0x1F1E6, 0x1F1EB }, + ["flag: albania"]={ 0x1F1E6, 0x1F1F1 }, + ["flag: algeria"]={ 0x1F1E9, 0x1F1FF }, + ["flag: american samoa"]={ 0x1F1E6, 0x1F1F8 }, + ["flag: andorra"]={ 0x1F1E6, 0x1F1E9 }, + ["flag: angola"]={ 0x1F1E6, 0x1F1F4 }, + ["flag: anguilla"]={ 0x1F1E6, 0x1F1EE }, + ["flag: antarctica"]={ 0x1F1E6, 0x1F1F6 }, + ["flag: antigua & barbuda"]={ 0x1F1E6, 0x1F1EC }, + ["flag: argentina"]={ 0x1F1E6, 0x1F1F7 }, + ["flag: armenia"]={ 0x1F1E6, 0x1F1F2 }, + ["flag: aruba"]={ 0x1F1E6, 0x1F1FC }, + ["flag: ascension island"]={ 0x1F1E6, 0x1F1E8 }, + ["flag: australia"]={ 0x1F1E6, 0x1F1FA }, + ["flag: austria"]={ 0x1F1E6, 0x1F1F9 }, + ["flag: azerbaijan"]={ 0x1F1E6, 0x1F1FF }, + ["flag: bahamas"]={ 0x1F1E7, 0x1F1F8 }, + ["flag: bahrain"]={ 0x1F1E7, 0x1F1ED }, + ["flag: bangladesh"]={ 0x1F1E7, 0x1F1E9 }, + ["flag: barbados"]={ 0x1F1E7, 0x1F1E7 }, + ["flag: belarus"]={ 0x1F1E7, 0x1F1FE }, + ["flag: belgium"]={ 0x1F1E7, 0x1F1EA }, + ["flag: belize"]={ 0x1F1E7, 0x1F1FF }, + ["flag: benin"]={ 0x1F1E7, 0x1F1EF }, + ["flag: bermuda"]={ 0x1F1E7, 0x1F1F2 }, + ["flag: bhutan"]={ 0x1F1E7, 0x1F1F9 }, + ["flag: bolivia"]={ 0x1F1E7, 0x1F1F4 }, + ["flag: bosnia & herzegovina"]={ 0x1F1E7, 0x1F1E6 }, + ["flag: botswana"]={ 0x1F1E7, 0x1F1FC }, + ["flag: bouvet island"]={ 0x1F1E7, 0x1F1FB }, + ["flag: brazil"]={ 0x1F1E7, 0x1F1F7 }, + ["flag: british indian ocean territory"]={ 0x1F1EE, 0x1F1F4 }, + ["flag: british virgin islands"]={ 0x1F1FB, 0x1F1EC }, + ["flag: brunei"]={ 0x1F1E7, 0x1F1F3 }, + ["flag: bulgaria"]={ 0x1F1E7, 0x1F1EC }, + ["flag: burkina faso"]={ 0x1F1E7, 0x1F1EB }, + ["flag: burundi"]={ 0x1F1E7, 0x1F1EE }, + ["flag: cambodia"]={ 0x1F1F0, 0x1F1ED }, + ["flag: cameroon"]={ 0x1F1E8, 0x1F1F2 }, + ["flag: canada"]={ 0x1F1E8, 0x1F1E6 }, + ["flag: canary islands"]={ 0x1F1EE, 0x1F1E8 }, + ["flag: cape verde"]={ 0x1F1E8, 0x1F1FB }, + ["flag: caribbean netherlands"]={ 0x1F1E7, 0x1F1F6 }, + ["flag: cayman islands"]={ 0x1F1F0, 0x1F1FE }, + ["flag: central african republic"]={ 0x1F1E8, 0x1F1EB }, + ["flag: ceuta & melilla"]={ 0x1F1EA, 0x1F1E6 }, + ["flag: chad"]={ 0x1F1F9, 0x1F1E9 }, + ["flag: chile"]={ 0x1F1E8, 0x1F1F1 }, + ["flag: china"]={ 0x1F1E8, 0x1F1F3 }, + ["flag: christmas island"]={ 0x1F1E8, 0x1F1FD }, + ["flag: clipperton island"]={ 0x1F1E8, 0x1F1F5 }, + ["flag: cocos (keeling) islands"]={ 0x1F1E8, 0x1F1E8 }, + ["flag: colombia"]={ 0x1F1E8, 0x1F1F4 }, + ["flag: comoros"]={ 0x1F1F0, 0x1F1F2 }, + ["flag: congo - brazzaville"]={ 0x1F1E8, 0x1F1EC }, + ["flag: congo - kinshasa"]={ 0x1F1E8, 0x1F1E9 }, + ["flag: cook islands"]={ 0x1F1E8, 0x1F1F0 }, + ["flag: costa rica"]={ 0x1F1E8, 0x1F1F7 }, + ["flag: croatia"]={ 0x1F1ED, 0x1F1F7 }, + ["flag: cuba"]={ 0x1F1E8, 0x1F1FA }, + ["flag: curaçao"]={ 0x1F1E8, 0x1F1FC }, + ["flag: cyprus"]={ 0x1F1E8, 0x1F1FE }, + ["flag: czechia"]={ 0x1F1E8, 0x1F1FF }, + ["flag: côte d’ivoire"]={ 0x1F1E8, 0x1F1EE }, + ["flag: denmark"]={ 0x1F1E9, 0x1F1F0 }, + ["flag: diego garcia"]={ 0x1F1E9, 0x1F1EC }, + ["flag: djibouti"]={ 0x1F1E9, 0x1F1EF }, + ["flag: dominica"]={ 0x1F1E9, 0x1F1F2 }, + ["flag: dominican republic"]={ 0x1F1E9, 0x1F1F4 }, + ["flag: ecuador"]={ 0x1F1EA, 0x1F1E8 }, + ["flag: egypt"]={ 0x1F1EA, 0x1F1EC }, + ["flag: el salvador"]={ 0x1F1F8, 0x1F1FB }, + ["flag: england"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0065, 0xE006E, 0xE0067, 0xE007F }, + ["flag: equatorial guinea"]={ 0x1F1EC, 0x1F1F6 }, + ["flag: eritrea"]={ 0x1F1EA, 0x1F1F7 }, + ["flag: estonia"]={ 0x1F1EA, 0x1F1EA }, + ["flag: eswatini"]={ 0x1F1F8, 0x1F1FF }, + ["flag: ethiopia"]={ 0x1F1EA, 0x1F1F9 }, + ["flag: european union"]={ 0x1F1EA, 0x1F1FA }, + ["flag: falkland islands"]={ 0x1F1EB, 0x1F1F0 }, + ["flag: faroe islands"]={ 0x1F1EB, 0x1F1F4 }, + ["flag: fiji"]={ 0x1F1EB, 0x1F1EF }, + ["flag: finland"]={ 0x1F1EB, 0x1F1EE }, + ["flag: france"]={ 0x1F1EB, 0x1F1F7 }, + ["flag: french guiana"]={ 0x1F1EC, 0x1F1EB }, + ["flag: french polynesia"]={ 0x1F1F5, 0x1F1EB }, + ["flag: french southern territories"]={ 0x1F1F9, 0x1F1EB }, + ["flag: gabon"]={ 0x1F1EC, 0x1F1E6 }, + ["flag: gambia"]={ 0x1F1EC, 0x1F1F2 }, + ["flag: georgia"]={ 0x1F1EC, 0x1F1EA }, + ["flag: germany"]={ 0x1F1E9, 0x1F1EA }, + ["flag: ghana"]={ 0x1F1EC, 0x1F1ED }, + ["flag: gibraltar"]={ 0x1F1EC, 0x1F1EE }, + ["flag: greece"]={ 0x1F1EC, 0x1F1F7 }, + ["flag: greenland"]={ 0x1F1EC, 0x1F1F1 }, + ["flag: grenada"]={ 0x1F1EC, 0x1F1E9 }, + ["flag: guadeloupe"]={ 0x1F1EC, 0x1F1F5 }, + ["flag: guam"]={ 0x1F1EC, 0x1F1FA }, + ["flag: guatemala"]={ 0x1F1EC, 0x1F1F9 }, + ["flag: guernsey"]={ 0x1F1EC, 0x1F1EC }, + ["flag: guinea"]={ 0x1F1EC, 0x1F1F3 }, + ["flag: guinea-bissau"]={ 0x1F1EC, 0x1F1FC }, + ["flag: guyana"]={ 0x1F1EC, 0x1F1FE }, + ["flag: haiti"]={ 0x1F1ED, 0x1F1F9 }, + ["flag: heard & mcdonald islands"]={ 0x1F1ED, 0x1F1F2 }, + ["flag: honduras"]={ 0x1F1ED, 0x1F1F3 }, + ["flag: hong kong sar china"]={ 0x1F1ED, 0x1F1F0 }, + ["flag: hungary"]={ 0x1F1ED, 0x1F1FA }, + ["flag: iceland"]={ 0x1F1EE, 0x1F1F8 }, + ["flag: india"]={ 0x1F1EE, 0x1F1F3 }, + ["flag: indonesia"]={ 0x1F1EE, 0x1F1E9 }, + ["flag: iran"]={ 0x1F1EE, 0x1F1F7 }, + ["flag: iraq"]={ 0x1F1EE, 0x1F1F6 }, + ["flag: ireland"]={ 0x1F1EE, 0x1F1EA }, + ["flag: isle of man"]={ 0x1F1EE, 0x1F1F2 }, + ["flag: israel"]={ 0x1F1EE, 0x1F1F1 }, + ["flag: italy"]={ 0x1F1EE, 0x1F1F9 }, + ["flag: jamaica"]={ 0x1F1EF, 0x1F1F2 }, + ["flag: japan"]={ 0x1F1EF, 0x1F1F5 }, + ["flag: jersey"]={ 0x1F1EF, 0x1F1EA }, + ["flag: jordan"]={ 0x1F1EF, 0x1F1F4 }, + ["flag: kazakhstan"]={ 0x1F1F0, 0x1F1FF }, + ["flag: kenya"]={ 0x1F1F0, 0x1F1EA }, + ["flag: kiribati"]={ 0x1F1F0, 0x1F1EE }, + ["flag: kosovo"]={ 0x1F1FD, 0x1F1F0 }, + ["flag: kuwait"]={ 0x1F1F0, 0x1F1FC }, + ["flag: kyrgyzstan"]={ 0x1F1F0, 0x1F1EC }, + ["flag: laos"]={ 0x1F1F1, 0x1F1E6 }, + ["flag: latvia"]={ 0x1F1F1, 0x1F1FB }, + ["flag: lebanon"]={ 0x1F1F1, 0x1F1E7 }, + ["flag: lesotho"]={ 0x1F1F1, 0x1F1F8 }, + ["flag: liberia"]={ 0x1F1F1, 0x1F1F7 }, + ["flag: libya"]={ 0x1F1F1, 0x1F1FE }, + ["flag: liechtenstein"]={ 0x1F1F1, 0x1F1EE }, + ["flag: lithuania"]={ 0x1F1F1, 0x1F1F9 }, + ["flag: luxembourg"]={ 0x1F1F1, 0x1F1FA }, + ["flag: macao sar china"]={ 0x1F1F2, 0x1F1F4 }, + ["flag: macedonia"]={ 0x1F1F2, 0x1F1F0 }, + ["flag: madagascar"]={ 0x1F1F2, 0x1F1EC }, + ["flag: malawi"]={ 0x1F1F2, 0x1F1FC }, + ["flag: malaysia"]={ 0x1F1F2, 0x1F1FE }, + ["flag: maldives"]={ 0x1F1F2, 0x1F1FB }, + ["flag: mali"]={ 0x1F1F2, 0x1F1F1 }, + ["flag: malta"]={ 0x1F1F2, 0x1F1F9 }, + ["flag: marshall islands"]={ 0x1F1F2, 0x1F1ED }, + ["flag: martinique"]={ 0x1F1F2, 0x1F1F6 }, + ["flag: mauritania"]={ 0x1F1F2, 0x1F1F7 }, + ["flag: mauritius"]={ 0x1F1F2, 0x1F1FA }, + ["flag: mayotte"]={ 0x1F1FE, 0x1F1F9 }, + ["flag: mexico"]={ 0x1F1F2, 0x1F1FD }, + ["flag: micronesia"]={ 0x1F1EB, 0x1F1F2 }, + ["flag: moldova"]={ 0x1F1F2, 0x1F1E9 }, + ["flag: monaco"]={ 0x1F1F2, 0x1F1E8 }, + ["flag: mongolia"]={ 0x1F1F2, 0x1F1F3 }, + ["flag: montenegro"]={ 0x1F1F2, 0x1F1EA }, + ["flag: montserrat"]={ 0x1F1F2, 0x1F1F8 }, + ["flag: morocco"]={ 0x1F1F2, 0x1F1E6 }, + ["flag: mozambique"]={ 0x1F1F2, 0x1F1FF }, + ["flag: myanmar (burma)"]={ 0x1F1F2, 0x1F1F2 }, + ["flag: namibia"]={ 0x1F1F3, 0x1F1E6 }, + ["flag: nauru"]={ 0x1F1F3, 0x1F1F7 }, + ["flag: nepal"]={ 0x1F1F3, 0x1F1F5 }, + ["flag: netherlands"]={ 0x1F1F3, 0x1F1F1 }, + ["flag: new caledonia"]={ 0x1F1F3, 0x1F1E8 }, + ["flag: new zealand"]={ 0x1F1F3, 0x1F1FF }, + ["flag: nicaragua"]={ 0x1F1F3, 0x1F1EE }, + ["flag: niger"]={ 0x1F1F3, 0x1F1EA }, + ["flag: nigeria"]={ 0x1F1F3, 0x1F1EC }, + ["flag: niue"]={ 0x1F1F3, 0x1F1FA }, + ["flag: norfolk island"]={ 0x1F1F3, 0x1F1EB }, + ["flag: north korea"]={ 0x1F1F0, 0x1F1F5 }, + ["flag: northern mariana islands"]={ 0x1F1F2, 0x1F1F5 }, + ["flag: norway"]={ 0x1F1F3, 0x1F1F4 }, + ["flag: oman"]={ 0x1F1F4, 0x1F1F2 }, + ["flag: pakistan"]={ 0x1F1F5, 0x1F1F0 }, + ["flag: palau"]={ 0x1F1F5, 0x1F1FC }, + ["flag: palestinian territories"]={ 0x1F1F5, 0x1F1F8 }, + ["flag: panama"]={ 0x1F1F5, 0x1F1E6 }, + ["flag: papua new guinea"]={ 0x1F1F5, 0x1F1EC }, + ["flag: paraguay"]={ 0x1F1F5, 0x1F1FE }, + ["flag: peru"]={ 0x1F1F5, 0x1F1EA }, + ["flag: philippines"]={ 0x1F1F5, 0x1F1ED }, + ["flag: pitcairn islands"]={ 0x1F1F5, 0x1F1F3 }, + ["flag: poland"]={ 0x1F1F5, 0x1F1F1 }, + ["flag: portugal"]={ 0x1F1F5, 0x1F1F9 }, + ["flag: puerto rico"]={ 0x1F1F5, 0x1F1F7 }, + ["flag: qatar"]={ 0x1F1F6, 0x1F1E6 }, + ["flag: romania"]={ 0x1F1F7, 0x1F1F4 }, + ["flag: russia"]={ 0x1F1F7, 0x1F1FA }, + ["flag: rwanda"]={ 0x1F1F7, 0x1F1FC }, + ["flag: réunion"]={ 0x1F1F7, 0x1F1EA }, + ["flag: samoa"]={ 0x1F1FC, 0x1F1F8 }, + ["flag: san marino"]={ 0x1F1F8, 0x1F1F2 }, + ["flag: saudi arabia"]={ 0x1F1F8, 0x1F1E6 }, + ["flag: scotland"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0073, 0xE0063, 0xE0074, 0xE007F }, + ["flag: senegal"]={ 0x1F1F8, 0x1F1F3 }, + ["flag: serbia"]={ 0x1F1F7, 0x1F1F8 }, + ["flag: seychelles"]={ 0x1F1F8, 0x1F1E8 }, + ["flag: sierra leone"]={ 0x1F1F8, 0x1F1F1 }, + ["flag: singapore"]={ 0x1F1F8, 0x1F1EC }, + ["flag: sint maarten"]={ 0x1F1F8, 0x1F1FD }, + ["flag: slovakia"]={ 0x1F1F8, 0x1F1F0 }, + ["flag: slovenia"]={ 0x1F1F8, 0x1F1EE }, + ["flag: solomon islands"]={ 0x1F1F8, 0x1F1E7 }, + ["flag: somalia"]={ 0x1F1F8, 0x1F1F4 }, + ["flag: south africa"]={ 0x1F1FF, 0x1F1E6 }, + ["flag: south georgia & south sandwich islands"]={ 0x1F1EC, 0x1F1F8 }, + ["flag: south korea"]={ 0x1F1F0, 0x1F1F7 }, + ["flag: south sudan"]={ 0x1F1F8, 0x1F1F8 }, + ["flag: spain"]={ 0x1F1EA, 0x1F1F8 }, + ["flag: sri lanka"]={ 0x1F1F1, 0x1F1F0 }, + ["flag: st. barthélemy"]={ 0x1F1E7, 0x1F1F1 }, + ["flag: st. helena"]={ 0x1F1F8, 0x1F1ED }, + ["flag: st. kitts & nevis"]={ 0x1F1F0, 0x1F1F3 }, + ["flag: st. lucia"]={ 0x1F1F1, 0x1F1E8 }, + ["flag: st. martin"]={ 0x1F1F2, 0x1F1EB }, + ["flag: st. pierre & miquelon"]={ 0x1F1F5, 0x1F1F2 }, + ["flag: st. vincent & grenadines"]={ 0x1F1FB, 0x1F1E8 }, + ["flag: sudan"]={ 0x1F1F8, 0x1F1E9 }, + ["flag: suriname"]={ 0x1F1F8, 0x1F1F7 }, + ["flag: svalbard & jan mayen"]={ 0x1F1F8, 0x1F1EF }, + ["flag: sweden"]={ 0x1F1F8, 0x1F1EA }, + ["flag: switzerland"]={ 0x1F1E8, 0x1F1ED }, + ["flag: syria"]={ 0x1F1F8, 0x1F1FE }, + ["flag: são tomé & príncipe"]={ 0x1F1F8, 0x1F1F9 }, + ["flag: taiwan"]={ 0x1F1F9, 0x1F1FC }, + ["flag: tajikistan"]={ 0x1F1F9, 0x1F1EF }, + ["flag: tanzania"]={ 0x1F1F9, 0x1F1FF }, + ["flag: thailand"]={ 0x1F1F9, 0x1F1ED }, + ["flag: timor-leste"]={ 0x1F1F9, 0x1F1F1 }, + ["flag: togo"]={ 0x1F1F9, 0x1F1EC }, + ["flag: tokelau"]={ 0x1F1F9, 0x1F1F0 }, + ["flag: tonga"]={ 0x1F1F9, 0x1F1F4 }, + ["flag: trinidad & tobago"]={ 0x1F1F9, 0x1F1F9 }, + ["flag: tristan da cunha"]={ 0x1F1F9, 0x1F1E6 }, + ["flag: tunisia"]={ 0x1F1F9, 0x1F1F3 }, + ["flag: turkey"]={ 0x1F1F9, 0x1F1F7 }, + ["flag: turkmenistan"]={ 0x1F1F9, 0x1F1F2 }, + ["flag: turks & caicos islands"]={ 0x1F1F9, 0x1F1E8 }, + ["flag: tuvalu"]={ 0x1F1F9, 0x1F1FB }, + ["flag: u.s. outlying islands"]={ 0x1F1FA, 0x1F1F2 }, + ["flag: u.s. virgin islands"]={ 0x1F1FB, 0x1F1EE }, + ["flag: uganda"]={ 0x1F1FA, 0x1F1EC }, + ["flag: ukraine"]={ 0x1F1FA, 0x1F1E6 }, + ["flag: united arab emirates"]={ 0x1F1E6, 0x1F1EA }, + ["flag: united kingdom"]={ 0x1F1EC, 0x1F1E7 }, + ["flag: united nations"]={ 0x1F1FA, 0x1F1F3 }, + ["flag: united states"]={ 0x1F1FA, 0x1F1F8 }, + ["flag: uruguay"]={ 0x1F1FA, 0x1F1FE }, + ["flag: uzbekistan"]={ 0x1F1FA, 0x1F1FF }, + ["flag: vanuatu"]={ 0x1F1FB, 0x1F1FA }, + ["flag: vatican city"]={ 0x1F1FB, 0x1F1E6 }, + ["flag: venezuela"]={ 0x1F1FB, 0x1F1EA }, + ["flag: vietnam"]={ 0x1F1FB, 0x1F1F3 }, + ["flag: wales"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0077, 0xE006C, 0xE0073, 0xE007F }, + ["flag: wallis & futuna"]={ 0x1F1FC, 0x1F1EB }, + ["flag: western sahara"]={ 0x1F1EA, 0x1F1ED }, + ["flag: yemen"]={ 0x1F1FE, 0x1F1EA }, + ["flag: zambia"]={ 0x1F1FF, 0x1F1F2 }, + ["flag: zimbabwe"]={ 0x1F1FF, 0x1F1FC }, + ["flag: Åland islands"]={ 0x1F1E6, 0x1F1FD }, + ["flamingo"]={ 0x1F9A9 }, ["flashlight"]={ 0x1F526 }, - ["fleur-de-lis"]={ 0x269C }, + ["flat shoe"]={ 0x1F97F }, + ["fleur-de-lis"]={ 0x269C, 0xFE0F }, ["flexed biceps"]={ 0x1F4AA }, ["flexed biceps: dark skin tone"]={ 0x1F4AA, 0x1F3FF }, ["flexed biceps: light skin tone"]={ 0x1F4AA, 0x1F3FB }, @@ -613,8 +821,9 @@ return { ["floppy disk"]={ 0x1F4BE }, ["flower playing cards"]={ 0x1F3B4 }, ["flushed face"]={ 0x1F633 }, + ["flying disc"]={ 0x1F94F }, ["flying saucer"]={ 0x1F6F8 }, - ["fog"]={ 0x1F32B }, + ["fog"]={ 0x1F32B, 0xFE0F }, ["foggy"]={ 0x1F301 }, ["folded hands"]={ 0x1F64F }, ["folded hands: dark skin tone"]={ 0x1F64F, 0x1F3FF }, @@ -622,44 +831,41 @@ return { ["folded hands: medium skin tone"]={ 0x1F64F, 0x1F3FD }, ["folded hands: medium-dark skin tone"]={ 0x1F64F, 0x1F3FE }, ["folded hands: medium-light skin tone"]={ 0x1F64F, 0x1F3FC }, + ["foot"]={ 0x1F9B6 }, + ["foot: dark skin tone"]={ 0x1F9B6, 0x1F3FF }, + ["foot: light skin tone"]={ 0x1F9B6, 0x1F3FB }, + ["foot: medium skin tone"]={ 0x1F9B6, 0x1F3FD }, + ["foot: medium-dark skin tone"]={ 0x1F9B6, 0x1F3FE }, + ["foot: medium-light skin tone"]={ 0x1F9B6, 0x1F3FC }, ["footprints"]={ 0x1F463 }, ["fork and knife"]={ 0x1F374 }, - ["fork and knife with plate"]={ 0x1F37D }, + ["fork and knife with plate"]={ 0x1F37D, 0xFE0F }, ["fortune cookie"]={ 0x1F960 }, ["fountain"]={ 0x26F2 }, - ["fountain pen"]={ 0x1F58B }, + ["fountain pen"]={ 0x1F58B, 0xFE0F }, ["four leaf clover"]={ 0x1F340 }, ["four o’clock"]={ 0x1F553 }, ["four-thirty"]={ 0x1F55F }, - ["fox face"]={ 0x1F98A }, - ["framed picture"]={ 0x1F5BC }, - ["france"]={ 0x1F1EB, 0x1F1F7 }, + ["fox"]={ 0x1F98A }, + ["framed picture"]={ 0x1F5BC, 0xFE0F }, ["free button"]={ 0x1F193 }, ["french fries"]={ 0x1F35F }, - ["french guiana"]={ 0x1F1EC, 0x1F1EB }, - ["french polynesia"]={ 0x1F1F5, 0x1F1EB }, - ["french southern territories"]={ 0x1F1F9, 0x1F1EB }, ["fried shrimp"]={ 0x1F364 }, - ["frog face"]={ 0x1F438 }, + ["frog"]={ 0x1F438 }, ["front-facing baby chick"]={ 0x1F425 }, - ["frowning face"]={ 0x2639 }, + ["frowning face"]={ 0x2639, 0xFE0F }, ["frowning face with open mouth"]={ 0x1F626 }, ["fuel pump"]={ 0x26FD }, ["full moon"]={ 0x1F315 }, - ["full moon with face"]={ 0x1F31D }, - ["funeral urn"]={ 0x26B1 }, - ["gabon"]={ 0x1F1EC, 0x1F1E6 }, - ["gambia"]={ 0x1F1EC, 0x1F1F2 }, + ["full moon face"]={ 0x1F31D }, + ["funeral urn"]={ 0x26B1, 0xFE0F }, ["game die"]={ 0x1F3B2 }, - ["gear"]={ 0x2699 }, + ["garlic"]={ 0x1F9C4 }, + ["gear"]={ 0x2699, 0xFE0F }, ["gem stone"]={ 0x1F48E }, ["gemini"]={ 0x264A }, ["genie"]={ 0x1F9DE }, - ["georgia"]={ 0x1F1EC, 0x1F1EA }, - ["germany"]={ 0x1F1E9, 0x1F1EA }, - ["ghana"]={ 0x1F1EC, 0x1F1ED }, ["ghost"]={ 0x1F47B }, - ["gibraltar"]={ 0x1F1EC, 0x1F1EE }, ["giraffe"]={ 0x1F992 }, ["girl"]={ 0x1F467 }, ["girl: dark skin tone"]={ 0x1F467, 0x1F3FF }, @@ -678,59 +884,55 @@ return { ["goal net"]={ 0x1F945 }, ["goat"]={ 0x1F410 }, ["goblin"]={ 0x1F47A }, + ["goggles"]={ 0x1F97D }, ["gorilla"]={ 0x1F98D }, ["graduation cap"]={ 0x1F393 }, ["grapes"]={ 0x1F347 }, - ["greece"]={ 0x1F1EC, 0x1F1F7 }, ["green apple"]={ 0x1F34F }, ["green book"]={ 0x1F4D7 }, + ["green circle"]={ 0x1F7E2 }, ["green heart"]={ 0x1F49A }, ["green salad"]={ 0x1F957 }, - ["greenland"]={ 0x1F1EC, 0x1F1F1 }, - ["grenada"]={ 0x1F1EC, 0x1F1E9 }, + ["green square"]={ 0x1F7E9 }, ["grimacing face"]={ 0x1F62C }, - ["grinning cat face with smiling eyes"]={ 0x1F638 }, + ["grinning cat"]={ 0x1F63A }, + ["grinning cat with smiling eyes"]={ 0x1F638 }, ["grinning face"]={ 0x1F600 }, - ["grinning face with smiling eyes"]={ 0x1F601 }, + ["grinning face with big eyes"]={ 0x1F603 }, + ["grinning face with smiling eyes"]={ 0x1F604 }, + ["grinning face with sweat"]={ 0x1F605 }, + ["grinning squinting face"]={ 0x1F606 }, ["growing heart"]={ 0x1F497 }, - ["guadeloupe"]={ 0x1F1EC, 0x1F1F5 }, - ["guam"]={ 0x1F1EC, 0x1F1FA }, ["guard"]={ 0x1F482 }, ["guard: dark skin tone"]={ 0x1F482, 0x1F3FF }, ["guard: light skin tone"]={ 0x1F482, 0x1F3FB }, ["guard: medium skin tone"]={ 0x1F482, 0x1F3FD }, ["guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE }, ["guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC }, - ["guatemala"]={ 0x1F1EC, 0x1F1F9 }, - ["guernsey"]={ 0x1F1EC, 0x1F1EC }, - ["guinea"]={ 0x1F1EC, 0x1F1F3 }, - ["guinea-bissau"]={ 0x1F1EC, 0x1F1FC }, + ["guide dog"]={ 0x1F9AE }, ["guitar"]={ 0x1F3B8 }, - ["guyana"]={ 0x1F1EC, 0x1F1FE }, - ["haiti"]={ 0x1F1ED, 0x1F1F9 }, ["hamburger"]={ 0x1F354 }, ["hammer"]={ 0x1F528 }, - ["hammer and pick"]={ 0x2692 }, - ["hammer and wrench"]={ 0x1F6E0 }, - ["hamster face"]={ 0x1F439 }, + ["hammer and pick"]={ 0x2692, 0xFE0F }, + ["hammer and wrench"]={ 0x1F6E0, 0xFE0F }, + ["hamster"]={ 0x1F439 }, + ["hand with fingers splayed"]={ 0x1F590, 0xFE0F }, + ["hand with fingers splayed: dark skin tone"]={ 0x1F590, 0x1F3FF }, + ["hand with fingers splayed: light skin tone"]={ 0x1F590, 0x1F3FB }, + ["hand with fingers splayed: medium skin tone"]={ 0x1F590, 0x1F3FD }, + ["hand with fingers splayed: medium-dark skin tone"]={ 0x1F590, 0x1F3FE }, + ["hand with fingers splayed: medium-light skin tone"]={ 0x1F590, 0x1F3FC }, ["handbag"]={ 0x1F45C }, ["handshake"]={ 0x1F91D }, ["hatching chick"]={ 0x1F423 }, ["headphone"]={ 0x1F3A7 }, ["hear-no-evil monkey"]={ 0x1F649 }, - ["heard & mcdonald islands"]={ 0x1F1ED, 0x1F1F2 }, ["heart decoration"]={ 0x1F49F }, - ["heart suit"]={ 0x2665 }, + ["heart exclamation"]={ 0x2763, 0xFE0F }, + ["heart suit"]={ 0x2665, 0xFE0F }, ["heart with arrow"]={ 0x1F498 }, ["heart with ribbon"]={ 0x1F49D }, - ["heavy check mark"]={ 0x2714 }, - ["heavy division sign"]={ 0x2797 }, ["heavy dollar sign"]={ 0x1F4B2 }, - ["heavy heart exclamation"]={ 0x2763 }, - ["heavy large circle"]={ 0x2B55 }, - ["heavy minus sign"]={ 0x2796 }, - ["heavy multiplication x"]={ 0x2716 }, - ["heavy plus sign"]={ 0x2795 }, ["hedgehog"]={ 0x1F994 }, ["helicopter"]={ 0x1F681 }, ["herb"]={ 0x1F33F }, @@ -738,12 +940,13 @@ return { ["high voltage"]={ 0x26A1 }, ["high-heeled shoe"]={ 0x1F460 }, ["high-speed train"]={ 0x1F684 }, - ["high-speed train with bullet nose"]={ 0x1F685 }, - ["hole"]={ 0x1F573 }, - ["honduras"]={ 0x1F1ED, 0x1F1F3 }, + ["hiking boot"]={ 0x1F97E }, + ["hindu temple"]={ 0x1F6D5 }, + ["hippopotamus"]={ 0x1F99B }, + ["hole"]={ 0x1F573, 0xFE0F }, + ["hollow red circle"]={ 0x2B55 }, ["honey pot"]={ 0x1F36F }, ["honeybee"]={ 0x1F41D }, - ["hong kong sar china"]={ 0x1F1ED, 0x1F1F0 }, ["horizontal traffic light"]={ 0x1F6A5 }, ["horse"]={ 0x1F40E }, ["horse face"]={ 0x1F434 }, @@ -756,47 +959,39 @@ return { ["hospital"]={ 0x1F3E5 }, ["hot beverage"]={ 0x2615 }, ["hot dog"]={ 0x1F32D }, - ["hot pepper"]={ 0x1F336 }, - ["hot springs"]={ 0x2668 }, + ["hot face"]={ 0x1F975 }, + ["hot pepper"]={ 0x1F336, 0xFE0F }, + ["hot springs"]={ 0x2668, 0xFE0F }, ["hotel"]={ 0x1F3E8 }, - ["hourglass"]={ 0x231B }, - ["hourglass with flowing sand"]={ 0x23F3 }, + ["hourglass done"]={ 0x231B }, + ["hourglass not done"]={ 0x23F3 }, ["house"]={ 0x1F3E0 }, ["house with garden"]={ 0x1F3E1 }, + ["houses"]={ 0x1F3D8, 0xFE0F }, ["hugging face"]={ 0x1F917 }, ["hundred points"]={ 0x1F4AF }, - ["hungary"]={ 0x1F1ED, 0x1F1FA }, ["hushed face"]={ 0x1F62F }, ["ice cream"]={ 0x1F368 }, + ["ice cube"]={ 0x1F9CA }, ["ice hockey"]={ 0x1F3D2 }, - ["ice skate"]={ 0x26F8 }, - ["iceland"]={ 0x1F1EE, 0x1F1F8 }, + ["ice skate"]={ 0x26F8, 0xFE0F }, ["id button"]={ 0x1F194 }, ["inbox tray"]={ 0x1F4E5 }, ["incoming envelope"]={ 0x1F4E8 }, - ["index pointing up"]={ 0x261D }, + ["index pointing up"]={ 0x261D, 0xFE0F }, ["index pointing up: dark skin tone"]={ 0x261D, 0x1F3FF }, ["index pointing up: light skin tone"]={ 0x261D, 0x1F3FB }, ["index pointing up: medium skin tone"]={ 0x261D, 0x1F3FD }, ["index pointing up: medium-dark skin tone"]={ 0x261D, 0x1F3FE }, ["index pointing up: medium-light skin tone"]={ 0x261D, 0x1F3FC }, - ["india"]={ 0x1F1EE, 0x1F1F3 }, - ["indonesia"]={ 0x1F1EE, 0x1F1E9 }, - ["information"]={ 0x2139 }, + ["infinity"]={ 0x267E, 0xFE0F }, + ["information"]={ 0x2139, 0xFE0F }, ["input latin letters"]={ 0x1F524 }, ["input latin lowercase"]={ 0x1F521 }, ["input latin uppercase"]={ 0x1F520 }, ["input numbers"]={ 0x1F522 }, ["input symbols"]={ 0x1F523 }, - ["iran"]={ 0x1F1EE, 0x1F1F7 }, - ["iraq"]={ 0x1F1EE, 0x1F1F6 }, - ["ireland"]={ 0x1F1EE, 0x1F1EA }, - ["isle of man"]={ 0x1F1EE, 0x1F1F2 }, - ["israel"]={ 0x1F1EE, 0x1F1F1 }, - ["italy"]={ 0x1F1EE, 0x1F1F9 }, ["jack-o-lantern"]={ 0x1F383 }, - ["jamaica"]={ 0x1F1EF, 0x1F1F2 }, - ["japan"]={ 0x1F1EF, 0x1F1F5 }, ["japanese castle"]={ 0x1F3EF }, ["japanese dolls"]={ 0x1F38E }, ["japanese post office"]={ 0x1F3E3 }, @@ -804,110 +999,107 @@ return { ["japanese “acceptable” button"]={ 0x1F251 }, ["japanese “application” button"]={ 0x1F238 }, ["japanese “bargain” button"]={ 0x1F250 }, - ["japanese “congratulations” button"]={ 0x3297 }, + ["japanese “congratulations” button"]={ 0x3297, 0xFE0F }, ["japanese “discount” button"]={ 0x1F239 }, ["japanese “free of charge” button"]={ 0x1F21A }, ["japanese “here” button"]={ 0x1F201 }, - ["japanese “monthly amount” button"]={ 0x1F237 }, + ["japanese “monthly amount” button"]={ 0x1F237, 0xFE0F }, ["japanese “no vacancy” button"]={ 0x1F235 }, ["japanese “not free of charge” button"]={ 0x1F236 }, ["japanese “open for business” button"]={ 0x1F23A }, ["japanese “passing grade” button"]={ 0x1F234 }, ["japanese “prohibited” button"]={ 0x1F232 }, ["japanese “reserved” button"]={ 0x1F22F }, - ["japanese “secret” button"]={ 0x3299 }, - ["japanese “service charge” button"]={ 0x1F202 }, + ["japanese “secret” button"]={ 0x3299, 0xFE0F }, + ["japanese “service charge” button"]={ 0x1F202, 0xFE0F }, ["japanese “vacancy” button"]={ 0x1F233 }, ["jeans"]={ 0x1F456 }, - ["jersey"]={ 0x1F1EF, 0x1F1EA }, ["joker"]={ 0x1F0CF }, - ["jordan"]={ 0x1F1EF, 0x1F1F4 }, - ["joystick"]={ 0x1F579 }, + ["joystick"]={ 0x1F579, 0xFE0F }, ["kaaba"]={ 0x1F54B }, - ["kazakhstan"]={ 0x1F1F0, 0x1F1FF }, - ["kenya"]={ 0x1F1F0, 0x1F1EA }, + ["kangaroo"]={ 0x1F998 }, ["key"]={ 0x1F511 }, - ["keyboard"]={ 0x2328 }, - ["keycap 10"]={ 0x1F51F }, - ["keycap: 0"]={ 0x30, 0x20E3 }, - ["keycap: 1"]={ 0x31, 0x20E3 }, - ["keycap: 2"]={ 0x32, 0x20E3 }, - ["keycap: 3"]={ 0x33, 0x20E3 }, - ["keycap: 4"]={ 0x34, 0x20E3 }, - ["keycap: 5"]={ 0x35, 0x20E3 }, - ["keycap: 6"]={ 0x36, 0x20E3 }, - ["keycap: 7"]={ 0x37, 0x20E3 }, - ["keycap: 8"]={ 0x38, 0x20E3 }, - ["keycap: 9"]={ 0x39, 0x20E3 }, - ["keycap: asterisk"]={ 0x2A, 0x20E3 }, - ["keycap: hash"]={ 0x23, 0x20E3 }, + ["keyboard"]={ 0x2328, 0xFE0F }, + ["keycap: 0"]={ 0x30, 0xFE0F, 0x20E3 }, + ["keycap: 1"]={ 0x31, 0xFE0F, 0x20E3 }, + ["keycap: 10"]={ 0x1F51F }, + ["keycap: 2"]={ 0x32, 0xFE0F, 0x20E3 }, + ["keycap: 3"]={ 0x33, 0xFE0F, 0x20E3 }, + ["keycap: 4"]={ 0x34, 0xFE0F, 0x20E3 }, + ["keycap: 5"]={ 0x35, 0xFE0F, 0x20E3 }, + ["keycap: 6"]={ 0x36, 0xFE0F, 0x20E3 }, + ["keycap: 7"]={ 0x37, 0xFE0F, 0x20E3 }, + ["keycap: 8"]={ 0x38, 0xFE0F, 0x20E3 }, + ["keycap: 9"]={ 0x39, 0xFE0F, 0x20E3 }, + ["keycap: asterisk"]={ 0x2A, 0xFE0F, 0x20E3 }, + ["keycap: hash"]={ 0x23, 0xFE0F, 0x20E3 }, ["kick scooter"]={ 0x1F6F4 }, ["kimono"]={ 0x1F458 }, - ["kiribati"]={ 0x1F1F0, 0x1F1EE }, ["kiss"]={ 0x1F48F }, ["kiss mark"]={ 0x1F48B }, - ["kiss: man, man"]={ 0x1F468, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468 }, - ["kiss: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F468 }, - ["kiss: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0x200D, 0x1F48B, 0x200D, 0x1F469 }, - ["kissing cat face with closed eyes"]={ 0x1F63D }, + ["kiss: man, man"]={ 0x1F468, 0x200D, 0x2764, 0xFE0F, 0x200D, 0x1F48B, 0x200D, 0x1F468 }, + ["kiss: woman, man"]={ 0x1F469, 0x200D, 0x2764, 0xFE0F, 0x200D, 0x1F48B, 0x200D, 0x1F468 }, + ["kiss: woman, woman"]={ 0x1F469, 0x200D, 0x2764, 0xFE0F, 0x200D, 0x1F48B, 0x200D, 0x1F469 }, + ["kissing cat"]={ 0x1F63D }, ["kissing face"]={ 0x1F617 }, ["kissing face with closed eyes"]={ 0x1F61A }, ["kissing face with smiling eyes"]={ 0x1F619 }, ["kitchen knife"]={ 0x1F52A }, + ["kite"]={ 0x1FA81 }, ["kiwi fruit"]={ 0x1F95D }, ["koala"]={ 0x1F428 }, - ["kosovo"]={ 0x1F1FD, 0x1F1F0 }, - ["kuwait"]={ 0x1F1F0, 0x1F1FC }, - ["kyrgyzstan"]={ 0x1F1F0, 0x1F1EC }, - ["label"]={ 0x1F3F7 }, + ["lab coat"]={ 0x1F97C }, + ["label"]={ 0x1F3F7, 0xFE0F }, + ["lacrosse"]={ 0x1F94D }, ["lady beetle"]={ 0x1F41E }, - ["laos"]={ 0x1F1F1, 0x1F1E6 }, ["laptop computer"]={ 0x1F4BB }, ["large blue diamond"]={ 0x1F537 }, ["large orange diamond"]={ 0x1F536 }, ["last quarter moon"]={ 0x1F317 }, - ["last quarter moon with face"]={ 0x1F31C }, - ["last track button"]={ 0x23EE }, - ["latin cross"]={ 0x271D }, - ["latvia"]={ 0x1F1F1, 0x1F1FB }, + ["last quarter moon face"]={ 0x1F31C }, + ["last track button"]={ 0x23EE, 0xFE0F }, + ["latin cross"]={ 0x271D, 0xFE0F }, ["leaf fluttering in wind"]={ 0x1F343 }, - ["lebanon"]={ 0x1F1F1, 0x1F1E7 }, + ["leafy green"]={ 0x1F96C }, ["ledger"]={ 0x1F4D2 }, - ["left arrow"]={ 0x2B05 }, - ["left arrow curving right"]={ 0x21AA }, + ["left arrow"]={ 0x2B05, 0xFE0F }, + ["left arrow curving right"]={ 0x21AA, 0xFE0F }, ["left luggage"]={ 0x1F6C5 }, - ["left speech bubble"]={ 0x1F5E8 }, + ["left speech bubble"]={ 0x1F5E8, 0xFE0F }, ["left-facing fist"]={ 0x1F91B }, ["left-facing fist: dark skin tone"]={ 0x1F91B, 0x1F3FF }, ["left-facing fist: light skin tone"]={ 0x1F91B, 0x1F3FB }, ["left-facing fist: medium skin tone"]={ 0x1F91B, 0x1F3FD }, ["left-facing fist: medium-dark skin tone"]={ 0x1F91B, 0x1F3FE }, ["left-facing fist: medium-light skin tone"]={ 0x1F91B, 0x1F3FC }, - ["left-pointing magnifying glass"]={ 0x1F50D }, - ["left-right arrow"]={ 0x2194 }, + ["left-right arrow"]={ 0x2194, 0xFE0F }, + ["leg"]={ 0x1F9B5 }, + ["leg: dark skin tone"]={ 0x1F9B5, 0x1F3FF }, + ["leg: light skin tone"]={ 0x1F9B5, 0x1F3FB }, + ["leg: medium skin tone"]={ 0x1F9B5, 0x1F3FD }, + ["leg: medium-dark skin tone"]={ 0x1F9B5, 0x1F3FE }, + ["leg: medium-light skin tone"]={ 0x1F9B5, 0x1F3FC }, ["lemon"]={ 0x1F34B }, ["leo"]={ 0x264C }, ["leopard"]={ 0x1F406 }, - ["lesotho"]={ 0x1F1F1, 0x1F1F8 }, - ["level slider"]={ 0x1F39A }, - ["liberia"]={ 0x1F1F1, 0x1F1F7 }, + ["level slider"]={ 0x1F39A, 0xFE0F }, ["libra"]={ 0x264E }, - ["libya"]={ 0x1F1F1, 0x1F1FE }, - ["liechtenstein"]={ 0x1F1F1, 0x1F1EE }, ["light bulb"]={ 0x1F4A1 }, ["light rail"]={ 0x1F688 }, ["link"]={ 0x1F517 }, - ["linked paperclips"]={ 0x1F587 }, - ["lion face"]={ 0x1F981 }, + ["linked paperclips"]={ 0x1F587, 0xFE0F }, + ["lion"]={ 0x1F981 }, ["lipstick"]={ 0x1F484 }, - ["lithuania"]={ 0x1F1F1, 0x1F1F9 }, ["litter in bin sign"]={ 0x1F6AE }, ["lizard"]={ 0x1F98E }, + ["llama"]={ 0x1F999 }, + ["lobster"]={ 0x1F99E }, ["locked"]={ 0x1F512 }, ["locked with key"]={ 0x1F510 }, ["locked with pen"]={ 0x1F50F }, ["locomotive"]={ 0x1F682 }, ["lollipop"]={ 0x1F36D }, + ["lotion bottle"]={ 0x1F9F4 }, ["loudly crying face"]={ 0x1F62D }, ["loudspeaker"]={ 0x1F4E2 }, ["love hotel"]={ 0x1F3E9 }, @@ -918,26 +1110,20 @@ return { ["love-you gesture: medium skin tone"]={ 0x1F91F, 0x1F3FD }, ["love-you gesture: medium-dark skin tone"]={ 0x1F91F, 0x1F3FE }, ["love-you gesture: medium-light skin tone"]={ 0x1F91F, 0x1F3FC }, - ["luxembourg"]={ 0x1F1F1, 0x1F1FA }, + ["luggage"]={ 0x1F9F3 }, ["lying face"]={ 0x1F925 }, - ["macau sar china"]={ 0x1F1F2, 0x1F1F4 }, - ["macedonia"]={ 0x1F1F2, 0x1F1F0 }, - ["madagascar"]={ 0x1F1F2, 0x1F1EC }, ["mage"]={ 0x1F9D9 }, ["mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF }, ["mage: light skin tone"]={ 0x1F9D9, 0x1F3FB }, ["mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD }, ["mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE }, ["mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC }, + ["magnet"]={ 0x1F9F2 }, + ["magnifying glass tilted left"]={ 0x1F50D }, + ["magnifying glass tilted right"]={ 0x1F50E }, ["mahjong red dragon"]={ 0x1F004 }, - ["malawi"]={ 0x1F1F2, 0x1F1FC }, - ["malaysia"]={ 0x1F1F2, 0x1F1FE }, - ["maldives"]={ 0x1F1F2, 0x1F1FB }, - ["male sign"]={ 0x2642 }, - ["mali"]={ 0x1F1F2, 0x1F1F1 }, - ["malta"]={ 0x1F1F2, 0x1F1F9 }, + ["male sign"]={ 0x2642, 0xFE0F }, ["man"]={ 0x1F468 }, - ["man and woman holding hands"]={ 0x1F46B }, ["man artist"]={ 0x1F468, 0x200D, 0x1F3A8 }, ["man artist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A8 }, ["man artist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3A8 }, @@ -950,42 +1136,42 @@ return { ["man astronaut: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F680 }, ["man astronaut: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F680 }, ["man astronaut: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F680 }, - ["man biking"]={ 0x1F6B4, 0x200D, 0x2642 }, - ["man biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2642 }, - ["man biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2642 }, - ["man biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2642 }, - ["man biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2642 }, - ["man biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2642 }, - ["man bouncing ball"]={ 0x26F9, 0x200D, 0x2642 }, - ["man bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2642 }, - ["man bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2642 }, - ["man bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2642 }, - ["man bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2642 }, - ["man bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2642 }, - ["man bowing"]={ 0x1F647, 0x200D, 0x2642 }, - ["man bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2642 }, - ["man bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2642 }, - ["man bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2642 }, - ["man bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2642 }, - ["man bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2642 }, - ["man cartwheeling"]={ 0x1F938, 0x200D, 0x2642 }, - ["man cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2642 }, - ["man cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2642 }, - ["man cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2642 }, - ["man cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2642 }, - ["man cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2642 }, - ["man climbing"]={ 0x1F9D7, 0x200D, 0x2642 }, - ["man climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2642 }, - ["man climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2642 }, - ["man climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2642 }, - ["man climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2642 }, - ["man climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2642 }, - ["man construction worker"]={ 0x1F477, 0x200D, 0x2642 }, - ["man construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2642 }, - ["man construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2642 }, - ["man construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2642 }, - ["man construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2642 }, - ["man construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2642 }, + ["man biking"]={ 0x1F6B4, 0x200D, 0x2642, 0xFE0F }, + ["man biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man bouncing ball"]={ 0x26F9, 0xFE0F, 0x200D, 0x2642, 0xFE0F }, + ["man bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man bowing"]={ 0x1F647, 0x200D, 0x2642, 0xFE0F }, + ["man bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man cartwheeling"]={ 0x1F938, 0x200D, 0x2642, 0xFE0F }, + ["man cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man climbing"]={ 0x1F9D7, 0x200D, 0x2642, 0xFE0F }, + ["man climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man construction worker"]={ 0x1F477, 0x200D, 0x2642, 0xFE0F }, + ["man construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man cook"]={ 0x1F468, 0x200D, 0x1F373 }, ["man cook: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F373 }, ["man cook: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F373 }, @@ -998,36 +1184,36 @@ return { ["man dancing: medium skin tone"]={ 0x1F57A, 0x1F3FD }, ["man dancing: medium-dark skin tone"]={ 0x1F57A, 0x1F3FE }, ["man dancing: medium-light skin tone"]={ 0x1F57A, 0x1F3FC }, - ["man detective"]={ 0x1F575, 0x200D, 0x2642 }, - ["man detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2642 }, - ["man detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2642 }, - ["man detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2642 }, - ["man detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2642 }, - ["man detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2642 }, - ["man elf"]={ 0x1F9DD, 0x200D, 0x2642 }, - ["man elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2642 }, - ["man elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2642 }, - ["man elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2642 }, - ["man elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2642 }, - ["man elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2642 }, - ["man facepalming"]={ 0x1F926, 0x200D, 0x2642 }, - ["man facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2642 }, - ["man facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2642 }, - ["man facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2642 }, - ["man facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2642 }, - ["man facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2642 }, + ["man detective"]={ 0x1F575, 0xFE0F, 0x200D, 0x2642, 0xFE0F }, + ["man detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man elf"]={ 0x1F9DD, 0x200D, 0x2642, 0xFE0F }, + ["man elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man facepalming"]={ 0x1F926, 0x200D, 0x2642, 0xFE0F }, + ["man facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man factory worker"]={ 0x1F468, 0x200D, 0x1F3ED }, ["man factory worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3ED }, ["man factory worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3ED }, ["man factory worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3ED }, ["man factory worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3ED }, ["man factory worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3ED }, - ["man fairy"]={ 0x1F9DA, 0x200D, 0x2642 }, - ["man fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2642 }, - ["man fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2642 }, - ["man fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2642 }, - ["man fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2642 }, - ["man fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2642 }, + ["man fairy"]={ 0x1F9DA, 0x200D, 0x2642, 0xFE0F }, + ["man fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man farmer"]={ 0x1F468, 0x200D, 0x1F33E }, ["man farmer: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F33E }, ["man farmer: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F33E }, @@ -1040,205 +1226,241 @@ return { ["man firefighter: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F692 }, ["man firefighter: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F692 }, ["man firefighter: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F692 }, - ["man frowning"]={ 0x1F64D, 0x200D, 0x2642 }, - ["man frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2642 }, - ["man frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2642 }, - ["man frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2642 }, - ["man frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2642 }, - ["man frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2642 }, - ["man genie"]={ 0x1F9DE, 0x200D, 0x2642 }, - ["man gesturing no"]={ 0x1F645, 0x200D, 0x2642 }, - ["man gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2642 }, - ["man gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2642 }, - ["man gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2642 }, - ["man gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2642 }, - ["man gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2642 }, - ["man gesturing ok"]={ 0x1F646, 0x200D, 0x2642 }, - ["man gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2642 }, - ["man gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2642 }, - ["man gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2642 }, - ["man gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2642 }, - ["man gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2642 }, - ["man getting haircut"]={ 0x1F487, 0x200D, 0x2642 }, - ["man getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2642 }, - ["man getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2642 }, - ["man getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2642 }, - ["man getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2642 }, - ["man getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2642 }, - ["man getting massage"]={ 0x1F486, 0x200D, 0x2642 }, - ["man getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2642 }, - ["man getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2642 }, - ["man getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2642 }, - ["man getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2642 }, - ["man getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2642 }, - ["man golfing"]={ 0x1F3CC, 0x200D, 0x2642 }, - ["man golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2642 }, - ["man golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2642 }, - ["man golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2642 }, - ["man golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2642 }, - ["man golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2642 }, - ["man guard"]={ 0x1F482, 0x200D, 0x2642 }, - ["man guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2642 }, - ["man guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2642 }, - ["man guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2642 }, - ["man guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2642 }, - ["man guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2642 }, - ["man health worker"]={ 0x1F468, 0x200D, 0x2695 }, - ["man health worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2695 }, - ["man health worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2695 }, - ["man health worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2695 }, - ["man health worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2695 }, - ["man health worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2695 }, - ["man in business suit levitating"]={ 0x1F574 }, - ["man in business suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF }, - ["man in business suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB }, - ["man in business suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD }, - ["man in business suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE }, - ["man in business suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC }, - ["man in lotus position"]={ 0x1F9D8, 0x200D, 0x2642 }, - ["man in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2642 }, - ["man in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2642 }, - ["man in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2642 }, - ["man in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2642 }, - ["man in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2642 }, - ["man in steamy room"]={ 0x1F9D6, 0x200D, 0x2642 }, - ["man in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2642 }, - ["man in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2642 }, - ["man in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2642 }, - ["man in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2642 }, - ["man in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2642 }, + ["man frowning"]={ 0x1F64D, 0x200D, 0x2642, 0xFE0F }, + ["man frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man genie"]={ 0x1F9DE, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing no"]={ 0x1F645, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing ok"]={ 0x1F646, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man getting haircut"]={ 0x1F487, 0x200D, 0x2642, 0xFE0F }, + ["man getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man getting massage"]={ 0x1F486, 0x200D, 0x2642, 0xFE0F }, + ["man getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man golfing"]={ 0x1F3CC, 0xFE0F, 0x200D, 0x2642, 0xFE0F }, + ["man golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man guard"]={ 0x1F482, 0x200D, 0x2642, 0xFE0F }, + ["man guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man health worker"]={ 0x1F468, 0x200D, 0x2695, 0xFE0F }, + ["man health worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2695, 0xFE0F }, + ["man health worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2695, 0xFE0F }, + ["man health worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2695, 0xFE0F }, + ["man health worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2695, 0xFE0F }, + ["man health worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2695, 0xFE0F }, + ["man in lotus position"]={ 0x1F9D8, 0x200D, 0x2642, 0xFE0F }, + ["man in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man in manual wheelchair"]={ 0x1F468, 0x200D, 0x1F9BD }, + ["man in manual wheelchair: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9BD }, + ["man in manual wheelchair: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9BD }, + ["man in manual wheelchair: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9BD }, + ["man in manual wheelchair: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9BD }, + ["man in manual wheelchair: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9BD }, + ["man in motorized wheelchair"]={ 0x1F468, 0x200D, 0x1F9BC }, + ["man in motorized wheelchair: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9BC }, + ["man in motorized wheelchair: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9BC }, + ["man in motorized wheelchair: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9BC }, + ["man in motorized wheelchair: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9BC }, + ["man in motorized wheelchair: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9BC }, + ["man in steamy room"]={ 0x1F9D6, 0x200D, 0x2642, 0xFE0F }, + ["man in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man in suit levitating"]={ 0x1F574, 0xFE0F }, + ["man in suit levitating: dark skin tone"]={ 0x1F574, 0x1F3FF }, + ["man in suit levitating: light skin tone"]={ 0x1F574, 0x1F3FB }, + ["man in suit levitating: medium skin tone"]={ 0x1F574, 0x1F3FD }, + ["man in suit levitating: medium-dark skin tone"]={ 0x1F574, 0x1F3FE }, + ["man in suit levitating: medium-light skin tone"]={ 0x1F574, 0x1F3FC }, ["man in tuxedo"]={ 0x1F935 }, ["man in tuxedo: dark skin tone"]={ 0x1F935, 0x1F3FF }, ["man in tuxedo: light skin tone"]={ 0x1F935, 0x1F3FB }, ["man in tuxedo: medium skin tone"]={ 0x1F935, 0x1F3FD }, ["man in tuxedo: medium-dark skin tone"]={ 0x1F935, 0x1F3FE }, ["man in tuxedo: medium-light skin tone"]={ 0x1F935, 0x1F3FC }, - ["man judge"]={ 0x1F468, 0x200D, 0x2696 }, - ["man judge: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2696 }, - ["man judge: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2696 }, - ["man judge: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2696 }, - ["man judge: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2696 }, - ["man judge: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2696 }, - ["man juggling"]={ 0x1F939, 0x200D, 0x2642 }, - ["man juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2642 }, - ["man juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2642 }, - ["man juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2642 }, - ["man juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2642 }, - ["man juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2642 }, - ["man lifting weights"]={ 0x1F3CB, 0x200D, 0x2642 }, - ["man lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2642 }, - ["man lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2642 }, - ["man lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2642 }, - ["man lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2642 }, - ["man lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2642 }, - ["man mage"]={ 0x1F9D9, 0x200D, 0x2642 }, - ["man mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2642 }, - ["man mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2642 }, - ["man mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2642 }, - ["man mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2642 }, - ["man mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2642 }, + ["man judge"]={ 0x1F468, 0x200D, 0x2696, 0xFE0F }, + ["man judge: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2696, 0xFE0F }, + ["man judge: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2696, 0xFE0F }, + ["man judge: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2696, 0xFE0F }, + ["man judge: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2696, 0xFE0F }, + ["man judge: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2696, 0xFE0F }, + ["man juggling"]={ 0x1F939, 0x200D, 0x2642, 0xFE0F }, + ["man juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man kneeling"]={ 0x1F9CE, 0x200D, 0x2642, 0xFE0F }, + ["man kneeling: dark skin tone"]={ 0x1F9CE, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man kneeling: light skin tone"]={ 0x1F9CE, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man kneeling: medium skin tone"]={ 0x1F9CE, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man kneeling: medium-dark skin tone"]={ 0x1F9CE, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man kneeling: medium-light skin tone"]={ 0x1F9CE, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man lifting weights"]={ 0x1F3CB, 0xFE0F, 0x200D, 0x2642, 0xFE0F }, + ["man lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man mage"]={ 0x1F9D9, 0x200D, 0x2642, 0xFE0F }, + ["man mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man mechanic"]={ 0x1F468, 0x200D, 0x1F527 }, ["man mechanic: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F527 }, ["man mechanic: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F527 }, ["man mechanic: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F527 }, ["man mechanic: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F527 }, ["man mechanic: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F527 }, - ["man mountain biking"]={ 0x1F6B5, 0x200D, 0x2642 }, - ["man mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2642 }, - ["man mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2642 }, - ["man mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2642 }, - ["man mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2642 }, - ["man mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2642 }, + ["man mountain biking"]={ 0x1F6B5, 0x200D, 0x2642, 0xFE0F }, + ["man mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man office worker"]={ 0x1F468, 0x200D, 0x1F4BC }, ["man office worker: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F4BC }, ["man office worker: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F4BC }, ["man office worker: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F4BC }, ["man office worker: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F4BC }, ["man office worker: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F4BC }, - ["man pilot"]={ 0x1F468, 0x200D, 0x2708 }, - ["man pilot: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2708 }, - ["man pilot: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2708 }, - ["man pilot: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2708 }, - ["man pilot: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2708 }, - ["man pilot: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2708 }, - ["man playing handball"]={ 0x1F93E, 0x200D, 0x2642 }, - ["man playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2642 }, - ["man playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2642 }, - ["man playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2642 }, - ["man playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2642 }, - ["man playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2642 }, - ["man playing water polo"]={ 0x1F93D, 0x200D, 0x2642 }, - ["man playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2642 }, - ["man playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2642 }, - ["man playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2642 }, - ["man playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2642 }, - ["man playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2642 }, - ["man police officer"]={ 0x1F46E, 0x200D, 0x2642 }, - ["man police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2642 }, - ["man police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2642 }, - ["man police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2642 }, - ["man police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2642 }, - ["man police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2642 }, - ["man pouting"]={ 0x1F64E, 0x200D, 0x2642 }, - ["man pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2642 }, - ["man pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2642 }, - ["man pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2642 }, - ["man pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2642 }, - ["man pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2642 }, - ["man raising hand"]={ 0x1F64B, 0x200D, 0x2642 }, - ["man raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2642 }, - ["man raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2642 }, - ["man raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2642 }, - ["man raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2642 }, - ["man raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2642 }, - ["man rowing boat"]={ 0x1F6A3, 0x200D, 0x2642 }, - ["man rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2642 }, - ["man rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2642 }, - ["man rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2642 }, - ["man rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2642 }, - ["man rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2642 }, - ["man running"]={ 0x1F3C3, 0x200D, 0x2642 }, - ["man running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2642 }, - ["man running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2642 }, - ["man running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2642 }, - ["man running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2642 }, - ["man running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2642 }, + ["man pilot"]={ 0x1F468, 0x200D, 0x2708, 0xFE0F }, + ["man pilot: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x2708, 0xFE0F }, + ["man pilot: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x2708, 0xFE0F }, + ["man pilot: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x2708, 0xFE0F }, + ["man pilot: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x2708, 0xFE0F }, + ["man pilot: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x2708, 0xFE0F }, + ["man playing handball"]={ 0x1F93E, 0x200D, 0x2642, 0xFE0F }, + ["man playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man playing water polo"]={ 0x1F93D, 0x200D, 0x2642, 0xFE0F }, + ["man playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man police officer"]={ 0x1F46E, 0x200D, 0x2642, 0xFE0F }, + ["man police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man pouting"]={ 0x1F64E, 0x200D, 0x2642, 0xFE0F }, + ["man pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man raising hand"]={ 0x1F64B, 0x200D, 0x2642, 0xFE0F }, + ["man raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man rowing boat"]={ 0x1F6A3, 0x200D, 0x2642, 0xFE0F }, + ["man rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man running"]={ 0x1F3C3, 0x200D, 0x2642, 0xFE0F }, + ["man running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man scientist"]={ 0x1F468, 0x200D, 0x1F52C }, ["man scientist: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F52C }, ["man scientist: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F52C }, ["man scientist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F52C }, ["man scientist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F52C }, ["man scientist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F52C }, - ["man shrugging"]={ 0x1F937, 0x200D, 0x2642 }, - ["man shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2642 }, - ["man shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2642 }, - ["man shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2642 }, - ["man shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2642 }, - ["man shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2642 }, + ["man shrugging"]={ 0x1F937, 0x200D, 0x2642, 0xFE0F }, + ["man shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man singer"]={ 0x1F468, 0x200D, 0x1F3A4 }, ["man singer: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3A4 }, ["man singer: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3A4 }, ["man singer: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F3A4 }, ["man singer: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F3A4 }, ["man singer: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F3A4 }, + ["man standing"]={ 0x1F9CD, 0x200D, 0x2642, 0xFE0F }, + ["man standing: dark skin tone"]={ 0x1F9CD, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man standing: light skin tone"]={ 0x1F9CD, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man standing: medium skin tone"]={ 0x1F9CD, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man standing: medium-dark skin tone"]={ 0x1F9CD, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man standing: medium-light skin tone"]={ 0x1F9CD, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man student"]={ 0x1F468, 0x200D, 0x1F393 }, ["man student: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F393 }, ["man student: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F393 }, ["man student: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F393 }, ["man student: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F393 }, ["man student: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F393 }, - ["man surfing"]={ 0x1F3C4, 0x200D, 0x2642 }, - ["man surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2642 }, - ["man surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2642 }, - ["man surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2642 }, - ["man surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2642 }, - ["man surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2642 }, - ["man swimming"]={ 0x1F3CA, 0x200D, 0x2642 }, - ["man swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2642 }, - ["man swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2642 }, - ["man swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2642 }, - ["man swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2642 }, - ["man swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2642 }, + ["man superhero"]={ 0x1F9B8, 0x200D, 0x2642, 0xFE0F }, + ["man superhero: dark skin tone"]={ 0x1F9B8, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man superhero: light skin tone"]={ 0x1F9B8, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man superhero: medium skin tone"]={ 0x1F9B8, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man superhero: medium-dark skin tone"]={ 0x1F9B8, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man superhero: medium-light skin tone"]={ 0x1F9B8, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man supervillain"]={ 0x1F9B9, 0x200D, 0x2642, 0xFE0F }, + ["man supervillain: dark skin tone"]={ 0x1F9B9, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man supervillain: light skin tone"]={ 0x1F9B9, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man supervillain: medium skin tone"]={ 0x1F9B9, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man supervillain: medium-dark skin tone"]={ 0x1F9B9, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man supervillain: medium-light skin tone"]={ 0x1F9B9, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man surfing"]={ 0x1F3C4, 0x200D, 0x2642, 0xFE0F }, + ["man surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man swimming"]={ 0x1F3CA, 0x200D, 0x2642, 0xFE0F }, + ["man swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man teacher"]={ 0x1F468, 0x200D, 0x1F3EB }, ["man teacher: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F3EB }, ["man teacher: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F3EB }, @@ -1251,73 +1473,131 @@ return { ["man technologist: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F4BB }, ["man technologist: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F4BB }, ["man technologist: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F4BB }, - ["man tipping hand"]={ 0x1F481, 0x200D, 0x2642 }, - ["man tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2642 }, - ["man tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2642 }, - ["man tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2642 }, - ["man tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2642 }, - ["man tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2642 }, - ["man vampire"]={ 0x1F9DB, 0x200D, 0x2642 }, - ["man vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2642 }, - ["man vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2642 }, - ["man vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2642 }, - ["man vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2642 }, - ["man vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2642 }, - ["man walking"]={ 0x1F6B6, 0x200D, 0x2642 }, - ["man walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2642 }, - ["man walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2642 }, - ["man walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2642 }, - ["man walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2642 }, - ["man walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2642 }, - ["man wearing turban"]={ 0x1F473, 0x200D, 0x2642 }, - ["man wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2642 }, - ["man wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2642 }, - ["man wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2642 }, - ["man wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2642 }, - ["man wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2642 }, + ["man tipping hand"]={ 0x1F481, 0x200D, 0x2642, 0xFE0F }, + ["man tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man vampire"]={ 0x1F9DB, 0x200D, 0x2642, 0xFE0F }, + ["man vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man walking"]={ 0x1F6B6, 0x200D, 0x2642, 0xFE0F }, + ["man walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man wearing turban"]={ 0x1F473, 0x200D, 0x2642, 0xFE0F }, + ["man wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["man with chinese cap"]={ 0x1F472 }, ["man with chinese cap: dark skin tone"]={ 0x1F472, 0x1F3FF }, ["man with chinese cap: light skin tone"]={ 0x1F472, 0x1F3FB }, ["man with chinese cap: medium skin tone"]={ 0x1F472, 0x1F3FD }, ["man with chinese cap: medium-dark skin tone"]={ 0x1F472, 0x1F3FE }, ["man with chinese cap: medium-light skin tone"]={ 0x1F472, 0x1F3FC }, - ["man zombie"]={ 0x1F9DF, 0x200D, 0x2642 }, + ["man with probing cane"]={ 0x1F468, 0x200D, 0x1F9AF }, + ["man with probing cane: dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9AF }, + ["man with probing cane: light skin tone"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9AF }, + ["man with probing cane: medium skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9AF }, + ["man with probing cane: medium-dark skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9AF }, + ["man with probing cane: medium-light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9AF }, + ["man zombie"]={ 0x1F9DF, 0x200D, 0x2642, 0xFE0F }, + ["man: bald"]={ 0x1F468, 0x200D, 0x1F9B2 }, + ["man: beard"]={ 0x1F9D4 }, + ["man: blond hair"]={ 0x1F471, 0x200D, 0x2642, 0xFE0F }, + ["man: curly hair"]={ 0x1F468, 0x200D, 0x1F9B1 }, ["man: dark skin tone"]={ 0x1F468, 0x1F3FF }, + ["man: dark skin tone, bald"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9B2 }, + ["man: dark skin tone, beard"]={ 0x1F9D4, 0x1F3FF }, + ["man: dark skin tone, blond hair"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["man: dark skin tone, curly hair"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9B1 }, + ["man: dark skin tone, red hair"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9B0 }, + ["man: dark skin tone, white hair"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F9B3 }, ["man: light skin tone"]={ 0x1F468, 0x1F3FB }, + ["man: light skin tone, bald"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9B2 }, + ["man: light skin tone, beard"]={ 0x1F9D4, 0x1F3FB }, + ["man: light skin tone, blond hair"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["man: light skin tone, curly hair"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9B1 }, + ["man: light skin tone, red hair"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9B0 }, + ["man: light skin tone, white hair"]={ 0x1F468, 0x1F3FB, 0x200D, 0x1F9B3 }, ["man: medium skin tone"]={ 0x1F468, 0x1F3FD }, + ["man: medium skin tone, bald"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9B2 }, + ["man: medium skin tone, beard"]={ 0x1F9D4, 0x1F3FD }, + ["man: medium skin tone, blond hair"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["man: medium skin tone, curly hair"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9B1 }, + ["man: medium skin tone, red hair"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9B0 }, + ["man: medium skin tone, white hair"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F9B3 }, ["man: medium-dark skin tone"]={ 0x1F468, 0x1F3FE }, + ["man: medium-dark skin tone, bald"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9B2 }, + ["man: medium-dark skin tone, beard"]={ 0x1F9D4, 0x1F3FE }, + ["man: medium-dark skin tone, blond hair"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["man: medium-dark skin tone, curly hair"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9B1 }, + ["man: medium-dark skin tone, red hair"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9B0 }, + ["man: medium-dark skin tone, white hair"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F9B3 }, ["man: medium-light skin tone"]={ 0x1F468, 0x1F3FC }, - ["mantelpiece clock"]={ 0x1F570 }, + ["man: medium-light skin tone, bald"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9B2 }, + ["man: medium-light skin tone, beard"]={ 0x1F9D4, 0x1F3FC }, + ["man: medium-light skin tone, blond hair"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, + ["man: medium-light skin tone, curly hair"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9B1 }, + ["man: medium-light skin tone, red hair"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9B0 }, + ["man: medium-light skin tone, white hair"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F9B3 }, + ["man: red hair"]={ 0x1F468, 0x200D, 0x1F9B0 }, + ["man: white hair"]={ 0x1F468, 0x200D, 0x1F9B3 }, + ["mango"]={ 0x1F96D }, + ["mantelpiece clock"]={ 0x1F570, 0xFE0F }, + ["manual wheelchair"]={ 0x1F9BD }, ["man’s shoe"]={ 0x1F45E }, ["map of japan"]={ 0x1F5FE }, ["maple leaf"]={ 0x1F341 }, - ["marshall islands"]={ 0x1F1F2, 0x1F1ED }, ["martial arts uniform"]={ 0x1F94B }, - ["martinique"]={ 0x1F1F2, 0x1F1F6 }, - ["mauritania"]={ 0x1F1F2, 0x1F1F7 }, - ["mauritius"]={ 0x1F1F2, 0x1F1FA }, - ["mayotte"]={ 0x1F1FE, 0x1F1F9 }, + ["mate"]={ 0x1F9C9 }, ["meat on bone"]={ 0x1F356 }, - ["medical symbol"]={ 0x2695 }, + ["mechanical arm"]={ 0x1F9BE }, + ["mechanical leg"]={ 0x1F9BF }, + ["medical symbol"]={ 0x2695, 0xFE0F }, ["megaphone"]={ 0x1F4E3 }, ["melon"]={ 0x1F348 }, ["memo"]={ 0x1F4DD }, - ["men with bunny ears partying"]={ 0x1F46F, 0x200D, 0x2642 }, - ["men wrestling"]={ 0x1F93C, 0x200D, 0x2642 }, + ["men holding hands"]={ 0x1F46C }, + ["men holding hands: dark skin tone"]={ 0x1F46C, 0x1F3FF }, + ["men holding hands: dark skin tone, light skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["men holding hands: dark skin tone, medium skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD }, + ["men holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE }, + ["men holding hands: dark skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["men holding hands: light skin tone"]={ 0x1F46C, 0x1F3FB }, + ["men holding hands: medium skin tone"]={ 0x1F46C, 0x1F3FD }, + ["men holding hands: medium skin tone, light skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["men holding hands: medium skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["men holding hands: medium-dark skin tone"]={ 0x1F46C, 0x1F3FE }, + ["men holding hands: medium-dark skin tone, light skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["men holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD }, + ["men holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F468, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["men holding hands: medium-light skin tone"]={ 0x1F46C, 0x1F3FC }, + ["men holding hands: medium-light skin tone, light skin tone"]={ 0x1F468, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["men with bunny ears"]={ 0x1F46F, 0x200D, 0x2642, 0xFE0F }, + ["men wrestling"]={ 0x1F93C, 0x200D, 0x2642, 0xFE0F }, ["menorah"]={ 0x1F54E }, ["men’s room"]={ 0x1F6B9 }, - ["mermaid"]={ 0x1F9DC, 0x200D, 0x2640 }, - ["mermaid: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2640 }, - ["mermaid: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2640 }, - ["mermaid: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2640 }, - ["mermaid: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2640 }, - ["mermaid: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2640 }, - ["merman"]={ 0x1F9DC, 0x200D, 0x2642 }, - ["merman: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2642 }, - ["merman: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2642 }, - ["merman: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2642 }, - ["merman: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2642 }, - ["merman: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2642 }, + ["mermaid"]={ 0x1F9DC, 0x200D, 0x2640, 0xFE0F }, + ["mermaid: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["mermaid: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["mermaid: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["mermaid: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["mermaid: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["merman"]={ 0x1F9DC, 0x200D, 0x2642, 0xFE0F }, + ["merman: dark skin tone"]={ 0x1F9DC, 0x1F3FF, 0x200D, 0x2642, 0xFE0F }, + ["merman: light skin tone"]={ 0x1F9DC, 0x1F3FB, 0x200D, 0x2642, 0xFE0F }, + ["merman: medium skin tone"]={ 0x1F9DC, 0x1F3FD, 0x200D, 0x2642, 0xFE0F }, + ["merman: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE, 0x200D, 0x2642, 0xFE0F }, + ["merman: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC, 0x200D, 0x2642, 0xFE0F }, ["merperson"]={ 0x1F9DC }, ["merperson: dark skin tone"]={ 0x1F9DC, 0x1F3FF }, ["merperson: light skin tone"]={ 0x1F9DC, 0x1F3FB }, @@ -1325,8 +1605,7 @@ return { ["merperson: medium-dark skin tone"]={ 0x1F9DC, 0x1F3FE }, ["merperson: medium-light skin tone"]={ 0x1F9DC, 0x1F3FC }, ["metro"]={ 0x1F687 }, - ["mexico"]={ 0x1F1F2, 0x1F1FD }, - ["micronesia"]={ 0x1F1EB, 0x1F1F2 }, + ["microbe"]={ 0x1F9A0 }, ["microphone"]={ 0x1F3A4 }, ["microscope"]={ 0x1F52C }, ["middle finger"]={ 0x1F595 }, @@ -1335,53 +1614,50 @@ return { ["middle finger: medium skin tone"]={ 0x1F595, 0x1F3FD }, ["middle finger: medium-dark skin tone"]={ 0x1F595, 0x1F3FE }, ["middle finger: medium-light skin tone"]={ 0x1F595, 0x1F3FC }, - ["military medal"]={ 0x1F396 }, + ["military medal"]={ 0x1F396, 0xFE0F }, ["milky way"]={ 0x1F30C }, ["minibus"]={ 0x1F690 }, + ["minus sign"]={ 0x2796 }, ["moai"]={ 0x1F5FF }, ["mobile phone"]={ 0x1F4F1 }, ["mobile phone off"]={ 0x1F4F4 }, ["mobile phone with arrow"]={ 0x1F4F2 }, - ["moldova"]={ 0x1F1F2, 0x1F1E9 }, - ["monaco"]={ 0x1F1F2, 0x1F1E8 }, ["money bag"]={ 0x1F4B0 }, ["money with wings"]={ 0x1F4B8 }, ["money-mouth face"]={ 0x1F911 }, - ["mongolia"]={ 0x1F1F2, 0x1F1F3 }, ["monkey"]={ 0x1F412 }, ["monkey face"]={ 0x1F435 }, ["monorail"]={ 0x1F69D }, - ["montenegro"]={ 0x1F1F2, 0x1F1EA }, - ["montserrat"]={ 0x1F1F2, 0x1F1F8 }, + ["moon cake"]={ 0x1F96E }, ["moon viewing ceremony"]={ 0x1F391 }, - ["morocco"]={ 0x1F1F2, 0x1F1E6 }, ["mosque"]={ 0x1F54C }, - ["motor boat"]={ 0x1F6E5 }, + ["mosquito"]={ 0x1F99F }, + ["motor boat"]={ 0x1F6E5, 0xFE0F }, ["motor scooter"]={ 0x1F6F5 }, - ["motorcycle"]={ 0x1F3CD }, - ["motorway"]={ 0x1F6E3 }, + ["motorcycle"]={ 0x1F3CD, 0xFE0F }, + ["motorized wheelchair"]={ 0x1F9BC }, + ["motorway"]={ 0x1F6E3, 0xFE0F }, ["mount fuji"]={ 0x1F5FB }, - ["mountain"]={ 0x26F0 }, + ["mountain"]={ 0x26F0, 0xFE0F }, ["mountain cableway"]={ 0x1F6A0 }, ["mountain railway"]={ 0x1F69E }, ["mouse"]={ 0x1F401 }, ["mouse face"]={ 0x1F42D }, ["mouth"]={ 0x1F444 }, ["movie camera"]={ 0x1F3A5 }, - ["mozambique"]={ 0x1F1F2, 0x1F1FF }, ["mrs. claus"]={ 0x1F936 }, ["mrs. claus: dark skin tone"]={ 0x1F936, 0x1F3FF }, ["mrs. claus: light skin tone"]={ 0x1F936, 0x1F3FB }, ["mrs. claus: medium skin tone"]={ 0x1F936, 0x1F3FD }, ["mrs. claus: medium-dark skin tone"]={ 0x1F936, 0x1F3FE }, ["mrs. claus: medium-light skin tone"]={ 0x1F936, 0x1F3FC }, + ["multiplication sign"]={ 0x2716, 0xFE0F }, ["mushroom"]={ 0x1F344 }, ["musical keyboard"]={ 0x1F3B9 }, ["musical note"]={ 0x1F3B5 }, ["musical notes"]={ 0x1F3B6 }, ["musical score"]={ 0x1F3BC }, ["muted speaker"]={ 0x1F507 }, - ["myanmar (burma)"]={ 0x1F1F2, 0x1F1F2 }, ["nail polish"]={ 0x1F485 }, ["nail polish: dark skin tone"]={ 0x1F485, 0x1F3FF }, ["nail polish: light skin tone"]={ 0x1F485, 0x1F3FB }, @@ -1389,30 +1665,21 @@ return { ["nail polish: medium-dark skin tone"]={ 0x1F485, 0x1F3FE }, ["nail polish: medium-light skin tone"]={ 0x1F485, 0x1F3FC }, ["name badge"]={ 0x1F4DB }, - ["namibia"]={ 0x1F1F3, 0x1F1E6 }, - ["national park"]={ 0x1F3DE }, - ["nauru"]={ 0x1F1F3, 0x1F1F7 }, + ["national park"]={ 0x1F3DE, 0xFE0F }, ["nauseated face"]={ 0x1F922 }, + ["nazar amulet"]={ 0x1F9FF }, ["necktie"]={ 0x1F454 }, - ["nepal"]={ 0x1F1F3, 0x1F1F5 }, ["nerd face"]={ 0x1F913 }, - ["netherlands"]={ 0x1F1F3, 0x1F1F1 }, ["neutral face"]={ 0x1F610 }, ["new button"]={ 0x1F195 }, - ["new caledonia"]={ 0x1F1F3, 0x1F1E8 }, ["new moon"]={ 0x1F311 }, ["new moon face"]={ 0x1F31A }, - ["new zealand"]={ 0x1F1F3, 0x1F1FF }, ["newspaper"]={ 0x1F4F0 }, - ["next track button"]={ 0x23ED }, + ["next track button"]={ 0x23ED, 0xFE0F }, ["ng button"]={ 0x1F196 }, - ["nicaragua"]={ 0x1F1F3, 0x1F1EE }, - ["niger"]={ 0x1F1F3, 0x1F1EA }, - ["nigeria"]={ 0x1F1F3, 0x1F1EC }, ["night with stars"]={ 0x1F303 }, ["nine o’clock"]={ 0x1F558 }, ["nine-thirty"]={ 0x1F564 }, - ["niue"]={ 0x1F1F3, 0x1F1FA }, ["no bicycles"]={ 0x1F6B3 }, ["no entry"]={ 0x26D4 }, ["no littering"]={ 0x1F6AF }, @@ -1421,10 +1688,6 @@ return { ["no pedestrians"]={ 0x1F6B7 }, ["no smoking"]={ 0x1F6AD }, ["non-potable water"]={ 0x1F6B1 }, - ["norfolk island"]={ 0x1F1F3, 0x1F1EB }, - ["north korea"]={ 0x1F1F0, 0x1F1F5 }, - ["northern mariana islands"]={ 0x1F1F2, 0x1F1F5 }, - ["norway"]={ 0x1F1F3, 0x1F1F4 }, ["nose"]={ 0x1F443 }, ["nose: dark skin tone"]={ 0x1F443, 0x1F3FF }, ["nose: light skin tone"]={ 0x1F443, 0x1F3FB }, @@ -1434,12 +1697,12 @@ return { ["notebook"]={ 0x1F4D3 }, ["notebook with decorative cover"]={ 0x1F4D4 }, ["nut and bolt"]={ 0x1F529 }, - ["o button (blood type)"]={ 0x1F17E }, + ["o button (blood type)"]={ 0x1F17E, 0xFE0F }, ["octopus"]={ 0x1F419 }, ["oden"]={ 0x1F362 }, ["office building"]={ 0x1F3E2 }, ["ogre"]={ 0x1F479 }, - ["oil drum"]={ 0x1F6E2 }, + ["oil drum"]={ 0x1F6E2, 0xFE0F }, ["ok button"]={ 0x1F197 }, ["ok hand"]={ 0x1F44C }, ["ok hand: dark skin tone"]={ 0x1F44C, 0x1F3FF }, @@ -1447,7 +1710,7 @@ return { ["ok hand: medium skin tone"]={ 0x1F44C, 0x1F3FD }, ["ok hand: medium-dark skin tone"]={ 0x1F44C, 0x1F3FE }, ["ok hand: medium-light skin tone"]={ 0x1F44C, 0x1F3FC }, - ["old key"]={ 0x1F5DD }, + ["old key"]={ 0x1F5DD, 0xFE0F }, ["old man"]={ 0x1F474 }, ["old man: dark skin tone"]={ 0x1F474, 0x1F3FF }, ["old man: light skin tone"]={ 0x1F474, 0x1F3FB }, @@ -1460,14 +1723,13 @@ return { ["old woman: medium skin tone"]={ 0x1F475, 0x1F3FD }, ["old woman: medium-dark skin tone"]={ 0x1F475, 0x1F3FE }, ["old woman: medium-light skin tone"]={ 0x1F475, 0x1F3FC }, - ["older adult"]={ 0x1F9D3 }, - ["older adult: dark skin tone"]={ 0x1F9D3, 0x1F3FF }, - ["older adult: light skin tone"]={ 0x1F9D3, 0x1F3FB }, - ["older adult: medium skin tone"]={ 0x1F9D3, 0x1F3FD }, - ["older adult: medium-dark skin tone"]={ 0x1F9D3, 0x1F3FE }, - ["older adult: medium-light skin tone"]={ 0x1F9D3, 0x1F3FC }, - ["om"]={ 0x1F549 }, - ["oman"]={ 0x1F1F4, 0x1F1F2 }, + ["older person"]={ 0x1F9D3 }, + ["older person: dark skin tone"]={ 0x1F9D3, 0x1F3FF }, + ["older person: light skin tone"]={ 0x1F9D3, 0x1F3FB }, + ["older person: medium skin tone"]={ 0x1F9D3, 0x1F3FD }, + ["older person: medium-dark skin tone"]={ 0x1F9D3, 0x1F3FE }, + ["older person: medium-light skin tone"]={ 0x1F9D3, 0x1F3FC }, + ["om"]={ 0x1F549, 0xFE0F }, ["on! arrow"]={ 0x1F51B }, ["oncoming automobile"]={ 0x1F698 }, ["oncoming bus"]={ 0x1F68D }, @@ -1480,7 +1742,9 @@ return { ["oncoming police car"]={ 0x1F694 }, ["oncoming taxi"]={ 0x1F696 }, ["one o’clock"]={ 0x1F550 }, + ["one-piece swimsuit"]={ 0x1FA71 }, ["one-thirty"]={ 0x1F55C }, + ["onion"]={ 0x1F9C5 }, ["open book"]={ 0x1F4D6 }, ["open file folder"]={ 0x1F4C2 }, ["open hands"]={ 0x1F450 }, @@ -1494,20 +1758,22 @@ return { ["ophiuchus"]={ 0x26CE }, ["optical disk"]={ 0x1F4BF }, ["orange book"]={ 0x1F4D9 }, + ["orange circle"]={ 0x1F7E0 }, ["orange heart"]={ 0x1F9E1 }, - ["orthodox cross"]={ 0x2626 }, + ["orange square"]={ 0x1F7E7 }, + ["orangutan"]={ 0x1F9A7 }, + ["orthodox cross"]={ 0x2626, 0xFE0F }, + ["otter"]={ 0x1F9A6 }, ["outbox tray"]={ 0x1F4E4 }, ["owl"]={ 0x1F989 }, ["ox"]={ 0x1F402 }, - ["p button"]={ 0x1F17F }, + ["oyster"]={ 0x1F9AA }, + ["p button"]={ 0x1F17F, 0xFE0F }, ["package"]={ 0x1F4E6 }, ["page facing up"]={ 0x1F4C4 }, ["page with curl"]={ 0x1F4C3 }, ["pager"]={ 0x1F4DF }, - ["paintbrush"]={ 0x1F58C }, - ["pakistan"]={ 0x1F1F5, 0x1F1F0 }, - ["palau"]={ 0x1F1F5, 0x1F1FC }, - ["palestinian territories"]={ 0x1F1F5, 0x1F1F8 }, + ["paintbrush"]={ 0x1F58C, 0xFE0F }, ["palm tree"]={ 0x1F334 }, ["palms up together"]={ 0x1F932 }, ["palms up together: dark skin tone"]={ 0x1F932, 0x1F3FF }, @@ -1515,37 +1781,55 @@ return { ["palms up together: medium skin tone"]={ 0x1F932, 0x1F3FD }, ["palms up together: medium-dark skin tone"]={ 0x1F932, 0x1F3FE }, ["palms up together: medium-light skin tone"]={ 0x1F932, 0x1F3FC }, - ["panama"]={ 0x1F1F5, 0x1F1E6 }, ["pancakes"]={ 0x1F95E }, - ["panda face"]={ 0x1F43C }, + ["panda"]={ 0x1F43C }, ["paperclip"]={ 0x1F4CE }, - ["papua new guinea"]={ 0x1F1F5, 0x1F1EC }, - ["paraguay"]={ 0x1F1F5, 0x1F1FE }, - ["part alternation mark"]={ 0x303D }, + ["parachute"]={ 0x1FA82 }, + ["parrot"]={ 0x1F99C }, + ["part alternation mark"]={ 0x303D, 0xFE0F }, ["party popper"]={ 0x1F389 }, - ["passenger ship"]={ 0x1F6F3 }, + ["partying face"]={ 0x1F973 }, + ["passenger ship"]={ 0x1F6F3, 0xFE0F }, ["passport control"]={ 0x1F6C2 }, - ["pause button"]={ 0x23F8 }, + ["pause button"]={ 0x23F8, 0xFE0F }, ["paw prints"]={ 0x1F43E }, - ["peace symbol"]={ 0x262E }, + ["peace symbol"]={ 0x262E, 0xFE0F }, ["peach"]={ 0x1F351 }, + ["peacock"]={ 0x1F99A }, ["peanuts"]={ 0x1F95C }, ["pear"]={ 0x1F350 }, - ["pen"]={ 0x1F58A }, - ["pencil"]={ 0x270F }, + ["pen"]={ 0x1F58A, 0xFE0F }, + ["pencil"]={ 0x270F, 0xFE0F }, ["penguin"]={ 0x1F427 }, ["pensive face"]={ 0x1F614 }, - ["people with bunny ears partying"]={ 0x1F46F }, + ["people holding hands"]={ 0x1F9D1, 0x200D, 0x1F91D, 0x200D, 0x1F9D1 }, + ["people holding hands: dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FF }, + ["people holding hands: dark skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB }, + ["people holding hands: dark skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD }, + ["people holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE }, + ["people holding hands: dark skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC }, + ["people holding hands: light skin tone"]={ 0x1F9D1, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB }, + ["people holding hands: medium skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD }, + ["people holding hands: medium skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB }, + ["people holding hands: medium skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC }, + ["people holding hands: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FE }, + ["people holding hands: medium-dark skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB }, + ["people holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FD }, + ["people holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F9D1, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC }, + ["people holding hands: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FC }, + ["people holding hands: medium-light skin tone, light skin tone"]={ 0x1F9D1, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F9D1, 0x1F3FB }, + ["people with bunny ears"]={ 0x1F46F }, ["people wrestling"]={ 0x1F93C }, ["performing arts"]={ 0x1F3AD }, ["persevering face"]={ 0x1F623 }, + ["person"]={ 0x1F9D1 }, ["person biking"]={ 0x1F6B4 }, ["person biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF }, ["person biking: light skin tone"]={ 0x1F6B4, 0x1F3FB }, ["person biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD }, ["person biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE }, ["person biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC }, - ["person bouncing ball"]={ 0x26F9 }, + ["person bouncing ball"]={ 0x26F9, 0xFE0F }, ["person bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF }, ["person bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB }, ["person bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD }, @@ -1606,7 +1890,7 @@ return { ["person getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD }, ["person getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE }, ["person getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC }, - ["person golfing"]={ 0x1F3CC }, + ["person golfing"]={ 0x1F3CC, 0xFE0F }, ["person golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF }, ["person golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB }, ["person golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD }, @@ -1636,7 +1920,13 @@ return { ["person juggling: medium skin tone"]={ 0x1F939, 0x1F3FD }, ["person juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE }, ["person juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC }, - ["person lifting weights"]={ 0x1F3CB }, + ["person kneeling"]={ 0x1F9CE }, + ["person kneeling: dark skin tone"]={ 0x1F9CE, 0x1F3FF }, + ["person kneeling: light skin tone"]={ 0x1F9CE, 0x1F3FB }, + ["person kneeling: medium skin tone"]={ 0x1F9CE, 0x1F3FD }, + ["person kneeling: medium-dark skin tone"]={ 0x1F9CE, 0x1F3FE }, + ["person kneeling: medium-light skin tone"]={ 0x1F9CE, 0x1F3FC }, + ["person lifting weights"]={ 0x1F3CB, 0xFE0F }, ["person lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF }, ["person lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB }, ["person lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD }, @@ -1690,6 +1980,12 @@ return { ["person shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD }, ["person shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE }, ["person shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC }, + ["person standing"]={ 0x1F9CD }, + ["person standing: dark skin tone"]={ 0x1F9CD, 0x1F3FF }, + ["person standing: light skin tone"]={ 0x1F9CD, 0x1F3FB }, + ["person standing: medium skin tone"]={ 0x1F9CD, 0x1F3FD }, + ["person standing: medium-dark skin tone"]={ 0x1F9CD, 0x1F3FE }, + ["person standing: medium-light skin tone"]={ 0x1F9CD, 0x1F3FC }, ["person surfing"]={ 0x1F3C4 }, ["person surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF }, ["person surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB }, @@ -1726,26 +2022,43 @@ return { ["person wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD }, ["person wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE }, ["person wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC }, - ["peru"]={ 0x1F1F5, 0x1F1EA }, - ["philippines"]={ 0x1F1F5, 0x1F1ED }, - ["pick"]={ 0x26CF }, + ["person: blond hair"]={ 0x1F471 }, + ["person: dark skin tone"]={ 0x1F9D1, 0x1F3FF }, + ["person: dark skin tone, blond hair"]={ 0x1F471, 0x1F3FF }, + ["person: light skin tone"]={ 0x1F9D1, 0x1F3FB }, + ["person: light skin tone, blond hair"]={ 0x1F471, 0x1F3FB }, + ["person: medium skin tone"]={ 0x1F9D1, 0x1F3FD }, + ["person: medium skin tone, blond hair"]={ 0x1F471, 0x1F3FD }, + ["person: medium-dark skin tone"]={ 0x1F9D1, 0x1F3FE }, + ["person: medium-dark skin tone, blond hair"]={ 0x1F471, 0x1F3FE }, + ["person: medium-light skin tone"]={ 0x1F9D1, 0x1F3FC }, + ["person: medium-light skin tone, blond hair"]={ 0x1F471, 0x1F3FC }, + ["petri dish"]={ 0x1F9EB }, + ["pick"]={ 0x26CF, 0xFE0F }, ["pie"]={ 0x1F967 }, ["pig"]={ 0x1F416 }, ["pig face"]={ 0x1F437 }, ["pig nose"]={ 0x1F43D }, ["pile of poo"]={ 0x1F4A9 }, ["pill"]={ 0x1F48A }, + ["pinching hand"]={ 0x1F90F }, + ["pinching hand: dark skin tone"]={ 0x1F90F, 0x1F3FF }, + ["pinching hand: light skin tone"]={ 0x1F90F, 0x1F3FB }, + ["pinching hand: medium skin tone"]={ 0x1F90F, 0x1F3FD }, + ["pinching hand: medium-dark skin tone"]={ 0x1F90F, 0x1F3FE }, + ["pinching hand: medium-light skin tone"]={ 0x1F90F, 0x1F3FC }, ["pine decoration"]={ 0x1F38D }, ["pineapple"]={ 0x1F34D }, ["ping pong"]={ 0x1F3D3 }, + ["pirate flag"]={ 0x1F3F4, 0x200D, 0x2620, 0xFE0F }, ["pisces"]={ 0x2653 }, ["pistol"]={ 0x1F52B }, - ["pitcairn islands"]={ 0x1F1F5, 0x1F1F3 }, ["pizza"]={ 0x1F355 }, ["place of worship"]={ 0x1F6D0 }, - ["play button"]={ 0x25B6 }, - ["play or pause button"]={ 0x23EF }, - ["poland"]={ 0x1F1F5, 0x1F1F1 }, + ["play button"]={ 0x25B6, 0xFE0F }, + ["play or pause button"]={ 0x23EF, 0xFE0F }, + ["pleading face"]={ 0x1F97A }, + ["plus sign"]={ 0x2795 }, ["police car"]={ 0x1F693 }, ["police car light"]={ 0x1F6A8 }, ["police officer"]={ 0x1F46E }, @@ -1757,7 +2070,6 @@ return { ["poodle"]={ 0x1F429 }, ["pool 8 ball"]={ 0x1F3B1 }, ["popcorn"]={ 0x1F37F }, - ["portugal"]={ 0x1F1F5, 0x1F1F9 }, ["post office"]={ 0x1F3E4 }, ["postal horn"]={ 0x1F4EF }, ["postbox"]={ 0x1F4EE }, @@ -1766,7 +2078,7 @@ return { ["potato"]={ 0x1F954 }, ["poultry leg"]={ 0x1F357 }, ["pound banknote"]={ 0x1F4B7 }, - ["pouting cat face"]={ 0x1F63E }, + ["pouting cat"]={ 0x1F63E }, ["pouting face"]={ 0x1F621 }, ["prayer beads"]={ 0x1F4FF }, ["pregnant woman"]={ 0x1F930 }, @@ -1788,24 +2100,27 @@ return { ["princess: medium skin tone"]={ 0x1F478, 0x1F3FD }, ["princess: medium-dark skin tone"]={ 0x1F478, 0x1F3FE }, ["princess: medium-light skin tone"]={ 0x1F478, 0x1F3FC }, - ["printer"]={ 0x1F5A8 }, + ["printer"]={ 0x1F5A8, 0xFE0F }, + ["probing cane"]={ 0x1F9AF }, ["prohibited"]={ 0x1F6AB }, - ["puerto rico"]={ 0x1F1F5, 0x1F1F7 }, + ["purple circle"]={ 0x1F7E3 }, ["purple heart"]={ 0x1F49C }, + ["purple square"]={ 0x1F7EA }, ["purse"]={ 0x1F45B }, ["pushpin"]={ 0x1F4CC }, - ["qatar"]={ 0x1F1F6, 0x1F1E6 }, + ["puzzle piece"]={ 0x1F9E9 }, ["question mark"]={ 0x2753 }, ["rabbit"]={ 0x1F407 }, ["rabbit face"]={ 0x1F430 }, - ["racing car"]={ 0x1F3CE }, + ["raccoon"]={ 0x1F99D }, + ["racing car"]={ 0x1F3CE, 0xFE0F }, ["radio"]={ 0x1F4FB }, ["radio button"]={ 0x1F518 }, - ["radioactive"]={ 0x2622 }, + ["radioactive"]={ 0x2622, 0xFE0F }, ["railway car"]={ 0x1F683 }, - ["railway track"]={ 0x1F6E4 }, + ["railway track"]={ 0x1F6E4, 0xFE0F }, ["rainbow"]={ 0x1F308 }, - ["rainbow flag"]={ 0x1F3F3, 0x200D, 0x1F308 }, + ["rainbow flag"]={ 0x1F3F3, 0xFE0F, 0x200D, 0x1F308 }, ["raised back of hand"]={ 0x1F91A }, ["raised back of hand: dark skin tone"]={ 0x1F91A, 0x1F3FF }, ["raised back of hand: light skin tone"]={ 0x1F91A, 0x1F3FB }, @@ -1819,12 +2134,6 @@ return { ["raised fist: medium-dark skin tone"]={ 0x270A, 0x1F3FE }, ["raised fist: medium-light skin tone"]={ 0x270A, 0x1F3FC }, ["raised hand"]={ 0x270B }, - ["raised hand with fingers splayed"]={ 0x1F590 }, - ["raised hand with fingers splayed: dark skin tone"]={ 0x1F590, 0x1F3FF }, - ["raised hand with fingers splayed: light skin tone"]={ 0x1F590, 0x1F3FB }, - ["raised hand with fingers splayed: medium skin tone"]={ 0x1F590, 0x1F3FD }, - ["raised hand with fingers splayed: medium-dark skin tone"]={ 0x1F590, 0x1F3FE }, - ["raised hand with fingers splayed: medium-light skin tone"]={ 0x1F590, 0x1F3FC }, ["raised hand: dark skin tone"]={ 0x270B, 0x1F3FF }, ["raised hand: light skin tone"]={ 0x270B, 0x1F3FB }, ["raised hand: medium skin tone"]={ 0x270B, 0x1F3FD }, @@ -1838,62 +2147,65 @@ return { ["raising hands: medium-light skin tone"]={ 0x1F64C, 0x1F3FC }, ["ram"]={ 0x1F40F }, ["rat"]={ 0x1F400 }, - ["record button"]={ 0x23FA }, - ["recycling symbol"]={ 0x267B }, + ["razor"]={ 0x1FA92 }, + ["receipt"]={ 0x1F9FE }, + ["record button"]={ 0x23FA, 0xFE0F }, + ["recycling symbol"]={ 0x267B, 0xFE0F }, ["red apple"]={ 0x1F34E }, ["red circle"]={ 0x1F534 }, - ["red heart"]={ 0x2764 }, + ["red envelope"]={ 0x1F9E7 }, + ["red heart"]={ 0x2764, 0xFE0F }, ["red paper lantern"]={ 0x1F3EE }, + ["red square"]={ 0x1F7E5 }, ["red triangle pointed down"]={ 0x1F53B }, ["red triangle pointed up"]={ 0x1F53A }, - ["registered"]={ 0xAE }, + ["registered"]={ 0xAE, 0xFE0F }, ["relieved face"]={ 0x1F60C }, - ["reminder ribbon"]={ 0x1F397 }, + ["reminder ribbon"]={ 0x1F397, 0xFE0F }, ["repeat button"]={ 0x1F501 }, ["repeat single button"]={ 0x1F502 }, - ["rescue worker’s helmet"]={ 0x26D1 }, + ["rescue worker’s helmet"]={ 0x26D1, 0xFE0F }, ["restroom"]={ 0x1F6BB }, - ["reverse button"]={ 0x25C0 }, + ["reverse button"]={ 0x25C0, 0xFE0F }, ["revolving hearts"]={ 0x1F49E }, ["rhinoceros"]={ 0x1F98F }, ["ribbon"]={ 0x1F380 }, ["rice ball"]={ 0x1F359 }, ["rice cracker"]={ 0x1F358 }, - ["right anger bubble"]={ 0x1F5EF }, - ["right arrow"]={ 0x27A1 }, - ["right arrow curving down"]={ 0x2935 }, - ["right arrow curving left"]={ 0x21A9 }, - ["right arrow curving up"]={ 0x2934 }, + ["right anger bubble"]={ 0x1F5EF, 0xFE0F }, + ["right arrow"]={ 0x27A1, 0xFE0F }, + ["right arrow curving down"]={ 0x2935, 0xFE0F }, + ["right arrow curving left"]={ 0x21A9, 0xFE0F }, + ["right arrow curving up"]={ 0x2934, 0xFE0F }, ["right-facing fist"]={ 0x1F91C }, ["right-facing fist: dark skin tone"]={ 0x1F91C, 0x1F3FF }, ["right-facing fist: light skin tone"]={ 0x1F91C, 0x1F3FB }, ["right-facing fist: medium skin tone"]={ 0x1F91C, 0x1F3FD }, ["right-facing fist: medium-dark skin tone"]={ 0x1F91C, 0x1F3FE }, ["right-facing fist: medium-light skin tone"]={ 0x1F91C, 0x1F3FC }, - ["right-pointing magnifying glass"]={ 0x1F50E }, ["ring"]={ 0x1F48D }, + ["ringed planet"]={ 0x1FA90 }, ["roasted sweet potato"]={ 0x1F360 }, - ["robot face"]={ 0x1F916 }, + ["robot"]={ 0x1F916 }, ["rocket"]={ 0x1F680 }, - ["rolled-up newspaper"]={ 0x1F5DE }, + ["roll of paper"]={ 0x1F9FB }, + ["rolled-up newspaper"]={ 0x1F5DE, 0xFE0F }, ["roller coaster"]={ 0x1F3A2 }, ["rolling on the floor laughing"]={ 0x1F923 }, - ["romania"]={ 0x1F1F7, 0x1F1F4 }, ["rooster"]={ 0x1F413 }, ["rose"]={ 0x1F339 }, - ["rosette"]={ 0x1F3F5 }, + ["rosette"]={ 0x1F3F5, 0xFE0F }, ["round pushpin"]={ 0x1F4CD }, ["rugby football"]={ 0x1F3C9 }, ["running shirt"]={ 0x1F3BD }, ["running shoe"]={ 0x1F45F }, - ["russia"]={ 0x1F1F7, 0x1F1FA }, - ["rwanda"]={ 0x1F1F7, 0x1F1FC }, - ["réunion"]={ 0x1F1F7, 0x1F1EA }, + ["sad but relieved face"]={ 0x1F625 }, + ["safety pin"]={ 0x1F9F7 }, + ["safety vest"]={ 0x1F9BA }, ["sagittarius"]={ 0x2650 }, ["sailboat"]={ 0x26F5 }, ["sake"]={ 0x1F376 }, - ["samoa"]={ 0x1F1FC, 0x1F1F8 }, - ["san marino"]={ 0x1F1F8, 0x1F1F2 }, + ["salt"]={ 0x1F9C2 }, ["sandwich"]={ 0x1F96A }, ["santa claus"]={ 0x1F385 }, ["santa claus: dark skin tone"]={ 0x1F385, 0x1F3FF }, @@ -1901,18 +2213,16 @@ return { ["santa claus: medium skin tone"]={ 0x1F385, 0x1F3FD }, ["santa claus: medium-dark skin tone"]={ 0x1F385, 0x1F3FE }, ["santa claus: medium-light skin tone"]={ 0x1F385, 0x1F3FC }, - ["satellite"]={ 0x1F6F0 }, + ["sari"]={ 0x1F97B }, + ["satellite"]={ 0x1F6F0, 0xFE0F }, ["satellite antenna"]={ 0x1F4E1 }, - ["saudi arabia"]={ 0x1F1F8, 0x1F1E6 }, ["sauropod"]={ 0x1F995 }, ["saxophone"]={ 0x1F3B7 }, ["scarf"]={ 0x1F9E3 }, ["school"]={ 0x1F3EB }, - ["school backpack"]={ 0x1F392 }, - ["scissors"]={ 0x2702 }, + ["scissors"]={ 0x2702, 0xFE0F }, + ["scorpio"]={ 0x264F }, ["scorpion"]={ 0x1F982 }, - ["scorpius"]={ 0x264F }, - ["scotland"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0073, 0xE0063, 0xE0074, 0xE007F }, ["scroll"]={ 0x1F4DC }, ["seat"]={ 0x1F4BA }, ["see-no-evil monkey"]={ 0x1F648 }, @@ -1923,94 +2233,82 @@ return { ["selfie: medium skin tone"]={ 0x1F933, 0x1F3FD }, ["selfie: medium-dark skin tone"]={ 0x1F933, 0x1F3FE }, ["selfie: medium-light skin tone"]={ 0x1F933, 0x1F3FC }, - ["senegal"]={ 0x1F1F8, 0x1F1F3 }, - ["serbia"]={ 0x1F1F7, 0x1F1F8 }, + ["service dog"]={ 0x1F415, 0x200D, 0x1F9BA }, ["seven o’clock"]={ 0x1F556 }, ["seven-thirty"]={ 0x1F562 }, - ["seychelles"]={ 0x1F1F8, 0x1F1E8 }, ["shallow pan of food"]={ 0x1F958 }, - ["shamrock"]={ 0x2618 }, + ["shamrock"]={ 0x2618, 0xFE0F }, ["shark"]={ 0x1F988 }, ["shaved ice"]={ 0x1F367 }, ["sheaf of rice"]={ 0x1F33E }, - ["shield"]={ 0x1F6E1 }, - ["shinto shrine"]={ 0x26E9 }, + ["shield"]={ 0x1F6E1, 0xFE0F }, + ["shinto shrine"]={ 0x26E9, 0xFE0F }, ["ship"]={ 0x1F6A2 }, ["shooting star"]={ 0x1F320 }, - ["shopping bags"]={ 0x1F6CD }, + ["shopping bags"]={ 0x1F6CD, 0xFE0F }, ["shopping cart"]={ 0x1F6D2 }, ["shortcake"]={ 0x1F370 }, + ["shorts"]={ 0x1FA73 }, ["shower"]={ 0x1F6BF }, ["shrimp"]={ 0x1F990 }, ["shuffle tracks button"]={ 0x1F500 }, ["shushing face"]={ 0x1F92B }, - ["sierra leone"]={ 0x1F1F8, 0x1F1F1 }, ["sign of the horns"]={ 0x1F918 }, ["sign of the horns: dark skin tone"]={ 0x1F918, 0x1F3FF }, ["sign of the horns: light skin tone"]={ 0x1F918, 0x1F3FB }, ["sign of the horns: medium skin tone"]={ 0x1F918, 0x1F3FD }, ["sign of the horns: medium-dark skin tone"]={ 0x1F918, 0x1F3FE }, ["sign of the horns: medium-light skin tone"]={ 0x1F918, 0x1F3FC }, - ["singapore"]={ 0x1F1F8, 0x1F1EC }, - ["sint maarten"]={ 0x1F1F8, 0x1F1FD }, ["six o’clock"]={ 0x1F555 }, ["six-thirty"]={ 0x1F561 }, - ["skier"]={ 0x26F7 }, + ["skateboard"]={ 0x1F6F9 }, + ["skier"]={ 0x26F7, 0xFE0F }, ["skis"]={ 0x1F3BF }, ["skull"]={ 0x1F480 }, - ["skull and crossbones"]={ 0x2620 }, + ["skull and crossbones"]={ 0x2620, 0xFE0F }, + ["skunk"]={ 0x1F9A8 }, ["sled"]={ 0x1F6F7 }, ["sleeping face"]={ 0x1F634 }, ["sleepy face"]={ 0x1F62A }, ["slightly frowning face"]={ 0x1F641 }, ["slightly smiling face"]={ 0x1F642 }, ["slot machine"]={ 0x1F3B0 }, - ["slovakia"]={ 0x1F1F8, 0x1F1F0 }, - ["slovenia"]={ 0x1F1F8, 0x1F1EE }, - ["small airplane"]={ 0x1F6E9 }, + ["sloth"]={ 0x1F9A5 }, + ["small airplane"]={ 0x1F6E9, 0xFE0F }, ["small blue diamond"]={ 0x1F539 }, ["small orange diamond"]={ 0x1F538 }, - ["smiling cat face with heart-eyes"]={ 0x1F63B }, - ["smiling cat face with open mouth"]={ 0x1F63A }, - ["smiling face"]={ 0x263A }, + ["smiling cat with heart-eyes"]={ 0x1F63B }, + ["smiling face"]={ 0x263A, 0xFE0F }, ["smiling face with halo"]={ 0x1F607 }, ["smiling face with heart-eyes"]={ 0x1F60D }, + ["smiling face with hearts"]={ 0x1F970 }, ["smiling face with horns"]={ 0x1F608 }, - ["smiling face with open mouth"]={ 0x1F603 }, - ["smiling face with open mouth & closed eyes"]={ 0x1F606 }, - ["smiling face with open mouth & cold sweat"]={ 0x1F605 }, - ["smiling face with open mouth & smiling eyes"]={ 0x1F604 }, ["smiling face with smiling eyes"]={ 0x1F60A }, ["smiling face with sunglasses"]={ 0x1F60E }, ["smirking face"]={ 0x1F60F }, ["snail"]={ 0x1F40C }, ["snake"]={ 0x1F40D }, ["sneezing face"]={ 0x1F927 }, - ["snow-capped mountain"]={ 0x1F3D4 }, + ["snow-capped mountain"]={ 0x1F3D4, 0xFE0F }, ["snowboarder"]={ 0x1F3C2 }, ["snowboarder: dark skin tone"]={ 0x1F3C2, 0x1F3FF }, ["snowboarder: light skin tone"]={ 0x1F3C2, 0x1F3FB }, ["snowboarder: medium skin tone"]={ 0x1F3C2, 0x1F3FD }, ["snowboarder: medium-dark skin tone"]={ 0x1F3C2, 0x1F3FE }, ["snowboarder: medium-light skin tone"]={ 0x1F3C2, 0x1F3FC }, - ["snowflake"]={ 0x2744 }, - ["snowman"]={ 0x2603 }, + ["snowflake"]={ 0x2744, 0xFE0F }, + ["snowman"]={ 0x2603, 0xFE0F }, ["snowman without snow"]={ 0x26C4 }, + ["soap"]={ 0x1F9FC }, ["soccer ball"]={ 0x26BD }, ["socks"]={ 0x1F9E6 }, ["soft ice cream"]={ 0x1F366 }, - ["solomon islands"]={ 0x1F1F8, 0x1F1E7 }, - ["somalia"]={ 0x1F1F8, 0x1F1F4 }, + ["softball"]={ 0x1F94E }, ["soon arrow"]={ 0x1F51C }, ["sos button"]={ 0x1F198 }, - ["south africa"]={ 0x1F1FF, 0x1F1E6 }, - ["south georgia & south sandwich islands"]={ 0x1F1EC, 0x1F1F8 }, - ["south korea"]={ 0x1F1F0, 0x1F1F7 }, - ["south sudan"]={ 0x1F1F8, 0x1F1F8 }, - ["spade suit"]={ 0x2660 }, + ["spade suit"]={ 0x2660, 0xFE0F }, ["spaghetti"]={ 0x1F35D }, - ["spain"]={ 0x1F1EA, 0x1F1F8 }, - ["sparkle"]={ 0x2747 }, + ["sparkle"]={ 0x2747, 0xFE0F }, ["sparkler"]={ 0x1F387 }, ["sparkles"]={ 0x2728 }, ["sparkling heart"]={ 0x1F496 }, @@ -2018,79 +2316,79 @@ return { ["speaker high volume"]={ 0x1F50A }, ["speaker low volume"]={ 0x1F508 }, ["speaker medium volume"]={ 0x1F509 }, - ["speaking head"]={ 0x1F5E3 }, + ["speaking head"]={ 0x1F5E3, 0xFE0F }, ["speech balloon"]={ 0x1F4AC }, ["speedboat"]={ 0x1F6A4 }, - ["spider"]={ 0x1F577 }, - ["spider web"]={ 0x1F578 }, - ["spiral calendar"]={ 0x1F5D3 }, - ["spiral notepad"]={ 0x1F5D2 }, + ["spider"]={ 0x1F577, 0xFE0F }, + ["spider web"]={ 0x1F578, 0xFE0F }, + ["spiral calendar"]={ 0x1F5D3, 0xFE0F }, + ["spiral notepad"]={ 0x1F5D2, 0xFE0F }, ["spiral shell"]={ 0x1F41A }, + ["sponge"]={ 0x1F9FD }, ["spoon"]={ 0x1F944 }, ["sport utility vehicle"]={ 0x1F699 }, ["sports medal"]={ 0x1F3C5 }, ["spouting whale"]={ 0x1F433 }, ["squid"]={ 0x1F991 }, - ["sri lanka"]={ 0x1F1F1, 0x1F1F0 }, - ["st. barthélemy"]={ 0x1F1E7, 0x1F1F1 }, - ["st. helena"]={ 0x1F1F8, 0x1F1ED }, - ["st. kitts & nevis"]={ 0x1F1F0, 0x1F1F3 }, - ["st. lucia"]={ 0x1F1F1, 0x1F1E8 }, - ["st. martin"]={ 0x1F1F2, 0x1F1EB }, - ["st. pierre & miquelon"]={ 0x1F1F5, 0x1F1F2 }, - ["st. vincent & grenadines"]={ 0x1F1FB, 0x1F1E8 }, - ["stadium"]={ 0x1F3DF }, - ["star and crescent"]={ 0x262A }, - ["star of david"]={ 0x2721 }, + ["squinting face with tongue"]={ 0x1F61D }, + ["stadium"]={ 0x1F3DF, 0xFE0F }, + ["star"]={ 0x2B50 }, + ["star and crescent"]={ 0x262A, 0xFE0F }, + ["star of david"]={ 0x2721, 0xFE0F }, ["star-struck"]={ 0x1F929 }, ["station"]={ 0x1F689 }, ["statue of liberty"]={ 0x1F5FD }, ["steaming bowl"]={ 0x1F35C }, - ["stop button"]={ 0x23F9 }, + ["stethoscope"]={ 0x1FA7A }, + ["stop button"]={ 0x23F9, 0xFE0F }, ["stop sign"]={ 0x1F6D1 }, - ["stopwatch"]={ 0x23F1 }, + ["stopwatch"]={ 0x23F1, 0xFE0F }, ["straight ruler"]={ 0x1F4CF }, ["strawberry"]={ 0x1F353 }, - ["studio microphone"]={ 0x1F399 }, + ["studio microphone"]={ 0x1F399, 0xFE0F }, ["stuffed flatbread"]={ 0x1F959 }, - ["sudan"]={ 0x1F1F8, 0x1F1E9 }, - ["sun"]={ 0x2600 }, + ["sun"]={ 0x2600, 0xFE0F }, ["sun behind cloud"]={ 0x26C5 }, - ["sun behind large cloud"]={ 0x1F325 }, - ["sun behind rain cloud"]={ 0x1F326 }, - ["sun behind small cloud"]={ 0x1F324 }, + ["sun behind large cloud"]={ 0x1F325, 0xFE0F }, + ["sun behind rain cloud"]={ 0x1F326, 0xFE0F }, + ["sun behind small cloud"]={ 0x1F324, 0xFE0F }, ["sun with face"]={ 0x1F31E }, ["sunflower"]={ 0x1F33B }, - ["sunglasses"]={ 0x1F576 }, + ["sunglasses"]={ 0x1F576, 0xFE0F }, ["sunrise"]={ 0x1F305 }, ["sunrise over mountains"]={ 0x1F304 }, ["sunset"]={ 0x1F307 }, - ["suriname"]={ 0x1F1F8, 0x1F1F7 }, + ["superhero"]={ 0x1F9B8 }, + ["superhero: dark skin tone"]={ 0x1F9B8, 0x1F3FF }, + ["superhero: light skin tone"]={ 0x1F9B8, 0x1F3FB }, + ["superhero: medium skin tone"]={ 0x1F9B8, 0x1F3FD }, + ["superhero: medium-dark skin tone"]={ 0x1F9B8, 0x1F3FE }, + ["superhero: medium-light skin tone"]={ 0x1F9B8, 0x1F3FC }, + ["supervillain"]={ 0x1F9B9 }, + ["supervillain: dark skin tone"]={ 0x1F9B9, 0x1F3FF }, + ["supervillain: light skin tone"]={ 0x1F9B9, 0x1F3FB }, + ["supervillain: medium skin tone"]={ 0x1F9B9, 0x1F3FD }, + ["supervillain: medium-dark skin tone"]={ 0x1F9B9, 0x1F3FE }, + ["supervillain: medium-light skin tone"]={ 0x1F9B9, 0x1F3FC }, ["sushi"]={ 0x1F363 }, ["suspension railway"]={ 0x1F69F }, - ["svalbard & jan mayen"]={ 0x1F1F8, 0x1F1EF }, - ["swaziland"]={ 0x1F1F8, 0x1F1FF }, + ["swan"]={ 0x1F9A2 }, ["sweat droplets"]={ 0x1F4A6 }, - ["sweden"]={ 0x1F1F8, 0x1F1EA }, - ["switzerland"]={ 0x1F1E8, 0x1F1ED }, + ["swim brief"]={ 0x1FA72 }, ["synagogue"]={ 0x1F54D }, - ["syria"]={ 0x1F1F8, 0x1F1FE }, ["syringe"]={ 0x1F489 }, - ["são tomé & príncipe"]={ 0x1F1F8, 0x1F1F9 }, ["t-rex"]={ 0x1F996 }, ["t-shirt"]={ 0x1F455 }, ["taco"]={ 0x1F32E }, - ["taiwan"]={ 0x1F1F9, 0x1F1FC }, - ["tajikistan"]={ 0x1F1F9, 0x1F1EF }, ["takeout box"]={ 0x1F961 }, ["tanabata tree"]={ 0x1F38B }, ["tangerine"]={ 0x1F34A }, - ["tanzania"]={ 0x1F1F9, 0x1F1FF }, ["taurus"]={ 0x2649 }, ["taxi"]={ 0x1F695 }, ["teacup without handle"]={ 0x1F375 }, ["tear-off calendar"]={ 0x1F4C6 }, - ["telephone"]={ 0x260E }, + ["teddy bear"]={ 0x1F9F8 }, + ["telephone"]={ 0x260E, 0xFE0F }, ["telephone receiver"]={ 0x1F4DE }, ["telescope"]={ 0x1F52D }, ["television"]={ 0x1F4FA }, @@ -2098,10 +2396,11 @@ return { ["ten-thirty"]={ 0x1F565 }, ["tennis"]={ 0x1F3BE }, ["tent"]={ 0x26FA }, - ["thailand"]={ 0x1F1F9, 0x1F1ED }, - ["thermometer"]={ 0x1F321 }, + ["test tube"]={ 0x1F9EA }, + ["thermometer"]={ 0x1F321, 0xFE0F }, ["thinking face"]={ 0x1F914 }, ["thought balloon"]={ 0x1F4AD }, + ["thread"]={ 0x1F9F5 }, ["three o’clock"]={ 0x1F552 }, ["three-thirty"]={ 0x1F55E }, ["thumbs down"]={ 0x1F44E }, @@ -2119,30 +2418,26 @@ return { ["ticket"]={ 0x1F3AB }, ["tiger"]={ 0x1F405 }, ["tiger face"]={ 0x1F42F }, - ["timer clock"]={ 0x23F2 }, - ["timor-leste"]={ 0x1F1F9, 0x1F1F1 }, + ["timer clock"]={ 0x23F2, 0xFE0F }, ["tired face"]={ 0x1F62B }, - ["togo"]={ 0x1F1F9, 0x1F1EC }, ["toilet"]={ 0x1F6BD }, - ["tokelau"]={ 0x1F1F9, 0x1F1F0 }, ["tokyo tower"]={ 0x1F5FC }, ["tomato"]={ 0x1F345 }, - ["tonga"]={ 0x1F1F9, 0x1F1F4 }, ["tongue"]={ 0x1F445 }, + ["toolbox"]={ 0x1F9F0 }, + ["tooth"]={ 0x1F9B7 }, ["top arrow"]={ 0x1F51D }, ["top hat"]={ 0x1F3A9 }, - ["tornado"]={ 0x1F32A }, - ["trackball"]={ 0x1F5B2 }, + ["tornado"]={ 0x1F32A, 0xFE0F }, + ["trackball"]={ 0x1F5B2, 0xFE0F }, ["tractor"]={ 0x1F69C }, - ["trade mark"]={ 0x2122 }, + ["trade mark"]={ 0x2122, 0xFE0F }, ["train"]={ 0x1F686 }, ["tram"]={ 0x1F68A }, ["tram car"]={ 0x1F68B }, ["triangular flag"]={ 0x1F6A9 }, ["triangular ruler"]={ 0x1F4D0 }, ["trident emblem"]={ 0x1F531 }, - ["trinidad & tobago"]={ 0x1F1F9, 0x1F1F9 }, - ["tristan da cunha"]={ 0x1F1F9, 0x1F1E6 }, ["trolleybus"]={ 0x1F68E }, ["trophy"]={ 0x1F3C6 }, ["tropical drink"]={ 0x1F379 }, @@ -2150,55 +2445,36 @@ return { ["trumpet"]={ 0x1F3BA }, ["tulip"]={ 0x1F337 }, ["tumbler glass"]={ 0x1F943 }, - ["tunisia"]={ 0x1F1F9, 0x1F1F3 }, - ["turkey"]={ 0x1F1F9, 0x1F1F7 }, - ["turkmenistan"]={ 0x1F1F9, 0x1F1F2 }, - ["turks & caicos islands"]={ 0x1F1F9, 0x1F1E8 }, + ["turkey"]={ 0x1F983 }, ["turtle"]={ 0x1F422 }, - ["tuvalu"]={ 0x1F1F9, 0x1F1FB }, ["twelve o’clock"]={ 0x1F55B }, ["twelve-thirty"]={ 0x1F567 }, ["two hearts"]={ 0x1F495 }, - ["two men holding hands"]={ 0x1F46C }, ["two o’clock"]={ 0x1F551 }, - ["two women holding hands"]={ 0x1F46D }, ["two-hump camel"]={ 0x1F42B }, ["two-thirty"]={ 0x1F55D }, - ["u.s. outlying islands"]={ 0x1F1FA, 0x1F1F2 }, - ["u.s. virgin islands"]={ 0x1F1FB, 0x1F1EE }, - ["uganda"]={ 0x1F1FA, 0x1F1EC }, - ["ukraine"]={ 0x1F1FA, 0x1F1E6 }, - ["umbrella"]={ 0x2602 }, - ["umbrella on ground"]={ 0x26F1 }, + ["umbrella"]={ 0x2602, 0xFE0F }, + ["umbrella on ground"]={ 0x26F1, 0xFE0F }, ["umbrella with rain drops"]={ 0x2614 }, ["unamused face"]={ 0x1F612 }, - ["unicorn face"]={ 0x1F984 }, - ["united arab emirates"]={ 0x1F1E6, 0x1F1EA }, - ["united kingdom"]={ 0x1F1EC, 0x1F1E7 }, - ["united nations"]={ 0x1F1FA, 0x1F1F3 }, - ["united states"]={ 0x1F1FA, 0x1F1F8 }, + ["unicorn"]={ 0x1F984 }, ["unlocked"]={ 0x1F513 }, - ["up arrow"]={ 0x2B06 }, - ["up button"]={ 0x1F53C }, + ["up arrow"]={ 0x2B06, 0xFE0F }, ["up! button"]={ 0x1F199 }, - ["up-down arrow"]={ 0x2195 }, - ["up-left arrow"]={ 0x2196 }, - ["up-right arrow"]={ 0x2197 }, + ["up-down arrow"]={ 0x2195, 0xFE0F }, + ["up-left arrow"]={ 0x2196, 0xFE0F }, + ["up-right arrow"]={ 0x2197, 0xFE0F }, ["upside-down face"]={ 0x1F643 }, - ["uruguay"]={ 0x1F1FA, 0x1F1FE }, - ["uzbekistan"]={ 0x1F1FA, 0x1F1FF }, + ["upwards button"]={ 0x1F53C }, ["vampire"]={ 0x1F9DB }, ["vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF }, ["vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB }, ["vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD }, ["vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE }, ["vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC }, - ["vanuatu"]={ 0x1F1FB, 0x1F1FA }, - ["vatican city"]={ 0x1F1FB, 0x1F1E6 }, - ["venezuela"]={ 0x1F1FB, 0x1F1EA }, ["vertical traffic light"]={ 0x1F6A6 }, ["vibration mode"]={ 0x1F4F3 }, - ["victory hand"]={ 0x270C }, + ["victory hand"]={ 0x270C, 0xFE0F }, ["victory hand: dark skin tone"]={ 0x270C, 0x1F3FF }, ["victory hand: light skin tone"]={ 0x270C, 0x1F3FB }, ["victory hand: medium skin tone"]={ 0x270C, 0x1F3FD }, @@ -2207,7 +2483,6 @@ return { ["video camera"]={ 0x1F4F9 }, ["video game"]={ 0x1F3AE }, ["videocassette"]={ 0x1F4FC }, - ["vietnam"]={ 0x1F1FB, 0x1F1F3 }, ["violin"]={ 0x1F3BB }, ["virgo"]={ 0x264D }, ["volcano"]={ 0x1F30B }, @@ -2219,12 +2494,11 @@ return { ["vulcan salute: medium skin tone"]={ 0x1F596, 0x1F3FD }, ["vulcan salute: medium-dark skin tone"]={ 0x1F596, 0x1F3FE }, ["vulcan salute: medium-light skin tone"]={ 0x1F596, 0x1F3FC }, - ["wales"]={ 0x1F3F4, 0xE0067, 0xE0062, 0xE0077, 0xE006C, 0xE0073, 0xE007F }, - ["wallis & futuna"]={ 0x1F1FC, 0x1F1EB }, + ["waffle"]={ 0x1F9C7 }, ["waning crescent moon"]={ 0x1F318 }, ["waning gibbous moon"]={ 0x1F316 }, - ["warning"]={ 0x26A0 }, - ["wastebasket"]={ 0x1F5D1 }, + ["warning"]={ 0x26A0, 0xFE0F }, + ["wastebasket"]={ 0x1F5D1, 0xFE0F }, ["watch"]={ 0x231A }, ["water buffalo"]={ 0x1F403 }, ["water closet"]={ 0x1F6BE }, @@ -2236,35 +2510,60 @@ return { ["waving hand: medium skin tone"]={ 0x1F44B, 0x1F3FD }, ["waving hand: medium-dark skin tone"]={ 0x1F44B, 0x1F3FE }, ["waving hand: medium-light skin tone"]={ 0x1F44B, 0x1F3FC }, - ["wavy dash"]={ 0x3030 }, + ["wavy dash"]={ 0x3030, 0xFE0F }, ["waxing crescent moon"]={ 0x1F312 }, ["waxing gibbous moon"]={ 0x1F314 }, - ["weary cat face"]={ 0x1F640 }, + ["weary cat"]={ 0x1F640 }, ["weary face"]={ 0x1F629 }, ["wedding"]={ 0x1F492 }, - ["western sahara"]={ 0x1F1EA, 0x1F1ED }, ["whale"]={ 0x1F40B }, - ["wheel of dharma"]={ 0x2638 }, + ["wheel of dharma"]={ 0x2638, 0xFE0F }, ["wheelchair symbol"]={ 0x267F }, ["white circle"]={ 0x26AA }, ["white exclamation mark"]={ 0x2755 }, - ["white flag"]={ 0x1F3F3 }, + ["white flag"]={ 0x1F3F3, 0xFE0F }, ["white flower"]={ 0x1F4AE }, - ["white heavy check mark"]={ 0x2705 }, + ["white heart"]={ 0x1F90D }, ["white large square"]={ 0x2B1C }, - ["white medium square"]={ 0x25FB }, - ["white medium star"]={ 0x2B50 }, + ["white medium square"]={ 0x25FB, 0xFE0F }, ["white medium-small square"]={ 0x25FD }, ["white question mark"]={ 0x2754 }, - ["white small square"]={ 0x25AB }, + ["white small square"]={ 0x25AB, 0xFE0F }, ["white square button"]={ 0x1F533 }, ["wilted flower"]={ 0x1F940 }, ["wind chime"]={ 0x1F390 }, - ["wind face"]={ 0x1F32C }, + ["wind face"]={ 0x1F32C, 0xFE0F }, ["wine glass"]={ 0x1F377 }, ["winking face"]={ 0x1F609 }, - ["wolf face"]={ 0x1F43A }, + ["winking face with tongue"]={ 0x1F61C }, + ["wolf"]={ 0x1F43A }, ["woman"]={ 0x1F469 }, + ["woman and man holding hands"]={ 0x1F46B }, + ["woman and man holding hands: dark skin tone"]={ 0x1F46B, 0x1F3FF }, + ["woman and man holding hands: dark skin tone, light skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["woman and man holding hands: dark skin tone, medium skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD }, + ["woman and man holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE }, + ["woman and man holding hands: dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["woman and man holding hands: light skin tone"]={ 0x1F46B, 0x1F3FB }, + ["woman and man holding hands: light skin tone, dark skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF }, + ["woman and man holding hands: light skin tone, medium skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD }, + ["woman and man holding hands: light skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE }, + ["woman and man holding hands: light skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["woman and man holding hands: medium skin tone"]={ 0x1F46B, 0x1F3FD }, + ["woman and man holding hands: medium skin tone, dark skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF }, + ["woman and man holding hands: medium skin tone, light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["woman and man holding hands: medium skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE }, + ["woman and man holding hands: medium skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["woman and man holding hands: medium-dark skin tone"]={ 0x1F46B, 0x1F3FE }, + ["woman and man holding hands: medium-dark skin tone, dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF }, + ["woman and man holding hands: medium-dark skin tone, light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["woman and man holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD }, + ["woman and man holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FC }, + ["woman and man holding hands: medium-light skin tone"]={ 0x1F46B, 0x1F3FC }, + ["woman and man holding hands: medium-light skin tone, dark skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FF }, + ["woman and man holding hands: medium-light skin tone, light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FB }, + ["woman and man holding hands: medium-light skin tone, medium skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FD }, + ["woman and man holding hands: medium-light skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F468, 0x1F3FE }, ["woman artist"]={ 0x1F469, 0x200D, 0x1F3A8 }, ["woman artist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3A8 }, ["woman artist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3A8 }, @@ -2277,42 +2576,42 @@ return { ["woman astronaut: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F680 }, ["woman astronaut: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F680 }, ["woman astronaut: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F680 }, - ["woman biking"]={ 0x1F6B4, 0x200D, 0x2640 }, - ["woman biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2640 }, - ["woman biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2640 }, - ["woman biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2640 }, - ["woman biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2640 }, - ["woman biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2640 }, - ["woman bouncing ball"]={ 0x26F9, 0x200D, 0x2640 }, - ["woman bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2640 }, - ["woman bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2640 }, - ["woman bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2640 }, - ["woman bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2640 }, - ["woman bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2640 }, - ["woman bowing"]={ 0x1F647, 0x200D, 0x2640 }, - ["woman bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2640 }, - ["woman bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2640 }, - ["woman bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2640 }, - ["woman bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2640 }, - ["woman bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2640 }, - ["woman cartwheeling"]={ 0x1F938, 0x200D, 0x2640 }, - ["woman cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2640 }, - ["woman cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2640 }, - ["woman cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2640 }, - ["woman cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2640 }, - ["woman cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2640 }, - ["woman climbing"]={ 0x1F9D7, 0x200D, 0x2640 }, - ["woman climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2640 }, - ["woman climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2640 }, - ["woman climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2640 }, - ["woman climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2640 }, - ["woman climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2640 }, - ["woman construction worker"]={ 0x1F477, 0x200D, 0x2640 }, - ["woman construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2640 }, - ["woman construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2640 }, - ["woman construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2640 }, - ["woman construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2640 }, - ["woman construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2640 }, + ["woman biking"]={ 0x1F6B4, 0x200D, 0x2640, 0xFE0F }, + ["woman biking: dark skin tone"]={ 0x1F6B4, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman biking: light skin tone"]={ 0x1F6B4, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman biking: medium skin tone"]={ 0x1F6B4, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman biking: medium-dark skin tone"]={ 0x1F6B4, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman biking: medium-light skin tone"]={ 0x1F6B4, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman bouncing ball"]={ 0x26F9, 0xFE0F, 0x200D, 0x2640, 0xFE0F }, + ["woman bouncing ball: dark skin tone"]={ 0x26F9, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman bouncing ball: light skin tone"]={ 0x26F9, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman bouncing ball: medium skin tone"]={ 0x26F9, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman bouncing ball: medium-dark skin tone"]={ 0x26F9, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman bouncing ball: medium-light skin tone"]={ 0x26F9, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman bowing"]={ 0x1F647, 0x200D, 0x2640, 0xFE0F }, + ["woman bowing: dark skin tone"]={ 0x1F647, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman bowing: light skin tone"]={ 0x1F647, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman bowing: medium skin tone"]={ 0x1F647, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman bowing: medium-dark skin tone"]={ 0x1F647, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman bowing: medium-light skin tone"]={ 0x1F647, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman cartwheeling"]={ 0x1F938, 0x200D, 0x2640, 0xFE0F }, + ["woman cartwheeling: dark skin tone"]={ 0x1F938, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman cartwheeling: light skin tone"]={ 0x1F938, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman cartwheeling: medium skin tone"]={ 0x1F938, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman cartwheeling: medium-dark skin tone"]={ 0x1F938, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman cartwheeling: medium-light skin tone"]={ 0x1F938, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman climbing"]={ 0x1F9D7, 0x200D, 0x2640, 0xFE0F }, + ["woman climbing: dark skin tone"]={ 0x1F9D7, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman climbing: light skin tone"]={ 0x1F9D7, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman climbing: medium skin tone"]={ 0x1F9D7, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman climbing: medium-dark skin tone"]={ 0x1F9D7, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman climbing: medium-light skin tone"]={ 0x1F9D7, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman construction worker"]={ 0x1F477, 0x200D, 0x2640, 0xFE0F }, + ["woman construction worker: dark skin tone"]={ 0x1F477, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman construction worker: light skin tone"]={ 0x1F477, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman construction worker: medium skin tone"]={ 0x1F477, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman construction worker: medium-dark skin tone"]={ 0x1F477, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman construction worker: medium-light skin tone"]={ 0x1F477, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman cook"]={ 0x1F469, 0x200D, 0x1F373 }, ["woman cook: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F373 }, ["woman cook: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F373 }, @@ -2325,36 +2624,36 @@ return { ["woman dancing: medium skin tone"]={ 0x1F483, 0x1F3FD }, ["woman dancing: medium-dark skin tone"]={ 0x1F483, 0x1F3FE }, ["woman dancing: medium-light skin tone"]={ 0x1F483, 0x1F3FC }, - ["woman detective"]={ 0x1F575, 0x200D, 0x2640 }, - ["woman detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2640 }, - ["woman detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2640 }, - ["woman detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2640 }, - ["woman detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2640 }, - ["woman detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2640 }, - ["woman elf"]={ 0x1F9DD, 0x200D, 0x2640 }, - ["woman elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2640 }, - ["woman elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2640 }, - ["woman elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2640 }, - ["woman elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2640 }, - ["woman elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2640 }, - ["woman facepalming"]={ 0x1F926, 0x200D, 0x2640 }, - ["woman facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2640 }, - ["woman facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2640 }, - ["woman facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2640 }, - ["woman facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2640 }, - ["woman facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2640 }, + ["woman detective"]={ 0x1F575, 0xFE0F, 0x200D, 0x2640, 0xFE0F }, + ["woman detective: dark skin tone"]={ 0x1F575, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman detective: light skin tone"]={ 0x1F575, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman detective: medium skin tone"]={ 0x1F575, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman detective: medium-dark skin tone"]={ 0x1F575, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman detective: medium-light skin tone"]={ 0x1F575, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman elf"]={ 0x1F9DD, 0x200D, 0x2640, 0xFE0F }, + ["woman elf: dark skin tone"]={ 0x1F9DD, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman elf: light skin tone"]={ 0x1F9DD, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman elf: medium skin tone"]={ 0x1F9DD, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman elf: medium-dark skin tone"]={ 0x1F9DD, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman elf: medium-light skin tone"]={ 0x1F9DD, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman facepalming"]={ 0x1F926, 0x200D, 0x2640, 0xFE0F }, + ["woman facepalming: dark skin tone"]={ 0x1F926, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman facepalming: light skin tone"]={ 0x1F926, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman facepalming: medium skin tone"]={ 0x1F926, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman facepalming: medium-dark skin tone"]={ 0x1F926, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman facepalming: medium-light skin tone"]={ 0x1F926, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman factory worker"]={ 0x1F469, 0x200D, 0x1F3ED }, ["woman factory worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3ED }, ["woman factory worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3ED }, ["woman factory worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3ED }, ["woman factory worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3ED }, ["woman factory worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3ED }, - ["woman fairy"]={ 0x1F9DA, 0x200D, 0x2640 }, - ["woman fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2640 }, - ["woman fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2640 }, - ["woman fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2640 }, - ["woman fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2640 }, - ["woman fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2640 }, + ["woman fairy"]={ 0x1F9DA, 0x200D, 0x2640, 0xFE0F }, + ["woman fairy: dark skin tone"]={ 0x1F9DA, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman fairy: light skin tone"]={ 0x1F9DA, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman fairy: medium skin tone"]={ 0x1F9DA, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman fairy: medium-dark skin tone"]={ 0x1F9DA, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman fairy: medium-light skin tone"]={ 0x1F9DA, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman farmer"]={ 0x1F469, 0x200D, 0x1F33E }, ["woman farmer: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F33E }, ["woman farmer: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F33E }, @@ -2367,193 +2666,229 @@ return { ["woman firefighter: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F692 }, ["woman firefighter: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F692 }, ["woman firefighter: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F692 }, - ["woman frowning"]={ 0x1F64D, 0x200D, 0x2640 }, - ["woman frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2640 }, - ["woman frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2640 }, - ["woman frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2640 }, - ["woman frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2640 }, - ["woman frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2640 }, - ["woman genie"]={ 0x1F9DE, 0x200D, 0x2640 }, - ["woman gesturing no"]={ 0x1F645, 0x200D, 0x2640 }, - ["woman gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2640 }, - ["woman gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2640 }, - ["woman gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2640 }, - ["woman gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2640 }, - ["woman gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2640 }, - ["woman gesturing ok"]={ 0x1F646, 0x200D, 0x2640 }, - ["woman gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2640 }, - ["woman gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2640 }, - ["woman gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2640 }, - ["woman gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2640 }, - ["woman gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2640 }, - ["woman getting haircut"]={ 0x1F487, 0x200D, 0x2640 }, - ["woman getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2640 }, - ["woman getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2640 }, - ["woman getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2640 }, - ["woman getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2640 }, - ["woman getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2640 }, - ["woman getting massage"]={ 0x1F486, 0x200D, 0x2640 }, - ["woman getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2640 }, - ["woman getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2640 }, - ["woman getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2640 }, - ["woman getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2640 }, - ["woman getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2640 }, - ["woman golfing"]={ 0x1F3CC, 0x200D, 0x2640 }, - ["woman golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2640 }, - ["woman golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2640 }, - ["woman golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2640 }, - ["woman golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2640 }, - ["woman golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2640 }, - ["woman guard"]={ 0x1F482, 0x200D, 0x2640 }, - ["woman guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2640 }, - ["woman guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2640 }, - ["woman guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2640 }, - ["woman guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2640 }, - ["woman guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2640 }, - ["woman health worker"]={ 0x1F469, 0x200D, 0x2695 }, - ["woman health worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2695 }, - ["woman health worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2695 }, - ["woman health worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2695 }, - ["woman health worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2695 }, - ["woman health worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2695 }, - ["woman in lotus position"]={ 0x1F9D8, 0x200D, 0x2640 }, - ["woman in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2640 }, - ["woman in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2640 }, - ["woman in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2640 }, - ["woman in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2640 }, - ["woman in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2640 }, - ["woman in steamy room"]={ 0x1F9D6, 0x200D, 0x2640 }, - ["woman in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2640 }, - ["woman in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2640 }, - ["woman in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2640 }, - ["woman in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2640 }, - ["woman in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2640 }, - ["woman judge"]={ 0x1F469, 0x200D, 0x2696 }, - ["woman judge: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2696 }, - ["woman judge: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2696 }, - ["woman judge: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2696 }, - ["woman judge: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2696 }, - ["woman judge: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2696 }, - ["woman juggling"]={ 0x1F939, 0x200D, 0x2640 }, - ["woman juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2640 }, - ["woman juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2640 }, - ["woman juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2640 }, - ["woman juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2640 }, - ["woman juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2640 }, - ["woman lifting weights"]={ 0x1F3CB, 0x200D, 0x2640 }, - ["woman lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2640 }, - ["woman lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2640 }, - ["woman lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2640 }, - ["woman lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2640 }, - ["woman lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2640 }, - ["woman mage"]={ 0x1F9D9, 0x200D, 0x2640 }, - ["woman mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2640 }, - ["woman mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2640 }, - ["woman mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2640 }, - ["woman mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2640 }, - ["woman mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2640 }, + ["woman frowning"]={ 0x1F64D, 0x200D, 0x2640, 0xFE0F }, + ["woman frowning: dark skin tone"]={ 0x1F64D, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman frowning: light skin tone"]={ 0x1F64D, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman frowning: medium skin tone"]={ 0x1F64D, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman frowning: medium-dark skin tone"]={ 0x1F64D, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman frowning: medium-light skin tone"]={ 0x1F64D, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman genie"]={ 0x1F9DE, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing no"]={ 0x1F645, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing no: dark skin tone"]={ 0x1F645, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing no: light skin tone"]={ 0x1F645, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing no: medium skin tone"]={ 0x1F645, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing no: medium-dark skin tone"]={ 0x1F645, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing no: medium-light skin tone"]={ 0x1F645, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing ok"]={ 0x1F646, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing ok: dark skin tone"]={ 0x1F646, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing ok: light skin tone"]={ 0x1F646, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing ok: medium skin tone"]={ 0x1F646, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing ok: medium-dark skin tone"]={ 0x1F646, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman gesturing ok: medium-light skin tone"]={ 0x1F646, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman getting haircut"]={ 0x1F487, 0x200D, 0x2640, 0xFE0F }, + ["woman getting haircut: dark skin tone"]={ 0x1F487, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman getting haircut: light skin tone"]={ 0x1F487, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman getting haircut: medium skin tone"]={ 0x1F487, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman getting haircut: medium-dark skin tone"]={ 0x1F487, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman getting haircut: medium-light skin tone"]={ 0x1F487, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman getting massage"]={ 0x1F486, 0x200D, 0x2640, 0xFE0F }, + ["woman getting massage: dark skin tone"]={ 0x1F486, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman getting massage: light skin tone"]={ 0x1F486, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman getting massage: medium skin tone"]={ 0x1F486, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman getting massage: medium-dark skin tone"]={ 0x1F486, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman getting massage: medium-light skin tone"]={ 0x1F486, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman golfing"]={ 0x1F3CC, 0xFE0F, 0x200D, 0x2640, 0xFE0F }, + ["woman golfing: dark skin tone"]={ 0x1F3CC, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman golfing: light skin tone"]={ 0x1F3CC, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman golfing: medium skin tone"]={ 0x1F3CC, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman golfing: medium-dark skin tone"]={ 0x1F3CC, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman golfing: medium-light skin tone"]={ 0x1F3CC, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman guard"]={ 0x1F482, 0x200D, 0x2640, 0xFE0F }, + ["woman guard: dark skin tone"]={ 0x1F482, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman guard: light skin tone"]={ 0x1F482, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman guard: medium skin tone"]={ 0x1F482, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman guard: medium-dark skin tone"]={ 0x1F482, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman guard: medium-light skin tone"]={ 0x1F482, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman health worker"]={ 0x1F469, 0x200D, 0x2695, 0xFE0F }, + ["woman health worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2695, 0xFE0F }, + ["woman health worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2695, 0xFE0F }, + ["woman health worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2695, 0xFE0F }, + ["woman health worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2695, 0xFE0F }, + ["woman health worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2695, 0xFE0F }, + ["woman in lotus position"]={ 0x1F9D8, 0x200D, 0x2640, 0xFE0F }, + ["woman in lotus position: dark skin tone"]={ 0x1F9D8, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman in lotus position: light skin tone"]={ 0x1F9D8, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman in lotus position: medium skin tone"]={ 0x1F9D8, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman in lotus position: medium-dark skin tone"]={ 0x1F9D8, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman in lotus position: medium-light skin tone"]={ 0x1F9D8, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman in manual wheelchair"]={ 0x1F469, 0x200D, 0x1F9BD }, + ["woman in manual wheelchair: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9BD }, + ["woman in manual wheelchair: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9BD }, + ["woman in manual wheelchair: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9BD }, + ["woman in manual wheelchair: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9BD }, + ["woman in manual wheelchair: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9BD }, + ["woman in motorized wheelchair"]={ 0x1F469, 0x200D, 0x1F9BC }, + ["woman in motorized wheelchair: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9BC }, + ["woman in motorized wheelchair: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9BC }, + ["woman in motorized wheelchair: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9BC }, + ["woman in motorized wheelchair: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9BC }, + ["woman in motorized wheelchair: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9BC }, + ["woman in steamy room"]={ 0x1F9D6, 0x200D, 0x2640, 0xFE0F }, + ["woman in steamy room: dark skin tone"]={ 0x1F9D6, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman in steamy room: light skin tone"]={ 0x1F9D6, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman in steamy room: medium skin tone"]={ 0x1F9D6, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman in steamy room: medium-dark skin tone"]={ 0x1F9D6, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman in steamy room: medium-light skin tone"]={ 0x1F9D6, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman judge"]={ 0x1F469, 0x200D, 0x2696, 0xFE0F }, + ["woman judge: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2696, 0xFE0F }, + ["woman judge: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2696, 0xFE0F }, + ["woman judge: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2696, 0xFE0F }, + ["woman judge: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2696, 0xFE0F }, + ["woman judge: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2696, 0xFE0F }, + ["woman juggling"]={ 0x1F939, 0x200D, 0x2640, 0xFE0F }, + ["woman juggling: dark skin tone"]={ 0x1F939, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman juggling: light skin tone"]={ 0x1F939, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman juggling: medium skin tone"]={ 0x1F939, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman juggling: medium-dark skin tone"]={ 0x1F939, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman juggling: medium-light skin tone"]={ 0x1F939, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman kneeling"]={ 0x1F9CE, 0x200D, 0x2640, 0xFE0F }, + ["woman kneeling: dark skin tone"]={ 0x1F9CE, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman kneeling: light skin tone"]={ 0x1F9CE, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman kneeling: medium skin tone"]={ 0x1F9CE, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman kneeling: medium-dark skin tone"]={ 0x1F9CE, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman kneeling: medium-light skin tone"]={ 0x1F9CE, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman lifting weights"]={ 0x1F3CB, 0xFE0F, 0x200D, 0x2640, 0xFE0F }, + ["woman lifting weights: dark skin tone"]={ 0x1F3CB, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman lifting weights: light skin tone"]={ 0x1F3CB, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman lifting weights: medium skin tone"]={ 0x1F3CB, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman lifting weights: medium-dark skin tone"]={ 0x1F3CB, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman lifting weights: medium-light skin tone"]={ 0x1F3CB, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman mage"]={ 0x1F9D9, 0x200D, 0x2640, 0xFE0F }, + ["woman mage: dark skin tone"]={ 0x1F9D9, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman mage: light skin tone"]={ 0x1F9D9, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman mage: medium skin tone"]={ 0x1F9D9, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman mage: medium-dark skin tone"]={ 0x1F9D9, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman mage: medium-light skin tone"]={ 0x1F9D9, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman mechanic"]={ 0x1F469, 0x200D, 0x1F527 }, ["woman mechanic: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F527 }, ["woman mechanic: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F527 }, ["woman mechanic: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F527 }, ["woman mechanic: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F527 }, ["woman mechanic: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F527 }, - ["woman mountain biking"]={ 0x1F6B5, 0x200D, 0x2640 }, - ["woman mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2640 }, - ["woman mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2640 }, - ["woman mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2640 }, - ["woman mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2640 }, - ["woman mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2640 }, + ["woman mountain biking"]={ 0x1F6B5, 0x200D, 0x2640, 0xFE0F }, + ["woman mountain biking: dark skin tone"]={ 0x1F6B5, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman mountain biking: light skin tone"]={ 0x1F6B5, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman mountain biking: medium skin tone"]={ 0x1F6B5, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman mountain biking: medium-dark skin tone"]={ 0x1F6B5, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman mountain biking: medium-light skin tone"]={ 0x1F6B5, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman office worker"]={ 0x1F469, 0x200D, 0x1F4BC }, ["woman office worker: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F4BC }, ["woman office worker: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F4BC }, ["woman office worker: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F4BC }, ["woman office worker: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F4BC }, ["woman office worker: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F4BC }, - ["woman pilot"]={ 0x1F469, 0x200D, 0x2708 }, - ["woman pilot: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2708 }, - ["woman pilot: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2708 }, - ["woman pilot: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2708 }, - ["woman pilot: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2708 }, - ["woman pilot: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2708 }, - ["woman playing handball"]={ 0x1F93E, 0x200D, 0x2640 }, - ["woman playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2640 }, - ["woman playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2640 }, - ["woman playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2640 }, - ["woman playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2640 }, - ["woman playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2640 }, - ["woman playing water polo"]={ 0x1F93D, 0x200D, 0x2640 }, - ["woman playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2640 }, - ["woman playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2640 }, - ["woman playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2640 }, - ["woman playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2640 }, - ["woman playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2640 }, - ["woman police officer"]={ 0x1F46E, 0x200D, 0x2640 }, - ["woman police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2640 }, - ["woman police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2640 }, - ["woman police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2640 }, - ["woman police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2640 }, - ["woman police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2640 }, - ["woman pouting"]={ 0x1F64E, 0x200D, 0x2640 }, - ["woman pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2640 }, - ["woman pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2640 }, - ["woman pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2640 }, - ["woman pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2640 }, - ["woman pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2640 }, - ["woman raising hand"]={ 0x1F64B, 0x200D, 0x2640 }, - ["woman raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2640 }, - ["woman raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2640 }, - ["woman raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2640 }, - ["woman raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2640 }, - ["woman raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2640 }, - ["woman rowing boat"]={ 0x1F6A3, 0x200D, 0x2640 }, - ["woman rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2640 }, - ["woman rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2640 }, - ["woman rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2640 }, - ["woman rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2640 }, - ["woman rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2640 }, - ["woman running"]={ 0x1F3C3, 0x200D, 0x2640 }, - ["woman running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2640 }, - ["woman running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2640 }, - ["woman running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2640 }, - ["woman running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2640 }, - ["woman running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2640 }, + ["woman pilot"]={ 0x1F469, 0x200D, 0x2708, 0xFE0F }, + ["woman pilot: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x2708, 0xFE0F }, + ["woman pilot: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x2708, 0xFE0F }, + ["woman pilot: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x2708, 0xFE0F }, + ["woman pilot: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x2708, 0xFE0F }, + ["woman pilot: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x2708, 0xFE0F }, + ["woman playing handball"]={ 0x1F93E, 0x200D, 0x2640, 0xFE0F }, + ["woman playing handball: dark skin tone"]={ 0x1F93E, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman playing handball: light skin tone"]={ 0x1F93E, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman playing handball: medium skin tone"]={ 0x1F93E, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman playing handball: medium-dark skin tone"]={ 0x1F93E, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman playing handball: medium-light skin tone"]={ 0x1F93E, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman playing water polo"]={ 0x1F93D, 0x200D, 0x2640, 0xFE0F }, + ["woman playing water polo: dark skin tone"]={ 0x1F93D, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman playing water polo: light skin tone"]={ 0x1F93D, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman playing water polo: medium skin tone"]={ 0x1F93D, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman playing water polo: medium-dark skin tone"]={ 0x1F93D, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman playing water polo: medium-light skin tone"]={ 0x1F93D, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman police officer"]={ 0x1F46E, 0x200D, 0x2640, 0xFE0F }, + ["woman police officer: dark skin tone"]={ 0x1F46E, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman police officer: light skin tone"]={ 0x1F46E, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman police officer: medium skin tone"]={ 0x1F46E, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman police officer: medium-dark skin tone"]={ 0x1F46E, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman police officer: medium-light skin tone"]={ 0x1F46E, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman pouting"]={ 0x1F64E, 0x200D, 0x2640, 0xFE0F }, + ["woman pouting: dark skin tone"]={ 0x1F64E, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman pouting: light skin tone"]={ 0x1F64E, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman pouting: medium skin tone"]={ 0x1F64E, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman pouting: medium-dark skin tone"]={ 0x1F64E, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman pouting: medium-light skin tone"]={ 0x1F64E, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman raising hand"]={ 0x1F64B, 0x200D, 0x2640, 0xFE0F }, + ["woman raising hand: dark skin tone"]={ 0x1F64B, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman raising hand: light skin tone"]={ 0x1F64B, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman raising hand: medium skin tone"]={ 0x1F64B, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman raising hand: medium-dark skin tone"]={ 0x1F64B, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman raising hand: medium-light skin tone"]={ 0x1F64B, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman rowing boat"]={ 0x1F6A3, 0x200D, 0x2640, 0xFE0F }, + ["woman rowing boat: dark skin tone"]={ 0x1F6A3, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman rowing boat: light skin tone"]={ 0x1F6A3, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman rowing boat: medium skin tone"]={ 0x1F6A3, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman rowing boat: medium-dark skin tone"]={ 0x1F6A3, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman rowing boat: medium-light skin tone"]={ 0x1F6A3, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman running"]={ 0x1F3C3, 0x200D, 0x2640, 0xFE0F }, + ["woman running: dark skin tone"]={ 0x1F3C3, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman running: light skin tone"]={ 0x1F3C3, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman running: medium skin tone"]={ 0x1F3C3, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman running: medium-dark skin tone"]={ 0x1F3C3, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman running: medium-light skin tone"]={ 0x1F3C3, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman scientist"]={ 0x1F469, 0x200D, 0x1F52C }, ["woman scientist: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F52C }, ["woman scientist: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F52C }, ["woman scientist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F52C }, ["woman scientist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F52C }, ["woman scientist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F52C }, - ["woman shrugging"]={ 0x1F937, 0x200D, 0x2640 }, - ["woman shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2640 }, - ["woman shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2640 }, - ["woman shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2640 }, - ["woman shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2640 }, - ["woman shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2640 }, + ["woman shrugging"]={ 0x1F937, 0x200D, 0x2640, 0xFE0F }, + ["woman shrugging: dark skin tone"]={ 0x1F937, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman shrugging: light skin tone"]={ 0x1F937, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman shrugging: medium skin tone"]={ 0x1F937, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman shrugging: medium-dark skin tone"]={ 0x1F937, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman shrugging: medium-light skin tone"]={ 0x1F937, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman singer"]={ 0x1F469, 0x200D, 0x1F3A4 }, ["woman singer: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3A4 }, ["woman singer: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3A4 }, ["woman singer: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F3A4 }, ["woman singer: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F3A4 }, ["woman singer: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F3A4 }, + ["woman standing"]={ 0x1F9CD, 0x200D, 0x2640, 0xFE0F }, + ["woman standing: dark skin tone"]={ 0x1F9CD, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman standing: light skin tone"]={ 0x1F9CD, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman standing: medium skin tone"]={ 0x1F9CD, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman standing: medium-dark skin tone"]={ 0x1F9CD, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman standing: medium-light skin tone"]={ 0x1F9CD, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman student"]={ 0x1F469, 0x200D, 0x1F393 }, ["woman student: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F393 }, ["woman student: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F393 }, ["woman student: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F393 }, ["woman student: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F393 }, ["woman student: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F393 }, - ["woman surfing"]={ 0x1F3C4, 0x200D, 0x2640 }, - ["woman surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2640 }, - ["woman surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2640 }, - ["woman surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2640 }, - ["woman surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2640 }, - ["woman surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2640 }, - ["woman swimming"]={ 0x1F3CA, 0x200D, 0x2640 }, - ["woman swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2640 }, - ["woman swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2640 }, - ["woman swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2640 }, - ["woman swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2640 }, - ["woman swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2640 }, + ["woman superhero"]={ 0x1F9B8, 0x200D, 0x2640, 0xFE0F }, + ["woman superhero: dark skin tone"]={ 0x1F9B8, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman superhero: light skin tone"]={ 0x1F9B8, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman superhero: medium skin tone"]={ 0x1F9B8, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman superhero: medium-dark skin tone"]={ 0x1F9B8, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman superhero: medium-light skin tone"]={ 0x1F9B8, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman supervillain"]={ 0x1F9B9, 0x200D, 0x2640, 0xFE0F }, + ["woman supervillain: dark skin tone"]={ 0x1F9B9, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman supervillain: light skin tone"]={ 0x1F9B9, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman supervillain: medium skin tone"]={ 0x1F9B9, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman supervillain: medium-dark skin tone"]={ 0x1F9B9, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman supervillain: medium-light skin tone"]={ 0x1F9B9, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman surfing"]={ 0x1F3C4, 0x200D, 0x2640, 0xFE0F }, + ["woman surfing: dark skin tone"]={ 0x1F3C4, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman surfing: light skin tone"]={ 0x1F3C4, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman surfing: medium skin tone"]={ 0x1F3C4, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman surfing: medium-dark skin tone"]={ 0x1F3C4, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman surfing: medium-light skin tone"]={ 0x1F3C4, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman swimming"]={ 0x1F3CA, 0x200D, 0x2640, 0xFE0F }, + ["woman swimming: dark skin tone"]={ 0x1F3CA, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman swimming: light skin tone"]={ 0x1F3CA, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman swimming: medium skin tone"]={ 0x1F3CA, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman swimming: medium-dark skin tone"]={ 0x1F3CA, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman swimming: medium-light skin tone"]={ 0x1F3CA, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman teacher"]={ 0x1F469, 0x200D, 0x1F3EB }, ["woman teacher: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F3EB }, ["woman teacher: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F3EB }, @@ -2566,68 +2901,123 @@ return { ["woman technologist: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F4BB }, ["woman technologist: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F4BB }, ["woman technologist: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F4BB }, - ["woman tipping hand"]={ 0x1F481, 0x200D, 0x2640 }, - ["woman tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2640 }, - ["woman tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2640 }, - ["woman tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2640 }, - ["woman tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2640 }, - ["woman tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2640 }, - ["woman vampire"]={ 0x1F9DB, 0x200D, 0x2640 }, - ["woman vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2640 }, - ["woman vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2640 }, - ["woman vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2640 }, - ["woman vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2640 }, - ["woman vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2640 }, - ["woman walking"]={ 0x1F6B6, 0x200D, 0x2640 }, - ["woman walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2640 }, - ["woman walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2640 }, - ["woman walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2640 }, - ["woman walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2640 }, - ["woman walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2640 }, - ["woman wearing turban"]={ 0x1F473, 0x200D, 0x2640 }, - ["woman wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2640 }, - ["woman wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2640 }, - ["woman wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2640 }, - ["woman wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2640 }, - ["woman wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2640 }, + ["woman tipping hand"]={ 0x1F481, 0x200D, 0x2640, 0xFE0F }, + ["woman tipping hand: dark skin tone"]={ 0x1F481, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman tipping hand: light skin tone"]={ 0x1F481, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman tipping hand: medium skin tone"]={ 0x1F481, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman tipping hand: medium-dark skin tone"]={ 0x1F481, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman tipping hand: medium-light skin tone"]={ 0x1F481, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman vampire"]={ 0x1F9DB, 0x200D, 0x2640, 0xFE0F }, + ["woman vampire: dark skin tone"]={ 0x1F9DB, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman vampire: light skin tone"]={ 0x1F9DB, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman vampire: medium skin tone"]={ 0x1F9DB, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman vampire: medium-dark skin tone"]={ 0x1F9DB, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman vampire: medium-light skin tone"]={ 0x1F9DB, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman walking"]={ 0x1F6B6, 0x200D, 0x2640, 0xFE0F }, + ["woman walking: dark skin tone"]={ 0x1F6B6, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman walking: light skin tone"]={ 0x1F6B6, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman walking: medium skin tone"]={ 0x1F6B6, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman walking: medium-dark skin tone"]={ 0x1F6B6, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman walking: medium-light skin tone"]={ 0x1F6B6, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman wearing turban"]={ 0x1F473, 0x200D, 0x2640, 0xFE0F }, + ["woman wearing turban: dark skin tone"]={ 0x1F473, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman wearing turban: light skin tone"]={ 0x1F473, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman wearing turban: medium skin tone"]={ 0x1F473, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman wearing turban: medium-dark skin tone"]={ 0x1F473, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman wearing turban: medium-light skin tone"]={ 0x1F473, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, ["woman with headscarf"]={ 0x1F9D5 }, ["woman with headscarf: dark skin tone"]={ 0x1F9D5, 0x1F3FF }, ["woman with headscarf: light skin tone"]={ 0x1F9D5, 0x1F3FB }, ["woman with headscarf: medium skin tone"]={ 0x1F9D5, 0x1F3FD }, ["woman with headscarf: medium-dark skin tone"]={ 0x1F9D5, 0x1F3FE }, ["woman with headscarf: medium-light skin tone"]={ 0x1F9D5, 0x1F3FC }, - ["woman zombie"]={ 0x1F9DF, 0x200D, 0x2640 }, + ["woman with probing cane"]={ 0x1F469, 0x200D, 0x1F9AF }, + ["woman with probing cane: dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9AF }, + ["woman with probing cane: light skin tone"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9AF }, + ["woman with probing cane: medium skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9AF }, + ["woman with probing cane: medium-dark skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9AF }, + ["woman with probing cane: medium-light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9AF }, + ["woman zombie"]={ 0x1F9DF, 0x200D, 0x2640, 0xFE0F }, + ["woman: bald"]={ 0x1F469, 0x200D, 0x1F9B2 }, + ["woman: blond hair"]={ 0x1F471, 0x200D, 0x2640, 0xFE0F }, + ["woman: curly hair"]={ 0x1F469, 0x200D, 0x1F9B1 }, ["woman: dark skin tone"]={ 0x1F469, 0x1F3FF }, + ["woman: dark skin tone, bald"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9B2 }, + ["woman: dark skin tone, blond hair"]={ 0x1F471, 0x1F3FF, 0x200D, 0x2640, 0xFE0F }, + ["woman: dark skin tone, curly hair"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9B1 }, + ["woman: dark skin tone, red hair"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9B0 }, + ["woman: dark skin tone, white hair"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F9B3 }, ["woman: light skin tone"]={ 0x1F469, 0x1F3FB }, + ["woman: light skin tone, bald"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9B2 }, + ["woman: light skin tone, blond hair"]={ 0x1F471, 0x1F3FB, 0x200D, 0x2640, 0xFE0F }, + ["woman: light skin tone, curly hair"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9B1 }, + ["woman: light skin tone, red hair"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9B0 }, + ["woman: light skin tone, white hair"]={ 0x1F469, 0x1F3FB, 0x200D, 0x1F9B3 }, ["woman: medium skin tone"]={ 0x1F469, 0x1F3FD }, + ["woman: medium skin tone, bald"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9B2 }, + ["woman: medium skin tone, blond hair"]={ 0x1F471, 0x1F3FD, 0x200D, 0x2640, 0xFE0F }, + ["woman: medium skin tone, curly hair"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9B1 }, + ["woman: medium skin tone, red hair"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9B0 }, + ["woman: medium skin tone, white hair"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F9B3 }, ["woman: medium-dark skin tone"]={ 0x1F469, 0x1F3FE }, + ["woman: medium-dark skin tone, bald"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9B2 }, + ["woman: medium-dark skin tone, blond hair"]={ 0x1F471, 0x1F3FE, 0x200D, 0x2640, 0xFE0F }, + ["woman: medium-dark skin tone, curly hair"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9B1 }, + ["woman: medium-dark skin tone, red hair"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9B0 }, + ["woman: medium-dark skin tone, white hair"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F9B3 }, ["woman: medium-light skin tone"]={ 0x1F469, 0x1F3FC }, + ["woman: medium-light skin tone, bald"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9B2 }, + ["woman: medium-light skin tone, blond hair"]={ 0x1F471, 0x1F3FC, 0x200D, 0x2640, 0xFE0F }, + ["woman: medium-light skin tone, curly hair"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9B1 }, + ["woman: medium-light skin tone, red hair"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9B0 }, + ["woman: medium-light skin tone, white hair"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F9B3 }, + ["woman: red hair"]={ 0x1F469, 0x200D, 0x1F9B0 }, + ["woman: white hair"]={ 0x1F469, 0x200D, 0x1F9B3 }, ["woman’s boot"]={ 0x1F462 }, ["woman’s clothes"]={ 0x1F45A }, ["woman’s hat"]={ 0x1F452 }, ["woman’s sandal"]={ 0x1F461 }, - ["women with bunny ears partying"]={ 0x1F46F, 0x200D, 0x2640 }, - ["women wrestling"]={ 0x1F93C, 0x200D, 0x2640 }, + ["women holding hands"]={ 0x1F46D }, + ["women holding hands: dark skin tone"]={ 0x1F46D, 0x1F3FF }, + ["women holding hands: dark skin tone, light skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB }, + ["women holding hands: dark skin tone, medium skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD }, + ["women holding hands: dark skin tone, medium-dark skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FE }, + ["women holding hands: dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FF, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC }, + ["women holding hands: light skin tone"]={ 0x1F46D, 0x1F3FB }, + ["women holding hands: medium skin tone"]={ 0x1F46D, 0x1F3FD }, + ["women holding hands: medium skin tone, light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB }, + ["women holding hands: medium skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FD, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC }, + ["women holding hands: medium-dark skin tone"]={ 0x1F46D, 0x1F3FE }, + ["women holding hands: medium-dark skin tone, light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB }, + ["women holding hands: medium-dark skin tone, medium skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FD }, + ["women holding hands: medium-dark skin tone, medium-light skin tone"]={ 0x1F469, 0x1F3FE, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FC }, + ["women holding hands: medium-light skin tone"]={ 0x1F46D, 0x1F3FC }, + ["women holding hands: medium-light skin tone, light skin tone"]={ 0x1F469, 0x1F3FC, 0x200D, 0x1F91D, 0x200D, 0x1F469, 0x1F3FB }, + ["women with bunny ears"]={ 0x1F46F, 0x200D, 0x2640, 0xFE0F }, + ["women wrestling"]={ 0x1F93C, 0x200D, 0x2640, 0xFE0F }, ["women’s room"]={ 0x1F6BA }, - ["world map"]={ 0x1F5FA }, + ["woozy face"]={ 0x1F974 }, + ["world map"]={ 0x1F5FA, 0xFE0F }, ["worried face"]={ 0x1F61F }, ["wrapped gift"]={ 0x1F381 }, ["wrench"]={ 0x1F527 }, - ["writing hand"]={ 0x270D }, + ["writing hand"]={ 0x270D, 0xFE0F }, ["writing hand: dark skin tone"]={ 0x270D, 0x1F3FF }, ["writing hand: light skin tone"]={ 0x270D, 0x1F3FB }, ["writing hand: medium skin tone"]={ 0x270D, 0x1F3FD }, ["writing hand: medium-dark skin tone"]={ 0x270D, 0x1F3FE }, ["writing hand: medium-light skin tone"]={ 0x270D, 0x1F3FC }, + ["yarn"]={ 0x1F9F6 }, + ["yawning face"]={ 0x1F971 }, + ["yellow circle"]={ 0x1F7E1 }, ["yellow heart"]={ 0x1F49B }, - ["yemen"]={ 0x1F1FE, 0x1F1EA }, + ["yellow square"]={ 0x1F7E8 }, ["yen banknote"]={ 0x1F4B4 }, - ["yin yang"]={ 0x262F }, - ["zambia"]={ 0x1F1FF, 0x1F1F2 }, + ["yin yang"]={ 0x262F, 0xFE0F }, + ["yo-yo"]={ 0x1FA80 }, + ["zany face"]={ 0x1F92A }, ["zebra"]={ 0x1F993 }, - ["zimbabwe"]={ 0x1F1FF, 0x1F1FC }, ["zipper-mouth face"]={ 0x1F910 }, ["zombie"]={ 0x1F9DF }, ["zzz"]={ 0x1F4A4 }, - ["Åland islands"]={ 0x1F1E6, 0x1F1FD }, -} +} \ No newline at end of file diff --git a/tex/context/base/mkiv/char-ini.lua b/tex/context/base/mkiv/char-ini.lua index c308a2c0f..fb9d9f126 100644 --- a/tex/context/base/mkiv/char-ini.lua +++ b/tex/context/base/mkiv/char-ini.lua @@ -234,6 +234,7 @@ local blocks = allocate { ["cham"] = { first = 0x0AA00, last = 0x0AA5F, description = "Cham" }, ["cherokee"] = { first = 0x013A0, last = 0x013FF, otf="cher", description = "Cherokee" }, ["cherokeesupplement"] = { first = 0x0AB70, last = 0x0ABBF, description = "Cherokee Supplement" }, + ["chesssymbols"] = { first = 0x1FA00, last = 0x1FA6F, description = "Chess Symbols" }, ["cjkcompatibility"] = { first = 0x03300, last = 0x033FF, otf="hang", description = "CJK Compatibility" }, ["cjkcompatibilityforms"] = { first = 0x0FE30, last = 0x0FE4F, otf="hang", description = "CJK Compatibility Forms" }, ["cjkcompatibilityideographs"] = { first = 0x0F900, last = 0x0FAFF, otf="hang", description = "CJK Compatibility Ideographs" }, @@ -296,6 +297,7 @@ local blocks = allocate { -- ["digitsthai"] = { first = 0x00E50, last = 0x00E59, math = true }, -- ["digitstibetan"] = { first = 0x00F20, last = 0x00F29, math = true }, ["dingbats"] = { first = 0x02700, last = 0x027BF, description = "Dingbats" }, + ["dogra"] = { first = 0x11800, last = 0x1184F, description = "Dogra" }, ["dominotiles"] = { first = 0x1F030, last = 0x1F09F, description = "Domino Tiles" }, ["duployan"] = { first = 0x1BC00, last = 0x1BC9F, description = "Duployan" }, ["earlydynasticcuneiform"] = { first = 0x12480, last = 0x1254F, description = "Early Dynastic Cuneiform" }, @@ -314,6 +316,7 @@ local blocks = allocate { ["geometricshapes"] = { first = 0x025A0, last = 0x025FF, math = true, description = "Geometric Shapes" }, ["geometricshapesextended"] = { first = 0x1F780, last = 0x1F7FF, description = "Geometric Shapes Extended" }, ["georgian"] = { first = 0x010A0, last = 0x010FF, otf="geor", description = "Georgian" }, + ["georgianextended"] = { first = 0x01C90, last = 0x01CBF, description = "Georgian Extended" }, ["georgiansupplement"] = { first = 0x02D00, last = 0x02D2F, otf="geor", description = "Georgian Supplement" }, ["glagolitic"] = { first = 0x02C00, last = 0x02C5F, otf="glag", description = "Glagolitic" }, ["glagoliticsupplement"] = { first = 0x1E000, last = 0x1E02F, description = "Glagolitic Supplement" }, @@ -322,6 +325,7 @@ local blocks = allocate { ["greekandcoptic"] = { first = 0x00370, last = 0x003FF, otf="grek", description = "Greek and Coptic" }, ["greekextended"] = { first = 0x01F00, last = 0x01FFF, otf="grek", description = "Greek Extended" }, ["gujarati"] = { first = 0x00A80, last = 0x00AFF, otf="gujr", description = "Gujarati" }, + ["gunjalagondi"] = { first = 0x11D60, last = 0x11DAF, description = "Gunjala Gondi" }, ["gurmukhi"] = { first = 0x00A00, last = 0x00A7F, otf="guru", description = "Gurmukhi" }, ["halfwidthandfullwidthforms"] = { first = 0x0FF00, last = 0x0FFEF, description = "Halfwidth and Fullwidth Forms" }, ["hangulcompatibilityjamo"] = { first = 0x03130, last = 0x0318F, otf="jamo", description = "Hangul Compatibility Jamo" }, @@ -329,6 +333,7 @@ local blocks = allocate { ["hanguljamoextendeda"] = { first = 0x0A960, last = 0x0A97F, description = "Hangul Jamo Extended-A" }, ["hanguljamoextendedb"] = { first = 0x0D7B0, last = 0x0D7FF, description = "Hangul Jamo Extended-B" }, ["hangulsyllables"] = { first = 0x0AC00, last = 0x0D7AF, otf="hang", description = "Hangul Syllables" }, + ["hanifirohingya"] = { first = 0x10D00, last = 0x10D3F, description = "Hanifi Rohingya" }, ["hanunoo"] = { first = 0x01720, last = 0x0173F, otf="hano", description = "Hanunoo" }, ["hatran"] = { first = 0x108E0, last = 0x108FF, description = "Hatran" }, ["hebrew"] = { first = 0x00590, last = 0x005FF, otf="hebr", description = "Hebrew" }, @@ -338,6 +343,7 @@ local blocks = allocate { ["ideographicdescriptioncharacters"] = { first = 0x02FF0, last = 0x02FFF, description = "Ideographic Description Characters" }, ["ideographicsymbolsandpunctuation"] = { first = 0x16FE0, last = 0x16FFF, description = "Ideographic Symbols and Punctuation" }, ["imperialaramaic"] = { first = 0x10840, last = 0x1085F, description = "Imperial Aramaic" }, + ["indicsiyaqnumbers"] = { first = 0x1EC70, last = 0x1ECBF, description = "Indic Siyaq Numbers" }, ["inscriptionalpahlavi"] = { first = 0x10B60, last = 0x10B7F, description = "Inscriptional Pahlavi" }, ["inscriptionalparthian"] = { first = 0x10B40, last = 0x10B5F, description = "Inscriptional Parthian" }, ["ipaextensions"] = { first = 0x00250, last = 0x002AF, description = "IPA Extensions" }, @@ -396,6 +402,7 @@ local blocks = allocate { ["lydian"] = { first = 0x10920, last = 0x1093F, description = "Lydian" }, ["mahajani"] = { first = 0x11150, last = 0x1117F, description = "Mahajani" }, ["mahjongtiles"] = { first = 0x1F000, last = 0x1F02F, description = "Mahjong Tiles" }, + ["makasar"] = { first = 0x11EE0, last = 0x11EFF, description = "Makasar" }, ["malayalam"] = { first = 0x00D00, last = 0x00D7F, otf="mlym", description = "Malayalam" }, ["mandaic"] = { first = 0x00840, last = 0x0085F, otf="mand", description = "Mandaic" }, ["manichaean"] = { first = 0x10AC0, last = 0x10AFF, description = "Manichaean" }, @@ -403,6 +410,8 @@ local blocks = allocate { ["masaramgondi"] = { first = 0x11D00, last = 0x11D5F, description = "Masaram Gondi" }, ["mathematicalalphanumericsymbols"] = { first = 0x1D400, last = 0x1D7FF, math = true, description = "Mathematical Alphanumeric Symbols" }, ["mathematicaloperators"] = { first = 0x02200, last = 0x022FF, math = true, description = "Mathematical Operators" }, + ["mayannumerals"] = { first = 0x1D2E0, last = 0x1D2FF, description = "Mayan Numerals" }, + ["medefaidrin"] = { first = 0x16E40, last = 0x16E9F, description = "Medefaidrin" }, ["meeteimayek"] = { first = 0x0ABC0, last = 0x0ABFF, description = "Meetei Mayek" }, ["meeteimayekextensions"] = { first = 0x0AAE0, last = 0x0AAFF, description = "Meetei Mayek Extensions" }, ["mendekikakui"] = { first = 0x1E800, last = 0x1E8DF, description = "Mende Kikakui" }, @@ -438,6 +447,7 @@ local blocks = allocate { ["oldnortharabian"] = { first = 0x10A80, last = 0x10A9F, description = "Old North Arabian" }, ["oldpermic"] = { first = 0x10350, last = 0x1037F, description = "Old Permic" }, ["oldpersian"] = { first = 0x103A0, last = 0x103DF, otf="xpeo", description = "Old Persian" }, + ["oldsogdian"] = { first = 0x10F00, last = 0x10F2F, description = "Old Sogdian" }, ["oldsoutharabian"] = { first = 0x10A60, last = 0x10A7F, description = "Old South Arabian" }, ["oldturkic"] = { first = 0x10C00, last = 0x10C4F, description = "Old Turkic" }, ["opticalcharacterrecognition"] = { first = 0x02440, last = 0x0245F, description = "Optical Character Recognition" }, @@ -468,6 +478,7 @@ local blocks = allocate { ["sinhala"] = { first = 0x00D80, last = 0x00DFF, otf="sinh", description = "Sinhala" }, ["sinhalaarchaicnumbers"] = { first = 0x111E0, last = 0x111FF, description = "Sinhala Archaic Numbers" }, ["smallformvariants"] = { first = 0x0FE50, last = 0x0FE6F, description = "Small Form Variants" }, + ["sogdian"] = { first = 0x10F30, last = 0x10F6F, description = "Sogdian" }, ["sorasompeng"] = { first = 0x110D0, last = 0x110FF, description = "Sora Sompeng" }, ["soyombo"] = { first = 0x11A50, last = 0x11AAF, description = "Soyombo" }, ["spacingmodifierletters"] = { first = 0x002B0, last = 0x002FF, description = "Spacing Modifier Letters" }, @@ -606,7 +617,8 @@ characters.otfscripts = otfscripts setmetatableindex(otfscripts,function(t,unicode) for k, v in next, blocks do - local first, last = v.first, v.last + local first = v.first + local last = v.last if unicode >= first and unicode <= last then local script = v.otf or "dflt" for u=first,last do @@ -631,25 +643,27 @@ function characters.getrange(name,expression) -- used in font fallback definitio name = gsub(name,'"',"0x") -- goodie: tex hex notation local start, stop if expression then - local first, rest = lpegmatch(splitter2,name) - local range = rawget(blocks,lower(gsub(first,"[^a-zA-Z0-9]",""))) - if range then - start = range.first - stop = range.last - local s = loadstring("return 0 " .. rest) - if type(s) == "function" then - local d = s() - if type(d) == "number" then - start = start + d - stop = stop + d - return start, stop, nil + local n = tonumber(name) + if n then + return n, n, nil + else + local first, rest = lpegmatch(splitter2,name) + local range = rawget(blocks,lower(gsub(first,"[^a-zA-Z0-9]",""))) + if range then + local s = loadstring("return 0 " .. rest) + if type(s) == "function" then + local d = s() + if type(d) == "number" then + return range.first + d, range.last + d, nil + end end end end end - start, stop = lpegmatch(splitter1,name) + local start, stop = lpegmatch(splitter1,name) if start and stop then - start, stop = tonumber(start,16) or tonumber(start), tonumber(stop,16) or tonumber(stop) + start = tonumber(start,16) or tonumber(start) + stop = tonumber(stop, 16) or tonumber(stop) if start and stop then return start, stop, nil end @@ -738,6 +752,10 @@ local is_punctuation = allocate ( tohash { "pc","pd","ps","pe","pi","pf","po", } ) +local is_symbol = allocate ( tohash { + "sm", "sc", "sk", "so", +} ) + -- to be redone: store checked characters characters.is_character = is_character @@ -746,6 +764,7 @@ characters.is_command = is_command characters.is_spacing = is_spacing characters.is_mark = is_mark characters.is_punctuation = is_punctuation +characters.is_symbol = is_symbol local mti = function(t,k) if type(k) == "number" then @@ -1039,7 +1058,8 @@ setmetatableindex(specialchars, function(t,u) local c = data[u] local s = c and c.specials if s then - local tt, ttn = { }, 0 + local tt = { } + local ttn = 0 for i=2,#s do local si = s[i] local c = data[si] @@ -1265,9 +1285,11 @@ lpegpatterns.utf8lower = utf8lower -- string lpegpatterns.utf8upper = utf8upper -- string lpegpatterns.utf8shape = utf8shape -- string -function characters.lower (str) return lpegmatch(utf8lower,str) end -function characters.upper (str) return lpegmatch(utf8upper,str) end -function characters.shaped(str) return lpegmatch(utf8shape,str) end +function characters.lower (str) return str and lpegmatch(utf8lower,str) or "" end +function characters.upper (str) return str and lpegmatch(utf8upper,str) or "" end +function characters.shaped(str) return str and lpegmatch(utf8shape,str) or "" end + +lpeg.setutfcasers(characters.lower,characters.upper) -- local str = [[ -- ÀÁÂÃÄÅàáâãäå àáâãäåàáâãäå ÀÁÂÃÄÅÀÁÂÃÄÅ AAAAAAaaaaaa diff --git a/tex/context/base/mkiv/char-ini.mkiv b/tex/context/base/mkiv/char-ini.mkiv index 9c41df673..0519aaf91 100644 --- a/tex/context/base/mkiv/char-ini.mkiv +++ b/tex/context/base/mkiv/char-ini.mkiv @@ -42,8 +42,8 @@ % use \normalUchar when possible .. the next one is nice for documents and it also accepts % 0x prefixed numbers -\def\utfchar #1{\clf_utfchar \numexpr#1\relax} -\def\safechar#1{\clf_safechar\numexpr#1\relax} +\def\utfchar #1{\clf_utfchar {#1}} +\def\safechar#1{\clf_safechar{#1}} \unexpanded\def\Ux #1{\Uchar\numexpr"#1\relax} % used in xml \def\eUx#1{\Uchar\numexpr"#1\relax} % used in xml @@ -66,6 +66,18 @@ \normalstartimath\char#1\normalstopimath \fi\fi} +\unexpanded\def\textormathchars#1% + {{\font_text_or_mathchars#1\relax}} + +\unexpanded\def\font_text_or_mathchars#1#2\relax + {\relax\ifmmode + #1#2% + \else\iffontchar\font`#1\relax + #1#2\relax + \else + \normalstartimath#1#2\normalstopimath + \fi\fi} + %D The codes are stored in the format, so we don't need to reinitialize %D them (unless of course we have adapted the table). It is on the agenda %D to do this with \type {tex.lccode} cum suis once they're available. diff --git a/tex/context/base/mkiv/char-tex.lua b/tex/context/base/mkiv/char-tex.lua index 065152881..bbaf11875 100644 --- a/tex/context/base/mkiv/char-tex.lua +++ b/tex/context/base/mkiv/char-tex.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['char-tex'] = { local lpeg = lpeg local tonumber, next, type = tonumber, next, type -local format, find, gmatch = string.format, string.find, string.gmatch +local format, find, gmatch, match = string.format, string.find, string.gmatch, string.match local utfchar, utfbyte = utf.char, utf.byte local concat, tohash = table.concat, table.tohash local P, C, R, S, V, Cs, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.V, lpeg.Cs, lpeg.Cc @@ -462,16 +462,24 @@ function commands.makeactive(n,name) -- not used -- context("\\catcode%s=13\\unexpanded\\def %s{\\%s}",n,utfchar(n),name) end +local function to_number(s) + local n = tonumber(s) + if n then + return n + end + return tonumber(match(s,'^"(.*)$'),16) or 0 +end + implement { name = "utfchar", - actions = { utfchar, contextsprint }, - arguments = "integer" + actions = { to_number, utfchar, contextsprint }, + arguments = "string" } implement { name = "safechar", - actions = { texcharacters.safechar, contextsprint }, - arguments = "integer" + actions = { to_number, texcharacters.safechar, contextsprint }, + arguments = "string" } implement { @@ -592,14 +600,17 @@ if not csletters then end -- if isletter then - local lc, uc = chr.lccode, chr.uccode + local lc = chr.lccode + local uc = chr.uccode if not lc then - chr.lccode, lc = u, u + chr.lccode = u + lc = u elseif type(lc) == "table" then lc = u end if not uc then - chr.uccode, uc = u, u + chr.uccode = u + uc = u elseif type(uc) == "table" then uc = u end @@ -623,12 +634,14 @@ if not csletters then -- local lc, uc = chr.lccode, chr.uccode if not lc then - chr.lccode, lc = u, u + chr.lccode = u + lc = u elseif type(lc) == "table" then lc = u end if not uc then - chr.uccode, uc = u, u + chr.uccode = u + uc = u elseif type(uc) == "table" then uc = u end diff --git a/tex/context/base/mkiv/char-utf.lua b/tex/context/base/mkiv/char-utf.lua index 4dc7eba7a..110a4a48c 100644 --- a/tex/context/base/mkiv/char-utf.lua +++ b/tex/context/base/mkiv/char-utf.lua @@ -107,8 +107,10 @@ else local function backtrack(v,last,target) local vs = v.specials if vs and #vs == 3 and vs[1] == "char" then - local one, two = vs[2], vs[3] - local first, second = utfchar(one), utfchar(two) .. last + local one = vs[2] + local two = vs[3] + local first = utfchar(one) + local second = utfchar(two) .. last collapsed[first..second] = target backtrack(data[one],second,target) end @@ -141,8 +143,11 @@ else local size = #vs if kind == "char" and size == 3 then -- what if more than 3 -- - local one, two = vs[2], vs[3] - local first, second, combination = utfchar(one), utfchar(two), utfchar(unicode) + local one = vs[2] + local two = vs[3] + local first = utfchar(one) + local second = utfchar(two) + local combination = utfchar(unicode) -- collapsed[first..second] = combination backtrack(data[one],second,combination) diff --git a/tex/context/base/mkiv/chem-str.lua b/tex/context/base/mkiv/chem-str.lua index 7581a61d1..9f0738fc5 100644 --- a/tex/context/base/mkiv/chem-str.lua +++ b/tex/context/base/mkiv/chem-str.lua @@ -766,9 +766,6 @@ function chemistry.stop() if trace_metapost then report_chemistry("metapost code:\n%s", mpcode) end - if metapost.instance(chemistry.instance) then - f_initialize = nil - end metapost.graphic { instance = chemistry.instance, format = chemistry.format, @@ -776,7 +773,6 @@ function chemistry.stop() data = mpcode, definitions = f_initialize, } - t_initialize = "" metacode = nil end end diff --git a/tex/context/base/mkiv/chem-str.mkiv b/tex/context/base/mkiv/chem-str.mkiv index 646cf13f1..71b104e47 100644 --- a/tex/context/base/mkiv/chem-str.mkiv +++ b/tex/context/base/mkiv/chem-str.mkiv @@ -650,18 +650,18 @@ \chem_formula_bot_nop \fi\fi \ifcsname\??chemicalsymbol d:\detokenize{#1}\endcsname - \t_chem_mid\expandafter{\the\t_chem_mid\chemicalsymbol[d:#1]\aligntab}% + \toksapp\t_chem_mid{\chemicalsymbol[d:#1]\aligntab}% \else - \t_chem_mid\expandafter{\the\t_chem_mid\molecule{#1}\aligntab}% + \toksapp\t_chem_mid{\molecule{#1}\aligntab}% \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 {\toksapp\t_chem_top{\aligntab}} +\def\chem_formula_bot_nop {\toksapp\t_chem_bot{\aligntab}} +\def\chem_formula_top_yes#1{\toksapp\t_chem_top{\chem_formula_top_indeed{#1}\aligntab}\settrue\c_chem_has_top} +\def\chem_formula_bot_yes#1{\toksapp\t_chem_bot{\chem_formula_bot_indeed{#1}\aligntab}\settrue\c_chem_has_bot} \def\chem_formula_top_indeed#1{\strut#1} \def\chem_formula_bot_indeed#1{\strut#1} diff --git a/tex/context/base/mkiv/cldf-bas.lua b/tex/context/base/mkiv/cldf-bas.lua index 070546637..f55132a06 100644 --- a/tex/context/base/mkiv/cldf-bas.lua +++ b/tex/context/base/mkiv/cldf-bas.lua @@ -22,27 +22,38 @@ if not modules then modules = { } end modules ['cldf-bas'] = { -- flush(ctxcatcodes,"}") -- end -local tonumber = tonumber -local type = type -local format = string.format -local utfchar = utf.char -local concat = table.concat +local tonumber = tonumber +local type = type +local format = string.format +local utfchar = utf.char +local concat = table.concat -local context = context -local ctxcore = context.core -local variables = interfaces.variables +local context = context +local ctxcore = context.core -local nodepool = nodes.pool -local new_rule = nodepool.rule -local new_glyph = nodepool.glyph -local current_attr = nodes.current_attr +local variables = interfaces.variables -local current_font = font.current -local texgetcount = tex.getcount -local texsetcount = tex.setcount +local ctx_flushnode = context.nuts.flush + +local nuts = nodes.nuts +local tonode = nuts.tonode +local nodepool = nuts.pool +local new_rule = nodepool.rule +local new_glyph = nodepool.glyph +local new_latelua = nodepool.latelua + +local setattrlist = nuts.setattrlist + +local texgetcount = tex.getcount +local texsetcount = tex.setcount -- a set of basic fast ones +function context.setfontid(n) + -- isn't there a setter? + context("\\setfontid%i\\relax",n) +end + function context.char(k) -- used as escape too, so don't change to utf if type(k) == "table" then local n = #k @@ -70,30 +81,35 @@ function context.utfchar(k) end end -function context.rule(w,h,d,dir) +function context.rule(w,h,d,direction) local rule if type(w) == "table" then - rule = new_rule(w.width,w.height,w.depth,w.dir) + rule = new_rule(w.width,w.height,w.depth,w.direction) else - rule = new_rule(w,h,d,dir) + rule = new_rule(w,h,d,direction) end - rule.attr = current_attr() - context(rule) + setattrlist(rule,true) + context(tonode(rule)) + -- ctx_flushnode(tonode(rule)) end function context.glyph(id,k) if id then if not k then - id, k = current_font(), id + id, k = true, id end local glyph = new_glyph(id,k) - glyph.attr = current_attr() - context(glyph) + setattrlist(glyph,true) + context(tonode(glyph)) + -- ctx_flushnode(tonode(glyph)) end end -local function ctx_par () context("\\par") end -local function ctx_space() context("\\space") end +-- local function ctx_par () context("\\par") end +-- local function ctx_space() context("\\space") end + +local ctx_par = context.cs.par +local ctx_space = context.cs.space context.par = ctx_par context.space = ctx_space @@ -101,8 +117,11 @@ context.space = ctx_space ctxcore.par = ctx_par ctxcore.space = ctx_space -local function ctx_bgroup() context("{") end -local function ctx_egroup() context("}") end +-- local function ctx_bgroup() context("{") end +-- local function ctx_egroup() context("}") end + +local ctx_bgroup = context.cs.bgroup +local ctx_egroup = context.cs.egroup context.bgroup = ctx_bgroup context.egroup = ctx_egroup @@ -136,13 +155,21 @@ function ctxcore.flushboxregister(n) context(type(n) == "number" and [[\box%s ]] or [[\box\%s]],n) end -function ctxcore.beginhbox() context([[\hbox{]]) end -function ctxcore.beginvbox() context([[\vbox{]]) end -function ctxcore.beginvtop() context([[\vtop{]]) end +-- function ctxcore.beginhbox() context([[\hbox\bgroup]]) end +-- function ctxcore.beginvbox() context([[\vbox\bgroup]]) end +-- function ctxcore.beginvtop() context([[\vtop\bgroup]]) end + +local ctx_hbox = context.cs.hbox +local ctx_vbox = context.cs.vbox +local ctx_vtop = context.cs.vtop -ctxcore.endhbox = ctx_egroup -ctxcore.endvbox = ctx_egroup -ctxcore.endvtop = ctx_egroup +function ctxcore.beginhbox() ctx_hbox() ctx_bgroup() end +function ctxcore.beginvbox() ctx_vbox() ctx_bgroup() end +function ctxcore.beginvtop() ctx_vtop() ctx_bgroup() end + +ctxcore.endhbox = ctx_egroup -- \egroup +ctxcore.endvbox = ctx_egroup -- \egroup +ctxcore.endvtop = ctx_egroup -- \egroup local function allocate(name,what,cmd) local a = format("c_syst_last_allocated_%s",what) @@ -165,3 +192,65 @@ context.registers = { -- not really a register but kind of belongs here newchar = function(name,u) context([[\chardef\%s=%s\relax]],name,u) end, } + +do + + if CONTEXTLMTXMODE > 1 then + + function context.latelua(f) + -- table check moved elsewhere + local latelua = new_latelua(f) + setattrlist(latelua,true) -- will become an option + ctx_flushnode(latelua,true) + end + + else + + function context.latelua(f) + if type(f) == "table" then + local action = f.action + local specification = f.specification or f + f = function() action(specification) end + end + local latelua = new_latelua(f) + setattrlist(latelua,true) -- will become an option + ctx_flushnode(latelua,true) + end + + end + +end +-- yes or no + +do + + local NC = ctxcore.NC + local BC = ctxcore.BC + local NR = ctxcore.NR + + context.nc = setmetatable({ }, { + __call = + function(t,...) + NC() + return context(...) + end, + __index = + function(t,k) + NC() + return context[k] + end, + } + ) + + function context.bc(...) + BC() + return context(...) + end + + function context.nr(...) + NC() + NR() + end + +end + diff --git a/tex/context/base/mkiv/cldf-ini.lua b/tex/context/base/mkiv/cldf-ini.lua index 8cd6408d3..9b1a4e368 100644 --- a/tex/context/base/mkiv/cldf-ini.lua +++ b/tex/context/base/mkiv/cldf-ini.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['cldf-ini'] = { license = "see context related readme files" } +-- todo: {token} -> 3 tokens + -- This started as an experiment: generating context code at the lua end. After all -- it is surprisingly simple to implement due to metatables. I was wondering if -- there was a more natural way to deal with commands at the lua end. Of course it's @@ -29,7 +31,7 @@ if not modules then modules = { } end modules ['cldf-ini'] = { -- todo : context("%bold{total: }%s",total) -- todo : context.documentvariable("title") -- --- during the crited project we ran into the situation that luajittex was 10-20 times +-- During the crited project we ran into the situation that luajittex was 10-20 times -- slower that luatex ... after 3 days of testing and probing we finally figured out that -- the the differences between the lua and luajit hashers can lead to quite a slowdown -- in some cases. @@ -52,6 +54,11 @@ if not modules then modules = { } end modules ['cldf-ini'] = { -- watching Trio Hiromi Uehara, Anthony Jackson & Simon Phillips (discovered via the -- later on YT). Hopefully the video breaks made the following better in the end. +-- This module is also a test bed for experimental features so the content changes over +-- time (for the better or worse). There have been no fundamental changes for many years +-- and performance has not changed much either. + + local format, stripstring = string.format, string.strip local next, type, tostring, tonumber, unpack, select, rawset = next, type, tostring, tonumber, unpack, select, rawset local insert, remove, concat = table.insert, table.remove, table.concat @@ -84,6 +91,13 @@ local texgetcount = tex.getcount local isnode = node.is_node local writenode = node.write local copynodelist = node.copy_list +local tonut = node.direct.todirect +local tonode = node.direct.tonode + +local istoken = token.is_token +local newtoken = token.new +local createtoken = token.create +local setluatoken = token.set_lua local catcodenumbers = catcodes.numbers @@ -104,16 +118,31 @@ local report_cld = logs.reporter("cld","stack") local processlines = true -- experiments.register("context.processlines", function(v) processlines = v end) +local tokenflushmode = true +local nodeflushmode = true +local scannerdefmode = true +local maxflushnodeindex = 0x10FFFF - 1 + +-- tokenflushmode = false +-- scannerdefmode = false +-- nodeflushmode = false + -- In earlier experiments a function tables was referred to as lua.calls and the -- primitive \luafunctions was \luacall and we used our own implementation of -- a function table (more indirectness). +local trialtypesettingstate = createtoken("trialtypesettingstate").index + +function context.trialtypesetting() + return texgetcount(trialtypesettingstate) ~= 0 +end + local knownfunctions = lua.get_functions_table() local showstackusage = false trackers.register("context.stack",function(v) showstackusage = v end) -local freed, nofused, noffreed = { }, 0, 0 -- maybe use the number of @@trialtypesetting +local freed, nofused, noffreed = { }, 0, 0 local usedstack = function() return nofused, noffreed @@ -122,7 +151,7 @@ end local flushfunction = function(slot,arg) if arg() then -- keep - elseif texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + elseif texgetcount(trialtypesettingstate) == 0 then noffreed = noffreed + 1 freed[noffreed] = slot knownfunctions[slot] = false @@ -147,7 +176,7 @@ local storefunction = function(arg) end local flushnode = function(slot,arg) - if texgetcount("@@trialtypesetting") == 0 then -- @@trialtypesetting is private! + if texgetcount(trialtypesettingstate) == 0 then writenode(arg) noffreed = noffreed + 1 freed[noffreed] = slot @@ -182,9 +211,13 @@ local f_resolve = nil local p_resolve = ((1-lpegP("."))^1 / function(s) f_resolve = f_resolve[s] end * lpegP(".")^0)^1 local function resolvestoredfunction(str) - f_resolve = global - lpegmatch(p_resolve,str) - return f_resolve + if type(str) == "string" then + f_resolve = global + lpegmatch(p_resolve,str) + return f_resolve + else + return str + end end local function expose(slot,f,...) -- so we can register yet undefined functions @@ -246,17 +279,17 @@ local registerfunction = function(f,direct) -- either f=code or f=namespace,dire func = resolvestoredfunction(f) end if type(func) ~= "function" then - func = function() report_cld("invalid resolve %A",f) end + func = function() report_cld("invalid resolve %A, case %s",f,1) end end elseif type(f) == "string" then func = loadstring(f) if type(func) ~= "function" then - func = function() report_cld("invalid code %A",f) end + func = function() report_cld("invalid code %A, case %s",f,2) end end elseif type(f) == "function" then func = f else - func = function() report_cld("invalid function %A",f) end + func = function() report_cld("invalid function %A, case %s",f,3) end end knownfunctions[slot] = func return slot @@ -305,53 +338,52 @@ local storedscanners = interfaces.storedscanners storage.register("interfaces/storedscanners", storedscanners, "interfaces.storedscanners") local interfacescanners = setmetatablenewindex(function(t,k,v) + rawset(t,k,v) if storedscanners[k] then - -- report_cld("warning: scanner %a is already set",k) + -- report_cld("warning: scanner %a is already set (mode 1a)",k) -- os.exit() -- \scan_ is already in the format -- report_cld("using interface scanner: %s",k) + elseif scannerdefmode then + -- report_cld("installing interface scanner: %s (mode 1b)",k) + -- local n = registerfunction(interfaces.scanners[k],true) + local n = registerfunction("interfaces.scanners."..k,true) + storedscanners[k] = n + local name = "clf_" .. k + setluatoken(name,n,"global") -- todo : protected and "protected" or "" else - -- todo: allocate slot here and pass it + -- report_cld("installing interface scanner: %s (mode 1c)",k) storedscanners[k] = true - -- report_cld("installing interface scanner: %s",k) context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",k,k) end - rawset(t,k,v) + -- rawset(t,k,v) end) function interfaces.registerscanner(name,action,protected,public,call) + rawset(interfacescanners,name,action) if storedscanners[name] then - -- report_cld("warning: scanner %a is already set",k) + -- report_cld("warning: scanner %a is already set (mode 2a)",name) -- os.exit() -- \scan_ is already in the format -- report_cld("using interface scanner: %s",k) + elseif scannerdefmode then + -- report_cld("installing interface scanner: %s (mode 2b)",name) + -- local n = registerfunction(action,true) -- todo + local n = registerfunction("interfaces.scanners."..name,true) + storedscanners[name] = n + local name = public and name or ("clf_" .. name) + setluatoken(name,n,"global",protected and "protected" or "") else storedscanners[name] = true --- if protected then --- -- report_cld("installing expandable interface scanner: %s",k) --- if public then --- context("\\installprotectedctxscanner{%s}{interfaces.scanners.%s}",name,name) --- else --- context("\\installprotectedctxscanner{clf_%s}{interfaces.scanners.%s}",name,name) --- end --- else --- -- report_cld("installing protected interface scanner: %s",k) --- if public then --- context("\\installctxscanner{%s}{interfaces.scanners.%s}",name,name) --- else --- context("\\installctxscanner{clf_%s}{interfaces.scanners.%s}",name,name) --- end --- end - -- report_cld("installing interface scanner: %s",k) - context("\\install%sctxscanner%s{%s%s}{interfaces.scanners.%s}", - protected and "protected" or "", - call and "call" or "", - public and "" or "clf_", - name, - name - ) - end - rawset(interfacescanners,name,action) + -- report_cld("installing interface scanner: %s (mode 2c)",name) + context("\\install%sctxscanner{%s%s}{interfaces.scanners.%s}", + protected and "protected" or "", + public and "" or "clf_", + name, + name + ) + end + -- rawset(interfacescanners,name,action) end interfaces.scanners = storage.mark(interfacescanners) @@ -379,7 +411,7 @@ end local function dummy() end -function commands.ctxresetter(name) +function commands.ctxresetter(name) -- to be checked return function() if storedscanners[name] then rawset(interfacescanners,name,dummy) @@ -388,10 +420,6 @@ function commands.ctxresetter(name) end end -function context.trialtypesetting() - return texgetcount("@@trialtypesetting") ~= 0 -end - -- Should we keep the catcodes with the function? local catcodestack = { } @@ -673,6 +701,8 @@ local s_cldl_option_b = "[\\cldl" local s_cldl_option_f = "[\\cldl" -- add space (not needed) local s_cldl_option_e = "]" local s_cldl_option_s = "\\cldl" +----- s_cldl_option_d = "\\cldd" +local s_cldl_option_d = s_cldl_option_s local s_cldl_argument_b = "{\\cldl" local s_cldl_argument_f = "{\\cldl " local s_cldl_argument_e = "}" @@ -683,14 +713,23 @@ local s_cldl_argument_e = "}" -- local s_cldl_argument_b = "{" -- local s_cldl_argument_f = "{ " +local t_cldl_luafunction = createtoken("luafunctioncall") +local lua_expandable_call_token_code = token.command_id and token.command_id("lua_expandable_call") + local function writer(parent,command,...) -- already optimized before call - flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes + + if type(command) == "string" then -- for now + flush(currentcatcodes,command) -- todo: ctx|prt|texcatcodes + else + flush(command) -- todo: ctx|prt|texcatcodes + end + local direct = false -- local t = { ... } -- for i=1,#t do -- local ti = t[i] for i=1,select("#",...) do - local ti = (select(i,...)) + local ti = select(i,...) if direct then local typ = type(ti) if typ == "string" or typ == "number" then @@ -703,6 +742,8 @@ local function writer(parent,command,...) -- already optimized before call -- nothing elseif ti == "" then flush(currentcatcodes,"{}") + -- elseif ti == 1 then + -- flush(currentcatcodes,"{1}") else local typ = type(ti) if typ == "string" then @@ -719,7 +760,7 @@ local function writer(parent,command,...) -- already optimized before call flush(currentcatcodes,"}") end elseif typ == "number" then - -- numbers never have funny catcodes + -- numbers never have funny catcodesz flush(currentcatcodes,"{",ti,"}") elseif typ == "table" then local tn = #ti @@ -749,7 +790,16 @@ local function writer(parent,command,...) -- already optimized before call elseif tn == 1 then -- some 20% faster than the next loop local tj = ti[1] if type(tj) == "function" then - flush(currentcatcodes,s_cldl_option_b,storefunction(tj),s_cldl_option_e) + tj = storefunction(tj) + if tokenflushmode then + if newtoken then + flush(currentcatcodes,"[",newtoken(tj,lua_expandable_call_code),"]") + else + flush(currentcatcodes,"[",t_cldl_luafunction,tj,"]") + end + else + flush(currentcatcodes,s_cldl_option_b,tj,s_cldl_option_e) + end else flush(currentcatcodes,"[",tj,"]") end @@ -758,10 +808,15 @@ local function writer(parent,command,...) -- already optimized before call for j=1,tn do local tj = ti[j] if type(tj) == "function" then - if j == tn then - flush(currentcatcodes,s_cldl_option_s,storefunction(tj),"]") + tj = storefunction(tj) + if tokenflushmode then + if newtoken then + flush(currentcatcodes,"[",newtoken(tj,lua_expandable_call_code),j == tn and "]" or ",") + else + flush(currentcatcodes,"[",t_cldl_luafunction,tj,j == tn and "]" or ",") + end else - flush(currentcatcodes,s_cldl_option_s,storefunction(tj),",") + flush(currentcatcodes,s_cldl_option_s,tj,j == tn and "]" or ",") end else if j == tn then @@ -774,7 +829,16 @@ local function writer(parent,command,...) -- already optimized before call end elseif typ == "function" then -- todo: ctx|prt|texcatcodes - flush(currentcatcodes,s_cldl_argument_f,storefunction(ti),s_cldl_argument_e) + ti = storefunction(ti) + if tokenflushmode then + if newtoken then + flush(currentcatcodes,"{",newtoken(ti,lua_expandable_call_token_code),"}") + else + flush(currentcatcodes,"{",t_cldl_luafunction,ti,"}") + end + else + flush(currentcatcodes,s_cldl_argument_f,ti,s_cldl_argument_e) + end elseif typ == "boolean" then if ti then flushdirect(currentcatcodes,"\r") @@ -783,62 +847,123 @@ local function writer(parent,command,...) -- already optimized before call end elseif typ == "thread" then report_context("coroutines not supported as we cannot yield across boundaries") - elseif isnode(ti) then -- slow - flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e) + elseif isnode(ti) then -- slow | why {} here ? + if nodeflushmode then + local n = tonut(ti) + if n <= maxflushnodeindex then + flush(currentcatcodes,"{",ti,"}") + else + flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e) + end + else + flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e) + end else report_context("error: %a gets a weird argument %a",command,ti) end +-- else +-- local n = isnode(ti) +-- if n then +-- if nodeflushmode and n <= maxflushnodeindex then +-- flush(ti) +-- else +-- flush(currentcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e) +-- end +-- else +-- report_context("error: %a gets a weird argument %a",command,ti) +-- end +-- end end end end --- if performance really matters we can consider a compiler but it will never --- pay off - --- local function prtwriter(command,...) -- already optimized before call --- flush(prtcatcodes,command) --- for i=1,select("#",...) do --- local ti = (select(i,...)) --- if ti == nil then --- -- nothing --- elseif ti == "" then --- flush(prtcatcodes,"{}") --- else --- local tp = type(ti) --- if tp == "string" or tp == "number"then --- flush(prtcatcodes,"{",ti,"}") --- elseif tp == "function" then --- flush(prtcatcodes,s_cldl_argument_f,storefunction(ti),s_cldl_argument_e) --- elseif isnode(ti) then --- flush(prtcatcodes,s_cldl_argument_b,storenode(ti),s_cldl_argument_e) +local core + +if tokenflushmode then -- combine them + + local toks = tokens.cache + + context.tokenizedcs = toks + + core = setmetatableindex(function(parent,k) + local t + local f = function(first,...) + if not t then + t = toks[k] + end + if first == nil then + flush(t) + else + return writer(context,t,first,...) + end + end + parent[k] = f + return f + end) + +-- core = setmetatableindex(function(parent,k) +-- local t +-- local f = function(first,...) +-- if not t then +-- t = toks[k] +-- end +-- local f = function(first,...) +-- if first == nil then +-- flush(t) -- else --- report_context("fatal error: prt %a gets a weird argument %a",command,ti) +-- return writer(context,t,first,...) -- end -- end +-- parent[k] = f +-- if first == nil then +-- flush(t) +-- else +-- return writer(context,t,first,...) +-- end -- end --- end +-- parent[k] = f +-- return f +-- end) + + core.cs = setmetatableindex(function(parent,k) + local t + local f = function() + if not t then + t = toks[k] + end + flush(t) + end + parent[k] = f + return f + end) + +else + + context.tokenizedcs = false + + core = setmetatableindex(function(parent,k) + local c = "\\" .. k + local f = function(first,...) + if first == nil then + flush(currentcatcodes,c) + else + return writer(context,c,first,...) + end + end + parent[k] = f + return f + end) -local core = setmetatableindex(function(parent,k) - local c = "\\" .. k -- tostring(k) - local f = function(first,...) - if first == nil then + core.cs = setmetatableindex(function(parent,k) + local c = "\\" .. k -- tostring(k) + local f = function() flush(currentcatcodes,c) - else - return writer(context,c,first,...) end - end - parent[k] = f - return f -end) + parent[k] = f + return f + end) -core.cs = setmetatableindex(function(parent,k) - local c = "\\" .. k -- tostring(k) - local f = function() - flush(currentcatcodes,c) - end - parent[k] = f - return f -end) +end local indexer = function(parent,k) if type(k) == "string" then @@ -933,8 +1058,16 @@ local caller = function(parent,f,a,...) end elseif typ == "function" then -- ignored: a ... - flush(currentcatcodes,"{\\cldl",storefunction(f),"}") -- todo: ctx|prt|texcatcodes - -- flush(currentcatcodes,"{",storefunction(f),"}") -- todo: ctx|prt|texcatcodes + f = storefunction(f) + if tokenflushmode then + if newtoken then + flush(currentcatcodes,"{",newtoken(f,lua_expandable_call_token_code),"}") + else + flush(currentcatcodes,"{",t_cldl_luafunction,f,"}") + end + else + flush(currentcatcodes,s_cldl_argument_b,f,s_cldl_argument_e) -- todo: ctx|prt|texcatcodes + end elseif typ == "boolean" then if f then if a ~= nil then @@ -953,20 +1086,55 @@ local caller = function(parent,f,a,...) elseif typ == "thread" then report_context("coroutines not supported as we cannot yield across boundaries") elseif isnode(f) then -- slow - -- writenode(f) - flush(currentcatcodes,"\\cldl",storenode(f)," ") - -- flush(currentcatcodes,"",storenode(f)," ") + if nodeflushmode then + local n = tonut(f) + if n <= maxflushnodeindex then + flush(f) + else + flush(currentcatcodes,s_cldl_option_s,storenode(f)," ") + end + else + flush(currentcatcodes,s_cldl_option_s,storenode(f)," ") + end else report_context("error: %a gets a weird argument %a","context",f) end +-- else +-- local n = isnode(f) +-- if n then +-- if nodeflushmode and n <= maxflushnodeindex then +-- flush(f) +-- else +-- flush(currentcatcodes,s_cldl_option_s,storenode(f)," ") +-- end +-- else +-- report_context("error: %a gets a weird argument %a","context",f) +-- end +-- end end end -context.nodes = { +context.nodes = { -- todo store = storenode, flush = function(n) - flush(currentcatcodes,"\\cldl",storenode(n)," ") - -- flush(currentcatcodes,"",storenode(n)," ") + if nodeflushmode and tonut(n) <= maxflushnodeindex then + flush(n) + else + flush(currentcatcodes,d and s_cldl_option_d or s_cldl_option_s,storenode(n)," ") + end + end, +} + +context.nuts = { -- todo + store = function(n) + return storenode(tonut(n)) + end, + flush = function(n,d) + if nodeflushmode and n <= maxflushnodeindex then + flush(tonode(n)) + else + flush(currentcatcodes,d and s_cldl_option_d or s_cldl_option_s,storenode(tonode(n))," ") + end end, } @@ -1012,8 +1180,8 @@ local nofflushes = 0 local tracingpermitted = true local visualizer = lpeg.replacer { - { "\n","<>" }, - { "\r","<>" }, + { "\n", "<>" }, + { "\r", "<>" }, } statistics.register("traced context", function() @@ -1026,13 +1194,48 @@ statistics.register("traced context", function() end end) +local function userdata(argument) + if isnode(argument) then + return formatters["<< %s node %i>>"](nodes.nodecodes[argument.id],tonut(argument)) + end + if istoken(argument) then + local csname = argument.csname + if csname then + -- return formatters["<<\\%s>>"](csname) + return formatters["\\%s"](csname) + end + local cmdname = argument.cmdname + if cmdname == "lua_expandable_call" or cmdname == "lua_call" then + return "<>" -- argument.mode + end + return "<>" + end + return "<>" +end + + local tracedwriter = function(parent,...) -- also catcodes ? nofwriters = nofwriters + 1 local savedflush = flush local savedflushdirect = flushdirect -- unlikely to be used here - local t, n = { "w : - : " }, 1 + local t = { "w : - : " } + local n = 1 local traced = function(catcodes,...) -- todo: check for catcodes - local s = concat({...}) + local s = type(catcodes) == "number" and { ... } or { catcodes, ... } + for i=1,#s do + local argument = s[i] + local argtype = type(argument) + if argtype == "string" then + s[i] = lpegmatch(visualizer,argument) + elseif argtype == "number" then + s[i] = argument + elseif argtype == "userdata" then + s[i] = userdata(argument) + else + s[i] = formatters["<<%S>>"](argument) + end + end + s = concat(s) s = lpegmatch(visualizer,s) n = n + 1 t[n] = s @@ -1060,9 +1263,10 @@ end local traced = function(one,two,...) if two ~= nil then -- only catcodes if 'one' is number - local catcodes = type(one) == "number" and one + local catcodes = type(one) == "number" and one local arguments = catcodes and { two, ... } or { one, two, ... } - local collapsed, c = { formatters["f : %s : "](catcodes or '-') }, 1 + local collapsed = { formatters["f : %s : "](catcodes or '-') } + local c = 1 for i=1,#arguments do local argument = arguments[i] local argtype = type(argument) @@ -1071,6 +1275,8 @@ local traced = function(one,two,...) collapsed[c] = lpegmatch(visualizer,argument) elseif argtype == "number" then collapsed[c] = argument + elseif argtype == "userdata" then + collapsed[c] = userdata(argument) else collapsed[c] = formatters["<<%S>>"](argument) end @@ -1083,6 +1289,8 @@ local traced = function(one,two,...) currenttrace(formatters["f : - : %s"](lpegmatch(visualizer,one))) elseif argtype == "number" then currenttrace(formatters["f : - : %s"](one)) + elseif argtype == "userdata" then + currenttrace(formatters["F : - : %s"](userdata(one))) else currenttrace(formatters["f : - : <<%S>>"](one)) end @@ -1175,24 +1383,21 @@ do local sentinel = string.char(26) -- ASCII SUB character : endoffileasciicode : ignorecatcode local level = 0 - local function collect(c,...) -- can be optimized - -- snippets - for i=1,select("#",...) do + local function collect(c,a,...) -- can be optimized + if type(c) == "userdata" then nofcollected = nofcollected + 1 - collected[nofcollected] = (select(i,...)) + -- collected[nofcollected] = userdata(c) + collected[nofcollected] = "\\" .. c.csname + end + if a then + for i=1,select("#",a,...) do + local c = select(i,a,...) + nofcollected = nofcollected + 1 + collected[nofcollected] = type(c) == "userdata" and userdata(c) or c + end end end - -- local function collectdirect(c,...) -- can be optimized - -- -- lines - -- for i=1,select("#",...) do - -- n = n + 1 - -- t[n] = (select(i,...)) - -- n = n + 1 - -- t[n] = "\r" - -- end - -- end - local collectdirect = collect local permitted = true @@ -1224,34 +1429,39 @@ do end end -end - --- + local findtexfile = resolvers.findtexfile + local findfile = resolvers.findfile -function context.runfile(filename) - local foundname = resolvers.findtexfile(file.addsuffix(filename,"cld")) or "" - if foundname ~= "" then - local ok = dofile(foundname) - if type(ok) == "function" then - if trace_cld then - report_context("begin of file %a (function call)",foundname) - end - ok() - if trace_cld then - report_context("end of file %a (function call)",foundname) + function context.runfile(filename) + local foundname = findtexfile(file.addsuffix(filename,"cld")) or "" + if foundname ~= "" then + local ok = dofile(foundname) + if type(ok) == "function" then + if trace_cld then + report_context("begin of file %a (function call)",foundname) + end + ok() + if trace_cld then + report_context("end of file %a (function call)",foundname) + end + elseif ok then + report_context("file %a is processed and returns true",foundname) + else + report_context("file %a is processed and returns nothing",foundname) end - elseif ok then - report_context("file %a is processed and returns true",foundname) else - report_context("file %a is processed and returns nothing",foundname) + report_context("unknown file %a",filename) end - else - report_context("unknown file %a",filename) end -end -function context.loadfile(filename) - context(stripstring(loaddata(resolvers.findfile(filename)))) + function context.loadfile(filename) + context(stripstring(loaddata(findfile(filename)))) + end + + function context.loadviafile(filename) + viafile(stripstring(loaddata(findfile(filename)))) + end + end -- some functions @@ -1270,7 +1480,7 @@ do local function indexer(parent,k) local f = function(...) - local a = { ... } + local a = { ... } -- this also freezes ... return function() -- return context[k](unpack(a)) return core[k](unpack(a)) @@ -1295,46 +1505,48 @@ do end -do - - -- context.nested (todo: lines), creates strings - - local nested = { } - - local function indexer(parent,k) -- not ok when traced - local f = function(...) - local t, savedflush, n = { }, flush, 0 - flush = function(c,f,s,...) -- catcodes are ignored - n = n + 1 - t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 - end - -- context[k](...) - core[k](...) - flush = savedflush - return concat(t) - end - parent[k] = f - return f - end - - local function caller(parent,...) - local t, savedflush, n = { }, flush, 0 - flush = function(c,f,s,...) -- catcodes are ignored - n = n + 1 - t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 - end - -- context(...) - defaultcaller(context,...) - flush = savedflush - return concat(t) - end - - setmetatableindex(nested,indexer) - setmetatablecall (nested,caller) - - context.nested = nested +-- do +-- +-- -- context.nested (todo: lines), creates strings +-- +-- local nested = { } +-- +-- local function indexer(parent,k) -- not ok when traced +-- local f = function(...) +-- local t, savedflush, n = { }, flush, 0 +-- flush = function(c,f,s,...) -- catcodes are ignored +-- n = n + 1 +-- t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 +-- end +-- -- context[k](...) +-- core[k](...) +-- flush = savedflush +-- return concat(t) +-- end +-- parent[k] = f +-- return f +-- end +-- +-- local function caller(parent,...) +-- local t, savedflush, n = { }, flush, 0 +-- flush = function(c,f,s,...) -- catcodes are ignored +-- n = n + 1 +-- t[n] = s and concat{f,s,...} or f -- optimized for #args == 1 +-- end +-- -- context(...) +-- defaultcaller(context,...) +-- flush = savedflush +-- return concat(t) +-- end +-- +-- setmetatableindex(nested,indexer) +-- setmetatablecall (nested,caller) +-- +-- context.nested = nested +-- +-- end -end +context.nested = context.delayed -- verbatim @@ -1360,14 +1572,22 @@ function context.newindexer(catcodes,cmdcodes) contentcatcodes = savedcatcodes end - handler.cs = setmetatableindex(function(parent,k) - local c = "\\" .. k -- tostring(k) - local f = function() - flush(cmdcodes,c) - end - parent[k] = f - return f - end) + if tokenflushmode then + + handler.cs = core.cs + + else + + handler.cs = setmetatableindex(function(parent,k) + local c = "\\" .. k -- tostring(k) + local f = function() + flush(cmdcodes,c) + end + parent[k] = f + return f + end) + + end setmetatableindex(handler,indexer) setmetatablecall (handler,caller) @@ -1420,21 +1640,51 @@ do end end - local function indexer(parent,k) - if type(k) == "string" then - local c = "\\" .. k - local f = function(first,...) - if first == nil then - flush(currentcatcodes,c) - else - return formattedflush(parent,c,first,...) + local indexer + + if tokenflushmode then -- combine them + + local toks = tokens.cache + + indexer = function(parent,k) + if type(k) == "string" then + local t + local f = function(first,...) + if not t then + t = toks[k] + end + if first == nil then + flush(t) + else + return formattedflush(parent,t,first,...) + end + end + parent[k] = f + return f + else + return context -- catch + end + end + + else + + indexer = function(parent,k) + if type(k) == "string" then + local c = "\\" .. k + local f = function(first,...) + if first == nil then + flush(currentcatcodes,c) + else + return formattedflush(parent,c,first,...) + end end + parent[k] = f + return f + else + return context -- catch end - parent[k] = f - return f - else - return context -- catch end + end -- formatted([catcodes,]format[,...]) diff --git a/tex/context/base/mkiv/cldf-ini.mkiv b/tex/context/base/mkiv/cldf-ini.mkiv index 27ce42aa2..29fb15d68 100644 --- a/tex/context/base/mkiv/cldf-ini.mkiv +++ b/tex/context/base/mkiv/cldf-ini.mkiv @@ -13,6 +13,8 @@ \writestatus{loading}{ConTeXt Lua Documents / Initialization} +\newcount\trialtypesettingstate % gets aliased at the Lua end + \registerctxluafile{cldf-ini}{} %D With each new update of \MKIV\ we can join Within Temptation in @@ -41,14 +43,16 @@ % \fi \let\cldl\luafunction +\let\cldd\lateluafunction % \catcode`=\activecatcode \let\luafunction % saves 10% on the call -% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode1=\activecatcode \global\let^^A=\cldf -% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode2=\activecatcode \global\let^^B=\cldn +% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode1=\activecatcode \glet^^A=\cldf +% \catcodetable\ctxcatcodes \catcode`^=\superscriptcatcode\catcode2=\activecatcode \glet^^B=\cldn \normalprotected\def\cldprocessfile#1{\directlua{context.runfile("#1")}} \def\cldloadfile #1{\directlua{context.loadfile("#1")}} + \def\cldloadviafile#1{\directlua{context.loadviafile("#1")}} \def\cldcontext #1{\directlua{context(#1)}} \def\cldcommand #1{\directlua{context.#1}} % \def\cldverbatim #1{\directlua{context.verbatim.#1}} % maybe make verbatim global diff --git a/tex/context/base/mkiv/cldf-int.lua b/tex/context/base/mkiv/cldf-int.lua index a97eadf35..52cfea8d0 100644 --- a/tex/context/base/mkiv/cldf-int.lua +++ b/tex/context/base/mkiv/cldf-int.lua @@ -88,9 +88,10 @@ function interfaces.definecommand(name,specification) -- name is optional else -- we could flush immediate but tracing is bad then stack[name] = { } - local opt, done = 0, false + local opt = 0 + local done = false local snippets = { } -- we can reuse it - local mkivdo = "\\mkivdo" .. name -- maybe clddo + local mkivdo = "\\mkivdo" .. name -- maybe clddo snippets[#snippets+1] = "\\def" snippets[#snippets+1] = mkivdo for i=1,na do diff --git a/tex/context/base/mkiv/cldf-scn.lua b/tex/context/base/mkiv/cldf-scn.lua index ccf1f01c6..d0b16e034 100644 --- a/tex/context/base/mkiv/cldf-scn.lua +++ b/tex/context/base/mkiv/cldf-scn.lua @@ -25,6 +25,7 @@ local scanners = interfaces.scanners local register = interfaces.registerscanner local compile = tokens.compile or function() end +local presets = tokens.presets local dummy = function() end @@ -47,6 +48,10 @@ function interfaces.implement(specification) if name == "" then name = nil end + local p = arguments and presets[arguments] + if p then + arguments = p + end local scanner local resetter = onlyonce and name and commands.ctxresetter(name) if resetter then @@ -72,7 +77,7 @@ function interfaces.implement(specification) if scanners[name] and not specification.overload then report("warning: 'scanners.%s' is redefined",name) end --- scanners[name] = scanner + -- scanners[name] = scanner -- we now use: register(name,scanner,specification.protected,specification.public,specification.call) if private then return diff --git a/tex/context/base/mkiv/cldf-ver.lua b/tex/context/base/mkiv/cldf-ver.lua index 3710b2415..7a1c81301 100644 --- a/tex/context/base/mkiv/cldf-ver.lua +++ b/tex/context/base/mkiv/cldf-ver.lua @@ -13,32 +13,69 @@ if not modules then modules = { } end modules ['cldf-ver'] = { local concat, tohandle = table.concat, table.tohandle local splitlines, strip = string.splitlines, string.strip local tostring, type = tostring, type +local assignbuffer = buffers.assign local context = context -local function flush(...) - context(concat{...,"\r"}) -- was \n +context.tobuffer = assignbuffer -- (name,str,catcodes) + +function context.tolines(str,strip) + local lines = type(str) == "string" and splitlines(str) or str + for i=1,#lines do + if strip then + context(strip(lines[i]) .. " ") + else + context(lines[i] .. " ") + end + end end -local function t_tocontext(...) - context.starttyping { "typing" } -- else [1] is intercepted - context.pushcatcodes("verbatim") - tohandle(flush,...) -- ok? - context.stoptyping() - context.popcatcodes() +-- local function flush(...) +-- context(concat { ..., "\r" }) -- was \n +-- end +-- +-- somehow this doesn't work any longer .. i need to figure out why +-- +-- local function t_tocontext(t) +-- context.starttyping { "typing" } -- else [1] is intercepted +-- context.pushcatcodes("verbatim") +-- -- tohandle(flush,...) +-- context(table.serialize(t)) +-- context.stoptyping() +-- context.popcatcodes() +-- end +-- +-- local function s_tocontext(first,second,...) -- we need to catch {\} +-- context.type() +-- context("{") +-- context.pushcatcodes("verbatim") +-- if second then +-- context(concat({ first, second, ... }, " ")) +-- else +-- context(first) -- no need to waste a { } +-- end +-- context.popcatcodes() +-- context("}") +-- end + +local t_buffer = { "t_o_c_o_n_t_e_x_t" } +local t_typing = { "typing" } +local t_type = { "type" } + +local function flush(s,inline) + assignbuffer("t_o_c_o_n_t_e_x_t",s) + context[inline and "typeinlinebuffer" or "typebuffer"](t_buffer) + context.resetbuffer(t_buffer) end -local function s_tocontext(first,...) -- we need to catch {\} - context.type() - context("{") - context.pushcatcodes("verbatim") - if first then - context(first) -- no need to waste a { } - else - context(concat({first,...}," ")) - end - context.popcatcodes() - context("}") +local function t_tocontext(t) + local s = table.serialize(t) + context(function() flush(s,false) end) +end + +local function s_tocontext(first,second,...) -- we need to catch {\} + local s = second and concat({ first, second, ... }, " ") or first + context(function() flush(s,true) end) end local function b_tocontext(b) @@ -74,15 +111,3 @@ end) context.tocontext = tocontext -context.tobuffer = buffers.assign -- (name,str,catcodes) - -function context.tolines(str,strip) - local lines = type(str) == "string" and splitlines(str) or str - for i=1,#lines do - if strip then - context(strip(lines[i]) .. " ") - else - context(lines[i] .. " ") - end - end -end diff --git a/tex/context/base/mkiv/colo-imp-crayola.mkiv b/tex/context/base/mkiv/colo-imp-crayola.mkiv index dbae02d5a..ae955ec1c 100644 --- a/tex/context/base/mkiv/colo-imp-crayola.mkiv +++ b/tex/context/base/mkiv/colo-imp-crayola.mkiv @@ -1,9 +1,9 @@ %D \module -%D [ file=colo-imp-crayola -%D version=2016.03.21, -%D title=\CONTEXT\ Color Macros, -%D subtitle=Crayola, -%D author=Alan Braslau] +%D [ file=colo-imp-crayola +%D version=2016.03.21, +%D title=\CONTEXT\ Color Macros, +%D subtitle=Crayola, +%D author=Alan Braslau] %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/tex/context/base/mkiv/colo-imp-svg.mkiv b/tex/context/base/mkiv/colo-imp-svg.mkiv new file mode 100644 index 000000000..f39adaa98 --- /dev/null +++ b/tex/context/base/mkiv/colo-imp-svg.mkiv @@ -0,0 +1,164 @@ +%D \module +%D [ file=colo-imp-svg, +%D version=2018.09.17, +%D title=\CONTEXT\ Color Macros, +%D subtitle=SVG] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA, See mreadme.pdf for +%C details. + +%D This module was prepared by an user who wants to stay anonymous and is +%D derived from \url {http://www.december.com/html/spec/colorsvghex.html}. + +\startprotectedcolors + +\definecolor [black] [h=000000] +\definecolor [navy] [h=000080] +\definecolor [darkblue] [h=00008B] +\definecolor [mediumblue] [h=0000CD] +\definecolor [blue] [h=0000FF] +\definecolor [darkgreen] [h=006400] +\definecolor [green] [h=008000] +\definecolor [teal] [h=008080] +\definecolor [darkcyan] [h=008B8B] +\definecolor [deepskyblue] [h=00BFFF] +\definecolor [darkturquoise] [h=00CED1] +\definecolor [mediumspringgreen] [h=00FA9A] +\definecolor [lime] [h=00FF00] +\definecolor [springgreen] [h=00FF7F] +\definecolor [cyan] [h=00FFFF] +\definecolor [aqua] [h=00FFFF] +\definecolor [midnightblue] [h=191970] +\definecolor [dodgerblue] [h=1E90FF] +\definecolor [lightseagreen] [h=20B2AA] +\definecolor [forestgreen] [h=228B22] +\definecolor [seagreen] [h=2E8B57] +\definecolor [darkslategray] [h=2F4F4F] +\definecolor [darkslategrey] [h=2F4F4F] +\definecolor [limegreen] [h=32CD32] +\definecolor [mediumseagreen] [h=3CB371] +\definecolor [turquoise] [h=40E0D0] +\definecolor [royalblue] [h=4169E1] +\definecolor [steelblue] [h=4682B4] +\definecolor [darkslateblue] [h=483D8B] +\definecolor [mediumturquoise] [h=48D1CC] +\definecolor [indigo] [h=4B0082] +\definecolor [darkolivegreen] [h=556B2F] +\definecolor [cadetblue] [h=5F9EA0] +\definecolor [cornflowerblue] [h=6495ED] +\definecolor [mediumaquamarine] [h=66CDAA] +\definecolor [dimgrey] [h=696969] +\definecolor [dimgray] [h=696969] +\definecolor [slateblue] [h=6A5ACD] +\definecolor [olivedrab] [h=6B8E23] +\definecolor [slategrey] [h=708090] +\definecolor [slategray] [h=708090] +\definecolor [lightslategray] [h=778899] +\definecolor [lightslategrey] [h=778899] +\definecolor [mediumslateblue] [h=7B68EE] +\definecolor [lawngreen] [h=7CFC00] +\definecolor [chartreuse] [h=7FFF00] +\definecolor [aquamarine] [h=7FFFD4] +\definecolor [maroon] [h=800000] +\definecolor [purple] [h=800080] +\definecolor [olive] [h=808000] +\definecolor [gray] [h=808080] +\definecolor [grey] [h=808080] +\definecolor [skyblue] [h=87CEEB] +\definecolor [lightskyblue] [h=87CEFA] +\definecolor [blueviolet] [h=8A2BE2] +\definecolor [darkred] [h=8B0000] +\definecolor [darkmagenta] [h=8B008B] +\definecolor [saddlebrown] [h=8B4513] +\definecolor [darkseagreen] [h=8FBC8F] +\definecolor [lightgreen] [h=90EE90] +\definecolor [mediumpurple] [h=9370DB] +\definecolor [darkviolet] [h=9400D3] +\definecolor [palegreen] [h=98FB98] +\definecolor [darkorchid] [h=9932CC] +\definecolor [yellowgreen] [h=9ACD32] +\definecolor [sienna] [h=A0522D] +\definecolor [brown] [h=A52A2A] +\definecolor [darkgray] [h=A9A9A9] +\definecolor [darkgrey] [h=A9A9A9] +\definecolor [lightblue] [h=ADD8E6] +\definecolor [greenyellow] [h=ADFF2F] +\definecolor [paleturquoise] [h=AFEEEE] +\definecolor [lightsteelblue] [h=B0C4DE] +\definecolor [powderblue] [h=B0E0E6] +\definecolor [firebrick] [h=B22222] +\definecolor [darkgoldenrod] [h=B8860B] +\definecolor [mediumorchid] [h=BA55D3] +\definecolor [rosybrown] [h=BC8F8F] +\definecolor [darkkhaki] [h=BDB76B] +\definecolor [silver] [h=C0C0C0] +\definecolor [mediumvioletred] [h=C71585] +\definecolor [indianred] [h=CD5C5C] +\definecolor [peru] [h=CD853F] +\definecolor [chocolate] [h=D2691E] +\definecolor [tan] [h=D2B48C] +\definecolor [lightgray] [h=D3D3D3] +\definecolor [lightgrey] [h=D3D3D3] +\definecolor [thistle] [h=D8BFD8] +\definecolor [orchid] [h=DA70D6] +\definecolor [goldenrod] [h=DAA520] +\definecolor [palevioletred] [h=DB7093] +\definecolor [crimson] [h=DC143C] +\definecolor [gainsboro] [h=DCDCDC] +\definecolor [plum] [h=DDA0DD] +\definecolor [burlywood] [h=DEB887] +\definecolor [lightcyan] [h=E0FFFF] +\definecolor [lavender] [h=E6E6FA] +\definecolor [darksalmon] [h=E9967A] +\definecolor [violet] [h=EE82EE] +\definecolor [palegoldenrod] [h=EEE8AA] +\definecolor [lightcoral] [h=F08080] +\definecolor [khaki] [h=F0E68C] +\definecolor [aliceblue] [h=F0F8FF] +\definecolor [honeydew] [h=F0FFF0] +\definecolor [azure] [h=F0FFFF] +\definecolor [sandybrown] [h=F4A460] +\definecolor [wheat] [h=F5DEB3] +\definecolor [beige] [h=F5F5DC] +\definecolor [whitesmoke] [h=F5F5F5] +\definecolor [mintcream] [h=F5FFFA] +\definecolor [ghostwhite] [h=F8F8FF] +\definecolor [salmon] [h=FA8072] +\definecolor [antiquewhite] [h=FAEBD7] +\definecolor [linen] [h=FAF0E6] +\definecolor [lightgoldenrodyellow] [h=FAFAD2] +\definecolor [oldlace] [h=FDF5E6] +\definecolor [red] [h=FF0000] +\definecolor [fuchsia] [h=FF00FF] +\definecolor [magenta] [h=FF00FF] +\definecolor [deeppink] [h=FF1493] +\definecolor [orangered] [h=FF4500] +\definecolor [tomato] [h=FF6347] +\definecolor [hotpink] [h=FF69B4] +\definecolor [coral] [h=FF7F50] +\definecolor [darkorange] [h=FF8C00] +\definecolor [lightsalmon] [h=FFA07A] +\definecolor [orange] [h=FFA500] +\definecolor [lightpink] [h=FFB6C1] +\definecolor [pink] [h=FFC0CB] +\definecolor [gold] [h=FFD700] +\definecolor [peachpuff] [h=FFDAB9] +\definecolor [navajowhite] [h=FFDEAD] +\definecolor [moccasin] [h=FFE4B5] +\definecolor [bisque] [h=FFE4C4] +\definecolor [mistyrose] [h=FFE4E1] +\definecolor [blanchedalmond] [h=FFEBCD] +\definecolor [papayawhip] [h=FFEFD5] +\definecolor [lavenderblush] [h=FFF0F5] +\definecolor [seashell] [h=FFF5EE] +\definecolor [cornsilk] [h=FFF8DC] +\definecolor [lemonchiffon] [h=FFFACD] +\definecolor [floralwhite] [h=FFFAF0] +\definecolor [snow] [h=FFFAFA] +\definecolor [yellow] [h=FFFF00] +\definecolor [lightyellow] [h=FFFFE0] +\definecolor [ivory] [h=FFFFF0] +\definecolor [white] [h=FFFFFF] + +\stopprotectedcolors diff --git a/tex/context/base/mkiv/colo-ini.lua b/tex/context/base/mkiv/colo-ini.lua index 921612b0f..3c8d23abc 100644 --- a/tex/context/base/mkiv/colo-ini.lua +++ b/tex/context/base/mkiv/colo-ini.lua @@ -43,6 +43,7 @@ local texsetattribute = tex.setattribute local texgetattribute = tex.getattribute local texgetcount = tex.getcount local texgettoks = tex.gettoks +local texgetmacro = tokens.getters.macro local a_color = attributes.private('color') local a_transparency = attributes.private('transparency') @@ -273,7 +274,9 @@ local function forcedmodel(model) -- delayed till the backend but mp directly return 2 end elseif model == 5 then -- spot - if cmyk_okay then + if spot_okay then + return 5 + elseif cmyk_okay then return 4 elseif rgb_okay then return 3 @@ -309,7 +312,8 @@ local function definetransparency(name,n,global) end local settings = settings_to_hash_strict(n) if settings then - local a, t = settings.a, settings.t + local a = settings.a + local t = settings.t if a and t then definetransparent(name, transparencies.register(name,transparent[a] or tonumber(a) or 1,tonumber(t) or 1), global) else @@ -440,16 +444,23 @@ local function defineprocesscolor(name,str,global,freeze) -- still inconsistent else local settings = settings_to_hash_strict(str) if settings then - local r, g, b = settings.r, settings.g, settings.b + local r = settings.r + local g = settings.g + local b = settings.b if r or g or b then -- we can consider a combined rgb cmyk s definition definecolor(name, register_color(name,'rgb', tonumber(r) or 0, tonumber(g) or 0, tonumber(b) or 0), global) else - local c, m, y, k = settings.c, settings.m, settings.y, settings.k + local c = settings.c + local m = settings.m + local y = settings.y + local k = settings.k if c or m or y or k then definecolor(name, register_color(name,'cmyk',tonumber(c) or 0, tonumber(m) or 0, tonumber(y) or 0, tonumber(k) or 0), global) else - local h, s, v = settings.h, settings.s, settings.v + local h = settings.h + local s = settings.s + local v = settings.v if v then r, g, b = colors.hsvtorgb(tonumber(h) or 0, tonumber(s) or 1, tonumber(v) or 1) -- maybe later native definecolor(name, register_color(name,'rgb',r,g,b), global) @@ -468,7 +479,8 @@ local function defineprocesscolor(name,str,global,freeze) -- still inconsistent end end end - local a, t = settings.a, settings.t + local a = settings.a + local t = settings.t if a and t then definetransparent(name, transparencies.register(name,transparent[a] or tonumber(a) or 1,tonumber(t) or 1), global) elseif colors.couple then @@ -520,7 +532,8 @@ local function definespotcolor(name,parent,str,global) do_registerspotcolor(parent,cp,t.e,1,"",tp) -- p not really needed, only diagnostics if name and name ~= "" then definecolor(name,register_color(name,'spot',parent,1,"",tp),true) - local ta, tt = t.a, t.t + local ta = t.a + local tt = t.t if ta and tt then definetransparent(name, transparencies.register(name,transparent[ta] or tonumber(ta) or 1,tonumber(tt) or 1), global) elseif colors.couple then @@ -564,7 +577,7 @@ local function f(i,colors,fraction) return otf end -local function definemixcolor(makename,name,fractions,cs,global,freeze) +local function definemixcolor(makecolor,name,fractions,cs,global,freeze) local values = { } for i=1,#cs do -- do fraction in here local v = colorvalues[cs[i]] @@ -592,12 +605,15 @@ local function definemixcolor(makename,name,fractions,cs,global,freeze) end definecolor(name,ca,global,freeze) else - report_colors("invalid specification of components for color %a",makename) + report_colors("invalid specification of components for color %a",makecolor) end end local function definemultitonecolor(name,multispec,colorspec,selfspec) - local dd, pp, nn, max = { }, { }, { }, 0 + local dd = { } + local pp = { } + local nn = { } + local max = 0 for k,v in gmatch(multispec,"([^=,]+)=([^%,]*)") do -- use settings_to_array max = max + 1 dd[max] = k @@ -608,12 +624,12 @@ local function definemultitonecolor(name,multispec,colorspec,selfspec) nn = concat(nn,'_') local parent = gsub(lower(nn),"[^%d%a%.]+","_") if not colorspec or colorspec == "" then + -- this can happens when we come from metapost local cc = { } for i=1,max do --- cc[i] = l_color[dd[i]] cc[i] = resolvedname(dd[i]) end - definemixcolor(name,parent,pp,cc,global,freeze) -- can become local + definemixcolor(name,parent,pp,cc,true,true) else if selfspec ~= "" then colorspec = colorspec .. "," .. selfspec @@ -645,24 +661,29 @@ colors.definemultitonecolor = definemultitonecolor -- that we cannot cast .. so we really need to use (s,s,s) for gray in order -- to be able to map onto 'color' -local function mpcolor(model,ca,ta,default) +local function mpcolor(model,ca,ta,default,name) local cv = colorvalues[ca] if cv then local tv = transparencyvalues[ta] + -- maybe move the 5 logic into the forcedmodel call + local cm = cv[1] if model == 1 then - model = cv[1] + model = cm end model = forcedmodel(model) + if cm == 5 and model == 4 then + model = 5 -- a cheat but ok as spot colors have a representation + end if tv then if model == 2 then return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5]) elseif model == 3 then return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5]) elseif model == 4 then - return formatters["transparent(%s,%s,cmyk(%s,%s,%s,%s))"](tv[1],tv[2],cv[6],cv[7],cv[8],cv[9]) + return formatters["transparent(%s,%s,(%s,%s,%s,%s))"](tv[1],tv[2],cv[6],cv[7],cv[8],cv[9]) elseif model == 5 then -- return formatters['transparent(%s,%s,multitonecolor("%s",%s,"%s","%s"))'](tv[1],tv[2],cv[10],cv[11],cv[12],cv[13]) - return formatters['transparent(%s,%s,namedcolor("%s"))'](tv[1],tv[2],cv[10]) + return formatters['transparent(%s,%s,namedcolor("%s"))'](tv[1],tv[2],name or cv[10]) else -- see ** in meta-ini.mkiv: return formatters["transparent(%s,%s,(%s))"](tv[1],tv[2],cv[2]) return formatters["transparent(%s,%s,(%s,%s,%s))"](tv[1],tv[2],cv[3],cv[4],cv[5]) end @@ -672,10 +693,9 @@ local function mpcolor(model,ca,ta,default) elseif model == 3 then return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5]) elseif model == 4 then - return formatters["cmyk(%s,%s,%s,%s)"](cv[6],cv[7],cv[8],cv[9]) + return formatters["(%s,%s,%s,%s)"](cv[6],cv[7],cv[8],cv[9]) elseif model == 5 then - -- return formatters['multitonecolor("%s",%s,"%s","%s")'](cv[10],cv[11],cv[12],cv[13]) - return formatters['namedcolor("%s")'](cv[10]) + return formatters['namedcolor("%s")'](name or cv[10]) else -- see ** in meta-ini.mkiv: return formatters["%s"]((cv[2])) return formatters["(%s,%s,%s)"](cv[3],cv[4],cv[5]) end @@ -698,7 +718,8 @@ local paletnamespace = getnamespace("colorpalet") local function namedcolorattributes(name) local space = texgetattribute(a_colormodel) - local prefix = texgettoks("t_colo_prefix") + ----- prefix = texgettoks("t_colo_prefix") + local prefix = texgetmacro("currentcolorprefix") local color if prefix ~= "" then color = valid[prefix..name] @@ -734,7 +755,8 @@ end colors.namedcolorattributes = namedcolorattributes -- can be used local local function mpnamedcolor(name) - return mpcolor(namedcolorattributes(name)) + local model, ca, ta = namedcolorattributes(name) + return mpcolor(model,ca,ta,nil,name) end local function mpoptions(model,ca,ta,default) -- will move to mlib-col .. not really needed @@ -1090,7 +1112,7 @@ implement { implement { name = "defineprocesscolordummy", actions = defineprocesscolor, - arguments = { "'d_u_m_m_y'", "string", false, false } + arguments = { "'c_o_l_o_r'", "string", false, false } } implement { diff --git a/tex/context/base/mkiv/colo-ini.mkiv b/tex/context/base/mkiv/colo-ini.mkiv index daee8ada6..7079322f7 100644 --- a/tex/context/base/mkiv/colo-ini.mkiv +++ b/tex/context/base/mkiv/colo-ini.mkiv @@ -592,22 +592,22 @@ % \the\everysetuppalet % \colo_helpers_initialize_maintextcolor} -\newtoks\t_colo_prefix % used in mp interface +% \newtoks\t_colo_prefix % used in mp interface \def\colo_palets_setup[#1]% {\edef\currentcolorpalet{#1}% \ifx\currentcolorpalet\empty % seems to be a reset \let\currentcolorprefix\empty - \t_colo_prefix\emptytoks + %\t_colo_prefix\emptytoks \else\ifcsname\??paletlist\currentcolorpalet\endcsname \edef\currentcolorprefix{#1:}% - \t_colo_prefix\expandafter{\currentcolorprefix}% + %\t_colo_prefix\expandafter{\currentcolorprefix}% \else \colo_helpers_show_message\m!colors7\currentcolorpalet \let\currentcolorpalet\empty \let\currentcolorprefix\empty - \t_colo_prefix\emptytoks + %\t_colo_prefix\emptytoks \fi\fi \the\everysetuppalet \colo_helpers_initialize_maintextcolor} @@ -782,7 +782,12 @@ % Since we couple definitions, we could stick to one test. Todo. Same for mpcolor. -\def\v_colo_dummy_name{d_u_m_m_y} +\def\v_colo_dummy_name{c_o_l_o_r} + +\letvalue{\??colorattribute \v_colo_dummy_name}\empty +\letvalue{\??transparencyattribute\v_colo_dummy_name}\empty +\letvalue{\??colorsetter \v_colo_dummy_name}\empty +\letvalue{\??transparencysetter \v_colo_dummy_name}\empty \letvalue{\??colorsetter -}\empty % used? \letvalue{\??transparencysetter-}\empty % used? @@ -942,7 +947,7 @@ \def\colo_basics_defined_and_activated#1% {\clf_defineprocesscolordummy{#1}% we could pass dummy here too - \colo_basics_synchronize{d_u_m_m_y}% + \colo_basics_synchronize{\v_colo_dummy_name}% \colo_helpers_activate_dummy} \def\colo_basics_define_process @@ -1058,7 +1063,7 @@ %D Here is a more efficient helper for pgf: %D -%D \starttying +%D \starttyping %D \startluacode %D function commands.pgfxcolorspec(ca) -- {}{}{colorspace}{list} %D local cv = attributes.colors.values[ca] diff --git a/tex/context/base/mkiv/colo-run.lua b/tex/context/base/mkiv/colo-run.lua index 2e4cca5ab..2e7ae08e3 100644 --- a/tex/context/base/mkiv/colo-run.lua +++ b/tex/context/base/mkiv/colo-run.lua @@ -14,7 +14,7 @@ local commands = commands local context = context local colors = attributes.colors -local private = table.tohash { "d_u_m_m_y", "maintextcolor", "themaintextcolor" } +local private = table.tohash { "c_o_l_o_r", "maintextcolor", "themaintextcolor" } function commands.showcolorset(name) local set = colors.setlist(name) diff --git a/tex/context/base/mkiv/cont-log.mkiv b/tex/context/base/mkiv/cont-log.mkiv index 8b4660f3a..f9fc6a8f7 100644 --- a/tex/context/base/mkiv/cont-log.mkiv +++ b/tex/context/base/mkiv/cont-log.mkiv @@ -133,7 +133,7 @@ \let\logofont\nullfont -\loadmapfile[original-base.map] % stil needed? not if we assume afm +% \loadmapfile[original-base.map] % stil needed? not if we assume afm \unexpanded\def\setMFPfont% more sensitive for low level changes {\font\logofont=logo% @@ -205,7 +205,7 @@ \unexpanded\def\Lua {Lua} \unexpanded\def\luajitTeX{luajit\wordboundary\TeX} \unexpanded\def\metaTeX {meta\wordboundary\TeX} -\unexpanded\def\XeTeX {X\lower.5\exheight\hbox{\kern-.15\emwidth\mirror{E}}\kern-.1667\emwidth\TeX} +%unexpanded\def\XeTeX {X\lower.5\exheight\hbox{\kern-.15\emwidth\mirror{E}}\kern-.1667\emwidth\TeX} % Adapted from a patch by Mojca: @@ -237,40 +237,6 @@ \let\LuaTeX \luaTeX \let\XETEX \XeTeX -% \unexpanded\def\MkApproved % joke, not used so it might move -% {\dontleavehmode\rotate -% [\c!rotation={\ifnum\texengine=\luatexengine\cldcontext{45-45*\the\luatexversion/100}\else0\fi}, -% \c!align=\v!middle, -% \c!foregroundstyle=\v!type, -% \c!foregroundcolor=darkred, -% \c!frame=\v!on, -% \c!offset=1ex, -% \c!background=\v!color, -% \c!backgroundcolor=lightgray, -% \c!framecolor=darkred, -% \c!rulethickness=2pt] -% {Mk\ifnum\texengine=\luatexengine IV\else II\fi\\approved}} - -% \unexpanded\def\luaTeX -% {\dontleavehmode\begingroup -% Lua% -% \setbox0\hbox{oT}% -% \setbox2\hbox{o\kern0ptT}% -% \ifdim\wd0=\wd2 -% \setbox0\hbox dir TRT{To}% -% \setbox2\hbox{T\kern0pto}% -% \hskip\dimexpr\wd0-\wd2\relax -% \fi -% \TeX -% \endgroup} -% -% a further iteration from the list, patched again - -% \ifx\fontalternative\s!it -\else -% \ifx\fontalternative\s!sl -\else -% \ifx\fontalternative\s!bi -\else -% \ifx\fontalternative\s!bs -\fi\fi\fi\fi - \unexpanded\def\LuaTeX {\dontleavehmode \begingroup @@ -317,6 +283,8 @@ \unexpanded\def\MPIV{MpIV} \unexpanded\def\MPVI{MpVI} +\unexpanded\def\LMTX{lmtx} + \appendtoks \def\ConTeXt {ConTeXt}% \def\MetaPost {MetaPost}% diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 9cb893260..f8abf6fad 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,13 +11,27 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2018.04.04 00:51} +\newcontextversion{2019.02.22 19:35} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. \unprotect -% \writestatus\m!system{beware: some patches loaded from cont-new.mkiv} +\writestatus\m!system{beware: some patches loaded from cont-new.mkiv} + +% math-ini.mkiv + +\ifdefined\t \else \unexpanded\def\t{\mathortext\text\mathtext} \fi +\ifdefined\w \else \unexpanded\def\w{\mathortext\word\mathword} \fi + +\appendtoks + \let\t\mathtext + \let\w\mathword +\to \everymathematics + +% \let\assumelongusagecs\relax % todo: fails on legends-001.tex + +% done \protect \endinput diff --git a/tex/context/base/mkiv/cont-run.lua b/tex/context/base/mkiv/cont-run.lua index 9bd252e60..2634654fe 100644 --- a/tex/context/base/mkiv/cont-run.lua +++ b/tex/context/base/mkiv/cont-run.lua @@ -142,6 +142,7 @@ trackers.register("sandbox.tracecalls",sandbox.logcalls) trackers.register("sandbox.tracefiles",sandbox.logfiles) local sandboxing = environment.arguments.sandbox +local debugging = environment.arguments.debug if sandboxing then @@ -170,15 +171,33 @@ if sandboxing then \let\normalprimitive\relax ]] -end + debug = { + traceback = traceback, + } -local function processjob() + package.loaded.debug = debug - environment.initializefilenames() -- todo: check if we really need to pre-prep the filename +elseif debugging then + + -- we keep debug + +else + + debug = { + traceback = traceback, + getinfo = getinfo, + sethook = sethook, + } + + package.loaded.debug = debug + +end + +local preparejob preparejob = function() -- tricky: we need a hook for this local arguments = environment.arguments - local suffix = environment.suffix - local filename = environment.filename -- hm, not inputfilename ! + + environment.lmtxmode = CONTEXTLMTXMODE if arguments.nosynctex then luatex.synctex.setup { @@ -222,6 +241,24 @@ local function processjob() -- directives.enable("logs.errors",arguments.errors) -- end + preparejob = function() end + + job.prepare = preparejob + +end + +job.prepare = preparejob + +local function processjob() + + environment.initializefilenames() -- todo: check if we really need to pre-prep the filename + + local arguments = environment.arguments + local suffix = environment.suffix + local filename = environment.filename -- hm, not inputfilename ! + + preparejob() + if not filename or filename == "" then -- skip elseif suffix == "xml" or arguments.forcexml then @@ -285,7 +322,6 @@ local function processjob() -- \writestatus{system}{processing as tex} -- We have a regular tex file so no \starttext yet as we can -- load fonts. - -- context.enabletrackers { "resolvers.*" } context.input(filename) -- context.disabletrackers { "resolvers.*" } diff --git a/tex/context/base/mkiv/cont-run.mkiv b/tex/context/base/mkiv/cont-run.mkiv index b650be67d..f841ce530 100644 --- a/tex/context/base/mkiv/cont-run.mkiv +++ b/tex/context/base/mkiv/cont-run.mkiv @@ -25,19 +25,29 @@ \let\synctexsetfilename \clf_synctexsetfilename \let\synctexresetfilename\clf_synctexresetfilename \let\synctexblockfilename\clf_synctexblockfilename -\let\synctexpause \clf_synctexpause -\let\synctexresume \clf_synctexresume -\appendtoks\clf_synctexpause \to\everybeforeoutput -\appendtoks\clf_synctexresume\to\everyafteroutput +\let\synctexpause \donothing +\let\synctexresume \donothing +\let\synctexpushline\donothing +\let\synctexpopline \donothing + +\appendtoks\synctexpause \to\everybeforeoutput +\appendtoks\synctexresume\to\everyafteroutput \unexpanded\def\setupsynctex[#1]% {\begingroup \getdummyparameters[\c!state=\v!stop,\c!method=\v!max,#1]% + \edef\p_state{\dummyparameter\c!state}% \clf_setupsynctex - state {\dummyparameter\c!state}% + state {\p_state}% method {\dummyparameter\c!method}% \relax + \ifx\p_state\v!start + \glet\synctexpause \clf_synctexpause + \glet\synctexresume \clf_synctexresume + \glet\synctexpushline\clf_synctexpushline + \glet\synctexpopline \clf_synctexpopline + \fi \endgroup} \unexpanded\def\blocksynctexfile[#1]% diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index 9a52cfe78..cd0170587 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -42,9 +42,13 @@ %D has to match \type {YYYY.MM.DD HH:MM} format. \edef\contextformat {\jobname} -\edef\contextversion{2018.04.04 00:51} +\edef\contextversion{2019.02.22 19:35} \edef\contextkind {beta} +%D Kind of special: + +\chardef\contextlmtxmode\directlua{tex.print(CONTEXTLMTXMODE or 0)}\relax + %D For those who want to use this: \let\fmtname \contextformat @@ -77,8 +81,8 @@ %D We just quit if new functionality is expected. -\ifnum\luatexversion<105 % also change message - \writestatus{!!!!}{Your luatex binary is too old, you need at least version 1.05!} +\ifnum\luatexversion<109 % also change message + \writestatus{!!!!}{Your luatex binary is too old, you need at least version 1.09!} \expandafter\end \fi @@ -99,6 +103,7 @@ \loadmarkfile{luat-cod} \loadmarkfile{luat-bas} \loadmarkfile{luat-lib} +\loadmarkfile{luat-soc} \loadmarkfile{catc-ini} \loadmarkfile{catc-act} @@ -106,6 +111,7 @@ \loadmarkfile{catc-ctx} \loadmarkfile{catc-sym} +\loadmarkfile{toks-ini} \loadmarkfile{cldf-ini} % \tracecatcodetables @@ -114,7 +120,7 @@ % \unexpanded long before etex came around. \loadmarkfile{luat-ini} -\loadmarkfile{toks-ini} +\loadmarkfile{toks-scn} \loadmarkfile{syst-aux} \loadmarkfile{syst-lua} @@ -125,13 +131,18 @@ \loadmarkfile{luat-usr} -% \loadmarkfile{luat-ini} % moved up -% \loadmarkfile{toks-ini} % moved up - \loadmkvifile{file-ini} \loadmkvifile{file-res} \loadmkvifile{file-lib} +\doifelsefileexists{core-lmt.mkiv} {\loadmarkfile{core-lmt}} {} + +% needs more checking for clashes: +% +% no need to register, just execute once, slightly faster +% +% \doifelsefileexists{l-macro-imp-codes.lua}{\registerctxluafile{l-macro-imp-codes}{}}{} + \loadmarkfile{supp-dir} \loadmarkfile{char-utf} % generic code (i.e. not much tex) ... could become unic-ini @@ -153,6 +164,7 @@ % \loadmarkfile{luat-ini} \loadmarkfile{toks-tra} +\loadmarkfile{toks-aux} %loadmarkfile{toks-map} % obsolete, never used \loadmarkfile{attr-ini} @@ -170,6 +182,8 @@ \loadmarkfile{node-mig} %loadmarkfile{node-pag} +\loadmarkfile{driv-ini} + \loadmarkfile{back-ini} \loadmarkfile{attr-col} @@ -202,6 +216,7 @@ \loadmkvifile{file-syn} \loadmkvifile{file-mod} +\loadmarkfile{core-sys} \loadmarkfile{core-con} \loadmarkfile{cont-fil} @@ -274,7 +289,6 @@ \loadmarkfile{spac-lin} \loadmarkfile{spac-pag} \loadmarkfile{spac-par} -%loadmarkfile{spac-adj} % no longer needed \loadmarkfile{spac-def} \loadmkvifile{spac-prf} \loadmarkfile{spac-grd} @@ -296,7 +310,7 @@ \loadmarkfile{strc-lab} \loadmarkfile{strc-syn} -\loadmarkfile{core-sys} +% \loadmarkfile{core-sys} \loadmarkfile{page-var} \loadmkvifile{page-otr} @@ -319,9 +333,11 @@ \loadmarkfile{page-pst} \loadmkvifile{page-mbk} -\loadmarkfile{page-mul} % partly overloaded -\loadmarkfile{page-mix} % new -\loadmarkfile{page-set} +%loadmarkfile{page-mul} % \usecolumns[old-multicolumns] +\loadmarkfile{page-mix} +\loadmarkfile{page-smp} +%loadmarkfile{page-set} % \usecolumns[old-columnsets] +\loadmarkfile{page-cst} \loadmarkfile{page-pcl} % new \loadmarkfile{pack-lyr} \loadmarkfile{pack-pos} @@ -507,6 +523,7 @@ \loadmkvifile{strc-not} \loadmkvifile{strc-lnt} +\loadmkivfile{strc-usr} \loadmarkfile{pack-com} \loadmarkfile{typo-del} @@ -547,7 +564,7 @@ \loadmarkfile{cont-log} -\loadmarkfile{task-ini} +% \loadmarkfile{task-ini} \loadmarkfile{cldf-ver} % verbatim, this can come late \loadmarkfile{cldf-com} % commands, this can come late @@ -565,13 +582,24 @@ \loadmarkfile{back-exp} \loadmarkfile{back-pdf} % actually, this one should load the next three using document.arguments.backend + \loadmarkfile{mlib-pdf} \loadmarkfile{mlib-pps} \loadmarkfile{meta-pdf} +\loadmarkfile{meta-blb} \loadmarkfile{grph-epd} +\loadmarkfile{math-inc} % an experiment +\loadmarkfile{publ-inc} % an experiment + +\loadmarkfile{task-ini} + +\loadmarkfile{syst-cmp} % compatibility stuff moved here + \loadmarkfile{cont-run} % the main runner (used in cont-yes.mkiv) +\doifelsefileexists{driv-shp.mkiv} {\loadmarkfile{driv-shp}} {} + \setupcurrentlanguage[\defaultlanguagetag] \prependtoks @@ -582,6 +610,14 @@ \ctxlua{statistics.stoptiming(statistics)}% \to \everyjob +% \appendtoks +% \ctxlua{job.prepare()}% +% \to \everyjob + +% \appendtoks +% \enabletrackers[*]% +% \to \everyjob + \appendtoks \ctxlua{statistics.savefmtstatus("\jobname","\contextversion","context.mkiv","\contextkind","\contextbanner")}% can become automatic \to \everydump diff --git a/tex/context/base/mkiv/core-con.lua b/tex/context/base/mkiv/core-con.lua index 87b4c063e..3829efc9c 100644 --- a/tex/context/base/mkiv/core-con.lua +++ b/tex/context/base/mkiv/core-con.lua @@ -16,7 +16,7 @@ slower but look nicer this way.

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

--ldx]]-- -local floor, date, time, concat = math.floor, os.date, os.time, table.concat +local floor, osdate, ostime, concat = math.floor, os.date, os.time, table.concat local lower, upper, rep, match, gsub = string.lower, string.upper, string.rep, string.match, string.gsub local utfchar, utfbyte = utf.char, utf.byte local tonumber, tostring, type, rawset = tonumber, tostring, type, rawset @@ -33,6 +33,7 @@ local setmetatableindex = table.setmetatableindex local formatters = string.formatters local variables = interfaces.variables local constants = interfaces.constants +local addformatter = utilities.strings.formatters.add local texset = tex.set @@ -42,6 +43,9 @@ local converters = converters languages = languages or { } local languages = languages +local helpers = converters.helpers or { } +converters.helpers = helpers + local ctx_labeltext = context.labeltext local ctx_LABELTEXT = context.LABELTEXT local ctx_space = context.space @@ -304,14 +308,14 @@ local function leapyear(year) end local function textime() - return tonumber(date("%H")) * 60 + tonumber(date("%M")) + return tonumber(osdate("%H")) * 60 + tonumber(osdate("%M")) end -function converters.year () return date("%Y") end -function converters.month () return date("%m") end -function converters.hour () return date("%H") end -function converters.minute() return date("%M") end -function converters.second() return date("%S") end +function converters.year () return osdate("%Y") end +function converters.month () return osdate("%m") end +function converters.hour () return osdate("%H") end +function converters.minute() return osdate("%M") end +function converters.second() return osdate("%S") end converters.weekday = weekday converters.isleapyear = isleapyear @@ -323,11 +327,11 @@ implement { name = "weekday", actions = { weekday, context }, arguments = { "i implement { name = "leapyear", actions = { leapyear, context }, arguments = { "integer" } } implement { name = "nofdays", actions = { nofdays, context }, arguments = { "integer", "integer" } } -implement { name = "year", actions = { date, context }, arguments = "'%Y'" } -implement { name = "month", actions = { date, context }, arguments = "'%m'" } -implement { name = "hour", actions = { date, context }, arguments = "'%H'" } -implement { name = "minute", actions = { date, context }, arguments = "'%M'" } -implement { name = "second", actions = { date, context }, arguments = "'%S'" } +implement { name = "year", actions = { osdate, context }, arguments = "'%Y'" } +implement { name = "month", actions = { osdate, context }, arguments = "'%m'" } +implement { name = "hour", actions = { osdate, context }, arguments = "'%H'" } +implement { name = "minute", actions = { osdate, context }, arguments = "'%M'" } +implement { name = "second", actions = { osdate, context }, arguments = "'%S'" } implement { name = "textime", actions = { textime, context } } implement { @@ -1222,45 +1226,108 @@ setmetatableindex(months, function(t,k) return "unknown" end) setmetatableindex(days, function(t,k) return "unknown" end) setmetatableindex(monthmnems, function(t,k) return months[k] .. ":mnem" end) -local function dayname(n) - return days[n] -end +do -local function weekdayname(day,month,year) - return days[weekday(day,month,year)] -end + local function dayname(n) + ctx_labeltext(days[n]) + end -local function monthname(n) - return months[n] -end + local function weekdayname(day,month,year) + ctx_labeltext(days[weekday(day,month,year)]) + end -local function monthmnem(n) - return monthmnems[n] -end + local function monthname(n) + ctx_labeltext(months[n]) + end -implement { - name = "dayname", - actions = { dayname, ctx_labeltext }, - arguments = "integer", -} + local function monthmnem(n) + ctx_labeltext(monthmnems[n]) + end -implement { - name = "weekdayname", - actions = { weekdayname, ctx_labeltext }, - arguments = { "integer", "integer", "integer" } -} + implement { + name = "dayname", + actions = dayname, + arguments = "integer", + } -implement { - name = "monthname", - actions = { monthname, ctx_labeltext }, - arguments = { "integer" } -} + implement { + name = "weekdayname", + actions = weekdayname, + arguments = { "integer", "integer", "integer" } + } -implement { - name = "monthmnem", - actions = { monthmnem, ctx_labeltext }, - arguments = { "integer" } -} + implement { + name = "monthname", + actions = monthname, + arguments = { "integer" } + } + + implement { + name = "monthmnem", + actions = monthmnem, + arguments = { "integer" } + } + + local f_monthlong = formatters["\\monthlong{%s}"] + local f_monthshort = formatters["\\monthshort{%s}"] + local f_weekday = formatters["\\weekday{%s}"] + local f_dayoftheweek = formatters["\\dayoftheweek{%s}{%s}{%s}"] + + local function tomonthlong (m) return f_monthlong (tonumber(m) or 1) end + local function tomonthshort(m) return f_monthshort(tonumber(m) or 1) end + local function toweekday (d) return f_weekday (tonumber(d) or 1) end + + local function todayoftheweek(d,m,y) + return f_dayoftheweek(tonumber(d) or 1,tonumber(m) or 1,tonumber(y) or 2000) + end + + addformatter(formatters,"monthlong", [[tomonthlong(%s)]], { tomonthlong = tomonthlong }) + addformatter(formatters,"monthshort", [[tomonthshort(%s)]], { tomonthshort = tomonthshort }) + addformatter(formatters,"weekday", [[toweekday(%s)]], { toweekday = toweekday }) + addformatter(formatters,"dayoftheweek",[[todayoftheweek(%s,%s,%s)]],{ todayoftheweek = todayoftheweek }) + + -- using %t is slower, even with caching as we seldom use > 3 items per epoch + + local function toeyear (e) return osdate("%Y",tonumber(e)) end + local function toemonth (e) return osdate("%m",tonumber(e)) end + local function toeday (e) return osdate("%d",tonumber(e)) end + local function toeminute(e) return osdate("%M",tonumber(e)) end + local function toesecond(e) return osdate("%S",tonumber(e)) end + + local function toemonthlong(e) + return f_monthlong(tonumber(osdate("%m",tonumber(e)))) + end + + local function toemonthshort(e) + return f_monthshort(tonumber(osdate("%m",tonumber(e)))) + end + + local function toeweek(e) -- we run from 1-7 not 0-6 + return tostring(tonumber(osdate("%w",tonumber(e)))+1) + end + + local function toeweekday(e) + return f_weekday(tonumber(osdate("%w",tonumber(e)))+1) + end + + local function toedate(format,e) + return osdate(format,tonumber(e)) + end + + addformatter(formatters,"eyear", [[toeyear(%s)]], { toeyear = toeyear }) + addformatter(formatters,"emonth", [[toemonth(%s)]], { toemonth = toemonth }) + addformatter(formatters,"eday", [[toeday(%s)]], { toeday = toeday }) + addformatter(formatters,"eweek", [[toeweek(%s)]], { toeweek = toeweek }) + addformatter(formatters,"eminute", [[toeminute(%s)]], { toeminute = toeminute }) + addformatter(formatters,"esecond", [[toesecond(%s)]], { toesecond = toesecond }) + + addformatter(formatters,"emonthlong", [[toemonthlong(%s)]], { toemonthlong = toemonthlong }) + addformatter(formatters,"emonthshort", [[toemonthshort(%s)]], { toemonthshort = toemonthshort }) + addformatter(formatters,"eweekday", [[toeweekday(%s)]], { toeweekday = toeweekday }) + + addformatter(formatters,"edate", [[toedate(%s,%s)]], { toedate = toedate }) + +end -- a prelude to a function that we can use at the lua end @@ -1287,125 +1354,146 @@ local variants = { jalali = setmetatableindex(function(t,k) return months[k] .. ":jalali" end), } -local function currentdate(str,currentlanguage) -- second argument false : no label - local list = utilities.parsers.settings_to_array(str) - local splitlabel = languages.labels.split or string.itself -- we need to get the loading order right - local year = tex.year - local month = tex.month - local day = tex.day - local auto = true - if currentlanguage == "" then - currentlanguage = false - end - for i=1,#list do - local entry = list[i] - local convert = dateconverters[entry] - if convert then - year, month, day = convert(year,month,day) - else - local tag, plus = splitlabel(entry) - local ordinal, mnemonic, whatordinal, highordinal = false, false, nil, false - if not tag then - tag = entry - elseif plus == "+" or plus == "ord" then - ordinal = true - elseif plus == "++" or plus == "highord" then - ordinal = true - highordinal = true - -- elseif plus == "mnem" then - -- mnemonic = true - elseif plus then -- elseif plus == "mnem" then - mnemonic = variants[plus] - end - if not auto and spaced[tag] then - ctx_space() - end - auto = false - if tag == v_year or tag == "y" or tag == "Y" then - context(year) - elseif tag == "yy" or tag == "YY" then - context("%02i",year % 100) - elseif tag == v_month or tag == "m" then - if currentlanguage == false then - context(Word(months[month])) - elseif mnemonic then - ctx_labeltext(variables[mnemonic[month]]) - else - ctx_labeltext(variables[months[month]]) +do + + local function currentdate(str,currentlanguage,year,month,day) -- second argument false : no label + local list = utilities.parsers.settings_to_array(str) + local splitlabel = languages.labels.split or string.itself -- we need to get the loading order right + -- local year = tex.year + -- local month = tex.month + -- local day = tex.day + local auto = true + if currentlanguage == "" then + currentlanguage = false + end + for i=1,#list do + local entry = list[i] + local convert = dateconverters[entry] + if convert then + year, month, day = convert(year,month,day) + else + local tag, plus = splitlabel(entry) + local ordinal, mnemonic, whatordinal, highordinal = false, false, nil, false + if not tag then + tag = entry + elseif plus == "+" or plus == "ord" then + ordinal = true + elseif plus == "++" or plus == "highord" then + ordinal = true + highordinal = true + -- elseif plus == "mnem" then + -- mnemonic = true + elseif plus then -- elseif plus == "mnem" then + mnemonic = variants[plus] end - elseif tag == v_MONTH then - if currentlanguage == false then - context(Word(variables[months[month]])) - elseif mnemonic then - ctx_LABELTEXT(variables[mnemonic[month]]) - else - ctx_LABELTEXT(variables[months[month]]) + if not auto and spaced[tag] then + ctx_space() end - elseif tag == "mm" then - context("%02i",month) - elseif tag == "M" then - context(month) - elseif tag == v_day or tag == "d" then - if currentlanguage == false then + auto = false + if tag == v_year or tag == "y" or tag == "Y" then + context(year) + elseif tag == "yy" or tag == "YY" then + context("%02i",year % 100) + elseif tag == v_month or tag == "m" then + if currentlanguage == false then + context(Word(months[month])) + elseif mnemonic then + ctx_labeltext(variables[mnemonic[month]]) + else + ctx_labeltext(variables[months[month]]) + end + elseif tag == v_MONTH then + if currentlanguage == false then + context(Word(variables[months[month]])) + elseif mnemonic then + ctx_LABELTEXT(variables[mnemonic[month]]) + else + ctx_LABELTEXT(variables[months[month]]) + end + elseif tag == "mm" then + context("%02i",month) + elseif tag == "M" then + context(month) + elseif tag == v_day or tag == "d" then + if currentlanguage == false then + context(day) + else + ctx_convertnumber(v_day,day) -- why not direct + end + whatordinal = day + elseif tag == "dd" then + context("%02i",day) + whatordinal = day + elseif tag == "D" then context(day) - else - ctx_convertnumber(v_day,day) -- why not direct + whatordinal = day + elseif tag == v_weekday or tag == "w" then + local wd = weekday(day,month,year) + if currentlanguage == false then + context(Word(days[wd])) + else + ctx_labeltext(variables[days[wd]]) + end + elseif tag == v_WEEKDAY then + local wd = weekday(day,month,year) + if currentlanguage == false then + context(Word(days[wd])) + else + ctx_LABELTEXT(variables[days[wd]]) + end + elseif tag == "W" then + context(weekday(day,month,year)) + elseif tag == v_referral then + context("%04i%02i%02i",year,month,day) + elseif tag == v_space or tag == "\\ " then + ctx_space() + auto = true + elseif tag ~= "" then + context(tag) + auto = true end - whatordinal = day - elseif tag == "dd" then - context("%02i",day) - whatordinal = day - elseif tag == "D" then - context(day) - whatordinal = day - elseif tag == v_weekday or tag == "w" then - local wd = weekday(day,month,year) - if currentlanguage == false then - context(Word(days[wd])) - else - ctx_labeltext(variables[days[wd]]) - end - elseif tag == v_WEEKDAY then - local wd = weekday(day,month,year) - if currentlanguage == false then - context(Word(days[wd])) - else - ctx_LABELTEXT(variables[days[wd]]) - end - elseif tag == "W" then - context(weekday(day,month,year)) - elseif tag == v_referral then - context("%04i%02i%02i",year,month,day) - elseif tag == v_space or tag == "\\ " then - ctx_space() - auto = true - elseif tag ~= "" then - context(tag) - auto = true - end - if ordinal and whatordinal then - if currentlanguage == false then - -- ignore - else - context[highordinal and "highordinalstr" or "ordinalstr"](converters.ordinal(whatordinal,currentlanguage)) + if ordinal and whatordinal then + if currentlanguage == false then + -- ignore + else + context[highordinal and "highordinalstr" or "ordinalstr"](converters.ordinal(whatordinal,currentlanguage)) + end end end end end -end + implement { + name = "currentdate", + arguments = { "string", "string", "string", "integer", "integer", "integer" }, + actions = function(pattern,default,language,year,month,day) + currentdate( + pattern == "" and default or pattern, + language == "" and false or language, + year, month, day + ) + end, + } + + local function todate(s,y,m,d) + if y or m or d then + return formatters["\\date[y=%s,m=%s,d=%s][%s]\\relax"](y or "",m or "",d or "",s or "") + else + return formatters["\\currentdate[%s]\\relax"](s) + end + end + + addformatter(formatters,"date", [[todate(...)]], { todate = todate }) + -- context("one: %4!date!","MONTH",2020,12,11) context.par() + -- context("one: %4!date!","month",2020,12,11) context.par() + -- context("one: %4!date!","year,-,mm,-,dd",2020,12,11) context.par() -implement { - name = "currentdate", - arguments = "3 strings", - actions = function(pattern,default,language) - currentdate( - pattern == "" and default or pattern, - language == "" and false or language - ) - end, -} + -- context("two: %3!date!","MONTH",false,12) context.par() + -- context("two: %3!date!","month",false,12) context.par() + -- context("two: %3!date!","year,-,mm,-,dd",false,12) context.par() + +end implement { name = "unihex", @@ -1586,3 +1674,4 @@ implement { } } } + diff --git a/tex/context/base/mkiv/core-con.mkiv b/tex/context/base/mkiv/core-con.mkiv index b4f247fcb..303fb1291 100644 --- a/tex/context/base/mkiv/core-con.mkiv +++ b/tex/context/base/mkiv/core-con.mkiv @@ -190,10 +190,10 @@ %D want to use as meaningful commands as possible, and because \TEX\ already %D uses up some of those, we save the original meanings. -\savenormalmeaning\time -\savenormalmeaning\year -\savenormalmeaning\month -\savenormalmeaning\day +% \savenormalmeaning\time +% \savenormalmeaning\year +% \savenormalmeaning\month +% \savenormalmeaning\day %D \macros %D {month,MONTH} @@ -218,7 +218,7 @@ %D \showsetup{month} %D \showsetup{MONTH} -\let\month \monthlong +\let\month\monthlong \unexpanded\def\MONTH #1{\WORD{\month {#1}}} \unexpanded\def\MONTHLONG #1{\WORD{\monthlong {#1}}} @@ -414,30 +414,43 @@ {\dosingleempty\syst_converters_current_date} \def\syst_converters_current_date[#1]% - {\begingroup + {\dontleavehmode + \begingroup \the\everycurrentdate - \clf_currentdate{#1}{\currentdatespecification}{\labellanguage}% + \clf_currentdate + {#1}{\currentdatespecification}{\labellanguage}% + \normalyear\normalmonth\normalday \endgroup} \unexpanded\def\date {\dodoubleempty\syst_converters_date} \def\syst_converters_date[#1][#2]% - {\begingroup + {\dontleavehmode + \begingroup + \scratchcounterone \normalyear + \scratchcountertwo \normalmonth + \scratchcounterthree\normalday \iffirstargument - \letdummyparameter\c!d\normalday - \letdummyparameter\c!m\normalmonth - \letdummyparameter\c!y\normalyear + \letdummyparameter\c!y\empty + \letdummyparameter\c!m\empty + \letdummyparameter\c!d\empty \getdummyparameters[#1]% - \normalday \directdummyparameter\c!d\relax - \normalmonth\directdummyparameter\c!m\relax - \normalyear \directdummyparameter\c!y\relax + \edef\temp{\dummyparameter\c!y}\ifx\temp\empty\else\scratchcounterone \temp\fi + \edef\temp{\dummyparameter\c!m}\ifx\temp\empty\else\scratchcountertwo \temp\fi + \edef\temp{\dummyparameter\c!d}\ifx\temp\empty\else\scratchcounterthree\temp\fi + \relax \fi - \syst_converters_current_date[#2]% + \the\everycurrentdate + \clf_currentdate + {#2}{\currentdatespecification}{\labellanguage}% + \scratchcounterone\scratchcountertwo\scratchcounterthree \endgroup} \def\rawdate[#1]% expandable and no labels - {\clf_currentdate{#1}{\currentdatespecification}{}} + {\clf_currentdate + {#1}{\currentdatespecification}{}% + \normalyear\normalmonth\normalday} %D \macros %D {currenttime} @@ -454,7 +467,7 @@ \let\currentminute\!!plusone \let\currentsecond\!!plusone -\def\currenttimespecification{h,:,m} +% \def\currenttimespecification{h,:,m} \unexpanded\def\currenttime {\doifelsenextoptional\syst_converters_current_time_yes\syst_converters_current_time_nop} @@ -805,61 +818,119 @@ \ifdefined\symbol \else \def\symbol[#1]{#1} \fi % todo +% \defineconversion +% [set 0] +% [{\symbol[bullet]}, +% {\symbol[dash]}, +% {\symbol[star]}, +% {\symbol[triangle]}, +% {\symbol[circle]}, +% {\symbol[medcircle]}, +% {\symbol[bigcircle]}, +% {\symbol[square]}, +% {\symbol[checkmark]}] + +% \defineconversion +% [set 1] +% [\mathematics{\star}, +% \mathematics{\star\star}, +% \mathematics{\star\star\star}, +% \mathematics{\ddagger}, +% \mathematics{\ddagger\ddagger}, +% \mathematics{\ddagger\ddagger\ddagger}, +% \mathematics{\ast}, +% \mathematics{\ast\ast}, +% \mathematics{\ast\ast\ast}] +% +% \defineconversion +% [set 2] +% [\mathematics{\ast}, +% \mathematics{\dag}, +% \mathematics{\ddag}, +% \mathematics{\ast\ast}, +% \mathematics{\dag\dag}, +% \mathematics{\ddag\ddag}, +% \mathematics{\ast\ast\ast}, +% \mathematics{\dag\dag\dag}, +% \mathematics{\ddag\ddag\ddag}, +% \mathematics{\ast\ast\ast\ast}, +% \mathematics{\dag\dag\dag\dag}, +% \mathematics{\ddag\ddag\ddag\ddag}] +% +% \defineconversion +% [set 3] +% [\mathematics{\star}, +% \mathematics{\star\star}, +% \mathematics{\star\star\star}, +% \mathematics{\ddagger}, +% \mathematics{\ddagger\ddagger}, +% \mathematics{\ddagger\ddagger\ddagger}, +% \mathematics{\P}, +% \mathematics{\P\P}, +% \mathematics{\P\P\P}, +% \mathematics{\S}, +% \mathematics{\S\S}, +% \mathematics{\S\S\S}, +% \mathematics{\ast}, +% \mathematics{\ast\ast}, +% \mathematics{\ast\ast\ast}] + \defineconversion [set 0] - [{\symbol[bullet]}, - {\symbol[dash]}, - {\symbol[star]}, - {\symbol[triangle]}, - {\symbol[circle]}, - {\symbol[medcircle]}, - {\symbol[bigcircle]}, - {\symbol[square]}] + [\symbol{bullet}, + \symbol{dash}, + \symbol{star}, + \symbol{triangle}, + \symbol{circle}, + \symbol{medcircle}, + \symbol{bigcircle}, + \symbol{square}, + \symbol{checkmark}] \defineconversion [set 1] - [\mathematics{\star}, - \mathematics{\star\star}, - \mathematics{\star\star\star}, - \mathematics{\ddagger}, - \mathematics{\ddagger\ddagger}, - \mathematics{\ddagger\ddagger\ddagger}, - \mathematics{\ast}, - \mathematics{\ast\ast}, - \mathematics{\ast\ast\ast}] + [\textormathchars{⋆}, + \textormathchars{⋆⋆}, + \textormathchars{⋆⋆⋆}, + \textormathchars{‡}, + \textormathchars{‡‡}, + \textormathchars{‡‡‡}, + \textormathchars{∗}, + \textormathchars{∗∗}, + \textormathchars{∗∗∗}] \defineconversion [set 2] - [\mathematics{*}, - \mathematics{\dag}, - \mathematics{\ddag}, - \mathematics{**}, - \mathematics{\dag\dag}, - \mathematics{\ddag\ddag}, - \mathematics{***}, - \mathematics{\dag\dag\dag}, - \mathematics{\ddag\ddag\ddag}, - \mathematics{****}, - \mathematics{\dag\dag\dag\dag}, - \mathematics{\ddag\ddag\ddag\ddag}] + [\textormathchars{∗}, + \textormathchars{†}, + \textormathchars{‡}, + \textormathchars{∗∗}, + \textormathchars{††}, + \textormathchars{‡‡}, + \textormathchars{∗∗∗}, + \textormathchars{†††}, + \textormathchars{‡‡‡}, + \textormathchars{∗∗∗∗}, + \textormathchars{††††}, + \textormathchars{‡‡‡‡}] \defineconversion [set 3] - [\mathematics{\star}, - \mathematics{\star\star}, - \mathematics{\star\star\star}, - \mathematics{\ddagger}, - \mathematics{\ddagger\ddagger}, - \mathematics{\ddagger\ddagger\ddagger}, - \mathematics{\P}, - \mathematics{\P\P}, - \mathematics{\P\P\P}, - \mathematics{\S}, - \mathematics{\S\S}, - \mathematics{\S\S\S}, - \mathematics{\ast}, - \mathematics{\ast\ast}, - \mathematics{\ast\ast\ast}] + [\textormathchars{⋆}, + \textormathchars{⋆⋆}, + \textormathchars{⋆⋆⋆}, + \textormathchars{‡}, + \textormathchars{‡‡}, + \textormathchars{‡‡‡}, + \textormathchars{¶}, + \textormathchars{¶¶}, + \textormathchars{¶¶¶}, + \textormathchars{§}, + \textormathchars{§§}, + \textormathchars{§§§}, + \textormathchars{∗}, + \textormathchars{∗∗}, + \textormathchars{∗∗∗}] %D Iteration of suggestion by WS on mailinglist 2010.12.22: %D @@ -888,4 +959,23 @@ data {#1}% \relax} +%D For those who sart counting at zero: +%D +%D \starttyping +%D \defineconversionset [zero] [n,zero] [n] +%D +%D \setuphead [sectionconversionset=zero] +%D +%D \starttext +%D \startchapter [title=Introduction] +%D \startsection [title=First topic] \stopsection +%D \startsection [title=Second topic] \stopsection +%D \stopchapter +%D \stoptext +%D \stoptyping + +\def\zeronumberconversion#1{\number\numexpr#1-\plusone\relax} + +\defineconversion [zero] [\zeronumberconversion] + \protect \endinput diff --git a/tex/context/base/mkiv/core-dat.lua b/tex/context/base/mkiv/core-dat.lua index fa4d089d0..b49750159 100644 --- a/tex/context/base/mkiv/core-dat.lua +++ b/tex/context/base/mkiv/core-dat.lua @@ -15,6 +15,7 @@ local tonumber, tostring, type = tonumber, tostring, type local context = context local commands = commands +local ctx_latelua = context.latelua local trace_datasets = false trackers.register("job.datasets" , function(v) trace_datasets = v end) local trace_pagestates = false trackers.register("job.pagestates", function(v) trace_pagestates = v end) @@ -35,6 +36,7 @@ local v_yes = interfaces.variables.yes local new_latelua = nodes.pool.latelua local implement = interfaces.implement +local getnamespace = interfaces.getnamespace local collected = allocate() local tobesaved = allocate() @@ -106,6 +108,9 @@ end datasets.setdata = setdata function datasets.extend(name,tag) + if type(name) == "table" then + name, tag = name.name, name.tag + end local set = sets[name] local order = set.order + 1 local realpage = texgetcount("realpageno") @@ -146,10 +151,8 @@ local function setdataset(settings) local name, tag = setdata(settings) if settings.delay ~= v_yes then -- - elseif type(tag) == "number" then - context(new_latelua(formatters["job.datasets.extend(%q,%i)"](name,tag))) else - context(new_latelua(formatters["job.datasets.extend(%q,%q)"](name,tag))) + context(new_latelua { action = job.datasets.extend, name = name, tag = tag }) end end @@ -242,9 +245,7 @@ local function setstate(settings) return name, tag, data end -pagestates.setstate = setstate - -function pagestates.extend(name,tag) +local function extend(name,tag) local realpage = texgetcount("realpageno") if trace_pagestates then report_pagestate("action %a, name %a, tag %a, preset %a","synchronize",name,tag,realpage) @@ -252,7 +253,7 @@ function pagestates.extend(name,tag) tobesaved[name][tag] = realpage end -function pagestates.realpage(name,tag,default) +local function realpage(name,tag,default) local t = collected[name] if t then t = t[tag] or t[tonumber(tag)] @@ -267,21 +268,36 @@ function pagestates.realpage(name,tag,default) return default end -local function setpagestate(settings) - local name, tag, data = setstate(settings) - if type(tag) == "number" then - context(new_latelua(formatters["job.pagestates.extend(%q,%i)"](name,tag))) - else - context(new_latelua(formatters["job.pagestates.extend(%q,%q)"](name,tag))) - end -end - -local function pagestaterealpage(name,tag) +local function realpageorder(name,tag) local t = collected[name] - t = t and (t[tag] or t[tonumber(tag)]) if t then - context(t) + local p = t[tag] + if p then + local n = 1 + for i=tag-1,1,-1 do + if t[i] == p then + n = n +1 + end + end + return n + end end + return 0 +end + +pagestates.setstate = setstate +pagestates.extend = extend +pagestates.realpage = realpage +pagestates.realpageorder = realpageorder + +function pagestates.countervalue(name) + return name and texgetcount(getnamespace("pagestatecounter") .. name) or 0 +end + +local function setpagestate(settings) + local name, tag = setstate(settings) + -- context(new_latelua(function() extend(name,tag) end)) + ctx_latelua(function() extend(name,tag) end) end local function setpagestaterealpageno(name,tag) @@ -304,7 +320,7 @@ implement { implement { name = "pagestaterealpage", - actions = pagestaterealpage, + actions = { realpage, context }, arguments = "2 strings", } @@ -313,3 +329,9 @@ implement { actions = setpagestaterealpageno, arguments = "2 strings", } + +implement { + name = "pagestaterealpageorder", + actions = { realpageorder, context }, + arguments = { "string", "integer" } +} diff --git a/tex/context/base/mkiv/core-dat.mkiv b/tex/context/base/mkiv/core-dat.mkiv index 3bb923af4..9f4344b99 100644 --- a/tex/context/base/mkiv/core-dat.mkiv +++ b/tex/context/base/mkiv/core-dat.mkiv @@ -73,9 +73,18 @@ {\clf_datasetvariable{#1}{#2}{#3}} \installcorenamespace{pagestate} +\installcorenamespace{pagestatecounter} \installcommandhandler \??pagestate {pagestate} \??pagestate +\def\syst_pagestates_allocate + {\expandafter\newcount\csname\??pagestatecounter\currentpagestate\endcsname + \expandafter\let\expandafter\c_syst_pagestate\csname\??pagestatecounter\currentpagestate\endcsname} + +\appendtoks + \syst_pagestates_allocate +\to \everydefinepagestate + \setuppagestate [\c!delay=\v!yes] @@ -85,17 +94,31 @@ \def\syst_pagestates_set[#1][#2]% {\begingroup \edef\currentpagestate{#1}% + \ifcsname\??pagestatecounter\currentpagestate\endcsname + \let\c_syst_pagestate\lastnamedcs + \else + \syst_pagestates_allocate + \fi + \global\advance\c_syst_pagestate\plusone + \scratchcounter\lastnamedcs \clf_setpagestate name {\currentpagestate}% - tag {#2}% + tag {\ifsecondargument#2\else\number\c_syst_pagestate\fi}% delay {\pagestateparameter\c!delay}% \relax \endgroup} -\def\pagestaterealpage#1#2% - {\clf_pagestaterealpage{#1}{#2}} +\unexpanded\def\autosetpagestate#1% + {\secondargumentfalse\syst_pagestates_set[#1]} + +\def\autopagestatenumber#1{\begincsname\??pagestatecounter#1\endcsname} + +\def\pagestaterealpage #1#2{\clf_pagestaterealpage {#1}{#2}} +\def\setpagestaterealpageno#1#2{\clf_setpagestaterealpageno{#1}{#2}} +\def\pagestaterealpageorder#1#2{\clf_pagestaterealpageorder{#1}#2\relax} -\def\setpagestaterealpageno#1#2% - {\clf_setpagestaterealpageno{#1}{#2}} +\def\autopagestaterealpage #1{\clf_pagestaterealpage {#1}{\number\autopagestatenumber{#1}}} +\def\setautopagestaterealpageno#1{\clf_setpagestaterealpageno{#1}{\number\autopagestatenumber{#1}}} +\def\autopagestaterealpageorder#1{\clf_pagestaterealpageorder{#1}\numexpr\autopagestatenumber{#1}\relax} \protect diff --git a/tex/context/base/mkiv/core-def.mkiv b/tex/context/base/mkiv/core-def.mkiv index 9dbb16f5c..95f7f2577 100644 --- a/tex/context/base/mkiv/core-def.mkiv +++ b/tex/context/base/mkiv/core-def.mkiv @@ -39,7 +39,7 @@ % \flushcommentanchors \flushnotes \synchronizenotes - \OTRSETshowstatus + % \OTRSETshowstatus \registerparoptions % \flushsyncpositions \flushpostponednodedata diff --git a/tex/context/base/mkiv/core-env.lua b/tex/context/base/mkiv/core-env.lua index 0ef37a6d6..50759dd19 100644 --- a/tex/context/base/mkiv/core-env.lua +++ b/tex/context/base/mkiv/core-env.lua @@ -26,6 +26,7 @@ local setmetatablenewindex = table.setmetatablenewindex local setmetatablecall = table.setmetatablecall local createtoken = token.create +local isdefined = tokens.isdefined texmodes = allocate { } tex.modes = texmodes texsystemmodes = allocate { } tex.systemmodes = texsystemmodes @@ -40,18 +41,27 @@ local systemmodes = { } -- we could use the built-in tex.is[count|dimen|skip|toks] here but caching -- at the lua end is not that bad (and we need more anyway) --- undefined: mode == 0 or cmdname = "undefined_cs" - -local cache = setmetatableindex(function(t,k) - local v = createtoken(k) - t[k] = v - return v -end) +local cache = tokens.cache -- we can have a modes cache too -local iftrue = cache["iftrue"].mode -local undefined = cache["*undefined*crap*"].mode -- is this ok? +local iftrue = cache["iftrue"].mode + +local dimencode = cache["scratchdimen"] .command +local countcode = cache["scratchcounter"] .command +local tokencode = cache["scratchtoken"] .command +local skipcode = cache["scratchskip"] .command +local muskipcode = cache["scratchmuskip"] .command +----- attributecode = cache["scratchattribute"].command + +local types = { + [dimencode] = "dimen", + [countcode] = "count", + [tokencode] = "token", + [skipcode] = "skip", + [muskipcode] = "muskip", + -- [attributecode] = "attribute", +} setmetatableindex(texmodes, function(t,k) local m = modes[k] @@ -59,16 +69,17 @@ setmetatableindex(texmodes, function(t,k) return m() elseif k then local n = "mode>" .. k - if cache[n].mode == 0 then - return false - else + if isdefined(n) then rawset(modes,k, function() return texgetcount(n) == 1 end) return texgetcount(n) == 1 -- 2 is prevented + else + return false end else return false end end) + setmetatablenewindex(texmodes, function(t,k) report_mode("you cannot set the %s named %a this way","mode",k) end) @@ -79,11 +90,11 @@ setmetatableindex(texsystemmodes, function(t,k) return m() else local n = "mode>*" .. k - if cache[n].mode == 0 then - return false - else + if isdefined(n) then rawset(systemmodes,k,function() return texgetcount(n) == 1 end) return texgetcount(n) == 1 -- 2 is prevented + else + return false end end end) @@ -112,31 +123,7 @@ setmetatablenewindex(texifs, function(t,k) -- just ignore end) -setmetatableindex(texisdefined, function(t,k) - return k and cache[k].mode ~= 0 -end) -setmetatablecall(texisdefined, function(t,k) - return k and cache[k].mode ~= 0 -end) -setmetatablenewindex(texisdefined, function(t,k) - -- just ignore -end) - -local dimencode = cache["scratchdimen"] .command -local countcode = cache["scratchcounter"] .command -local tokencode = cache["scratchtoken"] .command -local skipcode = cache["scratchskip"] .command -local muskipcode = cache["scratchmuskip"] .command ----- attributecode = cache["scratchattribute"].command - -local types = { - [dimencode] = "dimen", - [countcode] = "count", - [tokencode] = "token", - [skipcode] = "skip", - [muskipcode] = "muskip", - -- [attributecode] = "attribute", -} +tex.isdefined = isdefined function tex.isdimen(name) local hit = cache[name] diff --git a/tex/context/base/mkiv/core-env.mkiv b/tex/context/base/mkiv/core-env.mkiv index c93350db0..758ee126d 100644 --- a/tex/context/base/mkiv/core-env.mkiv +++ b/tex/context/base/mkiv/core-env.mkiv @@ -68,6 +68,14 @@ {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi \lastnamedcs\disabledmode} +\unexpanded\def\globalsetmode#1% + {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi + \global\lastnamedcs\enabledmode} + +\unexpanded\def\globalresetmode#1% + {\ifcsname\??mode#1\endcsname\else\syst_modes_new{#1}\fi + \global\lastnamedcs\disabledmode} + \unexpanded\def\newsystemmode#1% {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi} @@ -79,6 +87,14 @@ {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi \lastnamedcs\disabledmode} +\unexpanded\def\globalsetsystemmode#1% + {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi + \global\lastnamedcs\enabledmode} + +\unexpanded\def\globalresetsystemmode#1% + {\ifcsname\??mode\systemmodeprefix#1\endcsname\else\syst_modes_new{\systemmodeprefix#1}\fi + \global\lastnamedcs\disabledmode} + % \def\dosetsystemmode#1% % {\csname\??mode\systemmodeprefix#1\endcsname\enabledmode} % @@ -87,16 +103,18 @@ % demo: trialtypesetting is a systemmode as well as an if -\newsystemmode{trialtypesetting} % the name of \@@trialtypesetting might change (also at the lua end) +\newsystemmode{trialtypesetting} -\expandafter\let\expandafter\@@trialtypesetting\csname\??mode\systemmodeprefix trialtypesetting\endcsname % private ! +\expandafter\let\csname\??mode\systemmodeprefix trialtypesetting\endcsname\trialtypesettingstate \appendtoks - \@@trialtypesetting\enabledmode + \trialtypesettingstate\enabledmode + \luacopyinputnodes\plusone \to \everysettrialtypesetting \appendtoks - \@@trialtypesetting\disabledmode + \trialtypesettingstate\disabledmode + \luacopyinputnodes\zerocount \to \everyresettrialtypesetting % user ones @@ -661,6 +679,24 @@ \dodoglobal\undefinevalue{\??setup:#1}% \fi} +% \unexpanded\def\resetsetups[#1]% see x-fo for usage +% {\dodoglobal\expandafter\let\csname\??setup +% \ifgridsnapping\ifcsname\??setup\v!grid:#1\endcsname\v!grid\fi +% :#1\endcsname\undefined} + +\unexpanded\def\copysetups + {\dodoubleargument\syst_setups_copy} + +% \def\syst_setups_copy[#1][#2]% +% {\ifcsname\??setup:#2\endcsname +% \expandafter\let\csname\??setup:#1\expandafter\endcsname\csname\??setup:#2\endcsname +% \fi} + +\def\syst_setups_copy[#1][#2]% + {\ifcsname\??setup:#2\endcsname + \expandafter\let\csname\??setup:#1\expandafter\endcsname\lastnamedcs + \fi} + \unexpanded\def\showsetupsdefinition[#1]% {\showvalue{\??setup:#1}} % temp hack for debugging @@ -777,7 +813,7 @@ %{\edef\m_syst_string_one{\csname\??variables\ifcsname\??variables#1:#2\endcsname#1:#2\else:\fi\endcsname}% {\edef\m_syst_string_one{\begincsname\??variables#1:#2\endcsname}% \ifx\m_syst_string_one\empty - \expandafter\firstoffourarguments + \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} diff --git a/tex/context/base/mkiv/core-lmt.lua b/tex/context/base/mkiv/core-lmt.lua new file mode 100644 index 000000000..700ce4721 --- /dev/null +++ b/tex/context/base/mkiv/core-lmt.lua @@ -0,0 +1,34 @@ +if not modules then modules = { } end modules ['core-lmt'] = { + version = 1.001, + comment = "companion to core-lmt.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local implement = interfaces.implement +local scankeyword = tokens.scanners.keyword + +local settextdir = tex.settextdir +local setlinedir = tex.setlinedir +local setpardir = tex.setpardir +local setboxdir = tex.setboxdir + +local function scandir(what) + if scankeyword("tlt") then + what(0) + elseif scankeyword("trt") then + what(1) + -- elseif scankeyword("rtt") then + -- what(2) + -- elseif scankeyword("ltl") then + -- what(3) + else + what(0) + end +end + +implement { name = "textdir", public = true, protected = true, actions = function() scandir(settextdir) end } +implement { name = "linedir", public = true, protected = true, actions = function() scandir(setlinedir) end } +implement { name = "pardir", public = true, protected = true, actions = function() scandir(setpardir) end } +implement { name = "boxdir", public = true, protected = true, actions = function() scandir(setboxdir) end } diff --git a/tex/context/base/mkiv/core-lmt.mkiv b/tex/context/base/mkiv/core-lmt.mkiv new file mode 100644 index 000000000..eda667969 --- /dev/null +++ b/tex/context/base/mkiv/core-lmt.mkiv @@ -0,0 +1,32 @@ +%D \module +%D [ file=core-lmt, +%D version=2010.08.2, +%D title=\CONTEXT\ System Macros, +%D subtitle=Primitives, +%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. + +\ifcase\contextlmtxmode\expandafter\endinput\fi + +\writestatus{loading}{ConTeXt System Macros / Primitives} + +\ifdefined\textdir \else + \registerctxluafile{core-lmt}{} +\fi + +\unprotect + +% nothing yet + +\protect \endinput + +% \starttext +% abc{\textdir TRTdef}ghi +% abc{\textdir trtdef}ghi +% \boxdirection0=1 +% \stoptext diff --git a/tex/context/base/mkiv/core-sys.lua b/tex/context/base/mkiv/core-sys.lua index 26229235b..4078ab8a8 100644 --- a/tex/context/base/mkiv/core-sys.lua +++ b/tex/context/base/mkiv/core-sys.lua @@ -73,13 +73,13 @@ implement { name = "outputfilename", actions = function() context(environme statistics.register("result saved in file", function() -- suffix will be fetched from backend local outputfilename = environment.outputfilename or environment.jobname or tex.jobname or "" - if (tex.pdfoutput or tex.outputmode) > 0 then + -- if (tex.pdfoutput or tex.outputmode) > 0 then return format("%s.%s, compresslevel %s, objectcompresslevel %s",outputfilename,"pdf", lpdf.getcompression() ) - else - return format("%s.%s",outputfilename,"dvi") -- hard to imagine - end + -- else + -- return format("%s.%s",outputfilename,"dvi") -- hard to imagine + -- end end) implement { diff --git a/tex/context/base/mkiv/core-two.lua b/tex/context/base/mkiv/core-two.lua index 1e59004be..3ab2112b9 100644 --- a/tex/context/base/mkiv/core-two.lua +++ b/tex/context/base/mkiv/core-two.lua @@ -32,7 +32,7 @@ end job.register('job.passes.collected', tobesaved, initializer, nil) -local function allocate(id) +local function define(id) local p = tobesaved[id] if not p then p = { } @@ -41,10 +41,8 @@ local function allocate(id) return p end -jobpasses.define = allocate - -function jobpasses.save(id,str,index) - local jti = allocate(id) +local function save(id,str,index) + local jti = define(id) if index then jti[index] = str else @@ -52,30 +50,30 @@ function jobpasses.save(id,str,index) end end -function jobpasses.savetagged(id,tag,str) - local jti = allocate(id) +local function savetagged(id,tag,str) + local jti = define(id) jti[tag] = str end -function jobpasses.getdata(id,index,default) +local function getdata(id,index,default) local jti = collected[id] local value = jti and jti[index] return value ~= "" and value or default or "" end -function jobpasses.getfield(id,index,tag,default) +local function getfield(id,index,tag,default) local jti = collected[id] jti = jti and jti[index] local value = jti and jti[tag] return value ~= "" and value or default or "" end -function jobpasses.getcollected(id) +local function getcollected(id) return collected[id] or { } end -function jobpasses.gettobesaved(id) - return allocate(id) +local function gettobesaved(id) + return define(id) end local function get(id) @@ -87,23 +85,17 @@ end local function first(id) local jti = collected[id] - if jti and #jti > 0 then - return jti[1] - end + return jti and jti[1] end local function last(id) local jti = collected[id] - if jti and #jti > 0 then - return jti[#jti] - end + return jti and jti[#jti] end local function find(id,n) local jti = collected[id] - if jti and jti[n] then - return jti[n] - end + return jti and jti[n] or nil end local function count(id) @@ -132,44 +124,49 @@ end local check = first --- - -jobpasses.get = get -jobpasses.first = first -jobpasses.last = last -jobpasses.find = find -jobpasses.list = list -jobpasses.count = count -jobpasses.check = check -jobpasses.inlist = inlist +jobpasses.define = define +jobpasses.save = save +jobpasses.savetagged = savetagged +jobpasses.getdata = getdata +jobpasses.getfield = getfield +jobpasses.getcollected = getcollected +jobpasses.gettobesaved = gettobesaved +jobpasses.get = get +jobpasses.first = first +jobpasses.last = last +jobpasses.find = find +jobpasses.list = list +jobpasses.count = count +jobpasses.check = check +jobpasses.inlist = inlist -- interface local implement = interfaces.implement -implement { name = "gettwopassdata", actions = { get , context }, arguments = "string" } +implement { name = "gettwopassdata", actions = { get, context }, arguments = "string" } implement { name = "getfirsttwopassdata",actions = { first, context }, arguments = "string" } -implement { name = "getlasttwopassdata", actions = { last , context }, arguments = "string" } -implement { name = "findtwopassdata", actions = { find , context }, arguments = "2 strings" } -implement { name = "gettwopassdatalist", actions = { list , context }, arguments = "string" } +implement { name = "getlasttwopassdata", actions = { last, context }, arguments = "string" } +implement { name = "findtwopassdata", actions = { find, context }, arguments = "2 strings" } +implement { name = "gettwopassdatalist", actions = { list, context }, arguments = "string" } implement { name = "counttwopassdata", actions = { count, context }, arguments = "string" } implement { name = "checktwopassdata", actions = { check, context }, arguments = "string" } implement { name = "definetwopasslist", - actions = jobpasses.define, + actions = define, arguments = "string" } implement { name = "savetwopassdata", - actions = jobpasses.save, + actions = save, arguments = "2 strings", } implement { name = "savetaggedtwopassdata", - actions = jobpasses.savetagged, + actions = savetagged, arguments = "3 strings", } @@ -178,3 +175,23 @@ implement { actions = { inlist, commands.doifelse }, arguments = "2 strings", } + +-- local ctx_latelua = context.latelua + +-- implement { +-- name = "lazysavetwopassdata", +-- arguments = "3 strings", +-- public = true, +-- actions = function(a,b,c) +-- ctx_latelua(function() save(a,c) end) +-- end, +-- } + +-- implement { +-- name = "lazysavetaggedtwopassdata", +-- arguments = "3 strings", +-- public = true, +-- actions = function(a,b,c) +-- ctx_latelua(function() savetagged(a,b,c) end) +-- end, +-- } diff --git a/tex/context/base/mkiv/core-two.mkiv b/tex/context/base/mkiv/core-two.mkiv index f83d63042..aae4902bc 100644 --- a/tex/context/base/mkiv/core-two.mkiv +++ b/tex/context/base/mkiv/core-two.mkiv @@ -74,10 +74,10 @@ \registerctxluafile{core-two}{} \def\immediatesavetwopassdata #1#2#3{\normalexpanded{\noexpand\clf_savetwopassdata{#1}{#3}}} -\def\savetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatecommand{savetwopassdata('#1',"#3")}}} -\def\lazysavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatecommand{savetwopassdata('#1',"#3")}}} -\def\savetaggedtwopassdata #1#2#3#4{\normalexpanded{\noexpand\clf_savetaggedtwopassdata{#1}{#3}{#4}}} -\def\lazysavetaggedtwopassdata#1#2#3#4{\normalexpanded{\noexpand\ctxlatecommand{savetaggedtwopassdata('#1','#3',"#4")}}} +\def \lazysavetwopassdata #1#2#3{\normalexpanded{\noexpand\ctxlatecommand{savetwopassdata("#1","#3")}}} +\let \savetwopassdata \lazysavetwopassdata +\def \savetaggedtwopassdata#1#2#3#4{\normalexpanded{\noexpand\clf_savetaggedtwopassdata{#1}{#3}{#4}}} +\def\lazysavetaggedtwopassdata#1#2#3#4{\normalexpanded{\noexpand\ctxlatecommand{savetaggedtwopassdata("#1",'#3',"#4")}}} % temp hack: needs a proper \starteverytimeluacode diff --git a/tex/context/base/mkiv/core-uti.lua b/tex/context/base/mkiv/core-uti.lua index b281b81a4..cd867db1b 100644 --- a/tex/context/base/mkiv/core-uti.lua +++ b/tex/context/base/mkiv/core-uti.lua @@ -43,7 +43,7 @@ local report_passes = logs.reporter("job","passes") job = job or { } local job = job -job.version = 1.30 +job.version = 1.31 job.packversion = 1.02 -- some day we will implement loading of other jobs and then we need @@ -195,6 +195,7 @@ end local packlist = { "numbers", + "ownnumbers", "metadata", "sectiondata", "prefixdata", @@ -209,6 +210,7 @@ local packlist = { local skiplist = { "datasets", "userdata", + "positions", } -- not ok as we can have arbitrary keys in userdata and dataset so some day we @@ -398,7 +400,7 @@ function statistics.callbacks() local c_internal = status.callbacks or 0 local c_file = status.indirect_callbacks or 0 local c_direct = status.direct_callbacks or 0 - local c_late = status.late_callbacks or 0 + local c_late = backends.noflatelua() or 0 local c_function = status.function_callbacks or 0 local c_total = c_internal + c_file + c_direct + c_late + c_function local n_pages = texgetcount('realpageno') - 1 @@ -430,6 +432,7 @@ end) -- local used_wood_factor = watts_per_core * kg_per_watt_per_second / speedup_by_other_engine -- local used_wood_factor = (50 / 15000000) / 1.2 + function statistics.formatruntime(runtime) if not environment.initex then -- else error when testing as not counters yet -- stoptiming(statistics) -- to be sure @@ -438,19 +441,15 @@ function statistics.formatruntime(runtime) if pages > shipped then pages = shipped end + runtime = tonumber(runtime) if shipped > 0 or pages > 0 then - runtime = tonumber(runtime) local persecond = (runtime > 0) and (shipped/runtime) or pages - if pages == 0 then pages = shipped end - -- if TEXENGINE == "luajittex" then - -- local saved = watts_per_core * runtime * kg_per_watt_per_second / speedup_by_other_engine - -- local saved = used_wood_factor * runtime - -- return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second, %f mg tree saved by using luajittex",runtime,pages,shipped,persecond,saved*1000*1000) - -- else - return format("%s seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond) - -- end + if pages == 0 then + pages = shipped + end + return format("%0.3f seconds, %i processed pages, %i shipped pages, %.3f pages/second",runtime,pages,shipped,persecond) else - return format("%s seconds",runtime) + return format("%0.3f seconds",runtime) end end end diff --git a/tex/context/base/mkiv/data-aux.lua b/tex/context/base/mkiv/data-aux.lua index 1e020d1e8..c57f16d2c 100644 --- a/tex/context/base/mkiv/data-aux.lua +++ b/tex/context/base/mkiv/data-aux.lua @@ -50,7 +50,7 @@ function resolvers.updatescript(oldname,newname) -- oldname -> own.name, not per local newdata = io.loaddata(newscript) if newdata then if trace_locating then - report_scripts("old script content replaced by new content") + report_scripts("old script content replaced by new content: %s",oldscript) end io.savedata(oldscript,newdata) break diff --git a/tex/context/base/mkiv/data-pre.lua b/tex/context/base/mkiv/data-pre.lua index 70b2e7354..5e3020b70 100644 --- a/tex/context/base/mkiv/data-pre.lua +++ b/tex/context/base/mkiv/data-pre.lua @@ -6,6 +6,25 @@ if not modules then modules = { } end modules ['data-pre'] = { license = "see context related readme files" } +-- filename : only the basename, including suffix (file:) +-- pathname : the pathpart (path:) +-- locate : lookup in database (full: kpse: loc:) +-- home : home path +-- jobpath : job path +-- relative : relative path ./ ../ ../.. (rel:) +-- auto : relatove or lookup +-- toppath : topmost path in input stack +-- selfautodir : rather tex specific +-- selfautoloc : rather tex specific +-- selfautoparent : rather tex specific +-- environment : expansion of variable (env:) +-- +-- nodename : computer name +-- machine : private, when set +-- sysname : operating system name +-- version : operating system version +-- release : operating system release + local resolvers = resolvers local prefixes = resolvers.prefixes @@ -140,7 +159,6 @@ resolvers.setdynamic("toppath") resolvers.setdynamic("jobpath") -- for a while (obsolete): - -prefixes.jobfile = prefixes.jobpath - -resolvers.setdynamic("jobfile") +-- +-- prefixes.jobfile = prefixes.jobpath +-- resolvers.setdynamic("jobfile") diff --git a/tex/context/base/mkiv/data-res.lua b/tex/context/base/mkiv/data-res.lua index 9fb33f88d..0c2735fc2 100644 --- a/tex/context/base/mkiv/data-res.lua +++ b/tex/context/base/mkiv/data-res.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['data-res'] = { -- todo: cache:/// home:/// selfautoparent:/// (sometime end 2012) local gsub, find, lower, upper, match, gmatch = string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch -local concat, insert, remove, sortedkeys, sortedhash = table.concat, table.insert, table.remove, table.sortedkeys, table.sortedhash +local concat, insert, remove = table.concat, table.insert, table.remove local next, type, rawget = next, type, rawget local os = os @@ -1875,7 +1875,7 @@ function resolvers.booleanvariable(str,default) end function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move, can be a nice iterator instead - local hashes = instance.hashes + local hashes = instance.hashes for i=1,#hashes do local hash = hashes[i] local blobtype = hash.type @@ -1903,7 +1903,7 @@ function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move, end end if after then - after(blobtype,blobpath,pattern,total,checked,done) + after(blobtype,blobpath,pattern,checked,done) end end end diff --git a/tex/context/base/mkiv/data-tex.lua b/tex/context/base/mkiv/data-tex.lua index 2d2c9b24d..8f978a204 100644 --- a/tex/context/base/mkiv/data-tex.lua +++ b/tex/context/base/mkiv/data-tex.lua @@ -149,19 +149,19 @@ function helpers.textopener(tag,filename,filehandle,coding) currentline = currentline + 1 -- self.currentline = currentline local content = lines[currentline] - if not content then - return nil - elseif content == "" then + if content == "" then return "" -- elseif content == ctrl_d or ctrl_z then -- return nil -- we need this as \endinput does not work in prints - else + elseif content then local runner = textlineactions.runner if runner then return runner(content,filename,currentline,noflines,coding) or content else return content end + else + return nil end end end diff --git a/tex/context/base/mkiv/data-tre.lua b/tex/context/base/mkiv/data-tre.lua index 4388731f9..c4d43e3eb 100644 --- a/tex/context/base/mkiv/data-tre.lua +++ b/tex/context/base/mkiv/data-tre.lua @@ -100,11 +100,10 @@ end function resolvers.hashers.tree(specification) local name = specification.filename - -- if trace_locating then + if trace_locating then report_trees("analyzing %a",name) - -- end + end resolvers.methodhandler("hashers",name) - resolvers.generators.file(specification) end diff --git a/tex/context/base/mkiv/data-use.lua b/tex/context/base/mkiv/data-use.lua index ff25c803a..5985a2eac 100644 --- a/tex/context/base/mkiv/data-use.lua +++ b/tex/context/base/mkiv/data-use.lua @@ -69,7 +69,11 @@ function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner) - } io.savedata(luvname,table.serialize(luvdata,true)) lua.registerfinalizer(function() - logs.report("format banner","%s",banner) + if jit then + logs.report("format banner","%s lua: %s jit",banner,LUAVERSION) + else + logs.report("format banner","%s lua: %s",banner,LUAVERSION) + end logs.newline() end) end diff --git a/tex/context/base/mkiv/data-zip.lua b/tex/context/base/mkiv/data-zip.lua index 32666bef2..6f20b4a9d 100644 --- a/tex/context/base/mkiv/data-zip.lua +++ b/tex/context/base/mkiv/data-zip.lua @@ -31,11 +31,11 @@ local resolvers = resolvers zip = zip or { } local zip = zip -zip.archives = zip.archives or { } -local archives = zip.archives +local archives = zip.archives or { } +zip.archives = archives -zip.registeredfiles = zip.registeredfiles or { } -local registeredfiles = zip.registeredfiles +local registeredfiles = zip.registeredfiles or { } +zip.registeredfiles = registeredfiles local function validzip(str) -- todo: use url splitter if not find(str,"^zip://") then @@ -108,7 +108,7 @@ function resolvers.finders.zip(specification) end local dfile = zfile:open(queryname) if dfile then - dfile = zfile:close() + dfile:close() if trace_locating then report_zip("finder: file %a found",queryname) end diff --git a/tex/context/base/mkiv/driv-ini.lua b/tex/context/base/mkiv/driv-ini.lua new file mode 100644 index 000000000..e16327f27 --- /dev/null +++ b/tex/context/base/mkiv/driv-ini.lua @@ -0,0 +1,194 @@ +if not modules then modules = { } end modules ['driv-ini'] = { + version = 1.001, + comment = "companion to driv-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type = type +local addsuffix = file.addsuffix + +local setmetatableindex = table.setmetatableindex +local formatters = string.formatters + +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming + +local report = logs.reporter("drivers") + +local instances = { } +local helpers = { } +local prepared = { } +local wrappedup = { } +local currentdriver = "default" + +local prepare = nil +local convert = nil +local wrapup = nil +local outputfilename = nil + +drivers = drivers or { + instances = instances, + helpers = helpers, + lmtxversion = 0.10, +} + +local dummy = function() end + +local defaulthandlers = { + prepare = dummy, + initialize = dummy, + finalize = dummy, + updatefontstate = dummy, + wrapup = dummy, + convert = dummy, + outputfilename = dummy, +} + +function drivers.install(specification) + local name = specification.name + if not name then + report("missing driver name") + return + end + local actions = specification.actions + if not actions then + report("no actions for driver %a",name) + return + end + local flushers = specification.flushers + if not flushers then + report("no flushers for driver %a",name) + return + end + setmetatableindex(actions,defaulthandlers) + instances[name] = specification +end + +function drivers.convert(boxnumber) + callbacks.functions.start_page_number() + starttiming(drivers) + convert(boxnumber) + stoptiming(drivers) + callbacks.functions.stop_page_number() +end + +function drivers.outputfilename() + return outputfilename() +end + + +luatex.wrapup(function() + if not wrappedup[currentdriver] then + starttiming(drivers) + wrapup() + stoptiming(drivers) + wrappedup[currentdriver] = true + end +end) + +function drivers.enable(name) + currentdriver = name or "default" + local actions = instances[currentdriver].actions + prepare = actions.prepare + wrapup = actions.wrapup + convert = actions.convert + outputfilename = actions.outputfilename + -- + if prepare and not prepared[currentdriver] then + starttiming(drivers) + prepare() + stoptiming(drivers) + prepared[currentdriver] = true + end +end + +statistics.register("driver time",function() + return statistics.elapsedseconds(drivers) +end) + +interfaces.implement { + name = "shipoutpage", + arguments = "integer", + actions = drivers.convert, +} + +interfaces.implement { + name = "enabledriver", + arguments = "string", + actions = drivers.enable, +} + +-- The default driver: + +do + + local filename = nil + + drivers.install { + name = "default", + actions = { + convert = tex.shipout, + outputfilename = function() + if not filename then + filename = addsuffix(tex.jobname,"pdf") + end + return filename + end, + }, + flushers = { + -- we always need this entry + }, + } + +end + +setmetatableindex(instances,function() return instances.default end) + +-- for now: + +drivers.enable("default") + +-- helpers + +local s_matrix_0 = "1 0 0 1" +local f_matrix_2 = formatters["%.6F 0 0 %.6F"] +local f_matrix_4 = formatters["%.6F %.6F %.6F %.6F"] + +directives.register("pdf.stripzeros",function() + f_matrix_2 = formatters["%.6N 0 0 %.6N"] + f_matrix_4 = formatters["%.6N %.6N %.6N %.6N"] +end) + +function helpers.tomatrix(rx,sx,sy,ry,tx,ty) -- todo: tx ty + if type(rx) == "string" then + return rx + else + if not rx then + rx = 1 + elseif rx == 0 then + rx = 0.0001 + end + if not ry then + ry = 1 + elseif ry == 0 then + ry = 0.0001 + end + if not sx then + sx = 0 + end + if not sy then + sy = 0 + end + if sx == 0 and sy == 0 then + if rx == 1 and ry == 1 then + return s_matrix_0 + else + return f_matrix_2(rx,ry) + end + else + return f_matrix_4(rx,sx,sy,ry) + end + end +end diff --git a/tex/context/base/mkiv/driv-ini.mkiv b/tex/context/base/mkiv/driv-ini.mkiv new file mode 100644 index 000000000..95b6c88a7 --- /dev/null +++ b/tex/context/base/mkiv/driv-ini.mkiv @@ -0,0 +1,25 @@ +%D \module +%D [ file=driv-ini, +%D version=2018.07.26, +%D title=\CONTEXT\ Driver Macros, +%D subtitle=Initialization, +%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 Driver Macros / Initialization} + +\registerctxluafile{driv-ini}{} + +\unprotect + +\def\page_shipout_box#1% + {\clf_shipoutpage#1\relax + \setbox#1\emptybox + \global\deadcycles\zerocount} + +\protect \endinput diff --git a/tex/context/base/mkiv/export-example.css b/tex/context/base/mkiv/export-example.css index 812873afc..c39f0bec6 100644 --- a/tex/context/base/mkiv/export-example.css +++ b/tex/context/base/mkiv/export-example.css @@ -34,8 +34,9 @@ @namespace context url('http://www.pragma-ade.com/context/export') ; -/* ignore : mixed */ -/* metadata: display */ +/* ignore : mixed */ +/* metadata : display */ +/* extradata: display */ ignore, context|div.ignore { @@ -57,6 +58,11 @@ context|div.xmetavariable { display : none ; } +extradata, +context|div.extradata { + display : none ; +} + /* document : display */ document:before, @@ -679,6 +685,7 @@ context|div.combinationcaption { /* listcontent : mixed */ /* listdata : mixed */ /* listpage : mixed */ +/* listtext : inline */ list, context|div.list { @@ -758,6 +765,11 @@ context|div.listpage { display : none ; } +listtext, +context|div.listtext { + display : inline ; +} + /* delimitedblock : display */ /* delimited : inline */ /* delimitedsymbol : inline */ @@ -1024,6 +1036,20 @@ context|div.math-display { margin : 1ex 0ex 1em 3em ; } +/* publication : inline */ +/* pubfld : inline */ + +publication, +context|div.publication { + display : inline ; +} + +pubfld[detail="title"], +context|div.pubfld.title { + display : inline ; + font-weight : italic ; +} + /* quantity : inline */ /* unit : inline */ /* number : inline */ @@ -1097,6 +1123,13 @@ context|div.comment { font-family : "DejaVu Sans Mono", "Lucida Console", monospace ; } +/* blocks */ + +block, +context|div.block { + display : block ; +} + /* special */ c, diff --git a/tex/context/base/mkiv/file-job.lua b/tex/context/base/mkiv/file-job.lua index dbf6da9b4..486aee63a 100644 --- a/tex/context/base/mkiv/file-job.lua +++ b/tex/context/base/mkiv/file-job.lua @@ -386,7 +386,6 @@ local function starttext() if trace_jobfiles then report_jobfiles("starting text") end - -- registerfileinfo[begin]jobfilename context.dostarttext() end textlevel = textlevel + 1 @@ -406,8 +405,6 @@ local function stoptext() report_jobfiles("stopping text") end context.dostoptext() - -- registerfileinfo[end]jobfilename - context.finalend() stopped = true end end diff --git a/tex/context/base/mkiv/file-job.mkvi b/tex/context/base/mkiv/file-job.mkvi index e1ea405c0..a46e519c0 100644 --- a/tex/context/base/mkiv/file-job.mkvi +++ b/tex/context/base/mkiv/file-job.mkvi @@ -312,6 +312,12 @@ {\documentvariable\c!after \stoptext} +\unexpanded\def\doifelsedocumentvariable#name{\doifelsesomething{\documentvariable{#name}}} +\unexpanded\def\doifdocumentvariable #name{\doifsomething {\documentvariable{#name}}} +\unexpanded\def\doifnotdocumentvariable #name{\doifnot {\documentvariable{#name}}} + +\let\doifdocumentvariableelse\doifelsedocumentvariable + \def\documentvariable#name% {\getvariable\s!document{#name}} @@ -347,12 +353,15 @@ % Bonus: -\installcorenamespace{samplefile} +% \installcorenamespace{samplefile} +% +% \unexpanded\def\samplefile#1% +% {\ifcsname\??samplefile#1\endcsname \else +% \setxvalue{\??samplefile#1}{\cldloadfile{#1}}% +% \fi +% \lastnamedcs} \unexpanded\def\samplefile#1% - {\ifcsname\??samplefile#1\endcsname \else - \setxvalue{\??samplefile#1}{\cldloadfile{#1}}% - \fi - \lastnamedcs} + {\clf_samplefile{#1}} \protect \endinput diff --git a/tex/context/base/mkiv/file-mod.mkvi b/tex/context/base/mkiv/file-mod.mkvi index a2a3b7793..a06770e24 100644 --- a/tex/context/base/mkiv/file-mod.mkvi +++ b/tex/context/base/mkiv/file-mod.mkvi @@ -36,9 +36,9 @@ \let\usetexmodule\usemodules \def\strc_modules_use[#category][#name][#parameters]% category=t|m|x|p|... - {\pushmacro\currentmodule - \pushmacro\currentmodulecategory - \pushmacro\currentmoduleparameters + {\push_macro_currentmodule + \push_macro_currentmodulecategory + \push_macro_currentmoduleparameters \ifthirdargument \edef\currentmodulecategory {#category}% \edef\currentmodule {#name}% @@ -57,9 +57,9 @@ \let \currentmoduleparameters\empty \fi\fi \processcommacommand[\currentmodule]{\strc_modules_use_indeed\currentmodulecategory}% - \popmacro\currentmoduleparameters - \popmacro\currentmodulecategory - \popmacro\currentmodule} + \pop_macro_currentmoduleparameters + \pop_macro_currentmodulecategory + \pop_macro_currentmodule} \def\strc_modules_use_indeed#category#name% {\ifx\currentmoduleparameters\empty\else @@ -70,20 +70,24 @@ \installcorenamespace{module} -\let\currentmoduleparameters\empty \let\currentmodule \s!unknown +\let\currentmodulecategory \empty +\let\currentmoduleparameters\empty -\newcount \c_syst_modules_nesting +\installmacrostack\currentmodule +\installmacrostack\currentmodulecategory +\installmacrostack\currentmoduleparameters -\newtoks\everysetupmodule +\newcount\c_syst_modules_nesting +\newtoks \everysetupmodule \unexpanded\def\startmodule {\doifelsenextoptionalcs\syst_modules_start_yes\syst_modules_start_nop} \def\syst_modules_start_yes[#name]% {\global\advance\c_syst_modules_nesting\plusone - \pushmacro\currentmodule - \pushmacro\currentmoduleparameters + \push_macro_currentmodule + \push_macro_currentmoduleparameters \def\currentmodule{#name}} \def\syst_modules_start_nop#name % @@ -93,8 +97,8 @@ {\ifcase\c_syst_modules_nesting \writestatus\m!system{module wrapping error in '\currentmodule'}% \else - \popmacro\currentmoduleparameters - \popmacro\currentmodule + \pop_macro_currentmoduleparameters + \pop_macro_currentmodule \global\advance\c_syst_modules_nesting\minusone \fi} @@ -203,7 +207,7 @@ {\ifcsname\??runtimeloaded#2\endcsname % already loaded \else - \global\let#1\undefined + \glet#1\undefined \startreadingfile \startnointerference % \bgroup \cleanupfeatures % better \setnormalcatcodes / test first diff --git a/tex/context/base/mkiv/font-aux.lua b/tex/context/base/mkiv/font-aux.lua index fcbcd6d32..4ac6278cb 100644 --- a/tex/context/base/mkiv/font-aux.lua +++ b/tex/context/base/mkiv/font-aux.lua @@ -185,6 +185,7 @@ end local getters = { -- maybe better getters[format][...] kern = { ["type1"] = afm.getkern, + ["type3"] = afm.getkern, ["opentype"] = otf.getkern, }, substitution = { diff --git a/tex/context/base/mkiv/font-cff.lua b/tex/context/base/mkiv/font-cff.lua index 1d4f01007..46deedb5f 100644 --- a/tex/context/base/mkiv/font-cff.lua +++ b/tex/context/base/mkiv/font-cff.lua @@ -26,14 +26,16 @@ if not modules then modules = { } end modules ['font-cff'] = { -- with merging subroutines and flattening, not so much with calculations.) On -- the other hand, we can now feed back cff2 stuff. -local next, type, tonumber = next, type, tonumber +local next, type, tonumber, rawget = next, type, tonumber, rawget local byte, char, gmatch = string.byte, string.char, string.gmatch -local concat, remove = table.concat, table.remove +local concat, remove, unpack = table.concat, table.remove, table.unpack local floor, abs, round, ceil, min, max = math.floor, math.abs, math.round, math.ceil, math.min, math.max local P, C, R, S, C, Cs, Ct = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Ct local lpegmatch = lpeg.match local formatters = string.formatters local bytetable = string.bytetable +local idiv = number.idiv +local rshift, band, extract = bit32.rshift, bit32.band, bit32.extract local readers = fonts.handlers.otf.readers local streamreader = readers.streamreader @@ -47,6 +49,21 @@ local setposition = streamreader.setposition local getposition = streamreader.getposition local readbytetable = streamreader.readbytetable +directives.register("fonts.streamreader",function() + + streamreader = utilities.streams + + readstring = streamreader.readstring + readbyte = streamreader.readcardinal1 + readushort = streamreader.readcardinal2 + readuint = streamreader.readcardinal3 + readulong = streamreader.readcardinal4 + setposition = streamreader.setposition + getposition = streamreader.getposition + readbytetable = streamreader.readbytetable + +end) + local setmetatableindex = table.setmetatableindex local trace_charstrings = false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings = v end) @@ -272,12 +289,30 @@ do result.fontbbox = { unpack(stack,1,4) } top = 0 end - -- + P("\06") / function() end -- bluevalues - -- + P("\07") / function() end -- otherblues - -- + P("\08") / function() end -- familyblues - -- + P("\09") / function() end -- familyotherblues - -- + P("\10") / function() end -- strhw - -- + P("\11") / function() end -- stdvw + + P("\06") / function() + result.bluevalues = { unpack(stack,1,top) } + top = 0 + end + + P("\07") / function() + result.otherblues = { unpack(stack,1,top) } + top = 0 + end + + P("\08") / function() + result.familyblues = { unpack(stack,1,top) } + top = 0 + end + + P("\09") / function() + result.familyotherblues = { unpack(stack,1,top) } + top = 0 + end + + P("\10") / function() + result.strhw = stack[top] + top = 0 + end + + P("\11") / function() + result.strvw = stack[top] + top = 0 + end + P("\13") / function() result.uniqueid = stack[top] top = 0 @@ -371,6 +406,26 @@ do result.strokewidth = stack[top] top = 0 end + + P("\09") / function() + result.bluescale = stack[top] + top = 0 + end + + P("\10") / function() + result.bluesnap = stack[top] + top = 0 + end + + P("\11") / function() + result.bluefuzz = stack[top] + top = 0 + end + + P("\12") / function() + result.stemsnaph = { unpack(stack,1,top) } + top = 0 + end + + P("\13") / function() + result.stemsnapv = { unpack(stack,1,top) } + top = 0 + end + P("\20") / function() result.syntheticbase = stack[top] top = 0 @@ -431,52 +486,27 @@ do -- the second variant is much faster. Not that it matters much as we don't see -- such numbers often. - local p_last = P("\x0F") / "0" + P("\x1F") / "1" + P("\x2F") / "2" + P("\x3F") / "3" - + P("\x4F") / "4" + P("\x5F") / "5" + P("\x6F") / "6" + P("\x7F") / "7" - + P("\x8F") / "8" + P("\x9F") / "9" + P("\xAF") / "" + P("\xBF") / "" - + P("\xCF") / "" + P("\xDF") / "" + P("\xEF") / "" + R("\xF0\xFF") / "" - - -- local remap = { [0] = - -- "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0.", "0E", "0E-", "0", "0-", "0", - -- "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "0.", "0E", "0E-", "0", "0-", "0", - -- "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "0.", "0E", "0E-", "0", "0-", "0", - -- "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "0.", "0E", "0E-", "0", "0-", "0", - -- "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "0.", "0E", "0E-", "0", "0-", "0", - -- "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "0.", "0E", "0E-", "0", "0-", "0", - -- "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "0.", "0E", "0E-", "0", "0-", "0", - -- "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "0.", "0E", "0E-", "0", "0-", "0", - -- "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "0.", "0E", "0E-", "0", "0-", "0", - -- "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "0.", "0E", "0E-", "0", "0-", "0", - -- ".0", ".1", ".2", ".3", ".4", ".5", ".6", ".7", ".8", ".9", "..", ".E", ".E-", ".", ".-", ".", - -- "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "E.", "EE", "EE-", "E", "E-", "E", - -- "E-0", "E-1", "E-2", "E-3", "E-4", "E-5", "E-6", "E-7", "E-8", "E-9", "E-.", "E-E", "E-E-", "E-", "E--", "E-", - -- "-0", "-1", "-2", "-3", "-4", "-5", "-6", "-7", "-8", "-9", "-.", "-E", "-E-", "-", "--", "-", - -- } - - -- local p_nibbles = Cs(((1-p_last)/byte/remap)^0+p_last) - - -- local p = P("\30") * p_nibbles / function(t) - -- print(tonumber(t)) - -- end - local remap = { ["\x00"] = "00", ["\x01"] = "01", ["\x02"] = "02", ["\x03"] = "03", ["\x04"] = "04", ["\x05"] = "05", ["\x06"] = "06", ["\x07"] = "07", ["\x08"] = "08", ["\x09"] = "09", ["\x0A"] = "0.", ["\x0B"] = "0E", ["\x0C"] = "0E-", ["\x0D"] = "0", ["\x0E"] = "0-", ["\x0F"] = "0", - ["\x10"] = "10", ["\x11"] = "11", ["\x12"] = "12", ["\x13"] = "13", ["\x14"] = "14", ["\x15"] = "15", ["\x16"] = "16", ["\x17"] = "17", ["\x18"] = "18", ["\x19"] = "19", ["\x1A"] = "0.", ["\x1B"] = "0E", ["\x1C"] = "0E-", ["\x1D"] = "0", ["\x1E"] = "0-", ["\x1F"] = "0", - ["\x20"] = "20", ["\x21"] = "21", ["\x22"] = "22", ["\x23"] = "23", ["\x24"] = "24", ["\x25"] = "25", ["\x26"] = "26", ["\x27"] = "27", ["\x28"] = "28", ["\x29"] = "29", ["\x2A"] = "0.", ["\x2B"] = "0E", ["\x2C"] = "0E-", ["\x2D"] = "0", ["\x2E"] = "0-", ["\x2F"] = "0", - ["\x30"] = "30", ["\x31"] = "31", ["\x32"] = "32", ["\x33"] = "33", ["\x34"] = "34", ["\x35"] = "35", ["\x36"] = "36", ["\x37"] = "37", ["\x38"] = "38", ["\x39"] = "39", ["\x3A"] = "0.", ["\x3B"] = "0E", ["\x3C"] = "0E-", ["\x3D"] = "0", ["\x3E"] = "0-", ["\x3F"] = "0", - ["\x40"] = "40", ["\x41"] = "41", ["\x42"] = "42", ["\x43"] = "43", ["\x44"] = "44", ["\x45"] = "45", ["\x46"] = "46", ["\x47"] = "47", ["\x48"] = "48", ["\x49"] = "49", ["\x4A"] = "0.", ["\x4B"] = "0E", ["\x4C"] = "0E-", ["\x4D"] = "0", ["\x4E"] = "0-", ["\x4F"] = "0", - ["\x50"] = "50", ["\x51"] = "51", ["\x52"] = "52", ["\x53"] = "53", ["\x54"] = "54", ["\x55"] = "55", ["\x56"] = "56", ["\x57"] = "57", ["\x58"] = "58", ["\x59"] = "59", ["\x5A"] = "0.", ["\x5B"] = "0E", ["\x5C"] = "0E-", ["\x5D"] = "0", ["\x5E"] = "0-", ["\x5F"] = "0", - ["\x60"] = "60", ["\x61"] = "61", ["\x62"] = "62", ["\x63"] = "63", ["\x64"] = "64", ["\x65"] = "65", ["\x66"] = "66", ["\x67"] = "67", ["\x68"] = "68", ["\x69"] = "69", ["\x6A"] = "0.", ["\x6B"] = "0E", ["\x6C"] = "0E-", ["\x6D"] = "0", ["\x6E"] = "0-", ["\x6F"] = "0", - ["\x70"] = "70", ["\x71"] = "71", ["\x72"] = "72", ["\x73"] = "73", ["\x74"] = "74", ["\x75"] = "75", ["\x76"] = "76", ["\x77"] = "77", ["\x78"] = "78", ["\x79"] = "79", ["\x7A"] = "0.", ["\x7B"] = "0E", ["\x7C"] = "0E-", ["\x7D"] = "0", ["\x7E"] = "0-", ["\x7F"] = "0", - ["\x80"] = "80", ["\x81"] = "81", ["\x82"] = "82", ["\x83"] = "83", ["\x84"] = "84", ["\x85"] = "85", ["\x86"] = "86", ["\x87"] = "87", ["\x88"] = "88", ["\x89"] = "89", ["\x8A"] = "0.", ["\x8B"] = "0E", ["\x8C"] = "0E-", ["\x8D"] = "0", ["\x8E"] = "0-", ["\x8F"] = "0", - ["\x90"] = "90", ["\x91"] = "91", ["\x92"] = "92", ["\x93"] = "93", ["\x94"] = "94", ["\x95"] = "95", ["\x96"] = "96", ["\x97"] = "97", ["\x98"] = "98", ["\x99"] = "99", ["\x9A"] = "0.", ["\x9B"] = "0E", ["\x9C"] = "0E-", ["\x9D"] = "0", ["\x9E"] = "0-", ["\x9F"] = "0", + ["\x10"] = "10", ["\x11"] = "11", ["\x12"] = "12", ["\x13"] = "13", ["\x14"] = "14", ["\x15"] = "15", ["\x16"] = "16", ["\x17"] = "17", ["\x18"] = "18", ["\x19"] = "19", ["\x1A"] = "1.", ["\x1B"] = "1E", ["\x1C"] = "1E-", ["\x1D"] = "1", ["\x1E"] = "1-", ["\x1F"] = "1", + ["\x20"] = "20", ["\x21"] = "21", ["\x22"] = "22", ["\x23"] = "23", ["\x24"] = "24", ["\x25"] = "25", ["\x26"] = "26", ["\x27"] = "27", ["\x28"] = "28", ["\x29"] = "29", ["\x2A"] = "2.", ["\x2B"] = "2E", ["\x2C"] = "2E-", ["\x2D"] = "2", ["\x2E"] = "2-", ["\x2F"] = "2", + ["\x30"] = "30", ["\x31"] = "31", ["\x32"] = "32", ["\x33"] = "33", ["\x34"] = "34", ["\x35"] = "35", ["\x36"] = "36", ["\x37"] = "37", ["\x38"] = "38", ["\x39"] = "39", ["\x3A"] = "3.", ["\x3B"] = "3E", ["\x3C"] = "3E-", ["\x3D"] = "3", ["\x3E"] = "3-", ["\x3F"] = "3", + ["\x40"] = "40", ["\x41"] = "41", ["\x42"] = "42", ["\x43"] = "43", ["\x44"] = "44", ["\x45"] = "45", ["\x46"] = "46", ["\x47"] = "47", ["\x48"] = "48", ["\x49"] = "49", ["\x4A"] = "4.", ["\x4B"] = "4E", ["\x4C"] = "4E-", ["\x4D"] = "4", ["\x4E"] = "4-", ["\x4F"] = "4", + ["\x50"] = "50", ["\x51"] = "51", ["\x52"] = "52", ["\x53"] = "53", ["\x54"] = "54", ["\x55"] = "55", ["\x56"] = "56", ["\x57"] = "57", ["\x58"] = "58", ["\x59"] = "59", ["\x5A"] = "5.", ["\x5B"] = "5E", ["\x5C"] = "5E-", ["\x5D"] = "5", ["\x5E"] = "5-", ["\x5F"] = "5", + ["\x60"] = "60", ["\x61"] = "61", ["\x62"] = "62", ["\x63"] = "63", ["\x64"] = "64", ["\x65"] = "65", ["\x66"] = "66", ["\x67"] = "67", ["\x68"] = "68", ["\x69"] = "69", ["\x6A"] = "6.", ["\x6B"] = "6E", ["\x6C"] = "6E-", ["\x6D"] = "6", ["\x6E"] = "6-", ["\x6F"] = "6", + ["\x70"] = "70", ["\x71"] = "71", ["\x72"] = "72", ["\x73"] = "73", ["\x74"] = "74", ["\x75"] = "75", ["\x76"] = "76", ["\x77"] = "77", ["\x78"] = "78", ["\x79"] = "79", ["\x7A"] = "7.", ["\x7B"] = "7E", ["\x7C"] = "7E-", ["\x7D"] = "7", ["\x7E"] = "7-", ["\x7F"] = "7", + ["\x80"] = "80", ["\x81"] = "81", ["\x82"] = "82", ["\x83"] = "83", ["\x84"] = "84", ["\x85"] = "85", ["\x86"] = "86", ["\x87"] = "87", ["\x88"] = "88", ["\x89"] = "89", ["\x8A"] = "8.", ["\x8B"] = "8E", ["\x8C"] = "8E-", ["\x8D"] = "8", ["\x8E"] = "8-", ["\x8F"] = "8", + ["\x90"] = "90", ["\x91"] = "91", ["\x92"] = "92", ["\x93"] = "93", ["\x94"] = "94", ["\x95"] = "95", ["\x96"] = "96", ["\x97"] = "97", ["\x98"] = "98", ["\x99"] = "99", ["\x9A"] = "9.", ["\x9B"] = "9E", ["\x9C"] = "9E-", ["\x9D"] = "9", ["\x9E"] = "9-", ["\x9F"] = "9", ["\xA0"] = ".0", ["\xA1"] = ".1", ["\xA2"] = ".2", ["\xA3"] = ".3", ["\xA4"] = ".4", ["\xA5"] = ".5", ["\xA6"] = ".6", ["\xA7"] = ".7", ["\xA8"] = ".8", ["\xA9"] = ".9", ["\xAA"] = "..", ["\xAB"] = ".E", ["\xAC"] = ".E-", ["\xAD"] = ".", ["\xAE"] = ".-", ["\xAF"] = ".", ["\xB0"] = "E0", ["\xB1"] = "E1", ["\xB2"] = "E2", ["\xB3"] = "E3", ["\xB4"] = "E4", ["\xB5"] = "E5", ["\xB6"] = "E6", ["\xB7"] = "E7", ["\xB8"] = "E8", ["\xB9"] = "E9", ["\xBA"] = "E.", ["\xBB"] = "EE", ["\xBC"] = "EE-", ["\xBD"] = "E", ["\xBE"] = "E-", ["\xBF"] = "E", ["\xC0"] = "E-0", ["\xC1"] = "E-1", ["\xC2"] = "E-2", ["\xC3"] = "E-3", ["\xC4"] = "E-4", ["\xC5"] = "E-5", ["\xC6"] = "E-6", ["\xC7"] = "E-7", ["\xC8"] = "E-8", ["\xC9"] = "E-9", ["\xCA"] = "E-.", ["\xCB"] = "E-E", ["\xCC"] = "E-E-", ["\xCD"] = "E-", ["\xCE"] = "E--", ["\xCF"] = "E-", ["\xD0"] = "-0", ["\xD1"] = "-1", ["\xD2"] = "-2", ["\xD3"] = "-3", ["\xD4"] = "-4", ["\xD5"] = "-5", ["\xD6"] = "-6", ["\xD7"] = "-7", ["\xD8"] = "-8", ["\xD9"] = "-9", ["\xDA"] = "-.", ["\xDB"] = "-E", ["\xDC"] = "-E-", ["\xDD"] = "-", ["\xDE"] = "--", ["\xDF"] = "-", } - local p_nibbles = P("\30") * Cs(((1-p_last)/remap)^0+p_last) / function(n) + local p_last = S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF") + + R("\xF0\xFF") + + local p_nibbles = P("\30") * Cs(((1-p_last)/remap)^0 * (P(1)/remap)) / function(n) -- 0-9=digit a=. b=E c=E- d=reserved e=- f=finish top = top + 1 stack[top] = tonumber(n) or 0 @@ -1215,7 +1245,7 @@ do if trace_charstrings then showstate("stem") end - stems = stems + top/2 + stems = stems + idiv(top,2) top = 0 end @@ -1236,14 +1266,15 @@ do if trace_charstrings then showstate(operator == 19 and "hintmark" or "cntrmask") end - stems = stems + top/2 + stems = stems + idiv(top,2) top = 0 if stems == 0 then -- forget about it elseif stems <= 8 then return 1 else - return floor((stems+7)/8) + -- return floor((stems+7)/8) + return idiv(stems+7,8) end end @@ -1290,8 +1321,9 @@ do local function hsbw() if version == 1 then if trace_charstrings then - showstate("dotsection") + showstate("hsbw") end + -- lsb = stack[top-1] width = stack[top] end top = 0 @@ -1513,88 +1545,115 @@ do [037] = flex1, } - local c_endchar = char(14) + local chars = setmetatableindex(function (t,k) + local v = char(k) + t[k] = v + return v + end) - local passon do + local c_endchar = chars[14] - -- todo: round in blend - -- todo: delay this hash + -- todo: round in blend - local rshift = bit32.rshift - local band = bit32.band - local round = math.round + local encode = { } - local encode = table.setmetatableindex(function(t,i) - for i=-2048,-1130 do - t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - for i=-1131,-108 do - local v = 0xFB00 - i - 108 - t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF)) - end - for i=-107,107 do - t[i] = char(i + 139) - end - for i=108,1131 do - local v = 0xF700 + i - 108 - t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF)) - end - for i=1132,2048 do - t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + -- this eventually can become a helper + + setmetatableindex(encode,function(t,i) + for i=-2048,-1130 do + t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + for i=-1131,-108 do + local v = 0xFB00 - i - 108 + t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=-107,107 do + t[i] = chars[i + 139] + end + for i=108,1131 do + local v = 0xF700 + i - 108 +-- t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF)) + t[i] = char(extract(v,8,8),extract(v,0,8)) + end + for i=1132,2048 do + t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + setmetatableindex(encode,function(t,k) + -- 16.16-bit signed fixed value + local r = round(k) + local v = rawget(t,r) + if v then + return v end - return t[i] + local v1 = floor(k) + local v2 = floor((k - v1) * 0x10000) + return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8)) end) + return t[i] + end) - local function setvsindex() - local vsindex = stack[top] - updateregions(vsindex) - top = top - 1 - end + readers.cffencoder = encode - local function blend() - local n = stack[top] - top = top - 1 - if not axis then - -- fatal error - elseif n == 1 then - top = top - nofregions - local v = stack[top] + local function p_setvsindex() + local vsindex = stack[top] + updateregions(vsindex) + top = top - 1 + end + + local function p_blend() + -- leaves n values on stack + local n = stack[top] + top = top - 1 + if not axis then + -- fatal error + elseif n == 1 then + top = top - nofregions + local v = stack[top] + for r=1,nofregions do + v = v + stack[top+r] * factors[r] + end + stack[top] = round(v) + else + top = top - nofregions * n + local d = top + local k = top - n + for i=1,n do + k = k + 1 + local v = stack[k] for r=1,nofregions do - v = v + stack[top+r] * factors[r] - end - stack[top] = round(v) - else - top = top - nofregions * n - local d = top - local k = top - n - for i=1,n do - k = k + 1 - local v = stack[k] - for r=1,nofregions do - v = v + stack[d+r] * factors[r] - end - stack[k] = round(v) - d = d + nofregions + v = v + stack[d+r] * factors[r] end + stack[k] = round(v) + d = d + nofregions end end + end - passon = function(operation) - if operation == 15 then - setvsindex() - elseif operation == 16 then - blend() - else - for i=1,top do - r = r + 1 - result[r] = encode[stack[i]] - end - r = r + 1 - result[r] = char(operation) -- maybe use a hash - top = 0 - end + local function p_getstem() + local n = 0 + if top % 2 ~= 0 then + n = 1 + end + if top > n then + stems = stems + idiv(top-n,2) end + end + local function p_getmask() + local n = 0 + if top % 2 ~= 0 then + n = 1 + end + if top > n then + stems = stems + idiv(top-n,2) + end + if stems == 0 then + return 0 + elseif stems <= 8 then + return 1 + else + return idiv(stems+7,8) + end end -- end of experiment @@ -1627,6 +1686,42 @@ do local justpass = false + -- local function decode(str) + -- local a, b, c, d, e = byte(str,1,5) + -- if a == 28 then + -- if c then + -- local n = 0x100 * b + c + -- if n >= 0x8000 then + -- return n - 0x10000 + -- else + -- return n + -- end + -- end + -- elseif a < 32 then + -- return false + -- elseif a <= 246 then + -- return a - 139 + -- elseif a <= 250 then + -- if b then + -- return a*256 - 63124 + b + -- end + -- elseif a <= 254 then + -- if b then + -- return -a*256 + 64148 - b + -- end + -- else + -- if e then + -- local n = 0x100 * b + c + -- if n >= 0x8000 then + -- return n - 0x10000 + (0x100 * d + e)/0xFFFF + -- else + -- return n + (0x100 * d + e)/0xFFFF + -- end + -- end + -- end + -- return false + -- end + process = function(tab) local i = 1 local n = #tab @@ -1651,9 +1746,9 @@ do stack[top] = -t*256 + 64148 - tab[i+1] i = i + 2 else + -- a 16.16 float local n = 0x100 * tab[i+1] + tab[i+2] - if n >= 0x8000 then - -- stack[top] = n - 0xFFFF - 1 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF + if n >= 0x8000 then stack[top] = n - 0x10000 + (0x100 * tab[i+3] + tab[i+4])/0xFFFF else stack[top] = n + (0x100 * tab[i+3] + tab[i+4])/0xFFFF @@ -1700,19 +1795,94 @@ do elseif t == 12 then i = i + 1 local t = tab[i] - local a = subactions[t] - if a then - a(t) + if justpass then + if t >= 34 or t <= 37 then -- flexes + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + r = r + 1 ; result[r] = chars[12] + r = r + 1 ; result[r] = chars[t] + top = 0 + else + local a = subactions[t] + if a then + a(t) + else + top = 0 + end + end else - if trace_charstrings then - showvalue("",t) + local a = subactions[t] + if a then + a(t) + else + if trace_charstrings then + showvalue("",t) + end + top = 0 end - top = 0 end i = i + 1 elseif justpass then - passon(t) - i = i + 1 + -- todo: local a = passactions + if t == 15 then + p_setvsindex() + i = i + 1 + elseif t == 16 then + local s = p_blend() or 0 + i = i + s + 1 + -- cff 1: (when cff2 strip them) + elseif t == 1 or t == 3 or t == 18 or operation == 23 then + p_getstem() -- at the start +if true then + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 + end + r = r + 1 ; result[r] = chars[t] +else + top = 0 +end + i = i + 1 + -- cff 1: (when cff2 strip them) + elseif t == 19 or t == 20 then + local s = p_getmask() or 0 -- after the stems +if true then + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 + end + r = r + 1 ; result[r] = chars[t] + for j=1,s do + i = i + 1 + r = r + 1 ; result[r] = chars[tab[i]] + end +else + i = i + s + top = 0 +end + i = i + 1 + -- cff 1: closepath + elseif t == 9 then + top = 0 + i = i + 1 + elseif t == 13 then + local s = hsbw() or 0 + i = i + s + 1 + else + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 + end + r = r + 1 ; result[r] = chars[t] + i = i + 1 + end else local a = actions[t] if a then @@ -1772,20 +1942,33 @@ do -- end local function setbias(globals,locals) - if version == 1 then +-- if version == 1 then -- charstring version, not cff +-- return +-- 0, +-- 0 +-- return +-- 1, +-- 1 +-- else + local g = #globals + local l = #locals return - false, - false - else - local g, l = #globals, #locals - return - ((g < 1240 and 107) or (g < 33900 and 1131) or 32768) + 1, - ((l < 1240 and 107) or (l < 33900 and 1131) or 32768) + 1 - end + ((g < 1240 and 107) or (g < 33900 and 1131) or 32768) + 1, + ((l < 1240 and 107) or (l < 33900 and 1131) or 32768) + 1 +-- end end local function processshape(tab,index) + if not tab then + glyphs[index] = { + boundingbox = { 0, 0, 0, 0 }, + width = 0, + name = charset and charset[index] or nil, + } + return + end + tab = bytetable(tab) x = 0 @@ -1801,7 +1984,6 @@ do ymin = 0 ymax = 0 checked = false - if trace_charstrings then report("glyph: %i",index) report("data : % t",tab) @@ -1921,19 +2103,20 @@ do globalbias, localbias = setbias(globals,locals) nominalwidth, defaultwidth = setwidths(dictionary.private) - startparsing(fontdata,data,streams) - - for index=1,#charstrings do - processshape(charstrings[index],index-1) - charstrings[index] = nil -- free memory (what if used more often?) + if charstrings then + startparsing(fontdata,data,streams) + for index=1,#charstrings do + processshape(charstrings[index],index-1) +-- charstrings[index] = nil -- free memory (what if used more often?) + end + stopparsing(fontdata,data) + else + report("no charstrings") end - - stopparsing(fontdata,data) - return glyphs end - parsecharstring = function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion) + parsecharstring = function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams) keepcurve = doshapes version = tversion @@ -1944,6 +2127,8 @@ do vsindex = dictionary.vsindex or 0 glyphs = glphs or { } + justpass = streams == true + globalbias, localbias = setbias(globals,locals) nominalwidth, defaultwidth = setwidths(dictionary.private) @@ -2118,7 +2303,7 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) local format = readbyte(f) if format == 1 then for i=0,nofglyphs do -- notdef included (needs checking) - local index = readbyte(i) + local index = readbyte(f) fdindex[i] = index if index > maxindex then maxindex = index @@ -2149,23 +2334,27 @@ local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) -- hm, always if maxindex >= 0 then local cidarray = cid.fdarray - setposition(f,header.offset+cidarray) - local dictionaries = readlengths(f) - for i=1,#dictionaries do - dictionaries[i] = readstring(f,dictionaries[i]) - end - parsedictionaries(data,dictionaries) - cid.dictionaries = dictionaries - readcidprivates(f,data) - for i=1,#dictionaries do - readlocals(f,data,dictionaries[i]) - end - startparsing(fontdata,data,streams) - for i=1,#charstrings do - parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) - charstrings[i] = nil + if cidarray then + setposition(f,header.offset+cidarray) + local dictionaries = readlengths(f) + for i=1,#dictionaries do + dictionaries[i] = readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + cid.dictionaries = dictionaries + readcidprivates(f,data) + for i=1,#dictionaries do + readlocals(f,data,dictionaries[i]) + end + startparsing(fontdata,data,streams) + for i=1,#charstrings do + parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams) +-- charstrings[i] = nil + end + stopparsing(fontdata,data) + else + report("no cid array") end - stopparsing(fontdata,data) end end @@ -2184,7 +2373,7 @@ local function cleanup(data,dictionaries) end function readers.cff(f,fontdata,specification) - local tableoffset = gotodatatable(f,fontdata,"cff",specification.details) + local tableoffset = gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs) if tableoffset then local header = readheader(f) if header.major ~= 1 then @@ -2207,14 +2396,17 @@ function readers.cff(f,fontdata,specification) -- local dic = dictionaries[1] local cid = dic.cid - fontdata.cffinfo = { - familynamename = dic.familyname, + -- + local cffinfo = { + familyname = dic.familyname, fullname = dic.fullname, boundingbox = dic.boundingbox, weight = dic.weight, italicangle = dic.italicangle, underlineposition = dic.underlineposition, underlinethickness = dic.underlinethickness, + defaultwidth = dic.defaultwidthx, + nominalwidth = dic.nominalwidthx, monospaced = dic.monospaced, } fontdata.cidinfo = cid and { @@ -2222,13 +2414,31 @@ function readers.cff(f,fontdata,specification) ordering = cid.ordering, supplement = cid.supplement, } + fontdata.cffinfo = cffinfo -- - if specification.glyphs then - local all = specification.shapes or false + local all = specification.shapes or specification.streams or false + if specification.glyphs or all then if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff") + readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams) else - readnoselect(f,fontdata,data,glyphs,all,"cff") + readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + end + end + local private = dic.private + if private then + local data = private.data + if type(data) == "table" then + cffinfo.defaultwidth = data.defaultwidth or cffinfo.defaultwidth + cffinfo.nominalwidth = data.nominalwidth or cffinfo.nominalwidth + cffinfo.bluevalues = data.bluevalues + cffinfo.otherblues = data.otherblues + cffinfo.familyblues = data.familyblues + cffinfo.familyotherblues = data.familyotherblues + cffinfo.bluescale = data.bluescale + cffinfo.blueshift = data.blueshift + cffinfo.bluefuzz = data.bluefuzz + cffinfo.stdhw = data.stdhw + cffinfo.stdvw = data.stdvw end end cleanup(data,dictionaries) @@ -2267,7 +2477,7 @@ function readers.cff2(f,fontdata,specification) data.factors = specification.factors -- local cid = data.dictionaries[1].cid - local all = specification.shapes or false + local all = specification.shapes or specification.streams or false if cid and cid.fdselect then readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) else @@ -2300,7 +2510,7 @@ function readers.cffcheck(filename) dictionaries = dictionaries, strings = strings, glyphs = glyphs, - nofglyphs = 4, + nofglyphs = 0, } -- parsedictionaries(data,dictionaries,"cff") diff --git a/tex/context/base/mkiv/font-cft.lua b/tex/context/base/mkiv/font-cft.lua index 83227ca4a..2e1610f17 100644 --- a/tex/context/base/mkiv/font-cft.lua +++ b/tex/context/base/mkiv/font-cft.lua @@ -248,6 +248,16 @@ do mathitalics = t_boolean, textitalics = t_boolean, finalized = t_boolean, + effect = { + effect = t_cardinal, + width = t_float, + factor = t_float, + hfactor = t_float, + vfactor = t_float, + wdelta = t_float, + hdelta = t_float, + ddelta = t_float, + } }, parameters = { mathsize = t_cardinal, diff --git a/tex/context/base/mkiv/font-chk.lua b/tex/context/base/mkiv/font-chk.lua index 3613432c1..ab145ce4d 100644 --- a/tex/context/base/mkiv/font-chk.lua +++ b/tex/context/base/mkiv/font-chk.lua @@ -66,14 +66,12 @@ local hpack_node = node.hpack local nuts = nodes.nuts local tonut = nuts.tonut -local tonode = nuts.tonode - -local getfont = nuts.getfont -local getchar = nuts.getchar +local isglyph = nuts.isglyph local setchar = nuts.setchar -local traverse_id = nuts.traverse_id +local nextglyph = nuts.traversers.glyph + local remove_node = nuts.remove local insert_node_after = nuts.insert_after @@ -142,7 +140,7 @@ local mapping = allocate { -- this is just an experiment to illustrate some prin table.setmetatableindex(mapping, function(t,k) - v = "placeholder unknown gray" + local v = "placeholder unknown gray" t[k] = v return v end @@ -196,7 +194,10 @@ local variants = allocate { { tag = "yellow", r = .6, g = .6, b = 0 }, } -local pdf_blob = "pdf: q %.6F 0 0 %.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q" +-- bah .. low level pdf ... should be a rule or plugged in + +----- pdf_blob = "pdf: q %.6F 0 0 %.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q" +local pdf_blob = "q %.6F 0 0 %.6F 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q" local cache = { } -- saves some tables but not that impressive @@ -235,8 +236,8 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul width = size*fake.width, height = size*fake.height, depth = size*fake.depth, - -- bah .. low level pdf ... should be a rule or plugged in - commands = { { "special", formatters[pdf_blob](scale,scale,r,g,b,r,g,b,fake.code) } } + -- commands = { { "special", formatters[pdf_blob](scale,scale,r,g,b,r,g,b,fake.code) } } + commands = { { "pdf", formatters[pdf_blob](scale,scale,r,g,b,r,g,b,fake.code) } } } cache[hash] = char end @@ -278,7 +279,7 @@ end local function placeholder(font,char) local tfmdata = fontdata[font] - local category = chardata[char].category + local category = chardata[char].category or "unknown" local fakechar = mapping[category] local slot = getprivateslot(font,fakechar) if not slot then @@ -292,15 +293,12 @@ checkers.placeholder = placeholder function checkers.missing(head) local lastfont, characters, found = nil, nil, nil - head = tonut(head) - for n in traverse_id(glyph_code,head) do -- faster than while loop so we delay removal - local font = getfont(n) - local char = getchar(n) + for n, char, font in nextglyph, head do -- faster than while loop so we delay removal if font ~= lastfont then characters = fontcharacters[font] lastfont = font end - if font > 0 and not characters[char] and is_character[chardata[char].category] then + if font > 0 and not characters[char] and is_character[chardata[char].category or "unknown"] then if action == "remove" then onetimemessage(font,char,"missing (will be deleted)") elseif action == "replace" then @@ -324,7 +322,8 @@ function checkers.missing(head) elseif action == "replace" then for i=1,#found do local node = found[i] - local kind, char = placeholder(getfont(node),getchar(node)) + local char, font = isglyph(node) + local kind, char = placeholder(font,char) if kind == "node" then insert_node_after(head,node,tonut(char)) head = remove_node(head,node,true) @@ -337,7 +336,7 @@ function checkers.missing(head) else -- maye write a report to the log end - return tonode(head), false + return head end local relevant = { @@ -362,6 +361,9 @@ local function getmissing(id) local messages = shared and shared.messages if messages then local filename = d.properties.filename + if not filename then + filename = tostring(d) + end local tf = t[filename] or { } for i=1,#relevant do local tm = messages[relevant[i]] @@ -390,7 +392,6 @@ checkers.getmissing = getmissing do local reported = true - local tracked = false callback.register("glyph_not_found",function(font,char) if font > 0 then @@ -408,7 +409,6 @@ do trackers.register("fonts.missing", function(v) if v then enableaction("processors","fonts.checkers.missing") - tracked = true else disableaction("processors","fonts.checkers.missing") end @@ -419,27 +419,25 @@ do end) logs.registerfinalactions(function() --- if tracked then - local collected, details = getmissing() - if next(collected) then + local collected, details = getmissing() + if next(collected) then + for filename, list in sortedhash(details) do + logs.startfilelogging(report,"missing characters",filename) + for u, v in sortedhash(list) do + report("%4i %U %c %s",v,u,u,chardata[u].description) + end + logs.stopfilelogging() + end + if logs.loggingerrors() then for filename, list in sortedhash(details) do - logs.startfilelogging(report,"missing characters",filename) + logs.starterrorlogging(report,"missing characters",filename) for u, v in sortedhash(list) do report("%4i %U %c %s",v,u,u,chardata[u].description) end - logs.stopfilelogging() - end - if logs.loggingerrors() then - for filename, list in sortedhash(details) do - logs.starterrorlogging(report,"missing characters",filename) - for u, v in sortedhash(list) do - report("%4i %U %c %s",v,u,u,chardata[u].description) - end - logs.stoperrorlogging() - end + logs.stoperrorlogging() end end --- end + end end) end @@ -507,3 +505,31 @@ local dummies_specification = { registerotffeature(dummies_specification) registerafmfeature(dummies_specification) + +-- + +local function addvisualspace(tfmdata) + local spacechar = tfmdata.characters[32] + if spacechar and not spacechar.commands then + local w = spacechar.width + local h = tfmdata.parameters.xheight + local c = { + width = w, + commands = { { "rule", h, w } } + } + local u = addprivate(tfmdata, "visualspace", c) + end +end + +local visualspace_specification = { + name = "visualspace", + description = "visual space", + default = true, + manipulators = { + base = addvisualspace, + node = addvisualspace, + } +} + +registerotffeature(visualspace_specification) +registerafmfeature(visualspace_specification) diff --git a/tex/context/base/mkiv/font-col.lua b/tex/context/base/mkiv/font-col.lua index 7bbaf31cb..d197c7c85 100644 --- a/tex/context/base/mkiv/font-col.lua +++ b/tex/context/base/mkiv/font-col.lua @@ -19,15 +19,11 @@ local fastcopy = table.fastcopy local formatters = string.formatters local nuts = nodes.nuts -local tonut = nuts.tonut - -local getfont = nuts.getfont -local getchar = nuts.getchar local setfont = nuts.setfont -local traverse_id = nuts.traverse_id -local traverse_char = nuts.traverse_char +----- traverse_char = nuts.traverse_char +local nextchar = nuts.traversers.char local settings_to_hash = utilities.parsers.settings_to_hash @@ -47,28 +43,38 @@ collections.definitions = definitions local vectors = collections.vectors or { } collections.vectors = vectors -local fonthashes = fonts.hashes -local fonthelpers = fonts.helpers - -local fontdata = fonthashes.identifiers -local fontquads = fonthashes.quads -local chardata = fonthashes.characters -local propdata = fonthashes.properties +local helpers = fonts.helpers +local charcommand = helpers.commands.char +local rightcommand = helpers.commands.right +local addprivate = helpers.addprivate +local hasprivate = helpers.hasprivate +local fontpatternhassize = helpers.fontpatternhassize -local addprivate = fonthelpers.addprivate -local hasprivate = fonthelpers.hasprivate +local hashes = fonts.hashes +local fontdata = hashes.identifiers +local fontquads = hashes.quads +local chardata = hashes.characters +local propdata = hashes.properties +local mathparameters = hashes.mathparameters local currentfont = font.current local addcharacters = font.addcharacters -local fontpatternhassize = fonts.helpers.fontpatternhassize - local implement = interfaces.implement local list = { } local current = 0 local enabled = false +local validvectors = table.setmetatableindex(function(t,k) + local v = false + if not mathparameters[k] then + v = vectors[k] + end + t[k] = v + return v +end) + local function checkenabled() -- a bit ugly but nicer than a fuzzy state while defining math if next(vectors) then @@ -113,6 +119,23 @@ function collections.define(name,font,ranges,details) end details = settings_to_hash(details) -- todo, combine per font start/stop as arrays + local offset = details.offset + if type(offset) == "string" then + offset = characters.getrange(offset,true) or false + else + offset = tonumber(offset) or false + end + local target = details.target + if type(target) == "string" then + target = characters.getrange(target,true) or false + else + target = tonumber(target) or false + end + local rscale = tonumber (details.rscale) or 1 + local force = toboolean(details.force,true) + local check = toboolean(details.check,true) + local factor = tonumber(details.factor) + local features = details.features for s in gmatch(ranges,"[^, ]+") do local start, stop, description, gaps = characters.getrange(s,true) if start and stop then @@ -127,24 +150,19 @@ function collections.define(name,font,ranges,details) end end end - local offset = details.offset - if type(offset) == "string" then - local start = characters.getrange(offset,true) - offset = start or false - else - offset = tonumber(offset) or false - end d[#d+1] = { font = font, start = start, stop = stop, gaps = gaps, offset = offset, - rscale = tonumber (details.rscale) or 1, - force = toboolean(details.force,true), - check = toboolean(details.check,true), - factor = tonumber(details.factor), - features = details.features, + target = target, + rscale = rscale, + force = force, + check = check, + method = details.method, + factor = factor, + features = features, } end end @@ -163,6 +181,32 @@ end -- check: when true, only set when present in font -- force: when false, then not set when already set +local uccodes = characters.uccodes +local lccodes = characters.lccodes + +local methods = { + lowercase = function(oldchars,newchars,vector,start,stop,cloneid) + for k, v in next, oldchars do + if k >= start and k <= stop then + local lccode = lccodes[k] + if k ~= lccode and newchars[lccode] then + vector[k] = { cloneid, lccode } + end + end + end + end, + uppercase = function(oldchars,newchars,vector,start,stop,cloneid) + for k, v in next, oldchars do + if k >= start and k <= stop then + local uccode = uccodes[k] + if k ~= uccode and newchars[uccode] then + vector[k] = { cloneid, uccode } + end + end + end + end, +} + function collections.clonevector(name) statistics.starttiming(fonts) if trace_collecting then @@ -179,7 +223,9 @@ function collections.clonevector(name) local check = definition.check local force = definition.force local offset = definition.offset or start - local remap = definition.remap + local remap = definition.remap -- not used + local target = definition.target + local method = definition.method local cloneid = list[i] local oldchars = fontdata[current].characters local newchars = fontdata[cloneid].characters @@ -188,28 +234,60 @@ function collections.clonevector(name) vector.factor = factor end if trace_collecting then - report_fonts("remapping font %a to %a for range %U - %U",current,cloneid,start,stop) + if target then + report_fonts("remapping font %a to %a for range %U - %U, offset %X, target %U",current,cloneid,start,stop,offset,target) + else + report_fonts("remapping font %a to %a for range %U - %U, offset %X",current,cloneid,start,stop,offset) + end end - if check then - for unicode = start, stop do - local unic = unicode + offset - start - if not newchars[unicode] then - -- not in font - elseif force or (not vector[unic] and not oldchars[unic]) then - if remap then - vector[unic] = { cloneid, remap[unicode] } - else + if method then + method = methods[method] + end + if method then + method(oldchars,newchars,vector,start,stop,cloneid) + elseif check then + if target then + for unicode = start, stop do + local unic = unicode + offset - start + if not newchars[target] then + -- not in font + elseif force or (not vector[unic] and not oldchars[unic]) then + vector[unic] = { cloneid, target } + end + target = target + 1 + end + elseif remap then + -- not used + else + for unicode = start, stop do + local unic = unicode + offset - start + if not newchars[unicode] then + -- not in font + elseif force or (not vector[unic] and not oldchars[unic]) then vector[unic] = cloneid end end end else - for unicode = start, stop do - local unic = unicode + offset - start - if force or (not vector[unic] and not oldchars[unic]) then - if remap then + if target then + for unicode = start, stop do + local unic = unicode + offset - start + if force or (not vector[unic] and not oldchars[unic]) then + vector[unic] = { cloneid, target } + end + target = target + 1 + end + elseif remap then + for unicode = start, stop do + local unic = unicode + offset - start + if force or (not vector[unic] and not oldchars[unic]) then vector[unic] = { cloneid, remap[unicode] } - else + end + end + else + for unicode = start, stop do + local unic = unicode + offset - start + if force or (not vector[unic] and not oldchars[unic]) then vector[unic] = cloneid end end @@ -219,8 +297,11 @@ function collections.clonevector(name) if trace_collecting then report_fonts("activating collection %a for font %a",name,current) end - checkenabled() statistics.stoptiming(fonts) + -- for WS: needs checking + if validvectors[current] then + checkenabled() + end end -- we already have this parser @@ -284,13 +365,16 @@ local function monoslot(font,char,parent,factor) local width = factor * fontquads[parent] local character = characters[char] if character then + -- runtime patching of the font (can only be new characters) + -- instead of messing with existing dimensions local data = { + -- no features so a simple copy width = width, height = character.height, depth = character.depth, commands = { - { "right", (width - character.width or 0)/2 }, - { "slot", 0, char } + rightcommand[(width - character.width or 0)/2], + charcommand[char], } } local u = addprivate(tfmdata, privatename, data) @@ -308,12 +392,9 @@ local function monoslot(font,char,parent,factor) end function collections.process(head) -- this way we keep feature processing - local done = false - for n in traverse_char(tonut(head)) do - local font = getfont(n) - local vector = vectors[font] + for n, char, font in nextchar, head do + local vector = validvectors[font] if vector then - local char = getchar(n) local vect = vector[char] if not vect then -- keep it @@ -326,7 +407,6 @@ function collections.process(head) -- this way we keep feature processing ) end setfont(n,newfont,newchar) - done = true else local fakemono = vector.factor if trace_collecting then @@ -339,11 +419,10 @@ function collections.process(head) -- this way we keep feature processing else setfont(n,vect) end - done = true end end end - return head, done + return head end function collections.found(font,char) -- this way we keep feature processing diff --git a/tex/context/base/mkiv/font-col.mkvi b/tex/context/base/mkiv/font-col.mkvi index a9c461e44..7ba92b526 100644 --- a/tex/context/base/mkiv/font-col.mkvi +++ b/tex/context/base/mkiv/font-col.mkvi @@ -23,6 +23,11 @@ % \definefontfallback [whatever] [Slanted] [0x0060-0x007F] [force=yes] % \definefontfallback [whatever] [Bold] [0x0080-0x00FF,0x00A0-0x00AF] [rscale=1.2] % \definefontfallback [whatever] [BoldSlanted] [0x00C0-0x00C7] [check=yes,force=yes] +% +% \definefontfeature [emboldened] [effect={width=0.1,delta=0.4,factor=0.3}] +% \definefontsynonym [SansEmboldened] [Sans] [features=emboldened] +% \definefontfallback[FakeSansCaps] [SansEmboldened] [0x0000-0xFFFF] [rscale=.8,method=uppercase] +% \definefontsynonym [SansCaps] [file:MyriadPro-Regular.otf] [fallbacks=FakeSansCaps] \writestatus{loading}{ConTeXt Font Macros / Collections} diff --git a/tex/context/base/mkiv/font-con.lua b/tex/context/base/mkiv/font-con.lua index add646da1..354fd4ac3 100644 --- a/tex/context/base/mkiv/font-con.lua +++ b/tex/context/base/mkiv/font-con.lua @@ -46,10 +46,11 @@ constructors.namemode = "fullpath" -- will be a function constructors.version = 1.01 constructors.cache = containers.define("fonts", "constructors", constructors.version, false) -constructors.privateoffset = 0xF0000 -- 0x10FFFF | context also uses privates: 0xE000-0xEFFF - +constructors.privateoffset = fonts.privateoffsets.textbase or 0xF0000 constructors.cacheintex = true -- so we see the original table in fonts.font +constructors.addtounicode = true + -- This might become an interface: local designsizes = allocate() @@ -98,6 +99,24 @@ function constructors.getprivate(tfmdata) return private end +function constructors.setmathparameter(tfmdata,name,value) + local m = tfmdata.mathparameters + local c = tfmdata.MathConstants + if m then + m[name] = value + end + if c and c ~= m then + c[name] = value + end +end + +function constructors.getmathparameter(tfmdata,name) + local p = tfmdata.mathparameters or tfmdata.MathConstants + if p then + return p[name] + end +end + --[[ldx--

Beware, the boundingbox is passed as reference so we may not overwrite it in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to @@ -407,7 +426,10 @@ function constructors.scale(tfmdata,specification) targetparameters.forcedsize = forcedsize -- context specific targetparameters.extrafactor = extrafactor -- context specific -- + local addtounicode = constructors.addtounicode + -- local tounicode = fonts.mappings.tounicode + local unknowncode = tounicode(0xFFFD) -- local defaultwidth = resources.defaultwidth or 0 local defaultheight = resources.defaultheight or 0 @@ -455,7 +477,8 @@ function constructors.scale(tfmdata,specification) local psname = properties.psname or tfmdata.psname local name = properties.name or tfmdata.name -- - -- the psname used in pdf file as well as for selecting subfont in ttc + -- The psname used in pdf file as well as for selecting subfont in ttc although + -- we don't need that subfont look up here (mapfile stuff). -- local psname, psfixed = fixedpsname(psname,fontname or fullname or file.nameonly(filename)) -- @@ -477,20 +500,28 @@ function constructors.scale(tfmdata,specification) target.shrink = expansion.shrink target.step = expansion.step end + -- slanting + local slantfactor = parameters.slantfactor or 0 + if slantfactor ~= 0 then + target.slant = slantfactor * 1000 + else + target.slant = 0 + end -- widening local extendfactor = parameters.extendfactor or 0 if extendfactor ~= 0 and extendfactor ~= 1 then hdelta = hdelta * extendfactor - target.extend = extendfactor * 1000 -- extent ? + target.extend = extendfactor * 1000 else target.extend = 1000 -- extent ? end - -- slanting - local slantfactor = parameters.slantfactor or 0 - if slantfactor ~= 0 then - target.slant = slantfactor * 1000 + -- squeezing + local squeezefactor = parameters.squeezefactor or 0 + if squeezefactor ~= 0 and squeezefactor ~= 1 then + vdelta = vdelta * squeezefactor + target.squeeze = squeezefactor * 1000 else - target.slant = 0 + target.squeeze = 1000 -- extent ? end -- effects local mode = parameters.mode or 0 @@ -499,7 +530,7 @@ function constructors.scale(tfmdata,specification) end local width = parameters.width or 0 if width ~= 0 then - target.width = width + target.width = width * delta * 1000 / 655360 end -- targetparameters.factor = delta @@ -565,6 +596,7 @@ function constructors.scale(tfmdata,specification) targetparameters.descender = delta * descender end -- +-- inspect(targetparameters) constructors.enhanceparameters(targetparameters) -- official copies for us, now virtual -- local protrusionfactor = (targetquad ~= 0 and 1000/targetquad) or 0 @@ -708,11 +740,19 @@ function constructors.scale(tfmdata,specification) end end local isunicode = description.unicode - if isunicode then - chr.unicode = isunicode - chr.tounicode = tounicode(isunicode) - -- in luatex > 0.85 we can do this: - -- chr.tounicode = isunicode + if addtounicode then + if isunicode then + chr.unicode = isunicode + chr.tounicode = tounicode(isunicode) + -- in luatex > 0.85 we can do this: + -- chr.tounicode = isunicode + else + chr.tounicode = unknowncode + end + else + if isunicode then + chr.unicode = isunicode + end end if hasquality then -- we could move these calculations elsewhere (saves calculations) @@ -742,12 +782,15 @@ function constructors.scale(tfmdata,specification) local t = { } for i=1,#vv do local vvi = vv[i] - t[i] = { - ["start"] = (vvi["start"] or 0)*vdelta, - ["end"] = (vvi["end"] or 0)*vdelta, - ["advance"] = (vvi["advance"] or 0)*vdelta, - ["extender"] = vvi["extender"], - ["glyph"] = vvi["glyph"], + local s = vvi["start"] or 0 + local e = vvi["end"] or 0 + local a = vvi["advance"] or 0 + t[i] = { -- zero check nicer for 5.3 + ["start"] = s == 0 and 0 or s * vdelta, + ["end"] = e == 0 and 0 or e * vdelta, + ["advance"] = a == 0 and 0 or a * vdelta, + ["extender"] = vvi["extender"], + ["glyph"] = vvi["glyph"], } end chr.vert_variants = t @@ -757,12 +800,15 @@ function constructors.scale(tfmdata,specification) local t = { } for i=1,#hv do local hvi = hv[i] - t[i] = { - ["start"] = (hvi["start"] or 0)*hdelta, - ["end"] = (hvi["end"] or 0)*hdelta, - ["advance"] = (hvi["advance"] or 0)*hdelta, - ["extender"] = hvi["extender"], - ["glyph"] = hvi["glyph"], + local s = hvi["start"] or 0 + local e = hvi["end"] or 0 + local a = hvi["advance"] or 0 + t[i] = { -- zero check nicer for 5.3 + ["start"] = s == 0 and 0 or s * hdelta, + ["end"] = e == 0 and 0 or e * hdelta, + ["advance"] = a == 0 and 0 or a * hdelta, + ["extender"] = hvi["extender"], + ["glyph"] = hvi["glyph"], } end chr.horiz_variants = t @@ -781,7 +827,10 @@ function constructors.scale(tfmdata,specification) if stackmath then local mk = character.mathkerns if mk then - local tr, tl, br, bl = mk.topright, mk.topleft, mk.bottomright, mk.bottomleft + local tr = mk.topright + local tl = mk.topleft + local br = mk.bottomright + local bl = mk.bottomleft chr.mathkern = { -- singular -> should be patched in luatex ! top_right = tr and mathkerns(tr,vdelta) or nil, top_left = tl and mathkerns(tl,vdelta) or nil, @@ -876,7 +925,7 @@ function constructors.scale(tfmdata,specification) else chr.commands = vc end - chr.index = nil + -- chr.index = nil end end targetcharacters[unicode] = chr @@ -886,15 +935,14 @@ function constructors.scale(tfmdata,specification) -- constructors.aftercopyingcharacters(target,tfmdata) -- - constructors.trytosharefont(target,tfmdata) + constructors.trytosharefont(target,tfmdata) -- -- catch inconsistencies -- local vfonts = target.fonts --- if isvirtual then -if isvirtual or target.type == "virtual" or properties.virtualized then + if isvirtual or target.type == "virtual" or properties.virtualized then properties.virtualized = true -target.type = "virtual" + target.type = "virtual" if not vfonts or #vfonts == 0 then target.fonts = { { id = 0 } } end @@ -947,12 +995,16 @@ function constructors.finalize(tfmdata) parameters.width = 0 end -- + if not parameters.slantfactor then + parameters.slantfactor = tfmdata.slant or 0 + end + -- if not parameters.extendfactor then parameters.extendfactor = tfmdata.extend or 0 end -- - if not parameters.slantfactor then - parameters.slantfactor = tfmdata.slant or 0 + if not parameters.squeezefactor then + parameters.squeezefactor = tfmdata.squeeze or 0 end -- local designsize = parameters.designsize @@ -988,24 +1040,22 @@ function constructors.finalize(tfmdata) properties.virtualized = tfmdata.type == "virtual" end -- - if not tfmdata.properties then - tfmdata.properties = { - fontname = tfmdata.fontname, - filename = tfmdata.filename, - fullname = tfmdata.fullname, - name = tfmdata.name, - psname = tfmdata.psname, - -- - encodingbytes = tfmdata.encodingbytes or 1, - embedding = tfmdata.embedding or "subset", - tounicode = tfmdata.tounicode or 1, - cidinfo = tfmdata.cidinfo or nil, - format = tfmdata.format or "type1", - direction = tfmdata.direction or 0, - writingmode = tfmdata.writingmode or "horizontal", - identity = tfmdata.identity or "horizontal", - } - end + properties.fontname = tfmdata.fontname + properties.filename = tfmdata.filename + properties.fullname = tfmdata.fullname + properties.name = tfmdata.name + properties.psname = tfmdata.psname + -- + properties.encodingbytes = tfmdata.encodingbytes or 1 + properties.embedding = tfmdata.embedding or "subset" + properties.tounicode = tfmdata.tounicode or 1 + properties.cidinfo = tfmdata.cidinfo or nil + properties.format = tfmdata.format or "type1" + properties.direction = tfmdata.direction or 0 + properties.writingmode = tfmdata.writingmode or "horizontal" + properties.identity = tfmdata.identity or "horizontal" + properties.usedbitmap = tfmdata.usedbitmap + -- if not tfmdata.resources then tfmdata.resources = { } end @@ -1043,8 +1093,9 @@ function constructors.finalize(tfmdata) tfmdata.stretch = nil tfmdata.shrink = nil tfmdata.step = nil - tfmdata.extend = nil tfmdata.slant = nil + tfmdata.extend = nil + tfmdata.squeeze = nil tfmdata.mode = nil tfmdata.width = nil tfmdata.units = nil @@ -1097,7 +1148,18 @@ hashmethods.normal = function(list) -- no need to add to hash (maybe we need a skip list) else n = n + 1 - s[n] = k .. '=' .. tostring(v) + if type(v) == "table" then + -- table.sequenced + local t = { } + local m = 0 + for k, v in next, v do + m = m + 1 + t[m] = k .. '=' .. tostring(v) + end + s[n] = k .. '={' .. concat(t,",") .. "}" + else + s[n] = k .. '=' .. tostring(v) + end end end if n > 0 then @@ -1115,7 +1177,9 @@ loose our testcases for .

--ldx]]-- function constructors.hashinstance(specification,force) - local hash, size, fallbacks = specification.hash, specification.size, specification.fallbacks + local hash = specification.hash + local size = specification.size + local fallbacks = specification.fallbacks if force or not hash then hash = constructors.hashfeatures(specification) specification.hash = hash @@ -1553,7 +1617,8 @@ end -- while typesetting function constructors.collectprocessors(what,tfmdata,features,trace,report) - local processes, nofprocesses = { }, 0 + local processes = { } + local nofprocesses = 0 if features and next(features) then local properties = tfmdata.properties local whathandler = handlers[what] diff --git a/tex/context/base/mkiv/font-ctx.lua b/tex/context/base/mkiv/font-ctx.lua index 87885f64f..6847a2b8d 100644 --- a/tex/context/base/mkiv/font-ctx.lua +++ b/tex/context/base/mkiv/font-ctx.lua @@ -12,21 +12,23 @@ if not modules then modules = { } end modules ['font-ctx'] = { -- Todo: make a proper 'next id' mechanism (register etc) or wait till 'true' -- in virtual fonts indices is implemented. -local context, commands = context, commands +local tostring, next, type, rawget, tonumber = tostring, next, type, rawget, tonumber local format, gmatch, match, find, lower, upper, gsub, byte, topattern = string.format, string.gmatch, string.match, string.find, string.lower, string.upper, string.gsub, string.byte, string.topattern local concat, serialize, sort, fastcopy, mergedtable = table.concat, table.serialize, table.sort, table.fastcopy, table.merged local sortedhash, sortedkeys, sequenced = table.sortedhash, table.sortedkeys, table.sequenced -local settings_to_hash, hash_to_string, settings_to_array = utilities.parsers.settings_to_hash, utilities.parsers.hash_to_string, utilities.parsers.settings_to_array +local parsers = utilities.parsers +local settings_to_hash, hash_to_string, settings_to_array = parsers.settings_to_hash, parsers.hash_to_string, parsers.settings_to_array local formatcolumns = utilities.formatters.formatcolumns local mergehashes = utilities.parsers.mergehashes local formatters = string.formatters local basename = file.basename -local tostring, next, type, rawget, tonumber = tostring, next, type, rawget, tonumber local utfchar, utfbyte = utf.char, utf.byte local round = math.round +local context, commands = context, commands + local P, S, C, Cc, Cf, Cg, Ct, lpegmatch = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Ct, lpeg.match local trace_features = false trackers.register("fonts.features", function(v) trace_features = v end) @@ -66,6 +68,8 @@ local hashes = fonts.hashes local currentfont = font.current local definefont = font.define +local getprivateslot = helpers.getprivateslot + local cleanname = names.cleanname local encodings = fonts.encodings @@ -75,11 +79,12 @@ local aglunicodes = nil -- delayed loading local nuts = nodes.nuts local tonut = nuts.tonut +local nextchar = nuts.traversers.char + local getattr = nuts.getattr local setattr = nuts.setattr local getprop = nuts.getprop local setprop = nuts.setprop -local getfont = nuts.getfont local setsubtype = nuts.setsubtype local texgetattribute = tex.getattribute @@ -158,17 +163,8 @@ helpers.name = getfontname local addformatter = utilities.strings.formatters.add -if LUAVERSION < 5.2 then - - addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], "local fontname = fonts.helpers.name") - addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],"local sequenced = table.sequenced") - -else - - addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = helpers.name }) - addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced }) - -end +addformatter(formatters,"font:name", [["'"..fontname(%s).."'"]], { fontname = helpers.name }) +addformatter(formatters,"font:features",[["'"..sequenced(%s," ",true).."'"]],{ sequenced = table.sequenced }) -- ... like font-sfm or so @@ -472,36 +468,40 @@ registerotffeature { -- }, -- } -local beforecopyingcharacters = sequencers.new { - name = "beforecopyingcharacters", - arguments = "target,original", -} +do + + local beforecopyingcharacters = sequencers.new { + name = "beforecopyingcharacters", + arguments = "target,original", + } -appendgroup(beforecopyingcharacters,"before") -- user -appendgroup(beforecopyingcharacters,"system") -- private -appendgroup(beforecopyingcharacters,"after" ) -- user + appendgroup(beforecopyingcharacters,"before") -- user + appendgroup(beforecopyingcharacters,"system") -- private + appendgroup(beforecopyingcharacters,"after" ) -- user -function constructors.beforecopyingcharacters(original,target) - local runner = beforecopyingcharacters.runner - if runner then - runner(original,target) + function constructors.beforecopyingcharacters(original,target) + local runner = beforecopyingcharacters.runner + if runner then + runner(original,target) + end end -end -local aftercopyingcharacters = sequencers.new { - name = "aftercopyingcharacters", - arguments = "target,original", -} + local aftercopyingcharacters = sequencers.new { + name = "aftercopyingcharacters", + arguments = "target,original", + } -appendgroup(aftercopyingcharacters,"before") -- user -appendgroup(aftercopyingcharacters,"system") -- private -appendgroup(aftercopyingcharacters,"after" ) -- user + appendgroup(aftercopyingcharacters,"before") -- user + appendgroup(aftercopyingcharacters,"system") -- private + appendgroup(aftercopyingcharacters,"after" ) -- user -function constructors.aftercopyingcharacters(original,target) - local runner = aftercopyingcharacters.runner - if runner then - runner(original,target) + function constructors.aftercopyingcharacters(original,target) + local runner = aftercopyingcharacters.runner + if runner then + runner(original,target) + end end + end --[[ldx-- @@ -566,6 +566,12 @@ local function definecontext(name,t) -- can be shared return number, t end +-- {a,b,c} as table (so we don' need to parse again when it gets applied) +-- we will update this ... when we have foo={a,b,c} then we can keep the table + +-- \definefontfeature[demo][a={b,c}] +-- \definefontfeature[demo][a={b=12,c={34,35}}] + local function presetcontext(name,parent,features) -- will go to con and shared if features == "" and find(parent,"=",1,true) then features = parent @@ -575,6 +581,16 @@ local function presetcontext(name,parent,features) -- will go to con and shared features = { } elseif type(features) == "string" then features = normalize_features(settings_to_hash(features)) + -- if type(value) == "string" and find(value,"[=:]") then + -- local t = settings_to_hash_colon_too(value) -- clashes with foo=file:bar + for key, value in next, features do + if type(value) == "string" and find(value,"[=]") then + local t = settings_to_hash(value) + if next(t) then + features[key] = sequenced(normalize_features(t,true),",") + end + end + end else features = normalize_features(features) end @@ -584,8 +600,8 @@ local function presetcontext(name,parent,features) -- will go to con and shared local s = setups[p] if s then for k, v in next, s do --- no, as then we cannot overload: e.g. math,mathextra --- reverted, so we only take from parent when not set + -- no, as then we cannot overload: e.g. math,mathextra + -- reverted, so we only take from parent when not set if features[k] == nil then features[k] = v end @@ -777,7 +793,8 @@ end local function registercontext(fontnumber,extraname,option) local extra = setups[extraname] if extra then - local mergedfeatures, mergedname = { }, nil + local mergedfeatures = { } + local mergedname = nil if option < 0 then mergedname = fontnumber .. "-" .. extraname else @@ -997,25 +1014,33 @@ definers.registersplit(":",colonized,"direct") -- define (two steps) ------ space = P(" ") ------ spaces = space^0 -local leftparent = (P"(") -local rightparent = (P")") -local value = C((leftparent * (1-rightparent)^0 * rightparent + (1-space))^1) -local dimension = C((space/"" + P(1))^1) -local rest = C(P(1)^0) -local scale_none = Cc(0) -local scale_at = (P("at") +P("@")) * Cc(1) * spaces * dimension -- dimension -local scale_sa = P("sa") * Cc(2) * spaces * dimension -- number -local scale_mo = P("mo") * Cc(3) * spaces * dimension -- number -local scale_scaled = P("scaled") * Cc(4) * spaces * dimension -- number -local scale_ht = P("ht") * Cc(5) * spaces * dimension -- dimension -local scale_cp = P("cp") * Cc(6) * spaces * dimension -- dimension - -local specialscale = { [5] = "ht", [6] = "cp" } - -local sizepattern = spaces * (scale_at + scale_sa + scale_mo + scale_ht + scale_cp + scale_scaled + scale_none) -local splitpattern = spaces * value * spaces * rest +local sizepattern, splitpattern, specialscale do + + ----- space = P(" ") + ----- spaces = space^0 + local leftparent = (P"(") + local rightparent = (P")") + local leftbrace = (P"{") + local rightbrace = (P"}") + local withinparents = leftparent * (1-rightparent)^0 * rightparent + local withinbraces = leftbrace * (1-rightbrace )^0 * rightbrace + local value = C((withinparents + withinbraces + (1-space))^1) + local dimension = C((space/"" + P(1))^1) + local rest = C(P(1)^0) + local scale_none = Cc(0) + local scale_at = (P("at") +P("@")) * Cc(1) * spaces * dimension -- dimension + local scale_sa = P("sa") * Cc(2) * spaces * dimension -- number + local scale_mo = P("mo") * Cc(3) * spaces * dimension -- number + local scale_scaled = P("scaled") * Cc(4) * spaces * dimension -- number + local scale_ht = P("ht") * Cc(5) * spaces * dimension -- dimension + local scale_cp = P("cp") * Cc(6) * spaces * dimension -- dimension + + specialscale = { [5] = "ht", [6] = "cp" } + + sizepattern = spaces * (scale_at + scale_sa + scale_mo + scale_ht + scale_cp + scale_scaled + scale_none) + splitpattern = spaces * value * spaces * rest + +end function helpers.splitfontpattern(str) local name, size = lpegmatch(splitpattern,str) @@ -1299,7 +1324,6 @@ do -- else too many locals local busy = false scanners.definefont_two = function() - local global = scanboolean() -- \ifx\fontclass\empty\s!false\else\s!true\fi local cs = scanstring () -- {#csname}% local str = scanstring () -- \somefontfile @@ -1411,6 +1435,7 @@ do -- else too many locals specification.fallbacks = fontfallbacks end end + -- local tfmdata = definers.read(specification,size) -- id not yet known (size in spec?) -- local lastfontid = 0 @@ -1426,15 +1451,15 @@ do -- else too many locals -- characters[0x2007] = { width = characters[0x0030] and characters[0x0030].width or parameters.space } -- figure -- characters[0x2008] = { width = characters[0x002E] and characters[0x002E].width or parameters.space } -- period -- - local fallbacks = specification.fallbacks + local fallbacks = specification.fallbacks or "" local mathsize = (mathsize == 1 or mathsize == 2 or mathsize == 3) and mathsize or nil -- can be unset so we test 1 2 3 - if fallbacks and fallbacks ~= "" and mathsize and not busy then + if fallbacks ~= "" and mathsize and not busy then busy = true -- We need this ugly hack in order to resolve fontnames (at the \TEX end). Originally -- math was done in Lua after loading (plugged into aftercopying). -- -- After tl 2017 I'll also do text fallbacks this way (although backups there are done - -- in a completely different way. + -- in a completely different way.) if trace_defining then report_defining("defining %a, id %a, target %a, features %a / %a, fallbacks %a / %a, step %a", name,id,nice_cs(cs),classfeatures,fontfeatures,classfallbacks,fontfallbacks,1) @@ -1825,7 +1850,7 @@ function mappings.loadfile(name) if trace_mapfiles then report_mapfiles("loading map file %a",name) end - pdf.mapfile(name) + lpdf.setmapfile(name) loaded[name] = true end end @@ -1843,17 +1868,15 @@ function mappings.loadline(how,line) if trace_mapfiles then report_mapfiles("processing map line %a",line) end - pdf.mapline(how) + lpdf.setmapline(how) loaded[how] = true end end function mappings.reset() - pdf.mapfile("") + lpdf.setmapfile("") -- tricky ... backend related end -mappings.reset() -- resets the default file - implement { name = "loadmapfile", actions = mappings.loadfile, @@ -1876,19 +1899,36 @@ implement { -- => commands -local function nametoslot(name) +local pattern = P("P") + * (lpeg.patterns.hexdigit^4 / function(s) return tonumber(s,16) end) + * P(-1) + +local function nametoslot(name) -- also supports PXXXXX (4+ positions) local t = type(name) if t == "string" then - local slot = unicodes[true][name] + local unic = unicodes[true] + local slot = unic[name] + if slot then + return slot + end + -- + local slot = unic[gsub(name,"_"," ")] or unic[gsub(name,"_","-")] or + unic[gsub(name,"-"," ")] or unic[gsub(name,"-","_")] or + unic[gsub(name," ","_")] or unic[gsub(name," ","-")] if slot then return slot end + -- if not aglunicodes then aglunicodes = encodings.agl.unicodes end local char = characters[true] local slot = aglunicodes[name] - if char[slot] then + if slot and char[slot] then + return slot + end + local slot = lpegmatch(pattern,name) + if slot and char[slot] then return slot end -- not in font @@ -1901,14 +1941,13 @@ local function nametoslot(name) end end - local found = { } local function descriptiontoslot(name) local t = type(name) if t == "string" then -- slow - local list = sortedkeys(chardata) + local list = sortedkeys(chardata) -- can be a cache with weak tables local slot = found[name] local char = characters[true] if slot then @@ -1971,13 +2010,17 @@ local function descriptiontoslot(name) end end -local function indextoslot(index) - local r = resources[true] +local function indextoslot(font,index) + if not index then + index = font + font = true + end + local r = resources[font] if r then local indices = r.indices if not indices then indices = { } - local c = characters[true] + local c = characters[font] for unicode, data in next, c do local di = data.index if di then @@ -2397,9 +2440,12 @@ do return f and (f.gpos[n] or f.gsub[n]) end + local ctx_doifelse = commands.doifelse + local ctx_doif = commands.doif + implement { name = "doifelsecurrentfonthasfeature", - actions = { constructors.currentfonthasfeature, commands.doifelse }, + actions = { constructors.currentfonthasfeature, ctx_doifelse }, arguments = "string" } @@ -2443,9 +2489,22 @@ do implement { name = "definefontfeature", arguments = "3 strings", - actions = presetcontext + actions = presetcontext, } + implement { + name = "doifelsefontfeature", + arguments = "string", + actions = function(name) ctx_doifelse(contextnumber(name) > 1) end, + } + + implement { + name = "doifunknownfontfeature", + arguments = "string", + actions = function(name) ctx_doif(contextnumber(name) == 0) end, + } + + implement { name = "adaptfontfeature", arguments = "2 strings", @@ -2602,8 +2661,6 @@ do local unsetvalue = attributes.unsetvalue - local traverse_char = nuts.traverse_char - local a_color = attributes.private('color') local a_colormodel = attributes.private('colormodel') local a_state = attributes.private('state') @@ -2627,11 +2684,14 @@ do [states.pstf] = "font:5", } + -- todo: traversers + -- todo: check attr_list so that we can use the same .. helper: setcolorattr + local function markstates(head) if head then head = tonut(head) local model = getattr(head,a_colormodel) or 1 - for glyph in traverse_char(head) do + for glyph in nextchar, head do local a = getprop(glyph,a_state) if a then local name = colornames[a] @@ -2682,8 +2742,8 @@ do function methods.nocolor(head,font,attr) - for n in traverse_char(head) do - if not font or getfont(n) == font then + for n, c, f in nextchar, head do + if not font or f == font then setattr(n,a_color,unsetvalue) end end @@ -2708,9 +2768,13 @@ implement { arguments = "string", } -local list = storage.shared.bodyfontsizes or { } +local sharedstorage = storage.shared -storage.shared.bodyfontsizes = list +local list = sharedstorage.bodyfontsizes or { } +local unknown = sharedstorage.unknownbodyfontsizes or { } + +sharedstorage.bodyfontsizes = list +sharedstorage.unknownbodyfontsizes = unknown implement { name = "registerbodyfontsize", @@ -2720,6 +2784,17 @@ implement { end } +interfaces.implement { + name = "registerunknownbodysize", + arguments = "string", + actions = function(size) + if not unknown[size] then + interfaces.showmessage("fonts",14,size) + end + unknown[size] = true + end, +} + implement { name = "getbodyfontsizes", arguments = "string", @@ -2873,6 +2948,12 @@ end -- for the font manual +statistics.register("body font sizes", function() + if next(unknown) then + return formatters["defined: % t, undefined: % t"](sortedkeys(list),sortedkeys(unknown)) + end +end) + statistics.register("used fonts",function() if trace_usage then local filename = file.nameonly(environment.jobname) .. "-fonts-usage.lua" @@ -3018,79 +3099,285 @@ end -- for the moment here (and not in font-con.lua): -local identical = table.identical -local copy = table.copy -local fontdata = fonts.hashes.identifiers -local addcharacters = font.addcharacters - --- This helper is mostly meant to add last-resort (virtual) characters --- or runtime generated fonts (so we forget about features and such). It --- will probably take a while before it get used. - -local trace_adding = false -local report_adding = logs.reporter("fonts","add characters") - -trackers.register("fonts.addcharacters",function(v) trace_adding = v end) - -if addcharacters then - - function fonts.constructors.addcharacters(id,list) - local newchar = list.characters - if newchar then - local data = fontdata[id] - local newfont = list.fonts - local oldchar = data.characters - local oldfont = data.fonts - addcharacters(id, { - characters = newchar, - fonts = newfont, - nomath = not data.properties.hasmath, - }) - -- this is just for tracing, as the assignment only uses the fonts list - -- and doesn't store it otherwise - if newfont then - if oldfont then - local oldn = #oldfont - local newn = #newfont - for n=1,newn do - local ok = false - local nf = newfont[n] - for o=1,oldn do - if identical(nf,oldfont[o]) then - ok = true - break +do + + local identical = table.identical + local copy = table.copy + local fontdata = fonts.hashes.identifiers + local addcharacters = font.addcharacters + + -- This helper is mostly meant to add last-resort (virtual) characters + -- or runtime generated fonts (so we forget about features and such). It + -- will probably take a while before it get used. + + local trace_adding = false + local report_adding = logs.reporter("fonts","add characters") + + trackers.register("fonts.addcharacters",function(v) trace_adding = v end) + + if addcharacters then + + function fonts.constructors.addcharacters(id,list) + local newchar = list.characters + if newchar then + local data = fontdata[id] + local newfont = list.fonts + local oldchar = data.characters + local oldfont = data.fonts + addcharacters(id, { + characters = newchar, + fonts = newfont, + nomath = not data.properties.hasmath, + }) + -- this is just for tracing, as the assignment only uses the fonts list + -- and doesn't store it otherwise + if newfont then + if oldfont then + local oldn = #oldfont + local newn = #newfont + for n=1,newn do + local ok = false + local nf = newfont[n] + for o=1,oldn do + if identical(nf,oldfont[o]) then + ok = true + break + end + end + if not ok then + oldn = oldn + 1 + oldfont[oldn] = newfont[i] end end - if not ok then - oldn = oldn + 1 - oldfont[oldn] = newfont[i] - end + else + data.fonts = newfont end - else - data.fonts = newfont end - end - -- this is because we need to know what goes on and also might - -- want to access character data - for u, c in next, newchar do - if trace_adding then - report_adding("adding character %U to font %!font:name!",u,id) + -- this is because we need to know what goes on and also might + -- want to access character data + for u, c in next, newchar do + if trace_adding then + report_adding("adding character %U to font %!font:name!",u,id) + end + oldchar[u] = c end - oldchar[u] = c end end + + else + function fonts.constructors.addcharacters(id,list) + report_adding("adding characters to %!font:name! is not yet supported",id) + end end -else - function fonts.constructors.addcharacters(id,list) - report_adding("adding characters to %!font:name! is not yet supported",id) + implement { + name = "addfontpath", + arguments = "string", + actions = function(list) + names.addruntimepath(settings_to_array(list)) + end + } + +end + +-- moved here + +do + + local family_font = node.family_font + local new_glyph = nodes.pool.glyph + local fontproperties = fonts.hashes.properties + + local function getprivateslot(id,name) + if not name then + name = id + id = currentfont() + end + local properties = fontproperties[id] + local privates = properties and properties.privates + return privates and privates[name] + end + + local function getprivatenode(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + local font = properties.id + local slot = getprivateslot(font,name) + if slot then + -- todo: set current attribibutes + local char = tfmdata.characters[slot] + local tonode = char.tonode + if tonode then + return tonode(font,char) + else + return new_glyph(font,slot) + end + end + end + + local function getprivatecharornode(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + local font = properties.id + local slot = getprivateslot(font,name) + if slot then + -- todo: set current attributes + local char = tfmdata.characters[slot] + local tonode = char.tonode + if tonode then + return "node", tonode(tfmdata,char) + else + return "char", slot + end + end end + + helpers.getprivateslot = getprivateslot + helpers.getprivatenode = getprivatenode + helpers.getprivatecharornode = getprivatecharornode + + implement { + name = "getprivatechar", + arguments = "string", + actions = function(name) + local p = getprivateslot(name) + if p then + context(utfchar(p)) + end + end + } + + implement { + name = "getprivatemathchar", + arguments = "string", + actions = function(name) + local p = getprivateslot(family_font(0),name) + if p then + context(utfchar(p)) + end + end + } + + implement { + name = "getprivateslot", + arguments = "string", + actions = function(name) + local p = getprivateslot(name) + if p then + context(p) + end + end + } + end -implement { - name = "addfontpath", - arguments = "string", - actions = function(list) - names.addruntimepath(settings_to_array(list)) +-- handy, for now here: + +function fonts.helpers.collectanchors(tfmdata) + + local resources = tfmdata.resources -- todo: use shared + + if not resources or resources.anchors then + return resources.anchors end -} + + local anchors = { } + + local function set(unicode,target,class,anchor) + local a = anchors[unicode] + if not a then + anchors[unicode] = { [target] = { anchor } } + return + end + local t = a[target] + if not t then + a[target] = { anchor } + return + end + local x = anchor[1] + local y = anchor[2] + for k, v in next, t do + if v[1] == x and v[2] == y then + return + end + end + t[#t+1] = anchor + end + + local function getanchors(steps,target) + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + for unicode, data in next, coverage do + local class = data[1] + local anchor = data[2] + if anchor[1] ~= 0 or anchor[2] ~= 0 then + set(unicode,target,class,anchor) + end + end + end + end + + local function getcursives(steps) + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + for unicode, data in next, coverage do + local class = data[1] + local en = data[2] + local ex = data[3] + if en then + set(unicode,"entry",class,en) + end + if ex then + set(unicode,"exit", class,ex) + end + end + end + end + + local function collect(list) + if list then + for i=1,#list do + local entry = list[i] + local steps = entry.steps + local kind = entry.type + if kind == "gpos_mark2mark" then + getanchors(steps,"mark") + elseif kind == "gpos_mark2base" then + getanchors(steps,"base") + elseif kind == "gpos_mark2ligature" then + getanchors(steps,"ligature") + elseif kind == "gpos_cursive" then + getcursives(steps) + end + end + end + end + + collect(resources.sequences) + collect(resources.sublookups) + + local function sorter(a,b) + if a[1] == b[1] then + return a[2] < b[2] + else + return a[1] < b[1] + end + end + + for unicode, old in next, anchors do + for target, list in next, old do + sort(list,sorter) + end + end + + resources.anchors = anchors + + return anchors + +end diff --git a/tex/context/base/mkiv/font-def.lua b/tex/context/base/mkiv/font-def.lua index 97d25f180..f3d0f8187 100644 --- a/tex/context/base/mkiv/font-def.lua +++ b/tex/context/base/mkiv/font-def.lua @@ -80,53 +80,6 @@ and prepares a table that will move along as we proceed.

-- name name(sub) name(sub)*spec name*spec -- name@spec*oeps -local splitter, splitspecifiers = nil, "" -- not so nice - -local P, C, S, Cc = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc - -local left = P("(") -local right = P(")") -local colon = P(":") -local space = P(" ") - -definers.defaultlookup = "file" - -local prefixpattern = P(false) - -local function addspecifier(symbol) - splitspecifiers = splitspecifiers .. symbol - local method = S(splitspecifiers) - local lookup = C(prefixpattern) * colon - local sub = left * C(P(1-left-right-method)^1) * right - local specification = C(method) * C(P(1)^1) - local name = C((1-sub-specification)^1) - splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc(""))) -end - -local function addlookup(str,default) - prefixpattern = prefixpattern + P(str) -end - -definers.addlookup = addlookup - -addlookup("file") -addlookup("name") -addlookup("spec") - -local function getspecification(str) - return lpegmatch(splitter,str or "") -- weird catch -end - -definers.getspecification = getspecification - -function definers.registersplit(symbol,action,verbosename) - addspecifier(symbol) - variants[symbol] = action - if verbosename then - variants[verbosename] = action - end -end - local function makespecification(specification,lookup,name,sub,method,detail,size) size = size or 655360 if not lookup or lookup == "" then @@ -151,13 +104,65 @@ local function makespecification(specification,lookup,name,sub,method,detail,siz return t end - definers.makespecification = makespecification -function definers.analyze(specification, size) - -- can be optimized with locals - local lookup, name, sub, method, detail = getspecification(specification or "") - return makespecification(specification, lookup, name, sub, method, detail, size) +if context then + + local splitter, splitspecifiers = nil, "" -- not so nice + + local P, C, S, Cc, Cs = lpeg.P, lpeg.C, lpeg.S, lpeg.Cc, lpeg.Cs + + local left = P("(") + local right = P(")") + local colon = P(":") + local space = P(" ") + local lbrace = P("{") + local rbrace = P("}") + + definers.defaultlookup = "file" + + local prefixpattern = P(false) + + local function addspecifier(symbol) + splitspecifiers = splitspecifiers .. symbol + local method = S(splitspecifiers) + local lookup = C(prefixpattern) * colon + local sub = left * C(P(1-left-right-method)^1) * right + local specification = C(method) * C(P(1)^1) + local name = Cs((lbrace/"") * (1-rbrace)^1 * (rbrace/"") + (1-sub-specification)^1) + splitter = P((lookup + Cc("")) * name * (sub + Cc("")) * (specification + Cc(""))) + end + + local function addlookup(str) + prefixpattern = prefixpattern + P(str) + end + + definers.addlookup = addlookup + + addlookup("file") + addlookup("name") + addlookup("spec") + + local function getspecification(str) + return lpegmatch(splitter,str or "") -- weird catch + end + + definers.getspecification = getspecification + + function definers.registersplit(symbol,action,verbosename) + addspecifier(symbol) + variants[symbol] = action + if verbosename then + variants[verbosename] = action + end + end + + function definers.analyze(specification, size) + -- can be optimized with locals + local lookup, name, sub, method, detail = getspecification(specification or "") + return makespecification(specification, lookup, name, sub, method, detail, size) + end + end --[[ldx-- @@ -203,9 +208,9 @@ function resolvers.name(specification) features.normal = normal end normal.instance = instance - if not callbacks.supported.glyph_stream_provider then - normal.variableshapes = true -- for the moment - end + -- if not callbacks.supported.glyph_stream_provider then + -- normal.variableshapes = true -- for the moment + -- end end -- local suffix = lower(suffixonly(resolved)) @@ -335,7 +340,7 @@ local function checkfeatures(tfmdata) for script, languages in next, scripts do if languages["*"] then -- ok - elseif not languages[usedlanguage] then + elseif context and not languages[usedlanguage] then report_defining("font %!font:name!, feature %a, script %a, no language %a", tfmdata,feature,script,usedlanguage) end @@ -355,7 +360,7 @@ local function checkfeatures(tfmdata) if not languages["*"] then for i=1,#foundlanguages do local language = foundlanguages[i] - if not languages[language] then + if context and not languages[language] then report_defining("font %!font:name!, feature %a, script %a, no language %a", tfmdata,feature,script,language) end @@ -377,6 +382,7 @@ function definers.loadfont(specification) -- todo: also hash by instance / factors local tfmdata = loadedfonts[hash] -- hashes by size ! if not tfmdata then + -- normally context will not end up here often (if so there is an issue somewhere) local forced = specification.forced or "" if forced ~= "" then local reader = readers[lower(forced)] -- normally forced is already lowered diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua index 02e5a7df6..046ba2850 100644 --- a/tex/context/base/mkiv/font-dsp.lua +++ b/tex/context/base/mkiv/font-dsp.lua @@ -51,7 +51,10 @@ if not modules then modules = { } end modules ['font-dsp'] = { -- All this packing in the otf format is somewhat obsessive as nowadays 4K resolution -- multi-gig videos pass through our networks and storage and memory is abundant. -local next, type = next, type +-- Although we use a few table readers there i sno real gain in there (apart from having +-- less code. After all there are often not that many demanding features. + +local next, type, tonumber = next, type, tonumber local band = bit32.band local extract = bit32.extract local bor = bit32.bor @@ -68,12 +71,13 @@ local reversed = table.reversed local sort = table.sort local insert = table.insert local round = math.round -local lpegmatch = lpeg.match +local settings_to_hash = utilities.parsers.settings_to_hash_colon_too local setmetatableindex = table.setmetatableindex local formatters = string.formatters local sortedkeys = table.sortedkeys local sortedhash = table.sortedhash +local sequenced = table.sequenced local report = logs.reporter("otf reader") @@ -82,10 +86,11 @@ local streamreader = readers.streamreader local setposition = streamreader.setposition local getposition = streamreader.getposition -local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer -local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer +local readuinteger = streamreader.readcardinal1 +local readushort = streamreader.readcardinal2 +local readulong = streamreader.readcardinal4 local readinteger = streamreader.readinteger1 -local readshort = streamreader.readinteger2 -- 16-bit signed integer +local readshort = streamreader.readinteger2 local readstring = streamreader.readstring local readtag = streamreader.readtag local readbytes = streamreader.readbytes @@ -93,9 +98,41 @@ local readfixed = streamreader.readfixed4 local read2dot14 = streamreader.read2dot14 local skipshort = streamreader.skipshort local skipbytes = streamreader.skip -local readfword = readshort local readbytetable = streamreader.readbytetable local readbyte = streamreader.readbyte +local readcardinaltable = streamreader.readcardinaltable +local readintegertable = streamreader.readintegertable +local readfword = readshort + +local short = 2 +local ushort = 2 +local ulong = 4 + +directives.register("fonts.streamreader",function() + + streamreader = utilities.streams + + setposition = streamreader.setposition + getposition = streamreader.getposition + readuinteger = streamreader.readcardinal1 + readushort = streamreader.readcardinal2 + readulong = streamreader.readcardinal4 + readinteger = streamreader.readinteger1 + readshort = streamreader.readinteger2 + readstring = streamreader.readstring + readtag = streamreader.readtag + readbytes = streamreader.readbytes + readfixed = streamreader.readfixed4 + read2dot14 = streamreader.read2dot14 + skipshort = streamreader.skipshort + skipbytes = streamreader.skip + readbytetable = streamreader.readbytetable + readbyte = streamreader.readbyte + readcardinaltable = streamreader.readcardinaltable + readintegertable = streamreader.readintegertable + readfword = readshort + +end) local gsubhandlers = { } local gposhandlers = { } @@ -196,39 +233,6 @@ local read_integer = { streamreader.readinteger4, } --- using helpers doesn't make much sense, subtle differences --- --- local function readushortarray(f,n) --- local t = { } --- for i=1,n do --- t[i] = readushort(f) --- end --- return t --- end --- --- local function readulongarray(f,n) --- local t = { } --- for i=1,n do --- t[i] = readulong(f) --- end --- return t --- end --- --- local function readushortarray(f,target,first,size) --- if not size then --- for i=1,size do --- target[i] = readushort(f) --- end --- else --- for i=1,size do --- target[first+i] = readushort(f) --- end --- end --- return target --- end --- --- so we get some half helper - half non helper mix then - -- Traditionally we use these unique names (so that we can flatten the lookup list -- (we create subsets runtime) but I will adapt the old code to newer names. @@ -300,30 +304,16 @@ end) -- wght:400,wdth:100,ital:1 --- local names = table.setmetatableindex ( { --- weight = "wght", --- width = "wdth", --- italic = "ital", --- }, "self") - --- todo: spaces in name but not before : - -local pattern = lpeg.Cf ( - lpeg.Ct("") * - lpeg.Cg ( - --(lpeg.R("az")^1/names) * lpeg.S(" :") * - lpeg.C((lpeg.R("az","09")+lpeg.P(" "))^1) * lpeg.S(" :=") * - (lpeg.patterns.number/tonumber) * lpeg.S(" ,")^0 - )^1, rawset -) +local function axistofactors(str) + local t = settings_to_hash(str) + for k, v in next, t do + t[k] = tonumber(v) or v -- this also normalizes numbers itself + end + return t +end local hash = table.setmetatableindex(function(t,k) - local v = lpegmatch(pattern,k) - local t = { } - for k, v in sortedhash(v) do - t[#t+1] = k .. "=" .. v - end - v = concat(t,",") + local v = sequenced(axistofactors(k),",") t[k] = v return v end) @@ -340,10 +330,6 @@ function helpers.normalizedaxis(str) return hash[str] or str end -local function axistofactors(str) - return lpegmatch(pattern,str) -end - -- contradicting spec ... (signs) so i'll check it and fix it once we have -- proper fonts @@ -498,10 +484,7 @@ local function readvariationdata(f,storeoffset,factors) -- store local format = readushort(f) local regionoffset = storeoffset + readulong(f) local nofdeltadata = readushort(f) - local deltadata = { } - for i=1,nofdeltadata do - deltadata[i] = readulong(f) - end + local deltadata = readcardinaltable(f,nofdeltadata,ulong) -- regions setposition(f,regionoffset) local nofaxis = readushort(f) @@ -532,10 +515,7 @@ local function readvariationdata(f,storeoffset,factors) -- store end -- we could test before and save a for for i=1,nofdeltasets do - local t = { } -- newtable - for i=1,nofshorts do - t[i] = readshort(f) - end + local t = readintegertable(f,nofshorts,short) for i=nofshorts+1,nofregions do t[i] = readinteger(f) end @@ -560,21 +540,32 @@ helpers.readvariationdata = readvariationdata local function readcoverage(f,offset,simple) setposition(f,offset) local coverageformat = readushort(f) - local coverage = { } if coverageformat == 1 then local nofcoverage = readushort(f) if simple then - for i=1,nofcoverage do - coverage[i] = readushort(f) + -- often 1 or 2 + if nofcoverage == 1 then + return { readushort(f) } + elseif nofcoverage == 2 then + return { readushort(f), readushort(f) } + else + return readcardinaltable(f,nofcoverage,ushort) end + elseif nofcoverage == 1 then + return { [readushort(f)] = 0 } + elseif nofcoverage == 2 then + return { [readushort(f)] = 0, [readushort(f)] = 1 } else + local coverage = { } for i=0,nofcoverage-1 do coverage[readushort(f)] = i -- index in record end + return coverage end elseif coverageformat == 2 then local nofranges = readushort(f) - local n = simple and 1 or 0 -- needs checking + local coverage = { } + local n = simple and 1 or 0 -- needs checking for i=1,nofranges do local firstindex = readushort(f) local lastindex = readushort(f) @@ -591,10 +582,11 @@ local function readcoverage(f,offset,simple) end end end + return coverage else report("unknown coverage format %a ",coverageformat) + return { } end - return coverage end local function readclassdef(f,offset,preset) @@ -828,23 +820,17 @@ local function readfirst(f,offset) return { readushort(f) } end -local function readarray(f,offset,first) +-- quite often 0, 1, 2 + +function readarray(f,offset) if offset then setposition(f,offset) end local n = readushort(f) - if first then - local t = { first } - for i=2,n do - t[i] = readushort(f) - end - return t, n + if n == 1 then + return { readushort(f) }, 1 elseif n > 0 then - local t = { } - for i=1,n do - t[i] = readushort(f) - end - return t, n + return readcardinaltable(f,n,ushort), n end end @@ -1023,8 +1009,9 @@ local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,n rules = rules, } elseif subtype == 3 then - local current = readarray(f) + local nofglyphs = readushort(f) local noflookups = readushort(f) + local current = readcardinaltable(f,nofglyphs,ushort) local lookups = readlookuparray(f,noflookups,#current) current = readcoveragearray(f,tableoffset,current,true) return { @@ -1231,7 +1218,7 @@ function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofg local delta = readshort(f) -- can be negative local coverage = readcoverage(f,tableoffset+coverage) -- not simple as we need to set key/value anyway for index in next, coverage do - local newindex = index + delta + local newindex = (index + delta) % 65536 -- modulo is new in 1.8.3 if index > nofglyphs or newindex > nofglyphs then report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) coverage[index] = nil @@ -1245,10 +1232,7 @@ function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofg elseif subtype == 2 then -- in streamreader a seek and fetch is faster than a temp table local coverage = readushort(f) local nofreplacements = readushort(f) - local replacements = { } - for i=1,nofreplacements do - replacements[i] = readushort(f) - end + local replacements = readcardinaltable(f,nofreplacements,ushort) local coverage = readcoverage(f,tableoffset + coverage) -- not simple as we need to set key/value anyway for index, newindex in next, coverage do newindex = newindex + 1 @@ -1276,18 +1260,10 @@ local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyp if subtype == 1 then local coverage = readushort(f) local nofsequence = readushort(f) - local sequences = { } - for i=1,nofsequence do - sequences[i] = readushort(f) - end + local sequences = readcardinaltable(f,nofsequence,ushort) for i=1,nofsequence do setposition(f,tableoffset + sequences[i]) - local n = readushort(f) - local s = { } - for i=1,n do - s[i] = readushort(f) - end - sequences[i] = s + sequences[i] = readcardinaltable(f,readushort(f),ushort) end local coverage = readcoverage(f,tableoffset + coverage) for index, newindex in next, coverage do @@ -1322,19 +1298,20 @@ function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,no if subtype == 1 then local coverage = readushort(f) local nofsets = readushort(f) - local ligatures = { } - for i=1,nofsets do - ligatures[i] = readushort(f) - end + local ligatures = readcardinaltable(f,nofsets,ushort) for i=1,nofsets do local offset = lookupoffset + offset + ligatures[i] setposition(f,offset) local n = readushort(f) - local l = { } - for i=1,n do - l[i] = offset + readushort(f) + if n == 1 then + ligatures[i] = { offset + readushort(f) } + else + local l = { } + for i=1,n do + l[i] = offset + readushort(f) + end + ligatures[i] = l end - ligatures[i] = l end local coverage = readcoverage(f,tableoffset + coverage) for index, newindex in next, coverage do @@ -1982,10 +1959,15 @@ do local parameters = readushort(f) -- feature.parameters local noflookups = readushort(f) if noflookups > 0 then - local lookups = { } +-- local lookups = { } +-- feature.lookups = lookups +-- for j=1,noflookups do +-- lookups[j] = readushort(f) + 1 +-- end + local lookups = readcardinaltable(f,noflookups,ushort) feature.lookups = lookups for j=1,noflookups do - lookups[j] = readushort(f) + 1 + lookups[j] = lookups[j] + 1 end end if parameters > 0 then @@ -2001,11 +1983,8 @@ do local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) setposition(f,lookupoffset) - local lookups = { } local noflookups = readushort(f) - for i=1,noflookups do - lookups[i] = readushort(f) - end + local lookups = readcardinaltable(f,noflookups,ushort) for lookupid=1,noflookups do local offset = lookups[lookupid] setposition(f,lookupoffset+offset) @@ -2237,7 +2216,7 @@ do report_issue(i,what,sequence,"no") elseif not next(rlookups) then -- can be ok as it aborts a chain sequence - report_issue(i,what,sequence,"empty") + -- report_issue(i,what,sequence,"empty") rule.lookups = nil else -- we can have holes in rlookups flagged false and we can have multiple lookups @@ -2296,9 +2275,7 @@ do end end end --- report("before : % t",rlookups[index]) rlookups[index] = noffound > 0 and found or false --- report("after : % t",rlookups[index]) else rlookups[index] = false end @@ -2322,7 +2299,7 @@ do local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) setposition(f,variationsoffset) - local version = readulong(f) + local version = readulong(f) -- two times readushort local nofrecords = readulong(f) local records = { } for i=1,nofrecords do @@ -2338,11 +2315,12 @@ do record.condition = nil record.matchtype = "always" else - setposition(f,variationsoffset+offset) + local offset = variationsoffset+offset + setposition(f,offset) local nofconditions = readushort(f) local conditions = { } for i=1,nofconditions do - conditions[i] = variationsoffset+offset+readulong(f) + conditions[i] = offset + readulong(f) end record.conditions = conditions record.matchtype = "condition" @@ -2385,10 +2363,7 @@ do setposition(f,tableoffset) local parameters = readulong(f) -- feature parameters local noflookups = readushort(f) - local lookups = { } - for i=1,noflookups do - lookups[i] = readushort(f) -- not sure what to do with these - end + local lookups = readcardinaltable(f,noflookups,ushort) -- not sure what to do with these -- todo : resolve to proper lookups record.substitutions = lookups end @@ -2449,7 +2424,7 @@ do elseif specification.globalkerns then name = "globalkern" else - report("ignoring global kern table using gpos kern feature") + report("ignoring global kern table, using gpos kern feature") return end setposition(f,datatable.offset) @@ -2611,10 +2586,7 @@ function readers.gdef(f,fontdata,specification) local format = readushort(f) if format == 1 then local nofsets = readushort(f) - local sets = { } - for i=1,nofsets do - sets[i] = readulong(f) - end + local sets = readcardinaltable(f,nofsets,ulong) for i=1,nofsets do local offset = sets[i] if offset ~= 0 then @@ -2851,14 +2823,8 @@ local function readmathvariants(f,fontdata,offset) local hcoverage = readushort(f) local vnofglyphs = readushort(f) local hnofglyphs = readushort(f) - local vconstruction = { } - local hconstruction = { } - for i=1,vnofglyphs do - vconstruction[i] = readushort(f) - end - for i=1,hnofglyphs do - hconstruction[i] = readushort(f) - end + local vconstruction = readcardinaltable(f,vnofglyphs,ushort) + local hconstruction = readcardinaltable(f,hnofglyphs,ushort) fontdata.mathconstants.MinConnectorOverlap = minoverlap @@ -3033,10 +2999,7 @@ function readers.cpal(f,fontdata,specification) local nofcolorrecords = readushort(f) local firstcoloroffset = readulong(f) local colorrecords = { } - local palettes = { } - for i=1,nofpalettes do - palettes[i] = readushort(f) - end + local palettes = readcardinaltable(f,nofpalettes,ushort) if version == 1 then -- used for guis local palettettypesoffset = readulong(f) @@ -3109,183 +3072,324 @@ function readers.sbix(f,fontdata,specification) for i=1,nofstrikes do strikes[i] = readulong(f) end - -- if true then - local shapes = { } - local done = 0 - for i=1,nofstrikes do - local strikeoffset = strikes[i] + tableoffset - setposition(f,strikeoffset) - strikes[i] = { - ppem = readushort(f), - ppi = readushort(f), - offset = strikeoffset + local shapes = { } + local done = 0 + for i=1,nofstrikes do + local strikeoffset = strikes[i] + tableoffset + setposition(f,strikeoffset) + strikes[i] = { + ppem = readushort(f), + ppi = readushort(f), + offset = strikeoffset + } + end + -- highest first + sort(strikes,function(a,b) + if b.ppem == a.ppem then + return b.ppi < a.ppi + else + return b.ppem < a.ppem + end + end) + local glyphs = { } + for i=1,nofstrikes do + local strike = strikes[i] + local strikeppem = strike.ppem + local strikeppi = strike.ppi + local strikeoffset = strike.offset + setposition(f,strikeoffset) + for i=0,nofglyphs do + glyphs[i] = readulong(f) + end + local glyphoffset = glyphs[0] + for i=0,nofglyphs-1 do + local nextoffset = glyphs[i+1] + if not shapes[i] then + local datasize = nextoffset - glyphoffset + if datasize > 0 then + setposition(f,strikeoffset + glyphoffset) + shapes[i] = { + x = readshort(f), + y = readshort(f), + tag = readtag(f), -- maybe for tracing + data = readstring(f,datasize-8), + ppem = strikeppem, -- not used, for tracing + ppi = strikeppi, -- not used, for tracing + } + done = done + 1 + if done == nofglyphs then + break + end + end + end + glyphoffset = nextoffset + end + end + fontdata.pngshapes = shapes + end +end + +-- Another bitmap (so not that useful) format. But Luigi found a font that +-- has them , so ... + +do + + local function getmetrics(f) + return { + ascender = readinteger(f), + descender = readinteger(f), + widthmax = readuinteger(f), + caretslopedumerator = readinteger(f), + caretslopedenominator = readinteger(f), + caretoffset = readinteger(f), + minorigin = readinteger(f), + minadvance = readinteger(f), + maxbefore = readinteger(f), + minafter = readinteger(f), + pad1 = readinteger(f), + pad2 = readinteger(f), + } + end + + -- bad names + + local function getbigmetrics(f) + -- bigmetrics, maybe just skip 9 bytes + return { + height = readuinteger(f), + width = readuinteger(f), + horiBearingX = readinteger(f), + horiBearingY = readinteger(f), + horiAdvance = readuinteger(f), + vertBearingX = readinteger(f), + vertBearingY = readinteger(f), + vertAdvance = readuinteger(f), + } + end + + local function getsmallmetrics(f) + -- smallmetrics, maybe just skip 5 bytes + return { + height = readuinteger(f), + width = readuinteger(f), + bearingX = readinteger(f), + bearingY = readinteger(f), + advance = readuinteger(f), + } + end + + function readers.cblc(f,fontdata,specification) + -- should we delay this ? + local ctdttableoffset = gotodatatable(f,fontdata,"cbdt",specification.glyphs) + if not ctdttableoffset then + return + end + local cblctableoffset = gotodatatable(f,fontdata,"cblc",specification.glyphs) + if cblctableoffset then + local majorversion = readushort(f) + local minorversion = readushort(f) + local nofsizetables = readulong(f) + local sizetables = { } + local shapes = { } + local subtables = { } + for i=1,nofsizetables do + sizetables[i] = { + subtables = readulong(f), + indexsize = readulong(f), + nofsubtables = readulong(f), + colorref = readulong(f), + hormetrics = getmetrics(f), + vermetrics = getmetrics(f), + firstindex = readushort(f), + lastindex = readushort(f), + ppemx = readbyte(f), + ppemy = readbyte(f), + bitdepth = readbyte(f), + flags = readbyte(f), } end - -- highest first - sort(strikes,function(a,b) - if b.ppem == a.ppem then - return b.ppi < a.ppi + sort(sizetables,function(a,b) + if b.ppemx == a.ppemx then + return b.bitdepth < a.bitdepth else - return b.ppem < a.ppem + return b.ppemx < a.ppemx end end) - local glyphs = { } - for i=1,nofstrikes do - local strike = strikes[i] - local strikeppem = strike.ppem - local strikeppi = strike.ppi - local strikeoffset = strike.offset - setposition(f,strikeoffset) - for i=0,nofglyphs do - glyphs[i] = readulong(f) + for i=1,nofsizetables do + local s = sizetables[i] + local d = false + for j=s.firstindex,s.lastindex do + if not shapes[j] then + shapes[j] = i + d = true + end end - local glyphoffset = glyphs[0] - for i=0,nofglyphs-1 do - local nextoffset = glyphs[i+1] - if not shapes[i] then - local datasize = nextoffset - glyphoffset - if datasize > 0 then - setposition(f,strikeoffset + glyphoffset) - shapes[i] = { - x = readshort(f), - y = readshort(f), - tag = readtag(f), -- maybe for tracing - data = readstring(f,datasize-8), - ppem = strikeppem, -- not used, for tracing - ppi = strikeppi, -- not used, for tracing - } - done = done + 1 - if done == nofglyphs then - break + if d then + s.used = true + end + end + for i=1,nofsizetables do + local s = sizetables[i] + if s.used then + local offset = s.subtables + setposition(f,cblctableoffset+offset) + for j=1,s.nofsubtables do + local firstindex = readushort(f) + local lastindex = readushort(f) + local tableoffset = readulong(f) + offset + for k=firstindex,lastindex do + if shapes[k] == i then + local s = subtables[tableoffset] + if not s then + s = { + firstindex = firstindex, + lastindex = lastindex, + } + subtables[tableoffset] = s + end + shapes[k] = s end end end - glyphoffset = nextoffset end end - fontdata.sbixshapes = shapes - -- else - -- for i=1,nofstrikes do - -- local strikeoffset = strikes[i] + tableoffset - -- setposition(f,strikeoffset) - -- local glyphs = { } - -- strikes[i] = { - -- ppem = readushort(f), - -- ppi = readushort(f), - -- glyphs = glyphs, - -- } - -- for i=0,nofglyphs do - -- glyphs[i] = readulong(f) - -- end - -- local glyphoffset = glyphs[0] - -- for i=0,nofglyphs-1 do - -- local nextoffset = glyphs[i+1] - -- local datasize = nextoffset - glyphoffset - -- if datasize > 0 then - -- setposition(f,strikeoffset + glyphoffset) - -- glyphs[i] = { - -- x = readshort(f), - -- y = readshort(f), - -- tag = readtag(f), - -- data = readstring(f,datasize-8) - -- } - -- glyphoffset = nextoffset - -- end - -- end - -- end - -- fontdata.sbixshapes = strikes + + -- there is no need to sort in string stream but we have a nicer trace + -- if needed + + for offset, subtable in sortedhash(subtables) do + local tabletype = readushort(f) + subtable.format = readushort(f) + local baseoffset = readulong(f) + ctdttableoffset + local offsets = { } + local metrics = nil + if tabletype == 1 then + -- we have the usual one more to get the size + for i=subtable.firstindex,subtable.lastindex do + offsets[i] = readulong(f) + baseoffset + end + skipbytes(f,4) + elseif tabletype == 2 then + local size = readulong(f) + local done = baseoffset + metrics = getbigmetrics(f) + for i=subtable.firstindex,subtable.lastindex do + offsets[i] = done + done = done + size + end + elseif tabletype == 3 then + -- we have the usual one more to get the size + local n = subtable.lastindex - subtable.firstindex + 2 + for i=subtable.firstindex,subtable.lastindex do + offsets[i] = readushort(f) + baseoffset + end + if math.odd(n) then + skipbytes(f,4) + else + skipbytes(f,2) + end + elseif tabletype == 4 then + for i=1,readulong(f) do + offsets[readushort(f)] = readushort(f) + baseoffset + end + elseif tabletype == 5 then + local size = readulong(f) + local done = baseoffset + metrics = getbigmetrics(f) + local n = readulong(f) + for i=1,n do + offsets[readushort(f)] = done + done = done + size + end + if math.odd(n) then + skipbytes(f,2) + end + else + return -- unsupported format + end + subtable.offsets = offsets + subtable.metrics = metrics + end + + -- we only support a few sensible types ... there are hardly any fonts so + -- why are there so many variants ... not the best spec + + local default = { width = 0, height = 0 } + local glyphs = fontdata.glyphs + + for index, subtable in sortedhash(shapes) do + if type(subtable) == "table" then + local data = nil + local metrics = default + local format = subtable.format + local offset = subtable.offsets[index] + setposition(f,offset) + if format == 17 then + metrics = getsmallmetrics(f) + data = readstring(f,readulong(f)) + elseif format == 18 then + metrics = getbigmetrics(f) + data = readstring(f,readulong(f)) + elseif format == 19 then + metrics = subtable.metrics + data = readstring(f,readulong(f)) + else + -- forget about it + end + local x = metrics.width + local y = metrics.height + shapes[index] = { + -- maybe some metrics + x = x, + y = y, + data = data, + } + -- I'll look into this in more details when needed + -- as we can use the bearings to get better boxes. + local glyph = glyphs[index] + if not glyph.boundingbox then + local width = glyph.width + local height = width * y/x + glyph.boundingbox = { 0, 0, width, height } + end + + else + shapes[index] = { + x = 0, + y = 0, + data = "", + } + end + end + + fontdata.pngshapes = shapes -- we cheat + end + end + + function readers.cbdt(f,fontdata,specification) + -- local tableoffset = gotodatatable(f,fontdata,"ctdt",specification.glyphs) + -- if tableoffset then + -- local majorversion = readushort(f) + -- local minorversion = readushort(f) -- end end -end --- function readers.cblc(f,fontdata,specification) --- local tableoffset = gotodatatable(f,fontdata,"cblc",specification.glyphs) --- if tableoffset then --- end --- end --- --- function readers.cbdt(f,fontdata,specification) --- local tableoffset = gotodatatable(f,fontdata,"ctdt",specification.glyphs) --- if tableoffset then --- --- local function getmetrics(f) --- return { --- ascender = readinteger(f), --- descender = readinteger(f), --- widthmax = readcardinal(f), --- caretslopedumerator = readinteger(f), --- caretslopedenominator = readinteger(f), --- caretoffset = readinteger(f), --- minorigin = readinteger(f), --- minadvance = readinteger(f), --- maxbefore = readinteger(f), --- minafter = readinteger(f), --- pad1 = readinteger(f), --- pad2 = readinteger(f), --- } --- end --- --- local majorversion = readushort(f) --- local minorversion = readushort(f) --- local nofsizetables = readulong(f) --- local sizetable = { } --- for i=1,nofsizetables do --- sizetable[i] = { --- subtables = readulong(f), --- indexsize = readulong(f), --- nofsubtables = readulong(f), --- colorref = readulong(f), --- hormetrics = getmetrics(f), --- vermetrics = getmetrics(f), --- firstindex = readushort(f), --- lastindex = readushort(f), --- ppemx = readbyte(f), --- ppemy = readbyte(f), --- bitdepth = readbyte(f), --- flags = readbyte(f), --- } --- end --- --- sort(sizetable,function(a,b) --- if b.ppemx == a.ppemx then --- return b.bitdepth < a.bitdepth --- else --- return b.ppemx < a.ppemx --- end --- end) --- --- local shapes = { } --- --- for i=1,nofsizetables do --- local s = sizetables[i] --- for j=firstindex,lastindex do --- if not shapes[j] then --- shapes[j] = { --- i --- } --- end --- end --- end --- --- inspect(shapes) --- --- end --- end + -- function readers.ebdt(f,fontdata,specification) + -- if specification.glyphs then + -- end + -- end --- function readers.ebdt(f,fontdata,specification) --- if specification.glyphs then --- end --- end + -- function readers.ebsc(f,fontdata,specification) + -- if specification.glyphs then + -- end + -- end --- function readers.ebsc(f,fontdata,specification) --- if specification.glyphs then --- end --- end + -- function readers.eblc(f,fontdata,specification) + -- if specification.glyphs then + -- end + -- end --- function readers.eblc(f,fontdata,specification) --- if specification.glyphs then --- end --- end +end -- + AVAR : optional -- + CFF2 : otf outlines @@ -3398,7 +3502,8 @@ function readers.avar(f,fontdata,specification) local lastfrom = false local lastto = false for i=1,nofvalues do - local f, t = read2dot14(f), read2dot14(f) + local f = read2dot14(f) + local t = read2dot14(f) if lastfrom and f <= lastfrom then -- ignore elseif lastto and t >= lastto then @@ -3426,11 +3531,10 @@ function readers.avar(f,fontdata,specification) return false end - local majorversion = readushort(f) -- 1 - local minorversion = readushort(f) -- 0 - local reserved = readushort(f) - local nofaxis = readushort(f) - local segments = { } + local version = readulong(f) -- 0x00010000 + local reserved = readushort(f) + local nofaxis = readushort(f) + local segments = { } for i=1,nofaxis do segments[i] = collect() end @@ -3441,7 +3545,7 @@ end function readers.fvar(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"fvar",true) -- specification.variable or specification.instancenames if tableoffset then - local version = readulong(f) -- 1.0 + local version = readulong(f) -- 0x00010000 local offsettoaxis = tableoffset + readushort(f) local reserved = skipshort(f) -- pair 1 @@ -3527,7 +3631,7 @@ function readers.hvar(f,fontdata,specification) return end - local version = readulong(f) -- 1.0 + local version = readulong(f) -- 0x00010000 local variationoffset = tableoffset + readulong(f) -- the store local advanceoffset = tableoffset + readulong(f) local lsboffset = tableoffset + readulong(f) @@ -3624,7 +3728,7 @@ end function readers.mvar(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"mvar",specification.variable) if tableoffset then - local version = readulong(f) -- 1.0 + local version = readulong(f) -- 0x00010000 local reserved = skipshort(f,1) local recordsize = readushort(f) local nofrecords = readushort(f) diff --git a/tex/context/base/mkiv/font-emp.mkvi b/tex/context/base/mkiv/font-emp.mkvi index 1b6d46798..b5c09d4c2 100644 --- a/tex/context/base/mkiv/font-emp.mkvi +++ b/tex/context/base/mkiv/font-emp.mkvi @@ -227,12 +227,22 @@ %D their style as good as possible. These macros are obsolete %D in \MKIV. -\unexpanded\def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}} -\unexpanded\def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}} -\unexpanded\def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}} -\unexpanded\def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}} - -\unexpanded\def\emph {\groupedcommand{\em}{}} +% \unexpanded\def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}} +% \unexpanded\def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}} +% \unexpanded\def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}} +% \unexpanded\def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}} +% \unexpanded\def\emph {\groupedcommand{\em}{}} + +\unexpanded\def\font_emphasis_bf{\bf\def\emphit{\bi}\def\emphsl{\bs}} +\unexpanded\def\font_emphasis_it{\it\def\emphbf{\bi}\def\emphsl{\sl}} +\unexpanded\def\font_emphasis_sl{\sl\def\emphbf{\bs}\def\emphit{\it}} +\unexpanded\def\font_emphasis_tf{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}} + +\unexpanded\def\emphbf{\triggergroupedcommandcs\font_emphasis_bf} +\unexpanded\def\emphit{\triggergroupedcommandcs\font_emphasis_it} +\unexpanded\def\emphsl{\triggergroupedcommandcs\font_emphasis_sl} +\unexpanded\def\emphtf{\triggergroupedcommandcs\font_emphasis_tf} +\unexpanded\def\emph {\triggergroupedcommandcs\em} \unexpanded\def\emphasized{\bgroup\em\let\nexttoken} diff --git a/tex/context/base/mkiv/font-enh.lua b/tex/context/base/mkiv/font-enh.lua index b1fcd9be8..9ec116d47 100644 --- a/tex/context/base/mkiv/font-enh.lua +++ b/tex/context/base/mkiv/font-enh.lua @@ -115,7 +115,7 @@ local registerotffeature = otffeatures.register ----- tosixteen = fonts.mappings.tounicode16 -local function initializeunicoding(tfmdata) +local function initialize(tfmdata) local goodies = tfmdata.goodies local newcoding = nil for i=1,#goodies do @@ -165,18 +165,14 @@ local function initializeunicoding(tfmdata) end end -local unicoding_specification = { +local specification = { name = "unicoding", description = "adapt unicode table", initializers = { - base = initializeunicoding, - node = initializeunicoding, + base = initialize, + node = initialize, }, - -- manipulators = { - -- base = finalizeunicoding, - -- node = finalizeunicoding, - -- } } -registerotffeature(unicoding_specification) -registerafmfeature(unicoding_specification) +registerotffeature(specification) +registerafmfeature(specification) diff --git a/tex/context/base/mkiv/font-ext.lua b/tex/context/base/mkiv/font-ext.lua deleted file mode 100644 index d873dccd4..000000000 --- a/tex/context/base/mkiv/font-ext.lua +++ /dev/null @@ -1,1856 +0,0 @@ -if not modules then modules = { } end modules ['font-ext'] = { - version = 1.001, - comment = "companion to font-ini.mkiv and hand-ini.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - -local next, type, tonumber = next, type, tonumber -local byte, find, formatters = string.byte, string.find, string.formatters -local utfchar = utf.char -local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort - -local context = context -local fonts = fonts -local utilities = utilities - -local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end) -local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end) - -local report_expansions = logs.reporter("fonts","expansions") -local report_protrusions = logs.reporter("fonts","protrusions") - ---[[ldx-- -

When we implement functions that deal with features, most of them -will depend of the font format. Here we define the few that are kind -of neutral.

---ldx]]-- - -local handlers = fonts.handlers -local hashes = fonts.hashes -local otf = handlers.otf -local afm = handlers.afm - -local registerotffeature = otf.features.register -local registerafmfeature = afm.features.register - -local fontdata = hashes.identifiers -local fontproperties = hashes.properties - -local constructors = fonts.constructors -local getprivate = constructors.getprivate - -local allocate = utilities.storage.allocate -local settings_to_array = utilities.parsers.settings_to_array -local settings_to_hash = utilities.parsers.settings_to_hash -local getparameters = utilities.parsers.getparameters -local gettexdimen = tex.getdimen -local family_font = node.family_font - -local setmetatableindex = table.setmetatableindex - -local implement = interfaces.implement -local variables = interfaces.variables - - -local v_background = variables.background -local v_frame = variables.frame -local v_empty = variables.empty -local v_none = variables.none - --- -- -- -- -- -- --- shared --- -- -- -- -- -- - -local function get_class_and_vector(tfmdata,value,where) -- "expansions" - local g_where = tfmdata.goodies and tfmdata.goodies[where] - local f_where = fonts[where] - local g_classes = g_where and g_where.classes - local f_classes = f_where and f_where.classes - local class = (g_classes and g_classes[value]) or (f_classes and f_classes[value]) - if class then - local class_vector = class.vector - local g_vectors = g_where and g_where.vectors - local f_vectors = f_where and f_where.vectors - local vector = (g_vectors and g_vectors[class_vector]) or (f_vectors and f_vectors[class_vector]) - return class, vector - end -end - --- -- -- -- -- -- --- expansion (hz) --- -- -- -- -- -- - -local expansions = fonts.expansions or allocate() - -fonts.expansions = expansions - -local classes = expansions.classes or allocate() -local vectors = expansions.vectors or allocate() - -expansions.classes = classes -expansions.vectors = vectors - --- beware, pdftex itself uses percentages * 10 --- --- todo: get rid of byte() here - -classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } - -classes['quality'] = { - stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1 -} - -vectors['default'] = { - [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7, - [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7, - [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7, - [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, - [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, - [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, - [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, - [byte('w')] = 0.7, [byte('z')] = 0.7, - [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, -} - -vectors['quality'] = vectors['default'] -- metatable ? - -local function initializeexpansion(tfmdata,value) - if value then - local class, vector = get_class_and_vector(tfmdata,value,"expansions") - if class then - if vector then - local stretch = class.stretch or 0 - local shrink = class.shrink or 0 - local step = class.step or 0 - local factor = class.factor or 1 - if trace_expansion then - report_expansions("setting class %a, vector %a, factor %a, stretch %a, shrink %a, step %a", - value,class.vector,factor,stretch,shrink,step) - end - tfmdata.parameters.expansion = { - stretch = 10 * stretch, - shrink = 10 * shrink, - step = 10 * step, - factor = factor, - } - local data = characters and characters.data - for i, chr in next, tfmdata.characters do - local v = vector[i] - if data and not v then -- we could move the data test outside (needed for plain) - local d = data[i] - if d then - local s = d.shcode - if not s then - -- sorry - elseif type(s) == "table" then - v = ((vector[s[1]] or 0) + (vector[s[#s]] or 0)) / 2 - else - v = vector[s] or 0 - end - end - end - if v and v ~= 0 then - chr.expansion_factor = v*factor - else -- can be option - chr.expansion_factor = factor - end - end - elseif trace_expansion then - report_expansions("unknown vector %a in class %a",class.vector,value) - end - elseif trace_expansion then - report_expansions("unknown class %a",value) - end - end -end - -local expansion_specification = { - name = "expansion", - description = "apply hz optimization", - initializers = { - base = initializeexpansion, - node = initializeexpansion, - } -} - -registerotffeature(expansion_specification) -registerafmfeature(expansion_specification) - -fonts.goodies.register("expansions", function(...) return fonts.goodies.report("expansions", trace_expansion, ...) end) - -implement { - name = "setupfontexpansion", - arguments = "2 strings", - actions = function(class,settings) getparameters(classes,class,'preset',settings) end -} - --- -- -- -- -- -- --- protrusion --- -- -- -- -- -- - -fonts.protrusions = allocate() -local protrusions = fonts.protrusions - -protrusions.classes = allocate() -protrusions.vectors = allocate() - -local classes = protrusions.classes -local vectors = protrusions.vectors - --- the values need to be revisioned - -classes.preset = { factor = 1, left = 1, right = 1 } - -classes['pure'] = { - vector = 'pure', factor = 1 -} -classes['punctuation'] = { - vector = 'punctuation', factor = 1 -} -classes['alpha'] = { - vector = 'alpha', factor = 1 -} -classes['quality'] = { - vector = 'quality', factor = 1 -} - -vectors['pure'] = { - - [0x002C] = { 0, 1 }, -- comma - [0x002E] = { 0, 1 }, -- period - [0x003A] = { 0, 1 }, -- colon - [0x003B] = { 0, 1 }, -- semicolon - [0x002D] = { 0, 1 }, -- hyphen - [0x00AD] = { 0, 1 }, -- also hyphen - [0x2013] = { 0, 0.50 }, -- endash - [0x2014] = { 0, 0.33 }, -- emdash - [0x3001] = { 0, 1 }, -- ideographic comma 、 - [0x3002] = { 0, 1 }, -- ideographic full stop 。 - [0x060C] = { 0, 1 }, -- arabic comma ، - [0x061B] = { 0, 1 }, -- arabic semicolon ؛ - [0x06D4] = { 0, 1 }, -- arabic full stop ۔ - -} - -vectors['punctuation'] = { - - [0x003F] = { 0, 0.20 }, -- ? - [0x00BF] = { 0, 0.20 }, -- ¿ - [0x0021] = { 0, 0.20 }, -- ! - [0x00A1] = { 0, 0.20 }, -- ¡ - [0x0028] = { 0.05, 0 }, -- ( - [0x0029] = { 0, 0.05 }, -- ) - [0x005B] = { 0.05, 0 }, -- [ - [0x005D] = { 0, 0.05 }, -- ] - [0x002C] = { 0, 0.70 }, -- comma - [0x002E] = { 0, 0.70 }, -- period - [0x003A] = { 0, 0.50 }, -- colon - [0x003B] = { 0, 0.50 }, -- semicolon - [0x002D] = { 0, 0.70 }, -- hyphen - [0x00AD] = { 0, 0.70 }, -- also hyphen - [0x2013] = { 0, 0.30 }, -- endash - [0x2014] = { 0, 0.20 }, -- emdash - [0x060C] = { 0, 0.70 }, -- arabic comma - [0x061B] = { 0, 0.50 }, -- arabic semicolon - [0x06D4] = { 0, 0.70 }, -- arabic full stop - [0x061F] = { 0, 0.20 }, -- ؟ - - -- todo: left and right quotes: .5 double, .7 single - - [0x2039] = { 0.70, 0.70 }, -- left single guillemet ‹ - [0x203A] = { 0.70, 0.70 }, -- right single guillemet › - [0x00AB] = { 0.50, 0.50 }, -- left guillemet « - [0x00BB] = { 0.50, 0.50 }, -- right guillemet » - - [0x2018] = { 0.70, 0.70 }, -- left single quotation mark ‘ - [0x2019] = { 0, 0.70 }, -- right single quotation mark ’ - [0x201A] = { 0.70, 0 }, -- single low-9 quotation mark , - [0x201B] = { 0.70, 0 }, -- single high-reversed-9 quotation mark ‛ - [0x201C] = { 0.50, 0.50 }, -- left double quotation mark “ - [0x201D] = { 0, 0.50 }, -- right double quotation mark ” - [0x201E] = { 0.50, 0 }, -- double low-9 quotation mark „ - [0x201F] = { 0.50, 0 }, -- double high-reversed-9 quotation mark ‟ - -} - -vectors['alpha'] = { - - [byte("A")] = { .05, .05 }, - [byte("F")] = { 0, .05 }, - [byte("J")] = { .05, 0 }, - [byte("K")] = { 0, .05 }, - [byte("L")] = { 0, .05 }, - [byte("T")] = { .05, .05 }, - [byte("V")] = { .05, .05 }, - [byte("W")] = { .05, .05 }, - [byte("X")] = { .05, .05 }, - [byte("Y")] = { .05, .05 }, - - [byte("k")] = { 0, .05 }, - [byte("r")] = { 0, .05 }, - [byte("t")] = { 0, .05 }, - [byte("v")] = { .05, .05 }, - [byte("w")] = { .05, .05 }, - [byte("x")] = { .05, .05 }, - [byte("y")] = { .05, .05 }, - -} - -vectors['quality'] = table.merged( - vectors['punctuation'], - vectors['alpha'] -) - --- As this is experimental code, users should not depend on it. The implications are still --- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the --- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The --- double trick should not be needed it proper hanging punctuation is used in which case --- values < 1 can be used. --- --- preferred (in context, usine vectors): --- --- \definefontfeature[whatever][default][mode=node,protrusion=quality] --- --- using lfbd and rtbd, with possibibility to enable only one side : --- --- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn] --- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn] --- --- idem, using multiplier --- --- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] --- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn] --- --- idem, using named feature file (less frozen): --- --- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] - -classes['double'] = { -- for testing opbd - factor = 2, left = 1, right = 1, -} - -local function map_opbd_onto_protrusion(tfmdata,value,opbd) - local characters = tfmdata.characters - local descriptions = tfmdata.descriptions - local properties = tfmdata.properties - local resources = tfmdata.resources - local rawdata = tfmdata.shared.rawdata - local lookuphash = rawdata.lookuphash - local lookuptags = resources.lookuptags - local script = properties.script - local language = properties.language - local done, factor, left, right = false, 1, 1, 1 - local class = classes[value] - if class then - factor = class.factor or 1 - left = class.left or 1 - right = class.right or 1 - else - factor = tonumber(value) or 1 - end - if opbd ~= "right" then - local validlookups, lookuplist = otf.collectlookups(rawdata,"lfbd",script,language) - if validlookups then - for i=1,#lookuplist do - local lookup = lookuplist[i] - local steps = lookup.steps - if steps then - if trace_protrusion then - report_protrusions("setting left using lfbd") - end - for i=1,#steps do - local step = steps[i] - local coverage = step.coverage - if coverage then - for k, v in next, coverage do - -- local p = - v[3] / descriptions[k].width-- or 1 ~= 0 too but the same - local p = - (v[1] / 1000) * factor * left - characters[k].left_protruding = p - if trace_protrusion then - report_protrusions("lfbd -> %C -> %p",k,p) - end - end - end - end - done = true - end - end - end - end - if opbd ~= "left" then - local validlookups, lookuplist = otf.collectlookups(rawdata,"rtbd",script,language) - if validlookups then - for i=1,#lookuplist do - local lookup = lookuplist[i] - local steps = lookup.steps - if steps then - if trace_protrusion then - report_protrusions("setting right using rtbd") - end - for i=1,#steps do - local step = steps[i] - local coverage = step.coverage - if coverage then - for k, v in next, coverage do - -- local p = v[3] / descriptions[k].width -- or 3 - local p = (v[1] / 1000) * factor * right - characters[k].right_protruding = p - if trace_protrusion then - report_protrusions("rtbd -> %C -> %p",k,p) - end - end - end - end - end - done = true - end - end - end -end - --- The opbd test is just there because it was discussed on the context development list. However, --- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported --- till we have a proper test font. - -local function initializeprotrusion(tfmdata,value) - if value then - local opbd = tfmdata.shared.features.opbd - if opbd then - -- possible values: left right both yes no (experimental) - map_opbd_onto_protrusion(tfmdata,value,opbd) - else - local class, vector = get_class_and_vector(tfmdata,value,"protrusions") - if class then - if vector then - local factor = class.factor or 1 - local left = class.left or 1 - local right = class.right or 1 - if trace_protrusion then - report_protrusions("setting class %a, vector %a, factor %a, left %a, right %a", - value,class.vector,factor,left,right) - end - local data = characters.data - local emwidth = tfmdata.parameters.quad - tfmdata.parameters.protrusion = { - factor = factor, - left = left, - right = right, - } - for i, chr in next, tfmdata.characters do - local v, pl, pr = vector[i], nil, nil - if v then - pl, pr = v[1], v[2] - else - local d = data[i] - if d then - local s = d.shcode - if not s then - -- sorry - elseif type(s) == "table" then - local vl, vr = vector[s[1]], vector[s[#s]] - if vl then pl = vl[1] end - if vr then pr = vr[2] end - else - v = vector[s] - if v then - pl, pr = v[1], v[2] - end - end - end - end - if pl and pl ~= 0 then - chr.left_protruding = left *pl*factor - end - if pr and pr ~= 0 then - chr.right_protruding = right*pr*factor - end - end - elseif trace_protrusion then - report_protrusions("unknown vector %a in class %a",class.vector,value) - end - elseif trace_protrusion then - report_protrusions("unknown class %a",value) - end - end - end -end - -local protrusion_specification = { - name = "protrusion", - description = "l/r margin character protrusion", - initializers = { - base = initializeprotrusion, - node = initializeprotrusion, - } -} - -registerotffeature(protrusion_specification) -registerafmfeature(protrusion_specification) - -fonts.goodies.register("protrusions", function(...) return fonts.goodies.report("protrusions", trace_protrusion, ...) end) - -implement { - name = "setupfontprotrusion", - arguments = "2 strings", - actions = function(class,settings) getparameters(classes,class,'preset',settings) end -} - --- -- -- - -local function initializenostackmath(tfmdata,value) - tfmdata.properties.nostackmath = value and true -end - -registerotffeature { - name = "nostackmath", - description = "disable math stacking mechanism", - initializers = { - base = initializenostackmath, - node = initializenostackmath, - } -} - -local function initializerealdimensions(tfmdata,value) - tfmdata.properties.realdimensions = value and true -end - -registerotffeature { - name = "realdimensions", - description = "accept negative dimenions", - initializers = { - base = initializerealdimensions, - node = initializerealdimensions, - } -} - -local function initializeitlc(tfmdata,value) -- hm, always value - if value then - -- the magic 40 and it formula come from Dohyun Kim but we might need another guess - local parameters = tfmdata.parameters - local italicangle = parameters.italicangle - if italicangle and italicangle ~= 0 then - local properties = tfmdata.properties - local factor = tonumber(value) or 1 - properties.hasitalics = true - properties.autoitalicamount = factor * (parameters.uwidth or 40)/2 - end - end -end - -local italic_specification = { - name = "itlc", - description = "italic correction", - initializers = { - base = initializeitlc, - node = initializeitlc, - } -} - -registerotffeature(italic_specification) -registerafmfeature(italic_specification) - -local function initializetextitalics(tfmdata,value) -- yes no delay - tfmdata.properties.textitalics = toboolean(value) -end - -local textitalics_specification = { - name = "textitalics", - description = "use alternative text italic correction", - initializers = { - base = initializetextitalics, - node = initializetextitalics, - } -} - -registerotffeature(textitalics_specification) -registerafmfeature(textitalics_specification) - --- local function initializemathitalics(tfmdata,value) -- yes no delay --- tfmdata.properties.mathitalics = toboolean(value) --- end --- --- local mathitalics_specification = { --- name = "mathitalics", --- description = "use alternative math italic correction", --- initializers = { --- base = initializemathitalics, --- node = initializemathitalics, --- } --- } - --- registerotffeature(mathitalics_specification) --- registerafmfeature(mathitalics_specification) - --- slanting - -local function initializeslant(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - elseif value > 1 then - value = 1 - elseif value < -1 then - value = -1 - end - tfmdata.parameters.slantfactor = value -end - -local slant_specification = { - name = "slant", - description = "slant glyphs", - initializers = { - base = initializeslant, - node = initializeslant, - } -} - -registerotffeature(slant_specification) -registerafmfeature(slant_specification) - -local function initializeextend(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - elseif value > 10 then - value = 10 - elseif value < -10 then - value = -10 - end - tfmdata.parameters.extendfactor = value -end - -local extend_specification = { - name = "extend", - description = "scale glyphs horizontally", - initializers = { - base = initializeextend, - node = initializeextend, - } -} - -registerotffeature(extend_specification) -registerafmfeature(extend_specification) - --- For Wolfgang Schuster: --- --- \definefontfeature[thisway][default][script=hang,language=zhs,dimensions={2,2,2}] --- \definedfont[file:kozminpr6nregular*thisway] --- --- For the moment we don't mess with the descriptions. - -local function manipulatedimensions(tfmdata,key,value) - if type(value) == "string" and value ~= "" then - local characters = tfmdata.characters - local parameters = tfmdata.parameters - local emwidth = parameters.quad - local exheight = parameters.xheight - local newwidth = false - local newheight = false - local newdepth = false - if value == "strut" then - newheight = gettexdimen("strutht") - newdepth = gettexdimen("strutdp") - elseif value == "mono" then - newwidth = emwidth - else - local spec = settings_to_array(value) - newwidth = tonumber(spec[1]) - newheight = tonumber(spec[2]) - newdepth = tonumber(spec[3]) - if newwidth then newwidth = newwidth * emwidth end - if newheight then newheight = newheight * exheight end - if newdepth then newdepth = newdepth * exheight end - end - if newwidth or newheight or newdepth then - local additions = { } - for unicode, old_c in next, characters do - local oldwidth = old_c.width - local oldheight = old_c.height - local olddepth = old_c.depth - local width = newwidth or oldwidth or 0 - local height = newheight or oldheight or 0 - local depth = newdepth or olddepth or 0 - if oldwidth ~= width or oldheight ~= height or olddepth ~= depth then - local private = getprivate(tfmdata) - local newslot = { "slot", 1, private } -- { "slot", 0, private } - local new_c - local commands = oldwidth ~= width and { - { "right", (width - oldwidth) / 2 }, - newslot, - } or { - newslot, - } - if height > 0 then - if depth > 0 then - new_c = { - width = width, - height = height, - depth = depth, - commands = commands, - } - else - new_c = { - width = width, - height = height, - commands = commands, - } - end - else - if depth > 0 then - new_c = { - width = width, - depth = depth, - commands = commands, - } - else - new_c = { - width = width, - commands = commands, - } - end - end - setmetatableindex(new_c,old_c) - characters[unicode] = new_c - additions[private] = old_c - end - end - for k, v in next, additions do - characters[k] = v - end - -- elseif height > 0 and depth > 0 then - -- for unicode, old_c in next, characters do - -- old_c.height = height - -- old_c.depth = depth - -- end - -- elseif height > 0 then - -- for unicode, old_c in next, characters do - -- old_c.height = height - -- end - -- elseif depth > 0 then - -- for unicode, old_c in next, characters do - -- old_c.depth = depth - -- end - end - end -end - -local dimensions_specification = { - name = "dimensions", - description = "force dimensions", - manipulators = { - base = manipulatedimensions, - node = manipulatedimensions, - } -} - -registerotffeature(dimensions_specification) -registerafmfeature(dimensions_specification) - --------------------------------------------------------------------------------------------------------------- - --- local function fakemonospace(tfmdata) --- local resources = tfmdata.resources --- local gposfeatures = resources.features.gpos --- local characters = tfmdata.characters --- local descriptions = tfmdata.descriptions --- local sequences = resources.sequences --- local coverage = { } --- local units = tfmdata.shared.rawdata.metadata.units --- for k, v in next, characters do --- local w = descriptions[k].width --- local d = units - w --- coverage[k] = { -d/2, 0, units, 0 } --- end --- local f = { dflt = { dflt = true } } --- local s = #sequences + 1 --- local t = { --- features = { fakemono = f }, --- flags = { false, false, false, false }, --- index = s, --- name = "p_s_" .. s, --- nofsteps = 1, --- order = { "fakemono" }, --- skiphash = false, --- type = "gpos_single", --- steps = { --- { --- format = "single", --- coverage = coverage, --- } --- } --- } --- gposfeatures["fakemono"] = f --- sequences[s] = t --- end --- --- fonts.constructors.features.otf.register { --- name = "fakemono", --- description = "fake monospaced", --- initializers = { --- node = fakemonospace, --- }, --- } - --------------------------------------------------------------------------------------------------------------- - --- for zhichu chen (see mailing list archive): we might add a few more variants --- in due time --- --- \definefontfeature[boxed][default][boundingbox=yes] % paleblue --- --- maybe: --- --- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression --- --- local gray = { "pdf", "origin", "/Tr1 gs .75 g" } --- local black = { "pdf", "origin", "/Tr0 gs 0 g" } - - --- boundingbox={yes|background|frame|empty|} - -local push = { "push" } -local pop = { "pop" } - ------ gray = { "pdf", "origin", ".75 g .75 G" } ------ black = { "pdf", "origin", "0 g 0 G" } ------ gray = { "pdf", ".75 g" } ------ black = { "pdf", "0 g" } - --- local bp = number.dimenfactors.bp --- --- local downcache = setmetatableindex(function(t,d) --- local v = { "down", d } --- t[d] = v --- return v --- end) --- --- local backcache = setmetatableindex(function(t,h) --- local h = h * bp --- local v = setmetatableindex(function(t,w) --- -- local v = { "rule", h, w } --- local v = { "pdf", "origin", formatters["0 0 %.6F %.6F re F"](w*bp,h) } --- t[w] = v --- return v --- end) --- t[h] = v --- return v --- end) --- --- local forecache = setmetatableindex(function(t,h) --- local h = h * bp --- local v = setmetatableindex(function(t,w) --- local v = { "pdf", "origin", formatters["%.6F w 0 0 %.6F %.6F re S"](0.25*65536*bp,w*bp,h) } --- t[w] = v --- return v --- end) --- t[h] = v --- return v --- end) - -local bp = number.dimenfactors.bp -local r = 16384 * bp -- 65536 // 4 - -local backcache = setmetatableindex(function(t,h) - local h = h * bp - local v = setmetatableindex(function(t,d) - local d = d * bp - local v = setmetatableindex(function(t,w) - local v = { "pdf", "origin", formatters["%.6F w 0 %.6F %.6F %.6F re f"](r,-d,w*bp,h+d) } - t[w] = v - return v - end) - t[d] = v - return v - end) - t[h] = v - return v -end) - -local forecache = setmetatableindex(function(t,h) - local h = h * bp - local v = setmetatableindex(function(t,d) - local d = d * bp - local v = setmetatableindex(function(t,w) - -- the frame goes through the boundingbox - -- local v = { "pdf", "origin", formatters["[] 0 d 0 J %.6F w %.6F %.6F %.6F re S"](r,-d,w*bp,h+d) } - local v = { "pdf", "origin", formatters["[] 0 d 0 J %.6F w %.6F %.6F %.6F %.6F re S"](r,r/2,-d+r/2,w*bp-r,h+d-r) } - t[w] = v - return v - end) - t[d] = v - return v - end) - t[h] = v - return v -end) - -local startcolor = nil -local stopcolor = nil - -local function showboundingbox(tfmdata,key,value) - if value then - if not backcolors then - local vfspecials = backends.pdf.tables.vfspecials - startcolor = vfspecials.startcolor - stopcolor = vfspecials.stopcolor - end - local characters = tfmdata.characters - local additions = { } - local rulecache = backcache - local showchar = true - local color = "palegray" - if type(value) == "string" then - value = settings_to_array(value) - for i=1,#value do - local v = value[i] - if v == v_frame then - rulecache = forecache - elseif v == v_background then - rulecache = backcache - elseif v == v_empty then - showchar = false - elseif v == v_none then - color = nil - else - color = v - end - end - end - local gray = color and startcolor(color) or nil - local black = gray and stopcolor or nil - for unicode, old_c in next, characters do - local private = getprivate(tfmdata) - local width = old_c.width or 0 - local height = old_c.height or 0 - local depth = old_c.depth or 0 - local char = showchar and { "slot", 1, private } or nil -- { "slot", 0, private } - -- local new_c - -- if depth == 0 then - -- new_c = { - -- width = width, - -- height = height, - -- commands = { - -- push, - -- gray, - -- rulecache[height][width], - -- black, - -- pop, - -- char, - -- } - -- } - -- else - -- new_c = { - -- width = width, - -- height = height, - -- depth = depth, - -- commands = { - -- push, - -- downcache[depth], - -- gray, - -- rulecache[height+depth][width], - -- black, - -- pop, - -- char, - -- } - -- } - -- end - local rule = rulecache[height][depth][width] - local new_c = { - width = width, - height = height, - depth = depth, - commands = gray and { - -- push, - gray, - rule, - black, - -- pop, - char, - } or { - rule, - char, - } - } - setmetatableindex(new_c,old_c) - characters[unicode] = new_c - additions[private] = old_c - end - for k, v in next, additions do - characters[k] = v - end - end -end - -registerotffeature { - name = "boundingbox", - description = "show boundingbox", - manipulators = { - base = showboundingbox, - node = showboundingbox, - } -} - --- -- for notosans but not general --- --- do --- --- local v_local = interfaces and interfaces.variables and interfaces.variables["local"] or "local" --- --- local utfbyte = utf.byte --- --- local function initialize(tfmdata,key,value) --- local characters = tfmdata.characters --- local parameters = tfmdata.parameters --- local oldchar = 32 --- local newchar = 32 --- if value == "locl" or value == v_local then --- newchar = fonts.handlers.otf.getsubstitution(tfmdata,oldchar,"locl",true) or oldchar --- elseif value == true then --- -- use normal space --- elseif value then --- newchar = utfbyte(value) --- else --- return --- end --- local newchar = newchar and characters[newchar] --- local newspace = newchar and newchar.width --- if newspace > 0 then --- parameters.space = newspace --- parameters.space_stretch = newspace/2 --- parameters.space_shrink = newspace/3 --- parameters.extra_space = parameters.space_shrink --- end --- end --- --- registerotffeature { --- name = 'space', -- true|false|locl|character --- description = 'space settings', --- manipulators = { --- base = initialize, --- node = initialize, --- } --- } --- --- end - -do - - local P, lpegpatterns, lpegmatch = lpeg.P, lpeg.patterns, lpeg.match - - local amount, stretch, shrink, extra - - local factor = lpegpatterns.unsigned - local space = lpegpatterns.space - local pattern = ( - (factor / function(n) amount = tonumber(n) or amount end) - + (P("+") + P("plus" )) * space^0 * (factor / function(n) stretch = tonumber(n) or stretch end) - + (P("-") + P("minus")) * space^0 * (factor / function(n) shrink = tonumber(n) or shrink end) - + ( P("extra")) * space^0 * (factor / function(n) extra = tonumber(n) or extra end) - + space^1 - )^1 - - local function initialize(tfmdata,key,value) - local characters = tfmdata.characters - local parameters = tfmdata.parameters - if type(value) == "string" then - local emwidth = parameters.quad - amount, stretch, shrink, extra = 0, 0, 0, false - lpegmatch(pattern,value) - if not extra then - if shrink ~= 0 then - extra = shrink - elseif stretch ~= 0 then - extra = stretch - else - extra = amount - end - end - parameters.space = amount * emwidth - parameters.space_stretch = stretch * emwidth - parameters.space_shrink = shrink * emwidth - parameters.extra_space = extra * emwidth - end - end - - -- 1.1 + 1.2 - 1.3 minus 1.4 plus 1.1 extra 1.4 -- last one wins - - registerotffeature { - name = "spacing", - description = "space settings", - manipulators = { - base = initialize, - node = initialize, - } - } - -end - --- -- historic stuff, move from font-ota (handled differently, typo-rep) --- --- local delete_node = nodes.delete --- local fontdata = fonts.hashes.identifiers --- --- local nodecodes = nodes.nodecodes --- local glyph_code = nodecodes.glyph --- --- local strippables = allocate() --- fonts.strippables = strippables --- --- strippables.joiners = table.tohash { --- 0x200C, -- zwnj --- 0x200D, -- zwj --- } --- --- strippables.all = table.tohash { --- 0x000AD, 0x017B4, 0x017B5, 0x0200B, 0x0200C, 0x0200D, 0x0200E, 0x0200F, 0x0202A, 0x0202B, --- 0x0202C, 0x0202D, 0x0202E, 0x02060, 0x02061, 0x02062, 0x02063, 0x0206A, 0x0206B, 0x0206C, --- 0x0206D, 0x0206E, 0x0206F, 0x0FEFF, 0x1D173, 0x1D174, 0x1D175, 0x1D176, 0x1D177, 0x1D178, --- 0x1D179, 0x1D17A, 0xE0001, 0xE0020, 0xE0021, 0xE0022, 0xE0023, 0xE0024, 0xE0025, 0xE0026, --- 0xE0027, 0xE0028, 0xE0029, 0xE002A, 0xE002B, 0xE002C, 0xE002D, 0xE002E, 0xE002F, 0xE0030, --- 0xE0031, 0xE0032, 0xE0033, 0xE0034, 0xE0035, 0xE0036, 0xE0037, 0xE0038, 0xE0039, 0xE003A, --- 0xE003B, 0xE003C, 0xE003D, 0xE003E, 0xE003F, 0xE0040, 0xE0041, 0xE0042, 0xE0043, 0xE0044, --- 0xE0045, 0xE0046, 0xE0047, 0xE0048, 0xE0049, 0xE004A, 0xE004B, 0xE004C, 0xE004D, 0xE004E, --- 0xE004F, 0xE0050, 0xE0051, 0xE0052, 0xE0053, 0xE0054, 0xE0055, 0xE0056, 0xE0057, 0xE0058, --- 0xE0059, 0xE005A, 0xE005B, 0xE005C, 0xE005D, 0xE005E, 0xE005F, 0xE0060, 0xE0061, 0xE0062, --- 0xE0063, 0xE0064, 0xE0065, 0xE0066, 0xE0067, 0xE0068, 0xE0069, 0xE006A, 0xE006B, 0xE006C, --- 0xE006D, 0xE006E, 0xE006F, 0xE0070, 0xE0071, 0xE0072, 0xE0073, 0xE0074, 0xE0075, 0xE0076, --- 0xE0077, 0xE0078, 0xE0079, 0xE007A, 0xE007B, 0xE007C, 0xE007D, 0xE007E, 0xE007F, --- } --- --- strippables[true] = strippables.joiners --- --- local function processformatters(head,font) --- local subset = fontdata[font].shared.features.formatters --- local vector = subset and strippables[subset] --- if vector then --- local current, done = head, false --- while current do --- if current.id == glyph_code and current.subtype<256 and current.font == font then --- local char = current.char --- if vector[char] then --- head, current = delete_node(head,current) --- done = true --- else --- current = current.next --- end --- else --- current = current.next --- end --- end --- return head, done --- else --- return head, false --- end --- end --- --- registerotffeature { --- name = "formatters", --- description = "hide formatting characters", --- methods = { --- base = processformatters, --- node = processformatters, --- } --- } - --- not to be used! experimental code, only needed when testing - -local is_letter = characters.is_letter -local always = true - -local function collapseitalics(tfmdata,key,value) - local threshold = value == true and 100 or tonumber(value) - if threshold and threshold > 0 then - if threshold > 100 then - threshold = 100 - end - for unicode, data in next, tfmdata.characters do - if always or is_letter[unicode] or is_letter[data.unicode] then - local italic = data.italic - if italic and italic ~= 0 then - local width = data.width - if width and width ~= 0 then - local delta = threshold * italic / 100 - data.width = width + delta - data.italic = italic - delta - end - end - end - end - end -end - -local dimensions_specification = { - name = "collapseitalics", - description = "collapse italics", - manipulators = { - base = collapseitalics, - node = collapseitalics, - } -} - -registerotffeature(dimensions_specification) -registerafmfeature(dimensions_specification) - --- a handy helper (might change or be moved to another namespace) - -local nodepool = nodes.pool -local new_glyph = nodepool.glyph - -local helpers = fonts.helpers -local currentfont = font.current - -local currentprivate = 0xE000 -local maximumprivate = 0xEFFF - --- if we run out of space we can think of another range but by sharing we can --- use these privates for mechanisms like alignments-on-character and such - -local sharedprivates = setmetatableindex(function(t,k) - v = currentprivate - if currentprivate < maximumprivate then - currentprivate = currentprivate + 1 - else - -- reuse last slot, todo: warning - end - t[k] = v - return v -end) - -function helpers.addprivate(tfmdata,name,characterdata) - local properties = tfmdata.properties - local characters = tfmdata.characters - local privates = properties.privates - if not privates then - privates = { } - properties.privates = privates - end - if not name then - name = formatters["anonymous_private_0x%05X"](currentprivate) - end - local usedprivate = sharedprivates[name] - privates[name] = usedprivate - characters[usedprivate] = characterdata - return usedprivate -end - -local function getprivateslot(id,name) - if not name then - name = id - id = currentfont() - end - local properties = fontproperties[id] - local privates = properties and properties.privates - return privates and privates[name] -end - -local function getprivatenode(tfmdata,name) - if type(tfmdata) == "number" then - tfmdata = fontdata[tfmdata] - end - local properties = tfmdata.properties - local font = properties.id - local slot = getprivateslot(font,name) - if slot then - -- todo: set current attribibutes - local char = tfmdata.characters[slot] - local tonode = char.tonode - if tonode then - return tonode(font,char) - else - return new_glyph(font,slot) - end - end -end - -local function getprivatecharornode(tfmdata,name) - if type(tfmdata) == "number" then - tfmdata = fontdata[tfmdata] - end - local properties = tfmdata.properties - local font = properties.id - local slot = getprivateslot(font,name) - if slot then - -- todo: set current attributes - local char = tfmdata.characters[slot] - local tonode = char.tonode - if tonode then - return "node", tonode(tfmdata,char) - else - return "char", slot - end - end -end - -helpers.getprivateslot = getprivateslot -helpers.getprivatenode = getprivatenode -helpers.getprivatecharornode = getprivatecharornode - -function helpers.getprivates(tfmdata) - if type(tfmdata) == "number" then - tfmdata = fontdata[tfmdata] - end - local properties = tfmdata.properties - return properties and properties.privates -end - -function helpers.hasprivate(tfmdata,name) - if type(tfmdata) == "number" then - tfmdata = fontdata[tfmdata] - end - local properties = tfmdata.properties - local privates = properties and properties.privates - return privates and privates[name] or false -end - --- relatively new: - -do - - local extraprivates = { } - - function fonts.helpers.addextraprivate(name,f) - extraprivates[#extraprivates+1] = { name, f } - end - - local function addextraprivates(tfmdata) - for i=1,#extraprivates do - local e = extraprivates[i] - local c = e[2](tfmdata) - if c then - fonts.helpers.addprivate(tfmdata, e[1], c) - end - end - end - - constructors.newfeatures.otf.register { - name = "extraprivates", - description = "extra privates", - default = true, - manipulators = { - base = addextraprivates, - node = addextraprivates, - } - } - -end - -implement { - name = "getprivatechar", - arguments = "string", - actions = function(name) - local p = getprivateslot(name) - if p then - context(utfchar(p)) - end - end -} - -implement { - name = "getprivatemathchar", - arguments = "string", - actions = function(name) - local p = getprivateslot(family_font(0),name) - if p then - context(utfchar(p)) - end - end -} - -implement { - name = "getprivateslot", - arguments = "string", - actions = function(name) - local p = getprivateslot(name) - if p then - context(p) - end - end -} - --- requested for latex but not supported unless really needed in context: --- --- registerotffeature { --- name = "ignoremathconstants", --- description = "ignore math constants table", --- initializers = { --- base = function(tfmdata,value) --- if value then --- tfmdata.mathparameters = nil --- end --- end --- } --- } - --- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0 - -do - - local splitter = lpeg.splitat(",",tonumber) - local lpegmatch = lpeg.match - - local function initialize(tfmdata,value) - local mathparameters = tfmdata.mathparameters - if mathparameters then - local sup, sub - if type(value) == "string" then - sup, sub = lpegmatch(splitter,value) - if not sup then - sub, sup = 0, 0 - elseif not sub then - sub, sup = sup, 0 - end - elseif type(value) == "number" then - sup, sub = 0, value - end - mathparameters.NoLimitSupFactor = sup - mathparameters.NoLimitSubFactor = sub - end - end - - registerotffeature { - name = "mathnolimitsmode", - description = "influence nolimits placement", - initializers = { - base = initialize, - node = initialize, - } - } - -end - -do - - local function initialize(tfmdata,value) - local properties = tfmdata.properties - if properties then - properties.identity = value == "vertical" and "vertical" or "horizontal" - end - end - - registerotffeature { - name = "identity", - description = "set font identity", - initializers = { - base = initialize, - node = initialize, - } - } - - local function initialize(tfmdata,value) - local properties = tfmdata.properties - if properties then - properties.writingmode = value == "vertical" and "vertical" or "horizontal" - end - end - - registerotffeature { - name = "writingmode", - description = "set font direction", - initializers = { - base = initialize, - node = initialize, - } - } - -end - -do -- another hack for a crappy font - - local function additalictowidth(tfmdata,key,value) - local characters = tfmdata.characters - local additions = { } - for unicode, old_c in next, characters do - -- maybe check for math - local oldwidth = old_c.width - local olditalic = old_c.italic - if olditalic and olditalic ~= 0 then - local private = getprivate(tfmdata) - local new_c = { - width = oldwidth + olditalic, - height = old_c.height, - depth = old_c.depth, - commands = { - -- { "slot", 1, private }, - -- { "slot", 0, private }, - { "char", private }, - { "right", olditalic }, - }, - } - setmetatableindex(new_c,old_c) - characters[unicode] = new_c - additions[private] = old_c - end - end - for k, v in next, additions do - characters[k] = v - end - end - - registerotffeature { - name = "italicwidths", - description = "add italic to width", - manipulators = { - base = additalictowidth, - -- node = additalictowidth, -- only makes sense for math - } - } - -end - -do - - local tounicode = fonts.mappings.tounicode - - local function check(tfmdata,key,value) - if value == "ligatures" then - local private = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 - local collected = fonts.handlers.otf.readers.getcomponents(tfmdata.shared.rawdata) - if collected and next(collected)then - for unicode, char in next, tfmdata.characters do - if true then -- if unicode >= private or (unicode >= 0xE000 and unicode <= 0xF8FF) then - local u = collected[unicode] - if u then - local n = #u - for i=1,n do - if u[i] > private then - n = 0 - break - end - end - if n > 0 then - if n == 1 then - u = u[1] - end - char.unicode = u - char.tounicode = tounicode(u) - end - end - end - end - end - end - end - - -- forceunicodes=ligatures : aggressive lig resolving (e.g. for emoji) - -- - -- kind of like: \enabletrackers[fonts.mapping.forceligatures] - - registerotffeature { - name = "forceunicodes", - description = "forceunicodes", - manipulators = { - base = check, - node = check, - } - } - -end - -do - - -- This is a rather special test-only feature that I added for the sake of testing - -- Idris's husayni. We wanted to know if uniscribe obeys the order of lookups in a - -- font, in spite of what the description of handling arabic suggests. And indeed, - -- mixed-in lookups of other features (like all these ss* in husayni) are handled - -- the same in context as in uniscribe. If one sets reorderlookups=arab then we sort - -- according to the "assumed" order so e.g. the ss* move to after the standard - -- features. The observed difference in rendering is an indication that uniscribe is - -- quite faithful to the font (while e.g. tests with the hb plugin demonstrate some - -- interference, apart from some hard coded init etc expectations). Anyway, it means - -- that we're okay with the (generic) node processor. A pitfall is that in context - -- we can actually control more, so we can trigger an analyze pass with e.g. - -- dflt/dflt while the libraries depend on the script settings for that. Uniscribe - -- probably also parses the string and when seeing arabic will follow a different - -- code path, although it seems to treat all features equal. - - local trace_reorder = trackers.register("fonts.reorderlookups",function(v) trace_reorder = v end) - local report_reorder = logs.reporter("fonts","reorder") - - local vectors = { } - - vectors.arab = { - gsub = { - ccmp = 1, - isol = 2, - fina = 3, - medi = 4, - init = 5, - rlig = 6, - rclt = 7, - calt = 8, - liga = 9, - dlig = 10, - cswh = 11, - mset = 12, - }, - gpos = { - curs = 1, - kern = 2, - mark = 3, - mkmk = 4, - }, - } - - function otf.reorderlookups(tfmdata,vector) - local order = vectors[vector] - if not order then - return - end - local oldsequences = tfmdata.resources.sequences - if oldsequences then - local sequences = { } - for i=1,#oldsequences do - sequences[i] = oldsequences[i] - end - for i=1,#sequences do - local s = sequences[i] - local features = s.features - local kind = s.type - local index = s.index - if features then - local when - local what - for feature in sortedhash(features) do - if not what then - what = find(kind,"^gsub") and "gsub" or "gpos" - end - local newwhen = order[what][feature] - if not newwhen then - -- skip - elseif not when then - when = newwhen - elseif newwhen < when then - when = newwhen - end - end - s.ondex = s.index - s.index = i - s.what = what == "gsub" and 1 or 2 - s.when = when or 99 - else - s.ondex = s.index - s.index = i - s.what = 1 - s.when = 99 - end - end - sort(sequences,function(a,b) - local what_a = a.what - local what_b = b.what - if what_a ~= what_b then - return a.index < b.index - end - local when_a = a.when - local when_b = b.when - if when_a == when_b then - return a.index < b.index - else - return when_a < when_b - end - end) - local swapped = 0 - for i=1,#sequences do - local sequence = sequences[i] - local features = sequence.features - if features then - local index = sequence.index - if index ~= i then - swapped = swapped + 1 - end - if trace_reorder then - if swapped == 1 then - report_reorder() - report_reorder("start swapping lookups in font %!font:name!",tfmdata) - report_reorder() - report_reorder("gsub order: % t",table.swapped(order.gsub)) - report_reorder("gpos order: % t",table.swapped(order.gpos)) - report_reorder() - end - report_reorder("%03i : lookup %03i, type %s, sorted %2i, moved %s, % t", - i,index,sequence.what == 1 and "gsub" or "gpos",sequence.when or 99, - (index > i and "-") or (index < i and "+") or "=",sortedkeys(features)) - end - end - sequence.what = nil - sequence.when = nil - sequence.index = sequence.ondex - end - if swapped > 0 then - if trace_reorder then - report_reorder() - report_reorder("stop swapping lookups, %i lookups swapped",swapped) - report_reorder() - end --- tfmdata.resources.sequences = sequences - tfmdata.shared.reorderedsequences = sequences - end - end - end - - -- maybe delay till ra is filled - - local function reorderlookups(tfmdata,key,value) - if value then - otf.reorderlookups(tfmdata,value) - end - end - - registerotffeature { - name = "reorderlookups", - description = "reorder lookups", - manipulators = { - base = reorderlookups, - node = reorderlookups, - } - } - -end - --- maybe useful - -local function initializeoutline(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - else - value = tonumber(value) or 0 - end - if value then - value = value * 1000 - end - tfmdata.parameters.mode = 1 - tfmdata.parameters.width = value -end - -local outline_specification = { - name = "outline", - description = "outline glyphs", - initializers = { - base = initializeoutline, - node = initializeoutline, - } -} - -registerotffeature(outline_specification) -registerafmfeature(outline_specification) - --- definitely ugly - -local report_effect = logs.reporter("fonts","effect") -local trace_effect = false - -trackers.register("fonts.effect", function(v) trace_effect = v end) - -local effects = { - inner = 0, - normal = 0, - outer = 1, - outline = 1, - both = 2, - hidden = 3, -} - -local function initializeeffect(tfmdata,value) - local spec - if type(value) == "number" then - spec = { width = value } - else - spec = settings_to_hash(value) - end - local effect = spec.effect or "both" - local width = tonumber(spec.width) or 0 - local mode = effects[effect] - if not mode then - report_effect("invalid effect %a",effect) - elseif width == 0 and mode == 0 then - report_effect("invalid width %a for effect %a",width,effect) - else - local parameters = tfmdata.parameters - local properties = tfmdata.properties - parameters.mode = mode - parameters.width = width * 1000 - local factor = tonumber(spec.factor) or 0 - local hfactor = tonumber(spec.vfactor) or factor - local vfactor = tonumber(spec.hfactor) or factor - local delta = tonumber(spec.delta) or 1 - local wdelta = tonumber(spec.wdelta) or delta - local hdelta = tonumber(spec.hdelta) or delta - local ddelta = tonumber(spec.ddelta) or hdelta - properties.effect = { - effect = effect, - width = width, - factor = factor, - hfactor = hfactor, - vfactor = vfactor, - wdelta = wdelta, - hdelta = hdelta, - ddelta = ddelta, - } - end -end - -local function manipulateeffect(tfmdata) - local effect = tfmdata.properties.effect - if effect then - local characters = tfmdata.characters - local parameters = tfmdata.parameters - local multiplier = effect.width * 100 - local wdelta = effect.wdelta * parameters.hfactor * multiplier - local hdelta = effect.hdelta * parameters.vfactor * multiplier - local ddelta = effect.ddelta * parameters.vfactor * multiplier - local hshift = wdelta / 2 - local factor = (1 + effect.factor) * parameters.factor - local hfactor = (1 + effect.hfactor) * parameters.hfactor - local vfactor = (1 + effect.vfactor) * parameters.vfactor - for unicode, old_c in next, characters do - local oldwidth = old_c.width - local oldheight = old_c.height - local olddepth = old_c.depth - if oldwidth and oldwidth > 0 then - old_c.width = oldwidth + wdelta - old_c.commands = { - { "right", hshift }, - { "char", unicode }, - } - end - if oldheight and oldheight > 0 then - old_c.height = oldheight + hdelta - end - if olddepth and olddepth > 0 then - old_c.depth = olddepth + ddelta - end - end - parameters.factor = factor - parameters.hfactor = hfactor - parameters.vfactor = vfactor - if trace_effect then - report_effect("applying effect") - report_effect(" effect : %s", effect.effect) - report_effect(" width : %s => %s", effect.width, multiplier) - report_effect(" factor : %s => %s", effect.factor, factor ) - report_effect(" hfactor : %s => %s", effect.hfactor,hfactor) - report_effect(" vfactor : %s => %s", effect.vfactor,vfactor) - report_effect(" wdelta : %s => %s", effect.wdelta, wdelta) - report_effect(" hdelta : %s => %s", effect.hdelta, hdelta) - report_effect(" ddelta : %s => %s", effect.ddelta, ddelta) - end - end -end - -local effect_specification = { - name = "effect", - description = "apply effects to glyphs", - initializers = { - base = initializeeffect, - node = initializeeffect, - }, - manipulators = { - base = manipulateeffect, - node = manipulateeffect, - }, -} - -registerotffeature(effect_specification) -registerafmfeature(effect_specification) diff --git a/tex/context/base/mkiv/font-fbk.lua b/tex/context/base/mkiv/font-fbk.lua index 79ebc3f25..122e43ddc 100644 --- a/tex/context/base/mkiv/font-fbk.lua +++ b/tex/context/base/mkiv/font-fbk.lua @@ -14,38 +14,38 @@ local next = next

This is very experimental code!

--ldx]]-- -local trace_combining_visualize = false trackers.register("fonts.composing.visualize", function(v) trace_combining_visualize = v end) -local trace_combining_define = false trackers.register("fonts.composing.define", function(v) trace_combining_define = v end) +local trace_visualize = false trackers.register("fonts.composing.visualize", function(v) trace_visualize = v end) +local trace_define = false trackers.register("fonts.composing.define", function(v) trace_define = v end) -trackers.register("fonts.combining", "fonts.composing.define") -- for old times sake (and manuals) -trackers.register("fonts.combining.all", "fonts.composing.*") -- for old times sake (and manuals) - -local report_combining = logs.reporter("fonts","combining") - -local force_combining = false -- just for demo purposes (see mk) +local report = logs.reporter("fonts","combining") local allocate = utilities.storage.allocate local fonts = fonts local handlers = fonts.handlers local constructors = fonts.constructors +local helpers = fonts.helpers local otf = handlers.otf local afm = handlers.afm local registerotffeature = otf.features.register local registerafmfeature = afm.features.register +local addotffeature = otf.addfeature + local unicodecharacters = characters.data local unicodefallbacks = characters.fallbacks -local vf = handlers.vf -local commands = vf.combiner.commands -local push = vf.predefined.push -local pop = vf.predefined.pop +local vfcommands = helpers.commands +local charcommand = vfcommands.char +local rightcommand = vfcommands.right +local downcommand = vfcommands.down +local upcommand = vfcommands.up +local push = vfcommands.push +local pop = vfcommands.pop -local force_composed = false -local cache = { } -- we could make these weak -local fraction = 0.15 -- 30 units for lucida +local force_combining = false -- just for demo purposes (see mk) +local fraction = 0.15 -- 30 units for lucida -- todo: we also need to update the feature hashes ... i'll do that when i'm in the mood -- and/or when i need it @@ -65,15 +65,15 @@ local function composecharacters(tfmdata) local italicfactor = parameters.italicfactor or 0 local vfspecials = backends.tables.vfspecials --brr local red, green, blue, black - if trace_combining_visualize then + if trace_visualize then red = vfspecials.startcolor("red") green = vfspecials.startcolor("green") blue = vfspecials.startcolor("blue") black = vfspecials.stopcolor end local compose = fonts.goodies.getcompositions(tfmdata) - if compose and trace_combining_visualize then - report_combining("using compose information from goodies file") + if compose and trace_visualize then + report("using compose information from goodies file") end local done = false for i, c in next, unicodecharacters do -- loop over all characters ... not that efficient but a specials hash takes memory @@ -105,31 +105,25 @@ local function composecharacters(tfmdata) acc = unicodefallbacks[acc] charsacc = acc and characters[acc] end - local chr_t = cache[chr] - if not chr_t then - -- chr_t = { "slot", 1, chr } - -- chr_t = { "slot", 0, chr } - chr_t = { "char", chr } - cache[chr] = chr_t - end + local chr_t = charcommand[chr] if charsacc then - if trace_combining_define then - report_combining("composed %C, base %C, accent %C",i,chr,acc) - end - local acc_t = cache[acc] - if not acc_t then - -- acc_t = { "slot", 1, acc } - -- acc_t = { "slot", 0, acc } - acc_t = { "char", acc } - cache[acc] = acc_t + if trace_define then + report("composed %C, base %C, accent %C",i,chr,acc) end + local acc_t = charcommand[acc] local cb = descriptions[chr].boundingbox local ab = descriptions[acc].boundingbox -- todo: adapt height if cb and ab then - local c_llx, c_lly, c_urx, c_ury = scale*cb[1], scale*cb[2], scale*cb[3], scale*cb[4] - local a_llx, a_lly, a_urx, a_ury = scale*ab[1], scale*ab[2], scale*ab[3], scale*ab[4] - local done = false + local c_llx = scale*cb[1] + local c_lly = scale*cb[2] + local c_urx = scale*cb[3] + local c_ury = scale*cb[4] + local a_llx = scale*ab[1] + local a_lly = scale*ab[2] + local a_urx = scale*ab[3] + local a_ury = scale*ab[4] + local done = false if compose then local i_compose = compose[i] local i_anchored = i_compose and i_compose.anchored @@ -148,26 +142,30 @@ local function composecharacters(tfmdata) local ay = a_anchor.y or 0 local dx = cx - ax local dy = cy - ay - if trace_combining_define then - report_combining("building %C from %C and %C",i,chr,acc) - report_combining(" boundingbox:") - report_combining(" chr: %3i %3i %3i %3i",unpack(cb)) - report_combining(" acc: %3i %3i %3i %3i",unpack(ab)) - report_combining(" anchors:") - report_combining(" chr: %3i %3i",cx,cy) - report_combining(" acc: %3i %3i",ax,ay) - report_combining(" delta:") - report_combining(" %s: %3i %3i",i_anchored,dx,dy) + if trace_define then + report("building %C from %C and %C",i,chr,acc) + report(" boundingbox:") + report(" chr: %3i %3i %3i %3i",unpack(cb)) + report(" acc: %3i %3i %3i %3i",unpack(ab)) + report(" anchors:") + report(" chr: %3i %3i",cx,cy) + report(" acc: %3i %3i",ax,ay) + report(" delta:") + report(" %s: %3i %3i",i_anchored,dx,dy) end - if trace_combining_visualize then - t.commands = { push, {"right", scale*dx}, {"down",-scale*dy}, green, acc_t, black, pop, chr_t } - -- t.commands = { - -- push, {"right", scale*cx}, {"down", -scale*cy}, red, {"rule",10000,10000,10000}, pop, - -- push, {"right", scale*ax}, {"down", -scale*ay}, blue, {"rule",10000,10000,10000}, pop, - -- push, {"right", scale*dx}, {"down", -scale*dy}, green, acc_t, black, pop, chr_t - -- } + local right = rightcommand[scale*dx] + local down = upcommand[scale*dy] + if trace_visualize then + t.commands = { + push, right, down, + green, acc_t, black, + pop, chr_t, + } else - t.commands = { push, {"right", scale*dx}, {"down",-scale*dy}, acc_t, pop, chr_t } + t.commands = { + push, right, down, + acc_t, pop, chr_t, + } end done = true end @@ -179,10 +177,17 @@ local function composecharacters(tfmdata) local dx = (c_urx - a_urx - a_llx + c_llx)/2 local dd = (c_urx - c_llx)*italicfactor if a_ury < 0 then - if trace_combining_visualize then - t.commands = { push, {"right", dx-dd}, red, acc_t, black, pop, chr_t } + local right = rightcommand[dx-dd] + if trace_visualize then + t.commands = { + push, right, red, acc_t, + black, pop, chr_t, + } else - t.commands = { push, {"right", dx-dd}, acc_t, pop, chr_t } + t.commands = { + push, right, acc_t, pop, + chr_t, + } end elseif c_ury > a_lly then -- messy test local dy @@ -214,27 +219,46 @@ local function composecharacters(tfmdata) else dy = - deltaxheight + extraxheight end - if trace_combining_visualize then - t.commands = { push, { "right", dx+dd }, { "down", dy }, green, acc_t, black, pop, chr_t } + local right = rightcommand[dx+dd] + local down = downcommand[dy] + if trace_visualize then + t.commands = { + push, right, down, green, + acc_t, black, pop, chr_t, + } else - t.commands = { push, { "right", dx+dd }, { "down", dy }, acc_t, pop, chr_t } + t.commands = { + push, right, down, acc_t, + pop, chr_t, + } end else - if trace_combining_visualize then - t.commands = { push, { "right", dx+dd }, blue, acc_t, black, pop, chr_t } + local right = rightcommand[dx+dd] + if trace_visualize then + t.commands = { + push, right, blue, acc_t, + black, pop, chr_t, + } else - t.commands = { push, { "right", dx+dd }, acc_t, pop, chr_t } + t.commands = { + push, right, acc_t, pop, + chr_t, + } end end end else - t.commands = { chr_t } -- else index mess + t.commands = { + chr_t, -- else index mess + } end else - if trace_combining_define then - report_combining("%C becomes simplified %C",i,chr) + if trace_define then + report("%C becomes simplified %C",i,chr) end - t.commands = { chr_t } -- else index mess + t.commands = { + chr_t, -- else index mess + } end done = true characters[i] = t @@ -254,7 +278,7 @@ local function composecharacters(tfmdata) end end -local compose_specification = { +local specification = { name = "compose", description = "additional composed characters", manipulators = { @@ -263,75 +287,71 @@ local compose_specification = { } } -registerotffeature(compose_specification) -registerafmfeature(compose_specification) +registerotffeature(specification) +registerafmfeature(specification) -vf.helpers.composecharacters = composecharacters +addotffeature { + name = "char-ligatures", + type = "ligature", + data = characters.splits.char, + order = { "char-ligatures" }, + prepend = true, +} --- This installs the builder into the regular virtual font builder, --- which only makes sense as demo. +addotffeature { + name = "compat-ligatures", + type = "ligature", + data = characters.splits.compat, + order = { "compat-ligatures" }, + prepend = true, +} -commands["compose.trace.enable"] = function() - trace_combining_visualize = true -end +registerotffeature { + name = 'char-ligatures', + description = 'unicode char specials to ligatures', +} -commands["compose.trace.disable"] = function() - trace_combining_visualize = false -end +registerotffeature { + name = 'compat-ligatures', + description = 'unicode compat specials to ligatures', +} -commands["compose.force.enable"] = function() - force_combining = true -end +do -commands["compose.force.disable"] = function() - force_combining = false -end + -- This installs the builder into the regular virtual font builder, + -- which only makes sense as demo. -commands["compose.trace.set"] = function(g,v) - if v[2] == nil then - trace_combining_visualize = true - else - trace_combining_visualize = v[2] - end -end - -commands["compose.apply"] = function(g,v) - composecharacters(g) -end + local vf = handlers.vf + local commands = vf.combiner.commands --- vf builder + vf.helpers.composecharacters = composecharacters --- { "pdf", "origin", "q " .. s .. " 0 0 " .. s .. " 0 0 cm" }, --- { "pdf", "origin", "q 1 0 0 1 " .. -w .. " " .. -h .. " cm" }, --- { "pdf", "origin", "/Fm\XX\space Do" }, --- { "pdf", "origin", "Q" }, --- { "pdf", "origin", "Q" }, + commands["compose.trace.enable"] = function() + trace_visualize = true + end --- new and experimental + commands["compose.trace.disable"] = function() + trace_visualize = false + end -local everywhere = { ["*"] = { ["*"] = true } } -- or: { ["*"] = { "*" } } -local noflags = { } + commands["compose.force.enable"] = function() + force_combining = true + end -local char_specification = { - type = "ligature", - features = everywhere, - data = characters.splits.char, - order = { "char-ligatures" }, - flags = noflags, - prepend = true, -} + commands["compose.force.disable"] = function() + force_combining = false + end -local compat_specification = { - type = "ligature", - features = everywhere, - data = characters.splits.compat, - order = { "compat-ligatures" }, - flags = noflags, - prepend = true, -} + commands["compose.trace.set"] = function(g,v) + if v[2] == nil then + trace_visualize = true + else + trace_visualize = v[2] + end + end -otf.addfeature("char-ligatures", char_specification) -- xlig (extra) -otf.addfeature("compat-ligatures",compat_specification) -- plig (pseudo) + commands["compose.apply"] = function(g,v) + composecharacters(g) + end -registerotffeature { name = 'char-ligatures', description = 'unicode char specials to ligatures' } -registerotffeature { name = 'compat-ligatures', description = 'unicode compat specials to ligatures' } +end diff --git a/tex/context/base/mkiv/font-fea.mkvi b/tex/context/base/mkiv/font-fea.mkvi index 5f65543ab..4a5356090 100644 --- a/tex/context/base/mkiv/font-fea.mkvi +++ b/tex/context/base/mkiv/font-fea.mkvi @@ -368,11 +368,19 @@ % \doifelsecurrentfonthasfeature{crap}{YES}{NO} % \doifelsecurrentfonthasfeature{kern}{YES}{NO} -\def\doifelsecurrentfonthasfeature#feature% +\def\doifelsecurrentfonthasfeature#feature% expandable {\clf_doifelsecurrentfonthasfeature{#feature}} \let\doifcurrentfonthasfeatureelse\doifelsecurrentfonthasfeature +\def\doifelsefontfeature#feature% expandable + {\clf_doifelsefontfeature{#feature}} + +\let\doiffontfeatureelse\doifelsefontfeature + +\def\doifunknownfontfeature#feature% expandable + {\clf_doifunknownfontfeature{#feature}} + % new: \clf_registerlanguagefeatures diff --git a/tex/context/base/mkiv/font-fil.mkvi b/tex/context/base/mkiv/font-fil.mkvi index 01fa4a338..16ce57f8a 100644 --- a/tex/context/base/mkiv/font-fil.mkvi +++ b/tex/context/base/mkiv/font-fil.mkvi @@ -42,19 +42,17 @@ % % \setupbodyfont[palatino] -\let\fontclass\empty - \unexpanded\def\startfontclass {\dosingleempty\font_basics_start_font_class} \def\font_basics_start_font_class[#class]% - {\pushmacro\fontclass + {\push_macro_fontclass \doifelse{#class}\v!each {\let\fontclass\empty} {\doifsomething{#class}{\def\fontclass{#class}}}} \unexpanded\def\stopfontclass - {\popmacro\fontclass} + {\pop_macro_fontclass} \def\classfont#class#name{#class#name} % \definefont[whatever][\classfont{xx}{yy} at 10pt] @@ -109,11 +107,14 @@ \let\p_designsize\undefined \expandafter\font_basics_get_font_parameter_yes#specification,]=,} +% todo: check if we can use \edef but then we need to protect \mathsizesuffix .. in fact that +% can be default then: \let\mathsizesuffix\relax .. i need to play with it first + \def\font_basics_get_font_parameter_nop#key=#value,% {\if]#key% \font_basics_get_font_parameter_nop_finish \else - \expandafter\normaldef\csname p_#key\endcsname{#value}% + \expandafter\normaldef\csname p_#key\endcsname{#value}% % no edef as we need to keep \mathsizesuffix \expandafter\font_basics_get_font_parameter_nop \fi} @@ -121,13 +122,13 @@ {\if]#key% \font_basics_get_font_parameter_yes_finish \else - \expandafter\normaldef\csname p_#key\endcsname{#value}% + \expandafter\normaldef\csname p_#key\endcsname{#value}% % no edef as we need to keep \mathsizesuffix \expandafter\font_basics_get_font_parameter_yes \fi} % helpers, some day these will be toks and counts -% \def\fntsetdefname {\global\let\somefontname\defaultfontfile} +% \def\fntsetdefname {\glet\somefontname\defaultfontfile} % \def\fntsetsomename{\gdef\somefontname} % takes argument % \def\fntsetnopsize {\let\somefontsize\empty} % \def\fntsetsomesize{\def\somefontsize} % takes argument @@ -145,10 +146,10 @@ \expandafter\let\csname\??fontfile\m_font_name\s!designsize\endcsname\undefined} \def\font_basics_define_font_synonym_yes_nil - {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\undefined - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\undefined - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\undefined - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\undefined} + {\expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\undefined + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\undefined + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\undefined + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\undefined} \def\font_basics_get_font_parameter_nop_finish {\expandafter\let\csname\??fontfile\m_font_name\s!features \endcsname\p_features @@ -157,10 +158,10 @@ \expandafter\let\csname\??fontfile\m_font_name\s!designsize\endcsname\p_designsize} \def\font_basics_get_font_parameter_yes_finish - {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\p_features - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\p_fallbacks - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\p_goodies - \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\p_designsize} + {\expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\p_features + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!fallbacks \endcsname\p_fallbacks + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\p_goodies + \expandafter\glet\csname\??fontfile\fontclass\m_font_name\s!designsize\endcsname\p_designsize} %\definefontsynonym [KopFont] [\fontclassname{officina}{SerifBold}] % @@ -306,6 +307,8 @@ #2% \fi\fi} +\installmacrostack\fontclass + %D Files or names can have properties and these need to be consulted %D at some point. They can inherit them. diff --git a/tex/context/base/mkiv/font-gbn.lua b/tex/context/base/mkiv/font-gbn.lua deleted file mode 100644 index 8f1acac65..000000000 --- a/tex/context/base/mkiv/font-gbn.lua +++ /dev/null @@ -1,262 +0,0 @@ -if not modules then modules = { } end modules ['font-gbn'] = { - version = 1.001, - comment = "companion to luatex-*.tex", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- generic [base|node] mode handler - -if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() -end - -local next = next - -local fonts = fonts -local nodes = nodes - -local nuts = nodes.nuts -- context abstraction of direct nodes - -local traverse_id = nuts.traverse_id -local flush_node = nuts.flush_node - -local glyph_code = nodes.nodecodes.glyph -local disc_code = nodes.nodecodes.disc - -local tonode = nuts.tonode -local tonut = nuts.tonut - -local getfont = nuts.getfont -local getchar = nuts.getchar -local getid = nuts.getid -local getboth = nuts.getboth -local getprev = nuts.getprev -local getnext = nuts.getnext -local getdisc = nuts.getdisc -local setchar = nuts.setchar -local setlink = nuts.setlink -local setprev = nuts.setprev - --- from now on we apply ligaturing and kerning here because it might interfere with complex --- opentype discretionary handling where the base ligature pass expect some weird extra --- pointers (which then confuse the tail slider that has some checking built in) - -local n_ligaturing = node.ligaturing -local n_kerning = node.kerning - -local ligaturing = nuts.ligaturing -local kerning = nuts.kerning - -local basemodepass = true - -local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning = nil end -local function k_warning() texio.write_nl("warning: node.kerning called directly") k_warning = nil end - -function node.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return n_ligaturing(...) -end - -function node.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return n_kerning(...) -end - -function nodes.handlers.setbasemodepass(v) - basemodepass = v -end - --------- nodes.handlers.nodepass(head) -function nodes.handlers.nodepass(head,groupcode,size,packtype,direction) - local fontdata = fonts.hashes.identifiers - if fontdata then - local nuthead = tonut(head) - local usedfonts = { } - local basefonts = { } - local prevfont = nil - local basefont = nil - local variants = nil - local redundant = nil - local nofused = 0 - for n in traverse_id(glyph_code,nuthead) do - local font = getfont(n) - if font ~= prevfont then - if basefont then - basefont[2] = getprev(n) - end - prevfont = font - local used = usedfonts[font] - if not used then - local tfmdata = fontdata[font] -- - if tfmdata then - local shared = tfmdata.shared -- we need to check shared, only when same features - if shared then - local processors = shared.processes - if processors and #processors > 0 then - usedfonts[font] = processors - nofused = nofused + 1 - elseif basemodepass then - basefont = { n, nil } - basefonts[#basefonts+1] = basefont - end - end - local resources = tfmdata.resources - variants = resources and resources.variants - variants = variants and next(variants) and variants or false - end - else - local tfmdata = fontdata[prevfont] - if tfmdata then - local resources = tfmdata.resources - variants = resources and resources.variants - variants = variants and next(variants) and variants or false - end - end - end - if variants then - local char = getchar(n) - if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) then - local hash = variants[char] - if hash then - local p = getprev(n) - if p and getid(p) == glyph_code then - local variant = hash[getchar(p)] - if variant then - setchar(p,variant) - end - end - end - -- per generic user request we always remove selectors - if not redundant then - redundant = { n } - else - redundant[#redundant+1] = n - end - end - end - end - local nofbasefonts = #basefonts - if redundant then - for i=1,#redundant do - local r = redundant[i] - local p, n = getboth(r) - if r == nuthead then - nuthead = n - setprev(n) - else - setlink(p,n) - end - if nofbasefonts > 0 then - for i=1,nofbasefonts do - local bi = basefonts[i] - if r == bi[1] then - bi[1] = n - end - if r == bi[2] then - bi[2] = n - end - end - end - flush_node(r) - end - end - for d in traverse_id(disc_code,nuthead) do - local _, _, r = getdisc(d) - if r then - for n in traverse_id(glyph_code,r) do - local font = getfont(n) - if font ~= prevfont then - prevfont = font - local used = usedfonts[font] - if not used then - local tfmdata = fontdata[font] -- - if tfmdata then - local shared = tfmdata.shared -- we need to check shared, only when same features - if shared then - local processors = shared.processes - if processors and #processors > 0 then - usedfonts[font] = processors - nofused = nofused + 1 - end - end - end - end - end - end - end - end - if next(usedfonts) then - for font, processors in next, usedfonts do - for i=1,#processors do - head = processors[i](head,font,0,direction,nofused) or head - end - end - end - if basemodepass and nofbasefonts > 0 then - for i=1,nofbasefonts do - local range = basefonts[i] - local start = range[1] - local stop = range[2] - if start then - local front = nuthead == start - local prev, next - if stop then - next = getnext(stop) - start, stop = ligaturing(start,stop) - start, stop = kerning(start,stop) - else - prev = getprev(start) - start = ligaturing(start) - start = kerning(start) - end - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) - end - if front and nuthead ~= start then - head = tonode(start) - end - end - end - end - return head, true - else - return head, false - end -end - -function nodes.handlers.basepass(head) - if basemodepass then - head = n_ligaturing(head) - head = n_kerning(head) - end - return head, true -end - -local nodepass = nodes.handlers.nodepass -local basepass = nodes.handlers.basepass -local injectpass = nodes.injections.handler -local protectpass = nodes.handlers.protectglyphs - -function nodes.simple_font_handler(head,groupcode,size,packtype,direction) - if head then - head = nodepass(head,groupcode,size,packtype,direction) - head = injectpass(head) - if not basemodepass then - head = basepass(head) - end - protectpass(head) - return head, true - else - return head, false - end -end diff --git a/tex/context/base/mkiv/font-gds.mkvi b/tex/context/base/mkiv/font-gds.mkvi index 549ede46f..05cf08790 100644 --- a/tex/context/base/mkiv/font-gds.mkvi +++ b/tex/context/base/mkiv/font-gds.mkvi @@ -62,7 +62,7 @@ % % \definedfont[husayni*husayni-colored at 36pt] % -% \starttext \pardir TRT \textdir TRT +% \starttext \righttoleft % % \setfontcolorscheme[1] % diff --git a/tex/context/base/mkiv/font-hsh.lua b/tex/context/base/mkiv/font-hsh.lua index 60a27c043..8d1e85145 100644 --- a/tex/context/base/mkiv/font-hsh.lua +++ b/tex/context/base/mkiv/font-hsh.lua @@ -18,48 +18,50 @@ fonts.hashes = hashes -- todo: autoallocate ... just create on the fly .. use constructors.keys (problem: plurals) -local identifiers = hashes.identifiers or allocate() -local characters = hashes.characters or allocate() -- chardata -local descriptions = hashes.descriptions or allocate() -local parameters = hashes.parameters or allocate() -local properties = hashes.properties or allocate() -local resources = hashes.resources or allocate() -local spacings = hashes.spacings or allocate() -local spaces = hashes.spaces or allocate() -local quads = hashes.quads or allocate() -- maybe also spacedata -local xheights = hashes.xheights or allocate() -local csnames = hashes.csnames or allocate() -- namedata -local features = hashes.features or allocate() -local marks = hashes.marks or allocate() -local classes = hashes.classes or allocate() -local italics = hashes.italics or allocate() -local lastmathids = hashes.lastmathids or allocate() -local dynamics = hashes.dynamics or allocate() -local unicodes = hashes.unicodes or allocate() -local originals = hashes.originals or allocate() -local modes = hashes.modes or allocate() -local variants = hashes.variants or allocate() - -hashes.characters = characters -hashes.descriptions = descriptions -hashes.parameters = parameters -hashes.properties = properties -hashes.resources = resources -hashes.spacings = spacings -hashes.spaces = spaces -hashes.quads = quads hashes.emwidths = quads -hashes.xheights = xheights hashes.exheights = xheights -hashes.csnames = csnames -hashes.features = features -hashes.marks = marks -hashes.classes = classes -hashes.italics = italics -hashes.lastmathids = lastmathids -hashes.dynamics = dynamics -hashes.unicodes = unicodes -hashes.originals = originals -hashes.modes = modes -hashes.variants = variants +local identifiers = hashes.identifiers or allocate() +local characters = hashes.characters or allocate() -- chardata +local descriptions = hashes.descriptions or allocate() +local parameters = hashes.parameters or allocate() +local mathparameters = hashes.mathparameters or allocate() +local properties = hashes.properties or allocate() +local resources = hashes.resources or allocate() +local spacings = hashes.spacings or allocate() +local spaces = hashes.spaces or allocate() +local quads = hashes.quads or allocate() -- maybe also spacedata +local xheights = hashes.xheights or allocate() +local csnames = hashes.csnames or allocate() -- namedata +local features = hashes.features or allocate() +local marks = hashes.marks or allocate() +local classes = hashes.classes or allocate() +local italics = hashes.italics or allocate() +local lastmathids = hashes.lastmathids or allocate() +local dynamics = hashes.dynamics or allocate() +local unicodes = hashes.unicodes or allocate() +local originals = hashes.originals or allocate() +local modes = hashes.modes or allocate() +local variants = hashes.variants or allocate() + +hashes.characters = characters +hashes.descriptions = descriptions +hashes.parameters = parameters +hashes.mathparameters = mathparameters +hashes.properties = properties +hashes.resources = resources +hashes.spacings = spacings +hashes.spaces = spaces +hashes.quads = quads hashes.emwidths = quads +hashes.xheights = xheights hashes.exheights = xheights +hashes.csnames = csnames +hashes.features = features +hashes.marks = marks +hashes.classes = classes +hashes.italics = italics +hashes.lastmathids = lastmathids +hashes.dynamics = dynamics +hashes.unicodes = unicodes +hashes.originals = originals +hashes.modes = modes +hashes.variants = variants local nodepool = nodes and nodes.pool local dummyglyph = nodepool and nodepool.register(nodepool.glyph()) @@ -68,7 +70,9 @@ local nulldata = allocate { name = "nullfont", characters = { }, descriptions = { }, - properties = { }, + properties = { + designsize = 786432, + }, parameters = { -- lmromanregular @ 12pt slantperpoint = 0, spacing = { @@ -87,6 +91,7 @@ local nulldata = allocate { x_height = 338952, -- 5 quad = 786432, -- 6 extra_space = 85459, -- 7 + size = 786432, }, } @@ -148,6 +153,16 @@ setmetatableindex(parameters, function(t,k) end end) +setmetatableindex(mathparameters, function(t,k) + if k == true then + return mathparameters[currentfont()] + else + local mathparameters = identifiers[k].mathparameters + t[k] = mathparameters + return mathparameters + end +end) + setmetatableindex(properties, function(t,k) if k == true then return properties[currentfont()] diff --git a/tex/context/base/mkiv/font-imp-dimensions.lua b/tex/context/base/mkiv/font-imp-dimensions.lua new file mode 100644 index 000000000..a7125625d --- /dev/null +++ b/tex/context/base/mkiv/font-imp-dimensions.lua @@ -0,0 +1,115 @@ +if not modules then modules = { } end modules ['font-imp-dimensions'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber + +local fonts = fonts +local utilities = utilities + +local helpers = fonts.helpers +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char +local rightcommand = helpers.commands.right + +local handlers = fonts.handlers +local otf = handlers.otf +local afm = handlers.afm + +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local settings_to_array = utilities.parsers.settings_to_array +local gettexdimen = tex.getdimen + +-- For Wolfgang Schuster: +-- +-- \definefontfeature[thisway][default][script=hang,language=zhs,dimensions={2,2,2}] +-- \definedfont[file:kozminpr6nregular*thisway] + +local function initialize(tfmdata,key,value) + if type(value) == "string" and value ~= "" then + local characters = tfmdata.characters + local parameters = tfmdata.parameters + local emwidth = parameters.quad + local exheight = parameters.xheight + local newwidth = false + local newheight = false + local newdepth = false + if value == "strut" then + newheight = gettexdimen("strutht") + newdepth = gettexdimen("strutdp") + elseif value == "mono" then + newwidth = emwidth + else + local spec = settings_to_array(value) + newwidth = tonumber(spec[1]) + newheight = tonumber(spec[2]) + newdepth = tonumber(spec[3]) + if newwidth then newwidth = newwidth * emwidth end + if newheight then newheight = newheight * exheight end + if newdepth then newdepth = newdepth * exheight end + end + if newwidth or newheight or newdepth then + for unicode, character in next, characters do + local oldwidth = character.width + local oldheight = character.height + local olddepth = character.depth + local width = newwidth or oldwidth or 0 + local height = newheight or oldheight or 0 + local depth = newdepth or olddepth or 0 + if oldwidth ~= width or oldheight ~= height or olddepth ~= depth then + character.width = width + character.height = height + character.depth = depth + if oldwidth ~= width then + local commands = character.commands + local hshift = rightcommand[(width - oldwidth) / 2] + if commands then + character.commands = prependcommands ( + commands, + hshift + ) + else + character.commands = { + hshift, + charcommand[unicode], + } + end + end + end + end + end + end +end + +local specification = { + name = "dimensions", + description = "force dimensions", + manipulators = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initialize(tfmdata,value) + tfmdata.properties.realdimensions = value and true +end + +registerotffeature { + name = "realdimensions", + description = "accept negative dimenions", + initializers = { + base = initialize, + node = initialize, + } +} diff --git a/tex/context/base/mkiv/font-imp-effects.lua b/tex/context/base/mkiv/font-imp-effects.lua new file mode 100644 index 000000000..cc6e4c0bf --- /dev/null +++ b/tex/context/base/mkiv/font-imp-effects.lua @@ -0,0 +1,414 @@ +if not modules then modules = { } end modules ['font-imp-effects'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: pickup from goodies: if type(effect) then ... + +local next, type, tonumber = next, type, tonumber +local is_boolean = string.is_boolean + +local fonts = fonts + +local handlers = fonts.handlers +local registerotffeature = handlers.otf.features.register +local registerafmfeature = handlers.afm.features.register + +local settings_to_hash = utilities.parsers.settings_to_hash_colon_too + +local helpers = fonts.helpers +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char +local leftcommand = helpers.commands.left +local rightcommand = helpers.commands.right +local upcommand = helpers.commands.up +local downcommand = helpers.commands.down +local dummycommand = helpers.commands.dummy + +----- constructors = fonts.constructors +----- getmathparameter = constructors.getmathparameter +----- setmathparameter = constructors.setmathparameter + +local report_effect = logs.reporter("fonts","effect") +local report_slant = logs.reporter("fonts","slant") +local report_extend = logs.reporter("fonts","extend") +local report_squeeze = logs.reporter("fonts","squeeze") + +local trace = false + +trackers.register("fonts.effect", function(v) trace = v end) +trackers.register("fonts.slant", function(v) trace = v end) +trackers.register("fonts.extend", function(v) trace = v end) +trackers.register("fonts.squeeze",function(v) trace = v end) + +local function initializeslant(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 1 then + value = 1 + elseif value < -1 then + value = -1 + end + if trace then + report_slant("applying %0.3f",value) + end + tfmdata.parameters.slantfactor = value +end + +local specification = { + name = "slant", + description = "slant glyphs", + initializers = { + base = initializeslant, + node = initializeslant, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initializeextend(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 10 then + value = 10 + elseif value < -10 then + value = -10 + end + if trace then + report_extend("applying %0.3f",value) + end + tfmdata.parameters.extendfactor = value +end + +local specification = { + name = "extend", + description = "scale glyphs horizontally", + initializers = { + base = initializeextend, + node = initializeextend, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initializesqueeze(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + elseif value > 10 then + value = 10 + elseif value < -10 then + value = -10 + end + if trace then + report_squeeze("applying %0.3f",value) + end + tfmdata.parameters.squeezefactor = value +end + +local specification = { + name = "squeeze", + description = "scale glyphs vertically", + initializers = { + base = initializesqueeze, + node = initializesqueeze, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local effects = { + inner = 0, + normal = 0, + outer = 1, + outline = 1, + both = 2, + hidden = 3, +} + +local function initializeeffect(tfmdata,value) + local spec + if type(value) == "number" then + spec = { width = value } + else + spec = settings_to_hash(value) + end + local effect = spec.effect or "both" + local width = tonumber(spec.width) or 0 + local mode = effects[effect] + if not mode then + report_effect("invalid effect %a",effect) + elseif width == 0 and mode == 0 then + report_effect("invalid width %a for effect %a",width,effect) + else + local parameters = tfmdata.parameters + local properties = tfmdata.properties + parameters.mode = mode + parameters.width = width * 1000 + if is_boolean(spec.auto) == true then + local squeeze = 1 - width/20 + local average = (1 - squeeze) * width * 100 + spec.squeeze = squeeze + spec.extend = 1 + width/2 + spec.wdelta = average + spec.hdelta = average/2 + spec.ddelta = average/2 + spec.vshift = average/2 + end + local factor = tonumber(spec.factor) or 0 + local hfactor = tonumber(spec.hfactor) or factor + local vfactor = tonumber(spec.vfactor) or factor + local delta = tonumber(spec.delta) or 1 + local wdelta = tonumber(spec.wdelta) or delta + local hdelta = tonumber(spec.hdelta) or delta + local ddelta = tonumber(spec.ddelta) or hdelta + local vshift = tonumber(spec.vshift) or 0 + local slant = spec.slant + local extend = spec.extend + local squeeze = spec.squeeze + if slant then + initializeslant(tfmdata,slant) + end + if extend then + initializeextend(tfmdata,extend) + end + if squeeze then + initializesqueeze(tfmdata,squeeze) + end + properties.effect = { + effect = effect, + width = width, + factor = factor, + hfactor = hfactor, + vfactor = vfactor, + wdelta = wdelta, + hdelta = hdelta, + ddelta = ddelta, + vshift = vshift, + slant = tfmdata.parameters.slantfactor, + extend = tfmdata.parameters.extendfactor, + squeeze = tfmdata.parameters.squeezefactor, + } + end +end + +local rules = { + "RadicalRuleThickness", + "OverbarRuleThickness", + "FractionRuleThickness", + "UnderbarRuleThickness", +} + +-- local commands = char.commands +-- if commands then +-- local command = commands[1] +-- if command and command[1] == "right" then +-- commands[1] = rightcommand[command[2]-snap] +-- end +-- end + +local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + if delta ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dx) + end + end + end +end + +local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + + local function wdpatch(char) + if wsnap ~= 0 then + char.width = char.width + wdelta/2 + end + end + + local function htpatch(char) + if hsnap ~= 0 then + local height = char.height + if height then + char.height = char.height + 2 * dy + end + end + end + + local character = characters[0x221A] + + if character and character.next then +-- print("base char",0x221A,table.sequenced(character)) + local char = character + local next = character.next + wdpatch(char) + htpatch(char) + while next do + char = characters[next] + wdpatch(char) + htpatch(char) +-- print("next char",next,table.sequenced(char)) + next = char.next + end + if char then + local v = char.vert_variants + if v then + local top = v[#v] + if top then + local char = characters[top.glyph] +-- print("top char",top.glyph,table.sequenced(char)) + htpatch(char) + end + end + end + end +end + +-- local show_effect = { "lua", function(f,c) +-- report_effect("font id %i, char %C",f,c) +-- inspect(fonts.hashes.characters[f][c]) +-- end } + +-- local show_effect = { "lua", "print('!')" } + +local function manipulateeffect(tfmdata) + local effect = tfmdata.properties.effect + if effect then + local characters = tfmdata.characters + local parameters = tfmdata.parameters + local mathparameters = tfmdata.mathparameters + local multiplier = effect.width * 100 + local factor = parameters.factor + local hfactor = parameters.hfactor + local vfactor = parameters.vfactor + local wdelta = effect.wdelta * hfactor * multiplier + local hdelta = effect.hdelta * vfactor * multiplier + local ddelta = effect.ddelta * vfactor * multiplier + local vshift = effect.vshift * vfactor * multiplier + local squeeze = effect.squeeze + local hshift = wdelta / 2 + local dx = multiplier * vfactor + local dy = vshift + local factor = (1 + effect.factor) * factor + local hfactor = (1 + effect.hfactor) * hfactor + local vfactor = (1 + effect.vfactor) * vfactor + local vshift = vshift ~= 0 and upcommand[vshift] or false + for unicode, character in next, characters do + local oldwidth = character.width + local oldheight = character.height + local olddepth = character.depth + if oldwidth and oldwidth > 0 then + character.width = oldwidth + wdelta + local commands = character.commands + local hshift = rightcommand[hshift] + if vshift then + if commands then + prependcommands ( commands, +-- show_effect, + hshift, + vshift + ) + else + character.commands = { +-- show_effect, + hshift, + vshift, + charcommand[unicode] + } + end + else + if commands then + prependcommands ( commands, +-- show_effect, + hshift + ) + else + character.commands = { +-- show_effect, + hshift, + charcommand[unicode] + } + end + end + end + if oldheight and oldheight > 0 then + character.height = oldheight + hdelta + end + if olddepth and olddepth > 0 then + character.depth = olddepth + ddelta + end + end + if mathparameters then + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + end + parameters.factor = factor + parameters.hfactor = hfactor + parameters.vfactor = vfactor + if trace then + report_effect("applying") + report_effect(" effect : %s", effect.effect) + report_effect(" width : %s => %s", effect.width, multiplier) + report_effect(" factor : %s => %s", effect.factor, factor ) + report_effect(" hfactor : %s => %s", effect.hfactor,hfactor) + report_effect(" vfactor : %s => %s", effect.vfactor,vfactor) + report_effect(" wdelta : %s => %s", effect.wdelta, wdelta) + report_effect(" hdelta : %s => %s", effect.hdelta, hdelta) + report_effect(" ddelta : %s => %s", effect.ddelta, ddelta) + end + end +end + +local specification = { + name = "effect", + description = "apply effects to glyphs", + initializers = { + base = initializeeffect, + node = initializeeffect, + }, + manipulators = { + base = manipulateeffect, + node = manipulateeffect, + }, +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initializeoutline(tfmdata,value) + value = tonumber(value) + if not value then + value = 0 + else + value = tonumber(value) or 0 + end + local parameters = tfmdata.parameters + local properties = tfmdata.properties + parameters.mode = effects.outline + parameters.width = value * 1000 + properties.effect = { + effect = effect, + width = width, + } +end + +local specification = { + name = "outline", + description = "outline glyphs", + initializers = { + base = initializeoutline, + node = initializeoutline, + } +} + +registerotffeature(specification) +registerafmfeature(specification) diff --git a/tex/context/base/mkiv/font-imp-italics.lua b/tex/context/base/mkiv/font-imp-italics.lua new file mode 100644 index 000000000..83c785d38 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-italics.lua @@ -0,0 +1,147 @@ +if not modules then modules = { } end modules ['font-imp-italics'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next + +local fonts = fonts +local handlers = fonts.handlers +local registerotffeature = handlers.otf.features.register +local registerafmfeature = handlers.afm.features.register + +local function initialize(tfmdata,key,value) + for unicode, character in next, tfmdata.characters do + local olditalic = character.italic + if olditalic and olditalic ~= 0 then + character.width = character.width + olditalic + character.italic = 0 + end + end +end + +local specification = { + name = "italicwidths", + description = "add italic to width", + manipulators = { + base = initialize, + node = initialize, -- only makes sense for math + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local function initialize(tfmdata,value) -- hm, always value + if value then + -- the magic 40 and it formula come from Dohyun Kim but we might need another guess + local parameters = tfmdata.parameters + local italicangle = parameters.italicangle + if italicangle and italicangle ~= 0 then + local properties = tfmdata.properties + local factor = tonumber(value) or 1 + properties.hasitalics = true + properties.autoitalicamount = factor * (parameters.uwidth or 40)/2 + end + end +end + +local specification = { + name = "itlc", + description = "italic correction", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +if context then + + local function initialize(tfmdata,value) -- yes no delay + tfmdata.properties.textitalics = toboolean(value) + end + + local specification = { + name = "textitalics", + description = "use alternative text italic correction", + initializers = { + base = initialize, + node = initialize, + } + } + + registerotffeature(specification) + registerafmfeature(specification) + +end + +-- no longer used + +-- if context then +-- +-- -- local function initializemathitalics(tfmdata,value) -- yes no delay +-- -- tfmdata.properties.mathitalics = toboolean(value) +-- -- end +-- -- +-- -- local specification = { +-- -- name = "mathitalics", +-- -- description = "use alternative math italic correction", +-- -- initializers = { +-- -- base = initializemathitalics, +-- -- node = initializemathitalics, +-- -- } +-- -- } +-- -- +-- -- registerotffeature(specification) +-- -- registerafmfeature(specification) +-- +-- end + +-- -- also not used, only when testing + +if context then + + local letter = characters.is_letter + local always = true + + local function collapseitalics(tfmdata,key,value) + local threshold = value == true and 100 or tonumber(value) + if threshold and threshold > 0 then + if threshold > 100 then + threshold = 100 + end + for unicode, data in next, tfmdata.characters do + if always or letter[unicode] or letter[data.unicode] then + local italic = data.italic + if italic and italic ~= 0 then + local width = data.width + if width and width ~= 0 then + local delta = threshold * italic / 100 + data.width = width + delta + data.italic = italic - delta + end + end + end + end + end + end + + local dimensions_specification = { + name = "collapseitalics", + description = "collapse italics", + manipulators = { + base = collapseitalics, + node = collapseitalics, + } + } + + registerotffeature(dimensions_specification) + registerafmfeature(dimensions_specification) + +end diff --git a/tex/context/base/mkiv/font-imp-ligatures.lua b/tex/context/base/mkiv/font-imp-ligatures.lua new file mode 100644 index 000000000..091eb5d4b --- /dev/null +++ b/tex/context/base/mkiv/font-imp-ligatures.lua @@ -0,0 +1,136 @@ +if not modules then modules = { } end modules ['font-imp-ligatures'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local lpegmatch = lpeg.match +local utfsplit = utf.split +local settings_to_array = utilities.parsers.settings_to_array + +local fonts = fonts +local otf = fonts.handlers.otf +local registerotffeature = otf.features.register +local addotffeature = otf.addfeature + +-- This is a quick and dirty hack. + +local lookups = { } +local protect = { } +local revert = { } +local zwjchar = 0x200C +local zwj = { zwjchar } + +addotffeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + prepend = true, -- make sure we do it early + future = true, -- avoid nilling due to no steps yet + lookups = { + { + type = "multiple", + data = lookups, + }, + }, + data = { + rules = protect, + } +} + +addotffeature { + name = "blockligatures", + type = "chainsubstitution", + nocheck = true, -- because there is no 0x200C in the font + append = true, -- this is done late + overload = false, -- we don't want to overload the previous definition + lookups = { + { + type = "ligature", + data = lookups, + }, + }, + data = { + rules = revert, + } +} + +registerotffeature { + name = 'blockligatures', + description = 'block certain ligatures', +} + +local splitter = lpeg.splitat(":") + +local function blockligatures(str) + + local t = settings_to_array(str) + + for i=1,#t do + local ti = t[i] + local before, current, after = lpegmatch(splitter,ti) + if current and after then -- before is returned when no match + -- experimental joke + if before then + before = utfsplit(before) + for i=1,#before do + before[i] = { before[i] } + end + end + if current then + current = utfsplit(current) + end + if after then + after = utfsplit(after) + for i=1,#after do + after[i] = { after[i] } + end + end + else + before = nil + current = utfsplit(ti) + after = nil + end + if #current > 1 then + local one = current[1] + local two = current[2] + lookups[one] = { one, zwjchar } + local one = { one } + local two = { two } + local new = #protect + 1 + protect[new] = { + before = before, + current = { one, two }, + after = after, + lookups = { 1 }, -- not shared ! + } + revert[new] = { + -- before = before, + current = { one, zwj }, + -- after = { two, unpack(after) }, + after = { two }, + lookups = { 1 }, -- not shared ! + } + end + end +end + +-- blockligatures("\0\0") + +otf.helpers.blockligatures = blockligatures + +-- blockligatures("fi,ff") +-- blockligatures("fl") +-- blockligatures("u:fl:age") + +if context then + + interfaces.implement { + name = "blockligatures", + arguments = "string", + actions = blockligatures, + } + +end diff --git a/tex/context/base/mkiv/font-imp-math.lua b/tex/context/base/mkiv/font-imp-math.lua new file mode 100644 index 000000000..d93ece405 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-math.lua @@ -0,0 +1,81 @@ +if not modules then modules = { } end modules ['font-imp-math'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber + +local fonts = fonts +local helpers = fonts.helpers +local registerotffeature = fonts.handlers.otf.features.register + +local setmetatableindex = table.setmetatableindex + +-- requested for latex but not supported unless really needed in context: +-- +-- registerotffeature { +-- name = "ignoremathconstants", +-- description = "ignore math constants table", +-- initializers = { +-- base = function(tfmdata,value) +-- if value then +-- tfmdata.mathparameters = nil +-- end +-- end +-- } +-- } + +-- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0 + +local splitter = lpeg.splitat(",",tonumber) +local lpegmatch = lpeg.match + +local function initialize(tfmdata,value) + local mathparameters = tfmdata.mathparameters + if mathparameters then + local sup, sub + if type(value) == "string" then + sup, sub = lpegmatch(splitter,value) + if not sup then + sub, sup = 0, 0 + elseif not sub then + sub, sup = sup, 0 + end + elseif type(value) == "number" then + sup, sub = 0, value + end + if sup then + mathparameters.NoLimitSupFactor = sup + end + if sub then + mathparameters.NoLimitSubFactor = sub + end + end +end + +registerotffeature { + name = "mathnolimitsmode", + description = "influence nolimits placement", + initializers = { + base = initialize, + node = initialize, + } +} + +local function initialize(tfmdata,value) + tfmdata.properties.nostackmath = value and true +end + +registerotffeature { + name = "nostackmath", + description = "disable math stacking mechanism", + initializers = { + base = initialize, + node = initialize, + } +} diff --git a/tex/context/base/mkiv/font-imp-notused.lua b/tex/context/base/mkiv/font-imp-notused.lua new file mode 100644 index 000000000..be36c9898 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-notused.lua @@ -0,0 +1,168 @@ +if not modules then modules = { } end modules ['font-imp-notused'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +-- local next = next +-- local utfbyte = utf.byte +-- +-- local fonts = fonts +-- +-- local handlers = fonts.handlers +-- local otf = handlers.otf +-- local afm = handlers.afm +-- +-- local registerotffeature = otf.features.register +-- local registerafmfeature = afm.features.register + +-- local function initialize(tfmdata) +-- local resources = tfmdata.resources +-- local gposfeatures = resources.features.gpos +-- local characters = tfmdata.characters +-- local descriptions = tfmdata.descriptions +-- local sequences = resources.sequences +-- local coverage = { } +-- local units = tfmdata.shared.rawdata.metadata.units +-- for k, v in next, characters do +-- local w = descriptions[k].width +-- local d = units - w +-- coverage[k] = { -d/2, 0, units, 0 } +-- end +-- local f = { dflt = { dflt = true } } +-- local s = #sequences + 1 +-- local t = { +-- features = { fakemono = f }, +-- flags = { false, false, false, false }, +-- index = s, +-- name = "p_s_" .. s, +-- nofsteps = 1, +-- order = { "fakemono" }, +-- skiphash = false, +-- type = "gpos_single", +-- steps = { +-- { +-- format = "single", +-- coverage = coverage, +-- } +-- } +-- } +-- gposfeatures["fakemono"] = f +-- sequences[s] = t +-- end +-- +-- registerotffeature { +-- name = "fakemono", +-- description = "fake monospaced", +-- initializers = { +-- node = initialize, +-- }, +-- } + +-- -- for notosans but not general +-- +-- local v_local = interfaces and interfaces.variables and interfaces.variables["local"] or "local" +-- +-- local function initialize(tfmdata,key,value) +-- local characters = tfmdata.characters +-- local parameters = tfmdata.parameters +-- local oldchar = 32 +-- local newchar = 32 +-- if value == "locl" or value == v_local then +-- newchar = fonts.handlers.otf.getsubstitution(tfmdata,oldchar,"locl",true) or oldchar +-- elseif value == true then +-- -- use normal space +-- elseif value then +-- newchar = utfbyte(value) +-- else +-- return +-- end +-- local newchar = newchar and characters[newchar] +-- local newspace = newchar and newchar.width +-- if newspace > 0 then +-- parameters.space = newspace +-- parameters.space_stretch = newspace/2 +-- parameters.space_shrink = newspace/3 +-- parameters.extra_space = parameters.space_shrink +-- end +-- end +-- +-- registerotffeature { +-- name = 'space', -- true|false|locl|character +-- description = 'space settings', +-- manipulators = { +-- base = initialize, +-- node = initialize, +-- } +-- } + +-- -- historic stuff, move from font-ota (handled differently, typo-rep) +-- +-- local delete_node = nodes.delete +-- local fontdata = fonts.hashes.identifiers +-- +-- local nodecodes = nodes.nodecodes +-- local glyph_code = nodecodes.glyph +-- +-- local strippables = allocate() +-- fonts.strippables = strippables +-- +-- strippables.joiners = table.tohash { +-- 0x200C, -- zwnj +-- 0x200D, -- zwj +-- } +-- +-- strippables.all = table.tohash { +-- 0x000AD, 0x017B4, 0x017B5, 0x0200B, 0x0200C, 0x0200D, 0x0200E, 0x0200F, 0x0202A, 0x0202B, +-- 0x0202C, 0x0202D, 0x0202E, 0x02060, 0x02061, 0x02062, 0x02063, 0x0206A, 0x0206B, 0x0206C, +-- 0x0206D, 0x0206E, 0x0206F, 0x0FEFF, 0x1D173, 0x1D174, 0x1D175, 0x1D176, 0x1D177, 0x1D178, +-- 0x1D179, 0x1D17A, 0xE0001, 0xE0020, 0xE0021, 0xE0022, 0xE0023, 0xE0024, 0xE0025, 0xE0026, +-- 0xE0027, 0xE0028, 0xE0029, 0xE002A, 0xE002B, 0xE002C, 0xE002D, 0xE002E, 0xE002F, 0xE0030, +-- 0xE0031, 0xE0032, 0xE0033, 0xE0034, 0xE0035, 0xE0036, 0xE0037, 0xE0038, 0xE0039, 0xE003A, +-- 0xE003B, 0xE003C, 0xE003D, 0xE003E, 0xE003F, 0xE0040, 0xE0041, 0xE0042, 0xE0043, 0xE0044, +-- 0xE0045, 0xE0046, 0xE0047, 0xE0048, 0xE0049, 0xE004A, 0xE004B, 0xE004C, 0xE004D, 0xE004E, +-- 0xE004F, 0xE0050, 0xE0051, 0xE0052, 0xE0053, 0xE0054, 0xE0055, 0xE0056, 0xE0057, 0xE0058, +-- 0xE0059, 0xE005A, 0xE005B, 0xE005C, 0xE005D, 0xE005E, 0xE005F, 0xE0060, 0xE0061, 0xE0062, +-- 0xE0063, 0xE0064, 0xE0065, 0xE0066, 0xE0067, 0xE0068, 0xE0069, 0xE006A, 0xE006B, 0xE006C, +-- 0xE006D, 0xE006E, 0xE006F, 0xE0070, 0xE0071, 0xE0072, 0xE0073, 0xE0074, 0xE0075, 0xE0076, +-- 0xE0077, 0xE0078, 0xE0079, 0xE007A, 0xE007B, 0xE007C, 0xE007D, 0xE007E, 0xE007F, +-- } +-- +-- strippables[true] = strippables.joiners +-- +-- local function processformatters(head,font) +-- local subset = fontdata[font].shared.features.formatters +-- local vector = subset and strippables[subset] +-- if vector then +-- local current, done = head, false +-- while current do +-- if current.id == glyph_code and current.subtype<256 and current.font == font then +-- local char = current.char +-- if vector[char] then +-- head, current = delete_node(head,current) +-- done = true +-- else +-- current = current.next +-- end +-- else +-- current = current.next +-- end +-- end +-- return head, done +-- else +-- return head, false +-- end +-- end +-- +-- registerotffeature { +-- name = "formatters", +-- description = "hide formatting characters", +-- methods = { +-- base = processformatters, +-- node = processformatters, +-- } +-- } diff --git a/tex/context/base/mkiv/font-imp-properties.lua b/tex/context/base/mkiv/font-imp-properties.lua new file mode 100644 index 000000000..5805235b7 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-properties.lua @@ -0,0 +1,130 @@ +if not modules then modules = { } end modules ['font-imp-properties'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber, select = next, type, tonumber, select +local byte, find, formatters = string.byte, string.find, string.formatters +local utfchar = utf.char +local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort +local insert = table.insert + +local context = context +local fonts = fonts +local utilities = utilities + +local helpers = fonts.helpers + +local handlers = fonts.handlers +local hashes = fonts.hashes +local otf = handlers.otf +local afm = handlers.afm + +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local fontdata = hashes.identifiers +local fontproperties = hashes.properties + +local constructors = fonts.constructors +local getprivate = constructors.getprivate + +local allocate = utilities.storage.allocate +local family_font = node.family_font + +local setmetatableindex = table.setmetatableindex + +local implement = interfaces.implement + +do + + local P, lpegpatterns, lpegmatch = lpeg.P, lpeg.patterns, lpeg.match + + local amount, stretch, shrink, extra + + local factor = lpegpatterns.unsigned + local space = lpegpatterns.space + local pattern = ( + (factor / function(n) amount = tonumber(n) or amount end) + + (P("+") + P("plus" )) * space^0 * (factor / function(n) stretch = tonumber(n) or stretch end) + + (P("-") + P("minus")) * space^0 * (factor / function(n) shrink = tonumber(n) or shrink end) + + ( P("extra")) * space^0 * (factor / function(n) extra = tonumber(n) or extra end) + + space^1 + )^1 + + local function initialize(tfmdata,key,value) + local characters = tfmdata.characters + local parameters = tfmdata.parameters + if type(value) == "string" then + local emwidth = parameters.quad + amount, stretch, shrink, extra = 0, 0, 0, false + lpegmatch(pattern,value) + if not extra then + if shrink ~= 0 then + extra = shrink + elseif stretch ~= 0 then + extra = stretch + else + extra = amount + end + end + parameters.space = amount * emwidth + parameters.space_stretch = stretch * emwidth + parameters.space_shrink = shrink * emwidth + parameters.extra_space = extra * emwidth + end + end + + -- 1.1 + 1.2 - 1.3 minus 1.4 plus 1.1 extra 1.4 -- last one wins + + registerotffeature { + name = "spacing", + description = "space settings", + manipulators = { + base = initialize, + node = initialize, + } + } + +end + +do + + local function initialize(tfmdata,value) + local properties = tfmdata.properties + if properties then + properties.identity = value == "vertical" and "vertical" or "horizontal" + end + end + + registerotffeature { + name = "identity", + description = "set font identity", + initializers = { + base = initialize, + node = initialize, + } + } + + local function initialize(tfmdata,value) + local properties = tfmdata.properties + if properties then + properties.writingmode = value == "vertical" and "vertical" or "horizontal" + end + end + + registerotffeature { + name = "writingmode", + description = "set font direction", + initializers = { + base = initialize, + node = initialize, + } + } + +end diff --git a/tex/context/base/mkiv/font-imp-quality.lua b/tex/context/base/mkiv/font-imp-quality.lua new file mode 100644 index 000000000..01f0afe63 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-quality.lua @@ -0,0 +1,527 @@ +if not modules then modules = { } end modules ['font-imp-quality'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type, tonumber = next, type, tonumber +local byte = string.byte +local insert = table.insert + +local fonts = fonts +local utilities = utilities + +local handlers = fonts.handlers +local otf = handlers.otf +local afm = handlers.afm +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register + +local allocate = utilities.storage.allocate +local getparameters = utilities.parsers.getparameters + +local implement = interfaces and interfaces.implement + +local trace_protrusion = false trackers.register("fonts.protrusion", function(v) trace_protrusion = v end) +local trace_expansion = false trackers.register("fonts.expansion", function(v) trace_expansion = v end) + +local report_expansions = logs.reporter("fonts","expansions") +local report_protrusions = logs.reporter("fonts","protrusions") + +-- -- -- -- -- -- +-- shared +-- -- -- -- -- -- + +local function get_class_and_vector(tfmdata,value,where) -- "expansions" + local g_where = tfmdata.goodies and tfmdata.goodies[where] + local f_where = fonts[where] + local g_classes = g_where and g_where.classes + local f_classes = f_where and f_where.classes + local class = (g_classes and g_classes[value]) or (f_classes and f_classes[value]) + if class then + local class_vector = class.vector + local g_vectors = g_where and g_where.vectors + local f_vectors = f_where and f_where.vectors + local vector = (g_vectors and g_vectors[class_vector]) or (f_vectors and f_vectors[class_vector]) + return class, vector + end +end + +-- -- -- -- -- -- +-- expansion (hz) +-- -- -- -- -- -- + +local expansions = fonts.expansions or allocate() + +fonts.expansions = expansions + +local classes = expansions.classes or allocate() +local vectors = expansions.vectors or allocate() + +expansions.classes = classes +expansions.vectors = vectors + +-- beware, pdftex itself uses percentages * 10 +-- +-- todo: get rid of byte() here + +classes.preset = { stretch = 2, shrink = 2, step = .5, factor = 1 } + +classes['quality'] = { + stretch = 2, shrink = 2, step = .5, vector = 'default', factor = 1 +} + +vectors['default'] = { + [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7, + [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7, + [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7, + [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, + [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, + [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, + [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, + [byte('w')] = 0.7, [byte('z')] = 0.7, + [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, +} + +vectors['quality'] = vectors['default'] -- metatable ? + +local function initialize(tfmdata,value) + if value then + local class, vector = get_class_and_vector(tfmdata,value,"expansions") + if class then + if vector then + local stretch = class.stretch or 0 + local shrink = class.shrink or 0 + local step = class.step or 0 + local factor = class.factor or 1 + if trace_expansion then + report_expansions("setting class %a, vector %a, factor %a, stretch %a, shrink %a, step %a", + value,class.vector,factor,stretch,shrink,step) + end + tfmdata.parameters.expansion = { + stretch = 10 * stretch, + shrink = 10 * shrink, + step = 10 * step, + factor = factor, + } + local data = characters and characters.data + for i, chr in next, tfmdata.characters do + local v = vector[i] + if data and not v then -- we could move the data test outside (needed for plain) + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + v = ((vector[s[1]] or 0) + (vector[s[#s]] or 0)) / 2 + else + v = vector[s] or 0 + end + end + end + if v and v ~= 0 then + chr.expansion_factor = v*factor + else -- can be option + chr.expansion_factor = factor + end + end + elseif trace_expansion then + report_expansions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_expansion then + report_expansions("unknown class %a",value) + end + end +end + +local specification = { + name = "expansion", + description = "apply hz optimization", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +fonts.goodies.register("expansions", function(...) return fonts.goodies.report("expansions", trace_expansion, ...) end) + +if context then + + implement { + name = "setupfontexpansion", + arguments = "2 strings", + actions = function(class,settings) getparameters(classes,class,'preset',settings) end + } + +end + +-- -- -- -- -- -- +-- protrusion +-- -- -- -- -- -- + +fonts.protrusions = allocate() +local protrusions = fonts.protrusions + +protrusions.classes = allocate() +protrusions.vectors = allocate() + +local classes = protrusions.classes +local vectors = protrusions.vectors + +-- the values need to be revisioned + +classes.preset = { factor = 1, left = 1, right = 1 } + +classes['pure'] = { + vector = 'pure', factor = 1 +} +classes['punctuation'] = { + vector = 'punctuation', factor = 1 +} +classes['alpha'] = { + vector = 'alpha', factor = 1 +} +classes['quality'] = { + vector = 'quality', factor = 1 +} + +vectors['pure'] = { + + [0x002C] = { 0, 1 }, -- comma + [0x002E] = { 0, 1 }, -- period + [0x003A] = { 0, 1 }, -- colon + [0x003B] = { 0, 1 }, -- semicolon + [0x002D] = { 0, 1 }, -- hyphen + [0x00AD] = { 0, 1 }, -- also hyphen + [0x2013] = { 0, 0.50 }, -- endash + [0x2014] = { 0, 0.33 }, -- emdash + [0x3001] = { 0, 1 }, -- ideographic comma 、 + [0x3002] = { 0, 1 }, -- ideographic full stop 。 + [0x060C] = { 0, 1 }, -- arabic comma ، + [0x061B] = { 0, 1 }, -- arabic semicolon ؛ + [0x06D4] = { 0, 1 }, -- arabic full stop ۔ + +} + +vectors['punctuation'] = { + + [0x003F] = { 0, 0.20 }, -- ? + [0x00BF] = { 0.20, 0 }, -- ¿ + [0x0021] = { 0, 0.20 }, -- ! + [0x00A1] = { 0.20, 0, }, -- ¡ + [0x0028] = { 0.05, 0 }, -- ( + [0x0029] = { 0, 0.05 }, -- ) + [0x005B] = { 0.05, 0 }, -- [ + [0x005D] = { 0, 0.05 }, -- ] + [0x002C] = { 0, 0.70 }, -- comma + [0x002E] = { 0, 0.70 }, -- period + [0x003A] = { 0, 0.50 }, -- colon + [0x003B] = { 0, 0.50 }, -- semicolon + [0x002D] = { 0, 0.70 }, -- hyphen + [0x00AD] = { 0, 0.70 }, -- also hyphen + [0x2013] = { 0, 0.30 }, -- endash + [0x2014] = { 0, 0.20 }, -- emdash + [0x060C] = { 0, 0.70 }, -- arabic comma + [0x061B] = { 0, 0.50 }, -- arabic semicolon + [0x06D4] = { 0, 0.70 }, -- arabic full stop + [0x061F] = { 0, 0.20 }, -- ؟ + + -- todo: left and right quotes: .5 double, .7 single + + [0x2039] = { 0.70, 0.70 }, -- left single guillemet ‹ + [0x203A] = { 0.70, 0.70 }, -- right single guillemet › + [0x00AB] = { 0.50, 0.50 }, -- left guillemet « + [0x00BB] = { 0.50, 0.50 }, -- right guillemet » + + [0x2018] = { 0.70, 0.70 }, -- left single quotation mark ‘ + [0x2019] = { 0, 0.70 }, -- right single quotation mark ’ + [0x201A] = { 0.70, 0 }, -- single low-9 quotation mark , + [0x201B] = { 0.70, 0 }, -- single high-reversed-9 quotation mark ‛ + [0x201C] = { 0.50, 0.50 }, -- left double quotation mark “ + [0x201D] = { 0, 0.50 }, -- right double quotation mark ” + [0x201E] = { 0.50, 0 }, -- double low-9 quotation mark „ + [0x201F] = { 0.50, 0 }, -- double high-reversed-9 quotation mark ‟ + +} + +vectors['alpha'] = { + + [byte("A")] = { .05, .05 }, + [byte("F")] = { 0, .05 }, + [byte("J")] = { .05, 0 }, + [byte("K")] = { 0, .05 }, + [byte("L")] = { 0, .05 }, + [byte("T")] = { .05, .05 }, + [byte("V")] = { .05, .05 }, + [byte("W")] = { .05, .05 }, + [byte("X")] = { .05, .05 }, + [byte("Y")] = { .05, .05 }, + + [byte("k")] = { 0, .05 }, + [byte("r")] = { 0, .05 }, + [byte("t")] = { 0, .05 }, + [byte("v")] = { .05, .05 }, + [byte("w")] = { .05, .05 }, + [byte("x")] = { .05, .05 }, + [byte("y")] = { .05, .05 }, + +} + +vectors['quality'] = table.merged( + vectors['punctuation'], + vectors['alpha'] +) + +-- As this is experimental code, users should not depend on it. The implications are still +-- discussed on the ConTeXt Dev List and we're not sure yet what exactly the spec is (the +-- next code is tested with a gyre font patched by / fea file made by Khaled Hosny). The +-- double trick should not be needed it proper hanging punctuation is used in which case +-- values < 1 can be used. +-- +-- preferred (in context, usine vectors): +-- +-- \definefontfeature[whatever][default][mode=node,protrusion=quality] +-- +-- using lfbd and rtbd, with possibibility to enable only one side : +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=yes, opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=right,opbd=yes,script=latn] +-- +-- idem, using multiplier +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn] +-- \definefontfeature[whocares][default][mode=node,protrusion=double,opbd=yes,script=latn] +-- +-- idem, using named feature file (less frozen): +-- +-- \definefontfeature[whocares][default][mode=node,protrusion=2,opbd=yes,script=latn,featurefile=texgyrepagella-regularxx.fea] + +classes['double'] = { -- for testing opbd + factor = 2, left = 1, right = 1, +} + +local function map_opbd_onto_protrusion(tfmdata,value,opbd) + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local properties = tfmdata.properties + local parameters = tfmdata.parameters + local resources = tfmdata.resources + local rawdata = tfmdata.shared.rawdata + local lookuphash = rawdata.lookuphash + local lookuptags = resources.lookuptags + local script = properties.script + local language = properties.language + local units = parameters.units + local done, factor, left, right = false, 1, 1, 1 + local class = classes[value] + if class then + factor = class.factor or 1 + left = class.left or 1 + right = class.right or 1 + else + factor = tonumber(value) or 1 + end + local lfactor = left * factor + local rfactor = right * factor + if trace_protrusion then + report_protrusions("left factor %0.3F, right factor %0.3F",lfactor,rfactor) + end + tfmdata.parameters.protrusion = { + factor = factor, + left = left, + right = right, + } + if opbd ~= "right" then + local validlookups, lookuplist = otf.collectlookups(rawdata,"lfbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + if steps then + if trace_protrusion then + report_protrusions("setting left using lfbd") + end + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + if v == true then + -- zero + else + local w = descriptions[k].width + local d = - v[1] + if w == 0 or d == 0 then + -- ignored + else + local p = lfactor * d/units + characters[k].left_protruding = p + if trace_protrusion then + report_protrusions("lfbd -> %0.3F %C",p,k) + end + end + end + end + end + end + done = true + end + end + end + end + if opbd ~= "left" then + local validlookups, lookuplist = otf.collectlookups(rawdata,"rtbd",script,language) + if validlookups then + for i=1,#lookuplist do + local lookup = lookuplist[i] + local steps = lookup.steps + if steps then + if trace_protrusion then + report_protrusions("setting right using rtbd") + end + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + for k, v in next, coverage do + if v == true then + -- zero + else + local w = descriptions[k].width + local d = - v[3] + if w == 0 or d == 0 then + -- ignored + else + local p = rfactor * d/units + characters[k].right_protruding = p + if trace_protrusion then + report_protrusions("rtbd -> %0.3F %C",p,k) + end + end + end + end + end + end + end + done = true + end + end + end +end + +-- The opbd test is just there because it was discussed on the context development list. However, +-- the mentioned fxlbi.otf font only has some kerns for digits. So, consider this feature not supported +-- till we have a proper test font. + +local function initialize(tfmdata,value) + if value then + local opbd = tfmdata.shared.features.opbd + if opbd then + -- possible values: left right both yes no (experimental) + map_opbd_onto_protrusion(tfmdata,value,opbd) + else + local class, vector = get_class_and_vector(tfmdata,value,"protrusions") + if class then + if vector then + local factor = class.factor or 1 + local left = class.left or 1 + local right = class.right or 1 + if trace_protrusion then + report_protrusions("setting class %a, vector %a, factor %a, left %a, right %a", + value,class.vector,factor,left,right) + end + local data = characters.data + local emwidth = tfmdata.parameters.quad + local lfactor = left * factor + local rfactor = right * factor + if trace_protrusion then + report_protrusions("left factor %0.3F, right factor %0.3F",lfactor,rfactor) + end + tfmdata.parameters.protrusion = { + factor = factor, + left = left, + right = right, + } + for i, chr in next, tfmdata.characters do + local v = vector[i] + local pl = nil + local pr = nil + if v then + pl = v[1] + pr = v[2] + else + local d = data[i] + if d then + local s = d.shcode + if not s then + -- sorry + elseif type(s) == "table" then + local vl = vector[s[1]] + local vr = vector[s[#s]] + if vl then pl = vl[1] end + if vr then pr = vr[2] end + else + v = vector[s] + if v then + pl = v[1] + pr = v[2] + end + end + end + end + if pl and pl ~= 0 then + local p = pl * lfactor + chr.left_protruding = p + if trace_protrusion then + report_protrusions("left -> %0.3F %C ",p,i) + end + end + if pr and pr ~= 0 then + local p = pr * rfactor + chr.right_protruding = p + if trace_protrusion then + report_protrusions("right -> %0.3F %C",p,i) + end + end + end + elseif trace_protrusion then + report_protrusions("unknown vector %a in class %a",class.vector,value) + end + elseif trace_protrusion then + report_protrusions("unknown class %a",value) + end + end + end +end + +local specification = { + name = "protrusion", + description = "l/r margin character protrusion", + initializers = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +fonts.goodies.register("protrusions", function(...) return fonts.goodies.report("protrusions", trace_protrusion, ...) end) + +if context then + + implement { + name = "setupfontprotrusion", + arguments = "2 strings", + actions = function(class,settings) getparameters(classes,class,'preset',settings) end + } + +end diff --git a/tex/context/base/mkiv/font-imp-reorder.lua b/tex/context/base/mkiv/font-imp-reorder.lua new file mode 100644 index 000000000..b2dec781c --- /dev/null +++ b/tex/context/base/mkiv/font-imp-reorder.lua @@ -0,0 +1,174 @@ +if not modules then modules = { } end modules ['font-imp-reorder'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next = next +local find = string.find +local sortedhash, sortedkeys, sort = table.sortedhash, table.sortedkeys, table.sort + +local fonts = fonts +local otf = fonts.handlers.otf +local registerotffeature = otf.features.register + +-- This is a rather special test-only feature that I added for the sake of testing +-- Idris's husayni. We wanted to know if uniscribe obeys the order of lookups in a +-- font, in spite of what the description of handling arabic suggests. And indeed, +-- mixed-in lookups of other features (like all these ss* in husayni) are handled +-- the same in context as in uniscribe. If one sets reorderlookups=arab then we sort +-- according to the "assumed" order so e.g. the ss* move to after the standard +-- features. The observed difference in rendering is an indication that uniscribe is +-- quite faithful to the font (while e.g. tests with the hb plugin demonstrate some +-- interference, apart from some hard coded init etc expectations). Anyway, it means +-- that we're okay with the (generic) node processor. A pitfall is that in context +-- we can actually control more, so we can trigger an analyze pass with e.g. +-- dflt/dflt while the libraries depend on the script settings for that. Uniscribe +-- probably also parses the string and when seeing arabic will follow a different +-- code path, although it seems to treat all features equal. + +local trace_reorder = trackers.register("fonts.reorderlookups",function(v) trace_reorder = v end) +local report_reorder = logs.reporter("fonts","reorder") + +local vectors = { } + +vectors.arab = { + gsub = { + ccmp = 1, + isol = 2, + fina = 3, + medi = 4, + init = 5, + rlig = 6, + rclt = 7, + calt = 8, + liga = 9, + dlig = 10, + cswh = 11, + mset = 12, + }, + gpos = { + curs = 1, + kern = 2, + mark = 3, + mkmk = 4, + }, +} + +local function compare(a,b) + local what_a = a.what + local what_b = b.what + if what_a ~= what_b then + return a.index < b.index + end + local when_a = a.when + local when_b = b.when + if when_a == when_b then + return a.index < b.index + else + return when_a < when_b + end +end + +function otf.reorderlookups(tfmdata,vector) + local order = vectors[vector] + if not order then + return + end + local oldsequences = tfmdata.resources.sequences + if oldsequences then + local sequences = { } + for i=1,#oldsequences do + sequences[i] = oldsequences[i] + end + for i=1,#sequences do + local s = sequences[i] + local features = s.features + local kind = s.type + local index = s.index + if features then + local when + local what + for feature in sortedhash(features) do + if not what then + what = find(kind,"^gsub") and "gsub" or "gpos" + end + local newwhen = order[what][feature] + if not newwhen then + -- skip + elseif not when then + when = newwhen + elseif newwhen < when then + when = newwhen + end + end + s.ondex = s.index + s.index = i + s.what = what == "gsub" and 1 or 2 + s.when = when or 99 + else + s.ondex = s.index + s.index = i + s.what = 1 + s.when = 99 + end + end + sort(sequences,compare) + local swapped = 0 + for i=1,#sequences do + local sequence = sequences[i] + local features = sequence.features + if features then + local index = sequence.index + if index ~= i then + swapped = swapped + 1 + end + if trace_reorder then + if swapped == 1 then + report_reorder() + report_reorder("start swapping lookups in font %!font:name!",tfmdata) + report_reorder() + report_reorder("gsub order: % t",table.swapped(order.gsub)) + report_reorder("gpos order: % t",table.swapped(order.gpos)) + report_reorder() + end + report_reorder("%03i : lookup %03i, type %s, sorted %2i, moved %s, % t", + i,index,sequence.what == 1 and "gsub" or "gpos",sequence.when or 99, + (index > i and "-") or (index < i and "+") or "=",sortedkeys(features)) + end + end + sequence.what = nil + sequence.when = nil + sequence.index = sequence.ondex + end + if swapped > 0 then + if trace_reorder then + report_reorder() + report_reorder("stop swapping lookups, %i lookups swapped",swapped) + report_reorder() + end + tfmdata.shared.reorderedsequences = sequences + end + end +end + +-- maybe delay till ra is filled + +local function initialize(tfmdata,key,value) + if value then + otf.reorderlookups(tfmdata,value) + end +end + +registerotffeature { + name = "reorderlookups", + description = "reorder lookups", + manipulators = { + base = initialize, + node = initialize, + } +} diff --git a/tex/context/base/mkiv/font-imp-tex.lua b/tex/context/base/mkiv/font-imp-tex.lua new file mode 100644 index 000000000..b4b9a7b69 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-tex.lua @@ -0,0 +1,144 @@ +if not modules then modules = { } end modules ['font-imp-tex'] = { + version = 1.001, + comment = "companion to font-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local next = next + +local fonts = fonts +local otf = fonts.handlers.otf +local registerotffeature = otf.features.register +local addotffeature = otf.addfeature + +-- tlig (we need numbers for some fonts so ...) + +local specification = { + type = "ligature", + order = { "tlig" }, + prepend = true, + data = { + -- endash = "hyphen hyphen", + -- emdash = "hyphen hyphen hyphen", + [0x2013] = { 0x002D, 0x002D }, + [0x2014] = { 0x002D, 0x002D, 0x002D }, + -- quotedblleft = "quoteleft quoteleft", + -- quotedblright = "quoteright quoteright", + -- quotedblleft = "grave grave", + -- quotedblright = "quotesingle quotesingle", + -- quotedblbase = "comma comma", + }, +} + +addotffeature("tlig",specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = "tlig", + description = "tex ligatures", +} + +-- trep + +local specification = { + type = "substitution", + order = { "trep" }, + prepend = true, + data = { + -- [0x0022] = 0x201D, + [0x0027] = 0x2019, + -- [0x0060] = 0x2018, + }, +} + +addotffeature("trep",specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = "trep", + description = "tex replacements", +} + +-- some day this will be moved to font-imp-scripts.lua + +-- anum + +local anum_arabic = { + [0x0030] = 0x0660, + [0x0031] = 0x0661, + [0x0032] = 0x0662, + [0x0033] = 0x0663, + [0x0034] = 0x0664, + [0x0035] = 0x0665, + [0x0036] = 0x0666, + [0x0037] = 0x0667, + [0x0038] = 0x0668, + [0x0039] = 0x0669, +} + +local anum_persian = { + [0x0030] = 0x06F0, + [0x0031] = 0x06F1, + [0x0032] = 0x06F2, + [0x0033] = 0x06F3, + [0x0034] = 0x06F4, + [0x0035] = 0x06F5, + [0x0036] = 0x06F6, + [0x0037] = 0x06F7, + [0x0038] = 0x06F8, + [0x0039] = 0x06F9, +} + +local function valid(data) + local features = data.resources.features + if features then + for k, v in next, features do + for k, v in next, v do + if v.arab then + return true + end + end + end + end +end + +local specification = { + { + type = "substitution", + features = { arab = { urd = true, dflt = true } }, + order = { "anum" }, + data = anum_arabic, + valid = valid, + }, + { + type = "substitution", + features = { arab = { urd = true } }, + order = { "anum" }, + data = anum_persian, + valid = valid, + }, +} + +addotffeature("anum",specification) + +registerotffeature { + -- this makes it a known feature (in tables) + name = "anum", + description = "arabic digits", +} + +-- -- example: +-- +-- fonts.handlers.otf.addfeature { +-- name = "hangulfix", +-- type = "substitution", +-- features = { ["hang"] = { ["*"] = true } }, +-- data = { +-- [0x1160] = 0x119E, +-- }, +-- order = { "hangulfix" }, +-- flags = { }, +-- prepend = true, +-- }) diff --git a/tex/context/base/mkiv/font-imp-tracing.lua b/tex/context/base/mkiv/font-imp-tracing.lua new file mode 100644 index 000000000..6ce445143 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-tracing.lua @@ -0,0 +1,281 @@ +if not modules then modules = { } end modules ['font-imp-tracing'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next, type = next, type +local concat = table.concat +local formatters = string.formatters + +local fonts = fonts + +local handlers = fonts.handlers +local registerotffeature = handlers.otf.features.register +local registerafmfeature = handlers.afm.features.register + +local settings_to_array = utilities.parsers.settings_to_array +local setmetatableindex = table.setmetatableindex + +local helpers = fonts.helpers +local appendcommandtable = helpers.appendcommandtable +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char + +local variables = interfaces.variables + +local v_background = variables.background +local v_frame = variables.frame +local v_empty = variables.empty +local v_none = variables.none + +-- for zhichu chen (see mailing list archive): we might add a few more variants +-- in due time +-- +-- \definefontfeature[boxed][default][boundingbox=yes] % paleblue +-- +-- maybe: +-- +-- \definecolor[DummyColor][s=.75,t=.5,a=1] {\DummyColor test} \nopdfcompression +-- +-- local gray = { "pdf", "origin", "/Tr1 gs .75 g" } +-- local black = { "pdf", "origin", "/Tr0 gs 0 g" } + +-- boundingbox={yes|background|frame|empty|} + +local bp = number.dimenfactors.bp +local r = 16384 * bp -- 65536 // 4 +local f_1 = formatters["%.6F w 0 %.6F %.6F %.6F re f"] +local f_2 = formatters["[] 0 d 0 J %.6F w %.6F %.6F %.6F %.6F re S"] + +-- change this into w h d instead of h d w + +local backcache = setmetatableindex(function(t,h) + local h = h * bp + local v = setmetatableindex(function(t,d) + local d = d * bp + local v = setmetatableindex(function(t,w) + local v = { "pdf", "origin", f_1(r,-d,w*bp,h+d) } + t[w] = v + return v + end) + t[d] = v + return v + end) + t[h] = v + return v +end) + +local forecache = setmetatableindex(function(t,h) + local h = h * bp + local v = setmetatableindex(function(t,d) + local d = d * bp + local v = setmetatableindex(function(t,w) + -- the frame goes through the boundingbox + local v = { "pdf", "origin", f_2(r,r/2,-d+r/2,w*bp-r,h+d-r) } + t[w] = v + return v + end) + t[d] = v + return v + end) + t[h] = v + return v +end) + +local startcolor = nil +local stopcolor = nil + +local function initialize(tfmdata,key,value) + if value then + if not backcolors then + local vfspecials = backends.pdf.tables.vfspecials + startcolor = vfspecials.startcolor + stopcolor = vfspecials.stopcolor + end + local characters = tfmdata.characters + local rulecache = backcache + local showchar = true + local color = "palegray" + if type(value) == "string" then + value = settings_to_array(value) + for i=1,#value do + local v = value[i] + if v == v_frame then + rulecache = forecache + elseif v == v_background then + rulecache = backcache + elseif v == v_empty then + showchar = false + elseif v == v_none then + color = nil + else + color = v + end + end + end + local gray = color and startcolor(color) or nil + local black = gray and stopcolor or nil + for unicode, character in next, characters do + local width = character.width or 0 + local height = character.height or 0 + local depth = character.depth or 0 + local rule = rulecache[height][depth][width] + if showchar then + local commands = character.commands + if commands then + if gray then + character.commands = prependcommands ( + commands, gray, rule, black + ) + else + character.commands = prependcommands ( + commands, rule + ) + end + else + local char = charcommand[unicode] + if gray then + character.commands = { + gray, rule, black, char + } + else + character.commands = { + rule, char + } + end + end + else + if gray then + character.commands = { + gray, rule, black + } + else + character.commands = { + rule + } + end + end + end + end +end + +local specification = { + name = "boundingbox", + description = "show boundingbox", + manipulators = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) + +local f_m = formatters["%F %F m"] +local f_l = formatters["%F %F l"] +local f_b = formatters["[] 0 d 0 J %.6F w"] +local f_e = formatters["s"] + +local function ladder(list,docolor,nocolor,lst,offset,sign,default) + local l = lst[1] + local x1 = bp * (offset + l.kern) * sign + local y1 = bp * l.height + local t = { f_b(r,r/2), f_m(x1,y1) } + local n = 2 + local m = #lst + if default > 0 then + default = default * bp + r + else + default = default * bp - r + end + if m == 1 then + n = n + 1 t[n] = f_l(x1,default) + else + for i=1,m do + local l = lst[i] + local x2 = bp * (offset + l.kern) * sign + local y2 = bp * l.height + if i > 1 and y2 == 0 then + y2 = default + end + n = n + 1 t[n] = f_l(x2,y1) + n = n + 1 t[n] = f_l(x2,y2) + x1, y1 = x2, y2 + end + end + n = n + 1 t[n] = f_e() + list[#list+1] = docolor + list[#list+1] = { "pdf", "origin", concat(t," ") } + list[#list+1] = nocolor +end + +local function initialize(tfmdata,key,value) + if value then + if not backcolors then + local vfspecials = backends.pdf.tables.vfspecials + startcolor = vfspecials.startcolor + stopcolor = vfspecials.stopcolor + end + local characters = tfmdata.characters + local brcolor = startcolor("darkred") + local trcolor = startcolor("darkgreen") + local blcolor = startcolor("darkblue") + local tlcolor = startcolor("darkyellow") + local black = stopcolor + for unicode, character in next, characters do + local mathkern = character.mathkern + if mathkern then + -- more efficient would be co collect more in one pdf + -- directive but this is hardly used so not worth the + -- effort + local width = character.width or 0 + local height = character.height or 0 + local depth = character.depth or 0 + local list = { } + local br = mathkern.bottom_right + local tr = mathkern.top_right + local bl = mathkern.bottom_left + local tl = mathkern.top_left + if br then + ladder(list,brcolor,black,br,width,1,height) + end + if tr then + ladder(list,trcolor,black,tr,width,1,-depth) + end + if bl then + ladder(list,blcolor,black,bl,0,-1,height) + end + if tl then + ladder(list,tlcolor,black,tl,0,-1,-depth) + end + if #list > 0 then + local commands = character.commands + if commands then + character.commands = appendcommandtable(commands,list) + else + list[#list+1] = charcommand[unicode] + character.commands = list + end + end + end + end + end +end + +local specification = { + name = "staircase", + description = "show staircase kerns", + position=1, + manipulators = { + base = initialize, + node = initialize, + } +} + +registerotffeature(specification) +registerafmfeature(specification) diff --git a/tex/context/base/mkiv/font-imp-unicode.lua b/tex/context/base/mkiv/font-imp-unicode.lua new file mode 100644 index 000000000..ddb965ec9 --- /dev/null +++ b/tex/context/base/mkiv/font-imp-unicode.lua @@ -0,0 +1,82 @@ +if not modules then modules = { } end modules ['font-imp-unicode'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if not context then return end + +local next = next + +local fonts = fonts +local helpers = fonts.helpers +local constructors = fonts.constructors +local registerotffeature = fonts.handlers.otf.features.register + +local extraprivates = helpers.extraprivates +local addprivate = helpers.addprivate + +local function initialize(tfmdata) + for i=1,#extraprivates do + local e = extraprivates[i] + local c = e[2](tfmdata) + if c then + addprivate(tfmdata, e[1], c) + end + end +end + +constructors.newfeatures.otf.register { + name = "extraprivates", + description = "extra privates", + default = true, + manipulators = { + base = initialize, + node = initialize, + } +} + +local tounicode = fonts.mappings.tounicode + +local function initialize(tfmdata,key,value) + if value == "ligatures" then + local private = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 + local collected = fonts.handlers.otf.readers.getcomponents(tfmdata.shared.rawdata) + if collected and next(collected)then + for unicode, char in next, tfmdata.characters do + local u = collected[unicode] + if u then + local n = #u + for i=1,n do + if u[i] > private then + n = 0 + break + end + end + if n > 0 then + if n == 1 then + u = u[1] + end + char.unicode = u + char.tounicode = tounicode(u) + end + end + end + end + end +end + +-- forceunicodes=ligatures : aggressive lig resolving (e.g. for emoji) +-- +-- kind of like: \enabletrackers[fonts.mapping.forceligatures] + +registerotffeature { + name = "forceunicodes", + description = "forceunicodes", + manipulators = { + base = initialize, + node = initialize, + } +} diff --git a/tex/context/base/mkiv/font-ini.lua b/tex/context/base/mkiv/font-ini.lua index 3d5dd27a2..462e30bf9 100644 --- a/tex/context/base/mkiv/font-ini.lua +++ b/tex/context/base/mkiv/font-ini.lua @@ -10,22 +10,45 @@ if not modules then modules = { } end modules ['font-ini'] = {

Not much is happening here.

--ldx]]-- -local allocate = utilities.storage.allocate +local allocate = utilities.storage.allocate +local sortedhash = table.sortedhash -fonts = fonts or { } -local fonts = fonts +fonts = fonts or { } +local fonts = fonts -fonts.hashes = fonts.hashes or { identifiers = allocate() } -fonts.tables = fonts.tables or { } -fonts.helpers = fonts.helpers or { } -fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata -fonts.specifiers = fonts.specifiers or { } -- in format ! +local identifiers = allocate() -fonts.analyzers = { } -- not needed here -fonts.readers = { } -fonts.definers = { methods = { } } -fonts.loggers = { register = function() end } +fonts.hashes = fonts.hashes or { identifiers = identifiers } +fonts.tables = fonts.tables or { } +fonts.helpers = fonts.helpers or { } +fonts.tracers = fonts.tracers or { } -- for the moment till we have move to moduledata +fonts.specifiers = fonts.specifiers or { } -- in format ! + +fonts.analyzers = { } -- not needed here +fonts.readers = { } +fonts.definers = { methods = { } } +fonts.loggers = { register = function() end } if context then + + font.originaleach = font.each + + function font.each() + return sortedhash(identifiers) + end + fontloader = nil + end + +-- Outside context one can bump textbase to some higher value but only the +-- textbase given here is officially supported (read: bug testing etc will +-- use the values below). + +fonts.privateoffsets = { + textbase = 0xF0000, -- used for hidden (opentype features) + textextrabase = 0xFD000, -- used for visible by name + mathextrabase = 0xFE000, -- used for visible by code + mathbase = 0xFF000, -- used for hidden (virtual math) + keepnames = false, -- when set to true names are always kept (not for context) +} diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi index 693182919..dd8a5f148 100644 --- a/tex/context/base/mkiv/font-ini.mkvi +++ b/tex/context/base/mkiv/font-ini.mkvi @@ -341,12 +341,16 @@ \the\everybodyfont \settrue\c_font_synchronize} +\let\savedfont\empty + +\installmacrostack\savedfont + \unexpanded\def\savefont {\edef\savedfont{\the\font}% gives \csname - \pushmacro\savedfont} + \push_macro_savedfont} \unexpanded\def\restorefont - {\popmacro\savedfont + {\pop_macro_savedfont \savedfont} \unexpanded\def\pushcurrentfont @@ -424,7 +428,7 @@ % % \def\normalizebodyfontsize_indeed#macro#body% % {\edef#macro{\ctxcommand{nbfs(\number\dimexpr#body,\number\fontdigits)}}% -% \global\expandafter\let\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro} +% \expandafter\glet\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro} % % \def\thenormalizedbodyfontsize#body% % {\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}} @@ -439,7 +443,7 @@ \def\normalizebodyfontsize_indeed#macro#body% {\edef#macro{\clf_nbfs\dimexpr#body\relax}% - \global\expandafter\let\csname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro} + \expandafter\glet\csname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro} \def\thenormalizedbodyfontsize#body% {\clf_nbfs\dimexpr#body\relax} @@ -583,8 +587,7 @@ \def\font_basics_define_fontstyle[#commands][#style]% style: rm ss tt ... {\ifcsname\??fontstyleknown#style\endcsname \else % can be delayed till used (cg, hw) \font_helpers_register_style{#style}% - % todo: apptoks - \t_font_style_commands\expandafter{\the\t_font_style_commands\m_font_style_command{#style}}% + \toksapp\t_font_style_commands{\m_font_style_command{#style}}% \fi \processcommalist[#commands]{\font_basics_define_fontstyle_indeed{#style}}} @@ -595,17 +598,14 @@ \unexpanded\def\definefontsize[#size]% {\ifcsname\??fontsizeknown#size\endcsname \else \font_helpers_register_size{#size}% - \t_font_size_commands\expandafter{\the\t_font_size_commands - \m_font_size_command{#size}}% + \toksapp\t_font_size_commands{\m_font_size_command{#size}}% \fi \font_helpers_check_fontname_combinations} \unexpanded\def\definefontalternative[#alternative]% {\ifcsname\??fontalternativeknown#alternative\endcsname \else \font_helpers_register_alternative{#alternative}% - % todo: apptoks - \t_font_alternative_commands\expandafter{\the\t_font_alternative_commands - \m_font_alternative_command{#alternative}}% + \toksapp\t_font_alternative_commands{\m_font_alternative_command{#alternative}}% \fi \font_helpers_check_fontname_combinations} @@ -775,7 +775,7 @@ \unexpanded\def\font_helpers_low_level_define#specification#csname% {% we can now set more at the lua end - \global\let\somefontname\defaultfontfile + \glet\somefontname\defaultfontfile \let\somefontsize\empty \clf_definefont_one{\detokenize\expandafter{\normalexpanded{#specification}}}% the escapestring catches at \somedimen % sets \scaledfontmode and \somefontname and \somefontsize @@ -912,7 +912,7 @@ %D The following macros are used at the \LUA\ end. Watch the \type {\normal} %D hackery: this makes the mkvi parser happy. -% \normaldef\fntsetdefname {\global\let\somefontname\defaultfontfile} % do before calling +% \normaldef\fntsetdefname {\glet\somefontname\defaultfontfile} % do before calling % \normaldef\fntsetnopsize {\let\somefontsize\empty} % do before calling % \normaldef\fntsetsomename{\normalgdef\somefontname} % takes argument % \normaldef\fntsetsomesize{\normaldef\somefontsize} % takes argument @@ -1038,7 +1038,7 @@ {\begingroup \font_basics_define_font[#name][#specification][#settings]% \csname#name\endcsname - \global\let\lastglobalrawfontcall\lastrawfontcall + \glet\lastglobalrawfontcall\lastrawfontcall \endgroup \expandafter\let\csname#name\endcsname\lastglobalrawfontcall} @@ -1377,16 +1377,16 @@ %D settings (just to be sure, as it's not really needed). \def\font_basics_define_body_font_environment_empty[#body][#settings][#dummy]% - {\pushmacro\fontclass + {\push_macro_fontclass \let\fontclass\empty \font_basics_define_body_font_environment_class[][#body][#settings]% - \popmacro\fontclass} + \pop_macro_fontclass} \def\font_basics_define_body_font_environment_unset[#body][#dummya][#dummyb]% - {\pushmacro\fontclass + {\push_macro_fontclass \let\fontclass\empty \font_basics_define_body_font_environment_class[][#body][]% - \popmacro\fontclass} + \pop_macro_fontclass} %D We don't check too soon as we can refer to later definitions. @@ -1397,13 +1397,13 @@ \ifcsname\??fontenvironmentknown#class#normalizedbody\endcsname % environment and size already defined \else\ifproductionrun - \pushmacro\fontclass + \push_macro_fontclass \edef\fontclass{#class}% \font_helpers_register_environment{#class}{#normalizedbody}% \settrue\c_font_defining_environment_state \font_helpers_define_unknown_font{#normalizedbody}% current class \setfalse\c_font_defining_environment_state - \popmacro\fontclass + \pop_macro_fontclass \fi\fi \font_helpers_register_fontbody{#normalizedbody}} @@ -1527,12 +1527,12 @@ \fi} \def\font_basics_define_body_font_class_given[#1][#2][#3]#4% - {\pushmacro\fontclass + {\push_macro_fontclass \doifelse{#4}\s!default {\let\fontclass\empty} {\def\fontclass{#4}}% \definebodyfont[#1][#2][#3]% - \popmacro\fontclass} + \pop_macro_fontclass} \def\font_basics_define_body_font_class_known {\ifthirdargument @@ -1644,13 +1644,13 @@ \unexpanded\def\font_basics_define_body_font_yes_xx[#one#two#rest=#value]% global {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-1\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-1\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-0}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-2\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-2\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-4}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-3\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-3\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-5}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% } @@ -1673,9 +1673,9 @@ \unexpanded\def\font_basics_define_body_font_yes_mm[#one#two#rest=#value]% global {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi - \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined - % \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined - % \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined + \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined + % \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined + % \expandafter\glet\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\s!mm-#one#two#rest\endcsname {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}% } @@ -1727,7 +1727,8 @@ \font_helpers_process_style_list{\font_helpers_define_unknown_check_definitions{#body}}% \ifconditional\c_font_defining_state \ifconditional\c_font_defining_environment_state\else - \showmessage\m!fonts{14}{#body}% main + %\showmessage\m!fonts{14}{#body}% main + \clf_registerunknownbodysize{#body}% \fi \setfalse\c_font_defining_state \font_helpers_register_fontbody{#body}% @@ -1741,13 +1742,6 @@ \fi \fi} -% \def\font_helpers_define_unknown_check_sizes#body#relativesize% -% {\ifcsname\??fontenvironments\s!default#relativesize\endcsname % fontclass ? -% % how \lastnamedcs here -% \expandafter\normalizebodyfontsize\csname\??fontenvironments#body#relativesize\endcsname{\csname\??fontenvironments\s!default#relativesize\endcsname\dimexpr#body\relax}% -% \settrue\c_font_defining_state -% \fi} - \def\font_helpers_define_unknown_check_sizes#body#relativesize% {\ifcsname\??fontenvironments\s!default#relativesize\endcsname % fontclass ? \expandafter\normalizebodyfontsize\csname\??fontenvironments#body#relativesize\endcsname{\csname\??fontenvironments\s!default#relativesize\endcsname\dimexpr#body\relax}% @@ -2363,7 +2357,7 @@ \noexpand\edef\noexpand\xtextface {\currentbodyfontdimension\s!x }% \noexpand\edef\noexpand\xxtextface {\currentbodyfontdimension\s!xx }% }% - \global\expandafter\let\csname\??fontbodyfaces\fontbody\endcsname\font_basics_set_faces} + \expandafter\glet\csname\??fontbodyfaces\fontbody\endcsname\font_basics_set_faces} % \def\currentbodyfontdimension#parameter% % {\the\dimexpr @@ -2505,15 +2499,15 @@ %D \stoptyping % \unexpanded\def\usebodyfont[#1]% -% {\pushmacro\fontclass +% {\push_macro_fontclass % \switchtobodyfont[#1]% -% \popmacro\fontclass +% \pop_macro_fontclass % \ifx\fontclass\empty\else\setupbodyfont\relax\fi} % \unexpanded\def\usebodyfont[#1]% -% {\pushmacro\fontclass +% {\push_macro_fontclass % \font_helpers_set_font\zerocount{#1}% -% \popmacro\fontclass +% \pop_macro_fontclass % \ifx\fontclass\empty \else % \font_basics_setupbodyfont_nop % \fi} @@ -2716,7 +2710,7 @@ \unexpanded\def\font_basics_predefine#1#2% {\font_basics_defined_font_yes[#2]% - \global\expandafter\let\csname#1\expandafter\endcsname\csname\v_font_identifier_basic\endcsname} + \expandafter\glet\csname#1\expandafter\endcsname\csname\v_font_identifier_basic\endcsname} \unexpanded\def\font_basics_predefined#1% {\font_basics_predefine{\??predefinedfont#1}{#1}} @@ -2763,7 +2757,26 @@ \expandafter\getprivatechar \fi} -% new +%D Some fonts can have color specifiers: +%D +%D \starttyping +%D \definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes] +%D \definefontsynonym[emoji][seguiemj*seguiemj-cl] +%D +%D \definecolor[emoji-red] [r=.4] +%D \definecolor[emoji-gray][s=1,t=.5,a=1] +%D +%D %definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] % bad +%D \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] % okay +%D +%D \definefontfeature[seguiemj-r][ccmp=yes,dist=yes,colr=emoji-r] +%D +%D \definefont[MyEmojiR][seguiemj*seguiemj-r @ 100pt] +%D +%D \startTEXpage[offset=10pt] +%D \MyEmojiR\resolvedemoji{triangular ruler} +%D \stopTEXpage +%D \stoptyping \unexpanded\def\definefontcolorpalette {\dodoubleargument\font_define_color_palette} diff --git a/tex/context/base/mkiv/font-lib.mkvi b/tex/context/base/mkiv/font-lib.mkvi index 24ab68781..3cff81751 100644 --- a/tex/context/base/mkiv/font-lib.mkvi +++ b/tex/context/base/mkiv/font-lib.mkvi @@ -26,22 +26,27 @@ % the otf font loader: +% helpers + + \registerctxluafile{font-otr}{optimize} % opentype fontloader \registerctxluafile{font-web}{} % opentype fontloader \registerctxluafile{font-cff}{optimize} % quadratic outlines \registerctxluafile{font-ttf}{optimize} % cubic outlines \registerctxluafile{font-dsp}{optimize} % ... for this one \registerctxluafile{font-hsh}{} % hashes used by context -\registerctxluafile{font-nod}{} +\registerctxluafile{font-vfc}{} +\registerctxluafile{font-prv}{} % needs hashes +\registerctxluafile{font-nod}{optimize} \registerctxluafile{font-oti}{} % otf initialization \registerctxluafile{font-ott}{} % otf tables (first) \registerctxluafile{font-otl}{} \registerctxluafile{font-oto}{} -\registerctxluafile{font-otj}{} +\registerctxluafile{font-otj}{optimize} \registerctxluafile{font-oup}{} \registerctxluafile{font-ota}{} -\registerctxluafile{font-ots}{} -\registerctxluafile{font-otd}{} +\registerctxluafile{font-ots}{optimize} +\registerctxluafile{font-otd}{optimize} \registerctxluafile{font-otc}{} \registerctxluafile{font-oth}{} \registerctxluafile{font-osd}{} @@ -55,7 +60,12 @@ % tfm -\registerctxluafile{font-tfm}{} +\doifelsefileexists {font-tpk.lua} { + \registerctxluafile{font-tpk}{optimize} + \registerctxluafile{font-tfm}{} +} { + \registerctxluafile{font-tfm}{} +} % name database @@ -87,7 +97,28 @@ \registerctxluafile{font-def}{} \registerctxluafile{font-ctx}{} % after def as it overloads -\registerctxluafile{font-ext}{} +% extensions, order matters + +\registerctxluafile{font-imp-ligatures}{} +\registerctxluafile{font-imp-tex}{} +\registerctxluafile{font-imp-reorder}{} +\registerctxluafile{font-imp-properties}{} +\registerctxluafile{font-imp-unicode}{} +\registerctxluafile{font-imp-math}{} +\registerctxluafile{font-imp-notused}{} +\registerctxluafile{font-imp-effects}{} +\registerctxluafile{font-imp-quality}{} +\registerctxluafile{font-imp-italics}{} +\registerctxluafile{font-imp-dimensions}{} + +\doifelsefileexists{font-imp-scripts.lua} { + \registerctxluafile{font-imp-scripts}{} +} { + % not yet, lmtx feature +} + +\registerctxluafile{font-imp-tracing}{} % comes last! + \registerctxluafile{font-fbk}{} \registerctxluafile{font-aux}{} diff --git a/tex/context/base/mkiv/font-map.lua b/tex/context/base/mkiv/font-map.lua index 66cf2db39..d931b822e 100644 --- a/tex/context/base/mkiv/font-map.lua +++ b/tex/context/base/mkiv/font-map.lua @@ -168,44 +168,73 @@ local function tounicode16sequence(unicodes) return concat(t) end -local function tounicode(unicode) - if type(unicode) == "table" then - local t = { } - for l=1,#unicode do - local u = unicode[l] - if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then - t[l] = f_single(u) - else - u = u - 0x10000 - t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00) - end - end - return concat(t) - else - if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then - return f_single(unicode) - else - unicode = unicode - 0x10000 - return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) - end - end -end +-- local function tounicode(unicode) +-- if type(unicode) == "table" then +-- local t = { } +-- for l=1,#unicode do +-- local u = unicode[l] +-- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then +-- t[l] = f_single(u) +-- else +-- u = u - 0x10000 +-- t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00) +-- end +-- end +-- return concat(t) +-- else +-- if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then +-- return f_single(unicode) +-- else +-- unicode = unicode - 0x10000 +-- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) +-- end +-- end +-- end --- no real gain on runs +local unknown = f_single(0xFFFD) --- local hash = table.setmetatableindex(function(t,u) +-- local function tounicode(unicode) +-- if type(unicode) == "table" then +-- local t = { } +-- for l=1,#unicode do +-- t[l] = tounicode(unicode[l]) +-- end +-- return concat(t) +-- elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then +-- return unknown +-- elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then +-- return unknown +-- elseif unicode >= 0x100000 and unicode <= 0x10FFFF then +-- return unknown +-- elseif unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then +-- return f_single(unicode) +-- else +-- unicode = unicode - 0x10000 +-- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) +-- end +-- end + +-- local hash = table.setmetatableindex(function(t,k) -- local v --- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then --- v = f_single(u) +-- if k >= 0x00E000 and k <= 0x00F8FF then +-- v = unknown +-- elseif k >= 0x0F0000 and k <= 0x0FFFFF then +-- v = unknown +-- elseif k >= 0x100000 and k <= 0x10FFFF then +-- v = unknown +-- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then +-- v = f_single(k) -- else --- u = u - 0x10000 --- v = f_double(rshift(u,10)+0xD800,u%1024+0xDC00) +-- local k = k - 0x10000 +-- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00) -- end --- t[u] = v +-- t[k] = v -- return v -- end) -- --- local function tounicode(unicode,name) +-- table.makeweak(hash) +-- +-- local function tounicode(unicode) -- if type(unicode) == "table" then -- local t = { } -- for l=1,#unicode do @@ -217,6 +246,69 @@ end -- end -- end +local hash = { } +local conc = { } + +-- table.makeweak(hash) + +-- table.setmetatableindex(hash,function(t,k) +-- if type(k) == "table" then +-- local n = #k +-- for l=1,n do +-- conc[l] = hash[k[l]] +-- end +-- return concat(conc,"",1,n) +-- end +-- local v +-- if k >= 0x00E000 and k <= 0x00F8FF then +-- v = unknown +-- elseif k >= 0x0F0000 and k <= 0x0FFFFF then +-- v = unknown +-- elseif k >= 0x100000 and k <= 0x10FFFF then +-- v = unknown +-- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then +-- v = f_single(k) +-- else +-- local k = k - 0x10000 +-- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00) +-- end +-- t[k] = v +-- return v +-- end) +-- +-- local function tounicode(unicode) +-- return hash[unicode] +-- end + +table.setmetatableindex(hash,function(t,k) + if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then + v = f_single(k) + else + local k = k - 0x10000 + v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00) + end + t[k] = v + return v +end) + +local function tounicode(k) + if type(k) == "table" then + local n = #k + for l=1,n do + conc[l] = hash[k[l]] + end + return concat(conc,"",1,n) + elseif k >= 0x00E000 and k <= 0x00F8FF then + return unknown + elseif k >= 0x0F0000 and k <= 0x0FFFFF then + return unknown + elseif k >= 0x100000 and k <= 0x10FFFF then + return unknown + else + return hash[k] + end +end + local function fromunicode16(str) if #str == 4 then return tonumber(str,16) @@ -431,7 +523,8 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) glyph.unicode = unicode end else - local t, n = { }, 0 + local t = { } + local n = 0 for l=1,nsplit do local base = split[l] local u = unicodes[base] or unicodevector[base] or contextvector[name] @@ -487,12 +580,17 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) missing[du] = true nofmissing = nofmissing + 1 end + else + -- maybe a message or so end end else local overload = overloads[du] if overload then glyph.unicode = overload.unicode + elseif not glyph.unicode then + missing[du] = true + nofmissing = nofmissing + 1 end end end diff --git a/tex/context/base/mkiv/font-mat.mkvi b/tex/context/base/mkiv/font-mat.mkvi index 0134f3fe6..64810d327 100644 --- a/tex/context/base/mkiv/font-mat.mkvi +++ b/tex/context/base/mkiv/font-mat.mkvi @@ -263,12 +263,12 @@ \fi} \def\font_helpers_bidirectional_mathstrategy_nop_changed - {\textfont \c_font_fam_mr_rl\textfont \c_font_fam_mr - \scriptfont \c_font_fam_mr_rl\scriptfont \c_font_fam_mr - \scriptscriptfont\c_font_fam_mr_rl\scriptscriptfont\c_font_fam_mr - \textfont \c_font_fam_mr_lr\textfont \c_font_fam_mr + {\textfont \c_font_fam_mr_lr\textfont \c_font_fam_mr \scriptfont \c_font_fam_mr_lr\scriptfont \c_font_fam_mr - \scriptscriptfont\c_font_fam_mr_lr\scriptscriptfont\c_font_fam_mr} + \scriptscriptfont\c_font_fam_mr_lr\scriptscriptfont\c_font_fam_mr + \textfont \c_font_fam_mr_rl\textfont \c_font_fam_mr + \scriptfont \c_font_fam_mr_rl\scriptfont \c_font_fam_mr + \scriptscriptfont\c_font_fam_mr_rl\scriptscriptfont\c_font_fam_mr} \appendtoks \ifconditional\c_font_bidirectional_mathstrategy @@ -313,12 +313,12 @@ {\textfont \c_font_fam_mb \textfont \c_font_fam_mr \scriptfont \c_font_fam_mb \scriptfont \c_font_fam_mr \scriptscriptfont\c_font_fam_mb \scriptscriptfont\c_font_fam_mr - \textfont \c_font_fam_mb_rl\textfont \c_font_fam_mr_rl - \scriptfont \c_font_fam_mb_rl\scriptfont \c_font_fam_mr_rl - \scriptscriptfont\c_font_fam_mb_rl\scriptscriptfont\c_font_fam_mr_rl \textfont \c_font_fam_mb_lr\textfont \c_font_fam_mr_lr \scriptfont \c_font_fam_mb_lr\scriptfont \c_font_fam_mr_lr - \scriptscriptfont\c_font_fam_mb_lr\scriptscriptfont\c_font_fam_mr_lr} + \scriptscriptfont\c_font_fam_mb_lr\scriptscriptfont\c_font_fam_mr_lr + \textfont \c_font_fam_mb_rl\textfont \c_font_fam_mr_rl + \scriptfont \c_font_fam_mb_rl\scriptfont \c_font_fam_mr_rl + \scriptscriptfont\c_font_fam_mb_rl\scriptscriptfont\c_font_fam_mr_rl} \def\font_helpers_apply_complete_bold_mathstrategy {\ifconditional\c_font_complete_bold_mathstrategy @@ -425,13 +425,16 @@ \ifdefined\mathdefault \else \let\mathdefault\relax \fi +\newconditional\c_math_bold + \unexpanded\def\mr % math regular {\ifmmode \font_helpers_synchronize_math_family_mr \else \font_helpers_set_current_font_alternative\s!mr \fi - \mathdefault} + \mathdefault + \setfalse\c_math_bold} \unexpanded\def\mb % math bold {\ifmmode @@ -439,12 +442,17 @@ \else \font_helpers_set_current_font_alternative\s!mb \fi - \mathdefault} + \mathdefault + \settrue\c_math_bold} \appendtoks \font_helpers_synchronize_math_family % auto bold \to \everymathematics +\appendtoks + \ifconditional\c_math_bold\mb\fi +\to \everymathematics + %D \macros %D {bigmath,nobigmath} %D diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua index e1f158c83..c75b92984 100644 --- a/tex/context/base/mkiv/font-mis.lua +++ b/tex/context/base/mkiv/font-mis.lua @@ -8,20 +8,20 @@ if not modules then modules = { } end modules ['font-mis'] = { fonts = fonts or { } -fonts.helpers = fonts.helpers or { } -local helpers = fonts.helpers +local helpers = fonts.helpers or { } +fonts.helpers = helpers -fonts.handlers = fonts.handlers or { } -local handlers = fonts.handlers +local handlers = fonts.handlers or { } +fonts.handlers = handlers -handlers.otf = handlers.otf or { } -local otf = handlers.otf +local otf = handlers.otf or { } +handlers.otf = otf local readers = otf.readers if readers then - otf.version = otf.version or 3.103 + otf.version = otf.version or 3.107 otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true) function fonts.helpers.getfeatures(name,save) diff --git a/tex/context/base/mkiv/font-mps.lua b/tex/context/base/mkiv/font-mps.lua index cde34f2ae..895835958 100644 --- a/tex/context/base/mkiv/font-mps.lua +++ b/tex/context/base/mkiv/font-mps.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['font-mps'] = { license = "see context related readme files" } +local tostring = tostring local concat = table.concat local formatters = string.formatters @@ -35,6 +36,17 @@ local f_draw = formatters["draw %s;"] local f_boundingbox = formatters["((%.6F,%.6F)--(%.6F,%.6F)--(%.6F,%.6F)--(%.6F,%.6F)--cycle)"] local f_vertical = formatters["((%.6F,%.6F)--(%.6F,%.6F))"] +directives.register("metapost.stripzeros", function() + + f_moveto = formatters["(%.6N,%.6N)"] + f_lineto = formatters["--(%.6N,%.6N)"] + f_curveto = formatters["..controls(%.6N,%.6N)and(%.6N,%.6N)..(%.6N,%.6N)"] + + f_boundingbox = formatters["((%.6N,%.6N)--(%.6N,%.6N)--(%.6N,%.6N)--(%.6N,%.6N)--cycle)"] + f_vertical = formatters["((%.6N,%.6N)--(%.6N,%.6N))"] + +end) + function metapost.boundingbox(d,factor) local bounds = d.boundingbox local factor = factor or 1 @@ -97,9 +109,12 @@ function metapost.paths(d,xfactor,yfactor) elseif operator =="q" then -- "quadraticto" size = size + 1 -- first is always a moveto - local l_x, l_y = xfactor*sequence[i-2], yfactor*sequence[i-1] - local m_x, m_y = xfactor*sequence[i+1], yfactor*sequence[i+2] - local r_x, r_y = xfactor*sequence[i+3], yfactor*sequence[i+4] + local l_x = xfactor*sequence[i-2] + local l_y = yfactor*sequence[i-1] + local m_x = xfactor*sequence[i+1] + local m_y = yfactor*sequence[i+2] + local r_x = xfactor*sequence[i+3] + local r_y = yfactor*sequence[i+4] path[size] = f_curveto ( l_x + 2/3 * (m_x-l_x), l_y + 2/3 * (m_y-l_y), @@ -137,9 +152,12 @@ function metapost.paths(d,xfactor,yfactor) size = size + 1 -- first is always a moveto local prev = segments[i-1] - local l_x, l_y = xfactor*prev[#prev-2], yfactor*prev[#prev-1] - local m_x, m_y = xfactor*segment[1], yfactor*segment[2] - local r_x, r_y = xfactor*segment[3], yfactor*segment[4] + local l_x = xfactor*prev[#prev-2] + local l_y = yfactor*prev[#prev-1] + local m_x = xfactor*segment[1] + local m_y = yfactor*segment[2] + local r_x = xfactor*segment[3] + local r_y = yfactor*segment[4] path[size] = f_curveto ( l_x + 2/3 * (m_x-l_x), l_y + 2/3 * (m_y-l_y), @@ -196,7 +214,10 @@ function metapost.maxbounds(data,index,factor) local boundingbox = glyph.boundingbox local xmin, ymin, xmax, ymax if not maxbounds then - xmin, ymin, xmax, ymax = 0, 0, 0, 0 + xmin = 0 + ymin = 0 + xmax = 0 + ymax = 0 for i=1,#glyphs do local d = glyphs[i] if d then @@ -240,45 +261,52 @@ end -- right time. It's probably why I like watching https://www.youtube.com/watch?v=c5FqpddnJmc -- so much: precisely (and perfectly) timed too. -local nodecodes = nodes.nodecodes -- no nuts yet - -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local rule_code = nodecodes.rule - -local normal_rule = nodes.rulecodes.normal - -local nuts = nodes.nuts -local getnext = nuts.getnext -local getid = nuts.getid -local getlist = nuts.getlist -local getchar = nuts.getchar -local getfont = nuts.getfont -local getsubtype = nuts.getsubtype -local getfield = nuts.getfield -local getbox = nuts.getbox -local getwhd = nuts.getwhd -local getkern = nuts.getkern -local getshift = nuts.getshift -local getwidth = nuts.getwidth -local getheight = nuts.getheight -local getdepth = nuts.getdepth - -local effective_glue = nuts.effective_glue - -local characters = fonts.hashes.characters -local parameters = fonts.hashes.parameters -local shapes = fonts.hashes.shapes -local topaths = metapost.paths - -local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.6F,%.6F)(%,t);"] -local f_rule = formatters["mfun_do_outline_rule_flush(%q,%.6F,%.6F,%.6F,%.6F);"] -local f_bounds = formatters["checkbounds(%.6F,%.6F,%.6F,%.6F);"] -local s_nothing = "(origin scaled 10)" +local nodecodes = nodes.nodecodes -- no nuts yet +local rulecodes = nodes.rulecodes + +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local rule_code = nodecodes.rule + +local normalrule_code = rulecodes.normal + +local nuts = nodes.nuts +local getnext = nuts.getnext +local getid = nuts.getid +local getlist = nuts.getlist +local getsubtype = nuts.getsubtype +local getfield = nuts.getfield +local getbox = nuts.getbox +local getwhd = nuts.getwhd +local getkern = nuts.getkern +local getshift = nuts.getshift +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth +local getexpansion = nuts.getexpansion +local isglyph = nuts.isglyph + +local effective_glue = nuts.effective_glue + +local characters = fonts.hashes.characters +local parameters = fonts.hashes.parameters +local shapes = fonts.hashes.shapes +local topaths = metapost.paths + +local f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.6F,%.6F,%q)(%,t);"] +local f_rule = formatters["mfun_do_outline_rule_flush(%q,%.6F,%.6F,%.6F,%.6F);"] +local f_bounds = formatters["checkbounds(%.6F,%.6F,%.6F,%.6F);"] +local s_nothing = "(origin scaled 10)" + +directives.register("metapost.stripzeros", function() + f_code = formatters["mfun_do_outline_text_flush(%q,%i,%.6N,%.6N,%q)(%,t);"] + f_rule = formatters["mfun_do_outline_rule_flush(%q,%.6N,%.6N,%.6N,%.6N);"] + f_bounds = formatters["checkbounds(%.6N,%.6N,%.6N,%.6N);"] +end) local sc = 10 local fc = number.dimenfactors.bp * sc / 10 @@ -302,13 +330,14 @@ function metapost.output(kind,font,char,advance,shift,ex) local advance = advance or 0 local exfactor = ex or 0 local wfactor = 1 + local detail = kind == "p" and tostring(char) or "" if exfactor ~= 0 then wfactor = (1+(ex/units)/1000) xfactor = xfactor * wfactor end local paths = topaths(glyf,xfactor,yfactor) if paths then - local code = f_code(kind,#paths,advance,shift,paths) + local code = f_code(kind,#paths,advance,shift,detail,paths) return code, character.width * fc * wfactor else return "", 0 @@ -337,9 +366,9 @@ function fonts.metapost.boxtomp(n,kind) horizontal = function(parent,current,xoffset,yoffset) local dx = 0 while current do - local id = getid(current) - if id == glyph_code then - local code, width = metapost.output(kind,getfont(current),getchar(current),xoffset+dx,yoffset,getfield(current,"expansion_factor")) + local char, id = isglyph(current) + if char then + local code, width = metapost.output(kind,id,char,xoffset+dx,yoffset,getexpansion(current)) result[#result+1] = code dx = dx + width elseif id == disc_code then @@ -374,7 +403,7 @@ function fonts.metapost.boxtomp(n,kind) dp = getdepth(parent) end local hd = (ht + dp) * fc - if hd ~= 0 and getsubtype(current) == normal_rule then + if hd ~= 0 and getsubtype(current) == normalrule_code then result[#result+1] = f_rule(kind,xoffset+dx+wd/2,yoffset+hd/2,wd,hd) end dx = dx + wd diff --git a/tex/context/base/mkiv/font-nod.lua b/tex/context/base/mkiv/font-nod.lua index 2670a924b..a0eb88a25 100644 --- a/tex/context/base/mkiv/font-nod.lua +++ b/tex/context/base/mkiv/font-nod.lua @@ -32,6 +32,10 @@ nodes.tasks = tasks local handlers = nodes.handlers or { } nodes.handlers = handlers +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + local injections = nodes.injections or { } nodes.injections = injections @@ -52,23 +56,17 @@ local kern_code = nodecodes.kern local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid local getfont = nuts.getfont local getsubtype = nuts.getsubtype -local getchar = nuts.getchar local getlist = nuts.getlist local getdisc = nuts.getdisc -local getcomponents = nuts.getcomponents local isglyph = nuts.isglyph local getkern = nuts.getkern -local getdir = nuts.getdir +local getdirection = nuts.getdirection local getwidth = nuts.getwidth local setbox = nuts.setbox @@ -78,10 +76,11 @@ local setsubtype = nuts.setsubtype local copy_node_list = nuts.copy_list local hpack_node_list = nuts.hpack local flush_node_list = nuts.flush_list -local traverse_nodes = nuts.traverse ------ traverse_id = nuts.traverse_id local protect_glyphs = nuts.protect_glyphs +local nextnode = nuts.traversers.node +local nextglyph = nuts.traversers.glyph + local nodepool = nuts.pool local new_glyph = nodepool.glyph @@ -98,11 +97,8 @@ local fontparameters = hashes.parameters local properties = nodes.properties.data --- direct.set_properties_mode(true,false) --- direct.set_properties_mode(true,true) -- default - local function freeze(h,where) - for n in traverse_nodes(tonut(h)) do -- todo: disc but not traced anyway + for n in nextnode, h do -- todo: disc but not traced anyway local p = properties[n] if p then local i = p.injections if i then p.injections = fastcopy(i) end @@ -115,15 +111,15 @@ local function freeze(h,where) end function char_tracers.collect(head,list,tag,n) - head = tonut(head) n = n or 0 - local ok, fn = false, nil + local ok = false + local fn = nil while head do - local c, id = isglyph(head) - if c then - local f = getfont(head) - if f ~= fn then - ok, fn = false, f + local char, id = isglyph(head) + if char then + local font = id + if font ~= fn then + ok, fn = false, font end if not ok then ok = true @@ -132,23 +128,23 @@ function char_tracers.collect(head,list,tag,n) list[n][tag] = { } end local l = list[n][tag] - -- l[#l+1] = { c, f, i } - l[#l+1] = { c, f } + -- l[#l+1] = { char, font, i } + l[#l+1] = { char, font } elseif id == disc_code then -- skip -- local pre, post, replace = getdisc(head) -- if replace then - -- for n in traverse_id(glyph_code,replace) do + -- for n in nextglyph, replace do -- l[#l+1] = { c, f } -- end -- end -- if pre then - -- for n in traverse_id(glyph_code,pre) do + -- for n in nextglyph, pre do -- l[#l+1] = { c, f } -- end -- end -- if post then - -- for n in traverse_id(glyph_code,post) do + -- for n in nextglyph, post do -- l[#l+1] = { c, f } -- end -- end @@ -164,7 +160,8 @@ function char_tracers.equal(ta, tb) return false else for i=1,#ta do - local a, b = ta[i], tb[i] + local a = ta[i] + local b = tb[i] -- if a[1] ~= b[1] or a[2] ~= b[2] or a[3] ~= b[3] then if a[1] ~= b[1] or a[2] ~= b[2] then return false @@ -221,12 +218,12 @@ function char_tracers.start() function handlers.characters(head) local n = #list char_tracers.collect(head,list,'before',n) - local h, d = npc(tonode(head)) -- for the moment tonode + head = npc(head) -- for the moment tonode char_tracers.collect(head,list,'after',n) if #list > n then list[#list+1] = { } end - return h, d + return head end function char_tracers.stop() tracers.list['characters'] = list @@ -297,47 +294,44 @@ end function step_tracers.features() -- we cannot use first_glyph here as it only finds characters with subtype < 256 local f = collection[1] - while f do - if getid(f) == glyph_code then - local tfmdata = fontidentifiers[getfont(f)] - local features = tfmdata.resources.features - local result_1 = { } - local result_2 = { } - local gpos = features and features.gpos or { } - local gsub = features and features.gsub or { } - for feature, value in table.sortedhash(tfmdata.shared.features) do - if feature == "number" or feature == "features" then - value = false - elseif type(value) == "boolean" then - if value then - value = "yes" - else - value = false - end - else - -- use value - end + for n, char, font in nextglyph, f do + local tfmdata = fontidentifiers[font] + local features = tfmdata.resources.features + local result_1 = { } + local result_2 = { } + local gpos = features and features.gpos or { } + local gsub = features and features.gsub or { } + for feature, value in table.sortedhash(tfmdata.shared.features) do + if feature == "number" or feature == "features" then + value = false + elseif type(value) == "boolean" then if value then - if gpos[feature] or gsub[feature] or feature == "language" or feature == "script" then - result_1[#result_1+1] = formatters["%s=%s"](feature,value) - else - result_2[#result_2+1] = formatters["%s=%s"](feature,value) - end + value = "yes" + else + value = false end - end - if #result_1 > 0 then - context("{\\bf[basic:} %, t{\\bf]} ",result_1) else - context("{\\bf[}no basic features{\\bf]} ") + -- use value end - if #result_2 > 0 then - context("{\\bf[extra:} %, t{\\bf]}",result_2) - else - context("{\\bf[}no extra features{\\bf]}") + if value then + if gpos[feature] or gsub[feature] or feature == "language" or feature == "script" then + result_1[#result_1+1] = formatters["%s=%s"](feature,value) + else + result_2[#result_2+1] = formatters["%s=%s"](feature,value) + end end - return end - f = getnext(f) + if #result_1 > 0 then + context("{\\bf[basic:} %, t{\\bf]} ",result_1) + else + context("{\\bf[}no basic features{\\bf]} ") + end + if #result_2 > 0 then + context("{\\bf[extra:} %, t{\\bf]}",result_2) + else + context("{\\bf[}no extra features{\\bf]}") + end + return end end @@ -349,21 +343,15 @@ end function step_tracers.font(command) local c = collection[1] - while c do - local id = getid(c) - if id == glyph_code then - local font = getfont(c) - local name = file.basename(fontproperties[font].filename or "unknown") - local size = fontparameters[font].size or 0 - if command then - context[command](font,name,size) -- size in sp - else - context("[%s: %s @ %p]",font,name,size) - end - return + for n, char, font in nextglyph, c do + local name = file.basename(fontproperties[font].filename or "unknown") + local size = fontparameters[font].size or 0 + if command then + context[command](font,name,size) -- size in sp else - c = getnext(c) + context("[%s: %s @ %p]",font,name,size) end + return end end @@ -376,9 +364,7 @@ local colors = { function step_tracers.codes(i,command,space) local c = collection[i] - local function showchar(c) - local f = getfont(c) - local c = getchar(c) + local function showchar(c,f) if command then local d = fontdescriptions[f] local d = d and d[c] @@ -392,10 +378,10 @@ function step_tracers.codes(i,command,space) if w then context.startcolor(colors[what]) context("%s:",what) - for c in traverse_nodes(w) do - local id = getid(c) + for c, id in nextnode, w do if id == glyph_code then - showchar(c) + local c, f = isglyph(c) + showchar(c,f) else context("[%s]",nodecodes[id]) end @@ -406,11 +392,11 @@ function step_tracers.codes(i,command,space) end while c do - local id = getid(c) - if id == glyph_code then - showchar(c) - elseif id == dir_code or id == localpar_code then - context("[%s]",getdir(c)) + local char, id = isglyph(c) + if char then + showchar(char,id) + elseif id == dir_code or (id == localpar_code and getsubtype(c) == 0) then + context("[%s]",getdirection(c) or "?") elseif id == disc_code then local pre, post, replace = getdisc(c) if pre or post or replace then @@ -453,13 +439,12 @@ end function step_tracers.check(head) if collecting then step_tracers.reset() - local h = tonut(head) - local n = copy_node_list(h) + local n = copy_node_list(head) freeze(n,"check") - injections.keepcounts(n) -- one-time + injections.keepcounts() -- one-time local l = injections.handler(n,"trace") if l then -- hm, can be false - n = tonut(l) + n = l end protect_glyphs(n) collection[1] = n @@ -470,13 +455,12 @@ function step_tracers.register(head) if collecting then local nc = #collection+1 if messages[nc] then - local h = tonut(head) - local n = copy_node_list(h) + local n = copy_node_list(head) freeze(n,"register") - injections.keepcounts(n) -- one-time + injections.keepcounts() -- one-time local l = injections.handler(n,"trace") if l then -- hm, can be false - n = tonut(l) + n = l end protect_glyphs(n) collection[nc] = n @@ -501,14 +485,11 @@ local threshold = 65536 -- 1pt local function toutf(list,result,nofresult,stopcriterium,nostrip) if list then - for n in traverse_nodes(tonut(list)) do - local c, id = isglyph(n) - if c then - local components = getcomponents(n) - if components then - result, nofresult = toutf(components,result,nofresult,false,true) - elseif c > 0 then - local fc = fontcharacters[getfont(n)] + for n, id in nextnode, tonut(list) do + if id == glyph_code then + local c, f = isglyph(n) + if c > 0 then + local fc = fontcharacters[f] if fc then local fcc = fc[c] if fcc then diff --git a/tex/context/base/mkiv/font-ocl.lua b/tex/context/base/mkiv/font-ocl.lua index b17cf991d..0976cdb21 100644 --- a/tex/context/base/mkiv/font-ocl.lua +++ b/tex/context/base/mkiv/font-ocl.lua @@ -13,13 +13,20 @@ local round, max = math.round, math.round local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash local setmetatableindex = table.setmetatableindex -local formatters = string.formatters -local tounicode = fonts.mappings.tounicode +local formatters = string.formatters +local tounicode = fonts.mappings.tounicode -local otf = fonts.handlers.otf +local helpers = fonts.helpers -local f_color = formatters["%.3f %.3f %.3f rg"] -local f_gray = formatters["%.3f g"] +local charcommand = helpers.commands.char +local rightcommand = helpers.commands.right +local leftcommand = helpers.commands.left +local downcommand = helpers.commands.down + +local otf = fonts.handlers.otf + +local f_color = formatters["%.3f %.3f %.3f rg"] +local f_gray = formatters["%.3f g"] if context then @@ -56,31 +63,41 @@ end) if context then + -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] -- looks bad + -- \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray] -- looks okay + local colors = attributes.list[attributes.private('color')] or { } local transparencies = attributes.list[attributes.private('transparency')] or { } function otf.registerpalette(name,values) sharedpalettes[name] = values + local color = lpdf.color + local transparency = lpdf.transparency + local register = colors.register for i=1,#values do local v = values[i] - local c = nil - local t = nil - if type(v) == "table" then - c = colors.register(name,"rgb", - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - ) + if v == "textcolor" then + values[i] = false else - c = colors[v] - t = transparencies[v] - end - if c and t then - values[i] = hash[lpdf.color(1,c) .. " " .. lpdf.transparency(t)] - elseif c then - values[i] = hash[lpdf.color(1,c)] - elseif t then - values[i] = hash[lpdf.color(1,t)] + local c = nil + local t = nil + if type(v) == "table" then + c = register(name,"rgb", + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + ) + else + c = colors[v] + t = transparencies[v] + end + if c and t then + values[i] = hash[color(1,c) .. " " .. transparency(t)] + elseif c then + values[i] = hash[color(1,c)] + elseif t then + values[i] = hash[color(1,t)] + end end end end @@ -91,11 +108,13 @@ else -- for generic sharedpalettes[name] = values for i=1,#values do local v = values[i] - values[i] = hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] + if v then + values[i] = hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end end end @@ -127,16 +146,11 @@ local start = { "pdf", "mode", "font" } -- force text mode (so get q Q right) local push = { "pdf", "page", "q" } local pop = { "pdf", "page", "Q" } -if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY < 6472 then - start = { "nop" } - ----- = stop -end - -- -- This one results in color directives inside BT ET but has less q Q pairs. It -- -- only shows the first glyph in acrobat and nothing more. No problem with other -- -- renderers. -- --- local function initializecolr(tfmdata,kind,value) -- hm, always value +-- local function initialize(tfmdata,kind,value) -- hm, always value -- if value then -- local resources = tfmdata.resources -- local palettes = resources.colorpalettes @@ -161,11 +175,6 @@ end -- tfmdata.fonts = { -- { id = 0 } -- } --- local widths = setmetatableindex(function(t,k) --- local v = { "right", -k } --- t[k] = v --- return v --- end) -- -- -- local getactualtext = otf.getactualtext -- local default = colorvalues[#colorvalues] @@ -173,12 +182,6 @@ end -- local actualb = { "pdf", "page", b } -- saves tables -- local actuale = { "pdf", "page", e } -- saves tables -- -- --- local cache = setmetatableindex(function(t,k) --- local v = { "char", k } -- could he a weak shared hash --- t[k] = v --- return v --- end) --- -- -- for unicode, character in next, characters do -- local description = descriptions[unicode] -- if description then @@ -187,7 +190,7 @@ end -- local u = description.unicode or characters[unicode].unicode -- local w = character.width or 0 -- local s = #colorlist --- local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same +-- local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same -- local t = { -- start, -- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } @@ -202,7 +205,7 @@ end -- n = n + 1 t[n] = v -- l = v -- end --- n = n + 1 t[n] = cache[entry.slot] +-- n = n + 1 t[n] = charcommand[entry.slot] -- if s > 1 and i < s and goback then -- n = n + 1 t[n] = goback -- end @@ -221,7 +224,7 @@ end -- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat -- -- fails displaying the overlays correctly. Other renderers do it right. -local function initializecolr(tfmdata,kind,value) -- hm, always value +local function initialize(tfmdata,kind,value) if value then local resources = tfmdata.resources local palettes = resources.colorpalettes @@ -232,8 +235,14 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value converted = setmetatableindex(convert) resources.converted = converted end - local colorvalues = sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or { } - local classes = #colorvalues + local colorvalues = sharedpalettes[value] + local default = false -- so the text color (bad for icon overloads) + if colorvalues then + default = colorvalues[#colorvalues] + else + colorvalues = converted[palettes[tonumber(value) or 1] or palettes[1]] or { } + end + local classes = #colorvalues if classes == 0 then return end @@ -246,24 +255,12 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value tfmdata.fonts = { { id = 0 } } - local widths = setmetatableindex(function(t,k) - local v = { "right", -k } - t[k] = v - return v - end) -- local getactualtext = otf.getactualtext - local default = colorvalues[#colorvalues] local b, e = getactualtext(tounicode(0xFFFD)) local actualb = { "pdf", "page", b } -- saves tables local actuale = { "pdf", "page", e } -- saves tables -- - local cache = setmetatableindex(function(t,k) - local v = { "char", k } -- could he a weak shared hash - t[k] = v - return v - end) - -- for unicode, character in next, characters do local description = descriptions[unicode] if description then @@ -272,7 +269,7 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value local u = description.unicode or characters[unicode].unicode local w = character.width or 0 local s = #colorlist - local goback = w ~= 0 and widths[w] or nil -- needs checking: are widths the same + local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same local t = { start, -- really needed not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } @@ -291,8 +288,14 @@ local function initializecolr(tfmdata,kind,value) -- hm, always value f = true n = n + 1 t[n] = v l = v + else + if f then + n = n + 1 t[n] = pop + end + f = false + l = nil end - n = n + 1 t[n] = cache[entry.slot] + n = n + 1 t[n] = charcommand[entry.slot] if s > 1 and i < s and goback then n = n + 1 t[n] = goback end @@ -314,80 +317,60 @@ fonts.handlers.otf.features.register { name = "colr", description = "color glyphs", manipulators = { - base = initializecolr, - node = initializecolr, + base = initialize, + node = initialize, } } do - -- local f_setstream = formatters[ [[io.savedata("svg-glyph-%05i",%q)]] ] - -- local f_getstream = formatters[ [[svg-glyph-%05i]] ] - - -- function otfsvg.storepdfdata(pdf) - -- nofstreams = nofstreams + 1 - -- storepdfdata = function(pdf) - -- nofstreams = nofstreams + 1 - -- return f_setstream(nofstreams,pdf), f_getstream(nofstreams) - -- end - -- end - local nofstreams = 0 local f_name = formatters[ [[pdf-glyph-%05i]] ] local f_used = context and formatters[ [[original:///%s]] ] or formatters[ [[%s]] ] local hashed = { } local cache = { } - function otf.storepdfdata(pdf) - local done = hashed[pdf] - if not done then - nofstreams = nofstreams + 1 - local o, n = epdf.openMemStream(pdf,#pdf,f_name(nofstreams)) - cache[n] = o -- we need to keep in mem - done = f_used(n) - hashed[pdf] = done + if epdf then + + local openpdf = epdf.openMemStream + + function otf.storepdfdata(pdf) + local done = hashed[pdf] + if not done then + nofstreams = nofstreams + 1 + local o, n = openpdf(pdf,#pdf,f_name(nofstreams)) + cache[n] = o -- we need to keep in mem + done = f_used(n) + hashed[pdf] = done + end + return done + end + + else + + local openpdf = pdfe.new + ----- prefix = "data:application/pdf," + + function otf.storepdfdata(pdf) + local done = hashed[pdf] + if not done then + nofstreams = nofstreams + 1 + local f = f_name(nofstreams) + local n = openpdf(pdf,#pdf,f) + done = f_used(n) + hashed[pdf] = done + end + return done end - return nil, done, nil - end - -- maybe more efficient but much slower (and we hash already) - -- - -- if context then - -- - -- local storepdfdata = otf.storepdfdata - -- local initialized = false - -- - -- function otf.storepdfdata(pdf) - -- if not initialized then - -- if resolvers.setmemstream then - -- local f_setstream = formatters[ [[resolvers.setmemstream("pdf-glyph-%05i",%q,true)]] ] - -- local f_getstream = formatters[ [[memstream:///pdf-glyph-%05i]] ] - -- local f_nilstream = formatters[ [[resolvers.resetmemstream("pdf-glyph-%05i",true)]] ] - -- storepdfdata = function(pdf) - -- local done = hashed[pdf] - -- local set = nil - -- local reset = nil - -- if not done then - -- nofstreams = nofstreams + 1 - -- set = f_setstream(nofstreams,pdf) - -- done = f_getstream(nofstreams) - -- reset = f_nilstream(nofstreams) - -- hashed[pdf] = done - -- end - -- return set, done, reset - -- end - -- otf.storepdfdata = storepdfdata - -- end - -- initialized = true - -- end - -- return storepdfdata(pdf) - -- end - -- - -- end + end end -local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg +-- I'll probably make a variant for context as we can do it more efficient there than in +-- generic. + +local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg if not tfmdata or not pdfshapes or not kind then return end @@ -400,7 +383,7 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg properties.virtualized = true -- tfmdata.fonts = { - { id = 0 } + { id = 0 } -- not really needed } -- local getactualtext = otf.getactualtext @@ -410,6 +393,12 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg local actualb = { "pdf", "page", b } -- saves tables local actuale = { "pdf", "page", e } -- saves tables -- + local vfimage = lpdf and lpdf.vfimage or function(wd,ht,dp,data,name) + -- needed for generic (if used there at all) + local name = storepdfdata(data) + return { "image", { filename = name, width = wd, height = ht, depth = dp } } + end + -- for unicode, character in sortedhash(characters) do -- sort is nicer for svg local index = character.index if index then @@ -428,31 +417,30 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = sbix|svg dy = 0 end if data then - local setcode, name, nilcode = storepdfdata(data) - if name then - local bt = unicode and getactualtext(unicode) - local wd = character.width or 0 - local ht = character.height or 0 - local dp = character.depth or 0 - character.commands = { - not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) }, - { "down", dp + dy * hfactor }, - { "right", dx * hfactor }, - -- setcode and { "lua", setcode } or nop, - { "image", { filename = name, width = wd, height = ht, depth = dp } }, - -- nilcode and { "lua", nilcode } or nop, - actuale, - } - character[kind] = true - end + -- We can delay storage by a lua function in commands: but then we need to + -- be able to provide our own mem stream name (so that we can reserve it). + -- Anyway, we will do this different in a future version of context. + local bt = unicode and getactualtext(unicode) + local wd = character.width or 0 + local ht = character.height or 0 + local dp = character.depth or 0 + -- The down and right will change too (we can move that elsewhere). + character.commands = { + not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) }, + downcommand[dp + dy * hfactor], + rightcommand[dx * hfactor], + vfimage(wd,ht,dp,data,name), + actuale, + } + character[kind] = true end end end end local otfsvg = otf.svg or { } -otf.svg = otfsvg -otf.svgenabled = true +otf.svg = otfsvg +otf.svgenabled = true do @@ -583,27 +571,27 @@ fonts.handlers.otf.features.register { -- This can be done differently e.g. with ffi and gm and we can share code anway. Using -- batchmode in gm is not faster and as it accumulates we would need to flush all --- individual shapes. +-- individual shapes. But ... in context lmtx (and maybe the backport) we will use +-- a different and more efficient method anyway. I'm still wondering if I should +-- keep color code in generic. Maybe it should be optional. -local otfsbix = otf.sbix or { } -otf.sbix = otfsbix -otf.sbixenabled = true +local otfpng = otf.png or { } +otf.png = otfpng +otf.pngenabled = true do - -- for now png but also other bitmap formats - - local report_sbix = logs.reporter("fonts","sbix conversion") + local report_png = logs.reporter("fonts","png conversion") local loaddata = io.loaddata local savedata = io.savedata local remove = os.remove local runner = sandbox and sandbox.registerrunner { - name = "otfsbix", + name = "otfpng", program = "gm", - template = "convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log", - -- reporter = report_sbix, + template = "convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", + -- reporter = report_png, } if not runner then @@ -611,29 +599,29 @@ do -- poor mans variant for generic: -- runner = function() - return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log") + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") end end -- Alternatively we can create a single pdf file with -adjoin and then pick up pages from -- that file but creating thousands of small files is no fun either. - function otfsbix.topdf(sbixshapes) + function otfpng.topdf(pngshapes) local pdfshapes = { } - local sbixfile = "temp-otf-sbix-shape.sbix" - local pdffile = "temp-otf-sbix-shape.pdf" + local pngfile = "temp-otf-png-shape.png" + local pdffile = "temp-otf-png-shape.pdf" local nofdone = 0 - local indices = sortedkeys(sbixshapes) -- can be sparse + local indices = sortedkeys(pngshapes) -- can be sparse local nofindices = #indices - report_sbix("processing %i sbix containers",nofindices) + report_png("processing %i png containers",nofindices) statistics.starttiming() for i=1,nofindices do local index = indices[i] - local entry = sbixshapes[index] - local data = entry.data + local entry = pngshapes[index] + local data = entry.data -- or placeholder local x = entry.x local y = entry.y - savedata(sbixfile,data) + savedata(pngfile,data) runner() pdfshapes[index] = { x = x ~= 0 and x or nil, @@ -642,43 +630,44 @@ do } nofdone = nofdone + 1 if nofdone % 100 == 0 then - report_sbix("%i shapes processed",nofdone) + report_png("%i shapes processed",nofdone) end end - report_sbix("processing %i pdf results",nofindices) - remove(sbixfile) + report_png("processing %i pdf results",nofindices) + remove(pngfile) remove(pdffile) statistics.stoptiming() if statistics.elapsedseconds then - report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") + report_png("png conversion time %s",statistics.elapsedseconds() or "-") end return pdfshapes - -- end end end -local function initializesbix(tfmdata,kind,value) -- hm, always value - if value and otf.sbixenabled then - local sbix = tfmdata.properties.sbix - local hash = sbix and sbix.hash - local timestamp = sbix and sbix.timestamp +-- This will change in a future version of context. More direct. + +local function initializepng(tfmdata,kind,value) -- hm, always value + if value and otf.pngenabled then + local png = tfmdata.properties.png + local hash = png and png.hash + local timestamp = png and png.timestamp if not hash then return end local pdffile = containers.read(otf.pdfcache,hash) local pdfshapes = pdffile and pdffile.pdfshapes if not pdfshapes or pdffile.timestamp ~= timestamp then - local sbixfile = containers.read(otf.sbixcache,hash) - local sbixshapes = sbixfile and sbixfile.sbixshapes - pdfshapes = sbixshapes and otfsbix.topdf(sbixshapes) or { } + local pngfile = containers.read(otf.pngcache,hash) + local pngshapes = pngfile and pngfile.pngshapes + pdfshapes = pngshapes and otfpng.topdf(pngshapes) or { } containers.write(otf.pdfcache, hash, { pdfshapes = pdfshapes, timestamp = timestamp, }) end -- - pdftovirtual(tfmdata,pdfshapes,"sbix") + pdftovirtual(tfmdata,pdfshapes,"png") end end @@ -686,8 +675,16 @@ fonts.handlers.otf.features.register { name = "sbix", description = "sbix glyphs", manipulators = { - base = initializesbix, - node = initializesbix, + base = initializepng, + node = initializepng, } } +fonts.handlers.otf.features.register { + name = "cblc", + description = "cblc glyphs", + manipulators = { + base = initializepng, + node = initializepng, + } +} diff --git a/tex/context/base/mkiv/font-one.lua b/tex/context/base/mkiv/font-one.lua index a3dc7b038..18ba51185 100644 --- a/tex/context/base/mkiv/font-one.lua +++ b/tex/context/base/mkiv/font-one.lua @@ -86,14 +86,16 @@ function afm.load(filename) local name = file.removesuffix(file.basename(filename)) local data = containers.read(afm.cache,name) local attr = lfs.attributes(filename) - local size, time = attr.size or 0, attr.modification or 0 + local size = attr and attr.size or 0 + local time = attr and attr.modification or 0 -- local pfbfile = file.replacesuffix(name,"pfb") local pfbname = resolvers.findfile(pfbfile,"pfb") or "" if pfbname == "" then pfbname = resolvers.findfile(file.basename(pfbfile),"pfb") or "" end - local pfbsize, pfbtime = 0, 0 + local pfbsize = 0 + local pfbtime = 0 if pfbname ~= "" then local attr = lfs.attributes(pfbname) pfbsize = attr.size or 0 @@ -106,6 +108,7 @@ function afm.load(filename) afmenhancers.apply(data,filename) -- otfreaders.addunicodetable(data) -- only when not done yet fonts.mappings.addtounicode(data,filename) + otfreaders.stripredundant(data) -- otfreaders.extend(data) otfreaders.pack(data) data.size = size @@ -323,7 +326,8 @@ local addthem = function(rawdata,ligatures) local one = descriptions[unicodes[ligname]] if one then for _, pair in next, ligdata do - local two, three = unicodes[pair[1]], unicodes[pair[2]] + local two = unicodes[pair[1]] + local three = unicodes[pair[2]] if two and three then local ol = one.ligatures if ol then @@ -391,7 +395,7 @@ local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust h if what then for complex, simple in next, what do complex = unicodes[complex] - simple = unicodes[simple] + simple = unicodes[simple] if complex and simple then local complexdescription = descriptions[complex] if complexdescription then -- optional @@ -444,7 +448,8 @@ local function adddimensions(data) -- we need to normalize afm to otf i.e. index for unicode, description in next, data.descriptions do local bb = description.boundingbox if bb then - local ht, dp = bb[4], -bb[2] + local ht = bb[4] + local dp = -bb[2] if ht == 0 or ht < 0 then -- no need to set it and no negative heights, nil == 0 else diff --git a/tex/context/base/mkiv/font-onr.lua b/tex/context/base/mkiv/font-onr.lua index 26a782649..8523d8729 100644 --- a/tex/context/base/mkiv/font-onr.lua +++ b/tex/context/base/mkiv/font-onr.lua @@ -26,7 +26,7 @@ local match, lower, gsub, strip, find = string.match, string.lower, string.gsub, local char, byte, sub = string.char, string.byte, string.sub local abs = math.abs local bxor, rshift = bit32.bxor, bit32.rshift -local P, S, R, Cmt, C, Ct, Cs, Carg, Cf, Cg = lpeg.P, lpeg.S, lpeg.R, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg +local P, S, R, V, Cmt, C, Ct, Cs, Carg, Cf, Cg, Cc = lpeg.P, lpeg.S, lpeg.R, lpeg.V, lpeg.Cmt, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.Carg, lpeg.Cf, lpeg.Cg, lpeg.Cc local lpegmatch, patterns = lpeg.match, lpeg.patterns local trace_indexing = false trackers.register("afm.indexing", function(v) trace_indexing = v end) @@ -83,31 +83,40 @@ do end - local charstrings = P("/CharStrings") - local subroutines = P("/Subrs") - local encoding = P("/Encoding") - local dup = P("dup") - local put = P("put") - local array = P("array") - local name = P("/") * C((R("az","AZ","09")+S("-_."))^1) - local digits = R("09")^1 - local cardinal = digits / tonumber - local spaces = P(" ")^1 - local spacing = patterns.whitespace^0 + local charstrings = P("/CharStrings") + local subroutines = P("/Subrs") + local encoding = P("/Encoding") + local dup = P("dup") + local put = P("put") + local array = P("array") + local name = P("/") * C((R("az","AZ","09")+S("-_."))^1) + local digits = R("09")^1 + local cardinal = digits / tonumber + local spaces = P(" ")^1 + local spacing = patterns.whitespace^0 local routines, vector, chars, n, m local initialize = function(str,position,size) n = 0 - m = size -- % tonumber(size) + m = size return position + 1 end local setroutine = function(str,position,index,size,filename) - local forward = position + tonumber(size) + if routines[index] then + -- we have passed the end + return false + end + local forward = position + size local stream = decrypt(sub(str,position+1,forward),4330,4) routines[index] = { byte(stream,1,#stream) } - return forward + n = n + 1 + if n >= m then + -- m should be index now but can we assume ordering? + return #str + end + return forward + 1 end local setvector = function(str,position,name,size,filename) @@ -152,7 +161,7 @@ do local p_filterroutines = -- dup RD or -| NP or | (1-subroutines)^0 * subroutines * spaces * Cmt(cardinal,initialize) - * (Cmt(cardinal * spaces * cardinal * p_rd * Carg(1), setroutine) * p_np + P(1))^1 + * (Cmt(cardinal * spaces * cardinal * p_rd * Carg(1), setroutine) * p_np + (1-p_nd))^1 local p_filtershapes = -- /foo RD ND (1-charstrings)^0 * charstrings * spaces * Cmt(cardinal,initialize) @@ -175,7 +184,33 @@ do -- if one of first 4 not 0-9A-F then binary else hex - local function loadpfbvector(filename,shapestoo) + local key = spacing * P("/") * R("az","AZ") + local str = spacing * Cs { (P("(")/"") * ((1 - P("\\(") - P("\\)") - S("()")) + V(1))^0 * (P(")")/"") } + local num = spacing * (R("09") + S("+-."))^1 / tonumber + local arr = spacing * Ct (S("[{") * (num)^0 * spacing * S("]}")) + local boo = spacing * (P("true") * Cc(true) + P("false") * Cc(false)) + local nam = spacing * P("/") * Cs(R("az","AZ")^1) + + local p_filtermetadata = ( + P("/") * Carg(1) * ( ( + C("version") * str + + C("Copyright") * str + + C("Notice") * str + + C("FullName") * str + + C("FamilyName") * str + + C("Weight") * str + + C("ItalicAngle") * num + + C("isFixedPitch") * boo + + C("UnderlinePosition") * num + + C("UnderlineThickness") * num + + C("FontName") * nam + + C("FontMatrix") * arr + + C("FontBBox") * arr + ) ) / function(t,k,v) t[lower(k)] = v end + + P(1) + )^0 * Carg(1) + + local function loadpfbvector(filename,shapestoo,streams) -- for the moment limited to encoding only local data = io.loaddata(resolvers.findfile(filename)) @@ -200,11 +235,14 @@ do binary = decrypt(binary,55665,4) local names = { } + local encoding = lpegmatch(p_filterencoding,ascii) + local metadata = lpegmatch(p_filtermetadata,ascii,1,{}) local glyphs = { } routines, vector, chars = { }, { }, { } - if shapestoo then + if shapestoo or streams then + -- io.savedata("foo.txt",binary) lpegmatch(p_filterroutines,binary,1,filename) lpegmatch(p_filtershapes,binary,1,filename) local data = { @@ -216,7 +254,8 @@ do } }, } - fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,true) + -- only cff 1 in type 1 fonts + fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams) else lpegmatch(p_filternames,binary,1,filename) end @@ -225,7 +264,7 @@ do routines, vector, chars = nil, nil, nil - return names, encoding, glyphs + return names, encoding, glyphs, metadata end diff --git a/tex/context/base/mkiv/font-osd.lua b/tex/context/base/mkiv/font-osd.lua index 9f99fd57f..32d791b48 100644 --- a/tex/context/base/mkiv/font-osd.lua +++ b/tex/context/base/mkiv/font-osd.lua @@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag license = "see context related readme files" } + +-- we need to check nbsphash (context only) + -- A few remarks: -- -- This code is a partial rewrite of the code that deals with devanagari. The data @@ -96,8 +99,6 @@ local otffeatures = fonts.constructors.features.otf local registerotffeature = otffeatures.register local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut local getnext = nuts.getnext local getprev = nuts.getprev @@ -152,47 +153,27 @@ replace_all_nbsp = function(head) -- delayed definition return replace_all_nbsp(head) end -local xprocesscharacters = nil +local processcharacters = nil if context then - xprocesscharacters = function(head,font) - xprocesscharacters = nodes.handlers.characters - return xprocesscharacters(head,font) + local fontprocesses = fonts.hashes.processes + function processcharacters(head,font) + local processors = fontprocesses[font] + for i=1,#processors do + head = processors[i](head,font,0) + end + return head end else - xprocesscharacters = function(head,font) - xprocesscharacters = nodes.handlers.nodepass -- generic - return xprocesscharacters(head,font) + function processcharacters(head,font) + local processors = fontdata[font].shared.processes + for i=1,#processors do + head = processors[i](head,font,0) + end + return head end end -local function processcharacters(head,font) - return tonut(xprocesscharacters(tonode(head))) -- can be more efficient in context, just direct call -end - --- to be tested: --- --- local processcharacters = nil --- --- if context then --- local fontprocesses = fonts.hashes.processes --- function processcharacters(head,font) --- local processors = fontprocesses[font] --- for i=1,#processors do --- head = processors[i](head,font,0) --- end --- return head, true --- end --- else --- function processcharacters(head,font) --- local processors = fontdata[font].shared.processes --- for i=1,#processors do --- head = processors[i](head,font,0) --- end --- return head, true --- end --- end - -- We can assume that script are not mixed in the source but if that is the case -- we might need to have consonants etc per script and initialize a local table -- pointing to the right one. But not now. @@ -293,10 +274,6 @@ if not indicgroups and characters then characters.indicgroups = indicgroups -else - - indicgroups = table.setmetatableindex("table") - end local consonant = indicgroups.consonant @@ -422,19 +399,19 @@ local sequence_remove_joiners = { -- as it might depends on the font. Not that it's a bottleneck. local basic_shaping_forms = { - init = true, -- new - abvs = true, -- new + -- init = true, -- new + -- abvs = true, -- new akhn = true, blwf = true, - calt = true, -- new + -- calt = true, -- new cjct = true, half = true, - haln = true, -- new + -- haln = true, -- new nukt = true, pref = true, - pres = true, -- new + -- pres = true, -- new pstf = true, - psts = true, -- new + -- psts = true, -- new rkrf = true, rphf = true, vatu = true, @@ -605,9 +582,7 @@ local function initializedevanagi(tfmdata) end end end -if reph then - seqsubset[#seqsubset+1] = { kind, coverage, reph } -end + seqsubset[#seqsubset+1] = { kind, coverage, reph } end end end @@ -691,6 +666,19 @@ registerotffeature { }, } +local show_syntax_errors = false + +local function inject_syntax_error(head,current,char) + local signal = copy_node(current) + copyinjection(signal,current) + if pre_mark[char] then + setchar(signal,dotted_circle) + else + setchar(current,dotted_circle) + end + return insert_node_after(head,current,signal) +end + -- hm, this is applied to one character: local function initialize_one(font,attr) -- we need a proper hook into the dataset initializer @@ -793,10 +781,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) setprop(tempcurrent,a_state,unsetvalue) if getchar(next) == getchar(tempcurrent) then flush_list(tempcurrent) - local n = copy_node(current) - copyinjection(n,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set - setchar(current,dotted_circle) - head = insert_node_after(head, current, n) + if show_syntax_errors then + head, current = inject_syntax_error(head,current,char) + end else setchar(current,getchar(tempcurrent)) -- we assumes that the result of blwf consists of one node local freenode = getnext(current) @@ -1217,7 +1204,7 @@ function handlers.devanagari_reorder_reph(head,start) while current do local char = ischar(current,startfont) if char and getprop(current,a_syllabe) == startattr then - if not c and mark_above_below_post[char] and after_subscript[char] then + if not c and mark_above_below_post[char] and not after_subscript[char] then c = current end current = getnext(current) @@ -1560,10 +1547,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas setprop(current,a_state,unsetvalue) if halant[getchar(current)] then setnext(getnext(current),tmp) - local nc = copy_node(current) - copyinjection(nc,current) - setchar(current,dotted_circle) - head = insert_node_after(head,current,nc) + if show_syntax_errors then + head, current = inject_syntax_error(head,current,char) + end else setnext(current,tmp) -- assumes that result of pref, blwf, or pstf consists of one node if changestop then @@ -2058,24 +2044,10 @@ local function analyze_next_chars_two(c,font) end end -local show_syntax_errors = false - -local function inject_syntax_error(head,current,char) - local signal = copy_node(current) - copyinjection(signal,current) - if pre_mark[char] then - setchar(signal,dotted_circle) - else - setchar(current,dotted_circle) - end - return insert_node_after(head,current,signal) -end - -- It looks like these two analyzers were written independently but they share -- a lot. Common code has been synced. local function method_one(head,font,attr) - head = tonut(head) local current = head local start = true local done = false @@ -2270,14 +2242,13 @@ local function method_one(head,font,attr) head = replace_all_nbsp(head) end - return tonode(head), done + return head, done end -- there is a good change that when we run into one with subtype < 256 that the rest is also done -- so maybe we can omit this check (it's pretty hard to get glyphs in the stream out of the blue) local function method_two(head,font,attr) - head = tonut(head) local current = head local start = true local done = false @@ -2366,7 +2337,7 @@ local function method_two(head,font,attr) head = replace_all_nbsp(head) end - return tonode(head), done + return head, done end for i=1,nofscripts do diff --git a/tex/context/base/mkiv/font-ota.lua b/tex/context/base/mkiv/font-ota.lua index de626c120..76c267a81 100644 --- a/tex/context/base/mkiv/font-ota.lua +++ b/tex/context/base/mkiv/font-ota.lua @@ -37,12 +37,10 @@ local getprev = nuts.getprev local getprev = nuts.getprev local getprop = nuts.getprop local setprop = nuts.setprop -local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar local ischar = nuts.is_char -local traverse_id = nuts.traverse_id local end_of_math = nuts.end_of_math local nodecodes = nodes.nodecodes @@ -112,6 +110,8 @@ analyzers.useunicodemarks = false -- todo: analyzers per script/lang, cross font, so we need an font id hash -> script -- e.g. latin -> hyphenate, arab -> 1/2/3 analyze -- its own namespace +-- done can go away as can tonut + function analyzers.setstate(head,font) local useunicodemarks = analyzers.useunicodemarks local tfmdata = fontdata[font] @@ -302,9 +302,9 @@ if not classifiers then end function methods.arab(head,font,attr) - local first, last = nil, nil - local c_first, c_last = nil, nil - local current, done = head, false + local first, last, c_first, c_last + local current = head + local done = false current = tonut(current) while current do local char, id = ischar(current,font) diff --git a/tex/context/base/mkiv/font-otc.lua b/tex/context/base/mkiv/font-otc.lua index 2bad62d60..a774a81c2 100644 --- a/tex/context/base/mkiv/font-otc.lua +++ b/tex/context/base/mkiv/font-otc.lua @@ -6,11 +6,10 @@ if not modules then modules = { } end modules ['font-otc'] = { license = "see context related readme files" } -local format, insert, sortedkeys, tohash = string.format, table.insert, table.sortedkeys, table.tohash -local type, next = type, next +local insert, sortedkeys, sortedhash, tohash = table.insert, table.sortedkeys, table.sortedhash, table.tohash +local type, next, tonumber = type, next, tonumber local lpegmatch = lpeg.match -local utfbyte, utflen, utfsplit = utf.byte, utf.len, utf.split -local match = string.match +local utfbyte, utflen = utf.byte, utf.len local sortedhash = table.sortedhash -- we assume that the other otf stuff is loaded already @@ -175,6 +174,10 @@ local function addfeature(data,feature,specifications) return end + local p = lpeg.P("P") + * (lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end) + * lpeg.P(-1) + local function tounicode(code) if not code then return @@ -184,6 +187,7 @@ local function addfeature(data,feature,specifications) end local u = unicodes[code] if u then + -- unicodes[code] = u return u end if utflen(code) == 1 then @@ -192,10 +196,19 @@ local function addfeature(data,feature,specifications) return u end end + local u = lpegmatch(p,code) + if u then + -- unicodes[code] = u + return u + end if not aglunicodes then aglunicodes = fonts.encodings.agl.unicodes -- delayed end - return aglunicodes[code] + local u = aglunicodes[code] + if u then + -- unicodes[code] = u + return u + end end local coverup = otf.coverup @@ -265,7 +278,8 @@ local function addfeature(data,feature,specifications) if not nocheck and not description then skip = skip + 1 elseif type(replacement) == "table" then - local r, n = { }, 0 + local r = { } + local n = 0 for i=1,#replacement do local u = tounicode(replacement[i]) if nocheck or descriptions[u] then @@ -467,6 +481,8 @@ local function addfeature(data,feature,specifications) if not subtype then subtype = lookup.type end + elseif v == 0 then + lookups[k] = { { type = "gsub_remove" } } else lookups[k] = false -- { false } -- new end @@ -813,177 +829,6 @@ otf.enhancers.enhance = enhance otf.enhancers.register("check extra features",enhance) --- tlig -- - -local tlig = { -- we need numbers for some fonts so ... - -- endash = "hyphen hyphen", - -- emdash = "hyphen hyphen hyphen", - [0x2013] = { 0x002D, 0x002D }, - [0x2014] = { 0x002D, 0x002D, 0x002D }, - -- quotedblleft = "quoteleft quoteleft", - -- quotedblright = "quoteright quoteright", - -- quotedblleft = "grave grave", - -- quotedblright = "quotesingle quotesingle", - -- quotedblbase = "comma comma", -} - -local tlig_specification = { - type = "ligature", - features = everywhere, - data = tlig, - order = { "tlig" }, - flags = noflags, - prepend = true, -} - -otf.addfeature("tlig",tlig_specification) - -registerotffeature { - -- this makes it a known feature (in tables) - name = 'tlig', - description = 'tex ligatures', -} - --- trep - -local trep = { - -- [0x0022] = 0x201D, - [0x0027] = 0x2019, - -- [0x0060] = 0x2018, -} - -local trep_specification = { - type = "substitution", - features = everywhere, - data = trep, - order = { "trep" }, - flags = noflags, - prepend = true, -} - -otf.addfeature("trep",trep_specification) - -registerotffeature { - -- this makes it a known feature (in tables) - name = 'trep', - description = 'tex replacements', -} - --- -- tcom (obsolete, was already not set for a while) - --- if characters.combined then --- --- local tcom = { } --- --- local function initialize() --- characters.initialize() --- for first, seconds in next, characters.combined do --- for second, combination in next, seconds do --- tcom[combination] = { first, second } --- end --- end --- -- return false --- end --- --- local tcom_specification = { --- type = "ligature", --- features = everywhere, --- data = tcom, --- order = { "tcom" }, --- flags = noflags, --- initialize = initialize, --- } --- --- otf.addfeature("tcom",tcom_specification) --- --- registerotffeature { --- name = 'tcom', --- description = 'tex combinations', --- } --- --- end - --- anum - -local anum_arabic = { - [0x0030] = 0x0660, - [0x0031] = 0x0661, - [0x0032] = 0x0662, - [0x0033] = 0x0663, - [0x0034] = 0x0664, - [0x0035] = 0x0665, - [0x0036] = 0x0666, - [0x0037] = 0x0667, - [0x0038] = 0x0668, - [0x0039] = 0x0669, -} - -local anum_persian = { - [0x0030] = 0x06F0, - [0x0031] = 0x06F1, - [0x0032] = 0x06F2, - [0x0033] = 0x06F3, - [0x0034] = 0x06F4, - [0x0035] = 0x06F5, - [0x0036] = 0x06F6, - [0x0037] = 0x06F7, - [0x0038] = 0x06F8, - [0x0039] = 0x06F9, -} - -local function valid(data) - local features = data.resources.features - if features then - for k, v in next, features do - for k, v in next, v do - if v.arab then - return true - end - end - end - end -end - -local anum_specification = { - { - type = "substitution", - features = { arab = { urd = true, dflt = true } }, - order = { "anum" }, - data = anum_arabic, - flags = noflags, -- { }, - valid = valid, - }, - { - type = "substitution", - features = { arab = { urd = true } }, - order = { "anum" }, - data = anum_persian, - flags = noflags, -- { }, - valid = valid, - }, -} - -otf.addfeature("anum",anum_specification) -- todo: only when there is already an arab script feature - -registerotffeature { - -- this makes it a known feature (in tables) - name = 'anum', - description = 'arabic digits', -} - --- maybe: - --- fonts.handlers.otf.addfeature("hangulfix",{ --- type = "substitution", --- features = { ["hang"] = { ["*"] = true } }, --- data = { --- [0x1160] = 0x119E, --- }, --- order = { "hangulfix" }, --- flags = { }, --- prepend = true, --- }) - -- fonts.handlers.otf.features.register { -- name = 'hangulfix', -- description = 'fixes for hangul', @@ -1028,126 +873,3 @@ registerotffeature { -- a = { b = -500 }, -- } -- } - --- This is a quick and dirty hack. - -local lookups = { } -local protect = { } -local revert = { } -local zwjchar = 0x200C -local zwj = { zwjchar } - -otf.addfeature { - name = "blockligatures", - type = "chainsubstitution", - nocheck = true, -- because there is no 0x200C in the font - prepend = true, -- make sure we do it early - future = true, -- avoid nilling due to no steps yet - lookups = { - { - type = "multiple", - data = lookups, - }, - }, - data = { - rules = protect, - } -} - -otf.addfeature { - name = "blockligatures", - type = "chainsubstitution", - nocheck = true, -- because there is no 0x200C in the font - append = true, -- this is done late - overload = false, -- we don't want to overload the previous definition - lookups = { - { - type = "ligature", - data = lookups, - }, - }, - data = { - rules = revert, - } -} - -registerotffeature { - name = 'blockligatures', - description = 'block certain ligatures', -} - -local settings_to_array = utilities.parsers and utilities.parsers.settings_to_array - or function(s) return string.split(s,",") end -- for generic - -local splitter = lpeg.splitat(":") - -local function blockligatures(str) - - local t = settings_to_array(str) - - for i=1,#t do - local ti = t[i] - local before, current, after = lpegmatch(splitter,ti) - if current and after then -- before is returned when no match - -- experimental joke - if before then - before = utfsplit(before) - for i=1,#before do - before[i] = { before[i] } - end - end - if current then - current = utfsplit(current) - end - if after then - after = utfsplit(after) - for i=1,#after do - after[i] = { after[i] } - end - end - else - before = nil - current = utfsplit(ti) - after = nil - end - if #current > 1 then - local one = current[1] - local two = current[2] - lookups[one] = { one, zwjchar } - local one = { one } - local two = { two } - local new = #protect + 1 - protect[new] = { - before = before, - current = { one, two }, - after = after, - lookups = { 1 }, -- not shared ! - } - revert[new] = { - -- before = before, - current = { one, zwj }, - -- after = { two, unpack(after) }, - after = { two }, - lookups = { 1 }, -- not shared ! - } - end - end -end - --- blockligatures("\0\0") - -otf.helpers.blockligatures = blockligatures - --- blockligatures("fi,ff") --- blockligatures("fl") --- blockligatures("u:fl:age") - -if context then - - interfaces.implement { - name = "blockligatures", - arguments = "string", - actions = blockligatures, - } - -end diff --git a/tex/context/base/mkiv/font-otj.lua b/tex/context/base/mkiv/font-otj.lua index 9037939df..bb3038935 100644 --- a/tex/context/base/mkiv/font-otj.lua +++ b/tex/context/base/mkiv/font-otj.lua @@ -97,8 +97,11 @@ local setlink = nuts.setlink local setwidth = nuts.setwidth local getwidth = nuts.getwidth -local traverse_id = nuts.traverse_id -local traverse_char = nuts.traverse_char +----- traverse_id = nuts.traverse_id +----- traverse_char = nuts.traverse_char +local nextchar = nuts.traversers.char +local nextglue = nuts.traversers.glue + local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after @@ -128,6 +131,10 @@ do if not fontkern then -- generic return n end +end end + +do if not italickern then -- generic + local thekern = nuts.new("kern",3) -- italiccorrection local setkern = nuts.setkern local copy_node = nuts.copy_node @@ -298,10 +305,10 @@ end -- kind: 0=single 1=first of pair, 2=second of pair function injections.setposition(kind,current,factor,rlmode,spec,injection) - local x = factor*spec[1] - local y = factor*spec[2] - local w = factor*spec[3] - local h = factor*spec[4] + local x = factor * (spec[1] or 0) + local y = factor * (spec[2] or 0) + local w = factor * (spec[3] or 0) + local h = factor * (spec[4] or 0) if x ~= 0 or w ~= 0 or y ~= 0 or h ~= 0 then -- okay? local yoffset = y - h local leftkern = x -- both kerns are set in a pair kern compared @@ -449,7 +456,8 @@ function injections.setmove(current,factor,rlmode,x,injection) end function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) -- ba=baseanchor, ma=markanchor - local dx, dy = factor*(ba[1]-ma[1]), factor*(ba[2]-ma[2]) + local dx = factor*(ba[1]-ma[1]) + local dy = factor*(ba[2]-ma[2]) nofregisteredmarks = nofregisteredmarks + 1 if rlmode >= 0 then dx = tfmbase.width - dx -- see later commented ox @@ -462,15 +470,18 @@ function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmar if i.markmark then -- out of order mkmk: yes or no or option else - if dx ~= 0 then - i.markx = dx - end - if y ~= 0 then - i.marky = dy - end - if rlmode then - i.markdir = rlmode - end + -- if dx ~= 0 then + -- i.markx = dx + -- end + -- if y ~= 0 then + -- i.marky = dy + -- end + -- if rlmode then + -- i.markdir = rlmode + -- end + i.markx = dx + i.marky = dy + i.markdir = rlmode or 0 i.markbase = nofregisteredmarks i.markbasenode = base i.markmark = mkmk @@ -558,7 +569,7 @@ end local function showsub(n,what,where) report_injections("begin subrun: %s",where) - for n in traverse_char(n) do + for n in nextchar, n do showchar(n,where) show(n,what,where," ") end @@ -628,7 +639,6 @@ end -- +D-replace +D-replace local function inject_kerns_only(head,where) - head = tonut(head) if trace_injections then trace(head,"kerns") end @@ -684,7 +694,8 @@ local function inject_kerns_only(head,where) -- glyph|disc|glyph (special case) local leftkern = i.leftkern if leftkern and leftkern ~= 0 then - setfield(prev,"replace",fontkern(leftkern)) -- maybe also leftkern + replace = fontkern(leftkern) + done = true end end end @@ -704,7 +715,7 @@ local function inject_kerns_only(head,where) local done = false if pre then -- left|pre glyphs|right - for n in traverse_char(pre) do + for n in nextchar, pre do local p = rawget(properties,n) if p then local i = p.injections or p.preinjections @@ -720,7 +731,7 @@ local function inject_kerns_only(head,where) end if post then -- left|post glyphs|right - for n in traverse_char(post) do + for n in nextchar, post do local p = rawget(properties,n) if p then local i = p.injections or p.postinjections @@ -736,7 +747,7 @@ local function inject_kerns_only(head,where) end if replace then -- left|replace glyphs|right - for n in traverse_char(replace) do + for n in nextchar, replace do local p = rawget(properties,n) if p then local i = p.injections or p.replaceinjections @@ -771,11 +782,10 @@ local function inject_kerns_only(head,where) if trace_injections then show_result(head) end - return tonode(head), true + return head end local function inject_positions_only(head,where) - head = tonut(head) if trace_injections then trace(head,"positions") end @@ -826,7 +836,9 @@ local function inject_positions_only(head,where) if replace then -- error, we expect an empty one else - setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern +--KE setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern + replace = fontkern(rightkern) -- maybe also leftkern --KE + done = true --KE end end end @@ -859,7 +871,8 @@ local function inject_positions_only(head,where) -- new .. okay? local leftkern = i.leftkern if leftkern and leftkern ~= 0 then - setfield(prev,"replace",fontkern(leftkern)) -- maybe also leftkern + replace = fontkern(leftkern) + done = true end end end @@ -878,7 +891,7 @@ local function inject_positions_only(head,where) local done = false if pre then -- left|pre glyphs|right - for n in traverse_char(pre) do + for n in nextchar, pre do local p = rawget(properties,n) if p then local i = p.injections or p.preinjections @@ -903,7 +916,7 @@ local function inject_positions_only(head,where) end if post then -- left|post glyphs|right - for n in traverse_char(post) do + for n in nextchar, post do local p = rawget(properties,n) if p then local i = p.injections or p.postinjections @@ -928,7 +941,7 @@ local function inject_positions_only(head,where) end if replace then -- left|replace glyphs|right - for n in traverse_char(replace) do + for n in nextchar, replace do local p = rawget(properties,n) if p then local i = p.injections or p.replaceinjections @@ -1002,7 +1015,7 @@ local function inject_positions_only(head,where) if trace_injections then show_result(head) end - return tonode(head), true + return head end local function showoffset(n,flag) @@ -1013,7 +1026,6 @@ local function showoffset(n,flag) end local function inject_everything(head,where) - head = tonut(head) if trace_injections then trace(head,"everything") end @@ -1276,7 +1288,8 @@ local function inject_everything(head,where) if replace then -- error, we expect an empty one else - setfield(next,"replace",fontkern(rightkern)) -- maybe also leftkern + replace = fontkern(rightkern) + done = true end end end @@ -1309,7 +1322,8 @@ local function inject_everything(head,where) if i then local leftkern = i.leftkern if leftkern and leftkern ~= 0 then - setfield(prev,"replace",fontkern(leftkern)) -- maybe also leftkern + replace = fontkern(leftkern) + done = true end end end @@ -1344,7 +1358,7 @@ local function inject_everything(head,where) local done = false if pre then -- left|pre glyphs|right - for n in traverse_char(pre) do + for n in nextchar, pre do local p = rawget(properties,n) if p then local i = p.injections or p.preinjections @@ -1375,7 +1389,7 @@ local function inject_everything(head,where) end if post then -- left|post glyphs|right - for n in traverse_char(post) do + for n in nextchar, post do local p = rawget(properties,n) if p then local i = p.injections or p.postinjections @@ -1406,7 +1420,7 @@ local function inject_everything(head,where) end if replace then -- left|replace glyphs|right - for n in traverse_char(replace) do + for n in nextchar, replace do local p = rawget(properties,n) if p then local i = p.injections or p.replaceinjections @@ -1514,7 +1528,7 @@ local function inject_everything(head,where) if trace_injections then show_result(head) end - return tonode(head), true + return head end -- space triggers @@ -1603,7 +1617,7 @@ end local function injectspaces(head) if not triggers then - return head, false + return head end local lastfont = nil local spacekerns = nil @@ -1613,7 +1627,6 @@ local function injectspaces(head) local threshold = 0 local leftkern = false local rightkern = false - local nuthead = tonut(head) local function updatefont(font,trig) leftkerns = trig.left @@ -1623,7 +1636,7 @@ local function injectspaces(head) factor = getthreshold(font) end - for n in traverse_id(glue_code,nuthead) do + for n in nextglue, head do local prev, next = getspaceboth(n) local prevchar = prev and ischar(prev) local nextchar = next and ischar(next) @@ -1661,12 +1674,8 @@ local function injectspaces(head) if trace_spaces then report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) end - local h = insert_node_before(nuthead,n,italickern(lnew)) - if h == nuthead then - head = tonode(h) - nuthead = h - end - insert_node_after(nuthead,n,italickern(rnew)) + head = insert_node_before(head,n,italickern(lnew)) + insert_node_after(head,n,italickern(rnew)) else local new = old + (leftkern + rightkern) * factor if trace_spaces then @@ -1681,7 +1690,7 @@ local function injectspaces(head) if trace_spaces then report_spaces("%C [%p + %p]",prevchar,old,new) end - insert_node_after(nuthead,n,italickern(new)) -- tricky with traverse but ok + insert_node_after(head,n,italickern(new)) -- tricky with traverse but ok else local new = old + leftkern * factor if trace_spaces then @@ -1700,7 +1709,7 @@ local function injectspaces(head) if trace_spaces then report_spaces("%C [%p + %p]",nextchar,old,new) end - insert_node_after(nuthead,n,italickern(new)) + insert_node_after(head,n,italickern(new)) else local new = old + rightkern * factor if trace_spaces then @@ -1714,7 +1723,8 @@ local function injectspaces(head) end triggers = false - return head, true + + return head end -- @@ -1740,6 +1750,6 @@ function injections.handler(head,where) end return inject_kerns_only(head,where) else - return head, false + return head end end diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua index a71e3ad98..df83dc968 100644 --- a/tex/context/base/mkiv/font-otl.lua +++ b/tex/context/base/mkiv/font-otl.lua @@ -52,14 +52,14 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.103 -- beware: also sync font-mis.lua and in mtx-fonts -otf.cache = containers.define("fonts", "otl", otf.version, true) -otf.svgcache = containers.define("fonts", "svg", otf.version, true) -otf.sbixcache = containers.define("fonts", "sbix", otf.version, true) -otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) +otf.version = 3.107 -- beware: also sync font-mis.lua and in mtx-fonts +otf.cache = containers.define("fonts", "otl", otf.version, true) +otf.svgcache = containers.define("fonts", "svg", otf.version, true) +otf.pngcache = containers.define("fonts", "png", otf.version, true) +otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) otf.svgenabled = false -otf.sbixenabled = false +otf.pngenabled = false local otfreaders = otf.readers @@ -152,17 +152,17 @@ function otf.load(filename,sub,instance) report_otf("forced reload of %a due to hard coded flag",filename) reload = true end - if reload then + if reload then report_otf("loading %a, hash %a",filename,hash) -- - starttiming(otfreaders) + starttiming(otfreaders,true) data = otfreaders.loadfont(filename,sub or 1,instance) -- we can pass the number instead (if it comes from a name search) if data then -- todo: make this a plugin - local used = checkmemory() - local resources = data.resources - local svgshapes = resources.svgshapes - local sbixshapes = resources.sbixshapes + local used = checkmemory() + local resources = data.resources + local svgshapes = resources.svgshapes + local pngshapes = resources.pngshapes if cleanup == 0 then checkmemory(used,threshold,tracememory) end @@ -186,16 +186,16 @@ function otf.load(filename,sub,instance) checkmemory(used,threshold,tracememory) end end - if sbixshapes then - resources.sbixshapes = nil - if otf.sbixenabled then + if pngshapes then + resources.pngshapes = nil + if otf.pngenabled then local timestamp = os.date() -- work in progress ... a bit boring to do - containers.write(otf.sbixcache,hash, { - sbixshapes = sbixshapes, - timestamp = timestamp, + containers.write(otf.pngcache,hash, { + pngshapes = pngshapes, + timestamp = timestamp, }) - data.properties.sbix = { + data.properties.png = { hash = hash, timestamp = timestamp, } @@ -242,6 +242,7 @@ function otf.load(filename,sub,instance) checkmemory(used,threshold,tracememory) end else + stoptiming(otfreaders) data = nil report_otf("loading failed due to read error") end @@ -405,6 +406,7 @@ local function copytotfm(data,cache_id) local fontname = metadata.fontname local fullname = metadata.fullname or fontname local psname = fontname or fullname + local subfont = metadata.subfontindex local units = metadata.units or 1000 -- if units == 0 then -- catch bugs in fonts @@ -499,6 +501,7 @@ local function copytotfm(data,cache_id) properties.fullname = fullname properties.psname = psname properties.name = filename or fullname + properties.subfont = subfont -- -- properties.name = specification.name -- properties.sub = specification.sub diff --git a/tex/context/base/mkiv/font-oto.lua b/tex/context/base/mkiv/font-oto.lua index 4b986bd3b..6f6d89d43 100644 --- a/tex/context/base/mkiv/font-oto.lua +++ b/tex/context/base/mkiv/font-oto.lua @@ -49,7 +49,9 @@ local function gref(descriptions,n) return f_unicode(n) end elseif n then - local num, nam, j = { }, { }, 0 + local num = { } + local nam = { } + local j = 0 for i=1,#n do local ni = n[i] if tonumber(ni) then -- first is likely a key @@ -121,8 +123,8 @@ local basehash, basehashes, applied = { }, 1, { } local function registerbasehash(tfmdata) local properties = tfmdata.properties - local hash = concat(applied," ") - local base = basehash[hash] + local hash = concat(applied," ") + local base = basehash[hash] if not base then basehashes = basehashes + 1 base = basehashes @@ -310,13 +312,16 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis for i=1,nofligatures do local ligature = ligatures[i] - local unicode, tree = ligature[1], ligature[2] + local unicode = ligature[1] + local tree = ligature[2] make_1(present,tree,"ctx_"..unicode) end for i=1,nofligatures do - local ligature = ligatures[i] - local unicode, tree, lookupname = ligature[1], ligature[2], ligature[3] + local ligature = ligatures[i] + local unicode = ligature[1] + local tree = ligature[2] + local lookupname = ligature[3] make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) end @@ -415,36 +420,42 @@ local function checkmathreplacements(tfmdata,fullname,fixitalics) for unicode, replacement in next, changed do local u = characters[unicode] local r = characters[replacement] - local n = u.next - local v = u.vert_variants - local h = u.horiz_variants - if fixitalics then - -- quite some warnings on stix ... - local ui = u.italic - if ui and not r.italic then + if u and r then + local n = u.next + local v = u.vert_variants + local h = u.horiz_variants + if fixitalics then + -- quite some warnings on stix ... + local ui = u.italic + if ui and not r.italic then + if trace_preparing then + report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) + end + r.italic = ui -- print(ui,ri) + end + end + if n and not r.next then if trace_preparing then - report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) + report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) end - r.italic = ui -- print(ui,ri) + r.next = n end - end - if n and not r.next then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) + if v and not r.vert_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) + end + r.vert_variants = v end - r.next = n - end - if v and not r.vert_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) + if h and not r.horiz_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) + end + r.horiz_variants = h end - r.vert_variants = v - end - if h and not r.horiz_variants then + else if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) + report_prepare("error replacing %C by %U",unicode,replacement) end - r.horiz_variants = h end end end diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua index 5bac75052..c7ff6b726 100644 --- a/tex/context/base/mkiv/font-otr.lua +++ b/tex/context/base/mkiv/font-otr.lua @@ -25,7 +25,7 @@ if not modules then modules = { } end modules ['font-otr'] = { -- are just a unicode string but it doesn't save that much. It will be an option -- some day. --- Optimizing the widths wil be done anyway as it save quite some on a cjk font +-- Optimizing the widths will be done anyway as it save quite some on a cjk font -- and the existing (old) code if okay. -- todo: more messages (only if really needed) @@ -67,6 +67,7 @@ if not modules then modules = { } end modules ['font-otr'] = { local next, type, tonumber = next, type, tonumber local byte, lower, char, gsub = string.byte, string.lower, string.char, string.gsub +local fullstrip = string.fullstrip local floor, round = math.floor, math.round local P, R, S, C, Cs, Cc, Ct, Carg, Cmt = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg, lpeg.Cmt local lpegmatch = lpeg.match @@ -121,11 +122,47 @@ local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed num local readfword = readshort -- 16-bit signed integer that describes a quantity in FUnits local readufword = readushort -- 16-bit unsigned integer that describes a quantity in FUnits local readoffset = readushort +local readcardinaltable = streamreader.readcardinaltable +local readintegertable = streamreader.readintegertable function streamreader.readtag(f) return lower(stripstring(readstring(f,4))) end +local short = 2 +local ushort = 2 +local ulong = 4 + +directives.register("fonts.streamreader",function() + + streamreader = utilities.streams + + openfile = streamreader.open + closefile = streamreader.close + setposition = streamreader.setposition + skipshort = streamreader.skipshort + readbytes = streamreader.readbytes + readstring = streamreader.readstring + readbyte = streamreader.readcardinal1 + readushort = streamreader.readcardinal2 + readuint = streamreader.readcardinal3 + readulong = streamreader.readcardinal4 + readshort = streamreader.readinteger2 + readlong = streamreader.readinteger4 + readfixed = streamreader.readfixed4 + read2dot14 = streamreader.read2dot14 + readfword = readshort + readufword = readushort + readoffset = readushort + readcardinaltable = streamreader.readcardinaltable + readintegertable = streamreader.readintegertable + + function streamreader.readtag(f) + return lower(stripstring(readstring(f,4))) + end + +end) + -- date represented in number of seconds since 12:00 midnight, January 1, 1904. The value is represented as a -- signed 64-bit integer @@ -704,20 +741,30 @@ readers.helpers = helpers local function gotodatatable(f,fontdata,tag,criterium) if criterium and f then - local datatable = fontdata.tables[tag] - if datatable then - local tableoffset = datatable.offset - setposition(f,tableoffset) - return tableoffset + local tables = fontdata.tables + if tables then + local datatable = tables[tag] + if datatable then + local tableoffset = datatable.offset + setposition(f,tableoffset) + return tableoffset + end + else + report("no tables") end end end local function reportskippedtable(f,fontdata,tag,criterium) if criterium and f then - local datatable = fontdata.tables[tag] - if datatable then - report("loading of table %a skipped",tag) + local tables = fontdata.tables + if tables then + local datatable = tables[tag] + if datatable then + report("loading of table %a skipped",tag) + end + else + report("no tables") end end end @@ -749,6 +796,16 @@ local platformnames = { compatiblefullname = true, } +local platformextras = { + uniqueid = true, + version = true, + copyright = true, + license = true, + licenseurl = true, + manufacturer = true, + vendorurl = true, +} + function readers.name(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"name",true) if tableoffset then @@ -819,6 +876,18 @@ function readers.name(f,fontdata,specification) -- and extend when we run into it (todo: proper reverse hash) .. we're only -- interested in english anyway -- + local function decoded(platform,encoding,content) + local decoder = decoders[platform] + if decoder then + decoder = decoder[encoding] + end + if decoder then + return decoder(content) + else + return content + end + end + -- local function filter(platform,e,l) local namelist = namelists[platform] for i=1,#namelist do @@ -830,14 +899,7 @@ function readers.name(f,fontdata,specification) local language = name.language if (not e or encoding == e) and (not l or language == l) then setposition(f,name.offset) - local content = readstring(f,name.length) - local decoder = decoders[platform] - if decoder then - decoder = decoder[encoding] - end - if decoder then - content = decoder(content) - end + local content = decoded(platform,encoding,readstring(f,name.length)) if nametag then names[nametag] = { content = content, @@ -864,23 +926,16 @@ function readers.name(f,fontdata,specification) fontdata.extras = extras -- if specification.platformnames then - local collected = { } + local collected = { } + local platformextras = specification.platformextras and platformextras for platform, namelist in next, namelists do local filtered = false for i=1,#namelist do local entry = namelist[i] local name = entry.name - if platformnames[name] then + if platformnames[name] or (platformextras and platformextras[name]) then setposition(f,entry.offset) - local content = readstring(f,entry.length) - local encoding = entry.encoding - local decoder = decoders[platform] - if decoder then - decoder = decoder[encoding] - end - if decoder then - content = decoder(content) - end + local content = decoded(platform,entry.encoding,readstring(f,entry.length)) if filtered then filtered[name] = content else @@ -923,7 +978,7 @@ readers["os/2"] = function(f,fontdata) local version = readushort(f) local windowsmetrics = { version = version, - averagewidth = readshort(f), + averagewidth = readshort(f), -- ushort? weightclass = readushort(f), widthclass = readushort(f), fstype = readushort(f), @@ -953,7 +1008,7 @@ readers["os/2"] = function(f,fontdata) if version >= 1 then windowsmetrics.codepageranges = { readulong(f), readulong(f) } end - if version >= 3 then + if version >= 2 then windowsmetrics.xheight = readshort(f) windowsmetrics.capheight = readshort(f) windowsmetrics.defaultchar = readushort(f) @@ -980,24 +1035,28 @@ end readers.head = function(f,fontdata) local tableoffset = gotodatatable(f,fontdata,"head",true) if tableoffset then + local version = readulong(f) + local fontversion = readulong(f) local fontheader = { - version = readfixed(f), - revision = readfixed(f), - checksum = readulong(f), - magic = readulong(f), - flags = readushort(f), - units = readushort(f), - created = readlongdatetime(f), - modified = readlongdatetime(f), - xmin = readshort(f), - ymin = readshort(f), - xmax = readshort(f), - ymax = readshort(f), - macstyle = readushort(f), - smallpixels = readushort(f), - directionhint = readshort(f), - indextolocformat = readshort(f), - glyphformat = readshort(f), + version = version, + fontversion = number.to16dot16(fontversion), + fontversionnumber = fontversion, + -- checksum = readulong(f), + checksum = readushort(f) * 0x10000 + readushort(f), + magic = readulong(f), + flags = readushort(f), + units = readushort(f), + created = readlongdatetime(f), + modified = readlongdatetime(f), + xmin = readshort(f), + ymin = readshort(f), + xmax = readshort(f), + ymax = readshort(f), + macstyle = readushort(f), + smallpixels = readushort(f), + directionhint = readshort(f), + indextolocformat = readshort(f), + glyphformat = readshort(f), } fontdata.fontheader = fontheader else @@ -1013,7 +1072,7 @@ readers.hhea = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"hhea",specification.details) if tableoffset then fontdata.horizontalheader = { - version = readfixed(f), -- two ushorts: major minor + version = readulong(f), ascender = readfword(f), descender = readfword(f), linegap = readfword(f), @@ -1042,7 +1101,7 @@ readers.vhea = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"vhea",specification.details) if tableoffset then fontdata.verticalheader = { - version = readfixed(f), + version = readulong(f), ascender = readfword(f), descender = readfword(f), linegap = readfword(f), @@ -1075,15 +1134,15 @@ end readers.maxp = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"maxp",specification.details) if tableoffset then - local version = readfixed(f) + local version = readulong(f) local nofglyphs = readushort(f) fontdata.nofglyphs = nofglyphs - if version == 0.5 then + if version == 0x00005000 then fontdata.maximumprofile = { version = version, nofglyphs = nofglyphs, } - elseif version == 1.0 then + elseif version == 0x00010000 then fontdata.maximumprofile = { version = version, nofglyphs = nofglyphs, @@ -1124,15 +1183,14 @@ readers.hmtx = function(f,fontdata,specification) local leftsidebearing = 0 for i=0,nofmetrics-1 do local glyph = glyphs[i] - width = readshort(f) + width = readshort(f) -- readushort leftsidebearing = readshort(f) if width ~= 0 then glyph.width = width end --- for now --- if leftsidebearing ~= 0 then --- glyph.lsb = leftsidebearing --- end + -- if leftsidebearing ~= 0 then + -- glyph.lsb = leftsidebearing + -- end end -- The next can happen in for instance a monospace font or in a cjk font -- with fixed widths. @@ -1145,7 +1203,6 @@ readers.hmtx = function(f,fontdata,specification) -- glyph.lsb = leftsidebearing -- end end - -- hm, there can be a lsb here end end @@ -1195,7 +1252,7 @@ end readers.post = function(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"post",true) if tableoffset then - local version = readfixed(f) + local version = readulong(f) fontdata.postscript = { version = version, italicangle = round(1000*readfixed(f))/1000, @@ -1209,12 +1266,12 @@ readers.post = function(f,fontdata,specification) } if not specification.glyphs then -- enough done - elseif version == 1.0 then + elseif version == 0x00010000 then -- mac encoding (258 glyphs) for index=0,#standardromanencoding do glyphs[index].name = standardromanencoding[index] end - elseif version == 2.0 then + elseif version == 0x00020000 then local glyphs = fontdata.glyphs local nofglyphs = readushort(f) local indices = { } @@ -1245,10 +1302,6 @@ readers.post = function(f,fontdata,specification) end end end - elseif version == 2.5 then - -- depricated, will be done when needed - elseif version == 3.0 then - -- no ps name information end else fontdata.postscript = { } @@ -1321,34 +1374,18 @@ formatreaders[4] = function(f,fontdata,offset) -- skipshort(f,3) -- searchrange entryselector rangeshift -- - local endchars = { } - local startchars = { } - local deltas = { } - local offsets = { } - local indices = { } local mapping = fontdata.mapping local glyphs = fontdata.glyphs local duplicates = fontdata.duplicates local nofdone = 0 - -- - for i=1,nofsegments do - endchars[i] = readushort(f) - end - local reserved = readushort(f) -- 0 - for i=1,nofsegments do - startchars[i] = readushort(f) - end - for i=1,nofsegments do - deltas[i] = readshort(f) - end - for i=1,nofsegments do - offsets[i] = readushort(f) - end + local endchars = readcardinaltable(f,nofsegments,ushort) + local reserved = readushort(f) -- 0 + local startchars = readcardinaltable(f,nofsegments,ushort) + local deltas = readcardinaltable(f,nofsegments,ushort) + local offsets = readcardinaltable(f,nofsegments,ushort) -- format length language nofsegments searchrange entryselector rangeshift 4-tables - local size = (length - 2 * 2 - 5 * 2 - 4 * 2 * nofsegments) / 2 - for i=1,size-1 do - indices[i] = readushort(f) - end + local size = (length - 2 * 2 - 5 * 2 - 4 * 2 * nofsegments) / 2 + local indices = readcardinaltable(f,size-1,ushort) -- for segment=1,nofsegments do local startchar = startchars[segment] @@ -1927,14 +1964,16 @@ local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,inst designsize = fontdata.designsize, minsize = fontdata.minsize, maxsize = fontdata.maxsize, + boundingbox = fontheader and { fontheader.xmin or 0, fontheader.ymin or 0, fontheader.xmax or 0, fontheader.ymax or 0 } or nil, monospaced = (tonumber(postscript.monospaced or 0) > 0) or metrics.panosewidth == "monospaced", averagewidth = metrics.averagewidth, - xheight = metrics.xheight, - capheight = metrics.capheight, -- not always present and probably crap + xheight = metrics.xheight, -- can be missing + capheight = metrics.capheight or fontdata.maxy, -- can be missing ascender = metrics.typoascender, descender = metrics.typodescender, platformnames = platformnames or nil, instancenames = instancenames or nil, + tableoffsets = fontdata.tableoffsets, } if metricstoo then local keys = { @@ -1996,7 +2035,8 @@ local function loadtables(f,specification,offset) } for i=1,fontdata.noftables do local tag = lower(stripstring(readstring(f,4))) - local checksum = readulong(f) -- not used + -- local checksum = readulong(f) -- not used + local checksum = readushort(f) * 0x10000 + readushort(f) local offset = readulong(f) local length = readulong(f) if offset + length > filesize then @@ -2008,13 +2048,14 @@ local function loadtables(f,specification,offset) length = length, } end +-- inspect(tables) fontdata.foundtables = sortedkeys(tables) if tables.cff or tables.cff2 then fontdata.format = "opentype" else fontdata.format = "truetype" end - return fontdata + return fontdata, tables end local function prepareglyps(fontdata) @@ -2043,7 +2084,7 @@ local variablefonts_supported = (context and true) or (logs and logs.application local function readdata(f,offset,specification) - local fontdata = loadtables(f,specification,offset) + local fontdata, tables = loadtables(f,specification,offset) if specification.glyphs then prepareglyps(fontdata) @@ -2182,10 +2223,20 @@ local function readdata(f,offset,specification) readtable("math",f,fontdata,specification) fontdata.locations = nil - fontdata.tables = nil fontdata.cidmaps = nil fontdata.dictionaries = nil -- fontdata.cff = nil + + if specification.tableoffsets then + fontdata.tableoffsets = tables + setmetatableindex(tables, { + version = fontdata.version, + noftables = fontdata.noftables, + searchrange = fontdata.searchrange, + entryselector = fontdata.entryselector, + rangeshift = fontdata.rangeshift, + }) + end return fontdata end @@ -2209,12 +2260,9 @@ local function loadfontdata(specification) fontdata = readdata(f,0,specification) elseif version == "ttcf" then local subfont = tonumber(specification.subfont) - local offsets = { } local ttcversion = readulong(f) local nofsubfonts = readulong(f) - for i=1,nofsubfonts do - offsets[i] = readulong(f) - end + local offsets = readcardinaltable(f,nofsubfonts,ulong) if subfont then -- a number of not if subfont >= 1 and subfont <= nofsubfonts then fontdata = readdata(f,offsets[subfont],specification) @@ -2296,12 +2344,13 @@ local function loadfont(specification,n,instance) specification.instance = specification.instance or instance end local function message(str) - report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) + report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) end local ok, result = xpcall(loadfontdata,message,specification) if ok then return result end +-- return loadfontdata(specification) end -- we need even less, but we can have a 'detail' variant @@ -2323,13 +2372,26 @@ function readers.loadshapes(filename,n,instance,streams) v.math = nil -- v.name = nil end + local names = fontdata.names + if names then + for k, v in next, names do + names[k] = fullstrip(v.content) + end + end end return fontdata and { - -- version = 0.123 -- todo - filename = filename, - format = fontdata.format, - glyphs = fontdata.glyphs, - units = fontdata.fontheader.units, + -- version = 0.123 -- todo + filename = filename, + format = fontdata.format, + glyphs = fontdata.glyphs, + units = fontdata.fontheader.units, + cffinfo = fontdata.cffinfo, + fontheader = fontdata.fontheader, + horizontalheader = fontdata.horizontalheader, + verticalheader = fontdata.verticalheader, + maximumprofile = fontdata.maximumprofile, + names = fontdata.names, + postscript = fontdata.postscript, } or { filename = filename, format = "unknown", @@ -2385,7 +2447,7 @@ function readers.loadfont(filename,n,instance) mathconstants = fontdata.mathconstants, colorpalettes = fontdata.colorpalettes, svgshapes = fontdata.svgshapes, - sbixshapes = fontdata.sbixshapes, + pngshapes = fontdata.pngshapes, variabledata = fontdata.variabledata, foundtables = fontdata.foundtables, }, @@ -2400,10 +2462,12 @@ function readers.getinfo(filename,specification) -- string, nil|number|table local platformnames = false local rawfamilynames = false local instancenames = true + local tableoffsets = false if type(specification) == "table" then subfont = tonumber(specification.subfont) platformnames = specification.platformnames rawfamilynames = specification.rawfamilynames + tableoffsets = specification.tableoffsets else subfont = tonumber(specification) end @@ -2412,6 +2476,7 @@ function readers.getinfo(filename,specification) -- string, nil|number|table details = true, platformnames = platformnames, instancenames = true, + tableoffsets = tableoffsets, -- rawfamilynames = rawfamilynames, } if fontdata then diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index 25083dfce..563094fc1 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -82,7 +82,7 @@ mechanisms. Both put some constraints on the code here.

-- Todo: check if we copy attributes to disc nodes if needed. -- -- Todo: it would be nice if we could get rid of components. In other places we can use --- the unicode properties. +-- the unicode properties. We can just keep a lua table. -- -- Remark: We do some disc juggling where we need to keep in mind that the pre, post and -- replace fields can have prev pointers to a nesting node ... I wonder if that is still @@ -176,8 +176,6 @@ registertracker("otf.sample", "otf.steps","otf.substitutions","otf.positi registertracker("otf.sample.silent", "otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut local getfield = nuts.getfield local getnext = nuts.getnext @@ -191,7 +189,6 @@ local getattr = nuts.getattr local setattr = nuts.setattr local getprop = nuts.getprop local setprop = nuts.setprop -local getfont = nuts.getfont local getsubtype = nuts.getsubtype local setsubtype = nuts.setsubtype local getchar = nuts.getchar @@ -201,10 +198,10 @@ local setdisc = nuts.setdisc local setlink = nuts.setlink local getcomponents = nuts.getcomponents -- the original one, not yet node-aux local setcomponents = nuts.setcomponents -- the original one, not yet node-aux -local getdir = nuts.getdir local getwidth = nuts.getwidth local ischar = nuts.is_char +local isglyph = nuts.isglyph local usesfont = nuts.uses_font local insert_node_after = nuts.insert_after @@ -215,17 +212,12 @@ local find_node_tail = nuts.tail local flush_node_list = nuts.flush_list local flush_node = nuts.flush_node local end_of_math = nuts.end_of_math -local traverse_nodes = nuts.traverse ------ traverse_id = nuts.traverse_id -local set_components = nuts.set_components -local take_components = nuts.take_components -local count_components = nuts.count_components -local copy_no_components = nuts.copy_no_components -local copy_only_glyphs = nuts.copy_only_glyphs local setmetatable = setmetatable local setmetatableindex = table.setmetatableindex +local nextnode = nuts.traversers.node + ----- zwnj = 0x200C ----- zwj = 0x200D @@ -240,8 +232,8 @@ local math_code = nodecodes.math local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local discretionary_code = disccodes.discretionary -local ligature_code = glyphcodes.ligature +local discretionarydisc_code = disccodes.discretionary +local ligatureglyph_code = glyphcodes.ligature local a_state = attributes.private('state') local a_noligature = attributes.private("noligature") @@ -458,26 +450,28 @@ end -- start is a mark and we need to keep that one -local take_components = getcomponents -- we overload here (for now) -local set_components = setcomponents -- we overload here (for now) ------ get_components = getcomponents -- we overload here (for now) +local copy_no_components = nuts.copy_no_components +local copy_only_glyphs = nuts.copy_only_glyphs + +local set_components = setcomponents +local take_components = getcomponents local function count_components(start,marks) - if getid(start) ~= glyph_code then - return 0 - elseif getsubtype(start) == ligature_code then - local i = 0 - local components = getcomponents(start) - while components do - i = i + count_components(components,marks) - components = getnext(components) + local char = isglyph(start) + if char then + if getsubtype(start) == ligatureglyph_code then + local i = 0 + local components = getcomponents(start) + while components do + i = i + count_components(components,marks) + components = getnext(components) + end + return i + elseif not marks[char] then + return 1 end - return i - elseif not marks[getchar(start)] then - return 1 - else - return 0 end + return 0 end local function markstoligature(head,start,stop,char) @@ -494,7 +488,7 @@ local function markstoligature(head,start,stop,char) end resetinjection(base) setchar(base,char) - setsubtype(base,ligature_code) + setsubtype(base,ligatureglyph_code) set_components(base,start) setlink(prev,base,next) return head, base @@ -530,7 +524,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou end resetinjection(base) setchar(base,char) - setsubtype(base,ligature_code) + setsubtype(base,ligatureglyph_code) set_components(base,comp) setlink(prev,base,next) if not discfound then @@ -612,7 +606,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou set_components(base,copied) replace = base if forcediscretionaries then - setdisc(discfound,pre,post,replace,discretionary_code) + setdisc(discfound,pre,post,replace,discretionarydisc_code) else setdisc(discfound,pre,post,replace) end @@ -623,7 +617,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou return head, base end -local function multiple_glyphs(head,start,multiple,skiphash,what) -- what to do with skiphash matches here +local function multiple_glyphs(head,start,multiple,skiphash,what,stop) -- what to do with skiphash matches here local nofmultiples = #multiple if nofmultiples > 0 then resetinjection(start) @@ -784,23 +778,17 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip -- ok, goto next lookup end end - else -- is the check for disc still valid here ? and why only replace then + else local discfound = false - local lastdisc = nil local hasmarks = marks[startchar] while current do local char, id = ischar(current,currentfont) if char then if skiphash and skiphash[char] then current = getnext(current) - -- if stop then stop = current end -- ? - else -- ligature is a tree - local lg = ligature[char] -- can there be multiple in a row? maybe in a bad font + else + local lg = ligature[char] if lg then - if not discfound and lastdisc then - discfound = lastdisc - lastdisc = nil - end if marks[char] then hasmarks = true end @@ -815,58 +803,89 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip -- kind of weird break elseif id == disc_code then - -- - -- Kai: see chainprocs, we probably could do the same here or was there a reason - -- why we kept the replace check here. - -- - -- if not discfound then - -- discfound = current - -- end - -- if current == stop then - -- break -- okay? or before the disc - -- else - -- current = getnext(current) - -- end - -- - local replace = getfield(current,"replace") -- hm: pre and post - if replace then - -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature) - -- we can end up here when we have a start run .. testruns start at a disc but - -- so here we have the other case: char + disc - while replace do - local char, id = ischar(replace,currentfont) - if char then - local lg = ligature[char] -- can there be multiple in a row? maybe in a bad font - if lg then - if marks[char] then - hasmarks = true -- very unlikely - end - ligature = lg - replace = getnext(replace) - else - return head, start, false, false - end - else - return head, start, false, false - end - end - stop = current - end - lastdisc = current - current = getnext(current) + discfound = current + break else break end end + -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature) + -- we can end up here when we have a start run .. testruns start at a disc but + -- so here we have the other case: char + disc + if discfound then + -- don't assume marks in a disc and we don't run over a disc (for now) + local pre, post, replace = getdisc(discfound) + local match + if replace then + local char = ischar(replace,currentfont) + if char and ligature[char] then + match = true + end + end + if not match and pre then + local char = ischar(pre,currentfont) + if char and ligature[char] then + match = true + end + end + if not match and not pre or not replace then + local n = getnext(discfound) + local char = ischar(n,currentfont) + if char and ligature[char] then + match = true + end + end + if match then + -- we force a restart + local ishead = head == start + local prev = getprev(start) + if stop then + setnext(stop) + local tail = getprev(stop) + local copy = copy_node_list(start) + local liat = find_node_tail(copy) + if pre then + setlink(liat,pre) + end + if replace then + setlink(tail,replace) + end + pre = copy + replace = start + else + setnext(start) + local copy = copy_node(start) + if pre then + setlink(copy,pre) + end + if replace then + setlink(start,replace) + end + pre = copy + replace = start + end + setdisc(discfound,pre,post,replace) + if prev then + setlink(prev,discfound) + else + setprev(discfound) + head = discfound + end + start = discfound + return head, start, true, true + end + end local lig = ligature.ligature if lig then if stop then if trace_ligatures then local stopchar = getchar(stop) - head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) + -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) + head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) else - head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) + -- head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) + head, start = toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) end else -- weird but happens (in some arabic font) @@ -876,12 +895,12 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) end end - return head, start, true, discfound + return head, start, true, false else -- weird but happens, pseudo ligatures ... just the components end end - return head, start, false, discfound + return head, start, false, false end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) @@ -920,7 +939,8 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,st end local format = step.format if format == "pair" then - local a, b = krn[1], krn[2] + local a = krn[1] + local b = krn[2] if a == true then -- zero elseif a then -- #a > 0 @@ -1270,6 +1290,14 @@ local function getmapping(dataset,sequence,currentlookup) end end +function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if trace_chains then + logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start))) + end + head, start = remove_node(head,start,true) + return head, getprev(start), true +end + function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) local mapping = currentlookup.mapping if mapping == nil then @@ -1380,7 +1408,7 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup if trace_multiples then logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) end - return multiple_glyphs(head,start,replacement,skiphash,dataset[1]) + return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop) end end return head, start, false @@ -1532,7 +1560,8 @@ function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlm end local format = currentlookup.format if format == "pair" then - local a, b = krn[1], krn[2] + local a = krn[1] + local b = krn[2] if a == true then -- zero elseif a then @@ -1986,6 +2015,9 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) end end + else + -- we skip but we could also delete as option .. what does an empty lookup actually mean + -- in opentype ... anyway, we could map it onto gsub_remove if needed end i = i + 1 if i > size or not start then @@ -2625,7 +2657,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s end end else - notmatchreplace[prev] = true -- new, for Kai to check + -- notmatchreplace[prev] = true -- not according to Kai end end prev = getprev(prev) @@ -2754,7 +2786,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s end end else - notmatchreplace[current] = true -- new, for Kai to check + -- notmatchreplace[current] = true -- not according to Kai end current = getnext(current) elseif id == glue_code then @@ -2802,6 +2834,9 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s notmatchpre = { } notmatchpost = { } notmatchreplace = { } + -- notmatchpre = { a = 1, b = 1 } notmatchpre .a = nil notmatchpre .b = nil + -- notmatchpost = { a = 1, b = 1 } notmatchpost .a = nil notmatchpost .b = nil + -- notmatchreplace = { a = 1, b = 1 } notmatchreplace.a = nil notmatchreplace.b = nil end return head, start, done end @@ -3159,7 +3194,7 @@ local function testrun(disc,t_run,c_run,...) local d = d_replace > d_post and d_replace or d_post local head = getnext(disc) -- is: next local tail = head - for i=1,d do + for i=2,d do -- must start at 2 according to Kai local nx = getnext(tail) local id = getid(nx) if id == disc_code then @@ -3419,7 +3454,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase a = getattr(sub,0) end if not a or (a == attr) then - for n in traverse_nodes(sub) do -- only gpos + for n in nextnode, sub do -- only gpos if n == last then break end @@ -3584,7 +3619,7 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase a = getattr(sub,0) end if not a or (a == attr) then - for n in traverse_nodes(sub) do -- only gpos + for n in nextnode, sub do -- only gpos if n == last then break end @@ -3606,129 +3641,57 @@ local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,datase end end --- to be checked, nowadays we probably can assume properly matched directions --- so maybe we no longer need a stack - --- local function txtdirstate(start,stack,top,rlparmode) --- local dir = getdir(start) --- local new = 1 --- if dir == "+TRT" then --- top = top + 1 --- stack[top] = dir --- new = -1 --- elseif dir == "+TLT" then --- top = top + 1 --- stack[top] = dir --- elseif dir == "-TRT" or dir == "-TLT" then --- if top == 1 then --- top = 0 --- new = rlparmode --- else --- top = top - 1 --- if stack[top] == "+TRT" then --- new = -1 --- end --- end --- else --- new = rlparmode --- end --- return getnext(start), top, new --- end --- --- local function pardirstate(start) --- local dir = getdir(start) --- local new = 0 --- if dir == "TLT" then --- new = 1 --- elseif dir == "TRT" then --- new = -1 --- end --- return getnext(start), new, new --- end +local txtdirstate, pardirstate do -- this might change (no need for nxt in pardirstate) -local function txtdirstate(start,stack,top,rlparmode) - local nxt = getnext(start) - local dir = getdir(start) - if dir == "+TRT" then - top = top + 1 - stack[top] = dir - return nxt, top, -1 - elseif dir == "+TLT" then - top = top + 1 - stack[top] = dir - return nxt, top, 1 - elseif dir == "-TRT" or dir == "-TLT" then - if top == 1 then - return nxt, 0, rlparmode - else - top = top - 1 - if stack[top] == "+TRT" then - return nxt, top, -1 + local getdirection = nuts.getdirection + local lefttoright = 0 + local righttoleft = 1 + + txtdirstate = function(start,stack,top,rlparmode) + local dir, pop = getdirection(start) + if pop then + if top == 1 then + return 0, rlparmode else - return nxt, top, 1 + top = top - 1 + if stack[top] == righttoleft then + return top, -1 + else + return top, 1 + end end + elseif dir == lefttoright then + top = top + 1 + stack[top] = lefttoright + return top, 1 + elseif dir == righttoleft then + top = top + 1 + stack[top] = righttoleft + return top, -1 + else + return top, rlparmode end - else - return nxt, top, rlparmode end -end -local function pardirstate(start) - local nxt = getnext(start) - local dir = getdir(start) - if dir == "TLT" then - return nxt, 1, 1 - elseif dir == "TRT" then - return nxt, -1, -1 - else - return nxt, 0, 0 + pardirstate = function(start) + local dir = getdirection(start) + if dir == lefttoright then + return 1, 1 + elseif dir == righttoleft then + return -1, -1 + -- for old times sake we we handle strings too + elseif dir == "TLT" then + return 1, 1 + elseif dir == "TRT" then + return -1, -1 + else + return 0, 0 + end end + end --- -- this will become: --- --- local getdirection = nuts.getdirection --- --- local function txtdirstate1(start,stack,top,rlparmode) --- local nxt = getnext(start) --- local dir, sub = getdirection(start) --- if sub then --- if top == 1 then --- return nxt, 0, rlparmode --- elseif dir < 2 then --- top = top - 1 --- if stack[top] == 1 then --- return nxt, top, -1 --- else --- return nxt, top, 1 --- end --- else --- return nxt, top, rlparmode --- end --- elseif dir == 1 then --- top = top + 1 --- stack[top] = 1 --- return nxt, top, -1 --- elseif dir == 0 then --- top = top + 1 --- stack[top] = 0 --- return nxt, top, 1 --- else --- return nxt, top, rlparmode --- end --- end --- --- local function pardirstate1(start) --- local nxt = getnext(start) --- local dir = getdirection(start) --- if dir == 0 then --- return nxt, 1, 1 --- elseif dir == 1 then --- return nxt, -1, -1 --- else --- return nxt, 0, 0 --- end --- end +-- These are non public helpers that can change without notice! otf.helpers = otf.helpers or { } otf.helpers.txtdirstate = txtdirstate @@ -3832,20 +3795,23 @@ do -- attr = false -- end - local head = tonut(head) - if trace_steps then checkstep(head) end - local initialrl = direction == "TRT" and -1 or 0 - -- local initialrl = (direction == 1 or direction == "TRT") and -1 or 0 + local initialrl = 0 - local done = false - -- local datasets = otf.dataset(tfmdata,font,attr) + if getid(head) == localpar_code and getsubtype(head) == 0 then + initialrl = pardirstate(head) + elseif direction == 1 or direction == "TRT" then + initialrl = -1 + end + + -- local done = false local datasets = otfdataset(tfmdata,font,attr) - local dirstack = { } -- could move outside function but we can have local runs + local dirstack = { nil } -- could move outside function but we can have local runs sweephead = { } + -- sweephead = { a = 1, b = 1 } sweephead.a = nil sweephead.b = nil -- Keeping track of the headnode is needed for devanagari. (I generalized it a bit -- so that multiple cases are also covered.) We could prepend a temp node. @@ -3872,9 +3838,9 @@ do -- are not frozen as we might extend or change this. Is this used at all apart from some -- experiments? local h, ok = handler(head,dataset,sequence,initialrl,font,attr) -- less arguments now - if ok then - done = true - end + -- if ok then + -- done = true + -- end if h and h ~= head then head = h end @@ -3907,7 +3873,7 @@ do local ok head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) if ok then - done = true + -- done = true break end end @@ -3948,12 +3914,14 @@ do a = true end if a then - local ok - head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done = true - end - if start then + local ok, df + head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + -- if ok then + -- done = true + -- end + if df then +-- print("restart 1",typ) + elseif start then start = getnext(start) end else @@ -3976,18 +3944,20 @@ do else start, ok = comprun(start,c_run_single, font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) end - if ok then - done = true - end + -- if ok then + -- done = true + -- end else start = getnext(start) end elseif id == math_code then start = getnext(end_of_math(start)) elseif id == dir_code then - start, topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) - elseif id == localpar_code then - start, rlparmode, rlmode = pardirstate(start) + topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) + start = getnext(start) + -- elseif id == localpar_code then + -- rlparmode, rlmode = pardirstate(start) + -- start = getnext(start) else start = getnext(start) end @@ -4011,6 +3981,7 @@ do a = true end if a then + local ok, df for i=m[1],m[2] do local step = steps[i] -- for i=1,#m do @@ -4019,10 +3990,12 @@ do local lookupmatch = lookupcache[char] if lookupmatch then -- we could move all code inline but that makes things even more unreadable - local ok - head, start, ok = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done = true +-- local ok, df + head, start, ok, df = handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + break + elseif ok then + -- done = true break elseif not start then -- don't ask why ... shouldn't happen @@ -4030,7 +4003,9 @@ do end end end - if start then + if df then +-- print("restart 2",typ) + elseif start then start = getnext(start) end else @@ -4053,18 +4028,20 @@ do else start, ok = comprun(start,c_run_multiple, font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) end - if ok then - done = true - end + -- if ok then + -- done = true + -- end else start = getnext(start) end elseif id == math_code then start = getnext(end_of_math(start)) elseif id == dir_code then - start, topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) - elseif id == localpar_code then - start, rlparmode, rlmode = pardirstate(start) + topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) + start = getnext(start) + -- elseif id == localpar_code then + -- rlparmode, rlmode = pardirstate(start) + -- start = getnext(start) else start = getnext(start) end @@ -4079,12 +4056,12 @@ do end nesting = nesting - 1 - head = tonode(head) - return head, done + -- return head, done + return head end - -- This is not an official helpoer and used for tracing experiments. It can be changed as I like + -- This is not an official helper and used for tracing experiments. It can be changed as I like -- at any moment. At some point it might be used in a module that can help font development. function otf.datasetpositionprocessor(head,font,direction,dataset) @@ -4118,12 +4095,10 @@ do local steps = sequence.steps local nofsteps = sequence.nofsteps - local head = tonut(head) local done = false - local dirstack = { } -- could move outside function but we can have local runs + local dirstack = { nil } -- could move outside function but we can have local runs (maybe a few more nils) local start = head - local initialrl = direction == "TRT" and -1 or 0 - -- local initialrl = (direction == 1 or direction == "TRT") and -1 or 0 + local initialrl = (direction == 1 or direction == "TRT") and -1 or 0 local rlmode = initialrl local rlparmode = initialrl local topstack = 0 @@ -4173,15 +4148,17 @@ do elseif id == math_code then start = getnext(end_of_math(start)) elseif id == dir_code then - start, topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) - elseif id == localpar_code then - start, rlparmode, rlmode = pardirstate(start) + topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) + start = getnext(start) + -- elseif id == localpar_code then + -- rlparmode, rlmode = pardirstate(start) + -- start = getnext(start) else start = getnext(start) end end - return tonode(head) -- , matches + return head end -- end of experiment @@ -4193,9 +4170,26 @@ end local plugins = { } otf.plugins = plugins +local report = logs.reporter("fonts") + function otf.registerplugin(name,f) if type(name) == "string" and type(f) == "function" then plugins[name] = { name, f } + report() + report("plugin %a has been loaded, please be aware of possible side effects",name) + report() + if logs.pushtarget then + logs.pushtarget("log") + end + report("Plugins are not officially supported unless stated otherwise. This is because") + report("they bypass the regular font handling and therefore some features in ConTeXt") + report("(especially those related to fonts) might not work as expected or might not work") + report("at all. Some plugins are for testing and development only and might change") + report("whenever we feel the need for it.") + report() + if logs.poptarget then + logs.poptarget() + end end end diff --git a/tex/context/base/mkiv/font-ott.lua b/tex/context/base/mkiv/font-ott.lua index 59d92f40d..10420f6ee 100644 --- a/tex/context/base/mkiv/font-ott.lua +++ b/tex/context/base/mkiv/font-ott.lua @@ -8,7 +8,8 @@ if not modules then modules = { } end modules ["font-ott"] = { } local type, next, tonumber, tostring, rawget, rawset = type, next, tonumber, tostring, rawget, rawset -local gsub, lower, format, match = string.gsub, string.lower, string.format, string.match +local gsub, lower, format, match, gmatch, find = string.gsub, string.lower, string.format, string.match, string.gmatch, string.find +local sequenced = table.sequenced local is_boolean = string.is_boolean local setmetatableindex = table.setmetatableindex @@ -389,6 +390,7 @@ local languages = allocate { ["kiu" ] = "kirmanjki", ["kjd" ] = "southern kiwai", ["kjp" ] = "eastern pwo karen", + ["kjz" ] = "bumthangkha", ["kkn" ] = "kokni", ["klm" ] = "kalmyk", ["kmb" ] = "kamba", @@ -477,6 +479,7 @@ local languages = allocate { ["mdr" ] = "mandar", ["men" ] = "me'en", ["mer" ] = "meru", + ["mfa" ] = "pattani malay", ["mfe" ] = "morisyen", ["min" ] = "minangkabau", ["miz" ] = "mizo", @@ -674,6 +677,7 @@ local languages = allocate { ["tpi" ] = "tok pisin", ["trk" ] = "turkish", ["tsg" ] = "tsonga", + ["tsj" ] = "tshangla", ["tua" ] = "turoyo aramaic", ["tul" ] = "tulu", ["tuv" ] = "tuvin", @@ -704,6 +708,7 @@ local languages = allocate { ["xbd" ] = "lü", ["xhs" ] = "xhosa", ["xjb" ] = "minjangbal", + ["xkf" ] = "khengkha", ["xog" ] = "soga", ["xpe" ] = "kpelle (liberia)", ["yak" ] = "sakha", @@ -987,9 +992,13 @@ setmetatableindex(languages, function(t,k) return "dflt" end) -setmetatablenewindex(languages, "ignore") -setmetatablenewindex(baselines, "ignore") -setmetatablenewindex(baselines, "ignore") +if setmetatablenewindex then + + setmetatablenewindex(languages, "ignore") + setmetatablenewindex(scripts, "ignore") + setmetatablenewindex(baselines, "ignore") + +end local function resolve(t,k) if k then @@ -1029,7 +1038,11 @@ local function assign(t,k,v) end end -setmetatablenewindex(features, assign) +if setmetatablenewindex then + + setmetatablenewindex(features, assign) + +end local checkers = { rand = function(v) @@ -1085,7 +1098,7 @@ storage.register("fonts/otf/usedfeatures", usedfeatures, "fonts.handlers.otf.sta local normalizedaxis = otf.readers.helpers.normalizedaxis or function(s) return s end -function otffeatures.normalize(features) +function otffeatures.normalize(features,wrap) -- wrap is for context if features then local h = { } for key, value in next, features do @@ -1098,9 +1111,9 @@ function otffeatures.normalize(features) h.script = rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" -- auto adds elseif k == "axis" then h[k] = normalizedaxis(value) -if not callbacks.supported.glyph_stream_provider then - h.variableshapes = true -- for the moment -end + if not callbacks.supported.glyph_stream_provider then + h.variableshapes = true -- for the moment + end else local uk = usedfeatures[key] local uv = uk[value] @@ -1113,10 +1126,27 @@ end elseif type(value) == "string" then local b = is_boolean(value) if type(b) == "nil" then - uv = lower(value) + -- we do this elsewhere + -- + -- if find(value,"=") then + -- local t = { } + -- for k, v in gmatch(value,"([^%s,=]+)%s*=%s*([^%s,=]+)") do + -- t[k] = tonumber(v) or v + -- end + -- if next(t) then + -- value = sequenced(t,",") + -- end + -- end + if wrap and find(value,",") then + uv = "{"..lower(value).."}" + else + uv = lower(value) + end else uv = b end + elseif type(value) == "table" then + uv = sequenced(t,",") else uv = value end diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index 79ac76abe..d1faadbf7 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -11,27 +11,34 @@ local P, R, S = lpeg.P, lpeg.R, lpeg.S local lpegmatch = lpeg.match local insert, remove, copy, unpack = table.insert, table.remove, table.copy, table.unpack -local formatters = string.formatters -local sortedkeys = table.sortedkeys -local sortedhash = table.sortedhash -local tohash = table.tohash -local setmetatableindex = table.setmetatableindex - -local report = logs.reporter("otf reader") - -local trace_markwidth = false trackers.register("otf.markwidth",function(v) trace_markwidth = v end) - -local readers = fonts.handlers.otf.readers -local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF - -local f_private = formatters["P%05X"] -local f_unicode = formatters["U%05X"] -local f_index = formatters["I%05X"] -local f_character_y = formatters["%C"] -local f_character_n = formatters["[ %C ]"] - -local check_duplicates = true -- can become an option (pseudo feature) / aways needed anyway -local check_soft_hyphen = true -- can become an option (pseudo feature) / needed for tagging +local formatters = string.formatters +local sortedkeys = table.sortedkeys +local sortedhash = table.sortedhash +local tohash = table.tohash +local setmetatableindex = table.setmetatableindex + +local report_error = logs.reporter("otf reader","error") +local report_markwidth = logs.reporter("otf reader","markwidth") +local report_cleanup = logs.reporter("otf reader","cleanup") +local report_optimizations = logs.reporter("otf reader","merges") +local report_unicodes = logs.reporter("otf reader","unicodes") + +local trace_markwidth = false trackers.register("otf.markwidth", function(v) trace_markwidth = v end) +local trace_cleanup = false trackers.register("otf.cleanups", function(v) trace_cleanups = v end) +local trace_optimizations = false trackers.register("otf.optimizations", function(v) trace_optimizations = v end) +local trace_unicodes = false trackers.register("otf.unicodes", function(v) trace_unicodes = v end) + +local readers = fonts.handlers.otf.readers +local privateoffset = fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -- 0x10FFFF + +local f_private = formatters["P%05X"] +local f_unicode = formatters["U%05X"] +local f_index = formatters["I%05X"] +local f_character_y = formatters["%C"] +local f_character_n = formatters["[ %C ]"] + +local check_duplicates = true -- can become an option (pseudo feature) / aways needed anyway +local check_soft_hyphen = true -- can become an option (pseudo feature) / needed for tagging directives.register("otf.checksofthyphen",function(v) check_soft_hyphen = v @@ -67,6 +74,8 @@ local function unifyresources(fontdata,indices) return end -- + local nofindices = #indices + -- local variants = fontdata.resources.variants if variants then for selector, unicodes in next, variants do @@ -83,8 +92,8 @@ local function unifyresources(fontdata,indices) local u = indices[k] if u then newmarks[u] = v - else - report("discarding mark %i",k) + elseif trace_optimizations then + report_optimizations("discarding mark %i",k) end end return newmarks @@ -123,7 +132,12 @@ local function unifyresources(fontdata,indices) if not done[c] then local t = { } for k, v in next, c do - t[indices[k]] = v + local ug = indices[k] + if ug then + t[ug] = v + else + report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices) + end end cover[i] = t done[c] = d @@ -131,11 +145,16 @@ local function unifyresources(fontdata,indices) end end -- - local function recursed(c) -- ligs are not packed + local function recursed(c,kind) -- ligs are not packed local t = { } for g, d in next, c do if type(d) == "table" then - t[indices[g]] = recursed(d) + local ug = indices[g] + if ug then + t[ug] = recursed(d,kind) + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices) + end else t[g] = indices[d] -- ligature end @@ -167,19 +186,31 @@ local function unifyresources(fontdata,indices) if duplicates then for g1, d1 in next, c do local ug1 = indices[g1] - local ud1 = indices[d1] - t1[ug1] = ud1 - -- - local dg1 = duplicates[ug1] - if dg1 then - for u in next, dg1 do - t1[u] = ud1 + if ug1 then + local ud1 = indices[d1] + if ud1 then + t1[ug1] = ud1 + local dg1 = duplicates[ug1] + if dg1 then + for u in next, dg1 do + t1[u] = ud1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices) end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) end end else for g1, d1 in next, c do - t1[indices[g1]] = indices[d1] + local ug1 = indices[g1] + if ug1 then + t1[ug1] = indices[d1] + else + report_error("fuzzy case %i in unifying %s: %i",2,kind,g1) + end end end done[c] = t1 @@ -193,15 +224,25 @@ local function unifyresources(fontdata,indices) if not t1 then t1 = { } for g1, d1 in next, c do - local t2 = done[d1] - if not t2 then - t2 = { } - for g2, d2 in next, d1 do - t2[indices[g2]] = d2 + local ug1 = indices[g1] + if ug1 then + local t2 = done[d1] + if not t2 then + t2 = { } + for g2, d2 in next, d1 do + local ug2 = indices[g2] + if ug2 then + t2[ug2] = d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices) + end + end + done[d1] = t2 end - done[d1] = t2 + t1[ug1] = t2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) end - t1[indices[g1]] = t2 end done[c] = t1 end @@ -210,7 +251,7 @@ local function unifyresources(fontdata,indices) elseif kind == "gsub_ligature" then local c = step.coverage if c then - step.coverage = recursed(c) + step.coverage = recursed(c,kind) end elseif kind == "gsub_alternate" or kind == "gsub_multiple" then local c = step.coverage @@ -221,22 +262,37 @@ local function unifyresources(fontdata,indices) if duplicates then for g1, d1 in next, c do for i=1,#d1 do - d1[i] = indices[d1[i]] + local d1i = d1[i] + local d1u = indices[d1i] + if d1u then + d1[i] = d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices) + end end local ug1 = indices[g1] - t1[ug1] = d1 - -- - local dg1 = duplicates[ug1] - if dg1 then - for u in next, dg1 do - t1[u] = copy(d1) + if ug1 then + t1[ug1] = d1 + local dg1 = duplicates[ug1] + if dg1 then + for u in next, dg1 do + t1[u] = copy(d1) + end end + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) end end else for g1, d1 in next, c do for i=1,#d1 do - d1[i] = indices[d1[i]] + local d1i = d1[i] + local d1u = indices[d1i] + if d1u then + d1[i] = d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices) + end end t1[indices[g1]] = d1 end @@ -245,6 +301,41 @@ local function unifyresources(fontdata,indices) end step.coverage = t1 end + elseif kind == "gpos_single" then + local c = step.coverage + if c then + local t1 = done[c] + if not t1 then + t1 = { } + if duplicates then + for g1, d1 in next, c do + local ug1 = indices[g1] + if ug1 then + t1[ug1] = d1 + local dg1 = duplicates[ug1] + if dg1 then + for u in next, dg1 do + t1[u] = d1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1, d1 in next, c do + local ug1 = indices[g1] + if ug1 then + t1[ug1] = d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end + end + end + done[c] = t1 + end + step.coverage = t1 + end elseif kind == "gpos_mark2base" or kind == "gpos_mark2mark" or kind == "gpos_mark2ligature" then local c = step.coverage if c then @@ -252,7 +343,12 @@ local function unifyresources(fontdata,indices) if not t1 then t1 = { } for g1, d1 in next, c do - t1[indices[g1]] = d1 + local ug1 = indices[g1] + if ug1 then + t1[ug1] = d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end end done[c] = t1 end @@ -267,7 +363,12 @@ local function unifyresources(fontdata,indices) if not t2 then t2 = { } for g2, d2 in next, d1 do - t2[indices[g2]] = d2 + local ug2 = indices[g2] + if ug2 then + t2[ug2] = d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices) + end end done[d1] = t2 end @@ -276,7 +377,7 @@ local function unifyresources(fontdata,indices) done[c] = c end end - elseif kind == "gpos_single" then + elseif kind == "gpos_cursive" then local c = step.coverage if c then local t1 = done[c] @@ -285,47 +386,29 @@ local function unifyresources(fontdata,indices) if duplicates then for g1, d1 in next, c do local ug1 = indices[g1] - t1[ug1] = d1 - -- - local dg1 = duplicates[ug1] - if dg1 then - for u in next, dg1 do - t1[u] = d1 + if ug1 then + t1[ug1] = d1 + -- + local dg1 = duplicates[ug1] + if dg1 then + -- probably needs a bit more + for u in next, dg1 do + t1[u] = copy(d1) + end end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) end end else - for g1, d1 in next, c do - t1[indices[g1]] = d1 - end - end - done[c] = t1 - end - step.coverage = t1 - end - elseif kind == "gpos_cursive" then - local c = step.coverage - if c then - local t1 = done[c] - if not t1 then - t1 = { } - if duplicates then for g1, d1 in next, c do local ug1 = indices[g1] - t1[ug1] = d1 - -- - local dg1 = duplicates[ug1] - if dg1 then - -- probably needs a bit more - for u in next, dg1 do - t1[u] = copy(d1) - end + if ug1 then + t1[ug1] = d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) end end - else - for g1, d1 in next, c do - t1[indices[g1]] = d1 - end end done[c] = t1 end @@ -376,9 +459,13 @@ local function copyduplicates(fontdata) if not ds or ds.width == 0 then if ds then descriptions[0xAD] = nil - report("patching soft hyphen") + if trace_unicodes then + report_unicodes("patching soft hyphen") + end else - report("adding soft hyphen") + if trace_unicodes then + report_unicodes("adding soft hyphen") + end end if not duplicates then duplicates = { } @@ -414,10 +501,12 @@ local function copyduplicates(fontdata) end n = n + 1 end - if n <= m then - report("duplicates: %i : % t",n,t) - else - report("duplicates: %i : % t ...",n,t) + if trace_unicodes then + if n <= m then + report_unicodes("%i : % t",n,t) + else + report_unicodes("%i : % t ...",n,t) + end end else -- what a mess @@ -457,7 +546,6 @@ local function checklookups(fontdata,missing,nofmissing) end end end - local function collectthem(sequences) if not sequences then return @@ -549,7 +637,9 @@ local function checklookups(fontdata,missing,nofmissing) end end if nofmissing <= 0 then - report("all done in %s loops",loops) + if trace_unicodes then + report_unicodes("all missings done in %s loops",loops) + end return elseif old == nofmissing then break @@ -601,7 +691,9 @@ local function checklookups(fontdata,missing,nofmissing) recursed(ligatures[i]) end if nofmissing <= 0 then - report("all done in %s loops",loops) + if trace_unicodes then + report_unicodes("all missings done in %s loops",loops) + end return elseif old == nofmissing then break @@ -611,7 +703,7 @@ local function checklookups(fontdata,missing,nofmissing) n = 0 end - if nofmissing > 0 then + if trace_unicodes and nofmissing > 0 then local done = { } for i, r in next, missing do if r then @@ -623,7 +715,7 @@ local function checklookups(fontdata,missing,nofmissing) end end if next(done) then - report("not unicoded: % t",sortedkeys(done)) + report_unicodes("not unicoded: % t",sortedkeys(done)) end end end @@ -648,6 +740,10 @@ local function unifymissing(fontdata) resources.unicodes = nil end +local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 +local puafirst = 0xE000 +local pualast = 0xF8FF + local function unifyglyphs(fontdata,usenames) local private = fontdata.private or privateoffset local glyphs = fontdata.glyphs @@ -671,44 +767,107 @@ local function unifyglyphs(fontdata,usenames) indices[0] = zerocode end -- - for index=1,#glyphs do - local glyph = glyphs[index] - local unicode = glyph.unicode -- this is the primary one - if not unicode then - -- report("assigning private unicode %U to glyph indexed %05X (%s)",private,index,"unset") - unicode = private - -- glyph.unicode = -1 - if names then + if names then + -- seldom uses, we don't issue message ... this branch might even go away + for index=1,#glyphs do + local glyph = glyphs[index] + local unicode = glyph.unicode -- this is the primary one + if not unicode then + unicode = private local name = glyph.name or f_private(unicode) indices[index] = name names[name] = unicode - else - indices[index] = unicode - end - private = private + 1 - elseif descriptions[unicode] then - -- real weird - report("assigning private unicode %U to glyph indexed %05X (%C)",private,index,unicode) - unicode = private - -- glyph.unicode = -1 - if names then + private = private + 1 + elseif unicode >= firstprivate then + unicode = private local name = glyph.name or f_private(unicode) indices[index] = name names[name] = unicode + private = private + 1 + elseif unicode >= puafirst and unicode <= pualast then + local name = glyph.name or f_private(unicode) + indices[index] = name + names[name] = unicode + elseif descriptions[unicode] then + unicode = private + local name = glyph.name or f_private(unicode) + indices[index] = name + names[name] = unicode + private = private + 1 else - indices[index] = unicode - end - private = private + 1 - else - if names then local name = glyph.name or f_unicode(unicode) indices[index] = name names[name] = unicode + end + descriptions[unicode] = glyph + end + elseif trace_unicodes then + for index=1,#glyphs do + local glyph = glyphs[index] + local unicode = glyph.unicode -- this is the primary one + if not unicode then + unicode = private + indices[index] = unicode + private = private + 1 + elseif unicode >= firstprivate then + local name = glyph.name + if name then + report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private) + else + report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private) + end + unicode = private + indices[index] = unicode + private = private + 1 + elseif unicode >= puafirst and unicode <= pualast then + local name = glyph.name + if name then + report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index) + else + report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index) + end + indices[index] = unicode + elseif descriptions[unicode] then + local name = glyph.name + if name then + report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index) + else + report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index) + end + unicode = private + indices[index] = unicode + private = private + 1 else indices[index] = unicode end + descriptions[unicode] = glyph + end + else + for index=1,#glyphs do + local glyph = glyphs[index] + local unicode = glyph.unicode -- this is the primary one + if not unicode then + unicode = private + indices[index] = unicode + private = private + 1 + elseif unicode >= firstprivate then + local name = glyph.name + unicode = private + indices[index] = unicode + private = private + 1 + elseif unicode >= puafirst and unicode <= pualast then + local name = glyph.name + indices[index] = unicode + elseif descriptions[unicode] then + local name = glyph.name + unicode = private + indices[index] = unicode + private = private + 1 + else + indices[index] = unicode + end + descriptions[unicode] = glyph end - descriptions[unicode] = glyph end -- for index=1,#glyphs do @@ -757,37 +916,93 @@ local function unifyglyphs(fontdata,usenames) return indices, names end -local p_bogusname = ( - (P("uni") + P("UNI") + P("Uni") + P("U") + P("u")) * S("Xx")^0 * R("09","AF")^1 - + (P("identity") + P("Identity") + P("IDENTITY")) * R("09","AF")^1 - + (P("index") + P("Index") + P("INDEX")) * R("09")^1 -) * P(-1) +local p_crappyname do + + local p_hex = R("af","AF","09") + local p_digit = R("09") + local p_done = S("._-")^0 + P(-1) + local p_alpha = R("az","AZ") + local p_ALPHA = R("AZ") + + p_crappyname = ( + -- (P("uni") + P("UNI") + P("Uni") + P("U") + P("u")) + lpeg.utfchartabletopattern({ "uni", "u" },true) + * S("Xx_")^0 + * p_hex^1 + -- + (P("identity") + P("Identity") + P("IDENTITY") + P("glyph") + P("jamo")) + + lpeg.utfchartabletopattern({ "identity", "glyph", "jamo" },true) + * p_hex^1 + -- + (P("index") + P("Index") + P("INDEX")+ P("afii")) + + lpeg.utfchartabletopattern({ "index", "afii" }, true) + * p_digit^1 + -- also happens l + + p_digit + * p_hex^3 + + p_alpha + * p_digit^1 + -- sort of special + + P("aj") + * p_digit^1 + + P("eh_") + * (p_digit^1 + p_ALPHA * p_digit^1) + + (1-P("_"))^1 + * P("_uni") + * p_hex^1 + + P("_") + * P(1)^1 + ) * p_done + +end + +-- In context we only keep glyph names because of tracing and access by name +-- so weird names make no sense. + +local forcekeep = false -- only for testing something + +directives.register("otf.keepnames",function(v) + report_cleanup("keeping weird glyph names, expect larger files and more memory usage") + forcekeep = v +end) local function stripredundant(fontdata) local descriptions = fontdata.descriptions if descriptions then local n = 0 local c = 0 - for unicode, d in next, descriptions do - local name = d.name - if name and lpegmatch(p_bogusname,name) then - d.name = nil - n = n + 1 + -- in context we always strip + if (not context and fonts.privateoffsets.keepnames) or forcekeep then + for unicode, d in next, descriptions do + if d.class == "base" then + d.class = nil + c = c + 1 + end end - if d.class == "base" then - d.class = nil - c = c + 1 + else + for unicode, d in next, descriptions do + local name = d.name + if name and lpegmatch(p_crappyname,name) then + d.name = nil + n = n + 1 + end + if d.class == "base" then + d.class = nil + c = c + 1 + end end end - if n > 0 then - report("%s bogus names removed (verbose unicode)",n) - end - if c > 0 then - report("%s base class tags removed (default is base)",c) + if trace_cleanup then + if n > 0 then + report_cleanup("%s bogus names removed (verbose unicode)",n) + end + if c > 0 then + report_cleanup("%s base class tags removed (default is base)",c) + end end end end +readers.stripredundant = stripredundant + function readers.getcomponents(fontdata) -- handy for resolving ligatures when names are missing local resources = fontdata.resources if resources then @@ -813,9 +1028,9 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n end for i=1,#steps do -- we actually had/have this in base mode - local coverage = steps[i].coverage - if coverage then - for k, v in next, coverage do + local c = steps[i].coverage + if c then + for k, v in next, c do traverse(k,k,v) end end @@ -1251,7 +1466,9 @@ function readers.pack(data) end return false elseif nt >= threshold then - local one, two, rest = 0, 0, 0 + local one = 0 + local two = 0 + local rest = 0 if pass == 1 then for k,v in next, c do if v == 1 then @@ -2125,17 +2342,24 @@ local function mergesteps_1(lookup,strict) local f = first.format for i=2,nofsteps do if steps[i].format ~= f then - report("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end return 0 end end end - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end local target = first.coverage for i=2,nofsteps do - for k, v in next, steps[i].coverage do - if not target[k] then - target[k] = v + local c = steps[i].coverage + if c then + for k, v in next, c do + if not target[k] then + target[k] = v + end end end end @@ -2156,24 +2380,31 @@ local function mergesteps_2(lookup) -- pairs local f = first.format for i=2,nofsteps do if steps[i].format ~= f then - report("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end return 0 end end end - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end local target = first.coverage for i=2,nofsteps do - for k, v in next, steps[i].coverage do - local tk = target[k] - if tk then - for kk, vv in next, v do - if tk[kk] == nil then - tk[kk] = vv + local c = steps[i].coverage + if c then + for k, v in next, c do + local tk = target[k] + if tk then + for kk, vv in next, v do + if tk[kk] == nil then + tk[kk] = vv + end end + else + target[k] = v end - else - target[k] = v end end end @@ -2189,17 +2420,24 @@ end local function mergesteps_3(lookup,strict) -- marks local steps = lookup.steps local nofsteps = lookup.nofsteps - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end -- check first local coverage = { } for i=1,nofsteps do - for k, v in next, steps[i].coverage do - local tk = coverage[k] -- { class, { x, y } } - if tk then - report("quitting merge due to multiple checks") - return nofsteps - else - coverage[k] = v + local c = steps[i].coverage + if c then + for k, v in next, c do + local tk = coverage[k] -- { class, { x, y } } + if tk then + if trace_optimizations then + report_optimizations("quitting merge due to multiple checks") + end + return nofsteps + else + coverage[k] = v + end end end end @@ -2245,15 +2483,20 @@ local function mergesteps_4(lookup) -- ligatures local steps = lookup.steps local nofsteps = lookup.nofsteps local first = steps[1] - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end local target = first.coverage for i=2,nofsteps do - for k, v in next, steps[i].coverage do - local tk = target[k] - if tk then - nested(v,tk) - else - target[k] = v + local c = steps[i].coverage + if c then + for k, v in next, c do + local tk = target[k] + if tk then + nested(v,tk) + else + target[k] = v + end end end end @@ -2270,7 +2513,9 @@ local function mergesteps_5(lookup) -- cursive local steps = lookup.steps local nofsteps = lookup.nofsteps local first = steps[1] - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end local target = first.coverage local hash = nil for k, v in next, target do @@ -2278,18 +2523,21 @@ local function mergesteps_5(lookup) -- cursive break end for i=2,nofsteps do - for k, v in next, steps[i].coverage do - local tk = target[k] - if tk then - if not tk[2] then - tk[2] = v[2] - end - if not tk[3] then - tk[3] = v[3] + local c = steps[i].coverage + if c then + for k, v in next, c do + local tk = target[k] + if tk then + if not tk[2] then + tk[2] = v[2] + end + if not tk[3] then + tk[3] = v[3] + end + else + target[k] = v + v[1] = hash end - else - target[k] = v - v[1] = hash end end end @@ -2319,7 +2567,9 @@ local function checkkerns(lookup) end end if kerns then - report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end local c = { } for g1, d1 in next, coverage do if d1 and d1 ~= true then @@ -2379,7 +2629,9 @@ local function checkpairs(lookup) if step.format == "pair" then local coverage = onlykerns(step) if coverage then - report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end for g1, d1 in next, coverage do local d = { } for g2, d2 in next, d1 do @@ -2502,17 +2754,19 @@ function readers.compact(data) end end end - else - report("no lookups in %a",what) + elseif trace_optimizations then + report_optimizations("no lookups in %a",what) end end compact("sequences") compact("sublookups") - if merged > 0 then - report("%i steps of %i removed due to merging",merged,allsteps) - end - if kerned > 0 then - report("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) + if trace_optimizations then + if merged > 0 then + report_optimizations("%i steps of %i removed due to merging",merged,allsteps) + end + if kerned > 0 then + report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) + end end end @@ -2612,7 +2866,7 @@ function readers.expand(data) -- or bb? d.width = defaultwidth elseif trace_markwidth and wd ~= 0 and d.class == "mark" then - report("mark %a with width %b found in %a",d.name or "",wd,basename) + report_markwidth("mark %a with width %b found in %a",d.name or "",wd,basename) end if bb then local ht = bb[4] diff --git a/tex/context/base/mkiv/font-pre.mkiv b/tex/context/base/mkiv/font-pre.mkiv index b49bc560e..c1c24b854 100644 --- a/tex/context/base/mkiv/font-pre.mkiv +++ b/tex/context/base/mkiv/font-pre.mkiv @@ -53,10 +53,7 @@ script=auto, % on speed; 'base' just doesn't play well with dynamics; some day we can even autoscript=position, autolanguage=position, -% ccmp=yes, kern=yes, % consider skipping the base passes when no base mode is used -% palt=yes, -% pwid=yes, mark=yes, mkmk=yes, curs=yes] @@ -323,6 +320,22 @@ \definefontfeature [tamil-two] [tamil-one] [script=tml2] \definefontfeature [telugu-two] [telugu-one] [script=tel2] +% tibetan + +\definefontfeature + [tibetan] + [always] + [script=tibt, + language=dflt, + locl=yes, + ccmp=yes, + abvs=yes, + blws=yes, + calt=yes, + liga=yes, + abvm=yes, + blwm=yes] + % cjk \definefontfeature @@ -452,9 +465,37 @@ [slanted] [slant=.2] +% \definefontfeature +% [boldened] +% [extend=1.2] + +%D Neat: + +% By eye: +% +% \definefontfeature[boldened-10][effect={width=0.10,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.125,extend=1.025,squeeze=0.99250}] +% \definefontfeature[boldened-15][effect={width=0.15,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.250,extend=1.050,squeeze=0.98750}] +% \definefontfeature[boldened-20][effect={width=0.20,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.375,extend=1.075,squeeze=0.98125}] +% \definefontfeature[boldened-30][effect={width=0.30,delta=1.0,hdelta=0.500,ddelta=0.150,vshift=0.500,extend=1.100,squeeze=0.97500}] +% +% By calculation: +% +% \definefontfeature[boldened-10][effect={width=0.10,delta=1.0,hdelta=0.02500,ddelta=0.02500,vshift=0.02500,extend=1.050,squeeze=0.99500}] +% \definefontfeature[boldened-15][effect={width=0.15,delta=1.0,hdelta=0.05625,ddelta=0.05625,vshift=0.05625,extend=1.075,squeeze=0.99250}] +% \definefontfeature[boldened-20][effect={width=0.20,delta=1.0,hdelta=0.10000,ddelta=0.10000,vshift=0.10000,extend=1.100,squeeze=0.99000}] +% \definefontfeature[boldened-30][effect={width=0.30,delta=1.0,hdelta=0.22500,ddelta=0.22500,vshift=0.22500,extend=1.150,squeeze=0.98500}] +% +% So we can do this: + +\definefontfeature[boldened-10][effect={width=0.10,auto=yes}] +\definefontfeature[boldened-15][effect={width=0.15,auto=yes}] +\definefontfeature[boldened-20][effect={width=0.20,auto=yes}] +\definefontfeature[boldened-25][effect={width=0.25,auto=yes}] +\definefontfeature[boldened-30][effect={width=0.30,auto=yes}] + \definefontfeature [boldened] - [extend=1.2] + [boldened-30] %D Emoji: diff --git a/tex/context/base/mkiv/font-prv.lua b/tex/context/base/mkiv/font-prv.lua new file mode 100644 index 000000000..20c06d2e5 --- /dev/null +++ b/tex/context/base/mkiv/font-prv.lua @@ -0,0 +1,78 @@ +if not modules then modules = { } end modules ['font-prv'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type = type +local formatters = string.formatters + +local fonts = fonts +local helpers = fonts.helpers +local fontdata = fonts.hashes.identifiers + +local setmetatableindex = table.setmetatableindex + +local currentprivate = fonts.privateoffsets.textextrabase +local maximumprivate = currentprivate + 0xFFF + +local extraprivates = { } +helpers.extraprivates = extraprivates + +function fonts.helpers.addextraprivate(name,f) + extraprivates[#extraprivates+1] = { name, f } +end + +-- if we run out of space we can think of another range but by sharing we can +-- use these privates for mechanisms like alignments-on-character and such + +local sharedprivates = setmetatableindex(function(t,k) + local v = currentprivate + if currentprivate < maximumprivate then + currentprivate = currentprivate + 1 + else + -- reuse last slot, todo: warning + end + t[k] = v + return v +end) + +function helpers.addprivate(tfmdata,name,characterdata) + local properties = tfmdata.properties + local characters = tfmdata.characters + local privates = properties.privates + if not privates then + privates = { } + properties.privates = privates + end + if not name then + name = formatters["anonymous_private_0x%05X"](currentprivate) + end + local usedprivate = sharedprivates[name] + privates[name] = usedprivate + characters[usedprivate] = characterdata + return usedprivate +end + +function helpers.getprivates(tfmdata) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + return properties and properties.privates +end + +function helpers.hasprivate(tfmdata,name) + if type(tfmdata) == "number" then + tfmdata = fontdata[tfmdata] + end + local properties = tfmdata.properties + local privates = properties and properties.privates + return privates and privates[name] or false +end + +function helpers.privateslot(name) + return rawget(sharedprivates,name) +end diff --git a/tex/context/base/mkiv/font-sel.lua b/tex/context/base/mkiv/font-sel.lua index e7f56047b..15d3838f6 100644 --- a/tex/context/base/mkiv/font-sel.lua +++ b/tex/context/base/mkiv/font-sel.lua @@ -232,52 +232,6 @@ local m_alternative = { ["sc"] = "smallcaps" } ---~ methods["style"] = function(data,alternative,style) ---~ local family = data.metadata.family ---~ local style = m_alternative[style] or style ---~ if trace_alternatives then ---~ report_selectfont("Alternative '%s': Using method 'style' with argument '%s'",alternative,style) ---~ end ---~ local fontweight = m_name[style] and m_name[style]["weight"] or "regular" ---~ local fontstyle = m_name[style] and m_name[style]["style"] or "normal" ---~ local fontwidth = m_name[style] and m_name[style]["width"] or "normal" ---~ local pattern = getlookups{ ---~ familyname = cleanname(family), ---~ pfmweight = m_weight[fontweight], ---~ style = fontstyle ---~ } ---~ if #pattern == 1 then ---~ selectfont_savefile(data,alternative,0,"default",pattern[1]) ---~ elseif #pattern > 1 then ---~ local bodyfontsize, minsize, maxsize, width = nil, nil, nil, nil ---~ for patternindex, patternentry in next, pattern do ---~ minsize = patternentry["minsize"] ---~ maxsize = patternentry["maxsize"] ---~ width = patternentry["pfmwidth"] ---~ if minsize and maxsize then ---~ for fontsize, fontstate in next, bodyfontsizes do ---~ bodyfontsize, _ = number.splitdimen(fontsize) ---~ bodyfontsize = bodyfontsize * 10 ---~ if minsize < bodyfontsize and bodyfontsize < maxsize then ---~ if bodyfontsize == 100 then ---~ selectfont_savefile(data,alternative,0,"default",patternentry) ---~ end ---~ selectfont_savefile(data,alternative,bodyfontsize,fontsize,patternentry) ---~ end ---~ end ---~ else ---~ if width == m_width[fontwidth] then ---~ selectfont_savefile(data,alternative,0,"default",patternentry) ---~ end ---~ end ---~ end ---~ else ---~ if trace_alternatives then ---~ report_selectfont("Alternative '%s': No font was found for the requested style '%s' from '%s'",alternative,style,family) ---~ end ---~ end ---~ end - local function m_style_family(family) local askedname = cleanname(family) local familyname = getlookups{ familyname = askedname } @@ -348,7 +302,7 @@ local function m_style_style(entries,style) if style == "italic" and entry["angle"] and entry["angle"] ~= 0 then t[#t+1] = entry elseif style == "normal" and entry["angle"] and entry["angle"] ~= 0 then - --~ Fix needed for fonts with wrong value for the style field + -- Fix needed for fonts with wrong value for the style field elseif entry["style"] == style then t[#t+1] = entry end @@ -448,10 +402,10 @@ methods[v_default] = function(data,alternative) report_selectfont("Alternative '%s': The family '%s' contains only one font",alternative,family) end selectfont_savefile(data,alternative,0,"default",result[1]) - --~ if trace_alternatives then - --~ report_selectfont("Alternative '%s': Changing method 'default' to method 'style'",alternative) - --~ end - --~ methods["file"](data,alternative,result[1]["filename"]) + -- if trace_alternatives then + -- report_selectfont("Alternative '%s': Changing method 'default' to method 'style'",alternative) + -- end + -- methods["file"](data,alternative,result[1]["filename"]) else if trace_alternatives then report_selectfont("Alternative '%s': Changing method 'default' to method 'style'",alternative) @@ -499,38 +453,6 @@ function selectfont.userdata(index) end end ---~ function selectfont.registerfiles(index) ---~ local data = data[index] ---~ local colon = splitat(":",true) ---~ for alternative, _ in next, alternatives do ---~ local arguments = data.alternatives[alternative] ---~ if arguments ~= "" then ---~ local entries = settings_to_array(arguments) ---~ local setmethod = false ---~ for index, entry in next, entries do ---~ method, argument = lpegmatch(colon,entry) ---~ if not argument then ---~ argument = method ---~ method = "name" ---~ end ---~ if extras[method] then ---~ extras[method](data,alternative,argument) ---~ elseif methods[method] then ---~ if not setmethod then ---~ setmethod = true ---~ methods[method](data,alternative,argument) ---~ end ---~ end ---~ end ---~ if not setmethod then ---~ methods[v_default](data,alternative) ---~ end ---~ else ---~ methods[v_default](data,alternative) ---~ end ---~ end ---~ end - function selectfont.registerfiles(index) local data = data[index] local colon = splitat(":",true) @@ -662,8 +584,8 @@ function selectfont.fontsynonym(data,class,style,alternative,index) local fontsizes = sortedkeys(fontfiles) local fallback = index ~= 0 local fontclass = lower(class) - --~ local fontfeature = data.features and data.features[alternative] or data.options.features - --~ local fontgoodie = data.goodies and data.goodies [alternative] or data.options.goodies + --local fontfeature = data.features and data.features[alternative] or data.options.features + --local fontgoodie = data.goodies and data.goodies [alternative] or data.options.goodies local fontfeature = selectfont.features(data,style,alternative) local fontgoodie = selectfont.goodies (data,style,alternative) local synonym = m_synonym[style] and m_synonym[style][alternative] @@ -675,25 +597,25 @@ function selectfont.fontsynonym(data,class,style,alternative,index) end local fontfallback = formatters["fallback-%s-%s-%s"](fontclass,style,alternative) for _, fontsize in next, fontsizes do - --~ if trace_typescript then - --~ report_typescript("Synonym: '%s', Size: '%s', File: '%s'",fontfile,fontfiles[fontsize][1],fontfiles[fontsize][2]) - --~ end + -- if trace_typescript then + -- report_typescript("Synonym: '%s', Size: '%s', File: '%s'",fontfile,fontfiles[fontsize][1],fontfiles[fontsize][2]) + -- end registerdesignsizes(fontfile,fontfiles[fontsize][1],fontfiles[fontsize][2]) end if fallback then - --~ if trace_typescript then - --~ report_typescript("Synonym: '%s', File: '%s', Features: '%s'",fontsynonym,fontfile,fontfeature) - --~ end + -- if trace_typescript then + -- report_typescript("Synonym: '%s', File: '%s', Features: '%s'",fontsynonym,fontfile,fontfeature) + -- end ctx_definefontsynonym( { fontsynonym }, { fontfile }, { features = fontfeature } ) else - --~ if trace_typescript then - --~ report_typescript("Synonym: '%s', File: '%s', Features: '%s', Goodies: '%s', Fallbacks: '%s'",fontsynonym,fontfile,fontfeature,fontgoodie,fontfallback) - --~ end + -- if trace_typescript then + -- report_typescript("Synonym: '%s', File: '%s', Features: '%s', Goodies: '%s', Fallbacks: '%s'",fontsynonym,fontfile,fontfeature,fontgoodie,fontfallback) + -- end ctx_definefontsynonym( { fontsynonym }, { fontfile }, { features = fontfeature, goodies = fontgoodie, fallbacks = fontfallback } ) if synonym then - --~ if trace_typescript then - --~ report_typescript("Synonym: '%s', File: '%s'",synonym,fontsynonym) - --~ end + -- if trace_typescript then + -- report_typescript("Synonym: '%s', File: '%s'",synonym,fontsynonym) + -- end ctx_definefontsynonym( { synonym }, { fontsynonym } ) end end @@ -711,9 +633,9 @@ function selectfont.fontfallback(data,class,style,alternative,index) if index == 1 then ctx_resetfontfallback( { fontfallback } ) end - --~ if trace_typescript then - --~ report_typescript("Fallback: '%s', Synonym: '%s', Range: '%s', Scale: '%s', Check: '%s', Force: '%s'",fontfallback,fontsynonym,range,scale,check,force) - --~ end + -- if trace_typescript then + -- report_typescript("Fallback: '%s', Synonym: '%s', Range: '%s', Scale: '%s', Check: '%s', Force: '%s'",fontfallback,fontsynonym,range,scale,check,force) + -- end ctx_definefontfallback( { fontfallback }, { fontsynonym }, { range }, { rscale = scale, check = check, force = force } ) end @@ -730,9 +652,9 @@ function selectfont.filefallback(data,class,style,alternative,index) if index == 1 then ctx_resetfontfallback( { fontfallback } ) end - --~ if trace_typescript then - --~ report_typescript("Fallback: '%s', File: '%s', Features: '%s', Range: '%s', Scale: '%s', Check: '%s', Force: '%s', Offset: '%s'",fontfallback,fontfile[2],fontfeature,range,scale,check,force,offset) - --~ end + -- if trace_typescript then + -- report_typescript("Fallback: '%s', File: '%s', Features: '%s', Range: '%s', Scale: '%s', Check: '%s', Force: '%s', Offset: '%s'",fontfallback,fontfile[2],fontfeature,range,scale,check,force,offset) + -- end ctx_definefontfallback( { fontfallback }, { formatters["file:%s*%s"](fontfile[2],fontfeature) }, { range }, { rscale = scale, check = check, force = force, offset = offset } ) end @@ -763,9 +685,9 @@ function selectfont.fallback(data) local fallbacks = fallbacks[fontclass] and fallbacks[fontclass][fontstyle] if fallbacks then for index, entry in next, fallbacks do - --~ I need different fallback routines for math and text because - --~ font synonyms can’t be used with math fonts and I have to apply - --~ feature settings with the \definefontfallback command. + -- I need different fallback routines for math and text because + -- font synonyms can’t be used with math fonts and I have to apply + -- feature settings with the \definefontfallback command. if fontstyle == "mm" then selectfont.mathfallback(index,entry,fontclass,fontstyle) else @@ -792,7 +714,8 @@ function selectfont.typescript(data) end end for alternative, _ in next, alternatives do - if style == "mm" then -- Set math fonts only for upright and bold alternatives + if style == "mm" then + -- Set math fonts only for upright and bold alternatives if alternative == "tf" or alternative == "bf" then selectfont.fontsynonym (data,class,style,alternative,0) end @@ -813,9 +736,9 @@ function selectfont.bodyfont(data) for alternative, _ in next, alternatives do fontsynonym = formatters["synonym-%s-%s-%s"](fontclass,fontstyle,alternative) fontlist[#fontlist+1] = formatters["%s=%s sa 1"] (alternative,fontsynonym) - --~ if trace_typescript then - --~ report_typescript("Alternative '%s': Synonym '%s'",alternative,fontsynonym) - --~ end + -- if trace_typescript then + -- report_typescript("Alternative '%s': Synonym '%s'",alternative,fontsynonym) + -- end end fontlist = concat(fontlist,",") ctx_definebodyfont( { class }, { fontsizes }, { fontstyle }, { fontlist } ) @@ -836,9 +759,9 @@ function selectfont.typeface(data) local style = m_style[fontstyle] local size = data.options.designsize ~= "" and data.options.designsize or "default" local scale = data.options.rscale ~= "" and data.options.rscale or 1 - --~ if trace_typescript then - --~ report_typescript("Class: '%s', Style: '%s', Size: '%s', Scale: '%s'",fontclass,fontstyle,size,scale) - --~ end + -- if trace_typescript then + -- report_typescript("Class: '%s', Style: '%s', Size: '%s', Scale: '%s'",fontclass,fontstyle,size,scale) + -- end ctx_definetypeface( { fontclass }, { fontstyle }, { style }, { "" }, { "default" }, { designsize = size, rscale = scale } ) end diff --git a/tex/context/base/mkiv/font-set.mkvi b/tex/context/base/mkiv/font-set.mkvi index 2c6d065d8..aac83e1aa 100644 --- a/tex/context/base/mkiv/font-set.mkvi +++ b/tex/context/base/mkiv/font-set.mkvi @@ -46,7 +46,7 @@ % \def\font_preloads_reset_nullfont % this is needed because some macro packages (tikz) misuse \nullfont % {\dorecurse\plusseven{\fontdimen\recurselevel\nullfont\zeropoint}% keep en eye on this as: % \clf_resetnullfont % in luatex 0.70 this will also do the previous -% \globallet\font_preloads_reset_nullfont\relax} +% \glet\font_preloads_reset_nullfont\relax} \def\font_preload_check_mode {\doifelsemode{lmmath} @@ -122,14 +122,14 @@ \font_preloads_reset \else \font_preloads_reset - \pushmacro\fontstyle + \push_macro_fontstyle \ifcsname\??fontclass\fontclass\s!mm\s!features\endcsname \else \font_preload_default_fonts_mm \fi \ifcsname\??fontclass\fontclass\s!tt\s!features\endcsname \else \font_preload_default_fonts_tt \fi - \popmacro\fontstyle + \pop_macro_fontstyle \font_preloads_reset_checked % reset third, mm and tt \setupbodyfont[\fontstyle]% \fi} diff --git a/tex/context/base/mkiv/font-shp.lua b/tex/context/base/mkiv/font-shp.lua index 75a12ac82..d5c194c85 100644 --- a/tex/context/base/mkiv/font-shp.lua +++ b/tex/context/base/mkiv/font-shp.lua @@ -12,6 +12,7 @@ local formatters = string.formatters local otf = fonts.handlers.otf local afm = fonts.handlers.afm +local pfb = fonts.handlers.pfb local hashes = fonts.hashes local identifiers = hashes.identifiers @@ -39,7 +40,8 @@ local function packoutlines(data,makesequence) return end if makesequence then - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local glyph = glyphs[index] local segments = glyph.segments if segments then @@ -48,6 +50,7 @@ local function packoutlines(data,makesequence) for i=1,#segments do local segment = segments[i] local nofsegment = #segment + -- why last first ... needs documenting nofsequence = nofsequence + 1 sequence[nofsequence] = segment[nofsegment] for i=1,nofsegment-1 do @@ -64,7 +67,8 @@ local function packoutlines(data,makesequence) local common = { } local reverse = { } local last = 0 - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local segments = glyphs[index].segments if segments then for i=1,#segments do @@ -73,7 +77,8 @@ local function packoutlines(data,makesequence) end end end - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local segments = glyphs[index].segments if segments then for i=1,#segments do @@ -114,7 +119,8 @@ local function unpackoutlines(data) if not glyphs then return end - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local segments = glyphs[index].segments if segments then for i=1,#segments do @@ -131,7 +137,7 @@ end -- todo: loaders per format local readers = otf.readers -local cleanname = readers.helpers.cleanname +local cleanname = otf.readers.helpers.cleanname local function makehash(filename,sub,instance) local name = cleanname(file.basename(filename)) @@ -157,7 +163,7 @@ local function loadoutlines(cache,filename,sub,instance) local hash = makehash(filename,sub,instance) data = containers.read(cache,hash) if not data or data.time ~= time or data.size ~= size then - data = readers.loadshapes(filename,sub,instance) + data = otf.readers.loadshapes(filename,sub,instance) if data then data.size = size data.format = data.format or (kind == "otf" and "opentype") or "truetype" @@ -204,19 +210,16 @@ local function loadstreams(cache,filename,sub,instance) local size = attr and attr.size or 0 local time = attr and attr.modification or 0 local sub = tonumber(sub) - - -- fonts.formats - if size > 0 and (kind == "otf" or kind == "ttf" or kind == "tcc") then local hash = makehash(filename,sub,instance) data = containers.read(cache,hash) if not data or data.time ~= time or data.size ~= size then - data = readers.loadshapes(filename,sub,instance,true) + data = otf.readers.loadshapes(filename,sub,instance,true) if data then local glyphs = data.glyphs local streams = { } if glyphs then - for i=0,#glyphs do + for i=0,#glyphs-1 do streams[i] = glyphs[i].stream or "" end end @@ -229,13 +232,68 @@ local function loadstreams(cache,filename,sub,instance) data = containers.read(cache,hash) -- frees old mem end end + elseif size > 0 and (kind == "pfb") then + local hash = makehash(filename,sub,instance) + data = containers.read(cache,hash) + if not data or data.time ~= time or data.size ~= size then + local names, encoding, streams, metadata = pfb.loadvector(filename,false,true) + if streams then + local fontbbox = metadata.fontbbox or { 0, 0, 0, 0 } + for i=0,#streams do + streams[i] = streams[i].stream or "\14" + end + data = { + filename = filename, + size = size, + time = time, + format = "type1", + streams = streams, + fontheader = { + fontversion = metadata.version, + units = 1000, -- can this be different? + xmin = fontbbox[1], + ymin = fontbbox[2], + xmax = fontbbox[3], + ymax = fontbbox[4], + }, + horizontalheader = { + ascender = 0, + descender = 0, + }, + maximumprofile = { + nofglyphs = #streams + 1, + }, + names = { + copyright = metadata.copyright, + family = metadata.familyname, + fullname = metadata.fullname, + fontname = metadata.fontname, + subfamily = metadata.subfamilyname, + trademark = metadata.trademark, + notice = metadata.notice, + version = metadata.version, + }, + cffinfo = { + familyname = metadata.familyname, + fullname = metadata.fullname, + italicangle = metadata.italicangle, + monospaced = metadata.isfixedpitch and true or false, + underlineposition = metadata.underlineposition, + underlinethickness = metadata.underlinethickness, + weight = metadata.weight, + }, + } + containers.write(cache,hash,data) + data = containers.read(cache,hash) -- frees old mem + end + end else data = { filename = filename, size = 0, time = time, format = "unknown", - glyphs = { } + streams = { } } end return data @@ -265,7 +323,15 @@ hashes.shapes = table.setmetatableindex(function(t,k) end end) -local function loadstreamdata(fontdata,streams) +local function getstreamhash(fontid) + local fontdata = identifiers[fontid] + if fontdata then + local properties = fontdata.properties + return makehash(properties.filename,fontdata.subindex,properties.instance) + end +end + +local function loadstreamdata(fontdata) local properties = fontdata.properties local filename = properties.filename local subindex = fontdata.subindex @@ -289,12 +355,19 @@ end) otf.loadoutlinedata = loadoutlinedata -- not public otf.loadstreamdata = loadstreamdata -- not public otf.loadshapes = loadshapes +otf.getstreamhash = getstreamhash -- not public, might move to other namespace --- experimental code, for me only ... unsupported +-- experimental code, for me only ... unsupported (todo: use %N) -local f_c = string.formatters["%F %F %F %F %F %F c"] -local f_l = string.formatters["%F %F l"] -local f_m = string.formatters["%F %F m"] +local f_c = formatters["%F %F %F %F %F %F c"] +local f_l = formatters["%F %F l"] +local f_m = formatters["%F %F m"] + +directives.register("pdf.stripzeros",function() + f_c = formatters["%N %N %N %N %N %N c"] + f_l = formatters["%N %N l"] + f_m = formatters["%N %N m"] +end) local function segmentstopdf(segments,factor,bt,et) local t = { } @@ -316,9 +389,12 @@ local function segmentstopdf(segments,factor,bt,et) elseif w == "q" then local p = segments[i-1] local n = #p - local l_x, l_y = factor*p[n-2], factor*p[n-1] - local m_x, m_y = factor*s[1], factor*s[2] - local r_x, r_y = factor*s[3], factor*s[4] + local l_x = factor*p[n-2] + local l_y = factor*p[n-1] + local m_x = factor*s[1] + local m_y = factor*s[2] + local r_x = factor*s[3] + local r_y = factor*s[4] m = m + 1 t[m] = f_c ( l_x + 2/3 * (m_x-l_x), l_y + 2/3 * (m_y-l_y), @@ -338,7 +414,7 @@ local function segmentstopdf(segments,factor,bt,et) end end -local function addvariableshapes(tfmdata,key,value) +local function initialize(tfmdata,key,value) if value then local shapes = otf.loadoutlinedata(tfmdata) if not shapes then @@ -354,7 +430,9 @@ local function addvariableshapes(tfmdata,key,value) local factor = hfactor / 65536 local getactualtext = otf.getactualtext for unicode, char in next, characters do - if not char.commands then + if char.commands then + -- can't happen as we're doing this before other messing around + else local shape = glyphs[char.index] if shape then local segments = shape.segments @@ -375,12 +453,12 @@ otf.features.register { name = "variableshapes", -- enforced for now description = "variable shapes", manipulators = { - base = addvariableshapes, - node = addvariableshapes, + base = initialize, + node = initialize, } } --- In the end it is easier to just provide the new charstring (cff) and points (ttdf). First +-- In the end it is easier to just provide the new charstring (cff) and points (ttf). First -- of all we already have the right information so there is no need to patch the already complex -- backend code (we only need to make sure the cff is valid). Also, I prototyped support for -- these fonts using (converted to) normal postscript shapes, a functionality that was already diff --git a/tex/context/base/mkiv/font-sol.lua b/tex/context/base/mkiv/font-sol.lua index 8967d88e6..002f9df13 100644 --- a/tex/context/base/mkiv/font-sol.lua +++ b/tex/context/base/mkiv/font-sol.lua @@ -54,8 +54,6 @@ local settings_to_hash = utilities.parsers.settings_to_hash local tasks = nodes.tasks local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getfield = nuts.getfield local getnext = nuts.getnext @@ -65,8 +63,10 @@ local getattr = nuts.getattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getlist = nuts.getlist -local getdir = nuts.getdir +local getdirection = nuts.getdirection local getwidth = nuts.getwidth +local getdata = nuts.getdata + local getboxglue = nuts.getboxglue local setattr = nuts.setattr @@ -78,13 +78,15 @@ local find_node_tail = nuts.tail local flush_node = nuts.flush_node local flush_node_list = nuts.flush_list local copy_node_list = nuts.copy_list -local traverse_nodes = nuts.traverse -local traverse_ids = nuts.traverse_id local hpack_nodes = nuts.hpack local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local protect_glyphs = nuts.protect_glyphs +local nextnode = nuts.traversers.next +local nexthlist = nuts.traversers.hlist +local nextwhatsit = nuts.traversers.whatsit + local repack_hlist = nuts.repackhlist local nodes_to_utf = nodes.listtoutf @@ -108,13 +110,15 @@ local whatsit_code = nodecodes.whatsit local fontkern_code = kerncodes.fontkern -local userdefined_code = whatsitcodes.userdefined +local userdefinedwhatsit_code = whatsitcodes.userdefined + +local nodeproperties = nodes.properties.data local nodepool = nuts.pool local usernodeids = nodepool.userids -local new_textdir = nodepool.textdir -local new_usernumber = nodepool.usernumber +local new_direction = nodepool.direction +local new_usernode = nodepool.usernode local new_glue = nodepool.glue local new_leftskip = nodepool.leftskip @@ -237,7 +241,6 @@ local function convert(featuresets,name,list) fs = contextsetups[feature] fn = fs and fs.number end --- inspect(fs) if fn then nofnumbers = nofnumbers + 1 numbers[nofnumbers] = fn @@ -344,20 +347,23 @@ directives.register("builders.paragraphs.solutions.splitters.encapsulate", funct encapsulate = v end) -function splitters.split(head) - -- quite fast - head = tonut(head) - local current, done, rlmode, start, stop, attribute = head, false, false, nil, nil, 0 - cache, max_less, max_more = { }, 0, 0 +function splitters.split(head) -- best also pass the direction + local current = head + local r2l = false + local start = nil + local stop = nil + local attribute = 0 + cache = { } + max_less = 0 + max_more = 0 local function flush() -- we can move this local font = getfont(start) local last = getnext(stop) --- local list = last and copy_node_list(start,last) or copy_node_list(start) - local list = last and copy_node_list(start,stop) or copy_node_list(start) - local n = #cache + 1 + local list = last and copy_node_list(start,last) or copy_node_list(start) + local n = #cache + 1 if encapsulate then - local user_one = new_usernumber(splitter_one,n) - local user_two = new_usernumber(splitter_two,n) + local user_one = new_usernode(splitter_one,n) + local user_two = new_usernode(splitter_two,n) head, start = insert_node_before(head,start,user_one) insert_node_after(head,stop,user_two) else @@ -371,9 +377,8 @@ function splitters.split(head) end end end - local r2l = rlmode == "TRT" or rlmode == "+TRT" if r2l then - local dirnode = new_textdir("+TRT") + local dirnode = new_direction(righttoleft) -- brrr, we don't pop ... to be done (when used at all) setlink(dirnode,list) list = dirnode end @@ -393,7 +398,7 @@ function splitters.split(head) local m = #solution.more if l > max_less then max_less = l end if m > max_more then max_more = m end - start, stop, done = nil, nil, true + start, stop = nil, nil end while current do -- also ischar local next = getnext(current) @@ -422,11 +427,19 @@ function splitters.split(head) else start, stop = nil, nil end - elseif id == dir_code or id == localpar_code then + elseif id == dir_code then + -- not tested (to be done by idris when font is ready) if start then flush() end - rlmode = getdir(current) + local direction, pop = getdirection(current) + r2l = not pop and direction == righttoleft + elseif id == localpar_code and getsubtype(current) == 0 then + if start then + flush() -- very unlikely as this starts a paragraph + end + local direction = getdirection(current) + r2l = direction == righttoleft or direction == "TRT" -- for old times sake else if start then flush() @@ -438,31 +451,37 @@ function splitters.split(head) flush() end nofparagraphs = nofparagraphs + 1 - nofwords = nofwords + #cache - return tonode(head), done + nofwords = nofwords + #cache + return head end local function collect_words(list) -- can be made faster for attributes - local words, w, word = { }, 0, nil + local words = { } + local w = 0 + local word = nil if encapsulate then - for current in traverse_ids(whatsit_code,list) do - if getsubtype(current) == userdefined_code then -- hm - local user_id = getfield(current,"user_id") - if user_id == splitter_one then - word = { getfield(current,"value"), current, current } - w = w + 1 - words[w] = word - elseif user_id == splitter_two then - if word then - word[3] = current - else - -- something is wrong + for current, subtype in nextwhatsit, list do + if subtype == userdefinedwhatsit_code then -- hm + local p = nodeproperties[current] + if p then + local user_id = p.id + if user_id == splitter_one then + word = { p.data, current, current } + w = w + 1 + words[w] = word + elseif user_id == splitter_two then + if word then + word[3] = current + else + -- something is wrong + end end end end end else - local current, first, last, index = list, nil, nil, nil + local first, last, index + local current = list while current do -- todo: disc and kern local id = getid(current) @@ -527,7 +546,9 @@ local function collect_words(list) -- can be made faster for attributes if trace_split then for i=1,#words do local w = words[i] - local n, f, l = w[1], w[2], w[3] + local n = w[1] + local f = w[2] + local l = w[3] local c = cache[n] if c then report_splitters("found %4i: word %a, cached %a",n,nodes_to_utf(f,true,true,l),nodes_to_utf(c.original,true)) @@ -584,21 +605,20 @@ local function doit(word,list,best,width,badness,line,set,listdir) noftries = noftries + 1 local first = copy_node_list(original) if not trace_colors then - for n in traverse_nodes(first) do -- maybe fast force so no attr needed + for n in nextnode, first do -- maybe fast force so no attr needed setattr(n,0,featurenumber) -- this forces dynamics end elseif set == "less" then - for n in traverse_nodes(first) do + for n in nextnode, first do setnodecolor(n,"font:isol") -- yellow setattr(n,0,featurenumber) end else - for n in traverse_nodes(first) do + for n in nextnode, first do setnodecolor(n,"font:medi") -- green setattr(n,0,featurenumber) end end -first = tonode(first) local font = found.font local setdynamics = setfontdynamics[font] if setdynamics then @@ -610,7 +630,6 @@ first = tonode(first) report_solutions("fatal error, no dynamics for font %a",font) end first = inject_kerns(first) -first = tonut(first) if getid(first) == whatsit_code then local temp = first first = getnext(first) @@ -753,19 +772,19 @@ function splitters.optimize(head) if trace_optimize then report_optimizers("preroll %a, variant %a, criterium %a, cache size %a",preroll,variant,criterium,nc) end - for current in traverse_ids(hlist_code,tonut(head)) do + for current in nexthlist, head do line = line + 1 - local sign = getfield(current,"glue_sign") - local dir = getdir(current) - local width = getwidth(current) - local list = getlist(current) + local sign = getfield(current,"glue_sign") + local direction = getdirection(current) + local width = getwidth(current) + local list = getlist(current) if not encapsulate and getid(list) == glyph_code then -- nasty .. we always assume a prev being there .. future luatex will always have a leftskip set -- is this assignment ok ? .. needs checking list = insert_node_before(list,list,new_leftskip(0)) -- new_glue(0) setlist(current,list) end - local temp, badness = repack_hlist(list,width,'exactly',dir) -- it would be nice if the badness was stored in the node + local temp, badness = repack_hlist(list,width,"exactly",direction) -- it would be nice if the badness was stored in the node if badness > 0 then if sign == 0 then if trace_optimize then @@ -785,7 +804,8 @@ function splitters.optimize(head) set, max = "less", max_less end -- we can keep the best variants - local lastbest, lastbadness = nil, badness + local lastbest = nil + local lastbadness = badness if preroll then local bb, base for i=1,max do @@ -858,7 +878,7 @@ statistics.register("optimizer statistics", function() if nofwords > 0 then local elapsed = statistics.elapsedtime(splitters) local average = noftries/elapsed - return format("%s words identified in %s paragraphs, %s words retried, %s lines tried, %0.3f seconds used, %s adapted, %0.1f lines per second", + return format("%s words identified in %s paragraphs, %s words retried, %s lines tried, %s seconds used, %s adapted, %0.1f lines per second", nofwords,nofparagraphs,noftries,nofadapted+nofkept,elapsed,nofadapted,average) end end) diff --git a/tex/context/base/mkiv/font-sty.mkvi b/tex/context/base/mkiv/font-sty.mkvi index 2d00c5ec8..8200aa957 100644 --- a/tex/context/base/mkiv/font-sty.mkvi +++ b/tex/context/base/mkiv/font-sty.mkvi @@ -59,17 +59,17 @@ \newconstant\c_fonts_basics_alternative_style_method \def\font_basics_define_alternative_style_indeed#variantone#varianttwo#command% - {\setvalue{\??alternativestyle#command}{\font_helpers_apply_alternative_style{#variantone}{#varianttwo}}% + {\setuvalue{\??alternativestyle#command}{\font_helpers_apply_alternative_style{#variantone}{#varianttwo}}% \ifcsname#command\endcsname % no redefinition \else\ifnum\c_fonts_basics_alternative_style_method=\plusone \ifthirdargument - \setuevalue{#command}{\groupedcommand{\expandafter\noexpand\begincsname\??alternativestyle#command\endcsname}{}}% + \setuevalue{#command}{\triggergroupedcommandcs\begincsname\??alternativestyle#command\endcsname}% \else - \setuvalue{#command}{\groupedcommand{#variantone}{}}% + \setuvalue{#command}{\triggergroupedcommand{#variantone}}% \fi \else - \setuvalue{#command}{\groupedcommand{#variantone}{}}% + \setuvalue{#command}{\triggergroupedcommand{#variantone}}% \fi\fi} \def\font_helpers_apply_alternative_style @@ -279,17 +279,26 @@ \fi\fi \endcsname{#name}} +% \setvalue{\??styleargument1}#name% +% {\groupedcommand{\begincsname#name\endcsname}{}} + \setvalue{\??styleargument1}#name% - {\groupedcommand{\csname#name\endcsname}{}} + {\expandafter\triggergroupedcommandcs\begincsname#name\endcsname} + +% \setvalue{\??styleargument2}#name% +% {\groupedcommand{\font_styles_use_defined{#name}}{}} % or {\font_styles_apply_grouped{#name}} \setvalue{\??styleargument2}#name% - {\groupedcommand{\font_styles_use_defined{#name}}{}} % or {\font_styles_apply_grouped{#name}} + {\triggergroupedcommand{\font_styles_use_defined{#name}}} % or {\font_styles_apply_grouped{#name}} \setvalue{\??styleargument3}#specification% {\doifelseassignment{#specification}\font_styles_assignment\font_styles_direct{#specification}} -\def\font_styles_assignment#specification{\groupedcommand{\font_styles_use_generic{#specification}}{}} -\def\font_styles_direct #specification{\groupedcommand{\definedfont[#specification]}{}} +% \def\font_styles_assignment#specification{\groupedcommand{\font_styles_use_generic{#specification}}{}} +% \def\font_styles_direct #specification{\groupedcommand{\definedfont[#specification]}{}} + +\def\font_styles_assignment#specification{\triggergroupedcommand{\font_styles_use_generic{#specification}}} +\def\font_styles_direct #specification{\triggergroupedcommand{\definedfont[#specification]}} % environments diff --git a/tex/context/base/mkiv/font-sym.mkvi b/tex/context/base/mkiv/font-sym.mkvi index 0e709f161..3ff85fb4a 100644 --- a/tex/context/base/mkiv/font-sym.mkvi +++ b/tex/context/base/mkiv/font-sym.mkvi @@ -167,7 +167,7 @@ \def\font_basics_define_symbolic_font {\definefont[currentsymbolfont][\askedsymbolfont]% \currentsymbolfont - \global\expandafter\let\csname\??symbolfont\askedsymbolfont\endcsname\lastrawfontcall} + \expandafter\glet\csname\??symbolfont\askedsymbolfont\endcsname\lastrawfontcall} \unexpanded\def\getnamedglyphstyled#fontname#character{{\setstyledsymbolicfont{#fontname}\clf_fontchar{#character}}} \unexpanded\def\getnamedglyphdirect#fontname#character{{\setdirectsymbolicfont{#fontname}\clf_fontchar{#character}}} diff --git a/tex/context/base/mkiv/font-syn.lua b/tex/context/base/mkiv/font-syn.lua index 52f425db3..dfe32b57b 100644 --- a/tex/context/base/mkiv/font-syn.lua +++ b/tex/context/base/mkiv/font-syn.lua @@ -1172,7 +1172,7 @@ local function analyzefiles(olddata) report_names("scanning path %a for %s files",blobpath,suffix) end, function(blobtype,blobpath,pattern,total,checked,done) blobpath = resolveprefix(blobpath) -- no shortcut - report_names("%s entries found, %s %s files checked, %s okay",total,checked,suffix,done) + report_names("%s %s files checked, %s okay",checked,suffix,done) end) end @@ -2009,7 +2009,8 @@ local lastlookups, lastpattern = { }, "" local function look_them_up(lookups,specification) for key, value in sortedhash(specification) do - local t, n = { }, 0 + local t = { } + local n = 0 if find(value,"*",1,true) then value = topattern(value) for i=1,#lookups do diff --git a/tex/context/base/mkiv/font-tfm.lua b/tex/context/base/mkiv/font-tfm.lua index 0059e6296..6e4f86980 100644 --- a/tex/context/base/mkiv/font-tfm.lua +++ b/tex/context/base/mkiv/font-tfm.lua @@ -9,6 +9,7 @@ if not modules then modules = { } end modules ['font-tfm'] = { local next, type = next, type local match, format = string.match, string.format local concat, sortedhash = table.concat, table.sortedhash +local idiv = number.idiv local trace_defining = false trackers.register("fonts.defining", function(v) trace_defining = v end) local trace_features = false trackers.register("tfm.features", function(v) trace_features = v end) @@ -21,6 +22,7 @@ local setmetatableindex = table.setmetatableindex local fonts = fonts local handlers = fonts.handlers +local helpers = fonts.helpers local readers = fonts.readers local constructors = fonts.constructors local encodings = fonts.encodings @@ -39,6 +41,8 @@ local registertfmfeature = tfmfeatures.register local tfmenhancers = constructors.enhancers.tfm local registertfmenhancer = tfmenhancers.register +local charcommand = helpers.commands.char + constructors.resolvevirtualtoo = false -- wil be set in font-ctx.lua fonts.formats.tfm = "type1" -- we need to have at least a value here @@ -114,219 +118,266 @@ local depth = { } -- table.setmetatableindex("number") -- -- So "czechdqcheat=yes" is then a valid feature. And yes, it's a cheat. +local read_from_tfm, check_tfm do -local function read_from_tfm(specification) - local filename = specification.filename - local size = specification.size - depth[filename] = (depth[filename] or 0) + 1 - if trace_defining then - report_defining("loading tfm file %a at size %s",filename,size) - end - local tfmdata = font.read_tfm(filename,size) -- not cached, fast enough - if tfmdata then - - local features = specification.features and specification.features.normal or { } - local features = constructors.checkedfeatures("tfm",features) - specification.features.normal = features + local tfmreaders = context and tfm.readers + local loadtfmvf = tfmreaders and tfmreaders.loadtfmvf + local loadtfm = font.read_tfm + local loadvf = font.read_vf - -- If reencode returns a new table, we assume that we're doing something - -- special. An 'auto' reencode pickt up its vector from the pfb file. + directives.register("fonts.tfm.builtin",function(v) + loadtfmvf = tfmreaders and tfmreaders.loadtfmvf + if v and loadtfm then + loadtfmvf = false + end + end) - local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification) - if newtfmdata then - tfmdata = newtfmdata + read_from_tfm = function(specification) + local filename = specification.filename + local size = specification.size + depth[filename] = (depth[filename] or 0) + 1 + if trace_defining then + report_defining("loading tfm file %a at size %s",filename,size) + end + local tfmdata -- not cached, fast enough + if loadtfmvf then + tfmdata = loadtfmvf(filename,size) + else + tfmdata = loadtfm(filename,size) end + if tfmdata then - local resources = tfmdata.resources or { } - local properties = tfmdata.properties or { } - local parameters = tfmdata.parameters or { } - local shared = tfmdata.shared or { } - -- - shared.features = features - shared.resources = resources - -- - properties.name = tfmdata.name -- todo: fallback - properties.fontname = tfmdata.fontname -- todo: fallback - properties.psname = tfmdata.psname -- todo: fallback - properties.fullname = tfmdata.fullname -- todo: fallback - properties.filename = specification.filename -- todo: fallback - properties.format = fonts.formats.tfm -- better than nothing - -- - tfmdata.properties = properties - tfmdata.resources = resources - tfmdata.parameters = parameters - tfmdata.shared = shared - -- - shared.rawdata = { resources = resources } - shared.features = features - -- - -- The next branch is only entered when we have a proper encoded file i.e. - -- unicodes and such. It really nakes no sense to do feature juggling when - -- we have no names and unicodes. - -- - if newtfmdata then - -- - -- Some opentype processing assumes these to be present: - -- - if not resources.marks then - resources.marks = { } - end - if not resources.sequences then - resources.sequences = { } - end - if not resources.features then - resources.features = { - gsub = { }, - gpos = { }, - } - end - if not tfmdata.changed then - tfmdata.changed = { } - end - if not tfmdata.descriptions then - tfmdata.descriptions = tfmdata.characters + local features = specification.features and specification.features.normal or { } + local features = constructors.checkedfeatures("tfm",features) + specification.features.normal = features + + -- If reencode returns a new table, we assume that we're doing something + -- special. An 'auto' reencode picks up its vector from the pfb file. + + local newtfmdata = (depth[filename] == 1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata = newtfmdata end + + local resources = tfmdata.resources or { } + local properties = tfmdata.properties or { } + local parameters = tfmdata.parameters or { } + local shared = tfmdata.shared or { } -- - -- It might be handy to have this: - -- - otf.readers.addunicodetable(tfmdata) - -- - -- We make a pseudo opentype font, e.g. kerns and ligatures etc: - -- - tfmenhancers.apply(tfmdata,filename) - -- - -- Now user stuff can kick in. - -- - constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) - -- - -- As that can also mess with names and such, we are now ready for finalizing - -- the unicode information. This is a different order that for instance type one - -- (afm) files. First we try to deduce unicodes from already present information. + shared.features = features + shared.resources = resources -- - otf.readers.unifymissing(tfmdata) + properties.name = tfmdata.name -- todo: fallback + properties.fontname = tfmdata.fontname -- todo: fallback + properties.psname = tfmdata.psname -- todo: fallback + properties.fullname = tfmdata.fullname -- todo: fallback + properties.filename = specification.filename -- todo: fallback + properties.format = tfmdata.format or fonts.formats.tfm -- better than nothing + properties.usedbitmap = tfmdata.usedbitmap -- - -- Next we fill in the gaps, based on names from teh agl. Probably not much will - -- happen here. + tfmdata.properties = properties + tfmdata.resources = resources + tfmdata.parameters = parameters + tfmdata.shared = shared -- - fonts.mappings.addtounicode(tfmdata,filename) + shared.rawdata = { resources = resources } + shared.features = features -- - -- The tounicode data is passed to the backend that constructs the vectors for us. + -- The next branch is only entered when we have a proper encoded file i.e. + -- unicodes and such. It really nakes no sense to do feature juggling when + -- we have no names and unicodes. -- - tfmdata.tounicode = 1 - local tounicode = fonts.mappings.tounicode - for unicode, v in next, tfmdata.characters do - local u = v.unicode - if u then - v.tounicode = tounicode(u) + if newtfmdata then + -- + -- Some opentype processing assumes these to be present: + -- + if not resources.marks then + resources.marks = { } + end + if not resources.sequences then + resources.sequences = { } + end + if not resources.features then + resources.features = { + gsub = { }, + gpos = { }, + } + end + if not tfmdata.changed then + tfmdata.changed = { } + end + if not tfmdata.descriptions then + tfmdata.descriptions = tfmdata.characters + end + -- + -- It might be handy to have this: + -- + otf.readers.addunicodetable(tfmdata) + -- + -- We make a pseudo opentype font, e.g. kerns and ligatures etc: + -- + tfmenhancers.apply(tfmdata,filename) + -- + -- Now user stuff can kick in. + -- + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + -- + -- As that can also mess with names and such, we are now ready for finalizing + -- the unicode information. This is a different order that for instance type one + -- (afm) files. First we try to deduce unicodes from already present information. + -- + otf.readers.unifymissing(tfmdata) + -- + -- Next we fill in the gaps, based on names from teh agl. Probably not much will + -- happen here. + -- + fonts.mappings.addtounicode(tfmdata,filename) + -- + -- The tounicode data is passed to the backend that constructs the vectors for us. + -- + tfmdata.tounicode = 1 + local tounicode = fonts.mappings.tounicode + for unicode, v in next, tfmdata.characters do + local u = v.unicode + if u then + v.tounicode = tounicode(u) + end + end + -- + -- However, when we use a bitmap font those vectors can't be constructed because + -- that information is not carried with those fonts (there is no name info, nor + -- proper index info, nor unicodes at that end). So, we provide it ourselves. + -- + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) end end -- - -- However, when we use a bitmap font those vectors can't be constructed because - -- that information is not carried with those fonts (there is no name info, nor - -- proper index info, nor unicodes at that end). So, we provide it ourselves. + shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil -- - if tfmdata.usedbitmap then - tfm.addtounicode(tfmdata) + if size < 0 then + size = idiv(65536 * -size,100) end - end - -- - shared.processes = next(features) and tfm.setfeatures(tfmdata,features) or nil - -- - parameters.factor = 1 -- already scaled - parameters.size = size - parameters.slant = parameters.slant or parameters[1] or 0 - parameters.space = parameters.space or parameters[2] or 0 - parameters.space_stretch = parameters.space_stretch or parameters[3] or 0 - parameters.space_shrink = parameters.space_shrink or parameters[4] or 0 - parameters.x_height = parameters.x_height or parameters[5] or 0 - parameters.quad = parameters.quad or parameters[6] or 0 - parameters.extra_space = parameters.extra_space or parameters[7] or 0 - -- - constructors.enhanceparameters(parameters) -- official copies for us - -- - properties.private = properties.private or tfmdata.private or privateoffset - -- - if newtfmdata then + parameters.factor = 1 -- already scaled + parameters.units = 1000 -- just in case + parameters.size = size + parameters.slant = parameters.slant or parameters[1] or 0 + parameters.space = parameters.space or parameters[2] or 0 + parameters.space_stretch = parameters.space_stretch or parameters[3] or 0 + parameters.space_shrink = parameters.space_shrink or parameters[4] or 0 + parameters.x_height = parameters.x_height or parameters[5] or 0 + parameters.quad = parameters.quad or parameters[6] or 0 + parameters.extra_space = parameters.extra_space or parameters[7] or 0 -- - -- We do nothing as we assume flat tfm files. It would become real messy - -- otherwise and I don't have something for testing on my system anyway. + constructors.enhanceparameters(parameters) -- official copies for us -- - elseif constructors.resolvevirtualtoo then - fonts.loggers.register(tfmdata,file.suffix(filename),specification) -- strange, why here - local vfname = findbinfile(specification.name, 'ovf') - if vfname and vfname ~= "" then - local vfdata = font.read_vf(vfname,size) -- not cached, fast enough - if vfdata then - local chars = tfmdata.characters - for k,v in next, vfdata.characters do - chars[k].commands = v.commands + properties.private = properties.private or tfmdata.private or privateoffset + -- + if newtfmdata then + -- + -- We do nothing as we assume flat tfm files. It would become real messy + -- otherwise and I don't have something for testing on my system anyway. + -- + elseif loadtfmvf then + -- already loaded + local fonts = tfmdata.fonts + if fonts then + for i=1,#fonts do + local font = fonts[i] + local id = font.id + if not id then + local name = font.name + local size = font.size + if name and size then + local data, id = constructors.readanddefine(name,size) + if id then + font.id = id + font.name = nil + font.size = nil + end + end + end end - properties.virtualized = true - tfmdata.fonts = vfdata.fonts - tfmdata.type = "virtual" -- else nested calls with cummulative scaling - local fontlist = vfdata.fonts - local name = file.nameonly(filename) - for i=1,#fontlist do - local n = fontlist[i].name - local s = fontlist[i].size - local d = depth[filename] - s = constructors.scaled(s,vfdata.designsize) - if d > tfm.maxnestingdepth then - report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) - fontlist[i] = { id = 0 } - elseif (d > 1) and (s > tfm.maxnestingsize) then - report_defining("virtual font %a exceeds size %s",n,s) - fontlist[i] = { id = 0 } - else - local t, id = fonts.constructors.readanddefine(n,s) - fontlist[i] = { id = id } + end + elseif constructors.resolvevirtualtoo then + fonts.loggers.register(tfmdata,file.suffix(filename),specification) -- strange, why here + local vfname = findbinfile(specification.name, 'ovf') + if vfname and vfname ~= "" then + local vfdata = loadvf(vfname,size) + if vfdata then + local chars = tfmdata.characters + for k,v in next, vfdata.characters do + chars[k].commands = v.commands + end + properties.virtualized = true + tfmdata.fonts = vfdata.fonts + tfmdata.type = "virtual" -- else nested calls with cummulative scaling + local fontlist = vfdata.fonts + local name = file.nameonly(filename) + for i=1,#fontlist do + local n = fontlist[i].name + local s = fontlist[i].size + local d = depth[filename] + s = constructors.scaled(s,vfdata.designsize) + if d > tfm.maxnestingdepth then + report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) + fontlist[i] = { id = 0 } + elseif (d > 1) and (s > tfm.maxnestingsize) then + report_defining("virtual font %a exceeds size %s",n,s) + fontlist[i] = { id = 0 } + else + local t, id = constructors.readanddefine(n,s) + fontlist[i] = { id = id } + end end end end end + -- + -- This is for old times sake (and context specific) so we comment it. It has + -- to do with encoding prefixes (a context naming that was later adopted by + -- the lm/gyre project) + -- + -- if not features.encoding then + -- local encoding, filename = match(properties.filename,"^(.-)%-(.*)$") + -- if filename and encoding and encodings.known and encodings.known[encoding] then + -- features.encoding = encoding + -- end + -- end + -- + -- Some afterthoughts: + -- + properties.haskerns = true + properties.hasligatures = true + properties.hasitalics = true + resources.unicodes = { } + resources.lookuptags = { } + -- + depth[filename] = depth[filename] - 1 + -- + return tfmdata + else + depth[filename] = depth[filename] - 1 end - -- - -- This is for old times sake (and context specific) so we comment it. It has - -- to do with encoding prefixes (a context naming that was later adopted by - -- the lm/gyre project) - -- - -- if not features.encoding then - -- local encoding, filename = match(properties.filename,"^(.-)%-(.*)$") - -- if filename and encoding and encodings.known and encodings.known[encoding] then - -- features.encoding = encoding - -- end - -- end - -- - -- Some afterthoughts: - -- - properties.haskerns = true - properties.hasligatures = true - resources.unicodes = { } - resources.lookuptags = { } - -- - depth[filename] = depth[filename] - 1 - -- - return tfmdata - else - depth[filename] = depth[filename] - 1 end -end -local function check_tfm(specification,fullname) -- we could split up like afm/otf - local foundname = findbinfile(fullname, 'tfm') or "" - if foundname == "" then - foundname = findbinfile(fullname, 'ofm') or "" -- not needed in context - end - if foundname == "" then - foundname = fonts.names.getfilename(fullname,"tfm") or "" - end - if foundname ~= "" then - specification.filename = foundname - specification.format = "ofm" - return read_from_tfm(specification) - elseif trace_defining then - report_defining("loading tfm with name %a fails",specification.name) + check_tfm = function(specification,fullname) -- we could split up like afm/otf + local foundname = findbinfile(fullname, 'tfm') or "" + if foundname == "" then + foundname = findbinfile(fullname, 'ofm') or "" -- not needed in context + end + if foundname == "" then + foundname = fonts.names.getfilename(fullname,"tfm") or "" + end + if foundname ~= "" then + specification.filename = foundname + specification.format = "ofm" + return read_from_tfm(specification) + elseif trace_defining then + report_defining("loading tfm with name %a fails",specification.name) + end end + end readers.check_tfm = check_tfm @@ -409,7 +460,7 @@ do local vector = false if type(pfbfile) == "string" then - local pfb = fonts.constructors.handlers.pfb + local pfb = constructors.handlers.pfb if pfb and pfb.loadvector then local v, e = pfb.loadvector(pfbfile) if v then @@ -438,7 +489,7 @@ do local originals = tfmdata.characters local indices = { } local parentfont = { "font", 1 } - local private = tfmdata or fonts.constructors.privateoffset + local private = tfmdata.privateoffset or constructors.privateoffset local reported = encdone[tfmfile][encfile] -- create characters table @@ -463,9 +514,9 @@ do indices[index] = unicode original.name = name -- so one can lookup weird names if backmap then - original.index = backmap[name] + original.index = backmap[name] else -- probably bitmap - original.commands = { parentfont, { "char", index } } + original.commands = { parentfont, charcommand[index] } -- or "slot" original.oindex = index end done[name] = true @@ -512,6 +563,7 @@ do tfmdata.psname = file.nameonly(pfbfile or tfmdata.name) tfmdata.filename = pfbfile tfmdata.encodingbytes = 2 + -- tfmdata.format = bitmap and "type3" or "type1" tfmdata.format = "type1" tfmdata.tounicode = 1 tfmdata.embedding = "subset" @@ -548,24 +600,18 @@ end end ]] - local flushstreamobject = lpdf and lpdf.flushstreamobject - local setfontattributes = pdf.setfontattributes + local flushstreamobject = lpdf and lpdf.flushstreamobject -- context + local setfontattributes = lpdf and lpdf.setfontattributes -- context - if flushstreamobject then - -- we're in context - else + if not flushstreamobject then flushstreamobject = function(data) - return pdf.obj { - immediate = true, - type = "stream", - string = data, - } + return pdf.obj { immediate = true, type = "stream", string = data } -- generic end end if not setfontattributes then setfontattributes = function(id,data) - print(format("your luatex is too old so no tounicode bitmap font%i",id)) + return pdf.setfontattributes(id,data) -- generic end end @@ -593,7 +639,7 @@ end -- Now we implement the regular features handlers. We need to convert the -- tfm specific structures to opentype structures. In basemode they are --- converted back so that is a bti of a waste but it's fast enough. +-- converted back so that is a bit of a waste but it's fast enough. do diff --git a/tex/context/base/mkiv/font-tra.mkiv b/tex/context/base/mkiv/font-tra.mkiv index c51ba78fc..205ca5ca0 100644 --- a/tex/context/base/mkiv/font-tra.mkiv +++ b/tex/context/base/mkiv/font-tra.mkiv @@ -188,7 +188,7 @@ % \showotfstepmessages\recurselevel % \blank % \startlinecorrection -% \dontleavehmode\bgroup\resetallattributes\pardir TLT\textdir TLT\relax\tttf\recurselevel: \showotfstepchars\recurselevel\egroup +% \dontleavehmode\bgroup\resetallattributes\lefttoright\tttf\recurselevel: \showotfstepchars\recurselevel\egroup % \stoplinecorrection % \blank % \startlinecorrection diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua index df08787f9..d2fe0917c 100644 --- a/tex/context/base/mkiv/font-ttf.lua +++ b/tex/context/base/mkiv/font-ttf.lua @@ -35,26 +35,53 @@ if not modules then modules = { } end modules ['font-ttf'] = { local next, type, unpack = next, type, unpack local band, rshift = bit32.band, bit32.rshift local sqrt, round = math.sqrt, math.round -local char = string.char +local char, rep = string.char, string.rep local concat = table.concat +local idiv = number.idiv +local setmetatableindex = table.setmetatableindex -local report = logs.reporter("otf reader","ttf") +local report = logs.reporter("otf reader","ttf") -local trace_deltas = false +local trace_deltas = false -local readers = fonts.handlers.otf.readers -local streamreader = readers.streamreader +local readers = fonts.handlers.otf.readers +local streamreader = readers.streamreader -local setposition = streamreader.setposition -local getposition = streamreader.getposition -local skipbytes = streamreader.skip -local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer -local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer -local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer -local readchar = streamreader.readinteger1 -- 8-bit signed integer -local readshort = streamreader.readinteger2 -- 16-bit signed integer -local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14) -local readinteger = streamreader.readinteger1 +local setposition = streamreader.setposition +local getposition = streamreader.getposition +local skipbytes = streamreader.skip +local readbyte = streamreader.readcardinal1 -- 8-bit unsigned integer +local readushort = streamreader.readcardinal2 -- 16-bit unsigned integer +local readulong = streamreader.readcardinal4 -- 24-bit unsigned integer +local readchar = streamreader.readinteger1 -- 8-bit signed integer +local readshort = streamreader.readinteger2 -- 16-bit signed integer +local read2dot14 = streamreader.read2dot14 -- 16-bit signed fixed number with the low 14 bits of fraction (2.14) (F2DOT14) +local readinteger = streamreader.readinteger1 +local readcardinaltable = streamreader.readcardinaltable +local readintegertable = streamreader.readintegertable + +directives.register("fonts.streamreader",function() + + streamreader = utilities.streams + + setposition = streamreader.setposition + getposition = streamreader.getposition + skipbytes = streamreader.skip + readbyte = streamreader.readcardinal1 + readushort = streamreader.readcardinal2 + readulong = streamreader.readcardinal4 + readchar = streamreader.readinteger1 + readshort = streamreader.readinteger2 + read2dot14 = streamreader.read2dot14 + readinteger = streamreader.readinteger1 + readcardinaltable = streamreader.readcardinaltable + readintegertable = streamreader.readintegertable + +end) + +local short = 2 +local ushort = 2 +local ulong = 4 local helpers = readers.helpers local gotodatatable = helpers.gotodatatable @@ -90,22 +117,41 @@ local function mergecomposites(glyphs,shapes) local yscale = matrix[4] local xoffset = matrix[5] local yoffset = matrix[6] - for i=1,#subpoints do - local p = subpoints[i] - local x = p[1] - local y = p[2] - nofpoints = nofpoints + 1 - points[nofpoints] = { - xscale * x + xrotate * y + xoffset, - yscale * y + yrotate * x + yoffset, - p[3] - } + local count = #subpoints + if xscale == 1 and yscale == 1 and xrotate == 0 and yrotate == 0 then + for i=1,count do + local p = subpoints[i] + nofpoints = nofpoints + 1 + points[nofpoints] = { + p[1] + xoffset, + p[2] + yoffset, + p[3] + } + end + else + for i=1,count do + local p = subpoints[i] + local x = p[1] + local y = p[2] + nofpoints = nofpoints + 1 + points[nofpoints] = { + xscale * x + xrotate * y + xoffset, + yscale * y + yrotate * x + yoffset, + p[3] + } + end end - for i=1,#subcontours do + local subcount = #subcontours + if subcount == 1 then nofcontours = nofcontours + 1 - contours[nofcontours] = offset + subcontours[i] + contours[nofcontours] = offset + subcontours[1] + else + for i=1,#subcontours do + nofcontours = nofcontours + 1 + contours[nofcontours] = offset + subcontours[i] + end end - offset = offset + #subpoints + offset = offset + count else report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) end @@ -116,7 +162,8 @@ local function mergecomposites(glyphs,shapes) return contours, points end - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local shape = shapes[index] if shape then local components = shape.components @@ -128,7 +175,7 @@ local function mergecomposites(glyphs,shapes) end -local function readnothing(f,nofcontours) +local function readnothing(f) return { type = "nothing", } @@ -259,7 +306,8 @@ end local quadratic = false local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox overhead - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local shape = shapes[index] if shape then local glyph = glyphs[index] @@ -271,7 +319,8 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox local nofsegments = 0 glyph.segments = segments if nofcontours > 0 then - local px, py = 0, 0 -- we could use these in calculations which saves a copy + local px = 0 + local py = 0 local first = 1 for i=1,nofcontours do local last = contours[i] @@ -299,15 +348,20 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox end control_pt = first_pt end - local x, y = first_pt[1], first_pt[2] + local x = first_pt[1] + local y = first_pt[2] if not done then - xmin, ymin, xmax, ymax = x, y, x, y + xmin = x + ymin = y + xmax = x + ymax = y done = true end nofsegments = nofsegments + 1 segments[nofsegments] = { x, y, "m" } -- "moveto" if not quadratic then - px, py = x, y + px = x + py = y end local previous_pt = first_pt for i=first,last do @@ -327,8 +381,10 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox control_pt = current_pt end elseif current_on then - local x1, y1 = control_pt[1], control_pt[2] - local x2, y2 = current_pt[1], current_pt[2] + local x1 = control_pt[1] + local y1 = control_pt[2] + local x2 = current_pt[1] + local y2 = current_pt[2] nofsegments = nofsegments + 1 if quadratic then segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" @@ -338,8 +394,10 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox end control_pt = false else - local x2, y2 = (previous_pt[1]+current_pt[1])/2, (previous_pt[2]+current_pt[2])/2 - local x1, y1 = control_pt[1], control_pt[2] + local x2 = (previous_pt[1]+current_pt[1])/2 + local y2 = (previous_pt[2]+current_pt[2])/2 + local x1 = control_pt[1] + local y1 = control_pt[2] nofsegments = nofsegments + 1 if quadratic then segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" @@ -355,14 +413,17 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox -- we're already done, probably a simple curve else nofsegments = nofsegments + 1 - local x2, y2 = first_pt[1], first_pt[2] + local x2 = first_pt[1] + local y2 = first_pt[2] if not control_pt then segments[nofsegments] = { x2, y2, "l" } -- "lineto" elseif quadratic then - local x1, y1 = control_pt[1], control_pt[2] + local x1 = control_pt[1] + local y1 = control_pt[2] segments[nofsegments] = { x1, y1, x2, y2, "q" } -- "quadraticto" else - local x1, y1 = control_pt[1], control_pt[2] + local x1 = control_pt[1] + local y1 = control_pt[2] x1, y1, x2, y2, px, py = curveto(x1, y1, px, py, x2, y2) segments[nofsegments] = { x1, y1, x2, y2, px, py, "c" } -- "curveto" -- px, py = x2, y2 @@ -379,7 +440,8 @@ local function contours2outlines_normal(glyphs,shapes) -- maybe accept the bbox end local function contours2outlines_shaped(glyphs,shapes,keepcurve) - for index=1,#glyphs do +-- for index=1,#glyphs do + for index=0,#glyphs-1 do local shape = shapes[index] if shape then local glyph = glyphs[index] @@ -425,7 +487,8 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) end control_pt = first_pt end - local x, y = first_pt[1], first_pt[2] + local x = first_pt[1] + local y = first_pt[2] if not done then xmin, ymin, xmax, ymax = x, y, x, y done = true @@ -438,7 +501,8 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) segments[nofsegments] = { x, y, "m" } -- "moveto" end if not quadratic then - px, py = x, y + px = x + py = y end local previous_pt = first_pt for i=first,last do @@ -448,7 +512,8 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) if previous_on then if current_on then -- both normal points - local x, y = current_pt[1], current_pt[2] + local x = current_pt[1] + local y = current_pt[2] if x < xmin then xmin = x elseif x > xmax then xmax = x end if y < ymin then ymin = y elseif y > ymax then ymax = y end if keepcurve then @@ -456,14 +521,17 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) segments[nofsegments] = { x, y, "l" } -- "lineto" end if not quadratic then - px, py = x, y + px = x + py = y end else control_pt = current_pt end elseif current_on then - local x1, y1 = control_pt[1], control_pt[2] - local x2, y2 = current_pt[1], current_pt[2] + local x1 = control_pt[1] + local y1 = control_pt[2] + local x2 = current_pt[1] + local y2 = current_pt[2] if quadratic then if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end @@ -486,8 +554,10 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) end control_pt = false else - local x2, y2 = (previous_pt[1]+current_pt[1])/2, (previous_pt[2]+current_pt[2])/2 - local x1, y1 = control_pt[1], control_pt[2] + local x2 = (previous_pt[1]+current_pt[1])/2 + local y2 = (previous_pt[2]+current_pt[2])/2 + local x1 = control_pt[1] + local y1 = control_pt[2] if quadratic then if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end @@ -520,8 +590,10 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve) segments[nofsegments] = { first_pt[1], first_pt[2], "l" } -- "lineto" end else - local x1, y1 = control_pt[1], control_pt[2] - local x2, y2 = first_pt[1], first_pt[2] + local x1 = control_pt[1] + local y1 = control_pt[2] + local x2 = first_pt[1] + local y2 = first_pt[2] if x1 < xmin then xmin = x1 elseif x1 > xmax then xmax = x1 end if y1 < ymin then ymin = y1 elseif y1 > ymax then ymax = y1 end if quadratic then @@ -558,8 +630,13 @@ end local c_zero = char(0) local s_zero = char(0,0) +-- local shorthash = setmetatableindex(function(t,k) +-- t[k] = char(band(rshift(k,8),0xFF),band(k,0xFF)) return t[k] +-- end) + local function toushort(n) return char(band(rshift(n,8),0xFF),band(n,0xFF)) + -- return shorthash[n] end local function toshort(n) @@ -567,125 +644,152 @@ local function toshort(n) n = n + 0x10000 end return char(band(rshift(n,8),0xFF),band(n,0xFF)) + -- return shorthash[n] end -- todo: we can reuse result, xpoints and ypoints +local chars = setmetatableindex(function(t,k) + for i=0,255 do local v = char(i) t[i] = v end return t[k] +end) + local function repackpoints(glyphs,shapes) local noboundingbox = { 0, 0, 0, 0 } local result = { } -- reused - for index=1,#glyphs do + local xpoints = { } -- reused + local ypoints = { } -- reused + for index=0,#glyphs-1 do local shape = shapes[index] if shape then local r = 0 local glyph = glyphs[index] - if false then -- shape.type == "composite" - -- we merged them - else - local contours = shape.contours - local nofcontours = contours and #contours or 0 - local boundingbox = glyph.boundingbox or noboundingbox - r = r + 1 result[r] = toshort(nofcontours) - r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin - r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin - r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax - r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax - if nofcontours > 0 then - for i=1,nofcontours do - r = r + 1 result[r] = toshort(contours[i]-1) - end - r = r + 1 result[r] = s_zero -- no instructions - local points = shape.points - local currentx = 0 - local currenty = 0 - local xpoints = { } - local ypoints = { } - local x = 0 - local y = 0 - local lastflag = nil - local nofflags = 0 - for i=1,#points do - local pt = points[i] - local px = pt[1] - local py = pt[2] - local fl = pt[3] and 0x01 or 0x00 - if px == currentx then - fl = fl + 0x10 + local contours = shape.contours + local nofcontours = contours and #contours or 0 + local boundingbox = glyph.boundingbox or noboundingbox + r = r + 1 result[r] = toshort(nofcontours) + r = r + 1 result[r] = toshort(boundingbox[1]) -- xmin + r = r + 1 result[r] = toshort(boundingbox[2]) -- ymin + r = r + 1 result[r] = toshort(boundingbox[3]) -- xmax + r = r + 1 result[r] = toshort(boundingbox[4]) -- ymax + if nofcontours > 0 then + for i=1,nofcontours do + r = r + 1 result[r] = toshort(contours[i]-1) + end + r = r + 1 result[r] = s_zero -- no instructions + local points = shape.points + local currentx = 0 + local currenty = 0 + -- local xpoints = { } + -- local ypoints = { } + local x = 0 + local y = 0 + local lastflag = nil + local nofflags = 0 + for i=1,#points do + local pt = points[i] + local px = pt[1] + local py = pt[2] + local fl = pt[3] and 0x01 or 0x00 + if px == currentx then + fl = fl + 0x10 + else + local dx = round(px - currentx) + x = x + 1 + if dx < -255 or dx > 255 then + xpoints[x] = toshort(dx) + elseif dx < 0 then + fl = fl + 0x02 + -- xpoints[x] = char(-dx) + xpoints[x] = chars[-dx] + elseif dx > 0 then + fl = fl + 0x12 + -- xpoints[x] = char(dx) + xpoints[x] = chars[dx] else - local dx = round(px - currentx) - if dx < -255 or dx > 255 then - x = x + 1 xpoints[x] = toshort(dx) - elseif dx < 0 then - fl = fl + 0x02 - x = x + 1 xpoints[x] = char(-dx) - elseif dx > 0 then - fl = fl + 0x12 - x = x + 1 xpoints[x] = char(dx) - else - fl = fl + 0x02 - x = x + 1 xpoints[x] = c_zero - end + fl = fl + 0x02 + xpoints[x] = c_zero end - if py == currenty then - fl = fl + 0x20 + end + if py == currenty then + fl = fl + 0x20 + else + local dy = round(py - currenty) + y = y + 1 + if dy < -255 or dy > 255 then + ypoints[y] = toshort(dy) + elseif dy < 0 then + fl = fl + 0x04 + -- ypoints[y] = char(-dy) + ypoints[y] = chars[-dy] + elseif dy > 0 then + fl = fl + 0x24 + -- ypoints[y] = char(dy) + ypoints[y] = chars[dy] else - local dy = round(py - currenty) - if dy < -255 or dy > 255 then - y = y + 1 ypoints[y] = toshort(dy) - elseif dy < 0 then - fl = fl + 0x04 - y = y + 1 ypoints[y] = char(-dy) - elseif dy > 0 then - fl = fl + 0x24 - y = y + 1 ypoints[y] = char(dy) - else - fl = fl + 0x04 - y = y + 1 ypoints[y] = c_zero - end - end - currentx = px - currenty = py - if lastflag == fl then - nofflags = nofflags + 1 - else -- if > 255 - if nofflags == 1 then - r = r + 1 result[r] = char(lastflag) - elseif nofflags == 2 then - r = r + 1 result[r] = char(lastflag,lastflag) - elseif nofflags > 2 then - lastflag = lastflag + 0x08 - r = r + 1 result[r] = char(lastflag,nofflags-1) - end - nofflags = 1 - lastflag = fl + fl = fl + 0x04 + ypoints[y] = c_zero end end - if nofflags == 1 then - r = r + 1 result[r] = char(lastflag) - elseif nofflags == 2 then - r = r + 1 result[r] = char(lastflag,lastflag) - elseif nofflags > 2 then - lastflag = lastflag + 0x08 - r = r + 1 result[r] = char(lastflag,nofflags-1) + currentx = px + currenty = py + if lastflag == fl then + nofflags = nofflags + 1 + else -- if > 255 + if nofflags == 1 then + -- r = r + 1 result[r] = char(lastflag) + r = r + 1 result[r] = chars[lastflag] + elseif nofflags == 2 then + r = r + 1 result[r] = char(lastflag,lastflag) + elseif nofflags > 2 then + lastflag = lastflag + 0x08 + r = r + 1 result[r] = char(lastflag,nofflags-1) + end + nofflags = 1 + lastflag = fl end - r = r + 1 result[r] = concat(xpoints) - r = r + 1 result[r] = concat(ypoints) end + if nofflags == 1 then + -- r = r + 1 result[r] = char(lastflag) + r = r + 1 result[r] = chars[lastflag] + elseif nofflags == 2 then + r = r + 1 result[r] = char(lastflag,lastflag) + elseif nofflags > 2 then + lastflag = lastflag + 0x08 + r = r + 1 result[r] = char(lastflag,nofflags-1) + end + -- r = r + 1 result[r] = concat(xpoints) + -- r = r + 1 result[r] = concat(ypoints) + r = r + 1 result[r] = concat(xpoints,"",1,x) + r = r + 1 result[r] = concat(ypoints,"",1,y) end - glyph.stream = concat(result,"",1,r) - else - -- fatal + -- can be helper or delegated to user + local stream = concat(result,"",1,r) + local length = #stream + local padding = idiv(length+3,4) * 4 - length + if padding > 0 then + -- stream = stream .. rep("\0",padding) -- can be a repeater + if padding == 1 then + padding = "\0" + elseif padding == 2 then + padding = "\0\0" + else + padding = "\0\0\0" + end + padding = stream .. padding + end + glyph.stream = stream end end end -- end of converter +local flags = { } + local function readglyph(f,nofcontours) -- read deltas here, saves space - local points = { } - local contours = { } - local instructions = { } - local flags = { } + local points = { } + -- local instructions = { } + local contours = { } -- readintegertable(f,nofcontours,short) for i=1,nofcontours do contours[i] = readshort(f) + 1 end @@ -699,9 +803,15 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space local flag = readbyte(f) flags[i] = flag if band(flag,0x08) ~= 0 then - for j=1,readbyte(f) do + local n = readbyte(f) + if n == 1 then i = i + 1 flags[i] = flag + else + for j=1,n do + i = i + 1 + flags[i] = flag + end end end i = i + 1 @@ -710,16 +820,16 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space -- can be repeated local x = 0 for i=1,nofpoints do - local flag = flags[i] - local short = band(flag,0x02) ~= 0 - local same = band(flag,0x10) ~= 0 - if short then - if same then + local flag = flags[i] + -- local short = band(flag,0x04) ~= 0 + -- local same = band(flag,0x20) ~= 0 + if band(flag,0x02) ~= 0 then + if band(flag,0x10) ~= 0 then x = x + readbyte(f) else x = x - readbyte(f) end - elseif same then + elseif band(flag,0x10) ~= 0 then -- copy else x = x + readshort(f) @@ -728,16 +838,16 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space end local y = 0 for i=1,nofpoints do - local flag = flags[i] - local short = band(flag,0x04) ~= 0 - local same = band(flag,0x20) ~= 0 - if short then - if same then + local flag = flags[i] + -- local short = band(flag,0x04) ~= 0 + -- local same = band(flag,0x20) ~= 0 + if band(flag,0x04) ~= 0 then + if band(flag,0x20) ~= 0 then y = y + readbyte(f) else y = y - readbyte(f) end - elseif same then + elseif band(flag,0x20) ~= 0 then -- copy else y = y + readshort(f) @@ -833,7 +943,7 @@ local function readcomposite(f) if band(flags,0x0100) ~= 0 then instructions = true end - if not band(flags,0x0020) ~= 0 then -- f_more + if band(flags,0x0020) == 0 then -- f_more break end end @@ -858,21 +968,27 @@ function readers.loca(f,fontdata,specification) -- locations are relative to the glypdata table (glyf) local offset = fontdata.tables.glyf.offset local format = fontdata.fontheader.indextolocformat + local profile = fontdata.maximumprofile + local nofglyphs = profile and profile.nofglyphs local locations = { } setposition(f,datatable.offset) if format == 1 then - local nofglyphs = datatable.length/4 - 2 + if not nofglyphs then + nofglyphs = idiv(datatable.length,4) - 1 + end for i=0,nofglyphs do locations[i] = offset + readulong(f) end fontdata.nofglyphs = nofglyphs else - local nofglyphs = datatable.length/2 - 2 + if not nofglyphs then + nofglyphs = idiv(datatable.length,2) - 1 + end for i=0,nofglyphs do locations[i] = offset + readushort(f) * 2 end - fontdata.nofglyphs = nofglyphs end + fontdata.nofglyphs = nofglyphs fontdata.locations = locations end end @@ -888,15 +1004,16 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module local filesize = fontdata.filesize local nothing = { 0, 0, 0, 0 } local shapes = { } - local loadshapes = specification.shapes or specification.instance - for index=0,nofglyphs do + local loadshapes = specification.shapes or specification.instance or specification.streams + for index=0,nofglyphs-1 do local location = locations[index] + local length = locations[index+1] - location if location >= filesize then report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) fontdata.nofglyphs = index - 1 fontdata.badfont = true break - elseif location > 0 then + elseif length > 0 then setposition(f,location) local nofcontours = readshort(f) glyphs[index].boundingbox = { @@ -908,7 +1025,7 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module if not loadshapes then -- save space elseif nofcontours == 0 then - shapes[index] = readnothing(f,nofcontours) + shapes[index] = readnothing(f) elseif nofcontours > 0 then shapes[index] = readglyph(f,nofcontours) else @@ -916,7 +1033,7 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module end else if loadshapes then - shapes[index] = { } + shapes[index] = readnothing(f) end glyphs[index].boundingbox = nothing end @@ -933,7 +1050,13 @@ function readers.glyf(f,fontdata,specification) -- part goes to cff module contours2outlines_shaped(glyphs,shapes,specification.shapes) end elseif specification.shapes then - contours2outlines_normal(glyphs,shapes) + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_normal(glyphs,shapes) + end + elseif specification.streams then + repackpoints(glyphs,shapes) end end end @@ -1234,10 +1357,6 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) end end if shape.type == "glyph" then --- if glyph.name == "u1f31d" then --- if glyph.unicode == 127773 then --- inspect(deltas) --- end applyaxis(glyph,shape,deltas,dowidth) else -- todo: args_are_xy_values mess .. i have to be really bored diff --git a/tex/context/base/mkiv/font-var.mkvi b/tex/context/base/mkiv/font-var.mkvi index fb60b711c..8520a5c32 100644 --- a/tex/context/base/mkiv/font-var.mkvi +++ b/tex/context/base/mkiv/font-var.mkvi @@ -50,6 +50,8 @@ \let\fontsize \defaultfontsize \let\fontface \!!zerocount +\installmacrostack\fontstyle + % we can use an indirect mapping for fontclasses (map string onto numbers) and indeed this % is somewhat more efficient but also makes the code messy ... maybe some day ... diff --git a/tex/context/base/mkiv/font-vfc.lua b/tex/context/base/mkiv/font-vfc.lua new file mode 100644 index 000000000..dfe6b3afc --- /dev/null +++ b/tex/context/base/mkiv/font-vfc.lua @@ -0,0 +1,123 @@ +if not modules then modules = { } end modules ['font-vfc'] = { + version = 1.001, + comment = "companion to font-ini.mkiv and hand-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local select, type = select, type +local insert = table.insert + +local fonts = fonts +local helpers = fonts.helpers + +local setmetatableindex = table.setmetatableindex +local makeweak = table.makeweak + +-- Helpers dealing with virtual fonts: beware, these are final values so +-- don't change the content of tables gotten this way! + +local push = { "push" } +local pop = { "pop" } +local dummy = { "comment" } + +function helpers.prependcommands(commands,...) + insert(commands,1,push) + for i=select("#",...),1,-1 do + local s = (select(i,...)) + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end + +function helpers.appendcommands(commands,...) + insert(commands,1,push) + insert(commands,pop) + for i=1,select("#",...) do + local s = (select(i,...)) + if s then + insert(commands,s) + end + end + return commands +end + +function helpers.prependcommandtable(commands,t) + insert(commands,1,push) + for i=#t,1,-1 do + local s = t[i] + if s then + insert(commands,1,s) + end + end + insert(commands,pop) + return commands +end + +function helpers.appendcommandtable(commands,t) + insert(commands,1,push) + insert(commands,pop) + for i=1,#t do + local s = t[i] + if s then + insert(commands,s) + end + end + return commands +end + +-- todo: maybe weak +-- todo: maybe indirect so that we can't change them + +local char = setmetatableindex(function(t,k) + -- local v = { "char", k } + local v = { "slot", 0, k } + t[k] = v + return v +end) + +local right = setmetatableindex(function(t,k) + local v = { "right", k } + t[k] = v + return v +end) + +local left = setmetatableindex(function(t,k) + local v = { "right", -k } + t[k] = v + return v +end) + +local down = setmetatableindex(function(t,k) + local v = { "down", k } + t[k] = v + return v +end) + +local up = setmetatableindex(function(t,k) + local v = { "down", -k } + t[k] = v + return v +end) + +-- makeweak(char) +-- makeweak(right) +-- makeweak(left) +-- makeweak(up) +-- makeweak(down) + +helpers.commands = utilities.storage.allocate { + char = char, + right = right, + left = left, + down = down, + up = up, + push = push, + pop = pop, + dummy = dummy, +} + diff --git a/tex/context/base/mkiv/font-vir.lua b/tex/context/base/mkiv/font-vir.lua index 03ad7fc85..c3071cac0 100644 --- a/tex/context/base/mkiv/font-vir.lua +++ b/tex/context/base/mkiv/font-vir.lua @@ -14,7 +14,7 @@ if not modules then modules = { } end modules ['font-vir'] = { -- -- vf.rule vf.special vf.right vf.push vf.down vf.char vf.node vf.fontid vf.pop vf.image vf.nop -local next = next +local next, setmetatable, getmetatable = next, setmetatable, getmetatable local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex @@ -66,11 +66,7 @@ local combinations = { } local combiner = { } local whatever = allocate() local helpers = allocate() -local predefined = allocate { - dummy = { "comment" }, - push = { "push" }, - pop = { "pop" }, -} +local predefined = fonts.helpers.commands methods.variants = variants -- todo .. wrong namespace vf.combinations = combinations @@ -110,8 +106,10 @@ local function combine_assign(g, name, from, to, start, force) if not from then from, to = 0, 0xFF00 end if not to then to = from end if not start then start = from end - local fc, gc = f.characters, g.characters - local fd, gd = f.descriptions, g.descriptions + local fc = f.characters + local gc = g.characters + local fd = f.descriptions + local gd = g.descriptions local hn = #g.fonts+1 g.fonts[hn] = { id = id } -- no need to be sparse for i=from,to do @@ -137,8 +135,10 @@ end local function combine_names(g,name,force) local f, id = constructors.readanddefine(name,g.specification.size) if f and id then - local fc, gc = f.characters, g.characters - local fd, gd = f.descriptions, g.descriptions + local fc = f.characters + local gc = g.characters + local fd = f.descriptions + local gd = g.descriptions g.fonts[#g.fonts+1] = { id = id } -- no need to be sparse local hn = #g.fonts for k, v in next, fc do @@ -153,7 +153,8 @@ local function combine_names(g,name,force) end local combine_feature = function(g,v) - local key, value = v[2], v[3] + local key = v[2] + local value = v[3] if key then if value == nil then value = true diff --git a/tex/context/base/mkiv/font-web.lua b/tex/context/base/mkiv/font-web.lua index 452a8f59b..376b036f2 100644 --- a/tex/context/base/mkiv/font-web.lua +++ b/tex/context/base/mkiv/font-web.lua @@ -23,18 +23,30 @@ local streamwriter = readers and readers.streamwriter or utilities.files local readstring = streamreader.readstring local readcardinal2 = streamreader.readcardinal2 local readcardinal4 = streamreader.readcardinal4 +local getsize = streamreader.getsize +local setposition = streamreader.setposition +local getposition = streamreader.getposition local writestring = streamwriter.writestring local writecardinal4 = streamwriter.writecardinal4 local writecardinal2 = streamwriter.writecardinal2 local writebyte = streamwriter.writebyte -local getsize = streamreader.getsize -local setposition = streamreader.setposition -local getposition = streamreader.getposition - local decompress = zlib.decompress +directives.register("fonts.streamreader",function() + + streamreader = utilities.streams + + readstring = streamreader.readstring + readcardinal2 = streamreader.readcardinal2 + readcardinal4 = streamreader.readcardinal4 + getsize = streamreader.getsize + setposition = streamreader.setposition + getposition = streamreader.getposition + +end) + local infotags = { ["os/2"] = true, ["head"] = true, diff --git a/tex/context/base/mkiv/font-xtx.lua b/tex/context/base/mkiv/font-xtx.lua deleted file mode 100644 index 494ac00a9..000000000 --- a/tex/context/base/mkiv/font-xtx.lua +++ /dev/null @@ -1,97 +0,0 @@ -if not modules then modules = { } end modules ['luatex-fonts-def'] = { - version = 1.001, - comment = "companion to luatex-*.tex", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - -if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() -end - -local fonts = fonts - --- A bit of tuning for definitions. - -fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload - --- tricky: we sort of bypass the parser and directly feed all into --- the sub parser - -function fonts.definers.getspecification(str) - return "", str, "", ":", str -end - --- the generic name parser (different from context!) - -local list = { } - -local function issome () list.lookup = 'name' end -- xetex mode prefers name (not in context!) -local function isfile () list.lookup = 'file' end -local function isname () list.lookup = 'name' end -local function thename(s) list.name = s end -local function issub (v) list.sub = v end -local function iscrap (s) list.crap = string.lower(s) end -local function iskey (k,v) list[k] = v end -local function istrue (s) list[s] = true end -local function isfalse(s) list[s] = false end - -local P, S, R, C = lpeg.P, lpeg.S, lpeg.R, lpeg.C - -local spaces = P(" ")^0 -local namespec = (1-S("/:("))^0 -- was: (1-S("/: ("))^0 -local crapspec = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces -local filename_1 = P("file:")/isfile * (namespec/thename) -local filename_2 = P("[") * P(true)/isname * (((1-P("]"))^0)/thename) * P("]") -local fontname_1 = P("name:")/isname * (namespec/thename) -local fontname_2 = P(true)/issome * (namespec/thename) -local sometext = (R("az","AZ","09") + S("+-.{}"))^1 -local truevalue = P("+") * spaces * (sometext/istrue) -local falsevalue = P("-") * spaces * (sometext/isfalse) -local keyvalue = (C(sometext) * spaces * P("=") * spaces * C(sometext))/iskey -local somevalue = sometext/istrue -local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim -local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces -local options = P(":") * spaces * (P(";")^0 * option)^0 - -local pattern = (filename_1 + filename_2 + fontname_1 + fontname_2) * subvalue^0 * crapspec^0 * options^0 - -local function colonized(specification) -- xetex mode - list = { } - lpeg.match(pattern,specification.specification) - list.crap = nil -- style not supported, maybe some day - if list.name then - specification.name = list.name - list.name = nil - end - if list.lookup then - specification.lookup = list.lookup - list.lookup = nil - end - if list.sub then - specification.sub = list.sub - list.sub = nil - end - specification.features.normal = fonts.handlers.otf.features.normalize(list) - return specification -end - -fonts.definers.registersplit(":",colonized,"cryptic") -fonts.definers.registersplit("", colonized,"more cryptic") -- catches \font\text=[names] - -function fonts.definers.applypostprocessors(tfmdata) - local postprocessors = tfmdata.postprocessors - if postprocessors then - for i=1,#postprocessors do - local extrahash = postprocessors[i](tfmdata) -- after scaling etc - if type(extrahash) == "string" and extrahash ~= "" then - -- e.g. a reencoding needs this - extrahash = string.gsub(lower(extrahash),"[^a-z]","-") - tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash) - end - end - end - return tfmdata -end diff --git a/tex/context/base/mkiv/good-ctx.lua b/tex/context/base/mkiv/good-ctx.lua index 00e4ed78d..82ef25e29 100644 --- a/tex/context/base/mkiv/good-ctx.lua +++ b/tex/context/base/mkiv/good-ctx.lua @@ -29,14 +29,10 @@ local registerotffeature = fonts.handlers.otf.features.register local fontgoodies = fonts.goodies or { } -local glyph_code = nodes.nodecodes.glyph - local nuts = nodes.nuts local tonut = nuts.tonut -local getfont = nuts.getfont -local getchar = nuts.getchar local getattr = nuts.getattr -local traverse_id = nuts.traverse_id +local nextglyph = nuts.traversers.glyph -- colorschemes @@ -100,10 +96,10 @@ local function setcolorscheme(tfmdata,scheme) end end if privatestoo then - local private = fonts.constructors.privateoffset - local descriptions = tfmdata.descriptions + local privateoffset = fonts.constructors.privateoffset + local descriptions = tfmdata.descriptions for unicode, data in next, characters do - if unicode >= private then + if unicode >= privateoffset then if not reverse[unicode] then local d = descriptions[unicode] if d then @@ -128,68 +124,9 @@ local function setcolorscheme(tfmdata,scheme) end local fontproperties = fonts.hashes.properties - local a_colorscheme = attributes.private('colorscheme') local setnodecolor = nodes.tracers.colors.set - --- function colorschemes.coloring(head) --- local lastfont, lastscheme --- local done = false --- for n in traverse_id(glyph_code,tonut(head)) do --- local a = getattr(n,a_colorscheme) --- if a then --- local f = getfont(n) --- if f ~= lastfont then --- lastscheme = fontproperties[f].colorscheme --- lastfont = f --- end --- if lastscheme then --- local sc = lastscheme[getchar(n)] --- if sc then --- done = true --- setnodecolor(n,"colorscheme:"..a..":"..sc) -- slow --- end --- end --- end --- end --- return head, done --- end - --- seldom used, mostly in manuals, so non critical .. anyhow, somewhat faster: - --- function colorschemes.coloring(head) --- local lastfont = nil --- local lastattr = nil --- local lastscheme = nil --- local lastprefix = nil --- local done = nil --- for n in traverse_id(glyph_code,tonut(head)) do --- local a = getattr(n,a_colorscheme) --- if a then --- if a ~= lastattr then --- lastattr = a --- lastprefix = "colorscheme:" .. a .. ":" --- end --- local f = getfont(n) --- if f ~= lastfont then --- lastfont = f --- lastscheme = fontproperties[f].colorscheme --- end --- if lastscheme then --- local sc = lastscheme[getchar(n)] --- if sc then --- setnodecolor(n,lastprefix .. sc) -- slow --- done = true --- end --- end --- end --- end --- return head, done --- end - --- ok, in case we have hundreds of pages colored: - -local cache = { } -- this could be a weak table +local cache = { } -- this could be a weak table setmetatableindex(cache,function(t,a) local v = { } @@ -207,11 +144,9 @@ function colorschemes.coloring(head) local lastattr = nil local lastcache = nil local lastscheme = nil - local done = nil - for n in traverse_id(glyph_code,tonut(head)) do + for n, char, f in nextglyph, head do local a = getattr(n,a_colorscheme) if a then - local f = getfont(n) if f ~= lastfont then lastfont = f lastscheme = fontproperties[f].colorscheme @@ -221,19 +156,18 @@ function colorschemes.coloring(head) lastcache = cache[a] end if lastscheme then - local sc = lastscheme[getchar(n)] + local sc = lastscheme[char] if sc then setnodecolor(n,lastcache[sc]) -- we could inline this one - done = true end end end end - return head, done + return head end function colorschemes.enable() - nodes.tasks.appendaction("processors","fonts","fonts.goodies.colorschemes.coloring") + nodes.tasks.enableaction("processors","fonts.goodies.colorschemes.coloring") function colorschemes.enable() end end diff --git a/tex/context/base/mkiv/grph-epd.lua b/tex/context/base/mkiv/grph-epd.lua index 7855ce891..f8fa62953 100644 --- a/tex/context/base/mkiv/grph-epd.lua +++ b/tex/context/base/mkiv/grph-epd.lua @@ -8,25 +8,26 @@ if not modules then modules = { } end modules ['grph-epd'] = { local variables = interfaces.variables local settings_to_hash = utilities.parsers.settings_to_hash +local codeinjections = backends.pdf.codeinjections --- todo: page, name, file, url +local trace = false trackers.register("figures.merging", function(v) trace = v end) --- I have some experimental code for including comments and fields but it's --- unfinished and not included as it was just a proof of concept to get some idea --- about what is needed and possible. But the placeholders are here already. - -local codeinjections = backends.codeinjections +local report = logs.reporter("backend","merging") local function mergegoodies(optionlist) local options = settings_to_hash(optionlist) - local all = options[variables.all] or options[variables.yes] - if all or options[variables.reference] then + local yes = options[variables.yes] + local all = options[variables.all] + if next(options) then + report("% t",table.sortedkeys(options)) + end + if all or yes or options[variables.reference] then codeinjections.mergereferences() end if all or options[variables.comment] then codeinjections.mergecomments() end - if all or options[variables.bookmark] then + if all or yes or options[variables.bookmark] then codeinjections.mergebookmarks() end if all or options[variables.field] then @@ -39,6 +40,7 @@ local function mergegoodies(optionlist) end function figures.mergegoodies(optionlist) + -- todo: we can use runtoks instead context.stepwise(function() -- we use stepwise because we might need to define symbols -- for stamps that have no default appearance diff --git a/tex/context/base/mkiv/grph-inc.lua b/tex/context/base/mkiv/grph-inc.lua index f2d7847eb..1e5c30d44 100644 --- a/tex/context/base/mkiv/grph-inc.lua +++ b/tex/context/base/mkiv/grph-inc.lua @@ -6,6 +6,11 @@ if not modules then modules = { } end modules ['grph-inc'] = { license = "see context related readme files" } +-- todo: in pdfe: pdfe.copyappearance(document,objnum) +-- +-- local im = createimage { filename = fullname } +-- local on = images.flushobject(im,document.__xrefs__[AP]) + -- todo: files are sometimes located twice -- todo: empty filename or only suffix always false (not found) -- lowercase types @@ -40,17 +45,16 @@ run TeX code from within Lua. Some more functionality will move to Lua. -- todo: store loaded pages per pdf file someplace -local tonumber, tostring, next = tonumber, tostring, next +local tonumber, tostring, next, unpack = tonumber, tostring, next, unpack local format, lower, find, match, gsub = string.format, string.lower, string.find, string.match, string.gsub local longtostring = string.longtostring local contains = table.contains -local sortedhash = table.sortedhash +local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys local concat, insert, remove = table.concat, table.insert, table.remove local todimen = string.todimen local collapsepath = file.collapsepath local formatters = string.formatters -local formatcolumns = utilities.formatters.formatcolumns -local max, odd = math.max, math.odd +local odd = math.odd local P, R, S, Cc, C, Cs, Ct, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.Cc, lpeg.C, lpeg.Cs, lpeg.Ct, lpeg.match @@ -60,7 +64,10 @@ local allocate = utilities.storage.allocate local setmetatableindex = table.setmetatableindex local replacetemplate = utilities.templates.replace -local images = img +local bpfactor = number.dimenfactors.bp + +images = images or { } +local images = images local hasscheme = url.hasscheme local urlhashed = url.hashed @@ -104,7 +111,7 @@ local v_local = variables["local"] local v_default = variables.default local v_auto = variables.auto -local maxdimen = 0x3FFFFFFF -- 2^30-1 +local maxdimen = tex.magicconstants.maxdimen -- 0x3FFFFFFF -- 2^30-1 local ctx_doscalefigure = context.doscalefigure local ctx_relocateexternalfigure = context.relocateexternalfigure @@ -120,11 +127,11 @@ function checkimage(figure) local width = figure.width local height = figure.height if width <= 0 or height <= 0 then - report_inclusion("image %a has bad dimensions (%p,%p), discarding",figure.filename,width,height) + report_inclusion("image %a has bad dimensions (%p,%p), discarding",figure.filename or "?",width,height) return false, "bad dimensions" end - local xres = figure.xres - local yres = figure.yres + -- local xres = figure.xres + -- local yres = figure.yres local changes = false if height > width then if height > maxdimen then @@ -150,14 +157,117 @@ function checkimage(figure) end end ---- some extra img functions --- can become luat-img.lua +--- begin of mapping / this will become graphics & code|nodeinjections but not this year + +local __img__ = type(img) == "table" and img or { } +images.__img__ =__img__ + +local imgnew = __img__.new +local imgscan = __img__.scan +local imgcopy = __img__.copy +local imgwrap = __img__.node +local imgembed = __img__.immediatewrite + +if imgnew then + -- catch (actually we should be less picky in img) + local __img__new__ = img_new + imgnew = function(t) + t.kind = nil + return __img__new__(t) + end +end + +updaters.register("backend.update",function() + local img = images.__img__ + imgnew = img.new + imgscan = img.scan + imgcopy = img.copy + imgwrap = img.wrap + imgembed = img.embed +end) + +local imagekeys = { -- only relevant ones + "width", "height", "depth", "bbox", + "colordepth", "colorspace", + "filename", "filepath", "visiblefilename", + "imagetype", "stream", + "index", "objnum", + "pagebox", "page", "pages", + "rotation", "transform", + "xsize", "ysize", "xres", "yres", +} + +local imagesizes = { + art = true, bleed = true, crop = true, + media = true, none = true, trim = true, +} + +local imagetypes = { [0] = + "none", + "pdf", "png", "jpg", "jp2", "jbig2", + "stream", "memstream", +} + +imagetypes = table.swapped(imagetypes,imagetypes) + +images.keys = imagekeys +images.types = imagetypes +images.sizes = imagesizes + +-- new interface + +local function createimage(specification) + return imgnew(specification) +end + +local function copyimage(specification) + return imgcopy(specification) +end + +local function scanimage(specification) + return imgscan(specification) +end + +local function embedimage(specification) + -- write the image to file + return imgembed(specification) +end + +local function wrapimage(specification) + -- create an image rule + return imgwrap(specification) +end + +images.create = createimage +images.scan = scanimage +images.copy = copyimage +images.wrap = wrapimage +images.embed = embedimage + +-- now we reimplement img: + +img = { + new = createimage, + scan = scanimage, + copy = copyimage, + node = wrapimage, + write = function(specification) context(wrapimage(specification)) end, + immediatewrite = embedimage, + immediatewriteobject = function() end, -- not upported, experimental anyway + boxes = function() return sortedkeys(imagesizes) end, + fields = function() return imagekeys end, + types = function() return { unpack(imagetypes,0,#imagetypes) } end, +} -local allimagekeys = images.keys() +-- end of copies / mapping local function imagetotable(imgtable) + if type(imgtable) == "table" then + return copy(imgtable) + end local result = { } - for k=1,#allimagekeys do - local key = allimagekeys[k] + for k=1,#imagekeys do + local key = imagekeys[k] result[key] = imgtable[key] end return result @@ -171,41 +281,24 @@ function images.print(i,...) return table.print(imagetotable(i),...) end -function images.clone(i,data) - i.width = data.width or i.width - i.height = data.height or i.height - -- attr etc - return i -end - -local validsizes = table.tohash(images.boxes()) -local validtypes = table.tohash(images.types()) - local function checkimagesize(size) if size then size = gsub(size,"box","") - return validsizes[size] and size or "crop" + return imagesizes[size] and size or "crop" else return "crop" end end -local newimage = images.new -local scanimage = images.scan -local copyimage = images.copy -local cloneimage = images.clone -local imagetonode = images.node - -images.check = checkimage -images.checksize = checkimagesize -images.tonode = imagetonode -images.totable = imagetotable +images.check = checkimage +images.checksize = checkimagesize +images.totable = imagetotable -local indexed = { } - -function images.ofindex(n) - return indexed[n] -end +-- local indexed = { } +-- +-- function images.ofindex(n) +-- return indexed[n] +-- end --- we can consider an grph-ini file @@ -372,22 +465,30 @@ function figures.setorder(list) -- can be table or string end end +local function guessfromstring(str) + if str then + for i=1,#figures_magics do + local pattern = figures_magics[i] + if lpegmatch(pattern.pattern,str) then + local format = pattern.format + if trace_figures then + report_inclusion("file %a has format %a",filename,format) + end + return format + end + end + end +end + +figures.guessfromstring = guessfromstring + function figures.guess(filename) local f = io.open(filename,'rb') if f then local str = f:read(100) f:close() if str then - for i=1,#figures_magics do - local pattern = figures_magics[i] - if lpegmatch(pattern.pattern,str) then - local format = pattern.format - if trace_figures then - report_inclusion("file %a has format %a",filename,format) - end - return format - end - end + return guessfromstring(str) end end end @@ -571,6 +672,7 @@ function figures.initialize(request) request.cache = request.cache ~= "" and request.cache request.prefix = request.prefix ~= "" and request.prefix request.format = request.format ~= "" and request.format + request.compact = request.compact == v_yes table.merge(figuredata.request,request) end return figuredata @@ -818,7 +920,7 @@ local function register(askedname,specification) end elseif io.exists(oldname) then report_inclusion("file %a is bugged",oldname) - if format and validtypes[format] then + if format and imagetypes[format] then specification.fullname = oldname end specification.converted = false @@ -827,13 +929,13 @@ local function register(askedname,specification) end end if format then - local found = figures_suffixes[format] -- validtypes[format] + local found = figures_suffixes[format] if not found then specification.found = false if trace_figures then report_inclusion("format %a is not supported",format) end - elseif validtypes[format] then + elseif imagetypes[format] then specification.found = true if trace_figures then report_inclusion("format %a natively supported by backend",format) @@ -1362,15 +1464,18 @@ end local pagecount = { } function checkers.generic(data) - local dr, du, ds = data.request, data.used, data.status - local name = du.fullname or "unknown generic" - local page = du.page or dr.page - local size = dr.size or "crop" - local color = dr.color or "natural" - local mask = dr.mask or "none" - local conversion = dr.conversion - local resolution = dr.resolution - local arguments = dr.arguments + local dr, du, ds = data.request, data.used, data.status + local name = du.fullname or "unknown generic" + local page = du.page or dr.page + local size = dr.size or "crop" + local color = dr.color or "natural" + local mask = dr.mask or "none" + local conversion = dr.conversion + local resolution = dr.resolution + local arguments = dr.arguments + local scanimage = dr.scanimage or scanimage + local userpassword = dr.userpassword + local ownerpassword = dr.ownerpassword if not conversion or conversion == "" then conversion = "default" end @@ -1390,22 +1495,29 @@ function checkers.generic(data) resolution, arguments ) + -- local figure = figures_loaded[hash] if figure == nil then - figure = newimage { + figure = createimage { filename = name, page = page, pagebox = dr.size, keepopen = dr.keepopen or false, + userpassword = userpassword, + ownerpassword = ownerpassword, -- visiblefilename = "", -- this prohibits the full filename ending up in the file } codeinjections.setfigurecolorspace(data,figure) codeinjections.setfiguremask(data,figure) if figure then - -- new, bonus check + -- new, bonus check (a bogus check in lmtx) if page and page > 1 then - local f = scanimage{ filename = name } - if f.page and f.pages < page then + local f = scanimage { + filename = name, + userpassword = userpassword, + ownerpassword = ownerpassword, + } + if f and f.page and f.pages < page then report_inclusion("no page %i in %a, using page 1",page,name) page = 1 figure.page = page @@ -1418,6 +1530,10 @@ function checkers.generic(data) ds.found = false ds.error = true end + if figure.attr and not f.attr then + -- tricky as img doesn't allow it + f.attr = figure.attr + end figure = f end local f, d = codeinjections.setfigurealternative(data,figure) @@ -1459,6 +1575,11 @@ function figures.getrealpage(index) return pofimages[index] or 0 end +local function updatepage(specification) + local n = specification.n + pofimages[n] = pofimages[n] or tex.count.realpageno -- so when reused we register the first one only +end + function includers.generic(data) local dr, du, ds = data.request, data.used, data.status -- here we set the 'natural dimensions' @@ -1472,10 +1593,13 @@ function includers.generic(data) -- height = dr.height, -- } if figure == nil then - figure = ds.private + figure = ds.private -- the img object if figure then - figure = copyimage(figure) - figure = figure and cloneimage(figure,data.request) or false + figure = (dr.copyimage or copyimage)(figure) + if figure then + figure.width = dr.width or figure.width + figure.height = dr.height or figure.height + end end figures_used[hash] = figure end @@ -1483,16 +1607,15 @@ function includers.generic(data) local nr = figures.boxnumber nofimages = nofimages + 1 ds.pageindex = nofimages - local image = imagetonode(figure) - local pager = new_latelua(function() - pofimages[nofimages] = pofimages[nofimages] or tex.count.realpageno -- so when reused we register the first one only - end) + local image = wrapimage(figure) + local pager = new_latelua { action = updatepage, n = nofimages } image.next = pager pager.prev = image - local box = hpack(image) -- imagetonode(figure) not longer valid - - indexed[figure.index] = figure - box.width, box.height, box.depth = figure.width, figure.height, 0 -- new, hm, tricky, we need to do that in tex (yet) + local box = hpack(image) + -- indexed[figure.index] = figure + box.width = figure.width + box.height = figure.height + box.depth = 0 texsetbox(nr,box) ds.objectnumber = figure.objnum ctx_relocateexternalfigure() @@ -1546,7 +1669,7 @@ function checkers.mov(data) nodeinjections.insertmovie { width = width, height = height, - factor = number.dimenfactors.bp, + factor = bpfactor, ["repeat"] = dr["repeat"], controls = dr.controls, preview = dr.preview, @@ -1916,8 +2039,10 @@ function figures.getinfo(name,page) end if name.name then local data = figures.push(name) - figures.identify() - figures.check() + data = figures.identify(data) + if data.status and data.status.status > 0 then + data = figures.check(data) + end figures.pop() return data end @@ -1961,8 +2086,11 @@ implement { { "arguments" }, { "repeat" }, { "transform" }, + { "compact" }, { "width", "dimen" }, { "height", "dimen" }, + { "userpassword" }, + { "ownerpassword" }, } } } diff --git a/tex/context/base/mkiv/grph-inc.mkiv b/tex/context/base/mkiv/grph-inc.mkiv index 677883fbb..20e7c11a6 100644 --- a/tex/context/base/mkiv/grph-inc.mkiv +++ b/tex/context/base/mkiv/grph-inc.mkiv @@ -20,7 +20,15 @@ \writestatus{loading}{ConTeXt Graphic Macros / Figure Inclusion} -\registerctxluafile{grph-inc}{} +\ifcase\contextlmtxmode + \registerctxluafile{grph-inc}{} +\else + \registerctxluafile{grph-img}{} + \registerctxluafile{grph-inc}{} + \registerctxluafile{grph-bmp}{} + \registerctxluafile{grph-chk}{} +\fi + \registerctxluafile{grph-con}{} \registerctxluafile{grph-fil}{} \registerctxluafile{grph-mem}{} @@ -32,7 +40,7 @@ %D Including graphics is complicated by the fact that we need to locate them first, %D optionally manipulate them and scale then next. Lookups are to be done as efficient %D as possible and inclusion of the data might happens only once. In \MKIV\ much of this -%D is delegated to the \LUA\ end. There is nor so much less code as in \MKII\ but it's +%D is delegated to the \LUA\ end. There is not so much less code as in \MKII\ but it's %D more powerful, flexible, pluggable and some of the extended functionality has been %D moved from modules to the core. The overall functionality is rather stable and has %D not changed much over the years. @@ -105,6 +113,9 @@ \c!align =\v!none, % New, for Tacos extremely large graphics. \c!crossreference =\v!no, \c!transform =\v!auto, + \c!userpassword =, + \c!ownerpassword =, + \c!compact =, ] %D Defining figures. @@ -201,7 +212,7 @@ {\grph_include_use_indeed{#1}{#2}{#3}{#4}}}}} \def\grph_include_use_indeed#1#2#3#4% - {\setvalue{\??externalfigureinstance#1}{\grph_include_setup{#2}{#3}{#4}}% + {\dodoglobal\setvalue{\??externalfigureinstance#1}{\grph_include_setup{#2}{#3}{#4}}% \grph_include_analyze_collection[#2][#4]} % inclusion @@ -317,27 +328,30 @@ % \dostarttagged\t!image\empty \clf_figure_push { - name {\p_grph_include_name}% - label {\ifx\p_label\empty\p_grph_include_label\else\p_label\fi}% - page {\externalfigureparameter\c!page}% - file {\externalfigureparameter\c!file}% - size {\externalfigureparameter\c!size}% - object {\externalfigureparameter\c!object}% - prefix {\externalfigureparameter\c!prefix}% - cache {\externalfigureparameter\c!cache}% - format {\externalfigureparameter\c!method}% - preset {\externalfigureparameter\c!prefix}% - controls {\externalfigureparameter\c!controls}% - resources {\externalfigureparameter\c!resources}% - preview {\externalfigureparameter\c!preview}% - display {\externalfigureparameter\c!display}% - mask {\externalfigureparameter\c!mask}% - conversion {\externalfigureparameter\c!conversion}% - resolution {\externalfigureparameter\c!resolution}% - color {\externalfigureparameter\c!color}% unprocessed raw key - arguments {\externalfigureparameter\c!arguments}% used for converters - repeat {\externalfigureparameter\c!repeat}% - transform {\externalfigureparameter\c!transform}% + name {\p_grph_include_name}% + label {\ifx\p_label\empty\p_grph_include_label\else\p_label\fi}% + page {\externalfigureparameter\c!page}% + file {\externalfigureparameter\c!file}% + size {\externalfigureparameter\c!size}% + object {\externalfigureparameter\c!object}% + prefix {\externalfigureparameter\c!prefix}% + cache {\externalfigureparameter\c!cache}% + format {\externalfigureparameter\c!method}% + preset {\externalfigureparameter\c!prefix}% + controls {\externalfigureparameter\c!controls}% + resources {\externalfigureparameter\c!resources}% + preview {\externalfigureparameter\c!preview}% + display {\externalfigureparameter\c!display}% + mask {\externalfigureparameter\c!mask}% + conversion {\externalfigureparameter\c!conversion}% + resolution {\externalfigureparameter\c!resolution}% + color {\externalfigureparameter\c!color}% unprocessed raw key + arguments {\externalfigureparameter\c!arguments}% used for converters + repeat {\externalfigureparameter\c!repeat}% + transform {\externalfigureparameter\c!transform}% + compact {\externalfigureparameter\c!compact}% experiment, share fonts + userpassword {\externalfigureparameter\c!userpassword}% + ownerpassword{\externalfigureparameter\c!ownerpassword}% \ifx\p_width\empty \else width \dimexpr\p_width\relax \fi @@ -589,9 +603,9 @@ \def\grph_include_set_mode {\ifcase\figurestatus - \global\resetsystemmode\v!figure % todo, also: \v!resource + \globalresetsystemmode\v!figure % todo, also: \v!resource \else - \global\setsystemmode \v!figure % todo, also: \v!resource + \globalsetsystemmode \v!figure % todo, also: \v!resource \fi} \appendtoks @@ -641,10 +655,41 @@ \unexpanded\def\docheckfiguremps #1{\global\setbox\foundexternalfigure\vpack{\convertMPtoPDF{#1}11}} \unexpanded\def\docheckfiguremprun #1#2{\global\setbox\foundexternalfigure\vpack{\useMPrun{#1}{#2}}} -\unexpanded\def\relocateexternalfigure % easier here than in lua +% \unexpanded\def\relocateexternalfigure % easier here than in lua +% {\global\setbox\foundexternalfigure\vpack to \ht\foundexternalfigure\bgroup +% \vss +% \ht\foundexternalfigure\zeropoint +% \hpack to \wd\foundexternalfigure\bgroup +% \box\foundexternalfigure +% \hss +% \egroup +% \egroup} + +\unexpanded\def\relocateexternalfigure {\global\setbox\foundexternalfigure\vpack to \ht\foundexternalfigure\bgroup - \vss + % + % The \vss can (!) introduce 1 sp excess visible in xform which in itself + % is not that important but some don't like these cosmetic side effects, for + % instance we can get: + % + % vss : \vbox(845.1575+0.0)x597.23125, glue set 845.15747fil, direction TLT + % vskip : \vbox(845.1575+0.0)x597.23125, direction TLT + % + % or + % + % 1 0 0 1 0 0.00003 cm + % 1 0 0 1 0 0 cm + % + % This is a known property of using glue and can even depend on the architecture + % (float implementation). Anyway, let's for now use a skip. Of course this can + % shift the issue elsewhere, as vss is used a lot elsewhere. + % + % \vss + \vkern\ht\foundexternalfigure + % + % \parfillskip\zeropoint \ht\foundexternalfigure\zeropoint + \dp\foundexternalfigure\zeropoint \hpack to \wd\foundexternalfigure\bgroup \box\foundexternalfigure \hss diff --git a/tex/context/base/mkiv/grph-mem.lua b/tex/context/base/mkiv/grph-mem.lua index bb48ae8d5..ff3548350 100644 --- a/tex/context/base/mkiv/grph-mem.lua +++ b/tex/context/base/mkiv/grph-mem.lua @@ -20,67 +20,143 @@ local gsub = string.gsub local report = logs.reporter("memstream") local trace = false trackers.register ("graphics.memstreams", function(v) trace = v end) local data = { } -local opened = { } -local function setmemstream(name,stream,once) - if once and data[name] then +if pdfe then + + local function setmemstream(name,stream,once) + if once and data[name] then + if trace then + report("not overloading %a",name) -- + end + return data[name] + end + local kind = figures.guessfromstring(stream) + local identifier = false + if kind == "pdf" then + identifier = pdfe.new(stream,#stream,name) + if not identifier then + report("no valid pdf stream %a",name) + elseif trace then + report("setting %a with identifier %a",name,identifier) + end + else + identifier = "m_k_i_v_memstream_" .. name .. "." .. kind + io.savedata(identifier,stream) + end + if not identifier then + identifier = "invalid-memstream" + end + data[name] = identifier + return identifier + end + + resolvers.setmemstream = setmemstream + + function resolvers.finders.memstream(specification) + local name = specification.path + local identifier = data[name] + if identifier then + if trace then + report("reusing %a with identifier %a",name,identifier) + end + return identifier + end + local stream = io.loaddata(name) + if stream and stream ~= "" then + return setmemstream(name,stream) + end if trace then - report("not overloading %a",name) -- + report("no valid memstream %a",name) end - return data[name] + return resolvers.finders.notfound() end - local memstream, identifier = epdf.openMemStream(stream,#stream,name) - if not identifier then - report("no valid stream %a",name) - identifier = "invalid-memstream" - elseif trace then - report("setting %a with identifier %a",name,identifier) + + local flush = { } + + function resolvers.resetmemstream(name,afterpage) + if afterpage then + flush[#flush+1] = name + end end - data [name] = identifier - opened[name] = memstream - return identifier -end -resolvers.setmemstream = setmemstream + luatex.registerpageactions(function() + if #flush > 0 then + for i=1,#flush do + local identifier = data[name] + if identifier then + os.remove(identifier) + data[name] = nil + end + end + flush = { } + end + end) + +else -function resolvers.finders.memstream(specification) - local name = specification.path - local identifier = data[name] - if identifier then - if trace then - report("reusing %a with identifier %a",name,identifier) + local opened = { } + + local function setmemstream(name,stream,once) + if once and data[name] then + if trace then + report("not overloading %a",name) -- + end + return data[name] end + local memstream, identifier = epdf.openMemStream(stream,#stream,name) + if not identifier then + report("no valid stream %a",name) + identifier = "invalid-memstream" + elseif trace then + report("setting %a with identifier %a",name,identifier) + end + data [name] = identifier + opened[name] = memstream return identifier end - local stream = io.loaddata(name) - if not stream or stream == "" then - if trace then - report("no valid file %a",name) + + resolvers.setmemstream = setmemstream + + function resolvers.finders.memstream(specification) + local name = specification.path + local identifier = data[name] + if identifier then + if trace then + report("reusing %a with identifier %a",name,identifier) + end + return identifier + end + local stream = io.loaddata(name) + if not stream or stream == "" then + if trace then + report("no valid file %a",name) + end + return resolvers.finders.notfound() + else + return setmemstream(name,stream) end - return resolvers.finders.notfound() - else - return setmemstream(name,stream) end -end -local flush = { } + local flush = { } -function resolvers.resetmemstream(name,afterpage) - if afterpage then - flush[#flush+1] = name - else - opened[name] = nil + function resolvers.resetmemstream(name,afterpage) + if afterpage then + flush[#flush+1] = name + else + opened[name] = nil + end end -end -luatex.registerpageactions(function() - if #flush > 0 then - for i=1,#flush do - opened[flush[i]] = nil -- we keep of course data[name] because of reuse + luatex.registerpageactions(function() + if #flush > 0 then + for i=1,#flush do + opened[flush[i]] = nil -- we keep of course data[name] because of reuse + end + flush = { } end - flush = { } - end -end) + end) + +end figures.identifiers.list[#figures.identifiers.list+1] = function(specification) local name = specification.request.name diff --git a/tex/context/base/mkiv/grph-pat.lua b/tex/context/base/mkiv/grph-pat.lua index 89b29906d..e38a9a674 100644 --- a/tex/context/base/mkiv/grph-pat.lua +++ b/tex/context/base/mkiv/grph-pat.lua @@ -15,7 +15,7 @@ local texsetbox = tex.setbox local texgetbox = tex.getbox local nodepool = nodes.pool -local new_literal = nodepool.pdforiginliteral -- really ? +local new_literal = nodepool.originliteral -- really ? local new_hlist = nodepool.hlist local names = { } @@ -37,7 +37,7 @@ interfaces.implement { if not name or name == "" then return end - nodes.handlers.finalize(box,"object") + nodes.handlers.finalizebox(number) names[name] = lpdf.registerpattern { number = number, width = specification.width or box.width, diff --git a/tex/context/base/mkiv/grph-rul.lua b/tex/context/base/mkiv/grph-rul.lua index 03f678973..08edade1f 100644 --- a/tex/context/base/mkiv/grph-rul.lua +++ b/tex/context/base/mkiv/grph-rul.lua @@ -8,33 +8,48 @@ if not modules then modules = { } end modules ['grph-rul'] = { local tonumber, next, type = tonumber, next, type -local attributes = attributes -local nodes = nodes -local context = context +local attributes = attributes +local nodes = nodes +local context = context -local ruleactions = nodes.rules.ruleactions -local userrule = nodes.rules.userrule -local bpfactor = number.dimenfactors.bp -local pdfprint = pdf.print +local bpfactor = number.dimenfactors.bp -local current_attr = nodes.current_attr -local setfield = nodes.setfield +local nuts = nodes.nuts +local userrule = nuts.rules.userrule +local outlinerule = nuts.pool.outlinerule +local ruleactions = nuts.rules.ruleactions -local getattribute = tex.getattribute +local setattrlist = nuts.setattrlist +local setattr = nuts.setattr +local tonode = nuts.tonode -local a_color = attributes.private('color') -local a_transparency = attributes.private('transparency') -local a_colormodel = attributes.private('colormodel') +local getattribute = tex.getattribute -local mpcolor = attributes.colors.mpcolor +local lefttoright_code = nodes.dirvalues.lefttoright -local trace_mp = false trackers.register("rules.mp", function(v) trace_mp = v end) +local a_color = attributes.private('color') +local a_transparency = attributes.private('transparency') +local a_colormodel = attributes.private('colormodel') -local report_mp = logs.reporter("rules","mp") +local mpcolor = attributes.colors.mpcolor -local floor = math.floor -local getrandom = utilities.randomizer.get -local formatters = string.formatters +local trace_mp = false trackers.register("rules.mp", function(v) trace_mp = v end) + +local report_mp = logs.reporter("rules","mp") + +local floor = math.floor +local getrandom = utilities.randomizer.get +local formatters = string.formatters + +-- This is very pdf specific. Maybe move some to lpdf-rul.lua some day. + +local pdfprint + +pdfprint = function(...) pdfprint = lpdf.print return pdfprint(...) end + +updaters.register("backend.update",function() + pdfprint = lpdf.print +end) do @@ -97,19 +112,18 @@ def RuleColor = %color% enddef ; ruleactions.mp = function(p,h,v,i,n) local name = p.name or "fake:rest" local code = (predefined[name] or predefined["fake:rest"]) { - data = p.data or "", - width = p.width * bpfactor, - height = p.height * bpfactor, - depth = p.depth * bpfactor, - factor = (p.factor or 0) * bpfactor, -- needs checking - offset = p.offset or 0, - line = (p.line or 65536) * bpfactor, - color = mpcolor(p.ma,p.ca,p.ta), - option = p.option or "", - direction = p.direction or "TLT", - h = h * bpfactor, - v = v * bpfactor, - + data = p.data or "", + width = p.width * bpfactor, + height = p.height * bpfactor, + depth = p.depth * bpfactor, + factor = (p.factor or 0) * bpfactor, -- needs checking + offset = p.offset or 0, + line = (p.line or 65536) * bpfactor, + color = mpcolor(p.ma,p.ca,p.ta), + option = p.option or "", + direction = p.direction or lefttoright_code, + h = h * bpfactor, + v = v * bpfactor, } if not initialized then initialized = true @@ -134,14 +148,28 @@ do local f_rectangle = formatters["%.6F w %.6F %.6F %.6F %.6F re %s"] local f_baselined = formatters["%.6F w %.6F %.6F %.6F %.6F re s %.6F %.6F m %.6F %.6F l s"] local f_dashlined = formatters["%.6F w %.6F %.6F %.6F %.6F re s [%.6F %.6F] 2 d %.6F %.6F m %.6F %.6F l s"] - local f_radtangle = formatters[ [[ - %.6F w %.6F %.6F m - %.6F %.6F l %.6F %.6F %.6F %.6F y - %.6F %.6F l %.6F %.6F %.6F %.6F y - %.6F %.6F l %.6F %.6F %.6F %.6F y - %.6F %.6F l %.6F %.6F %.6F %.6F y - h %s - ]] ] + local f_radtangle = formatters[ + [[%.6F w %.6F %.6F m +%.6F %.6F l %.6F %.6F %.6F %.6F y +%.6F %.6F l %.6F %.6F %.6F %.6F y +%.6F %.6F l %.6F %.6F %.6F %.6F y +%.6F %.6F l %.6F %.6F %.6F %.6F y +h %s]] + ] + + directives.register("metapost.stripzeros",function() -- confusing name but ok + f_rectangle = formatters["%.6N w %.6N %.6N %.6N %.6N re %s"] + f_baselined = formatters["%.6N w %.6N %.6N %.6N %.6N re s %.6N %.6N m %.6N %.6N l s"] + f_dashlined = formatters["%.6N w %.6N %.6N %.6N %.6N re s [%.6N %.6N] 2 d %.6N %.6N m %.6N %.6N l s"] + f_radtangle = formatters[ +[[%.6N w %.6N %.6N m +%.6N %.6N l %.6N %.6N %.6N %.6N y +%.6N %.6N l %.6N %.6N %.6N %.6N y +%.6N %.6N l %.6N %.6N %.6N %.6N y +%.6N %.6N l %.6N %.6N %.6N %.6N y +h %s]] + ] + end) ruleactions.fill = function(p,h,v,i,n) local l = (p.line or 65536)*bpfactor @@ -210,17 +238,44 @@ interfaces.implement { local ma = getattribute(a_colormodel) or 1 local ca = getattribute(a_color) local ta = getattribute(a_transparency) - setfield(rule,"attr",current_attr()) + setattrlist(rule,true) if t.type == "mp" then t.ma = ma t.ca = ca t.ta = ta else - rule[a_colormodel] = ma - rule[a_color] = ca - rule[a_transparency] = ta + setattr(rule,a_colormodel,ma) + setattr(rule,a_color,ca) + setattr(rule,a_transparency,ta) end - context(rule) + context(tonode(rule)) -- will become context.nodes.flush + end +} + +interfaces.implement { + name = "outlinerule", + public = true, + protected = true, + arguments = { { + { "width", "dimension" }, + { "height", "dimension" }, + { "depth", "dimension" }, + { "line", "dimension" }, + } } , + actions = function(t) + local rule = outlinerule(t.width,t.height,t.depth,t.line) + setattrlist(rule,true) + context(tonode(rule)) -- will become context.nodes.flush + end +} + +interfaces.implement { + name = "framedoutline", + arguments = { "dimension", "dimension", "dimension", "dimension" }, + actions = function(w,h,d,l) + local rule = outlinerule(w,h,d,l) + setattrlist(rule,true) + context(tonode(rule)) -- will become context.nodes.flush end } @@ -247,8 +302,8 @@ interfaces.implement { type = "mp", name = t.name, } - setfield(rule,"attr",current_attr()) - context(rule) + setattrlist(rule,true) + context(tonode(rule)) end } diff --git a/tex/context/base/mkiv/grph-swf.lua b/tex/context/base/mkiv/grph-swf.lua index 30089cdc4..a9297d48d 100644 --- a/tex/context/base/mkiv/grph-swf.lua +++ b/tex/context/base/mkiv/grph-swf.lua @@ -37,9 +37,10 @@ local function getheader(name) buffer = f:read(20) -- ('*a') end f:close() + -- can be done better now that we have stream readers buffer = { match(buffer,"(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)") } for i=1,9 do - buffer[i] = tobitstring(byte(buffer[i])) + buffer[i] = tobitstring(byte(buffer[i]),8,8) end local framebits = concat(buffer,"",1,9) local n = tonumber(sub(framebits,1,5),2) diff --git a/tex/context/base/mkiv/grph-trf.mkiv b/tex/context/base/mkiv/grph-trf.mkiv index 6bd0e65cc..35e812b3e 100644 --- a/tex/context/base/mkiv/grph-trf.mkiv +++ b/tex/context/base/mkiv/grph-trf.mkiv @@ -146,10 +146,10 @@ \d_grph_scale_ht\ht\nextbox \d_grph_scale_dp\dp\nextbox % - \global\let\finalscaleboxxscale \!!plusone - \global\let\finalscaleboxyscale \!!plusone - \xdef \finalscaleboxwidth {\the\d_grph_scale_wd}% - \xdef \finalscaleboxheight{\the\d_grph_scale_ht}% + \glet\finalscaleboxxscale \!!plusone + \glet\finalscaleboxyscale \!!plusone + \xdef\finalscaleboxwidth {\the\d_grph_scale_wd}% + \xdef\finalscaleboxheight{\the\d_grph_scale_ht}% % \forgetall \dontcomplain @@ -164,11 +164,38 @@ \box\nextbox \egroup} +% \def\grph_scale_apply +% {\d_grph_scale_wd\finalscaleboxxscale\d_grph_scale_wd +% \d_grph_scale_ht\finalscaleboxyscale\d_grph_scale_ht +% \d_grph_scale_dp\finalscaleboxyscale\d_grph_scale_dp +% \setbox\nextbox\hpack +% {\dostartscaling \finalscaleboxxscale \finalscaleboxyscale +% \smashedbox\nextbox +% \dostopscaling}% +% \wd\nextbox\d_grph_scale_wd +% \ht\nextbox\d_grph_scale_ht +% \dp\nextbox\d_grph_scale_dp} + \def\grph_scale_apply {\d_grph_scale_wd\finalscaleboxxscale\d_grph_scale_wd \d_grph_scale_ht\finalscaleboxyscale\d_grph_scale_ht \d_grph_scale_dp\finalscaleboxyscale\d_grph_scale_dp - \setbox\nextbox\hpack + \ifdim\d_grph_scale_wd=\wd\nextbox + \ifdim\d_grph_scale_ht=\ht\nextbox + \ifdim\d_grph_scale_dp=\dp\nextbox + % \grph_scale_apply_nop + \else + \grph_scale_apply_yes + \fi + \else + \grph_scale_apply_yes + \fi + \else + \grph_scale_apply_yes + \fi} + +\def\grph_scale_apply_yes + {\setbox\nextbox\hpack {\dostartscaling \finalscaleboxxscale \finalscaleboxyscale \smashedbox\nextbox \dostopscaling}% @@ -871,7 +898,7 @@ \egroup} \def\grph_rotate_finish_indeed - {\hbox\bgroup + {\hpack\bgroup \ifx\p_rotation_rotation\empty \grph_rotate_finish_nop \else diff --git a/tex/context/base/mkiv/java-imp-exa.mkiv b/tex/context/base/mkiv/java-imp-exa.mkiv deleted file mode 100644 index 584ee1351..000000000 --- a/tex/context/base/mkiv/java-imp-exa.mkiv +++ /dev/null @@ -1,395 +0,0 @@ -%D \module -%D [ file=java-exa, -%D version=2002.??.??, -%D title=\CONTEXT\ JavaScript Macros, -%D subtitle=Example Support, -%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. - -% XFDF versus HTML -% localhost versus remote versus set - -% filename | filename-nr => name -% fakename | fakename-nr => file upload, unless localhost -% -% we erase the list because otherwise we end up in browser remembering -% problems; also, it is not possible to set upload fields 'manually' - -\startJSpreamble request_1 used now - - var example_method = "HTML" ; - var example_host = "" ; - var example_port = "" ; - var example_url = "" ; - var example_file = "" ; - - var example_log = true ; % false - - function stripped_exa_value( name ) { - f = this.getField(name) ; - if (f) { - str = f.value ; - if (str.indexOf(name+'-')==0) { - str = str.substr(name.length+1) ; - } - return str ; - } else { - return "" ; - } - } - - function identify_example_url ( ) { - if (example_log) { - console.clear ; - console.println("base url: "+this.baseURL) ; - console.println("this url: "+this.URL) ; - } - if (this.baseURL != "") { - example_url = this.baseURL ; - } else { - if (this.URL != "") { - example_url = this.URL - } - } - if (example_url.indexOf("file://")>=0) { - example_url = "" ; - } - str = stripped_exa_value("examplehost") ; - if (str != "auto") { - example_host = str ; - if (str == "localhost") { - example_port = "8061" - } - } - str = stripped_exa_value("exampleport") ; - if (str != "auto") { - example_port = str ; - } - if (example_log) { - console.println("example_url: "+example_url) ; - console.println("example_host: "+example_host) ; - console.println("example_port: "+example_port) ; - } - } - - function check_example_url ( url ) { - if (url.indexOf("file://")>=0) { - url = "http://localhost:8061" ; - console.println("file url replaced by: "+url) ; - } else { - if (url.indexOf("://")<0) { - url = "http://" + url ; - } - if (example_log) { - console.println("url before check: "+url) ; - } -% url = url.replace(/(http:\\\/\\\/.+)(\\\/.*$)/, "$1") ; - url = url.replace(/(https*:\\\/\\\/.+?)(\\\/.*$)/, "$1/exarequest") ; - if (example_log) { - console.println("url after check: "+url) ; - } - } - return url ; - } - - function set_example_xfdf ( method ) { - example_method = method ; - } - - function set_example_file ( file ) { - example_method = file ; - } - - function set_example_host ( host ) { - example_host = host ; - } - - function set_example_port ( port ) { - example_host = host ; - } - - function do_erase_example_file(tag) { - f = this.getField(tag) ; - if (f) { - f.value = "" ; - } - } - - function do_erase_example_list(tag) { - for (i=1;i<=100;i++) { - f = this.getField(tag+"-"+i) ; - if (f) { - f.value = "" ; - } else { - return - } - } - } - - function do_submit_example_url ( url ) { - if ((example_method == "XFDF" ) || (url.indexOf("localhost")>=0)) { - do_erase_example_file("fakename") ; - do_erase_example_list("fakename") ; - } - url = check_example_url(url) ; - if (example_log) { - console.println("submitting form to "+url+" using method "+example_method) ; - } - if (example_file != "") { - url = url + "/" + example_file ; - } - % we need the bFDF for acrobat 5 - this.submitForm({cURL : url, bFDF : false, cSubmitAs : example_method}) ; - } - - function submit_example_form ( ) { - identify_example_url() ; - if (example_host != "") { - if (example_port != "") { - do_submit_example_url(example_host+":"+example_port) ; - } else { - do_submit_example_url(example_host) ; - } - } else { - if (example_url != "") { - do_submit_example_url(example_url) ; - } else { - if (example_port != "") { - do_submit_example_url("localhost"+":"+example_port) ; - } else { - do_submit_example_url("localhost:8061") ; % local exampler - } - } - } - resetfilename () ; - } - - function submit_form ( host, port) { - set_example_host(host) ; - set_example_post(post) ; - submit_example_form ; - } - -\stopJSpreamble - -\startJSpreamble request_2 used now - - var exa_command = "" ; - var exa_option = "" ; - var exa_filename = "" ; - var exa_filelist = "" ; - var exa_registered = "" ; - - function set_request (command,option) { - exa_command = command ; - if (exa_command == "") { - exa_option = option ; - } else { if (option == "") { - exa_option = "" ; - } else { if (option.indexOf("--")<0) { - exa_option = "--action=" + option ; - } else { - exa_option = option ; - } } } - } - - function assemble_request ( ) { - v = this.getField('filename') ; - if (v) { - exa_filename = v.value ; - } - v = this.getField('filelist') ; - if (v) { - exa_filelist = v.value ; - } -% exa_filename = exa_filename.replace(/\\\\/g,'/') ; -% exa_filelist = exa_filelist.replace(/\\\\/g,'/') ; - str = "\\n" ; - str = str+"" ; - if (exa_filelist == "") { - exa_filelist = exa_registered ; - } else { if (exa_registered != "") { - exa_filelist = exa_filelist + "\\n" + exa_registered ; - } } - if (exa_command != "") { - str = str+""+exa_command+"" ; - } - if (exa_option != "") { - str = str+""+exa_option+"" ; - } - if (exa_filename != "") { - str = str+""+exa_filename+"" ; - } - var fls = "" ; - if (exa_filelist != "") { - % old method, soon obsolete - lst = exa_filelist.split(/\\s/) ; - for (i=0;i"+lst[i]+"" ; - } - } else { if (exa_multiple) { - for (i=1;i<=100;i++) { - % console.println("file field "+i) ; - f = this.getField("filename-"+ i) ; -% if (f) { if (f.value != "") { -% if (g) { if (g.value == "") { -% fls = fls+""+f.value+"" ; -% } else { -% fls = fls+""+f.value+"" ; -% } } else { -% fls = fls+""+f.value+"" ; -% } -% } } - if (f) { if (f.value != "") { - fls = fls + "" ; - } else { - % console.println("b") ; - fls = fls + " label='" + g.value + "'>" ; - } } else { - % console.println("c") ; - fls = fls + ">" ; - } - fls = fls + f.value + "" ; - } } - } - } } - if (fls != "") { - str = str + "" + fls + "" ; - } - str = str + "" ; - v = this.getField('exa:request') ; - if (v) { - v.value = str ; - } - } - -\stopJSpreamble - -\startJSpreamble request_3 used now - - var exa_multiple = false ; - - function setfilename ( suffixes ) { - if (event.targetName) { - var name = event.targetName ; - var fake = name.replace(/filename/,"fakename") ; - } else { - var name = 'filename' ; - var fake = 'fakename' ; - } - f = this.getField(fake) ; - if (f) { - f.browseForFileToSubmit() ; - if ((suffixes != "") && (f.value != "")) { - % - s = suffixes.replace(/,/g,"|") ; - r = new RegExp() ; - s = "\\\\.(" + s + ")$" ; - r.compile(s, "i") ; - if (f.value.search(r)<=0) { - f.value = "" ; - app.alert('This filetype is not permitted.') ; - % - % lst = suffixes.split(/,/) ; - % ok = false ; - % for (i=0;i=0) { -% f.value = "" ; -% } -% } - } - this.dirty = false ; - } - - function addfilename () { - if (exa_multiple) { - h = this.getField("filelist") ; - g = this.getField("filename") ; - if ((g) && (h)) { - str = g.value ; - if (h.value == "") { - h.value = str ; - } else { - h.value = h.value + "\\n" + str ; - } - g.value = "" ; - this.value = "" ; - } - } - this.dirty = false ; - } - - % this only works with client that assembles request - - function registerfilename (str) { - if (str!="") { - h = this.getField("filelist") ; - if (h) { - if (h.value != "") { - h.value = h.value + "\\n" ; - } - h.value = h.value + str ; - } else { - if (exa_registered != "") { - exa_registered = exa_registered + "\\n" ; - } - exa_registered = exa_registered + str ; - } - } - console.show ; - console.println('registered files') ; - console.println("file: "+str) ; - console.println("list: "+exa_registered) ; - this.dirty = false ; - } - - function checkfilename () { - } - - function getfilename ( suffixes ) { - setfilename(suffixes) ; - checkfilename() ; - addfilename() ; - } - - function resetfilename () { - do_erase_example_file("fakename") ; - do_erase_example_file("filename") ; - do_erase_example_file("filelist") ; - do_erase_example_list("filename") ; - do_erase_example_list("fakename") ; - } - -\stopJSpreamble - -\endinput diff --git a/tex/context/base/mkiv/java-imp-example.mkiv b/tex/context/base/mkiv/java-imp-example.mkiv new file mode 100644 index 000000000..82d5b0cb0 --- /dev/null +++ b/tex/context/base/mkiv/java-imp-example.mkiv @@ -0,0 +1,398 @@ +%D \module +%D [ file=java-imp-example, % was: java-exa +%D version=2002.??.??, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Example Support, +%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. + +%D This code is just kept as an example of dealign with forms and submitting data to +%D a server. We used this to create stepwise growing student test forms and such. + +% XFDF versus HTML +% localhost versus remote versus set + +% filename | filename-nr => name +% fakename | fakename-nr => file upload, unless localhost +% +% we erase the list because otherwise we end up in browser remembering +% problems; also, it is not possible to set upload fields 'manually' + +\startJSpreamble request_1 used now + + var example_method = "HTML" ; + var example_host = "" ; + var example_port = "" ; + var example_url = "" ; + var example_file = "" ; + + var example_log = true ; % false + + function stripped_exa_value( name ) { + f = this.getField(name) ; + if (f) { + str = f.value ; + if (str.indexOf(name+'-')==0) { + str = str.substr(name.length+1) ; + } + return str ; + } else { + return "" ; + } + } + + function identify_example_url ( ) { + if (example_log) { + console.clear ; + console.println("base url: "+this.baseURL) ; + console.println("this url: "+this.URL) ; + } + if (this.baseURL != "") { + example_url = this.baseURL ; + } else { + if (this.URL != "") { + example_url = this.URL + } + } + if (example_url.indexOf("file://")>=0) { + example_url = "" ; + } + str = stripped_exa_value("examplehost") ; + if (str != "auto") { + example_host = str ; + if (str == "localhost") { + example_port = "8061" + } + } + str = stripped_exa_value("exampleport") ; + if (str != "auto") { + example_port = str ; + } + if (example_log) { + console.println("example_url: "+example_url) ; + console.println("example_host: "+example_host) ; + console.println("example_port: "+example_port) ; + } + } + + function check_example_url ( url ) { + if (url.indexOf("file://")>=0) { + url = "http://localhost:8061" ; + console.println("file url replaced by: "+url) ; + } else { + if (url.indexOf("://")<0) { + url = "http://" + url ; + } + if (example_log) { + console.println("url before check: "+url) ; + } +% url = url.replace(/(http:\\\/\\\/.+)(\\\/.*$)/, "$1") ; + url = url.replace(/(https*:\\\/\\\/.+?)(\\\/.*$)/, "$1/exarequest") ; + if (example_log) { + console.println("url after check: "+url) ; + } + } + return url ; + } + + function set_example_xfdf ( method ) { + example_method = method ; + } + + function set_example_file ( file ) { + example_method = file ; + } + + function set_example_host ( host ) { + example_host = host ; + } + + function set_example_port ( port ) { + example_host = host ; + } + + function do_erase_example_file(tag) { + f = this.getField(tag) ; + if (f) { + f.value = "" ; + } + } + + function do_erase_example_list(tag) { + for (i=1;i<=100;i++) { + f = this.getField(tag+"-"+i) ; + if (f) { + f.value = "" ; + } else { + return + } + } + } + + function do_submit_example_url ( url ) { + if ((example_method == "XFDF" ) || (url.indexOf("localhost")>=0)) { + do_erase_example_file("fakename") ; + do_erase_example_list("fakename") ; + } + url = check_example_url(url) ; + if (example_log) { + console.println("submitting form to "+url+" using method "+example_method) ; + } + if (example_file != "") { + url = url + "/" + example_file ; + } + % we need the bFDF for acrobat 5 + this.submitForm({cURL : url, bFDF : false, cSubmitAs : example_method}) ; + } + + function submit_example_form ( ) { + identify_example_url() ; + if (example_host != "") { + if (example_port != "") { + do_submit_example_url(example_host+":"+example_port) ; + } else { + do_submit_example_url(example_host) ; + } + } else { + if (example_url != "") { + do_submit_example_url(example_url) ; + } else { + if (example_port != "") { + do_submit_example_url("localhost"+":"+example_port) ; + } else { + do_submit_example_url("localhost:8061") ; % local exampler + } + } + } + resetfilename () ; + } + + function submit_form ( host, port) { + set_example_host(host) ; + set_example_post(post) ; + submit_example_form ; + } + +\stopJSpreamble + +\startJSpreamble request_2 used now + + var exa_command = "" ; + var exa_option = "" ; + var exa_filename = "" ; + var exa_filelist = "" ; + var exa_registered = "" ; + + function set_request (command,option) { + exa_command = command ; + if (exa_command == "") { + exa_option = option ; + } else { if (option == "") { + exa_option = "" ; + } else { if (option.indexOf("--")<0) { + exa_option = "--action=" + option ; + } else { + exa_option = option ; + } } } + } + + function assemble_request ( ) { + v = this.getField('filename') ; + if (v) { + exa_filename = v.value ; + } + v = this.getField('filelist') ; + if (v) { + exa_filelist = v.value ; + } +% exa_filename = exa_filename.replace(/\\\\/g,'/') ; +% exa_filelist = exa_filelist.replace(/\\\\/g,'/') ; + str = "\\n" ; + str = str+"" ; + if (exa_filelist == "") { + exa_filelist = exa_registered ; + } else { if (exa_registered != "") { + exa_filelist = exa_filelist + "\\n" + exa_registered ; + } } + if (exa_command != "") { + str = str+""+exa_command+"" ; + } + if (exa_option != "") { + str = str+""+exa_option+"" ; + } + if (exa_filename != "") { + str = str+""+exa_filename+"" ; + } + var fls = "" ; + if (exa_filelist != "") { + % old method, soon obsolete + lst = exa_filelist.split(/\\s/) ; + for (i=0;i"+lst[i]+"" ; + } + } else { if (exa_multiple) { + for (i=1;i<=100;i++) { + % console.println("file field "+i) ; + f = this.getField("filename-"+ i) ; +% if (f) { if (f.value != "") { +% if (g) { if (g.value == "") { +% fls = fls+""+f.value+"" ; +% } else { +% fls = fls+""+f.value+"" ; +% } } else { +% fls = fls+""+f.value+"" ; +% } +% } } + if (f) { if (f.value != "") { + fls = fls + "" ; + } else { + % console.println("b") ; + fls = fls + " label='" + g.value + "'>" ; + } } else { + % console.println("c") ; + fls = fls + ">" ; + } + fls = fls + f.value + "" ; + } } + } + } } + if (fls != "") { + str = str + "" + fls + "" ; + } + str = str + "" ; + v = this.getField('exa:request') ; + if (v) { + v.value = str ; + } + } + +\stopJSpreamble + +\startJSpreamble request_3 used now + + var exa_multiple = false ; + + function setfilename ( suffixes ) { + if (event.targetName) { + var name = event.targetName ; + var fake = name.replace(/filename/,"fakename") ; + } else { + var name = 'filename' ; + var fake = 'fakename' ; + } + f = this.getField(fake) ; + if (f) { + f.browseForFileToSubmit() ; + if ((suffixes != "") && (f.value != "")) { + % + s = suffixes.replace(/,/g,"|") ; + r = new RegExp() ; + s = "\\\\.(" + s + ")$" ; + r.compile(s, "i") ; + if (f.value.search(r)<=0) { + f.value = "" ; + app.alert('This filetype is not permitted.') ; + % + % lst = suffixes.split(/,/) ; + % ok = false ; + % for (i=0;i=0) { +% f.value = "" ; +% } +% } + } + this.dirty = false ; + } + + function addfilename () { + if (exa_multiple) { + h = this.getField("filelist") ; + g = this.getField("filename") ; + if ((g) && (h)) { + str = g.value ; + if (h.value == "") { + h.value = str ; + } else { + h.value = h.value + "\\n" + str ; + } + g.value = "" ; + this.value = "" ; + } + } + this.dirty = false ; + } + + % this only works with client that assembles request + + function registerfilename (str) { + if (str!="") { + h = this.getField("filelist") ; + if (h) { + if (h.value != "") { + h.value = h.value + "\\n" ; + } + h.value = h.value + str ; + } else { + if (exa_registered != "") { + exa_registered = exa_registered + "\\n" ; + } + exa_registered = exa_registered + str ; + } + } + console.show ; + console.println('registered files') ; + console.println("file: "+str) ; + console.println("list: "+exa_registered) ; + this.dirty = false ; + } + + function checkfilename () { + } + + function getfilename ( suffixes ) { + setfilename(suffixes) ; + checkfilename() ; + addfilename() ; + } + + function resetfilename () { + do_erase_example_file("fakename") ; + do_erase_example_file("filename") ; + do_erase_example_file("filelist") ; + do_erase_example_list("filename") ; + do_erase_example_list("fakename") ; + } + +\stopJSpreamble + +\endinput diff --git a/tex/context/base/mkiv/java-imp-fields.mkiv b/tex/context/base/mkiv/java-imp-fields.mkiv new file mode 100644 index 000000000..5801c3216 --- /dev/null +++ b/tex/context/base/mkiv/java-imp-fields.mkiv @@ -0,0 +1,648 @@ +%D \module +%D [ file=java-imp-fields, % was java-fld +%D version=1998.05.20, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Field Support, +%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. + +%D In \LUATEX\ the following does not work out well: +%D +%D \starttyping +%D v = v.replace(/\\\\"e/g,"\\353") ; +%D \stoptyping +%D +%D But this does: +%D +%D \starttyping +%D v = String(v).replace(/\\\\"e/g,"\\353") ; +%D \stoptyping +%D +%D Probably a \UNICODE\ issue. Beware, in \MKIV\ we have a +%D different escaping of \type {\\}. +%D +%D Watch out: cf. the latest pdf specification we've changed On into Yes. Also, +%D we've changed the test for the on value into !Off as we dón't know what value it +%D gets in the reader. + +% Is this still okay? We can have unicode now, can't we? Anyway it's kind of +% messy and unneeded in these unicode times. + +\startluasetups javascript:pdfencoding + local ctx_verbatim = context.verbatim + local utfbyte = utf.byte + local sortedhash = table.sortedhash + + ctx_verbatim("{\n") + for accent, group in sortedhash(characters.tex.accentmapping) do + for character, mapping in sortedhash(group) do + if character == "" then + character = " " + end + if accent == '"' then + ctx_verbatim(" '\\\\%s%s' : '\\u%04X',\n",accent,character,utfbyte(mapping)) + else + ctx_verbatim(' "\\\\%s%s" : "\\u%04X",\n',accent,character,utfbyte(mapping)) + end + end + end + for command, mapping in sortedhash(characters.tex.commandmapping) do + ctx_verbatim(' "\\\\%s" : "\\u%04X",\n',command,utfbyte(mapping)) + end + -- ctx_verbatim(" '\\\\<<' : '\\u00AB',\n") + -- ctx_verbatim(" '\\\\>>' : '\\u00BB',\n") + ctx_verbatim("}\n") + +\stopluasetups + +% maybe make { } tex braces in javascript code so that we can call lua + +\def\JavaScriptTeXAccentMapping{\luasetup{javascript:pdfencoding}} + +\startJSpreamble SanitizeTeXInput used later + +var TeXAccentMapping = \JavaScriptTeXAccentMapping + +function TeX_Replacer(original,str) { + return (TeXAccentMapping[str] || str) ; +} + +function Sanitized_TeX_String(value) { + return (value.replace(/(\\..)/g, TeX_Replacer)) ; +} + +var TeX_Key_Mode = 0 ; +var TeX_Key_Char = "" ; + +function Initialize_TeX_Keystroke() { + TeX_Key_Char = "" ; + TeX_Key_Mode = 0 ; +} + +function Sanitized_TeX_Keystroke(change) { + if (!event.willCommit) { + if (change=="\\") { + TeX_Key_Mode = 1 ; + return ("") + } else if (TeX_Key_Mode == 1) { + TeX_Key_Mode = 2 ; + TeX_Key_Char = change ; + return ("") + } else if (TeX_Key_Mode == 2) { + TeX_Key_Mode = 0 ; + TeX_Key_Char = "\\"+TeX_Key_Char+change ; + return (Sanitized_TeX_String(TeX_Key_Char)) + } else { + TeX_Key_Mode = 0 ; + return (change) + } + } +} + +function Initialize_TeX_Key() { + Initialize_TeX_Keystroke() ; +} + +function Convert_TeX_Key() { + if (!event.willCommit) { + event.change = Sanitized_TeX_Keystroke(event.change) ; + } +} + +function Convert_TeX_String() { + event.value = Sanitized_TeX_String(event.value) ; +} + +\stopJSpreamble + +% \startJScode {Initialize_TeX_Key} uses {SanitizeTeXInput} +% Initialize_TeX_Keystroke() ; +% \stopJScode +% +% \startJScode {Convert_TeX_Key} uses {SanitizeTeXInput} +% if (!event.willCommit) { +% event.change = Sanitized_TeX_Keystroke(event.change) ; +% } +% \stopJScode +% +% \startJScode{Convert_TeX_String} uses {SanitizeTeXInput} +% event.value = Sanitized_TeX_String(event.value) ; +% \stopJScode + +% was used now but we autocheck anyway so lets test this for a while + +\startJSpreamble FieldsStates used later + +var visible_field = new Array() ; +var visible_fields = 0 ; + +function PresetFields() { + this.syncAnnotScan() ; +} + +function Preset_Fields() { + this.syncAnnotScan() ; +} + +function Hide_When_Down() { + event.target.hidden = true ; +} + +function Hide_Field(Name) { + var v = this.getField(Name) ; + if (v) { + v.hidden = true ; + v.readonly = true ; + this.dirty = false ; + } +} + +function Do_Vide_Field(Name, Closable) { + var v = this.getField(Name) ; + if (v) { + ++visible_fields ; + visible_field[visible_fields] = Name ; + v.hidden = false ; + if (Closable) { + v.readonly = false ; + v.value = "Yes" ; + } + this.dirty = false ; + } +} + +function Vide_Field(Name) { + Do_Vide_Field(Name,false) ; +} + +function Vide_Hide_Field(Name) { + Do_Vide_Field(Name,true) ; +} + +function Hide_Fields() { + while (visible_fields>0) { + Hide_Field(visible_field[visible_fields]) ; + --visible_fields ; + } +} + +function Vide_Fields(Name) { + Hide_Fields() ; + Vide_Field(Name) ; +} + +function Vide_Hide_Fields(Name) { + Hide_Fields() ; + Vide_Hide_Field(Name) ; +} + +function Toggle_Hide(Name) { + var v = this.getField(Name) ; + if (v) { + v.hidden = !v.hidden ; + this.dirty = false ; + } +} + +function Field_On(Name) { + v = this.getField(Name) ; + if (v) { + v.value = "Yes" ; + this.dirty = false ; + } +} + +function Field_Off(Name) { + var v = this.getField(Name) ; + if (v) { + v.value = "Off" ; + this.dirty = false ; + } +} + +function Toggle_Value(Name) { + var v = this.getField(Name) ; + if (v) { + if (v.value != "Off") { + v.value = "Off" ; + } else { + v.value = "Yes" ; + } + } + this.dirty = false ; +} + +function Toggle_Read(Name) { + var v = this.getField(Name); + if (v) { + v.readonly = !v.readonly ; + } +} + +function Flip_Fields(Name) { + var Names = Name.split(",") ; + for (var i=0; i < Names.length; i++) { + v = this.getField(Names[i]) ; + if (v) { + v.hidden = !v.hidden ; + v.value = "Yes" ; + } + } +} + +function Forget_Changes() { + this.dirty = false ; +} + +function ForgetChanges() { + this.dirty = false ; +} + +function Step_Fields (Name, First, Last) { + for (var i = Number(First) ; i <= Number(Last) ; i++) { + var s = Name + ":" + i ; + var v = this.getField(s) ; + if (v) { + ++visible_fields ; + visible_field[visible_fields] = s ; + if (v.hidden) { + v.hidden = false ; + this.dirty = false ; + return ; + } + } + } +} +\stopJSpreamble + +\definereference[VideFields] [JS(Vide_Fields)] +\definereference[HideFields] [JS(Hide_Fields)] +\definereference[ForgetChanges][JS(Forget_Changes)] +\definereference[StepFields] [JS(Step_Fields)] + +% This can be done more efficient, by keeping track of the +% current top of the stack. + +\startJSpreamble FieldStack used later + +function Field_Name(FieldSet,i) { + return this.getField(FieldSet + ":" + i) +} + +function Reset_Fields(FieldSet) { + var i = 1 ; + while (true) { + var v = Field_Name(FieldSet,i) ; + if (!v) { + break ; + } else { + v.value = "Off" ; + } + i++ ; + } + this.dirty = false ; +} + +function Set_Fields(FieldSet) { + var i = 1 ; + while (true) { + var v = Field_Name(FieldSet,i) ; + if (!v) { + break ; + } else { + v.value = "Yes" ; + } + i++ ; + } + this.dirty = false ; +} + +function Set_Field(FieldSet, FieldName) { + Reset_Fields(FieldSet) ; + var v = Field_Name(FieldSet,FieldName) ; + if (v) { + v.value = "Yes" ; + this.dirty = false ; + } +} + +function Reset_Field(FieldSet, FieldName) { + Set_Fields(FieldSet) ; + var v = Field_Name(FieldSet,FieldName) ; + if (v) { + v.value = "Off" ; + this.dirty = false ; + } +} + +function Walk_Field(FieldSet) { + var i = 1 ; + this.syncAnnotScan(); + while (true) { + var v = Field_Name(FieldSet,i) ; + if (v) { + if (v.value != "Off") { + v.value = "Off" ; + v = Field_Name(FieldSet,i + 1) ; + if (! v) { + v = Field_Name(FieldSet,1) ; + } else { + } + if (v) { + v.value = "Yes" ; + } + break ; + } + i++ ; + } else { + v = Field_Name(FieldSet,1) ; + if (v) { + v.value = "Yes" ; + } + break ; + } + } + this.dirty = false ; +} + +var FieldSets = new Array() ; + +function Do_Get_Check_Walk_Field(FieldSet) { + var f = FieldSets[FieldSet] + if (! f) { + f = new Array() ; + f.number = 0 ; + f.delay = 500 ; + f.paused = false ; + f.running = false ; + f.name = FieldSet ; + f.timeout = null ; + f.repeat = true ; + f.total = 0 ; + f.pauseset = new Array() ; + FieldSets[FieldSet] = f ; + for (var i=1; i>0; i++) { + var v = Field_Name(FieldSet,i) ; + if (! v) { + f.total = i - 1 ; + break ; + } + } + f.start = 0 ; + f.stop = f.total ; + f.pause = 0 ; + } + this.dirty = false ; + return f +} + +function Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,n) { + var v = Field_Name(FieldSet,fieldset.number) ; + if (v) { + if (v.value != "Off") { + v.value = "Off" ; + } + } + v = Field_Name(FieldSet,n) ; + if (v) { + fieldset.number = n ; + v.value = "Yes" ; + if (fieldset.pauseset[n]) { + // fieldset.pause = n ; + // Do_Stop_Auto_Walk_Field(Fieldset) ; + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.paused = true ; + } + } + this.dirty = false ; +} + +function Do_Next_Auto_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + if (fieldset.number >= fieldset.stop) { + if (fieldset.repeat == false) { + fieldset.running = false ; + Do_Stop_Auto_Walk_Field(fieldset) ; + } else { + Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.start) ; + } + } else { + Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.number+1) ; + } + this.dirty = false ; + } +} + +function Do_Stop_Auto_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + try { + app.clearInterval(fieldset.timeout) ; + app.clearTimeOut(fieldset.timeout) ; + } catch (e) { + } + this.dirty = false ; + } +} + +function Do_Start_Auto_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + Do_Stop_Auto_Walk_Field(FieldSet) ; + Do_Next_Auto_Walk_Field(FieldSet) ; + fieldset.timeout = app.setInterval("Do_Next_Auto_Walk_Field('"+FieldSet+"')", fieldset.delay) ; + this.dirty = false ; + } +} + +function Start_Walk_Field(FieldSet, Delay) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + fieldset.number = 0 ; + if (Delay) { + fieldset.delay = Delay ; + } + Reset_Fields(FieldSet) ; + Do_Start_Auto_Walk_Field(FieldSet) ; + fieldset.running = true ; + fieldset.paused = false ; + } +} + +function Pause_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + if (fieldset.running) { + if (fieldset.paused) { + Do_Start_Auto_Walk_Field(FieldSet) ; + fieldset.paused = false ; + } else { + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.paused = true ; + } + } + } +} + +function Start_Pause_Walk_Field(FieldSet, Delay, Option) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + if (Option == "once") { + fieldset.repeat = false ; + } else if (Option == "pause") { + fieldset.repeat = false ; + } else { + fieldset.repeat = true ; + } + if (Option == "pause") { + for (i=3; i 1) { + fieldset.start = fieldset.pause - 1 ; + } else { + fieldset.start = 1 ; + } + fieldset.stop = fieldset.total ; + } else { + var Start = arguments[3] ; + var Stop = arguments[4] ; + if (typeof Start == "string") { + fieldset.start = parseInt(Start) ; + } else if (typeof Start == "number") { + fieldset.start = Start ; + } else { + fieldset.start = 1 ; + } + if (typeof Stop == "string") { + fieldset.stop = parseInt(Stop) ; + } else if (typeof Stop == "number") { + fieldset.stop = Stop ; + } else { + fieldset.stop = fieldset.total ; + } + fieldset.pause = 0 ; + } + if (fieldset.running) { + if (fieldset.paused) { + Do_Start_Auto_Walk_Field(FieldSet) ; + fieldset.paused = false ; + } else { + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.paused = true ; + } + } else { + fieldset.number = fieldset.start - 1 ; + if (Delay) { + fieldset.delay = Delay ; + } + Reset_Fields(FieldSet) ; + Do_Start_Auto_Walk_Field(FieldSet) ; + fieldset.running = true ; + fieldset.paused = false ; + } + } +} + +function Stop_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.running = false ; + fieldset.paused = false ; + } +} + +function Reset_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.number = 0 ; + fieldset.running = false ; + fieldset.paused = false ; + Reset_Fields(FieldSet) ; + } +} + +function Previous_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.running = false ; + fieldset.paused = false ; + if (fieldset.number>0) { + var v = Field_Name(FieldSet,fieldset.number) ; + if (v) { + if (v.value != "Off") { + v.value = "Off" ; + } + } + fieldset.number-- ; + v = Field_Name(FieldSet,fieldset.number) ; + if (v) { + v.value = "Yes" ; + } + this.dirty = false ; + } + } +} + +function Next_Walk_Field(FieldSet) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + Do_Stop_Auto_Walk_Field(FieldSet) ; + fieldset.running = false ; + fieldset.paused = false ; + var f = fieldset.number + 1 ; + var v = Field_Name(FieldSet,f) ; + if (v) { + var v = Field_Name(FieldSet,fieldset.number) ; + if (v) { + if (v.value != "Off") { + v.value = "Off" ; + } + } + fieldset.number++ ; + v = Field_Name(FieldSet,fieldset.number) ; + if (v) { + v.value = "Yes" ; + } + this.dirty = false ; + } + } +} + +function Set_Walk_Field_Delay(FieldSet, Delay) { + var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; + if (fieldset) { + if (Delay) { + fieldset.delay = Delay ; + if (fieldset.running) { + Do_Stop_Auto_Walk_Field(FieldSet) ; + Do_Start_Auto_Walk_Field(FieldSet) ; + } + } + } +} + +\stopJSpreamble + +\definereference[Walk] [JS(Walk_Field)] +\definereference[StartWalk] [JS(Start_Walk_Field)] +\definereference[StopWalk] [JS(Stop_Walk_Field)] +\definereference[PauseWalk] [JS(Pause_Walk_Field)] +\definereference[ResetWalk] [JS(Reset_Walk_Field)] +\definereference[PreviousWalk][JS(Previous_Walk_Field)] +\definereference[NextWalk] [JS(Next_Walk_Field)] +\definereference[SetWalkDelay][JS(Set_Walk_Field_Delay)] + +\endinput diff --git a/tex/context/base/mkiv/java-imp-fil.mkiv b/tex/context/base/mkiv/java-imp-fil.mkiv deleted file mode 100644 index 808950f28..000000000 --- a/tex/context/base/mkiv/java-imp-fil.mkiv +++ /dev/null @@ -1,52 +0,0 @@ -%D \module -%D [ file=java-fil, -%D version=1998.06.01, -%D title=\CONTEXT\ JavaScript Macros, -%D subtitle=Filing and Printing, -%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. - -\startJSpreamble Auxiliary used now - - function DocumentFileName() { - var Paths = this.path.split("/") ; - Paths = Paths[Paths.length-1].split(".") ; - return(Paths[0]) - } - - function Print_Page_Range(From,To) { - if ((Number(From)>0) && (Number(To) >= Number(From))) { - var myFrom = Number(From)-1 ; - var myTo = Number(To)-1 ; - this.print(false,myFrom,myTo,true) ; - } - } - - function Print_This_Page() { - this.print(false,this.pageNum,this.pageNum,true) ; - } - -\stopJSpreamble - -\definereference - [PrintSubPaginas] - [JS(Print_Page_Range{\firstsubpage,\lastsubpage})] - -\definereference - [PrintSubPages] - [JS(Print_Page_Range{\firstsubpage,\lastsubpage})] - -\definereference - [PrintDezePagina] - [JS(Print_This_Page)] - -\definereference - [PrintThisPage] - [JS(Print_This_Page)] - -\endinput diff --git a/tex/context/base/mkiv/java-imp-fld.mkiv b/tex/context/base/mkiv/java-imp-fld.mkiv deleted file mode 100644 index cbd53fffb..000000000 --- a/tex/context/base/mkiv/java-imp-fld.mkiv +++ /dev/null @@ -1,625 +0,0 @@ -%D \module -%D [ file=java-fld, -%D version=1998.05.20, -%D title=\CONTEXT\ JavaScript Macros, -%D subtitle=Field Support, -%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. - -%D In \LUATEX\ the following does not work out well: -%D -%D \starttyping -%D v = v.replace(/\\\\"e/g,"\\353") ; -%D \stoptyping -%D -%D But this does: -%D -%D \starttyping -%D v = String(v).replace(/\\\\"e/g,"\\353") ; -%D \stoptyping -%D -%D Probably a \UNICODE\ issue. Beware, in \MKIV\ we have a -%D different escaping of \type {\\}. -%D -%D Watch out: cf. the latest pdf specification we've changed -%D On into Yes. Also, we've changed the test for the on value -%D into !Off as we dón't know what value it gets in the reader. - -% Is this still okay? We can have unicode now, can't we? Anyway it's kind of -% messy and unneeded in these unicode times. - -\startluasetups javascript:pdfencoding - local ctx_verbatim = context.verbatim - local utfbyte = utf.byte - local sortedhash = table.sortedhash - - ctx_verbatim("{\n") - for accent, group in sortedhash(characters.tex.accentmapping) do - for character, mapping in sortedhash(group) do - if character == "" then - character = " " - end - if accent == '"' then - ctx_verbatim(" '\\\\%s%s' : '\\u%04X',\n",accent,character,utfbyte(mapping)) - else - ctx_verbatim(' "\\\\%s%s" : "\\u%04X",\n',accent,character,utfbyte(mapping)) - end - end - end - for command, mapping in sortedhash(characters.tex.commandmapping) do - ctx_verbatim(' "\\\\%s" : "\\u%04X",\n',command,utfbyte(mapping)) - end - -- ctx_verbatim(" '\\\\<<' : '\\u00AB',\n") - -- ctx_verbatim(" '\\\\>>' : '\\u00BB',\n") - ctx_verbatim("}\n") - -\stopluasetups - -% maybe make { } tex braces in javascript code so that we can call lua - -\def\JavaScriptTeXAccentMapping{\luasetup{javascript:pdfencoding}} - -\startJSpreamble SanitizeTeXInput used later - -var TeXAccentMapping = \JavaScriptTeXAccentMapping - -function TeX_Replacer(original,str) { - return (TeXAccentMapping[str] || str) ; -} - -function Sanitized_TeX_String(value) { - return (value.replace(/(\\..)/g, TeX_Replacer)) ; -} - -var TeX_Key_Mode = 0 ; -var TeX_Key_Char = "" ; - -function Initialize_TeX_Keystroke() { - TeX_Key_Char = "" ; - TeX_Key_Mode = 0 ; -} - -function Sanitized_TeX_Keystroke(change) { - if (!event.willCommit) { - if (change=="\\") { - TeX_Key_Mode = 1 ; - return ("") - } else if (TeX_Key_Mode == 1) { - TeX_Key_Mode = 2 ; - TeX_Key_Char = change ; - return ("") - } else if (TeX_Key_Mode == 2) { - TeX_Key_Mode = 0 ; - TeX_Key_Char = "\\"+TeX_Key_Char+change ; - return (Sanitized_TeX_String(TeX_Key_Char)) - } else { - TeX_Key_Mode = 0 ; - return (change) - } - } -} - -function Initialize_TeX_Key() { - Initialize_TeX_Keystroke() ; -} - -function Convert_TeX_Key() { - if (!event.willCommit) { - event.change = Sanitized_TeX_Keystroke(event.change) ; - } -} - -function Convert_TeX_String() { - event.value = Sanitized_TeX_String(event.value) ; -} - -\stopJSpreamble - -% \startJScode {Initialize_TeX_Key} uses {SanitizeTeXInput} -% Initialize_TeX_Keystroke() ; -% \stopJScode -% -% \startJScode {Convert_TeX_Key} uses {SanitizeTeXInput} -% if (!event.willCommit) { -% event.change = Sanitized_TeX_Keystroke(event.change) ; -% } -% \stopJScode -% -% \startJScode{Convert_TeX_String} uses {SanitizeTeXInput} -% event.value = Sanitized_TeX_String(event.value) ; -% \stopJScode - -% was used now but we autocheck anyway so lets test this for a while - -\startJSpreamble FieldsStates used later - -var visible_field = new Array() ; -var visible_fields = 0 ; - -function PresetFields() { - this.syncAnnotScan() ; -} - -function Preset_Fields() { - this.syncAnnotScan() ; -} - -function Hide_When_Down() { - event.target.hidden = true ; -} - -function Hide_Field(Name) { - var v = this.getField(Name) ; - if (v) { - v.hidden = true ; - v.readonly = true ; - this.dirty = false ; - } -} - -function Do_Vide_Field(Name, Closable) { - var v = this.getField(Name) ; - if (v) { - ++visible_fields ; - visible_field[visible_fields] = Name ; - v.hidden = false ; - if (Closable) { - v.readonly = false ; - v.value = "Yes" ; - } - this.dirty = false ; - } -} - -function Vide_Field(Name) { - Do_Vide_Field(Name,false) ; -} - -function Vide_Hide_Field(Name) { - Do_Vide_Field(Name,true) ; -} - -function Hide_Fields() { - while (visible_fields>0) { - Hide_Field(visible_field[visible_fields]) ; - --visible_fields ; - } -} - -function Vide_Fields(Name) { - Hide_Fields() ; - Vide_Field(Name) ; -} - -function Vide_Hide_Fields(Name) { - Hide_Fields() ; - Vide_Hide_Field(Name) ; -} - -function Toggle_Hide(Name) { - var v = this.getField(Name) ; - if (v) { - v.hidden = !v.hidden ; - this.dirty = false ; - } -} - -function Field_On(Name) { - v = this.getField(Name) ; - if (v) { - v.value = "Yes" ; - this.dirty = false ; - } -} - -function Field_Off(Name) { - var v = this.getField(Name) ; - if (v) { - v.value = "Off" ; - this.dirty = false ; - } -} - -function Toggle_Value(Name) { - var v = this.getField(Name) ; - if (v) { - if (v.value != "Off") { - v.value = "Off" ; - } else { - v.value = "Yes" ; - } - } - this.dirty = false ; -} - -function Toggle_Read(Name) { - var v = this.getField(Name); - if (v) { - v.readonly = !v.readonly ; - } -} - -function Flip_Fields(Name) { - var Names = Name.split(",") ; - for (var i=0; i < Names.length; i++) { - v = this.getField(Names[i]) ; - if (v) { - v.hidden = !v.hidden ; - v.value = "Yes" ; - } - } -} - -function Forget_Changes() { - this.dirty = false ; -} - -function ForgetChanges() { - this.dirty = false ; -} -\stopJSpreamble - -\definereference[ForgetChanges][JS(Forget_Changes)] - -% This can be done more efficient, by keeping track of the -% current top of the stack. - -\startJSpreamble FieldStack used later - -function Field_Name(FieldSet,i) { - return this.getField(FieldSet + ":" + i) -} - -function Reset_Fields(FieldSet) { - var i = 1 ; - while (true) { - v = Field_Name(FieldSet,i) ; - if (!v) { - break ; - } else { - v.value = "Off" ; - } - i++ ; - } - this.dirty = false ; -} - -function Set_Fields(FieldSet) { - var i = 1 ; - while (true) { - v = Field_Name(FieldSet,i) ; - if (!v) { - break ; - } else { - v.value = "Yes" ; - } - i++ ; - } - this.dirty = false ; -} - -function Set_Field(FieldSet, FieldName) { - Reset_Fields(FieldSet) ; - v = Field_Name(FieldSet,FieldName) ; - if (v) { - v.value = "Yes" ; - this.dirty = false ; - } -} - -function Reset_Field(FieldSet, FieldName) { - Set_Fields(FieldSet) ; - v = Field_Name(FieldSet,FieldName) ; - if (v) { - v.value = "Off" ; - this.dirty = false ; - } -} - -function Walk_Field(FieldSet) { - var i = 1 ; - while (true) { - v = Field_Name(FieldSet,i) ; - if (v) { - if (v.value != "Off") { - v.value = "Off" ; - var ii = i ; - ii++ ; - v = Field_Name(FieldSet,ii) ; - if (! v) { - v = Field_Name(FieldSet,1) ; - } - if (v) { - v.value = "Yes" ; - } - break ; - } - i++ ; - } else { - break ; - } - } - this.dirty = false ; -} - -var FieldSets = new Array() ; - -function Do_Get_Check_Walk_Field(FieldSet) { - var f = FieldSets[FieldSet] - if (! f) { - f = new Array() ; - f.number = 0 ; - f.delay = 500 ; - f.paused = false ; - f.running = false ; - f.name = FieldSet ; - f.timeout = null ; - f.repeat = true ; - f.total = 0 ; - f.pauseset = new Array() ; - FieldSets[FieldSet] = f ; - for (var i=1; i>0; i++) { - var v = Field_Name(FieldSet,i) ; - if (! v) { - f.total = i - 1 ; - break ; - } - } - f.start = 0 ; - f.stop = f.total ; - f.pause = 0 ; - } - this.dirty = false ; - return f -} - -function Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,n) { - var v = Field_Name(FieldSet,fieldset.number) ; - if (v) { - if (v.value != "Off") { - v.value = "Off" ; - } - } - v = Field_Name(FieldSet,n) ; - if (v) { - fieldset.number = n ; - v.value = "Yes" ; - if (fieldset.pauseset[n]) { - // fieldset.pause = n ; - // Do_Stop_Auto_Walk_Field(Fieldset) ; - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.paused = true ; - } - } - this.dirty = false ; -} - -function Do_Next_Auto_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - if (fieldset.number >= fieldset.stop) { - if (fieldset.repeat == false) { - fieldset.running = false ; - Do_Stop_Auto_Walk_Field(fieldset) ; - } else { - Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.start) ; - } - } else { - Do_Next_Auto_Walk_Field_Step(FieldSet,fieldset,fieldset.number+1) ; - } - this.dirty = false ; - } -} - -function Do_Stop_Auto_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - try { - app.clearInterval(fieldset.timeout) ; - app.clearTimeOut(fieldset.timeout) ; - } catch (e) { - } - this.dirty = false ; - } -} - -function Do_Start_Auto_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - Do_Stop_Auto_Walk_Field(FieldSet) ; - Do_Next_Auto_Walk_Field(FieldSet) ; - fieldset.timeout = app.setInterval("Do_Next_Auto_Walk_Field('"+FieldSet+"')", fieldset.delay) ; - this.dirty = false ; - } -} - -function Start_Walk_Field(FieldSet, Delay) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - fieldset.number = 0 ; - if (Delay) { - fieldset.delay = Delay ; - } - Reset_Fields(FieldSet) ; - Do_Start_Auto_Walk_Field(FieldSet) ; - fieldset.running = true ; - fieldset.paused = false ; - } -} - -function Pause_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - if (fieldset.running) { - if (fieldset.paused) { - Do_Start_Auto_Walk_Field(FieldSet) ; - fieldset.paused = false ; - } else { - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.paused = true ; - } - } - } -} - -function Start_Pause_Walk_Field(FieldSet, Delay, Option) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - if (Option == "once") { - fieldset.repeat = false ; - } else if (Option == "pause") { - fieldset.repeat = false ; - } else { - fieldset.repeat = true ; - } - if (Option == "pause") { - for (i=3; i 1) { - fieldset.start = fieldset.pause - 1 ; - } else { - fieldset.start = 1 ; - } - fieldset.stop = fieldset.total ; - } else { - var Start = arguments[3] ; - var Stop = arguments[4] ; - if (typeof Start == "string") { - fieldset.start = parseInt(Start) ; - } else if (typeof Start == "number") { - fieldset.start = Start ; - } else { - fieldset.start = 1 ; - } - if (typeof Stop == "string") { - fieldset.stop = parseInt(Stop) ; - } else if (typeof Stop == "number") { - fieldset.stop = Stop ; - } else { - fieldset.stop = fieldset.total ; - } - fieldset.pause = 0 ; - } - if (fieldset.running) { - if (fieldset.paused) { - Do_Start_Auto_Walk_Field(FieldSet) ; - fieldset.paused = false ; - } else { - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.paused = true ; - } - } else { - fieldset.number = fieldset.start - 1 ; - if (Delay) { - fieldset.delay = Delay ; - } - Reset_Fields(FieldSet) ; - Do_Start_Auto_Walk_Field(FieldSet) ; - fieldset.running = true ; - fieldset.paused = false ; - } - } -} - -function Stop_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.running = false ; - fieldset.paused = false ; - } -} - -function Reset_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.number = 0 ; - fieldset.running = false ; - fieldset.paused = false ; - Reset_Fields(FieldSet) ; - } -} - -function Previous_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.running = false ; - fieldset.paused = false ; - if (fieldset.number>0) { - var v = Field_Name(FieldSet,fieldset.number) ; - if (v) { - if (v.value != "Off") { - v.value = "Off" ; - } - } - fieldset.number-- ; - v = Field_Name(FieldSet,fieldset.number) ; - if (v) { - v.value = "Yes" ; - } - this.dirty = false ; - } - } -} - -function Next_Walk_Field(FieldSet) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - Do_Stop_Auto_Walk_Field(FieldSet) ; - fieldset.running = false ; - fieldset.paused = false ; - var f = fieldset.number + 1 ; - var v = Field_Name(FieldSet,f) ; - if (v) { - var v = Field_Name(FieldSet,fieldset.number) ; - if (v) { - if (v.value != "Off") { - v.value = "Off" ; - } - } - fieldset.number++ ; - v = Field_Name(FieldSet,fieldset.number) ; - if (v) { - v.value = "Yes" ; - } - this.dirty = false ; - } - } -} - -function Set_Walk_Field_Delay(FieldSet, Delay) { - var fieldset = Do_Get_Check_Walk_Field(FieldSet) ; - if (fieldset) { - if (Delay) { - fieldset.delay = Delay ; - if (fieldset.running) { - Do_Stop_Auto_Walk_Field(FieldSet) ; - Do_Start_Auto_Walk_Field(FieldSet) ; - } - } - } -} - -\stopJSpreamble - -\definereference[Walk] [JS(Walk_Field)] -\definereference[StartWalk] [JS(Start_Walk_Field)] -\definereference[StopWalk] [JS(Stop_Walk_Field)] -\definereference[PauseWalk] [JS(Pause_Walk_Field)] -\definereference[ResetWalk] [JS(Reset_Walk_Field)] -\definereference[PreviousWalk][JS(Previous_Walk_Field)] -\definereference[NextWalk] [JS(Next_Walk_Field)] -\definereference[SetWalkDelay][JS(Set_Walk_Field_Delay)] - -\endinput diff --git a/tex/context/base/mkiv/java-imp-highlight.mkiv b/tex/context/base/mkiv/java-imp-highlight.mkiv new file mode 100644 index 000000000..b55628f4b --- /dev/null +++ b/tex/context/base/mkiv/java-imp-highlight.mkiv @@ -0,0 +1,34 @@ +%D \module +%D [ file=java-imp-highlightm, % was: java-rhh +%D version=2010.02.01, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Runtime Highlight Hack, +%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. + +%D As hightlighting is rather intrusive it makes sense to turn it off when +%D using nice appearances. + +% app.runtimeHighlightColor = [ "T" ] ; +% +% var SavedAlwaysShowFocus = app.alwaysShowFocus ; +% app.alwaysShowFocus = true ; +% "app.alwaysShowFocus = SavedAlwaysShowFocus ; " + +\startJSpreamble RuntimeHighlightHack used now + var SavedHighlightState = app.runtimeHighlight ; + var SavedFocusRectState = app.focusRect ; + app.runtimeHighlight = false ; + app.focusRect = true ; + this.setAction("WillClose", + "app.runtimeHighlight = SavedHighlightState ; " + + "app.focusRect = SavedFocusRectState ; " + ) ; +\stopJSpreamble + +\endinput diff --git a/tex/context/base/mkiv/java-imp-print.mkiv b/tex/context/base/mkiv/java-imp-print.mkiv new file mode 100644 index 000000000..3d5325ff0 --- /dev/null +++ b/tex/context/base/mkiv/java-imp-print.mkiv @@ -0,0 +1,52 @@ +%D \module +%D [ file=java-imp-print, % was: java-fil +%D version=1998.06.01, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Filing and Printing, +%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. + +\startJSpreamble auxiliary used now + + function DocumentFileName() { + var Paths = this.path.split("/") ; + Paths = Paths[Paths.length-1].split(".") ; + return(Paths[0]) + } + + function Print_Page_Range(From,To) { + if ((Number(From)>0) && (Number(To) >= Number(From))) { + var myFrom = Number(From)-1 ; + var myTo = Number(To)-1 ; + this.print(false,myFrom,myTo,true) ; + } + } + + function Print_This_Page() { + this.print(false,this.pageNum,this.pageNum,true) ; + } + +\stopJSpreamble + +\definereference + [PrintSubPaginas] + [JS(Print_Page_Range{\firstsubpage,\lastsubpage})] + +\definereference + [PrintSubPages] + [JS(Print_Page_Range{\firstsubpage,\lastsubpage})] + +\definereference + [PrintDezePagina] + [JS(Print_This_Page)] + +\definereference + [PrintThisPage] + [JS(Print_This_Page)] + +\endinput diff --git a/tex/context/base/mkiv/java-imp-rhh.mkiv b/tex/context/base/mkiv/java-imp-rhh.mkiv deleted file mode 100644 index 5f057f550..000000000 --- a/tex/context/base/mkiv/java-imp-rhh.mkiv +++ /dev/null @@ -1,34 +0,0 @@ -%D \module -%D [ file=java-rhh, -%D version=2010.02.01, -%D title=\CONTEXT\ JavaScript Macros, -%D subtitle=Runtime Highlight Hack, -%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. - -%D As hightlighting is rather intrusive it makes sense to turn it off when -%D using nice appearances. - -% app.runtimeHighlightColor = [ "T" ] ; -% -% var SavedAlwaysShowFocus = app.alwaysShowFocus ; -% app.alwaysShowFocus = true ; -% "app.alwaysShowFocus = SavedAlwaysShowFocus ; " - -\startJSpreamble RuntimeHighlightHack used now - var SavedHighlightState = app.runtimeHighlight ; - var SavedFocusRectState = app.focusRect ; - app.runtimeHighlight = false ; - app.focusRect = true ; - this.setAction("WillClose", - "app.runtimeHighlight = SavedHighlightState ; " + - "app.focusRect = SavedFocusRectState ; " - ) ; -\stopJSpreamble - -\endinput diff --git a/tex/context/base/mkiv/java-imp-steps.mkiv b/tex/context/base/mkiv/java-imp-steps.mkiv new file mode 100644 index 000000000..3990e4d7a --- /dev/null +++ b/tex/context/base/mkiv/java-imp-steps.mkiv @@ -0,0 +1,123 @@ +%D \module +%D [ file=java-imp-steps, % was: java-stp +%D version=2004.03.15, +%D title=\CONTEXT\ JavaScript Macros, +%D subtitle=Stepping, +%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. + +% we define ocglist global, otherwise we quickly run into a memory hog (even +% out of memory in a 512 Meg machine) + +% we cannot use doc_visited[this.pageNum] instead of doc_currentstep because +% of some funny side effect (i.e. dup or so) + +% todo: test with later as we do autoinsert now + +\startJSpreamble Steps used now + +var doc_ocglist = this.getOCGs() ; +var doc_stepname = "step" ; +var doc_currentstep = 0 ; +var doc_maxstep = 50 ; +var doc_visited = new Array() ; +var doc_busy = new Array() ; + +function SetupStepper(layername,laststep) { + doc_stepname = layername ; + doc_maxstep = laststep ; + for (var i=0; i<=this.numPages; i++) { + doc_visited[i] = 0 ; + doc_busy[i] = 0 ; + } +} + +for (var i=0; i<=this.numPages; i++) { + doc_visited[i] = 0 ; + doc_busy[i] = 0 ; +} + +function GetOCG(name) { + for (var i=0; i < doc_ocglist.length; i++) { + if (doc_ocglist[i].name == name) { + return doc_ocglist[i] ; + } + } + return null ; +} + +function CheckBusy() { + var ocg = GetOCG("step:busy") ; + if (ocg != null) { + if (doc_visited[this.pageNum]==0) { + ocg.state = true ; + } else { + if (doc_visited[this.pageNum]= first and b <= last - end - -- tricky, these nested captures - return utf8byte / f -- nil when invalid range - end -end - --- print(lpeg.match(lpeg.Cs((C(lpeg.UR("αω"))/{ ["χ"] = "OEPS" })^0),"αωχαω")) - -- lpeg.print(lpeg.R("ab","cd","gh")) -- lpeg.print(lpeg.P("a","b","c")) -- lpeg.print(lpeg.S("a","b","c")) @@ -944,7 +888,7 @@ local function make2(t,rest) -- only ascii return p end -function lpeg.utfchartabletopattern(list,insensitive) -- goes to util-lpg +local function utfchartabletopattern(list,insensitive) -- goes to util-lpg local tree = { } local n = #list if n == 0 then @@ -1022,6 +966,15 @@ function lpeg.utfchartabletopattern(list,insensitive) -- goes to util-lpg return (insensitive and make2 or make1)(tree) end +lpeg.utfchartabletopattern = utfchartabletopattern + +function lpeg.utfreplacer(list,insensitive) + local pattern = Cs((utfchartabletopattern(list,insensitive)/list + utf8character)^0) + return function(str) + return lpegmatch(pattern,str) or str + end +end + -- local t = { "start", "stoep", "staart", "paard" } -- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1) @@ -1119,25 +1072,38 @@ end -- moved here (before util-str) ------ digit = R("09") ------ period = P(".") ------ zero = P("0") -local trailingzeros = zero^0 * -digit -- suggested by Roberto R -local case_1 = period * trailingzeros / "" -local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "") -local number = digits * (case_1 + case_2) -local stripper = Cs((number + 1)^0) +do + + local trailingzeros = zero^0 * -digit -- suggested by Roberto + local stripper = Cs(( + digits * ( + period * trailingzeros / "" + + period * (digit - trailingzeros)^1 * (trailingzeros / "") + ) + 1 + )^0) -lpeg.patterns.stripzeros = stripper + lpeg.patterns.stripzeros = stripper -- multiple in string --- local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100" --- collectgarbage("collect") --- str = string.rep(sample,10000) --- local ts = os.clock() --- lpegmatch(stripper,str) --- print(#str, os.clock()-ts, lpegmatch(stripper,sample)) + local nonzero = digit - zero + local trailingzeros = zero^1 * endofstring + local stripper = Cs( (1-period)^0 * ( + period * trailingzeros/"" + + period * (nonzero^1 + (trailingzeros/"") + zero^1)^0 + + endofstring + )) + + lpeg.patterns.stripzero = stripper -- slightly more efficient but expects a float ! + + -- local sample = "bla 11.00 bla 11 bla 0.1100 bla 1.00100 bla 0.00 bla 0.001 bla 1.1100 bla 0.100100100 bla 0.00100100100" + -- collectgarbage("collect") + -- str = string.rep(sample,10000) + -- local ts = os.clock() + -- lpegmatch(stripper,str) + -- print(#str, os.clock()-ts, lpegmatch(stripper,sample)) + +end --- for practical reasone we keep this here: +-- for practical reasons we keep this here: local byte_to_HEX = { } local byte_to_hex = { } @@ -1209,3 +1175,22 @@ end -- local h = "ADFE0345" -- local b = lpegmatch(patterns.hextobytes,h) -- print(h,b,string.tohex(b),string.toHEX(b)) + +local patterns = { } -- can be made weak + +local function containsws(what) + local p = patterns[what] + if not p then + local p1 = P(what) * (whitespace + endofstring) * Cc(true) + local p2 = whitespace * P(p1) + p = P(p1) + P(1-p2)^0 * p2 + Cc(false) + patterns[what] = p + end + return p +end + +lpeg.containsws = containsws + +function string.containsws(str,what) + return lpegmatch(patterns[what] or containsws(what),str) +end diff --git a/tex/context/base/mkiv/l-lua.lua b/tex/context/base/mkiv/l-lua.lua index 426706f06..d8989364e 100644 --- a/tex/context/base/mkiv/l-lua.lua +++ b/tex/context/base/mkiv/l-lua.lua @@ -35,8 +35,6 @@ if LUAVERSION < 5.2 and jit then LUAVERSION = 5.2 end -_LUAVERSION = LUAVERSION -- for old times sake, will go away - -- lpeg if not lpeg then @@ -230,23 +228,27 @@ elseif not ffi.number then ffi.number = tonumber end -if not bit32 then -- and utf8 then - -- bit32 = load ( [[ -- replacement code with 5.3 syntax so that 5.2 doesn't bark on it ]] ) - bit32 = require("l-bit32") -end +-- if not bit32 then -- and utf8 then +-- -- bit32 = load ( [[ -- replacement code with 5.3 syntax so that 5.2 doesn't bark on it ]] ) +-- bit32 = require("l-bit32") +-- end -- We need this due a bug in luatex socket loading: -local loaded = package.loaded - -if not loaded["socket"] then loaded["socket"] = loaded["socket.core"] end -if not loaded["mime"] then loaded["mime"] = loaded["mime.core"] end - -if not socket.mime then socket.mime = package.loaded["mime"] end - -if not loaded["socket.mime"] then loaded["socket.mime"] = socket.mime end -if not loaded["socket.http"] then loaded["socket.http"] = socket.http end -if not loaded["socket.ftp"] then loaded["socket.ftp"] = socket.ftp end -if not loaded["socket.smtp"] then loaded["socket.smtp"] = socket.smtp end -if not loaded["socket.tp"] then loaded["socket.tp"] = socket.tp end -if not loaded["socket.url"] then loaded["socket.url"] = socket.url end +-- local loaded = package.loaded +-- +-- if not loaded["socket"] then loaded["socket"] = loaded["socket.core"] end +-- if not loaded["mime"] then loaded["mime"] = loaded["mime.core"] end +-- +-- if not socket.mime then socket.mime = package.loaded["mime"] end +-- +-- if not loaded["socket.mime"] then loaded["socket.mime"] = socket.mime end +-- if not loaded["socket.http"] then loaded["socket.http"] = socket.http end +-- if not loaded["socket.ftp"] then loaded["socket.ftp"] = socket.ftp end +-- if not loaded["socket.smtp"] then loaded["socket.smtp"] = socket.smtp end +-- if not loaded["socket.tp"] then loaded["socket.tp"] = socket.tp end +-- if not loaded["socket.url"] then loaded["socket.url"] = socket.url end + +if LUAVERSION > 5.3 then + collectgarbage("generational") +end diff --git a/tex/context/base/mkiv/l-macro-imp-optimize.lua b/tex/context/base/mkiv/l-macro-imp-optimize.lua index e04b37eab..7d7fafefd 100644 --- a/tex/context/base/mkiv/l-macro-imp-optimize.lua +++ b/tex/context/base/mkiv/l-macro-imp-optimize.lua @@ -46,17 +46,22 @@ if LUAVERSION >= 5.3 and lua.macros then -- #define rshift(a,b) ((a >> b) & 0xFFFFFFFF) -- ]] - lua.macros.resolvestring [[ - #define band(a,b) (a&b) - #define bnot(a) (~a&0xFFFFFFFF) - #define bor(a,b) ((a|b)&0xFFFFFFFF) - #define btest(a,b) ((a&b)~=0) - #define bxor(a,b) ((a~b)&0xFFFFFFFF) - #define rshift(a,b) ((a&b)~=0) - #define extract(a,b,c) ((a>>b)&~(-1<>b)&0x1)) - #define lshift(a,b) ((a<>b)&0xFFFFFFFF) - ]] +lua.macros.resolvestring [[ +#define band(a,b) ((a)&(b)) +#define bnot(a) (~(a)&0xFFFFFFFF) +#define bor(a,b) (((a)|(b))&0xFFFFFFFF) +#define btest(a,b) (((a)&(b))~=0) +#define bxor(a,b) (((a)~(b))&0xFFFFFFFF) +#define rshift(a,b) (((a)&(b))~=0) +#define extract(a,b,c) (((a)>>(b))&~(-1<<(c))) +#define extract(a,b) (((a)>>(b))&0x1) +#define extract1(a,b) ((a >> b) & 0x01) +#define extract2(a,b) ((a >> b) & 0x03) +#define extract4(a,b) ((a >> b) & 0x0F) +#define lshift(a,b) (((a)<<(b))&0xFFFFFFFF) +#define rshift(a,b) (((a)>>(b))&0xFFFFFFFF) +#define intdiv(a,b) ((a)//(b)) +#define idiv(a,b) ((a)//(b)) +]] end diff --git a/tex/context/base/mkiv/l-macro.lua b/tex/context/base/mkiv/l-macro.lua index 30c7cbec6..24a3d07bc 100644 --- a/tex/context/base/mkiv/l-macro.lua +++ b/tex/context/base/mkiv/l-macro.lua @@ -14,14 +14,16 @@ if not modules then modules = { } end modules ['l-macros'] = { local S, P, R, V, C, Cs, Cc, Ct, Carg = lpeg.S, lpeg.P, lpeg.R, lpeg.V, lpeg.C, lpeg.Cs, lpeg.Cc, lpeg.Ct, lpeg.Carg local lpegmatch = lpeg.match local concat = table.concat -local format, sub = string.format, string.sub +local format, sub, match = string.format, string.sub, string.match local next, load, type = next, load, type local newline = S("\n\r")^1 local continue = P("\\") * newline +local whitespace = S(" \t\n\r") local spaces = S(" \t") + continue -local name = R("az","AZ","__","09")^1 -local body = ((1+continue/"")-newline)^1 +local nametoken = R("az","AZ","__","09") +local name = nametoken^1 +local body = ((continue/"" + 1) - newline)^1 local lparent = P("(") local rparent = P(")") local noparent = 1 - (lparent + rparent) @@ -53,7 +55,9 @@ end -- todo: zero case -resolve = C(C(name) * arguments^-1) / function(raw,s,a) +local safeguard = P("local") * whitespace^1 * name * (whitespace + P("=")) + +resolve = safeguard + C(C(name) * (arguments^-1)) / function(raw,s,a) local d = definitions[s] if d then if a then @@ -85,7 +89,7 @@ subparser = Cs((resolve + P(1))^1) local enddefine = P("#enddefine") / "" -local beginregister = (C(name) * spaces^0 * (arguments + Cc(false)) * C((1-enddefine)^1) * enddefine) / function(k,a,v) +local beginregister = (C(name) * (arguments + Cc(false)) * C((1-enddefine)^1) * enddefine) / function(k,a,v) local n = 0 if a then n = #a @@ -103,14 +107,14 @@ local beginregister = (C(name) * spaces^0 * (arguments + Cc(false)) * C((1-endde end local d = definitions[k] if not d then - d = { [0] = false, false, false, false, false, false, false, false, false } + d = { a = a, [0] = false, false, false, false, false, false, false, false, false } definitions[k] = d end d[n] = lpegmatch(subparser,v) or v return "" end -local register = (C(name) * spaces^0 * (arguments + Cc(false)) * spaces^0 * C(body)) / function(k,a,v) +local register = (Cs(name) * (arguments + Cc(false)) * spaces^0 * Cs(body)) / function(k,a,v) local n = 0 if a then n = #a @@ -128,7 +132,7 @@ local register = (C(name) * spaces^0 * (arguments + Cc(false)) * spaces^0 * C(bo end local d = definitions[k] if not d then - d = { [0] = false, false, false, false, false, false, false, false, false } + d = { a = a, [0] = false, false, false, false, false, false, false, false, false } definitions[k] = d end d[n] = lpegmatch(subparser,v) or v @@ -162,6 +166,25 @@ function macros.reset() patterns = { } end +function macros.showdefinitions() + -- no helpers loaded but not called early + for name, list in table.sortedhash(definitions) do + local arguments = list.a + if arguments then + arguments = "(" .. concat(arguments,",") .. ")" + else + arguments = "" + end + print("macro: " .. name .. arguments) + for i=0,#list do + local l = list[i] + if l then + print(" " .. l) + end + end + end +end + function macros.resolvestring(str) return lpegmatch(parser,str) or str end @@ -170,6 +193,51 @@ function macros.resolving() return next(patterns) end +local function reload(path,name,data) + local only = match(name,".-([^/]+)%.lua") + if only and only ~= "" then + local name = path .. "/" .. only + local f = io.open(name,"wb") + f:write(data) + f:close() + local f = loadfile(name) + os.remove(name) + return f + end +end + +-- local function reload(path,name,data) +-- if path and path ~= "" then +-- local only = file.nameonly(name) .. "-macro.lua" +-- local name = file.join(path,only) +-- io.savedata(name,data) +-- local l = loadfile(name) +-- os.remove(name) +-- return l +-- end +-- return load(data,name) +-- end +-- +-- assumes no helpers + +local function reload(path,name,data) + if path and path ~= "" then + local only = string.match(name,".-([^/]+)%.lua") + if only and only ~= "" then + local name = path .. "/" .. only .. "-macro.lua" + local f = io.open(name,"wb") + if f then + f:write(data) + f:close() + local l = loadfile(name) + os.remove(name) + return l + end + end + end + return load(data,name) +end + local function loaded(name,trace,detail) -- local c = io.loaddata(fullname) -- not yet available local f = io.open(name,"rb") @@ -194,12 +262,11 @@ local function loaded(name,trace,detail) report_lua("no macros expanded in '%s'",name) end end - if #name > 30 then - n = "--[[" .. sub(name,-30) .. "]] " .. n - else - n = "--[[" .. name .. "]] " .. n - end - return load(n) + -- if #name > 30 then + -- name = sub(name,-30) + -- end + -- n = "--[[" .. name .. "]]\n" .. n + return reload(lfs and lfs.currentdir(),name,n) end macros.loaded = loaded diff --git a/tex/context/base/mkiv/l-number.lua b/tex/context/base/mkiv/l-number.lua index a83e8f8f9..9fd2f82f7 100644 --- a/tex/context/base/mkiv/l-number.lua +++ b/tex/context/base/mkiv/l-number.lua @@ -81,13 +81,14 @@ if bit32 then "0", "0", "0", "0", "0", "0", "0", "0", } - function number.tobitstring(b,m) - -- if really needed we can speed this one up - -- because small numbers need less extraction - local n = 32 - for i=0,31 do + function number.tobitstring(b,m,w) + if not w then + w = 32 + end + local n = w + for i=0,w-1 do local v = bextract(b,i) - local k = 32 - i + local k = w - i if v == 1 then n = k t[k] = "1" @@ -95,12 +96,14 @@ if bit32 then t[k] = "0" end end - if m then + if w then + return concat(t,"",1,w) + elseif m then m = 33 - m * 8 if m < 1 then m = 1 end - return concat(t,"",m) + return concat(t,"",1,m) elseif n < 8 then return concat(t) elseif n < 16 then @@ -232,3 +235,7 @@ function number.decimaltobyte(d) return b end end + +function number.idiv(i,d) + return floor(i/d) -- i//d in 5.3 +end diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua index 9b54c9840..cf469f79d 100644 --- a/tex/context/base/mkiv/l-os.lua +++ b/tex/context/base/mkiv/l-os.lua @@ -32,11 +32,78 @@ 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 --- The following code permits traversing the environment table, at least --- in luatex. Internally all environment names are uppercase. +-- This check needs to happen real early on. Todo: we can pick it up from the commandline +-- if we pass --binpath= (which is useful anyway) + +do + local selfdir = os.selfdir + if selfdir == "" then + selfdir = nil + end + if not selfdir then + -- We need a fallback plan so let's see what we get. + if arg then + -- passed by mtx-context ... saves network access + for i=1,#arg do + local a = arg[i] + if find(a,"^%-%-[c:]*texmfbinpath=") then + selfdir = gsub(a,"^.-=","") + break + end + end + end + if not selfdir then + selfdir = os.selfbin or "luatex" + if find(selfdir,"[/\\]") then + selfdir = gsub(selfdir,"[/\\][^/\\]*$","") + elseif os.getenv then + local path = os.getenv("PATH") + local name = gsub(selfdir,"^.*[/\\][^/\\]","") + local patt = "[^:]+" + if os.type == "windows" then + patt = "[^;]+" + name = name .. ".exe" + end + local isfile + if lfs then + -- we're okay as lfs is assumed present + local attributes = lfs.attributes + isfile = function(name) + local a = attributes(name,"mode") + return a == "file" or a == "link" or nil + end + else + -- we're not okay and much will not work as we miss lfs + local open = io.open + isfile = function(name) + local f = open(name) + if f then + f:close() + return true + end + end + end + for p in gmatch(path,patt) do + -- possible speedup: there must be tex in 'p' + if isfile(p .. "/" .. name) then + selfdir = p + break + end + end + end + end + -- let's hope we're okay now + os.selfdir = selfdir or "." + end +end +-- print(os.selfdir) os.exit() + +-- 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. +-- as the binary (Luatex is normally okay). But to be sure we set the seed anyway. It will be better +-- in Lua 5.4 (according to the announcements.) math.initialseed = tonumber(string.sub(string.reverse(tostring(ceil(socket and socket.gettime()*10000 or time()))),1,6)) @@ -156,7 +223,7 @@ end local launchers = { windows = "start %s", macosx = "open %s", - unix = "$BROWSER %s &> /dev/null &", + unix = "xdg-open %s &> /dev/null &", } function os.launch(str) @@ -223,6 +290,13 @@ local name, platform = os.name or "linux", os.getenv("MTX_PLATFORM") or "" -- os.bits = 32 | 64 +-- os.uname() +-- sysname +-- machine +-- release +-- version +-- nodename + if platform ~= "" then os.platform = platform @@ -234,10 +308,12 @@ elseif os.type == "windows" then -- PROCESSOR_ARCHITECTURE : binary platform -- PROCESSOR_ARCHITEW6432 : OS platform + -- mswin-64 is now win64 + function resolvers.platform(t,k) - local platform, architecture = "", os.getenv("PROCESSOR_ARCHITECTURE") or "" + local architecture = os.getenv("PROCESSOR_ARCHITECTURE") or "" + local platform = "" if find(architecture,"AMD64",1,true) then - -- platform = "mswin-64" platform = "win64" else platform = "mswin" @@ -251,13 +327,17 @@ elseif name == "linux" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first - local platform, architecture = "", os.getenv("HOSTTYPE") or resultof("uname -m") or "" - if find(architecture,"x86_64",1,true) then - platform = "linux-64" + local architecture = os.getenv("HOSTTYPE") or resultof("uname -m") or "" + local platform = os.getenv("MTX_PLATFORM") or "" + local musl = find(os.selfdir or "","linuxmusl") + if platform ~= "" then + -- we're done + elseif find(architecture,"x86_64",1,true) then + platform = musl and "linuxmusl" or "linux-64" elseif find(architecture,"ppc",1,true) then platform = "linux-ppc" else - platform = "linux" + platform = musl and "linuxmusl" or "linux" end os.setenv("MTX_PLATFORM",platform) os.platform = platform @@ -277,11 +357,13 @@ elseif name == "macosx" then ]]-- function resolvers.platform(t,k) - -- local platform, architecture = "", os.getenv("HOSTTYPE") or "" + -- local platform = "" + -- local architecture = os.getenv("HOSTTYPE") or "" -- if architecture == "" then -- architecture = resultof("echo $HOSTTYPE") or "" -- end - local platform, architecture = "", resultof("echo $HOSTTYPE") or "" + local architecture = resultof("echo $HOSTTYPE") or "" + local platform = "" if architecture == "" then -- print("\nI have no clue what kind of OSX you're running so let's assume an 32 bit intel.\n") platform = "osx-intel" @@ -300,7 +382,8 @@ elseif name == "macosx" then elseif name == "sunos" then function resolvers.platform(t,k) - local platform, architecture = "", resultof("uname -m") or "" + local architecture = resultof("uname -m") or "" + local platform = "" if find(architecture,"sparc",1,true) then platform = "solaris-sparc" else -- if architecture == 'i86pc' @@ -314,7 +397,8 @@ elseif name == "sunos" then elseif name == "freebsd" then function resolvers.platform(t,k) - local platform, architecture = "", resultof("uname -m") or "" + local architecture = resultof("uname -m") or "" + local platform = "" if find(architecture,"amd64",1,true) then platform = "freebsd-amd64" else @@ -329,7 +413,8 @@ elseif name == "kfreebsd" then function resolvers.platform(t,k) -- we sometimes have HOSTTYPE set so let's check that first - local platform, architecture = "", os.getenv("HOSTTYPE") or resultof("uname -m") or "" + local architecture = os.getenv("HOSTTYPE") or resultof("uname -m") or "" + local platform = "" if find(architecture,"x86_64",1,true) then platform = "kfreebsd-amd64" else @@ -564,3 +649,20 @@ function os.validdate(year,month,day) end return year, month, day end + +local osexit = os.exit +local exitcode = nil + +function os.setexitcode(code) + exitcode = code +end + +function os.exit(c) + if exitcode ~= nil then + return osexit(exitcode) + end + if c ~= nil then + return osexit(c) + end + return osexit() +end diff --git a/tex/context/base/mkiv/l-package.lua b/tex/context/base/mkiv/l-package.lua index 4faee76bf..0dd71e5ec 100644 --- a/tex/context/base/mkiv/l-package.lua +++ b/tex/context/base/mkiv/l-package.lua @@ -394,3 +394,7 @@ end -- front .. table.insert(searchers,1,helpers.loaded) + +if context then + package.path = "" +end diff --git a/tex/context/base/mkiv/l-sandbox.lua b/tex/context/base/mkiv/l-sandbox.lua index 2ecec0023..c2e1753d3 100644 --- a/tex/context/base/mkiv/l-sandbox.lua +++ b/tex/context/base/mkiv/l-sandbox.lua @@ -190,6 +190,9 @@ end function sandbox.enable() if not sandboxed then + debug = { + traceback = debug.traceback, + } for i=1,#initializers do initializers[i].action() end diff --git a/tex/context/base/mkiv/l-sha.lua b/tex/context/base/mkiv/l-sha.lua new file mode 100644 index 000000000..8481f7f45 --- /dev/null +++ b/tex/context/base/mkiv/l-sha.lua @@ -0,0 +1,27 @@ +if not modules then modules = { } end modules ['l-sha'] = { + 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" +} + +if sha2 then + + local lpegmatch = lpeg.match + local lpegpatterns = lpeg.patterns + local bytestohex = lpegpatterns.bytestohex + local bytestoHEX = lpegpatterns.bytestoHEX + + local digest256 = sha2.digest256 + local digest384 = sha2.digest384 + local digest512 = sha2.digest512 + + sha2.hash256 = function(str) return lpegmatch(bytestohex,digest256(str)) end + sha2.hash384 = function(str) return lpegmatch(bytestohex,digest384(str)) end + sha2.hash512 = function(str) return lpegmatch(bytestohex,digest512(str)) end + sha2.HASH256 = function(str) return lpegmatch(bytestoHEX,digest256(str)) end + sha2.HASH384 = function(str) return lpegmatch(bytestoHEX,digest384(str)) end + sha2.HASH512 = function(str) return lpegmatch(bytestoHEX,digest512(str)) end + +end diff --git a/tex/context/base/mkiv/l-table.lua b/tex/context/base/mkiv/l-table.lua index 5cd65dd67..57130a50d 100644 --- a/tex/context/base/mkiv/l-table.lua +++ b/tex/context/base/mkiv/l-table.lua @@ -8,10 +8,9 @@ if not modules then modules = { } end modules ['l-table'] = { local type, next, tostring, tonumber, select = type, next, tostring, tonumber, select local table, string = table, string -local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove +local concat, sort = table.concat, table.sort local format, lower, dump = string.format, string.lower, string.dump local getmetatable, setmetatable = getmetatable, setmetatable -local getinfo = debug.getinfo local lpegmatch, patterns = lpeg.match, lpeg.patterns local floor = math.floor @@ -27,7 +26,8 @@ function table.getn(t) end function table.strip(tab) - local lst, l = { }, 0 + local lst = { } + local l = 0 for i=1,#tab do local s = lpegmatch(stripper,tab[i]) or "" if s == "" then @@ -42,7 +42,8 @@ end function table.keys(t) if t then - local keys, k = { }, 0 + local keys = { } + local k = 0 for key in next, t do k = k + 1 keys[k] = key @@ -146,7 +147,9 @@ end local function sortedkeys(tab) if tab then - local srt, category, s = { }, 0, 0 -- 0=unknown 1=string, 2=number 3=mixed + local srt = { } + local category = 0 -- 0=unknown 1=string, 2=number 3=mixed + local s = 0 for key in next, tab do s = s + 1 srt[s] = key @@ -186,7 +189,8 @@ end local function sortedhashonly(tab) if tab then - local srt, s = { }, 0 + local srt = { } + local s = 0 for key in next, tab do if type(key) == "string" then s = s + 1 @@ -204,7 +208,8 @@ end local function sortedindexonly(tab) if tab then - local srt, s = { }, 0 + local srt = { } + local s = 0 for key in next, tab do if type(key) == "number" then s = s + 1 @@ -222,7 +227,8 @@ end local function sortedhashkeys(tab,cmp) -- fast one if tab then - local srt, s = { }, 0 + local srt = { } + local s = 0 for key in next, tab do if key then s= s + 1 @@ -318,7 +324,9 @@ end -- end function table.merge(t, ...) -- first one is target - t = t or { } + if not t then + t = { } + end for i=1,select("#",...) do for k, v in next, (select(i,...)) do t[k] = v @@ -384,7 +392,8 @@ end -- end function table.imerged(...) - local tmp, ntmp = { }, 0 + local tmp = { } + local ntmp = 0 for i=1,select("#",...) do local nst = select(i,...) for j=1,#nst do @@ -421,7 +430,9 @@ end -- todo : copy without metatable local function copy(t,tables) -- taken from lua wiki, slightly adapted - tables = tables or { } + if not tables then + tables = { } + end local tcopy = { } if not tables[t] then tables[t] = tcopy @@ -472,7 +483,8 @@ function table.tohash(t,value) end function table.fromhash(t) - local hsh, h = { }, 0 + local hsh = { } + local h = 0 for k, v in next, t do if v then h = h + 1 @@ -670,7 +682,8 @@ local function do_serialize(root,name,depth,level,indexed) end -- we could check for k (index) being number (cardinal) if root and next(root) ~= nil then - local first, last = nil, 0 + local first = nil + local last = 0 if compact then last = #root for k=1,last do @@ -830,22 +843,25 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tv == "function" then if functions then - local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip - -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip - if tk == "number" then - if hexify then - handle(format("%s [0x%X]=load(%q),",depth,k,f)) + local getinfo = debug and debug.getinfo + if getinfo then + local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip + -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip + if tk == "number" then + if hexify then + handle(format("%s [0x%X]=load(%q),",depth,k,f)) + else + handle(format("%s [%s]=load(%q),",depth,k,f)) + end + elseif tk == "boolean" then + handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + elseif tk ~= "string" then + -- ignore + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s=load(%q),",depth,k,f)) else - handle(format("%s [%s]=load(%q),",depth,k,f)) + handle(format("%s [%q]=load(%q),",depth,k,f)) end - elseif tk == "boolean" then - handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) - elseif tk ~= "string" then - -- ignore - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=load(%q),",depth,k,f)) - else - handle(format("%s [%q]=load(%q),",depth,k,f)) end end else @@ -958,7 +974,8 @@ end -- number : [number] = { } function table.serialize(root,name,specification) - local t, n = { }, 0 + local t = { } + local n = 0 local function flush(s) n = n + 1 t[n] = s @@ -982,13 +999,15 @@ function table.tofile(filename,root,name,specification) local f = io.open(filename,'w') if f then if maxtab > 1 then - local t, n = { }, 0 + local t = { } + local n = 0 local function flush(s) n = n + 1 t[n] = s if n > maxtab then f:write(concat(t,"\n"),"\n") -- hm, write(sometable) should be nice - t, n = { }, 0 -- we could recycle t if needed + t = { } -- we could recycle t if needed + n = 0 end end serialize(flush,root,name,specification) @@ -1006,12 +1025,12 @@ end local function flattened(t,f,depth) -- also handles { nil, 1, nil, 2 } if f == nil then - f = { } + f = { } depth = 0xFFFF elseif tonumber(f) then -- assume that only two arguments are given depth = f - f = { } + f = { } elseif not depth then depth = 0xFFFF end @@ -1099,8 +1118,12 @@ local function are_equal(a,b,n,m) -- indexed if a == b then return true elseif a and b and #a == #b then - n = n or 1 - m = m or #a + if not n then + n = 1 + end + if not m then + m = #a + end for i=n,m do local ai, bi = a[i], b[i] if ai==bi then @@ -1213,7 +1236,8 @@ end function table.reversed(t) if t then - local tt, tn = { }, #t + local tt = { } + local tn = #t if tn > 0 then local ttn = 0 for i=tn,1,-1 do @@ -1228,24 +1252,32 @@ end function table.reverse(t) -- check with 5.3 ? if t then local n = #t + local m = n + 1 for i=1,floor(n/2) do -- maybe just n//2 - local j = n - i + 1 + local j = m - i t[i], t[j] = t[j], t[i] end return t end end -function table.sequenced(t,sep,simple) -- hash only +local function sequenced(t,sep,simple) if not t then return "" + elseif type(t) == "string" then + return t -- handy fallback end local n = #t local s = { } if n > 0 then -- indexed for i=1,n do - s[i] = tostring(t[i]) + local v = t[i] + if type(v) == "table" then + s[i] = "{" .. sequenced(v,sep,simple) .. "}" + else + s[i] = tostring(t[i]) + end end else -- hashed @@ -1257,17 +1289,27 @@ function table.sequenced(t,sep,simple) -- hash only s[n] = k elseif v and v~= "" then n = n + 1 - s[n] = k .. "=" .. tostring(v) + if type(v) == "table" then + s[n] = k .. "={" .. sequenced(v,sep,simple) .. "}" + else + s[n] = k .. "=" .. tostring(v) + end end else n = n + 1 - s[n] = k .. "=" .. tostring(v) + if type(v) == "table" then + s[n] = k .. "={" .. sequenced(v,sep,simple) .. "}" + else + s[n] = k .. "=" .. tostring(v) + end end end end return concat(s,sep or " | ") end +table.sequenced = sequenced + function table.print(t,...) if type(t) ~= "table" then print(tostring(t)) @@ -1312,8 +1354,8 @@ end function table.unique(old) local hash = { } - local new = { } - local n = 0 + local new = { } + local n = 0 for i=1,#old do local oi = old[i] if not hash[oi] then @@ -1334,12 +1376,14 @@ end function table.values(t,s) -- optional sort flag if t then - local values, keys, v = { }, { }, 0 + local values = { } + local keys = { } + local v = 0 for key, value in next, t do if not keys[value] then v = v + 1 values[v] = value - keys[k] = key + keys[k] = key end end if s then diff --git a/tex/context/base/mkiv/l-unicode.lua b/tex/context/base/mkiv/l-unicode.lua index b5f52d312..13e0a3fa1 100644 --- a/tex/context/base/mkiv/l-unicode.lua +++ b/tex/context/base/mkiv/l-unicode.lua @@ -21,13 +21,33 @@ if not modules then modules = { } end modules ['l-unicode'] = { -- todo: utf.sub replacement (used in syst-aux) -- we put these in the utf namespace: --- used : byte char gmatch len lower sub upper --- not used : dump find format gfind gsub match rep reverse +-- used : byte char len lower sub upper +-- not used : dump find format gmatch gfind gsub match rep reverse -utf = utf or (unicode and unicode.utf8) or { } +-- utf = utf or (unicode and unicode.utf8) or { } + +-- not supported: +-- +-- dump, find, format, gfind, gmatch, gsub, lower, match, rep, reverse, upper + +utf = utf or { } +unicode = nil + +if not string.utfcharacters then + + -- New: this gmatch hack is taken from the Lua 5.2 book. It's about two times slower + -- than the built-in string.utfcharacters. + + local gmatch = string.gmatch + + function string.characters(str) + return gmatch(str,".[\128-\191]*") + end -utf.characters = utf.characters or string.utfcharacters -utf.values = utf.values or string.utfvalues + +end + +utf.characters = string.utfcharacters -- string.utfvalues -- string.utfcharacters @@ -53,23 +73,19 @@ local bytepairs = string.bytepairs local finder = lpeg.finder local replacer = lpeg.replacer -local utfvalues = utf.values -local utfgmatch = utf.gmatch -- not always present - local p_utftype = patterns.utftype local p_utfstricttype = patterns.utfstricttype local p_utfoffset = patterns.utfoffset -local p_utf8char = patterns.utf8character +local p_utf8character = patterns.utf8character +local p_utf8char = patterns.utf8char local p_utf8byte = patterns.utf8byte local p_utfbom = patterns.utfbom local p_newline = patterns.newline local p_whitespace = patterns.whitespace -if not unicode then - - unicode = { utf = utf } -- for a while - -end +-- if not unicode then +-- unicode = { utf = utf } -- for a while +-- end if not utf.char then @@ -164,10 +180,8 @@ if not utf.byte then if not utf.byte then - local utf8byte = patterns.utf8byte - function utf.byte(c) - return lpegmatch(utf8byte,c) + return lpegmatch(p_utf8byte,c) end end @@ -281,7 +295,7 @@ if not utf.len then -- -- alternative 1: 0.77 -- - -- local utfcharcounter = utfbom^-1 * Cs((p_utf8char/'!')^0) + -- local utfcharcounter = utfbom^-1 * Cs((p_utf8character/'!')^0) -- -- function utf.len(str) -- return #lpegmatch(utfcharcounter,str or "") @@ -291,7 +305,7 @@ if not utf.len then -- -- local n = 0 -- - -- local utfcharcounter = utfbom^-1 * (p_utf8char/function() n = n + 1 end)^0 -- slow + -- local utfcharcounter = utfbom^-1 * (p_utf8character/function() n = n + 1 end)^0 -- slow -- -- function utf.length(str) -- n = 0 @@ -368,7 +382,7 @@ if not utf.sub then -- inefficient as lpeg just copies ^n -- local function sub(str,start,stop) - -- local pattern = p_utf8char^-(start-1) * C(p_utf8char^-(stop-start+1)) + -- local pattern = p_utf8character^-(start-1) * C(p_utf8character^-(stop-start+1)) -- inspect(pattern) -- return lpegmatch(pattern,str) or "" -- end @@ -391,7 +405,7 @@ if not utf.sub then -- end -- end -- - -- local pattern = Cmt(p_utf8char,slide)^0 + -- local pattern = Cmt(p_utf8character,slide)^0 -- -- function utf.sub(str,start,stop) -- todo: from the end -- if not start then @@ -446,11 +460,11 @@ if not utf.sub then end end - local pattern_zero = Cmt(p_utf8char,slide_zero)^0 - local pattern_one = Cmt(p_utf8char,slide_one )^0 - local pattern_two = Cmt(p_utf8char,slide_two )^0 + local pattern_zero = Cmt(p_utf8character,slide_zero)^0 + local pattern_one = Cmt(p_utf8character,slide_one )^0 + local pattern_two = Cmt(p_utf8character,slide_two )^0 - local pattern_first = C(patterns.utf8character) + local pattern_first = C(p_utf8character) function utf.sub(str,start,stop) if not start then @@ -546,7 +560,7 @@ end -- a replacement for simple gsubs: -- function utf.remapper(mapping) --- local pattern = Cs((p_utf8char/mapping)^0) +-- local pattern = Cs((p_utf8character/mapping)^0) -- return function(str) -- if not str or str == "" then -- return "" @@ -568,16 +582,16 @@ function utf.remapper(mapping,option,action) -- static also returns a pattern return "" else if not pattern then - pattern = Cs((tabletopattern(mapping)/action + p_utf8char)^0) + pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0) end return lpegmatch(pattern,str) end end elseif option == "pattern" then - return Cs((tabletopattern(mapping)/action + p_utf8char)^0) + return Cs((tabletopattern(mapping)/action + p_utf8character)^0) -- elseif option == "static" then else - local pattern = Cs((tabletopattern(mapping)/action + p_utf8char)^0) + local pattern = Cs((tabletopattern(mapping)/action + p_utf8character)^0) return function(str) if not str or str == "" then return "" @@ -588,9 +602,9 @@ function utf.remapper(mapping,option,action) -- static also returns a pattern end elseif variant == "function" then if option == "pattern" then - return Cs((p_utf8char/mapping + p_utf8char)^0) + return Cs((p_utf8character/mapping + p_utf8character)^0) else - local pattern = Cs((p_utf8char/mapping + p_utf8char)^0) + local pattern = Cs((p_utf8character/mapping + p_utf8character)^0) return function(str) if not str or str == "" then return "" @@ -637,9 +651,9 @@ end -- inspect(utf.split("a b c d",true)) local utflinesplitter = p_utfbom^-1 * lpeg.tsplitat(p_newline) -local utfcharsplitter_ows = p_utfbom^-1 * Ct(C(p_utf8char)^0) -local utfcharsplitter_iws = p_utfbom^-1 * Ct((p_whitespace^1 + C(p_utf8char))^0) -local utfcharsplitter_raw = Ct(C(p_utf8char)^0) +local utfcharsplitter_ows = p_utfbom^-1 * Ct(C(p_utf8character)^0) +local utfcharsplitter_iws = p_utfbom^-1 * Ct((p_whitespace^1 + C(p_utf8character))^0) +local utfcharsplitter_raw = Ct(C(p_utf8character)^0) patterns.utflinesplitter = utflinesplitter @@ -775,7 +789,7 @@ local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_ -- if right then -- local now = 256*left + right -- if more > 0 then --- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong +-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- more = 0 -- r = r + 1 -- result[r] = utfchar(now) @@ -804,7 +818,7 @@ local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_ -- if right then -- local now = 256*right + left -- if more > 0 then --- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong +-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- more = 0 -- r = r + 1 -- result[r] = utfchar(now) @@ -834,7 +848,7 @@ local utf_32_le_linesplitter = utf_32_le_getbom * lpeg.tsplitat(patterns.utf_32_ -- if right then -- local now = 256*right + left -- if more > 0 then --- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong +-- now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- more = 0 -- r = r + 1 -- result[r] = utfchar(now) @@ -911,7 +925,7 @@ local more = 0 local p_utf16_to_utf8_be = C(1) * C(1) /function(left,right) local now = 256*byte(left) + byte(right) if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 more = 0 return utfchar(now) elseif now >= 0xD800 and now <= 0xDBFF then @@ -925,7 +939,7 @@ end local p_utf16_to_utf8_le = C(1) * C(1) /function(right,left) local now = 256*byte(left) + byte(right) if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 more = 0 return utfchar(now) elseif now >= 0xD800 and now <= 0xDBFF then @@ -1119,15 +1133,6 @@ function utf.utf8_to_utf16(str,littleendian,nobom) end end --- function utf.tocodes(str,separator) -- can be sped up with an lpeg --- local t, n = { }, 0 --- for u in utfvalues(str) do --- n = n + 1 --- t[n] = format("0x%04X",u) --- end --- return concat(t,separator or " ") --- end - local pattern = Cs ( (p_utf8byte / function(unicode ) return format( "0x%04X", unicode) end) * (p_utf8byte * Carg(1) / function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0 @@ -1163,25 +1168,10 @@ end -- -local p_nany = p_utf8char / "" - -if utfgmatch then - - function utf.count(str,what) - if type(what) == "string" then - local n = 0 - for _ in utfgmatch(str,what) do - n = n + 1 - end - return n - else -- 4 times slower but still faster than / function - return #lpegmatch(Cs((P(what)/" " + p_nany)^0),str) - end - end - -else +do - local cache = { } + local p_nany = p_utf8character / "" + local cache = { } function utf.count(str,what) if type(what) == "string" then @@ -1198,23 +1188,7 @@ else end --- maybe also register as string.utf* - - -if not utf.characters then - - -- New: this gmatch hack is taken from the Lua 5.2 book. It's about two times slower - -- than the built-in string.utfcharacters. - - function utf.characters(str) - return gmatch(str,".[\128-\191]*") - end - - string.utfcharacters = utf.characters - -end - -if not utf.values then +if not string.utfvalues then -- So, a logical next step is to check for the values variant. It over five times -- slower than the built-in string.utfvalues. I optimized it a bit for n=0,1. @@ -1226,7 +1200,7 @@ if not utf.values then -- we share this one end - -- function utf.values(str) + -- function string.utfvalues(str) -- local n = #str -- if n == 0 then -- return wrap(dummy) @@ -1241,7 +1215,7 @@ if not utf.values then -- -- faster: - function utf.values(str) + function string.utfvalues(str) local n = #str if n == 0 then return dummy @@ -1264,11 +1238,11 @@ if not utf.values then -- slower: -- - -- local pattern = C(patterns.utf8character) * Cp() - -- ----- pattern = patterns.utf8character/utfbyte * Cp() - -- ----- pattern = patterns.utf8byte * Cp() + -- local pattern = C(p_utf8character) * Cp() + -- ----- pattern = p_utf8character/utfbyte * Cp() + -- ----- pattern = p_utf8byte * Cp() -- - -- function utf.values(str) -- one of the cases where a find is faster than an lpeg + -- function string.utfvalues(str) -- one of the cases where a find is faster than an lpeg -- local n = #str -- if n == 0 then -- return dummy @@ -1287,10 +1261,10 @@ if not utf.values then -- end -- end - string.utfvalues = utf.values - end +utf.values = string.utfvalues + function utf.chrlen(u) -- u is number return (u < 0x80 and 1) or @@ -1310,7 +1284,7 @@ if bit32 then local extract = bit32.extract local char = string.char - function unicode.toutf32string(n) + function utf.toutf32string(n) if n <= 0xFF then return char(n) .. @@ -1359,3 +1333,73 @@ function string.utfpadd(s,n) end return s end + +-- goodies + +do + + local utfcharacters = utf.characters or string.utfcharacters + local utfchar = utf.char or string.utfcharacter + + lpeg.UP = P + + if utfcharacters then + + function lpeg.US(str) + local p = P(false) + for uc in utfcharacters(str) do + p = p + P(uc) + end + return p + end + + else + + function lpeg.US(str) + local p = P(false) + local f = function(uc) + p = p + P(uc) + end + lpegmatch((p_utf8char/f)^0,str) + return p + end + + end + + local range = p_utf8byte * p_utf8byte + Cc(false) -- utf8byte is already a capture + + function lpeg.UR(str,more) + local first, last + if type(str) == "number" then + first = str + last = more or first + else + first, last = lpegmatch(range,str) + if not last then + return P(str) + end + end + if first == last then + return P(str) + end + if not utfchar then + utfchar = utf.char -- maybe delayed + end + if utfchar and (last - first < 8) then -- a somewhat arbitrary criterium + local p = P(false) + for i=first,last do + p = p + P(utfchar(i)) + end + return p -- nil when invalid range + else + local f = function(b) + return b >= first and b <= last + end + -- tricky, these nested captures + return p_utf8byte / f -- nil when invalid range + end + end + + -- print(lpeg.match(lpeg.Cs((C(lpeg.UR("αω"))/{ ["χ"] = "OEPS" })^0),"αωχαω")) + +end diff --git a/tex/context/base/mkiv/lang-def.lua b/tex/context/base/mkiv/lang-def.lua index c0c3981f7..3f04bed0d 100644 --- a/tex/context/base/mkiv/lang-def.lua +++ b/tex/context/base/mkiv/lang-def.lua @@ -224,6 +224,15 @@ local specifications = allocate { ["opentype"] = "fin", ["variant"] = "fi", }, + { + ["description"] = "Estonian", + ["script"] = "latn", + ["bibliographical"] = "est", + ["terminological"] = "est", + ["context"] = "et", + ["opentype"] = "est", + ["variant"] = "et", + }, { ["description"] = "French", ["script"] = "latn", diff --git a/tex/context/base/mkiv/lang-def.mkiv b/tex/context/base/mkiv/lang-def.mkiv index 28245e591..7f3e85f08 100644 --- a/tex/context/base/mkiv/lang-def.mkiv +++ b/tex/context/base/mkiv/lang-def.mkiv @@ -21,19 +21,6 @@ % Swedish, German, Yiddish, Afrikaans, Dutch, English, Flemush, % Frisian, Plattdeutsch -\installlanguage - [\s!nl] - [\c!spacing=\v!packed, - \c!leftsentence=\emdash, - \c!rightsentence=\emdash, - \c!leftsubsentence=\emdash, - \c!rightsubsentence=\emdash, - \c!leftquote=\lowerleftsingleninequote, - \c!rightquote=\upperrightsingleninequote, - \c!leftquotation=\lowerleftdoubleninequote, - \c!rightquotation=\upperrightdoubleninequote, - \c!date={\v!day,\space,\v!month,\space,\v!year}] - \installlanguage [\s!en] [\c!spacing=\v!broad, @@ -50,6 +37,19 @@ \s!lefthyphenmin=2, \s!righthyphenmin=3] +\installlanguage + [\s!nl] + [\c!spacing=\v!packed, + \c!leftsentence=\emdash, + \c!rightsentence=\emdash, + \c!leftsubsentence=\emdash, + \c!rightsubsentence=\emdash, + \c!leftquote=\lowerleftsingleninequote, + \c!rightquote=\upperrightsingleninequote, + \c!leftquotation=\lowerleftdoubleninequote, + \c!rightquotation=\upperrightdoubleninequote, + \c!date={\v!day,\space,\v!month,\space,\v!year}] + \installlanguage [\s!de] [\c!spacing=\v!packed, @@ -327,6 +327,22 @@ \c!rightquotation=\upperrightdoubleninequote, \c!date={\v!year,\space,\v!month,\space,\v!day}] +\installlanguage + [\s!et] + [\c!default=\s!en, + \c!spacing=\v!packed, + \c!leftsentence=\emdash, + \c!rightsentence=\emdash, + \c!leftsubsentence=\emdash, + \c!rightsubsentence=\emdash, + \c!leftquote=\leftguillemot, + \c!rightquote=\rightguillemot, + \c!leftquotation=\lowerrightdoubleninequote, + \c!rightquotation=\upperrightdoublesixquote, + \c!time={h,{.},m}, + \c!date={\v!day,.,\space,\v!month,\space,\v!year}, + \s!patterns=\s!et] + \installlanguage [\s!hu] [\c!spacing=\v!packed, @@ -341,6 +357,7 @@ \c!date={\v!year,.,\space,\v!month,\space,\v!day,.}] \installlanguage [\s!finnish] [\s!fi] +\installlanguage [\s!estonian] [\s!et] \installlanguage [\s!hungarian] [\s!hu] % Altaic Languages: Uigur, Uzbek, Azeri/Azerbaijani, Chuvash, @@ -580,6 +597,7 @@ \c!rightquote=\rightguillemot, \c!leftquotation=\leftguillemot, \c!rightquotation=\rightguillemot, + \c!time={h,{\Uchar104 },m},% we need to cheat in order to get the h \c!date={\v!day:mnem,\v!space,\v!month,\v!space,\v!year}] \installlanguage diff --git a/tex/context/base/mkiv/lang-dis.lua b/tex/context/base/mkiv/lang-dis.lua index 65a53a702..5603d1193 100644 --- a/tex/context/base/mkiv/lang-dis.lua +++ b/tex/context/base/mkiv/lang-dis.lua @@ -17,14 +17,10 @@ local nuts = nodes.nuts local enableaction = tasks.enableaction local setaction = tasks.setaction -local tonode = nuts.tonode -local tonut = nuts.tonut - local setfield = nuts.setfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid -local getfont = nuts.getfont local getattr = nuts.getattr local getsubtype = nuts.getsubtype local setsubtype = nuts.setsubtype @@ -40,10 +36,11 @@ local isglyph = nuts.isglyph local copy_node = nuts.copy local remove_node = nuts.remove -local traverse_id = nuts.traverse_id local flush_list = nuts.flush_list local flush_node = nuts.flush_node +local nextdisc = nuts.traversers.disc + local new_disc = nuts.pool.disc local nodecodes = nodes.nodecodes @@ -52,10 +49,7 @@ local disccodes = nodes.disccodes local disc_code = nodecodes.disc local glyph_code = nodecodes.glyph -local discretionary_code = disccodes.discretionary -local explicit_code = disccodes.explicit -local automatic_code = disccodes.automatic -local regular_code = disccodes.regular +local explicitdisc_code = disccodes.explicit local a_visualize = attributes.private("visualizediscretionary") local setattribute = tex.setattribute @@ -69,7 +63,7 @@ local check_regular = true local setlistcolor = nodes.tracers.colors.setlist function languages.visualizediscretionaries(head) - for d in traverse_id(disc_code,tonut(head)) do + for d in nextdisc, head do if getattr(d,a_visualize) then local pre, post, replace = getdisc(d) if pre then @@ -83,6 +77,7 @@ function languages.visualizediscretionaries(head) end end end + return head end local enabled = false @@ -129,13 +124,9 @@ end local wiped = 0 -local flatten_discretionaries = node.flatten_discretionaries -- todo in nodes +local flatten_discretionaries = nuts.flatten_discretionaries -- todo in nodes -if flatten_discretionaries then - - -- This is not that much faster than the lua variant simply because there is - -- seldom a replace list but it fits in the picture. See luatex-todo.w for the - -- code. +-- if flatten_discretionaries then function languages.flatten(head) local h, n = flatten_discretionaries(head) @@ -143,51 +134,50 @@ if flatten_discretionaries then return h, n > 0 end -else - - local function wipe(head,delayed) - local p, n = getboth(delayed) - local _, _, h, _, _, t = getdisc(delayed,true) - if p or n then - if h then - setlink(p,h) - setlink(t,n) - setfield(delayed,"replace") - else - setlink(p,n) - end - end - if head == delayed then - head = h - end - wiped = wiped + 1 - flush_node(delayed) - return head - end - - function languages.flatten(head) - local nuthead = tonut(head) - local delayed = nil - for d in traverse_id(disc_code,nuthead) do - if delayed then - nuthead = wipe(nuthead,delayed) - end - delayed = d - end - if delayed then - return tonode(wipe(nuthead,delayed)), true - else - return head, false - end - end - -end +-- else +-- +-- local function wipe(head,delayed) +-- local p, n = getboth(delayed) +-- local _, _, h, _, _, t = getdisc(delayed,true) +-- if p or n then +-- if h then +-- setlink(p,h) +-- setlink(t,n) +-- setfield(delayed,"replace") +-- else +-- setlink(p,n) +-- end +-- end +-- if head == delayed then +-- head = h +-- end +-- wiped = wiped + 1 +-- flush_node(delayed) +-- return head +-- end +-- +-- function languages.flatten(head) +-- local delayed = nil +-- for d in nextdisc, head do +-- if delayed then +-- head = wipe(head,delayed) +-- end +-- delayed = d +-- end +-- if delayed then +-- return wipe(head,delayed), true +-- else +-- return head, false +-- end +-- end +-- +-- end function languages.nofflattened() return wiped -- handy for testing end --- experiment +-- experiment: for now not in not in export mode! local flatten = languages.flatten local getlist = nodes.getlist @@ -198,10 +188,11 @@ function nodes.handlers.flatten(head,where) if head and (where == "box" or where == "adjusted_hbox") then return flatten(head) end - return true + return head end directives.register("hyphenator.flatten",function(v) + -- use with care setaction("processors","nodes.handlers.flatten",v) setaction("contributers","nodes.handlers.flattenline",v) end) @@ -227,6 +218,6 @@ function languages.explicithyphen(template) end end end - setdisc(disc,pre,post,nil,explicit_code,tex.exhyphenpenalty) + setdisc(disc,pre,post,nil,explicitdisc_code,tex.exhyphenpenalty) return disc end diff --git a/tex/context/base/mkiv/lang-exp.lua b/tex/context/base/mkiv/lang-exp.lua index 70fad48b0..254961ee6 100644 --- a/tex/context/base/mkiv/lang-exp.lua +++ b/tex/context/base/mkiv/lang-exp.lua @@ -31,6 +31,8 @@ local expanders -- this will go away if LUATEXVERSION < 1.005 then -- not loaded any more + -- some shortcuts go here + expanders = { [discretionary_code] = function(d,template) -- \discretionary @@ -172,23 +174,23 @@ languages.expanders = expanders ----- expand_explicit = expanders and expanders[explicit_code] ----- expand_automatic = expanders and expanders[automatic_code] -if LUATEXVERSION < 1.005 then -- not loaded any more - - expanded = function(head) - local done = hyphenate(head) - if done then - for d in traverse_id(disc_code,tonut(head)) do - local s = getsubtype(d) - if s ~= discretionary_code then - expanders[s](d,template) - done = true - end - end - end - return head, done - end - -end +-- if LUATEXVERSION < 1.005 then -- not loaded any more +-- +-- expanded = function(head) +-- local done = hyphenate(head) +-- if done then +-- for d in traverse_id(disc_code,head) do +-- local s = getsubtype(d) +-- if s ~= discretionary_code then +-- expanders[s](d,template) +-- done = true +-- end +-- end +-- end +-- return head, done +-- end +-- +-- end -- if id == disc_code then -- if expanded then diff --git a/tex/context/base/mkiv/lang-hyp.lua b/tex/context/base/mkiv/lang-hyp.lua index e29446b65..92b400d4f 100644 --- a/tex/context/base/mkiv/lang-hyp.lua +++ b/tex/context/base/mkiv/lang-hyp.lua @@ -626,13 +626,10 @@ if context then local math_code = nodecodes.math local hlist_code = nodecodes.hlist - local discretionary_code = disccodes.discretionary - local explicit_code = disccodes.explicit - local automatic_code = disccodes.automatic - local regular_code = disccodes.regular + local automaticdisc_code = disccodes.automatic + local regulardisc_code = disccodes.regular local nuts = nodes.nuts - local tonut = nodes.tonut local tonode = nodes.tonode local nodepool = nuts.pool @@ -666,7 +663,9 @@ if context then local remove_node = nuts.remove local end_of_math = nuts.end_of_math local node_tail = nuts.tail - local traverse_id = nuts.traverse_id + + local nexthlist = nuts.traversers.hlist + local nextdisc = nuts.traversers.disc local setcolor = nodes.tracers.colors.set @@ -1028,9 +1027,7 @@ featureset.hyphenonly = hyphenonly == v_yes function traditional.hyphenate(head) - local first = tonut(head) - - + local first = head local tail = nil local last = nil local current = first @@ -1289,7 +1286,7 @@ featureset.hyphenonly = hyphenonly == v_yes if leftchar then post = serialize(true,leftchar) end - setdisc(disc,pre,post,nil,regular_code,hyphenpenalty) + setdisc(disc,pre,post,nil,regulardisc_code,hyphenpenalty) if attrnode then setattrlist(disc,attrnode) end @@ -1324,7 +1321,7 @@ featureset.hyphenonly = hyphenonly == v_yes end end -- maybe regular code - setdisc(disc,pre,post,replace,regular_code,hyphenpenalty) + setdisc(disc,pre,post,replace,regulardisc_code,hyphenpenalty) if attrnode then setattrlist(disc,attrnode) end @@ -1364,7 +1361,7 @@ featureset.hyphenonly = hyphenonly == v_yes end pre = copy_node(glyph) setchar(pre,rightchar and rightchar > 0 and rightchar or code) - setdisc(disc,pre,post,replace,automatic_code,hyphenpenalty) -- ex ? + setdisc(disc,pre,post,replace,automaticdisc_code,hyphenpenalty) -- ex ? if attrnode then setattrlist(disc,attrnode) end @@ -1386,7 +1383,7 @@ featureset.hyphenonly = hyphenonly == v_yes local pre = copy_list(start) local post = nil local replace = start - setdisc(disc,pre,post,replace,automatic_code,hyphenpenalty) -- ex ? + setdisc(disc,pre,post,replace,automaticdisc_code,hyphenpenalty) -- ex ? if attrnode then setattrlist(disc,attrnode) end @@ -1585,7 +1582,7 @@ featureset.hyphenonly = hyphenonly == v_yes stoptiming(traditional) - return head, true + return head end statistics.register("hyphenation",function() @@ -1613,15 +1610,31 @@ featureset.hyphenonly = hyphenonly == v_yes -- local replaceaction = nodes.tasks.replaceaction -- no longer overload this way (too many local switches) - local hyphenate = lang.hyphenate - local methods = { } - local usedmethod = false - local stack = { } + local hyphenate = lang.hyphenate + local hyphenating = nuts.hyphenating + local methods = { } + local usedmethod = false + local stack = { } - local function original(head) - local done = hyphenate(head) - return head, done - end + local original = hyphenating and + function(head) + return (hyphenating(head)) + end + or + function(head) + hyphenate(tonode(head)) + return head -- a nut + end + + -- local has_language = lang.has_language + -- + -- local function original(head) -- kernel.hyphenation(head) + -- local h = tonode(head) + -- if has_language(h) then + -- hyphenate(h) + -- end + -- return head + -- end local getcount = tex.getcount @@ -1637,13 +1650,13 @@ featureset.hyphenonly = hyphenonly == v_yes forced = false return usedmethod(head) else - return head, false + return head end else return usedmethod(head) end else - return head, false + return head end end @@ -1729,13 +1742,12 @@ featureset.hyphenonly = hyphenonly == v_yes } function nodes.stripdiscretionaries(head) - local h = tonut(head) - for l in traverse_id(hlist_code,h) do - for d in traverse_id(disc_code,getlist(l)) do + for l in nexthlist, head do + for d in nextdisc, getlist(l) do remove_node(h,false,true) end end - return tonode(h) + return head end diff --git a/tex/context/base/mkiv/lang-hyp.mkiv b/tex/context/base/mkiv/lang-hyp.mkiv index feec82659..9301fd1d8 100644 --- a/tex/context/base/mkiv/lang-hyp.mkiv +++ b/tex/context/base/mkiv/lang-hyp.mkiv @@ -48,10 +48,11 @@ \automatichyphenmode \plusone \hyphenpenaltymode \plusfour -\hyphenpenalty 50 % hyphenator -\automatichyphenpenalty 50 % - -\explicithyphenpenalty 50 % \- -\compoundhyphenpenalty 50 +\hyphenpenalty 50 % hyphenator +\automatichyphenpenalty 50 % - +\explicithyphenpenalty 50 % \- +\compoundhyphenpenalty 50 +\exceptionpenalty 1000 %D This command can change! At some point we will keep the setting with the %D paragraph and then the \type {\par} can go. diff --git a/tex/context/base/mkiv/lang-ini.mkiv b/tex/context/base/mkiv/lang-ini.mkiv index 7c83ae38f..296cf7f1c 100644 --- a/tex/context/base/mkiv/lang-ini.mkiv +++ b/tex/context/base/mkiv/lang-ini.mkiv @@ -15,10 +15,10 @@ % \cldcontext{languages.numbers[tex.count.mainlanguagenumber]} -%D This module implements the (for the moment still simple) -%D multi||language support of \CONTEXT, which should not be -%D confused with the multi||lingual interface. This support -%D will be extended when needed. +%D This module implements multi||language support of \CONTEXT, which should not be +%D confused with the multi||lingual interface. This support will be extended when +%D needed. Properties of languages are defined in \TEX\ files as well as \LUA\ +%D files. \writestatus{loading}{ConTeXt Language Macros / Initialization} @@ -28,41 +28,27 @@ \unprotect -% \def\testlanguage[#1]% -% {\start -% \language[#1] -% \number\normallanguage/\the\lefthyphenmin/\the\righthyphenmin: -% \input tufte -% \hyphenatedword{effetestenofditwerkt} -% \par -% \stop} -% -% \testlanguage[de] \testlanguage[de-de] \testlanguage[de-at] \testlanguage[de-ch] \page -% \testlanguage[en] \testlanguage[us] \testlanguage[en-us] \testlanguage[uk] \testlanguage[en-gb] \page - \ifdefined\nonfrenchspacing\else \let\nonfrenchspacing\relax \fi \ifdefined\frenchspacing \else \let\frenchspacing \relax \fi -%D When loading hyphenation patterns, \TEX\ assign a number to -%D each loaded table, starting with~0. Switching to a specific -%D table is done by assigning the relevant number to the -%D predefined \COUNTER\ \type{\language}. +%D When loading hyphenation patterns, \TEX\ assign a number to each loaded table, +%D starting with~0. Switching to a specific table is done by assigning the relevant +%D number to the predefined \COUNTER\ \type {\language}. However, in \MKIV\ a lot +%D of management is delegated to \LUA. -%D We keep track of the last loaded patterns by means of a -%D pseudo \COUNTER. This just one of those situations in which -%D we don't want to spent a real one. Language zero has no -%D patterns, first of all because I like to start numbering -%D at one. It may come in handy for special purposes as well. +%D We keep track of the last loaded patterns by means of a pseudo \COUNTER. This +%D just one of those situations in which we don't want to spent a real one. Language +%D zero has no patterns, first of all because I like to start numbering at one. It +%D may come in handy for special purposes as well. \normallanguage\zerocount \def\loadedlanguage{1} %D \macros %D {currentlanguage, setupcurrentlanguage} %D -%D Instead of numbers,we are going to use symbolic names for -%D the languages. The current langage is saved in the macro -%D \type {\currentlanguage}. The setup macro is mainly used -%D for cosmetic purposes. +%D Instead of numbers,we are going to use symbolic names for the languages. The +%D current langage is saved in the macro \type {\currentlanguage}. The setup macro +%D is mainly used for cosmetic purposes. %D %D \starttyping %D \dorecurse{3} @@ -79,10 +65,9 @@ %D \macros %D {defaultlanguage,languageparameter,specificlanguageparameter} - -%D We don't use the commandhandler here (yet) because we have -%D a rather special fallback mechanism so quite some compatibility -%D testing is needed. +%D +%D We don't use the commandhandler here (yet) because we have a rather special +%D fallback mechanism so quite some compatibility testing is needed. \installcorenamespace{language} \installcorenamespace{languagelinked} @@ -96,33 +81,6 @@ #1% \fi} -% \def\languageparameter#1% -% {\ifcsname\??language\currentlanguage#1\endcsname -% \csname\??language\currentlanguage#1\endcsname -% \else\ifcsname\??language\currentlanguage\s!default\endcsname -% \expandafter\specificlanguageparameter\csname\??language\currentlanguage\s!default\endcsname{#1}% -% \else\ifcsname\??language\s!default#1\endcsname -% \csname\??language\s!default#1\endcsname -% \fi\fi\fi} -% -% \def\specificlanguageparameter#1#2% -% {\ifcsname\??language#1#2\endcsname -% \csname\??language#1#2\endcsname -% \else\ifcsname\??language#1\s!default\endcsname -% \expandafter\specificlanguageparameter\csname\??language#1\s!default\endcsname{#2}% -% \else\ifcsname\??language\s!default#2\endcsname -% \csname\??language\s!default#2\endcsname -% \fi\fi\fi} -% -% \def\mainlanguageparameter#1% -% {\ifcsname\??language\currentmainlanguage#1\endcsname -% \csname\??language\currentmainlanguage#1\endcsname -% \else\ifcsname\??language\currentmainlanguage\s!default\endcsname -% \expandafter\specificlanguageparameter\csname\??language\currentmainlanguage\s!default\endcsname{#1}% -% \else\ifcsname\??language\s!default#1\endcsname -% \csname\??language\s!default#1\endcsname -% \fi\fi\fi} - \def\languageparameter#1% {\ifcsname\??language\currentlanguage#1\endcsname \lastnamedcs @@ -152,15 +110,6 @@ \let\usedlanguageparameter\languageparameter -% \def\askedlanguageparameter#1% assumes \currentusedlanguage being set -% {\ifcsname\??language\currentusedlanguage#1\endcsname -% \csname\??language\currentusedlanguage#1\endcsname -% \else\ifcsname\??language\currentusedlanguage\s!default\endcsname -% \expandafter\specificlanguageparameter\csname\??language\currentusedlanguage\s!default\endcsname{#1}% -% \else\ifcsname\??language\s!default#1\endcsname -% \csname\??language\s!default#1\endcsname -% \fi\fi\fi} - \def\askedlanguageparameter#1% assumes \currentusedlanguage being set {\ifcsname\??language\currentusedlanguage#1\endcsname \lastnamedcs @@ -171,7 +120,6 @@ \fi\fi\fi} \unexpanded\def\setusedlanguage#1% -% {\edef\currentusedlanguage{\reallanguagetag{#1\c!language}}% {\edef\currentusedlanguage{\reallanguagetag{#1}}% \ifx\currentusedlanguage\empty \let\currentusedlanguage \currentlanguage @@ -208,43 +156,23 @@ %D \macros %D {installlanguage} %D -%D Hyphenation patterns can only be loaded when the format file -%D is prepared. The next macro takes care of this loading. A -%D language is specified with +%D Hyphenation patterns can only be loaded when the format file is prepared. The +%D next macro takes care of this loading. A language is specified with %D %D \showsetup{installlanguage} %D -%D When \type {state} equals \type {start}, both patterns -%D and additional hyphenation specifications are loaded. These -%D files are seached for on the system path and are to be -%D named: -%D -%D \starttyping -%D lang-identifier.\f!patternsextension -%D lang-identifier.\f!hyhensextension -%D \stoptyping +%D When \type {state} equals \type {start}, both patterns and additional hyphenation +%D specifications are loaded. These files are seached for in the patterns path +%D have names like \type {lang-nl.lua}. %D -%D The \type{spacing} variable specifies how the spaces after -%D punctuation has to be handled. English is by tradition more -%D tolerant to inter||sentence spacing than other languages. -%D -%D This macro also defines \type {\identifier} as a shortcut -%D switch to the language. Furthermore the command defined as -%D being language specific, are executed. With -%D \type {default} we can default to another language -%D (patterns) at format generation time. This default language -%D is overruled when the appropriate patterns are loaded (some -%D implementations support run time addition of patterns to a -%D preloaded format). - -%D \macros -%D {preloadlanguages} +%D The \type {spacing} variable specifies how the spaces after punctuation has to be +%D handled. English is by tradition more tolerant to inter||sentence spacing than +%D other languages. %D -%D We first try to load the files defined as file synonym -%D for \type {lang-*.pat} and \type {lang-*.hyp}. After that we -%D fall back on those files. The macro \type {\preloadpatterns} -%D reports which patterns are loaded and what hyphenmin -%D values are set. +%D This macro also defines \type {\identifier} as a shortcut switch to the language. +%D Furthermore the command defined as being language specific, are executed. With +%D \type {default} we can default to another language (patterns) at format +%D generation time. Patterns are loaded at runtime. \newtoks \everysetuplanguage @@ -260,7 +188,6 @@ \let\doiflanguageelse\doifelselanguage \def\reallanguagetag#1% - %{\ifcsname\??languagelinked#1\endcsname\csname\??languagelinked#1\endcsname\else#1\fi} {\ifcsname\??languagelinked#1\endcsname\lastnamedcs\else#1\fi} % \language[#1] gave unwanted side effect of loading language specifics @@ -285,10 +212,9 @@ \def\lang_basics_install_indeed#1#2% {\ifcsname#1\endcsname\else\setuvalue{#1}{\lang_basics_set_current[#2]}\fi} -%D When the second argument is a language identifier, a -%D synonym is created. This feature is present because we -%D used dutch mnemonics in the dutch version, but nowadays -%D conform a standard. +%D When the second argument is a language identifier, a synonym is created. This +%D feature is present because we used dutch mnemonics in the dutch version, but +%D nowadays conform a standard. \unexpanded\def\doifelsepatterns#1% {\begingroup % will change @@ -317,13 +243,15 @@ \let\lang_basics_synchronize\relax % be nice for setups till we have one \fi +\installmacrostack\currentlanguage + \def\lang_basics_setup[#1][#2]% {\ifsecondargument - \pushmacro\currentlanguage % can be default + \push_macro_currentlanguage % can be default \edef\currentsetuplanguage{\reallanguagetag{#1}}% \getparameters[\??language\currentsetuplanguage][#2]% \the\everysetuplanguage - \popmacro\currentlanguage + \pop_macro_currentlanguage %\doif\currentsetuplanguage\currentlanguage we can have influenced inheritance (default) \else \let\currentsetuplanguage\currentlanguage @@ -364,6 +292,7 @@ \c!middlespeech=, \c!rightspeech=\languageparameter\c!rightquotation, \c!limittext=\unknown, + \c!time={h,:,m}, \c!date={\v!year,\ ,\v!month,\ ,\v!day}, \c!text=Ag, \s!font=] % \v!auto : experimental ! @@ -374,26 +303,21 @@ % [\s!default] % [\c!righthyphenchar="AD] -%D The values \type {leftsentence} and \type -%D {rightsentence} can be (and are) used to implement -%D automatic subsentence boundary glyphs, like in {\fr -%D |<|french guillemots|>|} or {\de |<|german guillemots|>|} or -%D {\nl |<|dutch dashes|>|} like situations. Furthermore \type -%D {leftquotation} and \type {leftquote} come into view -%D \quotation {when we quote} or \quote {quote} something. +%D The values \type {leftsentence} and \type {rightsentence} can be (and are) used +%D to implement automatic subsentence boundary glyphs, like in {\fr |<|french +%D guillemots|>|} or {\de |<|german guillemots|>|} or {\nl |<|dutch dashes|>|} like +%D situations. Furthermore \type {leftquotation} and \type {leftquote} come into +%D view \quotation {when we quote} or \quote {quote} something. %D \macros -%D {currentdatespecification} +%D {currentdatespecification, currenttimespecification} %D -%D Just to make things easy we can ask for the current date -%D specification by saying: +%D Just to make things easy we can ask for the current date specification by saying: \def\currentdatespecification{\languageparameter\c!date} +\def\currenttimespecification{\languageparameter\c!time} -%D This command is not meant for users. - -%D Carefull reading of these macros shows that it's legal to -%D say +%D Carefull reading of these macros shows that it's legal to say %D %D \starttyping %D \installlanguage [du] [de] @@ -402,54 +326,39 @@ %D \macros %D {language,mainlanguage} %D -%D Switching to another language (actually another hyphenation -%D pattern) is done with: +%D Switching to another language (actually another hyphenation pattern) is done +%D with: %D %D \starttyping %D \language[identifier] %D \stoptyping %D -%D or with \type{\identifier}. Just to be compatible with -%D \PLAIN\ \TEX, we still support the original meaning, so +%D or with \type {\identifier}. Just to be compatible with \PLAIN\ \TEX, we still +%D support the original meaning, so %D %D \starttyping %D \language=1 %D \stoptyping %D -%D is a valid operation, where the relation between number -%D and language depends on the order in installing languages. +%D is a valid operation, where the relation between number and language depends on +%D the order in installing languages. %D %D \showsetup{language} %D \showsetup{mainlanguage} %D -%D Both commands take a predefined language identifier as -%D argument. We can use \type{\mainlanguage[identifier]} for -%D setting the (indeed) main language. This is the language -%D used for translating labels like {\em figure} and {\em -%D table}. The main language defaults to the current language. -%D -%D We take care of local as well as standardized language -%D switching (fr and fa, de and du, but nl and nl). +%D Both commands take a predefined language identifier as argument. We can use \type +%D {\mainlanguage[identifier]} for setting the (indeed) main language. This is the +%D language used for translating labels like {\em figure} and {\em table}. The main +%D language defaults to the current language. \newtoks \everylanguage -% \def\lang_basics_synchronize% assumes that \currentlanguage is set % % % use different name as complex -% {\normallanguage\ctxcommand{languagenumber(% -% "\currentlanguage",% -% "\defaultlanguage\currentlanguage",% -% "\languageparameter\s!patterns"% -% )}\relax -% \the\everylanguage\relax} - -% (some 20%) faster but code jungle (the publication code can have excessive -% switching - \installcorenamespace{languagenumbers} \appendtoks % we need to reassign the number because new patterns can be defined later on % so let's hope not that many \setups happen during a run - \global\expandafter\let\csname\??languagenumbers\currentlanguage\endcsname\undefined + \expandafter\glet\csname\??languagenumbers\currentlanguage\endcsname\undefined \to \everysetuplanguage \def\lang_basics_synchronize_yes @@ -471,7 +380,7 @@ \letvalue{\??languagenumbers}\lang_basics_synchronize_yes % runtime \to \everydump -\def\lang_basics_synchronize% assumes that \currentlanguage is set % % % use different name as complex +\def\lang_basics_synchronize {\normallanguage\csname\??languagenumbers \ifcsname\??languagenumbers\currentlanguage\endcsname \currentlanguage @@ -481,12 +390,7 @@ \the\everylanguage \relax} -% experimental - \newcount\hyphenstate - -% so far - \newcount\hyphenminoffset \unexpanded\def\lesshyphens @@ -530,7 +434,7 @@ % \setups[\languageparameter\c!setups]% % \to \everylanguage -%D You can setup the 'default' language to reset settings. +%D You can setup the default language to reset settings. \appendtoks \edef\currentlanguagesetups{\languageparameter\c!setups}% @@ -548,7 +452,12 @@ % this will move to core-spa ! \appendtoks - \doifelse{\languageparameter\c!spacing}\v!broad\nonfrenchspacing\frenchspacing + \edef\p_spacing{\languageparameter\c!spacing}% + \ifx\p_spacing\v!broad + \nonfrenchspacing + \else + \frenchspacing + \fi \to \everylanguage % \mainlanguage[nl] \setuplanguage[nl][lefthyphen=,righthyphen=?] @@ -576,11 +485,6 @@ \fi \to \everylanguage -% The following may be a solution for the fact that one cannot -% change catcodes of characters like : and ; inside an environment. - -% we will also permit access by the other names - %D Fast switcher \def\lang_basics_switch_asked @@ -613,23 +517,13 @@ \newcount\mainlanguagenumber -% \unexpanded\def\mainlanguage[#1]% -% {\edef\askedlanguage{#1}% -% \ifx\askedlanguage\empty \else -% \ifcsname\??languagelinked\askedlanguage\endcsname -% \edef\askedlanguage{\csname\??languagelinked\askedlanguage\endcsname}% -% \ifx\currentlanguage\askedlanguage -% \ifx\currentmainlanguage\askedlanguage \else -% \setcurrentlanguage\askedlanguage\askedlanguage -% \lang_basics_synchronize -% \fi -% \else -% \setcurrentlanguage\askedlanguage\askedlanguage -% \lang_basics_synchronize -% \fi -% \fi -% \fi -% \mainlanguagenumber\normallanguage} +%D Beware: you might need to use \type {\dontleavehmode} outside and|/|or \type {\par} +%D inside the group! + +\unexpanded\def\startlanguage + {\begingroup\language} + +\let\stoplanguage\endgroup \unexpanded\def\mainlanguage[#1]% {\edef\askedlanguage{#1}% @@ -662,9 +556,8 @@ \def\splitsymbol#1% {\splitsequence{#1}{\languageparameter\c!limittext}} -%D Just like with subsentence boundary symbols, quotes -%D placement depends on the current language, therefore we show -%D the defaults here. +%D Just like with subsentence boundary symbols, quotes placement depends on the +%D current language, therefore we show the defaults here. %D %D \def\ShowLanguageValues [#1] [#2] #3 #4 %D {\blank @@ -686,6 +579,7 @@ %D \ShowLanguageValues [da] [danish] deense ... %D \ShowLanguageValues [de] [german] duitse degelijkheid %D \ShowLanguageValues [en] [english] engelse humor +%D \ShowLanguageValues [et] [estonian] ... %D \ShowLanguageValues [fi] [finnish] finse ... %D \ShowLanguageValues [fr] [french] franse slag %D \ShowLanguageValues [it] [italian] italiaanse ... @@ -699,10 +593,9 @@ %D \ShowLanguageValues [sv] [swedish] zweedse ... %D \ShowLanguageValues [tr] [turkish] turks fruit -%D We support a lot of languages. These are specified and -%D loaded in separate files, according to their roots. Here -%D we only take care of (postponed) setting of the current -%D language. +%D We support a lot of languages. These are specified and loaded in separate files, +%D according to their roots. Here we only take care of (postponed) setting of the +%D current language. %D %D \unprotect %D \placetable{The germanic languages (\type{lang-ger})} @@ -773,9 +666,8 @@ \unexpanded\def\nopatterns{\normallanguage\minusone} -%D We default to the language belonging to the interface. This -%D is one of the few places outside the interface modules where -%D \type{\startinterface} is used. +%D We default to the language belonging to the interface. This is one of the few +%D places outside the interface modules where \type {\startinterface} is used. \setupcurrentlanguage[\s!en] diff --git a/tex/context/base/mkiv/lang-lab.mkiv b/tex/context/base/mkiv/lang-lab.mkiv index 73637753d..9d73d96e5 100644 --- a/tex/context/base/mkiv/lang-lab.mkiv +++ b/tex/context/base/mkiv/lang-lab.mkiv @@ -277,10 +277,16 @@ \def\lang_labels_text_prefix_copy_pair[#1=#2]% {\lang_labels_text_prefix_copy_pair_indeed{#1}[#2,,]} +% \def\lang_labels_text_prefix_copy_pair_indeed#1[#2,#3]% +% {\expandafter\let +% \csname\??label\currenttextprefixclass:\currenttextprefixtag:#1\expandafter\endcsname +% \csname\??label\currenttextprefixclass:\currenttextprefixtag:#2\endcsname} +% +% this delays the aliasing so that we can switch maillanguage in between + \def\lang_labels_text_prefix_copy_pair_indeed#1[#2,#3]% - {\expandafter\let - \csname\??label\currenttextprefixclass:\currenttextprefixtag:#1\expandafter\endcsname - \csname\??label\currenttextprefixclass:\currenttextprefixtag:#2\endcsname} + {\expandafter\edef\csname\??label\currenttextprefixclass:#1\endcsname + {{\noexpand\csname\??label\currenttextprefixclass:\noexpand\reallanguagetag\noexpand\currentmainlanguage:#2\endcsname}{}}} \definelabelclass [head] [0] % titles \definelabelclass [label] [0] % texts diff --git a/tex/context/base/mkiv/lang-mis.mkiv b/tex/context/base/mkiv/lang-mis.mkiv index eb7dc7d80..3ec29a782 100644 --- a/tex/context/base/mkiv/lang-mis.mkiv +++ b/tex/context/base/mkiv/lang-mis.mkiv @@ -145,7 +145,11 @@ %D modules these can be tuned by a setup command. Watch the (maybe) better looking %D compound hyphen. -\ifx\compoundhyphen \undefined \unexpanded\def\compoundhyphen {\hbox{-\kern-.25ex-}} \fi +% hm why ex + +\ifx\compoundhyphen \undefined + \unexpanded\def\compoundhyphen {\hbox{-\kern-.10775\emwidth-}} % .25\exheight +\fi %D The last two variables are needed for subsentences |<|like this one|>| which we %D did not yet mention. We want to enable breaking but at the same time don't want @@ -156,7 +160,8 @@ \ifx\postwordbreak\undefined \unexpanded\def\postwordbreak {\penalty\zerocount \hskip\zeropoint\relax} \fi \ifx\hspaceamount \undefined \def\hspaceamount#1#2{.16667\emwidth} \fi % language specific -\unexpanded\def\permithyphenation{\ifhmode\prewordbreak\fi} % doesn't remove spaces +%unexpanded\def\permithyphenation{\ifhmode\prewordbreak\fi} % doesn't remove spaces +\unexpanded\def\permithyphenation{\ifhmode\wordboundary\fi} % doesn't remove spaces %D \macros %D {beginofsubsentence,endofsubsentence, @@ -202,22 +207,21 @@ \setnewconstant\discretionarymode\plusone -\unexpanded\def\ignorediscretionaries - {\discretionarymode\zerocount} +\unexpanded\def\ignorediscretionaries{\discretionarymode\zerocount} +\unexpanded\def\obeydiscretionaries {\discretionarymode\plusone} \def\lang_discretionaries_command {% if direct if, we need \relax for lookahead in math mode \csname\??discretionarymode \ifcase\discretionarymode - n% \csstring\lang_discretionaries_process_none + n% \else\ifmmode - m% \csstring\lang_discretionaries_process_math + m% \else - t% \csstring\lang_discretionaries_process_text + t% \fi\fi \endcsname} -% \def\lang_discretionaries_process_none#1% \setvalue{\??discretionarymode n}#1% {\detokenize{#1}} @@ -230,19 +234,22 @@ \newconditional\punctafterdiscretionary \newconditional\spaceafterdiscretionary -\def\lang_discretionaries_check_before +\def\lang_discretionaries_check_before %i sused grouped {\ifvmode \dontleavehmode \fi \ifhmode - \begingroup - \setbox\scratchbox\lastbox - \ifzeropt\wd\scratchbox - \let\postwordbreak\prewordbreak - \fi - \box\scratchbox\relax - \endgroup - \fi} + %\begingroup + %\setbox\scratchbox\lastbox + %\ifzeropt\wd\scratchbox + % \box\scratchbox\relax + % \endgroup + % \let\postwordbreak\prewordbreak + %\else + % \box\scratchbox\relax + % \endgroup + %\fi + \fi} \def\lang_discretionaries_check_after {\setfalse\punctafterdiscretionary @@ -254,10 +261,8 @@ \ifx :\nextnext \settrue \punctafterdiscretionary \else \ifx ;\nextnext \settrue \punctafterdiscretionary \fi\fi\fi\fi\fi\fi} -%let\lang_discretionaries_process_math\handlemathmodediscretionary \letvalue{\??discretionarymode m}\handlemathmodediscretionary -% \def\lang_discretionaries_process_text#1% grouped ! \setvalue{\??discretionarymode t}#1% {\bgroup \let\nextnextnext\egroup @@ -278,39 +283,47 @@ \ifcsname\??discretionaryaction\string#1\endcsname \lastnamedcs \else\ifconditional\spaceafterdiscretionary - \prewordbreak\hbox{\string#1}\relax + %\prewordbreak\hbox{\string#1}\relax + \wordboundary\hbox{\string#1}\relax \else\ifconditional\punctafterdiscretionary - \prewordbreak\hbox{\string#1}\relax + %\prewordbreak\hbox{\string#1}\relax + \wordboundary\hbox{\string#1}\wordboundary \else - \prewordbreak\hbox{\string#1}\prewordbreak + %\prewordbreak\hbox{\string#1}\prewordbreak + \wordboundary\hbox{\string#1}\wordboundary \fi\fi\fi \def\nextnextnext{\afterassignment\egroup\let\next=}% \else \lang_discretionaries_check_before % the next line has been changed (20050203) - % \prewordbreak\hbox{\textmodediscretionary\nextnext}\allowbreak\postwordbreak + % \prewordbreak\hbox{\textmodediscretionary\nextnext}\postwordbreak % but an hbox blocks a possible \discretionary \ifcsname\??discretionaryaction\endcsname \lastnamedcs \else\ifconditional\spaceafterdiscretionary - \prewordbreak\textmodediscretionary\relax + %\prewordbreak\textmodediscretionary\relax + \wordboundary\textmodediscretionary\relax \else\ifconditional\punctafterdiscretionary - \prewordbreak\textmodediscretionary\relax + %\prewordbreak\textmodediscretionary\relax + \wordboundary\textmodediscretionary\relax \else - \prewordbreak\textmodediscretionary\prewordbreak + %\prewordbreak\textmodediscretionary\prewordbreak + \wordboundary\textmodediscretionary\wordboundary \fi\fi\fi - % \prewordbreak\textmodediscretionary\nextnext\allowbreak\postwordbreak \fi \else\ifcsname\??discretionaryaction\discretionarytoken\endcsname \lastnamedcs \else \lang_discretionaries_check_before \ifconditional\spaceafterdiscretionary - \prewordbreak\hbox{#2}\relax + %\prewordbreak\hbox{#2}\relax + \wordboundary\hbox{#2}\relax \else\ifconditional\punctafterdiscretionary - \prewordbreak\hbox{#2}\relax + %\prewordbreak\hbox{#2}\relax + \wordboundary\hbox{#2}\relax \else - \prewordbreak\discretionary{\hbox{#2}}{}{\hbox{#2}}\allowbreak\postwordbreak + %\prewordbreak\discretionary{\hbox{#2}}{}{\hbox{#2}}\postwordbreak + \wordboundary\discretionary{\hbox{#2}}{}{\hbox{#2}}\wordboundary \fi\fi \fi\fi \nextnextnext} @@ -324,35 +337,33 @@ \unexpanded\def\directdiscretionary {\csname\??discretionarymode \ifcase\discretionarymode - n% \csstring\lang_discretionaries_process_none + n% \else - d% \csstring\lang_discretionaries_process_direct + d% \fi \endcsname} \unexpanded\def\indirectdiscretionary {\csname\??discretionarymode \ifcase\discretionarymode - n% \csstring\lang_discretionaries_process_none + n% \else - i% \csstring\lang_discretionaries_process_indirect + i% \fi \endcsname} -% \unexpanded\def\lang_discretionaries_process_direct#1% \setuvalue{\??discretionarymode d}#1% {\edef\discretionarytoken{\detokenize{#1}}% \let\textmodediscretionary\compoundhyphen - %\executeifdefined{\??discretionaryaction\discretionarytoken}{\indirectdiscretionary{#1}}} \ifcsname\??discretionaryaction\discretionarytoken\endcsname \expandafter\lastnamedcs \else \expandafter\indirectdiscretionary \fi{#1}} -% \unexpanded\unexpanded\def\lang_discretionaries_process_indirect#1% \setuvalue{\??discretionarymode i}#1% - {\prewordbreak\discretionary{\hbox{#1}}{}{\hbox{#1}}\allowbreak\postwordbreak} + %{\prewordbreak\discretionary{\hbox{#1}}{}{\hbox{#1}}\postwordbreak} + {\wordboundary\discretionary{\hbox{#1}}{}{\hbox{#1}}\wordboundary} \unexpanded\def\definetextmodediscretionary #1 {\setvalue{\??discretionaryaction\detokenize{#1}}} @@ -376,11 +387,14 @@ \def\lang_discretionaries_hyphen_like#1#2% {\ifconditional\spaceafterdiscretionary - \prewordbreak\hbox{#1}\relax + %prewordbreak\hbox{#1}\relax + \wordboundary\hbox{#1}\relax \else\ifconditional\punctafterdiscretionary - \prewordbreak\hbox{#1}\relax + %prewordbreak\hbox{#1}\relax + \wordboundary\hbox{#1}\relax \else - \prewordbreak#2\postwordbreak % was prewordbreak + %\prewordbreak#2\postwordbreak % was prewordbreak + \wordboundary#2\wordboundary \fi\fi} \definetextmodediscretionary {} @@ -397,59 +411,65 @@ \definetextmodediscretionary ( {\ifdim\lastskip>\zeropoint - (\prewordbreak + %(\prewordbreak + (\wordboundary \else - \prewordbreak\discretionary{}{(-}{(}\prewordbreak + %\prewordbreak\discretionary{}{(-}{(}\prewordbreak + \wordboundary\discretionary{}{(-}{(}\wordboundary \fi} \definetextmodediscretionary ~ - {\prewordbreak\discretionary{-}{}{\thinspace}\postwordbreak} + %{\prewordbreak\discretionary{-}{}{\thinspace}\postwordbreak} + {\wordboundary\discretionary{-}{}{\thinspace}\wordboundary} \definetextmodediscretionary ' - {\prewordbreak\discretionary{-}{}{'}\postwordbreak} + %{\prewordbreak\discretionary{-}{}{'}\postwordbreak} + {\wordboundary\discretionary{-}{}{'}\wordboundary} \definetextmodediscretionary ^ - {\prewordbreak\discretionary{\hbox{\normalstartimath|\normalstopimath}}{}{\hbox{\normalstartimath|\normalstopimath}}% - \allowbreak\postwordbreak} % bugged - -% \definetextmodediscretionary < -% {\beginofsubsentence\prewordbreak\beginofsubsentencespacing} -% -% \definetextmodediscretionary > -% {\endofsubsentencespacing\prewordbreak\endofsubsentence} -% -% \definetextmodediscretionary = -% {\prewordbreak\midsentence\prewordbreak} + %{\prewordbreak\discretionary{\hbox{\normalstartimath|\normalstopimath}}{}{\hbox{\normalstartimath|\normalstopimath}}% + % \postwordbreak} % bugged + {\wordboundary\discretionary{\hbox{\normalstartimath|\normalstopimath}}{}{\hbox{\normalstartimath|\normalstopimath}}% + \wordboundary} % bugged \definetextmodediscretionary < - {\beginofsubsentence\prewordbreak\beginofsubsentencespacing + %{\beginofsubsentence\prewordbreak\beginofsubsentencespacing + {\beginofsubsentence\wordboundary\beginofsubsentencespacing \aftergroup\ignorespaces} % tricky, we need to go over the \nextnextnext \definetextmodediscretionary > {\removeunwantedspaces - \endofsubsentencespacing\prewordbreak\endofsubsentence} + %\endofsubsentencespacing\prewordbreak\endofsubsentence} + \endofsubsentencespacing\wordboundary\endofsubsentence} \definetextmodediscretionary = {\removeunwantedspaces - \prewordbreak\midsentence\prewordbreak + %\prewordbreak\midsentence\prewordbreak + \wordboundary\midsentence\wordboundary \aftergroup\ignorespaces} % french -\definetextmodediscretionary : {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{:}:} -\definetextmodediscretionary ; {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{;};} -\definetextmodediscretionary ? {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{?}?} -\definetextmodediscretionary ! {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{!}!} +%definetextmodediscretionary : {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{:}:} +%definetextmodediscretionary ; {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{;};} +%definetextmodediscretionary ? {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{?}?} +%definetextmodediscretionary ! {\removeunwantedspaces\prewordbreak\kern\hspaceamount\empty{!}!} + +\definetextmodediscretionary : {\removeunwantedspaces\wordboundary\kern\hspaceamount\empty{:}:} +\definetextmodediscretionary ; {\removeunwantedspaces\wordboundary\kern\hspaceamount\empty{;};} +\definetextmodediscretionary ? {\removeunwantedspaces\wordboundary\kern\hspaceamount\empty{?}?} +\definetextmodediscretionary ! {\removeunwantedspaces\wordboundary\kern\hspaceamount\empty{!}!} -\definetextmodediscretionary * - {\prewordbreak\discretionary{-}{}{\kern.05em}\prewordbreak} +%definetextmodediscretionary * {\prewordbreak\discretionary{-}{}{\kern.05\emwidth}\prewordbreak} +\definetextmodediscretionary * {\wordboundary\discretionary{-}{}{\kern.05\emwidth}\wordboundary} % spanish -\definetextmodediscretionary ?? {\prewordbreak\questiondown} -\definetextmodediscretionary !! {\prewordbreak\exclamdown} +%definetextmodediscretionary ?? {\prewordbreak\questiondown} +%definetextmodediscretionary !! {\prewordbreak\exclamdown} -% \ifx\normalcompound\undefined \let\normalcompound=| \fi +\definetextmodediscretionary ?? {\wordboundary\questiondown} +\definetextmodediscretionary !! {\wordboundary\exclamdown} %D \installdiscretionary | + %D \installdiscretionary + = diff --git a/tex/context/base/mkiv/lang-rep.lua b/tex/context/base/mkiv/lang-rep.lua index a5c4d97c8..93509d82a 100644 --- a/tex/context/base/mkiv/lang-rep.lua +++ b/tex/context/base/mkiv/lang-rep.lua @@ -42,8 +42,6 @@ local report_replacement = logs.reporter("languages","replacements") local glyph_code = nodes.nodecodes.glyph local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev @@ -217,9 +215,7 @@ local function tonodes(list,template) end function replacements.handler(head) - head = tonut(head) local current = head - local done = false local overload = attributes.applyoverloads while current do if getid(current) == glyph_code then @@ -327,14 +323,13 @@ function replacements.handler(head) if overload then overload(final,getnext(precurrent),getprev(current)) end - done = true end end end -- we're one ahead now but we need to because we handle words current = getnext(current) end - return tonode(head), done + return head end local enabled = false diff --git a/tex/context/base/mkiv/lang-spa.mkiv b/tex/context/base/mkiv/lang-spa.mkiv index e7cb0025f..7109ad051 100644 --- a/tex/context/base/mkiv/lang-spa.mkiv +++ b/tex/context/base/mkiv/lang-spa.mkiv @@ -41,17 +41,15 @@ %D Alternative discretionary handlers: -\definetextmodediscretionary : - {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{:}:} +%definetextmodediscretionary : {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{:}:} +%definetextmodediscretionary ; {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{;};} +%definetextmodediscretionary ? {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{?}?} +%definetextmodediscretionary ! {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{!}!} -\definetextmodediscretionary ; - {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{;};} - -\definetextmodediscretionary ? - {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{?}?} - -\definetextmodediscretionary ! - {\removeunwantedspaces\prewordbreak\kern\hspaceamount\currentlanguage{!}!} +\definetextmodediscretionary : {\removeunwantedspaces\wordboundary\kern\hspaceamount\currentlanguage{:}:} +\definetextmodediscretionary ; {\removeunwantedspaces\wordboundary\kern\hspaceamount\currentlanguage{;};} +\definetextmodediscretionary ? {\removeunwantedspaces\wordboundary\kern\hspaceamount\currentlanguage{?}?} +\definetextmodediscretionary ! {\removeunwantedspaces\wordboundary\kern\hspaceamount\currentlanguage{!}!} %D \startbuffer %D \mainlanguage[en] \quotation{test \quotation{test} test}\par diff --git a/tex/context/base/mkiv/lang-txt.lua b/tex/context/base/mkiv/lang-txt.lua index b1f50bc80..d287f7e6d 100644 --- a/tex/context/base/mkiv/lang-txt.lua +++ b/tex/context/base/mkiv/lang-txt.lua @@ -25,6 +25,7 @@ if not modules then modules = { } end modules ['lang-txt'] = { -- de German Tobias Burnus, ... -- en English Hans Hagen, ... -- es Spanish Andrés Montoya, ... +-- et Estonian Clyde Johnston -- fi Finish ... -- fr French Daniel Flipo, Arthur Reutenauer -- gr Greek Apostolos Syropoulos, Thomas Schmitz @@ -86,6 +87,7 @@ data.labels={ ["labels"]={ ["de"]="Band", ["en"]="Volume", + ["et"]="Köide", ["nl"]="Deel", ["pe"]="جلد", }, @@ -95,6 +97,7 @@ data.labels={ ["de"]="und", ["en"]="and", ["es"]="y", + ["et"]="ja", ["fr"]="et", ["it"]="e", ["nl"]="en", @@ -106,6 +109,7 @@ data.labels={ ["de"]="Auflage", ["en"]="edition", ["es"]="edición", + ["et"]="väljaanne", ["fr"]="édition", ["it"]="edizione", ["nl"]="editie", @@ -116,6 +120,7 @@ data.labels={ ["labels"]={ ["de"]="Herausgeber", ["en"]="editor", + ["et"]="toimetaja", ["fr"]="éditeur", ["it"]="a cura di", ["pe"]="ویراستار", @@ -126,6 +131,7 @@ data.labels={ ["de"]="Herausgeber", ["en"]="editors", ["es"]="editores", + ["et"]="toimetajad", ["fr"]="éditeurs", ["it"]="a cura di", }, @@ -143,6 +149,7 @@ data.labels={ ["de"]="Masterarbeit", ["en"]="Master's thesis", ["es"]="Tesis de maestría", + ["et"]="magistritöö", ["fr"]="Thèse de master (DEA, DESS, master)", ["it"]="Tesi di laurea", ["nl"]="Masterproef", @@ -169,12 +176,14 @@ data.labels={ ["others"]={ ["labels"]={ ["en"]="et al.", + ["et"]="jt", }, }, ["p"]={ ["labels"]={ ["de"]="S.", ["en"]="p.", + ["et"]="lk", ["pe"]="ص", }, }, @@ -182,6 +191,7 @@ data.labels={ ["labels"]={ ["de"]="Seiten", ["en"]="pages", + ["et"]="leheküljed", ["nl"]="paginas", ["pe"]="صفحات", }, @@ -191,6 +201,7 @@ data.labels={ ["de"]="Patent", ["en"]="Patent", ["es"]="Patente", + ["et"]="Patent", ["fr"]="Brevet", ["it"]="Brevetto", ["nl"]="Octrooi", @@ -201,6 +212,7 @@ data.labels={ ["de"]="Dissertation", ["en"]="PhD thesis", ["es"]="Tesis doctoral", + ["et"]="doktoritöö", ["fr"]="Thèse de doctorat", ["it"]="Tesi di dottorato", ["nl"]="Proefschrift", @@ -211,6 +223,7 @@ data.labels={ ["labels"]={ ["de"]="S.", ["en"]="pp.", + ["et"]="lk-d", ["pe"]="صص", }, }, @@ -219,6 +232,7 @@ data.labels={ ["de"]="Technischer Bericht", ["en"]="Technical report", ["es"]="Informe técnico", + ["et"]="tehniline raport", ["fr"]="Rapport technique", ["it"]="Relazione tecnica", ["nl"]="Technisch rapport", @@ -229,6 +243,7 @@ data.labels={ ["labels"]={ ["de"]="Band", ["en"]="volume", + ["et"]="köide", ["nl"]="deel", ["pe"]="جلد", }, @@ -238,6 +253,7 @@ data.labels={ ["de"]="mit", ["en"]="with", ["es"]="con", + ["et"]="koos", ["fr"]="avec", ["it"]="con", ["nl"]="met", @@ -615,28 +631,29 @@ data.labels={ ["labels"]={ ["af"]="", ["ca"]="", - ["cs"]="a", + ["cs"]=" a ", ["da"]="", - ["de"]="und", - ["en"]="and", - ["es"]="y", + ["de"]=" und ", + ["en"]=" and ", + ["es"]=" y ", + ["et"]=" ja ", ["fi"]="", ["fr"]="", ["gr"]="", - ["hr"]="i", - ["hu"]="és", + ["hr"]=" i ", + ["hu"]=" és ", ["it"]="", ["la"]="", ["lt"]="", ["nb"]="", - ["nl"]="en", + ["nl"]=" en ", ["nn"]="", - ["pe"]="و", - ["pl"]="i", + ["pe"]=" و ", + ["pl"]=" i ", ["pt"]="", ["ro"]="", ["ru"]="", - ["sk"]="a", + ["sk"]=" a ", ["sl"]="", ["sv"]="", ["tk"]="", @@ -657,6 +674,7 @@ data.labels={ ["de"]="Anhang ", ["en"]="Appendix ", ["es"]="Apéndice ", + ["et"]="Lisa ", ["fi"]="", ["fr"]="Annexe ", ["gr"]="Παράρτημα", @@ -697,6 +715,7 @@ data.labels={ ["de"]="April", ["en"]="April", ["es"]="abril", + ["et"]="aprill", ["fi"]="huhtikuu", ["fr"]="avril", ["gr"]="Απρίλιος", @@ -739,6 +758,7 @@ data.labels={ ["de"]="", ["en"]="apr", ["es"]="abr.", + ["et"]="apr", ["fi"]="", ["fr"]="", ["gr"]="", @@ -773,6 +793,7 @@ data.labels={ ["de"]="auf Seite ", ["en"]="at page ", ["es"]="en la página ", + ["et"]="leheküljel ", ["fi"]="", ["fr"]="à la page ", ["gr"]="", @@ -812,6 +833,7 @@ data.labels={ ["de"]="August", ["en"]="August", ["es"]="agosto", + ["et"]="august", ["fi"]="elokuu", ["fr"]="août", ["gr"]="Αύγουστος", @@ -854,6 +876,7 @@ data.labels={ ["de"]="", ["en"]="aug", ["es"]="ago.", + ["et"]="aug", ["fi"]="", ["fr"]="", ["gr"]="", @@ -890,6 +913,7 @@ data.labels={ ["de"]="Kapitel ", ["en"]="Chapter ", ["es"]="Capítulo ", + ["et"]="Peatükk ", ["fi"]="", ["fr"]="Chapitre ", ["gr"]="Κεφάλαιο", @@ -926,6 +950,7 @@ data.labels={ ["de"]="", ["en"]=" (continued)", ["es"]=" (continúa)", + ["et"]=" (jätkub)", ["fi"]="", ["fr"]="", ["gr"]="", @@ -954,6 +979,7 @@ data.labels={ ["day"]={ ["labels"]={ ["en"]="day", + ["et"]="päev", ["kr"]="일", ["nl"]="dag", ["pe"]="روز", @@ -972,6 +998,7 @@ data.labels={ ["de"]="Dezember", ["en"]="December", ["es"]="diciembre", + ["et"]="detsember", ["fi"]="joulukuu", ["fr"]="décembre", ["gr"]="Δεκέμβριος", @@ -1014,6 +1041,7 @@ data.labels={ ["de"]="", ["en"]="dec", ["es"]="dic.", + ["et"]="dets", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1051,6 +1079,7 @@ data.labels={ ["de"]="Februar", ["en"]="February", ["es"]="febrero", + ["et"]="veebruar", ["fi"]="helmikuu", ["fr"]="février", ["gr"]="Φεβρουάριος", @@ -1093,6 +1122,7 @@ data.labels={ ["de"]="", ["en"]="feb", ["es"]="feb.", + ["et"]="veebr", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1128,6 +1158,7 @@ data.labels={ ["de"]="Abbildung ", ["en"]="Figure ", ["es"]="Figura ", + ["et"]="Joonis ", ["fi"]="Kuva ", ["fr"]="Figure ", ["gr"]="Σχήμα", @@ -1158,6 +1189,7 @@ data.labels={ ["followingpage"]={ ["labels"]={ ["en"]="on a following page", + ["et"]="järgmisel leheküljel", ["nl"]="op een volgende bladzijde", ["pe"]="در صفحات آینده", }, @@ -1173,6 +1205,7 @@ data.labels={ ["de"]="Freitag", ["en"]="Friday", ["es"]="viernes", + ["et"]="reede", ["fi"]="perjantai", ["fr"]="vendredi", ["gr"]="Παρασκευή", @@ -1211,6 +1244,7 @@ data.labels={ ["de"]="Graphik ", ["en"]="Graphic ", ["es"]="Gráfico ", + ["et"]="Pilt ", ["fi"]="Grafiikka ", ["fr"]="Illustration ", ["gr"]="Γραφικό", @@ -1247,6 +1281,7 @@ data.labels={ ["de"]="siehe oben", ["en"]="as we show above", ["es"]="como se muestra arriba", + ["et"]="nii nagu üleval näidatud", ["fi"]="", ["fr"]="ci-dessus", ["gr"]="", @@ -1283,6 +1318,7 @@ data.labels={ ["de"]="siehe unten", ["en"]="as we show below", ["es"]="como se muestra abajo", + ["et"]="nii nagu all näidatud", ["fi"]="", ["fr"]="ci-dessous", ["gr"]="", @@ -1320,6 +1356,7 @@ data.labels={ ["de"]="Intermezzo ", ["en"]="Intermezzo ", ["es"]="Intermedio ", + ["et"]="Vahemäng ", ["fi"]="Intermezzo ", ["fr"]="Intermède ", ["gr"]="Παύση", @@ -1359,6 +1396,7 @@ data.labels={ ["de"]="Januar", ["en"]="January", ["es"]="enero", + ["et"]="jaanuar", ["fi"]="tammikuu", ["fr"]="janvier", ["gr"]="Ιανουάριος", @@ -1401,6 +1439,7 @@ data.labels={ ["de"]="", ["en"]="jan", ["es"]="ene.", + ["et"]="jaan", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1439,6 +1478,7 @@ data.labels={ ["de"]="Juli", ["en"]="July", ["es"]="julio", + ["et"]="juuli", ["fi"]="heinäkuu", ["fr"]="juillet", ["gr"]="Ιούλιος", @@ -1481,6 +1521,7 @@ data.labels={ ["de"]="", ["en"]="jul", ["es"]="jul.", + ["et"]="juuli", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1518,6 +1559,7 @@ data.labels={ ["de"]="Juni", ["en"]="June", ["es"]="junio", + ["et"]="juuni", ["fi"]="kesäkuu", ["fr"]="juin", ["gr"]="Ιούνιος", @@ -1560,6 +1602,7 @@ data.labels={ ["de"]="", ["en"]="jun", ["es"]="jun.", + ["et"]="juuni", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1595,6 +1638,7 @@ data.labels={ ["de"]="Zeile ", ["en"]="line ", ["es"]="línea ", + ["et"]="joon ", ["fi"]="rivi ", ["fr"]="ligne ", ["gr"]="Γραμμή", @@ -1633,6 +1677,7 @@ data.labels={ ["de"]="Zeilen ", ["en"]="lines ", ["es"]="líneas ", + ["et"]="jooned ", ["fi"]="rivie ", ["fr"]="lignes ", ["gr"]="Γραμμές", @@ -1672,6 +1717,7 @@ data.labels={ ["de"]="März", ["en"]="March", ["es"]="marzo", + ["et"]="märts", ["fi"]="maaliskuu", ["fr"]="mars", ["gr"]="Μάρτιος", @@ -1714,6 +1760,7 @@ data.labels={ ["de"]="", ["en"]="mar", ["es"]="mar.", + ["et"]="märts", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1752,6 +1799,7 @@ data.labels={ ["de"]="Mai", ["en"]="May", ["es"]="mayo", + ["et"]="mai", ["fi"]="toukokuu", ["fr"]="mai", ["gr"]="Μάιος", @@ -1794,6 +1842,7 @@ data.labels={ ["de"]="", ["en"]="may", ["es"]="may.", + ["et"]="mai", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1829,6 +1878,7 @@ data.labels={ ["de"]="Montag", ["en"]="Monday", ["es"]="lunes", + ["et"]="esmaspäev", ["fi"]="maanantai", ["fr"]="lundi", ["gr"]="Δευτέρα", @@ -1859,6 +1909,7 @@ data.labels={ ["month"]={ ["labels"]={ ["en"]="month", + ["et"]="kuu", ["kr"]="월", ["nl"]="maand", ["pe"]="ماه", @@ -1877,6 +1928,7 @@ data.labels={ ["de"]="November", ["en"]="November", ["es"]="noviembre", + ["et"]="november", ["fi"]="marraskuu", ["fr"]="novembre", ["gr"]="Νοέμβριος", @@ -1919,6 +1971,7 @@ data.labels={ ["de"]="", ["en"]="nov", ["es"]="nov.", + ["et"]="nov", ["fi"]="", ["fr"]="", ["gr"]="", @@ -1955,6 +2008,7 @@ data.labels={ ["de"]="Oktober", ["en"]="October", ["es"]="octubre", + ["et"]="oktoober", ["fi"]="lokakuu", ["fr"]="octobre", ["gr"]="Οκτώβριος", @@ -1997,6 +2051,7 @@ data.labels={ ["de"]="", ["en"]="oct", ["es"]="oct.", + ["et"]="okt", ["fi"]="", ["fr"]="", ["gr"]="", @@ -2031,6 +2086,7 @@ data.labels={ ["de"]="Seite ", ["en"]="page ", ["es"]="página ", + ["et"]="lehekülg ", ["fi"]="", ["fr"]="page ", ["gr"]="", @@ -2068,6 +2124,7 @@ data.labels={ ["de"]="Teil ", ["en"]="Part ", ["es"]="Parte ", + ["et"]="Osa ", ["fi"]="Osa ", ["fr"]="Partie ", ["gr"]="Μέρος", @@ -2098,6 +2155,7 @@ data.labels={ ["precedingpage"]={ ["labels"]={ ["en"]="on a preceding page", + ["et"]="eelmisel lehel", ["nl"]="op een voorgaande bladzijde", ["pe"]="در صفحات گذشته", }, @@ -2113,6 +2171,7 @@ data.labels={ ["de"]="Samstag", ["en"]="Saturday", ["es"]="sábado", + ["et"]="laupäev", ["fi"]="lauantai", ["fr"]="samedi", ["gr"]="Σάββατο", @@ -2152,6 +2211,7 @@ data.labels={ ["de"]="", ["en"]="", ["es"]="Sección ", + ["et"]="jaos ", ["fi"]="", ["fr"]="Section ", ["gr"]="Ενότητα", @@ -2189,6 +2249,7 @@ data.labels={ ["de"]="siehe ", ["en"]="see ", ["es"]="ver: ", + ["et"]="vaadake ", ["fi"]="", ["fr"]="cf. ", ["gr"]="", @@ -2228,6 +2289,7 @@ data.labels={ ["de"]="September", ["en"]="September", ["es"]="septiembre", + ["et"]="september", ["fi"]="syyskuu", ["fr"]="septembre", ["gr"]="Σεπτέμβριος", @@ -2270,6 +2332,7 @@ data.labels={ ["de"]="", ["en"]="sep", ["es"]="sep.", + ["et"]="sept", ["fi"]="", ["fr"]="", ["gr"]="", @@ -2306,6 +2369,7 @@ data.labels={ ["de"]="", ["en"]="", ["es"]="Subsección ", + ["et"]="alajaotis ", ["fi"]="", ["fr"]="Soussection ", ["gr"]="Υπόενότητα", @@ -2344,6 +2408,7 @@ data.labels={ ["de"]="", ["en"]="", ["es"]="Subsubsección ", + ["et"]="alamjaotis ", ["fi"]="", ["fr"]="Soussoussection ", ["gr"]="", @@ -2382,6 +2447,7 @@ data.labels={ ["de"]="", ["en"]="", ["es"]="Subsubsubsección ", + ["et"]="", ["fi"]="", ["fr"]="Soussoussoussection ", ["gr"]="", @@ -2419,6 +2485,7 @@ data.labels={ ["de"]="Sonntag", ["en"]="Sunday", ["es"]="domingo", + ["et"]="pühapäev", ["fi"]="sunnuntai", ["fr"]="dimanche", ["gr"]="Κυριακή", @@ -2457,6 +2524,7 @@ data.labels={ ["de"]="Tabelle ", ["en"]="Table ", ["es"]="Tabla ", + ["et"]="Tabel ", ["fi"]="Taulukko ", ["fr"]="Tableau ", ["gr"]="Πίνακας", @@ -2495,6 +2563,7 @@ data.labels={ ["de"]="Donnerstag", ["en"]="Thursday", ["es"]="jueves", + ["et"]="neljapäev", ["fi"]="torstai", ["fr"]="jeudi", ["gr"]="Πέμπτη", @@ -2533,6 +2602,7 @@ data.labels={ ["de"]="Dienstag", ["en"]="Tuesday", ["es"]="martes", + ["et"]="teisipäev", ["fi"]="tiistai", ["fr"]="mardi", ["gr"]="Τρίτη", @@ -2571,6 +2641,7 @@ data.labels={ ["de"]="Mittwoch", ["en"]="Wednesday", ["es"]="miércoles", + ["et"]="kolmapäev", ["fi"]="keskiviikko", ["fr"]="mercredi", ["gr"]="Τετάρτη", @@ -2601,6 +2672,7 @@ data.labels={ ["year"]={ ["labels"]={ ["en"]="year", + ["et"]="aasta", ["kr"]="년", ["nl"]="jaar", ["pe"]="سال", @@ -2619,6 +2691,7 @@ data.labels={ ["de"]="Abkürzungen", ["en"]="Abbreviations", ["es"]="Abreviaturas", + ["et"]="Lühend", ["fi"]="Lyhennyksi", ["fr"]="Abréviations", ["gr"]="Συντομογραφίες", @@ -2657,6 +2730,7 @@ data.labels={ ["de"]="Inhalt", ["en"]="Contents", ["es"]="Contenido", + ["et"]="Sisu", ["fi"]="Sisällys", ["fr"]="Table des matières", ["gr"]="Περιεχόμενα", @@ -2695,6 +2769,7 @@ data.labels={ ["de"]="Abbildungen", ["en"]="Figures", ["es"]="Figuras", + ["et"]="Arvandmed", ["fi"]="Kuvi", ["fr"]="Figures", ["gr"]="Σχήματα", @@ -2733,6 +2808,7 @@ data.labels={ ["de"]="Graphiken", ["en"]="Graphics", ["es"]="Gráficos", + ["et"]="Graafika", ["fi"]="Grafiikkaoi", ["fr"]="Graphiques", ["gr"]="Γραφικά", @@ -2771,6 +2847,7 @@ data.labels={ ["de"]="Index", ["en"]="Index", ["es"]="Índice", + ["et"]="Indeks", ["fi"]="Indeksiluku", ["fr"]="Index", ["gr"]="Ευρετήριο", @@ -2809,6 +2886,7 @@ data.labels={ ["de"]="Intermezzi", ["en"]="Intermezzos", ["es"]="Intermedios", + ["et"]="Vahemängud", ["fi"]="Intermezzos", ["fr"]="Intermèdes", ["gr"]="Παύσεις", @@ -2846,6 +2924,7 @@ data.labels={ ["de"]="Logos", ["en"]="Logos", ["es"]="Logotipos", + ["et"]="Logos", ["fi"]="Vertauskuva", ["fr"]="Logos", ["gr"]="Λογότυπα", @@ -2882,6 +2961,7 @@ data.labels={ ["de"]="Literatur", ["en"]="References", ["es"]="Bibliografía", + ["et"]="Viited", ["fi"]="", ["fr"]="Bibliographie", ["gr"]="", @@ -2919,6 +2999,7 @@ data.labels={ ["de"]="Tabellen", ["en"]="Tables", ["es"]="Tablas", + ["et"]="Tabelid", ["fi"]="Taulukkoj", ["fr"]="Tableaux", ["gr"]="Πίνακες", @@ -2957,6 +3038,7 @@ data.labels={ ["de"]="Einheiten", ["en"]="Units", ["es"]="Unidades", + ["et"]="Ühikud", ["fi"]="Yksiköt", ["fr"]="Unités", ["gr"]="Μονάδες", diff --git a/tex/context/base/mkiv/lang-url.lua b/tex/context/base/mkiv/lang-url.lua index 95d959206..17ad15cd8 100644 --- a/tex/context/base/mkiv/lang-url.lua +++ b/tex/context/base/mkiv/lang-url.lua @@ -8,7 +8,6 @@ if not modules then modules = { } end modules ['lang-url'] = { local utfcharacters, utfvalues, utfbyte, utfchar = utf.characters, utf.values, utf.byte, utf.char local min, max = math.min, math.max -local concat = table.concat local context = context @@ -77,9 +76,10 @@ urls.righthyphenmin = 3 urls.discretionary = nil urls.packslashes = false -directives.register("hyphenators.urls.packslashes",function(v) - urls.packslashes = v -end) +directives.register("hyphenators.urls.packslashes",function(v) urls.packslashes = v end) + +local trace = false trackers.register("hyphenators.urls",function(v) trace = v end) +local report = logs.reporter("hyphenators","urls") -- local ctx_a = context.a -- local ctx_b = context.b @@ -153,8 +153,10 @@ local function action(hyphenatedurl,str,left,right,disc) local pack = urls.packslashes local length = 0 local list = utf.split(str) + local size = #list + local prev = nil - for i=1,#list do + for i=1,size do local what = nil local dodi = false local char = list[i] @@ -162,7 +164,7 @@ local function action(hyphenatedurl,str,left,right,disc) char = mapping[char] or char if char == disc then dodi = true - elseif pack and char == "/" and list[i+1] == "/" then + elseif pack and char == "/" and (list[i+1] == "/" or prev == "/") then what = "c" else local how = characters[char] @@ -192,9 +194,13 @@ local function action(hyphenatedurl,str,left,right,disc) else list[i] = "\\" .. what .. "{" .. utfbyte(char) .. "}" end + prev = char + end + if trace then + report("old : %s",str) + report("new : %t",list) end - list = concat(list) - context(list) + context("%t",list) end -- urls.action = function(_,...) action(...) end -- sort of obsolete diff --git a/tex/context/base/mkiv/lang-wrd.lua b/tex/context/base/mkiv/lang-wrd.lua index 7363dbb31..9fbced2ce 100644 --- a/tex/context/base/mkiv/lang-wrd.lua +++ b/tex/context/base/mkiv/lang-wrd.lua @@ -31,7 +31,6 @@ local numbers = languages.numbers local registered = languages.registered local nuts = nodes.nuts -local tonut = nuts.tonut ----- getfield = nuts.getfield local getnext = nuts.getnext @@ -43,8 +42,8 @@ local setattr = nuts.setattr local getlang = nuts.getlang local ischar = nuts.ischar -local traverse_nodes = nuts.traverse ------ traverse_ids = nuts.traverse_id +local nextnode = nuts.traversers.node +----- nextglyph = nuts.traversers.glyph local wordsdata = words.data local chardata = characters.data @@ -145,14 +144,13 @@ end -- there is an n=1 problem somewhere in nested boxes local function mark_words(head,whenfound) -- can be optimized and shared - local current, language, done = tonut(head), nil, nil, 0, false + local current, language = head, nil, nil, 0 local str, s, nds, n = { }, 0, { }, 0 -- n could also be a table, saves calls local function action() if s > 0 then local word = concat(str,"",1,s) local mark = whenfound(language,word) if mark then - done = true for i=1,n do mark(nds[i]) end @@ -198,7 +196,7 @@ local function mark_words(head,whenfound) -- can be optimized and shared -- n = n + 1 -- nds[n] = current -- -- - -- for current in traverse_ids(glyph_code,r) do + -- for current in nextglyph, r do -- local code = getchar(current) -- n = n + 1 -- nds[n] = current @@ -217,7 +215,7 @@ local function mark_words(head,whenfound) -- can be optimized and shared if s > 0 then action() end - return head, done + return head end local methods = { } @@ -285,7 +283,7 @@ local function sweep(language,str) end methods[1] = function(head) - for n in traverse_nodes(head) do + for n in nextnode, head do setattr(n,a_color,unsetvalue) -- hm, not that selective (reset color) end return mark_words(head,sweep) @@ -380,7 +378,7 @@ local function sweep(language,str) end methods[3] = function(head) - for n in traverse_nodes(head) do + for n in nextnode, head do setattr(n,a_color,unsetvalue) end return mark_words(head,sweep) diff --git a/tex/context/base/mkiv/lpdf-ano.lua b/tex/context/base/mkiv/lpdf-ano.lua index 01f015b72..49bf973c9 100644 --- a/tex/context/base/mkiv/lpdf-ano.lua +++ b/tex/context/base/mkiv/lpdf-ano.lua @@ -18,6 +18,7 @@ local rep, format, find = string.rep, string.format, string.find local min = math.min local lpegmatch = lpeg.match local formatters = string.formatters +local sortedkeys = table.sortedkeys local backends, lpdf = backends, lpdf @@ -48,10 +49,6 @@ local nodeinjections = backends.pdf.nodeinjections local codeinjections = backends.pdf.codeinjections local registrations = backends.pdf.registrations -local getpos = codeinjections.getpos -local gethpos = codeinjections.gethpos -local getvpos = codeinjections.getvpos - local javascriptcode = interactions.javascripts.code local references = structures.references @@ -68,12 +65,15 @@ local executers = references.executers local nodepool = nodes.pool ------ pdfannotation_node = nodepool.pdfannotation ------ pdfdestination_node = nodepool.pdfdestination local new_latelua = nodepool.latelua local texgetcount = tex.getcount +local jobpositions = job.positions +local getpos = jobpositions.getpos +local gethpos = jobpositions.gethpos +local getvpos = jobpositions.getvpos + local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array local pdfreference = lpdf.reference @@ -106,6 +106,32 @@ local pdf_fit = pdfconstant("Fit") local pdf_named = pdfconstant("Named") local autoprefix = "#" +local usedautoprefixes = { } + +local function registerautoprefix(name) + local internal = autoprefix .. name + if usedautoprefixes[internal] == nil then + usedautoprefixes[internal] = false + end + return internal +end + +local function useautoprefix(name) + local internal = autoprefix .. name + usedautoprefixes[internal] = true + return internal +end + +local function checkautoprefixes(destinations) + for k, v in next, usedautoprefixes do + if not v then + if trace_destinations then + report_destinations("flushing unused autoprefix %a",k) + end + destinations[k] = nil + end + end +end -- Bah, I hate this kind of features .. anyway, as we have delayed resolving we -- only support a document-wide setup and it has to be set before the first one @@ -113,9 +139,9 @@ local autoprefix = "#" -- thin without dashing lines. This is as far as I'm prepared to go. This way -- it can also be used as a debug feature. -local pdf_border_style = pdfarray { 0, 0, 0 } -- radius radius linewidth -local pdf_border_color = nil -local set_border = false +local pdf_border_style = pdfarray { 0, 0, 0 } -- radius radius linewidth +local pdf_border_color = nil +local set_border = false local function pdfborder() set_border = true @@ -131,7 +157,9 @@ directives.register("references.border",function(v) local c = m and m[v] local v = c and attributes.colors.value(c) if v then - local r, g, b = v[3], v[4], v[5] + local r = v[3] + local g = v[4] + local b = v[5] -- if r == g and g == b then -- pdf_border_color = pdfarray { r } -- reduced, not not ... bugged viewers -- else @@ -192,12 +220,16 @@ local defaultdestination = pdfarray { 0, pdf_fit } -- fit is default (see lpdf-nod) -local destinations = { } -- to be used soon +local destinations = { } +local reported = setmetatableindex("table") local function pdfregisterdestination(name,reference) local d = destinations[name] if d then - report_destinations("ignoring duplicate destination %a with reference %a",name,reference) + if not reported[name][reference] then + report_destinations("ignoring duplicate destination %a with reference %a",name,reference) + reported[name][reference] = true + end else destinations[name] = reference end @@ -222,7 +254,11 @@ end) local function pdfnametree(destinations) local slices = { } - local sorted = table.sortedkeys(destinations) + checkautoprefixes(destinations) + if not next(destinations) then + return + end + local sorted = sortedkeys(destinations) local size = #sorted if size <= 1.5*maxslice then @@ -232,11 +268,12 @@ local function pdfnametree(destinations) for i=1,size,maxslice do local amount = min(i+maxslice-1,size) local names = pdfarray { } + local n = 0 for j=i,amount do local destination = sorted[j] local pagenumber = destinations[destination] - names[#names+1] = tostring(destination) -- tostring is a safeguard - names[#names+1] = pdfreference(pagenumber) + n = n + 1 ; names[n] = tostring(destination) -- tostring is a safeguard + n = n + 1 ; names[n] = pdfreference(pagenumber) end local first = sorted[i] local last = sorted[amount] @@ -254,18 +291,23 @@ local function pdfnametree(destinations) } end local function collectkids(slices,first,last) - local k = pdfarray() - local d = pdfdictionary { - Kids = k, - Limits = pdfarray { - slices[first].limits[1], - slices[last ].limits[2], - }, - } - for i=first,last do - k[#k+1] = slices[i].reference + local f = slices[first] + local l = slices[last] + if f and l then + local k = pdfarray() + local n = 0 + local d = pdfdictionary { + Kids = k, + Limits = pdfarray { + f.limits[1], + l.limits[2], + }, + } + for i=first,last do + n = n + 1 ; k[n] = slices[i].reference + end + return d end - return d end if #slices == 1 then return slices[1].reference @@ -276,14 +318,24 @@ local function pdfnametree(destinations) local size = #slices for i=1,size,maxslice do local kids = collectkids(slices,i,min(i+maxslice-1,size)) - temp[#temp+1] = { - reference = pdfreference(pdfflushobject(kids)), - limits = kids.Limits, - } + if kids then + temp[#temp+1] = { + reference = pdfreference(pdfflushobject(kids)), + limits = kids.Limits, + } + else + -- error + end end slices = temp else - return pdfreference(pdfflushobject(collectkids(slices,1,#slices))) + local kids = collectkids(slices,1,#slices) + if kids then + return pdfreference(pdfflushobject(kids)) + else + -- error + return + end end end end @@ -292,8 +344,9 @@ end local function pdfdestinationspecification() if next(destinations) then -- safeguard local r = pdfnametree(destinations) - -- pdfaddtocatalog("Dests",r) - pdfaddtonames("Dests",r) + if r then + pdfaddtonames("Dests",r) + end if not log_destinations then destinations = nil end @@ -309,14 +362,25 @@ lpdf.registerdocumentfinalizer(pdfdestinationspecification,"collect destinations local destinations = { } -local f_xyz = formatters["<< /D [ %i 0 R /XYZ %0.3F %0.3F null ] >>"] +local f_xyz = formatters["<< /D [ %i 0 R /XYZ %.6F %.6F null ] >>"] local f_fit = formatters["<< /D [ %i 0 R /Fit ] >>"] local f_fitb = formatters["<< /D [ %i 0 R /FitB ] >>"] -local f_fith = formatters["<< /D [ %i 0 R /FitH %0.3F ] >>"] -local f_fitv = formatters["<< /D [ %i 0 R /FitV %0.3F ] >>"] -local f_fitbh = formatters["<< /D [ %i 0 R /FitBH %0.3F ] >>"] -local f_fitbv = formatters["<< /D [ %i 0 R /FitBV %0.3F ] >>"] -local f_fitr = formatters["<< /D [ %i 0 R /FitR %0.3F %0.3F %0.3F %0.3F ] >>"] +local f_fith = formatters["<< /D [ %i 0 R /FitH %.6F ] >>"] +local f_fitv = formatters["<< /D [ %i 0 R /FitV %.6F ] >>"] +local f_fitbh = formatters["<< /D [ %i 0 R /FitBH %.6F ] >>"] +local f_fitbv = formatters["<< /D [ %i 0 R /FitBV %.6F ] >>"] +local f_fitr = formatters["<< /D [ %i 0 R /FitR %.6F %.6F %.6F %.6F ] >>"] + +directives.register("pdf.stripzeros",function() + f_xyz = formatters["<< /D [ %i 0 R /XYZ %.6N %.6N null ] >>"] + f_fit = formatters["<< /D [ %i 0 R /Fit ] >>"] + f_fitb = formatters["<< /D [ %i 0 R /FitB ] >>"] + f_fith = formatters["<< /D [ %i 0 R /FitH %.6N ] >>"] + f_fitv = formatters["<< /D [ %i 0 R /FitV %.6N ] >>"] + f_fitbh = formatters["<< /D [ %i 0 R /FitBH %.6N ] >>"] + f_fitbv = formatters["<< /D [ %i 0 R /FitBV %.6N ] >>"] + f_fitr = formatters["<< /D [ %i 0 R /FitR %.6N %.6N %.6N %.6N ] >>"] +end) local v_standard = variables.standard local v_frame = variables.frame @@ -404,13 +468,15 @@ local pagedestinations = setmetatableindex(function(t,k) -- not the same as the return v end) -local function flushdestination(width,height,depth,names,view) - local r = pdfpagereference(texgetcount("realpageno")) +local function flushdestination(specification) + local names = specification.names + local view = specification.view + local r = pdfpagereference(texgetcount("realpageno")) if (references.innermethod ~= v_name) and (view == defaultview or not view or view == "") then r = pagedestinations[r] else local action = view and destinationactions[view] or defaultaction - r = pdfdelayedobject(action(r,width,height,depth,offset)) + r = pdfdelayedobject(action(r,specification.width,specification.height,specification.depth,offset)) end for n=1,#names do local name = names[n] @@ -459,7 +525,7 @@ function nodeinjections.destination(width,height,depth,names,view) elseif type(name) == "number" then local used = usedinternals[name] usedviews[name] = view - names[n] = autoprefix .. name + names[n] = registerautoprefix(name) doview = true else usedviews[name] = view @@ -479,10 +545,9 @@ function nodeinjections.destination(width,height,depth,names,view) local used = usedinternals[name] if used and used ~= defaultview then usedviews[name] = view - names[n] = autoprefix .. name + names[n] = registerautoprefix(name) doview = true else - -- names[n] = autoprefix .. name names[n] = false end end @@ -493,7 +558,14 @@ function nodeinjections.destination(width,height,depth,names,view) end end if doview then - return new_latelua(function() flushdestination(width,height,depth,names,view) end) + return new_latelua { + action = flushdestination, + width = width, + height = height, + depth = depth, + names = names, + view = view, + } end end @@ -504,7 +576,7 @@ local function pdflinkpage(page) end local function pdflinkinternal(internal,page) - local method = references.innermethod + -- local method = references.innermethod if internal then flaginternals[internal] = true -- for bookmarks and so local used = usedinternals[internal] @@ -512,7 +584,7 @@ local function pdflinkinternal(internal,page) return pagereferences[page] else if type(internal) ~= "string" then - internal = autoprefix .. internal + internal = useautoprefix(internal) end return pdfdictionary { S = pdf_goto, @@ -559,7 +631,7 @@ local function pdffilelink(filename,destination,page,actions) end filename = file.addsuffix(filename,"pdf") if (not destination or destination == "") or (references.outermethod == v_page) then - destination = pdfarray { (page or 0) - 1, pdf_fit } + destination = pdfarray { (page or 1) - 1, pdf_fit } end return pdfdictionary { S = pdf_gotor, -- can also be pdf_launch @@ -635,7 +707,7 @@ local function pdfaction(actions) return nil end end - return first, actions.n + return first, actions.n or #actions end end end @@ -686,9 +758,15 @@ local nofused = 0 local nofspecial = 0 local share = true -local f_annot = formatters["<< /Type /Annot %s /Rect [ %0.3F %0.3F %0.3F %0.3F ] >>"] +local f_annot = formatters["<< /Type /Annot %s /Rect [ %0.6F %0.6F %0.6F %0.6F ] >>"] -directives.register("references.sharelinks", function(v) share = v end) +directives.register("pdf.stripzeros",function() + f_annot = formatters["<< /Type /Annot %s /Rect [ %0.6N %0.6N %0.6N %0.6N ] >>"] +end) + +directives.register("references.sharelinks", function(v) + share = v +end) setmetatableindex(hashed,function(t,k) local v = pdfdelayedobject(k) @@ -699,24 +777,26 @@ setmetatableindex(hashed,function(t,k) return v end) -local function finishreference(width,height,depth,prerolled) -- %0.2f looks okay enough (no scaling anyway) - local annot = hashed[f_annot(prerolled,pdfrectangle(width,height,depth))] +local function finishreference(specification) -- %0.2f looks okay enough (no scaling anyway) + local annot = hashed[f_annot(specification.prerolled,pdfrectangle(specification.width,specification.height,specification.depth))] nofused = nofused + 1 return pdfregisterannotation(annot) end -local function finishannotation(width,height,depth,prerolled,r) +local function finishannotation(specification) + local prerolled = specification.prerolled + local objref = specification.objref if type(prerolled) == "function" then prerolled = prerolled() end - local annot = f_annot(prerolled,pdfrectangle(width,height,depth)) - if r then - pdfdelayedobject(annot,r) + local annot = f_annot(prerolled,pdfrectangle(specification.width,specification.height,specification.depth)) + if objref then + pdfdelayedobject(annot,objref) else - r = pdfdelayedobject(annot) + objref = pdfdelayedobject(annot) end nofspecial = nofspecial + 1 - return pdfregisterannotation(r) + return pdfregisterannotation(objref) end function nodeinjections.reference(width,height,depth,prerolled) @@ -724,17 +804,30 @@ function nodeinjections.reference(width,height,depth,prerolled) if trace_references then report_references("link: width %p, height %p, depth %p, prerolled %a",width,height,depth,prerolled) end - return new_latelua(function() finishreference(width,height,depth,prerolled) end) + return new_latelua { + action = finishreference, + width = width, + height = height, + depth = depth, + prerolled = prerolled, + } end end -function nodeinjections.annotation(width,height,depth,prerolled,r) +function nodeinjections.annotation(width,height,depth,prerolled,objref) if prerolled then if trace_references then report_references("special: width %p, height %p, depth %p, prerolled %a",width,height,depth, type(prerolled) == "string" and prerolled or "-") end - return new_latelua(function() finishannotation(width,height,depth,prerolled,r or false) end) + return new_latelua { + action = finishannotation, + width = width, + height = height, + depth = depth, + prerolled = prerolled, + objref = objref or false, + } end end @@ -757,7 +850,9 @@ pdfregisterannotation = lpdf.registerannotation function lpdf.annotationspecification() if annotations then local r = pdfdelayedobject(tostring(annotations)) -- delayed so okay in latelua - pdfaddtopageattributes("Annots",pdfreference(r)) + if r then + pdfaddtopageattributes("Annots",pdfreference(r)) + end annotations = nil end end @@ -872,16 +967,21 @@ end runners["special operation"] = runners["special"] runners["special operation with arguments"] = runners["special"] +local reported = { } + function specials.internal(var,actions) -- better resolve in strc-ref - local i = tonumber(var.operation) + local o = var.operation + local i = o and tonumber(o) local v = i and references.internals[i] - if not v then - -- error - report_references("no internal reference %a",i or "") - else - flaginternals[i] = true + if v then + flaginternals[i] = true -- also done in pdflinkinternal return pdflinkinternal(i,v.references.realpage) end + local v = i or o or "" + if not reported[v] then + report_references("no internal reference %a",v) + reported[v] = true + end end -- realpage already resolved @@ -946,19 +1046,18 @@ end -- sections --- function specials.section(var,actions) --- local sectionname = var.operation --- local destination = var.arguments --- local internal = structures.sections.internalreference(sectionname,destination) --- if internal then --- var.special = "internal" --- var.operation = internal --- var.arguments = nil --- specials.internal(var,actions) --- end --- end - -specials.section = specials.internal -- specials.section just need to have a value as it's checked +function specials.section(var,actions) + -- a bit duplicate + local sectionname = var.arguments + local destination = var.operation + local internal = structures.sections.internalreference(sectionname,destination) + if internal then + var.special = "internal" + var.operation = internal + var.arguments = nil + return specials.internal(var,actions) + end +end -- todo, do this in references namespace ordered instead (this is an experiment) @@ -1129,7 +1228,8 @@ end local function build(levels,start,parent,method,nested) local startlevel = levels[start].level local noflevels = #levels - local i, n = start, 0 + local i = start + local n = 0 local child, entry, m, prev, first, last, f, l while i and i <= noflevels do local current = levels[i] @@ -1146,11 +1246,12 @@ local function build(levels,start,parent,method,nested) local variant = "unknown" if reftype == "table" then -- we're okay - variant = "list" - block = reference.block + variant = "list" + block = reference.block + realpage = reference.realpage elseif reftype == "string" then local resolved = references.identify("",reference) - local realpage = resolved and structures.references.setreferencerealpage(resolved) or 0 + realpage = resolved and structures.references.setreferencerealpage(resolved) or 0 if realpage > 0 then variant = "realpage" realpage = realpage @@ -1251,7 +1352,6 @@ end function codeinjections.addbookmarks(levels,method) if levels and #levels > 0 then --- inspect(levels) local parent = pdfreserveobject() local _, m, first, last = build(levels,1,pdfreference(parent),method or "internal",false) local dict = pdfdictionary { diff --git a/tex/context/base/mkiv/lpdf-aux.lua b/tex/context/base/mkiv/lpdf-aux.lua new file mode 100644 index 000000000..0d7cecbb8 --- /dev/null +++ b/tex/context/base/mkiv/lpdf-aux.lua @@ -0,0 +1,152 @@ +if not modules then modules = { } end modules ['lpdf-aux'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tonumber = tonumber +local format, concat = string.format, table.concat +local utfchar, utfbyte, char = utf.char, utf.byte, string.char +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local P, C, R, S, Cc, Cs, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs, lpeg.V +local rshift = bit32.rshift + +lpdf = lpdf or { } + +-- tosixteen -- + +local cache = table.setmetatableindex(function(t,k) -- can be made weak + local v = utfbyte(k) + if v < 0x10000 then + v = format("%04x",v) + else + v = format("%04x%04x",rshift(v,10),v%1024+0xDC00) + end + t[k] = v + return v +end) + +local unified = Cs(Cc("")) + +function lpdf.tosixteen(str) -- an lpeg might be faster (no table) + if not str or str == "" then + return "" -- not () as we want an indication that it's unicode + else + return lpegmatch(unified,str) + end +end + +-- fromsixteen -- + +-- local zero = S(" \n\r\t") + P("\\ ") +-- local one = C(4) +-- local two = P("d") * R("89","af") * C(2) * C(4) +-- +-- local pattern = P { "start", +-- start = V("wrapped") + V("unwrapped") + V("original"), +-- original = Cs(P(1)^0), +-- wrapped = P("<") * V("unwrapped") * P(">") * P(-1), +-- unwrapped = P("feff") +-- * Cs( ( +-- zero / "" +-- + two / function(a,b) +-- a = (tonumber(a,16) - 0xD800) * 1024 +-- b = (tonumber(b,16) - 0xDC00) +-- return utfchar(a+b) +-- end +-- + one / function(a) +-- return utfchar(tonumber(a,16)) +-- end +-- )^1 ) * P(-1) +-- } +-- +-- function lpdf.fromsixteen(s) +-- return lpegmatch(pattern,s) or s +-- end + +local more = 0 + +local pattern = C(4) / function(s) -- needs checking ! + local now = tonumber(s,16) + if more > 0 then + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + more = 0 + return utfchar(now) + elseif now >= 0xD800 and now <= 0xDBFF then + more = now + return "" -- else the c's end up in the stream + else + return utfchar(now) + end +end + +local pattern = P(true) / function() more = 0 end * Cs(pattern^0) + +function lpdf.fromsixteen(str) + if not str or str == "" then + return "" + else + return lpegmatch(pattern,str) + end +end + +-- frombytes -- + +local b_pattern = Cs((P("\\")/"" * ( + S("()") + + S("nrtbf")/ { n = "\n", r = "\r", t = "\t", b = "\b", f = "\f" } + + lpegpatterns.octdigit^-3 / function(s) return char(tonumber(s,8)) end) ++ P(1))^0) + +local u_pattern = lpegpatterns.utfbom_16_be * lpegpatterns.utf16_to_utf8_be -- official + + lpegpatterns.utfbom_16_le * lpegpatterns.utf16_to_utf8_le -- we've seen these + +local h_pattern = lpegpatterns.hextobytes + +local zero = S(" \n\r\t") + P("\\ ") +local one = C(4) +local two = P("d") * R("89","af") * C(2) * C(4) + +local x_pattern = P { "start", + start = V("wrapped") + V("unwrapped") + V("original"), + original = Cs(P(1)^0), + wrapped = P("<") * V("unwrapped") * P(">") * P(-1), + unwrapped = P("feff") + * Cs( ( + zero / "" + + two / function(a,b) + a = (tonumber(a,16) - 0xD800) * 1024 + b = (tonumber(b,16) - 0xDC00) + return utfchar(a+b) + end + + one / function(a) + return utfchar(tonumber(a,16)) + end + )^1 ) * P(-1) +} + +function lpdf.frombytes(s,hex) + if not s or s == "" then + return "" + end + if hex then + local x = lpegmatch(x_pattern,s) + if x then + return x + end + local h = lpegmatch(h_pattern,s) + if h then + return h + end + else + local u = lpegmatch(u_pattern,s) + if u then + return u + end + end + return lpegmatch(b_pattern,s) +end + +-- done -- diff --git a/tex/context/base/mkiv/lpdf-col.lua b/tex/context/base/mkiv/lpdf-col.lua index d1a1af97d..b697dc481 100644 --- a/tex/context/base/mkiv/lpdf-col.lua +++ b/tex/context/base/mkiv/lpdf-col.lua @@ -23,7 +23,7 @@ local registrations = backends.pdf.registrations local nodepool = nodes.nuts.pool local register = nodepool.register -local pdfpageliteral = nodepool.pdfpageliteral +local pageliteral = nodepool.pageliteral local pdfconstant = lpdf.constant local pdfdictionary = lpdf.dictionary @@ -64,13 +64,20 @@ local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"] local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"] local f_tr = formatters["Tr%s"] local f_cm = formatters["q %.6F %.6F %.6F %.6F %.6F %.6F cm"] -local f_effect = formatters["%s Tc %s w %s Tr"] +local f_effect = formatters["%s Tc %s w %s Tr"] -- %.3F ? local f_tr_gs = formatters["/Tr%s gs"] local f_num_1 = tostring local f_num_2 = formatters["%s %s"] local f_num_3 = formatters["%s %s %s"] local f_num_4 = formatters["%s %s %s %s"] +directives.register("pdf.stripzeros",function() + f_gray = formatters["%.3N g %.3N G"] + f_rgb = formatters["%.3N %.3N %.3N rg %.3N %.3N %.3N RG"] + f_cmyk = formatters["%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K"] + f_cm = formatters["q %.6N %.6N %.6N %.6N %.6N %.6N cm"] +end) + local report_color = logs.reporter("colors","backend") -- page groups (might move to lpdf-ini.lua) @@ -122,26 +129,26 @@ lpdf.registerpagefinalizer(addpagegroup,3,"pagegroup") -- color injection function nodeinjections.rgbcolor(r,g,b) - return register(pdfpageliteral(f_rgb(r,g,b,r,g,b))) + return register(pageliteral(f_rgb(r,g,b,r,g,b))) end function nodeinjections.cmykcolor(c,m,y,k) - return register(pdfpageliteral(f_cmyk(c,m,y,k,c,m,y,k))) + return register(pageliteral(f_cmyk(c,m,y,k,c,m,y,k))) end function nodeinjections.graycolor(s) -- caching 0/1 does not pay off - return register(pdfpageliteral(f_gray(s,s))) + return register(pageliteral(f_gray(s,s))) end function nodeinjections.spotcolor(n,f,d,p) if type(p) == "string" then p = gsub(p,","," ") -- brr misuse of spot end - return register(pdfpageliteral(f_spot(n,n,p,p))) + return register(pageliteral(f_spot(n,n,p,p))) end function nodeinjections.transparency(n) - return register(pdfpageliteral(f_tr_gs(n))) + return register(pageliteral(f_tr_gs(n))) end -- a bit weird but let's keep it here for a while @@ -160,7 +167,7 @@ function nodeinjections.effect(effect,stretch,rulethickness) -- always, no zero test (removed) rulethickness = bp * rulethickness effect = effects[effect] or effects['normal'] - return register(pdfpageliteral(f_effect(stretch,rulethickness,effect))) -- watch order + return register(pageliteral(f_effect(stretch,rulethickness,effect))) -- watch order end -- spot- and indexcolors @@ -335,7 +342,9 @@ local function registersomeindexcolor(name,noffractions,names,p,colorspace,range colorspace, pdfreference(n), } - local vector, set, n = { }, { }, #values + local vector = { } + local set = { } + local n = #values for i=255,0,-1 do for j=1,n do set[j] = format("%02X",round(values[j]*i)) @@ -512,13 +521,21 @@ local function lpdfcolor(model,ca,default) -- todo: use gray when no color local s = cv[2] return f_gray(s,s) elseif model == 3 then - local r, g, b = cv[3], cv[4], cv[5] + local r = cv[3] + local g = cv[4] + local b = cv[5] return f_rgb(r,g,b,r,g,b) elseif model == 4 then - local c, m, y, k = cv[6],cv[7],cv[8],cv[9] + local c = cv[6] + local m = cv[7] + local y = cv[8] + local k = cv[9] return f_cmyk(c,m,y,k,c,m,y,k) else - local n,f,d,p = cv[10],cv[11],cv[12],cv[13] + local n = cv[10] + local f = cv[11] + local d = cv[12] + local p = cv[13] if type(p) == "string" then p = gsub(p,","," ") -- brr misuse of spot end @@ -617,7 +634,7 @@ function lpdf.colorvalues(model,ca,default) return cv[3], cv[4], cv[5] elseif model == 4 then return cv[6], cv[7], cv[8], cv[9] - elseif model == 4 then + elseif model == 5 then return cv[13] end else @@ -717,6 +734,10 @@ do local f_slant = formatters["q 1 0 %.6F 1 0 0 cm"] + directives.register("pdf.stripzeros",function() + f_slant = formatters["q 1 0 %.6N 1 0 0 cm"] + end) + -- local fillcolors = { -- red = { "pdf", "origin", "1 0 0 rg" }, -- green = { "pdf", "origin", "0 1 0 rg" }, diff --git a/tex/context/base/mkiv/lpdf-epa.lua b/tex/context/base/mkiv/lpdf-epa.lua index 89b2c6e0e..570d73881 100644 --- a/tex/context/base/mkiv/lpdf-epa.lua +++ b/tex/context/base/mkiv/lpdf-epa.lua @@ -6,49 +6,79 @@ if not modules then modules = { } end modules ['lpdf-epa'] = { license = "see context related readme files" } --- This is a rather experimental feature and the code will probably change. +-- Links can also have quadpoint -local type, tonumber = type, tonumber -local format, gsub, lower = string.format, string.gsub, string.lower +-- embedded files ... not bound to a page + +local type, tonumber, next = type, tonumber, next +local format, gsub, lower, find = string.format, string.gsub, string.lower, string.find local formatters = string.formatters +local concat, merged = table.concat, table.merged local abs = math.abs local expandname = file.expandname local allocate = utilities.storage.allocate +local bor, band = bit32.bor, bit32.band local isfile = lfs.isfile ------ lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) +local trace_comments = false trackers.register("figures.comments", function(v) trace_comments = v end) +local trace_fields = false trackers.register("figures.fields", function(v) trace_fields = v end) +local trace_outlines = false trackers.register("figures.outlines", function(v) trace_outlines = v end) + +local report_link = logs.reporter("backend","link") +local report_comment = logs.reporter("backend","comment") +local report_field = logs.reporter("backend","field") +local report_outline = logs.reporter("backend","outline") + +local lpdf = lpdf +local epdf = epdf +local backends = backends +local context = context + +local nodeinjections = backends.pdf.nodeinjections + +local pdfarray = lpdf.array +local pdfdictionary = lpdf.dictionary +local pdfconstant = lpdf.constant +local pdfreserveobject = lpdf.reserveobject +local pdfreference = lpdf.reference -local trace_links = false trackers.register("figures.links", function(v) trace_links = v end) -local trace_outlines = false trackers.register("figures.outliness", function(v) trace_outlines = v end) +local pdfcopyboolean = lpdf.copyboolean +local pdfcopyunicode = lpdf.copyunicode +local pdfcopyarray = lpdf.copyarray +local pdfcopydictionary = lpdf.copydictionary +local pdfcopynumber = lpdf.copynumber +local pdfcopyinteger = lpdf.copyinteger +local pdfcopystring = lpdf.copystring +local pdfcopyconstant = lpdf.copyconstant -local report_link = logs.reporter("backend","link") -local report_comment = logs.reporter("backend","comment") -local report_field = logs.reporter("backend","field") -local report_outline = logs.reporter("backend","outline") +local createimage = images.create +local embedimage = images.embed -local epdf = epdf -local backends = backends -local lpdf = lpdf -local context = context +local hpack_node = nodes.hpack -local loadpdffile = lpdf.epdf.load +local loadpdffile = lpdf.epdf.load -local nameonly = file.nameonly +local nameonly = file.nameonly -local variables = interfaces.variables -local codeinjections = backends.pdf.codeinjections ------ urlescaper = lpegpatterns.urlescaper ------ utftohigh = lpegpatterns.utftohigh -local escapetex = characters.filters.utf.private.escape +local variables = interfaces.variables +local codeinjections = backends.pdf.codeinjections +----- urlescaper = lpegpatterns.urlescaper +----- utftohigh = lpegpatterns.utftohigh +local escapetex = characters.filters.utf.private.escape -local bookmarks = structures.bookmarks +local bookmarks = structures.bookmarks -local maxdimen = 0x3FFFFFFF -- 2^30-1 +local maxdimen = 0x3FFFFFFF -- 2^30-1 + +local bpfactor = number.dimenfactors.bp local layerspec = { -- predefining saves time - "epdflinks" + "epdfcontent" } +local getpos = function() getpos = backends.codeinjections.getpos return getpos () end + local collected = allocate() local tobesaved = allocate() @@ -66,6 +96,68 @@ end job.register('job.embedded.collected',tobesaved,initializer) +local function validdocument(specification) + if figures and not specification then + specification = figures and figures.current() + specification = specification and specification.status + end + if specification then + local fullname = specification.fullname + local expanded = lower(expandname(fullname)) + -- we could add a check for duplicate page insertion + tobesaved[expanded] = true + --- but that is messy anyway so we forget about it + return specification, fullname, loadpdffile(fullname) -- costs time + end +end + +local function getmediasize(specification,pagedata) + local xscale = specification.xscale or 1 + local yscale = specification.yscale or 1 + ----- size = specification.size or "crop" -- todo + local mediabox = pagedata.MediaBox + local llx = mediabox[1] + local lly = mediabox[2] + local urx = mediabox[3] + local ury = mediabox[4] + local width = xscale * (urx - llx) -- \\overlaywidth, \\overlayheight + local height = yscale * (ury - lly) -- \\overlaywidth, \\overlayheight + return llx, lly, urx, ury, width, height, xscale, yscale +end + +local function getdimensions(annotation,llx,lly,xscale,yscale,width,height,report) + local rectangle = annotation.Rect + local a_llx = rectangle[1] + local a_lly = rectangle[2] + local a_urx = rectangle[3] + local a_ury = rectangle[4] + local x = xscale * (a_llx - llx) + local y = yscale * (a_lly - lly) + local w = xscale * (a_urx - a_llx) + local h = yscale * (a_ury - a_lly) + if w > width or h > height or w < 0 or h < 0 or abs(x) > (maxdimen/2) or abs(y) > (maxdimen/2) then + report("broken rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2) + return + end + return x, y, w, h, a_llx, a_lly, a_urx, a_ury +end + +local layerused = false + +local function initializelayer(height,width) + if not layerused then + context.definelayer(layerspec, { height = height .. "bp", width = width .. "bp" }) + layerused = true + end +end + +function codeinjections.flushmergelayer() + if layerused then + context.flushlayer(layerspec) + layerused = false + end +end + local f_namespace = formatters["lpdf-epa-%s-"] local function makenamespace(filename) @@ -182,82 +274,51 @@ local function link_file(x,y,w,h,document,annotation) end end +-- maybe handler per subtype and then one loop but then what about order ... + function codeinjections.mergereferences(specification) - if figures and not specification then - specification = figures and figures.current() - specification = specification and specification.status - end - if not specification then - return "" - end - local fullname = specification.fullname - local expanded = lower(expandname(fullname)) - -- we could add a check for duplicate page insertion - tobesaved[expanded] = true - --- but that is messy anyway so we forget about it - local document = loadpdffile(fullname) -- costs time + local specification, fullname, document = validdocument(specification) if not document then return "" end - local pagenumber = specification.page or 1 - local xscale = specification.yscale or 1 - local yscale = specification.yscale or 1 - local size = specification.size or "crop" -- todo + local pagenumber = specification.page or 1 local pagedata = document.pages[pagenumber] local annotations = pagedata and pagedata.Annots local namespace = makenamespace(fullname) local reference = namespace .. pagenumber - if annotations and annotations.n > 0 then - local mediabox = pagedata.MediaBox - local llx = mediabox[1] - local lly = mediabox[2] - local urx = mediabox[3] - local ury = mediabox[4] - local width = xscale * (urx - llx) -- \\overlaywidth, \\overlayheight - local height = yscale * (ury - lly) -- \\overlaywidth, \\overlayheight - context.definelayer( { "epdflinks" }, { height = height.."bp" , width = width.."bp" }) - for i=1,annotations.n do + if annotations and #annotations > 0 then + local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) + initializelayer(height,width) + for i=1,#annotations do local annotation = annotations[i] if annotation then - local subtype = annotation.Subtype - local rectangle = annotation.Rect - local a_llx = rectangle[1] - local a_lly = rectangle[2] - local a_urx = rectangle[3] - local a_ury = rectangle[4] - local x = xscale * (a_llx - llx) - local y = yscale * (a_lly - lly) - local w = xscale * (a_urx - a_llx) - local h = yscale * (a_ury - a_lly) - if subtype == "Link" then + if annotation.Subtype == "Link" then local a = annotation.A if not a then report_link("missing link annotation") - elseif w > width or h > height or w < 0 or h < 0 or abs(x) > (maxdimen/2) or abs(y) > (maxdimen/2) then - report_link("broken link rectangle [%.6F %.6F %.6F %.6F] (max: %.6F)",a_llx,a_lly,a_urx,a_ury,maxdimen/2) else - local linktype = a.S - if linktype == "GoTo" then - link_goto(x,y,w,h,document,annotation,pagedata,namespace) - elseif linktype == "GoToR" then - link_file(x,y,w,h,document,annotation) - elseif linktype == "URI" then - link_uri(x,y,w,h,document,annotation) - elseif trace_links then - report_link("unsupported link annotation %a",linktype) + local x, y, w, h = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_link) + if x then + local linktype = a.S + if linktype == "GoTo" then + link_goto(x,y,w,h,document,annotation,pagedata,namespace) + elseif linktype == "GoToR" then + link_file(x,y,w,h,document,annotation) + elseif linktype == "URI" then + link_uri(x,y,w,h,document,annotation) + elseif trace_links then + report_link("unsupported link annotation %a",linktype) + end end end - elseif trace_links then - report_link("unsupported annotation %a",subtype) end elseif trace_links then report_link("broken annotation, index %a",i) end end - context.flushlayer { "epdflinks" } end -- moved outside previous test - context.setgvalue("figurereference",reference) -- global + context.setgvalue("figurereference",reference) -- global, todo: setmacro if trace_links then report_link("setting figure reference to %a",reference) end @@ -270,43 +331,527 @@ function codeinjections.mergeviewerlayers(specification) if true then return end - if not specification then - specification = figures and figures.current() - specification = specification and specification.status + local specification, fullname, document = validdocument(specification) + if not document then + return "" end - if specification then - local fullname = specification.fullname - local document = loadpdffile(fullname) - if document then - local namespace = makenamespace(fullname) - local layers = document.layers - if layers then - for i=1,layers.n do - local layer = layers[i] - if layer then - local tag = namespace .. gsub(layer," ",":") - local title = tag - if trace_links then - report_link("using layer %a",tag) + local namespace = makenamespace(fullname) + local layers = document.layers + if layers then + for i=1,#layers do + local layer = layers[i] + if layer then + local tag = namespace .. gsub(layer," ",":") + local title = tag + if trace_links then + report_link("using layer %a",tag) + end + attributes.viewerlayers.define { -- also does some cleaning + tag = tag, -- todo: #3A or so + title = title, + visible = variables.start, + editable = variables.yes, + printable = variables.yes, + } + codeinjections.useviewerlayer(tag) + elseif trace_links then + report_link("broken layer, index %a",i) + end + end + end +end + +-- It took a bit of puzzling and playing around to come to the following +-- implementation. In the end it looks simple but as usual it takes a while +-- to see what the specification (and implementation) boils down to. Lots of +-- shared properties and such. The scaling took some trial and error as +-- viewers differ. I had to extend some low level helpers to make it more +-- comfortable. Hm, the specification is somewhat incomplete as some fields +-- are permitted even if not mentioned so in the end we can share more code. +-- +-- If all works ok, we can get rid of some copies which saves time and space. + +local commentlike = { + Text = "text", + FreeText = "freetext", + Line = "line", + Square = "shape", + Circle = "shape", + Polygon = "poly", + PolyLine = "poly", + Highlight = "markup", + Underline = "markup", + Squiggly = "markup", + StrikeOut = "markup", + Caret = "text", + Stamp = "stamp", + Ink = "ink", + Popup = "popup", +} + +local function copyBS(v) -- dict can be shared + if v then + -- return pdfdictionary { + -- Type = copypdfconstant(V.Type), + -- W = copypdfnumber (V.W), + -- S = copypdfstring (V.S), + -- D = copypdfarray (V.D), + -- } + return copypdfdictionary(v) + end +end + +local function copyBE(v) -- dict can be shared + if v then + -- return pdfdictionary { + -- S = copypdfstring(V.S), + -- I = copypdfnumber(V.I), + -- } + return copypdfdictionary(v) + end +end + +local function copyBorder(v) -- dict can be shared + if v then + -- todo + return copypdfarray(v) + end +end + +local function copyPopup(v,references) + if v then + local p = references[v] + if p then + return pdfreference(p) + end + end +end + +local function copyParent(v,references) + if v then + local p = references[v] + if p then + return pdfreference(p) + end + end +end + +local function copyIRT(v,references) + if v then + local p = references[v] + if p then + return pdfreference(p) + end + end +end + +local function copyC(v) + if v then + -- todo: check color space + return pdfcopyarray(v) + end +end + +local function finalizer(d,xscale,yscale,a_llx,a_ury) + local q = d.QuadPoints or d.Vertices or d.CL + if q then + return function() + local h, v = pdfgetpos() -- already scaled + for i=1,#q,2 do + q[i] = xscale * q[i] + (h*bpfactor - xscale * a_llx) + q[i+1] = yscale * q[i+1] + (v*bpfactor - yscale * a_ury) + end + return d() + end + end + q = d.InkList or d.Path + if q then + return function() + local h, v = pdfgetpos() -- already scaled + for i=1,#q do + local q = q[i] + for i=1,#q,2 do + q[i] = xscale * q[i] + (h*bpfactor - xscale * a_llx) + q[i+1] = yscale * q[i+1] + (v*bpfactor - yscale * a_ury) + end + end + return d() + end + end + return d() +end + +local validstamps = { + Approved = true, + Experimental = true, + NotApproved = true, + AsIs = true, + Expired = true, + NotForPublicRelease = true, + Confidential = true, + Final = true, + Sold = true, + Departmental = true, + ForComment = true, + TopSecret = true, + Draft = true, + ForPublicRelease = true, +} + +-- todo: we can use runtoks instead of steps + +local function validStamp(v) + local name = "Stamped" -- fallback + if v then + local ok = validstamps[v] + if ok then + name = ok + else + for k in next, validstamps do + if find(v,k.."$") then + name = k + validstamps[v] = k + break + end + end + end + end + -- we temporary return to \TEX: + context.predefinesymbol { name } + context.step() + -- beware, an error is not reported + return pdfconstant(name), codeinjections.analyzenormalsymbol(name) +end + +local annotationflags = lpdf.flags.annotations + +local function copyF(v,lock) -- todo: bxor 24 + if lock then + v = bor(v or 0,annotationflags.ReadOnly + annotationflags.Locked + annotationflags.LockedContents) + end + if v then + return pdfcopyinteger(v) + end +end + +-- Speed is not really an issue so we don't optimize this code too much. In the end (after +-- testing we end up with less code that we started with. + +function codeinjections.mergecomments(specification) + local specification, fullname, document = validdocument(specification) + if not document then + return "" + end + local pagenumber = specification.page or 1 + local pagedata = document.pages[pagenumber] + local annotations = pagedata and pagedata.Annots + if annotations and #annotations > 0 then + local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) + initializelayer(height,width) + -- + local lockflags = specification.lock -- todo: proper parameter + local references = { } + local usedpopups = { } + for i=1,#annotations do + local annotation = annotations[i] + if annotation then + local subtype = annotation.Subtype + if commentlike[subtype] then + references[annotation] = pdfreserveobject() + local p = annotation.Popup + if p then + usedpopups[p] = true + end + end + end + end + -- + for i=1,#annotations do + -- we keep the order + local annotation = annotations[i] + if annotation then + local reference = references[annotation] + if reference then + local subtype = annotation.Subtype + local kind = commentlike[subtype] + if kind ~= "popup" or usedpopups[annotation] then + local x, y, w, h, a_llx, a_lly, a_urx, a_ury = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_comment) + if x then + local voffset = h + local dictionary = pdfdictionary { + Subtype = pdfconstant (subtype), + -- common (skipped: P AP AS OC AF BM StructParent) + Contents = pdfcopyunicode(annotation.Contents), + NM = pdfcopystring (annotation.NM), + M = pdfcopystring (annotation.M), + F = copyF (annotation.F,lockflags), + C = copyC (annotation.C), + ca = pdfcopynumber (annotation.ca), + CA = pdfcopynumber (annotation.CA), + Lang = pdfcopystring (annotation.Lang), + -- also common + CreationDate = pdfcopystring (annotation.CreationDate), + T = pdfcopyunicode(annotation.T), + Subj = pdfcopyunicode(annotation.Subj), + -- border + Border = pdfcopyarray (annotation.Border), + BS = copyBS (annotation.BS), + BE = copyBE (annotation.BE), + -- sort of common + Popup = copyPopup (annotation.Popup,references), + RC = pdfcopyunicode(annotation.RC) -- string or stream + } + if kind == "markup" then + dictionary.IRT = copyIRT (annotation.IRT,references) + dictionary.RT = pdfconstant (annotation.RT) + dictionary.IT = pdfcopyconstant (annotation.IT) + dictionary.QuadPoints = pdfcopyarray (annotation.QuadPoints) + -- dictionary.RD = pdfcopyarray (annotation.RD) + elseif kind == "text" then + -- somehow F fails to view : /F 24 : bit4=nozoom bit5=norotate + dictionary.F = nil + dictionary.Open = pdfcopyboolean (annotation.Open) + dictionary.Name = pdfcopyunicode (annotation.Name) + dictionary.State = pdfcopystring (annotation.State) + dictionary.StateModel = pdfcopystring (annotation.StateModel) + dictionary.IT = pdfcopyconstant (annotation.IT) + dictionary.QuadPoints = pdfcopyarray (annotation.QuadPoints) + dictionary.RD = pdfcopyarray (annotation.RD) -- caret + dictionary.Sy = pdfcopyconstant (annotation.Sy) -- caret + voffset = 0 + elseif kind == "freetext" then + dictionary.DA = pdfcopystring (annotation.DA) + dictionary.Q = pdfcopyinteger (annotation.Q) + dictionary.DS = pdfcopystring (annotation.DS) + dictionary.CL = pdfcopyarray (annotation.CL) + dictionary.IT = pdfcopyconstant (annotation.IT) + dictionary.LE = pdfcopyconstant (annotation.LE) + -- dictionary.RC = pdfcopystring (annotation.RC) + elseif kind == "line" then + dictionary.LE = pdfcopyarray (annotation.LE) + dictionary.IC = pdfcopyarray (annotation.IC) + dictionary.LL = pdfcopynumber (annotation.LL) + dictionary.LLE = pdfcopynumber (annotation.LLE) + dictionary.Cap = pdfcopyboolean (annotation.Cap) + dictionary.IT = pdfcopyconstant (annotation.IT) + dictionary.LLO = pdfcopynumber (annotation.LLO) + dictionary.CP = pdfcopyconstant (annotation.CP) + dictionary.Measure = pdfcopydictionary(annotation.Measure) -- names + dictionary.CO = pdfcopyarray (annotation.CO) + voffset = 0 + elseif kind == "shape" then + dictionary.IC = pdfcopyarray (annotation.IC) + -- dictionary.RD = pdfcopyarray (annotation.RD) + voffset = 0 + elseif kind == "stamp" then + local name, appearance = validStamp(annotation.Name) + dictionary.Name = name + dictionary.AP = appearance + voffset = 0 + elseif kind == "ink" then + dictionary.InkList = pdfcopyarray (annotation.InkList) + elseif kind == "poly" then + dictionary.Vertices = pdfcopyarray (annotation.Vertices) + -- dictionary.LE = pdfcopyarray (annotation.LE) -- todo: names in array + dictionary.IC = pdfcopyarray (annotation.IC) + dictionary.IT = pdfcopyconstant (annotation.IT) + dictionary.Measure = pdfcopydictionary(annotation.Measure) + dictionary.Path = pdfcopyarray (annotation.Path) + -- dictionary.RD = pdfcopyarray (annotation.RD) + elseif kind == "popup" then + dictionary.Open = pdfcopyboolean (annotation.Open) + dictionary.Parent = copyParent (annotation.Parent,references) + voffset = 0 + end + if dictionary then + local locationspec = { + x = x .. "bp", + y = y .. "bp", + voffset = voffset .. "bp", + preset = "leftbottom", + } + local finalize = finalizer(dictionary,xscale,yscale,a_llx,a_ury) + context.setlayer(layerspec,locationspec,function() + context(hpack_node(nodeinjections.annotation(w/bpfactor,h/bpfactor,0,finalize,reference))) + end) + end end - attributes.viewerlayers.define { -- also does some cleaning - tag = tag, -- todo: #3A or so - title = title, - visible = variables.start, - editable = variables.yes, - printable = variables.yes, - } - codeinjections.useviewerlayer(tag) - elseif trace_links then - report_link("broken layer, index %a",i) + else + -- report_comment("skipping annotation, index %a",i) end end + elseif trace_comments then + report_comment("broken annotation, index %a",i) end end end + return namespace end --- new: for taco +local widgetflags = lpdf.flags.widgets + +local function flagstoset(flag,flags) + local t = { } + if flags then + for k, v in next, flags do + if band(flag,v) ~= 0 then + t[k] = true + end + end + end + return t +end + +-- BS : border style dict +-- R : rotation 0 90 180 270 +-- BG : background array +-- CA : caption string +-- RC : roll over caption +-- AC : down caption +-- I/RI/IX : icon streams +-- IF : fit dictionary +-- TP : text position number + +-- Opt : array of texts +-- TI : top index + +-- V : value +-- DV : default value +-- DS : default string +-- RV : rich +-- Q : quadding (0=left 1=middle 2=right) + +function codeinjections.mergefields(specification) + local specification, fullname, document = validdocument(specification) + if not document then + return "" + end + local pagenumber = specification.page or 1 + local pagedata = document.pages[pagenumber] + local annotations = pagedata and pagedata.Annots + if annotations and #annotations > 0 then + local llx, lly, urx, ury, width, height, xscale, yscale = getmediasize(specification,pagedata,xscale,yscale) + initializelayer(height,width) + -- + for i=1,#annotations do + -- we keep the order + local annotation = annotations[i] + if annotation then + local subtype = annotation.Subtype + if subtype == "Widget" then + local parent = annotation.Parent or { } + local name = annotation.T or parent.T + local what = annotation.FT or parent.FT + if name and what then + local x, y, w, h, a_llx, a_lly, a_urx, a_ury = getdimensions(annotation,llx,lly,xscale,yscale,width,height,report_field) + if x then + x = x .. "bp" + y = y .. "bp" + local W, H = w, h + w = w .. "bp" + h = h .. "bp" + if trace_fields then + report_field("field %a, type %a, dx %s, dy %s, wd %s, ht %s",name,what,x,y,w,h) + end + local locationspec = { + x = x, + y = y, + preset = "leftbottom", + } + -- + local aflags = flagstoset(annotation.F or parent.F, annotationflags) + local wflags = flagstoset(annotation.Ff or parent.Ff, widgetflags) + if what == "Tx" then + -- DA DV F FT MaxLen MK Q T V | AA OC + if wflags.MultiLine then + wflags.MultiLine = nil + what = "text" + else + what = "line" + end + -- via context + local fieldspec = { + width = w, + height = h, + offset = variables.overlay, + frame = trace_links and variables.on or variables.off, + n = annotation.MaxLen or (parent and parent.MaxLen), + type = what, + option = concat(merged(aflags,wflags),","), + } + context.setlayer (layerspec,locationspec,function() + context.definefieldbody ( { name } , fieldspec ) + context.fieldbody ( { name } ) + end) + -- + elseif what == "Btn" then + if wflags.Radio or wflags.RadiosInUnison then + -- AP AS DA F Ff FT H MK T V | AA OC + wflags.Radio = nil + wflags.RadiosInUnison = nil + what = "radio" + elseif wflags.PushButton then + -- AP DA F Ff FT H MK T | AA OC + -- + -- Push buttons only have an appearance and some associated + -- actions so they are not worth copying. + -- + wflags.PushButton = nil + what = "push" + else + -- AP AS DA F Ff FT H MK T V | OC AA + what = "check" + -- direct + local AP = annotation.AP or (parent and parent.AP) + if AP then + local a = document.__xrefs__[AP] + if a and pdfe.copyappearance then + local o = pdfe.copyappearance(document,a) + if o then + AP = pdfreference(o) + end + end + end + local dictionary = pdfdictionary { + Subtype = pdfconstant("Widget"), + FT = pdfconstant("Btn"), + T = pdfcopyunicode(annotation.T or parent.T), + F = pdfcopyinteger(annotation.F or parent.F), + Ff = pdfcopyinteger(annotation.Ff or parent.Ff), + AS = pdfcopyconstant(annotation.AS or (parent and parent.AS)), + AP = AP and pdfreference(AP), + } + local finalize = dictionary() + context.setlayer(layerspec,locationspec,function() + context(hpack_node(nodeinjections.annotation(W/bpfactor,H/bpfactor,0,finalize))) + end) + -- + end + elseif what == "Ch" then + -- F Ff FT Opt T | AA OC (rest follows) + if wflags.PopUp then + wflags.PopUp = nil + if wflags.Edit then + wflags.Edit = nil + what = "combo" + else + what = "popup" + end + else + what = "choice" + end + elseif what == "Sig" then + what = "signature" + else + what = nil + end + end + end + end + end + end + end +end -- Beware, bookmarks can be in pdfdoc encoding or in unicode. However, in mkiv we -- write out the strings in unicode (hex). When we read them in, we check for a bom @@ -337,7 +882,7 @@ function codeinjections.getbookmarks(filename) local outlines = document.Catalog.Outlines local pages = document.pages - local nofpages = pages.n -- we need to access once in order to initialize + local nofpages = document.nofpages local destinations = document.destinations -- I need to check this destination analyzer with the one in annotations .. best share @@ -359,7 +904,7 @@ function codeinjections.getbookmarks(filename) entry.realpage = pagedata.number end elseif kind == "table" then - local pageref = destination.n + local pageref = #destination if pageref then local pagedata = pages[pageref] if pagedata then @@ -367,8 +912,8 @@ function codeinjections.getbookmarks(filename) end end end - else - -- maybe + -- elseif subtype then + -- report("unsupported bookmark action %a",subtype) end else local destination = current.Dest @@ -383,6 +928,8 @@ function codeinjections.getbookmarks(filename) local pagedata = destination and destination[1] if pagedata and pagedata.Type == "Page" then entry.realpage = pagedata.number + -- else + -- report("unsupported bookmark destination (no page)") end end end @@ -471,16 +1018,6 @@ function codeinjections.mergebookmarks(specification) end end --- placeholders: - -function codeinjections.mergecomments(specification) - report_comment("unfinished experimental code, not used yet") -end - -function codeinjections.mergefields(specification) - report_field("unfinished experimental code, not used yet") -end - -- A bit more than a placeholder but in the same perspective as -- inclusion of comments and fields: -- @@ -501,7 +1038,7 @@ function codeinjections.getinfo(specification) local catalog = pdffile.Catalog local info = pdffile.Info local pages = pdffile.pages - local nofpages = pages.n + local nofpages = pdffile.nofpages if metadata then local m = catalog.Metadata if m then @@ -525,10 +1062,8 @@ function codeinjections.getinfo(specification) local media = nobox local page = pages[pagenumber] if page then - crop = page.CropBox or nobox - media = page.MediaBox or crop or nobox - crop.n = nil -- nicer - media.n = nil -- nicer + crop = page.CropBox or nobox + media = page.MediaBox or crop or nobox end local bbox = crop or media or nobox return { diff --git a/tex/context/base/mkiv/lpdf-epd.lua b/tex/context/base/mkiv/lpdf-epd.lua index cf02b5a22..86aa6f294 100644 --- a/tex/context/base/mkiv/lpdf-epd.lua +++ b/tex/context/base/mkiv/lpdf-epd.lua @@ -32,7 +32,7 @@ if not modules then modules = { } end modules ['lpdf-epd'] = { -- already was unicode). local setmetatable, rawset, rawget, type, next = setmetatable, rawset, rawget, type, next -local tostring, tonumber = tostring, tonumber +local tostring, tonumber, unpack = tostring, tonumber, unpack local lower, match, char, byte, find = string.lower, string.match, string.char, string.byte, string.find local abs = math.abs local concat = table.concat @@ -67,13 +67,27 @@ local xref = registry["epdf.XRef"] local catalog = registry["epdf.Catalog"] local pdfdoc = registry["epdf.PDFDoc"] +if not (object and dictionary and array and xref and catalog and pdfdoc) then + logs.report("fatal error","invalid pdf inclusion library (%s)",1) + os.exit() +end + local openPDF = epdf.open +local getMajorVersion = pdfdoc.getPDFMajorVersion +local getMinorVersion = pdfdoc.getPDFMinorVersion +local getXRef = pdfdoc.getXRef +local getRawCatalog = pdfdoc.getCatalog + +if not (openPDF and getMajorVersion and getMinorVersion and getXRef and getRawCatalog) then + logs.report("fatal error","invalid pdf inclusion library (%s)",2) + os.exit() +end + local getDict = object.getDict local getArray = object.getArray local getReal = object.getReal local getInt = object.getInt -local getNum = object.getNum local getString = object.getString local getBool = object.getBool local getName = object.getName @@ -81,59 +95,81 @@ local getRef = object.getRef local getRefNum = object.getRefNum local getType = object.getType -local getTypeName = object.getTypeName + +if not (getDict and getArray and getReal and getInt and getString and getBool and getName and getRef and getRefNum and getType) then + logs.report("fatal error","invalid pdf inclusion library (%s)",3) + os.exit() +end local streamReset = object.streamReset local streamGetDict = object.streamGetDict local streamGetChar = object.streamGetChar +local streamGetAll = object.streamGetAll + +if not (streamReset and streamGetDict and streamGetChar) then + logs.report("fatal error","invalid pdf inclusion library (%s)",3) + os.exit() +end local dictGetLength = dictionary.getLength local dictGetVal = dictionary.getVal local dictGetValNF = dictionary.getValNF local dictGetKey = dictionary.getKey +if not (dictGetLength and dictGetVal and dictGetValNF and dictGetKey) then + logs.report("fatal error","invalid pdf inclusion library (%s)",4) + os.exit() +end + local arrayGetLength = array.getLength local arrayGetNF = array.getNF local arrayGet = array.get +if not (arrayGetLength and arrayGetNF and arrayGet) then + logs.report("fatal error","invalid pdf inclusion library (%s)",5) + os.exit() +end + -- these are kind of weird as they can't be accessed by (root) object local getNumPages = catalog.getNumPages local getPageRef = catalog.getPageRef -local getXRef = pdfdoc.getXRef -local getRawCatalog = pdfdoc.getCatalog - local fetch = xref.fetch local getCatalog = xref.getCatalog local getDocInfo = xref.getDocInfo +if not (getNumPages and getPageRef and fetch and getCatalog and getDocInfo) then + logs.report("fatal error","invalid pdf inclusion library (%s)",6) + os.exit() +end + -- we're done with library shortcuts -local report_epdf = logs.reporter("epdf") - -local typenames = { [0] = - "boolean", - "integer", - "real", - "string", - "name", - "null", - "array", - "dictionary", - "stream", - "ref", - "cmd", - "error", - "eof", - "none", - "integer64", +local typenames = { [0] = + "boolean", + "integer", + "real", + "string", + "name", + "null", + "array", + "dictionary", + "stream", + "ref", + "cmd", + "error", + "eof", + "none", + "integer64", } -local typenumbers = table.swapped(typenames) +local typenumbers = table.swapped(typenames) + +local null_object_code = typenumbers.null +local ref_object_code = typenumbers.ref -local null_code = typenumbers.null -local ref_code = typenumbers.ref +local report_epdf = logs.reporter("epdf") local function fatal_error(...) report_epdf(...) @@ -206,32 +242,30 @@ local function prepare(document,d,t,n,k,mt,flags) if v then local r = dictGetValNF(d,i) local kind = getType(v) - if kind == null_code then + if kind == null_object_code then -- ignore - else + elseif kind then local key = dictGetKey(d,i) - if kind then - if r and getType(r) == ref_code then - local objnum = getRefNum(r) - local cached = document.__cache__[objnum] - if not cached then - cached = checked_access[kind](v,document,objnum,mt) - if cached then - document.__cache__[objnum] = cached - document.__xrefs__[cached] = objnum - end - end - t[key] = cached - else - local v, flag = checked_access[kind](v,document) - t[key] = v - if flag and flags then - flags[key] = flag -- flags + if r and getType(r) == ref_object_code then + local objnum = getRefNum(r) + local cached = document.__cache__[objnum] + if not cached then + cached = checked_access[kind](v,document,objnum,mt) + if cached then + document.__cache__[objnum] = cached + document.__xrefs__[cached] = objnum end end + t[key] = cached else - report_epdf("warning: nil value for key %a in dictionary",key) + local v, flag = checked_access[kind](v,document) + t[key] = v + if flag and flags then + flags[key] = flag -- flags + end end + else + report_epdf("warning: nil value for key %a in dictionary",key) end else fatal_error("error: invalid value at index %a in dictionary of %a",i,document.filename) @@ -245,6 +279,42 @@ local function prepare(document,d,t,n,k,mt,flags) return t[k] end +-- local function prepare(document,d,t,n,k,mt,flags) +-- for i=1,n do +-- local v = dictGetValNF(d,i) +-- if v then +-- local key = dictGetKey(d,i) +-- local kind = getType(v) +-- if kind == ref_object_code then +-- local objnum = getRefNum(v) +-- local cached = document.__cache__[objnum] +-- if not cached then +-- local v = dictGetVal(d,i) +-- local kind = getType(v) +-- cached = checked_access[kind](v,document,objnum,mt) +-- if cached then +-- document.__cache__[objnum] = cached +-- document.__xrefs__[cached] = objnum +-- end +-- end +-- t[key] = cached +-- else +-- local v, flag = checked_access[kind](v,document) +-- t[key] = v +-- if flag and flags then +-- flags[key] = flag -- flags +-- end +-- end +-- end +-- end +-- if mt then +-- setmetatable(t,mt) +-- else +-- getmetatable(t).__index = nil +-- end +-- return t[k] +-- end + local function some_dictionary(d,document) local n = d and dictGetLength(d) or 0 if n > 0 then @@ -293,11 +363,11 @@ local function prepare(document,a,t,n,k) local v = arrayGet(a,i) if v then local kind = getType(v) - if kind == null_code then + if kind == null_object_code then -- ignore elseif kind then local r = arrayGetNF(a,i) - if r and getType(r) == ref_code then + if r and getType(r) == ref_object_code then local objnum = getRefNum(r) local cached = document.__cache__[objnum] if not cached then @@ -326,6 +396,37 @@ local function prepare(document,a,t,n,k) end end +-- local function prepare(document,a,t,n,k) +-- for i=1,n do +-- local v = arrayGetNF(a,i) +-- if v then +-- local kind = getType(v) +-- if kind == ref_object_code then +-- local objnum = getRefNum(v) +-- local cached = document.__cache__[objnum] +-- if not cached then +-- local v = arrayGet(a,i) +-- local kind = getType(v) +-- cached = checked_access[kind](v,document,objnum) +-- document.__cache__[objnum] = cached +-- document.__xrefs__[cached] = objnum +-- end +-- t[i] = cached +-- else +-- t[i] = checked_access[kind](v,document) +-- end +-- end +-- end +-- local m = getmetatable(t) +-- if m then +-- m.__index = nil +-- m.__len = nil +-- end +-- if k then +-- return t[k] +-- end +-- end + local function some_array(a,document) local n = a and arrayGetLength(a) or 0 if n > 0 then @@ -376,23 +477,53 @@ end -- todo: collect chunks -local function streamaccess(s,_,what) - if not what or what == "all" or what == "*all" then - local t, n = { }, 0 - streamReset(s) +-- local function streamaccess(s,_,what) +-- if not what or what == "all" or what == "*all" then +-- local t, n = { }, 0 +-- streamReset(s) +-- while true do +-- local c = streamGetChar(s) +-- if c < 0 then +-- break +-- else +-- n = n + 1 +-- t[n] = char(c) +-- end +-- end +-- return concat(t,"",1,n) +-- end +-- end + +local function getstream(s) + streamReset(s) + if streamGetAll then + return streamGetAll(s) + else + local t, b, n = { }, { }, 0 while true do local c = streamGetChar(s) if c < 0 then break else n = n + 1 - t[n] = char(c) + b[n] = c + end + if n == 2000 then + t[#t+1] = char(unpack(b,1,n)) + n = 1 end end + t[#t+1] = char(unpack(b,1,n)) return concat(t) end end +local function streamaccess(s,_,what) + if not what or what == "all" or what == "*all" then + return getstream(s) + end +end + local function get_stream(d,document) if d then streamReset(d) @@ -562,16 +693,19 @@ end -- with but it won't win a beauty contest. local function getpages(document,Catalog) - local __data__ = document.__data__ - local __xrefs__ = document.__xrefs__ - local __cache__ = document.__cache__ - local __xref__ = document.__xref__ + local __data__ = document.__data__ + local __xrefs__ = document.__xrefs__ + local __cache__ = document.__cache__ + local __xref__ = document.__xref__ + -- + local rawcatalog = getRawCatalog(__data__) + local nofpages = getNumPages(rawcatalog) -- - local rawcatalog = getRawCatalog(__data__) - local nofpages = getNumPages(rawcatalog) + local majorversion = getMajorVersion(__data__) + local minorversion = getMinorVersion(__data__) -- - local pages = { } - local metatable = { __index = Catalog.Pages } -- somewhat empty + local pages = { } + local metatable = { __index = Catalog.Pages } -- somewhat empty -- for pagenumber=1,nofpages do local pagereference = getPageRef(rawcatalog,pagenumber).num @@ -580,6 +714,7 @@ local function getpages(document,Catalog) if pagedata then -- rawset(pagedata,"number",pagenumber) pagedata.number = pagenumber + pagedata.object = pageobject pages[pagenumber] = pagedata __xrefs__[pagedata] = pagereference __cache__[pagereference] = pagedata @@ -590,7 +725,10 @@ local function getpages(document,Catalog) -- pages.n = nofpages -- - document.pages = pages + document.pages = pages + document.majorversion = majorversion + document.minorversion = minorversion + -- return pages end @@ -637,6 +775,8 @@ function lpdf_epdf.load(filename) document.Catalog = some_dictionary(getDict(getCatalog(__xref__)),document) document.Info = some_dictionary(getDict(getDocInfo(__xref__)),document) setmetatableindex(document,resolve) + -- + document.nofpages = getNumPages(getRawCatalog(__data__)) else document = false end @@ -735,14 +875,14 @@ local fromunicode = ( P(1) )^1 * Carg(1) -local function analyzefonts(document,resources) -- unfinished +local function analyzefonts(document,resources) -- unfinished, see mtx-pdf for better code local fonts = document.__fonts__ if resources then local fontlist = resources.Font if fontlist then for id, data in expanded(fontlist) do if not fonts[id] then - -- a quck hack ... I will look into it more detail if I find a real + -- a quick hack ... I will look into it more detail if I find a real -- -application for it local tounicode = data.ToUnicode() if tounicode then @@ -836,7 +976,7 @@ function lpdf_epdf.getpagecontent(document,pagenumber) end --- This is also an experiment. When I really neet it I can improve it, fo rinstance +-- This is also an experiment. When I really need it I can improve it, for instance -- with proper position calculating. It might be usefull for some search or so. local softhyphen = utfchar(0xAD) .. "$" @@ -925,3 +1065,249 @@ end -- local destination = document.__data__:findDest(name) -- return destination and destination.number -- end + +-- This is experimental code that we need for testing the transition from +-- poppler to a new lightweight library. Don't rely on this code to remain +-- as it is now. Interesting is that performance of this variant is the same +-- as the natural page includer. + +if img then do + + local copydictionary = nil + local copyarray = nil + + local ref_object_code = typenumbers.ref + local boolean_object_code = typenumbers.boolean + local integer_object_code = typenumbers.integer + local real_object_code = typenumbers.real + local string_object_code = typenumbers.string + local name_object_code = typenumbers.name + local null_object_code = typenumbers.null + local array_object_code = typenumbers.array + local dictionary_object_code = typenumbers.dictionary + local stream_object_code = typenumbers.stream + local cmd_object_code = typenumbers.cmd + + local pdfreserveobject = lpdf.reserveobject + local pdfflushobject = lpdf.flushobject + local pdfflushstreamobject = lpdf.flushstreamobject + local pdfreference = lpdf.reference + local pdfconstant = lpdf.constant + local pdfarray = lpdf.array + local pdfdictionary = lpdf.dictionary + local pdfunicode = lpdf.unicode + local pdfstring = lpdf.string + local pdfnull = lpdf.null + + local report = logs.reporter("backend","xobjects") + + local factor = 65536 / (7200/7227) -- 1/number.dimenfactors.bp + + local createimage = images.create + + local function scaledbbox(b) + return { b[1]*factor, b[2]*factor, b[3]*factor, b[4]*factor } + end + + local function copyobject(xref,copied,kind,r,v) + if kind == null_object_code then + return pdfnull() + elseif r and getType(r) == ref_object_code then + local objnum = getRefNum(r) + local r = copied[objnum] + if r then + -- report("%s object %i is reused",kind,objnum) + else + local o + r = pdfreserveobject() + copied[objnum] = r + if kind == array_object_code then + local a = copyarray(xref,copied,fetch(xref,objnum,0)) + pdfflushobject(r,tostring(a)) + elseif kind == dictionary_object_code then + local d = copydictionary(xref,copied,fetch(xref,objnum,0)) + pdfflushobject(r,tostring(d)) + elseif kind == stream_object_code then + local f = fetch(xref,objnum,0) + local d = copydictionary(xref,copied,false,streamGetDict(f)) + local s = getstream(f) + -- + d.Filter = nil + d.Length = nil + d.DecodeParms = nil + d.DL = nil + -- + pdfflushstreamobject(s,d,true,r) + else + report("reference not done: %s", kind) + end + end + return pdfreference(r) + elseif kind == array_object_code then + return copyarray(xref,copied,v) + elseif kind == dictionary_object_code then + return copydictionary(xref,copied,v) + elseif kind == integer_object_code then + return getInt(v) + elseif kind == real_object_code then + return getReal(v) + elseif kind == name_object_code then + return pdfconstant(getName(v)) + elseif kind == string_object_code then + local s = getString(v) + if not s or s == "" then + return "" + end + local u = lpegmatch(u_pattern,s) + if u then + return pdfunicode(s) + end + return pdfstring(s) + elseif kind == boolean_object_code then + return getBool(v) + elseif kind == stream_object_code then + -- hm ... + return getStream(v) + else + report("object not done: %s", kind) + end + end + + copyarray = function (xref,copied,object) + local a = getArray(object) + local n = a and arrayGetLength(a) or 0 + if n > 0 then + local target = pdfarray() + for i=1,n do + local v = arrayGet(a,i) + if v then + local kind = getType(v) + local r = arrayGetNF(a,i) + target[i] = copyobject(xref,copied,kind,r,v) + end + end + return target + end + end + + copydictionary = function (xref,copied,object,d) + local d = d or getDict(object) + local n = d and dictGetLength(d) or 0 + if n > 0 then + local target = pdfdictionary() + for i=1,n do + local v = dictGetVal(d,i) + if v then + local kind = getType(v) + local key = dictGetKey(d,i) + local r = dictGetValNF(d,i) + target[key] = copyobject(xref,copied,kind,r,v) + end + end + return target + end + end + + local function copy_resources(pdfdoc,xref,copied,pagedata) + local object = pagedata.object + if object then + local d = getDict(object) + local n = d and dictGetLength(d) or 0 + for i=1,n do + local k = dictGetKey(d,i) + if v and k == "Resources" then + local v = dictGetVal(d,i) + local kind = getType(v) + local r = dictGetValNF(d,i) + return copyobject(xref,copied,kind,r,v) + end + end + end + end + + local function openpdf(filename) + local pdfdoc = lpdf_epdf.load(filename) + if pdfdoc then + pdfdoc.__copied__ = pdfdoc.__copied__ or { } + pdfdoc.filename = filename + return pdfdoc + end + end + + local function closepdf(pdfdoc) + if pdfdoc then + lpdf_epdf.unload(pdfdoc.filename) + end + end + + local function querypdf(pdfdoc,pagenumber) + if pdfdoc then + if not pagenumber then + pagenumber = 1 + end + local root = pdfdoc.Catalog + local page = pdfdoc.pages[pagenumber] + if page then + local mediabox = page.MediaBox or { 0, 0, 0, 0 } + local cropbox = page.CropBox or mediabox + return { + filename = pdfdoc.filename, + pagenumber = pagenumber, + nofpages = pdfdoc.nofpages, + boundingbox = scaledbbox(cropbox), + cropbox = cropbox, + mediabox = mediabox, + bleedbox = page.BleedBox or cropbox, + trimbox = page.TrimBox or cropbox, + artbox = page.ArtBox or cropbox, + } + end + end + end + + local function copypage(pdfdoc,pagenumber,attributes) + if pdfdoc then + local root = pdfdoc.Catalog + local page = pdfdoc.pages[pagenumber or 1] + local pageinfo = querypdf(pdfdoc,pagenumber) + local contents = page.Contents + local xref = pdfdoc.__xref__ + local copied = pdfdoc.__copied__ + -- + local xobject = pdfdictionary { + Type = pdfconstant("XObject"), + Subtype = pdfconstant("Form"), + -- image attributes + FormType = 1, + BBox = pageinfo.cropbox, + -- Metadata = copy(xref,copied,root,"Metadata"), + -- Group = copy(xref,copied,page,"Group"), + -- LastModified = copy(xref,copied,page,"LastModified"), + -- Metadata = copy(xref,copied,page,"Metadata"), + -- PieceInfo = copy(xref,copied,page,"PieceInfo"), + Resources = copy_resources(pdfdoc,xref,copied,page), + -- SeparationInfo = copy(xref,copied,page,"SeparationInfo"), + } + if attributes then + for k, v in next, expand(attributes) do + page[k] = v -- maybe nested + end + end + return createimage { + bbox = pageinfo.boundingbox, + stream = contents(), + attr = xobject(), + } + end + end + + -- todo: codeinjections + + lpdf_epdf.image = { + open = openpdf, + close = closepdf, + query = querypdf, + copy = copypage, + } + +end end diff --git a/tex/context/base/mkiv/lpdf-fld.lua b/tex/context/base/mkiv/lpdf-fld.lua index 73de5eaf6..983be508f 100644 --- a/tex/context/base/mkiv/lpdf-fld.lua +++ b/tex/context/base/mkiv/lpdf-fld.lua @@ -103,7 +103,7 @@ local pdf_tx = pdfconstant("Tx") local pdf_sig = pdfconstant("Sig") local pdf_ch = pdfconstant("Ch") local pdf_btn = pdfconstant("Btn") ------ pdf_yes = pdfconstant("Yes") +local pdf_yes = pdfconstant("Yes") local pdf_off = pdfconstant("Off") local pdf_p = pdfconstant("P") -- None Invert Outline Push local pdf_n = pdfconstant("N") -- None Invert Outline Push @@ -341,10 +341,10 @@ local function fieldsurrounding(specification) alternative, a = "tf", s.tf end local tag = fontstyle .. fontalternative - fontsize = todimen(fontsize) - fontsize = fontsize and (bpfactor * fontsize) or 12 + fontsize = todimen(fontsize) + fontsize = fontsize and (bpfactor * fontsize) or 12 fontraise = 0.1 * fontsize -- todo: figure out what the natural one is and compensate for strutdp - local fontcode = formatters["%0.4f Tf %0.4f Ts"](fontsize,fontraise) + local fontcode = formatters["%0.4F Tf %0.4F Ts"](fontsize,fontraise) -- we could test for colorvalue being 1 (black) and omit it then local colorcode = pdfcolor(3,colorvalue) -- we force an rgb color space if trace_fields then @@ -360,14 +360,16 @@ local function fieldsurrounding(specification) return tostring(stream) end +-- Can we use any font? + codeinjections.fieldsurrounding = fieldsurrounding local function registerfonts() if next(usedfonts) then checkpdfdocencoding() -- already done - local d = pdfdictionary() - local pdffonttype, pdffontsubtype = pdfconstant("Font"), pdfconstant("Type1") - -- for tag, name in next, usedfonts do + local pdffontlist = pdfdictionary() + local pdffonttype = pdfconstant("Font") + local pdffontsubtype = pdfconstant("Type1") for tag, name in sortedhash(usedfonts) do local f = pdfdictionary { Type = pdffonttype, @@ -376,9 +378,9 @@ local function registerfonts() BaseFont = pdfconstant(name), Encoding = pdfdocencodingvector, } - d[tag] = pdfreference(pdfflushobject(f)) + pdffontlist[tag] = pdfreference(pdfflushobject(f)) end - return d + return pdffontlist end end @@ -386,7 +388,7 @@ end local function fieldappearances(specification) -- todo: caching - local values = specification.values + local values = specification.values local default = specification.default -- todo if not values then -- error @@ -402,22 +404,51 @@ local function fieldappearances(specification) n, r, d = v[1], v[2], v[3] end local appearance = pdfdictionary { - N = registeredsymbol(n), R = registeredsymbol(r), D = registeredsymbol(d), + N = registeredsymbol(n), + R = registeredsymbol(r), + D = registeredsymbol(d), } return pdfshareobjectreference(appearance) -- return pdfreference(pdfflushobject(appearance)) end -local YesorOn = "Yes" -- somehow On is not always working out well any longer (why o why this change) - --- beware ... maybe we should have unique /Yes1 ... we will probably --- change this one too. +-- The rendering part of form support has always been crappy and didn't really +-- improve over time. Did bugs become features? Who knows. Why provide for instance +-- control over appearance and then ignore it when the mouse clicks someplace else. +-- Strangely enough a lot of effort went into JavaScript support while basic +-- appearance control of checkboxes stayed poor. I found this link when googling for +-- conformation after the n^th time looking into this behaviour: +-- +-- https://stackoverflow.com/questions/15479855/pdf-appearance-streams-checkbox-not-shown-correctly-after-focus-lost +-- +-- ... "In particular check boxes, therefore, whenever not interacting with the user, shall +-- be displayed using their normal captions, not their appearances." -- --- TODO: the same as radio .. play safe and use different names. +-- So: don't use check boxes. In fact, even radio buttons can have these funny "flash some +-- funny symbol" side effect when clocking on them. I tried all combinations if /H and /AP +-- and /AS and ... Because (afaiks) the acrobat interface assumes that one uses dingbats no +-- one really cared about getting custom appeances done well. This erratic behaviour might +-- as well be the reason why no open source viewer ever bothered implementing forms. It's +-- probably also why most forms out there look kind of bad. + +local function fieldstates_precheck(specification) + local values = specification.values + local default = specification.default + if not values or values == "" then + return + end + local yes = settings_to_array(values)[1] + local yesshown, yesvalue = lpegmatch(splitter,yes) + if not (yesshown and yesvalue) then + yesshown = yes + end + return default == settings_to_array(yesshown)[1] and pdf_yes or pdf_off +end -local function fieldstates_check(specification,forceyes,values,default,yesdefault) +local function fieldstates_check(specification) -- we don't use Opt here (too messy for radio buttons) - local values, default = values or specification.values, default or specification.default + local values = specification.values + local default = specification.default if not values or values == "" then -- error return @@ -459,28 +490,27 @@ local function fieldstates_check(specification,forceyes,values,default,yesdefaul if not offvalue then offvalue = offn end - if forceyes == true then - forceyes = YesorOn -- spec likes Yes more but we've used On for ages now - else - -- false or string - end if default == yesn then - default = pdfconstant(forceyes or yesn) + default = pdf_yes + yesvalue = yesvalue == yesn and "Yes" or "Off" else - default = pdf_off + default = pdf_off + yesvalue = "Off" end local appearance - if false then -- needs testing + -- if false then + if true then + -- needs testing appearance = pdfdictionary { -- maybe also cache components - N = pdfshareobjectreference(pdfdictionary { [forceyes or yesn] = registeredsymbol(yesn), Off = registeredsymbol(offn) }), - R = pdfshareobjectreference(pdfdictionary { [forceyes or yesr] = registeredsymbol(yesr), Off = registeredsymbol(offr) }), - D = pdfshareobjectreference(pdfdictionary { [forceyes or yesd] = registeredsymbol(yesd), Off = registeredsymbol(offd) }), + N = pdfshareobjectreference(pdfdictionary { Yes = registeredsymbol(yesn), Off = registeredsymbol(offn) }), + R = pdfshareobjectreference(pdfdictionary { Yes = registeredsymbol(yesr), Off = registeredsymbol(offr) }), + D = pdfshareobjectreference(pdfdictionary { Yes = registeredsymbol(yesd), Off = registeredsymbol(offd) }), } else appearance = pdfdictionary { -- maybe also cache components - N = pdfdictionary { [forceyes or yesn] = registeredsymbol(yesn), Off = registeredsymbol(offn) }, - R = pdfdictionary { [forceyes or yesr] = registeredsymbol(yesr), Off = registeredsymbol(offr) }, - D = pdfdictionary { [forceyes or yesd] = registeredsymbol(yesd), Off = registeredsymbol(offd) } + N = pdfdictionary { Yes = registeredsymbol(yesn), Off = registeredsymbol(offn) }, + R = pdfdictionary { Yes = registeredsymbol(yesr), Off = registeredsymbol(offr) }, + D = pdfdictionary { Yes = registeredsymbol(yesd), Off = registeredsymbol(offd) } } end local appearanceref = pdfshareobjectreference(appearance) @@ -488,12 +518,11 @@ local function fieldstates_check(specification,forceyes,values,default,yesdefaul return appearanceref, default, yesvalue end --- It looks like there is always a (MK related) symbol used and that --- the appearances are only used as ornaments behind a symbol. So, --- contrary to what we did when widgets showed up, we now limit --- ourself to more dumb definitions. Especially when highlighting is --- enabled weird interferences happen. So, we play safe (some nice code --- has been removed that worked well till recently). +-- It looks like there is always a (MK related) symbol used and that the appearances +-- are only used as ornaments behind a symbol. So, contrary to what we did when +-- widgets showed up, we now limit ourself to more dumb definitions. Especially when +-- highlighting is enabled weird interferences happen. So, we play safe (some nice +-- code has been removed that worked well till recently). local function fieldstates_radio(specification,name,parent) local values = values or specification.values @@ -572,7 +601,7 @@ local function fieldstates_radio(specification,name,parent) return appearanceref, default, yesvalue end -local function fielddefault(field) +local function fielddefault(field,pdf_yes) local default = field.default if not default or default == "" then local values = settings_to_array(field.values) @@ -581,12 +610,12 @@ local function fielddefault(field) if not default or default == "" then return pdf_off else - return pdfconstant(default) + return pdf_yes or pdfconstant(default) end end local function fieldoptions(specification) - local values = specification.values + local values = specification.values local default = specification.default if values then local v = settings_to_array(values) @@ -790,7 +819,9 @@ function codeinjections.definefield(specification) end function codeinjections.clonefield(specification) -- obsolete - local p, c, v = specification.parent, specification.children, specification.alternative + local p = specification.parent + local c = specification.children + local v = specification.alternative if not p or not c then if trace_fields then report_fields("invalid clone, children %a, parent %a, alternative %a",c,p,v) @@ -874,7 +905,8 @@ local function enhance(specification,option) return specification end --- finish +-- finish (if we also collect parents we can inline the kids which is +-- more efficient ... but hardly anyone used widgets so ...) local collected = pdfarray() local forceencoding = false @@ -949,14 +981,14 @@ end local function save_parent(field,specification,d,hasopt) local kidsnum = pdfreserveobject() - d.Kids = pdfreference(kidsnum) + d.Kids = pdfreference(kidsnum) field.kidsnum = kidsnum - field.kids = pdfarray() + field.kids = pdfarray() if hasopt then local optnum = pdfreserveobject() - d.Opt = pdfreference(optnum) + d.Opt = pdfreference(optnum) field.optnum = optnum - field.opt = pdfarray() + field.opt = pdfarray() end local pnum = pdfflushobject(d) field.pobj = pnum @@ -972,16 +1004,21 @@ local function save_kid(field,specification,d,optname) opt[#opt+1] = optname end end - local width, height, depth = specification.width or 0, specification.height or 0, specification.depth + local width = specification.width or 0 + local height = specification.height or 0 + local depth = specification.depth or 0 local box = hpack_node(nodeinjections.annotation(width,height,depth,d(),kn)) - box.width, box.height, box.depth = width, height, depth -- redundant + -- redundant + box.width = width + box.height = height + box.depth = depth return box end local function makelineparent(field,specification) - local text = pdfunicode(field.default) + local text = pdfunicode(field.default) local length = tonumber(specification.length or 0) or 0 - local d = pdfdictionary { + local d = pdfdictionary { Subtype = pdf_widget, T = pdfunicode(specification.title), F = fieldplus(specification), @@ -999,7 +1036,8 @@ local function makelineparent(field,specification) end local function makelinechild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1010,7 +1048,7 @@ local function makelinechild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent text %a",name) @@ -1047,9 +1085,9 @@ end -- copy of line ... probably also needs a /Lock local function makesignatureparent(field,specification) - local text = pdfunicode(field.default) + local text = pdfunicode(field.default) local length = tonumber(specification.length or 0) or 0 - local d = pdfdictionary { + local d = pdfdictionary { Subtype = pdf_widget, T = pdfunicode(specification.title), F = fieldplus(specification), @@ -1067,7 +1105,8 @@ local function makesignatureparent(field,specification) end local function makesignaturechild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1078,7 +1117,7 @@ local function makesignaturechild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent text %a",name) @@ -1124,7 +1163,8 @@ local function makechoiceparent(field,specification) end local function makechoicechild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1135,7 +1175,7 @@ local function makechoicechild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent choice %a",name) @@ -1169,20 +1209,22 @@ function methods.combo(name,specification) end local function makecheckparent(field,specification) + local default = fieldstates_precheck(field) local d = pdfdictionary { T = pdfunicode(specification.title), -- todo: when tracing use a string F = fieldplus(specification), Ff = fieldflag(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared FT = pdf_btn, - V = fielddefault(field), + V = fielddefault(field,default), } save_parent(field,specification,d,true) end local function makecheckchild(name,specification) - local field, parent = clones[name], nil + local field = clones[name] + local parent = nil if field then parent = fields[field.parent] if not parent.pobj then @@ -1193,7 +1235,7 @@ local function makecheckchild(name,specification) end else parent = fields[name] - field = parent + field = parent if not parent.pobj then if trace_fields then report_fields("using parent check %a",name) @@ -1209,7 +1251,7 @@ local function makecheckchild(name,specification) Parent = pdfreference(parent.pobj), F = fieldplus(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared H = pdf_n, } local fontsymbol = specification.fontsymbol @@ -1221,10 +1263,10 @@ local function makecheckchild(name,specification) d.MK = fieldrendering(specification) return save_kid(parent,specification,d) else - local appearance, default, value = fieldstates_check(field,true) + local appearance, default, value = fieldstates_check(field) d.AS = default d.AP = appearance - return save_kid(parent,specification,d,value) + return save_kid(parent,specification,d) end end @@ -1239,7 +1281,7 @@ local function makepushparent(field,specification) -- check if we can share with F = fieldplus(specification), Ff = fieldflag(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared FT = pdf_btn, AP = fieldappearances(field), H = pdf_p, @@ -1276,7 +1318,7 @@ local function makepushchild(name,specification) Parent = pdfreference(field.pobj), F = fieldplus(specification), OC = fieldlayer(specification), - AA = fieldactions(specification), + AA = fieldactions(specification), -- can be shared H = pdf_p, } if fontsymbol and fontsymbol ~= "" then @@ -1311,7 +1353,7 @@ end local function makeradiochild(name,specification) local field, parent = clones[name], nil if field then - field = radios[field.parent] + field = radios[field.parent] parent = fields[field.parent] if not parent.pobj then if trace_fields then diff --git a/tex/context/base/mkiv/lpdf-fmt.lua b/tex/context/base/mkiv/lpdf-fmt.lua index 0830d2d8d..25a72fa49 100644 --- a/tex/context/base/mkiv/lpdf-fmt.lua +++ b/tex/context/base/mkiv/lpdf-fmt.lua @@ -116,6 +116,7 @@ local formats = utilities.storage.allocate { jbig2_compression = true, -- todo: block at lua level jpeg2000_compression = true, -- todo: block at lua level include_cidsets = true, + include_charsets = true, inject_metadata = function() -- nothing end @@ -131,6 +132,7 @@ local formats = utilities.storage.allocate { spot_colors = true, internal_icc_profiles = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() addtoinfo("GTS_PDFXVersion","PDF/X-1a:2001") injectxmpinfo("xml://rdf:RDF","PDF/X-1a:2001",false) @@ -146,6 +148,7 @@ local formats = utilities.storage.allocate { spot_colors = true, internal_icc_profiles = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() addtoinfo("GTS_PDFXVersion","PDF/X-1a:2003") injectxmpinfo("xml://rdf:RDF","PDF/X-1a:2003",false) @@ -165,6 +168,7 @@ local formats = utilities.storage.allocate { internal_icc_profiles = true, include_intents = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() addtoinfo("GTS_PDFXVersion","PDF/X-3:2002") end @@ -184,6 +188,7 @@ local formats = utilities.storage.allocate { include_intents = true, jbig2_compression = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() addtoinfo("GTS_PDFXVersion","PDF/X-3:2003") end @@ -207,6 +212,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, object_compression = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","PDF/X-4",false) insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","1",false) @@ -233,6 +239,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, object_compression = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","PDF/X-4p",false) insertxmpinfo("xml://rdf:Description/xmpMM:InstanceID","1",false) @@ -259,6 +266,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, object_compression = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() -- todo end @@ -284,6 +292,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, object_compression = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() -- todo end @@ -308,6 +317,7 @@ local formats = utilities.storage.allocate { nchannel_colorspace = true, object_compression = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() -- todo end @@ -328,6 +338,7 @@ local formats = utilities.storage.allocate { tagging = true, -- NEW; the only difference to PDF/A-1b internal_icc_profiles = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","1A",false) end @@ -347,6 +358,7 @@ local formats = utilities.storage.allocate { forms = true, internal_icc_profiles = true, include_cidsets = true, + include_charsets = true, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","1B",false) end @@ -371,6 +383,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, -- NEW object_compression = true, include_cidsets = false, + include_charsets = false, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","2A",false) end @@ -395,6 +408,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, object_compression = true, include_cidsets = false, + include_charsets = false, inject_metadata = function() injectxmpinfo("xml://rdf:RDF","3A",false) end @@ -418,6 +432,7 @@ local formats = utilities.storage.allocate { jpeg2000_compression = true, object_compression = true, include_cidsets = true, + include_charsets = true, --- really ? inject_metadata = function() injectxmpinfo("xml://rdf:RDF","3A",false) injectxmpinfo("xml://rdf:RDF","1",false) @@ -753,7 +768,11 @@ function codeinjections.setformat(s) majorversion,minorversion) end -- - pdf.setomitcidset(formatspecification.include_cidsets == false and 1 or 0) + -- cid sets can always omitted now, but those validators still complain so let's + -- for a while keep it (for luigi): + -- + lpdf.setomitcidset (formatspecification.include_cidsets == false and 1 or 0) + lpdf.setomitcharset(formatspecification.include_charsets == false and 1 or 0) -- -- context.setupcolors { -- not this way -- cmyk = spec.cmyk_colors and variables.yes or variables.no, diff --git a/tex/context/base/mkiv/lpdf-fnt.lua b/tex/context/base/mkiv/lpdf-fnt.lua new file mode 100644 index 000000000..1caa2f93c --- /dev/null +++ b/tex/context/base/mkiv/lpdf-fnt.lua @@ -0,0 +1,202 @@ +if not modules then modules = { } end modules ['lpdf-fnt'] = { + version = 1.001, + comment = "companion to lpdf-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is experimental code. + +local match, gmatch = string.match, string.gmatch +local tonumber = tonumber + +local pdfreserveobject = lpdf.reserveobject +local pdfincludechar = lpdf.includechar +local pdfincludefont = lpdf.includefont +local pdfreference = lpdf.reference + +local pdfe = lpdf.epdf + +local tobemerged = { } +local trace_merge = false trackers.register("graphics.fonts",function(v) trace_merge = v end) +local report_merge = logs.reporter("graphics","fonts") + +local function register(usedname,cleanname) + local cleanname = cleanname or fonts.names.cleanname(usedname) + local fontid = fonts.definers.internal { name = cleanname } + if fontid then + local objref = pdfreserveobject() + pdfincludefont(fontid) + if trace_merge then + report_merge("registering %a with name %a, id %a and object %a",usedname,cleanname,fontid,objref) + end + return { + id = fontid, + reference = objref, + indices = { }, + cleanname = cleanname, + } + end + return false +end + +function lpdf.registerfont(usedname,cleanname) + local v = register(usedname,cleanname) + tobemerged[usedname] = v + return v +end + +table.setmetatableindex(tobemerged,function(t,k) + return lpdf.registerfont(k) +end) + +local function finalizefont(v) + local indextoslot = fonts.helpers.indextoslot + if v then + local id = v.id + local n = 0 + for i in next, v.indices do + local u = indextoslot(id,i) + -- pdfincludechar(id,u) + n = n + 1 + end + v.n = n + end +end + +statistics.register("merged fonts", function() + if next(tobemerged) then + local t = { } + for k, v in table.sortedhash(tobemerged) do + t[#t+1] = string.formatters["%s (+%i)"](k,v.n) + end + return table.concat(t," ") + end +end) + +function lpdf.finalizefonts() + for k, v in next, tobemerged do + finalizefont(v) + end +end + +callback.register("font_descriptor_objnum_provider",function(name) + local m = rawget(tobemerged,name) + if m then + -- finalizefont(m) + local r = m.reference or 0 + if trace_merge then + report_merge("using object %a for font descriptor of %a",r,name) + end + return r + end + return 0 +end) + +local function getunicodes1(str,indices) + for s in gmatch(str,"beginbfrange%s*(.-)%s*endbfrange") do + for first, last, offset in gmatch(s,"<([^>]+)>%s+<([^>]+)>%s+<([^>]+)>") do + for i=tonumber(first,16),tonumber(last,16) do + indices[i] = true + end + end + end + for s in gmatch(str,"beginbfchar%s*(.-)%s*endbfchar") do + for old, new in gmatch(s,"<([^>]+)>%s+<([^>]+)>") do + indices[tonumber(old,16)] = true + end + end +end + +local function getunicodes2(widths,indices) + for i=1,#widths,2 do + local start = widths[i] + local count = #widths[i+1] + if start and count then + for i=start,start+count-1 do + indices[i] = true + end + end + end +end + +local function checkedfonts(pdfdoc,xref,copied,page) + local list = page.Resources.Font + local done = { } + for k, somefont in pdfe.expanded(list) do + if somefont.Subtype == "Type0" and somefont.Encoding == "Identity-H" then + local descendants = somefont.DescendantFonts + if descendants then + for i=1,#descendants do + local d = descendants[i] + if d then + local subtype = d.Subtype + if subtype == "CIDFontType0" or subtype == "CIDFontType2" then + local basefont = somefont.BaseFont + if basefont then + local fontname = match(basefont,"^[A-Z]+%+(.+)$") + local fontdata = tobemerged[fontname] + if fontdata then + local descriptor = d.FontDescriptor + if descriptor then + local okay = false + local widths = d.W + if widths then + getunicodes2(widths,fontdata.indices) + okay = true + else + local tounicode = somefont.ToUnicode + if tounicode then + getunicodes1(tounicode(),fontdata.indices) + okay = true + end + end + if okay then + local r = xref[descriptor] + done[r] = fontdata.reference + end + end + end + end + end + end + end + end + end + end + return next(done) and done +end + +if pdfincludefont then + + function lpdf.epdf.plugin(pdfdoc,xref,copied,page) + local done = checkedfonts(pdfdoc,xref,copied,page) + if done then + return { + FontDescriptor = function(xref,copied,object,key,value,copyobject) + local r = value[3] + local d = done[r] + if d then + return pdfreference(d) + else + return copyobject(xref,copied,object,key,value) + end + end + } + end + end + +else + + function lpdf.epdf.plugin() end + +end + +lpdf.registerdocumentfinalizer(lpdf.finalizefonts) + +-- already defined in font-ocl but the context variatn will go here +-- +-- function lpdf.vfimage(wd,ht,dp,data,name) +-- return { "image", { filename = name, width = wd, height = ht, depth = dp } } +-- end diff --git a/tex/context/base/mkiv/lpdf-grp.lua b/tex/context/base/mkiv/lpdf-grp.lua index 34925fddd..49cc76871 100644 --- a/tex/context/base/mkiv/lpdf-grp.lua +++ b/tex/context/base/mkiv/lpdf-grp.lua @@ -29,6 +29,10 @@ local pdfboolean = lpdf.boolean local pdfreference = lpdf.reference local pdfflushobject = lpdf.flushobject +local createimage = images.create +local wrapimage = images.wrap +local embedimage = images.embed + -- can also be done indirectly: -- -- 12 : << /AntiAlias false /ColorSpace 8 0 R /Coords [ 0.0 0.0 1.0 0.0 ] /Domain [ 0.0 1.0 ] /Extend [ true true ] /Function 22 0 R /ShadingType 2 >> @@ -153,13 +157,18 @@ function nodeinjections.injectbitmap(t) elseif height == 0 then height = width * yresolution / xresolution end - local image = img.new { + local a = pdfdictionary { + BBox = pdfarray { 0, 0, urx * basepoints, ury * basepoints } + } + local image = createimage { stream = formatters[template](d(),t.data), width = width, height = height, bbox = { 0, 0, urx, ury }, + attr = a(), + nobbox = true, } - return img.node(image) + return wrapimage(image) end -- general graphic helpers @@ -181,7 +190,7 @@ function codeinjections.setfigurealternative(data,figure) local displayfigure = figures.check() if displayfigure then -- figure.aform = true - img.immediatewrite(figure) + embedimage(figure) local a = pdfarray { pdfdictionary { Image = pdfreference(figure.objnum), @@ -215,14 +224,14 @@ function codeinjections.getpreviewfigure(request) end local image = figure.status.private if image then - img.immediatewrite(image) + embedimage(image) end return figure end function codeinjections.setfiguremask(data,figure) -- mark local request = data.request - local mask = request.mask + local mask = request.mask if mask and mask ~= "" then figures.push { name = mask, @@ -233,15 +242,16 @@ function codeinjections.setfiguremask(data,figure) -- mark width = request.width, height = request.height, } - figures.identify() - local maskfigure = figures.check() - if maskfigure then - local image = maskfigure.status.private + mask = figures.identify() + mask = figures.check(mask) + if mask then + local image = mask.status.private if image then - img.immediatewrite(image) + figures.include(mask) + embedimage(image) local d = pdfdictionary { Interpolate = false, - SMask = pdfreference(image.objnum), + SMask = pdfreference(mask.status.objectnumber), } figure.attr = d() end @@ -250,39 +260,16 @@ function codeinjections.setfiguremask(data,figure) -- mark end end --- temp hack +-- experimental (q Q is not really needed) -function img.package(image) -- see lpdf-u3d ** - local boundingbox = image.bbox - local imagetag = "Im" .. image.index - local resources = pdfdictionary { - ProcSet = pdfarray { - pdfconstant("PDF"), - pdfconstant("ImageC") - }, - Resources = pdfdictionary { - XObject = pdfdictionary { - [imagetag] = pdfreference(image.objnum) - } - } - } - local width = boundingbox[3] - local height = boundingbox[4] - local xform = img.scan { - attr = resources(), - stream = formatters["%.6F 0 0 %.6F 0 0 cm /%s Do"](width,height,imagetag), - bbox = { 0, 0, width/basepoints, height/basepoints }, - } - img.immediatewrite(xform) - return xform -end +local f_pattern = formatters["q /Pattern cs /%s scn 0 0 %.6F %.6F re f Q"] --- experimental +directives.register("pdf.stripzeros",function() + f_pattern = formatters["q /Pattern cs /%s scn 0 0 %.6N %.6N re f Q"] +end) -local nofpatterns = 0 -local f_pattern = formatters["q /Pattern cs /%s scn 0 0 %.6F %.6F re f Q"] -- q Q is not really needed - -local texsavebox = tex.saveboxresource +local saveboxresource = tex.boxresources.save +local nofpatterns = 0 function lpdf.registerpattern(specification) nofpatterns = nofpatterns + 1 @@ -299,10 +286,11 @@ function lpdf.registerpattern(specification) (specification.voffset or 0) * basepoints, }, } + local resources = lpdf.collectedresources{ patterns = false } local attributes = d() local onlybounds = 1 - local patternobj = texsavebox(specification.number,attributes,resources,true,onlybounds) + local patternobj = saveboxresource(specification.number,attributes,resources,true,onlybounds) lpdf.adddocumentpattern("Pt" .. nofpatterns,lpdf.reference(patternobj )) return nofpatterns end diff --git a/tex/context/base/mkiv/lpdf-ini.lua b/tex/context/base/mkiv/lpdf-ini.lua index 8af1fb409..ec837449f 100644 --- a/tex/context/base/mkiv/lpdf-ini.lua +++ b/tex/context/base/mkiv/lpdf-ini.lua @@ -13,7 +13,8 @@ local char, byte, format, gsub, concat, match, sub, gmatch = string.char, string local utfchar, utfbyte, utfvalues = utf.char, utf.byte, utf.values local sind, cosd, max, min = math.sind, math.cosd, math.max, math.min local sort = table.sort -local lpegmatch, P, C, R, S, Cc, Cs = lpeg.match, lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs +local P, C, R, S, Cc, Cs, V = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Cs, lpeg.V +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local formatters = string.formatters local isboolean = string.is_boolean local rshift = bit32.rshift @@ -31,217 +32,234 @@ local context = context -- encoded utf16 string type between <>. We could probably save some bytes by using -- strings between () but then we end up with escaped ()\ too. --- gethpos : used --- getpos : used --- getvpos : used --- --- getmatrix : used --- hasmatrix : used --- --- mapfile : used in font-ctx.lua --- mapline : used in font-ctx.lua --- --- maxobjnum : not used --- obj : used --- immediateobj : used --- objtype : not used --- pageref : used --- print : can be used --- refobj : used --- registerannot : not to be used --- reserveobj : used - --- pdf.catalog : used --- pdf.info : used --- pdf.trailer : used --- pdf.names : not to be used - --- pdf.setinfo : used --- pdf.setcatalog : used --- pdf.setnames : not to be used --- pdf.settrailer : used - --- pdf.getinfo : used --- pdf.getcatalog : used --- pdf.getnames : not to be used --- pdf.gettrailer : used - -local pdf = pdf -local factor = number.dimenfactors.bp - -local pdfsetinfo = pdf.setinfo -local pdfsetcatalog = pdf.setcatalog ------ pdfsettrailerid = pdf.settrailerid ------ pdfsetnames = pdf.setnames ------ pdfsettrailer = pdf.settrailer - -local pdfsetpageresources = pdf.setpageresources -local pdfsetpageattributes = pdf.setpageattributes -local pdfsetpagesattributes = pdf.setpagesattributes - -local pdfgetpos = pdf.getpos -local pdfgethpos = pdf.gethpos -local pdfgetvpos = pdf.getvpos -local pdfgetmatrix = pdf.getmatrix -local pdfhasmatrix = pdf.hasmatrix - -local pdfreserveobject = pdf.reserveobj -local pdfimmediateobject = pdf.immediateobj -local pdfdeferredobject = pdf.obj -local pdfreferenceobject = pdf.refobj - -local function pdfdisablecommand(command) - pdf[command] = function() report_blocked("'pdf.%s' is not supported",command) end -end +pdf = type(pdf) == "table" and pdf or { } +local factor = number.dimenfactors.bp -pdfdisablecommand("setinfo") -pdfdisablecommand("setcatalog") -pdfdisablecommand("setnames") -pdfdisablecommand("settrailer") -pdfdisablecommand("setpageresources") -pdfdisablecommand("setpageattributes") -pdfdisablecommand("setpagesattributes") -pdfdisablecommand("registerannot") +local codeinjections = { } +local nodeinjections = { } -pdf.disablecommand = pdfdisablecommand +local backends = backends -local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) -local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) -local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end) -local trace_detail = false trackers.register("backend.detail", function(v) trace_detail = v end) - -local backends = backends -local pdfbackend = { +local pdfbackend = { comment = "backend for directly generating pdf output", - nodeinjections = { }, - codeinjections = { }, + nodeinjections = nodeinjections, + codeinjections = codeinjections, registrations = { }, tables = { }, } -backends.pdf = pdfbackend -lpdf = lpdf or { } -local lpdf = lpdf -lpdf.flags = lpdf.flags or { } -- will be filled later +backends.pdf = pdfbackend -do +lpdf = lpdf or { } +local lpdf = lpdf +lpdf.flags = lpdf.flags or { } -- will be filled later + +local trace_finalizers = false trackers.register("backend.finalizers", function(v) trace_finalizers = v end) +local trace_resources = false trackers.register("backend.resources", function(v) trace_resources = v end) +local trace_objects = false trackers.register("backend.objects", function(v) trace_objects = v end) +local trace_detail = false trackers.register("backend.detail", function(v) trace_detail = v end) - local setmajorversion = pdf.setmajorversion - local setminorversion = pdf.setminorversion - local getmajorversion = pdf.getmajorversion - local getminorversion = pdf.getminorversion +do - if not setmajorversion then + local pdfsetmajorversion, pdfsetminorversion, pdfgetmajorversion, pdfgetminorversion + local pdfsetcompresslevel, pdfsetobjectcompresslevel, pdfgetcompresslevel, pdfgetobjectcompresslevel + local pdfsetsuppressoptionalinfo, pdfsetomitcidset, pdfsetomitcharset - setmajorversion = function() end - getmajorversion = function() return 1 end + updaters.register("backend.update.lpdf",function() + pdfsetmajorversion = pdf.setmajorversion + pdfsetminorversion = pdf.setminorversion + pdfgetmajorversion = pdf.getmajorversion + pdfgetminorversion = pdf.getminorversion - pdf.setmajorversion = setmajorversion - pdf.getmajorversion = getmajorversion + pdfsetcompresslevel = pdf.setcompresslevel + pdfsetobjectcompresslevel = pdf.setobjcompresslevel + pdfgetcompresslevel = pdf.getcompresslevel + pdfgetobjectcompresslevel = pdf.getobjcompresslevel - end + pdfsetsuppressoptionalinfo = pdf.setsuppressoptionalinfo + pdfsetomitcidset = pdf.setomitcidset + pdfsetomitcharset = pdf.setomitcharset + end) function lpdf.setversion(major,minor) - setmajorversion(major or 1) - setminorversion(minor or 7) + pdfsetmajorversion(major or 1) + pdfsetminorversion(minor or 7) end function lpdf.getversion(major,minor) - return getmajorversion(), getminorversion() + return pdfgetmajorversion(), pdfgetminorversion() end - lpdf.majorversion = getmajorversion - lpdf.minorversion = getminorversion - -end - -do - - local setcompresslevel = pdf.setcompresslevel - local setobjectcompresslevel = pdf.setobjcompresslevel - local getcompresslevel = pdf.getcompresslevel - local getobjectcompresslevel = pdf.getobjcompresslevel + function lpdf.majorversion() return pdfgetmajorversion() end + function lpdf.minorversion() return pdfgetminorversion() end local frozen = false + local clevel = 3 + local olevel = 1 function lpdf.setcompression(level,objectlevel,freeze) if not frozen then - setcompresslevel(level or 3) - setobjectcompresslevel(objectlevel or level or 3) + if pdfsetcompresslevel then + pdfsetcompresslevel(level or 3) + pdfsetobjectcompresslevel(objectlevel or level or 3) + else + clevel = level + olevel = objectlevel + end frozen = freeze end end function lpdf.getcompression() - return getcompresslevel(), getobjectcompresslevel() + if pdfgetcompresslevel then + return pdfgetcompresslevel(), pdfgetobjectcompresslevel() + else + return clevel, olevel + end end - lpdf.compresslevel = getcompresslevel - lpdf.objectcompresslevel = getobjectcompresslevel + function lpdf.compresslevel() + if pdfgetcompresslevel then + return pdfgetcompresslevel() + else + return clevel + end + end -end + function lpdf.objectcompresslevel() + if pdfgetobjectcompresslevel then + return pdfgetobjectcompresslevel() + else + return olevel + end + end -local codeinjections = pdfbackend.codeinjections -local nodeinjections = pdfbackend.nodeinjections - -codeinjections.getpos = pdfgetpos lpdf.getpos = pdfgetpos -codeinjections.gethpos = pdfgethpos lpdf.gethpos = pdfgethpos -codeinjections.getvpos = pdfgetvpos lpdf.getvpos = pdfgetvpos -codeinjections.hasmatrix = pdfhasmatrix lpdf.hasmatrix = pdfhasmatrix -codeinjections.getmatrix = pdfgetmatrix lpdf.getmatrix = pdfgetmatrix - --- local function transform(llx,lly,urx,ury,rx,sx,sy,ry) --- local x1 = llx * rx + lly * sy --- local y1 = llx * sx + lly * ry --- local x2 = llx * rx + ury * sy --- local y2 = llx * sx + ury * ry --- local x3 = urx * rx + lly * sy --- local y3 = urx * sx + lly * ry --- local x4 = urx * rx + ury * sy --- local y4 = urx * sx + ury * ry --- llx = min(x1,x2,x3,x4); --- lly = min(y1,y2,y3,y4); --- urx = max(x1,x2,x3,x4); --- ury = max(y1,y2,y3,y4); --- return llx, lly, urx, ury --- end + function lpdf.setsuppressoptionalinfo(n) + if pdfsetsuppressoptionalinfo then + pdfsetsuppressoptionalinfo(n) -- todo + end + end -function lpdf.transform(llx,lly,urx,ury) -- not yet used so unchecked - if pdfhasmatrix() then - local sx, rx, ry, sy = pdfgetmatrix() - local w, h = urx - llx, ury - lly - return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w - -- return transform(llx,lly,urx,ury,sx,rx,ry,sy) - else - return llx, lly, urx, ury + function lpdf.setomitcidset(v) + return pdfsetomitcidset(v) end + + function lpdf.setomitcharset(v) + return pdfsetomitcharset(v) + end + end --- funny values for tx and ty - -function lpdf.rectangle(width,height,depth,offset) - local tx, ty = pdfgetpos() - if offset then - tx = tx - offset - ty = ty + offset - width = width + 2*offset - height = height + offset - depth = depth + offset - end - if pdfhasmatrix() then - local rx, sx, sy, ry = pdfgetmatrix() - return - factor * tx, - factor * (ty - ry*depth + sx*width), - factor * (tx + rx*width - sy*height), - factor * (ty + ry*height - sx*width) - else - return - factor * tx, - factor * (ty - depth), - factor * (tx + width), - factor * (ty + height) +do + + local pdfgetxformname, pdfincludeimage + + updaters.register("backend.update.lpdf",function() + pdfgetxformname = pdf.getxformname + pdfincludeimage = pdf.includeimage + end) + + function lpdf.getxformname(id) return pdfgetxformname(id) end + function lpdf.includeimage(id) return pdfincludeimage(id) end + +end + + local pdfsetpageresources, pdfsetpageattributes, pdfsetpagesattributes + local pdfreserveobject, pdfimmediateobject, pdfdeferredobject, pdfreferenceobject + local pdfgetpagereference + + updaters.register("backend.update.lpdf",function() + pdfreserveobject = pdf.reserveobj + pdfimmediateobject = pdf.immediateobj + pdfdeferredobject = pdf.obj + pdfreferenceobject = pdf.refobj + + pdfgetpagereference = pdf.getpageref + + pdfsetpageresources = pdf.setpageresources + pdfsetpageattributes = pdf.setpageattributes + pdfsetpagesattributes = pdf.setpagesattributes + end) + +local jobpositions = job.positions +local getpos = jobpositions.getpos + +jobpositions.registerhandlers { + getpos = pdf.getpos, + gethpos = pdf.gethpos, + getvpos = pdf.getvpos, +} + +do + + local pdfgetmatrix, pdfhasmatrix, pdfprint + + updaters.register("backend.update.lpdf",function() + pdfgetmatrix = pdf.getmatrix + pdfhasmatrix = pdf.hasmatrix + pdfprint = pdf.print + end) + + function lpdf.print(...) + return pdfprint(...) + end + + pdfbackend.codeinjections.print = lpdf.print -- will go + + -- local function transform(llx,lly,urx,ury,rx,sx,sy,ry) + -- local x1 = llx * rx + lly * sy + -- local y1 = llx * sx + lly * ry + -- local x2 = llx * rx + ury * sy + -- local y2 = llx * sx + ury * ry + -- local x3 = urx * rx + lly * sy + -- local y3 = urx * sx + lly * ry + -- local x4 = urx * rx + ury * sy + -- local y4 = urx * sx + ury * ry + -- llx = min(x1,x2,x3,x4); + -- lly = min(y1,y2,y3,y4); + -- urx = max(x1,x2,x3,x4); + -- ury = max(y1,y2,y3,y4); + -- return llx, lly, urx, ury + -- end + -- + -- function lpdf.transform(llx,lly,urx,ury) -- not yet used so unchecked + -- if pdfhasmatrix() then + -- local sx, rx, ry, sy = pdfgetmatrix() + -- local w, h = urx - llx, ury - lly + -- return llx, lly, llx + sy*w - ry*h, lly + sx*h - rx*w + -- -- return transform(llx,lly,urx,ury,sx,rx,ry,sy) + -- else + -- return llx, lly, urx, ury + -- end + -- end + + -- funny values for tx and ty + + function lpdf.rectangle(width,height,depth,offset) + local tx, ty = getpos() + if offset then + tx = tx - offset + ty = ty + offset + width = width + 2*offset + height = height + offset + depth = depth + offset + end + if pdfhasmatrix() then + local rx, sx, sy, ry = pdfgetmatrix() + return + factor * tx, + factor * (ty - ry*depth + sx*width), + factor * (tx + rx*width - sy*height), + factor * (ty + ry*height - sx*width) + else + return + factor * tx, + factor * (ty - depth), + factor * (tx + width), + factor * (ty + height) + end end + end -- we could use a hash of predefined unicodes @@ -265,204 +283,290 @@ end -- end -- end -local cache = table.setmetatableindex(function(t,k) -- can be made weak - local v = utfbyte(k) - if v < 0x10000 then - v = format("%04x",v) - else - v = format("%04x%04x",rshift(v,10),v%1024+0xDC00) +local tosixteen, fromsixteen, topdfdoc, frompdfdoc, toeight, fromeight + +do + + local escaped = Cs(Cc("(") * (S("\\()\n\r\t\b\f")/"\\%0" + P(1))^0 * Cc(")")) + + local cache = table.setmetatableindex(function(t,k) -- can be made weak + local v = utfbyte(k) + if v < 0x10000 then + v = format("%04x",v) + else + v = format("%04x%04x",rshift(v,10),v%1024+0xDC00) + end + t[k] = v + return v + end) + + local unified = Cs(Cc("")) + + tosixteen = function(str) -- an lpeg might be faster (no table) + if not str or str == "" then + return "" -- not () as we want an indication that it's unicode + else + return lpegmatch(unified,str) + end end - t[k] = v - return v -end) -local escaped = Cs(Cc("(") * (S("\\()")/"\\%0" + P(1))^0 * Cc(")")) -local unified = Cs(Cc("")) + local more = 0 -local function tosixteen(str) -- an lpeg might be faster (no table) - if not str or str == "" then - return "" -- not () as we want an indication that it's unicode - else - return lpegmatch(unified,str) + local pattern = C(4) / function(s) -- needs checking ! + local now = tonumber(s,16) + if more > 0 then + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + more = 0 + return utfchar(now) + elseif now >= 0xD800 and now <= 0xDBFF then + more = now + return "" -- else the c's end up in the stream + else + return utfchar(now) + end end -end -local more = 0 - -local pattern = C(4) / function(s) -- needs checking ! - local now = tonumber(s,16) - if more > 0 then - now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong - more = 0 - return utfchar(now) - elseif now >= 0xD800 and now <= 0xDBFF then - more = now - return "" -- else the c's end up in the stream - else - return utfchar(now) + local pattern = P(true) / function() more = 0 end * Cs(pattern^0) + + fromsixteen = function(str) + if not str or str == "" then + return "" + else + return lpegmatch(pattern,str) + end end -end -local pattern = P(true) / function() more = 0 end * Cs(pattern^0) + local toregime = regimes.toregime + local fromregime = regimes.fromregime -local function fromsixteen(str) - if not str or str == "" then - return "" - else - return lpegmatch(pattern,str) + topdfdoc = function(str,default) + if not str or str == "" then + return "" + else + return lpegmatch(escaped,toregime("pdfdoc",str,default)) -- could be combined if needed + end end -end -local toregime = regimes.toregime -local fromregime = regimes.fromregime + frompdfdoc = function(str) + if not str or str == "" then + return "" + else + return fromregime("pdfdoc",str) + end + end -local function topdfdoc(str,default) - if not str or str == "" then - return "" - else - return lpegmatch(escaped,toregime("pdfdoc",str,default)) -- could be combined if needed + if not toregime then topdfdoc = function(s) return s end end + if not fromregime then frompdfdoc = function(s) return s end end + + toeight = function(str) + if not str or str == "" then + return "()" + else + return lpegmatch(escaped,str) + end end -end -local function frompdfdoc(str) - if not str or str == "" then - return "" - else - return fromregime("pdfdoc",str) + local b_pattern = Cs((P("\\")/"" * ( + S("()") + + S("nrtbf") / { n = "\n", r = "\r", t = "\t", b = "\b", f = "\f" } + + lpegpatterns.octdigit^-3 / function(s) return char(tonumber(s,8)) end) + + P(1))^0) + + fromeight = function(str) + if not str or str == "" then + return "" + else + return lpegmatch(unescape,str) + end end -end -if not toregime then topdfdoc = function(s) return s end end -if not fromregime then frompdfdoc = function(s) return s end end + local u_pattern = lpegpatterns.utfbom_16_be * lpegpatterns.utf16_to_utf8_be -- official + + lpegpatterns.utfbom_16_le * lpegpatterns.utf16_to_utf8_le -- we've seen these + + local h_pattern = lpegpatterns.hextobytes + + local zero = S(" \n\r\t") + P("\\ ") + local one = C(4) + local two = P("d") * R("89","af") * C(2) * C(4) + + local x_pattern = P { "start", + start = V("wrapped") + V("unwrapped") + V("original"), + original = Cs(P(1)^0), + wrapped = P("<") * V("unwrapped") * P(">") * P(-1), + unwrapped = P("feff") + * Cs( ( + zero / "" + + two / function(a,b) + a = (tonumber(a,16) - 0xD800) * 1024 + b = (tonumber(b,16) - 0xDC00) + return utfchar(a+b) + end + + one / function(a) + return utfchar(tonumber(a,16)) + end + )^1 ) * P(-1) + } -local function toeight(str) - if not str or str == "" then - return "()" - else - return lpegmatch(escaped,str) + function lpdf.frombytes(s,hex) + if not s or s == "" then + return "" + end + if hex then + local x = lpegmatch(x_pattern,s) + if x then + return x + end + local h = lpegmatch(h_pattern,s) + if h then + return h + end + else + local u = lpegmatch(u_pattern,s) + if u then + return u + end + end + return lpegmatch(b_pattern,s) end -end -lpdf.tosixteen = tosixteen -lpdf.toeight = toeight -lpdf.topdfdoc = topdfdoc -lpdf.fromsixteen = fromsixteen -lpdf.frompdfdoc = frompdfdoc - -local function merge_t(a,b) - local t = { } - for k,v in next, a do t[k] = v end - for k,v in next, b do t[k] = v end - return setmetatable(t,getmetatable(a)) -end + lpdf.tosixteen = tosixteen + lpdf.toeight = toeight + lpdf.topdfdoc = topdfdoc + lpdf.fromsixteen = fromsixteen + lpdf.fromeight = fromeight + lpdf.frompdfdoc = frompdfdoc -local f_key_null = formatters["/%s null"] -local f_key_value = formatters["/%s %s"] -local f_key_dictionary = formatters["/%s << % t >>"] -local f_dictionary = formatters["<< % t >>"] -local f_key_array = formatters["/%s [ % t ]"] -local f_array = formatters["[ % t ]"] -local f_key_number = formatters["/%s %F"] -local f_tonumber = formatters["%F"] +end local tostring_a, tostring_d -tostring_d = function(t,contentonly,key) - if next(t) then - local r, n = { }, 0 - for k in next, t do - n = n + 1 - r[n] = k - end - sort(r) - for i=1,n do - local k = r[i] - local v = t[k] - local tv = type(v) - if tv == "string" then - r[i] = f_key_value(k,toeight(v)) - elseif tv == "number" then - r[i] = f_key_number(k,v) - -- elseif tv == "unicode" then -- can't happen - -- r[i] = f_key_value(k,tosixteen(v)) - elseif tv == "table" then - local mv = getmetatable(v) - if mv and mv.__lpdftype then - -- if v == t then - -- report_objects("ignoring circular reference in dirctionary") - -- r[i] = f_key_null(k) - -- else - r[i] = f_key_value(k,tostring(v)) - -- end - elseif v[1] then - r[i] = f_key_value(k,tostring_a(v)) +do + + local f_key_null = formatters["/%s null"] + local f_key_value = formatters["/%s %s"] + local f_key_dictionary = formatters["/%s << % t >>"] + local f_dictionary = formatters["<< % t >>"] + local f_key_array = formatters["/%s [ % t ]"] + local f_array = formatters["[ % t ]"] + local f_key_number = formatters["/%s %N"] -- always with max 9 digits and integer is possible + local f_tonumber = formatters["%N"] -- always with max 9 digits and integer is possible + + tostring_d = function(t,contentonly,key) + if next(t) then + local r = { } + local n = 0 + local e + for k, v in next, t do + if k == "__extra__" then + e = v + elseif k == "__stream__" then + -- do nothing (yet) else - r[i] = f_key_value(k,tostring_d(v)) + n = n + 1 + r[n] = k end + end + if n > 1 then + sort(r) + end + for i=1,n do + local k = r[i] + local v = t[k] + local tv = type(v) + -- mostly tables + if tv == "table" then + -- local mv = getmetatable(v) + -- if mv and mv.__lpdftype then + if v.__lpdftype__ then + -- if v == t then + -- report_objects("ignoring circular reference in dirctionary") + -- r[i] = f_key_null(k) + -- else + r[i] = f_key_value(k,tostring(v)) + -- end + elseif v[1] then + r[i] = f_key_value(k,tostring_a(v)) + else + r[i] = f_key_value(k,tostring_d(v)) + end + elseif tv == "string" then + r[i] = f_key_value(k,toeight(v)) + elseif tv == "number" then + r[i] = f_key_number(k,v) + else + r[i] = f_key_value(k,tostring(v)) + end + end + if e then + r[n+1] = e + end + if contentonly then + return concat(r," ") + elseif key then + return f_key_dictionary(key,r) else - r[i] = f_key_value(k,tostring(v)) + return f_dictionary(r) end - end - if contentonly then - return concat(r," ") - elseif key then - return f_key_dictionary(key,r) + elseif contentonly then + return "" else - return f_dictionary(r) + return "<< >>" end - elseif contentonly then - return "" - else - return "<< >>" end -end -tostring_a = function(t,contentonly,key) - local tn = #t - if tn ~= 0 then - local r = { } - for k=1,tn do - local v = t[k] - local tv = type(v) - if tv == "string" then - r[k] = toeight(v) - elseif tv == "number" then - r[k] = f_tonumber(v) - -- elseif tv == "unicode" then - -- r[k] = tosixteen(v) - elseif tv == "table" then - local mv = getmetatable(v) - local mt = mv and mv.__lpdftype - if mt then - -- if v == t then - -- report_objects("ignoring circular reference in array") - -- r[k] = "null" - -- else - r[k] = tostring(v) - -- end - elseif v[1] then - r[k] = tostring_a(v) + tostring_a = function(t,contentonly,key) + local tn = #t + if tn ~= 0 then + local r = { } + for k=1,tn do + local v = t[k] + local tv = type(v) + -- mostly numbers and tables + if tv == "number" then + r[k] = f_tonumber(v) + elseif tv == "table" then + -- local mv = getmetatable(v) + -- if mv and mv.__lpdftype then + if v.__lpdftype__ then + -- if v == t then + -- report_objects("ignoring circular reference in array") + -- r[k] = "null" + -- else + r[k] = tostring(v) + -- end + elseif v[1] then + r[k] = tostring_a(v) + else + r[k] = tostring_d(v) + end + elseif tv == "string" then + r[k] = toeight(v) else - r[k] = tostring_d(v) + r[k] = tostring(v) end + end + local e = t.__extra__ + if e then + r[tn+1] = e + end + if contentonly then + return concat(r, " ") + elseif key then + return f_key_array(key,r) else - r[k] = tostring(v) + return f_array(r) end - end - if contentonly then - return concat(r, " ") - elseif key then - return f_key_array(key,r) + elseif contentonly then + return "" else - return f_array(r) + return "[ ]" end - elseif contentonly then - return "" - else - return "[ ]" end + end +local f_tonumber = formatters["%N"] + local tostring_x = function(t) return concat(t," ") end local tostring_s = function(t) return toeight(t[1]) end local tostring_p = function(t) return topdfdoc(t[1],t[2]) end @@ -484,6 +588,17 @@ local tostring_v = function(t) end end +local tostring_l = function(t) + local s = t[1] + if not s or s == "" then + return "()" + elseif t[2] then + return "<" .. s .. ">" + else + return "(" .. s .. ")" + end +end + local function value_x(t) return t end local function value_s(t) return t[1] end local function value_p(t) return t[1] end @@ -495,24 +610,75 @@ local function value_a(t) return tostring_a(t,true) end local function value_z() return nil end local function value_t(t) return t.value or true end local function value_f(t) return t.value or false end -local function value_r() return t[1] or 0 end -- null -local function value_v() return t[1] end +local function value_r(t) return t[1] or 0 end -- null +local function value_v(t) return t[1] end +local function value_l(t) return t[1] end + +local function add_to_d(t,v) + local k = type(v) + if k == "string" then + if t.__extra__ then + t.__extra__ = t.__extra__ .. " " .. v + else + t.__extra__ = v + end + elseif k == "table" then + for k, v in next, v do + t[k] = v + end + end + return t +end + +local function add_to_a(t,v) + local k = type(v) + if k == "string" then + if t.__extra__ then + t.__extra__ = t.__extra__ .. " " .. v + else + t.__extra__ = v + end + elseif k == "table" then + local n = #t + for i=1,#v do + n = n + 1 + t[n] = v[i] + end + end + return t +end local function add_x(t,k,v) rawset(t,k,tostring(v)) end -local mt_x = { __lpdftype = "stream", __tostring = tostring_x, __call = value_x, __newindex = add_x } -local mt_d = { __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d } -local mt_a = { __lpdftype = "array", __tostring = tostring_a, __call = value_a } -local mt_u = { __lpdftype = "unicode", __tostring = tostring_u, __call = value_u } -local mt_s = { __lpdftype = "string", __tostring = tostring_s, __call = value_s } -local mt_p = { __lpdftype = "docstring", __tostring = tostring_p, __call = value_p } -local mt_n = { __lpdftype = "number", __tostring = tostring_n, __call = value_n } -local mt_c = { __lpdftype = "constant", __tostring = tostring_c, __call = value_c } -local mt_z = { __lpdftype = "null", __tostring = tostring_z, __call = value_z } -local mt_t = { __lpdftype = "true", __tostring = tostring_t, __call = value_t } -local mt_f = { __lpdftype = "false", __tostring = tostring_f, __call = value_f } -local mt_r = { __lpdftype = "reference", __tostring = tostring_r, __call = value_r } -local mt_v = { __lpdftype = "verbose", __tostring = tostring_v, __call = value_v } +-- local mt_x = { __index = { __lpdftype__ = "stream" }, __lpdftype = "stream", __tostring = tostring_x, __call = value_x, __newindex = add_x } +-- local mt_d = { __index = { __lpdftype__ = "dictionary" }, __lpdftype = "dictionary", __tostring = tostring_d, __call = value_d, __add = add_to_d } +-- local mt_a = { __index = { __lpdftype__ = "array" }, __lpdftype = "array", __tostring = tostring_a, __call = value_a, __add = add_to_a } +-- local mt_u = { __index = { __lpdftype__ = "unicode" }, __lpdftype = "unicode", __tostring = tostring_u, __call = value_u } +-- local mt_s = { __index = { __lpdftype__ = "string" }, __lpdftype = "string", __tostring = tostring_s, __call = value_s } +-- local mt_p = { __index = { __lpdftype__ = "docstring" }, __lpdftype = "docstring", __tostring = tostring_p, __call = value_p } +-- local mt_n = { __index = { __lpdftype__ = "number" }, __lpdftype = "number", __tostring = tostring_n, __call = value_n } +-- local mt_c = { __index = { __lpdftype__ = "constant" }, __lpdftype = "constant", __tostring = tostring_c, __call = value_c } +-- local mt_z = { __index = { __lpdftype__ = "null" }, __lpdftype = "null", __tostring = tostring_z, __call = value_z } +-- local mt_t = { __index = { __lpdftype__ = "true" }, __lpdftype = "true", __tostring = tostring_t, __call = value_t } +-- local mt_f = { __index = { __lpdftype__ = "false" }, __lpdftype = "false", __tostring = tostring_f, __call = value_f } +-- local mt_r = { __index = { __lpdftype__ = "reference" }, __lpdftype = "reference", __tostring = tostring_r, __call = value_r } +-- local mt_v = { __index = { __lpdftype__ = "verbose" }, __lpdftype = "verbose", __tostring = tostring_v, __call = value_v } +-- local mt_l = { __index = { __lpdftype__ = "literal" }, __lpdftype = "literal", __tostring = tostring_l, __call = value_l } + +local mt_x = { __index = { __lpdftype__ = "stream" }, __tostring = tostring_x, __call = value_x, __newindex = add_x } +local mt_d = { __index = { __lpdftype__ = "dictionary" }, __tostring = tostring_d, __call = value_d, __add = add_to_d } +local mt_a = { __index = { __lpdftype__ = "array" }, __tostring = tostring_a, __call = value_a, __add = add_to_a } +local mt_u = { __index = { __lpdftype__ = "unicode" }, __tostring = tostring_u, __call = value_u } +local mt_s = { __index = { __lpdftype__ = "string" }, __tostring = tostring_s, __call = value_s } +local mt_p = { __index = { __lpdftype__ = "docstring" }, __tostring = tostring_p, __call = value_p } +local mt_n = { __index = { __lpdftype__ = "number" }, __tostring = tostring_n, __call = value_n } +local mt_c = { __index = { __lpdftype__ = "constant" }, __tostring = tostring_c, __call = value_c } +local mt_z = { __index = { __lpdftype__ = "null" }, __tostring = tostring_z, __call = value_z } +local mt_t = { __index = { __lpdftype__ = "true" }, __tostring = tostring_t, __call = value_t } +local mt_f = { __index = { __lpdftype__ = "false" }, __tostring = tostring_f, __call = value_f } +local mt_r = { __index = { __lpdftype__ = "reference" }, __tostring = tostring_r, __call = value_r } +local mt_v = { __index = { __lpdftype__ = "verbose" }, __tostring = tostring_v, __call = value_v } +local mt_l = { __index = { __lpdftype__ = "literal" }, __tostring = tostring_l, __call = value_l } local function pdfstream(t) -- we need to add attributes if t then @@ -522,9 +688,9 @@ local function pdfstream(t) -- we need to add attributes t[i] = tostring(t[i]) end elseif tt == "string" then - t= { t } + t = { t } else - t= { tostring(t) } + t = { tostring(t) } end end return setmetatable(t or { },mt_x) @@ -554,46 +720,70 @@ local function pdfunicode(str,default) return setmetatable({ str or default or "" },mt_u) -- could be a string end -local cache = { } -- can be weak - -local function pdfnumber(n,default) -- 0-10 - n = n or default - local c = cache[n] - if not c then - c = setmetatable({ n },mt_n) - -- cache[n] = c -- too many numbers - end - return c +local function pdfliteral(str,hex) -- can also produce a hex <> instead of () literal + return setmetatable({ str, hex },mt_l) end -for i=-1,9 do cache[i] = pdfnumber(i) end +local pdfnumber, pdfconstant -local cache = { } -- can be weak +do -local forbidden, replacements = "\0\t\n\r\f ()[]{}/%%#\\", { } -- table faster than function + local cache = { } -- can be weak -for s in gmatch(forbidden,".") do - replacements[s] = format("#%02x",byte(s)) -end + pdfnumber = function(n,default) -- 0-10 + if not n then + n = default + end + local c = cache[n] + if not c then + c = setmetatable({ n },mt_n) + -- cache[n] = c -- too many numbers + end + return c + end + + for i=-1,9 do cache[i] = pdfnumber(i) end + + local replacer = S("\0\t\n\r\f ()[]{}/%%#\\") / { + ["\00"]="#00", + ["\09"]="#09", + ["\10"]="#0a", + ["\12"]="#0c", + ["\13"]="#0d", + [ " " ]="#20", + [ "#" ]="#23", + [ "%" ]="#25", + [ "(" ]="#28", + [ ")" ]="#29", + [ "/" ]="#2f", + [ "[" ]="#5b", + [ "\\"]="#5c", + [ "]" ]="#5d", + [ "{" ]="#7b", + [ "}" ]="#7d", + } + P(1) + + local escaped = Cs(Cc("/") * replacer^0) + + local cache = table.setmetatableindex(function(t,k) + local v = setmetatable({ lpegmatch(escaped,k) }, mt_c) + t[k] = v + return v + end) + + pdfconstant = function(str,default) + if not str then + str = default or "none" + end + return cache[str] + end -local escaped = Cs(Cc("/") * (S(forbidden)/replacements + P(1))^0) + local escaped = Cs(replacer^0) -local function pdfconstant(str,default) - str = str or default or "" - local c = cache[str] - if not c then - -- c = setmetatable({ "/" .. str },mt_c) - c = setmetatable({ lpegmatch(escaped,str) },mt_c) - cache[str] = c + function lpdf.escaped(str) + return lpegmatch(escaped,str) or str end - return c -end -local escaped = Cs((S(forbidden)/replacements + P(1))^0) ------ escaped = Cs((1-forbidden)^0 * S(forbidden)/replacements * ((S(forbidden)/replacements + P(1))^0) - -function lpdf.escaped(str) - return lpegmatch(escaped,str) or str end local pdfnull, pdfboolean, pdfreference, pdfverbose @@ -657,6 +847,7 @@ lpdf.null = pdfnull lpdf.boolean = pdfboolean lpdf.reference = pdfreference lpdf.verbose = pdfverbose +lpdf.literal = pdfliteral local names, cache = { }, { } @@ -673,13 +864,7 @@ function lpdf.reserveobject(name) return r end --- lpdf.reserveobject = pdfreserveobject --- lpdf.immediateobject = pdfimmediateobject --- lpdf.deferredobject = pdfdeferredobject --- lpdf.referenceobject = pdfreferenceobject - -local pagereference = pdf.pageref -- tex.pdfpageref is obsolete -local nofpages = 0 +local nofpages = 0 function lpdf.pagereference(n) if nofpages == 0 then @@ -689,12 +874,24 @@ function lpdf.pagereference(n) end end if n > nofpages then - return pagereference(nofpages) -- or 1, could be configureable + return pdfgetpagereference(nofpages) -- or 1, could be configureable else - return pagereference(n) + return pdfgetpagereference(n) end end +function lpdf.nofpages() + return structures.pages.nofpages +end + +function lpdf.obj(...) + pdfdeferredobject(...) +end + +function lpdf.immediateobj(...) + pdfimmediateobject(...) +end + function lpdf.delayedobject(data,n) if n then pdfdeferredobject(n,data) @@ -733,14 +930,22 @@ function lpdf.flushobject(name,data) end end - -function lpdf.flushstreamobject(data,dict,compressed) -- default compressed +function lpdf.flushstreamobject(data,dict,compressed,objnum) -- default compressed if trace_objects then report_objects("flushing stream object of %s bytes",#data) end - local dtype = type(dict) + local dtype = type(dict) + local kind = compressed == "raw" and "raw" or "stream" + local nolength = nil + if compressed == "raw" then + compressed = nil + nolength = true + -- data = string.formatters["<< %s >>stream\n%s\nendstream"](attr,data) + end return pdfdeferredobject { + objnum = objnum, immediate = true, + nolength = nolength, compresslevel = compressed == false and 0 or nil, type = "stream", string = data, @@ -748,12 +953,13 @@ function lpdf.flushstreamobject(data,dict,compressed) -- default compressed } end -function lpdf.flushstreamfileobject(filename,dict,compressed) -- default compressed +function lpdf.flushstreamfileobject(filename,dict,compressed,objnum) -- default compressed if trace_objects then report_objects("flushing stream file object %a",filename) end local dtype = type(dict) return pdfdeferredobject { + objnum = objnum, immediate = true, compresslevel = compressed == false and 0 or nil, type = "stream", @@ -810,6 +1016,14 @@ local function resetpageproperties() pagesattributes = pdfdictionary() end +function lpdf.getpageproperties() + return { + pageresources = pageresources, + pageattributes = pageattributes, + pagesattributes = pagesattributes, + } +end + resetpageproperties() local function setpageproperties() @@ -882,37 +1096,28 @@ function lpdf.finalizedocument() if not environment.initex then run(documentfinalizers,"document") function lpdf.finalizedocument() - report_finalizing("serious error: the document is finalized multiple times") + -- report_finalizing("serious error: the document is finalized multiple times") function lpdf.finalizedocument() end end end end --- codeinjections.finalizepage = lpdf.finalizepage -- no longer triggered at the tex end - -if not callbacks.register("finish_pdfpage", lpdf.finalizepage) then - - local find_tail = nodes.tail - local latelua_node = nodes.pool.latelua - - function nodeinjections.finalizepage(head) - local t = find_tail(head.list) - if t then - local n = latelua_node("lpdf.finalizepage(true)") -- last in the shipout - t.next = n - n.prev = t - end - return head, true - end - - nodes.tasks.appendaction("shipouts","normalizers","backends.pdf.nodeinjections.finalizepage") +callbacks.register("finish_pdfpage", lpdf.finalizepage) +callbacks.register("finish_pdffile", lpdf.finalizedocument) -end +do -callbacks.register("finish_pdffile", lpdf.finalizedocument) + local pdfsetinfo, pdfsetcatalog, pdfsettrailerid -- pdfsetnames pdfsettrailer + updaters.register("backend.update.lpdf",function() + pdfsetinfo = pdf.setinfo + pdfsetcatalog = pdf.setcatalog + pdfsettrailerid = pdf.settrailerid + end) -do + function lpdf.settrailerid(id) + pdfsettrailerid(id) + end -- some minimal tracing, handy for checking the order @@ -934,18 +1139,16 @@ do local info = pdfdictionary { Type = pdfconstant("Info") } -- nicer, but when we assign we nil the Type ----- names = pdfdictionary { Type = pdfconstant("Names") } -- nicer, but when we assign we nil the Type - local function flushcatalog() + local function checkcatalog() if not environment.initex then trace_flush("catalog") - catalog.Type = nil - pdfsetcatalog(catalog()) + return true end end - local function flushinfo() + local function checkinfo() if not environment.initex then trace_flush("info") - info.Type = nil if lpdf.majorversion() > 1 then for k, v in next, info do if k == "CreationDate" or k == "ModDate" then @@ -955,17 +1158,36 @@ do end end end + return true + end + end + + local function flushcatalog() + if checkcatalog() then + catalog.Type = nil + pdfsetcatalog(catalog()) + end + end + + local function flushinfo() + if checkinfo() then + info.Type = nil pdfsetinfo(info()) end end - -- local function flushnames() - -- if not environment.initex then - -- trace_flush("names") - -- names.Type = nil - -- pdfsetnames(names()) - -- end - -- end + function lpdf.getcatalog() + if checkcatalog() then + catalog.Type = pdfconstant("Catalog") + return pdfreference(pdfimmediateobject(tostring(catalog))) + end + end + + function lpdf.getinfo() + if checkinfo() then + return pdfreference(pdfimmediateobject(tostring(info))) + end + end function lpdf.addtocatalog(k,v) if not (lpdf.protectresources and catalog[k]) then @@ -1007,20 +1229,19 @@ do end end - local r_extgstates, d_extgstates = pdfreserveobject(), pdfdictionary() local p_extgstates = pdfreference(r_extgstates) - local r_colorspaces, d_colorspaces = pdfreserveobject(), pdfdictionary() local p_colorspaces = pdfreference(r_colorspaces) - local r_patterns, d_patterns = pdfreserveobject(), pdfdictionary() local p_patterns = pdfreference(r_patterns) - local r_shades, d_shades = pdfreserveobject(), pdfdictionary() local p_shades = pdfreference(r_shades) + local r_extgstates, r_colorspaces, r_patterns, r_shades + local d_extgstates, d_colorspaces, d_patterns, d_shades + local p_extgstates, p_colorspaces, p_patterns, p_shades - local function checkextgstates () if next(d_extgstates ) then addtopageresources("ExtGState", p_extgstates ) end end - local function checkcolorspaces() if next(d_colorspaces) then addtopageresources("ColorSpace",p_colorspaces) end end - local function checkpatterns () if next(d_patterns ) then addtopageresources("Pattern", p_patterns ) end end - local function checkshades () if next(d_shades ) then addtopageresources("Shading", p_shades ) end end + local function checkextgstates () if d_extgstates then addtopageresources("ExtGState", p_extgstates ) end end + local function checkcolorspaces() if d_colorspaces then addtopageresources("ColorSpace",p_colorspaces) end end + local function checkpatterns () if d_patterns then addtopageresources("Pattern", p_patterns ) end end + local function checkshades () if d_shades then addtopageresources("Shading", p_shades ) end end - local function flushextgstates () if next(d_extgstates ) then trace_flush("extgstates") pdfimmediateobject(r_extgstates, tostring(d_extgstates )) end end - local function flushcolorspaces() if next(d_colorspaces) then trace_flush("colorspaces") pdfimmediateobject(r_colorspaces,tostring(d_colorspaces)) end end - local function flushpatterns () if next(d_patterns ) then trace_flush("patterns") pdfimmediateobject(r_patterns, tostring(d_patterns )) end end - local function flushshades () if next(d_shades ) then trace_flush("shades") pdfimmediateobject(r_shades, tostring(d_shades )) end end + local function flushextgstates () if d_extgstates then trace_flush("extgstates") pdfimmediateobject(r_extgstates, tostring(d_extgstates )) end end + local function flushcolorspaces() if d_colorspaces then trace_flush("colorspaces") pdfimmediateobject(r_colorspaces,tostring(d_colorspaces)) end end + local function flushpatterns () if d_patterns then trace_flush("patterns") pdfimmediateobject(r_patterns, tostring(d_patterns )) end end + local function flushshades () if d_shades then trace_flush("shades") pdfimmediateobject(r_shades, tostring(d_shades )) end end -- patterns are special as they need resources to so we can get recursive references and in that case -- acrobat doesn't show anything (other viewers handle it well) @@ -1029,10 +1250,10 @@ do -- todo: force when not yet set function lpdf.collectedresources(options) - local ExtGState = next(d_extgstates ) and p_extgstates - local ColorSpace = next(d_colorspaces) and p_colorspaces - local Pattern = next(d_patterns ) and p_patterns - local Shading = next(d_shades ) and p_shades + local ExtGState = d_extgstates and next(d_extgstates ) and p_extgstates + local ColorSpace = d_colorspaces and next(d_colorspaces) and p_colorspaces + local Pattern = d_patterns and next(d_patterns ) and p_patterns + local Shading = d_shades and next(d_shades ) and p_shades if options and options.patterns == false then Pattern = nil end @@ -1042,18 +1263,56 @@ do ColorSpace = ColorSpace, Pattern = Pattern, Shading = Shading, - -- ProcSet = pdfarray { pdfconstant("PDF") }, } - return collected() + if options and options.serialize == false then + return collected + else + return collected() + end else - return "" + if options and options.serialize == false then + return pdfdictionary { } + else + return "" + end end end - function lpdf.adddocumentextgstate (k,v) d_extgstates [k] = v end - function lpdf.adddocumentcolorspace(k,v) d_colorspaces[k] = v end - function lpdf.adddocumentpattern (k,v) d_patterns [k] = v end - function lpdf.adddocumentshade (k,v) d_shades [k] = v end + function lpdf.adddocumentextgstate (k,v) + if not d_extgstates then + r_extgstates = pdfreserveobject() + d_extgstates = pdfdictionary() + p_extgstates = pdfreference(r_extgstates) + end + d_extgstates[k] = v + end + + function lpdf.adddocumentcolorspace(k,v) + if not d_colorspaces then + r_colorspaces = pdfreserveobject() + d_colorspaces = pdfdictionary() + p_colorspaces = pdfreference(r_colorspaces) + end + d_colorspaces[k] = v + end + + function lpdf.adddocumentpattern(k,v) + if not d_patterns then + r_patterns = pdfreserveobject() + d_patterns = pdfdictionary() + p_patterns = pdfreference(r_patterns) + end + d_patterns[k] = v + end + + function lpdf.adddocumentshade(k,v) + if not d_shades then + r_shades = pdfreserveobject() + d_shades = pdfdictionary() + p_shades = pdfreference(r_shades) + end + d_shades[k] = v + end registerdocumentfinalizer(flushextgstates,3,"extended graphic states") registerdocumentfinalizer(flushcolorspaces,3,"color spaces") @@ -1074,7 +1333,8 @@ end -- in strc-bkm: lpdf.registerdocumentfinalizer(function() structures.bookmarks.place() end,1) function lpdf.rotationcm(a) - local s, c = sind(a), cosd(a) + local s = sind(a) + local c = cosd(a) return format("%.6F %.6F %.6F %.6F 0 0 cm",c,s,-s,c) end @@ -1127,12 +1387,12 @@ do return Y and format("D:%s%s%s%s%s%s%s%s'%s'",Y,M,D,h,m,s,Zs,Zh,Zm) end - function lpdf.id(nodate) + function lpdf.id(date) local banner = environment.jobname or tex.jobname or "unknown" - if nodate then + if not date then return banner else - return format("%s.%s",banner,timestamp) + return format("%s | %s",banner,timestamp) end end @@ -1190,7 +1450,6 @@ function lpdf.checkedvalue(value,variant) -- code not shared end end end - -- return nil end function lpdf.limited(n,min,max,default) @@ -1210,61 +1469,6 @@ function lpdf.limited(n,min,max,default) end end --- if not pdfreferenceobject then --- --- local delayed = { } --- --- local function flush() --- local n = 0 --- for k,v in next, delayed do --- pdfimmediateobject(k,v) --- n = n + 1 --- end --- if trace_objects then --- report_objects("%s objects flushed",n) --- end --- delayed = { } --- end --- --- lpdf.registerdocumentfinalizer(flush,3,"objects") -- so we need a final flush too --- lpdf.registerpagefinalizer (flush,3,"objects") -- somehow this lags behind .. I need to look into that some day --- --- function lpdf.delayedobject(data) --- local n = pdfreserveobject() --- delayed[n] = data --- return n --- end --- --- end - --- setmetatable(pdf, { --- __index = function(t,k) --- if k == "info" then return pdf.getinfo() --- elseif k == "catalog" then return pdf.getcatalog() --- elseif k == "names" then return pdf.getnames() --- elseif k == "trailer" then return pdf.gettrailer() --- elseif k == "pageattribute" then return pdf.getpageattribute() --- elseif k == "pageattributes" then return pdf.getpageattributes() --- elseif k == "pageresources" then return pdf.getpageresources() --- elseif --- return nil --- end --- end, --- __newindex = function(t,k,v) --- if k == "info" then return pdf.setinfo(v) --- elseif k == "catalog" then return pdf.setcatalog(v) --- elseif k == "names" then return pdf.setnames(v) --- elseif k == "trailer" then return pdf.settrailer(v) --- elseif k == "pageattribute" then return pdf.setpageattribute(v) --- elseif k == "pageattributes" then return pdf.setpageattributes(v) --- elseif k == "pageresources" then return pdf.setpageresources(v) --- else --- rawset(t,k,v) --- end --- end, --- }) - - -- The next variant of ActualText is what Taco and I could come up with -- eventually. As of September 2013 Acrobat copies okay, Sumatra copies a -- question mark, pdftotext injects an extra space and Okular adds a @@ -1287,7 +1491,7 @@ do local f_actual_text = formatters["/Span <> BDC"] local context = context - local pdfdirect = nodes.pool.pdfdirectliteral + local pdfdirect = nodes.pool.directliteral -- we can use nuts.write deep down -- todo: use tounicode from the font mapper @@ -1383,11 +1587,9 @@ end function lpdf.copyarray(a) if a then local t = pdfarray() - local k = a.__kind for i=1,#a do t[i] = a(i) end --- inspect(t) return t end end @@ -1398,7 +1600,6 @@ function lpdf.copydictionary(d) for k, v in next, d do t[k] = d(k) end --- inspect(t) return t end end @@ -1420,3 +1621,73 @@ function lpdf.copystring(v) return pdfstring(v) end end + +do + + local pdfincludechar, pdfincludecharlist, pdfincludefont + local pdfgetfontname, pdfgetfontobjnum + local pdfsetmapfile, pdfsetmapline + + updaters.register("backend.update.lpdf",function() + pdfincludechar = pdf.includechar + pdfincludefont = pdf.includefont + pdfincludecharlist = pdf.includecharlist + pdfgetfontname = pdf.getfontname + pdfgetfontobjnum = pdf.getfontobjnum + pdfsetmapfile = pdf.mapfile + pdfsetmapline = pdf.mapline + end) + + function lpdf.includechar(f,c) pdfincludechar(f,c) end + function lpdf.includefont(...) pdfincludefont(...) end + + function lpdf.includecharlist(f,c) pdfincludecharlist(f,c) end -- can be disabled + + function lpdf.getfontname (id) return pdfgetfontname (id) end + function lpdf.getfontobjnumber(id) return pdfgetfontobjnum(id) end + + function lpdf.setmapfile(...) pdfsetmapfile(...) end + function lpdf.setmapline(...) pdfsetmapline(...) end + +end + +do + + -- This is obsolete but old viewers might still use it as directive + -- for what to send to a postscript printer. + + local a_procset, d_procset + + function lpdf.procset(dict) + if not a_procset then + a_procset = pdfarray { + pdfconstant("PDF"), + pdfconstant("Text"), + pdfconstant("ImageB"), + pdfconstant("ImageC"), + pdfconstant("ImageI"), + } + a_procset = pdfreference(pdfimmediateobject(tostring(a_procset))) + end + if dict then + if not d_procset then + d_procset = pdfdictionary { + ProcSet = a_procset + } + d_procset = pdfreference(pdfimmediateobject(tostring(d_procset))) + end + return d_procset + else + return a_procset + end + end + +end + +-- a left-over + +if environment.arguments.nocompression then + lpdf.setcompression(0,0,true) +end + + diff --git a/tex/context/base/mkiv/lpdf-mis.lua b/tex/context/base/mkiv/lpdf-mis.lua index 6d1b09ca0..77f11918b 100644 --- a/tex/context/base/mkiv/lpdf-mis.lua +++ b/tex/context/base/mkiv/lpdf-mis.lua @@ -18,7 +18,6 @@ if not modules then modules = { } end modules ['lpdf-mis'] = { local next, tostring, type = next, tostring, type local format, gsub, formatters = string.format, string.gsub, string.formatters local flattened = table.flattened -local texset, texget = tex.set, tex.get local backends, lpdf, nodes = backends, lpdf, nodes @@ -30,7 +29,7 @@ local nuts = nodes.nuts local copy_node = nuts.copy local nodepool = nuts.pool -local pdfpageliteral = nodepool.pdfpageliteral +local pageliteral = nodepool.pageliteral local register = nodepool.register local pdfdictionary = lpdf.dictionary @@ -54,6 +53,8 @@ local addtonames = lpdf.addtonames local pdfgetmetadata = lpdf.getmetadata +local texset = tex.set + local variables = interfaces.variables local v_stop = variables.stop @@ -72,11 +73,18 @@ local v_page = variables.page local v_paper = variables.paper local v_attachment = variables.attachment local v_layer = variables.layer +local v_lefttoright = variables.lefttoright +local v_righttoleft = variables.righttoleft +local v_title = variables.title + +local positive = register(pageliteral("/GSpositive gs")) +local negative = register(pageliteral("/GSnegative gs")) +local overprint = register(pageliteral("/GSoverprint gs")) +local knockout = register(pageliteral("/GSknockout gs")) + +local omitextraboxes = false -local positive = register(pdfpageliteral("/GSpositive gs")) -local negative = register(pdfpageliteral("/GSnegative gs")) -local overprint = register(pdfpageliteral("/GSoverprint gs")) -local knockout = register(pdfpageliteral("/GSknockout gs")) +directives.register("backend.omitextraboxes", function(v) omitextraboxes = v end) local function initializenegative() local a = pdfarray { 0, 1 } @@ -86,7 +94,7 @@ local function initializenegative() Range = a, Domain = a, } - local negative = pdfdictionary { Type = g, TR = pdfreference(pdfflushstreamobject("{ 1 exch sub }",d)) } + local negative = pdfdictionary { Type = g, TR = pdfreference(pdfflushstreamobject("{ 1 exch sub }",d)) } -- can be shared local positive = pdfdictionary { Type = g, TR = pdfconstant("Identity") } adddocumentextgstate("GSnegative", pdfreference(pdfflushobject(negative))) adddocumentextgstate("GSpositive", pdfreference(pdfflushobject(positive))) @@ -230,6 +238,12 @@ local function setupidentity() addtoinfo("ID", pdfstring(id), id) -- needed for pdf/x -- addtoinfo("ConTeXt.Version",version) + -- + local lmtx = codeinjections.lmtxmode() + if lmtx then + addtoinfo("ConTeXt.LMTX",formatters["%0.2f"](lmtx)) + end + -- addtoinfo("ConTeXt.Time",os.date("%Y-%m-%d %H:%M")) addtoinfo("ConTeXt.Jobname",jobname) addtoinfo("ConTeXt.Url","www.pragma-ade.com") @@ -254,7 +268,9 @@ local function flushjavascripts() local a = pdfarray() local pdf_javascript = pdfconstant("JavaScript") for i=1,#t do - local name, script = t[i][1], t[i][2] + local ti = t[i] + local name = ti[1] + local script = ti[2] local j = pdfdictionary { S = pdf_javascript, JS = pdfreference(pdfflushstreamobject(script)), @@ -304,14 +320,26 @@ local plusspecs = { [v_paper] = { paper = true, }, + [v_title] ={ + title = true, + }, + [v_lefttoright] ={ + direction = "L2R", + }, + [v_righttoleft] ={ + direction = "R2R", + }, } local pagespecs = { -- - [v_max] = plusspecs[v_max], - [v_bookmark] = plusspecs[v_bookmark], - [v_attachment] = plusspecs[v_attachment], - [v_layer] = plusspecs[v_layer], + [v_max] = plusspecs[v_max], + [v_bookmark] = plusspecs[v_bookmark], + [v_attachment] = plusspecs[v_attachment], + [v_layer] = plusspecs[v_layer], + [v_lefttoright] = plusspecs[v_lefttoright], + [v_righttoleft] = plusspecs[v_righttoleft], + [v_title] = plusspecs[v_title], -- [v_none] = { }, @@ -372,21 +400,23 @@ local cropoffset, bleedoffset, trimoffset, artoffset = 0, 0, 0, 0 local marked = false local copies = false +local getpagedimensions getpagedimensions = function() + getpagedimensions = backends.codeinjections.getpagedimensions + return getpagedimensions() +end + function codeinjections.setupcanvas(specification) local paperheight = specification.paperheight local paperwidth = specification.paperwidth local paperdouble = specification.doublesided - if paperheight then - texset('global','pageheight',paperheight) - end - if paperwidth then - texset('global','pagewidth',paperwidth) - end + -- + paperwidth, paperheight = codeinjections.setpagedimensions(paperwidth,paperheight) + -- pagespec = specification.mode or pagespec topoffset = specification.topoffset or 0 leftoffset = specification.leftoffset or 0 - height = specification.height or texget("pageheight") - width = specification.width or texget("pagewidth") + height = specification.height or paperheight + width = specification.width or paperwidth marked = specification.print -- copies = specification.copies @@ -433,13 +463,15 @@ local function documentspecification() end end end - -- - local layout = spec.layout - local mode = spec.mode - local fit = spec.fit - local fixed = spec.fixed - local duplex = spec.duplex - local paper = spec.paper + -- maybe interfaces.variables + local layout = spec.layout + local mode = spec.mode + local fit = spec.fit + local fixed = spec.fixed + local duplex = spec.duplex + local paper = spec.paper + local title = spec.title + local direction = spec.direction if layout then addtocatalog("PageLayout",pdfconstant(layout)) end @@ -458,34 +490,42 @@ local function documentspecification() prints = pdfarray(flattened(pages.toranges(marked))) end end - if fit or fixed or duplex or copies or paper or prints then + if fit or fixed or duplex or copies or paper or prints or title or direction then addtocatalog("ViewerPreferences",pdfdictionary { - FitWindow = fit and true or nil, - PrintScaling = fixed and pdfconstant("None") or nil, - Duplex = duplex and pdfconstant(duplex) or nil, - NumCopies = copies and copies or nil, - PickTrayByPDFSize = paper and true or nil, - PrintPageRange = prints or nil, + FitWindow = fit and true or nil, + PrintScaling = fixed and pdfconstant("None") or nil, + Duplex = duplex and pdfconstant(duplex) or nil, + NumCopies = copies and copies or nil, + PickTrayByPDFSize = paper and true or nil, + PrintPageRange = prints or nil, + DisplayDocTitle = title and true or nil, + Direction = direction and pdfconstant(direction) or nil, }) end addtoinfo ("Trapped", pdfconstant("False")) -- '/Trapped' in /Info, 'Trapped' in XMP addtocatalog("Version", pdfconstant(format("1.%s",pdfminorversion()))) + addtocatalog("Lang", pdfstring(tokens.getters.macro("currentmainlanguage"))) end -- temp hack: the mediabox is not under our control and has a precision of 5 digits local factor = number.dimenfactors.bp -local f_value = formatters["%0.6F"] +local f_value = formatters["%.6F"] + +directives.register("pdf.stripzeros",function() + local f_value = formatters["%.6N"] +end) local function boxvalue(n) -- we could share them return pdfverbose(f_value(factor * n)) end local function pagespecification() + local paperwidth, paperheight = codeinjections.getpagedimensions() local llx = leftoffset - local lly = texget("pageheight") + topoffset - height + local lly = paperheight + topoffset - height local urx = width - leftoffset - local ury = texget("pageheight") - topoffset + local ury = paperheight - topoffset -- boxes can be cached local function extrabox(WhatBox,offset,always) if offset ~= 0 or always then @@ -497,10 +537,14 @@ local function pagespecification() }) end end - extrabox("CropBox",cropoffset,true) -- mandate for rendering - extrabox("TrimBox",trimoffset,true) -- mandate for pdf/x - extrabox("BleedBox",bleedoffset) -- optional - -- extrabox("ArtBox",artoffset) -- optional .. unclear what this is meant to do + if omitextraboxes then + -- only useful for testing / comparing + else + extrabox("CropBox",cropoffset,true) -- mandate for rendering + extrabox("TrimBox",trimoffset,true) -- mandate for pdf/x + extrabox("BleedBox",bleedoffset) -- optional + -- extrabox("ArtBox",artoffset) -- optional .. unclear what this is meant to do + end end lpdf.registerpagefinalizer(pagespecification,"page specification") diff --git a/tex/context/base/mkiv/lpdf-nod.lua b/tex/context/base/mkiv/lpdf-nod.lua index e3c1778f2..8bcf18c62 100644 --- a/tex/context/base/mkiv/lpdf-nod.lua +++ b/tex/context/base/mkiv/lpdf-nod.lua @@ -6,178 +6,84 @@ if not modules then modules = { } end modules ['lpdf-nod'] = { license = "see context related readme files" } -local type = type - -local formatters = string.formatters +if CONTEXTLMTXMODE > 1 then + return +end -local whatsitcodes = nodes.whatsitcodes -local nodeinjections = backends.nodeinjections +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes -local nuts = nodes.nuts -local tonut = nuts.tonut +local nodeinjections = backends.nodeinjections -local setfield = nuts.setfield +local nuts = nodes.nuts -local copy_node = nuts.copy -local new_node = nuts.new +local setfield = nuts.setfield +local setdata = nuts.setdata -local nodepool = nuts.pool -local register = nodepool.register +local copy_node = nuts.copy +local new_node = nuts.new -local literalvalues = nodes.literalvalues +local nodepool = nuts.pool +local register = nodepool.register -local pdforiginliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdforiginliteral,"mode",literalvalues.origin) -local pdfpageliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfpageliteral, "mode",literalvalues.page) -local pdfdirectliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfdirectliteral,"mode",literalvalues.direct) -local pdfrawliteral = register(new_node("whatsit", whatsitcodes.pdfliteral)) setfield(pdfrawliteral, "mode",literalvalues.raw) +local whatsit_code = nodecodes.whatsit -local pdfsave = register(new_node("whatsit", whatsitcodes.pdfsave)) -local pdfrestore = register(new_node("whatsit", whatsitcodes.pdfrestore)) -local pdfsetmatrix = register(new_node("whatsit", whatsitcodes.pdfsetmatrix)) ------ pdfdest = register(new_node("whatsit", whatsitcodes.pdfdest)) setfield(pdfdest,"named_id",1) -- xyz_zoom untouched ------ pdfannot = register(new_node("whatsit", whatsitcodes.pdfannot)) +local savewhatsit_code = whatsitcodes.save +local restorewhatsit_code = whatsitcodes.restore +local setmatrixwhatsit_code = whatsitcodes.setmatrix +local literalwhatsit_code = whatsitcodes.literal -local variables = interfaces.variables +local literalvalues = nodes.literalvalues +local originliteral_code = literalvalues.origin +local pageliteral_code = literalvalues.page +local directliteral_code = literalvalues.direct +local rawliteral_code = literalvalues.raw -function nodepool.pdforiginliteral(str) local t = copy_node(pdforiginliteral) setfield(t,"data",str) return t end -function nodepool.pdfpageliteral (str) local t = copy_node(pdfpageliteral ) setfield(t,"data",str) return t end -function nodepool.pdfdirectliteral(str) local t = copy_node(pdfdirectliteral) setfield(t,"data",str) return t end -function nodepool.pdfrawliteral (str) local t = copy_node(pdfrawliteral ) setfield(t,"data",str) return t end +local tomatrix = drivers.helpers.tomatrix -nodepool.pdfliteral = nodepool.pdfpageliteral -- best is to use a specific one: origin | page | direct | raw +local originliteralnode = register(new_node(whatsit_code, literalwhatsit_code)) setfield(originliteralnode,"mode",originliteral_code) +local pageliteralnode = register(new_node(whatsit_code, literalwhatsit_code)) setfield(pageliteralnode, "mode",pageliteral_code) +local directliteralnode = register(new_node(whatsit_code, literalwhatsit_code)) setfield(directliteralnode,"mode",directliteral_code) +local rawliteralnode = register(new_node(whatsit_code, literalwhatsit_code)) setfield(rawliteralnode, "mode",rawliteral_code) -function nodepool.pdfsave() - return copy_node(pdfsave) -end +function nodepool.originliteral(str) local t = copy_node(originliteralnode) setdata(t,str) return t end +function nodepool.pageliteral (str) local t = copy_node(pageliteralnode ) setdata(t,str) return t end +function nodepool.directliteral(str) local t = copy_node(directliteralnode) setdata(t,str) return t end +function nodepool.rawliteral (str) local t = copy_node(rawliteralnode ) setdata(t,str) return t end -function nodepool.pdfrestore() - return copy_node(pdfrestore) -end +local literals = { + [originliteral_code] = originliteralnode, [literalvalues[originliteral_code]] = originliteralnode, + [pageliteral_code] = pageliteralnode, [literalvalues[pageliteral_code]] = pageliteralnode, + [directliteral_code] = directliteralnode, [literalvalues[directliteral_code]] = directliteralnode, + [rawliteral_code] = rawliteralnode, [literalvalues[rawliteral_code]] = rawliteralnode, +} -function nodepool.pdfsetmatrix(rx,sx,sy,ry,tx,ty) -- todo: tx ty - local t = copy_node(pdfsetmatrix) - if type(rx) == "string" then - setfield(t,"data",rx) +function nodepool.literal(mode,str) + if str then + local t = copy_node(literals[mode] or pageliteralnode) + setdata(t,str) + return t else - if not rx then - rx = 1 - elseif rx == 0 then - rx = 0.0001 - end - if not ry then - ry = 1 - elseif ry == 0 then - ry = 0.0001 - end - if not sx then - sx = 0 - end - if not sy then - sy = 0 - end - if sx == 0 and sy == 0 then - if rx == 1 and ry == 1 then - setfield(t,"data","1 0 0 1") - else - setfield(t,"data",formatters["%0.6F 0 0 %0.6F"](rx,ry)) - end - else - setfield(t,"data",formatters["%0.6F %0.6F %0.6F %0.6F"](rx,sx,sy,ry)) - end + local t = copy_node(pageliteralnode) + setdata(t,mode) + return t end - return t end -nodeinjections.save = nodepool.pdfsave -nodeinjections.restore = nodepool.pdfrestore -nodeinjections.transform = nodepool.pdfsetmatrix - --- the next one is implemented differently, using latelua - -function nodepool.pdfannotation(w,h,d,data,n) - report("don't use node based annotations!") - os.exit() - -- local t = copy_node(pdfannot) - -- if w and w ~= 0 then - -- setfield(t,"width",w) - -- end - -- if h and h ~= 0 then - -- setfield(t,"height",h) - -- end - -- if d and d ~= 0 then - -- setfield(t,"depth",d) - -- end - -- if n then - -- setfield(t,"objnum",n) - -- end - -- if data and data ~= "" then - -- setfield(t,"data",data) - -- end - -- return t +local savenode = register(new_node(whatsit_code, savewhatsit_code)) +local restorenode = register(new_node(whatsit_code, restorewhatsit_code)) +local setmatrixnode = register(new_node(whatsit_code, setmatrixwhatsit_code)) + +function nodepool.save() + return copy_node(savenode) end --- (!) The next code in pdfdest.w is wrong: --- --- case pdf_dest_xyz: --- if (matrixused()) { --- set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_dest_margin) ; --- } else { --- pdf_ann_left(p) = pos.h ; --- pdf_ann_top (p) = pos.v ; --- } --- break ; --- --- so we need to force a matrix. - --- local views = { -- beware, we do support the pdf keys but this is *not* official --- xyz = 0, [variables.standard] = 0, --- fit = 1, [variables.fit] = 1, --- fith = 2, [variables.width] = 2, --- fitv = 3, [variables.height] = 3, --- fitb = 4, --- fitbh = 5, [variables.minwidth] = 5, --- fitbv = 6, [variables.minheight] = 6, --- fitr = 7, --- } - -function nodepool.pdfdestination(w,h,d,name,view,n) - report("don't use node based destinations!") - os.exit() - -- local t = copy_node(pdfdest) - -- local hasdimensions = false - -- if w and w ~= 0 then - -- setfield(t,"width",w) - -- hasdimensions = true - -- end - -- if h and h ~= 0 then - -- setfield(t,"height",h) - -- hasdimensions = true - -- end - -- if d and d ~= 0 then - -- setfield(t,"depth",d) - -- hasdimensions = true - -- end - -- if n then - -- setfield(t,"objnum",n) - -- end - -- view = views[view] or view or 1 -- fit is default - -- setfield(t,"dest_id",name) - -- setfield(t,"dest_type",view) - -- if hasdimensions and view == 0 then -- xyz - -- -- see (!) s -> m -> t -> r - -- -- linked - -- local s = copy_node(pdfsave) - -- local m = copy_node(pdfsetmatrix) - -- local r = copy_node(pdfrestore) - -- setfield(m,"data","1 0 0 1") - -- setfield(s,"next",m) - -- setfield(m,"next",t) - -- setfield(t,"next",r) - -- setfield(m,"prev",s) - -- setfield(t,"prev",m) - -- setfield(r,"prev",t) - -- return s -- a list - -- else - -- return t - -- end +function nodepool.restore() + return copy_node(restorenode) +end + +function nodepool.setmatrix(rx,sx,sy,ry,tx,ty) + local t = copy_node(setmatrixnode) + setdata(t,tomatrix(rx,sx,sy,ry,tx,ty)) + return t end diff --git a/tex/context/base/mkiv/lpdf-pda.xml b/tex/context/base/mkiv/lpdf-pda.xml index efdfc4d7d..2f07fed2d 100644 --- a/tex/context/base/mkiv/lpdf-pda.xml +++ b/tex/context/base/mkiv/lpdf-pda.xml @@ -30,6 +30,7 @@ + @@ -100,40 +101,76 @@ - external - Name of the ConTeXt job - ConTeXt.Jobname - Text + external + Name of the ConTeXt job + ConTeXt.Jobname + Text - external - Time stamp of ConTeXt version - ConTeXt.Time - Text + external + Time stamp of ConTeXt version + ConTeXt.Time + Text - external - ConTeXt website - ConTeXt.Url - Text + external + ConTeXt website + ConTeXt.Url + Text - external - ConTeXt version - ConTeXt.Version - Text + external + ConTeXt support + ConTeXt.Support + Text - external - Banner of pdftex or one of its successors - PTEX.Fullbanner - Text + external + ConTeXt version + ConTeXt.Version + Text - external - Document identifier - ID - Text + external + ConTeXt LMTX version + ConTeXt.LMTX + Text + + + external + TeX support + TeX.Support + Text + + + external + LuaTeX version + LuaTeX.Version + Text + + + external + LuaTeX functionality + LuaTeX.Functionality + Text + + + external + LuaTeX Lua version + LuaTeX.LuaVersion + Text + + + external + LuaTeX platform + LuaTeX.Platform + Text + + + external + Document identifier + ID + Text diff --git a/tex/context/base/mkiv/lpdf-pde.lua b/tex/context/base/mkiv/lpdf-pde.lua new file mode 100644 index 000000000..9d14f8f5e --- /dev/null +++ b/tex/context/base/mkiv/lpdf-pde.lua @@ -0,0 +1,1157 @@ +if not modules then modules = { } end modules ['lpdf-epd'] = { + version = 1.001, + comment = "companion to lpdf-epa.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", + history = "this one replaces the poppler/pdfe binding", +} + +-- \enabledirectives[graphics.pdf.uselua] +-- \enabledirectives[graphics.pdf.recompress] +-- \enabledirectives[graphics.pdf.stripmarked] + +-- maximum integer : +2^32 +-- maximum real : +2^15 +-- minimum real : 1/(2^16) + +-- get_flagged : does that still work + +-- ppdoc_permissions (ppdoc *pdf); + +-- PPSTRING_ENCODED 1 << 0 +-- PPSTRING_DECODED 1 << 1 +-- PPSTRING_EXEC 1 << 2 postscript only +-- PPSTRING_PLAIN 0 +-- PPSTRING_BASE16 1 << 3 +-- PPSTRING_BASE85 1 << 4 +-- PPSTRING_UTF16BE 1 << 5 +-- PPSTRING_UTF16LE 1 << 6 + +-- PPDOC_ALLOW_PRINT 1 << 2 printing +-- PPDOC_ALLOW_MODIFY 1 << 3 filling form fields, signing, creating template pages +-- PPDOC_ALLOW_COPY 1 << 4 copying, copying for accessibility +-- PPDOC_ALLOW_ANNOTS 1 << 5 filling form fields, copying, signing +-- PPDOC_ALLOW_EXTRACT 1 << 9 contents copying for accessibility +-- PPDOC_ALLOW_ASSEMBLY 1 << 10 no effect +-- PPDOC_ALLOW_PRINT_HIRES 1 << 11 no effect + +-- PPCRYPT_NONE 0 no encryption, go ahead +-- PPCRYPT_DONE 1 encryption present but password succeeded, go ahead +-- PPCRYPT_PASS -1 encryption present, need non-empty password +-- PPCRYPT_FAIL -2 invalid or unsupported encryption (eg. undocumented in pdf spec) + +local setmetatable, rawset, rawget, type, next = setmetatable, rawset, rawget, type, next +local tostring, tonumber, unpack = tostring, tonumber, unpack +local char, byte, find = string.char, string.byte, string.find +local abs = math.abs +local concat, swapped, sortedhash, sortedkeys = table.concat, table.swapped, table.sortedhash, table.sortedkeys +local utfchar = string.char +local setmetatableindex = table.setmetatableindex + +local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns +local P, C, S, R, Ct, Cc, V, Carg, Cs, Cf, Cg = lpeg.P, lpeg.C, lpeg.S, lpeg.R, lpeg.Ct, lpeg.Cc, lpeg.V, lpeg.Carg, lpeg.Cs, lpeg.Cf, lpeg.Cg + +if not lpdf then + require("lpdf-aux") +end + +if not (number and number.dimenfactors) then + require("util-dim") +end + +local epdf = pdfe + lpdf = lpdf or { } +local lpdf = lpdf +local lpdf_epdf = { } +lpdf.epdf = lpdf_epdf + +local openPDF = epdf.open +local newPDF = epdf.new +local closePDF = epdf.close + +local getcatalog = epdf.getcatalog +local getinfo = epdf.getinfo +local gettrailer = epdf.gettrailer +local getnofpages = epdf.getnofpages +local getversion = epdf.getversion +local getbox = epdf.getbox +local getstatus = epdf.getstatus +local unencrypt = epdf.unencrypt + +local dictionarytotable = epdf.dictionarytotable +local arraytotable = epdf.arraytotable +local pagestotable = epdf.pagestotable +local readwholestream = epdf.readwholestream + +local getfromreference = pdfe.getfromreference + +local report_epdf = logs.reporter("epdf") + +local allocate = utilities.storage.allocate + +local bpfactor = number.dimenfactors.bp + +local objectcodes = { [0] = + "none", + "null", + "bool", + "integer", + "number", + "name", + "string", + "array", + "dictionary", + "stream", + "reference", +} + +local encryptioncodes = { + [0] = "notencrypted", + [1] = "unencrypted", + [-1] = "protected", + [-2] = "failure", +} + +objectcodes = allocate(swapped(objectcodes,objectcodes)) +encryptioncodes = allocate(swapped(encryptioncodes,encryptioncodes)) + +pdfe.objectcodes = objectcodes +pdfe.encryptioncodes = encryptioncodes + +local null_object_code = objectcodes.null +local reference_object_code = objectcodes.reference + +local none_object_code = objectcodes.none +local null_object_code = objectcodes.null +local bool_object_code = objectcodes.bool +local integer_object_code = objectcodes.integer +local number_object_code = objectcodes.number +local name_object_code = objectcodes.name +local string_object_code = objectcodes.string +local array_object_code = objectcodes.array +local dictionary_object_code = objectcodes.dictionary +local stream_object_code = objectcodes.stream +local reference_object_code = objectcodes.reference + +local checked_access +local get_flagged -- from pdfe -> lpdf + +if lpdf.dictionary then + + -- we're in context + + local pdfdictionary = lpdf.dictionary + local pdfarray = lpdf.array + local pdfconstant = lpdf.constant + local pdfstring = lpdf.string + local pdfunicode = lpdf.unicode + + get_flagged = function(t,f,k) + local tk = t[k] -- triggers resolve + local fk = f[k] + if not fk then + return tk + elseif fk == "name" then + return pdfconstant(tk) + elseif fk == "array" then + return pdfarray(tk) + elseif fk == "dictionary" then + return pdfarray(tk) + elseif fk == "rawtext" then + return pdfstring(tk) + elseif fk == "unicode" then + return pdfunicode(tk) + else + return tk + end + end + +else + + get_flagged = function(t,f,k) + return t[k] + end + +end + +-- We need to convert the string from utf16 although there is no way to +-- check if we have a regular string starting with a bom. So, we have +-- na dilemma here: a pdf doc encoded string can be invalid utf. + +-- : implicit 0 appended if odd +-- (byte encoded) : \( \) \\ escaped +-- +-- : utf16be +-- +-- \r \r \t \b \f \( \) \\ \NNN and \ : append next line +-- +-- the getString function gives back bytes so we don't need to worry about +-- the hex aspect. + +local some_dictionary +local some_array +local some_stream +local some_reference + +local some_string = lpdf.frombytes + +local function get_value(document,t,key) + if not key then + return + end + local value = t[key] + if not value then + return + end + if type(value) ~= "table" then + return value + end + -- we can assume names to be simple and strings to be tables + local kind = value[1] + if kind == name_object_code then + return value[2] + elseif kind == string_object_code then + return some_string(value[2],value[3]) + elseif kind == array_object_code then + return some_array(value[2],document) + elseif kind == dictionary_object_code then + return some_dictionary(value[2],document) + elseif kind == stream_object_code then + return some_stream(value,document) + elseif kind == reference_object_code then + return some_reference(value,document) + end + return value +end + +some_dictionary = function (d,document) + local f = dictionarytotable(d,true) + local t = setmetatable({ __raw__ = f, __type__ = dictionary_object_code }, { + __index = function(t,k) + return get_value(document,f,k) + end, + __call = function(t,k) + return get_flagged(t,f,k) + end, + } ) + return t, "dictionary" +end + +some_array = function (a,document) + local f = arraytotable(a,true) + local n = #f + local t = setmetatable({ __raw__ = f, __type__ = array_object_code, n = n }, { + __index = function(t,k) + return get_value(document,f,k) + end, + __call = function(t,k) + return get_flagged(t,f,k) + end, + __len = function(t,k) + return n + end, + } ) + return t, "array" +end + +some_stream = function(s,d,document) + local f = dictionarytotable(d,true) + local t = setmetatable({ __raw__ = f, __type__ = stream_object_code }, { + __index = function(t,k) + return get_value(document,f,k) + end, + __call = function(t,raw) + if raw == false then + return readwholestream(s,false) -- original + else + return readwholestream(s,true) -- uncompressed + end + end, + } ) + return t, "stream" +end + +some_reference = function(r,document) + local objnum = r[3] + local cached = document.__cache__[objnum] + if not cached then + local kind, object, b, c = getfromreference(r[2]) + if kind == dictionary_object_code then + cached = some_dictionary(object,document) + elseif kind == array_object_code then + cached = some_array(object,document) + elseif kind == stream_object_code then + cached = some_stream(object,b,document) + else + cached = { kind, object, b, c } + -- really cache this? + end + document.__cache__[objnum] = cached + document.__xrefs__[cached] = objnum + end + return cached +end + +local resolvers = { } +lpdf_epdf.resolvers = resolvers + +local function resolve(document,k) + local resolver = resolvers[k] + if resolver then + local entry = resolver(document) + document[k] = entry + return entry + end +end + +local function getnames(document,n,target) -- direct + if n then + local Names = n.Names + if Names then + if not target then + target = { } + end + for i=1,#Names,2 do + target[Names[i]] = Names[i+1] + end + else + local Kids = n.Kids + if Kids then + for i=1,#Kids do + target = getnames(document,Kids[i],target) + end + end + end + return target + end +end + +local function getkids(document,n,target) -- direct + if n then + local Kids = n.Kids + if Kids then + for i=1,#Kids do + target = getkids(document,Kids[i],target) + end + elseif target then + target[#target+1] = n + else + target = { n } + end + return target + end +end + +function resolvers.destinations(document) + local Names = document.Catalog.Names + return getnames(document,Names and Names.Dests) +end + +function resolvers.javascripts(document) + local Names = document.Catalog.Names + return getnames(document,Names and Names.JavaScript) +end + +function resolvers.widgets(document) + local Names = document.Catalog.AcroForm + return Names and Names.Fields +end + +function resolvers.embeddedfiles(document) + local Names = document.Catalog.Names + return getnames(document,Names and Names.EmbeddedFiles) +end + +-- /OCProperties << +-- /OCGs [ 15 0 R 17 0 R 19 0 R 21 0 R 23 0 R 25 0 R 27 0 R ] +-- /D << +-- /Order [ 15 0 R 17 0 R 19 0 R 21 0 R 23 0 R 25 0 R 27 0 R ] +-- /ON [ 15 0 R 17 0 R 19 0 R 21 0 R 23 0 R 25 0 R 27 0 R ] +-- /OFF [ ] +-- >> +-- >> + +function resolvers.layers(document) + local properties = document.Catalog.OCProperties + if properties then + local layers = properties.OCGs + if layers then + local t = { } + for i=1,#layers do + local layer = layers[i] + t[i] = layer.Name + end + -- t.n = n + return t + end + end +end + +function resolvers.structure(document) + -- this might become a tree + return document.Catalog.StructTreeRoot +end + +function resolvers.pages(document) + local __data__ = document.__data__ + local __xrefs__ = document.__xrefs__ + local __cache__ = document.__cache__ + -- + local nofpages = document.nofpages + local pages = { } + local rawpages = pagestotable(__data__) + document.pages = pages + -- + for pagenumber=1,nofpages do + local rawpagedata = rawpages[pagenumber] + local pagereference = rawpagedata[3] + local pageobject = rawpagedata[1] + local pagedata = some_dictionary(pageobject,document) + if pagedata and pageobject then + pagedata.number = pagenumber + pagedata.MediaBox = getbox(pageobject,"MediaBox") + pagedata.CropBox = getbox(pageobject,"CropBox") + pagedata.BleedBox = getbox(pageobject,"BleedBox") + pagedata.ArtBox = getbox(pageobject,"ArtBox") + pagedata.TrimBox = getbox(pageobject,"TrimBox") + pages[pagenumber] = pagedata + __xrefs__[pagedata] = pagereference + __cache__[pagereference] = pagedata + else + report_epdf("missing pagedata for page %i",i) + end + end + -- + -- pages.n = nofpages + -- + return pages +end + +local loaded = { } +local nofloaded = 0 + +function lpdf_epdf.load(filename,userpassword,ownerpassword,fromstring) + local document = loaded[filename] + if not document then + statistics.starttiming(lpdf_epdf) + local __data__ + if fromstring then + __data__ = newPDF(filename,#filename) + else + __data__ = openPDF(filename) + end + if __data__ then + if userpassword and getstatus(__data__) < 0 then + unencrypt(__data__,userpassword,nil) + end + if ownerpassword and getstatus(__data__) < 0 then + unencrypt(__data__,nil,ownerpassword) + end + if getstatus(__data__) < 0 then + report_epdf("the document is encrypted, provide proper passwords",getstatus(__data__)) + __data__ = false + end + if __data__ then + document = { + filename = filename, + __cache__ = { }, + __xrefs__ = { }, + __fonts__ = { }, + __copied__ = { }, + __data__ = __data__, + } + document.Catalog = some_dictionary(getcatalog(__data__),document) + document.Info = some_dictionary(getinfo(__data__),document) + document.Trailer = some_dictionary(gettrailer(__data__),document) + -- + setmetatableindex(document,resolve) + -- + document.majorversion, document.minorversion = getversion(__data__) + -- + document.nofpages = getnofpages(__data__) + else + document = false + end + else + document = false + end + loaded[filename] = document + loaded[document] = document + statistics.stoptiming(lpdf_epdf) + -- print(statistics.elapsedtime(lpdf_epdf)) + end + return document or nil +end + +function lpdf_epdf.unload(filename) + if type(filename) == "table" then + filename = filename.filename + end + if type(filename) == "string" then + local document = loaded[filename] + if document then +-- report_epdf("%04i closed: %s",nofloaded,filename) +-- nofloaded = nofloaded - 1 + loaded[document] = nil + loaded[filename] = nil + end + end +end + +-- for k, v in expanded(t) do + +local function expanded(t) + local function iterator(raw,k) + local k, v = next(raw,k) + if v then + return k, t[k] + end + end + return iterator, t.__raw__, nil +end + +---------.expand = expand +lpdf_epdf.expanded = expanded + +-- we could resolve the text stream in one pass if we directly handle the +-- font but why should we complicate things + +local spaces = lpegpatterns.whitespace^1 +local optspaces = lpegpatterns.whitespace^0 +local numchar = P("\\")/"" * (R("09")^3/function(s) return char(tonumber(s,8)) end) + + P("\\") * P(1) +local key = P("/") * C(R("AZ","az","09","__")^1) +local number = Ct(Cc("number") * (lpegpatterns.number/tonumber)) +local keyword = Ct(Cc("name") * key) +local operator = C((R("AZ","az")+P("*")+P("'")+P('"'))^1) + +local grammar = P { "start", + start = (keyword + number + V("dictionary") + V("array") + V("hexstring") + V("decstring") + spaces)^1, + keyvalue = key * optspaces * V("start"), + array = Ct(Cc("array") * P("[") * Ct(V("start")^1) * P("]")), + dictionary = Ct(Cc("dict") * P("<<") * Ct(V("keyvalue")^1) * P(">>")), + hexstring = Ct(Cc("hex") * P("<") * Cs(( 1-P(">"))^1) * P(">")), + decstring = Ct(Cc("dec") * P("(") * Cs((numchar+1-(P")"))^1) * P(")")), -- untested +} + +local operation = Ct(grammar^1 * operator) +local parser = Ct((operation + P(1))^1) + +-- todo: speed this one up + +local numchar = P("\\") * (R("09")^3 + P(1)) +local number = lpegpatterns.number +local keyword = P("/") * R("AZ","az","09","__")^1 +local operator = (R("AZ","az")+P("*")+P("'")+P('"'))^1 + +local skipstart = P("BDC") + P("BMC") + P("DP") + P("MP") +local skipstop = P("EMC") +local skipkeep = P("/ActualText") + +local grammar = P { "skip", + start = keyword + number + V("dictionary") + V("array") + V("hexstring") + V("decstring") + spaces, + keyvalue = optspaces * (keyword * optspaces * V("start") * optspaces)^1, + xeyvalue = optspaces * ((keyword - skipkeep) * optspaces * V("start") * optspaces)^1, + array = P("[") * V("start")^0 * P("]"), + dictionary = P("<<") * V("keyvalue")^0 * P(">>"), + xictionary = P("<<") * V("xeyvalue")^0 * P(">>"), + hexstring = P("<") * ( 1-P(">"))^0 * P(">"), + decstring = P("(") * (numchar+1-(P")"))^0 * P(")"), + skip = (optspaces * ( keyword * optspaces * V("xictionary") * optspaces * skipstart + skipstop) / "") + + V("start") + + operator +} + +local stripper = Cs((grammar + P(1))^1) + +function lpdf_epdf.parsecontent(str) + return lpegmatch(parser,str) +end + +function lpdf_epdf.stripcontent(str) + if find(str,"EMC") then + return lpegmatch(stripper,str) + else + return str + end +end + +-- beginbfrange : +-- [ ] +-- beginbfchar : + +local fromsixteen = lpdf.fromsixteen -- maybe inline the lpeg ... but not worth it + +local function f_bfchar(t,a,b) + t[tonumber(a,16)] = fromsixteen(b) +end + +local function f_bfrange_1(t,a,b,c) + print("todo 1",a,b,c) + -- c is string + -- todo t[tonumber(a,16)] = fromsixteen(b) +end + +local function f_bfrange_2(t,a,b,c) + print("todo 2",a,b,c) + -- c is table + -- todo t[tonumber(a,16)] = fromsixteen(b) +end + +local optionals = spaces^0 +local hexstring = optionals * P("<") * C((1-P(">"))^1) * P(">") +local bfchar = Carg(1) * hexstring * hexstring / f_bfchar +local bfrange = Carg(1) * hexstring * hexstring * hexstring / f_bfrange_1 + + Carg(1) * hexstring * hexstring * optionals * P("[") * Ct(hexstring^1) * optionals * P("]") / f_bfrange_2 +local fromunicode = ( + P("beginbfchar" ) * bfchar ^1 * optionals * P("endbfchar" ) + + P("beginbfrange") * bfrange^1 * optionals * P("endbfrange") + + spaces + + P(1) +)^1 * Carg(1) + +local function analyzefonts(document,resources) -- unfinished, see mtx-pdf for better code + local fonts = document.__fonts__ + if resources then + local fontlist = resources.Font + if fontlist then + for id, data in expanded(fontlist) do + if not fonts[id] then + -- a quick hack ... I will look into it more detail if I find a real + -- -application for it + local tounicode = data.ToUnicode() + if tounicode then + tounicode = lpegmatch(fromunicode,tounicode,1,{}) + end + fonts[id] = { + tounicode = type(tounicode) == "table" and tounicode or { } + } + setmetatableindex(fonts[id],"self") + end + end + end + end + return fonts +end + +local more = 0 +local unic = nil -- cheaper than passing each time as Carg(1) + +local p_hex_to_utf = C(4) / function(s) -- needs checking ! + local now = tonumber(s,16) + if more > 0 then + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 -- the 0x10000 smells wrong + more = 0 + return unic[now] or utfchar(now) + elseif now >= 0xD800 and now <= 0xDBFF then + more = now + -- return "" + else + return unic[now] or utfchar(now) + end +end + +local p_dec_to_utf = C(1) / function(s) -- needs checking ! + local now = byte(s) + return unic[now] or utfchar(now) +end + +local p_hex_to_utf = P(true) / function() more = 0 end * Cs(p_hex_to_utf^1) +local p_dec_to_utf = P(true) / function() more = 0 end * Cs(p_dec_to_utf^1) + +function lpdf_epdf.getpagecontent(document,pagenumber) + + local page = document.pages[pagenumber] + + if not page then + return + end + + local fonts = analyzefonts(document,page.Resources) + + local content = page.Contents() or "" + local list = lpegmatch(parser,content) + local font = nil + -- local unic = nil + + for i=1,#list do + local entry = list[i] + local size = #entry + local operator = entry[size] + if operator == "Tf" then + font = fonts[entry[1]] + unic = font.tounicode + elseif operator == "TJ" then -- { array, TJ } + local list = entry[1] + for i=1,#list do + local li = list[i] + if type(li) == "table" then + if li[1] == "hex" then + list[i] = lpegmatch(p_hex_to_utf,li[2]) + else + list[i] = lpegmatch(p_dec_to_utf,li[2]) + end + else + -- kern + end + end + elseif operator == "Tj" or operator == "'" or operator == '"' then -- { string, Tj } { string, ' } { n, m, string, " } + local list = entry[size-1] + if list[1] == "hex" then + list[2] = lpegmatch(p_hex_to_utf,li[2]) + else + list[2] = lpegmatch(p_dec_to_utf,li[2]) + end + end + end + + unic = nil -- can be collected + + return list + +end + +-- This is also an experiment. When I really need it I can improve it, for instance +-- with proper position calculating. It might be usefull for some search or so. + +local softhyphen = utfchar(0xAD) .. "$" +local linefactor = 1.3 + +function lpdf_epdf.contenttotext(document,list) -- maybe signal fonts + local last_y = 0 + local last_f = 0 + local text = { } + local last = 0 + + for i=1,#list do + local entry = list[i] + local size = #entry + local operator = entry[size] + if operator == "Tf" then + last_f = entry[2] + elseif operator == "TJ" then + local list = entry[1] + for i=1,#list do + local li = list[i] + if type(li) == "string" then + last = last + 1 + text[last] = li + elseif li < -50 then + last = last + 1 + text[last] = " " + end + end + line = concat(list) + elseif operator == "Tj" then + last = last + 1 + text[last] = entry[size-1] + elseif operator == "cm" or operator == "Tm" then + local ty = entry[6] + local dy = abs(last_y - ty) + if dy > linefactor*last_f then + if last > 0 then + if find(text[last],softhyphen,1,true) then + -- ignore + else + last = last + 1 + text[last] = "\n" + end + end + end + last_y = ty + end + end + + return concat(text) +end + +function lpdf_epdf.getstructure(document,list) -- just a test + local depth = 0 + for i=1,#list do + local entry = list[i] + local size = #entry + local operator = entry[size] + if operator == "BDC" then + report_epdf("%w%s : %s",depth,entry[1] or "?",entry[2] and entry[2].MCID or "?") + depth = depth + 1 + elseif operator == "EMC" then + depth = depth - 1 + elseif operator == "TJ" then + local list = entry[1] + for i=1,#list do + local li = list[i] + if type(li) == "string" then + report_epdf("%w > %s",depth,li) + elseif li < -50 then + report_epdf("%w >",depth,li) + end + end + elseif operator == "Tj" then + report_epdf("%w > %s",depth,entry[size-1]) + end + end +end + +if img then do + + -- This can be made a bit faster (just get raw data and pass it) but I will + -- do that later. In the end the benefit is probably neglectable. + + local recompress = false + local stripmarked = false + + local copydictionary = nil + local copyarray = nil + + local pdfreserveobject = lpdf.reserveobject + local shareobjectreference = lpdf.shareobjectreference + local pdfflushobject = lpdf.flushobject + local pdfflushstreamobject = lpdf.flushstreamobject + local pdfreference = lpdf.reference + local pdfconstant = lpdf.constant + local pdfarray = lpdf.array + local pdfdictionary = lpdf.dictionary + local pdfnull = lpdf.null + local pdfliteral = lpdf.literal + + local report = logs.reporter("backend","xobjects") + + local factor = 65536 / (7200/7227) -- 1/number.dimenfactors.bp + + local createimage = images.create + + directives.register("graphics.pdf.recompress", function(v) recompress = v end) + directives.register("graphics.pdf.stripmarked", function(v) stripmarked = v end) + + local function scaledbbox(b) + return { b[1]*factor, b[2]*factor, b[3]*factor, b[4]*factor } + end + + local codecs = { + ASCIIHexDecode = true, + ASCII85Decode = true, + RunLengthDecode = true, + FlateDecode = true, + LZWDecode = true, + } + + local function deepcopyobject(xref,copied,value) + -- no need for tables, just nested loop with obj + local objnum = xref[value] + if objnum then + local usednum = copied[objnum] + if usednum then + -- report("%s object %i is reused",kind,objnum) + else + usednum = pdfreserveobject() + copied[objnum] = usednum + local entry = value + local kind = entry.__type__ + if kind == array_object_code then + local a = copyarray(xref,copied,entry) + pdfflushobject(usednum,tostring(a)) + elseif kind == dictionary_object_code then + local d = copydictionary(xref,copied,entry) + pdfflushobject(usednum,tostring(d)) + elseif kind == stream_object_code then + local d = copydictionary(xref,copied,entry) + local filter = d.Filter + if filter and codecs[filter] and recompress then + -- recompress + d.Filter = nil + d.Length = nil + d.DecodeParms = nil -- relates to filter + d.DL = nil -- needed? + local s = entry() -- get uncompressed stream + pdfflushstreamobject(s,d,true,usednum) -- compress stream + else + -- keep as-is, even Length which indicates the + -- decompressed length + local s = entry(false) -- get compressed stream + -- pdfflushstreamobject(s,d,false,usednum,true) -- don't compress stream + pdfflushstreamobject(s,d,"raw",usednum) -- don't compress stream + end + else + local t = type(value) + if t == "string" then + value = pdfconstant(value) + elseif t == "table" then + local kind = value[1] + local entry = value[2] + if kind == name_object_code then + value = pdfconstant(entry) + elseif kind == string_object_code then + value = pdfliteral(entry,value[3]) + elseif kind == null_object_code then + value = pdfnull() + elseif kind == reference_object_code then + value = deepcopyobject(xref,copied,entry) + else + value = tostring(entry) + end + end + pdfflushobject(usednum,value) + end + end + return pdfreference(usednum) + elseif kind == stream_object_code then + report("stream not done: %s", objectcodes[kind] or "?") + else + report("object not done: %s", objectcodes[kind] or "?") + end + end + + local function copyobject(xref,copied,object,key,value) + if not value then + value = object.__raw__[key] + end + local t = type(value) + if t == "string" then + return pdfconstant(value) + elseif t ~= "table" then + return value + end + local kind = value[1] + if kind == name_object_code then + return pdfconstant(value[2]) + elseif kind == string_object_code then + return pdfliteral(value[2],value[3]) + elseif kind == array_object_code then + return copyarray(xref,copied,object[key]) + elseif kind == dictionary_object_code then + return copydictionary(xref,copied,object[key]) + elseif kind == null_object_code then + return pdfnull() + elseif kind == reference_object_code then + -- expand + return deepcopyobject(xref,copied,object[key]) + else + report("weird: %s", objecttypes[kind] or "?") + end + end + + copyarray = function (xref,copied,object) + local target = pdfarray() + local source = object.__raw__ + for i=1,#source do + target[i] = copyobject(xref,copied,object,i,source[i]) + end + return target + end + + local plugins = nil + + -- Sorting the hash slows down upto 5% bit but it is still as fast as the C + -- code. We could loop over the index instead but sorting might be nicer in + -- the end. + + copydictionary = function (xref,copied,object) + local target = pdfdictionary() + local source = object.__raw__ + -- for key, value in next, source do + for key, value in sortedhash(source) do + if plugins then + local p = plugins[key] + if p then + target[key] = p(xref,copied,object,key,value,copyobject) -- maybe a table of methods + else + target[key] = copyobject(xref,copied,object,key,value) + end + else + target[key] = copyobject(xref,copied,object,key,value) + end + end + return target + end + + -- local function copyresources(pdfdoc,xref,copied,pagedata) + -- local Resources = pagedata.Resources + -- if Resources then + -- local r = pdfreserveobject() + -- local d = copydictionary(xref,copied,Resources) + -- pdfflushobject(r,tostring(d)) + -- return pdfreference(r) + -- end + -- end + + local function copyresources(pdfdoc,xref,copied,pagedata) + local Resources = pagedata.Resources + -- + -- -- This needs testing: + -- + -- if not Resources then + -- local Parent = page.Parent + -- while (Parent and (Parent.__type__ == dictionary_object_code or Parent.__type__ == reference_object_code) do + -- Resources = Parent.Resources + -- if Resources then + -- break + -- end + -- Parent = Parent.Parent + -- end + -- end + if Resources then + local d = copydictionary(xref,copied,Resources) + return shareobjectreference(d) + end + end + + local openpdf = lpdf_epdf.load + local closepdf = lpdf_epdf.unload + + local function newpdf(str,userpassword,ownerpassword) + return openpdf(str,userpassword,ownerpassword,true) + end + + local function querypdf(pdfdoc,pagenumber) + if pdfdoc then + if not pagenumber then + pagenumber = 1 + end + local root = pdfdoc.Catalog + local page = pdfdoc.pages[pagenumber] + if page then + -- todo + local mediabox = page.MediaBox or { 0, 0, 0, 0 } + local cropbox = page.CropBox or mediabox + return { + filename = pdfdoc.filename, + pagenumber = pagenumber, + nofpages = pdfdoc.nofpages, + boundingbox = scaledbbox(cropbox), + cropbox = cropbox, + mediabox = mediabox, + bleedbox = page.BleedBox or cropbox, + trimbox = page.TrimBox or cropbox, + artbox = page.ArtBox or cropbox, + rotation = page.Rotate or 0, + xsize = cropbox[3] - cropbox[1], + ysize = cropbox[4] - cropbox[2], + } + end + end + end + + local function copypage(pdfdoc,pagenumber,attributes,compact,width,height,attr) + if pdfdoc then + local root = pdfdoc.Catalog + local page = pdfdoc.pages[pagenumber or 1] + local pageinfo = querypdf(pdfdoc,pagenumber) + local contents = page.Contents + local xref = pdfdoc.__xrefs__ + local copied = pdfdoc.__copied__ + if compact and lpdf_epdf.plugin then + plugins = lpdf_epdf.plugin(pdfdoc,xref,copied,page) + end + local xobject = pdfdictionary { + Type = pdfconstant("XObject"), + Subtype = pdfconstant("Form"), + FormType = 1, + Group = copyobject(xref,copied,page,"Group"), + LastModified = copyobject(xref,copied,page,"LastModified"), + Metadata = copyobject(xref,copied,page,"Metadata"), + PieceInfo = copyobject(xref,copied,page,"PieceInfo"), + Resources = copyresources(pdfdoc,xref,copied,page), + SeparationInfo = copyobject(xref,copied,page,"SeparationInfo"), + } + attr + if attributes then + for k, v in expanded(attributes) do + page[k] = v -- maybe nested + end + end + local content = "" + local nolength = nil + local ctype = contents.__type__ + -- we always recompress because image object streams can not be + -- influenced (yet) + if ctype == stream_object_code then + if stripmarked then + content = contents() -- uncompressed + local stripped = lpdf_epdf.stripcontent(content) + if stripped ~= content then + -- report("%i bytes stripped on page %i",#content-#stripped,pagenumber or 1) + content = stripped + end + elseif recompress then + content = contents() -- uncompressed + else + local Filter = copyobject(xref,copied,contents,"Filter") + local Length = copyobject(xref,copied,contents,"Length") + if Length and Filter then + nolength = true + xobject.Length = Length + xobject.Filter = Filter + content = contents(false) -- uncompressed + else + content = contents() -- uncompressed + end + end + elseif ctype == array_object_code then + content = { } + for i=1,#contents do + content[i] = contents[i]() -- uncompressed + end + content = concat(content," ") + end + -- still not nice: we double wrap now + plugins = nil + local rotation = pageinfo.rotation + local boundingbox = pageinfo.boundingbox + local transform = nil + if rotation == 90 then + transform = 3 + elseif rotation == 180 then + transform = 2 + elseif rotation == 270 then + transform = 1 + elseif rotation > 1 and rotation < 4 then + transform = rotation + end + xobject.BBox = pdfarray { + boundingbox[1] * bpfactor, + boundingbox[2] * bpfactor, + boundingbox[3] * bpfactor, + boundingbox[4] * bpfactor, + } + -- maybe like bitmaps + return createimage { -- beware: can be a img.new or a dummy + bbox = boundingbox, + transform = transform, + nolength = nolength, + nobbox = true, + notype = true, + stream = content, -- todo: no compress, pass directly also length, filter etc + attr = xobject(), + kind = images.types.stream, + } + end + end + + lpdf_epdf.image = { + open = openpdf, + close = closepdf, + new = newpdf, + query = querypdf, + copy = copypage, + } + +-- lpdf.injectors.pdf = function(specification) +-- local d = lpdf_epdf.load(specification.filename) +-- print(d) +-- end + + +end end + +-- local d = lpdf_epdf.load("e:/tmp/oeps.pdf") +-- inspect(d) +-- inspect(d.Catalog.Lang) +-- inspect(d.Catalog.OCProperties.D.AS[1].Event) +-- inspect(d.Catalog.Metadata()) +-- inspect(d.Catalog.Pages.Kids[1]) +-- inspect(d.layers) +-- inspect(d.pages) +-- inspect(d.destinations) +-- inspect(lpdf_epdf.getpagecontent(d,1)) +-- inspect(lpdf_epdf.contenttotext(document,lpdf_epdf.getpagecontent(d,1))) +-- inspect(lpdf_epdf.getstructure(document,lpdf_epdf.getpagecontent(d,1))) diff --git a/tex/context/base/mkiv/lpdf-pdx.xml b/tex/context/base/mkiv/lpdf-pdx.xml index 889862c76..35726a5c0 100644 --- a/tex/context/base/mkiv/lpdf-pdx.xml +++ b/tex/context/base/mkiv/lpdf-pdx.xml @@ -29,6 +29,7 @@ + diff --git a/tex/context/base/mkiv/lpdf-pua.xml b/tex/context/base/mkiv/lpdf-pua.xml index f985b54d3..f717762b6 100644 --- a/tex/context/base/mkiv/lpdf-pua.xml +++ b/tex/context/base/mkiv/lpdf-pua.xml @@ -29,6 +29,7 @@ + @@ -110,6 +111,12 @@ ConTeXt.Url Text + + external + ConTeXt support + ConTeXt.Support + Text + external ConTeXt version @@ -118,8 +125,38 @@ external - Banner of pdftex or one of its successors - PTEX.Fullbanner + ConTeXt LMTX version + ConTeXt.LMTX + Text + + + external + TeX support + TeX.Support + Text + + + external + LuaTeX version + LuaTeX.Version + Text + + + external + LuaTeX functionality + LuaTeX.Functionality + Text + + + external + LuaTeX Lua version + LuaTeX.LuaVersion + Text + + + external + LuaTeX platform + LuaTeX.Platform Text diff --git a/tex/context/base/mkiv/lpdf-ren.lua b/tex/context/base/mkiv/lpdf-ren.lua index e9b22f382..d6e95e66a 100644 --- a/tex/context/base/mkiv/lpdf-ren.lua +++ b/tex/context/base/mkiv/lpdf-ren.lua @@ -54,7 +54,7 @@ local copy_node = nuts.copy local nodepool = nuts.pool local register = nodepool.register -local pdfpageliteral = nodepool.pdfpageliteral +local pageliteral = nodepool.pageliteral local pdf_ocg = pdfconstant("OCG") local pdf_ocmd = pdfconstant("OCMD") @@ -261,7 +261,7 @@ function nodeinjections.startlayer(name) local c = cache[name] if not c then useviewerlayer(name) - c = register(pdfpageliteral(f_bdc(escapednames[name]))) + c = register(pageliteral(f_bdc(escapednames[name]))) cache[name] = c end return copy_node(c) @@ -269,7 +269,7 @@ end function nodeinjections.stoplayer() if not stop then - stop = register(pdfpageliteral(s_emc)) + stop = register(pageliteral(s_emc)) end return copy_node(stop) end @@ -286,7 +286,7 @@ function nodeinjections.startstackedlayer(s,t,first,last) r[#r+1] = startlayer(values[t[i]]) end r = concat(r," ") - return pdfpageliteral(r) + return pageliteral(r) end function nodeinjections.stopstackedlayer(s,t,first,last) @@ -295,7 +295,7 @@ function nodeinjections.stopstackedlayer(s,t,first,last) r[#r+1] = stoplayer() end r = concat(r," ") - return pdfpageliteral(r) + return pageliteral(r) end function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2) @@ -307,7 +307,7 @@ function nodeinjections.changestackedlayer(s,t1,first1,last1,t2,first2,last2) r[#r+1] = startlayer(values[t2[i]]) end r = concat(r," ") - return pdfpageliteral(r) + return pageliteral(r) end -- transitions diff --git a/tex/context/base/mkiv/lpdf-res.lua b/tex/context/base/mkiv/lpdf-res.lua index 8b00835ef..d3c591343 100644 --- a/tex/context/base/mkiv/lpdf-res.lua +++ b/tex/context/base/mkiv/lpdf-res.lua @@ -6,23 +6,25 @@ if not modules then modules = { } end modules ['lpdf-res'] = { license = "see context related readme files" } -local codeinjections = backends.codeinjections -local implement = interfaces.implement +local codeinjections = backends.codeinjections -local nuts = nodes.nuts -local tonut = nodes.tonut +local nuts = nodes.nuts +local tonut = nodes.tonut -local setwhd = nuts.setwhd -local setlist = nuts.setlist +local setwhd = nuts.setwhd +local setlist = nuts.setlist -local new_hlist = nuts.pool.hlist +local new_hlist = nuts.pool.hlist -local saveboxresource = tex.saveboxresource -local useboxresource = tex.useboxresource -local getboxresource = tex.getboxresourcedimensions +local boxresources = tex.boxresources +local saveboxresource = boxresources.save +local useboxresource = boxresources.use +local getboxresourcedimensions = boxresources.getdimensions + +local pdfcollectedresources = lpdf.collectedresources function codeinjections.registerboxresource(n,offset) - local r = saveboxresource(n,nil,lpdf.collectedresources(),true,0,offset or 0) -- direct, todo: accept functions as attr/resources + local r = saveboxresource(n,nil,pdfcollectedresources(),true,0,offset or 0) -- direct, todo: accept functions as attr/resources return r end @@ -35,5 +37,5 @@ function codeinjections.restoreboxresource(index) end function codeinjections.boxresourcedimensions(index) - return getboxresource(index) + return getboxresourcedimensions(index) end diff --git a/tex/context/base/mkiv/lpdf-swf.lua b/tex/context/base/mkiv/lpdf-swf.lua index 0ac107f8b..44e42dc5f 100644 --- a/tex/context/base/mkiv/lpdf-swf.lua +++ b/tex/context/base/mkiv/lpdf-swf.lua @@ -11,6 +11,7 @@ if not modules then modules = { } end modules ['lpdf-swf'] = { local format, gsub = string.format, string.gsub local concat = table.concat +local formatters = string.formatters local backends = backends local lpdf = lpdf @@ -33,6 +34,43 @@ local trace_swf = false trackers.register("backend.swf", function(v) trace_swf local report_swf = logs.reporter("backend","swf") +-------------------------------------------------------------------------------------- + +local createimage = images.create +local embedimage = images.embed + +local basepoints = number.dimenfactors.bp + +local f_image = formatters["%.6F 0 0 %.6F 0 0 cm /%s Do"] + +directives.register("pdf.stripzeros",function() + f_image = formatters["%.6N 0 0 %.6N 0 0 cm /%s Do"] +end) + +local function package(image) -- see lpdf-u3d ** + local boundingbox = image.bbox + local imagetag = "Im" .. image.index -- this is not ok + local resources = pdfdictionary { + ProcSet = lpdf.procset(), + Resources = pdfdictionary { + XObject = pdfdictionary { + [imagetag] = pdfreference(image.objnum) + } + } + } + local width = boundingbox[3] + local height = boundingbox[4] + local xform = createimage { + attr = resources(), + stream = f_image(width,height,imagetag), + bbox = { 0, 0, width/basepoints, height/basepoints }, + } + embedimage(xform) + return xform +end + +-------------------------------------------------------------------------------------- + local activations = { click = "XA", page = "PO", @@ -65,7 +103,10 @@ local function insertswf(spec) local preview = checkedkey(display,"preview","string") local toolbar = checkedkey(display,"toolbar","boolean") - local embeddedreference = codeinjections.embedfile { file = filename } + local embeddedreference = codeinjections.embedfile { + file = filename, + compress = false, + } local flash = pdfdictionary { Subtype = pdfconstant("RichMediaConfiguration"), @@ -122,6 +163,7 @@ local function insertswf(spec) file = fullname, usedname = usedname, keepdir = true, + compress = false, } names[#names+1] = pdfstring(filename) names[#names+1] = embeddedreference @@ -275,7 +317,7 @@ local function insertswf(spec) end end if figure then - local image = img.package(figure.status.private) + local image = package(figure.status.private) appearance = pdfdictionary { N = pdfreference(image.objnum) } if trace_swf then report_swf("using preview %s",preview) diff --git a/tex/context/base/mkiv/lpdf-tag.lua b/tex/context/base/mkiv/lpdf-tag.lua index f4ecfc8a6..0a2fe679e 100644 --- a/tex/context/base/mkiv/lpdf-tag.lua +++ b/tex/context/base/mkiv/lpdf-tag.lua @@ -13,7 +13,8 @@ local settings_to_hash = utilities.parsers.settings_to_hash local sortedhash = table.sortedhash local formatters = string.formatters -local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end) +local trace_tags = false trackers.register("structures.tags", function(v) trace_tags = v end) +local trace_info = false trackers.register("structures.tags.info", function(v) trace_info = v end) local report_tags = logs.reporter("backend","tags") @@ -51,11 +52,9 @@ local a_tagged = attributes.private('tagged') local a_image = attributes.private('image') local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local nodepool = nuts.pool -local pdfpageliteral = nodepool.pdfpageliteral +local pageliteral = nodepool.pageliteral local register = nodepool.register local getid = nuts.getid @@ -68,17 +67,17 @@ local setlink = nuts.setlink local setlist = nuts.setlist local copy_node = nuts.copy -local traverse_nodes = nuts.traverse local tosequence = nuts.tosequence -local structure_stack = { } -local structure_kids = pdfarray() -local structure_ref = pdfreserveobject() -local parent_ref = pdfreserveobject() -local root = { pref = pdfreference(structure_ref), kids = structure_kids } +local nextnode = nuts.traversers.node + +local structure_kids -- delayed +local structure_ref -- delayed +local parent_ref -- delayed +local root -- delayed +local names -- delayed local tree = { } local elements = { } -local names = pdfarray() local structurestags = structures.tags local taglist = structurestags.taglist @@ -112,7 +111,7 @@ local usedmapping = { } -- end local function finishstructure() - if #structure_kids > 0 then + if root and #structure_kids > 0 then local nums, n = pdfarray(), 0 for i=1,#tree do n = n + 1 ; nums[n] = i - 1 @@ -171,6 +170,7 @@ local index, pageref, pagenum, list = 0, nil, 0, nil local pdf_mcr = pdfconstant("MCR") local pdf_struct_element = pdfconstant("StructElem") +local pdf_s = pdfconstant("S") local function initializepage() index = 0 @@ -183,6 +183,8 @@ end local function finishpage() -- flush what can be flushed addtopageattributes("StructParents",pagenum-1) + -- there might be more + addtopageattributes("Tabs",s) end -- here we can flush and free elements that are finished @@ -255,9 +257,10 @@ local function makeelement(fulltag,parent) AF = af, } local s = pdfreference(pdfflushobject(d)) - if id then - names[#names+1] = id - names[#names+1] = s + if id and names then + local size = #names + names[size+1] = id + names[size+2] = s end local kids = parent.kids kids[#kids+1] = s @@ -314,27 +317,35 @@ end -- no need to adapt head, as we always operate on lists local EMCliteral = nil +local visualize = nil function nodeinjections.addtags(head) if not EMCliteral then - EMCliteral = register(pdfpageliteral("EMC")) + EMCliteral = register(pageliteral("EMC")) end local last = nil local ranges = { } local range = nil - local head = tonut(head) + + if not root then + structure_kids = pdfarray() + structure_ref = pdfreserveobject() + parent_ref = pdfreserveobject() + root = { pref = pdfreference(structure_ref), kids = structure_kids } + names = pdfarray() + end local function collectranges(head,list) - for n in traverse_nodes(head) do - local id = getid(n) + for n, id in nextnode, head do if id == glyph_code then -- maybe also disc - local at = getattr(n,a_tagged) - if not at then - range = nil - elseif last ~= at then + local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact + -- if not at then + -- range = nil + -- elseif ... + if last ~= at then range = { at, "glyph", n, n, list } -- attr id start stop list ranges[#ranges+1] = range last = at @@ -344,12 +355,12 @@ function nodeinjections.addtags(head) elseif id == hlist_code or id == vlist_code then local at = getattr(n,a_image) if at then - local at = getattr(n,a_tagged) - if not at then - range = nil - else + local at = getattr(n,a_tagged) or false -- false: pagebody or so, so artifact + -- if not at then + -- range = nil + -- else ranges[#ranges+1] = { at, "image", n, n, list } -- attr id start stop list - end + -- end last = nil else collectranges(getlist(n),n) @@ -379,89 +390,117 @@ function nodeinjections.addtags(head) local top = nil local noftop = 0 + + local function inject(start,stop,list,literal,left,right) + local prev = getprev(start) + if prev then + setlink(prev,literal) + end + if left then + setlink(literal,left,start) + else + setlink(literal,start) + end + if list and getlist(list) == start then + setlist(list,literal) + end + local literal = copy_node(EMCliteral) + -- use insert instead: + local next = getnext(stop) + if next then + setlink(literal,next) + end + if right then + setlink(stop,right,literal) + else + setlink(stop,literal) + end + end + for i=1,#ranges do - local range = ranges[i] - local attr = range[1] - local id = range[2] - local start = range[3] - local stop = range[4] - local list = range[5] - local specification = taglist[attr] - local taglist = specification.taglist - local noftags = #taglist - local common = 0 - if top then - for i=1,noftags >= noftop and noftop or noftags do - if top[i] == taglist[i] then - common = i - else - break + + local range = ranges[i] + local attr = range[1] + local id = range[2] + local start = range[3] + local stop = range[4] + local list = range[5] + + if attr then + + local specification = taglist[attr] + local taglist = specification.taglist + local noftags = #taglist + local common = 0 + local literal = nil + local ignore = false + + if top then + for i=1,noftags >= noftop and noftop or noftags do + if top[i] == taglist[i] then + common = i + else + break + end end end - end - local prev = common > 0 and elements[taglist[common]] or root - local ignore = false - local literal = nil - - for j=common+1,noftags do - local tag = taglist[j] - local prv = elements[tag] or makeelement(tag,prev) - if prv == false then - -- ignore this one - prev = false - ignore = true - break - elseif prv == true then - -- skip this one - else - prev = prv + local prev = common > 0 and elements[taglist[common]] or root + + for j=common+1,noftags do + local tag = taglist[j] + local prv = elements[tag] or makeelement(tag,prev) + if prv == false then + -- ignore this one + prev = false + ignore = true + break + elseif prv == true then + -- skip this one + else + prev = prv + end end - end - if prev then - literal = pdfpageliteral(makecontent(prev,id,specification)) - elseif ignore then - literal = pdfpageliteral(makeignore(specification)) - end - if literal then - local prev = getprev(start) if prev then - setlink(prev,literal) - end - setlink(literal,start) - if list and getlist(list) == start then - setlist(list,literal) + literal = pageliteral(makecontent(prev,id,specification)) + elseif ignore then + literal = pageliteral(makeignore(specification)) + else + -- maybe also ignore or maybe better: comment or so end - local literal = copy_node(EMCliteral) - -- use insert instead: - local next = getnext(stop) - if next then - setlink(literal,next) + + if literal then + local left,right + if trace_info then + local name = specification.tagname + if name then + if not visualize then + visualize = nodes.visualizers.register("tags") + end + left = visualize(name) + right = visualize() + end + end + inject(start,stop,list,literal,left,right) end - setlink(stop,literal) - end --- if literal then --- if list and getlist(list) == start then --- setlink(literal,start) --- setlist(list,literal) --- else --- setlink(getprev(start),literal,start) --- end --- -- use insert instead: --- local literal = copy_node(EMCliteral) --- setlink(stop,literal,getnext(stop)) --- end + top = taglist + noftop = noftags + + else + + local literal = pageliteral(makeignore(specification)) + + inject(start,stop,list,literal) + + end - top = taglist - noftop = noftags end finishpage() - head = tonode(head) - return head, true + return head end @@ -472,8 +511,7 @@ end -- local last, ranges, range = nil, { }, nil -- -- local function collectranges(head,list) --- for n in traverse_nodes(head) do --- local id = getid(n) -- 14: image, 8: literal (mp) +-- for n, id in nextnode, head do -- if id == glyph_code then -- local at = getattr(n,a_tagged) -- if not at then @@ -505,7 +543,6 @@ end -- -- initializepage() -- --- head = tonut(head) -- collectranges(head) -- -- if trace_tags then @@ -577,9 +614,9 @@ end -- end -- -- if r > 0 then --- local literal = pdfpageliteral(concat(result,"\n")) +-- local literal = pageliteral(concat(result,"\n")) -- -- use insert instead: --- local literal = pdfpageliteral(result) +-- local literal = pageliteral(result) -- local prev = getprev(start) -- if prev then -- setlink(prev,literal) @@ -601,7 +638,7 @@ end -- for i=1,noftop do -- result[i] = "EMC" -- end --- local literal = pdfpageliteral(concat(result,"\n")) +-- local literal = pageliteral(concat(result,"\n")) -- -- use insert instead: -- local next = getnext(last) -- if next then @@ -612,8 +649,7 @@ end -- -- finishpage() -- --- head = tonode(head) --- return head, true +-- return head -- -- end diff --git a/tex/context/base/mkiv/lpdf-u3d.lua b/tex/context/base/mkiv/lpdf-u3d.lua index dfd4c1b06..f6897e92d 100644 --- a/tex/context/base/mkiv/lpdf-u3d.lua +++ b/tex/context/base/mkiv/lpdf-u3d.lua @@ -27,7 +27,6 @@ local nodeinjections = backends.pdf.nodeinjections local pdfconstant = lpdf.constant local pdfboolean = lpdf.boolean -local pdfnumber = lpdf.number local pdfunicode = lpdf.unicode local pdfdictionary = lpdf.dictionary local pdfarray = lpdf.array @@ -39,6 +38,8 @@ local pdfflushstreamfileobject = lpdf.flushstreamfileobject local checkedkey = lpdf.checkedkey local limited = lpdf.limited +local embedimage = images.embed + local schemes = table.tohash { "Artwork", "None", "White", "Day", "Night", "Hard", "Primary", "Blue", "Red", "Cube", "CAD", "Headlamp", @@ -347,6 +348,12 @@ end local stored_js, stored_3d, stored_pr, streams = { }, { }, { }, { } +local f_image = formatters["q /GS gs %.6F 0 0 %.6F 0 0 cm /IM Do Q"] + +directives.register("pdf.stripzeros",function() + f_image = formatters["q /GS gs %.6N 0 0 %.6N 0 0 cm /IM Do Q"] +end) + local function insert3d(spec) -- width, height, factor, display, controls, label, foundname local width, height, factor = spec.width, spec.height, spec.factor or number.dimenfactors.bp @@ -431,7 +438,7 @@ local function insert3d(spec) -- width, height, factor, display, controls, label local tag = formatters["%s:%s:%s"](label,stream,preview) local ref = stored_pr[tag] if not ref then - local figure = img.immediatewrite { + local figure = embedimage { filename = preview, width = width, height = height @@ -440,13 +447,13 @@ local function insert3d(spec) -- width, height, factor, display, controls, label stored_pr[tag] = ref end if ref then -- see back-pdf ** .. here we have a local /IM ! - local zero, one = pdfnumber(0), pdfnumber(1) -- not really needed local pw = pdfdictionary { Type = pdfconstant("XObject"), Subtype = pdfconstant("Form"), - FormType = one, - BBox = pdfarray { zero, zero, pdfnumber(factor*width), pdfnumber(factor*height) }, - Matrix = pdfarray { one, zero, zero, one, zero, zero }, + FormType = 1, + BBox = pdfarray { 0, 0, pdfnumber(factor*width), pdfnumber(factor*height) }, + Matrix = pdfarray { 1, 0, 0, 1, 0, 0 }, + ProcSet = lpdf.procset(), Resources = pdfdictionary { XObject = pdfdictionary { IM = pdfreference(ref) @@ -455,13 +462,12 @@ local function insert3d(spec) -- width, height, factor, display, controls, label ExtGState = pdfdictionary { GS = pdfdictionary { Type = pdfconstant("ExtGState"), - CA = one, - ca = one, + CA = 1, + ca = 1, } }, - ProcSet = pdfarray { pdfconstant("PDF"), pdfconstant("ImageC") }, } - local pwd = pdfflushstreamobject(formatters["q /GS gs %.6F 0 0 %.6F 0 0 cm /IM Do Q"](factor*width,factor*height),pw) + local pwd = pdfflushstreamobject(f_image(factor*width,factor*height),pw) annot.AP = pdfdictionary { N = pdfreference(pwd) } diff --git a/tex/context/base/mkiv/lpdf-wid.lua b/tex/context/base/mkiv/lpdf-wid.lua index 03febbf01..a929ed2ce 100644 --- a/tex/context/base/mkiv/lpdf-wid.lua +++ b/tex/context/base/mkiv/lpdf-wid.lua @@ -11,11 +11,11 @@ if not modules then modules = { } end modules ['lpdf-wid'] = { -- had renditions but they turned out to be unreliable from the start and look -- obsolete too or at least they are bound to the (obsolete) flash technology for -- rendering. They were already complex constructs. Now we have rich media which --- instead of providing a robust future proof framework fo rgeneral media types +-- instead of providing a robust future proof framework for general media types -- again seems to depend on viewers built in (yes, also kind of obsolete) flash -- technology, and we cannot expect this non-open technology to show up in open -- browsers. So, in the end we can best just use links to external resources to be --- future proof. Just look at the viewer prferences pane to see how fragile support +-- future proof. Just look at the viewer preferences pane to see how fragile support -- is. Interestingly u3d support is kind of built in, while e.g. mp4 support relies -- on wrapping in swf. We used to stay ahead of the pack with support of the fancy -- pdf features but it backfires and is not worth the trouble. And yes, for control @@ -29,7 +29,7 @@ local gmatch, gsub, find, lower = string.gmatch, string.gsub, string.find, strin local stripstring = string.strip local settings_to_array = utilities.parsers.settings_to_array local settings_to_hash = utilities.parsers.settings_to_hash -local sortedhash = table.sortedhash +local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys local report_media = logs.reporter("backend","media") local report_attachment = logs.reporter("backend","attachment") @@ -141,6 +141,10 @@ local attachment_symbols = { attachment_symbols.PushPin = attachment_symbols.Pushpin attachment_symbols.Default = attachment_symbols.Pushpin +function lpdf.attachmentsymbols() + return sortedkeys(comment_symbols) +end + local comment_symbols = { Comment = pdfconstant("Comment"), Help = pdfconstant("Help"), @@ -154,6 +158,10 @@ local comment_symbols = { comment_symbols.NewParagraph = Newparagraph comment_symbols.Default = Note +function lpdf.commentsymbols() + return sortedkeys(comment_symbols) +end + local function analyzesymbol(symbol,collection) if not symbol or symbol == "" then return collection and collection.Default, nil @@ -239,10 +247,12 @@ local function flushembeddedfiles() e[#e+1] = pdfstring(tag) e[#e+1] = reference -- already a reference else - -- messy spec ... when annot not in named else twice in menu list acrobat + -- -- messy spec ... when annot not in named else twice in menu list acrobat end end - lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e }))) + if #e > 0 then + lpdf.addtonames("EmbeddedFiles",pdfreference(pdfflushobject(pdfdictionary{ Names = e }))) + end end end @@ -257,9 +267,13 @@ function codeinjections.embedfile(specification) local keepdir = specification.keepdir -- can change local usedname = specification.usedname local filetype = specification.filetype + local compress = specification.compress if filename == "" then filename = nil end + if compress == nil then + compress = true + end if data then local r = filestreams[hash] if r == false then @@ -314,7 +328,7 @@ function codeinjections.embedfile(specification) specification.data = true -- signal that still data but already flushed else local foundname = specification.foundname or filename - f = pdfflushstreamfileobject(foundname,a) + f = pdfflushstreamfileobject(foundname,a,compress) end local d = pdfdictionary { Type = pdfconstant("Filespec"), @@ -417,7 +431,8 @@ function codeinjections.attachmentid(filename) -- not used in context return filestreams[filename] end -local nofcomments, usepopupcomments = 0, false +local nofcomments = 0 +local usepopupcomments = false local defaultattributes = { ["xmlns"] = "http://www.w3.org/1999/xhtml", @@ -612,7 +627,8 @@ local function insertrendering(specification) local option = settings_to_hash(specification.option) if not mf[label] then local filename = specification.filename - local isurl = find(filename,"://",1,true) + local isurl = find(filename,"://",1,true) + local mimetype = specification.mimetype or specification.mime -- local start = pdfdictionary { -- Type = pdfconstant("MediaOffset"), -- S = pdfconstant("T"), -- time @@ -648,13 +664,17 @@ local function insertrendering(specification) if isurl then descriptor.FS = pdfconstant("URL") elseif option[v_embed] then - descriptor.EF = codeinjections.embedfile { file = filename } + descriptor.EF = codeinjections.embedfile { + file = filename, + mimetype = mimetype, -- yes or no + compress = false, + } end local clip = pdfdictionary { Type = pdfconstant("MediaClip"), S = pdfconstant("MCD"), N = label, - CT = specification.mime, + CT = mimetype, Alt = pdfarray { "", "file not found" }, -- language id + message D = pdfreference(pdfflushobject(descriptor)), -- P = pdfreference(pdfflushobject(parameters)), diff --git a/tex/context/base/mkiv/lpdf-xmp.lua b/tex/context/base/mkiv/lpdf-xmp.lua index eb15a3582..508bb1997 100644 --- a/tex/context/base/mkiv/lpdf-xmp.lua +++ b/tex/context/base/mkiv/lpdf-xmp.lua @@ -11,6 +11,7 @@ local tostring, type = tostring, type local format, gsub = string.format, string.gsub local utfchar = utf.char local xmlfillin = xml.fillin +local md5HEX = md5.HEX local trace_xmp = false trackers.register("backend.xmp", function(v) trace_xmp = v end) local trace_info = false trackers.register("backend.info", function(v) trace_info = v end) @@ -33,7 +34,7 @@ local pdfgetmetadata = lpdf.getmetadata -- XMP-Toolkit-SDK-CC201607.zip. So we hardcode the id. local xpacket = format ( [[ - + %%s @@ -46,7 +47,8 @@ local mapping = { ["ConTeXt.Url"] = { "context", "rdf:Description/pdfx:ConTeXt.Url" }, ["ConTeXt.Support"] = { "context", "rdf:Description/pdfx:ConTeXt.Support" }, ["ConTeXt.Version"] = { "context", "rdf:Description/pdfx:ConTeXt.Version" }, - ["TeX.Support"] = { "metadata", "rdf:Description/pdfx:TeX.Support" }, + ["ConTeXt.LMTX"] = { "context", "rdf:Description/pdfx:ConTeXt.LMTX" }, + ["TeX.Support"] = { "metadata","rdf:Description/pdfx:TeX.Support" }, ["LuaTeX.Version"] = { "metadata","rdf:Description/pdfx:LuaTeX.Version" }, ["LuaTeX.Functionality"] = { "metadata","rdf:Description/pdfx:LuaTeX.Functionality" }, ["LuaTeX.LuaVersion"] = { "metadata","rdf:Description/pdfx:LuaTeX.LuaVersion" }, @@ -89,7 +91,7 @@ local mapping = { ["CaptionWriter"] = { "metadata", "rdf:Description/photoshop:CaptionWriter" }, } -pdf.setsuppressoptionalinfo( +lpdf.setsuppressoptionalinfo ( 0 -- + 1 -- pdfnofullbanner + 2 -- pdfnofilename @@ -104,59 +106,62 @@ pdf.setsuppressoptionalinfo( ) local included = backends.included - -local pdfsettrailerid = pdf.settrailerid - -local lpdfid = lpdf.id +local lpdfid = lpdf.id function lpdf.id() -- overload of ini return lpdfid(included.date) end -pdf.disablecommand("settrailerid") +local settrailerid = lpdf.settrailerid -- this is the wrapped one + +local trailerid = nil +local dates = nil -function lpdf.settrailerid(v) - if v then - local b = toboolean(v) or v == "" +local function update() + if trailer_id then + local b = toboolean(trailer_id) or trailer_id == "" if b then - v = "This file is processed by ConTeXt and LuaTeX." + trailer_id = "This file is processed by ConTeXt and LuaTeX." else - v = tostring(v) + trailer_id = tostring(trailer_id) end - local h = md5.HEX(v) + local h = md5HEX(trailer_id) if b then report_info("using frozen trailer id") else - report_info("using hashed trailer id %a (%a)",v,h) + report_info("using hashed trailer id %a (%a)",trailer_id,h) end - pdfsettrailerid(format("[<%s> <%s>]",h,h)) + settrailerid(format("[<%s> <%s>]",h,h)) end -end - -function lpdf.setdates(v) - local t = type(v) + -- + local t = type(dates) if t == "number" or t == "string" then - t = converters.totime(v) - if t then + local d = converters.totime(dates) + if d then included.date = true included.id = "fake" - report_info("forced date/time information %a will be used",lpdf.settime(t)) - lpdf.settrailerid(false) + report_info("forced date/time information %a will be used",lpdf.settime(d)) + settrailerid(false) return end - end - v = toboolean(v) - included.date = v - if v then - included.id = true - else - report_info("no date/time but fake id information will be added") - lpdf.settrailerid(true) - included.id = "fake" - -- maybe: lpdf.settime(231631200) -- 1975-05-05 % first entry of knuth about tex mentioned in DT + if t == "string" then + dates = toboolean(dates) + included.date = dates + if dates ~= false then + included.id = true + else + report_info("no date/time but fake id information will be added") + settrailerid(true) + included.id = "fake" + end + end end end +function lpdf.settrailerid(v) trailerid = v end +function lpdf.setdates (v) dates = v end + +lpdf.registerdocumentfinalizer(update,"trailer id and dates",1) directives.register("backend.trailerid", lpdf.settrailerid) directives.register("backend.date", lpdf.setdates) @@ -313,7 +318,7 @@ local function flushxmpinfo() commands.poprandomseed() -- hack end --- his will be enabled when we can inhibit compression for a stream at the lua end +-- this will be enabled when we can inhibit compression for a stream at the lua end lpdf.registerdocumentfinalizer(flushxmpinfo,1,"metadata") diff --git a/tex/context/base/mkiv/luat-bas.mkiv b/tex/context/base/mkiv/luat-bas.mkiv index b1af4da3e..0add4ce69 100644 --- a/tex/context/base/mkiv/luat-bas.mkiv +++ b/tex/context/base/mkiv/luat-bas.mkiv @@ -13,6 +13,7 @@ \writestatus{loading}{ConTeXt Lua Macros / Basic Lua Libraries} +\registerctxluafile{l-bit32} {} % before sandbox \registerctxluafile{l-lua} {} % before sandbox \registerctxluafile{l-macro} {} \registerctxluafile{l-sandbox} {} @@ -30,6 +31,7 @@ \registerctxluafile{l-file} {} \registerctxluafile{l-gzip} {} \registerctxluafile{l-md5} {} +\registerctxluafile{l-sha} {} \registerctxluafile{l-dir} {} \registerctxluafile{l-unicode} {optimize} %registerctxluafile{l-utils} {} diff --git a/tex/context/base/mkiv/luat-cbk.lua b/tex/context/base/mkiv/luat-cbk.lua index 6fcfdc7f2..d3184e1af 100644 --- a/tex/context/base/mkiv/luat-cbk.lua +++ b/tex/context/base/mkiv/luat-cbk.lua @@ -121,6 +121,12 @@ if trace_calls then end +-- temporary, not public: + +callbacks.functions = { } + +-- till here + local reported = { } local function register_usercall(what,name,func) diff --git a/tex/context/base/mkiv/luat-cnf.lua b/tex/context/base/mkiv/luat-cnf.lua index b6ee15083..0670d1684 100644 --- a/tex/context/base/mkiv/luat-cnf.lua +++ b/tex/context/base/mkiv/luat-cnf.lua @@ -154,6 +154,8 @@ function texconfig.init() end +CONTEXTLMTXMODE = %s + -- we provide a qualified path callback.register('find_format_file',function(name) @@ -212,7 +214,7 @@ local function makestub() t[#t+1] = format("texconfig.%s=%s",v,tv) end end - io.savedata(name,format("%s\n\n%s",concat(t,"\n"),format(stub,firsttable))) + io.savedata(name,format("%s\n\n%s",concat(t,"\n"),format(stub,firsttable,tostring(CONTEXTLMTXMODE) or 0))) logs.newline() end diff --git a/tex/context/base/mkiv/luat-cod.lua b/tex/context/base/mkiv/luat-cod.lua index 91bb7c2e1..dcb16c0dd 100644 --- a/tex/context/base/mkiv/luat-cod.lua +++ b/tex/context/base/mkiv/luat-cod.lua @@ -11,6 +11,10 @@ local match, gsub, find, format, gmatch = string.match, string.gsub, string.find local texconfig, lua = texconfig, lua +-- maybe pick up from commandline: +-- +-- texconfig.interaction: 0=batchmode 1=nonstopmode 2=scrollmode 3=errornonstopmode 4=normal + -- some basic housekeeping texconfig.kpse_init = false @@ -38,7 +42,7 @@ lua.bytedata = bytedata lua.bytedone = bytedone local setbytecode = lua.setbytecode -local getbytecode = lua.getbytecode +----- getbytecode = lua.getbytecode lua.firstbytecode = 501 lua.lastbytecode = lua.lastbytecode or (lua.firstbytecode - 1) -- as we load ourselves again ... maybe return earlier @@ -49,9 +53,13 @@ end -- no file.* and utilities.parsers.* functions yet +local strip = false if arg then for i=-1,#arg do if arg[i] == "--c:strip" then strip = true break end end end + function lua.registercode(filename,options) local barename = gsub(filename,"%.[%a%d]+$","") - if barename == filename then filename = filename .. ".lua" end + if barename == filename then + filename = filename .. ".lua" + end local basename = match(barename,"^.+[/\\](.-)$") or barename if not bytedone[basename] then local opts = { } @@ -66,7 +74,11 @@ function lua.registercode(filename,options) if environment.initex then local n = lua.lastbytecode + 1 bytedata[n] = { name = barename, options = opts } - setbytecode(n,code) + if strip or opts.strip then + setbytecode(n,code,true) + else + setbytecode(n,code) + end lua.lastbytecode = n end elseif environment.initex then @@ -129,6 +141,18 @@ if LUATEXVERION == nil then + (tonumber(LUATEXVERSION) or (string.byte(LUATEXVERSION)-string.byte("a")+10))/1000 end +if CONTEXTLMTXMODE == nil then + if status.obj_ptr == nil then + CONTEXTLMTXMODE = 2 + else + CONTEXTLMTXMODE = 0 + for i=1,#arg do if arg[i] == "--c:lmtx" then + CONTEXTLMTXMODE, pdf, img = 1, nil, nil + break + end end + end +end + if LUATEXFUNCTIONALITY == nil then LUATEXFUNCTIONALITY = status.development_id or 6346 end @@ -143,7 +167,7 @@ end environment.luatexengine = LUATEXENGINE environment.luatexversion = LUATEXVERSION -environment.luatexfuncitonality = LUATEXFUNCTIONALITY +environment.luatexfunctionality = LUATEXFUNCTIONALITY environment.jitsupported = JITSUPPORTED environment.initex = INITEXMODE environment.initexmode = INITEXMODE @@ -151,12 +175,14 @@ environment.initexmode = INITEXMODE if not environment.luafilechunk then function environment.luafilechunk(filename) + local fullname = filename if sourcepath ~= "" then - filename = sourcepath .. "/" .. filename + fullname = sourcepath .. "/" .. filename end - local data = loadfile(filename) - texio.write("term and log","<",data and "+ " or "- ",filename,">") + local data = loadfile(fullname) + texio.write("term and log","<",data and "+ " or "- ",fullname,">") if data then +-- package.loaded[gsub(filename,"%..-$"] = data() end return data @@ -187,6 +213,21 @@ end -- a kpse error when disabled. This is an engine issue that will -- be sorted out in due time. +if not lfs.isfile then + + local attributes = lfs.attributes + + function lfs.isdir(name) + return attributes(name,"mode") == "directory" + end + + function lfs.isfile(name) + local a = attributes(name,"mode") + return a == "file" or a == "link" or nil + end + +end + local isfile = lfs.isfile local function source_file(name) @@ -229,6 +270,15 @@ local function open_read_file(name) } end +local function find_data_file(name) + return source_file(name) +end + +local open_data_file = open_read_file + callback.register('find_read_file' , find_read_file ) callback.register('open_read_file' , open_read_file ) callback.register('find_write_file', find_write_file) + +callback.register('find_data_file' , find_data_file ) +callback.register('open_data_file' , open_data_file ) diff --git a/tex/context/base/mkiv/luat-env.lua b/tex/context/base/mkiv/luat-env.lua index 5b46b4036..e0c69d207 100644 --- a/tex/context/base/mkiv/luat-env.lua +++ b/tex/context/base/mkiv/luat-env.lua @@ -11,7 +11,8 @@ -- sense. Much of this evolved before bytecode arrays were available and so a lot of -- code has disappeared already. -local rawset, rawget, loadfile, assert = rawset, rawget, loadfile, assert +local rawset, rawget, loadfile = rawset, rawget, loadfile +local gsub = string.gsub local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end) @@ -123,7 +124,7 @@ function environment.loadluafile(filename, version) luaname = file.addsuffix(basename,luasuffixes.lua) lucname = file.addsuffix(basename,luasuffixes.luc) else - luaname = basename -- forced suffix + luaname = filename -- forced suffix lucname = nil end -- when not overloaded by explicit suffix we look for a luc file first @@ -136,7 +137,7 @@ function environment.loadluafile(filename, version) chunk = loadfile(fullname) -- this way we don't need a file exists check end if chunk then - assert(chunk)() + chunk() if version then -- we check of the version number of this chunk matches local v = version -- can be nil @@ -168,9 +169,24 @@ function environment.loadluafile(filename, version) report_lua("unknown file %a",filename) end else - assert(chunk)() + chunk() return true end end return false end + +environment.filenames = setmetatable( { }, { + __index = function(t,k) + local v = environment.files[k] + if v then + return (gsub(v,"%.+$","")) + end + end, + __newindex = function(t,k) + -- nothing + end, + __len = function(t) + return #environment.files + end, +} ) diff --git a/tex/context/base/mkiv/luat-fio.lua b/tex/context/base/mkiv/luat-fio.lua index 806caefe6..2996ae66a 100644 --- a/tex/context/base/mkiv/luat-fio.lua +++ b/tex/context/base/mkiv/luat-fio.lua @@ -70,12 +70,16 @@ if not resolvers.initialized() then return okay or "" end + resolvers.findpk = findpk + -- register('process_jobname' , function(name) return name end, true) register('find_read_file' , function(id,name) return findtexfile(name) end, true) register('open_read_file' , function( name) return opentexfile(name) end, true) register('find_data_file' , function(name) return findbinfile(name,"tex") end, true) + register('open_data_file' , function(name) return opentexfile(name) end, true) + register('find_enc_file' , function(name) return findbinfile(name,"enc") end, true) register('find_font_file' , function(name) return findbinfile(name,"tfm") end, true) -- register('find_format_file' , function(name) return findbinfile(name,"fmt") end, true) diff --git a/tex/context/base/mkiv/luat-fmt.lua b/tex/context/base/mkiv/luat-fmt.lua index 30c55eecc..1c9222d95 100644 --- a/tex/context/base/mkiv/luat-fmt.lua +++ b/tex/context/base/mkiv/luat-fmt.lua @@ -19,9 +19,9 @@ local function primaryflags() if arguments.silent then flags[#flags+1] = "--interaction=batchmode" end - if arguments.jit then - flags[#flags+1] = "--jiton" - end + -- if arguments.jit then + -- flags[#flags+1] = "--jiton" + -- end return concat(flags," ") end @@ -48,10 +48,16 @@ local function secondaryflags() if arguments.ansi then flags[#flags+1] = "--c:ansi" end + if arguments.strip then + flags[#flags+1] = "--c:strip" + end + if arguments.lmtx then + flags[#flags+1] = "--c:lmtx" + end return concat(flags," ") end --- The silent option is Taco. It's a bit of a hack because we cannot yet mess +-- The silent option is for Taco. It's a bit of a hack because we cannot yet mess -- with directives. In fact, I could probably clean up the maker a bit by now. local template = [[--ini %primaryflags% --lua=%luafile% %texfile% %secondaryflags% %dump% %redirect%]] diff --git a/tex/context/base/mkiv/luat-ini.lua b/tex/context/base/mkiv/luat-ini.lua index de7254922..ffd402c77 100644 --- a/tex/context/base/mkiv/luat-ini.lua +++ b/tex/context/base/mkiv/luat-ini.lua @@ -25,15 +25,19 @@ if not global then global = _G end -LUATEXVERSION = status.luatex_version/100 - + tonumber(status.luatex_revision)/1000 +LUATEXVERSION = status.luatex_version/100 + + tonumber(status.luatex_revision)/1000 -LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) - or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex") +LUATEXENGINE = status.luatex_engine and string.lower(status.luatex_engine) + or (string.find(status.banner,"LuajitTeX",1,true) and "luajittex" or "luatex") -JITSUPPORTED = LUATEXENGINE == "luajittex" or jit +LUATEXFUNCTIONALITY = status.development_id or 6346 -INITEXMODE = status.ini_version +JITSUPPORTED = LUATEXENGINE == "luajittex" or jit + +INITEXMODE = status.ini_version + +CONTEXTLMTXMODE = CONTEXTLMTXMODE or (status.obj_ptr == nil and 2 or 1) function os.setlocale() -- no need for a message diff --git a/tex/context/base/mkiv/luat-ini.mkiv b/tex/context/base/mkiv/luat-ini.mkiv index 872d27e77..da5a3a310 100644 --- a/tex/context/base/mkiv/luat-ini.mkiv +++ b/tex/context/base/mkiv/luat-ini.mkiv @@ -265,55 +265,84 @@ % \def\syst_helpers_checked_stripped_csname#1% % {\if\noexpand#1\letterbackslash\else#1\fi} -\normalprotected\def\installctxfunction#1#2% expandable - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax - \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\installctxscanner#1#2% expandable - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax - \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\installprotectedctxfunction#1#2% protected - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax - \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\installprotectedctxscanner#1#2% protected - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax - \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} - -% not yet used - -\ifdefined\luafunctioncall \else - \protected\def\luafunctioncall{\luafunctioncall} -\fi +\ifdefined\normalluadef + + \normalprotected\def\installctxfunction#1#2% expandable + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax} + + \normalprotected\def\installctxscanner#1#2% expandable + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax} + + \normalprotected\def\installprotectedctxfunction#1#2% protected + {\edef\m_syst_name{\csstring#1}% + \global\normalprotected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax} + + \normalprotected\def\installprotectedctxscanner#1#2% protected + {\edef\m_syst_name{\csstring#1}% + \global\normalprotected\expandafter\normalluadef\csname\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax} + + \normalprotected\def\resetctxscanner#1% + {\edef\m_syst_name{\csstring#1}% + \expandafter\glet\csname\m_syst_name\endcsname\relax} + + % \let\installctxfunctioncall \installctxfunction + % \let\installctxscannercall \installctxscanner + % \let\installprotectedctxfunctioncall\installprotectedctxfunction + % \let\installprotectedctxscannercall \installprotectedctxscanner + +\else + + \ifdefined\luafunctioncall \else + \normalprotected\def\luafunctioncall{\luafunction} + \fi + + \normalprotected\def\installctxfunction#1#2% expandable + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax + \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} + + \normalprotected\def\installctxscanner#1#2% expandable + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax + \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunction\csname\??luafunction\m_syst_name\endcsname}} + + \normalprotected\def\installprotectedctxfunction#1#2% protected + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax + \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} + + \normalprotected\def\installprotectedctxscanner#1#2% protected + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax + \expandafter\xdef\csname\m_syst_name\endcsname{\noexpand\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} + + \normalprotected\def\resetctxscanner#1% + {\edef\m_syst_name{\csstring#1}% + \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\zerocount + \expandafter\glet\csname\m_syst_name\endcsname\relax} + + % \normalprotected\def\installctxfunctioncall#1#2% + % {\edef\m_syst_name{\csstring#1}% + % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax + % \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} + % + % \normalprotected\def\installctxscannercall#1#2% + % {\edef\m_syst_name{\csstring#1}% + % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax + % \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} + % + % \normalprotected\def\installprotectedctxfunctioncall#1#2% + % {\edef\m_syst_name{\csstring#1}% + % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax + % \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} + % + % \normalprotected\def\installprotectedctxscannercall#1#2% + % {\edef\m_syst_name{\csstring#1}% + % \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax + % \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} -\normalprotected\def\installctxfunctioncall#1#2% - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax - \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\installctxscannercall#1#2% - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax - \expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\installprotectedctxfunctioncall#1#2% - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxfunction("#2",true)}\relax - \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\installprotectedctxscannercall#1#2% - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\ctxcommand{ctxscanner("\m_syst_name","#2",true)}\relax - \normalprotected\expandafter\xdef\csname\m_syst_name\endcsname{\luafunctioncall\csname\??luafunction\m_syst_name\endcsname}} - -\normalprotected\def\resetctxscanner#1% - {\edef\m_syst_name{\csstring#1}% - \global\expandafter\chardef\csname\??luafunction\m_syst_name\endcsname\zerocount - \global\expandafter\let\csname\m_syst_name\endcsname\relax} +\fi \protect \endinput diff --git a/tex/context/base/mkiv/luat-lib.mkiv b/tex/context/base/mkiv/luat-lib.mkiv index 0df31a4e5..d5f6099ca 100644 --- a/tex/context/base/mkiv/luat-lib.mkiv +++ b/tex/context/base/mkiv/luat-lib.mkiv @@ -19,7 +19,7 @@ \registerctxluafile{util-sac}{optimize} \registerctxluafile{util-sto}{} % could also be done in trac-deb.mkiv \registerctxluafile{util-pck}{} -\registerctxluafile{util-seq}{} +% \registerctxluafile{util-seq}{} %registerctxluafile{util-mrg}{} % not needed in context itself, only mtxrun %registerctxluafile{util-lua}{} % moved \registerctxluafile{util-prs}{} @@ -35,11 +35,25 @@ \registerctxluafile{util-deb}{} % could also be done in trac-deb.mkiv \registerctxluafile{util-tpl}{} % needs tracker +\registerctxluafile{util-seq}{} \registerctxluafile{util-sta}{} \registerctxluafile{util-sbx}{} % needs tracker and templates +\registerctxluafile{util-soc-imp-reset} {} +\registerctxluafile{util-soc-imp-socket} {} +%registerctxluafile{util-soc-imp-copas} {} +\registerctxluafile{util-soc-imp-ltn12} {} +%registerctxluafile{util-soc-imp-mbox} {} +\registerctxluafile{util-soc-imp-mime} {} +\registerctxluafile{util-soc-imp-url} {} +\registerctxluafile{util-soc-imp-headers}{} +\registerctxluafile{util-soc-imp-http} {} +\registerctxluafile{util-soc-imp-tp} {} +%registerctxluafile{util-soc-imp-ftp} {} +%registerctxluafile{util-soc-imp-smtp} {} + \registerctxluafile{data-ini}{} \registerctxluafile{data-exp}{} \registerctxluafile{data-env}{} diff --git a/tex/context/base/mkiv/luat-run.lua b/tex/context/base/mkiv/luat-run.lua index 59fb0b937..98f981777 100644 --- a/tex/context/base/mkiv/luat-run.lua +++ b/tex/context/base/mkiv/luat-run.lua @@ -115,6 +115,29 @@ local function wrapup_synctex() synctex.wrapup() end +-- For Taco ... + +local sequencers = utilities.sequencers +local appendgroup = sequencers.appendgroup +local appendaction = sequencers.appendaction +local wrapupactions = sequencers.new { } + +appendgroup(wrapupactions,"system") +appendgroup(wrapupactions,"user") + +local function wrapup_run() + local runner = wrapupactions.runner + if runner then + runner() + end +end + +function luatex.wrapup(action) + appendaction(wrapupactions,"user",action) +end + +appendaction(wrapupactions,"system",synctex.wrapup) + -- this can be done later callbacks.register('start_run', start_run, "actions performed at the beginning of a run") @@ -126,20 +149,26 @@ callbacks.register('stop_run', stop_run, "actions perf callbacks.register('report_output_pages', report_output_pages, "actions performed when reporting pages") callbacks.register('report_output_log', report_output_log, "actions performed when reporting log file") -callbacks.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout") -callbacks.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout") +---------.register('start_page_number', start_shipout_page, "actions performed at the beginning of a shipout") +---------.register('stop_page_number', stop_shipout_page, "actions performed at the end of a shipout") + +callbacks.register('start_page_number', function() end, "actions performed at the beginning of a shipout") +callbacks.register('stop_page_number', function() end, "actions performed at the end of a shipout") callbacks.register('process_input_buffer', false, "actions performed when reading data") callbacks.register('process_output_buffer', false, "actions performed when writing data") callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format") -- comes after \everydump -if LUATEXFUNCTIONALITY and LUATEXFUNCTIONALITY > 6505 then - callbacks.register("finish_synctex", wrapup_synctex, "rename temporary synctex file") - callbacks.register('wrapup_run', false, "actions performed after closing files") -else - callbacks.register("finish_synctex_callback", wrapup_synctex, "rename temporary synctex file") -end +-- finish_synctex might go away (move to wrapup_run) + +callbacks.register("finish_synctex", wrapup_synctex, "rename temporary synctex file") +callbacks.register('wrapup_run', wrapup_run, "actions performed after closing files") + +-- temp hack for testing: + +callbacks.functions.start_page_number = start_shipout_page +callbacks.functions.stop_page_number = stop_shipout_page -- an example: @@ -176,14 +205,6 @@ luatex.registerstopactions(luatex.cleanuptempfiles) -- filenames -local types = { - "data", - "font map", - "image", - "font subset", - "full font", -} - local report_open = logs.reporter("open source") local report_close = logs.reporter("close source") local report_load = logs.reporter("load resource") @@ -199,15 +220,8 @@ function luatex.currentfile() return stack[#stack] or tex.jobname end -local function report_start(left,name) - if not left then - -- skip - elseif left ~= 1 then - if all then - -- report_load("%s > %s",types[left],name or "?") - report_load("type %a, name %a",types[left],name or "?") - end - elseif find(name,"virtual://",1,true) then +local function report_start(name) + if find(name,"virtual://",1,true) then insert(stack,false) else insert(stack,name) @@ -219,16 +233,47 @@ local function report_start(left,name) end end -local function report_stop(right) - if level == 1 or not right or right == 1 then - local name = remove(stack) - if name then - -- report_close("%i > %i > %s",level,total,name or "?") - report_close("level %i, order %i, name %a",level,total,name or "?") - level = level - 1 - synctex.setfilename(stack[#stack] or tex.jobname) +local function report_stop() + local name = remove(stack) + if name then + -- report_close("%i > %i > %s",level,total,name or "?") + report_close("level %i, order %i, name %a",level,total,name or "?") + level = level - 1 + synctex.setfilename(stack[#stack] or tex.jobname) + end +end + +if CONTEXTLMTXMODE < 2 then + + local types = { + "data", + "font map", + "image", + "font subset", + "full font", + } + + local do_report_start = report_start + local do_report_stop = report_stop + + report_start = function(left,name) + if not left then + -- skip + elseif left ~= 1 then + if all then + report_load("type %a, name %a",types[left],name or "?") + end + else + do_report_start(name) + end + end + + report_stop = function(right) + if level == 1 or not right or right == 1 then + do_report_stop() end end + end local function report_none() diff --git a/tex/context/base/mkiv/luat-soc.lua b/tex/context/base/mkiv/luat-soc.lua deleted file mode 100644 index 9342a4b33..000000000 --- a/tex/context/base/mkiv/luat-soc.lua +++ /dev/null @@ -1,11 +0,0 @@ --- This is just a loader. The package handler knows about the TEX tree. - --- require "luatex/lua/socket.lua" --- require "luatex/lua/ltn12.lua" --- require "luatex/lua/mime.lua" --- require "luatex/lua/socket/http.lua" --- require "luatex/lua/socket/url.lua" --- require "luatex/lua/socket/tp.lua" --- require "luatex/lua/socket/ftp.lua" - --- "luatex/lua/socket/smtp.lua" diff --git a/tex/context/base/mkiv/luat-soc.mkiv b/tex/context/base/mkiv/luat-soc.mkiv new file mode 100644 index 000000000..b2ce70483 --- /dev/null +++ b/tex/context/base/mkiv/luat-soc.mkiv @@ -0,0 +1,52 @@ +%D \module +%D [ file=luat-soc, +%D version=2018.08.05, +%D title=\CONTEXT\ Lua Macros, +%D subtitle=Socket Libraries, +%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 Lua Macros / Socket Libraries} + +%D In \LUATEX\ we provide the socket library that is more or less the standard one +%D for \LUA. It has been around for a while and seems to be pretty stable. The +%D binary module is copmpiled into \LUATEX\ and the accompanying .lua files are +%D preloaded. These files are mostly written by Diego Nehab, Andre Carregal, Javier +%D Guerra, and Fabio Mascarenhas with contributions from Diego Nehab, Mike Pall, +%D David Burgess, Leonardo Godinho, Thomas Harning Jr., and Gary NG. The originals +%D are part of and copyrighted by the Kepler project. +%D +%D Here we reload a slightly reworked version of these \type {.lua} files. We keep +%D the same (documented) interface but streamlined some fo the code. No more +%D modules, no more pre 5.2 \LUA, etc. Also, as it loads into the \CONTEXT +%D ecosystem, we plug in some logging. (and maybe tracing in the future). As we +%D don't support serial ports in \LUATEX, related code has been dropped. +%D +%D The files are reformatted so that we can more easilly add additional features +%D and|/|or tracing options. Any error introduced there is our fault! The url module +%D might be replaced by the one in \CONTEXT. When we need mbox a suitable variant +%D will be provided. + +%D Currently we preload the related \LUA\ code in \LUATEX, but that might change at +%D some point. We're prepared for that. + +% \registerctxluafile{util-soc-imp-reset} {} +% +% \registerctxluafile{util-soc-imp-socket} {} +% % registerctxluafile{util-soc-imp-copas} {} +% \registerctxluafile{util-soc-imp-ltn12} {} +% % registerctxluafile{util-soc-imp-mbox} {} +% \registerctxluafile{util-soc-imp-mime} {} +% \registerctxluafile{util-soc-imp-url} {} +% \registerctxluafile{util-soc-imp-headers}{} +% \registerctxluafile{util-soc-imp-http} {} +% \registerctxluafile{util-soc-imp-tp} {} +% % registerctxluafile{util-soc-imp-ftp} {} +% % registerctxluafile{util-soc-imp-smtp} {} + +\endinput diff --git a/tex/context/base/mkiv/luat-sto.lua b/tex/context/base/mkiv/luat-sto.lua index e67830b0d..ce891765a 100644 --- a/tex/context/base/mkiv/luat-sto.lua +++ b/tex/context/base/mkiv/luat-sto.lua @@ -78,7 +78,7 @@ if environment.initex then dumped = concat({ definition, comment, dumped },"\n") local code = nil local name = formatters["slot %s (%s)"](max,name) - if LUAVERSION >= 5.3 and LUATEXFUNCTIONALITY >= 6454 then + if LUAVERSION >= 5.3 then local code = loadstring(dumped,name) setbytecode(max,code,strip) else diff --git a/tex/context/base/mkiv/luat-usr.lua b/tex/context/base/mkiv/luat-usr.lua index ebcb0f0e8..b49379bbf 100644 --- a/tex/context/base/mkiv/luat-usr.lua +++ b/tex/context/base/mkiv/luat-usr.lua @@ -26,8 +26,6 @@ local io = io local os = os local lpeg = lpeg -local luanames = lua.name -- luatex itself - local setmetatableindex = table.setmetatableindex local load = load local xpcall = xpcall @@ -135,7 +133,6 @@ local function registername(name,message) messages[lnn] = message numbers[name] = lnn end - luanames[lnn] = instance_banner(message) local report = reporter("lua instance",message) local proxy = { -- we can access all via: diff --git a/tex/context/base/mkiv/luat-usr.mkiv b/tex/context/base/mkiv/luat-usr.mkiv index 760de9f21..f3868ccf4 100644 --- a/tex/context/base/mkiv/luat-usr.mkiv +++ b/tex/context/base/mkiv/luat-usr.mkiv @@ -69,7 +69,7 @@ \obeyluatokens \csname\??luacode#1\endcsname}% % - \global\expandafter\let\csname\s!stop#1\s!code\endcsname\relax + \expandafter\glet\csname\s!stop#1\s!code\endcsname\relax % \normalexpanded{\xdef\csname\??luacode#1\endcsname##1\csname\s!stop#1\s!code\endcsname}% {\noexpand\expandafter\endgroup @@ -77,7 +77,7 @@ \expandafter\noexpand\csname clf_\fullname\endcsname \noexpand\expandafter{\noexpand\normalexpanded{##1}}}% % - \global\expandafter\let\csname#1\s!code\expandafter\endcsname\csname clf_\fullname\endcsname + \expandafter\glet\csname#1\s!code\expandafter\endcsname\csname clf_\fullname\endcsname \fi \fi \egroup} diff --git a/tex/context/base/mkiv/lxml-aux.lua b/tex/context/base/mkiv/lxml-aux.lua index 78cf1d6bd..ed0f03fd8 100644 --- a/tex/context/base/mkiv/lxml-aux.lua +++ b/tex/context/base/mkiv/lxml-aux.lua @@ -134,10 +134,12 @@ end function xml.collect_tags(root, pattern, nonamespace) local collected = xmlapplylpath(root,pattern) if collected then - local t, n = { }, 0 + local t = { } + local n = 0 for c=1,#collected do - local e = collected[c] - local ns, tg = e.ns, e.tg + local e = collected[c] + local ns = e.ns + local tg = e.tg n = n + 1 if nonamespace then t[n] = tg @@ -226,7 +228,7 @@ function xml.delete(root,pattern) if trace_manipulations then report('deleting',pattern,c,e) end - local d = p.dt + local d = p.dt local ni = e.ni if ni <= #d then if false then @@ -313,8 +315,10 @@ local function inject_element(root,pattern,whatever,prepend) local element = root and xmltoelement(whatever,root) local collected = element and xmlapplylpath(root,pattern) local function inject_e(e) - local r = e.__p__ - local d, k, rri = r.dt, e.ni, r.ri + local r = e.__p__ + local d = r.dt + local k = e.ni + local rri = r.ri local edt = (rri and d[rri].dt) or (d and d[k] and d[k].dt) if edt then local be, af @@ -354,7 +358,8 @@ local function insert_element(root,pattern,whatever,before) -- todo: element als local collected = element and xmlapplylpath(root,pattern) local function insert_e(e) local r = e.__p__ - local d, k = r.dt, e.ni + local d = r.dt + local k = e.ni if not before then k = k + 1 end @@ -860,8 +865,10 @@ function xml.separate(x,pattern) report_xml("warning: xml.separate changes root") x = d end - local t, n = { "\n" }, 1 - local i, nd = 1, #d + local t = { "\n" } + local n = 1 + local i = 1 + local nd = #d while i <= nd do while i <= nd do local di = d[i] diff --git a/tex/context/base/mkiv/lxml-css.lua b/tex/context/base/mkiv/lxml-css.lua index 1787c53df..b0f5c9b72 100644 --- a/tex/context/base/mkiv/lxml-css.lua +++ b/tex/context/base/mkiv/lxml-css.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['lxml-css'] = { license = "see context related readme files" } -local tonumber, rawset, type = tonumber, rawset, type +local tonumber, rawset, type, select = tonumber, rawset, type, select local lower, format, find, gmatch = string.lower, string.format, string.find, string.gmatch local topattern, is_empty = string.topattern, string.is_empty local P, S, C, R, Cb, Cg, Carg, Ct, Cc, Cf, Cs = lpeg.P, lpeg.S, lpeg.C, lpeg.R, lpeg.Cb, lpeg.Cg, lpeg.Carg, lpeg.Ct, lpeg.Cc, lpeg.Cf, lpeg.Cs @@ -118,24 +118,33 @@ css.padding = padding -- print(padding("0",pixel,hsize,exheight,emwidth)) --- local currentfont = font.current --- local texget = tex.get --- local hashes = fonts.hashes --- local quads = hashes.quads --- local xheights = hashes.xheights --- --- local function padding(str) --- local font = currentfont() --- local exheight = xheights[font] --- local emwidth = quads[font] --- local hsize = texget("hsize")/100 --- local pixel = emwidth/100 --- return padding(str,pixel,hsize,exheight,emwidth) --- end --- --- function css.simplepadding(str) --- context("%ssp",padding(str,pixel,hsize,exheight,emwidth)) --- end +local context = context + +if context then + + local currentfont = font.current + local texget = tex.get + local hashes = fonts.hashes + local quads = hashes.quads + local xheights = hashes.xheights + + local function todimension(str) + local font = currentfont() + local exheight = xheights[font] + local emwidth = quads[font] + local hsize = texget("hsize")/100 + local pixel = emwidth/100 + return dimension(str,pixel,hsize,exheight,emwidth) + end + + css.todimension = todimension + + function context.cssdimension(str) + -- context("%ssp",todimension(str)) + context(todimension(str) .. "sp") + end + +end local pattern = Cf( Ct("") * ( Cg( @@ -949,7 +958,7 @@ local someaction = skipspace * colon * skipspace * (somevalue/ctx_sprint) -- -- cache patterns (2.13): -local patterns= setmetatableindex(function(t,k) +local patterns = setmetatableindex(function(t,k) local v = P(k * someaction + 1)^0 t[k] = v return v @@ -993,3 +1002,91 @@ interfaces.implement { actions = css.mappedstylevalue, arguments = "3 strings", } + +-- more (for mm) + +local containsws = string.containsws +local classsplitter = lpeg.tsplitat(whitespace^1) + +function xml.functions.classes(e,class) -- cache + if class then + local at = e.at + local data = at[class] or at.class + if data then + return lpegmatch(classsplitter,data) or { } + end + end + return { } +end + +-- function xml.functions.hasclass(e,class,name) +-- if class then +-- local at = e.at +-- local data = at[class] or at.class +-- if data then +-- return data == name or containsws(data,name) +-- end +-- end +-- return false +-- end +-- +-- function xml.expressions.hasclass(attribute,name) +-- if attribute then +-- return attribute == name or containsws(attribute,name) +-- end +-- return false +-- end + +function xml.functions.hasclass(e,class,name,more,...) + if class and name then + local at = e.at + local data = at[class] or at.class + if not data or data == "" then + return false + end + if data == name or data == more then + return true + end + if containsws(data,name) then + return true + end + if not more then + return false + end + if containsws(data,more) then + return true + end + for i=1,select("#",...) do + if containsws(data,select(i,...)) then + return true + end + end + end + return false +end + +function xml.expressions.hasclass(data,name,more,...) + if data then + if not data or data == "" then + return false + end + if data == name or data == more then + return true + end + if containsws(data,name) then + return true + end + if not more then + return false + end + if containsws(data,more) then + return true + end + for i=1,select("#",...) do + if containsws(data,select(i,...)) then + return true + end + end + end + return false +end diff --git a/tex/context/base/mkiv/lxml-inf.lua b/tex/context/base/mkiv/lxml-inf.lua index 8d99d6270..6fb64c0fe 100644 --- a/tex/context/base/mkiv/lxml-inf.lua +++ b/tex/context/base/mkiv/lxml-inf.lua @@ -17,7 +17,8 @@ local getid = lxml.getid local status, stack local function get(e,d) - local ns, tg = e.ns, e.tg + local ns = e.ns + local tg = e.tg local name = tg if ns ~= "" then name = ns .. ":" .. tg end stack[d] = name diff --git a/tex/context/base/mkiv/lxml-ini.mkiv b/tex/context/base/mkiv/lxml-ini.mkiv index 7c97ffb2c..5cb4bb22d 100644 --- a/tex/context/base/mkiv/lxml-ini.mkiv +++ b/tex/context/base/mkiv/lxml-ini.mkiv @@ -36,11 +36,11 @@ % for now indirect -\def\xmlconcat #1#2#3{\clf_xmlconcat {#1}{#2}{\detokenize{#3}}} -\def\xmlconcatrange #1#2#3#4#5{\clf_xmlconcatrange {#1}{#2}{#3}{#4}{\detokenize{#5}}} -\def\xmlload #1#2{\clf_xmlload {#1}{#2}{\directxmlparameter\c!compress}} -\def\xmlloadbuffer #1#2{\clf_xmlloadbuffer {#1}{#2}{\directxmlparameter\c!compress}} -\def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!compress}} +\def\xmlconcat #1#2#3{\clf_xmlconcat {#1}{#2}{\detokenize{#3}}} +\def\xmlconcatrange #1#2#3#4#5{\clf_xmlconcatrange{#1}{#2}{#3}{#4}{\detokenize{#5}}} +\def\xmlload #1#2{\clf_xmlload {#1}{#2}{\directxmlparameter\c!compress}} +\def\xmlloadbuffer #1#2{\clf_xmlloadbuffer {#1}{#2}{\directxmlparameter\c!compress}} +\def\xmlloaddata #1#2{\clf_xmlloaddata {#1}{#2}{\directxmlparameter\c!compress}} % aliased @@ -231,6 +231,7 @@ \unexpanded\def\xmlremovedocumentsetup #1#2{\clf_xmlremovesetup {#1}{#2}} \unexpanded\def\xmlresetdocumentsetups #1{\clf_xmlresetsetups {#1}} +\unexpanded\def\xmlflushsetups #1{\clf_xmlflushsetups {#1}{*}{}} % #1 == id where to apply * \unexpanded\def\xmlflushdocumentsetups #1#2{\clf_xmlflushsetups {#1}{*}{#2}} % #1 == id where to apply * and #2 \let\xmlregistersetup \xmlappendsetup @@ -240,7 +241,7 @@ \unexpanded\def\xmlregisteredsetups {\xmlstarttiming - \xmlflushsetups + \xmlflushsetups\xmldocument \xmldefaulttotext\xmldocument % after include \xmlstoptiming} @@ -260,8 +261,8 @@ %xmlpushdocument{#3}% #2{#3}{#4}% \setcatcodetable\notcatcodes - \doifelsenothing{#5} - {\xmlsetup{#3}{xml:process}} + \doifelsenothing{#5}% + {\xmlsetup{#3}{xml:process}}% {\xmlsetup{#3}{#5}}% %xmlpopdocument \endgroup} @@ -326,7 +327,7 @@ \fi \unexpanded\def\stopxmldisplayverbatim {\endofverbatimlines - \stoppacked} + \stoppacked}% \doinitializeverbatim \beginofverbatimlines} @@ -404,7 +405,7 @@ \c!entities=\v!no] % load big entity file \appendtoks - \doif{\directxmlparameter\c!entities}\clf_xmlloadentities + \doif{\directxmlparameter\c!entities}\v!yes\clf_xmlloadentities \to \everysetupxml \def\xmlmapvalue #1#2#3{\setvalue{\??xmlmapvalue#1:#2}{#3}} % keep #3 to grab spaces diff --git a/tex/context/base/mkiv/lxml-lpt.lua b/tex/context/base/mkiv/lxml-lpt.lua index bb6fb4568..392c1a401 100644 --- a/tex/context/base/mkiv/lxml-lpt.lua +++ b/tex/context/base/mkiv/lxml-lpt.lua @@ -157,32 +157,47 @@ apply_axis['root'] = function(list) end apply_axis['self'] = function(list) ---~ local collected = { } ---~ for l=1,#list do ---~ collected[l] = list[l] ---~ end ---~ return collected + -- local collected = { } + -- for l=1,#list do + -- collected[l] = list[l] + -- end + -- return collected return list end apply_axis['child'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] local dt = ll.dt if dt then -- weird that this is needed - local en = 0 - for k=1,#dt do - local dk = dt[k] + local n = #dt + if n == 0 then + ll.en = 0 + elseif n == 1 then + local dk = dt[1] if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh - en = en + 1 - dk.ei = en + dk.ni = 1 -- refresh + dk.ei = 1 + ll.en = 1 end + else + local en = 0 + for k=1,#dt do + local dk = dt[k] + if dk.tg then + c = c + 1 + en = en + 1 + collected[c] = dk + dk.ni = k -- refresh + dk.ei = en + end + end + ll.en = en end - ll.en = en end end return collected @@ -191,25 +206,43 @@ end local function collect(list,collected,c) local dt = list.dt if dt then - local en = 0 - for k=1,#dt do - local dk = dt[k] + local n = #dt + if n == 0 then + list.en = 0 + elseif n == 1 then + local dk = dt[1] if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh - en = en + 1 - dk.ei = en + dk.ni = 1 -- refresh + dk.ei = 1 c = collect(dk,collected,c) + list.en = 1 + else + list.en = 0 end + else + local en = 0 + for k=1,n do + local dk = dt[k] + if dk.tg then + c = c + 1 + en = en + 1 + collected[c] = dk + dk.ni = k -- refresh + dk.ei = en + c = collect(dk,collected,c) + end + end + list.en = en end - list.en = en end return c end apply_axis['descendant'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do c = collect(list[l],collected,c) end @@ -219,24 +252,41 @@ end local function collect(list,collected,c) local dt = list.dt if dt then - local en = 0 - for k=1,#dt do - local dk = dt[k] + local n = #dt + if n == 0 then + list.en = 0 + elseif n == 1 then + local dk = dt[1] if dk.tg then c = c + 1 collected[c] = dk - dk.ni = k -- refresh - en = en + 1 - dk.ei = en + dk.ni = 1 -- refresh + dk.ei = 1 c = collect(dk,collected,c) + list.en = 1 end + else + local en = 0 + for k=1,#dt do + local dk = dt[k] + if dk.tg then + c = c + 1 + en = en + 1 + collected[c] = dk + dk.ni = k -- refresh + dk.ei = en + c = collect(dk,collected,c) + end + end + list.en = en end - list.en = en end return c end + apply_axis['descendant-or-self'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] if ll.special ~= true then -- catch double root @@ -249,7 +299,8 @@ apply_axis['descendant-or-self'] = function(list) end apply_axis['ancestor'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] while ll do @@ -264,7 +315,8 @@ apply_axis['ancestor'] = function(list) end apply_axis['ancestor-or-self'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] c = c + 1 @@ -281,7 +333,8 @@ apply_axis['ancestor-or-self'] = function(list) end apply_axis['parent'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local pl = list[l].__p__ if pl then @@ -301,45 +354,47 @@ apply_axis['namespace'] = function(list) end apply_axis['following'] = function(list) -- incomplete ---~ local collected, c = { }, 0 ---~ for l=1,#list do ---~ local ll = list[l] ---~ local p = ll.__p__ ---~ local d = p.dt ---~ for i=ll.ni+1,#d do ---~ local di = d[i] ---~ if type(di) == "table" then ---~ c = c + 1 ---~ collected[c] = di ---~ break ---~ end ---~ end ---~ end ---~ return collected + -- local collected, c = { }, 0 + -- for l=1,#list do + -- local ll = list[l] + -- local p = ll.__p__ + -- local d = p.dt + -- for i=ll.ni+1,#d do + -- local di = d[i] + -- if type(di) == "table" then + -- c = c + 1 + -- collected[c] = di + -- break + -- end + -- end + -- end + -- return collected return { } end apply_axis['preceding'] = function(list) -- incomplete ---~ local collected, c = { }, 0 ---~ for l=1,#list do ---~ local ll = list[l] ---~ local p = ll.__p__ ---~ local d = p.dt ---~ for i=ll.ni-1,1,-1 do ---~ local di = d[i] ---~ if type(di) == "table" then ---~ c = c + 1 ---~ collected[c] = di ---~ break ---~ end ---~ end ---~ end ---~ return collected + -- local collected = { } + -- local c = 0 + -- for l=1,#list do + -- local ll = list[l] + -- local p = ll.__p__ + -- local d = p.dt + -- for i=ll.ni-1,1,-1 do + -- local di = d[i] + -- if type(di) == "table" then + -- c = c + 1 + -- collected[c] = di + -- break + -- end + -- end + -- end + -- return collected return { } end apply_axis['following-sibling'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] local p = ll.__p__ @@ -356,7 +411,8 @@ apply_axis['following-sibling'] = function(list) end apply_axis['preceding-sibling'] = function(list) - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] local p = ll.__p__ @@ -373,7 +429,8 @@ apply_axis['preceding-sibling'] = function(list) end apply_axis['reverse-sibling'] = function(list) -- reverse preceding - local collected, c = { }, 0 + local collected = { } + local c = 0 for l=1,#list do local ll = list[l] local p = ll.__p__ @@ -400,7 +457,8 @@ local function apply_nodes(list,directive,nodes) -- ... currently ignored local maxn = #nodes if maxn == 3 then --optimized loop - local nns, ntg = nodes[2], nodes[3] + local nns = nodes[2] + local ntg = nodes[3] if not nns and not ntg then -- wildcard if directive then return list @@ -408,40 +466,47 @@ local function apply_nodes(list,directive,nodes) return { } end else - local collected, c, m, p = { }, 0, 0, nil + local collected = { } + local c = 0 + local m = 0 + local p = nil if not nns then -- only check tag for l=1,#list do - local ll = list[l] + local ll = list[l] local ltg = ll.tg if ltg then if directive then if ntg == ltg then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end elseif ntg ~= ltg then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end end end elseif not ntg then -- only check namespace for l=1,#list do - local ll = list[l] + local ll = list[l] local lns = ll.rn or ll.ns if lns then if directive then if lns == nns then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end elseif lns ~= nns then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end end end @@ -454,14 +519,16 @@ local function apply_nodes(list,directive,nodes) local ok = ltg == ntg and lns == nns if directive then if ok then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end elseif not ok then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end end end @@ -469,15 +536,19 @@ local function apply_nodes(list,directive,nodes) return collected end else - local collected, c, m, p = { }, 0, 0, nil + local collected = { } + local c = 0 + local m = 0 + local p = nil for l=1,#list do - local ll = list[l] + local ll = list[l] local ltg = ll.tg if ltg then local lns = ll.rn or ll.ns - local ok = false + local ok = false for n=1,maxn,3 do - local nns, ntg = nodes[n+1], nodes[n+2] + local nns = nodes[n+1] + local ntg = nodes[n+2] ok = (not ntg or ltg == ntg) and (not nns or lns == nns) if ok then break @@ -485,14 +556,16 @@ local function apply_nodes(list,directive,nodes) end if directive then if ok then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end elseif not ok then - local llp = ll.__p__ ; if llp ~= p then p, m = llp, 1 else m = m + 1 end + local llp = ll.__p__ ; if llp ~= p then p = llp ; m = 1 else m = m + 1 end c = c + 1 - collected[c], ll.mi = ll, m + collected[c] = ll + ll.mi = m end end end @@ -503,7 +576,8 @@ end local quit_expression = false local function apply_expression(list,expression,order) - local collected, c = { }, 0 + local collected = { } + local c = 0 quit_expression = false for l=1,#list do local ll = list[l] @@ -900,7 +974,8 @@ local function tagstostring(list) local t = { } for i=1, #list do local li = list[i] - local ns, tg = li.ns, li.tg + local ns = li.ns + local tg = li.tg if not ns or ns == "" then ns = "*" end if not tg or tg == "" then tg = "*" end t[i] = (tg == "@rt@" and "[root]") or format("%s:%s",ns,tg) @@ -1365,7 +1440,8 @@ expressions.name = function(e,n) -- ns + tg if n == 0 then found = type(e) == "table" and e elseif n < 0 then - local d, k = e.__p__.dt, e.ni + local d = e.__p__.dt + local k = e.ni for i=k-1,1,-1 do local di = d[i] if type(di) == "table" then @@ -1378,7 +1454,8 @@ expressions.name = function(e,n) -- ns + tg end end else - local d, k = e.__p__.dt, e.ni + local d = e.__p__.dt + local k = e.ni for i=k+1,#d,1 do local di = d[i] if type(di) == "table" then @@ -1392,7 +1469,8 @@ expressions.name = function(e,n) -- ns + tg end end if found then - local ns, tg = found.rn or found.ns or "", found.tg + local ns = found.rn or found.ns or "" + local tg = found.tg if ns ~= "" then return ns .. ":" .. tg else @@ -1412,7 +1490,8 @@ expressions.tag = function(e,n) -- only tg if n == 0 then found = (type(e) == "table") and e -- seems to fail elseif n < 0 then - local d, k = e.__p__.dt, e.ni + local d = e.__p__.dt + local k = e.ni for i=k-1,1,-1 do local di = d[i] if type(di) == "table" then @@ -1425,7 +1504,8 @@ expressions.tag = function(e,n) -- only tg end end else - local d, k = e.__p__.dt, e.ni + local d = e.__p__.dt + local k = e.ni for i=k+1,#d,1 do local di = d[i] if type(di) == "table" then @@ -1592,8 +1672,8 @@ end -- local w = lpeg.patterns.whitespace -- local p = w^0 * lpeg.Cf(lpeg.Ct("") * lpeg.Cg(lpeg.C((1-w)^1) * lpeg.Cc(true) * w^0)^1,rawset) --- function xml.functions.classes(e) -- cache --- local class = e.at.class +-- function xml.functions.classes(e,class) -- cache +-- class = class and e.at[class] or e.at.class -- if class then -- return lpegmatch(p,class) -- else diff --git a/tex/context/base/mkiv/lxml-tex.lua b/tex/context/base/mkiv/lxml-tex.lua index b8280ba9c..ae3edba56 100644 --- a/tex/context/base/mkiv/lxml-tex.lua +++ b/tex/context/base/mkiv/lxml-tex.lua @@ -92,6 +92,8 @@ local forceraw = false local p_texescape = patterns.texescape +local tokenizedcs = context.tokenizedcs + directives.enable("xml.path.keeplastmatch") -- tex entities @@ -499,13 +501,29 @@ function lxml.checkindex(name) return root and root.index or 0 end -function lxml.withindex(name,n,command) -- will change as name is always there now - local i, p = lpegmatch(splitter,n) - if p then - contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}") - else - contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}") +if tokenizedcs then + + function lxml.withindex(name,n,command) -- will change as name is always there now + local i, p = lpegmatch(splitter,n) + local w = tokenizedcs.xmlw + if p then + contextsprint(ctxcatcodes,w,"{",command,"}{",n,"}") + else + contextsprint(ctxcatcodes,w,"{",command,"}{",name,"::",n,"}") + end + end + +else + + function lxml.withindex(name,n,command) -- will change as name is always there now + local i, p = lpegmatch(splitter,n) + if p then + contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",n,"}") + else + contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",name,"::",n,"}") + end end + end function lxml.getindex(name,n) -- will change as name is always there now @@ -728,21 +746,6 @@ end local default_element_handler = xml.gethandlers("verbose").functions["@el@"] --- local xmlw = setmetatableindex(function(t,k) --- local v = setmetatableindex(function(t,kk) --- local v --- if kk == false then --- v = "\\xmlw{" .. k .. "}{" --- else --- v = "\\xmlw{" .. k .. "}{" .. kk .. "::" --- end --- t[kk] = v --- return v --- end) --- t[k]= v --- return v --- end) - local setfilename = false local trace_name = false local report_name = logs.reporter("lxml") @@ -765,39 +768,80 @@ trackers.register("system.synctex.xml",function(v) trace_name = v end) -local function tex_element(e,handlers) - if setfilename then - syncfilename(e,"element") - end - local command = e.command - if command == nil then - default_element_handler(e,handlers) - elseif command == true then - -- text (no ) / so, no mkii fallback then - handlers.serialize(e.dt,handlers) - elseif command == false then - -- ignore - else - local tc = type(command) - if tc == "string" then - local rootname, ix = e.name, e.ix - if rootname then - if not ix then - addindex(rootname,false,true) - ix = e.ix +local tex_element + +if tokenizedcs then + + tex_element = function(e,handlers) + if setfilename then + syncfilename(e,"element") + end + local command = e.command + if command == nil then + default_element_handler(e,handlers) + elseif command == true then + -- text (no ) / so, no mkii fallback then + handlers.serialize(e.dt,handlers) + elseif command == false then + -- ignore + else + local tc = type(command) + if tc == "string" then + local rootname, ix = e.name, e.ix + local w = tokenizedcs.xmlw + if rootname then + if not ix then + addindex(rootname,false,true) + ix = e.ix + end + contextsprint(ctxcatcodes,w,"{",command,"}{",rootname,"::",ix,"}") + else + report_lxml("fatal error: no index for %a",command) + contextsprint(ctxcatcodes,w,"{",command,"}{",ix or 0,"}") end - -- faster than context.xmlw - contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}") - -- contextsprint(ctxcatcodes,xmlw[command][rootname],ix,"}") - else - report_lxml("fatal error: no index for %a",command) - contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}") - -- contextsprint(ctxcatcodes,xmlw[command][false],ix or 0,"}") + elseif tc == "function" then + command(e) + end + end + end + +else + + tex_element = function(e,handlers) + if setfilename then + syncfilename(e,"element") + end + local command = e.command + if command == nil then + default_element_handler(e,handlers) + elseif command == true then + -- text (no ) / so, no mkii fallback then + handlers.serialize(e.dt,handlers) + elseif command == false then + -- ignore + else + local tc = type(command) + if tc == "string" then + local rootname, ix = e.name, e.ix + if rootname then + if not ix then + addindex(rootname,false,true) + ix = e.ix + end + -- faster than context.xmlw + contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",rootname,"::",ix,"}") + -- contextsprint(ctxcatcodes,xmlw[command][rootname],ix,"}") + else + report_lxml("fatal error: no index for %a",command) + contextsprint(ctxcatcodes,"\\xmlw{",command,"}{",ix or 0,"}") + -- contextsprint(ctxcatcodes,xmlw[command][false],ix or 0,"}") + end + elseif tc == "function" then + command(e) end - elseif tc == "function" then - command(e) end end + end -- @@ -1180,7 +1224,7 @@ function lxml.flushsetups(id,...) local sd = setups[document] if sd then for k=1,#sd do - local v= sd[k] + local v = sd[k] if not done[v] then if trace_loading then report_lxml("applying setup %02i : %a to %a",k,v,document) @@ -1442,29 +1486,63 @@ end -- the number of commands is often relative small but there can be many calls -- to this finalizer -local function command(collected,cmd,otherwise) - local n = collected and #collected - if n and n > 0 then - local wildcard = find(cmd,"*",1,true) - for c=1,n do -- maybe optimize for n=1 - local e = collected[c] - local ix = e.ix - local name = e.name - if name and not ix then - addindex(name,false,true) - ix = e.ix - end - if not ix or not name then - report_lxml("no valid node index for element %a using command %s",name or "?",cmd) - elseif wildcard then - contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}") - else - contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",name,"::",ix,"}") +local command + +if tokenizedcs then + + command = function(collected,cmd,otherwise) + local n = collected and #collected + local w = tokenizedcs.xmlw + if n and n > 0 then + local wildcard = find(cmd,"*",1,true) + for c=1,n do -- maybe optimize for n=1 + local e = collected[c] + local ix = e.ix + local name = e.name + if name and not ix then + addindex(name,false,true) + ix = e.ix + end + if not ix or not name then + report_lxml("no valid node index for element %a using command %s",name or "?",cmd) + elseif wildcard then + contextsprint(ctxcatcodes,w,"{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}") + else + contextsprint(ctxcatcodes,w,"{",cmd,"}{",name,"::",ix,"}") + end + end + elseif otherwise then + contextsprint(ctxcatcodes,w,"{",otherwise,"}{#1}") + end + end + +else + + command = function(collected,cmd,otherwise) + local n = collected and #collected + if n and n > 0 then + local wildcard = find(cmd,"*",1,true) + for c=1,n do -- maybe optimize for n=1 + local e = collected[c] + local ix = e.ix + local name = e.name + if name and not ix then + addindex(name,false,true) + ix = e.ix + end + if not ix or not name then + report_lxml("no valid node index for element %a using command %s",name or "?",cmd) + elseif wildcard then + contextsprint(ctxcatcodes,"\\xmlw{",(gsub(cmd,"%*",e.tg)),"}{",name,"::",ix,"}") + else + contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",name,"::",ix,"}") + end end + elseif otherwise then + contextsprint(ctxcatcodes,"\\xmlw{",otherwise,"}{#1}") end - elseif otherwise then - contextsprint(ctxcatcodes,"\\xmlw{",otherwise,"}{#1}") end + end -- local wildcards = setmetatableindex(function(t,k) @@ -1675,7 +1753,7 @@ local function concatrange(collected,start,stop,separator,lastseparator,textonly end end -local function concat(collected,separator,lastseparator,textonly) -- test this on mml +local function concatlist(collected,separator,lastseparator,textonly) -- test this on mml concatrange(collected,false,false,separator,lastseparator,textonly) end @@ -1697,14 +1775,12 @@ texfinalizers.context = ctxtext texfinalizers.position = position texfinalizers.match = match texfinalizers.index = index -texfinalizers.concat = concat +texfinalizers.concat = concatlist texfinalizers.concatrange = concatrange texfinalizers.chainattribute = chainattribute texfinalizers.chainpath = chainpath texfinalizers.default = all -- !! -local concat = table.concat - function texfinalizers.tag(collected,n) if collected then local nc = #collected @@ -1997,7 +2073,7 @@ do implement { name = "xmldoifatt", arguments = "3 strings", - actions = function(id,l,v) + actions = function(id,k,v) local e = getid(id) ctx_doif(e and e.at[k] == v or false) end @@ -2006,7 +2082,7 @@ do implement { name = "xmldoifnotatt", arguments = "3 strings", - actions = function(id,l,v) + actions = function(id,k,v) local e = getid(id) ctx_doifnot(e and e.at[k] == v or false) end @@ -2015,7 +2091,7 @@ do implement { name = "xmldoifelseatt", arguments = "3 strings", - actions = function(id,l,v) + actions = function(id,k,v) local e = getid(id) ctx_doifelse(e and e.at[k] == v or false) end @@ -2139,24 +2215,51 @@ function lxml.direct(id) end end -function lxml.command(id,pattern,cmd) - local i, p = getid(id,true) - local collected = xmlapplylpath(getid(i),pattern) - if collected then - local nc = #collected - if nc > 0 then - local rootname = p or i.name - for c=1,nc do - local e = collected[c] - local ix = e.ix - if not ix then - addindex(rootname,false,true) - ix = e.ix +if tokenizedcs then + + function lxml.command(id,pattern,cmd) + local i, p = getid(id,true) + local collected = xmlapplylpath(getid(i),pattern) + if collected then + local nc = #collected + if nc > 0 then + local rootname = p or i.name + local w = tokenizedcs.xmlw + for c=1,nc do + local e = collected[c] + local ix = e.ix + if not ix then + addindex(rootname,false,true) + ix = e.ix + end + contextsprint(ctxcatcodes,w,"{",cmd,"}{",rootname,"::",ix,"}") + end + end + end + end + +else + + function lxml.command(id,pattern,cmd) + local i, p = getid(id,true) + local collected = xmlapplylpath(getid(i),pattern) + if collected then + local nc = #collected + if nc > 0 then + local rootname = p or i.name + for c=1,nc do + local e = collected[c] + local ix = e.ix + if not ix then + addindex(rootname,false,true) + ix = e.ix + end + contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}") end - contextsprint(ctxcatcodes,"\\xmlw{",cmd,"}{",rootname,"::",ix,"}") end end end + end -- loops @@ -2292,13 +2395,13 @@ function texfinalizers.lettered(collected) end end ---~ function texfinalizers.apply(collected,what) -- to be tested ---~ if collected then ---~ for c=1,#collected do ---~ contextsprint(ctxcatcodes,what(collected[c].dt[1])) ---~ end ---~ end ---~ end +-- function texfinalizers.apply(collected,what) -- to be tested +-- if collected then +-- for c=1,#collected do +-- contextsprint(ctxcatcodes,what(collected[c].dt[1])) +-- end +-- end +-- end function lxml.toparameters(id) local e = getid(id) @@ -2357,49 +2460,56 @@ end -- parameters -function lxml.setatt(id,name,value) - local e = getid(id) - if e then - local a = e.at - if a then - a[name] = value - else - e.at = { [name] = value } +do + + local function setatt(id,name,value) + local e = getid(id) + if e then + local a = e.at + if a then + a[name] = value + else + e.at = { [name] = value } + end end end -end -function lxml.setpar(id,name,value) - local e = getid(id) - if e then - local p = e.pa - if p then - p[name] = value - else - e.pa = { [name] = value } + local function setpar(id,name,value) + local e = getid(id) + if e then + local p = e.pa + if p then + p[name] = value + else + e.pa = { [name] = value } + end end end -end -function lxml.setattribute(id,pattern,name,value) - local collected = xmlapplylpath(getid(id),pattern) - if collected then - for i=1,#collected do - setatt(collected[i],name,value) + lxml.setatt = setatt + lxml.setpar = setpar + + function lxml.setattribute(id,pattern,name,value) + local collected = xmlapplylpath(getid(id),pattern) + if collected then + for i=1,#collected do + setatt(collected[i],name,value) + end end end -end -function lxml.setparameter(id,pattern,name,value) - local collected = xmlapplylpath(getid(id),pattern) - if collected then - for i=1,#collected do - setpar(collected[i],name,value) + function lxml.setparameter(id,pattern,name,value) + local collected = xmlapplylpath(getid(id),pattern) + if collected then + for i=1,#collected do + setpar(collected[i],name,value) + end end end -end -lxml.setparam = lxml.setparameter + lxml.setparam = lxml.setparameter + +end -- relatively new: @@ -2629,3 +2739,59 @@ function texfinalizers.xml(collected,name,setup) buffers.assign(name,strip(xmltostring(root))) context.xmlprocessbuffer(name,name,setup or (name..":setup")) end + +-- experiment + +do + + local xmltoelement = xml.toelement + local xmlreindex = xml.reindex + + function lxml.replace(root,pattern,whatever) + if type(root) == "string" then + root = lxml.getid(root) + end + local collected = xmlapplylpath(root,pattern) + if collected then + local isstring = type(whatever) == "string" + for c=1,#collected do + local e = collected[c] + local p = e.__p__ + if p then + local d = p.dt + local n = e.ni + local w = isstring and whatever or whatever(e) + if w then + local t = xmltoelement(w,root).dt + if t then + t.__p__ = p + if type(t) == "table" then + local t1 = t[1] + d[n] = t1 + t1.at.type = e.at.type or t1.at.type + for i=2,#t do + n = n + 1 + insert(d,n,t[i]) + end + else + d[n] = t + end + xmlreindex(d) -- probably not needed + end + end + end + end + end + end + + -- function document.mess_around(root) + -- lxml.replace( + -- root, + -- "p[@variant='foo']", + -- function(c) + -- return (string.gsub(tostring(c),"foo","%1")) + -- end + -- ) + -- end + +end diff --git a/tex/context/base/mkiv/m-fonts-plugins.mkiv b/tex/context/base/mkiv/m-fonts-plugins.mkiv index b74b8c3d0..154e47804 100644 --- a/tex/context/base/mkiv/m-fonts-plugins.mkiv +++ b/tex/context/base/mkiv/m-fonts-plugins.mkiv @@ -186,6 +186,7 @@ \definefontfeature [arabic-node] [arabic] + [salt=yes] % seems to be needed for husayni \definefontfeature [arabic-native] @@ -224,7 +225,7 @@ \getbuffer[#5-definitions] \showfontkerns \showmakeup[discretionary] - \enabletrackers[fonts.plugins.hb.colors]% + % \enabletrackers[fonts.plugins.hb.colors]% \testfeatureonce{1}{ \getbuffer[#5-text] } @@ -263,7 +264,7 @@ \title{#1 #3 #4} \start \getbuffer[#5-definitions] - \enabletrackers[fonts.plugins.hb.colors]% + % \enabletrackers[fonts.plugins.hb.colors]% \testfeatureonce{1}{ \setupalign[flushleft] % easier to compare \getbuffer[#5-text] diff --git a/tex/context/base/mkiv/math-act.lua b/tex/context/base/mkiv/math-act.lua index 77a355b22..07ef32746 100644 --- a/tex/context/base/mkiv/math-act.lua +++ b/tex/context/base/mkiv/math-act.lua @@ -23,6 +23,12 @@ local mathematics = mathematics local texsetdimen = tex.setdimen local abs = math.abs +local helpers = fonts.helpers +local upcommand = helpers.commands.up +local rightcommand = helpers.commands.right +local charcommand = helpers.commands.char +local prependcommands = helpers.prependcommands + local sequencers = utilities.sequencers local appendgroup = sequencers.appendgroup local appendaction = sequencers.appendaction @@ -237,7 +243,6 @@ function mathematics.overloaddimensions(target,original,set) local factor = parameters.factor local hfactor = parameters.hfactor local vfactor = parameters.vfactor - local addprivate = fonts.helpers.addprivate -- to be sure target.type = "virtual" target.properties.virtualized = true @@ -257,7 +262,8 @@ function mathematics.overloaddimensions(target,original,set) local height = data.height local depth = data.depth if trace_defining and (width or height or depth) then - report_math("overloading dimensions of %C, width %a, height %a, depth %a",unicode,width,height,depth) + report_math("overloading dimensions of %C, width %p, height %p, depth %p", + unicode,width or 0,height or 0,depth or 0) end if width then character.width = width * hfactor end if height then character.height = height * vfactor end @@ -270,25 +276,26 @@ function mathematics.overloaddimensions(target,original,set) if d then xoffset = - d.boundingbox[1] * hfactor character.width = character.width + xoffset - xoffset = { "right", xoffset } + xoffset = rightcommand[xoffset] + else + xoffset = nil end - elseif xoffset then - xoffset = { "right", xoffset * hfactor } + elseif xoffset and xoffset ~= 0 then + xoffset = rightcommand[xoffset * hfactor] + else + xoffset = nil end - if yoffset then - yoffset = { "down", -yoffset * vfactor } + if yoffset and yoffset ~= 0 then + yoffset = upcommand[yoffset * vfactor] + else + yoffset = nil end if xoffset or yoffset then - if character.commands then - if yoffset then - insert(character.commands,1,yoffset) - end - if xoffset then - insert(character.commands,1,xoffset) - end + local commands = characters.commands + if commands then + prependcommands(commands,yoffset,xoffset) else - -- local slot = { "slot", 1, addprivate(target,nil,fastcopy(character)) } - local slot = { "slot", 0, addprivate(target,nil,fastcopy(character)) } + local slot = charcommand[unicode] if xoffset and yoffset then character.commands = { xoffset, yoffset, slot } elseif xoffset then @@ -297,7 +304,6 @@ function mathematics.overloaddimensions(target,original,set) character.commands = { yoffset, slot } end end - character.index = nil end elseif trace_defining then report_math("no overloading dimensions of %C, not in font",unicode) @@ -732,9 +738,9 @@ function mathematics.finishfallbacks(target,specification,fallbacks) done[unic] = true end end + local step = offset - start for unicode = start, stop do - local unic = unicode + offset - start - remap(unic,unicode,false) + remap(unicode + step,unicode,false) end if gaps then for unic, unicode in next, gaps do diff --git a/tex/context/base/mkiv/math-ali.mkiv b/tex/context/base/mkiv/math-ali.mkiv index 083fb7645..ecfac6887 100644 --- a/tex/context/base/mkiv/math-ali.mkiv +++ b/tex/context/base/mkiv/math-ali.mkiv @@ -321,11 +321,18 @@ \def\math_alignment_EQ {\NC=} +\installmacrostack\NC % maybe more to shared table definitions +\installmacrostack\NN % maybe more to shared table definitions +\installmacrostack\EQ % maybe more to shared table definitions +\installmacrostack\NR % maybe more to shared table definitions +\installmacrostack\BC % maybe more to shared table definitions +\installmacrostack\EC % maybe more to shared table definitions + \appendtoks - \pushmacro\NC - \pushmacro\NN - \pushmacro\EQ - \pushmacro\NR + \push_macro_NC + \push_macro_NN + \push_macro_EQ + \push_macro_NR \let\NC\math_alignment_NC \let\NN\math_alignment_NN \let\EQ\math_alignment_EQ @@ -334,10 +341,10 @@ \to \everymathalignment \appendtoks - \popmacro\NR - \popmacro\EQ - \popmacro\NN - \popmacro\NC + \pop_macro_NR + \pop_macro_EQ + \pop_macro_NN + \pop_macro_NC \to \everymathalignmentdone \let\math_alignment_snap_start\relax @@ -694,11 +701,11 @@ {\unskip \math_cases_end_math \aligntab - \global\let\math_cases_NC\math_cases_NC_first + \glet\math_cases_NC\math_cases_NC_first \dodirectdoubleempty\math_cases_NR} \def\math_cases_NC_first - {\global\let\math_cases_NC\math_cases_NC_second} + {\glet\math_cases_NC\math_cases_NC_second} \def\math_cases_NC_second {\math_cases_end_math\aligntab} @@ -722,7 +729,7 @@ \let\NC\math_cases_NC_zero \let\MC\math_cases_MC_zero \let\NR\math_cases_NR_zero - \global\let\math_cases_NC\math_cases_NC_first + \glet\math_cases_NC\math_cases_NC_first \normalbaselines \mathsurround\zeropoint \everycr\emptytoks diff --git a/tex/context/base/mkiv/math-arr.mkiv b/tex/context/base/mkiv/math-arr.mkiv index a0dda66b9..2edb91465 100644 --- a/tex/context/base/mkiv/math-arr.mkiv +++ b/tex/context/base/mkiv/math-arr.mkiv @@ -67,39 +67,46 @@ \def\math_arrows_construct#1#2#3#4#5% hm, looks like we do a double mathrel (a bit cleaned up .. needs checking) {\begingroup - \def\m_math_arrows_factor{1}% - \def\m_math_arrows_extra {0}% + \let\m_math_arrows_factor\!!plusone + \let\m_math_arrows_extra \!!zerocount \edef\p_math_spacing{#1}% \csname\??matharrowsettings \ifcsname\??matharrowsettings\p_math_spacing\endcsname\p_math_spacing\else\s!unknown\fi \endcsname \mathsurround\zeropoint - \muskip0=\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax - \muskip2=\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax - \setbox0\hbox{\normalstartimath - \scriptstyle - \mkern\muskip0\relax - #5\relax - \mkern\muskip2\relax - \normalstopimath}% - \setbox2\hbox{\normalstartimath - \scriptstyle - \mkern\muskip0\relax - #4\relax - \mkern\muskip2\relax - \normalstopimath}% - \setbox4\hbox{#3\displaystyle}% - \dimen0\wd0\relax - \ifdim\wd2>\dimen0 - \dimen0\wd2\relax + \scratchmuskipone\muexpr\m_math_arrows_factor\muexpr\thirdoffourarguments #2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\firstoffourarguments #2\onemuskip\relax + \scratchmuskiptwo\muexpr\m_math_arrows_factor\muexpr\fourthoffourarguments#2\onemuskip\relax+\m_math_arrows_extra\onemuskip+\secondoffourarguments#2\onemuskip\relax + \setbox\scratchboxone\hbox + {\normalstartimath + \scriptstyle + \mkern\scratchmuskipone\relax + #5\relax + \mkern\scratchmuskiptwo\relax + \normalstopimath}% + \setbox\scratchboxtwo\hbox + {\normalstartimath + \scriptstyle + \mkern\scratchmuskipone\relax + #4\relax + \mkern\scratchmuskiptwo\relax + \normalstopimath}% + \setbox\scratchboxthree\hbox{#3\displaystyle}% + \scratchdimenone\wd\scratchboxone\relax + \ifdim\wd\scratchboxtwo>\scratchdimenone + \scratchdimenone\wd\scratchboxtwo\relax \fi - \ifdim\wd4>\dimen0 - \dimen0\wd4\relax + \ifdim\wd\scratchboxthree>\scratchdimenone + \scratchdimenone\wd\scratchboxthree\relax \fi - \ifdim\wd4=\dimen0\else - \setbox4\hbox to \dimen0{#3\displaystyle}% + \ifdim\wd\scratchboxthree=\scratchdimenone\else + \setbox\scratchboxthree\hbox to \scratchdimenone{#3\displaystyle}% \fi - \mathrel{\mathop{\hbox to \dimen0{\hss\copy4\hss}}\limits\normalsuperscript{\box0}\normalsubscript{\box2}}% pack ? + \mathrel + {\mathop + {\hpack to \scratchdimenone{\hss\box\scratchboxthree\hss}}% pack ? copy ? + \limits + \normalsuperscript{\box\scratchboxone}% + \normalsubscript {\box\scratchboxtwo}}% \endgroup} \let\math_arrows_construct_single\math_arrows_construct diff --git a/tex/context/base/mkiv/math-dim.lua b/tex/context/base/mkiv/math-dim.lua index 72b9d7e50..eb7adb53f 100644 --- a/tex/context/base/mkiv/math-dim.lua +++ b/tex/context/base/mkiv/math-dim.lua @@ -157,7 +157,8 @@ function mathematics.dimensions(dimens) -- beware, dimens get spoiled for variable, styles in next, defaults do local tt = { } for style, default in next, styles do - local one, two = default[1], default[2] + local one = default[1] + local two = default[2] local value = dimens[one] if value then tt[style] = value diff --git a/tex/context/base/mkiv/math-dir.lua b/tex/context/base/mkiv/math-dir.lua index 759f1e797..38aa44358 100644 --- a/tex/context/base/mkiv/math-dir.lua +++ b/tex/context/base/mkiv/math-dir.lua @@ -48,7 +48,9 @@ local vlist_code = nodecodes.vlist local nodepool = nuts.pool -local new_textdir = nodepool.textdir +local new_direction = nodepool.direction + +local lefttoright_code = nodes.dirvalues.lefttoright local chardirections = characters.directions local charmirrors = characters.mirrors @@ -60,16 +62,14 @@ local a_mathbidi = attributes.private('mathbidi') local function processmath(head) local current = head - local done = false local start = nil local stop = nil local function capsulate() - head = insert_node_before(head,start,new_textdir("+TLT")) - insert_node_after(head,stop,new_textdir("-TLT")) + head = insert_node_before(head,start,new_direction(lefttoright_code)) + insert_node_after(head,stop,new_direction(lefttoright_code,true)) if trace_directions then report_directions("reversed: %s",nodes.listtoutf(start,false,false,stop)) end - done = true start = false stop = nil end @@ -100,7 +100,6 @@ local function processmath(head) if trace_directions then report_directions("mirrored: %C to %C",char,mirror) end - done = true end end end @@ -108,11 +107,8 @@ local function processmath(head) elseif not start then -- nothing if id == hlist_code or id == vlist_code then - local list, d = processmath(getlist(current)) + local list = processmath(getlist(current)) setlist(current,list) - if d then - done = true - end end elseif start == stop then start = nil @@ -121,11 +117,8 @@ local function processmath(head) -- math can pack things into hlists .. we need to make sure we don't process -- too often: needs checking if id == hlist_code or id == vlist_code then - local list, d = processmath(getlist(current)) + local list = processmath(getlist(current)) setlist(current,list) - if d then - done = true - end end end current = getnext(current) @@ -137,21 +130,18 @@ local function processmath(head) else capsulate() end - return head, done + return head end local enabled = false function directions.processmath(head) -- style, penalties if enabled then - local h = tonut(head) - local a = getattr(h,a_mathbidi) + local a = getattr(head,a_mathbidi) if a and a > 0 then - local head, done = processmath(h) - return tonode(head), done + return processmath(head) end end - return head, false end function directions.setmath(n) diff --git a/tex/context/base/mkiv/math-ext.lua b/tex/context/base/mkiv/math-ext.lua index a4b865713..b923853f4 100644 --- a/tex/context/base/mkiv/math-ext.lua +++ b/tex/context/base/mkiv/math-ext.lua @@ -7,29 +7,30 @@ if not modules then modules = { } end modules ['math-ext'] = { } local rawget = rawget - -local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end) - local basename = file.basename +local sortedhash = table.sortedhash + +local mathematics = mathematics +local extras = mathematics.extras or { } +mathematics.extras = extras -local mathematics = mathematics -local characters = characters +local characters = characters +local chardata = characters.data +local mathpairs = characters.mathpairs -local report_math = logs.reporter("mathematics") +local trace_virtual = false +local report_math = logs.reporter("mathematics") -mathematics.extras = mathematics.extras or { } -local extras = mathematics.extras +trackers.register("math.virtual", function(v) trace_virtual = v end) -local mathplus = { } -local chardata = characters.data -local mathpairs = characters.mathpairs +local mathplus = { } -- todo: store them and skip storage if already stored -- todo: make a char-ctx.lua (or is this already side effect of save in format) local function addextra(unicode) local min = mathematics.extrabase - local max = mathematics.privatebase - 1 + local max = min + 0xFFF if unicode >= min and unicode <= max then if chardata[unicode] then mathplus[unicode] = true @@ -47,7 +48,7 @@ function extras.copy(target,original) local characters = target.characters local properties = target.properties local parameters = target.parameters - for unicode in table.sortedhash(mathplus) do + for unicode in sortedhash(mathplus) do local extradesc = chardata[unicode] local nextinsize = extradesc.nextinsize if nextinsize then diff --git a/tex/context/base/mkiv/math-fbk.lua b/tex/context/base/mkiv/math-fbk.lua index 7aa8c437f..963461de5 100644 --- a/tex/context/base/mkiv/math-fbk.lua +++ b/tex/context/base/mkiv/math-fbk.lua @@ -20,10 +20,22 @@ local sortedhash = table.sortedhash local fallbacks = { } mathematics.fallbacks = fallbacks +local helpers = fonts.helpers +local prependcommands = helpers.prependcommands +local charcommand = helpers.commands.char +local leftcommand = helpers.commands.left +local rightcommand = helpers.commands.right +local upcommand = helpers.commands.up +local downcommand = helpers.commands.down +local dummycommand = helpers.commands.dummy +local popcommand = helpers.commands.pop +local pushcommand = helpers.commands.push + local virtualcharacters = { } -local identifiers = fonts.hashes.identifiers -local lastmathids = fonts.hashes.lastmathids +local hashes = fonts.hashes +local identifiers = hashes.identifiers +local lastmathids = hashes.lastmathids -- we need a trick (todo): if we define scriptscript, script and text in -- that order we could use their id's .. i.e. we could always add a font @@ -115,6 +127,8 @@ function fallbacks.apply(target,original) } target.mathrelation = data -- + local fullname = trace_fallbacks and target.properties.fullname + -- for k, v in sortedhash(virtualcharacters) do if not characters[k] then local tv = type(v) @@ -132,7 +146,7 @@ function fallbacks.apply(target,original) -- something else end if trace_fallbacks and characters[k] then - report_fallbacks("extending math font %a with %U",target.properties.fullname,k) + report_fallbacks("extending math font %a with %U",fullname,k) end end end @@ -151,22 +165,21 @@ local function reference(index,char) if index then return { "slot", index, char } else - return { "char", char } + return charcommand[char] end end -local function raised(data,down) - local replacement = data.replacement - local character = data.scriptdata.characters[replacement] +local function raised(data,replacement,down) + local character = data.scriptdata.characters[replacement] if character then + local size = data.size return { width = character.width, height = character.height, depth = character.depth, commands = { - { "down", down and data.size/4 or -data.size/2 }, -- maybe exheight + down and downcommand[size/4] or upcommand[size/2], reference(data.scriptindex,replacement) - -- { "slot", data.scriptindex or 0, char } -- hm, data.mathrelation.scriptindex } } end @@ -177,33 +190,18 @@ end -- virtualcharacters[0x208A] = 0x2212 -- virtualcharacters[0x208B] = 0x002B -virtualcharacters[0x207A] = function(data) - data.replacement = 0x002B - return raised(data) -end - -virtualcharacters[0x207B] = function(data) - data.replacement = 0x2212 - return raised(data) -end - -virtualcharacters[0x208A] = function(data) - data.replacement = 0x002B - return raised(data,true) -end - -virtualcharacters[0x208B] = function(data) - data.replacement = 0x2212 - return raised(data,true) -end +virtualcharacters[0x207A] = function(data) return raised(data,0x002B) end +virtualcharacters[0x207B] = function(data) return raised(data,0x2212) end +virtualcharacters[0x208A] = function(data) return raised(data,0x002B,true) end +virtualcharacters[0x208B] = function(data) return raised(data,0x2212,true) end -- local function repeated(data,char,n,fraction) -- local character = data.characters[char] -- if character then -- local width = character.width -- local delta = width - character.italic -- width * fraction --- local c = { "char", char } --- local r = { "right", right } +-- local c = charcommand[char] +-- local r = rightcommand[right] -- local commands = { } -- for i=1,n-1 do -- width = width + delta @@ -234,14 +232,9 @@ addextra(0xFE350) -- MATHEMATICAL DOUBLE ARROW LEFT END addextra(0xFE351) -- MATHEMATICAL DOUBLE ARROW MIDDLE PART addextra(0xFE352) -- MATHEMATICAL DOUBLE ARROW RIGHT END -local push = { "push" } -local pop = { "pop" } -local leftarrow = { "char", 0x2190 } -local relbar = { "char", 0x2212 } -local rightarrow = { "char", 0x2192 } --- local leftarrow = { "slot", 0, 0x2190 } --- local relbar = { "slot", 0, 0x2212 } --- local rightarrow = { "slot", 0, 0x2192 } +local leftarrow = charcommand[0x2190] +local relbar = charcommand[0x2212] +local rightarrow = charcommand[0x2192] virtualcharacters[0xFE350] = function(data) -- return combined(data,0x2190,0x2212) -- leftarrow relbar @@ -254,11 +247,11 @@ virtualcharacters[0xFE350] = function(data) height = size, depth = size, commands = { - push, - { "down", size/2 }, + pushcommand, + downcommand[size/2], leftarrow, - pop, - { "down", -size/2 }, + popcommand, + upcommand[size/2], relbar, } } @@ -275,11 +268,11 @@ virtualcharacters[0xFE351] = function(data) height = size, depth = size, commands = { - push, - { "down", size/2 }, + pushcommand, + downcommand[size/2], relbar, - pop, - { "down", -size/2 }, + popcommand, + upcommand[size/2], relbar, } } @@ -297,12 +290,12 @@ virtualcharacters[0xFE352] = function(data) height = size, depth = size, commands = { - push, - { "down", size/2 }, + pushcommand, + downcommand[size/2], relbar, - pop, - { "right", chartwo.width - charone.width }, - { "down", -size/2 }, + popcommand, + rightcommand[chartwo.width - charone.width], + upcommand[size/2], rightarrow, } } @@ -325,10 +318,12 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s height = height or 0 depth = depth or 0 end - local correction = swap and { "down", (olddata.height or 0) - height } or { "down", olddata.height + (offset or 0)} + local oldheight = olddata.height or 0 + local correction = swap and + downcommand[oldheight - height] + or downcommand[oldheight + (offset or 0)] local newdata = { - commands = { correction, { "slot", 1, oldchr } }, - -- commands = { correction, { "slot", 0, oldchr } }, + commands = { correction, charcommand[oldchr] }, width = olddata.width, height = height, depth = depth, @@ -340,14 +335,12 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s local oldnextdata = characters[nextglyph] if oldnextdata then local newnextdata = { - commands = { correction, { "slot", 1, nextglyph } }, - -- commands = { correction, { "slot", 0, nextglyph } }, + commands = { correction, charcommand[nextglyph] }, width = oldnextdata.width, height = height, depth = depth, } --- local newnextglyph = addprivate(target,formatters["M-N-%H"](nextglyph),newnextdata) - local newnextglyph = addprivate(target,nil,newnextdata) + local newnextglyph = addprivate(target,formatters["M-N-%H"](nextglyph),newnextdata) newdata.next = newnextglyph local nextnextglyph = oldnextdata.next if nextnextglyph == nextglyph then @@ -372,14 +365,12 @@ local function accent_to_extensible(target,newchr,original,oldchr,height,depth,s local olddata = characters[oldglyph] if olddata then local newdata = { - commands = { correction, { "slot", 1, oldglyph } }, - -- commands = { correction, { "slot", 0, oldglyph } }, + commands = { correction, charcommand[oldglyph] }, width = olddata.width, height = height, depth = depth, } --- hvi.glyph = addprivate(target,formatters["M-H-%H"](oldglyph),newdata) - hvi.glyph = addprivate(target,nil,newdata) + hvi.glyph = addprivate(target,formatters["M-H-%H"](oldglyph),newdata) else report_fallbacks("error in fallback: no valid horiz_variants, slot %X, index %i",oldglyph,i) end @@ -393,15 +384,16 @@ end virtualcharacters[0x203E] = function(data) local target = data.target - local height, depth = 0, 0 --- local mathparameters = target.mathparameters --- if mathparameters then --- height = mathparameters.OverbarVerticalGap --- depth = mathparameters.UnderbarVerticalGap --- else + local height = 0 + local depth = 0 + -- local mathparameters = target.mathparameters + -- if mathparameters then + -- height = mathparameters.OverbarVerticalGap + -- depth = mathparameters.UnderbarVerticalGap + -- else height = target.parameters.xheight/4 depth = height --- end + -- end return accent_to_extensible(target,0x203E,data.original,0x0305,height,depth,nil,nil,0x203E) end @@ -431,7 +423,7 @@ local function spacefraction(data,fraction) local width = fraction * data.target.parameters.space return { width = width, - commands = { { "right", width } } + commands = { rightcommand[width] } } end @@ -439,7 +431,7 @@ local function charfraction(data,char) local width = data.target.characters[char].width return { width = width, - commands = { { "right", width } } + commands = { rightcommand[width] } } end @@ -447,7 +439,7 @@ local function quadfraction(data,fraction) local width = fraction * data.target.parameters.quad return { width = width, - commands = { { "right", width } } + commands = { rightcommand[width] } } end @@ -527,9 +519,8 @@ local function smashed(data,unicode,optional) local shift = oldchar.height - height local newchar = { commands = { - { "down", shift }, - { "slot", 0, unicode }, --- { "char", unicode }, + downcommand[shift], + charcommand[unicode], }, height = height, width = oldchar.width, @@ -607,11 +598,11 @@ local function actuarian(data) width = basewidth + 4 * linewidth, unicode = 0x20E7, commands = { - { "right", 2 * linewidth }, - { "down", - baseheight - 3 * linewidth }, + rightcommand[2 * linewidth], + downcommand[- baseheight - 3 * linewidth], { "rule", linewidth, basewidth + 4 * linewidth }, - { "right", -linewidth }, - { "down", baseheight + 4 * linewidth }, + leftcommand[linewidth], + downcommand[baseheight + 4 * linewidth], { "rule", baseheight + 5 * linewidth, linewidth }, }, } @@ -629,11 +620,11 @@ local function equals(data,unicode,snippet,advance,n) -- mathpair needs them unicode = unicode, width = n*basechar.width + (n-1)*advance, commands = { - { "char", snippet }, - { "right", advance }, - { "char", snippet }, - n > 2 and { "right", advance } or nil, - n > 2 and { "char", snippet } or nil, + charcommand[snippet], + rightcommand[advance], + charcommand[snippet], + n > 2 and rightcommand[advance] or nil, + n > 2 and charcommand[snippet] or nil, }, } end @@ -657,11 +648,43 @@ virtualcharacters[0x2980] = function(data) return equals(data,0x2980,0x007C,-1/8 -- height = height, -- we cheat (no time now) -- depth = depth, -- we cheat (no time now) -- commands = { --- { "down", - height/2 }, -- sort of works --- { "char", 0x003D }, --- { "right", -width }, --- { "down", height }, -- sort of works --- { "char", 0x003D }, +-- upcommand[height/2], -- sort of works +-- charcommand[0x003D], +-- leftcommand[width], +-- downcommand[height], -- sort of works +-- charcommand[0x003D], -- }, -- } -- end + +-- lucida needs this + +virtualcharacters[0x305] = function(data) + local target = data.target + local height = target.parameters.xheight/8 + local width = target.parameters.emwidth/2 + local depth = height + local used = 0.8 * width + return { + width = width, + height = height, + depth = depth, + commands = { { "rule", height, width } }, + horiz_variants = { + { + advance = width, + ["end"] = used, + glyph = 0x305, + start = 0, + }, + { + advance = width, + ["end"] = 0, + extender = 1, + glyph = 0x305, + start = used, + }, + } + } +end + diff --git a/tex/context/base/mkiv/math-fen.mkiv b/tex/context/base/mkiv/math-fen.mkiv index a32ea410e..6c6724bf5 100644 --- a/tex/context/base/mkiv/math-fen.mkiv +++ b/tex/context/base/mkiv/math-fen.mkiv @@ -65,14 +65,19 @@ % we need the direct use of \Udelimiter because of { etc -\newconditional\c_math_fenced_mirror \settrue\c_math_fenced_mirror +\newconditional\c_math_fenced_mirror \settrue \c_math_fenced_mirror +\newconditional\c_math_fenced_sized \setfalse\c_math_fenced_sized \unexpanded\def\math_fenced_inject#1#2#3#4% {\ifx#1\empty #2.% \else \edef\p_mathclass{\mathfenceparameter\c!mathclass}% - \edef\p_factor{\mathfenceparameter\c!factor}% + \ifconditional\c_math_fenced_sized + \let\p_factor\v!fixed + \else + \edef\p_factor{\mathfenceparameter\c!factor}% + \fi \ifx\p_factor\empty \ifx\p_mathclass\empty #2% @@ -97,7 +102,11 @@ \s!axis % #2% \else - \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax + \ifx\p_factor\v!fixed + \scratchdimen\scaledpoint + \else + \scratchdimen\dimexpr\p_factor\bodyfontsize/2\relax + \fi #3% \s!height\scratchdimen \s!depth\scratchdimen @@ -121,16 +130,14 @@ \mathfenceparameter\c!left \fi}% \math_fenced_color_push - % \normalleft\ifx\p_left\empty.\else\Udelimiter\plusfour\fam\p_left\relax\fi \math_fenced_inject\p_left\normalleft\Uleft\plusfour \math_fenced_color_pop} \def\math_fenced_middle {\edef\p_middle - {\mathfenceparameter\c!middle}% + {\mathfenceparameter\c!middle}% \mskip\thinmuskip \math_fenced_color_push - % \normalmiddle\ifx\p_middle\empty.\else\Udelimiter\plusfour\fam\p_middle\relax\fi \math_fenced_inject\p_middle\normalmiddle\Umiddle\plusfour \math_fenced_color_pop \mskip\thinmuskip} @@ -147,7 +154,6 @@ \mathfenceparameter\c!right \fi}% \math_fenced_color_push - % \normalright \ifx\p_right\empty.\else\Udelimiter\plusfive\fam\p_right\relax\fi \math_fenced_inject\p_right\normalright\Uright\plusfive \math_fenced_color_pop} @@ -194,16 +200,60 @@ \edef\currentmathfence{#1}% \dosingleempty\math_fenced_fenced_indeed} -\unexpanded\def\math_fenced_fenced_indeed[#1]#2% +\def\math_fenced_force_size#1#2% + {\attribute\mathsizeattribute\numexpr#1*\plushundred+#2\relax} + +% \unexpanded\def\math_fenced_fenced_indeed[#1]#2% +% {\iffirstargument\setupcurrentmathfence[#1]\fi +% \math_fenced_fenced_common +% \edef\p_size{\mathfenceparameter\c!size}% +% \ifx\p_size\empty +% \setfalse\c_math_fenced_sized +% \else +% \settrue\c_math_fenced_sized +% \math_fenced_force_size\bigmathdelimitervariant\p_size +% \fi +% \math_fenced_left +% #2% +% \math_fenced_right +% \stopusemathstyleparameter +% \endgroup +% \advance\c_math_fenced_nesting\minusone} + +\unexpanded\def\math_fenced_fenced_indeed[#1]% {\iffirstargument\setupcurrentmathfence[#1]\fi \math_fenced_fenced_common - \math_fenced_left - #2% - \math_fenced_right - \stopusemathstyleparameter + \edef\p_size{\mathfenceparameter\c!size}% + \ifx\p_size\empty + \expandafter\math_fenced_fenced_indeed_adapt + \else + \expandafter\math_fenced_fenced_indeed_fixed + \fi} + +\unexpanded\def\math_fenced_fenced_indeed_finish + {\stopusemathstyleparameter \endgroup \advance\c_math_fenced_nesting\minusone} +\unexpanded\def\math_fenced_fenced_indeed_fixed#1% + {\math_fenced_force_size\bigmathdelimitervariant\p_size + \settrue\c_math_fenced_sized + \math_fenced_left + \setfalse\c_math_fenced_sized + #1% + \settrue\c_math_fenced_sized + \math_fenced_right + \setfalse\c_math_fenced_sized + \math_fenced_fenced_indeed_finish} + +\unexpanded\def\math_fenced_fenced_indeed_adapt#1% + {\setfalse\c_math_fenced_sized + \math_fenced_left + #1% + \setfalse\c_math_fenced_sized + \math_fenced_right + \math_fenced_fenced_indeed_finish} + \appendtoks \let\fenced\math_fenced_fenced \to \everymathematics @@ -440,31 +490,31 @@ \installmathfencepair \letteropenbrace \Lbrace \letterclosebrace \Rbrace % as we escape in mp textexts -\installmathfencepair . \Lnothing . \Rnothing -\installmathfencepair . \Rnothingmirrored . \Lnothingmirrored +\installmathfencepair . \Lnothing . \Rnothing +\installmathfencepair . \Rnothingmirrored . \Lnothingmirrored -\installmathfencepair [ \Lbracket ] \Rbracket -\installmathfencepair ] \Rbracketmirrored [ \Lbracketmirrored +\installmathfencepair [ \Lbracket ] \Rbracket +\installmathfencepair ] \Rbracketmirrored [ \Lbracketmirrored -\installmathfencepair ( \Lparenthesis ) \Rparenthesis -\installmathfencepair ) \Rparentmirrored ( \Lparentmirrored +\installmathfencepair ( \Lparenthesis ) \Rparenthesis +\installmathfencepair ) \Rparenthesismirrored ( \Lparenthesismirrored -\installmathfencepair < \Langle > \Rangle -\installmathfencepair > \Ranglemirrored < \Langlemirrored +\installmathfencepair < \Langle > \Rangle +\installmathfencepair > \Ranglemirrored < \Langlemirrored -\installmathfencepair / \Lsolidus / \Rsolidus -%installmathfencepair / \Rsolidusmirrored / \Lsolidusmirrored +\installmathfencepair / \Lsolidus / \Rsolidus +%installmathfencepair / \Rsolidusmirrored / \Lsolidusmirrored -\installmathfencepair | \Lbar | \Rbar -%installmathfencepair | \Rbarmirrored | \Lbarmirrored +\installmathfencepair | \Lbar | \Rbar +%installmathfencepair | \Rbarmirrored | \Lbarmirrored -\installmathfencepair ⌊ \Lfloor ⌋ \Rfloor -\installmathfencepair ⌋ \Rfloormirrored ⌊ \Lfloormirrored -\installmathfencepair ⌈ \Lceiling ⌉ \Rceiling -\installmathfencepair ⌉ \Rceilingmirrored ⌈ \Lceilingmirrored +\installmathfencepair ⌊ \Lfloor ⌋ \Rfloor +\installmathfencepair ⌋ \Rfloormirrored ⌊ \Lfloormirrored +\installmathfencepair ⌈ \Lceiling ⌉ \Rceiling +\installmathfencepair ⌉ \Rceilingmirrored ⌈ \Lceilingmirrored -\installmathfencepair ⟨ \Langle ⟩ \Rangle -\installmathfencepair ⟩ \Ranglemirrored ⟨ \Langlemirrored +\installmathfencepair ⟨ \Langle ⟩ \Rangle +\installmathfencepair ⟩ \Ranglemirrored ⟨ \Langlemirrored \installmathfencepair ⟪ \Ldoubleangle ⟫ \Rdoubleangle \installmathfencepair ⟫ \Rdoubleanglemirrored ⟪ \Ldoubleanglemirrored @@ -475,10 +525,10 @@ \installmathfencepair ⦀ \Ltriplebar ⦀ \Rtriplebar %installmathfencepair ⦀ \Rtriplebarmirrored ⦀ \Ltriplebarmirrored -% \installmathfencepair { \Lbrace } \Rbrace -% \installmathfencepair } \Rbracemirrored { \Lbracemirrored +% \installmathfencepair { \Lbrace } \Rbrace +% \installmathfencepair } \Rbracemirrored { \Lbracemirrored -\installmathfencepair ⦗ \Linterv ⦘ \Rinterv +\installmathfencepair ⦗ \Linterval ⦘ \Rinterval \appendtoks \ignorediscretionaries % so $\mtext{a|b}$ works, this is ok because it's an \hbox @@ -591,7 +641,7 @@ \ifcase\bigmathdelimitermethod \math_fenced_step#2\relax \or - \attribute\mathsizeattribute\numexpr\bigmathdelimitervariant*\plushundred+#1\relax + \math_fenced_force_size\bigmathdelimitervariant{#1}\relax \math_fenced_step#2\relax \else \math_fenced_step#2{\vpack to\csname\??mathbig\number#1\endcsname\bodyfontsize{}}% @@ -621,7 +671,7 @@ \unexpanded\def\mathdelimiterstep#1#2% {\begingroup - \attribute\mathsizeattribute\numexpr\plushundred+#1\relax + \math_fenced_force_size\plusone{#1}% \math_fenced_step#2\relax \endgroup} diff --git a/tex/context/base/mkiv/math-frc.lua b/tex/context/base/mkiv/math-frc.lua index 5c4879527..190c36410 100644 --- a/tex/context/base/mkiv/math-frc.lua +++ b/tex/context/base/mkiv/math-frc.lua @@ -28,8 +28,8 @@ end) local ctx_normalatop = context.normalatop local ctx_normalover = context.normalover -local function mathfraction(how,left,right,width) -- of course we could use the scanners directly here which - if how == v_no then -- is faster but also less abstract ... maybe some day +local function mathfraction(how,left,right,width) + if how == v_no then if left == 0x002E and right == 0x002E then ctx_normalatop() else diff --git a/tex/context/base/mkiv/math-frc.mkiv b/tex/context/base/mkiv/math-frc.mkiv index 9a5ce62b0..97107a6bf 100644 --- a/tex/context/base/mkiv/math-frc.mkiv +++ b/tex/context/base/mkiv/math-frc.mkiv @@ -611,6 +611,46 @@ % \unexpanded\def\ShowMathFractions#1#2% % {\mathematics{x+\tfrac{#1}{#2}+1+\frac{#1}{#2}+2+\sfrac{#1}{#2}+g}} +%D More fracking (for Alan): + +\def\s!vfrac{vfrac} + +\unexpanded\def\math_frac_colored_vulgar#1#2% + {\savecolor + \colo_helpers_activate\p_math_fractions_color + {\restorecolor#1}\Uskewed/{\restorecolor#2}} + +\unexpanded\def\math_frac_normal_vulgar#1#2% + {{#1}\Uskewed/{#2}} + +\unexpanded\def\vfrac#1#2% + {\bgroup + \edef\p_math_fractions_color{\namedmathfractionparameter\s!vfrac\c!color}% + \ifx\p_math_fractions_color\empty + \expandafter\math_frac_normal_vulgar + \else + \expandafter\math_frac_colored_vulgar + \fi + {#1}% + {#2}% + \egroup} + +\appendtoks + \edef\p_hfactor{\namedmathfractionparameter\s!vfrac\c!hfactor}% + \edef\p_vfactor{\namedmathfractionparameter\s!vfrac\c!vfactor}% + \Umathskewedfractionhgap\textstyle \p_hfactor\fontemwidth \mathstylefont\textstyle + \Umathskewedfractionhgap\scriptstyle \p_hfactor\fontemwidth \mathstylefont\scriptstyle + \Umathskewedfractionhgap\scriptscriptstyle\p_hfactor\fontemwidth \mathstylefont\scriptscriptstyle + \Umathskewedfractionvgap\textstyle \p_vfactor\fontexheight\mathstylefont\textstyle + \Umathskewedfractionvgap\scriptstyle \p_vfactor\fontexheight\mathstylefont\scriptstyle + \Umathskewedfractionvgap\scriptscriptstyle\p_vfactor\fontexheight\mathstylefont\scriptscriptstyle +\to \everysetupmathfraction + +\setupmathfraction + [\s!vfrac] + [\c!hfactor=.2, + \c!vfactor=.1] + \protect \endinput % I have no clue what \mthfrac and \mthsqrt are supposed to do but @@ -660,7 +700,7 @@ % \unexpanded\def\mthfrac#1#2#3{[mthfrac: #1 #2 #3]} % \unexpanded\def\mthsqrt#1#2#3{[mthsqrt: #1 #2 #3]} -% used for prototypine \Uskewed +% used for prototyping \Uskewed % % \unexpanded\def\skewedfractiona#1#2{% % \raise diff --git a/tex/context/base/mkiv/math-inc.lua b/tex/context/base/mkiv/math-inc.lua new file mode 100644 index 000000000..010d29a35 --- /dev/null +++ b/tex/context/base/mkiv/math-inc.lua @@ -0,0 +1,87 @@ +if not modules then modules = { } end modules ['back-inc'] = { + version = 1.001, + comment = "companion to back-exp.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- This is an experiment. If it's really useful then I'll make a more efficient +-- local export facility. + +local tonumber, next = tonumber, next +local utfbyte, utfchar, utfsplit = utf.byte, utf.char, utf.split +local match, gsub = string.match, string.gsub +local nspaces = string.nspaces +local concat = table.concat +local xmltext = xml.text +local undent = buffers.undent + +local f_entity = string.formatters["&x%X;"] +local f_blob = string.formatters['\n\n\n\n%s'] + +local all = nil +local back = nil + +local function unmath(s) + local t = utfsplit(s) + for i=1,#t do + local ti = t[i] + local bi = utfbyte(ti) + if bi > 0xFFFF then + local ch = back[bi] + t[i] = ch and utfchar(ch) or f_entity(bi) + end + end + s = concat(t) + return s +end + +local function beautify(s) + local b = match(s,"^( *)%s*$") + if b and e then + b = #b + e = #e + if e > b then + s = undent(nspaces[e-b] .. s) + elseif e < b then + s = undent((gsub(s,"^( *)",nspaces[b-e]))) + end + end + return s +end + +local function getblob(n) + if all == nil then + local name = file.nameonly(tex.jobname) + local full = name .. "-export/" .. name .. "-raw.xml" + if lfs.isfile(full) then + all = { } + back = { } + local root = xml.load(full) + for c in xml.collected(root,"formulacontent") do + local index = tonumber(c.at.n) + all[index] = f_blob(index,beautify(xmltext(c,"math") or "")) + end + local it = mathematics.alphabets.regular.it + for k, v in next, it.digits do back[v] = k end + for k, v in next, it.ucletters do back[v] = k end + for k, v in next, it.lcletters do back[v] = k end + else + all = false + end + end + if all == false then + return "" + end + return unmath(all[n] or "") +end + +interfaces.implement { + name = "xmlformulatobuffer", + arguments = { "integer", "string" }, + actions = function(n,target) + buffers.assign(target,getblob(n)) + end +} diff --git a/tex/context/base/mkiv/math-inc.mkiv b/tex/context/base/mkiv/math-inc.mkiv new file mode 100644 index 000000000..2821580cb --- /dev/null +++ b/tex/context/base/mkiv/math-inc.mkiv @@ -0,0 +1,69 @@ +%D \module +%D [ file=math-inc, +%D version=2018.06.23, +%D title=\CONTEXT\ Math Macros, +%D subtitle=XML inclusion, +%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 Math Macros / XML inclusion} + +\registerctxluafile{math-inc}{} + +%D I had some doubt about including this in \CONTEXT\ but it might serve some users +%D anyway. It's always the question to what extent one can be really roundtrip. I +%D might improve it when I need it. + +% Talking about creating from a source ... June Lee's transcription of +% Close to You by Jacob Collier is an amazing example: +% +% https://www.youtube.com/watch?v=hdBVN-HMuqI + +\unprotect + +\definesymbol[mmlattachment][{\infofont\darkred mml}] +\definesymbol[mmlcomment] [{\infofont\darkblue mml}] + +\unexpanded\def\lxml_add_mml_blob#1#2% + {\relax + \clf_xmlformulatobuffer\number\c_strc_formulas_n{temp-xml-export}% + #2% + [\c!symbol=#1,% + \c!space=\v!yes,% + \c!buffer=temp-xml-export,% + \c!name={formula-\number\c_strc_formulas_n.xml}]% + \relax} + +\unexpanded\def\xmlattachmml + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \lxml_add_mml_blob{mmlattachment}\attachment + \dostoptagged + \fi \fi \fi} + +\unexpanded\def\xmlcommentmml + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \lxml_add_mml_blob{mmlcomment}\comment + \dostoptagged + \fi \fi \fi} + +%D This kind of feature creep is not yet configurable, nor documented. + +\unexpanded\def\xmladdmmlsource + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \inleftmargin{% + \lxml_add_mml_blob{mmlattachment}\attachment + \quad + \lxml_add_mml_blob{mmlcomment}\comment + }% + \dostoptagged + \fi \fi \fi} + +\protect \endinput diff --git a/tex/context/base/mkiv/math-ini.lua b/tex/context/base/mkiv/math-ini.lua index b79ef8c8c..7a8419702 100644 --- a/tex/context/base/mkiv/math-ini.lua +++ b/tex/context/base/mkiv/math-ini.lua @@ -36,8 +36,8 @@ local report_math = logs.reporter("mathematics","initializing") mathematics = mathematics or { } local mathematics = mathematics -mathematics.extrabase = 0xFE000 -- here we push some virtuals -mathematics.privatebase = 0xFF000 -- here we push the ex +mathematics.extrabase = fonts.privateoffsets.mathextrabase -- here we push some virtuals +mathematics.privatebase = fonts.privateoffsets.mathbase -- here we push the ex local unsetvalue = attributes.unsetvalue local allocate = utilities.storage.allocate @@ -289,7 +289,8 @@ function mathematics.define(family) local data = characters.data for unicode, character in sortedhash(data) do local symbol = character.mathsymbol - local mset, dset = true, true + local mset = true + local dset = true if symbol then local other = data[symbol] local class = other.mathclass @@ -641,7 +642,7 @@ function mathematics.big(tfmdata,unicode,n,method) end end end - else + elseif method == 3 then local size = 1.33^n if method == 4 then size = tfmdata.parameters.size * size diff --git a/tex/context/base/mkiv/math-ini.mkiv b/tex/context/base/mkiv/math-ini.mkiv index 17d900d74..50da1a400 100644 --- a/tex/context/base/mkiv/math-ini.mkiv +++ b/tex/context/base/mkiv/math-ini.mkiv @@ -123,9 +123,12 @@ \definesystemattribute[mathbidi] [public] \definesystemattribute[mathdomain] [public] \definesystemattribute[mathcollapsing] [public] +\definesystemattribute[mathunstack] [public] \definesystemattribute[displaymath] [public] +\mathflattenmode 31 + \appendtoks \attribute\mathmodeattribute\plusone \to \everydisplay @@ -217,18 +220,20 @@ \unexpanded\def\startmathematics % no grouping, if ever then also an optional second {\doifelsenextoptionalcs\math_mathematics_start_yes\math_mathematics_start_nop} +\installmacrostack\currentmathematics + \unexpanded\def\math_mathematics_start_yes[#1]% - {\pushmacro\currentmathematics + {\push_macro_currentmathematics \edef\currentmathematics{#1}% check for valid \the\everyswitchmathematics} \unexpanded\def\math_mathematics_start_nop - {\pushmacro\currentmathematics + {\push_macro_currentmathematics \let\currentmathematics\empty \the\everyswitchmathematics} \unexpanded\def\stopmathematics - {\popmacro\currentmathematics + {\pop_macro_currentmathematics \the\everyswitchmathematics} \definemathematics[\v!default] % not needed, but nicer when nesting back to normal @@ -734,7 +739,6 @@ % % \def\math_op{\ifx\nexttoken\bgroup\else\nexttoken\egroup\fi} - % this one too: \letvalue{\??mathcodecommand op}\mathop ? \unexpanded\def\normalmbox @@ -750,17 +754,15 @@ {\ifmmode\normalmbox\else\normalhbox\fi} \unexpanded\def\enablembox - {\appendtoks\math_enable_mbox\to \everymathematics} - {\everymathematics\expandafter{\the\everymathematics\math_enable_mbox}} + {\toksapp\everymathematics{\math_enable_mbox}} \def\math_enable_mbox - {\ifdefined\normalhbox\else\let\normalhbox\hbox\fi % ? - \let\hbox\mbox} + {\let\hbox\mbox} \unexpanded\def\snappedmath#1% sort of \struttedbox {\dontleavehmode \begingroup - \setbox\scratchbox\hbox\bgroup + \setbox\scratchbox\normalhbox\bgroup \startimath#1\stopimath \egroup \ht\scratchbox\strutht @@ -1077,8 +1079,8 @@ % most math fonts have messed up primes, just test this: $\prime^{\prime^{\prime}}$ -{ \catcode\circumflexasciicode\othercatcode \global\let\othercircumflextoken ^ } -{ \catcode\circumflexasciicode\superscriptcatcode \global\let\superscriptcircumflextoken^ } +{ \catcode\circumflexasciicode\othercatcode \glet\othercircumflextoken ^ } +{ \catcode\circumflexasciicode\superscriptcatcode \glet\superscriptcircumflextoken^ } \ifdefined \prime \else \Umathchardef\prime "0 "0 "2032 @@ -1273,9 +1275,13 @@ %D Memory saver: +\def\math_basics_check_compact + {\doifelse{\mathematicsparameter\c!compact}\v!yes + \enabledirectives\disabledirectives[math.virtual.optional]} + \appendtoks \ifx\currentmathematics\empty - \doifelse{\mathematicsparameter\c!compact}\v!yes\enabledirectives\disabledirectives[math.virtual.optional]% + \math_basics_check_compact % less tracing \fi \to \everysetupmathematics @@ -1311,18 +1317,31 @@ %D \HL %D \stoptabulate +% We will use proper constants when we go numbers instead of XXX. + \newconditional\c_math_right_to_left +\installcorenamespace{mathaligndirection} + +\setvalue{\??mathaligndirection r2l}{\settrue\c_math_right_to_left} +\setvalue{\??mathaligndirection\v!righttoleft}{\settrue\c_math_right_to_left} + \appendtoks - \doifelse{\mathematicsparameter\c!align}{r2l}\settrue\setfalse\c_math_right_to_left + \ifcsname\??mathaligndirection\mathematicsparameter\c!align\endcsname + \lastnamedcs + \else + \setfalse\c_math_right_to_left + \fi \to \everyswitchmathematics \unexpanded\def\math_basics_synchronize_direction - {\mathdir T\ifconditional\c_math_right_to_left R\else L\fi T} + {\mathdirection\ifconditional\c_math_right_to_left\directionrighttoleft\else\directionlefttoright\fi} + +% Not \everymathematics as it comes too late and I'm not in the mood for a mixed mode +% kludge now (should be a property of beginmath nodes and passed to callbacks). \appendtoks \math_basics_synchronize_direction -%to \everymathematics % comes too late and I'm not in the mood for a mixed mode kludge now (should be a property of beginmath nodes and passed to callbacks) \to \everyswitchmathematics % experimental (needed for an article) @@ -1337,11 +1356,6 @@ \letvalue{\??mathbidi\v!yes}\math_bidi_enable \letvalue{\??mathbidi\v!no }\math_bidi_disable -% \appendtoks -% \edef\p_bidi{\mathematicsparameter\c!bidi}% -% \csname\??mathbidi\ifcsname\??mathbidi\p_bidi\endcsname\p_bidi\else\v!no\fi\endcsname -% \to \everysetupmathematics - \appendtoks \edef\p_bidi{\mathematicsparameter\c!bidi}% still needed ? \ifcsname\??mathbidi\p_bidi\endcsname\lastnamedcs\else\math_bidi_disable\fi @@ -1434,7 +1448,7 @@ \def\math_collapsing_initialize {\ifnum\c_math_collapsing_attribute=\attributeunsetvalue \else \clf_initializemathcollapsing % one time - \global\let\math_collapsing_initialize\relax + \glet\math_collapsing_initialize\relax \fi} \appendtoks @@ -1471,7 +1485,7 @@ \def\math_italics_initialize {\ifnum\c_math_italics_attribute=\attributeunsetvalue \else \clf_initializemathitalics % one time - \global\let\math_italics_initialize\relax + \glet\math_italics_initialize\relax \fi} \appendtoks @@ -1511,7 +1525,7 @@ \def\math_kernpairs_initialize {\ifnum\c_math_kernpairs_attribute=\attributeunsetvalue \else \clf_initializemathkernpairs % one time - \global\let\math_kernpairs_initialize\relax + \glet\math_kernpairs_initialize\relax \fi} \appendtoks @@ -2343,7 +2357,7 @@ % \c_math_styles_state_cramped\zerocount % \c_math_styles_state_size \zerocount % \rawprocesscommacommand[\m_math_style_asked]\math_style_collect -% \global\expandafter\let\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}% +% \expandafter\glet\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}% % \csname\??mathstylecache\m_math_style_asked\endcsname} \def\math_style_set_indeed @@ -2365,7 +2379,7 @@ \c_math_styles_state_cramped\zerocount \c_math_styles_state_size \zerocount \rawprocesscommacommand[\m_math_style_asked]\math_style_collect - \global\expandafter\let\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}% + \expandafter\glet\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}% \csname\??mathstylecache\m_math_style_asked\endcsname} \letvalue{\??mathstyle \??mathstyle }\math_style_set_mathstyle_mathstyle % still needed? @@ -2468,10 +2482,12 @@ % I need to decide: % -%mathscriptboxmode\zerocount % no kerning -%mathscriptboxmode\plusone % lists -\mathscriptboxmode\plustwo % lists and boxes -%mathscriptboxmode\plusthree % lists and boxes with \boundary=1 (also for testing and demo) +%mathscriptboxmode \zerocount % no kerning +%mathscriptboxmode \plusone % lists +\mathscriptboxmode \plustwo % lists and boxes +\mathscriptcharmode \plusone % lists and boxes +%mathscriptboxmode \plusthree % lists and boxes with \boundary=1 (also for testing and demo) +\mathrulethicknessmode\plusone % adaptive \unexpanded\def\mathtext {\mathortext{\math_text_choice_font\relax}\hbox} \unexpanded\def\mathword {\mathortext{\math_text_choice_word\relax}\hbox} @@ -2529,7 +2545,7 @@ % this can become an option: \unexpanded\def\math_display_align_hack % I don't like the global, maybe we should push and pop - {\global\let\math_display_align_hack_indeed\math_display_align_hack_remove_skip + {\glet\math_display_align_hack_indeed\math_display_align_hack_remove_skip \math_openup\displayopenupvalue % was \math_openup\jot \everycr{\noalign{\math_display_align_hack_indeed}}} @@ -2537,7 +2553,7 @@ {\ifdim\prevdepth>-\thousandpoint \vskip\dimexpr-\lineskiplimit+\normallineskiplimit\relax \fi - \global\let\math_display_align_hack_indeed\math_display_align_hack_insert_penalty} + \glet\math_display_align_hack_indeed\math_display_align_hack_insert_penalty} \def\math_display_align_hack_insert_penalty {\penalty\interdisplaylinepenalty} @@ -2767,7 +2783,7 @@ \def\math_domain_initialize {\ifnum\c_math_domain_attribute=\attributeunsetvalue \else \clf_initializemathdomain % one time - \global\let\math_domain_initialize\relax + \glet\math_domain_initialize\relax \fi} \appendtoks @@ -2791,7 +2807,7 @@ \installcorenamespace{mathrules} -\unexpanded\def\enablemathrules{\global\letvalue{\??mathrules\fontclass}\plusone} +\unexpanded\def\enablemathrules{\letgvalue{\??mathrules\fontclass}\plusone} \appendtoks \mathrulesmode\ifcsname\??mathrules\fontclass\endcsname @@ -2802,6 +2818,70 @@ \mathrulesfam\zerocount \to \everymathematics +%D Maybe: + +% \starttabulate[|||c|c|] +% \BC positive \BC negative \BC text \BC math \NC \NR +% \NC \tex {f1} \tex {hairspace} \tex{,} \NC \tex {b1} \tex {neghairspace} \NC {\darkred\vl}\f1{\darkblue\vl} \NC ${\darkred\vl}\f1{\darkblue\vl}$ \NC \NR +% \NC \tex {f2} \tex {thinspace} \tex{:} \NC \tex {b2} \tex {negthinspace} \tex{!} \NC {\darkred\vl}\f2{\darkblue\vl} \NC ${\darkred\vl}\f2{\darkblue\vl}$ \NC \NR +% \NC \tex {f3} \tex {medspace} \tex{;} \NC \tex {b3} \tex {negmedspace} \NC {\darkred\vl}\f3{\darkblue\vl} \NC ${\darkred\vl}\f3{\darkblue\vl}$ \NC \NR +% \NC \tex {f4} \tex {thickspace} \NC \tex {b4} \tex {negthickspace} \NC {\darkred\vl}\f4{\darkblue\vl} \NC ${\darkred\vl}\f4{\darkblue\vl}$ \NC \NR +% \NC \tex {f5} \tex {enspace} \NC \tex {b5} \NC {\darkred\vl}\f5{\darkblue\vl} \NC ${\darkred\vl}\f5{\darkblue\vl}$ \NC \NR +% \NC \tex {f6} \tex {emspace} \NC \tex {b6} \NC {\darkred\vl}\f6{\darkblue\vl} \NC ${\darkred\vl}\f6{\darkblue\vl}$ \NC \NR +% \stoptabulate + +% \unexpanded\def\negenspace{\kern-.5\emwidth} +% \unexpanded\def\negemspace{\kern- \emwidth} +% +% \unexpanded\def\math_f#1% +% {\ifcase#1\or +% \hairspace +% \or +% \thinspace +% \or +% \medspace +% \or +% \thickspace +% \or +% \enspace +% \or +% \emspace +% \fi} +% +% \unexpanded\def\math_b#1% +% {\ifcase#1\or +% \neghairspace +% \or +% \negthinspace +% \or +% \negmedspace +% \or +% \negthickspace +% \or +% \negenspace +% \or +% \negemspace +% \fi} +% +% \appendtoks +% \let\f\math_f +% \let\b\math_b +% \to \everymathematics + +%D Experiment + +\unexpanded\def\math_scripts_stack + {\attribute\mathunstackattribute\attributeunsetvalue} + +\unexpanded\def\math_scripts_unstack + {\clf_enablescriptunstacking + \attribute\mathunstackattribute\plusone} + +\appendtoks + \let\stackscripts \math_scripts_stack + \let\unstackscripts\math_scripts_unstack +\to \everymathematics + \protect \endinput % % not used (yet) diff --git a/tex/context/base/mkiv/math-noa.lua b/tex/context/base/mkiv/math-noa.lua index 529837cfa..ea7583587 100644 --- a/tex/context/base/mkiv/math-noa.lua +++ b/tex/context/base/mkiv/math-noa.lua @@ -19,7 +19,7 @@ if not modules then modules = { } end modules ['math-noa'] = { -- 20D6 -> 2190 -- 20D7 -> 2192 --- todo: most is math_char so we can have simple dedicated loops +-- todo: most is mathchar_code so we can have simple dedicated loops -- nota bene: uunderdelimiter uoverdelimiter etc are radicals (we have 5 types) @@ -31,177 +31,184 @@ local insert, remove = table.insert, table.remove local div = math.div local bor, band = bit32.bor, bit32.band -local fonts = fonts -local nodes = nodes -local node = node -local mathematics = mathematics -local context = context - -local otf = fonts.handlers.otf -local otffeatures = fonts.constructors.features.otf -local registerotffeature = otffeatures.register - -local privateattribute = attributes.private -local registertracker = trackers.register -local registerdirective = directives.register -local logreporter = logs.reporter -local setmetatableindex = table.setmetatableindex - -local colortracers = nodes.tracers.colors - -local trace_remapping = false registertracker("math.remapping", function(v) trace_remapping = v end) -local trace_processing = false registertracker("math.processing", function(v) trace_processing = v end) -local trace_analyzing = false registertracker("math.analyzing", function(v) trace_analyzing = v end) -local trace_normalizing = false registertracker("math.normalizing", function(v) trace_normalizing = v end) -local trace_collapsing = false registertracker("math.collapsing", function(v) trace_collapsing = v end) -local trace_fixing = false registertracker("math.fixing", function(v) trace_foxing = v end) -local trace_patching = false registertracker("math.patching", function(v) trace_patching = v end) -local trace_goodies = false registertracker("math.goodies", function(v) trace_goodies = v end) -local trace_variants = false registertracker("math.variants", function(v) trace_variants = v end) -local trace_alternates = false registertracker("math.alternates", function(v) trace_alternates = v end) -local trace_italics = false registertracker("math.italics", function(v) trace_italics = v end) -local trace_kernpairs = false registertracker("math.kernpairs", function(v) trace_kernpairs = v end) -local trace_domains = false registertracker("math.domains", function(v) trace_domains = v end) -local trace_families = false registertracker("math.families", function(v) trace_families = v end) -local trace_fences = false registertracker("math.fences", function(v) trace_fences = v end) - -local check_coverage = true registerdirective("math.checkcoverage", function(v) check_coverage = v end) - -local report_processing = logreporter("mathematics","processing") -local report_remapping = logreporter("mathematics","remapping") -local report_normalizing = logreporter("mathematics","normalizing") -local report_collapsing = logreporter("mathematics","collapsing") -local report_fixing = logreporter("mathematics","fixing") -local report_patching = logreporter("mathematics","patching") -local report_goodies = logreporter("mathematics","goodies") -local report_variants = logreporter("mathematics","variants") -local report_alternates = logreporter("mathematics","alternates") -local report_italics = logreporter("mathematics","italics") -local report_kernpairs = logreporter("mathematics","kernpairs") -local report_domains = logreporter("mathematics","domains") -local report_families = logreporter("mathematics","families") -local report_fences = logreporter("mathematics","fences") - -local a_mathrendering = privateattribute("mathrendering") -local a_exportstatus = privateattribute("exportstatus") - -local nuts = nodes.nuts -local nodepool = nuts.pool -local tonut = nuts.tonut -local tonode = nuts.tonode -local nutstring = nuts.tostring - -local setfield = nuts.setfield -local setlink = nuts.setlink -local setlist = nuts.setlist -local setnext = nuts.setnext -local setprev = nuts.setprev -local setchar = nuts.setchar -local setfam = nuts.setfam -local setsubtype = nuts.setsubtype -local setattr = nuts.setattr -local setattrlist = nuts.setattrlist - -local getfield = nuts.getfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getboth = nuts.getboth -local getid = nuts.getid -local getsubtype = nuts.getsubtype -local getchar = nuts.getchar -local getfont = nuts.getfont -local getfam = nuts.getfam -local getattr = nuts.getattr -local getlist = nuts.getlist - -local getnucleus = nuts.getnucleus -local getsub = nuts.getsub -local getsup = nuts.getsup - -local setnucleus = nuts.setnucleus -local setsub = nuts.setsub -local setsup = nuts.setsup - -local flush_node = nuts.flush -local copy_node = nuts.copy -local slide_nodes = nuts.slide -local set_visual = nuts.setvisual - -local mlist_to_hlist = nodes.mlist_to_hlist - -local font_of_family = node.family_font - -local new_kern = nodepool.kern -local new_submlist = nodepool.submlist -local new_noad = nodepool.noad -local new_delimiter = nodepool.delimiter -local new_fence = nodepool.fence - -local fonthashes = fonts.hashes -local fontdata = fonthashes.identifiers -local fontcharacters = fonthashes.characters -local fontitalics = fonthashes.italics - -local variables = interfaces.variables -local texsetattribute = tex.setattribute -local texgetattribute = tex.getattribute -local unsetvalue = attributes.unsetvalue -local implement = interfaces.implement - -local v_reset = variables.reset - -local chardata = characters.data - -noads = noads or { } -- todo: only here -local noads = noads - -noads.processors = noads.processors or { } -local processors = noads.processors - -noads.handlers = noads.handlers or { } -local handlers = noads.handlers - -local tasks = nodes.tasks -local enableaction = tasks.enableaction -local setaction = tasks.setaction - -local nodecodes = nodes.nodecodes -local noadcodes = nodes.noadcodes -local fencecodes = nodes.fencecodes - -local noad_ord = noadcodes.ord -local noad_rel = noadcodes.rel -local noad_bin = noadcodes.bin -local noad_open = noadcodes.open -local noad_close = noadcodes.close -local noad_punct = noadcodes.punct -local noad_opdisplaylimits = noadcodes.opdisplaylimits -local noad_oplimits = noadcodes.oplimits -local noad_opnolimits = noadcodes.opnolimits -local noad_inner = noadcodes.inner - -local math_noad = nodecodes.noad -- attr nucleus sub sup -local math_accent = nodecodes.accent -- attr nucleus sub sup accent -local math_radical = nodecodes.radical -- attr nucleus sub sup left degree -local math_fraction = nodecodes.fraction -- attr nucleus sub sup left right -local math_subbox = nodecodes.subbox -- attr list -local math_submlist = nodecodes.submlist -- attr list -local math_char = nodecodes.mathchar -- attr fam char -local math_textchar = nodecodes.mathtextchar -- attr fam char -local math_delim = nodecodes.delim -- attr small_fam small_char large_fam large_char ------ math_style = nodecodes.style -- attr style -local math_choice = nodecodes.choice -- attr display text script scriptscript -local math_fence = nodecodes.fence -- attr subtype - -local left_fence_code = fencecodes.left -local middle_fence_code = fencecodes.middle -local right_fence_code = fencecodes.right +local fonts = fonts +local nodes = nodes +local node = node +local mathematics = mathematics +local context = context + +local otf = fonts.handlers.otf +local otffeatures = fonts.constructors.features.otf +local registerotffeature = otffeatures.register + +local privateattribute = attributes.private +local registertracker = trackers.register +local registerdirective = directives.register +local logreporter = logs.reporter +local setmetatableindex = table.setmetatableindex + +local colortracers = nodes.tracers.colors + +local trace_remapping = false registertracker("math.remapping", function(v) trace_remapping = v end) +local trace_processing = false registertracker("math.processing", function(v) trace_processing = v end) +local trace_analyzing = false registertracker("math.analyzing", function(v) trace_analyzing = v end) +local trace_normalizing = false registertracker("math.normalizing", function(v) trace_normalizing = v end) +local trace_collapsing = false registertracker("math.collapsing", function(v) trace_collapsing = v end) +local trace_fixing = false registertracker("math.fixing", function(v) trace_foxing = v end) +local trace_patching = false registertracker("math.patching", function(v) trace_patching = v end) +local trace_goodies = false registertracker("math.goodies", function(v) trace_goodies = v end) +local trace_variants = false registertracker("math.variants", function(v) trace_variants = v end) +local trace_alternates = false registertracker("math.alternates", function(v) trace_alternates = v end) +local trace_italics = false registertracker("math.italics", function(v) trace_italics = v end) +local trace_kernpairs = false registertracker("math.kernpairs", function(v) trace_kernpairs = v end) +local trace_domains = false registertracker("math.domains", function(v) trace_domains = v end) +local trace_families = false registertracker("math.families", function(v) trace_families = v end) +local trace_fences = false registertracker("math.fences", function(v) trace_fences = v end) +local trace_unstacking = false registertracker("math.unstack", function(v) trace_unstacking = v end) + +local check_coverage = true registerdirective("math.checkcoverage", function(v) check_coverage = v end) + +local report_processing = logreporter("mathematics","processing") +local report_remapping = logreporter("mathematics","remapping") +local report_normalizing = logreporter("mathematics","normalizing") +local report_collapsing = logreporter("mathematics","collapsing") +local report_fixing = logreporter("mathematics","fixing") +local report_patching = logreporter("mathematics","patching") +local report_goodies = logreporter("mathematics","goodies") +local report_variants = logreporter("mathematics","variants") +local report_alternates = logreporter("mathematics","alternates") +local report_italics = logreporter("mathematics","italics") +local report_kernpairs = logreporter("mathematics","kernpairs") +local report_domains = logreporter("mathematics","domains") +local report_families = logreporter("mathematics","families") +local report_fences = logreporter("mathematics","fences") +local report_unstacking = logreporter("mathematics","unstack") + +local a_mathrendering = privateattribute("mathrendering") +local a_exportstatus = privateattribute("exportstatus") + +local nuts = nodes.nuts +local nodepool = nuts.pool +local tonut = nuts.tonut +local nutstring = nuts.tostring + +local setfield = nuts.setfield +local setlink = nuts.setlink +local setlist = nuts.setlist +local setnext = nuts.setnext +local setprev = nuts.setprev +local setchar = nuts.setchar +local setfam = nuts.setfam +local setsubtype = nuts.setsubtype +local setattr = nuts.setattr +local setattrlist = nuts.setattrlist +local setwidth = nuts.setwidth +local setheight = nuts.setheight +local setdepth = nuts.setdepth + +local getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getboth = nuts.getboth +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar +local getfont = nuts.getfont +local getfam = nuts.getfam +local getattr = nuts.getattr +local getlist = nuts.getlist +local getwidth = nuts.getwidth +local getheight = nuts.getheight +local getdepth = nuts.getdepth + +local getnucleus = nuts.getnucleus +local getsub = nuts.getsub +local getsup = nuts.getsup + +local setnucleus = nuts.setnucleus +local setsub = nuts.setsub +local setsup = nuts.setsup + +local flush_node = nuts.flush +local copy_node = nuts.copy +local slide_nodes = nuts.slide +local set_visual = nuts.setvisual + +local mlist_to_hlist = nuts.mlist_to_hlist + +local font_of_family = node.family_font + +local new_kern = nodepool.kern +local new_submlist = nodepool.submlist +local new_noad = nodepool.noad +local new_delimiter = nodepool.delimiter +local new_fence = nodepool.fence + +local fonthashes = fonts.hashes +local fontdata = fonthashes.identifiers +local fontcharacters = fonthashes.characters +local fontitalics = fonthashes.italics + +local variables = interfaces.variables +local texsetattribute = tex.setattribute +local texgetattribute = tex.getattribute +local unsetvalue = attributes.unsetvalue +local implement = interfaces.implement + +local v_reset = variables.reset + +local chardata = characters.data + +noads = noads or { } -- todo: only here +local noads = noads + +noads.processors = noads.processors or { } +local processors = noads.processors + +noads.handlers = noads.handlers or { } +local handlers = noads.handlers + +local tasks = nodes.tasks +local enableaction = tasks.enableaction +local setaction = tasks.setaction + +local nodecodes = nodes.nodecodes +local noadcodes = nodes.noadcodes +local fencecodes = nodes.fencecodes + +local ordnoad_code = noadcodes.ord +local relnode_code = noadcodes.rel +local binnoad_code = noadcodes.bin +local opennoad_code = noadcodes.open +local closenoad_code = noadcodes.close +local punctnoad_code = noadcodes.punct +local opdisplaylimitsnoad_code = noadcodes.opdisplaylimits +local oplimitsnoad_code = noadcodes.oplimits +local opnolimitsnoad_code = noadcodes.opnolimits +local innernoad_code = noadcodes.inner + +local noad_code = nodecodes.noad -- attr nucleus sub sup +local accent_code = nodecodes.accent -- attr nucleus sub sup accent +local radical_code = nodecodes.radical -- attr nucleus sub sup left degree +local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right +local subbox_code = nodecodes.subbox -- attr list +local submlist_code = nodecodes.submlist -- attr list +local mathchar_code = nodecodes.mathchar -- attr fam char +local mathtextchar_code = nodecodes.mathtextchar -- attr fam char +local delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char +----- style_code = nodecodes.style -- attr style +local math_choice = nodecodes.choice -- attr display text script scriptscript +local fence_code = nodecodes.fence -- attr subtype + +local leftfence_code = fencecodes.left +local middlefence_code = fencecodes.middle +local rightfence_code = fencecodes.right -- local mathclasses = mathematics.classes -- local fenceclasses = { --- [left_fence_code] = mathclasses.open, --- [middle_fence_code] = mathclasses.middle, --- [right_fence_code] = mathclasses.close, +-- [leftfence_code] = mathclasses.open, +-- [middlefence_code] = mathclasses.middle, +-- [rightfence_code] = mathclasses.close, -- } -- this initial stuff is tricky as we can have removed and new nodes with the same address @@ -211,6 +218,7 @@ local right_fence_code = fencecodes.right -- local sf = setfield local st = setmetatableindex("number") setfield = function(n,f,v) st[f] = st[f] + 1 sf(n,f,v) end mathematics.SETFIELD = st local function process(start,what,n,parent) + if n then n = n + 1 else @@ -224,9 +232,9 @@ local function process(start,what,n,parent) while start do local id = getid(start) if trace_processing then - if id == math_noad then + if id == noad_code then report_processing("%w%S, class %a",n*2,nutstring(start),noadcodes[getsubtype(start)]) - elseif id == math_char then + elseif id == mathchar_code then local char = getchar(start) local font = getfont(start) local fam = getfam(start) @@ -256,16 +264,16 @@ local function process(start,what,n,parent) -- report_processing("stop processing") end end - elseif id == math_noad then + elseif id == noad_code then -- single characters are like this local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list noad = getsup (start) if noad then process(noad,what,n,start) end -- list noad = getsub (start) if noad then process(noad,what,n,start) end -- list - elseif id == math_char or id == math_textchar or id == math_delim then + elseif id == mathchar_code or id == mathtextchar_code or id == delim_code then break - elseif id == math_subbox or id == math_submlist then + elseif id == subbox_code or id == submlist_code then local noad = getlist(start) if noad then process(noad,what,n,start) end -- list (not getlist !) - elseif id == math_fraction then + elseif id == fraction_code then local noad = getfield(start,"num") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"denom") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"left") if noad then process(noad,what,n,start) end -- delimiter @@ -275,21 +283,21 @@ local function process(start,what,n,parent) noad = getfield(start,"text") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"script") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"scriptscript") if noad then process(noad,what,n,start) end -- list - elseif id == math_fence then + elseif id == fence_code then local noad = getfield(start,"delim") if noad then process(noad,what,n,start) end -- delimiter - elseif id == math_radical then + elseif id == radical_code then local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list noad = getsup (start) if noad then process(noad,what,n,start) end -- list noad = getsub (start) if noad then process(noad,what,n,start) end -- list noad = getfield(start,"left") if noad then process(noad,what,n,start) end -- delimiter noad = getfield(start,"degree") if noad then process(noad,what,n,start) end -- list - elseif id == math_accent then + elseif id == accent_code then local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list noad = getsup (start) if noad then process(noad,what,n,start) end -- list noad = getsub (start) if noad then process(noad,what,n,start) end -- list noad = getfield(start,"accent") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"bot_accent") if noad then process(noad,what,n,start) end -- list - -- elseif id == math_style then + -- elseif id == style_code then -- -- has a next -- else -- -- glue, penalty, etc @@ -297,20 +305,20 @@ local function process(start,what,n,parent) start = getnext(start) end if not parent then - return initial, true -- only first level -- for now + return initial -- only first level -- for now end end local function processnested(current,what,n) local noad = nil local id = getid(current) - if id == math_noad then + if id == noad_code then noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list - elseif id == math_subbox or id == math_submlist then + elseif id == subbox_code or id == submlist_code then noad = getlist(current) if noad then process(noad,what,n,current) end -- list (not getlist !) - elseif id == math_fraction then + elseif id == fraction_code then noad = getfield(current,"num") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"denom") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,what,n,current) end -- delimiter @@ -320,15 +328,15 @@ local function processnested(current,what,n) noad = getfield(current,"text") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"script") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"scriptscript") if noad then process(noad,what,n,current) end -- list - elseif id == math_fence then + elseif id == fence_code then noad = getfield(current,"delim") if noad then process(noad,what,n,current) end -- delimiter - elseif id == math_radical then + elseif id == radical_code then noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,what,n,current) end -- delimiter noad = getfield(current,"degree") if noad then process(noad,what,n,current) end -- list - elseif id == math_accent then + elseif id == accent_code then noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list @@ -340,13 +348,13 @@ end local function processstep(current,process,n,id) local noad = nil local id = id or getid(current) - if id == math_noad then + if id == noad_code then noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list - elseif id == math_subbox or id == math_submlist then + elseif id == subbox_code or id == submlist_code then noad = getlist(current) if noad then process(noad,n,current) end -- list (not getlist !) - elseif id == math_fraction then + elseif id == fraction_code then noad = getfield(current,"num") if noad then process(noad,n,current) end -- list noad = getfield(current,"denom") if noad then process(noad,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,n,current) end -- delimiter @@ -356,15 +364,15 @@ local function processstep(current,process,n,id) noad = getfield(current,"text") if noad then process(noad,n,current) end -- list noad = getfield(current,"script") if noad then process(noad,n,current) end -- list noad = getfield(current,"scriptscript") if noad then process(noad,n,current) end -- list - elseif id == math_fence then + elseif id == fence_code then noad = getfield(current,"delim") if noad then process(noad,n,current) end -- delimiter - elseif id == math_radical then + elseif id == radical_code then noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,n,current) end -- delimiter noad = getfield(current,"degree") if noad then process(noad,n,current) end -- list - elseif id == math_accent then + elseif id == accent_code then noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list @@ -374,15 +382,14 @@ local function processstep(current,process,n,id) end local function processnoads(head,actions,banner) - local h, d if trace_processing then report_processing("start %a",banner) - h, d = process(tonut(head),actions) + head = process(head,actions) report_processing("stop %a",banner) else - h, d = process(tonut(head),actions) + head = process(head,actions) end - return h and tonode(h) or head, d == nil and true or d + return head end noads.process = processnoads @@ -456,7 +463,35 @@ do "pseudobold", } - families[math_char] = function(pointer) + families[fraction_code] = function(pointer,what,n,parent) + local a = getattr(pointer,a_mathfamily) + if a and a >= 0 then + if a > 0 then + setattr(pointer,a_mathfamily,0) + if a > 5 then + a = a - 3 + end + end + setfam(pointer,a) + end + processnested(pointer,families,n+1) + end + + families[noad_code] = function(pointer,what,n,parent) + local a = getattr(pointer,a_mathfamily) + if a and a >= 0 then + if a > 0 then + setattr(pointer,a_mathfamily,0) + if a > 5 then + a = a - 3 + end + end + setfam(pointer,a) + end + processnested(pointer,families,n+1) + end + + families[mathchar_code] = function(pointer) if getfam(pointer) == 0 then local a = getattr(pointer,a_mathfamily) if a and a > 0 then @@ -501,8 +536,7 @@ do end end end - - families[math_delim] = function(pointer) + families[delim_code] = function(pointer) if getfield(pointer,"small_fam") == 0 then local a = getattr(pointer,a_mathfamily) if a and a > 0 then @@ -534,7 +568,7 @@ do -- will become: - -- families[math_delim] = function(pointer) + -- families[delim_code] = function(pointer) -- if getfam(pointer) == 0 then -- local a = getattr(pointer,a_mathfamily) -- if a and a > 0 then @@ -556,11 +590,11 @@ do -- end -- end - families[math_textchar] = families[math_char] + families[mathtextchar_code] = families[mathchar_code] function handlers.families(head,style,penalties) processnoads(head,families,"families") - return true + return true -- not needed end end @@ -604,7 +638,7 @@ do end end - relocate[math_char] = function(pointer) + relocate[mathchar_code] = function(pointer) local g = getattr(pointer,a_mathgreek) or 0 local a = getattr(pointer,a_mathalphabet) or 0 local char = getchar(pointer) @@ -671,13 +705,13 @@ do end end - relocate[math_textchar] = function(pointer) + relocate[mathtextchar_code] = function(pointer) if trace_analyzing then setnodecolor(pointer,"font:init") end end - relocate[math_delim] = function(pointer) + relocate[delim_code] = function(pointer) if trace_analyzing then setnodecolor(pointer,"font:fina") end @@ -685,7 +719,7 @@ do function handlers.relocate(head,style,penalties) processnoads(head,relocate,"relocate") - return true + return true -- not needed end end @@ -698,7 +732,7 @@ do local rendersets = mathematics.renderings.numbers or { } -- store - render[math_char] = function(pointer) + render[mathchar_code] = function(pointer) local attr = getattr(pointer,a_mathrendering) if attr and attr > 0 then local char = getchar(pointer) @@ -719,7 +753,7 @@ do function handlers.render(head,style,penalties) processnoads(head,render,"render") - return true + return true -- not needed end end @@ -739,51 +773,46 @@ do local a_mathsize = privateattribute("mathsize") -- this might move into other fence code local resize = { } - resize[math_fence] = function(pointer) + resize[fence_code] = function(pointer) local subtype = getsubtype(pointer) - if subtype == left_fence_code or subtype == right_fence_code then + if subtype == leftfence_code or subtype == rightfence_code then local a = getattr(pointer,a_mathsize) if a and a > 0 then - local method, size = div(a,100), a % 100 + local method = div(a,100) + local size = a % 100 setattr(pointer,a_mathsize,0) local delimiter = getfield(pointer,"delim") - local chr = getfield(delimiter,"small_char") + local chr = getchar(delimiter) if chr > 0 then - local fam = getfield(delimiter,"small_fam") + local fam = getfam(delimiter) local id = font_of_family(fam) if id > 0 then - setfield(delimiter,"small_char",mathematics.big(fontdata[id],chr,size,method)) + local data = fontdata[id] + local char = mathematics.big(data,chr,size,method) + local ht = getheight(pointer) + local dp = getdepth(pointer) + if ht == 1 or dp == 1 then -- 1 scaled point is a signal + local chardata = data.characters[char] + if ht == 1 then + setheight(pointer,chardata.height) + end + if dp == 1 then + setdepth(pointer,chardata.depth) + end + end + if trace_fences then + report_fences("replacing %C by %C using method %a and size %a",chr,char,method,size) + end + setchar(delimiter,char) end end end end end - -- will become: - - -- resize[math_fence] = function(pointer) - -- local subtype = getsubtype(pointer) - -- if subtype == left_fence_code or subtype == right_fence_code then - -- local a = getattr(pointer,a_mathsize) - -- if a and a > 0 then - -- local method, size = div(a,100), a % 100 - -- setattr(pointer,a_mathsize,0) - -- local delimiter = getfield(pointer,"delim") - -- local chr = getchar(delimiter) - -- if chr > 0 then - -- local fam = getfam(delimiter) - -- local id = font_of_family(fam) - -- if id > 0 then - -- setchar(delimiter,mathematics.big(fontdata[id],chr,size,method)) - -- end - -- end - -- end - -- end - -- end - function handlers.resize(head,style,penalties) processnoads(head,resize,"resize") - return true + return true -- not needed end end @@ -797,8 +826,8 @@ do local dummyfencechar = 0x2E local function makefence(what,char) - local d = new_delimiter() - local f = new_fence() + local d = new_delimiter() -- todo: attr + local f = new_fence() -- todo: attr if char then local sym = getnucleus(char) local chr = getchar(sym) @@ -821,8 +850,8 @@ do -- will become -- local function makefence(what,char) - -- local d = new_delimiter() - -- local f = new_fence() + -- local d = new_delimiter() -- todo: attr + -- local f = new_fence() -- todo: attr -- if char then -- local sym = getnucleus(char) -- local chr = getchar(sym) @@ -843,7 +872,7 @@ do local function makelist(noad,f_o,o_next,c_prev,f_c,middle) local list = new_submlist() setlist(list,f_o) - setsubtype(noad,noad_inner) + setsubtype(noad,innernoad_code) setnucleus(noad,list) setlink(f_o,o_next) setlink(c_prev,f_c) @@ -854,7 +883,7 @@ do local m = middle[current] if m then local next = getnext(current) - local fence = makefence(middle_fence_code,current) + local fence = makefence(middlefence_code,current) setnucleus(current) flush_node(current) middle[current] = nil @@ -876,8 +905,8 @@ do if o_next == close then return close else - local f_o = makefence(left_fence_code,open) - local f_c = makefence(right_fence_code,close) + local f_o = makefence(leftfence_code,open) + local f_c = makefence(rightfence_code,close) makelist(open,f_o,o_next,c_prev,f_c,middle) setnucleus(close) flush_node(close) @@ -890,8 +919,8 @@ do end local function convert_open(open,last,middle) - local f_o = makefence(left_fence_code,open) - local f_c = makefence(right_fence_code) + local f_o = makefence(leftfence_code,open) + local f_c = makefence(rightfence_code) local o_prev, o_next = getboth(open) local l_prev, l_next = getboth(last) makelist(open,f_o,o_next,last,f_c,middle) @@ -903,8 +932,8 @@ do end local function convert_close(close,first,middle) - local f_o = makefence(left_fence_code) - local f_c = makefence(right_fence_code,close) + local f_o = makefence(leftfence_code) + local f_c = makefence(rightfence_code,close) local c_prev = getprev(close) makelist(close,f_o,first,c_prev,f_c,middle) return close @@ -922,7 +951,7 @@ do local middle = nil -- todo: use properties while current do local id = getid(current) - if id == math_noad then + if id == noad_code then local a = getattr(current,a_autofence) if a and a > 0 then local stack = stacks[n] @@ -1009,7 +1038,7 @@ do function handlers.autofences(head,style,penalties) if enabled then -- tex.modes.c_math_fences_auto -- inspect(nodes.totree(head)) - processfences(tonut(head),1) + processfences(head,1) -- inspect(nodes.totree(head)) end end @@ -1031,9 +1060,9 @@ do local next = getnext(pointer) local start_super, stop_super, start_sub, stop_sub local mode = "unset" - while next and getid(next) == math_noad do + while next and getid(next) == noad_code do local nextnucleus = getnucleus(next) - if nextnucleus and getid(nextnucleus) == math_char and not getsub(next) and not getsup(next) then + if nextnucleus and getid(nextnucleus) == mathchar_code and not getsub(next) and not getsup(next) then local char = getchar(nextnucleus) local s = superscripts[char] if s then @@ -1088,6 +1117,18 @@ do setnext(stop_super) end if start_sub then + +-- if mode == "sub" then +-- local sup = getsup(pointer) +-- if sup and not getsub(pointer) then +-- local nxt = getnext(pointer) +-- local new = new_noad(pointer) +-- setnucleus(new,new_submlist()) +-- setlink(pointer,new,nxt) +-- pointer = new +-- end +-- end + if start_sub == stop_sub then setsub(pointer,getnucleus(start_sub)) else @@ -1103,16 +1144,57 @@ do -- we could return stop end - unscript[math_char] = replace -- not noads as we need to recurse + unscript[mathchar_code] = replace -- not noads as we need to recurse function handlers.unscript(head,style,penalties) processnoads(head,unscript,"unscript") - -- processnoads(head,checkers,"checkers") - return true + return true -- not needed end end +do + + local unstack = { } noads.processors.unstack = unstack + local enabled = false + local a_unstack = privateattribute("mathunstack") + + unstack[noad_code] = function(pointer) + if getattr(pointer,a_unstack) then + local sup = getsup(pointer) + local sub = getsub(pointer) + if sup and sub then + -- if trace_unstacking then + -- report_unstacking() -- todo ... what to show ... + -- end + local nxt = getnext(pointer) + local new = new_noad(pointer) + setnucleus(new,new_submlist()) + setsub(pointer) + setsub(new,sub) + setlink(pointer,new,nxt) + end + end + end + + function handlers.unstack(head,style,penalties) + if enabled then + processnoads(head,unstack,"unstack") + return true -- not needed + end + end + + implement { + name = "enablescriptunstacking", + onlyonce = true, + actions = function() + enableaction("math","noads.handlers.unstack") + enabled = true + end + } + +end + do local function collected(list) @@ -1306,7 +1388,7 @@ do arguments = { "integer", "string" } } - alternate[math_char] = function(pointer) -- slow + alternate[mathchar_code] = function(pointer) -- slow local a = getattr(pointer,a_mathalternate) if a and a > 0 then setattr(pointer,a_mathalternate,0) @@ -1347,7 +1429,7 @@ do function handlers.alternates(head,style,penalties) processnoads(head,alternate,"alternate") - return true + return true -- not needed end end @@ -1365,7 +1447,7 @@ end -- in opentype the italic correction of a limop is added to the width and luatex does -- some juggling that we want to avoid but we need to do something here (in fact, we could --- better fix the width of the character +-- better fix the width of the character) do @@ -1382,8 +1464,8 @@ do local c_negative_d = "trace:dr" local function insert_kern(current,kern) - local sub = new_submlist() - local noad = new_noad() + local sub = new_submlist() -- todo: attr + local noad = new_noad() -- todo: attr setlist(sub,kern) setnext(kern,noad) setnucleus(noad,current) @@ -1393,7 +1475,7 @@ do registertracker("math.italics.visualize", function(v) if v then italic_kern = function(k) - local n = new_kern(k) + local n = new_kern(k) -- todo: attr set_visual(n,"italic") return n end @@ -1454,7 +1536,7 @@ do end - italics[math_char] = function(pointer,what,n,parent) + italics[mathchar_code] = function(pointer,what,n,parent) local method = getattr(pointer,a_mathitalics) if method and method > 0 and method < 100 then local char = getchar(pointer) @@ -1485,7 +1567,7 @@ do function handlers.italics(head,style,penalties) processnoads(head,italics,"italics") - return true + return true -- not needed end local enable = function() @@ -1582,7 +1664,7 @@ do -- no correction after prime because that moved to a superscript - kernpairs[math_char] = function(pointer,what,n,parent) + kernpairs[mathchar_code] = function(pointer,what,n,parent) if getattr(pointer,a_kernpairs) == 1 then local font = getfont(pointer) local list = hash[font] @@ -1591,7 +1673,7 @@ do local found = list[first] if found then local next = getnext(parent) - if next and getid(next) == math_noad then + if next and getid(next) == noad_code then pointer = getnucleus(next) if pointer then if getfont(pointer) == font then @@ -1602,7 +1684,7 @@ do if trace_kernpairs then report_kernpairs("adding %p kerning between %C and %C",kern,first,second) end - setlink(parent,new_kern(kern),getnext(parent)) + setlink(parent,new_kern(kern),getnext(parent)) -- todo: attr end end end @@ -1614,7 +1696,7 @@ do function handlers.kernpairs(head,style,penalties) processnoads(head,kernpairs,"kernpairs") - return true + return true -- not needed end end @@ -1629,20 +1711,20 @@ do local collapse = { } local mathlists = characters.mathlists local validpair = { - [noad_ord] = true, - [noad_rel] = true, - [noad_bin] = true, -- new - [noad_open] = true, -- new - [noad_close] = true, -- new - [noad_punct] = true, -- new - [noad_opdisplaylimits] = true, - [noad_oplimits] = true, - [noad_opnolimits] = true, + [ordnoad_code] = true, + [relnode_code] = true, + [binnoad_code] = true, -- new + [opennoad_code] = true, -- new + [closenoad_code] = true, -- new + [punctnoad_code] = true, -- new + [opdisplaylimitsnoad_code] = true, + [oplimitsnoad_code] = true, + [opnolimitsnoad_code] = true, } local reported = setmetatableindex("table") - collapse[math_char] = function(pointer,what,n,parent) + collapse[mathchar_code] = function(pointer,what,n,parent) if parent and mathlists[getchar(pointer)] then local found, last, lucleus, lsup, lsub, category @@ -1727,7 +1809,7 @@ do function noads.handlers.collapse(head,style,penalties) processnoads(head,collapse,"collapse") - return true + return true -- not needed end local enable = function() @@ -1784,7 +1866,7 @@ do -- local function movesubscript(parent,current_nucleus,oldchar,newchar) -- local prev = getprev(parent) - -- if prev and getid(prev) == math_noad then + -- if prev and getid(prev) == noad_code then -- local psup = getsup(prev) -- local psub = getsub(prev) -- if not psup and not psub then @@ -1827,7 +1909,7 @@ do setnucleus(parent,dummy) end - fixscripts[math_char] = function(pointer,what,n,parent,nested) -- todo: switch to turn in on and off + fixscripts[mathchar_code] = function(pointer,what,n,parent,nested) -- todo: switch to turn in on and off if parent then local oldchar = getchar(pointer) local newchar = movesub[oldchar] @@ -1846,7 +1928,7 @@ do -- print("[char] --- sup") else local prev = getprev(parent) - if prev and getid(prev) == math_noad then + if prev and getid(prev) == noad_code then local psub = getsub(prev) local psup = getsup(prev) if psub then @@ -1875,7 +1957,7 @@ do function noads.handlers.fixscripts(head,style,penalties) processnoads(head,fixscripts,"fixscripts") - return true + return true -- not needed end end @@ -1901,14 +1983,14 @@ do [0x2ACB] = 0xFE00, [0x2ACC] = 0xFE00, } - variants[math_char] = function(pointer,what,n,parent) -- also set export value + variants[mathchar_code] = function(pointer,what,n,parent) -- also set export value local char = getchar(pointer) local selector = validvariants[char] if selector then local next = getnext(parent) - if next and getid(next) == math_noad then + if next and getid(next) == noad_code then local nucleus = getnucleus(next) - if nucleus and getid(nucleus) == math_char and getchar(nucleus) == selector then + if nucleus and getid(nucleus) == mathchar_code and getchar(nucleus) == selector then local variant local tfmdata = fontdata[getfont(pointer)] local mathvariants = tfmdata.resources.variants -- and variantdata @@ -1939,7 +2021,7 @@ do function handlers.variants(head,style,penalties) processnoads(head,variants,"unicode variant") - return true + return true -- not needed end end @@ -1950,25 +2032,25 @@ do local classes = { } local colors = { - [noad_rel] = "trace:dr", - [noad_ord] = "trace:db", - [noad_bin] = "trace:dg", - [noad_open] = "trace:dm", - [noad_close] = "trace:dm", - [noad_punct] = "trace:dc", - -- [noad_opdisplaylimits] = "", - -- [noad_oplimits] = "", - -- [noad_opnolimits] = "", - -- [noad_inner = "", - -- [noad_under = "", - -- [noad_over = "", - -- [noad_vcenter = "", + [relnode_code] = "trace:dr", + [ordnoad_code] = "trace:db", + [binnoad_code] = "trace:dg", + [opennoad_code] = "trace:dm", + [closenoad_code] = "trace:dm", + [punctnoad_code] = "trace:dc", + -- [opdisplaylimitsnoad_code] = "", + -- [oplimitsnoad_code] = "", + -- [opnolimitsnoad_code] = "", + -- [innernoad_code = "", + -- [undernoad_code] = "", + -- [overnoad_code] = "", + -- [vcenternoad_code] = "", } local setcolor = colortracers.set local resetcolor = colortracers.reset - classes[math_char] = function(pointer,what,n,parent) + classes[mathchar_code] = function(pointer,what,n,parent) local color = colors[getsubtype(parent)] if color then setcolor(pointer,color) @@ -1979,7 +2061,7 @@ do function handlers.classes(head,style,penalties) processnoads(head,classes,"classes") - return true + return true -- not needed end registertracker("math.classes",function(v) @@ -2006,11 +2088,11 @@ do local a_mathdomain = privateattribute("mathdomain") mathematics.domains = categories local permitted = { - ordinary = noad_ord, - binary = noad_bin, - relation = noad_rel, - punctuation = noad_punct, - inner = noad_inner, + ordinary = ordnoad_code, + binary = binnoad_code, + relation = relnode_code, + punctuation = punctnoad_code, + inner = innernoad_code, } function mathematics.registerdomain(data) @@ -2113,7 +2195,7 @@ do return hash end - domains[math_char] = function(pointer,what,n,parent) + domains[mathchar_code] = function(pointer,what,n,parent) local attr = getattr(pointer,a_mathdomain) if attr then local domain = numbers[attr] @@ -2140,7 +2222,7 @@ do function handlers.domains(head,style,penalties) processnoads(head,domains,"domains") - return true + return true -- not needed end end @@ -2148,7 +2230,7 @@ end -- just for me function handlers.showtree(head,style,penalties) - inspect(nodes.totree(head)) + inspect(nodes.totree(tonut(head))) end registertracker("math.showtree",function(v) @@ -2163,7 +2245,7 @@ do local visual = false function handlers.makeup(head) - applyvisuals(tonut(head),visual) + applyvisuals(head,visual) end registertracker("math.makeup",function(v) @@ -2184,9 +2266,15 @@ do -- end) function builders.kernel.mlist_to_hlist(head,style,penalties) - return mlist_to_hlist(head,style,force_penalties or penalties), true + return mlist_to_hlist(head,style,force_penalties or penalties) end + -- function builders.kernel.mlist_to_hlist(head,style,penalties) + -- local h = mlist_to_hlist(head,style,force_penalties or penalties) + -- inspect(nodes.totree(h,true,true,true)) + -- return h + -- end + implement { name = "setmathpenalties", arguments = "integer", @@ -2197,41 +2285,15 @@ do end --- function builders.kernel.mlist_to_hlist(head,style,penalties) --- print("!!!!!!! BEFORE",penalties) --- for n in node.traverse(head) do print(n) end --- print("!!!!!!!") --- head = mlist_to_hlist(head,style,penalties) --- print("!!!!!!! AFTER") --- for n in node.traverse(head) do print(n) end --- print("!!!!!!!") --- return head, true --- end - -tasks.new { - name = "math", - arguments = 2, - processor = utilities.sequencers.nodeprocessor, - sequence = { - "before", - "normalizers", - "builders", - "after", - }, -} - -tasks.freezegroup("math", "normalizers") -- experimental -tasks.freezegroup("math", "builders") -- experimental - local actions = tasks.actions("math") -- head, style, penalties local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming function processors.mlist_to_hlist(head,style,penalties) starttiming(noads) - local head, done = actions(head,style,penalties) + head = actions(head,style,penalties) stoptiming(noads) - return head, done + return head end callbacks.register('mlist_to_hlist',processors.mlist_to_hlist,"preprocessing math list") diff --git a/tex/context/base/mkiv/math-pln.mkiv b/tex/context/base/mkiv/math-pln.mkiv index d0e7e377d..1003444b8 100644 --- a/tex/context/base/mkiv/math-pln.mkiv +++ b/tex/context/base/mkiv/math-pln.mkiv @@ -171,7 +171,7 @@ \crcr \noalign\bgroup \kern\scratchdimentwo - \global\let\cr\endline + \glet\cr\endline \egroup }% \ialign{% diff --git a/tex/context/base/mkiv/math-spa.lua b/tex/context/base/mkiv/math-spa.lua index 92ee662b9..33d9501d8 100644 --- a/tex/context/base/mkiv/math-spa.lua +++ b/tex/context/base/mkiv/math-spa.lua @@ -8,24 +8,23 @@ if not modules then modules = { } end modules ['math-spa'] = { -- for the moment (when testing) we use a penalty 1 -local penalty_code = nodes.nodecodes.penalty -local glue_code = nodes.nodecodes.glue +local penalty_code = nodes.nodecodes.penalty +local glue_code = nodes.nodecodes.glue -local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode -local getid = nuts.getid -local getnext = nuts.getnext -local getwidth = nuts.getwidth -local setglue = nuts.setglue -local getpenalty = nuts.getpenalty -local setpenalty = nuts.setpenalty +local nuts = nodes.nuts +local tonut = nodes.tonut +local tonode = nodes.tonode -local traverse_id = nuts.traverse_id -local get_dimensions = nuts.dimensions +local getid = nuts.getid +local getnext = nuts.getnext +local getwidth = nuts.getwidth +local setglue = nuts.setglue +local getpenalty = nuts.getpenalty +local setpenalty = nuts.setpenalty +local getdimensions = nuts.dimensions +local nextglue = nuts.traversers.glue - -local texsetdimen = tex.setdimen +local texsetdimen = tex.setdimen local v_none = interfaces.variables.none local v_auto = interfaces.variables.auto @@ -33,9 +32,8 @@ local v_auto = interfaces.variables.auto local method = v_none local distance = 0 -function noads.handlers.align(l) +function noads.handlers.align(h) if method ~= v_none then - local h = tonut(l) if method == v_auto then local s = h while s do @@ -47,7 +45,7 @@ function noads.handlers.align(l) s = n n = getnext(s) end - local w = get_dimensions(h,n) + distance + local w = getdimensions(h,n) + distance texsetdimen("global","d_strc_math_indent",w) break end @@ -56,13 +54,12 @@ function noads.handlers.align(l) else texsetdimen("global","d_strc_math_indent",distance) end - for n in traverse_id(glue_code,h) do + for n in nextglue, h do setglue(n,getwidth(n),0,0) end else -- texsetdimen("global","d_strc_math_indent",0) end - return l, true end interfaces.implement { diff --git a/tex/context/base/mkiv/math-stc.mkvi b/tex/context/base/mkiv/math-stc.mkvi index c9d469d61..92325d0af 100644 --- a/tex/context/base/mkiv/math-stc.mkvi +++ b/tex/context/base/mkiv/math-stc.mkvi @@ -413,13 +413,13 @@ \fi % \ifdim\wd\scratchboxone<\scratchwidth - \setbox\scratchboxone\hbox to \scratchwidth{\hss\unhbox\scratchboxone\hss}% unhboxing makes leaders work + \setbox\scratchboxone\hpack to \scratchwidth{\hss\unhbox\scratchboxone\hss}% unhboxing makes leaders work \fi \ifdim\wd\scratchboxtwo<\scratchwidth - \setbox\scratchboxtwo\hbox to \scratchwidth{\hss\unhbox\scratchboxtwo\hss}% + \setbox\scratchboxtwo\hpack to \scratchwidth{\hss\unhbox\scratchboxtwo\hss}% \fi \ifdim\wd\scratchboxthree<\scratchwidth - \setbox\scratchboxthree\hbox to \scratchwidth{\hss\unhbox\scratchboxthree\hss}% + \setbox\scratchboxthree\hpack to \scratchwidth{\hss\unhbox\scratchboxthree\hss}% \fi % \ifcsname\??mathstackerslocation\p_location\endcsname @@ -448,7 +448,7 @@ \fi % \ifzeropt\scratchdistance\else - \setbox\scratchboxthree\hbox{\lower\scratchdistance\box\scratchboxthree}% + \setbox\scratchboxthree\hpack{\lower\scratchdistance\box\scratchboxthree}% \fi % \math_stackers_normalize_three @@ -603,7 +603,7 @@ \advance\scratchwidth2\scratchhoffset % \setbox\scratchboxtwo\csname\??mathstackersalternative\p_alternative\endcsname - \setbox\scratchboxthree\hbox to \scratchwidth{\hss\box\scratchboxthree\hss}% + \setbox\scratchboxthree\hpack to \scratchwidth{\hss\box\scratchboxthree\hss}% % \scratchunicode#codeextra\relax \ifcase\scratchunicode\else @@ -803,10 +803,10 @@ \advance\scratchwidth2\scratchhoffset % \ifdim\wd\scratchboxone<\scratchwidth - \setbox\scratchboxone\hbox to \scratchwidth{\hss\unhbox\scratchboxone\hss}% + \setbox\scratchboxone\hpack to \scratchwidth{\hss\unhbox\scratchboxone\hss}% \fi \ifdim\wd\scratchboxthree<\scratchwidth - \setbox\scratchboxthree\hbox to \scratchwidth{\hss\unhbox\scratchboxthree\hss}% + \setbox\scratchboxthree\hpack to \scratchwidth{\hss\unhbox\scratchboxthree\hss}% \fi % \math_stackers_normalize_three diff --git a/tex/context/base/mkiv/math-tag.lua b/tex/context/base/mkiv/math-tag.lua index d1ed90d38..03f9e70bb 100644 --- a/tex/context/base/mkiv/math-tag.lua +++ b/tex/context/base/mkiv/math-tag.lua @@ -14,90 +14,92 @@ if not modules then modules = { } end modules ['math-tag'] = { local find, match = string.find, string.match local insert, remove, concat = table.insert, table.remove, table.concat -local attributes = attributes -local nodes = nodes - -local nuts = nodes.nuts -local tonut = nuts.tonut - -local getnext = nuts.getnext -local getid = nuts.getid -local getchar = nuts.getchar -local getfont = nuts.getfont -local getlist = nuts.getlist -local getfield = nuts.getfield -local getdisc = nuts.getdisc -local getsubtype = nuts.getsubtype -local getattr = nuts.getattr -local setattr = nuts.setattr -local getcomponents = nuts.getcomponents -local getwidth = nuts.getwidth - -local getnucleus = nuts.getnucleus -local getsub = nuts.getsub -local getsup = nuts.getsup - -local set_attributes = nuts.setattributes -local traverse_nodes = nuts.traverse - -local nodecodes = nodes.nodecodes - -local math_noad_code = nodecodes.noad -- attr nucleus sub sup -local math_accent_code = nodecodes.accent -- attr nucleus sub sup accent -local math_radical_code = nodecodes.radical -- attr nucleus sub sup left degree -local math_fraction_code = nodecodes.fraction -- attr nucleus sub sup left right -local math_box_code = nodecodes.subbox -- attr list -local math_sub_code = nodecodes.submlist -- attr list -local math_char_code = nodecodes.mathchar -- attr fam char -local math_textchar_code = nodecodes.mathtextchar -- attr fam char -local math_delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char -local math_style_code = nodecodes.style -- attr style -local math_choice_code = nodecodes.choice -- attr display text script scriptscript -local math_fence_code = nodecodes.fence -- attr subtype - -local accentcodes = nodes.accentcodes - -local math_fixed_top = accentcodes.fixedtop -local math_fixed_bottom = accentcodes.fixedbottom -local math_fixed_both = accentcodes.fixedboth - -local kerncodes = nodes.kerncodes - -local fontkern_code = kerncodes.fontkern -local italickern_code = kerncodes.italickern - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glyph_code = nodecodes.glyph -local disc_code = nodecodes.disc -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local math_code = nodecodes.math - -local processnoads = noads.process - -local a_tagged = attributes.private('tagged') -local a_mathcategory = attributes.private('mathcategory') -local a_mathmode = attributes.private('mathmode') - -local tags = structures.tags - -local start_tagged = tags.start -local restart_tagged = tags.restart -local stop_tagged = tags.stop -local taglist = tags.taglist - -local chardata = characters.data - -local getmathcodes = tex.getmathcodes -local mathcodes = mathematics.codes -local ordinary_code = mathcodes.ordinary -local variable_code = mathcodes.variable - -local fromunicode16 = fonts.mappings.fromunicode16 -local fontcharacters = fonts.hashes.characters - -local report_tags = logs.reporter("structure","tags") +local attributes = attributes +local nodes = nodes + +local nuts = nodes.nuts +local tonut = nuts.tonut + +local getnext = nuts.getnext +local getid = nuts.getid +local getchar = nuts.getchar +local getfont = nuts.getfont +local getlist = nuts.getlist +local getfield = nuts.getfield +local getdisc = nuts.getdisc +local getsubtype = nuts.getsubtype +local getattr = nuts.getattr +local getattrlist = nuts.getattrlist +local setattr = nuts.setattr +local getcomponents = nuts.getcomponents -- not really needed +local getwidth = nuts.getwidth + +local getnucleus = nuts.getnucleus +local getsub = nuts.getsub +local getsup = nuts.getsup + +local set_attributes = nuts.setattributes + +local nextnode = nuts.traversers.node + +local nodecodes = nodes.nodecodes + +local noad_code = nodecodes.noad -- attr nucleus sub sup +local accent_code = nodecodes.accent -- attr nucleus sub sup accent +local radical_code = nodecodes.radical -- attr nucleus sub sup left degree +local fraction_code = nodecodes.fraction -- attr nucleus sub sup left right +local subbox_code = nodecodes.subbox -- attr list +local submlist_code = nodecodes.submlist -- attr list +local mathchar_code = nodecodes.mathchar -- attr fam char +local mathtextchar_code = nodecodes.mathtextchar -- attr fam char +local delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char +local style_code = nodecodes.style -- attr style +local choice_code = nodecodes.choice -- attr display text script scriptscript +local fence_code = nodecodes.fence -- attr subtype + +local accentcodes = nodes.accentcodes + +local fixedtopaccent_code = accentcodes.fixedtop +local fixedbottomaccent_code = accentcodes.fixedbottom +local fixedbothaccent_code = accentcodes.fixedboth + +local kerncodes = nodes.kerncodes + +local fontkern_code = kerncodes.fontkern +local italickern_code = kerncodes.italickern + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local math_code = nodecodes.math + +local processnoads = noads.process + +local a_tagged = attributes.private('tagged') +local a_mathcategory = attributes.private('mathcategory') +local a_mathmode = attributes.private('mathmode') + +local tags = structures.tags + +local start_tagged = tags.start +local restart_tagged = tags.restart +local stop_tagged = tags.stop +local taglist = tags.taglist + +local chardata = characters.data + +local getmathcodes = tex.getmathcodes +local mathcodes = mathematics.codes +local ordinary_mathcode = mathcodes.ordinary +local variable_mathcode = mathcodes.variable + +local fromunicode16 = fonts.mappings.fromunicode16 +local fontcharacters = fonts.hashes.characters + +local report_tags = logs.reporter("structure","tags") local process @@ -154,12 +156,19 @@ local fencesstack = { } -- glyph nodes and such can happen in under and over stuff +-- local function getunicode(n) -- instead of getchar +-- local char = getchar(n) +-- -- local font = font_of_family(getfield(n,"fam")) -- font_of_family +-- local font = getfont(n) +-- local data = fontcharacters[font][char] +-- return data.unicode or char +-- end + local function getunicode(n) -- instead of getchar - local char = getchar(n) - -- local font = font_of_family(getfield(n,"fam")) -- font_of_family - local font = getfont(n) + -- local char, font = isglyph(n) -- no, we have a mathchar + local char, font = getchar(n), getfont(n) local data = fontcharacters[font][char] - return data.unicode or char + return data.unicode or char -- can be a table but unlikely for math characters end ------------------- @@ -167,7 +176,7 @@ end local content = { } local found = false -content[math_char_code] = function() found = true end +content[mathchar_code] = function() found = true end local function hascontent(head) found = false @@ -177,18 +186,25 @@ end -------------------- -local function showtag(n,id) - local attr = getattr(n,a_tagged) - report_tags("%s = %s",nodecodes[id or getid(n)],attr and taglist[attr].tagname or "?") -end +-- todo: use properties + +-- local function showtag(n,id,old) +-- local attr = getattr(n,a_tagged) +-- local curr = tags.current() +-- report_tags("%s, node %s, attr %s:%s (%s), top %s (%s)", +-- old and "before" or "after ", +-- nodecodes[id], +-- getattrlist(n), +-- attr or "?",attr and taglist[attr].tagname or "?", +-- curr or "?",curr and taglist[curr].tagname or "?" +-- ) +-- end process = function(start) -- we cannot use the processor as we have no finalizers (yet) local mtexttag = nil while start do local id = getid(start) - --- showtag(start,id) - + -- showtag(start,id,true) if id == glyph_code or id == disc_code then if not mtexttag then mtexttag = start_tagged("mtext") @@ -201,11 +217,11 @@ process = function(start) -- we cannot use the processor as we have no finalizer stop_tagged() mtexttag = nil end - if id == math_char_code then + if id == mathchar_code then local char = getchar(start) local code = getmathcodes(char) local tag - if code == ordinary_code or code == variable_code then + if code == ordinary_mathcode or code == variable_mathcode then local ch = chardata[char] local mc = ch and ch.mathclass if mc == "number" then @@ -225,8 +241,9 @@ process = function(start) -- we cannot use the processor as we have no finalizer setattr(start,a_tagged,start_tagged(tag)) -- todo: a_mathcategory end stop_tagged() + -- showtag(start,id,false) break -- okay? - elseif id == math_textchar_code then -- or id == glyph_code + elseif id == mathtextchar_code then -- or id == glyph_code -- check for code local a = getattr(start,a_mathcategory) if a then @@ -235,116 +252,127 @@ process = function(start) -- we cannot use the processor as we have no finalizer setattr(start,a_tagged,start_tagged("ms")) -- mtext end stop_tagged() + -- showtag(start,id,false) break - elseif id == math_delim_code then + elseif id == delim_code then -- check for code setattr(start,a_tagged,start_tagged("mo")) stop_tagged() + -- showtag(start,id,false) break - elseif id == math_style_code then + elseif id == style_code then -- has a next - elseif id == math_noad_code then + elseif id == noad_code then + -- setattr(start,a_tagged,tags.current()) processsubsup(start) - elseif id == math_box_code or id == hlist_code or id == vlist_code then - -- keep an eye on math_box_code and see what ends up in there + elseif id == dubbox_code or id == hlist_code or id == vlist_code then + -- keep an eye on subbox_code and see what ends up in there local attr = getattr(start,a_tagged) -if not attr then - -- just skip -else - local specification = taglist[attr] - if specification then - local tag = specification.tagname - if tag == "formulacaption" then - -- skip - elseif tag == "mstacker" then - local list = getlist(start) - if list then - process(list) - end - else - if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then - tag = "mtext" - end - local text = start_tagged(tag) - setattr(start,a_tagged,text) - local list = getlist(start) - if not list then - -- empty list - elseif not attr then - -- box comes from strange place - set_attributes(list,a_tagged,text) -- only the first node ? + if not attr then + -- just skip + else + local specification = taglist[attr] + if specification then + local tag = specification.tagname + if tag == "formulacaption" then + -- skip + elseif tag == "mstacker" then + local list = getlist(start) + if list then + process(list) + end else - -- Beware, the first node in list is the actual list so we definitely - -- need to nest. This approach is a hack, maybe I'll make a proper - -- nesting feature to deal with this at another level. Here we just - -- fake structure by enforcing the inner one. - -- - -- todo: have a local list with local tags that then get appended - -- - local tagdata = specification.taglist - local common = #tagdata + 1 - local function runner(list,depth) -- quite inefficient - local cache = { } -- we can have nested unboxed mess so best local to runner - local keep = nil - -- local keep = { } -- win case we might need to move keep outside - for n in traverse_nodes(list) do - local id = getid(n) - local mth = id == math_code and getsubtype(n) - if mth == 0 then - -- insert(keep,text) - keep = text - text = start_tagged("mrow") - common = common + 1 - end - local aa = getattr(n,a_tagged) - if aa then - local ac = cache[aa] - if not ac then - local tagdata = taglist[aa].taglist - local extra = #tagdata - if common <= extra then - for i=common,extra do - ac = restart_tagged(tagdata[i]) -- can be made faster - end - for i=common,extra do - stop_tagged() -- can be made faster + if tag ~= "mstackertop" and tag ~= "mstackermid" and tag ~= "mstackerbot" then + tag = "mtext" + end + local text = start_tagged(tag) + setattr(start,a_tagged,text) + local list = getlist(start) + if not list then + -- empty list + elseif not attr then + -- box comes from strange place + set_attributes(list,a_tagged,text) -- only the first node ? + else + -- Beware, the first node in list is the actual list so we definitely + -- need to nest. This approach is a hack, maybe I'll make a proper + -- nesting feature to deal with this at another level. Here we just + -- fake structure by enforcing the inner one. + -- + -- todo: have a local list with local tags that then get appended + -- + local tagdata = specification.taglist + local common = #tagdata + 1 + local function runner(list,depth) -- quite inefficient + local cache = { } -- we can have nested unboxed mess so best local to runner + local keep = nil + -- local keep = { } -- win case we might need to move keep outside + for n, id, subtype in nextnode, list do + local mth = id == math_code and subtype + if mth == 0 then -- hm left_code + -- insert(keep,text) + keep = text + text = start_tagged("mrow") + common = common + 1 + end + local aa = getattr(n,a_tagged) + if aa then + local ac = cache[aa] + if not ac then + local tagdata = taglist[aa].taglist + local extra = #tagdata + if common <= extra then + for i=common,extra do + ac = restart_tagged(tagdata[i]) -- can be made faster + end + for i=common,extra do + stop_tagged() -- can be made faster + end + else + ac = text end - else - ac = text + cache[aa] = ac end - cache[aa] = ac + setattr(n,a_tagged,ac) + else + setattr(n,a_tagged,text) + end + if id == hlist_code or id == vlist_code then + runner(getlist(n),depth+1) + elseif id == glyph_code then + -- this should not be needed + local components = getcomponents(n) -- unlikely set + if components then + runner(getcomponent,depth+1) + end + elseif id == disc_code then + -- this should not be needed + local pre, post, replace = getdisc(n) + if pre then + runner(pre,depth+1) + end + if post then + runner(post,depth+1) + end + if replace then + runner(replace,depth+1) + end + end + if mth == 1 then + stop_tagged() + -- text = remove(keep) + text = keep + common = common - 1 end - setattr(n,a_tagged,ac) - else - setattr(n,a_tagged,text) - end - - if id == hlist_code or id == vlist_code then - runner(getlist(n),depth+1) - elseif id == glyph_code then - -- this should not be needed (todo: use tounicode info) - runner(getcomponents(n),depth+1) - elseif id == disc_code then - local pre, post, replace = getdisc(n) - runner(pre,depth+1) -- idem - runner(post,depth+1) -- idem - runner(replace,depth+1) -- idem - end - if mth == 1 then - stop_tagged() - -- text = remove(keep) - text = keep - common = common - 1 end end + runner(list,0) end - runner(list,0) + stop_tagged() end - stop_tagged() end end -end - elseif id == math_sub_code then -- normally a hbox + elseif id == submlistcode then -- normally a hbox local list = getlist(start) if list then local attr = getattr(start,a_tagged) @@ -370,7 +398,7 @@ end end elseif tag == "mstacker" then -- or tag == "mstackertop" or tag == "mstackermid" or tag == "mstackerbot" then -- looks like it gets processed twice --- do we still end up here ? + -- do we still end up here ? setattr(start,a_tagged,restart_tagged(attr)) -- so we just reuse the attribute process(list) stop_tagged() @@ -385,7 +413,7 @@ end stop_tagged() end end - elseif id == math_fraction_code then + elseif id == fraction_code then local num = getfield(start,"num") local denom = getfield(start,"denom") local left = getfield(start,"left") @@ -404,7 +432,7 @@ end process(right) stop_tagged() end - elseif id == math_choice_code then + elseif id == choice_code then local display = getfield(start,"display") local text = getfield(start,"text") local script = getfield(start,"script") @@ -421,7 +449,7 @@ end if scriptscript then process(scriptscript) end - elseif id == math_fence_code then + elseif id == fence_code then local delim = getfield(start,"delim") local subtype = getfield(start,"subtype") if subtype == 1 then @@ -478,7 +506,7 @@ end else -- can't happen end - elseif id == math_radical_code then + elseif id == radical_code then local left = getfield(start,"left") local degree = getfield(start,"degree") if left then @@ -496,7 +524,7 @@ end processsubsup(start) stop_tagged() end - elseif id == math_accent_code then + elseif id == accent_code then local accent = getfield(start,"accent") local bot_accent = getfield(start,"bot_accent") local subtype = getsubtype(start) @@ -506,8 +534,8 @@ end accent = true, top = getunicode(accent), bottom = getunicode(bot_accent), - topfixed = subtype == math_fixed_top or subtype == math_fixed_both, - bottomfixed = subtype == math_fixed_bottom or subtype == math_fixed_both, + topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code, + bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code, })) processsubsup(start) process(bot_accent) @@ -517,7 +545,7 @@ end setattr(start,a_tagged,start_tagged("munder", { accent = true, bottom = getunicode(bot_accent), - bottomfixed = subtype == math_fixed_bottom or subtype == math_fixed_both, + bottomfixed = subtype == fixedbottomaccent_code or subtype == fixedbothaccent_code, })) processsubsup(start) process(bot_accent) @@ -527,7 +555,7 @@ end setattr(start,a_tagged,start_tagged("mover", { accent = true, top = getunicode(accent), - topfixed = subtype == math_fixed_top or subtype == math_fixed_both, + topfixed = subtype == fixedtopaccent_code or subtype == fixedbothaccent_code, })) processsubsup(start) process(accent) @@ -544,6 +572,7 @@ end stop_tagged() end end +-- showtag(start,id,false) start = getnext(start) end if mtexttag then @@ -552,12 +581,10 @@ end end function noads.handlers.tags(head,style,penalties) - head = tonut(head) - local v_mode = getattr(head,a_mathmode) - local v_math = start_tagged("math", { mode = v_mode == 1 and "display" or "inline" }) + start_tagged("math", { mode = (getattr(head,a_mathmode) == 1) and "display" or "inline" }) +-- start_tagged("mrow") setattr(head,a_tagged,start_tagged("mrow")) process(head) stop_tagged() stop_tagged() - return true end diff --git a/tex/context/base/mkiv/math-vfu.lua b/tex/context/base/mkiv/math-vfu.lua index 4767ffa90..ed6f69f41 100644 --- a/tex/context/base/mkiv/math-vfu.lua +++ b/tex/context/base/mkiv/math-vfu.lua @@ -46,9 +46,18 @@ fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vecto local vfmath = allocate() fonts.handlers.vf.math = vfmath +local helpers = fonts.helpers +local vfcommands = helpers.commands +local rightcommand = vfcommands.right +local leftcommand = vfcommands.left +local downcommand = vfcommands.down +local upcommand = vfcommands.up +local push = vfcommands.push +local pop = vfcommands.pop + local shared = { } --- local push, pop, back = { "push" }, { "pop" }, { "slot", 1, 0x2215 } +-- local back = { "slot", 1, 0x2215 } -- -- local function negate(main,characters,id,size,unicode,basecode) -- if not characters[unicode] then @@ -64,8 +73,8 @@ local shared = { } -- commands = { -- { "slot", 1, basecode }, -- push, --- { "down", ht/5}, --- { "right", - wd/2}, +-- downcommand[ht/5], +-- leftcommand[wd/2], -- back, -- push, -- } @@ -139,107 +148,96 @@ local function parent(main,characters,id,size,unicode,first,rule,last) end end -local push, pop, step = { "push" }, { "pop" }, 0.2 -- 0.1 is nicer but gives larger files +local step = 0.2 -- 0.1 is nicer but gives larger files local function make(main,characters,id,size,n,m) local old = 0xFF000 + n - local c = characters[old] + local c = characters[old] if c then - local upslot, dnslot, uprule, dnrule = 0xFF100 + n, 0xFF200 + n, 0xFF300 + m, 0xFF400 + m - local xu = main.parameters.x_height + 0.3*size - local xd = 0.3*size - local w, h, d = c.width, c.height, c.depth + local upslot = 0xFF100 + n + local dnslot = 0xFF200 + n + local uprule = 0xFF300 + m + local dnrule = 0xFF400 + m + local xu = main.parameters.x_height + 0.3*size + local xd = 0.3*size + local w = c.width or 0 + local h = c.height or 0 + local d = c.depth or 0 local thickness = h - d local rulewidth = step*size -- we could use an overlap - local slot = { "slot", id, old } - local rule = { "rule", thickness, rulewidth } - local up = { "down", -xu } - local dn = { "down", xd } - local ht, dp = xu + 3*thickness, 0 + local slot = { "slot", id, old } + local rule = { "rule", thickness, rulewidth } + local up = upcommand[xu] + local dn = downcommand[xd] + local ht = xu + 3*thickness + local dp = 0 if not characters[uprule] then - characters[uprule] = { width = rulewidth, height = ht, depth = dp, commands = { push, up, rule, pop } } + characters[uprule] = { + width = rulewidth, + height = ht, + depth = dp, + commands = { push, up, rule, pop }, + } end - characters[upslot] = { width = w, height = ht, depth = dp, commands = { push, up, slot, pop } } - local ht, dp = 0, xd + 3*thickness + characters[upslot] = { + width = w, + height = ht, + depth = dp, + commands = { push, up, slot, pop }, + } + local ht = 0 + local dp = xd + 3*thickness if not characters[dnrule] then - characters[dnrule] = { width = rulewidth, height = ht, depth = dp, commands = { push, dn, rule, pop } } + characters[dnrule] = { + width = rulewidth, + height = ht, + depth = dp, + commands = { push, dn, rule, pop } + } end - characters[dnslot] = { width = w, height = ht, depth = dp, commands = { push, dn, slot, pop } } + characters[dnslot] = { + width = w, + height = ht, + depth = dp, + commands = { push, dn, slot, pop }, + } end end local function clipped(main,characters,id,size,unicode,original) -- push/pop needed? local minus = characters[original] if minus then - local mu = size/18 - local step = 3*mu + local mu = size/18 + local step = 3*mu local width = minus.width if width > step then width = width - step - step = step / 2 + step = step / 2 else width = width / 2 - step = width + step = width end characters[unicode] = { width = width, height = minus.height, depth = minus.depth, - commands = { push, { "right", -step }, { "slot", id, original }, pop } + commands = { + push, + leftcommand[step], + { "slot", id, original }, + pop, + } } end end --- fails: pdf:page: pdf:direct: ... some funny displacement - --- this does not yet work ... { "scale", 2, 0, 0, 3 } .. commented code --- --- this does not work ... no interpretation going on here --- --- local nodeinjections = backends.nodeinjections --- { "node", nodeinjections.save() }, --- { "node", nodeinjections.transform(.7,0,0,.7) }, --- commands[#commands+1] = { "node", nodeinjections.restore() } - --- local done = { } --- --- local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess --- local raised = characters[private] --- if raised then --- if not done[unicode] then --- report_virtual("temporary too large %U due to issues in luatex backend",unicode) --- done[unicode] = true --- end --- local up = 0.85 * main.parameters.x_height --- local slot = { "slot", id, private } --- local commands = { --- push, --- { "down", - up }, --- -- { "scale", .7, 0, 0, .7 }, --- slot, --- } --- for i=2,n do --- commands[#commands+1] = slot --- end --- commands[#commands+1] = pop --- characters[unicode] = { --- width = .7 * n * raised.width, --- height = .7 * (raised.height + up), --- depth = .7 * (raised.depth - up), --- commands = commands, --- } --- end --- end - local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess local raised = fonts.hashes.characters[main.fonts[id_of_smaller].id][private] -- characters[private] if raised then - local up = 0.85 * main.parameters.x_height + local up = 0.85 * main.parameters.x_height local slot = { "slot", id_of_smaller, private } local commands = { - push, - { "down", - up }, - slot, + push, upcommand[up], slot, } for i=2,n do commands[#commands+1] = slot @@ -258,65 +256,85 @@ end local function dots(main,characters,id,size,unicode) local c = characters[0x002E] if c then - local w, h, d = c.width, c.height, c.depth - local mu = size/18 - local right3mu = { "right", 3*mu } - local right1mu = { "right", 1*mu } - local up1size = { "down", -.1*size } - local up4size = { "down", -.4*size } - local up7size = { "down", -.7*size } - local right2muw = { "right", 2*mu + w } - local slot = { "slot", id, 0x002E } + local w = c.width + local h = c.height + local d = c.depth + local mu = size/18 + local right3mu = rightcommand[3*mu] + local right1mu = rightcommand[1*mu] + local up1size = upcommand[.1*size] + local up4size = upcommand[.4*size] + local up7size = upcommand[.7*size] + local right2muw = rightcommand[2*mu + w] + local slot = { "slot", id, 0x002E } if unicode == 0x22EF then local c = characters[0x022C5] if c then - local w, h, d = c.width, c.height, c.depth - local slot = { "slot", id, 0x022C5 } + local width = c.width + local height = c.height + local depth = c.depth + local slot = { "slot", id, 0x022C5 } characters[unicode] = { - width = 3*w + 2*3*mu, height = h, depth = d, - commands = { push, slot, right3mu, slot, right3mu, slot, pop } + width = 3*width + 2*3*mu, + height = height, + depth = depth, + commands = { + push, slot, right3mu, slot, right3mu, slot, pop, + } } end elseif unicode == 0x22EE then -- weird height ! characters[unicode] = { - width = w, height = h+(1.4)*size, depth = 0, - commands = { push, push, slot, pop, up4size, push, slot, pop, up4size, slot, pop } + width = w, + height = h+(1.4)*size, + depth = 0, + commands = { + push, push, slot, pop, up4size, push, slot, pop, up4size, slot, pop, + } } elseif unicode == 0x22F1 then characters[unicode] = { - width = 3*w + 6*size/18, height = 1.5*size, depth = 0, + width = 3*w + 6*size/18, + height = 1.5*size, + depth = 0, commands = { push, - right1mu, - push, up7size, slot, pop, - right2muw, - push, up4size, slot, pop, - right2muw, - push, up1size, slot, pop, - right1mu, + right1mu, + push, up7size, slot, pop, + right2muw, + push, up4size, slot, pop, + right2muw, + push, up1size, slot, pop, + right1mu, pop } } elseif unicode == 0x22F0 then characters[unicode] = { - width = 3*w + 6*size/18, height = 1.5*size, depth = 0, + width = 3*w + 6*size/18, + height = 1.5*size, + depth = 0, commands = { push, - right1mu, - push, up1size, slot, pop, - right2muw, - push, up4size, slot, pop, - right2muw, - push, up7size, slot, pop, - right1mu, + right1mu, + push, up1size, slot, pop, + right2muw, + push, up4size, slot, pop, + right2muw, + push, up7size, slot, pop, + right1mu, pop } } else characters[unicode] = { - width = 3*w + 2*3*mu, height = h, depth = d, - commands = { push, slot, right3mu, slot, right3mu, slot, pop } + width = 3*w + 2*3*mu, + height = h, + depth = d, + commands = { + push, slot, right3mu, slot, right3mu, slot, pop, + } } end end @@ -331,21 +349,23 @@ local function vertbar(main,characters,id,size,parent,scale,unicode) width = cp.width, height = cp.height + sc, depth = cp.depth + sc, + next = cp.next, -- can be extensible commands = { - push, { "down", -sc }, pc, pop, - push, { "down", sc }, pc, pop, + push, upcommand [sc], pc, pop, + push, downcommand[sc], pc, pop, pc, }, - next = cp.next -- can be extensible } cp.next = unicode end end local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what) - local c1, c2 = characters[u1], characters[u2] + local c1 = characters[u1] + local c2 = characters[u2] if c1 and c2 then - local w1, w2 = c1.width, c2.width + local w1 = c1.width + local w2 = c2.width local mu = size/18 characters[unicode] = { width = w1 + w2 - d12 * mu, @@ -353,7 +373,7 @@ local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what) depth = max(c1.depth or 0, c2.depth or 0), commands = { { "slot", id, u1 }, - { "right", -d12*mu } , + leftcommand[d12*mu], { "slot", id, u2 }, }, } @@ -361,19 +381,23 @@ local function jointwo(main,characters,id,size,unicode,u1,d12,u2,what) end local function jointhree(main,characters,id,size,unicode,u1,d12,u2,d23,u3) - local c1, c2, c3 = characters[u1], characters[u2], characters[u3] + local c1 = characters[u1] + local c2 = characters[u2] + local c3 = characters[u3] if c1 and c2 and c3 then - local w1, w2, w3 = c1.width, c2.width, c3.width + local w1 = c1.width + local w2 = c2.width + local w3 = c3.width local mu = size/18 characters[unicode] = { width = w1 + w2 + w3 - d12*mu - d23*mu, height = max(c1.height or 0, c2.height or 0, c3.height or 0), - depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0), + depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0), commands = { { "slot", id, u1 }, - { "right", - d12*mu } , + leftcommand[d12*mu], { "slot", id, u2 }, - { "right", - d23*mu }, + leftcommand[d23*mu], { "slot", id, u3 }, } } @@ -381,24 +405,32 @@ local function jointhree(main,characters,id,size,unicode,u1,d12,u2,d23,u3) end local function stack(main,characters,id,size,unicode,u1,d12,u2) - local c1, c2 = characters[u1], characters[u2] - if c1 and c2 then - local w1, w2 = c1.width, c2.width - local h1, h2 = c1.height, c2.height - local d1, d2 = c1.depth, c2.depth - local mu = size/18 - characters[unicode] = { - width = w1, - height = h1 + h2 + d12, - depth = d1, - commands = { - { "slot", id, u1 }, - { "right", - w1/2 - w2/2 } , - { "down", -h1 + d2 -d12*mu } , - { "slot", id, u2 }, - } - } + local c1 = characters[u1] + if not c1 then + return + end + local c2 = characters[u2] + if not c2 then + return end + local w1 = c1.width or 0 + local h1 = c1.height or 0 + local d1 = c1.depth or 0 + local w2 = c2.width or 0 + local h2 = c2.height or 0 + local d2 = c2.depth or 0 + local mu = size/18 + characters[unicode] = { + width = w1, + height = h1 + h2 + d12, + depth = d1, + commands = { + { "slot", id, u1 }, + leftcommand[w1/2 + w2/2], + downcommand[-h1 + d2 -d12*mu], + { "slot", id, u2 }, + } + } end local function repeated(main,characters,id,size,unicode,u,n,private,fraction) -- math-fbk.lua @@ -406,16 +438,14 @@ local function repeated(main,characters,id,size,unicode,u,n,private,fraction) -- if c then local width = c.width local italic = fraction*width -- c.italic or 0 -- larger ones have funny italics - local tc = { "slot", id, u } - local tr = { "right", -italic } -- see hack elsewhere + local tc = { "slot", id, u } + local tr = leftcommand[italic] -- see hack elsewhere local commands = { } for i=1,n-1 do commands[#commands+1] = tc commands[#commands+1] = tr end commands[#commands+1] = tc --- inspect(c) --- inspect(commands) local next = c.next if next then repeated(main,characters,id,size,private,next,n,private+1,fraction) @@ -589,7 +619,8 @@ setmetatableindex(reverse, function(t,name) if trace_virtual then report_virtual("initializing math vector %a",name) end - local m, r = mathencodings[name], { } + local m = mathencodings[name] + local r = { } for u, i in next, m do r[i] = u end @@ -597,6 +628,10 @@ setmetatableindex(reverse, function(t,name) return r end) +-- use char and font hash +-- +-- commands = { { "font", slot }, { "char", unicode } }, + local function copy_glyph(main,target,original,unicode,slot) local addprivate = fonts.helpers.addprivate local olddata = original[unicode] @@ -623,7 +658,6 @@ local function copy_glyph(main,target,original,unicode,slot) } local newnextglyph = addprivate(main,formatters["M-N-%H"](nextglyph),newnextdata) newdata.next = newnextglyph --- report_virtual("copied next: %X",newdata.next) local nextnextglyph = oldnextdata.next if nextnextglyph == nextglyph then break @@ -649,7 +683,6 @@ local function copy_glyph(main,target,original,unicode,slot) commands = { { "slot", slot, oldglyph } }, } hvi.glyph = addprivate(main,formatters["M-H-%H"](oldglyph),newdata) --- report_virtual("copied h variant: %X at index %i",hvi.glyph,i) end end local vv = olddata.vert_variants @@ -668,7 +701,6 @@ local function copy_glyph(main,target,original,unicode,slot) commands = { { "slot", slot, oldglyph } }, } vvi.glyph = addprivate(main,formatters["M-V-%H"](oldglyph),newdata) --- report_virtual("copied v variant: %X at index %i",vvi.glyph,i) end end return newdata @@ -678,13 +710,17 @@ end vfmath.copy_glyph = copy_glyph function vfmath.define(specification,set,goodies) - local name = specification.name -- symbolic name - local size = specification.size -- given size - local loaded, fontlist, names, main = { }, { }, { }, nil - local start = (trace_virtual or trace_timings) and os.clock() - local okset, n = { }, 0 + local name = specification.name -- symbolic name + local size = specification.size -- given size + local loaded = { } + local fontlist = { } + local names = { } + local main = nil + local start = (trace_virtual or trace_timings) and os.clock() + local okset = { } + local n = 0 for s=1,#set do - local ss = set[s] + local ss = set[s] local ssname = ss.name if add_optional and ss.optional then if trace_virtual then @@ -828,11 +864,11 @@ function vfmath.define(specification,set,goodies) elseif add_optional and ss.optional then -- skip, redundant else - local newparameters = fs.parameters + local newparameters = fs.parameters local newmathparameters = fs.mathparameters if newmathparameters then if not parameters_done or ss.parameters then - mathparameters = newmathparameters + mathparameters = newmathparameters parameters_done = true end elseif not newparameters then @@ -867,7 +903,7 @@ function vfmath.define(specification,set,goodies) -- report_virtual("loading and virtualizing font %a at size %p, setting sy parameters",name,size) end if ss.overlay then - local fc = fs.characters + local fc = fs.characters local first = ss.first if first then local last = ss.last or first @@ -882,12 +918,14 @@ function vfmath.define(specification,set,goodies) else local vectorname = ss.vector if vectorname then - local offset = 0xFF000 - local vector = mathencodings[vectorname] - local rotcev = reverse[vectorname] + local offset = 0xFF000 + local vector = mathencodings[vectorname] + local rotcev = reverse[vectorname] local isextension = ss.extension if vector and rotcev then - local fc, fd, si = fs.characters, fs.descriptions, shared[s] + local fc = fs.characters + local fd = fs.descriptions + local si = shared[s] local skewchar = ss.skewchar for unicode, index in next, vector do local fci = fc[index] @@ -913,8 +951,8 @@ function vfmath.define(specification,set,goodies) ref = { { 'slot', s, index } } si[index] = ref end - local kerns = fci.kerns - local width = fci.width + local kerns = fci.kerns + local width = fci.width local italic = fci.italic if italic and italic > 0 then -- int_a^b diff --git a/tex/context/base/mkiv/meta-blb.lua b/tex/context/base/mkiv/meta-blb.lua new file mode 100644 index 000000000..e1c0de74f --- /dev/null +++ b/tex/context/base/mkiv/meta-blb.lua @@ -0,0 +1,322 @@ +if not modules then modules = { } end modules ['meta-blb'] = { + version = 1.001, + comment = "companion to mlib-ctx.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files", +} + +-- This could be integrated in other modules but for me it also serves +-- as an example of usign the plugin mechanism. + +local tonumber = tonumber + +local setmetatableindex = table.setmetatableindex +local insert, remove = table.insert, table.remove +local formatters = string.formatters + +local topoints = number.topoints +local mpprint = mp.print +local mpinteger = mp.integer +local mppoints = mp.points +local mptriplet = mp.triplet +local mptripletpoints = mp.tripletpoints + +local nuts = nodes.nuts +local hpack = nuts.hpack +local setbox = nuts.setbox +local getwhd = nuts.getwhd +local getwidth = nuts.getwidth +local toutf = nuts.toutf + +local trace = false +local report = logs.reporter("metapost","blobs") + +trackers.register("metapost.blobs", function(v) trace = v end) + +local allblobs = { } + +local function newcategory(t,k) + if trace then + report("new category %a",k) + end + local v = { + name = k, + text = "", + blobs = { }, + } + t[k] = v + return v +end + +local texblobs = setmetatableindex(newcategory) + +local function blob_raw_reset(category) + -- we need to keep the allblobs + if category then + if trace then + report("reset category %a",category) + end + texblobs[category] = nil + else + if trace then + report("reset all") + end + texblobs = setmetatableindex(newcategory) + end +end + +local function blob_raw_dimensions(i) + local blob = allblobs[i] + if blob then + return getwhd(blob) + else + return 0, 0, 0 + end +end + +local function blob_raw_content(i) + return allblobs[i] +end + +local function blob_raw_toutf(i) + return toutf(allblobs[i]) +end + +local function blob_raw_wipe(i) + allblobs[i] = false +end + +mp.mf_blob_raw_dimensions = blob_raw_dimensions +mp.mf_blob_raw_content = blob_raw_content +mp.mf_blob_raw_reset = blob_raw_reset +mp.mf_blob_raw_wipe = blob_raw_wipe +mp.mf_blob_raw_toutf = blob_raw_toutf + +function mp.mf_blob_new(category,text) + if trace then + report("category %a, text %a",category,text) + end + texblobs[category].text = text +end + +function mp.mf_blob_add(category,blob) + local tb = texblobs[category].blobs + local tn = #allblobs + 1 + blob = hpack(blob) + allblobs[tn] = blob + tb[#tb+1] = tn + if trace then + report("category %a, blob %a set, content %a",category,tn,blob_raw_toutf(tn)) + end +end + +function mp.mf_blob_width(category,i) + local index = texblobs[category].blobs[i] + local blob = allblobs[index] + if blob then + mppoints(getwidth(blob) or 0) + else + mpinteger(0) + end +end + +function mp.mf_blob_size(category,i) + mpprint(#texblobs[category].blobs or 0) +end + +function mp.mf_blob_index(category,i) + mpprint(texblobs[category].blobs[i] or 0) +end + +function mp.mf_blob_dimensions(category,i) + local index = texblobs[category].blobs[i] + local blob = allblobs[index] + if blob then + mptripletpoints(getwhd(blob)) + else + mptriplet(0,0,0) + end +end + +local sxsy = metapost.sxsy +local cm = metapost.cm + +local f_f = formatters["%.6F"] + +directives.register("pdf.stripzeros",function() + f_f = formatters["%.6N"] +end) + +local function injectblob(object,blob) + local sx, rx, ry, sy, tx, ty = cm(object) + local wd, ht, dp = blob_raw_dimensions(blob) + if wd then + object.path = false + object.color = false + object.grouped = true + object.istext = true + return function() + if trace then + report("injecting blob %a, width %p, heigth %p, depth %p, text %a",blob,wd,ht,dp,blob_raw_toutf(blob)) + end + context.MPLIBgetblobscaledcm(blob, + f_f(sx), f_f(rx), f_f(ry), + f_f(sy), f_f(tx), f_f(ty), + sxsy(wd,ht,dp)) + end + end +end + +-- mp.mf_blob_inject = injectblob + +local function getblob(box,blob) + setbox(box,blob_raw_content(blob)) + blob_raw_wipe(blob) +end + +interfaces.implement { + name = "mpgetblob", + actions = getblob, + arguments = { "integer", "integer" }, +} + +-- the plug: + + +local function reset() + blob_raw_reset() +end + +local function process(object,prescript,before,after) +-- if prescript.tb_stage == "inject" then + local tb_blob = tonumber(prescript.tb_blob) + if tb_blob then + before[#before+1] = injectblob(object,tb_blob) + end +-- end +end + +metapost.installplugin { + name = "texblob", + reset = reset, + process = process, +} + +-- Here follows an example of usage of the above: a more modern +-- version of followokens (in meta-imp-txt.mkiv). + +local nodecodes = nodes.nodecodes +local kerncodes = nodes.kerncodes + +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern + +local fontkern_code = kerncodes.fontkern +local italickern_code = kerncodes.italickern + +local a_fontkern = attributes.private("fontkern") + +local nuts = nodes.nuts +local takebox = nuts.takebox +local getlist = nuts.getlist +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local setlink = nuts.setlink +local setlist = nuts.setlist +local getnext = nuts.getnext +local flatten_list = nuts.flatten_discretionaries +local remove_node = nuts.remove +local flush_node = nuts.flush + +local addblob = mp.mf_blob_add +local newblob = mp.mf_blob_new + +local visible_codes = { + [nodecodes.glyph] = true, + [nodecodes.glue] = true, + [nodecodes.hlist] = true, + [nodecodes.vlist] = true, + [nodecodes.rule] = true, +} + +local function initialize(category,box) + local wrap = takebox(box) + if wrap then + local head = getlist(wrap) + local tail = nil + local temp = nil + if head then + local n = { } + local s = 0 + head = flatten_list(head) + local current = head + while current do + local id = getid(current) + if visible_codes[id] then + head, current, tail = remove_node(head,current) + s = s + 1 + n[s] = tail + elseif id == kern_code then + local subtype = getsubtype(current) + if subtype == fontkern_code or subtype == italickern_code then -- or current[a_fontkern] + head, current, temp = remove_node(head,current) + setlink(tail,temp) + else + head, current, temp = remove_node(head,current) + s = s + 1 + n[s] = temp + end + elseif id == glue_code then + head, current, temp = remove_node(head,current) + s = s + 1 + n[s] = temp + else + current = getnext(current) + end + end + for i=1,s do + n[i] = addblob(category,n[i]) + end + setlist(wrap,head) + end + flush_node(wrap) + end +end + +interfaces.implement { + name = "MPLIBconvertfollowtext", + arguments = { "integer","integer" }, + actions = initialize, +} + +local mp_category = 0 +local mp_str = "" + +function mp.mf_inject_blob(category,str) + newblob(category,str) -- only for tracing + mp_category = category + mp_str = str + tex.runtoks("mpblobtext") +end + +interfaces.implement { + name = "mpblobtext", + actions = function() + context.MPLIBfollowtext(mp_category,mp_str) + end +} + +local process = function(object,prescript,before,after) + if prescript.ft_category then + object.path = false + object.color = false + object.grouped = true + object.istext = true + end +end + +metapost.installplugin { + name = "followtext", + process = process, +} diff --git a/tex/context/base/mkiv/meta-blb.mkiv b/tex/context/base/mkiv/meta-blb.mkiv new file mode 100644 index 000000000..4a5381dfc --- /dev/null +++ b/tex/context/base/mkiv/meta-blb.mkiv @@ -0,0 +1,56 @@ +%D \module +%D [ file=meta-blb, +%D version=2018.04.12, +%D title=\METAPOST\ Graphics, +%D subtitle=Blobs, +%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}{MetaPost Graphics / Blobs} + +\registerctxluafile{meta-blb}{} + +\unprotect + +\unexpanded\def\MPLIBgetblobscaledcm#1#2#3#4#5#6#7#8#9% + {\clf_mpgetblob\MPtextbox#1\relax + \setbox\MPbox\hpack\bgroup + \dotransformnextbox{#2}{#3}{#4}{#5}{#6}{#7}% + \vpack to \zeropoint\bgroup + \vss + \hpack to \zeropoint \bgroup + % \fastsxsy{#8}{#9}{\raise\dp\MPtextbox\box\MPtextbox}% + \fastsxsy{#8}{#9}{\box\MPtextbox}% + \hss + \egroup + \egroup + \egroup + \smashbox\MPbox + \box\MPbox} + +%D An example of usage: + +\definefontfeature[followtext][liga=no] + +\unexpanded\def\MPLIBfollowtext#1#2% + {\begingroup + \scratchcounter#1\relax + \setbox\scratchbox\hbox{\addff{followtext}#2}% + \clf_MPLIBconvertfollowtext\scratchcounter\scratchbox + \endgroup} + +% \def\reversedtext#1% +% {\cldcontext{table.concat(table.reverse(utf.totable(\!!bs#1\!!es)))}} + +%D New: + +\newtoks\mpblobtext + +\mpblobtext{\global\setbox\mptextbox\vbox{\clf_mpblobtext}} + +\protect \endinput diff --git a/tex/context/base/mkiv/meta-fnt.lua b/tex/context/base/mkiv/meta-fnt.lua index d061c926a..69212d08c 100644 --- a/tex/context/base/mkiv/meta-fnt.lua +++ b/tex/context/base/mkiv/meta-fnt.lua @@ -108,19 +108,17 @@ local function process(mpxformat,name,instances,scalefactor) for i=1,instances do characters = { } descriptions = { } - metapost.process( - mpxformat, - { + metapost.process { + mpx = mpxformat, + flusher = flusher, + askedfig = "all", + -- incontext = false, + data = { formatters["randomseed := %s ;"](i*10), formatters["charscale := %s ;"](scalefactor), data, }, - false, - flusher, - false, - false, - "all" - ) + } lists[i] = { characters = characters, descriptions = descriptions, @@ -191,9 +189,9 @@ statistics.register("metapost font generation", function() if total > 0 then local time = statistics.elapsedtime(flusher) if total > 0 then - return format("%i glyphs, %.3f seconds runtime, %.1f glyphs/second", total, time, total/time) + return format("%i glyphs, %s seconds runtime, %.1f glyphs/second", total, time, total/tonumber(time)) else - return format("%i glyphs, %.3f seconds runtime", total, time) + return format("%i glyphs, %s seconds runtime", total, time) end end end) @@ -202,9 +200,9 @@ statistics.register("metapost font loading",function() if variants > 0 then local time = statistics.elapsedtime(metapost.fonts) if variants > 0 then - return format("%.3f seconds, %i instances, %.3f instances/second", time, variants, variants/time) + return format("%s seconds, %i instances, %.3f instances/second", time, variants, variants/tonumber(time)) else - return format("%.3f seconds, %i instances", time, variants) + return format("%s seconds, %i instances", time, variants) end end end) diff --git a/tex/context/base/mkiv/meta-imp-dum.mkiv b/tex/context/base/mkiv/meta-imp-dum.mkiv index e6ccc234c..481afe82a 100644 --- a/tex/context/base/mkiv/meta-imp-dum.mkiv +++ b/tex/context/base/mkiv/meta-imp-dum.mkiv @@ -59,7 +59,7 @@ % clip currentpicture to p ; % \stopuseMPgraphic -\startuseMPgraphic{figure:placeholder}{width,height,reduction,color} +\startuseMPgraphic{minifun::figure:placeholder}{width,height,reduction,color} begingroup ; save w, h, d, r, p, c, b ; numeric w, h, d, r ; path p ; @@ -88,7 +88,7 @@ \defineoverlay [figure:placeholder:graphic] [\useMPgraphic - {figure:placeholder}% + {minifun::figure:placeholder}% {width=\figurewidth,% height=\figureheight,% reduction=\externalfigureparameter\c!reduction,% diff --git a/tex/context/base/mkiv/meta-imp-mat.mkiv b/tex/context/base/mkiv/meta-imp-mat.mkiv index 19a5ba385..495864a9e 100644 --- a/tex/context/base/mkiv/meta-imp-mat.mkiv +++ b/tex/context/base/mkiv/meta-imp-mat.mkiv @@ -15,8 +15,16 @@ % % / for cambria -\startMPextensions +%D We need this for Alan, who nests math in \METAPOST: + +\unprotect + +\setupmathstackers + [\c!mp=minifun::math:stacker:\number\scratchunicode] +\protect + +\startMPextensions vardef math_stacker_bracket_shape(expr delta, rotate) = image ( draw @@ -129,55 +137,55 @@ enddef ; \stopMPextensions -\startuniqueMPgraphic{math:stacker:\number"FE3B4}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE3B4}{axis,ex,em} math_stacker_draw_accent(math_stacker_bracket_shape(OverlayHeight,false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE3B5}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE3B5}{axis,ex,em} math_stacker_draw_accent(math_stacker_bracket_shape(OverlayDepth,true)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE3DC}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DC}{axis,ex,em} math_stacker_draw_accent(math_stacker_parent_shape(OverlayHeight,false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE3DD}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DD}{axis,ex,em} math_stacker_draw_accent(math_stacker_parent_shape(OverlayDepth,true)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE3DE}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DE}{axis,ex,em} math_stacker_draw_accent(math_stacker_brace_shape(OverlayHeight,false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE3DF}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE3DF}{axis,ex,em} math_stacker_draw_accent(math_stacker_brace_shape(OverlayDepth,true)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE33E}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE33E}{axis,ex,em} math_stacker_draw_accent(math_stacker_bar_shape(false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"FE33F}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"FE33F}{axis,ex,em} math_stacker_draw_accent(math_stacker_bar_shape(true)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"2190}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"2190}{axis,ex,em} math_stacker_draw_arrow(math_stacker_arrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"2192}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"2192}{axis,ex,em} math_stacker_draw_arrow(math_stacker_arrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},true)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"2194}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"2194}{axis,ex,em} math_stacker_draw_arrow(math_stacker_leftrightarrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"27F7}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"27F7}{axis,ex,em} math_stacker_draw_arrow(math_stacker_leftrightarrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ; \stopuniqueMPgraphic -\startuniqueMPgraphic{math:stacker:\number"21C4}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:stacker:\number"21C4}{axis,ex,em} math_stacker_draw_arrow(math_stacker_rightoverleftarrow_shape(\MPvar{axis},\MPvar{ex},\MPvar{em},false)) ; \stopuniqueMPgraphic @@ -193,7 +201,7 @@ enddef ; \stopMPextensions -\startuniqueMPgraphic{math:radical:default}{axis,ex,em} +\startuniqueMPgraphic{minifun::math:radical:default}{axis,ex,em} draw math_radical_simple(OverlayWidth,OverlayHeight,OverlayDepth,OverlayOffset) withpen pencircle xscaled (2OverlayLineWidth) yscaled (3OverlayLineWidth/4) rotated 30 diff --git a/tex/context/base/mkiv/meta-imp-txt.mkiv b/tex/context/base/mkiv/meta-imp-txt.mkiv index e9660b3a7..d4329cd6f 100644 --- a/tex/context/base/mkiv/meta-imp-txt.mkiv +++ b/tex/context/base/mkiv/meta-imp-txt.mkiv @@ -202,7 +202,10 @@ \stopMPdefinitions \startluacode + local context = context + local nodecodes = nodes.nodecodes + local kerncodes = nodes.kerncodes local visible_code = { [nodecodes.glyph] = true, @@ -212,72 +215,66 @@ [nodecodes.rule] = true, } - local disc_code = nodecodes.disc - local kern_code = nodecodes.kern - - local c_userkern = nodes.kerncodes.userkern + local kern_code = nodecodes.kern + local c_userkern = kerncodes.userkern local a_fontkern = attributes.private("fontkern") + local copynode = nodes.copy + local freenode = nodes.free + + local topoints = number.topoints + local mpprint = mp.print + local n = nil local s = 0 function mp.follow_reset() - r = nil + for i=1,#n do + freenode(n[i]) + end + n = nil s = 0 end function mp.follow_initialize(b) - if not r then - local l = tex.takebox(b).list - n = { } - s = 0 - while l do - local c = l - l = l.next - local id = c.id - if visible_code[id] then - s = s + 1 - n[s] = c - c.prev = nil - c.next = nil - elseif id == kern_code then - if c.subtype == c_userkern and not c[a_fontkern] then + if not n then + local head = tex.takebox(b).list + if head then + n = { } + s = 0 + head = node.flatten_discretionaries(head) + local current = head + while current do + local id = current.id + if visible_code[id] then s = s + 1 - n[s] = c - c.prev = nil - else - n[s].next = c - c.prev = n[s] - end - c.next = nil - elseif id == disc_code then - local r = c.replace - while r do + head, current, n[s] = nodes.remove(head,current) + elseif id == kern_code and current.subtype == c_userkern and not current[a_fontkern] then s = s + 1 - n[s] = r - r = r.next - r.prev = nil - r.next = nil + head, current, n[s] = nodes.remove(head,current) + else + current = current.next end end + nodes.flush_list(head) end end end function mp.follow_size() - mp.print(s) + mpprint(s) end function mp.follow_slot(i) - mp.print('textext("\\getfollowtoken{' .. i .. '}")') + mpprint('textext("\\getfollowtoken{' .. i .. '}")') end function mp.follow_text(s) - context(n[s]) + context(copynode(n[s])) end function mp.follow_width(i) - mp.print(number.topoints(n[i].width)) + mpprint(topoints(n[i].width)) end \stopluacode @@ -373,9 +370,8 @@ [medium] \startuniqueMPgraphic{EnglishRule}{height,width,color} - height = \MPvar{height} ; x1 = 0 ; x3 = \MPvar{width} ; x2 = x4 = .5x3 ; - y1 = y3 = 0 ; y2 = -y4 = height/2 ; + y1 = y3 = 0 ; y2 = -y4 = \MPvar{height}/2 ; fill z1..z2..z3 & z3..z4..z1 & cycle withcolor \MPvar{color} ; \stopuniqueMPgraphic diff --git a/tex/context/base/mkiv/meta-ini.lua b/tex/context/base/mkiv/meta-ini.lua index 6c4768671..f320efe20 100644 --- a/tex/context/base/mkiv/meta-ini.lua +++ b/tex/context/base/mkiv/meta-ini.lua @@ -117,23 +117,23 @@ do local data = false - function mp.start_saving_data(n) + function mp.mf_start_saving_data(n) data = { } end - function mp.stop_saving_data() + function mp.mf_stop_saving_data() if data then -- nothing end end - function mp.finish_saving_data() + function mp.mf_finish_saving_data() if data then -- nothing end end - function mp.save_data(str) + function mp.mf_save_data(str) if data then data[#data+1] = str end diff --git a/tex/context/base/mkiv/meta-ini.mkiv b/tex/context/base/mkiv/meta-ini.mkiv index 61e3523e6..89c7699de 100644 --- a/tex/context/base/mkiv/meta-ini.mkiv +++ b/tex/context/base/mkiv/meta-ini.mkiv @@ -97,7 +97,7 @@ \ifx\currentMPinstance\empty \let\currentMPinstance\defaultMPinstance \fi - \global\t_meta_definitions\expandafter{\the\t_meta_definitions#2}% + \gtoksapp\t_meta_definitions{#2}% \let\currentMPinstance\m_meta_saved_instance} \let\stopMPdefinitions\relax @@ -111,7 +111,7 @@ \let\stopMPextensions\relax \unexpanded\def\startMPinitializations#1\stopMPinitializations % for all instances, when enabled - {\global\t_meta_initializations\expandafter{\the\t_meta_initializations#1}} + {\gtoksapp\t_meta_initializations{#1}} \let\stopMPinitializations\relax @@ -131,7 +131,7 @@ \ifx\m_meta_option\!!plustoken \else \global\t_meta_inclusions\emptytoks \fi - \global\t_meta_inclusions\expandafter{\the\t_meta_inclusions#2}% + \gtoksapp\t_meta_inclusions{#2}% \let\currentMPinstance\m_meta_saved_instance} \let\stopMPinclusions\relax @@ -152,7 +152,7 @@ \ifx\m_meta_option\!!plustoken \else \global\t_meta_inclusions\emptytoks \fi - \global\t_meta_inclusions\expandafter{\the\t_meta_inclusions#2}% + \gtoksapp\t_meta_inclusions{#2}% \let\currentMPinstance\m_meta_saved_instance} \installcommandhandler \??mpinstance {MPinstance} \??mpinstance @@ -211,6 +211,7 @@ \def\currentMPformat {\currentMPinstance} \defineMPinstance[metafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] +\defineMPinstance[minifun] [\s!format=minifun,\s!extensions=\v!yes,\s!initializations=\v!yes] \defineMPinstance[extrafun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes] \defineMPinstance[lessfun] [\s!format=metafun] \defineMPinstance[doublefun] [\s!format=metafun,\s!extensions=\v!yes,\s!initializations=\v!yes,\c!method=\s!double] @@ -275,11 +276,13 @@ \endgroup} \def\meta_process_graphic_start - {\setbox\b_meta_graphic\hpack\bgroup} + {\pushMPboundingbox + \setbox\b_meta_graphic\hpack\bgroup} \def\meta_process_graphic_stop {\egroup - \meta_place_graphic} + \meta_place_graphic + \popMPboundingbox} \unexpanded\def\meta_process_graphic_instance#1% {\edef\currentMPinstance{#1}% @@ -365,12 +368,12 @@ \let\MPdrawingdata\empty \unexpanded\def\resetMPdrawing - {\global\let\MPdrawingdata\empty + {\glet\MPdrawingdata\empty \global\MPdrawingdonefalse} \unexpanded\def\pushMPdrawing {\globalpushmacro\MPdrawingdata - \global\let\MPdrawingdata\empty} + \glet\MPdrawingdata\empty} \unexpanded\def\popMPdrawing {\globalpopmacro\MPdrawingdata} @@ -728,7 +731,7 @@ % \def\meta_start_use_graphic#1#2#3\stopuseMPgraphic % %{\setgvalue{\??mpgraphic#1}{\meta_handle_use_graphic{#1}{#2}{#3}}} % %{\setxvalue{\??mpgraphic#1}{\noexpand\meta_handle_use_graphic{#1}{\normalunexpanded{#2}}{\normalunexpanded{#3}}}} -% {\global\expandafter\gdef\csname\??mpgraphic#1\expandafter\endcsname\expandafter{\expandafter\meta_handle_use_graphic\expandafter{\normalexpanded{#1}}{#2}{#3}}} +% {\expandafter\gdef\csname\??mpgraphic#1\expandafter\endcsname\expandafter{\expandafter\meta_handle_use_graphic\expandafter{\normalexpanded{#1}}{#2}{#3}}} % % cleaner: @@ -785,11 +788,28 @@ \unexpanded\def\useMPgraphic {\dodoublegroupempty\meta_use_graphic} +% \def\meta_use_graphic#1#2% +% {\meta_begin_graphic_group{#1}% +% %\doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}% +% \doifsomething{#2}{\setupMPvariables[#1][#2]}% +% \csname\??mpgraphic#1\endcsname\empty +% \meta_end_graphic_group} + \def\meta_use_graphic#1#2% {\meta_begin_graphic_group{#1}% -% \doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}% - \doifsomething{#2}{\setupMPvariables[#1][#2]}% - \csname\??mpgraphic#1\endcsname\empty + \ifcsname\??mpgraphic#1\endcsname + \edef\usedMPgraphicname{#1}% + \else\ifcsname\??mpgraphic\currentMPgraphicname\endcsname + \let\usedMPgraphicname\currentMPgraphicname + \else + \let\usedMPgraphicname\empty + \fi\fi + \ifx\usedMPgraphicname\empty + % message + \else + \doifsomething{#2}{\setupMPvariables[\usedMPgraphicname][#2]}% + \csname\??mpgraphic\usedMPgraphicname\endcsname + \fi \meta_end_graphic_group} \let\reuseMPgraphic \useMPgraphic % we can save a setup here if needed @@ -861,19 +881,6 @@ {\meta_prepare_instance_variable{#1}% \edef\overlaystamp{\overlaystamp:\MPvariable{#1}}} -%D \macros -%D {MPdatafile} -%D -%D We redefine a macro from \type {supp-mps.tex}: - -% This will change ... - -\def\MPdataMPYfile{\jobname-mpgraph.mpy} - -\startMPextensions - def data_mpy_file = "\noexpand\MPdataMPYfile" enddef ; -\stopMPextensions - \unexpanded\def\getMPdata {\clf_getMPdata} \let\rawMPdata \clf_getMPdata diff --git a/tex/context/base/mkiv/meta-nod.lua b/tex/context/base/mkiv/meta-nod.lua new file mode 100644 index 000000000..422b4ee14 --- /dev/null +++ b/tex/context/base/mkiv/meta-nod.lua @@ -0,0 +1,81 @@ +if not modules then modules = { } end modules ['meta-nod'] = { + version = 1.001, + comment = "companion to meta-nod.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local tonumber = tonumber +local P, R, Cs, lpegmatch = lpeg.P, lpeg.R, lpeg.Cs, lpeg.match + +local references = { } +local trace = false +local report = logs.reporter("metapost","nodes") + +local context = context +local implement = interfaces.implement + +trackers.register("metapost.nodes", function(v) trace = v end) + +local word = R("AZ","az","__")^1 + +local pattern = Cs ( + ( + word / function(s) return references[s] or s end + + P("{") / "[" + + P("}") / "]" + + P(1) + )^1 +) + +implement { + name = "grph_nodes_initialize", + actions = function() + references = { } + end +} + +implement { + name = "grph_nodes_reset", + actions = function() + references = { } + end +} + +implement { + name = "grph_nodes_register", + arguments = { "string", "integer" }, + actions = function(s,r) + if not tonumber(s) then + if trace then + report("register %i as %a",t,s) + end + references[s] = r + end + end +} + +implement { + name = "grph_nodes_resolve", + arguments = "string", + actions = function(s) + local r = references[s] + if r then + if trace then + report("resolve %a to %i",s,r) + end + context(r) + return + end + local n = lpegmatch(pattern,s) + if s ~= n then + if trace then + report("resolve '%s' to %s",s,n) + end + context(n) + return + end + context(s) + end +} diff --git a/tex/context/base/mkiv/meta-nod.mkiv b/tex/context/base/mkiv/meta-nod.mkiv index 5c7b3d503..9f966349c 100644 --- a/tex/context/base/mkiv/meta-nod.mkiv +++ b/tex/context/base/mkiv/meta-nod.mkiv @@ -11,6 +11,8 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +\registerctxluafile{meta-nod}{} + \unprotect \defineMPinstance @@ -105,6 +107,11 @@ \let\stopnodes\relax +%D Hm, we started out simple but it now quickly becomes the usual mess of +%D \TEX, \METAPOST\ and \LUA. Hard to understand. + +\newcount\c_meta_nodes_n + \unexpanded\def\startnodes {\dosingleempty\meta_nodes_start} @@ -116,10 +123,12 @@ \edef\p_meta_option{\metanodesparameter\c!option}% \edef\p_meta_alternative{\metanodesparameter\c!alternative}% \the\t_every_meta_nodes + \c_meta_nodes_n\zerocount \t_meta_nodes\emptytoks #2\removeunwantedspaces % for alan, will be commented: \writestatus{metanodes}{\detokenize\expandafter{\the\t_meta_nodes}}% + \clf_grph_nodes_initialize \startMPcode mfun_node_init(% \the\dimexpr\metanodesparameter\c!dx\relax,% @@ -129,11 +138,9 @@ \the\t_meta_nodes ; mfun_node_flush ; \stopMPcode + \clf_grph_nodes_reset \egroup} -% \unexpanded\def\grph_nodes_node[#1,#2]#3% -% {\etoksapp\t_meta_nodes{mfun_node_make(\number#1,\number#2,"\metanodesparameter\c!command{#3}");}} - \unexpanded\def\grph_nodes_node {\dodoubleempty\grph_nodes_node_two} @@ -146,13 +153,20 @@ \setupcurrentmetanodes[#3]% \fi \edef\p_label{#4}% + \edef\p_reference{\metanodesparameter\c!reference}% + \ifx\p_reference\empty\else + \clf_grph_nodes_register{\p_reference}\c_meta_nodes_n\relax + \fi \normalexpanded{\endgroup\noexpand\etoksapp\t_meta_nodes{% mfun_node_make(\number#1,\number#2% - \ifx\p_label\empty \else + \ifx\p_label\empty + ,""% + \else ,"\metanodesparameter\c!command{\p_label}"% \fi );% - }}} + }}% + \advance\c_meta_nodes_n\plusone} \appendtoks \let\placenode\grph_nodes_node @@ -199,8 +213,11 @@ \space mfun_nodes_fromto\begincsname\??metanodesposition\metanodesparameter\c!position\endcsname(% \metanodesparameter\c!offset,% - \number#1,\number#2% - \ifx\p_label\empty \else + % \number#1,\number#2% + \clf_grph_nodes_resolve{#1},\clf_grph_nodes_resolve{#2}% + \ifx\p_label\empty + ,""% + \else ,"\ifx\p_command\empty\p_label\else\p_command{\p_label}\fi"% \fi )% diff --git a/tex/context/base/mkiv/meta-pdf.lua b/tex/context/base/mkiv/meta-pdf.lua index 4a185cebd..5bcd161c0 100644 --- a/tex/context/base/mkiv/meta-pdf.lua +++ b/tex/context/base/mkiv/meta-pdf.lua @@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['meta-pdf'] = { license = "see context related readme files" } +-- This module is not used in practice but we keep it around for historic +-- reasons. + -- Finally we used an optimized version. The test code can be found in -- meta-pdh.lua but since we no longer want to overload functione we use -- more locals now. This module keeps changing as it is also a testbed. @@ -35,20 +38,24 @@ local pdfgraycode = lpdf.graycode local pdfspotcode = lpdf.spotcode local pdftransparencycode = lpdf.transparencycode local pdffinishtransparencycode = lpdf.finishtransparencycode ------ pdfpageliteral = nodes.pool.pdfpageliteral metapost.mptopdf = metapost.mptopdf or { } local mptopdf = metapost.mptopdf mptopdf.nofconverted = 0 -local f_translate = formatters["1 0 0 0 1 %F %F cm"] -- no %s due to 1e-035 issues -local f_concat = formatters["%F %F %F %F %F %F cm"] -- no %s due to 1e-035 issues +local f_translate = formatters["1 0 0 0 1 %.6F %.6F cm"] +local f_concat = formatters["%.6F %.6F %.6F %.6F %.6F %.6F cm"] + +directives.register("pdf.stripzeros",function() + f_translate = formatters["1 0 0 0 1 %.6N %.6N cm"] + f_concat = formatters["%.6N %.6N %.6N %.6N %.6N %.6N cm"] +end) local m_path, m_stack, m_texts, m_version, m_date, m_shortcuts = { }, { }, { }, 0, 0, false local m_stack_close, m_stack_path, m_stack_concat = false, { }, nil -local extra_path_code, ignore_path = nil, false +local extra_path_data, ignore_path = nil, false local specials = { } local function resetpath() @@ -57,28 +64,21 @@ end local function resetall() m_path, m_stack, m_texts, m_version, m_shortcuts = { }, { }, { }, 0, false - extra_path_code, ignore_path = nil, false + extra_path_data, ignore_path = nil, false specials = { } resetpath() end resetall() --- -- this does not work as expected (displacement of text) beware, needs another --- -- comment hack --- --- local function pdfcode(str) --- context(pdfpageliteral(str)) --- end - local pdfcode = context.pdfliteral local function mpscode(str) if ignore_path then pdfcode("h W n") - if extra_path_code then - pdfcode(extra_path_code) - extra_path_code = nil + if extra_path_data then + pdfcode(extra_path_data) + extra_path_data = nil end ignore_path = false else @@ -99,16 +99,28 @@ local function flushpath(cmd) if #m_stack_path > 0 then local path = { } if m_stack_concat then - local sx, sy = m_stack_concat[1], m_stack_concat[4] - local rx, ry = m_stack_concat[2], m_stack_concat[3] - local tx, ty = m_stack_concat[5], m_stack_concat[6] + local sx = m_stack_concat[1] + local sy = m_stack_concat[4] + local rx = m_stack_concat[2] + local ry = m_stack_concat[3] + local tx = m_stack_concat[5] + local ty = m_stack_concat[6] local d = (sx*sy) - (rx*ry) for k=1,#m_stack_path do - local v = m_stack_path[k] - local px, py = v[1], v[2] ; v[1], v[2] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[1],v[2]) + local v = m_stack_path[k] + local px = v[1] + local py = v[2] + v[1] = (sy*(px-tx)-ry*(py-ty))/d + v[2] = (sx*(py-ty)-rx*(px-tx))/d if #v == 7 then - local px, py = v[3], v[4] ; v[3], v[4] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[3],v[4]) - local px, py = v[5], v[6] ; v[5], v[6] = (sy*(px-tx)-ry*(py-ty))/d, (sx*(py-ty)-rx*(px-tx))/d -- mpconcat(v[5],v[6]) + px = v[3] + py = v[4] + v[3] = (sy*(px-tx)-ry*(py-ty))/d + v[4] = (sx*(py-ty)-rx*(px-tx))/d + px = v[5] + py = v[6] + v[5] = (sy*(px-tx)-ry*(py-ty))/d + v[6] = (sx*(py-ty)-rx*(px-tx))/d end path[k] = concat(v," ") end @@ -161,7 +173,8 @@ function mps.lineto(x,y) end function mps.rlineto(x,y) - local dx, dy = 0, 0 + local dx = 0 + local dy = 0 local topofstack = #m_stack_path if topofstack > 0 then local msp = m_stack_path[topofstack] @@ -238,7 +251,8 @@ function mps.clip() end function mps.textext(font, scale, str) -- old parser - local dx, dy = 0, 0 + local dx = 0 + local dy = 0 if #m_stack_path > 0 then dx, dy = m_stack_path[1][1], m_stack_path[1][2] end @@ -279,7 +293,7 @@ local function linearshade(colorspace,domain,ca,cb,coordinates) nofshades = nofshades + 1 local name = formatters["MpsSh%s"](nofshades) lpdf.linearshade(name,domain,ca,cb,1,colorspace,coordinates) - extra_path_code, ignore_path = formatters["/%s sh Q"](name), true + extra_path_data, ignore_path = formatters["/%s sh Q"](name), true pdfcode("q /Pattern cs") end @@ -288,7 +302,7 @@ local function circularshade(colorspace,domain,ca,cb,coordinates) nofshades = nofshades + 1 local name = formatters["MpsSh%s"](nofshades) lpdf.circularshade(name,domain,ca,cb,1,colorspace,coordinates) - extra_path_code, ignore_path = formatters["/%s sh Q"](name), true + extra_path_data, ignore_path = formatters["/%s sh Q"](name), true pdfcode("q /Pattern cs") end @@ -333,9 +347,12 @@ handlers[50] = function() report_mptopdf("skipping special %s",50) end --end of not supported function mps.setrgbcolor(r,g,b) -- extra check - r, g, b = tonumber(r), tonumber(g), tonumber(b) -- needed when we use lpeg + r = tonumber(r) -- needed when we use lpeg + g = tonumber(g) -- needed when we use lpeg + b = tonumber(b) -- needed when we use lpeg if r == 0.0123 and g < 0.1 then - g, b = round(g*10000), round(b*10000) + g = round(g*10000) + b = round(b*10000) local s = specials[b] local h = round(s[#s]) local handler = handlers[h] @@ -345,7 +362,8 @@ function mps.setrgbcolor(r,g,b) -- extra check report_mptopdf("unknown special handler %s (1)",h) end elseif r == 0.123 and g < 0.1 then - g, b = round(g*1000), round(b*1000) + g = round(g*1000) + b = round(b*1000) local s = specials[b] local h = round(s[#s]) local handler = handlers[h] diff --git a/tex/context/base/mkiv/meta-pdh.mkiv b/tex/context/base/mkiv/meta-pdh.mkiv index f9eff73ca..e4ac92fb4 100644 --- a/tex/context/base/mkiv/meta-pdh.mkiv +++ b/tex/context/base/mkiv/meta-pdh.mkiv @@ -92,15 +92,15 @@ {\ifx\objectoffset\undefined\zeropoint\else\objectoffset\fi} \def\resetMPvariables#1#2#3% - {\global\let\MPwidth \!!zeropoint - \global\let\MPheight\!!zeropoint - \global\let\MPllx \!!zerocount - \global\let\MPlly \!!zerocount - \global\let\MPurx \!!zerocount - \global\let\MPury \!!zerocount - \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi - \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi - \xdef\MPfilename {#1}} + {\glet\MPwidth \!!zeropoint + \glet\MPheight \!!zeropoint + \glet\MPllx \!!zerocount + \glet\MPlly \!!zerocount + \glet\MPurx \!!zerocount + \glet\MPury \!!zerocount + \xdef\MPxscale {#2}\ifx\MPxscale\empty\let\MPxscale\!!plusone\fi + \xdef\MPyscale {#3}\ifx\MPyscale\empty\let\MPyscale\!!plusone\fi + \xdef\MPfilename {#1}} %D The main macro: @@ -164,7 +164,7 @@ \else \getMPPDFobject \fi - \global\let\currentPDFresources\empty + \glet\currentPDFresources\empty \else \box#1% \fi} @@ -250,12 +250,12 @@ %D Some day we may consider collecting local resources. \appendtoks - \global\let\currentPDFresources\empty % kind of redundant + \glet\currentPDFresources\empty % kind of redundant \to \MPstartresources % \appendtoks % \collectPDFresources -% \global\let\currentPDFresources\collectedPDFresources +% \glet\currentPDFresources\collectedPDFresources % \to \MPstopresources \appendtoksonce diff --git a/tex/context/base/mkiv/meta-tex.lua b/tex/context/base/mkiv/meta-tex.lua index fdf118424..c2f72bcf3 100644 --- a/tex/context/base/mkiv/meta-tex.lua +++ b/tex/context/base/mkiv/meta-tex.lua @@ -126,11 +126,7 @@ do arguments = "2 strings", } - if LUAVERSION < 5.2 then - utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp") - else - utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], { texexp = metapost.texexp }) - end + utilities.strings.formatters.add(formatters,"texexp", [[texexp(...)]], { texexp = metapost.texexp }) local f_textext = formatters[ [[textext("%s")]] ] local f_mthtext = formatters[ [[textext("\mathematics{%s}")]] ] diff --git a/tex/context/base/mkiv/metatex.tex b/tex/context/base/mkiv/metatex.tex deleted file mode 100644 index 7c8a7ff01..000000000 --- a/tex/context/base/mkiv/metatex.tex +++ /dev/null @@ -1,30 +0,0 @@ -%D \module -%D [ file=metatex, -%D version=2008.10.10, -%D title=\METATEX, -%D subtitle=\METATEX\ Format Generation, -%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. - -%D We can experiment here with runtime loading, i.e. no longer -%D use a format. However, we still need a stub then but it could -%D as well be luatools (mtxrun) itself then. - -%D This format is just a minimal layer on top of the \LUATEX\ -%D engine and will not provide high level functionality. It can -%D be used as basis for dedicated (specialized) macro packages. -%D -%D A format is generated with the command; -%D -%D \starttyping -%D mtxrun --script metatex --make -%D \stoptyping -%D -%D For the moment this is a placeholder. Maybe some day ... the old -%D file history/metatex/metatex.tex so I can pick up from there if -%D needed. diff --git a/tex/context/base/mkiv/mlib-ctx.lua b/tex/context/base/mkiv/mlib-ctx.lua index c568b92a3..89f2fa0ee 100644 --- a/tex/context/base/mkiv/mlib-ctx.lua +++ b/tex/context/base/mkiv/mlib-ctx.lua @@ -11,46 +11,29 @@ local format, concat = string.format, table.concat local settings_to_hash = utilities.parsers.settings_to_hash local formatters = string.formatters -local report_metapost = logs.reporter("metapost") +local report_metapost = logs.reporter ("metapost") +local status_metapost = logs.messenger("metapost") -local starttiming = statistics.starttiming -local stoptiming = statistics.stoptiming +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming -local mplib = mplib +local trace_graphic = false -metapost = metapost or { } -local metapost = metapost -local context = context +trackers.register("metapost.graphics", + function(v) trace_graphic = v end +); -local setters = tokens.setters -local setmacro = setters.macro -local implement = interfaces.implement +local mplib = mplib -local v_no = interfaces.variables.no +metapost = metapost or { } +local metapost = metapost +local context = context -metapost.defaultformat = "metafun" -metapost.defaultinstance = "metafun" -metapost.defaultmethod = "default" +local setters = tokens.setters +local setmacro = setters.macro +local implement = interfaces.implement -local function setmpsformat(specification) - local instance = specification.instance - local format = specification.format - local method = specification.method - if not instance or instance == "" then - instance = metapost.defaultinstance - specification.instance = instance - end - if not format or format == "" then - format = metapost.defaultformat - specification.format = format - end - if not method or method == "" then - method = metapost.defaultmethod - specification.method = method - end - specification.mpx = metapost.format(instance,format,method) - return specification -end +local v_no = interfaces.variables.no local extensiondata = metapost.extensiondata or storage.allocate { } metapost.extensiondata = extensiondata @@ -96,9 +79,6 @@ implement { arguments = "string" } -local report_metapost = logs.reporter ("metapost") -local status_metapost = logs.messenger("metapost") - local patterns = { "meta-imp-%s.mkiv", "meta-imp-%s.tex", @@ -192,7 +172,9 @@ implement { -- or just move the scanners to pps function metapost.graphic(specification) - metapost.graphic_base_pass(setmpsformat(specification)) + metapost.pushformat(specification) + metapost.graphic_base_pass(specification) + metapost.popformat() end function metapost.startgraphic(t) @@ -208,9 +190,6 @@ function metapost.startgraphic(t) if not t.method then t.method = metapost.defaultmethod end - if not t.definitions then - t.definitions = "" - end t.data = { } return t end @@ -218,8 +197,10 @@ end function metapost.stopgraphic(t) if t then t.data = concat(t.data or { },"\n") + if trace_graphic then + report_metapost("\n"..t.data.."\n") + end metapost.graphic(t) - t.data = "" end end @@ -265,8 +246,7 @@ implement { } function metapost.getclippath(specification) -- why not a special instance for this - setmpsformat(specification) - local mpx = specification.mpx + local mpx = metapost.pushformat(specification) local data = specification.data or "" if mpx and data ~= "" then starttiming(metapost) @@ -285,7 +265,10 @@ function metapost.getclippath(specification) -- why not a special instance for t result = metapost.filterclippath(result) end stoptiming(metapost) + metapost.pushformat() return result + else + metapost.pushformat() end end @@ -337,23 +320,17 @@ implement { } } -statistics.register("metapost processing time", function() +statistics.register("metapost", function() local n = metapost.n if n and n > 0 then - local nofconverted = metapost.makempy.nofconverted local elapsedtime = statistics.elapsedtime - local elapsed = statistics.elapsed - local instances, memory = metapost.getstatistics(true) - local str = format("%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, memory: %0.3f M", + local elapsed = statistics.elapsed + local instances, + memory = metapost.getstatistics(true) + return format("%s seconds, loading: %s, execution: %s, n: %s, average: %s, instances: %i, luacalls: %i, memory: %0.3f M", elapsedtime(metapost), elapsedtime(mplib), elapsedtime(metapost.exectime), n, elapsedtime((elapsed(metapost) + elapsed(mplib) + elapsed(metapost.exectime)) / n), - instances, memory/(1024*1024)) - if nofconverted > 0 then - return format("%s, external: %s (%s calls)", - str, elapsedtime(metapost.makempy), nofconverted) - else - return str - end + instances, metapost.nofscriptruns(),memory/(1024*1024)) else return nil end diff --git a/tex/context/base/mkiv/mlib-int.lua b/tex/context/base/mkiv/mlib-int.lua index bd3ba213f..63e7278da 100644 --- a/tex/context/base/mkiv/mlib-int.lua +++ b/tex/context/base/mkiv/mlib-int.lua @@ -7,11 +7,14 @@ if not modules then modules = { } end modules ['mlib-int'] = { } local factor = number.dimenfactors.bp -local mpprint = mp.print ------ mpboolean = mp.boolean ------ mpquoted = mp.quoted +----- mpprint = mp.print +local mpnumeric = mp.numeric +local mpboolean = mp.boolean +local mpstring = mp.string +local mpquoted = mp.quoted local getdimen = tex.getdimen local getcount = tex.getcount +local getmacro = tokens.getters.macro local get = tex.get local mpcolor = attributes.colors.mpcolor local emwidths = fonts.hashes.emwidths @@ -19,90 +22,90 @@ local exheights = fonts.hashes.exheights local mpgetdimen = mp.getdimen -function mp.PaperHeight () mpprint(getdimen("paperheight") *factor) end -function mp.PaperWidth () mpprint(getdimen("paperwidth") *factor) end -function mp.PrintPaperHeight () mpprint(getdimen("printpaperheight") *factor) end -function mp.PrintPaperWidth () mpprint(getdimen("printpaperwidth") *factor) end -function mp.TopSpace () mpprint(getdimen("topspace") *factor) end -function mp.BottomSpace () mpprint(getdimen("bottomspace") *factor) end -function mp.BackSpace () mpprint(getdimen("backspace") *factor) end -function mp.CutSpace () mpprint(getdimen("cutspace") *factor) end -function mp.MakeupHeight () mpprint(getdimen("makeupheight") *factor) end -function mp.MakeupWidth () mpprint(getdimen("makeupwidth") *factor) end -function mp.TopHeight () mpprint(getdimen("topheight") *factor) end -function mp.TopDistance () mpprint(getdimen("topdistance") *factor) end -function mp.HeaderHeight () mpprint(getdimen("headerheight") *factor) end -function mp.HeaderDistance () mpprint(getdimen("headerdistance") *factor) end -function mp.TextHeight () mpprint(getdimen("textheight") *factor) end -function mp.FooterDistance () mpprint(getdimen("footerdistance") *factor) end -function mp.FooterHeight () mpprint(getdimen("footerheight") *factor) end -function mp.BottomDistance () mpprint(getdimen("bottomdistance") *factor) end -function mp.BottomHeight () mpprint(getdimen("bottomheight") *factor) end -function mp.LeftEdgeWidth () mpprint(getdimen("leftedgewidth") *factor) end -function mp.LeftEdgeDistance () mpprint(getdimen("leftedgedistance") *factor) end -function mp.LeftMarginWidth () mpprint(getdimen("leftmarginwidth") *factor) end -function mp.LeftMarginDistance () mpprint(getdimen("leftmargindistance") *factor) end -function mp.TextWidth () mpprint(getdimen("textwidth") *factor) end -function mp.RightMarginDistance () mpprint(getdimen("rightmargindistance") *factor) end -function mp.RightMarginWidth () mpprint(getdimen("rightmarginwidth") *factor) end -function mp.RightEdgeDistance () mpprint(getdimen("rightedgedistance") *factor) end -function mp.RightEdgeWidth () mpprint(getdimen("rightedgewidth") *factor) end -function mp.InnerMarginDistance () mpprint(getdimen("innermargindistance") *factor) end -function mp.InnerMarginWidth () mpprint(getdimen("innermarginwidth") *factor) end -function mp.OuterMarginDistance () mpprint(getdimen("outermargindistance") *factor) end -function mp.OuterMarginWidth () mpprint(getdimen("outermarginwidth") *factor) end -function mp.InnerEdgeDistance () mpprint(getdimen("inneredgedistance") *factor) end -function mp.InnerEdgeWidth () mpprint(getdimen("inneredgewidth") *factor) end -function mp.OuterEdgeDistance () mpprint(getdimen("outeredgedistance") *factor) end -function mp.OuterEdgeWidth () mpprint(getdimen("outeredgewidth") *factor) end -function mp.PageOffset () mpprint(getdimen("pagebackgroundoffset")*factor) end -function mp.PageDepth () mpprint(getdimen("pagebackgrounddepth") *factor) end -function mp.LayoutColumns () mpprint(getcount("layoutcolumns")) end -function mp.LayoutColumnDistance() mpprint(getdimen("layoutcolumndistance")*factor) end -function mp.LayoutColumnWidth () mpprint(getdimen("layoutcolumnwidth") *factor) end -function mp.SpineWidth () mpprint(getdimen("spinewidth") *factor) end -function mp.PaperBleed () mpprint(getdimen("paperbleed") *factor) end - -function mp.RealPageNumber () mpprint(getcount("realpageno")) end -function mp.LastPageNumber () mpprint(getcount("lastpageno")) end - -function mp.PageNumber () mpprint(getcount("pageno")) end -function mp.NOfPages () mpprint(getcount("lastpageno")) end - -function mp.SubPageNumber () mpprint(getcount("subpageno")) end -function mp.NOfSubPages () mpprint(getcount("lastsubpageno")) end - -function mp.CurrentColumn () mpprint(getcount("mofcolumns")) end -function mp.NOfColumns () mpprint(getcount("nofcolumns")) end - -function mp.BaseLineSkip () mpprint(get ("baselineskip",true) *factor) end -function mp.LineHeight () mpprint(getdimen("lineheight") *factor) end -function mp.BodyFontSize () mpprint(getdimen("bodyfontsize") *factor) end - -function mp.TopSkip () mpprint(get ("topskip",true) *factor) end -function mp.StrutHeight () mpprint(getdimen("strutht") *factor) end -function mp.StrutDepth () mpprint(getdimen("strutdp") *factor) end - -function mp.PageNumber () mpprint(getcount("pageno")) end -function mp.RealPageNumber () mpprint(getcount("realpageno")) end -function mp.NOfPages () mpprint(getcount("lastpageno")) end - -function mp.CurrentWidth () mpprint(get ("hsize") *factor) end -function mp.CurrentHeight () mpprint(get ("vsize") *factor) end - -function mp.EmWidth () mpprint(emwidths [false]*factor) end -function mp.ExHeight () mpprint(exheights[false]*factor) end +function mp.PaperHeight () mpnumeric(getdimen("paperheight") *factor) end +function mp.PaperWidth () mpnumeric(getdimen("paperwidth") *factor) end +function mp.PrintPaperHeight () mpnumeric(getdimen("printpaperheight") *factor) end +function mp.PrintPaperWidth () mpnumeric(getdimen("printpaperwidth") *factor) end +function mp.TopSpace () mpnumeric(getdimen("topspace") *factor) end +function mp.BottomSpace () mpnumeric(getdimen("bottomspace") *factor) end +function mp.BackSpace () mpnumeric(getdimen("backspace") *factor) end +function mp.CutSpace () mpnumeric(getdimen("cutspace") *factor) end +function mp.MakeupHeight () mpnumeric(getdimen("makeupheight") *factor) end +function mp.MakeupWidth () mpnumeric(getdimen("makeupwidth") *factor) end +function mp.TopHeight () mpnumeric(getdimen("topheight") *factor) end +function mp.TopDistance () mpnumeric(getdimen("topdistance") *factor) end +function mp.HeaderHeight () mpnumeric(getdimen("headerheight") *factor) end +function mp.HeaderDistance () mpnumeric(getdimen("headerdistance") *factor) end +function mp.TextHeight () mpnumeric(getdimen("textheight") *factor) end +function mp.FooterDistance () mpnumeric(getdimen("footerdistance") *factor) end +function mp.FooterHeight () mpnumeric(getdimen("footerheight") *factor) end +function mp.BottomDistance () mpnumeric(getdimen("bottomdistance") *factor) end +function mp.BottomHeight () mpnumeric(getdimen("bottomheight") *factor) end +function mp.LeftEdgeWidth () mpnumeric(getdimen("leftedgewidth") *factor) end +function mp.LeftEdgeDistance () mpnumeric(getdimen("leftedgedistance") *factor) end +function mp.LeftMarginWidth () mpnumeric(getdimen("leftmarginwidth") *factor) end +function mp.LeftMarginDistance () mpnumeric(getdimen("leftmargindistance") *factor) end +function mp.TextWidth () mpnumeric(getdimen("textwidth") *factor) end +function mp.RightMarginDistance () mpnumeric(getdimen("rightmargindistance") *factor) end +function mp.RightMarginWidth () mpnumeric(getdimen("rightmarginwidth") *factor) end +function mp.RightEdgeDistance () mpnumeric(getdimen("rightedgedistance") *factor) end +function mp.RightEdgeWidth () mpnumeric(getdimen("rightedgewidth") *factor) end +function mp.InnerMarginDistance () mpnumeric(getdimen("innermargindistance") *factor) end +function mp.InnerMarginWidth () mpnumeric(getdimen("innermarginwidth") *factor) end +function mp.OuterMarginDistance () mpnumeric(getdimen("outermargindistance") *factor) end +function mp.OuterMarginWidth () mpnumeric(getdimen("outermarginwidth") *factor) end +function mp.InnerEdgeDistance () mpnumeric(getdimen("inneredgedistance") *factor) end +function mp.InnerEdgeWidth () mpnumeric(getdimen("inneredgewidth") *factor) end +function mp.OuterEdgeDistance () mpnumeric(getdimen("outeredgedistance") *factor) end +function mp.OuterEdgeWidth () mpnumeric(getdimen("outeredgewidth") *factor) end +function mp.PageOffset () mpnumeric(getdimen("pagebackgroundoffset")*factor) end +function mp.PageDepth () mpnumeric(getdimen("pagebackgrounddepth") *factor) end +function mp.LayoutColumns () mpnumeric(getcount("layoutcolumns")) end +function mp.LayoutColumnDistance() mpnumeric(getdimen("layoutcolumndistance")*factor) end +function mp.LayoutColumnWidth () mpnumeric(getdimen("layoutcolumnwidth") *factor) end +function mp.SpineWidth () mpnumeric(getdimen("spinewidth") *factor) end +function mp.PaperBleed () mpnumeric(getdimen("paperbleed") *factor) end + +function mp.RealPageNumber () mpnumeric(getcount("realpageno")) end +function mp.LastPageNumber () mpnumeric(getcount("lastpageno")) end + +function mp.PageNumber () mpnumeric(getcount("pageno")) end +function mp.NOfPages () mpnumeric(getcount("lastpageno")) end + +function mp.SubPageNumber () mpnumeric(getcount("subpageno")) end +function mp.NOfSubPages () mpnumeric(getcount("lastsubpageno")) end + +function mp.CurrentColumn () mpnumeric(getcount("mofcolumns")) end +function mp.NOfColumns () mpnumeric(getcount("nofcolumns")) end + +function mp.BaseLineSkip () mpnumeric(get ("baselineskip",true) *factor) end +function mp.LineHeight () mpnumeric(getdimen("lineheight") *factor) end +function mp.BodyFontSize () mpnumeric(getdimen("bodyfontsize") *factor) end + +function mp.TopSkip () mpnumeric(get ("topskip",true) *factor) end +function mp.StrutHeight () mpnumeric(getdimen("strutht") *factor) end +function mp.StrutDepth () mpnumeric(getdimen("strutdp") *factor) end + +function mp.PageNumber () mpnumeric(getcount("pageno")) end +function mp.RealPageNumber () mpnumeric(getcount("realpageno")) end +function mp.NOfPages () mpnumeric(getcount("lastpageno")) end + +function mp.CurrentWidth () mpnumeric(get ("hsize") *factor) end +function mp.CurrentHeight () mpnumeric(get ("vsize") *factor) end + +function mp.EmWidth () mpnumeric(emwidths [false]*factor) end +function mp.ExHeight () mpnumeric(exheights[false]*factor) end mp.HSize = mp.CurrentWidth mp.VSize = mp.CurrentHeight mp.LastPageNumber = mp.NOfPages -function mp.PageFraction () +function mp.PageFraction() local lastpage = getcount("lastpageno") if lastpage > 1 then - mpprint((getcount("realpageno")-1)/(lastpage-1)) + mpnumeric((getcount("realpageno")-1)/(lastpage-1)) else - mpprint(1) + mpnumeric(1) end end @@ -112,30 +115,22 @@ local on_right = structures.pages.on_right local is_odd = structures.pages.is_odd local in_body = structures.pages.in_body -mp.OnRightPage = function() mpprint(on_right()) end -- needs checking -mp.OnOddPage = function() mpprint(is_odd ()) end -- needs checking -mp.InPageBody = function() mpprint(in_body ()) end -- needs checking +mp.OnRightPage = function() mpboolean(on_right()) end -- needs checking +mp.OnOddPage = function() mpboolean(is_odd ()) end -- needs checking +mp.InPageBody = function() mpboolean(in_body ()) end -- needs checking -- mp.CurrentLayout : \currentlayout -function mp.OverlayWidth () mpprint(getdimen("d_overlay_width") *factor) end -function mp.OverlayHeight () mpprint(getdimen("d_overlay_height") *factor) end -function mp.OverlayDepth () mpprint(getdimen("d_overlay_depth") *factor) end -function mp.OverlayLineWidth () mpprint(getdimen("d_overlay_linewidth")*factor) end -function mp.OverlayOffset () mpprint(getdimen("d_overlay_offset") *factor) end +function mp.OverlayWidth () mpnumeric(getdimen("d_overlay_width") * factor) end +function mp.OverlayHeight () mpnumeric(getdimen("d_overlay_height") * factor) end +function mp.OverlayDepth () mpnumeric(getdimen("d_overlay_depth") * factor) end +function mp.OverlayLineWidth() mpnumeric(getdimen("d_overlay_linewidth") * factor) end +function mp.OverlayOffset () mpnumeric(getdimen("d_overlay_offset") * factor) end +function mp.OverlayRegion () mpstring(getmacro("m_overlay_region")) end -function mp.defaultcolormodel() +function mp.mf_default_color_model() local colormethod = getcount("MPcolormethod") - -- if colormethod == 0 then - -- return 1 - -- elseif colormethod == 1 then - -- return 1 - -- elseif colormethod == 2 then - -- return 3 - -- else - -- return 3 - -- end - return (colormethod == 0 or colormethod == 1) and 1 or 3 + return mpnumeric((colormethod == 0 or colormethod == 1) and 1 or 3) end -- not much difference (10000 calls in a graphic neither as expansion seems to win diff --git a/tex/context/base/mkiv/mlib-lua.lua b/tex/context/base/mkiv/mlib-lua.lua index 19e731b85..d7c2a0fc3 100644 --- a/tex/context/base/mkiv/mlib-lua.lua +++ b/tex/context/base/mkiv/mlib-lua.lua @@ -10,11 +10,11 @@ if not modules then modules = { } end modules ['mlib-lua'] = { -- maybe we need mplib.model, but how with instances -local type, tostring, select, loadstring = type, tostring, select, loadstring +local type, tostring, tonumber, select, loadstring = type, tostring, tonumber, select, loadstring local find, match, gsub, gmatch = string.find, string.match, string.gsub, string.gmatch +local concat, insert, remove = table.concat, table.insert, table.remove local formatters = string.formatters -local concat = table.concat local lpegmatch = lpeg.match local lpegpatterns = lpeg.patterns @@ -26,105 +26,18 @@ local report_message = logs.reporter("metapost") local trace_luarun = false trackers.register("metapost.lua",function(v) trace_luarun = v end) local trace_enabled = true -local be_tolerant = true directives.register("metapost.lua.tolerant",function(v) be_tolerant = v end) +local be_tolerant = true directives.register("metapost.lua.tolerant", function(v) be_tolerant = v end) -mp = mp or { } -- system namespace -MP = MP or { } -- user namespace +local get, set, aux = { }, { }, { } -local buffer, n, max = { }, 0, 10 -- we reuse upto max - -function mp._f_() - if trace_enabled and trace_luarun then - local result = concat(buffer," ",1,n) - if n > max then - buffer = { } - end - n = 0 - report_luarun("data: %s",result) - return result - else - if n == 0 then - return "" - end - local result - if n == 1 then - result = buffer[1] - else - result = concat(buffer," ",1,n) - end - if n > max then - buffer = { } - end - n = 0 - return result - end -end - -local f_code = formatters["%s return mp._f_()"] - -local f_numeric = formatters["%.16f"] -local f_integer = formatters["%i"] -local f_pair = formatters["(%.16f,%.16f)"] -local f_triplet = formatters["(%.16f,%.16f,%.16f)"] -local f_quadruple = formatters["(%.16f,%.16f,%.16f,%.16f)"] - -local function mpprint(...) -- we can optimize for n=1 - for i=1,select("#",...) do - local value = select(i,...) - if value ~= nil then - n = n + 1 - local t = type(value) - if t == "number" then - buffer[n] = f_numeric(value) - elseif t == "string" then - buffer[n] = value - elseif t == "table" then - buffer[n] = "(" .. concat(value,",") .. ")" - else -- boolean or whatever - buffer[n] = tostring(value) - end - end - end -end - -local r = P('%') / "percent" - + P('"') / "dquote" - + P('\n') / "crlf" - -- + P(' ') / "space" -local a = Cc("&") -local q = Cc('"') -local p = Cs(q * (r * a)^-1 * (a * r * (P(-1) + a) + P(1))^0 * q) - -local function mpvprint(...) -- variable print - for i=1,select("#",...) do - local value = select(i,...) - if value ~= nil then - n = n + 1 - local t = type(value) - if t == "number" then - buffer[n] = f_numeric(value) - elseif t == "string" then - buffer[n] = lpegmatch(p,value) - elseif t == "table" then - local m = #t - if m == 2 then - buffer[n] = f_pair(unpack(t)) - elseif m == 3 then - buffer[n] = f_triplet(unpack(t)) - elseif m == 4 then - buffer[n] = f_quadruple(unpack(t)) - else -- error - buffer[n] = "" - end - else -- boolean or whatever - buffer[n] = tostring(value) - end - end - end -end +mp = mp or { -- system namespace + set = set, + get = get, + aux = aux, +} -mp.print = mpprint -mp.vprint = mpvprint +MP = MP or { -- user namespace +} -- We had this: -- @@ -139,150 +52,540 @@ mp.vprint = mpvprint -- lua.mp("somedefdname","foo") table.setmetatablecall(mp,function(t,k,...) return t[k](...) end) +table.setmetatablecall(MP,function(t,k,...) return t[k](...) end) -function mp.boolean(b) - n = n + 1 - buffer[n] = b and "true" or "false" -end +do -function mp.numeric(f) - n = n + 1 - buffer[n] = f and f_numeric(f) or "0" -end + local currentmpx = nil + local stack = { } -function mp.integer(i) - n = n + 1 - -- buffer[n] = i and f_integer(i) or "0" - buffer[n] = i or "0" -end + local get_numeric = mplib.get_numeric + local get_string = mplib.get_string + local get_boolean = mplib.get_boolean + local get_path = mplib.get_path + local set_path = mplib.set_path + + get.numeric = function(s) return get_numeric(currentmpx,s) end + get.string = function(s) return get_string (currentmpx,s) end + get.boolean = function(s) return get_boolean(currentmpx,s) end + get.path = function(s) return get_path (currentmpx,s) end + get.number = function(s) return get_numeric(currentmpx,s) end -function mp.pair(x,y) - n = n + 1 - if type(x) == "table" then - buffer[n] = f_pair(x[1],x[2]) - else - buffer[n] = f_pair(x,y) + set.path = function(s,t) return set_path(currentmpx,s,t) end -- not working yet + + function metapost.pushscriptrunner(mpx) + insert(stack,mpx) + currentmpx = mpx end -end -function mp.triplet(x,y,z) - n = n + 1 - if type(x) == "table" then - buffer[n] = f_triplet(x[1],x[2],x[3]) - else - buffer[n] = f_triplet(x,y,z) + function metapost.popscriptrunner() + currentmpx = remove(stack,mpx) end + end -function mp.quadruple(w,x,y,z) - n = n + 1 - if type(w) == "table" then - buffer[n] = f_quadruple(w[1],w[2],w[3],w[4]) - else - buffer[n] = f_quadruple(w,x,y,z) +do + + local buffer = { } + local n = 0 + local max = 20 -- we reuse upto max + local nesting = 0 + local runs = 0 + + local function _f_() + if trace_enabled and trace_luarun then + local result = concat(buffer," ",1,n) + if n > max then + buffer = { } + end + n = 0 + report_luarun("%i: data: %s",nesting,result) + return result + else + if n == 0 then + return "" + end + local result + if n == 1 then + result = buffer[1] + else + result = concat(buffer," ",1,n) + end + if n > max then + buffer = { } + end + n = 0 + return result + end + end + + mp._f_ = _f_ -- convenient to have it in a top module + aux.flush = _f_ + + ----- f_code = formatters["%s return mp._f_()"] + + local f_integer = formatters["%i"] + + local f_numeric = formatters["%n"] -- maybe %N + local f_pair = formatters["(%n,%n)"] + local f_ctrl = formatters["(%n,%n) .. controls (%n,%n) and (%n,%n)"] + local f_triplet = formatters["(%n,%n,%n)"] + local f_quadruple = formatters["(%n,%n,%n,%n)"] + + local f_points = formatters["%p"] + local f_pair_pt = formatters["(%p,%p)"] + local f_ctrl_pt = formatters["(%p,%p) .. controls (%p,%p) and (%p,%p)"] + local f_triplet_pt = formatters["(%p,%p,%p)"] + local f_quadruple_pt = formatters["(%p,%p,%p,%p)"] + + local r = P('%') / "percent" + + P('"') / "dquote" + + P('\n') / "crlf" + -- + P(' ') / "space" + local a = Cc("&") + local q = Cc('"') + local p = Cs(q * (r * a)^-1 * (a * r * (P(-1) + a) + P(1))^0 * q) + + mp.cleaned = function(s) return lpegmatch(p,s) or s end + + -- local function mpprint(...) -- we can optimize for n=1 + -- for i=1,select("#",...) do + -- local value = (select(i,...)) + -- if value ~= nil then + -- n = n + 1 + -- local t = type(value) + -- if t == "number" then + -- buffer[n] = f_numeric(value) + -- elseif t == "string" then + -- buffer[n] = value + -- elseif t == "table" then + -- buffer[n] = "(" .. concat(value,",") .. ")" + -- else -- boolean or whatever + -- buffer[n] = tostring(value) + -- end + -- end + -- end + -- end + + local function mpp(value) + n = n + 1 + local t = type(value) + if t == "number" then + buffer[n] = f_numeric(value) + elseif t == "string" then + buffer[n] = value + elseif t == "table" then + buffer[n] = "(" .. concat(value,",") .. ")" + else -- boolean or whatever + buffer[n] = tostring(value) + end + end + + local function mpprint(first,second,...) + if second == nil then + if first ~= nil then + mpp(first) + end + else + for i=1,select("#",first,second,...) do + local value = (select(i,first,second,...)) + if value ~= nil then + mpp(value) + end + end + end end -end -function mp.path(t,connector,cycle) - if type(t) == "table" then - local tn = #t - if tn > 0 then - if connector == true then - connector = "--" - cycle = true - elseif not connector then - connector = "--" + local function mpp(value) + n = n + 1 + local t = type(value) + if t == "number" then + buffer[n] = f_numeric(value) + elseif t == "string" then + buffer[n] = lpegmatch(p,value) + elseif t == "table" then + if #t > 4 then + buffer[n] = "" + else + buffer[n] = "(" .. concat(value,",") .. ")" end - local ti = t[1] - n = n + 1 ; buffer[n] = f_pair(ti[1],ti[2]) - for i=2,tn do - local ti = t[i] - n = n + 1 ; buffer[n] = connector - n = n + 1 ; buffer[n] = f_pair(ti[1],ti[2]) + else -- boolean or whatever + buffer[n] = tostring(value) + end + end + + local function mpvprint(first,second,...) -- variable print + if second == nil then + if first ~= nil then + mpp(first) end - if cycle then - n = n + 1 ; buffer[n] = connector - n = n + 1 ; buffer[n] = "cycle" + else + for i=1,select("#",first,second,...) do + local value = (select(i,first,second,...)) + if value ~= nil then + mpp(value) + end end end end -end -function mp.size(t) - n = n + 1 - buffer[n] = type(t) == "table" and f_numeric(#t) or "0" -end + local function mpstring(value) + n = n + 1 + buffer[n] = lpegmatch(p,value) + end -local mpnamedcolor = attributes.colors.mpnamedcolor + local function mpboolean(b) + n = n + 1 + buffer[n] = b and "true" or "false" + end -mp.NamedColor = function(str) - mpprint(mpnamedcolor(str)) -end + local function mpnumeric(f) + n = n + 1 + if not f or f == 0 then + buffer[n] = "0" + else + buffer[n] = f_numeric(f) + end + end --- experiment: names can change + local function mpinteger(i) + n = n + 1 + -- buffer[n] = i and f_integer(i) or "0" + buffer[n] = i or "0" + end -local datasets = { } -mp.datasets = datasets + local function mppoints(i) + n = n + 1 + if not i or i == 0 then + buffer[n] = "0pt" + else + buffer[n] = f_points(i) + end + end -function datasets.load(tag,filename) - if not filename then - tag, filename = file.basename(tag), tag + local function mppair(x,y) + n = n + 1 + if type(x) == "table" then + buffer[n] = f_pair(x[1],x[2]) + else + buffer[n] = f_pair(x,y) + end end - local data = mp.dataset(io.loaddata(filename) or "") - datasets[tag] = { - Data = data, - Line = function(n) mp.path(data[n or 1]) end, - Size = function() mp.size(data) end, - } -end --- + local function mppairpoints(x,y) + n = n + 1 + if type(x) == "table" then + buffer[n] = f_pair_pt(x[1],x[2]) + else + buffer[n] = f_pair_pt(x,y) + end + end + + local function mptriplet(x,y,z) + n = n + 1 + if type(x) == "table" then + buffer[n] = f_triplet(x[1],x[2],x[3]) + else + buffer[n] = f_triplet(x,y,z) + end + end -local replacer = lpeg.replacer("@","%%") + local function mptripletpoints(x,y,z) + n = n + 1 + if type(x) == "table" then + buffer[n] = f_triplet_pt(x[1],x[2],x[3]) + else + buffer[n] = f_triplet_pt(x,y,z) + end + end -function mp.fprint(fmt,...) - n = n + 1 - if not find(fmt,"%",1,true) then - fmt = lpegmatch(replacer,fmt) + local function mpquadruple(w,x,y,z) + n = n + 1 + if type(w) == "table" then + buffer[n] = f_quadruple(w[1],w[2],w[3],w[4]) + else + buffer[n] = f_quadruple(w,x,y,z) + end end - buffer[n] = formatters[fmt](...) -end -local function mpquoted(fmt,s,...) - n = n + 1 - if s then + local function mpquadruplepoints(w,x,y,z) + n = n + 1 + if type(w) == "table" then + buffer[n] = f_quadruple_pt(w[1],w[2],w[3],w[4]) + else + buffer[n] = f_quadruple_pt(w,x,y,z) + end + end + + -- we have three kind of connectors: + -- + -- .. ... -- (true) + + local function mp_path(f2,f6,t,connector,cycle) + if type(t) == "table" then + local tn = #t + if tn == 1 then + local t1 = t[1] + n = n + 1 ; buffer[n] = f2(t1[1],t1[2]) + elseif tn > 0 then + if connector == true or connector == nil then + connector = ".." + elseif connector == false then + connector = "--" + end + if cycle == nil then + cycle = t.cycle + if cycle == nil then + cycle = true + end + end + local six = connector == ".." -- otherwise we use whatever gets asked for + local controls = connector -- whatever + local a = t[1] + local b = t[2] + n = n + 1 + if six and #a == 6 and #b == 6 then + buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4]) + controls = ".." + else + buffer[n] = f2(a[1],a[2]) + controls = connector + end + for i=2,tn-1 do + a = b + b = t[i+1] + n = n + 1 + buffer[n] = connector + n = n + 1 + if six and #a == 6 and #b == 6 then + buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4]) + controls = ".." + else + buffer[n] = f2(a[1],a[2]) + controls = connector + end + end + n = n + 1 + buffer[n] = connector + a = b + b = t[1] + n = n + 1 + if cycle then + if six and #a == 6 and #b == 6 then + buffer[n] = f6(a[1],a[2],a[5],a[6],b[3],b[4]) + controls = ".." + else + buffer[n] = f2(a[1],a[2]) + controls = connector + end + n = n + 1 + buffer[n] = connector + n = n + 1 + buffer[n] = "cycle" + else + buffer[n] = f2(a[1],a[2]) + end + end + end + end + + local function mppath(...) + mp_path(f_pair,f_ctrl,...) + end + + local function mppathpoints(...) + mp_path(f_pair_pt,f_ctrl_pt,...) + end + + local function mpsize(t) + n = n + 1 + buffer[n] = type(t) == "table" and f_numeric(#t) or "0" + end + + local replacer = lpeg.replacer("@","%%") + + local function mpfprint(fmt,...) + n = n + 1 if not find(fmt,"%",1,true) then fmt = lpegmatch(replacer,fmt) end - -- buffer[n] = '"' .. formatters[fmt](s,...) .. '"' - buffer[n] = lpegmatch(p,formatters[fmt](s,...)) - elseif fmt then - -- buffer[n] = '"' .. fmt .. '"' - buffer[n] = lpegmatch(p,fmt) - else - -- something is wrong + buffer[n] = formatters[fmt](...) end + + local function mpquoted(fmt,s,...) + if s then + n = n + 1 + if not find(fmt,"%",1,true) then + fmt = lpegmatch(replacer,fmt) + end + -- buffer[n] = '"' .. formatters[fmt](s,...) .. '"' + buffer[n] = lpegmatch(p,formatters[fmt](s,...)) + elseif fmt then + n = n + 1 + -- buffer[n] = '"' .. fmt .. '"' + buffer[n] = lpegmatch(p,fmt) + else + -- something is wrong + end + end + + aux.print = mpprint + aux.vprint = mpvprint + aux.boolean = mpboolean + aux.string = mpstring + aux.numeric = mpnumeric + aux.number = mpnumeric + aux.integer = mpinteger + aux.points = mppoints + aux.pair = mppair + aux.pairpoints = mppairpoints + aux.triplet = mptriplet + aux.tripletpoints = mptripletpoints + aux.quadruple = mpquadruple + aux.quadruplepoints = mpquadruplepoints + aux.path = mppath + aux.pathpoints = mppathpoints + aux.size = mpsize + aux.fprint = mpfprint + aux.quoted = mpquoted + + -- we need access to the variables + + function metapost.nofscriptruns() + return runs + end + + -- sometimes we gain (e.g. .5 sec on the sync test) + + local cache = table.makeweak() + + function metapost.runscript(code) + nesting = nesting + 1 + local trace = trace_enabled and trace_luarun + if trace then + report_luarun("%i: code: %s",nesting,code) + end + runs = runs + 1 + local f = cache[code] + if not f then + f = loadstring(code .. " return mp._f_()") + if f then + cache[code] = f + elseif be_tolerant then + f = loadstring(code) + if f then + cache[code] = f + end + end + end + if f then + local _buffer_ = buffer + local _n_ = n + buffer = { } + n = 0 + local result = f() + if result then + local t = type(result) + if t == "number" then + result = f_numeric(result) + elseif t ~= "string" then + result = tostring(result) + end + if trace then + if #result == 0 then + report_luarun("%i: no result",nesting) + else + report_luarun("%i: result: %s",nesting,result) + end + end + buffer = _buffer_ + n = _n_ + nesting = nesting - 1 + return result + elseif trace then + report_luarun("%i: no result",nesting) + end + buffer, n = _buffer_, _n_ + else + report_luarun("%i: no result, invalid code: %s",nesting,code) + end + nesting = nesting - 1 + return "" + end + + -- for the moment + + for k, v in next, aux do mp[k] = v end + end -mp.quoted = mpquoted +do + + local mpnamedcolor = attributes.colors.mpnamedcolor + local mpprint = aux.print -function mp.n(t) + mp.mf_named_color = function(str) + mpprint(mpnamedcolor(str)) + end + +end + +function mp.n(t) -- used ? return type(t) == "table" and #t or 0 end -local whitespace = lpegpatterns.whitespace -local newline = lpegpatterns.newline -local setsep = newline^2 -local comment = (S("#%") + P("--")) * (1-newline)^0 * (whitespace - setsep)^0 -local value = (1-whitespace)^1 / tonumber -local entry = Ct( value * whitespace * value) -local set = Ct((entry * (whitespace-setsep)^0 * comment^0)^1) -local series = Ct((set * whitespace^0)^1) +do + + -- experiment: names can change + + local mppath = aux.path + local mpsize = aux.size + + local whitespace = lpegpatterns.whitespace + local newline = lpegpatterns.newline + local setsep = newline^2 + local comment = (S("#%") + P("--")) * (1-newline)^0 * (whitespace - setsep)^0 + local value = (1-whitespace)^1 / tonumber + local entry = Ct( value * whitespace * value) + local set = Ct((entry * (whitespace-setsep)^0 * comment^0)^1) + local series = Ct((set * whitespace^0)^1) + + local pattern = whitespace^0 * series -local pattern = whitespace^0 * series + local datasets = { } + mp.datasets = datasets + + function mp.dataset(str) + return lpegmatch(pattern,str) + end + + function datasets.load(tag,filename) + if not filename then + tag, filename = file.basename(tag), tag + end + local data = lpegmatch(pattern,io.loaddata(filename) or "") + datasets[tag] = { + data = data, + line = function(n) mppath(data[n or 1]) end, + size = function() mpsize(data) end, + } + end + + table.setmetatablecall(datasets,function(t,k,f,...) + local d = datasets[k] + local t = type(d) + if t == "table" then + d = d[f] + if type(d) == "function" then + d(...) + else + mpvprint(...) + end + elseif t == "function" then + d(f,...) + end + end) -function mp.dataset(str) - return lpegmatch(pattern,str) end -- \startluacode @@ -314,255 +617,157 @@ end -- endfor ; -- \stopMPpage -local cache, n = { }, 0 -- todo: when > n then reset cache or make weak - -function metapost.runscript(code) - local trace = trace_enabled and trace_luarun - if trace then - report_luarun("code: %s",code) - end - local f - if n > 100 then - cache = nil -- forget about caching - f = loadstring(f_code(code)) - if not f and be_tolerant then - f = loadstring(code) - end - else - f = cache[code] - if not f then - f = loadstring(f_code(code)) - if f then - n = n + 1 - cache[code] = f - elseif be_tolerant then - f = loadstring(code) - if f then - n = n + 1 - cache[code] = f - end - end - end - end - if f then - local result = f() - if result then - local t = type(result) - if t == "number" then - result = f_numeric(result) - elseif t ~= "string" then - result = tostring(result) - end - if trace then - report_luarun("result: %s",result) - end - return result - elseif trace then - report_luarun("no result") - end - else - report_luarun("no result, invalid code: %s",code) - end - return "" -end - --- function metapost.initializescriptrunner(mpx) --- mp.numeric = function(s) return mpx:get_numeric(s) end --- mp.string = function(s) return mpx:get_string (s) end --- mp.boolean = function(s) return mpx:get_boolean(s) end --- mp.number = mp.numeric --- end - -local get_numeric = mplib.get_numeric -local get_string = mplib.get_string -local get_boolean = mplib.get_boolean -local get_number = get_numeric - --- function metapost.initializescriptrunner(mpx) --- mp.numeric = function(s) return get_numeric(mpx,s) end --- mp.string = function(s) return get_string (mpx,s) end --- mp.boolean = function(s) return get_boolean(mpx,s) end --- mp.number = mp.numeric --- end - -local currentmpx = nil - -local get = { } -mp.get = get - -get.numeric = function(s) return get_numeric(currentmpx,s) end -get.string = function(s) return get_string (currentmpx,s) end -get.boolean = function(s) return get_boolean(currentmpx,s) end -get.number = mp.numeric - -function metapost.initializescriptrunner(mpx,trialrun) - currentmpx = mpx - if trace_luarun then - report_luarun("type of run: %s", trialrun and "trial" or "final") - end - -- trace_enabled = not trialrun blocks too much -end - -- texts: -local factor = 65536*(7227/7200) -local textexts = nil -local mptriplet = mp.triplet -local nbdimensions = nodes.boxes.dimensions - -function mp.tt_initialize(tt) - textexts = tt -end +do --- function mp.tt_wd(n) --- local box = textexts and textexts[n] --- mpprint(box and box.width/factor or 0) --- end --- function mp.tt_ht(n) --- local box = textexts and textexts[n] --- mpprint(box and box.height/factor or 0) --- end --- function mp.tt_dp(n) --- local box = textexts and textexts[n] --- mpprint(box and box.depth/factor or 0) --- end - -function mp.tt_dimensions(n) - local box = textexts and textexts[n] - if box then - -- could be made faster with nuts but not critical - mptriplet(box.width/factor,box.height/factor,box.depth/factor) - else - mptriplet(0,0,0) - end -end + local mptriplet = mp.triplet -function mp.tb_dimensions(category,name) - local w, h, d = nbdimensions(category,name) - mptriplet(w/factor,h/factor,d/factor) -end + local bpfactor = number.dimenfactors.bp + local textexts = nil + local mptriplet = mp.triplet + local nbdimensions = nodes.boxes.dimensions -function mp.report(a,b) - if b then - report_message("%s : %s",a,b) - elseif a then - report_message("%s : %s","message",a) + function mp.mf_tt_initialize(tt) + textexts = tt end -end --- + function mp.mf_tt_dimensions(n) + local box = textexts and textexts[n] + if box then + -- could be made faster with nuts but not critical + mptriplet(box.width*bpfactor,box.height*bpfactor,box.depth*bpfactor) + else + mptriplet(0,0,0) + end + end -local hashes = { } + function mp.mf_tb_dimensions(category,name) + local w, h, d = nbdimensions(category,name) + mptriplet(w*bpfactor,h*bpfactor,d*bpfactor) + end -function mp.newhash() - for i=1,#hashes+1 do - if not hashes[i] then - hashes[i] = { } - mpprint(i) - return + function mp.report(a,b,c,...) + if c then + report_message("%s : %s",a,formatters[(gsub(b,"@","%%"))](c,...)) + elseif b then + report_message("%s : %s",a,b) + elseif a then + report_message("%s : %s","message",a) end end -end -function mp.disposehash(n) - hashes[n] = nil end -function mp.inhash(n,key) - local h = hashes[n] - mpprint(h and h[key] and true or false) -end +do + + local mpprint = aux.print + local modes = tex.modes + local systemmodes = tex.systemmodes -function mp.tohash(n,key) - local h = hashes[n] - if h then - h[key] = true + function mp.mode(s) + mpprint(modes[s] and true or false) end -end -local modes = tex.modes -local systemmodes = tex.systemmodes + function mp.systemmode(s) + mpprint(systemmodes[s] and true or false) + end -function mp.mode(s) - mpprint(modes[s] and true or false) -end + mp.processingmode = mp.mode -function mp.systemmode(s) - mpprint(systemmodes[s] and true or false) end -- for alan's nodes: -function mp.isarray(str) - mpprint(find(str,"%d") and true or false) -end +do + + local mpprint = aux.print + local mpquoted = aux.quoted + + function mp.isarray(str) + mpprint(find(str,"%d") and true or false) + end + + function mp.prefix(str) + mpquoted(match(str,"^(.-)[%d%[]") or str) + end + + -- function mp.dimension(str) + -- local n = 0 + -- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg + -- n = n + 1 + -- end + -- mpprint(n) + -- end + + mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint) + + -- faster and okay as we don't have many variables but probably only + -- basename makes sense and even then it's not called that often + + -- local hash = table.setmetatableindex(function(t,k) + -- local v = find(k,"%d") and true or false + -- t[k] = v + -- return v + -- end) + -- + -- function mp.isarray(str) + -- mpprint(hash[str]) + -- end + -- + -- local hash = table.setmetatableindex(function(t,k) + -- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"' + -- t[k] = v + -- return v + -- end) + -- + -- function mp.prefix(str) + -- mpprint(hash[str]) + -- end -function mp.prefix(str) - mpquoted(match(str,"^(.-)[%d%[]") or str) end --- function mp.dimension(str) --- local n = 0 --- for s in gmatch(str,"%[?%-?%d+%]?") do --todo: lpeg --- n = n + 1 --- end --- mpprint(n) --- end +do -mp.dimension = lpeg.counter(P("[") * lpegpatterns.integer * P("]") + lpegpatterns.integer,mpprint) + local getmacro = tex.getmacro + local getdimen = tex.getdimen + local getcount = tex.getcount + local gettoks = tex.gettoks + local setmacro = tex.setmacro + local setdimen = tex.setdimen + local setcount = tex.setcount + local settoks = tex.settoks --- faster and okay as we don't have many variables but probably only --- basename makes sense and even then it's not called that often + local mpprint = mp.print + local mpquoted = mp.quoted --- local hash = table.setmetatableindex(function(t,k) --- local v = find(k,"%d") and true or false --- t[k] = v --- return v --- end) --- --- function mp.isarray(str) --- mpprint(hash[str]) --- end --- --- local hash = table.setmetatableindex(function(t,k) --- local v = '"' .. (match(k,"^(.-)%d") or k) .. '"' --- t[k] = v --- return v --- end) --- --- function mp.prefix(str) --- mpprint(hash[str]) --- end + local bpfactor = number.dimenfactors.bp -local getdimen = tex.getdimen -local getcount = tex.getcount -local gettoks = tex.gettoks -local setdimen = tex.setdimen -local setcount = tex.setcount -local settoks = tex.settoks + -- more helpers -local mpprint = mp.print -local mpquoted = mp.quoted + local function getmacro(k) mpprint (getmacro(k)) end + local function getdimen(k) mpprint (getdimen(k)*bpfactor) end + local function getcount(k) mpprint (getcount(k)) end + local function gettoks (k) mpquoted(gettoks (k)) end -local factor = number.dimenfactors.bp + local function setmacro(k,v) setmacro(k,v) end + local function setdimen(k,v) setdimen(k,v/bpfactor) end + local function setcount(k,v) setcount(k,v) end + local function settoks (k,v) settoks (k,v) end --- more helpers + -- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix -function mp.getdimen(k) mpprint (getdimen(k)*factor) end -function mp.getcount(k) mpprint (getcount(k)) end -function mp.gettoks (k) mpquoted(gettoks (k)) end -function mp.setdimen(k,v) setdimen(k,v/factor) end -function mp.setcount(k,v) setcount(k,v) end -function mp.settoks (k,v) settoks (k,v) end + mp._get_macro_ = getmacro mp.getmacro = getmacro + mp._get_dimen_ = getdimen mp.getdimen = getdimen + mp._get_count_ = getcount mp.getcount = getcount + mp._get_toks_ = gettoks mp.gettoks = gettoks --- def foo = lua.mp.foo ... enddef ; % loops due to foo in suffix + mp._set_macro_ = setmacro mp.setmacro = setmacro + mp._set_dimen_ = setdimen mp.setdimen = setdimen + mp._set_count_ = setcount mp.setcount = setcount + mp._set_toks_ = settoks mp.settoks = settoks -mp._get_dimen_ = mp.getdimen -mp._get_count_ = mp.getcount -mp._get_toks_ = mp.gettoks -mp._set_dimen_ = mp.setdimen -mp._set_count_ = mp.setcount -mp._set_toks_ = mp.settoks +end -- position fun @@ -656,6 +861,21 @@ do end +do + + local mppair = mp.pair + + function mp.textextanchor(s) + local x, y = match(s,"tx_anchor=(%S+) (%S+)") -- todo: make an lpeg + if x and y then + x = tonumber(x) + y = tonumber(y) + end + mppair(x or 0,y or 0) + end + +end + do local mprint = mp.print @@ -674,31 +894,65 @@ end do - local mpvprint = mp.vprint + local mpprint = aux.print + local mpvprint = aux.vprint - local stores = { } + local hashes = { } - function mp.newstore(name) - stores[name] = { } + function mp.newhash(name) + if name then + hashes[name] = { } + else + for i=1,#hashes+1 do + if not hashes[i] then + hashes[i] = { } + mpvprint(i) + return + end + end + end end - function mp.disposestore(name) - stores[name] = nil + function mp.disposehash(n) + if tonumber(n) then + hashes[n] = false + else + hashes[n] = nil + end end - function mp.tostore(name,key,value) - stores[name][key] = value + function mp.inhash(n,key) + local h = hashes[n] + mpvprint(h and h[key] and true or false) end - function mp.fromstore(name,key) - mpvprint(stores[name][key]) -- type specific + function mp.tohash(n,key,value) + local h = hashes[n] + if h then + if value == nil then + h[key] = true + else + h[key] = value + end + end + end + + function mp.fromhash(n,key) + local h = hashes[n] + mpvprint(h and h[key] or false) end interfaces.implement { - name = "getMPstored", + name = "MPfromhash", arguments = "2 strings", actions = function(name,key) - context(stores[name][key]) + local h = hashes[name] or hashes[tonumber(name)] + if h then + local v = h[key] or h[tonumber(key)] + if v then + context(v) + end + end end } @@ -706,11 +960,70 @@ end do - local mpprint = mp.print - local texmodes = tex.modes + -- a bit overkill: just a find(str,"mf_object=") can be enough - function mp.processingmode(s) - mpprint(tostring(texmodes[s])) + local mpboolean = aux.boolean + + local p1 = P("mf_object=") + local p2 = lpegpatterns.eol * p1 + local pattern = (1-p2)^0 * p2 + p1 + + function mp.isobject(str) + mpboolean(pattern and str ~= "" and lpegmatch(pattern,str)) end end + +do + + local mpnumeric = aux.numeric + local mppair = aux.pair + local mpgetpath = get.path + + local p = nil + local n = 0 + + local function mf_path_length(name) + p = mpgetpath(name) + n = p and #p or 0 + mpnumeric(n) + end + + local function mf_path_point(i) + if i > 0 and i <= n then + local pi = p[i] + mppair(pi[1],pi[2]) + end + end + + local function mf_path_left(i) + if i > 0 and i <= n then + local pi = p[i] + mppair(pi[5],pi[6]) + end + end + + local function mf_path_right(i) + if i > 0 and i <= n then + local pn + if i == 1 then + pn = p[2] or p[1] + else + pn = p[i+1] or p[1] + end + mppair(pn[3],pn[4]) + end + end + + local function mf_path_reset() + p = nil + n = 0 + end + + mp.mf_path_length = mf_path_length mp.pathlength = mf_path_length + mp.mf_path_point = mf_path_point mp.pathpoint = mf_path_point + mp.mf_path_left = mf_path_left mp.pathleft = mf_path_left + mp.mf_path_right = mf_path_right mp.pathright = mf_path_right + mp.mf_path_reset = mf_path_reset mp.pathreset = mf_path_reset + +end diff --git a/tex/context/base/mkiv/mlib-pdf.lua b/tex/context/base/mkiv/mlib-pdf.lua index 75f810fb3..92fde5e13 100644 --- a/tex/context/base/mkiv/mlib-pdf.lua +++ b/tex/context/base/mkiv/mlib-pdf.lua @@ -6,9 +6,8 @@ if not modules then modules = { } end modules ['mlib-pdf'] = { license = "see context related readme files", } --- maybe %s is better than %f - -local format, concat, gsub = string.format, table.concat, string.gsub +local gsub = string.gsub +local concat, insert, remove = table.concat, table.insert, table.remove local abs, sqrt, round = math.abs, math.sqrt, math.round local setmetatable, rawset, tostring, tonumber, type = setmetatable, rawset, tostring, tonumber, type local P, S, C, Ct, Cc, Cg, Cf, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cf, lpeg.Carg @@ -41,23 +40,34 @@ local pdfflusher = { } metapost.flushers.pdf = pdfflusher metapost.n = 0 -metapost.optimize = true -- false local experiment = true -- uses context(node) that already does delayed nodes local savedliterals = nil -- needs checking -local mpsliteral = nodes.pool.register(node.new("whatsit",nodes.whatsitcodes.pdfliteral)) -- pdfliteral.mode = 1 - -local f_f = formatters["%F"] - -local f_m = formatters["%F %F m"] -local f_c = formatters["%F %F %F %F %F %F c"] -local f_l = formatters["%F %F l"] -local f_cm = formatters["%F %F %F %F %F %F cm"] -local f_M = formatters["%F M"] +local mpsliteral = nodes.pool.originliteral + +local f_f = formatters["%.6F"] +local f_m = formatters["%.6F %.6F m"] +local f_c = formatters["%.6F %.6F %.6F %.6F %.6F %.6F c"] +local f_l = formatters["%.6F %.6F l"] +local f_cm = formatters["%.6F %.6F %.6F %.6F %.6F %.6F cm"] +local f_M = formatters["%.6F M"] local f_j = formatters["%i j"] local f_J = formatters["%i J"] -local f_d = formatters["[%s] %F d"] -local f_w = formatters["%F w"] +local f_d = formatters["[%s] %.6F d"] +local f_w = formatters["%.3F w"] + +directives.register("metapost.stripzeros",function() + f_f = formatters["%.6N"] + f_m = formatters["%.6N %.6N m"] + f_c = formatters["%.6N %.6N %.6N %.6N %.6N %.6N c"] + f_l = formatters["%.6N %.6N l"] + f_cm = formatters["%.6N %.6N %.6N %.6N %.6N %.6N cm"] + f_M = formatters["%.6N M"] + f_j = formatters["%i j"] + f_J = formatters["%i J"] + f_d = formatters["[%s] %.6N d"] + f_w = formatters["%.3N w"] +end) directives.register("metapost.savetable",function(v) if type(v) == "string" then @@ -73,60 +83,28 @@ trackers.register("metapost.forcestroke",function(v) force_stroke = v end) -local pdfliteral = function(pdfcode) - local literal = copy_node(mpsliteral) - literal.data = pdfcode - return literal -end - -- Because in MKiV we always have two passes, we save the objects. When an extra -- mp run is done (due to for instance texts identifier in the parse pass), we -- get a new result table and the stored objects are forgotten. Otherwise they -- are reused. local function getobjects(result,figure,index) - if metapost.optimize then - local robjects = result.objects - if not robjects then - robjects = { } - result.objects = robjects - end - local fobjects = robjects[index or 1] - if not fobjects then - fobjects = figure:objects() - robjects[index] = fobjects - end - return fobjects - else - return figure:objects() - end + return figure:objects() end -function metapost.convert(result, trialrun, flusher, multipass, askedfig) - if trialrun then - local multipassindeed = metapost.parse(result,askedfig) - if multipass and not multipassindeed and metapost.optimize then - if save_table then - table.save(save_table,metapost.totable(result,1)) -- direct - end - metapost.flush(result,flusher,askedfig) -- saves a run - else - return false - end - else - if save_table then - table.save(save_table,metapost.totable(result,1)) -- direct - end - metapost.flush(result,flusher,askedfig) +function metapost.convert(specification,result) + local flusher = specification.flusher + local askedfig = specification.askedfig + if save_table then + table.save(save_table,metapost.totable(result,1)) -- direct end + metapost.flush(specification,result) return true -- done end function metapost.flushliteral(d) if savedliterals then - local literal = copy_node(mpsliteral) - literal.data = savedliterals[d] - write_node(literal) + write_node(mpsliteral(savedliterals[d])) else report_metapost("problem flushing literal %a",d) end @@ -140,7 +118,7 @@ function pdfflusher.comment(message) if message then message = formatters["%% mps graphic %s: %s"](metapost.n,message) if experiment then - context(pdfliteral(message)) + context(mpsliteral(message)) elseif savedliterals then local last = #savedliterals + 1 savedliterals[last] = message @@ -169,7 +147,7 @@ function pdfflusher.flushfigure(pdfliterals) -- table if #pdfliterals > 0 then pdfliterals = concat(pdfliterals,"\n") if experiment then - context(pdfliteral(pdfliterals)) + context(mpsliteral(pdfliterals)) else if savedliterals then local last = #savedliterals + 1 @@ -320,15 +298,6 @@ local p_boolean = P("false") * Cc(false) + P("true") * Cc(true) local p_set = Ct(number^1) local p_path = Ct(Ct(number * number^-5)^1) --- local variable = --- P("1:") * key * p_number --- + P("2:") * key * p_string --- + P("3:") * key * p_boolean --- + S("4568") * P(":") * key * p_set --- + P("7:") * key * p_path --- --- local pattern_key = Cf ( Carg(1) * (Cg(variable * newline^0)^0), rawset) - local variable = P("1:") * p_number + P("2:") * p_string @@ -374,7 +343,9 @@ function metapost.processspecial(str) end end -local function setproperties(figure) +local stack = { } + +local function pushproperties(figure) local boundingbox = figure:boundingbox() local properties = { llx = boundingbox[1], @@ -388,313 +359,321 @@ local function setproperties(figure) italic = figure:italcorr(), number = figure:charcode() or 0, } + insert(stack,properties) metapost.properties = properties return properties end +local function popproperties() + metapost.properties = remove(stack) +end + local function nocomment() end metapost.comment = nocomment -function metapost.flush(result,flusher,askedfig) +function metapost.flush(specification,result) if result then - local figures = result.fig + local flusher = specification.flusher + local askedfig = specification.askedfig + local incontext = specification.incontext + local figures = result.fig if figures then flusher = flusher or pdfflusher - local resetplugins = metapost.resetplugins or ignore -- before figure - local processplugins = metapost.processplugins or ignore -- each object + local resetplugins = metapost.resetplugins or ignore -- before figure + local processplugins = metapost.processplugins or ignore -- each object local synchronizeplugins = metapost.synchronizeplugins or ignore - local pluginactions = metapost.pluginactions or ignore -- before / after - local startfigure = flusher.startfigure - local stopfigure = flusher.stopfigure - local flushfigure = flusher.flushfigure - local textfigure = flusher.textfigure - local processspecial = flusher.processspecial or metapost.processspecial - metapost.comment = flusher.comment or nocomment + local pluginactions = metapost.pluginactions or ignore -- before / after + local startfigure = flusher.startfigure + local stopfigure = flusher.stopfigure + local flushfigure = flusher.flushfigure + local textfigure = flusher.textfigure + local processspecial = flusher.processspecial or metapost.processspecial + metapost.comment = flusher.comment or nocomment for index=1,#figures do - local figure = figures[index] - local properties = setproperties(figure) + local figure = figures[index] + local properties = pushproperties(figure) if askedfig == "direct" or askedfig == "all" or askedfig == properties.number then - local objects = getobjects(result,figure,index) - local result = { } - local miterlimit, linecap, linejoin, dashed = -1, -1, -1, false - local llx = properties.llx - local lly = properties.lly - local urx = properties.urx - local ury = properties.ury + local objects = getobjects(result,figure,index) + local result = { } + local miterlimit = -1 + local linecap = -1 + local linejoin = -1 + local dashed = false + local llx = properties.llx + local lly = properties.lly + local urx = properties.urx + local ury = properties.ury if urx < llx then -- invalid startfigure(properties.number,0,0,0,0,"invalid",figure) stopfigure() else - startfigure(properties.number,llx,lly,urx,ury,"begin",figure) - result[#result+1] = "q" - if objects then - resetplugins(result) -- we should move the colorinitializer here - local savedpath = nil - local savedhtap = nil - for o=1,#objects do - local object = objects[o] - local objecttype = object.type - if objecttype == "text" then - result[#result+1] = "q" - local ot = object.transform -- 3,4,5,6,1,2 - result[#result+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) -- TH: formatters["%F %F m %F %F %F %F 0 0 cm"](unpack(ot)) - flushfigure(result) -- flush accumulated literals - result = { } - textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) - result[#result+1] = "Q" - elseif objecttype == "special" then - if processspecial then - processspecial(object.prescript) - end - elseif objecttype == "start_clip" then - local evenodd = not object.istext and object.postscript == "evenodd" - result[#result+1] = "q" - flushnormalpath(object.path,result,false) - result[#result+1] = evenodd and "W* n" or "W n" - elseif objecttype == "stop_clip" then - result[#result+1] = "Q" - miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false - elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then - -- skip - else - -- we use an indirect table as we want to overload - -- entries but this is not possible in userdata - -- - -- can be optimized if no path - -- - local original = object - local object = { } - setmetatable(object, { - __index = original - }) - -- first we analyze - local before, after = processplugins(object) - local evenodd, collect, both = false, false, false - local postscript = object.postscript - if not object.istext then - if postscript == "evenodd" then - evenodd = true - elseif postscript == "collect" then - collect = true - elseif postscript == "both" then - both = true - elseif postscript == "eoboth" then - evenodd = true - both = true - end - end - -- - if collect then - if not savedpath then - savedpath = { object.path or false } - savedhtap = { object.htap or false } - else - savedpath[#savedpath+1] = object.path or false - savedhtap[#savedhtap+1] = object.htap or false + + -- we need to be indirect if we want the one-pass solution + + local function processfigure() + result[#result+1] = "q" + if objects then + -- resetplugins(result) -- we should move the colorinitializer here + local savedpath = nil + local savedhtap = nil + for o=1,#objects do + local object = objects[o] + local objecttype = object.type + if objecttype == "text" then + result[#result+1] = "q" + local ot = object.transform -- 3,4,5,6,1,2 + result[#result+1] = f_cm(ot[3],ot[4],ot[5],ot[6],ot[1],ot[2]) + flushfigure(result) -- flush accumulated literals + result = { } + textfigure(object.font,object.dsize,object.text,object.width,object.height,object.depth) + result[#result+1] = "Q" + elseif objecttype == "special" then + if processspecial then + processspecial(object.prescript) end + elseif objecttype == "start_clip" then + local evenodd = not object.istext and object.postscript == "evenodd" + result[#result+1] = "q" + flushnormalpath(object.path,result,false) + result[#result+1] = evenodd and "W* n" or "W n" + elseif objecttype == "stop_clip" then + result[#result+1] = "Q" + miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false + elseif objecttype == "start_bounds" or objecttype == "stop_bounds" then + -- skip else - local objecttype = object.type -- can have changed - if before then - result = pluginactions(before,result,flushfigure) - end - local ml = object.miterlimit - if ml and ml ~= miterlimit then - miterlimit = ml - result[#result+1] = f_M(ml) - end - local lj = object.linejoin - if lj and lj ~= linejoin then - linejoin = lj - result[#result+1] = f_j(lj) - end - local lc = object.linecap - if lc and lc ~= linecap then - linecap = lc - result[#result+1] = f_J(lc) + -- we use an indirect table as we want to overload + -- entries but this is not possible in userdata + -- + -- can be optimized if no path + -- + local original = object + local object = { } + setmetatable(object, { + __index = original + }) + local before, + after = processplugins(object) + local evenodd = false + local collect = false + local both = false + local postscript = object.postscript + if not object.istext then + if postscript == "evenodd" then + evenodd = true + elseif postscript == "collect" then + collect = true + elseif postscript == "both" then + both = true + elseif postscript == "eoboth" then + evenodd = true + both = true + end end - if both then - if dashed ~= false then -- was just dashed test - result[#result+1] = "[] 0 d" - dashed = false + -- + if collect then + if not savedpath then + savedpath = { object.path or false } + savedhtap = { object.htap or false } + else + savedpath[#savedpath+1] = object.path or false + savedhtap[#savedhtap+1] = object.htap or false end else - local dl = object.dash - if dl then - local d = f_d(concat(dl.dashes or {}," "),dl.offset) - if d ~= dashed then - dashed = d - result[#result+1] = d - end - elseif dashed ~= false then -- was just dashed test - result[#result+1] = "[] 0 d" - dashed = false + local objecttype = object.type -- can have changed + if before then + result = pluginactions(before,result,flushfigure) end - end - local path = object.path -- newpath - local transformed, penwidth = false, 1 - local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" - local pen = object.pen - if pen then - if pen.type == 'elliptical' then - transformed, penwidth = pen_characteristics(original) -- boolean, value - result[#result+1] = f_w(penwidth) -- todo: only if changed - if objecttype == 'fill' then - objecttype = 'both' + local ml = object.miterlimit + if ml and ml ~= miterlimit then + miterlimit = ml + result[#result+1] = f_M(ml) + end + local lj = object.linejoin + if lj and lj ~= linejoin then + linejoin = lj + result[#result+1] = f_j(lj) + end + local lc = object.linecap + if lc and lc ~= linecap then + linecap = lc + result[#result+1] = f_J(lc) + end + if both then + if dashed ~= false then -- was just dashed test + result[#result+1] = "[] 0 d" + dashed = false end - else -- calculated by mplib itself - objecttype = 'fill' - end - end - if transformed then - result[#result+1] = "q" - end - if path then - if savedpath then - for i=1,#savedpath do - local path = savedpath[i] - if transformed then - flushconcatpath(path,result,open) - else - flushnormalpath(path,result,open) + else + local dl = object.dash + if dl then + local d = f_d(concat(dl.dashes or {}," "),dl.offset) + if d ~= dashed then + dashed = d + result[#result+1] = d end + elseif dashed ~= false then -- was just dashed test + result[#result+1] = "[] 0 d" + dashed = false end - savedpath = nil end - if transformed then - flushconcatpath(path,result,open) - else - flushnormalpath(path,result,open) - end - if force_stroke then - result[#result+1] = open and "S" or "h S" - elseif objecttype == "fill" then - result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo - elseif objecttype == "outline" then - if both then - result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo - else - result[#result+1] = open and "S" or "h S" - end - elseif objecttype == "both" then - result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath + local path = object.path -- newpath + local transformed = false + local penwidth = 1 + local open = path and path[1].left_type and path[#path].right_type -- at this moment only "end_point" + local pen = object.pen + if pen then + if pen.type == "elliptical" then + transformed, penwidth = pen_characteristics(original) -- boolean, value + result[#result+1] = f_w(penwidth) -- todo: only if changed + if objecttype == "fill" then + objecttype = "both" + end + else -- calculated by mplib itself + objecttype = "fill" + end end - end - if transformed then - result[#result+1] = "Q" - end - local path = object.htap - if path then if transformed then result[#result+1] = "q" end - if savedhtap then - for i=1,#savedhtap do - local path = savedhtap[i] - if transformed then - flushconcatpath(path,result,open) + if path then + if savedpath then + for i=1,#savedpath do + local path = savedpath[i] + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + end + savedpath = nil + end + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + if force_stroke then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "fill" then + result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo + elseif objecttype == "outline" then + if both then + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo else - flushnormalpath(path,result,open) + result[#result+1] = open and "S" or "h S" end + elseif objecttype == "both" then + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath end - savedhtap = nil - evenodd = true end if transformed then - flushconcatpath(path,result,open) - else - flushnormalpath(path,result,open) + result[#result+1] = "Q" end - if force_stroke then - result[#result+1] = open and "S" or "h S" - elseif objecttype == "fill" then - result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo - elseif objecttype == "outline" then - result[#result+1] = open and "S" or "h S" - elseif objecttype == "both" then - result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath + local path = object.htap + if path then + if transformed then + result[#result+1] = "q" + end + if savedhtap then + for i=1,#savedhtap do + local path = savedhtap[i] + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + end + savedhtap = nil + evenodd = true + end + if transformed then + flushconcatpath(path,result,open) + else + flushnormalpath(path,result,open) + end + if force_stroke then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "fill" then + result[#result+1] = evenodd and "h f*" or "h f" -- f* = eo + elseif objecttype == "outline" then + result[#result+1] = open and "S" or "h S" + elseif objecttype == "both" then + result[#result+1] = evenodd and "h B*" or "h B" -- B* = eo -- b includes closepath + end + if transformed then + result[#result+1] = "Q" + end end - if transformed then - result[#result+1] = "Q" + if after then + result = pluginactions(after,result,flushfigure) end end - if after then - result = pluginactions(after,result,flushfigure) + if object.grouped then + -- can be qQ'd so changes can end up in groups + miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false end end - if object.grouped then - -- can be qQ'd so changes can end up in groups - miterlimit, linecap, linejoin, dashed = -1, -1, -1, "" -- was false - end end end + result[#result+1] = "Q" + flushfigure(result) + end + startfigure(properties.number,llx,lly,urx,ury,"begin",figure) + if incontext then + context(function() processfigure() end) + else + processfigure() end - result[#result+1] = "Q" - flushfigure(result) stopfigure("end") + end if askedfig ~= "all" then break end end + popproperties() end metapost.comment = nocomment + resetplugins(result) -- we should move the colorinitializer here end end end -function metapost.parse(result,askedfig) - if result then - local figures = result.fig - if figures then - local multipass = false - local analyzeplugins = metapost.analyzeplugins -- each object - for index=1,#figures do - local figure = figures[index] - local properties = setproperties(figure) - if askedfig == "direct" or askedfig == "all" or askedfig == properties.number then - local objects = getobjects(result,figure,index) - if objects then - for o=1,#objects do - if analyzeplugins(objects[o]) then - multipass = true - end - end - end - if askedfig ~= "all" then - break - end - end +-- tracing: + +do + + local result = { } + + local flusher = { + startfigure = function() + result = { } + context.startnointerference() + end, + flushfigure = function(literals) + local n = #result + for i=1,#literals do + result[n+i] = literals[i] end - return multipass + end, + stopfigure = function() + context.stopnointerference() end - end -end + } --- tracing: + local specification = { + flusher = flusher, + -- incontext = true, + } -local result = { } - -local flusher = { - startfigure = function() - result = { } - context.startnointerference() - end, - flushfigure = function(literals) - local n = #result - for i=1,#literals do - result[n+i] = literals[i] - end - end, - stopfigure = function() - context.stopnointerference() + function metapost.pdfliterals(result) + metapost.flush(specification,result) + return result end -} -function metapost.pdfliterals(result) - metapost.flush(result,flusher) - return result end function metapost.totable(result,askedfig) @@ -702,7 +681,6 @@ function metapost.totable(result,askedfig) local figure = result and result.fig and result.fig[1] if figure then local results = { } - -- local objects = figure:objects() local objects = getobjects(result,figure,askedfig) for o=1,#objects do local object = objects[o] diff --git a/tex/context/base/mkiv/mlib-pdf.mkiv b/tex/context/base/mkiv/mlib-pdf.mkiv index 147b67f74..6dc73a153 100644 --- a/tex/context/base/mkiv/mlib-pdf.mkiv +++ b/tex/context/base/mkiv/mlib-pdf.mkiv @@ -47,6 +47,18 @@ \global\MPurx \zeropoint \global\MPury \zeropoint} +\let\popMPboundingbox\relax + +\unexpanded\def\pushMPboundingbox + {\edef\popMPboundingbox + {\global\MPwidth \the\MPwidth + \global\MPheight\the\MPheight + \global\MPllx \the\MPllx + \global\MPlly \the\MPlly + \global\MPurx \the\MPurx + \global\MPury \the\MPury + \relax}} + \unexpanded\def\repositionMPboxindeed {\setbox\MPbox\hpack\bgroup \kern-\MPllx @@ -76,15 +88,15 @@ \wd\MPbox\MPwidth \ht\MPbox\MPheight} -\unexpanded\def\MPtextext#1#2#3#4#5% beware: we use a different method now (see mlib-pps) - {\begingroup - \setbox\MPbox\hbox{\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% text - \MPllx-#4\onebasepoint - \MPlly-#5\onebasepoint - \repositionMPbox - \smashbox\MPbox - \box\MPbox - \endgroup} +% \unexpanded\def\MPtextext#1#2#3#4#5% beware: we use a different method now (see mlib-pps) +% {\begingroup +% \setbox\MPbox\hbox{\font\temp=#1\space at #2\onebasepoint \let\c\char \temp #3}% text +% \MPllx-#4\onebasepoint +% \MPlly-#5\onebasepoint +% \repositionMPbox +% \smashbox\MPbox +% \box\MPbox +% \endgroup} % MPLIB specific: diff --git a/tex/context/base/mkiv/mlib-pps.lua b/tex/context/base/mkiv/mlib-pps.lua index bb5ce31e5..5708577fe 100644 --- a/tex/context/base/mkiv/mlib-pps.lua +++ b/tex/context/base/mkiv/mlib-pps.lua @@ -6,8 +6,8 @@ if not modules then modules = { } end modules ['mlib-pps'] = { license = "see context related readme files", } -local format, gmatch, match, split = string.format, string.gmatch, string.match, string.split -local tonumber, type, unpack, next = tonumber, type, unpack, next +local format, gmatch, match, split, gsub = string.format, string.gmatch, string.match, string.split, string.gsub +local tonumber, type, unpack, next, select = tonumber, type, unpack, next, select local round, sqrt, min, max = math.round, math.sqrt, math.min, math.max local insert, remove, concat = table.insert, table.remove, table.concat local Cs, Cf, C, Cg, Ct, P, S, V, Carg = lpeg.Cs, lpeg.Cf, lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.S, lpeg.V, lpeg.Carg @@ -23,7 +23,6 @@ local context = context local implement = interfaces.implement local setmacro = interfaces.setmacro ------ texgetbox = tex.getbox local texsetbox = tex.setbox local textakebox = tex.takebox -- or: nodes.takebox local copy_list = node.copy_list @@ -37,6 +36,7 @@ local stoptiming = statistics.stoptiming local trace_runs = false trackers.register("metapost.runs", function(v) trace_runs = v end) local trace_textexts = false trackers.register("metapost.textexts", function(v) trace_textexts = v end) local trace_scripts = false trackers.register("metapost.scripts", function(v) trace_scripts = v end) +local trace_btexetex = false trackers.register("metapost.btexetex", function(v) trace_btexetex = v end) local report_metapost = logs.reporter("metapost") local report_textexts = logs.reporter("metapost","textexts") @@ -57,9 +57,6 @@ local cmyktorgb = colors.cmyktorgb -- or function() return 0,0,0 e local rgbtogray = colors.rgbtogray -- or function() return 0 end local cmyktogray = colors.cmyktogray -- or function() return 0 end -metapost.makempy = metapost.makempy or { nofconverted = 0 } -local makempy = metapost.makempy - local nooutercolor = "0 g 0 G" local nooutertransparency = "/Tr0 gs" -- only when set local outercolormode = 0 @@ -97,14 +94,25 @@ end local f_f = formatters["%F"] local f_f3 = formatters["%.3F"] - local f_gray = formatters["%.3F g %.3F G"] local f_rgb = formatters["%.3F %.3F %.3F rg %.3F %.3F %.3F RG"] local f_cmyk = formatters["%.3F %.3F %.3F %.3F k %.3F %.3F %.3F %.3F K"] -local f_cm = formatters["q %F %F %F %F %F %F cm"] -local f_shade = formatters["MpSh%s"] +local f_cm_b = formatters["q %.6F %.6F %.6F %.6F %.6F %.6F cm"] +local f_scn = formatters["%.3F"] +local f_shade = formatters["MpSh%s"] local f_spot = formatters["/%s cs /%s CS %s SCN %s scn"] +local s_cm_e = "Q" + +directives.register("metapost.stripzeros",function() + f_f = formatters["%N"] + f_f3 = formatters["%.3N"] + f_gray = formatters["%.3N g %.3N G"] + f_rgb = formatters["%.3N %.3N %.3N rg %.3N %.3N %.3N RG"] + f_cmyk = formatters["%.3N %.3N %.3N %.3N k %.3N %.3N %.3N %.3N K"] + f_cm_b = formatters["q %.6N %.6N %.6N %.6N %.6N %.6N cm"] + f_scn = formatters["%.3N"] +end) local function checked_color_pair(color,...) if not color then @@ -194,7 +202,8 @@ local function checkandconvert(ca,cb,model) ca = { cmyktorgb(ca[1],ca[2],ca[3],ca[4]) } cb = { cmyktorgb(cb[1],cb[2],cb[3],cb[4]) } elseif #ca == 1 then - local a, b = 1-ca[1], 1-cb[1] + local a = 1 - ca[1] + local b = 1 - cb[1] ca = { a, a, a } cb = { b, b, b } end @@ -244,16 +253,18 @@ local function preset(t,k) return v end -local function startjob(plugmode) +local function startjob(plugmode,kind) + insert(stack,top) top = { - textexts = { }, -- all boxes, optionally with a different color - texlast = 0, - texdata = setmetatableindex({},preset), -- references to textexts in order or usage - plugmode = plugmode, -- some day we can then skip all pre/postscripts + textexts = { }, -- all boxes, optionally with a different color + texstrings = { }, + texlast = 0, + texdata = setmetatableindex({},preset), -- references to textexts in order or usage + plugmode = plugmode, -- some day we can then skip all pre/postscripts } - insert(stack,top) if trace_runs then - report_metapost("starting run at level %i",#stack) + report_metapost("starting %s run at level %i in %s mode", + kind,#stack+1,plugmode and "plug" or "normal") end return top end @@ -261,16 +272,17 @@ end local function stopjob() if top then for slot, content in next, top.textexts do - flush_list(content) - if trace_textexts then - report_textexts("freeing text %s",slot) + if content then + flush_list(content) + if trace_textexts then + report_textexts("freeing text %s",slot) + end end end if trace_runs then - report_metapost("stopping run at level %i",#stack) + report_metapost("stopping run at level %i",#stack+1) end - remove(stack) - top = stack[#stack] + top = remove(stack) return top end end @@ -281,7 +293,7 @@ end -- end of new -local function settext(box,slot) +local settext = function(box,slot,str) if top then -- if trace_textexts then -- report_textexts("getting text %s from box %s",slot,box) @@ -290,10 +302,10 @@ local function settext(box,slot) end end -local function gettext(box,slot) +local gettext = function(box,slot) if top then - -- maybe check how often referenced - texsetbox(box,copy_list(top.textexts[slot])) + texsetbox(box,top.textexts[slot]) + top.textexts[slot] = false -- if trace_textexts then -- report_textexts("putting text %s in box %s",slot,box) -- end @@ -323,14 +335,19 @@ function models.all(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) elseif n == 3 then - local r, g, b = cr[1], cr[2], cr[3] + local r = cr[1] + local g = cr[2] + local b = cr[3] if r == g and g == b then return checked_color_pair(f_gray,r,r) else return checked_color_pair(f_rgb,r,g,b,r,g,b) end else - local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + local c = cr[1] + local m = cr[2] + local y = cr[3] + local k = cr[4] if c == m and m == y and y == 0 then k = 1 - k return checked_color_pair(f_gray,k,k) @@ -342,10 +359,15 @@ function models.all(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) elseif n == 3 then - local r, g, b = cr[1], cr[2], cr[3] + local r = cr[1] + local g = cr[2] + local b = cr[3] return checked_color_pair(f_rgb,r,g,b,r,g,b) else - local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + local c = cr[1] + local m = cr[2] + local y = cr[3] + local k = cr[4] return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end @@ -359,14 +381,19 @@ function models.rgb(cr) local s = cr[1] checked_color_pair(f_gray,s,s) elseif n == 3 then - local r, g, b = cr[1], cr[2], cr[3] + local r = cr[1] + local g = cr[2] + local b = cr[3] if r == g and g == b then return checked_color_pair(f_gray,r,r) else return checked_color_pair(f_rgb,r,g,b,r,g,b) end else - local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + local c = cr[1] + local m = cr[2] + local y = cr[3] + local k = cr[4] if c == m and m == y and y == 0 then k = 1 - k return checked_color_pair(f_gray,k,k) @@ -379,11 +406,12 @@ function models.rgb(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) else + local r = cr[1] + local g = cr[2] + local b = cr[3] local r, g, b if n == 3 then - r, g, b = cmyktorgb(cr[1],cr[2],cr[3],cr[4]) - else - r, g, b = cr[1], cr[2], cr[3] + r, g, b = cmyktorgb(r,g,b,cr[4]) end return checked_color_pair(f_rgb,r,g,b,r,g,b) end @@ -398,7 +426,9 @@ function models.cmyk(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) elseif n == 3 then - local r, g, b = cr[1], cr[2], cr[3] + local r = cr[1] + local g = cr[2] + local b = cr[3] if r == g and g == b then return checked_color_pair(f_gray,r,r) else @@ -406,7 +436,10 @@ function models.cmyk(cr) return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end else - local c, m, y, k = cr[1], cr[2], cr[3], cr[4] + local c = cr[1] + local m = cr[2] + local y = cr[3] + local k = cr[4] if c == m and m == y and y == 0 then k = k - 1 return checked_color_pair(f_gray,k,k) @@ -418,18 +451,20 @@ function models.cmyk(cr) local s = cr[1] return checked_color_pair(f_gray,s,s) else - local c, m, y, k + local c = cr[1] + local m = cr[2] + local y = cr[3] + local k = cr[4] if n == 3 then - c, m, y, k = rgbtocmyk(cr[1],cr[2],cr[3]) - else - c, m, y, k = cr[1], cr[2], cr[3], cr[4] + c, m, y, k = rgbtocmyk(c,m,y) end return checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) end end function models.gray(cr) - local n, s = #cr, 0 + local n = #cr + local s = 0 if n == 0 then return checked_color_pair() elseif n == 4 then @@ -454,76 +489,9 @@ setmetatableindex(models, function(t,k) end) local function colorconverter(cs) - -- return models[colors.currentmodel()](cs) return models[outercolormodel](cs) end -local btex = P("btex") -local etex = P(" etex") -local vtex = P("verbatimtex") -local ttex = P("textext") -local gtex = P("graphictext") -local multipass = P("forcemultipass") -local spacing = S(" \n\r\t\v")^0 -local dquote = P('"') - -local found, forced = false, false - -local function convert(str) - found = true - return "rawtextext(\"" .. str .. "\")" -- centered -end -local function ditto(str) - return "\" & ditto & \"" -end -local function register() - found = true -end -local function force() - forced = true -end - -local texmess = (dquote/ditto + (1 - etex))^0 - -local function ignore(s) - report_metapost("ignoring verbatim tex: %s",s) - return "" -end - --- local parser = P { --- [1] = Cs((V(2)/register + V(4)/ignore + V(3)/convert + V(5)/force + 1)^0), --- [2] = ttex + gtex, --- [3] = btex * spacing * Cs(texmess) * etex, --- [4] = vtex * spacing * Cs(texmess) * etex, --- [5] = multipass, -- experimental, only for testing --- } - --- currently a a one-liner produces less code - --- textext.*(".*") can have "'s but tricky parsing as we can have concatenated strings --- so this is something for a boring plane or train trip and we might assume proper mp --- input anyway - -local parser = Cs(( - (ttex + gtex)/register - + (btex * spacing * Cs(texmess) * etex)/convert - + (vtex * spacing * Cs(texmess) * etex)/ignore - + 1 -)^0) - -local checking_enabled = false directives.register("metapost.checktexts",function(v) checking_enabled = v end) - -local function checktexts(str) - if checking_enabled then - found, forced = false, false - return lpegmatch(parser,str), found, forced - else - return str - end -end - -metapost.checktexts = checktexts - local factor = 65536*(7227/7200) implement { @@ -541,42 +509,15 @@ local function sxsy(wd,ht,dp) -- helper for text return (wd ~= 0 and factor/wd) or 0, (hd ~= 0 and factor/hd) or 0 end +metapost.sxsy = sxsy + -- for stock mp we need to declare the booleans first -local no_first_run = "boolean mfun_first_run ; mfun_first_run := false ;" -local do_first_run = "boolean mfun_first_run ; mfun_first_run := true ;" -local no_trial_run = "boolean mfun_trial_run ; mfun_trial_run := false ;" -local do_trial_run = "boolean mfun_trial_run ; mfun_trial_run := true ;" local do_begin_fig = "; beginfig(1) ; " local do_end_fig = "; endfig ;" local do_safeguard = ";" --- local f_text_data = formatters["mfun_tt_w[%i] := %f ; mfun_tt_h[%i] := %f ; mfun_tt_d[%i] := %f ;"] --- --- function metapost.textextsdata() --- local textexts = top.textexts --- local collected = { } --- local nofcollected = 0 --- for k, data in sortedhash(top.texdata) do -- sort is nicer in trace --- local texorder = data.texorder --- for n=1,#texorder do --- local box = textexts[texorder[n]] --- if box then --- local wd, ht, dp = box.width/factor, box.height/factor, box.depth/factor --- if trace_textexts then --- report_textexts("passed data item %s:%s > (%p,%p,%p)",k,n,wd,ht,dp) --- end --- nofcollected = nofcollected + 1 --- collected[nofcollected] = f_text_data(n,wd,n,ht,n,dp) --- else --- break --- end --- end --- end --- return collected --- end - -function metapost.textextsdata() +function metapost.preparetextextsdata() local textexts = top.textexts local collected = { } for k, data in sortedhash(top.texdata) do -- sort is nicer in trace @@ -590,18 +531,10 @@ function metapost.textextsdata() end end end - mp.tt_initialize(collected) + mp.mf_tt_initialize(collected) end - -metapost.intermediate = metapost.intermediate or { } -metapost.intermediate.actions = metapost.intermediate.actions or { } - -metapost.method = 1 -- 1:dumb 2:clever - --- maybe we can latelua the texts some day - -local processmetapost = metapost.process +local runmetapost = metapost.run local function checkaskedfig(askedfig) -- return askedfig, wrappit if not askedfig then @@ -624,231 +557,98 @@ local function extrapass() if trace_runs then report_metapost("second run of job %s, asked figure %a",top.nofruns,top.askedfig) end - local textexts = metapost.textextsdata() - processmetapost(top.mpx, { - top.wrappit and do_begin_fig or "", - no_trial_run, - textexts and concat(textexts," ;\n") or "", - top.initializations, - do_safeguard, - top.data, - top.wrappit and do_end_fig or "", - }, false, nil, false, true, top.askedfig) + metapost.preparetextextsdata() + runmetapost { + mpx = top.mpx, + askedfig = top.askedfig, + incontext = true, + data = { + top.wrappit and do_begin_fig or "", + no_trial_run, + top.initializations, + do_safeguard, + top.data, + top.wrappit and do_end_fig or "", + }, + } end -function metapost.graphic_base_pass(specification) -- name will change (see mlib-ctx.lua) - local top = startjob(true) - -- +-- This one is called from the \TEX\ end so the specification is different +-- from the specification to metapost,run cum suis! The definitions and +-- extension used to be handled here but are now delegated to the format +-- initializers because we need to accumulate them for nested instances (a +-- side effect of going single pass). + +function metapost.graphic_base_pass(specification) + local top = startjob(true,"base") local mpx = specification.mpx -- mandate local data = specification.data or "" - local definitions = specification.definitions or "" - -- local extensions = metapost.getextensions(specification.instance,specification.useextensions) - local extensions = specification.extensions or "" local inclusions = specification.inclusions or "" local initializations = specification.initializations or "" - local askedfig = specification.figure -- no default else no wrapper + local askedfig, + wrappit = checkaskedfig(specification.figure) + nofruns = nofruns + 1 + top.askedfig = askedfig + top.wrappit = wrappit + top.nofruns = nofruns metapost.namespace = specification.namespace or "" - -- - local askedfig, wrappit = checkaskedfig(askedfig) - -- - nofruns = nofruns + 1 - -- - top.askedfig = askedfig - top.wrappit = wrappit - top.nofruns = nofruns - -- - local done_1, done_2, done_3, forced_1, forced_2, forced_3 - if checking_enabled then - data, done_1, forced_1 = checktexts(data) - if extensions == "" then - extensions, done_2, forced_2 = "", false, false - else - extensions, done_2, forced_2 = checktexts(extensions) - end - if inclusions == "" then - inclusions, done_3, forced_3 = "", false, false - else - inclusions, done_3, forced_3 = checktexts(inclusions) - end - end - top.intermediate = false - top.multipass = false -- no needed here - top.mpx = mpx - top.data = data - top.initializations = initializations - local method = metapost.method + top.mpx = mpx + top.data = data + top.initializations = initializations if trace_runs then - if method == 1 then - report_metapost("forcing two runs due to library configuration") - elseif method ~= 2 then - report_metapost("ignoring run due to library configuration") - elseif not (done_1 or done_2 or done_3) then - report_metapost("forcing one run only due to analysis") - elseif done_1 then - report_metapost("forcing at max two runs due to main code") - elseif done_2 then - report_metapost("forcing at max two runs due to extensions") - else - report_metapost("forcing at max two runs due to inclusions") - end + report_metapost("running job %s, asked figure %a",nofruns,askedfig) end - if method == 1 or (method == 2 and (done_1 or done_2 or done_3)) then - if trace_runs then - report_metapost("first run of job %s, asked figure %a",nofruns,askedfig) - end - -- first true means: trialrun, second true means: avoid extra run if no multipass - local flushed = processmetapost(mpx, { - definitions, - extensions, - inclusions, - wrappit and do_begin_fig or "", - do_first_run, - do_trial_run, - initializations, - do_safeguard, - data, - wrappit and do_end_fig or "", - }, true, nil, not (forced_1 or forced_2 or forced_3), false, askedfig) - if top.intermediate then - for _, action in next, metapost.intermediate.actions do - action() - end - end - if not flushed or not metapost.optimize then - -- tricky, we can only ask once for objects and therefore - -- we really need a second run when not optimized - -- context.MPLIBextrapass(askedfig) - context(extrapass) - end - else - if trace_runs then - report_metapost("running job %s, asked figure %a",nofruns,askedfig) - end - processmetapost(mpx, { - definitions, - extensions, + runmetapost { + mpx = mpx, + askedfig = askedfig, + incontext = true, + data = { inclusions, wrappit and do_begin_fig or "", - do_first_run, - no_trial_run, initializations, do_safeguard, data, wrappit and do_end_fig or "", - }, false, nil, false, false, askedfig) - end + }, + } context(stopjob) end --- we overload metapost.process here - -function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig, plugmode) -- overloads - startjob(plugmode) - processmetapost(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) - stopjob() -end - -local start = [[\starttext]] -local preamble = [[\def\MPLIBgraphictext#1{\startTEXpage[scale=10000]#1\stopTEXpage}]] -local stop = [[\stoptext]] - -local mpyfilename = nil - -function makempy.registerfile(filename) - mpyfilename = filename +local function oldschool(mpx, data, trial_run, flusher, was_multi_pass, is_extra_pass, askedfig, incontext) + metapost.process { + mpx = mpx, + flusher = flusher, + askedfig = askedfig, + useplugins = incontext, + incontext = incontext, + data = data, + } end -implement { - name = "registermpyfile", - actions = makempy.registerfile, - arguments = "string" -} - -local pdftompy = sandbox.registerrunner { - name = "mpy:pstoedit", - program = "pstoedit", - template = "-ssp -dt -f mpost %pdffile% %mpyfile%", - checkers = { - pdffile = "writable", - mpyfile = "readable", - }, - reporter = report_metapost, -} - -local textopdf = sandbox.registerrunner { - name = "mpy:context", - program = "context", - template = "--once %runmode% %texfile%", - checkers = { - runmode = "string", - texfile = "readable", - }, - reporter = report_metapost, -} - -function makempy.processgraphics(graphics) - if #graphics == 0 then - return - end - if mpyfilename and exists(mpyfilename) then - report_metapost("using file: %s",mpyfilename) - return - end - makempy.nofconverted = makempy.nofconverted + 1 - starttiming(makempy) - local mpofile = tex.jobname .. "-mpgraph" - local mpyfile = file.replacesuffix(mpofile,"mpy") - local pdffile = file.replacesuffix(mpofile,"pdf") - local texfile = file.replacesuffix(mpofile,"tex") - savedata(texfile, { start, preamble, metapost.tex.get(), concat(graphics,"\n"), stop }, "\n") - textopdf { - runmode = tex.interactionmode == 0 and "--batchmode" or "", - texfile = texfile, - } - if exists(pdffile) then - pdftompy { - pdffile = pdffile, - mpyfile = mpyfile, - } - if exists(mpyfile) then - local result, r = { }, 0 - local data = io.loaddata(mpyfile) - if data and #data > 0 then - for figure in gmatch(data,"beginfig(.-)endfig") do - r = r + 1 - result[r] = formatters["begingraphictextfig%sendgraphictextfig ;\n"](figure) - end - savedata(mpyfile,concat(result,"")) - end - end +function metapost.process(specification,...) + if type(specification) ~= "table" then + oldschool(specification,...) + else + startjob(specification.incontext or specification.useplugins,"process") + runmetapost(specification) + stopjob() end - stoptiming(makempy) end -- -- the new plugin handler -- -- -local sequencers = utilities.sequencers -local appendgroup = sequencers.appendgroup -local appendaction = sequencers.appendaction +local sequencers = utilities.sequencers +local appendgroup = sequencers.appendgroup +local appendaction = sequencers.appendaction -local resetter = nil -local analyzer = nil -local processor = nil - -local resetteractions = sequencers.new { arguments = "t" } -local analyzeractions = sequencers.new { arguments = "object,prescript" } -local processoractions = sequencers.new { arguments = "object,prescript,before,after" } +local resetteractions = sequencers.new { arguments = "t" } +local processoractions = sequencers.new { arguments = "object,prescript,before,after" } appendgroup(resetteractions, "system") -appendgroup(analyzeractions, "system") appendgroup(processoractions,"system") -- later entries come first ---~ local scriptsplitter = Cf(Ct("") * ( ---~ Cg(C((1-S("= "))^1) * S("= ")^1 * C((1-S("\n\r"))^0) * S("\n\r")^0) ---~ )^0, rawset) - local scriptsplitter = Ct ( Ct ( C((1-S("= "))^1) * S("= ")^1 * C((1-S("\n\r"))^0) * S("\n\r")^0 )^0 ) @@ -857,22 +657,24 @@ local function splitprescript(script) local hash = lpegmatch(scriptsplitter,script) for i=#hash,1,-1 do local h = hash[i] -if h == "reset" then - for k, v in next, hash do - if type(k) ~= "number" then - hash[k] = nil + if h == "reset" then + for k, v in next, hash do + if type(k) ~= "number" then + hash[k] = nil + end + end + else + hash[h[1]] = h[2] end end -else - hash[h[1]] = h[2] -end - end if trace_scripts then report_scripts(table.serialize(hash,"prescript")) end return hash end +metapost.splitprescript = splitprescript + -- -- not used: -- -- local function splitpostscript(script) @@ -906,27 +708,9 @@ end function metapost.resetplugins(t) -- intialize plugins, before figure if top.plugmode then - outercolormodel = colors.currentmodel() -- currently overloads the one set at the tex end - - -- plugins can have been added - resetter = resetteractions.runner - analyzer = analyzeractions.runner - processor = processoractions.runner - -- let's apply one runner - resetter(t) - end -end - -function metapost.analyzeplugins(object) -- each object (first pass) - if top.plugmode then - local prescript = object.prescript -- specifications - if prescript and #prescript > 0 then - analyzer(object,splitprescript(prescript) or {}) - return top.multipass - end + resetteractions.runner(t) end - return false end function metapost.processplugins(object) -- each object (second pass) @@ -935,7 +719,7 @@ function metapost.processplugins(object) -- each object (second pass) if prescript and #prescript > 0 then local before = { } local after = { } - processor(object,splitprescript(prescript) or {},before,after) + processoractions.runner(object,splitprescript(prescript) or {},before,after) return #before > 0 and before, #after > 0 and after else local c = object.color @@ -954,11 +738,16 @@ local basepoints = number.dimenfactors["bp"] local function cm(object) local op = object.path if op then - local first, second, fourth = op[1], op[2], op[4] + local first = op[1] + local second = op[2] + local fourth = op[4] if fourth then - local tx, ty = first.x_coord , first.y_coord - local sx, sy = second.x_coord - tx, fourth.y_coord - ty - local rx, ry = second.y_coord - ty, fourth.x_coord - tx + local tx = first.x_coord + local ty = first.y_coord + local sx = second.x_coord - tx + local sy = fourth.y_coord - ty + local rx = second.y_coord - ty + local ry = fourth.x_coord - tx if sx == 0 then sx = 0.00001 end if sy == 0 then sy = 0.00001 end return sx, rx, ry, sy, tx, ty @@ -967,6 +756,8 @@ local function cm(object) return 1, 0, 0, 1, 0, 0 -- weird case end +metapost.cm = cm + -- color local function cl_reset(t) @@ -975,157 +766,195 @@ end -- text -local function tx_reset() - if top then - -- why ? - top.texhash = { } - top.texlast = 0 +local tx_reset, tx_process do + + local eol = S("\n\r")^1 + local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0) + local splitter = Ct( + ( ( + P("s:") * C((1-eol)^1) + + P("n:") * ((1-eol)^1/tonumber) + + P("b:") * ((1-eol)^1/toboolean) + ) * eol^0 )^0) + + local function applyformat(s) + local t = lpegmatch(splitter,s) + if #t == 1 then + return s + else + local f = lpegmatch(cleaner,t[1]) + return formatters[f](unpack(t,2)) + end end -end -local fmt = formatters["%s %s %s % t"] ------ pat = tsplitat(":") -local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work - -local f_gray_yes = formatters["s=%F,a=%F,t=%F"] -local f_gray_nop = formatters["s=%F"] -local f_rgb_yes = formatters["r=%F,g=%F,b=%F,a=%F,t=%F"] -local f_rgb_nop = formatters["r=%F,g=%F,b=%F"] -local f_cmyk_yes = formatters["c=%F,m=%F,y=%F,k=%F,a=%F,t=%F"] -local f_cmyk_nop = formatters["c=%F,m=%F,y=%F,k=%F"] - -local ctx_MPLIBsetNtext = context.MPLIBsetNtext -local ctx_MPLIBsetCtext = context.MPLIBsetCtext -local ctx_MPLIBsettext = context.MPLIBsettext - --- we reuse content when possible --- we always create at least one instance (for dimensions) --- we make sure we don't do that when we use one (else counter issues with e.g. \definelabel) - -local eol = S("\n\r")^1 -local cleaner = Cs((P("@@")/"@" + P("@")/"%%" + P(1))^0) -local splitter = Ct( - ( ( - P("s:") * C((1-eol)^1) - + P("n:") * ((1-eol)^1/tonumber) - + P("b:") * ((1-eol)^1/toboolean) - ) * eol^0 )^0) - -local function applyformat(s) - local t = lpegmatch(splitter,s) - if #t == 1 then - return s - else - local f = lpegmatch(cleaner,t[1]) - return formatters[f](unpack(t,2)) - end -end - -local function tx_analyze(object,prescript) - local data = top.texdata[metapost.properties.number] - local tx_stage = prescript.tx_stage - if tx_stage == "trial" then - local tx_trial = data.textrial + 1 - data.textrial = tx_trial - local tx_number = tonumber(prescript.tx_number) - local s = object.postscript or "" - local c = object.color -- only simple ones, no transparency - if #c == 0 then - local txc = prescript.tx_color - if txc then - c = lpegmatch(pat,txc) + local fmt = formatters["%s %s %s % t"] + ----- pat = tsplitat(":") + local pat = lpeg.tsplitter(":",tonumber) -- so that %F can do its work + + local f_gray_yes = formatters["s=%.3F,a=%i,t=%.3F"] + local f_gray_nop = formatters["s=%.3F"] + local f_rgb_yes = formatters["r=%.3F,g=%.3F,b=%.3F,a=%.3F,t=%.3F"] + local f_rgb_nop = formatters["r=%.3F,g=%.3F,b=%.3F"] + local f_cmyk_yes = formatters["c=%.3F,m=%.3F,y=%.3F,k=%.3F,a=%.3F,t=%.3F"] + local f_cmyk_nop = formatters["c=%.3F,m=%.3F,y=%.3F,k=%.3F"] + + directives.register("metapost.stripzeros",function() + f_gray_yes = formatters["s=%.3N,a=%i,t=%.3N"] + f_gray_nop = formatters["s=%.3N"] + f_rgb_yes = formatters["r=%.3N,g=%.3N,b=%.3N,a=%.3N,t=%.3N"] + f_rgb_nop = formatters["r=%.3N,g=%.3N,b=%.3N"] + f_cmyk_yes = formatters["c=%.3N,m=%.3N,y=%.3N,k=%.3N,a=%.3N,t=%.3N"] + f_cmyk_nop = formatters["c=%.3N,m=%.3N,y=%.3N,k=%.3N"] + end) + + local ctx_MPLIBsetNtext = context.MPLIBsetNtextX + local ctx_MPLIBsetCtext = context.MPLIBsetCtextX + local ctx_MPLIBsettext = context.MPLIBsettextX + + local bp = number.dimenfactors.bp + + local mp_index = 0 + local mp_target = 0 + local mp_c = nil + local mp_a = nil + local mp_t = nil + + local function processtext() + local mp_text = top.texstrings[mp_index] + if not mp_text then + report_textexts("missing text for index %a",mp_index) + elseif not mp_c then + ctx_MPLIBsetNtext(mp_target,mp_text) + elseif #mp_c == 1 then + if mp_a and mp_t then + ctx_MPLIBsetCtext(mp_target,f_gray_yes(mp_c[1],mp_a,mp_t),mp_text) + else + ctx_MPLIBsetCtext(mp_target,f_gray_nop(mp_c[1]),mp_text) end - end - if prescript.tx_type == "format" then - s = applyformat(s) - end - local a = tonumber(prescript.tr_alternative) - local t = tonumber(prescript.tr_transparency) - local h = fmt(tx_number,a or "-",t or "-",c or "-") - local n = data.texhash[h] -- todo: hashed variant with s (nicer for similar labels) - if n then - data.texslots[tx_trial] = n - if trace_textexts then - report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"old",n,h,s) + elseif #mp_c == 3 then + if mp_a and mp_t then + ctx_MPLIBsetCtext(mp_target,f_rgb_nop(mp_c[1],mp_c[2],mp_c[3],mp_a,mp_t),mp_text) + else + ctx_MPLIBsetCtext(mp_target,f_rgb_nop(mp_c[1],mp_c[2],mp_c[3]),mp_text) end - elseif prescript.tx_global == "yes" and data.texorder[tx_number] then - -- we already have one flush and don't want it redone .. this needs checking - if trace_textexts then - report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"ignored",tx_last,h,s) + elseif #mp_c == 4 then + if mp_a and mp_t then + ctx_MPLIBsetCtext(mp_target,f_cmyk_yes(mp_c[1],mp_c[2],mp_c[3],mp_c[4],mp_a,mp_t),mp_text) + else + ctx_MPLIBsetCtext(mp_target,f_cmyk_nop(mp_c[1],mp_c[2],mp_c[3],mp_c[4]),mp_text) end else - local tx_last = top.texlast + 1 - top.texlast = tx_last - -- report_textexts("tex string: %s",s) - if not c then - ctx_MPLIBsetNtext(tx_last,s) - elseif #c == 1 then - if a and t then - ctx_MPLIBsetCtext(tx_last,f_gray_yes(c[1],a,t),s) - else - ctx_MPLIBsetCtext(tx_last,f_gray_nop(c[1]),s) - end - elseif #c == 3 then - if a and t then - ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3],a,t),s) - else - ctx_MPLIBsetCtext(tx_last,f_rgb_nop(c[1],c[2],c[3]),s) - end - elseif #c == 4 then - if a and t then - ctx_MPLIBsetCtext(tx_last,f_cmyk_yes(c[1],c[2],c[3],c[4],a,t),s) - else - ctx_MPLIBsetCtext(tx_last,f_cmyk_nop(c[1],c[2],c[3],c[4]),s) - end - else - ctx_MPLIBsetNtext(tx_last,s) + -- can't happen + ctx_MPLIBsetNtext(mp_target,mp_text) + end + end + + function mp.mf_some_text(index,str) + mp_target = index + mp_index = index + mp_c = nil + mp_a = nil + mp_t = nil + top.texstrings[mp_index] = str + tex.runtoks("mptexttoks") + local box = textakebox("mptextbox") + top.textexts[mp_target] = box + mp.triplet(bp*box.width,bp*box.height,bp*box.depth) + madetext = nil + end + + local madetext = nil + + function mp.mf_made_text(index) + mp.mf_some_text(index,madetext) + end + + function metapost.maketext(s,mode) + if mode and mode == 1 then + if trace_btexetex then + report_metapost("ignoring verbatimtex: [[%s]]",s) end - top.multipass = true - data.texhash [h] = tx_last - -- data.texhash [tx_number] = tx_last - data.texslots[tx_trial] = tx_last - data.texorder[tx_number] = tx_last - if trace_textexts then - report_textexts("stage %a, usage %a, number %a, %s %a, hash %a, text %a",tx_stage,tx_trial,tx_number,"new",tx_last,h,s) + else + if trace_btexetex then + report_metapost("handling btex ... etex: [[%s]]",s) end + -- madetext = utilities.strings.collapse(s) + madetext = s + return "rawmadetext" end - elseif tx_stage == "extra" then - local tx_trial = data.textrial + 1 - data.textrial = tx_trial - local tx_number = tonumber(prescript.tx_number) - if not data.texorder[tx_number] then - local s = object.postscript or "" - local tx_last = top.texlast + 1 - top.texlast = tx_last - ctx_MPLIBsettext(tx_last,s) - top.multipass = true - data.texslots[tx_trial] = tx_last - data.texorder[tx_number] = tx_last - if trace_textexts then - report_textexts("stage %a, usage %a, number %a, extra %a, text %a",tx_stage,tx_trial,tx_number,tx_last,s) + end + + function mp.mf_formatted_text(index,fmt,...) + local t = { } + for i=1,select("#",...) do + local ti = select(i,...) + if type(ti) ~= "table" then + t[#t+1] = ti end end + local f = lpegmatch(cleaner,fmt) + local s = formatters[f](unpack(t)) or "" + mp.mf_some_text(index,s) end -end -local function tx_process(object,prescript,before,after) - local data = top.texdata[metapost.properties.number] - local tx_number = tonumber(prescript.tx_number) - if tx_number then - local tx_stage = prescript.tx_stage - if tx_stage == "final" then - local tx_final = data.texfinal + 1 - data.texfinal = tx_final - local n = data.texslots[tx_final] + interfaces.implement { + name = "mptexttoks", + actions = processtext, + } + + tx_reset = function() + if top then + top.texhash = { } + top.texlast = 0 + end + end + + tx_process = function(object,prescript,before,after) + local data = top.texdata[metapost.properties.number] + local index = tonumber(prescript.tx_index) + if index then if trace_textexts then - report_textexts("stage %a, usage %a, number %a, use %a",tx_stage,tx_final,tx_number,n) + report_textexts("using index %a",index) + end + -- + mp_c = object.color + if #mp_c == 0 then + local txc = prescript.tx_color + if txc then + mp_c = lpegmatch(pat,txc) + end + end + mp_a = tonumber(prescript.tr_alternative) + mp_t = tonumber(prescript.tr_transparency) + -- + mp_index = index + mp_target = top.texlast - 1 + top.texlast = mp_target + -- + local mp_text = top.texstrings[mp_index] + local box + if prescript.tx_cache == "no" then + tex.runtoks("mptexttoks") + box = textakebox("mptextbox") + else + local hash = fmt(mp_text,mp_a or "-",mp_t or "-",mp_c or "-") + box = data.texhash[hash] + if box then + box = copy_list(box) + else + tex.runtoks("mptexttoks") + box = textakebox("mptextbox") + data.texhash[hash] = box + end end - local sx, rx, ry, sy, tx, ty = cm(object) -- needs to be frozen outside the function - local box = top.textexts[n] + top.textexts[mp_target] = box + -- if box then + -- we need to freeze the variables outside the function + local sx, rx, ry, sy, tx, ty = cm(object) + local target = mp_target before[#before+1] = function() - -- flush always happens, we can have a special flush function injected before - context.MPLIBgettextscaledcm(n, + context.MPLIBgettextscaledcm(target, f_f(sx), -- bah ... %s no longer checks f_f(rx), -- bah ... %s no longer checks f_f(ry), -- bah ... %s no longer checks @@ -1136,7 +965,7 @@ local function tx_process(object,prescript,before,after) end else before[#before+1] = function() - report_textexts("unknown %s",tx_number) + report_textexts("unknown %s",index) end end if not trace_textexts then @@ -1147,6 +976,7 @@ local function tx_process(object,prescript,before,after) object.istext = true end end + end -- we could probably redo normal textexts in the next way but as it's rather optimized @@ -1182,30 +1012,31 @@ end -- graphics (we use the given index because pictures can be reused) -local graphics = { } -function metapost.intermediate.actions.makempy() - if #graphics > 0 then - makempy.processgraphics(graphics) - graphics = { } -- ? could be gt_reset - end -end +local gt_reset, gt_process do + + local graphics = { } -local function gt_analyze(object,prescript) - local gt_stage = prescript.gt_stage - local gt_index = tonumber(prescript.gt_index) - if gt_stage == "trial" and not graphics[gt_index] then - graphics[gt_index] = formatters["\\MPLIBgraphictext{%s}"](object.postscript or "") - top.intermediate = true - top.multipass = true + + local mp_index = 0 + local mp_str = "" + + function mp.mf_graphic_text(index,str) + if not graphics[index] then + mp_index = index + mp_str = str + tex.runtoks("mpgraphictexttoks") + end end -end --- local function gt_process(object,prescript,before,after) --- local gt_stage = prescript.gt_stage --- if gt_stage == "final" then --- end --- end + interfaces.implement { + name = "mpgraphictexttoks", + actions = function() + context.MPLIBgraphictext(mp_index,mp_str) + end, + } + +end -- shades @@ -1342,7 +1173,7 @@ end local function bm_process(object,prescript,before,after) local bm_xresolution = prescript.bm_xresolution if bm_xresolution then - before[#before+1] = f_cm(cm(object)) + before[#before+1] = f_cm_b(cm(object)) before[#before+1] = function() figures.bitmapimage { xresolution = tonumber(bm_xresolution), @@ -1352,7 +1183,7 @@ local function bm_process(object,prescript,before,after) data = object.postscript } end - before[#before+1] = "Q" + before[#before+1] = s_cm_e object.path = false object.color = false object.grouped = true @@ -1364,10 +1195,13 @@ end local function ps_process(object,prescript,before,after) local ps_label = prescript.ps_label if ps_label then - local op = object.path - local first, third = op[1], op[3] - local x, y = first.x_coord, first.y_coord - local w, h = third.x_coord - x, third.y_coord - y + local op = object.path + local first = op[1] + local third = op[3] + local x = first.x_coord + local y = first.y_coord + local w = third.x_coord - x + local h = third.y_coord - y local properties = metapost.properties x = x - properties.llx y = properties.ury - y @@ -1380,14 +1214,33 @@ end -- figures +-- local sx, rx, ry, sy, tx, ty = cm(object) +-- sxsy(box.width,box.height,box.depth)) + +function mp.mf_external_figure(filename) + local f = figures.getinfo(filename) + local w = 0 + local h = 0 + if f then + local u = f.used + if u and u.fullname then + w = u.width or 0 + h = u.height or 0 + end + else + report_metapost("external figure %a not found",filename) + end + mp.triplet(w/65536,h/65536,0) +end + local function fg_process(object,prescript,before,after) local fg_name = prescript.fg_name if fg_name then - before[#before+1] = f_cm(cm(object)) -- beware: does not use the cm stack + before[#before+1] = f_cm_b(cm(object)) -- beware: does not use the cm stack before[#before+1] = function() context.MPLIBfigure(fg_name,prescript.fg_mask or "") end - before[#before+1] = "Q" + before[#before+1] = s_cm_e object.path = false object.grouped = true end @@ -1411,14 +1264,27 @@ local remappers = { [4] = formatters["c=%s,m=%s,y=%s,k=%s"], } +local processlast = 0 +local processhash = setmetatableindex(function(t,k) + processlast = processlast + 1 + local v = formatters["mp_%s"](processlast) + defineprocesscolor(v,k,true,true) + t[k] = v + return v +end) + +local function checked_transparency(alternative,transparency,before,after) + alternative = tonumber(alternative) or 1 + transparency = tonumber(transparency) or 0 + before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,alternative,transparency,true)) + after [#after +1] = "/Tr0 gs" -- outertransparency +end + local function tr_process(object,prescript,before,after) -- before can be shortcut to t local tr_alternative = prescript.tr_alternative if tr_alternative then - tr_alternative = tonumber(tr_alternative) - local tr_transparency = tonumber(prescript.tr_transparency) - before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,tr_alternative,tr_transparency,true)) - after[#after+1] = "/Tr0 gs" -- outertransparency + checked_transparency(tr_alternative,prescript.tr_transparency,before,after) end local cs = object.color if cs and #cs > 0 then @@ -1429,29 +1295,35 @@ local function tr_process(object,prescript,before,after) else local sp_name = prescript.sp_name or "black" if sp_type == "spot" then - local sp_value = prescript.sp_value or "s:1" - local sp_temp = formatters["mp:%s"](sp_value) - local s = split(sp_value,":") - local r = remappers[#s] - defineprocesscolor(sp_temp,r and r(unpack(s)) or "s=0",true,true) - definespotcolor(sp_name,sp_temp,"p=1",true) + local sp_value = prescript.sp_value or "1" + local components = split(sp_value,":") + local specification = remappers[#components] + if specification then + specification = specification(unpack(components)) + else + specification = "s=0" + end + local sp_spec = processhash[specification] + definespotcolor(sp_name,sp_spec,"p=1",true) sp_type = "named" elseif sp_type == "multitone" then -- (fractions of a multitone) don't work well in mupdf - local sp_value = prescript.sp_value or "s:1" - local sp_spec = { } + local sp_value = prescript.sp_value or "1" + local sp_specs = { } local sp_list = split(sp_value," ") for i=1,#sp_list do - local v = sp_list[i] - local t = formatters["mp:%s"](v) - local s = split(v,":") - local r = remappers[#s] - defineprocesscolor(t,r and r(unpack(s)) or "s=0",true,true) - local tt = formatters["ms:%s"](v) - definespotcolor(tt,t,"p=1",true) - sp_spec[#sp_spec+1] = formatters["%s=1"](t) + local sp_value = sp_list[i] + local components = split(sp_value,":") + local specification = remappers[#components] + if specification then + specification = specification(unpack(components)) + else + specification = "s=0" + end + local sp_spec = processhash[specification] + sp_specs[i] = formatters["%s=1"](sp_spec) end - sp_spec = concat(sp_spec,",") - definemultitonecolor(sp_name,sp_spec,"","",true) + sp_specs = concat(sp_specs,",") + definemultitonecolor(sp_name,sp_specs,"","") sp_type = "named" end if sp_type == "named" then @@ -1463,8 +1335,7 @@ local function tr_process(object,prescript,before,after) local t = t_list[sp_name] -- string or attribute local v = t and transparencyvalue(t) if v then - before[#before+1] = formatters["/Tr%s gs"](registertransparency(nil,v[1],v[2],true)) - after[#after+1] = "/Tr0 gs" -- outertransparency + checked_transparency(v[1],v[2],before,after) end end local c = c_list[sp_name] -- string or attribute @@ -1472,29 +1343,34 @@ local function tr_process(object,prescript,before,after) if v then -- all=1 gray=2 rgb=3 cmyk=4 local colorspace = v[1] - local f = cs[1] + local factor = cs[1] if colorspace == 2 then - local s = f*v[2] + local s = factor * v[2] c_b, c_a = checked_color_pair(f_gray,s,s) elseif colorspace == 3 then - local r, g, b = f*v[3], f*v[4], f*v[5] + local r = factor * v[3] + local g = factor * v[4] + local b = factor * v[5] c_b, c_a = checked_color_pair(f_rgb,r,g,b,r,g,b) elseif colorspace == 4 or colorspace == 1 then - local c, m, y, k = f*v[6], f*v[7], f*v[8], f*v[9] + local c = factor * v[6] + local m = factor * v[7] + local y = factor * v[8] + local k = factor * v[9] c_b, c_a = checked_color_pair(f_cmyk,c,m,y,k,c,m,y,k) elseif colorspace == 5 then -- not all viewers show the fractions ok local name = v[10] local value = split(v[13],",") - if f ~= 1 then + if factor ~= 1 then for i=1,#value do - value[i] = f * (tonumber(value[i]) or 1) + value[i] = f_scn(factor * (tonumber(value[i]) or 1)) end end value = concat(value," ") c_b, c_a = checked_color_pair(f_spot,name,name,value,value) else - local s = f*v[2] + local s = factor *v[2] c_b, c_a = checked_color_pair(f_gray,s,s) end end @@ -1519,10 +1395,6 @@ end -- groups -local types = { - isolated -} - local function gr_process(object,prescript,before,after) local gr_state = prescript.gr_state if not gr_state then @@ -1530,7 +1402,10 @@ local function gr_process(object,prescript,before,after) elseif gr_state == "start" then local gr_type = utilities.parsers.settings_to_set(prescript.gr_type) local path = object.path - local p1, p2, p3, p4 = path[1], path[2], path[3], path[4] + local p1 = path[1] + local p2 = path[2] + local p3 = path[3] + local p4 = path[4] local llx = min(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord) local lly = min(p1.y_coord,p2.y_coord,p3.y_coord,p4.y_coord) local urx = max(p1.x_coord,p2.x_coord,p3.x_coord,p4.x_coord) @@ -1554,82 +1429,88 @@ end -- outlines -local outlinetexts = { } +local ot_reset, ot_process do -local function ot_reset() - outlinetexts = { } -end + local outlinetexts = { } -- also in top data -local function ot_analyze(object,prescript) - local ot_stage = prescript.ot_stage - local ot_index = tonumber(prescript.ot_index) - if ot_index and ot_stage == "trial" and not outlinetexts[ot_index] then - local ot_kind = prescript.ot_kind or "" - top.intermediate = true - top.multipass = true - context.MPLIBoutlinetext(ot_index,ot_kind,object.postscript) + ot_reset = function () + outlinetexts = { } end -end -local function ot_process(object,prescript,before,after) -end + local mp_index = 0 + local mp_kind = "" + local mp_str = "" -implement { - name = "MPLIBconvertoutlinetext", - arguments = { "integer", "string", "integer" }, - actions = function(index,kind,box) - local boxtomp = fonts.metapost.boxtomp - if boxtomp then - outlinetexts[index] = boxtomp(box,kind) - else - outlinetexts[index] = "" + function mp.mf_outline_text(index,str,kind) + if not outlinetexts[index] then + mp_index = index + mp_kind = kind + mp_str = str + tex.runtoks("mpoutlinetoks") end end -} -function mp.get_outline_text(index) -- maybe we need a more private namespace - mp.print(outlinetexts[index] or "draw origin;") -end + interfaces.implement { + name = "mpoutlinetoks", + actions = function() + context.MPLIBoutlinetext(mp_index,mp_kind,mp_str) + end, + } + implement { + name = "MPLIBconvertoutlinetext", + arguments = { "integer", "string", "integer" }, + actions = function(index,kind,box) + local boxtomp = fonts.metapost.boxtomp + if boxtomp then + outlinetexts[index] = boxtomp(box,kind) + else + outlinetexts[index] = "" + end + end + } --- definitions + function mp.mf_get_outline_text(index) -- maybe we need a more private namespace + mp.print(outlinetexts[index] or "draw origin;") + end -appendaction(resetteractions, "system",ot_reset) -appendaction(resetteractions, "system",cl_reset) -appendaction(resetteractions, "system",tx_reset) +end -appendaction(processoractions,"system",ot_process) -appendaction(processoractions,"system",gr_process) +-- mf_object= -appendaction(analyzeractions, "system",ot_analyze) -appendaction(analyzeractions, "system",tx_analyze) -appendaction(analyzeractions, "system",gt_analyze) +local p1 = P("mf_object=") +local p2 = lpeg.patterns.eol * p1 +local pattern = (1-p2)^0 * p2 + p1 -appendaction(processoractions,"system",sh_process) --- (processoractions,"system",gt_process) -appendaction(processoractions,"system",bm_process) -appendaction(processoractions,"system",tx_process) -appendaction(processoractions,"system",bx_process) -appendaction(processoractions,"system",ps_process) -appendaction(processoractions,"system",fg_process) -appendaction(processoractions,"system",tr_process) -- last, as color can be reset +function metapost.isobject(str) + return pattern and str ~= "" and lpegmatch(p,str) and true or false +end -appendaction(processoractions,"system",la_process) +local function installplugin(specification) + local reset = specification.reset + local process = specification.process + local object = specification.object + if reset then + appendaction(resetteractions,"system",reset) + end + if process then + appendaction(processoractions,"system",process) + end +end --- function metapost.installplugin(reset,analyze,process) --- if reset then --- appendaction(resetteractions,"system",reset) --- end --- if analyze then --- appendaction(analyzeractions,"system",analyze) --- end --- if process then --- appendaction(processoractions,"system",process) --- end --- end +metapost.installplugin = installplugin --- we're nice and set them already +-- definitions -resetter = resetteractions .runner -analyzer = analyzeractions .runner -processor = processoractions.runner +installplugin { name = "outline", reset = ot_reset, process = ot_process } +installplugin { name = "color", reset = cl_reset, process = cl_process } +installplugin { name = "text", reset = tx_reset, process = tx_process } +installplugin { name = "group", reset = gr_reset, process = gr_process } +installplugin { name = "graphictext", reset = gt_reset, process = gt_process } +installplugin { name = "shade", reset = sh_reset, process = sh_process } +installplugin { name = "bitmap", reset = bm_reset, process = bm_process } +installplugin { name = "box", reset = bx_reset, process = bx_process } +installplugin { name = "position", reset = ps_reset, process = ps_process } +installplugin { name = "figure", reset = fg_reset, process = fg_process } +installplugin { name = "layer", reset = la_reset, process = la_process } +installplugin { name = "transparency", reset = tr_reset, process = tr_process } diff --git a/tex/context/base/mkiv/mlib-pps.mkiv b/tex/context/base/mkiv/mlib-pps.mkiv index c9d181bf9..051130585 100644 --- a/tex/context/base/mkiv/mlib-pps.mkiv +++ b/tex/context/base/mkiv/mlib-pps.mkiv @@ -57,14 +57,36 @@ \let\MPLIBsettext\MPLIBsetNtext +\unexpanded\def\MPLIBsetNtextX#1% #2% box text + {\MPLIBflushenvironment + \hbox\bgroup % text + \meta_set_current_color + \let\MPLIBflushenvironment\doMPLIBflushenvironment + \let\next} + +\unexpanded\def\MPLIBsetCtextX#1#2% #3% box colorspec text + {\MPLIBflushenvironment + \hbox\bgroup % text + \directcolored[#2]% + \meta_set_current_color % so, textcolor wins ! + \let\MPLIBflushenvironment\doMPLIBflushenvironment + \let\next} + +\let\MPLIBsettextX\MPLIBsetNtextX + \unexpanded\def\MPLIBgettextscaled#1#2#3% why a copy .. can be used more often {\clf_mpgettext\MPtextbox #1% \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=#2,\c!sy=#3]{\raise\dp\MPtextbox\box\MPtextbox}\forcecolorhack\hss}}} +% \unexpanded\def\MPLIBfigure#1#2% +% {\setbox\scratchbox\hpack{\externalfigure[#1][\c!mask=#2]}% +% \clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint +% \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=\sx,\c!sy=\sy]{\box\scratchbox}\hss}}} + \unexpanded\def\MPLIBfigure#1#2% {\setbox\scratchbox\hpack{\externalfigure[#1][\c!mask=#2]}% \clf_mpsetsxsy\wd\scratchbox\ht\scratchbox\zeropoint - \vpack to \zeropoint{\vss\hpack to \zeropoint{\scale[\c!sx=\sx,\c!sy=\sy]{\box\scratchbox}\hss}}} + \vpack to \zeropoint{\vss\hpack to \zeropoint{\fastsxsy{\sx}{\sy}{\box\scratchbox}\hss}}} % horrible (we could inline scale and matrix code): @@ -185,4 +207,15 @@ \setbox\scratchbox\hpack\bgroup \unexpanded\def\MPLIBstopgroup{\doMPLIBstopgroup{#1}{#2}{#3}{#4}{#5}{#6}}} +% For now here ... will be cleaned up: + +\newtoks\mptexttoks +\newbox \mptextbox +\newtoks\mpoutlinetoks +\newtoks\mpgraphictexttoks + +\mptexttoks {\global\setbox\mptextbox\hbox{\clf_mptexttoks}} +\mpoutlinetoks {\global\setbox\mptextbox\vbox{\clf_mpoutlinetoks}} +\mpgraphictexttoks{\global\setbox\mptextbox\vbox{\clf_mpgraphictexttoks}} + \protect \endinput diff --git a/tex/context/base/mkiv/mlib-run.lua b/tex/context/base/mkiv/mlib-run.lua index 18bc7e4da..670c0e16b 100644 --- a/tex/context/base/mkiv/mlib-run.lua +++ b/tex/context/base/mkiv/mlib-run.lua @@ -6,6 +6,8 @@ if not modules then modules = { } end modules ['mlib-run'] = { license = "see context related readme files", } +-- todo mpx :execute -> mlib.execute(mpx,) + -- cmyk -> done, native -- spot -> done, but needs reworking (simpler) -- multitone -> @@ -30,7 +32,6 @@ nears zero.

--ldx]]-- local type, tostring, tonumber, next = type, tostring, tonumber, next -local gsub, match, find = string.gsub, string.match, string.find local striplines = utilities.strings.striplines local concat, insert, remove = table.concat, table.insert, table.remove @@ -70,20 +71,6 @@ end ----- mpbasepath = lpeg.instringchecker(lpeg.append { "/metapost/context/", "/metapost/base/" }) local mpbasepath = lpeg.instringchecker(P("/metapost/") * (P("context") + P("base")) * P("/")) --- local function i_finder(askedname,mode,ftype) -- fake message for mpost.map and metafun.mpvi --- local foundname = file.is_qualified_path(askedname) and askedname or resolvers.findfile(askedname,ftype) --- if not mpbasepath(foundname) then --- -- we could use the via file but we don't have a complete io interface yet --- local data, found, forced = metapost.checktexts(io.loaddata(foundname) or "") --- if found then --- local tempname = luatex.registertempfile(foundname,true) --- io.savedata(tempname,data) --- foundname = tempname --- end --- end --- return foundname --- end - -- mplib has no real io interface so we have a different mechanism than -- tex (as soon as we have more control, we will use the normal code) -- @@ -97,21 +84,6 @@ do local new_instance = mplib.new - local function preprocessed(name) - if not mpbasepath(name) then - -- we could use the via file but we don't have a complete io interface yet - local data, found, forced = metapost.checktexts(io.loaddata(name) or "") - if found then - local temp = luatex.registertempfile(name,true) - io.savedata(temp,data) - return temp - end - end - return name - end - - mplib.preprocessed = preprocessed -- helper - local function validftype(ftype) if ftype == "" then -- whatever @@ -123,14 +95,13 @@ do end finders.file = function(specification,name,mode,ftype) - return preprocessed(resolvers.findfile(name,validftype(ftype))) + return resolvers.findfile(name,validftype(ftype)) end local function i_finder(name,mode,ftype) -- fake message for mpost.map and metafun.mpvi local specification = url.hashed(name) local finder = finders[specification.scheme] or finders.file local found = finder(specification,name,mode,validftype(ftype)) - -- print(found) return found end @@ -160,7 +131,9 @@ function metapost.reporterror(result) if not result then report_metapost("error: no result object returned") elseif result.status > 0 then - local t, e, l = result.term, result.error, result.log + local t = result.term + local e = result.error + local l = result.log local report = metapost.texerrors and texerrormessage or report_metapost if t and t ~= "" then report("mp error: %s",striplines(t)) @@ -193,7 +166,8 @@ local f_preamble = formatters [ [[ local methods = { double = "double", scaled = "scaled", - binary = "binary", + -- binary = "binary", + binary = "double", decimal = "decimal", default = "scaled", } @@ -208,18 +182,6 @@ end -- todo: random_seed -local f_textext = formatters[ [[rawtextext("%s")]] ] - -function metapost.maketext(s,mode) - if mode and mode == 1 then - -- report_metapost("ignoring verbatimtex: %s",s) - else - -- report_metapost("handling btex ... etex: %s",s) - s = gsub(s,'"','"&ditto&"') - return f_textext(s) - end -end - local seed = nil function metapost.load(name,method) @@ -291,24 +253,103 @@ function metapost.unload(mpx) stoptiming(mplib) end -local mpxformats = { } +-- The flatten hack is needed because the library currently barks on \n\n and the +-- collapse because mp cannot handle snippets due to grouping issues. + +local function flatten(source,target) + for i=1,#source do + local d = source[i] + if type(d) == "table" then + flatten(d,target) + elseif d and d ~= "" then + target[#target+1] = d + end + end + return target +end + +local function prepareddata(data,collapse) + if data and data ~= "" then + if type(data) == "table" then + data = flatten(data,{ }) + if collapse then + data = #data > 1 and concat(data,"\n") or data[1] + end + end + return data + end +end + +metapost.defaultformat = "metafun" +metapost.defaultinstance = "metafun" +metapost.defaultmethod = "default" -function metapost.format(instance,name,method) +local mpxformats = { } +local nofformats = 0 +local mpxpreambles = { } + +function metapost.pushformat(specification,f,m) -- was: instance, name, method + if type(specification) ~= "table" then + specification = { + instance = specification, + format = f, + method = m, + } + end + local instance = specification.instance + local format = specification.format + local method = specification.method + local definitions = specification.definitions + local extensions = specification.extensions + local preamble = nil if not instance or instance == "" then - instance = "metafun" -- brrr + instance = metapost.defaultinstance + specification.instance = instance + end + if not format or format == "" then + format = metapost.defaultformat + specification.format = format + end + if not method or method == "" then + method = metapost.defaultmethod + specification.method = method + end + if definitions and definitions ~= "" then + preamble = definitions + end + if extensions and extensions ~= "" then + if preamble then + preamble = preamble .. "\n" .. extensions + else + preamble = extensions + end + end + nofformats = nofformats + 1 + local usedinstance = instance .. ":" .. nofformats + local mpx = mpxformats[usedinstance] + local mpp = mpxpreambles[instance] or "" + if preamble then + preamble = prepareddata(preamble,true) + mpp = mpp .. "\n" .. preamble + mpxpreambles[instance] = mpp end - name = name or instance - local mpx = mpxformats[instance] if not mpx then - report_metapost("initializing instance %a using format %a",instance,name) - mpx = metapost.checkformat(name,method) - mpxformats[instance] = mpx + report_metapost("initializing instance %a using format %a and method %a",usedinstance,format,method) + mpx = metapost.checkformat(format,method) + mpxformats[usedinstance] = mpx + if mpp ~= "" then + preamble = mpp + end + end + if preamble then + mpx:execute(preamble) end + specification.mpx = mpx return mpx end -function metapost.instance(instance) - return mpxformats[instance] +function metapost.popformat() + nofformats = nofformats - 1 end function metapost.reset(mpx) @@ -335,10 +376,6 @@ local mp_tag = 0 -- key/values -if not metapost.initializescriptrunner then - function metapost.initializescriptrunner() end -end - do local stack, top = { }, nil @@ -379,16 +416,47 @@ do end -function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, askedfig) - local converted, result = false, { } - if type(mpx) == "string" then - mpx = metapost.format(mpx) -- goody + +if not metapost.process then + + function metapost.process(specification) + metapost.run(specification) + end + +end + +-- run, process, convert and flush all work with a specification with the +-- following (often optional) fields +-- +-- mpx string or mp object +-- data string or table of strings +-- flusher table with flush methods +-- askedfig string ("all" etc) or number +-- incontext boolean +-- plugmode boolean + +local function makebeginbanner(specification) + return formatters["%% begin graphic: n=%s\n\n"](metapost.n) +end + +local function makeendbanner(specification) + return "\n% end graphic\n\n" +end + +function metapost.run(specification) + local mpx = specification.mpx + local data = specification.data + local converted = false + local result = { } + local mpxdone = type(mpx) == "string" + if mpxdone then + mpx = metapost.pushformat { instance = mpx, format = mpx } end if mpx and data then local tra = nil starttiming(metapost) - metapost.variables = { } - metapost.initializescriptrunner(mpx,trialrun) + metapost.variables = { } -- todo also push / pop + metapost.pushscriptrunner(mpx) if trace_graphics then tra = mp_tra[mpx] if not tra then @@ -400,39 +468,12 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, } mp_tra[mpx] = tra end - local banner = formatters["%% begin graphic: n=%s, trialrun=%s, multipass=%s, isextrapass=%s\n\n"]( - metapost.n, tostring(trialrun), tostring(multipass), tostring(isextrapass)) + local banner = makebeginbanner(specification) tra.inp:write(banner) tra.log:write(banner) end - if type(data) == "table" then - -- this hack is needed because the library currently barks on \n\n - -- eventually we can text for "" in the next loop - local n = 0 - local nofsnippets = #data - for i=1,nofsnippets do - local d = data[i] - if d ~= "" then - n = n + 1 - data[n] = d - end - end - for i=nofsnippets,n+1,-1 do - data[i] = nil - end - -- and this one because mp cannot handle snippets due to grouping issues - if metapost.collapse then - if #data > 1 then - data = concat(data,"\n") - else - data = data[1] - end - end - -- end of hacks - end - + local data = prepareddata(data,metapost.collapse) local function process(d,i) - -- d = string.gsub(d,"\r","") if d then if trace_graphics then if i then @@ -444,7 +485,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, end end starttiming(metapost.exectime) - result = mpx:execute(d) -- some day we wil use a coroutine with textexts + result = mpx:execute(d) stoptiming(metapost.exectime) if trace_graphics and result then local str = result.log or result.error @@ -461,7 +502,7 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, end end if result.fig then - converted = metapost.convert(result, trialrun, flusher, multipass, askedfig) + converted = metapost.convert(specification,result) end end elseif i then @@ -475,7 +516,6 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, if trace_tracingall then mpx:execute("tracingall;") end - -- table.insert(data,2,"") for i=1,#data do process(data[i],i) end @@ -486,17 +526,25 @@ function metapost.process(mpx, data, trialrun, flusher, multipass, isextrapass, process(data) end if trace_graphics then - local banner = "\n% end graphic\n\n" + local banner = makeendbanner(specification) tra.inp:write(banner) tra.log:write(banner) end stoptiming(metapost) + metapost.popscriptrunner(mpx) + end + if mpxdone then + metapost.popformat() end return converted, result end -function metapost.convert() - report_metapost('warning: no converter set') +if not metapost.convert then + + function metapost.convert() + report_metapost('warning: no converter set') + end + end -- handy @@ -564,7 +612,7 @@ end -- goodie -function metapost.quickanddirty(mpxformat,data,plugmode) +function metapost.quickanddirty(mpxformat,data,incontext) if not data then mpxformat = "metafun" data = mpxformat @@ -584,7 +632,14 @@ function metapost.quickanddirty(mpxformat,data,plugmode) end } local data = formatters["; beginfig(1) ;\n %s\n ; endfig ;"](data) - metapost.process(mpxformat, { data }, false, flusher, false, false, "all", plugmode) + metapost.process { + mpx = mpxformat, + flusher = flusher, + askedfig = "all", + useplugins = incontext, + incontext = incontext, + data = { data }, + } if code then return { bbox = bbox or { 0, 0, 0, 0 }, @@ -619,7 +674,6 @@ do local width = 0 local height = 0 local depth = 0 - local mpx = false local flusher = { startfigure = function(n,llx,lly,urx,ury) @@ -637,13 +691,18 @@ do end } - function metapost.simple(format,code) -- even less than metapost.quickcanddirty - local mpx = metapost.format(format or "metafun","metafun") + function metapost.simple(format,code) -- even less than metapost.quickcanddirty + local mpx = metapost.pushformat { } -- takes defaults -- metapost.setoutercolor(2) - metapost.process(mpx, - { "beginfig(1);", code, "endfig;" }, - false, flusher, false, false, 1, true -- last true is plugmode ! - ) + metapost.process { + mpx = mpx, + flusher = flusher, + askedfig = 1, + useplugins = false, + incontext = false, + data = { "beginfig(1);", code, "endfig;" }, + } + metapost.popformat() if result then local stream = concat(result," ") result = nil -- cleanup diff --git a/tex/context/base/mkiv/mtx-context-domotica.tex b/tex/context/base/mkiv/mtx-context-domotica.tex index 83562ee30..5a162893b 100644 --- a/tex/context/base/mkiv/mtx-context-domotica.tex +++ b/tex/context/base/mkiv/mtx-context-domotica.tex @@ -29,7 +29,9 @@ % % example: context --extra=domotica --openzwave ./config/fibaro/fgms.xml ./open-zwave-master/config/aeotec/zw100.xml % example: context --extra=domotica --openzwave --pattern="./open-zwave-master/config/**.xml" -% example: context --extra=domotica --hue hue-pragma-tasks.lua +% example: context --extra=domotica --hue hue-pragma-tasks.lua +% example: context --extra=domotica --hue pragma-youless-gas.lua --year=2018 --month=8 +% example: context --extra=domotica --hue pragma-youless-electricity.lua % % end help @@ -161,8 +163,11 @@ \stopmode + \startmode[hue] + \usemodule[youless] + \starttext \setupheadertexts @@ -171,10 +176,22 @@ local arguments = document.arguments local files = document.files - local pattern = arguments.pattern local filename = files[1] - - if filename then + local pattern = arguments.pattern + local year = arguments.year + local month = arguments.month + + local action = (arguments.tasks and "task") + or (arguments.graphics and "graphics") + or (string.find(filename,"tasks") and "tasks") + or (string.find(filename,"electricity") and "graphics") + or (string.find(filename,"pulse") and "graphics") + or (string.find(filename,"gas") and "graphics") + + if not filename or filename == "" then + logs.report("youless","provide filename") + context("no files given") + elseif action == "tasks" then context.starttitle { title = "Hue: " .. file.nameonly(filename) } filename = file.addsuffix(filename,"lua") if lfs.isfile(filename) then @@ -183,9 +200,11 @@ context("unknown file %a",filename) end context.stoptitle() + elseif action == "graphics" then + moduledata.youless.graphics { year = year, month = month, filename = filename } else - context("no files given") - context.stoptitle() + logs.report("youless","provide --status or --graphics") + context("no action given") end \stopluacode diff --git a/tex/context/base/mkiv/mtx-context-fonts.tex b/tex/context/base/mkiv/mtx-context-fonts.tex new file mode 100644 index 000000000..f1f74c9e9 --- /dev/null +++ b/tex/context/base/mkiv/mtx-context-fonts.tex @@ -0,0 +1,98 @@ +%D \module +%D [ file=mtx-context-fonts, +%D version=2018.10.10, +%D title=\CONTEXT\ Extra Trickry, +%D subtitle=Show Font Info, +%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. + +% begin help +% +% usage: context --extra=fonts [options] name +% +% --topspace=dimension : distance above first line +% --backspace=dimension : distance before left margin +% --paperformat=spec : paper*print or paperxprint +% --compact : small margins, 8pt font +% --verycompact : small margins, 7pt font +% +% example: context --extra=fonts --name=dejavu-serif +% end help + +\input mtx-context-common.tex + +\usemodule[fonts-charts] +\usemodule[fonts-tables] + +\input mtx-context-common.tex + +\doifdocumentargument {compact} { + \setdocumentargument{topspace} {5mm} + \setdocumentargument{backspace}{5mm} + \setdocumentargument{bodyfont} {8pt} +} + +\doifdocumentargument {verycompact} { + \setdocumentargument{topspace} {5mm} + \setdocumentargument{backspace}{5mm} + \setdocumentargument{bodyfont} {7pt} +} + +\setupbodyfont + [dejavu,9pt,tt,\getdocumentargument{bodyfont}] % dejavu is more complete + +\setuplayout + [header=0cm, + footer=1.5cm, + topspace=\getdocumentargumentdefault{topspace}{1.5cm}, + backspace=\getdocumentargumentdefault{backspace}{1.5cm}, + width=middle, + height=middle] + +\setuppapersize + [\getdocumentargument{paperformat_paper}] + [\getdocumentargument{paperformat_print}] + +\starttexdefinition unexpanded showfontdetails [#1] + \starttitle[title=#1] + \startsubject[title=Properties] + \showfontproperties[#1] + \stopsubject + \startsubject[title=Parameters] + \showfontparameters[#1] + \stopsubject + \startsubject[title=Positionings] + \showfontpositionings[#1] + \stopsubject + \startsubject[title=Substitutions] + \showfontsubstitutions[#1] + \stopsubject + \startsubject[title=Unicodevariants] + \showfontunicodevariants[#1] + \stopsubject + \startsubject[title=Ligatures] + \showfontligatures[#1] + \stopsubject + \showfontchart[#1,page=yes] + \stoptitle +\stoptexdefinition + +\starttext + + \startluacode + local files = document.files + if #files > 0 then + for i=1,#files do + context.showfontdetails { name = files[i] .. "*default" } + end + else + context("No font name(s) given.") + end + \stopluacode + +\stoptext diff --git a/tex/context/base/mkiv/mtx-context-listing.tex b/tex/context/base/mkiv/mtx-context-listing.tex index f7c3d2868..1053e80b9 100644 --- a/tex/context/base/mkiv/mtx-context-listing.tex +++ b/tex/context/base/mkiv/mtx-context-listing.tex @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -%D This is a \TEXEXEC\ features that has been moved to \MKIV. +%D This is a \TEXEXEC\ feature that has been moved to \MKIV. % begin help % @@ -44,7 +44,7 @@ } \setupbodyfont - [dejavu,11pt,tt,\getdocumentargument{bodyfont}] % dejavu is more complete + [dejavu,9pt,tt,\getdocumentargument{bodyfont}] % dejavu is more complete \setuptyping [lines=yes] diff --git a/tex/context/base/mkiv/mtx-context-xml.tex b/tex/context/base/mkiv/mtx-context-xml.tex index f8bfeef3a..875f02da6 100644 --- a/tex/context/base/mkiv/mtx-context-xml.tex +++ b/tex/context/base/mkiv/mtx-context-xml.tex @@ -76,6 +76,11 @@ if template then moduledata.xml.analyzers.allsetups(files,type(template) == "string" and template or nil) end + context.page() + for i=1,#files do + context.type(files[i]) + context.par() + end else context("no action given") end diff --git a/tex/context/base/mkiv/mult-aux.mkiv b/tex/context/base/mkiv/mult-aux.mkiv index a1aecc354..5e7de2270 100644 --- a/tex/context/base/mkiv/mult-aux.mkiv +++ b/tex/context/base/mkiv/mult-aux.mkiv @@ -180,6 +180,10 @@ \def\mult_check_for_assignment_indeed#1=#2#3\_end_ {\if#2@\assignmentfalse\else\assignmenttrue\fi} +\def\mult_check_for_assignment_indeed_begin_#1=#2#3\_end_ + {\if#2@} + + \def\mult_check_for_assignment#1% {\expandafter\mult_check_for_assignment_indeed\detokenize{#1}=@@\_end_} @@ -223,7 +227,8 @@ {\ifx#2\relax\let#2\empty\fi % it is hardly faster but produces less expansion tracing \def#3##1{\csname\ifcsname#1#2:##1\endcsname#1#2:##1\else\expandafter#5\csname#1#2:\s!parent\endcsname{##1}\fi\endcsname}% \def#4##1##2{\ifcsname##1:##2\endcsname##1:##2\else\expandafter#5\csname##1:\s!parent\endcsname{##2}\fi}% - \def#5##1##2{\ifx##1\relax\??empty\else#4{##1}{##2}\fi}% is {} needed around ##1 ? + %\def#5##1##2{\ifx##1\relax\??empty\else#4{##1}{##2}\fi}% is {} needed around ##1 ? + \def#5##1##2{\ifx##1\relax\??empty\else#4##1{##2}\fi}% is {} needed around ##1 ? \def#6##1##2{\csname\ifcsname#1##1:##2\endcsname#1##1:##2\else\expandafter#5\csname#1##1:\s!parent\endcsname{##2}\fi\endcsname}% \def#7##1{\detokenize\expandafter\expandafter\expandafter{\csname#1#2:##1\endcsname}}% always root, no backtrack \def#8##1{\begincsname#1#2:##1\endcsname}} @@ -255,7 +260,8 @@ {\ifx#2\relax\let#2\empty\fi \def#3##1{#1#4{#1#2}{##1}:}% leading #1 was missing .. is this one used? \def#4##1##2{\ifcsname##1:##2\endcsname##1\else\expandafter#5\csname##1:\s!parent\endcsname{##2}\fi}% - \def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}% + %\def#5##1##2{\ifx##1\relax\else#4{##1}{##2}\fi}% + \def#5##1##2{\ifx##1\relax\else#4##1{##2}\fi}% \def#6{#1#2:}% \def#7##1{#1##1:}% \def#8{\ifx#2\empty\else\ifcsname#1#2:\s!parent\endcsname\else\expandafter\let\csname#1#2:\s!parent\endcsname#1\fi\fi}% @@ -389,6 +395,43 @@ \the#7% \let#4#9}} +% \unexpanded\def\mult_interfaces_install_define_handler#1#2#3#4#5#6#7#8#9% why is \expanded still needed in clones +% {\ifx#4\relax\let#4\empty\fi % see \defineregister +% \unexpanded\def#2{\dotripleempty#5}% +% \newtoks#6% +% \newtoks#7% +% \unexpanded\def#5[##1][##2][##3]% [child][parent][settings] | [child][settings] | [child][parent] | [child] +% {\let#9#4% +% \edef#4{##1}% +% \ifthirdargument +% \the#6% predefine +% \edef#8{##2}% +% \mult_check_for_parent{#1}{#3}#4#8% +% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% +% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% +% \mult_interfaces_get_parameters{#1#4:}[##3]% +% \else\ifsecondargument +% \the#6% predefine +% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##2}=@@\_end_ +% \edef#8{##2}% +% \mult_check_for_parent{#1}{#3}#4#8% +% \expandafter\edef\csname#1#4:\s!chain\endcsname{\mult_interfaces_chain#1{##2}##1}% +% \expandafter\edef\csname#1#4:\s!parent\endcsname{#1##2}% +% \else +% \let#8\empty +% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% +% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% +% \mult_interfaces_get_parameters{#1#4:}[##2]% +% \fi +% \else +% \the#6% predefine +% \let#8\empty +% \expandafter\edef\csname#1#4:\s!chain\endcsname{##1}% +% \expandafter\edef\csname#1#4:\s!parent\endcsname{#3}% +% \fi\fi +% \the#7% +% \let#4#9}} + \unexpanded\def\installdefinehandler#1#2#3% {\normalexpanded {\mult_interfaces_install_define_handler @@ -466,7 +509,7 @@ \let#3#7% \else\iffirstargument % \mult_check_for_assignment{##1}% - \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_ + \expandafter\mult_check_for_assignment_indeed\detokenize{##1}=@@\_end_ \ifassignment % \setuplayout[key=value] \let#7#3% @@ -496,6 +539,54 @@ #2\zerocount % mode is always zero at the end \the#9}} +% \unexpanded\def\mult_interfaces_install_switch_setup_handler_b#1#2#3#4#5#6#7#8#9% +% {\newtoks#5% +% \newconstant#2% +% \newtoks#8% +% \newtoks#9% +% \ifx#6\relax\let#6\empty\fi +% \unexpanded\def#4[##1][##2]% maybe helper +% {\ifsecondargument % no commalist here +% % \setuplayout[whatever][key=value] +% \let#7#3% +% \let#6#3% +% \edef#3{##1}% +% #2\doingrootsetupnamed +% \mult_interfaces_get_parameters{#1#3:}[##2]% +% \the#5% +% \ifx#3#6\the#8\fi % only switchsetups if previous == current +% \let#3#7% +% \else\iffirstargument +% % \mult_check_for_assignment{##1}% +% \ifcondition\expandafter\mult_check_for_assignment_indeed_begin_\detokenize{##1}=@@\_end_ +% % \setuplayout[whatever] +% \let#6#3% % previous becomes current +% \edef#3{##1}% this will catch reset so one needs to test for it +% #2\doingrootsetnamed +% \the#5% % we can check for previous vs current +% \the#8% switchsetups +% \else +% % \setuplayout[key=value] +% \let#7#3% +% \let#6#3% +% \let#3\empty +% #2\doingrootsetuproot +% \mult_interfaces_get_parameters{#1:}[##1]% +% \the#5% +% \the#8% switchsetups +% \let#3#7% +% \fi +% \else +% % \setuplayout +% \let#6#3% % previous becomes current +% \let#3\empty % current becomes empty +% #2\doingrootsetroot +% \the#5% +% \the#8% switchsetups +% \fi\fi +% #2\zerocount % mode is always zero at the end +% \the#9}} + \unexpanded\def\installswitchsetuphandler#1#2% {\normalexpanded {\mult_interfaces_install_switch_setup_handler_a @@ -966,176 +1057,176 @@ \def\s!double{double} \def\s!triple{triple} -\unexpanded\def\syst_helpers_double_empty#1#2#3% - {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_double_empty_one_yes_mult#2#3}% - {\syst_helpers_double_empty_one_nop_mult#1}} - -\def\syst_helpers_double_empty_one_yes_mult#1#2[#3]% - {\firstargumenttrue - \doifelsenextoptional - {\secondargumenttrue#2[{#3}]}% - {\syst_helpers_double_empty_two_nop_mult#1{#3}}} - -\def\syst_helpers_double_empty_one_nop_mult% #1% - {\firstargumentfalse - \secondargumentfalse - }% #1} - -\def\syst_helpers_double_empty_two_nop_mult - {\secondargumentfalse - \if_next_blank_space_token - \expandafter\syst_helpers_double_empty_one_spaced_mult - \else - \expandafter\syst_helpers_double_empty_one_normal_mult - \fi} - -\def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] } -\def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]} - -\unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8% - {\ifx#3\relax\let#3\empty\fi - \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it - \newtoks#4% - \newtoks#7% - \edef\m_mult_interface_setup{\csstring#2_}% - \unexpanded\edef#2{\syst_helpers_double_empty - \csname\m_mult_interface_setup\s!simple\endcsname - \csname\m_mult_interface_setup\s!single\endcsname - \csname\m_mult_interface_setup\s!double\endcsname}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]% - {\let#6#3% - \def#8####1% we will have a simple one as well - {\edef#3{####1}% - \mult_interfaces_get_parameters{#1#3:}[##2]% - \the#4}% - \processcommalist[##1]#8% - \let#3#6% - \the#7}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]% - {\let#6#3% - \let#3\empty - \mult_interfaces_get_parameters{#1:}[##1]% - \the#4% - \let#3#6% - \the#7}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname% - {\let#6#3% - \let#3\empty - \the#4% - \let#3#6% - \the#7}} - -\unexpanded\def\installsetuphandler#1#2% - {\normalexpanded - {\mult_interfaces_install_setup_handler - {\noexpand#1}% \??aa - \expandafter\noexpand\csname setup#2\endcsname - \expandafter\noexpand\csname current#2\endcsname - \expandafter\noexpand\csname everysetup#2\endcsname - \expandafter\noexpand\csname setupcurrent#2\endcsname - \expandafter\noexpand\csname saved_setup_current#2\endcsname - \expandafter\noexpand\csname everysetup#2root\endcsname - \expandafter\noexpand\csname nested_setup_current#2\endcsname}} - -\unexpanded\def\syst_helpers_triple_empty#1#2#3#4% - {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_triple_empty_one_yes_mult#2#3#4}% - {\syst_helpers_triple_empty_one_nop_mult#1}} - -\def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]% - {\firstargumenttrue - \doifelsenextoptional - {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}% - {\syst_helpers_triple_empty_two_nop_mult#1{#4}}} - -\def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]% - {\secondargumenttrue - \doifelsenextoptional - {\thirdargumenttrue#2[{#3}][{#4}]}% - {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}} - -\def\syst_helpers_triple_empty_one_nop_mult % #1% - {\firstargumentfalse - \secondargumentfalse - \thirdargumentfalse - } % #1 - -\def\syst_helpers_triple_empty_two_nop_mult - {\secondargumentfalse - \thirdargumentfalse - \if_next_blank_space_token - \expandafter\syst_helpers_triple_empty_two_spaced_mult - \else - \expandafter\syst_helpers_triple_empty_two_normal_mult - \fi} - -\def\syst_helpers_triple_empty_three_nop_mult - {\thirdargumentfalse - \if_next_blank_space_token - \expandafter\syst_helpers_triple_empty_three_spaced_mult - \else - \expandafter\syst_helpers_triple_empty_three_normal_mult - \fi} - -\def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] } -\def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]} -\def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] } -\def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]} - -\unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8% - {\ifx#3\relax\let#3\empty\fi - \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% - \newtoks#4% - \edef\m_mult_interface_setup{\csstring#2_}% - \unexpanded\edef#2{\syst_helpers_triple_empty - \csname\m_mult_interface_setup\s!simple\endcsname - \csname\m_mult_interface_setup\s!single\endcsname - \csname\m_mult_interface_setup\s!double\endcsname - \csname\m_mult_interface_setup\s!triple\endcsname}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]% - {\let#7#3% - \def#8####1% - {\edef#3{####1}% - \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}% - \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent - \the#4}% - \processcommalist[##1]#8% - \let#3#7}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]% - {\let#7#3% - \def#8####1% - {\edef#3{####1}% - #6% checks parent and sets if needed - \mult_interfaces_get_parameters{#1#3:}[##2]% - \the#4}% - \processcommalist[##1]#8% - \let#3#7}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]% - {\let#7#3% - \let#3\empty - \mult_interfaces_get_parameters{#1:}[##1]% - \the#4% - \let#3#7}% - \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname% - {\let#7#3% - \let#3\empty - \the#4% - \let#3#7}} - -\unexpanded\def\installautosetuphandler#1#2% - {\normalexpanded - {\mult_interfaces_install_auto_setup_handler - {\noexpand#1}% \??aa - \expandafter\noexpand\csname setup#2\endcsname - \expandafter\noexpand\csname current#2\endcsname - \expandafter\noexpand\csname everysetup#2\endcsname - \expandafter\noexpand\csname setupcurrent#2\endcsname - \expandafter\noexpand\csname check#2parent\endcsname - \expandafter\noexpand\csname saved_setup_current#2\endcsname - \expandafter\noexpand\csname nested_setup_current#2\endcsname}} +% \unexpanded\def\syst_helpers_double_empty#1#2#3% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_double_empty_one_yes_mult#2#3}% +% {\syst_helpers_double_empty_one_nop_mult#1}} +% +% \def\syst_helpers_double_empty_one_yes_mult#1#2[#3]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\secondargumenttrue#2[{#3}]}% +% {\syst_helpers_double_empty_two_nop_mult#1{#3}}} +% +% \def\syst_helpers_double_empty_one_nop_mult% #1% +% {\firstargumentfalse +% \secondargumentfalse +% }% #1} +% +% \def\syst_helpers_double_empty_two_nop_mult +% {\secondargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_double_empty_one_spaced_mult +% \else +% \expandafter\syst_helpers_double_empty_one_normal_mult +% \fi} +% +% \def\syst_helpers_double_empty_one_spaced_mult#1#2{#1[{#2}] } +% \def\syst_helpers_double_empty_one_normal_mult#1#2{#1[{#2}]} +% +% \unexpanded\def\mult_interfaces_install_setup_handler#1#2#3#4#5#6#7#8% +% {\ifx#3\relax\let#3\empty\fi +% \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% no every ! don't change it +% \newtoks#4% +% \newtoks#7% +% \edef\m_mult_interface_setup{\csstring#2_}% +% \unexpanded\edef#2{\syst_helpers_double_empty +% \csname\m_mult_interface_setup\s!simple\endcsname +% \csname\m_mult_interface_setup\s!single\endcsname +% \csname\m_mult_interface_setup\s!double\endcsname}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]% +% {\let#6#3% +% \def#8####1% we will have a simple one as well +% {\edef#3{####1}% +% \mult_interfaces_get_parameters{#1#3:}[##2]% +% \the#4}% +% \processcommalist[##1]#8% +% \let#3#6% +% \the#7}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]% +% {\let#6#3% +% \let#3\empty +% \mult_interfaces_get_parameters{#1:}[##1]% +% \the#4% +% \let#3#6% +% \the#7}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname% +% {\let#6#3% +% \let#3\empty +% \the#4% +% \let#3#6% +% \the#7}} + +% \unexpanded\def\installsetuphandler#1#2% +% {\normalexpanded +% {\mult_interfaces_install_setup_handler +% {\noexpand#1}% \??aa +% \expandafter\noexpand\csname setup#2\endcsname +% \expandafter\noexpand\csname current#2\endcsname +% \expandafter\noexpand\csname everysetup#2\endcsname +% \expandafter\noexpand\csname setupcurrent#2\endcsname +% \expandafter\noexpand\csname saved_setup_current#2\endcsname +% \expandafter\noexpand\csname everysetup#2root\endcsname +% \expandafter\noexpand\csname nested_setup_current#2\endcsname}} +% +% \unexpanded\def\syst_helpers_triple_empty#1#2#3#4% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_triple_empty_one_yes_mult#2#3#4}% +% {\syst_helpers_triple_empty_one_nop_mult#1}} +% +% \def\syst_helpers_triple_empty_one_yes_mult#1#2#3[#4]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\syst_helpers_triple_empty_two_yes_mult#2#3{#4}}% +% {\syst_helpers_triple_empty_two_nop_mult#1{#4}}} +% +% \def\syst_helpers_triple_empty_two_yes_mult#1#2#3[#4]% +% {\secondargumenttrue +% \doifelsenextoptional +% {\thirdargumenttrue#2[{#3}][{#4}]}% +% {\syst_helpers_triple_empty_three_nop_mult#1{#3}{#4}}} +% +% \def\syst_helpers_triple_empty_one_nop_mult % #1% +% {\firstargumentfalse +% \secondargumentfalse +% \thirdargumentfalse +% } % #1 +% +% \def\syst_helpers_triple_empty_two_nop_mult +% {\secondargumentfalse +% \thirdargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_triple_empty_two_spaced_mult +% \else +% \expandafter\syst_helpers_triple_empty_two_normal_mult +% \fi} +% +% \def\syst_helpers_triple_empty_three_nop_mult +% {\thirdargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_triple_empty_three_spaced_mult +% \else +% \expandafter\syst_helpers_triple_empty_three_normal_mult +% \fi} +% +% \def\syst_helpers_triple_empty_two_spaced_mult #1#2{#1[{#2}] } +% \def\syst_helpers_triple_empty_two_normal_mult #1#2{#1[{#2}]} +% \def\syst_helpers_triple_empty_three_spaced_mult#1#2#3{#1[{#2}][{#3}] } +% \def\syst_helpers_triple_empty_three_normal_mult#1#2#3{#1[{#2}][{#3}]} +% +% \unexpanded\def\mult_interfaces_install_auto_setup_handler#1#2#3#4#5#6#7#8% +% {\ifx#3\relax\let#3\empty\fi +% \unexpanded\def#5{\mult_interfaces_get_parameters{#1#3:}}% +% \newtoks#4% +% \edef\m_mult_interface_setup{\csstring#2_}% +% \unexpanded\edef#2{\syst_helpers_triple_empty +% \csname\m_mult_interface_setup\s!simple\endcsname +% \csname\m_mult_interface_setup\s!single\endcsname +% \csname\m_mult_interface_setup\s!double\endcsname +% \csname\m_mult_interface_setup\s!triple\endcsname}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!triple\endcsname[##1][##2][##3]% +% {\let#7#3% +% \def#8####1% +% {\edef#3{####1}% +% \expandafter\def\csname#1#3:\s!parent\endcsname{#1##2}% +% \mult_interfaces_get_parameters{#1#3:}[##3]% always sets parent +% \the#4}% +% \processcommalist[##1]#8% +% \let#3#7}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!double\endcsname[##1][##2]% +% {\let#7#3% +% \def#8####1% +% {\edef#3{####1}% +% #6% checks parent and sets if needed +% \mult_interfaces_get_parameters{#1#3:}[##2]% +% \the#4}% +% \processcommalist[##1]#8% +% \let#3#7}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!single\endcsname[##1]% +% {\let#7#3% +% \let#3\empty +% \mult_interfaces_get_parameters{#1:}[##1]% +% \the#4% +% \let#3#7}% +% \unexpanded\expandafter\def\csname\m_mult_interface_setup\s!simple\endcsname% +% {\let#7#3% +% \let#3\empty +% \the#4% +% \let#3#7}} +% +% \unexpanded\def\installautosetuphandler#1#2% +% {\normalexpanded +% {\mult_interfaces_install_auto_setup_handler +% {\noexpand#1}% \??aa +% \expandafter\noexpand\csname setup#2\endcsname +% \expandafter\noexpand\csname current#2\endcsname +% \expandafter\noexpand\csname everysetup#2\endcsname +% \expandafter\noexpand\csname setupcurrent#2\endcsname +% \expandafter\noexpand\csname check#2parent\endcsname +% \expandafter\noexpand\csname saved_setup_current#2\endcsname +% \expandafter\noexpand\csname nested_setup_current#2\endcsname}} % okay, we can also get rid of the #9, but this code looks pretty bad, while the previous is % still okay given that we can also use #6 as setup (so in fact we can save some cs again and @@ -1197,9 +1288,11 @@ {\dodoubleempty#7}% \unexpanded\def#7[##1][##2]% {\ifsecondargument - #3\c_mult_set\expandafter{\the\c_mult_set#9[##1][##2]}% + %#3\c_mult_set\expandafter{\the\c_mult_set#9[##1][##2]}% + #3\toksapp\c_mult_set{#9[##1][##2]}% \else\iffirstargument - #3\c_mult_set\expandafter{\the\c_mult_set#8[##1]}% + %#3\c_mult_set\expandafter{\the\c_mult_set#8[##1]}% + #3\toksapp\c_mult_set{#8[##1]}% \fi\fi}} \unexpanded\def\installdefinitionsetmember#1#2#3#4% @@ -1230,9 +1323,30 @@ \expandafter\noexpand\csname current#2parent\endcsname \expandafter\noexpand\csname inject#2parent\endcsname}} +% Faster but not used that much to make a dent in performance. But, because it's +% cleaner anyway and also gives less tracing, we apply it a few times. + +\unexpanded\def\syst_helpers_install_macro_stack#1#2#3% + {\xdef\m_syst_helpers_push_macro{\csstring#1}% + \expandafter\newcount\csname#3\m_syst_helpers_push_macro\endcsname + \expandafter\edef\csname push_macro_\m_syst_helpers_push_macro\endcsname + {\noexpand\expandafter\glet + \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname + \noexpand#1% + \global\advance\csname#3\m_syst_helpers_push_macro\endcsname\plusone}% + \expandafter\edef\csname pop_macro_\m_syst_helpers_push_macro\endcsname + {\global\advance\csname#3\m_syst_helpers_push_macro\endcsname\minusone + \noexpand\expandafter#2% + \noexpand\expandafter\noexpand#1% + \noexpand\csname\m_syst_helpers_push_macro\noexpand\the\csname#3\m_syst_helpers_push_macro\endcsname\endcsname}} + +\unexpanded\def\installmacrostack #1{\syst_helpers_install_macro_stack#1\let \??localpushedmacro } +\unexpanded\def\installglobalmacrostack#1{\syst_helpers_install_macro_stack#1\glet\??globalpushedmacro} + \protect -%\unprotect +% \unprotect +% % \installcorenamespace {test} \installcommandhandler \??test {test} \??test % \unexpanded\def\TestMeA[#1]% % {\edef\currenttest{#1} @@ -1247,12 +1361,92 @@ % \unexpanded\def\TestMeD[#1]% % {\edef\currenttest{#1} % \doubleexpandafter\ifx\testparameter\c!before\empty \relax \else \relax \fi} -% \protect % -% \starttext -% \definetest[foo] \definetest[bar][foo] \setuptest[bar][before=indeed] -% \resettimer \dorecurse{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502 -% \resettimer \dorecurse{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530 -% \resettimer \dorecurse{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487 -% \resettimer \dorecurse{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493 -% \stoptext +% \protect +% +% \starttext +% \definetest[foo] \definetest[bar][foo] \setuptest[bar][before=indeed] +% \resettimer \dorecurse{100000}{\TestMeA[bar]} A:\elapsedtime \par % 0.502 +% \resettimer \dorecurse{100000}{\TestMeB[bar]} B:\elapsedtime \par % 0.530 +% \resettimer \dorecurse{100000}{\TestMeC[bar]} C:\elapsedtime \par % 0.487 +% \resettimer \dorecurse{100000}{\TestMeD[bar]} D:\elapsedtime \par % 0.493 +% \stoptext + +% There is no real demand for this ... even if this is twice as fast we only gain +% a few milliseconds: +% +% \unexpanded\def\foo#1{[foo:#1]} +% +% \installcommalistprocessor {foo} \foo +% \installcommalistprocessorcommand \processfoolist {foo} \foo +% +% \commalistprocessor{foo}[a,b,c,d] +% \processfoolist [a, b, c, d] +% +% \testfeatureonce{30000}{} \elapsedtime\par % 0.01 -> 0.00 +% \testfeatureonce{30000}{\processfoolist [fixed,middle]} \elapsedtime\par % 0.07 -> 0.06 +% \testfeatureonce{30000}{\commalistprocessor{foo}[fixed,middle]} \elapsedtime\par % 0.09 -> 0.08 +% \testfeatureonce{30000}{\processcommalist [fixed,middle]\foo} \elapsedtime\par % 0.13 -> 0.12 +% +% For instance the luatex manual only has some 3000 calls. But I keep this around as one +% never knows when we might need it. +% +% \installcorenamespace{commalistprocessor} +% \installcorenamespace{commalistprocessorcheck} +% \installcorenamespace{commalistprocessorwrap} +% \installcorenamespace{commalistprocessorfirst} +% \installcorenamespace{commalistprocessorcheckspace} +% \installcorenamespace{commalistprocessorcheckfinish} +% \installcorenamespace{commalistprocessoraction} +% \installcorenamespace{commalistprocessorgobblespace} +% +% \unexpanded\def\installcommalistprocessor#1#2% 7 macro names overhead +% {\let\nexttoken\relax +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessor#1\endcsname[% +% {\futurelet\nexttoken\csname\??commalistprocessorcheck#1\endcsname}% +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessorcheck#1\endcsname +% {\noexpand\ifx\nexttoken]% +% \noexpand\expandafter\noexpand\gobblethreearguments +% \noexpand\else +% \noexpand\expandafter\csname\??commalistprocessorwrap#1\endcsname +% \noexpand\fi +% \relax}% this one preserved the next {} +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessorwrap#1\endcsname##1]% +% {\csname\??commalistprocessorfirst#1\endcsname##1,]\relax}% +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessorfirst#1\endcsname##1% picks up \relax +% {\csname\??commalistprocessorcheckspace#1\endcsname}% +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessorcheckspace#1\endcsname +% {\noexpand\ifx\nexttoken\noexpand\blankspace +% \noexpand\expandafter\csname\??commalistprocessorgobblespace#1\endcsname +% \noexpand\else +% \noexpand\expandafter\csname\??commalistprocessorcheckfinish#1\endcsname +% \noexpand\fi}% +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessorcheckfinish#1\endcsname +% {\noexpand\ifx\nexttoken]% +% \noexpand\expandafter\noexpand\gobbleoneargument +% \noexpand\else +% \noexpand\expandafter\csname\??commalistprocessoraction#1\endcsname +% \noexpand\fi}% +% % +% \unexpanded\expandafter\edef\csname\??commalistprocessoraction#1\endcsname##1,% +% {\noexpand#2{##1}% +% \futurelet\nexttoken\csname\??commalistprocessorcheckspace#1\endcsname}% +% % +% \let\next\:% +% \unexpanded\edef \:{\csname\??commalistprocessorgobblespace#1\endcsname}% +% \unexpanded\expandafter\edef\: {\futurelet\nexttoken\csname\??commalistprocessorcheckspace#1\endcsname}% +% \let\:\next +% % +% } +% +% \unexpanded\def\installcommalistprocessorcommand#1#2#3% +% {\installcommalistprocessor{#2}{#3}% +% \expandafter\let\expandafter#1\csname\??commalistprocessor#2\endcsname} +% +% \unexpanded\def\commalistprocessor#1{\csname\??commalistprocessor#1\endcsname} diff --git a/tex/context/base/mkiv/mult-def.lua b/tex/context/base/mkiv/mult-def.lua index 925c22cd2..e03a82a76 100644 --- a/tex/context/base/mkiv/mult-def.lua +++ b/tex/context/base/mkiv/mult-def.lua @@ -7503,6 +7503,10 @@ return { ["pe"]="تاریخ", ["ro"]="data", }, + ["time"]={ + ["en"]="time", + ["nl"]="tijd", + }, ["deepnumbercommand"]={ ["cs"]="deepnumbercommand", ["de"]="deepnumbercommand", @@ -8278,7 +8282,7 @@ return { ["ro"]="inaltime", }, ["hfactor"]={ - ["cs"]="vfaktor", + ["cs"]="hfaktor", ["de"]="hfaktor", ["en"]="hfactor", ["fr"]="facteurhauteur", @@ -8287,6 +8291,14 @@ return { ["pe"]="عامل‌ارتفاع", ["ro"]="hfactor", }, + ["vfactor"]={ + ["cs"]="vfaktor", + ["de"]="vfaktor", + ["en"]="vfactor", + ["it"]="vfactor", + ["nl"]="vfactor", + ["ro"]="vfactor", + }, ["hfil"]={ ["cs"]="hfil", ["de"]="hfil", @@ -11544,6 +11556,12 @@ return { ["pe"]="گام‌وای", ["ro"]="ystep", }, + ["ownerpassword"]={ + ["en"]="ownerpassword", + }, + ["userpassword"]={ + ["en"]="userpassword", + }, }, ["elements"]={ ["answerlines"]={ @@ -13020,6 +13038,10 @@ return { ["cite"]={ ["en"]="cite", }, + ["closed"]={ + ["en"]="closed", + ["nl"]="gesloten", + }, ["color"]={ ["cs"]="barevne", ["de"]="farbe", @@ -15538,7 +15560,7 @@ return { ["ro"]="postscript", }, ["precedingpage"]={ - ["en"]="followingpage", + ["en"]="precedingpage", ["nl"]="voorafgaandepagina", }, ["preference"]={ @@ -17053,6 +17075,9 @@ return { ["unframed"]={ ["en"]="unframed", }, + ["unicode"]={ + ["en"]="unicode", + }, ["unit"]={ ["cs"]="jednotka", ["de"]="einheit", @@ -17815,8 +17840,8 @@ return { ["cd:brackets-l"] = { en = "[...,...]", lua = "{..., ...}" }, ["cd:parenthesis-s"] = { en = "(...)" }, ["cd:parenthesis-l"] = { en = "(...,...)" }, - ["cd:index-s"] = { en = "[...]" }, - ["cd:index-l"] = { en = "[..+...+..]" }, + ["cd:index-s"] = { en = "{...}" }, + ["cd:index-l"] = { en = "{..+...+..}" }, ["cd:math-s"] = { en = "$...$" }, ["cd:math-l"] = { en = "$...$" }, ["cd:inlinemath-s"] = { en = "$...$" }, diff --git a/tex/context/base/mkiv/mult-fun.lua b/tex/context/base/mkiv/mult-fun.lua index 9b7062605..0776f36b4 100644 --- a/tex/context/base/mkiv/mult-fun.lua +++ b/tex/context/base/mkiv/mult-fun.lua @@ -3,7 +3,7 @@ return { -- "nocolormodel", "greycolormodel", "graycolormodel", "rgbcolormodel", "cmykcolormodel", "shadefactor", - "textextoffset", + "textextoffset", "textextanchor", "normaltransparent", "multiplytransparent", "screentransparent", "overlaytransparent", "softlighttransparent", "hardlighttransparent", "colordodgetransparent", "colorburntransparent", "darkentransparent", "lightentransparent", "differencetransparent", "exclusiontransparent", @@ -53,17 +53,19 @@ return { "shadedinto", "withshadecolors", "withshadedomain", "withshademethod", "withshadefactor", "withshadevector", "withshadecenter", "withshadedirection", "withshaderadius", "withshadetransform", - "withshadestep", "withshadefraction", + "withshadestep", "withshadefraction", "withshadeorigin", "shownshadevector", "shownshadeorigin", "cmyk", "spotcolor", "multitonecolor", "namedcolor", "drawfill", "undrawfill", "inverted", "uncolored", "softened", "grayed", "greyed", "onlayer", "along", - "graphictext", "loadfigure", "externalfigure", "figure", "register", "outlinetext", -- "lua", + "graphictext", "loadfigure", "externalfigure", "figure", "register", + "outlinetext", "filloutlinetext", "drawoutlinetext", "outlinetexttopath", "checkedbounds", "checkbounds", "strut", "rule", "withmask", "bitmapimage", "colordecimals", "ddecimal", "dddecimal", "ddddecimal", "colordecimalslist", "textext", "thetextext", "rawtextext", "textextoffset", "texbox", "thetexbox", "rawtexbox", "istextext", + "notcached", "verbatim", "thelabel", "label", "autoalign", @@ -144,5 +146,31 @@ return { "sortlist", "copylist", "shapedlist", "listtocurves", "listtolines", "listsize", "listlast", "uniquelist", -- "circularpath", "squarepath", "linearpath", + -- + "theoffset", + -- + "texmode", "systemmode", + "texvar", "texstr", + "isarray", "prefix", "dimension", + "getmacro", "getdimen", "getcount", "gettoks", + "setmacro", "setdimen", "setcount", "settoks", + -- + "positionpath", "positioncurve", "positionxy", "positionpxy", + "positionwhd", "positionpage", "positionregion", "positionbox", + "positionanchor", "positioninregion", "positionatanchor", + -- + "wdpart", "htpart", "dppart", + -- + "texvar", "texstr", + -- + "inpath", "pointof", "leftof", "rightof", + -- + "newhash", "disposehash", "inhash", "tohash", + -- + "isarray", "prefix", "isobject", + -- + "comment", "report", "lua", "mp", "MP", "luacall", + -- + "mirrored", "mirroredabout", }, } diff --git a/tex/context/base/mkiv/mult-ini.lua b/tex/context/base/mkiv/mult-ini.lua index 3f320bf7f..0c8581281 100644 --- a/tex/context/base/mkiv/mult-ini.lua +++ b/tex/context/base/mkiv/mult-ini.lua @@ -105,6 +105,22 @@ function interfaces.getnamespace(n) return usednamespaces[n] .. ">" end +if documentdata then + + local prefix, getmacro + + function documentdata.variable(name) + if not prefix then + prefix = usednamespaces.variables .. ">document:" + end + if not getmacro then + getmacro = tokens.getters.macro + end + return getmacro(prefix..name) + end + +end + local function resolve(t,k) local v = logs.reporter(k) t[k] = v diff --git a/tex/context/base/mkiv/mult-ini.mkiv b/tex/context/base/mkiv/mult-ini.mkiv index d66749d14..634e2c1d8 100644 --- a/tex/context/base/mkiv/mult-ini.mkiv +++ b/tex/context/base/mkiv/mult-ini.mkiv @@ -111,6 +111,8 @@ \def\s!spread{spread} \let\!!spread\s!spread % obsolete \def\s!plus {plus} \let\!!plus \s!plus % obsolete \def\s!minus {minus} \let\!!minus \s!minus % obsolete +\def\s!left {left} +\def\s!right {right} \def\s!fil {fil} \def\s!fill {fill} \let\!!fill \s!fill % obsolete \def\s!filll {filll} @@ -122,11 +124,6 @@ \def\s!top {top} \def\s!both {both} -%D Kind of special: - -\edef\!!TLT{\detokenize{TLT}} -\edef\!!TRT{\detokenize{TRT}} - %D \macros %D {defineinterfaceconstant, %D defineinterfacevariable, @@ -341,17 +338,17 @@ %D These will become obsolete: \unexpanded\def\startmessages #1 library: #2 % - {\bgroup + {\begingroup \ifcsname\m!prefix!#2\endcsname\else\setgvalue{\m!prefix!#2}{#2}\fi - \catcode\endoflineasciicode\activecatcode + \catcode\endoflineasciicode\othercatcode \doifelseinset{#1}{\currentresponses,all}\mult_messages_start_yes\mult_messages_start_nop{#2}} \def\mult_messages_start_yes#1#2\stopmessages {\clf_setinterfacemessages{#1}{#2}% - \egroup} + \endgroup} \def\mult_messages_start_nop#1#2\stopmessages - {\egroup} + {\endgroup} \let\stopmessages\relax diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua index 0acba3b87..75c048c92 100644 --- a/tex/context/base/mkiv/mult-low.lua +++ b/tex/context/base/mkiv/mult-low.lua @@ -12,7 +12,8 @@ return { ["constants"] = { -- "zerocount", "minusone", "minustwo", "plusone", "plustwo", "plusthree", "plusfour", "plusfive", - "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", "plushundred", "plustwohundred", + "plussix", "plusseven", "pluseight", "plusnine", "plusten", "plussixteen", + "plusfifty", "plushundred", "plusonehundred", "plustwohundred", "plusfivehundred", "plusthousand", "plustenthousand", "plustwentythousand", "medcard", "maxcard", "maxcardminusone", "zeropoint", "onepoint", "halfapoint", "onebasepoint", "maxcount", "maxdimen", "scaledpoint", "thousandpoint", "points", "halfpoint", @@ -20,7 +21,9 @@ return { "zeromuskip", "onemuskip", "pluscxxvii", "pluscxxviii", "pluscclv", "pluscclvi", "normalpagebox", - -- -- + -- + "directionlefttoright", "directionrighttoleft", + -- "endoflinetoken", "outputnewlinechar", -- "emptytoks", "empty", "undefined", @@ -31,9 +34,7 @@ return { -- "fmtname", "fmtversion", "texengine", "texenginename", "texengineversion", "texenginefunctionality", "luatexengine", "pdftexengine", "xetexengine", "unknownengine", - -- "etexversion", - -- "pdftexversion", "pdftexrevision", - -- "xetexversion", "xetexrevision", + "contextformat", "contextversion", "contextkind", "contextlmtxmode", "contextmark", "mksuffix", -- "activecatcode", -- @@ -59,6 +60,7 @@ return { "spaceasciicode", "hashasciicode", "dollarasciicode", "commentasciicode", "ampersandasciicode", "colonasciicode", "backslashasciicode", "circumflexasciicode", "underscoreasciicode", "leftbraceasciicode", "barasciicode", "rightbraceasciicode", "tildeasciicode", "delasciicode", + "leftparentasciicode", "rightparentasciicode", "lessthanasciicode", "morethanasciicode", "doublecommentsignal", "atsignasciicode", "exclamationmarkasciicode", "questionmarkasciicode", "doublequoteasciicode", "singlequoteasciicode", "forwardslashasciicode", @@ -101,7 +103,9 @@ return { "startcomponent", "stopcomponent", "component", "startproduct", "stopproduct", "product", "startproject", "stopproject", "project", - "starttext", "stoptext", "startnotext", "stopnotext","startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", + "starttext", "stoptext", "startnotext", "stopnotext", + "startdocument", "stopdocument", "documentvariable", "unexpandeddocumentvariable", "setupdocument", "presetdocument", + "doifelsedocumentvariable", "doifdocumentvariableelse", "doifdocumentvariable", "doifnotdocumentvariable", "startmodule", "stopmodule", "usemodule", "usetexmodule", "useluamodule","setupmodule","currentmoduleparameter","moduleparameter", "everystarttext", "everystoptext", -- @@ -153,10 +157,12 @@ return { "texdefinition", -- "doifelsesetups", "doifsetupselse", "doifsetups", "doifnotsetups", "setup", "setups", "texsetup", "xmlsetup", "luasetup", "directsetup", "fastsetup", + "copysetups", "resetsetups", "doifelsecommandhandler", "doifcommandhandlerelse", "doifnotcommandhandler", "doifcommandhandler", -- "newmode", "setmode", "resetmode", "newsystemmode", "setsystemmode", "resetsystemmode", "pushsystemmode", "popsystemmode", + "globalsetmode", "globalresetmode", "globalsetsystemmode", "globalresetsystemmode", "booleanmodevalue", -- "newcount", "newdimen", "newskip", "newmuskip", "newbox", "newtoks", "newread", "newwrite", "newmarks", "newinsert", "newattribute", "newif", @@ -165,14 +171,19 @@ return { "then", "begcsname", -- + "autorule", + -- "strippedcsname","checkedstrippedcsname", -- "firstargumentfalse", "firstargumenttrue", "secondargumentfalse", "secondargumenttrue", "thirdargumentfalse", "thirdargumenttrue", "fourthargumentfalse", "fourthargumenttrue", - "fifthargumentfalse", "fifthsargumenttrue", - "sixthargumentfalse", "sixtsargumenttrue", + "fifthargumentfalse", "fifthargumenttrue", + "sixthargumentfalse", "sixthargumenttrue", + "seventhargumentfalse", "seventhargumenttrue", + -- + "vkern", "hkern", -- "doglobal", "dodoglobal", "redoglobal", "resetglobal", -- @@ -197,8 +208,8 @@ return { -- "hglue", "vglue", "hfillneg", "vfillneg", "hfilllneg", "vfilllneg", -- - "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", - "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", + "ruledhss", "ruledhfil", "ruledhfill", "ruledhfilll", "ruledhfilneg", "ruledhfillneg", "normalhfillneg", "normalhfilllneg", + "ruledvss", "ruledvfil", "ruledvfill", "ruledvfilll", "ruledvfilneg", "ruledvfillneg", "normalvfillneg", "normalvfilllneg", "ruledhbox", "ruledvbox", "ruledvtop", "ruledvcenter", "ruledmbox", "ruledhpack", "ruledvpack", "ruledtpack", "ruledhskip", "ruledvskip", "ruledkern", "ruledmskip", "ruledmkern", @@ -214,11 +225,20 @@ return { "scratchtoks", "globalscratchtoks", "privatescratchtoks", "scratchbox", "globalscratchbox", "privatescratchbox", -- + "globalscratchcounterone", "globalscratchcountertwo", "globalscratchcounterthree", + -- + "groupedcommand", "groupedcommandcs", + "triggergroupedcommand", "triggergroupedcommandcs", + "simplegroupedcommand", "pickupgroupedcommand", + -- "normalbaselineskip", "normallineskip", "normallineskiplimit", -- "availablehsize", "localhsize", "setlocalhsize", "distributedhsize", "hsizefraction", -- + "next", "nexttoken", + -- "nextbox", "dowithnextbox", "dowithnextboxcs", "dowithnextboxcontent", "dowithnextboxcontentcs", "flushnextbox", + "boxisempty", -- "scratchwidth", "scratchheight", "scratchdepth", "scratchoffset", "scratchdistance", "scratchhsize", "scratchvsize", @@ -239,6 +259,7 @@ return { "scratchleftskip", "scratchrightskip", "scratchtopskip", "scratchbottomskip", -- "doif", "doifnot", "doifelse", + "firstinset", "doifinset", "doifnotinset", "doifelseinset", "doifinsetelse", "doifelsenextchar", "doifnextcharelse", @@ -262,7 +283,7 @@ return { "doifelsenumber", "doifnumberelse", "doifnumber", "doifnotnumber", "doifelsecommon", "doifcommonelse", "doifcommon", "doifnotcommon", "doifinstring", "doifnotinstring", "doifelseinstring", "doifinstringelse", - "doifelseassignment", "doifassignmentelse", "docheckassignment", + "doifelseassignment", "doifassignmentelse", "docheckassignment", "doifelseassignmentcs", "doifassignmentelsecs", "doiftext", "doifelsetext", "doiftextelse", "doifnottext", -- "tracingall", "tracingnone", "loggingall", @@ -278,7 +299,7 @@ return { "singleexpandafter", "doubleexpandafter", "tripleexpandafter", -- "dontleavehmode", "removelastspace", "removeunwantedspaces", "keepunwantedspaces", - "removepunctuation", "ignoreparskip", "forcestrutdepth", + "removepunctuation", "ignoreparskip", "forcestrutdepth", "onlynonbreakablespace", -- "wait", "writestatus", "define", "defineexpandable", "redefine", -- @@ -329,7 +350,7 @@ return { "dosinglegroupempty", "dodoublegroupempty", "dotriplegroupempty", "doquadruplegroupempty", "doquintuplegroupempty", "permitspacesbetweengroups", "dontpermitspacesbetweengroups", -- - "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", + "nopdfcompression", "maximumpdfcompression", "normalpdfcompression", "onlypdfobjectcompression", "nopdfobjectcompression", -- "modulonumber", "dividenumber", -- @@ -403,12 +424,8 @@ return { "startluacode", "stopluacode", "startlua", "stoplua", "startctxfunction","stopctxfunction","ctxfunction", "startctxfunctiondefinition","stopctxfunctiondefinition", - "installctxfunction", "installctxfunctioncall", - "installprotectedctxfunction", "installprotectedctxfunctioncall", - "installctxscanner", "installctxscannercall", - "resetctxscanner", - "installprotectedctxscanner", "installprotectedctxscannercall", - "cldprocessfile", "cldloadfile", "cldcontext", "cldcommand", + "installctxfunction", "installprotectedctxfunction", "installprotectedctxscanner", "installctxscanner", "resetctxscanner", + "cldprocessfile", "cldloadfile", "cldloadviafile", "cldcontext", "cldcommand", -- "carryoverpar", "lastlinewidth", @@ -433,7 +450,8 @@ return { -- "nospace", "nospacing", "dospacing", -- - "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", + "naturalhbox", "naturalvbox", "naturalvtop", "naturalhpack", "naturalvpack", "naturaltpack", + "reversehbox", "reversevbox", "reversevtop", "reversehpack", "reversevpack", "reversetpack", -- "frule", -- diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua index 1cd5f5810..579750bc9 100644 --- a/tex/context/base/mkiv/mult-prm.lua +++ b/tex/context/base/mkiv/mult-prm.lua @@ -231,35 +231,44 @@ return { "breakafterdirmode", "catcodetable", "clearmarks", - "copyfont", "compoundhyphenmode", + "copyfont", "crampeddisplaystyle", "crampedscriptscriptstyle", "crampedscriptstyle", "crampedtextstyle", + "csstring", "draftmode", "dviextension", "dvifeedback", "dvivariable", "efcode", + "endlocalcontrol", "etoksapp", "etokspre", + "exceptionpenalty", "expanded", "expandglyphsinfont", "explicitdiscretionary", "explicithyphenpenalty", + "fixupboxesmode", "fontid", "formatname", "gleaders", + "gtoksapp", + "gtokspre", "hjcode", "hyphenationbounds", "hyphenationmin", "hyphenpenaltymode", "ifabsdim", "ifabsnum", + "ifcondition", "ifincsname", "ifprimitive", "ignoreligaturesinfont", + "immediateassigned", + "immediateassignment", "initcatcodetable", "insertht", "lastnamedcs", @@ -269,6 +278,7 @@ return { "lastxpos", "lastypos", "latelua", + "lateluafunction", "leftghost", "leftmarginkern", "letcharcode", @@ -280,6 +290,10 @@ return { "localleftbox", "localrightbox", "lpcode", + "luabytecode", + "luabytecodecall", + "luacopyinputnodes", + "luadef", "luaescapestring", "luafunction", "luafunctioncall", @@ -291,14 +305,17 @@ return { "mathdirection", "mathdisplayskipmode", "matheqnogapstep", + "mathflattenmode", "mathitalicsmode", "mathnolimitsmode", "mathoption", "mathpenaltiesmode", "mathrulesfam", "mathrulesmode", - "mathscriptsmode", + "mathrulethicknessmode", "mathscriptboxmode", + "mathscriptcharmode", + "mathscriptsmode", "mathstyle", "mathsurroundmode", "mathsurroundskip", @@ -362,6 +379,8 @@ return { "uniformdeviate", "useboxresource", "useimageresource", + "xtoksapp", + "xtokspre", }, ["omega"]={ "Omegaminorversion", @@ -422,15 +441,17 @@ return { "pdflastypos", "pdflinkmargin", "pdfliteral", + "pdfmajorversion", "pdfmapfile", "pdfmapline", - "pdfmajorversion", "pdfminorversion", "pdfnames", "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfobjcompresslevel", + "pdfomitcharset", + "pdfomitcidset", "pdfoutline", "pdfoutput", "pdfpageattr", @@ -447,6 +468,7 @@ return { "pdfprotrudechars", "pdfpxdimen", "pdfrandomseed", + "pdfrecompress", "pdfrefobj", "pdfrefxform", "pdfrefximage", @@ -522,7 +544,6 @@ return { "cr", "crcr", "csname", - "csstring", "day", "deadcycles", "def", @@ -580,6 +601,7 @@ return { "fontname", "futurelet", "gdef", + "glet", "global", "globaldefs", "halign", @@ -823,4 +845,4 @@ return { ["xetex"]={ "XeTeXversion", }, -} +} \ No newline at end of file diff --git a/tex/context/base/mkiv/mult-prm.mkiv b/tex/context/base/mkiv/mult-prm.mkiv index 1b9195f41..5ffb84d38 100644 --- a/tex/context/base/mkiv/mult-prm.mkiv +++ b/tex/context/base/mkiv/mult-prm.mkiv @@ -55,7 +55,7 @@ "pdflastobj", "pdflastxform", "pdflastximage", "pdflastximagepages", "pdflastxpos", "pdflastypos", "pdflinkmargin", "pdfliteral", "pdfmapfile", "pdfmapline", "pdfmajorversion", "pdfminorversion", "pdfnames", - "pdfnoligatures", "pdfnormaldeviate", "pdfobj", + "pdfnoligatures", "pdfnormaldeviate", "pdfobj", "pdfrecompress", "pdfobjcompresslevel", "pdfoutline", "pdfoutput", "pdfpageattr", "pdfpagebox", "pdfpageheight", "pdfpageref", "pdfpageresources", "pdfpagesattr", "pdfpagewidth", "pdfpkfixeddpi", "pdfpkmode", @@ -68,6 +68,7 @@ "pdftracingfonts", "pdftrailer", "pdftrailerid", "pdfuniformdeviate", "pdfuniqueresname", "pdfvorigin", "pdfxform", "pdfxformattr", "pdfxformmargin", "pdfxformname", "pdfxformresources", "pdfximage", + "pdfomitcidset", "pdfomitcharset", }, aleph = { -- we don't bother "Alephminorversion", "Alephrevision", "Alephversion", diff --git a/tex/context/base/mkiv/mult-sys.mkiv b/tex/context/base/mkiv/mult-sys.mkiv index 7000eed7b..fdb2ea732 100644 --- a/tex/context/base/mkiv/mult-sys.mkiv +++ b/tex/context/base/mkiv/mult-sys.mkiv @@ -55,6 +55,7 @@ \definesystemconstant {danish} \definesystemconstant {da} \definesystemconstant {dutch} \definesystemconstant {nl} \definesystemconstant {english} \definesystemconstant {en} +\definesystemconstant {estonian} \definesystemconstant {et} \definesystemconstant {farsi} \definesystemconstant {fa} % just persian \definesystemconstant {finnish} \definesystemconstant {fi} \definesystemconstant {french} \definesystemconstant {fr} @@ -240,6 +241,7 @@ \definesystemconstant {next} \definesystemconstant {pickup} +\definesystemconstant {forget} \definesystemconstant {ascii} \definesystemconstant {default} \definesystemconstant {unknown} diff --git a/tex/context/base/mkiv/node-acc.lua b/tex/context/base/mkiv/node-acc.lua index 03f6d7476..e6c617602 100644 --- a/tex/context/base/mkiv/node-acc.lua +++ b/tex/context/base/mkiv/node-acc.lua @@ -8,7 +8,6 @@ if not modules then modules = { } end modules ['node-acc'] = { local nodes, node = nodes, node -local nodecodes = nodes.nodecodes local tasks = nodes.tasks local nuts = nodes.nuts @@ -16,6 +15,7 @@ local tonut = nodes.tonut local tonode = nodes.tonode local getid = nuts.getid +local getsubtype = nuts.getsubtype local getattr = nuts.getattr local getlist = nuts.getlist local getchar = nuts.getchar @@ -28,21 +28,28 @@ local setsubtype = nuts.setsubtype local getwidth = nuts.getwidth local setwidth = nuts.setwidth ------ traverse_nodes = nuts.traverse -local traverse_id = nuts.traverse_id +local nextglyph = nuts.traversers.glyph +local nextnode = nuts.traversers.node + ----- copy_node = nuts.copy local insert_after = nuts.insert_after local copy_no_components = nuts.copy_no_components +local nodecodes = nodes.nodecodes +local gluecodes = nodes.gluecodes + local glue_code = nodecodes.glue ----- kern_code = nodecodes.kern local glyph_code = nodecodes.glyph local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist +local userskip_code = gluecodes.user +local spaceskip_code = gluecodes.spaceskip +local xspaceskip_code = gluecodes.xspaceskip + local a_characters = attributes.private("characters") -local threshold = 65536 -- not used local nofreplaced = 0 -- todo: nbsp etc @@ -50,6 +57,9 @@ local nofreplaced = 0 -- todo: maybe cache as we now create many nodes -- todo: check for subtype related to spacing (13/14 but most seems to be user anyway) +local trace = false trackers.register("backend.spaces", function(v) trace = v end) +local slot = nil + local function injectspaces(head) local p, p_id local n = head @@ -57,32 +67,42 @@ local function injectspaces(head) local id = getid(n) if id == glue_code then if p and getid(p) == glyph_code then - -- unless we don't care about the little bit of overhead - -- we can just: local g = copy_node(g) - local g = copy_no_components(p) - local a = getattr(n,a_characters) - setchar(g,32) - setlink(p,g,n) - setwidth(n,getwidth(n) - getwidth(g)) - if a then - setattr(g,a_characters,a) + local s = getsubtype(n) + if s == spaceskip_code or s == xspaceskip_code then + -- unless we don't care about the little bit of overhead + -- we can just: local g = copy_node(g) + local g = copy_no_components(p) + local a = getattr(n,a_characters) + setchar(g,slot) + setlink(p,g,n) + setwidth(n,getwidth(n) - getwidth(g)) + -- setsubtype(n,userskip_code) + if a then + setattr(g,a_characters,a) + end + setattr(n,a_characters,0) + nofreplaced = nofreplaced + 1 end - setattr(n,a_characters,0) - nofreplaced = nofreplaced + 1 end elseif id == hlist_code or id == vlist_code then - injectspaces(getlist(n),attribute) + injectspaces(getlist(n),slot) end p_id = id p = n n = getnext(n) end - return head, true -- always done anyway + return head end nodes.handlers.accessibility = function(head) - local head, done = injectspaces(tonut(head)) - return tonode(head), done + if trace then + if not slot then + slot = fonts.helpers.privateslot("visualspace") + end + else + slot = 32 + end + return injectspaces(head,slot) end statistics.register("inserted spaces in output",function() @@ -99,7 +119,7 @@ end) -- -- local function compact(n) -- local t = { } --- for n in traverse_id(glyph_code,n) do +-- for n in nextglyph, n do -- t[#t+1] = utfchar(getchar(n)) -- check for unicode -- end -- return concat(t,"") @@ -107,8 +127,7 @@ end) -- -- local function injectspans(head) -- local done = false --- for n in traverse_nodes(tonuts(head)) do --- local id = getid(n) +-- for n, id in nextnode, tonuts(head) do -- if id == disc then -- local r = getfield(n,"replace") -- local p = getfield(n,"pre") @@ -134,18 +153,17 @@ end) -- -- tasks.appendaction("processors", "words", "nodes.injectspans") -- --- local pdfpageliteral = nuts.pool.pdfpageliteral +-- local pageliteral = nuts.pool.pageliteral -- -- local function injectspans(head) -- local done = false --- for n in traverse_nodes(tonut(head)) do --- local id = getid(n) +-- for n, id in nextnode, tonut(head) do -- if id == disc then -- local a = getattr(n,a_hyphenated) -- if a then -- local str = codes[a] --- local b = pdfpageliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str))) --- local e = pdfpageliteral("EMC") +-- local b = pageliteral(format("/Span << /ActualText %s >> BDC", lpdf.tosixteen(str))) +-- local e = pageliteral("EMC") -- insert_before(head,n,b) -- insert_after(head,n,e) -- done = true diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua index 84567068b..d6a9950fe 100644 --- a/tex/context/base/mkiv/node-aux.lua +++ b/tex/context/base/mkiv/node-aux.lua @@ -32,8 +32,6 @@ local getnext = nuts.getnext local getid = nuts.getid local getsubtype = nuts.getsubtype local getlist = nuts.getlist -local getfont = nuts.getfont -local getchar = nuts.getchar local getattr = nuts.getattr local getboth = nuts.getboth local getcomponents = nuts.getcomponents @@ -51,8 +49,10 @@ local setprev = nuts.setprev local setcomponents = nuts.setcomponents local setattrlist = nuts.setattrlist -local traverse_nodes = nuts.traverse -local traverse_id = nuts.traverse_id +----- traverse_nodes = nuts.traverse +----- traverse_id = nuts.traverse_id +local nextnode = nuts.traversers.node +local nextglyph = nuts.traversers.glyph local flush_node = nuts.flush local flush_list = nuts.flush_list local hpack_nodes = nuts.hpack @@ -154,9 +154,8 @@ function nodes.repackhlist(list,...) end local function set_attributes(head,attr,value) - for n in traverse_nodes(head) do + for n, id in nextnode, head do setattr(n,attr,value) - local id = getid(n) if id == hlist_node or id == vlist_node then set_attributes(getlist(n),attr,value) end @@ -164,11 +163,10 @@ local function set_attributes(head,attr,value) end local function set_unset_attributes(head,attr,value) - for n in traverse_nodes(head) do + for n, id in nextnode, head do if not getattr(n,attr) then setattr(n,attr,value) end - local id = getid(n) if id == hlist_code or id == vlist_code then set_unset_attributes(getlist(n),attr,value) end @@ -176,9 +174,8 @@ local function set_unset_attributes(head,attr,value) end local function unset_attributes(head,attr) - for n in traverse_nodes(head) do + for n, id in nextnode, head do setattr(n,attr,unsetvalue) - local id = getid(n) if id == hlist_code or id == vlist_code then unset_attributes(getlist(n),attr) end @@ -197,98 +194,11 @@ nuts.setattributes = set_attributes nodes.setattributes nuts.setunsetattributes = set_unset_attributes nodes.setunsetattributes = vianuts(set_unset_attributes) nuts.unsetattributes = unset_attributes nodes.unsetattributes = vianuts(unset_attributes) --- history: --- --- local function glyph_width(a) --- local ch = chardata[getfont(a)][getchar(a)] --- return (ch and ch.width) or 0 --- end --- --- local function glyph_total(a) --- local ch = chardata[getfont(a)][getchar(a)] --- return (ch and (ch.height+ch.depth)) or 0 --- end --- --- local function non_discardable(a) -- inline --- return getid(id) < math_node -- brrrr --- end --- --- local function calculate_badness(t,s) --- if t == 0 then --- return 0 --- elseif s <= 0 then --- return INF_BAD --- else --- local r --- if t <= 7230584 then --- r = t * 297 / s --- elseif s >= 1663497 then --- r = t / floor(s / 297) --- else --- r = t --- end --- r = floor(r) --- if r > 1290 then --- return INF_BAD --- else --- return floor((r * r * r + 0x20000) / 0x40000) -- 0400000 / 01000000 --- end --- end --- end --- --- left-overs --- --- local function round_xn_over_d(x, n, d) --- local positive -- was x >= 0 --- if x >= 0 then --- positive = true --- else --- x = -x --- positive = false --- end --- local t = floor(x % 0x8000) * n -- 0100000 --- local f = floor(t / 0x8000) -- 0100000 --- local u = floor(x / 0x8000) * n + f -- 0100000 --- local v = floor(u % d) * 0x8000 + f -- 0100000 --- if floor(u / d) >= 0x8000 then -- 0100000 --- report_parbuilders('arith_error') --- else --- u = 0x8000 * floor(u / d) + floor(v / d) -- 0100000 --- end --- v = floor(v % d) --- if 2*v >= d then --- u = u + 1 --- end --- if positive then --- return u --- else --- return -u --- end --- end --- --- local function firstline(n) --- while n do --- local id = getid(n) --- if id == hlist_code then --- if getsubtype(n) == line_code then --- return n --- else --- return firstline(getlist(n)) --- end --- elseif id == vlist_code then --- return firstline(getlist(n)) --- end --- n = getnext(n) --- end --- end --- --- nodes.firstline = firstline - function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255 if untagged then return first_glyph(n) else - for g in traverse_id(glyph_code,n) do + for g in nextglyph ,n do return g end end @@ -297,8 +207,8 @@ end local function firstcharinbox(n) local l = getlist(getbox(n)) if l then - for g in traverse_id(glyph_code,l) do - return getchar(g) + for g, c in nextglyph, l do + return c end end return 0 @@ -431,10 +341,9 @@ nodes.link = function(list,currentfont,currentattr,head,tail) end local function locate(start,wantedid,wantedsubtype) - for n in traverse_nodes(start) do - local id = getid(n) + for n, id, subtype in nextnode, start do if id == wantedid then - if not wantedsubtype or getsubtype(n) == wantedsubtype then + if not wantedsubtype or subtype == wantedsubtype then return n end elseif id == hlist_code or id == vlist_code then @@ -490,87 +399,6 @@ end -- end -- end --- these component helpers might move to another module - --- nodemode helper: here we also flatten components, no check for disc here - -function nuts.set_components(target,start,stop) - local head = getcomponents(target) - if head then - flush_list(head) - head = nil - end - if start then - setprev(start) - else - return nil - end - if stop then - setnext(stop) - end - local tail = nil - while start do - local c = getcomponents(start) - local n = getnext(start) - if c then - if head then - setlink(tail,c) - else - head = c - end - tail = find_tail(c) - setcomponents(start) - flush_node(start) - else - if head then - setlink(tail,start) - else - head = start - end - tail = start - end - start = n - end - setcomponents(target,head) - -- maybe also upgrade the subtype but we don't use it anyway - return head -end - -function nuts.get_components(target) - return getcomponents(target) -end - -nuts.get_components = getcomponents - -function nuts.take_components(target) - local c = getcomponents(target) - setcomponents(target) - -- maybe also upgrade the subtype but we don't use it anyway - return c -end - --- nodemode helper: we assume a glyph and a flat components list (basemode can --- have nested components) - -function nuts.count_components(n,marks) - local components = getcomponents(n) - if components then - if marks then - local i = 0 - for g in traverse_id(glyph_code,components) do - if not marks[getchar(g)] then - i = i + 1 - end - end - return i - else - return count(glyph_code,components) - end - else - return 0 - end -end - -- nodemode helper: the next and prev pointers are untouched function nuts.copy_no_components(g,copyinjection) @@ -596,7 +424,7 @@ end function nuts.copy_only_glyphs(current) local head = nil local previous = nil - for n in traverse_id(glyph_code,current) do + for n in nextglyph, current do n = copy_node(n) if head then setlink(previous,n) diff --git a/tex/context/base/mkiv/node-bck.lua b/tex/context/base/mkiv/node-bck.lua index 4ed5abe5e..a19e5e969 100644 --- a/tex/context/base/mkiv/node-bck.lua +++ b/tex/context/base/mkiv/node-bck.lua @@ -9,178 +9,288 @@ if not modules then modules = { } end modules ['node-bck'] = { -- beware, this one takes quite some runtime, so we need a status flag -- maybe some page related state +-- todo: done (or just get rid of done altogether) ... saves no purpose +-- any longer + local attributes, nodes, node = attributes, nodes, node -local enableaction = nodes.tasks.enableaction +local enableaction = nodes.tasks.enableaction -local nodecodes = nodes.nodecodes -local listcodes = nodes.listcodes +local nodecodes = nodes.nodecodes +local listcodes = nodes.listcodes -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local cell_code = listcodes.cell +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist -local nuts = nodes.nuts -local nodepool = nuts.pool +local alignmentlist_code = listcodes.alignment +local celllist_code = listcodes.cell -local tonode = nuts.tonode -local tonut = nuts.tonut +local nuts = nodes.nuts +local nodepool = nuts.pool -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getlist = nuts.getlist -local getattr = nuts.getattr -local getsubtype = nuts.getsubtype -local getwhd = nuts.getwhd +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getlist = nuts.getlist +local getattr = nuts.getattr +local getsubtype = nuts.getsubtype +local getwhd = nuts.getwhd +local getwidth = nuts.getwidth +local getprop = nuts.getprop -local setattr = nuts.setattr -local setlink = nuts.setlink -local setlist = nuts.setlist +local setattr = nuts.setattr +local setlink = nuts.setlink +local setlist = nuts.setlist +local setattributelist = nuts.setattributelist +local setprop = nuts.setprop -local traverse = nuts.traverse -local traverse_id = nuts.traverse_id +local takebox = nuts.takebox +local findtail = nuts.tail -local new_rule = nodepool.rule -local new_glue = nodepool.glue +local nextnode = nuts.traversers.node +local nexthlist = nuts.traversers.hlist +local nextlist = nuts.traversers.list -local a_color = attributes.private('color') -local a_transparency = attributes.private('transparency') -local a_colormodel = attributes.private('colormodel') -local a_background = attributes.private('background') -local a_alignbackground = attributes.private('alignbackground') +local flush_node_list = nuts.flush_list -local function add_backgrounds(head) -- rather old code .. to be redone - local current = head - while current do - local id = getid(current) - if id == hlist_code or id == vlist_code then - local list = getlist(current) - if list then - local head = add_backgrounds(list) - if head then - setlist(current,head) - list = head - end +local new_rule = nodepool.rule +local new_kern = nodepool.kern +local new_hlist = nodepool.hlist + +local privateattributes = attributes.private +local unsetvalue = attributes.unsetvalue + +local linefillers = nodes.linefillers + +local a_color = privateattributes("color") +local a_transparency = privateattributes("transparency") +local a_colormodel = privateattributes("colormodel") +local a_background = privateattributes("background") +local a_alignbackground = privateattributes("alignbackground") +local a_linefiller = privateattributes("linefiller") +local a_ruled = privateattributes("ruled") + +local trace_alignment = false +local report_alignment = logs.reporter("backgrounds","alignment") + +trackers.register("backgrounds.alignments",function(v) trace_alignment = v end) + +-- We can't use listbuilders with where=alignment because at that stage we have +-- unset boxes. Also, post_linebreak is unsuitable for nested processing as we +-- get the same stuff many times (wrapped again and again). +-- +-- After many experiments with different callbacks the shipout is still the best +-- place but then we need to store some settings longer or save them with the node. +-- For color only we can get away with it with an extra attribute flagging a row +-- but for more complex stuff we can better do as we do here now. + +local overshoot = math.floor(65781/5) -- could be an option per table (just also store it) + +local function colored_a(current,list,template,id) + local width, height, depth = getwhd(current) + local total = height + depth + if width > 0 and total > 0 then + local rule = nil + -- + local a = getattr(template,a_linefiller) + if a then + local d = linefillers.data[a%1000] + if d then + rule = linefillers.filler(template,d,width,height,depth) + end + end + -- + if not rule then + rule = new_rule(width,height,depth) + end + setattributelist(rule,template) + local back = new_kern(-((id == vlist_code and total) or width)) + return setlink(rule,back,list) + end +end + +local function colored_b(current,list,template,id,indent) + local width, height, depth = getwhd(current) + local total = height + depth + if width > 0 and total > 0 then + local fore = (indent ~= 0) and new_kern(indent) + local rule = nil + -- + local a = getattr(template,a_linefiller) + if a then + local d = linefillers.data[a%1000] + if d then + rule = linefillers.filler(template,d,width-indent,height,depth) end - local width, height, depth = getwhd(current) - if width > 0 then - local background = getattr(current,a_background) + end + -- + if not rule then + rule = new_rule(width-indent,height+overshoot,depth+overshoot) + setattributelist(rule,template) + end + if overshoot == 0 then + local back = new_kern(-((id == vlist_code and total) or width)) + return setlink(fore,rule,back,list) + else + rule = new_hlist(rule) + return setlink(fore,rule,list) + end + end +end + +local templates = { } +local currentrow = 0 +local enabled = false +local alignments = false + +local function add_alignbackgrounds(head,list) + for current, id, subtype, list in nextlist, list do + if list and id == hlist_code and subtype == celllist_code then + for template in nexthlist, list do + local background = getattr(template,a_alignbackground) if background then - -- direct to hbox - -- colorspace is already set so we can omit that and stick to color - local mode = getattr(current,a_colormodel) - if mode then - local skip = id == hlist_code and width or (height + depth) - local glue = new_glue(-skip) - local rule = new_rule(width,height,depth) - local color = getattr(current,a_color) - local transparency = getattr(current,a_transparency) - setattr(rule,a_colormodel,mode) - if color then - setattr(rule,a_color,color) - end - if transparency then - setattr(rule,a_transparency,transparency) - end --- setlink(rule,glue) --- if list then --- setlink(glue,list) --- end --- setlist(current,rule) - setlist(current,rule,glue,list) + local list = colored_a(current,list,template) + if list then + setlist(current,list) end + setattr(template,a_alignbackground,unsetvalue) -- or property end + break end end - current = getnext(current) end - return head, true + local template = getprop(head,"alignmentchecked") + if template then + list = colored_b(head,list,template[1],hlist_code,template[2]) + flush_node_list(template) + templates[currentrow] = false + return list + end end -local function add_alignbackgrounds(head) - local current = head - while current do - local id = getid(current) - if id == hlist_code then - local list = getlist(current) - if not list then - -- no need to look - elseif getsubtype(current) == cell_code then - local background = nil - local found = nil - -- for l in traverse(list) do - -- background = getattr(l,a_alignbackground) - -- if background then - -- found = l - -- break - -- end - -- end - -- we know that it's a fake hlist (could be user node) - -- but we cannot store tables in user nodes yet - for l in traverse_id(hpack_code,list) do - background = getattr(l,a_alignbackground) - if background then - found = l +local function add_backgrounds(head,id,list) + if list then + for current, id, subtype, list in nextlist, list do + if list then + if alignments and subtype == alignmentlist_code then + local l = add_alignbackgrounds(current,list) + if l then + list = l + setlist(current,list) end - break end - -- - if background then - -- current has subtype 5 (cell) - local width, height, depth = getwhd(current) - if width > 0 then - local mode = getattr(found,a_colormodel) - if mode then - local glue = new_glue(-width) - local rule = new_rule(width,height,depth) - local color = getattr(found,a_color) - local transparency = getattr(found,a_transparency) - setattr(rule,a_colormodel,mode) - if color then - setattr(rule,a_color,color) - end - if transparency then - setattr(rule,a_transparency,transparency) - end - setlink(rule,glue) - if list then - setlink(glue,list) - end - setlist(current,rule) - end - end + local l = add_backgrounds(current,id,list) + if l then + list = l + setlist(current,l) end - else - add_alignbackgrounds(list) end - elseif id == vlist_code then - local list = getlist(current) - if list then - add_alignbackgrounds(list) + end + end + if id == hlist_code or id == vlist_code then + local background = getattr(head,a_background) + if background then + list = colored_a(head,list,head,id) + -- not needed + setattr(head,a_background,unsetvalue) -- or property + return list + end + end +end + +function nodes.handlers.backgrounds(head) + add_backgrounds(head,getid(head),getlist(head)) + return head +end + +function nodes.handlers.backgroundspage(head,where) + if head and where == "alignment" then + for n in nexthlist, head do + local p = getprop(n,"alignmentchecked") + if not p and getsubtype(n) == alignmentlist_code then + currentrow = currentrow + 1 + local template = templates[currentrow] + if trace_alignment then + report_alignment("%03i %s %s",currentrow,"page",template and "+" or "-") + end + setprop(n,"alignmentchecked",template) end end - current = getnext(current) end - return head, true + return head end --- nodes.handlers.backgrounds = add_backgrounds --- nodes.handlers.alignbackgrounds = add_alignbackgrounds +function nodes.handlers.backgroundsvbox(head,where) + if head and where == "vbox" then + local list = getlist(head) + if list then + for n in nexthlist, list do + local p = getprop(n,"alignmentchecked") + if not p and getsubtype(n) == alignmentlist_code then + currentrow = currentrow + 1 + local template = templates[currentrow] + if trace_alignment then + report_alignment("%03i %s %s",currentrow,"vbox",template and "+" or "-") + end + setprop(n,"alignmentchecked",template) + end + end + end + end + return head +end -nodes.handlers.backgrounds = function(head) local head, done = add_backgrounds (tonut(head)) return tonode(head), done end -nodes.handlers.alignbackgrounds = function(head) local head, done = add_alignbackgrounds(tonut(head)) return tonode(head), done end +-- interfaces.implement { +-- name = "enablebackgroundboxes", +-- onlyonce = true, +-- actions = enableaction, +-- arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" } +-- } +-- +-- doing it in the shipout works as well but this is nicer + +local function enable(alignmentstoo) + if not enabled then + enabled = true + enableaction("shipouts","nodes.handlers.backgrounds") + end + if not alignments and alignmentstoo then + alignments = true + enableaction("vboxbuilders","nodes.handlers.backgroundsvbox") + enableaction("mvlbuilders", "nodes.handlers.backgroundspage") + end +end interfaces.implement { name = "enablebackgroundboxes", onlyonce = true, - actions = enableaction, - arguments = { "'shipouts'", "'nodes.handlers.backgrounds'" } + actions = enable, } interfaces.implement { name = "enablebackgroundalign", onlyonce = true, - actions = enableaction, - arguments = { "'shipouts'", "'nodes.handlers.alignbackgrounds'" } + actions = function() + enable(true) + end, +} + +interfaces.implement { + name = "setbackgroundrowdata", + arguments = { "integer", "integer", "dimension" }, + actions = function(row,box,indent) + row = row -1 -- better here than in tex + if box == 0 then + templates[row] = false + else + templates[row] = { takebox(box), indent } + end + end, +} + +interfaces.implement { + name = "resetbackgroundrowdata", + actions = function() + currentrow = 0 + end, } diff --git a/tex/context/base/mkiv/node-bck.mkiv b/tex/context/base/mkiv/node-bck.mkiv index 6bfc43d6a..b09327443 100644 --- a/tex/context/base/mkiv/node-bck.mkiv +++ b/tex/context/base/mkiv/node-bck.mkiv @@ -16,12 +16,10 @@ %D This is first attempt to replacing backgrounds in a few tables %D mechanisms. When used more frequently, we can store the color %D spec in the attribute. -%D -%D Maybe move some to the bar handler. \unprotect -\registerctxluafile{node-bck}{} +\registerctxluafile{node-bck}{optimize} % \backgroundvbox[green] {\input tufte } \par % \backgroundvbox[blue] {\input ward } \par @@ -74,6 +72,9 @@ \unexpanded\def\backgroundvbox{\node_backgrounds_boxes_add\vbox} \unexpanded\def\backgroundvtop{\node_backgrounds_boxes_add\vtop} +\unexpanded\def\backgroundline{\dontleavehmode + \node_backgrounds_boxes_add\hbox} + % \def\node_backgrounds_boxes_add#1[#2]% % {\begingroup % \clf_enablebackgroundboxes @@ -90,18 +91,4 @@ {\clf_enablebackgroundboxes #1\backgroundcolorattr{#2}} -% less argument carry over: -% -% \def\node_backgrounds_boxes_add#1[#2]% -% {\clf_enablebackgroundboxes#1% -% \ifcsname\??colorattribute\currentcolorprefix#2\endcsname -% \thebackgroundcolorattr{\currentcolorprefix#2}% -% \else\ifcsname\??colorattribute#2\endcsname -% \thebackgroundcolorattr{#2}% -% \fi\fi} - -% \def\backgroundvbox[#1]{\vbox \backgroundcolorattr{#1}} -% \def\backgroundvtop[#1]{\vtop \backgroundcolorattr{#1}} -% \def\backgroundhbox[#1]{\hbox \backgroundcolorattr{#1}} - \protect \endinput diff --git a/tex/context/base/mkiv/node-dir.lua b/tex/context/base/mkiv/node-dir.lua index 59564ac93..3f0cba67e 100644 --- a/tex/context/base/mkiv/node-dir.lua +++ b/tex/context/base/mkiv/node-dir.lua @@ -6,304 +6,61 @@ if not modules then modules = { } end modules ['node-dir'] = { license = "see context related readme files" } ---[[ -

In the process of cleaning up the lua variant of the parbuilder -we ran into a couple of functions (translated c macros) that were -somewhat inefficient. More convenient is to use hashes although at -the c-end still macros are used. In the process directions.h was -adapted and now has the mappings as comments. This lua file is -based on that file. -]]-- - -local allocate = utilities.storage.allocate - -local nodes = nodes - -nodes.is_mirrored = allocate { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, -} - -nodes.is_rotated = allocate { -- used - -- TLT = false, - -- TRT = false, - -- LTL = false, - RTT = true, ["+RTT"] = true, -} - -nodes.textdir_is_parallel = allocate { -- used - TLT = { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - TRT= { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - LTL = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, - RTT = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - } -} - -nodes.pardir_is_parallel = allocate { - TLT = { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - TRT = { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - LTL = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, - RTT = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, -} - -nodes.pardir_is_opposite = allocate { - TLT = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - TRT = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - LTL = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - RTT = true, ["+RTT"] = true, - }, - RTT = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - -- RTT = false, - }, -} - -nodes.textdir_is_opposite = allocate { -- used - TLT = { - -- TLT = false, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - TRT= { - TLT = true, ["+TLT"] = true, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - LTL = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - RTT = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, -} - -nodes.glyphdir_is_opposite = allocate { - TLT = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - TRT= { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - LTL = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - RTT = { - -- TLT = false, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, -} - -nodes.pardir_is_equal = allocate { -- used - TLT = { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - TRT= { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - LTL= { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - -- RTT = false, - }, - RTT= { - -- TLT = false, - -- TRT = false, - -- LTL = false, - RTT = true, ["+RTT"] = true, - }, -} - -nodes.textdir_is_equal = allocate { -- used - TLT = { - TLT = true, ["+TLT"] = true, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - TRT= { - -- TLT = false, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, - LTL = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, - RTT = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, -} - -nodes.glyphdir_is_equal = allocate { -- used - TLT = { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - RTT = true, ["+RTT"] = true, - }, - TRT= { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - RTT = true, ["+RTT"] = true, - }, - LTL = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - -- RTT = false, - }, - RTT = { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - -- LTL = false, - RTT = true, ["+RTT"] = true, - }, -} - -nodes.partextdir_is_equal = allocate { - TLT = { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, - TRT= { - -- TLT = false, - -- TRT = false, - LTL = true, ["+LTL"] = true, - RTT = true, ["+RTT"] = true, - }, - LTL = { - TLT = true, ["+TLT"] = true, - -- TRT = false, - -- LTL = false, - -- RTT = false, - }, - RTT = { - -- TLT = false, - TRT = true, ["+TRT"] = true, - -- LTL = false, - -- RTT = false, - }, -} - -nodes.textdir_is_is = allocate { - TLT = true, ["+TLT"] = true, - -- TRT = false, - -- LTL = false, - -- RTT = false, -} - -nodes.glyphdir_is_orthogonal = allocate { - TLT = true, ["+TLT"] = true, - TRT = true, ["+TRT"] = true, - LTL = true, ["+LTL"] = true, - -- RTT = false -} - -nodes.dir_is_pop = allocate { -- used - ["-TRT"] = true, - ["-TLT"] = true, - ["-LTL"] = true, - ["-RTT"] = true, -} - -nodes.dir_negation = allocate { -- used - ["-TRT"] = "+TRT", - ["-TLT"] = "+TLT", - ["-LTL"] = "+LTL", - ["-RTT"] = "+RTT", - ["+TRT"] = "-TRT", - ["+TLT"] = "-TLT", - ["+LTL"] = "-LTL", - ["+RTT"] = "-RTT", -} +-- This is experimental code, so when I change it I need to check other modules +-- too. +-- +-- Local par nodes are somewhat special. They start a paragraph and then register +-- the par direction. But they can also show op mid paragraph in which case they +-- register boxes and penalties. In that case the direction should not be affected. +-- +-- We can assume that when hpack and prelinebreak filters are called, a local par +-- still sits at the head, but after a linebreak pass this node can be after the +-- leftskip (when present). + +local nodes = nodes +local nuts = nodes.nuts + +local nodecodes = nodes.nodecodes +local localpar_code = nodecodes.localpar + +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getdirection = nuts.getdirection + +local dirvalues = nodes.dirvalues +local lefttoright = dirvalues.lefttoright +local righttoleft = dirvalues.righttoleft + +local localparnewgraf_code = 0 + +local function newstack(head,direction) + local stack = { } + local top = 0 + if head and getid(head) == localpar_code and getsubtype(head) == localparnewgraf_code then + direction = getdirection(head) + end + if not direction then + direction = lefttoright + elseif direction == "TLT" then + direction = lefttoright + elseif direction == "TRT" then + direction = righttoleft + end + local function update(node) + local dir, pop = getdirection(node) + if not pop then + top = top + 1 + stack[top] = dir + return dir + elseif top == 0 then + return direction + elseif top == 1 then + top = 0 + return direction + else + top = top - 1 + return stack[top] + end + end + return direction, update +end diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index 975eb0bec..dc681d165 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -16,16 +16,15 @@ local next, type, format = next, type, string.format local attributes, nodes, node = attributes, nodes, node local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut local getnext = nuts.getnext -local getprev = nuts.getprev local getid = nuts.getid local getlist = nuts.getlist local getleader = nuts.getleader local getattr = nuts.getattr local getwidth = nuts.getwidth +local getwhd = nuts.getwhd +local getorientation = nuts.getorientation local setlist = nuts.setlist local setleader = nuts.setleader @@ -34,10 +33,22 @@ local copy_node = nuts.copy local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after +local nextnode = nuts.traversers.node + local nodecodes = nodes.nodecodes -local whatcodes = nodes.whatcodes local rulecodes = nodes.rulecodes +----- normalrule_code = rulecodes.normal +local boxrule_code = rulecodes.box +local imagerule_code = rulecodes.image +local emptyrule_code = rulecodes.empty +----- userrule_code = rulecodes.user +----- overrule_code = rulecodes.over +----- underrule_code = rulecodes.under +----- fractionrule_code = rulecodes.fraction +----- radicalrule_code = rulecodes.radical +----- outlinerule_code = rulecodes.outline + local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc local glue_code = nodecodes.glue @@ -82,37 +93,34 @@ local finalizer = plugin.finalizer local flusher = plugin.flusher if not processor then return function(head) - return head, false + return head end elseif initializer or finalizer or resolver then return function(head) starttiming(attributes) - local done, used, ok, inheritance = false, nil, false, nil + local used, inheritance if resolver then inheritance = resolver() end if initializer then initializer(namespace,attribute,head) end - head, ok = processor(namespace,attribute,head,inheritance) - if ok then - if finalizer then - head, ok, used = finalizer(namespace,attribute,head) - if used and flusher then - head = flusher(namespace,attribute,head,used) - end + head = processor(namespace,attribute,head,inheritance) + if finalizer then + head, used = finalizer(namespace,attribute,head) + if used and flusher then + head = flusher(namespace,attribute,head,used) end - done = true end stoptiming(attributes) - return head, done + return head end else return function(head) starttiming(attributes) - local head, done = processor(namespace,attribute,head) + head = processor(namespace,attribute,head) stoptiming(attributes) - return head, done + return head end end nodes.plugindata = nil @@ -126,7 +134,7 @@ end -- the injectors local nsdata, nsnone, nslistwise, nsforced, nsselector, nstrigger -local current, current_selector, done = 0, 0, false -- nb, stack has a local current ! +local current, current_selector = 0, 0 -- nb, stack has a local current ! local nsbegin, nsend, nsreset function states.initialize(namespace,attribute,head) @@ -138,7 +146,6 @@ function states.initialize(namespace,attribute,head) nstrigger = triggering and namespace.triggering and a_trigger current = 0 current_selector = 0 - done = false -- todo: done cleanup nsstep = namespace.resolve_step if nsstep then nsreset = namespace.resolve_reset @@ -151,7 +158,6 @@ end function states.finalize(namespace,attribute,head) -- is this one ok? if current > 0 and nsnone then - head = tonut(head) local id = getid(head) if id == hlist_code or id == vlist_code then local content = getlist(head) @@ -164,20 +170,17 @@ function states.finalize(namespace,attribute,head) -- is this one ok? else head = insert_node_before(head,head,copy_node(nsnone)) end - return tonode(head), true, true + return head, true end - return head, false, false + return head, false end -- we need to deal with literals too (reset as well as oval) local function process(attribute,head,inheritance,default) -- one attribute - local stack = head - local done = false local check = false local leader = nil - while stack do - local id = getid(stack) + for stack, id in nextnode, head do if id == glyph_code or id == disc_code then check = true -- disc no longer needed as we flatten replace elseif id == glue_code then @@ -188,39 +191,52 @@ local function process(attribute,head,inheritance,default) -- one attribute elseif id == hlist_code or id == vlist_code then local content = getlist(stack) if content then + -- tricky checking + local outer + if getorientation(stack) then + outer = getattr(stack,attribute) + if outer then + if default and outer == inheritance then + if current ~= default then + head = insert_node_before(head,stack,copy_node(nsdata[default])) + current = default + end + elseif current ~= outer then + head = insert_node_before(head,stack,copy_node(nsdata[c])) + current = outer + end + elseif default and inheritance then + if current ~= default then + head = insert_node_before(head,stack,copy_node(nsdata[default])) + current = default + end + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current = 0 + end + end -- begin nested -- + local list if nstrigger and getattr(stack,nstrigger) then - local outer = getattr(stack,attribute) + if not outer then + outer = getattr(stack,attribute) + end if outer ~= inheritance then - local list, ok = process(attribute,content,inheritance,outer) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = process(attribute,content,inheritance,outer) else - local list, ok = process(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = process(attribute,content,inheritance,default) end else - local list, ok = process(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = process(attribute,content,inheritance,default) + end + if content ~= list then + setlist(stack,list) end -- end nested -- end elseif id == rule_code then - check = getwidth(stack) ~= 0 + local wd, ht, dp = getwhd(stack) + check = wd ~= 0 or (ht+dp) ~= 0 end -- much faster this way than using a check() and nested() function if check then @@ -230,12 +246,10 @@ local function process(attribute,head,inheritance,default) -- one attribute if current ~= default then head = insert_node_before(head,stack,copy_node(nsdata[default])) current = default - done = true end elseif current ~= c then head = insert_node_before(head,stack,copy_node(nsdata[c])) current = c - done = true end if leader then local savedcurrent = current @@ -247,33 +261,19 @@ local function process(attribute,head,inheritance,default) -- one attribute current = 0 end -- begin nested -- + local list if nstrigger and getattr(stack,nstrigger) then local outer = getattr(stack,attribute) if outer ~= inheritance then - local list, ok = process(attribute,leader,inheritance,outer) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = process(attribute,leader,inheritance,outer) else - local list, ok = process(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = process(attribute,leader,inheritance,default) end else - local list, ok = process(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = process(attribute,leader,inheritance,default) + end + if leader ~= list then + setleader(stack,list) end -- end nested -- current = savedcurrent @@ -283,23 +283,19 @@ local function process(attribute,head,inheritance,default) -- one attribute if current ~= default then head = insert_node_before(head,stack,copy_node(nsdata[default])) current = default - done = true end elseif current > 0 then head = insert_node_before(head,stack,copy_node(nsnone)) current = 0 - done = true end check = false end - stack = getnext(stack) end - return head, done + return head end states.process = function(namespace,attribute,head,default) - local head, done = process(attribute,tonut(head),default) - return tonode(head), done + return process(attribute,head,default) end -- we can force a selector, e.g. document wide color spaces, saves a little @@ -309,13 +305,9 @@ end -- each other with the same color but different color spaces e.g. \showcolor) local function selective(attribute,head,inheritance,default) -- two attributes - -- local head = head - local stack = head - local done = false local check = false local leader = nil - while stack do - local id = getid(stack) + for stack, id, subtype in nextnode, head do if id == glyph_code or id == disc_code then check = true -- disc no longer needed as we flatten replace elseif id == glue_code then @@ -326,41 +318,66 @@ local function selective(attribute,head,inheritance,default) -- two attributes elseif id == hlist_code or id == vlist_code then local content = getlist(stack) if content then + -- tricky checking + local outer + if getorientation(stack) then + outer = getattr(stack,attribute) + if outer then + if default and outer == inheritance then + if current ~= default then + local data = nsdata[default] + head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector])) + current = default + end + else + local s = getattr(stack,nsselector) + -- local s = nsforced or getattr(stack,nsselector) + if current ~= outer or current_selector ~= s then + local data = nsdata[outer] + head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector])) + current = outer + current_selector = s + end + end + elseif default and inheritance then + if current ~= default then + local data = nsdata[default] + head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector])) + current = default + end + elseif current > 0 then + head = insert_node_before(head,stack,copy_node(nsnone)) + current, current_selector = 0, 0 + end + end -- begin nested + local list if nstrigger and getattr(stack,nstrigger) then - local outer = getattr(stack,attribute) + if not outer then + outer = getattr(stack,attribute) + end if outer ~= inheritance then - local list, ok = selective(attribute,content,inheritance,outer) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = selective(attribute,content,inheritance,outer) else - local list, ok = selective(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = selective(attribute,content,inheritance,default) end else - local list, ok = selective(attribute,content,inheritance,default) - if content ~= list then - setlist(stack,list) - end - if ok then - done = true - end + list = selective(attribute,content,inheritance,default) + end + if content ~= list then + setlist(stack,list) end -- end nested end elseif id == rule_code then - check = getwidth(stack) ~= 0 + if subtype == boxrule_code or subtype == imagerule_code or subtype == emptyrule_code then + -- so no redundant color stuff (only here, layers for instance should obey) + check = false + else + local wd, ht, dp = getwhd(stack) + check = wd ~= 0 or (ht+dp) ~= 0 + end end - if check then local c = getattr(stack,attribute) if c then @@ -369,9 +386,6 @@ local function selective(attribute,head,inheritance,default) -- two attributes local data = nsdata[default] head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector])) current = default - if ok then - done = true - end end else local s = getattr(stack,nsselector) @@ -379,43 +393,25 @@ local function selective(attribute,head,inheritance,default) -- two attributes if current ~= c or current_selector ~= s then local data = nsdata[c] head = insert_node_before(head,stack,copy_node(data[nsforced or s or nsselector])) - -- head = insert_node_before(head,stack,copy_node(data[s or nsselector])) current = c current_selector = s - if ok then - done = true - end end end if leader then -- begin nested + local list if nstrigger and getattr(stack,nstrigger) then local outer = getattr(stack,attribute) if outer ~= inheritance then - local list, ok = selective(attribute,leader,inheritance,outer) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = selective(attribute,leader,inheritance,outer) else - local list, ok = selective(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = selective(attribute,leader,inheritance,default) end else - local list, ok = selective(attribute,leader,inheritance,default) - if leader ~= list then - setleader(stack,list) - end - if ok then - done = true - end + list = selective(attribute,leader,inheritance,default) + end + if leader ~= list then + setleader(stack,list) end -- end nested leader = false @@ -425,22 +421,19 @@ local function selective(attribute,head,inheritance,default) -- two attributes local data = nsdata[default] head = insert_node_before(head,stack,copy_node(data[nsforced or getattr(stack,nsselector) or nsselector])) current = default - done = true end elseif current > 0 then head = insert_node_before(head,stack,copy_node(nsnone)) - current, current_selector, done = 0, 0, true + current, current_selector = 0, 0 end check = false end - stack = getnext(stack) end - return head, done + return head end states.selective = function(namespace,attribute,head,default) - local head = selective(attribute,tonut(head),default) - return tonode(head), true + return selective(attribute,head,default) end -- Ideally the next one should be merged with the previous but keeping it separate is @@ -454,7 +447,6 @@ end local function stacked(attribute,head,default) -- no triggering, no inheritance, but list-wise local stack = head - local done = false local current = default or 0 local depth = 0 local check = false @@ -472,42 +464,30 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, local content = getlist(stack) if content then -- the problem is that broken lines gets the attribute which can be a later one + local list if nslistwise then local a = getattr(stack,attribute) if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below local p = current current = a head = insert_node_before(head,stack,copy_node(nsdata[a])) - local list = stacked(attribute,content,current) -- two return values - if content ~= list then - setlist(stack,list) - end + list = stacked(attribute,content,current) -- two return values head, stack = insert_node_after(head,stack,copy_node(nsnone)) current = p - done = true else - local list, ok = stacked(attribute,content,current) - if content ~= list then - setlist(stack,list) -- only if ok - end - if ok then - done = true - end + list = stacked(attribute,content,current) end else - local list, ok = stacked(attribute,content,current) - if content ~= list then - setlist(stack,list) -- only if ok - end - if ok then - done = true - end + list = stacked(attribute,content,current) + end + if content ~= list then + setlist(stack,list) -- only if ok end end elseif id == rule_code then - check = getwidth(stack) ~= 0 + local wd, ht, dp = getwhd(stack) + check = wd ~= 0 or (ht+dp) ~= 0 end - if check then local a = getattr(stack,attribute) if a then @@ -515,15 +495,14 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, head = insert_node_before(head,stack,copy_node(nsdata[a])) depth = depth + 1 current = a - done = true end if leader then - local list, ok = stacked(attribute,content,current) - if leader ~= list then - setleader(stack,list) -- only if ok - end - if ok then - done = true + local content = getlist(leader) + if content then + local list = stacked(attribute,content,current) + if leader ~= list then + setleader(stack,list) -- only if ok + end end leader = false end @@ -533,7 +512,6 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, head = insert_node_before(head,stack,copy_node(nsnone)) depth = depth - 1 current = 0 - done = true end check = false end @@ -543,24 +521,22 @@ local function stacked(attribute,head,default) -- no triggering, no inheritance, head = insert_node_after(head,stack,copy_node(nsnone)) depth = depth - 1 end - return head, done + return head end states.stacked = function(namespace,attribute,head,default) - local head, done = stacked(attribute,tonut(head),default) - return tonode(head), done + return stacked(attribute,head,default) end -- experimental local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise --- nsbegin() + -- nsbegin() local stacked = false local current = head local previous = head - local done = false local attrib = default or unsetvalue local check = false local leader = false @@ -576,38 +552,27 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, end elseif id == hlist_code or id == vlist_code then local content = getlist(current) - if not content then - -- skip - elseif nslistwise then - local a = getattr(current,attribute) - if a and attrib ~= a and nslistwise[a] then -- viewerlayer - head = insert_node_before(head,current,copy_node(nsdata[a])) - local list = stacker(attribute,content,a) - if list ~= content then - setlist(current,list) + if content then + local list + if nslistwise then + local a = getattr(current,attribute) + if a and attrib ~= a and nslistwise[a] then -- viewerlayer + head = insert_node_before(head,current,copy_node(nsdata[a])) + list = stacker(attribute,content,a) + head, current = insert_node_after(head,current,copy_node(nsnone)) + else + list = stacker(attribute,content,attrib) end - done = true - head, current = insert_node_after(head,current,copy_node(nsnone)) else - local list, ok = stacker(attribute,content,attrib) - if content ~= list then - setlist(current,list) - end - if ok then - done = true - end + list = stacker(attribute,content,default) end - else - local list, ok = stacker(attribute,content,default) if list ~= content then setlist(current,list) end - if ok then - done = true - end end elseif id == rule_code then - check = getwidth(current) ~= 0 + local wd, ht, dp = getwhd(current) + check = wd ~= 0 or (ht+dp) ~= 0 end if check then @@ -619,16 +584,22 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, end local n = nsstep(a) if n then - head = insert_node_before(head,current,tonut(n)) -- a + head = insert_node_before(head,current,n) -- a end attrib = a - done = true if leader then -- tricky as a leader has to be a list so we cannot inject before - local list, ok = stacker(attribute,leader,attrib) - if ok then - done = true + -- local list = stacker(attribute,leader,attrib) + -- leader = false + + local content = getlist(leader) + if content then + local list = stacker(attribute,leader,attrib) + if leader ~= list then + setleader(current,list) + end end + leader = false end end @@ -642,18 +613,101 @@ local function stacker(attribute,head,default) -- no triggering, no inheritance, if stacked then local n = nsend() while n do - head = insert_node_after(head,previous,tonut(n)) + head = insert_node_after(head,previous,n) n = nsend() end end - return head, done + return head end +-- local nextid = nodes.nuts.traversers.id +-- +-- local function stacker(attribute,head,default) -- no triggering, no inheritance, but list-wise +-- +-- -- nsbegin() +-- local stacked = false +-- +-- local current = head +-- local previous = head +-- local attrib = default or unsetvalue +-- local check = false +-- local leader = false +-- +-- local id = getid(current) +-- while current do +-- if id == glyph_code then +-- check = true +-- elseif id == glue_code then +-- leader = getleader(current) +-- if leader then +-- check = true +-- end +-- elseif id == hlist_code or id == vlist_code then +-- local content = getlist(current) +-- if content then +-- local list +-- if nslistwise then +-- local a = getattr(current,attribute) +-- if a and attrib ~= a and nslistwise[a] then -- viewerlayer +-- head = insert_node_before(head,current,copy_node(nsdata[a])) +-- list = stacker(attribute,content,a) +-- head, current = insert_node_after(head,current,copy_node(nsnone)) +-- else +-- list = stacker(attribute,content,attrib) +-- end +-- else +-- list = stacker(attribute,content,default) +-- end +-- if list ~= content then +-- setlist(current,list) +-- end +-- end +-- elseif id == rule_code then +-- check = getwidth(current) ~= 0 +-- end +-- +-- if check then +-- local a = getattr(current,attribute) or unsetvalue +-- if a ~= attrib then +-- if not stacked then +-- stacked = true +-- nsbegin() +-- end +-- local n = nsstep(a) +-- if n then +-- head = insert_node_before(head,current,n) -- a +-- end +-- attrib = a +-- if leader then +-- -- tricky as a leader has to be a list so we cannot inject before +-- local list = stacker(attribute,leader,attrib) +-- leader = false +-- end +-- end +-- check = false +-- end +-- +-- previous = current +-- +-- current, id = nextid(current,current) +-- end +-- +-- if stacked then +-- local n = nsend() +-- while n do +-- head = insert_node_after(head,previous,n) +-- n = nsend() +-- end +-- end +-- +-- return head +-- end + states.stacker = function(namespace,attribute,head,default) - local head, done = stacker(attribute,tonut(head),default) + local head = stacker(attribute,head,default) nsreset() - return tonode(head), done + return head end -- -- -- diff --git a/tex/context/base/mkiv/node-fin.mkiv b/tex/context/base/mkiv/node-fin.mkiv index 4f1ff2aba..086b19ae5 100644 --- a/tex/context/base/mkiv/node-fin.mkiv +++ b/tex/context/base/mkiv/node-fin.mkiv @@ -18,8 +18,8 @@ \unprotect -\registerctxluafile{node-shp}{} -\registerctxluafile{node-fin}{} % we might generalize this one +\registerctxluafile{node-shp}{optimize} +\registerctxluafile{node-fin}{optimize} % we might generalize this one % we might have two variants at some point (efficiency) diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua index f846f996d..154853121 100644 --- a/tex/context/base/mkiv/node-fnt.lua +++ b/tex/context/base/mkiv/node-fnt.lua @@ -37,22 +37,20 @@ local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming local nodecodes = nodes.nodecodes +local boundarycodes = nodes.boundarycodes + local handlers = nodes.handlers local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getattr = nuts.getattr local getid = nuts.getid -local getfont = nuts.getfont local getsubtype = nuts.getsubtype -local getchar = nuts.getchar local getdisc = nuts.getdisc local getnext = nuts.getnext local getprev = nuts.getprev local getboth = nuts.getboth -local getfield = nuts.getfield +local getdata = nuts.getdata ----- getdisc = nuts.getdisc local setchar = nuts.setchar local setlink = nuts.setlink @@ -62,14 +60,18 @@ local setprev = nuts.setprev local isglyph = nuts.isglyph -- unchecked local ischar = nuts.ischar -- checked -local traverse_id = nuts.traverse_id -local traverse_char = nuts.traverse_char -local protect_glyph = nuts.protect_glyph +----- traverse_id = nuts.traverse_id +----- traverse_char = nuts.traverse_char +local nextboundary = nuts.traversers.boundary +local nextdisc = nuts.traversers.disc +local nextchar = nuts.traversers.char + local flush_node = nuts.flush local disc_code = nodecodes.disc local boundary_code = nodecodes.boundary -local word_boundary = nodes.boundarycodes.word + +local wordboundary_code = boundarycodes.word local protect_glyphs = nuts.protect_glyphs local unprotect_glyphs = nuts.unprotect_glyphs @@ -144,10 +146,10 @@ local kerning = nuts.kerning -- -- -- this will go away -- --- local disccodes = nodes.disccodes --- local explicit_code = disccodes.explicit --- local automatic_code = disccodes.automatic --- local expanders = nil +-- local disccodes = nodes.disccodes +-- local explicitdisc_code = disccodes.explicit +-- local automaticdisc_code = disccodes.automatic +-- local expanders = nil -- -- function fonts.setdiscexpansion(v) -- if v == nil or v == true then @@ -172,17 +174,17 @@ local function start_trace(head) report_fonts() report_fonts("checking node list, run %s",run) report_fonts() - local n = tonut(head) + local n = head while n do local char, id = isglyph(n) if char then - local font = getfont(n) + local font = id local attr = getattr(n,0) or 0 report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,char) elseif id == disc_code then report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n)) elseif id == boundary_code then - report_fonts("[boundary] %i:%i",getsubtype(n),getfield(n,"value")) + report_fonts("[boundary] %i:%i",getsubtype(n),getdata(n)) else report_fonts("[%s]",nodecodes[id]) end @@ -202,32 +204,23 @@ local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expa report_fonts() end -function handlers.characters(head,groupcode,size,packtype,direction) - -- either next or not, but definitely no already processed list - starttiming(nodes) - - local usedfonts = { } - local attrfonts = { } - local basefonts = { } - local basefont = nil - local prevfont = nil - local prevattr = 0 - local done = false - local variants = nil - local redundant = nil - local nuthead = tonut(head) - local lastfont = nil - local lastproc = nil - local lastnone = nil - - local a, u, b, r, e = 0, 0, 0, 0, 0 - - if trace_fontrun then - start_trace(head) - end - -- There is no gain in checking for a single glyph and then having a fast path. On the - -- metafun manual (with some 2500 single char lists) the difference is just noise. +do + + local usedfonts + local attrfonts + local basefonts + local basefont + local prevfont + local prevattr + local variants + local redundant + local firstnone + local lastfont + local lastproc + local lastnone + + local a, u, b, r, e local function protectnone() protect_glyphs(firstnone,lastnone) @@ -296,288 +289,290 @@ function handlers.characters(head,groupcode,size,packtype,direction) end end - for n in traverse_char(nuthead) do - local font = getfont(n) - -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context - local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context - if font ~= prevfont or attr ~= prevattr then - prevfont = font - prevattr = attr - variants = fontvariants[font] - local fontmode = fontmodes[font] - if fontmode == "none" then - setnone(n) - elseif fontmode == "base" then - setbase(n) - else - setnode(n,font,attr) - end - elseif firstnone then - lastnone = n + function handlers.characters(head,groupcode,size,packtype,direction) + -- either next or not, but definitely no already processed list + starttiming(nodes) + + usedfonts = { } + attrfonts = { } + basefonts = { } + basefont = nil + prevfont = nil + prevattr = 0 + variants = nil + redundant = nil + firstnone = nil + lastfont = nil + lastproc = nil + lastnone = nil + + a, u, b, r, e = 0, 0, 0, 0, 0 + + if trace_fontrun then + start_trace(head) end - if variants then - local char = getchar(n) - if char >= 0xFE00 and (char <= 0xFE0F or (char >= 0xE0100 and char <= 0xE01EF)) then - local hash = variants[char] - if hash then - local p = getprev(n) - if p then - local char = ischar(p) -- checked - local variant = hash[char] - if variant then - if trace_variants then - report_fonts("replacing %C by %C",char,variant) - end - setchar(p,variant) - if redundant then - r = r + 1 - redundant[r] = n - else - r = 1 - redundant = { n } + + -- There is no gain in checking for a single glyph and then having a fast path. On the + -- metafun manual (with some 2500 single char lists) the difference is just noise. + + for n, char, font in nextchar, head do + -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context + local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context + if font ~= prevfont or attr ~= prevattr then + prevfont = font + prevattr = attr + variants = fontvariants[font] + local fontmode = fontmodes[font] + if fontmode == "none" then + setnone(n) + elseif fontmode == "base" then + setbase(n) + else + setnode(n,font,attr) + end + elseif firstnone then + lastnone = n + end + if variants then + if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then + local hash = variants[char] + if hash then + local p = getprev(n) + if p then + local char = ischar(p) -- checked + local variant = hash[char] + if variant then + if trace_variants then + report_fonts("replacing %C by %C",char,variant) + end + setchar(p,variant) + if redundant then + r = r + 1 + redundant[r] = n + else + r = 1 + redundant = { n } + end end end + elseif keep_redundant then + -- go on, can be used for tracing + elseif redundant then + r = r + 1 + redundant[r] = n + else + r = 1 + redundant = { n } end - elseif keep_redundant then - -- go on, can be used for tracing - elseif redundant then - r = r + 1 - redundant[r] = n - else - r = 1 - redundant = { n } end end end - end - if firstnone then - protectnone() - end + if firstnone then + protectnone() + end - if force_boundaryrun then + if force_boundaryrun then - -- we can inject wordboundaries and then let the hyphenator do its work - -- but we need to get rid of those nodes in order to build ligatures - -- and kern (a rather context thing) + -- we can inject wordboundaries and then let the hyphenator do its work + -- but we need to get rid of those nodes in order to build ligatures + -- and kern (a rather context thing) - for b in traverse_id(boundary_code,nuthead) do - if getsubtype(b) == word_boundary then - if redundant then - r = r + 1 - redundant[r] = b - else - r = 1 - redundant = { b } + for b, subtype in nextboundary, head do + if subtype == wordboundary_code then + if redundant then + r = r + 1 + redundant[r] = b + else + r = 1 + redundant = { b } + end end end - end - end + end - if redundant then - for i=1,r do - local r = redundant[i] - local p, n = getboth(r) - if r == nuthead then - nuthead = n - setprev(n) - else - setlink(p,n) - end - if b > 0 then - for i=1,b do - local bi = basefonts[i] - local b1 = bi[1] - local b2 = bi[2] - if b1 == b2 then - if b1 == r then - bi[1] = false - bi[2] = false + if redundant then + for i=1,r do + local r = redundant[i] + local p, n = getboth(r) + if r == head then + head = n + setprev(n) + else + setlink(p,n) + end + if b > 0 then + for i=1,b do + local bi = basefonts[i] + local b1 = bi[1] + local b2 = bi[2] + if b1 == b2 then + if b1 == r then + bi[1] = false + bi[2] = false + end + elseif b1 == r then + bi[1] = n + elseif b2 == r then + bi[2] = p end - elseif b1 == r then - bi[1] = n - elseif b2 == r then - bi[2] = p end end + flush_node(r) end - flush_node(r) end - end - if force_discrun then - - -- basefont is not supported in disc only runs ... it would mean a lot of - -- ranges .. we could try to run basemode as a separate processor run but - -- not for now (we can consider it when the new node code is tested - for d in traverse_id(disc_code,nuthead) do - -- we could use first_glyph, only doing replace is good enough because - -- pre and post are normally used for hyphens and these come from fonts - -- that part of the hyphenated word - local _, _, r = getdisc(d) - if r then - local prevfont = nil - local prevattr = nil - local none = false - for n in traverse_char(r) do - local font = getfont(n) - local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context - if font ~= prevfont or attr ~= prevattr then - prevfont = font - prevattr = attr - local fontmode = fontmodes[font] - if fontmode == "none" then - setnone(n) - elseif fontmode == "base" then - setbase(n) - else - setnode(n,font,attr) + if force_discrun then + + -- basefont is not supported in disc only runs ... it would mean a lot of + -- ranges .. we could try to run basemode as a separate processor run but + -- not for now (we can consider it when the new node code is tested + for d in nextdisc, head do + -- we could use first_glyph, only doing replace is good enough because + -- pre and post are normally used for hyphens and these come from fonts + -- that part of the hyphenated word + local _, _, r = getdisc(d) + if r then + local prevfont = nil + local prevattr = nil + local none = false + for n, char, font in nextchar, r do + local attr = getattr(n) or 0 -- zero attribute is reserved for fonts in context + if font ~= prevfont or attr ~= prevattr then + prevfont = font + prevattr = attr + local fontmode = fontmodes[font] + if fontmode == "none" then + setnone(n) + elseif fontmode == "base" then + setbase(n) + else + setnode(n,font,attr) + end + elseif firstnone then + -- lastnone = n + lastnone = nil end - elseif firstnone then - -- lastnone = n - lastnone = nil + -- we assume one font for now (and if there are more and we get into issues then + -- we can always remove the break) + break end - -- we assume one font for now (and if there are more and we get into issues then - -- we can always remove the break) - break - end - if firstnone then - protectnone() + if firstnone then + protectnone() + end + -- elseif expanders then + -- local subtype = getsubtype(d) + -- if subtype == automaticdisc_code or subtype == explicitdisc_code then + -- expanders[subtype](d) + -- e = e + 1 + -- end end - -- elseif expanders then - -- local subtype = getsubtype(d) - -- if subtype == automatic_code or subtype == explicit_code then - -- expanders[subtype](d) - -- e = e + 1 - -- end end - end - - end - if trace_fontrun then - stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders) - end + end - -- in context we always have at least 2 processors - if u == 0 then - -- skip - elseif u == 1 then - local attr = a > 0 and 0 or false -- 0 is the savest way - for i=1,#lastproc do - local h, d = lastproc[i](head,lastfont,attr,direction) - if d then - if h then - head = h - end - done = true - end + if trace_fontrun then + stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expanders) end - else - -- local attr = a == 0 and false or 0 -- 0 is the savest way - local attr = a > 0 and 0 or false -- 0 is the savest way - for font, processors in next, usedfonts do -- unordered - for i=1,#processors do - local h, d = processors[i](head,font,attr,direction,u) - if d then - if h then - head = h - end - done = true - end + + -- in context we always have at least 2 processors + if u == 0 then + -- skip + elseif u == 1 then + local attr = a > 0 and 0 or false -- 0 is the savest way + for i=1,#lastproc do + head = lastproc[i](head,lastfont,attr,direction) end - end - end - if a == 0 then - -- skip - elseif a == 1 then - local font, dynamics = next(attrfonts) - for attribute, processors in next, dynamics do -- unordered, attr can switch in between - for i=1,#processors do - local h, d = processors[i](head,font,attribute,direction) - if d then - if h then - head = h - end - done = true + else + -- local attr = a == 0 and false or 0 -- 0 is the savest way + local attr = a > 0 and 0 or false -- 0 is the savest way + for font, processors in next, usedfonts do -- unordered + for i=1,#processors do + head = processors[i](head,font,attr,direction,u) end end end - else - for font, dynamics in next, attrfonts do + if a == 0 then + -- skip + elseif a == 1 then + local font, dynamics = next(attrfonts) for attribute, processors in next, dynamics do -- unordered, attr can switch in between for i=1,#processors do - local h, d = processors[i](head,font,attribute,direction,a) - if d then - if h then - head = h - end - done = true - end + head = processors[i](head,font,attribute,direction) end end - end - end - if b == 0 then - -- skip - elseif b == 1 then - -- only one font - local range = basefonts[1] - local start = range[1] - local stop = range[2] - if (start or stop) and (start ~= stop) then - local front = nuthead == start - if stop then - start = ligaturing(start,stop) - start = kerning(start,stop) - elseif start then -- safeguard - start = ligaturing(start) - start = kerning(start) - end - if front and nuthead ~= start then - -- nuthead = start - head = tonode(start) + else + for font, dynamics in next, attrfonts do + for attribute, processors in next, dynamics do -- unordered, attr can switch in between + for i=1,#processors do + head = processors[i](head,font,attribute,direction,a) + end + end end end - else - -- multiple fonts - for i=1,b do - local range = basefonts[i] + if b == 0 then + -- skip + elseif b == 1 then + -- only one font + local range = basefonts[1] local start = range[1] local stop = range[2] - if start then -- and start ~= stop but that seldom happens - local front = nuthead == start - local prev = getprev(start) - local next = getnext(stop) + if (start or stop) and (start ~= stop) then + local front = head == start if stop then - start, stop = ligaturing(start,stop) - start, stop = kerning(start,stop) - else + start = ligaturing(start,stop) + start = kerning(start,stop) + elseif start then -- safeguard start = ligaturing(start) start = kerning(start) end - -- is done automatically - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) + if front and head ~= start then + head = start end - -- till here - if front and nuthead ~= start then - nuthead = start - head = tonode(start) + end + else + -- multiple fonts + for i=1,b do + local range = basefonts[i] + local start = range[1] + local stop = range[2] + if start then -- and start ~= stop but that seldom happens + local front = head == start + local prev = getprev(start) + local next = getnext(stop) + if stop then + start, stop = ligaturing(start,stop) + start, stop = kerning(start,stop) + else + start = ligaturing(start) + start = kerning(start) + end + -- is done automatically + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + -- till here + if front and head ~= start then + head = start + end end end end + + stoptiming(nodes) + + if trace_characters then + nodes.report(head) + end + + return head end - stoptiming(nodes) - if trace_characters then - nodes.report(head,done) - end - return head, true + end -handlers.protectglyphs = function(n) protect_glyphs (tonut(n)) return n, true end -handlers.unprotectglyphs = function(n) unprotect_glyphs(tonut(n)) return n, true end +handlers.protectglyphs = protect_glyphs +handlers.unprotectglyphs = unprotect_glyphs diff --git a/tex/context/base/mkiv/node-ini.lua b/tex/context/base/mkiv/node-ini.lua index 50da140ce..f910c7e01 100644 --- a/tex/context/base/mkiv/node-ini.lua +++ b/tex/context/base/mkiv/node-ini.lua @@ -70,6 +70,12 @@ local formatcolumns = utilities.formatters.formatcolumns local getsubtypes = node.subtypes local getvalues = node.values +tex.magicconstants = { -- we use tex.constants for something else + running = -1073741824, + maxdimen = 1073741823, -- 0x3FFFFFFF or 2^30-1 + trueinch = 4736286, +} + -- local listcodes = allocate { -- [0] = "unknown", -- [1] = "line", @@ -108,12 +114,11 @@ dircodes = allocate { } -- local glyphcodes = allocate { --- [0] = "character", --- [1] = "glyph", --- [2] = "ligature", --- [3] = "ghost", --- [4] = "left", --- [5] = "right", +-- [ 1] = "character", +-- [ 2] = "ligature", +-- [ 4] = "ghost", +-- [ 8] = "left", +-- [16] = "right", -- } local glyphcodes = mark(getsubtypes("glyph")) @@ -281,11 +286,12 @@ local function simplified(t) end local nodecodes = simplified(node.types()) -local whatcodes = simplified(node.whatsits()) +local whatcodes = simplified(node.whatsits and node.whatsits() or { }) local usercodes = allocate { [ 97] = "attribute", -- a [100] = "number", -- d + [102] = "float", -- f [108] = "lua", -- l [110] = "node", -- n [115] = "string", -- s @@ -306,7 +312,7 @@ local noadoptions = allocate { -- local directionvalues = mark(getvalues("dir")) -- local gluevalues = mark(getvalues("glue")) --- local pdfliteralvalues = mark(getvalues("pdf_literal")) +-- local literalvalues = mark(getvalues("literal")) local dirvalues = allocate { [0] = "TLT", @@ -323,7 +329,7 @@ local gluevalues = allocate { [4] = "filll", } -local pdfliteralvalues = allocate { +local literalvalues = allocate { [0] = "origin", [1] = "page", [2] = "always", @@ -356,41 +362,90 @@ usercodes = allocate(swapped(usercodes,usercodes)) noadoptions = allocate(swapped(noadoptions,noadoptions)) dirvalues = allocate(swapped(dirvalues,dirvalues)) gluevalues = allocate(swapped(gluevalues,gluevalues)) -pdfliteralvalues = allocate(swapped(pdfliteralvalues,pdfliteralvalues)) - -nodes.gluecodes = gluecodes -nodes.dircodes = dircodes -nodes.boundarycodes = boundarycodes -nodes.noadcodes = noadcodes -nodes.nodecodes = nodecodes -nodes.whatcodes = whatcodes -nodes.listcodes = listcodes -nodes.glyphcodes = glyphcodes -nodes.kerncodes = kerncodes -nodes.penaltycodes = penaltycodes -nodes.mathcodes = mathcodes -nodes.fillcodes = fillcodes -nodes.margincodes = margincodes -nodes.disccodes = disccodes -nodes.accentcodes = accentcodes -nodes.radicalcodes = radicalcodes -nodes.fencecodes = fencecodes -nodes.rulecodes = rulecodes -nodes.leadercodes = leadercodes -nodes.usercodes = usercodes -nodes.noadoptions = noadoptions -nodes.dirvalues = dirvalues -nodes.gluevalues = gluevalues -nodes.pdfliteralvalues = pdfliteralvalues - -nodes.skipcodes = gluecodes -- more friendly -nodes.directioncodes = dircodes -- more friendly -nodes.whatsitcodes = whatcodes -- more official -nodes.marginkerncodes = margincodes -nodes.discretionarycodes = disccodes -nodes.directionvalues = dirvalues -- more friendly -nodes.skipvalues = gluevalues -- more friendly -nodes.literalvalues = pdfliteralvalues -- more friendly +literalvalues = allocate(swapped(literalvalues,literalvalues)) + +if CONTEXTLMTXMODE > 1 then + whatcodes.literal = 0x1 whatcodes[0x1] = "literal" + whatcodes.latelua = 0x2 whatcodes[0x2] = "latelua" + whatcodes.userdefined = 0x3 whatcodes[0x3] = "userdefined" + whatcodes.savepos = 0x4 whatcodes[0x4] = "savepos" + whatcodes.save = 0x5 whatcodes[0x5] = "save" + whatcodes.restore = 0x6 whatcodes[0x6] = "restore" + whatcodes.setmatrix = 0x7 whatcodes[0x7] = "setmatrix" + whatcodes.open = 0x8 whatcodes[0x8] = "open" + whatcodes.close = 0x9 whatcodes[0x9] = "close" + whatcodes.write = 0xA whatcodes[0xA] = "write" +elseif not whatcodes.literal then + whatcodes.literal = whatcodes.pdfliteral + whatcodes.save = whatcodes.pdfsave + whatcodes.restore = whatcodes.pdfrestore + whatcodes.setmatrix = whatcodes.pdfsetmatrix +end + +nodes.gluecodes = gluecodes +nodes.dircodes = dircodes +nodes.boundarycodes = boundarycodes +nodes.noadcodes = noadcodes +nodes.nodecodes = nodecodes +nodes.whatcodes = whatcodes +nodes.listcodes = listcodes +nodes.glyphcodes = glyphcodes +nodes.kerncodes = kerncodes +nodes.penaltycodes = penaltycodes +nodes.mathcodes = mathcodes +nodes.fillcodes = fillcodes +nodes.margincodes = margincodes +nodes.disccodes = disccodes +nodes.accentcodes = accentcodes +nodes.radicalcodes = radicalcodes +nodes.fencecodes = fencecodes +nodes.rulecodes = rulecodes +nodes.leadercodes = leadercodes +nodes.usercodes = usercodes +nodes.noadoptions = noadoptions +nodes.dirvalues = dirvalues +nodes.gluevalues = gluevalues +nodes.literalvalues = literalvalues + +dirvalues.lefttoright = 0 +dirvalues.righttoleft = 1 + +nodes.subtypes = allocate { + [nodecodes.accent] = accentcodes, + [nodecodes.boundary] = boundarycodes, + [nodecodes.dir] = dircodes, + [nodecodes.disc] = disccodes, + [nodecodes.fence] = fencecodes, + [nodecodes.glue] = gluecodes, + [nodecodes.glyph] = glyphcodes, + [nodecodes.hlist] = listcodes, + [nodecodes.kern] = kerncodes, + [nodecodes.marginkern] = margincodes, + [nodecodes.math] = mathcodes, + [nodecodes.noad] = noadcodes, + [nodecodes.penalty] = penaltycodes, + [nodecodes.radical] = radicalcodes, + [nodecodes.rule] = rulecodes, + [nodecodes.vlist] = listcodes, + [nodecodes.whatsit] = whatcodes, +} + +table.setmetatableindex(nodes.subtypes,function(t,k) + local v = { } + t[k] = v + return v +end) + +nodes.skipcodes = gluecodes -- more friendly +nodes.directioncodes = dircodes -- more friendly +nodes.whatsitcodes = whatcodes -- more official +nodes.marginkerncodes = margincodes +nodes.discretionarycodes = disccodes +nodes.directionvalues = dirvalues -- more friendly +nodes.skipvalues = gluevalues -- more friendly +nodes.literalvalues = literalvalues -- more friendly + +glyphcodes.glyph = glyphcodes.character listcodes.row = listcodes.alignment listcodes.column = listcodes.alignment @@ -399,7 +454,7 @@ kerncodes.kerning = kerncodes.fontkern kerncodes.italiccorrection = kerncodes.italiccorrection or 1 -- new -pdfliteralvalues.direct = pdfliteralvalues.always +literalvalues.direct = literalvalues.always nodes.codes = allocate { -- mostly for listing glue = skipcodes, @@ -468,4 +523,3 @@ end if node.fix_node_lists then node.fix_node_lists(false) end - diff --git a/tex/context/base/mkiv/node-ini.mkiv b/tex/context/base/mkiv/node-ini.mkiv index 8f1079163..35013c4b8 100644 --- a/tex/context/base/mkiv/node-ini.mkiv +++ b/tex/context/base/mkiv/node-ini.mkiv @@ -21,7 +21,7 @@ \registerctxluafile{node-met}{} \registerctxluafile{node-nut}{} \registerctxluafile{node-res}{} -\registerctxluafile{node-ppt}{} % experimental +%registerctxluafile{node-ppt}{} % experimental, not used so probably useless \registerctxluafile{node-dir}{} \registerctxluafile{node-aux}{} \registerctxluafile{node-tst}{} @@ -34,9 +34,9 @@ \registerctxluafile{node-ext}{} \registerctxluafile{node-acc}{} % experimental %registerctxluafile{node-prp}{} % makes no sense (yet) -\registerctxluafile{node-ppt}{} \registerctxluafile{node-scn}{} \registerctxluafile{node-syn}{} +\registerctxluafile{node-par}{} \newcount\c_node_tracers_show_box % box number diff --git a/tex/context/base/mkiv/node-ltp.lua b/tex/context/base/mkiv/node-ltp.lua index 865f69c2c..0d501890b 100644 --- a/tex/context/base/mkiv/node-ltp.lua +++ b/tex/context/base/mkiv/node-ltp.lua @@ -134,6 +134,53 @@ if not modules then modules = { } end modules ['node-par'] = { ]]-- +--[[-- + +#define dir_TLT 0 +#define dir_TRT 1 +#define dir_LTL 2 +#define dir_RTT 3 + +#define dir_TLT_or_TRT(A) (A < 2) +#define dir_LTL_or_RTT(A) (A > 1) + +#define textdir_parallel(A,B) (\ +(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \ +(dir_LTL_or_RTT(A) and dir_LTL_or_RTT(B))\ +) + +#define pardir_parallel(A,B) (\ +(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \ +(dir_LTL_or_RTT(A) and dir_LTL_or_RTT(B))\ +) + +#define pardir_opposite(A,B) (\ +(A == dir_LTL and B == dir_RTT) or \ +(A == dir_RTT and B == dir_LTL)\ +) + +#define textdir_opposite(A,B) (\ +(A == dir_TLT and B == dir_TRT) or \ +(A == dir_TRT and B == dir_TLT)\ +) + +#define glyphdir_opposite(A,B) 0 + +#define pardir_equal(A,B) (\ +(dir_TLT_or_TRT(A) and dir_TLT_or_TRT(B)) or \ +(A == dir_LTL and B == dir_LTL) or \ +(A == dir_RTT and B == dir_RTT)\ +) + +#define textdir_equal(A,B) (\ +(A == dir_TLT and B == dir_TLT) or \ +(A == dir_TRT and B == dir_TRT) or \ +(A == dir_LTL and dir_LTL_or_RTT(B)) or \ +(A == dir_RTT and dir_LTL_or_RTT(B))\ +) + +--]]-- + local tonumber = tonumber local utfchar = utf.char local write, write_nl = texio.write, texio.write_nl @@ -191,7 +238,6 @@ local parameters = fonthashes.parameters local nuts = nodes.nuts local tonut = nuts.tonut -local tonode = nuts.tonode local getfield = nuts.getfield local getid = nuts.getid @@ -200,21 +246,20 @@ local getnext = nuts.getnext local getprev = nuts.getprev local getboth = nuts.getboth local getlist = nuts.getlist -local getfont = nuts.getfont -local getchar = nuts.getchar local getdisc = nuts.getdisc local getattr = nuts.getattr local getdisc = nuts.getdisc local getglue = nuts.getglue local getwhd = nuts.getwhd -local getcomponents = nuts.getcomponents local getkern = nuts.getkern local getpenalty = nuts.getpenalty -local getdir = nuts.getdir +local getdirection = nuts.getdirection local getshift = nuts.getshift local getwidth = nuts.getwidth local getheight = nuts.getheight local getdepth = nuts.getdepth +local getdata = nuts.getdata +local getwhd = nuts.getwhd local isglyph = nuts.isglyph @@ -229,11 +274,10 @@ local setsubtype = nuts.setsubtype local setglue = nuts.setglue local setwhd = nuts.setwhd local setkern = nuts.setkern -local setdir = nuts.setdir +local setdirection = nuts.setdirection local setshift = nuts.setshift local setwidth = nuts.setwidth ------ setheight = nuts.setheight ------ setdepth = nuts.setdepth +local setexpansion = nuts.setexpansion local slide_node_list = nuts.slide -- get rid of this, probably ok > 78.2 local find_tail = nuts.tail @@ -246,13 +290,14 @@ local replace_node = nuts.replace local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local is_zero_glue = nuts.is_zero_glue +local is_skipable = nuts.protrusion_skippable local nodepool = nuts.pool local nodecodes = nodes.nodecodes local kerncodes = nodes.kerncodes local glyphcodes = nodes.glyphcodes -local gluecodes = nodes.gluecodes +local leadercodes = nodes.leadercodes local margincodes = nodes.margincodes local disccodes = nodes.disccodes local mathcodes = nodes.mathcodes @@ -276,9 +321,9 @@ local marginkern_code = nodecodes.marginkern local dir_code = nodecodes.dir local boundary_code = nodecodes.boundary -local protrusion_code = boundarycodes.protrusion +local protrusionboundary_code = boundarycodes.protrusion -local leaders_code = gluecodes.leaders +local leaders_code = leadercodes.leaders local localpar_code = nodecodes.localpar @@ -287,17 +332,17 @@ local italickern_code = kerncodes.italiccorrection local fontkern_code = kerncodes.fontkern local accentkern_code = kerncodes.accentkern -local ligature_code = glyphcodes.ligature +local ligatureglyph_code = glyphcodes.ligature -local stretch_orders = nodes.fillcodes +local fillcodes = nodes.fillcodes local leftmargin_code = margincodes.left ----- rightmargin_code = margincodes.right -local automatic_disc_code = disccodes.automatic -local regular_disc_code = disccodes.regular -local first_disc_code = disccodes.first -local second_disc_code = disccodes.second +local automaticdisc_code = disccodes.automatic +local regulardisc_code = disccodes.regular +local firstdisc_code = disccodes.first +local seconddisc_code = disccodes.second local endmath_code = mathcodes.endmath @@ -323,7 +368,7 @@ local fit_decent_class = 2 -- fitness for all other lines local fit_tight_class = 3 -- fitness for lines shrinking 0.5 to 1.0 of their shrinkability local new_penalty = nodepool.penalty -local new_dir = nodepool.textdir +local new_direction = nodepool.direction local new_leftmarginkern = nodepool.leftmarginkern local new_rightmarginkern = nodepool.rightmarginkern local new_leftskip = nodepool.leftskip @@ -334,17 +379,6 @@ local new_temp = nodepool.temp local new_rule = nodepool.rule local new_hlist = nodepool.hlist -local is_rotated = nodes.is_rotated -local is_parallel = nodes.textdir_is_parallel -local is_opposite = nodes.textdir_is_opposite -local textdir_is_equal = nodes.textdir_is_equal -local pardir_is_equal = nodes.pardir_is_equal -local glyphdir_is_equal = nodes.glyphdir_is_equal - -local dir_pops = nodes.dir_is_pop -local dir_negations = nodes.dir_negation -local is_skipable = nuts.protrusion_skippable - -- helpers -- -- It makes more sense to move the somewhat messy dir state tracking @@ -359,22 +393,24 @@ end -- in the parbuilder. local function checked_line_dir(stack,current) - if not dir_pops[current] then + local direction, pop = getdirection(current) + if not pop then local n = stack.n + 1 stack.n = n stack[n] = current - return getdir(current) + return direction elseif n > 0 then local n = stack.n local dirnode = stack[n] dirstack.n = n - 1 - return getdir(dirnode) + direction = getdirection(dirnode) -- we could save it + return direction else report_parbuilders("warning: missing pop node (%a)",1) -- in line ... end end --- The next function checks a dir nodes in a list and appends the negations +-- The next function checks dir nodes in a list and appends the negations -- that are currently needed (some day LuaTeX will be more tolerant). We use -- the negations for the next line. @@ -382,10 +418,12 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop) local e = start local n = stack.n local h = nil + -- todo: traverse while start and start ~= stop do local id = getid(start) if id == dir_code then - if not dir_pops[getdir(start)] then -- weird, what is this # + local direction, pop = getdirection(start) + if not pop then n = n + 1 stack[n] = start elseif n > 0 then @@ -397,7 +435,7 @@ local function inject_dirs_at_end_of_line(stack,current,start,stop) start = getnext(start) end for i=n,1,-1 do - h, current = insert_node_after(current,current,new_dir(dir_negations[getdir(stack[i])])) + h, current = insert_node_after(current,current,new_direction(getdirection(stack[i]),true)) end stack.n = n return current @@ -406,7 +444,7 @@ end local function inject_dirs_at_begin_of_line(stack,current) local h = nil for i=stack.n,1,-1 do - h, current = insert_node_after(current,current,new_dir(stack[i])) + h, current = insert_node_after(current,current,new_direction(stack[i])) end stack.n = 0 return current @@ -507,9 +545,9 @@ end) local function kern_stretch_shrink(p,d) local left = getprev(p) if left then - local char = isglyph(left) + local char, font = isglyph(left) if char then - local data = expansions[getfont(left)][char] + local data = expansions[font][char] if data then local stretch = data.stretch local shrink = data.shrink @@ -630,8 +668,8 @@ local function find(head) -- do we really want to recurse into an hlist? head = getnext(head) end elseif id == boundary_code then - if getsubtype(head) == protrusion_code then - local v = getfield(head,"value") + if getsubtype(head) == protrusionboundary_code then + local v = getdata(head) if v == 1 or v == 3 then head = getnext(head) if head then @@ -654,19 +692,19 @@ end local function find_protchar_left(l) -- weird function local ln = getnext(l) - if ln and getid(ln) == hlist_code and not getlist(ln) and getfield(ln,"width") == 0 and getfield(ln,"height") == 0 and getfield(ln,"depth") == 0 then - l = getnext(l) - else -- if d then -- was always true - local id = getid(l) - while ln and not (id == glyph_code or id < math_code) do -- is there always a glyph? - l = ln - ln = getnext(l) - id = getid(ln) - end + if ln and getid(ln) == hlist_code and not getlist(ln) then + local w, h, d = getwhd(ln) + if w == 0 and h == 0 and d == 0 then + l = getnext(l) + return find(l) or l + end + end -- if d then -- was always true + local id = getid(l) + while ln and not (id == glyph_code or id < math_code) do -- is there always a glyph? + l = ln + ln = getnext(l) + id = getid(ln) end - -- if getid(l) == glyph_code then - -- return l - -- end return find(l) or l end @@ -684,8 +722,8 @@ local function find(head,tail) tail = getprev(tail) end elseif id == boundary_code then - if getsubtype(head) == protrusion_code then - local v = getfield(tail,"value") + if getsubtype(head) == protrusionboundary_code then + local v = getdata(tail) if v == 2 or v == 3 then tail = getprev(tail) if tail then @@ -711,8 +749,8 @@ local function find_protchar_right(l,r) end local function left_pw(p) - local font = getfont(p) - local prot = chardata[font][getchar(p)].left_protruding + local char, font = isglyph(p) + local prot = chardata[font][char].left_protruding if not prot or prot == 0 then return 0 end @@ -720,8 +758,8 @@ local function left_pw(p) end local function right_pw(p) - local font = getfont(p) - local prot = chardata[font][getchar(p)].right_protruding + local char, font = isglyph(p) + local prot = chardata[font][char].right_protruding if not prot or prot == 0 then return 0 end @@ -748,13 +786,13 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw local char, id = isglyph(s) if char then local wd, ht, dp = getwhd(s) - if is_rotated[line_break_dir] then -- can be shared + if is_rotated(line_break_dir) then size = size + ht + dp else size = size + wd end if checked_expansion then - local data = checked_expansion[getfont(s)] + local data = checked_expansion[id] -- id == font if data then data = data[char] if data then @@ -765,7 +803,7 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw end elseif id == hlist_code or id == vlist_code then local wd, ht, dp = getwhd(s) - if is_parallel[getdir(s)][line_break_dir] then + if textdir_parallel(getdirection(s),line_break_dir) then size = size + wd else size = size + ht + dp @@ -796,1709 +834,1712 @@ local function add_to_width(line_break_dir,checked_expansion,s) -- split into tw return size, adjust_stretch, adjust_shrink end -local function compute_break_width(par,break_type,p) -- split in two - local break_width = par.break_width - if break_type > unhyphenated_code then - local disc_width = par.disc_width - local checked_expansion = par.checked_expansion - local line_break_dir = par.line_break_dir - local break_size = break_width.size + disc_width.size - local break_adjust_stretch = break_width.adjust_stretch + disc_width.adjust_stretch - local break_adjust_shrink = break_width.adjust_shrink + disc_width.adjust_shrink - local pre, post, replace = getdisc(p) - if replace then - local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace) - break_size = break_size - size - break_adjust_stretch = break_adjust_stretch - adjust_stretch - break_adjust_shrink = break_adjust_shrink - adjust_shrink - end - if post then - local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,post) - break_size = break_size + size - break_adjust_stretch = break_adjust_stretch + adjust_stretch - break_adjust_shrink = break_adjust_shrink + adjust_shrink - end - break_width.size = break_size - break_width.adjust_stretch = break_adjust_stretch - break_width.adjust_shrink = break_adjust_shrink - if not post then - p = getnext(p) - else - return - end - end - while p do -- skip spacing etc - local id = getid(p) - if id == glyph_code then - return -- happens often - elseif id == glue_code then - local wd, stretch, shrink, stretch_order = getglue(p) - local order = stretch_orders[stretch_order] - break_width.size = break_width.size - wd - break_width[order] = break_width[order] - stretch - break_width.shrink = break_width.shrink - shrink - elseif id == penalty_code then - -- do nothing - elseif id == kern_code then - local s = getsubtype(p) - if s == userkern_code or s == italickern_code then - break_width.size = break_width.size - getkern(p) +-- We can actually make par local to this module as we never break inside a break call and that way the +-- array is reused. At some point the information will be part of the paragraph spec as passed. + +local hztolerance = 2500 +local hzwarned = false + +do + + local function compute_break_width(par,break_type,p) -- split in two + local break_width = par.break_width + if break_type > unhyphenated_code then + local disc_width = par.disc_width + local checked_expansion = par.checked_expansion + local line_break_dir = par.line_break_dir + local break_size = break_width.size + disc_width.size + local break_adjust_stretch = break_width.adjust_stretch + disc_width.adjust_stretch + local break_adjust_shrink = break_width.adjust_shrink + disc_width.adjust_shrink + local pre, post, replace = getdisc(p) + if replace then + local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace) + break_size = break_size - size + break_adjust_stretch = break_adjust_stretch - adjust_stretch + break_adjust_shrink = break_adjust_shrink - adjust_shrink + end + if post then + local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,post) + break_size = break_size + size + break_adjust_stretch = break_adjust_stretch + adjust_stretch + break_adjust_shrink = break_adjust_shrink + adjust_shrink + end + break_width.size = break_size + break_width.adjust_stretch = break_adjust_stretch + break_width.adjust_shrink = break_adjust_shrink + if not post then + p = getnext(p) else return end - elseif id == math_code then - break_width.size = break_width.size - getkern(p) -- surround - -- new in luatex - local wd, stretch, shrink, stretch_order = getglue(p) - local order = stretch_orders[stretch_order] - break_width.size = break_width.size - wd - break_width[order] = break_width[order] - stretch - break_width.shrink = break_width.shrink - shrink - else - return end - p = getnext(p) - end -end - -local function append_to_vlist(par, b) - local prev_depth = par.prev_depth - local head_field = par.head_field - local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail - local is_hlist = getid(b) == hlist_code - -- if prev_depth > par.ignored_dimen then - if prev_depth > ignore_depth then - if is_hlist then - local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip) - local delta = width - prev_depth - getheight(b) -- deficiency of space between baselines - local skip = nil - if delta < par.line_skip_limit then - width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip) - skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order) - else - skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order) - end - if head_field then - setlink(tail_field,skip) + while p do -- skip spacing etc + local id = getid(p) + if id == glyph_code then + return -- happens often + elseif id == glue_code then + local wd, stretch, shrink, stretch_order = getglue(p) + local order = fillcodes[stretch_order] + break_width.size = break_width.size - wd + break_width[order] = break_width[order] - stretch + break_width.shrink = break_width.shrink - shrink + elseif id == penalty_code then + -- do nothing + elseif id == kern_code then + local s = getsubtype(p) + if s == userkern_code or s == italickern_code then + break_width.size = break_width.size - getkern(p) + else + return + end + elseif id == math_code then + break_width.size = break_width.size - getkern(p) -- surround + -- new in luatex + local wd, stretch, shrink, stretch_order = getglue(p) + local order = fillcodes[stretch_order] + break_width.size = break_width.size - wd + break_width[order] = break_width[order] - stretch + break_width.shrink = break_width.shrink - shrink else - par.head_field = skip - head_field = skip + return end - tail_field = skip + p = getnext(p) end end - if head_field then - setlink(tail_field,b) - else - par.head_field = b - end - if is_hlist then - local pd = getdepth(b) - par.prev_depth = pd - texnest[texnest.ptr].prevdepth = pd - end -end -local function append_list(par, b) - local head_field = par.head_field - if head_field then - local n = slide_node_list(head_field) -- todo: find_tail - setlink(n,b) - else - par.head_field = b + local function append_to_vlist(par, b) + local prev_depth = par.prev_depth + local head_field = par.head_field + local tail_field = head_field and slide_node_list(head_field) -- todo: find_tail + local is_hlist = getid(b) == hlist_code + -- if prev_depth > par.ignored_dimen then + if prev_depth > ignore_depth then + if is_hlist then + local width, stretch, shrink, stretch_order, shrink_order = getglue(par.baseline_skip) + local delta = width - prev_depth - getheight(b) -- deficiency of space between baselines + local skip = nil + if delta < par.line_skip_limit then + width, stretch, shrink, stretch_order, shrink_order = getglue(par.lineskip) + skip = new_lineskip(width, stretch, shrink, stretch_order, shrink_order) + else + skip = new_baselineskip(delta, stretch, shrink, stretch_order, shrink_order) + end + if head_field then + setlink(tail_field,skip) + else + par.head_field = skip + head_field = skip + end + tail_field = skip + end + end + if head_field then + setlink(tail_field,b) + else + par.head_field = b + end + if is_hlist then + local pd = getdepth(b) + par.prev_depth = pd + texnest[texnest.ptr].prevdepth = pd + end end -end - --- We can actually make par local to this module as we never break inside a break call and that way the --- array is reused. At some point the information will be part of the paragraph spec as passed. - -local hztolerance = 2500 -local hzwarned = false - -local function used_skip(s) - return s and not is_zero_glue(s) and s -end -local function initialize_line_break(head,display) - - local hang_indent = tex.hangindent or 0 - local hsize = tex.hsize or 0 - local hang_after = tex.hangafter or 0 - local par_shape_ptr = tex.parshape - local left_skip = tonut(tex.leftskip) -- nodes - local right_skip = tonut(tex.rightskip) -- nodes - local pretolerance = tex.pretolerance - local tolerance = tex.tolerance - local adjust_spacing = tex.adjustspacing - local protrude_chars = tex.protrudechars - local last_line_fit = tex.lastlinefit - - local newhead = new_temp() - setnext(newhead,head) - - local adjust_spacing_status = adjust_spacing > 1 and -1 or 0 - - -- metatables - - local par = { - head = newhead, - head_field = nil, - display = display, - font_in_short_display = 0, - no_shrink_error_yet = true, -- have we complained about infinite shrinkage? - second_pass = false, -- is this our second attempt to break this paragraph? - final_pass = false, -- is this our final attempt to break this paragraph? - threshold = 0, -- maximum badness on feasible lines - - passive = nil, -- most recent node on passive list - printed_node = head, -- most recent node that has been printed - pass_number = 0, -- the number of passive nodes allocated on this pass - auto_breaking = 0, -- make auto_breaking accessible out of line_break - - active_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 }, - break_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 }, - disc_width = { size = 0, adjust_stretch = 0, adjust_shrink = 0 }, - fill_width = { stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 }, - background = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 }, - - hang_indent = hang_indent, - hsize = hsize, - hang_after = hang_after, - par_shape_ptr = par_shape_ptr, - left_skip = left_skip, - right_skip = right_skip, - pretolerance = pretolerance, - tolerance = tolerance, - - protrude_chars = protrude_chars, - adjust_spacing = adjust_spacing, - max_stretch_ratio = adjust_spacing_status, - max_shrink_ratio = adjust_spacing_status, - cur_font_step = adjust_spacing_status, - checked_expansion = false, - tracing_paragraphs = tex.tracingparagraphs > 0, - - emergency_stretch = tex.emergencystretch or 0, - looseness = tex.looseness or 0, - line_penalty = tex.linepenalty or 0, - hyphen_penalty = tex.hyphenpenalty or 0, - broken_penalty = tex.brokenpenalty or 0, - inter_line_penalty = tex.interlinepenalty or 0, - club_penalty = tex.clubpenalty or 0, - widow_penalty = tex.widowpenalty or 0, - display_widow_penalty = tex.displaywidowpenalty or 0, - ex_hyphen_penalty = tex.exhyphenpenalty or 0, - - adj_demerits = tex.adjdemerits or 0, - double_hyphen_demerits = tex.doublehyphendemerits or 0, - final_hyphen_demerits = tex.finalhyphendemerits or 0, - - first_line = 0, -- tex.nest[tex.nest.ptr].modeline, -- 0, -- cur_list.pg_field - - -- each_line_height = tex.pdfeachlineheight or 0, -- this will go away - -- each_line_depth = tex.pdfeachlinedepth or 0, -- this will go away - -- first_line_height = tex.pdffirstlineheight or 0, -- this will go away - -- last_line_depth = tex.pdflastlinedepth or 0, -- this will go away - - -- ignored_dimen = tex.pdfignoreddimen or 0, - - baseline_skip = tonut(tex.baselineskip), - lineskip = tonut(tex.lineskip), - line_skip_limit = tex.lineskiplimit, - - prev_depth = texnest[texnest.ptr].prevdepth, - - final_par_glue = slide_node_list(head), -- todo: we know tail already, slow - - par_break_dir = tex.pardir, - line_break_dir = tex.pardir, - - internal_pen_inter = 0, -- running localinterlinepenalty - internal_pen_broken = 0, -- running localbrokenpenalty - internal_left_box = nil, -- running localleftbox - internal_left_box_width = 0, -- running localleftbox width - init_internal_left_box = nil, -- running localleftbox - init_internal_left_box_width = 0, -- running localleftbox width - internal_right_box = nil, -- running localrightbox - internal_right_box_width = 0, -- running localrightbox width - - best_place = { }, -- how to achieve minimal_demerits - best_pl_line = { }, -- corresponding line number - easy_line = 0, -- line numbers easy_line are equivalent in break nodes - last_special_line = 0, -- line numbers last_special_line all have the same width - first_width = 0, -- the width of all lines last_special_line, if no parshape has been specified - second_width = 0, -- the width of all lines last_special_line - first_indent = 0, -- left margin to go with first_width - second_indent = 0, -- left margin to go with second_width - - best_bet = nil, -- use this passive node and its predecessors - fewest_demerits = 0, -- the demerits associated with best_bet - best_line = 0, -- line number following the last line of the new paragraph - line_diff = 0, -- the difference between the current line number and the optimum best_line - - -- not yet used - - best_pl_short = { }, -- shortfall corresponding to minimal_demerits - best_pl_glue = { }, -- corresponding glue stretch or shrink - do_last_line_fit = false, - last_line_fit = last_line_fit, - - minimum_demerits = awful_badness, - - minimal_demerits = { - - [fit_very_loose_class] = awful_badness, - [fit_loose_class] = awful_badness, - [fit_decent_class] = awful_badness, - [fit_tight_class] = awful_badness, - - }, - - prev_char_p = nil, - - statistics = { - - noflines = 0, - nofprotrudedlines = 0, - nofadjustedlines = 0, - - }, - - -- -- just a thought ... parshape functions ... it would be nice to - -- -- also store the height so far (probably not too hard) although - -- -- in most cases we work on grids in such cases - -- - -- adapt_width = function(par,line) - -- -- carry attribute, so that we can accumulate - -- local left = 655360 * (line - 1) - -- local right = 655360 * (line - 1) - -- return left, right - -- end + local function append_list(par, b) + local head_field = par.head_field + if head_field then + local n = slide_node_list(head_field) -- todo: find_tail + setlink(n,b) + else + par.head_field = b + end + end + + local function used_skip(s) + return s and not is_zero_glue(s) and s + end + + local function initialize_line_break(head,display) + + local hang_indent = tex.hangindent or 0 + local hsize = tex.hsize or 0 + local hang_after = tex.hangafter or 0 + local par_shape_ptr = tex.parshape + local left_skip = tonut(tex.leftskip) -- nodes + local right_skip = tonut(tex.rightskip) -- nodes + local pretolerance = tex.pretolerance + local tolerance = tex.tolerance + local adjust_spacing = tex.adjustspacing + local protrude_chars = tex.protrudechars + local last_line_fit = tex.lastlinefit + local par_dir = tex.pardirection + + local newhead = new_temp() + setnext(newhead,head) + + local adjust_spacing_status = adjust_spacing > 1 and -1 or 0 + + -- metatables + + local par = { + head = newhead, + head_field = nil, + display = display, + font_in_short_display = 0, + no_shrink_error_yet = true, -- have we complained about infinite shrinkage? + second_pass = false, -- is this our second attempt to break this paragraph? + final_pass = false, -- is this our final attempt to break this paragraph? + threshold = 0, -- maximum badness on feasible lines + + passive = nil, -- most recent node on passive list + printed_node = head, -- most recent node that has been printed + pass_number = 0, -- the number of passive nodes allocated on this pass + auto_breaking = 0, -- make auto_breaking accessible out of line_break + + active_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 }, + break_width = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0, adjust_stretch = 0, adjust_shrink = 0 }, + disc_width = { size = 0, adjust_stretch = 0, adjust_shrink = 0 }, + fill_width = { stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 }, + background = { size = 0, stretch = 0, fi = 0, fil = 0, fill = 0, filll = 0, shrink = 0 }, + + hang_indent = hang_indent, + hsize = hsize, + hang_after = hang_after, + par_shape_ptr = par_shape_ptr, + left_skip = left_skip, + right_skip = right_skip, + pretolerance = pretolerance, + tolerance = tolerance, + + protrude_chars = protrude_chars, + adjust_spacing = adjust_spacing, + max_stretch_ratio = adjust_spacing_status, + max_shrink_ratio = adjust_spacing_status, + cur_font_step = adjust_spacing_status, + checked_expansion = false, + tracing_paragraphs = tex.tracingparagraphs > 0, + + emergency_stretch = tex.emergencystretch or 0, + looseness = tex.looseness or 0, + line_penalty = tex.linepenalty or 0, + hyphen_penalty = tex.hyphenpenalty or 0, + broken_penalty = tex.brokenpenalty or 0, + inter_line_penalty = tex.interlinepenalty or 0, + club_penalty = tex.clubpenalty or 0, + widow_penalty = tex.widowpenalty or 0, + display_widow_penalty = tex.displaywidowpenalty or 0, + ex_hyphen_penalty = tex.exhyphenpenalty or 0, + + adj_demerits = tex.adjdemerits or 0, + double_hyphen_demerits = tex.doublehyphendemerits or 0, + final_hyphen_demerits = tex.finalhyphendemerits or 0, + + first_line = 0, -- texnest[texnest.ptr].modeline, -- 0, -- cur_list.pg_field + + -- each_line_height = tex.pdfeachlineheight or 0, -- this will go away + -- each_line_depth = tex.pdfeachlinedepth or 0, -- this will go away + -- first_line_height = tex.pdffirstlineheight or 0, -- this will go away + -- last_line_depth = tex.pdflastlinedepth or 0, -- this will go away + + -- ignored_dimen = tex.pdfignoreddimen or 0, + + baseline_skip = tonut(tex.baselineskip), + lineskip = tonut(tex.lineskip), + line_skip_limit = tex.lineskiplimit, + + prev_depth = texnest[texnest.ptr].prevdepth, + + final_par_glue = slide_node_list(head), -- todo: we know tail already, slow + + par_break_dir = par_dir, + line_break_dir = par_dir, + + internal_pen_inter = 0, -- running localinterlinepenalty + internal_pen_broken = 0, -- running localbrokenpenalty + internal_left_box = nil, -- running localleftbox + internal_left_box_width = 0, -- running localleftbox width + init_internal_left_box = nil, -- running localleftbox + init_internal_left_box_width = 0, -- running localleftbox width + internal_right_box = nil, -- running localrightbox + internal_right_box_width = 0, -- running localrightbox width + + best_place = { }, -- how to achieve minimal_demerits + best_pl_line = { }, -- corresponding line number + easy_line = 0, -- line numbers easy_line are equivalent in break nodes + last_special_line = 0, -- line numbers last_special_line all have the same width + first_width = 0, -- the width of all lines last_special_line, if no parshape has been specified + second_width = 0, -- the width of all lines last_special_line + first_indent = 0, -- left margin to go with first_width + second_indent = 0, -- left margin to go with second_width + + best_bet = nil, -- use this passive node and its predecessors + fewest_demerits = 0, -- the demerits associated with best_bet + best_line = 0, -- line number following the last line of the new paragraph + line_diff = 0, -- the difference between the current line number and the optimum best_line + + -- not yet used + + best_pl_short = { }, -- shortfall corresponding to minimal_demerits + best_pl_glue = { }, -- corresponding glue stretch or shrink + do_last_line_fit = false, + last_line_fit = last_line_fit, + + minimum_demerits = awful_badness, + + minimal_demerits = { + + [fit_very_loose_class] = awful_badness, + [fit_loose_class] = awful_badness, + [fit_decent_class] = awful_badness, + [fit_tight_class] = awful_badness, + + }, + + prev_char_p = nil, + + statistics = { + + noflines = 0, + nofprotrudedlines = 0, + nofadjustedlines = 0, + + }, + + -- -- just a thought ... parshape functions ... it would be nice to + -- -- also store the height so far (probably not too hard) although + -- -- in most cases we work on grids in such cases + -- + -- adapt_width = function(par,line) + -- -- carry attribute, so that we can accumulate + -- local left = 655360 * (line - 1) + -- local right = 655360 * (line - 1) + -- return left, right + -- end - } + } - -- optimizers + -- optimizers - par.used_left_skip = used_skip(par.left_skip) - par.used_right_skip = used_skip(par.right_skip) + par.used_left_skip = used_skip(par.left_skip) + par.used_right_skip = used_skip(par.right_skip) - -- so far + -- so far - if adjust_spacing > 1 then - local checked_expansion = { par = par } - setmetatableindex(checked_expansion,check_expand_pars) - par.checked_expansion = checked_expansion + if adjust_spacing > 1 then + local checked_expansion = { par = par } + setmetatableindex(checked_expansion,check_expand_pars) + par.checked_expansion = checked_expansion - if par.tolerance < hztolerance then - if not hzwarned then - report_parbuilders("setting tolerance to %a for hz",hztolerance) - hzwarned = true + if par.tolerance < hztolerance then + if not hzwarned then + report_parbuilders("setting tolerance to %a for hz",hztolerance) + hzwarned = true + end + par.tolerance = hztolerance end - par.tolerance = hztolerance - end - expand_kerns = expand_kerns_mode or (adjust_spacing == 2) + expand_kerns = expand_kerns_mode or (adjust_spacing == 2) - end + end - -- we need par for the error message + -- we need par for the error message - local background = par.background + local background = par.background - local l = check_shrinkage(par,left_skip) - local r = check_shrinkage(par,right_skip) + local l = check_shrinkage(par,left_skip) + local r = check_shrinkage(par,right_skip) - local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = getglue(l) - local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = getglue(r) + local lwidth, lstretch, lshrink, lstretch_order, lshrink_order = getglue(l) + local rwidth, rstretch, rshrink, rstretch_order, rshrink_order = getglue(r) - local l_order = stretch_orders[lstretch_order] - local r_order = stretch_orders[rstretch_order] + local l_order = fillcodes[lstretch_order] + local r_order = fillcodes[rstretch_order] - background.size = lwidth + rwidth - background.shrink = lshrink + rshrink - background[l_order] = lstretch - background[r_order] = rstretch + background[r_order] + background.size = lwidth + rwidth + background.shrink = lshrink + rshrink + background[l_order] = lstretch + background[r_order] = rstretch + background[r_order] - -- this will move up so that we can assign the whole par table + -- this will move up so that we can assign the whole par table - if not par_shape_ptr then - if hang_indent == 0 then - par.second_width = hsize - par.second_indent = 0 - else - local abs_hang_after = hang_after >0 and hang_after or -hang_after - local abs_hang_indent = hang_indent>0 and hang_indent or -hang_indent - par.last_special_line = abs_hang_after - if hang_after < 0 then - par.first_width = hsize - abs_hang_indent - if hang_indent >= 0 then - par.first_indent = hang_indent - else - par.first_indent = 0 - end + if not par_shape_ptr then + if hang_indent == 0 then par.second_width = hsize par.second_indent = 0 else - par.first_width = hsize - par.first_indent = 0 - par.second_width = hsize - abs_hang_indent - if hang_indent >= 0 then - par.second_indent = hang_indent - else + local abs_hang_after = hang_after >0 and hang_after or -hang_after + local abs_hang_indent = hang_indent>0 and hang_indent or -hang_indent + par.last_special_line = abs_hang_after + if hang_after < 0 then + par.first_width = hsize - abs_hang_indent + if hang_indent >= 0 then + par.first_indent = hang_indent + else + par.first_indent = 0 + end + par.second_width = hsize par.second_indent = 0 + else + par.first_width = hsize + par.first_indent = 0 + par.second_width = hsize - abs_hang_indent + if hang_indent >= 0 then + par.second_indent = hang_indent + else + par.second_indent = 0 + end end end + else + local last_special_line = #par_shape_ptr + par.last_special_line = last_special_line + local parshape = par_shape_ptr[last_special_line] + par.second_width = parshape[2] + par.second_indent = parshape[1] end - else - local last_special_line = #par_shape_ptr - par.last_special_line = last_special_line - local parshape = par_shape_ptr[last_special_line] - par.second_width = parshape[2] - par.second_indent = parshape[1] - end - if par.looseness == 0 then - par.easy_line = par.last_special_line - else - par.easy_line = max_halfword - end + if par.looseness == 0 then + par.easy_line = par.last_special_line + else + par.easy_line = max_halfword + end - if pretolerance >= 0 then - par.threshold = pretolerance - par.second_pass = false - par.final_pass = false - else - par.threshold = tolerance - par.second_pass = true - par.final_pass = par.emergency_stretch <= 0 - if trace_basic then - if par.final_pass then - report_parbuilders("enabling second and final pass") - else - report_parbuilders("enabling second pass") + if pretolerance >= 0 then + par.threshold = pretolerance + par.second_pass = false + par.final_pass = false + else + par.threshold = tolerance + par.second_pass = true + par.final_pass = par.emergency_stretch <= 0 + if trace_basic then + if par.final_pass then + report_parbuilders("enabling second and final pass") + else + report_parbuilders("enabling second pass") + end end end - end - if last_line_fit > 0 then - local final_par_glue = par.final_par_glue - local stretch = getfield(final_par_glue,"stretch") - local stretch_order = getfield(final_par_glue,"stretch_order") - if stretch > 0 and stretch_order > 0 and background.fi == 0 and background.fil == 0 and background.fill == 0 and background.filll == 0 then - par.do_last_line_fit = true - local si = stretch_orders[stretch_order] - if trace_lastlinefit or trace_basic then - report_parbuilders("enabling last line fit, stretch order %a set to %a, linefit is %a",si,stretch,last_line_fit) + if last_line_fit > 0 then + local final_par_glue = par.final_par_glue + local stretch = getfield(final_par_glue,"stretch") + local stretch_order = getfield(final_par_glue,"stretch_order") + if stretch > 0 and stretch_order > 0 and background.fi == 0 and background.fil == 0 and background.fill == 0 and background.filll == 0 then + par.do_last_line_fit = true + local si = fillcodes[stretch_order] + if trace_lastlinefit or trace_basic then + report_parbuilders("enabling last line fit, stretch order %a set to %a, linefit is %a",si,stretch,last_line_fit) + end + par.fill_width[si] = stretch end - par.fill_width[si] = stretch end - end - return par -end + return par + end --- there are still all kind of artefacts in here (a side effect I guess of pdftex, --- etex, omega and other extensions that got obscured by patching) + -- there are still all kind of artefacts in here (a side effect I guess of pdftex, + -- etex, omega and other extensions that got obscured by patching) -local function post_line_break(par) + local function post_line_break(par) - local prevgraf = texnest[texnest.ptr].prevgraf - local current_line = prevgraf + 1 -- the current line number being justified + local prevgraf = texnest[texnest.ptr].prevgraf + local current_line = prevgraf + 1 -- the current line number being justified - local adjust_spacing = par.adjust_spacing - local protrude_chars = par.protrude_chars - local statistics = par.statistics + local adjust_spacing = par.adjust_spacing + local protrude_chars = par.protrude_chars + local statistics = par.statistics - local stack = new_dir_stack() + local stack = new_dir_stack() - local leftskip = par.used_left_skip -- used or normal ? - local rightskip = par.right_skip - local parshape = par.par_shape_ptr - ----- ignored_dimen = par.ignored_dimen + local leftskip = par.used_left_skip -- used or normal ? + local rightskip = par.right_skip + local parshape = par.par_shape_ptr + ----- ignored_dimen = par.ignored_dimen - local adapt_width = par.adapt_width + local adapt_width = par.adapt_width - -- reverse the links of the relevant passive nodes, goto first breakpoint + -- reverse the links of the relevant passive nodes, goto first breakpoint - local current_break = nil + local current_break = nil - local break_node = par.best_bet.break_node - repeat - local first_break = break_node - break_node = break_node.prev_break - first_break.prev_break = current_break - current_break = first_break - until not break_node + local break_node = par.best_bet.break_node + repeat + local first_break = break_node + break_node = break_node.prev_break + first_break.prev_break = current_break + current_break = first_break + until not break_node - local head = par.head + local head = par.head - -- maybe : each_... + -- maybe : each_... - while current_break do + while current_break do - inject_dirs_at_begin_of_line(stack,head) + inject_dirs_at_begin_of_line(stack,head) - local disc_break = false - local post_disc_break = false - local glue_break = false + local disc_break = false + local post_disc_break = false + local glue_break = false - local lineend = nil -- q lineend refers to the last node of the line (and paragraph) - local lastnode = current_break.cur_break -- r lastnode refers to the node after which the dir nodes should be closed + local lineend = nil -- lineend : the last node of the line (and paragraph) + local lastnode = current_break.cur_break -- lastnode: the node after which the dir nodes should be closed - if not lastnode then - -- only at the end - lastnode = slide_node_list(head) -- todo: find_tail - if lastnode == par.final_par_glue then - lineend = lastnode - lastnode = getprev(lastnode) - end - else -- todo: use insert_list_after - local id = getid(lastnode) - if id == glue_code then - -- lastnode is normal skip - lastnode = replace_node(lastnode,new_rightskip(rightskip)) - glue_break = true - lineend = lastnode - lastnode = getprev(lastnode) - elseif id == disc_code then - local prevlast = getprev(lastnode) - local nextlast = getnext(lastnode) - local subtype = getsubtype(lastnode) - local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode,true) - if subtype == second_disc_code then - if not (getid(prevlast) == disc_code and getsubtype(prevlast) == first_disc_code) then - report_parbuilders('unsupported disc at location %a',3) - end - if pre then - flush_node_list(pre) - pre = nil -- signal + if not lastnode then + -- only at the end + lastnode = slide_node_list(head) -- todo: find_tail + if lastnode == par.final_par_glue then + lineend = lastnode + lastnode = getprev(lastnode) + end + else -- todo: use insert_list_after + local id = getid(lastnode) + if id == glue_code then + -- lastnode is normal skip + lastnode = replace_node(lastnode,new_rightskip(rightskip)) + glue_break = true + lineend = lastnode + lastnode = getprev(lastnode) + elseif id == disc_code then + local prevlast = getprev(lastnode) + local nextlast = getnext(lastnode) + local subtype = getsubtype(lastnode) + local pre, post, replace, pretail, posttail, replacetail = getdisc(lastnode,true) + if subtype == seconddisc_code then + if not (getid(prevlast) == disc_code and getsubtype(prevlast) == firstdisc_code) then + report_parbuilders('unsupported disc at location %a',3) + end + if pre then + flush_node_list(pre) + pre = nil -- signal + end + if replace then + setlink(prevlast,replace) + setlink(replacetail,lastnode) + replace = nil -- signal + end + setdisc(lastnode,pre,post,replace) + local pre, post, replace = getdisc(prevlast) + if pre then + flush_node_list(pre) + end + if replace then + flush_node_list(replace) + end + if post then + flush_node_list(post) + end + setdisc(prevlast) -- nil,nil,nil + elseif subtype == firstdisc_code then + -- what is v ... next probably + if not (getid(v) == disc_code and getsubtype(v) == seconddisc_code) then + report_parbuilders('unsupported disc at location %a',4) + end + setsubtype(nextlast,regulardisc_code) + setfield(nextlast,"replace",post) + setfield(lastnode,"post") -- nil end if replace then - setlink(prevlast,replace) - setlink(replacetail,lastnode) - replace = nil -- signal + flush_node_list(replace) end - setdisc(lastnode,pre,post,replace) - local pre, post, replace = getdisc(prevlast) if pre then - flush_node_list(pre) - end - if replace then - flush_node_list(replace) + setlink(prevlast,pre) + setlink(pretail,lastnode) end if post then - flush_node_list(post) - end - setdisc(prevlast) -- nil,nil,nil - elseif subtype == first_disc_code then - -- what is v ... next probably - if not (getid(v) == disc_code and getsubtype(v) == second_disc_code) then - report_parbuilders('unsupported disc at location %a',4) + setlink(lastnode,post) + setlink(posttail,nextlast) + post_disc_break = true end - setsubtype(nextlast,regular_disc_code) - setfield(nextlast,"replace",post) - setfield(lastnode,"post") -- nil - end - if replace then - flush_node_list(replace) + setdisc(lastnode) -- nil, nil, nil + disc_break = true + elseif id == kern_code then + setkern(lastnode,0) + elseif getid(lastnode) == math_code then + setkern(lastnode,0) -- surround + -- new in luatex + setglue(lastnode) -- zeros end - if pre then - setlink(prevlast,pre) - setlink(pretail,lastnode) + end + lastnode = inject_dirs_at_end_of_line(stack,lastnode,getnext(head),current_break.cur_break) + local rightbox = current_break.passive_right_box + if rightbox then + lastnode = insert_node_after(lastnode,lastnode,copy_node(rightbox)) + end + if not lineend then + lineend = lastnode + end + if lineend and lineend ~= head and protrude_chars > 0 then + local id = getid(lineend) + local c = (disc_break and (id == glyph_code or id ~= disc_code) and lineend) or getprev(lineend) + local p = find_protchar_right(getnext(head),c) + if p and getid(p) == glyph_code then + local w, last_rightmost_char = right_pw(p) + if last_rightmost_char and w ~= 0 then + -- so we inherit attributes, lineend is new pseudo head + lineend, c = insert_node_after(lineend,c,new_rightmarginkern(copy_node(last_rightmost_char),-w)) + end end - if post then - setlink(lastnode,post) - setlink(posttail,nextlast) - post_disc_break = true + end + -- we finish the line + local r = getnext(lineend) + setnext(lineend) + if not glue_break then + if rightskip then + insert_node_after(lineend,lineend,new_rightskip(right_skip)) -- lineend moves on as pseudo head end - setdisc(lastnode) -- nil, nil, nil - disc_break = true - elseif id == kern_code then - setkern(lastnode,0) - elseif getid(lastnode) == math_code then - setkern(lastnode,0) -- surround - -- new in luatex - setglue(lastnode) -- zeros end - end - lastnode = inject_dirs_at_end_of_line(stack,lastnode,getnext(head),current_break.cur_break) - local rightbox = current_break.passive_right_box - if rightbox then - lastnode = insert_node_after(lastnode,lastnode,copy_node(rightbox)) - end - if not lineend then - lineend = lastnode - end - if lineend and lineend ~= head and protrude_chars > 0 then - local id = getid(lineend) - local c = (disc_break and (id == glyph_code or id ~= disc_code) and lineend) or getprev(lineend) - local p = find_protchar_right(getnext(head),c) - if p and getid(p) == glyph_code then - local w, last_rightmost_char = right_pw(p) - if last_rightmost_char and w ~= 0 then - -- so we inherit attributes, lineend is new pseudo head - lineend, c = insert_node_after(lineend,c,new_rightmarginkern(copy_node(last_rightmost_char),-w)) + -- each time ? + local q = getnext(head) + setlink(head,r) + -- insert leftbox (if needed after parindent) + local leftbox = current_break.passive_left_box + if leftbox then + local first = getnext(q) + if first and current_line == (par.first_line + 1) and getid(first) == hlist_code and not getlist(first) then + insert_node_after(q,q,copy_node(leftbox)) + else + q = insert_node_before(q,q,copy_node(leftbox)) end end - end - -- we finish the line - local r = getnext(lineend) - setnext(lineend) - if not glue_break then - if rightskip then - insert_node_after(lineend,lineend,new_rightskip(right_skip)) -- lineend moves on as pseudo head + if protrude_chars > 0 then + local p = find_protchar_left(q) + if p and getid(p) == glyph_code then + local w, last_leftmost_char = left_pw(p) + if last_leftmost_char and w ~= 0 then + -- so we inherit attributes, q is pseudo head and moves back + q = insert_node_before(q,q,new_leftmarginkern(copy_node(last_leftmost_char),-w)) + end + end end - end - -- each time ? - local q = getnext(head) - setlink(head,r) - -- insert leftbox (if needed after parindent) - local leftbox = current_break.passive_left_box - if leftbox then - local first = getnext(q) - if first and current_line == (par.first_line + 1) and getid(first) == hlist_code and not getlist(first) then - insert_node_after(q,q,copy_node(leftbox)) + if leftskip then + q = insert_node_before(q,q,new_leftskip(leftskip)) + end + local cur_width, cur_indent + if current_line > par.last_special_line then + cur_indent = par.second_indent + cur_width = par.second_width + elseif parshape then + local shape = parshape[current_line] + cur_indent = shape[1] + cur_width = shape[2] else - q = insert_node_before(q,q,copy_node(leftbox)) - end - end - if protrude_chars > 0 then - local p = find_protchar_left(q) - if p and getid(p) == glyph_code then - local w, last_leftmost_char = left_pw(p) - if last_leftmost_char and w ~= 0 then - -- so we inherit attributes, q is pseudo head and moves back - q = insert_node_before(q,q,new_leftmarginkern(copy_node(last_leftmost_char),-w)) - end + cur_indent = par.first_indent + cur_width = par.first_width end - end - if leftskip then - q = insert_node_before(q,q,new_leftskip(leftskip)) - end - local cur_width, cur_indent - if current_line > par.last_special_line then - cur_indent = par.second_indent - cur_width = par.second_width - elseif parshape then - local shape = parshape[current_line] - cur_indent = shape[1] - cur_width = shape[2] - else - cur_indent = par.first_indent - cur_width = par.first_width - end - if adapt_width then -- extension - local l, r = adapt_width(par,current_line) - cur_indent = cur_indent + l - cur_width = cur_width - l - r - end + if adapt_width then -- extension + local l, r = adapt_width(par,current_line) + cur_indent = cur_indent + l + cur_width = cur_width - l - r + end - statistics.noflines = statistics.noflines + 1 - local finished_line = nil - if adjust_spacing > 0 then - statistics.nofadjustedlines = statistics.nofadjustedlines + 1 - finished_line = xpack_nodes(q,cur_width,"cal_expand_ratio",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis) - else - finished_line = xpack_nodes(q,cur_width,"exactly",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis) - end - if protrude_chars > 0 then - statistics.nofprotrudedlines = statistics.nofprotrudedlines + 1 - end - -- wrong: - local adjust_head = texlists.adjust_head - local pre_adjust_head = texlists.pre_adjust_head - -- - setshift(finished_line,cur_indent) - -- - -- -- this is gone: - -- - -- if par.each_line_height ~= ignored_dimen then - -- setheight(finished_line,par.each_line_height) - -- end - -- if par.each_line_depth ~= ignored_dimen then - -- setdepth(finished_line,par.each_line_depth) - -- end - -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then - -- setheight(finished_line,par.first_line_height) - -- end - -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then - -- setdepth(finished_line,par.last_line_depth) - -- end - -- - if texlists.pre_adjust_head ~= pre_adjust_head then - append_list(par, texlists.pre_adjust_head) - texlists.pre_adjust_head = pre_adjust_head - end - append_to_vlist(par,finished_line) - if texlists.adjust_head ~= adjust_head then - append_list(par, texlists.adjust_head) - texlists.adjust_head = adjust_head - end - -- - local pen - if current_line + 1 ~= par.best_line then - if current_break.passive_pen_inter then - pen = current_break.passive_pen_inter + statistics.noflines = statistics.noflines + 1 + local finished_line = nil + if adjust_spacing > 0 then + statistics.nofadjustedlines = statistics.nofadjustedlines + 1 + finished_line = xpack_nodes(q,cur_width,"cal_expand_ratio",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis) else - pen = par.inter_line_penalty - end - if current_line == prevgraf + 1 then - pen = pen + par.club_penalty - end - if current_line + 2 == par.best_line then - if par.display then - pen = pen + par.display_widow_penalty + finished_line = xpack_nodes(q,cur_width,"exactly",par.par_break_dir,par.first_line,current_line) -- ,current_break.analysis) + end + if protrude_chars > 0 then + statistics.nofprotrudedlines = statistics.nofprotrudedlines + 1 + end + -- wrong: + local adjust_head = texlists.adjust_head + local pre_adjust_head = texlists.pre_adjust_head + -- + setshift(finished_line,cur_indent) + -- + -- -- this is gone: + -- + -- if par.each_line_height ~= ignored_dimen then + -- setheight(finished_line,par.each_line_height) + -- end + -- if par.each_line_depth ~= ignored_dimen then + -- setdepth(finished_line,par.each_line_depth) + -- end + -- if par.first_line_height ~= ignored_dimen and (current_line == par.first_line + 1) then + -- setheight(finished_line,par.first_line_height) + -- end + -- if par.last_line_depth ~= ignored_dimen and current_line + 1 == par.best_line then + -- setdepth(finished_line,par.last_line_depth) + -- end + -- + if texlists.pre_adjust_head ~= pre_adjust_head then + append_list(par, texlists.pre_adjust_head) + texlists.pre_adjust_head = pre_adjust_head + end + append_to_vlist(par,finished_line) + if texlists.adjust_head ~= adjust_head then + append_list(par, texlists.adjust_head) + texlists.adjust_head = adjust_head + end + -- + local pen + if current_line + 1 ~= par.best_line then + if current_break.passive_pen_inter then + pen = current_break.passive_pen_inter else - pen = pen + par.widow_penalty + pen = par.inter_line_penalty end - end - if disc_break then - if current_break.passive_pen_broken ~= 0 then - pen = pen + current_break.passive_pen_broken - else - pen = pen + par.broken_penalty + if current_line == prevgraf + 1 then + pen = pen + par.club_penalty end - end - if pen ~= 0 then - append_to_vlist(par,new_penalty(pen)) - end - end - current_line = current_line + 1 - current_break = current_break.prev_break - if current_break and not post_disc_break then - local current = head - local next = nil - while true do - next = getnext(current) - if next == current_break.cur_break then - break + if current_line + 2 == par.best_line then + if par.display then + pen = pen + par.display_widow_penalty + else + pen = pen + par.widow_penalty + end end - local id = getid(next) - if id == glyph_code then - break - elseif id == localpar_code then - -- nothing - elseif id < math_code then - -- messy criterium - break - elseif id == math_code then - -- keep the math node - setkern(next,0) -- surround - -- new in luatex - setglue(lastnode) -- zeros - break - elseif id == kern_code then - local subtype = getsubtype(next) - if subtype == fontkern_code or subtype == accentkern_code then - -- fontkerns and accent kerns as well as otf injections - break + if disc_break then + if current_break.passive_pen_broken ~= 0 then + pen = pen + current_break.passive_pen_broken + else + pen = pen + par.broken_penalty end end - current = next + if pen ~= 0 then + append_to_vlist(par,new_penalty(pen)) + end end - if current ~= head then - setnext(current) - flush_node_list(getnext(head)) - setlink(head,next) + current_line = current_line + 1 + current_break = current_break.prev_break + if current_break and not post_disc_break then + local current = head + local next = nil + while true do + next = getnext(current) + if next == current_break.cur_break then + break + end + local id = getid(next) + if id == glyph_code then + break + elseif id == localpar_code then + -- nothing + elseif id < math_code then + -- messy criterium + break + elseif id == math_code then + -- keep the math node + setkern(next,0) -- surround + -- new in luatex + setglue(lastnode) -- zeros + break + elseif id == kern_code then + local subtype = getsubtype(next) + if subtype == fontkern_code or subtype == accentkern_code then + -- fontkerns and accent kerns as well as otf injections + break + end + end + current = next + end + if current ~= head then + setnext(current) + flush_node_list(getnext(head)) + setlink(head,next) + end end end - end - -- if current_line ~= par.best_line then - -- report_parbuilders("line breaking") - -- end - par.head = nil -- needs checking - current_line = current_line - 1 - if trace_basic then - report_parbuilders("paragraph broken into %a lines",current_line) - end - texnest[texnest.ptr].prevgraf = current_line -end - -local function wrap_up(par) - if par.tracing_paragraphs then - diagnostics.stop() - end - if par.do_last_line_fit then - local best_bet = par.best_bet - local active_short = best_bet.active_short - local active_glue = best_bet.active_glue - if active_short == 0 then - if trace_lastlinefit then - report_parbuilders("disabling last line fit, no active_short") - end - par.do_last_line_fit = false - else - local glue = par.final_par_glue - setwidth(glue,getwidth(glue) + active_short - active_glue) - setfield(glue,"stretch",0) - if trace_lastlinefit then - report_parbuilders("applying last line fit, short %a, glue %p",active_short,active_glue) - end + -- if current_line ~= par.best_line then + -- report_parbuilders("line breaking") + -- end + par.head = nil -- needs checking + current_line = current_line - 1 + if trace_basic then + report_parbuilders("paragraph broken into %a lines",current_line) end + texnest[texnest.ptr].prevgraf = current_line end - -- we have a bunch of glue and and temp nodes not freed - local head = par.head - if getid(head) == temp_code then - par.head = getnext(head) - flush_node(head) - end - post_line_break(par) - reset_meta(par) - register_statistics(par) - return par.head_field -end --- we could do active nodes differently ... table instead of linked list or a list --- with prev nodes but it doesn't save much (as we still need to keep indices then --- in next) - -local function deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) -- no need for adjust if disabled - local active = par.active - local active_width = par.active_width - prev_r.next = r.next - -- removes r - -- r = nil - if prev_r == active then - r = active.next - if r.id == delta_code then - local aw = active_width.size + r.size active_width.size = aw cur_active_width.size = aw - local aw = active_width.stretch + r.stretch active_width.stretch = aw cur_active_width.stretch = aw - local aw = active_width.fi + r.fi active_width.fi = aw cur_active_width.fi = aw - local aw = active_width.fil + r.fil active_width.fil = aw cur_active_width.fil = aw - local aw = active_width.fill + r.fill active_width.fill = aw cur_active_width.fill = aw - local aw = active_width.filll + r.filll active_width.filll = aw cur_active_width.filll = aw - local aw = active_width.shrink + r.shrink active_width.shrink = aw cur_active_width.shrink = aw - if checked_expansion then - local aw = active_width.adjust_stretch + r.adjust_stretch active_width.adjust_stretch = aw cur_active_width.adjust_stretch = aw - local aw = active_width.adjust_shrink + r.adjust_shrink active_width.adjust_shrink = aw cur_active_width.adjust_shrink = aw - end - active.next = r.next - -- removes r - -- r = nil + local function wrap_up(par) + if par.tracing_paragraphs then + diagnostics.stop() end - elseif prev_r.id == delta_code then - r = prev_r.next - if r == active then - cur_active_width.size = cur_active_width.size - prev_r.size - cur_active_width.stretch = cur_active_width.stretch - prev_r.stretch - cur_active_width.fi = cur_active_width.fi - prev_r.fi - cur_active_width.fil = cur_active_width.fil - prev_r.fil - cur_active_width.fill = cur_active_width.fill - prev_r.fill - cur_active_width.filll = cur_active_width.filll - prev_r.filll - cur_active_width.shrink = cur_active_width.shrink - prev_r.shrink - if checked_expansion then - cur_active_width.adjust_stretch = cur_active_width.adjust_stretch - prev_r.adjust_stretch - cur_active_width.adjust_shrink = cur_active_width.adjust_shrink - prev_r.adjust_shrink + if par.do_last_line_fit then + local best_bet = par.best_bet + local active_short = best_bet.active_short + local active_glue = best_bet.active_glue + if active_short == 0 then + if trace_lastlinefit then + report_parbuilders("disabling last line fit, no active_short") + end + par.do_last_line_fit = false + else + local glue = par.final_par_glue + setwidth(glue,getwidth(glue) + active_short - active_glue) + setfield(glue,"stretch",0) + if trace_lastlinefit then + report_parbuilders("applying last line fit, short %a, glue %p",active_short,active_glue) + end end - prev_prev_r.next = active - -- removes prev_r - -- prev_r = nil - prev_r = prev_prev_r - elseif r.id == delta_code then - local rn = r.size cur_active_width.size = cur_active_width.size + rn prev_r.size = prev_r.size + rn - local rn = r.stretch cur_active_width.stretch = cur_active_width.stretch + rn prev_r.stretch = prev_r.stretch + rn - local rn = r.fi cur_active_width.fi = cur_active_width.fi + rn prev_r.fi = prev_r.fi + rn - local rn = r.fil cur_active_width.fil = cur_active_width.fil + rn prev_r.fil = prev_r.fil + rn - local rn = r.fill cur_active_width.fill = cur_active_width.fill + rn prev_r.fill = prev_r.fill + rn - local rn = r.filll cur_active_width.filll = cur_active_width.filll + rn prev_r.filll = prev_r.fill + rn - local rn = r.shrink cur_active_width.shrink = cur_active_width.shrink + rn prev_r.shrink = prev_r.shrink + rn - if checked_expansion then - local rn = r.adjust_stretch cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + rn prev_r.adjust_stretch = prev_r.adjust_stretch + rn - local rn = r.adjust_shrink cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + rn prev_r.adjust_shrink = prev_r.adjust_shrink + rn + end + -- we have a bunch of glue and and temp nodes not freed + local head = par.head + if getid(head) == temp_code then + par.head = getnext(head) + flush_node(head) + end + post_line_break(par) + reset_meta(par) + register_statistics(par) + return par.head_field + end + + -- we could do active nodes differently ... table instead of linked list or a list + -- with prev nodes but it doesn't save much (as we still need to keep indices then + -- in next) + + local function deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) -- no need for adjust if disabled + local active = par.active + local active_width = par.active_width + prev_r.next = r.next + -- removes r + -- r = nil + if prev_r == active then + r = active.next + if r.id == delta_code then + local aw = active_width.size + r.size active_width.size = aw cur_active_width.size = aw + local aw = active_width.stretch + r.stretch active_width.stretch = aw cur_active_width.stretch = aw + local aw = active_width.fi + r.fi active_width.fi = aw cur_active_width.fi = aw + local aw = active_width.fil + r.fil active_width.fil = aw cur_active_width.fil = aw + local aw = active_width.fill + r.fill active_width.fill = aw cur_active_width.fill = aw + local aw = active_width.filll + r.filll active_width.filll = aw cur_active_width.filll = aw + local aw = active_width.shrink + r.shrink active_width.shrink = aw cur_active_width.shrink = aw + if checked_expansion then + local aw = active_width.adjust_stretch + r.adjust_stretch active_width.adjust_stretch = aw cur_active_width.adjust_stretch = aw + local aw = active_width.adjust_shrink + r.adjust_shrink active_width.adjust_shrink = aw cur_active_width.adjust_shrink = aw + end + active.next = r.next + -- removes r + -- r = nil + end + elseif prev_r.id == delta_code then + r = prev_r.next + if r == active then + cur_active_width.size = cur_active_width.size - prev_r.size + cur_active_width.stretch = cur_active_width.stretch - prev_r.stretch + cur_active_width.fi = cur_active_width.fi - prev_r.fi + cur_active_width.fil = cur_active_width.fil - prev_r.fil + cur_active_width.fill = cur_active_width.fill - prev_r.fill + cur_active_width.filll = cur_active_width.filll - prev_r.filll + cur_active_width.shrink = cur_active_width.shrink - prev_r.shrink + if checked_expansion then + cur_active_width.adjust_stretch = cur_active_width.adjust_stretch - prev_r.adjust_stretch + cur_active_width.adjust_shrink = cur_active_width.adjust_shrink - prev_r.adjust_shrink + end + prev_prev_r.next = active + -- removes prev_r + -- prev_r = nil + prev_r = prev_prev_r + elseif r.id == delta_code then + local rn = r.size cur_active_width.size = cur_active_width.size + rn prev_r.size = prev_r.size + rn + local rn = r.stretch cur_active_width.stretch = cur_active_width.stretch + rn prev_r.stretch = prev_r.stretch + rn + local rn = r.fi cur_active_width.fi = cur_active_width.fi + rn prev_r.fi = prev_r.fi + rn + local rn = r.fil cur_active_width.fil = cur_active_width.fil + rn prev_r.fil = prev_r.fil + rn + local rn = r.fill cur_active_width.fill = cur_active_width.fill + rn prev_r.fill = prev_r.fill + rn + local rn = r.filll cur_active_width.filll = cur_active_width.filll + rn prev_r.filll = prev_r.fill + rn + local rn = r.shrink cur_active_width.shrink = cur_active_width.shrink + rn prev_r.shrink = prev_r.shrink + rn + if checked_expansion then + local rn = r.adjust_stretch cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + rn prev_r.adjust_stretch = prev_r.adjust_stretch + rn + local rn = r.adjust_shrink cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + rn prev_r.adjust_shrink = prev_r.adjust_shrink + rn + end + prev_r.next = r.next + -- removes r + -- r = nil end - prev_r.next = r.next - -- removes r - -- r = nil end + return prev_r, r end - return prev_r, r -end -local function lastlinecrap(shortfall,active_short,active_glue,cur_active_width,fill_width,last_line_fit) - if active_short == 0 or active_glue <= 0 then - return false, 0, fit_decent_class, 0, 0 - end - if cur_active_width.fi ~= fill_width.fi or cur_active_width.fil ~= fill_width.fil or cur_active_width.fill ~= fill_width.fill or cur_active_width.filll ~= fill_width.filll then - return false, 0, fit_decent_class, 0, 0 - end - local adjustment = active_short > 0 and cur_active_width.stretch or cur_active_width.shrink - if adjustment <= 0 then - return false, 0, fit_decent_class, adjustment, 0 - end - adjustment = calculate_fraction(adjustment,active_short,active_glue,maxdimen) - if last_line_fit < 1000 then - adjustment = calculate_fraction(adjustment,last_line_fit,1000,maxdimen) -- uses previous adjustment - end - local fit_class = fit_decent_class - if adjustment > 0 then - local stretch = cur_active_width.stretch - if adjustment > shortfall then - adjustment = shortfall - end - if adjustment > 7230584 and stretch < 1663497 then - return true, fit_very_loose_class, shortfall, adjustment, infinite_badness + local function lastlinecrap(shortfall,active_short,active_glue,cur_active_width,fill_width,last_line_fit) + if active_short == 0 or active_glue <= 0 then + return false, 0, fit_decent_class, 0, 0 end - -- if adjustment == 0 then -- badness = 0 - -- return true, shortfall, fit_decent_class, 0, 0 - -- elseif stretch <= 0 then -- badness = 10000 - -- return true, shortfall, fit_very_loose_class, adjustment, 10000 - -- end - -- local badness = (adjustment == 0 and 0) or (stretch <= 0 and 10000) or calculate_badness(adjustment,stretch) - local badness = calculate_badness(adjustment,stretch) - if badness > 99 then - return true, shortfall, fit_very_loose_class, adjustment, badness - elseif badness > 12 then - return true, shortfall, fit_loose_class, adjustment, badness - else - return true, shortfall, fit_decent_class, adjustment, badness + if cur_active_width.fi ~= fill_width.fi or cur_active_width.fil ~= fill_width.fil or cur_active_width.fill ~= fill_width.fill or cur_active_width.filll ~= fill_width.filll then + return false, 0, fit_decent_class, 0, 0 end - elseif adjustment < 0 then - local shrink = cur_active_width.shrink - if -adjustment > shrink then - adjustment = -shrink + local adjustment = active_short > 0 and cur_active_width.stretch or cur_active_width.shrink + if adjustment <= 0 then + return false, 0, fit_decent_class, adjustment, 0 end - local badness = calculate_badness(-adjustment,shrink) - if badness > 12 then - return true, shortfall, fit_tight_class, adjustment, badness - else - return true, shortfall, fit_decent_class, adjustment, badness + adjustment = calculate_fraction(adjustment,active_short,active_glue,maxdimen) + if last_line_fit < 1000 then + adjustment = calculate_fraction(adjustment,last_line_fit,1000,maxdimen) -- uses previous adjustment end - else - return false, 0, fit_decent_class, 0, 0 - end -end - --- todo: statistics .. count tries and so - -local trialcount = 0 - -local function try_break(pi, break_type, par, first_p, current, checked_expansion) - --- trialcount = trialcount + 1 --- print(trialcount,pi,break_type,current,nuts.tostring(current)) - - if pi >= infinite_penalty then -- this breakpoint is inhibited by infinite penalty - local p_active = par.active - return p_active, p_active and p_active.next - elseif pi <= -infinite_penalty then -- this breakpoint will be forced - pi = eject_penalty - end - - local prev_prev_r = nil -- a step behind prev_r, if type(prev_r)=delta_code - local prev_r = par.active -- stays a step behind r - local r = nil -- runs through the active list - local no_break_yet = true -- have we found a feasible break at current? - local node_r_stays_active = false -- should node r remain in the active list? - local line_width = 0 -- the current line will be justified to this width - local line_number = 0 -- line number of current active node - local old_line_number = 0 -- maximum line number in current equivalence class of lines - - local protrude_chars = par.protrude_chars - local checked_expansion = par.checked_expansion - local break_width = par.break_width - local active_width = par.active_width - local background = par.background - local minimal_demerits = par.minimal_demerits - local best_place = par.best_place - local best_pl_line = par.best_pl_line - local best_pl_short = par.best_pl_short - local best_pl_glue = par.best_pl_glue - local do_last_line_fit = par.do_last_line_fit - local final_pass = par.final_pass - local tracing_paragraphs = par.tracing_paragraphs - -- local par_active = par.active - - local adapt_width = par.adapt_width - - local parshape = par.par_shape_ptr - - local cur_active_width = checked_expansion and { -- distance from current active node - size = active_width.size, - stretch = active_width.stretch, - fi = active_width.fi, - fil = active_width.fil, - fill = active_width.fill, - filll = active_width.filll, - shrink = active_width.shrink, - adjust_stretch = active_width.adjust_stretch, - adjust_shrink = active_width.adjust_shrink, - } or { - size = active_width.size, - stretch = active_width.stretch, - fi = active_width.fi, - fil = active_width.fil, - fill = active_width.fill, - filll = active_width.filll, - shrink = active_width.shrink, - } - - while true do - r = prev_r.next - if r.id == delta_code then - cur_active_width.size = cur_active_width.size + r.size - cur_active_width.stretch = cur_active_width.stretch + r.stretch - cur_active_width.fi = cur_active_width.fi + r.fi - cur_active_width.fil = cur_active_width.fil + r.fil - cur_active_width.fill = cur_active_width.fill + r.fill - cur_active_width.filll = cur_active_width.filll + r.filll - cur_active_width.shrink = cur_active_width.shrink + r.shrink - if checked_expansion then - cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + r.adjust_stretch - cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + r.adjust_shrink + local fit_class = fit_decent_class + if adjustment > 0 then + local stretch = cur_active_width.stretch + if adjustment > shortfall then + adjustment = shortfall + end + if adjustment > 7230584 and stretch < 1663497 then + return true, fit_very_loose_class, shortfall, adjustment, infinite_badness + end + -- if adjustment == 0 then -- badness = 0 + -- return true, shortfall, fit_decent_class, 0, 0 + -- elseif stretch <= 0 then -- badness = 10000 + -- return true, shortfall, fit_very_loose_class, adjustment, 10000 + -- end + -- local badness = (adjustment == 0 and 0) or (stretch <= 0 and 10000) or calculate_badness(adjustment,stretch) + local badness = calculate_badness(adjustment,stretch) + if badness > 99 then + return true, shortfall, fit_very_loose_class, adjustment, badness + elseif badness > 12 then + return true, shortfall, fit_loose_class, adjustment, badness + else + return true, shortfall, fit_decent_class, adjustment, badness + end + elseif adjustment < 0 then + local shrink = cur_active_width.shrink + if -adjustment > shrink then + adjustment = -shrink + end + local badness = calculate_badness(-adjustment,shrink) + if badness > 12 then + return true, shortfall, fit_tight_class, adjustment, badness + else + return true, shortfall, fit_decent_class, adjustment, badness end - prev_prev_r = prev_r - prev_r = r else - line_number = r.line_number - if line_number > old_line_number then - local minimum_demerits = par.minimum_demerits - if minimum_demerits < awful_badness and (old_line_number ~= par.easy_line or r == par.active) then - if no_break_yet then - no_break_yet = false - break_width.size = background.size - break_width.stretch = background.stretch - break_width.fi = background.fi - break_width.fil = background.fil - break_width.fill = background.fill - break_width.filll = background.filll - break_width.shrink = background.shrink - if checked_expansion then - break_width.adjust_stretch = 0 - break_width.adjust_shrink = 0 + return false, 0, fit_decent_class, 0, 0 + end + end + + -- todo: statistics .. count tries and so + + local trialcount = 0 + + local function try_break(pi, break_type, par, first_p, current, checked_expansion) + + -- trialcount = trialcount + 1 + -- print(trialcount,pi,break_type,current,nuts.tostring(current)) + + if pi >= infinite_penalty then -- this breakpoint is inhibited by infinite penalty + local p_active = par.active + return p_active, p_active and p_active.next + elseif pi <= -infinite_penalty then -- this breakpoint will be forced + pi = eject_penalty + end + + local prev_prev_r = nil -- a step behind prev_r, if type(prev_r)=delta_code + local prev_r = par.active -- stays a step behind r + local r = nil -- runs through the active list + local no_break_yet = true -- have we found a feasible break at current? + local node_r_stays_active = false -- should node r remain in the active list? + local line_width = 0 -- the current line will be justified to this width + local line_number = 0 -- line number of current active node + local old_line_number = 0 -- maximum line number in current equivalence class of lines + + local protrude_chars = par.protrude_chars + local checked_expansion = par.checked_expansion + local break_width = par.break_width + local active_width = par.active_width + local background = par.background + local minimal_demerits = par.minimal_demerits + local best_place = par.best_place + local best_pl_line = par.best_pl_line + local best_pl_short = par.best_pl_short + local best_pl_glue = par.best_pl_glue + local do_last_line_fit = par.do_last_line_fit + local final_pass = par.final_pass + local tracing_paragraphs = par.tracing_paragraphs + -- local par_active = par.active + + local adapt_width = par.adapt_width + + local parshape = par.par_shape_ptr + + local cur_active_width = checked_expansion and { -- distance from current active node + size = active_width.size, + stretch = active_width.stretch, + fi = active_width.fi, + fil = active_width.fil, + fill = active_width.fill, + filll = active_width.filll, + shrink = active_width.shrink, + adjust_stretch = active_width.adjust_stretch, + adjust_shrink = active_width.adjust_shrink, + } or { + size = active_width.size, + stretch = active_width.stretch, + fi = active_width.fi, + fil = active_width.fil, + fill = active_width.fill, + filll = active_width.filll, + shrink = active_width.shrink, + } + + while true do + r = prev_r.next + if r.id == delta_code then + cur_active_width.size = cur_active_width.size + r.size + cur_active_width.stretch = cur_active_width.stretch + r.stretch + cur_active_width.fi = cur_active_width.fi + r.fi + cur_active_width.fil = cur_active_width.fil + r.fil + cur_active_width.fill = cur_active_width.fill + r.fill + cur_active_width.filll = cur_active_width.filll + r.filll + cur_active_width.shrink = cur_active_width.shrink + r.shrink + if checked_expansion then + cur_active_width.adjust_stretch = cur_active_width.adjust_stretch + r.adjust_stretch + cur_active_width.adjust_shrink = cur_active_width.adjust_shrink + r.adjust_shrink + end + prev_prev_r = prev_r + prev_r = r + else + line_number = r.line_number + if line_number > old_line_number then + local minimum_demerits = par.minimum_demerits + if minimum_demerits < awful_badness and (old_line_number ~= par.easy_line or r == par.active) then + if no_break_yet then + no_break_yet = false + break_width.size = background.size + break_width.stretch = background.stretch + break_width.fi = background.fi + break_width.fil = background.fil + break_width.fill = background.fill + break_width.filll = background.filll + break_width.shrink = background.shrink + if checked_expansion then + break_width.adjust_stretch = 0 + break_width.adjust_shrink = 0 + end + if current then + compute_break_width(par,break_type,current) + end end - if current then - compute_break_width(par,break_type,current) + if prev_r.id == delta_code then + prev_r.size = prev_r.size - cur_active_width.size + break_width.size + prev_r.stretch = prev_r.stretch - cur_active_width.stretc + break_width.stretch + prev_r.fi = prev_r.fi - cur_active_width.fi + break_width.fi + prev_r.fil = prev_r.fil - cur_active_width.fil + break_width.fil + prev_r.fill = prev_r.fill - cur_active_width.fill + break_width.fill + prev_r.filll = prev_r.filll - cur_active_width.filll + break_width.filll + prev_r.shrink = prev_r.shrink - cur_active_width.shrink + break_width.shrink + if checked_expansion then + prev_r.adjust_stretch = prev_r.adjust_stretch - cur_active_width.adjust_stretch + break_width.adjust_stretch + prev_r.adjust_shrink = prev_r.adjust_shrink - cur_active_width.adjust_shrink + break_width.adjust_shrink + end + elseif prev_r == par.active then + active_width.size = break_width.size + active_width.stretch = break_width.stretch + active_width.fi = break_width.fi + active_width.fil = break_width.fil + active_width.fill = break_width.fill + active_width.filll = break_width.filll + active_width.shrink = break_width.shrink + if checked_expansion then + active_width.adjust_stretch = break_width.adjust_stretch + active_width.adjust_shrink = break_width.adjust_shrink + end + else + local q = checked_expansion and { + id = delta_code, + subtype = nosubtype_code, + next = r, + size = break_width.size - cur_active_width.size, + stretch = break_width.stretch - cur_active_width.stretch, + fi = break_width.fi - cur_active_width.fi, + fil = break_width.fil - cur_active_width.fil, + fill = break_width.fill - cur_active_width.fill, + filll = break_width.filll - cur_active_width.filll, + shrink = break_width.shrink - cur_active_width.shrink, + adjust_stretch = break_width.adjust_stretch - cur_active_width.adjust_stretch, + adjust_shrink = break_width.adjust_shrink - cur_active_width.adjust_shrink, + } or { + id = delta_code, + subtype = nosubtype_code, + next = r, + size = break_width.size - cur_active_width.size, + stretch = break_width.stretch - cur_active_width.stretch, + fi = break_width.fi - cur_active_width.fi, + fil = break_width.fil - cur_active_width.fil, + fill = break_width.fill - cur_active_width.fill, + filll = break_width.filll - cur_active_width.filll, + shrink = break_width.shrink - cur_active_width.shrink, + } + prev_r.next = q + prev_prev_r = prev_r + prev_r = q end - end - if prev_r.id == delta_code then - prev_r.size = prev_r.size - cur_active_width.size + break_width.size - prev_r.stretch = prev_r.stretch - cur_active_width.stretc + break_width.stretch - prev_r.fi = prev_r.fi - cur_active_width.fi + break_width.fi - prev_r.fil = prev_r.fil - cur_active_width.fil + break_width.fil - prev_r.fill = prev_r.fill - cur_active_width.fill + break_width.fill - prev_r.filll = prev_r.filll - cur_active_width.filll + break_width.filll - prev_r.shrink = prev_r.shrink - cur_active_width.shrink + break_width.shrink - if checked_expansion then - prev_r.adjust_stretch = prev_r.adjust_stretch - cur_active_width.adjust_stretch + break_width.adjust_stretch - prev_r.adjust_shrink = prev_r.adjust_shrink - cur_active_width.adjust_shrink + break_width.adjust_shrink + local adj_demerits = par.adj_demerits + local abs_adj_demerits = adj_demerits > 0 and adj_demerits or -adj_demerits + if abs_adj_demerits >= awful_badness - minimum_demerits then + minimum_demerits = awful_badness - 1 + else + minimum_demerits = minimum_demerits + abs_adj_demerits end - elseif prev_r == par.active then - active_width.size = break_width.size - active_width.stretch = break_width.stretch - active_width.fi = break_width.fi - active_width.fil = break_width.fil - active_width.fill = break_width.fill - active_width.filll = break_width.filll - active_width.shrink = break_width.shrink - if checked_expansion then - active_width.adjust_stretch = break_width.adjust_stretch - active_width.adjust_shrink = break_width.adjust_shrink + for fit_class = fit_very_loose_class, fit_tight_class do + if minimal_demerits[fit_class] <= minimum_demerits then + -- insert a new active node from best_place[fit_class] to current + par.pass_number = par.pass_number + 1 + local prev_break = best_place[fit_class] + local passive = { + id = passive_code, + subtype = nosubtype_code, + next = par.passive, + cur_break = current, + serial = par.pass_number, + prev_break = prev_break, + passive_pen_inter = par.internal_pen_inter, + passive_pen_broken = par.internal_pen_broken, + passive_last_left_box = par.internal_left_box, + passive_last_left_box_width = par.internal_left_box_width, + passive_left_box = prev_break and prev_break.passive_last_left_box or par.init_internal_left_box, + passive_left_box_width = prev_break and prev_break.passive_last_left_box_width or par.init_internal_left_box_width, + passive_right_box = par.internal_right_box, + passive_right_box_width = par.internal_right_box_width, + -- analysis = table.fastcopy(cur_active_width), + } + par.passive = passive + local q = { + id = break_type, + subtype = fit_class, + break_node = passive, + line_number = best_pl_line[fit_class] + 1, + total_demerits = minimal_demerits[fit_class], -- or 0, + next = r, + } + if do_last_line_fit then + local active_short = best_pl_short[fit_class] + local active_glue = best_pl_glue[fit_class] + q.active_short = active_short + q.active_glue = active_glue + if trace_lastlinefit then + report_parbuilders("setting short to %i and glue to %p using class %a",active_short,active_glue,fit_class) + end + end + -- q.next = r -- already done + prev_r.next = q + prev_r = q + if tracing_paragraphs then + diagnostics.break_node(par,q,fit_class,break_type,current) + end + end + minimal_demerits[fit_class] = awful_badness end - else - local q = checked_expansion and { - id = delta_code, - subtype = nosubtype_code, - next = r, - size = break_width.size - cur_active_width.size, - stretch = break_width.stretch - cur_active_width.stretch, - fi = break_width.fi - cur_active_width.fi, - fil = break_width.fil - cur_active_width.fil, - fill = break_width.fill - cur_active_width.fill, - filll = break_width.filll - cur_active_width.filll, - shrink = break_width.shrink - cur_active_width.shrink, - adjust_stretch = break_width.adjust_stretch - cur_active_width.adjust_stretch, - adjust_shrink = break_width.adjust_shrink - cur_active_width.adjust_shrink, - } or { - id = delta_code, - subtype = nosubtype_code, - next = r, - size = break_width.size - cur_active_width.size, - stretch = break_width.stretch - cur_active_width.stretch, - fi = break_width.fi - cur_active_width.fi, - fil = break_width.fil - cur_active_width.fil, - fill = break_width.fill - cur_active_width.fill, - filll = break_width.filll - cur_active_width.filll, - shrink = break_width.shrink - cur_active_width.shrink, - } - prev_r.next = q - prev_prev_r = prev_r - prev_r = q - end - local adj_demerits = par.adj_demerits - local abs_adj_demerits = adj_demerits > 0 and adj_demerits or -adj_demerits - if abs_adj_demerits >= awful_badness - minimum_demerits then - minimum_demerits = awful_badness - 1 - else - minimum_demerits = minimum_demerits + abs_adj_demerits - end - for fit_class = fit_very_loose_class, fit_tight_class do - if minimal_demerits[fit_class] <= minimum_demerits then - -- insert a new active node from best_place[fit_class] to current - par.pass_number = par.pass_number + 1 - local prev_break = best_place[fit_class] - local passive = { - id = passive_code, - subtype = nosubtype_code, - next = par.passive, - cur_break = current, - serial = par.pass_number, - prev_break = prev_break, - passive_pen_inter = par.internal_pen_inter, - passive_pen_broken = par.internal_pen_broken, - passive_last_left_box = par.internal_left_box, - passive_last_left_box_width = par.internal_left_box_width, - passive_left_box = prev_break and prev_break.passive_last_left_box or par.init_internal_left_box, - passive_left_box_width = prev_break and prev_break.passive_last_left_box_width or par.init_internal_left_box_width, - passive_right_box = par.internal_right_box, - passive_right_box_width = par.internal_right_box_width, --- analysis = table.fastcopy(cur_active_width), - } - par.passive = passive - local q = { - id = break_type, - subtype = fit_class, - break_node = passive, - line_number = best_pl_line[fit_class] + 1, - total_demerits = minimal_demerits[fit_class], -- or 0, + par.minimum_demerits = awful_badness + if r ~= par.active then + local q = checked_expansion and { + id = delta_code, + subtype = nosubtype_code, + next = r, + size = cur_active_width.size - break_width.size, + stretch = cur_active_width.stretch - break_width.stretch, + fi = cur_active_width.fi - break_width.fi, + fil = cur_active_width.fil - break_width.fil, + fill = cur_active_width.fill - break_width.fill, + filll = cur_active_width.filll - break_width.filll, + shrink = cur_active_width.shrink - break_width.shrink, + adjust_stretch = cur_active_width.adjust_stretch - break_width.adjust_stretch, + adjust_shrink = cur_active_width.adjust_shrink - break_width.adjust_shrink, + } or { + id = delta_code, + subtype = nosubtype_code, next = r, + size = cur_active_width.size - break_width.size, + stretch = cur_active_width.stretch - break_width.stretch, + fi = cur_active_width.fi - break_width.fi, + fil = cur_active_width.fil - break_width.fil, + fill = cur_active_width.fill - break_width.fill, + filll = cur_active_width.filll - break_width.filll, + shrink = cur_active_width.shrink - break_width.shrink, } - if do_last_line_fit then - local active_short = best_pl_short[fit_class] - local active_glue = best_pl_glue[fit_class] - q.active_short = active_short - q.active_glue = active_glue - if trace_lastlinefit then - report_parbuilders("setting short to %i and glue to %p using class %a",active_short,active_glue,fit_class) - end - end -- q.next = r -- already done prev_r.next = q + prev_prev_r = prev_r prev_r = q - if tracing_paragraphs then - diagnostics.break_node(par,q,fit_class,break_type,current) - end end - minimal_demerits[fit_class] = awful_badness - end - par.minimum_demerits = awful_badness - if r ~= par.active then - local q = checked_expansion and { - id = delta_code, - subtype = nosubtype_code, - next = r, - size = cur_active_width.size - break_width.size, - stretch = cur_active_width.stretch - break_width.stretch, - fi = cur_active_width.fi - break_width.fi, - fil = cur_active_width.fil - break_width.fil, - fill = cur_active_width.fill - break_width.fill, - filll = cur_active_width.filll - break_width.filll, - shrink = cur_active_width.shrink - break_width.shrink, - adjust_stretch = cur_active_width.adjust_stretch - break_width.adjust_stretch, - adjust_shrink = cur_active_width.adjust_shrink - break_width.adjust_shrink, - } or { - id = delta_code, - subtype = nosubtype_code, - next = r, - size = cur_active_width.size - break_width.size, - stretch = cur_active_width.stretch - break_width.stretch, - fi = cur_active_width.fi - break_width.fi, - fil = cur_active_width.fil - break_width.fil, - fill = cur_active_width.fill - break_width.fill, - filll = cur_active_width.filll - break_width.filll, - shrink = cur_active_width.shrink - break_width.shrink, - } - -- q.next = r -- already done - prev_r.next = q - prev_prev_r = prev_r - prev_r = q end - end - if r == par.active then - return r, r and r.next -- p_active, n_active - end - if line_number > par.easy_line then - old_line_number = max_halfword - 1 - line_width = par.second_width - else - old_line_number = line_number - if line_number > par.last_special_line then + if r == par.active then + return r, r and r.next -- p_active, n_active + end + if line_number > par.easy_line then + old_line_number = max_halfword - 1 line_width = par.second_width - elseif parshape then - line_width = parshape[line_number][2] else - line_width = par.first_width + old_line_number = line_number + if line_number > par.last_special_line then + line_width = par.second_width + elseif parshape then + line_width = parshape[line_number][2] + else + line_width = par.first_width + end end - end - if adapt_width then - local l, r = adapt_width(par,line_number) - line_width = line_width - l - r - end - end - local artificial_demerits = false -- has d been forced to zero - local shortfall = line_width - cur_active_width.size - par.internal_right_box_width -- used in badness calculations - if not r.break_node then - shortfall = shortfall - par.init_internal_left_box_width - else - shortfall = shortfall - (r.break_node.passive_last_left_box_width or 0) - end - local pw, lp, rp -- used later on - if protrude_chars > 1 then - -- this is quite time consuming - local b = r.break_node - local l = b and b.cur_break or first_p - local o = current and getprev(current) - if current and getid(current) == disc_code then - local pre, _, _, pretail = getdisc(current,true) - if pre then - o = pretail - else - o = find_protchar_right(l,o) + if adapt_width then + local l, r = adapt_width(par,line_number) + line_width = line_width - l - r end - else - o = find_protchar_right(l,o) end - if o and getid(o) == glyph_code then - pw, rp = right_pw(o) - shortfall = shortfall + pw - end - local id = getid(l) - if id == glyph_code then - -- ok ? - elseif id == disc_code and getfield(l,"post") then - l = getfield(l,"post") -- TODO: first char could be a disc + local artificial_demerits = false -- has d been forced to zero + local shortfall = line_width - cur_active_width.size - par.internal_right_box_width -- used in badness calculations + if not r.break_node then + shortfall = shortfall - par.init_internal_left_box_width else - l = find_protchar_left(l) - end - if l and getid(l) == glyph_code then - pw, lp = left_pw(l) - shortfall = shortfall + pw + shortfall = shortfall - (r.break_node.passive_last_left_box_width or 0) end - end - if checked_expansion and shortfall ~= 0 then - local margin_kern_stretch = 0 - local margin_kern_shrink = 0 + local pw, lp, rp -- used later on if protrude_chars > 1 then - if lp then - local data = expansions[getfont(lp)][getchar(lp)] - if data then - margin_kern_stretch, margin_kern_shrink = data.glyphstretch, data.glyphshrink + -- this is quite time consuming + local b = r.break_node + local l = b and b.cur_break or first_p + local o = current and getprev(current) + if current and getid(current) == disc_code then + local pre, _, _, pretail = getdisc(current,true) + if pre then + o = pretail + else + o = find_protchar_right(l,o) end + else + o = find_protchar_right(l,o) end - if rp then - local data = expansions[getfont(lp)][getchar(lp)] - if data then - margin_kern_stretch = margin_kern_stretch + data.glyphstretch - margin_kern_shrink = margin_kern_shrink + data.glyphshrink - end + if o and getid(o) == glyph_code then + pw, rp = right_pw(o) + shortfall = shortfall + pw end - end - local total = cur_active_width.adjust_stretch + margin_kern_stretch - if shortfall > 0 and total > 0 then - if total > shortfall then - shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2 + local id = getid(l) + if id == glyph_code then + -- ok ? + elseif id == disc_code and getfield(l,"post") then + l = getfield(l,"post") -- TODO: first char could be a disc else - shortfall = shortfall - total + l = find_protchar_left(l) end - else - total = cur_active_width.adjust_shrink + margin_kern_shrink - if shortfall < 0 and total > 0 then - if total > - shortfall then - shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2 - else - shortfall = shortfall + total - end + if l and getid(l) == glyph_code then + pw, lp = left_pw(l) + shortfall = shortfall + pw end end - end - local b = 0 - local g = 0 - local fit_class = fit_decent_class - local found = false - if shortfall > 0 then - if cur_active_width.fi ~= 0 or cur_active_width.fil ~= 0 or cur_active_width.fill ~= 0 or cur_active_width.filll ~= 0 then - if not do_last_line_fit then - -- okay - elseif not current then - found, shortfall, fit_class, g, b = lastlinecrap(shortfall,r.active_short,r.active_glue,cur_active_width,par.fill_width,par.last_line_fit) + if checked_expansion and shortfall ~= 0 then + local margin_kern_stretch = 0 + local margin_kern_shrink = 0 + if protrude_chars > 1 then + if lp then + local char, font = isglyph(lp) + local data = expansions[font][char] + if data then + margin_kern_stretch, margin_kern_shrink = data.glyphstretch, data.glyphshrink + end + end + if rp then + local char, font = isglyph(rp) + local data = expansions[font][char] + if data then + margin_kern_stretch = margin_kern_stretch + data.glyphstretch + margin_kern_shrink = margin_kern_shrink + data.glyphshrink + end + end + end + local total = cur_active_width.adjust_stretch + margin_kern_stretch + if shortfall > 0 and total > 0 then + if total > shortfall then + shortfall = total / (par.max_stretch_ratio / par.cur_font_step) / 2 + else + shortfall = shortfall - total + end else - shortfall = 0 + total = cur_active_width.adjust_shrink + margin_kern_shrink + if shortfall < 0 and total > 0 then + if total > - shortfall then + shortfall = - total / (par.max_shrink_ratio / par.cur_font_step) / 2 + else + shortfall = shortfall + total + end + end end - else - local stretch = cur_active_width.stretch - if shortfall > 7230584 and stretch < 1663497 then - b = infinite_badness - fit_class = fit_very_loose_class + end + local b = 0 + local g = 0 + local fit_class = fit_decent_class + local found = false + if shortfall > 0 then + if cur_active_width.fi ~= 0 or cur_active_width.fil ~= 0 or cur_active_width.fill ~= 0 or cur_active_width.filll ~= 0 then + if not do_last_line_fit then + -- okay + elseif not current then + found, shortfall, fit_class, g, b = lastlinecrap(shortfall,r.active_short,r.active_glue,cur_active_width,par.fill_width,par.last_line_fit) + else + shortfall = 0 + end else - b = calculate_badness(shortfall,stretch) - if b > 99 then + local stretch = cur_active_width.stretch + if shortfall > 7230584 and stretch < 1663497 then + b = infinite_badness fit_class = fit_very_loose_class - elseif b > 12 then - fit_class = fit_loose_class else - fit_class = fit_decent_class + b = calculate_badness(shortfall,stretch) + if b > 99 then + fit_class = fit_very_loose_class + elseif b > 12 then + fit_class = fit_loose_class + else + fit_class = fit_decent_class + end end end - end - else - local shrink = cur_active_width.shrink - if -shortfall > shrink then - b = infinite_badness + 1 - else - b = calculate_badness(-shortfall,shrink) - end - if b > 12 then - fit_class = fit_tight_class - else - fit_class = fit_decent_class - end - end - if do_last_line_fit and not found then - if not current then - -- g = 0 - shortfall = 0 - elseif shortfall > 0 then - g = cur_active_width.stretch - elseif shortfall < 0 then - g = cur_active_width.shrink else - g = 0 + local shrink = cur_active_width.shrink + if -shortfall > shrink then + b = infinite_badness + 1 + else + b = calculate_badness(-shortfall,shrink) + end + if b > 12 then + fit_class = fit_tight_class + else + fit_class = fit_decent_class + end end - end - -- ::FOUND:: - local continue_only = false -- brrr - if b > infinite_badness or pi == eject_penalty then - if final_pass and par.minimum_demerits == awful_badness and r.next == par.active and prev_r == par.active then - artificial_demerits = true -- set demerits zero, this break is forced - node_r_stays_active = false - elseif b > par.threshold then - prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) - continue_only = true - else - node_r_stays_active = false + if do_last_line_fit and not found then + if not current then + -- g = 0 + shortfall = 0 + elseif shortfall > 0 then + g = cur_active_width.stretch + elseif shortfall < 0 then + g = cur_active_width.shrink + else + g = 0 + end end - else - prev_r = r - if b > par.threshold then - continue_only = true + -- ::FOUND:: + local continue_only = false -- brrr + if b > infinite_badness or pi == eject_penalty then + if final_pass and par.minimum_demerits == awful_badness and r.next == par.active and prev_r == par.active then + artificial_demerits = true -- set demerits zero, this break is forced + node_r_stays_active = false + elseif b > par.threshold then + prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) + continue_only = true + else + node_r_stays_active = false + end else - node_r_stays_active = true - end - end - if not continue_only then - local d = 0 - if not artificial_demerits then - d = par.line_penalty + b - if (d >= 0 and d or -d) >= 10000 then -- abs(d) - d = 100000000 + prev_r = r + if b > par.threshold then + continue_only = true else - d = d * d + node_r_stays_active = true end - if pi == 0 then - -- nothing - elseif pi > 0 then - d = d + pi * pi - elseif pi > eject_penalty then - d = d - pi * pi - end - if break_type == hyphenated_code and r.id == hyphenated_code then - if current then - d = d + par.double_hyphen_demerits + end + if not continue_only then + local d = 0 + if not artificial_demerits then + d = par.line_penalty + b + if (d >= 0 and d or -d) >= 10000 then -- abs(d) + d = 100000000 else - d = d + par.final_hyphen_demerits + d = d * d + end + if pi == 0 then + -- nothing + elseif pi > 0 then + d = d + pi * pi + elseif pi > eject_penalty then + d = d - pi * pi + end + if break_type == hyphenated_code and r.id == hyphenated_code then + if current then + d = d + par.double_hyphen_demerits + else + d = d + par.final_hyphen_demerits + end + end + local delta = fit_class - r.subtype + if (delta >= 0 and delta or -delta) > 1 then -- abs(delta) + d = d + par.adj_demerits end end - local delta = fit_class - r.subtype - if (delta >= 0 and delta or -delta) > 1 then -- abs(delta) - d = d + par.adj_demerits + if tracing_paragraphs then + diagnostics.feasible_break(par,current,r,b,pi,d,artificial_demerits) end - end - if tracing_paragraphs then - diagnostics.feasible_break(par,current,r,b,pi,d,artificial_demerits) - end - d = d + r.total_demerits -- this is the minimum total demerits from the beginning to current via r - if d <= minimal_demerits[fit_class] then - minimal_demerits[fit_class] = d - best_place [fit_class] = r.break_node - best_pl_line [fit_class] = line_number - if do_last_line_fit then - best_pl_short[fit_class] = shortfall - best_pl_glue [fit_class] = g - if trace_lastlinefit then - report_parbuilders("storing last line fit short %a and glue %p in class %a",shortfall,g,fit_class) + d = d + r.total_demerits -- this is the minimum total demerits from the beginning to current via r + if d <= minimal_demerits[fit_class] then + minimal_demerits[fit_class] = d + best_place [fit_class] = r.break_node + best_pl_line [fit_class] = line_number + if do_last_line_fit then + best_pl_short[fit_class] = shortfall + best_pl_glue [fit_class] = g + if trace_lastlinefit then + report_parbuilders("storing last line fit short %a and glue %p in class %a",shortfall,g,fit_class) + end + end + if d < par.minimum_demerits then + par.minimum_demerits = d end end - if d < par.minimum_demerits then - par.minimum_demerits = d + if not node_r_stays_active then + prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) end end - if not node_r_stays_active then - prev_r, r = deactivate_node(par,prev_prev_r,prev_r,r,cur_active_width,checked_expansion) - end end end end -end - --- we can call the normal one for simple box building in the otr so we need --- frequent enabling/disabling -local dcolor = { [0] = "red", "green", "blue", "magenta", "cyan", "gray" } + -- we can call the normal one for simple box building in the otr so we need + -- frequent enabling/disabling -local temp_head = new_temp() + local temp_head = new_temp() -function constructors.methods.basic(head,d) - head = tonut(head) - - if trace_basic then - report_parbuilders("starting at %a",head) - end + function constructors.methods.basic(head,d) + if trace_basic then + report_parbuilders("starting at %a",head) + end - local par = initialize_line_break(head,d) + local par = initialize_line_break(head,d) - local checked_expansion = par.checked_expansion - local active_width = par.active_width - local disc_width = par.disc_width - local background = par.background - local tracing_paragraphs = par.tracing_paragraphs + local checked_expansion = par.checked_expansion + local active_width = par.active_width + local disc_width = par.disc_width + local background = par.background + local tracing_paragraphs = par.tracing_paragraphs - local dirstack = new_dir_stack() + local dirstack = new_dir_stack() - if tracing_paragraphs then - diagnostics.start() - if par.pretolerance >= 0 then - diagnostics.current_pass(par,"firstpass") + if tracing_paragraphs then + diagnostics.start() + if par.pretolerance >= 0 then + diagnostics.current_pass(par,"firstpass") + end end - end - while true do - reset_meta(par) - if par.threshold > infinite_badness then - par.threshold = infinite_badness - end - par.active.next = { - id = unhyphenated_code, - subtype = fit_decent_class, - next = par.active, - break_node = nil, - line_number = par.first_line + 1, - total_demerits = 0, - active_short = 0, - active_glue = 0, - } - active_width.size = background.size - active_width.stretch = background.stretch - active_width.fi = background.fi - active_width.fil = background.fil - active_width.fill = background.fill - active_width.filll = background.filll - active_width.shrink = background.shrink - - if checked_expansion then - active_width.adjust_stretch = 0 - active_width.adjust_shrink = 0 - end + while true do + reset_meta(par) + if par.threshold > infinite_badness then + par.threshold = infinite_badness + end + par.active.next = { + id = unhyphenated_code, + subtype = fit_decent_class, + next = par.active, + break_node = nil, + line_number = par.first_line + 1, + total_demerits = 0, + active_short = 0, + active_glue = 0, + } + active_width.size = background.size + active_width.stretch = background.stretch + active_width.fi = background.fi + active_width.fil = background.fil + active_width.fill = background.fill + active_width.filll = background.filll + active_width.shrink = background.shrink - par.passive = nil -- = 0 - par.printed_node = temp_head -- only when tracing, shared - par.pass_number = 0 --- par.auto_breaking = true + if checked_expansion then + active_width.adjust_stretch = 0 + active_width.adjust_shrink = 0 + end - setnext(temp_head,head) + par.passive = nil -- = 0 + par.printed_node = temp_head -- only when tracing, shared + par.pass_number = 0 + -- par.auto_breaking = true - local current = head - local first_p = current + setnext(temp_head,head) - local auto_breaking = true + local current = head + local first_p = current - par.font_in_short_display = 0 + local auto_breaking = true - if current then - local id = getid(current) - if id == localpar_code then - par.init_internal_left_box = getfield(current,"box_left") - par.init_internal_left_box_width = getfield(current,"box_left_width") - par.internal_pen_inter = getfield(current,"pen_inter") - par.internal_pen_broken = getfield(current,"pen_broken") - par.internal_left_box = par.init_internal_left_box - par.internal_left_box_width = par.init_internal_left_box_width - par.internal_right_box = getfield(current,"box_right") - par.internal_right_box_width = getfield(current,"box_right_width") + par.font_in_short_display = 0 + + if current then + local id = getid(current) + if id == localpar_code then + par.init_internal_left_box = getfield(current,"box_left") + par.init_internal_left_box_width = getfield(current,"box_left_width") + par.internal_pen_inter = getfield(current,"pen_inter") + par.internal_pen_broken = getfield(current,"pen_broken") + par.internal_left_box = par.init_internal_left_box + par.internal_left_box_width = par.init_internal_left_box_width + par.internal_right_box = getfield(current,"box_right") + par.internal_right_box_width = getfield(current,"box_right_width") + end end - end - -- all passes are combined in this loop so maybe we should split this into - -- three function calls; we then also need to do the wrap_up elsewhere + -- all passes are combined in this loop so maybe we should split this into + -- three function calls; we then also need to do the wrap_up elsewhere - -- split into normal and expansion loop + -- split into normal and expansion loop - -- use an active local + -- use an active local - local fontexp, lastfont -- we can pass fontexp to calculate width if needed + local fontexp, lastfont -- we can pass fontexp to calculate width if needed - -- i flattened the inner loop over glyphs .. it looks nicer and the extra p_active ~= n_active - -- test is fast enough (and try_break now returns the updated values); the kern helper has been - -- inlined as it did a double check on id so in fact we had hardly any code to share + -- i flattened the inner loop over glyphs .. it looks nicer and the extra p_active ~= n_active + -- test is fast enough (and try_break now returns the updated values); the kern helper has been + -- inlined as it did a double check on id so in fact we had hardly any code to share - local p_active = par.active - local n_active = p_active and p_active.next - local second_pass = par.second_pass + local p_active = par.active + local n_active = p_active and p_active.next + local second_pass = par.second_pass - trialcount = 0 + trialcount = 0 - while current and p_active ~= n_active do - local char, id = isglyph(current) - if char then - local wd, ht, dp = getwhd(current) - if is_rotated[par.line_break_dir] then - active_width.size = active_width.size + ht + dp - else - active_width.size = active_width.size + wd - end - if checked_expansion then - local currentfont = getfont(current) - local data = checked_expansion[currentfont] - if data then - if currentfont ~= lastfont then - fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer - lastfont = currentfont - end - if fontexps then - local expansion = fontexps[char] - if expansion then - active_width.adjust_stretch = active_width.adjust_stretch + expansion.glyphstretch - active_width.adjust_shrink = active_width.adjust_shrink + expansion.glyphshrink + while current and p_active ~= n_active do + local char, id = isglyph(current) + if char then + local wd, ht, dp = getwhd(current) + if is_rotated(par.line_break_dir) then + active_width.size = active_width.size + ht + dp + else + active_width.size = active_width.size + wd + end + if checked_expansion then + local font = id -- == font + local data = checked_expansion[font] + if data then + if font ~= lastfont then + fontexps = checked_expansion[font] -- a bit redundant for the par line packer + lastfont = currentfont + end + if fontexps then + local expansion = fontexps[char] + if expansion then + active_width.adjust_stretch = active_width.adjust_stretch + expansion.glyphstretch + active_width.adjust_shrink = active_width.adjust_shrink + expansion.glyphshrink + end end end end - end - elseif id == hlist_code or id == vlist_code then - local wd, ht, dp = getwhd(current) - if is_parallel[getdir(current)][par.line_break_dir] then - active_width.size = active_width.size + wd - else - active_width.size = active_width.size + ht + dp - end - elseif id == glue_code then --- if par.auto_breaking then - if auto_breaking then - local prev_p = getprev(current) - if prev_p and prev_p ~= temp_head then - local id = getid(prev_p) - -- we need to check this with the latest patches to the tex kernel - if (id == glyph_code) or (id < math_code) then - p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) - elseif id == kern_code then - local s = getsubtype(prev_p) - if s ~= userkern_code and s ~= italickern_code then + elseif id == hlist_code or id == vlist_code then + local wd, ht, dp = getwhd(current) + if textdir_parallel(getdirection(current),par.line_break_dir) then + active_width.size = active_width.size + wd + else + active_width.size = active_width.size + ht + dp + end + elseif id == glue_code then + -- if par.auto_breaking then + if auto_breaking then + local prev_p = getprev(current) + if prev_p and prev_p ~= temp_head then + local id = getid(prev_p) + -- we need to check this with the latest patches to the tex kernel + if (id == glyph_code) or (id < math_code) then p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) + elseif id == kern_code then + local s = getsubtype(prev_p) + if s ~= userkern_code and s ~= italickern_code then + p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) + end end end end - end - check_shrinkage(par,current) - local width, stretch, shrink, stretch_order = getglue(current) - local order = stretch_orders[stretch_order] - active_width.size = active_width.size + width - active_width[order] = active_width[order] + stretch - active_width.shrink = active_width.shrink + shrink - elseif id == disc_code then - local subtype = getsubtype(current) - if subtype ~= second_disc_code then - local line_break_dir = par.line_break_dir - if second_pass or subtype <= automatic_disc_code then - local actual_pen = subtype == automatic_disc_code and par.ex_hyphen_penalty or par.hyphen_penalty - -- 0.81 : - -- local actual_pen = getpenalty(current) - -- - local pre, post, replace = getdisc(current) - if not pre then -- trivial pre-break - disc_width.size = 0 - if checked_expansion then - disc_width.adjust_stretch = 0 - disc_width.adjust_shrink = 0 - end - p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion) - else - local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre) - disc_width.size = size - active_width.size = active_width.size + size - if checked_expansion then - disc_width.adjust_stretch = adjust_stretch - disc_width.adjust_shrink = adjust_shrink - active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch - active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink + check_shrinkage(par,current) + local width, stretch, shrink, stretch_order = getglue(current) + local order = fillcodes[stretch_order] + active_width.size = active_width.size + width + active_width[order] = active_width[order] + stretch + active_width.shrink = active_width.shrink + shrink + elseif id == disc_code then + local subtype = getsubtype(current) + if subtype ~= seconddisc_code then + local line_break_dir = par.line_break_dir + if second_pass or subtype <= automaticdisc_code then + local actual_pen = subtype == automaticdisc_code and par.ex_hyphen_penalty or par.hyphen_penalty + -- 0.81 : + -- local actual_pen = getpenalty(current) + -- + local pre, post, replace = getdisc(current) + if not pre then -- trivial pre-break + disc_width.size = 0 + if checked_expansion then + disc_width.adjust_stretch = 0 + disc_width.adjust_shrink = 0 + end + p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion) else - -- disc_width.adjust_stretch = 0 - -- disc_width.adjust_shrink = 0 - end - p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion) - if subtype == first_disc_code then - local cur_p_next = getnext(current) - if getid(cur_p_next) ~= disc_code or getsubtype(cur_p_next) ~= second_disc_code then - report_parbuilders("unsupported disc at location %a",1) + local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre) + disc_width.size = size + active_width.size = active_width.size + size + if checked_expansion then + disc_width.adjust_stretch = adjust_stretch + disc_width.adjust_shrink = adjust_shrink + active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch + active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink else - local pre = getfield(cur_p_next,"pre") - if pre then - local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre) - disc_width.size = disc_width.size + size - if checked_expansion then - disc_width.adjust_stretch = disc_width.adjust_stretch + adjust_stretch - disc_width.adjust_shrink = disc_width.adjust_shrink + adjust_shrink - end - p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, cur_p_next, checked_expansion) - -- - -- I will look into this some day ... comment in linebreak.w says that this fails, - -- maybe this is what Taco means with his comment in the luatex manual. - -- - -- do_one_seven_eight(sub_disc_width_from_active_width); - -- do_one_seven_eight(reset_disc_width); - -- s = vlink_no_break(vlink(current)); - -- add_to_widths(s, line_break_dir, adjust_spacing,disc_width); - -- ext_try_break(...,first_p,vlink(current)); - -- + -- disc_width.adjust_stretch = 0 + -- disc_width.adjust_shrink = 0 + end + p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, current, checked_expansion) + if subtype == firstdisc_code then + local cur_p_next = getnext(current) + if getid(cur_p_next) ~= disc_code or getsubtype(cur_p_next) ~= seconddisc_code then + report_parbuilders("unsupported disc at location %a",1) else - report_parbuilders("unsupported disc at location %a",2) + local pre = getfield(cur_p_next,"pre") + if pre then + local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,pre) + disc_width.size = disc_width.size + size + if checked_expansion then + disc_width.adjust_stretch = disc_width.adjust_stretch + adjust_stretch + disc_width.adjust_shrink = disc_width.adjust_shrink + adjust_shrink + end + p_active, n_active = try_break(actual_pen, hyphenated_code, par, first_p, cur_p_next, checked_expansion) + -- + -- I will look into this some day ... comment in linebreak.w says that this fails, + -- maybe this is what Taco means with his comment in the luatex manual. + -- + -- do_one_seven_eight(sub_disc_width_from_active_width); + -- do_one_seven_eight(reset_disc_width); + -- s = vlink_no_break(vlink(current)); + -- add_to_widths(s, line_break_dir, adjust_spacing,disc_width); + -- ext_try_break(...,first_p,vlink(current)); + -- + else + report_parbuilders("unsupported disc at location %a",2) + end end end + -- beware, we cannot restore to a saved value as the try_break adapts active_width + active_width.size = active_width.size - disc_width.size + if checked_expansion then + active_width.adjust_stretch = active_width.adjust_stretch - disc_width.adjust_stretch + active_width.adjust_shrink = active_width.adjust_shrink - disc_width.adjust_shrink + end end - -- beware, we cannot restore to a saved value as the try_break adapts active_width - active_width.size = active_width.size - disc_width.size + end + if replace then + local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace) + active_width.size = active_width.size + size if checked_expansion then - active_width.adjust_stretch = active_width.adjust_stretch - disc_width.adjust_stretch - active_width.adjust_shrink = active_width.adjust_shrink - disc_width.adjust_shrink + active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch + active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink end end end - if replace then - local size, adjust_stretch, adjust_shrink = add_to_width(line_break_dir,checked_expansion,replace) - active_width.size = active_width.size + size - if checked_expansion then - active_width.adjust_stretch = active_width.adjust_stretch + adjust_stretch - active_width.adjust_shrink = active_width.adjust_shrink + adjust_shrink + elseif id == kern_code then + local s = getsubtype(current) + if s == userkern_code or s == italickern_code then + local v = getnext(current) + -- if par.auto_breaking and getid(v) == glue_code then + if auto_breaking and getid(v) == glue_code then + p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) + end + local active_width = par.active_width + active_width.size = active_width.size + getkern(current) + else + local kern = getkern(current) + if kern ~= 0 then + active_width.size = active_width.size + kern + if checked_expansion and expand_kerns and getsubtype(current) == fontkern_code then + local stretch, shrink = kern_stretch_shrink(current,kern) + if expand_kerns == "stretch" then + active_width.adjust_stretch = active_width.adjust_stretch + stretch + elseif expand_kerns == "shrink" then + active_width.adjust_shrink = active_width.adjust_shrink + shrink + else + active_width.adjust_stretch = active_width.adjust_stretch + stretch + active_width.adjust_shrink = active_width.adjust_shrink + shrink + end + end end end - end - elseif id == kern_code then - local s = getsubtype(current) - if s == userkern_code or s == italickern_code then + elseif id == math_code then + -- par.auto_breaking = getsubtype(current) == endmath_code + auto_breaking = getsubtype(current) == endmath_code local v = getnext(current) - -- if par.auto_breaking and getid(v) == glue_code then + -- if par.auto_breaking and getid(v) == glue_code then if auto_breaking and getid(v) == glue_code then p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) end local active_width = par.active_width - active_width.size = active_width.size + getkern(current) - else - local kern = getkern(current) - if kern ~= 0 then - active_width.size = active_width.size + kern - if checked_expansion and expand_kerns and getsubtype(current) == fontkern_code then - local stretch, shrink = kern_stretch_shrink(current,kern) - if expand_kerns == "stretch" then - active_width.adjust_stretch = active_width.adjust_stretch + stretch - elseif expand_kerns == "shrink" then - active_width.adjust_shrink = active_width.adjust_shrink + shrink - else - active_width.adjust_stretch = active_width.adjust_stretch + stretch - active_width.adjust_shrink = active_width.adjust_shrink + shrink - end - end + active_width.size = active_width.size + getkern(current) -- surround + -- new in luatex + + getwidth(current) + elseif id == rule_code then + active_width.size = active_width.size + getwidth(current) + elseif id == penalty_code then + p_active, n_active = try_break(getpenalty(current), unhyphenated_code, par, first_p, current, checked_expansion) + elseif id == dir_code then + par.line_break_dir = checked_line_dir(dirstack) or par.line_break_dir + elseif id == localpar_code then + par.internal_pen_inter = getfield(current,"pen_inter") + par.internal_pen_broken = getfield(current,"pen_broken") + par.internal_left_box = getfield(current,"box_left") + par.internal_left_box_width = getfield(current,"box_left_width") + par.internal_right_box = getfield(current,"box_right") + par.internal_right_box_width = getfield(current,"box_right_width") + elseif trace_unsupported then + if id == mark_code or id == ins_code or id == adjust_code then + -- skip + else + report_parbuilders("node of type %a found in paragraph",type(id)) end end - elseif id == math_code then --- par.auto_breaking = getsubtype(current) == endmath_code - auto_breaking = getsubtype(current) == endmath_code - local v = getnext(current) --- if par.auto_breaking and getid(v) == glue_code then - if auto_breaking and getid(v) == glue_code then - p_active, n_active = try_break(0, unhyphenated_code, par, first_p, current, checked_expansion) - end - local active_width = par.active_width - active_width.size = active_width.size + getkern(current) -- surround - -- new in luatex - + getwidth(current) - elseif id == rule_code then - active_width.size = active_width.size + getwidth(current) - elseif id == penalty_code then - p_active, n_active = try_break(getpenalty(current), unhyphenated_code, par, first_p, current, checked_expansion) - elseif id == dir_code then - par.line_break_dir = checked_line_dir(dirstack) or par.line_break_dir - elseif id == localpar_code then - par.internal_pen_inter = getfield(current,"pen_inter") - par.internal_pen_broken = getfield(current,"pen_broken") - par.internal_left_box = getfield(current,"box_left") - par.internal_left_box_width = getfield(current,"box_left_width") - par.internal_right_box = getfield(current,"box_right") - par.internal_right_box_width = getfield(current,"box_right_width") - elseif trace_unsupported then - if id == mark_code or id == ins_code or id == adjust_code then - -- skip - else - report_parbuilders("node of type %a found in paragraph",type(id)) - end + current = getnext(current) end - current = getnext(current) - end - if not current then - local p_active, n_active = try_break(eject_penalty, hyphenated_code, par, first_p, current, checked_expansion) - if n_active ~= p_active then - local r = n_active - par.fewest_demerits = awful_badness - repeat -- use local d - if r.id ~= delta_code and r.total_demerits < par.fewest_demerits then - par.fewest_demerits = r.total_demerits - par.best_bet = r - end - r = r.next - until r == p_active - par.best_line = par.best_bet.line_number - local asked_looseness = par.looseness - if asked_looseness == 0 then - return tonode(wrap_up(par)) - end - local r = n_active - local actual_looseness = 0 - -- minimize assignments to par but happens seldom - repeat - if r.id ~= delta_code then - local line_diff = r.line_number - par.best_line - par.line_diff = line_diff - if (line_diff < actual_looseness and asked_looseness <= line_diff) or - (line_diff > actual_looseness and asked_looseness >= line_diff) then - par.best_bet = r - actual_looseness = line_diff + if not current then + local p_active, n_active = try_break(eject_penalty, hyphenated_code, par, first_p, current, checked_expansion) + if n_active ~= p_active then + local r = n_active + par.fewest_demerits = awful_badness + repeat -- use local d + if r.id ~= delta_code and r.total_demerits < par.fewest_demerits then par.fewest_demerits = r.total_demerits - elseif line_diff == actual_looseness and r.total_demerits < par.fewest_demerits then par.best_bet = r - par.fewest_demerits = r.total_demerits end + r = r.next + until r == p_active + par.best_line = par.best_bet.line_number + local asked_looseness = par.looseness + if asked_looseness == 0 then + return wrap_up(par) + end + local r = n_active + local actual_looseness = 0 + -- minimize assignments to par but happens seldom + repeat + if r.id ~= delta_code then + local line_diff = r.line_number - par.best_line + par.line_diff = line_diff + if (line_diff < actual_looseness and asked_looseness <= line_diff) or + (line_diff > actual_looseness and asked_looseness >= line_diff) then + par.best_bet = r + actual_looseness = line_diff + par.fewest_demerits = r.total_demerits + elseif line_diff == actual_looseness and r.total_demerits < par.fewest_demerits then + par.best_bet = r + par.fewest_demerits = r.total_demerits + end + end + r = r.next + until r == p_active + par.best_line = par.best_bet.line_number + if actual_looseness == asked_looseness or par.final_pass then + return wrap_up(par) end - r = r.next - until r == p_active - par.best_line = par.best_bet.line_number - if actual_looseness == asked_looseness or par.final_pass then - return tonode(wrap_up(par)) end end - end - reset_meta(par) -- clean up the memory by removing the break nodes - if not second_pass then - if tracing_paragraphs then - diagnostics.current_pass(par,"secondpass") - end - par.threshold = par.tolerance - par.second_pass = true - par.final_pass = par.emergency_stretch <= 0 - else - if tracing_paragraphs then - diagnostics.current_pass(par,"emergencypass") + reset_meta(par) -- clean up the memory by removing the break nodes + if not second_pass then + if tracing_paragraphs then + diagnostics.current_pass(par,"secondpass") + end + par.threshold = par.tolerance + par.second_pass = true + par.final_pass = par.emergency_stretch <= 0 + else + if tracing_paragraphs then + diagnostics.current_pass(par,"emergencypass") + end + par.background.stretch = par.background.stretch + par.emergency_stretch + par.final_pass = true end - par.background.stretch = par.background.stretch + par.emergency_stretch - par.final_pass = true end + return wrap_up(par) end - return tonode(wrap_up(par)) + end -- standard tex logging .. will be adapted .. @@ -2531,16 +2572,19 @@ do while a do local char, id = isglyph(a) if char then - local font = getfont(a) - if font ~= font_in_short_display then - write(target,tex.fontidentifier(font) .. ' ') - font_in_short_display = font + -- id == font + if id ~= font_in_short_display then + write(target,tex.fontidentifier(id) .. ' ') + font_in_short_display = id end - -- todo: instead of components the split tounicode string - if getsubtype(a) == ligature_code then - font_in_short_display = short_display(target,getcomponents(a),font_in_short_display) + local u = chardata[id][char] + local u = u.unicode or char + if type(u) == "table" then + for i=1,#u do + write(target,utfchar(u[i])) + end else - write(target,utfchar(char)) + write(target,utfchar(u)) end elseif id == disc_code then local pre, post, replace = getdisc(a) @@ -2713,55 +2757,6 @@ do local setnodecolor = nodes.tracers.colors.set - local function glyph_width_height_depth(curdir,pdir,p) - local wd, ht, dp = getwhd(p) - if is_rotated[curdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else - local half = wd / 2 - return ht + dp, half, half - end - elseif is_rotated[pdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else - return ht + dp, wd, 0 -- weird - end - else - if glyphdir_is_equal[curdir][pdir] then - return wd, ht, dp - elseif is_opposite[curdir][pdir] then - return wd, dp, ht - else -- can this happen? - return ht + dp, wd, 0 - end - end - end - - local function pack_width_height_depth(curdir,pdir,p) - local wd, ht, dp = getwhd(p) - if is_rotated[curdir] then - if is_parallel[curdir][pdir] then - local half = (ht + dp) / 2 - return wd, half, half - else -- can this happen? - local half = wd / 2 - return ht + dp, half, half - end - else - if pardir_is_equal[curdir][pdir] then - return wd, ht, dp - elseif is_opposite[curdir][pdir] then - return wd, dp, ht - else -- weird dimensions, can this happen? - return ht + dp, wd, 0 - end - end - end - -- local function xpack(head,width,method,direction,analysis) -- -- -- inspect(analysis) @@ -2776,7 +2771,7 @@ do -- local hlist = new_hlist() -- -- setlist(hlist,head) - -- setdir(hlist,direction or tex.textdir) + -- setdirection(hlist,direction or tex.textdirection) -- setwhd(hlist,width,height,depth) -- -- if delta == 0 then @@ -2889,7 +2884,7 @@ do local hlist = new_hlist() - setdir(hlist,direction) + setdirection(hlist,direction) if head == nil then setwidth(hlist,width) @@ -2942,10 +2937,10 @@ do local char, id = isglyph(current) if char then if cal_expand_ratio then - local currentfont = getfont(current) - if currentfont ~= lastfont then - fontexps = checked_expansion[currentfont] -- a bit redundant for the par line packer - lastfont = currentfont + local font = id -- == font + if font ~= lastfont then + fontexps = checked_expansion[font] -- a bit redundant for the par line packer + lastfont = font end if fontexps then local expansion = fontexps[char] @@ -2958,7 +2953,7 @@ do end end -- use inline - local wd, ht, dp = glyph_width_height_depth(hpack_dir,"TLT",current) -- was TRT ? + local wd, ht, dp = getwhd(current) natural = natural + wd if ht > height then height = ht @@ -2984,7 +2979,7 @@ do end elseif id == disc_code then local subtype = getsubtype(current) - if subtype ~= second_disc_code then + if subtype ~= seconddisc_code then -- todo : local stretch, shrink = char_stretch_shrink(s) local replace = getfield(current,"replace") if replace then @@ -3008,7 +3003,7 @@ do end elseif id == hlist_code or id == vlist_code then local sh = getshift(current) - local wd, ht, dp = pack_width_height_depth(hpack_dir,getdir(current) or hpack_dir,current) -- added: or pack_dir + local wd, ht, dp = getwhd(current) local hs, ds = ht - sh, dp + sh natural = natural + wd if hs > height then @@ -3114,14 +3109,13 @@ do local fontexps, lastfont for i=1,expansion_index do - local g = expansion_stack[i] - local e = 0 - local char = isglyph(g) + local g = expansion_stack[i] + local e = 0 + local char, font = isglyph(g) if char then - local currentfont = getfont(g) - if currentfont ~= lastfont then - fontexps = expansions[currentfont] - lastfont = currentfont + if font ~= lastfont then + fontexps = expansions[font] + lastfont = font end local data = fontexps[char] if trace_expansion then @@ -3133,7 +3127,7 @@ do local stretch, shrink = kern_stretch_shrink(g,kern) e = font_expand_ratio * stretch / 1000 end - setfield(g,"expansion_factor",e) + setexpansion(g,e) end end local tso = total_stretch[order] @@ -3171,14 +3165,13 @@ do local fontexps, lastfont for i=1,expansion_index do - local g = expansion_stack[i] - local e = 0 - local char = isglyph(g) + local g = expansion_stack[i] + local e = 0 + local char, font = isglyph(g) if char then - local currentfont = getfont(g) - if currentfont ~= lastfont then - fontexps = expansions[currentfont] - lastfont = currentfont + if font ~= lastfont then + fontexps = expansions[font] + lastfont = font end local data = fontexps[char] if trace_expansion then @@ -3190,7 +3183,7 @@ do local stretch, shrink = kern_stretch_shrink(g,kern) e = font_expand_ratio * shrink / 1000 end - setfield(g,"expansion_factor",e) + setexpansion(g,e) end end local tso = total_shrink[order] @@ -3214,7 +3207,7 @@ do local overfullrule = tex.overfullrule if fuzz > hfuzz and overfullrule > 0 then -- weird, is always called and no rules shows up - setnext(slide_node_list(list),new_rule(overfullrule,nil,nil,getdir(hlist))) -- todo: find_tail + setnext(slide_node_list(list),new_rule(overfullrule,nil,nil,getdirection(hlist))) -- todo: find_tail end diagnostics.overfull_hbox(hlist,line,-delta) end diff --git a/tex/context/base/mkiv/node-met.lua b/tex/context/base/mkiv/node-met.lua index 12a9256bc..f5db4babd 100644 --- a/tex/context/base/mkiv/node-met.lua +++ b/tex/context/base/mkiv/node-met.lua @@ -68,65 +68,70 @@ end nodes = nodes or { } local nodes = nodes -local nodecodes = nodes.nodecodes - -nodes.tostring = node.tostring or tostring -nodes.copy = node.copy -nodes.copy_node = node.copy -nodes.copy_list = node.copy_list -nodes.delete = node.delete -nodes.dimensions = node.dimensions -nodes.rangedimensions = node.rangedimensions -nodes.end_of_math = node.end_of_math -nodes.flush = node.flush_node -nodes.flush_node = node.flush_node -nodes.flush_list = node.flush_list -nodes.free = node.free -nodes.insert_after = node.insert_after -nodes.insert_before = node.insert_before -nodes.hpack = node.hpack -nodes.new = node.new -nodes.tail = node.tail -nodes.traverse = node.traverse -nodes.traverse_id = node.traverse_id -nodes.traverse_char = node.traverse_char -nodes.slide = node.slide -nodes.vpack = node.vpack -nodes.fields = node.fields -nodes.is_node = node.is_node -nodes.setglue = node.setglue - -nodes.first_glyph = node.first_glyph -nodes.has_glyph = node.has_glyph or node.first_glyph - -nodes.current_attr = node.current_attr -nodes.has_field = node.has_field -nodes.last_node = node.last_node -nodes.usedlist = node.usedlist -nodes.protrusion_skippable = node.protrusion_skippable -nodes.check_discretionaries = node.check_discretionaries -nodes.write = node.write - -nodes.count = node.count -nodes.length = node.length - -nodes.has_attribute = node.has_attribute -nodes.set_attribute = node.set_attribute -nodes.find_attribute = node.find_attribute -nodes.unset_attribute = node.unset_attribute - -nodes.protect_glyph = node.protect_glyph -nodes.protect_glyphs = node.protect_glyphs -nodes.unprotect_glyph = node.unprotect_glyph -nodes.unprotect_glyphs = node.unprotect_glyphs -nodes.kerning = node.kerning -nodes.ligaturing = node.ligaturing -nodes.mlist_to_hlist = node.mlist_to_hlist - -nodes.effective_glue = node.effective_glue -nodes.getglue = node.getglue -nodes.setglue = node.setglue -nodes.is_zero_glue = node.is_zero_glue +local nodecodes = nodes.nodecodes + +nodes.tostring = node.tostring or tostring +nodes.copy = node.copy +nodes.copy_node = node.copy +nodes.copy_list = node.copy_list +nodes.delete = node.delete +nodes.dimensions = node.dimensions +nodes.rangedimensions = node.rangedimensions +nodes.end_of_math = node.end_of_math +nodes.flush = node.flush_node +nodes.flush_node = node.flush_node +nodes.flush_list = node.flush_list +nodes.free = node.free +nodes.insert_after = node.insert_after +nodes.insert_before = node.insert_before +nodes.hpack = node.hpack +nodes.new = node.new +nodes.tail = node.tail +nodes.traverse = node.traverse +nodes.traverse_id = node.traverse_id +nodes.traverse_char = node.traverse_char +nodes.traverse_glyph = node.traverse_glyph +nodes.traverse_list = node.traverse_list +nodes.slide = node.slide +nodes.vpack = node.vpack +nodes.fields = node.fields +nodes.is_node = node.is_node +nodes.setglue = node.setglue +nodes.uses_font = node.uses_font + +nodes.first_glyph = node.first_glyph +nodes.has_glyph = node.has_glyph or node.first_glyph + +nodes.current_attr = node.current_attr +nodes.has_field = node.has_field +nodes.last_node = node.last_node +nodes.usedlist = node.usedlist +nodes.protrusion_skippable = node.protrusion_skippable +nodes.check_discretionaries = node.check_discretionaries +nodes.write = node.write +nodes.flatten_discretionaries = node.flatten_discretionaries + +nodes.count = node.count +nodes.length = node.length + +nodes.has_attribute = node.has_attribute +nodes.set_attribute = node.set_attribute +nodes.find_attribute = node.find_attribute +nodes.unset_attribute = node.unset_attribute + +nodes.protect_glyph = node.protect_glyph +nodes.protect_glyphs = node.protect_glyphs +nodes.unprotect_glyph = node.unprotect_glyph +nodes.unprotect_glyphs = node.unprotect_glyphs +nodes.kerning = node.kerning +nodes.ligaturing = node.ligaturing +nodes.hyphenating = node.hyphenating +nodes.mlist_to_hlist = node.mlist_to_hlist + +nodes.effective_glue = node.effective_glue +nodes.getglue = node.getglue +nodes.setglue = node.setglue +nodes.is_zero_glue = node.is_zero_glue nodes.tonode = function(n) return n end nodes.tonut = function(n) return n end @@ -163,7 +168,7 @@ local n_setlink = node.setlink or -- always -- not that fast but not used often anyway local h = nil for i=1,select("#",...) do - local n = (select(i,...)) + local n = select(i,...) if not n then -- go on elseif h then @@ -621,7 +626,7 @@ local messyhack = table.tohash { -- temporary solution nodecodes.action, } -table.setmetatableindex(keys,function(t,k) +setmetatableindex(keys,function(t,k) local v = (k == "attributelist" or k == nodecodes.attributelist) and { } or getfields(k) if messyhack[k] then for i=1,#v do @@ -638,7 +643,7 @@ table.setmetatableindex(keys,function(t,k) return v end) -table.setmetatableindex(whatsitkeys,function(t,k) +setmetatableindex(whatsitkeys,function(t,k) local v = getfields(whatsit_code,k) if v[ 0] then v[#v+1] = "next" v[ 0] = nil end if v[-1] then v[#v+1] = "prev" v[-1] = nil end @@ -659,46 +664,3 @@ end nodes.keys = keys -- [id][subtype] nodes.fields = nodefields -- (n) - --- for the moment (pre 6380) - -if not nodes.unprotect_glyph then - - local protect_glyph = nodes.protect_glyph - local protect_glyphs = nodes.protect_glyphs - local unprotect_glyph = nodes.unprotect_glyph - local unprotect_glyphs = nodes.unprotect_glyphs - - local getnext = nodes.getnext - local setnext = nodes.setnext - - function nodes.protectglyphs(first,last) - if first == last then - return protect_glyph(first) - elseif last then - local nxt = getnext(last) - setnext(last) - local f, b = protect_glyphs(first) - setnext(last,nxt) - return f, b - else - return protect_glyphs(first) - end - end - - function nodes.unprotectglyphs(first,last) - if first == last then - return unprotect_glyph(first) - elseif last then - local nxt = getnext(last) - setnext(last) - local f, b = unprotect_glyphs(first) - setnext(last,nxt) - return f, b - else - return unprotect_glyphs(first) - end - end - -end - diff --git a/tex/context/base/mkiv/node-mig.lua b/tex/context/base/mkiv/node-mig.lua index b3820a7d8..32b09a186 100644 --- a/tex/context/base/mkiv/node-mig.lua +++ b/tex/context/base/mkiv/node-mig.lua @@ -89,12 +89,11 @@ local function locate(head,first,last,ni,nm) end function nodes.handlers.migrate(head,where) - local done = false if head then if trace_migrations then report_nodes("migration sweep %a",where) end - local current = tonut(head) + local current = head while current do local id = getid(current) -- inserts_too is a temp hack, we should only do them when it concerns @@ -124,13 +123,12 @@ function nodes.handlers.migrate(head,where) setlink(last,n) end setlink(current,first) - done = true current = last end end current = getnext(next) end - return head, done + return head end end diff --git a/tex/context/base/mkiv/node-nut.lua b/tex/context/base/mkiv/node-nut.lua index 3e9a08b48..6a38cca67 100644 --- a/tex/context/base/mkiv/node-nut.lua +++ b/tex/context/base/mkiv/node-nut.lua @@ -96,6 +96,7 @@ local fastcopy = table.fastcopy local nodecodes = nodes.nodecodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist +local glyph_code = nodecodes.glyph local nuts = nodes.nuts or { } nodes.nuts = nuts @@ -126,11 +127,11 @@ nodes.tonut = tonut -- function nuts.reportattr() -- inspect(hash) -- end --- + -- local function track(name) -- local n = 0 --- local f = nuts[name] --- function nuts[name](...) +-- local f = direct[name] +-- direct[name] = function(...) -- n = n + 1 -- if n % 1000 == 0 then -- print(name,n) @@ -138,112 +139,81 @@ nodes.tonut = tonut -- return f(...) -- end -- end --- -- track("getfield") -- helpers -if not direct.getfam then -- LUATEXVERSION < 1.070 - - local getfield = direct.getfield - local setfield = direct.setfield - - direct.getfam = function(n) return getfield(n,"small_fam") end - direct.setfam = function(n,f) setfield(n,"small_fam",f) end - -end - -if not direct.getdirection then - - local getdir = direct.getdir - local setdir = direct.setdir - - direct.getdirection = function(n) - local d = getdir(n) - if d == "TLT" then return 0 end - if d == "+TLT" then return 0, false end - if d == "-TLT" then return 0, true end - if d == "TRT" then return 1 end - if d == "+TRT" then return 1, false end - if d == "-TRT" then return 1, true end - if d == "LTL" then return 2 end - if d == "+LTL" then return 2, false end - if d == "-LTL" then return 2, true end - if d == "RTT" then return 3 end - if d == "+RTT" then return 3, false end - if d == "-RTT" then return 3, true end - end - - direct.setdirection = function(n,d,c) - if d == 0 then if c == true then setdir(n,"-TLT") elseif c == false then setdir(n,"+TLT") else setdir(n,"TLT") end - elseif d == 1 then if c == true then setdir(n,"-TRT") elseif c == false then setdir(n,"+TRT") else setdir(n,"TRT") end - elseif d == 2 then if c == true then setdir(n,"-LTL") elseif c == false then setdir(n,"+LTL") else setdir(n,"LTL") end - elseif d == 3 then if c == true then setdir(n,"-RTT") elseif c == false then setdir(n,"+RTT") else setdir(n,"RTT") end - else if c == true then setdir(n,"-TLT") elseif c == false then setdir(n,"+TLT") else setdir(n,"TLT") end end - end - -end - -local nuts = nodes.nuts - -nuts.tostring = direct.tostring -nuts.copy = direct.copy -nuts.copy_node = direct.copy -nuts.copy_list = direct.copy_list -nuts.delete = direct.delete -nuts.dimensions = direct.dimensions -nuts.rangedimensions = direct.rangedimensions -nuts.end_of_math = direct.end_of_math -nuts.flush = direct.flush_node -nuts.flush_node = direct.flush_node -nuts.flush_list = direct.flush_list -nuts.free = direct.free -nuts.insert_after = direct.insert_after -nuts.insert_before = direct.insert_before -nuts.hpack = direct.hpack -nuts.new = direct.new -nuts.tail = direct.tail -nuts.traverse = direct.traverse -nuts.traverse_id = direct.traverse_id -nuts.traverse_char = direct.traverse_char -nuts.slide = direct.slide -nuts.writable_spec = direct.writable_spec -nuts.vpack = direct.vpack -nuts.is_node = direct.is_node -nuts.is_direct = direct.is_direct -nuts.is_nut = direct.is_direct -nuts.first_glyph = direct.first_glyph -nuts.has_glyph = direct.has_glyph or direct.first_glyph -nuts.count = direct.count -nuts.length = direct.length -nuts.find_attribute = direct.find_attribute -nuts.unset_attribute = direct.unset_attribute - -nuts.current_attr = direct.current_attr -nuts.has_field = direct.has_field -nuts.last_node = direct.last_node -nuts.usedlist = direct.usedlist -nuts.protrusion_skippable = direct.protrusion_skippable -nuts.check_discretionaries = direct.check_discretionaries -nuts.write = direct.write - -nuts.has_attribute = direct.has_attribute -nuts.set_attribute = direct.set_attribute -nuts.unset_attribute = direct.unset_attribute - -nuts.protect_glyph = direct.protect_glyph -nuts.protect_glyphs = direct.protect_glyphs -nuts.unprotect_glyph = direct.unprotect_glyph -nuts.unprotect_glyphs = direct.unprotect_glyphs -nuts.ligaturing = direct.ligaturing -nuts.kerning = direct.kerning - -if not direct.mlist_to_hlist then -- needed +local nuts = nodes.nuts + +nuts.check_discretionaries = direct.check_discretionaries +nuts.copy = direct.copy +nuts.copy_list = direct.copy_list +nuts.copy_node = direct.copy +nuts.count = direct.count +nuts.current_attr = direct.current_attr +nuts.delete = direct.delete +nuts.dimensions = direct.dimensions +nuts.end_of_math = direct.end_of_math +nuts.find_attribute = direct.find_attribute +nuts.first_glyph = direct.first_glyph +nuts.flatten_discretionaries = direct.flatten_discretionaries +nuts.flush = direct.flush_node +nuts.flush_list = direct.flush_list +nuts.flush_node = direct.flush_node +nuts.free = direct.free +nuts.get_synctex_fields = direct.get_synctex_fields +nuts.has_attribute = direct.has_attribute +nuts.has_field = direct.has_field +nuts.has_glyph = direct.has_glyph or direct.first_glyph +nuts.hpack = direct.hpack +nuts.insert_after = direct.insert_after +nuts.insert_before = direct.insert_before +nuts.is_direct = direct.is_direct +nuts.is_node = direct.is_node +nuts.is_nut = direct.is_direct +nuts.kerning = direct.kerning +nuts.hyphenating = direct.hyphenating +nuts.last_node = direct.last_node +nuts.length = direct.length +nuts.ligaturing = direct.ligaturing +nuts.new = direct.new +nuts.protect_glyph = direct.protect_glyph +nuts.protect_glyphs = direct.protect_glyphs +nuts.flush_components = direct.flush_components +nuts.protrusion_skippable = direct.protrusion_skippable +nuts.rangedimensions = direct.rangedimensions +nuts.set_attribute = direct.set_attribute +nuts.set_synctex_fields = direct.set_synctex_fields +nuts.slide = direct.slide +nuts.tail = direct.tail +nuts.tostring = direct.tostring +nuts.traverse = direct.traverse +nuts.traverse_char = direct.traverse_char +nuts.traverse_glyph = direct.traverse_glyph +nuts.traverse_id = direct.traverse_id +nuts.traverse_list = direct.traverse_list +nuts.unprotect_glyph = direct.unprotect_glyph +nuts.unprotect_glyphs = direct.unprotect_glyphs +nuts.unset_attribute = direct.unset_attribute +nuts.unset_attribute = direct.unset_attribute +nuts.usedlist = direct.usedlist +nuts.uses_font = direct.uses_font +nuts.vpack = direct.vpack +nuts.writable_spec = direct.writable_spec +nuts.write = direct.write +nuts.mlist_to_hlist = direct.mlist_to_hlist + +if not nuts.mlist_to_hlist then local n_mlist_to_hlist = node.mlist_to_hlist - function nuts.mlist_to_hlist(head) - return tonode(n_mlist_to_hlist(tonut(head))) + function nuts.mlist_to_hlist(head,...) + if head then + local head = n_mlist_to_hlist(tonode(head),...) + if head then + return tonut(head) + end + end end end @@ -276,6 +246,14 @@ nuts.setdisc = direct.setdisc nuts.getdiscretionary = direct.getdisc nuts.setdiscretionary = direct.setdisc +nuts.getdata = direct.getdata +nuts.setdata = direct.setdata +nuts.getvalue = direct.getdata +nuts.setvalue = direct.setdata + +nuts.getexpansion = direct.getexpansion +nuts.setexpansion = direct.setexpansion + nuts.getwhd = direct.getwhd nuts.setwhd = direct.setwhd nuts.getwidth = direct.getwidth @@ -286,6 +264,8 @@ nuts.getdepth = direct.getdepth nuts.setdepth = direct.setdepth nuts.getshift = direct.getshift nuts.setshift = direct.setshift +nuts.getorientation = direct.getorientation or function() end +nuts.setorientation = direct.setorientation or function() end nuts.getnucleus = direct.getnucleus nuts.setnucleus = direct.setnucleus @@ -726,14 +706,10 @@ nodes.properties = { data = propertydata, } -------.set_properties_mode(true,false) -- shallow copy ... problem: in fonts we then affect the originals too -direct.set_properties_mode(true,true) -- create metatable, slower but needed for font-otj.lua (unless we use an intermediate table) - --- todo: --- --- function direct.set_properties_mode() --- -- we really need the set modes --- end +if direct.set_properties_mode then + direct.set_properties_mode(true,true) -- create metatable, slower but needed for font-otj.lua (unless we use an intermediate table) + function direct.set_properties_mode() end +end -- experimental code with respect to copying attributes has been removed -- as it doesn't pay of (most attributes are only accessed once anyway) @@ -770,8 +746,22 @@ nuts.theprop = function(n) return p end -nodes.setprop = nodes.setproperty -nodes.getprop = nodes.getproperty +nuts.isdone = function(n,k) + local p = propertydata[n] + if not p then + propertydata[n] = { [k] = true } + return false + end + local v = p[k] + if v == nil then + propertydata[n] = { [k] = true } + return false + end + return v +end + +-- nodes.setprop = nodes.setproperty +-- nodes.getprop = nodes.getproperty function nuts.copy_properties(source,target,what) local newprops = propertydata[source] @@ -800,116 +790,3 @@ function nuts.copy_properties(source,target,what) end return newprops -- for checking end - --- here: - -nuts.get_synctex_fields = direct.get_synctex_fields -nuts.set_synctex_fields = direct.set_synctex_fields - --- for now - -nodes.uses_font = nodes.uses_font -nuts.uses_font = direct.uses_font - -if not nuts.uses_font then - - local glyph_code = nodecodes.glyph - local getdisc = nuts.getdisc - local getfont = nuts.getfont - local traverse_id = nuts.traverse_id - local tonut = nodes.tonut - - function nuts.uses_font(n,font) - local pre, post, replace = getdisc(n) - if pre then - -- traverse_char - for n in traverse_id(glyph_code,pre) do - if getfont(n) == font then - return true - end - end - end - if post then - for n in traverse_id(glyph_code,post) do - if getfont(n) == font then - return true - end - end - end - if replace then - for n in traverse_id(glyph_code,replace) do - if getfont(n) == font then - return true - end - end - end - return false - end - - function nodes.uses_font(n,font) - return nuts.uses_font(tonut(n),font) - end - -end - --- for the moment (pre 6380) - -if not nuts.unprotect_glyph then - - local protect_glyph = nuts.protect_glyph - local protect_glyphs = nuts.protect_glyphs - local unprotect_glyph = nuts.unprotect_glyph - local unprotect_glyphs = nuts.unprotect_glyphs - - local getnext = nuts.getnext - local setnext = nuts.setnext - - function nuts.protectglyphs(first,last) - if first == last then - return protect_glyph(first) - elseif last then - local nxt = getnext(last) - setnext(last) - local f, b = protect_glyphs(first) - setnext(last,nxt) - return f, b - else - return protect_glyphs(first) - end - end - - function nuts.unprotectglyphs(first,last) - if first == last then - return unprotect_glyph(first) - elseif last then - local nxt = getnext(last) - setnext(last) - local f, b = unprotect_glyphs(first) - setnext(last,nxt) - return f, b - else - return unprotect_glyphs(first) - end - end - -end - -if LUATEXFUNCTIONALITY < 6384 then -- LUATEXVERSION < 1.070 - - local getfield = nuts.getfield - local setfield = nuts.setfield - - function nuts.getboxglue(n,glue_set,glue_order,glue_sign) - return - getfield(n,"glue_set"), - getfield(n,"glue_order"), - getfield(n,"glue_sign") - end - - function nuts.setboxglue(n,glue_set,glue_order,glue_sign) - setfield(n,"glue_set", glue_set or 0) - setfield(n,"glue_order",glue_order or 0) - setfield(n,"glue_sign", glue_sign or 0) - end - -end diff --git a/tex/context/base/mkiv/node-par.lua b/tex/context/base/mkiv/node-par.lua new file mode 100644 index 000000000..8564c8764 --- /dev/null +++ b/tex/context/base/mkiv/node-par.lua @@ -0,0 +1,48 @@ +if not modules then modules = { } end modules ['node-par'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local starttiming = statistics.starttiming +local stoptiming = statistics.stoptiming + +local sequencers = utilities.sequencers + +-- This are called a lot! + +local actions = nodes.tasks.actions("everypar") + +local function everypar(head) + starttiming(builders) + head = actions(head) + stoptiming(builders) + return head +end + +callbacks.register("insert_local_par",everypar,"after paragraph start") + +local actions = sequencers.new { + name = "newgraf", + arguments = "mode,indented", + returnvalues = "indented", + results = "indented", +} + +sequencers.appendgroup(actions,"before") -- user +sequencers.appendgroup(actions,"system") -- private +sequencers.appendgroup(actions,"after" ) -- user + +local function newgraf(mode,indented) + local runner = actions.runner + if runner then + starttiming(builders) + indent = runner(mode,indented) + stoptiming(builders) + end + return indented +end + +callbacks.register("new_graf",newgraf,"before paragraph start") diff --git a/tex/context/base/mkiv/node-ppt.lua b/tex/context/base/mkiv/node-ppt.lua index 5ebfca87d..485e742b6 100644 --- a/tex/context/base/mkiv/node-ppt.lua +++ b/tex/context/base/mkiv/node-ppt.lua @@ -26,12 +26,14 @@ local getid = nuts.getid local getnext = nuts.getnext local getprev = nuts.getprev local getsubtype = nuts.getsubtype -local getfield = nuts.getfield local getlist = nuts.getlist local setlist = nuts.setlist +local getprop = nuts.getprop + local removenode = nuts.remove -local traverse = nuts.traverse -local traverse_id = nuts.traverse_id + +local nextnode = nuts.traversers.node +local nextwhatsit = nuts.traversers.whatsit local nodecodes = nodes.nodecodes local whatsitcodes = nodes.whatsitcodes @@ -39,18 +41,17 @@ local whatsitcodes = nodes.whatsitcodes local whatsit_code = nodecodes.whatsit local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local userdefined_code = whatsitcodes.userdefined + +local userdefinedwhatsit_code = whatsitcodes.userdefined local nodepool = nodes.pool -local new_usernumber = nodepool.usernumber +local new_usernode = nodepool.usernode local variables = interfaces.variables local v_before = variables.before local v_after = variables.after local v_here = variables.here -local cache = { } -local nofslots = 0 local property_id = nodepool.userids["property"] local properties = nodes.properties @@ -71,15 +72,8 @@ local function register(where,data,...) where = v_after end if data then - local data = { where, data, ... } nofslots = nofslots + 1 - if nofslots > 1 then - cache[nofslots] = data - else - -- report("restarting attacher") - cache = { data } -- also forces collection - end - return new_usernumber(property_id,nofslots) + return new_usernode(property_id,{ where, data, ... }) end end @@ -108,17 +102,9 @@ local f_delayed = formatters["return function(target,head,where,propdata,paren local f_immediate = formatters["return function(target,head,where,propdata) %s end"] local nofdelayed = 0 -- better is to keep track of it per page ... we can have deleted nodes with properties +local nofslots = 0 function actions.delayed(target,head,where,propdata,code,...) -- this one is used at the tex end --- local kind = type(code) --- if kind == "string" then --- code, err = load(f_delayed(code)) --- if code then --- code = code() --- end --- elseif kind ~= "function" then --- code = nil --- end if code then local delayed = propdata.delayed if delayed then @@ -131,15 +117,6 @@ function actions.delayed(target,head,where,propdata,code,...) -- this one is use end function actions.fdelayed(target,head,where,propdata,code,...) -- this one is used at the tex end --- local kind = type(code) --- if kind == "string" then --- code, err = load(f_delayed(code)) --- if code then --- code = code() --- end --- elseif kind ~= "function" then --- code = nil --- end if code then local delayed = propdata.delayed if delayed then @@ -170,81 +147,41 @@ function actions.immediate(target,head,where,propdata,code,...) -- this one is u end end --- another experiment (a table or function closure are equally efficient); a function --- is easier when we want to experiment with different (compatible) implementations - --- local nutpool = nuts.pool --- local nut_usernumber = nutpool.usernumber - --- function nodes.nuts.pool.deferredfunction(...) --- nofdelayed = nofdelayed + 1 --- local n = nut_usernumber(property_id,0) --- propertydata[n] = { deferred = { ... } } --- return n --- end - --- function nodes.nuts.pool.deferredfunction(f) --- nofdelayed = nofdelayed + 1 --- local n = nut_usernumber(property_id,0) --- propertydata[n] = { deferred = f } --- return n --- end - --- maybe actions will get parent too - local function delayed(head,parent) -- direct based - for target in traverse(head) do + for target, id in nextnode, head do local p = propertydata[target] if p then - -- local deferred = p.deferred -- kind of late lua (but too soon as we have no access to pdf.h/v) - -- if deferred then - -- -- if #deferred > 0 then - -- -- deferred[1](unpack(deferred,2)) - -- -- else - -- -- deferred[1]() - -- -- end - -- deferred() - -- p.deferred = false - -- if nofdelayed == 1 then - -- nofdelayed = 0 - -- return head - -- else - -- nofdelayed = nofdelayed - 1 - -- end - -- else - local delayed = p.delayed - if delayed then - for i=1,#delayed do - local d = delayed[i] - local code = d[2] - local kind = type(code) - if kind == "string" then - code, err = load(f_delayed(code)) - if code then - code = code() - end - end - local where = d[1] - if where then - local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent - if h and h ~= head then - head = h - end - else - code(unpack(d,3)) + local delayed = p.delayed + if delayed then + for i=1,#delayed do + local d = delayed[i] + local code = d[2] + local kind = type(code) + if kind == "string" then + code, err = load(f_delayed(code)) + if code then + code = code() end end - p.delayed = nil - if nofdelayed == 1 then - nofdelayed = 0 - return head + local where = d[1] + if where then + local h = code(target,where,head,p,parent,unpack(d,3)) -- target where propdata head parent + if h and h ~= head then + head = h + end else - nofdelayed = nofdelayed - 1 + code(unpack(d,3)) end end - -- end + p.delayed = nil + if nofdelayed == 1 then + nofdelayed = 0 + return head + else + nofdelayed = nofdelayed - 1 + end + end end - local id = getid(target) if id == hlist_code or id == vlist_code then local list = getlist(target) if list then @@ -268,14 +205,13 @@ function properties.delayed(head) -- if nofdelayed > 0 then -- if next(propertydata) then starttiming(properties) - head = delayed(tonut(head)) + head = delayed(head) stoptiming(properties) - return tonode(head), true -- done in shipout anyway -- else -- delayed = 0 - -- end + -- end end - return head, false + return head end -- more explicit ones too @@ -284,7 +220,7 @@ local anchored = { [v_before] = function(n) while n do n = getprev(n) - if getid(n) == whatsit_code and getsubtype(n) == user_code and getfield(n,"user_id") == property_id then + if getid(n) == whatsit_code and getsubtype(n) == user_code and getprop(n,"id") == property_id then -- continue else return n @@ -296,7 +232,7 @@ local anchored = { n = getnext(n) if getid(n) == whatsit_code then local subtype = getsubtype(n) - if (subtype == userdefined_code and getfield(n,"user_id") == property_id) then + if (subtype == userdefinedwhatsit_code and getprop(n,"id") == property_id) then -- continue else return n @@ -320,26 +256,22 @@ end) function properties.attach(head) if nofslots <= 0 then - return head, false + return head end - local done = false local last = nil - local head = tonut(head) starttiming(properties) - for source in traverse_id(whatsit_code,head) do - if getsubtype(source) == userdefined_code then + for source, subtype in nextwhatsit, head do + if subtype == userdefinedwhatsit_code then if last then removenode(head,last,true) last = nil end - if getfield(source,"user_id") == property_id then - local slot = getfield(source,"value") - local data = cache[slot] + if getprop(source,"id") == property_id then + local data = getprop(source,"data") if data then - cache[slot] = nil local where = data[1] local target = anchored[where](source) if target then @@ -393,7 +325,7 @@ function properties.attach(head) target,nodecodes[getid(target)],serialize(propertydata[target],false)) end end - if nofslots == 1 then + if nofslots == 1 then nofslots = 0 last = source break @@ -412,25 +344,22 @@ function properties.attach(head) stoptiming(properties) - return head, done + return head end -local tasks = nodes.tasks - -- maybe better hard coded in-place --- tasks.prependaction("processors","before","nodes.properties.attach") --- tasks.appendaction("shipouts","normalizers","nodes.properties.delayed") - statistics.register("properties processing time", function() return statistics.elapsedseconds(properties) end) -- only for development +-- local tasks = nodes.tasks +-- -- local function show(head,level,report) --- for target in traverse(head) do +-- for target in nextnode, head do -- local p = propertydata[target] -- if p then -- report("level %i, node %i, id %s, data %s", diff --git a/tex/context/base/mkiv/node-pro.lua b/tex/context/base/mkiv/node-pro.lua index 4509bac18..b6b130588 100644 --- a/tex/context/base/mkiv/node-pro.lua +++ b/tex/context/base/mkiv/node-pro.lua @@ -35,7 +35,7 @@ do local n = 0 local function reconstruct(head) -- we probably have a better one - local t, n, h = { }, 0, tonut(head) + local t, n, h = { }, 0, head while h do n = n + 1 local char, id = isglyph(h) @@ -49,7 +49,7 @@ do return concat(t) end - function processors.tracer(what,state,head,groupcode,before,after,show) + function processors.tracer(what,head,groupcode,before,after,show) if not groupcode then groupcode = "unknown" elseif groupcode == "" then @@ -57,16 +57,14 @@ do end n = n + 1 if show then - report_nodes("%s: location %a, state %a, group %a, # before %a, # after %s, stream: %s",what,n,state,groupcode,before,after,reconstruct(head)) + report_nodes("%s: location %a, group %a, # before %a, # after %s, stream: %s",what,n,groupcode,before,after,reconstruct(head)) else - report_nodes("%s: location %a, state %a, group %a, # before %a, # after %s",what,n,state,groupcode,before,after) + report_nodes("%s: location %a, group %a, # before %a, # after %s",what,n,groupcode,before,after) end end end -local tracer = processors.tracer - processors.enabled = true -- this will become a proper state (like trackers) do @@ -74,154 +72,131 @@ do local has_glyph = nodes.has_glyph local count_nodes = nodes.countall - function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction + local texget = tex.get + + local tracer = processors.tracer + + local function pre_linebreak_filter(head,groupcode) local found = force_processors or has_glyph(head) if found then if trace_callbacks then local before = count_nodes(head,true) - local head, done = actions(head,groupcode) -- ,size,packtype,direction + head = actions(head,groupcode) local after = count_nodes(head,true) - if done then - tracer("pre_linebreak","changed",head,groupcode,before,after,true) - else - tracer("pre_linebreak","unchanged",head,groupcode,before,after,true) - end - return done and head or true + tracer("pre_linebreak",head,groupcode,before,after,true) else - local head, done = actions(head,groupcode) -- ,size,packtype,direction - return done and head or true + head = actions(head,groupcode) end elseif trace_callbacks then local n = count_nodes(head,false) - tracer("pre_linebreak","no chars",head,groupcode,n,n) + tracer("pre_linebreak",head,groupcode,n,n) end - return true + return head end local function hpack_filter(head,groupcode,size,packtype,direction,attributes) local found = force_processors or has_glyph(head) if found then + -- + -- yes or no or maybe an option + -- + if not direction then + direction = texget("textdir") + end + -- if trace_callbacks then local before = count_nodes(head,true) - local head, done = actions(head,groupcode,size,packtype,direction,attributes) + head = actions(head,groupcode,size,packtype,direction,attributes) local after = count_nodes(head,true) - if done then - tracer("hpack","changed",head,groupcode,before,after,true) - else - tracer("hpack","unchanged",head,groupcode,before,after,true) - end - return done and head or true + tracer("hpack",head,groupcode,before,after,true) else - local head, done = actions(head,groupcode,size,packtype,direction,attributes) - return done and head or true + head = actions(head,groupcode,size,packtype,direction,attributes) end elseif trace_callbacks then local n = count_nodes(head,false) - tracer("hpack","no chars",head,groupcode,n,n) + tracer("hpack",head,groupcode,n,n) end - return true + return head end - processors.hpack_filter = hpack_filter + processors.pre_linebreak_filter = pre_linebreak_filter + processors.hpack_filter = hpack_filter do - local setfield = nodes.setfield - local hpack = nodes.hpack + local hpack = nodes.hpack function nodes.fullhpack(head,...) - local ok = hpack_filter(head) - if not done or done == true then - ok = head - end - local hp, b = hpack(ok,...) - setfield(hp,"prev",nil) - setfield(hp,"next",nil) - return hp, b + return hpack((hpack_filter(head)),...) end end do - local setboth = nuts.setboth - local hpack = nuts.hpack + local hpack = nuts.hpack function nuts.fullhpack(head,...) - local ok = hpack_filter(tonode(head)) - if not done or done == true then - ok = head - else - ok = tonut(ok) - end - local hp, b = hpack(...) - setboth(hp) - return hp, b + return hpack(tonut(hpack_filter(tonode(head))),...) end end - callbacks.register('pre_linebreak_filter', processors.pre_linebreak_filter, "all kind of horizontal manipulations (before par break)") - callbacks.register('hpack_filter' , processors.hpack_filter, "all kind of horizontal manipulations (before hbox creation)") + callbacks.register('pre_linebreak_filter', pre_linebreak_filter, "horizontal manipulations (before par break)") + callbacks.register('hpack_filter' , hpack_filter, "horizontal manipulations (before hbox creation)") end do + -- Beware, these are packaged boxes so no first_glyph test needed. Maybe some day I'll add a hash + -- with valid groupcodes. Watch out, much can pass twice, for instance vadjust passes two times, local actions = tasks.actions("finalizers") -- head, where local count_nodes = nodes.countall - -- beware, these are packaged boxes so no first_glyph test - -- maybe some day a hash with valid groupcodes - -- - -- beware, much can pass twice, for instance vadjust passes two times - -- - -- something weird here .. group mvl when making a vbox + local tracer = processors.tracer - function processors.post_linebreak_filter(head,groupcode) + local function post_linebreak_filter(head,groupcode) if trace_callbacks then local before = count_nodes(head,true) - local head, done = actions(head,groupcode) + head = actions(head,groupcode) local after = count_nodes(head,true) - if done then - tracer("post_linebreak","changed",head,groupcode,before,after,true) - else - tracer("post_linebreak","unchanged",head,groupcode,before,after,true) - end - return done and head or true + tracer("post_linebreak",head,groupcode,before,after,true) else - local head, done = actions(head,groupcode) - return done and head or true + head = actions(head,groupcode) end + return head end - callbacks.register('post_linebreak_filter', processors.post_linebreak_filter,"all kind of horizontal manipulations (after par break)") + processors.post_linebreak_filter = post_linebreak_filter + + callbacks.register("post_linebreak_filter", post_linebreak_filter,"horizontal manipulations (after par break)") end do - local texnest = tex.nest + local texnest = tex.nest - local getlist = nodes.getlist - local setlist = nodes.setlist - local getsubtype = nodes.getsubtype + local getlist = nodes.getlist + local setlist = nodes.setlist + local getsubtype = nodes.getsubtype - local line_code = nodes.listcodes.line + local linelist_code = nodes.listcodes.line - local actions = tasks.actions("contributers") + local actions = tasks.actions("contributers") function processors.contribute_filter(groupcode) if groupcode == "box" then -- "pre_box" local whatever = texnest[texnest.ptr] if whatever then local line = whatever.tail - if line and getsubtype(line) == line_code then + if line and getsubtype(line) == linelist_code then local head = getlist(line) if head then - local okay, done = actions(head,groupcode,line) - if okay and okay ~= head then - setlist(line,okay) + local result = actions(head,groupcode,line) + if result and result ~= head then + setlist(line,result) end end end @@ -229,7 +204,7 @@ do end end - callbacks.register('contribute_filter', processors.contribute_filter,"things done with lines") + callbacks.register("contribute_filter", processors.contribute_filter,"things done with lines") end diff --git a/tex/context/base/mkiv/node-ref.lua b/tex/context/base/mkiv/node-ref.lua index 1ec77e83d..e12bd95bd 100644 --- a/tex/context/base/mkiv/node-ref.lua +++ b/tex/context/base/mkiv/node-ref.lua @@ -67,21 +67,25 @@ local getattr = nuts.getattr local setattr = nuts.setattr local getsubtype = nuts.getsubtype local getwhd = nuts.getwhd -local getdir = nuts.getdir +local getdirection = nuts.getdirection local setshift = nuts.setshift local getboxglue = nuts.getboxglue local hpack_list = nuts.hpack local vpack_list = nuts.vpack -local list_dimensions = nuts.dimensions -local list_rangedimensions = nuts.rangedimensions +local getdimensions = nuts.dimensions +local getrangedimensions = nuts.rangedimensions local traverse = nuts.traverse local find_node_tail = nuts.tail local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local listcodes = nodes.listcodes +local dirvalues = nodes.dirvalues +local lefttoright_code = dirvalues.lefttoright +local righttoleft_code = dirvalues.righttoleft + local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local glue_code = nodecodes.glue @@ -90,11 +94,11 @@ local rule_code = nodecodes.rule local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local leftskip_code = skipcodes.leftskip -local rightskip_code = skipcodes.rightskip -local parfillskip_code = skipcodes.parfillskip +local leftskip_code = gluecodes.leftskip +local rightskip_code = gluecodes.rightskip +local parfillskip_code = gluecodes.parfillskip -local line_code = listcodes.line +----- linelist_code = listcodes.line local new_rule = nodepool.rule local new_kern = nodepool.kern @@ -113,9 +117,9 @@ local implement = interfaces.implement local function hlist_dimensions(start,stop,parent) local last = stop and getnext(stop) if parent then - return list_rangedimensions(parent,start,last) + return getrangedimensions(parent,start,last) else - return list_dimensions(start,last) + return getdimensions(start,last) end end @@ -250,11 +254,13 @@ local function dimensions(parent,start,stop) -- in principle we could move some end end --- is pardir important at all? - local function inject_range(head,first,last,reference,make,stack,parent,pardir,txtdir) local width, height, depth, line = dimensions(parent,first,last) - if txtdir == "+TRT" or (txtdir == "===" and pardir == "TRT") then -- KH: textdir == "===" test added + if txtdir == righttoleft_code then + width = - width + elseif textdir == lefttoright_code then + -- go on + elseif pardir == righttoleft_code then width = - width end local result, resolved = make(width,height,depth,reference) @@ -264,7 +270,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t local l = getlist(line) if trace_areas then report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","line", - reference,pardir or "---",txtdir or "---", + reference,pardir or "?",txtdir or "?", tosequence(l,nil,true),width,height,depth) end setlist(line,result) @@ -273,7 +279,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t elseif head == first then if trace_areas then report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","head", - reference,pardir or "---",txtdir or "---", + reference,pardir or "?",txtdir or "?", tosequence(first,last,true),width,height,depth) end setlink(result,first) @@ -281,7 +287,7 @@ local function inject_range(head,first,last,reference,make,stack,parent,pardir,t else if trace_areas then report_area("%s: %i : %s %s %s => w=%p, h=%p, d=%p","middle", - reference,pardir or "---",txtdir or "---", + reference,pardir or "?",txtdir or "?", tosequence(first,last,true),width,height,depth) end if first == last and getid(parent) == vlist_code and getid(first) == hlist_code then @@ -306,7 +312,7 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) local correction = 0 local moveright = false local first = getlist(current) - if id == hlist_code then -- box_code line_code + if id == hlist_code then -- boxlist_code linelist_code -- can be either an explicit hbox or a line and there is no way -- to recognize this; anyway only if ht/dp (then inline) local sr = stack[reference] @@ -337,7 +343,7 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) correction = height + depth height, depth = depth, height -- ugly hack, needed because pdftex backend does something funny end - if pardir == "TRT" then + if pardir == righttoleft_code then width = - width end local result, resolved = make(width,height,depth,reference) @@ -345,7 +351,7 @@ local function inject_list(id,current,reference,make,stack,pardir,txtdir) if result and resolved then if trace_areas then report_area("%s: %04i %s %s %s: w=%p, h=%p, d=%p, c=%S","box", - reference,pardir or "---",txtdir or "----","[]",width,height,depth,resolved) + reference,pardir or "?",txtdir or "?","[]",width,height,depth,resolved) end if not first then setlist(current,result) @@ -370,12 +376,6 @@ end local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main local first, last, firstdir, reference - if not pardir then - pardir = "===" - end - if not texdir then - txtdir = "===" - end local current = head while current do local id = getid(current) @@ -404,8 +404,8 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx end local list = getlist(current) if list then - local h, ok - h, ok, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) + local h + h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) if h ~= current then setlist(current,h) end @@ -416,9 +416,12 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left? -- elseif id == dir_code then - txtdir = getdir(current) - elseif id == localpar_code then -- only test at begin - pardir = getdir(current) + local direction, pop = getdirection(current) + txtdir = not pop and direction -- we might need a stack + elseif id == localpar_code then + if getsubtype(current) == 0 then + pardir = getdirection(current) + end else local r = getattr(current,attribute) if not r then @@ -441,46 +444,183 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx if reference and (done[reference] or 0) == 0 then head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) end - return head, true, pardir, txtdir + return head, pardir, txtdir end --- local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular ! --- if not pardir then --- pardir = "===" --- end --- if not texdir then --- txtdir = "===" +-- -- not faster either: +-- +-- local findattr = node.direct.find_attribute +-- +-- local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main +-- local first, last, firstdir, reference +-- local someatt = findattr(head,attribute) +-- if someatt then +-- local current = head +-- while current do +-- local id = getid(current) +-- if id == hlist_code or id == vlist_code then +-- local r = getattr(current,attribute) +-- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)] +-- -- test \goto{\TeX}[page(2)] test \gotobox{\hbox {x} \hbox {x}}[page(2)] +-- -- if r and (not skip or r >) skip then -- maybe no > test +-- -- inject_list(id,current,r,make,stack,pardir,txtdir) +-- -- end +-- if r then +-- if not reference then +-- reference, first, last, firstdir = r, current, current, txtdir +-- elseif r == reference then +-- -- same link +-- last = current +-- elseif (done[reference] or 0) == 0 then +-- if not skip or r > skip then -- maybe no > test +-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- reference, first, last, firstdir = nil, nil, nil, nil +-- end +-- else +-- reference, first, last, firstdir = r, current, current, txtdir +-- end +-- done[r] = (done[r] or 0) + 1 +-- end +-- local list = getlist(current) +-- if list then +-- local h +-- h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) +-- if h ~= current then +-- setlist(current,h) +-- end +-- end +-- if r then +-- done[r] = done[r] - 1 +-- end +-- elseif id == dir_code then +-- local direction, pop = getdirection(current) +-- txtdir = not pop and direction -- we might need a stack +-- elseif id == localpar_code then -- only test at begin +-- pardir = getdirection(current) +-- elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left? +-- -- +-- else +-- local r = getattr(current,attribute) +-- if not r then +-- -- just go on, can be kerns +-- elseif not reference then +-- reference, first, last, firstdir = r, current, current, txtdir +-- elseif r == reference then +-- last = current +-- elseif (done[reference] or 0) == 0 then -- or id == glue_code and getsubtype(current) == right_skip_code +-- if not skip or r > skip then -- maybe no > test +-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- reference, first, last, firstdir = nil, nil, nil, nil +-- end +-- else +-- reference, first, last, firstdir = r, current, current, txtdir +-- end +-- end +-- current = getnext(current) +-- end +-- if reference and (done[reference] or 0) == 0 then +-- head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- end +-- else +-- local current = head +-- while current do +-- local id = getid(current) +-- if id == hlist_code or id == vlist_code then +-- local list = getlist(current) +-- if list then +-- local h = inject_areas(list,attribute,make,stack,done,skip or 0,current,pardir,txtdir) +-- if h ~= current then +-- setlist(current,h) +-- end +-- end +-- elseif id == dir_code then +-- local direction, pop = getdirection(current) +-- txtdir = not pop and direction -- we might need a stack +-- elseif id == localpar_code then -- only test at begin +-- pardir = getdirection(current) +-- end +-- current = getnext(current) +-- end -- end +-- return head, pardir, txtdir +-- end + +-- -- maybe first check for glyphs and use a goto: +-- +-- local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main +-- local first, last, firstdir, reference -- local current = head -- while current do -- local id = getid(current) --- if id == hlist_code or id == vlist_code then --- local r = getattr(current,attribute) --- if r and not done[r] then --- done[r] = true --- inject_list(id,current,r,make,stack,pardir,txtdir) +-- local r -- else scope message due to goto +-- if id == glyph_code then +-- goto rest +-- elseif id == hlist_code or id == vlist_code then +-- r = getattr(current,attribute) +-- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)] +-- -- test \goto{\TeX}[page(2)] test \gotobox{\hbox {x} \hbox {x}}[page(2)] +-- -- if r and (not skip or r >) skip then -- maybe no > test +-- -- inject_list(id,current,r,make,stack,pardir,txtdir) +-- -- end +-- if r then +-- if not reference then +-- reference, first, last, firstdir = r, current, current, txtdir +-- elseif r == reference then +-- -- same link +-- last = current +-- elseif (done[reference] or 0) == 0 then +-- if not skip or r > skip then -- maybe no > test +-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- reference, first, last, firstdir = nil, nil, nil, nil +-- end +-- else +-- reference, first, last, firstdir = r, current, current, txtdir +-- end +-- done[r] = (done[r] or 0) + 1 -- end -- local list = getlist(current) -- if list then --- local h = inject_area(list,attribute,make,stack,done,current,pardir,txtdir) +-- local h +-- h, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) -- if h ~= current then -- setlist(current,h) -- end -- end +-- if r then +-- done[r] = done[r] - 1 +-- end +-- elseif id == glue_code and getsubtype(current) == leftskip_code then -- any glue at the left? +-- -- -- elseif id == dir_code then --- txtdir = getdir(current) --- elseif id == localpar_code then --- pardir = getdir(current) --- else --- local r = getattr(current,attribute) --- if r and not done[r] then --- done[r] = true --- head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir) +-- local direction, pop = getdirection(current) +-- txtdir = not pop and direction -- we might need a stack +-- elseif id == localpar_code then -- only test at begin +-- pardir = getdirection(current) +-- end +-- goto next +-- ::rest:: +-- r = getattr(current,attribute) +-- if not r then +-- -- just go on, can be kerns +-- elseif not reference then +-- reference, first, last, firstdir = r, current, current, txtdir +-- elseif r == reference then +-- last = current +-- elseif (done[reference] or 0) == 0 then -- or id == glue_code and getsubtype(current) == right_skip_code +-- if not skip or r > skip then -- maybe no > test +-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- reference, first, last, firstdir = nil, nil, nil, nil -- end +-- else +-- reference, first, last, firstdir = r, current, current, txtdir -- end +-- ::next:: -- current = getnext(current) -- end --- return head, true +-- if reference and (done[reference] or 0) == 0 then +-- head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- end +-- return head, pardir, txtdir -- end -- tracing: todo: use predefined colors @@ -595,11 +735,11 @@ nodes.references = { -- todo: get rid of n (n is just a number, can be used for tracing, obsolete) -local function setreference(h,d,r) +local function setreference(h,d,r) -- h and d can be nil topofstack = topofstack + 1 -- the preroll permits us to determine samepage (but delayed also has some advantages) -- so some part of the backend work is already done here - stack[topofstack] = { r, h, d, codeinjections.prerollreference(r) } + stack[topofstack] = { r, h or false, d or false, codeinjections.prerollreference(r) } -- texsetattribute(attribute,topofstack) -- todo -> at tex end texsetcount("lastreferenceattribute",topofstack) end @@ -615,7 +755,11 @@ local function makereference(width,height,depth,reference) -- height and depth a if trace_references then report_reference("resolving attribute %a",reference) end - local resolved, ht, dp, set, n = sr[1], sr[2], sr[3], sr[4], sr[5] + local resolved = sr[1] + local ht = sr[2] + local dp = sr[3] + local set = sr[4] + local n = sr[5] -- logs.report("temp","child: ht=%p dp=%p, parent: ht=%p dp=%p",ht,dp,height,depth) if ht then if height < ht then height = ht end @@ -672,11 +816,9 @@ end function nodes.references.handler(head) if head and topofstack > 0 then - local head = tonut(head) - local head, done = inject_areas(head,attribute,makereference,stack,done) - return tonode(head), done + return (inject_areas(head,attribute,makereference,stack,done)) else - return head, false + return head end end @@ -706,7 +848,11 @@ local function makedestination(width,height,depth,reference) if trace_destinations then report_destination("resolving attribute %a",reference) end - local resolved, ht, dp, name, view = sr[1], sr[2], sr[3], sr[4], sr[5] -- sr[4] will change to just internal + local resolved = sr[1] + local ht = sr[2] + local dp = sr[3] + local name = sr[4] + local view = sr[5] if ht then if height < ht then height = ht end if depth < dp then depth = dp end @@ -783,21 +929,12 @@ local function makedestination(width,height,depth,reference) end end --- function nodes.destinations.handler(head) --- if head and topofstack > 0 then --- return inject_area(head,attribute,makedestination,stack,done) -- singular --- else --- return head, false --- end --- end function nodes.destinations.handler(head) if head and topofstack > 0 then - local head = tonut(head) - local head, done = inject_areas(head,attribute,makedestination,stack,done) - return tonode(head), done + return (inject_areas(head,attribute,makedestination,stack,done)) else - return head, false + return head end end @@ -907,15 +1044,3 @@ statistics.register("interactive elements", function() return nil end end) - -function references.enableinteraction() - enableaction("shipouts","nodes.references.handler") - enableaction("shipouts","nodes.destinations.handler") - function references.enableinteraction() end -end - -implement { - name = "enableinteraction", - actions = references.enableinteraction, - onlyonce = true -} diff --git a/tex/context/base/mkiv/node-res.lua b/tex/context/base/mkiv/node-res.lua index a6211e80e..d9999968a 100644 --- a/tex/context/base/mkiv/node-res.lua +++ b/tex/context/base/mkiv/node-res.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['node-res'] = { license = "see context related readme files" } +local type, next = type, next local gmatch, format = string.gmatch, string.format --[[ldx-- @@ -13,34 +14,39 @@ local gmatch, format = string.gmatch, string.format for debugging node management.

--ldx]]-- -local report_nodes = logs.reporter("nodes","housekeeping") - local nodes, node = nodes, node -nodes.pool = nodes.pool or { } -local nodepool = nodes.pool +local report_nodes = logs.reporter("nodes","housekeeping") -local whatsitcodes = nodes.whatsitcodes -local skipcodes = nodes.skipcodes -local kerncodes = nodes.kerncodes -local rulecodes = nodes.rulecodes -local nodecodes = nodes.nodecodes -local gluecodes = nodes.gluecodes -local boundarycodes = nodes.boundarycodes -local usercodes = nodes.usercodes +nodes.pool = nodes.pool or { } +local nodepool = nodes.pool -local glyph_code = nodecodes.glyph +local whatsitcodes = nodes.whatsitcodes +local gluecodes = nodes.gluecodes +local kerncodes = nodes.kerncodes +local rulecodes = nodes.rulecodes +local nodecodes = nodes.nodecodes +local leadercodes = nodes.leadercodes +local boundarycodes = nodes.boundarycodes +local usercodes = nodes.usercodes -local allocate = utilities.storage.allocate +local nodeproperties = nodes.properties.data -local texgetcount = tex.getcount +local glyph_code = nodecodes.glyph +local rule_code = nodecodes.rule +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local whatsit_code = nodecodes.whatsit -local reserved, nofreserved = { }, 0 +local currentfont = font.current +local texgetcount = tex.getcount --- user nodes +local allocate = utilities.storage.allocate -local userids = allocate() -local lastid = 0 +local reserved = { } +local nofreserved = 0 +local userids = allocate() +local lastid = 0 setmetatable(userids, { __index = function(t,k) @@ -89,6 +95,9 @@ local setwidth = nuts.setwidth local setsubtype = nuts.setsubtype local setleader = nuts.setleader +local setdata = nuts.setdata +local setvalue = nuts.setvalue + local copy_nut = nuts.copy local new_nut = nuts.new local flush_nut = nuts.flush @@ -147,68 +156,68 @@ nutpool.register = register_node -- could be register_nut -- so far -local disc = register_nut(new_nut("disc")) -local kern = register_nut(new_nut("kern",kerncodes.userkern)) -local fontkern = register_nut(new_nut("kern",kerncodes.fontkern)) -local italickern = register_nut(new_nut("kern",kerncodes.italiccorrection)) -local penalty = register_nut(new_nut("penalty")) -local glue = register_nut(new_nut("glue")) -- glue.spec = nil -local glue_spec = register_nut(new_nut("glue_spec")) -local glyph = register_nut(new_nut("glyph",0)) +local disc = register_nut(new_nut(nodecodes.disc)) +local kern = register_nut(new_nut(kern_code,kerncodes.userkern)) +local fontkern = register_nut(new_nut(kern_code,kerncodes.fontkern)) +local italickern = register_nut(new_nut(kern_code,kerncodes.italiccorrection)) +local penalty = register_nut(new_nut(nodecodes.penalty)) +local glue = register_nut(new_nut(glue_code)) -- glue.spec = nil +local glue_spec = register_nut(new_nut(nodecodes.gluespec)) +local glyph = register_nut(new_nut(glyph_code,0)) -local textdir = register_nut(new_nut("dir")) +local textdir = register_nut(new_nut(nodecodes.dir)) -local latelua = register_nut(new_nut("whatsit",whatsitcodes.latelua)) -local special = register_nut(new_nut("whatsit",whatsitcodes.special)) +local latelua = register_nut(new_nut(whatsit_code,whatsitcodes.latelua)) +local savepos = register_nut(new_nut(whatsit_code,whatsitcodes.savepos)) -local user_node = new_nut("whatsit",whatsitcodes.userdefined) +local user_node = new_nut(whatsit_code,whatsitcodes.userdefined) -local user_number = register_nut(copy_nut(user_node)) setfield(user_number, "type",usercodes.number) -local user_nodes = register_nut(copy_nut(user_node)) setfield(user_nodes, "type",usercodes.node) -local user_string = register_nut(copy_nut(user_node)) setfield(user_string, "type",usercodes.string) -local user_tokens = register_nut(copy_nut(user_node)) setfield(user_tokens, "type",usercodes.token) ------ user_lua = register_nut(copy_nut(user_node)) setfield(user_lua, "type",usercodes.lua) -- in > 0.95 -local user_attributes = register_nut(copy_nut(user_node)) setfield(user_attributes,"type",usercodes.attribute) +if CONTEXTLMTXMODE < 2 then + setfield(user_node,"type",usercodes.number) +end -local left_margin_kern = register_nut(new_nut("margin_kern",0)) -local right_margin_kern = register_nut(new_nut("margin_kern",1)) +local left_margin_kern = register_nut(new_nut(nodecodes.marginkern,0)) +local right_margin_kern = register_nut(new_nut(nodecodes.marginkern,1)) -local lineskip = register_nut(new_nut("glue",skipcodes.lineskip)) -local baselineskip = register_nut(new_nut("glue",skipcodes.baselineskip)) -local leftskip = register_nut(new_nut("glue",skipcodes.leftskip)) -local rightskip = register_nut(new_nut("glue",skipcodes.rightskip)) +local lineskip = register_nut(new_nut(glue_code,gluecodes.lineskip)) +local baselineskip = register_nut(new_nut(glue_code,gluecodes.baselineskip)) +local leftskip = register_nut(new_nut(glue_code,gluecodes.leftskip)) +local rightskip = register_nut(new_nut(glue_code,gluecodes.rightskip)) -local temp = register_nut(new_nut("temp",0)) +local temp = register_nut(new_nut(nodecodes.temp,0)) -local noad = register_nut(new_nut("noad")) -local delimiter = register_nut(new_nut("delim")) -local fence = register_nut(new_nut("fence")) -local submlist = register_nut(new_nut("sub_mlist")) -local accent = register_nut(new_nut("accent")) -local radical = register_nut(new_nut("radical")) -local fraction = register_nut(new_nut("fraction")) -local subbox = register_nut(new_nut("sub_box")) -local mathchar = register_nut(new_nut("math_char")) -local mathtextchar = register_nut(new_nut("math_text_char")) -local choice = register_nut(new_nut("choice")) +local noad = register_nut(new_nut(nodecodes.noad)) +local delimiter = register_nut(new_nut(nodecodes.delim)) +local fence = register_nut(new_nut(nodecodes.fence)) +local submlist = register_nut(new_nut(nodecodes.submlist)) +local accent = register_nut(new_nut(nodecodes.accent)) +local radical = register_nut(new_nut(nodecodes.radical)) +local fraction = register_nut(new_nut(nodecodes.fraction)) +local subbox = register_nut(new_nut(nodecodes.subbox)) +local mathchar = register_nut(new_nut(nodecodes.mathchar)) +local mathtextchar = register_nut(new_nut(nodecodes.mathtextchar)) +local choice = register_nut(new_nut(nodecodes.choice)) -local boundary = register_nut(new_nut("boundary",boundarycodes.user)) -local wordboundary = register_nut(new_nut("boundary",boundarycodes.word)) +local boundary = register_nut(new_nut(nodecodes.boundary,boundarycodes.user)) +local wordboundary = register_nut(new_nut(nodecodes.boundary,boundarycodes.word)) -local cleader = register_nut(copy_nut(glue)) setsubtype(cleader,gluecodes.cleaders) setglue(cleader,0,65536,0,2,0) +local cleader = register_nut(copy_nut(glue)) setsubtype(cleader,leadercodes.cleaders) setglue(cleader,0,65536,0,2,0) -- the dir field needs to be set otherwise crash: -local rule = register_nut(new_nut("rule")) setdir(rule, "TLT") -local emptyrule = register_nut(new_nut("rule",rulecodes.empty)) setdir(rule, "TLT") -local userrule = register_nut(new_nut("rule",rulecodes.user)) setdir(rule, "TLT") -local hlist = register_nut(new_nut("hlist")) setdir(hlist,"TLT") -local vlist = register_nut(new_nut("vlist")) setdir(vlist,"TLT") +local lefttoright_code = nodes.dirvalues.lefttoright + +local rule = register_nut(new_nut(rule_code)) setdirection(rule, lefttoright_code) +local emptyrule = register_nut(new_nut(rule_code,rulecodes.empty)) setdirection(rule, lefttoright_code) +local userrule = register_nut(new_nut(rule_code,rulecodes.user)) setdirection(rule, lefttoright_code) +local outlinerule = register_nut(new_nut(rule_code,rulecodes.outline)) setdirection(rule, lefttoright_code) +local hlist = register_nut(new_nut(nodecodes.hlist)) setdirection(hlist,lefttoright_code) +local vlist = register_nut(new_nut(nodecodes.vlist)) setdirection(vlist,lefttoright_code) function nutpool.glyph(fnt,chr) local n = copy_nut(glyph) if fnt then - setfont(n,fnt,chr) + setfont(n,fnt == true and currentfont() or fnt,chr) elseif chr then setchar(n,chr) end @@ -234,7 +243,7 @@ end function nutpool.boundary(v) local n = copy_nut(boundary) if v and v ~= 0 then - setfield(n,"value",v) + setvalue(n,v) end return n end @@ -242,7 +251,7 @@ end function nutpool.wordboundary(v) local n = copy_nut(wordboundary) if v and v ~= 0 then - setfield(n,"value",v) + setvalue(n,v) end return n end @@ -335,7 +344,7 @@ function nutpool.disc(pre,post,replace) return d end -function nutpool.textdir(dir) +function nutpool.textdir(dir) -- obsolete ! local t = copy_nut(textdir) if dir then setdir(t,dir) @@ -355,35 +364,49 @@ function nutpool.direction(dir,swap) return t end -function nutpool.rule(width,height,depth,dir) -- w/h/d == nil will let them adapt +function nutpool.rule(width,height,depth,direction) -- w/h/d == nil will let them adapt local n = copy_nut(rule) if width or height or depth then setwhd(n,width,height,depth) end - if dir then - setdir(n,dir) + if direction then + setdirection(n,direction) end return n end -function nutpool.emptyrule(width,height,depth,dir) -- w/h/d == nil will let them adapt +function nutpool.emptyrule(width,height,depth,direction) -- w/h/d == nil will let them adapt local n = copy_nut(emptyrule) if width or height or depth then setwhd(n,width,height,depth) end - if dir then - setdir(n,dir) + if direction then + setdirection(n,direction) end return n end -function nutpool.userrule(width,height,depth,dir) -- w/h/d == nil will let them adapt +function nutpool.userrule(width,height,depth,direction) -- w/h/d == nil will let them adapt local n = copy_nut(userrule) if width or height or depth then setwhd(n,width,height,depth) end - if dir then - setdir(n,dir) + if direction then + setdirection(n,direction) + end + return n +end + +function nutpool.outlinerule(width,height,depth,line,direction) -- w/h/d == nil will let them adapt + local n = copy_nut(outlinerule) + if width or height or depth then + setwhd(n,width,height,depth) + end + if line then + setfield(n,"transform",line) + end + if direction then + setdirection(n,direction) end return n end @@ -399,13 +422,32 @@ function nutpool.leader(width,list) return n end -function nutpool.latelua(code) - local n = copy_nut(latelua) - setfield(n,"string",code) - return n +function nutpool.savepos() + return copy_nut(savepos) end -nutpool.lateluafunction = nutpool.latelua +if CONTEXTLMTXMODE > 1 then + + function nutpool.latelua(code) + local n = copy_nut(latelua) + nodeproperties[n] = { data = code } + return n + end + +else + + function nutpool.latelua(code) + local n = copy_nut(latelua) + if type(code) == "table" then + local action = code.action + local specification = code.specification or code + code = function() action(specification) end + end + setdata(n,code) + return n + end + +end function nutpool.leftmarginkern(glyph,width) local n = copy_nut(left_margin_kern) @@ -494,86 +536,21 @@ function nodepool.vlist(list,width,height,depth,shift) return tonode(new_vlist(list and tonut(list),width,height,depth,shift)) end --- local num = userids["my id"] --- local str = userids[num] - -function nutpool.usernumber(id,num) - local n = copy_nut(user_number) - if num then - setfield(n,"user_id",id) - setfield(n,"value",num) - elseif id then - setfield(n,"value",id) - end - return n -end - -function nutpool.userlist(id,list) - local n = copy_nut(user_nodes) - if list then - setfield(n,"user_id",id) - setfield(n,"value",list) - else - setfield(n,"value",id) - end - return n -end - -function nutpool.userstring(id,str) - local n = copy_nut(user_string) - if str then - setfield(n,"user_id",id) - setfield(n,"value",str) - else - setfield(n,"value",id) - end - return n -end - -function nutpool.usertokens(id,tokens) - local n = copy_nut(user_tokens) - if tokens then - setfield(n,"user_id",id) - setfield(n,"value",tokens) - else - setfield(n,"value",id) - end - return n -end - -function nutpool.userlua(id,code) - local n = copy_nut(user_lua) - if code then - setfield(n,"user_id",id) - setfield(n,"value",code) - else - setfield(n,"value",id) - end - return n -end - -function nutpool.userattributes(id,attr) - local n = copy_nut(user_attributes) - if attr then - setfield(n,"user_id",id) - setfield(n,"value",attr) - else - setfield(n,"value",id) - end - return n -end - -function nutpool.special(str) - local n = copy_nut(special) - setfield(n,"data",str) +function nutpool.usernode(id,data) + local n = copy_nut(user_node) + nodeproperties[n] = { + id = id, + data = data, + } return n end -- housekeeping local function cleanup(nofboxes) -- todo - if nodes.tracers.steppers then -- to be resolved - nodes.tracers.steppers.reset() -- todo: make a registration subsystem + local tracers = nodes.tracers + if tracers and tracers.steppers then -- to be resolved + tracers.steppers.reset() -- todo: make a registration subsystem end local nl = 0 local nr = nofreserved @@ -624,3 +601,45 @@ statistics.register("node memory usage", function() -- comes after cleanup ! end) lua.registerfinalizer(cleanup, "cleanup reserved nodes") + +-- experiment + +do + + local glyph = tonode(glyph) + local traverse_id = nodes.traverse_id + + local traversers = table.setmetatableindex(function(t,k) + local v = traverse_id(type(k) == "number" and k or nodecodes[k],glyph) + t[k] = v + return v + end) + + traversers.node = nodes.traverse (glyph) + traversers.char = nodes.traverse_char (glyph) + if nuts.traverse_glyph then traversers.glyph = nodes.traverse_glyph(glyph) end + if nuts.traverse_list then traversers.list = nodes.traverse_list (glyph) end + + nodes.traversers = traversers + +end + +do + + local glyph = glyph + local traverse_id = nuts.traverse_id + + local traversers = table.setmetatableindex(function(t,k) + local v = traverse_id(type(k) == "number" and k or nodecodes[k],glyph) + t[k] = v + return v + end) + + traversers.node = nuts.traverse (glyph) + traversers.char = nuts.traverse_char (glyph) + if nuts.traverse_glyph then traversers.glyph = nuts.traverse_glyph(glyph) end + if nuts.traverse_list then traversers.list = nuts.traverse_list (glyph) end + + nuts.traversers = traversers + +end diff --git a/tex/context/base/mkiv/node-rul.lua b/tex/context/base/mkiv/node-rul.lua index 2b0368c2b..ea0e5c7a0 100644 --- a/tex/context/base/mkiv/node-rul.lua +++ b/tex/context/base/mkiv/node-rul.lua @@ -37,18 +37,20 @@ local setlink = nuts.setlink local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid -local getdir = nuts.getdir +local getdirection = nuts.getdirection local getattr = nuts.getattr local setattr = nuts.setattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getlist = nuts.getlist local setwhd = nuts.setwhd -local setdir = nuts.setdir local setattrlist = nuts.setattrlist local setshift = nuts.setshift local getwidth = nuts.getwidth local setwidth = nuts.setwidth +local setfield = nuts.setfield + +local isglyph = nuts.isglyph local flushlist = nuts.flush_list local effective_glue = nuts.effective_glue @@ -56,17 +58,16 @@ local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local find_tail = nuts.tail local setglue = nuts.setglue -local traverse_id = nuts.traverse_id -local list_dimensions = nuts.rangedimensions +local getrangedimensions = nuts.rangedimensions local hpack_nodes = nuts.hpack -local current_attr = nuts.current_attr local copy_list = nuts.copy_list +local nexthlist = nuts.traversers.hlist + local nodecodes = nodes.nodecodes local rulecodes = nodes.rulecodes local gluecodes = nodes.gluecodes local listcodes = nodes.listcodes -local kerncodes = nodes.kerncodes local glyph_code = nodecodes.glyph local localpar_code = nodecodes.localpar @@ -74,8 +75,8 @@ local dir_code = nodecodes.dir local glue_code = nodecodes.glue local hlist_code = nodecodes.hlist -local indent_code = listcodes.indent -local line_code = listcodes.line +local indentlist_code = listcodes.indent +local linelist_code = listcodes.line local leftskip_code = gluecodes.leftskip local rightskip_code = gluecodes.rightskip @@ -121,8 +122,8 @@ local setmetatableindex = table.setmetatableindex -- -local striprange = nodes.striprange -local processwords = nodes.processwords +local striprange = nuts.striprange +local processwords = nuts.processwords -- @@ -144,7 +145,7 @@ local function usernutrule(t,noattributes) if noattributes == false or noattributes == nil then -- avoid fuzzy ones else - setattrlist(r,current_attr()) + setattrlist(r,true) end properties[r] = t return r @@ -156,9 +157,11 @@ local function userrule(t,noattributes) return tonode(usernutrule(t,noattributes)) end -rules.userrule = userrule -local ruleactions = { } -rules.ruleactions = ruleactions +rules.userrule = userrule +local ruleactions = { } + +rules .ruleactions = ruleactions +nutrules.ruleactions = ruleactions -- convenient local function mathradical(n,h,v) ----- size = getfield(n,"index") @@ -203,18 +206,18 @@ local subtypeactions = { [rulecodes.radical] = mathradical, } -callbacks.register( - "process_rule", - function(n,h,v) - local n = tonut(n) - local s = getsubtype(n) - local a = subtypeactions[s] - if a then - a(n,h,v) - end - end, - "handle additional user rule features" -) +local function process_rule(n,h,v) + local n = tonut(n) + local s = getsubtype(n) + local a = subtypeactions[s] + if a then + a(n,h,v) + end +end + +callbacks.register("process_rule",process_rule,"handle additional user rule features") + +callbacks.functions.process_rule = process_rule -- @@ -239,9 +242,9 @@ end local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose local font = nil - local id = getid(f) - if id == glyph_code then - font = getfont(f) + local char, id = isglyph(f) + if char then + font = id elseif id == hlist_code then font = getattr(f,a_runningtext) end @@ -263,7 +266,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a if not f then return head end - local w, ht, dp = list_dimensions(parent,f,getnext(l)) + local w, ht, dp = getrangedimensions(parent,f,getnext(l)) local method = d.method local empty = d.empty == v_yes local offset = d.offset @@ -331,7 +334,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a end end if mp and mp ~= "" then - local r = userrule { + local r = usernutrule { width = w, height = ht, depth = dp, @@ -344,16 +347,17 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a ca = color, ta = transparency, } - inject(tonut(r),w,ht,dp) + inject(r,w,ht,dp) else local tx = d.text if tx then - tx = copy_list(tx) + local l = copy_list(tx) if d["repeat"] == v_yes then - tx = new_leader(w,tx) + l = new_leader(w,l) + setattrlist(l,tx) end - local r = hpack_nodes(tx,w,"exactly") - inject(r,w,ht,dp) + l = hpack_nodes(l,w,"exactly") + inject(l,w,ht,dp) else for i=1,level do local ht = (offset+(i-1)*dy)*e + rulethickness - m @@ -373,10 +377,8 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a return head end -local process = nodes.processwords - rules.handler = function(head) - return process(a_ruled,data,flush_ruled,head) + return processwords(a_ruled,data,flush_ruled,head) end function rules.enable() @@ -409,7 +411,7 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha local next = getnext(last) setprev(first) setnext(last) - local width, height, depth = list_dimensions(parent,first,next) + local width, height, depth = getrangedimensions(parent,first,next) local list = hpack_nodes(first,width,"exactly") -- we can use a simple pack if first == head then head = list @@ -429,9 +431,9 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha return head end -local process = nodes.processwords - -nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end +nodes.shifts.handler = function(head) + return processwords(a_shifted,data,flush_shifted,head) +end function nodes.shifts.enable() enableaction("shipouts","nodes.shifts.handler") @@ -459,7 +461,7 @@ local function linefiller(current,data,width,location) local ca = data.ca local ta = data.ta if mp and mp ~= "" then - return tonut(userrule { + return usernutrule { width = width, height = height, depth = depth, @@ -470,18 +472,56 @@ local function linefiller(current,data,width,location) ca = ca, ta = ta, option = location, - direction = getdir(current), - }) + direction = getdirection(current), + } else - local linefiller = new_rule(width,height,depth) + local rule = new_rule(width,height,depth) if ca then - setattr(linefiller,a_colorspace,ma) - setattr(linefiller,a_color,ca) + setattr(rule,a_colorspace,ma) + setattr(rule,a_color,ca) end if ta then - setattr(linefiller,a_transparency,ta) + setattr(rule,a_transparency,ta) + end + return rule + end +end + +function nodes.linefillers.filler(current,data,width,height,depth) + if width and width > 0 then + local height = height or data.height or 0 + local depth = depth or data.depth or 0 + if (height + depth) ~= 0 then + local mp = data.mp + local ma = data.ma + local ca = data.ca + local ta = data.ta + if mp and mp ~= "" then + return usernutrule { + width = width, + height = height, + depth = depth, + type = "mp", + line = data.rulethickness, + data = mp, + ma = ma, + ca = ca, + ta = ta, + option = location, + direction = getdirection(current), + } + else + local rule = new_rule(width,height,depth) + if ca then + setattr(rule,a_colorspace,ma) + setattr(rule,a_color,ca) + end + if ta then + setattr(rule,a_transparency,ta) + end + return rule + end end - return linefiller end end @@ -496,119 +536,115 @@ local function find_attr(head,attr) end function nodes.linefillers.handler(head) --- local current = tonut(head) -- when we hook into the contributers - for current in traverse_id(hlist_code,tonut(head)) do - if getsubtype(current) == line_code then - local list = getlist(current) - if list then - -- why doesn't leftskip take the attributes - -- or list[linefiller] or maybe first match (maybe we need a fast helper for that) - local a = getattr(current,a_linefiller) - if a then - local class = a % 1000 - local data = data[class] - if data then - local location = data.location - local scope = data.scope - local distance = data.distance - local threshold = data.threshold - local leftlocal = false - local rightlocal = false - -- - if scope == v_right then - leftlocal = true - elseif scope == v_left then - rightlocal = true - elseif scope == v_local then - leftlocal = true - rightlocal = true - end - -- - if location == v_left or location == v_both then - local lskip = nil -- leftskip - local iskip = nil -- indentation - local head = list - while head do - local id = getid(head) - if id == glue_code then - if getsubtype(head) == leftskip_code then - lskip = head - else - break - end - elseif id == localpar_code or id == dir_code then - -- go on - elseif id == hlist_code then - if getsubtype(head) == indent_code then - iskip = head - end - break + for current, subtype, list in nexthlist, head do + if list and subtype == linelist_code then + -- why doesn't leftskip take the attributes + -- or list[linefiller] or maybe first match (maybe we need a fast helper for that) + local a = getattr(current,a_linefiller) + if a then + local class = a % 1000 + local data = data[class] + if data then + local location = data.location + local scope = data.scope + local distance = data.distance + local threshold = data.threshold + local leftlocal = false + local rightlocal = false + -- + if scope == v_right then + leftlocal = true + elseif scope == v_left then + rightlocal = true + elseif scope == v_local then + leftlocal = true + rightlocal = true + end + -- + if location == v_left or location == v_both then + local lskip = nil -- leftskip + local iskip = nil -- indentation + local head = list + while head do + local id = getid(head) + if id == glue_code then + if getsubtype(head) == leftskip_code then + lskip = head else break end - head = getnext(head) + elseif id == localpar_code or id == dir_code then + -- go on + elseif id == hlist_code then + if getsubtype(head) == indentlist_code then + iskip = head + end + break + else + break end - if head then - local indentation = iskip and getwidth(iskip) or 0 - local leftfixed = lskip and getwidth(lskip) or 0 - local lefttotal = lskip and effective_glue(lskip,current) or 0 - local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance - if width > threshold then - if iskip then - setwidth(iskip,0) + head = getnext(head) + end + if head then + local indentation = iskip and getwidth(iskip) or 0 + local leftfixed = lskip and getwidth(lskip) or 0 + local lefttotal = lskip and effective_glue(lskip,current) or 0 + local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance + if width > threshold then + if iskip then + setwidth(iskip,0) + end + if lskip then + setglue(lskip,leftlocal and getwidth(lskip) or nil) + if distance > 0 then + insert_node_after(list,lskip,new_kern(distance)) end - if lskip then - setglue(lskip,leftlocal and getwidth(lskip) or nil) - if distance > 0 then - insert_node_after(list,lskip,new_kern(distance)) - end - insert_node_after(list,lskip,linefiller(current,data,width,"left")) - else - insert_node_before(list,head,linefiller(current,data,width,"left")) - if distance > 0 then - insert_node_before(list,head,new_kern(distance)) - end + insert_node_after(list,lskip,linefiller(current,data,width,"left")) + else + insert_node_before(list,head,linefiller(current,data,width,"left")) + if distance > 0 then + insert_node_before(list,head,new_kern(distance)) end end end end - -- - if location == v_right or location == v_both then - local pskip = nil -- parfillskip - local rskip = nil -- rightskip - local tail = find_tail(list) - while tail and getid(tail) == glue_code do - local subtype = getsubtype(tail) - if subtype == rightskip_code then - rskip = tail - elseif subtype == parfillskip_code then - pskip = tail - else - break - end - tail = getprev(tail) + end + -- + if location == v_right or location == v_both then + local pskip = nil -- parfillskip + local rskip = nil -- rightskip + local tail = find_tail(list) + while tail and getid(tail) == glue_code do + local subtype = getsubtype(tail) + if subtype == rightskip_code then + rskip = tail + elseif subtype == parfillskip_code then + pskip = tail + else + break end - if tail then - local rightfixed = rskip and getwidth(rskip) or 0 - local righttotal = rskip and effective_glue(rskip,current) or 0 - local parfixed = pskip and getwidth(pskip) or 0 - local partotal = pskip and effective_glue(pskip,current) or 0 - local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance - if width > threshold then - if pskip then - setglue(pskip) + tail = getprev(tail) + end + if tail then + local rightfixed = rskip and getwidth(rskip) or 0 + local righttotal = rskip and effective_glue(rskip,current) or 0 + local parfixed = pskip and getwidth(pskip) or 0 + local partotal = pskip and effective_glue(pskip,current) or 0 + local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance + if width > threshold then + if pskip then + setglue(pskip) + end + if rskip then + setglue(rskip,rightlocal and getwidth(rskip) or nil) + if distance > 0 then + insert_node_before(list,rskip,new_kern(distance)) end - if rskip then - setglue(rskip,rightlocal and getwidth(rskip) or nil) - if distance > 0 then - insert_node_before(list,rskip,new_kern(distance)) - end - insert_node_before(list,rskip,linefiller(current,data,width,"right")) - else - insert_node_after(list,tail,linefiller(current,data,width,"right")) - if distance > 0 then - insert_node_after(list,tail,new_kern(distance)) - end + insert_node_before(list,rskip,linefiller(current,data,width,"right")) + else + insert_node_after(list,tail,linefiller(current,data,width,"right")) + if distance > 0 then + insert_node_after(list,tail,new_kern(distance)) end end end @@ -708,3 +744,35 @@ implement { onlyonce = true, actions = nodes.linefillers.enable } + +-- We add a bonus feature here: + +interfaces.implement { + name = "autorule", + arguments = { + { + { "width", "dimension" }, + { "height", "dimension" }, + { "depth", "dimension" }, + { "left", "dimension" }, + { "right", "dimension" }, + }, + }, + actions = function(t) + local l = t.left + local r = t.right + local n = new_rule( + t.width, + t.height, + t.depth + ) + setattrlist(n,true) + if l then + setfield(n,"left",l) + end + if r then + setfield(n,"right",r) + end + context(tonode(n)) + end +} diff --git a/tex/context/base/mkiv/node-rul.mkiv b/tex/context/base/mkiv/node-rul.mkiv index 643e93c42..19f398eb9 100644 --- a/tex/context/base/mkiv/node-rul.mkiv +++ b/tex/context/base/mkiv/node-rul.mkiv @@ -71,7 +71,7 @@ %definesystemattribute[ruled] %definesystemattribute[shifted] -\registerctxluafile{node-rul}{} +\registerctxluafile{node-rul}{optimize} \installcorenamespace{bar} \installcorenamespace{barindex} @@ -146,6 +146,8 @@ {\node_rules_set{#1}\barparameter\c!left}% {\relax\barparameter\c!right}} +% store in properties + \unexpanded\def\node_rules_set#1% maybe reverse the 1000 (also maybe use more attributes instead of settings) {\edef\currentbar{#1}% \usebarstyleandcolor\c!foregroundstyle\c!foregroundcolor @@ -571,4 +573,39 @@ \c!distance=.25\emwidth, \c!rulethickness=.25\exheight] +%D Bonus: +%D +%D \starttyping +%D \startuseMPgraphic{foo} +%D fill unitsquare +%D xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8) +%D shifted (-ExHeight/8,ExHeight/16) +%D withcolor RuleColor ; +%D \stopuseMPgraphic +%D +%D \definelinefiller[foo][mp=foo,color=darkred] +%D +%D \linefillerhbox[foo]{OEPS} +%D \stoptyping + +\unexpanded\def\node_backgrounds_filler_box#1#2[#3]% + {\bgroup + \clf_enablebackgroundboxes + \dowithnextbox{% + \node_linefiller_set{#3}% already sets the attribute + #1% + attr \backgroundattribute \plusone + % attr \linefillerattribute \the\attribute\linefillerattribute + {\box\nextbox}% + \egroup}% + #2} + +\unexpanded\def\linefillerhbox{\node_backgrounds_filler_box\hpack\hbox} +\unexpanded\def\linefillervbox{\node_backgrounds_filler_box\vpack\vbox} +\unexpanded\def\linefillervtop{\node_backgrounds_filler_box\tpack\vtop} + +%D Bonus: + +\unexpanded\def\autorule{\clf_autorule} + \protect \endinput diff --git a/tex/context/base/mkiv/node-scn.lua b/tex/context/base/mkiv/node-scn.lua index b294b3013..a40a5271a 100644 --- a/tex/context/base/mkiv/node-scn.lua +++ b/tex/context/base/mkiv/node-scn.lua @@ -12,8 +12,6 @@ local attributes = attributes local nodes = nodes local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut local getnext = nuts.getnext local getprev = nuts.getprev @@ -26,9 +24,8 @@ local setlist = nuts.setlist local end_of_math = nuts.end_of_math local nodecodes = nodes.nodecodes -local rulecodes = nodes.rulecodes +local leadercodes = nodes.leadercodes local gluecodes = nodes.gluecodes -local listcodes = nodes.listcodes local kerncodes = nodes.kerncodes local glyph_code = nodecodes.glyph @@ -46,7 +43,8 @@ local vlist_code = nodecodes.vlist local userskip_code = gluecodes.userskip local spaceskip_code = gluecodes.spaceskip local xspaceskip_code = gluecodes.xspaceskip -local leader_code = gluecodes.leaders + +local leaders_code = leadercodes.leaders local fontkern_code = kerncodes.fontkern @@ -97,7 +95,7 @@ local function striprange(first,last) -- todo: dir return first, last end -nodes.striprange = striprange +nuts.striprange = striprange -- todo: order and maybe other dimensions @@ -205,7 +203,7 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl elseif id == glue_code then -- catch \underbar{a} \underbar{a} (subtype test is needed) local subtype = getsubtype(n) - if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leader_code)) then + if getattr(n,attribute) and (subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code or (leaders and subtype >= leaders_code)) then l = n else head, done = flush(head,f,l,d,level,parent,strip), true @@ -228,17 +226,11 @@ local function processwords(attribute,data,flush,head,parent,skip) -- we have hl end end -nodes.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir - head = tonut(head) - if parent then - parent = tonut(parent) - end - local head, done = processwords(attribute,data,flush,head,parent) - return tonode(head), done +nuts.processwords = function(attribute,data,flush,head,parent) -- we have hlistdir and local dir + return processwords(attribute,data,flush,head,parent) end -- works on lines ! - -- todo: stack because skip can change when nested local function processranges(attribute,flush,head,parent,depth,skip) @@ -319,11 +311,6 @@ local function processranges(attribute,flush,head,parent,depth,skip) end end -nodes.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir - head = tonut(head) - if parent then - parent = tonut(parent) - end - local head, done = processranges(attribute,flush,head,parent,0) - return tonode(head), done +nuts.processranges = function(attribute,flush,head,parent) -- we have hlistdir and local dir + return processranges(attribute,flush,head,parent,0) end diff --git a/tex/context/base/mkiv/node-ser.lua b/tex/context/base/mkiv/node-ser.lua index 7ed2b8d00..6fc2b7ea4 100644 --- a/tex/context/base/mkiv/node-ser.lua +++ b/tex/context/base/mkiv/node-ser.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['node-ser'] = { -- beware, some field names will change in a next releases -- of luatex; this is pretty old code that needs an overhaul -local type = type +local type, tostring = type, tostring local concat, tohash, sortedkeys, printtable, serialize = table.concat, table.tohash, table.sortedkeys, table.print, table.serialize local formatters, format, rep = string.formatters, string.format, string.rep @@ -24,16 +24,17 @@ local is_node = nodes.is_node local nodecodes = nodes.nodecodes local subtcodes = nodes.codes -local noadcodes = nodes.noadcodes local getfields = nodes.fields local tonode = nodes.tonode +local tonut = nodes.tonut local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist ----- utfchar = utf.char local f_char = formatters["%U"] +local f_attr = formatters["<%i>"] ----- fontchars = { } table.setmetatableindex(fontchars,function(t,k) fontchars = fonts.hashes.characters return fontchars[k] end) ----- f_char = utilities.strings.chkuni -- formatters["%!chkuni!"] @@ -87,7 +88,7 @@ local ignore = allocate ( tohash { local dimension = allocate ( tohash { "width", "height", "depth", "shift", "stretch", "shrink", - "xoffset", "yoffset", "xadvance", + "xoffset", "yoffset", "surround", "kern", "box_left_width", "box_right_width" @@ -145,6 +146,7 @@ local function totable(n,flat,verbose,noattributes) -- nicest: n,true,true,true if ignore[v] then -- skip elseif noattributes and v == "attr" then + tt[v] = f_attr(tonut(nv)) -- skip elseif v == "prev" then tt[v] = "" diff --git a/tex/context/base/mkiv/node-shp.lua b/tex/context/base/mkiv/node-shp.lua index 2e7a3529a..306e38f6a 100644 --- a/tex/context/base/mkiv/node-shp.lua +++ b/tex/context/base/mkiv/node-shp.lua @@ -13,50 +13,51 @@ local format = string.format local concat, sortedpairs = table.concat, table.sortedpairs local setmetatableindex = table.setmetatableindex -local nodecodes = nodes.nodecodes -local whatsitcodes = nodes.whatsitcodes -local disccodes = nodes.disccodes +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes +local disccodes = nodes.disccodes -local tasks = nodes.tasks -local handlers = nodes.handlers +local tasks = nodes.tasks +local handlers = nodes.handlers -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local disc_code = nodecodes.disc -local whatsit_code = nodecodes.whatsit +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local whatsit_code = nodecodes.whatsit -local fulldisc_code = disccodes.discretionary +local discretionarydisc_code = disccodes.discretionary -local texgetbox = tex.getbox +local implement = interfaces.implement -local implement = interfaces.implement +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode +local remove_node = nuts.remove -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode -local remove_node = nuts.remove -local traverse_nodes = nuts.traverse +local nextnode = nuts.traversers.node -local setfield = nuts.setfield -local setlink = nuts.setlink -local setprev = nuts.setprev -local setnext = nuts.setnext -local getid = nuts.getid -local getdisc = nuts.getdisc -local getboth = nuts.getboth -local getnext = nuts.getnext -local getlist = nuts.getlist -local getsubtype = nuts.getsubtype +local setfield = nuts.setfield +local setlink = nuts.setlink +local setprev = nuts.setprev +local setnext = nuts.setnext +local getid = nuts.getid +local getdisc = nuts.getdisc +local getboth = nuts.getboth +local getnext = nuts.getnext +local getlist = nuts.getlist +local getsubtype = nuts.getsubtype -local setlist = nuts.setlist +local setlist = nuts.setlist -local removables = { +local getbox = nuts.getbox + +local removables = { [whatsitcodes.open] = true, [whatsitcodes.close] = true, [whatsitcodes.write] = true, [whatsitcodes.savepos] = true, [whatsitcodes.latelua] = true, - [whatsitcodes.pdfdest] = true, + -- [whatsitcodes.pdfdest] = true, } -- About 10% of the nodes make no sense for the backend. By (at least) @@ -72,7 +73,7 @@ local function cleanup_redundant(head) -- better name is: flatten_page while start do local id = getid(start) if id == disc_code then - if getsubtype(start) == fulldisc_code then + if getsubtype(start) == discretionarydisc_code then local _, _, replace, _, _ tail = getdisc(start,true) if replace then local prev, next = getboth(start) @@ -117,6 +118,8 @@ local function cleanup_redundant(head) -- better name is: flatten_page return head end +handlers.cleanuppage = cleanup_redundant -- nut + local function cleanup_flushed(head) -- rough local start = head while start do @@ -143,26 +146,20 @@ local function cleanup_flushed(head) -- rough return head end -function handlers.cleanuppage(head) - return tonode(cleanup_redundant(tonut(head))), true -end - -function handlers.cleanupbox(head) - return tonode(cleanup_flushed(tonut(head))), true +function handlers.cleanupbox(box) + cleanup_flushed(getbox(box)) end local actions = tasks.actions("shipouts") -function handlers.finalize(head,where) -- problem, attr loaded before node, todo ... - return actions(head,where) +function handlers.finalizebox(box) + actions(getbox(box)) -- nut end --- handlers.finalize = actions - -- interface -implement { name = "cleanupbox", actions = { texgetbox, cleanup_flushed }, arguments = "integer" } -implement { name = "finalizebox", actions = { texgetbox, actions }, arguments = "integer" } +implement { name = "cleanupbox", actions = handlers.cleanupbox, arguments = "integer" } +implement { name = "finalizebox", actions = handlers.finalizebox, arguments = "integer" } -- just in case we want to optimize lookups: @@ -192,8 +189,7 @@ local function count(head,data,subcategory) -- no components, pre, post, replace .. can maybe an option .. but -- we use this for optimization so it makes sense to look the the -- main node only - for n in traverse_nodes(tonut(head)) do - local id = getid(n) + for n, id in nextnode, tonut(head) do local dn = data[nodecodes[id]] -- we could use id and then later convert to nodecodes dn[subcategory] = dn[subcategory] + 1 if id == hlist_code or id == vlist_code then diff --git a/tex/context/base/mkiv/node-syn.lua b/tex/context/base/mkiv/node-syn.lua index 9d716c44a..a00dc65ec 100644 --- a/tex/context/base/mkiv/node-syn.lua +++ b/tex/context/base/mkiv/node-syn.lua @@ -24,7 +24,16 @@ if not modules then modules = { } end modules ['node-syn'] = { -- I only tested SumatraPDF with SciTE, for which one needs to configure in the -- viewer: -- --- InverseSearchCmdLine = c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l" $ +-- InverseSearchCmdLine = c:\data\system\scite\wscite\scite.exe "%f" "-goto:%l" $ +-- +-- In fact, a way more powerful implementation would have been not to add a library +-- to a viewer, but letthe viewer call an external program: +-- +-- InverseSearchCmdLine = mtxrun.exe --script synctex --edit --name="%f" --line="%l" $ +-- +-- which would (re)launch the editor in the right spot. That way we can really +-- tune well to the macro package used and also avoid the fuzzy heuristics of +-- the library. -- -- Unfortunately syntex always removes the files at the end and not at the start -- (this happens in synctexterminate) so we need to work around that by using an @@ -124,10 +133,9 @@ local openfile, renamefile, removefile = io.open, os.rename, os.remove local report_system = logs.reporter("system") local tex = tex +local texget = tex.get local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getid = nuts.getid local getlist = nuts.getlist @@ -168,14 +176,9 @@ local set_synctex_tag = tex.set_synctex_tag local force_synctex_tag = tex.force_synctex_tag local force_synctex_line = tex.force_synctex_line ----- get_synctex_tag = tex.get_synctex_tag ------ get_synctex_line = tex.get_synctex_line +local get_synctex_line = tex.get_synctex_line local set_synctex_mode = tex.set_synctex_mode -local getpos = function() - getpos = backends.codeinjections.getpos - return getpos() - end - local foundintree = resolvers.foundintree local eol = "\010" @@ -199,6 +202,8 @@ local f_vlist_2 = formatters["v%i,%i:%i,%s:%i,%i,%i\010"] local synctex = luatex.synctex or { } luatex.synctex = synctex +local getpos ; getpos = function() getpos = job.positions.getpos return getpos() end + -- status stuff local enabled = false @@ -268,6 +273,34 @@ function synctex.resetfilename() end end +do + + local nesting = 0 + local ignored = false + + function synctex.pushline() + nesting = nesting + 1 + if nesting == 1 then + local l = get_synctex_line() + ignored = l and l > 0 + if not ignored then + force_synctex_line(texget("inputlineno")) + end + end + end + + function synctex.popline() + if nesting == 1 then + if not ignored then + force_synctex_line() + ignored = false + end + end + nesting = nesting - 1 + end + +end + -- the node stuff local filehandle = nil @@ -324,6 +357,7 @@ end function synctex.wrapup() if tmpfile then renamefile(tmpfile,logfile) + tmpfile = nil end end @@ -340,9 +374,15 @@ local function flushpostamble() enabled = false end +local getpagedimensions getpagedimensions = function() + getpagedimensions = backends.codeinjections.getpagedimensions + return getpagedimensions() +end + -- local function doaction(action,t,l,w,h,d) +-- local pagewidth, pageheight = getpagedimensions() -- local x, y = getpos() --- filehandle:write(action(t,l,x,tex.pageheight-y,w,h,d)) +-- filehandle:write(action(t,l,x,pageheight-y,w,h,d)) -- nofobjects = nofobjects + 1 -- end -- @@ -378,24 +418,27 @@ end -- generic -- -- local function doaction(t,l,w,h,d) +-- local pagewidth, pageheight = getpagedimensions() -- local x, y = getpos() --- filehandle:write(f_hlist_1(t,l,x,tex.pageheight-y,w,h,d)) +-- filehandle:write(f_hlist_1(t,l,x,pageheight-y,w,h,d)) -- nofobjects = nofobjects + 1 -- end local x_hlist do local function doaction_1(t,l,w,h,d) + local pagewidth, pageheight = getpagedimensions() local x, y = getpos() - filehandle:write(f_hlist_1(t,l,x,tex.pageheight-y,w,h,d)) + filehandle:write(f_hlist_1(t,l,x,pageheight-y,w,h,d)) nofobjects = nofobjects + 1 end -- local lastx, lasty, lastw, lasth, lastd -- -- local function doaction_2(t,l,w,h,d) + -- local pagewidth, pageheight = getpagedimensions() -- local x, y = getpos() - -- y = tex.pageheight-y + -- y = pageheight-y -- filehandle:write(f_hlist_2(t,l, -- x == lastx and "=" or x, -- y == lasty and "=" or y, @@ -412,8 +455,9 @@ local x_hlist do local lasty = false local function doaction_2(t,l,w,h,d) + local pagewidth, pageheight = getpagedimensions() local x, y = getpos() - y = tex.pageheight - y + y = pageheight - y filehandle:write(f_hlist_2(t,l,x,y == lasty and "=" or y,w,h,d)) lasty = y nofobjects = nofobjects + 1 @@ -623,16 +667,10 @@ end collect = collect_max function synctex.collect(head,where) - if enabled then - if where == "object" then - return head, false - else - local h = tonut(head) - h = collect(h,h) - return tonode(h), true - end + if enabled and where ~= "object" then + return collect(head,head) else - return head, false + return head end end @@ -645,10 +683,9 @@ function synctex.start() writeanchor() filehandle:write("{",nofsheets,eol) -- this seems to work: - local h = tex.pageheight - local w = tex.pagewidth + local pagewidth, pageheight = getpagedimensions() filehandle:write(z_hlist) - filehandle:write(f_vlist_1(0,0,0,h,w,h,0)) + filehandle:write(f_vlist_1(0,0,0,pageheight,pagewidth,pageheight,0)) end end end @@ -678,7 +715,7 @@ function synctex.enable() enabled = true set_synctex_mode(3) -- we want details if not used then - nodes.tasks.appendaction("shipouts", "after", "luatex.synctex.collect") + nodes.tasks.enableaction("shipouts","luatex.synctex.collect") report_system("synctex functionality is enabled, expect 5-10 pct runtime overhead!") used = true end @@ -786,11 +823,21 @@ implement { } implement { - name = "synctexpause", - actions = synctex.pause, + name = "synctexpause", + actions = synctex.pause, } implement { - name = "synctexresume", - actions = synctex.resume, + name = "synctexresume", + actions = synctex.resume, +} + +interfaces.implement { + name = "synctexpushline", + actions = synctex.pushline, +} +interfaces.implement { + name = "synctexpopline", + actions = synctex.popline, } + diff --git a/tex/context/base/mkiv/node-tex.lua b/tex/context/base/mkiv/node-tex.lua index c9d3091df..5857fd2e6 100644 --- a/tex/context/base/mkiv/node-tex.lua +++ b/tex/context/base/mkiv/node-tex.lua @@ -6,33 +6,40 @@ if not modules then modules = { } end modules ['node-tex'] = { license = "see context related readme files" } -builders = builders or { } -local kernel = builders.kernel or { } -builders.kernel = kernel - -local hyphenate = lang.hyphenate -local ligaturing = node.ligaturing -local kerning = node.kerning - -kernel.originals = { - hyphenate = hyphenate, - ligaturing = ligaturing, - kerning = kerning, -} +builders = builders or { } +local kernel = builders.kernel or { } +builders.kernel = kernel + +local nuts = nodes.nuts + +local hyphenate = lang.hyphenate +local hyphenating = nuts.hyphenating +local ligaturing = nuts.ligaturing +local kerning = nuts.kerning +local cleanup = nuts.flush_components function kernel.hyphenation(head) - local done = hyphenate(head) - return head, done + return (hyphenate(head)) -- nodes ! +end + +function kernel.hyphenating(head) + return (hyphenating(head)) end function kernel.ligaturing(head) - local head, tail, done = ligaturing(head) -- we return 3 values indeed - return head, done + return (ligaturing(head)) end function kernel.kerning(head) - local head, tail, done = kerning(head) -- we return 3 values indeed - return head, done + return (kerning(head)) +end + +if cleanup then + + function kernel.cleanup(head) + return (cleanup(head)) + end + end callbacks.register('hyphenate' , false, "normal hyphenation routine, called elsewhere") diff --git a/tex/context/base/mkiv/node-tra.lua b/tex/context/base/mkiv/node-tra.lua index f12599866..e1b6927fb 100644 --- a/tex/context/base/mkiv/node-tra.lua +++ b/tex/context/base/mkiv/node-tra.lua @@ -21,68 +21,67 @@ local report_nodes = logs.reporter("nodes","tracing") local nodes, node, context = nodes, node, context -local texgetattribute = tex.getattribute - -local tracers = nodes.tracers or { } -nodes.tracers = tracers - -local tasks = nodes.tasks or { } -nodes.tasks = tasks - -local handlers = nodes.handlers or {} -nodes.handlers = handlers - -local injections = nodes.injections or { } -nodes.injections = injections - -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getchar = nuts.getchar -local getsubtype = nuts.getsubtype -local getlist = nuts.getlist -local getdisc = nuts.getdisc -local setattr = nuts.setattr -local getglue = nuts.getglue -local isglyph = nuts.isglyph -local getcomponents = nuts.getcomponents -local getdir = nuts.getdir -local getwidth = nuts.getwidth - -local flush_list = nuts.flush_list -local count_nodes = nuts.countall -local used_nodes = nuts.usedlist - -local traverse_by_id = nuts.traverse_id -local traverse_nodes = nuts.traverse -local d_tostring = nuts.tostring - -local nutpool = nuts.pool -local new_rule = nutpool.rule - -local nodecodes = nodes.nodecodes -local whatcodes = nodes.whatcodes -local skipcodes = nodes.skipcodes -local fillcodes = nodes.fillcodes - -local glyph_code = nodecodes.glyph -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local disc_code = nodecodes.disc -local glue_code = nodecodes.glue -local kern_code = nodecodes.kern -local rule_code = nodecodes.rule -local dir_code = nodecodes.dir -local localpar_code = nodecodes.localpar -local whatsit_code = nodecodes.whatsit - -local dimenfactors = number.dimenfactors -local fillorders = nodes.fillcodes -local formatters = string.formatters +local texgetattribute = tex.getattribute + +local tracers = nodes.tracers or { } +nodes.tracers = tracers + +local tasks = nodes.tasks or { } +nodes.tasks = tasks + +local handlers = nodes.handlers or {} +nodes.handlers = handlers + +local injections = nodes.injections or { } +nodes.injections = injections + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local getdisc = nuts.getdisc +local setattr = nuts.setattr +local getglue = nuts.getglue +local isglyph = nuts.isglyph +local getdirection = nuts.getdirection +local getwidth = nuts.getwidth + +local flush_list = nuts.flush_list +local count_nodes = nuts.countall +local used_nodes = nuts.usedlist + +local nextnode = nuts.traversers.node +local nextglyph = nuts.traversers.glyph + +local d_tostring = nuts.tostring + +local nutpool = nuts.pool +local new_rule = nutpool.rule + +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes +local fillcodes = nodes.fillcodes + +local subtypes = nodes.subtypes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local rule_code = nodecodes.rule +local dir_code = nodecodes.dir +local localpar_code = nodecodes.localpar +local whatsit_code = nodecodes.whatsit + +local dimenfactors = number.dimenfactors +local formatters = string.formatters -- this will be reorganized: @@ -90,23 +89,26 @@ function nodes.showlist(head, message) if message then report_nodes(message) end - for n in traverse_nodes(tonut(head)) do + for n in nextnode, tonut(head) do report_nodes(d_tostring(n)) end end function nodes.handlers.checkglyphs(head,message) - local h = tonut(head) + local h = tonut(head) -- tonut needed? local t = { } - for g in traverse_by_id(glyph_code,h) do - t[#t+1] = formatters["%U:%s"](getchar(g),getsubtype(g)) + local n = 0 + local f = formatters["%U:%s"] + for g, char, font in nextglyph, h do + n = n + 1 + t[n] = f(char,getsubtype(g)) end - if #t > 0 then - if message and message ~= "" then - report_nodes("%s, %s glyphs: % t",message,#t,t) - else - report_nodes("%s glyphs: % t",#t,t) - end + if n == 0 then + -- nothing to report + elseif message and message ~= "" then + report_nodes("%s, %s glyphs: % t",message,n,t) + else + report_nodes("%s glyphs: % t",n,t) end return false end @@ -114,8 +116,8 @@ end function nodes.handlers.checkforleaks(sparse) local l = { } local q = used_nodes() - for p in traverse_nodes(q) do - local s = table.serialize(nodes.astable(p,sparse),nodecodes[getid(p)]) + for p, id in nextnode, q do + local s = table.serialize(nodes.astable(p,sparse),nodecodes[id]) l[s] = (l[s] or 0) + 1 end flush_list(q) @@ -124,42 +126,51 @@ function nodes.handlers.checkforleaks(sparse) end end -local f_sequence = formatters["U+%04X:%s"] -local f_subrange = formatters["[[ %s ][ %s ][ %s ]]"] +local fontcharacters -- = fonts.hashes.descriptions local function tosequence(start,stop,compact) if start then + if not fontcharacters then + fontcharacters = fonts.hashes.descriptions + if not fontcharacters then + return "[no char data]" + end + end + local f_sequence = formatters["U+%04X:%s"] + local f_subrange = formatters["[[ %s ][ %s ][ %s ]]"] start = tonut(start) stop = stop and tonut(stop) local t = { } + local n = 0 while start do local c, id = isglyph(start) if c then - if compact then - local components = getcomponents(start) - if components then - t[#t+1] = tosequence(components,nil,compact) - else - t[#t+1] = utfchar(c) + local u = fontcharacters[id][c] -- id == font id + u = u and u.unicode or c + if type(u) == "table" then + local tt = { } + for i=1,#u do + local c = u[i] + tt[i] = compact and utfchar(c) or f_sequence(c,utfchar(c)) end + n = n + 1 ; t[n] = "(" .. concat(tt," ") .. ")" else - t[#t+1] = f_sequence(c,utfchar(c)) + n = n + 1 ; t[n] = compact and utfchar(c) or f_sequence(c,utfchar(c)) end elseif id == disc_code then local pre, post, replace = getdisc(start) t[#t+1] = f_subrange(pre and tosequence(pre),post and tosequence(post),replace and tosequence(replace)) elseif id == rule_code then - if compact then - t[#t+1] = "|" - else - t[#t+1] = nodecodes[id] - end - elseif id == dir_code or id == localpar_code then - t[#t+1] = "[" .. getdir(start) .. "]" + n = n + 1 ; t[n] = compact and "|" or nodecodes[id] or "?" + elseif id == dir_code then + local d, p = getdirection(start) + n = n + 1 ; t[n] = "[<" .. (p and "-" or "+") .. d .. ">]" -- todo l2r etc + elseif id == localpar_code and getsubtype(start) == 0 then + n = n + 1 ; t[n] = "[<" .. getdirection(start) .. ">]" -- todo l2r etc elseif compact then - t[#t+1] = "[]" + n = n + 1 ; t[n] = "[]" else - t[#t+1] = nodecodes[id] + n = n + 1 ; t[n] = nodecodes[id] end if start == stop then break @@ -180,13 +191,13 @@ end nodes.tosequence = tosequence nuts .tosequence = tosequence -function nodes.report(t,done) - report_nodes("output %a, changed %a, %s nodes",status.output_active,done,count_nodes(tonut(t))) +function nodes.report(t) + report_nodes("output %a, %s nodes",status.output_active,count_nodes(t)) end function nodes.packlist(head) local t = { } - for n in traverse_nodes(tonut(head)) do + for n in nextnode, tonut(head) do t[#t+1] = d_tostring(n) end return t @@ -198,10 +209,11 @@ function nodes.idstostring(head,tail) local t = { } local last_id = nil local last_n = 0 - for n in traverse_nodes(head,tail) do -- hm, does not stop at tail - local id = getid(n) + local f_two = formatters["[%s*%s]"] + local f_one = formatters["[%s]"] + for n, id, subtype in nextnode, head do if id == whatsit_code then - id = whatcodes[getsubtype(n)] + id = whatsitcodes[subtype] else id = nodecodes[id] end @@ -212,9 +224,9 @@ function nodes.idstostring(head,tail) last_n = last_n + 1 else if last_n > 1 then - t[#t+1] = formatters["[%s*%s]"](last_n,last_id) + t[#t+1] = f_two(last_n,last_id) else - t[#t+1] = formatters["[%s]"](last_id) + t[#t+1] = f_one(last_id) end last_id = id last_n = 1 @@ -227,14 +239,29 @@ function nodes.idstostring(head,tail) t[#t+1] = "no nodes" else if last_n > 1 then - t[#t+1] = formatters["[%s*%s]"](last_n,last_id) + t[#t+1] = f_two(last_n,last_id) else - t[#t+1] = formatters["[%s]"](last_id) + t[#t+1] = f_one(last_id) end end return concat(t," ") end +function nodes.idsandsubtypes(head) + local h = tonut(head) + local t = { } + local f = formatters["%s:%s"] + for n, id, subtype in nextnode, h do + local c = nodecodes[id] + if subtype then + t[#t+1] = f(c,subtypes[id][subtype]) + else + t[#t+1] = c + end + end + return concat(t, " ") +end + -- function nodes.xidstostring(head,tail) -- only for special tracing of backlinks -- head = tonut(head) -- tail = tonut(tail) @@ -299,17 +326,19 @@ nodes.showsimplelist = function(h,depth) showsimplelist(h,depth,0) end local function listtoutf(h,joiner,textonly,last,nodisc) local w = { } local n = 0 + local g = formatters["<%i>"] + local d = formatters["[%s|%s|%s]"] while h do local c, id = isglyph(h) if c then - n = n + 1 ; w[n] = c >= 0 and utfchar(c) or formatters["<%i>"](c) + n = n + 1 ; w[n] = c >= 0 and utfchar(c) or g(c) if joiner then n = n + 1 ; w[n] = joiner end elseif id == disc_code then local pre, pos, rep = getdisc(h) if not nodisc then - n = n + 1 ; w[n] = formatters["[%s|%s|%s]"] ( + n = n + 1 ; w[n] = d( pre and listtoutf(pre,joiner,textonly) or "", pos and listtoutf(pos,joiner,textonly) or "", rep and listtoutf(rep,joiner,textonly) or "" @@ -354,11 +383,9 @@ local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" } local function showboxes(n,symbol,depth) depth = depth or 0 symbol = symbol or "." - for n in traverse_nodes(tonut(n)) do - local id = getid(n) + for n, id, subtype in nextnode, tonut(n) do if id == hlist_code or id == vlist_code then - local s = getsubtype(n) - report_nodes(rep(symbol,depth) .. what[s] or s) + report_nodes(rep(symbol,depth) .. what[subtype] or subtype) showboxes(getlist(n),symbol,depth+1) end end @@ -401,17 +428,17 @@ local function nodetodimen(n) width = width / 65536 if stretch_order ~= 0 then if shrink_order ~= 0 then - return f_f_f(width,stretch,fillorders[stretch_order],shrink,fillorders[shrink_order]) + return f_f_f(width,stretch,fillcodes[stretch_order],shrink,fillcodes[shrink_order]) elseif shrink ~= 0 then - return f_f_m(width,stretch,fillorders[stretch_order],shrink) + return f_f_m(width,stretch,fillcodes[stretch_order],shrink) else - return f_f_z(width,stretch,fillorders[stretch_order]) + return f_f_z(width,stretch,fillcodes[stretch_order]) end elseif shrink_order ~= 0 then if stretch ~= 0 then - return f_p_f(width,stretch,shrink,fillorders[shrink_order]) + return f_p_f(width,stretch,shrink,fillcodes[shrink_order]) else - return f_z_f(width,shrink,fillorders[shrink_order]) + return f_z_f(width,shrink,fillcodes[shrink_order]) end elseif stretch ~= 0 then if shrink ~= 0 then @@ -631,6 +658,9 @@ end tracers.setproperties = setproperties +-- setting attrlist entries instead of attr for successive entries doesn't +-- speed up much (this function is only used in tracers anyway) + function tracers.setlist(n,c,s) local nn = tonut(n) local mc = m_color[c] diff --git a/tex/context/base/mkiv/node-tsk.lua b/tex/context/base/mkiv/node-tsk.lua index 1ce7ab1dc..0378c14c6 100644 --- a/tex/context/base/mkiv/node-tsk.lua +++ b/tex/context/base/mkiv/node-tsk.lua @@ -52,19 +52,21 @@ end function tasks.new(specification) -- was: name,arguments,list local name = specification.name - local arguments = specification.arguments or 0 local sequence = specification.sequence if name and sequence then local tasklist = newsequencer { + name = name -- we can move more to the sequencer now .. todo } tasksdata[name] = { + name = name, list = tasklist, runner = false, - arguments = arguments, - -- sequence = sequence, frozen = { }, - processor = specification.processor or nodeprocessor + processor = specification.processor or nodeprocessor, + -- could be metatable but best freeze it + arguments = specification.arguments or 0, + templates = specification.templates, } for l=1,#sequence do appendgroup(tasklist,sequence[l]) @@ -170,18 +172,26 @@ function tasks.disablegroup(name,group) end end -function tasks.appendaction(name,group,action,where,kind) +function tasks.appendaction(name,group,action,where,kind,state) local data = validgroup(name,"append action") if data then - appendaction(data.list,group,action,where,kind) + local list = data.list + appendaction(list,group,action,where,kind) + if state == "disabled" or (state == "production" and environment.initex) then + disableaction(list,action) + end data.runner = false end end -function tasks.prependaction(name,group,action,where,kind) +function tasks.prependaction(name,group,action,where,kind,state) local data = validgroup(name,"prepend action") if data then - prependaction(data.list,group,action,where,kind) + local list = data.list + prependaction(list,group,action,where,kind) + if state == "disabled" or (state == "production" and environment.initex) then + disableaction(list,action) + end data.runner = false end end @@ -216,112 +226,29 @@ statistics.register("node list callback tasks", function() end end) -function tasks.actions(name) -- we optimize for the number or arguments (no ...) +local function create(data,t) + created = created + 1 + local runner = compile(data.list,data.processor,t) + if trace_tasks then + report_tasks("creating runner %a, %i actions enabled",t.name,data.list.steps or 0) + end + data.runner = runner + return runner +end + +function tasks.actions(name) local data = tasksdata[name] if data then - local n = data.arguments or 0 - if n == 0 then - return function(head) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a",name) - end - runner = compile(data.list,data.processor,0) - data.runner = runner - end - return runner(head) - end - elseif n == 1 then - return function(head,one) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a with %s extra arguments",name,1) - end - runner = compile(data.list,data.processor,1) - data.runner = runner - end - return runner(head,one) - end - elseif n == 2 then - return function(head,one,two) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a with %s extra arguments",name,2) - end - runner = compile(data.list,data.processor,2) - data.runner = runner - end - return runner(head,one,two) - end - elseif n == 3 then - return function(head,one,two,three) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a with %s extra arguments",name,3) - end - runner = compile(data.list,data.processor,3) - data.runner = runner - end - return runner(head,one,two,three) - end - elseif n == 4 then - return function(head,one,two,three,four) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a with %s extra arguments",name,4) - end - runner = compile(data.list,data.processor,4) - data.runner = runner - end - return runner(head,one,two,three,four) - end - elseif n == 5 then - return function(head,one,two,three,four,five) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a with %s extra arguments",name,5) - end - runner = compile(data.list,data.processor,5) - data.runner = runner - end - return runner(head,one,two,three,four,five) - end - else - return function(head,...) - total = total + 1 -- will go away - local runner = data.runner - if not runner then - created = created + 1 - if trace_tasks then - report_tasks("creating runner %a with %s extra arguments",name,n) - end - runner = compile(data.list,data.processor,"n") - data.runner = runner - end - return runner(head,...) + local t = data.templates + if t then + t.name = data.name + return function(...) + total = total + 1 + return (data.runner or create(data,t))(...) end end - else - return nil end + return nil end function tasks.table(name) --maybe move this to task-deb.lua @@ -351,12 +278,132 @@ function tasks.table(name) --maybe move this to task-deb.lua end end --- this will move +-- -- shipouts everypar -- -- + +-- the shipout handlers acts on boxes so we don't need to return something +-- and also don't need to keep the state (done) + +local templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead)))) +]], + +nut = [[ + nuthead = %action%(nuthead) +]], + +nohead = [[ + %action%(tonode(nuthead)) +]], + +nonut = [[ + %action%(nuthead) +]], + +} + +tasks.new { + name = "shipouts", + processor = nodeprocessor, + sequence = { + "before", -- users + "normalizers", -- system + "finishers", -- system + "after", -- users + "wrapup", -- system + }, + templates = templates +} + +tasks.new { + name = "everypar", + processor = nodeprocessor, + sequence = { + "before", -- users + "normalizers", -- system + "after", -- users + }, + templates = templates, +} + +-- -- finalizers -- -- + +tasks.new { + name = "finalizers", + sequence = { + "before", -- for users + "normalizers", + "fonts", + "lists", + "after", -- for users + }, + processor = nodeprocessor, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode) +]], + +nonut = [[ + %action%(nuthead,groupcode) +]], + + } +} + +-- -- processors -- -- tasks.new { name = "processors", - arguments = 5, -- often only the first is used, and the last three are only passed in hpack filter --- arguments = 2, processor = nodeprocessor, sequence = { "before", -- for users @@ -366,56 +413,297 @@ tasks.new { "fonts", "lists", "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode,size,packtype,direction,attributes) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,direction,attributes))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode,size,packtype,direction,attributes) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode,size,packtype,direction,attributes) +]], + +nonut = [[ + %action%(nuthead,groupcode,size,packtype,direction,attributes) +]], + } } tasks.new { name = "finalizers", - arguments = 1, processor = nodeprocessor, sequence = { "before", -- for users "normalizers", --- "characters", --- "finishers", "fonts", "lists", "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead)))) +]], + +nut = [[ + nuthead = %action%(nuthead) +]], + +nohead = [[ + %action%(tonode(nuthead)) +]], + +nonut = [[ + %action%(nuthead) +]], + } } tasks.new { - name = "shipouts", - arguments = 1, - -- nostate = true, -- maybe but only for main ones so little gain + name = "mvlbuilders", processor = nodeprocessor, sequence = { "before", -- for users "normalizers", - "finishers", "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode) +]], + +nonut = [[ + %action%(nuthead,groupcode) +]], + } } tasks.new { - name = "mvlbuilders", - arguments = 1, + name = "vboxbuilders", processor = nodeprocessor, sequence = { "before", -- for users "normalizers", "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode,size,packtype,maxdepth,direction) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode,size,packtype,maxdepth,direction) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode,size,packtype,maxdepth,direction) +]], + +nonut = [[ + %action%(nuthead,groupcode,size,packtype,maxdepth,direction) +]], + } + } tasks.new { - name = "vboxbuilders", - arguments = 5, + name = "contributers", processor = nodeprocessor, sequence = { "before", -- for users "normalizers", "after", -- for users + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,groupcode,line) + local nuthead = tonut(head) + local nutline = tonut(line) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),groupcode,line))) +]], + +nut = [[ + nuthead = %action%(nuthead,groupcode,nutline) +]], + +nohead = [[ + %action%(tonode(nuthead),groupcode,line) +]], + +nonut = [[ + %action%(nuthead,groupcode,nutline) +]], + + } +} + +-- -- math -- -- + +tasks.new { + name = "math", + processor = nodeprocessor, + sequence = { + "before", + "normalizers", + "builders", + "after", + }, + templates = { + +default = [[ +return function(head) + return head +end +]], + +process = [[ +local tonut = nodes.tonut +local tonode = nodes.nuts.tonode + +%localize% + +return function(head,style,penalties) + local nuthead = tonut(head) + +%actions% + return tonode(nuthead) +end +]], + +step = [[ + nuthead = tonut((%action%(tonode(nuthead),style,penalties))) +]], + +nut = [[ + nuthead = %action%(nuthead,style,penalties) +]], + +nohead = [[ + %action%(tonode(nuthead),style,penalties) +]], + +nonut = [[ + %action%(nuthead,style,penalties) +]], + } } @@ -441,14 +729,69 @@ tasks.new { -- } -- } -tasks.new { - name = "contributers", - arguments = 2, -- [head] where parent - processor = nodeprocessor, - sequence = { - "before", -- for users - "normalizers", - "after", -- for users - } -} +-- for now quite useless (too fuzzy) +-- +-- tasks.new { +-- name = "listbuilders", +-- processor = nodeprocessor, +-- sequence = { +-- "before", -- for users +-- "normalizers", +-- "after", -- for users +-- }, +-- templates = { +-- -- we don't need a default +-- default = [[ +-- return function(box,location,prevdepth) +-- return box, prevdepth +-- end +-- ]], +-- process = [[ +-- %localize% +-- return function(box,location,prevdepth,mirrored) +-- %actions% +-- return box, prevdepth +-- end +-- ]], +-- step = [[ +-- box, prevdepth = %action%(box,location,prevdepth,mirrored) +-- ]], +-- }, +-- } + +-- -- math -- -- + +-- not really a node processor +-- tasks.new { +-- name = "newpar", +-- processor = nodeprocessor, +-- sequence = { +-- "before", +-- "normalizers", +-- "after", +-- }, +-- templates = { +-- +-- default = [[ +-- return function(mode,indent) +-- return indent +-- end +-- ]], +-- +-- process = [[ +-- %localize% +-- +-- return function(mode,indent) +-- +-- %actions% +-- return indent +-- end +-- ]], +-- +-- step = [[ +-- indent = %action%(mode,indent) +-- ]], +-- +-- } +-- } diff --git a/tex/context/base/mkiv/node-tst.lua b/tex/context/base/mkiv/node-tst.lua index 7ad35bd71..0dacff375 100644 --- a/tex/context/base/mkiv/node-tst.lua +++ b/tex/context/base/mkiv/node-tst.lua @@ -10,7 +10,7 @@ local nodes, node = nodes, node local chardata = characters.data local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local glue_code = nodecodes.glue local penalty_code = nodecodes.penalty @@ -19,10 +19,10 @@ local glyph_code = nodecodes.glyph local whatsit_code = nodecodes.whatsit local hlist_code = nodecodes.hlist -local leftskip_code = skipcodes.leftskip -local rightskip_code = skipcodes.rightskip -local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip -local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip +local leftskip_code = gluecodes.leftskip +local rightskip_code = gluecodes.rightskip +local abovedisplayshortskip_code = gluecodes.abovedisplayshortskip +local belowdisplayshortskip_code = gluecodes.belowdisplayshortskip local nuts = nodes.nuts diff --git a/tex/context/base/mkiv/pack-bar.mkiv b/tex/context/base/mkiv/pack-bar.mkiv index 06eeebd14..b67d6f14b 100644 --- a/tex/context/base/mkiv/pack-bar.mkiv +++ b/tex/context/base/mkiv/pack-bar.mkiv @@ -72,16 +72,16 @@ \vskip\zeropoint\s!plus-\positionbarparameter\c!n \s!fill}} \unexpanded\def\horizontalgrowingbar[#1]% - {\hbox to \hsize + {\hpack to \hsize {\setuppositionbar[#1]% \usepositionbarstyleandcolor\c!style\c!color - \leaders\vrule\hskip\zeropoint\s!plus \numexpr\positionbarparameter\c!n-\positionbarparameter\c!min+\plusone\relax\s!fill + \leaders\vrule\hskip\zeropoint\s!plus\numexpr\positionbarparameter\c!n-\positionbarparameter\c!min+\plusone\relax\s!fill \vrule\s!width\zeropoint\s!height\positionbarparameter\c!height\s!depth\positionbarparameter\c!depth \hskip\zeropoint\s!plus \positionbarparameter\c!max\s!fill \hskip\zeropoint\s!plus-\positionbarparameter\c!n \s!fill}} \unexpanded\def\verticalgrowingbar[#1]% - {\vbox to \vsize + {\vpack to \vsize {\setuppositionbar[#1]% \usepositionbarstyleandcolor\c!style\c!color \leaders\hrule\vskip\zeropoint\s!plus\numexpr\positionbarparameter\c!n-\positionbarparameter\c!min+\plusone\relax\s!fill diff --git a/tex/context/base/mkiv/pack-bck.mkvi b/tex/context/base/mkiv/pack-bck.mkvi index 346e7df57..9f9d843ce 100644 --- a/tex/context/base/mkiv/pack-bck.mkvi +++ b/tex/context/base/mkiv/pack-bck.mkvi @@ -245,18 +245,42 @@ %D \macros %D {backgroundline} -\unexpanded\def\backgroundline[#color]% - {\dontleavehmode - \dowithnextbox{\pack_backgrounds_add_to_nextbox{#color}}\hbox} +% \unexpanded\def\backgroundline[#color]% +% {\dontleavehmode +% \dowithnextbox{\pack_backgrounds_add_to_nextbox{#color}}\hbox} +% +% \unexpanded\def\pack_backgrounds_add_to_nextbox#color% handy helper +% {\hpack +% {\dousecolorparameter{#color}% +% \vrule +% \??width \nextboxwd +% \??height\nextboxht +% \??depth \nextboxdp +% \hskip-\nextboxwd +% \flushnextbox}} + +%D We implement this elsewhere avoiding the rule. -\unexpanded\def\pack_backgrounds_add_to_nextbox#color% handy helper - {\hbox - {\dousecolorparameter{#color}% - \vrule - \!!width \nextboxwd - \!!height\nextboxht - \!!depth \nextboxdp - \hskip-\nextboxwd - \flushnextbox}} +% \unexpanded\def\backgroundline +% {\dontleavehmode +% \pack_backgrounds_add_to_nextbox\hbox\hpack} +% +% \unexpanded\def\pack_backgrounds_add_to_nextbox#box#pack[#color]% +% {\dontleavehmode +% \dowithnextbox{\pack_backgrounds_add_to_nextbox_indeed#pack{#color}}#box} +% +% \unexpanded\def\pack_backgrounds_add_to_nextbox_indeed#pack#color% handy helper +% {#pack% +% {\dousecolorparameter{#color}% +% \vrule +% \??width \nextboxwd +% \??height\nextboxht +% \??depth \nextboxdp +% \hskip-\nextboxwd +% \flushnextbox}} +% +% \unexpanded\def\backgroundhbox{\pack_backgrounds_add_to_nextbox\hbox\hpack} +% \unexpanded\def\backgroundvtop{\pack_backgrounds_add_to_nextbox\vtop\tpack} +% \unexpanded\def\backgroundvbox{\pack_backgrounds_add_to_nextbox\vbox\vpack} \protect \endinput diff --git a/tex/context/base/mkiv/pack-box.mkiv b/tex/context/base/mkiv/pack-box.mkiv index c53b4520c..bf6d4662d 100644 --- a/tex/context/base/mkiv/pack-box.mkiv +++ b/tex/context/base/mkiv/pack-box.mkiv @@ -108,6 +108,7 @@ {\global\advance\c_pack_anchors_n\plusone \pagereference[\v!layer:\v!anchor:\number\c_pack_anchors_n]% \putboxincache\v!anchor{\number\c_pack_anchors_n}\b_pack_anchors +% \xtoksapp\t_pack_anchors_flush{\pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}}% \doglobal\appendetoks \pack_anchors_flush{\number\c_pack_anchors_n}{#1}{#2}% \to \t_pack_anchors_flush diff --git a/tex/context/base/mkiv/pack-com.mkiv b/tex/context/base/mkiv/pack-com.mkiv index 59354208e..1c6f2de73 100644 --- a/tex/context/base/mkiv/pack-com.mkiv +++ b/tex/context/base/mkiv/pack-com.mkiv @@ -73,7 +73,7 @@ \newsystemmode{combination} \appendtoks - \global\resetsystemmode{combination}% + \globalresetsystemmode{combination}% \to \everyinsidefloat \newcount\c_pack_combinations_nesting % local @@ -113,7 +113,7 @@ \setbox\b_pack_combinations_content_saved \box\b_pack_combinations_content \setbox\b_pack_combinations_caption_saved \box\b_pack_combinations_caption \else - \global\setsystemmode{combination}% why global + \globalsetsystemmode{combination}% why global \fi} \def\pack_combinations_pop @@ -126,7 +126,7 @@ \setbox\b_pack_combinations_content \box\b_pack_combinations_content_saved \setbox\b_pack_combinations_caption \box\b_pack_combinations_caption_saved \else - \global\resetsystemmode{combination}% why global + \globalresetsystemmode{combination}% why global \fi \advance\c_pack_combinations_nesting\minusone} @@ -205,7 +205,7 @@ % {\bgroup % \scratchtoks{{}}% % \dorecurse\c_pack_combinations_y -% {\scratchtoks\expandafter{\the\scratchtoks{}{}}}% +% {\toksapp{{}{}}}% % \expandafter\egroup\the\scratchtoks % \egroup % \dostoptagged @@ -290,7 +290,7 @@ \alignmark\alignmark \m_pack_combinations_rightfiller \aligntab - \tabskip\zeropoint \s!plus 1fill + \tabskip\zeropoint \s!plus 1fill % \fillskip \alignmark\alignmark \cr \pack_combinations_pickup} @@ -437,10 +437,10 @@ \nointerlineskip % indeed \combinationparameter\c!inbetween \global\c_pack_combinations_x\c_pack_combinations_max - \globallet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes + \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_yes \else \global\setbox\b_pack_combinations_captions\emptybox - \globallet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop + \glet\pack_combinations_flush_captions_indeed\pack_combinations_flush_captions_nop \fi}% \pack_combinations_flush_captions_indeed \crcr} @@ -656,7 +656,7 @@ \newsystemmode{pairedbox} \appendtoks - \global\resetsystemmode{pairedbox}% + \globalresetsystemmode{pairedbox}% \to \everyinsidefloat \installcorenamespace {pairedbox} @@ -720,7 +720,7 @@ \let\startcaption\pack_common_caption_start \let\stopcaption \pack_common_caption_stop % - \global\setsystemmode{pairedbox}% + \globalsetsystemmode{pairedbox}% \pack_pairedboxes_before \assumelongusagecs\pack_pairedboxes_first_pickup} diff --git a/tex/context/base/mkiv/pack-cut.mkiv b/tex/context/base/mkiv/pack-cut.mkiv index ffd0251d5..84c14d648 100644 --- a/tex/context/base/mkiv/pack-cut.mkiv +++ b/tex/context/base/mkiv/pack-cut.mkiv @@ -65,85 +65,87 @@ \def\cutmarkrulethickness{\onepoint} \unexpanded\def\horizontalcuts - {\normalhbox to \d_pack_cutmarks_width - {\dorecurse\horizontalcutmarks{\vrule\s!width\cutmarkrulethickness\s!height\cutmarklength\normalhfill}% + {\hpack to \d_pack_cutmarks_width + {\dorecurse\horizontalcutmarks{\vrule\s!width\cutmarkrulethickness\s!height\cutmarklength\hfill}% \unskip}} \unexpanded\def\verticalcuts - {\normalvbox to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax + {\vpack to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax {\hsize\cutmarklength - \dorecurse\verticalcutmarks{\vrule\s!height\cutmarkrulethickness\s!width\hsize\normalvfill}% + \dorecurse\verticalcutmarks{\vrule\s!height\cutmarkrulethickness\s!width\hsize\vfill}% \unskip}} \unexpanded\def\baselinecuts {\ifdim\d_pack_cutmarks_depth>\zeropoint - \normalvbox to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax + \vpack to \dimexpr\d_pack_cutmarks_height+\d_pack_cutmarks_depth\relax {\hsize\dimexpr\cutmarklength/2\relax - \normalvskip\zeropoint\s!plus\d_pack_cutmarks_height + \vskip\zeropoint\s!plus\d_pack_cutmarks_height \vrule\s!height\cutmarkrulethickness\s!width\hsize - \normalvskip\zeropoint\s!plus\d_pack_cutmarks_depth}% + \vskip\zeropoint\s!plus\d_pack_cutmarks_depth}% \fi} \unexpanded\def\cutmarksymbols#1% - {\normalhbox to \d_pack_cutmarks_width - {\setbox\scratchbox\normalhbox to \cutmarklength - {\normalhss\infofont\cutmarksymbol\normalhss}% - \normalhss - \normalvbox to \cutmarklength + {\hpack to \d_pack_cutmarks_width + {\setbox\scratchbox\hbox to \cutmarklength + {\hss\infofont\cutmarksymbol\hss}% + \hss + \vpack to \cutmarklength {\scratchdimen\dimexpr\cutmarklength/2\relax \scratchskip \ifx\cutmarkhoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkhoffset\fi - \normalvss - \hpack to \d_pack_cutmarks_width - {\llap{\copy\scratchbox\normalhskip\scratchskip}% - \normalhskip\scratchdimen\hss\infofont#1\hss\normalhskip\scratchdimen - \rlap{\normalhskip\scratchskip\copy\scratchbox}}% - \normalvss}% - \normalhss}} + \vss + \hbox to \d_pack_cutmarks_width + {\llap{\copy\scratchbox\hskip\scratchskip}% + \hskip\scratchdimen\hss + \infofont#1% + \hss\hskip\scratchdimen + \rlap{\hskip\scratchskip\copy\scratchbox}}% + \vss}% + \hss}} \unexpanded\def\makecutbox#1% {\bgroup \d_pack_cutmarks_height\ht#1% \d_pack_cutmarks_depth \dp#1% \d_pack_cutmarks_width \wd#1% - \setbox#1\normalhbox + \setbox#1\hpack {\dontcomplain \forgetall \boxmaxdepth\maxdimen \offinterlineskip \scratchdimen\dimexpr\cutmarklength/2\relax \hsize\d_pack_cutmarks_width - \setbox\scratchbox\normalvbox - {\setbox\scratchbox\normalhbox{\horizontalcuts}% + \setbox\scratchbox\vpack + {\setbox\scratchbox\hpack{\horizontalcuts}% \scratchskip\ifx\cutmarkvoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkvoffset\fi - \tlap{\copy\scratchbox\normalvskip\scratchskip}% + \tlap{\copy\scratchbox\vskip\scratchskip}% \hpack to \d_pack_cutmarks_width {\scratchskip\ifx\cutmarkhoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkhoffset\fi - \setbox\scratchbox\normalhbox{\verticalcuts}% - \llap{\copy\scratchbox\normalhskip\scratchskip}% + \setbox\scratchbox\hpack{\verticalcuts}% + \llap{\copy\scratchbox\hskip\scratchskip}% \ifdim\d_pack_cutmarks_depth=\zeropoint - \normalhfill + \hfill \else \bgroup - \setbox\scratchbox\normalhbox{\baselinecuts}% - \llap{\copy\scratchbox\normalhskip\scratchskip}% - \normalhfill - \rlap{\normalhskip\scratchskip\copy\scratchbox}% + \setbox\scratchbox\hpack{\baselinecuts}% + \llap{\copy\scratchbox\hskip\scratchskip}% + \hfill + \rlap{\hskip\scratchskip\copy\scratchbox}% \egroup \fi - \rlap{\normalhskip\scratchskip\copy\scratchbox}}% - \blap{\normalvskip\scratchskip\copy\scratchbox}}% + \rlap{\hskip\scratchskip\copy\scratchbox}}% + \blap{\vskip\scratchskip\copy\scratchbox}}% \ht\scratchbox\d_pack_cutmarks_height \dp\scratchbox\d_pack_cutmarks_depth \wd\scratchbox\zeropoint \startcolor[\defaulttextcolor]% \box\scratchbox \ifx\cutmarksymbol\relax \else - \setbox\scratchbox\normalvbox + \setbox\scratchbox\vpack {\scratchskip\ifx\cutmarkvoffset\empty\cutmarkoffset\scratchdimen\else\cutmarkvoffset\fi \vskip-\dimexpr\scratchskip+\cutmarklength\relax - \normalhbox{\cutmarksymbols\cutmarktoptext}% + \hpack{\cutmarksymbols\cutmarktoptext}% \vskip\dimexpr\scratchskip+\d_pack_cutmarks_height+\d_pack_cutmarks_depth+\scratchskip\relax - \normalhbox{\cutmarksymbols\cutmarkbottomtext}}% + \hpack{\cutmarksymbols\cutmarkbottomtext}}% \ht\scratchbox\d_pack_cutmarks_height \dp\scratchbox\d_pack_cutmarks_depth \wd\scratchbox\zeropoint @@ -156,8 +158,8 @@ \dp#1\d_pack_cutmarks_depth \egroup} -\unexpanded\def\cuthbox{\normalhbox\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalhbox} -\unexpanded\def\cutvbox{\normalvbox\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvbox} -\unexpanded\def\cutvtop{\normalvtop\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\normalvtop} +\unexpanded\def\cuthbox{\hpack\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\hbox} +\unexpanded\def\cutvbox{\vpack\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\vbox} +\unexpanded\def\cutvtop{\tpack\bgroup\dowithnextbox{\makecutbox\nextbox\flushnextbox\egroup}\vtop} \protect \endinput diff --git a/tex/context/base/mkiv/pack-lyr.mkiv b/tex/context/base/mkiv/pack-lyr.mkiv index 8661fe57a..e7070cfde 100644 --- a/tex/context/base/mkiv/pack-lyr.mkiv +++ b/tex/context/base/mkiv/pack-lyr.mkiv @@ -293,8 +293,8 @@ {\setbox\b_layers\emptybox \d_pack_layers_x_position\p_pack_layers_sx\dimexpr\p_pack_layers_x\relax \d_pack_layers_y_position\p_pack_layers_sy\dimexpr\p_pack_layers_y\relax - \globallet\lastlayerxpos\!!zeropoint - \globallet\lastlayerypos\!!zeropoint + \glet\lastlayerxpos\!!zeropoint + \glet\lastlayerypos\!!zeropoint \doifinset\v!bottom\p_pack_layers_corner\pack_layers_set_bottom_positions \doifinset\v!right \p_pack_layers_corner\pack_layers_set_right_positions \doifinset\v!middle\p_pack_layers_corner\pack_layers_set_middle_positions @@ -540,24 +540,85 @@ % todo: pass the layer with \lastnamedcs +% \def\pack_layers_flush_single +% {\startoverlay +% {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}% +% {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\fi}% +% \stopoverlay} +% +% \def\pack_layers_flush_double#1% +% {\startoverlay +% {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}% +% {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount {\currentlayer:\the\realpageno}\fi}% +% {\ifcsname\??layerbox#1\currentlayer \endcsname\pack_layers_flush_indeed\plusone {#1\currentlayer }\fi}% +% {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\fi}% +% \stopoverlay} + +% optimized: + \def\pack_layers_flush_single - {\startoverlay - {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}% - {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\fi}% - \stopoverlay} + {\ifcsname\??layerbox\currentlayer\endcsname + \ifvoid\lastnamedcs + \ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname + \ifvoid\lastnamedcs\else + \chardef\b_layer_two\lastnamedcs + \pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two + \fi + \fi + \else + \chardef\b_layer_one\lastnamedcs + \ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname + \ifvoid\lastnamedcs\else + \chardef\b_layer_two\lastnamedcs + \startoverlay + {\pack_layers_flush_indeed\plusone \currentlayer \b_layer_one}% + {\pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two}% + \stopoverlay + \fi + \else + \pack_layers_flush_indeed\plusone\currentlayer\b_layer_one + \fi + \fi + \else\ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname + \ifvoid\lastnamedcs + % nothing + \else + \chardef\b_layer_two\lastnamedcs + \pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two + \fi + \fi\fi} + +% less optimized: \def\pack_layers_flush_double#1% {\startoverlay - {\ifcsname\??layerbox \currentlayer \endcsname\pack_layers_flush_indeed\plusone \currentlayer \fi}% - {\ifcsname\??layerbox \currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount {\currentlayer:\the\realpageno}\fi}% - {\ifcsname\??layerbox#1\currentlayer \endcsname\pack_layers_flush_indeed\plusone {#1\currentlayer }\fi}% - {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname\pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\fi}% + {\ifcsname\??layerbox\currentlayer\endcsname + \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs + \pack_layers_flush_indeed\plusone\currentlayer\b_layer_two + \fi + \fi}% + {\ifcsname\??layerbox\currentlayer:\the\realpageno\endcsname + \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs + \pack_layers_flush_indeed\zerocount{\currentlayer:\the\realpageno}\b_layer_two + \fi + \fi}% + {\ifcsname\??layerbox#1\currentlayer\endcsname + \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs + \pack_layers_flush_indeed\plusone{#1\currentlayer}\b_layer_two + \fi + \fi}% + {\ifcsname\??layerbox#1\currentlayer:\the\realpageno\endcsname + \ifvoid\lastnamedcss\else \chardef\b_layer_two\lastnamedcs + \pack_layers_flush_indeed\zerocount{#1\currentlayer:\the\realpageno}\b_layer_two + \fi + \fi}% \stopoverlay} \let\pack_layers_top_fill \relax \let\pack_layers_bottom_fill\vss -\def\pack_layers_flush_indeed#1#2% quite core, so optimized +%def\pack_layers_flush_indeed#1#2% +\def\pack_layers_flush_indeed#1#2#3% {\begingroup % already grouped \offinterlineskip \edef\p_pack_layers_preset{\layerparameter\c!preset}% @@ -587,7 +648,8 @@ \fi\fi \fi \fi - \chardef\b_layers\csname\??layerbox#2\endcsname % trick + %chardef\b_layers\csname\??layerbox#2\endcsname % trick + \let\b_layers#3% % we need to copy in order to retain the negative offsets for a next % stage of additions, i.e. llx/lly accumulate in repeat mode and the % compensation may differ each flush depending on added content diff --git a/tex/context/base/mkiv/pack-mrl.mkiv b/tex/context/base/mkiv/pack-mrl.mkiv index 85aa3ad04..665d245b3 100644 --- a/tex/context/base/mkiv/pack-mrl.mkiv +++ b/tex/context/base/mkiv/pack-mrl.mkiv @@ -39,7 +39,7 @@ \installsimplecommandhandler \??blackrules {blackrules} \unexpanded\def\blackrule - {\hbox\bgroup + {\hpack\bgroup \doifelsenextoptionalcs\pack_black_rule_pickup\pack_black_rule_indeed} \def\pack_black_rule_pickup[#1]% @@ -99,7 +99,7 @@ %D would probably have taken more tokens. \unexpanded\def\blackrules % probably never used - {\hbox\bgroup + {\hpack\bgroup \doifelsenextoptionalcs\pack_black_rules_pickup\pack_black_rules_indeed} \def\pack_black_rules_pickup[#1]% @@ -121,23 +121,25 @@ \fi \fi \useblackrulesstyleandcolor\c!style\c!color - \edef\brule - {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname - \lastnamedcs - \else - \vrule - \fi}% - \dorecurse\scratchcounter % a typical case of where we can use a simple loop - {\brule - \s!width \scratchwidth - \s!height\scratchheight - \s!depth \scratchdepth - \ifzeropt\scratchdistance\else - \hskip\scratchdistance - \fi}% + % a typical case of where we can use a simple loop or even a leaders + \dorecurse\scratchcounter\pack_black_rules_step \unskip \egroup} +\def\pack_black_rules_step + {\ifcsname\??blackruletype\directblackrulesparameter\c!type\endcsname + \lastnamedcs + \else + \vrule + \fi + \s!width \scratchwidth + \s!height\scratchheight + \s!depth \scratchdepth + \relax + \ifzeropt\scratchdistance\else + \hskip\scratchdistance + \fi} + \installcorenamespace{blackruletype} \setvalue{\??blackruletype mp}% @@ -578,7 +580,7 @@ {\page[\v!preference] % interferes \directtextrulesparameter\c!before\relax \blank[\v!samepage,\v!nowhite]% - \pack_textrule_with_text{#1}% + \pack_textrule_with_text_yes{#1}% \blank[\v!samepage,\v!nowhite]% \directtextrulesparameter\c!inbetween\relax \endgraf} @@ -598,9 +600,10 @@ \directtextrulesparameter\c!inbetween\relax \page[\v!preference]} -\def\pack_textrule_with_text#1% - {\bgroup - \setbox\scratchbox\hbox to \availablehsize +\def\pack_textrule_with_text_yes#1% + {\noindent % this will force side floats to be calculated + \bgroup + \setbox\scratchbox\hpack to \availablehsize {\scratchwidth \directtextrulesparameter\c!rulethickness\relax \scratchheight\dimexpr .5\exheight+.5\scratchwidth\relax \scratchdepth \dimexpr-.5\exheight+.5\scratchwidth\relax @@ -611,19 +614,41 @@ #1% \hskip\leftmargindistance}} {\color[\directtextrulesparameter\c!rulecolor] - {\vrule\s!height\scratchheight\s!depth\scratchdepth\s!width\directtextrulesparameter\c!width}% + {\vrule + \s!height\scratchheight + \s!depth \scratchdepth + \s!width \directtextrulesparameter\c!width}% \hbox spread 2\dimexpr\directtextrulesparameter\c!distance\relax {\hss \usetextrulesstyleandcolor\c!style\c!color \strut#1% \hss}}}% \color[\directtextrulesparameter\c!rulecolor] - {\leaders\hrule\s!height\scratchheight\s!depth\scratchdepth\hfill}}% + {\leaders\hrule + \s!height\scratchheight + \s!depth \scratchdepth + \hfill}}% \ht\scratchbox\strutht \dp\scratchbox\strutdp - \noindent\box\scratchbox + \box\scratchbox + %\carryoverpar \egroup} +\def\pack_textrule_with_text_nop#1% + {\ifhmode + \endgraf + \fi + \doifelse{\directtextrulesparameter\c!depthcorrection}\v!on + \pack_textrule_correct_depth_yes + \pack_textrule_correct_depth_nop + \nointerlineskip + \noindent\vpack % was \dontleavehmode + {\color[\directtextrulesparameter\c!rulecolor] + {\hrule + \s!depth \directtextrulesparameter\c!rulethickness + \s!height\zeropoint + \s!width \availablehsize}}} + \def\pack_textrule_correct_depth_yes {\vskip\dimexpr \strutdp +.5\exheight @@ -643,15 +668,9 @@ \def\pack_textrule_following#1% {\doifelsenothing{#1} - {\ifhmode - \endgraf - \fi - \doifelse{\directtextrulesparameter\c!depthcorrection}\v!on\pack_textrule_correct_depth_yes\pack_textrule_correct_depth_nop - \nointerlineskip - \noindent\vbox % was \dontleavehmode - {\color[\directtextrulesparameter\c!rulecolor] - {\hrule\s!depth\directtextrulesparameter\c!rulethickness\s!height\zeropoint\s!width\availablehsize}}} - {\pack_textrule_with_text{#1}}% + \pack_textrule_with_text_nop + \pack_textrule_with_text_yes + {#1}% \ifvmode \prevdepth\zeropoint \fi} diff --git a/tex/context/base/mkiv/pack-obj.lua b/tex/context/base/mkiv/pack-obj.lua index 3f2b2edfe..ea36b10de 100644 --- a/tex/context/base/mkiv/pack-obj.lua +++ b/tex/context/base/mkiv/pack-obj.lua @@ -13,9 +13,11 @@ reusable components.

local context = context local codeinjections = backends.codeinjections - local ctx_doifelse = commands.doifelse +local report = logs.reporter("objects") +local trace = false trackers.register("objects",function(v) trace = v end) + local nuts = nodes.nuts local setlink = nuts.setlink @@ -26,10 +28,7 @@ local new_latelua = nuts.pool.latelua local settexdimen = tokens.setters.dimen -local gettexbox = tokens.getters.box -local settexbox = tokens.setters.box -local gettexdimen = tokens.getters.dimen -local gettexcount = tokens.getters.count +local getcount = tex.getcount local implement = interfaces.implement local setmacro = interfaces.setmacro @@ -54,8 +53,16 @@ end job.register('job.objects.collected', tobesaved, initializer, nil) local function saveobject(tag,number,page) - local t = { number, page } - tobesaved[tag], collected[tag] = t, t + local data = { number, page } + tobesaved[tag] = data + collected[tag] = data +end + +local function saveobjectspec(specification) + local tag = specification.tag + local data = { specification.number, specification.page } + tobesaved[tag] = data + collected[tag] = data end local function setobject(tag,number,page) @@ -128,8 +135,9 @@ objects = { local objects = objects function objects.register(ns,id,b,referenced,offset,mode) - objects.n = objects.n + 1 - nodes.handlers.finalize(gettexbox(b),"object") + local n = objects.n + 1 + objects.n = n + nodes.handlers.finalizebox(b) if mode == 0 then -- tex data[ns][id] = { @@ -147,6 +155,9 @@ function objects.register(ns,id,b,referenced,offset,mode) mode, } end + if trace then + report("registering object %a (n=%i)",id,n) + end end function objects.restore(ns,id) -- why not just pass a box number here too (ok, we also set offset) @@ -159,9 +170,12 @@ function objects.restore(ns,id) -- why not just pass a box number here too (ok, local hbox = codeinjections.restoreboxresource(index) -- a nut ! if status then local list = getlist(hbox) - local page = new_latelua(function() - saveobject(ns .. "::" .. id,index,gettexcount("realpageno")) - end) + local page = new_latelua { + action = saveobjectspec, + tag = ns .. "::" .. id, + number = index, + page = getcount("realpageno"), + } setlink(list,page) end setbox("objectbox",hbox) @@ -170,6 +184,9 @@ function objects.restore(ns,id) -- why not just pass a box number here too (ok, setbox("objectbox",nil) settexdimen("objectoff",0) -- for good old times end + if trace then + report("restoring object %a",id) + end end function objects.dimensions(index) @@ -191,7 +208,7 @@ function objects.reference(ns,id) end function objects.page(ns,id) - return getobjectpage(ns .."::" .. id,gettexcount("realpageno")) + return getobjectpage(ns .."::" .. id,getcount("realpageno")) end function objects.found(ns,id) diff --git a/tex/context/base/mkiv/pack-obj.mkiv b/tex/context/base/mkiv/pack-obj.mkiv index aeb5cb4f4..d08c66494 100644 --- a/tex/context/base/mkiv/pack-obj.mkiv +++ b/tex/context/base/mkiv/pack-obj.mkiv @@ -51,7 +51,8 @@ \newdimen\objectht \def\objectheight{\the\objectht} \newdimen\objectdp \def\objectdepth {\the\objectdp} -%D If I have time I will use the unreferenced variant for e.g. mp reuse. +%D If I have time I will use the unreferenced variant for e.g. mp reuse. This can be +%D rewritten in \LUA\ anyway. \unexpanded\def\setreferencedobject #1#2{\begingroup\synctexpause\objectoff\objectoffset\inobjecttrue\dowithnextbox{\pack_objects_set_yes{#1}{#2}}} \unexpanded\def\settightreferencedobject #1#2{\begingroup\synctexpause\objectoff\zeropoint \inobjecttrue\dowithnextbox{\pack_objects_set_yes{#1}{#2}}} @@ -65,14 +66,8 @@ \newconstant\c_pack_objects_offset_mode % 0=tex 1=box -\unexpanded\def\pack_objects_temp_check % this will go away - {\ifnum\texenginefunctionality<6401\relax - \c_pack_objects_offset_mode\zerocount - \fi} - \unexpanded\def\pack_objects_set_yes#1#2% - {\pack_objects_temp_check % this will go away - \ifcase\c_pack_objects_offset_mode + {\ifcase\c_pack_objects_offset_mode \ifzeropt\objectoff \pack_objects_package_nop\nextbox \else @@ -86,8 +81,7 @@ \endgroup} \unexpanded\def\pack_objects_set_nop#1#2% - {\pack_objects_temp_check % this will go away - \ifcase\c_pack_objects_offset_mode + {\ifcase\c_pack_objects_offset_mode \ifzeropt\objectoff \pack_objects_package_nop\nextbox \else diff --git a/tex/context/base/mkiv/pack-rul.lua b/tex/context/base/mkiv/pack-rul.lua index c9771546c..455d0bff8 100644 --- a/tex/context/base/mkiv/pack-rul.lua +++ b/tex/context/base/mkiv/pack-rul.lua @@ -20,42 +20,50 @@ if not modules then modules = { } end modules ['pack-rul'] = { local type = type -local context = context - -local hlist_code = nodes.nodecodes.hlist -local vlist_code = nodes.nodecodes.vlist -local box_code = nodes.listcodes.box -local line_code = nodes.listcodes.line -local equation_code = nodes.listcodes.equation - -local texsetdimen = tex.setdimen -local texsetcount = tex.setcount - -local implement = interfaces.implement - -local nuts = nodes.nuts - -local getnext = nuts.getnext -local getprev = nuts.getprev -local getlist = nuts.getlist -local setlist = nuts.setlist -local getwhd = nuts.getwhd -local getid = nuts.getid -local getsubtype = nuts.getsubtype -local getbox = nuts.getbox -local getdir = nuts.getdir -local setshift = nuts.setshift -local setwidth = nuts.setwidth -local getwidth = nuts.getwidth -local setboxglue = nuts.setboxglue -local getboxglue = nuts.getboxglue - -local hpack = nuts.hpack -local traverse_id = nuts.traverse_id -local list_dimensions = nuts.dimensions -local flush_node = nuts.flush - -local checkformath = false +local context = context + +local nodecodes = nodes.nodecodes +local listcodes = nodes.listcodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist + +local boxlist_code = listcodes.box +local linelist_code = listcodes.line +local equationlist_code = listcodes.equation + +local texsetdimen = tex.setdimen +local texsetcount = tex.setcount + +local implement = interfaces.implement + +local nuts = nodes.nuts + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getlist = nuts.getlist +local setlist = nuts.setlist +local getwhd = nuts.getwhd +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getbox = nuts.getbox +local getdirection = nuts.getdirection +local setshift = nuts.setshift +local setwidth = nuts.setwidth +local getwidth = nuts.getwidth +local setboxglue = nuts.setboxglue +local getboxglue = nuts.getboxglue + +local hpack = nuts.hpack +local getdimensions = nuts.dimensions +local flush_node = nuts.flush + +local traversers = nuts.traversers +local nexthlist = traversers.hlist +local nextvlist = traversers.vlist +local nextlist = traversers.list + +local checkformath = false directives.register("framed.checkmath",function(v) checkformath = v end) -- experiment @@ -76,24 +84,25 @@ local function doreshapeframedbox(n) if boxwidth ~= 0 then -- and h.subtype == vlist_code local list = getlist(box) if list then - local function check(n,repack) + local hdone = false + for n, id, subtype, list in nextlist, list do -- no dir etc needed local width, height, depth = getwhd(n) if not firstheight then firstheight = height end lastdepth = depth noflines = noflines + 1 - local l = getlist(n) - if l then - if repack then - local subtype = getsubtype(n) - if subtype == box_code or subtype == line_code then - lastlinelength = list_dimensions(l,getdir(n)) + if list then + if id == hlist_code then + if subtype == boxlist_code or subtype == linelist_code then + lastlinelength = getdimensions(list) else lastlinelength = width end + hdone = true else lastlinelength = width + -- vdone = true end if lastlinelength > maxwidth then maxwidth = lastlinelength @@ -107,31 +116,19 @@ local function doreshapeframedbox(n) totalwidth = totalwidth + lastlinelength end end - local hdone = false - for h in traverse_id(hlist_code,list) do -- no dir etc needed - check(h,true) - hdone = true - end - -- local vdone = false - for v in traverse_id(vlist_code,list) do -- no dir etc needed - check(v,false) - -- vdone = true - end if not firstheight then -- done) elseif maxwidth ~= 0 then if hdone then - for h in traverse_id(hlist_code,list) do - local l = getlist(h) - if l then - local subtype = getsubtype(h) - if subtype == box_code or subtype == line_code then - local p = hpack(l,maxwidth,'exactly',getdir(h)) -- multiple return value + for h, id, subtype, list in nextlist, list do + if list and id == hlist_code then + if subtype == boxlist_code or subtype == linelist_code then + local p = hpack(list,maxwidth,'exactly',getdirection(h)) -- multiple return value local set, order, sign = getboxglue(p) setboxglue(h,set,order,sign) setlist(p) flush_node(p) - elseif checkformath and subtype == equation_code then + elseif checkformath and subtype == equationlist_code then -- display formulas use a shift if nofnonzero == 1 then setshift(h,0) @@ -142,7 +139,7 @@ local function doreshapeframedbox(n) end end -- if vdone then - -- for v in traverse_id(vlist_code,list) do + -- for v in nextvlist, list do -- local width = getwidth(n) -- if width > maxwidth then -- setwidth(v,maxwidth) @@ -164,7 +161,7 @@ local function doreshapeframedbox(n) texsetdimen("global","framedaveragewidth",averagewidth) end -local function doanalyzeframedbox(n) +local function doanalyzeframedbox(n) -- traverse_list local box = getbox(n) local noflines = 0 local firstheight = nil @@ -172,7 +169,7 @@ local function doanalyzeframedbox(n) if getwidth(box) ~= 0 then local list = getlist(box) if list then - local function check(n) + for n in nexthlist, list do local width, height, depth = getwhd(n) if not firstheight then firstheight = height @@ -180,11 +177,13 @@ local function doanalyzeframedbox(n) lastdepth = depth noflines = noflines + 1 end - for h in traverse_id(hlist_code,list) do - check(h) - end - for v in traverse_id(vlist_code,list) do - check(v) + for n in nextvlist, list do + local width, height, depth = getwhd(n) + if not firstheight then + firstheight = height + end + lastdepth = depth + noflines = noflines + 1 end end end @@ -210,16 +209,11 @@ local function maxboxwidth(box) end local lastlinelength = 0 local maxwidth = 0 - local function check(n,repack) + for n, subtype in nexthlist, list do -- no dir etc needed local l = getlist(n) if l then - if repack then - local subtype = getsubtype(n) - if subtype == box_code or subtype == line_code then - lastlinelength = list_dimensions(l,getdir(n)) - else - lastlinelength = getwidth(n) - end + if subtype == boxlist_code or subtype == linelist_code then + lastlinelength = getdimensions(l) else lastlinelength = getwidth(n) end @@ -228,11 +222,14 @@ local function maxboxwidth(box) end end end - for h in traverse_id(hlist_code,list) do -- no dir etc needed - check(h,true) - end - for v in traverse_id(vlist_code,list) do -- no dir etc needed - check(v,false) + for n, subtype in nextvlist, list do -- no dir etc needed + local l = getlist(n) + if l then + lastlinelength = getwidth(n) + if lastlinelength > maxwidth then + maxwidth = lastlinelength + end + end end return maxwidth end diff --git a/tex/context/base/mkiv/pack-rul.mkiv b/tex/context/base/mkiv/pack-rul.mkiv index c208baaf0..3d03942aa 100644 --- a/tex/context/base/mkiv/pack-rul.mkiv +++ b/tex/context/base/mkiv/pack-rul.mkiv @@ -18,7 +18,7 @@ %D packaging and expansion we also keep tracing reasonable. For instance, multiple %D stacked backgrounds can slow down a run if not optimized this way. -\registerctxluafile{pack-rul}{} +\registerctxluafile{pack-rul}{optimize} \unprotect @@ -141,6 +141,7 @@ \setupframed [\c!width=\v!fit, \c!height=\v!broad, + %\c!minheight=\zeropoint, %\c!lines=, \c!offset=.25\exheight, % \defaultframeoffset \c!empty=\v!no, @@ -239,7 +240,6 @@ \let\p_framed_backgroundcolor \empty \let\p_framed_framecolor \empty \let\p_framed_component \empty -\let\p_framed_region \empty \let\p_framed_background \empty \let\p_framed_rulethickness \empty \let\p_framed_foregroundcolor \empty @@ -443,6 +443,8 @@ \newdimen\d_overlay_offset \newdimen\d_overlay_linewidth +\let\m_overlay_region\empty + % expandable ... in a future version the space will go (in my one can use Overlay*) \def\overlaywidth {\the\d_overlay_width \space} % We preset the variables @@ -450,6 +452,7 @@ \def\overlaydepth {\the\d_overlay_depth \space} % values. \def\overlayoffset {\the\d_overlay_offset \space} % of the frame can be (are) \def\overlaylinewidth {\the\d_overlay_linewidth\space} % set somewhere else. +\def\overlayregion {\m_overlay_region} % public but kind of protected @@ -553,40 +556,36 @@ \def\pack_framed_process_background_indeed_internal#1% % : in name {\bgroup - \setbox\b_framed_extra\hbox{%\bgroup - \ifzeropt\framedbackgroundoffset - %\csname\??overlaybuiltin\m_framed_background\endcsname - #1 - \else + \setbox\b_framed_extra\hpack\bgroup + \ifzeropt\framedbackgroundoffset\else \kern-\framedbackgroundoffset - %\hbox{\csname\??overlaybuiltin\m_framed_background\endcsname}% - \hbox{#1}% \fi - }%\egroup + \hbox\bgroup#1\egroup + \egroup \wd\b_framed_extra\zeropoint \ht\b_framed_extra\framedbackgroundheight \dp\b_framed_extra\framedbackgrounddepth \box\b_framed_extra \egroup} -\def\pack_framed_process_background_indeed_external#1% +% \def\pack_framed_process_background_indeed_external#1% +% {\pack_framed_overlay_initialize +% \bgroup +% \setbox\b_framed_extra\hpack\bgroup +% \ifzeropt\framedbackgroundoffset\else +% \kern-\framedbackgroundoffset +% \fi +% \hbox\bgroup#1\egroup +% \egroup +% \wd\b_framed_extra\zeropoint +% \ht\b_framed_extra\framedbackgroundheight +% \dp\b_framed_extra\framedbackgrounddepth +% \box\b_framed_extra +% \egroup} + +\def\pack_framed_process_background_indeed_external {\pack_framed_overlay_initialize - \bgroup - \setbox\b_framed_extra\hbox{%\bgroup - \ifzeropt\framedbackgroundoffset - %\csname\??overlay\m_framed_background\endcsname - #1% - \else - \kern-\framedbackgroundoffset - %\hbox{\csname\??overlay\m_framed_background\endcsname}% - \hbox{#1}% - \fi - }%\egroup - \wd\b_framed_extra\zeropoint - \ht\b_framed_extra\framedbackgroundheight - \dp\b_framed_extra\framedbackgrounddepth - \box\b_framed_extra - \egroup} + \pack_framed_process_background_indeed_internal} \def\pack_framed_process_backgrounds#1,#2% #2 gobbles spaces (we could avoid one catch if we have nextbackground) {\edef\m_framed_background{#1}% @@ -606,15 +605,23 @@ \def\pack_framed_background_box_content% fuzzy but needed hack, this \vss, otherwise {\vpack to \framedbackgroundheight{\vss\box\b_framed_normal\vss}} % vertical shift \backgroundheight -\def\pack_framed_add_region % experiment - {\ifx\p_framed_region\v!yes - \anch_mark_region_box\b_framed_normal - \else - \anch_mark_tagged_box\b_framed_normal\p_framed_region +\def\pack_framed_set_region % experiment + {\ifx\m_overlay_region\v!yes + \edef\m_overlay_region{\reservedautoregiontag}% \fi} +% \def\pack_framed_add_region % experiment +% {\ifx\m_overlay_region\v!yes +% \anch_mark_region_box\b_framed_normal +% \else +% \anch_mark_tagged_box\b_framed_normal\m_overlay_region +% \fi} + +\def\pack_framed_add_region % experiment + {\anch_mark_tagged_box\b_framed_normal\m_overlay_region} + \def\pack_framed_add_background - {\setbox\b_framed_normal\hbox % was vbox % see also *1* + {\setbox\b_framed_normal\hpack % was vbox % see also *1* {%\pack_framed_forgetall % can be relaxed \boxmaxdepth\maxdimen \framedbackgroundoffset\d_framed_backgroundoffset @@ -631,7 +638,7 @@ \setlayoutcomponentattribute{\v!background:\p_framed_component}% \fi \let\foregroundbox\pack_framed_background_box_content - \hbox \layoutcomponentboxattribute to \framedbackgroundwidth\bgroup % width in case 'foreground' is used as overlay + \hpack \layoutcomponentboxattribute to \framedbackgroundwidth\bgroup % width in case 'foreground' is used as overlay \the\everybackgroundbox % moved \expandafter\pack_framed_process_backgrounds\p_framed_background,\s!unknown,\relax % hm, messy .. look into it \box\b_framed_normal @@ -692,10 +699,10 @@ \scratchdimen\zeropoint \fi \edef\overlaylinecolor{\framedparameter\c!framecolor}% twice, also in background - \setbox\b_framed_extra\hbox + \setbox\b_framed_extra\hpack {\kern-\d_framed_frameoffset \raise\scratchdimen - \hbox{\ifx\overlaylinecolor\empty\else\dousecolorparameter\overlaylinecolor\fi\pack_framed_stroked_box}}% + \hpack{\ifx\overlaylinecolor\empty\else\dousecolorparameter\overlaylinecolor\fi\pack_framed_stroked_box}}% \wd\b_framed_extra\wd\b_framed_normal \ht\b_framed_extra\ht\b_framed_normal \dp\b_framed_extra\dp\b_framed_normal @@ -724,26 +731,45 @@ % \dp\scratchbox\d_framed_target_dp % \box\scratchbox} -\def\pack_framed_stroked_box_normal +\def\pack_framed_stroked_box_normal_opened {\setbox\scratchbox\vpack \bgroup - \csname \??framedtop\p_framed_frame\framedparameter\c!topframe \endcsname + \csname\??framedtop\p_framed_frame\framedparameter\c!topframe\endcsname \nointerlineskip % new (needed for fences) - \hbox \bgroup - \csname \??framedleft\p_framed_frame\framedparameter\c!leftframe \endcsname + \hpack \bgroup + \csname\??framedleft\p_framed_frame\framedparameter\c!leftframe\endcsname \novrule \s!width \d_framed_target_wd \s!height\d_framed_target_ht \s!depth \d_framed_target_dp - \csname \??framedright\p_framed_frame\framedparameter\c!rightframe \endcsname + \csname\??framedright\p_framed_frame\framedparameter\c!rightframe\endcsname \egroup \nointerlineskip % new (needed for fences) - \csname \??framedbottom\p_framed_frame\framedparameter\c!bottomframe\endcsname + \csname\??framedbottom\p_framed_frame\framedparameter\c!bottomframe\endcsname \egroup \wd\scratchbox\d_framed_target_wd \ht\scratchbox\d_framed_target_ht \dp\scratchbox\d_framed_target_dp \box\scratchbox} +\def\pack_framed_stroked_box_normal_closed + {\hpack\bgroup + \scratchdimen.5\d_framed_linewidth + \hskip\scratchdimen + \clf_framedoutline + \dimexpr\d_framed_target_wd-\d_framed_linewidth\relax + \dimexpr\d_framed_target_ht-\scratchdimen\relax + \dimexpr\d_framed_target_dp-\scratchdimen\relax + \d_framed_linewidth + \relax + \egroup} + +\def\pack_framed_stroked_box_normal + {\ifx\p_framed_frame\v!closed + \pack_framed_stroked_box_normal_closed + \else + \pack_framed_stroked_box_normal_opened + \fi} + \def\pack_framed_t_rule{\hrule\s!height\d_framed_linewidth\kern-\d_framed_linewidth} \def\pack_framed_b_rule{\kern-\d_framed_linewidth\hrule\s!height\d_framed_linewidth} \def\pack_framed_r_rule{\kern-\d_framed_linewidth\vrule\s!width\d_framed_linewidth} @@ -836,7 +862,7 @@ %D for passing this identifier between brackets lays in the mere fact that this way %D we can use the optional argument grabbers. -\def\defaultframeoffset{.25ex} +\def\defaultframeoffset{.25\exheight} \installcorenamespace{regularframedlevel} @@ -999,9 +1025,11 @@ \edef\currentframed{#1}% \pack_framed_initialize \setbox\b_framed_normal\hbox{#4}% - \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\v!yes % maybe later named - \pack_framed_add_region + \iftrialtypesetting \else + \edef\m_overlay_region{\framedparameter\c!region}% + \ifx\m_overlay_region\empty\else + \pack_framed_set_region + \fi \fi \setupcurrentframed[#3]% \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds @@ -1028,6 +1056,11 @@ \pack_framed_add_background \fi \pack_framed_restore_depth + \iftrialtypesetting \else + \ifx\m_overlay_region\empty\else + \pack_framed_add_region + \fi + \fi \box\b_framed_normal \egroup} @@ -1036,9 +1069,9 @@ \unexpanded\def\pack_framed_process_box_indeed#1#2% component box (assumes parameters set and grouped usage) {\setbox\b_framed_normal\box#2% could actually be \let\b_framed_normal#2 - \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\empty\else - \pack_framed_add_region + \edef\m_overlay_region{\framedparameter\c!region}% + \ifx\m_overlay_region\empty\else + \pack_framed_set_region \fi \edef\p_framed_rulethickness{\framedparameter\c!rulethickness}% also used in backgrounds \d_framed_frameoffset\framedparameter\c!frameoffset\relax % also used in backgrounds @@ -1061,6 +1094,9 @@ \edef\p_framed_component{#1}% \pack_framed_add_background \fi + \ifx\m_overlay_region\empty\else + \pack_framed_add_region + \fi \box\b_framed_normal \egroup} @@ -1602,6 +1638,13 @@ \fi \ifconditional\c_framed_has_height \ht\b_framed_normal\d_framed_height + \else + \edef\p_framed_minheight{\framedparameter\c!minheight}% + \ifx\p_framed_minheight\empty \else + \ifdim\ht\b_framed_normal<\p_framed_minheight + \ht\b_framed_normal\p_framed_minheight + \fi + \fi \fi \edef\p_framed_empty{\framedparameter\c!empty}% \ifx\p_framed_empty\v!yes @@ -1609,9 +1652,9 @@ \fi \pack_framed_stop_orientation % moved here at 2014-05-25 \iftrialtypesetting \else - \edef\p_framed_region{\framedparameter\c!region}% - \ifx\p_framed_region\empty\else - \pack_framed_add_region + \edef\m_overlay_region{\framedparameter\c!region}% + \ifx\m_overlay_region\empty\else + \pack_framed_set_region \fi \fi \d_framed_applied_offset @@ -1649,6 +1692,11 @@ \fi \fi \pack_framed_locator_after\p_framed_location + \iftrialtypesetting \else + \ifx\m_overlay_region\empty\else + \pack_framed_add_region + \fi + \fi \box\b_framed_normal \global\frameddimensionstate % global so to be used directly afterwards ! \ifconditional\c_framed_has_width @@ -2203,7 +2251,7 @@ \ignorespaces} \def\dododoformatonelinerbox - {\hbox to \hsize % maybe \hpack + {\hpack to \hsize % was \hbox {\ifcase\raggedstatus\or\hss\or\hss \fi \unhbox\nextbox \removeunwantedspaces \ifcase\raggedstatus\or \or\hss\or\hss\fi}% @@ -2324,7 +2372,7 @@ \doformatonelinerbox} \def\pack_framed_format_format_vsize - {\vbox to \d_framed_height + {\vbox to \d_framed_height % no vpack .. maybe grid \bgroup \let\postprocessframebox\relax % \pack_framed_forgetall @@ -2551,9 +2599,9 @@ \par \kern-\d_framed_linewidth \dontleavehmode - \hpack to \zeropoint{\normalhss\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth}% + \hpack to \zeropoint{\hss\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth}% \hfill - \hpack to \zeropoint{\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth\normalhss}% + \hpack to \zeropoint{\vrule\s!height\d_framed_linewidth\s!depth\zeropoint\s!width\scratchwidth\hss}% \par \nointerlineskip \kern\scratchoffset @@ -2792,7 +2840,7 @@ \csname\??framedtextlocation\framedtextparameter\c!location\endcsname \resetframedtextparameter\c!location \pack_framed_text_check - \setbox\b_framed_normal\vbox + \setbox\b_framed_normal\vbox % \vpack \startboxedcontent \hsize\localhsize % \insidefloattrue % ? better @@ -3069,7 +3117,7 @@ \fi} \def\pack_framed_start_content_indeed - {\setbox\b_framed_normal\hbox\bgroup % maybe \hpack + {\setbox\b_framed_normal\hpack\bgroup \setlocalhsize \hsize\localhsize \scratchleftoffset \framedcontentparameter\c!leftoffset \relax @@ -3079,16 +3127,16 @@ \advance\hsize\dimexpr-\scratchleftoffset-\scratchrightoffset \relax \advance\vsize\dimexpr-\scratchtopoffset -\scratchbottomoffset\relax \kern\scratchleftoffset - \vbox\bgroup + \vpack\bgroup \vskip\scratchtopoffset - \vbox\bgroup - \forgetall - \blank[\v!disable]} + \vbox\bgroup + \forgetall + \blank[\v!disable]} \def\pack_framed_stop_content_indeed - {\removelastskip - \egroup - \vskip\scratchbottomoffset + {\removelastskip + \egroup + \vskip\scratchbottomoffset \egroup \kern\scratchrightoffset \egroup @@ -3132,4 +3180,16 @@ \let\themaxboxwidth\clf_themaxboxwidth +%D New: slow but ok for most cases: + +\unexpanded\def\doifelseframed#1% + {\ifcase\numexpr\zerocount + \immediateassignment\edef\tempstring{#1\c!frame }\ifx\tempstring\v!on +\plusone\fi + \immediateassignment\edef\tempstring{#1\c!topframe }\ifx\tempstring\v!on +\plusone\fi + \immediateassignment\edef\tempstring{#1\c!bottomframe}\ifx\tempstring\v!on +\plusone\fi + \immediateassignment\edef\tempstring{#1\c!leftframe }\ifx\tempstring\v!on +\plusone\fi + \immediateassignment\edef\tempstring{#1\c!rightframe }\ifx\tempstring\v!on +\plusone\fi + \immediateassignment\edef\tempstring{#1\c!background }\ifx\tempstring\empty\else+\plusone\fi + \relax\expandafter\secondoftwoarguments\else\expandafter\firstoftwoarguments\fi} + \protect \endinput diff --git a/tex/context/base/mkiv/page-bck.mkiv b/tex/context/base/mkiv/page-bck.mkiv index b44910bbe..1ec7cdbb8 100644 --- a/tex/context/base/mkiv/page-bck.mkiv +++ b/tex/context/base/mkiv/page-bck.mkiv @@ -52,7 +52,7 @@ \let\currentotrbackground\empty -%D This is the only spot where we hav ea low level dependency on the way +%D This is the only spot where we have a low level dependency on the way %D parent chains are defined but we want the speed. \unexpanded\def\page_backgrounds_check_background diff --git a/tex/context/base/mkiv/page-box.mkvi b/tex/context/base/mkiv/page-box.mkvi index 083a94390..10d591631 100644 --- a/tex/context/base/mkiv/page-box.mkvi +++ b/tex/context/base/mkiv/page-box.mkvi @@ -15,7 +15,7 @@ \unprotect -%D The often two step approach (_indeed) saves skippign tokens +%D The often two step approach (_indeed) saves skipping tokens %D which is nicer for tracing. %D Centering the paper area on the print area is determined @@ -251,14 +251,25 @@ \def\page_boxes_apply_offsets#1% {\setbox#1\vpack to \paperheight {\hsize\paperwidth - \vskip\topspace - \doifbothsides - {\hskip\backspace} - {\hskip\backspace} - {\hskip\dimexpr\paperwidth-\backspace-\makeupwidth\relax}% + \vkern\topspace +% \parfillskip\zeropoint + \hkern\doifbothsides\backspace\backspace{\dimexpr\paperwidth-\backspace-\makeupwidth\relax}% \box#1}% \dp#1\zeropoint} +% \def\page_boxes_apply_offset#box% +% {\scratchwidth \wd#box% +% \scratchheight\ht#box% +% \scratchdepth \dp#box% +% \setbox#box\vpack +% {\offinterlineskip +% \vkern\topoffset +% \hkern\doifbothsides\backoffset\backoffset{-\backoffset}% +% \box#box}% +% \wd#box\scratchwidth +% \ht#box\scratchheight +% \dp#box\scratchdepth} + % \let\page_boxes_apply_clip_paper \gobbleoneargument % \let\page_boxes_apply_clip_print_left \gobbleoneargument % \let\page_boxes_apply_clip_print_right\gobbleoneargument diff --git a/tex/context/base/mkiv/page-cst.lua b/tex/context/base/mkiv/page-cst.lua index 155d6e8b0..1c2f5fc0b 100644 --- a/tex/context/base/mkiv/page-cst.lua +++ b/tex/context/base/mkiv/page-cst.lua @@ -19,87 +19,86 @@ local trace_cells = false trackers.register("columnsets.cells", function(v) t local report = logs.reporter("column sets") -local setmetatableindex = table.setmetatableindex - -local properties = nodes.properties - -local nodecodes = nodes.nodecodes -local rulecodes = nodes.rulecodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local kern_code = nodecodes.kern -local glue_code = nodecodes.glue -local penalty_code = nodecodes.penalty -local rule_code = nodecodes.rule - -local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut - -local hpack = nuts.hpack -local vpack = nuts.vpack -local flushlist = nuts.flush_list ------ removenode = nuts.remove - -local setlink = nuts.setlink -local setlist = nuts.setlist -local setnext = nuts.setnext -local setprev = nuts.setprev -local setsubtype = nuts.setsubtype -local setbox = nuts.setbox -local getwhd = nuts.getwhd -local setwhd = nuts.setwhd -local getkern = nuts.getkern -local getpenalty = nuts.getpenalty -local getwidth = nuts.getwidth -local getheight = nuts.getheight - -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getlist = nuts.getlist -local getsubtype = nuts.getsubtype -local takebox = nuts.takebox -local takelist = nuts.takelist -local splitbox = nuts.splitbox -local getattribute = nuts.getattribute -local copylist = nuts.copy_list - -local getbox = nuts.getbox -local getcount = tex.getcount -local getdimen = tex.getdimen - -local texsetbox = tex.setbox -local texsetcount = tex.setcount -local texsetdimen = tex.setdimen - -local theprop = nuts.theprop - -local nodepool = nuts.pool - -local new_vlist = nodepool.vlist -local new_trace_rule = nodepool.rule -local new_empty_rule = nodepool.emptyrule - -local context = context -local implement = interfaces.implement - -local variables = interfaces.variables -local v_here = variables.here -local v_fixed = variables.fixed -local v_top = variables.top -local v_bottom = variables.bottom -local v_repeat = variables["repeat"] -local v_yes = variables.yes -local v_page = variables.page -local v_first = variables.first -local v_last = variables.last ------ v_wide = variables.wide - -pagebuilders = pagebuilders or { } -- todo: pages.builders -pagebuilders.columnsets = pagebuilders.columnsets or { } -local columnsets = pagebuilders.columnsets +local setmetatableindex = table.setmetatableindex + +local properties = nodes.properties + +local nodecodes = nodes.nodecodes + +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local kern_code = nodecodes.kern +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local rule_code = nodecodes.rule + +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut + +local hpack = nuts.hpack +local vpack = nuts.vpack +local flushlist = nuts.flush_list +----- removenode = nuts.remove + +local setlink = nuts.setlink +local setlist = nuts.setlist +local setnext = nuts.setnext +local setprev = nuts.setprev +local setsubtype = nuts.setsubtype +local setbox = nuts.setbox +local getwhd = nuts.getwhd +local setwhd = nuts.setwhd +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local getwidth = nuts.getwidth +local getheight = nuts.getheight + +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getlist = nuts.getlist +local getsubtype = nuts.getsubtype +local takebox = nuts.takebox +local takelist = nuts.takelist +local splitbox = nuts.splitbox +local getattribute = nuts.getattribute +local copylist = nuts.copy_list + +local getbox = nuts.getbox +local getcount = tex.getcount +local getdimen = tex.getdimen + +local texsetbox = tex.setbox +local texsetcount = tex.setcount +local texsetdimen = tex.setdimen + +local theprop = nuts.theprop + +local nodepool = nuts.pool + +local new_vlist = nodepool.vlist +local new_trace_rule = nodepool.rule +local new_empty_rule = nodepool.emptyrule + +local context = context +local implement = interfaces.implement + +local variables = interfaces.variables +local v_here = variables.here +local v_fixed = variables.fixed +local v_top = variables.top +local v_bottom = variables.bottom +local v_repeat = variables["repeat"] +local v_yes = variables.yes +local v_page = variables.page +local v_first = variables.first +local v_last = variables.last +----- v_wide = variables.wide + +pagebuilders = pagebuilders or { } -- todo: pages.builders +pagebuilders.columnsets = pagebuilders.columnsets or { } +local columnsets = pagebuilders.columnsets local data = { [""] = { } } diff --git a/tex/context/base/mkiv/page-cst.mkiv b/tex/context/base/mkiv/page-cst.mkiv index f6eede68a..37df4e8b1 100644 --- a/tex/context/base/mkiv/page-cst.mkiv +++ b/tex/context/base/mkiv/page-cst.mkiv @@ -765,7 +765,7 @@ % state start | repeat -% for now (transition) +%D The old one: \let\definecolumnset \definepagegrid \let\setupcolumnset \setuppagegrid @@ -782,5 +782,6 @@ \let\setupcolumnsetarea \setuppagegridarea \let\setupcolumnsetareatext\setuppagegridareatext -\protect +%D It ends here. +\protect \endinput diff --git a/tex/context/base/mkiv/page-ffl.mkiv b/tex/context/base/mkiv/page-ffl.mkiv index 5536371a7..414cae4ac 100644 --- a/tex/context/base/mkiv/page-ffl.mkiv +++ b/tex/context/base/mkiv/page-ffl.mkiv @@ -84,26 +84,29 @@ \def\strc_floats_facing_flush {\ifnum\c_strc_floats_flushed<\c_strc_floats_saved - \global\advance\c_strc_floats_flushed\plusone - \floatingpenalty\zerocount - \insert\namedinsertionnumber\s!topfloat\bgroup - \forgetall - \ifconditional\c_page_one_top_of_insert - \ifconditional\c_page_one_correct_top_insert - \topskipcorrection % [xx] new: see icare topbleed - \kern-\lineskip - \par - \prevdepth\maxdimen - \fi + \strc_floats_facing_flush_indeed % less tracing + \fi} + +\def\strc_floats_facing_flush_indeed + {\global\advance\c_strc_floats_flushed\plusone + \floatingpenalty\zerocount + \insert\namedinsertionnumber\s!topfloat\bgroup + \forgetall + \ifconditional\c_page_one_top_of_insert + \ifconditional\c_page_one_correct_top_insert + \topskipcorrection % [xx] new: see icare topbleed + \kern-\lineskip + \par + \prevdepth\maxdimen \fi - \directboxfromcache{\currentfacingfloat}{\number\c_strc_floats_flushed}% - \vskip\s_page_one_between_top_insert - \egroup - \ifnum\c_strc_floats_saved=\c_strc_floats_flushed - \global\c_strc_floats_saved \zerocount - \global\c_strc_floats_flushed\zerocount - \resetboxesincache{\currentfacingfloat}% \fi + \directboxfromcache{\currentfacingfloat}{\number\c_strc_floats_flushed}% + \vkern\s_page_one_between_top_insert + \egroup + \ifnum\c_strc_floats_saved=\c_strc_floats_flushed + \global\c_strc_floats_saved \zerocount + \global\c_strc_floats_flushed\zerocount + \resetboxesincache{\currentfacingfloat}% \fi} \unexpanded\def\strc_floats_facing_setup diff --git a/tex/context/base/mkiv/page-flt.mkiv b/tex/context/base/mkiv/page-flt.mkiv index a06c90ec1..83e2b4954 100644 --- a/tex/context/base/mkiv/page-flt.mkiv +++ b/tex/context/base/mkiv/page-flt.mkiv @@ -284,16 +284,16 @@ \doifnotinset\v!low\floatspecification\vfill}% \page_otr_fill_and_eject_page} -\let\m_page_otf_checked_page_float\relax +\let\m_page_otr_checked_page_float\relax \unexpanded\def\page_floats_flush_page_floats % used in postpone - {\edef\m_page_otf_checked_page_float{\clf_checkedpagefloat}% - \ifx\m_page_otf_checked_page_float\empty + {\edef\m_page_otr_checked_page_float{\clf_checkedpagefloat}% + \ifx\m_page_otr_checked_page_float\empty % nothing - \else\ifx\m_page_otf_checked_page_float\v!empty + \else\ifx\m_page_otr_checked_page_float\v!empty \emptyhbox \page_otr_fill_and_eject_page % why not dummy_page \else - \page_floats_flush_page_floats_indeed\m_page_otf_checked_page_float + \page_floats_flush_page_floats_indeed\m_page_otr_checked_page_float \fi\fi} % temp hack, needed to prevent floatbox being forgotten during diff --git a/tex/context/base/mkiv/page-imp.mkiv b/tex/context/base/mkiv/page-imp.mkiv index c08f9856f..838ad7421 100644 --- a/tex/context/base/mkiv/page-imp.mkiv +++ b/tex/context/base/mkiv/page-imp.mkiv @@ -26,7 +26,7 @@ \newtoks\t_page_text_data \unexpanded\def\starttextdata#1\stoptextdata - {\global\let\page_shipouts_flush_text_data\page_shipouts_flush_text_data_indeed + {\glet\page_shipouts_flush_text_data\page_shipouts_flush_text_data_indeed \globaladdtotoks\t_page_text_data{#1}} \let\stoptextdata\relax @@ -34,7 +34,7 @@ \def\page_shipouts_flush_text_data_indeed {\vsmashed{\the\t_page_text_data}% \global\t_page_text_data\emptytoks - \global\let\page_shipouts_flush_text_data\relax} + \glet\page_shipouts_flush_text_data\relax} \let\page_shipouts_flush_text_data\relax @@ -63,9 +63,21 @@ \newbox \shipoutscratchbox -\setnewconstant\shipoutfinalizemethod\plusone % this will be default (we will have two finalizers) +\setnewconstant\shipoutfinalizemethod\plusone -\unexpanded\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed +\unexpanded\def\shipoutrange#1#2% + {\begingroup + \scratchtoks\emptytoks + \dostepwiserecurse{#1}{\numexpr#2-\plusone\relax}\plusone{\etoksapp\scratchtoks{##1,}}% + \xdef\pagestoshipout{\the\scratchtoks,\number#2}% + \doglobal\appendtoks + \ifnum\realpageno>\numexpr#2+\plusone\relax + \global\everypar{\normalend}% + \fi + \to\everyaftershipout + \endgroup} + +\unexpanded\def\installshipoutmethod#1#2% % a handler takes one argument: something to be boxed {\setgvalue{\??shipoutmethod#1}##1{#2{##1}}} % and shipped out (don't depend on the exact package) \let\installpagehandler\installshipoutmethod % will go @@ -73,13 +85,6 @@ \unexpanded\def\invokepagehandler#1% {\expandnamespacevalue\??shipoutmethod{#1}\v!normal} -% \def\page_shipouts_handle -% {\csname\??shipoutmethod\ifcsname\??shipoutmethod\v_page_target_method\endcsname -% \v_page_target_method -% \else -% \v!none -% \fi\endcsname} - \def\page_shipouts_handle {\ifcsname\??shipoutmethod\v_page_target_method\endcsname \expandafter\lastnamedcs @@ -112,12 +117,14 @@ \page_boxes_flush_before \fi \the\everybeforeshipout - \ifcase\shipoutfinalizemethod + \ifcase\shipoutfinalizemethod % not nice ... needs thinking \page_shipouts_handle{#1}% \else - \setbox\shipoutscratchbox\hpack{#1}% just in case there are objects there, hook for testing (will go away) - \finalizeshipoutbox\shipoutscratchbox - \page_shipouts_handle{\box\shipoutscratchbox}% + \setbox\shipoutscratchbox\hpack + {#1}% just in case there are objects there, hook for testing (will go away) + \page_shipouts_handle + {\finalizeshipoutbox\shipoutscratchbox + \box\shipoutscratchbox}% \fi \setnextrealpageno % so this comes before \everyaftershipout so in fact: \the\everyaftershipout % at this point we're already on the next realpage @@ -127,11 +134,12 @@ \def\page_shipouts_ignore#1% {\begingroup - \message - {[\ifarrangingpages arranged \fi page + \writestatus\m!system + {\ifarrangingpages arranged \fi page \ifarrangingpages\the\arrangeno\else\the\realpageno\fi\normalspace - not flushed]}% - \setbox\scratchbox\hpack{#1}% + not flushed}% + % \setbox\scratchbox\hpack + % {#1}% no finalize \deadcycles\zerocount \endgroup} @@ -154,7 +162,11 @@ \box\scratchbox \endgroup} -\newdimen\d_page_shipouts_offset \d_page_shipouts_offset=-1in +\ifdefined \page_shipout_box \else + + \def\page_shipout_box#1{\normalshipout\box#1\relax} % takes a number + +\fi \def\page_shipouts_normal#1% {\global\advance\shippedoutpages\plusone @@ -173,30 +185,36 @@ \normalexpanded{\doifelseinset{\the\shippedoutpages}{\pagestoshipout}}\donetrue\donefalse \fi \ifdone - \setbox\shipoutscratchbox\hpack{#1}% + \setbox\shipoutscratchbox\hpack + {#1}% finalizes \ifcase\shipoutfinalizemethod \finalizeshipoutbox\shipoutscratchbox \fi - \normalshipout\vpack - {\offinterlineskip - \vskip\d_page_shipouts_offset - \hskip\d_page_shipouts_offset + \setbox\shipoutscratchbox\vpack + {\scratchdimen\clf_shipoutoffset\relax + \ifdim\scratchdimen=\zeropoint\else + \offinterlineskip + \vkern\scratchdimen + \hkern\scratchdimen + \fi \hpack {\page_otr_flush_every_stuff \page_otr_flush_special_content \box\shipoutscratchbox}}% + \page_shipout_box\shipoutscratchbox % takes a box number! \else \page_shipouts_ignore{#1}% \fi} \def\page_shipouts_arrange#1% - {% \global\advance\shippedoutpages\plusone - \begingroup - \setbox\scratchbox\hpack + {\begingroup + \setbox\shipoutscratchbox\hpack + {#1}% finalizes + \setbox\shipoutscratchbox\hpack {\page_otr_flush_every_stuff \page_otr_flush_special_content \box\shipoutscratchbox}% - \pusharrangedpage\scratchbox + \pusharrangedpage\shipoutscratchbox \deadcycles\zerocount \endgroup} @@ -310,14 +328,14 @@ \let\pusharrangedpage\relax \def\dosetuparrangement#1#2#3#4#5#6#7#8% - {\global\arrangedpageX #1% - \global\arrangedpageY #2% - \global\arrangedpageT #3% - \global\c_page_marks_nx #4% - \global\c_page_marks_ny #5% - \global\let\pusharrangedpage #6% - \global\let\poparrangedpages #7% - \global\let\handlearrangedpage#8} + {\global\arrangedpageX #1% + \global\arrangedpageY #2% + \global\arrangedpageT #3% + \global\c_page_marks_nx #4% + \global\c_page_marks_ny #5% + \glet \pusharrangedpage #6% + \glet \poparrangedpages #7% + \glet \handlearrangedpage#8} \installpagearrangement {\v!normal} {\global\arrangingpagesfalse} diff --git a/tex/context/base/mkiv/page-inf.mkiv b/tex/context/base/mkiv/page-inf.mkiv index 2064f9f25..4519083bf 100644 --- a/tex/context/base/mkiv/page-inf.mkiv +++ b/tex/context/base/mkiv/page-inf.mkiv @@ -112,14 +112,16 @@ {\vfill \settexthoffset \hsize\dimexpr\scratchdimen-2\texthoffset\relax - \hskip\texthoffset % brrrr + \hkern\texthoffset % brrrr \vbox to \zeropoint{\vss\page_info_place_info}% - \vskip\bodyfontsize}% + \vkern\bodyfontsize}% \dp\b_page_versions\zeropoint \wd\b_page_versions\scratchdimen - \setbox#1\hpack{\box#1\hskip-\scratchdimen\box\b_page_versions}} + \setbox#1\hpack{\box#1\hkern-\scratchdimen\box\b_page_versions}} \setupversion % resets [\v!final] +\let\page_info_add_to_box\gobbleoneargument + \protect \endinput diff --git a/tex/context/base/mkiv/page-ini.lua b/tex/context/base/mkiv/page-ini.lua index 5b73c9729..3d5534128 100644 --- a/tex/context/base/mkiv/page-ini.lua +++ b/tex/context/base/mkiv/page-ini.lua @@ -41,23 +41,39 @@ function pages.mark(name,list) local page = list[i] local sign = false if type(page) == "string" then - local s, p = match(page,"([%+%-])(%d+)") - if s then - sign, page = s, p + local f, t = match(page,"(%d+)[:%-](%d+)") + if f and t then + f, t = tonumber(f), tonumber(t) + if f and t and f <= t then + if trace then + report("marking page %i upto %i as %a",f,t,name) + end + for page=f,t do + data[page][name] = true + end + end + page = false + else + local s, p = match(page,"([%+%-])(%d+)") + if s then + sign, page = s, p + end end end - page = tonumber(page) if page then - if sign == "+" then - page = realpage + page - end - if sign == "-" then - report("negative page numbers are not supported") - else - if trace then - report("marking page %i as %a",page,name) + page = tonumber(page) + if page then + if sign == "+" then + page = realpage + page + end + if sign == "-" then + report("negative page numbers are not supported") + else + if trace then + report("marking page %i as %a",page,name) + end + data[page][name] = true end - data[page][name] = true end end end @@ -75,7 +91,6 @@ local function marked(name) rawset(data,i,nil) end local pagedata = rawget(data,realpage) - print(pagedata and pagedata[name] and true or false) return pagedata and pagedata[name] and true or false end diff --git a/tex/context/base/mkiv/page-ini.mkiv b/tex/context/base/mkiv/page-ini.mkiv index dc94edf76..38477dc27 100644 --- a/tex/context/base/mkiv/page-ini.mkiv +++ b/tex/context/base/mkiv/page-ini.mkiv @@ -80,7 +80,7 @@ \fi} \def\page_otr_flush_pending_content - {\vskip\zeropoint\relax + {\vkern\zeropoint\relax \ifvoid\normalpagebox \else \unvbox\normalpagebox \penalty\outputpenalty @@ -256,7 +256,10 @@ \box\pagebox \egroup \ifconditional\c_page_boxes_save_page_body \copy\b_page_boxes_saved_page_body \fi} -\appendtoks \restoreglobalbodyfont \to \everybeforepagebody +\appendtoks + \restoreglobalbodyfont + \pickupattributes +\to \everybeforepagebody \ifdefined\nestednewbox \else \newbox\nestednextbox \fi % hm, still needed? diff --git a/tex/context/base/mkiv/page-inj.mkvi b/tex/context/base/mkiv/page-inj.mkvi index cabd07bac..5f48ffd13 100644 --- a/tex/context/base/mkiv/page-inj.mkvi +++ b/tex/context/base/mkiv/page-inj.mkvi @@ -124,7 +124,7 @@ \ifx\currentpageinjectionalternative\v!none \else % increment counter but don’t generate output \forgetparindent \dontcomplain - \setconstant\shipoutfinalizemethod\zerocount + \setconstant\shipoutfinalizemethod\zerocount % this is messy \page_injections_flush_indeed \fi} diff --git a/tex/context/base/mkiv/page-lay.mkiv b/tex/context/base/mkiv/page-lay.mkiv index 7b80dadb9..02cc5aa17 100644 --- a/tex/context/base/mkiv/page-lay.mkiv +++ b/tex/context/base/mkiv/page-lay.mkiv @@ -13,19 +13,16 @@ \writestatus{loading}{ConTeXt Page Macros / Layout Specification} -%D Before you start wondering why some of the page related -%D modules skip upward or left in order to place elements, you -%D must realize that the reference point is the top left -%D corner of the main typesetting area. One reason for this -%D choice is that it suited some viewers that displayed page -%D areas. Another reason is that margins, edges and top and -%D bottom areas are kind of virtual, while the header, text -%D and footer areas normally determine the text flow. +%D Before you start wondering why some of the page related modules skip upward or +%D left in order to place elements, you must realize that the reference point is the +%D top left corner of the main typesetting area. One reason for this choice is that +%D it suited some viewers that displayed page areas. Another reason is that margins, +%D edges and top and bottom areas are kind of virtual, while the header, text and +%D footer areas normally determine the text flow. \unprotect -%D The dimensions related to layout areas are represented by -%D real dimensions. +%D The dimensions related to layout areas are represented by real dimensions. \newdimen\paperheight \paperheight = 297mm \newdimen\paperwidth \paperwidth = 210mm @@ -69,17 +66,15 @@ \newdimen\totaltextwidth -%D The next series of dimensions are complemented by left -%D and rights ones. +%D The next series of dimensions are complemented by left and rights ones. \newdimen\margindistance \newdimen\edgedistance \newdimen\marginwidth \newdimen\edgewidth -%D Because a distance does not really makes sense when there -%D is no area, we use a zero distance in case there is no -%D area. +%D Because a distance does not really makes sense when there is no area, we use a +%D zero distance in case there is no area. %D The horizontal distances are: @@ -149,12 +144,12 @@ \let\currentlayout\empty \fi \letlayoutparameter\c!state\v!normal % global ? still needed ? - \global\let\currentlayout\currentlayout % global + \glet\currentlayout\currentlayout % global \page_layouts_synchronize \page_layouts_check_next \or % \setuplayout (reverts to main layout) \letlayoutparameter\c!state\v!normal % global ? still needed ? - \global\let\currentlayout\empty % global + \glet\currentlayout\empty % global \page_layouts_synchronize \page_layouts_check_next \fi @@ -244,16 +239,15 @@ \swapmacros\innersidetotal \outersidetotal \to \everyswapmargins -%D The papersize macros have a long history and we don't want -%D to change the commands so they keep looking a bit complex. +%D The papersize macros have a long history and we don't want to change the commands +%D so they keep looking a bit complex. %D \macros %D {definepapersize} %D -%D Before we start calculating layout dimensions, we will -%D first take care of paper sizes. The first argument can be -%D either an assignment (for defaults) or an identifier, in -%D which case the second argument is an assignment. +%D Before we start calculating layout dimensions, we will first take care of paper +%D sizes. The first argument can be either an assignment (for defaults) or an +%D identifier, in which case the second argument is an assignment. %D %D \showsetup{definepapersize} %D @@ -281,8 +275,8 @@ %D \macros %D {setuppaper,setuppapersize} %D -%D When setting up the papersize on which to typeset and -%D print, we can also determine some more characteristics. +%D When setting up the papersize on which to typeset and print, we can also +%D determine some more characteristics. %D %D \showsetup{setuppapersize} %D @@ -335,9 +329,8 @@ \def\v_page_target_xy {\numexpr\v_page_target_nx*\v_page_target_ny\relax} -% Normally we will not use this command directly but for now it -% works out okay. In the future we might use more of the related -% commands. +%D Normally we will not use this command directly but for now it works out okay. In +%D the future we might use more of the related commands. \setuplayouttarget [% these are rather special @@ -462,7 +455,7 @@ \appendtoks \page_paper_reinstate - \global\let\page_paper_reinstate\relax + \glet\page_paper_reinstate\relax \to \everyaftershipout \unexpanded\def\page_paper_set_restore#1#2% @@ -538,7 +531,7 @@ \ifx\currentlayouttarget\empty \let\currentlayouttarget\currentpage \fi - \global\let\papersize\currentlayouttarget + \glet\papersize\currentlayouttarget \page_paper_reset_paper \processcommacommand[\m_page_asked_paper]\page_paper_handle_page_option \global\paperwidth \layouttargetparameter\c!width \relax @@ -561,7 +554,7 @@ % locate paper target \page_paper_reset_print \processcommacommand[\m_page_asked_print]\page_paper_identify_target - \global\let\printpapersize\currentlayouttarget + \glet\printpapersize\currentlayouttarget \page_paper_reset_print \processcommacommand[\m_page_asked_print]\page_paper_handle_print_option \global\printpaperwidth \layouttargetparameter\c!width \relax @@ -814,18 +807,18 @@ {\edef\m_page_check{#1} \edef\m_page_state{\namedlayoutparameter\m_page_check\c!state}% \ifx\m_page_state\v!start - \global\let\v_page_layouts_pre_check\currentlayout - \global\let\currentlayout\m_page_check + \glet\v_page_layouts_pre_check\currentlayout + \glet\currentlayout\m_page_check \page_layouts_synchronize \else\ifx\m_page_state\v!repeat - \global\let\v_page_layouts_pre_check\relax - \global\let\currentlayout\m_page_check + \glet\v_page_layouts_pre_check\relax + \glet\currentlayout\m_page_check \page_layouts_synchronize \fi\fi} \def\page_layouts_check_revert - {\global\let\currentlayout\v_page_layouts_pre_check - \global\let\v_page_layouts_pre_check\relax + {\glet\currentlayout\v_page_layouts_pre_check + \glet\v_page_layouts_pre_check\relax \page_layouts_synchronize} \def\page_layouts_check_default @@ -996,6 +989,7 @@ \newdimen\d_page_adepts_pushed_text_height \newdimen\d_page_adepts_pushed_footer_height \newdimen\d_page_adepts_height +\newdimen\d_page_adapts_delta \unexpanded\def\adaptlayout {\dodoubleempty\page_adapts_layout} @@ -1040,8 +1034,8 @@ \page_otr_command_set_vsize % \page_backgrounds_recalculate - \global\let\page_adepts_push\relax - \global\let\page_adepts_pop\page_adepts_pop_indeed} + \glet\page_adepts_push\relax + \glet\page_adepts_pop\page_adepts_pop_indeed} % \def\page_adapts_check % {\csname\??pageadaptations\the\ifcsname\??pageadaptations\the\realpageno\endcsname\realpageno\else\zerocount\fi\endcsname} @@ -1067,8 +1061,8 @@ {\global\textheight \d_page_adepts_pushed_text_height \global\footerheight\d_page_adepts_pushed_footer_height \page_layouts_synchronize - \global\let\page_adepts_push\page_adepts_push_indeed - \global\let\page_adepts_pop\relax} + \glet\page_adepts_push\page_adepts_push_indeed + \glet\page_adepts_pop\relax} \appendtoks \page_adapts_check \to \everystarttext \appendtoks \page_adapts_reset \to \everyshipout @@ -1153,8 +1147,8 @@ \def\compensatedinnermakeupmargin {\dimexpr\ifconditional\innermakeupcompensation+\innermakeupmargin\else\zeropoint\fi\relax} -\unexpanded\def\freezetextwidth % name will change % \makeupwidth may be set to \textwidth - {\textwidth\makeupwidth % which is a tricky but valid value +\unexpanded\def\freezetextwidth % name will change % \makeupwidth may be set to \textwidth + {\textwidth\makeupwidth % which is a tricky but valid value \edef\m_currentlayout_text_width {\layoutparameter\c!textwidth }% \edef\m_currentlayout_text_margin{\layoutparameter\c!textmargin}% \ifx\m_currentlayout_text_width\empty \else @@ -1174,15 +1168,9 @@ {\freezetextwidth \page_otr_command_set_hsize} -% The next few are better off in page-ini.mkiv - -%D When we start at an even page, we need to swap the layout -%D differently. We cannot adapt the real page number, since -%D it is used in cross referencing. The next switch is set -%D when we start at an even page. - -% We could use nested if here plus some \@EAEAEA's but but the -% next variant has less expansion which is nicer in tracing. +%D When we start at an even page, we need to swap the layout differently. We cannot +%D adapt the real page number, since it is used in cross referencing. The next +%D switch is set when we start at an even page. % #single #left #right @@ -1262,7 +1250,7 @@ % \to \everybeforeshipout \def\goleftonpage % name will change (we could cache) - {\hskip-\dimexpr\leftmargindistance+\leftmarginwidth+\leftedgedistance+\leftedgewidth\relax} + {\hkern-\dimexpr\leftmargindistance+\leftmarginwidth+\leftedgedistance+\leftedgewidth\relax} \def\doifelsemarginswap#1#2% {\doifbothsides{#1}{#1}{#2}} @@ -1327,12 +1315,9 @@ %D \macros %D {startlocallayout} %D -%D These macros should be used with care. They permit local -%D layouts (as used in fitting pages, see \type {page-app.tex}). - -%D This is kind of obsolete now that we have \type -%D {\definelayout}, so this hack will disappear in future -%D versions. +%D These macros should be used with care. They permit local layouts (as used in +%D fitting pages, see \type {page-app.tex}). This is kind of obsolete now that we +%D have \type {\definelayout}, so this hack will disappear in future versions. \unexpanded\def\startlocallayout {\globalpushmacro\page_paper_restore @@ -1367,19 +1352,16 @@ \glet\page_grids_add_to_one\gobbleoneargument \glet\page_grids_add_to_mix\gobbleoneargument -%D The default dimensions are quite old and will not change. -%D The funny fractions were introduced when we went from fixed -%D dimensions to relative ones. Since \CONTEXT\ is a dutch -%D package, the dimensions are based on the metric system. The -%D asymmetrical layout is kind of handy for short -%D quick||and||dirty stapled documents. +%D The default dimensions are quite old and will not change. The funny fractions +%D were introduced when we went from fixed dimensions to relative ones. Since +%D \CONTEXT\ is a dutch package, the dimensions are based on the metric system. The +%D asymmetrical layout is kind of handy for short quick||and||dirty stapled +%D documents. %D -%D Although valid, it is not a real good idea to use -%D dimensions based on the \type {em} unit. First of all, -%D since there are no fonts loaded yet, this dimension makes -%D no sense, and second, you would loose track of values, -%D since they could change while going to a new page, -%D depending on the current font setting. +%D Although valid, it is not a real good idea to use dimensions based on the \type +%D {em} unit. First of all, since there are no fonts loaded yet, this dimension +%D makes no sense, and second, you would loose track of values, since they could +%D change while going to a new page, depending on the current font setting. \setuplayout [ \c!topspace=.08417508418\paperheight, % 2.5cm @@ -1435,8 +1417,8 @@ \c!columns=\plusone, \c!columndistance=\zeropoint] -%D First we define a whole range of (DIN) papersizes, -%D of which the A-series makes most sense. We enable checking. +%D First we define a whole range of (DIN) papersizes, of which the A-series makes +%D most sense. We enable checking. \definepapersize [A0] [\c!width=841mm,\c!height=1189mm] \definepapersize [A1] [\c!width=594mm,\c!height=841mm] @@ -1477,18 +1459,17 @@ \definepapersize [C9] [\c!width=40mm,\c!height=57mm] \definepapersize [C10] [\c!width=28mm,\c!height=40mm] -%D Per August 2004 the rounding of some (seldom used) sizes -%D were corrected top the latest DIN specifications. Peter -%D Rolf came up with these and a few more missing sizes. -%D Watch out: spaces and slashes! +%D Per August 2004 the rounding of some (seldom used) sizes were corrected top the +%D latest DIN specifications. Peter Rolf came up with these and a few more missing +%D sizes. Watch out: spaces and slashes! \definepapersize [4 A0] [\c!width=1682mm,\c!height=2378mm] \definepapersize [2 A0] [\c!width=1189mm,\c!height=1682mm] \definepapersize [C6/C5] [\c!width=114mm,\c!height=229mm] -%D Because there are no standardized screen sizes, we define -%D a bunch of sizes with $4:3$ ratios. The \type {S6} size is -%D nearly as wide as a sheet of \type {A4} paper. +%D Because there are no standardized screen sizes, we define a bunch of sizes with +%D $4:3$ ratios. The \type {S6} size is nearly as wide as a sheet of \type {A4} +%D paper. \definepapersize [S3] [\c!width=300pt,\c!height=225pt] \definepapersize [S4] [\c!width=400pt,\c!height=300pt] @@ -1509,15 +1490,13 @@ \definepapersize [S55] [\c!width=500pt,\c!height=500pt] \definepapersize [S66] [\c!width=600pt,\c!height=600pt] -%D One may wonder if \TEX\ should be used for typesetting -%D \CDROM\ covers, but it does not hurt to have the paper size -%D ready. +%D One may wonder if \TEX\ should be used for typesetting \CDROM\ covers, but it +%D does not hurt to have the paper size ready. \definepapersize [CD] [\c!width=120mm,\c!height=120mm] -%D The next series is for our English speaking friends who -%D decided to stick to non metric values. Thanks to Nelson -%D Beebe for completing the inch based list. +%D The next series is for our English speaking friends who decided to stick to non +%D metric values. Thanks to Nelson Beebe for completing the inch based list. \definepapersize [letter] [\c!width=8.5in,\c!height=11in] \definepapersize [ledger] [\c!width=11in,\c!height=17in] @@ -1573,9 +1552,9 @@ \definepapersize [business] [\c!width=85mm,\c!height=55mm] \definepapersize [businessUS] [\c!width=3.5in,\c!height=2in] -%D We can now default to a reasonable size. We match the print -%D paper size with the typeset paper size. This setting should -%D come after the first layout specification (already done). +%D We can now default to a reasonable size. We match the print paper size with the +%D typeset paper size. This setting should come after the first layout specification +%D (already done). % \definepapersize % [\v!default] diff --git a/tex/context/base/mkiv/page-lin.lua b/tex/context/base/mkiv/page-lin.lua index a6b6a12c4..3689c7f8d 100644 --- a/tex/context/base/mkiv/page-lin.lua +++ b/tex/context/base/mkiv/page-lin.lua @@ -43,15 +43,14 @@ local v_no = variables.no local properties = nodes.properties local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes -local whatcodes = nodes.whatcodes local listcodes = nodes.listcodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local whatsit_code = nodecodes.whatsit local glyph_code = nodecodes.glyph -local line_code = listcodes.line + +local linelist_code = listcodes.line local a_displaymath = attributes.private('displaymath') local a_linenumber = attributes.private('linenumber') @@ -71,7 +70,7 @@ local getattr = nuts.getattr local setattr = nuts.setattr local getlist = nuts.getlist local getbox = nuts.getbox ------ getdir = nuts.getdir +----- getdirection = nuts.getdirection ----- getwidth = nuts.getwidth local getheight = nuts.getheight local getdepth = nuts.getdepth @@ -79,8 +78,9 @@ local getdepth = nuts.getdepth local setprop = nuts.setprop local getprop = nuts.getprop -local traverse_id = nuts.traverse_id -local traverse = nuts.traverse +local nexthlist = nuts.traversers.hlist +local nextvlist = nuts.traversers.vlist + local copy_node = nuts.copy ----- hpack_nodes = nuts.hpack local is_display_math = nuts.is_display_math @@ -224,7 +224,9 @@ implement { local function check_number(n,a,skip,sameline) local d = data[a] if d then - local tag, skipflag, s = d.tag or "", 0, d.start or 1 + local tag = d.tag or "" + local skipflag = 0 + local s = d.start or 1 current_list[#current_list+1] = { n, s } if sameline then skipflag = 0 @@ -244,7 +246,7 @@ local function check_number(n,a,skip,sameline) end local p = checkline(n) if p then - ctx_makelinenumber(tag,skipflag,s,p.hsize,p.reverse and "TRT" or "TLT") + ctx_makelinenumber(tag,skipflag,s,p.hsize,p.reverse and 1 or 0) else report_lines("needs checking") end @@ -283,8 +285,8 @@ end local function listisnumbered(list) if list then - for n in traverse_id(hlist_code,list) do - if getsubtype(n) == line_code then + for n, subtype in nexthlist, list do + if subtype == linelist_code then local a = getattr(n,a_linenumber) if a then -- a quick test for lines (only valid when \par before \stoplinenumbering) @@ -306,7 +308,7 @@ local function findnumberedlist(list) while n do local id = getid(n) if id == hlist_code then - if getsubtype(n) == line_code then + if getsubtype(n) == linelist_code then local a = getattr(n,a_linenumber) if a then return a > 0 and list @@ -383,9 +385,8 @@ function boxed.stage_one(n,nested) local skip = false local function check() - for n in traverse_id(hlist_code,list) do -- attr test here and quit as soon as zero found - local subtype = getsubtype(n) - if subtype ~= line_code then + for n, subtype in nexthlist, list do + if subtype ~= linelist_code then -- go on elseif getheight(n) == 0 and getdepth(n) == 0 then -- skip funny hlists -- todo: check line subtype @@ -450,7 +451,7 @@ function boxed.stage_one(n,nested) if not list then return end - for n in traverse_id(vlist_code,list) do + for n in nextvlist, list do local p = properties[n] if p and p.columngap then if trace_numbers then @@ -472,18 +473,21 @@ end function boxed.stage_two(n,m) if #current_list > 0 then m = m or lines.scratchbox - local t, tn = { }, 0 - for l in traverse_id(hlist_code,getlist(getbox(m))) do + local t = { } + local tn = 0 + for l in nexthlist, getlist(getbox(m)) do tn = tn + 1 t[tn] = copy_node(l) -- use take_box instead end for i=1,#current_list do local li = current_list[i] - local n, m, ti = li[1], li[2], t[i] + local n = li[1] + local m = li[2] + local ti = t[i] if ti then - -- local d = getdir(n) + -- local d = getdirection(n) -- local l = getlist(n) - -- if d == "TRT" then + -- if d == 1 then -- local w = getwidth(n) -- ti = hpack_nodes(linked_nodes(new_kern(-w),ti,new_kern(w))) -- end diff --git a/tex/context/base/mkiv/page-lin.mkvi b/tex/context/base/mkiv/page-lin.mkvi index 4348d6770..a27ba5736 100644 --- a/tex/context/base/mkiv/page-lin.mkvi +++ b/tex/context/base/mkiv/page-lin.mkvi @@ -46,6 +46,10 @@ \attribute\linenumberattribute\attributeunsetvalue \to \everyforgetall +\appendtoks + \attribute\linenumberattribute \attributeunsetvalue +\to \everyinsidefloat + \newcount \linenumber % not used \newbox \b_page_lines_scratch \newcount \c_page_lines_reference @@ -275,8 +279,8 @@ \fi\fi\fi \fi \the\beforeeverylinenumbering - \globallet\page_postprocessors_page \page_postprocessors_linenumbers_page - \globallet\page_postprocessors_column\page_postprocessors_linenumbers_column + \glet\page_postprocessors_page \page_postprocessors_linenumbers_page + \glet\page_postprocessors_column\page_postprocessors_linenumbers_column \global\settrue\page_postprocessors_needed_box % see core-rul.mkiv \ifcase\c_page_lines_mode\relax \page_lines_start_update % continue @@ -349,7 +353,7 @@ \d_page_lines_distance\linenumberingparameter\c!distance\relax \edef\p_align{\linenumberingparameter\c!align}% \edef\p_location{\linenumberingparameter\c!location}% - \ifcase\istltdir#dir\relax + \ifcase#dir\relax \settrue \c_page_lines_dir_left_to_right \else \setfalse\c_page_lines_dir_left_to_right diff --git a/tex/context/base/mkiv/page-mix.lua b/tex/context/base/mkiv/page-mix.lua index 107ac1410..192b8a30a 100644 --- a/tex/context/base/mkiv/page-mix.lua +++ b/tex/context/base/mkiv/page-mix.lua @@ -69,8 +69,6 @@ local getpenalty = nuts.getpenalty local getwidth = nuts.getwidth local getheight = nuts.getheight local getdepth = nuts.getdepth -local traverse_id = nuts.traverse_id -local traverse = nuts.traverse local theprop = nuts.theprop @@ -829,23 +827,6 @@ local function report_deltas(result,str) report_state("%s, cycles %s, deltas % | t",str,result.cycle or 1,t) end --- local function xxcollectinserts(h) --- local skips, total, order = 0, 0, 0 --- print(h) --- if h then --- h = getlist(h) --- for n in traverse(h) do --- print(tonode(n)) --- end --- for n in traverse_id(insert_code,h) do --- order = order + 1 --- total = total + getheight(n) --- skips = skips + structures.notes.check_spacing(getsubtype(n),order) --- end --- end --- return skips, total --- end - local function setsplit(specification) splitruns = splitruns + 1 if trace_state then diff --git a/tex/context/base/mkiv/page-mix.mkiv b/tex/context/base/mkiv/page-mix.mkiv index 684ebc585..436c4a1dc 100644 --- a/tex/context/base/mkiv/page-mix.mkiv +++ b/tex/context/base/mkiv/page-mix.mkiv @@ -371,6 +371,9 @@ \let\currentmixedcolumnsmethod\empty +\installmacrostack\currentmixedcolumns +\installmacrostack\currentmixedcolumnsmethod + \unexpanded\def\startmixedcolumns {\dodoubleempty\page_mix_start_columns} @@ -385,8 +388,8 @@ \fi\fi} \unexpanded\def\page_mix_start_columns - {\pushmacro\currentmixedcolumns - \pushmacro\currentmixedcolumnsmethod + {\push_macro_currentmixedcolumns + \push_macro_currentmixedcolumnsmethod \ifsecondargument \singleexpandafter\page_mix_start_columns_a \else\iffirstargument @@ -462,8 +465,8 @@ \let\stopmixedcolumns\page_mix_columns_stop_nop} \unexpanded\def\page_mix_fast_columns_start#1% - {\pushmacro\currentmixedcolumns - \pushmacro\currentmixedcolumnsmethod + {\push_macro_currentmixedcolumns + \push_macro_currentmixedcolumnsmethod \edef\currentmixedcolumns{#1}% \edef\currentmixedcolumnsmethod{\mixedcolumnsparameter\c!method}% \mixedcolumnsparameter\c!before\relax % so, it doesn't listen to local settings ! @@ -492,15 +495,15 @@ \endgroup \begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax \mixedcolumnsparameter\c!after\relax - \popmacro\currentmixedcolumnsmethod - \popmacro\currentmixedcolumns + \pop_macro_currentmixedcolumnsmethod + \pop_macro_currentmixedcolumns \the\t_page_mix_at_the_end\global\t_page_mix_at_the_end\emptytoks} \unexpanded\def\page_mix_columns_stop_nop {\page_mix_finalize_columns \endgroup - \popmacro\currentmixedcolumnsmethod - \popmacro\currentmixedcolumns + \pop_macro_currentmixedcolumnsmethod + \pop_macro_currentmixedcolumns \the\t_page_mix_at_the_end\global\t_page_mix_at_the_end\emptytoks} % \unexpanded\def\page_mix_columns_stop_yes @@ -509,12 +512,12 @@ % \begincsname\??mixedcolumnsafter\currentmixedcolumnsmethod\endcsname\relax % \mixedcolumnsparameter\c!after\relax % \ifx\currentmixedcolumnsmethod\s!otr -% \popmacro\currentmixedcolumnsmethod -% \popmacro\currentmixedcolumns +% \pop_macro_currentmixedcolumnsmethod +% \pop_macro_currentmixedcolumns % \synchronizeoutput % brrr, otherwise sometimes issues in itemize % \else -% \popmacro\currentmixedcolumnsmethod -% \popmacro\currentmixedcolumns +% \pop_macro_currentmixedcolumnsmethod +% \pop_macro_currentmixedcolumns % \fi % } diff --git a/tex/context/base/mkiv/page-mul.mkiv b/tex/context/base/mkiv/page-mul.mkiv index 51af24b6a..957981703 100644 --- a/tex/context/base/mkiv/page-mul.mkiv +++ b/tex/context/base/mkiv/page-mul.mkiv @@ -471,7 +471,7 @@ \page_mul_postprocess_lines \page_mul_postprocess_columns \dohandleallcolumns - {\global\setbox\currentcolumnbox\hbox to \d_page_mul_used_width + {\global\setbox\currentcolumnbox\hpack to \d_page_mul_used_width {\box\currentcolumnbox}% \wd\currentcolumnbox\d_page_mul_used_width \ifheightencolumns @@ -479,12 +479,12 @@ \fi}% \page_mul_calculate_column_result_dimensions \overlaycolumnfootnotes - \setbox\columnpagebox\vbox - {\hbox \ifconditional\c_page_mul_reverse dir TRT \fi to \makeupwidth + \setbox\columnpagebox\vpack % \vbox + {\ifconditional\c_page_mul_reverse\reversehpack\else\naturalhpack\fi to \makeupwidth {\hskip\ifconditional\c_page_mul_reverse\d_page_mul_rightskip\else\d_page_mul_leftskip\fi\relax \dohandleallcolumns {\finishcolumnbox - {\setbox\scratchbox\hbox + {\setbox\scratchbox\hpack {\ifx\finishcolumnbox\relax\else\strut\fi \box\currentcolumnbox}% hm, why strut \anch_mark_column_box\scratchbox @@ -499,13 +499,13 @@ \fi \global\setbox\currenttopcolumnbox\emptybox}% \advance\scratchdimen \ht\columnpagebox - \setbox\scratchbox\hbox to \makeupwidth + \setbox\scratchbox\hbox to \makeupwidth % between can be something so no \hpack {\vrule \s!width \zeropoint \s!height\scratchdimen \s!depth \dp\columnpagebox \dostepwiserecurse\plustwo\nofcolumns\plusone{\hfil\page_mul_between_columns}\hfil}% - \setbox\columnpagebox\hbox + \setbox\columnpagebox\hpack {\box\columnpagebox \hskip-\makeupwidth \box\scratchbox}% @@ -761,7 +761,7 @@ \page_mul_set_n_of_lines \advance\c_page_mul_n_of_lines \minustwo \scratchdimen\dimexpr\c_page_mul_n_of_lines\lineheight+\topskip\relax - \setbox\b_page_mul_notes\hbox{\lower\scratchdimen\box\b_page_mul_notes}% + \setbox\b_page_mul_notes\hpack{\lower\scratchdimen\box\b_page_mul_notes}% \ht\b_page_mul_notes\openstrutheight \dp\b_page_mul_notes\openstrutdepth \wd\b_page_mul_notes\zeropoint @@ -784,7 +784,7 @@ \getnoflines\scratchdimen \advance\noflines \minustwo \scratchdimen\dimexpr\noflines\lineheight+\topskip\relax - \setbox\b_page_mul_notes\hbox{\lower\scratchdimen\box\b_page_mul_notes}% + \setbox\b_page_mul_notes\hpack{\lower\scratchdimen\box\b_page_mul_notes}% \ht\b_page_mul_notes\openstrutheight \dp\b_page_mul_notes\openstrutdepth \wd\b_page_mul_notes\zeropoint @@ -890,6 +890,7 @@ \def\page_mul_routine_balance {\bgroup + % why no \forgetall here \page_mul_initialize_variables \widowpenalty\zerocount \setbox\b_page_mul_balance_content\vbox{\unvbox\normalpagebox}% @@ -1135,7 +1136,7 @@ % \global\savednoffloats\zerocount % \global\setfalse\c_page_floats_some_waiting % \else -% \global\let\page_floats_column_pop_saved\relax +% \glet\page_floats_column_pop_saved\relax % \fi} % % \let\page_floats_column_pop_saved\relax @@ -1249,7 +1250,7 @@ \xdef\insertionheight{\the\dimen0}% \egroup \else - \global\let\insertionheight\zeropoint + \glet\insertionheight\zeropoint \fi} \def\docolumnroomfloat @@ -1364,7 +1365,7 @@ \global\setbox\currenttopcolumnbox\vbox {\snaptogrid\vbox {\copy\currenttopcolumnbox - \hbox{\vphantom{\vskip\floatheight}}}% known from previous + \hpack{\vphantom{\vskip\floatheight}}}% known from previous \whitespace % nodig ? \blank[\rootfloatparameter\c!spaceafter]}% \else @@ -1848,4 +1849,17 @@ \s!page_otr_command_test_column =\page_mul_command_test_column ] +\installfloatmethod \s!multicolumn \v!here \page_mul_place_float_here +\installfloatmethod \s!multicolumn \v!force \page_mul_place_float_force +\installfloatmethod \s!multicolumn \v!top \page_mul_place_float_top +\installfloatmethod \s!multicolumn \v!bottom \page_mul_place_float_bottom + +\appendtoks + \flushingcolumnfloatsfalse +\to \everybeforesectionheadhandle + +\appendtoks + \flushingcolumnfloatstrue +\to \everyaftersectionheadhandle + \protect \endinput diff --git a/tex/context/base/mkiv/page-one.mkiv b/tex/context/base/mkiv/page-one.mkiv index 348c301fc..64c4a7134 100644 --- a/tex/context/base/mkiv/page-one.mkiv +++ b/tex/context/base/mkiv/page-one.mkiv @@ -73,6 +73,7 @@ \else \global\vsize\textheight \fi + \global\advance\vsize\d_page_adapts_delta % alternatively we could set it in builders.buildpage_filter % \ifdim\pagegoal<\maxdimen .. \fi \global\pagegoal\dimexpr\vsize-\d_page_floats_inserted_top-\d_page_floats_inserted_bottom\relax} @@ -141,16 +142,17 @@ {\page_otr_command_flush_top_insertions % this is messy ... we will provide a more tight area (no big deal as we can % do that at the lua end) +% \parfillskip\zeropoint \page_one_registered_text_area_a#1#2% \unvbox % \ifgridsnapping - \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax + \vkern\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax \prevdepth\openstrutdepth \page_otr_command_flush_bottom_insertions \vfil \else\ifcase\bottomraggednessmode % ragged (default) - \vskip\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax + \vkern\dimexpr\openstrutdepth-\d_page_one_natural_depth\relax \prevdepth\openstrutdepth \page_otr_command_flush_bottom_insertions \vfil @@ -159,7 +161,7 @@ \page_otr_command_flush_bottom_insertions \or % baseline - \kern\dimexpr\maxdepth-\d_page_one_natural_depth\relax + \vkern\dimexpr\maxdepth-\d_page_one_natural_depth\relax \page_otr_command_flush_bottom_insertions \fi\fi \fakepagenotes}% @@ -228,6 +230,9 @@ \vskip\s_page_one_between_top_insert \egroup} +\let\totaltopinserted\!!zeropoint +\let\totalbotinserted\!!zeropoint + \unexpanded\def\page_one_command_set_top_insertions {\bgroup \ifconditional\c_page_floats_some_waiting @@ -312,38 +317,44 @@ \unexpanded\def\page_one_command_flush_top_insertions {\ifvoid\namedinsertionnumber\s!topfloat\else - \ifgridsnapping - \box\namedinsertionnumber\s!topfloat - \vskip-\topskip - \vskip\strutheight % [xx] new: see icare topbleed - \else - \ifcase\c_page_floats_insertions_topskip_mode - % 0: default, do nothing - \or - % 1: no topskip (crossed fingers) - \vskip-\topskip - \vskip\strutheight - \fi - \unvbox\namedinsertionnumber\s!topfloat - \fi + \page_one_command_flush_top_insertions_indeed % less tracing \fi \global\d_page_floats_inserted_top\zeropoint} +\def\page_one_command_flush_top_insertions_indeed + {\ifgridsnapping + \box\namedinsertionnumber\s!topfloat + \vkern-\topskip + \vkern\strutheight % [xx] new: see icare topbleed + \else + \ifcase\c_page_floats_insertions_topskip_mode + % 0: default, do nothing + \or + % 1: no topskip (crossed fingers) + \vskip-\topskip % skip ! + \vkern\strutheight + \fi + \unvbox\namedinsertionnumber\s!topfloat + \fi} + \unexpanded\def\page_one_command_flush_bottom_insertions {\ifvoid\namedinsertionnumber\s!bottomfloat\else - \ifgridsnapping - % \floatparameter\c!bottombefore - \snaptogrid\hbox{\box\namedinsertionnumber\s!bottomfloat}% - % \floatparameter\c!bottomafter - \else - \floatparameter\c!bottombefore - \unvbox\namedinsertionnumber\s!bottomfloat - \floatparameter\c!bottomafter - \fi + \page_one_command_flush_bottom_insertions_indeed \fi \global\d_page_floats_inserted_bottom\zeropoint \global\setfalse\c_page_floats_not_permitted} +\def\page_one_command_flush_bottom_insertions_indeed + {\ifgridsnapping + % \floatparameter\c!bottombefore + \snaptogrid\hbox{\box\namedinsertionnumber\s!bottomfloat}% + % \floatparameter\c!bottomafter + \else + \floatparameter\c!bottombefore + \unvbox\namedinsertionnumber\s!bottomfloat + \floatparameter\c!bottomafter + \fi} + \unexpanded\def\page_one_command_flush_floats {\global\settrue\c_page_floats_flushing \ifconditional\c_page_floats_some_waiting diff --git a/tex/context/base/mkiv/page-otr.mkvi b/tex/context/base/mkiv/page-otr.mkvi index ebaf17ebc..909f5cd4d 100644 --- a/tex/context/base/mkiv/page-otr.mkvi +++ b/tex/context/base/mkiv/page-otr.mkvi @@ -97,7 +97,7 @@ \newconstant\c_page_otr_eject_penalty \c_page_otr_eject_penalty -\plustenthousand \newconstant\c_page_otr_super_penalty \c_page_otr_super_penalty -\plustwentythousand -\newcount \c_page_otf_trigger_penalty \c_page_otf_trigger_penalty -100010 +\newcount \c_page_otr_trigger_penalty \c_page_otr_trigger_penalty -100010 \newif \ifinotr % we keep this (name) for old times sake @@ -127,9 +127,9 @@ \endgroup} \unexpanded\def\installoutputroutine#invoke#action% \invoke \action - {\global\advance\c_page_otf_trigger_penalty\minusone - \edef#invoke{\page_otr_trigger{\number\c_page_otf_trigger_penalty}}% - \setvalue{\??otrtriggers\number\c_page_otf_trigger_penalty}{#action}} + {\global\advance\c_page_otr_trigger_penalty\minusone + \edef#invoke{\page_otr_trigger{\number\c_page_otr_trigger_penalty}}% + \setvalue{\??otrtriggers\number\c_page_otr_trigger_penalty}{#action}} \unexpanded\def\page_otr_triggered_output_routine_traced {\ifcsname\??otrtriggers\the\outputpenalty\endcsname @@ -160,7 +160,7 @@ \ifdefined\everybeforeoutput \else \newtoks\everybeforeoutput \fi \ifdefined\everyafteroutput \else \newtoks\everyafteroutput \fi -\def\page_otf_set_engine_output_routine#content% +\def\page_otr_set_engine_output_routine#content% {\global\output {\inotrtrue \the\everybeforeoutput @@ -172,7 +172,7 @@ % \ifdefined\everybeforeoutputgroup \else \newtoks\everybeforeoutputgroup \fi % \ifdefined\everyafteroutputgroup \else \newtoks\everyafteroutputgroup \fi % -% \def\page_otf_set_engine_output_routine#content% +% \def\page_otr_set_engine_output_routine#content% % {\the\everybeforeoutputgroup % \global\output % {\inotrtrue @@ -187,7 +187,7 @@ % \fi % \to \everyafteroutputgroup -\page_otf_set_engine_output_routine\page_otr_triggered_output_routine +\page_otr_set_engine_output_routine\page_otr_triggered_output_routine \installoutputroutine\synchronizeoutput % use \triggerpagebuilder instead {\ifvoid\normalpagebox\else diff --git a/tex/context/base/mkiv/page-pcl.mkiv b/tex/context/base/mkiv/page-pcl.mkiv index 53d9f781d..140444fc2 100644 --- a/tex/context/base/mkiv/page-pcl.mkiv +++ b/tex/context/base/mkiv/page-pcl.mkiv @@ -30,19 +30,18 @@ \definemeasure[threecolumns][\dimexpr\plusthree\columnwidth+\plustwo \columndistance\relax] \definemeasure[fourcolumns] [\dimexpr\plusfour \columnwidth+\plusthree\columndistance\relax] -\newcount\c_page_col_n_of_columns \c_page_col_n_of_columns\plusone -\newcount\c_page_col_current \c_page_col_current \plusone -\newdimen\d_page_col_distance -\newdimen\d_page_col_max_height -\newdimen\d_page_col_max_width -%newdimen\d_page_col_balance_step -\newdimen\d_page_col_column_width - -\newdimen\d_page_col_top_height -\newdimen\d_page_col_top_width - -\newdimen\d_page_col_available -\newdimen\d_page_col_sofar +\newcount \c_page_col_n_of_columns \c_page_col_n_of_columns\plusone +\newcount \c_page_col_current \c_page_col_current \plusone +\newdimen \d_page_col_distance +\newdimen \d_page_col_max_height +\newdimen \d_page_col_max_width +%newdimen \d_page_col_balance_step +\newdimen \d_page_col_column_width +\newdimen \d_page_col_top_height +\newdimen \d_page_col_top_width +\newdimen \d_page_col_available +\newdimen \d_page_col_sofar +\newconditional\c_page_col_page %D We need to step over empty columns. @@ -700,6 +699,7 @@ \setuppagecolumns [\c!distance=1.5\bodyfontsize, \c!n=\plustwo, + \c!page=\v!yes, %\c!align=, % inherit (also replaces tolerance) %\c!before=, %\c!after=, @@ -727,9 +727,39 @@ \ifdefined \columnwidth \else \newdimen\columnwidth \fi \ifdefined \columndistance \else \newdimen\columndistance \fi +\def\page_col_pickup_preceding + {\begingroup + \setupoutputroutine[\s!mixedcolumn]% + \c_page_mix_routine\c_page_mix_routine_intercept + \page_otr_trigger_output_routine + \ifvoid\b_page_mix_preceding \else + % moved here, before the packaging + \page_postprocessors_linenumbers_deepbox\b_page_mix_preceding + % we need to avoid unvboxing with successive balanced on one page + \global\setbox\b_page_mix_preceding\vbox\bgroup + % yes or no: \forcestrutdepth + \unvbox\b_page_mix_preceding + \forcestrutdepth + \egroup + \wd\b_page_mix_preceding\makeupwidth + \global\d_page_mix_preceding_height\ht\b_page_mix_preceding + \fi + \endgroup} + +\def\page_col_flush_preceding + {\ifvoid\b_page_mix_preceding \else + % this is just one method but ok for now + \begingroup + % we might need more but for now this is ok + \setupfloat[\c!spacebefore=,\c!spaceafter=]% + \startplacefigure[\c!location={\v!top,\v!none}]% + \box\b_page_mix_preceding + \stopplacefigure + \endgroup + \fi} + \unexpanded\def\startpagecolumns - {\page - \begingroup + {\begingroup \begingroup \dosingleempty\page_col_start} @@ -738,6 +768,15 @@ {\let\currentpagecolumns\empty \setuppagecolumns[#1]}% {\edef\currentpagecolumns{#1}}% + \edef\p_page{\pagecolumnsparameter\c!page}% + \ifx\p_page\empty + \setfalse\c_page_col_page + \else\ifx\p_page\v!no + \setfalse\c_page_col_page + \else + \settrue\c_page_col_page + \page[\p_page]% + \fi\fi \c_page_col_n_of_columns\pagecolumnsparameter\c!n\relax \ifnum\c_page_col_n_of_columns>\plusone \expandafter\page_col_start_yes @@ -769,13 +808,21 @@ \useblankparameter \pagecolumnsparameter % \useprofileparameter\pagecolumnsparameter % - \usemixedcolumnscolorparameter\c!color + \usepagecolumnscolorparameter\c!color % \setupnotes[\c!width=\textwidth]% % \usesetupsparameter\pagecolumnsparameter % + % This will become a method but for now it's good enough + % + \ifconditional\c_page_col_page\else + \page_col_pickup_preceding + \fi \setupoutputroutine[\s!pagecolumn]% + \ifconditional\c_page_col_page\else + \page_col_flush_preceding + \fi % \setupfloats[\c!ntop=\plusthousand]% % \setupfloats[\c!nbottom=\plusthousand]% diff --git a/tex/context/base/mkiv/page-run.mkiv b/tex/context/base/mkiv/page-run.mkiv index 19adfaa9c..85da8d9e5 100644 --- a/tex/context/base/mkiv/page-run.mkiv +++ b/tex/context/base/mkiv/page-run.mkiv @@ -153,6 +153,7 @@ \v!right=>\c_page_grids_lineno_mode \plusone, \v!left=>\c_page_grids_lineno_mode \plustwo, \v!outer=>\c_page_grids_lineno_mode \plusthree, + \v!inner=>\c_page_grids_lineno_mode \plusfour, \v!columns=>\c_page_grids_columns_mode\plusone]% new option \ifcase\c_page_grids_location \let\page_grids_add_to_box\gobbleoneargument @@ -179,13 +180,13 @@ \gridboxlinemode \c_page_grids_line_mode \gridboxlinenomode\c_page_grids_lineno_mode \setgridbox\scratchbox\makeupwidth\textheight % todo: check color - \global\setbox#1\hbox % global ? + \global\setbox#1\hpack % global ? {\ifcase\c_page_grids_location\or\or\box#1\hskip-\makeupwidth\fi \begingroup % color \ifcase\layoutcolumns\else \gray \setlayoutcomponentattribute{\v!grid:\v!columns}% - \hbox \layoutcomponentboxattribute to \makeupwidth + \hpack \layoutcomponentboxattribute to \makeupwidth {\dorecurse\layoutcolumns {\hskip\layoutcolumnwidth \ifnum\recurselevel<\layoutcolumns @@ -197,7 +198,7 @@ \hskip-\makeupwidth \fi \setlayoutcomponentattribute{\v!grid:\v!lines}% - \hbox \layoutcomponentboxattribute{\box\scratchbox}% + \hpack \layoutcomponentboxattribute{\box\scratchbox}% \endgroup \ifcase\c_page_grids_location\or\hskip-\makeupwidth\box#1\fi}% \stopcolor} diff --git a/tex/context/base/mkiv/page-sel.mkvi b/tex/context/base/mkiv/page-sel.mkvi index 335d01187..e11a50f5b 100644 --- a/tex/context/base/mkiv/page-sel.mkvi +++ b/tex/context/base/mkiv/page-sel.mkvi @@ -342,7 +342,7 @@ \def\page_selectors_slice_indeed[#filename][#oddsettings][#evensettings]% {\bgroup \dontcomplain - \global\let\slicedpagenumber\!!zerocount + \glet\slicedpagenumber\!!zerocount \getfiguredimensions[#filename]% \setupcurrentwithpages [\c!offset=\zeropoint,% @@ -366,7 +366,7 @@ \c!header=\zeropoint,\c!footer=\zeropoint]% \fi \dorecurse\noffigurepages - {\global\let\slicedpagenumber\recurselevel + {\glet\slicedpagenumber\recurselevel \ifnum\c_page_selectors_n>\plusone \dorecurse\c_page_selectors_n {\let\slicedpagestepx\recurselevel diff --git a/tex/context/base/mkiv/page-set.mkiv b/tex/context/base/mkiv/page-set.mkiv index 3579e3b48..dd145b322 100644 --- a/tex/context/base/mkiv/page-set.mkiv +++ b/tex/context/base/mkiv/page-set.mkiv @@ -248,8 +248,8 @@ \!!counta#1\relax \fi \fi - \relax % needed ! ! ! ! else lookahead over \fi and \@EA - \@EA\egroup\@EA\scratchcounter\the\!!counta\relax} + \relax % needed ! ! ! ! else lookahead over \fi and \expandafter + \expandafter\egroup\expandafter\scratchcounter\the\!!counta\relax} \def\OTRSETsetcorrectcellht {\bgroup @@ -260,8 +260,8 @@ \restoreglobalbodyfont \fi \advance\!!dimena\strutht - \relax % needed ! ! ! ! else lookahead over \fi and \@EA - \@EA\egroup\@EA\scratchdimen\the\!!dimena\relax} + \relax % needed ! ! ! ! else lookahead over \fi and \expandafter + \expandafter\egroup\expandafter\scratchdimen\the\!!dimena\relax} \def\doOTRSETsetgridcells#1#2#3#4#5#6% placeholder col row wid hei {data} {\!!countd#2\advance\!!countd#4\advance\!!countd\minusone @@ -487,7 +487,7 @@ \let\OTRSETbalht\zeropoint \def\OTRSETreducegridbox % for the moment no difference between methods - {\globallet\OTRSETbalht\zeropoint + {\glet\OTRSETbalht\zeropoint \ifcase\OTRSETbalancemethod % no balancing \else @@ -578,7 +578,7 @@ \else \page_otr_construct_and_shipout\box\OTRfinalpagebox\zerocount % three arguments \fi \fi - \globallet\OTRSETbalht\zeropoint + \glet\OTRSETbalht\zeropoint \egroup \fi} @@ -642,7 +642,7 @@ {\page_set_command_set_vsize} \def\doOTRSETcolumnseparator - {\hbox to \zeropoint{\hss\red\vl\hss}} + {\hpack to \zeropoint{\hss\red\vl\hss}} \let\OTRSETcolumnseparator\relax @@ -754,7 +754,7 @@ \fi}% \ifdim\lastskipinotr>\zeropoint \scratchskip\ht\scratchbox - \setbox\scratchbox\hbox + \setbox\scratchbox\hpack {\lower\strutdepth\box\scratchbox}% \dp\scratchbox\scratchdimen \ht\scratchbox\scratchskip @@ -942,7 +942,7 @@ \fi \ifenoughcolumncells \OTRSETsetgridcells\mofcolumns\columnfirstcell\columnhcells\columnvcells - {\hbox{\copy#1}}% + {\hpack{\copy#1}}% \page_set_command_set_vsize \else \OTRSETsavebox{#1}% @@ -1155,7 +1155,7 @@ %OTRSETprepareforcolumnslot3{#1}% %ruledvskip\columnslotspacing\lineheight \blank[\number\columnslotspacing*\v!line]% - \snaptogrid\hbox to \hsize{\hss\box#1\hss}% strange, why the centering + \snaptogrid\hpack to \hsize{\hss\box#1\hss}% strange, why the centering \blank[\number\columnslotspacing*\v!line]% \else \OTRSETstoreincolumnslotSOMEWHERE2{#1}% @@ -1336,7 +1336,7 @@ % a quick hack ... will be redone % \ifdim\wd\floatbox<\floatwidth \ifhbox\floatbox - \global\setbox\floatbox\hbox{\unhbox\floatbox}% + \global\setbox\floatbox\hpack{\unhbox\floatbox}% \fi \fi % \dp\floatbox\zeropoint @@ -1417,7 +1417,7 @@ {\advance\totalcolumnspace \OTRSETlocalwidth\recurselevel \advance\totalcolumnspace \namedcolumnsetparameter{\currentcolumnset:\recurselevel}\c!distance}% \ifdim\totalcolumnspace>\wd\scratchbox - \setbox\scratchbox\hbox to \totalcolumnspace{\hss\box\scratchbox\hss}% + \setbox\scratchbox\hpack to \totalcolumnspace{\hss\box\scratchbox\hss}% \fi \page_set_cell_set\currenthcell\currentvcell\box\scratchbox \egroup @@ -1619,17 +1619,17 @@ \def\dostartcolumnset[#1][#2]% {\increment\columnsetlevel\relax - \global\let\localcolumnmaxcells\!!zerocount + \glet\localcolumnmaxcells\!!zerocount \global\setfalse\OTRSETfinish \ifnum\columnsetlevel=\plusone \bgroup \saveinterlinespace - \globallet\columnsetpage\!!plusone + \glet\columnsetpage\!!plusone \def\currentcolumnset{#2}% \insidecolumnstrue % will be different flag in addition \setupoutputroutine[\s!columnset]% \doifelsenothing{#1} - {\globallet\OTRSETlist\s!default} + {\glet\OTRSETlist\s!default} {\xdef\OTRSETlist{#1}}% \OTRSETstartnextpage \OTRSETassignwidths @@ -1659,7 +1659,7 @@ \global\setbox\OTRfinalpagebox\OTRSETmakegridbox \ht\OTRfinalpagebox\textheight % signals output that there is content \OTRSETdofinaloutput - \globallet\OTRSETbalht\zeropoint + \glet\OTRSETbalht\zeropoint \egroup} {}} @@ -1678,7 +1678,7 @@ \ifvoid\OTRfinalpagebox\else % probably balanced \ifdim\ht\OTRfinalpagebox<\textheight - \snaptogrid[\v!page]\hbox{\box\OTRfinalpagebox}% + \snaptogrid[\v!page]\hpack{\box\OTRfinalpagebox}% \else \box\OTRfinalpagebox \fi @@ -1765,7 +1765,7 @@ \def\OTRSETstartnextpage {\doifsomething\OTRSETlist {\getfromcommacommand[\OTRSETlist][1]% - \global\let\OTRSETidentifier\commalistelement + \glet\OTRSETidentifier\commalistelement \xdef\currentcolumnset{\commalistelement}% \checkcolumnsetparent \let\newcommalistelement\empty @@ -1848,7 +1848,7 @@ {\unvbox\normalpagebox \global\lastskipinotr\lastskip}% \ifdim\lastskipinotr>\zeropoint - \global\setbox\b_page_set_preceding\hbox + \global\setbox\b_page_set_preceding\hpack {\lower\strutdepth\box\b_page_set_preceding}% \fi \dp\b_page_set_preceding\strutdepth @@ -1970,7 +1970,7 @@ \def\columnplaceholder#1#2% {\hbox - {\setbox\scratchbox\hbox to \hsize + {\setbox\scratchbox\hpack to \hsize {\iftracecolumnset \hskip-.5ex% \startcolor[columnset:#2]\vrule\s!width\exheight\s!height.5\exheight\s!depth.5\exheight\stopcolor @@ -2032,7 +2032,7 @@ \def\page_set_place_float_slot {\setbox\floatbox\vbox{\page_otr_command_flush_float_box}% \dp\floatbox\strutdp - \@EA\uppercasestring\floatmethod\to\floatmethod + \expandafter\uppercasestring\floatmethod\to\floatmethod \OTRSETstoreincolumnslot\floatmethod\floatbox \page_floats_report_total} @@ -2337,11 +2337,11 @@ \advance\!!countb \minusone % new (*) \doif{\columntextareaparameter\c!location}\v!depth - {\setbox\scratchbox\hbox{\lower\strutdepth\box\scratchbox}% + {\setbox\scratchbox\hpack{\lower\strutdepth\box\scratchbox}% \dp\scratchbox\zeropoint \ht\scratchbox\!!heighta}% % - \setbox0\hbox + \setbox0\hpack {\ifcase\!!countc \copy\scratchbox % \box \else @@ -2360,7 +2360,7 @@ \advance\!!counta \columntextareaparameter\c!nx \advance\!!counta -\!!countc \advance\!!widtha -\!!widthb - \setbox0\hbox + \setbox0\hpack % {\hskip-\namedlayoutparameter\v!odd\c!backspace {\hskip-\layoutparameter\c!backspace \clip @@ -2560,7 +2560,7 @@ % todo: nboven/onder %\OTRSETstoreincolumnslotHERE\scratchbox \edef\floatmethod{\namedframedtextparameter{\??columnsetspan#1}\c!default}% - \@EA\uppercasestring\floatmethod\to\floatmethod + \expandafter\uppercasestring\floatmethod\to\floatmethod % todo : \v!here -> here enzovoorts \OTRSETstoreincolumnslot\floatmethod\scratchbox \checknextindentation[\namedframedtextparameter{\??columnsetspan#1}\c!indentnext]% @@ -2626,6 +2626,23 @@ % \s!page_otr_command_flush_margin_blocks =\page_set_command_flush_margin_blocks, % not used ] +\installfloatmethod \s!columnset \v!here \page_set_place_float_here +\installfloatmethod \s!columnset \v!force \page_set_place_float_force +\installfloatmethod \s!columnset \v!top \page_set_place_float_top +\installfloatmethod \s!columnset \v!bottom \page_set_place_float_bottom +\installfloatmethod \s!columnset \v!page \page_set_place_float_page +\installfloatmethod \s!columnset \s!tblr \page_set_place_float_slot +\installfloatmethod \s!columnset \s!lrtb \page_set_place_float_slot +\installfloatmethod \s!columnset \s!tbrl \page_set_place_float_slot +\installfloatmethod \s!columnset \s!rltb \page_set_place_float_slot +\installfloatmethod \s!columnset \s!fxtb \page_set_place_float_slot +\installfloatmethod \s!columnset \s!btlr \page_set_place_float_slot +\installfloatmethod \s!columnset \s!lrbt \page_set_place_float_slot +\installfloatmethod \s!columnset \s!btrl \page_set_place_float_slot +\installfloatmethod \s!columnset \s!rlbt \page_set_place_float_slot +\installfloatmethod \s!columnset \s!fxbt \page_set_place_float_slot +\installfloatmethod \s!columnset \s!fixd \page_set_place_float_force + \protect \endinput % extreme examples (1) diff --git a/tex/context/base/mkiv/page-sid.mkiv b/tex/context/base/mkiv/page-sid.mkiv index 6f5d9f357..803381244 100644 --- a/tex/context/base/mkiv/page-sid.mkiv +++ b/tex/context/base/mkiv/page-sid.mkiv @@ -41,6 +41,9 @@ \newdimen \d_page_sides_progress \newdimen \d_page_sides_page_total +\newdimen \d_page_sides_leftoffset +\newdimen \d_page_sides_rightoffset + %newbox \b_page_sides_bottom \newcount \c_page_sides_lines_done @@ -48,6 +51,7 @@ \newcount \c_page_sides_n_of_lines \newcount \c_page_sides_n_of_hang \newconstant \c_page_sides_float_type +\newcount \c_page_sides_hangafter \newconditional \c_page_sides_short \newconditional \c_page_sides_flag @@ -77,6 +81,9 @@ \newdimen \d_page_sides_progression +\newcount \c_page_sides_m_of_lines +\newconditional \c_page_sides_delayed + \newif \iftracesidefloats % public (might change) %D Defaults: @@ -216,6 +223,8 @@ +\compensatedinnermakeupmargin \relax \fi + \global\d_page_sides_leftoffset \d_page_sides_rightskip + \global\d_page_sides_rightoffset\d_page_sides_leftskip \ifdim\d_page_sides_rightskip>\zeropoint \global\advance\d_page_sides_rightskip\rightskip \fi @@ -394,7 +403,8 @@ \endgroup \else \forcestrutdepth - \fi} + \fi + \page_otr_command_set_vsize} % new \def\page_sides_flush_floats {\par @@ -541,30 +551,43 @@ \def\page_sides_inject_dummy_lines {\par \nointerlineskip + % \ifnum\lastpenalty>\zerocount + % \penalty\plustenthousand + % \fi \dontleavehmode \iftracesidefloats \page_sides_inject_dummy_line_traced \else \page_sides_inject_dummy_line_normal \fi - \vskip-\dimexpr\lineheight+\strutdp\relax + \par + % on an empty page we have topskip, say 12pt + \ignoreparskip + % this can be 18.5pt + \kern-\dimexpr\lineheight+\strutdp\relax + % so we can actually have a -2.5pt skip on top \ignoreparskip \blank[\v!samepage] - \blank[\v!disable]} + \blank[\v!disable] + % now say we are negative now + \ifdim\pagetotal<\zeropoint + % then we're at the top of the page ... quite messy .. i really need to + % make the page builder a bit more flexible .. should we do something now? + \fi} %D Checkers: \def\page_sides_check_floats_after_par {\page_sides_check_floats_indeed \ifdim\d_page_sides_pagetotal=\pagetotal \else - \global\let\page_sides_check_floats\page_sides_check_floats_indeed + \glet\page_sides_check_floats\page_sides_check_floats_indeed \page_sides_flush_floats \global\c_page_sides_n_of_lines\zerocount % here ! \fi} \unexpanded\def\page_sides_flush_floats_after_par {\global\d_page_sides_pagetotal\pagetotal - \global\let\page_sides_check_floats\page_sides_check_floats_after_par} + \glet\page_sides_check_floats\page_sides_check_floats_after_par} \unexpanded\def\page_sides_forget_floats {\global\d_page_sides_vsize\d_page_sides_vsize_reset @@ -651,18 +674,49 @@ \fi \endgroup} +% \def\page_sides_analyse_progress +% {\d_page_sides_progress\d_page_sides_vsize +% \ifconditional\c_page_sides_flag +% \advance\d_page_sides_progress-\d_page_sides_page_total +% \global\setfalse\c_page_sides_flag +% \else +% \advance\d_page_sides_progress-\pagetotal +% \fi} + +% test case +% +% \usemodule[art-01] +% \starttext +% \dorecurse{40}{\line{#1}} +% \placefigure[left]{}{} +% \input ward +% \startitemize +% \item word \item word \item word \item word +% \stopitemize +% \input ward +% \page +% \stoptext + \def\page_sides_analyse_progress - {\d_page_sides_progress\d_page_sides_vsize + {%\page_otr_command_set_vsize % this is new, otherwise topfloats are not taken into account + \d_page_sides_progress\d_page_sides_vsize \ifconditional\c_page_sides_flag \advance\d_page_sides_progress-\d_page_sides_page_total \global\setfalse\c_page_sides_flag \else + \ifdim\dimexpr\d_page_sides_progress+\d_page_sides_bottomtotal\relax>\pagegoal + % we adapt pagegoal because we can already have placed something with + % everypar and we hope that it triggers a flush, see test above + \pagegoal\dimexpr\pagegoal-\d_page_sides_bottomtotal\relax + \fi \advance\d_page_sides_progress-\pagetotal \fi} \def\page_sides_analyse_space {\global\settrue\c_page_sides_flag - \page_sides_force_depth +% \ifdim\pagegoal=\maxdimen +% \pagegoal\textheight % maybe +% \fi \global\d_page_sides_page_total \pagetotal % global \ifnum\c_page_sides_float_type<\plusfour \global\d_page_sides_width \zeropoint @@ -716,8 +770,18 @@ %D As we have no clear end of one or more paragraphs we only have pre float %D skips. -\def\page_sides_handle_float#1% grid (4) is rather experimental - {\page_sides_check_horizontal_skips +\newconstant\c_page_sides_page_method % will be: \c_page_sides_page_method\plusone + +\def\page_otr_force_new_page_one + {\vskip\d_page_sides_height + \penalty\outputpenalty + \vskip-\dimexpr\d_page_sides_height-\strutdp\relax + \prevdepth\strutdp} + %\ignoreparskip} + +\def\page_sides_handle_float#1% + {\page_sides_initialize_checker + \page_sides_check_horizontal_skips \page_sides_check_vertical_skips \page_sides_apply_horizontal_shift \page_sides_check_previous_float @@ -726,13 +790,26 @@ \page_sides_relocate_float{#1}% \page_sides_apply_vertical_shift \page_sides_analyse_space - \ifconditional\c_page_floats_room \else - \page_otr_fill_and_eject_page + \ifconditional\c_page_floats_room + \global\setfalse\c_page_sides_delayed + % we're ok + \else + \global\settrue\c_page_sides_delayed + \global\c_page_sides_m_of_lines\c_page_sides_n_of_lines + \ifcase\c_page_sides_page_method + \page_otr_fill_and_eject_page + \or + \page_otr_force_new_page_one + \else + \page_otr_fill_and_eject_page + \fi + \global\c_page_sides_n_of_lines\c_page_sides_m_of_lines \page_sides_analyse_space %\page_sides_inject_before \page_sides_inject_dummy_lines \fi \page_sides_place_float + \global\setfalse\c_page_sides_delayed \page_sides_check_floats_reset \page_sides_wrapup} @@ -740,8 +817,7 @@ {% we need to do this aftergroup \aftergroup\par \aftergroup\ignoreparskip - \aftergroup\ignorespaces - } + \aftergroup\ignorespaces} \def\page_sides_check_floats_indeed {\page_sides_analyse_progress @@ -752,7 +828,16 @@ \fi \parskip\s_spac_whitespace_parskip} % not needed -\let\page_sides_check_floats\page_sides_check_floats_indeed +% \let\page_sides_check_floats\page_sides_check_floats_indeed + +\let\page_sides_check_floats\relax + +\def\page_sides_initialize_checker + {\ifx\page_sides_check_floats\relax + \glet\page_sides_check_floats\page_sides_check_floats_indeed + \clf_enablesidefloatchecker + \glet\page_sides_initialize_checker\relax + \fi} \unexpanded\def\page_sides_check_floats_tracer {\begingroup @@ -771,8 +856,30 @@ \fi \endgroup} +% tricky test: + +% \starttext +% \dorecurse{33}{\line{#1}} +% \placefigure[left]{}{} +% \input ward +% \startitemize +% \item word \item word \item word \item word +% \stopitemize +% \input ward +% \page +% \placefigure[left]{}{} +% \dontleavehmode \begingroup \input ward \par \endgroup +% \dontleavehmode \begingroup \input ward \par \endgroup +% \dontleavehmode \begingroup \input ward \par \endgroup +% \input ward +% \stoptext + \unexpanded\def\page_sides_check_floats_set {\edef\p_sidethreshold{\floatparameter\c!sidethreshold}% + \ifconditional\c_page_sides_delayed + % For Alan's hanging right float that moved to the next page. + \d_page_sides_progress\zeropoint + \fi \ifx\p_sidethreshold\v!old \d_page_sides_progression\dimexpr\d_page_sides_progress+\strutht-\roundingeps\relax \c_page_sides_n_of_hang\d_page_sides_progression @@ -785,8 +892,14 @@ \dimexpr\d_page_sides_progress-\p_sidethreshold\relax \fi \getnoflines\d_page_sides_progression + % this can be an option + \ifdim\dimexpr\noflines\lineheight>\dimexpr\pagegoal-\pagetotal\relax + \getrawnoflines\d_page_sides_progression + \fi + % \c_page_sides_n_of_hang\noflines \fi + \global\c_page_sides_hangafter\zerocount \ifnum\c_page_sides_n_of_hang>\zerocount \ifcase\c_page_sides_n_of_lines \else @@ -822,6 +935,7 @@ \else \hangindent \ifnum\c_page_sides_float_type>\plusfour -\fi\d_page_sides_width \hangafter-\c_page_sides_n_of_hang + \global\c_page_sides_hangafter\hangafter \fi \fi \global\advance\c_page_sides_checks_done \plusone @@ -830,7 +944,16 @@ \fi} \unexpanded\def\page_sides_check_floats_reset - {\global\c_page_sides_checks_done\zerocount} + {\ifcase\c_page_sides_checks_done\else + \ifcase\c_page_sides_hangafter\else + % we need to deal with par's ending in a group which would restore + % hang parameters + \global\c_page_sides_hangafter\zerocount + \hangindent\zeropoint + \fi + % \global % no, otherwise a next hangindent won't work + \c_page_sides_checks_done\zerocount + \fi} \unexpanded\def\page_sides_synchronize_floats {\ifinner \else diff --git a/tex/context/base/mkiv/page-smp.mkiv b/tex/context/base/mkiv/page-smp.mkiv new file mode 100644 index 000000000..2711c9944 --- /dev/null +++ b/tex/context/base/mkiv/page-smp.mkiv @@ -0,0 +1,59 @@ +%D \module +%D [ file=page-smp, % was: core-mul, page-mul +%D version=1998.03.15, +%D title=\CONTEXT\ Page Macros, +%D subtitle=Simple Multi Column Output, +%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 + +%D The old one: + +\definemixedcolumns + [\v!columns] + % compatible with columns default : + [\c!balance=\v!yes, + \c!blank={\v!line,\v!fixed}] + +\unexpanded\def\setupcolumns + {\setupmixedcolumns[\v!columns]} + +%D This will be replaced by mixed box. + +\unexpanded\def\startsimplecolumns + {\dosingleempty\page_simple_start} + +\def\page_simple_start[#1]% + {\bgroup + \setsimplecolumnshsize[#1]% + \nopenalties + \setbox\scratchbox\vbox\bgroup + \forgetall} % \blank[\v!disable] + +\unexpanded\def\stopsimplecolumns + {\removebottomthings + \egroup + \rigidcolumnbalance\scratchbox + \egroup} + +\unexpanded\def\setsimplecolumnshsize[#1]% + {\getdummyparameters + [\c!width=\hsize, + \c!distance=1.5\bodyfontsize, + \c!n=2, + \c!lines=0, + #1]% + \edef\rigidcolumnlines + {\directdummyparameter\c!lines}% + \setrigidcolumnhsize + {\directdummyparameter\c!width}% + {\directdummyparameter\c!distance}% + {\directdummyparameter\c!n}} + +\protect \endinput diff --git a/tex/context/base/mkiv/page-spr.mkiv b/tex/context/base/mkiv/page-spr.mkiv index dc1e013d5..bb95ee467 100644 --- a/tex/context/base/mkiv/page-spr.mkiv +++ b/tex/context/base/mkiv/page-spr.mkiv @@ -23,15 +23,32 @@ % beware, ugly overload, to be redone +% \def\normalsettextpagecontent#1#2#3% #2 and #3 will disappear +% {\setbox#1\hbox +% {\setlayoutcomponentattribute{\v!page:\v!text}% +% \vbox \layoutcomponentboxattribute to \textheight +% {\offinterlineskip +% \freezetextwidth +% \hsize\textwidth % local variant of \sethsize +% \boxmaxdepth\maxdepth +% \noindent % content can be < \hsize +% \page_otr_command_package_contents#2#3}}% +% \dp#1\zeropoint +% \ifconditional\c_page_spread_busy +% \normalsettextpagecontent_spread{#1}% +% \else +% \normalsettextpagecontent_normal{#1}% +% \fi} + \def\normalsettextpagecontent#1#2#3% #2 and #3 will disappear - {\setbox#1\hbox + {\setbox#1\hpack {\setlayoutcomponentattribute{\v!page:\v!text}% - \vbox \layoutcomponentboxattribute to \textheight + \vpack \layoutcomponentboxattribute to \textheight {\offinterlineskip \freezetextwidth \hsize\textwidth % local variant of \sethsize \boxmaxdepth\maxdepth - \noindent % content can be < \hsize + \noindent % content can be < \hsize \page_otr_command_package_contents#2#3}}% \dp#1\zeropoint \ifconditional\c_page_spread_busy @@ -40,12 +57,18 @@ \normalsettextpagecontent_normal{#1}% \fi} +% \def\normalsettextpagecontent_normal#1% +% {\setbox#1\hbox to \makeupwidth +% {\hss\box#1\hss}} % never change the \hss's + \def\normalsettextpagecontent_normal#1% - {\setbox#1\hbox to \makeupwidth - {\hss\box#1\hss}} % never change the \hss's + {\ifdim\wd#1=\makeupwidth\else + \setbox#1\hpack to \makeupwidth + {\hss\box#1\hss}% never change the \hss's + \fi} \def\normalsettextpagecontent_spread#1% - {\setbox#1\hbox to \makeupwidth + {\setbox#1\hpack to \makeupwidth {\ifvoid\b_page_spread_content \ifconditional\c_page_spread_once \box#1% diff --git a/tex/context/base/mkiv/page-str.lua b/tex/context/base/mkiv/page-str.lua index 4aeffffd8..ebb49a918 100644 --- a/tex/context/base/mkiv/page-str.lua +++ b/tex/context/base/mkiv/page-str.lua @@ -20,18 +20,27 @@ local implement = interfaces.implement local nodecodes = nodes.nodecodes -local slide_node_list = nodes.slide -local write_node = nodes.write -local flush_node = nodes.flush -local copy_node_list = nodes.copy_list -local vpack_node_list = nodes.vpack +local nuts = nodes.nuts +local tonut = nodes.tonut +local slide_node_list = nuts.slide +local write_node = nuts.write +local flush_node = nuts.flush +local copy_node_list = nuts.copy_list +local vpack_node_list = nuts.vpack + +local getbox = nuts.getbox +local setlink = nuts.setlink +local getlist = nuts.getlist +local setlist = nuts.setlist +local getwhd = nuts.getwhd +local setwhd = nuts.setwhd local settings_to_array = utilities.parsers.settings_to_array local enableaction = nodes.tasks.enableaction local texgetdimen = tex.getdimen -local texgetbox = tex.getbox +----- texgetbox = tex.getbox local trace_collecting = false trackers.register("streams.collecting", function(v) trace_collecting = v end) local trace_flushing = false trackers.register("streams.flushing", function(v) trace_flushing = v end) @@ -41,7 +50,11 @@ local report_streams = logs.reporter("streams") streams = streams or { } -- might move to the builders namespace local streams = streams -local data, name, stack = { }, nil, { } +-- maybe store head and tail ... first we need usage + +local data = { } +local name = nil +local stack = { } function streams.enable(newname) if newname == "default" then @@ -66,7 +79,7 @@ end function streams.collect(head,where) if name and head and name ~= "default" then - local tail = node.slide(head) + local head = tonut(head) local dana = data[name] if not dana then dana = { } @@ -75,7 +88,7 @@ function streams.collect(head,where) local last = dana[#dana] if last then local tail = slide_node_list(last) - tail.next, head.prev = head, tail + setlink(tail,head) elseif last == false then dana[#dana] = head else @@ -84,9 +97,9 @@ function streams.collect(head,where) if trace_collecting then report_streams("appending snippet %a to slot %s",name,#dana) end - return nil, true + return nil else - return head, false + return head end end @@ -118,7 +131,7 @@ function streams.flush(name,copy) -- problem: we need to migrate afterwards for i=1,dn do local di = dana[i] if di then - write_node(copy_node_list(di.list)) -- list, will be option + write_node(copy_node_list(getlist(di))) -- list, will be option end end if copy then @@ -131,8 +144,8 @@ function streams.flush(name,copy) -- problem: we need to migrate afterwards for i=1,dn do local di = dana[i] if di then - write_node(di.list) -- list, will be option - di.list = nil + write_node(getlist(di)) -- list, will be option + setlist(di) flush_node(di) end end @@ -167,7 +180,7 @@ function streams.synchronize(list) -- this is an experiment ! local slot = dana[m] if slot then local vbox = vpack_node_list(slot) - local ht, dp = vbox.height, vbox.depth + local wd, ht, dp = getwhd(vbox) if ht > height then height = ht end @@ -191,32 +204,36 @@ function streams.synchronize(list) -- this is an experiment ! local dana = data[name] local vbox = dana[m] if vbox then - local delta_height = height - vbox.height - local delta_depth = depth - vbox.depth + local wd, ht, dp = getwhd(vbox) + local delta_height = height - ht + local delta_depth = depth - dp if delta_height > 0 or delta_depth > 0 then if false then -- actually we need to add glue and repack - vbox.height, vbox.depth = height, depth + setwhd(vbox,false,height,depth) if trace_flushing then report_streams("slot %s of %a with delta (%p,%p) is compensated",m,i,delta_height,delta_depth) end else -- this is not yet ok as we also need to keep an eye on vertical spacing -- so we might need to do some splitting or whatever - local tail = vbox.list and slide_node_list(vbox.list) - local n, delta = 0, delta_height -- for tracing + local list = getlist(vbox) + local tail = list and slide_node_list(list) + local n = 0 + local delta = delta_height -- for tracing while delta > 0 do -- we need to add some interline penalties - local line = copy_node_list(texgetbox("strutbox")) - line.height, line.depth = strutht, strutdp + local line = copy_node_list(getbox("strutbox")) + setwhd(line,false,strutht,strutdp) if tail then - tail.next, line.prev = line, tail + setlink(tail,line) end - tail = line - n, delta = n +1, delta - struthtdp + tail = line + n = n + 1 + delta = delta - struthtdp end - dana[m] = vpack_node_list(vbox.list) - vbox.list = nil + dana[m] = vpack_node_list(getlist(vbox)) + setlist(vbox) flush_node(vbox) if trace_flushing then report_streams("slot %s:%s with delta (%p,%p) is compensated by %s lines",m,i,delta_height,delta_depth,n) @@ -230,6 +247,8 @@ function streams.synchronize(list) -- this is an experiment ! end end +-- hm, nut or node + tasks.appendaction("mvlbuilders", "normalizers", "streams.collect") tasks.disableaction("mvlbuilders", "streams.collect") diff --git a/tex/context/base/mkiv/page-str.mkiv b/tex/context/base/mkiv/page-str.mkiv index 57a465603..354c1f3c3 100644 --- a/tex/context/base/mkiv/page-str.mkiv +++ b/tex/context/base/mkiv/page-str.mkiv @@ -56,7 +56,7 @@ \unexpanded\def\disableoutputstream {\inoutputstreamfalse - \global\let\currentoutputstream\s!default + \glet\currentoutputstream\s!default \clf_disablestream} \unexpanded\def\startoutputstream[#1]% diff --git a/tex/context/base/mkiv/page-txt.mkvi b/tex/context/base/mkiv/page-txt.mkvi index b043b60c7..97668c143 100644 --- a/tex/context/base/mkiv/page-txt.mkvi +++ b/tex/context/base/mkiv/page-txt.mkvi @@ -98,8 +98,8 @@ {\expandafter\normalgdef\csname\??layouttextsreset#vertical\endcsname{\page_layouts_set_element_status_normal#vertical}} \def\page_layouts_set_element_status_normal#vertical% - {\global\expandafter\let\csname\namedlayoutelementhash#vertical\c!state\endcsname\v!normal - \global\expandafter\let\csname\??layouttextsreset#vertical\endcsname\relax + {\expandafter\glet\csname\namedlayoutelementhash#vertical\c!state\endcsname\v!normal + \expandafter\glet\csname\??layouttextsreset#vertical\endcsname\relax \page_layouts_synchronize_element{#vertical}} \def\page_layouts_synchronize_element#vertical% @@ -527,10 +527,10 @@ \page_layouts_place_text_line_right \page_layouts_place_text_line_left \namedlayoutelementparameter\currentlayouttextline\c!after - \kern\zeropoint}% keep the \dp, beware of \vtops, never change this! + \vkern\zeropoint}% keep the \dp, beware of \vtops, never change this! \dp\b_page_layouts_element\zeropoint \box\b_page_layouts_element - \vskip-#height\relax} + \vkern-#height\relax} \let\page_layouts_extra_at_margin_left \plusone \let\page_layouts_extra_at_margin_right\plustwo @@ -831,21 +831,21 @@ \calculatereducedvsizes \swapmargins \offinterlineskip - \vskip\dimexpr-\topheight-\topdistance\relax + \vkern\dimexpr-\topheight-\topdistance\relax \the\toptextcontent - \vskip\dimexpr\topheight+\topdistance\relax + \vkern\dimexpr\topheight+\topdistance\relax \the\headertextcontent - \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax + \vkern\dimexpr\headerheight+\headerdistance+\textdistance\relax \anch_positions_place_anchors - \vskip\dimexpr-\textdistance-\textheight\relax + \vkern\dimexpr-\textdistance-\textheight\relax \the\texttextcontent - \vskip\textheight + \vkern\textheight \the\everyendoftextbody - \vskip\footerdistance + \vkern\footerdistance \the\footertextcontent - \vskip\dimexpr\footerheight+\bottomdistance\relax + \vkern\dimexpr\footerheight+\bottomdistance\relax \the\bottomtextcontent - \vskip\bottomheight + \vkern\bottomheight \vfilll}% \smashbox\b_page_layouts_element \box\b_page_layouts_element} @@ -854,16 +854,20 @@ % \let\page_prepare_backgrounds\gobbleoneargument % \fi +% only for very special controlled cases or experiments: + +\let\page_scale_text_box\gobbleoneargument + \def\page_insert_body#1#2% {\setbox\b_page_layouts_element\vpack {\offinterlineskip \calculatereducedvsizes \calculatehsizes \swapmargins - \vskip\dimexpr\headerheight+\headerdistance+\textdistance\relax + \vkern\dimexpr\headerheight+\headerdistance+\textdistance\relax \dontleavehmode %\page_prepare_backgrounds{#2}% - \hbox to \makeupwidth + \hpack to \makeupwidth {\begingroup \swapmargins \goleftonpage @@ -880,6 +884,7 @@ \settextpagecontent\b_page_layouts_element{#1}{#2}% \page_backgrounds_add_to_text\b_page_layouts_element \page_grids_add_to_box\b_page_layouts_element + \page_scale_text_box\b_page_layouts_element \box\b_page_layouts_element \begingroup \ifdim\rightmarginwidth>\zeropoint diff --git a/tex/context/base/mkiv/publ-aut.lua b/tex/context/base/mkiv/publ-aut.lua index be0c771a3..e74c7ee18 100644 --- a/tex/context/base/mkiv/publ-aut.lua +++ b/tex/context/base/mkiv/publ-aut.lua @@ -16,6 +16,7 @@ local lpeg = lpeg local type, next, tostring, tonumber = type, next, tostring, tonumber local concat, sortedhash = table.concat, table.sortedhash local utfsub = utf.sub +local find = string.find local formatters = string.formatters local P, S, C, V, Cs, Ct, Cg, Cf, Cc = lpeg.P, lpeg.S, lpeg.C, lpeg.V, lpeg.Cs, lpeg.Ct, lpeg.Cg, lpeg.Cf, lpeg.Cc @@ -38,6 +39,8 @@ local chardata = characters.data local trace_hashing = false trackers.register("publications.authorhash", function(v) trace_hashing = v end) +local expand_authors = false directives.register("publications.prerollauthor", function(v) expand_authors = v end) + local report = logs.reporter("publications","authors") local report_cite = logs.reporter("publications","cite") @@ -61,8 +64,8 @@ local v_last = interfaces.variables.last local space = lpegpatterns.whitespace local comma = P(",") -local period = P(".") -local dash = P("-") +local period = P(".") + P("{.}") +local dash = P("-") + P("{-}") local firstcharacter = lpegpatterns.utf8byte local utf8character = lpegpatterns.utf8character local p_and = space^1 * (P("and") + P("&&") + P("++")) * space^1 @@ -123,6 +126,8 @@ end local authormap = allocate() publications.authormap = authormap +local prerollcmdstring = publications.prerollcmdstring + local function splitauthor(author,justsplit) local detail, remapped if not justsplit then @@ -142,6 +147,9 @@ local function splitauthor(author,justsplit) end local author = remapped or author local firstnames, vons, surnames, initials, juniors, options + if expand_authors and find(author,"\\btxcmd") then + author = prerollcmdstring(author) + end local split = lpegmatch(commasplitter,author) local n = #split detail = { @@ -151,8 +159,11 @@ local function splitauthor(author,justsplit) if n == 1 then -- {First Middle von Last} local words = lpegmatch(spacesplitter,author) - firstnames, vons, surnames = { }, { }, { } - local i, n = 1, #words + local i = 1 + local n = #words + firstnames = { } + vons = { } + surnames = { } while i <= n do local w = words[i] if is_upper(w) then @@ -190,9 +201,12 @@ local function splitauthor(author,justsplit) elseif n == 2 then -- {Last, First} -- {von Last, First} - firstnames, vons, surnames = { }, { }, { } local words = lpegmatch(spacesplitter,split[1]) - local i, n = 1, #words + local i = 1 + local n = #words + firstnames = { } + vons = { } + surnames = { } while i <= n do local w = words[i] if is_upper(w) then @@ -202,21 +216,25 @@ local function splitauthor(author,justsplit) end end while i <= n do - surnames[#surnames+1], i = words[i], i + 1 + surnames[#surnames+1] = words[i] + i = i + 1 end -- local words = lpegmatch(spacesplitter,split[2]) - local i, n = 1, #words + local i = 1 + local n = #words while i <= n do local w = words[i] if is_upper(w) then - firstnames[#firstnames+1], i = w, i + 1 + firstnames[#firstnames+1] = w + i = i + 1 else break end end while i <= n do - vons[#vons+1], i = words[i], i + 1 + vons[#vons+1] = words[i] + i = i + 1 end if surnames and firstnames and #surnames == 0 then -- safeguard @@ -308,12 +326,14 @@ local function the_initials(initials,symbol,connector) if not connector then connector = "-" end - local result, r = { }, 0 + local result = { } + local r = 0 for i=1,#initials do local initial = initials[i] if type(initial) == "table" then -- J.-J. - local set, s = { }, 0 + local set = { } + local s = 0 for i=1,#initial do if i > 1 then s = s + 1 ; set[s] = connector @@ -825,8 +845,10 @@ local p_clean = Cs ( ( + lpeg.patterns.utf8character )^1) +-- Probabbly more robust is a two pass approach. + authorhashers.short = function(authors) - -- a short is a real dumb hardcodes kind of tag and we only support + -- a short is a real dumb hardcoded kind of tag and we only support -- this one because some users might expect it, not because it makes -- sense if type(authors) == "table" then diff --git a/tex/context/base/mkiv/publ-dat.lua b/tex/context/base/mkiv/publ-dat.lua index 310df82f3..f09e97a8d 100644 --- a/tex/context/base/mkiv/publ-dat.lua +++ b/tex/context/base/mkiv/publ-dat.lua @@ -22,6 +22,10 @@ if not characters then dofile(resolvers.findfile("char-tex.lua")) end +if not utilities.sequencers then + dofile(resolvers.findfile("util-seq.lua")) +end + local lower, find, sub = string.lower, string.find, string.sub local concat, copy, tohash = table.concat, table.copy, table.tohash local next, type, rawget, tonumber = next, type, rawget, tonumber @@ -30,7 +34,7 @@ local lpegmatch, lpegpatterns = lpeg.match, lpeg.patterns local textoutf = characters and characters.tex.toutf local settings_to_hash, settings_to_array = utilities.parsers.settings_to_hash, utilities.parsers.settings_to_array local formatters = string.formatters -local sortedkeys, sortedhash, keys = table.sortedkeys, table.sortedhash, table.keys +local sortedkeys, sortedhash, keys, sort = table.sortedkeys, table.sortedhash, table.keys, table.sort local xmlcollected, xmltext, xmlconvert = xml.collected, xml.text, xml.convert local setmetatableindex = table.setmetatableindex @@ -439,7 +443,7 @@ do ----- command = P("\\") * (Carg(1) * C(R("az","AZ")^1) * space^0 / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end) local command = P("\\") * (Carg(1) * C(csletter^1) * space^0 / function(list,c) list[c] = (list[c] or 0) + 1 return "btxcmd{" .. c .. "}" end) local whatever = P("\\") * P(" ")^1 / " " - + P("\\") * ( P("hbox") + P("raise") ) -- bah + ----- + P("\\") * ( P("hbox") + P("raise") ) -- bah -- no longer local somemath = P("$") * ((1-P("$"))^1) * P("$") -- let's not assume nested math ----- character = lpegpatterns.utf8character local any = P(1) @@ -482,6 +486,8 @@ do local tags = table.setmetatableindex("table") + local indirectcrossrefs = true + local function do_definition(category,tag,tab,dataset) publicationsstats.nofdefinitions = publicationsstats.nofdefinitions + 1 if tag == "" then @@ -529,11 +535,23 @@ do value = lpegmatch(filter_2,value,1,dataset.commands) -- we need to start at 1 for { } end if normalized == "crossref" then - local parent = luadata[value] - if parent then - setmetatableindex(entries,parent) + if indirectcrossrefs then + setmetatableindex(entries,function(t,k) + local parent = rawget(luadata,value) + if parent == entries then + report_duplicates("bad parent %a for %a in dataset %s",value,hashtag,dataset.name) + setmetatableindex(entries,nil) + return entries + elseif parent then + setmetatableindex(entries,parent) + return entries[k] + else + report_duplicates("no valid parent %a for %a in dataset %s",value,hashtag,dataset.name) + setmetatableindex(entries,nil) + end + end) else - -- warning + dataset.nofcrossrefs = dataset.nofcrossrefs +1 end end entries[normalized] = value @@ -640,16 +658,17 @@ do local somevalue = d_value + b_value + s_value + r_value + n_value + e_value local value = Cs((somevalue * ((spacing * hash * spacing)/"" * somevalue)^0)) - local stripper = lpegpatterns.stripper - value = value / function(s) return lpegmatch(stripper,s) end + local stripper = lpegpatterns.collapser + local stripped = value / function(s) return lpegmatch(stripper,s) end local forget = percent^1 * (1-lineending)^0 local spacing = spacing * forget^0 * spacing - local assignment = spacing * key * spacing * equal * spacing * value * spacing + local replacement= spacing * key * spacing * equal * spacing * value * spacing + local assignment = spacing * key * spacing * equal * spacing * stripped * spacing local definition = category * spacing * left * spacing * tag * spacing * comma * Ct((assignment * comma^0)^0) * spacing * right * Carg(1) / do_definition local crapword = C((1-space-left)^1) - local shortcut = Cmt(crapword,function(_,p,s) return lower(s) == "string" and p end) * spacing * left * ((assignment * Carg(1))/do_shortcut * comma^0)^0 * spacing * right + local shortcut = Cmt(crapword,function(_,p,s) return lower(s) == "string" and p end) * spacing * left * ((replacement * Carg(1))/do_shortcut * comma^0)^0 * spacing * right local comment = Cmt(crapword,function(_,p,s) return lower(s) == "comment" and p end) * spacing * lpegpatterns.argument * Carg(1) / do_comment local casecrap = #S("sScC") * (shortcut + comment) @@ -682,12 +701,37 @@ do statistics.starttiming(publications) publicationsstats.nofbytes = publicationsstats.nofbytes + size current.nofbytes = current.nofbytes + size + current.nofcrossrefs = 0 if source then table.insert(current.sources, { filename = source, checksum = md5.HEX(content) }) current.loaded[source] = kind or true end - current.newtags = #current.luadata > 0 and { } or current.newtags + local luadata = current.luadata + current.newtags = #luadata > 0 and { } or current.newtags lpegmatch(bibtotable,content or "",1,current) + if current.nofcrossrefs > 0 then + for tag, entries in next, luadata do + local value = entries.crossref + if value then + local parent = luadata[value] + if parent == entries then + report_duplicates("bad parent %a for %a in dataset %s",value,hashtag,dataset.name) + elseif parent then + local t = { } + for k, v in next, parent do + if not entries[k] then + entries[k] = v + t[#t+1] = k + end + end + sort(t) + entries.inherited = concat(t,",") + else + report_duplicates("no valid parent %a for %a in dataset %s",value,hashtag,dataset.name) + end + end + end + end statistics.stoptiming(publications) end @@ -708,22 +752,27 @@ do local compact = false -- can be a directive but then we also need to deal with newlines ... not now - function publications.converttoxml(dataset,nice,dontstore,usedonly,subset) -- we have fields ! + function publications.converttoxml(dataset,nice,dontstore,usedonly,subset,noversion,rawtoo) -- we have fields ! local current = datasets[dataset] local luadata = subset or (current and current.luadata) if luadata then statistics.starttiming(publications) -- local result, r, n = { }, 0, 0 - local usedonly = usedonly and publications.usedentries() + if usedonly then + usedonly = publications.usedentries() + usedonly = usedonly[current.name] + end -- r = r + 1 ; result[r] = "" - r = r + 1 ; result[r] = "" + r = r + 1 ; result[r] = formatters[""](current.name) -- if nice then -- will be default local f_entry_start = formatters[" "] local s_entry_stop = " " local f_field = formatters[" %s"] + local f_cdata = formatters[" "] + for tag, entry in sortedhash(luadata) do if not usedonly or usedonly[tag] then r = r + 1 ; result[r] = f_entry_start(tag,entry.category,entry.index) @@ -737,6 +786,11 @@ do end end end + if rawtoo then + local s = publications.savers.bib(current,false,{ [tag] = entry }) + s = utilities.strings.striplines(s,"prune and collapse") + r = r + 1 ; result[r] = f_cdata(s) + end r = r + 1 ; result[r] = s_entry_stop n = n + 1 end @@ -766,7 +820,7 @@ do -- r = r + 1 ; result[r] = "" -- - result = concat(result,nice and "\n" or nil) + result = concat(result,nice and "\n" or nil,noversion and 2 or 1,#result) -- if dontstore then -- indeed @@ -1084,7 +1138,7 @@ do \ifdefined\btxcmd % we're probably in context \else - \def\btxcmd#1{\csname#1\endcsname} + \def\btxcmd#1{\begincsname#1\endcsname} \fi } @@ -1094,8 +1148,8 @@ do local f_start = formatters["@%s{%s,\n"] local f_field = formatters[" %s = {%s},\n"] local s_stop = "}\n\n" - local result = { s_preamble } - local n, r = 0, 1 + local result = { } + local n, r = 0, 0 for tag, data in sortedhash(tobesaved) do r = r + 1 ; result[r] = f_start(data.category or "article",tag) for key, value in sortedhash(data) do @@ -1106,8 +1160,16 @@ do r = r + 1 ; result[r] = s_stop n = n + 1 end - report("%s entries from dataset %a saved in %a",n,dataset,filename) - io.savedata(filename,concat(result)) + result = concat(result) + if find(result,"\\btxcmd") then + result = s_preamble .. result + end + if filename then + report("%s entries from dataset %a saved in %a",n,dataset,filename) + io.savedata(filename,result) + else + return result + end end function savers.lua(dataset,filename,tobesaved) @@ -1127,8 +1189,8 @@ do table.save(filename,list) end - function savers.xml(dataset,filename,tobesaved) - local result, n = publications.converttoxml(dataset,true,true,false,tobesaved) + function savers.xml(dataset,filename,tobesaved,rawtoo) + local result, n = publications.converttoxml(dataset,true,true,false,tobesaved,false,rawtoo) report("%s entries from dataset %a saved in %a",n,dataset,filename) io.savedata(filename,result) end @@ -1175,6 +1237,8 @@ do return dataset end + publications.savers = savers + if implement then implement { @@ -1248,3 +1312,18 @@ do writers.pagenumber = writers.range end + +if implement then + + implement { + name = "btxshortcut", + arguments = "2 strings", + actions = function(instance,key) + local d = publications.datasets[instance] + context(d and d.shortcuts[key] or "?") + end, + } + +end + +-- inspect(publications.load { filename = "e:/tmp/oeps.bib" }) diff --git a/tex/context/base/mkiv/publ-imp-apa.mkvi b/tex/context/base/mkiv/publ-imp-apa.mkvi index cd78a8799..160cc4522 100644 --- a/tex/context/base/mkiv/publ-imp-apa.mkvi +++ b/tex/context/base/mkiv/publ-imp-apa.mkvi @@ -432,8 +432,44 @@ \c!style=\v!italic] \definebtx + [apa:\s!cite:subtitle] + [apa:\s!cite:title] + +\definebtx + [apa:\s!cite:booktitle] + [apa:\s!cite:title] + +\definebtx + [apa:\s!cite:subbooktitle] [apa:\s!cite:booktitle] + +% Will these get used? + +\definebtx + [apa:\s!cite:title:inbook] [apa:\s!cite:title] + [\c!style=] % not italic + +\definebtx + [apa:\s!cite:title:incollection] + [apa:\s!cite:title:inbook] + +\definebtx + [apa:\s!cite:title:inproceedings] + [apa:\s!cite:title:inbook] + +\definebtx + [apa:\s!cite:subtitle:inbook] + [apa:\s!cite:title:inbook] + +\definebtx + [apa:\s!cite:subtitle:incollection] + [apa:\s!cite:title:incollection] + +\definebtx + [apa:\s!cite:subtitle:inproceedings] + [apa:\s!cite:title:inproceedings] + \definebtx [apa:\s!cite:tag] @@ -441,7 +477,6 @@ [\c!left={[}, \c!right={]}] - \definebtx [apa:\s!cite:index] [apa:\s!cite] @@ -679,6 +714,50 @@ \fastsetup{\s!btx:\s!cite:author:years} \stopsetups +% these setups need to be explicitly defined in order to get cite rendering + +\startsetups \s!btx:apa:\s!cite:organization + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:booktitle + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subbooktitle + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +% are these needed? + +\startsetups \s!btx:apa:\s!cite:title:inbook + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:title:incollection + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:title:inproceedings + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle:inbook + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle:incollection + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + +\startsetups \s!btx:apa:\s!cite:subtitle:inproceedings + \fastsetup{\s!btx:\s!cite:normal} +\stopsetups + % used in publ-imp-page.mkvi \startsetups btx:apa:list:page-or-pages @@ -797,7 +876,7 @@ % A book might have an editor AND an author \doif {\currentbtxcategory} {book} { \doifnot {\btxfoundname{author}} {editor} { - \btxdoif {ineditor} { % ineditor authorconversion + \btxdoif {ineditor} { % ineditor specific authorconversion \btxleftparenthesis \btxflush{ineditor} \btxcomma @@ -973,11 +1052,11 @@ \starttexdefinition unexpanded btx:apa:editor-in \btxdoif {booktitle} { \btxlabeltext{In} + \btxspace \doifnot {\btxfoundname{author}} {editor} { - \btxspace \texdefinition{btx:apa:author-or-editor} {ineditor} + \btxcomma } - \btxspace \texdefinition{btx:apa:composed-title}{booktitle} \btxperiod } diff --git a/tex/context/base/mkiv/publ-imp-cite.mkvi b/tex/context/base/mkiv/publ-imp-cite.mkvi index 8fe96429d..56af83a1b 100644 --- a/tex/context/base/mkiv/publ-imp-cite.mkvi +++ b/tex/context/base/mkiv/publ-imp-cite.mkvi @@ -232,9 +232,6 @@ \startsetups \s!btx:\s!cite:pages \fastsetup{\s!btx:\s!cite:range} \stopsetups -\startsetups \s!btx:\s!cite:organization - \fastsetup{\s!btx:\s!cite:range} -\stopsetups % is the next one used? % Yes, bibtex is a mess and one can have pages or sometimes page diff --git a/tex/context/base/mkiv/publ-inc.lua b/tex/context/base/mkiv/publ-inc.lua new file mode 100644 index 000000000..9231be3c1 --- /dev/null +++ b/tex/context/base/mkiv/publ-inc.lua @@ -0,0 +1,26 @@ +if not modules then modules = { } end modules ['publ-inc'] = { + version = 1.001, + comment = "this module part of publication support", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local fullstrip = string.fullstrip +local datasets, savers = publications.datasets, publications.savers +local assignbuffer = buffers.assign + +interfaces.implement { + name = "btxentrytobuffer", + arguments = "3 strings", + actions = function(dataset,tag,target) + local d = datasets[dataset] + if d then + d = d.luadata[tag] + end + if d then + d = fullstrip(savers.bib(dataset,false,{ [tag] = d })) + end + assignbuffer(target,d or "") + end +} diff --git a/tex/context/base/mkiv/publ-inc.mkiv b/tex/context/base/mkiv/publ-inc.mkiv new file mode 100644 index 000000000..c1728f44a --- /dev/null +++ b/tex/context/base/mkiv/publ-inc.mkiv @@ -0,0 +1,63 @@ +%D \module +%D [ file=publ-inc, +%D version=2018.06.23, +%D title=\CONTEXT\ Publication Macros, +%D subtitle=XML inclusion, +%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 Publication Macros / XML inclusion} + +\registerctxluafile{publ-inc}{} + +%D A teaser for Alan. + +\unprotect + +\definesymbol[btxattachment][{\infofont\darkred btx}] +\definesymbol[btxcomment] [{\infofont\darkblue btx}] + +\unexpanded\def\btx_add_blob#1#2% + {\relax + \clf_btxentrytobuffer{\currentbtxdataset}{\currentbtxtag}{temp-btx-export}% + #2% + [\c!symbol=#1,% + \c!space=\v!yes, + \c!buffer=temp-btx-export,% + \c!name={\currentbtxtag.bib}]% + \relax} + +\unexpanded\def\btxattach + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \btx_add_blob{btxattachment}\attachment + \dostoptagged + \fi \fi \fi} + +\unexpanded\def\btxcomment + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \btx_add_blob{btxcomment}\comment + \dostoptagged + \fi \fi \fi} + +%D This kind of feature creep is not yet configurable, nor documented. + +\unexpanded\def\btxaddsource + {\iftrialtypesetting \else \ifexporting \iflocation + \dostarttagged\t!ignore\empty + \llap{% + \btx_add_blob{btxattachment}\attachment + \quad + \btx_add_blob{btxcomment}\comment + \hskip\leftmargindistance + }% + \dostoptagged + \fi \fi \fi} + +\protect \endinput diff --git a/tex/context/base/mkiv/publ-ini.lua b/tex/context/base/mkiv/publ-ini.lua index 9dfeda168..f62352f07 100644 --- a/tex/context/base/mkiv/publ-ini.lua +++ b/tex/context/base/mkiv/publ-ini.lua @@ -32,7 +32,7 @@ local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash local setmetatableindex = table.setmetatableindex local lpegmatch = lpeg.match local P, S, C, Ct, Cs, R, Carg = lpeg.P, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cs, lpeg.R, lpeg.Carg -local upper = utf.upper +local upper = characters.upper local report = logs.reporter("publications") local report_cite = logs.reporter("publications","cite") @@ -229,9 +229,9 @@ logs.registerfinalactions(function() logs.startfilelogging(report,"used btx commands") done = true end - if isdefined[command] then + if isdefined(command) then report("%-20s %-20s % 5i %s",name,command,n,"known") - elseif isdefined[upper(command)] then + elseif isdefined(upper(command)) then report("%-20s %-20s % 5i %s",name,command,n,"KNOWN") else report("%-20s %-20s % 5i %s",name,command,n,"unknown") @@ -246,7 +246,7 @@ logs.registerfinalactions(function() logs.starterrorlogging(report,"unknown btx commands") for name, dataset in sortedhash(datasets) do for command, n in sortedhash(dataset.commands) do - if not isdefined[command] and not isdefined[upper(command)] then + if not isdefined(command) and not isdefined(upper(command)) then report("%-20s %-20s % 5i %s",name,command,n,"unknown") end end @@ -1065,14 +1065,17 @@ do -- maybe not redo when already done local function shortsorter(a,b) - local ay, by = a[2], b[2] -- year + local ay = a[2] -- year + local by = b[2] -- year if ay ~= by then return ay < by end - local ay, by = a[3], b[3] -- suffix + local ay = a[3] -- suffix + local by = b[3] -- suffix if ay ~= by then -- bah, bah, bah - local an, bn = tonumber(ay), tonumber(by) + local an = tonumber(ay) + local bn = tonumber(by) if an and bn then return an < bn else @@ -2023,7 +2026,8 @@ do for i=1,nofranges do local r = ranges[i] ctx_btxsetconcat(concatstate(i,nofranges)) - local first, last = r[1], r[2] + local first = r[1] + local last = r[2] ctx_btxsetfirstinternal(first[2].internal) ctx_btxsetfirstpage(first[1]) if last then @@ -2044,7 +2048,8 @@ do } local function identical(a,b) - local na, nb = #a, #b + local na = #a + local nb = #b if na ~= nb then return false end @@ -2056,7 +2061,8 @@ do end return true end - local ha, hb = a.hash, b.hash + local ha = a.hash + local hb = b.hash if ha then return ha == hb end @@ -3456,3 +3462,20 @@ do } end + +do + + local btxstring = "" + + implement { + name = "btxcmdstring", + actions = function() if btxstring ~= "" then context(btxstring) end end, + } + + function publications.prerollcmdstring(str) + btxstring = str or "" + tex.runtoks("t_btx_cmd") + return nodes.toutf(tex.getbox("b_btx_cmd").list) or str + end + +end diff --git a/tex/context/base/mkiv/publ-ini.mkiv b/tex/context/base/mkiv/publ-ini.mkiv index 9f970547d..ead46929d 100644 --- a/tex/context/base/mkiv/publ-ini.mkiv +++ b/tex/context/base/mkiv/publ-ini.mkiv @@ -107,23 +107,27 @@ %D to split between cite and list here as it only complicates matters (timing) and is %D not clear either. -\let\currentbtxspecification\empty +\let\currentbtxspecification \empty +\let\currentbtxspecificationfallback\empty + +\installmacrostack\currentbtxspecification +\installmacrostack\currentbtxspecificationfallback \unexpanded\def\startbtxrenderingdefinitions[#1]% {\unprotect - \pushmacro\currentbtxspecification + \push_macro_currentbtxspecification \edef\currentbtxspecification{#1}} \unexpanded\def\stopbtxrenderingdefinitions - {\popmacro\currentbtxspecification + {\pop_macro_currentbtxspecification \protect} \unexpanded\def\loadbtxdefinitionfile [#1]{\clf_btxloaddefinitionfile {#1}} \unexpanded\def\loadbtxreplacementfile[#1]{\clf_btxloadreplacementfile{#1}} \unexpanded\def\publ_specification_push#1% - {\pushmacro\currentbtxspecification - \pushmacro\currentbtxspecificationfallback + {\push_macro_currentbtxspecification + \push_macro_currentbtxspecificationfallback \edef\currentbtxspecification{#1}% \edef\currentbtxspecificationfallback{\namedbtxparameter\currentbtxspecification\c!default}% \ifx\currentbtxspecificationfallback\currentbtxspecification @@ -132,8 +136,8 @@ \clf_btxsetspecification{\currentbtxspecification}} \unexpanded\def\publ_specification_pop - {\popmacro\currentbtxspecificationfallback - \popmacro\currentbtxspecification + {\pop_macro_currentbtxspecificationfallback + \pop_macro_currentbtxspecification \clf_btxsetspecification{\currentbtxspecification}} \unexpanded\def\publ_specification_set#1% beware: is global @@ -223,9 +227,6 @@ \installcommandhandler \??btxregister {btxregister} \??btxregister \installcommandhandler \??btxrendering {btxrendering} \??btxrendering -\let\currentbtxcitealternative \empty -\let\currentbtxspecificationfallback\empty - \unexpanded\def\setbtxparameterset#1#2% {\edef\currentbtx {\ifcsname\??btx\currentbtxspecification:#1:#2:\s!parent\endcsname @@ -333,6 +334,11 @@ \expandafter\publ_command_nop \fi{#1}} +\newtoks\t_btx_cmd +\newbox \b_btx_cmd + +\t_btx_cmd{\global\setbox\b_btx_cmd\hpack{\clf_btxcmdstring}} + \let\btxcmd\btxcommand \def\publ_command_yes#1% @@ -341,10 +347,10 @@ \def\publ_command_nop#1% {\ifcsname#1\endcsname \showmessage\m!publications{10}{#1,#1}% - \global\expandafter\let\csname\??btxcommand#1\expandafter\endcsname\csname#1\endcsname + \expandafter\glet\csname\??btxcommand#1\expandafter\endcsname\csname#1\endcsname \else\ifcsname\utfupper{#1}\endcsname \showmessage\m!publications{10}{#1}{\utfupper{#1}}% - \global\expandafter\let\csname\??btxcommand#1\expandafter\endcsname\csname\utfupper{#1}\endcsname + \expandafter\glet\csname\??btxcommand#1\expandafter\endcsname\csname\utfupper{#1}\endcsname \else \showmessage\m!publications{11}{#1}% \setugvalue{\??btxcommand#1}{\underbar{\tttf#1}}% @@ -385,6 +391,12 @@ \let\btxsetup\fastsetup +\def\btxfield #1{\dostarttagged\t!pubfld{#1}\clf_btxfield {\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged} +\def\btxdetail #1{\dostarttagged\t!pubfld{#1}\clf_btxdetail{\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged} +\def\btxflush #1{\dostarttagged\t!pubfld{#1}\clf_btxflush {\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged} +\def\btxdirect #1{\dostarttagged\t!pubfld{#1}\clf_btxdirect{\currentbtxdataset}{\currentbtxtag}{#1}\dostoptagged} +%def\btxauthorfield#1{\dostarttagged\t!pubfld{#1}\clf_btxauthorfield \currentbtxauthorindex{#1}\dostoptagged} + %D How complex will we go? Can we assume that e.g. an apa style will not be mixed %D with another one? I think this assumption is okay. For manuals we might want to %D mix but we can work around it. @@ -629,11 +641,13 @@ \unexpanded\def\btxnumberingsetup#1% {\begingroup + \dostarttagged\t!listtag\empty \setbtxparameterset{\c!list:\s!numbering}\currentbtxnumbering % brrrr \setbtxlist \btxparameter\c!left % \btxparameter\c!command{\publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}}% \publ_fast_setup\plusthree{\s!list:\s!numbering}{#1}% \btxparameter\c!right + \dostoptagged \endgroup \btx_reset_numbering} % probably not needed @@ -655,21 +669,34 @@ \def\btx_entry_inject_list_text {\publ_fast_setup\plusfour\s!list\s!text} +\ifdefined\dotagpublication \else \let\dotagpublication \gobbletwoarguments \fi + \unexpanded\def\btx_entry_inject {\begingroup + \dostarttagged\t!publication\empty + \dotagpublication\currentbtxdataset\currentbtxtag \redoconvertfont % see (**) in strc-lst, this will become an configuration option \edef\currentbtxcategory{\btxfield{category}}% \ignorespaces \ifconditional\c_btx_list_texts + \dostarttagged\t!listtext\s!left \currentbtxbefore + \dostoptagged \fi + %\dostarttagged\t!listcontent\empty \btx_entry_inject_list_text + %\dostoptagged \ifconditional\c_btx_list_pages + \dostarttagged\t!listpage\empty \btx_entry_inject_pages + \dostoptagged \fi \ifconditional\c_btx_list_texts + \dostarttagged\t!listtext\s!right \currentbtxafter + \dostoptagged \fi + \dostoptagged \endgroup} \unexpanded\def\btxshowentryinline @@ -843,6 +870,8 @@ \expandafter\p_command\expandafter{\number\nofbtxlistentries}\relax \fi \else + \dostarttagged\t!publications\currentbtxrendering + \dostarttagged\t!list{btx}% \startpacked[\v!blank]% % sorting and so \clf_btxpreparelistentries{\currentbtxdataset}% could be put in collect @@ -865,6 +894,8 @@ {\let\currentbtxlistentry\recurselevel \clf_btxflushlistentry{\currentbtxdataset}\currentbtxlistentry\relax}% \stoppacked + \dostoptagged + \dostoptagged \fi \btxrenderingparameter\c!after \fi @@ -978,8 +1009,10 @@ \strc_lists_apply_renderingsetup} \def\btx_entry_indeed - {\btx_list_reference_inject - \btx_entry_inject} + {\dostarttagged\t!listcontent\empty + \btx_list_reference_inject + \btx_entry_inject + \dostoptagged} \def\btx_page_indeed {} @@ -1113,7 +1146,8 @@ \let\btxcitereference\btx_cite_reference_inject -\let\currentbtxnumbering\empty +\let\currentbtxnumbering \empty +\let\currentbtxcitealternative \empty \appendtoks \edef\currentbtxnumbering{\btxrenderingparameter\c!numbering}% @@ -1995,4 +2029,15 @@ \fetchruntimecommand \showbtxfields \f!publ_tra \fetchruntimecommand \showbtxtables \f!publ_tra +%D Some potential crap: +%D +%D Because I consider this bad data management and a weird mix of languages only one +%D accessor is provided. + +\unexpanded\def\btxshortcut + {\dosingleempty\publ_shortcut} + +\def\publ_shortcut[#1]#2% + {\clf_btxshortcut{\iffirstargument#1\else\s!default\fi}{#2}} + \protect diff --git a/tex/context/base/mkiv/scrn-bar.mkvi b/tex/context/base/mkiv/scrn-bar.mkvi index 7634398f8..0c320cd03 100644 --- a/tex/context/base/mkiv/scrn-bar.mkvi +++ b/tex/context/base/mkiv/scrn-bar.mkvi @@ -138,7 +138,7 @@ \setbox2\hbox{\inheritedinteractionbarframed{\symbol[\interactionparameter\c!symbolset][\v!previouspage]}}% \scratchheight\ht2 % needed because we default to nothing \letinteractionbarparameter\c!strut\v!no - \letinteractionparameter\c!width\zeropoint + % \letinteractionparameter\c!width\zeropoint \scratchcounterone\zerocount % new, was 1 \processallactionsinset [#list] diff --git a/tex/context/base/mkiv/scrn-but.mkvi b/tex/context/base/mkiv/scrn-but.mkvi index 8bbd6eeda..87af29cfb 100644 --- a/tex/context/base/mkiv/scrn-but.mkvi +++ b/tex/context/base/mkiv/scrn-but.mkvi @@ -11,20 +11,16 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -% \restorestandardblank -% better namespace for pos - \writestatus{loading}{ConTeXt Screen Macros / Buttons} \registerctxluafile{scrn-but}{} \unprotect -%D Buttons are just what their names says: things that can be -%D clicked (pushed) on. They are similar to \type{\goto}, -%D except that the text argument is not interpreted. -%D Furthermore one can apply anything to them that can be done -%D with \type{\framed}. +%D Buttons are just what their names says: things that can be clicked (pushed) on. +%D They are similar to \type{\goto}, except that the text argument is not +%D interpreted. Furthermore one can apply anything to them that can be done with +%D \type {\framed}. %D %D \startbuffer %D \button[width=3cm,height=1.5cm]{Exit}[ExitViewer] @@ -119,8 +115,8 @@ %D \overlaybutton[reference] %D \stoptyping %D -%D This command can be used to define overlays an/or can be -%D used in the whatevertext areas, like: +%D This command can be used to define overlays an/or can be used in the whatevertext +%D areas, like: %D %D \starttyping %D \defineoverlay[PrevPage][\overlaybutton{PrevPage}] @@ -128,8 +124,7 @@ %D \setuptexttexts[\overlaybutton{NextPage}] %D \stoptyping %D -%D For practical reasons, this macro accepts square brackets -%D as well as braces. +%D For practical reasons, this macro accepts square brackets as well as braces. \unexpanded\def\overlaybutton {\dosingleempty\scrn_button_overlay} diff --git a/tex/context/base/mkiv/scrn-fld.mkvi b/tex/context/base/mkiv/scrn-fld.mkvi index dec334209..7710a32dc 100644 --- a/tex/context/base/mkiv/scrn-fld.mkvi +++ b/tex/context/base/mkiv/scrn-fld.mkvi @@ -480,7 +480,7 @@ \let\resetfields\relax -\def\scrn_field_load_scripts{\useJSscripts[fld]\globallet\scrn_field_load_scripts\relax} +\def\scrn_field_load_scripts{\useJSscripts[fld]\glet\scrn_field_load_scripts\relax} \newconditional\fieldlabelshown \newconditional\fieldframeshown @@ -627,11 +627,13 @@ %D Common stuff (obsolete) + \newcount\c_scrn_field_system_n -\def\nextsystemfield - {\global\advance\c_scrn_field_system_n\plusone - \def\currentsystemfield{sys::\number\c_scrn_field_system_n}} +\def\currentsystemfield{sys::\number\c_scrn_field_system_n} + +\unexpanded\def\nextsystemfield + {\global\advance\c_scrn_field_system_n\plusone} %D \CONTEXT\ had tooltips right from the moment that it %D supported fields. Due to the at that moment somewhat @@ -754,7 +756,8 @@ {\ifcsname\??fieldstack#tag\endcsname % already done \else - \setgvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][#settings]}% + %setgvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][#settings]}% + \setxvalue{\??fieldstack#tag}{\scrn_fieldstack_construct[#tag][#symbols][\normalunexpanded{#settings}]}% \fi} \unexpanded\def\fieldstack @@ -768,26 +771,28 @@ \newbox\b_scrn_fieldstack_box +\definesymbol[\s!empty][] + \def\scrn_fieldstack_add#tag#settings#symbol% {\advance\scratchcounter\plusone \edef\currentfieldstackname{#tag:\number\scratchcounter}% \ifnum\scratchcounter=\fieldcategoryparameter\c!start\relax - \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\empty},\c!default={#symbol}]% + \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default={#symbol}]% \else - \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\empty},\c!default=]% + \definefieldbody[\currentfieldstackname][\c!type=check,\c!values={#symbol,\s!empty},\c!default=\s!empty]% \fi \setbox\b_scrn_fieldstack_box\hbox{\symbol[#symbol]}% \setcollector [fieldstack] {\fieldbody [\currentfieldstackname] - [\c!option=\v!readonly, + [\c!option={\v!readonly}, \c!width=\wd\b_scrn_fieldstack_box, \c!height=\ht\b_scrn_fieldstack_box, \c!depth=\dp\b_scrn_fieldstack_box, #settings]}} -\def\scrn_fieldstack_construct[#tag][#symbols][#settings]% start=n, 0 == leeg +\unexpanded\def\scrn_fieldstack_construct[#tag][#symbols][#settings]% start=n, 0 == leeg {\iflocation \dontleavehmode \begingroup @@ -822,21 +827,56 @@ \unexpanded\def\overlayrollbutton {\dodoubleargument\scrn_rollbutton_overlay} -\def\scrn_rollbutton_overlay[#regionin][#regionout]% +\unexpanded\def\scrn_rollbutton_overlay[#regionin][#regionout]% + {\iffirstargument + \scrn_rollbutton_overlay_indeed[#regionin][#regionout]% + \else + \expandafter\scrn_rollbutton_overlay_indeed + \fi} + +% \def\scrn_rollbutton_overlay_indeed#regionin#regionout% +% {\iflocation +% \bgroup +% \global\advance\c_scrn_rollbutton_n\plusone +% \definesymbol +% [rollbutton:\number\c_scrn_rollbutton_n] +% [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% +% \definefieldbody +% [rollbutton:\number\c_scrn_rollbutton_n] +% [\c!type=push, +% \c!regionin={#regionin}, +% \c!regionout={#regionout}, +% \c!values=\currentsystemfield, +% \c!default=\currentsystemfield]% +% \fitfield[\currentsystemfield]% +% \egroup +% \fi} + +\def\scrn_rollbutton_overlay_indeed#regionin#regionout% {\iflocation \bgroup - \global\advance\c_scrn_rollbutton_n\plusone + \global\advance\c_scrn_rollbutton_n_button\plusone + \global\advance\c_scrn_rollbutton_n_symbol\plusone \definesymbol - [rollbutton:\number\c_scrn_rollbutton_n] + [rollsymbol:\number\c_scrn_rollbutton_n_symbol] [{\framed[\c!frame=\v!off,\c!width=\overlaywidth,\c!height=\overlayheight]{}}]% - \definefieldbody - [rollbutton:\number\c_scrn_rollbutton_n] - [\c!type=push, - \c!regionin={#regionin}, - \c!regionout={#regionout}, - \c!values=\currentsystemfield, - \c!default=\currentsystemfield]% - \fitfield[\currentsystemfield]% + % \definefieldbody + % [rollbutton:\number\c_scrn_rollbutton_n_button] + % [\c!type=push, + % \c!values=rollsymbol:\number\c_scrn_rollbutton_n_symbol, + % \c!default=rollsymbol:\number\c_scrn_rollbutton_n_symbol]% + % \fitfield + % [rollbutton:\number\c_scrn_rollbutton_n_button]% + % [\c!regionin={#regionin}, + % \c!regionout={#regionout}]% + % + \definefield + [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton] + [rollsymbol:\number\c_scrn_rollbutton_n_symbol]% + \fitfield + [rollbutton:\number\c_scrn_rollbutton_n_button]% + [\c!regionin={#regionin},\c!regionout={#regionout}]% + % \egroup \fi} @@ -914,7 +954,7 @@ %D We plug into the menu system \unexpanded\def\scrn_menu_psh_start[#reference]#text\stoppsh - {\starttxt\pushbutton[\currentmenu][#reference]\stoptxt} + {\starttxt\pushbutton[\currentinteractionmenu][#reference]\stoptxt} \unexpanded\def\scrn_menu_psh_direct[#reference]#text\\ {\scrn_menu_psh_start[#reference]\stoprob} @@ -956,6 +996,8 @@ \newcount\c_scrn_rollbutton_n_button \newcount\c_scrn_rollbutton_n_symbol +\def\lastrollbuttonindex{\the\c_scrn_rollbutton_n_button} + \unexpanded\def\rollbutton {\dodoubleempty\scrn_rollbutton} @@ -973,11 +1015,16 @@ \setbuttonparameter \usebuttonstyleandcolor} +\setupfield + [rollbutton] + [\c!frame=\v!off, + \c!offset=\v!overlay] + \def\scrn_rollbutton[#tag][#settings]#text[#reference]% {\dontleavehmode \bgroup - \advance\c_scrn_rollbutton_n_button\plusone - \advance\c_scrn_rollbutton_n_symbol\plusone + \global\advance\c_scrn_rollbutton_n_button\plusone + \global\advance\c_scrn_rollbutton_n_symbol\plusone \iffirstargument \ifsecondargument \edef\currentinteractionmenu{#tag}% @@ -994,21 +1041,18 @@ \else \let\scrn_rollbutton_symbol\scrn_rollbutton_symbol_b \fi - % todo: share symbols, tricky since different dimensions + % todo: share symbols, tricky since different dimensions (maybe \unique...) \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:n][\scrn_rollbutton_symbol{n}{#text}]% \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:r][\scrn_rollbutton_symbol{r}{#text}]% \definesymbol[rollsymbol:\number\c_scrn_rollbutton_n_symbol:d][\scrn_rollbutton_symbol{d}{#text}]% - \setupfield - [rollbutton] - [\c!frame=\v!off, - \c!offset=\v!overlay, - \c!clickout={#reference}]% \definefield [rollbutton:\number\c_scrn_rollbutton_n_button][push][rollbutton] [rollsymbol:\number\c_scrn_rollbutton_n_symbol:n,% rollsymbol:\number\c_scrn_rollbutton_n_symbol:r,% rollsymbol:\number\c_scrn_rollbutton_n_symbol:d]% - \fitfield[rollbutton:\number\c_scrn_rollbutton_n_button]% + \fitfield + [rollbutton:\number\c_scrn_rollbutton_n_button]% + [\c!clickout={#reference}]% \egroup} \unexpanded\def\scrn_rollbutton_symbol_indeed#getparameter#inheritedframed#setparameter#usestyleandcolor#what#text% @@ -1023,7 +1067,7 @@ %D We plug into the menu system \unexpanded\def\scrn_menu_rob_start[#reference]#text\stoprob - {\starttxt\rollbutton[\currentmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt} + {\starttxt\rollbutton[\currentinteractionmenu]{\ignorespaces#text\unskip}[#reference]\stoptxt} \unexpanded\def\scrn_menu_rob_direct[#reference]#text\\ {\scrn_menu_rob_start[#reference]#text\stoprob} diff --git a/tex/context/base/mkiv/scrn-ini.mkvi b/tex/context/base/mkiv/scrn-ini.mkvi index e1be43f37..557ceb563 100644 --- a/tex/context/base/mkiv/scrn-ini.mkvi +++ b/tex/context/base/mkiv/scrn-ini.mkvi @@ -61,7 +61,7 @@ \to \everyjob % it makes no sense to create an environment as we will seldom have structured -% interactionso a general start-stop will do +% interactions so a general start-stop will do % % \appendtoks % \setuevalue \currentinteraction {\scrn_interaction_direct{\currentinteraction}}% diff --git a/tex/context/base/mkiv/scrn-pag.mkvi b/tex/context/base/mkiv/scrn-pag.mkvi index 7695443ad..a3b0a78c6 100644 --- a/tex/context/base/mkiv/scrn-pag.mkvi +++ b/tex/context/base/mkiv/scrn-pag.mkvi @@ -188,13 +188,13 @@ \let\scrn_canvas_synchronize_complex\relax \appendtoks - \global\let\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed - \global\let\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed + \glet\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed + \glet\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed \to \everysetuplayout \appendtoks - \global\let\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed - \global\let\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed + \glet\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed + \glet\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed \to \everysetuplayouttarget \def\scrn_canvas_synchronize_only @@ -213,8 +213,8 @@ \def\scrn_canvas_synchronize_simple_indeed {\scrn_canvas_synchronize_only - %\global\let\scrn_canvas_synchronize_simple \relax - \global\let\scrn_canvas_synchronize_complex\relax} + %\glet\scrn_canvas_synchronize_simple \relax + \glet\scrn_canvas_synchronize_complex\relax} \def\scrn_canvas_synchronize_complex_indeed {\scrn_canvas_calculate % otherwise we need to hook it into setuppage etc @@ -235,8 +235,8 @@ copies \numexpr\interactionscreenparameter\c!copies\relax print {\interactionscreenparameter\c!print}% \relax - %\global\let\scrn_canvas_synchronize_simple \relax - \global\let\scrn_canvas_synchronize_complex\relax} + %\glet\scrn_canvas_synchronize_simple \relax + \glet\scrn_canvas_synchronize_complex\relax} \appendtoks \begingroup @@ -262,8 +262,8 @@ \c!option=\v!auto] \appendtoks - \global\let\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed - \global\let\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed + \glet\scrn_canvas_synchronize_simple \scrn_canvas_synchronize_simple_indeed + \glet\scrn_canvas_synchronize_complex\scrn_canvas_synchronize_complex_indeed \to \everysetupinteractionscreen %D Conditional page breaks: diff --git a/tex/context/base/mkiv/scrn-ref.mkvi b/tex/context/base/mkiv/scrn-ref.mkvi index bace13312..df395e550 100644 --- a/tex/context/base/mkiv/scrn-ref.mkvi +++ b/tex/context/base/mkiv/scrn-ref.mkvi @@ -83,15 +83,15 @@ %D delayed ... -\def\scrn_reference_enable_references - {\ifproductionrun - \clf_enableinteraction % only once anyway - \glet\scrn_reference_enable_references\relax - \fi} - -\appendtoks - \scrn_reference_enable_references -\to \everysetupinteraction +% \def\scrn_reference_enable_references +% {\ifproductionrun +% \clf_enableinteraction % only once anyway +% \glet\scrn_reference_enable_references\relax +% \fi} +% +% \appendtoks +% \scrn_reference_enable_references +% \to \everysetupinteraction \setupinteraction % start fit page and reset form [\c!openaction=, diff --git a/tex/context/base/mkiv/scrn-wid.mkvi b/tex/context/base/mkiv/scrn-wid.mkvi index c74125c72..d1571ca65 100644 --- a/tex/context/base/mkiv/scrn-wid.mkvi +++ b/tex/context/base/mkiv/scrn-wid.mkvi @@ -212,11 +212,10 @@ name {\attachmentparameter\c!name}% buffer {\attachmentparameter\c!buffer}% \relax - \setbox\b_scrn_attachment_link\hbox{\scrn_attachment_place}% \wd\b_scrn_attachment_link\currentattachmentwidth \ht\b_scrn_attachment_link\currentattachmentheight \dp\b_scrn_attachment_link\currentattachmentdepth - \box\b_scrn_attachment_link} + \expandnamespaceparameter\??attachmentlocation\attachmentparameter\c!location\s!unknown} \setvalue{\??attachmentmethod\v!hidden}% {\clf_insertattachment @@ -231,29 +230,48 @@ buffer {\attachmentparameter\c!buffer}% \relax} -\def\scrn_attachment_place - {\executeifdefined - {\??attachmentlocation\attachmentparameter\c!location}\hbox - {\box\b_scrn_attachment_link}} - -\setvalue{\??attachmentlocation\v!inmargin }{\inmargin } -\setvalue{\??attachmentlocation\v!leftedge }{\inleftedge } -\setvalue{\??attachmentlocation\v!rightedge }{\inrightedge } -\setvalue{\??attachmentlocation\v!leftmargin }{\inleftmargin } -\setvalue{\??attachmentlocation\v!rightmargin}{\inrightmargin} -\setvalue{\??attachmentlocation\v!high }{\high} -\setvalue{\??attachmentlocation\v!none }{\scrn_attachment_collect} -%setvalue{\??attachmentlocation\v!text }{\gobblenextargument} % gobbles the box - -\def\scrn_attachment_collect#content% +\unexpanded\def\scrn_attachment_flush_traced + {\hpack\bgroup + \blackrule % can be a fast one + [ \c!color=trace:r, + \c!width=\wd\b_scrn_attachment_link, + \c!height=\ht\b_scrn_attachment_link, + \c!depth=\dp\b_scrn_attachment_link]% + \kern-\wd\b_scrn_attachment_link + \box\b_scrn_attachment_link + \egroup} + +\unexpanded\def\scrn_attachment_flush_normal + {\box\b_scrn_attachment_link} + +\installtextracker + {attachments.anchors} + {\let\scrn_attachment_flush\scrn_attachment_flush_traced} + {\let\scrn_attachment_flush\scrn_attachment_flush_normal} + +\let\scrn_attachment_flush\scrn_attachment_flush_normal + +\setvalue{\??attachmentlocation\v!inmargin }{\inmargin {\scrn_attachment_flush}} +\setvalue{\??attachmentlocation\v!leftedge }{\inleftedge {\scrn_attachment_flush}} +\setvalue{\??attachmentlocation\v!rightedge }{\inrightedge {\scrn_attachment_flush}} +\setvalue{\??attachmentlocation\v!leftmargin }{\inleftmargin {\scrn_attachment_flush}} +\setvalue{\??attachmentlocation\v!rightmargin}{\inrightmargin{\scrn_attachment_flush}} +\setvalue{\??attachmentlocation\v!high }{\high {\scrn_attachment_flush}} + +\setvalue{\??attachmentlocation\v!none}% {\global\setbox\b_scrn_attachment_collect\hbox\bgroup \ifvoid\b_scrn_attachment_collect\else \box\b_scrn_attachment_collect \hskip\attachmentparameter\c!distance\relax \fi - #content% + \scrn_attachment_flush \egroup} +\setvalue{\??attachmentlocation\s!unknown}% + {\ifvoid\b_scrn_attachment_collect\else + \box\b_scrn_attachment_collect + \fi} + \unexpanded\def\placeattachments {\ifvoid\b_scrn_attachment_collect\else \box\b_scrn_attachment_collect @@ -317,7 +335,7 @@ % % test % -% \startcomment[symbol=Balloon] +% \startcomment[symbol=Help] % Do we want this kind of rubish? % \stopcomment % @@ -360,6 +378,9 @@ % % test +%D The implementation is mostly the same as for attachments but sharing code +%D will not make it cleaner. + \installcorenamespace{comment} \installcorenamespace{commentlocation} @@ -489,17 +510,37 @@ \dp\b_scrn_comment_link\currentcommentdepth \expandnamespaceparameter\??commentlocation\commentparameter\c!location\s!unknown} -\setvalue{\??commentmethods\v!hidden}% - {} +\letvalue{\??commentmethods\v!hidden}\donothing + +\unexpanded\def\scrn_comment_flush_traced + {\hpack\bgroup + \blackrule % can be a fast one + [ \c!color=trace:y, + \c!width=\wd\b_scrn_comment_link, + \c!height=\ht\b_scrn_comment_link, + \c!depth=\dp\b_scrn_comment_link]% + \kern-\wd\b_scrn_comment_link + \box\b_scrn_comment_link + \egroup} + +\unexpanded\def\scrn_comment_flush_normal + {\box\b_scrn_comment_link} + +\installtextracker + {comments.anchors} + {\let\scrn_comment_flush\scrn_comment_flush_traced} + {\let\scrn_comment_flush\scrn_comment_flush_normal} + +\let\scrn_comment_flush\scrn_comment_flush_normal % todo: dedicated margin classes -\setvalue{\??commentlocation\v!inmargin }{\inmargin {\box\b_scrn_comment_link}} -\setvalue{\??commentlocation\v!leftedge }{\inleftedge {\box\b_scrn_comment_link}} -\setvalue{\??commentlocation\v!rightedge }{\inrightedge {\box\b_scrn_comment_link}} -\setvalue{\??commentlocation\v!leftmargin }{\inleftmargin {\box\b_scrn_comment_link}} -\setvalue{\??commentlocation\v!rightmargin}{\inrightmargin{\box\b_scrn_comment_link}} -\setvalue{\??commentlocation\v!high }{\high {\box\b_scrn_comment_link}} +\setvalue{\??commentlocation\v!inmargin }{\inmargin {\scrn_comment_flush}} +\setvalue{\??commentlocation\v!leftedge }{\inleftedge {\scrn_comment_flush}} +\setvalue{\??commentlocation\v!rightedge }{\inrightedge {\scrn_comment_flush}} +\setvalue{\??commentlocation\v!leftmargin }{\inleftmargin {\scrn_comment_flush}} +\setvalue{\??commentlocation\v!rightmargin}{\inrightmargin{\scrn_comment_flush}} +\setvalue{\??commentlocation\v!high }{\high {\scrn_comment_flush}} \setvalue{\??commentlocation\v!none}% {\global\setbox\b_scrn_comment_collect\hbox\bgroup @@ -507,7 +548,7 @@ \box\b_scrn_comment_collect \hskip\commentparameter\c!distance\relax \fi - \box\b_scrn_comment_link + \scrn_comment_flush \egroup} \setvalue{\??commentlocation\s!unknown}% diff --git a/tex/context/base/mkiv/scrp-cjk.lua b/tex/context/base/mkiv/scrp-cjk.lua index b31dc335a..83eecf6a3 100644 --- a/tex/context/base/mkiv/scrp-cjk.lua +++ b/tex/context/base/mkiv/scrp-cjk.lua @@ -6,23 +6,24 @@ if not modules then modules = { } end modules ['scrp-cjk'] = { license = "see context related readme files" } --- We can speed this up by preallocating nodes and copying them but the --- gain is not that large. - --- The input line endings: there is no way to distinguish between --- inline spaces and endofline turned into spaces (would not make --- sense either because otherwise a wanted space at the end of a --- line would have to be a hard coded ones. +-- We can speed this up by preallocating nodes and copying them but the gain is not +-- that large. +-- +-- If needed we can speed this up (traversers and prev next and such) but cjk +-- documents don't have that many glyphs and certainly not much font processing so +-- there not much gain in it. +-- +-- The input line endings: there is no way to distinguish between inline spaces and +-- endofline turned into spaces (would not make sense either because otherwise a +-- wanted space at the end of a line would have to be a hard coded ones. local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local copy_node = nuts.copy local remove_node = nuts.remove -local traverse_id = nuts.traverse_id +local nextglyph = nuts.traversers.glyph local getnext = nuts.getnext local getprev = nuts.getprev @@ -41,12 +42,14 @@ local new_kern = nodepool.kern local new_penalty = nodepool.penalty local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes + local glyph_code = nodecodes.glyph local glue_code = nodecodes.glue -local userskip_code = skipcodes.userskip -local spaceskip_code = skipcodes.spaceskip -local xspaceskip_code = skipcodes.xspaceskip + +local userskip_code = gluecodes.userskip +local spaceskip_code = gluecodes.spaceskip +local xspaceskip_code = gluecodes.xspaceskip local a_scriptstatus = attributes.private('scriptstatus') local a_scriptinjection = attributes.private('scriptinjection') @@ -439,13 +442,16 @@ local injectors = { -- [previous] [current] local function process(head,first,last) if first ~= last then - local lastfont, previous, last = nil, "start", nil + local lastfont = nil + local previous = "start" + local last = nil while true do - local upcoming, id = getnext(first), getid(first) + local upcoming = getnext(first) + local id = getid(first) if id == glyph_code then - local a = getattr(first,a_scriptstatus) + local a = getattr(first,a_scriptstatus) local current = numbertocategory[a] - local action = injectors[previous] + local action = injectors[previous] if action then action = action[current] if action then @@ -459,12 +465,16 @@ local function process(head,first,last) end previous = current else -- glue - local p, n = getprev(first), upcoming + local p = getprev(first) + local n = upcoming if p and n then - local pid, nid = getid(p), getid(n) + local pid = getid(p) + local nid = getid(n) if pid == glyph_code and nid == glyph_code then - local pa, na = getattr(p,a_scriptstatus), getattr(n,a_scriptstatus) - local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na] + local pa = getattr(p,a_scriptstatus) + local na = getattr(n,a_scriptstatus) + local pcjk = pa and numbertocategory[pa] + local ncjk = na and numbertocategory[na] if not pcjk or not ncjk or pcjk == "korean" or ncjk == "korean" or pcjk == "other" or ncjk == "other" @@ -509,10 +519,9 @@ scripts.installmethod { } function scripts.decomposehangul(head) - local head = tonut(head) local done = false - for current in traverse_id(glyph_code,head) do - local lead_consonant, medial_vowel, tail_consonant = decomposed(getchar(current)) + for current, char in nextglyph, head do + local lead_consonant, medial_vowel, tail_consonant = decomposed(char) if lead_consonant then setchar(current,lead_consonant) local m = copy_node(current) @@ -526,7 +535,7 @@ function scripts.decomposehangul(head) done = true end end - return tonode(head), done + return head, done end -- nodes.tasks.prependaction("processors","normalizers","scripts.decomposehangul") @@ -695,13 +704,16 @@ local injectors = { -- [previous] [current] local function process(head,first,last) if first ~= last then - local lastfont, previous, last = nil, "start", nil + local lastfont = nil + local previous = "start" + local last = nil while true do - local upcoming, id = getnext(first), getid(first) + local upcoming = getnext(first) + local id = getid(first) if id == glyph_code then - local a = getattr(first,a_scriptstatus) + local a = getattr(first,a_scriptstatus) local current = numbertocategory[a] - local action = injectors[previous] + local action = injectors[previous] if action then action = action[current] if action then @@ -715,12 +727,16 @@ local function process(head,first,last) end previous = current else -- glue - local p, n = getprev(first), upcoming + local p = getprev(first) + local n = upcoming if p and n then - local pid, nid = getid(p), getid(n) + local pid = getid(p) + local nid = getid(n) if pid == glyph_code and nid == glyph_code then - local pa, na = getattr(p,a_scriptstatus), getattr(n,a_scriptstatus) - local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na] + local pa = getattr(p,a_scriptstatus) + local na = getattr(n,a_scriptstatus) + local pcjk = pa and numbertocategory[pa] + local ncjk = na and numbertocategory[na] if not pcjk or not ncjk or pcjk == "korean" or ncjk == "korean" or pcjk == "other" or ncjk == "other" @@ -917,13 +933,16 @@ local injectors = { -- [previous] [current] local function process(head,first,last) if first ~= last then - local lastfont, previous, last = nil, "start", nil + local lastfont = nil + local previous = "start" + local last = nil while true do - local upcoming, id = getnext(first), getid(first) + local upcoming = getnext(first) + local id = getid(first) if id == glyph_code then - local a = getattr(first,a_scriptstatus) + local a = getattr(first,a_scriptstatus) local current = numbertocategory[a] - local action = injectors[previous] + local action = injectors[previous] if action then action = action[current] if action then @@ -940,12 +959,16 @@ local function process(head,first,last) -- upcoming = getnext(end_of_math(current)) -- previous = "start" else -- glue - local p, n = getprev(first), upcoming -- we should remember prev + local p = getprev(first) + local n = upcoming if p and n then - local pid, nid = getid(p), getid(n) + local pid = getid(p) + local nid = getid(n) if pid == glyph_code and nid == glyph_code then - local pa, na = getattr(p,a_scriptstatus), getattr(n,a_scriptstatus) - local pcjk, ncjk = pa and numbertocategory[pa], na and numbertocategory[na] + local pa = getattr(p,a_scriptstatus) + local na = getattr(n,a_scriptstatus) + local pcjk = pa and numbertocategory[pa] + local ncjk = na and numbertocategory[na] if not pcjk or not ncjk or pcjk == "korean" or ncjk == "korean" or pcjk == "other" or ncjk == "other" diff --git a/tex/context/base/mkiv/scrp-eth.lua b/tex/context/base/mkiv/scrp-eth.lua index 43cb2ff6a..f6a994b88 100644 --- a/tex/context/base/mkiv/scrp-eth.lua +++ b/tex/context/base/mkiv/scrp-eth.lua @@ -12,71 +12,16 @@ if not modules then modules = { } end modules ['scrp-eth'] = { local nuts = nodes.nuts local getnext = nuts.getnext -local getfont = nuts.getfont -local getid = nuts.getid +local ischar = nuts.ischar local getattr = nuts.getattr -local insert_node_before = nuts.insert_before - -local nodepool = nuts.pool - -local new_glue = nodepool.glue -local new_penalty = nodepool.penalty - local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph local a_scriptstatus = attributes.private('scriptstatus') -local a_scriptinjection = attributes.private('scriptinjection') -local categorytonumber = scripts.categorytonumber local numbertocategory = scripts.numbertocategory -local hash = scripts.hash -local numbertodataset = scripts.numbertodataset - -local fonthashes = fonts.hashes -local parameters = fonthashes.parameters - -local space, stretch, shrink, lastfont - -local inter_character_space_factor = 1 -local inter_character_stretch_factor = 1 -local inter_character_shrink_factor = 1 - -local function space_glue(current) - local data = numbertodataset[getattr(current,a_scriptinjection)] - if data then - inter_character_space_factor = data.inter_character_space_factor or 1 - inter_character_stretch_factor = data.inter_character_stretch_factor or 1 - inter_character_shrink_factor = data.inter_character_shrink_factor or 1 - end - local font = getfont(current) - if lastfont ~= font then - local pf = parameters[font] - space = pf.space - stretch = pf.space_stretch - shrink = pf.space_shrink - lastfont = font - end - return new_glue( - inter_character_space_factor * space, - inter_character_stretch_factor * stretch, - inter_character_shrink_factor * shrink - ) -end - -local function insert_space(head,current) - insert_node_before(head,current,space_glue(current)) -end - -local function insert_zerowidthspace(head,current) - insert_node_before(head,current,new_glue(0)) -end - -local function insert_nobreakspace(head,current) - insert_node_before(head,current,new_penalty(10000)) - insert_node_before(head,current,space_glue(current)) -end +local inserters = scripts.inserters -- syllable [zerowidthspace] syllable -- syllable [zerowidthspace] word @@ -88,21 +33,22 @@ end -- sentence [space] word -- sentence [space] sentence + local injectors = { -- [previous] [current] ethiopic_syllable = { - ethiopic_syllable = insert_zerowidthspace, - ethiopic_word = insert_nobreakspace, - ethiopic_sentence = insert_nobreakspace, + ethiopic_syllable = inserters.zerowidthspace_before, + ethiopic_word = inserters.nobreakspace_before, + ethiopic_sentence = inserters.nobreakspace_before, }, ethiopic_word = { - ethiopic_syllable = insert_space, - ethiopic_word = insert_space, - ethiopic_sentence = insert_space, + ethiopic_syllable = inserters.space_before, + ethiopic_word = inserters.space_before, + ethiopic_sentence = inserters.space_before, }, ethiopic_sentence = { - ethiopic_syllable = insert_space, - ethiopic_word = insert_space, - ethiopic_sentence = insert_space, + ethiopic_syllable = inserters.space_before, + ethiopic_word = inserters.space_before, + ethiopic_sentence = inserters.space_before, }, } @@ -111,10 +57,10 @@ local function process(head,first,last) local injector = false local current = first while current do - local id = getid(current) - if id == glyph_code then + local char, id = ischar(current) + if char then local scriptstatus = getattr(current,a_scriptstatus) - local category = numbertocategory[scriptstatus] + local category = numbertocategory[scriptstatus] if injector then local action = injector[category] if action then @@ -122,8 +68,6 @@ local function process(head,first,last) end end injector = injectors[category] - else - -- nothing yet end if current == last then break diff --git a/tex/context/base/mkiv/scrp-ini.lua b/tex/context/base/mkiv/scrp-ini.lua index 9bd70e30a..e6aa5f072 100644 --- a/tex/context/base/mkiv/scrp-ini.lua +++ b/tex/context/base/mkiv/scrp-ini.lua @@ -22,72 +22,75 @@ local report_splitting = logs.reporter("scripts","splitting") local utfbyte, utfsplit = utf.byte, utf.split local gmatch = string.gmatch -local attributes = attributes -local nodes = nodes -local context = context +local attributes = attributes +local nodes = nodes +local context = context -local texsetattribute = tex.setattribute +local texsetattribute = tex.setattribute -local nodecodes = nodes.nodecodes -local unsetvalue = attributes.unsetvalue +local nodecodes = nodes.nodecodes +local unsetvalue = attributes.unsetvalue -local implement = interfaces.implement +local implement = interfaces.implement -local glyph_code = nodecodes.glyph -local glue_code = nodecodes.glue +local glyph_code = nodecodes.glyph +local glue_code = nodecodes.glue -local emwidths = fonts.hashes.emwidths -local exheights = fonts.hashes.exheights +local emwidths = fonts.hashes.emwidths +local exheights = fonts.hashes.exheights -local a_scriptinjection = attributes.private('scriptinjection') -local a_scriptsplitting = attributes.private('scriptsplitting') -local a_scriptstatus = attributes.private('scriptstatus') +local a_scriptinjection = attributes.private('scriptinjection') +local a_scriptsplitting = attributes.private('scriptsplitting') +local a_scriptstatus = attributes.private('scriptstatus') -local fontdata = fonts.hashes.identifiers -local allocate = utilities.storage.allocate -local setnodecolor = nodes.tracers.colors.set -local setmetatableindex = table.setmetatableindex +local fontdata = fonts.hashes.identifiers +local allocate = utilities.storage.allocate +local setnodecolor = nodes.tracers.colors.set +local setmetatableindex = table.setmetatableindex -local enableaction = nodes.tasks.enableaction -local disableaction = nodes.tasks.disableaction +local enableaction = nodes.tasks.enableaction +local disableaction = nodes.tasks.disableaction -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode +local nuts = nodes.nuts -local getnext = nuts.getnext -local getchar = nuts.getchar -local getfont = nuts.getfont -local getid = nuts.getid -local getattr = nuts.getattr -local setattr = nuts.setattr -local isglyph = nuts.isglyph +local getnext = nuts.getnext +local getchar = nuts.getchar +local getfont = nuts.getfont +local getid = nuts.getid +local getattr = nuts.getattr +local setattr = nuts.setattr +local isglyph = nuts.isglyph -local insert_node_after = nuts.insert_after -local first_glyph = nuts.first_glyph -local traverse_id = nuts.traverse_id -local traverse_char = nuts.traverse_char +local insert_node_after = nuts.insert_after +local insert_node_before = nuts.insert_before -local nodepool = nuts.pool +local first_glyph = nuts.first_glyph -local new_glue = nodepool.glue -local new_rule = nodepool.rule -local new_penalty = nodepool.penalty +----- traverse_id = nuts.traverse_id +----- traverse_char = nuts.traverse_char +local nextglyph = nuts.traversers.glyph +local nextchar = nuts.traversers.char -scripts = scripts or { } -local scripts = scripts +local nodepool = nuts.pool -scripts.hash = scripts.hash or { } -local hash = scripts.hash +local new_glue = nodepool.glue +local new_rule = nodepool.rule +local new_penalty = nodepool.penalty -local handlers = allocate() -scripts.handlers = handlers +scripts = scripts or { } +local scripts = scripts -local injectors = allocate() -scripts.injectors = handlers +scripts.hash = scripts.hash or { } +local hash = scripts.hash -local splitters = allocate() -scripts.splitters = splitters +local handlers = allocate() +scripts.handlers = handlers + +local injectors = allocate() +scripts.injectors = handlers + +local splitters = allocate() +scripts.splitters = splitters local hash = { -- we could put these presets in char-def.lua -- @@ -206,6 +209,11 @@ local hash = { -- we could put these presets in char-def.lua [0x1361] = "ethiopic_word", [0x1362] = "ethiopic_sentence", -- + -- tibetan: + -- + [0x0F0B] = "breaking_tsheg", + [0x0F0C] = "nonbreaking_tsheg", + } local function provide(t,k) @@ -225,6 +233,7 @@ local function provide(t,k) elseif (k >= 0x01160 and k <= 0x011A7) then v = "jamo_medial" elseif (k >= 0x011A8 and k <= 0x011FF) then v = "jamo_final" elseif (k >= 0x01200 and k <= 0x0139F) then v = "ethiopic_syllable" + elseif (k >= 0x00F00 and k <= 0x00FFF) then v = "tibetan" else v = false end t[k] = v @@ -267,6 +276,7 @@ function scripts.installmethod(handler) report_preprocessing("missing (default) dataset in script %a",name) datasets.default = { } -- slower but an error anyway end + for k, v in next, datasets do setmetatableindex(v,defaults) end @@ -387,6 +397,8 @@ local scriptcolors = allocate { -- todo: just named colors ethiopic_syllable = "trace:1", ethiopic_word = "trace:2", ethiopic_sentence = "trace:3", + breaking_tsheg = "trace:1", + nonbreaking_tsheg = "trace:2", } scripts.colors = scriptcolors @@ -409,6 +421,8 @@ local numbertocategory = allocate { -- rather bound to cjk ... will be generaliz "ethiopic_syllable", "ethiopic_word", "ethiopic_sentence", + "breaking_tsheg", + "nonbreaking_tsheg", } local categorytonumber = allocate(table.swapped(numbertocategory)) -- could be one table @@ -417,7 +431,7 @@ scripts.categorytonumber = categorytonumber scripts.numbertocategory = numbertocategory local function colorize(start,stop) - for n in traverse_id(glyph_code,start) do + for n in nextglyph, start do local kind = numbertocategory[getattr(n,a_scriptstatus)] if kind then local ac = scriptcolors[kind] @@ -450,13 +464,12 @@ end -- we can have a fonts.hashes.originals function scripts.injectors.handler(head) - head = tonut(head) local start = first_glyph(head) -- we already have glyphs here (subtype 1) if not start then - return tonode(head), false + return head else - local last_a, normal_process, lastfont, originals = nil, nil, nil, nil - local done, first, last, ok = false, nil, nil, false + local last_a, normal_process, lastfont, originals, first, last + local ok = false while start do local char, id = isglyph(start) if char then @@ -473,7 +486,7 @@ function scripts.injectors.handler(head) else normal_process(head,first,last) end - ok, done = false, true + ok = false end first, last = nil, nil end @@ -482,16 +495,15 @@ function scripts.injectors.handler(head) normal_process = handler.injector end if normal_process then - -- wrong: originals are indices ! - local font = getfont(start) - if font ~= lastfont then - originals = fontdata[font].resources + -- id == font + if id ~= lastfont then + originals = fontdata[id].resources if resources then originals = resources.originals else originals = nil -- can't happen end - lastfont = font + lastfont = id end if originals and type(originals) == "number" then char = originals[char] or char @@ -517,7 +529,7 @@ function scripts.injectors.handler(head) else normal_process(head,first,last) end - ok, done = false, true + ok = false end first, last = nil, nil end @@ -532,7 +544,7 @@ function scripts.injectors.handler(head) else normal_process(head,first,last) end - ok, done = false, true + ok = false end first, last = nil, nil end @@ -554,7 +566,7 @@ function scripts.injectors.handler(head) else normal_process(head,first,last) end - first, last, ok, done = nil, nil, false, true + first, last, ok = nil, nil, false elseif first then first, last = nil, nil end @@ -570,16 +582,15 @@ function scripts.injectors.handler(head) else normal_process(head,first,last) end - done = true end - return tonode(head), done + return head end end -- kind of experimental .. might move to it's own module -- function scripts.splitters.handler(head) --- return head, false +-- return head -- end local function addwords(tree,data) @@ -701,32 +712,6 @@ end) local categories = characters.categories or { } --- local function hit(root,head) --- local current = getnext(head) --- local lastrun = false --- local lastfinal = false --- while current and getid(current) == glyph_code do --- local char = getchar(current) --- local newroot = root[char] --- if newroot then --- local final = newroot.final --- if final then --- lastrun = current --- lastfinal = final --- end --- root = newroot --- elseif categories[char] == "mn" then --- -- continue --- else --- return lastrun, lastfinal --- end --- current = getnext(current) --- end --- if lastrun then --- return lastrun, lastfinal --- end --- end - local function hit(root,head) local current = getnext(head) local lastrun = false @@ -759,9 +744,7 @@ end local tree, attr, proc function splitters.handler(head) -- todo: also first_glyph test - head = tonut(head) local current = head - local done = false while current do if getid(current) == glyph_code then local a = getattr(current,a_scriptsplitting) @@ -792,7 +775,6 @@ function splitters.handler(head) -- todo: also first_glyph test end end head, current = proc(handler,head,current,last,1) - done = true else if trace_splitdetail then -- could be punctuation @@ -803,7 +785,6 @@ function splitters.handler(head) -- todo: also first_glyph test end end head, current = proc(handler,head,current,last,2) - done = true end end end @@ -813,7 +794,7 @@ function splitters.handler(head) -- todo: also first_glyph test end current = getnext(current) end - return tonode(head), done + return head end local function marker(head,current,font,color) -- could become: nodes.tracers.marker @@ -907,15 +888,13 @@ setmetatableindex(cache_nop,function(t,k) local v = { } t[k] = v return v end) -- playing nice function autofontfeature.handler(head) - for n in traverse_char(tonut(head)) do + for n, char, font in nextchar, head do -- if getattr(n,a_scriptinjection) then -- -- already tagged by script feature, maybe some day adapt -- else - local char = getchar(n) local script = otfscripts[char] if script then local dynamic = getattr(n,0) or 0 - local font = getfont(n) if dynamic > 0 then local slot = cache_yes[font] local attr = slot[script] @@ -980,3 +959,73 @@ implement { name = "resetscript", actions = scripts.reset } + +-- some common helpers + + +do + + local parameters = fonts.hashes.parameters + + local space, stretch, shrink, lastfont + + local inter_character_space_factor = 1 + local inter_character_stretch_factor = 1 + local inter_character_shrink_factor = 1 + + local function space_glue(current) + local data = numbertodataset[getattr(current,a_scriptinjection)] + if data then + inter_character_space_factor = data.inter_character_space_factor or 1 + inter_character_stretch_factor = data.inter_character_stretch_factor or 1 + inter_character_shrink_factor = data.inter_character_shrink_factor or 1 + end + local font = getfont(current) + if lastfont ~= font then + local pf = parameters[font] + space = pf.space + stretch = pf.space_stretch + shrink = pf.space_shrink + lastfont = font + end + return new_glue( + inter_character_space_factor * space, + inter_character_stretch_factor * stretch, + inter_character_shrink_factor * shrink + ) + end + + scripts.inserters = { + + space_before = function(head,current) + return insert_node_before(head,current,space_glue(current)) + end, + space_after = function(head,current) + return insert_node_after(head,current,space_glue(current)) + end, + + zerowidthspace_before = function(head,current) + return insert_node_before(head,current,new_glue(0)) + end, + zerowidthspace_after = function(head,current) + return insert_node_after(head,current,new_glue(0)) + end, + + nobreakspace_before = function(head,current) + local g = space_glue(current) + local p = new_penalty(10000) + head, current = insert_node_before(head,current,p) + return insert_node_before(head,current,g) + end, + nobreakspace_after = function(head,current) + local g = space_glue(current) + local p = new_penalty(10000) + head, current = insert_node_after(head,current,g) + return insert_node_after(head,current,p) + end, + + } + +end + +-- end of helpers diff --git a/tex/context/base/mkiv/scrp-ini.mkiv b/tex/context/base/mkiv/scrp-ini.mkiv index 8f28f505d..f2d1da627 100644 --- a/tex/context/base/mkiv/scrp-ini.mkiv +++ b/tex/context/base/mkiv/scrp-ini.mkiv @@ -17,10 +17,11 @@ \registerctxluafile{scrp-cjk}{} \registerctxluafile{scrp-eth}{} \registerctxluafile{scrp-tha}{} +\registerctxluafile{scrp-tib}{} -\definesystemattribute[scriptinjection][public] -\definesystemattribute[scriptsplitting][public] -\definesystemattribute[scriptstatus] [public] +\definesystemattribute[scriptinjection][public,pickup] +\definesystemattribute[scriptsplitting][public,pickup] +\definesystemattribute[scriptstatus] [public,pickup] %D Since scripts need specific \LUA\ code we use hard coded attribute %D values, but we might have more tricks at some time, so we use a @@ -43,10 +44,23 @@ \unexpanded\def\scripts_basics_set {\clf_setscript{\currentscript}{\scriptparameter\c!method}{\scriptparameter\c!preset}} -\unexpanded\def\setscript[#1]% +% \unexpanded\def\setscript[#1]% +% {\edef\currentscript{#1}% +% \scripts_basics_set} + +\unexpanded\def\setglobalscript[#1]% + {\edef\currentscript{#1}% + \scripts_basics_set + \pickupscriptinjectionattribute + \pickupscriptsplittingattribute + \pickupscriptstatusattribute} + +\unexpanded\def\setlocalscript[#1]% {\edef\currentscript{#1}% \scripts_basics_set} +\let\setscript\setlocalscript + \unexpanded\def\resetscript {\clf_resetscript} @@ -73,6 +87,7 @@ \definescript [nihongo] [\c!method=nihongo] \definescript [ethiopic] [\c!method=ethiopic] \definescript [thai] [\c!method=thai] +\definescript [tibetan] [\c!method=tibetan] \definescript [latin] [\c!method=] % resets the attribute (also currentscript) diff --git a/tex/context/base/mkiv/scrp-tib.lua b/tex/context/base/mkiv/scrp-tib.lua new file mode 100644 index 000000000..b67f69648 --- /dev/null +++ b/tex/context/base/mkiv/scrp-tib.lua @@ -0,0 +1,81 @@ +if not modules then modules = { } end modules ['scrp-tib'] = { + version = 1.001, + comment = "companion to scrp-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local nuts = nodes.nuts + +local getnext = nuts.getnext +local getattr = nuts.getattr +local ischar = nuts.ischar + +local a_scriptstatus = attributes.private('scriptstatus') + +local numbertocategory = scripts.numbertocategory +local inserters = scripts.inserters + +local injectors = { + breaking_tsheg = inserters.space_after, +} + +-- more efficient is to check directly +-- +-- local b_tsheg = 0x0F0B -- breaking +-- local n_tsheg = 0x0F0C -- nonbreaking +-- +-- if char == b_tsheg then +-- head, current = insert_space_after(head,current) +-- end +-- +-- but this is more general + +local function process(head,first,last) + if first ~= last then + local current = first + while current do + local char, id = ischar(current) + if char then + local scriptstatus = getattr(current,a_scriptstatus) + if scriptstatus and scriptstatus > 0 then + local category = numbertocategory[scriptstatus] + if category then + local injector = injectors[category] + if injector then + head, current = injector(head,current) + end + end + end + end + if current == last then + break + else + current = getnext(current) + end + end + end +end + +scripts.installmethod { + name = "tibetan", + injector = process, + datasets = { + default = { + inter_character_space_factor = 1, + inter_character_stretch_factor = 1, + inter_character_shrink_factor = 1, + }, + half = { + inter_character_space_factor = 0.5, + inter_character_stretch_factor = 0.5, + inter_character_shrink_factor = 0.5, + }, + quarter = { + inter_character_space_factor = 0.25, + inter_character_stretch_factor = 0.25, + inter_character_shrink_factor = 0.25, + }, + }, +} diff --git a/tex/context/base/mkiv/sort-ini.lua b/tex/context/base/mkiv/sort-ini.lua index f90b70be5..0916337b1 100644 --- a/tex/context/base/mkiv/sort-ini.lua +++ b/tex/context/base/mkiv/sort-ini.lua @@ -401,8 +401,10 @@ local function basic(a,b) -- trace ea and eb -- hashed (shared) entries return 0 end - local ea, eb = a.split, b.split - local na, nb = #ea, #eb + local ea = a.split + local eb = b.split + local na = #ea + local nb = #eb if na == 0 and nb == 0 then -- simple variant (single word) local result = 0 @@ -414,7 +416,8 @@ local function basic(a,b) -- trace ea and eb end end if result == 0 then - local la, lb = #ea.uc, #eb.uc + local la = #ea.uc + local lb = #eb.uc if la > lb then return 1 elseif lb > la then @@ -429,7 +432,8 @@ local function basic(a,b) -- trace ea and eb -- complex variant, used in register (multiple words) local result = 0 for i=1,nb < na and nb or na do - local eai, ebi = ea[i], eb[i] + local eai = ea[i] + local ebi = eb[i] for j=1,#sequence do local m = sequence[j] result = basicsort(eai[m],ebi[m]) @@ -438,7 +442,8 @@ local function basic(a,b) -- trace ea and eb end end if result == 0 then - local la, lb = #eai.uc, #ebi.uc + local la = #eai.uc + local lb = #ebi.uc if la > lb then return 1 elseif lb > la then @@ -586,8 +591,18 @@ function splitters.utf(str,checked) -- we could append m and u but this is clean -- end -- end end - local m_case, z_case, p_case, m_mapping, z_mapping, p_mapping, char, byte, n = { }, { }, { }, { }, { }, { }, { }, { }, 0 - local nm, nz, np = 0, 0, 0 + local m_case = { } + local z_case = { } + local p_case = { } + local m_mapping = { } + local z_mapping = { } + local p_mapping = { } + local char = { } + local byte = { } + local n = 0 + local nm = 0 + local nz = 0 + local np = 0 for sc in utfcharacters(str) do local b = utfbyte(sc) if b >= digitsoffset then diff --git a/tex/context/base/mkiv/sort-lan.lua b/tex/context/base/mkiv/sort-lan.lua index 1aa173d1b..b27798966 100644 --- a/tex/context/base/mkiv/sort-lan.lua +++ b/tex/context/base/mkiv/sort-lan.lua @@ -71,16 +71,22 @@ definitions['fr'] = { parent = 'default' } -- DIN 5007-1 -definitions['DIN 5007-1'] = { parent = 'default' } +definitions['DIN 5007-1'] = { + parent = 'default', + replacements = { + { "ß", "ss" }, + }, +} -- DIN 5007-2 definitions['DIN 5007-2'] = { parent = 'default', replacements = { - { "ä", 'ae' }, { "Ä", 'Ae' }, - { "ö", 'oe' }, { "Ö", 'Oe' }, - { "ü", 'ue' }, { "Ü", 'Ue' }, + { "ä", "ae" }, { "Ä", "Ae" }, + { "ö", "oe" }, { "Ö", "Oe" }, + { "ü", "ue" }, { "Ü", "Ue" }, + { "ß", "ss" }, }, } @@ -88,7 +94,9 @@ definitions['DIN 5007-2'] = { definitions['Duden'] = { parent = 'default', - replacements = { { "ß", 's' } }, + replacements = { + { "ß", "s" }, + }, } -- definitions['de'] = { parent = 'default' } -- new german @@ -126,7 +134,7 @@ definitions['de-AT'] = { }, } --- finish (by Wolfgang Schuster) +-- finnish (by Wolfgang Schuster) definitions['fi'] = { entries = { @@ -897,22 +905,24 @@ definitions["hu"] = { }, } ---- Estonian +-- Estonian definitions["et"] = { - entries = { -- w x y are used for foreign words only - ["a"] = "a", ["b"] = "b", ["d"] = "d", ["e"] = "e", ["f"] = "f", - ["g"] = "g", ["h"] = "h", ["i"] = "i", ["j"] = "j", ["k"] = "k", - ["l"] = "l", ["m"] = "m", ["n"] = "n", ["o"] = "o", ["p"] = "p", - ["r"] = "r", ["s"] = "s", ["š"] = "š", ["z"] = "z", ["ž"] = "ž", - ["t"] = "t", ["u"] = "u", ["v"] = "v", ["w"] = "v", ["õ"] = "õ", - ["ä"] = "ä", ["ö"] = "ö", ["ü"] = "ü", ["x"] = "x", ["y"] = "y", + entries = { -- f š z ž are used in estonian words of foreign origin, c č q w x y are used for foreign words only + ["a"] = "a", ["b"] = "b", ["c"] = "c", ["č"] = "č", ["d"] = "d", + ["e"] = "e", ["f"] = "f", ["g"] = "g", ["h"] = "h", ["i"] = "i", + ["j"] = "j", ["k"] = "k", ["l"] = "l", ["m"] = "m", ["n"] = "n", + ["o"] = "o", ["p"] = "p", ["q"] = "q", ["r"] = "r", ["s"] = "s", + ["š"] = "š", ["z"] = "z", ["ž"] = "ž", ["t"] = "t", ["u"] = "u", + ["v"] = "v", ["w"] = "w", ["õ"] = "õ", ["ä"] = "ä", ["ö"] = "ö", + ["ü"] = "ü", ["x"] = "x", ["y"] = "y", }, orders = { - "a", "b", "d", "e", "f", "g", "h", "i", "j", "k", - "l", "m", "n", "o", "p", "r", "s", "š", "z", "ž", - "t", "u", "v", "w", "õ", "ä", "ö", "ü", "x", "y", - } + "a", "b", "c", "č", "d", "e", "f", "g", "h", "i", + "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", + "š", "z", "ž", "t", "u", "v", "w", "õ", "ä", "ö", + "ü", "x", "y", + }, } --- Korean diff --git a/tex/context/base/mkiv/spac-adj.lua b/tex/context/base/mkiv/spac-adj.lua deleted file mode 100644 index 3db59881b..000000000 --- a/tex/context/base/mkiv/spac-adj.lua +++ /dev/null @@ -1,67 +0,0 @@ -if not modules then modules = { } end modules ['spac-adj'] = { - version = 1.001, - comment = "companion to spac-adj.mkiv", - author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright = "PRAGMA ADE / ConTeXt Development Team", - license = "see context related readme files" -} - --- sort of obsolete code - -local a_vadjust = attributes.private('graphicvadjust') - -local nodecodes = nodes.nodecodes - -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist - -local remove_node = nodes.remove -local hpack_node = node.hpack - -local enableaction = nodes.tasks.enableaction - -function nodes.handlers.graphicvadjust(head,groupcode) -- we can make an actionchain for mvl only - if groupcode == "" then -- mvl only - local h, p, done = head, nil, false - while h do - local id = h.id - if id == hlist_code or id == vlist_code then - local a = h[a_vadjust] - if a then - if p then - local n - head, h, n = remove_node(head,h) - local pl = p.list - if n.width ~= 0 then - n = hpack_node(n,0,'exactly') -- todo: dir - end - if pl then - pl.prev = n - n.next = pl - end - p.list = n - done = true - else - -- can't happen - end - else - p = h - h = h.next - end - else - h = h.next - end - end - return head, done - else - return head, false - end -end - -interfaces.implement { - name = "enablegraphicvadjust", - onlyonce = true, - actions = function() - enableaction("finalizers","nodes.handlers.graphicvadjust") - end -} diff --git a/tex/context/base/mkiv/spac-adj.mkiv b/tex/context/base/mkiv/spac-adj.mkiv deleted file mode 100644 index d29d15c17..000000000 --- a/tex/context/base/mkiv/spac-adj.mkiv +++ /dev/null @@ -1,51 +0,0 @@ -%D \module -%D [ file=spac-adj, % moved from spac-par.mkiv -%D version=2009.10.16, % 1997.03.31, was core-spa.tex -%D title=\CONTEXT\ Spacing Macros, -%D subtitle=Paragraphs, -%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 Spacing Macros / Adjustments} - -\unprotect - -% Very nasty but needed for margin stuff inside colored -% paragraphs. Obsolete for while . - -\registerctxluafile{spac-adj}{} - -\definesystemattribute [graphicvadjust] [public] - -\unexpanded\def\enablegraphicvadjust - {\writestatus\m!system{graphicvadjusting is no longer needed!} - \clf_enablegraphicvadjust %once anyway - \glet\enablegraphicvadjust\relax} - -\unexpanded\def\graphicvadjust % currently not enabled ... nasty bidi handling - {\clf_enablegraphicvadjust % and probably no longer needed anyway - \dowithnextboxcontentcs\forgetall\spac_vadjust_graphic_finish\vbox} - -\def\spac_vadjust_graphic_finish - {\vadjust - {\vbox attr \graphicvadjustattribute \plusone - {\unvbox\nextbox - % corrects for one line paragraphs - \nointerlineskip - \kern-\struttotal - \nointerlineskip - \verticalstrut}}} - -\unexpanded\def\fakedvadjust - {\dowithnextboxcs\spac_vadjust_faked_finish\vtop} - -\def\spac_vadjust_faked_finish - {\setbox\nextbox\hpack{\llap{\lower\strutdepth\box\nextbox}}% - \smashedbox\nextbox} - -\protect \endinput diff --git a/tex/context/base/mkiv/spac-ali.lua b/tex/context/base/mkiv/spac-ali.lua index 640478d34..b58040ac7 100644 --- a/tex/context/base/mkiv/spac-ali.lua +++ b/tex/context/base/mkiv/spac-ali.lua @@ -38,7 +38,8 @@ local listcodes = nodes.listcodes local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local line_code = listcodes.line + +local linelist_code = listcodes.line local new_stretch = nodepool.stretch @@ -63,13 +64,12 @@ local nofrealigned = 0 -- raggedright 0 0 fil -- raggedcenter 0 + 0 + - -local function handler(head,leftpage,realpageno) +local function handler(head,leftpage,realpageno) -- traverse_list local current = head - local done = false while current do local id = getid(current) if id == hlist_code then - if getsubtype(current) == line_code then + if getsubtype(current) == linelist_code then local a = takeattr(current,a_realign) if not a or a == 0 then -- skip @@ -102,7 +102,6 @@ local function handler(head,leftpage,realpageno) elseif trace_realign then report_realign("invalid flushing, align %a, page %a, realpage %a",align,pageno,realpageno) end - done = true nofrealigned = nofrealigned + 1 end end @@ -113,14 +112,11 @@ local function handler(head,leftpage,realpageno) end current = getnext(current) end - return head, done + return head end function alignments.handler(head) - local leftpage = isleftpage() - local realpageno = texgetcount("realpageno") - local head, done = handler(tonut(head),leftpage,realpageno) - return tonode(head), done + return handler(head,isleftpage(),texgetcount("realpageno")) end local enabled = false diff --git a/tex/context/base/mkiv/spac-ali.mkiv b/tex/context/base/mkiv/spac-ali.mkiv index fbcf45caa..4362ff250 100644 --- a/tex/context/base/mkiv/spac-ali.mkiv +++ b/tex/context/base/mkiv/spac-ali.mkiv @@ -27,7 +27,7 @@ % % but that also means myoption gets frozen due to caching. -\registerctxluafile{spac-ali}{} +\registerctxluafile{spac-ali}{optimize} \definesystemattribute[realign] [public] % might be combined with the next one \definesystemattribute[alignstate][public] % will make a single attributes for several states @@ -61,16 +61,6 @@ \newtoks\everyresetalign % todo -%D We will not use bodydir and pagedir so we disable them. That way we get -%D normal hyperlink support. We back on it (too hard to fake \type {\the}). - -\unexpanded\def\syst_fatal_dir_error#1% - {\writestatus{fatal error}{\string#1\space is forbidden}% - \wait} - -\def\pagedir {\syst_fatal_dir_error\pagedir} \let\normalpagedir\pagedir -\def\bodydir {\syst_fatal_dir_error\bodydir} \let\normalbodydir\bodydir - % This will become a more advanced layout controller soon: \newconditional\layoutlefttoright \settrue\layoutlefttoright @@ -94,63 +84,23 @@ \unexpanded\def\spac_directions_lefttoright_vmode {\settrue\displaylefttoright \settrue\inlinelefttoright - \textdir TLT\relax - \pardir TLT\relax} + \textdirection\directionlefttoright + \pardirection \directionlefttoright} \unexpanded\def\spac_directions_righttoleft_vmode {\setfalse\displaylefttoright \setfalse\inlinelefttoright - \textdir TRT\relax - \pardir TRT\relax} - -% % keep this as reference -% -% \unexpanded\def\spac_directions_lefttoright_hmode -% {\textdir TLT\relax -% \settrue\inlinelefttoright} -% -% \unexpanded\def\spac_directions_righttoleft_hmode -% {\textdir TRT\relax -% \setfalse\inlinelefttoright} -% -% \unexpanded\def\spac_directions_lefttoright_hmode -% {\ifzeropt\lastskip -% \textdir TLT\relax -% \else -% \scratchskip\lastskip -% \unskip -% \textdir TLT\relax -% \hskip\scratchskip -% \fi -% \settrue\inlinelefttoright} -% -% \unexpanded\def\spac_directions_righttoleft_hmode -% {\ifzeropt\lastskip -% \textdir TRT\relax -% \else -% \scratchskip\lastskip -% \unskip -% \textdir TRT\relax -% \hskip\scratchskip -% \fi -% \setfalse\inlinelefttoright} + \textdirection\directionrighttoleft + \pardirection \directionrighttoleft} \unexpanded\def\spac_directions_lefttoright_hmode - {\linedir TLT\relax % linedir keeps subtype of skip + {\linedirection\directionlefttoright % linedir keeps subtype of skip \settrue\inlinelefttoright} \unexpanded\def\spac_directions_righttoleft_hmode - {\linedir TRT\relax % linedir keeps subtype of skip + {\linedirection\directionrighttoleft % linedir keeps subtype of skip \setfalse\inlinelefttoright} -% \def\currentdirectionparameters -% {\ifconditional\inlinelefttoright \else -% idir {r2l}% -% \fi -% \ifconditional\displaylefttoright \else -% ddir {r2l}% -% \fi} - \unexpanded\def\synchronizelayoutdirection {\ifconditional\layoutlefttoright \spac_directions_synchronize_lr @@ -167,16 +117,17 @@ \def\spac_directions_synchronize_lr {\settrue\inlinelefttoright - \textdir TLT\relax - \pardir TLT\relax} + \textdirection\directionlefttoright + \pardirection \directionlefttoright} \def\spac_directions_synchronize_rl {\setfalse\inlinelefttoright - \textdir TRT\relax - \pardir TRT\relax} + \textdirection\directionrighttoleft + \pardirection \directionrighttoleft} \unexpanded\def\synchronizeinlinedirection - {\textdir T\ifconditional\inlinelefttoright L\else R\fi T\relax} + {% why not \linedirection here + \textdirection\ifconditional\inlinelefttoright\directionlefttoright\else\directionrighttoleft\fi} \unexpanded\def\checkedlefttoright {\ifvmode @@ -210,49 +161,20 @@ \unexpanded\def\usebidiparameter#1% {\begincsname\??bidi#1\c!bidi\endcsname} -% maybe some day: -% -% \newcount\postdirpenalty % \zerocount -% \newcount\predirpenalty % \zerocount -% -% \def\spac_directions_post_break -% {\ifhmode -% \removeunwantedspaces -% \penalty\postdirpenalty -% \fi} -% -% \def\spac_directions_pre_break -% {\ifhmode -% \penalty\predirpenalty -% \ignorespaces -% \fi} -% -% \unexpanded\def\spac_directions_lefttoright_hmode -% {\settrue\inlinelefttoright -% \textdir TLT\relax -% \aftergroup\spac_directions_post_break -% \spac_directions_pre_break} -% -% \unexpanded\def\spac_directions_righttoleft_hmode -% {\textdir TRT\relax -% \setfalse\inlinelefttoright -% \aftergroup\spac_directions_post_break -% \spac_directions_pre_break} - \unexpanded\def\showdirections {\dontleavehmode - \begingroup\infofont\textdir TLT[\space - layout:\ifconditional \layoutlefttoright l2r\else r2l\fi\space - display:\ifconditional\displaylefttoright l2r\else r2l\fi\space - inline:\ifconditional \inlinelefttoright l2r\else r2l\fi\space + \begingroup\infofont\textdirection\directionlefttoright[\space + layout: \ifconditional\layoutlefttoright l2r\else r2l\fi\space + display: \ifconditional\displaylefttoright l2r\else r2l\fi\space + inline: \ifconditional\inlinelefttoright l2r\else r2l\fi\space ]\endgroup} -\unexpanded\def\righttolefthbox#1#{\normalhbox dir TRT #1\bgroup\righttoleft\let\next} \let\rtlhbox\righttolefthbox -\unexpanded\def\lefttorighthbox#1#{\normalhbox dir TLT #1\bgroup\lefttoright\let\next} \let\ltrhbox\lefttorighthbox -\unexpanded\def\righttoleftvbox#1#{\normalvbox dir TRT #1\bgroup\righttoleft\let\next} \let\rtlvbox\righttoleftvbox -\unexpanded\def\lefttorightvbox#1#{\normalvbox dir TLT #1\bgroup\lefttoright\let\next} \let\ltrvbox\lefttorightvbox -\unexpanded\def\righttoleftvtop#1#{\normalvtop dir TRT #1\bgroup\righttoleft\let\next} \let\rtlvtop\righttoleftvtop -\unexpanded\def\lefttorightvtop#1#{\normalvtop dir TLT #1\bgroup\lefttoright\let\next} \let\ltrvtop\lefttorightvtop +\unexpanded\def\righttolefthbox#1#{\reversehbox#1\bgroup\righttoleft\let\next} \let\rtlhbox\righttolefthbox +\unexpanded\def\lefttorighthbox#1#{\naturalhbox#1\bgroup\lefttoright\let\next} \let\ltrhbox\lefttorighthbox +\unexpanded\def\righttoleftvbox#1#{\reversevbox#1\bgroup\righttoleft\let\next} \let\rtlvbox\righttoleftvbox +\unexpanded\def\lefttorightvbox#1#{\naturalvbox#1\bgroup\lefttoright\let\next} \let\ltrvbox\lefttorightvbox +\unexpanded\def\righttoleftvtop#1#{\reversevtop#1\bgroup\righttoleft\let\next} \let\rtlvtop\righttoleftvtop +\unexpanded\def\lefttorightvtop#1#{\naturalvtop#1\bgroup\lefttoright\let\next} \let\ltrvtop\lefttorightvtop \unexpanded\def\autodirhbox#1#{\hbox#1\bgroup\synchronizeinlinedirection\let\next} \unexpanded\def\autodirvbox#1#{\vbox#1\bgroup\synchronizeinlinedirection\let\next} % maybe also pardir or maybe just a \vbox @@ -355,7 +277,8 @@ \newconstant\c_spac_align_state_par_fill \def\v_spac_align_fill_amount {\plusone fil} -\def\v_spac_align_fill_amount_hard {\plusone fill} +\def\v_spac_align_fill_amount_hard {\plusone fill} +\def\v_spac_align_fill_amount_extreme {\plustenthousand filll} \def\v_spac_align_fill_amount_negative {\minusone fil} \def\v_spac_align_fill_amount_double {\plustwo fil} \def\v_spac_align_fill_amount_space {\plustwo fil} % can be added to xspace if we have a key @@ -479,7 +402,8 @@ \spaceskip \zeropoint\relax \xspaceskip \zeropoint\relax \parfillskip \zeropoint - \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_hard\relax + \parfillleftskip\zeropoint\s!plus\v_spac_align_fill_amount_extreme\relax + \parfillleftmode\plustwo % \plusone checks for multiple lines \parindent \zeropoint \relax} @@ -643,8 +567,8 @@ }}% kept, nice for tracing \edef\raggedcommand {\the\t_spac_align_collected }% \edef\updateraggedskips{\spac_align_flush_horizontal}% - \global\expandafter\let\csname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand - \global\expandafter\let\csname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips} + \expandafter\glet\csname\??alignmentnormalcache\m_spac_align_asked\endcsname\raggedcommand + \expandafter\glet\csname\??alignmentraggedcache\m_spac_align_asked\endcsname\updateraggedskips} \def\spac_align_collect#1% {\csname\??aligncommand#1\endcsname} diff --git a/tex/context/base/mkiv/spac-chr.lua b/tex/context/base/mkiv/spac-chr.lua index 0fa639f92..23cf9741b 100644 --- a/tex/context/base/mkiv/spac-chr.lua +++ b/tex/context/base/mkiv/spac-chr.lua @@ -27,9 +27,6 @@ local nodes, node = nodes, node local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut - local getnext = nuts.getnext local getprev = nuts.getprev local getattr = nuts.getattr @@ -38,7 +35,6 @@ local getlang = nuts.getlang local setchar = nuts.setchar local setattrlist = nuts.setattrlist local getfont = nuts.getfont -local getchar = nuts.getchar local setsubtype = nuts.setsubtype local setdisc = nuts.setdisc local isglyph = nuts.isglyph @@ -48,13 +44,13 @@ local setcolor = nodes.tracers.colors.set local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local remove_node = nuts.remove -local traverse_id = nuts.traverse_id -local traverse_char = nuts.traverse_char +----- traverse_id = nuts.traverse_id +----- traverse_char = nuts.traverse_char +local nextchar = nuts.traversers.char +local nextglyph = nuts.traversers.glyph local copy_node = nuts.copy -local tasks = nodes.tasks - local nodepool = nuts.pool local new_penalty = nodepool.penalty local new_glue = nodepool.glue @@ -63,12 +59,10 @@ local new_rule = nodepool.rule local new_disc = nodepool.disc local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes -local disccodes = nodes.disccodes +local gluecodes = nodes.gluecodes local glyph_code = nodecodes.glyph -local space_skip_code = skipcodes.spaceskip -local explicit_code = disccodes.explicit +local spaceskip_code = gluecodes.spaceskip local chardata = characters.data local is_punctuation = characters.is_punctuation @@ -101,8 +95,7 @@ local function inject_quad_space(unicode,head,current,fraction) setattrlist(glue,current) setattrlist(current) -- why reset all setattr(glue,a_character,unicode) - head, current = insert_node_after(head,current,glue) - return head, current + return insert_node_after(head,current,glue) end local function inject_char_space(unicode,head,current,parent) @@ -112,8 +105,7 @@ local function inject_char_space(unicode,head,current,parent) setattrlist(glue,current) setattrlist(current) -- why reset all setattr(glue,a_character,unicode) - head, current = insert_node_after(head,current,glue) - return head, current + return insert_node_after(head,current,glue) end local function inject_nobreak_space(unicode,head,current,space,spacestretch,spaceshrink) @@ -132,18 +124,17 @@ local function inject_nobreak_space(unicode,head,current,space,spacestretch,spac head, current = insert_node_after(head,current,kern) head, current = insert_node_after(head,current,penalty) end - head, current = insert_node_after(head,current,glue) - return head, current + return insert_node_after(head,current,glue) end local function nbsp(head,current) local para = fontparameters[getfont(current)] if getattr(current,a_alignstate) == 1 then -- flushright head, current = inject_nobreak_space(0x00A0,head,current,para.space,0,0) - setsubtype(current,space_skip_code) + setsubtype(current,spaceskip_code) else head, current = inject_nobreak_space(0x00A0,head,current,para.space,para.spacestretch,para.spaceshrink) - setsubtype(current,space_skip_code) + setsubtype(current,spaceskip_code) end return head, current end @@ -152,27 +143,13 @@ end function characters.replacenbsp(head,original) local head, current = nbsp(head,original) - head = remove_node(head,original,true) - return head, current + return remove_node(head,original,true) end --- function characters.replacenbspaces(head) --- for current in traverse_id(glyph_code,head) do --- if getchar(current) == 0x00A0 then --- local h = nbsp(head,current) --- if h then --- head = remove_node(h,current,true) --- end --- end --- end --- return head --- end - function characters.replacenbspaces(head) - local head = tonut(head) local wipe = false - for current in traverse_id(glyph_code,head) do -- can be anytiem so no traverse_char - if getchar(current) == 0x00A0 then + for current, char, font in nextglyph, head do -- can be anytime so no traverse_char + if char == 0x00A0 then if wipe then head = remove_node(h,current,true) wipe = false @@ -184,15 +161,16 @@ function characters.replacenbspaces(head) end end if wipe then - head = remove_node(h,current,true) + head = remove_node(head,current,true) end - return tonode(head) + return head end -- This initialization might move someplace else if we need more of it. The problem is that -- this module depends on fonts so we have an order problem. local nbsphash = { } setmetatableindex(nbsphash,function(t,k) + -- this needs checking ! for i=unicodeblocks.devanagari.first,unicodeblocks.devanagari.last do nbsphash[i] = true end for i=unicodeblocks.kannada .first,unicodeblocks.kannada .last do nbsphash[i] = true end setmetatableindex(nbsphash,nil) @@ -209,11 +187,11 @@ local methods = { [0x001F] = function(head,current) -- kind of special local next = getnext(current) if next then - local char = isglyph(next) + local char, font = isglyph(next) if char then head, current = remove_node(head,current,true) if not is_punctuation[char] then - local p = fontparameters[getfont(next)] + local p = fontparameters[font] head, current = insert_node_before(head,current,new_glue(p.space,p.space_stretch,p.space_shrink)) end end @@ -319,9 +297,7 @@ local methods = { characters.methods = methods -- function characters.handler(head) -- todo: use traverse_id --- head = tonut(head) -- local current = head --- local done = false -- while current do -- local char, id = isglyph(current) -- if char then @@ -335,47 +311,39 @@ characters.methods = methods -- if h then -- head = remove_node(h,current,true) -- end --- done = true -- end -- current = next -- else -- current = getnext(current) -- end -- end --- return tonode(head), done +-- return head -- end --- for current, char, font in traverse_char_data(head) will save 0.015 on a 300 page doc - -- this also works ok in math as we run over glyphs and these stay glyphs ... not sure -- about scripts and such but that is not important anyway ... some day we can consider -- special definitions in math function characters.handler(head) - local head = tonut(head) local wipe = false - for current in traverse_char(head) do - local char = getchar(current) - if char then - local method = methods[char] - if method then - if wipe then - head = remove_node(head,wipe,true) - wipe = false - end - if trace_characters then - report_characters("replacing character %C, description %a",char,lower(chardata[char].description)) - end - local h = method(head,current) - if h then - wipe = current - end - done = true + for current, char in nextchar, head do + local method = methods[char] + if method then + if wipe then + head = remove_node(head,wipe,true) + wipe = false + end + if trace_characters then + report_characters("replacing character %C, description %a",char,lower(chardata[char].description)) + end + local h = method(head,current) + if h then + wipe = current end end end if wipe then head = remove_node(head,wipe,true) end - return tonode(head), done + return head end diff --git a/tex/context/base/mkiv/spac-chr.mkiv b/tex/context/base/mkiv/spac-chr.mkiv index ed2cb47f9..23f4ac8dd 100644 --- a/tex/context/base/mkiv/spac-chr.mkiv +++ b/tex/context/base/mkiv/spac-chr.mkiv @@ -15,7 +15,7 @@ \unprotect -\registerctxluafile{spac-chr}{} +\registerctxluafile{spac-chr}{optimize} \definesystemattribute[characters][public] diff --git a/tex/context/base/mkiv/spac-flr.mkiv b/tex/context/base/mkiv/spac-flr.mkiv index 29351a3dd..bd50bfea6 100644 --- a/tex/context/base/mkiv/spac-flr.mkiv +++ b/tex/context/base/mkiv/spac-flr.mkiv @@ -60,6 +60,35 @@ \endgroup \ignorespaces} +% \definefiller +% [MyFiller] +% [offset=.25\emwidth, +% rightmargindistance=-\rightskip, +% method=middle] +% +% \startitemize[packed,joinedup][rightmargin=5em] +% \startitem +% \input sapolsky \fillupto[MyFiller]{RS} +% \stopitem +% \stopitemize + +\unexpanded\def\fillupto + {\dosingleempty\spac_fillers_upto} + +\def\spac_fillers_upto[#1]#2% + {\removeunwantedspaces + \begingroup + \edef\currentfiller{#1}% + \scratchdimen\dimexpr\fillerparameter\c!rightmargindistance\relax + \ifdim\scratchdimen=\zeropoint\else + \parfillskip \scratchdimen\s!plus \plusone\s!fil\relax + \fi + \spac_fillers_indeed[#1]% + \doifsomething{#2}{\hbox{#2}}% + \par + \endgroup + \ignorespaces} + \setvalue{\??filleralternative\s!unknown}% {} @@ -87,8 +116,8 @@ \setvalue{\??filleralternative\v!rule}% {\expandnamespaceparameter\??fillerleadermethod\fillerparameter\c!method\v!local \hrule - \!!height\fillerparameter\c!height - \!!depth \fillerparameter\c!depth + \s!height\fillerparameter\c!height + \s!depth \fillerparameter\c!depth \hfill} \letvalue{\??fillerleadermethod\s!local }\normalleaders % overflow ends up inbetween (current box) @@ -106,6 +135,7 @@ \c!depth=\zeropoint, \c!leftmargin=\zeropoint, \c!rightmargin=\zeropoint, + \c!rightmargindistance=\zeropoint, \c!alternative=\v!symbol, \c!method=\s!local] diff --git a/tex/context/base/mkiv/spac-grd.mkiv b/tex/context/base/mkiv/spac-grd.mkiv index 73c6e0dd1..72d017836 100644 --- a/tex/context/base/mkiv/spac-grd.mkiv +++ b/tex/context/base/mkiv/spac-grd.mkiv @@ -108,8 +108,8 @@ \newbox \b_spac_lines_correction_after \def\spac_lines_initialize_corrections - {\setbox\b_spac_lines_correction_before\hbox{\setstrut\strut}% - \setbox\b_spac_lines_correction_after \hbox{(}% + {\setbox\b_spac_lines_correction_before\hpack{\setstrut\strut}% + \setbox\b_spac_lines_correction_after \hbox {(}% \d_spac_lines_correction_before\dimexpr\ht\b_spac_lines_correction_before-\ht\b_spac_lines_correction_after\relax \d_spac_lines_correction_after \dimexpr\dp\b_spac_lines_correction_before-\dp\b_spac_lines_correction_after\relax \ifdim\d_spac_lines_correction_before<\zeropoint\d_spac_lines_correction_before\zeropoint\fi diff --git a/tex/context/base/mkiv/spac-hor.mkiv b/tex/context/base/mkiv/spac-hor.mkiv index ce747a202..32b7f06fb 100644 --- a/tex/context/base/mkiv/spac-hor.mkiv +++ b/tex/context/base/mkiv/spac-hor.mkiv @@ -17,8 +17,9 @@ \registerctxluafile{spac-hor}{} -\let \parfillrightskip \parfillskip -\newskip\parfillleftskip +\let \parfillrightskip \parfillskip +\newskip \parfillleftskip +\newconstant\parfillleftmode \let\v_spac_indentation_current\empty % amount/keyword @@ -205,6 +206,9 @@ \let\checkindentation\relax +\installmacrostack\checkindentation +\installmacrostack\ifindentation + \def\spac_indentation_remove {\ifdim\parindent=\zeropoint \else \begingroup @@ -218,21 +222,21 @@ \def\spac_indentation_do_toggle_indeed {\global\indentationfalse - \global\let\checkindentation\spac_indentation_no_toggle_indeed + \glet\checkindentation\spac_indentation_no_toggle_indeed \spac_indentation_remove} \def\spac_indentation_no_toggle_indeed {\global\indentationtrue - \global\let\checkindentation\spac_indentation_do_toggle_indeed} + \glet\checkindentation\spac_indentation_do_toggle_indeed} \def\spac_indentation_do_indeed {\global\indentationtrue} \def\spac_indentation_do_toggle - {\global\let\checkindentation\spac_indentation_do_toggle_indeed} + {\glet\checkindentation\spac_indentation_do_toggle_indeed} \def\spac_indentation_no_toggle - {\global\let\checkindentation\spac_indentation_no_toggle_indeed} + {\glet\checkindentation\spac_indentation_no_toggle_indeed} \def\spac_indentation_check_toggle {\ifcase\c_spac_indentation_toggle_state @@ -244,22 +248,22 @@ \fi} \def\spac_indentation_variant_yes - {\global\let\checkindentation\spac_indentation_do_indeed} + {\glet\checkindentation\spac_indentation_do_indeed} \def\spac_indentation_no_next_check {\spac_indentation_remove - \global\let\checkindentation\spac_indentation_do_indeed} + \glet\checkindentation\spac_indentation_do_indeed} \def\spac_indentation_variant_no % made global {\ifinpagebody \else \global\indentationfalse - \global\let\checkindentation\spac_indentation_no_next_check + \glet\checkindentation\spac_indentation_no_next_check \fi} \def\nonoindentation % bv bij floats {\ifinpagebody \else \global\indentationtrue - \global\let\checkindentation\spac_indentation_do_indeed + \glet\checkindentation\spac_indentation_do_indeed \fi} \def\spac_indentation_variant_force @@ -271,13 +275,13 @@ \fi \fi} \appendtoks - \pushmacro\checkindentation - \pushmacro\ifindentation + \push_macro_checkindentation + \push_macro_ifindentation \to \everypushsomestate \appendtoks - \popmacro\ifindentation - \popmacro\checkindentation + \pop_macro_ifindentation + \pop_macro_checkindentation \to \everypopsomestate % public: @@ -287,16 +291,16 @@ \let\doindentation\spac_indentation_variant_yes % public \def\dontrechecknextindentation % public (in macros) - {\global\let\dorechecknextindentation\relax} + {\glet\dorechecknextindentation\relax} \let\dorechecknextindentation\relax % public (in macros) \unexpanded\def\spac_indentation_check_next_indentation - {\global\let\dorechecknextindentation\relax + {\glet\dorechecknextindentation\relax \doifelsenextchar\par\donothing\spac_indentation_variant_no} % messy check as next is seldom \par \def\spac_indentation_variant_auto - {\global\let\dorechecknextindentation\spac_indentation_check_next_indentation} + {\glet\dorechecknextindentation\spac_indentation_check_next_indentation} %D This one sets up the local indentation behaviour (i.e. either or not %D a next paragraph will be indented). @@ -564,6 +568,13 @@ \fi \fi} +\unexpanded\def\onlynonbreakablespace + {\ifdim\lastskip=\interwordspace + \unskip + \nonbreakablespace + \fi + \ignorespaces} + % \startbuffer % \startlines \tt \fixedspaces % 0~1~~2~~~3~~~~4~~~~~5 @@ -598,12 +609,15 @@ \ifdefined\quad \else - \unexpanded\def\enskip{\hskip.5\emwidth} - \unexpanded\def\quad {\hskip \emwidth} - \unexpanded\def\qquad {\hskip 2\emwidth} + \unexpanded\def\enskip{\hskip.5\emwidth\relax} + \unexpanded\def\quad {\hskip \emwidth\relax} + \unexpanded\def\qquad {\hskip 2\emwidth\relax} \fi +\unexpanded\def\negenspace{\kern-.5\emwidth} +\unexpanded\def\negemspace{\kern- \emwidth} + \let\emspace\quad \unexpanded\def\charspace{ } % the unexpandable \space (as space can also be delimiter for numbers) @@ -1116,6 +1130,8 @@ \unexpanded\def\spac_spaces_checked_normal {\mathortext\normalspace{\dontleavehmode\normalspace}}% \unexpanded\def\spac_spaces_checked_fixed {\mathortext\normalspace{\dontleavehmode\fixedspace}}% +% hm, order matters when we \let in \obeyspaces + \installspacemethod \v!on {\obeyspaces \let\obeyedspace\spac_spaces_checked_control diff --git a/tex/context/base/mkiv/spac-lin.mkiv b/tex/context/base/mkiv/spac-lin.mkiv index 6558cb111..d862f6d81 100644 --- a/tex/context/base/mkiv/spac-lin.mkiv +++ b/tex/context/base/mkiv/spac-lin.mkiv @@ -86,7 +86,7 @@ \let\spac_lines_break\relax \fi \linesparameter\c!before - \pushmacro\checkindentation + \push_macro_checkindentation \whitespace \dostarttaggedchained\t!lines\currentlines\??lines \begingroup @@ -126,7 +126,7 @@ {\dostoptagged \endgroup \dostoptagged - \popmacro\checkindentation + \pop_macro_checkindentation \linesparameter\c!after \egroup} diff --git a/tex/context/base/mkiv/spac-pag.mkiv b/tex/context/base/mkiv/spac-pag.mkiv index c7d22f0e0..9adc591ed 100644 --- a/tex/context/base/mkiv/spac-pag.mkiv +++ b/tex/context/base/mkiv/spac-pag.mkiv @@ -151,6 +151,7 @@ \unexpanded\def\signalrightpage {\dotrackpagestate \s!paragraph\nofraggedparagraphs} % use \dontleavehmode if needed \unexpanded\def\doifelserightpage{\doifelserightpagestate\s!paragraph\nofraggedparagraphs} +\unexpanded\def\rightpageorder {\pagestaterealpageorder\s!paragraph\nofraggedparagraphs} \let\doifrightpageelse\doifelserightpage @@ -169,9 +170,9 @@ \fi \ifpagechanged \letgvalue{\??pagechanges#2:#1}\m_spac_pagestates_realpage - \globallet\lastchangedpage\m_spac_pagestates_realpage + \glet\lastchangedpage\m_spac_pagestates_realpage \else - \globallet\lastchangedpage\realfolio + \glet\lastchangedpage\realfolio \fi} \def\changedpagestate#1#2% diff --git a/tex/context/base/mkiv/spac-par.mkiv b/tex/context/base/mkiv/spac-par.mkiv index 4dd3db243..0932b7359 100644 --- a/tex/context/base/mkiv/spac-par.mkiv +++ b/tex/context/base/mkiv/spac-par.mkiv @@ -79,17 +79,17 @@ \setvalue{\??paragraphintro\v!first}#1% {\global\settrue\c_spac_paragraphs_intro_first - \global\t_spac_paragraphs_intro_first\expandafter{\the\t_spac_paragraphs_intro_first#1}% + \gtoksapp\t_spac_paragraphs_intro_first{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} \setvalue{\??paragraphintro\v!next}#1% {\global\settrue\c_spac_paragraphs_intro_next - \global\t_spac_paragraphs_intro_next\expandafter{\the\t_spac_paragraphs_intro_next#1}% + \gtoksapp\t_spac_paragraphs_intro_next{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} \setvalue{\??paragraphintro\v!each}#1% {\global\settrue\c_spac_paragraphs_intro_each - \global\t_spac_paragraphs_intro_each\expandafter{\the\t_spac_paragraphs_intro_each#1}% + \gtoksapp\t_spac_paragraphs_intro_each{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} %D We can say: @@ -130,7 +130,7 @@ \unexpanded\def\flushatparagraph#1% {\global\c_spac_paragraphs_intro_first\plusone - \global\t_spac_paragraphs_intro_first\expandafter{\the\t_spac_paragraphs_intro_first#1}% + \gtoksapp\t_spac_paragraphs_intro_first{#1}% \glet\insertparagraphintro\spac_paragraphs_flush_intro} %D Here comes the flusher (we misuse the one level expansion of token @@ -221,19 +221,19 @@ \dowithnextboxcs\spac_postponed_data_finish\hbox} \def\spac_postponed_data_finish - {\global\setbox\b_spac_postponed_data\hbox % to\zeropoint + {\global\setbox\b_spac_postponed_data\hpack % to\zeropoint {\box\b_spac_postponed_data\box\nextbox}% \endgroup} \def\spac_postponed_data_flush {%\iftrialtypesetting \else \ifvoid\b_spac_postponed_data\else - \hbox{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data + \hpack{\smashedbox\b_spac_postponed_data}% \box\b_spac_postponed_data \fi \glet\flushpostponednodedata\relax }%\fi} -\unexpanded\def\doflushatpar +\unexpanded\def\doflushatpar % might be renamed {\ifvmode \expandafter\flushatnextpar \else diff --git a/tex/context/base/mkiv/spac-prf.lua b/tex/context/base/mkiv/spac-prf.lua index a28f30593..32582c56f 100644 --- a/tex/context/base/mkiv/spac-prf.lua +++ b/tex/context/base/mkiv/spac-prf.lua @@ -17,6 +17,7 @@ local formatters = string.formatters local nodecodes = nodes.nodecodes local gluecodes = nodes.gluecodes local listcodes = nodes.listcodes +local leadercodes = nodes.leadercodes local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc @@ -30,10 +31,12 @@ local math_code = nodecodes.math local rule_code = nodecodes.rule local marginkern_code = nodecodes.marginkern -local leaders_code = gluecodes.leaders +local leaders_code = leadercodes.leaders + local lineskip_code = gluecodes.lineskip local baselineskip_code = gluecodes.baselineskip -local line_code = listcodes.line + +local linelist_code = listcodes.line local texlists = tex.lists local settexattribute = tex.setattribute @@ -128,6 +131,9 @@ local function getprofile(line,step) local margin = step / 4 local min = 0 local max = ceiling(getwidth(line)/step) + 1 + local wd = 0 + local ht = 0 + local dp = 0 for i=min,max do heights[i] = 0 @@ -136,8 +142,6 @@ local function getprofile(line,step) -- remember p - local wd, ht, dp = 0, 0, 0 - local function progress() position = width width = position + wd @@ -639,7 +643,7 @@ end local function profilelist(line,mvl) - local current = tonut(line) + local current = line local top = nil local bot = nil @@ -668,7 +672,7 @@ local function profilelist(line,mvl) local id = getid(current) if id == hlist_code then local subtype = getsubtype(current) - if subtype == line_code then + if subtype == linelist_code then t_profile = hasprofile(current) if t_profile then top = current @@ -710,7 +714,7 @@ local function profilelist(line,mvl) if id == hlist_code then -- check subtype local subtype = getsubtype(current) - if subtype == line_code then + if subtype == linelist_code then if top == current then -- skip bot = nil -- to be sure @@ -819,7 +823,7 @@ function profiling.profilebox(specification) local id = getid(current) if id == hlist_code then local subtype = getsubtype(current) - if subtype == line_code then + if subtype == linelist_code then if top then bot = current b_profile = setprofile(bot) @@ -899,9 +903,8 @@ end -- -- function profiling.vboxhandler(head,where) -- if head and not ignore[where] then --- local h = tonut(head) --- if getnext(h) then --- profilelist(h) +-- if getnext(head) then +-- profilelist(head) -- end -- end -- return head @@ -911,7 +914,7 @@ function profiling.pagehandler(head) if head then profilelist(head,true) end - return head, true + return head end interfaces.implement { diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua index 969a195e1..b55f1ca7c 100644 --- a/tex/context/base/mkiv/spac-ver.lua +++ b/tex/context/base/mkiv/spac-ver.lua @@ -116,8 +116,8 @@ local a_snapmethod = attributes.private('snapmethod') local a_snapvbox = attributes.private('snapvbox') local nuts = nodes.nuts -local tonode = nuts.tonode local tonut = nuts.tonut +local tonode = nuts.tonode local getnext = nuts.getnext local setlink = nuts.setlink @@ -147,15 +147,16 @@ local getdepth = nuts.getdepth local find_node_tail = nuts.tail local flush_node = nuts.flush_node -local traverse_nodes = nuts.traverse -local traverse_nodes_id = nuts.traverse_id local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local remove_node = nuts.remove local count_nodes = nuts.countall local hpack_node = nuts.hpack local vpack_node = nuts.vpack ------ writable_spec = nuts.writable_spec + +local nextnode = nuts.traversers.node +local nexthlist = nuts.traversers.hlist + local nodereference = nuts.reference local theprop = nuts.theprop @@ -170,8 +171,9 @@ local new_kern = nodepool.kern local new_rule = nodepool.rule local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes -local penaltycodes = nodes.penaltycodes +local gluecodes = nodes.gluecodes +----- penaltycodes = nodes.penaltycodes +----- listcodes = nodes.listcodes local penalty_code = nodecodes.penalty local kern_code = nodecodes.kern @@ -179,21 +181,22 @@ local glue_code = nodecodes.glue local insert_code = nodecodes.ins local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist +local rule_code = nodecodes.rule local localpar_code = nodecodes.localpar -local linebreak_code = penaltycodes.linebreakpenalty +local userskip_code = gluecodes.userskip +local lineskip_code = gluecodes.lineskip +local baselineskip_code = gluecodes.baselineskip +local parskip_code = gluecodes.parskip +local topskip_code = gluecodes.topskip +local splittopskip_code = gluecodes.splittopskip -local userskip_code = skipcodes.userskip -local lineskip_code = skipcodes.lineskip -local baselineskip_code = skipcodes.baselineskip -local parskip_code = skipcodes.parskip -local topskip_code = skipcodes.topskip -local splittopskip_code = skipcodes.splittopskip +local linelist_code = nodes.listcodes.line -local abovedisplayskip_code = skipcodes.abovedisplayskip -local belowdisplayskip_code = skipcodes.belowdisplayskip -local abovedisplayshortskip_code = skipcodes.abovedisplayshortskip -local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip +local abovedisplayskip_code = gluecodes.abovedisplayskip +local belowdisplayskip_code = gluecodes.belowdisplayskip +local abovedisplayshortskip_code = gluecodes.abovedisplayshortskip +local belowdisplayshortskip_code = gluecodes.belowdisplayshortskip local properties = nodes.properties.data @@ -208,90 +211,93 @@ vspacingdata.snapmethods = snapmethods storage.register("builders/vspacing/data/snapmethods", snapmethods, "builders.vspacing.data.snapmethods") -local default = { - [v_maxheight] = true, - [v_maxdepth] = true, - [v_strut] = true, - [v_hfraction] = 1, - [v_dfraction] = 1, - [v_bfraction] = 0.25, -} +do -local fractions = { - [v_minheight] = v_hfraction, [v_maxheight] = v_hfraction, - [v_mindepth] = v_dfraction, [v_maxdepth] = v_dfraction, - [v_box] = v_bfraction, - [v_top] = v_tlines, [v_bottom] = v_blines, -} + local default = { + [v_maxheight] = true, + [v_maxdepth] = true, + [v_strut] = true, + [v_hfraction] = 1, + [v_dfraction] = 1, + [v_bfraction] = 0.25, + } -local values = { - offset = "offset" -} + local fractions = { + [v_minheight] = v_hfraction, [v_maxheight] = v_hfraction, + [v_mindepth] = v_dfraction, [v_maxdepth] = v_dfraction, + [v_box] = v_bfraction, + [v_top] = v_tlines, [v_bottom] = v_blines, + } -local colonsplitter = lpeg.splitat(":") + local values = { + offset = "offset" + } -local function listtohash(str) - local t = { } - for s in gmatch(str,"[^, ]+") do - local key, detail = lpegmatch(colonsplitter,s) - local v = variables[key] - if v then - t[v] = true - if detail then - local k = fractions[key] - if k then - detail = tonumber("0" .. detail) - if detail then - t[k] = detail - end - else - k = values[key] + local colonsplitter = lpeg.splitat(":") + + local function listtohash(str) + local t = { } + for s in gmatch(str,"[^, ]+") do + local key, detail = lpegmatch(colonsplitter,s) + local v = variables[key] + if v then + t[v] = true + if detail then + local k = fractions[key] if k then - detail = todimen(detail) + detail = tonumber("0" .. detail) if detail then t[k] = detail end + else + k = values[key] + if k then + detail = todimen(detail) + if detail then + t[k] = detail + end + end end end + else + detail = tonumber("0" .. key) + if detail then + t[v_hfraction] = detail + t[v_dfraction] = detail + end end + end + if next(t) then + t[v_hfraction] = t[v_hfraction] or 1 + t[v_dfraction] = t[v_dfraction] or 1 + return t else - detail = tonumber("0" .. key) - if detail then - t[v_hfraction] = detail - t[v_dfraction] = detail - end + return default end end - if next(t) then - t[v_hfraction] = t[v_hfraction] or 1 - t[v_dfraction] = t[v_dfraction] or 1 - return t - else - return default + + function vspacing.definesnapmethod(name,method) + local n = #snapmethods + 1 + local t = listtohash(method) + snapmethods[n] = t + t.name = name -- not interfaced + t.specification = method -- not interfaced + context(n) end -end -function vspacing.definesnapmethod(name,method) - local n = #snapmethods + 1 - local t = listtohash(method) - snapmethods[n] = t - t.name = name -- not interfaced - t.specification = method -- not interfaced - context(n) end local function validvbox(parentid,list) if parentid == hlist_code then local id = getid(list) - if id == localpar_code then -- check for initial par subtype + if id == localpar_code and getsubtype(list) == 0 then list = getnext(list) if not next then return nil end end local done = nil - for n in traverse_nodes(list) do - local id = getid(n) + for n, id in nextnode, list do if id == vlist_code or id == hlist_code then if done then return nil @@ -320,14 +326,13 @@ local function already_done(parentid,list,a_snapmethod) -- todo: done when only -- problem: any snapped vbox ends up in a line if list and parentid == hlist_code then local id = getid(list) - if id == localpar_code then -- check for initial par subtype + if id == localpar_code and getsubtype(list) == 0 then list = getnext(list) if not list then return false end end - for n in traverse_nodes(list) do - local id = getid(n) + for n, id in nextnode, list do if id == hlist_code or id == vlist_code then -- local a = getattr(n,a_snapmethod) -- if not a then @@ -536,7 +541,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] if thebox and id == vlist_code then local list = getlist(thebox) local lw, lh, ld - for n in traverse_nodes_id(hlist_code,list) do + for n in nexthlist, list do lw, lh, ld = getwhd(n) break end @@ -572,7 +577,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] if thebox and id == vlist_code then local list = getlist(thebox) local lw, lh, ld - for n in traverse_nodes_id(hlist_code,list) do + for n in nexthlist, list do lw, lh, ld = getwhd(n) end if lh then @@ -872,14 +877,15 @@ end local trace_list, tracing_info, before, after = { }, false, "", "" local function nodes_to_string(head) - local current, t = head, { } + local current = head + local t = { } while current do local id = getid(current) local ty = nodecodes[id] if id == penalty_code then t[#t+1] = formatters["%s:%s"](ty,getpenalty(current)) elseif id == glue_code then - t[#t+1] = formatters["%s:%s:%p"](ty,skipcodes[getsubtype(current)],getwidth(current)) + t[#t+1] = formatters["%s:%s:%p"](ty,gluecodes[getsubtype(current)],getwidth(current)) elseif id == kern_code then t[#t+1] = formatters["%s:%p"](ty,getkern(current)) else @@ -1261,17 +1267,26 @@ do if trace then reset_tracing(head) end - local current, oldhead = head, head - local glue_order, glue_data, force_glue = 0, nil, false - local penalty_order, penalty_data, natural_penalty, special_penalty = 0, nil, nil, nil - local parskip, ignore_parskip, ignore_following, ignore_whitespace, keep_together = nil, false, false, false, false - local lastsnap = nil + local current = head + local oldhead = head + local glue_order = 0 + local glue_data + local force_glue = false + local penalty_order = 0 + local penalty_data + local natural_penalty + local special_penalty + local parskip + local ignore_parskip = false + local ignore_following = false + local ignore_whitespace = false + local keep_together = false + local lastsnap + local pagehead + local pagetail -- -- todo: keep_together: between headers -- - local pagehead = nil - local pagetail = nil - local function getpagelist() if not pagehead then pagehead = texlists.page_head @@ -1396,7 +1411,7 @@ do end head = insert_node_before(head,current,glue_data) else - -- report_vspacing("needs checking (%s): %p",skipcodes[getsubtype(glue_data)],w) + -- report_vspacing("needs checking (%s): %p",gluecodes[getsubtype(glue_data)],w) flush_node(glue_data) end end @@ -1814,7 +1829,7 @@ do if snap and trace_vsnapping then local w = getwidth(current) if w ~= 0 then - report_snapper("glue %p of type %a kept",w,skipcodes[subtype]) + report_snapper("glue %p of type %a kept",w,gluecodes[subtype]) end end if trace then @@ -1881,7 +1896,7 @@ do trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)]) end end - return head, true + return head end -- alignment after_output end box new_graf vmode_par hmode_par insert penalty before_display after_display @@ -1909,43 +1924,47 @@ do -- ugly code: we get partial lists (check if this stack is still okay) ... and we run -- into temp nodes (sigh) + local forceflush = false + function vspacing.pagehandler(newhead,where) -- local newhead = texlists.contrib_head if newhead then - newhead = tonut(newhead) local newtail = find_node_tail(newhead) -- best pass that tail, known anyway local flush = false stackhack = true -- todo: only when grid snapping once enabled -- todo: fast check if head = tail - for n in traverse_nodes(newhead) do -- we could just look for glue nodes - local id = getid(n) + for n, id, subtype in nextnode, newhead do -- we could just look for glue nodes if id ~= glue_code then flush = true - else - local subtype = getsubtype(n) - if subtype == userskip_code then - if getattr(n,a_skipcategory) then - stackhack = true - else - flush = true - end - elseif subtype == parskip_code then - -- if where == new_graf then ... end - if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then --- texsetcount("c_spac_vspacing_ignore_parskip",0) - setglue(n) - -- maybe removenode - end + elseif subtype == userskip_code then + if getattr(n,a_skipcategory) then + stackhack = true + else + flush = true + end + elseif subtype == parskip_code then + -- if where == new_graf then ... end + if texgetcount("c_spac_vspacing_ignore_parskip") > 0 then + -- texsetcount("c_spac_vspacing_ignore_parskip",0) + setglue(n) + -- maybe removenode end end end texsetcount("c_spac_vspacing_ignore_parskip",0) + + if forceflush then + forceflush = false + flush = true + end + if flush then if stackhead then if trace_collect_vspacing then report("%s > appending %s nodes to stack (final): %s",where,newhead) end setlink(stacktail,newhead) - newhead = stackhead - stackhead, stacktail = nil, nil + newhead = stackhead + stackhead = nil + stacktail = nil end if stackhack then stackhack = false @@ -1956,7 +1975,7 @@ do if trace_collect_vspacing then report("%s > flushing %s nodes: %s",where,newhead) end -- texlists.contrib_head = newhead end - return tonode(newhead) + return newhead else if stackhead then if trace_collect_vspacing then report("%s > appending %s nodes to stack (intermediate): %s",where,newhead) end @@ -1966,13 +1985,43 @@ do stackhead = newhead end stacktail = newtail - -- texlists.contrib_head = nil - -- newhead = nil end end return nil end + -- function vspacing.flushpagestack() + -- if stackhead then + -- local head = texlists.contrib_head + -- if head then + -- local tail = find_node_tail(head) + -- setlink(tail,stackhead) + -- else + -- texlists.contrib_head = tonode(stackhead) + -- end + -- stackhead, stacktail = nil, nil + -- end + -- + -- end + + function vspacing.pageoverflow() + local h = 0 + if stackhead then + for n, id in nextnode, stackhead do + if id == glue_code then + h = h + getwidth(n) + elseif id == kern_code then + h = h + getkern(n) + end + end + end + return h + end + + function vspacing.forcepageflush() + forceflush = true + end + local ignore = table.tohash { "split_keep", "split_off", @@ -1980,11 +2029,10 @@ do } function vspacing.vboxhandler(head,where) - if head and not ignore[where] then - local h = tonut(head) - if getnext(h) then -- what if a one liner and snapping? - h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper - return tonode(h) + if head and not ignore[where] and getnext(head) then + if getnext(head) then -- what if a one liner and snapping? + head = collapser(head,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper + return head end end return head @@ -2015,7 +2063,6 @@ do local outer = texnest[0] local enabled = true - local count = true local trace = false local report = logs.reporter("vspacing") @@ -2024,96 +2071,84 @@ do end) directives.register("vspacing.synchronizepage",function(v) - if v == true or v == "count" then - enabled = true - count = true - elseif v == "first" then - enabled = true - count = false - else - enabled = false - count = false - end + enabled = v end) - -- hm, check the old one + local ignoredepth = -65536000 - -- function vspacing.synchronizepage() - -- if enabled then - -- local head = texlists.hold_head - -- local skip = 0 - -- while head and head.id == insert_code do - -- head = head.next - -- skip = skip + 1 - -- end - -- if head then - -- outer.prevdepth = 0 - -- end - -- if trace then - -- report("prevdepth %s at page %i, skipped %i, value %p", - -- head and "reset" or "kept",texgetcount("realpageno"),skip,outer.prevdepth) - -- end - -- end - -- end + -- A previous version analyzed the number of lines moved to the next page in + -- synchronizepage because prevgraf is unreliable in that case. However, we cannot + -- tweak that parameter because it is also used in postlinebreak and hangafter, so + -- there is a danger for interference. Therefore we now do it dynamically. - local ignoredepth = -65536000 + -- We can also support other lists but there prevgraf probably is ok. - function vspacing.synchronizepage() + function vspacing.getnofpreviouslines(head) if enabled then - local newdepth = outer.prevdepth - local olddepth = newdepth - local oldlines = outer.prevgraf - local newlines = 0 - local boxfound = false - local head = texlists.contrib_head + if not thead then + head = texlists.page_head + end + local noflines = 0 if head then local tail = find_node_tail(tonut(head)) while tail do local id = getid(tail) if id == hlist_code then - if not boxfound then - newdepth = getdepth(tail) - boxfound = true - end - newlines = newlines + 1 - if not count then + if getsubtype(tail) == linelist_code then + noflines = noflines + 1 + else break end elseif id == vlist_code then - if not boxfound then - newdepth = getdepth(tail) - boxfound = true - end break elseif id == glue_code then local subtype = getsubtype(tail) - if not (subtype == baselineskip_code or subtype == lineskip_code) then - break - elseif boxfound and not count then - break + if subtype == baselineskip_code or subtype == lineskip_code then + -- we're ok + elseif subtype == parskip_code then + if getwidth(tail) > 0 then + break + else + -- we assume we're ok + end end elseif id == penalty_code then - if boxfound and not count then - break - end - else - -- ins, mark, kern, rule, boundary, whatsit + -- we're probably ok + elseif id == rule_code or id == kern_code then break + else + -- ins, mark, boundary, whatsit end tail = getprev(tail) end end - if boxfound then - -- what if newdepth ... - else - texset("prevdepth",ignoredepth) - outer.prevdepth = ignoredepth - end - texset("prevgraf", newlines) - outer.prevgraf = newlines + return noflines + end + end + + interfaces.implement { + name = "getnofpreviouslines", + public = true, + actions = vspacing.getnofpreviouslines, + } + + function vspacing.synchronizepage() + if enabled then if trace then - report("page %i, prevdepth %p (last depth %p), prevgraf %i (from %i), %sboxes", - texgetcount("realpageno"),olddepth,newdepth,oldlines,newlines,boxfound and "" or "no ") + local newdepth = outer.prevdepth + local olddepth = newdepth + if not texlists.page_head then + newdepth = ignoredepth + texset("prevdepth",ignoredepth) + outer.prevdepth = ignoredepth + end + report("page %i, prevdepth %p => %p",texgetcount("realpageno"),olddepth,newdepth) + -- report("list %s",nodes.idsandsubtypes(head)) + else + if not texlists.page_head then + texset("prevdepth",ignoredepth) + outer.prevdepth = ignoredepth + end end end end @@ -2226,7 +2261,7 @@ do -- end -- } - interfaces.implement { + implement { name = "removelastline", actions = function() local head = texlists.page_head @@ -2242,7 +2277,7 @@ do end } - interfaces.implement { + implement { name = "showpagelist", -- will improve actions = function() local head = texlists.page_head @@ -2256,4 +2291,14 @@ do end } + implement { + name = "pageoverflow", + actions = { vspacing.pageoverflow, context } + } + + implement { + name = "forcepageflush", + actions = vspacing.forcepageflush + } + end diff --git a/tex/context/base/mkiv/spac-ver.mkiv b/tex/context/base/mkiv/spac-ver.mkiv index b71e28219..7b36f9a5b 100644 --- a/tex/context/base/mkiv/spac-ver.mkiv +++ b/tex/context/base/mkiv/spac-ver.mkiv @@ -15,7 +15,7 @@ \unprotect -\registerctxluafile{spac-ver}{} +\registerctxluafile{spac-ver}{optimize} % todo: use usernodes ? @@ -165,6 +165,8 @@ \installcommandhandler \??interlinespace {interlinespace} \??interlinespace +\installmacrostack\currentinterlinespace + \unexpanded\def\setupinterlinespace {\dodoubleempty\spac_linespacing_setup} @@ -205,7 +207,7 @@ \ifx\p_spac_checked_interlinespace\empty \spac_linespacing_synchronize_local \else\ifcsname\namedinterlinespacehash\p_spac_checked_interlinespace\s!parent\endcsname % we could have a \s!check - \pushmacro\currentinterlinespace + \push_macro_currentinterlinespace \let\currentinterlinespace\p_spac_checked_interlinespace \spac_linespacing_setup_specified_interline_space % \dosetupspecifiedinterlinespaceindeed \iflocalinterlinespace @@ -215,7 +217,7 @@ \the\everysetuplocalinterlinespace \localinterlinespacefalse \fi - \popmacro\currentinterlinespace + \pop_macro_currentinterlinespace \else \normalexpanded{\noexpand\doifelseassignment{\p_spac_checked_interlinespace}% \setupspecifiedinterlinespace\setuprelativeinterlinespace[\p_spac_checked_interlinespace]}% @@ -230,9 +232,9 @@ \unexpanded\def\setuplocalinterlinespace[#1]% {\localinterlinespacetrue - \pushmacro\currentinterlinespace + \push_macro_currentinterlinespace \setupinterlinespace[#1]% - \popmacro\currentinterlinespace + \pop_macro_currentinterlinespace \localinterlinespacefalse} \let\switchtointerlinespace\setuplocalinterlinespace @@ -282,47 +284,50 @@ \unexpanded\def\smallbreak {\par - \ifdim\lastskip<\smallskipamount + \ifvmode\ifdim\lastskip<\smallskipamount \removelastskip - \penalty-50 + \penalty-\plusfifty \smallskip - \fi} + \fi\fi} \unexpanded\def\medbreak {\par - \ifdim\lastskip<\medskipamount + \ifvmode\ifdim\lastskip<\medskipamount \removelastskip - \penalty-100 + \penalty-\plusonehundred \medskip - \fi} + \fi\fi} \unexpanded\def\bigbreak {\par - \ifdim\lastskip<\bigskipamount + \ifvmode\ifdim\lastskip<\bigskipamount \removelastskip - \penalty-200 + \penalty-\plustwohundred \bigskip - \fi} + \fi\fi} -\unexpanded\def\break {\penalty-\plustenthousand} % can be hmode or vmode -\unexpanded\def\nobreak {\penalty \plustenthousand} % can be hmode or vmode -\unexpanded\def\allowbreak{\penalty \zeropoint} % can be hmode or vmode -\unexpanded\def\goodbreak {\par\penalty-500\relax} % forces vmode -\unexpanded\def\filbreak {\par\vfil\penalty-200\vfilneg} % forces vmode +\unexpanded\def\break {\penalty-\plustenthousand} % can be hmode or vmode +\unexpanded\def\nobreak {\penalty \plustenthousand} % can be hmode or vmode +\unexpanded\def\allowbreak{\penalty \zerocount} % can be hmode or vmode + +\unexpanded\def\goodbreak {\par\ifvmode\penalty-\plusfivehundred\relax\fi} % forces vmode +\unexpanded\def\filbreak {\par\ifvmode\vfil\penalty-\plustwohundred\vfilneg\fi} % forces vmode %D Made slightly more readable: \unexpanded\def\vglue {\afterassignment\spac_helpers_vglue_indeed\s_spac_lastskip=} \unexpanded\def\hglue {\afterassignment\spac_helpers_hglue_indeed\s_spac_lastskip=} -\unexpanded\def\topglue{\nointerlineskip\vglue-\topskip\vglue} +\unexpanded\def\topglue{\par\ifvmode\nointerlineskip\vglue-\topskip\vglue\fi} \def\spac_helpers_vglue_indeed {\par - \d_spac_prevdepth\prevdepth - \hrule\s!height\zeropoint - \nobreak - \vskip\s_spac_lastskip - \prevdepth\d_spac_prevdepth} + \ifvmode + \d_spac_prevdepth\prevdepth + \hrule\s!height\zeropoint + \nobreak + \vskip\s_spac_lastskip + \prevdepth\d_spac_prevdepth + \fi} \def\spac_helpers_hglue_indeed {\dontleavehmode @@ -895,11 +900,14 @@ \dosetstrut} \unexpanded\def\setcharstrut#1% - {\setbox\strutbox\hbox{#1}% hm, maybe hpack i.e. why apply fonts .. conceptual choice + {\setbox\strutbox\hbox{#1}% no \hpack, in case we have smallcaps \strutht\ht\strutbox \strutdp\dp\strutbox \dosetstrut} +\unexpanded\def\settightstrut + {\setcharstrut{(}} + \unexpanded\def\setfontstrut {\setcharstrut{(gplQT}} @@ -1307,9 +1315,41 @@ \let\normaloffinterlineskip\offinterlineskip % knuth's original +%D This is tricky. The prevdepth value is still set to the last one even if there is +%D nothing on the page. The same is true for prevgraf, which doesn't resemble the +%D value on the current page. +%D +%D So, here we kick in a checker but it has to happen after the output group and it +%D only has to be done once (output can trigger itself!). +%D +%D However, prevgraf is somehow bound to hangindent so we can get very +%D nasty side effects. So, in tne end we use our own variable! + +\ifdefined\getnofpreviouslines + % defined public at the lua end +\else + \let\getnofpreviouslines\!!zerocount +\fi + +\unexpanded\def\page_otr_synchronize_page_yes + {\aftergroup\page_otr_synchronize_page_indeed + \glet\page_otr_synchronize_page\relax} + +% \unexpanded\def\page_otr_synchronize_page_indeed +% {\clf_synchronizepage +% \glet\page_otr_synchronize_page\page_otr_synchronize_page_yes} +% +% This has to become an otr method: \s!page_otr_command_synchonize_page + +\unexpanded\def\page_otr_synchronize_page_indeed + {\ifx\currentoutputroutine\s!multicolumn\else\clf_synchronizepage\fi + \glet\page_otr_synchronize_page\page_otr_synchronize_page_yes} + +\let\page_otr_synchronize_page\page_otr_synchronize_page_yes + \appendtoks - \ifvmode\clf_synchronizepage\fi % a nasty hack (tested for a while now) -\to \everyafteroutput + \page_otr_synchronize_page +\to \everyaftershipout %D My own one: @@ -1361,7 +1401,7 @@ \let\restoreinterlinepenalty\relax \unexpanded\def\spac_penalties_restore - {\global\let\restoreinterlinepenalty\relax + {\glet\restoreinterlinepenalty\relax \global\resetpenalties\interlinepenalties \global\c_spac_keep_lines_together\zerocount} @@ -1369,7 +1409,7 @@ {\ifnum#1>\c_spac_keep_lines_together \global\c_spac_keep_lines_together#1% \global\setpenalties\interlinepenalties\c_spac_keep_lines_together\plustenthousand - \global\let\restoreinterlinepenalty\spac_penalties_restore + \glet\restoreinterlinepenalty\spac_penalties_restore \fi} \def\defaultdisplaywidowpenalty {50} @@ -1701,7 +1741,7 @@ \fi \doifelsenothing{#1}{\spac_grids_snap_value_set\v!normal}{\spac_grids_snap_value_set{#1}}% \clf_vspacingsnap\nextbox\attribute\snapmethodattribute\relax - \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% *pack ? + \ifvbox\nextbox\vbox\else\hbox\fi attr \snapmethodattribute \zerocount {\box\nextbox}% no pack (?), we snap \egroup} \def\spac_grids_check_nop @@ -1816,15 +1856,15 @@ \unexpanded\def\gridboxvbox {\ifcase\gridboxlinemode - \vbox + \vpack \or - \ruledvbox + \ruledvpack \or - \vbox + \vpack \or - \ruledvbox + \ruledvpack \else - \ruledvbox + \ruledvpack \fi} \def\gridboxwidth{\ifcase\gridboxlinemode0\or.5\or.5\or0\else.5\fi\linewidth} @@ -1836,8 +1876,10 @@ \resetteststrut \offinterlineskip \hsize#2% - \ifnum\gridboxlinenomode=\plusthree - \gridboxlinenomode\ifodd\realpageno\plusone\else\plustwo\fi + \ifcase\gridboxlinenomode\or\or\or + \gridboxlinenomode\doifoddpageelse\plusone\plustwo % 3: outer + \or + \gridboxlinenomode\doifoddpageelse\plustwo\plusone % 4: inner \fi \topskipcorrection \gridboxvbox % calculated size @@ -2014,7 +2056,7 @@ \expandafter\nostartblankhandling \fi} -\def\nostartblankhandling#1\stopblankhandling +\unexpanded\def\nostartblankhandling#1\stopblankhandling {} \def\dostartblankhandling @@ -2042,7 +2084,7 @@ \setfalse\c_space_vspacing_done \the\everybeforeblankhandling} -\def\addpredefinedblankskip#1#2% +\unexpanded\def\addpredefinedblankskip#1#2% {\settrue\c_space_vspacing_done \advance\s_spac_vspacing_temp#1\dimexpr\csname\??vspacingamount#2\endcsname\relax} @@ -2089,8 +2131,56 @@ \def\spac_vspacing_nop_ignore {\ifmmode\else\par\fi} -\def\directvspacing#1% - {\par\clf_vspacing{#1}} +% \unexpanded\def\directvspacing#1% +% {\par\clf_vspacing{#1}} +% +% +% \def\directdefaultvspacing +% {\ifinpagebody % somewhat weird +% \clf_vspacing{\currentvspacing}% +% \else\ifconditional\c_spac_packed_blank +% \clf_vspacing{\currentvspacing}% +% \fi\fi} +% +% \unexpanded\def\useblankparameter#1% faster local variant +% {\edef\m_spac_blank_asked{#1\c!blank}% +% \ifx\m_spac_blank_asked\empty\else +% \clf_vspacing{\m_spac_blank_asked} +% \fi} + +\installcorenamespace{vspacing} + +\unexpanded\def\directvspacing#1% + {\par + \ifcsname\??vspacing#1\endcsname + \lastnamedcs + \else + \spac_vspacing_yes_preset{#1}% + \fi} + +\def\spac_vspacing_yes_preset#1% + {\setxvalue{\??vspacing#1}{\clf_vspacing{#1}}% + %\writestatus{}{}% + %\writestatus{#1}{\expandafter\meaning\csname\??vspacing#1\endcsname}% + %\writestatus{}{}% + \csname\??vspacing#1\endcsname} + +\def\spac_vspacing_yes_indeed[#1]% + {\ifmmode\else + \directvspacing{#1}% + \fi} + +\def\spac_vspacing_nop_indeed + {\ifmmode\else + \directvspacing\currentvspacing + \fi} + +\def\directdefaultvspacing + {\ifinpagebody % somewhat weird + \directvspacing\currentvspacing + \else\ifconditional\c_spac_packed_blank + \directvspacing\currentvspacing + \fi\fi} \def\directcheckedvspacing {\ifinpagebody % somewhat weird @@ -2101,17 +2191,10 @@ \doubleexpandafter\gobbleoneargument \fi\fi} -\def\directdefaultvspacing - {\ifinpagebody % somewhat weird - \clf_vspacing{\currentvspacing}% - \else\ifconditional\c_spac_packed_blank - \clf_vspacing{\currentvspacing}% - \fi\fi} - \unexpanded\def\useblankparameter#1% faster local variant {\edef\m_spac_blank_asked{#1\c!blank}% \ifx\m_spac_blank_asked\empty\else - \clf_vspacing{\m_spac_blank_asked} + \directvspacing\m_spac_blank_asked \fi} % handy (and faster): @@ -2418,13 +2501,14 @@ \scratchwidth\dimexpr\wd\nextbox+\scratchdistance\relax \ifx\m_spac_hanging_location\v!right \hangindent\ifconditional\displaylefttoright-\fi\scratchwidth - \rlap{\hskip\dimexpr\hsize-\wd\nextbox\relax\box\nextbox}% + \rlap{\hskip\dimexpr\hsize-\leftskip-\wd\nextbox\relax\box\nextbox}% \leftskip is new \else \hangindent\ifconditional\displaylefttoright\else-\fi\scratchwidth \llap{\box\nextbox\hskip\scratchdistance}% \fi \ignorespaces} + %D \macros %D {startfixed} %D diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf index 74e8e3e8a..49b023fb8 100644 Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf index a2f2ee28b..8cbd7014c 100644 Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ diff --git a/tex/context/base/mkiv/strc-blk.lua b/tex/context/base/mkiv/strc-blk.lua index 703d36379..89df440c9 100644 --- a/tex/context/base/mkiv/strc-blk.lua +++ b/tex/context/base/mkiv/strc-blk.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['strc-blk'] = { -- this one runs on top of buffers and structure local type, next = type, next -local find, format, validstring = string.find, string.format, string.valid +local find, formatters, validstring = string.find, string.formatters, string.valid local settings_to_set, settings_to_array = utilities.parsers.settings_to_set, utilities.parsers.settings_to_array local allocate = utilities.storage.allocate @@ -25,6 +25,7 @@ structures.blocks = structures.blocks or { } local blocks = structures.blocks local sections = structures.sections local lists = structures.lists +local helpers = structures.helpers local collected = allocate() local tobesaved = allocate() @@ -42,14 +43,28 @@ end job.register('structures.blocks.collected', tobesaved, initializer) local listitem = utilities.parsers.listitem +local f_block = formatters["block.%s"] + +function blocks.uservariable(index,key,default) + local c = collected[index] + if c then + local u = c.userdata + if u then + local v = u[key] or default + if v then + context(v) + end + end + end +end -function blocks.print(name,data,hide) +local function printblock(index,name,data,hide) if hide then - context.dostarthiddenblock(name) + context.dostarthiddenblock(index,name) else - context.dostartnormalblock(name) + context.dostartnormalblock(index,name) end - context.viafile(data,format("block.%s",validstring(name,"noname"))) + context.viafile(data,f_block(validstring(name,"noname"))) if hide then context.dostophiddenblock() else @@ -57,12 +72,14 @@ function blocks.print(name,data,hide) end end +blocks.print = printblock + function blocks.define(name) states[name] = { all = "hide" } end function blocks.setstate(state,name,tag) - local all = tag == "" + local all = tag == "" local tags = not all and settings_to_array(tag) for n in listitem(name) do local sn = states[n] @@ -98,12 +115,12 @@ function blocks.select(state,name,tag,criterium) local metadata = ri.metadata if names[metadata.name] then if all then - blocks.print(name,ri.data,hide) + printblock(ri.index,name,ri.data,hide) else local mtags = metadata.tags for tag, sta in next, tags do if mtags[tag] then - blocks.print(name,ri.data,hide) + printblock(ri.index,name,ri.data,hide) break end end @@ -112,41 +129,51 @@ function blocks.select(state,name,tag,criterium) end end -function blocks.save(name,tag,buffer) -- wrong, not yet adapted - local data = buffers.getcontent(buffer) - local tags = settings_to_set(tag) - local plus, minus = false, false - if tags['+'] then plus = true tags['+'] = nil end - if tags['-'] then minus = true tags['-'] = nil end - tobesaved[#tobesaved+1] = { - metadata = { - name = name, - tags = tags, - plus = plus, +function blocks.save(name,tag,userdata,buffer) -- wrong, not yet adapted + local data = buffers.getcontent(buffer) + local tags = settings_to_set(tag) + local plus = false + local minus = false + local last = #tobesaved + 1 + local all = states[name].all + if tags['+'] then + plus = true + tags['+'] = nil + end + if tags['-'] then + minus = true + tags['-'] = nil + end + tobesaved[last] = helpers.simplify { + metadata = { + name = name, + tags = tags, + plus = plus, minus = minus, }, + index = last, + data = data or "error", + userdata = userdata and type(userdata) == "string" and helpers.touserdata(userdata), references = { - section = sections.currentid(), + section = sections.currentid(), }, - data = data or "error", } - local allstate = states[name].all if not next(tags) then - if allstate ~= "hide" then - blocks.print(name,data) + if all ~= "hide" then + printblock(last,name,data) elseif plus then - blocks.print(name,data,true) + printblock(last,name,data,true) end else local sn = states[name] for tag, _ in next, tags do if sn[tag] == nil then - if allstate ~= "hide" then - blocks.print(name,data) + if all ~= "hide" then + printblock(last,name,data) break end elseif sn[tag] ~= "hide" then - blocks.print(name,data) + printblock(last,name,data) break end end @@ -156,7 +183,8 @@ end -- interface -implement { name = "definestructureblock", actions = blocks.define, arguments = "string" } -implement { name = "savestructureblock", actions = blocks.save, arguments = "3 strings" } -implement { name = "selectstructureblock", actions = blocks.select, arguments = "4 strings" } -implement { name = "setstructureblockstate", actions = blocks.setstate, arguments = "3 strings" } +implement { name = "definestructureblock", actions = blocks.define, arguments = "string" } +implement { name = "savestructureblock", actions = blocks.save, arguments = "4 strings" } +implement { name = "selectstructureblock", actions = blocks.select, arguments = "4 strings" } +implement { name = "setstructureblockstate", actions = blocks.setstate, arguments = "3 strings" } +implement { name = "structureblockuservariable", actions = blocks.uservariable, arguments = { "integer", "string" } } diff --git a/tex/context/base/mkiv/strc-blk.mkiv b/tex/context/base/mkiv/strc-blk.mkiv index c42bb25ec..e52198721 100644 --- a/tex/context/base/mkiv/strc-blk.mkiv +++ b/tex/context/base/mkiv/strc-blk.mkiv @@ -34,48 +34,125 @@ \appendtoks \clf_definestructureblock{\currentblock}% - \setuevalue{\e!begin\currentblock}{\dodoubleempty\strc_blocks_begin[\currentblock]}% - \setuevalue{\e!end \currentblock}{}% + \setuevalue{\e!begin\currentblock}{\strc_blocks_begin{\currentblock}}% + \letvalue {\e!end \currentblock}\donothing \to \everydefineblock -\unexpanded\def\strc_blocks_begin[#1][#2]% - {\normalexpanded{\buff_pickup{@block@}{\e!begin#1}{\e!end#1}} - {}% before - {\clf_savestructureblock{#1}{#2}{@block@}}% - \plusone}% after +% The naive way: +% +% \unexpanded\def\strc_blocks_begin#1% +% {\dotripleempty\strc_blocks_begin_indeed[#1]} +% +% \unexpanded\def\strc_blocks_begin_indeed[#1][#2][#3]% +% {\normalexpanded{\buff_pickup{\??block}{\e!begin#1}{\e!end#1}} +% {}% +% {\clf_savestructureblock{#1}{#2}{#3}{\??block}}% +% \plusone}% +% +% We need to prevent too much lookahead which will gobble newlines +% that are needed for buffers. See blocks-002.tex as example. + +% maybe: systemmode "block:" + +\let\m_block \empty +\let\m_subblock\empty + +\unexpanded\def\strc_blocks_begin#1% + {\edef\m_block {#1}% + \let \m_subblock\empty + \doifelsenextoptionalcs\strc_blocks_begin_yes\strc_blocks_begin_nop} + +\unexpanded\def\strc_blocks_begin_yes[#1]% + {\doifelseassignmentcs{#1}% + \strc_blocks_begin_indeed + \strc_blocks_begin_tagged + {#1}} + +\unexpanded\def\strc_blocks_begin_tagged#1% + {\edef\m_subblock{#1}% + \doifelsenextoptionalcs\strc_blocks_begin_yes_yes\strc_blocks_begin_nop} + +\unexpanded\def\strc_blocks_begin_yes_yes[#1]% + {\strc_blocks_begin_indeed{#1}} + +\unexpanded\def\strc_blocks_begin_nop + {\strc_blocks_begin_indeed{}} + +\unexpanded\def\strc_blocks_begin_indeed#1% + {\normalexpanded{\buff_pickup{\??block}{\e!begin\m_block}{\e!end\m_block}}% + {}% + {\clf_savestructureblock{\m_block}{\m_subblock}{#1}{\??block}}% + \plusone} \let\strc_blocks_setup\relax +\newconstant \c_strc_blocks_index +\newconditional\c_strc_blocks_display + \unexpanded\def\dostarthiddenblock % called at lua end - {\startnointerference - \dostartnormalblock} + {\begingroup + \visiblefalse % blocks float + \startnointerference + \strc_start_block} \unexpanded\def\dostophiddenblock % called at lua end - {\dostopnormalblock - \stopnointerference} + {\strc_stop_block + \stopnointerference + \endgroup} + +\unexpanded\def\dostartnormalblock % called at lua end + {\begingroup + \visibletrue + \strc_start_block} -\unexpanded\def\dostartnormalblock#1% called at lua end - {\bgroup - \visibletrue % will change - \edef\currentblock{#1}% +\unexpanded\def\dostopnormalblock % called at lua end + {\strc_stop_block + \endgroup} + +\def\strc_start_block#1#2% + {\edef\currentblock{#2}% + \c_strc_blocks_index#1\relax \strc_blocks_setup \let\strc_blocks_setup\relax - \blockparameter\c!before - \useblockstyleandcolor\c!style\c!color % maybe moev one line up (font spacing) - \blockparameter\c!inner % better \c!setups + \edef\p_alternative{\blockparameter\c!alternative}% + \ifx\p_alternative\v!text + \setfalse\c_strc_blocks_display + \else + \settrue\c_strc_blocks_display + \fi + \ifconditional\c_strc_blocks_display + \blockparameter\c!before + \fi + \begingroup + \usesetupsparameter\blockparameter\relax + \dostarttagged\t!block\currentblock + \useblockstyleandcolor\c!style\c!color + \blockparameter\c!inner % old + \ifconditional\c_strc_blocks_display + \usealignparameter\blockparameter + \else + \blockparameter\c!left + \fi \ignorespaces} -\unexpanded\def\dostopnormalblock % called at lua end +\def\strc_stop_block {\removeunwantedspaces - \blockparameter\c!after - \par % todo: alternative = text, paragraph - \egroup} + \ifconditional\c_strc_blocks_display + \par + \else + \blockparameter\c!right + \fi + \dostoptagged + \endgroup + \ifconditional\c_strc_blocks_display + \blockparameter\c!after + \fi} \def\strc_blocks_set_state[#1][#2][#3]% state name tag {\clf_setstructureblockstate{#1}{#2}{#3}} \def\strc_blocks_select[#1][#2][#3][#4]% state name tag setups - {\bgroup + {\begingroup \doifelseassignment{#3} {\getparameters[\??blocktemp][\c!criterium=\v!text,#3]% \def\strc_blocks_setup{\setupcurrentblock[#3]}% @@ -83,7 +160,10 @@ {\getparameters[\??blocktemp][\c!criterium=\v!text,#4]% \def\strc_blocks_setup{\setupcurrentblock[#4]}% \clf_selectstructureblock{#1}{#2}{#3}{\csname\??blocktemp\c!criterium\endcsname}}% - \egroup} + \endgroup} + +\def\blockuservariable#1% + {\clf_structureblockuservariable\c_strc_blocks_index{#1}} % hide : save, if [+] also hidden execute % keep : save and normal execute diff --git a/tex/context/base/mkiv/strc-con.mkvi b/tex/context/base/mkiv/strc-con.mkvi index 57b69cc7f..d67307ba7 100644 --- a/tex/context/base/mkiv/strc-con.mkvi +++ b/tex/context/base/mkiv/strc-con.mkvi @@ -980,11 +980,11 @@ \xdef\currentconstructionincrementnumber{\constructionparameter\c!incrementnumber}% % \ifx\currentconstructionexpansion\empty - \global\let\currentconstructionexpansion\v!no + \glet\currentconstructionexpansion\v!no \fi % \ifx\currentconstructionreferenceprefix\empty - \global\let\currentconstructionreferenceprefix\referenceprefix + \glet\currentconstructionreferenceprefix\referenceprefix \fi \ifx\currentconstructionexpansion\s!xml \xmlstartraw @@ -994,9 +994,9 @@ \xdef\currentconstructionlist {\constructionparameter\c!list}% \xmlstopraw \ifx\currentconstructionlist\empty - \global\let\currentconstructionlist\currentconstructiontitle + \glet\currentconstructionlist\currentconstructiontitle \fi - \global\let\currentconstructioncoding\s!xml + \glet\currentconstructioncoding\s!xml \else \ifx\currentconstructionexpansion\v!yes \xdef\currentconstructiontitle {\constructionparameter\c!title}% @@ -1016,9 +1016,9 @@ \fi \fi \fi \ifx\currentconstructionlist\empty - \globallet\currentconstructionlist\currentconstructiontitle + \glet\currentconstructionlist\currentconstructiontitle \fi - \globallet\currentconstructioncoding\s!tex + \glet\currentconstructioncoding\s!tex \fi % \ifx\currentconstructiontitle\v!none % will become obsolete @@ -1093,7 +1093,7 @@ \endgroup \edef\noexpand\currentconstructionlistentry {\the\scratchcounter}% \edef\noexpand\currentconstructionattribute {\the\lastdestinationattribute}% - \edef\noexpand\currentconstructionsynchronize{\ctxlatecommand{enhancelist(\the\scratchcounter)}}% + \edef\noexpand\currentconstructionsynchronize{\clf_deferredenhancelist\the\scratchcounter}% }% \fi} @@ -1103,11 +1103,11 @@ \def\reinstateconstructionnumberentry#1% was xdef {\edef\currentconstructionattribute {\clf_getinternallistreference#1}% - \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}} + \edef\currentconstructionsynchronize{\clf_deferredenhancelist\number#1}} \def\reinstatecachedconstructionnumberentry#1% was xdef | #1 = cached index can be different from real {\edef\currentconstructionattribute {\clf_getinternalcachedlistreference#1}% destination - \edef\currentconstructionsynchronize{\ctxlatecommand{enhancelist(#1)}}} + \edef\currentconstructionsynchronize{\clf_deferredenhancelist\number#1}} \installstructurelistprocessor{construction}{\usestructurelistprocessor{number+title}} diff --git a/tex/context/base/mkiv/strc-def.mkiv b/tex/context/base/mkiv/strc-def.mkiv index 8d1fa371f..941f561c8 100644 --- a/tex/context/base/mkiv/strc-def.mkiv +++ b/tex/context/base/mkiv/strc-def.mkiv @@ -65,6 +65,17 @@ \setsectionblock [\v!bodypart] % default +% \setuphead[sectionsegments=\currentheadlevel] +% \setuphead[sectionsegments=current] +% +% \startchapter[title=One,ownnumber={A}] +% \startsection[title=OneOne,ownnumber={A.B}] +% \startsubsection[title=OneOneOne,ownnumber={A.B.C}] +% test +% \stopsubsection +% \stopsection +% \stopchapter + % \appendtoks % \setsectionblock[\v!bodypart]% default % \to \everyjob diff --git a/tex/context/base/mkiv/strc-doc.lua b/tex/context/base/mkiv/strc-doc.lua index 2de26ac64..4b2ac04b7 100644 --- a/tex/context/base/mkiv/strc-doc.lua +++ b/tex/context/base/mkiv/strc-doc.lua @@ -18,6 +18,7 @@ if not modules then modules = { } end modules ['strc-doc'] = { local next, type, tonumber, select = next, type, tonumber, select local find, match = string.find, string.match local concat, fastcopy, insert, remove = table.concat, table.fastcopy, table.insert, table.remove +local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys local max, min = math.max, math.min local allocate, mark, accesstable = utilities.storage.allocate, utilities.storage.mark, utilities.tables.accesstable local setmetatableindex = table.setmetatableindex @@ -37,11 +38,13 @@ local v_auto = variables.auto local v_strict = variables.strict local v_all = variables.all local v_positive = variables.positive +local v_current = variables.current local trace_sectioning = false trackers.register("structures.sectioning", function(v) trace_sectioning = v end) local trace_detail = false trackers.register("structures.detail", function(v) trace_detail = v end) local report_structure = logs.reporter("structure","sectioning") +local report_used = logs.reporter("structure") local context = context local commands = commands @@ -122,12 +125,16 @@ local tobesaved = allocate() sections.collected = collected sections.tobesaved = tobesaved --- local function initializer() --- collected = sections.collected --- tobesaved = sections.tobesaved --- end --- --- job.register('structures.sections.collected', tobesaved, initializer) +-- We have to save this mostly redundant list because we can have (rare) +-- cases with own numbers that don't end up in the list so we get out of +-- sync when we use (*). + +local function initializer() + collected = sections.collected + tobesaved = sections.tobesaved +end + +job.register('structures.sections.collected', tobesaved, initializer) local registered = sections.registered or allocate() sections.registered = registered @@ -158,7 +165,7 @@ end local lastsaved = 0 function sections.save(sectiondata) --- local sectionnumber = helpers.simplify(section.sectiondata) -- maybe done earlier +local sectiondata = helpers.simplify(sectiondata) -- maybe done earlier local numberdata = sectiondata.numberdata local ntobesaved = #tobesaved if not numberdata or sectiondata.metadata.nolist then @@ -178,28 +185,28 @@ function sections.currentsectionindex() return lastsaved -- only for special controlled situations end -function sections.load() - setmetatableindex(collected,nil) - local lists = lists.collected - for i=1,#lists do - local list = lists[i] - local metadata = list.metadata - if metadata and metadata.kind == "section" and not metadata.nolist then - local numberdata = list.numberdata - if numberdata then - collected[#collected+1] = numberdata - end - end - end - sections.load = functions.dummy -end - -table.setmetatableindex(collected, function(t,i) - sections.load() - return collected[i] or { } -end) - +-- See comment above (*). We cannot use the following space optimization: +-- +-- function sections.load() +-- setmetatableindex(collected,nil) +-- local lists = lists.collected +-- for i=1,#lists do +-- local list = lists[i] +-- local metadata = list.metadata +-- if metadata and metadata.kind == "section" and not metadata.nolist then +-- local numberdata = list.numberdata +-- if numberdata then +-- collected[#collected+1] = numberdata +-- end +-- end +-- end +-- sections.load = functions.dummy +-- end -- +-- table.setmetatableindex(collected, function(t,i) +-- sections.load() +-- return collected[i] or { } +-- end) sections.verbose = true @@ -382,8 +389,9 @@ function sections.setentry(given) -- new number olddepth = newdepth if metadata.increment then - local oldn, newn = numbers[newdepth] or 0, 0 - local fd = forced[newdepth] + local oldn = numbers[newdepth] or 0 + local newn = 0 + local fd = forced[newdepth] if fd then if fd[1] == "add" then newn = oldn + fd[2] + 1 @@ -438,7 +446,10 @@ end function sections.reportstructure() if sections.verbose then - local numbers, ownnumbers, status, depth = data.numbers, data.ownnumbers, data.status, data.depth + local numbers = data.numbers + local ownnumbers = data.ownnumbers + local status = data.status + local depth = data.depth local d = status[depth] local o = concat(ownnumbers,".",1,depth) local n = (numbers and concat(numbers,".",1,min(depth,#numbers))) or 0 @@ -711,8 +722,12 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref criterium = 0 end -- - local firstprefix, lastprefix = 0, 16 -- too much, could max found level - if segments then + local firstprefix = 0 + local lastprefix = 16 -- too much, could max found level + if segments == v_current then + firstprefix = data.depth + lastprefix = firstprefix + elseif segments then local f, l = match(tostring(segments),"^(.-):(.+)$") if l == "*" or l == v_all then l = 100 -- new @@ -731,9 +746,11 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref end end -- - local numbers, ownnumbers = entry.numbers, entry.ownnumbers + local numbers = entry.numbers + local ownnumbers = entry.ownnumbers if numbers then - local done, preceding = false, false + local done = false + local preceding = false -- local result = kind == "direct" and { } if result then @@ -751,11 +768,14 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref if prefixlist and (kind == "section" or kind == "prefix" or kind == "direct") then -- find valid set (problem: for sectionnumber we should pass the level) -- no holes - local b, e, bb, ee = 1, #prefixlist, 0, 0 + local b = 1 + local e = #prefixlist + local bb = 0 + local ee = 0 -- find last valid number for k=e,b,-1 do local prefix = prefixlist[k] - local index = sections.getlevel(prefix) or k + local index = sections.getlevel(prefix) or k if index >= firstprefix and index <= lastprefix then local number = numbers and numbers[index] if number then @@ -771,7 +791,7 @@ function sections.typesetnumber(entry,kind,...) -- kind='section','number','pref -- find valid range for k=b,e do local prefix = prefixlist[k] - local index = sections.getlevel(prefix) or k + local index = sections.getlevel(prefix) or k if index >= firstprefix and index <= lastprefix then local number = numbers and numbers[index] if number then @@ -972,6 +992,47 @@ function sections.getnumber(depth,what) -- redefined here context(askednumber) end +-- maybe handy + +function sections.showstructure() + + local tobesaved = structures.lists.tobesaved + + if not tobesaved then + return + end + + local levels = setmetatableindex("table") + local names = setmetatableindex("table") + + report_used() + report_used("sections") + for i=1,#tobesaved do + local si = tobesaved[i] + local md = si.metadata + if md and md.kind == "section" then + local level = md.level + local name = md.name + local numbers = si.numberdata.numbers + local title = si.titledata.title + report_used(" %i : %-10s %-20s %s",level,concat(numbers,"."),name,title) + levels[level][name] = true + names[name][level] = true + end + end + report_used() + report_used("levels") + for level, list in sortedhash(levels) do + report_used(" %s : % t",level,sortedkeys(list)) + end + report_used() + report_used("names") + for name, list in sortedhash(names) do + report_used(" %-10s : % t",name,sortedkeys(list)) + end + report_used() +end + -- experimental local levels = { } @@ -1042,6 +1103,7 @@ implement { name = "getsomefullstructurenumber", actions = sections.fullnumber, implement { name = "getspecificstructuretitle", actions = sections.structuredata, arguments = { "string", "'titledata.title'",false,"string" } } implement { name = "reportstructure", actions = sections.reportstructure } +implement { name = "showstructure", actions = sections.showstructure } implement { name = "registersection", diff --git a/tex/context/base/mkiv/strc-doc.mkiv b/tex/context/base/mkiv/strc-doc.mkiv index 805525487..516d87efe 100644 --- a/tex/context/base/mkiv/strc-doc.mkiv +++ b/tex/context/base/mkiv/strc-doc.mkiv @@ -19,6 +19,16 @@ %D This will move: +% \unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext +% {\clf_setinternalreference +% prefix {\currentstructurereferenceprefix}% +% reference {\currentstructurereference} +% internal \locationcount +% view {\interactionparameter\c!focus}% +% \relax +% \xdef\currentstructureattribute {\the\lastdestinationattribute}% +% \xdef\currentstructuresynchronize{\strc_lists_inject_enhance{#1}}} + \unexpanded\def\setstructuresynchronization#1% todo: use ctxcontext {\clf_setinternalreference prefix {\currentstructurereferenceprefix}% @@ -26,7 +36,20 @@ internal \locationcount view {\interactionparameter\c!focus}% \relax - \xdef\currentstructureattribute {\the\lastdestinationattribute}% - \xdef\currentstructuresynchronize{\strc_lists_inject_enhance{#1}{\the\locationcount}}} + \xdef\currentstructureattribute + {\the\lastdestinationattribute}% + \xdef\currentstructuresynchronize + {\currentstructuresynchronize + \strc_lists_inject_enhance{#1}}} + +\unexpanded\def\setstructurecomponentsynchronization#1% todo: use ctxcontext + {\clf_setinternalreference + prefix {\currentstructurecomponentreferenceprefix}% + reference {\currentstructurecomponentreference} + internal \locationcount + view {\interactionparameter\c!focus}% + \relax + \xdef\currentstructurecomponentattribute {\the\lastdestinationattribute}% + \xdef\currentstructurecomponentsynchronize{\strc_lists_inject_enhance{#1}}} \protect \endinput diff --git a/tex/context/base/mkiv/strc-flt.lua b/tex/context/base/mkiv/strc-flt.lua index 466fd515e..e3a0ea30e 100644 --- a/tex/context/base/mkiv/strc-flt.lua +++ b/tex/context/base/mkiv/strc-flt.lua @@ -7,3 +7,37 @@ if not modules then modules = { } end modules ['strc-flt'] = { } -- nothing + +local sequencers = utilities.sequencers +local appendaction = sequencers.appendaction +local enableaction = sequencers.enableaction +local disableaction = sequencers.disableaction + +local texgetdimen = tex.getdimen + +local trace = trackers.register("structure.sidefloats.pageflush") +local report = logs.reporter("structure","floats") + +local forcepageflush = builders.vspacing.forcepageflush + +function builders.checksidefloat(mode,indented) + local s = texgetdimen("d_page_sides_vsize") + if s > 0 then + if trace then + report("force flushing page state, height %p",s) + end + forcepageflush() + end + return indented +end + +appendaction ("newgraf","system","builders.checksidefloat") +disableaction("newgraf","builders.checksidefloat") + +interfaces.implement { + name = "enablesidefloatchecker", + onlyonce = true, + actions = function() + enableaction("newgraf","builders.checksidefloat") + end, +} diff --git a/tex/context/base/mkiv/strc-flt.mkvi b/tex/context/base/mkiv/strc-flt.mkvi index 632c67686..02f6fd753 100644 --- a/tex/context/base/mkiv/strc-flt.mkvi +++ b/tex/context/base/mkiv/strc-flt.mkvi @@ -61,9 +61,11 @@ \installcorenamespace{float} \installcorenamespace{floatbuilder} \installcorenamespace{floatcaption} +\installcorenamespace{floatframed} \installframedcommandhandler \??float {float} \??float \installframedcommandhandler \??floatcaption {floatcaption} \??floatcaption +\installframedcommandhandler \??floatframed {floatframed} \??floatframed \let\setupfloats \setupfloat \let\setupcaption \setupfloatcaption @@ -97,6 +99,8 @@ \c!textcolor=, \c!align=, \c!number=\v!yes, + \c!offset=\v!overlay, + \c!frame=\v!off, % \c!expansion=, % \c!prefix=, % \c!prefixconnector=, @@ -110,7 +114,7 @@ % \c!stopper=, \c!suffixseparator=, % currently rather hard coded \c!suffix=\floatcaptionsuffix, - \c!distance=\emwidth, + \c!distance=\emwidth, % plus .5\emwidth minus .25\emwidth \c!conversion=\v!numbers, \c!maxwidth=\hsize, \c!command=] @@ -171,6 +175,11 @@ \c!sidethreshold=.5\strutdp, % set to "old" to check with old method \c!numbering=\v!yes] +\setupfloatframed + [\c!frame=\v!off, + \c!offset=\v!overlay, + \c!strut=\v!no] + %D Individial settings: \installcounterassociation{floatcaption} @@ -207,6 +216,7 @@ \def\strc_floats_define_a[#1][#2][#3]% name names parent {\definefloatcaption[#1][#3]% + \definefloatframed[#1][#3]% \definecounter[#1][#3]% \definelist[#1][#3]% \copylabeltext[#1=#3]% @@ -215,6 +225,7 @@ \def\strc_floats_define_b[#1][#2][#3]% name parent settings {\definefloatcaption[#1][#2]% + \definefloatframed[#1][#2]% \definecounter[#1][#2]% \definelist[#1][#2]% \copylabeltext[#1=#2]% @@ -224,6 +235,7 @@ \def\strc_floats_define_c[#1][#2]% name names {\registerfloatcaptioncounter{#1}% \definefloatcaption[#1]% + \definefloatframed[#1]% \definecounter[#1]% \definelist[#1]% \presetlabeltext[#1=\Word{#1}~]% @@ -332,6 +344,7 @@ \def\strc_floats_make_complete_caption {\doifsomething{\floatcaptionparameter\c!spacebefore}{\blank[\floatcaptionparameter\c!spacebefore]}% + \strc_floats_make_complete_caption_before \synchronizedisplaydirection % temp hack, till we have a proper model \noindent \gdef\lastcaptiontag{\strut\thecurrentfloatnumber}% was xdef ... needs checking @@ -361,8 +374,26 @@ \thecurrentfloatcaption\endgraf \fi \endgroup + \strc_floats_make_complete_caption_after \doifsomething{\floatcaptionparameter\c!spaceafter}{\blank[\floatcaptionparameter\c!spaceafter]}} +%let\strc_floats_make_complete_caption_before\relax +\let\strc_floats_make_complete_caption_after \relax + +\def\strc_floats_make_complete_caption_before + {\doifelseframed\floatcaptionparameter\strc_floats_make_complete_caption_before_indeed\relax} + +\def\strc_floats_make_complete_caption_before_indeed + {\edef\m_strc_align{\floatcaptionparameter\c!align}% + \edef\m_strc_strut{\floatcaptionparameter\c!strut}% + \letfloatcaptionparameter\c!align\v!normal + \letfloatcaptionparameter\c!strut\v!no + \inheritedfloatcaptionframed + \bgroup + \letfloatcaptionparameter\c!align\m_strc_align + \letfloatcaptionparameter\c!strut\m_strc_strut + \let\strc_floats_make_complete_caption_after\egroup} + % \definefloat [figure-1] [figure] % \definefloat [figure-2] [figure] % \setupfloat [figure-1] [location=left,leftmargin=10mm] @@ -425,7 +456,7 @@ %D {\global\advance\c_strc_floats_n\plusone %D \xdef\strc_float_realpage{\datasetvariable\s!float{\number\c_strc_floats_n}\s!page}% %D \ifx\strc_float_realpage\empty -%D \globallet\strc_float_realpage\realpageno % \realfolio +%D \glet\strc_float_realpage\realpageno % \realfolio %D \fi} %D \stoptyping %D @@ -444,7 +475,7 @@ {\global\advance\c_strc_floats_n\plusone \xdef\strc_float_realpage{\pagestaterealpage\s!float{\number\c_strc_floats_n}}% \ifx\strc_float_realpage\empty - \globallet\strc_float_realpage\realpageno % \realfolio + \glet\strc_float_realpage\realpageno % \realfolio \fi} %D test case: @@ -482,7 +513,7 @@ \donothing {\writestatus\m!floatblocks{unknown float type '\currentfloat'}% \let\currentfloat\v!figure}% also a hack - \global\let\lastplacedfloat\currentfloat + \glet\lastplacedfloat\currentfloat \let\m_strc_floats_saved_userdata\empty \let\currentfloatcaption\currentfloat} @@ -493,8 +524,8 @@ {\global\emptyfloatcaptionfalse \global\nofloatcaptionfalse \global\nofloatnumberfalse - \global\let\askedfloatmethod \empty - \global\let\askedfloatoptions\empty} + \glet\askedfloatmethod \empty + \glet\askedfloatoptions\empty} % place @@ -505,10 +536,13 @@ \let\floatlocationmethod\empty \def\strc_floats_analyze_location - {% moved here, will do more + {% more will be moved here \let\floatlabel \empty \let\floatcolumn\empty \let\floatrow \empty + % + \edef\floatcaptionlocation{\floatcaptionparameter\c!location}% + % \setfloatmethodvariables\floatlocation} \unexpanded\def\strc_floats_place#tag% @@ -571,25 +605,49 @@ \strc_floats_set_current_tag{#tag}% \dodoubleempty\strc_floats_start_place_indeed} +%D We abuse the settings to pick up some float parameters too which makes it +%D messy. + \def\strc_floats_start_place_indeed[#settings][#userdata]% {\strc_floats_reset_variables - \edef\savedfloatlocation{\floatcaptionparameter\c!location}% + % save + \edef\m_location {\floatcaptionparameter\c!location}% + \edef\m_topoffset {\floatcaptionparameter\c!topoffset}% + \edef\m_bottomoffset{\floatcaptionparameter\c!bottomoffset}% + \edef\m_freeregion {\floatcaptionparameter\c!freeregion}% + % preset + \letfloatcaptionparameter \c!location \empty \setexpandedfloatcaptionparameter\c!topoffset {\floatparameter\c!topoffset}% \setexpandedfloatcaptionparameter\c!bottomoffset{\floatparameter\c!bottomoffset}% \setexpandedfloatcaptionparameter\c!freeregion {\floatparameter\c!freeregion}% - \setupcurrentfloatcaption[\c!location=,\c!reference=,\c!title=,\c!marking=,\c!list=,\c!bookmark=,#settings]% - \setexpandedfloatparameter\c!topoffset {\floatcaptionparameter\c!topoffset}% - \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}% - \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}% - \def\m_strc_floats_saved_userdata{#2}% + \letfloatcaptionparameter \c!reference \empty + \letfloatcaptionparameter \c!title \empty + \letfloatcaptionparameter \c!marking \empty + \letfloatcaptionparameter \c!list \empty + \letfloatcaptionparameter \c!bookmark \empty + % pickup + \setupcurrentfloatcaption[#settings]% + \ifsecondargument + \setupcurrentfloatuserdata[#userdata]% + \def\m_strc_floats_saved_userdata{#userdata}% + \else + \let\m_strc_floats_saved_userdata\empty + \fi + % check \edef\floatlocation{\floatcaptionparameter\c!location}% - \setfloatcaptionparameter\c!location{\savedfloatlocation}% not expanded \ifx\floatlocation\empty \edef\floatlocation{\floatparameter\c!default}% \fi - \ifsecondargument - \setupcurrentfloatuserdata[#userdata]% - \fi + % inherit + \setexpandedfloatparameter\c!topoffset {\floatcaptionparameter\c!topoffset}% + \setexpandedfloatparameter\c!bottomoffset{\floatcaptionparameter\c!bottomoffset}% + \setexpandedfloatparameter\c!freeregion {\floatcaptionparameter\c!freeregion}% + % restore + \letfloatcaptionparameter\c!location \m_location + \letfloatcaptionparameter\c!topoffset \m_topoffset + \letfloatcaptionparameter\c!bottomoffset\m_bottomoffset + \letfloatcaptionparameter\c!freeregion \m_freeregion + % \strc_floats_analyze_location \doifelseinset\v!split\floatlocation\strc_floats_place_next_box_split\strc_floats_place_next_box_normal \bgroup @@ -928,9 +986,9 @@ \def\strc_floats_place_packaged_boxes_indeed#userdata% {\bgroup \ifconditional\usesamefloatnumber - \globallet\currentfloatnumber \previousfloatnumber - \globallet\currentfloatattribute \empty - \globallet\currentfloatsynchronize\relax + \glet\currentfloatnumber \previousfloatnumber + \glet\currentfloatattribute \empty + \glet\currentfloatsynchronize\relax \else \edef\currentfloatcounter{\namedcounterparameter\currentfloat\s!name}% \edef\currentfloatgroup {\floatcaptionparameter\c!group}% @@ -962,10 +1020,10 @@ \s!hasnumber=\ifnofloatnumber \v!no\else\v!yes\fi,% \s!hastitle=\ifemptyfloatcaption\v!no\else\v!yes\fi]% [#userdata]% - \globallet\previousfloatnumber \m_strc_counters_last_registered_index - \globallet\currentfloatnumber \m_strc_counters_last_registered_index - \globallet\currentfloatattribute \m_strc_counters_last_registered_attribute - \globallet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize + \glet\previousfloatnumber \m_strc_counters_last_registered_index + \glet\currentfloatnumber \m_strc_counters_last_registered_index + \glet\currentfloatattribute \m_strc_counters_last_registered_attribute + \glet\currentfloatsynchronize\m_strc_counters_last_registered_synchronize \fi % \global\setfalse\usesamefloatnumber % one shot @@ -1191,11 +1249,11 @@ {\global\setbox\floatbox\hpack to \scratchwidth {\doifnotinset\v!right\floatlocation\hss \box\floatbox - \doifnotinset\v!left \floatlocation\hss}} + \doifnotinset\v!left\floatlocation\hss}} -\def\strc_floats_realign_floatbox_horizontal_two +\def\strc_floats_realign_floatbox_horizontal_two % why is this {\global\setbox\floatbox\hpack to \scratchwidth - {\doifnot{\floatparameter\c!location}\v!left \hss + {\doifnot{\floatparameter\c!location}\v!left\hss \box\floatbox \doifnot{\floatparameter\c!location}\v!right\hss}} @@ -1336,7 +1394,7 @@ % % \def\strc_floats_align_content_indeed % {\alignstrutmode\zerocount -% \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} +% \doifnotcommon\floatcaptionlocation{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} % {\shiftalignedline % {\floatparameter\c!leftmargin }{\floatparameter\c!rightmargin}% % {\floatparameter\c!innermargin}{\floatparameter\c!outermargin}}% @@ -1371,7 +1429,7 @@ \def\strc_floats_align_content_indeed {\alignstrutmode\zerocount \ifx\forcedfloatmethod\v!local \else - \doifnotcommon{\floatcaptionparameter\c!location}{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} + \doifnotcommon\floatcaptionlocation{\v!outermargin,\v!innermargin,\v!leftmargin,\v!rightmargin} {\strc_floats_shift_indeed\floatparameter}% \expandafter\strc_floats_align_indeed \fi} @@ -1462,23 +1520,21 @@ \fi\fi \strc_floats_align_content{\copy\b_strc_floats_content}}} + \def\strc_floats_prepare_page_caption - {\edef\p_strc_floats_caption_location{\floatcaptionparameter\c!location}% - \edef\p_strc_floats_caption_width {\floatcaptionparameter\c!width}% + {\edef\p_strc_floats_caption_width {\floatcaptionparameter\c!width}% \edef\p_strc_floats_caption_minwidth{\floatcaptionparameter\c!minwidth}% \edef\p_strc_floats_caption_align {\floatcaptionparameter\c!align}% \dostarttagged\t!floatcaption\empty - \ifx\p_strc_floats_caption_location\v!top - \strc_floats_prepare_page_caption_top_bottom - \else\ifx\p_strc_floats_caption_location\v!bottom - \strc_floats_prepare_page_caption_top_bottom - \else\ifx\p_strc_floats_caption_width\v!fit - \strc_floats_prepare_side_auto_caption - \else\ifx\p_strc_floats_caption_width\v!max - \strc_floats_prepare_side_auto_caption - \else - \strc_floats_prepare_side_width_caption - \fi\fi\fi\fi + \doifcommonelse\floatcaptionlocation{\v!top,\v!bottom} + {\strc_floats_prepare_page_caption_top_bottom} + {\ifx\p_strc_floats_caption_width\v!fit + \strc_floats_prepare_side_auto_caption + \else\ifx\p_strc_floats_caption_width\v!max + \strc_floats_prepare_side_auto_caption + \else + \strc_floats_prepare_side_width_caption + \fi\fi}% \dostoptagged} \def\strc_floats_prepare_page_caption_top_bottom @@ -1508,7 +1564,11 @@ \fi} \def\strc_floats_caption_set_align - {\normalexpanded{\setupalign[\v!reset,\p_strc_floats_caption_align]}} + {\edef\m_align{\v!reset\ifx\p_strc_floats_caption_align\empty\else,\fi\p_strc_floats_caption_align}% + \doifinset\v!tolerant \floatcaptionlocation{\edef\m_align{\m_align,\v!tolerant}}% + \doifinset\v!verytolerant\floatcaptionlocation{\edef\m_align{\m_align,\v!verytolerant}}% + \doifinset\v!stretch \floatcaptionlocation{\edef\m_align{\m_align,\v!stretch}}% + \setupalign[\m_align]} \def\strc_floats_prepare_side_auto_caption {\scratchdimen\dimexpr\hsize-\wd\b_strc_floats_content-\floatparameter\c!margin\relax @@ -1640,7 +1700,7 @@ {\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi % skip, no pack {\d_strc_float_temp_height\ht\b_strc_floats_content \box\b_strc_floats_content - \doifnotinset\v!hang{\floatcaptionparameter\c!location} + \doifnotinset\v!hang\floatcaptionlocation {\dotfskip{\floatcaptionparameter\c!distance}}% \vbox to\d_strc_float_temp_height{#1}}} @@ -1648,7 +1708,7 @@ {\ifconditional\c_strc_floats_par_float \hbox \else \expandafter \strc_floats_align_content \fi % skip, no pack {\d_strc_float_temp_height\ht\b_strc_floats_content \vbox to\d_strc_float_temp_height{#1}% - \doifnotinset\v!hang{\floatcaptionparameter\c!location} + \doifnotinset\v!hang\floatcaptionlocation {\dotfskip{\floatcaptionparameter\c!distance}}% \box\b_strc_floats_content}} @@ -1718,7 +1778,7 @@ \def\strc_floats_build_box_next % beware, we first check on left/rightmargin because there can be left/right also {\let\next\strc_floats_build_box_next_left - \processallactionsinset[\floatcaptionparameter\c!location] + \processallactionsinset[\floatcaptionlocation] [ \v!outermargin=>\let\next\strc_floats_build_box_next_outer_margin, \v!innermargin=>\let\next\strc_floats_build_box_next_inner_margin, \v!leftmargin=>\let\next\strc_floats_build_box_next_left_margin, @@ -1736,7 +1796,7 @@ \let\next\strc_floats_build_box_high \else \let\next\strc_floats_build_box_middle - \processallactionsinset[\floatcaptionparameter\c!location] + \processallactionsinset[\floatcaptionlocation] [ \v!low=>\let\next\strc_floats_build_box_low, \v!middle=>\let\next\strc_floats_build_box_middle, \v!high=>\let\next\strc_floats_build_box_high]% @@ -1749,14 +1809,13 @@ \def\strc_floats_flush_left_caption_hang {\hsmash{\llap{\box\b_strc_floats_caption\dotfskip{\floatcaptionparameter\c!distance}}}} -\def\strc_floats_flush_caption_hang % expanded can go - {\edef\p_strc_floats_caption_location{\floatcaptionparameter\c!location}% - \doifelseinset\v!righthanging\p_strc_floats_caption_location +\def\strc_floats_flush_caption_hang + {\doifelseinset\v!righthanging\floatcaptionlocation {\strc_floats_flush_right_caption_hang} - {\doifelseinset\v!lefthanging\p_strc_floats_caption_location + {\doifelseinset\v!lefthanging\floatcaptionlocation {\strc_floats_flush_left_caption_hang} - {\doifelseinset\v!hang\p_strc_floats_caption_location - {\doifelseinset\v!outer\p_strc_floats_caption_location + {\doifelseinset\v!hang\floatcaptionlocation + {\doifelseinset\v!outer\floatcaptionlocation {\doifelserightpagefloat{\strc_floats_flush_right_caption_hang}{\strc_floats_flush_left_caption_hang}} {\doifelseinset\v!right\floatcaptiondirectives {\strc_floats_flush_right_caption_hang} @@ -1834,6 +1893,7 @@ {\dp\b_strc_floats_caption\strutdepth \setbox\scratchbox\vbox {\d_strc_float_temp_width\wd\b_strc_floats_content + \hsize\d_strc_float_temp_width \ifconditional\c_strc_floats_par_float \strc_floats_locate_side_float{\box\b_strc_floats_caption}% \vss\strc_floats_between_stack @@ -1845,12 +1905,13 @@ \strc_floats_align_content{\box\b_strc_floats_content}% \fi}% \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy - \vbox to \noflines\lineheight{\unvbox\scratchbox}} % \vpack ? + \vpack to \noflines\lineheight{\unvbox\scratchbox}} \def\strc_floats_build_box_bottom_stack_grid {\dp\b_strc_floats_caption\strutdepth \setbox\scratchbox\vbox {\d_strc_float_temp_width\wd\b_strc_floats_content + \hsize\d_strc_float_temp_width \ifconditional\c_strc_floats_par_float \hpack{\box\b_strc_floats_content}% \vss\strc_floats_between_stack @@ -1862,7 +1923,7 @@ \strc_floats_locate_text_float{\box\b_strc_floats_caption}% \fi}% \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy - \vbox to \noflines\lineheight{\unvbox\scratchbox}} % \vpack ? + \vpack to \noflines\lineheight{\unvbox\scratchbox}} \def\strc_floats_build_box_top_stack_stretch {\dp\b_strc_floats_caption\strutdepth @@ -1872,6 +1933,7 @@ \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy \vbox to \noflines\lineheight % pack ? {\d_strc_float_temp_width\wd\b_strc_floats_content + \hsize\d_strc_float_temp_width \ifconditional\c_strc_floats_par_float \strc_floats_locate_side_float{\box\b_strc_floats_caption}% \vss\strc_floats_between_stack\vss @@ -1885,16 +1947,17 @@ \def\strc_floats_build_box_bottom_stack_stretch {\dp\b_strc_floats_caption\strutdepth - \setbox\scratchbox\vbox % pack ? - {\strc_floats_align_content{\copy\b_strc_floats_content }% + \setbox\scratchbox\vpack + {\strc_floats_align_content{\copy\b_strc_floats_content}% \strc_floats_align_caption{\copy\b_strc_floats_caption}}% \getnoflines{\dimexpr\htdp\scratchbox-10\scaledpoint\relax}% get rid of inaccuracy \vbox to \noflines\lineheight {\d_strc_float_temp_width\wd\b_strc_floats_content + \hsize\d_strc_float_temp_width \ifconditional\c_strc_floats_par_float \hpack{\box\b_strc_floats_content}% \vss\strc_floats_between_stack\vss - \strc_floats_locate_side_float{\box\b_strc_floats_caption} + \strc_floats_locate_side_float{\box\b_strc_floats_caption}% \else \page_otr_command_set_float_hsize \strc_floats_align_content{\box\b_strc_floats_content}% @@ -1906,14 +1969,14 @@ {\let\next\strc_floats_build_box_top_stack_normal \processfirstactioninset[\floatcaptionparameter\c!location] [ \v!grid=>\let\next\strc_floats_build_box_top_stack_grid, - \v!stretch=>\let\next\strc_floats_build_box_top_stack_stretch]% + \v!lines=>\let\next\strc_floats_build_box_top_stack_stretch]% was \v!grid but interfered \next} \def\strc_floats_build_box_bottom {\let\next\strc_floats_build_box_bottom_stack_normal \processfirstactioninset[\floatcaptionparameter\c!location] [ \v!grid=>\let\next\strc_floats_build_box_bottom_stack_grid, - \v!stretch=>\let\next\strc_floats_build_box_bottom_stack_stretch]% + \v!lines=>\let\next\strc_floats_build_box_bottom_stack_stretch]% was \v!grid but interfered \next} \def\strc_floats_relocate_caption_right#1{\strc_floats_align_caption{\hbox to \d_strc_float_temp_width{\hss#1}}} @@ -1921,23 +1984,50 @@ \unexpanded\def\installfloatboxbuilder#1#2{\setvalue{\??floatbuilder#1}{#2}} -\let\strc_floats_mark_box_as_free\relax - \def\strc_floats_build_box - {\global\setbox\floatbox\vbox % pack ? probably not + {\strc_floats_build_box_before + \global\setbox\floatbox\vbox % pack ? probably not {\strc_floats_set_local_hsize \forgetall \ifconditional\c_floats_store_minimal_package \strc_floats_build_box_separate_make \else - \let\floatcaptionarrangement\s!default + % \let\floatcaptionarrangement\s!default + \let\floatcaptionarrangement\v!bottom % for Alan \processcommacommand[\floatcaptionparameter\c!location]\strc_floats_build_box_step \ifcsname\??floatbuilder\floatcaptionarrangement\endcsname \lastnamedcs \else \strc_floats_build_box_default \fi - \fi}} + \fi}% + \strc_floats_build_box_after} + +% \let\strc_floats_build_box_before\relax +% \let\strc_floats_build_box_after \relax + +\def\strc_floats_build_box_before + {\let\currentfloatframed\currentfloat + \floatwidth\wd + \ifdim\wd\b_strc_floats_content>\wd\b_strc_floats_caption + \b_strc_floats_content\else\b_strc_floats_caption + \fi} + +\def\strc_floats_build_box_after + {\doifelseframed\floatframedparameter\strc_floats_build_box_after_indeed\relax} + +\def\strc_floats_build_box_after_indeed + {\global\setbox\floatbox\hpack + {\edef\m_width{\floatframedparameter\c!width}% + \ifx\m_width\v!fit + \let\m_width\floatwidth + \else\ifx\m_width\v!broad + \let\m_width\v!fit + \fi\fi + \letfloatframedparameter\c!strut\v!no + \letfloatframedparameter\c!width\m_width + \inheritedfloatframedframed + {\box\floatbox}}} % special purpose: used in floatcombinations @@ -1954,7 +2044,7 @@ \vpack to \onepoint{\box\b_strc_floats_caption}} \def\strc_floats_build_box_separate_split#1% - {\setbox\scratchbox\vbox{% + {\setbox\scratchbox\vbox\bgroup \setbox\scratchbox\vpack{#1}% \unvbox\scratchbox\relax \setbox\scratchbox\lastbox @@ -1965,13 +2055,20 @@ \unvbox\scratchbox \setbox\scratchbox\lastbox % \exitloop - % \fi}% + % \fi + %}% \splittopskip\zeropoint \global\setbox\b_strc_floats_separate_content\vsplit\scratchbox to \onepoint \global\setbox\b_strc_floats_separate_caption\vsplit\scratchbox to \onepoint - \global\setbox\b_strc_floats_separate_content\vpack{\unvbox\b_strc_floats_separate_content\setbox0\lastbox\unvbox0}% - \global\setbox\b_strc_floats_separate_caption\tpack{\unvbox\b_strc_floats_separate_caption\setbox0\lastbox\unvbox0}% - }} + \egroup + \global\setbox\b_strc_floats_separate_content\vpack + {\unvbox\b_strc_floats_separate_content + \setbox\scratchbox\lastbox + \unvbox\scratchbox}% + \global\setbox\b_strc_floats_separate_caption\tpack + {\unvbox\b_strc_floats_separate_caption + \setbox\scratchbox\lastbox + \unvbox\scratchbox}} % \def\strc_floats_build_box_step#1% % {\doifdefined{\??floatbuilder#1}{\def\floatcaptionarrangement{#1}\quitcommalist}} @@ -2105,8 +2202,9 @@ \def\strc_floats_prepare_side_caption_fit % or center when smaller {\ifdim\wd\b_strc_floats_caption>\wd\b_strc_floats_content\relax - \setbox\b_strc_floats_caption\vbox + \setbox\b_strc_floats_caption\vbox {\forgetall % needed? + \strc_floats_caption_set_align \hsize\wd\b_strc_floats_content \strc_floats_make_complete_caption}% \else @@ -2295,6 +2393,8 @@ \definesystemconstant{fxbt} \definesystemconstant{fixd} +% can move to page-one: + \installfloatmethod \s!singlecolumn \v!here \page_one_place_float_here \installfloatmethod \s!singlecolumn \v!force \page_one_place_float_force \installfloatmethod \s!singlecolumn \v!left \page_one_place_float_left @@ -2330,76 +2430,6 @@ \installfloatmethod \s!singlecolumn \s!fxbt \page_one_place_float_bottom \installfloatmethod \s!singlecolumn \s!fixd \page_one_place_float_force -\installfloatmethod \s!multicolumn \v!here \page_mul_place_float_here -\installfloatmethod \s!multicolumn \v!force \page_mul_place_float_force -%installfloatmethod \s!multicolumn \v!left -%installfloatmethod \s!multicolumn \v!right -%installfloatmethod \s!multicolumn \v!text -\installfloatmethod \s!multicolumn \v!top \page_mul_place_float_top -\installfloatmethod \s!multicolumn \v!bottom \page_mul_place_float_bottom -%installfloatmethod \s!multicolumn \v!auto -%installfloatmethod \s!multicolumn \v!margin -%installfloatmethod \s!multicolumn \v!opposite -%installfloatmethod \s!multicolumn \v!page -%installfloatmethod \s!multicolumn \v!leftpage -%installfloatmethod \s!multicolumn \v!rightpage -%installfloatmethod \s!multicolumn \v!inmargin -%installfloatmethod \s!multicolumn \v!inleft -%installfloatmethod \s!multicolumn \v!inright -%installfloatmethod \s!multicolumn \v!leftmargin -%installfloatmethod \s!multicolumn \v!rightmargin -%installfloatmethod \s!multicolumn \v!leftedge -%installfloatmethod \s!multicolumn \v!rightedge -%installfloatmethod \s!multicolumn \v!somewhere -%installfloatmethod \s!multicolumn \v!backspace -%installfloatmethod \s!multicolumn \v!cutspace -%installfloatmethod \s!multicolumn \s!tblr -%installfloatmethod \s!multicolumn \s!lrtb -%installfloatmethod \s!multicolumn \s!tbrl -%installfloatmethod \s!multicolumn \s!rltb -%installfloatmethod \s!multicolumn \s!fxtb -%installfloatmethod \s!multicolumn \s!btlr -%installfloatmethod \s!multicolumn \s!lrbt -%installfloatmethod \s!multicolumn \s!btrl -%installfloatmethod \s!multicolumn \s!rlbt -%installfloatmethod \s!multicolumn \s!fxbt -%installfloatmethod \s!multicolumn \s!fixd - -\installfloatmethod \s!columnset \v!here \page_set_place_float_here -\installfloatmethod \s!columnset \v!force \page_set_place_float_force -%installfloatmethod \s!columnset \v!left -%installfloatmethod \s!columnset \v!right -%installfloatmethod \s!columnset \v!text -\installfloatmethod \s!columnset \v!top \page_set_place_float_top -\installfloatmethod \s!columnset \v!bottom \page_set_place_float_bottom -%installfloatmethod \s!columnset \v!auto -%installfloatmethod \s!columnset \v!margin -%installfloatmethod \s!columnset \v!opposite -\installfloatmethod \s!columnset \v!page \page_set_place_float_page -%installfloatmethod \s!columnset \v!leftpage -%installfloatmethod \s!columnset \v!rightpage -%installfloatmethod \s!columnset \v!inmargin -%installfloatmethod \s!columnset \v!inleft -%installfloatmethod \s!columnset \v!inright -%installfloatmethod \s!columnset \v!leftmargin -%installfloatmethod \s!columnset \v!rightmargin -%installfloatmethod \s!columnset \v!leftedge -%installfloatmethod \s!columnset \v!rightedge -%installfloatmethod \s!columnset \v!somewhere -%installfloatmethod \s!columnset \v!backspace -%installfloatmethod \s!columnset \v!cutspace -\installfloatmethod \s!columnset \s!tblr \page_set_place_float_slot -\installfloatmethod \s!columnset \s!lrtb \page_set_place_float_slot -\installfloatmethod \s!columnset \s!tbrl \page_set_place_float_slot -\installfloatmethod \s!columnset \s!rltb \page_set_place_float_slot -\installfloatmethod \s!columnset \s!fxtb \page_set_place_float_slot -\installfloatmethod \s!columnset \s!btlr \page_set_place_float_slot -\installfloatmethod \s!columnset \s!lrbt \page_set_place_float_slot -\installfloatmethod \s!columnset \s!btrl \page_set_place_float_slot -\installfloatmethod \s!columnset \s!rlbt \page_set_place_float_slot -\installfloatmethod \s!columnset \s!fxbt \page_set_place_float_slot -\installfloatmethod \s!columnset \s!fixd \page_set_place_float_force - %D Local floats: \installcorenamespace{localfloats} diff --git a/tex/context/base/mkiv/strc-itm.mkvi b/tex/context/base/mkiv/strc-itm.mkvi index 0bea62de8..0fc204320 100644 --- a/tex/context/base/mkiv/strc-itm.mkvi +++ b/tex/context/base/mkiv/strc-itm.mkvi @@ -352,8 +352,8 @@ \csname\??itemgroupsetting\currentitemgroup\endcsname} \def\strc_itemgroups_reset_continue_state - {\global\expandafter\let\csname\??itemgroupoption \currentitemgroup\endcsname\relax - \global\expandafter\let\csname\??itemgroupsetting\currentitemgroup\endcsname\relax} + {\expandafter\glet\csname\??itemgroupoption \currentitemgroup\endcsname\relax + \expandafter\glet\csname\??itemgroupsetting\currentitemgroup\endcsname\relax} % These will become keywords. We will also add a feature to keep the while set % together. diff --git a/tex/context/base/mkiv/strc-lnt.mkvi b/tex/context/base/mkiv/strc-lnt.mkvi index cd10c9def..4a6f14245 100644 --- a/tex/context/base/mkiv/strc-lnt.mkvi +++ b/tex/context/base/mkiv/strc-lnt.mkvi @@ -242,13 +242,13 @@ \def\strc_linenotes_traced_indeed#1% {\iftracelinenotes - \hbox to \zeropoint + \hpack to \zeropoint {\forgetall \hsize\zeropoint \hss - \vbox to \strutheight{\llap{\red\infofont\setstrut\the\c_strc_linenotes}\vss}% + \vpack to \strutheight{\llap{\red\infofont\setstrut\the\c_strc_linenotes}\vss}% {\color[blue]{\vl}}% - \vbox to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}% + \vpack to \strutheight{\rlap{\red\infofont\setstrut#1}\vss}% \hss}% \prewordbreak \fi} diff --git a/tex/context/base/mkiv/strc-lst.lua b/tex/context/base/mkiv/strc-lst.lua index 13bdf7786..bc6135e72 100644 --- a/tex/context/base/mkiv/strc-lst.lua +++ b/tex/context/base/mkiv/strc-lst.lua @@ -35,6 +35,8 @@ local commands = commands local implement = interfaces.implement local conditionals = tex.conditionals +local ctx_latelua = context.latelua + local structures = structures local lists = structures.lists local sections = structures.sections @@ -97,7 +99,8 @@ local v_default = variables.default -- for the moment not public -- local function zerostrippedconcat(t,separator) - local f, l = 1, #t + local f = 1 + local l = #t for i=f,l do if t[i] == 0 then f = f + 1 @@ -307,7 +310,8 @@ local synchronizepage = function(r) -- bah ... will move return synchronizepage(r) end -function lists.enhance(n) +local function enhancelist(specification) + local n = specification.n local l = cached[n] if not l then report_lists("enhancing %a, unknown internal",n) @@ -348,6 +352,8 @@ function lists.enhance(n) end end +lists.enhance = enhancelist + -- we can use level instead but we can also decide to remove level from the metadata local nesting = { } @@ -847,18 +853,22 @@ end function lists.userdata(name,r,tag) -- to tex (todo: xml) local result = lists.result[r] if result then - local userdata, metadata = result.userdata, result.metadata + local userdata = result.userdata local str = userdata and userdata[tag] if str then - return str, metadata + return str, result.metadata end end end function lists.uservalue(name,r,tag,default) -- to lua local str = lists.result[r] - str = str and str.userdata - str = str and str[tag] + if str then + str = str.userdata + end + if str then + str = str[tag] + end return str or default end @@ -1071,8 +1081,19 @@ implement { implement { name = "enhancelist", - actions = lists.enhance, - arguments = "integer" + arguments = "integer", + actions = function(n) + enhancelist { n = n } + end +} + +implement { + name = "deferredenhancelist", + arguments = "integer", + protected = true, -- for now, pre 1.09 + actions = function(n) + ctx_latelua { action = enhancelist, n = n } + end, } implement { diff --git a/tex/context/base/mkiv/strc-lst.mkvi b/tex/context/base/mkiv/strc-lst.mkvi index 153d879b7..7bc859b67 100644 --- a/tex/context/base/mkiv/strc-lst.mkvi +++ b/tex/context/base/mkiv/strc-lst.mkvi @@ -145,8 +145,9 @@ {\endgroup} % \unexpanded -\def\strc_lists_inject_enhance#listindex#internal% - {\normalexpanded{\ctxlatecommand{enhancelist(\number#listindex)}}} + +\def\strc_lists_inject_enhance#listindex% + {\expandafter\clf_deferredenhancelist\number#listindex\relax} \unexpanded\def\strc_lists_inject_yes[#settings][#userdata]% can be used directly {\setupcurrentlist[\c!type=userdata,\c!location=\v!none,#settings]% grouped (use \let... @@ -168,16 +169,16 @@ userdata {\detokenize\expandafter{\normalexpanded{#userdata}}} \relax \edef\currentlistnumber{\the\scratchcounter}% -\setxvalue{\??listlocations\currentlist}{\the\locationcount}% + \setxvalue{\??listlocations\currentlist}{\the\locationcount}% \ifx\p_location\v!here % this branch injects nodes ! - \strc_lists_inject_enhance{\currentlistnumber}{\the\locationcount}% + \strc_lists_inject_enhance{\currentlistnumber}% \clf_setinternalreference internal \locationcount view {\interactionparameter\c!focus}% \relax % this will change \xdef\currentstructurelistattribute{\the\lastdestinationattribute}% - \dontleavehmode\hbox attr \destinationattribute \lastdestinationattribute{}% todo + \dontleavehmode\hpack attr \destinationattribute \lastdestinationattribute{}% todo \else % and this one doesn't \clf_enhancelist\currentlistnumber\relax @@ -467,7 +468,7 @@ \relax} \def\firststructureelementinlist#list% expandable - {\clf_firstinset{#list}} + {\firstinset{#list}} \def\structurelistsize {\clf_listsize} @@ -871,7 +872,7 @@ \appendtoks \dontcomplain - \letinteractionparameter\c!width\zeropoint % a weird one + % \letinteractionparameter\c!width\zeropoint % a weird one \to \t_lists_every_renderingsetup \appendtoks @@ -1091,7 +1092,7 @@ \fi \ifconditional\c_lists_has_page \ifconditional\c_lists_show_page - \setbox\b_strc_lists_page\hbox { + \setbox\b_strc_lists_page\hpack { \scratchdimen\listalternativeparameter\c!width \hbox \strc_lists_get_reference_attribute\v!pagenumber \ifdim\scratchdimen>\zeropoint to \scratchdimen\fi { \hfill diff --git a/tex/context/base/mkiv/strc-mar.lua b/tex/context/base/mkiv/strc-mar.lua index 24a7fd491..0221b9b8f 100644 --- a/tex/context/base/mkiv/strc-mar.lua +++ b/tex/context/base/mkiv/strc-mar.lua @@ -13,78 +13,82 @@ local insert, concat = table.insert, table.concat local tostring, next, rawget, type = tostring, next, rawget, type local lpegmatch = lpeg.match -local context = context -local commands = commands +local context = context +local commands = commands -local implement = interfaces.implement +local implement = interfaces.implement -local allocate = utilities.storage.allocate -local setmetatableindex = table.setmetatableindex +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex -local nuts = nodes.nuts -local tonut = nuts.tonut +local nuts = nodes.nuts +local tonut = nuts.tonut -local getid = nuts.getid -local getlist = nuts.getlist -local getattr = nuts.getattr -local getbox = nuts.getbox +local getid = nuts.getid +local getlist = nuts.getlist +local getattr = nuts.getattr +local getbox = nuts.getbox -local traverse = nuts.traverse -local traverse_id = nuts.traverse_id +local nextnode = nuts.traversers.node -local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist +local nodecodes = nodes.nodecodes +local whatsitcodes = nodes.whatsitcodes -local texsetattribute = tex.setattribute +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local whatsit_code = nodecodes.whatsit -local a_marks = attributes.private("structure","marks") +local lateluawhatsit_code = whatsitcodes.latelua -local trace_marks_set = false trackers.register("marks.set", function(v) trace_marks_set = v end) -local trace_marks_get = false trackers.register("marks.get", function(v) trace_marks_get = v end) -local trace_marks_all = false trackers.register("marks.detail", function(v) trace_marks_all = v end) +local texsetattribute = tex.setattribute -local report_marks = logs.reporter("structure","marks") +local a_marks = attributes.private("structure","marks") -local variables = interfaces.variables +local trace_marks_set = false trackers.register("marks.set", function(v) trace_marks_set = v end) +local trace_marks_get = false trackers.register("marks.get", function(v) trace_marks_get = v end) +local trace_marks_all = false trackers.register("marks.detail", function(v) trace_marks_all = v end) -local v_first = variables.first -local v_last = variables.last -local v_previous = variables.previous -local v_next = variables.next -local v_top = variables.top -local v_bottom = variables.bottom -local v_current = variables.current -local v_default = variables.default -local v_page = variables.page -local v_all = variables.all -local v_keep = variables.keep +local report_marks = logs.reporter("structure","marks") -local v_nocheck_suffix = ":" .. variables.nocheck +local variables = interfaces.variables -local v_first_nocheck = variables.first .. v_nocheck_suffix -local v_last_nocheck = variables.last .. v_nocheck_suffix -local v_previous_nocheck = variables.previous .. v_nocheck_suffix -local v_next_nocheck = variables.next .. v_nocheck_suffix -local v_top_nocheck = variables.top .. v_nocheck_suffix -local v_bottom_nocheck = variables.bottom .. v_nocheck_suffix +local v_first = variables.first +local v_last = variables.last +local v_previous = variables.previous +local v_next = variables.next +local v_top = variables.top +local v_bottom = variables.bottom +local v_current = variables.current +local v_default = variables.default +local v_page = variables.page +local v_all = variables.all +local v_keep = variables.keep -local structures = structures -local marks = structures.marks -local lists = structures.lists +local v_nocheck_suffix = ":" .. variables.nocheck -local settings_to_array = utilities.parsers.settings_to_array +local v_first_nocheck = variables.first .. v_nocheck_suffix +local v_last_nocheck = variables.last .. v_nocheck_suffix +local v_previous_nocheck = variables.previous .. v_nocheck_suffix +local v_next_nocheck = variables.next .. v_nocheck_suffix +local v_top_nocheck = variables.top .. v_nocheck_suffix +local v_bottom_nocheck = variables.bottom .. v_nocheck_suffix -local boxes_too = false -- at some point we can also tag boxes or use a zero char +local structures = structures +local marks = structures.marks +local lists = structures.lists + +local settings_to_array = utilities.parsers.settings_to_array + +local boxes_too = false -- at some point we can also tag boxes or use a zero char directives.register("marks.boxestoo", function(v) boxes_too = v end) -marks.data = marks.data or allocate() +local data = marks.data or allocate() +marks.data = data storage.register("structures/marks/data", marks.data, "structures.marks.data") -local data = marks.data local stack, topofstack = { }, 0 local ranges = { @@ -116,9 +120,9 @@ end -- identify range local function sweep(head,first,last) - for n in traverse(head) do - local id = getid(n) - if id == glyph_code then + for n, id, subtype in nextnode, head do + -- we need to handle empty heads so we test for latelua + if id == glyph_code or (id == whatsit_code and subtype == lateluawhatsit_code) then local a = getattr(n,a_marks) if not a then -- next @@ -433,7 +437,8 @@ local function resolve(name,first,last,strict,quitonfalse,notrace) if trace_marks_get and not notrace then report_marks("found chain [ % => T ]",fullchain) end - local chaindata, chainlength = { }, #fullchain + local chaindata = { } + local chainlength = #fullchain for i=1,chainlength do local cname = fullchain[i] if data[cname].set > 0 then @@ -509,7 +514,8 @@ local methods = { } local function doresolve(name,rangename,swap,df,dl,strict) local range = ranges[rangename] or ranges[v_page] - local first, last = range.first, range.last + local first = range.first + local last = range.last if trace_marks_get then report_marks("action %a, name %a, range %a, swap %a, first %a, last %a, df %a, dl %a, strict %a", "resolving",name,rangename,swap or false,first,last,df,dl,strict or false) @@ -638,7 +644,10 @@ function marks.tracers.showtable() context.tabulaterowbold("name","parent","chain","children","fullchain") context.ML() for k, v in table.sortedpairs(data) do - local parent, chain, children, fullchain = v.parent or "", v.chain or "", v.children or { }, v.fullchain or { } + local parent = v.parent or "" + local chain = v.chain or "" + local children = v.children or { } + local fullchain = v.fullchain or { } table.sort(children) -- in-place but harmless context.tabulaterowtyp(k,parent,chain,concat(children," "),concat(fullchain," ")) end @@ -647,28 +656,49 @@ end -- pushing to context: -local separator = context.nested.markingseparator -local command = context.nested.markingcommand -local ctxconcat = context.concat - -local function fetchonemark(name,range,method) - context(command(name,fetched(name,range,method))) -end +-- local separator = context.nested.markingseparator +-- local command = context.nested.markingcommand +-- local ctxconcat = context.concat + +-- local function fetchonemark(name,range,method) +-- context(command(name,fetched(name,range,method))) +-- end + +-- local function fetchtwomarks(name,range) +-- ctxconcat( { +-- command(name,fetched(name,range,v_first)), +-- command(name,fetched(name,range,v_last)), +-- }, separator(name)) +-- end + +-- local function fetchallmarks(name,range) +-- ctxconcat( { +-- command(name,fetched(name,range,v_previous)), +-- command(name,fetched(name,range,v_first)), +-- command(name,fetched(name,range,v_last)), +-- }, separator(name)) +-- end + + local ctx_separator = context.markingseparator + local ctx_command = context.markingcommand + + local function fetchonemark(name,range,method) + ctx_command(name,fetched(name,range,method)) + end -local function fetchtwomarks(name,range) - ctxconcat( { - command(name,fetched(name,range,v_first)), - command(name,fetched(name,range,v_last)), - }, separator(name)) -end + local function fetchtwomarks(name,range) + ctx_command(name,fetched(name,range,v_first)) + ctx_separator(name) + ctx_command(name,fetched(name,range,v_last)) + end -local function fetchallmarks(name,range) - ctxconcat( { - command(name,fetched(name,range,v_previous)), - command(name,fetched(name,range,v_first)), - command(name,fetched(name,range,v_last)), - }, separator(name)) -end + local function fetchallmarks(name,range) + ctx_command(name,fetched(name,range,v_previous)) + ctx_separator(name) + ctx_command(name,fetched(name,range,v_first)) + ctx_separator(name) + ctx_command(name,fetched(name,range,v_last)) + end function marks.fetch(name,range,method) -- chapter page first | chapter column:1 first if trace_marks_get then diff --git a/tex/context/base/mkiv/strc-mat.mkiv b/tex/context/base/mkiv/strc-mat.mkiv index 775d2aca1..0b80a26cd 100644 --- a/tex/context/base/mkiv/strc-mat.mkiv +++ b/tex/context/base/mkiv/strc-mat.mkiv @@ -208,9 +208,9 @@ \c!reference=#1,\c!title=\namedformulaentry,\c!bookmark=]% [#2]% \glet\namedformulaentry\empty % \relax - \globallet#3\m_strc_counters_last_registered_index - \globallet#4\m_strc_counters_last_registered_synchronize - \globallet#5\m_strc_counters_last_registered_attribute} + \glet#3\m_strc_counters_last_registered_index + \glet#4\m_strc_counters_last_registered_synchronize + \glet#5\m_strc_counters_last_registered_attribute} % modes: 0=unset, 1=forced, 2=none, 3=reference @@ -880,6 +880,9 @@ \par \fi \bgroup % HERE + \iftrialtypesetting\else + \global\advance\c_strc_formulas_n\plusone + \fi \def\currentformula{#1}% \strc_math_set_split \dostarttaggedchained\t!formula\currentformula\??formula @@ -896,7 +899,7 @@ {\edef\p_option{\formulaparameter\c!option}% \edef\p_option{\ifx\p_option\empty\else\p_option,\fi#2}}% \else - \edef\p_option{\formulaparameter\c!option} + \edef\p_option{\formulaparameter\c!option}% \fi \ifx\p_option\empty \else \rawprocesscommacommand[\p_option]\strc_formulas_option @@ -922,10 +925,15 @@ % tagging of formulanumbers is not ok (we get two display maths blobs) +\newcount\c_strc_formulas_n + +\ifdefined\dotagregisterformula \else \let\dotagregisterformula\gobbleoneargument \fi + \unexpanded\def\strc_formulas_stop_formula {\strc_formulas_place_number % in case it hasn't happened yet \strc_formulas_flush_number % in case we are in native mode \dostarttagged\t!formulacontent\empty + \dotagregisterformula\c_strc_formulas_n \csname\e!stop\formulaparameter\c!alternative\v!formula\endcsname \dostoptagged \dostoptagged diff --git a/tex/context/base/mkiv/strc-not.lua b/tex/context/base/mkiv/strc-not.lua index bb9d64beb..b2c8106e1 100644 --- a/tex/context/base/mkiv/strc-not.lua +++ b/tex/context/base/mkiv/strc-not.lua @@ -247,15 +247,38 @@ end notes.internal = internal notes.ordered = ordered +-- local function onsamepageasprevious(tag) +-- local same = false +-- local n = getn(tag,n) +-- local current = get(tag,n) +-- local previous = get(tag,n-1) +-- if current and previous then +-- local cr = current.references +-- local pr = previous.references +-- same = cr and pr and cr.realpage == pr.realpage +-- end +-- return same and true or false +-- end + local function onsamepageasprevious(tag) - local same = false - local n = getn(tag,n) - local current, previous = get(tag,n), get(tag,n-1) - if current and previous then - local cr, pr = current.references, previous.references - same = cr and pr and cr.realpage == pr.realpage + local n = getn(tag,n) + local current = get(tag,n) + if not current then + return false + end + local cr = current.references + if not cr then + return false + end + local previous = get(tag,n-1) + if not previous then + return false + end + local pr = previous.references + if not pr then + return false end - return same and true or false + return cr.realpage == pr.realpage end notes.doifonsamepageasprevious = onsamepageasprevious @@ -471,7 +494,7 @@ local texsetglue = tex.setglue local function check_spacing(n,i) local gn, pn, mn = texgetglue(n) local gi, pi, mi = texgetglue(i > 1 and "s_strc_notes_inbetween" or "s_strc_notes_before") - local gt, pt, mt = gn+gi, pn+pi, mn+mi + local gt, pt, mt = gn + gi, pn + pi, mn + mi if trace_insert then report_insert("%s %i: %p plus %p minus %p","always ",n,gn,pn,mn) report_insert("%s %i: %p plus %p minus %p",i > 1 and "inbetween" or "before ",n,gi,pi,mi) diff --git a/tex/context/base/mkiv/strc-not.mkvi b/tex/context/base/mkiv/strc-not.mkvi index 8952f0e9c..3ce01ef34 100644 --- a/tex/context/base/mkiv/strc-not.mkvi +++ b/tex/context/base/mkiv/strc-not.mkvi @@ -456,7 +456,7 @@ \edef\currentnotenumber{\clf_storenote{\currentnote}\currentconstructionlistentry}% \settrue\processingnote \ifconditional\c_strc_notes_skip - \globallet\lastnotesymbol\strc_notes_inject_symbol_nop + \glet\lastnotesymbol\strc_notes_inject_symbol_nop \else \iftypesettinglines % otherwise problems with \type {xxx} \ignorelines % makes footnotes work in \startlines ... \stoplines @@ -465,7 +465,7 @@ \strc_notes_inject_symbol_yes \else \unskip\unskip - \globallet\lastnotesymbol\strc_notes_inject_symbol_yes + \glet\lastnotesymbol\strc_notes_inject_symbol_yes \fi \fi \ifconditional\postponingnotes % todo: per note class @@ -734,7 +734,7 @@ \dostoptagged \egroup \endgroup - \globallet\lastnotesymbol\relax} + \glet\lastnotesymbol\relax} \unexpanded\def\strc_notes_inject_dummy % temp hack {\removeunwantedspaces @@ -745,7 +745,7 @@ \fi \nobreak \hpack to .5\emwidth{}% - \globallet\lastnotesymbol\relax} + \glet\lastnotesymbol\relax} \unexpanded\def\strc_notes_inject_separator % patch by WS due to request on list {\edef\p_textseparator{\noteparameter\c!textseparator}% @@ -1057,18 +1057,6 @@ \newskip \s_strc_notes_distance % we need to implement stretch \newcount\c_strc_notes_columns -% \def\strc_notes_set_distance -% {\begingroup -% \setbox\scratchbox\vbox % no reuse as it can mirror -% {\forgetall -% \restoreglobalbodyfont % really needed -% \dontcomplain -% \noteparameter\c!before -% \placenoterule -% \noteparameter\c!after}% -% \expandafter\endgroup\expandafter -% \s_strc_notes_distance\the\htdp\scratchbox\relax} % also dp now - \newskip \s_strc_notes_before \newskip \s_strc_notes_inbetween \newconditional\c_strc_notes_first_flushed @@ -1382,19 +1370,22 @@ \fi} \appendtoks - \strc_notes_set_penalties - \forgetall % again - \strc_notes_set_bodyfont - \redoconvertfont % to undo \undo calls in in headings etc - \splittopskip\strutht % not actually needed here - \splitmaxdepth\strutdp % not actually needed here - % not: -% \leftmargindistance \noteparameter\c!margindistance -% \rightmargindistance\leftmargindistance -% \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ? -% \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ? -% \fi - % + \strc_notes_set_penalties + \forgetall % again + \strc_notes_set_bodyfont + \redoconvertfont % to undo \undo calls in in headings etc + \splittopskip\strutht % not actually needed here + \splitmaxdepth\strutdp % not actually needed here + % + % not: + % + % \leftmargindistance \noteparameter\c!margindistance + % \rightmargindistance\leftmargindistance + % \ifnum\noteparameter\c!n=\zerocount % no ifcase new 31-07-99 ; always ? + % \doifnotinset{\noteparameter\c!width}{\v!fit,\v!broad}\setnotehsize % ? + % \fi + % + \pickupattributes \to \everyinsidenoteinsert % maybe but better use [scope=local] here @@ -1551,7 +1542,7 @@ \unexpanded\def\postponenotes {\ifconditional\postponingnotes\else \global\settrue\postponingnotes - \global\let\flushnotes\doflushnotes + \glet\flushnotes\doflushnotes \clf_postponenotes \fi} @@ -1560,7 +1551,7 @@ \unexpanded\def\startpostponingnotes % experimental, page-mix {\ifconditional\postponingnotes\else \global\settrue\postponingnotes - %\global\let\flushnotes\doflushnotes + %\glet\flushnotes\doflushnotes \clf_postponenotes \fi} @@ -1581,7 +1572,7 @@ \clf_flushpostponednotes% this also resets the states ! \global\setfalse\postponednote \global\setfalse\postponingnotes - \global\let\flushnotes\relax + \glet\flushnotes\relax \endgroup \fi} diff --git a/tex/context/base/mkiv/strc-num.lua b/tex/context/base/mkiv/strc-num.lua index e1a133f4a..25e575a56 100644 --- a/tex/context/base/mkiv/strc-num.lua +++ b/tex/context/base/mkiv/strc-num.lua @@ -273,7 +273,7 @@ end function counters.compact(name,level,onlynumbers) local cd = counterdata[name] if cd then - local data = cd.data + local data = cd.data local compact = { } for i=1,level or #data do local d = data[i] @@ -541,22 +541,26 @@ function counters.converted(name,spec) -- name can be number and reference to st local cd if type(name) == "number" then cd = specials.retrieve("counter",name) - cd = cd and cd.counter + if cd then + cd = cd.counter + end else cd = counterdata[name] end if cd then - local spec = spec or { } - local numbers, ownnumbers = { }, { } - local reverse = spec.order == v_reverse - local kind = spec.type or "number" - local data = cd.data + local spec = spec or { } + local numbers = { } + local ownnumbers = { } + local reverse = spec.order == v_reverse + local kind = spec.type or "number" + local data = cd.data for k=1,#data do local v = data[k] -- somewhat messy, what if subnr? only last must honour kind? local vn if v.own then - numbers[k], ownnumbers[k] = v.number, v.own + numbers[k] = v.number + ownnumbers[k] = v.own else if kind == v_first then vn = v.first @@ -577,13 +581,14 @@ function counters.converted(name,spec) -- name can be number and reference to st end end end - numbers[k], ownnumbers[k] = vn or v.number, nil + numbers[k] = vn or v.number + ownnumbers[k] = nil end end - cd.numbers = numbers + cd.numbers = numbers cd.ownnumbers = ownnumbers sections.typesetnumber(cd,'number',spec) - cd.numbers = nil + cd.numbers = nil cd.ownnumbers = nil end end diff --git a/tex/context/base/mkiv/strc-num.mkiv b/tex/context/base/mkiv/strc-num.mkiv index be35e7671..747df29a5 100644 --- a/tex/context/base/mkiv/strc-num.mkiv +++ b/tex/context/base/mkiv/strc-num.mkiv @@ -578,9 +578,9 @@ \xdef\currentstructurecomponentlist {#2\c!list}% \xmlstopraw \ifx\currentstructurecomponentlist\empty - \globallet\currentstructurecomponentlist\currentstructurecomponenttitle + \glet\currentstructurecomponentlist\currentstructurecomponenttitle \fi - \globallet\currentstructurecomponentcoding\s!xml + \glet\currentstructurecomponentcoding\s!xml \else \ifx\currentstructurecomponentexpansion\v!yes \xdef\currentstructurecomponenttitle {#2\c!title}% @@ -600,9 +600,9 @@ \fi \fi \fi \ifx\currentstructurecomponentlist\empty - \globallet\currentstructurecomponentlist\currentstructurecomponenttitle + \glet\currentstructurecomponentlist\currentstructurecomponenttitle \fi - \globallet\currentstructurecomponentcoding\s!tex + \glet\currentstructurecomponentcoding\s!tex \fi % \setnextinternalreference @@ -669,11 +669,9 @@ %} \relax \xdef\m_strc_counters_last_registered_index{\the\scratchcounter}% - \clf_setinternalreference - internal \locationcount - \relax - \xdef\m_strc_counters_last_registered_attribute {\the\lastdestinationattribute}% - \xdef\m_strc_counters_last_registered_synchronize{\strc_lists_inject_enhance{\m_strc_counters_last_registered_index}{\the\locationcount}}} + \setstructurecomponentsynchronization\m_strc_counters_last_registered_index + \glet\m_strc_counters_last_registered_attribute \currentstructurecomponentattribute + \glet\m_strc_counters_last_registered_synchronize\currentstructurecomponentsynchronize} \let\m_strc_counters_last_registered_index \relax \let\m_strc_counters_last_registered_attribute \relax diff --git a/tex/context/base/mkiv/strc-pag.lua b/tex/context/base/mkiv/strc-pag.lua index dcd35fc20..ee1b245b9 100644 --- a/tex/context/base/mkiv/strc-pag.lua +++ b/tex/context/base/mkiv/strc-pag.lua @@ -113,8 +113,9 @@ end -- end function pages.number(realdata,pagespec) - local userpage, block = realdata.number, realdata.block or "" -- sections.currentblock() - local numberspec = realdata.numberdata + local userpage = realdata.number + local block = realdata.block or "" -- sections.currentblock() + local numberspec = realdata.numberdata local conversionset = (pagespec and pagespec.conversionset ~= "" and pagespec.conversionset) or (numberspec and numberspec.conversionset ~= "" and numberspec.conversionset) or "" local conversion = (pagespec and pagespec.conversion ~= "" and pagespec.conversion ) or (numberspec and numberspec.conversion ~= "" and numberspec.conversion ) or "" local starter = (pagespec and pagespec.starter ~= "" and pagespec.starter ) or (numberspec and numberspec.starter ~= "" and numberspec.starter ) or "" @@ -212,9 +213,11 @@ end function helpers.prefixlastpage(data,prefixspec,pagespec) if data then - local r = data.references - local ls, lr = r.section, r.realpage - r.section, r.realpage = r.lastsection or r.section, r.lastrealpage or r.realpage + local r = data.references + local ls = r.section + local lr = r.realpage + r.section = r.lastsection or r.section + r.realpage = r.lastrealpage or r.realpage helpers.prefixpage(data,prefixspec,pagespec) r.section, r.realpage = ls, lr end @@ -227,7 +230,8 @@ function helpers.analyze(entry,specification) if not entry then return false, false, "no entry" end - local yes, no = variables.yes, variables.no + local yes = variables.yes + local no = variables.no -- section data local references = entry.references if not references then diff --git a/tex/context/base/mkiv/strc-pag.mkiv b/tex/context/base/mkiv/strc-pag.mkiv index d56f0de54..01361e2c5 100644 --- a/tex/context/base/mkiv/strc-pag.mkiv +++ b/tex/context/base/mkiv/strc-pag.mkiv @@ -152,7 +152,7 @@ \setupsubpagenumber [\c!way=\v!by\v!part, - \c!state=\v!stop] + \c!state=\v!start] % was stop but start looks better in logging % Counters @@ -263,7 +263,7 @@ \def\currentpage{\the\realpageno}% rather useless \appendtoks - \ifnum\realpageno>\lastpage \globallet\lastpage\lastrealpage \fi + \ifnum\realpageno>\lastpage \glet\lastpage\lastrealpage \fi \to \everyinitializepagecounters % States: @@ -309,6 +309,8 @@ % some day ifsinglesided and ifdoublesided will become obsolete +\newtoks\everysidedswitch + \appendtoks \singlesidedfalse \setfalse\layoutisdoublesided \doublesidedfalse \setfalse\layoutissinglesided @@ -317,13 +319,7 @@ \processallactionsinset[\directpagenumberingparameter\c!alternative] [ \v!singlesided=>\setsystemmode\v!singlesided\singlesidedtrue\settrue\layoutissinglesided, \v!doublesided=>\setsystemmode\v!doublesided\doublesidedtrue\settrue\layoutisdoublesided]% - \ifdefined\trackingmarginnotestrue - \ifdoublesided - \trackingmarginnotestrue - \else - \trackingmarginnotesfalse - \fi - \fi + \the\everysidedswitch \pageduplexmode \ifsinglesided \ifdoublesided\plustwo\else\zerocount\fi @@ -334,6 +330,16 @@ \strc_pagenumbers_set_location \to \everysetuppagenumbering +\appendtoks + \ifdefined\trackingmarginnotestrue + \ifdoublesided + \trackingmarginnotestrue + \else + \trackingmarginnotesfalse + \fi + \fi +\to \everysidedswitch + \ifdefined \page_backgrounds_recalculate \else \let\page_backgrounds_recalculate\relax \fi @@ -401,11 +407,10 @@ \unexpanded\def\strc_pagenumbers_check_state_change#1#2% {\edef\m_strc_pagenumbers_state_new{\namedcounterparameter#1\c!state}% \ifx\m_strc_pagenumbers_state_new\m_strc_pagenumbers_state_old \else - \doifelse\m_strc_pagenumbers_state_new\v!start - {#2\plustwo}% - {#2\zerocount}% + #2\ifx\m_strc_pagenumbers_state_new\v!start\plustwo\else\zerocount\fi \fi} + \appendtoks % todo: set state: none, start, stop, reset \strc_pagenumbers_check_state_change\s!realpage\c_strc_pagenumbers_state_realpage \to \everysetuprealpagenumber diff --git a/tex/context/base/mkiv/strc-ref.lua b/tex/context/base/mkiv/strc-ref.lua index f20d93161..e01bacaac 100644 --- a/tex/context/base/mkiv/strc-ref.lua +++ b/tex/context/base/mkiv/strc-ref.lua @@ -52,6 +52,8 @@ local context = context local commands = commands local implement = interfaces.implement +local ctx_latelua = context.latelua + local texgetcount = tex.getcount local texsetcount = tex.setcount local texconditionals = tex.conditionals @@ -72,6 +74,7 @@ local lists = structures.lists local counters = structures.counters local jobpositions = job.positions +local getpos = jobpositions.getpos -- some might become local @@ -137,6 +140,7 @@ storage.register("structures/references/defined", references.defined, "structure local initializers = { } local finalizers = { } +local somefound = false -- so we don't report missing when we have a fresh start function references.registerinitializer(func) -- we could use a token register instead initializers[#initializers+1] = func @@ -162,6 +166,7 @@ local function initializer() -- can we use a tobesaved as metatable for collecte end end end + somefound = next(collected) end local function finalizer() @@ -370,6 +375,8 @@ implement { arguments = "2 strings", } +local reported = setmetatableindex("table") + function references.set(data) local references = data.references local reference = references.reference @@ -388,16 +395,23 @@ function references.set(data) if ref == "" then -- skip elseif check_duplicates and pd[ref] then - if prefix and prefix ~= "" then - report_references("redundant reference %a in namespace %a",ref,prefix) - else - report_references("redundant reference %a",ref) + if not prefix then + prefix = "" + end + if not reported[prefix][ref] then + if prefix ~= "" then + report_references("redundant reference %a in namespace %a",ref,prefix) + else + report_references("redundant reference %a",ref) + end + reported[prefix][ref] = true end else n = n + 1 pd[ref] = data local r = data.references ctx_dofinishreference(prefix or "",ref or "",r and r.internal or 0) + -- ctx_latelua(function() structures.references.enhance(prefix or ref,ref or "") end) end end process_settings(reference,action) @@ -411,8 +425,6 @@ end -- end -- end -local getpos = function() getpos = backends.codeinjections.getpos return getpos () end - local function synchronizepage(reference) -- non public helper reference.realpage = texgetcount("realpageno") if jobpositions.used then @@ -422,17 +434,30 @@ end references.synchronizepage = synchronizepage -function references.enhance(prefix,tag) - local l = tobesaved[prefix][tag] +local function enhancereference(specification) + local l = tobesaved[specification.prefix][specification.tag] if l then synchronizepage(l.references) end end +references.enhance = enhancereference + +-- implement { +-- name = "enhancereference", +-- arguments = "2 strings", +-- actions = function(prefix,tag) +-- enhancereference { prefix = prefix, tag = tag } +-- end, +-- } + implement { - name = "enhancereference", - actions = references.enhance, + name = "deferredenhancereference", arguments = "2 strings", + protected = true, + actions = function(prefix,tag) + ctx_latelua { action = enhancereference, prefix = prefix, tag = tag } + end, } -- -- -- related to strc-ini.lua -- -- -- @@ -1004,9 +1029,9 @@ local function loadexternalreferences(name,utilitydata) local pages = struc.pages.collected -- pagenumber data -- a bit weird one, as we don't have the externals in the collected for prefix, set in next, external do -if prefix == "" then - prefix = name -- this can clash! -end + if prefix == "" then + prefix = name -- this can clash! + end for reference, data in next, set do if trace_importing then report_importing("registering %a reference, kind %a, name %a, prefix %a, reference %a", @@ -1034,9 +1059,9 @@ end if kind and realpage then references.pagedata = pages[realpage] local prefix = references.prefix or "" -if prefix == "" then - prefix = name -- this can clash! -end + if prefix == "" then + prefix = name -- this can clash! + end local target = external[prefix] if not target then target = { } @@ -1468,7 +1493,7 @@ local function identify_inner(set,var,prefix,collected,derived) end end -- we now ignore the split prefix and treat the whole inner as a potential - -- referenice into the global list + -- reference into the global list local i = collected[prefix] if i then i = i[inner] @@ -1524,6 +1549,17 @@ local function identify_outer(set,var,i) end return v end +-- weird too (we really need to check how this table is build + local v = identify_inner(set,var,var.outer,external) + if v then + v.kind = "outer with inner" + set.external = true + if trace_identifying then + report_identify_outer(set,v,i,"2c") + end + return v + end +-- -- somewhat rubish: we use outer as first step in the externals table so it makes no -- sense to have it as prefix so the next could be an option local external = external[""] @@ -1798,8 +1834,7 @@ local nofidentified = 0 local function identify(prefix,reference) if not reference then - prefix = "" - reference = prefix + prefix, reference = "", prefix end local set = resolve(prefix,reference) local bug = false @@ -1847,7 +1882,9 @@ function references.valid(prefix,reference,specification) local str = f_valid(prefix,reference) local u = unknowns[str] if not u then - interfaces.showmessage("references",1,str) -- 1 = unknown, 4 = illegal + if somefound then + interfaces.showmessage("references",1,str) -- 1 = unknown, 4 = illegal + end unknowns[str] = 1 nofunknowns = nofunknowns + 1 else @@ -1964,13 +2001,14 @@ local function setinternalreference(specification) local internal = specification.internal local destination = unsetvalue if innermethod == v_auto or innermethod == v_name then - local t, tn = { }, 0 -- maybe add to current (now only used for tracing) + local t = { } -- maybe add to current (now only used for tracing) + local tn = 0 local reference = specification.reference local view = specification.view if reference then local prefix = specification.prefix if prefix and prefix ~= "" then - prefix = prefix .. ":" -- watch out, : here + local prefix = prefix .. ":" -- watch out, : here local function action(ref) tn = tn + 1 t[tn] = prefix .. ref @@ -1987,7 +2025,7 @@ local function setinternalreference(specification) -- ugly .. later we decide to ignore it when we have a real one -- but for testing we might want to see them all if internal then - if innermethod ~= v_name then -- so page and auto + if innermethod ~= v_name then -- innermethod == v_auto -- we don't want too many #1 #2 #3 etc tn = tn + 1 t[tn] = internal -- when number it's internal @@ -2064,7 +2102,7 @@ function references.setandgetattribute(data) -- maybe do internal automatically local done = references.set(data) -- we had kind i.e .item -> full if done then attr = setinternalreference { - prefix = prefix, + prefix = rdat.prefix, reference = rdat.reference, internal = rdat.internal, view = rdat.view @@ -2285,7 +2323,8 @@ genericfilters.default = genericfilters.text function genericfilters.page(data,prefixspec,pagespec) local pagedata = data.pagedata if pagedata then - local number, conversion = pagedata.number, pagedata.conversion + local number = pagedata.number + local conversion = pagedata.conversion if not number then -- error elseif conversion then @@ -2527,10 +2566,19 @@ local function referencepagestate(position,detail,spread) if not actions then return 0 else - if not actions.pagestate then + local pagestate = actions.pagestate + for i=1,#actions do + local a = actions[i] + if a.outer then + pagestate = 0 + actions.pagestate = pagestate + break + end + end + if not pagestate then references.analyze(actions,position,spread) -- delayed unless explicitly asked for + pagestate = actions.pagestate end - local pagestate = actions.pagestate if detail then return pagestate elseif pagestate == 4 then diff --git a/tex/context/base/mkiv/strc-ref.mkvi b/tex/context/base/mkiv/strc-ref.mkvi index d0752407c..c7f204815 100644 --- a/tex/context/base/mkiv/strc-ref.mkvi +++ b/tex/context/base/mkiv/strc-ref.mkvi @@ -29,7 +29,7 @@ \registerctxluafile{strc-rsc}{} \registerctxluafile{strc-ref}{} -\registerctxluafile{node-ref}{} +\registerctxluafile{node-ref}{optimize} \unprotect @@ -45,19 +45,18 @@ % \definespecial\dosetexecuteJScode % ... -%D This module deals with referencing. In \CONTEXT\ referencing is one of -%D the core features, although at a first glance probably nobody will -%D notice. This is good, because referencing should be as hidden as possible. +%D This module deals with referencing. In \CONTEXT\ referencing is one of the core +%D features, although at a first glance probably nobody will notice. This is good, +%D because referencing should be as hidden as possible. %D -%D Before we start implementing functionality we provide a way to set -%D up this mechanism. +%D Before we start implementing functionality we provide a way to set up this +%D mechanism. %D %D \showsetup{setupreferencing} %D -%D In interactive documents verbose references don't always -%D make sense (what is a page number in an unnumbered -%D document). By setting the \type{interaction} variable, one -%D can influences the way interactive references are set. +%D In interactive documents verbose references don't always make sense (what is a +%D page number in an unnumbered document). By setting the \type{interaction} +%D variable, one can influences the way interactive references are set. \let\referenceprefix\empty @@ -122,20 +121,19 @@ \dosetdirectpagereference\m_strc_references_asked \fi} -%D Actually there is not much difference between a text and a -%D full reference, but it's the concept that counts. The low -%D level implementation is: +%D Actually there is not much difference between a text and a full reference, but +%D it's the concept that counts. The low level implementation is: \newcount\lastreferenceattribute \newcount\lastdestinationattribute \def\strc_references_finish#prefix#reference#internal% - {\normalexpanded{\ctxlatecommand{enhancereference("#prefix","#reference")}}} + {\normalexpanded{\clf_deferredenhancereference{#prefix}{#reference}}} \let\dofinishreference\strc_references_finish % used at lua end -% This is somewhat tricky: we want to keep the reference with the following word but -% that word should also hyphenate. We need to find a better way. +%D This is somewhat tricky: we want to keep the reference with the following word but +%D that word should also hyphenate. We need to find a better way. % 0 = nothing % 1 = bind to following word @@ -167,6 +165,32 @@ \unhbox\b_strc_destination_nodes \fi} +\def\strc_references_placeholder + {\ifx\dotaggedplaceholder\empty\else + \attribute\destinationattribute\lastdestinationattribute + \dotaggedplaceholder + \fi} + +\unexpanded\def\strc_references_destination_point_yes + {\strc_references_inject_before % new + \dostarttagged\t!reference\empty + \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup + \strc_references_flush_destination_nodes + \strc_references_placeholder + \egroup + \dostoptagged + \strc_references_inject_after} + +\unexpanded\def\strc_references_destination_point_nop + {\strc_references_inject_before % new + \dostarttagged\t!reference\empty + \dontleavehmode\hbox \bgroup + \strc_references_flush_destination_nodes + \strc_references_placeholder + \egroup + \dostoptagged + \strc_references_inject_after} + \unexpanded\def\strc_references_start_destination_nodes % messy but we need the delay {\setbox\b_strc_destination_nodes\hbox\bgroup} % also sets lastdestinationattribute @@ -188,14 +212,14 @@ \xmlstartraw \xdef\currentreferencedata{#text}% data, no text else conflict \xmlstopraw - \globallet\currentreferencecoding\s!xml + \glet\currentreferencecoding\s!xml \else \ifx\currentreferenceexpansion\v!yes \xdef\currentreferencedata{#text}% \else \xdef\currentreferencedata{\detokenize{#text}}% \fi - \globallet\currentreferencecoding\s!tex + \glet\currentreferencecoding\s!tex \fi % beware, the structures.references.set writes a \setnextinternalreference @@ -240,17 +264,9 @@ \xdef\currentdestinationattribute{\number\lastdestinationattribute}% % will become an option: \ifnum\lastdestinationattribute>\zerocount - \strc_references_inject_before % new - \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup - \strc_references_flush_destination_nodes - \egroup - \strc_references_inject_after % new + \strc_references_destination_point_yes \else\ifvoid\b_strc_destination_nodes\else - \strc_references_inject_before % new - \dontleavehmode\hbox \bgroup - \strc_references_flush_destination_nodes - \egroup - \strc_references_inject_after % new + \strc_references_destination_point_nop \fi\fi} \def\strc_references_set_page_only_destination_attribute#labels% could in fact be fully expandable @@ -324,17 +340,9 @@ \xdef\currentdestinationattribute{\number\lastdestinationattribute}% % will become an option: \ifnum\lastdestinationattribute>\zerocount - \strc_references_inject_before % new - \dontleavehmode\hbox attr \destinationattribute\lastdestinationattribute\bgroup - \strc_references_flush_destination_nodes - \egroup - \strc_references_inject_after % new + \strc_references_destination_point_yes \else\ifvoid\b_strc_destination_nodes\else - \strc_references_inject_before % new - \dontleavehmode\hbox \bgroup - \strc_references_flush_destination_nodes - \egroup - \strc_references_inject_after % new + \strc_references_destination_point_nop \fi\fi} \unexpanded\def\strc_references_direct_full @@ -479,10 +487,10 @@ {\scratchwidth \wd\nextbox \scratchheight\ht\nextbox \scratchdepth \dp\nextbox - \setbox\nextbox\hbox % \hpack ? + \setbox\nextbox\hpack {\framed[\c!frame=\v!off,#2]{\box\nextbox}}% \strc_references_set_simple_reference{#1}% - \setbox\nextbox\hbox attr \destinationattribute \currentdestinationattribute % \hpack ? + \setbox\nextbox\hpack attr \destinationattribute \currentdestinationattribute % \hpack ? {\strc_references_flush_destination_nodes \box\nextbox}% \setbox\nextbox\hpack{\box\nextbox}% @@ -494,7 +502,7 @@ \def\strc_references_content_nop_finish#1#2% {\strc_references_set_simple_reference{#1}% - \hbox attr \destinationattribute \currentdestinationattribute % \hpack ? + \hpack attr \destinationattribute \currentdestinationattribute % \hpack ? {\strc_references_flush_destination_nodes \box\nextbox}% \egroup} @@ -502,34 +510,31 @@ %D \macros %D {everyreference} %D -%D For rather tricky purposes, one can assign sanitizing -%D macros to \type{\everyreference} (no longer that relevant). +%D For rather tricky purposes, one can assign sanitizing macros to \type +%D {\everyreference} (no longer that relevant). \newevery \everyreference \relax -%D This is really needed, since for instance Polish has a -%D different alphabet and needs accented entries in registers. +%D This is really needed, since for instance Polish has a different alphabet and +%D needs accented entries in registers. \appendtoks \cleanupfeatures \to \everyreference -%D We did not yet discuss prefixing. Especially in interactive -%D documents, it's not always easy to keep track of duplicate -%D references. The prefix mechanism, which we will describe -%D later on, solves this problem. By (automatically) adding a -%D prefix one keeps references local, but the global ones in -%D view. To enable this feature, we explictly split the prefix -%D from the reference. +%D We did not yet discuss prefixing. Especially in interactive documents, it's not +%D always easy to keep track of duplicate references. The prefix mechanism, which we +%D will describe later on, solves this problem. By (automatically) adding a prefix +%D one keeps references local, but the global ones in view. To enable this feature, +%D we explictly split the prefix from the reference. \let\referenceprefix\empty -%D For a long time the only way to access an external file was -%D to use the file prefix (\type {somefile::}. However, when -%D you split up a document, redefining the references may be -%D such a pain, that another approach is feasible. By setting -%D the \type {autofile} variable to \type {yes} or \type -%D {page}, you can access the reference directly. +%D For a long time the only way to access an external file was to use the file +%D prefix (\type {somefile::}. However, when you split up a document, redefining the +%D references may be such a pain, that another approach is feasible. By setting the +%D \type {autofile} variable to \type {yes} or \type {page}, you can access the +%D reference directly. %D %D \starttabulate[||||] %D \NC filename::tag \NC page(filename::pnum) \NC tag \NC\NR @@ -540,9 +545,9 @@ \unexpanded\def\usereferences[#filename]{} % obsolete -%D As mentioned we will also use the cross reference mechanism -%D for navigational purposes. The main reason for this is that -%D we want to treat both categories alike: +%D As mentioned we will also use the cross reference mechanism for navigational +%D purposes. The main reason for this is that we want to treat both categories +%D alike: %D %D \starttyping %D \goto{go back}[PreviousJump] @@ -553,15 +558,13 @@ %D \type{colofon page} reference is, apart from hyperlinking, a %D rather normal reference. %D -%D We already saw that cross refences are written to and read -%D from a file. The pure navigational ones don't need to be -%D written to file, but both for fast processing and -%D transparant integration, they are saved internally as a sort -%D of reference. We can easily distinguish such system -%D references from real cross reference ones by their tag. +%D We already saw that cross refences are written to and read from a file. The pure +%D navigational ones don't need to be written to file, but both for fast processing +%D and transparant integration, they are saved internally as a sort of reference. We +%D can easily distinguish such system references from real cross reference ones by +%D their tag. %D -%D We also use the odd/even characteristic to determine the -%D page state. +%D We also use the odd/even characteristic to determine the page state. \let\currentrealreference \empty \let\currentpagereference \empty @@ -576,11 +579,10 @@ % % 0 = no page ref, 1=same page, 2=before, 3=after -%D Cross references appear as numbers (figure~1.1, chapter~2) -%D or pagenumbers (page~2, page 3--2), and are called with -%D \type{\in} and \type{\at}. In interactive documents we also -%D have \type{\goto}, \type{\button} and alike. These are more -%D versatile and look like: +%D Cross references appear as numbers (figure~1.1, chapter~2) or pagenumbers +%D (page~2, page 3--2), and are called with \type {\in} and \type {\at}. In +%D interactive documents we also have \type {\goto}, \type {\button} and alike. +%D These are more versatile and look like: %D %D \starttyping %D \goto[reference] @@ -592,23 +594,19 @@ %D \goto[action{argument}] %D \stoptyping %D -%D The first one is a normal reference, the second and third -%D are references to a file or \URL. The brace delimited -%D references for instance refer to a \JAVASCRIPT. The last -%D example shows that we can pass arguments to the actions. +%D The first one is a normal reference, the second and third are references to a +%D file or \URL. The brace delimited references for instance refer to a \JAVASCRIPT. +%D The last example shows that we can pass arguments to the actions. %D -%D Now we've come to the testing step. As we can see below, -%D this macro does bit more than testing: it also resolves -%D the reference. This means that whenever we test for the -%D existance of a reference at an outer level, we have all the -%D relevant properties of that reference avaliable inside the -%D true branche~(\type{#2}). +%D Now we've come to the testing step. As we can see below, this macro does bit more +%D than testing: it also resolves the reference. This means that whenever we test +%D for the existance of a reference at an outer level, we have all the relevant +%D properties of that reference avaliable inside the true branche~(\type {#2}). %D -%D The prefix has to do with localizing references. When a -%D prefix is set, looking for a reference comes to looking for -%D the prefixed one, and when not found, looking for the non -%D prefixed one. Consider for instance the prefix set to -%D \type{sidetrack}. +%D The prefix has to do with localizing references. When a prefix is set, looking +%D for a reference comes to looking for the prefixed one, and when not found, +%D looking for the non prefixed one. Consider for instance the prefix set to \type +%D {sidetrack}. %D %D \starttyping %D \pagereference[important] @@ -625,17 +623,15 @@ %D ...{sidetrack}{important}... %D \stoptyping %D -%D Now when we call for \type{unimportant}, we will indeed get -%D the pagenumber associated to this reference. But when we -%D call for \type{important}, while the prefix is still set, we -%D will get the pagenumber bound to the prefixed one. +%D Now when we call for \type{unimportant}, we will indeed get the pagenumber +%D associated to this reference. But when we call for \type{important}, while the +%D prefix is still set, we will get the pagenumber bound to the prefixed one. %D %D {\em Some day, when processing time and memory are no longer %D performance factors, we will introduce multi||level %D prefixes.} %D -%D Before we start analyzing, I introduce a general -%D definition macro. Consider: +%D Before we start analyzing, I introduce a general definition macro. Consider: %D %D \starttyping %D \goto{do}[JS(My_Script{"test",123}),titlepage] @@ -652,8 +648,7 @@ %D %D \showsetup{definereference} %D -%D We can trace references by setting the next switch to -%D true. +%D We can trace references by setting the next switch to true. \unexpanded\def\definereference {\dodoubleempty\strc_references_define_reference} @@ -673,23 +668,22 @@ %D \goto{somewhere}[JS(somescript),nextpage,JS(anotherscript)] %D \stoptyping %D -%D Actually supporting chains is up to the special driver. Here -%D we only provide the hooks. +%D Actually supporting chains is up to the special driver. Here we only provide the +%D hooks. %D \macros %D {highlighthyperlinks} %D -%D The next switch can be used to make user hyperlinks are -%D not highlighted when clicked on. +%D The next switch can be used to make user hyperlinks are not highlighted when +%D clicked on. \newconditional\highlighthyperlinks \settrue\highlighthyperlinks %D \macros %D {gotonewwindow} %D -%D To make the {\em goto previous jump} feature more -%D convenient when using more than one file, it makes sense -%D to force the viewer to open a new window for each file +%D To make the {\em goto previous jump} feature more convenient when using more than +%D one file, it makes sense to force the viewer to open a new window for each file %D opened. \newconditional\gotonewwindow \setfalse\gotonewwindow @@ -708,13 +702,11 @@ \let\doifreferencefoundelse \doifelsereferencefound -%D The tester only splits the reference in components but does -%D not look into them. The following macro does a preroll and -%D determines for instance the current real reference pagenumber. -%D The \type {\currentrealreference} macro does the same so unless -%D one wants to use the pagestate the next macro seldom needs to -%D be called. - +%D The tester only splits the reference in components but does not look into them. +%D The following macro does a preroll and determines for instance the current real +%D reference pagenumber. The \type {\currentrealreference} macro does the same so +%D unless one wants to use the pagestate the next macro seldom needs to be called. +%D %D The inner case is simple. Only two cases have to be taken %D care of: %D @@ -723,8 +715,8 @@ %D \goto{some text}[prefix:reference] %D \stoptyping %D -%D References to other files however are treated strict or -%D tolerant, depending on their loading and availability: +%D References to other files however are treated strict or tolerant, depending on +%D their loading and availability: %D %D \starttyping %D \useexternaldocument[somefile][filename][a nice description] @@ -734,72 +726,61 @@ %D \goto{unchecked reference}[anotherfile::reference] %D \stoptyping %D -%D An unknown reference is reported on the screen, in the log -%D file and, when enabled, in the left margin of the text. +%D An unknown reference is reported on the screen, in the log file and, when +%D enabled, in the left margin of the text. \let\unknownreference\gobbleoneargument -%D When a reference is not found, we typeset a placeholder -%D (two glyphs are often enough to represent the reference -%D text). +%D When a reference is not found, we typeset a placeholder (two glyphs are often +%D enough to represent the reference text). \def\dummyreference{{\tttf ??}} \def\emptyreference{{\tttf !!}} -%D To prevent repetitive messages concerning a reference -%D being defined, we set such an unknown reference to an empty -%D one after the first encounter. - -%D Apart from cross references supplied by the user, \CONTEXT\ -%D generates cross references itself. Most of them are not -%D saved as a reference, but stored with their source, for -%D instance a list or an index entry. Such automatically -%D generated, for the user invisible, references are called -%D {\em internal references}. The user supplied ones are -%D labeled as {\em external references}. -%D -%D A second important characteristic is that when we want to -%D support different backends (viewers), we need to support -%D named destinations as well as page numbers. I invite readers -%D to take a glance at the special driver modules to understand -%D the fine points of this. As a result we will deal with {\em -%D locations} as well as {\em real page numbers}. We explictly -%D call this pagenumber a real one, because it is independant -%D of the page numbering scheme used in the document. -%D -%D One of the reasons for \CONTEXT\ being the first \TEX\ base -%D macropackage to support sophisticated interactive \PDF\ -%D files, lays in the mere fact that real page numbers are -%D available in most two pass data, like references, list data -%D and index entries. -%D -%D We will speak of \type{thisis...} when we are marking a -%D location, and \type{goto...} when we point to such a -%D location. The latter one can be seen as a hyperlink to the -%D former one. In the next macros one we use constructs like: +%D To prevent repetitive messages concerning a reference being defined, we set such +%D an unknown reference to an empty one after the first encounter. +%D +%D Apart from cross references supplied by the user, \CONTEXT\ generates cross +%D references itself. Most of them are not saved as a reference, but stored with +%D their source, for instance a list or an index entry. Such automatically +%D generated, for the user invisible, references are called {\em internal +%D references}. The user supplied ones are labeled as {\em external references}. +%D +%D A second important characteristic is that when we want to support different +%D backends (viewers), we need to support named destinations as well as page +%D numbers. I invite readers to take a glance at the special driver modules to +%D understand the fine points of this. As a result we will deal with {\em locations} +%D as well as {\em real page numbers}. We explictly call this pagenumber a real one, +%D because it is independant of the page numbering scheme used in the document. +%D +%D One of the reasons for \CONTEXT\ being the first \TEX\ base macropackage to +%D support sophisticated interactive \PDF\ files, lays in the mere fact that real +%D page numbers are available in most two pass data, like references, list data and +%D index entries. +%D +%D We will speak of \type {thisis...} when we are marking a location, and +%D \type {goto...} when we point to such a location. The latter one can be seen as a +%D hyperlink to the former one. In the next macros one we use constructs like: %D %D \starttyping %D \dostart... %D \dostop... %D \stoptyping %D -%D Such macros are used to invoke the relevant specials from -%D the special driver modules (see \type{spec-ini}). The flag -%D \type{\iflocation} signals if we're in interactive mode. +%D The flag \type {\iflocation} signals if we're in interactive mode. \ifdefined\buttonheight \else \newdimen\buttonheight \fi \ifdefined\buttonwidth \else \newdimen\buttonwidth \fi -%D Internal references can best be set using the next few -%D macros. Setting such references to unique values is -%D completely up to the macros that call them. +%D Internal references can best be set using the next few macros. Setting such +%D references to unique values is completely up to the macros that call them. %D %D \starttyping %D \thisissomeinternal{tag}{identifier} %D \gotosomeinternal {tag}{identifier}{pagenumber}{text} %D \stoptyping - -%D We could do this in lua ... +%D +%D We could do this in \LUA\ \unknown \newif \iflocation \newcount\locationcount @@ -823,7 +804,7 @@ \clf_setinternalreference reference {#kind:#name}% no view \relax - \hbox attr \destinationattribute\lastdestinationattribute{}% + \hpack attr \destinationattribute\lastdestinationattribute{}% \endgroup} \installcorenamespace{savedinternalreference} @@ -845,12 +826,10 @@ \def\gotonextinternal#text#target% {\directgoto{#text}[internal(#target)]} -%D In this module we define three system references: one for -%D handling navigational, viewer specific, commands, another -%D for jumping to special pages, like the first or last one, -%D and a third reference for linking tree like lists, like -%D tables of contents. The latter two adapt themselves to the -%D current state. +%D In this module we define three system references: one for handling navigational, +%D viewer specific, commands, another for jumping to special pages, like the first +%D or last one, and a third reference for linking tree like lists, like tables of +%D contents. The latter two adapt themselves to the current state. %D %D An example of an action is: %D @@ -863,11 +842,10 @@ %D \starttyping %D \goto{some text}[\v!action(PreviousJump] %D \stoptyping - -%D One can also activate an automatic prefix mechanism. By -%D setting the \type{\prefix} variable to \type{+}, the prefix -%D is incremented, when set to \type{-} or empty, the prefix is -%D reset. Other values become the prefix. +%D +%D One can also activate an automatic prefix mechanism. By setting the +%D \type {\prefix} variable to \type {+}, the prefix is incremented, when set to +%D \type {-} or empty, the prefix is reset. Other values become the prefix. \newcount\prefixcounter @@ -892,13 +870,6 @@ \unexpanded\def\setupglobalreferenceprefix[#prefix]% {\xdef\referenceprefix{#prefix}} -% \unexpanded\def\pushreferenceprefix#prefix% -% {\pushmacro\referenceprefix -% \xdef\referenceprefix{#prefix}} % global - -% \unexpanded\def\popreferenceprefix -% {\popmacro\referenceprefix} - \unexpanded\def\globalpushreferenceprefix#prefix% {\xdef\referenceprefix{\clf_pushreferenceprefix{#prefix}}} @@ -935,16 +906,14 @@ \setupreferenceprefix[\referencingparameter\c!prefix] \to \everysetupreferencing -%D We can typeset a reference using \type{\in}, \type{\at} and -%D \type{\about} and goto specific locations using -%D \type{\goto}. The last one does not make that much sense in -%D a paper document. To complicate things, \PLAIN\ \TEX\ also -%D implements an \type {\in} but fortunately that one only -%D makes sense in math mode. +%D We can typeset a reference using \type {\in}, \type {\at} and \type {\about} and +%D goto specific locations using \type {\goto}. The last one does not make that much +%D sense in a paper document. To complicate things, \PLAIN\ \TEX\ also implements an +%D \type {\in} but fortunately that one only makes sense in math mode. %D -%D Typesetting the reference is a bit more complicated than one -%D would at first sight expect. This is due to the fact that we -%D distinguish three (five) alternative calls: +%D Typesetting the reference is a bit more complicated than one would at first sight +%D expect. This is due to the fact that we distinguish three (five) alternative +%D calls: %D %D \placefigure %D [here][three calls] @@ -971,25 +940,11 @@ %D \getbuffer %D \stoplines %D -%D The dual \type{{}} results in a split reference. In a -%D document meant for paper, one is tempted to use the last -%D (most straightforward) alternative. When a document is also -%D meant voor electronic distribution, the former alternatives -%D have preference, because everything between the \type{\in} -%D and~\type{[} becomes active (and when asked for, typeset -%D in a different color and typeface). - -% \unexpanded\def\in {\mathortext\donormalmathin \strc_references_in} -% \unexpanded\def\at {\mathortext\donormalmathat \strc_references_at} -% \unexpanded\def\about{\mathortext\donormalmathabout\strc_references_about} -% \unexpanded\def\from {\mathortext\donormalmathfrom \strc_references_from} -% \unexpanded\def\over {\mathortext\donormalmathover \strc_references_about} - -% \definecommand in {\strc_references_in} -% \definecommand at {\strc_references_at} -% \definecommand about {\strc_references_about} -% \definecommand from {\strc_references_from} -% \definecommand over {\strc_references_about} % needed here, else math problems +%D The dual \type {{}} results in a split reference. In a document meant for paper, +%D one is tempted to use the last (most straightforward) alternative. When a +%D document is also meant voor electronic distribution, the former alternatives have +%D preference, because everything between the \type {\in} and~\type {[} becomes +%D active (and when asked for, typeset in a different color and typeface). \appendtoks \ifdefined\in \let\normalmathin \in \unexpanded\def\in {\mathortext\normalmathin \strc_references_in } \else \let\in \strc_references_in \fi @@ -1009,8 +964,7 @@ \def\currentreferencedefault {\clf_filterreference{default}} \def\currentreferencerealpage{\clf_filterreference{realpage}} -%D The most straightforward way of retrieving references is -%D using \type{\ref}. +%D The most straightforward way of retrieving references is using \type {\ref}. \unexpanded\def\getreference % checking, unexpanded {\dodoubleargument\strc_references_get_reference} @@ -1040,12 +994,11 @@ \referencingparameter\c!right \endgroup} -%D The previously discussed setup macro lets us specify the -%D representation of references. A symbol reference does not -%D show the specific data, like the number of a figure, but -%D shows one of: \hbox {$^\goforwardcharacter$ -%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending -%D on the direction to go. +%D The previously discussed setup macro lets us specify the representation of +%D references. A symbol reference does not show the specific data, like the number +%D of a figure, but shows one of: \hbox {$^\goforwardcharacter$ +%D $^\gobackwardcharacter$ $^\gonowherecharacter$}, depending on the direction to +%D go. %D %D \starttyping %D ... \somewhere{backward text}{forward text}[someref] ... @@ -1141,7 +1094,7 @@ \expandafter\sixthofsixarguments \fi} \unexpanded\def\referencesymbol - {\hbox\bgroup + {\hpack\bgroup \strut \markreferencepage \high @@ -1210,17 +1163,23 @@ \newtoks\defaultleftreferencetoks \newtoks\defaultrightreferencetoks -\def\leftofreferencecontent {\nobreakspace} % we cannot do \definereferenceformat[at] .. so we need this +%def\leftofreferencecontent {\nobreakspace} % we cannot do \definereferenceformat[at] .. so we need this \let\rightofreferencecontent \empty \let\leftofreference \empty \let\rightofreference \empty +\unexpanded\def\leftofreferencecontent + {\removeunwantedspaces + \nonbreakablespace + \ignorespaces} + \installcorenamespace{referencinginteraction} \def\strc_references_interaction_all {\the\leftreferencetoks \doifelsesometoks\leftreferencetoks \leftofreferencecontent \donothing \leftofreference + \doifelsesometoks\leftreferencetoks\onlynonbreakablespace\relax % new, replace space by nonbreakable if present \currentreferencecontent \rightofreference \doifelsesometoks\rightreferencetoks\rightofreferencecontent\donothing @@ -1242,15 +1201,6 @@ \setvalue{\??referencinginteraction\v!symbol}% {\referencesymbol} -% \def\referencesequence -% {\csname\??referencinginteraction -% \ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname -% \referencingparameter\c!interaction -% \else -% \v!all -% \fi -% \endcsname} - \def\referencesequence {\ifcsname\??referencinginteraction\referencingparameter\c!interaction\endcsname \expandafter\lastnamedcs @@ -1311,9 +1261,8 @@ %D \macros %D {definereferenceformat} %D -%D The next few macros were made for for David Arnold and Taco -%D Hoekwater. They can be used for predefining reference -%D texts, and thereby stimulate efficiency. +%D The next few macros were made for for David Arnold and Taco Hoekwater. They can +%D be used for predefining reference texts, and thereby stimulate efficiency. %D %D \starttyping %D \definereferenceformat[informula] [left=(,right=),text=formula] @@ -1328,11 +1277,11 @@ %D the \informulas [b] \andformula [for:c] %D \stoptyping %D -%D Instead of a text, one can specify a label, which should -%D be defined with \type {\setuplabeltext}. +%D Instead of a text, one can specify a label, which should be defined with \type +%D {\setuplabeltext}. %D -%D Watch out: the second argument is somewhat special and mostly -%D meant for a suffix to a number: +%D Watch out: the second argument is somewhat special and mostly meant for a suffix +%D to a number: %D %D \startbuffer %D \definereferenceformat [intesta] [left=(,right=),text=Whatever~] @@ -1437,21 +1386,18 @@ % % \definereferenceformat[hellup][text=Hellup ,setups=referenceformat:numberplustext] -%D In interactive documents going to a specific location is not -%D bound to cross references. The \type{\goto} commands can be -%D used to let users access another part of the document. In -%D this respect, interactive tables of contents and registers -%D can be considered goto's. Because in fact a \type{\goto} is -%D just a reference without reference specific data, the -%D previous macros are implemented using the goto -%D functionality. +%D In interactive documents going to a specific location is not bound to cross +%D references. The \type {\goto} commands can be used to let users access another +%D part of the document. In this respect, interactive tables of contents and +%D registers can be considered goto's. Because in fact a \type {\goto} is just a +%D reference without reference specific data, the previous macros are implemented +%D using the goto functionality. %D %D \showsetup{goto} %D -%D One important characteristic is that the first argument of -%D \type{\goto} (and therefore \type{\at} and \type{\in} is -%D split at spaces. This means that, although hyphenation is -%D prevented, long references can cross line endings. +%D One important characteristic is that the first argument of \type {\goto} (and +%D therefore \type {\at} and \type {\in} is split at spaces. This means that, +%D although hyphenation is prevented, long references can cross line endings. % \starttext % \setupinteraction[state=start] @@ -1740,21 +1686,19 @@ \clf_doifelsereference{\referenceprefix}{#label}{\extrareferencearguments}% {\clf_injectcurrentreference \global\lastsavedreferenceattribute\lastreferenceattribute - \hbox attr \referenceattribute \lastreferenceattribute {\box\scratchbox}} + \hpack attr \referenceattribute \lastreferenceattribute {\box\scratchbox}} {\box\scratchbox}% \endgroup} -%D An reference to another document can be specified as a file -%D or as an \URL. Both are handled by the same mechanism and -%D can be issued by saying something like: +%D An reference to another document can be specified as a file or as an \URL. Both +%D are handled by the same mechanism and can be issued by saying something like: %D %D \starttyping %D \goto[dictionary::the letter a] %D \stoptyping %D -%D One can imagine that many references to such a dictionary -%D are made, so in most cases such a document reference in an -%D indirect one. +%D One can imagine that many references to such a dictionary are made, so in most +%D cases such a document reference in an indirect one. %D %D \showsetup{useexternaldocument} %D @@ -1766,8 +1710,8 @@ %D [The Famous English Dictionary] %D \stoptyping %D -%D The next macro implements these relations, and also take -%D care of loading the document specific references. +%D The next macro implements these relations, and also take care of loading the +%D document specific references. %D %D The \URL\ alternative takes four arguments: %D @@ -1789,9 +1733,8 @@ %D \useURL [id] [url] %D \stoptyping %D -%D This time we don't load the references when no file is -%D specified. This is logical when one keeps in mind that a -%D valid \URL\ can also be a mail address. +%D This time we don't load the references when no file is specified. This is logical +%D when one keeps in mind that a valid \URL\ can also be a mail address. \unexpanded\def\useurl {\doquadrupleempty\strc_references_use_url } % so that they can be used in expanded arguments \unexpanded\def\usefile{\dotripleargument\strc_references_use_file} % so that they can be used in expanded arguments @@ -1814,8 +1757,7 @@ %D \macros %D {url,setupurl} %D -%D We also have: \type{\url} for directly calling the -%D description. So we can say: +%D We also have: \type {\url} for directly calling the description. So we can say: %D %D \starttyping %D \useURL [one] [http://www.test.nl] @@ -1843,8 +1785,8 @@ \hyphenatedurl{\clf_geturl{#label}}% \endgroup} -%D This macro is hooked into a support macro, and thereby -%D \URL's break ok, according to the setting of a switch, +%D This macro is hooked into a support macro, and thereby \URL's break ok, according +%D to the setting of a switch, %D %D \startbuffer %D \useURL @@ -1858,9 +1800,8 @@ %D %D \getbuffer -%D When defining the external source of information, one can -%D also specify a suitable name (the last argument). This name -%D can be called upon with: +%D When defining the external source of information, one can also specify a suitable +%D name (the last argument). This name can be called upon with: %D %D \showsetup{from} %D @@ -1895,9 +1836,8 @@ %D \goto{some text}[identifier::location] %D \stoptyping -%D A special case of references are those to programs. These, -%D very system dependant references are implemented by abusing -%D some of the previous macros. +%D A special case of references are those to programs. These, very system dependant +%D references are implemented by abusing some of the previous macros. %D %D \showsetup{setupprograms} %D \showsetup{defineprogram} @@ -1918,15 +1858,14 @@ \def\strc_references_define_program[#name][#program][#description]% {\clf_defineprogram{#name}{#program}{#description}} -\def\program[#name]% incompatible, more consistent, hardy used anyway +\unexpanded\def\program[#name]% incompatible, more consistent, hardy used anyway {\dontleavehmode \begingroup \useprogramsstyleandcolor\c!style\c!color \clf_getprogram{#name}% \endgroup} -%D As we can see, we directly use the special reference -%D mechanism, which means that +%D As we can see, we directly use the special reference mechanism, which means that %D %D \starttyping %D \goto{some text}[program(name{args})] @@ -1934,11 +1873,10 @@ %D %D is valid. -%D The next macro provides access to the actual pagenumbers. -%D When documenting and sanitizing the original reference -%D macros, I decided to keep the present meaning as well as to -%D make this meaning available as a special reference method. -%D So now one can use: +%D The next macro provides access to the actual pagenumbers. When documenting and +%D sanitizing the original reference macros, I decided to keep the present meaning +%D as well as to make this meaning available as a special reference method. So now +%D one can use: %D %D \starttyping %D \gotopage{some text}[location] @@ -1967,8 +1905,7 @@ \def\gotopage#text[#target]% {\goto{#text}[\v!page(#target)]} -%D The previous definitions are somewhat obsolete so we don't -%D use it here. +%D The previous definitions are somewhat obsolete so we don't use it here. %D We can cross link documents by using: %D @@ -1980,16 +1917,14 @@ %D \coupledocument[print][somefile][chapter,section] %D \stoptyping %D -%D After which when applicable, we have available the -%D references: +%D After which when applicable, we have available the references: %D %D \starttyping %D \goto{print version}[print::chapter] %D \stoptyping %D -%D and alike. The title placement definition macros have a -%D key \type{file}, which is interpreted as the file to jump -%D to, that is, when one clicks on the title. +%D and alike. The title placement definition macros have a key \type {file}, which +%D is interpreted as the file to jump to, that is, when one clicks on the title. \def\coupledocument {\doquadrupleempty\strc_references_couple_document} @@ -2002,8 +1937,8 @@ %D \macros %D {dotextprefix} %D -%D In previous macros we used \type {\dotextprefix} to -%D generate a space between a label and a number. +%D In previous macros we used \type {\dotextprefix} to generate a space between +%D a label and a number. %D %D \starttyping %D \dotextprefix{text} @@ -2026,9 +1961,8 @@ \fi \endgroup} -%D In the next settings we see some variables that were not -%D used here and that concern the way the pagenumbers refered -%D to are typeset. +%D In the next settings we see some variables that were not used here and that +%D concern the way the pagenumbers refered to are typeset. \setupreferencing [\c!state=\v!start, diff --git a/tex/context/base/mkiv/strc-reg.lua b/tex/context/base/mkiv/strc-reg.lua index 2c667fba3..47ba1c533 100644 --- a/tex/context/base/mkiv/strc-reg.lua +++ b/tex/context/base/mkiv/strc-reg.lua @@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['strc-reg'] = { } local next, type, tonumber = next, type, tonumber -local format, gmatch = string.format, string.gmatch +local char, format, gmatch = string.char, string.format, string.gmatch local equal, concat, remove = table.are_equal, table.concat, table.remove local lpegmatch, P, C, Ct = lpeg.match, lpeg.P, lpeg.C, lpeg.Ct local allocate = utilities.storage.allocate @@ -38,6 +38,7 @@ local texgetcount = tex.getcount local variables = interfaces.variables local v_forward = variables.forward local v_all = variables.all +local v_no = variables.no local v_yes = variables.yes local v_packed = variables.packed local v_current = variables.current @@ -47,7 +48,7 @@ local v_last = variables.last local v_text = variables.text local context = context -local commands = commands +local ctx_latelua = context.latelua local implement = interfaces.implement @@ -81,10 +82,12 @@ local ctx_startregisterpages = context.startregisterpages local ctx_stopregisterpages = context.stopregisterpages local ctx_startregisterseewords = context.startregisterseewords local ctx_stopregisterseewords = context.stopregisterseewords + local ctx_registerentry = context.registerentry local ctx_registerseeword = context.registerseeword local ctx_registerpagerange = context.registerpagerange local ctx_registeronepage = context.registeronepage + local ctx_registerpacked = context.registerpacked -- possible export, but ugly code (overloads) @@ -452,23 +455,6 @@ local tagged = { } local function preprocessentries(rawdata) local entries = rawdata.entries if entries then - -- - -- local e = entries[1] or "" - -- local k = entries[2] or "" - -- local et, kt, entryproc, pageproc - -- if type(e) == "table" then - -- et = e - -- else - -- entryproc, e = splitprocessor(e) - -- et = lpegmatch(entrysplitter,e) - -- end - -- if type(k) == "table" then - -- kt = k - -- else - -- pageproc, k = splitprocessor(k) - -- kt = lpegmatch(entrysplitter,k) - -- end - -- local processors = rawdata.processors local et = entries.entries local kt = entries.keys @@ -533,6 +519,7 @@ local function storeregister(rawdata) -- metadata, references, entries metadata.kind = "entry" end -- + -- if not metadata.catcodes then metadata.catcodes = tex.catcodetable -- get end @@ -581,17 +568,20 @@ local function storeregister(rawdata) -- metadata, references, entries return #entries end -registers.store = storeregister - -function registers.enhance(name,n) - local data = tobesaved[name].metadata.notsaved and collected[name] or tobesaved[name] +local function enhanceregister(specification) + local name = specification.name + local n = specification.n + local saved = tobesaved[name] + local data = saved.metadata.notsaved and collected[name] or saved local entry = data.entries[n] if entry then entry.references.realpage = texgetcount("realpageno") end end -function registers.extend(name,tag,rawdata) -- maybe do lastsection internally +-- This can become extendregister(specification)! + +local function extendregister(name,tag,rawdata) -- maybe do lastsection internally if type(tag) == "string" then tag = tagged[tag] end @@ -635,6 +625,10 @@ function registers.extend(name,tag,rawdata) -- maybe do lastsection internally end end +registers.store = storeregister +registers.enhance = enhanceregister +registers.extend = extendregister + function registers.get(tag,n) local list = tobesaved[tag] return list and list.entries[n] @@ -642,13 +636,24 @@ end implement { name = "enhanceregister", - actions = registers.enhance, arguments = { "string", "integer" }, + actions = function(name,n) + enhanceregister { name = name, n = n } -- todo: move to scanner + end, +} + +implement { + name = "deferredenhanceregister", + arguments = { "string", "integer" }, + protected = true, + actions = function(name,n) + ctx_latelua { action = enhanceregister, name = name, n = n } + end, } implement { name = "extendregister", - actions = registers.extend, + actions = extendregister, arguments = "2 strings", } @@ -714,7 +719,8 @@ function registers.compare(a,b) local ka = a.metadata.kind local kb = b.metadata.kind if ka == kb then - local page_a, page_b = a.references.realpage, b.references.realpage + local page_a = a.references.realpage + local page_b = b.references.realpage if not page_a or not page_b then return 0 elseif page_a < page_b then @@ -739,7 +745,7 @@ local seeindex = 0 -- meerdere loops, seewords, dan words, anders seewords -local function crosslinkseewords(result) -- all words +local function crosslinkseewords(result,check) -- all words -- collect all seewords local seewords = { } for i=1,#result do @@ -783,24 +789,17 @@ local function crosslinkseewords(result) -- all words local seeparent = seeparents[text] if seeparent then local seeindex = seewords[text] - local s, ns, d, w, l = { }, 0, data.split, seeparent.split, data.list - -- trick: we influence sorting by adding fake subentries - for i=1,#d do - ns = ns + 1 - s[ns] = d[i] -- parent - end - for i=1,#w do - ns = ns + 1 - s[ns] = w[i] -- see - end - data.split = s - -- we also register a fake extra list entry so that the - -- collapser works okay - l[#l+1] = { text, "" } data.references.seeindex = seeindex if trace_registers then report_registers("see crosslink %03i: %s",seeindex,text) end + seeword.valid = true + elseif check then + report_registers("invalid crosslink : %s, %s",text,"ignored") + seeword.valid = false + else + report_registers("invalid crosslink : %s, %s",text,"passed") + seeword.valid = true end end end @@ -824,17 +823,22 @@ local function removeemptyentries(result) end end -function registers.prepare(data) +function registers.prepare(data,options) -- data has 'list' table local strip = sorters.strip local splitter = sorters.splitters.utf local result = data.result if result then + local seeprefix = char(0) for i=1, #result do local entry = result[i] local split = { } local list = entry.list if list then + if entry.seeword then + -- we can have multiple seewords, only two levels supported + list[#list+1] = { seeprefix .. strip(entry.seeword.text) } + end for l=1,#list do local ll = list[l] local word = ll[1] @@ -848,7 +852,7 @@ function registers.prepare(data) entry.split = split end removeemptyentries(result) - crosslinkseewords(result) + crosslinkseewords(result,options.check ~= v_no) end end @@ -861,7 +865,9 @@ function registers.sort(data,options) end function registers.unique(data,options) - local result, nofresult, prev = { }, 0, nil + local result = { } + local nofresult = 0 + local prev = nil local dataresult = data.result for k=1,#dataresult do local v = dataresult[k] @@ -873,7 +879,8 @@ function registers.unique(data,options) elseif pr.realpage ~= vr.realpage then -- ok else - local pl, vl = pr.lastrealpage, vr.lastrealpage + local pl = pr.lastrealpage + local vl = vr.lastrealpage if pl or vl then if not vl then -- ok @@ -901,7 +908,11 @@ end function registers.finalize(data,options) -- maps character to index (order) local result = data.result data.metadata.nofsorted = #result - local split, nofsplit, lasttag, done, nofdone = { }, 0, nil, nil, 0 + local split = { } + local nofsplit = 0 + local lasttag = nil + local done = nil + local nofdone = 0 local firstofsplit = sorters.firstofsplit for k=1,#result do local v = result[k] @@ -922,8 +933,46 @@ function registers.finalize(data,options) -- maps character to index (order) data.result = split end +-- local function analyzeregister(class,options) +-- local data = collected[class] +-- if data and data.entries then +-- options = options or { } +-- sorters.setlanguage(options.language,options.method,options.numberorder) +-- registers.filter(data,options) -- filter entries into results (criteria) +-- registers.prepare(data,options) -- adds split table parallel to list table +-- registers.sort(data,options) -- sorts results +-- registers.unique(data,options) -- get rid of duplicates +-- registers.finalize(data,options) -- split result in ranges +-- data.metadata.sorted = true +-- return data.metadata.nofsorted or 0 +-- else +-- return 0 +-- end +-- end + local function analyzeregister(class,options) - local data = collected[class] + local data = rawget(collected,class) + if not data then + local list = utilities.parsers.settings_to_array(class) + local entries = { } + local metadata = false + for i=1,#list do + local l = list[i] + local d = collected[l] + local e = d.entries + for i=1,#e do + entries[#entries+1] = e[i] + end + if not metadata then + metadata = d.metadata + end + end + data = { + metadata = metadata or { }, + entries = entries, + } + collected[class] = data + end if data and data.entries then options = options or { } sorters.setlanguage(options.language,options.method,options.numberorder) @@ -973,8 +1022,10 @@ implement { -- todo: ownnumber local function pagerange(f_entry,t_entry,is_last,prefixspec,pagespec) - local fer, ter = f_entry.references, t_entry.references + local fer = f_entry.references + local ter = t_entry.references ctx_registerpagerange( + f_entry.metadata.name or "", f_entry.processors and f_entry.processors[2] or "", fer.internal or 0, fer.realpage or 0, @@ -996,6 +1047,7 @@ end local function pagenumber(entry,prefixspec,pagespec) local er = entry.references ctx_registeronepage( + entry.metadata.name or "", entry.processors and entry.processors[2] or "", er.internal or 0, er.realpage or 0, @@ -1004,7 +1056,8 @@ local function pagenumber(entry,prefixspec,pagespec) end local function packed(f_entry,t_entry) - local fer, ter = f_entry.references, t_entry.references + local fer = f_entry.references + local ter = t_entry.references ctx_registerpacked( fer.internal or 0, ter.internal or 0 @@ -1013,8 +1066,12 @@ end local function collapsedpage(pages) for i=2,#pages do - local first, second = pages[i-1], pages[i] - local first_first, first_last, second_first, second_last = first[1], first[2], second[1], second[2] + local first = pages[i-1] + local second = pages[i] + local first_first = first[1] + local first_last = first[2] + local second_first = second[1] + local second_last = second[2] local first_last_pn = first_last .references.realpage local second_first_pn = second_first.references.realpage local second_last_pn = second_last .references.realpage @@ -1110,7 +1167,8 @@ function registers.flush(data,options,prefixspec,pagespec) done[i] = false end local data = sublist.data - local d, n = 0, 0 + local d = 0 + local n = 0 ctx_startregistersection(sublist.tag) for d=1,#data do local entry = data[d] @@ -1126,6 +1184,7 @@ function registers.flush(data,options,prefixspec,pagespec) end -- ok, this is tricky: we use e[i] delayed so we need it to be local -- but we don't want to allocate too many entries so there we go + while d < #data do d = d + 1 local entry = data[d] @@ -1164,8 +1223,8 @@ function registers.flush(data,options,prefixspec,pagespec) started = false end if n == i then --- ctx_stopregisterentries() --- ctx_startregisterentries(n) + -- ctx_stopregisterentries() + -- ctx_startregisterentries(n) else while n > i do n = n - 1 @@ -1186,127 +1245,131 @@ function registers.flush(data,options,prefixspec,pagespec) ctx_startregisterentry(0) -- will become a counter started = true if metadata then - ctx_registerentry(processor,internal,seeparent,function() h_title(e[i],metadata) end) + ctx_registerentry(metadata.name or "",processor,internal,seeparent,function() h_title(e[i],metadata) end) else -- can this happen? - ctx_registerentry(processor,internal,seeindex,e[i]) + ctx_registerentry("",processor,internal,seeindex,e[i]) end end end - if kind == 'entry' then - if show_page_number then - ctx_startregisterpages() - if collapse_singles or collapse_ranges then - -- we collapse ranges and keep existing ranges as they are - -- so we get prebuilt as well as built ranges - local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0 - while dd < #data do - dd = dd + 1 - local next = data[dd] - if next and next.metadata.kind == "see" then - dd = dd - 1 - break - else - local el, nl = entry.list, next.list - if not equal(el,nl) then - dd = dd - 1 - --~ first = nil - break - elseif next.references.lastrealpage then - nofpages = nofpages + 1 - pages[nofpages] = first and { first, last or first } or { entry, entry } - nofpages = nofpages + 1 - pages[nofpages] = { next, next } - first, last, prev = nil, nil, nil - elseif not first then - first, prev = next, next - elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ? - last, prev = next, next - else - nofpages = nofpages + 1 - pages[nofpages] = { first, last or first } - first, last, prev = next, nil, next - end - end - end - if first then + + local function case_1() + -- we collapse ranges and keep existing ranges as they are + -- so we get prebuilt as well as built ranges + local first, last, prev, pages, dd, nofpages = entry, nil, entry, { }, d, 0 + while dd < #data do + dd = dd + 1 + local next = data[dd] + if next and next.metadata.kind == "see" then + dd = dd - 1 + break + else + local el, nl = entry.list, next.list + if not equal(el,nl) then + dd = dd - 1 + --~ first = nil + break + elseif next.references.lastrealpage then + nofpages = nofpages + 1 + pages[nofpages] = first and { first, last or first } or { entry, entry } + nofpages = nofpages + 1 + pages[nofpages] = { next, next } + first, last, prev = nil, nil, nil + elseif not first then + first, prev = next, next + elseif next.references.realpage - prev.references.realpage == 1 then -- 1 ? + last, prev = next, next + else nofpages = nofpages + 1 pages[nofpages] = { first, last or first } + first, last, prev = next, nil, next end - if collapse_ranges and nofpages > 1 then - nofpages = collapsepages(pages) - end - if nofpages > 0 then -- or 0 - d = dd - for p=1,nofpages do - local first, last = pages[p][1], pages[p][2] - if first == last then - if first.references.lastrealpage then - pagerange(first,first,true,prefixspec,pagespec) - else - pagenumber(first,prefixspec,pagespec) - end - elseif last.references.lastrealpage then - pagerange(first,last,true,prefixspec,pagespec) - else - pagerange(first,last,false,prefixspec,pagespec) - end + end + end + if first then + nofpages = nofpages + 1 + pages[nofpages] = { first, last or first } + end + if collapse_ranges and nofpages > 1 then + nofpages = collapsepages(pages) + end + if nofpages > 0 then -- or 0 + d = dd + for p=1,nofpages do + local first, last = pages[p][1], pages[p][2] + if first == last then + if first.references.lastrealpage then + pagerange(first,first,true,prefixspec,pagespec) + else + pagenumber(first,prefixspec,pagespec) end - elseif entry.references.lastrealpage then - pagerange(entry,entry,true,prefixspec,pagespec) + elseif last.references.lastrealpage then + pagerange(first,last,true,prefixspec,pagespec) else - pagenumber(entry,prefixspec,pagespec) + pagerange(first,last,false,prefixspec,pagespec) end - elseif collapse_packed then - local first = nil - local last = nil - while true do - if not first then - first = entry - end - last = entry - if d == #data then - break - else - d = d + 1 - local next = data[d] - if next.metadata.kind == "see" or not equal(entry.list,next.list) then - d = d - 1 - break - else - entry = next - end - end + end + elseif entry.references.lastrealpage then + pagerange(entry,entry,true,prefixspec,pagespec) + else + pagenumber(entry,prefixspec,pagespec) + end + end + + local function case_2() + local first = nil + local last = nil + while true do + if not first then + first = entry + end + last = entry + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next end - packed(first,last) -- returns internals + end + end + packed(first,last) -- returns internals + end + + local function case_3() + while true do + if entry.references.lastrealpage then + pagerange(entry,entry,true,prefixspec,pagespec) else - while true do - if entry.references.lastrealpage then - pagerange(entry,entry,true,prefixspec,pagespec) - else - pagenumber(entry,prefixspec,pagespec) - end - if d == #data then - break - else - d = d + 1 - local next = data[d] - if next.metadata.kind == "see" or not equal(entry.list,next.list) then - d = d - 1 - break - else - entry = next - end - end + pagenumber(entry,prefixspec,pagespec) + end + if d == #data then + break + else + d = d + 1 + local next = data[d] + if next.metadata.kind == "see" or not equal(entry.list,next.list) then + d = d - 1 + break + else + entry = next end end - ctx_stopregisterpages() end - elseif kind == 'see' then - local t, nt = { }, 0 + end + + local function case_4() + local t = { } + local nt = 0 while true do - nt = nt + 1 - t[nt] = entry + if entry.seeword and entry.seeword.valid then + nt = nt + 1 + t[nt] = entry + end if d == #data then break else @@ -1320,19 +1383,36 @@ function registers.flush(data,options,prefixspec,pagespec) end end end - ctx_startregisterseewords() for i=1,nt do - local entry = t[i] + local entry = t[i] local seeword = entry.seeword local seetext = seeword.text or "" local processor = seeword.processor or (entry.processors and entry.processors[1]) or "" local seeindex = entry.references.seeindex or "" - -- ctx_registerseeword(i,nt,processor,0,seeindex,seetext) - ctx_registerseeword(i,nt,processor,0,seeindex,function() h_title(seetext,metadata) end) + ctx_registerseeword(metadata.name or "",i,nt,processor,0,seeindex,function() h_title(seetext,metadata) end) end + end + + if kind == "entry" then + if show_page_number then + ctx_startregisterpages() + if collapse_singles or collapse_ranges then + case_1() + elseif collapse_packed then + case_2() + else + case_3() + end + ctx_stopregisterpages() + end + elseif kind == "see" then + ctx_startregisterseewords() + case_4() ctx_stopregisterseewords() end + end + if started then ctx_stopregisterentry() started = false @@ -1373,6 +1453,7 @@ implement { { "numberorder" }, { "compress" }, { "criterium" }, + { "check" }, { "pagenumber", "boolean" }, }, { diff --git a/tex/context/base/mkiv/strc-reg.mkiv b/tex/context/base/mkiv/strc-reg.mkiv index 04fdef9ad..559e1bd42 100644 --- a/tex/context/base/mkiv/strc-reg.mkiv +++ b/tex/context/base/mkiv/strc-reg.mkiv @@ -83,6 +83,7 @@ \c!pagestyle=\v!slanted, \c!indicator=\v!yes, \c!criterium=\v!all, + \c!check=\v!yes, % check for weird see usage %\c!command=, \c!referencing=\v!on, \c!location=\v!middle, @@ -159,8 +160,8 @@ %D Registering: -\global\let\currentregistername \empty -\global\let\currentregisternumber\!!zerocount +\glet\currentregistername \empty +\glet\currentregisternumber\!!zerocount \def\strc_registers_register_page_entry {\iftrialtypesetting @@ -175,33 +176,33 @@ \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% \xmlstopraw - \globallet\currentregistercoding\s!xml} + \glet\currentregistercoding\s!xml} \def\strc_registers_register_page_expand_yes_entries {\xdef\currentregisterentriesa{\registerparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\registerparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\registerparameter{\c!entries:3}}% - \globallet\currentregistercoding\s!tex} + \glet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_nop_entries {\xdef\currentregisterentriesa{\detokenizedregisterparameter{\c!entries:1}}% \xdef\currentregisterentriesb{\detokenizedregisterparameter{\c!entries:2}}% \xdef\currentregisterentriesc{\detokenizedregisterparameter{\c!entries:3}}% - \globallet\currentregistercoding\s!tex} + \glet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_xml {\xmlstartraw \xdef\currentregisterentries{\registerparameter\c!entries}% \xmlstopraw - \globallet\currentregistercoding\s!xml} + \glet\currentregistercoding\s!xml} \def\strc_registers_register_page_expand_yes {\xdef\currentregisterentries{\registerparameter\c!entries}% - \globallet\currentregistercoding\s!tex} + \glet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_nop {\xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% - \globallet\currentregistercoding\s!tex} + \glet\currentregistercoding\s!tex} \def\strc_registers_register_page_expand_xml_keys {\xmlstartraw @@ -304,7 +305,7 @@ \ifx\currentregisterownnumber\v!yes \glet\currentregistersynchronize\relax \else - \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}% + \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}% \fi \currentregistersynchronize % here? % needs thinking ... bla\index{bla}. will break before the . but adding a @@ -340,7 +341,7 @@ % internal \locationcount % view {\interactionparameter\c!focus}% \relax % this will change - \xdef\currentregistersynchronize{\ctxlatecommand{enhanceregister("\currentregister",\currentregisternumber)}}% + \xdef\currentregistersynchronize{\clf_deferredenhanceregister{\currentregister}\number\currentregisternumber}% \currentregistersynchronize % here? \dostarttagged\t!registerlocation\currentregister \attribute\destinationattribute\lastdestinationattribute \signalcharacter % no \strut as it will be removed during cleanup @@ -352,16 +353,46 @@ \unexpanded\def\strc_registers_insert_entry[#1][#2]% {\def\currentregister{#1}% - \doifelse{\registerparameter\c!ownnumber}\v!yes - \strc_registers_insert_entry_yes - \strc_registers_insert_entry_nop - {#2}} + \edef\p_ownnumber{\registerparameter\c!ownnumber}% + \ifx\p_ownnumber\v!yes + \expandafter\strc_registers_insert_entry_yes + \else + \expandafter\strc_registers_insert_entry_nop + \fi{#2}} + +% \def\strc_registers_insert_entry_nop#1#2% +% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}} +% +% \def\strc_registers_insert_entry_yes#1#2#3% +% {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}} +% +% less tokens passed (nicer for tracing) .. could become installable + +\def\strc_registers_insert_entry_nop + {\ifvmode + \expandafter\strc_registers_insert_entry_nop_par + \else + \expandafter\strc_registers_insert_entry_nop_txt + \fi} + +\def\strc_registers_insert_entry_yes + {\ifvmode + \expandafter\strc_registers_insert_entry_yes_par + \else + \expandafter\strc_registers_insert_entry_yes_txt + \fi} + +\def\strc_registers_insert_entry_nop_par#1#2% + {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}} -\def\strc_registers_insert_entry_nop#1#2% - {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}}} +\def\strc_registers_insert_entry_yes_par#1#2#3% + {\flushatnextpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}} -\def\strc_registers_insert_entry_yes#1#2#3% - {\doflushatpar{\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}}} +\def\strc_registers_insert_entry_nop_txt#1#2% + {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!entries={#2}}{}} + +\def\strc_registers_insert_entry_yes_txt#1#2#3% + {\strc_registers_register_page_entry\currentregister{\c!keys={#1},\c!alternative=#2,\c!entries={#3}}{}} \unexpanded\def\startregister{\doquadrupleempty\strc_registers_start_entry} \unexpanded\def\stopregister {\dodoubleargument\strc_registers_stop_entry} @@ -403,14 +434,14 @@ \xmlstartraw \xdef\currentregisterentries{\registerparameter\c!entries}% \xmlstopraw - \globallet\currentregistercoding\s!xml + \glet\currentregistercoding\s!xml \else \ifx\currentregisterexpansion\v!yes \xdef\currentregisterentries{\registerparameter\c!entries}% \else \xdef\currentregisterentries{\detokenizedregisterparameter\c!entries}% \fi - \globallet\currentregistercoding\s!tex + \glet\currentregistercoding\s!tex \fi % I hate this kind of mess ... but it's a user request. \ifx\currentregisterentries\empty @@ -493,7 +524,7 @@ \xdef\currentregisterentries{\detokenize{#3}}% not ok yet \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet \xmlstopraw - \globallet\currentregistercoding\s!xml + \glet\currentregistercoding\s!xml \else \ifx\currentregisterexpansion\v!yes \xdef\currentregisterentries{#3}% not ok yet @@ -502,7 +533,7 @@ \xdef\currentregisterentries{\detokenize{#3}}% not ok yet \xdef\currentregisterseeword{\detokenize{#4}}% not ok yet \fi - \globallet\currentregistercoding\s!tex + \glet\currentregistercoding\s!tex \fi \setnextinternalreference % we could consider storing register entries in list @@ -544,8 +575,8 @@ \def\strc_registers_determine_characteristics[#1][#2]% {\begingroup - \edef\currentregister{#1}% - \setupregister[\currentregister][#2]% + \setupregister[#1][#2]% + \edef\currentregister{\firstinset{#1}}% \normalexpanded{\endgroup\noexpand\xdef\noexpand\utilityregisterlength{\clf_analyzeregister {\currentregister}% {% @@ -569,6 +600,8 @@ \dontcomplain \to \everyplaceregister +\newconditional\c_strc_registers_text_interaction + \unexpanded\def\placeregister {\dodoubleempty\strc_registers_place} @@ -576,30 +609,29 @@ {\iffirstargument \begingroup %\forgetall - \edef\currentregister{#1}% - \setupregister[\currentregister][#2]% + \setupregister[#1][#2]% can be a list + \edef\currentregister{\firstinset{#1}}% \the\everyplaceregister \ifnum\namedmixedcolumnsparameter\currentregister\c!n>\plusone \startmixedcolumns[\currentregister] - \strc_registers_place_indeed + \strc_registers_place_indeed{#1}% \stopmixedcolumns \else - \strc_registers_place_indeed + \strc_registers_place_indeed{#1}% \fi \endgroup \fi} -\newconditional\c_strc_registers_text_interaction - -\def\strc_registers_place_indeed +\def\strc_registers_place_indeed#1% {\doifelse{\registerparameter\c!interaction}\v!text \settrue\setfalse\c_strc_registers_text_interaction \clf_processregister - {\currentregister}% + {#1}% {% language {\registerparameter\s!language}% method {\registerparameter\c!method}% numberorder {\registerparameter\c!numberorder}% + check {\registerparameter\c!check}% compress {\registerparameter\c!compress}% criterium {\registerparameter\c!criterium}% pagenumber \ifx\registerpageseparatorsymbol\empty false\else true\fi @@ -639,9 +671,9 @@ \def\strc_registers_complete[#1][#2]% {\iffirstargument \begingroup - \edef\currentregister{#1}% + \edef\currentregister{\firstinset{#1}}% \normalexpanded{\startnamedsection[\v!chapter][\c!title={\headtext{\currentregister}},reference=\currentregister]}% - \placeregister[\currentregister][#2]% + \placeregister[#1][#2]% \page[\v!yes]% \stopnamedsection \endgroup @@ -835,15 +867,16 @@ \unexpanded\def\startregisterpages {\begingroup \dostarttagged\t!registerpages\empty - \useregisterstyleandcolor\c!pagestyle\c!pagecolor} + \useregisterstyleandcolor\c!pagestyle\c!pagecolor + \registerparameter\c!pageleft} \unexpanded\def\stopregisterpages - {\dostoptagged + {\registerparameter\c!pageright + \dostoptagged \endgroup} \unexpanded\def\startregisterseewords - {%\par % \ifhmode\crlf\fi % otherwise wrong level - \begingroup + {\begingroup \dostarttagged\t!registerpage\empty \useregisterstyleandcolor\c!pagestyle\c!pagecolor} @@ -876,46 +909,69 @@ % \fi} \unexpanded\def\withregisterpagecommand#1#2#3#4% - {\def\currentregisterpageindex{#2}% - \iflocation - \strc_references_goto_internal{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]% + {\ifcase#3\relax + {\tt [entry\space not\space flushed]}% \else - \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}% + \def\currentregisterpageindex{#2}% + \iflocation + \strc_references_goto_internal{\applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}}[internal(#2)]% + \else + \applyprocessor{#1}{\registerparameter\c!pagecommand{#4}}% + \fi \fi} -\unexpanded\def\registeronepage#1#2#3#4% #1:processor content - {\registerpageseparator - \global\setconstant\c_strc_registers_page_state\plusone - \dostarttagged\t!registerpage\empty - \withregisterpagecommand{#1}{#2}{#3}{#4}% - \dostoptagged} - -\unexpanded\def\registerpagerange#1#2#3#4#5#6#7% #1:processor content, content todo: -- configurable - {\registerpageseparator - \global\setconstant\c_strc_registers_page_state\plusone - \dostarttagged\t!registerpagerange\empty - \dostarttagged\t!registerfrompage\empty - \withregisterpagecommand{#1}{#2}{#3}{#4}% - \dostoptagged - \registeronepagerangeseparator - \dostarttagged\t!registertopage\empty - \withregisterpagecommand{#1}{#5}{#6}{#7}% - \dostoptagged - \dostoptagged} +\unexpanded\def\pushcurrentregister#1% + {\let\m_current_register\currentregister + \edef\currentregister{#1}} + +\unexpanded\def\popcurrentregister + {\let\currentregister\m_current_register} + +\unexpanded\def\registeronepage#1#2#3#4#5% #1:class #2:processor content + {\pushcurrentregister{#1}% + \edef\p_pagenumber{\registerparameter\c!pagenumber}% + \ifx\p_pagenumber\v!no\else + \registerpageseparator + \global\setconstant\c_strc_registers_page_state\plusone + \dostarttagged\t!registerpage\empty + \withregisterpagecommand{#2}{#3}{#4}{#5}% + \dostoptagged + \fi + \popcurrentregister} + +\unexpanded\def\registerpagerange#1#2#3#4#5#6#7#8% #1:class #2:processor content, content todo: -- configurable + {\pushcurrentregister{#1}% + \edef\p_pagenumber{\registerparameter\c!pagenumber}% + \ifx\p_pagenumber\v!no\else + \registerpageseparator + \global\setconstant\c_strc_registers_page_state\plusone + \dostarttagged\t!registerpagerange\empty + \dostarttagged\t!registerfrompage\empty + \withregisterpagecommand{#2}{#3}{#4}{#5}% + \dostoptagged + \registeronepagerangeseparator + \dostarttagged\t!registertopage\empty + \withregisterpagecommand{#2}{#6}{#7}{#8}% + \dostoptagged + \dostoptagged + \fi + \popcurrentregister} -\unexpanded\def\defaultregisterentry#1#2#3#4% #1:processor #2:internal #3:seeindex #4:word - {\def\currentregisterpageindex{#2}% +\unexpanded\def\defaultregisterentry#1#2#3#4#5% #1:class #2:processor #3:internal #4:seeindex #5:word + {\pushcurrentregister{#1}% + \def\currentregisterpageindex{#3}% \iflocation - \def\currentregisterseeindex{#3}% + \def\currentregisterseeindex{#4}% \ifconditional\c_strc_registers_text_interaction - \strc_references_goto_internal{\setlocationcolor\doapplyregisterentrycommand{#1}{#4}}[internal(#2)]% + \strc_references_goto_internal{\setlocationcolor\doapplyregisterentrycommand{#2}{#5}}[internal(#3)]% \else - \doapplyregisterentrycommand{#1}{#4}% + \doapplyregisterentrycommand{#2}{#5}% \fi \else \let\currentregisterseeindex\empty - \doapplyregisterentrycommand{#1}{#4}% - \fi} + \doapplyregisterentrycommand{#2}{#5}% + \fi + \popcurrentregister} \unexpanded\def\doapplyregisterentrycommand#1#2% processor text {\dostarttagged\t!registercontent\empty @@ -935,25 +991,29 @@ \applyprocessor{#1}{#2}% \fi\fi} -\unexpanded\def\defaultregisterseeword#1#2#3#4#5#6% i n #3:processor #4:internal #5:seeindex #6:word - {\registerpageseparator +\unexpanded\def\defaultregisterseeword#1#2#3#4#5#6#7% class i n #3:processor #4:internal #5:seeindex #6:word + {\pushcurrentregister{#1}% + \ifnum#2=\plusone + \registerpageseparator + \fi \global\setconstant\c_strc_registers_page_state\plustwo - \def\currentregisterpageindex{#4}% + \def\currentregisterpageindex{#5}% \dostarttagged\t!registersee\empty \settrue\c_strc_registers_page_done \iflocation - \def\currentregisterseeindex{#5}% + \def\currentregisterseeindex{#6}% \else \let\currentregisterseeindex\empty \fi - \ifnum#1=\plusone - \labeltexts\v!see{\doapplyregisterseecommand{#3}{#6}}% - \else\ifnum#1=#2\relax - \labeltexts\v!and{\doapplyregisterseecommand{#3}{#6}}% + \ifnum#2=\plusone + \labeltexts\v!see{\doapplyregisterseecommand{#4}{#7}}% + \else\ifnum#2=#3\relax + \labeltexts\v!and{\doapplyregisterseecommand{#4}{#7}}% \else - ,\space\doapplyregisterseecommand{#3}{#6}% + ,\space\doapplyregisterseecommand{#4}{#7}% \fi\fi - \dostoptagged} + \dostoptagged + \popcurrentregister} \let\registerseeword \defaultregisterseeword \let\registerentry \defaultregisterentry @@ -993,18 +1053,18 @@ \setvalue{\??registersymbol\v!none}% {\let\registerpageseparatorsymbol\empty - \let\registeronepage \gobblefourarguments - \let\registerpagerange \gobblesevenarguments} + \let\registeronepage \gobblefivearguments + \let\registerpagerange\gobbleeightarguments} \setvalue{\??registersymbol 1}% {\let\registerpageseparatorsymbol\space - \def\registeronepage {\symbol[1]\gobblefourarguments}% - \def\registerpagerange{\symbol[1]\gobblesevenarguments}} + \def\registeronepage {\symbol[1]\gobblefivearguments}% + \def\registerpagerange{\symbol[1]\gobbleeightarguments}} \setvalue{\??registersymbol 2}% {\let\registerpageseparatorsymbol\space - \def\registeronepage {\registerpagebuttonsymbol\gobblefourarguments}% - \def\registerpagerange{\registerpagebuttonsymbol\gobblesevenarguments}} + \def\registeronepage {\registerpagebuttonsymbol\gobblefivearguments}% + \def\registerpagerange{\registerpagebuttonsymbol\gobbleeightarguments}} \unexpanded\def\setregisterpagerendering {\doifelse{\registerparameter\c!pagenumber}\v!no @@ -1016,8 +1076,8 @@ \csname\??registersymbol\currentregisterpagesymbol\endcsname \else \let\registerpageseparatorsymbol\space - \def\registeronepage{\registerparameter\c!symbol\gobblefourarguments}% - \def\registerpagerange{\registerparameter\c!symbol\gobblesevenarguments}% + \def\registeronepage {\registerparameter\c!symbol\gobblefivearguments}% + \def\registerpagerange{\registerparameter\c!symbol\gobbleeightarguments}% \fi\fi} \appendtoks diff --git a/tex/context/base/mkiv/strc-ren.mkiv b/tex/context/base/mkiv/strc-ren.mkiv index 89aa6f55a..01464ad86 100644 --- a/tex/context/base/mkiv/strc-ren.mkiv +++ b/tex/context/base/mkiv/strc-ren.mkiv @@ -120,7 +120,7 @@ \setheadmarking \doresetstructureheadnumbercontent \ifconditional\c_strc_sectioning_empty - \setbox\b_strc_rendering_head\hbox \headreferenceattributes to \zeropoint{\strut}% + \setbox\b_strc_rendering_head\hpack \headreferenceattributes to \zeropoint{\strut}% \else \docheckheadreference \setbox\b_strc_rendering_head\hbox \headreferenceattributes @@ -139,7 +139,7 @@ \dosetstructureheadnumbercontent \doresetstructureheadnumbercontent \ifconditional\c_strc_sectioning_empty - \setbox\b_strc_rendering_head\hbox \headreferenceattributes to \zeropoint{\strut}% + \setbox\b_strc_rendering_head\hpack \headreferenceattributes to \zeropoint{\strut}% \else % = needed \docheckheadreference \setbox\b_strc_rendering_head\hbox \headreferenceattributes @@ -151,7 +151,7 @@ \strc_rendering_stop_placement} \unexpanded\def\strc_rendering_place_head_empty - {\hbox\headreferenceattributes{\getheadsyncs}} % \hpack ? + {\hpack\headreferenceattributes{\getheadsyncs}} %D \starttyping %D \def\StretchedBox#1% @@ -197,14 +197,13 @@ \def\strc_rendering_start_placement {\bgroup \setsystemmode\currenthead - % \strc_rendering_initialize_alternatives \strc_rendering_initialize_dimensions - % \strc_rendering_initialize_line_state \reseteverypar % needed indeed \noindent % ipv \whitespace elders, na \forgetall ! \bgroup + \synctexpushline \edef\p_aligntitle{\headparameter\c!aligntitle}% \ifx\p_aligntitle\v!yes \strc_rendering_initialize_hsize_local @@ -325,7 +324,9 @@ % kind of special, we want to snap heads also according to local specs local \setbox\b_strc_rendering_head\hbox {\hskip\dimexpr\d_strc_rendering_local_leftoffset+\headparameter\c!margin\relax - \box\b_strc_rendering_head}% + \box\b_strc_rendering_head + \getheadsyncs % a latelua why not in the box + }% \ifgridsnapping \applygridmethod {\headparameter\c!grid}% @@ -345,14 +346,14 @@ \nointerlineskip \dosomebreak\nobreak \fi - \getheadsyncs +% \getheadsyncs % a latelua why not in the box \else % somehow this goes ok even when we push in the margin probably because we gobble pars % in the process of collecting index entries etc \strut \flushnotes % new, here since we're in par mode \unhbox\b_strc_rendering_head - \getheadsyncs + \getheadsyncs % a latelua \ifconditional\headissomewhere \strc_sectioning_stay_on_this_line % test case: alternative=margintext and \startparagraph .. \else @@ -370,6 +371,7 @@ \fi \fi \fi + \synctexpopline \egroup \egroup \ifconditional\headisdisplay @@ -528,8 +530,14 @@ \def\fakedheadnumber{\vphantom{0}} % needed for mathplus +% \unexpanded\def\fakeheadnumbercontent +% {\hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}} + \unexpanded\def\fakeheadnumbercontent - {\hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}} + {\edef\p_hidenumber{\headparameter\c!hidenumber}% + \ifx\p_hidenumber\v!yes\else + \hbox to \zeropoint{\let\getheadnumber\fakedheadnumber\headnumbercontent}% + \fi} \unexpanded\def\strc_rendering_inject_number_and_text {\edef\p_command{\headparameter\c!command}% assumes \unexpanded definition @@ -777,18 +785,18 @@ \startsetups[\??headrenderings:\v!bottom] \ifconditional\headshownumber - \setbox0\hbox { + \setbox\scratchboxone\hbox { \headnumbercontent } - \setbox2\vbox { + \setbox\scratchboxtwo\vbox { \headsetupspacing - \advance\hsize-\wd0\relax + \advance\hsize-\wd\scratchboxone\relax \headtextcontent } \hbox { - \box0 + \box\scratchboxone \hskip\headnumberdistance - \box2 + \box\scratchboxtwo } \else \vbox { @@ -806,18 +814,18 @@ \startsetups[\??headrenderings:\v!top] \ifconditional\headshownumber - \setbox0\hbox { + \setbox\scratchboxone\hbox { \headnumbercontent } - \setbox2\vtop { + \setbox\scratchboxtwo\vtop { \headsetupspacing - \advance\hsize-\wd0\relax + \advance\hsize-\wd\scratchboxone\relax \headtextcontent } \hbox { - \box0 + \box\scratchboxone \hskip\headnumberdistance - \box2 + \box\scratchboxtwo } \else \vtop{ diff --git a/tex/context/base/mkiv/strc-sbe.mkiv b/tex/context/base/mkiv/strc-sbe.mkiv index 9f1d214cf..005f03df3 100644 --- a/tex/context/base/mkiv/strc-sbe.mkiv +++ b/tex/context/base/mkiv/strc-sbe.mkiv @@ -45,7 +45,7 @@ \def\strc_sectionblock_define[#1][#2][#3]% singular plural settings {\strc_sectionblock_define_normal[#1][#3]% - \expandafter\newif\csname if#2\endcsname % obsolete + %\expandafter\newif\csname if#2\endcsname % obsolete \strc_sectionblock_set_environment{#1}\empty \setuvalue{\e!start#2}{\startsectionblock[#1]}% \setuvalue{\e!stop #2}{\stopsectionblock}} @@ -98,7 +98,7 @@ \clf_pushsectionblock{#1} bookmark {\sectionblockparameter\c!bookmark}% \relax - \csname #1true\endcsname % obsolete + %\csname #1true\endcsname % obsolete \setsystemmode\currentsectionblock \the\everybeforesectionblock\relax \showmessage\m!structures1\currentsectionblock} diff --git a/tex/context/base/mkiv/strc-sec.mkiv b/tex/context/base/mkiv/strc-sec.mkiv index 4e5115a7d..4066a1f38 100644 --- a/tex/context/base/mkiv/strc-sec.mkiv +++ b/tex/context/base/mkiv/strc-sec.mkiv @@ -35,6 +35,7 @@ \c!label=, \c!coupling=, \c!ownnumber=, + % \c!interaction=\v!list, \c!sectionseparatorset=\s!default, \c!sectionconversionset=\s!default, \c!sectionstopper=, @@ -53,6 +54,10 @@ \def\m_strc_references_prefix_yes{+} \def\m_strc_references_prefix_nop{-} +\let\currentstructurereferenceprefix\empty + +\installglobalmacrostack\currentstructurereferenceprefix + \def\strc_sectioning_set_reference_prefix {\ifx\currentstructurereferenceprefix\empty % nothing @@ -64,7 +69,7 @@ \else \setupglobalreferenceprefix[\currentstructurereferenceprefix]% \fi\fi\fi - \let\currentstructurereferenceprefix\referenceprefix} + \glet\currentstructurereferenceprefix\referenceprefix} % why xdef ? @@ -108,9 +113,10 @@ \def\strc_sectioning_autobookmark#1% {\begingroup + % \settrialtypesetting \the\everypreroll \nodestostring\tempstring{#1}% - \globallet\currentstructurebookmark\tempstring + \glet\currentstructurebookmark\tempstring \endgroup} % zeros: @@ -150,9 +156,9 @@ \strc_sectioning_autobookmark\currentstructuretitle \fi \fi \fi \ifx\currentstructurelist\empty - \globallet\currentstructurelist\currentstructuretitle + \glet\currentstructurelist\currentstructuretitle \fi - \globallet\currentstructurecoding\s!xml + \glet\currentstructurecoding\s!xml \else \ifx\currentstructureexpansion\v!yes \xdef\currentstructuretitle {\structureparameter\c!title}% @@ -179,9 +185,9 @@ \fi \fi \fi \ifx\currentstructurelist\empty - \globallet\currentstructurelist\currentstructuretitle + \glet\currentstructurelist\currentstructuretitle \fi - \globallet\currentstructurecoding\s!tex + \glet\currentstructurecoding\s!tex \fi \setnextinternalreference \storeinternalreference\currentstructurename{\the\locationcount}% @@ -249,7 +255,7 @@ userdata {\detokenize{#3}}% will be converted to table at the lua end \relax \xdef\currentstructurelistnumber{\clf_currentsectiontolist}% - % \currentstructuresynchronize has to be called someplace, since it introduces a node + % \currentstructuresynchronize has to be called someplace, since it introduces a node \setstructuresynchronization\currentstructurelistnumber \endgroup} @@ -340,6 +346,9 @@ \installcommandhandler \??head {head} \??head +\installmacrostack\currenthead +\installmacrostack\currentheadparent + \setuphead [% %\c!after=, %\c!align=, @@ -479,16 +488,18 @@ \to \everysetuphead \unexpanded\def\doredefinehead#1#2% called at lua end - {\pushmacro\currenthead - \pushmacro\currentheadparent + {\push_macro_currenthead + \push_macro_currentheadparent \edef\currenthead{#1}% \edef\currentheadparent{#2}% \the\everyredefinehead\relax - \popmacro\currentheadparent - \popmacro\currenthead} + \pop_macro_currentheadparent + \pop_macro_currenthead} \let\currentnamedsection\empty +\installmacrostack\currentnamedsection + \unexpanded\def\startnamedsection {\dotripleempty\strc_sectioning_start_named_section} @@ -577,7 +588,7 @@ \fi} \def\strc_sectioning_setup_indeed[#1][#2][#3]% - {\pushmacro\currenthead + {\push_macro_currenthead \ifthirdargument \edef\currenthead{#1#2}% % not used at any more in mkiv (sets now) \setupcurrenthead[#3]% @@ -585,7 +596,7 @@ \edef\currenthead{#1}% \setupcurrenthead[#2]% \fi - \popmacro\currenthead} + \pop_macro_currenthead} % we share the parameters as sections are roots of heads so eventually we can % consider \definesection -> \definehead with one argument @@ -638,7 +649,8 @@ {\strc_sectioning_handle{#1}{\c!reference={#2},\c!title={#3}}{}} % name ref nr title -- \unexpanded\def\strc_sectioning_start_named_section[#1][#2][#3]% for the moment no grouping, too annoying with page breaks - {\pushmacro\currentnamedsection + {\push_macro_currentnamedsection + \push_macro_currentstructurereferenceprefix \edef\currentnamedsection{#1}% \setfalse\currentstructureown %\globalpushmacro\currenthead % this does not work out well @@ -659,7 +671,8 @@ \headparameter\c!aftersection \the\everyafterhead \resetsystemmode\currenthead - \popmacro\currentnamedsection} % new, also here now + \pop_macro_currentstructurereferenceprefix + \pop_macro_currentnamedsection} % new, also here now \let\dostarthead\strc_sectioning_start % used at lua end \let\dostophead \strc_sectioning_stop % used at lua end @@ -755,15 +768,25 @@ \setfalse\headshownumber \fi} +% Beware, we do need some node for anchoring marks and normally a zwnj will +% do but it interferes so we deal with it at the \LUA\ end. + \newtoks\everyheadsynchronization +% \appendtoks +% \currentstructuresynchronize +% \to \everyheadsynchronization + +\let\currentstructuresynchronize\donothing + \appendtoks \currentstructuresynchronize + \glet\currentstructuresynchronize\donothing \to \everyheadsynchronization \unexpanded\def\theheadsynchonization - {\the\everyheadsynchronization - \currentstructuresynchronize} + {% no, interferes: \signalcharacter + \the\everyheadsynchronization} % BEWARE: \marking[section]{my text} does not work as we use list indices instead % so we need a 'keep track of raw set option' (or maybe a funny internal prefix) @@ -802,6 +825,17 @@ \let\currentheadlevel \!!zerocount \let\currentheadcounter \!!zerocount +\let\strc_show_used\relax + +\installtextracker + {structures.showused} + {\let\strc_show_used\clf_showstructure} + {\let\strc_show_used\relax} + +\appendtoks + \strc_show_used +\to \everystoptext + \unexpanded\def\placeheadtext {\dosingleempty\strc_sectioning_place_head_text } % use with care \unexpanded\def\placeheadnumber{\dosingleempty\strc_sectioning_place_head_number} % use with care @@ -842,6 +876,9 @@ \ifdefined\triggerautostructurelevel \else \let\triggerautostructurelevel\relax \fi +\newtoks\everybeforesectionheadhandle +\newtoks\everyaftersectionheadhandle + \def\strc_sectioning_handle#1#2#3% name data userdata (we can move #1 to the caller) {\xdef\currenthead {#1}% \xdef\currentheadcoupling{\sectionheadcoupling\currenthead}% @@ -855,7 +892,7 @@ \strc_sectioning_initialize_placement \strc_sectioning_initialize_number % - \flushingcolumnfloatsfalse + \the\everybeforesectionheadhandle % % todo: also mark (for header) % @@ -941,7 +978,9 @@ \strc_sectioning_after_nop \fi\fi \fi - \flushingcolumnfloatstrue + % + \the\everyaftersectionheadhandle + % \setfalse\c_strc_sectioning_ignore_page % ignorespaces prevents spaces creeping in when after=\dontleavehmode \dostarttagged\t!sectioncontent\empty @@ -983,8 +1022,8 @@ \unexpanded\def\strc_rendering_place_head_section % see hidden below {\global\setbox\b_sectioning_delayed\hpack\bgroup \setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% - \hpack\headreferenceattributes{}% - \currentstructuresynchronize + \hpack\headreferenceattributes{}% also does the mark + \theheadsynchonization \egroup} \unexpanded\def\strc_rendering_place_head_hidden % maybe trialtypesetting check @@ -994,7 +1033,7 @@ {\noexpand\letgvalue{\??hiddenheadsync\currenthead}\relax \noexpand\setmarking[\currentheadcoupling]{li::\currentstructurelistnumber}% \hpack\headreferenceattributes{}% otherwise no destination ... maybe tag ref as hidden and fall back on page reference - \currentstructuresynchronize}} % and it's a node anyway + \theheadsynchonization}} % and it's a node anyway \def\synchronizehead #1{\csname\??hiddenheadsync#1\endcsname} \def\theheadreferenceattributes#1{\csname\??hiddenheadattr#1\endcsname} @@ -1003,6 +1042,26 @@ \unexpanded\def\placerawheadtext [#1]{\getspecificstructuretitle{\thenamedheadlevel{#1}}} \unexpanded\def\placerawheadnumber[#1]{\getfullstructurenumber{\thenamedheadlevel{#1}}} +\unexpanded\def\repeathead[#1]% + {\begingroup + \setupinteraction[\c!state=\v!stop]% + \def\currenthead{#1} + \strc_sectioning_initialize_placement + \strc_sectioning_initialize_number + \dostarttagged\t!sectioncaption\empty + \let\getheadsyncs \relax + \def\getheadtitle {\getmarking[#1]} + \def\getheadnumber{\getmarking[#1\v!number]} + \strc_sectioning_before_yes + \ifconditional\headshownumber + \strc_rendering_place_head_number_and_text + \else + \strc_rendering_place_head_text + \fi + \dostoptagged + \strc_sectioning_after_yes + \endgroup} + % \setuphead[chapter][placehead=hidden] % \chapter {test} % @@ -1154,7 +1213,7 @@ \else \strc_sectioning_check_layout \fi - \globallet\previoushead\currenthead} + \glet\previoushead\currenthead} \def\strc_sectioning_handle_page_yes {\ifconditional\c_strc_sectioning_ignore_page @@ -1178,7 +1237,7 @@ \fi \global\c_strc_sectioning_preceding_level\currentheadlevel \fi - \globallet\previoushead\currenthead} + \glet\previoushead\currenthead} \unexpanded\def\strc_sectioning_prevent_page_break#1% see strc-con {\ifconditional\c_strc_sectioning_auto_break diff --git a/tex/context/base/mkiv/strc-syn.mkiv b/tex/context/base/mkiv/strc-syn.mkiv index 1fb079f04..7f71e88f5 100644 --- a/tex/context/base/mkiv/strc-syn.mkiv +++ b/tex/context/base/mkiv/strc-syn.mkiv @@ -114,14 +114,14 @@ \xmlstartraw \xdef#2{#4}% \xmlstopraw - \globallet#3\s!xml + \glet#3\s!xml \else \ifx#1\v!yes \xdef#2{#4}% \else \xdef#2{\detokenize{#4}}% \fi - \globallet#3\s!tex + \glet#3\s!tex \fi} %D We now use a simple list variant: diff --git a/tex/context/base/mkiv/strc-tag.lua b/tex/context/base/mkiv/strc-tag.lua index 649465a6a..0453640ca 100644 --- a/tex/context/base/mkiv/strc-tag.lua +++ b/tex/context/base/mkiv/strc-tag.lua @@ -15,7 +15,6 @@ local type, next = type, next local insert, remove, unpack, concat, merge = table.insert, table.remove, table.unpack, table.concat, table.merge local find, topattern, format = string.find, string.topattern, string.format local lpegmatch, P, S, C, Cc = lpeg.match, lpeg.P, lpeg.S, lpeg.C, lpeg.Cc -local texattribute = tex.attribute local allocate = utilities.storage.allocate local settings_to_hash = utilities.parsers.settings_to_hash local setmetatableindex = table.setmetatableindex @@ -24,34 +23,44 @@ local trace_tags = false trackers.register("structures.tags", function(v) trace local report_tags = logs.reporter("structure","tags") -local attributes = attributes -local structures = structures -local implement = interfaces.implement - -local a_tagged = attributes.private('tagged') - -local unsetvalue = attributes.unsetvalue -local codeinjections = backends.codeinjections - -local taglist = allocate() -- access by attribute -local specifications = allocate() -- access by fulltag -local labels = allocate() -local stack = { } -local chain = { } -local ids = { } -local enabled = false -local tagcontext = { } -local tagpatterns = { } -local lasttags = { } -local stacksize = 0 -local metadata = nil -- applied to the next element -local documentdata = { } - -local tags = structures.tags -tags.taglist = taglist -- can best be hidden -tags.labels = labels -tags.patterns = tagpatterns -tags.specifications = specifications +local attributes = attributes +local structures = structures +local implement = interfaces.implement + +local a_tagged = attributes.private('tagged') + +local unsetvalue = attributes.unsetvalue +local codeinjections = backends.codeinjections + +local texgetattribute = tex.getattribute +local texsetattribute = tex.setattribute + +local taglist = allocate() -- access by attribute +local specifications = allocate() -- access by fulltag +local labels = allocate() +local stack = { } +local chain = { } +local ids = { } +local enabled = false +local tagcontext = { } +local tagpatterns = { } +local lasttags = { } +local stacksize = 0 +local metadata = nil -- applied to the next element +local documentdata = { } +local extradata = false + +local tags = structures.tags +tags.taglist = taglist -- can best be hidden +tags.labels = labels +tags.patterns = tagpatterns +tags.specifications = specifications + +function tags.current() + if stacksize > 0 then + return stack[stacksize] -- maybe copy or proxy + end +end -- Tags are internally stored as: -- @@ -126,6 +135,7 @@ local properties = allocate { -- todo: more "record = true" to improve forma listcontent = { pdf = "P", nature = "mixed" }, listdata = { pdf = "P", nature = "mixed" }, listpage = { pdf = "Reference", nature = "mixed" }, + listtext = { pdf = "Span", nature = "inline" }, delimitedblock = { pdf = "BlockQuote", nature = "display" }, delimited = { pdf = "Quote", nature = "inline" }, @@ -157,9 +167,11 @@ local properties = allocate { -- todo: more "record = true" to improve forma subformula = { pdf = "Div", nature = "display" }, link = { pdf = "Link", nature = "inline" }, + reference = { pdf = "Span", nature = "inline" }, margintextblock = { pdf = "Span", nature = "inline" }, margintext = { pdf = "Span", nature = "inline" }, + marginanchor = { pdf = "Span", nature = "inline" }, math = { pdf = "Div", nature = "inline" }, -- no display mn = { pdf = "Span", nature = "mixed" }, @@ -204,6 +216,14 @@ local properties = allocate { -- todo: more "record = true" to improve forma combinationpair = { pdf = "Span", nature = "display" }, combinationcontent = { pdf = "Span", nature = "mixed" }, combinationcaption = { pdf = "Span", nature = "mixed" }, + + publications = { pdf = "Div", nature = "display" }, + publication = { pdf = "Div", nature = "mixed" }, + pubfld = { pdf = "Span", nature = "inline" }, + + block = { pdf = "Div", nature = "display" }, + userdata = { pdf = "Div", nature = "display" }, + } tags.properties = properties @@ -215,7 +235,7 @@ local patterns = setmetatableindex(function(t,tag) end) function tags.locatedtag(tag) - local attribute = texattribute[a_tagged] + local attribute = texgetattribute(a_tagged) if attribute >= 0 then local specification = taglist[attribute] if specification then @@ -235,7 +255,7 @@ function tags.locatedtag(tag) end function structures.atlocation(str) - local specification = taglist[texattribute[a_tagged]] + local specification = taglist[texgetattribute(a_tagged)] if specification then if list then local taglist = specification.taglist @@ -287,6 +307,20 @@ function tags.getmetadata() return documentdata or { } end +function tags.registerextradata(name,serializer) + if type(serializer) == "function" then + if extradata then + extradata[name] = serializer + else + extradata = { [name] = serializer } + end + end +end + +function tags.getextradata() + return extradata +end + function tags.start(tag,specification) if not enabled then codeinjections.enabletags() @@ -349,7 +383,7 @@ function tags.start(tag,specification) specification.metadata = documentdata end -- - texattribute[a_tagged] = attribute + texsetattribute(a_tagged,attribute) return attribute end @@ -364,7 +398,7 @@ function tags.restart(attribute) taglist[attribute] = { taglist = { unpack(chain,1,stacksize) } } end stack[stacksize] = attribute - texattribute[a_tagged] = attribute + texsetattribute(a_tagged,attribute) return attribute end @@ -374,12 +408,12 @@ function tags.stop() end local t = stack[stacksize] if not t then - -- if trace_tags then + if trace_tags then report_tags("ignoring end tag, previous chain: %s",stacksize > 0 and concat(chain," ",1,stacksize) or "none") - -- end + end t = unsetvalue end - texattribute[a_tagged] = t + texsetattribute(a_tagged,t) return t end diff --git a/tex/context/base/mkiv/strc-tag.mkiv b/tex/context/base/mkiv/strc-tag.mkiv index 2ee71d67c..84e11a632 100644 --- a/tex/context/base/mkiv/strc-tag.mkiv +++ b/tex/context/base/mkiv/strc-tag.mkiv @@ -107,6 +107,7 @@ \def\t!listcontent {listcontent} % P \def\t!listdata {listdata} % P \def\t!listpage {listpage} % Reference +\def\t!listtext {listtext} % Span \def\t!delimitedblock {delimited} % BlockQuote \def\t!delimited {delimited} % Quote @@ -136,9 +137,11 @@ \def\t!subformula {subformula} % Div \def\t!link {link} % Link +\def\t!reference {reference} % Span \def\t!margintext {margintext} % Span \def\t!margintextblock {margintextblock} % Div +\def\t!marginanchor {marginanchor} % Span % we might opt for verbose variants so this is experimental: @@ -162,6 +165,13 @@ \def\t!combinationcontent {combinationcontent} % Span \def\t!combinationcaption {combinationcaption} % Span +\def\t!publications {publications} % Span +\def\t!publication {publication} % Span +\def\t!pubfld {pubfld} % Span + +\def\t!block {block} % Div +\def\t!userdata {userdata} % Div + % \setuptaglabeltext % [en] % [\t!document=document] @@ -180,42 +190,51 @@ \unexpanded\def\strc_tags_set_aspect_nop#1#2{} \unexpanded\def\strc_tags_set_aspect_yes#1#2{\clf_settagaspect{#1}{#2}} % todo: ignore when no export / also \let +\unexpanded\def\ignoretagsinexport[#1]% + {\clf_ignoretagsinexport{#1}} + \installcorenamespace{tagging} \installsetuponlycommandhandler \??tagging {tagging} +% it makes no sense to have labels ... maybe some day as a last 'replace' in the export +% which might be more efficient then ... okay, we now cannot overload but who cares + \unexpanded\def\strc_tags_element_start_yes{\dodoubleempty\strc_tags_element_start_yes_indeed} \unexpanded\def\strc_tags_element_start_nop{\dodoubleempty\strc_tags_element_start_nop_indeed} \unexpanded\def\strc_tags_element_start_yes_indeed {\iftrialtypesetting - \expandafter\strc_tags_element_start_nop_indeed + \expandafter\strc_tags_element_start_yes_indeed_nop \else \expandafter\strc_tags_element_start_yes_indeed_yes \fi} -\unexpanded\def\strc_tags_element_stop - {\iftrialtypesetting - \expandafter\strc_tags_element_stop_nop - \else - \expandafter\strc_tags_element_stop_yes - \fi} - -% it makes no sense to have labels ... maybe some day as a last 'replace' in the export -% which might be more efficient then ... okay, we now cannot overload but who cares +\unexpanded\def\strc_tags_element_start_yes_indeed_nop[#1][#2]% + {} \unexpanded\def\strc_tags_element_start_yes_indeed_yes[#1][#2]% {\clf_starttag_u{#1}{#2}} \unexpanded\def\strc_tags_element_stop_yes - {\clf_stoptag} + {\iftrialtypesetting + \expandafter\strc_tags_element_stop_yes_indeed_nop + \else + \expandafter\strc_tags_element_stop_yes_indeed_yes + \fi} -\unexpanded\def\strc_tags_element_start_nop_indeed[#1][#2]% +\unexpanded\def\strc_tags_element_stop_nop {} -\unexpanded\def\strc_tags_element_stop_nop +\unexpanded\def\strc_tags_element_stop_yes_indeed_nop {} +\unexpanded\def\strc_tags_element_stop_yes_indeed_yes + {\clf_stoptag} + +\let\strc_tags_element_start_nop_indeed\strc_tags_element_start_yes_indeed_nop +\let\strc_tags_element_stop_nop_indeed \strc_tags_element_stop_yes_indeed_nop + \def\strc_tags_report_hyphen#1% {\writestatus\m!languages{setting #1 to U+00AD}} @@ -293,12 +312,18 @@ % \dostarttaggedchained % {tag} {detail} \??hash % \dostarttaggednodetail % {tag} -% \unexpanded\def\strc_tags_enable -% {\let\dostarttagged\strc_tags_start_yes -% \let\dostoptagged \strc_tags_stop_yes} +\newconditional\c_strc_tags_enabled + +\let\dotaggedplaceholder\empty + +\chardef\strc_tags_placeholder_char\zerocount % "FFFC \unexpanded\def\strc_tags_enable - {\let\dostarttagged \strc_tags_enabled_start_detail + {% once enable one is toast + \global\settrue\c_strc_tags_enabled + % and gets: + \let\dotaggedplaceholder \strc_tags_placeholder_char + \let\dostarttagged \strc_tags_enabled_start_detail \let\dostarttaggednodetail\strc_tags_enabled_start_no_detail \let\dostarttaggedchained \strc_tags_enabled_start_chained \let\dostoptagged \strc_tags_enabled_stop @@ -306,12 +331,23 @@ \let\dostopignoretagging \strc_tags_stop_yes_ignore} \unexpanded\def\strc_tags_disable - {\let\dostarttagged \strc_tags_start_nop_detail - \let\dostarttaggednodetail\strc_tags_start_nop_no_detail - \let\dostarttaggedchained \strc_tags_start_nop_chained - \let\dostoptagged \strc_tags_stop_nop - \let\dostartignoretagging \strc_tags_start_nop_ignore - \let\dostopignoretagging \strc_tags_stop_nop_ignore} + {\ifconditional\c_strc_tags_enabled + % so now all are artifacts + \let\dotaggedplaceholder \strc_tags_placeholder_char + \let\dostarttagged \strc_tags_start_nop_detail + \let\dostarttaggednodetail\strc_tags_start_nop_no_detail + \let\dostarttaggedchained \strc_tags_start_nop_chained + \let\dostoptagged \strc_tags_stop_nop_ignore + \else + % initial + \let\dotaggedplaceholder \empty + \let\dostarttagged \strc_tags_start_nop_detail + \let\dostarttaggednodetail\strc_tags_start_nop_no_detail + \let\dostarttaggedchained \strc_tags_start_nop_chained + \let\dostoptagged \strc_tags_stop_nop_ignore + \let\dostartignoretagging \strc_tags_start_nop_ignore + \let\dostopignoretagging \strc_tags_stop_nop_ignore + \fi} % for luigi (beware: fully expandable): @@ -468,13 +504,27 @@ %D This will only work well with sane use. -\appendtoks - \dostartignoretagging -\to \everybeforepagebody +% \appendtoks +% {% +% \doglobal\appendtoks +% \strc_tags_start_yes_ignore +% \to \everybeforepagebody +% \doglobal\appendtoks +% \strc_tags_stop_yes_ignore +% \to \everyafterpagebody +% }% +% \to \everyenableelements + +% This doesn't work well either, so instead we handle the ornaments in the +% tagging in a different way (see attr -> false code). -\appendtoks - \dostopignoretagging -\to \everyafterpagebody +% \appendtoks +% \dostartignoretagging +% \to \everybeforepagebody +% +% \appendtoks +% \dostopignoretagging +% \to \everyafterpagebody % \doifelseinelement{structure:section} {yes} {no} % \doifelseinelement{structure:chapter} {yes} {no} diff --git a/tex/context/base/mkiv/strc-usr.lua b/tex/context/base/mkiv/strc-usr.lua new file mode 100644 index 000000000..f121fe296 --- /dev/null +++ b/tex/context/base/mkiv/strc-usr.lua @@ -0,0 +1,29 @@ +if not modules then modules = { } end modules ['strc-usr'] = { + version = 1.000, + comment = "companion to strc-usr.mkiv", + author = "Wolfgang Schuster", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- The following is copied from \type {tabl-xtb.lua} to make the userdata environment +-- work with \LUA\ documents. + +local context = context +local ctxcore = context.core + +local startuserdata = ctxcore.startuserdata +local stopuserdata = ctxcore.stopuserdata + +local startcollecting = context.startcollecting +local stopcollecting = context.stopcollecting + +function ctxcore.startuserdata(...) + startcollecting() + startuserdata(...) +end + +function ctxcore.stopuserdata() + stopuserdata() + stopcollecting() +end diff --git a/tex/context/base/mkiv/strc-usr.mkiv b/tex/context/base/mkiv/strc-usr.mkiv new file mode 100644 index 000000000..97b656fa0 --- /dev/null +++ b/tex/context/base/mkiv/strc-usr.mkiv @@ -0,0 +1,180 @@ +%D \module +%D [ file=strc-bkm, +%D version=2009.04.01, +%D title=\CONTEXT\ Structure Macros, +%D subtitle=Bookmarks, +%D author=Wolfgang Schuster, +%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 Structure Macros / Userdata} + +\registerctxluafile{strc-usr}{} + +%D It's a bit like blocks that also use buffers but more lightweight and with +%D inplace settings. +%D +%D \starttyping +%D \defineuserdata [test] [style=italic] +%D +%D \samplefile{klein} +%D +%D \startuserdata [before=\blank,after=\blank,color=red] +%D \samplefile{greenfield} +%D \stopuserdata +%D +%D \samplefile{sapolsky} +%D +%D \startuserdata [test] +%D \samplefile{bryson} +%D \stopuserdata +%D +%D \samplefile{jojomayer} +%D +%D \startuserdata [test] [before=\blank,after=\blank,color=red] +%D \samplefile{linden} +%D \stopuserdata +%D +%D \samplefile{montgomery} +%D \stoptyping +%D +%D Or from \LUA: +%D +%D \starttyping +%D \startluacode +%D context.startuserdata({color="blue"}) +%D context.samplefile("klein") +%D context.stopuserdata() +%D \stopluacode +%D \stoptyping +%D +%D An example of an alternative: +%D +%D \starttyping +%D \defineuserdataalternative [epigraph] [renderingsetup=userdata:epigraph] +%D +%D \startsetups [userdata:epigraph] +%D \startframedtext [location=right,frame=off,align={flushleft,broad},style=\tfx,offset=.25ex,width=.5\textwidth] +%D \begstrut\inlinebuffer[userdata]\endstrut +%D \hairline +%D \wordright{\userdataparameter{author}} +%D \stopframedtext +%D \stopsetups +%D +%D \defineuserdata +%D [epigraph] +%D [alternative=epigraph] +%D +%D \startuserdata [epigraph] [author={Sean B. Carrol}] +%D The fraction of fossil olfactory receptor genes is significantly higher in +%D all species with full color vision. This suggests that the evolution of +%D trichromatic vision --- which allows these primates to detect food, mates, +%D and danger with visual cues --- has reduced their reliance on the sense of +%D smell. +%D \stopuserdata +%D +%D \startuserdata [epigraph] [author={Sean B. Carrol}] +%D \samplefile{carrol} +%D \stopuserdata +%D \stoptyping + +\unprotect + +\installnamespace {userdata} +\installnamespace {userdataalternative} +\installnamespace {userdatarenderings} + +\installcommandhandler \????userdata {userdata} \????userdata +\installcommandhandler \????userdataalternative {userdataalternative} \????userdataalternative + +\unexpanded\def\startuserdata + {\begingroup + \let\currentuserdata\empty + \doifelsenextoptionalcs\userdata_start_delayed\userdata_start_indeed} + +% This variant works only when the userdata instance exists while the assignment check +% can also be used with undefined instances which falls back to the global settings. +% +% \def\userdata_start_delayed[#1]% +% {\ifcsname\nameduserdatahash{\detokenize\expandafter{\normalexpanded{#1}}}\s!parent\endcsname +% \expandafter\userdata_start_delayed_name +% \else +% \expandafter\userdata_start_delayed_parameters +% \fi[#1]} + +\def\userdata_start_delayed[#1]% + {\doifelseassignmentcs{#1}% + \userdata_start_delayed_parameters + \userdata_start_delayed_name + [#1]} + +\def\userdata_start_delayed_parameters[#1]% + {\setupcurrentuserdata[#1]% + \userdata_start_indeed} + +\def\userdata_start_delayed_name[#1]% + {\edef\currentuserdata{#1}% + \checkuserdataparent + \doifelsenextoptionalcs\userdata_start_delayed_parameters\userdata_start_indeed} + +\def\userdata_start_indeed + {\grabbufferdatadirect\s!userdata{\csstring\startuserdata}{\csstring\stopuserdata}} + +% \unexpanded\def\stopuserdata +% {\useuserdatastyleandcolor\c!style\c!color +% \usealignparameter\userdataparameter +% \edef\currentuserdataalternative{\userdataparameter\c!alternative}% +% \ifcsname\currentuserdataalternativehash\s!parent\endcsname \else +% \let\currentuserdataalternative\s!default +% \fi +% \edef\p_renderingsetup{\userdataalternativeparameter\c!renderingsetup}% +% \directsetup\p_renderingsetup +% \endgroup} + +\unexpanded\def\stopuserdata + {\userdataparameter\c!before % HH: moved, so we obey the outer spacing + \dostarttagged\t!userdata\currentuserdata % HH: added, maybe move up ? + \begingroup + \useuserdatastyleandcolor\c!style\c!color + \usealignparameter\userdataparameter % HH: added + \edef\currentuserdataalternative{\userdataparameter\c!alternative}% + \ifcsname\currentuserdataalternativehash\s!parent\endcsname \else + \let\currentuserdataalternative\s!default + \fi + \usesetupsparameter\userdataparameter + \edef\p_renderingsetup{\userdataalternativeparameter\c!renderingsetup}% + \directsetup\p_renderingsetup + \endgroup + \dostoptagged + \userdataparameter\c!after % HH: moved + \endgroup} + +\unexpanded\def\getuserdata + {\getbufferdata[\s!userdata]} + +\unexpanded\def\getinlineuserdata + {\inlinebuffer[\s!userdata]} + +\defineuserdataalternative + [\s!default] + [\c!renderingsetup=\????userdatarenderings:\s!default] + +% \startsetups[\????userdatarenderings:\s!default] +% \userdataparameter\c!before +% \usesetupsparameter\userdataparameter +% \getbufferdata[\s!userdata] +% \userdataparameter\c!after +% \stopsetups + +\startsetups[\????userdatarenderings:\s!default] + \getuserdata +\stopsetups + +\setupuserdata + [\c!alternative=\s!default] + +\protect diff --git a/tex/context/base/mkiv/supp-box.lua b/tex/context/base/mkiv/supp-box.lua index 40047167c..1f31f7681 100644 --- a/tex/context/base/mkiv/supp-box.lua +++ b/tex/context/base/mkiv/supp-box.lua @@ -20,63 +20,67 @@ local nodes = nodes local implement = interfaces.implement -local nodecodes = nodes.nodecodes - -local disc_code = nodecodes.disc -local hlist_code = nodecodes.hlist -local vlist_code = nodecodes.vlist -local glue_code = nodecodes.glue -local glyph_code = nodecodes.glyph - -local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode - ------ getfield = nuts.getfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getboth = nuts.getboth -local getdisc = nuts.getdisc -local getid = nuts.getid -local getlist = nuts.getlist -local getattribute = nuts.getattribute -local getbox = nuts.getbox -local getdir = nuts.getdir -local getwidth = nuts.getwidth -local takebox = nuts.takebox - ------ setfield = nuts.setfield -local setlink = nuts.setlink -local setboth = nuts.setboth -local setnext = nuts.setnext -local setbox = nuts.setbox -local setlist = nuts.setlist -local setdisc = nuts.setdisc -local setwidth = nuts.setwidth -local setheight = nuts.setheight -local setdepth = nuts.setdepth - -local flush_node = nuts.flush_node -local flush_list = nuts.flush_list -local copy_node = nuts.copy -local copy_list = nuts.copy_list -local find_tail = nuts.tail -local traverse_id = nuts.traverse_id -local list_dimensions = nuts.dimensions -local hpack = nuts.hpack - -local listtoutf = nodes.listtoutf - -local nodepool = nuts.pool -local new_penalty = nodepool.penalty -local new_hlist = nodepool.hlist -local new_glue = nodepool.glue - -local setlistcolor = nodes.tracers.colors.setlist - -local texget = tex.get -local texgetbox = tex.getbox -local texsetdimen = tex.setdimen +local nodecodes = nodes.nodecodes + +local disc_code = nodecodes.disc +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local glue_code = nodecodes.glue +local glyph_code = nodecodes.glyph + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode + +----- getfield = nuts.getfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getboth = nuts.getboth +local getdisc = nuts.getdisc +local getid = nuts.getid +local getlist = nuts.getlist +local getattribute = nuts.getattribute +local getbox = nuts.getbox +local getdirection = nuts.getdirection +local getwidth = nuts.getwidth +local takebox = nuts.takebox + +----- setfield = nuts.setfield +local setlink = nuts.setlink +local setboth = nuts.setboth +local setnext = nuts.setnext +local setbox = nuts.setbox +local setlist = nuts.setlist +local setdisc = nuts.setdisc +local setwidth = nuts.setwidth +local setheight = nuts.setheight +local setdepth = nuts.setdepth +local setshift = nuts.setshift + +local flush_node = nuts.flush_node +local flush_list = nuts.flush_list +local copy_node = nuts.copy +local copy_list = nuts.copy_list +local find_tail = nuts.tail +local getdimensions = nuts.dimensions +local hpack = nuts.hpack + +local nextdisc = nuts.traversers.disc +local nextdir = nuts.traversers.dir +local nexthlist = nuts.traversers.hlist + +local listtoutf = nodes.listtoutf + +local nodepool = nuts.pool +local new_penalty = nodepool.penalty +local new_hlist = nodepool.hlist +local new_glue = nodepool.glue + +local setlistcolor = nodes.tracers.colors.setlist + +local texget = tex.get +local texgetbox = tex.getbox +local texsetdimen = tex.setdimen local function hyphenatedlist(head,usecolor) local current = head and tonut(head) @@ -127,7 +131,7 @@ implement { -- local function hyphenatedhack(head,pre) -- pre = tonut(pre) --- for n in traverse_id(disc_code,tonut(head)) do +-- for n in nextdisc, tonut(head) do -- local hyphen = getfield(n,"pre") -- if hyphen then -- flush_list(hyphen) @@ -361,10 +365,12 @@ implement { } local function getnaturaldimensions(n) - local w, h, d = 0, 0, 0 + local w = 0 + local h = 0 + local d = 0 local l = getlist(getbox(n)) if l then - w, h, d = list_dimensions(l) + w, h, d = getdimensions(l) end texsetdimen("lastnaturalboxwd",w) texsetdimen("lastnaturalboxht",h) @@ -391,10 +397,12 @@ interfaces.implement { name = "getnaturalwd", arguments = "integer", actions = function(n) - local w, h, d = 0, 0, 0 + local w = 0 + local h = 0 + local d = 0 local l = getlist(getbox(n)) if l then - w, h, d = list_dimensions(l) + w, h, d = getdimensions(l) end context("\\dimexpr%i\\scaledpoint\\relax",w) end @@ -416,46 +424,60 @@ interfaces.implement { nodes.setboxtonaturalwd = setboxtonaturalwd -local function firstdirinbox(n) - local b = getbox(n) - if b then - local l = getlist(b) - if l then - for h in traverse_id(hlist_code,l) do - return getdir(h) +local doifelse = commands.doifelse + +do + + local dirvalues = nodes.dirvalues + local lefttoright_code = dirvalues.lefttoright + local righttoleft_code = dirvalues.righttoleft + + local function firstdirinbox(n) + local b = getbox(n) + if b then + local l = getlist(b) + if l then + for d in nextdir, l do + return getdirection(d) + end + for h in nexthlist, l do + return getdirection(h) + end end end + return lefttoright_code end -end -nodes.firstdirinbox = firstdirinbox + nodes.firstdirinbox = firstdirinbox -local doifelse = commands.doifelse + interfaces.implement { + name = "doifelserighttoleftinbox", + arguments = "integer", + actions = function(n) + doifelse(firstdirinbox(n) == righttoleft_code) + end + } -interfaces.implement { - name = "doifelserighttoleftinbox", - arguments = "integer", - actions = function(n) - doifelse(firstdirinbox(n) == "TRT") - end -} +end -- new (handy for mp) .. might move to its own module do - local flush_list = nodes.flush_list - local copy_list = nodes.copy_list - local takebox = nodes.takebox - local texsetbox = tex.setbox - - local new_hlist = nodes.pool.hlist - - local boxes = { } - nodes.boxes = boxes - local cache = table.setmetatableindex("table") - local report = logs.reporter("boxes","cache") - local trace = false + local nuts = nodes.nuts + local tonode = nuts.tonode + local takebox = nuts.takebox + local flush_list = nuts.flush_list + local copy_list = nuts.copy_list + local getwhd = nuts.getwhd + local setbox = nuts.setbox + local new_hlist = nuts.pool.hlist + + local boxes = { } + nodes.boxes = boxes + local cache = table.setmetatableindex("table") + local report = logs.reporter("boxes","cache") + local trace = false trackers.register("nodes.boxes",function(v) trace = v end) @@ -487,7 +509,9 @@ do if trace then report("category %a, name %a, %s (%s)",category,name,"direct",b and "content" or "empty") end - return b or nil + if b then + return tonode(b) + end end function boxes.restore(category,name,box,copy) @@ -508,11 +532,9 @@ do if trace then report("category %a, name %a, %s (%s)",category,name,"restore",b and "content" or "empty") end - texsetbox(box,b or nil) + setbox(box,b or nil) end - local getwhd = nodes.getwhd - function boxes.dimensions(category,name) name = tonumber(name) or name local b = cache[category][name] @@ -592,13 +614,19 @@ do actions = boxes.reset, } - implement { - name = "lastlinewidth", - actions = function() - local head = tex.lists.page_head - -- list dimensions returns 3 value but we take the first - context(head and list_dimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0) - end - } - end + +implement { + name = "lastlinewidth", + actions = function() + local head = tex.lists.page_head + -- list dimensions returns 3 value but we take the first + context(head and getdimensions(getlist(find_tail(tonut(tex.lists.page_head)))) or 0) + end +} + +interfaces.implement { + name = "shiftbox", + arguments = { "integer", "dimension" }, + actions = function(n,d) setshift(getbox(n),d) end, +} diff --git a/tex/context/base/mkiv/supp-box.mkiv b/tex/context/base/mkiv/supp-box.mkiv index fb9cbdf5d..59e710520 100644 --- a/tex/context/base/mkiv/supp-box.mkiv +++ b/tex/context/base/mkiv/supp-box.mkiv @@ -15,10 +15,14 @@ \unprotect -\registerctxluafile{supp-box}{} +\registerctxluafile{supp-box}{optimize} % This file is partially cleaned up. +%D First some defaults: + +\fixupboxesmode\plusone + % handy to have % % \hbox to \hsize @@ -208,8 +212,8 @@ %D \smashedvbox to ... {...} %D \stoptyping -\unexpanded\def\smashedhbox{\hbox\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\hbox} -\unexpanded\def\smashedvbox{\vbox\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\vbox} +\unexpanded\def\smashedhbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\hbox} +\unexpanded\def\smashedvbox{\vpack\bgroup\dowithnextboxcs\syst_boxes_smashed_nextbox\vbox} %D First we define a helper. We use a \LUATEX\ feature in order to avoid %D mathpalettes. @@ -576,7 +580,7 @@ \unexpanded\def\doifelsetext#1% {\begingroup - \setbox\scratchbox\hbox + \setbox\scratchbox\hpack {\settrialtypesetting \ignorespaces#1\removeunwantedspaces}% \ifzeropt\wd\scratchbox @@ -589,7 +593,7 @@ \unexpanded\def\doiftext#1% {\begingroup - \setbox\scratchbox\hbox + \setbox\scratchbox\hpack {\settrialtypesetting \ignorespaces#1\removeunwantedspaces}% \ifzeropt\wd\scratchbox @@ -670,7 +674,7 @@ %D \afterassignment\syst_boxes_with_next_box_indeed %D \else\ifx#2\vbox %D \afterassignment\syst_boxes_with_next_box_indeed -%D \else\ifx#2\normalvtop +%D \else\ifx#2\vtop %D \afterassignment\syst_boxes_with_next_box_indeed %D \else\ifx#2\normalvcenter %D \afterassignment\syst_boxes_with_next_box_indeed @@ -730,9 +734,9 @@ %D Some well known friends, but we implement them our own %D way. We want the macros to work in both math and text mode. -\def\dodorlap{\hpack to \zeropoint{\box\nextbox\normalhss}\endgroup} -\def\dodollap{\hpack to \zeropoint{\normalhss\box\nextbox}\endgroup} -\def\dodoclap{\hpack to \zeropoint{\normalhss\box\nextbox\normalhss}\endgroup} +\def\dodorlap{\hpack to \zeropoint{\box\nextbox\hss}\endgroup} +\def\dodollap{\hpack to \zeropoint{\hss\box\nextbox}\endgroup} +\def\dodoclap{\hpack to \zeropoint{\hss\box\nextbox\hss}\endgroup} \def\dorlap{\begingroup\dowithnextboxcs\dodorlap\hbox} \def\dollap{\begingroup\dowithnextboxcs\dodollap\hbox} @@ -746,8 +750,8 @@ \unexpanded\def\llap{\mathortext\domathllap\dollap} \unexpanded\def\clap{\mathortext\domathclap\doclap} -\def\dodotlap{\vpack to \zeropoint{\normalvss\box\nextbox}\endgroup} -\def\dodoblap{\vpack to \zeropoint{\box\nextbox\normalvss}\endgroup} +\def\dodotlap{\vpack to \zeropoint{\vss\box\nextbox}\endgroup} +\def\dodoblap{\vpack to \zeropoint{\box\nextbox\vss}\endgroup} \unexpanded\def\tlap{\begingroup\dowithnextboxcs\dodotlap\vbox} \unexpanded\def\blap{\begingroup\dowithnextboxcs\dodoblap\vbox} @@ -1183,8 +1187,8 @@ %D complex macro than needed at first sight. \def\dodoboundtext#1% - {\setbox0\hbox{#1}% - \advance\scratchdimen -\wd0 + {\setbox\scratchboxone\hbox{#1}% + \advance\scratchdimen -\wd\scratchboxone \ifdim\scratchdimen>\zeropoint\relax#1\fi}% \def\doboundtext#1#2#3% still used? @@ -1243,7 +1247,7 @@ \ifdim\wd\nextbox>\scratchdimen \setbox\scratchbox\hbox{\ifdone\space#2\else#2\space\fi}% \advance\scratchdimen -\wd\scratchbox - \setbox0\box\nextbox + \setbox\scratchboxone\box\nextbox \setbox\nextbox\vbox {\hsize\scratchdimen \hfuzz\maxdimen @@ -1254,7 +1258,7 @@ \rightskip\zeropoint \hskip\zeropoint \s!plus 1\s!fill % \hsize \fi - \unhcopy0}% + \unhcopy\scratchboxone}% \ifdim\ht\nextbox>\strutht \setbox\nextbox\vbox % if omitted: missing brace reported {\splittopskip\openstrutheight @@ -1262,7 +1266,7 @@ \setbox\nextbox\vsplit\nextbox to \strutht \else \doloop - {\setbox0\vsplit\nextbox to \strutht + {\setbox\scratchboxone\vsplit\nextbox to \strutht \ifdim\ht\nextbox>\strutht \else \exitloop \fi}% \fi \unvbox\nextbox @@ -1304,13 +1308,13 @@ {%\dontleavehmode \bgroup \let\speciallimitatetext\firstoffourarguments - \setbox0\hbox + \setbox\scratchboxone\hbox {\nohyphens \normallimitatetext{#1}{+#2}{}#4% \normallimitatetext{#1}{-#3}{}}% - \setbox2\hbox + \setbox\scratchboxtwo\hbox {#1}% - \ifdim\wd2<\wd0 #1\else\unhbox0\fi + \ifdim\wd\scratchboxtwo<\wd\scratchboxone #1\else\unhbox\scratchboxone\fi \egroup} \unexpanded\def\limitatetext#1#2#3% \expanded added 2003/01/16 @@ -1328,7 +1332,7 @@ %D \stoptyping \unexpanded\def\limitatefirstline#1#2#3% - {\hbox\bgroup\strut + {\hbox\bgroup\strut % \hpack \setbox\scratchbox\hbox{\begstrut#1\endstrut}% \ifdim\wd\scratchbox>#2\relax \setbox\scratchbox\hbox{#3}% @@ -1340,7 +1344,7 @@ {\unvbox\scratchbox \global\setbox\plusone\lastbox \global\setbox\plusone\hbox{\strut\unhbox\plusone}% - \hbox % to #2 + \hbox % to #2 % \hpack {\ifx\clip\undefined \box\plusone \else\ifdim\wd\plusone>\hsize @@ -1533,7 +1537,7 @@ %D a strut. \unexpanded\def\struttedbox - {\hbox\bgroup + {\hpack\bgroup \dowithnextboxcs\syst_boxes_struttedbox_finish\hbox} \def\syst_boxes_struttedbox_finish @@ -1550,7 +1554,7 @@ %D equals strutdepth. \unexpanded\def\topskippedbox - {\hbox\bgroup\dowithnextboxcs\syst_boxes_topskippedbox_finish\hbox} + {\hpack\bgroup\dowithnextboxcs\syst_boxes_topskippedbox_finish\hbox} \def\syst_boxes_topskippedbox_finish {\edef\m_boxes_tmp{\ifdim\strutdepth=\dp\nextbox\dp\nextbox\the\dp\nextbox\fi}% @@ -1606,22 +1610,22 @@ \unexpanded\def\centeredbox#1#% height +/-dimen width +/-dimen {\bgroup - \setbox0\vpack to \vsize + \setbox\scratchboxone\vpack to \vsize \bgroup \dontcomplain \forgetall - \setbox0\hbox{\vrule\s!width \zeropoint#1}% - \setbox2\vbox{\hrule\s!height\zeropoint#1}% - \advance\vsize \ht2 - \advance\hsize \wd0 + \setbox\scratchboxone\hpack{\vrule\s!width \zeropoint#1}% + \setbox\scratchboxtwo\vpack{\hrule\s!height\zeropoint#1}% + \advance\vsize \ht\scratchboxtwo + \advance\hsize \wd\scratchboxone \vpack to \vsize \bgroup - \vskip-\ht2 + \vskip-\ht\scratchboxtwo \vss \hpack to \hsize \bgroup \dowithnextbox - {\hskip-\wd0 + {\hskip-\wd\scratchboxone \hss \box\nextbox \hss @@ -1629,14 +1633,13 @@ \vss \egroup \egroup - \wd0\hsize - \ht0\vsize - \box0 + \wd\scratchboxone\hsize + \ht\scratchboxone\vsize + \box\scratchboxone \egroup} \hbox} -%D For those who don't want to deal with \type {\hsize} -%D and \type {\vsize}, we have: +%D For those who don't want to deal with \type {\hsize} and \type {\vsize}, we have: %D %D \starttyping %D \centerednextbox width 2bp height 2bp @@ -1670,9 +1673,9 @@ {\bgroup \dowithnextbox {\setlocalhsize - \setbox\scratchbox\hbox{\vrule\s!width \zeropoint#1}% + \setbox\scratchbox\hpack{\vrule\s!width \zeropoint#1}% \ifzeropt\wd\scratchbox\else\hsize\wd\scratchbox\fi - \setbox\scratchbox\vbox{\hrule\s!height\zeropoint#1}% + \setbox\scratchbox\vpack{\hrule\s!height\zeropoint#1}% \ifzeropt\ht\scratchbox\else\vsize\ht\scratchbox\fi \vpack to \vsize{\vss\hpack to \hsize{\hss\box\nextbox\hss}\vss}% \egroup}% @@ -1764,7 +1767,7 @@ {\dorecurse\rigidcolumns {\setbox\scratchbox\vsplit\rigidcolumnbox to \scratchdimen \dp\scratchbox\openstrutdepth - \setbox\scratchbox\normalvtop + \setbox\scratchbox\vtop \ifalignrigidcolumns to \ifstretchrigidcolumns\vsize\else\scratchdimen\fi \fi @@ -1874,21 +1877,21 @@ \unexpanded\def\convertvboxtohbox {\makehboxofhboxes - \setbox0\hbox{\unhbox0 \removehboxes}% - \noindent\unhbox0\par} + \setbox\scratchboxone\hpack{\unhbox\scratchboxone\removehboxes}% \hpack + \noindent\unhbox\scratchboxone\par} \unexpanded\def\makehboxofhboxes - {\setbox0\emptyhbox - \loop % \doloop { .. \exitloop .. } - \setbox2\lastbox - \ifhbox2 - \setbox0\hbox{\box2\unhbox0}% + {\setbox\scratchboxone\emptyhbox + \loop % \doloop { .. \exitloop .. } + \setbox\scratchboxtwo\lastbox + \ifhbox\scratchboxtwo + \setbox\scratchboxone\hpack{\box\scratchboxtwo\unhbox\scratchboxone}% \repeat} \unexpanded\def\removehboxes - {\setbox0\lastbox - \ifhbox0 - {\removehboxes}\unhbox0 + {\setbox\scratchboxone\lastbox + \ifhbox\scratchboxone + {\removehboxes}\unhbox\scratchboxone \fi} % And one special for notes: @@ -1947,7 +1950,7 @@ \doloop {\setbox\hhbox\vsplit\unhhedbox to \lineheight \ifvoid\unhhedbox - \setbox\hhbox\hbox{\strut\hboxofvbox\hhbox}% + \setbox\hhbox\hbox{\strut\hboxofvbox\hhbox}% \hpack \fi \ht\hhbox\strutht \dp\hhbox\strutdp @@ -2129,7 +2132,27 @@ %D %D \leavevmode\getbuffer +\def\boxisempty#1% + {\ifdim\wd#1=\zeropoint + \ifdim\ht#1=\zeropoint + \ifdim\dp#1=\zeropoint + \zerocount + \else + \plusone + \fi + \else + \plusone + \fi + \else + \plusone + \fi} + \def\syst_boxes_overlay_process + {\ifcase\boxisempty\nextbox\else + \syst_boxes_overlay_process_indeed + \fi} + +\def\syst_boxes_overlay_process_indeed {%\removeunwantedspaces % already done \scratchdepth\dp\ifdim\dp\nextbox>\dp\processbox\nextbox\else\processbox\fi \ifdim\ht\nextbox>\ht\processbox @@ -2198,9 +2221,9 @@ \unexpanded\def\cbox#1#{\vbox#1\syst_boxes_lrc_process\raggedcenter} \unexpanded\def\rbox#1#{\vbox#1\syst_boxes_lrc_process\raggedright } -\unexpanded\def\ltop#1#{\normalvtop#1\syst_boxes_lrc_process\raggedleft } -\unexpanded\def\ctop#1#{\normalvtop#1\syst_boxes_lrc_process\raggedcenter} -\unexpanded\def\rtop#1#{\normalvtop#1\syst_boxes_lrc_process\raggedright } +\unexpanded\def\ltop#1#{\vtop#1\syst_boxes_lrc_process\raggedleft } +\unexpanded\def\ctop#1#{\vtop#1\syst_boxes_lrc_process\raggedcenter} +\unexpanded\def\rtop#1#{\vtop#1\syst_boxes_lrc_process\raggedright } %D The alternatives \type {\tbox} and \type {\bbox} can be used %D to properly align boxes, like in: @@ -2222,8 +2245,8 @@ %D %D \getbuffer -\unexpanded\def\tbox{\hbox\bgroup\dowithnextboxcs\syst_boxes_tbox_finish\hbox} -\unexpanded\def\bbox{\hbox\bgroup\dowithnextboxcs\syst_boxes_bbox_finish\hbox} +\unexpanded\def\tbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_tbox_finish\hbox} +\unexpanded\def\bbox{\hpack\bgroup\dowithnextboxcs\syst_boxes_bbox_finish\hbox} \def\syst_boxes_tbox_finish {\scratchdepth\dimexpr\ht\nextbox+\dp\nextbox-\ht\strutbox\relax @@ -2289,7 +2312,7 @@ {\ifx\next\bgroup \expanded{\egroup#1 to \the\sizeofbox}% \else - \@EA\afterassignment\@EA\docommand\@EA\scratchdimen + \expandafter\afterassignment\expandafter\docommand\expandafter\scratchdimen \fi}% \docommand} @@ -2337,7 +2360,7 @@ \newbox\fakedboxcursor -\setbox\fakedboxcursor\hbox +\setbox\fakedboxcursor\hpack {\vrule\s!width\zeropoint\s!height\zeropoint\s!depth\zeropoint} \unexpanded\def\boxcursor % overloaded in core-vis @@ -2723,7 +2746,7 @@ % vcenter in text, we kunnen vcenter overloaden \unexpanded\def\halfwaybox - {\hbox\bgroup + {\hpack\bgroup \dowithnextboxcs\syst_boxes_halfwaybox_finish\hbox} \def\syst_boxes_halfwaybox_finish @@ -2732,7 +2755,7 @@ \egroup} \unexpanded\def\depthonlybox - {\vtop\bgroup + {\tpack\bgroup \dowithnextboxcs\syst_boxes_depthonlybox_finish\vbox} \def\syst_boxes_depthonlybox_finish @@ -2747,12 +2770,7 @@ %D And even rawer: - \let\naturalvtop \normalvtop - \let\naturalvcenter\normalvtop -\unexpanded\def\naturalhbox {\hbox dir TLT} -\unexpanded\def\naturalvbox {\vbox dir TLT} -\unexpanded\def\naturalhpack {\hpack dir TLT} -\unexpanded\def\naturalvpack {\vpack dir TLT} +\let\naturalvcenter\normalvtop % will go away %D \macros %D {vcenter} @@ -2764,7 +2782,7 @@ \dowithnextboxcs\syst_boxes_vcenter_finish\vbox} \def\syst_boxes_vcenter_finish - {\hpack{\normalstartimath\normalvcenter{\box\nextbox}\normalstopimath}% + {\hpack{\normalstartimath\vcenter{\box\nextbox}\normalstopimath}% \egroup} % could be \everymathematics @@ -2780,7 +2798,7 @@ %D A not so well unhboxable box can be made with: \unexpanded\def\frozenhbox - {\hbox\bgroup + {\hpack\bgroup \dowithnextboxcs\syst_boxes_frozenhbox_finish\hbox} \def\syst_boxes_frozenhbox_finish @@ -2837,19 +2855,19 @@ \unexpanded\def\spreadhbox#1% rebuilds \hbox{} {\bgroup \ifhbox#1\relax - \setbox2\emptybox + \setbox\scratchboxtwo\emptybox \unhbox#1% \doloop {\unpenalty\unskip\unpenalty\unskip\unpenalty\unskip - \setbox0\lastbox - \ifvoid0 + \setbox\scratchboxone\lastbox + \ifvoid\scratchboxone \exitloop \else - \setbox2\hbox - {\ifhbox0 \spreadhbox0\else\box0\fi - \ifvoid2 \else\hss\unhbox2\fi}% + \setbox\scratchboxtwo\hbox + {\ifhbox\scratchboxone \spreadhbox\scratchboxone\else\box\scratchboxone\fi + \ifvoid\scratchboxtwo \else\hss\unhbox\scratchboxtwo\fi}% \fi}% - \ifvoid2\else\unhbox2\fi + \ifvoid\scratchboxtwo\else\unhbox\scratchboxtwo\fi \else \box#1% \fi @@ -2974,6 +2992,24 @@ % \unexpanded\def\tightvbox{\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\vbox} % \unexpanded\def\tightvtop{\dowithnextbox{\ht\nextbox\zeropoint\box\nextbox}\vtop} +%D This one keeps dimensions and sets the shift field (and so it's more for testing +%D than for real usage): + +\unexpanded\def\shiftbox{\clf_shiftbox} + +%D This one has been moved from a 2 decade old file. It makes something boxed +%D sit on the baseline. + +\unexpanded\def\linebox + {\hpack\bgroup\dowithnextbox + {\scratchdimen\dimexpr\dimexpr\htdp\nextbox-\lineheight\relax/2+\dp\strutbox\relax + \setbox\nextbox\hpack{\lower\scratchdimen\box\nextbox}% + \ht\nextbox\ht\strutbox + \dp\nextbox\dp\strutbox + \box\nextbox + \egroup} + \hbox} + \protect \endinput % a bit of test code: diff --git a/tex/context/base/mkiv/supp-dir.mkiv b/tex/context/base/mkiv/supp-dir.mkiv index 42a0aa37c..277f2b7ca 100644 --- a/tex/context/base/mkiv/supp-dir.mkiv +++ b/tex/context/base/mkiv/supp-dir.mkiv @@ -11,40 +11,44 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -%D We no longer have the \ETEX\ direction primitives. - \unprotect -% \expanded{\defineactivecharacter \number"2000E} {\textdir TRT\relax} -% \expanded{\defineactivecharacter \number"2000F} {\textdir TLT\relax} +\chardef\directionlefttoright\zerocount +\chardef\directionrighttoleft\plusone -%D As we have less directions now we can use something +\edef\??bdir{\ifdefined\bodydir bdir\else direction\fi} -% \chardef\@@D@@TLT0 -% \chardef\@@D@@TRT1 -% \chardef\@@D@@RTT0 -% \chardef\@@D@@LRL1 -% -% \def\thetextdir{\csname @@D@@\the\textdir\endcsname} -% -% \ifnum\thetextdir=0 L\else R\fi \textdir TRT \ifnum\thetextdir=0 L\else R\fi +\unexpanded\edef\naturalhbox {\hbox \??bdir\directionlefttoright} +\unexpanded\edef\naturalvbox {\vbox \??bdir\directionlefttoright} +\unexpanded\edef\naturalvtop {\vtop \??bdir\directionlefttoright} +\unexpanded\edef\naturalhpack {\hpack \??bdir\directionlefttoright} +\unexpanded\edef\naturalvpack {\vpack \??bdir\directionlefttoright} +\unexpanded\edef\naturaltpack {\tpack \??bdir\directionlefttoright} -\unexpanded\def\showdirsinmargin - {\inleft{\normalexpanded{\noexpand\hbox dir TLT{\ttxx[\the\pardir,\the\textdir]}}}} +\unexpanded\edef\reversehbox {\hbox \??bdir\directionrighttoleft} +\unexpanded\edef\reversevbox {\vbox \??bdir\directionrighttoleft} +\unexpanded\edef\reversevtop {\vtop \??bdir\directionrighttoleft} +\unexpanded\edef\reversehpack {\hpack \??bdir\directionrighttoleft} +\unexpanded\edef\reversevpack {\vpack \??bdir\directionrighttoleft} +\unexpanded\edef\reversetpack {\tpack \??bdir\directionrighttoleft} -\bgroup - \catcode`L=\othercatcode \gdef\istltdir#1#2#3{\if#2L0\else1\fi} - \catcode`R=\othercatcode \gdef\istrtdir#1#2#3{\if#2R0\else1\fi} -\egroup +\ifdefined\bodydir + \let\bodydir \undefined \let\normalbodydir \undefined + \let\bodydirection\undefined \let\normalbodydirection\undefined +\fi -\def\istlttextdir{\expandafter\istltdir\the\textdir} -\def\istrttextdir{\expandafter\istrtdir\the\textdir} +\ifdefined\pagedir + \let\pagedir \undefined \let\normalpagedir \undefined + \let\pagedirection\undefined \let\normalpagedirection\undefined +\fi -\def\istltpardir {\expandafter\istltdir\the\pardir } -\def\istrtpardir {\expandafter\istrtdir\the\pardir } +% \expanded{\defineactivecharacter \number"2000E} {\textdirection\directionrighttoleft\relax} +% \expanded{\defineactivecharacter \number"2000F} {\textdirection\directionlefttoright\relax} -% \ifcase\istlttextdir Y\else N\fi -% \ifcase\istltpardir Y\else N\fi -% \ifcase\istltdir TRT\relax Y\else N\fi +\def\syst_direction_string#1{\ifcase#1=\plusone r2l\else l2r\fi} + +\unexpanded\def\showdirsinmargin + {\normalexpanded{\inleft{\naturalhbox + {\ttxx[\syst_direction_string\pardirection,\syst_direction_string\textdirection]}}}} \protect \endinput diff --git a/tex/context/base/mkiv/supp-mat.mkiv b/tex/context/base/mkiv/supp-mat.mkiv index 176233ae5..f72a0ff89 100644 --- a/tex/context/base/mkiv/supp-mat.mkiv +++ b/tex/context/base/mkiv/supp-mat.mkiv @@ -179,7 +179,7 @@ \popmacro\dodimensionsignal} \unexpanded\def\nodimension#1% - {\unskip#1\global\let\dodimensionsignal\relax} + {\unskip#1\glet\dodimensionsignal\relax} %D \macros %D {cramped} diff --git a/tex/context/base/mkiv/symb-emj.lua b/tex/context/base/mkiv/symb-emj.lua index 3075e0985..d6e2aebea 100644 --- a/tex/context/base/mkiv/symb-emj.lua +++ b/tex/context/base/mkiv/symb-emj.lua @@ -19,32 +19,27 @@ local protectglyphs = nodes.handlers.protectglyphs local tonodes = nodes.tonodes local currentfont = font.current --- fast enough, no need to memoize - -local glyph_code = nodes.nodecodes.glyph -local remove_node = nodes.remove -local getid = nodes.getid -local getnext = nodes.getnext -local getchar = nodes.getchar +local nuts = nodes.nuts +local tonode = nuts.tonode +local tonut = nuts.tonut +local remove_node = nuts.remove +local isglyph = nuts.isglyph local function removemodifiers(head) + local head = tonut(head) local current = head while current do - if getid(current) == glyph_code then - local char = getchar(current) -- using categories is too much - if char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then - head, current = remove_node(head,current,true) - else - current = getnext(current) - end + local char, id = isglyph(current) + if char and char == 0x200D or (char >= 0x1F3FB and char <= 0x1F3FF) then + head, current = remove_node(head,current,true) else current = getnext(current) end end - return head + return tonode(head) end --- attributes +-- fast enough, no need to memoize, maybe use attributes local function checkedemoji(name,id) local str = resolvedemoji(name) diff --git a/tex/context/base/mkiv/symb-imp-fontawesome.mkiv b/tex/context/base/mkiv/symb-imp-fontawesome.mkiv index 145adc46c..c638998ab 100644 --- a/tex/context/base/mkiv/symb-imp-fontawesome.mkiv +++ b/tex/context/base/mkiv/symb-imp-fontawesome.mkiv @@ -10,749 +10,786 @@ \definefontsynonym [FontAwesome] [file:FontAwesome.otf] %def\FontAwesomeSymbol#1{\getglyphstyled{FontAwesome}{\utfchar{0x#1}}} -\def\FontAwesomeSymbol#1{\getglyphstyled{FontAwesome}{\tochar{x:#1}}} +\def\FontAwesomeSymbol#1{\getglyphstyled{FontAwesome}{\tochar{n:#1}}} -\startsymbolset [fontawesome] +\startsymbolset [fontawesome] [font=fontawesome] - \definesymbol [500px] [\FontAwesomeSymbol{f26e}] - \definesymbol [adjust] [\FontAwesomeSymbol{f042}] - \definesymbol [adn] [\FontAwesomeSymbol{f170}] - \definesymbol [align-center] [\FontAwesomeSymbol{f037}] - \definesymbol [align-justify] [\FontAwesomeSymbol{f039}] - \definesymbol [align-left] [\FontAwesomeSymbol{f036}] - \definesymbol [align-right] [\FontAwesomeSymbol{f038}] - \definesymbol [amazon] [\FontAwesomeSymbol{f270}] - \definesymbol [ambulance] [\FontAwesomeSymbol{f0f9}] - \definesymbol [american-sign-language-interpreting] [\FontAwesomeSymbol{f2a3}] - \definesymbol [anchor] [\FontAwesomeSymbol{f13d}] - \definesymbol [android] [\FontAwesomeSymbol{f17b}] - \definesymbol [angellist] [\FontAwesomeSymbol{f209}] - \definesymbol [angle-double-down] [\FontAwesomeSymbol{f103}] - \definesymbol [angle-double-left] [\FontAwesomeSymbol{f100}] - \definesymbol [angle-double-right] [\FontAwesomeSymbol{f101}] - \definesymbol [angle-double-up] [\FontAwesomeSymbol{f102}] - \definesymbol [angle-down] [\FontAwesomeSymbol{f107}] - \definesymbol [angle-left] [\FontAwesomeSymbol{f104}] - \definesymbol [angle-right] [\FontAwesomeSymbol{f105}] - \definesymbol [angle-up] [\FontAwesomeSymbol{f106}] - \definesymbol [apple] [\FontAwesomeSymbol{f179}] - \definesymbol [archive] [\FontAwesomeSymbol{f187}] - \definesymbol [area-chart] [\FontAwesomeSymbol{f1fe}] - \definesymbol [arrow-circle-down] [\FontAwesomeSymbol{f0ab}] - \definesymbol [arrow-circle-left] [\FontAwesomeSymbol{f0a8}] - \definesymbol [arrow-circle-o-down] [\FontAwesomeSymbol{f01a}] - \definesymbol [arrow-circle-o-left] [\FontAwesomeSymbol{f190}] - \definesymbol [arrow-circle-o-right] [\FontAwesomeSymbol{f18e}] - \definesymbol [arrow-circle-o-up] [\FontAwesomeSymbol{f01b}] - \definesymbol [arrow-circle-right] [\FontAwesomeSymbol{f0a9}] - \definesymbol [arrow-circle-up] [\FontAwesomeSymbol{f0aa}] - \definesymbol [arrow-down] [\FontAwesomeSymbol{f063}] - \definesymbol [arrow-left] [\FontAwesomeSymbol{f060}] - \definesymbol [arrow-right] [\FontAwesomeSymbol{f061}] - \definesymbol [arrow-up] [\FontAwesomeSymbol{f062}] - \definesymbol [arrows] [\FontAwesomeSymbol{f047}] - \definesymbol [arrows-alt] [\FontAwesomeSymbol{f0b2}] - \definesymbol [arrows-h] [\FontAwesomeSymbol{f07e}] - \definesymbol [arrows-v] [\FontAwesomeSymbol{f07d}] - \definesymbol [asl-interpreting] [\FontAwesomeSymbol{f2a3}] - \definesymbol [assistive-listening-systems] [\FontAwesomeSymbol{f2a2}] - \definesymbol [asterisk] [\FontAwesomeSymbol{f069}] - \definesymbol [at] [\FontAwesomeSymbol{f1fa}] - \definesymbol [audio-description] [\FontAwesomeSymbol{f29e}] - \definesymbol [automobile] [\FontAwesomeSymbol{f1b9}] - \definesymbol [backward] [\FontAwesomeSymbol{f04a}] - \definesymbol [balance-scale] [\FontAwesomeSymbol{f24e}] - \definesymbol [ban] [\FontAwesomeSymbol{f05e}] - \definesymbol [bank] [\FontAwesomeSymbol{f19c}] - \definesymbol [bar-chart] [\FontAwesomeSymbol{f080}] - \definesymbol [bar-chart-o] [\FontAwesomeSymbol{f080}] - \definesymbol [barcode] [\FontAwesomeSymbol{f02a}] - \definesymbol [bars] [\FontAwesomeSymbol{f0c9}] - \definesymbol [battery-0] [\FontAwesomeSymbol{f244}] - \definesymbol [battery-1] [\FontAwesomeSymbol{f243}] - \definesymbol [battery-2] [\FontAwesomeSymbol{f242}] - \definesymbol [battery-3] [\FontAwesomeSymbol{f241}] - \definesymbol [battery-4] [\FontAwesomeSymbol{f240}] - \definesymbol [battery-empty] [\FontAwesomeSymbol{f244}] - \definesymbol [battery-full] [\FontAwesomeSymbol{f240}] - \definesymbol [battery-half] [\FontAwesomeSymbol{f242}] - \definesymbol [battery-quarter] [\FontAwesomeSymbol{f243}] - \definesymbol [battery-three-quarters] [\FontAwesomeSymbol{f241}] - \definesymbol [bed] [\FontAwesomeSymbol{f236}] - \definesymbol [beer] [\FontAwesomeSymbol{f0fc}] - \definesymbol [behance] [\FontAwesomeSymbol{f1b4}] - \definesymbol [behance-square] [\FontAwesomeSymbol{f1b5}] - \definesymbol [bell] [\FontAwesomeSymbol{f0f3}] - \definesymbol [bell-o] [\FontAwesomeSymbol{f0a2}] - \definesymbol [bell-slash] [\FontAwesomeSymbol{f1f6}] - \definesymbol [bell-slash-o] [\FontAwesomeSymbol{f1f7}] - \definesymbol [bicycle] [\FontAwesomeSymbol{f206}] - \definesymbol [binoculars] [\FontAwesomeSymbol{f1e5}] - \definesymbol [birthday-cake] [\FontAwesomeSymbol{f1fd}] - \definesymbol [bitbucket] [\FontAwesomeSymbol{f171}] - \definesymbol [bitbucket-square] [\FontAwesomeSymbol{f172}] - \definesymbol [bitcoin] [\FontAwesomeSymbol{f15a}] - \definesymbol [black-tie] [\FontAwesomeSymbol{f27e}] - \definesymbol [blind] [\FontAwesomeSymbol{f29d}] - \definesymbol [bluetooth] [\FontAwesomeSymbol{f293}] - \definesymbol [bluetooth-b] [\FontAwesomeSymbol{f294}] - \definesymbol [bold] [\FontAwesomeSymbol{f032}] - \definesymbol [bolt] [\FontAwesomeSymbol{f0e7}] - \definesymbol [bomb] [\FontAwesomeSymbol{f1e2}] - \definesymbol [book] [\FontAwesomeSymbol{f02d}] - \definesymbol [bookmark] [\FontAwesomeSymbol{f02e}] - \definesymbol [bookmark-o] [\FontAwesomeSymbol{f097}] - \definesymbol [braille] [\FontAwesomeSymbol{f2a1}] - \definesymbol [briefcase] [\FontAwesomeSymbol{f0b1}] - \definesymbol [btc] [\FontAwesomeSymbol{f15a}] - \definesymbol [bug] [\FontAwesomeSymbol{f188}] - \definesymbol [building] [\FontAwesomeSymbol{f1ad}] - \definesymbol [building-o] [\FontAwesomeSymbol{f0f7}] - \definesymbol [bullhorn] [\FontAwesomeSymbol{f0a1}] - \definesymbol [bullseye] [\FontAwesomeSymbol{f140}] - \definesymbol [bus] [\FontAwesomeSymbol{f207}] - \definesymbol [buysellads] [\FontAwesomeSymbol{f20d}] - \definesymbol [cab] [\FontAwesomeSymbol{f1ba}] - \definesymbol [calculator] [\FontAwesomeSymbol{f1ec}] - \definesymbol [calendar] [\FontAwesomeSymbol{f073}] - \definesymbol [calendar-check-o] [\FontAwesomeSymbol{f274}] - \definesymbol [calendar-minus-o] [\FontAwesomeSymbol{f272}] - \definesymbol [calendar-o] [\FontAwesomeSymbol{f133}] - \definesymbol [calendar-plus-o] [\FontAwesomeSymbol{f271}] - \definesymbol [calendar-times-o] [\FontAwesomeSymbol{f273}] - \definesymbol [camera] [\FontAwesomeSymbol{f030}] - \definesymbol [camera-retro] [\FontAwesomeSymbol{f083}] - \definesymbol [car] [\FontAwesomeSymbol{f1b9}] - \definesymbol [caret-down] [\FontAwesomeSymbol{f0d7}] - \definesymbol [caret-left] [\FontAwesomeSymbol{f0d9}] - \definesymbol [caret-right] [\FontAwesomeSymbol{f0da}] - \definesymbol [caret-square-o-down] [\FontAwesomeSymbol{f150}] - \definesymbol [caret-square-o-left] [\FontAwesomeSymbol{f191}] - \definesymbol [caret-square-o-right] [\FontAwesomeSymbol{f152}] - \definesymbol [caret-square-o-up] [\FontAwesomeSymbol{f151}] - \definesymbol [caret-up] [\FontAwesomeSymbol{f0d8}] - \definesymbol [cart-arrow-down] [\FontAwesomeSymbol{f218}] - \definesymbol [cart-plus] [\FontAwesomeSymbol{f217}] - \definesymbol [cc] [\FontAwesomeSymbol{f20a}] - \definesymbol [cc-amex] [\FontAwesomeSymbol{f1f3}] - \definesymbol [cc-diners-club] [\FontAwesomeSymbol{f24c}] - \definesymbol [cc-discover] [\FontAwesomeSymbol{f1f2}] - \definesymbol [cc-jcb] [\FontAwesomeSymbol{f24b}] - \definesymbol [cc-mastercard] [\FontAwesomeSymbol{f1f1}] - \definesymbol [cc-paypal] [\FontAwesomeSymbol{f1f4}] - \definesymbol [cc-stripe] [\FontAwesomeSymbol{f1f5}] - \definesymbol [cc-visa] [\FontAwesomeSymbol{f1f0}] - \definesymbol [certificate] [\FontAwesomeSymbol{f0a3}] - \definesymbol [chain] [\FontAwesomeSymbol{f0c1}] - \definesymbol [chain-broken] [\FontAwesomeSymbol{f127}] - \definesymbol [check] [\FontAwesomeSymbol{f00c}] - \definesymbol [check-circle] [\FontAwesomeSymbol{f058}] - \definesymbol [check-circle-o] [\FontAwesomeSymbol{f05d}] - \definesymbol [check-square] [\FontAwesomeSymbol{f14a}] - \definesymbol [check-square-o] [\FontAwesomeSymbol{f046}] - \definesymbol [chevron-circle-down] [\FontAwesomeSymbol{f13a}] - \definesymbol [chevron-circle-left] [\FontAwesomeSymbol{f137}] - \definesymbol [chevron-circle-right] [\FontAwesomeSymbol{f138}] - \definesymbol [chevron-circle-up] [\FontAwesomeSymbol{f139}] - \definesymbol [chevron-down] [\FontAwesomeSymbol{f078}] - \definesymbol [chevron-left] [\FontAwesomeSymbol{f053}] - \definesymbol [chevron-right] [\FontAwesomeSymbol{f054}] - \definesymbol [chevron-up] [\FontAwesomeSymbol{f077}] - \definesymbol [child] [\FontAwesomeSymbol{f1ae}] - \definesymbol [chrome] [\FontAwesomeSymbol{f268}] - \definesymbol [circle] [\FontAwesomeSymbol{f111}] - \definesymbol [circle-o] [\FontAwesomeSymbol{f10c}] - \definesymbol [circle-o-notch] [\FontAwesomeSymbol{f1ce}] - \definesymbol [circle-thin] [\FontAwesomeSymbol{f1db}] - \definesymbol [clipboard] [\FontAwesomeSymbol{f0ea}] - \definesymbol [clock-o] [\FontAwesomeSymbol{f017}] - \definesymbol [clone] [\FontAwesomeSymbol{f24d}] - \definesymbol [close] [\FontAwesomeSymbol{f00d}] - \definesymbol [cloud] [\FontAwesomeSymbol{f0c2}] - \definesymbol [cloud-download] [\FontAwesomeSymbol{f0ed}] - \definesymbol [cloud-upload] [\FontAwesomeSymbol{f0ee}] - \definesymbol [cny] [\FontAwesomeSymbol{f157}] - \definesymbol [code] [\FontAwesomeSymbol{f121}] - \definesymbol [code-fork] [\FontAwesomeSymbol{f126}] - \definesymbol [codepen] [\FontAwesomeSymbol{f1cb}] - \definesymbol [codiepie] [\FontAwesomeSymbol{f284}] - \definesymbol [coffee] [\FontAwesomeSymbol{f0f4}] - \definesymbol [cog] [\FontAwesomeSymbol{f013}] - \definesymbol [cogs] [\FontAwesomeSymbol{f085}] - \definesymbol [columns] [\FontAwesomeSymbol{f0db}] - \definesymbol [comment] [\FontAwesomeSymbol{f075}] - \definesymbol [comment-o] [\FontAwesomeSymbol{f0e5}] - \definesymbol [commenting] [\FontAwesomeSymbol{f27a}] - \definesymbol [commenting-o] [\FontAwesomeSymbol{f27b}] - \definesymbol [comments] [\FontAwesomeSymbol{f086}] - \definesymbol [comments-o] [\FontAwesomeSymbol{f0e6}] - \definesymbol [compass] [\FontAwesomeSymbol{f14e}] - \definesymbol [compress] [\FontAwesomeSymbol{f066}] - \definesymbol [connectdevelop] [\FontAwesomeSymbol{f20e}] - \definesymbol [contao] [\FontAwesomeSymbol{f26d}] - \definesymbol [copy] [\FontAwesomeSymbol{f0c5}] - \definesymbol [copyright] [\FontAwesomeSymbol{f1f9}] - \definesymbol [creative-commons] [\FontAwesomeSymbol{f25e}] - \definesymbol [credit-card] [\FontAwesomeSymbol{f09d}] - \definesymbol [credit-card-alt] [\FontAwesomeSymbol{f283}] - \definesymbol [crop] [\FontAwesomeSymbol{f125}] - \definesymbol [crosshairs] [\FontAwesomeSymbol{f05b}] - \definesymbol [css3] [\FontAwesomeSymbol{f13c}] - \definesymbol [cube] [\FontAwesomeSymbol{f1b2}] - \definesymbol [cubes] [\FontAwesomeSymbol{f1b3}] - \definesymbol [cut] [\FontAwesomeSymbol{f0c4}] - \definesymbol [cutlery] [\FontAwesomeSymbol{f0f5}] - \definesymbol [dashboard] [\FontAwesomeSymbol{f0e4}] - \definesymbol [dashcube] [\FontAwesomeSymbol{f210}] - \definesymbol [database] [\FontAwesomeSymbol{f1c0}] - \definesymbol [deaf] [\FontAwesomeSymbol{f2a4}] - \definesymbol [deafness] [\FontAwesomeSymbol{f2a4}] - \definesymbol [dedent] [\FontAwesomeSymbol{f03b}] - \definesymbol [delicious] [\FontAwesomeSymbol{f1a5}] - \definesymbol [desktop] [\FontAwesomeSymbol{f108}] - \definesymbol [deviantart] [\FontAwesomeSymbol{f1bd}] - \definesymbol [diamond] [\FontAwesomeSymbol{f219}] - \definesymbol [digg] [\FontAwesomeSymbol{f1a6}] - \definesymbol [dollar] [\FontAwesomeSymbol{f155}] - \definesymbol [dot-circle-o] [\FontAwesomeSymbol{f192}] - \definesymbol [download] [\FontAwesomeSymbol{f019}] - \definesymbol [dribbble] [\FontAwesomeSymbol{f17d}] - \definesymbol [dropbox] [\FontAwesomeSymbol{f16b}] - \definesymbol [drupal] [\FontAwesomeSymbol{f1a9}] - \definesymbol [edge] [\FontAwesomeSymbol{f282}] - \definesymbol [edit] [\FontAwesomeSymbol{f044}] - \definesymbol [eject] [\FontAwesomeSymbol{f052}] - \definesymbol [ellipsis-h] [\FontAwesomeSymbol{f141}] - \definesymbol [ellipsis-v] [\FontAwesomeSymbol{f142}] - \definesymbol [empire] [\FontAwesomeSymbol{f1d1}] - \definesymbol [envelope] [\FontAwesomeSymbol{f0e0}] - \definesymbol [envelope-o] [\FontAwesomeSymbol{f003}] - \definesymbol [envelope-square] [\FontAwesomeSymbol{f199}] - \definesymbol [envira] [\FontAwesomeSymbol{f299}] - \definesymbol [eraser] [\FontAwesomeSymbol{f12d}] - \definesymbol [eur] [\FontAwesomeSymbol{f153}] - \definesymbol [euro] [\FontAwesomeSymbol{f153}] - \definesymbol [exchange] [\FontAwesomeSymbol{f0ec}] - \definesymbol [exclamation] [\FontAwesomeSymbol{f12a}] - \definesymbol [exclamation-circle] [\FontAwesomeSymbol{f06a}] - \definesymbol [exclamation-triangle] [\FontAwesomeSymbol{f071}] - \definesymbol [expand] [\FontAwesomeSymbol{f065}] - \definesymbol [expeditedssl] [\FontAwesomeSymbol{f23e}] - \definesymbol [external-link] [\FontAwesomeSymbol{f08e}] - \definesymbol [external-link-square] [\FontAwesomeSymbol{f14c}] - \definesymbol [eye] [\FontAwesomeSymbol{f06e}] - \definesymbol [eye-slash] [\FontAwesomeSymbol{f070}] - \definesymbol [eyedropper] [\FontAwesomeSymbol{f1fb}] - \definesymbol [fa] [\FontAwesomeSymbol{f2b4}] - \definesymbol [facebook] [\FontAwesomeSymbol{f09a}] - \definesymbol [facebook-f] [\FontAwesomeSymbol{f09a}] - \definesymbol [facebook-official] [\FontAwesomeSymbol{f230}] - \definesymbol [facebook-square] [\FontAwesomeSymbol{f082}] - \definesymbol [fast-backward] [\FontAwesomeSymbol{f049}] - \definesymbol [fast-forward] [\FontAwesomeSymbol{f050}] - \definesymbol [fax] [\FontAwesomeSymbol{f1ac}] - \definesymbol [feed] [\FontAwesomeSymbol{f09e}] - \definesymbol [female] [\FontAwesomeSymbol{f182}] - \definesymbol [fighter-jet] [\FontAwesomeSymbol{f0fb}] - \definesymbol [file] [\FontAwesomeSymbol{f15b}] - \definesymbol [file-archive-o] [\FontAwesomeSymbol{f1c6}] - \definesymbol [file-audio-o] [\FontAwesomeSymbol{f1c7}] - \definesymbol [file-code-o] [\FontAwesomeSymbol{f1c9}] - \definesymbol [file-excel-o] [\FontAwesomeSymbol{f1c3}] - \definesymbol [file-image-o] [\FontAwesomeSymbol{f1c5}] - \definesymbol [file-movie-o] [\FontAwesomeSymbol{f1c8}] - \definesymbol [file-o] [\FontAwesomeSymbol{f016}] - \definesymbol [file-pdf-o] [\FontAwesomeSymbol{f1c1}] - \definesymbol [file-photo-o] [\FontAwesomeSymbol{f1c5}] - \definesymbol [file-picture-o] [\FontAwesomeSymbol{f1c5}] - \definesymbol [file-powerpoint-o] [\FontAwesomeSymbol{f1c4}] - \definesymbol [file-sound-o] [\FontAwesomeSymbol{f1c7}] - \definesymbol [file-text] [\FontAwesomeSymbol{f15c}] - \definesymbol [file-text-o] [\FontAwesomeSymbol{f0f6}] - \definesymbol [file-video-o] [\FontAwesomeSymbol{f1c8}] - \definesymbol [file-word-o] [\FontAwesomeSymbol{f1c2}] - \definesymbol [file-zip-o] [\FontAwesomeSymbol{f1c6}] - \definesymbol [files-o] [\FontAwesomeSymbol{f0c5}] - \definesymbol [film] [\FontAwesomeSymbol{f008}] - \definesymbol [filter] [\FontAwesomeSymbol{f0b0}] - \definesymbol [fire] [\FontAwesomeSymbol{f06d}] - \definesymbol [fire-extinguisher] [\FontAwesomeSymbol{f134}] - \definesymbol [firefox] [\FontAwesomeSymbol{f269}] - \definesymbol [first-order] [\FontAwesomeSymbol{f2b0}] - \definesymbol [flag] [\FontAwesomeSymbol{f024}] - \definesymbol [flag-checkered] [\FontAwesomeSymbol{f11e}] - \definesymbol [flag-o] [\FontAwesomeSymbol{f11d}] - \definesymbol [flash] [\FontAwesomeSymbol{f0e7}] - \definesymbol [flask] [\FontAwesomeSymbol{f0c3}] - \definesymbol [flickr] [\FontAwesomeSymbol{f16e}] - \definesymbol [floppy-o] [\FontAwesomeSymbol{f0c7}] - \definesymbol [folder] [\FontAwesomeSymbol{f07b}] - \definesymbol [folder-o] [\FontAwesomeSymbol{f114}] - \definesymbol [folder-open] [\FontAwesomeSymbol{f07c}] - \definesymbol [folder-open-o] [\FontAwesomeSymbol{f115}] - \definesymbol [font] [\FontAwesomeSymbol{f031}] - \definesymbol [font-awesome] [\FontAwesomeSymbol{f2b4}] - \definesymbol [fonticons] [\FontAwesomeSymbol{f280}] - \definesymbol [fort-awesome] [\FontAwesomeSymbol{f286}] - \definesymbol [forumbee] [\FontAwesomeSymbol{f211}] - \definesymbol [forward] [\FontAwesomeSymbol{f04e}] - \definesymbol [foursquare] [\FontAwesomeSymbol{f180}] - \definesymbol [frown-o] [\FontAwesomeSymbol{f119}] - \definesymbol [futbol-o] [\FontAwesomeSymbol{f1e3}] - \definesymbol [gamepad] [\FontAwesomeSymbol{f11b}] - \definesymbol [gavel] [\FontAwesomeSymbol{f0e3}] - \definesymbol [gbp] [\FontAwesomeSymbol{f154}] - \definesymbol [ge] [\FontAwesomeSymbol{f1d1}] - \definesymbol [gear] [\FontAwesomeSymbol{f013}] - \definesymbol [gears] [\FontAwesomeSymbol{f085}] - \definesymbol [genderless] [\FontAwesomeSymbol{f22d}] - \definesymbol [get-pocket] [\FontAwesomeSymbol{f265}] - \definesymbol [gg] [\FontAwesomeSymbol{f260}] - \definesymbol [gg-circle] [\FontAwesomeSymbol{f261}] - \definesymbol [gift] [\FontAwesomeSymbol{f06b}] - \definesymbol [git] [\FontAwesomeSymbol{f1d3}] - \definesymbol [git-square] [\FontAwesomeSymbol{f1d2}] - \definesymbol [github] [\FontAwesomeSymbol{f09b}] - \definesymbol [github-alt] [\FontAwesomeSymbol{f113}] - \definesymbol [github-square] [\FontAwesomeSymbol{f092}] - \definesymbol [gitlab] [\FontAwesomeSymbol{f296}] - \definesymbol [gittip] [\FontAwesomeSymbol{f184}] - \definesymbol [glass] [\FontAwesomeSymbol{f000}] - \definesymbol [glide] [\FontAwesomeSymbol{f2a5}] - \definesymbol [glide-g] [\FontAwesomeSymbol{f2a6}] - \definesymbol [globe] [\FontAwesomeSymbol{f0ac}] - \definesymbol [google] [\FontAwesomeSymbol{f1a0}] - \definesymbol [google-plus] [\FontAwesomeSymbol{f0d5}] - \definesymbol [google-plus-circle] [\FontAwesomeSymbol{f2b3}] - \definesymbol [google-plus-official] [\FontAwesomeSymbol{f2b3}] - \definesymbol [google-plus-square] [\FontAwesomeSymbol{f0d4}] - \definesymbol [google-wallet] [\FontAwesomeSymbol{f1ee}] - \definesymbol [graduation-cap] [\FontAwesomeSymbol{f19d}] - \definesymbol [gratipay] [\FontAwesomeSymbol{f184}] - \definesymbol [group] [\FontAwesomeSymbol{f0c0}] - \definesymbol [h-square] [\FontAwesomeSymbol{f0fd}] - \definesymbol [hacker-news] [\FontAwesomeSymbol{f1d4}] - \definesymbol [hand-grab-o] [\FontAwesomeSymbol{f255}] - \definesymbol [hand-lizard-o] [\FontAwesomeSymbol{f258}] - \definesymbol [hand-o-down] [\FontAwesomeSymbol{f0a7}] - \definesymbol [hand-o-left] [\FontAwesomeSymbol{f0a5}] - \definesymbol [hand-o-right] [\FontAwesomeSymbol{f0a4}] - \definesymbol [hand-o-up] [\FontAwesomeSymbol{f0a6}] - \definesymbol [hand-paper-o] [\FontAwesomeSymbol{f256}] - \definesymbol [hand-peace-o] [\FontAwesomeSymbol{f25b}] - \definesymbol [hand-pointer-o] [\FontAwesomeSymbol{f25a}] - \definesymbol [hand-rock-o] [\FontAwesomeSymbol{f255}] - \definesymbol [hand-scissors-o] [\FontAwesomeSymbol{f257}] - \definesymbol [hand-spock-o] [\FontAwesomeSymbol{f259}] - \definesymbol [hand-stop-o] [\FontAwesomeSymbol{f256}] - \definesymbol [hard-of-hearing] [\FontAwesomeSymbol{f2a4}] - \definesymbol [hashtag] [\FontAwesomeSymbol{f292}] - \definesymbol [hdd-o] [\FontAwesomeSymbol{f0a0}] - \definesymbol [header] [\FontAwesomeSymbol{f1dc}] - \definesymbol [headphones] [\FontAwesomeSymbol{f025}] - \definesymbol [heart] [\FontAwesomeSymbol{f004}] - \definesymbol [heart-o] [\FontAwesomeSymbol{f08a}] - \definesymbol [heartbeat] [\FontAwesomeSymbol{f21e}] - \definesymbol [history] [\FontAwesomeSymbol{f1da}] - \definesymbol [home] [\FontAwesomeSymbol{f015}] - \definesymbol [hospital-o] [\FontAwesomeSymbol{f0f8}] - \definesymbol [hotel] [\FontAwesomeSymbol{f236}] - \definesymbol [hourglass] [\FontAwesomeSymbol{f254}] - \definesymbol [hourglass-1] [\FontAwesomeSymbol{f251}] - \definesymbol [hourglass-2] [\FontAwesomeSymbol{f252}] - \definesymbol [hourglass-3] [\FontAwesomeSymbol{f253}] - \definesymbol [hourglass-end] [\FontAwesomeSymbol{f253}] - \definesymbol [hourglass-half] [\FontAwesomeSymbol{f252}] - \definesymbol [hourglass-o] [\FontAwesomeSymbol{f250}] - \definesymbol [hourglass-start] [\FontAwesomeSymbol{f251}] - \definesymbol [houzz] [\FontAwesomeSymbol{f27c}] - \definesymbol [html5] [\FontAwesomeSymbol{f13b}] - \definesymbol [i-cursor] [\FontAwesomeSymbol{f246}] - \definesymbol [ils] [\FontAwesomeSymbol{f20b}] - \definesymbol [image] [\FontAwesomeSymbol{f03e}] - \definesymbol [inbox] [\FontAwesomeSymbol{f01c}] - \definesymbol [indent] [\FontAwesomeSymbol{f03c}] - \definesymbol [industry] [\FontAwesomeSymbol{f275}] - \definesymbol [info] [\FontAwesomeSymbol{f129}] - \definesymbol [info-circle] [\FontAwesomeSymbol{f05a}] - \definesymbol [inr] [\FontAwesomeSymbol{f156}] - \definesymbol [instagram] [\FontAwesomeSymbol{f16d}] - \definesymbol [institution] [\FontAwesomeSymbol{f19c}] - \definesymbol [internet-explorer] [\FontAwesomeSymbol{f26b}] - \definesymbol [intersex] [\FontAwesomeSymbol{f224}] - \definesymbol [ioxhost] [\FontAwesomeSymbol{f208}] - \definesymbol [italic] [\FontAwesomeSymbol{f033}] - \definesymbol [joomla] [\FontAwesomeSymbol{f1aa}] - \definesymbol [jpy] [\FontAwesomeSymbol{f157}] - \definesymbol [jsfiddle] [\FontAwesomeSymbol{f1cc}] - \definesymbol [key] [\FontAwesomeSymbol{f084}] - \definesymbol [keyboard-o] [\FontAwesomeSymbol{f11c}] - \definesymbol [krw] [\FontAwesomeSymbol{f159}] - \definesymbol [language] [\FontAwesomeSymbol{f1ab}] - \definesymbol [laptop] [\FontAwesomeSymbol{f109}] - \definesymbol [lastfm] [\FontAwesomeSymbol{f202}] - \definesymbol [lastfm-square] [\FontAwesomeSymbol{f203}] - \definesymbol [leaf] [\FontAwesomeSymbol{f06c}] - \definesymbol [leanpub] [\FontAwesomeSymbol{f212}] - \definesymbol [legal] [\FontAwesomeSymbol{f0e3}] - \definesymbol [lemon-o] [\FontAwesomeSymbol{f094}] - \definesymbol [level-down] [\FontAwesomeSymbol{f149}] - \definesymbol [level-up] [\FontAwesomeSymbol{f148}] - \definesymbol [life-bouy] [\FontAwesomeSymbol{f1cd}] - \definesymbol [life-buoy] [\FontAwesomeSymbol{f1cd}] - \definesymbol [life-ring] [\FontAwesomeSymbol{f1cd}] - \definesymbol [life-saver] [\FontAwesomeSymbol{f1cd}] - \definesymbol [lightbulb-o] [\FontAwesomeSymbol{f0eb}] - \definesymbol [line-chart] [\FontAwesomeSymbol{f201}] - \definesymbol [link] [\FontAwesomeSymbol{f0c1}] - \definesymbol [linkedin] [\FontAwesomeSymbol{f0e1}] - \definesymbol [linkedin-square] [\FontAwesomeSymbol{f08c}] - \definesymbol [linux] [\FontAwesomeSymbol{f17c}] - \definesymbol [list] [\FontAwesomeSymbol{f03a}] - \definesymbol [list-alt] [\FontAwesomeSymbol{f022}] - \definesymbol [list-ol] [\FontAwesomeSymbol{f0cb}] - \definesymbol [list-ul] [\FontAwesomeSymbol{f0ca}] - \definesymbol [location-arrow] [\FontAwesomeSymbol{f124}] - \definesymbol [lock] [\FontAwesomeSymbol{f023}] - \definesymbol [long-arrow-down] [\FontAwesomeSymbol{f175}] - \definesymbol [long-arrow-left] [\FontAwesomeSymbol{f177}] - \definesymbol [long-arrow-right] [\FontAwesomeSymbol{f178}] - \definesymbol [long-arrow-up] [\FontAwesomeSymbol{f176}] - \definesymbol [low-vision] [\FontAwesomeSymbol{f2a8}] - \definesymbol [magic] [\FontAwesomeSymbol{f0d0}] - \definesymbol [magnet] [\FontAwesomeSymbol{f076}] - \definesymbol [mail-forward] [\FontAwesomeSymbol{f064}] - \definesymbol [mail-reply] [\FontAwesomeSymbol{f112}] - \definesymbol [mail-reply-all] [\FontAwesomeSymbol{f122}] - \definesymbol [male] [\FontAwesomeSymbol{f183}] - \definesymbol [map] [\FontAwesomeSymbol{f279}] - \definesymbol [map-marker] [\FontAwesomeSymbol{f041}] - \definesymbol [map-o] [\FontAwesomeSymbol{f278}] - \definesymbol [map-pin] [\FontAwesomeSymbol{f276}] - \definesymbol [map-signs] [\FontAwesomeSymbol{f277}] - \definesymbol [mars] [\FontAwesomeSymbol{f222}] - \definesymbol [mars-double] [\FontAwesomeSymbol{f227}] - \definesymbol [mars-stroke] [\FontAwesomeSymbol{f229}] - \definesymbol [mars-stroke-h] [\FontAwesomeSymbol{f22b}] - \definesymbol [mars-stroke-v] [\FontAwesomeSymbol{f22a}] - \definesymbol [maxcdn] [\FontAwesomeSymbol{f136}] - \definesymbol [meanpath] [\FontAwesomeSymbol{f20c}] - \definesymbol [medium] [\FontAwesomeSymbol{f23a}] - \definesymbol [medkit] [\FontAwesomeSymbol{f0fa}] - \definesymbol [meh-o] [\FontAwesomeSymbol{f11a}] - \definesymbol [mercury] [\FontAwesomeSymbol{f223}] - \definesymbol [microphone] [\FontAwesomeSymbol{f130}] - \definesymbol [microphone-slash] [\FontAwesomeSymbol{f131}] - \definesymbol [minus] [\FontAwesomeSymbol{f068}] - \definesymbol [minus-circle] [\FontAwesomeSymbol{f056}] - \definesymbol [minus-square] [\FontAwesomeSymbol{f146}] - \definesymbol [minus-square-o] [\FontAwesomeSymbol{f147}] - \definesymbol [mixcloud] [\FontAwesomeSymbol{f289}] - \definesymbol [mobile] [\FontAwesomeSymbol{f10b}] - \definesymbol [mobile-phone] [\FontAwesomeSymbol{f10b}] - \definesymbol [modx] [\FontAwesomeSymbol{f285}] - \definesymbol [money] [\FontAwesomeSymbol{f0d6}] - \definesymbol [moon-o] [\FontAwesomeSymbol{f186}] - \definesymbol [mortar-board] [\FontAwesomeSymbol{f19d}] - \definesymbol [motorcycle] [\FontAwesomeSymbol{f21c}] - \definesymbol [mouse-pointer] [\FontAwesomeSymbol{f245}] - \definesymbol [music] [\FontAwesomeSymbol{f001}] - \definesymbol [navicon] [\FontAwesomeSymbol{f0c9}] - \definesymbol [neuter] [\FontAwesomeSymbol{f22c}] - \definesymbol [newspaper-o] [\FontAwesomeSymbol{f1ea}] - \definesymbol [object-group] [\FontAwesomeSymbol{f247}] - \definesymbol [object-ungroup] [\FontAwesomeSymbol{f248}] - \definesymbol [odnoklassniki] [\FontAwesomeSymbol{f263}] - \definesymbol [odnoklassniki-square] [\FontAwesomeSymbol{f264}] - \definesymbol [opencart] [\FontAwesomeSymbol{f23d}] - \definesymbol [openid] [\FontAwesomeSymbol{f19b}] - \definesymbol [opera] [\FontAwesomeSymbol{f26a}] - \definesymbol [optin-monster] [\FontAwesomeSymbol{f23c}] - \definesymbol [outdent] [\FontAwesomeSymbol{f03b}] - \definesymbol [pagelines] [\FontAwesomeSymbol{f18c}] - \definesymbol [paint-brush] [\FontAwesomeSymbol{f1fc}] - \definesymbol [paper-plane] [\FontAwesomeSymbol{f1d8}] - \definesymbol [paper-plane-o] [\FontAwesomeSymbol{f1d9}] - \definesymbol [paperclip] [\FontAwesomeSymbol{f0c6}] - \definesymbol [paragraph] [\FontAwesomeSymbol{f1dd}] - \definesymbol [paste] [\FontAwesomeSymbol{f0ea}] - \definesymbol [pause] [\FontAwesomeSymbol{f04c}] - \definesymbol [pause-circle] [\FontAwesomeSymbol{f28b}] - \definesymbol [pause-circle-o] [\FontAwesomeSymbol{f28c}] - \definesymbol [paw] [\FontAwesomeSymbol{f1b0}] - \definesymbol [paypal] [\FontAwesomeSymbol{f1ed}] - \definesymbol [pencil] [\FontAwesomeSymbol{f040}] - \definesymbol [pencil-square] [\FontAwesomeSymbol{f14b}] - \definesymbol [pencil-square-o] [\FontAwesomeSymbol{f044}] - \definesymbol [percent] [\FontAwesomeSymbol{f295}] - \definesymbol [phone] [\FontAwesomeSymbol{f095}] - \definesymbol [phone-square] [\FontAwesomeSymbol{f098}] - \definesymbol [photo] [\FontAwesomeSymbol{f03e}] - \definesymbol [picture-o] [\FontAwesomeSymbol{f03e}] - \definesymbol [pie-chart] [\FontAwesomeSymbol{f200}] - \definesymbol [pied-piper] [\FontAwesomeSymbol{f2ae}] - \definesymbol [pied-piper-alt] [\FontAwesomeSymbol{f1a8}] - \definesymbol [pied-piper-pp] [\FontAwesomeSymbol{f1a7}] - \definesymbol [pinterest] [\FontAwesomeSymbol{f0d2}] - \definesymbol [pinterest-p] [\FontAwesomeSymbol{f231}] - \definesymbol [pinterest-square] [\FontAwesomeSymbol{f0d3}] - \definesymbol [plane] [\FontAwesomeSymbol{f072}] - \definesymbol [play] [\FontAwesomeSymbol{f04b}] - \definesymbol [play-circle] [\FontAwesomeSymbol{f144}] - \definesymbol [play-circle-o] [\FontAwesomeSymbol{f01d}] - \definesymbol [plug] [\FontAwesomeSymbol{f1e6}] - \definesymbol [plus] [\FontAwesomeSymbol{f067}] - \definesymbol [plus-circle] [\FontAwesomeSymbol{f055}] - \definesymbol [plus-square] [\FontAwesomeSymbol{f0fe}] - \definesymbol [plus-square-o] [\FontAwesomeSymbol{f196}] - \definesymbol [power-off] [\FontAwesomeSymbol{f011}] - \definesymbol [print] [\FontAwesomeSymbol{f02f}] - \definesymbol [product-hunt] [\FontAwesomeSymbol{f288}] - \definesymbol [puzzle-piece] [\FontAwesomeSymbol{f12e}] - \definesymbol [qq] [\FontAwesomeSymbol{f1d6}] - \definesymbol [qrcode] [\FontAwesomeSymbol{f029}] - \definesymbol [question] [\FontAwesomeSymbol{f128}] - \definesymbol [question-circle] [\FontAwesomeSymbol{f059}] - \definesymbol [question-circle-o] [\FontAwesomeSymbol{f29c}] - \definesymbol [quote-left] [\FontAwesomeSymbol{f10d}] - \definesymbol [quote-right] [\FontAwesomeSymbol{f10e}] - \definesymbol [ra] [\FontAwesomeSymbol{f1d0}] - \definesymbol [random] [\FontAwesomeSymbol{f074}] - \definesymbol [rebel] [\FontAwesomeSymbol{f1d0}] - \definesymbol [recycle] [\FontAwesomeSymbol{f1b8}] - \definesymbol [reddit] [\FontAwesomeSymbol{f1a1}] - \definesymbol [reddit-alien] [\FontAwesomeSymbol{f281}] - \definesymbol [reddit-square] [\FontAwesomeSymbol{f1a2}] - \definesymbol [refresh] [\FontAwesomeSymbol{f021}] - \definesymbol [registered] [\FontAwesomeSymbol{f25d}] - \definesymbol [remove] [\FontAwesomeSymbol{f00d}] - \definesymbol [renren] [\FontAwesomeSymbol{f18b}] - \definesymbol [reorder] [\FontAwesomeSymbol{f0c9}] - \definesymbol [repeat] [\FontAwesomeSymbol{f01e}] - \definesymbol [reply] [\FontAwesomeSymbol{f112}] - \definesymbol [reply-all] [\FontAwesomeSymbol{f122}] - \definesymbol [resistance] [\FontAwesomeSymbol{f1d0}] - \definesymbol [retweet] [\FontAwesomeSymbol{f079}] - \definesymbol [rmb] [\FontAwesomeSymbol{f157}] - \definesymbol [road] [\FontAwesomeSymbol{f018}] - \definesymbol [rocket] [\FontAwesomeSymbol{f135}] - \definesymbol [rotate-left] [\FontAwesomeSymbol{f0e2}] - \definesymbol [rotate-right] [\FontAwesomeSymbol{f01e}] - \definesymbol [rouble] [\FontAwesomeSymbol{f158}] - \definesymbol [rss] [\FontAwesomeSymbol{f09e}] - \definesymbol [rss-square] [\FontAwesomeSymbol{f143}] - \definesymbol [rub] [\FontAwesomeSymbol{f158}] - \definesymbol [ruble] [\FontAwesomeSymbol{f158}] - \definesymbol [rupee] [\FontAwesomeSymbol{f156}] - \definesymbol [safari] [\FontAwesomeSymbol{f267}] - \definesymbol [save] [\FontAwesomeSymbol{f0c7}] - \definesymbol [scissors] [\FontAwesomeSymbol{f0c4}] - \definesymbol [scribd] [\FontAwesomeSymbol{f28a}] - \definesymbol [search] [\FontAwesomeSymbol{f002}] - \definesymbol [search-minus] [\FontAwesomeSymbol{f010}] - \definesymbol [search-plus] [\FontAwesomeSymbol{f00e}] - \definesymbol [sellsy] [\FontAwesomeSymbol{f213}] - \definesymbol [send] [\FontAwesomeSymbol{f1d8}] - \definesymbol [send-o] [\FontAwesomeSymbol{f1d9}] - \definesymbol [server] [\FontAwesomeSymbol{f233}] - \definesymbol [share] [\FontAwesomeSymbol{f064}] - \definesymbol [share-alt] [\FontAwesomeSymbol{f1e0}] - \definesymbol [share-alt-square] [\FontAwesomeSymbol{f1e1}] - \definesymbol [share-square] [\FontAwesomeSymbol{f14d}] - \definesymbol [share-square-o] [\FontAwesomeSymbol{f045}] - \definesymbol [shekel] [\FontAwesomeSymbol{f20b}] - \definesymbol [sheqel] [\FontAwesomeSymbol{f20b}] - \definesymbol [shield] [\FontAwesomeSymbol{f132}] - \definesymbol [ship] [\FontAwesomeSymbol{f21a}] - \definesymbol [shirtsinbulk] [\FontAwesomeSymbol{f214}] - \definesymbol [shopping-bag] [\FontAwesomeSymbol{f290}] - \definesymbol [shopping-basket] [\FontAwesomeSymbol{f291}] - \definesymbol [shopping-cart] [\FontAwesomeSymbol{f07a}] - \definesymbol [sign-in] [\FontAwesomeSymbol{f090}] - \definesymbol [sign-language] [\FontAwesomeSymbol{f2a7}] - \definesymbol [sign-out] [\FontAwesomeSymbol{f08b}] - \definesymbol [signal] [\FontAwesomeSymbol{f012}] - \definesymbol [signing] [\FontAwesomeSymbol{f2a7}] - \definesymbol [simplybuilt] [\FontAwesomeSymbol{f215}] - \definesymbol [sitemap] [\FontAwesomeSymbol{f0e8}] - \definesymbol [skyatlas] [\FontAwesomeSymbol{f216}] - \definesymbol [skype] [\FontAwesomeSymbol{f17e}] - \definesymbol [slack] [\FontAwesomeSymbol{f198}] - \definesymbol [sliders] [\FontAwesomeSymbol{f1de}] - \definesymbol [slideshare] [\FontAwesomeSymbol{f1e7}] - \definesymbol [smile-o] [\FontAwesomeSymbol{f118}] - \definesymbol [snapchat] [\FontAwesomeSymbol{f2ab}] - \definesymbol [snapchat-ghost] [\FontAwesomeSymbol{f2ac}] - \definesymbol [snapchat-square] [\FontAwesomeSymbol{f2ad}] - \definesymbol [soccer-ball-o] [\FontAwesomeSymbol{f1e3}] - \definesymbol [sort] [\FontAwesomeSymbol{f0dc}] - \definesymbol [sort-alpha-asc] [\FontAwesomeSymbol{f15d}] - \definesymbol [sort-alpha-desc] [\FontAwesomeSymbol{f15e}] - \definesymbol [sort-amount-asc] [\FontAwesomeSymbol{f160}] - \definesymbol [sort-amount-desc] [\FontAwesomeSymbol{f161}] - \definesymbol [sort-asc] [\FontAwesomeSymbol{f0de}] - \definesymbol [sort-desc] [\FontAwesomeSymbol{f0dd}] - \definesymbol [sort-down] [\FontAwesomeSymbol{f0dd}] - \definesymbol [sort-numeric-asc] [\FontAwesomeSymbol{f162}] - \definesymbol [sort-numeric-desc] [\FontAwesomeSymbol{f163}] - \definesymbol [sort-up] [\FontAwesomeSymbol{f0de}] - \definesymbol [soundcloud] [\FontAwesomeSymbol{f1be}] - \definesymbol [space-shuttle] [\FontAwesomeSymbol{f197}] - \definesymbol [spinner] [\FontAwesomeSymbol{f110}] - \definesymbol [spoon] [\FontAwesomeSymbol{f1b1}] - \definesymbol [spotify] [\FontAwesomeSymbol{f1bc}] - \definesymbol [square] [\FontAwesomeSymbol{f0c8}] - \definesymbol [square-o] [\FontAwesomeSymbol{f096}] - \definesymbol [stack-exchange] [\FontAwesomeSymbol{f18d}] - \definesymbol [stack-overflow] [\FontAwesomeSymbol{f16c}] - \definesymbol [star] [\FontAwesomeSymbol{f005}] - \definesymbol [star-half] [\FontAwesomeSymbol{f089}] - \definesymbol [star-half-empty] [\FontAwesomeSymbol{f123}] - \definesymbol [star-half-full] [\FontAwesomeSymbol{f123}] - \definesymbol [star-half-o] [\FontAwesomeSymbol{f123}] - \definesymbol [star-o] [\FontAwesomeSymbol{f006}] - \definesymbol [steam] [\FontAwesomeSymbol{f1b6}] - \definesymbol [steam-square] [\FontAwesomeSymbol{f1b7}] - \definesymbol [step-backward] [\FontAwesomeSymbol{f048}] - \definesymbol [step-forward] [\FontAwesomeSymbol{f051}] - \definesymbol [stethoscope] [\FontAwesomeSymbol{f0f1}] - \definesymbol [sticky-note] [\FontAwesomeSymbol{f249}] - \definesymbol [sticky-note-o] [\FontAwesomeSymbol{f24a}] - \definesymbol [stop] [\FontAwesomeSymbol{f04d}] - \definesymbol [stop-circle] [\FontAwesomeSymbol{f28d}] - \definesymbol [stop-circle-o] [\FontAwesomeSymbol{f28e}] - \definesymbol [street-view] [\FontAwesomeSymbol{f21d}] - \definesymbol [strikethrough] [\FontAwesomeSymbol{f0cc}] - \definesymbol [stumbleupon] [\FontAwesomeSymbol{f1a4}] - \definesymbol [stumbleupon-circle] [\FontAwesomeSymbol{f1a3}] - \definesymbol [subscript] [\FontAwesomeSymbol{f12c}] - \definesymbol [subway] [\FontAwesomeSymbol{f239}] - \definesymbol [suitcase] [\FontAwesomeSymbol{f0f2}] - \definesymbol [sun-o] [\FontAwesomeSymbol{f185}] - \definesymbol [superscript] [\FontAwesomeSymbol{f12b}] - \definesymbol [support] [\FontAwesomeSymbol{f1cd}] - \definesymbol [table] [\FontAwesomeSymbol{f0ce}] - \definesymbol [tablet] [\FontAwesomeSymbol{f10a}] - \definesymbol [tachometer] [\FontAwesomeSymbol{f0e4}] - \definesymbol [tag] [\FontAwesomeSymbol{f02b}] - \definesymbol [tags] [\FontAwesomeSymbol{f02c}] - \definesymbol [tasks] [\FontAwesomeSymbol{f0ae}] - \definesymbol [taxi] [\FontAwesomeSymbol{f1ba}] - \definesymbol [television] [\FontAwesomeSymbol{f26c}] - \definesymbol [tencent-weibo] [\FontAwesomeSymbol{f1d5}] - \definesymbol [terminal] [\FontAwesomeSymbol{f120}] - \definesymbol [text-height] [\FontAwesomeSymbol{f034}] - \definesymbol [text-width] [\FontAwesomeSymbol{f035}] - \definesymbol [th] [\FontAwesomeSymbol{f00a}] - \definesymbol [th-large] [\FontAwesomeSymbol{f009}] - \definesymbol [th-list] [\FontAwesomeSymbol{f00b}] - \definesymbol [themeisle] [\FontAwesomeSymbol{f2b2}] - \definesymbol [thumb-tack] [\FontAwesomeSymbol{f08d}] - \definesymbol [thumbs-down] [\FontAwesomeSymbol{f165}] - \definesymbol [thumbs-o-down] [\FontAwesomeSymbol{f088}] - \definesymbol [thumbs-o-up] [\FontAwesomeSymbol{f087}] - \definesymbol [thumbs-up] [\FontAwesomeSymbol{f164}] - \definesymbol [ticket] [\FontAwesomeSymbol{f145}] - \definesymbol [times] [\FontAwesomeSymbol{f00d}] - \definesymbol [times-circle] [\FontAwesomeSymbol{f057}] - \definesymbol [times-circle-o] [\FontAwesomeSymbol{f05c}] - \definesymbol [tint] [\FontAwesomeSymbol{f043}] - \definesymbol [toggle-down] [\FontAwesomeSymbol{f150}] - \definesymbol [toggle-left] [\FontAwesomeSymbol{f191}] - \definesymbol [toggle-off] [\FontAwesomeSymbol{f204}] - \definesymbol [toggle-on] [\FontAwesomeSymbol{f205}] - \definesymbol [toggle-right] [\FontAwesomeSymbol{f152}] - \definesymbol [toggle-up] [\FontAwesomeSymbol{f151}] - \definesymbol [trademark] [\FontAwesomeSymbol{f25c}] - \definesymbol [train] [\FontAwesomeSymbol{f238}] - \definesymbol [transgender] [\FontAwesomeSymbol{f224}] - \definesymbol [transgender-alt] [\FontAwesomeSymbol{f225}] - \definesymbol [trash] [\FontAwesomeSymbol{f1f8}] - \definesymbol [trash-o] [\FontAwesomeSymbol{f014}] - \definesymbol [tree] [\FontAwesomeSymbol{f1bb}] - \definesymbol [trello] [\FontAwesomeSymbol{f181}] - \definesymbol [tripadvisor] [\FontAwesomeSymbol{f262}] - \definesymbol [trophy] [\FontAwesomeSymbol{f091}] - \definesymbol [truck] [\FontAwesomeSymbol{f0d1}] - \definesymbol [try] [\FontAwesomeSymbol{f195}] - \definesymbol [tty] [\FontAwesomeSymbol{f1e4}] - \definesymbol [tumblr] [\FontAwesomeSymbol{f173}] - \definesymbol [tumblr-square] [\FontAwesomeSymbol{f174}] - \definesymbol [turkish-lira] [\FontAwesomeSymbol{f195}] - \definesymbol [tv] [\FontAwesomeSymbol{f26c}] - \definesymbol [twitch] [\FontAwesomeSymbol{f1e8}] - \definesymbol [twitter] [\FontAwesomeSymbol{f099}] - \definesymbol [twitter-square] [\FontAwesomeSymbol{f081}] - \definesymbol [umbrella] [\FontAwesomeSymbol{f0e9}] - \definesymbol [underline] [\FontAwesomeSymbol{f0cd}] - \definesymbol [undo] [\FontAwesomeSymbol{f0e2}] - \definesymbol [universal-access] [\FontAwesomeSymbol{f29a}] - \definesymbol [university] [\FontAwesomeSymbol{f19c}] - \definesymbol [unlink] [\FontAwesomeSymbol{f127}] - \definesymbol [unlock] [\FontAwesomeSymbol{f09c}] - \definesymbol [unlock-alt] [\FontAwesomeSymbol{f13e}] - \definesymbol [unsorted] [\FontAwesomeSymbol{f0dc}] - \definesymbol [upload] [\FontAwesomeSymbol{f093}] - \definesymbol [usb] [\FontAwesomeSymbol{f287}] - \definesymbol [usd] [\FontAwesomeSymbol{f155}] - \definesymbol [user] [\FontAwesomeSymbol{f007}] - \definesymbol [user-md] [\FontAwesomeSymbol{f0f0}] - \definesymbol [user-plus] [\FontAwesomeSymbol{f234}] - \definesymbol [user-secret] [\FontAwesomeSymbol{f21b}] - \definesymbol [user-times] [\FontAwesomeSymbol{f235}] - \definesymbol [users] [\FontAwesomeSymbol{f0c0}] - \definesymbol [venus] [\FontAwesomeSymbol{f221}] - \definesymbol [venus-double] [\FontAwesomeSymbol{f226}] - \definesymbol [venus-mars] [\FontAwesomeSymbol{f228}] - \definesymbol [viacoin] [\FontAwesomeSymbol{f237}] - \definesymbol [viadeo] [\FontAwesomeSymbol{f2a9}] - \definesymbol [viadeo-square] [\FontAwesomeSymbol{f2aa}] - \definesymbol [video-camera] [\FontAwesomeSymbol{f03d}] - \definesymbol [vimeo] [\FontAwesomeSymbol{f27d}] - \definesymbol [vimeo-square] [\FontAwesomeSymbol{f194}] - \definesymbol [vine] [\FontAwesomeSymbol{f1ca}] - \definesymbol [vk] [\FontAwesomeSymbol{f189}] - \definesymbol [volume-control-phone] [\FontAwesomeSymbol{f2a0}] - \definesymbol [volume-down] [\FontAwesomeSymbol{f027}] - \definesymbol [volume-off] [\FontAwesomeSymbol{f026}] - \definesymbol [volume-up] [\FontAwesomeSymbol{f028}] - \definesymbol [warning] [\FontAwesomeSymbol{f071}] - \definesymbol [wechat] [\FontAwesomeSymbol{f1d7}] - \definesymbol [weibo] [\FontAwesomeSymbol{f18a}] - \definesymbol [weixin] [\FontAwesomeSymbol{f1d7}] - \definesymbol [whatsapp] [\FontAwesomeSymbol{f232}] - \definesymbol [wheelchair] [\FontAwesomeSymbol{f193}] - \definesymbol [wheelchair-alt] [\FontAwesomeSymbol{f29b}] - \definesymbol [wifi] [\FontAwesomeSymbol{f1eb}] - \definesymbol [wikipedia-w] [\FontAwesomeSymbol{f266}] - \definesymbol [windows] [\FontAwesomeSymbol{f17a}] - \definesymbol [won] [\FontAwesomeSymbol{f159}] - \definesymbol [wordpress] [\FontAwesomeSymbol{f19a}] - \definesymbol [wpbeginner] [\FontAwesomeSymbol{f297}] - \definesymbol [wpforms] [\FontAwesomeSymbol{f298}] - \definesymbol [wrench] [\FontAwesomeSymbol{f0ad}] - \definesymbol [xing] [\FontAwesomeSymbol{f168}] - \definesymbol [xing-square] [\FontAwesomeSymbol{f169}] - \definesymbol [y-combinator] [\FontAwesomeSymbol{f23b}] - \definesymbol [y-combinator-square] [\FontAwesomeSymbol{f1d4}] - \definesymbol [yahoo] [\FontAwesomeSymbol{f19e}] - \definesymbol [yc] [\FontAwesomeSymbol{f23b}] - \definesymbol [yc-square] [\FontAwesomeSymbol{f1d4}] - \definesymbol [yelp] [\FontAwesomeSymbol{f1e9}] - \definesymbol [yen] [\FontAwesomeSymbol{f157}] - \definesymbol [yoast] [\FontAwesomeSymbol{f2b1}] - \definesymbol [youtube] [\FontAwesomeSymbol{f167}] - \definesymbol [youtube-play] [\FontAwesomeSymbol{f16a}] - \definesymbol [youtube-square] [\FontAwesomeSymbol{f166}] + \definesymbol [wheelchair] [\FontAwesomeSymbol{_378}] +% \definesymbol [500px] [\FontAwesomeSymbol{f26e}] +% \definesymbol [adjust] [\FontAwesomeSymbol{f042}] +% \definesymbol [adn] [\FontAwesomeSymbol{f170}] +% \definesymbol [align-center] [\FontAwesomeSymbol{f037}] +% \definesymbol [align-justify] [\FontAwesomeSymbol{f039}] +% \definesymbol [align-left] [\FontAwesomeSymbol{f036}] +% \definesymbol [align-right] [\FontAwesomeSymbol{f038}] +% \definesymbol [amazon] [\FontAwesomeSymbol{f270}] +% \definesymbol [ambulance] [\FontAwesomeSymbol{f0f9}] +% \definesymbol [american-sign-language-interpreting] [\FontAwesomeSymbol{f2a3}] +% \definesymbol [anchor] [\FontAwesomeSymbol{f13d}] +% \definesymbol [android] [\FontAwesomeSymbol{f17b}] +% \definesymbol [angellist] [\FontAwesomeSymbol{f209}] +% \definesymbol [angle-double-down] [\FontAwesomeSymbol{f103}] +% \definesymbol [angle-double-left] [\FontAwesomeSymbol{f100}] +% \definesymbol [angle-double-right] [\FontAwesomeSymbol{f101}] +% \definesymbol [angle-double-up] [\FontAwesomeSymbol{f102}] +% \definesymbol [angle-down] [\FontAwesomeSymbol{f107}] +% \definesymbol [angle-left] [\FontAwesomeSymbol{f104}] +% \definesymbol [angle-right] [\FontAwesomeSymbol{f105}] +% \definesymbol [angle-up] [\FontAwesomeSymbol{f106}] +% \definesymbol [apple] [\FontAwesomeSymbol{f179}] +% \definesymbol [archive] [\FontAwesomeSymbol{f187}] +% \definesymbol [area-chart] [\FontAwesomeSymbol{f1fe}] +% \definesymbol [arrow-circle-down] [\FontAwesomeSymbol{f0ab}] +% \definesymbol [arrow-circle-left] [\FontAwesomeSymbol{f0a8}] +% \definesymbol [arrow-circle-o-down] [\FontAwesomeSymbol{f01a}] +% \definesymbol [arrow-circle-o-left] [\FontAwesomeSymbol{f190}] +% \definesymbol [arrow-circle-o-right] [\FontAwesomeSymbol{f18e}] +% \definesymbol [arrow-circle-o-up] [\FontAwesomeSymbol{f01b}] +% \definesymbol [arrow-circle-right] [\FontAwesomeSymbol{f0a9}] +% \definesymbol [arrow-circle-up] [\FontAwesomeSymbol{f0aa}] +% \definesymbol [arrow-down] [\FontAwesomeSymbol{f063}] +% \definesymbol [arrow-left] [\FontAwesomeSymbol{f060}] +% \definesymbol [arrow-right] [\FontAwesomeSymbol{f061}] +% \definesymbol [arrow-up] [\FontAwesomeSymbol{f062}] +% \definesymbol [arrows] [\FontAwesomeSymbol{f047}] +% \definesymbol [arrows-alt] [\FontAwesomeSymbol{f0b2}] +% \definesymbol [arrows-h] [\FontAwesomeSymbol{f07e}] +% \definesymbol [arrows-v] [\FontAwesomeSymbol{f07d}] +% \definesymbol [asl-interpreting] [\FontAwesomeSymbol{f2a3}] +% \definesymbol [assistive-listening-systems] [\FontAwesomeSymbol{f2a2}] +% \definesymbol [asterisk] [\FontAwesomeSymbol{f069}] +% \definesymbol [at] [\FontAwesomeSymbol{f1fa}] +% \definesymbol [audio-description] [\FontAwesomeSymbol{f29e}] +% \definesymbol [automobile] [\FontAwesomeSymbol{f1b9}] +% \definesymbol [backward] [\FontAwesomeSymbol{f04a}] +% \definesymbol [balance-scale] [\FontAwesomeSymbol{f24e}] +% \definesymbol [ban] [\FontAwesomeSymbol{f05e}] +% \definesymbol [bank] [\FontAwesomeSymbol{f19c}] +% \definesymbol [bar-chart] [\FontAwesomeSymbol{f080}] +% \definesymbol [bar-chart-o] [\FontAwesomeSymbol{f080}] +% \definesymbol [barcode] [\FontAwesomeSymbol{f02a}] +% \definesymbol [bars] [\FontAwesomeSymbol{f0c9}] +% \definesymbol [battery-0] [\FontAwesomeSymbol{f244}] +% \definesymbol [battery-1] [\FontAwesomeSymbol{f243}] +% \definesymbol [battery-2] [\FontAwesomeSymbol{f242}] +% \definesymbol [battery-3] [\FontAwesomeSymbol{f241}] +% \definesymbol [battery-4] [\FontAwesomeSymbol{f240}] +% \definesymbol [battery-empty] [\FontAwesomeSymbol{f244}] +% \definesymbol [battery-full] [\FontAwesomeSymbol{f240}] +% \definesymbol [battery-half] [\FontAwesomeSymbol{f242}] +% \definesymbol [battery-quarter] [\FontAwesomeSymbol{f243}] +% \definesymbol [battery-three-quarters] [\FontAwesomeSymbol{f241}] +% \definesymbol [bed] [\FontAwesomeSymbol{f236}] +% \definesymbol [beer] [\FontAwesomeSymbol{f0fc}] +% \definesymbol [behance] [\FontAwesomeSymbol{f1b4}] +% \definesymbol [behance-square] [\FontAwesomeSymbol{f1b5}] +% \definesymbol [bell] [\FontAwesomeSymbol{f0f3}] +% \definesymbol [bell-o] [\FontAwesomeSymbol{f0a2}] +% \definesymbol [bell-slash] [\FontAwesomeSymbol{f1f6}] +% \definesymbol [bell-slash-o] [\FontAwesomeSymbol{f1f7}] +% \definesymbol [bicycle] [\FontAwesomeSymbol{f206}] +% \definesymbol [binoculars] [\FontAwesomeSymbol{f1e5}] +% \definesymbol [birthday-cake] [\FontAwesomeSymbol{f1fd}] +% \definesymbol [bitbucket] [\FontAwesomeSymbol{f171}] +% \definesymbol [bitbucket-square] [\FontAwesomeSymbol{f172}] +% \definesymbol [bitcoin] [\FontAwesomeSymbol{f15a}] +% \definesymbol [black-tie] [\FontAwesomeSymbol{f27e}] +% \definesymbol [blind] [\FontAwesomeSymbol{f29d}] +% \definesymbol [bluetooth] [\FontAwesomeSymbol{f293}] +% \definesymbol [bluetooth-b] [\FontAwesomeSymbol{f294}] +% \definesymbol [bold] [\FontAwesomeSymbol{f032}] +% \definesymbol [bolt] [\FontAwesomeSymbol{f0e7}] +% \definesymbol [bomb] [\FontAwesomeSymbol{f1e2}] +% \definesymbol [book] [\FontAwesomeSymbol{f02d}] +% \definesymbol [bookmark] [\FontAwesomeSymbol{f02e}] +% \definesymbol [bookmark-o] [\FontAwesomeSymbol{f097}] +% \definesymbol [braille] [\FontAwesomeSymbol{f2a1}] +% \definesymbol [briefcase] [\FontAwesomeSymbol{f0b1}] +% \definesymbol [btc] [\FontAwesomeSymbol{f15a}] +% \definesymbol [bug] [\FontAwesomeSymbol{f188}] +% \definesymbol [building] [\FontAwesomeSymbol{f1ad}] +% \definesymbol [building-o] [\FontAwesomeSymbol{f0f7}] +% \definesymbol [bullhorn] [\FontAwesomeSymbol{f0a1}] +% \definesymbol [bullseye] [\FontAwesomeSymbol{f140}] +% \definesymbol [bus] [\FontAwesomeSymbol{f207}] +% \definesymbol [buysellads] [\FontAwesomeSymbol{f20d}] +% \definesymbol [cab] [\FontAwesomeSymbol{f1ba}] +% \definesymbol [calculator] [\FontAwesomeSymbol{f1ec}] +% \definesymbol [calendar] [\FontAwesomeSymbol{f073}] +% \definesymbol [calendar-check-o] [\FontAwesomeSymbol{f274}] +% \definesymbol [calendar-minus-o] [\FontAwesomeSymbol{f272}] +% \definesymbol [calendar-o] [\FontAwesomeSymbol{f133}] +% \definesymbol [calendar-plus-o] [\FontAwesomeSymbol{f271}] +% \definesymbol [calendar-times-o] [\FontAwesomeSymbol{f273}] +% \definesymbol [camera] [\FontAwesomeSymbol{f030}] +% \definesymbol [camera-retro] [\FontAwesomeSymbol{f083}] +% \definesymbol [car] [\FontAwesomeSymbol{f1b9}] +% \definesymbol [caret-down] [\FontAwesomeSymbol{f0d7}] +% \definesymbol [caret-left] [\FontAwesomeSymbol{f0d9}] +% \definesymbol [caret-right] [\FontAwesomeSymbol{f0da}] +% \definesymbol [caret-square-o-down] [\FontAwesomeSymbol{f150}] +% \definesymbol [caret-square-o-left] [\FontAwesomeSymbol{f191}] +% \definesymbol [caret-square-o-right] [\FontAwesomeSymbol{f152}] +% \definesymbol [caret-square-o-up] [\FontAwesomeSymbol{f151}] +% \definesymbol [caret-up] [\FontAwesomeSymbol{f0d8}] +% \definesymbol [cart-arrow-down] [\FontAwesomeSymbol{f218}] +% \definesymbol [cart-plus] [\FontAwesomeSymbol{f217}] +% \definesymbol [cc] [\FontAwesomeSymbol{f20a}] +% \definesymbol [cc-amex] [\FontAwesomeSymbol{f1f3}] +% \definesymbol [cc-diners-club] [\FontAwesomeSymbol{f24c}] +% \definesymbol [cc-discover] [\FontAwesomeSymbol{f1f2}] +% \definesymbol [cc-jcb] [\FontAwesomeSymbol{f24b}] +% \definesymbol [cc-mastercard] [\FontAwesomeSymbol{f1f1}] +% \definesymbol [cc-paypal] [\FontAwesomeSymbol{f1f4}] +% \definesymbol [cc-stripe] [\FontAwesomeSymbol{f1f5}] +% \definesymbol [cc-visa] [\FontAwesomeSymbol{f1f0}] +% \definesymbol [certificate] [\FontAwesomeSymbol{f0a3}] +% \definesymbol [chain] [\FontAwesomeSymbol{f0c1}] +% \definesymbol [chain-broken] [\FontAwesomeSymbol{f127}] +% \definesymbol [check] [\FontAwesomeSymbol{f00c}] +% \definesymbol [check-circle] [\FontAwesomeSymbol{f058}] +% \definesymbol [check-circle-o] [\FontAwesomeSymbol{f05d}] +% \definesymbol [check-square] [\FontAwesomeSymbol{f14a}] +% \definesymbol [check-square-o] [\FontAwesomeSymbol{f046}] +% \definesymbol [chevron-circle-down] [\FontAwesomeSymbol{f13a}] +% \definesymbol [chevron-circle-left] [\FontAwesomeSymbol{f137}] +% \definesymbol [chevron-circle-right] [\FontAwesomeSymbol{f138}] +% \definesymbol [chevron-circle-up] [\FontAwesomeSymbol{f139}] +% \definesymbol [chevron-down] [\FontAwesomeSymbol{f078}] +% \definesymbol [chevron-left] [\FontAwesomeSymbol{f053}] +% \definesymbol [chevron-right] [\FontAwesomeSymbol{f054}] +% \definesymbol [chevron-up] [\FontAwesomeSymbol{f077}] +% \definesymbol [child] [\FontAwesomeSymbol{f1ae}] +% \definesymbol [chrome] [\FontAwesomeSymbol{f268}] +% \definesymbol [circle] [\FontAwesomeSymbol{f111}] +% \definesymbol [circle-o] [\FontAwesomeSymbol{f10c}] +% \definesymbol [circle-o-notch] [\FontAwesomeSymbol{f1ce}] +% \definesymbol [circle-thin] [\FontAwesomeSymbol{f1db}] +% \definesymbol [clipboard] [\FontAwesomeSymbol{f0ea}] +% \definesymbol [clock-o] [\FontAwesomeSymbol{f017}] +% \definesymbol [clone] [\FontAwesomeSymbol{f24d}] +% \definesymbol [close] [\FontAwesomeSymbol{f00d}] +% \definesymbol [cloud] [\FontAwesomeSymbol{f0c2}] +% \definesymbol [cloud-download] [\FontAwesomeSymbol{f0ed}] +% \definesymbol [cloud-upload] [\FontAwesomeSymbol{f0ee}] +% \definesymbol [cny] [\FontAwesomeSymbol{f157}] +% \definesymbol [code] [\FontAwesomeSymbol{f121}] +% \definesymbol [code-fork] [\FontAwesomeSymbol{f126}] +% \definesymbol [codepen] [\FontAwesomeSymbol{f1cb}] +% \definesymbol [codiepie] [\FontAwesomeSymbol{f284}] +% \definesymbol [coffee] [\FontAwesomeSymbol{f0f4}] +% \definesymbol [cog] [\FontAwesomeSymbol{f013}] +% \definesymbol [cogs] [\FontAwesomeSymbol{f085}] +% \definesymbol [columns] [\FontAwesomeSymbol{f0db}] +% \definesymbol [comment] [\FontAwesomeSymbol{f075}] +% \definesymbol [comment-o] [\FontAwesomeSymbol{f0e5}] +% \definesymbol [commenting] [\FontAwesomeSymbol{f27a}] +% \definesymbol [commenting-o] [\FontAwesomeSymbol{f27b}] +% \definesymbol [comments] [\FontAwesomeSymbol{f086}] +% \definesymbol [comments-o] [\FontAwesomeSymbol{f0e6}] +% \definesymbol [compass] [\FontAwesomeSymbol{f14e}] +% \definesymbol [compress] [\FontAwesomeSymbol{f066}] +% \definesymbol [connectdevelop] [\FontAwesomeSymbol{f20e}] +% \definesymbol [contao] [\FontAwesomeSymbol{f26d}] +% \definesymbol [copy] [\FontAwesomeSymbol{f0c5}] +% \definesymbol [copyright] [\FontAwesomeSymbol{f1f9}] +% \definesymbol [creative-commons] [\FontAwesomeSymbol{f25e}] +% \definesymbol [credit-card] [\FontAwesomeSymbol{f09d}] +% \definesymbol [credit-card-alt] [\FontAwesomeSymbol{f283}] +% \definesymbol [crop] [\FontAwesomeSymbol{f125}] +% \definesymbol [crosshairs] [\FontAwesomeSymbol{f05b}] +% \definesymbol [css3] [\FontAwesomeSymbol{f13c}] +% \definesymbol [cube] [\FontAwesomeSymbol{f1b2}] +% \definesymbol [cubes] [\FontAwesomeSymbol{f1b3}] +% \definesymbol [cut] [\FontAwesomeSymbol{f0c4}] +% \definesymbol [cutlery] [\FontAwesomeSymbol{f0f5}] +% \definesymbol [dashboard] [\FontAwesomeSymbol{f0e4}] +% \definesymbol [dashcube] [\FontAwesomeSymbol{f210}] +% \definesymbol [database] [\FontAwesomeSymbol{f1c0}] +% \definesymbol [deaf] [\FontAwesomeSymbol{f2a4}] +% \definesymbol [deafness] [\FontAwesomeSymbol{f2a4}] +% \definesymbol [dedent] [\FontAwesomeSymbol{f03b}] +% \definesymbol [delicious] [\FontAwesomeSymbol{f1a5}] +% \definesymbol [desktop] [\FontAwesomeSymbol{f108}] +% \definesymbol [deviantart] [\FontAwesomeSymbol{f1bd}] +% \definesymbol [diamond] [\FontAwesomeSymbol{f219}] +% \definesymbol [digg] [\FontAwesomeSymbol{f1a6}] +% \definesymbol [dollar] [\FontAwesomeSymbol{f155}] +% \definesymbol [dot-circle-o] [\FontAwesomeSymbol{f192}] +% \definesymbol [download] [\FontAwesomeSymbol{f019}] +% \definesymbol [dribbble] [\FontAwesomeSymbol{f17d}] +% \definesymbol [dropbox] [\FontAwesomeSymbol{f16b}] +% \definesymbol [drupal] [\FontAwesomeSymbol{f1a9}] +% \definesymbol [edge] [\FontAwesomeSymbol{f282}] +% \definesymbol [edit] [\FontAwesomeSymbol{f044}] +% \definesymbol [eject] [\FontAwesomeSymbol{f052}] +% \definesymbol [ellipsis-h] [\FontAwesomeSymbol{f141}] +% \definesymbol [ellipsis-v] [\FontAwesomeSymbol{f142}] +% \definesymbol [empire] [\FontAwesomeSymbol{f1d1}] +% \definesymbol [envelope] [\FontAwesomeSymbol{f0e0}] +% \definesymbol [envelope-o] [\FontAwesomeSymbol{f003}] +% \definesymbol [envelope-square] [\FontAwesomeSymbol{f199}] +% \definesymbol [envira] [\FontAwesomeSymbol{f299}] +% \definesymbol [eraser] [\FontAwesomeSymbol{f12d}] +% \definesymbol [eur] [\FontAwesomeSymbol{f153}] +% \definesymbol [euro] [\FontAwesomeSymbol{f153}] +% \definesymbol [exchange] [\FontAwesomeSymbol{f0ec}] +% \definesymbol [exclamation] [\FontAwesomeSymbol{f12a}] +% \definesymbol [exclamation-circle] [\FontAwesomeSymbol{f06a}] +% \definesymbol [exclamation-triangle] [\FontAwesomeSymbol{f071}] +% \definesymbol [expand] [\FontAwesomeSymbol{f065}] +% \definesymbol [expeditedssl] [\FontAwesomeSymbol{f23e}] +% \definesymbol [external-link] [\FontAwesomeSymbol{f08e}] +% \definesymbol [external-link-square] [\FontAwesomeSymbol{f14c}] +% \definesymbol [eye] [\FontAwesomeSymbol{f06e}] +% \definesymbol [eye-slash] [\FontAwesomeSymbol{f070}] +% \definesymbol [eyedropper] [\FontAwesomeSymbol{f1fb}] +% \definesymbol [fa] [\FontAwesomeSymbol{f2b4}] +% \definesymbol [facebook] [\FontAwesomeSymbol{f09a}] +% \definesymbol [facebook-f] [\FontAwesomeSymbol{f09a}] +% \definesymbol [facebook-official] [\FontAwesomeSymbol{f230}] +% \definesymbol [facebook-square] [\FontAwesomeSymbol{f082}] +% \definesymbol [fast-backward] [\FontAwesomeSymbol{f049}] +% \definesymbol [fast-forward] [\FontAwesomeSymbol{f050}] +% \definesymbol [fax] [\FontAwesomeSymbol{f1ac}] +% \definesymbol [feed] [\FontAwesomeSymbol{f09e}] +% \definesymbol [female] [\FontAwesomeSymbol{f182}] +% \definesymbol [fighter-jet] [\FontAwesomeSymbol{f0fb}] +% \definesymbol [file] [\FontAwesomeSymbol{f15b}] +% \definesymbol [file-archive-o] [\FontAwesomeSymbol{f1c6}] +% \definesymbol [file-audio-o] [\FontAwesomeSymbol{f1c7}] +% \definesymbol [file-code-o] [\FontAwesomeSymbol{f1c9}] +% \definesymbol [file-excel-o] [\FontAwesomeSymbol{f1c3}] +% \definesymbol [file-image-o] [\FontAwesomeSymbol{f1c5}] +% \definesymbol [file-movie-o] [\FontAwesomeSymbol{f1c8}] +% \definesymbol [file-o] [\FontAwesomeSymbol{f016}] +% \definesymbol [file-pdf-o] [\FontAwesomeSymbol{f1c1}] +% \definesymbol [file-photo-o] [\FontAwesomeSymbol{f1c5}] +% \definesymbol [file-picture-o] [\FontAwesomeSymbol{f1c5}] +% \definesymbol [file-powerpoint-o] [\FontAwesomeSymbol{f1c4}] +% \definesymbol [file-sound-o] [\FontAwesomeSymbol{f1c7}] +% \definesymbol [file-text] [\FontAwesomeSymbol{f15c}] +% \definesymbol [file-text-o] [\FontAwesomeSymbol{f0f6}] +% \definesymbol [file-video-o] [\FontAwesomeSymbol{f1c8}] +% \definesymbol [file-word-o] [\FontAwesomeSymbol{f1c2}] +% \definesymbol [file-zip-o] [\FontAwesomeSymbol{f1c6}] +% \definesymbol [files-o] [\FontAwesomeSymbol{f0c5}] +% \definesymbol [film] [\FontAwesomeSymbol{f008}] +% \definesymbol [filter] [\FontAwesomeSymbol{f0b0}] +% \definesymbol [fire] [\FontAwesomeSymbol{f06d}] +% \definesymbol [fire-extinguisher] [\FontAwesomeSymbol{f134}] +% \definesymbol [firefox] [\FontAwesomeSymbol{f269}] +% \definesymbol [first-order] [\FontAwesomeSymbol{f2b0}] +% \definesymbol [flag] [\FontAwesomeSymbol{f024}] +% \definesymbol [flag-checkered] [\FontAwesomeSymbol{f11e}] +% \definesymbol [flag-o] [\FontAwesomeSymbol{f11d}] +% \definesymbol [flash] [\FontAwesomeSymbol{f0e7}] +% \definesymbol [flask] [\FontAwesomeSymbol{f0c3}] +% \definesymbol [flickr] [\FontAwesomeSymbol{f16e}] +% \definesymbol [floppy-o] [\FontAwesomeSymbol{f0c7}] +% \definesymbol [folder] [\FontAwesomeSymbol{f07b}] +% \definesymbol [folder-o] [\FontAwesomeSymbol{f114}] +% \definesymbol [folder-open] [\FontAwesomeSymbol{f07c}] +% \definesymbol [folder-open-o] [\FontAwesomeSymbol{f115}] +% \definesymbol [font] [\FontAwesomeSymbol{f031}] +% \definesymbol [font-awesome] [\FontAwesomeSymbol{f2b4}] +% \definesymbol [fonticons] [\FontAwesomeSymbol{f280}] +% \definesymbol [fort-awesome] [\FontAwesomeSymbol{f286}] +% \definesymbol [forumbee] [\FontAwesomeSymbol{f211}] +% \definesymbol [forward] [\FontAwesomeSymbol{f04e}] +% \definesymbol [foursquare] [\FontAwesomeSymbol{f180}] +% \definesymbol [frown-o] [\FontAwesomeSymbol{f119}] +% \definesymbol [futbol-o] [\FontAwesomeSymbol{f1e3}] +% \definesymbol [gamepad] [\FontAwesomeSymbol{f11b}] +% \definesymbol [gavel] [\FontAwesomeSymbol{f0e3}] +% \definesymbol [gbp] [\FontAwesomeSymbol{f154}] +% \definesymbol [ge] [\FontAwesomeSymbol{f1d1}] +% \definesymbol [gear] [\FontAwesomeSymbol{f013}] +% \definesymbol [gears] [\FontAwesomeSymbol{f085}] +% \definesymbol [genderless] [\FontAwesomeSymbol{f22d}] +% \definesymbol [get-pocket] [\FontAwesomeSymbol{f265}] +% \definesymbol [gg] [\FontAwesomeSymbol{f260}] +% \definesymbol [gg-circle] [\FontAwesomeSymbol{f261}] +% \definesymbol [gift] [\FontAwesomeSymbol{f06b}] +% \definesymbol [git] [\FontAwesomeSymbol{f1d3}] +% \definesymbol [git-square] [\FontAwesomeSymbol{f1d2}] +% \definesymbol [github] [\FontAwesomeSymbol{f09b}] +% \definesymbol [github-alt] [\FontAwesomeSymbol{f113}] +% \definesymbol [github-square] [\FontAwesomeSymbol{f092}] +% \definesymbol [gitlab] [\FontAwesomeSymbol{f296}] +% \definesymbol [gittip] [\FontAwesomeSymbol{f184}] +% \definesymbol [glass] [\FontAwesomeSymbol{f000}] +% \definesymbol [glide] [\FontAwesomeSymbol{f2a5}] +% \definesymbol [glide-g] [\FontAwesomeSymbol{f2a6}] +% \definesymbol [globe] [\FontAwesomeSymbol{f0ac}] +% \definesymbol [google] [\FontAwesomeSymbol{f1a0}] +% \definesymbol [google-plus] [\FontAwesomeSymbol{f0d5}] +% \definesymbol [google-plus-circle] [\FontAwesomeSymbol{f2b3}] +% \definesymbol [google-plus-official] [\FontAwesomeSymbol{f2b3}] +% \definesymbol [google-plus-square] [\FontAwesomeSymbol{f0d4}] +% \definesymbol [google-wallet] [\FontAwesomeSymbol{f1ee}] +% \definesymbol [graduation-cap] [\FontAwesomeSymbol{f19d}] +% \definesymbol [gratipay] [\FontAwesomeSymbol{f184}] +% \definesymbol [group] [\FontAwesomeSymbol{f0c0}] +% \definesymbol [h-square] [\FontAwesomeSymbol{f0fd}] +% \definesymbol [hacker-news] [\FontAwesomeSymbol{f1d4}] +% \definesymbol [hand-grab-o] [\FontAwesomeSymbol{f255}] +% \definesymbol [hand-lizard-o] [\FontAwesomeSymbol{f258}] +% \definesymbol [hand-o-down] [\FontAwesomeSymbol{f0a7}] +% \definesymbol [hand-o-left] [\FontAwesomeSymbol{f0a5}] +% \definesymbol [hand-o-right] [\FontAwesomeSymbol{f0a4}] +% \definesymbol [hand-o-up] [\FontAwesomeSymbol{f0a6}] +% \definesymbol [hand-paper-o] [\FontAwesomeSymbol{f256}] +% \definesymbol [hand-peace-o] [\FontAwesomeSymbol{f25b}] +% \definesymbol [hand-pointer-o] [\FontAwesomeSymbol{f25a}] +% \definesymbol [hand-rock-o] [\FontAwesomeSymbol{f255}] +% \definesymbol [hand-scissors-o] [\FontAwesomeSymbol{f257}] +% \definesymbol [hand-spock-o] [\FontAwesomeSymbol{f259}] +% \definesymbol [hand-stop-o] [\FontAwesomeSymbol{f256}] +% \definesymbol [hard-of-hearing] [\FontAwesomeSymbol{f2a4}] +% \definesymbol [hashtag] [\FontAwesomeSymbol{f292}] +% \definesymbol [hdd-o] [\FontAwesomeSymbol{f0a0}] +% \definesymbol [header] [\FontAwesomeSymbol{f1dc}] +% \definesymbol [headphones] [\FontAwesomeSymbol{f025}] +% \definesymbol [heart] [\FontAwesomeSymbol{f004}] +% \definesymbol [heart-o] [\FontAwesomeSymbol{f08a}] +% \definesymbol [heartbeat] [\FontAwesomeSymbol{f21e}] +% \definesymbol [history] [\FontAwesomeSymbol{f1da}] +% \definesymbol [home] [\FontAwesomeSymbol{f015}] +% \definesymbol [hospital-o] [\FontAwesomeSymbol{f0f8}] +% \definesymbol [hotel] [\FontAwesomeSymbol{f236}] +% \definesymbol [hourglass] [\FontAwesomeSymbol{f254}] +% \definesymbol [hourglass-1] [\FontAwesomeSymbol{f251}] +% \definesymbol [hourglass-2] [\FontAwesomeSymbol{f252}] +% \definesymbol [hourglass-3] [\FontAwesomeSymbol{f253}] +% \definesymbol [hourglass-end] [\FontAwesomeSymbol{f253}] +% \definesymbol [hourglass-half] [\FontAwesomeSymbol{f252}] +% \definesymbol [hourglass-o] [\FontAwesomeSymbol{f250}] +% \definesymbol [hourglass-start] [\FontAwesomeSymbol{f251}] +% \definesymbol [houzz] [\FontAwesomeSymbol{f27c}] +% \definesymbol [html5] [\FontAwesomeSymbol{f13b}] +% \definesymbol [i-cursor] [\FontAwesomeSymbol{f246}] +% \definesymbol [ils] [\FontAwesomeSymbol{f20b}] +% \definesymbol [image] [\FontAwesomeSymbol{f03e}] +% \definesymbol [inbox] [\FontAwesomeSymbol{f01c}] +% \definesymbol [indent] [\FontAwesomeSymbol{f03c}] +% \definesymbol [industry] [\FontAwesomeSymbol{f275}] +% \definesymbol [info] [\FontAwesomeSymbol{f129}] +% \definesymbol [info-circle] [\FontAwesomeSymbol{f05a}] +% \definesymbol [inr] [\FontAwesomeSymbol{f156}] +% \definesymbol [instagram] [\FontAwesomeSymbol{f16d}] +% \definesymbol [institution] [\FontAwesomeSymbol{f19c}] +% \definesymbol [internet-explorer] [\FontAwesomeSymbol{f26b}] +% \definesymbol [intersex] [\FontAwesomeSymbol{f224}] +% \definesymbol [ioxhost] [\FontAwesomeSymbol{f208}] +% \definesymbol [italic] [\FontAwesomeSymbol{f033}] +% \definesymbol [joomla] [\FontAwesomeSymbol{f1aa}] +% \definesymbol [jpy] [\FontAwesomeSymbol{f157}] +% \definesymbol [jsfiddle] [\FontAwesomeSymbol{f1cc}] +% \definesymbol [key] [\FontAwesomeSymbol{f084}] +% \definesymbol [keyboard-o] [\FontAwesomeSymbol{f11c}] +% \definesymbol [krw] [\FontAwesomeSymbol{f159}] +% \definesymbol [language] [\FontAwesomeSymbol{f1ab}] +% \definesymbol [laptop] [\FontAwesomeSymbol{f109}] +% \definesymbol [lastfm] [\FontAwesomeSymbol{f202}] +% \definesymbol [lastfm-square] [\FontAwesomeSymbol{f203}] +% \definesymbol [leaf] [\FontAwesomeSymbol{f06c}] +% \definesymbol [leanpub] [\FontAwesomeSymbol{f212}] +% \definesymbol [legal] [\FontAwesomeSymbol{f0e3}] +% \definesymbol [lemon-o] [\FontAwesomeSymbol{f094}] +% \definesymbol [level-down] [\FontAwesomeSymbol{f149}] +% \definesymbol [level-up] [\FontAwesomeSymbol{f148}] +% \definesymbol [life-bouy] [\FontAwesomeSymbol{f1cd}] +% \definesymbol [life-buoy] [\FontAwesomeSymbol{f1cd}] +% \definesymbol [life-ring] [\FontAwesomeSymbol{f1cd}] +% \definesymbol [life-saver] [\FontAwesomeSymbol{f1cd}] +% \definesymbol [lightbulb-o] [\FontAwesomeSymbol{f0eb}] +% \definesymbol [line-chart] [\FontAwesomeSymbol{f201}] +% \definesymbol [link] [\FontAwesomeSymbol{f0c1}] +% \definesymbol [linkedin] [\FontAwesomeSymbol{f0e1}] +% \definesymbol [linkedin-square] [\FontAwesomeSymbol{f08c}] +% \definesymbol [linux] [\FontAwesomeSymbol{f17c}] +% \definesymbol [list] [\FontAwesomeSymbol{f03a}] +% \definesymbol [list-alt] [\FontAwesomeSymbol{f022}] +% \definesymbol [list-ol] [\FontAwesomeSymbol{f0cb}] +% \definesymbol [list-ul] [\FontAwesomeSymbol{f0ca}] +% \definesymbol [location-arrow] [\FontAwesomeSymbol{f124}] +% \definesymbol [lock] [\FontAwesomeSymbol{f023}] +% \definesymbol [long-arrow-down] [\FontAwesomeSymbol{f175}] +% \definesymbol [long-arrow-left] [\FontAwesomeSymbol{f177}] +% \definesymbol [long-arrow-right] [\FontAwesomeSymbol{f178}] +% \definesymbol [long-arrow-up] [\FontAwesomeSymbol{f176}] +% \definesymbol [low-vision] [\FontAwesomeSymbol{f2a8}] +% \definesymbol [magic] [\FontAwesomeSymbol{f0d0}] +% \definesymbol [magnet] [\FontAwesomeSymbol{f076}] +% \definesymbol [mail-forward] [\FontAwesomeSymbol{f064}] +% \definesymbol [mail-reply] [\FontAwesomeSymbol{f112}] +% \definesymbol [mail-reply-all] [\FontAwesomeSymbol{f122}] +% \definesymbol [male] [\FontAwesomeSymbol{f183}] +% \definesymbol [map] [\FontAwesomeSymbol{f279}] +% \definesymbol [map-marker] [\FontAwesomeSymbol{f041}] +% \definesymbol [map-o] [\FontAwesomeSymbol{f278}] +% \definesymbol [map-pin] [\FontAwesomeSymbol{f276}] +% \definesymbol [map-signs] [\FontAwesomeSymbol{f277}] +% \definesymbol [mars] [\FontAwesomeSymbol{f222}] +% \definesymbol [mars-double] [\FontAwesomeSymbol{f227}] +% \definesymbol [mars-stroke] [\FontAwesomeSymbol{f229}] +% \definesymbol [mars-stroke-h] [\FontAwesomeSymbol{f22b}] +% \definesymbol [mars-stroke-v] [\FontAwesomeSymbol{f22a}] +% \definesymbol [maxcdn] [\FontAwesomeSymbol{f136}] +% \definesymbol [meanpath] [\FontAwesomeSymbol{f20c}] +% \definesymbol [medium] [\FontAwesomeSymbol{f23a}] +% \definesymbol [medkit] [\FontAwesomeSymbol{f0fa}] +% \definesymbol [meh-o] [\FontAwesomeSymbol{f11a}] +% \definesymbol [mercury] [\FontAwesomeSymbol{f223}] +% \definesymbol [microphone] [\FontAwesomeSymbol{f130}] +% \definesymbol [microphone-slash] [\FontAwesomeSymbol{f131}] +% \definesymbol [minus] [\FontAwesomeSymbol{f068}] +% \definesymbol [minus-circle] [\FontAwesomeSymbol{f056}] +% \definesymbol [minus-square] [\FontAwesomeSymbol{f146}] +% \definesymbol [minus-square-o] [\FontAwesomeSymbol{f147}] +% \definesymbol [mixcloud] [\FontAwesomeSymbol{f289}] +% \definesymbol [mobile] [\FontAwesomeSymbol{f10b}] +% \definesymbol [mobile-phone] [\FontAwesomeSymbol{f10b}] +% \definesymbol [modx] [\FontAwesomeSymbol{f285}] +% \definesymbol [money] [\FontAwesomeSymbol{f0d6}] +% \definesymbol [moon-o] [\FontAwesomeSymbol{f186}] +% \definesymbol [mortar-board] [\FontAwesomeSymbol{f19d}] +% \definesymbol [motorcycle] [\FontAwesomeSymbol{f21c}] +% \definesymbol [mouse-pointer] [\FontAwesomeSymbol{f245}] +% \definesymbol [music] [\FontAwesomeSymbol{f001}] +% \definesymbol [navicon] [\FontAwesomeSymbol{f0c9}] +% \definesymbol [neuter] [\FontAwesomeSymbol{f22c}] +% \definesymbol [newspaper-o] [\FontAwesomeSymbol{f1ea}] +% \definesymbol [object-group] [\FontAwesomeSymbol{f247}] +% \definesymbol [object-ungroup] [\FontAwesomeSymbol{f248}] +% \definesymbol [odnoklassniki] [\FontAwesomeSymbol{f263}] +% \definesymbol [odnoklassniki-square] [\FontAwesomeSymbol{f264}] +% \definesymbol [opencart] [\FontAwesomeSymbol{f23d}] +% \definesymbol [openid] [\FontAwesomeSymbol{f19b}] +% \definesymbol [opera] [\FontAwesomeSymbol{f26a}] +% \definesymbol [optin-monster] [\FontAwesomeSymbol{f23c}] +% \definesymbol [outdent] [\FontAwesomeSymbol{f03b}] +% \definesymbol [pagelines] [\FontAwesomeSymbol{f18c}] +% \definesymbol [paint-brush] [\FontAwesomeSymbol{f1fc}] +% \definesymbol [paper-plane] [\FontAwesomeSymbol{f1d8}] +% \definesymbol [paper-plane-o] [\FontAwesomeSymbol{f1d9}] +% \definesymbol [paperclip] [\FontAwesomeSymbol{f0c6}] +% \definesymbol [paragraph] [\FontAwesomeSymbol{f1dd}] +% \definesymbol [paste] [\FontAwesomeSymbol{f0ea}] +% \definesymbol [pause] [\FontAwesomeSymbol{f04c}] +% \definesymbol [pause-circle] [\FontAwesomeSymbol{f28b}] +% \definesymbol [pause-circle-o] [\FontAwesomeSymbol{f28c}] +% \definesymbol [paw] [\FontAwesomeSymbol{f1b0}] +% \definesymbol [paypal] [\FontAwesomeSymbol{f1ed}] +% \definesymbol [pencil] [\FontAwesomeSymbol{f040}] +% \definesymbol [pencil-square] [\FontAwesomeSymbol{f14b}] +% \definesymbol [pencil-square-o] [\FontAwesomeSymbol{f044}] +% \definesymbol [percent] [\FontAwesomeSymbol{f295}] +% \definesymbol [phone] [\FontAwesomeSymbol{f095}] +% \definesymbol [phone-square] [\FontAwesomeSymbol{f098}] +% \definesymbol [photo] [\FontAwesomeSymbol{f03e}] +% \definesymbol [picture-o] [\FontAwesomeSymbol{f03e}] +% \definesymbol [pie-chart] [\FontAwesomeSymbol{f200}] +% \definesymbol [pied-piper] [\FontAwesomeSymbol{f2ae}] +% \definesymbol [pied-piper-alt] [\FontAwesomeSymbol{f1a8}] +% \definesymbol [pied-piper-pp] [\FontAwesomeSymbol{f1a7}] +% \definesymbol [pinterest] [\FontAwesomeSymbol{f0d2}] +% \definesymbol [pinterest-p] [\FontAwesomeSymbol{f231}] +% \definesymbol [pinterest-square] [\FontAwesomeSymbol{f0d3}] +% \definesymbol [plane] [\FontAwesomeSymbol{f072}] +% \definesymbol [play] [\FontAwesomeSymbol{f04b}] +% \definesymbol [play-circle] [\FontAwesomeSymbol{f144}] +% \definesymbol [play-circle-o] [\FontAwesomeSymbol{f01d}] +% \definesymbol [plug] [\FontAwesomeSymbol{f1e6}] +% \definesymbol [plus] [\FontAwesomeSymbol{f067}] +% \definesymbol [plus-circle] [\FontAwesomeSymbol{f055}] +% \definesymbol [plus-square] [\FontAwesomeSymbol{f0fe}] +% \definesymbol [plus-square-o] [\FontAwesomeSymbol{f196}] +% \definesymbol [power-off] [\FontAwesomeSymbol{f011}] +% \definesymbol [print] [\FontAwesomeSymbol{f02f}] +% \definesymbol [product-hunt] [\FontAwesomeSymbol{f288}] +% \definesymbol [puzzle-piece] [\FontAwesomeSymbol{f12e}] +% \definesymbol [qq] [\FontAwesomeSymbol{f1d6}] +% \definesymbol [qrcode] [\FontAwesomeSymbol{f029}] +% \definesymbol [question] [\FontAwesomeSymbol{f128}] +% \definesymbol [question-circle] [\FontAwesomeSymbol{f059}] +% \definesymbol [question-circle-o] [\FontAwesomeSymbol{f29c}] +% \definesymbol [quote-left] [\FontAwesomeSymbol{f10d}] +% \definesymbol [quote-right] [\FontAwesomeSymbol{f10e}] +% \definesymbol [ra] [\FontAwesomeSymbol{f1d0}] +% \definesymbol [random] [\FontAwesomeSymbol{f074}] +% \definesymbol [rebel] [\FontAwesomeSymbol{f1d0}] +% \definesymbol [recycle] [\FontAwesomeSymbol{f1b8}] +% \definesymbol [reddit] [\FontAwesomeSymbol{f1a1}] +% \definesymbol [reddit-alien] [\FontAwesomeSymbol{f281}] +% \definesymbol [reddit-square] [\FontAwesomeSymbol{f1a2}] +% \definesymbol [refresh] [\FontAwesomeSymbol{f021}] +% \definesymbol [registered] [\FontAwesomeSymbol{f25d}] +% \definesymbol [remove] [\FontAwesomeSymbol{f00d}] +% \definesymbol [renren] [\FontAwesomeSymbol{f18b}] +% \definesymbol [reorder] [\FontAwesomeSymbol{f0c9}] +% \definesymbol [repeat] [\FontAwesomeSymbol{f01e}] +% \definesymbol [reply] [\FontAwesomeSymbol{f112}] +% \definesymbol [reply-all] [\FontAwesomeSymbol{f122}] +% \definesymbol [resistance] [\FontAwesomeSymbol{f1d0}] +% \definesymbol [retweet] [\FontAwesomeSymbol{f079}] +% \definesymbol [rmb] [\FontAwesomeSymbol{f157}] +% \definesymbol [road] [\FontAwesomeSymbol{f018}] +% \definesymbol [rocket] [\FontAwesomeSymbol{f135}] +% \definesymbol [rotate-left] [\FontAwesomeSymbol{f0e2}] +% \definesymbol [rotate-right] [\FontAwesomeSymbol{f01e}] +% \definesymbol [rouble] [\FontAwesomeSymbol{f158}] +% \definesymbol [rss] [\FontAwesomeSymbol{f09e}] +% \definesymbol [rss-square] [\FontAwesomeSymbol{f143}] +% \definesymbol [rub] [\FontAwesomeSymbol{f158}] +% \definesymbol [ruble] [\FontAwesomeSymbol{f158}] +% \definesymbol [rupee] [\FontAwesomeSymbol{f156}] +% \definesymbol [safari] [\FontAwesomeSymbol{f267}] +% \definesymbol [save] [\FontAwesomeSymbol{f0c7}] +% \definesymbol [scissors] [\FontAwesomeSymbol{f0c4}] +% \definesymbol [scribd] [\FontAwesomeSymbol{f28a}] +% \definesymbol [search] [\FontAwesomeSymbol{f002}] +% \definesymbol [search-minus] [\FontAwesomeSymbol{f010}] +% \definesymbol [search-plus] [\FontAwesomeSymbol{f00e}] +% \definesymbol [sellsy] [\FontAwesomeSymbol{f213}] +% \definesymbol [send] [\FontAwesomeSymbol{f1d8}] +% \definesymbol [send-o] [\FontAwesomeSymbol{f1d9}] +% \definesymbol [server] [\FontAwesomeSymbol{f233}] +% \definesymbol [share] [\FontAwesomeSymbol{f064}] +% \definesymbol [share-alt] [\FontAwesomeSymbol{f1e0}] +% \definesymbol [share-alt-square] [\FontAwesomeSymbol{f1e1}] +% \definesymbol [share-square] [\FontAwesomeSymbol{f14d}] +% \definesymbol [share-square-o] [\FontAwesomeSymbol{f045}] +% \definesymbol [shekel] [\FontAwesomeSymbol{f20b}] +% \definesymbol [sheqel] [\FontAwesomeSymbol{f20b}] +% \definesymbol [shield] [\FontAwesomeSymbol{f132}] +% \definesymbol [ship] [\FontAwesomeSymbol{f21a}] +% \definesymbol [shirtsinbulk] [\FontAwesomeSymbol{f214}] +% \definesymbol [shopping-bag] [\FontAwesomeSymbol{f290}] +% \definesymbol [shopping-basket] [\FontAwesomeSymbol{f291}] +% \definesymbol [shopping-cart] [\FontAwesomeSymbol{f07a}] +% \definesymbol [sign-in] [\FontAwesomeSymbol{f090}] +% \definesymbol [sign-language] [\FontAwesomeSymbol{f2a7}] +% \definesymbol [sign-out] [\FontAwesomeSymbol{f08b}] +% \definesymbol [signal] [\FontAwesomeSymbol{f012}] +% \definesymbol [signing] [\FontAwesomeSymbol{f2a7}] +% \definesymbol [simplybuilt] [\FontAwesomeSymbol{f215}] +% \definesymbol [sitemap] [\FontAwesomeSymbol{f0e8}] +% \definesymbol [skyatlas] [\FontAwesomeSymbol{f216}] +% \definesymbol [skype] [\FontAwesomeSymbol{f17e}] +% \definesymbol [slack] [\FontAwesomeSymbol{f198}] +% \definesymbol [sliders] [\FontAwesomeSymbol{f1de}] +% \definesymbol [slideshare] [\FontAwesomeSymbol{f1e7}] +% \definesymbol [smile-o] [\FontAwesomeSymbol{f118}] +% \definesymbol [snapchat] [\FontAwesomeSymbol{f2ab}] +% \definesymbol [snapchat-ghost] [\FontAwesomeSymbol{f2ac}] +% \definesymbol [snapchat-square] [\FontAwesomeSymbol{f2ad}] +% \definesymbol [soccer-ball-o] [\FontAwesomeSymbol{f1e3}] +% \definesymbol [sort] [\FontAwesomeSymbol{f0dc}] +% \definesymbol [sort-alpha-asc] [\FontAwesomeSymbol{f15d}] +% \definesymbol [sort-alpha-desc] [\FontAwesomeSymbol{f15e}] +% \definesymbol [sort-amount-asc] [\FontAwesomeSymbol{f160}] +% \definesymbol [sort-amount-desc] [\FontAwesomeSymbol{f161}] +% \definesymbol [sort-asc] [\FontAwesomeSymbol{f0de}] +% \definesymbol [sort-desc] [\FontAwesomeSymbol{f0dd}] +% \definesymbol [sort-down] [\FontAwesomeSymbol{f0dd}] +% \definesymbol [sort-numeric-asc] [\FontAwesomeSymbol{f162}] +% \definesymbol [sort-numeric-desc] [\FontAwesomeSymbol{f163}] +% \definesymbol [sort-up] [\FontAwesomeSymbol{f0de}] +% \definesymbol [soundcloud] [\FontAwesomeSymbol{f1be}] +% \definesymbol [space-shuttle] [\FontAwesomeSymbol{f197}] +% \definesymbol [spinner] [\FontAwesomeSymbol{f110}] +% \definesymbol [spoon] [\FontAwesomeSymbol{f1b1}] +% \definesymbol [spotify] [\FontAwesomeSymbol{f1bc}] +% \definesymbol [square] [\FontAwesomeSymbol{f0c8}] +% \definesymbol [square-o] [\FontAwesomeSymbol{f096}] +% \definesymbol [stack-exchange] [\FontAwesomeSymbol{f18d}] +% \definesymbol [stack-overflow] [\FontAwesomeSymbol{f16c}] +% \definesymbol [star] [\FontAwesomeSymbol{f005}] +% \definesymbol [star-half] [\FontAwesomeSymbol{f089}] +% \definesymbol [star-half-empty] [\FontAwesomeSymbol{f123}] +% \definesymbol [star-half-full] [\FontAwesomeSymbol{f123}] +% \definesymbol [star-half-o] [\FontAwesomeSymbol{f123}] +% \definesymbol [star-o] [\FontAwesomeSymbol{f006}] +% \definesymbol [steam] [\FontAwesomeSymbol{f1b6}] +% \definesymbol [steam-square] [\FontAwesomeSymbol{f1b7}] +% \definesymbol [step-backward] [\FontAwesomeSymbol{f048}] +% \definesymbol [step-forward] [\FontAwesomeSymbol{f051}] +% \definesymbol [stethoscope] [\FontAwesomeSymbol{f0f1}] +% \definesymbol [sticky-note] [\FontAwesomeSymbol{f249}] +% \definesymbol [sticky-note-o] [\FontAwesomeSymbol{f24a}] +% \definesymbol [stop] [\FontAwesomeSymbol{f04d}] +% \definesymbol [stop-circle] [\FontAwesomeSymbol{f28d}] +% \definesymbol [stop-circle-o] [\FontAwesomeSymbol{f28e}] +% \definesymbol [street-view] [\FontAwesomeSymbol{f21d}] +% \definesymbol [strikethrough] [\FontAwesomeSymbol{f0cc}] +% \definesymbol [stumbleupon] [\FontAwesomeSymbol{f1a4}] +% \definesymbol [stumbleupon-circle] [\FontAwesomeSymbol{f1a3}] +% \definesymbol [subscript] [\FontAwesomeSymbol{f12c}] +% \definesymbol [subway] [\FontAwesomeSymbol{f239}] +% \definesymbol [suitcase] [\FontAwesomeSymbol{f0f2}] +% \definesymbol [sun-o] [\FontAwesomeSymbol{f185}] +% \definesymbol [superscript] [\FontAwesomeSymbol{f12b}] +% \definesymbol [support] [\FontAwesomeSymbol{f1cd}] +% \definesymbol [table] [\FontAwesomeSymbol{f0ce}] +% \definesymbol [tablet] [\FontAwesomeSymbol{f10a}] +% \definesymbol [tachometer] [\FontAwesomeSymbol{f0e4}] +% \definesymbol [tag] [\FontAwesomeSymbol{f02b}] +% \definesymbol [tags] [\FontAwesomeSymbol{f02c}] +% \definesymbol [tasks] [\FontAwesomeSymbol{f0ae}] +% \definesymbol [taxi] [\FontAwesomeSymbol{f1ba}] +% \definesymbol [television] [\FontAwesomeSymbol{f26c}] +% \definesymbol [tencent-weibo] [\FontAwesomeSymbol{f1d5}] +% \definesymbol [terminal] [\FontAwesomeSymbol{f120}] +% \definesymbol [text-height] [\FontAwesomeSymbol{f034}] +% \definesymbol [text-width] [\FontAwesomeSymbol{f035}] +% \definesymbol [th] [\FontAwesomeSymbol{f00a}] +% \definesymbol [th-large] [\FontAwesomeSymbol{f009}] +% \definesymbol [th-list] [\FontAwesomeSymbol{f00b}] +% \definesymbol [themeisle] [\FontAwesomeSymbol{f2b2}] +% \definesymbol [thumb-tack] [\FontAwesomeSymbol{f08d}] +% \definesymbol [thumbs-down] [\FontAwesomeSymbol{f165}] +% \definesymbol [thumbs-o-down] [\FontAwesomeSymbol{f088}] +% \definesymbol [thumbs-o-up] [\FontAwesomeSymbol{f087}] +% \definesymbol [thumbs-up] [\FontAwesomeSymbol{f164}] +% \definesymbol [ticket] [\FontAwesomeSymbol{f145}] +% \definesymbol [times] [\FontAwesomeSymbol{f00d}] +% \definesymbol [times-circle] [\FontAwesomeSymbol{f057}] +% \definesymbol [times-circle-o] [\FontAwesomeSymbol{f05c}] +% \definesymbol [tint] [\FontAwesomeSymbol{f043}] +% \definesymbol [toggle-down] [\FontAwesomeSymbol{f150}] +% \definesymbol [toggle-left] [\FontAwesomeSymbol{f191}] +% \definesymbol [toggle-off] [\FontAwesomeSymbol{f204}] +% \definesymbol [toggle-on] [\FontAwesomeSymbol{f205}] +% \definesymbol [toggle-right] [\FontAwesomeSymbol{f152}] +% \definesymbol [toggle-up] [\FontAwesomeSymbol{f151}] +% \definesymbol [trademark] [\FontAwesomeSymbol{f25c}] +% \definesymbol [train] [\FontAwesomeSymbol{f238}] +% \definesymbol [transgender] [\FontAwesomeSymbol{f224}] +% \definesymbol [transgender-alt] [\FontAwesomeSymbol{f225}] +% \definesymbol [trash] [\FontAwesomeSymbol{f1f8}] +% \definesymbol [trash-o] [\FontAwesomeSymbol{f014}] +% \definesymbol [tree] [\FontAwesomeSymbol{f1bb}] +% \definesymbol [trello] [\FontAwesomeSymbol{f181}] +% \definesymbol [tripadvisor] [\FontAwesomeSymbol{f262}] +% \definesymbol [trophy] [\FontAwesomeSymbol{f091}] +% \definesymbol [truck] [\FontAwesomeSymbol{f0d1}] +% \definesymbol [try] [\FontAwesomeSymbol{f195}] +% \definesymbol [tty] [\FontAwesomeSymbol{f1e4}] +% \definesymbol [tumblr] [\FontAwesomeSymbol{f173}] +% \definesymbol [tumblr-square] [\FontAwesomeSymbol{f174}] +% \definesymbol [turkish-lira] [\FontAwesomeSymbol{f195}] +% \definesymbol [tv] [\FontAwesomeSymbol{f26c}] +% \definesymbol [twitch] [\FontAwesomeSymbol{f1e8}] +% \definesymbol [twitter] [\FontAwesomeSymbol{f099}] +% \definesymbol [twitter-square] [\FontAwesomeSymbol{f081}] +% \definesymbol [umbrella] [\FontAwesomeSymbol{f0e9}] +% \definesymbol [underline] [\FontAwesomeSymbol{f0cd}] +% \definesymbol [undo] [\FontAwesomeSymbol{f0e2}] +% \definesymbol [universal-access] [\FontAwesomeSymbol{f29a}] +% \definesymbol [university] [\FontAwesomeSymbol{f19c}] +% \definesymbol [unlink] [\FontAwesomeSymbol{f127}] +% \definesymbol [unlock] [\FontAwesomeSymbol{f09c}] +% \definesymbol [unlock-alt] [\FontAwesomeSymbol{f13e}] +% \definesymbol [unsorted] [\FontAwesomeSymbol{f0dc}] +% \definesymbol [upload] [\FontAwesomeSymbol{f093}] +% \definesymbol [usb] [\FontAwesomeSymbol{f287}] +% \definesymbol [usd] [\FontAwesomeSymbol{f155}] +% \definesymbol [user] [\FontAwesomeSymbol{f007}] +% \definesymbol [user-md] [\FontAwesomeSymbol{f0f0}] +% \definesymbol [user-plus] [\FontAwesomeSymbol{f234}] +% \definesymbol [user-secret] [\FontAwesomeSymbol{f21b}] +% \definesymbol [user-times] [\FontAwesomeSymbol{f235}] +% \definesymbol [users] [\FontAwesomeSymbol{f0c0}] +% \definesymbol [venus] [\FontAwesomeSymbol{f221}] +% \definesymbol [venus-double] [\FontAwesomeSymbol{f226}] +% \definesymbol [venus-mars] [\FontAwesomeSymbol{f228}] +% \definesymbol [viacoin] [\FontAwesomeSymbol{f237}] +% \definesymbol [viadeo] [\FontAwesomeSymbol{f2a9}] +% \definesymbol [viadeo-square] [\FontAwesomeSymbol{f2aa}] +% \definesymbol [video-camera] [\FontAwesomeSymbol{f03d}] +% \definesymbol [vimeo] [\FontAwesomeSymbol{f27d}] +% \definesymbol [vimeo-square] [\FontAwesomeSymbol{f194}] +% \definesymbol [vine] [\FontAwesomeSymbol{f1ca}] +% \definesymbol [vk] [\FontAwesomeSymbol{f189}] +% \definesymbol [volume-control-phone] [\FontAwesomeSymbol{f2a0}] +% \definesymbol [volume-down] [\FontAwesomeSymbol{f027}] +% \definesymbol [volume-off] [\FontAwesomeSymbol{f026}] +% \definesymbol [volume-up] [\FontAwesomeSymbol{f028}] +% \definesymbol [warning] [\FontAwesomeSymbol{f071}] +% \definesymbol [wechat] [\FontAwesomeSymbol{f1d7}] +% \definesymbol [weibo] [\FontAwesomeSymbol{f18a}] +% \definesymbol [weixin] [\FontAwesomeSymbol{f1d7}] +% \definesymbol [whatsapp] [\FontAwesomeSymbol{f232}] +% \definesymbol [wheelchair] [\FontAwesomeSymbol{f193}] +% \definesymbol [wheelchair-alt] [\FontAwesomeSymbol{f29b}] +% \definesymbol [wifi] [\FontAwesomeSymbol{f1eb}] +% \definesymbol [wikipedia-w] [\FontAwesomeSymbol{f266}] +% \definesymbol [windows] [\FontAwesomeSymbol{f17a}] +% \definesymbol [won] [\FontAwesomeSymbol{f159}] +% \definesymbol [wordpress] [\FontAwesomeSymbol{f19a}] +% \definesymbol [wpbeginner] [\FontAwesomeSymbol{f297}] +% \definesymbol [wpforms] [\FontAwesomeSymbol{f298}] +% \definesymbol [wrench] [\FontAwesomeSymbol{f0ad}] +% \definesymbol [xing] [\FontAwesomeSymbol{f168}] +% \definesymbol [xing-square] [\FontAwesomeSymbol{f169}] +% \definesymbol [y-combinator] [\FontAwesomeSymbol{f23b}] +% \definesymbol [y-combinator-square] [\FontAwesomeSymbol{f1d4}] +% \definesymbol [yahoo] [\FontAwesomeSymbol{f19e}] +% \definesymbol [yc] [\FontAwesomeSymbol{f23b}] +% \definesymbol [yc-square] [\FontAwesomeSymbol{f1d4}] +% \definesymbol [yelp] [\FontAwesomeSymbol{f1e9}] +% \definesymbol [yen] [\FontAwesomeSymbol{f157}] +% \definesymbol [yoast] [\FontAwesomeSymbol{f2b1}] +% \definesymbol [youtube] [\FontAwesomeSymbol{f167}] +% \definesymbol [youtube-play] [\FontAwesomeSymbol{f16a}] +% \definesymbol [youtube-square] [\FontAwesomeSymbol{f166}] + +\stopsymbolset + +\definefontsynonym [FontAwesomeBrands] [file:fontawesome5brandsregular400.otf] +\definefontsynonym [FontAwesomeRegular] [file:fontawesome5freeregular400.otf] +\definefontsynonym [FontAwesomeSolid] [file:fontawesome5freesolid900.otf] + +\startsymbolset [fontawesome-brands] [font=FontAwesomeBrands] + % Font Awesome Brands +\stopsymbolset + +\startsymbolset [fontawesome-regular] [font=FontAwesomeRegular] + % Font Awesome Regular +\stopsymbolset + +\startsymbolset [fontawesome-solid] [font=FontAwesomeSolid] + % Font Awesome Solid \stopsymbolset \continueifinputfile{symb-imp-fontawesome.mkiv} -% \usesymbols[fontawesome] +\usemodule[article-basic] \starttext - \showsymbolset[fontawesome] + % \usesymbols[fontawesome] + % + % \symbol[fontawesome][wheelchair] + % \symbol[fontawesome][angle-right] + % \symbol[fontawesome][angle right] + % \symbol[fontawesome][angle_right] + + % \showsymbolset[fontawesome] + + \startnamedsection [title] [title={Font Awesome Brands}] + \showsymbolset [fontawesome-brands] + \stopnamedsection + + \startnamedsection [title] [title={Font Awesome Regular}] + \showsymbolset [fontawesome-regular] + \stopnamedsection + + \startnamedsection [title] [title={Font Awesome Solid}] + \showsymbolset [fontawesome-solid] + \stopnamedsection \stoptext diff --git a/tex/context/base/mkiv/symb-imp-mis.mkiv b/tex/context/base/mkiv/symb-imp-mis.mkiv index d2657512f..2320ea59a 100644 --- a/tex/context/base/mkiv/symb-imp-mis.mkiv +++ b/tex/context/base/mkiv/symb-imp-mis.mkiv @@ -21,34 +21,36 @@ \definesymbol [\v!none] [] -\definesymbol [bullet] [\textmath\bullet] -\definesymbol [dash] [\textmath-] -\definesymbol [star] [\textmath\star] -\definesymbol [triangle] [\textmath\triangleright] -\definesymbol [circle] [\textmath\circ] -\definesymbol [square] [\textmath\square] -\definesymbol [diamond] [\textmath\diamond] +% \definesymbol [bullet] [\textmath\bullet] +% \definesymbol [dash] [\textmath-] +% \definesymbol [star] [\textmath\star] +% \definesymbol [triangle] [\textmath\triangleright] +% \definesymbol [circle] [\textmath\circ] +% \definesymbol [square] [\textmath\square] +% \definesymbol [diamond] [\textmath\diamond] +% \definesymbol [asterisk] [\textmath\ast] % I'm not sure about this ... I dislike the small bullet. So we provide % it as variant: \type {\setupsymbolset[text]}. Also, we want to be % backward compatible. -\startsymbolset[text] +% \startsymbolset[text] \definesymbol [bullet] [\textormathchar{"2022}] % • \bullet \definesymbol [dash] [\textormathchar{"2013}] % – - \definesymbol [star] [\textormathchar{"22C6}] % ✴ \star + \definesymbol [star] [\textormathchar{"22C6}] % ⋆ \star \definesymbol [triangle] [\textormathchar{"22B3}] % ⊳ \triangleright \definesymbol [circle] [\textormathchar{"2218}] % ∘ \circ \definesymbol [square] [\textormathchar{"25A1}] % □ \square \definesymbol [diamond] [\textormathchar{"22C4}] % ⋄ \diamond \definesymbol [checkmark] [\textormathchar{"2713}] % ✓ \checkmark + \definesymbol [asterisk] [\textormathchar{"2217}] % ∗ \asterisk \definesymbol [blacktriangle] [\textormathchar{"25B6}] % ▶ \definesymbol [blacksquare] [\textormathchar{"25A0}] % ■ \definesymbol [blackdiamond] [\textormathchar{"25C6}] % ◆ -\stopsymbolset +% \stopsymbolset \definesymbol [smallcircle] [\hbox{\raise.1ex\hbox{\textmath{\scriptscriptstyle\bigcirc}}}] \definesymbol [medcircle] [\hbox{\raise.1ex\hbox{\textmath{\scriptstyle \bigcirc}}}] @@ -62,6 +64,7 @@ \definesymbol [6] [\symbol{medcircle}] \definesymbol [7] [\symbol{bigcircle}] \definesymbol [8] [\symbol{square}] +\definesymbol [9] [\symbol{checkmark}] \definesymbol [S] [\sectionmark] \definesymbol [P] [\paragraphmark] diff --git a/tex/context/base/mkiv/symb-imp-mvs.mkiv b/tex/context/base/mkiv/symb-imp-mvs.mkiv index 9902fc9e8..f6a38214f 100644 --- a/tex/context/base/mkiv/symb-imp-mvs.mkiv +++ b/tex/context/base/mkiv/symb-imp-mvs.mkiv @@ -254,10 +254,16 @@ \stopsymbolset -%D \showsymbolset[astronomic] -%D \showsymbolset[zodiac] -%D \showsymbolset[europe] -%D \showsymbolset[martinvogel 1] -%D \showsymbolset[martinvogel 2] +\continueifinputfile{symb-imp-mvs.mkiv} -\endinput +\usemodule[article-basic] + +\starttext + +\startsubject[title={Astronomic}] \showsymbolset[astronomic] \stopsubject +\startsubject[title={Zodiac}] \showsymbolset[zodiac] \stopsubject +\startsubject[title={Europe}] \showsymbolset[europe] \stopsubject +\startsubject[title={Martinvogel 1}] \showsymbolset[martinvogel 1] \stopsubject +\startsubject[title={Martinvogel 2}] \showsymbolset[martinvogel 2] \stopsubject + +\stoptext diff --git a/tex/context/base/mkiv/symb-ini.mkiv b/tex/context/base/mkiv/symb-ini.mkiv index e4950e09d..abf857675 100644 --- a/tex/context/base/mkiv/symb-ini.mkiv +++ b/tex/context/base/mkiv/symb-ini.mkiv @@ -45,6 +45,7 @@ \installcorenamespace{symbol} \installcorenamespace{symbolset} +\installcorenamespace{symboldefault} \let\currentsymbol \empty \let\currentsymbolset\empty @@ -95,8 +96,9 @@ % Test test \symbol[whatever]\ test \symbol[whatever]. % Test test \symbol{whatever} test \symbol{whatever}. -\unexpanded\def\symbol % This one always gobbles spaces, - {\dodoubleempty\symb_place} % so never change it again! +\unexpanded\def\symbol + {\dontleavehmode % so we can start a paragraph with it + \dodoubleempty\symb_place} \def\symb_place % so we also handle \symbol{name} {\iffirstargument % which is nicer with following spaces @@ -112,13 +114,23 @@ \expandafter\symb_place_normal_b \fi} +% \def\symb_place_normal_a[#1][#2]% +% {\edef\currentsymbol{#2}% +% \ifcsname\??symbol#1:#2\endcsname +% \symb_place_indeed{#1:#2}% +% \else +% \symb_place_normal_c +% \fi} + \def\symb_place_normal_a[#1][#2]% {\edef\currentsymbol{#2}% \ifcsname\??symbol#1:#2\endcsname - \symb_place_indeed{#1:#2}% + \symb_place_indeed{#1:#2}% maybe use \lastnamescs + \else\ifcsname\??symboldefault#1\endcsname + \symb_place_named{#1}% maybe use \lastnamescs \else \symb_place_normal_c - \fi} + \fi\fi} \def\symb_place_normal_b[#1][#2]% {\edef\currentsymbol{#1}% @@ -160,11 +172,47 @@ \expandafter\symb_fetch_indeed \fi} +% \def\symb_fetch_indeed#1% +% {\ifcsname\??symbol#1:\currentsymbol\endcsname +% \symb_place_indeed{#1:\currentsymbol}% +% \fi} + \def\symb_fetch_indeed#1% {\ifcsname\??symbol#1:\currentsymbol\endcsname \symb_place_indeed{#1:\currentsymbol}% + \else\ifcsname\??symboldefault#1\endcsname + \symb_place_named{#1}% + \fi\fi} + +\def\symb_place_named#1% \relax's prevent lookahead problems + {\begingroup + \setbox\scratchbox\hbox\bgroup + \the\everysymbol + \getglyphstyled + {\csname\??symboldefault#1\endcsname}% + {\tochar{n:\currentsymbol}}% + \relax + \egroup + \ifdim\wd\scratchbox>\zeropoint + \unhbox\scratchbox + \endgroup + \setxvalue{\??symbol#1:\currentsymbol}% + {\symb_place_named_indeed{#1}{\currentsymbol}}% + \settrue\c_symb_found + \else + \endgroup \fi} +\unexpanded\def\symb_place_named_indeed#1#2% \relax's prevent lookahead problems + {\settrue\c_symb_found + \begingroup + \the\everysymbol + \getglyphstyled + {\csname\??symboldefault#1\endcsname}% + {\tochar{n:#2}}% + \relax + \endgroup} + \def\symb_place_retry#1% {\ifcsname\??symbol:#1\endcsname \symb_place_indeed{:#1}% @@ -273,9 +321,25 @@ \installcorenamespace{symbolsets} -\unexpanded\def\startsymbolset[#1]% +% \unexpanded\def\startsymbolset[#1]% +% {\pushmacro\m_symb_current_set +% \def\m_symb_current_set{#1}} + +% maybe a parameterhandler: + +\unexpanded\def\startsymbolset + {\dodoubleargument\symb_start_set} + +\def\symb_start_set[#1][#2]% {\pushmacro\m_symb_current_set - \def\m_symb_current_set{#1}} + \def\m_symb_current_set{#1}% + \ifsecondargument + \getdummyparameters[\s!font=,#2]% + \edef\p_font{\dummyparameter\s!font}% + \ifx\p_font\empty\else + \letvalue{\??symboldefault#1}\p_font + \fi + \fi} \unexpanded\def\stopsymbolset {\popmacro\m_symb_current_set} diff --git a/tex/context/base/mkiv/symb-run.mkiv b/tex/context/base/mkiv/symb-run.mkiv index ed4d90861..c25d13d48 100644 --- a/tex/context/base/mkiv/symb-run.mkiv +++ b/tex/context/base/mkiv/symb-run.mkiv @@ -12,23 +12,55 @@ %C details. \startluacode - function commands.showsymbolset(collection,symbols) + function commands.showsymbolset(collection,symbols,fontid) if type(symbols) == "string" then symbols = utilities.parsers.settings_to_array(symbols) end + local options = { framecolor = "orange", rulethickness = ".8pt", offset = interfaces.variables.overlay } + local list = table.tohash(symbols) + local alsofont = fontid > 0 + local defined = #symbols > 0 + local byname = false + if alsofont then + local is_symbol = characters.is_symbol + local chardata = characters.data + local resources = fonts.hashes.resources [fontid] + local characters = fonts.hashes.characters[fontid] + if resources and characters then + local unicodes = resources.unicodes + if unicodes then + for name, unicode in next, unicodes do + if not list[name] and name ~= ".notdef" then + local c = rawget(chardata,unicode) + if not c or is_symbol[c.category] then + list[name] = false + byname = true + end + end + end + end + end + end + local detail = defined and byname context.start() context.forcesymbolset { collection } - context.starttabulate { "|lT|l|l|" } - local options = { framecolor = "orange", rulethickness = ".8pt", offset = interfaces.variables.overlay } - for i=1,#symbols do - local symbol = symbols[i] + context.starttabulate { detail and "|lT|l|l|lT|" or "|lT|l|l|"} + for symbol, how in table.sortedhash(list) do context.NC() - context(symbol) + if detail and how then + context.bold(symbol) + else + context(symbol) + end context.NC() context.symbol(symbol) context.NC() context.framed(options,context.nested.symbol(symbol)) context.NC() + if detail and how then + context.bold("defined") + context.NC() + end context.NR() end context.stoptabulate() @@ -42,7 +74,23 @@ {\dosingleargument\symb_show_set} \gdef\symb_show_set[#1]% - {\ctxcommand{showsymbolset("#1","\symbolset{#1}")}} + {\begingroup + \edef\p_font{\begincsname\??symboldefault#1\endcsname}% + \begingroup + \ifx\p_font\empty + \global\globalscratchcounter\zerocount + \else + \definedfont[\p_font]% + \global\globalscratchcounter\fontid\font\relax + \fi + \endgroup + \ctxcommand { + showsymbolset ( + "#1", + "\symbolset{#1}", + \the\globalscratchcounter + ) }% + \endgroup} \protect diff --git a/tex/context/base/mkiv/syst-aux.lua b/tex/context/base/mkiv/syst-aux.lua index f9d8505f1..9b0ca82c4 100644 --- a/tex/context/base/mkiv/syst-aux.lua +++ b/tex/context/base/mkiv/syst-aux.lua @@ -323,9 +323,47 @@ end implement { name = "texdefinition_one", actions = texdefinition_one, scope = "private", arguments = "string" } implement { name = "texdefinition_two", actions = texdefinition_two, scope = "private" } -implement { name = "upper", arguments = "string", actions = { utf.upper, context } } -implement { name = "lower", arguments = "string", actions = { utf.lower, context } } -implement { name = "strip", arguments = "string", actions = { string.strip, context } } -- or utf.strip +do + + -- Quite probably we don't yet have characters loaded so we delay some + -- aliases. + + local _lower_, _upper_, _strip_ + + _lower_ = function(s) + if characters and characters.lower then + _lower_ = characters.lower + return _lower_(s) + end + return string.lower(s) + end + + _upper_ = function(s) + if characters and characters.upper then + _upper_ = characters.upper + return _upper_(s) + end + return string.upper(s) + end + + _strip_ = function(s) + -- or utf.strip + if string.strip then + _strip_ = string.strip + return _strip_(s) + end + return s + end + + local function lower(s) context(_lower_(s)) end + local function upper(s) context(_upper_(s)) end + local function strip(s) context(_strip_(s)) end + + implement { name = "upper", arguments = "string", actions = upper } + implement { name = "lower", arguments = "string", actions = lower } + implement { name = "strip", arguments = "string", actions = strip } + +end implement { name = "converteddimen", @@ -373,10 +411,17 @@ implement { -- not faster but just less tracing: -local firstoftwoarguments = context.firstoftwoarguments -local secondoftwoarguments = context.secondoftwoarguments -local firstofoneargument = context.firstofoneargument -local gobbleoneargument = context.gobbleoneargument +local ctx_protected_cs = context.protected.cs -- more efficient + +local ctx_firstoftwoarguments = ctx_protected_cs.firstoftwoarguments +local ctx_secondoftwoarguments = ctx_protected_cs.secondoftwoarguments +local ctx_firstofoneargument = ctx_protected_cs.firstofoneargument +local ctx_gobbleoneargument = ctx_protected_cs.gobbleoneargument + +context.firstoftwoarguments = ctx_firstoftwoarguments +context.secondoftwoarguments = ctx_secondoftwoarguments +context.firstofoneargument = ctx_firstofoneargument +context.gobbleoneargument = ctx_gobbleoneargument local hash = utilities.parsers.hashes.settings_to_set @@ -384,9 +429,9 @@ local function doifelsecommon(a,b) if a == b then setmacro("commalistelement",a) if a == "" then - secondoftwoarguments() + ctx_secondoftwoarguments() else - firstoftwoarguments() + ctx_firstoftwoarguments() end return end @@ -400,7 +445,7 @@ local function doifelsecommon(a,b) for k in next, ha do if hb[k] then setmacro("commalistelement",k) - firstoftwoarguments() + ctx_firstoftwoarguments() return end end @@ -408,28 +453,28 @@ local function doifelsecommon(a,b) if hash[a][b] then -- if settings_to_set(a)[b] then setmacro("commalistelement",b) - firstoftwoarguments() + ctx_firstoftwoarguments() return end elseif bb then if hash[b][a] then -- if settings_to_set(b)[a] then setmacro("commalistelement",a) - firstoftwoarguments() + ctx_firstoftwoarguments() return end end setmacro("commalistelement","") - secondoftwoarguments() + ctx_secondoftwoarguments() end local function doifcommon(a,b) if a == b then setmacro("commalistelement",a) if a == "" then - gobbleoneargument() + ctx_gobbleoneargument() else - firstofoneargument() + ctx_firstofoneargument() end return end @@ -443,7 +488,7 @@ local function doifcommon(a,b) for k in next, ha do if hb[k] then setmacro("commalistelement",k) - firstofoneargument() + ctx_firstofoneargument() return end end @@ -451,28 +496,28 @@ local function doifcommon(a,b) if hash[a][b] then -- if settings_to_set(a)[b] then setmacro("commalistelement",b) - firstofoneargument() + ctx_firstofoneargument() return end elseif bb then if hash[b][a] then -- if settings_to_set(b)[a] then setmacro("commalistelement",a) - firstofoneargument() + ctx_firstofoneargument() return end end setmacro("commalistelement","") - gobbleoneargument() + ctx_gobbleoneargument() end local function doifnotcommon(a,b) if a == b then setmacro("commalistelement",a) if a == "" then - firstofoneargument() + ctx_firstofoneargument() else - gobbleoneargument() + ctx_gobbleoneargument() end return end @@ -486,7 +531,7 @@ local function doifnotcommon(a,b) for k in next, ha do if hb[k] then setmacro("commalistelement",k) - gobbleoneargument() + ctx_gobbleoneargument() return end end @@ -494,28 +539,28 @@ local function doifnotcommon(a,b) if hash[a][b] then -- if settings_to_set(a)[b] then setmacro("commalistelement",b) - gobbleoneargument() + ctx_gobbleoneargument() return end elseif bb then if hash[b][a] then -- if settings_to_set(b)[a] then setmacro("commalistelement",a) - gobbleoneargument() + ctx_gobbleoneargument() return end end setmacro("commalistelement","") - firstofoneargument() + ctx_firstofoneargument() end local function doifelseinset(a,b) if a == b then setmacro("commalistelement",a) if a == "" then - secondoftwoarguments() + ctx_secondoftwoarguments() else - firstoftwoarguments() + ctx_firstoftwoarguments() end return end @@ -524,21 +569,21 @@ local function doifelseinset(a,b) if hash[b][a] then -- if settings_to_set(b)[a] then setmacro("commalistelement",a) - firstoftwoarguments() + ctx_firstoftwoarguments() return end end setmacro("commalistelement","") - secondoftwoarguments() + ctx_secondoftwoarguments() end local function doifinset(a,b) if a == b then setmacro("commalistelement",a) if a == "" then - gobbleoneargument() + ctx_gobbleoneargument() else - firstofoneargument() + ctx_firstofoneargument() end return end @@ -547,21 +592,21 @@ local function doifinset(a,b) if hash[b][a] then -- if settings_to_set(b)[a] then setmacro("commalistelement",a) - firstofoneargument() + ctx_firstofoneargument() return end end setmacro("commalistelement","") - gobbleoneargument() + ctx_gobbleoneargument() end local function doifnotinset(a,b) if a == b then setmacro("commalistelement",a) if a == "" then - firstofoneargument() + ctx_firstofoneargument() else - gobbleoneargument() + ctx_gobbleoneargument() end return end @@ -570,12 +615,12 @@ local function doifnotinset(a,b) if hash[b][a] then -- if settings_to_set(b)[a] then setmacro("commalistelement",a) - gobbleoneargument() + ctx_gobbleoneargument() return end end setmacro("commalistelement","") - firstofoneargument() + ctx_firstofoneargument() end implement { @@ -614,6 +659,20 @@ implement { arguments = "2 strings", } +-- done elsewhere: +-- +-- local function firstinset(a) +-- local aa = hash[a] +-- context(aa and aa[1] or a) +-- end +-- +-- implement { +-- name = "firstinset", +-- actions = firstinset, +-- arguments = "string", +-- private = false, +-- } + -- implement { -- name = "stringcompare", -- arguments = "2 strings", diff --git a/tex/context/base/mkiv/syst-aux.mkiv b/tex/context/base/mkiv/syst-aux.mkiv index 77f947753..3004c08b8 100644 --- a/tex/context/base/mkiv/syst-aux.mkiv +++ b/tex/context/base/mkiv/syst-aux.mkiv @@ -181,12 +181,9 @@ %D These are not needed any more now that we have wide screens (and bytes come %D cheap). -\let\@EA \singleexpandafter -\let\@EAEAEA \doubleexpandafter -\let\@EAEAEAEAEAEA\tripleexpandafter - -\let\@NX \noexpand -\def\@EAEA {\expandafter\expandafter} % can often be avoided +\let\@EA \singleexpandafter % obsolete +\let\@EAEAEA \doubleexpandafter % obsolete +\let\@EAEAEAEAEAEA\tripleexpandafter % obsolete %D Sometimes we pass macros as arguments to commands that don't expand them %D before interpretation. Such commands can be enclosed with \type {\expanded}, @@ -345,6 +342,18 @@ \let\doifnextoptionalelse \doifelsenextoptional \let\doifnextoptionalcselse\doifelsenextoptionalcs +% fails on assignments +% +% \unexpanded\def\doifelsenextoptional {\afterassignment\doifelsenextoptional_n \def\m_syst_action_yes} +% \def\doifelsenextoptional_n {\afterassignment\doifelsenextoptional_n_n\def\m_syst_action_nop} +% \def\doifelsenextoptional_n_n {\let\if_next_blank_space_token\iffalse +% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} +% +% \unexpanded\def\doifelsenextoptionalcs {\afterassignment\doifelsenextoptionalcs_n \let\m_syst_action_yes} +% \def\doifelsenextoptionalcs_n {\afterassignment\doifelsenextoptionalcs_n_n\let\m_syst_action_nop} +% \def\doifelsenextoptionalcs_n_n{\let\if_next_blank_space_token\iffalse +% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} + \def\syst_helpers_inspect_next_optional_character {\ifx\nexttoken\blankspace \expandafter\syst_helpers_reinspect_next_optional_character @@ -491,8 +500,6 @@ %D \type {\def} comes into action. This way the space after \type {\:} becomes a %D delimiter of the longer named \type {\reinspectnextcharacter}. -% try: \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_character} {...} - \let\next\: \def\:{\let\blankspace= } \: @@ -514,6 +521,31 @@ \let\:\next +%D This is much nicer and works too: + +% \def\firstofoneargument#1{#1} +% +% \expandafter\let\firstofoneargument{\blankspace= } +% +% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_character +% } {\let\if_next_blank_space_token\iftrue +% \futurelet\nexttoken\syst_helpers_inspect_next_character} +% +% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_optional_character +% } {\let\if_next_blank_space_token\iftrue +% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} +% +% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_bgroup_character +% } {\let\if_next_blank_space_token\iftrue +% \futurelet\nexttoken\syst_helpers_inspect_next_bgroup_character} +% +% \expandafter\def\firstofoneargument{\syst_helpers_reinspect_next_parenthesis_character +% } {\let\if_next_blank_space_token\iftrue +% \futurelet\nexttoken\syst_helpers_inspect_next_parenthesis_character} +% +% \expandafter\def\firstofoneargument{\syst_helpers_ignore_spacing_blankspace +% } {\futurelet\nexttoken\syst_helpers_ignore_spacing} + %D \macros %D {setvalue,setgvalue,setevalue,setxvalue, %D letvalue,letgvalue,getvalue,resetvalue, @@ -529,7 +561,7 @@ %D \setevalue {name}{...} = \edef\name{...} %D \setxvalue {name}{...} = \xdef\name{...} %D \letvalue {name}=\... = \let\name=\... -%D \letgvalue {name}=\... = \global\let\name=\... +%D \letgvalue {name}=\... = \glet\name=\... %D \getvalue {name} = \name %D \resetvalue {name} = \def\name{} %D \stoptyping @@ -537,16 +569,16 @@ %D As we will see, \CONTEXT\ uses these commands many times, which is mainly due to %D its object oriented and parameter driven character. -\def\setvalue #1{\expandafter \def\csname#1\endcsname} +\def\setvalue #1{\expandafter\def \csname#1\endcsname} \def\setgvalue #1{\expandafter\gdef\csname#1\endcsname} \def\setevalue #1{\expandafter\edef\csname#1\endcsname} \def\setxvalue #1{\expandafter\xdef\csname#1\endcsname} -\def\getvalue #1{\csname#1\endcsname} -\def\letvalue #1{\expandafter\let\csname#1\endcsname} -\def\letgvalue #1{\global\expandafter\let\csname#1\endcsname} -\def\resetvalue #1{\expandafter\let\csname#1\endcsname\empty} -\def\undefinevalue#1{\expandafter\let\csname#1\endcsname\undefined} -\def\ignorevalue#1#2{\expandafter\let\csname#1\endcsname\empty} +\def\getvalue #1{\csname#1\endcsname} % maybe: \begincsname#1\endcsname +\def\letvalue #1{\expandafter\let \csname#1\endcsname} +\def\letgvalue #1{\expandafter\glet\csname#1\endcsname} +\def\resetvalue #1{\expandafter\let \csname#1\endcsname\empty} +\def\undefinevalue#1{\expandafter\let \csname#1\endcsname\undefined} +\def\ignorevalue#1#2{\expandafter\let \csname#1\endcsname\empty} \def\setuvalue #1{\normalprotected\expandafter \def\csname#1\endcsname} \def\setuevalue #1{\normalprotected\expandafter\edef\csname#1\endcsname} @@ -562,7 +594,7 @@ %D tokens will save us some $300\times4=1200$ bytes of format file on a 32~bit %D system. Not that it matters much today. This shortcut is already defined: -\unexpanded\def\glet{\global\let} \let\globallet\glet +\let\globallet\glet %D \macros %D {doifundefined,doifdefined, @@ -635,7 +667,7 @@ {\ifcsname#1\endcsname\expandafter\let\csname#1\endcsname\undefined\fi} \def\globalundefine#1% conditional - {\ifcsname#1\endcsname\expandafter\global\let\csname#1\endcsname\undefined\fi} + {\ifcsname#1\endcsname\expandafter\glet\csname#1\endcsname\undefined\fi} %D Beware, being \type {\undefined} in \ETEX\ means that the macro {\em is} defined! %D @@ -705,6 +737,23 @@ \expandafter\secondoftwoarguments \fi} +%D Slightly faster on longer arguments (0.179 downto 0.141): +%D +%D \testfeatureonce{100000}{\doifelse{aaaaaaaaaaaaaaa}{bbbbbbbbbbbbbbb}\relax\relax} + +% \unexpanded\def\doifelse +% {\afterassignment\doifelse_n\edef\m_syst_string_one} +% +% \unexpanded\def\doifelse_n +% {\afterassignment\doifelse_n_n\edef\m_syst_string_two} +% +% \unexpanded\def\doifelse_n_n +% {\ifx\m_syst_string_one\m_syst_string_two +% \expandafter\firstoftwoarguments +% \else +% \expandafter\secondoftwoarguments +% \fi} + %D \macros %D {doifempty,doifemptyelse,doifnotempty} %D @@ -912,6 +961,7 @@ \unexpanded\def\doifelseinset#1#2{\clf_doifelseinset{#1}{#2}} \unexpanded\def\doifinset #1#2{\clf_doifinset {#1}{#2}} \unexpanded\def\doifnotinset #1#2{\clf_doifnotinset {#1}{#2}} + % \let\firstinset \clf_firstinset \let\doifinsetelse\doifelseinset @@ -1348,7 +1398,7 @@ %D %D Sometimes the action to be undertaken depends on the %D next character. This macro get this character and puts it in -%D \type{\firstcharacter}. +%D \type {\firstcharacter}. %D %D \starttyping %D \getfirstcharacter {string} @@ -2243,202 +2293,517 @@ % \dotripleempty\test[] xxx\par % \dotripleempty\test xxx\par +%D Common: + +\newtoks\t_syst_aux + +% \def\syst_helpers_empty_spaced_six {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][][] } +% \def\syst_helpers_empty_normal_six {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][][]} +% \def\syst_helpers_empty_spaced_five {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][] } +% \def\syst_helpers_empty_normal_five {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][][]} +% \def\syst_helpers_empty_spaced_four {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][] } +% \def\syst_helpers_empty_normal_four {\expandafter\m_syst_aux_do\the\t_syst_aux[][][][]} +% \def\syst_helpers_empty_spaced_three{\expandafter\m_syst_aux_do\the\t_syst_aux[][][] } +% \def\syst_helpers_empty_normal_three{\expandafter\m_syst_aux_do\the\t_syst_aux[][][]} +% \def\syst_helpers_empty_spaced_two {\expandafter\m_syst_aux_do\the\t_syst_aux[][] } +% \def\syst_helpers_empty_normal_two {\expandafter\m_syst_aux_do\the\t_syst_aux[][]} +% \def\syst_helpers_empty_spaced_one {\expandafter\m_syst_aux_do\the\t_syst_aux[] } +% \def\syst_helpers_empty_normal_one {\expandafter\m_syst_aux_do\the\t_syst_aux[]} +% +% \def\syst_helpers_single_empty_one_yes {\firstargumenttrue \m_syst_aux_do} +% \def\syst_helpers_double_empty_two_yes {\secondargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux} +% \def\syst_helpers_triple_empty_three_yes {\thirdargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux} +% \def\syst_helpers_quadruple_empty_four_yes {\fourthargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux} +% \def\syst_helpers_quintuple_empty_five_yes {\fifthargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux} +% \def\syst_helpers_sixtuple_empty_six_yes {\sixthargumenttrue \expandafter\m_syst_aux_do\the\t_syst_aux} +% \def\syst_helpers_seventuple_empty_seven_yes{\seventhargumenttrue\expandafter\m_syst_aux_do\the\t_syst_aux} +% +% with +% +% \unexpanded\def\dodoubleempty#1% +% {\syst_helpers_argument_reset +% \let\m_syst_aux_do#1% alias +% \let\m_syst_action_yes\syst_helpers_double_empty_one_yes +% \let\m_syst_action_nop\syst_helpers_double_empty_one_nop +% \let\if_next_blank_space_token\iffalse +% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} +% +% \def\syst_helpers_double_empty_one_yes[#1]% +% {\firstargumenttrue +% \t_syst_aux{[{#1}]}% assignment +% \let\m_syst_action_yes\syst_helpers_double_empty_two_yes +% \let\m_syst_action_nop\syst_helpers_double_empty_two_nop +% \let\if_next_blank_space_token\iffalse +% \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} +% +% But we use this as it keeps the original name visible: + +\def\syst_helpers_empty_spaced_six {\the\t_syst_aux[][][][][][] } +\def\syst_helpers_empty_normal_six {\the\t_syst_aux[][][][][][]} +\def\syst_helpers_empty_spaced_five {\the\t_syst_aux[][][][][] } +\def\syst_helpers_empty_normal_five {\the\t_syst_aux[][][][][]} +\def\syst_helpers_empty_spaced_four {\the\t_syst_aux[][][][] } +\def\syst_helpers_empty_normal_four {\the\t_syst_aux[][][][]} +\def\syst_helpers_empty_spaced_three{\the\t_syst_aux[][][] } +\def\syst_helpers_empty_normal_three{\the\t_syst_aux[][][]} +\def\syst_helpers_empty_spaced_two {\the\t_syst_aux[][] } +\def\syst_helpers_empty_normal_two {\the\t_syst_aux[][]} +\def\syst_helpers_empty_spaced_one {\the\t_syst_aux[] } +\def\syst_helpers_empty_normal_one {\the\t_syst_aux[]} + +\def\syst_helpers_single_empty_one_yes {\firstargumenttrue \the\t_syst_aux} +\def\syst_helpers_double_empty_two_yes {\secondargumenttrue \the\t_syst_aux} +\def\syst_helpers_triple_empty_three_yes {\thirdargumenttrue \the\t_syst_aux} +\def\syst_helpers_quadruple_empty_four_yes {\fourthargumenttrue \the\t_syst_aux} +\def\syst_helpers_quintuple_empty_five_yes {\fifthargumenttrue \the\t_syst_aux} +\def\syst_helpers_sixtuple_empty_six_yes {\sixthargumenttrue \the\t_syst_aux} +\def\syst_helpers_seventuple_empty_seven_yes{\seventhargumenttrue\the\t_syst_aux} + %D Single: +% \unexpanded\def\dosingleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\firstargumenttrue#1}% +% {\syst_helpers_single_empty_one_nop#1}} +% +% \def\syst_helpers_single_empty_one_nop#1% +% {\firstargumentfalse +% #1[]} + \unexpanded\def\dosingleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\firstargumenttrue#1}% - {\syst_helpers_single_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_single_empty_one_yes + \let\m_syst_action_nop\syst_helpers_single_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_single_empty_one_nop#1% +\def\syst_helpers_single_empty_one_nop {\firstargumentfalse - #1[]} + \the\t_syst_aux[]} %D Double +% \unexpanded\def\dodoubleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_double_empty_one_yes#1}% +% {\syst_helpers_double_empty_one_nop#1}} +% +% \def\syst_helpers_double_empty_one_yes#1[#2]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\secondargumenttrue#1[{#2}]}% +% {\syst_helpers_double_empty_two_nop#1{#2}}} +% +% \def\syst_helpers_double_empty_one_nop#1% +% {\firstargumentfalse +% \secondargumentfalse +% #1[][]} +% +% \def\syst_helpers_double_empty_two_nop +% {\secondargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_double_empty_one_spaced +% \else +% \expandafter\syst_helpers_double_empty_one_normal +% \fi} +% +% \def\syst_helpers_double_empty_one_spaced#1#2{#1[{#2}][] } +% \def\syst_helpers_double_empty_one_normal#1#2{#1[{#2}][]} + \unexpanded\def\dodoubleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_double_empty_one_yes#1}% - {\syst_helpers_double_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_double_empty_one_yes + \let\m_syst_action_nop\syst_helpers_double_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_double_empty_one_yes#1[#2]% +\def\syst_helpers_double_empty_one_yes[#1]% {\firstargumenttrue - \doifelsenextoptional - {\secondargumenttrue#1[{#2}]}% - {\syst_helpers_double_empty_two_nop#1{#2}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_double_empty_two_yes + \let\m_syst_action_nop\syst_helpers_double_empty_two_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_double_empty_one_nop#1% +\def\syst_helpers_double_empty_one_nop {\firstargumentfalse \secondargumentfalse - #1[][]} + \the\t_syst_aux[][]} \def\syst_helpers_double_empty_two_nop {\secondargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_double_empty_one_spaced + \expandafter\syst_helpers_empty_spaced_one \else - \expandafter\syst_helpers_double_empty_one_normal + \expandafter\syst_helpers_empty_normal_one \fi} -\def\syst_helpers_double_empty_one_spaced#1#2{#1[{#2}][] } -\def\syst_helpers_double_empty_one_normal#1#2{#1[{#2}][]} +% Triple -% Three +% \unexpanded\def\dotripleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_triple_empty_one_yes#1}% +% {\syst_helpers_triple_empty_one_nop#1}} +% +% \def\syst_helpers_triple_empty_one_yes#1[#2]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\syst_helpers_triple_empty_two_yes#1{#2}}% +% {\syst_helpers_triple_empty_two_nop#1{#2}}} +% +% \def\syst_helpers_triple_empty_two_yes#1#2[#3]% +% {\secondargumenttrue +% \doifelsenextoptional +% {\thirdargumenttrue#1[{#2}][{#3}]}% +% {\syst_helpers_triple_empty_three_nop#1{#2}{#3}}} +% +% \def\syst_helpers_triple_empty_one_nop#1% +% {\firstargumentfalse +% \secondargumentfalse +% \thirdargumentfalse +% #1[][][]} +% +% \def\syst_helpers_triple_empty_two_nop +% {\secondargumentfalse +% \thirdargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_triple_empty_two_spaced +% \else +% \expandafter\syst_helpers_triple_empty_two_normal +% \fi} +% +% \def\syst_helpers_triple_empty_three_nop +% {\thirdargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_triple_empty_three_spaced +% \else +% \expandafter\syst_helpers_triple_empty_three_normal +% \fi} +% +% \def\syst_helpers_triple_empty_two_spaced #1#2{#1[{#2}][][] } +% \def\syst_helpers_triple_empty_two_normal #1#2{#1[{#2}][][]} +% \def\syst_helpers_triple_empty_three_spaced#1#2#3{#1[{#2}][{#3}][] } +% \def\syst_helpers_triple_empty_three_normal#1#2#3{#1[{#2}][{#3}][]} \unexpanded\def\dotripleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_triple_empty_one_yes#1}% - {\syst_helpers_triple_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_triple_empty_one_yes + \let\m_syst_action_nop\syst_helpers_triple_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_triple_empty_one_yes#1[#2]% +\def\syst_helpers_triple_empty_one_yes[#1]% {\firstargumenttrue - \doifelsenextoptional - {\syst_helpers_triple_empty_two_yes#1{#2}}% - {\syst_helpers_triple_empty_two_nop#1{#2}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_triple_empty_two_yes + \let\m_syst_action_nop\syst_helpers_triple_empty_two_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_triple_empty_two_yes#1#2[#3]% +\def\syst_helpers_triple_empty_two_yes[#1]% {\secondargumenttrue - \doifelsenextoptional - {\thirdargumenttrue#1[{#2}][{#3}]}% - {\syst_helpers_triple_empty_three_nop#1{#2}{#3}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_triple_empty_three_yes + \let\m_syst_action_nop\syst_helpers_triple_empty_three_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_triple_empty_one_nop#1% +\def\syst_helpers_triple_empty_one_nop {\firstargumentfalse \secondargumentfalse \thirdargumentfalse - #1[][][]} + \the\t_syst_aux[][][]} \def\syst_helpers_triple_empty_two_nop {\secondargumentfalse \thirdargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_triple_empty_two_spaced + \expandafter\syst_helpers_empty_spaced_two \else - \expandafter\syst_helpers_triple_empty_two_normal + \expandafter\syst_helpers_empty_normal_two \fi} \def\syst_helpers_triple_empty_three_nop {\thirdargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_triple_empty_three_spaced + \expandafter\syst_helpers_empty_spaced_one \else - \expandafter\syst_helpers_triple_empty_three_normal + \expandafter\syst_helpers_empty_normal_one \fi} -\def\syst_helpers_triple_empty_two_spaced #1#2{#1[{#2}][][] } -\def\syst_helpers_triple_empty_two_normal #1#2{#1[{#2}][][]} -\def\syst_helpers_triple_empty_three_spaced#1#2#3{#1[{#2}][{#3}][] } -\def\syst_helpers_triple_empty_three_normal#1#2#3{#1[{#2}][{#3}][]} +%D Quadruple: -%D Four: +% \unexpanded\def\doquadrupleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_quadruple_empty_one_yes#1}% +% {\syst_helpers_quadruple_empty_one_nop#1}} +% +% \def\syst_helpers_quadruple_empty_one_yes#1[#2]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\syst_helpers_quadruple_empty_two_yes#1{#2}}% +% {\syst_helpers_quadruple_empty_two_nop#1{#2}}} +% +% \def\syst_helpers_quadruple_empty_two_yes#1#2[#3]% +% {\secondargumenttrue +% \doifelsenextoptional +% {\syst_helpers_quadruple_empty_three_yes#1{#2}{#3}}% +% {\syst_helpers_quadruple_empty_three_nop#1{#2}{#3}}} +% +% \def\syst_helpers_quadruple_empty_three_yes#1#2#3[#4]% +% {\thirdargumenttrue +% \doifelsenextoptional +% {\fourthargumenttrue#1[{#2}][{#3}][{#4}]}% +% {\syst_helpers_quadruple_empty_four_nop#1{#2}{#3}{#4}}} +% +% \def\syst_helpers_quadruple_empty_one_nop#1% +% {\firstargumentfalse +% \secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% #1[][][][]} +% +% \def\syst_helpers_quadruple_empty_two_nop +% {\secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quadruple_empty_two_spaced +% \else +% \expandafter\syst_helpers_quadruple_empty_two_normal +% \fi} +% +% \def\syst_helpers_quadruple_empty_three_nop +% {\thirdargumentfalse +% \fourthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quadruple_empty_three_spaced +% \else +% \expandafter\syst_helpers_quadruple_empty_three_normal +% \fi} +% +% \def\syst_helpers_quadruple_empty_four_nop +% {\fourthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quadruple_empty_four_spaced +% \else +% \expandafter\syst_helpers_quadruple_empty_four_normal +% \fi} +% +% \def\syst_helpers_quadruple_empty_two_spaced #1#2{#1[{#2}][][][] } +% \def\syst_helpers_quadruple_empty_two_normal #1#2{#1[{#2}][][][]} +% \def\syst_helpers_quadruple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][] } +% \def\syst_helpers_quadruple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][]} +% \def\syst_helpers_quadruple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][] } +% \def\syst_helpers_quadruple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][]} \unexpanded\def\doquadrupleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_quadruple_empty_one_yes#1}% - {\syst_helpers_quadruple_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_quadruple_empty_one_yes + \let\m_syst_action_nop\syst_helpers_quadruple_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quadruple_empty_one_yes#1[#2]% +\def\syst_helpers_quadruple_empty_one_yes[#1]% {\firstargumenttrue - \doifelsenextoptional - {\syst_helpers_quadruple_empty_two_yes#1{#2}}% - {\syst_helpers_quadruple_empty_two_nop#1{#2}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quadruple_empty_two_yes + \let\m_syst_action_nop\syst_helpers_quadruple_empty_two_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quadruple_empty_two_yes#1#2[#3]% +\def\syst_helpers_quadruple_empty_two_yes[#1]% {\secondargumenttrue - \doifelsenextoptional - {\syst_helpers_quadruple_empty_three_yes#1{#2}{#3}}% - {\syst_helpers_quadruple_empty_three_nop#1{#2}{#3}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quadruple_empty_three_yes + \let\m_syst_action_nop\syst_helpers_quadruple_empty_three_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quadruple_empty_three_yes#1#2#3[#4]% +\def\syst_helpers_quadruple_empty_three_yes[#1]% {\thirdargumenttrue - \doifelsenextoptional - {\fourthargumenttrue#1[{#2}][{#3}][{#4}]}% - {\syst_helpers_quadruple_empty_four_nop#1{#2}{#3}{#4}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quadruple_empty_four_yes + \let\m_syst_action_nop\syst_helpers_quadruple_empty_four_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quadruple_empty_one_nop#1% +\def\syst_helpers_quadruple_empty_one_nop {\firstargumentfalse \secondargumentfalse \thirdargumentfalse \fourthargumentfalse - #1[][][][]} + \the\t_syst_aux[][][][]} \def\syst_helpers_quadruple_empty_two_nop {\secondargumentfalse \thirdargumentfalse \fourthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quadruple_empty_two_spaced + \expandafter\syst_helpers_empty_spaced_three \else - \expandafter\syst_helpers_quadruple_empty_two_normal + \expandafter\syst_helpers_empty_normal_three \fi} \def\syst_helpers_quadruple_empty_three_nop {\thirdargumentfalse \fourthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quadruple_empty_three_spaced + \expandafter\syst_helpers_empty_spaced_two \else - \expandafter\syst_helpers_quadruple_empty_three_normal + \expandafter\syst_helpers_empty_normal_two \fi} \def\syst_helpers_quadruple_empty_four_nop {\fourthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quadruple_empty_four_spaced + \expandafter\syst_helpers_empty_spaced_one \else - \expandafter\syst_helpers_quadruple_empty_four_normal + \expandafter\syst_helpers_empty_normal_one \fi} -\def\syst_helpers_quadruple_empty_two_spaced #1#2{#1[{#2}][][][] } -\def\syst_helpers_quadruple_empty_two_normal #1#2{#1[{#2}][][][]} -\def\syst_helpers_quadruple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][] } -\def\syst_helpers_quadruple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][]} -\def\syst_helpers_quadruple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][] } -\def\syst_helpers_quadruple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][]} +%D Quintuple: -%D Five: +% \unexpanded\def\doquintupleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_quintuple_empty_one_yes#1}% +% {\syst_helpers_quintuple_empty_one_nop#1}} +% +% \def\syst_helpers_quintuple_empty_one_yes#1[#2]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\syst_helpers_quintuple_empty_two_yes#1{#2}}% +% {\syst_helpers_quintuple_empty_two_nop#1{#2}}} +% +% \def\syst_helpers_quintuple_empty_two_yes#1#2[#3]% +% {\secondargumenttrue +% \doifelsenextoptional +% {\syst_helpers_quintuple_empty_three_yes#1{#2}{#3}}% +% {\syst_helpers_quintuple_empty_three_nop#1{#2}{#3}}} +% +% \def\syst_helpers_quintuple_empty_three_yes#1#2#3[#4]% +% {\thirdargumenttrue +% \doifelsenextoptional +% {\syst_helpers_quintuple_empty_four_yes#1{#2}{#3}{#4}}% +% {\syst_helpers_quintuple_empty_four_nop#1{#2}{#3}{#4}}} +% +% \def\syst_helpers_quintuple_empty_four_yes#1#2#3#4[#5]% +% {\fourthargumenttrue +% \doifelsenextoptional +% {\fifthargumenttrue#1[{#2}][{#3}][{#4}][{#5}]}% +% {\syst_helpers_quintuple_empty_five_nop#1{#2}{#3}{#4}{#5}}} +% +% \def\syst_helpers_quintuple_empty_one_nop#1% +% {\firstargumentfalse +% \secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% #1[][][][][]} +% +% \def\syst_helpers_quintuple_empty_two_nop +% {\secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quintuple_empty_two_spaced +% \else +% \expandafter\syst_helpers_quintuple_empty_two_normal +% \fi} +% +% \def\syst_helpers_quintuple_empty_three_nop +% {\thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quintuple_empty_three_spaced +% \else +% \expandafter\syst_helpers_quintuple_empty_three_normal +% \fi} +% +% \def\syst_helpers_quintuple_empty_four_nop +% {\fourthargumentfalse +% \fifthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quintuple_empty_four_spaced +% \else +% \expandafter\syst_helpers_quintuple_empty_four_normal +% \fi} +% +% \def\syst_helpers_quintuple_empty_five_nop +% {\fifthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_quintuple_empty_five_spaced +% \else +% \expandafter\syst_helpers_quintuple_empty_five_normal +% \fi} +% +% \def\syst_helpers_quintuple_empty_two_spaced #1#2{#1[{#2}][][][][] } +% \def\syst_helpers_quintuple_empty_two_normal #1#2{#1[{#2}][][][][]} +% \def\syst_helpers_quintuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][] } +% \def\syst_helpers_quintuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][]} +% \def\syst_helpers_quintuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][] } +% \def\syst_helpers_quintuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][]} +% \def\syst_helpers_quintuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][] } +% \def\syst_helpers_quintuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][]} \unexpanded\def\doquintupleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_quintuple_empty_one_yes#1}% - {\syst_helpers_quintuple_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_quintuple_empty_one_yes + \let\m_syst_action_nop\syst_helpers_quintuple_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quintuple_empty_one_yes#1[#2]% +\def\syst_helpers_quintuple_empty_one_yes[#1]% {\firstargumenttrue - \doifelsenextoptional - {\syst_helpers_quintuple_empty_two_yes#1{#2}}% - {\syst_helpers_quintuple_empty_two_nop#1{#2}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quintuple_empty_two_yes + \let\m_syst_action_nop\syst_helpers_quintuple_empty_two_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quintuple_empty_two_yes#1#2[#3]% +\def\syst_helpers_quintuple_empty_two_yes[#1]% {\secondargumenttrue - \doifelsenextoptional - {\syst_helpers_quintuple_empty_three_yes#1{#2}{#3}}% - {\syst_helpers_quintuple_empty_three_nop#1{#2}{#3}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quintuple_empty_three_yes + \let\m_syst_action_nop\syst_helpers_quintuple_empty_three_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quintuple_empty_three_yes#1#2#3[#4]% +\def\syst_helpers_quintuple_empty_three_yes[#1]% {\thirdargumenttrue - \doifelsenextoptional - {\syst_helpers_quintuple_empty_four_yes#1{#2}{#3}{#4}}% - {\syst_helpers_quintuple_empty_four_nop#1{#2}{#3}{#4}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quintuple_empty_four_yes + \let\m_syst_action_nop\syst_helpers_quintuple_empty_four_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quintuple_empty_four_yes#1#2#3#4[#5]% +\def\syst_helpers_quintuple_empty_four_yes[#1]% {\fourthargumenttrue - \doifelsenextoptional - {\fifthargumenttrue#1[{#2}][{#3}][{#4}][{#5}]}% - {\syst_helpers_quintuple_empty_five_nop#1{#2}{#3}{#4}{#5}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_quintuple_empty_five_yes + \let\m_syst_action_nop\syst_helpers_quintuple_empty_five_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_quintuple_empty_one_nop#1% +\def\syst_helpers_quintuple_empty_one_nop {\firstargumentfalse \secondargumentfalse \thirdargumentfalse \fourthargumentfalse \fifthargumentfalse - #1[][][][][]} + \the\t_syst_aux[][][][][]} \def\syst_helpers_quintuple_empty_two_nop {\secondargumentfalse @@ -2446,9 +2811,9 @@ \fourthargumentfalse \fifthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quintuple_empty_two_spaced + \expandafter\syst_helpers_empty_spaced_four \else - \expandafter\syst_helpers_quintuple_empty_two_normal + \expandafter\syst_helpers_empty_normal_four \fi} \def\syst_helpers_quintuple_empty_three_nop @@ -2456,83 +2821,192 @@ \fourthargumentfalse \fifthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quintuple_empty_three_spaced + \expandafter\syst_helpers_empty_spaced_three \else - \expandafter\syst_helpers_quintuple_empty_three_normal + \expandafter\syst_helpers_empty_normal_three \fi} \def\syst_helpers_quintuple_empty_four_nop {\fourthargumentfalse \fifthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quintuple_empty_four_spaced + \expandafter\syst_helpers_empty_spaced_two \else - \expandafter\syst_helpers_quintuple_empty_four_normal + \expandafter\syst_helpers_empty_normal_two \fi} \def\syst_helpers_quintuple_empty_five_nop {\fifthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_quintuple_empty_five_spaced + \expandafter\syst_helpers_empty_spaced_one \else - \expandafter\syst_helpers_quintuple_empty_five_normal + \expandafter\syst_helpers_empty_normal_one \fi} -\def\syst_helpers_quintuple_empty_two_spaced #1#2{#1[{#2}][][][][] } -\def\syst_helpers_quintuple_empty_two_normal #1#2{#1[{#2}][][][][]} -\def\syst_helpers_quintuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][] } -\def\syst_helpers_quintuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][]} -\def\syst_helpers_quintuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][] } -\def\syst_helpers_quintuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][]} -\def\syst_helpers_quintuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][] } -\def\syst_helpers_quintuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][]} +%D Sixtuple: -%D Six +% \unexpanded\def\dosixtupleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_sixtuple_empty_one_yes#1} +% {\syst_helpers_sixtuple_empty_one_nop#1}} +% +% \def\syst_helpers_sixtuple_empty_one_yes#1[#2]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\syst_helpers_sixtuple_empty_two_yes#1{#2}}% +% {\syst_helpers_sixtuple_empty_two_nop#1{#2}}} +% +% \def\syst_helpers_sixtuple_empty_two_yes#1#2[#3]% +% {\secondargumenttrue +% \doifelsenextoptional +% {\syst_helpers_sixtuple_empty_three_yes#1{#2}{#3}}% +% {\syst_helpers_sixtuple_empty_three_nop#1{#2}{#3}}} +% +% \def\syst_helpers_sixtuple_empty_three_yes#1#2#3[#4]% +% {\thirdargumenttrue +% \doifelsenextoptional +% {\syst_helpers_sixtuple_empty_four_yes#1{#2}{#3}{#4}}% +% {\syst_helpers_sixtuple_empty_four_nop#1{#2}{#3}{#4}}} +% +% \def\syst_helpers_sixtuple_empty_four_yes#1#2#3#4[#5]% +% {\fourthargumenttrue +% \doifelsenextoptional +% {\syst_helpers_sixtuple_empty_five_yes#1{#2}{#3}{#4}{#5}}% +% {\syst_helpers_sixtuple_empty_five_nop#1{#2}{#3}{#4}{#5}}} +% +% \def\syst_helpers_sixtuple_empty_five_yes#1#2#3#4#5[#6]% +% {\fifthargumenttrue +% \doifelsenextoptional +% {\sixthargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}]}% +% {\syst_helpers_sixtuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}} +% +% \def\syst_helpers_sixtuple_empty_one_nop#1% +% {\firstargumentfalse +% \secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% #1[][][][][][]} +% +% \def\syst_helpers_sixtuple_empty_two_nop +% {\secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_sixtuple_empty_two_spaced +% \else +% \expandafter\syst_helpers_sixtuple_empty_two_normal +% \fi} +% +% \def\syst_helpers_sixtuple_empty_three_nop +% {\thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_sixtuple_empty_three_spaced +% \else +% \expandafter\syst_helpers_sixtuple_empty_three_normal +% \fi} +% +% \def\syst_helpers_sixtuple_empty_four_nop +% {\fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_sixtuple_empty_four_spaced +% \else +% \expandafter\syst_helpers_sixtuple_empty_four_normal +% \fi} +% +% \def\syst_helpers_sixtuple_empty_five_nop +% {\fifthargumentfalse +% \sixthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_sixtuple_empty_five_spaced +% \else +% \expandafter\syst_helpers_sixtuple_empty_five_normal +% \fi} +% +% \def\syst_helpers_sixtuple_empty_six_nop +% {\sixthargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_sixtuple_empty_six_spaced +% \else +% \expandafter\syst_helpers_sixtuple_empty_six_normal +% \fi} +% +% \def\syst_helpers_sixtuple_empty_two_spaced #1#2{#1[{#2}][][][][][] } +% \def\syst_helpers_sixtuple_empty_two_normal #1#2{#1[{#2}][][][][][]} +% \def\syst_helpers_sixtuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][] } +% \def\syst_helpers_sixtuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][]} +% \def\syst_helpers_sixtuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][] } +% \def\syst_helpers_sixtuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][]} +% \def\syst_helpers_sixtuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][] } +% \def\syst_helpers_sixtuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][]} +% \def\syst_helpers_sixtuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][] } +% \def\syst_helpers_sixtuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][]} \unexpanded\def\dosixtupleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_sixtuple_empty_one_yes#1} - {\syst_helpers_sixtuple_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_sixtuple_empty_one_yes + \let\m_syst_action_nop\syst_helpers_sixtuple_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_sixtuple_empty_one_yes#1[#2]% +\def\syst_helpers_sixtuple_empty_one_yes[#1]% {\firstargumenttrue - \doifelsenextoptional - {\syst_helpers_sixtuple_empty_two_yes#1{#2}}% - {\syst_helpers_sixtuple_empty_two_nop#1{#2}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_sixtuple_empty_two_yes + \let\m_syst_action_nop\syst_helpers_sixtuple_empty_two_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_sixtuple_empty_two_yes#1#2[#3]% +\def\syst_helpers_sixtuple_empty_two_yes[#1]% {\secondargumenttrue - \doifelsenextoptional - {\syst_helpers_sixtuple_empty_three_yes#1{#2}{#3}}% - {\syst_helpers_sixtuple_empty_three_nop#1{#2}{#3}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_sixtuple_empty_three_yes + \let\m_syst_action_nop\syst_helpers_sixtuple_empty_three_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_sixtuple_empty_three_yes#1#2#3[#4]% +\def\syst_helpers_sixtuple_empty_three_yes[#1]% {\thirdargumenttrue - \doifelsenextoptional - {\syst_helpers_sixtuple_empty_four_yes#1{#2}{#3}{#4}}% - {\syst_helpers_sixtuple_empty_four_nop#1{#2}{#3}{#4}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_sixtuple_empty_four_yes + \let\m_syst_action_nop\syst_helpers_sixtuple_empty_four_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_sixtuple_empty_four_yes#1#2#3#4[#5]% +\def\syst_helpers_sixtuple_empty_four_yes[#1]% {\fourthargumenttrue - \doifelsenextoptional - {\syst_helpers_sixtuple_empty_five_yes#1{#2}{#3}{#4}{#5}}% - {\syst_helpers_sixtuple_empty_five_nop#1{#2}{#3}{#4}{#5}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_sixtuple_empty_five_yes + \let\m_syst_action_nop\syst_helpers_sixtuple_empty_five_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_sixtuple_empty_five_yes#1#2#3#4#5[#6]% +\def\syst_helpers_sixtuple_empty_five_yes[#1]% {\fifthargumenttrue - \doifelsenextoptional - {\sixthargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}]}% - {\syst_helpers_sixtuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_sixtuple_empty_six_yes + \let\m_syst_action_nop\syst_helpers_sixtuple_empty_six_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_sixtuple_empty_one_nop#1% +\def\syst_helpers_sixtuple_empty_one_nop {\firstargumentfalse \secondargumentfalse \thirdargumentfalse \fourthargumentfalse \fifthargumentfalse \sixthargumentfalse - #1[][][][][][]} + \the\t_syst_aux[][][][][][]} \def\syst_helpers_sixtuple_empty_two_nop {\secondargumentfalse @@ -2541,9 +3015,9 @@ \fifthargumentfalse \sixthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_sixtuple_empty_two_spaced + \expandafter\syst_helpers_empty_spaced_five \else - \expandafter\syst_helpers_sixtuple_empty_two_normal + \expandafter\syst_helpers_empty_normal_five \fi} \def\syst_helpers_sixtuple_empty_three_nop @@ -2552,9 +3026,9 @@ \fifthargumentfalse \sixthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_sixtuple_empty_three_spaced + \expandafter\syst_helpers_empty_spaced_four \else - \expandafter\syst_helpers_sixtuple_empty_three_normal + \expandafter\syst_helpers_empty_normal_four \fi} \def\syst_helpers_sixtuple_empty_four_nop @@ -2562,84 +3036,215 @@ \fifthargumentfalse \sixthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_sixtuple_empty_four_spaced + \expandafter\syst_helpers_empty_spaced_three \else - \expandafter\syst_helpers_sixtuple_empty_four_normal + \expandafter\syst_helpers_empty_normal_three \fi} \def\syst_helpers_sixtuple_empty_five_nop {\fifthargumentfalse \sixthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_sixtuple_empty_five_spaced + \expandafter\syst_helpers_empty_spaced_two \else - \expandafter\syst_helpers_sixtuple_empty_five_normal + \expandafter\syst_helpers_empty_normal_two \fi} \def\syst_helpers_sixtuple_empty_six_nop {\sixthargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_sixtuple_empty_six_spaced + \expandafter\syst_helpers_empty_spaced_one \else - \expandafter\syst_helpers_sixtuple_empty_six_normal + \expandafter\syst_helpers_empty_normal_one \fi} -\def\syst_helpers_sixtuple_empty_two_spaced #1#2{#1[{#2}][][][][][] } -\def\syst_helpers_sixtuple_empty_two_normal #1#2{#1[{#2}][][][][][]} -\def\syst_helpers_sixtuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][] } -\def\syst_helpers_sixtuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][]} -\def\syst_helpers_sixtuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][] } -\def\syst_helpers_sixtuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][]} -\def\syst_helpers_sixtuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][] } -\def\syst_helpers_sixtuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][]} -\def\syst_helpers_sixtuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][] } -\def\syst_helpers_sixtuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][]} +%D Seventuple: -%D Seven: +% \unexpanded\def\doseventupleempty#1% +% {\syst_helpers_argument_reset +% \doifelsenextoptional +% {\syst_helpers_seventuple_empty_one_yes#1}% +% {\syst_helpers_seventuple_empty_one_nop#1}} +% +% \def\syst_helpers_seventuple_empty_one_yes#1[#2]% +% {\firstargumenttrue +% \doifelsenextoptional +% {\syst_helpers_seventuple_empty_two_yes#1{#2}}% +% {\syst_helpers_seventuple_empty_two_nop#1{#2}}} +% +% \def\syst_helpers_seventuple_empty_two_yes#1#2[#3]% +% {\secondargumenttrue +% \doifelsenextoptional +% {\syst_helpers_seventuple_empty_three_yes#1{#2}{#3}}% +% {\syst_helpers_seventuple_empty_three_nop#1{#2}{#3}}} +% +% \def\syst_helpers_seventuple_empty_three_yes#1#2#3[#4]% +% {\thirdargumenttrue +% \doifelsenextoptional +% {\syst_helpers_seventuple_empty_four_yes#1{#2}{#3}{#4}}% +% {\syst_helpers_seventuple_empty_four_nop#1{#2}{#3}{#4}}} +% +% \def\syst_helpers_seventuple_empty_four_yes#1#2#3#4[#5]% +% {\fourthargumenttrue +% \doifelsenextoptional +% {\syst_helpers_seventuple_empty_five_yes#1{#2}{#3}{#4}{#5}}% +% {\syst_helpers_seventuple_empty_five_nop#1{#2}{#3}{#4}{#5}}} +% +% \def\syst_helpers_seventuple_empty_five_yes#1#2#3#4#5[#6]% +% {\fifthargumenttrue +% \doifelsenextoptional +% {\syst_helpers_seventuple_empty_six_yes#1{#2}{#3}{#4}{#5}{#6}}% +% {\syst_helpers_seventuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}} +% +% \def\syst_helpers_seventuple_empty_six_yes#1#2#3#4#5#6[#7]% +% {\sixthargumenttrue +% \doifelsenextoptional +% {\seventhargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}]}% +% {\syst_helpers_seventuple_empty_seven_nop#1{#2}{#3}{#4}{#5}{#6}{#7}}} +% +% \def\syst_helpers_seventuple_empty_one_nop#1% +% {\firstargumentfalse +% \secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \seventhargumentfalse +% #1[][][][][][][]} +% +% \def\syst_helpers_seventuple_empty_two_nop +% {\secondargumentfalse +% \thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \seventhargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_seventuple_empty_two_spaced +% \else +% \expandafter\syst_helpers_seventuple_empty_two_normal +% \fi} +% +% \def\syst_helpers_seventuple_empty_three_nop +% {\thirdargumentfalse +% \fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \seventhargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_seventuple_empty_three_spaced +% \else +% \expandafter\syst_helpers_seventuple_empty_three_normal +% \fi} +% +% \def\syst_helpers_seventuple_empty_four_nop +% {\fourthargumentfalse +% \fifthargumentfalse +% \sixthargumentfalse +% \seventhargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_seventuple_empty_four_spaced +% \else +% \expandafter\syst_helpers_seventuple_empty_four_normal +% \fi} +% +% \def\syst_helpers_seventuple_empty_five_nop +% {\fifthargumentfalse +% \sixthargumentfalse +% \seventhargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_seventuple_empty_five_spaced +% \else +% \expandafter\syst_helpers_seventuple_empty_five_normal +% \fi} +% +% \def\syst_helpers_seventuple_empty_six_nop +% {\sixthargumentfalse +% \seventhargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_seventuple_empty_six_spaced +% \else +% \expandafter\syst_helpers_seventuple_empty_six_normal +% \fi} +% +% \def\syst_helpers_seventuple_empty_seven_nop +% {\seventhargumentfalse +% \if_next_blank_space_token +% \expandafter\syst_helpers_seventuple_empty_seven_spaced +% \else +% \expandafter\syst_helpers_seventuple_empty_seven_normal +% \fi} +% +% \def\syst_helpers_seventuple_empty_two_spaced #1#2{#1[{#2}][][][][][][] } +% \def\syst_helpers_seventuple_empty_two_normal #1#2{#1[{#2}][][][][][][]} +% \def\syst_helpers_seventuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][][] } +% \def\syst_helpers_seventuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][][]} +% \def\syst_helpers_seventuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][] } +% \def\syst_helpers_seventuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][]} +% \def\syst_helpers_seventuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][] } +% \def\syst_helpers_seventuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][]} +% \def\syst_helpers_seventuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][] } +% \def\syst_helpers_seventuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][]} +% \def\syst_helpers_seventuple_empty_seven_spaced#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][] } +% \def\syst_helpers_seventuple_empty_seven_normal#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][]} \unexpanded\def\doseventupleempty#1% {\syst_helpers_argument_reset - \doifelsenextoptional - {\syst_helpers_seventuple_empty_one_yes#1}% - {\syst_helpers_seventuple_empty_one_nop#1}} + \t_syst_aux{#1}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_one_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_one_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_one_yes#1[#2]% +\def\syst_helpers_seventuple_empty_one_yes[#1]% {\firstargumenttrue - \doifelsenextoptional - {\syst_helpers_seventuple_empty_two_yes#1{#2}}% - {\syst_helpers_seventuple_empty_two_nop#1{#2}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_two_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_two_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_two_yes#1#2[#3]% +\def\syst_helpers_seventuple_empty_two_yes[#1]% {\secondargumenttrue - \doifelsenextoptional - {\syst_helpers_seventuple_empty_three_yes#1{#2}{#3}}% - {\syst_helpers_seventuple_empty_three_nop#1{#2}{#3}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_three_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_three_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_three_yes#1#2#3[#4]% +\def\syst_helpers_seventuple_empty_three_yes[#1]% {\thirdargumenttrue - \doifelsenextoptional - {\syst_helpers_seventuple_empty_four_yes#1{#2}{#3}{#4}}% - {\syst_helpers_seventuple_empty_four_nop#1{#2}{#3}{#4}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_four_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_four_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_four_yes#1#2#3#4[#5]% +\def\syst_helpers_seventuple_empty_four_yes[#1]% {\fourthargumenttrue - \doifelsenextoptional - {\syst_helpers_seventuple_empty_five_yes#1{#2}{#3}{#4}{#5}}% - {\syst_helpers_seventuple_empty_five_nop#1{#2}{#3}{#4}{#5}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_five_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_five_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_five_yes#1#2#3#4#5[#6]% +\def\syst_helpers_seventuple_empty_five_yes[#1]% {\fifthargumenttrue - \doifelsenextoptional - {\syst_helpers_seventuple_empty_six_yes#1{#2}{#3}{#4}{#5}{#6}}% - {\syst_helpers_seventuple_empty_six_nop#1{#2}{#3}{#4}{#5}{#6}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_six_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_six_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_six_yes#1#2#3#4#5#6[#7]% +\def\syst_helpers_seventuple_empty_six_yes[#1]% {\sixthargumenttrue - \doifelsenextoptional - {\seventhargumenttrue#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}]}% - {\syst_helpers_seventuple_empty_seven_nop#1{#2}{#3}{#4}{#5}{#6}{#7}}} + \toksapp\t_syst_aux{[{#1}]}% + \let\m_syst_action_yes\syst_helpers_seventuple_empty_seven_yes + \let\m_syst_action_nop\syst_helpers_seventuple_empty_seven_nop + \let\if_next_blank_space_token\iffalse + \futurelet\nexttoken\syst_helpers_inspect_next_optional_character} -\def\syst_helpers_seventuple_empty_one_nop#1% +\def\syst_helpers_seventuple_empty_one_nop {\firstargumentfalse \secondargumentfalse \thirdargumentfalse @@ -2647,7 +3252,7 @@ \fifthargumentfalse \sixthargumentfalse \seventhargumentfalse - #1[][][][][][][]} + \the\t_syst_aux[][][][][][][]} \def\syst_helpers_seventuple_empty_two_nop {\secondargumentfalse @@ -2657,9 +3262,9 @@ \sixthargumentfalse \seventhargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_seventuple_empty_two_spaced + \expandafter\syst_helpers_empty_spaced_six \else - \expandafter\syst_helpers_seventuple_empty_two_normal + \expandafter\syst_helpers_empty_normal_six \fi} \def\syst_helpers_seventuple_empty_three_nop @@ -2669,9 +3274,9 @@ \sixthargumentfalse \seventhargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_seventuple_empty_three_spaced + \expandafter\syst_helpers_empty_spaced_five \else - \expandafter\syst_helpers_seventuple_empty_three_normal + \expandafter\syst_helpers_empty_normal_five \fi} \def\syst_helpers_seventuple_empty_four_nop @@ -2680,9 +3285,9 @@ \sixthargumentfalse \seventhargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_seventuple_empty_four_spaced + \expandafter\syst_helpers_empty_spaced_four \else - \expandafter\syst_helpers_seventuple_empty_four_normal + \expandafter\syst_helpers_empty_normal_four \fi} \def\syst_helpers_seventuple_empty_five_nop @@ -2690,40 +3295,29 @@ \sixthargumentfalse \seventhargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_seventuple_empty_five_spaced + \expandafter\syst_helpers_empty_spaced_three \else - \expandafter\syst_helpers_seventuple_empty_five_normal + \expandafter\syst_helpers_empty_normal_three \fi} \def\syst_helpers_seventuple_empty_six_nop {\sixthargumentfalse \seventhargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_seventuple_empty_six_spaced + \expandafter\syst_helpers_empty_spaced_two \else - \expandafter\syst_helpers_seventuple_empty_six_normal + \expandafter\syst_helpers_empty_normal_two \fi} \def\syst_helpers_seventuple_empty_seven_nop {\seventhargumentfalse \if_next_blank_space_token - \expandafter\syst_helpers_seventuple_empty_seven_spaced + \expandafter\syst_helpers_empty_spaced_one \else - \expandafter\syst_helpers_seventuple_empty_seven_normal + \expandafter\syst_helpers_empty_normal_one \fi} -\def\syst_helpers_seventuple_empty_two_spaced #1#2{#1[{#2}][][][][][][] } -\def\syst_helpers_seventuple_empty_two_normal #1#2{#1[{#2}][][][][][][]} -\def\syst_helpers_seventuple_empty_three_spaced #1#2#3{#1[{#2}][{#3}][][][][][] } -\def\syst_helpers_seventuple_empty_three_normal #1#2#3{#1[{#2}][{#3}][][][][][]} -\def\syst_helpers_seventuple_empty_four_spaced #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][] } -\def\syst_helpers_seventuple_empty_four_normal #1#2#3#4{#1[{#2}][{#3}][{#4}][][][][]} -\def\syst_helpers_seventuple_empty_five_spaced #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][] } -\def\syst_helpers_seventuple_empty_five_normal #1#2#3#4#5{#1[{#2}][{#3}][{#4}][{#5}][][][]} -\def\syst_helpers_seventuple_empty_six_spaced #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][] } -\def\syst_helpers_seventuple_empty_six_normal #1#2#3#4#5#6{#1[{#2}][{#3}][{#4}][{#5}][{#6}][][]} -\def\syst_helpers_seventuple_empty_seven_spaced#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][] } -\def\syst_helpers_seventuple_empty_seven_normal#1#2#3#4#5#6#7{#1[{#2}][{#3}][{#4}][{#5}][{#6}][{#7}][]} +%D Aliases: \let\dosingleargument \dosingleempty \let\dodoubleargument \dodoubleempty @@ -2900,7 +3494,7 @@ \begingroup \def\\ {\syst_helpers_get_grouped_argument\syst_helpers_get_grouped_argument_yes\syst_helpers_get_grouped_argument_nop} - \global\let\syst_helpers_get_grouped_argument_e\\ + \glet\syst_helpers_get_grouped_argument_e\\ \endgroup \def\syst_helpers_get_grouped_argument_f @@ -3031,13 +3625,13 @@ %D %D Trivial: -\unexpanded\def\letempty #1{\let#1\empty} -\unexpanded\def\globalletempty#1{\global\let#1\empty} +\unexpanded\def\letempty #1{\let #1\empty} +\unexpanded\def\globalletempty#1{\glet#1\empty} -\unexpanded\def\letvalueempty #1{\expandafter\let\csname#1\endcsname\empty} -\unexpanded\def\letgvalueempty#1{\global\expandafter\let\csname#1\endcsname\empty} -\unexpanded\def\letvaluerelax #1{\expandafter\let\csname#1\endcsname\relax} -\unexpanded\def\letgvalurelax #1{\global\expandafter\let\csname#1\endcsname\relax} +\unexpanded\def\letvalueempty #1{\expandafter\let \csname#1\endcsname\empty} +\unexpanded\def\letgvalueempty#1{\expandafter\glet\csname#1\endcsname\empty} +\unexpanded\def\letvaluerelax #1{\expandafter\let \csname#1\endcsname\relax} +\unexpanded\def\letgvalurelax #1{\expandafter\glet\csname#1\endcsname\relax} \unexpanded\def\relaxvalueifundefined#1% {\ifcsname#1\endcsname \else @@ -3183,17 +3777,25 @@ %D Apart from the prefixes, a few more \type{\expandafters} %D are needed: -\unexpanded\def\newif#1% - {\privatescratchcounter\escapechar - \escapechar\minusone - \expandafter\expandafter\expandafter - \redoglobal\expandafter\expandafter\expandafter - \edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}% - \expandafter\expandafter\expandafter - \redoglobal\expandafter\expandafter\expandafter - \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}% - \dodoglobal\@if#1{false}% - \escapechar\privatescratchcounter} +% \unexpanded\def\newif#1% uses the original plain \@if +% {\privatescratchcounter\escapechar +% \escapechar\minusone +% \expandafter\expandafter\expandafter +% \redoglobal\expandafter\expandafter\expandafter +% \edef\@if#1{true}{\let\noexpand#1\noexpand\iftrue}% +% \expandafter\expandafter\expandafter +% \redoglobal\expandafter\expandafter\expandafter +% \edef\@if#1{false}{\let\noexpand#1\noexpand\iffalse}% +% \dodoglobal\@if#1{false}% +% \escapechar\privatescratchcounter} + +\normalprotected\def\newif#1% see syst-ini.mkiv + {\let\new_if_saved\newif + \let\newif\new_if_check + \expandafter\redoglobal\expandafter\def\csname\expandafter\newif\csstring#1true\endcsname {\let#1\iftrue }% + \expandafter\redoglobal\expandafter\def\csname\expandafter\newif\csstring#1false\endcsname{\let#1\iffalse}% + \dodoglobal\csname\expandafter\newif\csstring#1false\endcsname + \let\newif\new_if_saved} %D Also new: @@ -3245,7 +3847,7 @@ % \bgroup \obeylines % -% \global\let\stoptexdefinition\relax +% \glet\stoptexdefinition\relax % % \unexpanded\gdef\starttexdefinition% % {\bgroup% @@ -3302,7 +3904,7 @@ % \bgroup \obeylines % -% \global\let\stoptexdefinition\relax +% \glet\stoptexdefinition\relax % % \unexpanded\gdef\starttexdefinition% % {\bgroup% @@ -3321,7 +3923,7 @@ \bgroup \obeylines -\global\let\stoptexdefinition\relax +\glet\stoptexdefinition\relax \unexpanded\gdef\starttexdefinition% {\bgroup% @@ -3538,8 +4140,8 @@ \unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone - \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname{#4}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname{#4}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \ifnum#3>\zerocount\relax \ifnum#2<#1\relax \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit @@ -3567,7 +4169,7 @@ \fi\expandafter{\the\numexpr\recurselevel+#3\relax}{#2}{#3}} \unexpanded\def\syst_helpers_recurse_content - {\csname\??recurseaction\recursedepth\endcsname} + {\csname\??recurseaction\the\outerrecurse\endcsname} \unexpanded\def\syst_helpers_stepwise_recurse_yes {\syst_helpers_recurse_content @@ -3591,11 +4193,11 @@ {\syst_helpers_stepwise_recurse_nop\relax} \unexpanded\def\syst_helpers_stepwise_recurse_nop#1#2#3#4% - {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname + {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname \global\advance\outerrecurse\minusone} % \unexpanded\def\nonostepwiserecurse#1#2#3% -% {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname +% {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname % \global\advance\outerrecurse\minusone} \unexpanded\def\dorecurse#1% @@ -3636,16 +4238,16 @@ \unexpanded\def\syst_helpers_recurse_x#1#2% {\global\advance\outerrecurse \plusone - \expandafter\gdef\csname\??recurseaction\recursedepth\endcsname{#2}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname{#2}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \expandafter\syst_helpers_recurse_indeed\expandafter1\expandafter{\number#1}} \unexpanded\def\syst_helpers_recurse_y#1#2% {\global\advance\outerrecurse \plusone - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\glet\csname\??recurseindex\the\outerrecurse\endcsname\recurselevel \let\recurselevel\!!plusone #2% - \expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname + \expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname \global\advance\outerrecurse \minusone} \unexpanded\def\syst_helpers_recurse_indeed#1#2% from to @@ -3670,7 +4272,7 @@ \syst_helpers_recurse_indeed} \unexpanded\def\syst_helpers_recurse_indeed_nop#1#2#3% - {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname + {\expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname \global\advance\outerrecurse \minusone } %D \macros @@ -3708,8 +4310,8 @@ \unexpanded\def\doloop#1% {\global\advance\outerrecurse \plusone - \expandafter\gdef\csname\??recurseaction\recursedepth\endcsname{#1}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname{#1}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \let\endofloop\syst_helpers_loop \syst_helpers_loop1} % no \plusone else \recurselevel wrong @@ -3723,7 +4325,7 @@ \unexpanded\def\syst_helpers_loop_nop#1% {\let\endofloop\syst_helpers_loop % new, permits nested \doloop's - \expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname + \expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname \global\advance\outerrecurse\minusone} \unexpanded\def\exitloop % \exitloop quits at end @@ -3771,59 +4373,61 @@ %D \stoptyping \def\syst_helpers_recurse_content - {\csname\??recurseaction\recursedepth\expandafter\expandafter\expandafter\endcsname - \expandafter\expandafter\expandafter{\expandafter\recurselevel\expandafter}\expandafter{\recursedepth}} + {\csname\??recurseaction\the\outerrecurse\expandafter\expandafter\expandafter\endcsname + \expandafter\expandafter\expandafter{\expandafter\recurselevel\expandafter}\expandafter{\the\outerrecurse}} \unexpanded\def\syst_helpers_recurse_x#1#2% {\global\advance\outerrecurse \plusone - \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#2}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#2}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \expandafter\syst_helpers_recurse_indeed\expandafter1\expandafter{\number#1}} \unexpanded\def\syst_helpers_recurse_y#1#2% {\global\advance\outerrecurse \plusone - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \let\recurselevel\!!plusone - \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#2}% + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#2}% \syst_helpers_recurse_content - \expandafter\let\expandafter\recurselevel\csname\??recurseindex\recursedepth\endcsname + \expandafter\let\expandafter\recurselevel\csname\??recurseindex\the\outerrecurse\endcsname \global\advance\outerrecurse \minusone} -\unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 - {\global\advance\outerrecurse \plusone - \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel - \ifnum#3>\zerocount\relax - \ifnum#2<#1\relax - \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit - \else - \let\syst_helpers_stepwise_next\syst_helpers_stepwise_recurse - \fi - \else - \ifnum#3<\zerocount\relax - \ifnum#1<#2\relax - \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit - \else - \let\syst_helpers_stepwise_next\syst_helpers_stepwise_reverse - \fi - \else - \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit - \fi - \fi\normalexpanded{\syst_helpers_stepwise_next{\number#1}{\number#2}{\number#3}}} - \unexpanded\def\doloop#1% {\global\advance\outerrecurse \plusone - \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#1}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#1}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \let\endofloop\syst_helpers_loop \syst_helpers_loop1} % no \plusone else \recurselevel wrong -% faster - +% for instance: +% +% \unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 +% {\global\advance\outerrecurse \plusone +% \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}% +% \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel +% \ifnum#3>\zerocount\relax +% \ifnum#2<#1\relax +% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit +% \else +% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_recurse +% \fi +% \else +% \ifnum#3<\zerocount\relax +% \ifnum#1<#2\relax +% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit +% \else +% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_reverse +% \fi +% \else +% \let\syst_helpers_stepwise_next\syst_helpers_stepwise_exit +% \fi +% \fi\normalexpanded{\syst_helpers_stepwise_next{\number#1}{\number#2}{\number#3}}} +% +% faster: +% % \unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 % {\global\advance\outerrecurse \plusone -% \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}% -% \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel +% \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}% +% \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel % \csname @swr% % \ifnum#3>\zerocount % \ifnum#2<#1\else d\fi @@ -3831,17 +4435,19 @@ % \ifnum#1<#2\else r\fi % \fi\fi % \expandafter\endcsname\normalexpanded{{\number#1}{\number#2}{\number#3}}} - +% % \let\@swr \syst_helpers_stepwise_exit % \let\@swrd\syst_helpers_stepwise_recurse % \let\@swrr\syst_helpers_stepwise_reverse +% +% nicer: \installsystemnamespace{recursestepwise} \unexpanded\def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 {\global\advance\outerrecurse \plusone - \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}% - \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel \csname\??recursestepwise % we need the x in order to avoid the \relax that tex adds \ifnum#3>\zerocount @@ -3860,8 +4466,8 @@ % % \def\dostepwiserecurse#1#2#3#4% can be made faster by postponing #4 % {\global\advance\outerrecurse \plusone -% \global\expandafter\def\csname\??recurseaction\recursedepth\endcsname##1##2{#4}% -% \global\expandafter\let\csname\??recurseindex\recursedepth\endcsname\recurselevel +% \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1##2{#4}% +% \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recurselevel % \normalexpanded % {\ifnum#3>\zerocount % \ifnum#2<#1 @@ -3936,10 +4542,10 @@ \unexpanded\def\doloopoverlist#1#2% {\global\advance\outerrecurse\plusone - \expandafter\gdef\csname\??recurseaction\recursedepth\endcsname##1{\edef\recursestring{##1}#2}% - \expandafter\glet\csname\??recurseindex\recursedepth\endcsname\recursestring - \normalexpanded{\processcommalist[#1]{\expandafter\noexpand\csname\??recurseaction\recursedepth\endcsname}}% - \expandafter\let\expandafter\recursestring\csname\??recurseindex\recursedepth\endcsname + \expandafter\gdef\csname\??recurseaction\the\outerrecurse\endcsname##1{\edef\recursestring{##1}#2}% + \expandafter\glet\csname\??recurseindex \the\outerrecurse\endcsname\recursestring + \normalexpanded{\processcommalist[#1]{\expandafter\noexpand\csname\??recurseaction\the\outerrecurse\endcsname}}% + \expandafter\let\expandafter\recursestring\csname\??recurseindex\the\outerrecurse\endcsname \global\advance\outerrecurse\minusone} %D \macros @@ -4113,14 +4719,22 @@ \def\syst_helpers_check_if_assignment_else#1=#2#3\_e_o_p_{\if#2@}% -\unexpanded\def\doifelseassignment#1% expandable +\unexpanded\def\doifelseassignment#1% {\expandafter\syst_helpers_check_if_assignment_else\detokenize{#1}=@@\_e_o_p_ \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} -\let\doifassignmentelse\doifelseassignment +\unexpanded\def\doifelseassignmentcs#1#2#3% + {\expandafter\syst_helpers_check_if_assignment_else\detokenize{#1}=@@\_e_o_p_ + \expandafter#3% + \else + \expandafter#2% + \fi} + +\let\doifassignmentelse \doifelseassignment +\let\doifassignmentelsecs\doifelseassignmentcs \newif\ifassignment @@ -4415,16 +5029,14 @@ %D \def\doezomaarwat#1{....#1....} %D \stoptyping %D -%D A disadvantage of this approach is that the tokens that -%D form \type{#1} are fixed the the moment the argument is read -%D in. Normally this is no problem, but for instance verbatim -%D environments adapt the \CATCODES\ of characters and therefore +%D A disadvantage of this approach is that the tokens that form \type{#1} are fixed +%D the the moment the argument is read in. Normally this is no problem, but for +%D instance verbatim environments adapt the \CATCODES\ of characters and therefore %D are not always happy with already fixed tokens. %D -%D Another problem arises when the argument is grouped not by -%D \type{{}} but by \type{\bgroup} and \type{\egroup}. Such an -%D argument fails, because the \type{\bgroup} is een as the -%D argument (which is quite normal). +%D Another problem arises when the argument is grouped not by \type {{}} but by +%D \type {\bgroup} and \type {\egroup}. Such an argument fails, because the \type +%D {\bgroup} is een as the argument (which is quite normal). %D %D The next macro offers a solution for both unwanted %D situations: @@ -4454,9 +5066,8 @@ %D .......... \rightword{the right way} %D \stoptyping %D -%D Here \TEX\ typesets \type{\bf the right way} unbreakable -%D at the end of the line. The solution mentioned before does -%D not work here. We also handle +%D Here \TEX\ typesets \type {\bf the right way} unbreakable at the end of the line. +%D The solution mentioned before does not work here. We also handle %D %D \starttyping %D to be \bold{bold} or not, that's the question @@ -4485,80 +5096,150 @@ % \afterassignment\m_syst_helpers_handle_group_before % \let\next=} -\unexpanded\def\syst_helpers_handle_group_normal#1#2% +% \unexpanded\def\syst_helpers_handle_group_normal#1#2% +% {\bgroup +% \def\m_syst_helpers_handle_group_before{#1}% +% \def\m_syst_helpers_handle_group_after {#2}% +% \afterassignment\m_syst_helpers_handle_group_normal_before +% \let\next=} +% +% \def\m_syst_helpers_handle_group_normal_before +% {\bgroup +% \m_syst_helpers_handle_group_before +% \bgroup +% \aftergroup\m_syst_helpers_handle_group_normal_after} +% +% \def\m_syst_helpers_handle_group_normal_after +% {\m_syst_helpers_handle_group_after +% \egroup +% \egroup} +% +% \unexpanded\def\syst_helpers_handle_group_simple#1#2% no inner group (so no kerning interference) +% {\bgroup +% \def\m_syst_helpers_handle_group_before{#1}% +% \def\m_syst_helpers_handle_group_after {#2}% +% \afterassignment\m_syst_helpers_handle_group_simple_before +% \let\next=} +% +% \def\m_syst_helpers_handle_group_simple_before +% {\bgroup +% \aftergroup\m_syst_helpers_handle_group_simple_after +% \m_syst_helpers_handle_group_before} +% +% \def\m_syst_helpers_handle_group_simple_after +% {\m_syst_helpers_handle_group_after +% \egroup}% +% +% \unexpanded\def\syst_helpers_handle_group_pickup#1#2#3% no inner group (so no kerning interference) +% {\bgroup +% \def\m_syst_helpers_handle_group_before{#1}% +% \def\m_syst_helpers_handle_group_after {#2\egroup#3}% +% \afterassignment\m_syst_helpers_handle_group_pickup_before +% \let\next=} +% +% \def\m_syst_helpers_handle_group_pickup_before +% {\bgroup +% \aftergroup\m_syst_helpers_handle_group_after +% \m_syst_helpers_handle_group_before} +% +% \unexpanded\def\syst_helpers_handle_group_nop +% {\ifnum\currentgrouptype=\semisimplegroupcode +% \expandafter\syst_helpers_handle_group_nop_a +% \else +% \expandafter\syst_helpers_handle_group_nop_b +% \fi} +% +% \def\syst_helpers_handle_group_nop_a#1#2% +% {\def\m_syst_helpers_handle_group_after{#2\endgroup}% +% \begingroup +% \aftergroup\m_syst_helpers_handle_group_after +% #1} +% +% \def\syst_helpers_handle_group_nop_b#1#2% +% {\def\m_syst_helpers_handle_group_after{#2\egroup}% +% \bgroup +% \aftergroup\m_syst_helpers_handle_group_after +% #1} + +\unexpanded\def\syst_helpers_handle_group_nop + {\ifnum\currentgrouptype=\semisimplegroupcode + \expandafter\syst_helpers_handle_group_nop_a + \else + \expandafter\syst_helpers_handle_group_nop_b + \fi} + +\def\syst_helpers_handle_group_nop_a + {\begingroup + \aftergroup\m_syst_helpers_handle_group_a + \aftergroup\endgroup + \m_syst_helpers_handle_group_b} + +\def\syst_helpers_handle_group_nop_b + {\bgroup + \aftergroup\m_syst_helpers_handle_group_a + \aftergroup\egroup + \m_syst_helpers_handle_group_b} + +\unexpanded\def\syst_helpers_handle_group_normal {\bgroup - \def\m_syst_helpers_handle_group_before{#1}% - \def\m_syst_helpers_handle_group_after {#2}% \afterassignment\m_syst_helpers_handle_group_normal_before \let\next=} \def\m_syst_helpers_handle_group_normal_before {\bgroup - \m_syst_helpers_handle_group_before + \m_syst_helpers_handle_group_b \bgroup - \aftergroup\m_syst_helpers_handle_group_normal_after} - -\def\m_syst_helpers_handle_group_normal_after - {\m_syst_helpers_handle_group_after - \egroup - \egroup} - -% keep: -% -% \unexpanded\def\syst_helpers_handle_group_simple#1#2% no inner group (so no kerning interference) -% {\bgroup -% %def\m_syst_helpers_handle_group_before{\bgroup#1\aftergroup\m_syst_helpers_handle_group_after}% interferes -% \def\m_syst_helpers_handle_group_before{\bgroup\aftergroup\m_syst_helpers_handle_group_after#1}% -% \def\m_syst_helpers_handle_group_after {#2\egroup}% -% \afterassignment\m_syst_helpers_handle_group_before -% \let\next=} + \aftergroup\m_syst_helpers_handle_group_a + \aftergroup\egroup + \aftergroup\egroup} -\unexpanded\def\syst_helpers_handle_group_simple#1#2% no inner group (so no kerning interference) +\unexpanded\def\syst_helpers_handle_group_simple% no inner group (so no kerning interference) {\bgroup - \def\m_syst_helpers_handle_group_before{#1}% - \def\m_syst_helpers_handle_group_after {#2}% \afterassignment\m_syst_helpers_handle_group_simple_before \let\next=} \def\m_syst_helpers_handle_group_simple_before {\bgroup \aftergroup\m_syst_helpers_handle_group_simple_after - \m_syst_helpers_handle_group_before} + \m_syst_helpers_handle_group_b} \def\m_syst_helpers_handle_group_simple_after - {\m_syst_helpers_handle_group_after + {\m_syst_helpers_handle_group_a \egroup}% -\unexpanded\def\syst_helpers_handle_group_pickup#1#2#3% no inner group (so no kerning interference) +\unexpanded\def\syst_helpers_handle_group_pickup% no inner group (so no kerning interference) {\bgroup - \def\m_syst_helpers_handle_group_before{#1}% - \def\m_syst_helpers_handle_group_after {#2\egroup#3}% \afterassignment\m_syst_helpers_handle_group_pickup_before \let\next=} \def\m_syst_helpers_handle_group_pickup_before {\bgroup - \aftergroup\m_syst_helpers_handle_group_after - \m_syst_helpers_handle_group_before} + \aftergroup\m_syst_helpers_handle_group_a + \aftergroup\egroup + \aftergroup\m_syst_helpers_handle_group_p + \m_syst_helpers_handle_group_b} -\unexpanded\def\syst_helpers_handle_group_nop +\unexpanded\def\syst_helpers_handle_group_nop_x {\ifnum\currentgrouptype=\semisimplegroupcode - \expandafter\syst_helpers_handle_group_nop_a + \begingroup + \aftergroup\endgroup \else - \expandafter\syst_helpers_handle_group_nop_b - \fi} + \bgroup + \aftergroup\egroup + \fi + \m_syst_helpers_handle_group_b} -\def\syst_helpers_handle_group_nop_a#1#2% - {\def\m_syst_helpers_handle_group_after{#2\endgroup}% - \begingroup - \aftergroup\m_syst_helpers_handle_group_after - #1} +\unexpanded\def\syst_helpers_handle_group_normal_x + {\bgroup + \afterassignment\m_syst_helpers_handle_group_normal_before_x + \let\next=} -\def\syst_helpers_handle_group_nop_b#1#2% - {\def\m_syst_helpers_handle_group_after{#2\egroup}% +\def\m_syst_helpers_handle_group_normal_before_x + {\bgroup + \m_syst_helpers_handle_group_b \bgroup - \aftergroup\m_syst_helpers_handle_group_after - #1} + \aftergroup\egroup + \aftergroup\egroup} %D I considered it a nuisance that %D @@ -4567,25 +5248,61 @@ %D {as grass} %D \stoptyping %D -%D was not interpreted as one would expect. This is due to the -%D fact that \type{\futurelet} obeys blank spaces, and a -%D line||ending token is treated as a blank space. So the final -%D implementation became: +%D was not interpreted as one would expect. This is due to the fact that \type +%D {\futurelet} obeys blank spaces, and a line||ending token is treated as a blank +%D space. So the final implementation became: + +% \unexpanded\def\groupedcommand#1#2% +% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}} +% +% \unexpanded\def\groupedcommandcs#1#2% +% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}} +% +% \unexpanded\def\triggergroupedcommand#1% +% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{}}{\syst_helpers_handle_group_nop{#1}{}}} +% +% \unexpanded\def\triggergroupedcommandcs#1% +% {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{}}{\syst_helpers_handle_group_nop{#1}{}}} +% +% \unexpanded\def\simplegroupedcommand#1#2% +% {\doifelsenextbgroup{\syst_helpers_handle_group_simple{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}} +% +% \unexpanded\def\pickupgroupedcommand#1#2#3% +% {\doifelsenextbgroup{\syst_helpers_handle_group_pickup{#1}{#2}{#3}}{\syst_helpers_handle_group_nop{#1}{#2}}} \unexpanded\def\groupedcommand#1#2% - {\doifelsenextbgroup{\syst_helpers_handle_group_normal{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}} + {\def\m_syst_helpers_handle_group_b{#1}% + \def\m_syst_helpers_handle_group_a{#2}% + \doifelsenextbgroupcs\syst_helpers_handle_group_normal\syst_helpers_handle_group_nop} + +\unexpanded\def\groupedcommandcs#1#2% + {\let\m_syst_helpers_handle_group_b#1% + \let\m_syst_helpers_handle_group_a#2% + \doifelsenextbgroupcs\syst_helpers_handle_group_normal\syst_helpers_handle_group_nop} \unexpanded\def\simplegroupedcommand#1#2% - {\doifelsenextbgroup{\syst_helpers_handle_group_simple{#1}{#2}}{\syst_helpers_handle_group_nop{#1}{#2}}} + {\def\m_syst_helpers_handle_group_b{#1}% + \def\m_syst_helpers_handle_group_a{#2}% + \doifelsenextbgroupcs\syst_helpers_handle_group_simple\syst_helpers_handle_group_nop} \unexpanded\def\pickupgroupedcommand#1#2#3% - {\doifelsenextbgroup{\syst_helpers_handle_group_pickup{#1}{#2}{#3}}{\syst_helpers_handle_group_nop{#1}{#2}}} + {\def\m_syst_helpers_handle_group_b{#1}% + \def\m_syst_helpers_handle_group_a{#2}% + \def\m_syst_helpers_handle_group_p{#2}% + \doifelsenextbgroupcs\syst_helpers_handle_group_pickup\syst_helpers_handle_group_nop} -%D Users should be aware of the fact that grouping can -%D interfere with ones paragraph settings that are executed -%D after the paragraph is closed. One should therefore -%D explictly close the paragraph with \type{\par}, else the -%D settings will be forgotten and not applied. So it's: +\unexpanded\def\triggergroupedcommand#1% + {\def\m_syst_helpers_handle_group_b{#1}% + \doifelsenextbgroupcs\syst_helpers_handle_group_normal_x\syst_helpers_handle_group_nop_x} + +\unexpanded\def\triggergroupedcommandcs#1% + {\let\m_syst_helpers_handle_group_b#1% + \doifelsenextbgroupcs\syst_helpers_handle_group_normal_x\syst_helpers_handle_group_nop_x} + +%D Users should be aware of the fact that grouping can interfere with ones paragraph +%D settings that are executed after the paragraph is closed. One should therefore +%D explictly close the paragraph with \type {\par}, else the settings will be +%D forgotten and not applied. So it's: %D %D \starttyping %D \def\BoldRaggedCenter% @@ -5392,7 +6109,7 @@ \fi} \unexpanded\def\globalprocesscommalist[#1]#2% - {\global\let\m_syst_helpers_comma_list_command_global#2% + {\glet\m_syst_helpers_comma_list_command_global#2% \expandafter\syst_helpers_comma_list_command_global_step#1,],} %D \macros @@ -5454,9 +6171,9 @@ \unexpanded\def\swapcounts#1#2{\c_syst_helpers_swapped #1\relax#1#2\relax#2\c_syst_helpers_swapped} \unexpanded\def\swapmacros#1#2{\let\m_syst_helpers_swapped#1\let #1#2\let #2\m_syst_helpers_swapped} -\unexpanded\def\globalswapdimens#1#2{\d_syst_helpers_swapped #1\global #1#2\global #2\d_syst_helpers_swapped} -\unexpanded\def\globalswapcounts#1#2{\c_syst_helpers_swapped #1\global #1#2\global #2\c_syst_helpers_swapped} -\unexpanded\def\globalswapmacros#1#2{\let\m_syst_helpers_swapped#1\global\let#1#2\global\let#2\m_syst_helpers_swapped} +\unexpanded\def\globalswapdimens#1#2{\d_syst_helpers_swapped #1\global#1#2\global#2\d_syst_helpers_swapped} +\unexpanded\def\globalswapcounts#1#2{\c_syst_helpers_swapped #1\global#1#2\global#2\c_syst_helpers_swapped} +\unexpanded\def\globalswapmacros#1#2{\let\m_syst_helpers_swapped#1\glet #1#2\glet #2\m_syst_helpers_swapped} %D \macros %D {pushmacro,popmacro} @@ -5481,11 +6198,11 @@ % \expandafter\newcount\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname % \fi % \global\advance\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname \plusone -% \global\expandafter\let\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1} +% \expandafter\glet\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1} % % \unexpanded\def\globalpopmacro#1% % {\xdef\m_syst_helpers_push_macro{\string#1}% -% \global\expandafter\let\expandafter#1\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname +% \expandafter\glet\expandafter#1\csname\the\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname % \global\advance\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname \minusone} % % \unexpanded\def\localpushmacro#1% this one can be used to push a value over an \egroup @@ -5494,7 +6211,7 @@ % \expandafter\newcount\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname % \fi % \global\advance\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname \plusone -% \global\expandafter\let\csname\the\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1} +% \expandafter\glet\csname\the\csname\??localpushedmacro\m_syst_helpers_push_macro\endcsname\m_syst_helpers_push_macro\endcsname#1} % % \unexpanded\def\localpopmacro#1% % {\xdef\m_syst_helpers_push_macro{\string#1}% @@ -5505,6 +6222,8 @@ % \let\popmacro \localpopmacro % % slightly faster but more important: less tracing +% +% possible optimization \installmacrostack\foo: \syst_push_foo \syst_pop_foo \let\m_syst_helpers_push_macro\empty @@ -5525,7 +6244,7 @@ \else \syst_helpers_push_macro_new_global \fi - \global\expandafter\let\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1} + \expandafter\glet\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1} \unexpanded\def\localpushmacro#1% this one can be used to push a value over an \egroup {\xdef\m_syst_helpers_push_macro{\csstring#1}% @@ -5534,13 +6253,13 @@ \else \syst_helpers_push_macro_new_local \fi - \global\expandafter\let\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1} + \expandafter\glet\csname\the\lastnamedcs\m_syst_helpers_push_macro\endcsname#1} \unexpanded\def\globalpopmacro#1% {\xdef\m_syst_helpers_push_macro{\csstring#1}% \c_syst_helpers_pop_count\csname\??globalpushedmacro\m_syst_helpers_push_macro\endcsname \global\advance\lastnamedcs \minusone - \global\expandafter\let\expandafter#1\csname\the\c_syst_helpers_pop_count\m_syst_helpers_push_macro\endcsname} + \expandafter\glet\expandafter#1\csname\the\c_syst_helpers_pop_count\m_syst_helpers_push_macro\endcsname} \unexpanded\def\localpopmacro#1% {\xdef\m_syst_helpers_push_macro{\csstring#1}% @@ -6060,7 +6779,7 @@ \unexpanded\def\processassignlist#1[#2]#3% {\def\syst_helpers_process_assign_list_assign[##1=##2=##3]% - {\doifnot{##3}\relax{#3{##1}}}% + {\doif{##3}\relax{#3{##1}}}% \def\syst_helpers_process_assign_list_step##1% {\syst_helpers_process_assign_list_assign[##1==\relax]}% \processcommalist[#2]\syst_helpers_process_assign_list_step} @@ -6996,14 +7715,6 @@ {\unprotect \syst_helpers_unprotected} -% awaiting the definitive implementation - -% \ifdefined\resettimer \else -% \let\resettimer \relax -% \newcount\elapsedtime -% \fi -% \def\elapsedseconds{\expandafter\withoutpt\the\dimexpr\elapsedtime sp\relax} - \let\resettimer \clf_resettimer \let\elapsedtime \clf_elapsedtime \let\elapsedseconds \elapsedtime @@ -7172,6 +7883,12 @@ \unexpanded\def\signalcharacter{\char\zerocount} % \zwj +% \unexpanded\def\signalcharacter +% {\scratchcounter\normallanguage +% \normallanguage\zerocount +% \char\zerocount +% \normallanguage\scratchcounter} + %D A few secial variants of commands defined here. Some more will be moved here (e.g. %D from table modules. @@ -7486,3 +8203,23 @@ % \edef\tempstring{\the#1}% % \tx\ttbf\string#1: \tttf\meaning\tempstring % \endgroup} + +%D Not needed now, but more efficient that expanding +% +% \chardef\_E_O_T_0 +% +% \unexpanded\def\doifelsetokens#1% +% {\dodoifelsetokens#1\_E_O_T_\_e_o_t_} +% +% \def\dodoifelsetokens#1#2\_e_o_t_ +% {\ifx#1\_E_O_T_ +% \expandafter\secondoftwoarguments +% \else +% \expandafter\firstoftwoarguments +% \fi} +% +% \def\emptytokscondition#1% +% {\doemptytokscondition#1\_E_O_T_\_e_o_t_} +% +% \def\doemptytokscondition#1#2\_e_o_t_ +% {\ifx#1\_E_O_T_} diff --git a/tex/context/base/mkiv/syst-cmp.lua b/tex/context/base/mkiv/syst-cmp.lua new file mode 100644 index 000000000..67595d043 --- /dev/null +++ b/tex/context/base/mkiv/syst-cmp.lua @@ -0,0 +1,8 @@ +if not modules then modules = { } end modules ['syst-cmp'] = { + version = 1.001, + comment = "companion to syst-cmp.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + diff --git a/tex/context/base/mkiv/syst-cmp.mkiv b/tex/context/base/mkiv/syst-cmp.mkiv new file mode 100644 index 000000000..a5ebdd8e3 --- /dev/null +++ b/tex/context/base/mkiv/syst-cmp.mkiv @@ -0,0 +1,22 @@ +%D \module +%D [ file=syst-cmp, +%D version=2018.12.05, +%D title=\CONTEXT\ System Macros, +%D subtitle=Compatibility, +%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. + +%D Some code that has been laying around for generic compatibility is (and will be) +%D moved here, for instance because tikz needs it. At some point I will make an +%D indirect interface for generic code (if needed). + +\registerctxluafile{syst-cmp}{} + +\unprotect + +\protect \endinput diff --git a/tex/context/base/mkiv/syst-ini.mkiv b/tex/context/base/mkiv/syst-ini.mkiv index 4b5cc616b..7ce48c79f 100644 --- a/tex/context/base/mkiv/syst-ini.mkiv +++ b/tex/context/base/mkiv/syst-ini.mkiv @@ -19,116 +19,124 @@ %D Characters can have special states, that can be triggered by setting their %D category coded. Some are preset, others are to be set as soon as possible, %D otherwise we cannot define any useful macros. - -%catcode`\^^@ = 9 % ascii null is ignored -%catcode`\\ = 0 % backslash is TeX escape character - -\catcode`\{ = 1 % left brace is begin-group character -\catcode`\} = 2 % right brace is end-group character -\catcode`\$ = 3 % dollar sign is math shift -\catcode`\& = 4 % ampersand is alignment tab -\catcode`\# = 6 % hash mark is macro parameter character -\catcode`\^ = 7 % circumflex and uparrow are for superscripts -\catcode`\_ = 8 % underline and downarrow are for subscripts -\catcode`\^^I = 10 % ascii tab is a blank space - -%catcode`\^^M = 5 % ascii return is end-line -%catcode`\% = 14 % percent sign is comment character -%catcode`\ = 10 % ascii space is blank space -%catcode`\^^? = 15 % ascii delete is invalid - -\catcode`\~ = 13 % tilde is active -\catcode`\^^L = 13 % ascii form-feed - -%catcode`\A = 11 -%....... -%catcode`\Z = 11 - -%catcode`\a = 11 -%....... -%catcode`\z = 11 - -\def ^^L{\par} -\def\^^M{\ } % control = control -\def\^^I{\ } % same for - -%D In \CONTEXT, we simply ignore end||of||file tokens: - -\catcode`\^^Z=9 - -%D It makes sense to know what engine we're running so let's try to deduce it. - -\chardef\unknownengine = 0 -\chardef\pdftexengine = 1 -\chardef\xetexengine = 2 -\chardef\luatexengine = 3 - -\chardef\statuswrite = 128 - -\ifx\directlua\undefined - \ifx\XeTeXversion\undefined - \ifx\pdftexversion\undefined - \let\texengine\unknownengine - \else - \let\texengine\pdftexengine - \fi - \else - \let\texengine\xetexengine - \fi -\else - \let\texengine\luatexengine -\fi - -\ifnum\texengine=\luatexengine - % for historic reasons we keep some mkii code around -\else - \immediate\write\statuswrite{>>>} - \immediate\write\statuswrite{>>> only luatex is supported} - \immediate\write\statuswrite{>>>} - \let\dump\relax - \expandafter\end -\fi +%D +%D First we define a bunch of constants. Normally we would \type {\setconstant} +%D but we're prestine and have no macros defined yet. Abstraction also makes it +%D possible to avoid the \type {^^} in the input. + +\chardef\escapecatcode 0 +\chardef\begingroupcatcode 1 +\chardef\endgroupcatcode 2 +\chardef\mathshiftcatcode 3 +\chardef\alignmentcatcode 4 +\chardef\endoflinecatcode 5 +\chardef\parametercatcode 6 +\chardef\superscriptcatcode 7 +\chardef\subscriptcatcode 8 +\chardef\ignorecatcode 9 +\chardef\spacecatcode 10 +\chardef\lettercatcode 11 +\chardef\othercatcode 12 % finally obsolete: \let\other \othercatcode +\chardef\activecatcode 13 % finally obsolete: \let\active\activecatcode +\chardef\commentcatcode 14 +\chardef\invalidcatcode 15 + +%chardef\zeroasciicode 0 +\chardef\tabasciicode 9 +\chardef\newlineasciicode 10 % don't confuse this one with \endoflineasciicode +\chardef\formfeedasciicode 12 +\chardef\endoflineasciicode 13 % somewhat messy but this can be the active \par +\chardef\endoffileasciicode 26 +\chardef\spaceasciicode 32 +\chardef\exclamationmarkasciicode 33 % ! used in namespace protection +\chardef\doublequoteasciicode 34 % " +\chardef\hashasciicode 35 +\chardef\dollarasciicode 36 +\chardef\commentasciicode 37 +\chardef\ampersandasciicode 38 +\chardef\singlequoteasciicode 39 % ' +\chardef\primeasciicode 39 % ' +\chardef\leftparentasciicode 40 +\chardef\rightparentasciicode 41 +\chardef\hyphenasciicode 45 +\chardef\forwardslashasciicode 47 % / +\chardef\colonasciicode 58 +\chardef\lessthanasciicode 60 % < used as alternative verbatim { +\chardef\morethanasciicode 62 % > used as alternative verbatim } +\chardef\questionmarkasciicode 63 % ? used in namespace protection +\chardef\atsignasciicode 64 % @ used in namespace protection +\chardef\backslashasciicode 92 % `\\ +\chardef\circumflexasciicode 94 +\chardef\underscoreasciicode 95 +\chardef\leftbraceasciicode 123 % `\{ +\chardef\barasciicode 124 % `\| +\chardef\rightbraceasciicode 125 % `\} +\chardef\tildeasciicode 126 % `\~ +\chardef\delasciicode 127 + +%catcode\zeroasciicode \ignorecatcode % `\^^@ ascii null is ignored +\catcode\tabasciicode \spacecatcode % `\^^I ascii tab is a blank space +\catcode\formfeedasciicode \activecatcode % `\^^L ascii form-feed (active, set later) +%catcode\endoflineasciicode \endoflinecatcode % `\^^M ascii return is end-line +\catcode\endoffileasciicode \ignorecatcode % `\^^Z endoffile (ignored in ConTeXt) +%catcode\spaceasciicode \spacecatcode % `\ ascii space is blank space +\catcode\hashasciicode \parametercatcode % `\# hash mark is macro parameter character +\catcode\dollarasciicode \mathshiftcatcode % `\$ dollar sign is math shift +%catcode\commentasciicode \commentcatcode % `\% percent sign is comment character +\catcode\ampersandasciicode \alignmentcatcode % `\& ampersand is alignment tab +%catcode\backslashasciicode \escapecatcode % `\\ backslash is TeX escape character +\catcode\circumflexasciicode \superscriptcatcode % `\^ circumflex and uparrow are for superscripts +\catcode\underscoreasciicode \subscriptcatcode % `\_ underline and downarrow are for subscripts +\catcode\leftbraceasciicode \begingroupcatcode % `\{ left brace is begin-group character +\catcode\rightbraceasciicode \endgroupcatcode % `\} right brace is end-group character +\catcode\tildeasciicode \activecatcode % `\~ tilde is active +%catcode\delasciicode \invalidcatcode % `\^^? ascii delete is invalid + +\chardef\statuswrite 128 %D Initialization of primitives. -\directlua 0 { % this info is stored in the format - lua.name[0] = "main ctx instance" +\directlua { + local baseprimitives = tex.extraprimitives("core","tex") + local moreprimitives = tex.extraprimitives("etex","luatex") - local coreprimitives = tex.extraprimitives("core") - local texprimitives = tex.extraprimitives("tex") - local etexprimitives = tex.extraprimitives("etex") - local luatexprimitives = tex.extraprimitives("luatex") + tex.enableprimitives("",moreprimitives) - tex.enableprimitives("",etexprimitives) - tex.enableprimitives("",luatexprimitives) + tex.enableprimitives("normal",baseprimitives) + tex.enableprimitives("normal",moreprimitives) - tex.enableprimitives("normal",coreprimitives) - tex.enableprimitives("normal",texprimitives) - tex.enableprimitives("normal",etexprimitives) - tex.enableprimitives("normal",luatexprimitives) + function tex.enableprimitives() end } -%D \ETEX\ has a not so handy way of telling you the version number, i.e. the revision -%D number has a period in it: +\def\space{ } +\def\empty{} + +\letcharcode \formfeedasciicode \par % \def ^^L{\par} formfeed +\letcharcode \tildeasciicode \ % tilde +\letcharcode \spaceasciicode \space % space -\def\gobbleoneargument#1{} % will be defined later on anyway +\expandafter\def\csname\Uchar\tabasciicode \endcsname {\ } % \def\^^I{\ } tab +\expandafter\def\csname\Uchar\formfeedasciicode \endcsname {\par} % \def\^^L{\par} formfeed +\expandafter\def\csname\Uchar\endoflineasciicode\endcsname {\ } % \def\^^M{\ } return -\mathchardef\etexversion = \numexpr\eTeXversion*100+\expandafter\gobbleoneargument\eTeXrevision\relax +%D For now: + +\def\gobbleoneargument#1{} % will be defined later on anyway %D First we define a simplified version of the \CONTEXT\ protection mechanism. %D Later we will implement a better variant. \def\unprotect {\edef\protect - {\catcode`@=\the\catcode`@\relax - \catcode`?=\the\catcode`?\relax - \catcode`!=\the\catcode`!\relax - \catcode`_=\the\catcode`_\relax + {\catcode\atsignasciicode \the\catcode\atsignasciicode \relax + \catcode\exclamationmarkasciicode\the\catcode\exclamationmarkasciicode\relax + \catcode\questionmarkasciicode \the\catcode\questionmarkasciicode \relax + \catcode\underscoreasciicode \the\catcode\underscoreasciicode \relax \let\protect\relax}% - \catcode`@=11 - \catcode`?=11 - \catcode`!=11 - \catcode`_=11 } + \catcode\atsignasciicode \lettercatcode + \catcode\exclamationmarkasciicode\lettercatcode + \catcode\questionmarkasciicode \lettercatcode + \catcode\underscoreasciicode \lettercatcode} \let\protect\relax @@ -169,13 +177,13 @@ \countdef \c_syst_max_allocated_read = 55 \c_syst_max_allocated_read = 16 \countdef \c_syst_min_allocated_language = 56 \c_syst_min_allocated_language = 0 \countdef \c_syst_max_allocated_language = 57 \c_syst_max_allocated_language = 255 -\countdef \c_syst_max_allocated_insert = 58 \c_syst_max_allocated_insert = 254 -\countdef \c_syst_min_allocated_insert = 59 \c_syst_min_allocated_insert = 128 +\countdef \c_syst_min_allocated_insert = 58 \c_syst_min_allocated_insert = 128 +\countdef \c_syst_max_allocated_insert = 59 \c_syst_max_allocated_insert = 254 \countdef \c_syst_min_allocated_family = 60 \c_syst_min_allocated_family = 128 \countdef \c_syst_max_allocated_family = 61 \c_syst_max_allocated_family = 255 -\countdef \c_syst_min_allocated_attribute = 62 \c_syst_min_allocated_attribute = 1024 % 127-1023 : private -\countdef \c_syst_min_allocated_write = 63 \c_syst_min_allocated_write = 0 % luatex >= 0.82 -\countdef \c_syst_max_allocated_write = 64 \c_syst_max_allocated_write = 127 % luatex >= 0.82 +\countdef \c_syst_min_allocated_attribute = 62 \c_syst_min_allocated_attribute = 1024 % 0-1023 : private +\countdef \c_syst_min_allocated_write = 63 \c_syst_min_allocated_write = 0 +\countdef \c_syst_max_allocated_write = 64 \c_syst_max_allocated_write = 127 \countdef \c_syst_last_allocated_count = 32 \c_syst_last_allocated_count = \c_syst_min_allocated_register \countdef \c_syst_last_allocated_dimen = 33 \c_syst_last_allocated_dimen = \c_syst_min_allocated_register @@ -212,10 +220,10 @@ % A few traditional allocations (these might go): -\countdef \count@ = 255 % hm, used in \newif .. todo: replace it there -\dimendef \dimen@ = 0 -\dimendef \dimen@i = 1 % global only -\dimendef \dimen@ii = 2 +\countdef \count@ 255 % hm, used in \newif .. todo: replace it there +\dimendef \dimen@ 0 +\dimendef \dimen@i 1 % global only +\dimendef \dimen@ii 2 %D So, effectively we start allocating from 256 and upwards. The inserts sit in the %D range 128 upto 254. Page numbers use the counters 0 upto 9 and the pagebox is @@ -258,8 +266,7 @@ % %D The next definitions are really needed (in \CONTEXT): -%newlinechar=10 \def\outputnewlinechar{\rawcharacter{10}} -\newlinechar=10 \edef\outputnewlinechar{^^J} +\newlinechar\newlineasciicode \edef\outputnewlinechar{\Uchar\newlineasciicode} % {^^J} %D One reason to start high with allocation is that it permits us to allocate %D consecutive ranges more easily, for instance if for \MPLIB\ we want to allocate a @@ -268,7 +275,8 @@ %D as all engines now provide many registers we removed all traces. \ifdefined\writestatus \else - \normalprotected\def\writestatus#1#2{\immediate\write\statuswrite{#1: #2}} + %\normalprotected\def\writestatus#1#2{\immediate\write\statuswrite{#1: #2}} + \normalprotected\def\writestatus#1#2{\message{#1: #2}} \fi \def\syst_basics_allocate_yes#1#2#3#4#5% last class method max name @@ -304,6 +312,7 @@ %D 128-1023 are private and should not be touched. \let\attributeunsetvalue\c_syst_min_counter_value % used to be \minusone + \normalprotected\def\newattribute{\syst_basics_allocate\c_syst_last_allocated_attribute\attribute\attributedef\c_syst_max_allocated_register} %D Not used by \CONTEXT\ but for instance \PICTEX\ needs it. It's a trick to force @@ -344,6 +353,10 @@ \newtoks \scratchtoksfour \newtoks \scratchtoksfive \newtoks \scratchtokssix \newbox \scratchboxfour \newbox \scratchboxfive \newbox \scratchboxsix +\newcount\globalscratchcounterone +\newcount\globalscratchcountertwo +\newcount\globalscratchcounterthree + %D \macros %D {tempstring} @@ -395,19 +408,19 @@ %D More allocations: -\newskip \zeroskip \zeroskip = 0pt plus 0pt minus 0pt -\newdimen \zeropoint \zeropoint = 0pt -\newdimen \onepoint \onepoint = 1pt -\newdimen \halfapoint \halfapoint = 0.5pt -\newdimen \maxdimen \maxdimen = 16383.99999pt -\newcount \maxcount \maxcount = 2147483647 -\newdimen \onebasepoint \onebasepoint = 1bp -\newdimen \scaledpoint \scaledpoint = 1sp -\newdimen \thousandpoint \thousandpoint = 1000pt -\newmuskip\zeromuskip \zeromuskip = 0mu -\newmuskip\onemuskip \onemuskip = 1mu +\newskip \zeroskip \zeroskip 0pt plus 0pt minus 0pt +\newdimen \zeropoint \zeropoint 0pt +\newdimen \onepoint \onepoint 1pt +\newdimen \halfapoint \halfapoint 0.5pt +\newdimen \maxdimen \maxdimen 16383.99999pt +\newcount \maxcount \maxcount 2147483647 +\newdimen \onebasepoint \onebasepoint 1bp +\newdimen \scaledpoint \scaledpoint 1sp +\newdimen \thousandpoint \thousandpoint 1000pt +\newmuskip\zeromuskip \zeromuskip 0mu +\newmuskip\onemuskip \onemuskip 1mu -\newmuskip\muquad \muquad = 18mu +\newmuskip\muquad \muquad 18mu \let\points \onepoint \let\halfpoint\halfapoint @@ -416,32 +429,35 @@ %D And even more: (todo: countdefs 60+) -%newcount \minusone \minusone = -1 -\newcount \minustwo \minustwo = -2 -%chardef \zerocount = 0 -%chardef \plusone = 1 -\chardef \plustwo = 2 -\chardef \plusthree = 3 -\chardef \plusfour = 4 -\chardef \plusfive = 5 -\chardef \plussix = 6 -\chardef \plusseven = 7 -\chardef \pluseight = 8 -\chardef \plusnine = 9 -\chardef \plusten = 10 -\chardef \plussixteen = 16 -\chardef \plushundred = 100 -\chardef \plustwohundred = 200 -\chardef \pluscxxvii = 127 -\chardef \pluscxxviii = 128 -\chardef \pluscclv = 255 -\chardef \pluscclvi = 256 -\chardef \plusthousand = 1000 -\chardef \plustenthousand = 10000 -\chardef \plustwentythousand = 20000 -\chardef \medcard = 32768 -\chardef \maxcard = 65536 % pdftex has less mathchars -\chardef \maxcardminusone = 65535 +%newcount\minusone \minusone -1 +\newcount\minustwo \minustwo -2 +%chardef \zerocount 0 +%chardef \plusone 1 +\chardef \plustwo 2 +\chardef \plusthree 3 +\chardef \plusfour 4 +\chardef \plusfive 5 +\chardef \plussix 6 +\chardef \plusseven 7 +\chardef \pluseight 8 +\chardef \plusnine 9 +\chardef \plusten 10 +\chardef \plussixteen 16 +\chardef \plusfifty 50 +\chardef \plushundred 100 +\chardef \plusonehundred 100 +\chardef \plustwohundred 200 +\chardef \plusfivehundred 500 +\chardef \pluscxxvii 127 +\chardef \pluscxxviii 128 +\chardef \pluscclv 255 +\chardef \pluscclvi 256 +\chardef \plusthousand 1000 +\chardef \plustenthousand 10000 +\chardef \plustwentythousand 20000 +\chardef \medcard 32768 +\chardef \maxcard 65536 % pdftex has less mathchars +\chardef \maxcardminusone 65535 %D \macros %D {doubleexpandafter,tripleexpandafter,expanded,startexpanded} @@ -462,8 +478,8 @@ \def\unvoidbox{\unhbox\voidbox} \def\emptybox {\box \voidbox} % used in initializations so no attributes -\def\emptyvbox{\normalvbox{}} % no copy as we need to set attributes -\def\emptyhbox{\normalhbox{}} % no copy as we need to set attributes +\def\emptyvbox{\normalvpack{}} % no copy as we need to set attributes +\def\emptyhbox{\normalhpack{}} % no copy as we need to set attributes \let\leavevmode\unvoidbox % we prefer to use \dontleavehmode @@ -506,21 +522,47 @@ %D creates \type {\footrue}, \type {\foofalse} to go with \type {\iffoo}. %D \stopnarrower -\normalprotected\def\newif#1% - {\count@\escapechar - \escapechar\minusone - \expandafter\expandafter\expandafter\def\@if #1{true}{\let#1\iftrue }% - \expandafter\expandafter\expandafter\def\@if#1{false}{\let#1\iffalse}% - \@if#1{false}% the condition starts out false - \escapechar\count@} - -\def\@if#1#2% - {\csname\expandafter\if@\string#1#2\endcsname} +% \normalprotected\def\newif#1% +% {\count@\escapechar +% \escapechar\minusone +% \expandafter\expandafter\expandafter\def\new_if #1{true}{\let#1\iftrue }% +% \expandafter\expandafter\expandafter\def\new_if#1{false}{\let#1\iffalse}% +% \new_if#1{false}% the condition starts out false +% \escapechar\count@} +% +% \def\new_if#1#2% +% {\csname\expandafter\if@\string#1#2\endcsname} +% +% \bgroup % `if' is required +% \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}} +% \egroup -\bgroup % `if' is required +% We use \csstring so there is no need to push/pop escapechar. +% We use different names so that we get a better error message. +% +% \normalprotected\def\newif#1% +% {\let\new_if_saved\newif +% \let\newif\new_if_check +% \expandafter\expandafter\expandafter\def\new_if_cs #1{true}{\let#1\iftrue }% +% \expandafter\expandafter\expandafter\def\new_if_cs#1{false}{\let#1\iffalse}% +% \new_if_cs#1{false}% +% \let\newif\new_if_saved} +% +% \normalprotected\def\new_if_cs#1#2% +% {\csname\expandafter\newif\csstring#1#2\endcsname} +% +% We wrap all into one macro: - \uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}} +\normalprotected\def\newif#1% + {\let\new_if_saved\newif + \let\newif\new_if_check + \expandafter\def\csname\expandafter\newif\csstring#1true\endcsname {\let#1\iftrue }% + \expandafter\def\csname\expandafter\newif\csstring#1false\endcsname{\let#1\iffalse}% + \csname\expandafter\newif\csstring#1false\endcsname + \let\newif\new_if_saved} +\bgroup + \normalexpanded{\gdef\noexpand\new_if_check\string i\string f{}} \egroup %D Let's test this one: @@ -534,32 +576,11 @@ %D A few shortcuts: -\normalprotected\def\glet {\global \let } \normalprotected\def\udef {\normalprotected\def } \normalprotected\def\ugdef{\normalprotected\gdef} \normalprotected\def\uedef{\normalprotected\edef} \normalprotected\def\uxdef{\normalprotected\xdef} -%D The catcode constants will be redefined in later catcode related modules -%D but they can be used in the same way. - -\chardef\escapecatcode = 0 -\chardef\begingroupcatcode = 1 -\chardef\endgroupcatcode = 2 -\chardef\mathshiftcatcode = 3 -\chardef\alignmentcatcode = 4 -\chardef\endoflinecatcode = 5 -\chardef\parametercatcode = 6 -\chardef\superscriptcatcode = 7 -\chardef\subscriptcatcode = 8 -\chardef\ignorecatcode = 9 -\chardef\spacecatcode = 10 -\chardef\lettercatcode = 11 -\chardef\othercatcode = 12 -\chardef\activecatcode = 13 -\chardef\commentcatcode = 14 -\chardef\invalidcatcode = 15 - %D For a while we keep the following, as systems like tikz need it. Best %D not use that one \CONTEXT. @@ -789,7 +810,8 @@ \normalprotected\def\newmacro #1{\let#1\empty} \normalprotected\def\setnewmacro#1{\let#1} -\def\!!plusone{1} +\def\!!zerocount{0} +\def\!!plusone {1} \normalprotected\def\newfraction#1{\let#1\!!plusone} @@ -872,28 +894,28 @@ \let\endgraf\par \let\endline\cr -\def\space{ } -\def\empty{} - \normalprotected\def\null{\hpack{}} %D The following two might be overloaded later on but some modules need then %D earlier. These functionality is reflected in the name and will not change. -\bgroup - \catcode`\^^M=\activecatcode% - \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}% - \global\let^^M\par% -\egroup - -\bgroup - \gdef\obeyspaces{\catcode`\ \activecatcode}% - \obeyspaces\global\let =\space% -\egroup +% \bgroup +% \catcode`\^^M=\activecatcode% +% \gdef\obeylines{\catcode`\^^M\activecatcode \let^^M\par}% +% \glet^^M\par% +% \egroup +% +% \bgroup +% \gdef\obeyspaces{\catcode`\ \activecatcode}% +% \obeyspaces\glet =\space% +% \egroup -%D A constant: +\def\obeylines {\catcode\endoflineasciicode\activecatcode\letcharcode\endoflineasciicode\par} +\def\obeyspaces{\catcode\spaceasciicode \activecatcode\letcharcode\spaceasciicode \space} -\let\endoflinetoken=^^M +% %D A constant: +% +% \let\endoflinetoken=^^M %D Also needed might be a simple loop structure and we borrow plain \TEX's one %D as it is often expected to be present and it is about the fastest you can @@ -948,6 +970,12 @@ \lineskip = 1pt \lineskiplimit = 0pt +%D Sometimes kerns make more sense than glue but we need to be in the +%D right mode: + +\normalprotected\def\vkern{\ifhmode\par \fi\kern} +\normalprotected\def\hkern{\ifvmode\dontleavehmode\fi\kern} + %D Again a few kind-of-extensions the core. These come from plain \TEX\ but %D are probably not used in \CONTEXT. @@ -976,116 +1004,47 @@ %D Backend: -% For the moment we define some \pdf... helpers but this will move to the backend -% module after which the official interfaces have to be used. This is needed for -% modules not made by ctx developers. - -\normalprotected\def\pdfliteral {\pdfextension literal } -\normalprotected\def\pdfcolorstack {\pdfextension colorstack } -\normalprotected\def\pdfsetmatrix {\pdfextension setmatrix } -\normalprotected\def\pdfsave {\pdfextension save\relax} -\normalprotected\def\pdfrestore {\pdfextension restore\relax} -\normalprotected\def\pdfobj {\pdfextension obj } -\normalprotected\def\pdfrefobj {\pdfextension refobj } -\normalprotected\def\pdfannot {\pdfextension annot } -\normalprotected\def\pdfstartlink {\pdfextension startlink } -\normalprotected\def\pdfendlink {\pdfextension endlink\relax} -\normalprotected\def\pdfoutline {\pdfextension outline } -\normalprotected\def\pdfdest {\pdfextension dest } -\normalprotected\def\pdfthread {\pdfextension thread } -\normalprotected\def\pdfstartthread {\pdfextension startthread } -\normalprotected\def\pdfendthread {\pdfextension endthread\relax} -\normalprotected\def\pdfinfo {\pdfextension info } -\normalprotected\def\pdfcatalog {\pdfextension catalog } -\normalprotected\def\pdfnames {\pdfextension names } -\normalprotected\def\pdfincludechars {\pdfextension includechars } -\normalprotected\def\pdffontattr {\pdfextension fontattr } -\normalprotected\def\pdfmapfile {\pdfextension mapfile } -\normalprotected\def\pdfmapline {\pdfextension mapline } -\normalprotected\def\pdftrailer {\pdfextension trailer } -\normalprotected\def\pdfglyphtounicode {\pdfextension glyphtounicode } - -% \chardef\pdfnofullbanner = 1 -% \chardef\pdfnofilename = 2 -% \chardef\pdfnopagenumber = 4 -% \chardef\pdfnoinfodict = 8 -% \chardef\pdfnocreator = 16 -% \chardef\pdfnocreationdate = 32 -% \chardef\pdfnomoddate = 64 -% \chardef\pdfnoproducer = 128 -% \chardef\pdfnotrapped = 256 -% \chardef\pdfnoid = 512 - -\def\pdftexversion {\numexpr\pdffeedback version\relax} -\def\pdftexrevision {\pdffeedback revision} -\def\pdflastlink {\numexpr\pdffeedback lastlink\relax} -\def\pdfretval {\numexpr\pdffeedback retval\relax} -\def\pdflastobj {\numexpr\pdffeedback lastobj\relax} -\def\pdflastannot {\numexpr\pdffeedback lastannot\relax} -\def\pdfxformname {\numexpr\pdffeedback xformname\relax} -\def\pdfcreationdate {\pdffeedback creationdate} -\def\pdffontname {\numexpr\pdffeedback fontname\relax} -\def\pdffontobjnum {\numexpr\pdffeedback fontobjnum\relax} -\def\pdffontsize {\dimexpr\pdffeedback fontsize\relax} -\def\pdfpageref {\numexpr\pdffeedback pageref\relax} -\def\pdfcolorstackinit {\pdffeedback colorstackinit} - -\let\pdfxform \saveboxresource -\let\pdflastxform \lastsavedboxresourceindex -\let\pdfrefxform \useboxresource -\let\pdfximage \saveimageresource -\let\pdflastximage \lastsavedimageresourceindex -\let\pdflastximagepages \lastsavedimageresourcepages -\let\pdfrefximage \useimageresource -\let\pdfsavepos \savepos -\let\pdflastxpos \lastxpos -\let\pdflastypos \lastypos - -\edef\pdfcompresslevel {\pdfvariable compresslevel} \pdfcompresslevel \plusnine -\edef\pdfobjcompresslevel {\pdfvariable objcompresslevel} \pdfobjcompresslevel \plusone -\edef\pdfdecimaldigits {\pdfvariable decimaldigits} \pdfdecimaldigits \plusfive -\edef\pdfgamma {\pdfvariable gamma} \pdfgamma \plusthousand -\edef\pdfimageresolution {\pdfvariable imageresolution} \pdfimageresolution 300 -\edef\pdfimageapplygamma {\pdfvariable imageapplygamma} \pdfimageapplygamma \zerocount -\edef\pdfimagegamma {\pdfvariable imagegamma} \pdfimagegamma 2200 -\edef\pdfimagehicolor {\pdfvariable imagehicolor} \pdfimagehicolor \plusone -\edef\pdfimageaddfilename {\pdfvariable imageaddfilename} \pdfimageaddfilename \plusone -\edef\pdfpkresolution {\pdfvariable pkresolution} \pdfpkresolution 1200 -\edef\pdfinclusioncopyfonts {\pdfvariable inclusioncopyfonts} \pdfinclusioncopyfonts \plusone -\edef\pdfinclusionerrorlevel {\pdfvariable inclusionerrorlevel} \pdfinclusionerrorlevel \zerocount -\edef\pdfgentounicode {\pdfvariable gentounicode} \pdfgentounicode \plusone -\edef\pdfpagebox {\pdfvariable pagebox} \pdfpagebox \zerocount -\edef\pdfmajorversion {\pdfvariable majorversion} % \pdfmajorversion \plusone -\edef\pdfminorversion {\pdfvariable minorversion} \pdfminorversion \plusseven -\edef\pdfuniqueresname {\pdfvariable uniqueresname} \pdfuniqueresname \zerocount -\edef\pdfhorigin {\pdfvariable horigin} \pdfhorigin 1in -\edef\pdfvorigin {\pdfvariable vorigin} \pdfvorigin \pdfhorigin -\edef\pdflinkmargin {\pdfvariable linkmargin} \pdflinkmargin \zeropoint -\edef\pdfdestmargin {\pdfvariable destmargin} \pdfdestmargin \zeropoint -\edef\pdfthreadmargin {\pdfvariable threadmargin} \pdfthreadmargin \zeropoint -\edef\pdfxformmargin {\pdfvariable xformmargin} \pdfxformmargin \zeropoint -\edef\pdfpkfixeddpi {\pdfvariable pkfixeddpi} \pdfpkfixeddpi \plusone -\edef\pdfignoreunknownimages {\pdfvariable ignoreunknownimages} \pdfignoreunknownimages \zerocount - -\edef\pdfpagesattr {\pdfvariable pagesattr} -\edef\pdfpageattr {\pdfvariable pageattr} -\edef\pdfpageresources {\pdfvariable pageresources} -\edef\pdfxformattr {\pdfvariable xformattr} -\edef\pdfxformresources {\pdfvariable xformresources} -\edef\pdfpkmode {\pdfvariable pkmode} - -\edef\pdfsuppressoptionalinfo{\pdfvariable suppressoptionalinfo } -\let \pdfsuppressptexinfo \pdfsuppressoptionalinfo -\edef\pdftrailerid {\pdfvariable trailerid } -\edef\pdfinfoomitdate {\pdfvariable suppressoptionalinfo \numexpr32+64\relax} - -\normalprotected\def\nopdfcompression {\pdfobjcompresslevel\zerocount \pdfcompresslevel\zerocount} -\normalprotected\def\maximumpdfcompression{\pdfobjcompresslevel\plusnine \pdfcompresslevel\plusnine } -\normalprotected\def\normalpdfcompression {\pdfobjcompresslevel\plusthree \pdfcompresslevel\plusthree} - -\normalpdfcompression - -\outputmode \zerocount % we generate the format in this mode +\ifdefined\pdfvariable + + \pdfvariable compresslevel \plusthree + \pdfvariable objcompresslevel \plusone + % \pdfvariable recompress \zerocount + \pdfvariable decimaldigits \plussix + \pdfvariable gamma \plusthousand + \pdfvariable imageresolution 300 + \pdfvariable imageapplygamma \zerocount + \pdfvariable imagegamma 2200 + \pdfvariable imagehicolor \plusone + \pdfvariable imageaddfilename \plusone + \pdfvariable pkresolution 1200 + \pdfvariable inclusioncopyfonts \plusone + \pdfvariable inclusionerrorlevel \zerocount + \pdfvariable gentounicode \plusone + \pdfvariable omitcidset \plusone + \pdfvariable omitcharset \plusone + \pdfvariable pagebox \zerocount + % \pdfvariable majorversion % \plusone + \pdfvariable minorversion \plusseven + \pdfvariable uniqueresname \zerocount + \pdfvariable horigin 1in + \pdfvariable vorigin 1in + % \pdfvariable linkmargin \zeropoint + % \pdfvariable destmargin \zeropoint + % \pdfvariable threadmargin \zeropoint + % \pdfvariable xformmargin \zeropoint + \pdfvariable pkfixeddpi \plusone + \pdfvariable ignoreunknownimages \zerocount + +\fi + +\let\nopdfcompression \relax +\let\onlypdfobjectcompression\relax +\let\maximumpdfcompression \relax +\let\normalpdfcompression \relax + +\ifdefined\outputmode + \outputmode \zerocount % we generate the format in this mode +\fi %D Basic status stuff. @@ -1102,12 +1061,10 @@ \def\dividenumber#1#2{\the\numexpr(#2-(#1/2))/#1\relax} \ifdefined\texenginename \else - %edef\texenginename{luatex} \edef\texenginename{\directlua{tex.print(LUATEXENGINE)}} \fi \ifdefined\texengineversion \else - %edef\texengineversion{\dividenumber{100}\luatexversion.\modulonumber{100}\luatexversion.\luatexrevision} \edef\texengineversion{\directlua{tex.print(LUATEXVERSION)}} \fi @@ -1120,43 +1077,39 @@ \savingvdiscards\plusone %D We only can set this one via directives (system.synctex) and we only support -%D the context variant. +%D the context variant. This will go away completely. \let\synctex\undefined \newcount\synctex \let\normalsynctex\synctex %D We get rid of the funny \TEX\ offset defaults of one inch by setting them to zero. -\voffset\zeropoint \let\voffset\relax \newdimen\voffset % prevent messing up -\hoffset\zeropoint \let\hoffset\relax \newdimen\hoffset % prevent messing up +\voffset\zeropoint \let\voffset\relax \newdimen\voffset \let\normalvoffset\voffset +\hoffset\zeropoint \let\hoffset\relax \newdimen\hoffset \let\normalhoffset\hoffset + +\ifdefined\pageleftoffset + \let\pageleftoffset \hoffset \let\normalpageleftoffset \hoffset + \let\pagerightoffset \hoffset \let\normalpagerightoffset \hoffset + \let\pagetopoffset \voffset \let\normalpagetopoffset \voffset + \let\pagebottomoffset\voffset \let\normalpagebottomoffset\voffset +\fi %D Handy. -\suppresslongerror \plusone % \let\suppresslongerror \relax -\suppressoutererror \plusone % \let\suppressoutererror \relax -\suppressmathparerror \plusone % \let\suppressmathparerror \relax -\suppressifcsnameerror\plusone % \let\suppressifcsnameerror\relax +\suppresslongerror \plusone +\suppressoutererror \plusone +\suppressmathparerror \plusone +\suppressifcsnameerror\plusone -\matheqnogapstep \zerocount % fr now +\let \suppresslongerror \relax +\newcount\suppresslongerror \let\normalsuppresslongerror \suppresslongerror +\let \suppressoutererror \suppresslongerror \let\normalsuppressoutererror \suppresslongerror +\let \suppressmathparerror \suppresslongerror \let\normalsuppressmathparerror \suppresslongerror +\let \suppressifcsnameerror\suppresslongerror \let\normalsuppressifcsnameerror\suppresslongerror -%D While cleaning this code up a bit I was listening to Heather Nova's \CD\ Redbird. -%D The first song on that \CD\ ends with a few lines suitable for ending this -%D initialization module: -%D -%D \startlines -%D And there's so much I can do for you -%D Given time I know that I can prove -%D Now my world is opened up to you -%D Come inside -%D -%D Welcome to my life -%D Welcome to my world -%D Come inside -%D \stoplines -%D -%D So let's see what \TEX\ can do now that we've opened up the basic machinery. +\matheqnogapstep\zerocount % for now -%D Now we define a few helpers that we need in a very early stage. We hav eno message system -%D yet but redundant definitions are fatal anyway. +%D Now we define a few helpers that we need in a very early stage. We have no +%D message system yet but redundant definitions are fatal anyway. \newcount\c_syst_helpers_n_of_namespaces \c_syst_helpers_n_of_namespaces\pluseight % 1-8 reserved for catcodes @@ -1183,30 +1136,4 @@ \let\normalstartdmath \Ustartdisplaymath \let\normalstopdmath \Ustopdisplaymath -%D For now: - -\ifdefined\protrusionboundary \else \let\protrusionboundary\boundary \fi -\ifdefined\wordboundary \else \let\wordboundary \noboundary \fi - -\ifdefined\mathrulesfam \else \newcount\mathrulesfam \fi -\ifdefined\mathrulesmode \else \newcount\mathrulesmode \fi -\ifdefined\mathsurroundmode \else \newcount\mathsurroundmode \fi -\ifdefined\mathitalicsmode \else \newcount\mathitalicsmode \fi -\ifdefined\mathdelimitersmode \else \newcount\mathdelimitersmode \fi -\ifdefined\mathscriptboxmode \else \newcount\mathscriptboxmode \fi - -\ifdefined\hyphenpenaltymode \else \newcount\hyphenpenaltymode \fi -\ifdefined\automatichyphenpenalty \else \newcount\automatichyphenpenalty \fi -\ifdefined\automatichyphenmode \else \newcount\automatichyphenmode \fi -\ifdefined\explicithyphenpenalty \else \newcount\explicithyphenpenalty \fi - -\ifdefined\explicitdiscretionary \else \let\explicitdiscretionary \- \fi -\ifdefined\automaticdiscretionary \else \def\automaticdiscretionary{\Uchar\exhyphenchar} \fi - -\ifdefined\mathpenaltiesmode \else \newcount\mathpenaltiesmode \fi -\ifdefined\prebinoppenalty \else \newcount\prebinoppenalty \fi -\ifdefined\prerelpenalty \else \newcount\prerelpenalty \fi - -\ifdefined\breakafterdirmode \else \newcount\breakafterdirmode \fi - \protect \endinput diff --git a/tex/context/base/mkiv/syst-lua.lua b/tex/context/base/mkiv/syst-lua.lua index 35cd22123..a63c49e8f 100644 --- a/tex/context/base/mkiv/syst-lua.lua +++ b/tex/context/base/mkiv/syst-lua.lua @@ -15,10 +15,10 @@ local context = context local implement = interfaces.implement local ctx_protected_cs = context.protected.cs -- more efficient -local ctx_firstoftwoarguments = ctx_protected_cs.firstoftwoarguments -local ctx_secondoftwoarguments = ctx_protected_cs.secondoftwoarguments -local ctx_firstofoneargument = ctx_protected_cs.firstofoneargument -local ctx_gobbleoneargument = ctx_protected_cs.gobbleoneargument +local ctx_firstoftwoarguments = context.firstoftwoarguments +local ctx_secondoftwoarguments = context.secondoftwoarguments +local ctx_firstofoneargument = context.firstofoneargument +local ctx_gobbleoneargument = context.gobbleoneargument local two_strings = interfaces.strings[2] @@ -105,7 +105,8 @@ local p_first = C((1-P(",")-P(-1))^0) implement { name = "firstinset", arguments = "string", - actions = function(str) context(lpegmatch(p_first,str or "")) end + actions = function(str) context(lpegmatch(p_first,str or "")) end, + public = true, } implement { diff --git a/tex/context/base/mkiv/syst-lua.mkiv b/tex/context/base/mkiv/syst-lua.mkiv index ca5f9679f..3600dac34 100644 --- a/tex/context/base/mkiv/syst-lua.mkiv +++ b/tex/context/base/mkiv/syst-lua.mkiv @@ -19,6 +19,42 @@ \def\expdoif #1#2{\clf_doifsame {#1}{#2}} \def\expdoifnot #1#2{\clf_doifnotsame {#1}{#2}} +%D Here is variant using a brainwave of the 12\high{+} hour \quotation {Long Road +%D Out of Eden}\footnote {Eden being Backo\TeX\ 2018, where the virtues of the \type +%D {\expanded} primitive were mentioned in talks.} trip. For now I don't really see +%D other useful applications. + +\ifdefined\immediateassignment + + \def\expandeddoif#1#2% + {\immediateassignment\edef\m_syst_string_one{#1}% + \immediateassignment\edef\m_syst_string_two{#2}% + \ifx\m_syst_string_one\m_syst_string_two + \expandafter\firstofoneargument + \else + \expandafter\gobbleoneargument + \fi} + + \def\expandeddoifnot#1#2% + {\immediateassignment\edef\m_syst_string_one{#1}% + \immediateassignment\edef\m_syst_string_two{#2}% + \ifx\m_syst_string_one\m_syst_string_two + \expandafter\gobbleoneargument + \else + \expandafter\firstofoneargument + \fi} + + \def\expandeddoifelse#1#2% + {\immediateassignment\edef\m_syst_string_one{#1}% + \immediateassignment\edef\m_syst_string_two{#2}% + \ifx\m_syst_string_one\m_syst_string_two + \expandafter\firstoftwoarguments + \else + \expandafter\secondoftwoarguments + \fi} + +\fi + % \testfeatureonce{100000}{\doifelse{hello world}{here i am}{}} % 0.3 % \testfeatureonce{100000}{\expandabledoifelse{hello world}{here i am}{}} % 1.5 diff --git a/tex/context/base/mkiv/syst-rtp.mkiv b/tex/context/base/mkiv/syst-rtp.mkiv new file mode 100644 index 000000000..82c0778b4 --- /dev/null +++ b/tex/context/base/mkiv/syst-rtp.mkiv @@ -0,0 +1,18 @@ +%D \module +%D [ file=syst-rtp, +%D version=2006.10.13, +%D title=\CONTEXT\ Core Macros, +%D subtitle=Run Time Processes, +%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 + +\let\executesystemcommand\clf_execute + +\protect \endinput diff --git a/tex/context/base/mkiv/tabl-com.mkiv b/tex/context/base/mkiv/tabl-com.mkiv index e90086368..01a55e313 100644 --- a/tex/context/base/mkiv/tabl-com.mkiv +++ b/tex/context/base/mkiv/tabl-com.mkiv @@ -15,39 +15,51 @@ \unprotect -\let\VL\relax - -\let\NC\relax -\let\RC\relax -\let\HC\relax -\let\EQ\relax - -\let\RQ\relax -\let\HQ\relax - -\let\NG\relax -\let\NN\relax -\let\ND\relax -\let\NR\relax -\let\NB\relax - +\let\AR\relax +\let\BA\relax +\let\BC\relax +\let\BL\relax \let\CC\relax \let\CL\relax \let\CM\relax \let\CR\relax - -\let\SR\relax +\let\DB\relax +\let\EQ\relax +\let\FB\relax +\let\FL\relax \let\FR\relax -\let\MR\relax +\let\HC\relax +\let\HL\relax +\let\HQ\relax +\let\HR\relax +\let\LB\relax +\let\LL\relax \let\LR\relax -\let\AR\relax - -\let\FL\relax \let\ML\relax -\let\LL\relax +\let\MR\relax +\let\NA\relax +\let\NB\relax +\let\NC\relax +\let\ND\relax +\let\NF\relax +\let\NG\relax +\let\NI\relax +\let\NL\relax +\let\NN\relax +\let\NP\relax +\let\NR\relax +\let\PB\relax +\let\RC\relax +\let\RQ\relax +\let\SR\relax \let\TL\relax -\let\BL\relax -\let\HL\relax -\let\HR\relax +\let\VL\relax + +\installmacrostack\BC +\installmacrostack\EC +\installmacrostack\EQ +\installmacrostack\NC +\installmacrostack\NN +\installmacrostack\NR \protect \endinput diff --git a/tex/context/base/mkiv/tabl-ltb.mkiv b/tex/context/base/mkiv/tabl-ltb.mkiv index 3147fa1cc..20ae8bf5a 100644 --- a/tex/context/base/mkiv/tabl-ltb.mkiv +++ b/tex/context/base/mkiv/tabl-ltb.mkiv @@ -705,14 +705,14 @@ \else \t_tabl_lines_head\emptytoks \fi - \pushmacro\BC - \pushmacro\EC + \push_macro_BC + \push_macro_EC \def\BC##1\EC{\appendtoks##1\to\t_tabl_lines_head}% \let\EC\relax} % signal \unexpanded\def\tabl_lines_EH - {\popmacro\EC - \popmacro\BC + {\pop_macro_EC + \pop_macro_BC \expandafter\startlinetablehead\the\t_tabl_lines_head\stoplinetablehead} \let\startlinetablebody\relax diff --git a/tex/context/base/mkiv/tabl-ntb.mkiv b/tex/context/base/mkiv/tabl-ntb.mkiv index 9acf2ef36..ca3d78800 100644 --- a/tex/context/base/mkiv/tabl-ntb.mkiv +++ b/tex/context/base/mkiv/tabl-ntb.mkiv @@ -271,10 +271,10 @@ \letvalue{\??naturaltablesqueeze\v!broad}\donetrue \letvalue{\??naturaltablesqueeze\v!local}\donetrue -\def\tabl_ntb_let_gal{\global\expandafter\let\csname\??naturaltablegal\m_tabl_tbl_level\endcsname} +\def\tabl_ntb_let_gal{\expandafter\glet\csname\??naturaltablegal\m_tabl_tbl_level\endcsname} \def\tabl_ntb_get_gal{\csname\??naturaltablegal\m_tabl_tbl_level\endcsname} -\def\tabl_ntb_let_tal#1{\global\expandafter\let\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname} +\def\tabl_ntb_let_tal#1{\expandafter\glet\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname} \def\tabl_ntb_get_tal#1{\csname\??naturaltabletal\m_tabl_tbl_level:\number#1\endcsname} \def\tabl_ntb_set_nob#1{\expandafter\let\csname\??naturaltablenob\m_tabl_tbl_level:\number#1\endcsname\plusone} @@ -291,8 +291,8 @@ %def\tabl_ntb_set_wd#1#2{\expandafter\xdef\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_set_ht#1#2{\expandafter\xdef\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! -%def\tabl_ntb_let_wd#1#2{\global\expandafter\let\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! -\def\tabl_ntb_let_ht#1#2{\global\expandafter\let\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! +%def\tabl_ntb_let_wd#1#2{\expandafter\glet\csname\??naturaltablewd\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! +\def\tabl_ntb_let_ht#1#2{\expandafter\glet\csname\??naturaltableht\m_tabl_tbl_level:\number#1:\number#2\endcsname} % global ! \def\tabl_ntb_get_tag#1#2{\csname\??naturaltabletag\m_tabl_tbl_level:\number#1:\number#2\endcsname} \def\tabl_ntb_get_col#1#2{\csname\??naturaltablecol\m_tabl_tbl_level:\number#1:\number#2\endcsname} @@ -306,10 +306,10 @@ \def\tabl_ntb_set_dis#1{\expandafter\xdef\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! \def\tabl_ntb_set_aut#1{\expandafter\xdef\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! -\def\tabl_ntb_let_wid#1{\global\expandafter\let\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! -\def\tabl_ntb_let_hei#1{\global\expandafter\let\csname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! -\def\tabl_ntb_let_dis#1{\global\expandafter\let\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! -\def\tabl_ntb_let_aut#1{\global\expandafter\let\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! +\def\tabl_ntb_let_wid#1{\expandafter\glet\csname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! +\def\tabl_ntb_let_hei#1{\expandafter\glet\csname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! +\def\tabl_ntb_let_dis#1{\expandafter\glet\csname\??naturaltabledis\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! +\def\tabl_ntb_let_aut#1{\expandafter\glet\csname\??naturaltableaut\m_tabl_tbl_level:\number#1\endcsname} % {#2} global ! \def\tabl_ntb_get_wid#1{\ifcsname\??naturaltablewid\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi} \def\tabl_ntb_get_hei#1{\ifcsname\??naturaltablehei\m_tabl_tbl_level:\number#1\endcsname\lastnamedcs\else\zeropoint\fi} @@ -1161,13 +1161,11 @@ \def\tabl_ntb_row_stop_boxed {% \noindent % no, else double leftskip in narrower - \normalexpanded - {\t_tabl_ntb - {\the\t_tabl_ntb - % no need for init - \tabl_ntb_row_align_start - \the\t_tabl_ntb_row - \tabl_ntb_row_align_stop}}} + \etoksapp\t_tabl_ntb + {% no need for init + \tabl_ntb_row_align_start + \the\t_tabl_ntb_row + \tabl_ntb_row_align_stop}} \def\tabl_ntb_row_stop_split {\ifcsname\??naturaltableset\m_tabl_tbl_level:\c!y++\the\c_tabl_ntb_current_row\endcsname @@ -1177,13 +1175,11 @@ \fi} \def\tabl_ntb_row_stop_split_nop - {\normalexpanded - {\t_tabl_ntb - {\the\t_tabl_ntb - \tabl_ntb_row_align_reset - \tabl_ntb_row_align_start - \the\t_tabl_ntb_row - \tabl_ntb_row_align_stop}}} + {\etoksapp\t_tabl_ntb + {\tabl_ntb_row_align_reset + \tabl_ntb_row_align_start + \the\t_tabl_ntb_row + \tabl_ntb_row_align_stop}} \def\tabl_ntb_row_stop_split_yes {\begingroup @@ -1192,13 +1188,11 @@ \xdef\m_tabl_ntb_after_split {\naturaltablelocalparameter\c!after}% to be checked \xdef\m_tabl_ntb_same_page {\naturaltablelocalparameter\c!samepage}% \endgroup - \normalexpanded - {\t_tabl_ntb - {\the\t_tabl_ntb - \tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}% - \tabl_ntb_row_align_start - \the\t_tabl_ntb_row - \tabl_ntb_row_align_stop}}} + \etoksapp\t_tabl_ntb + {\tabl_ntb_row_align_set{\m_tabl_ntb_before_split}{\m_tabl_ntb_after_split}{\m_tabl_ntb_same_page}% + \tabl_ntb_row_align_start + \the\t_tabl_ntb_row + \tabl_ntb_row_align_stop}} \unexpanded\def\tabl_ntb_row_align_set#1#2#3% {\xdef\m_tabl_ntb_before_split{#1}% @@ -1206,9 +1200,9 @@ \xdef\m_tabl_ntb_same_page {#3}} \unexpanded\def\tabl_ntb_row_align_reset - {\global\let\m_tabl_ntb_before_split\empty - \global\let\m_tabl_ntb_after_split \empty - \global\let\m_tabl_ntb_same_page \empty} + {\glet\m_tabl_ntb_before_split\empty + \glet\m_tabl_ntb_after_split \empty + \glet\m_tabl_ntb_same_page \empty} \def\tabl_ntb_prelocate_error {\writestatus\m!TABLE{fatal error: use \string\prelocateTBLrows\space to increase table memory (now: \the\c_tabl_prelocated_rows)}} @@ -1225,12 +1219,10 @@ \tabl_ntb_prelocate_error \fi}% \def\tabl_ntb_row_stop - {\normalexpanded - {\t_tabl_ntb - {\the\t_tabl_ntb - \tabl_ntb_row_align_start - \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname - \tabl_ntb_row_align_stop}}}% + {\etoksapp\t_tabl_ntb + {\tabl_ntb_row_align_start + \the\csname\??naturaltabletok\the\c_tabl_ntb_row\endcsname + \tabl_ntb_row_align_stop}}% \global\c_tabl_prelocated_rows#1\relax} \def\tabl_ntb_prelocate_okay @@ -1344,37 +1336,23 @@ {\global\advance\c_tabl_ntb_col\plusone \kern\d_tabl_ntb_columndistance} -% \setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2% -% {\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax -% \ifnum\scratchcounter>\zerocount -% \normalexpanded -% {\t_tabl_ntb_row -% {\the\t_tabl_ntb_row -% \tabl_ntb_span{\the\scratchcounter}% -% \tabl_ntb_plus}}% -% \fi} - \setvalue{\??naturaltablecell\the\c_tabl_ntb_none}#1#2% {\scratchcounter\tabl_ntb_get_col{#1}{#2}\relax \ifnum\scratchcounter>\zerocount - \normalexpanded - {\t_tabl_ntb_row - {\the\t_tabl_ntb_row - \tabl_ntb_span{\the\scratchcounter}}}% + \etoksapp\t_tabl_ntb_row + {\tabl_ntb_span{\the\scratchcounter}}% \fi} \setvalue{\??naturaltablecell\the\c_tabl_ntb_cell}#1#2% - {\t_tabl_ntb_row\expandafter{\the\t_tabl_ntb_row\tabl_ntb_pass #1 #2 }% space delimited -> less tokens + {\toksapp\t_tabl_ntb_row{\tabl_ntb_pass #1 #2 }% space delimited -> less tokens \scratchcounter\tabl_ntb_get_col{#1}{#2}\relax \ifnum\scratchcounter>\zerocount - \normalexpanded - {\t_tabl_ntb_row - {\the\t_tabl_ntb_row - \ifnum\scratchcounter=\plusone - \tabl_ntb_plus - \else - \tabl_ntb_skip{\the\scratchcounter}% - \fi}}% + \etoksapp\t_tabl_ntb_row + {\ifnum\scratchcounter=\plusone + \tabl_ntb_plus + \else + \tabl_ntb_skip{\the\scratchcounter}% + \fi}% \fi} \unexpanded\def\tabl_ntb_cell#1#2% diff --git a/tex/context/base/mkiv/tabl-tab.mkiv b/tex/context/base/mkiv/tabl-tab.mkiv index 54b18a385..631f29bc0 100644 --- a/tex/context/base/mkiv/tabl-tab.mkiv +++ b/tex/context/base/mkiv/tabl-tab.mkiv @@ -417,7 +417,7 @@ % Key "a": a{TOKENS} adds TOKENS to the right of (after) the template \newtableformatkey a#1% - {\!taDataColumnTemplate\expandafter{\the\!taDataColumnTemplate #1}% + {\toksapp\!taDataColumnTemplate{#1}% \doreadtableformatkeys} % Key "\{": Enclose template in braces. @@ -435,7 +435,7 @@ \scratchtoks\emptytoks \!thLoop \ifnum\scratchcounter>\zerocount - \scratchtoks\expandafter{\the\scratchtoks#2}% + \toksapp\scratchtoks{#2}% \advance\scratchcounter\minusone \repeat \expandafter\doreadtableformatkeys\the\scratchtoks} @@ -688,7 +688,7 @@ % extensions \newtableformatkey q% - {\letempty\!tqStyle + {\let\!tqStyle\empty \futurelet\!tnext\!tqTestForBracket} \newtableformatkey Q% @@ -928,7 +928,7 @@ \global\c_tabl_table_n_of_vrules\plusone \unskip \fi - \global\let\m_tabl_table_vrule_color\empty + \glet\m_tabl_table_vrule_color\empty \hfil \aligntab} @@ -1370,8 +1370,8 @@ {\tabl_tables_chuck_auto_row % before the tail, else noalign problem \tabl_table_insert_tail \starttablenoalign - \global\let\tabl_table_head\empty - \global\let\tabl_table_tail\empty + \glet\tabl_table_head\empty + \glet\tabl_table_tail\empty \stoptablenoalign \tabl_table_finish \ifx\p_tabl_table_frame\empty @@ -1481,7 +1481,7 @@ \tabl_table_restart % \starttablenoalign % \globalpushmacro\simpletableHL -% \global\let\simpletableHL\doverysimpletableHL +% \glet\simpletableHL\doverysimpletableHL % \stoptablenoalign \tabl_table_insert_head \ifsplittables \ifconditional \c_tabl_table_repeat_tail @@ -1593,8 +1593,8 @@ \egroup \dontcomplain \tabl_table_split_box\tablecontentbox - \global\let\tabl_table_head\empty % new here - \global\let\tabl_table_tail\empty % new here + \glet\tabl_table_head\empty % new here + \glet\tabl_table_tail\empty % new here \flushnotes \egroup} @@ -1691,8 +1691,8 @@ \starttablenoalign \nobreak \tabl_table_set_action\tableunknownstate - \globalletempty\tabl_tables_check_auto_row - \globalletempty\tabl_tables_chuck_auto_row + \glet\tabl_tables_check_auto_row\empty + \glet\tabl_tables_chuck_auto_row\empty \global\currenttablecolumn\zerocount \stoptablenoalign} @@ -1816,21 +1816,21 @@ %D the last row. \unexpanded\def\tabl_table_AR - {\globallet\tabl_tables_check_auto_row\tabl_tables_check_auto_row_indeed - \globallet\tabl_tables_chuck_auto_row\tabl_tables_chuck_auto_row_indeed} + {\glet\tabl_tables_check_auto_row\tabl_tables_check_auto_row_indeed + \glet\tabl_tables_chuck_auto_row\tabl_tables_chuck_auto_row_indeed} \let\tabl_tables_check_auto_row\empty \let\tabl_tables_chuck_auto_row\empty \def\tabl_tables_check_auto_row_indeed - {\globallet\tabl_tables_check_auto_row\empty + {\glet\tabl_tables_check_auto_row\empty \ifnum\tableactionstate=\tablerulestate \FR\else \ifnum\tableactionstate=\tableunknownstate\FR\else \MR\fi\fi} \def\tabl_tables_chuck_auto_row_indeed - {\globalletempty\tabl_tables_check_auto_row - \globalletempty\tabl_tables_chuck_auto_row + {\glet\tabl_tables_check_auto_row\empty + \glet\tabl_tables_chuck_auto_row\empty \ifnum\tableactionstate=\tablerulestate \SR\else \ifnum\tableactionstate=\tableunknownstate\SR\else \LR\fi\fi} @@ -1914,7 +1914,7 @@ \dosingleempty\table_tabl_VL_indeed} \def\table_tabl_VL_indeed[#1]% - {\global\let\m_tabl_table_vrule_color\empty + {\glet\m_tabl_table_vrule_color\empty \global\c_tabl_table_vrule_thickness_factor\m_tabl_table_VLwidth\relax \iffirstargument \rawprocesscommalist[#1]\tabl_table_vrulecommand @@ -1961,7 +1961,7 @@ \bgroup \global\c_tabl_table_hrule_thickness_factor\m_tabl_table_HLheight\relax \iffirstargument - \global\let\m_tabl_table_hrule_color\empty + \glet\m_tabl_table_hrule_color\empty \rawprocesscommalist[#1]\tabl_table_hrulecommand \ifx\m_tabl_table_hrule_color\empty\else \switchtocolor[\m_tabl_table_hrule_color]% @@ -2083,7 +2083,7 @@ \global\c_tabl_table_hrule_thickness_factor\m_tabl_table_HLheight\relax \global\c_tabl_table_drule_span\zerocount \iffirstargument - \global\let\m_tabl_table_hrule_color\empty + \glet\m_tabl_table_hrule_color\empty \rawprocesscommalist[#1]\tabl_table_drulecommand % \ifx\m_tabl_table_hrule_color\empty\else % \switchtocolor[\m_tabl_table_hrule_color]% see *DL* diff --git a/tex/context/base/mkiv/tabl-tbl.mkiv b/tex/context/base/mkiv/tabl-tbl.mkiv index 7a0d2c8a8..75839caed 100644 --- a/tex/context/base/mkiv/tabl-tbl.mkiv +++ b/tex/context/base/mkiv/tabl-tbl.mkiv @@ -158,6 +158,7 @@ \newtoks \t_tabl_tabulate_dummy \newtoks \t_tabl_tabulate_every_row \newtoks \t_tabl_tabulate_every_after_row +\newtoks \t_tabl_tabulate_every_real_row \newtoks \t_tabl_tabulate_initializers_first \newtoks \t_tabl_tabulate_initializers_second @@ -174,6 +175,8 @@ \newcount \c_tabl_tabulate_totalnoflines \newcount \c_tabl_tabulate_minusnoflines \newcount \c_tabl_tabulate_align +\newcount \c_tabl_tabulate_nofrealrows +\newcount \c_tabl_tabulate_autocolor \newcount \c_tabl_tabulate_nofcolumns % set at the lua end by parser \newcount \c_tabl_tabulate_has_rule_spec_first % set at the lua end by parser (for the moment a count) @@ -250,6 +253,18 @@ \installcorenamespace{tabulatefoot} \installcorenamespace{tabulatenext} +\prependtoks + \global\c_tabl_tabulate_nofrealrows\zerocount +\to \t_tabl_tabulate_initializers_first + +\prependtoks + \global\c_tabl_tabulate_nofrealrows\zerocount +\to \t_tabl_tabulate_initializers_second + +\prependtoks + \global\advance\c_tabl_tabulate_nofrealrows\plusone +\to \t_tabl_tabulate_every_real_row + \def\b_tabl_tabulate_current#1% {\csname\??tabulatebox\number#1\endcsname} % beware, a synonym @@ -354,8 +369,8 @@ \ifx\m_tabl_tabulate_color_local\empty \xdef\m_tabl_tabulate_color{#1}% \else - \global\let\m_tabl_tabulate_color\m_tabl_tabulate_color_local - \global\let\m_tabl_tabulate_color_local\empty + \glet\m_tabl_tabulate_color\m_tabl_tabulate_color_local + \glet\m_tabl_tabulate_color_local\empty \fi \ifcase\c_tabl_tabulate_localcolorspan \global\c_tabl_tabulate_colorspan#2\relax @@ -381,8 +396,8 @@ \ifx\m_tabl_tabulate_vrule_color_local\empty \xdef\m_tabl_tabulate_vrule_color{#1}% \else - \global\let\m_tabl_tabulate_vrule_color\m_tabl_tabulate_vrule_color_local - \global\let\m_tabl_tabulate_vrule_color_local\empty + \glet\m_tabl_tabulate_vrule_color\m_tabl_tabulate_vrule_color_local + \glet\m_tabl_tabulate_vrule_color_local\empty \fi} \let\tabl_tabulate_check_local_color \gobbletwoarguments @@ -553,13 +568,13 @@ \installtabulatepreambleoption{i}{\tabl_tabulate_set_preskip} \installtabulatepreambleoption{j}{\tabl_tabulate_set_posskip} \installtabulatepreambleoption{k}{\tabl_tabulate_set_preposskip} -\installtabulatepreambleoption{e}{\t_tabl_tabulate_settings\expandafter{\the\t_tabl_tabulate_settings\global\settrue\c_tabl_tabulate_equal}% +\installtabulatepreambleoption{e}{\toksapp\t_tabl_tabulate_settings{\global\settrue\c_tabl_tabulate_equal}% \tabl_tabulate_set_preamble} \installtabulatepreambleoption{g}{\tabl_tabulate_set_align} \installtabulatepreambleoption{.}{\tabl_tabulate_set_align.} \installtabulatepreambleoption{,}{\tabl_tabulate_set_align,} \installtabulatepreambleoption{C}{\tabl_tabulate_set_color_span} -\installtabulatepreambleoption{d}{\t_tabl_tabulate_settings\expandafter{\the\t_tabl_tabulate_settings\fixedspaces}% +\installtabulatepreambleoption{d}{\toksapp\t_tabl_tabulate_settings{\fixedspaces}% \tabl_tabulate_set_preamble} \installtabulatepreambleoption{ }{\tabl_tabulate_set_preamble} \installtabulatepreambleoption{A}{\tabl_tabulate_set_alignment} @@ -607,18 +622,18 @@ \tabl_tabulate_set_preamble} \def\tabl_tabulate_set_preskip#1% - {\doifelsenumber{#1} - {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble } + {\doifelsenumber{#1}% + {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }% {\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}} \def\tabl_tabulate_set_posskip#1% - {\doifelsenumber{#1} - {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble } + {\doifelsenumber{#1}% + {\s_tabl_tabulate_post#1\d_tabl_tabulate_unit\tabl_tabulate_set_preamble }% {\s_tabl_tabulate_post.5\d_tabl_tabulate_unit\tabl_tabulate_set_preamble#1}} \def\tabl_tabulate_set_preposskip#1% - {\doifelsenumber{#1} - {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble } + {\doifelsenumber{#1}% + {\s_tabl_tabulate_pre#1\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble }% {\s_tabl_tabulate_pre.5\d_tabl_tabulate_unit\s_tabl_tabulate_post\s_tabl_tabulate_pre\tabl_tabulate_set_preamble#1}} \def\tabl_tabulate_set_setups#1% @@ -704,6 +719,28 @@ \fi \tabl_tabulate_set_preamble} +% faster but seldom used +% +% \installcorenamespace{tabulatewidth} +% +% \setvalue{\??tabulatewidth\v!fit }{\c_tabl_tabulate_modus\plusthree} +% \setvalue{\??tabulatewidth\v!fixed}{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_nopbreak} +% \setvalue{\??tabulatewidth\v!auto }{\c_tabl_tabulate_modus\plusthree\settrue\c_tabl_tabulate_reshape} +% +% \def\tabl_tabulate_set_width_step#1% +% {\ifcsname\??tabulatewidth#1\endcsname +% \lastnamedcs +% \else +% \d_tabl_tabulate_width#1\relax +% \fi} +% +% \def\tabl_tabulate_set_width_indeed(#1)% +% {\rawprocesscommacommand[#1]\tabl_tabulate_set_width_step +% \ifconditional\c_tabl_tabulate_pwidth_set +% \global\advance\d_tabl_tabulate_width_p\d_tabl_tabulate_width % accumulated parwidth +% \fi +% \tabl_tabulate_set_preamble} +% \def\tabl_tabulate_set_raggedright {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedright \fi} \def\tabl_tabulate_set_raggedcenter{\ifnum\c_tabl_tabulate_type=\plusone \else\raggedcenter\fi} \def\tabl_tabulate_set_raggedleft {\ifnum\c_tabl_tabulate_type=\plusone \else\raggedleft \fi} @@ -772,10 +809,10 @@ \t_tabl_tabulate_emath\emptytoks \t_tabl_tabulate_font\emptytoks \t_tabl_tabulate_settings\emptytoks - \global\let\m_tabl_tabulate_alignment\empty - \global\let\m_tabl_tabulate_color\empty - \global\let\m_tabl_tabulate_text_color\empty - \global\let\m_tabl_tabulate_vrule_color\empty + \glet\m_tabl_tabulate_alignment\empty + \glet\m_tabl_tabulate_color\empty + \glet\m_tabl_tabulate_text_color\empty + \glet\m_tabl_tabulate_vrule_color\empty \global\c_tabl_tabulate_colorspan\zerocount \global\setfalse\c_tabl_auto_align_mode \global\advance\c_tabl_tabulate_columns\plusone @@ -799,8 +836,8 @@ \fi} \def\tabl_tabulate_set_last_entry#1% rulespec - {\global\let\m_tabl_tabulate_color\empty - \global\let\m_tabl_tabulate_vrule_color\empty + {\glet\m_tabl_tabulate_color\empty + \glet\m_tabl_tabulate_vrule_color\empty \edef\currenttabulationtrulespec{#1}% \ifx\currenttabulationtrulespec\empty \global\d_tabl_tabulate_vrulethickness\zeropoint @@ -1176,9 +1213,12 @@ \expandafter\tabl_start_regular_one \fi} +\def\tabl_default_format{|l|p|} + \def\tabl_start_regular_one[#1][#2]% {\doifelseassignment{#1} - {\setupcurrenttabulation[\c!format={|l|p|},#1]} + {\lettabulationparameter\c!format\tabl_default_format + \setupcurrenttabulation[#1]} {\def\p_format{#1}% \ifx\p_format\empty \def\p_format{|l|p|}% @@ -1189,7 +1229,7 @@ \def\tabl_start_regular_two[#1][#2]% {\def\p_format{#1}% \ifx\p_format\empty - \def\p_format{|l|p|}% + \let\p_format\tabl_default_format \fi \lettabulationparameter\c!format\p_format \setupcurrenttabulation[#2]% @@ -1278,7 +1318,7 @@ \fi\fi} \def\tabl_tabulate_outside_after_indeed - {\tabulationparameter\c!after}% + {\tabulationparameter\c!after} \def\tabl_tabulate_outside_inbetween_indeed {\doifempty{\tabulationparameter\c!after} @@ -1313,6 +1353,7 @@ \edef\p_bodyfont {\tabulationparameter\c!bodyfont} \edef\p_indenting {\tabulationparameter\c!indenting}% \edef\p_keeptogether {\tabulationparameter\c!keeptogether}% + \edef\p_blank {\tabulationparameter\c!blank}% % \ifx\p_keeptogether\v!no \settrue \c_tabl_tabulate_tolerant_break @@ -1325,6 +1366,8 @@ \settrue\c_tabl_tabulate_split \csname\??tabulatesplit\tabulationparameter\c!split\endcsname % + \let\m_tabl_tabulate_blank_default\p_blank + % \d_tabl_tabulate_unit\tabulationparameter\c!unit \d_tabl_tabulate_margin\tabulationparameter\c!margin \let\m_tabl_tabulate_vrule_color_default\p_rulecolor @@ -1371,14 +1414,15 @@ \let\m_tabl_tabulate_vrule_color_local \empty \let\m_tabl_tabulate_vrule_color_default\empty % used local \let\m_tabl_tabulate_hrule_color_default\empty % used local +\let\m_tabl_tabulate_blank_default \empty \appendtoks - \global\let\m_tabl_tabulate_color_previous \empty - \global\let\m_tabl_tabulate_color \empty - \global\let\m_tabl_tabulate_text_color \empty - \global\let\m_tabl_tabulate_color_local \empty - \global\let\m_tabl_tabulate_vrule_color \empty - \global\let\m_tabl_tabulate_vrule_color_local \empty + \glet\m_tabl_tabulate_color_previous \empty + \glet\m_tabl_tabulate_color \empty + \glet\m_tabl_tabulate_text_color \empty + \glet\m_tabl_tabulate_color_local \empty + \glet\m_tabl_tabulate_vrule_color \empty + \glet\m_tabl_tabulate_vrule_color_local \empty \global \d_tabl_tabulate_vrulethickness_local\zeropoint \to \t_tabl_tabulate_every_row @@ -1470,7 +1514,7 @@ % ruled columns \def\tabl_tabulate_column_vruled_preset - {\global\let\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default + {\glet\m_tabl_tabulate_vrule_color_local\m_tabl_tabulate_vrule_color_default \global\d_tabl_tabulate_vrulethickness_local\d_tabl_tabulate_vrulethickness_default} \def\tabl_tabulate_column_vruled#1#2% @@ -1513,7 +1557,7 @@ \global\c_tabl_tabulate_max_vrulecolumn\zerocount} \def\tabl_tabulate_vrule_reset_step % undefined or relax - {\global\expandafter\let\csname\??tabulatevrule\the\fastloopindex\endcsname\undefined} + {\expandafter\glet\csname\??tabulatevrule\the\fastloopindex\endcsname\undefined} \appendtoks \tabl_tabulate_vrule_reset @@ -1606,12 +1650,12 @@ \egroup} \def\tabl_tabulate_hrule_spec_ignore#1% - {%\global\let\currenttabulationlocalhrulecolor\empty + {%\glet\currenttabulationlocalhrulecolor\empty %\global\d_tabl_tabulate_hrulethickness_local\d_tabl_tabulate_hrulethickness_default \doifelsefastoptionalcheck#1#1} \def\tabl_tabulate_hrule_spec_pickup#1% - {\global\let\currenttabulationlocalhrulecolor\m_tabl_tabulate_hrule_color_default + {\glet\currenttabulationlocalhrulecolor\m_tabl_tabulate_hrule_color_default \global\d_tabl_tabulate_hrulethickness_local\d_tabl_tabulate_hrulethickness_default \doifelsefastoptionalcheck{\tabl_tabulate_hrule_preset#1}#1} @@ -1625,10 +1669,11 @@ #1} \def\tabl_tabulate_hrule_inject_normal - {\hrule - \s!height.5\d_tabl_tabulate_hrulethickness_local - \s!depth .5\d_tabl_tabulate_hrulethickness_local - \relax} + {\autorule + \s!height .5\d_tabl_tabulate_hrulethickness_local + \s!depth .5\d_tabl_tabulate_hrulethickness_local + \s!left \d_tabl_tabulate_indent + \relax} \def\tabl_tabulate_hrule_inject_colored {\dousecolorparameter\currenttabulationlocalhrulecolor @@ -1686,21 +1731,21 @@ \unexpanded\def\tabl_tabulate_color_set#1% we could store the attributes at the cost of a lua call {\begingroup \clf_enablebackgroundalign % was \node_backgrounds_align_initialize - \global\let\tabl_tabulate_color_repeat\tabl_tabulate_color_repeat_second + \glet\tabl_tabulate_color_repeat\tabl_tabulate_color_repeat_second \global\settrue\c_tabl_tabulate_has_colors \ifnum\c_tabl_tabulate_column>\c_tabl_tabulate_max_colorcolumn \global\c_tabl_tabulate_max_colorcolumn\c_tabl_tabulate_column \fi - \global\expandafter\xdef\csname\??tabulatecolor\the\c_tabl_tabulate_column\endcsname{#1}% - \hbox \thealignbackgroundcolorattr{#1}{}% pack ? + \expandafter\xdef\csname\??tabulatecolor\the\c_tabl_tabulate_column\endcsname{#1}% + \hpack \thealignbackgroundcolorattr{#1}{}% pack ? \endgroup} \def\tabl_tabulate_color_repeat_second % for split off lines {\begingroup \scratchcounter\numexpr\c_tabl_tabulate_column-\plusone\relax % ugly ! \ifcsname\??tabulatecolor\the\scratchcounter\endcsname - %\hbox \thealignbackgroundcolorattr{\csname\??tabulatecolor\the\scratchcounter\endcsname}{}% pack ? - \hbox \thealignbackgroundcolorattr{\lastnamedcs}{}% pack ? + % \hbox \thealignbackgroundcolorattr{\csname\??tabulatecolor\the\scratchcounter\endcsname}{}% pack ? + \hpack \expandafter\thealignbackgroundcolorattr\expandafter{\lastnamedcs}{}% pack ? \fi \endgroup} @@ -1722,7 +1767,7 @@ {\dofastloopcs\c_tabl_tabulate_max_colorcolumn\tabl_tabulate_color_reset_step} \def\tabl_tabulate_color_reset_step % undefined or empty? - {\global\expandafter\let\csname\??tabulatecolor\number\fastloopindex\endcsname\undefined} + {\expandafter\glet\csname\??tabulatecolor\number\fastloopindex\endcsname\undefined} \appendtoks \tabl_tabulate_color_reset @@ -1771,17 +1816,20 @@ \tabl_tabulate_register_par_options \to \t_tabl_tabulate_every_row +\def\tabl_tabulate_flush_indent_indeed + {\hbox to \d_tabl_tabulate_indent % pack ? + {% we now have a local hsize, and since we want to + % register positional info (i.e. real hsizes) we + % need to reconstitute the original hsize + \advance\hsize\d_tabl_tabulate_indent + % this is indeed rather messy and took a few hours + % to dis/uncover + \the\t_tabl_tabulate_every_row + \hss}} + \def\tabl_tabulate_flush_indent {\ifnum\c_tabl_tabulate_column=\zerocount - \hbox to \d_tabl_tabulate_indent % pack ? - {% we now have a local hsize, and since we want to - % register positional info (i.e. real hsizes) we - % need to reconstitute the original hsize - \advance\hsize\d_tabl_tabulate_indent - % this is indeed rather messy and took a few hours - % to dis/uncover - \the\t_tabl_tabulate_every_row - \hss}% + \tabl_tabulate_flush_indent_indeed \fi} \def\tabl_tabulate_digits{\digits} @@ -1800,7 +1848,7 @@ \unexpanded\def\tabl_tabulate_bskip_first {\setbox\b_tabl_tabulate\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop} \unexpanded\def\tabl_tabulate_eskip_first {\par\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes} -\unexpanded\def\tabl_tabulate_xbskip_first{\hbox\bgroup\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop} +\unexpanded\def\tabl_tabulate_xbskip_first{\hpack\bgroup\vbox\bgroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_nop} \unexpanded\def\tabl_tabulate_xeskip_first{\par\egroup\egroup\glet\tabl_tabulate_hook\tabl_tabulate_hook_yes} \let\tabl_tabulate_bbskip\relax @@ -1831,12 +1879,12 @@ % \def\tabl_tabulate_break_state_set % {%\writestatus{SET}{\the\c_tabl_tabulate_noflines}% -% \global\expandafter\let\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\conditionaltrue} +% \expandafter\glet\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\conditionaltrue} % % \def\tabl_tabulate_break_state_reset % {\ifcsname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname % %\writestatus{RESET}{\the\c_tabl_tabulate_noflines}% -% \global\expandafter\let\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\undefined +% \expandafter\glet\csname\??tabulatenobreak\the\c_tabl_tabulate_noflines\endcsname\undefined % \fi} % % \def\tabl_tabulate_break_state_allowbreak @@ -1912,8 +1960,6 @@ %D %D \typebuffer \getbuffer -\let\NI\relax - \unexpanded\def\tabl_tabulate_NI_first{\doifelsefastoptionalcheck\tabl_tbl_NI_yes\tabl_tbl_NI_nop} \def\tabl_tbl_NI_yes[#1]{\NC \itemtag[#1]\NC} @@ -2189,7 +2235,7 @@ % \def\tabulatedoHRfive % horizontal rule line (break untested) % {\starttabulatenoalign -% \globallet\dotabulateautoline\dotabulatelinerule +% \glet\dotabulateautoline\dotabulatelinerule % %\ifcase#1\or % todo: check what this does % \ifnum\noftabulatelines=\zerocount % \glet\dotabulateautoline\donothing @@ -2204,9 +2250,9 @@ % \tabl_tabulate_break_no % \ifx\dotabulateautoline\dotabulatelinerule\kern-\lineheight\fi % \ifnum\noftabulatelines=\totalnoftabulatelines -% \@EA\dotabulatenobreak +% \expandafter\dotabulatenobreak % \else -% \@EA\tabl_tabulate_break_allow +% \expandafter\tabl_tabulate_break_allow % \fi % \stoptabulatenoalign % \dotabulateautoline @@ -2403,8 +2449,8 @@ \dostarttaggedchained\t!tabulate\empty\??tabulation \dostarttagged\t!tabulaterow\empty \setfalse\inhibitmargindata % new per 2012.06.13 ... really needed - \everycr\expandafter{\the\everycr\dostoptagged\dostarttagged\t!tabulaterow\empty}% - % \toksapp\everycr{\dostoptagged\dostarttagged\t!tabulaterow\empty}% + % \everycr\expandafter{\the\everycr\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}% + \toksapp\everycr{\noalign{\the\t_tabl_tabulate_every_real_row}\dostoptagged\dostarttagged\t!tabulaterow\empty}% \expandafter\halign\expandafter{\the\t_tabl_tabulate_preamble\crcr\tabl_tabulate_insert_content\crcr}% \dostoptagged \dostoptagged @@ -2504,9 +2550,11 @@ \def\tabl_tabulate_TB_indeed[#1]% {\iffirstargument \blank[#1] - \else + \else\ifx\m_tabl_tabulate_blank_default\empty \blank - \fi + \else + \blank[\m_tabl_tabulate_blank_default]% + \fi\fi \stoptabulatenoalign} % to be tested: @@ -2729,4 +2777,295 @@ \unexpanded\def\tabulaterowtype{\tabl_tabulate_compact_row\type} \unexpanded\def\tabulaterowtyp {\tabl_tabulate_compact_row\typ} +%D Here we plug in a row background feature. As we only have support for +%D \type {frame=name} we can use these variables. +%D +%D \starttyping +%D \startuseMPgraphic{foo} +%D fill unitsquare +%D xyscaled (RuleWidth,RuleHeight+RuleDepth) enlarged (ExHeight/4,ExHeight/8) +%D randomized ExHeight +%D shifted (-ExHeight/8,ExHeight/16) +%D withcolor RuleColor ; +%D \stopuseMPgraphic +%D +%D \setuptabulate % wel only have frame=name so we can use these: +%D [background=foo, +%D backgroundcolor=darkred, +%D foregroundcolor=white] +%D +%D \definelinefiller[foo][mp=foo,color=darkgreen] +%D \definelinefiller[bar][mp=foo,color=darkred] +%D +%D \starttabulate[|||] +%D \DB foo \BC bar \BC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \stoptabulate +%D +%D \starttabulate[|||] +%D \PB foo \BC bar \BC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \stoptabulate +%D +%D \starttabulate[|||] +%D \FB[bar] foo \BC bar \BC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \stoptabulate +%D +%D \startnarrower +%D \starttabulate[|||] +%D \DB foo \DB bar \BC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \stoptabulate +%D \stopnarrower +%D +%D \starttabulate[|||] +%D \BC foo \BC bar \BC \NR +%D \NL[magenta] foo \NC bar \NC \NR +%D \NL[yellow] foo \NC bar \NC \NR +%D \NL[cyan] foo \NC bar \NC \NR +%D \NL[gray] foo \NC bar \NC \NR +%D \stoptabulate +%D +%D \starttabulate +%D \NL[red] foo \NC bar \NC \NR +%D \NL[green] foo \NL[red] bar \NC \NR +%D \NC foo \NC bar \NC \NR +%D \NL[blue] foo \NC \input tufte \NC \NR +%D \NL[gray] foo \NC bar \NC \NR +%D \NL[yellow] foo \NC bar \NC \NR +%D \stoptabulate +%D \stoptyping + +% \setuptabulate +% [\c!background=, +% \c!backgroundcolor=, +% \c!foregroundcolor=, +% \c!foregroundstyle=] + +\let\m_table_current_row_background \empty +\let\m_table_current_row_background_default \empty +\let\m_table_current_row_background_filler \empty +\let\m_table_current_row_background_defaultfiller\empty +\let\m_table_current_row_background_auto \empty + +\unexpanded\def\tabl_register_row_background#1% + {\xdef\m_table_current_row_background{#1}} + +\unexpanded\def\tabl_register_row_background_filler#1% + {\xdef\m_table_current_row_background_filler{#1}} + +\unexpanded\def\tabl_synchronize_row_background + {\iftrialtypesetting\else + \ifx\m_table_current_row_background_filler\empty + \ifx\m_table_current_row_background\empty + % nothing + \tabl_synchronize_row_background_dummy + \else + \tabl_synchronize_row_background_indeed\m_table_current_row_background + \fi + \else + \tabl_synchronize_row_background_filler_indeed\m_table_current_row_background_filler + \fi + \fi} + +\unexpanded\def\tabl_synchronize_row_background_dummy + {\iftrialtypesetting\else + \begingroup + %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\zerocount\zeropoint + \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\zerocount\zeropoint + \endgroup + \fi} + +\unexpanded\def\tabl_synchronize_row_background_indeed#1% + {\iftrialtypesetting\else + \begingroup + \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata + \dousecolorparameter{#1}% + \setbox\scratchbox\hpack{}% + %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\scratchbox\d_tabl_tabulate_indent + \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent + \endgroup + \fi} + +\unexpanded\def\tabl_synchronize_row_background_filler_indeed#1% + {\iftrialtypesetting\else + \begingroup + \clf_enablebackgroundalign % can be moved into \clf_setbackgroundrowdata + \node_linefiller_set{#1}% + \setbox\scratchbox\hpack{}% + %\clf_setbackgroundrowdata\numexpr\c_tabl_tabulate_nofrealrows+\minusone\relax\scratchbox\d_tabl_tabulate_indent + \clf_setbackgroundrowdata\c_tabl_tabulate_nofrealrows\scratchbox\d_tabl_tabulate_indent + \endgroup + \fi} + +\appendtoks + \glet\m_table_current_row_background\empty + \glet\m_table_current_row_background_filler\empty + \global\c_tabl_tabulate_nofrealrows\zerocount + \global\c_tabl_tabulate_autocolor\zerocount + \clf_resetbackgroundrowdata +\to \t_tabl_tabulate_initializers_first + +\appendtoks + \glet\m_table_current_row_background\empty + \glet\m_table_current_row_background_filler\empty + \global\c_tabl_tabulate_nofrealrows\zerocount + \global\c_tabl_tabulate_autocolor\zerocount + \clf_resetbackgroundrowdata +\to \t_tabl_tabulate_initializers_second + +\appendtoks + \tabl_synchronize_row_background +\to \t_tabl_tabulate_every_real_row + +\appendtoks + \glet\m_table_current_row_background\empty + \glet\m_table_current_row_background_filler\empty +\to \t_tabl_tabulate_every_after_row + +\unexpanded\def\tabl_tabulate_NL_first[#1]% + {\tabl_tabulate_column_normal\zerocount\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background{#1}% + \fi + \ignorespaces} + +\unexpanded\def\tabl_tabulate_ND_first + {\tabl_tabulate_column_normal\zerocount\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background\m_table_current_row_background_default + \fi + \ignorespaces} + +\unexpanded\def\tabl_tabulate_LB_first[#1]% + {\tabl_tabulate_column_normal\plusone\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background{#1}% + \fi + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \ignorespaces} + +\unexpanded\def\tabl_tabulate_DB_first + {\tabl_tabulate_column_normal\plusone\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background\m_table_current_row_background_default + \fi + \let\fontstyle\globalfontstyle + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \ignorespaces} + +\unexpanded\def\tabl_tabulate_NF_first[#1]% + {\tabl_tabulate_column_normal\zerocount\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background_filler{#1}% + \fi + \ignorespaces} + +\unexpanded\def\tabl_tabulate_NP_first + {\tabl_tabulate_column_normal\zerocount\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background_filler\m_table_current_row_background_default_filler + \fi + \ignorespaces} + +\unexpanded\def\tabl_tabulate_FB_first[#1]% + {\tabl_tabulate_column_normal\plusone\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background_filler{#1}% + \fi + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \ignorespaces} + +\unexpanded\def\tabl_tabulate_PB_first + {\tabl_tabulate_column_normal\plusone\zerocount\relax + \ifcase\c_tabl_tabulate_column\or + \tabl_register_row_background_filler\m_table_current_row_background_default_filler + \fi + \let\fontstyle\globalfontstyle + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \ignorespaces} + +\unexpanded\def\tabl_tabulate_BC_first % overloaded + {\tabl_tabulate_column_normal\plusone\zerocount + \let\fontstyle\globalfontstyle + \ifx\m_table_current_row_background\empty + \ifx\m_table_current_row_background_filler\empty + \usetabulationstyleandcolor\c!headstyle\c!headcolor + \else + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \fi + \else + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \fi} + +\unexpanded\def\tabl_tabulate_A_first + {\global\advance\c_tabl_tabulate_autocolor\plusone + \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\number\c_tabl_tabulate_autocolor}}% + \ifx\m_table_current_row_background_auto\empty + \global\c_tabl_tabulate_autocolor\plusone + \edef\m_table_current_row_background_auto{\tabulateparameter{\c!backgroundcolor:\number\c_tabl_tabulate_autocolor}}% + \fi + \ifx\m_table_current_row_background_auto\empty + \let\m_table_current_row_background_auto\empty % \m_table_current_row_background_default + \fi + \tabl_register_row_background{\m_table_current_row_background_auto}} + +\unexpanded\def\tabl_tabulate_NA_first + {\tabl_tabulate_column_normal\zerocount\zerocount\relax + \iftrialtypesetting\else + \ifcase\c_tabl_tabulate_column\or + \tabl_tabulate_A_first + \fi + \fi + \ignorespaces} + +\unexpanded\def\tabl_tabulate_BA_first + {\tabl_tabulate_column_normal\plusone\zerocount\relax + \iftrialtypesetting\else + \ifcase\c_tabl_tabulate_column\or + \tabl_tabulate_A_first + \fi + \fi + \usetabulationstyleandcolor\c!foregroundstyle\c!foregroundcolor + \ignorespaces} + +\appendtoks + \let\NL\tabl_tabulate_NL_first % NC with Line + \let\ND\tabl_tabulate_ND_first % NC with Default Line + \let\LB\tabl_tabulate_LB_first % BC with Line + \let\DB\tabl_tabulate_DB_first % BC with Default Line + \let\NF\tabl_tabulate_NF_first % NC with Filler + \let\NP\tabl_tabulate_NP_first % NC with Predefined Filler + \let\FB\tabl_tabulate_FB_first % BC with Filler + \let\PB\tabl_tabulate_PB_first % BC with Predefined Filler + \let\NA\tabl_tabulate_NA_first % NC with Auto Line + \let\BA\tabl_tabulate_BA_first % NC with Auto Line +\to \t_tabl_tabulate_initializers_first + +\appendtoks + \edef\m_table_current_row_background_default {\tabulateparameter\c!backgroundcolor}% + \edef\m_table_current_row_background_default_filler{\tabulateparameter\c!background}% + \let \m_table_current_row_background_auto \empty +\to \everytabulate + +\setuptabulate + [\c!headcolor=, + \c!headstyle=\bf, + \c!backgroundcolor=\tabulationparameter\c!rulecolor, + \c!foregroundcolor=, + \c!foregroundstyle=\tabulationparameter\c!headstyle] + \protect \endinput diff --git a/tex/context/base/mkiv/tabl-tsp.mkiv b/tex/context/base/mkiv/tabl-tsp.mkiv index 2c4b694b3..e0ddce38a 100644 --- a/tex/context/base/mkiv/tabl-tsp.mkiv +++ b/tex/context/base/mkiv/tabl-tsp.mkiv @@ -441,6 +441,35 @@ \exitloop \fi\fi} +%D Maybe handy: +%D +%D \starttyping +%D \splitfloat +%D {\placefigure{some caption}} +%D {\startsplittext +%D \typefile[option=TEX,before=,after=]{oeps.tex} +%D \stopsplittext} +%D \stoptyping + +\def\handlesplittext#1% + {\setbox\tsplitresult\vbox + {\vsplit\tsplitcontent to \dimexpr#1-\lineheight\relax}} + +\unexpanded\def\startsplittext + {\begingroup + \resettsplit + \let\tsplitminimumfreelines\!!zerocount + \let\tsplitminimumfreespace\!!zeropoint + \let\extrasplitfloatlines \!!plusone + \let\tsplitdirectsplitter \handlesplittext + \setbox\tsplitcontent\vbox\bgroup + \insidefloattrue} + +\unexpanded\def\stopsplittext + {\egroup + \handledirecttsplit + \endgroup} + \protect \endinput % test cases diff --git a/tex/context/base/mkiv/tabl-xtb.lua b/tex/context/base/mkiv/tabl-xtb.lua index 524ca109c..c9d50638e 100644 --- a/tex/context/base/mkiv/tabl-xtb.lua +++ b/tex/context/base/mkiv/tabl-xtb.lua @@ -70,7 +70,7 @@ local getbox = nuts.getbox local getwhd = nuts.getwhd local setlink = nuts.setlink -local setdir = nuts.setdir +local setdirection = nuts.setdirection local setshift = nuts.setshift local copy_node_list = nuts.copy_list @@ -84,6 +84,8 @@ local new_glue = nodepool.glue local new_kern = nodepool.kern local new_hlist = nodepool.hlist +local lefttoright_code = nodes.dirvalues.lefttoright + local v_stretch = variables.stretch local v_normal = variables.normal local v_width = variables.width @@ -375,7 +377,8 @@ function xtables.set_reflow_width() -- drc.dimensionstate = dimensionstate -- - local nx, ny = drc.nx, drc.ny + local nx = drc.nx + local ny = drc.ny if nx > 1 or ny > 1 then -- local spans = data.spans -- not used local self = true @@ -886,13 +889,13 @@ function xtables.construct() -- we have a direction issue here but hpack_node_list(list,0,"exactly","TLT") cannot be used -- due to the fact that we need the width local hbox = hpack_node_list(list) - setdir(hbox,"TLT") + setdirection(hbox,lefttoright_code) result[nofr] = { hbox, size, i < nofrange and rowdistance > 0 and rowdistance or false, -- might move false, - rp and rp.samepage or false, + rp or false, } end end @@ -901,7 +904,7 @@ function xtables.construct() result[1] [5] = false result[nofr][5] = false for i=2,nofr-1 do - local r = result[i] + local r = result[i][5] if r == v_both or r == v_before then result[i-1][5] = true elseif r == v_after then diff --git a/tex/context/base/mkiv/tabl-xtb.mkvi b/tex/context/base/mkiv/tabl-xtb.mkvi index dc4a30e2b..148304331 100644 --- a/tex/context/base/mkiv/tabl-xtb.mkvi +++ b/tex/context/base/mkiv/tabl-xtb.mkvi @@ -102,6 +102,10 @@ \newcount\c_tabl_x_nesting \newcount\c_tabl_x_skip_mode % 1 = skip \newdimen\d_tabl_x_textwidth +\newcount\c_tabl_x_swapped +\newcount\c_tabl_x_swapped_max + +\let\m_tabl_x_swapped_settings\empty \let\currentxtablerow \clf_x_table_r \let\currentxtablecolumn\clf_x_table_c @@ -112,6 +116,7 @@ \installcorenamespace{xtable} \installcorenamespace{xtablecheck} +\installcorenamespace{xtableswap} \installframedautocommandhandler \??xtable {xtable} \??xtable @@ -271,6 +276,8 @@ \let\tabl_x_start_cell_nop\relax \let\tabl_x_stop_cell \relax +\newtoks\t_table_x_cleanup + \unexpanded\def\tabl_x_process {\begingroup % * \forgetall % moved here @@ -296,6 +303,7 @@ % not so nice but needed as we use this in the setup \linewidth\xtableparameter\c!rulethickness\relax % so we freeze it + \c_tabl_x_swapped_max\zerocount \begingroup \let\tabl_x_start_row_yes \tabl_x_start_row_reflow_width_yes \let\tabl_x_start_row_nop \tabl_x_start_row_reflow_width_nop @@ -305,6 +313,10 @@ \let\tabl_x_stop_cell \tabl_x_stop_cell_reflow_width \settrialtypesetting \tabl_x_get_buffer + \ifcase\c_tabl_x_swapped_max + \else + \tabl_x_flush_swapped + \fi \clf_x_table_reflow_width \endgroup \begingroup @@ -315,7 +327,11 @@ \let\tabl_x_start_cell_nop\tabl_x_start_cell_reflow_height_nop \let\tabl_x_stop_cell \tabl_x_stop_cell_reflow_height \settrialtypesetting - \tabl_x_get_buffer + \ifcase\c_tabl_x_swapped_max + \tabl_x_get_buffer + \else + \tabl_x_flush_swapped + \fi \clf_x_table_reflow_height \endgroup \begingroup @@ -325,7 +341,11 @@ \let\tabl_x_start_cell_yes\tabl_x_start_cell_construct_yes \let\tabl_x_start_cell_nop\tabl_x_start_cell_construct_nop \let\tabl_x_stop_cell \tabl_x_stop_cell_construct - \tabl_x_get_buffer + \ifcase\c_tabl_x_swapped_max + \tabl_x_get_buffer + \else + \tabl_x_flush_swapped + \fi \clf_x_table_construct \endgroup \endgroup % * @@ -340,6 +360,7 @@ \dostoptagged \resetbuffer[\tabl_x_current_buffer]% \resetcharacteralign + \the\t_table_x_cleanup \egroup} % text flow split modes @@ -477,10 +498,6 @@ \unexpanded\def\stopxcell {\tabl_x_stop_cell} -\unexpanded\def\dummyxcell#1% - {\tabl_x_start_cell_nop - \tabl_x_stop_cell} - \unexpanded\def\dummyxcell {\tabl_x_start_cell_nop \tabl_x_stop_cell} @@ -879,4 +896,124 @@ \let\NR\tabl_x_nr \to \everypreparextable +%D Another bonus, suggested by Taco at the 2018 \CONTEXT\ meeting. + +\unexpanded\def\tabl_x_c_cell_start#settings% + {\begingroup + \tabl_x_set_checked{#settings}% + \doifelsenextoptionalcs\tabl_x_start_cell_yes\tabl_x_start_cell_nop} + +\unexpanded\def\tabl_x_c_cell_stop + {\tabl_x_stop_cell + \endgroup} + +% \unexpanded\def\dummyxcell +% {\tabl_x_start_cell_nop +% \tabl_x_stop_cell} + +\def\tabl_x_flush_swapped + {\dorecurse\c_tabl_x_swapped_max + {\expandafter + \startxrow + \the\csname\??xtableswap##1\endcsname\relax + \stopxrow}} + +\def\tabl_x_collect_allocate + {\expandafter\newtoks\csname\??xtableswap\number\c_tabl_x_swapped\endcsname + \expandafter\let\expandafter\t_tabl_x_swapped\csname\??xtableswap\number\c_tabl_x_swapped\endcsname} + +\def\tabl_x_collect_advance + {\global\advance\c_tabl_x_swapped\plusone + \ifnum\c_tabl_x_swapped>\c_tabl_x_swapped_max + \global\c_tabl_x_swapped_max\c_tabl_x_swapped + \fi + \expandafter\let\expandafter\t_tabl_x_swapped\csname\??xtableswap\number\c_tabl_x_swapped\endcsname + \ifx\t_tabl_x_swapped\relax + \tabl_x_collect_allocate + \fi} + +\unexpanded\def\tabl_x_collect_cell_start + {\doifelsenextoptionalcs + \tabl_x_collect_cell_start_yes + \tabl_x_collect_cell_start_nop} + +\def\tabl_x_collect_cell_start_nop#content\stopxcell + {\tabl_x_collect_advance + \ifx\m_tabl_x_swapped_settings\empty + \gtoksapp\t_tabl_x_swapped{\tabl_x_c_cell_start{}#content\tabl_x_c_cell_stop}% + \else + \gtoksapp\t_tabl_x_swapped\expandafter{\expandafter\tabl_x_c_cell_start\expandafter{\m_tabl_x_swapped_settings}#content\tabl_x_c_cell_stop}% + \fi} + +\def\tabl_x_collect_cell_start_yes[#settings]#content\stopxcell + {\tabl_x_collect_advance + \ifx\m_tabl_x_swapped_settings\empty + \gtoksapp\t_tabl_x_swapped{\tabl_x_c_cell_start{}[#settings]#content\tabl_x_c_cell_stop}% + \else + \gtoksapp\t_tabl_x_swapped\expandafter{\expandafter\tabl_x_c_cell_start\expandafter{\m_tabl_x_swapped_settings}[#settings]#content\tabl_x_c_cell_stop}% + \fi + \getdummyparameters[\c!ny=1,#settings]% + \scratchcounter\numexpr\dummyparameter\c!ny-\plusone\relax + \ifcase\scratchcounter\else + \dorecurse\scratchcounter\tabl_x_collect_advance + \fi} + +\unexpanded\def\startxcolumn % todo: arguments + {\begingroup + \global\c_tabl_x_swapped\zerocount + \let\startxcell\tabl_x_collect_cell_start + \let\stopxcell \relax + \doifelsenextoptionalcs\tabl_x_start_column_yes\tabl_x_start_column_nop} + +\def\tabl_x_start_column_yes[#1]% + {\xdef\m_tabl_x_swapped_settings{#1}} + +\def\tabl_x_start_column_nop + {\glet\m_tabl_x_swapped_settings\empty} + +\unexpanded\def\stopxcolumn + {\endgroup} + +\appendtoks + \dorecurse\c_tabl_x_swapped_max + {\global\csname\??xtableswap\number#1\endcsname\emptytoks}% +\to \t_table_x_cleanup + +%D \stopbuffer +%D \setupxtable[one][foregroundcolor=red] +%D \setupxtable[two][foregroundcolor=blue] +%D +%D \startlinecorrection +%D \startxtable +%D \startxrow[one] +%D \startxcell[width=5cm] Row 1, Column 1 \stopxcell +%D \startxcell Row 1, Column 2 \stopxcell +%D \startxcell Row 1, Column 3 \stopxcell +%D \stopxrow +%D \startxrow[two] +%D \startxcell Row 2, Column 1 \stopxcell +%D \startxcell Row 2, Column 2 \stopxcell +%D \startxcell Row 2, Column 3 \stopxcell +%D \stopxrow +%D \stopxtable +%D \stoplinecorrection +%D +%D \startlinecorrection +%D \startxtable +%D \startxcolumn[one] +%D \startxcell[width=5cm] Row 1, Column 1 \stopxcell +%D \startxcell Row 1, Column 2 \stopxcell +%D \startxcell Row 1, Column 3 \stopxcell +%D \stopxcolumn +%D \startxcolumn[two] +%D \startxcell Row 2, Column 1 \stopxcell +%D \startxcell Row 2, Column 2 \stopxcell +%D \startxcell Row 2, Column 3 \stopxcell +%D \stopxcolumn +%D \stopxtable +%D \stoplinecorrection +%D \stopbuffer +%D +%D \typebuffer \getbuffer + \protect \endinput diff --git a/tex/context/base/mkiv/task-ini.lua b/tex/context/base/mkiv/task-ini.lua index f41fb9b08..19fff66b8 100644 --- a/tex/context/base/mkiv/task-ini.lua +++ b/tex/context/base/mkiv/task-ini.lua @@ -18,224 +18,132 @@ if not modules then modules = { } end modules ['task-ini'] = { -- not apply the font handler, we can remove all checks for subtypes 255 local tasks = nodes.tasks -local prependaction = tasks.prependaction local appendaction = tasks.appendaction local disableaction = tasks.disableaction local enableaction = tasks.enableaction local freezegroup = tasks.freezegroup local freezecallbacks = callbacks.freeze -appendaction("processors", "normalizers", "languages.replacements.handler") -- disabled - -appendaction("processors", "normalizers", "typesetters.wrappers.handler") -- disabled -appendaction("processors", "normalizers", "typesetters.characters.handler") -- always on -appendaction("processors", "normalizers", "fonts.collections.process") -- disabled -appendaction("processors", "normalizers", "fonts.checkers.missing") -- disabled - -appendaction("processors", "characters", "scripts.autofontfeature.handler") -appendaction("processors", "characters", "scripts.splitters.handler") -- disabled -appendaction("processors", "characters", "typesetters.cleaners.handler") -- disabled -appendaction("processors", "characters", "typesetters.directions.handler") -- disabled -appendaction("processors", "characters", "typesetters.cases.handler") -- disabled -appendaction("processors", "characters", "typesetters.breakpoints.handler") -- disabled -appendaction("processors", "characters", "scripts.injectors.handler") -- disabled - -------------("processors", "words", "languages.replacements.handler") -- disabled -appendaction("processors", "words", "languages.words.check") -- disabled -- might move up, no disc check needed then -appendaction("processors", "words", "languages.hyphenators.handler") -- always on -appendaction("processors", "words", "typesetters.initials.handler") -- disabled -- might move up -appendaction("processors", "words", "typesetters.firstlines.handler") -- disabled - -appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split") -- experimental -appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo -appendaction("processors", "fonts", "nodes.injections.handler") -appendaction("processors", "fonts", "typesetters.fontkerns.handler") -appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo -appendaction("processors", "fonts", "builders.kernel.ligaturing") -- not always on (could be selective: if only node mode) -appendaction("processors", "fonts", "builders.kernel.kerning") -- not always on (could be selective: if only node mode) -appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move) -------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling) -appendaction("processors", "fonts", "nodes.handlers.flatten") - -appendaction("processors", "lists", "typesetters.rubies.check") -- disabled (maybe someplace else) -appendaction("processors", "lists", "typesetters.characteralign.handler") -- disabled (we need to to this after otf appliance) -appendaction("processors", "lists", "typesetters.spacings.handler") -- disabled -appendaction("processors", "lists", "typesetters.kerns.handler") -- disabled -appendaction("processors", "lists", "typesetters.digits.handler") -- disabled (after otf handling) -appendaction("processors", "lists", "typesetters.italics.handler") -- disabled (after otf/kern handling) -appendaction("processors", "lists", "languages.visualizediscretionaries") -- disabled - -appendaction("processors", "after", "typesetters.marksuspects") - -appendaction("shipouts", "normalizers", "typesetters.showsuspects") -appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler") -- disabled -------------("shipouts", "normalizers", "nodes.handlers.cleanuppage") -- disabled -appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace") -- disabled -appendaction("shipouts", "normalizers", "typesetters.alignments.handler") -- disabled -appendaction("shipouts", "normalizers", "nodes.references.handler") -- disabled -appendaction("shipouts", "normalizers", "nodes.destinations.handler") -- disabled -appendaction("shipouts", "normalizers", "nodes.rules.handler") -- disabled -appendaction("shipouts", "normalizers", "nodes.shifts.handler") -- disabled -appendaction("shipouts", "normalizers", "structures.tags.handler") -- disabled -appendaction("shipouts", "normalizers", "nodes.handlers.accessibility") -- disabled -appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds") -- disabled -appendaction("shipouts", "normalizers", "nodes.handlers.alignbackgrounds") -- disabled -------------("shipouts", "normalizers", "nodes.handlers.export") -- disabled -appendaction("shipouts", "normalizers", "typesetters.rubies.attach") -- disabled - -appendaction("shipouts", "finishers", "nodes.visualizers.handler") -- disabled -appendaction("shipouts", "finishers", "attributes.colors.handler") -- disabled -appendaction("shipouts", "finishers", "attributes.transparencies.handler") -- disabled -appendaction("shipouts", "finishers", "attributes.colorintents.handler") -- disabled -appendaction("shipouts", "finishers", "attributes.negatives.handler") -- disabled -appendaction("shipouts", "finishers", "attributes.effects.handler") -- disabled -appendaction("shipouts", "finishers", "attributes.viewerlayers.handler") -- disabled - ---maybe integrate relocate and families - -appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nohead") - -appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nohead") -- always on (maybe disabled) -appendaction("math", "normalizers", "noads.handlers.variants", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.families", nil, "nohead") -- always on - -appendaction("math", "normalizers", "noads.handlers.render", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.fixscripts",nil, "nohead") -- * first-- always on -appendaction("math", "normalizers", "noads.handlers.domains", nil, "nohead") -- * last -- disabled -appendaction("math", "normalizers", "noads.handlers.autofences",nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.resize", nil, "nohead") -- always on -------------("math", "normalizers", "noads.handlers.respace", nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.alternates",nil, "nohead") -- always on -appendaction("math", "normalizers", "noads.handlers.tags", nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.italics", nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nohead") -- disabled -appendaction("math", "normalizers", "noads.handlers.classes", nil, "nohead") -- disabled - -appendaction("math", "builders", "builders.kernel.mlist_to_hlist") -- always on -------------("math", "builders", "noads.handlers.italics", nil, "nohead") -- disabled -appendaction("math", "builders", "typesetters.directions.processmath") -- disabled (has to happen pretty late) -appendaction("math", "builders", "noads.handlers.makeup", nil, "nohead") -- disabled (has to happen last) -appendaction("math", "builders", "noads.handlers.align", nil, "nohead") - -appendaction("finalizers", "lists", "typesetters.paragraphs.normalize") -- moved here -appendaction("finalizers", "lists", "typesetters.margins.localhandler") -- disabled -appendaction("finalizers", "lists", "builders.paragraphs.keeptogether") -------------("finalizers", "lists", "nodes.handlers.graphicvadjust") -- todo -appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize") -- experimental -appendaction("finalizers", "lists", "builders.paragraphs.tag") - --- the next can also be in contributers normalizers (when we remove the loop in the handler) - -appendaction("finalizers", "lists", "nodes.linefillers.handler") - -appendaction("contributers", "normalizers", "nodes.handlers.flattenline") -appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds") - --- still experimental - -appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler") -- disabled -appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate") - -appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler") -- last ! -appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler") -- here ! - -------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler") -appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler") -appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler") -- here ! - --- experimental too - -appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler") -appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler") - --- rather special (this might get hardcoded): - -prependaction("processors", "before", "nodes.properties.attach") -- enabled but optimized for quick abort -appendaction ("shipouts", "normalizers", "nodes.properties.delayed") -- enabled but optimized for quick abort - --- speedup: only kick in when used - -disableaction("processors", "typesetters.wrappers.handler") -disableaction("processors", "languages.replacements.handler") -disableaction("processors", "typesetters.characteralign.handler") -disableaction("processors", "scripts.autofontfeature.handler") -disableaction("processors", "scripts.splitters.handler") -disableaction("processors", "scripts.injectors.handler") -- was enabled -disableaction("processors", "fonts.collections.process") -disableaction("processors", "fonts.checkers.missing") -disableaction("processors", "chars.handle_breakpoints") -disableaction("processors", "typesetters.cleaners.handler") -disableaction("processors", "typesetters.cases.handler") -disableaction("processors", "typesetters.digits.handler") -disableaction("processors", "typesetters.breakpoints.handler") -disableaction("processors", "typesetters.directions.handler") -disableaction("processors", "languages.words.check") -disableaction("processors", "typesetters.initials.handler") -disableaction("processors", "typesetters.firstlines.handler") -disableaction("processors", "typesetters.spacings.handler") -disableaction("processors", "typesetters.kerns.handler") -disableaction("processors", "typesetters.italics.handler") -disableaction("processors", "languages.visualizediscretionaries") -disableaction("processors", "nodes.handlers.stripping") -disableaction("processors", "builders.paragraphs.solutions.splitters.split") -disableaction("processors", "typesetters.rubies.check") -disableaction("processors", "typesetters.fontkerns.handler") -disableaction("processors", "nodes.handlers.flatten") -disableaction("processors", "typesetters.marksuspects") - -disableaction("shipouts", "typesetters.showsuspects") -disableaction("shipouts", "typesetters.margins.finalhandler") -disableaction("shipouts", "builders.paragraphs.expansion.trace") -disableaction("shipouts", "typesetters.alignments.handler") -disableaction("shipouts", "nodes.rules.handler") -disableaction("shipouts", "nodes.shifts.handler") -disableaction("shipouts", "attributes.colors.handler") -disableaction("shipouts", "attributes.transparencies.handler") -disableaction("shipouts", "attributes.colorintents.handler") -disableaction("shipouts", "attributes.effects.handler") -disableaction("shipouts", "attributes.negatives.handler") -disableaction("shipouts", "attributes.viewerlayers.handler") -disableaction("shipouts", "structures.tags.handler") -disableaction("shipouts", "nodes.visualizers.handler") -disableaction("shipouts", "nodes.handlers.accessibility") -disableaction("shipouts", "nodes.handlers.backgrounds") -disableaction("shipouts", "nodes.handlers.alignbackgrounds") -disableaction("shipouts", "nodes.references.handler") -disableaction("shipouts", "nodes.destinations.handler") --------------("shipouts", "nodes.handlers.export") -disableaction("shipouts", "typesetters.rubies.attach") - -disableaction("finalizers", "typesetters.margins.localhandler") -disableaction("finalizers", "builders.paragraphs.keeptogether") -disableaction("finalizers", "builders.paragraphs.solutions.splitters.optimize") --------------("finalizers", "nodes.handlers.graphicvadjust") -- sort of obsolete -disableaction("finalizers", "builders.paragraphs.tag") -disableaction("finalizers", "nodes.linefillers.handler") - -disableaction("contributers","nodes.handlers.flattenline") -disableaction("contributers","nodes.handlers.textbackgrounds") - -disableaction("math", "noads.handlers.showtree") -disableaction("math", "noads.handlers.tags") -disableaction("math", "noads.handlers.italics") -disableaction("math", "noads.handlers.collapse") -disableaction("math", "noads.handlers.kernpairs") -disableaction("math", "noads.handlers.domains") -disableaction("math", "noads.handlers.classes") -disableaction("math", "noads.handlers.autofences") -disableaction("math", "noads.handlers.makeup") -disableaction("math", "typesetters.directions.processmath") - -disableaction("mvlbuilders", "typesetters.margins.globalhandler") -disableaction("mvlbuilders", "nodes.handlers.migrate") -disableaction("mvlbuilders", "typesetters.checkers.handler") -disableaction("mvlbuilders", "builders.profiling.pagehandler") - --------------("vboxbuilders","typesetters.margins.localhandler") -disableaction("vboxbuilders","typesetters.checkers.handler") -disableaction("vboxbuilders","builders.profiling.vboxhandler") +------------("processors", "before", "nodes.properties.attach", nil, "nut", "enabled" ) + +appendaction("processors", "normalizers", "typesetters.periodkerns.handler", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "languages.replacements.handler", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "typesetters.wrappers.handler", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "typesetters.characters.handler", nil, "nut", "enabled" ) +appendaction("processors", "normalizers", "fonts.collections.process", nil, "nut", "disabled" ) +appendaction("processors", "normalizers", "fonts.checkers.missing", nil, "nut", "disabled" ) + +appendaction("processors", "characters", "scripts.autofontfeature.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "scripts.splitters.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.cleaners.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.directions.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.cases.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "typesetters.breakpoints.handler", nil, "nut", "disabled" ) +appendaction("processors", "characters", "scripts.injectors.handler", nil, "nut", "disabled" ) + +appendaction("processors", "words", "languages.words.check", nil, "nut", "disabled" ) +appendaction("processors", "words", "languages.hyphenators.handler", nil, "nut", "enabled" ) +appendaction("processors", "words", "typesetters.initials.handler", nil, "nut", "disabled" ) +appendaction("processors", "words", "typesetters.firstlines.handler", nil, "nut", "disabled" ) + +appendaction("processors", "fonts", "builders.paragraphs.solutions.splitters.split", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.characters", nil, "nut", "enabled" ) +appendaction("processors", "fonts", "nodes.injections.handler", nil, "nut", "enabled" ) +appendaction("processors", "fonts", "typesetters.fontkerns.handler", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nonut", "enabled" ) +appendaction("processors", "fonts", "builders.kernel.ligaturing", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "builders.kernel.kerning", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "builders.kernel.cleanup", nil, "nut", "enabled" ) +appendaction("processors", "fonts", "nodes.handlers.stripping", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "nodes.handlers.flatten", nil, "nut", "disabled" ) +appendaction("processors", "fonts", "fonts.goodies.colorschemes.coloring", nil, "nut", "disabled" ) + +appendaction("processors", "lists", "typesetters.rubies.check", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.characteralign.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.spacings.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.kerns.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.digits.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "typesetters.italics.handler", nil, "nut", "disabled" ) +appendaction("processors", "lists", "languages.visualizediscretionaries", nil, "nut", "disabled" ) + +appendaction("processors", "after", "typesetters.marksuspects", nil, "nut", "disabled" ) + +appendaction("shipouts", "normalizers", "typesetters.showsuspects", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "typesetters.margins.finalhandler", nil, "nut", "disabled" ) +------------("shipouts", "normalizers", "nodes.handlers.cleanuppage", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "builders.paragraphs.expansion.trace", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "typesetters.alignments.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.references.handler", nil, "nut", "production") +appendaction("shipouts", "normalizers", "nodes.destinations.handler", nil, "nut", "production") +appendaction("shipouts", "normalizers", "nodes.rules.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.shifts.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "structures.tags.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.handlers.accessibility", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "nodes.handlers.backgrounds", nil, "nut", "disabled" ) +appendaction("shipouts", "normalizers", "typesetters.rubies.attach", nil, "nut", "disabled" ) +------------("shipouts", "normalizers", "nodes.properties.delayed", nil, "nut", "production") + +appendaction("shipouts", "finishers", "nodes.visualizers.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.colors.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.transparencies.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.colorintents.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.negatives.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.effects.handler", nil, "nut", "disabled" ) +appendaction("shipouts", "finishers", "attributes.viewerlayers.handler", nil, "nut", "disabled" ) + +appendaction("shipouts", "wrapup", "nodes.handlers.export", nil, "nut", "disabled" ) -- always last +appendaction("shipouts", "wrapup", "luatex.synctex.collect", nil, "nut", "disabled" ) + +appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.unstack", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.variants", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.families", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.render", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.fixscripts", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.domains", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.autofences", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.resize", nil, "nonut", "enabled" ) +------------("math", "normalizers", "noads.handlers.respace", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.alternates", nil, "nonut", "enabled" ) +appendaction("math", "normalizers", "noads.handlers.tags", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.italics", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.kernpairs", nil, "nonut", "disabled" ) +appendaction("math", "normalizers", "noads.handlers.classes", nil, "nonut", "disabled" ) + +appendaction("math", "builders", "builders.kernel.mlist_to_hlist", nil, "nut", "enabled" ) -- mandate +appendaction("math", "builders", "typesetters.directions.processmath", nil, "nut", "disabled" ) +appendaction("math", "builders", "noads.handlers.makeup", nil, "nonut", "disabled" ) +appendaction("math", "builders", "noads.handlers.align", nil, "nonut", "enabled" ) + +appendaction("finalizers", "lists", "typesetters.paragraphs.normalize", nil, "nut", "enabled" ) -- "disabled" +appendaction("finalizers", "lists", "typesetters.margins.localhandler", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "builders.paragraphs.keeptogether", nil, "nut", "disabled" ) +appendaction("finalizers", "fonts", "builders.paragraphs.solutions.splitters.optimize", nil, "nonut", "disabled" ) +appendaction("finalizers", "lists", "builders.paragraphs.tag", nil, "nut", "disabled" ) +appendaction("finalizers", "lists", "nodes.linefillers.handler", nil, "nut", "disabled" ) + +appendaction("contributers", "normalizers", "nodes.handlers.flattenline", nil, "nut", "disabled" ) +appendaction("contributers", "normalizers", "nodes.handlers.textbackgrounds", nil, "nut", "disabled" ) + +appendaction("vboxbuilders", "normalizers", "nodes.handlers.backgroundsvbox", nil, "nut", "disabled" ) +------------("vboxbuilders", "normalizers", "typesetters.margins.localhandler", nil, "nut", "disabled" ) +appendaction("vboxbuilders", "normalizers", "builders.vspacing.vboxhandler", nil, "nut", "enabled" ) +appendaction("vboxbuilders", "normalizers", "builders.profiling.vboxhandler", nil, "nut", "disabled" ) +appendaction("vboxbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" ) + +appendaction("mvlbuilders", "normalizers", "nodes.handlers.backgroundspage", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "typesetters.margins.globalhandler", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "nodes.handlers.migrate", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "builders.vspacing.pagehandler", nil, "nut", "enabled" ) +appendaction("mvlbuilders", "normalizers", "builders.profiling.pagehandler", nil, "nut", "disabled" ) +appendaction("mvlbuilders", "normalizers", "typesetters.checkers.handler", nil, "nut", "disabled" ) + +appendaction("everypar", "normalizers", "nodes.handlers.checkparcounter", nil, "nut", "disabled" ) + +-- some protection freezecallbacks("find_.*_file", "find file using resolver") freezecallbacks("read_.*_file", "read file at once") @@ -253,8 +161,12 @@ freezegroup("finalizers", "normalizers") freezegroup("finalizers", "fonts") freezegroup("finalizers", "lists") +freezegroup("math", "normalizers") +freezegroup("math", "builders") + freezegroup("shipouts", "normalizers") freezegroup("shipouts", "finishers") +freezegroup("shipouts", "wrapup") freezegroup("mvlbuilders", "normalizers") freezegroup("vboxbuilders", "normalizers") @@ -265,15 +177,14 @@ freezegroup("vboxbuilders", "normalizers") freezegroup("math", "normalizers") freezegroup("math", "builders") --- new: disabled here +freezegroup("everypar", "normalizers") -disableaction("processors", "builders.kernel.ligaturing") -disableaction("processors", "builders.kernel.kerning") +-- new: disabled here directives.register("nodes.basepass", function(v) if v then - enableaction("processors", "builders.kernel.ligaturing") - enableaction("processors", "builders.kernel.kerning") + enableaction("processors", "builders.kernel.ligaturing") + enableaction("processors", "builders.kernel.kerning") else disableaction("processors", "builders.kernel.ligaturing") disableaction("processors", "builders.kernel.kerning") diff --git a/tex/context/base/mkiv/toks-aux.mkiv b/tex/context/base/mkiv/toks-aux.mkiv new file mode 100644 index 000000000..5b43de596 --- /dev/null +++ b/tex/context/base/mkiv/toks-aux.mkiv @@ -0,0 +1,51 @@ +%D \module +%D [ file=toks-aux, +%D version=2018.11.29, +%D title=\CONTEXT\ Token Support, +%D subtitle=Helpers, +%D author=Wolfgang Schuster, +%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 Token Support / Helpers} + +\unprotect + +\installcorenamespace {tokenlist} + +\unexpanded\def\definetokenlist[#1]% + {\ifcsname\??tokenlist#1\endcsname + \global\lastnamedcs\emptytoks + \else + \expandafter\newtoks\csname\??tokenlist#1\endcsname + \fi} + +\unexpanded\def\starttokenlist[#1]#2\stoptokenlist + {\ifcsname\??tokenlist#1\endcsname \else + \expandafter\newtoks\csname\??tokenlist#1\endcsname + \fi + \toksapp\lastnamedcs{#2}} + +\let\stoptokenlist\relax + +\def\gettokenlist[#1]% + {\ifcsname\??tokenlist#1\endcsname + \the\lastnamedcs + \fi} + +\def\settokenlist[#1]#2% + {\ifcsname\??tokenlist#1\endcsname \else + \expandafter\newtoks\csname\??tokenlist#1\endcsname + \fi + \toksapp\lastnamedcs{#2}} + +\unexpanded\def\resettokenlist[#1]% + {\ifcsname\??tokenlist#1\endcsname + \lastnamedcs\emptytoks + \fi} + +\protect diff --git a/tex/context/base/mkiv/toks-ini.lua b/tex/context/base/mkiv/toks-ini.lua index 15e5df267..43e2d80a3 100644 --- a/tex/context/base/mkiv/toks-ini.lua +++ b/tex/context/base/mkiv/toks-ini.lua @@ -18,41 +18,15 @@ local printtable = table.print local concat = table.concat local format = string.format -if setinspector then +if token.commands then - local istoken = token.is_token - local simple = { letter = "letter", other_char = "other" } + local commands = token.commands() - local function astable(t) - if t and istoken(t) then - local cmdname = t.cmdname - local simple = simple[cmdname] - if simple then - return { - category = simple, - character = utfchar(t.mode) or nil, - } - else - return { - command = t.command, - id = t.id, - tok = t.tok, - csname = t.csname, - active = t.active, - expandable = t.expandable, - protected = t.protected, - mode = t.mode, - index = t.index, - cmdname = cmdname, - } - end - end - end + tokens.commands = utilities.storage.allocate(table.swapped(commands,commands)) - tokens.istoken = istoken - tokens.astable = astable +else - setinspector("token",function(v) if istoken(v) then printtable(astable(v),tostring(v)) return true end end) + tokens.commands = { } end @@ -69,6 +43,8 @@ local scan_token = token.scan_token local scan_word = token.scan_word local scan_number = token.scan_number local scan_csname = token.scan_csname +local scan_real = token.scan_real +local scan_float = token.scan_float local get_next = token.get_next @@ -77,25 +53,26 @@ local get_macro = token.get_macro local get_meaning = token.get_meaning local get_cmdname = token.get_cmdname local set_char = token.set_char +local set_lua = token.set_lua + local create_token = token.create +local new_token = token.new +local is_defined = token.is_defined +local is_token = token.is_token -if not set_char then -- for a while - local contextsprint = context.sprint - local ctxcatcodes = catcodes.numbers.ctxcatcodes - set_char = function(n,u) contextsprint(ctxcatcodes,format("\\chardef\\%s=%s",n,u)) end -end +if not is_defined then + + is_defined = function(name) + return get_cmdname(create_token(name)) ~= "undefined_cs" + end -function tokens.defined(name) - return get_cmdname(create_token(name)) ~= "undefined_cs" end --- set_macro = function(k,v,g) --- if g == "global" then --- context.setgvalue(k,v or '') --- else --- context.setvalue(k,v or '') --- end --- end +tokens.new = new_token +tokens.create = create_token +tokens.istoken = is_token +tokens.isdefined = is_defined +tokens.defined = is_defined local bits = { escape = 0x00000001, -- 2^00 @@ -240,6 +217,8 @@ tokens.scanners = { -- these expand glue = scan_glue, skip = scan_glue, integer = scan_int, + real = scan_real, + float = scan_float, count = scan_int, string = scan_string, argument = scan_argument, @@ -268,6 +247,7 @@ tokens.getters = { -- these don't expand tokens.setters = { macro = set_macro, char = set_char, + lua = set_lua, count = tex.setcount, dimen = tex.setdimen, skip = tex.setglue, @@ -297,3 +277,48 @@ tokens.setters = { -- /* unsave_tex_scanner(texstate); */ -- return 1; -- } + +if setinspector then + + local simple = { letter = "letter", other_char = "other" } + + local function astable(t) + if t and is_token(t) then + local cmdname = t.cmdname + local simple = simple[cmdname] + if simple then + return { + category = simple, + character = utfchar(t.mode) or nil, + } + else + return { + command = t.command, + id = t.id, + tok = t.tok, + csname = t.csname, + active = t.active, + expandable = t.expandable, + protected = t.protected, + mode = t.mode, + index = t.index, + cmdname = cmdname, + } + end + end + end + + tokens.astable = astable + + setinspector("token",function(v) local t = astable(v) if t then printtable(t,tostring(v)) return true end end) + +end + +tokens.cache = table.setmetatableindex(function(t,k) + if not is_defined(k) then + set_macro(k,"","global") + end + local v = create_token(k) + t[k] = v + return v +end) diff --git a/tex/context/base/mkiv/toks-ini.mkiv b/tex/context/base/mkiv/toks-ini.mkiv index 9d3375432..af22d5393 100644 --- a/tex/context/base/mkiv/toks-ini.mkiv +++ b/tex/context/base/mkiv/toks-ini.mkiv @@ -15,11 +15,6 @@ \unprotect -\newtoks\t_get_macro % will go away - \registerctxluafile{toks-ini}{} -\registerctxluafile{toks-scn}{} -\registerctxluafile{cldf-scn}{} -\registerctxluafile{cldf-stp}{} \protect \endinput diff --git a/tex/context/base/mkiv/toks-scn.lua b/tex/context/base/mkiv/toks-scn.lua index fe32a1de4..f73ecc86c 100644 --- a/tex/context/base/mkiv/toks-scn.lua +++ b/tex/context/base/mkiv/toks-scn.lua @@ -106,7 +106,40 @@ local function scanconditional() return nil end +local function scantable(t,data) + if not data then + data = { } + end + local wrapped = scanopen() + while true do + local key = scanword() + if key then + local get = t[key] + if get then + data[key] = get() + else + -- catch all we can get + end + else + break + end + end + if wrapped then + scanclose() + end + return data +end + +function tokens.constant(s) + if type(s) == "string" then + return "'" .. s .. "'" + else + return s + end +end + scanners.list = scanlist +scanners.table = scantable scanners.conditional = scanconditional local shortcuts = { @@ -118,6 +151,7 @@ local shortcuts = { scanstring = scanstring, scaninteger = scaninteger, scannumber = scannumber, + scantable = scantable, scankeyword = scankeyword, scankeywordcs = scankeywordcs, scanword = scanword, @@ -254,6 +288,8 @@ local presets = { ["8 strings"] = { "string", "string", "string", "string", "string", "string", "string", "string" }, } +tokens.presets = presets + function tokens.compile(specification) local f = { } local n = 0 @@ -319,7 +355,7 @@ function tokens.compile(specification) return c end end - local p = t and presets[t] + local p = t and presets[t] -- already done in implement if p then t = p end @@ -460,35 +496,3 @@ end -- } -- -- os.exit() - -function tokens.scantable(t,data) - if not data then - data = { } - end - local wrapped = scanopen() - while true do - local key = scanword() - if key then - local get = t[key] - if get then - data[key] = get() - else - -- catch all we can get - end - else - break - end - end - if wrapped then - scanclose() - end - return data -end - -function tokens.constant(s) - if type(s) == "string" then - return "'" .. s .. "'" - else - return s - end -end diff --git a/tex/context/base/mkiv/toks-scn.mkiv b/tex/context/base/mkiv/toks-scn.mkiv new file mode 100644 index 000000000..49edf0c24 --- /dev/null +++ b/tex/context/base/mkiv/toks-scn.mkiv @@ -0,0 +1,22 @@ +%D \module +%D [ file=toks-ini, +%D version=2007.03.03, +%D title=\CONTEXT\ Token Support, +%D subtitle=Initialization, +%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 Token Support / Scanners} + +\unprotect + +\registerctxluafile{toks-scn}{} +\registerctxluafile{cldf-scn}{} +\registerctxluafile{cldf-stp}{} + +\protect \endinput diff --git a/tex/context/base/mkiv/trac-deb.lua b/tex/context/base/mkiv/trac-deb.lua index 03df86825..95f3052fe 100644 --- a/tex/context/base/mkiv/trac-deb.lua +++ b/tex/context/base/mkiv/trac-deb.lua @@ -220,7 +220,13 @@ function tracers.printerror(specification) else report_nl() if luaerrorline then - report("lua error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror) + if linenumber == 0 or not filename or filename == "" then + print("\nfatal lua error:\n\n",lastluaerror,"\n") + os.exit(1) + return + else + report("lua error on line %s in file %s:\n\n%s",linenumber,filename,lastluaerror) + end elseif lastmpserror then report("mp error on line %s in file %s:\n\n%s",linenumber,filename,lastmpserror) else @@ -341,22 +347,25 @@ directives.register("system.showerror", lmx.overloaderror) -- trace_calls(n) -- end) -- indirect is needed for nilling -local editor = [[scite "-open:%filename%" -goto:%linenumber%]] - -directives.register("system.editor",function(v) - editor = v -end) +-- Obsolete ... not that usefull as normally one runs from an editor and +-- when run unattended it makes no sense either. -callback.register("call_edit",function(filename,linenumber) - if editor then - editor = gsub(editor,"%%s",filename) - editor = gsub(editor,"%%d",linenumber) - editor = gsub(editor,"%%filename%%",filename) - editor = gsub(editor,"%%linenumber%%",linenumber) - logs.report("system","starting editor: %s",editor) - os.execute(editor) - end -end) +-- local editor = [[scite "-open:%filename%" -goto:%linenumber%]] +-- +-- directives.register("system.editor",function(v) +-- editor = v +-- end) +-- +-- callback.register("call_edit",function(filename,linenumber) +-- if editor then +-- editor = gsub(editor,"%%s",filename) +-- editor = gsub(editor,"%%d",linenumber) +-- editor = gsub(editor,"%%filename%%",filename) +-- editor = gsub(editor,"%%linenumber%%",linenumber) +-- logs.report("system","starting editor: %s",editor) +-- os.execute(editor) +-- end +-- end) implement { name = "showtrackers", actions = trackers.show } implement { name = "enabletrackers", actions = trackers.enable, arguments = "string" } diff --git a/tex/context/base/mkiv/trac-inf.lua b/tex/context/base/mkiv/trac-inf.lua index 439e8b2dc..7a5c35fd5 100644 --- a/tex/context/base/mkiv/trac-inf.lua +++ b/tex/context/base/mkiv/trac-inf.lua @@ -82,9 +82,13 @@ local seconds = function(n) return n or 0 end -- -- end -local function starttiming(instance) +local function starttiming(instance,reset) local timer = timers[instance or "notimer"] local it = timer.timing + if reset then + it = 0 + timer.loadtime = 0 + end if it == 0 then timer.starttime = ticks() if not timer.loadtime then @@ -123,6 +127,24 @@ local function elapsed(instance) end end +local function currenttime(instance) + if type(instance) == "number" then + return instance + else + local timer = timers[instance or "notimer"] + local it = timer.timing + if it > 1 then + -- whatever + else + local starttime = timer.starttime + if starttime and starttime > 0 then + return seconds(timer.loadtime + ticks() - starttime) + end + end + return 0 + end +end + local function elapsedtime(instance) return format("%0.3f",elapsed(instance)) end @@ -141,6 +163,7 @@ statistics.hastiming = hastiming statistics.resettiming = resettiming statistics.starttiming = starttiming statistics.stoptiming = stoptiming +statistics.currenttime = currenttime statistics.elapsed = elapsed statistics.elapsedtime = elapsedtime statistics.elapsedindeed = elapsedindeed @@ -229,17 +252,26 @@ end function statistics.runtime() stoptiming(statistics) - -- stoptiming(statistics) -- somehow we can start the timer twice, but where - return statistics.formatruntime(elapsedtime(statistics)) + -- stoptiming(statistics) -- somehow we can start the timer twice, but where + local runtime = lua.getruntime and lua.getruntime() or elapsedtime(statistics) + return statistics.formatruntime(runtime) end local report = logs.reporter("system") -function statistics.timed(action) +function statistics.timed(action,all) starttiming("run") action() stoptiming("run") - report("total runtime: %s seconds",elapsedtime("run")) + local runtime = tonumber(elapsedtime("run")) + if all then + local alltime = tonumber(lua.getruntime and lua.getruntime() or elapsedtime(statistics)) + if alltime and alltime > 0 then + report("total runtime: %0.3f seconds of %0.3f seconds",runtime,alltime) + return + end + end + report("total runtime: %0.3f seconds",runtime) end -- goodie diff --git a/tex/context/base/mkiv/trac-jus.lua b/tex/context/base/mkiv/trac-jus.lua index e7a030257..aec1844ec 100644 --- a/tex/context/base/mkiv/trac-jus.lua +++ b/tex/context/base/mkiv/trac-jus.lua @@ -15,7 +15,6 @@ local a_alignstate = attributes.private("alignstate") local a_justification = attributes.private("justification") local nuts = nodes.nuts -local tonut = nuts.tonut local getfield = nuts.getfield local getlist = nuts.getlist @@ -26,8 +25,9 @@ local setlink = nuts.setlink local getwidth = nuts.getwidth local findtail = nuts.tail -local traverse_id = nuts.traverse_id -local list_dimensions = nuts.dimensions +local nexthlist = nuts.traversers.hlist + +local getdimensions = nuts.dimensions local copy_list = nuts.copy_list local tracedrule = nodes.tracers.pool.nuts.rule @@ -77,14 +77,14 @@ trackers.register("visualizers.justification", function(v) end) function checkers.handler(head) - for current in traverse_id(hlist_code,tonut(head)) do + for current in nexthlist, head do if getattr(current,a_justification) == 1 then setattr(current,a_justification,0) -- kind of reset local width = getwidth(current) if width > 0 then local list = getlist(current) if list then - local naturalwidth, naturalheight, naturaldepth = list_dimensions(list) + local naturalwidth, naturalheight, naturaldepth = getdimensions(list) local delta = naturalwidth - width if naturalwidth == 0 or delta == 0 then -- special box diff --git a/tex/context/base/mkiv/trac-log.lua b/tex/context/base/mkiv/trac-log.lua index 1471bd4c7..206af5668 100644 --- a/tex/context/base/mkiv/trac-log.lua +++ b/tex/context/base/mkiv/trac-log.lua @@ -405,6 +405,15 @@ if runningtex then setlogfile = ignore settimedlog = ignore + -- settimedlog = function() + -- local localtime = os.localtime + -- local writeline = write_nl + -- write_nl = function(f,...) + -- writeline(f,localtime() .. " | " .. concat { ... }) + -- end + -- settimedlog = ignore + -- end + else local report_yes, subreport_yes, status_yes @@ -758,7 +767,7 @@ if tex then local report = logs.reporter("pages") -- not needed but saves checking when we grep for it local texgetcount = tex and tex.getcount - local real, user, sub + local real, user, sub = 0, 0, 0 function logs.start_page_number() real = texgetcount("realpageno") @@ -766,47 +775,35 @@ if tex then sub = texgetcount("subpageno") end - local timing = false - local starttime = nil - local lasttime = nil + local timing = false + local lasttime = nil trackers.register("pages.timing", function(v) -- only for myself (diagnostics) - starttime = os.clock() -- todo: use other timer - timing = true + timing = "" end) function logs.stop_page_number() -- the first page can includes the initialization so we omit this in average if timing then - local elapsed, average - local stoptime = os.clock() + local elapsed = statistics.currenttime(statistics) + local average, page if not lasttime or real < 2 then - elapsed = stoptime - average = stoptime - starttime = stoptime - else - elapsed = stoptime - lasttime - average = (stoptime - starttime) / (real - 1) - end - lasttime = stoptime - if real <= 0 then - report("flushing page, time %0.04f / %0.04f",elapsed,average) - elseif user <= 0 then - report("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) - elseif sub <= 0 then - report("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) + average = elapsed + page = elapsed else - report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) + average = elapsed / (real - 1) + page = elapsed - lasttime end + lasttime = elapsed + timing = formatters[", total %0.03f, page %0.03f, average %0.03f"](elapsed,page,average) + end + if real <= 0 then + report("flushing page%s",timing) + elseif user <= 0 then + report("flushing realpage %s%s",real,timing) + elseif sub <= 0 then + report("flushing realpage %s, userpage %s%s",real,user,timing) else - if real <= 0 then - report("flushing page") - elseif user <= 0 then - report("flushing realpage %s",real) - elseif sub <= 0 then - report("flushing realpage %s, userpage %s",real,user) - else - report("flushing realpage %s, userpage %s, subpage %s",real,user,sub) - end + report("flushing realpage %s, userpage %s, subpage %s%s",real,user,sub,timing) end logs.flush() end @@ -1031,7 +1028,7 @@ end if tex and tex.error then function logs.texerrormessage(...) -- for the moment we put this function here - tex.error(format(...), { }) + tex.error(format(...)) end else function logs.texerrormessage(...) diff --git a/tex/context/base/mkiv/trac-par.lua b/tex/context/base/mkiv/trac-par.lua index 56291f8c8..03f0a67d1 100644 --- a/tex/context/base/mkiv/trac-par.lua +++ b/tex/context/base/mkiv/trac-par.lua @@ -15,13 +15,13 @@ local concat = table.concat local nuts = nodes.nuts local tonut = nuts.tonut -local getfield = nuts.getfield local getid = nuts.getid local getnext = nuts.getnext local getlist = nuts.getlist -local getfont = nuts.getfont -local getchar = nuts.getchar local getwidth = nuts.getwidth +local getexpansion = nuts.getexpansion + +local isglyph = nuts.isglyph local nodecodes = nodes.nodecodes local hlist_code = nodecodes.hlist @@ -63,23 +63,23 @@ local function colorize(n) -- tricky: the built-in method creates dummy fonts and the last line normally has the -- original font and that one then has ex.auto set while n do - local id = getid(n) - if id == glyph_code then - local ne = getfield(n,"expansion_factor") + local char, id = isglyph(n) + if char then + local ne = getexpansion(n) if ne == 0 then if length > 0 then flush() end setnodecolor(n,"hz:zero") else - local f = getfont(n) - if f ~= font then + -- id == font + if id ~= font then if length > 0 then flush() end - local pf = parameters[f] + local pf = parameters[id] local ex = pf.expansion if ex and ex.auto then size = pf.size - font = f -- save lookups + font = id -- save lookups else size = false end @@ -100,7 +100,7 @@ local function colorize(n) end if trace_verbose then length = length + 1 - list[length] = utfchar(getchar(n)) + list[length] = utfchar(char) width = width + getwidth(n) -- no kerning yet end end @@ -109,7 +109,10 @@ local function colorize(n) if length > 0 then flush() end - colorize(getlist(n),flush) + local list = getlist(n) + if list then + colorize(list,flush) + end else -- nothing to show on kerns if length > 0 then flush() @@ -125,7 +128,7 @@ end builders.paragraphs.expansion = builders.paragraphs.expansion or { } function builders.paragraphs.expansion.trace(head) - colorize(tonut(head),true) + colorize(head,true) return head end diff --git a/tex/context/base/mkiv/trac-set.lua b/tex/context/base/mkiv/trac-set.lua index 530915fe0..6311d6382 100644 --- a/tex/context/base/mkiv/trac-set.lua +++ b/tex/context/base/mkiv/trac-set.lua @@ -396,3 +396,20 @@ if texconfig then directives.register("luatex.stacksize", function(v) set("stack_size",v) end) end + +-- for now here: + +local data = table.setmetatableindex("table") + +updaters = { + register = function(what,f) + local d = data[what] + d[#d+1] = f + end, + apply = function(what,...) + local d = data[what] + for i=1,#d do + d[i](...) + end + end, +} diff --git a/tex/context/base/mkiv/trac-vis.lua b/tex/context/base/mkiv/trac-vis.lua index 0e37752db..b61dadb51 100644 --- a/tex/context/base/mkiv/trac-vis.lua +++ b/tex/context/base/mkiv/trac-vis.lua @@ -28,8 +28,6 @@ local compactfloat = number.compactfloat -- todo: inline concat (more efficient) -- todo: tags can also be numbers (just add to hash) --- todo: dir and localpar nodes - local nodecodes = nodes.nodecodes local nuts = nodes.nuts @@ -47,12 +45,10 @@ local setattr = nuts.setattr local setwidth = nuts.setwidth local setshift = nuts.setshift -local getfield = nuts.getfield local getid = nuts.getid local getfont = nuts.getfont local getattr = nuts.getattr local getsubtype = nuts.getsubtype -local getchar = nuts.getchar local getbox = nuts.getbox local getlist = nuts.getlist local getleader = nuts.getleader @@ -63,22 +59,26 @@ local getdisc = nuts.getdisc local getwhd = nuts.getwhd local getkern = nuts.getkern local getpenalty = nuts.getpenalty -local getdir = nuts.getdir local getwidth = nuts.getwidth local getdepth = nuts.getdepth local getshift = nuts.getshift +local getexpansion = nuts.getexpansion + +local isglyph = nuts.isglyph local hpack_nodes = nuts.hpack local vpack_nodes = nuts.vpack local copy_list = nuts.copy_list +local copy_node = nuts.copy_node local flush_node_list = nuts.flush_list local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after -local traverse_nodes = nuts.traverse local apply_to_nodes = nuts.apply local find_tail = nuts.tail local effectiveglue = nuts.effective_glue +local nextnode = nuts.traversers.node + local hpack_string = nuts.typesetters.tohpack local texgetattribute = tex.getattribute @@ -188,13 +188,16 @@ end -- we can preset a bunch of bits -local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule") +local userrule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule") +local outlinerule -- bah, not yet defined: todo, delayed(nuts.rules,"userrule") -local function enable() +local function initialize() + -- if not usedfont then -- we use a narrow monospaced font -- infofont ? visualizers.setfont(fonts.definers.define { name = "lmmonoltcond10regular", size = tex.sp("4pt") }) end + -- for mode, value in next, modes do local tag = formatters["v_%s"](mode) attributes.viewerlayers.define { @@ -225,14 +228,25 @@ local function enable() l_line = layers.line l_space = layers.space l_depth = layers.depth - enableaction("shipouts","nodes.visualizers.handler") - report_visualize("enabled") - enabled = true - tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end -- if not userrule then userrule = nuts.rules.userrule end + -- + if not outlinerule then + outlinerule = nuts.pool.outlinerule + end + initialize = false +end + +local function enable() + if initialize then + initialize() + end + enableaction("shipouts","nodes.visualizers.handler") + report_visualize("enabled") + enabled = true + tex.setcount("global","c_syst_visualizers_state",1) -- so that we can optimize at the tex end end local function setvisual(n,a,what,list) -- this will become more efficient when we have the bit lib linked in @@ -454,7 +468,7 @@ local fontkern, italickern do local function somekern(head,current,cache,color,layer) local width = getkern(current) - local extra = getfield(current,"expansion_factor") + local extra = getexpansion(current) local kern = width + extra local info = cache[kern] if not info then @@ -495,7 +509,7 @@ local glyphexpansion do local f_cache = caches["glyphexpansion"] glyphexpansion = function(head,current) - local extra = getfield(current,"expansion_factor") + local extra = getexpansion(current) if extra ~= 0 then extra = extra / 1000 local info = f_cache[extra] @@ -529,7 +543,7 @@ local kernexpansion do local f_cache = caches["kernexpansion"] kernexpansion = function(head,current) - local extra = getfield(current,"expansion_factor") + local extra = getexpansion(current) if extra ~= 0 then extra = extra / 1000 local info = f_cache[extra] @@ -564,29 +578,17 @@ local whatsit do local w_cache = caches["whatsit"] local tags = { - open = "FIC", - write = "FIW", - close = "FIC", - special = "SPE", - latelua = "LUA", - savepos = "POS", - userdefined = "USR", - -- backend stuff - pdfliteral = "PDF", - pdfrefobj = "PDF", - pdfannot = "PDF", - pdfstartlink = "PDF", - pdfendlink = "PDF", - pdfdest = "PDF", - pdfthread = "PDF", - pdfstartthread = "PDF", - pdfendthread = "PDF", - pdfthreaddata = "PDF", - pdflinkdata = "PDF", - pdfcolorstack = "PDF", - pdfsetmatrix = "PDF", - pdfsave = "PDF", - pdfrestore = "PDF", + open = "OPN", + write = "WRI", + close = "CLS", + special = "SPE", + latelua = "LUA", + savepos = "POS", + userdefined = "USR", + literal = "LIT", + setmatrix = "MAT", + save = "SAV", + restore = "RES", } whatsit = function(head,current) @@ -700,40 +702,11 @@ local ruledbox do local wd, ht, dp = getwhd(current) if wd ~= 0 then local shift = getshift(current) - local dir = getdir(current) - -- if dir == "LTL" or dir == "RRT" then - -- wd, ht, dp = ht + dp, wd, 0 - -- end local next = getnext(current) local prev = previous - -- local prev = getprev(current) -- prev can be wrong in math mode < 0.78.3 setboth(current) local linewidth = emwidth/fraction local size = 2*linewidth - -- local baseline, baseskip - -- if dp ~= 0 and ht ~= 0 then - -- if wd > 20*linewidth then - -- local targetsize = wd - size - -- baseline = b_cache[targetsize] - -- if not baseline then - -- -- due to an optimized leader color/transparency we need to set the glue node in order - -- -- to trigger this mechanism - -- local leader = setlink(new_glue(size),new_rule(3*size,linewidth,0),new_glue(size)) - -- leader = hpack_nodes(leader) - -- baseline = new_glue(0,65536,0,2,0) - -- setleader(baseline,leader) - -- setsubtype(baseline,cleaders_code) - -- setlisttransparency(baseline,c_text) - -- baseline = hpack_nodes(baseline,targetsize) - -- b_cache[targetsize] = baseline - -- end - -- baseline = copy_list(baseline) - -- baseskip = new_kern(-wd+linewidth) - -- else - -- baseline = new_rule(wd-size,linewidth,0) - -- baseskip = new_kern(-wd+size) - -- end - -- end local this if not simple then this = b_cache[what] @@ -746,22 +719,9 @@ local ruledbox do end end -- we need to trigger the right mode (else sometimes no whatits) - -- local info = setlink( - -- this and copy_list(this) or nil, - -- new_rule(linewidth,ht,dp), - -- new_rule(wd-size,-dp+linewidth,dp), - -- new_rule(linewidth,ht,dp), - -- new_kern(-wd+linewidth), - -- new_rule(wd-size,ht,-ht+linewidth), - -- baseskip, - -- baseskip and baseline or nil - -- ) - -- - -- userrules: - -- local info = setlink( this and copy_list(this) or nil, - userrule { + (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule { width = wd, height = ht, depth = dp, @@ -772,7 +732,7 @@ local ruledbox do ) -- setlisttransparency(info,c_text) - info = new_hlist(info) + info = new_hlist(info) -- important -- setattr(info,a_layer,layer) if vertical then @@ -846,56 +806,16 @@ local ruledglyph do ruledglyph = function(head,current,previous) -- wrong for vertical glyphs local wd = getwidth(current) - -- local wd = chardata[getfont(current)][getchar(current)].width if wd ~= 0 then local wd, ht, dp = getwhd(current) - -- local dir = getdir(current) - -- if dir == "LTL" or dir = "RTT" then - -- wd, ht, dp = ht + dp, wd, 0 - -- end local next = getnext(current) local prev = previous setboth(current) local linewidth = emwidth/(2*fraction) local info -- - -- original - -- - -- local baseline - -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then - -- baseline = new_rule(wd-2*linewidth,linewidth,0) - -- end - -- local doublelinewidth = 2*linewidth - -- -- could be a pdf rule (or a user rule now) - -- info = setlink( - -- new_rule(linewidth,ht,dp), - -- new_rule(wd-doublelinewidth,-dp+linewidth,dp), - -- new_rule(linewidth,ht,dp), - -- new_kern(-wd+linewidth), - -- new_rule(wd-doublelinewidth,ht,-ht+linewidth), - -- new_kern(-wd+doublelinewidth), - -- baseline - -- ) - -- - -- experiment with subtype outline - -- - -- if (dp >= 0 and ht >= 0) or (dp <= 0 and ht <= 0) then - -- baseline = new_rule(wd,linewidth/2,0) - -- end - -- local r = new_rule(wd-linewidth,ht-linewidth/4,dp-linewidth/4) - -- setsubtype(r,nodes.rulecodes.outline) - -- setfield(r,"transform",linewidth) - -- info = setlink( - -- new_kern(linewidth/4), - -- r, - -- new_kern(-wd+linewidth/2), - -- baseline - -- ) - -- - -- userrules: - -- info = setlink( - userrule { + (dp == 0 and outlinerule and outlinerule(wd,ht,dp,linewidth)) or userrule { width = wd, height = ht, depth = dp, @@ -905,7 +825,8 @@ local ruledglyph do new_kern(-wd) ) -- - local char = chardata[getfont(current)][getchar(current)] + local c, f = isglyph(current) + local char = chardata[f][c] if char and type(char.unicode) == "table" then -- hackery test setlistcolor(info,c_ligature) setlisttransparency(info,c_ligature_d) @@ -942,19 +863,22 @@ end local ruledglue do - local gluecodes = nodes.gluecodes - local cleaders_code = gluecodes.cleaders - local userskip_code = gluecodes.userskip - local space_code = gluecodes.spaceskip - local xspace_code = gluecodes.xspaceskip - local leftskip_code = gluecodes.leftskip - local rightskip_code = gluecodes.rightskip + local gluecodes = nodes.gluecodes + local leadercodes = nodes.gluecodes + + local userskip_code = gluecodes.userskip + local spaceskip_code = gluecodes.spaceskip + local xspaceskip_code = gluecodes.xspaceskip + local leftskip_code = gluecodes.leftskip + local rightskip_code = gluecodes.rightskip + + local cleaders_code = leadercodes.cleaders local g_cache_v = caches["vglue"] local g_cache_h = caches["hglue"] local tags = { - -- userskip = "US", + -- [gluecodes.userskip] = "US", [gluecodes.lineskip] = "LS", [gluecodes.baselineskip] = "BS", [gluecodes.parskip] = "PS", @@ -973,12 +897,12 @@ local ruledglue do [gluecodes.thinmuskip] = "MS", [gluecodes.medmuskip] = "MM", [gluecodes.thickmuskip] = "ML", - [gluecodes.leaders] = "NL", - [gluecodes.cleaders] = "CL", - [gluecodes.xleaders] = "XL", - [gluecodes.gleaders] = "GL", - -- true = "VS", - -- false = "HS", + [leadercodes.leaders] = "NL", + [leadercodes.cleaders] = "CL", + [leadercodes.xleaders] = "XL", + [leadercodes.gleaders] = "GL", + -- true = "VS", + -- false = "HS", } -- we sometimes pass previous as we can have issues in math (not watertight for all) @@ -991,7 +915,7 @@ local ruledglue do if info then -- print("glue hit") else - if subtype == space_code or subtype == xspace_code then + if subtype == spaceskip_code or subtype == xspaceskip_code then info = sometext(amount,l_glue,c_space) elseif subtype == leftskip_code or subtype == rightskip_code then info = sometext(amount,l_glue,c_skip_a) @@ -1018,7 +942,7 @@ local ruledglue do -- ruledspace = function(head,current,parent) -- local subtype = getsubtype(current) - -- if subtype == space_code or subtype == xspace_code then + -- if subtype == spaceskip_code or subtype == xspaceskip_code then -- local width = effectiveglue(current,parent) -- local amount = formatters["%s:%0.3f"](tags[subtype] or "HS",width*pt_factor) -- local info = g_cache_h[amount] @@ -1041,10 +965,10 @@ local ruledglue do ruledspace = function(head,current,parent) local subtype = getsubtype(current) - if subtype == space_code or subtype == xspace_code then -- not yet all space + if subtype == spaceskip_code or subtype == xspaceskip_code then -- not yet all space local width = effectiveglue(current,parent) local info - if subtype == space_code then + if subtype == spaceskip_code then info = g_cache_s[width] if not info then info = someblob("SP",l_glue,c_space,nil,width) @@ -1179,24 +1103,26 @@ end do - local disc_code = nodecodes.disc - local kern_code = nodecodes.kern - local glyph_code = nodecodes.glyph - local glue_code = nodecodes.glue - local penalty_code = nodecodes.penalty - local whatsit_code = nodecodes.whatsit - local user_code = nodecodes.user - local math_code = nodecodes.math - local hlist_code = nodecodes.hlist - local vlist_code = nodecodes.vlist - - local kerncodes = nodes.kerncodes - local font_kern_code = kerncodes.fontkern - local italic_kern_code = kerncodes.italiccorrection - ----- user_kern_code = kerncodes.userkern - - local listcodes = nodes.listcodes - local line_code = listcodes.line + local disc_code = nodecodes.disc + local kern_code = nodecodes.kern + local glyph_code = nodecodes.glyph + local glue_code = nodecodes.glue + local penalty_code = nodecodes.penalty + local whatsit_code = nodecodes.whatsit + local user_code = nodecodes.user + local math_code = nodecodes.math + local hlist_code = nodecodes.hlist + local vlist_code = nodecodes.vlist + + local kerncodes = nodes.kerncodes + local fontkern_code = kerncodes.fontkern + local italickern_code = kerncodes.italiccorrection + ----- userkern_code = kerncodes.userkern + + local listcodes = nodes.listcodes + local linelist_code = listcodes.line + + local cache local function visualize(head,vertical,forced,parent) local trace_hbox = false @@ -1225,6 +1151,58 @@ do local prev_trace_fontkern = nil local prev_trace_italic = nil local prev_trace_expansion = nil + + -- local function setthem(t,k) + -- local v_trace_hbox = band(k, 1) ~= 0 + -- local v_trace_vbox = band(k, 2) ~= 0 + -- local v_trace_vtop = band(k, 4) ~= 0 + -- local v_trace_kern = band(k, 8) ~= 0 + -- local v_trace_glue = band(k, 16) ~= 0 + -- local v_trace_penalty = band(k, 32) ~= 0 + -- local v_trace_fontkern = band(k, 64) ~= 0 + -- local v_trace_strut = band(k, 128) ~= 0 + -- local v_trace_whatsit = band(k, 256) ~= 0 + -- local v_trace_glyph = band(k, 512) ~= 0 + -- local v_trace_simple = band(k, 1024) ~= 0 + -- local v_trace_user = band(k, 2048) ~= 0 + -- local v_trace_math = band(k, 4096) ~= 0 + -- local v_trace_italic = band(k, 8192) ~= 0 + -- local v_trace_origin = band(k, 16384) ~= 0 + -- local v_trace_discretionary = band(k, 32768) ~= 0 + -- local v_trace_expansion = band(k, 65536) ~= 0 + -- local v_trace_line = band(k,131072) ~= 0 + -- local v_trace_space = band(k,262144) ~= 0 + -- local v_trace_depth = band(k,524288) ~= 0 + -- local v = function() + -- trace_hbox = v_trace_hbox + -- trace_vbox = v_trace_vbox + -- trace_vtop = v_trace_vtop + -- trace_kern = v_trace_kern + -- trace_glue = v_trace_glue + -- trace_penalty = v_trace_penalty + -- trace_fontkern = v_trace_fontkern + -- trace_strut = v_trace_strut + -- trace_whatsit = v_trace_whatsit + -- trace_glyph = v_trace_glyph + -- trace_simple = v_trace_simple + -- trace_user = v_trace_user + -- trace_math = v_trace_math + -- trace_italic = v_trace_italic + -- trace_origin = v_trace_origin + -- trace_discretionary = v_trace_discretionary + -- trace_expansion = v_trace_expansion + -- trace_line = v_trace_line + -- trace_space = v_trace_space + -- trace_depth = v_trace_depth + -- end + -- t[k] = v + -- return v + -- end + -- + -- if not cache then + -- cache = setmetatableindex(setthem) + -- end + while current do local id = getid(current) local a = forced or getattr(current,a_visual) or unsetvalue @@ -1254,6 +1232,7 @@ do trace_space = false trace_depth = false else -- dead slow: + -- cache[a]() trace_hbox = band(a, 1) ~= 0 trace_vbox = band(a, 2) ~= 0 trace_vtop = band(a, 4) ~= 0 @@ -1303,14 +1282,14 @@ do setdisc(current,pre,post,replace) elseif id == kern_code then local subtype = getsubtype(current) - if subtype == font_kern_code then + if subtype == fontkern_code then if trace_fontkern or prev_trace_fontkern then head, current = fontkern(head,current) end if trace_expansion or prev_trace_expansion then head, current = kernexpansion(head,current) end - elseif subtype == italic_kern_code then + elseif subtype == italickern_code then if trace_italic or prev_trace_italic then head, current = italickern(head,current) elseif trace_kern then @@ -1342,7 +1321,7 @@ do if trace_depth then ruleddepth(current) end - if trace_line and getsubtype(current) == line_code then + if trace_line and getsubtype(current) == linelist_code then head, current = ruledbox(head,current,false,l_line,"L__",trace_simple,previous,trace_origin,parent) elseif trace_hbox then head, current = ruledbox(head,current,false,l_hbox,"H__",trace_simple,previous,trace_origin,parent) @@ -1390,9 +1369,9 @@ do local function handler(head) if usedfont then starttiming(visualizers) - head = visualize(tonut(head),true) + head = visualize(head,true) stoptiming(visualizers) - return tonode(head), true + return head, true else return head, false end @@ -1433,8 +1412,7 @@ do } local function markfonts(list) - for n in traverse_nodes(list) do - local id = getid(n) + for n, id in nextnode, list do if id == glyph_code then local font = getfont(n) local okay = used[font] @@ -1507,3 +1485,57 @@ do } end + +-- Here for now: + +do + + local function make(str,forecolor,rulecolor,layer) + if initialize then + initialize() + end + local rule = new_rule(emwidth/fraction,exheight,4*exheight) + setcolor(rule,rulecolor) + settransparency(rule,rulecolor) + local info + if str == "" then + info = new_hlist(rule) + else + local text = hpack_string(str,usedfont) + local list = getlist(text) + setlistcolor(list,textcolor) + setlisttransparency(list,textcolor) + setshift(text,3.5 * exheight) + info = new_hlist(setlink(rule,text)) + end + setattr(info,a_layer,layer) + return info + end + + function visualizers.register(name,textcolor,rulecolor) + if rawget(layers,name) then + -- message + return + end + local cache = caches[name] + local layer = layers[name] + if not textcolor then + textcolor = c_text_d + end + if not rulecolor then + rulecolor = c_origin_d + end + return function(str) + if not str then + str = "" + end + local info = cache[str] + if not info then + info = make(str,textcolor,rulecolor,layer) + cache[str] = info + end + return copy_node(info) + end + end + +end diff --git a/tex/context/base/mkiv/trac-vis.mkiv b/tex/context/base/mkiv/trac-vis.mkiv index a6a3fa5a2..570e6a7c7 100644 --- a/tex/context/base/mkiv/trac-vis.mkiv +++ b/tex/context/base/mkiv/trac-vis.mkiv @@ -76,7 +76,7 @@ \to \everyshipout \appendtoks - \global\let\syst_visualizers_speedup\relax + \glet\syst_visualizers_speedup\relax \to \t_syst_visualizers_optimize \def\syst_visualizers_speedup{\the\t_syst_visualizers_optimize} @@ -122,6 +122,11 @@ \unexpanded\def\showfontitalics {\clf_setvisual{italic}} +\unexpanded\def\showglyphdata + {\showglyphs + \showfontkerns + \showfontitalics} + \unexpanded\def\showfontexpansion {\clf_setvisual{expansion}} diff --git a/tex/context/base/mkiv/type-ini.mkvi b/tex/context/base/mkiv/type-ini.mkvi index 2ac3ee207..ac5f6af2f 100644 --- a/tex/context/base/mkiv/type-ini.mkvi +++ b/tex/context/base/mkiv/type-ini.mkvi @@ -45,18 +45,30 @@ \let\currenttypescripts\empty \let\currenttypefile \empty +\installmacrostack\currenttypefile + \let\typescriptone \empty % public, used in typescripts \let\typescripttwo \empty % public, used in typescripts \let\typescriptthree\empty % public, used in typescripts +\installmacrostack\typescriptone +\installmacrostack\typescripttwo +\installmacrostack\typescriptthree + \let\fontclassstyle \empty +\installmacrostack\fontclassstyle + \let\m_font_typescripts_one \empty \let\m_font_typescripts_two \empty \let\m_font_typescripts_three\empty \let\m_font_typescripts_check\empty \let\m_font_typescripts_match\empty +\installmacrostack\m_font_typescripts_one +\installmacrostack\m_font_typescripts_two +\installmacrostack\m_font_typescripts_three + \let\t_font_typescripts\relax % uses as synonym \installcorenamespace{typescriptcache} @@ -75,6 +87,9 @@ \let\typescriptmethod\plusone % 1: empty==all==true 2: empty==false \let\typescriptstate \plustwo % 1: process 2: store +\installmacrostack\typescriptmethod +\installmacrostack\typescriptstate + \unexpanded\def\starttypescriptcollection {\dosingleempty\font_typescripts_collection_start} @@ -95,19 +110,21 @@ \def\font_typescripts_use_one{\let\typescriptmethod\plusone\font_typescripts_use} \def\font_typescripts_use_two{\let\typescriptmethod\plustwo\font_typescripts_use} +\installmacrostack\stoptypescript + \unexpanded\def\font_typescripts_use[#one][#two][#three]% - {\pushmacro\m_font_typescripts_one - \pushmacro\m_font_typescripts_two - \pushmacro\m_font_typescripts_three + {\push_macro_m_font_typescripts_one + \push_macro_m_font_typescripts_two + \push_macro_m_font_typescripts_three \edef\m_font_typescripts_one {\truetypescript{#one}}% \edef\m_font_typescripts_two {\truetypescript{#two}}% \edef\m_font_typescripts_three{\truetypescript{#three}}% - \pushmacro\typescriptone - \pushmacro\typescripttwo - \pushmacro\typescriptthree - \pushmacro\typescriptmethod - \pushmacro\typescriptstate - \pushmacro\stoptypescript + \push_macro_typescriptone + \push_macro_typescripttwo + \push_macro_typescriptthree + \push_macro_typescriptmethod + \push_macro_typescriptstate + \push_macro_stoptypescript \typescriptfoundfalse \let\typescriptstate\plusone % why \iftracetypescripts @@ -119,15 +136,15 @@ \font_typescripts_use_display \fi \setfalse\c_font_typescripts_first_pass - \popmacro\stoptypescript - \popmacro\typescriptstate - \popmacro\typescriptmethod - \popmacro\typescriptthree - \popmacro\typescripttwo - \popmacro\typescriptone - \popmacro\m_font_typescripts_three - \popmacro\m_font_typescripts_two - \popmacro\m_font_typescripts_one} + \pop_macro_stoptypescript + \pop_macro_typescriptstate + \pop_macro_typescriptmethod + \pop_macro_typescriptthree + \pop_macro_typescripttwo + \pop_macro_typescriptone + \pop_macro_m_font_typescripts_three + \pop_macro_m_font_typescripts_two + \pop_macro_m_font_typescripts_one} \def\font_typescripts_use_display {\processcommacommand[\typescriptfiles]\font_typescripts_load_file @@ -170,10 +187,10 @@ % 1 then, it doesn't get stored without doing that explicitly \unexpanded\def\loadtypescriptfile[#1]% - {\pushmacro\typescriptstate + {\push_macro_typescriptstate \let\typescriptstate\plustwo % assumes 2 at the outer level \clf_loadtypescriptfile{#1}% - \popmacro\typescriptstate} + \pop_macro_typescriptstate} \unexpanded\def\loadfoundtypescriptfile#1% {\startreadingfile @@ -191,30 +208,26 @@ {\global\advance\c_font_typescripts_n_of_preloaded\plusone \expandafter\normalgdef\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname {\starttypescript#definitions\stoptypescript}% - %\normalexpanded{\global\t_font_typescripts{\the\expandafter\t_font_typescripts\noexpand\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}} - \global\t_font_typescripts\expandafter\expandafter\expandafter - {\expandafter\the\expandafter\t_font_typescripts - \csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}} + \gtoksapp\t_font_typescripts\expandafter + {\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}} \def\font_typescripts_collection_start_store#definitions\stoptypescriptcollection {\global\advance\c_font_typescripts_n_of_preloaded\plusone \expandafter\normalgdef\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname {\starttypescriptcollection#definitions\stoptypescriptcollection}% - %\normalexpanded{\global\t_font_typescripts{\the\expandafter\t_font_typescripts\noexpand\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}}} - \global\t_font_typescripts\expandafter\expandafter\expandafter - {\expandafter\the\expandafter\t_font_typescripts - \csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}} + \gtoksapp\t_font_typescripts\expandafter + {\csname\??typescriptcache\the\c_font_typescripts_n_of_preloaded\endcsname}} \def\font_typescripts_load_file#filename% {\setfalse\c_font_typescripts_quit - \pushmacro\currenttypefile + \push_macro_currenttypefile \def\currenttypefile{#filename}% \ifconditional\c_font_typescripts_preload \font_typescript_process_typescript_file_and_store \else \font_typescript_process_typescript_file \fi - \popmacro\currenttypefile + \pop_macro_currenttypefile \ifconditional\c_font_typescripts_quit \quitcommalist \setfalse\c_font_typescripts_quit @@ -294,8 +307,7 @@ \def\font_typescripts_start_gobble#definitions\stoptypescript{} \def\font_typescripts_start_document#definitions\stoptypescript - %{\appendtoks\starttypescript#definitions\stoptypescript\to\c_font_typescripts_document} - {\c_font_typescripts_document\expandafter{\the\c_font_typescripts_document\starttypescript#definitions\stoptypescript}} + {\toksapp\c_font_typescripts_document{\starttypescript#definitions\stoptypescript}} \def\font_typescripts_start_process % could be a faster \doifelsenextoptionalif needed {\let\typescriptone \m_font_typescripts_one @@ -344,10 +356,10 @@ \let\font_typescripts_start_process_again_three\font_typescripts_start_process_yes \def\font_typescripts_start_process_indeed - {\pushmacro\fontclass} + {\push_macro_fontclass} \unexpanded\def\stoptypescript - {\popmacro\fontclass} + {\pop_macro_fontclass} \def\font_typescripts_check#asked#target#followup[#value]% script use value next {\donefalse @@ -521,8 +533,8 @@ \let\@@tsdirection \empty \let\@@tsdesignsize\empty \geteparameters[\??ts][#settings]% todo raw - \pushmacro\fontclass - \pushmacro\fontclassstyle + \push_macro_fontclass + \push_macro_fontclassstyle \setcurrentfontclass{#name}% \savefontclassparameters{#style}\@@tsrscale\@@tsfeatures\@@tsfallbacks\@@tsgoodies\@@tsdesignsize\@@tsdirection \the\everybeforedefinetypeface} @@ -536,8 +548,8 @@ \def\font_typefaces_defining_stop {\the\everyafterdefinetypeface - \popmacro\fontclassstyle - \popmacro\fontclass} + \pop_macro_fontclassstyle + \pop_macro_fontclass} \def\dofastdefinetypeface#name#style#fontshape#fontsize#settings% called from the lua end (via case d) {\font_typefaces_define_indeed[#name][#style]% @@ -597,7 +609,7 @@ {\doifelsenothing{#styles} {\font_typescripts_inherit_indeed[#name][\s!rm,\s!ss,\s!tt,\s!mm][\fontclass]} {\doifnot{#name}{#parentclass} - {\global\let\font_typescripts_inherit_check\font_typescripts_inherit_check_indeed + {\glet\font_typescripts_inherit_check\font_typescripts_inherit_check_indeed \def\font_typescripts_inherit_check_step#style{\setevalue{\??typescriptinheritances#name:#style}{#parentclass}}% \processcommalist[#styles]\font_typescripts_inherit_check_step}}} diff --git a/tex/context/base/mkiv/type-set.mkiv b/tex/context/base/mkiv/type-set.mkiv index 1763de687..c6b0c8841 100644 --- a/tex/context/base/mkiv/type-set.mkiv +++ b/tex/context/base/mkiv/type-set.mkiv @@ -132,4 +132,6 @@ \definefilesynonym [type-imp-stixtwo.mkiv] [type-imp-stix.mkiv] +\definefilesynonym [type-imp-ibmplex.mkiv] [type-imp-plex.mkiv] + \protect \endinput diff --git a/tex/context/base/mkiv/typo-bld.lua b/tex/context/base/mkiv/typo-bld.lua index 753748a2e..55d74281f 100644 --- a/tex/context/base/mkiv/typo-bld.lua +++ b/tex/context/base/mkiv/typo-bld.lua @@ -54,10 +54,12 @@ storage.register("builders/paragraphs/constructors/names", names, "builders. storage.register("builders/paragraphs/constructors/numbers", numbers, "builders.paragraphs.constructors.numbers") local trace_page_builder = false trackers.register("builders.page", function(v) trace_page_builder = v end) +local trace_vbox_builder = false trackers.register("builders.vbox", function(v) trace_vbox_builder = v end) local trace_post_builder = false trackers.register("builders.post", function(v) trace_post_builder = v end) -local report_par_builder = logs.reporter("builders","par") local report_page_builder = logs.reporter("builders","page") +local report_vbox_builder = logs.reporter("builders","vbox") +local report_par_builder = logs.reporter("builders","par") local mainconstructor = nil -- not stored in format local nofconstructors = 0 @@ -137,7 +139,7 @@ end -- also for testing (now also surrounding spacing done) -function builders.paragraphs.constructors.methods.oneline(head,followed_by_display) +function parbuilders.constructors.methods.oneline(head,followed_by_display) -- when needed we will turn this into a helper local t = texnest[texnest.ptr] local h = hpack_node(head) @@ -193,15 +195,11 @@ function builders.vpack_filter(head,groupcode,size,packtype,maxdepth,direction) local done = false if head then starttiming(builders) - if trace_vpacking then + if trace_vbox_builder then local before = count_nodes(head) head, done = vboxactions(head,groupcode,size,packtype,maxdepth,direction) local after = count_nodes(head) - if done then - nodes.processors.tracer("vpack","changed",head,groupcode,before,after,true) - else - nodes.processors.tracer("vpack","unchanged",head,groupcode,before,after,true) - end + nodes.processors.tracer("vpack",head,groupcode,before,after,done) else head, done = vboxactions(head,groupcode) end @@ -254,13 +252,13 @@ function builders.buildpage_filter(groupcode) if trace_page_builder then report(groupcode) end - return nil, false -- no return value needed +-- return nil, false -- no return value needed + return nil end end -registercallback('vpack_filter', builders.vpack_filter, "vertical spacing etc") -registercallback('buildpage_filter', builders.buildpage_filter, "vertical spacing etc (mvl)") -----------------('contribute_filter', builders.contribute_filter, "adding content to lists") +registercallback('vpack_filter', builders.vpack_filter, "vertical spacing etc") +registercallback('buildpage_filter', builders.buildpage_filter, "vertical spacing etc (mvl)") statistics.register("v-node processing time", function() return statistics.elapsedseconds(builders) @@ -277,11 +275,21 @@ implement { name = "disableparbuilder", actions = constructors.disable } -- Here are some tracers: -local new_kern = nodes.pool.kern -local new_rule = nodes.pool.rule -local hpack = nodes.hpack +local nuts = nodes.nuts +local tonut = nodes.tonut local setcolor = nodes.tracers.colors.set local listtoutf = nodes.listtoutf +local new_kern = nuts.pool.kern +local new_rule = nuts.pool.rule +local hpack = nuts.hpack +local getheight = nuts.getheight +local getdepth = nuts.getdepth +local getdirection = nuts.getdirection +local getlist = nuts.getlist +local setwidth = nuts.setwidth +local setdirection = nuts.setdirection +local setlink = nuts.setlink +local tonode = nuts.tonode local report_hpack = logs.reporter("hpack routine") local report_vpack = logs.reporter("vpack routine") @@ -305,8 +313,9 @@ end) local report, show = false, false local function hpack_quality(how,detail,n,first,last) + n = tonut(n) if report then - local str = listtoutf(n.head,"",true,nil,true) + local str = listtoutf(getlist(n),"",true,nil,true) if last <= 0 then report_hpack("%s hbox: %s",how,str) elseif first > 0 and first < last then @@ -316,10 +325,10 @@ local function hpack_quality(how,detail,n,first,last) end end if show then - local width = 2*65536 - local height = n.height - local depth = n.depth - local dir = n.dir + local width = 2*65536 + local height = getheight(n) + local depth = getdepth(n) + local direction = getdirection(n) if height < 4*65526 then height = 4*65526 end @@ -327,12 +336,11 @@ local function hpack_quality(how,detail,n,first,last) depth = 2*65526 end local rule = new_rule(width,height,depth) - rule.dir = dir + setdirection(rule,direction) if how == "overfull" then setcolor(rule,"red") local kern = new_kern(-detail) - kern.next = rule - rule.prev = kern + setlink(kern,rule) rule = kern elseif how == "underfull" then setcolor(rule,"blue") @@ -342,9 +350,9 @@ local function hpack_quality(how,detail,n,first,last) setcolor(rule,"cyan") end rule = hpack(rule) - rule.width = 0 - rule.dir = dir - return rule + setwidth(rule,0) + setdirection(rule,direction) + return tonode(rule) -- can be a nut end end @@ -387,3 +395,4 @@ end) -- end, -- "experimental prevdepth checking" -- ) + diff --git a/tex/context/base/mkiv/typo-brk.lua b/tex/context/base/mkiv/typo-brk.lua index 51760bbf4..76e50ce18 100644 --- a/tex/context/base/mkiv/typo-brk.lua +++ b/tex/context/base/mkiv/typo-brk.lua @@ -23,7 +23,6 @@ local settings_to_array = utilities.parsers.settings_to_array local nuts = nodes.nuts local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev @@ -76,14 +75,14 @@ local new_wordboundary = nodepool.wordboundary local nodecodes = nodes.nodecodes local kerncodes = nodes.kerncodes -local glyph_code = nodecodes.glyph local kern_code = nodecodes.kern local math_code = nodecodes.math local fontkern_code = kerncodes.fontkern ------ userkern_code = kerncodes.userkern local italickern_code = kerncodes.italiccorrection +local is_letter = characters.is_letter + local typesetters = typesetters typesetters.breakpoints = typesetters.breakpoints or {} @@ -241,10 +240,9 @@ end function breakpoints.handler(head) local done = false - local nead = tonut(head) local attr = nil local map = nil - local current = nead + local current = head while current do local char, id = isglyph(current) if char then @@ -313,7 +311,7 @@ function breakpoints.handler(head) end end if not done then - return head, false + return head end -- we have hits local numbers = languages.numbers @@ -323,17 +321,21 @@ function breakpoints.handler(head) local stop = data[2] local cmap = data[3] local smap = data[4] --- local lang = getlang(start) -- -- we do a sanity check for language +-- local lang = getlang(start) -- local smap = lang and lang >= 0 and lang < 0x7FFF and (cmap[numbers[lang]] or cmap[""]) -- if smap then local nleft = smap.nleft local cleft = 0 local prev = getprev(start) - local kern = nil + local kern = nil while prev and nleft ~= cleft do - local id = getid(prev) - if id == glyph_code then + local char, id = isglyph(prev) + if char then + if not is_letter[char] then + cleft = -1 + break + end cleft = cleft + 1 prev = getprev(prev) elseif id == kern_code then @@ -359,6 +361,10 @@ function breakpoints.handler(head) while next and nright ~= cright do local char, id = isglyph(next) if char then + if not is_letter[char] then + cright = -1 + break + end if cright == 1 and cmap[char] then -- let's not make it too messy break @@ -383,13 +389,13 @@ function breakpoints.handler(head) if nright == cright then local method = methods[smap.type] if method then - nead, start = method(nead,start,stop,smap,kern) + head, start = method(head,start,stop,smap,kern) end end -- end end end - return tonode(nead), true + return head end local enabled = false diff --git a/tex/context/base/mkiv/typo-cap.lua b/tex/context/base/mkiv/typo-cap.lua index 4dffd1c49..7e8003c62 100644 --- a/tex/context/base/mkiv/typo-cap.lua +++ b/tex/context/base/mkiv/typo-cap.lua @@ -18,8 +18,6 @@ local report_casing = logs.reporter("typesetting","casing") local nodes, node = nodes, node local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut local getnext = nuts.getnext local getprev = nuts.getprev @@ -29,6 +27,7 @@ local takeattr = nuts.takeattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar +local isglyph = nuts.isglyph local getdisc = nuts.getdisc local setattr = nuts.setattr @@ -37,12 +36,12 @@ local setfont = nuts.setfont local copy_node = nuts.copy local end_of_math = nuts.end_of_math -local traverse_id = nuts.traverse_id local insert_after = nuts.insert_after local find_attribute = nuts.find_attribute +local nextglyph = nuts.traversers.glyph + local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes local kerncodes = nodes.kerncodes local glyph_code = nodecodes.glyph @@ -98,19 +97,6 @@ local function get(a) extract(a, 0, 8) -- run end --- local function get(a) --- return --- (a >> 8) & ~(-1 << 8), -- & 0x0FF -- tag --- (a >> 16) & ~(-1 << 12), -- & 0xFFF -- font --- (a >> 0) & ~(-1 << 8) -- & 0x0FF -- run --- end - --- print(get(set( 1, 0))) --- print(get(set( 1, 99))) --- print(get(set( 2, 96))) --- print(get(set( 30, 922))) --- print(get(set(250,4000))) - -- a previous implementation used char(0) as placeholder for the larger font, so we needed -- to remove it before it can do further harm ... that was too tricky as we use char 0 for -- other cases too @@ -128,10 +114,9 @@ local categories = characters.categories -- true false true == mixed local function replacer(start,codes) - local char = getchar(start) - local dc = codes[char] + local char, fnt = isglyph(start) + local dc = codes[char] if dc then - local fnt = getfont(start) local ifc = fontchar[fnt] if type(dc) == "table" then for i=1,#dc do @@ -149,13 +134,11 @@ local function replacer(start,codes) insert_after(start,start,g) end end - return start, true elseif ifc[dc] then setchar(start,dc) - return start, true end end - return start, false + return start end local registered, n = { }, 0 @@ -191,9 +174,9 @@ local function Words(start,attr,lastfont,n,count,where,first) -- looks quite com end if count == 1 and where ~= "post" then replacer(first or start,uccodes) - return start, true, true + return start, true else - return start, false, true + return start, true end end @@ -203,9 +186,9 @@ local function Word(start,attr,lastfont,n,count,where,first) end local function camel(start,attr,lastfont,n,count,where,first) - local _, done_1 = word(start,attr,lastfont,n,count,where,first) - local _, done_2 = Words(start,attr,lastfont,n,count,where,first) - return start, done_1 or done_2, true + word(start,attr,lastfont,n,count,where,first) + Words(start,attr,lastfont,n,count,where,first) + return start, true end -- local function mixed(start,attr,lastfont,n,count,where,first) @@ -216,19 +199,16 @@ end -- local char = getchar(first) -- local dc = uccodes[char] -- if not dc then --- return start, false, true +-- -- quit -- elseif dc == char then -- local lfa = lastfont[n] -- if lfa then -- setfont(first,lfa) --- return start, true, true --- else --- return start, false, true -- end -- else -- replacer(first or start,uccodes) --- return start, true, true -- end +-- return start, true -- end local function mixed(start,attr,lastfont,n,count,where,first) @@ -239,38 +219,33 @@ local function mixed(start,attr,lastfont,n,count,where,first) local char = getchar(used) local dc = uccodes[char] if not dc then - return start, false, true + -- quit elseif dc == char then local lfa = lastfont[n] if lfa then setfont(used,lfa) - return start, true, true - else - return start, false, true end - else - if check_kerns then - local p = getprev(used) - if p and getid(p) == glyph_code then - local c = lccodes[char] - local c = type(c) == "table" and c[1] or c - replacer(used,uccodes) - local fp = getfont(p) - local fc = getfont(used) - if fp ~= fc then - local k = fonts.getkern(fontdata[fp],getchar(p),c) - if k ~= 0 then - insert_after(p,p,newkern(k)) - end + elseif check_kerns then + local p = getprev(used) + if p and getid(p) == glyph_code then + local c = lccodes[char] + local c = type(c) == "table" and c[1] or c + replacer(used,uccodes) + local fp = getfont(p) + local fc = getfont(used) + if fp ~= fc then + local k = fonts.getkern(fontdata[fp],getchar(p),c) + if k ~= 0 then + insert_after(p,p,newkern(k)) end - else - replacer(used,uccodes) end else replacer(used,uccodes) end - return start, true, true + else + replacer(used,uccodes) end + return start, true end local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3 @@ -284,11 +259,11 @@ local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3 end end end - local s, d, c = replacer(first or start,uccodes) + local s, c = replacer(first or start,uccodes) if once then lastfont[n] = false -- here end - return start, d, c + return start, c end local function capital(start,attr,lastfont,n,where,count,first,count) -- 4 @@ -296,7 +271,7 @@ local function capital(start,attr,lastfont,n,where,count,first,count) -- 4 end local function none(start,attr,lastfont,n,count,where,first) - return start, false, true + return start, true end local function randomized(start,attr,lastfont,n,count,where,first) @@ -311,7 +286,7 @@ local function randomized(start,attr,lastfont,n,count,where,first) local n = getrandom("capital lu",0x41,0x5A) if tfm[n] then -- this also intercepts tables setchar(used,n) - return start, true + return start end end elseif kind == "ll" then @@ -319,11 +294,11 @@ local function randomized(start,attr,lastfont,n,count,where,first) local n = getrandom("capital ll",0x61,0x7A) if tfm[n] then -- this also intercepts tables setchar(used,n) - return start, true + return start end end end - return start, false + return start end register(variables.WORD, WORD) -- 1 @@ -341,10 +316,9 @@ register(variables.cap, variables.capital) -- clone register(variables.Cap, variables.Capital) -- clone function cases.handler(head) -- not real fast but also not used on much data - local start = tonut(head) + local start = head local lastfont = { } local lastattr = nil - local done = false local count = 0 local previd = nil local prev = nil @@ -367,10 +341,7 @@ function cases.handler(head) -- not real fast but also not used on much data end local action = actions[n] -- map back to low number if action then - start, ok = action(start,attr,lastfont,n,count) - if ok then - done = true - end + start = action(start,attr,lastfont,n,count) if trace_casing then report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok) end @@ -396,32 +367,38 @@ function cases.handler(head) -- not real fast but also not used on much data local pre, post, replace = getdisc(start) if replace then local cnt = count - for g in traverse_id(glyph_code,replace) do + for g in nextglyph, replace do cnt = cnt + 1 takeattr(g,a_cases) -- setattr(g,a_cases,unsetvalue) - local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g) - if quit then break end + local h, quit = action(start,attr,lastfont,n,cnt,"replace",g) + if quit then + break + end end end if pre then local cnt = count - for g in traverse_id(glyph_code,pre) do + for g in nextglyph, pre do cnt = cnt + 1 takeattr(g,a_cases) -- setattr(g,a_cases,unsetvalue) - local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g) - if quit then break end + local h, quit = action(start,attr,lastfont,n,cnt,"pre",g) + if quit then + break + end end end if post then local cnt = count - for g in traverse_id(glyph_code,post) do + for g in nextglyph, post do cnt = cnt + 1 takeattr(g,a_cases) -- setattr(g,a_cases,unsetvalue) - local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g) - if quit then break end + local h, quit = action(start,attr,lastfont,n,cnt,"post",g) + if quit then + break + end end end end @@ -441,17 +418,16 @@ function cases.handler(head) -- not real fast but also not used on much data start = getnext(start) end end - return head, done + return head end -- function cases.handler(head) -- not real fast but also not used on much data --- local attr, start = find_attribute(tonut(head),a_cases) +-- local attr, start = find_attribute(head,a_cases) -- if not start then -- return head, false -- end -- local lastfont = { } -- local lastattr = nil --- local done = false -- local count = 0 -- local previd = nil -- local prev = nil @@ -475,10 +451,7 @@ end -- end -- local action = actions[n] -- map back to low number -- if action then --- start, ok = action(start,attr,lastfont,n,count) --- if ok then --- done = true --- end +-- start = action(start,attr,lastfont,n,count) -- if trace_casing then -- report_casing("case trigger %a, instance %a, fontid %a, result %a",n,m,id,ok) -- end @@ -504,32 +477,38 @@ end -- local pre, post, replace = getdisc(start) -- if replace then -- local cnt = count --- for g in traverse_id(glyph_code,replace) do +-- for g in glyph_code, replace do -- cnt = cnt + 1 -- takeattr(g,a_cases) -- -- setattr(g,a_cases,unsetvalue) --- local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g) --- if quit then break end +-- local h, quit = action(start,attr,lastfont,n,cnt,"replace",g) +-- if quit then +-- break +-- end -- end -- end -- if pre then -- local cnt = count --- for g in traverse_id(glyph_code,pre) do +-- for g in nextglyph, pre do -- cnt = cnt + 1 -- takeattr(g,a_cases) -- -- setattr(g,a_cases,unsetvalue) --- local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g) --- if quit then break end +-- local h, quit = action(start,attr,lastfont,n,cnt,"pre",g) +-- if quit then +-- break +-- end -- end -- end -- if post then -- local cnt = count --- for g in traverse_id(glyph_code,post) do +-- for g in nextglyph, post do -- cnt = cnt + 1 -- takeattr(g,a_cases) -- -- setattr(g,a_cases,unsetvalue) --- local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g) --- if quit then break end +-- local h, quit = action(start,attr,lastfont,n,cnt,"post",g) +-- if quit then +-- break +-- end -- end -- end -- end @@ -555,26 +534,22 @@ end -- attr, start = find_attribute(start,a_cases) -- end -- end --- return head, done +-- return head -- end -- function cases.handler(head) -- let's assume head doesn't change ... no reason --- local done = false -- local lastfont = { } --- for first, last, size, attr in nuts.words(tonut(head),a_cases) do +-- for first, last, size, attr in nuts.words(head,a_cases) do -- local n, id, m = get(attr) -- if lastfont[n] == nil then -- lastfont[n] = id -- end -- local action = actions[n] -- if action then --- local _, ok = action(first,attr,lastfont,n) --- if ok then --- done = true --- end +-- action(first,attr,lastfont,n) -- end -- end --- return head, done +-- return head -- end local enabled = false diff --git a/tex/context/base/mkiv/typo-cap.mkiv b/tex/context/base/mkiv/typo-cap.mkiv index 4d1272e10..890b08186 100644 --- a/tex/context/base/mkiv/typo-cap.mkiv +++ b/tex/context/base/mkiv/typo-cap.mkiv @@ -81,20 +81,23 @@ % todo: names casings -\unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\v!WORD ]}{}} -\unexpanded\def\word {\groupedcommand{\setcharactercasing[\v!word ]}{}} -\unexpanded\def\Word {\groupedcommand{\setcharactercasing[\v!Word ]}{}} -\unexpanded\def\Words{\groupedcommand{\setcharactercasing[\v!Words]}{}} -\unexpanded\def\camel{\groupedcommand{\setcharactercasing[\v!camel]}{}} - -% This might become: -% -% \unexpanded\def\WORD {\bgroup\def\g_word{\setcharactercasing[\v!WORD ]}\afterassignment\g_word\let\nexttoken} -% \unexpanded\def\word {\bgroup\def\g_word{\setcharactercasing[\v!word ]}\afterassignment\g_word\let\nexttoken} -% \unexpanded\def\Word {\bgroup\def\g_word{\setcharactercasing[\v!Word ]}\afterassignment\g_word\let\nexttoken} -% \unexpanded\def\Words{\bgroup\def\g_word{\setcharactercasing[\v!Words]}\afterassignment\g_word\let\nexttoken} -% -% so no longer {\Word test} and { } mandate (also later \groupedcommands will go) +% \unexpanded\def\WORD {\groupedcommand{\setcharactercasing[\v!WORD ]}{}} +% \unexpanded\def\word {\groupedcommand{\setcharactercasing[\v!word ]}{}} +% \unexpanded\def\Word {\groupedcommand{\setcharactercasing[\v!Word ]}{}} +% \unexpanded\def\Words{\groupedcommand{\setcharactercasing[\v!Words]}{}} +% \unexpanded\def\camel{\groupedcommand{\setcharactercasing[\v!camel]}{}} + +\unexpanded\def\typo_capitale_WORD {\clf_setcharactercasing{\v!WORD }\fontid\font} +\unexpanded\def\typo_capitale_word {\clf_setcharactercasing{\v!word }\fontid\font} +\unexpanded\def\typo_capitale_Word {\clf_setcharactercasing{\v!Word }\fontid\font} +\unexpanded\def\typo_capitale_Words{\clf_setcharactercasing{\v!Words}\fontid\font} +\unexpanded\def\typo_capitale_camel{\clf_setcharactercasing{\v!camel}\fontid\font} + +\unexpanded\def\WORD {\triggergroupedcommandcs\typo_capitale_WORD } +\unexpanded\def\word {\triggergroupedcommandcs\typo_capitale_word } +\unexpanded\def\Word {\triggergroupedcommandcs\typo_capitale_Word } +\unexpanded\def\Words{\triggergroupedcommandcs\typo_capitale_Words} +\unexpanded\def\camel{\triggergroupedcommandcs\typo_capitale_camel} \let\WORDS\WORD \let\words\word @@ -176,16 +179,27 @@ \sc \clf_setcharactercasing{\currentcapitals}\fontid\font} -\unexpanded\def\pseudosmallcapped{\groupedcommand{\typo_capitals_set_fake\v!WORD }\donothing} % all upper -\unexpanded\def\pseudoSmallcapped{\groupedcommand{\typo_capitals_set_fake\v!capital}\donothing} % one upper + font -\unexpanded\def\pseudoSmallCapped{\groupedcommand{\typo_capitals_set_fake\v!Capital}\donothing} % some upper + font -\unexpanded\def\pseudoMixedCapped{\groupedcommand{\typo_capitals_set_fake\v!mixed }\donothing} % UpperCase +% \unexpanded\def\pseudosmallcapped{\groupedcommand{\typo_capitals_set_fake\v!WORD }\donothing} % all upper +% \unexpanded\def\pseudoSmallcapped{\groupedcommand{\typo_capitals_set_fake\v!capital}\donothing} % one upper + font +% \unexpanded\def\pseudoSmallCapped{\groupedcommand{\typo_capitals_set_fake\v!Capital}\donothing} % some upper + font +% \unexpanded\def\pseudoMixedCapped{\groupedcommand{\typo_capitals_set_fake\v!mixed }\donothing} % UpperCase +% +% \unexpanded\def\realsmallcapped {\groupedcommand{\typo_capitals_set_real\v!WORD }\donothing} % all lower +% \unexpanded\def\realSmallcapped {\groupedcommand{\typo_capitals_set_real\v!Word }\donothing} % one upper + font +% \unexpanded\def\realSmallCapped {\groupedcommand{\typo_capitals_set_real\v!Words }\donothing} % some upper +% +% \unexpanded\def\notsmallcapped {\groupedcommand{\typo_capitals_set_fake\v!word }\donothing} + +\unexpanded\def\pseudosmallcapped{\triggergroupedcommandcs\font_style_pseudosmallcapped} +\unexpanded\def\pseudoSmallcapped{\triggergroupedcommandcs\font_style_pseudoSmallcapped} +\unexpanded\def\pseudoSmallCapped{\triggergroupedcommandcs\font_style_pseudoSmallCapped} +\unexpanded\def\pseudoMixedCapped{\triggergroupedcommandcs\font_style_pseudoMixedCapped} -\unexpanded\def\realsmallcapped {\groupedcommand{\typo_capitals_set_real\v!WORD }\donothing} % all lower -\unexpanded\def\realSmallcapped {\groupedcommand{\typo_capitals_set_real\v!Word }\donothing} % one upper + font -\unexpanded\def\realSmallCapped {\groupedcommand{\typo_capitals_set_real\v!Words }\donothing} % some upper +\unexpanded\def\realsmallcapped {\triggergroupedcommandcs\font_style_realsmallcapped} +\unexpanded\def\realSmallcapped {\triggergroupedcommandcs\font_style_realSmallcapped} +\unexpanded\def\realSmallCapped {\triggergroupedcommandcs\font_style_realSmallCapped} -\unexpanded\def\notsmallcapped {\groupedcommand{\typo_capitals_set_fake\v!word }\donothing} +\unexpanded\def\notsmallcapped {\triggergroupedcommandcs\font_style_notsmallcapped} \unexpanded\def\font_style_pseudosmallcapped{\typo_capitals_set_fake\v!WORD } % all upper \unexpanded\def\font_style_pseudoSmallcapped{\typo_capitals_set_fake\v!capital} % one upper + font @@ -285,7 +299,9 @@ % % \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=] -\unexpanded\def\randomizetext{\groupedcommand{\attribute\caseattribute\pluseight}{}} +% \unexpanded\def\randomizetext{\groupedcommand{\attribute\caseattribute\pluseight}{}} + +\unexpanded\def\randomizetext{\triggergroupedcommand{\attribute\caseattribute\pluseight}} \definestartstop[randomized][\c!before=\dosetattribute{case}{8},\c!after=] diff --git a/tex/context/base/mkiv/typo-chr.lua b/tex/context/base/mkiv/typo-chr.lua index 80497a492..15d14c860 100644 --- a/tex/context/base/mkiv/typo-chr.lua +++ b/tex/context/base/mkiv/typo-chr.lua @@ -6,40 +6,40 @@ if not modules then modules = { } end modules ['typo-chr'] = { license = "see context related readme files" } --- local nodecodes = nodes.nodecodes --- local whatsitcodes = nodes.whatsitcodes --- local glyph_code = nodecodes.glyph --- local whatsit_code = nodecodes.whatsit --- local user_code = whatsitcodes.userdefined +-- This module can be optimized. + +-- local nodecodes = nodes.nodecodes +-- local whatsitcodes = nodes.whatsitcodes +-- +-- local glyph_code = nodecodes.glyph +-- local whatsit_code = nodecodes.whatsit -- --- local stringusernode = nodes.pool.userstring +-- local userwhatsit_code = whatsitcodes.userdefined -- --- local nuts = nodes.nuts --- local pool = nuts.pool +-- local stringusernode = nodes.pool.userstring -- --- local tonut = nuts.tonut --- local tonode = nuts.tonode --- local getid = nuts.getid --- local getprev = nuts.getprev --- local getsubtype = nuts.getsubtype --- local getchar = nuts.getchar --- local getfield = nuts.getfield +-- local nuts = nodes.nuts +-- local pool = nuts.pool -- --- local remove_node = nuts.remove --- local traverse_by_id = nuts.traverse_id +-- local getid = nuts.getid +-- local getprev = nuts.getprev +-- local getchar = nuts.getchar +-- local getdata = nuts.getdata +-- local getfield = nuts.getfield -- --- local signal = pool.userids.signal +-- local remove_node = nuts.remove +-- local nextwhatsit = nuts.traversers.whatsit -- --- local is_punctuation = characters.is_punctuation +-- local signal = pool.userids.signal +-- +-- local is_punctuation = characters.is_punctuation -- -- local actions = { -- removepunctuation = function(head,n) -- local prev = getprev(n) -- if prev then --- if getid(prev) == glyph_code then --- if is_punctuation[getchar(prev)] then --- head = remove_node(head,prev,true) --- end +-- if getid(prev) == glyph_code and is_punctuation[getchar(prev)] then +-- head = remove_node(head,prev,true) -- end -- end -- return head @@ -51,23 +51,18 @@ if not modules then modules = { } end modules ['typo-chr'] = { -- typesetters.signals = { } -- -- function typesetters.signals.handler(head) --- local h = tonut(head) -- local done = false --- for n in traverse_by_id(whatsit_code,h) do --- if getsubtype(n) == user_code and getfield(n,"user_id") == signal and getfield(n,"type") == 115 then --- local action = actions[getfield(n,"value")] +-- for n, subtype in nextwhatsit, head do +-- if subtype == userwhatsit_code and getfield(n,"user_id") == signal and getfield(n,"type") == 115 then +-- local action = actions[getdata(n)] -- if action then --- h = action(h,n) +-- head = action(h,n) -- end --- h = remove_node(h,n,true) +-- head = remove_node(head,n,true) -- done = true -- end -- end --- if done then --- return tonode(h), true --- else --- return head --- end +-- return head, done -- end -- -- local enabled = false @@ -88,35 +83,44 @@ if not modules then modules = { } end modules ['typo-chr'] = { local insert, remove = table.insert, table.remove -local context = context +local context = context +local ctx_doifelse = commands.doifelse + +local nodecodes = nodes.nodecodes +local boundarycodes = nodes.boundarycodes +local subtypes = nodes.subtypes + +local glyph_code = nodecodes.glyph +local localpar_code = nodecodes.localpar +local boundary_code = nodecodes.boundary -local nodecodes = nodes.nodecodes -local glyph_code = nodecodes.glyph -local localpar_code = nodecodes.localpar +local wordboundary_code = boundarycodes.word -local texnest = tex.nest -local flush_node = node.flush_node -local flush_list = node.flush_list +local texgetnest = tex.getnest -- to be used +local texsetcount = tex.setcount -local settexattribute = tex.setattribute -local punctuation = characters.is_punctuation +local flush_node = node.flush_node +local flush_list = node.flush_list -local variables = interfaces.variables -local v_all = variables.all -local v_reset = variables.reset +local settexattribute = tex.setattribute +local punctuation = characters.is_punctuation -local a_marked = attributes.numbers['marked'] -local lastmarked = 0 -local marked = { +local variables = interfaces.variables +local v_all = variables.all +local v_reset = variables.reset + +local stack = { } + +local a_marked = attributes.numbers['marked'] +local lastmarked = 0 +local marked = { [v_all] = 1, [""] = 1, [v_reset] = attributes.unsetvalue, } -local stack = { } - local function pickup() - local list = texnest[texnest.ptr] + local list = texgetnest() if list then local tail = list.tail if tail and tail.id == glyph_code and punctuation[tail.char] then @@ -171,8 +175,7 @@ local function pickup(head,tail,str) while true do local prev = first.prev if prev and prev[a_marked] == attr then - local id = prev.id - if id == localpar_code then + if prev.id == localpar_code then -- and prev.subtype == 0 break else first = prev @@ -187,7 +190,7 @@ end local actions = { remove = function(specification) - local list = texnest[texnest.ptr] + local list = texgetnest() if list then local head = list.head local tail = list.tail @@ -250,3 +253,95 @@ interfaces.implement { actions = markcontent, arguments = "string", } + +-- We just put these here. + +interfaces.implement { + name = "lastnodeidstring", + public = true, + actions = function() + local list = texgetnest() -- "top" + local okay = false + if list then + local tail = list.tail + if tail then + okay = nodecodes[tail.id] + end + end + context(okay or "") + end, +} + +-- local t_lastnodeid = token.create("c_syst_last_node_id") +-- +-- interfaces.implement { +-- name = "lastnodeid", +-- public = true, +-- actions = function() +-- ... +-- tex.setcount("c_syst_last_node_id",okay) +-- context.sprint(t_lastnodeid) +-- end, +-- } + +interfaces.implement { + name = "lastnodeid", + actions = function() + local list = texgetnest() -- "top" + local okay = -1 + if list then + local tail = list.tail + if tail then + okay = tail.id + end + end + texsetcount("c_syst_last_node_id",okay) + end, +} + +interfaces.implement { + name = "lastnodesubtypestring", + public = true, + actions = function() + local list = texgetnest() -- "top" + local okay = false + if list then + local tail = list.tail + if head then + okay = subtypes[tail.id][tail.subtype] + end + end + context(okay or "") + end, +} + +local function lastnodeequals(id,subtype) + local list = texgetnest() -- "top" + local okay = false + if list then + local tail = list.tail + if tail then + local i = tail.id + okay = i == id or i == nodecodes[id] + if subtype then + local s = tail.subtype + okay = s == subtype or s == subtypes[i][subtype] + end + end + end + ctx_doifelse(okay) +end + +interfaces.implement { + name = "lastnodeequals", + arguments = "2 strings", + actions = lastnodeequals, +} + +interfaces.implement { + name = "atwordboundary", + actions = function() + lastnodeequals(boundary_code,wordboundary_code) + end, +} + diff --git a/tex/context/base/mkiv/typo-chr.mkiv b/tex/context/base/mkiv/typo-chr.mkiv index c92c4562e..365c79e51 100644 --- a/tex/context/base/mkiv/typo-chr.mkiv +++ b/tex/context/base/mkiv/typo-chr.mkiv @@ -79,4 +79,23 @@ \def\typo_marked_remove[#1]% {\clf_pickupmarkedcontent action{remove}mark{#1}\relax} +%D A few helpers (put here for convenience): +%D +%D \starttyping +%D test test\doifelselastnode{boundary}{word}{YES}{NOP}test +%D test test\wordboundary \doifelselastnode{boundary}{word}{YES}{NOP}test +%D test test\wordboundary \doifelseatwordboundary{YES}{NOP}test +%D test test \lastnodeidstring test +%D test test\lastnodeidstring test +%D test test\number\lastnodeid test +%D \stoptyping + +\newcount\c_syst_last_node_id + +\unexpanded\def\doifelselastnode {\clf_lastnodeequals} +\unexpanded\def\doifelseatwordboundary{\clf_atwordboundary} +\unexpanded\def\lastnodeid {\clf_lastnodeid\c_syst_last_node_id} +% \lastnodeidstring % public expandable +% \lastnodesubstring % public expandable + \protect \endinput diff --git a/tex/context/base/mkiv/typo-cln.lua b/tex/context/base/mkiv/typo-cln.lua index b7187eaeb..b9b0e7d6c 100644 --- a/tex/context/base/mkiv/typo-cln.lua +++ b/tex/context/base/mkiv/typo-cln.lua @@ -31,15 +31,13 @@ local enableaction = nodes.tasks.enableaction local texsetattribute = tex.setattribute local nuts = nodes.nuts -local tonut = nuts.tonut -local getchar = nuts.getchar local getattr = nuts.getattr local setattr = nuts.setattr local setchar = nuts.setchar -local traverse_id = nuts.traverse_id +local nextglyph = nuts.traversers.glyph local unsetvalue = attributes.unsetvalue @@ -58,9 +56,8 @@ local resetter = { -- this will become an entry in char-def -- cleaning comes first. function cleaners.handler(head) - local inline, done = false, false - for n in traverse_id(glyph_code,tonut(head)) do - local char = getchar(n) + local inline = false + for n, char, font in nextglyph, head do if resetter[char] then inline = false elseif not inline then @@ -71,7 +68,6 @@ function cleaners.handler(head) -- some day, not much change that \SS ends up here else setchar(n,upper) - done = true if trace_autocase then report_autocase("") end @@ -80,7 +76,7 @@ function cleaners.handler(head) inline = true end end - return head, done + return head end -- see typo-cap for a more advanced settings handler .. not needed now diff --git a/tex/context/base/mkiv/typo-del.mkiv b/tex/context/base/mkiv/typo-del.mkiv index d12be6bcf..2ce98841e 100644 --- a/tex/context/base/mkiv/typo-del.mkiv +++ b/tex/context/base/mkiv/typo-del.mkiv @@ -71,35 +71,48 @@ \setnewconstant\boundarycharactermode\plusone +% old: skip symbol skip +% new: bound skip symbol skip bound + \unexpanded\def\midboundarycharacter#1#2% {\ifcase\boundarycharactermode \or - %\nobreak + \removeunwantedspaces + \wordboundary \hskip\hspaceamount\currentusedlanguage{#2}% \usedlanguageparameter#1% - %\nobreak \hskip\hspaceamount\currentusedlanguage{#2}% + \wordboundary + \ignorespaces \or \usedlanguageparameter#1% \fi \boundarycharactermode\plusone} +% old: symbol nobreak skip +% new: symbol nobreak skip wordboundary + \unexpanded\def\leftboundarycharacter#1#2% {\ifcase\boundarycharactermode \or \usedlanguageparameter#1% \nobreak - \hskip\hspaceamount\currentusedlanguage{#2}% + \hskip\hspaceamount\currentusedlanguage{#2}% why not a kern + \wordboundary \or \usedlanguageparameter#1% \fi \boundarycharactermode\plusone} +% old: preword skip symbol +% new: bound nobreak skip symbol + \unexpanded\def\rightboundarycharacter#1#2% {\ifcase\boundarycharactermode \or - \prewordbreak %\nobreak - \hskip\hspaceamount\currentusedlanguage{#2}% + \wordboundary + \nobreak + \hskip\hspaceamount\currentusedlanguage{#2}% why not a kern \usedlanguageparameter#1% \or \usedlanguageparameter#1% @@ -212,10 +225,15 @@ %D \typebuffer %D \getbuffer -\unexpanded\def\startsubsentence{\beginofsubsentence\prewordbreak\beginofsubsentencespacing\typo_subsentence_cleanup_start} -\unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\endofsubsentencespacing\prewordbreak\endofsubsentence} -\unexpanded\def\subsentence {\groupedcommand\startsubsentence\stopsubsentence} -\unexpanded\def\midsubsentence {\typo_subsentence_cleanup_start\prewordbreak\midsentence\prewordbreak\typo_subsentence_cleanup_stop} +%unexpanded\def\startsubsentence{\beginofsubsentence\prewordbreak\beginofsubsentencespacing\typo_subsentence_cleanup_start} +%unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\endofsubsentencespacing\prewordbreak\endofsubsentence} +%unexpanded\def\subsentence {\groupedcommandcs\startsubsentence\stopsubsentence} +%unexpanded\def\midsubsentence {\typo_subsentence_cleanup_start\prewordbreak\midsentence\prewordbreak\typo_subsentence_cleanup_stop} + +\unexpanded\def\startsubsentence{\beginofsubsentence\wordboundary\beginofsubsentencespacing\wordboundary\typo_subsentence_cleanup_start} +\unexpanded\def\stopsubsentence {\typo_subsentence_cleanup_stop\wordboundary\endofsubsentencespacing\wordboundary\endofsubsentence} +\unexpanded\def\subsentence {\groupedcommandcs\startsubsentence\stopsubsentence} +\unexpanded\def\midsubsentence {\typo_subsentence_cleanup_start\wordboundary\midsentence\wordboundary\typo_subsentence_cleanup_stop} \definehspace [quotation] [\zeropoint] \definehspace [interquotation] [.125em] @@ -277,6 +295,8 @@ \let\currentdelimitedtext\s!unknown +\installglobalmacrostack\currentdelimitedtext + \let\delimitedtextlevel\!!zerocount \def\c_typo_delimited_nesting{\csname\??delimitedtextlevel\currentparentdelimitedtext\endcsname} @@ -301,6 +321,8 @@ \let\currentdelimitedlanguage\empty +\installglobalmacrostack\currentdelimitedlanguage + \def\typo_delimited_set_language_nop {\setusedlanguage{\delimitedtextparameter\c!language}} @@ -333,8 +355,8 @@ \let\m_delimited_argument\empty} \def\typo_delimited_push#1#2% - {\globalpushmacro\currentdelimitedtext % can we combine these two - \globalpushmacro\currentdelimitedlanguage % the language used for hyphenation + {\push_macro_currentdelimitedtext % can we combine these two + \push_macro_currentdelimitedlanguage % the language used for hyphenation \edef\currentdelimitedtext{#1}% \edef\m_delimited_argument{#2}% \ifx\m_delimited_argument\empty @@ -350,8 +372,8 @@ \def\typo_delimited_pop {\global\advance\c_typo_delimited_nesting\minusone - \globalpopmacro\currentdelimitedlanguage - \globalpopmacro\currentdelimitedtext} + \pop_macro_currentdelimitedlanguage + \pop_macro_currentdelimitedtext} \installcorenamespace{delimitedtext} \installcorenamespace{delimitedtextlevel} @@ -414,6 +436,8 @@ \dostoptagged \ignorespaces} +\newconditional\c_typo_delimited_repeating + \def\typo_delimited_start_other {\edef\p_delimited_repeat{\delimitedtextparameter\c!repeat}% \ifx\p_delimited_repeat\v!yes @@ -421,6 +445,7 @@ \else \let\typo_delimited_repeat\relax \fi + \setfalse\c_typo_delimited_repeating \edef\p_delimited_location{\delimitedtextparameter\c!location}% \ifx\p_delimited_location\v!paragraph \singleexpandafter\typo_delimited_start_par @@ -493,7 +518,7 @@ \let\typo_delimited_stop_par_indeed\stopnarrower \fi % so far - \pushmacro\checkindentation + \push_macro_checkindentation \useindentingparameter\delimitedtextparameter % \begingroup @@ -515,7 +540,7 @@ {\typo_delimited_stop_content \rightdelimitedtextmark \carryoverpar\endgroup % new per 2013-01-21 ... please left floats - \popmacro\checkindentation + \pop_macro_checkindentation \typo_delimited_stop_par_indeed \delimitedtextparameter\c!after \edef\p_delimited_spaceafter{\delimitedtextparameter\c!spaceafter}% @@ -680,30 +705,37 @@ % test test test % \stoptext -\def\typo_delimited_handle_middle#1% - {\typo_delimited_stop_content - \begingroup - \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor - \setbox\scratchbox\hbox{\delimitedtextparameter#1}% - \ifdim\wd\scratchbox>\zeropoint - \ifdim\lastkern=\d_typo_delimited_signal - \unkern - \hskip\hspaceamount\currentusedlanguage{interquotation}% +% We have no real test case for this and it's broken already for a while, +% even in \MKII. Maybe we should to this in \LUA. Only Italian has the +% middlespeech parameter set. + +\def\typo_delimited_handle_middle#1% special case + {\ifconditional\c_typo_delimited_repeating + \begingroup + \usedelimitedtextstyleandcolor\c!symstyle\c!symcolor + \setbox\scratchbox\hbox{\delimitedtextparameter#1}% + \ifdim\wd\scratchbox>\zeropoint + \ifdim\lastkern=\d_typo_delimited_signal + \unkern + \hskip\hspaceamount\currentusedlanguage{interquotation}% + \else % maybe an option: + %\edef\p_delimited_margin{\delimitedtextparameter\c!location}% + %\ifx\p_delimited_margin\v!margin + % \hskip-\wd\scratchbox + %\fi + \fi + \strut % new, needed below + \dostarttagged\t!delimitedsymbol\empty + \dotagsetdelimitedsymbol\s!middle + \delimitedtextparameter#1% unhbox\scratchbox + \dostoptagged + % \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods + \kern\d_typo_delimited_signal % +- \prewordbreak \fi - \ifhmode % else funny pagebeaks - \penalty\plustenthousand - \hskip\zeropoint % == \prewordbreak - \fi - \strut % new, needed below - \dostarttagged\t!delimitedsymbol\empty - \dotagsetdelimitedsymbol\s!middle - \delimitedtextparameter#1% unhbox\scratchbox - \dostoptagged - % \penalty\plustenthousand % else overfull boxes, but that's better than dangling periods - \kern\d_typo_delimited_signal % +- \prewordbreak - \fi - \endgroup - \typo_delimited_start_content} + \endgroup + \else + \settrue\c_typo_delimited_repeating + \fi} \def\typo_delimited_handle_left#1% {\begingroup @@ -717,11 +749,11 @@ \unskip \hskip\hspaceamount\currentusedlanguage{interquotation}% \fi\fi - \strut % new, needed below - \ifhmode % else funny pagebeaks - \penalty\plustenthousand - \hskip\zeropoint % == \prewordbreak - \fi + % \strut % new, needed below + % \ifhmode % else funny pagebeaks + % \penalty\plustenthousand + % \hskip\zeropoint % == \prewordbreak + % \fi \strut % new, needed below \dostarttagged\t!delimitedsymbol\empty \dotagsetdelimitedsymbol\s!left diff --git a/tex/context/base/mkiv/typo-dha.lua b/tex/context/base/mkiv/typo-dha.lua index af01f0f0d..c0bbdc396 100644 --- a/tex/context/base/mkiv/typo-dha.lua +++ b/tex/context/base/mkiv/typo-dha.lua @@ -41,13 +41,11 @@ if not modules then modules = { } end modules ['typo-dha'] = { local nodes, node = nodes, node -local trace_directions = false trackers.register("typesetters.directions.default", function(v) trace_directions = v end) +local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end) local report_directions = logs.reporter("typesetting","text directions") local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev @@ -57,7 +55,7 @@ local getsubtype = nuts.getsubtype local getlist = nuts.getlist local getattr = nuts.getattr local getprop = nuts.getprop -local getdir = nuts.getdir +local getdirection = nuts.getdirection local isglyph = nuts.isglyph -- or ischar local setprop = nuts.setprop @@ -71,7 +69,7 @@ local end_of_math = nuts.end_of_math local nodepool = nuts.pool local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local glyph_code = nodecodes.glyph local math_code = nodecodes.math @@ -80,9 +78,13 @@ local glue_code = nodecodes.glue local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local parfillskip_code = skipcodes.parfillskip +local dirvalues = nodes.dirvalues +local lefttoright_code = dirvalues.lefttoright +local righttoleft_code = dirvalues.righttoleft -local new_textdir = nodepool.textdir +local parfillskip_code = gluecodes.parfillskip + +local new_direction = nodepool.direction local insert = table.insert @@ -104,14 +106,14 @@ local strip = false local s_isol = fonts.analyzers.states.isol -local function stopdir(finish) - local n = new_textdir(finish == "TRT" and "-TRT" or "-TLT") +local function stopdir(finish) -- we could use finish directly + local n = new_direction(finish == righttoleft_code and righttoleft_code or lefttoright_code,true) setprop(n,"direction",true) return n end -local function startdir(finish) - local n = new_textdir(finish == "TRT" and "+TRT" or "+TLT") +local function startdir(finish) -- we could use finish directly + local n = new_direction(finish == righttoleft_code and righttoleft_code or lefttoright_code) setprop(n,"direction",true) return n end @@ -136,7 +138,7 @@ end local function process(start) - local head = tonut(start) -- we have a global head + local head = start local current = head local autodir = 0 local embedded = 0 @@ -309,27 +311,31 @@ local function process(start) elseif id == kern_code then setprop(current,"direction",'k') elseif id == dir_code then - local dir = getdir(current) - if dir == "+TRT" then - autodir = -1 - elseif dir == "+TLT" then - autodir = 1 - elseif dir == "-TRT" or dir == "-TLT" then - if embedded and embedded~= 0 then + local direction, pop = getdirection(current) + if direction == righttoleft_code then + if not pop then + autodir = -1 + elseif embedded and embedded~= 0 then + autodir = embedded + else + autodir = 0 + end + elseif direction == lefttoright_code then + if not pop then + autodir = 1 + elseif embedded and embedded~= 0 then autodir = embedded else autodir = 0 end - else - -- message end textdir = autodir setprop(current,"direction",true) - elseif id == localpar_code then - local dir = getdir(current) - if dir == 'TRT' then + elseif id == localpar_code and getsubtype(current) == 0 then + local direction = getdirection(current) + if direction == righttoleft_code then autodir = -1 - elseif dir == 'TLT' then + elseif direction == lefttoright_code then autodir = 1 end pardir = autodir @@ -443,7 +449,7 @@ local function process(start) end end - return tonode(head), done + return head end diff --git a/tex/context/base/mkiv/typo-dig.lua b/tex/context/base/mkiv/typo-dig.lua index 61e96c6b6..175fc0cc7 100644 --- a/tex/context/base/mkiv/typo-dig.lua +++ b/tex/context/base/mkiv/typo-dig.lua @@ -20,15 +20,12 @@ local report_digits = logs.reporter("typesetting","digits") local nodes, node = nodes, node local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev -local getfont = nuts.getfont -local getchar = nuts.getchar local getid = nuts.getid local getwidth = nuts.getwidth +local isglyph = nuts.isglyph local takeattr = nuts.takeattr local setlink = nuts.setlink @@ -99,8 +96,7 @@ function nodes.aligned(head,start,stop,width,how) end actions[1] = function(head,start,attr) - local font = getfont(start) - local char = getchar(start) + local char, font = isglyph(start) local unic = chardata[font][char].unicode or char if charbase[unic].category == "nd" then -- ignore unic tables local oldwidth = getwidth(start) @@ -111,23 +107,21 @@ actions[1] = function(head,start,attr) attr%100,div(attr,100),char,unic,newwidth-oldwidth) end head, start = nodes.aligned(head,start,start,newwidth,"middle") - return head, start, true + return head, start end end - return head, start, false + return head, start end function digits.handler(head) - head = tonut(head) - local done, current, ok = false, head, false + local current = head while current do if getid(current) == glyph_code then local attr = takeattr(current,a_digits) if attr and attr > 0 then local action = actions[attr%100] -- map back to low number if action then - head, current, ok = action(head,current,attr) - done = done and ok + head, current = action(head,current,attr) elseif trace_digits then report_digits("unknown digit trigger %a",attr) end @@ -137,7 +131,7 @@ function digits.handler(head) current = getnext(current) end end - return tonode(head), done + return head end local m, enabled = 0, false -- a trick to make neighbouring ranges work diff --git a/tex/context/base/mkiv/typo-dir.lua b/tex/context/base/mkiv/typo-dir.lua index 7fbf5f6d3..88c84bd02 100644 --- a/tex/context/base/mkiv/typo-dir.lua +++ b/tex/context/base/mkiv/typo-dir.lua @@ -45,8 +45,9 @@ local band = bit32.band local texsetattribute = tex.setattribute local unsetvalue = attributes.unsetvalue -local getnext = nodes.getnext -local getattr = nodes.getattr +local nuts = nodes.nuts +local getnext = nuts.getnext +local getattr = nuts.getattr local enableaction = nodes.tasks.enableaction local tracers = nodes.tracers @@ -165,24 +166,24 @@ local stoptiming = statistics.stoptiming -- -- \enabledirectives[typesetters.directions.onetoo] -function directions.handler(head,_,_,_,direction) +function directions.handler(head,where,_,_,direction) local only_one = not getnext(head) if only_one and not one_too then - return head, false + return head end local attr = getattr(head,a_directions) if not attr or attr == 0 then - return head, false + return head end local method = getmethod(attr) local handler = handlers[method] if not handler then - return head, false + return head end starttiming(directions) - local head, done = handler(head,direction,only_one) + head = handler(head,direction,only_one,where) stoptiming(directions) - return head, done + return head end statistics.register("text directions", function() diff --git a/tex/context/base/mkiv/typo-dir.mkiv b/tex/context/base/mkiv/typo-dir.mkiv index d92c93793..7449a7053 100644 --- a/tex/context/base/mkiv/typo-dir.mkiv +++ b/tex/context/base/mkiv/typo-dir.mkiv @@ -18,17 +18,13 @@ \unprotect -\registerctxluafile{typo-dir}{} +\registerctxluafile{typo-dir}{optimize} \registerctxluafile{typo-dha}{} -\registerctxluafile{typo-dua}{} -\registerctxluafile{typo-dub}{} -\doifelsefileexists{typo-duc-new.lua} { - \registerctxluafile{typo-duc-new}{} -} { - \registerctxluafile{typo-duc}{} -} +%registerctxluafile{typo-dua}{} +%registerctxluafile{typo-dub}{} +\registerctxluafile{typo-duc}{} -\definesystemattribute[directions][public] +\definesystemattribute[directions][public,pickup] \installcorenamespace{directions} \installcorenamespace{directionsbidimode} @@ -69,8 +65,9 @@ \expandafter\glet\csname\??directionsbidimode\currentbidistamp\endcsname\currentbidimode} \appendtoks + \edef\p_bidi{\directionsparameter\c!bidi}% \edef\currentbidistamp - {\directionsparameter\c!bidi + {\p_bidi :\directionsparameter\c!method :\directionsparameter\c!fences}% \expandafter\let\expandafter\currentbidimode\csname\??directionsbidimode\currentbidistamp\endcsname @@ -83,6 +80,11 @@ \else \setdirection[\number\directionsbidimode]% \fi + \ifx\p_bidi\v!global + \pickupdirectionsattribute + \else + \forgetdirectionsattribute + \fi \to \everysetupdirections \appendtoks @@ -104,8 +106,8 @@ \unexpanded\edef\bidilro{\normalUchar"202D} \unexpanded\edef\bidirlo{\normalUchar"202E} -\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdir TLT\fi} -\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdir TRT\fi} +\unexpanded\def\dirlre{\ifcase\directionsbidimode\or\bidilre\or\textdirection\directionlefttoright\fi} +\unexpanded\def\dirrle{\ifcase\directionsbidimode\or\bidirle\or\textdirection\directionrighttoleft\fi} \unexpanded\def\dirlro{\ifcase\directionsbidimode\or\bidilro\or\setdirection[3]\fi} \unexpanded\def\dirrlo{\ifcase\directionsbidimode\or\bidirlo\or\setdirection[4]\fi} @@ -121,85 +123,85 @@ % bidi test -\definefontfeature - [arab] - [mode=node,language=dflt,script=arab, - init=yes,medi=yes,fina=yes,isol=yes, - liga=yes,dlig=yes,rlig=yes,clig=yes, - mark=yes,mkmk=yes,kern=yes,curs=yes] - -\font\Arabic=arabtype*arab at 20pt - -\def\LATIN{LATIN} {\setdirection[1]} % enable this -\def\ARAB {محمد} - -\startluacode - function documentdata.split_tokens(str) - for s in str:bytes() do - context.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s)) - end - end -\stopluacode - -\unexpanded\def\biditest#1#2#3% font text raw - {\dontleavehmode\hbox - {\framed[offset=overlay]{\tttf#2}\quad - \enabletrackers[typesetters.directions]% - \framed[offset=overlay]{#1#3}\quad - \disabletrackers[typesetters.directions]% - \tttf\ctxlua{documentdata.split_tokens([[\detokenize{#3}]])}}} - -\startbuffer[bidi-sample] -\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{LATIN ARAB}{\textdir TLT{\bidilro \LATIN\ \ARAB}}\par % right -> left -\biditest\Arabic{LATIN ARAB}{\textdir TRT{\bidilro \LATIN\ \ARAB}}\par % right -> left -\biditest\Arabic{BARA NITAL}{\textdir TLT{\bidirlo \LATIN\ \ARAB}}\par % left -> right -\biditest\Arabic{BARA NITAL}{\textdir TRT{\bidirlo \LATIN\ \ARAB}}\par % left -> right -\stopbuffer - -\startbuffer[bidi-sample] -\biditest\Arabic{LATIN BARA}{\textdir TLT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{BARA LATIN}{\textdir TRT\relax \LATIN\ \ARAB}\par -\biditest\Arabic{LATIN ARAB}{\textdir TLT\bidilro \LATIN\ \ARAB}\par % right -> left -\biditest\Arabic{LATIN ARAB}{\textdir TRT\bidilro \LATIN\ \ARAB}\par % right -> left -\biditest\Arabic{BARA NITAL}{\textdir TLT\bidirlo \LATIN\ \ARAB}\par % left -> right -\biditest\Arabic{BARA NITAL}{\textdir TRT\bidirlo \LATIN\ \ARAB}\par % left -> right -\stopbuffer - -\startbuffer[bidi-setup] -\setupdirections[bidi=off] -\stopbuffer - -{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} - -\startbuffer[bidi-setup] -\setupdirections[bidi=global] -\stopbuffer - -{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} - -\startbuffer[bidi-setup] -\setupdirections[bidi=local] -\stopbuffer - -{\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} - -\startbuffer[bidi-sample] -\setupdirections[bidi=global] - - \hbox{\righttoleft\arabicfont (0001)}\par - \dontleavehmode\hbox{\righttoleft\arabicfont (0002)}\par - {\righttoleft\arabicfont (0003)\par} - {\righttoleft\arabicfont (0004)}\par - \dontleavehmode{\righttoleft\arabicfont (0005)\par} - \dontleavehmode{\righttoleft\arabicfont (0006)}\par - \rtlhbox{\arabicfont (0007)}\par - \ltrhbox{\arabicfont (0008)}\par -\dontleavehmode\rtlhbox{\arabicfont (0009)}\par -\dontleavehmode\ltrhbox{\arabicfont (0010)}\par -\stopsetups - -{\typebuffer[bidi-sample] \getbuffer[bidi-sample]} - -\stoptext +% \definefontfeature +% [arab] +% [mode=node,language=dflt,script=arab, +% init=yes,medi=yes,fina=yes,isol=yes, +% liga=yes,dlig=yes,rlig=yes,clig=yes, +% mark=yes,mkmk=yes,kern=yes,curs=yes] +% +% \font\Arabic=arabtype*arab at 20pt +% +% \def\LATIN{LATIN} {\setdirection[1]} % enable this +% \def\ARAB {عربي} +% +% \startluacode +% function documentdata.split_tokens(str) +% for s in str:bytes() do +% context.sprint(tex.ctxcatcodes,string.format("\\hbox{\\char %s}",s)) +% end +% end +% \stopluacode +% +% \unexpanded\def\biditest#1#2#3% font text raw +% {\dontleavehmode\hbox +% {\framed[offset=overlay]{\tttf#2}\quad +% \enabletrackers[typesetters.directions]% +% \framed[offset=overlay]{#1#3}\quad +% \disabletrackers[typesetters.directions]% +% \tttf\ctxlua{documentdata.split_tokens([[\detokenize{#3}]])}}} +% +% \startbuffer[bidi-sample] +% \biditest\Arabic{LATIN BARA}{\lefttoright\relax \LATIN\ \ARAB}\par +% \biditest\Arabic{BARA LATIN}{\righttoleft\relax \LATIN\ \ARAB}\par +% \biditest\Arabic{LATIN ARAB}{\lefttoright{\bidilro \LATIN\ \ARAB}}\par % right -> left +% \biditest\Arabic{LATIN ARAB}{\righttoleft{\bidilro \LATIN\ \ARAB}}\par % right -> left +% \biditest\Arabic{BARA NITAL}{\lefttoright{\bidirlo \LATIN\ \ARAB}}\par % left -> right +% \biditest\Arabic{BARA NITAL}{\righttoleft{\bidirlo \LATIN\ \ARAB}}\par % left -> right +% \stopbuffer +% +% \startbuffer[bidi-sample] +% \biditest\Arabic{LATIN BARA}{\lefttoright\relax \LATIN\ \ARAB}\par +% \biditest\Arabic{BARA LATIN}{\righttoleft\relax \LATIN\ \ARAB}\par +% \biditest\Arabic{LATIN ARAB}{\lefttoright\bidilro \LATIN\ \ARAB}\par % right -> left +% \biditest\Arabic{LATIN ARAB}{\righttoleft\bidilro \LATIN\ \ARAB}\par % right -> left +% \biditest\Arabic{BARA NITAL}{\lefttoright\bidirlo \LATIN\ \ARAB}\par % left -> right +% \biditest\Arabic{BARA NITAL}{\righttoleft\bidirlo \LATIN\ \ARAB}\par % left -> right +% \stopbuffer +% +% \startbuffer[bidi-setup] +% \setupdirections[bidi=off] +% \stopbuffer +% +% {\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} +% +% \startbuffer[bidi-setup] +% \setupdirections[bidi=global] +% \stopbuffer +% +% {\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} +% +% \startbuffer[bidi-setup] +% \setupdirections[bidi=local] +% \stopbuffer +% +% {\typebuffer[bidi-setup] \getbuffer[bidi-setup] \getbuffer[bidi-sample]} +% +% \startbuffer[bidi-sample] +% \setupdirections[bidi=global] +% +% \hbox{\righttoleft\arabicfont (0001)}\par +% \dontleavehmode\hbox{\righttoleft\arabicfont (0002)}\par +% {\righttoleft\arabicfont (0003)\par} +% {\righttoleft\arabicfont (0004)}\par +% \dontleavehmode{\righttoleft\arabicfont (0005)\par} +% \dontleavehmode{\righttoleft\arabicfont (0006)}\par +% \rtlhbox{\arabicfont (0007)}\par +% \ltrhbox{\arabicfont (0008)}\par +% \dontleavehmode\rtlhbox{\arabicfont (0009)}\par +% \dontleavehmode\ltrhbox{\arabicfont (0010)}\par +% \stopsetups +% +% {\typebuffer[bidi-sample] \getbuffer[bidi-sample]} +% +% \stoptext diff --git a/tex/context/base/mkiv/typo-drp.lua b/tex/context/base/mkiv/typo-drp.lua index 1e142280f..9a59891e1 100644 --- a/tex/context/base/mkiv/typo-drp.lua +++ b/tex/context/base/mkiv/typo-drp.lua @@ -28,14 +28,11 @@ local enableaction = tasks.enableaction local disableaction = tasks.disableaction local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev local getchar = nuts.getchar local getid = nuts.getid -local getsubtype = nuts.getsubtype local getattr = nuts.getattr local getwhd = nuts.getwhd @@ -59,8 +56,9 @@ local new_kern = nodepool.kern local insert_before = nuts.insert_before local insert_after = nuts.insert_after local remove_node = nuts.remove -local traverse_id = nuts.traverse_id -local traverse = nuts.traverse + +local nextnode = nuts.traversers.node +local nextglyph = nuts.traversers.glyph local variables = interfaces.variables local v_default = variables.default @@ -139,9 +137,8 @@ interfaces.implement { -- a page so this has a low priority actions[v_default] = function(head,setting) - local done = false local id = getid(head) - if id == localpar_code then + if id == localpar_code then -- and getsubtype(head) == 0 -- begin of par local first = getnext(head) local indent = false @@ -173,7 +170,7 @@ actions[v_default] = function(head,setting) -- 1 char | n chars | skip first quote | ignore punct | keep punct -- if getattr(first,a_initial) then - for current in traverse(getnext(first)) do + for current in nextnode, getnext(first) do if getattr(current,a_initial) then last = current else @@ -189,10 +186,10 @@ actions[v_default] = function(head,setting) local next = getnext(first) if not next then -- don't start with a quote or so - return head, false + return head end last = nil - for current in traverse_id(glyph_code,next) do + for current in nextglyph, next do head, first = remove_node(head,first,true) first = current last = first @@ -200,21 +197,21 @@ actions[v_default] = function(head,setting) end if not last then -- no following glyph or so - return head, false + return head end else -- keep quote etc with initial local next = getnext(first) if not next then -- don't start with a quote or so - return head, false + return head end - for current in traverse_id(glyph_code,next) do + for current in nextglyph, next do last = current break end if last == first then - return head, false + return head end end elseif kind == "pf" then @@ -225,8 +222,7 @@ actions[v_default] = function(head,setting) -- maybe also: get all A. B. etc local next = getnext(first) if next then - for current in traverse_id(glyph_code,next) do - local char = getchar(current) + for current, char in nextglyph, next do local kind = category(char) if kind == "po" then if method[v_last] then @@ -241,7 +237,7 @@ actions[v_default] = function(head,setting) end end else - for current in traverse_id(glyph_code,first) do + for current in nextglyph, first do last = current if length <= 1 then break @@ -265,12 +261,12 @@ actions[v_default] = function(head,setting) end -- apply font --- local g = nodes.copy(tonode(current)) +-- local g = nuts.copy(current) -- g.subtype = 0 -- nodes.handlers.characters(g) -- nodes.handlers.protectglyphs(g) -- setchar(current,g.char) --- nodes.flush_node(g) +-- nuts.flush_node(g) -- can be a helper if ca and ca > 0 then @@ -319,7 +315,7 @@ actions[v_default] = function(head,setting) end -- local hoffset = width + hoffset + distance + (indent and parindent or 0) - for current in traverse_id(glyph_code,first) do + for current in nextglyph, first do setoffsets(current,-hoffset,-voffset) -- no longer - height here if current == last then break @@ -347,14 +343,12 @@ actions[v_default] = function(head,setting) if indent then insert_after(first,first,new_kern(-parindent)) end - done = true end end - return head, done + return head end function initials.handler(head) - head = tonut(head) local start = head local attr = nil while start do @@ -377,9 +371,8 @@ function initials.handler(head) if trace_initials then report_initials("processing initials, alternative %a",alternative) end - local head, done = action(head,settings) - return tonode(head), done + return action(head,settings) end end - return tonode(head), false + return head end diff --git a/tex/context/base/mkiv/typo-drp.mkiv b/tex/context/base/mkiv/typo-drp.mkiv index 371ea38d6..183925108 100644 --- a/tex/context/base/mkiv/typo-drp.mkiv +++ b/tex/context/base/mkiv/typo-drp.mkiv @@ -118,7 +118,7 @@ \kern\zeropoint % we need a node \p_text \endgroup - \globallet\typo_initial_handle\relax} + \glet\typo_initial_handle\relax} \let\typo_initial_handle\relax diff --git a/tex/context/base/mkiv/typo-dua.lua b/tex/context/base/mkiv/typo-dua.lua index 1e48dfb91..3db5f510a 100644 --- a/tex/context/base/mkiv/typo-dua.lua +++ b/tex/context/base/mkiv/typo-dua.lua @@ -68,8 +68,6 @@ local directiondata = characters.directions local mirrordata = characters.mirrors local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getid = nuts.getid @@ -77,11 +75,11 @@ local getsubtype = nuts.getsubtype local getlist = nuts.getlist local getchar = nuts.getchar local getprop = nuts.getprop -local getdir = nuts.getdir +local getdirection = nuts.getdirection local setprop = nuts.setprop local setchar = nuts.setchar -local setdir = nuts.setdir +local setdirection = nuts.setdirection ----- setattrlist = nuts.setattrlist local remove_node = nuts.remove @@ -89,10 +87,10 @@ local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local nodepool = nuts.pool -local new_textdir = nodepool.textdir +local new_direction = nodepool.direction local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local glyph_code = nodecodes.glyph local glue_code = nodecodes.glue @@ -101,23 +99,28 @@ local vlist_code = nodecodes.vlist local math_code = nodecodes.math local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local parfillskip_code = skipcodes.parfillskip ------ object_replacement = 0xFFFC -- object replacement character -local maximum_stack = 60 -- probably spec but not needed +local parfillskip_code = gluecodes.parfillskip + +local dirvalues = nodes.dirvalues +local lefttoright_code = dirvalues.lefttoright +local righttoleft_code = dirvalues.righttoleft + +local maximum_stack = 60 local directions = typesetters.directions local setcolor = directions.setcolor ------ a_directions = attributes.private('directions') - local remove_controls = true directives.register("typesetters.directions.one.removecontrols",function(v) remove_controls = v end) -local trace_directions = false trackers .register("typesetters.directions.one", function(v) trace_directions = v end) -local trace_details = false trackers .register("typesetters.directions.one.details", function(v) trace_details = v end) - local report_directions = logs.reporter("typesetting","directions one") +local trace_directions = false trackers .register("typesetters.directions", function(v) trace_directions = v end) +local trace_details = false trackers .register("typesetters.directions.details", function(v) trace_details = v end) + + + + local whitespace = { lre = true, rle = true, @@ -234,13 +237,19 @@ local function build_list(head) -- todo: store node pointer ... saves loop list[size] = { char = 0x0020, direction = "ws", original = "ws", level = 0 } current = getnext(current) elseif id == dir_code then - local dir = getdir(current) - if dir == "+TLT" then - list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 } - elseif dir == "+TRT" then - list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 } - elseif dir == "-TLT" or dir == "-TRT" then - list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } + local direction, pop = getdirection(current) + if direction == lefttoright_code then + if pop then + list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } + else + list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 } + end + elseif direction == righttoleft_code then + if pop then + list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } + else + list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 } + end else list[size] = { char = 0xFFFC, direction = "on", original = "on", level = 0, id = id } -- object replacement character end @@ -323,27 +332,33 @@ local function find_run_limit_b_s_ws_on(list,start,limit) return start end -local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar) - local id = getid(head) - if id == localpar_code then - if getdir(head) == "TRT" then - return 1, "TRT", true - else - return 0, "TLT", true +local function get_baselevel(head,list,size,direction) + -- This is an adapted version: + if direction == lefttoright_code or direction == righttoleft_code then + return direction, true + elseif getid(head) == localpar_code and getsubtype(head) == 0 then + direction = getdirection(head) + if direction == lefttoright_code or direction == righttoleft_code then + return direction, true end - else - -- P2, P3 - for i=1,size do - local entry = list[i] - local direction = entry.direction - if direction == "r" or direction == "al" then - return 1, "TRT", true - elseif direction == "l" then - return 0, "TLT", true - end + end + -- for old times sake we we handle strings too + if direction == "TLT" then + return lefttoright_code, true + elseif direction == "TRT" then + return righttoleft_code, true + end + -- P2, P3 + for i=1,size do + local entry = list[i] + local direction = entry.direction + if direction == "r" or direction == "al" then + return righttoleft_code, true + elseif direction == "l" then + return lefttoright_code, true end - return 0, "TLT", false end + return lefttoright_code, false end local function resolve_explicit(list,size,baselevel) @@ -409,7 +424,7 @@ local function resolve_explicit(list,size,baselevel) end -- X7 elseif direction == "pdf" then - if nofstack < maximum_stack then + if noifstack > 0 then local stacktop = stack[nofstack] nofstack = nofstack - 1 level = stacktop[1] @@ -418,7 +433,7 @@ local function resolve_explicit(list,size,baselevel) entry.direction = "bn" entry.remove = true elseif trace_directions then - report_directions("stack overflow at position %a with direction %a",i,direction) + report_directions("stack underflow at position %a with direction %a",i,direction) end -- X6 else @@ -679,8 +694,6 @@ local function resolve_levels(list,size,baselevel) end end --- This is not ok but we keep it as-is: - local function insert_dir_points(list,size) -- L2, but no actual reversion is done, we simply annotate where -- begindir/endddir node will be inserted. @@ -697,11 +710,11 @@ local function insert_dir_points(list,size) local begindir = nil local enddir = nil if level % 2 == 1 then - begindir = "+TRT" - enddir = "-TRT" + begindir = righttoleft_code + enddir = righttoleft_code else - begindir = "+TLT" - enddir = "-TLT" + begindir = lefttoright_code + enddir = lefttoright_code end for i=1,size do local entry = list[i] @@ -730,7 +743,6 @@ end local function apply_to_list(list,size,head,pardir) local index = 1 local current = head - local done = false while current do if index > size then report_directions("fatal error, size mismatch") @@ -751,34 +763,31 @@ local function apply_to_list(list,size,head,pardir) setcolor(current,direction,false,mirror) end elseif id == hlist_code or id == vlist_code then - setdir(current,pardir) -- is this really needed? + setdirection(current,pardir) -- is this really needed? elseif id == glue_code then if enddir and getsubtype(current) == parfillskip_code then -- insert the last enddir before \parfillskip glue - local d = new_textdir(enddir) - setprop(d,"directions",true) + local d = new_direction(enddir,true) + -- setprop(d,"directions",true) -- setattrlist(d,current) head = insert_node_before(head,current,d) enddir = false - done = true end elseif begindir then - if id == localpar_code then + if id == localpar_code and getsubtype(current) == 0 then -- localpar should always be the 1st node - local d = new_textdir(begindir) - setprop(d,"directions",true) + local d = new_direction(begindir) + -- setprop(d,"directions",true) -- setattrlist(d,current) head, current = insert_node_after(head,current,d) begindir = nil - done = true end end if begindir then - local d = new_textdir(begindir) - setprop(d,"directions",true) + local d = new_direction(begindir) + -- setprop(d,"directions",true) -- setattrlist(d,current) head = insert_node_before(head,current,d) - done = true end local skip = entry.skip if skip and skip > 0 then @@ -788,30 +797,28 @@ local function apply_to_list(list,size,head,pardir) end end if enddir then - local d = new_textdir(enddir) - setprop(d,"directions",true) + local d = new_direction(enddir,true) + -- setprop(d,"directions",true) -- setattrlist(d,current) head, current = insert_node_after(head,current,d) - done = true end if not entry.remove then current = getnext(current) elseif remove_controls then -- X9 head, current = remove_node(head,current,true) - done = true else current = getnext(current) end index = index + 1 end - return head, done + return head end -local function process(head) - head = tonut(head) +local function process(head,direction,only_one,where) + -- This is an adapted version: local list, size = build_list(head) - local baselevel, pardir, dirfound = get_baselevel(head,list,size) -- we always have an inline dir node in context + local baselevel, dirfound = get_baselevel(head,list,size,direction) if not dirfound and trace_details then report_directions("no initial direction found, gambling") end @@ -825,8 +832,7 @@ local function process(head) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - local head, done = apply_to_list(list,size,head,pardir) - return tonode(head), done + return apply_to_list(list,size,head,baselevel) end directions.installhandler(interfaces.variables.one,process) diff --git a/tex/context/base/mkiv/typo-dub.lua b/tex/context/base/mkiv/typo-dub.lua index d0747ae6c..f27e40476 100644 --- a/tex/context/base/mkiv/typo-dub.lua +++ b/tex/context/base/mkiv/typo-dub.lua @@ -55,8 +55,6 @@ local mirrordata = characters.mirrors local textclassdata = characters.textclasses local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getid = nuts.getid @@ -65,11 +63,11 @@ local getlist = nuts.getlist local getchar = nuts.getchar local getattr = nuts.getattr local getprop = nuts.getprop -local getdir = nuts.getdir +local getdirection = nuts.getdirection local setprop = nuts.setprop local setchar = nuts.setchar -local setdir = nuts.setdir +local setdirection = nuts.setdirection local setattrlist = nuts.setattrlist local remove_node = nuts.remove @@ -77,10 +75,10 @@ local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local nodepool = nuts.pool -local new_textdir = nodepool.textdir +local new_direction = nodepool.direction local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local glyph_code = nodecodes.glyph local glue_code = nodecodes.glue @@ -89,24 +87,29 @@ local vlist_code = nodecodes.vlist local math_code = nodecodes.math local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local parfillskip_code = skipcodes.parfillskip -local maximum_stack = 0xFF -- unicode: 60, will be jumped to 125, we don't care too much +local parfillskip_code = gluecodes.parfillskip + +local dirvalues = nodes.dirvalues +local lefttoright_code = dirvalues.lefttoright +local righttoleft_code = dirvalues.righttoleft + +local maximum_stack = 0xFF + +local a_directions = attributes.private('directions') local directions = typesetters.directions local setcolor = directions.setcolor local getfences = directions.getfences -local a_directions = attributes.private('directions') - local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end) ----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end) -local trace_directions = false trackers .register("typesetters.directions.two", function(v) trace_directions = v end) -local trace_details = false trackers .register("typesetters.directions.two.details", function(v) trace_details = v end) -local trace_list = false trackers .register("typesetters.directions.two.list", function(v) trace_list = v end) +local report_directions = logs.reporter("typesetting","directions three") -local report_directions = logs.reporter("typesetting","directions two") +local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end) +local trace_details = false trackers.register("typesetters.directions.details", function(v) trace_details = v end) +local trace_list = false trackers.register("typesetters.directions.list", function(v) trace_list = v end) -- strong (old): -- @@ -117,7 +120,7 @@ local report_directions = logs.reporter("typesetting","directions two") -- lre : left to right embedding -- rle : left to left embedding -- al : right to legt arabic (esp punctuation issues) - +-- -- weak: -- -- en : english number @@ -127,23 +130,23 @@ local report_directions = logs.reporter("typesetting","directions two") -- cs : common number separator -- nsm : nonspacing mark -- bn : boundary neutral - +-- -- neutral: -- -- b : paragraph separator -- s : segment separator -- ws : whitespace -- on : other neutrals - +-- -- interesting: this is indeed better (and more what we expect i.e. we already use this split -- in the old original (also these isolates) - +-- -- strong (new): -- -- l : left to right -- r : right to left -- al : right to left arabic (esp punctuation issues) - +-- -- explicit: (new) -- -- lro : left to right override @@ -206,27 +209,28 @@ end local function show_done(list,size) local joiner = utfchar(0x200C) local result = { } + local format = formatters["<%s>"] for i=1,size do local entry = list[i] local character = entry.char local begindir = entry.begindir local enddir = entry.enddir if begindir then - result[#result+1] = formatters["<%s>"](begindir) + result[#result+1] = format(begindir) end if entry.remove then -- continue elseif character == 0xFFFC then - result[#result+1] = formatters["<%s>"]("?") + result[#result+1] = format("?") elseif character == 0x0020 then - result[#result+1] = formatters["<%s>"](" ") + result[#result+1] = format(" ") elseif character >= 0x202A and character <= 0x202C then - result[#result+1] = formatters["<%s>"](entry.original) + result[#result+1] = format(entry.original) else result[#result+1] = utfchar(character) end if enddir then - result[#result+1] = formatters["<%s>"](enddir) + result[#result+1] = format(enddir) end end return concat(result,joiner) @@ -236,17 +240,7 @@ end -- char is only used for mirror, so in fact we can as well only store it for -- glyphs only --- using metatable is slightly faster so maybe some day ... - --- local space = { char = 0x0020, direction = "ws", original = "ws" } --- local lre = { char = 0x202A, direction = "lre", original = "lre" } --- local rle = { char = 0x202B, direction = "rle", original = "rle" } --- local pdf = { char = 0x202C, direction = "pdf", original = "pdf" } --- local object = { char = 0xFFFC, direction = "on", original = "on" } --- --- local t = { level = 0 } setmetatable(t,space) list[size] = t - -local function build_list(head) -- todo: store node pointer ... saves loop +local function build_list(head) -- P1 local current = head local list = { } @@ -282,13 +276,19 @@ local function build_list(head) -- todo: store node pointer ... saves loop list[size] = { char = 0x0020, direction = "ws", original = "ws", level = 0 } current = getnext(current) elseif id == dir_code then - local dir = getdir(current) - if dir == "+TLT" then - list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 } - elseif dir == "+TRT" then - list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 } - elseif dir == "-TLT" or dir == "-TRT" then - list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } + local direction, pop = getdirection(current) + if direction == lefttoright_code then + if pop then + list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } + else + list[size] = { char = 0x202A, direction = "lre", original = "lre", level = 0 } + end + elseif direction == righttoleft_code then + if pop then + list[size] = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } + else + list[size] = { char = 0x202B, direction = "rle", original = "rle", level = 0 } + end else list[size] = { char = 0xFFFC, direction = "on", original = "on", level = 0, id = id } -- object replacement character end @@ -343,8 +343,8 @@ end local function resolve_fences(list,size,start,limit) -- N0: funny effects, not always better, so it's an option - local stack = { } - local top = 0 + local stack = { } + local nofstack = 0 for i=start,limit do local entry = list[i] if entry.direction == "on" then @@ -355,15 +355,15 @@ local function resolve_fences(list,size,start,limit) entry.mirror = mirror entry.class = class if class == "open" then - top = top + 1 - stack[top] = { mirror, i, false } - elseif top == 0 then + nofstack = nofstack + 1 + stack[nofstack] = { mirror, i, false } + elseif nofstack == 0 then -- skip elseif class == "close" then - while top > 0 do - local s = stack[top] - if s[1] == char then - local open = s[2] + while nofstack > 0 do + local stacktop = stack[nofstack] + if stacktop[1] == char then + local open = stacktop[2] local close = i list[open ].paired = close list[close].paired = open @@ -371,7 +371,7 @@ local function resolve_fences(list,size,start,limit) else -- do we mirror or not end - top = top - 1 + nofstack = nofstack - 1 end end end @@ -394,27 +394,32 @@ end -- the action -local function get_baselevel(head,list,size) -- todo: skip if first is object (or pass head and test for localpar) - local id = getid(head) - if id == localpar_code then - if getdir(head) == "TRT" then - return 1, "TRT", true - else - return 0, "TLT", true +local function get_baselevel(head,list,size,direction) + if direction == lefttoright_code or direction == righttoleft_code then + return direction, true + elseif getid(head) == localpar_code and getsubtype(head) == 0 then + direction = getdirection(head) + if direction == lefttoright_code or direction == righttoleft_code then + return direction, true end - else - -- P2, P3 - for i=1,size do - local entry = list[i] - local direction = entry.direction - if direction == "r" or direction == "al" then -- and an ? - return 1, "TRT", true - elseif direction == "l" then - return 0, "TLT", true - end + end + -- for old times sake we we handle strings too + if direction == "TLT" then + return lefttoright_code, true + elseif direction == "TRT" then + return righttoleft_code, true + end + -- P2, P3 + for i=1,size do + local entry = list[i] + local direction = entry.direction + if direction == "r" or direction == "al" then -- and an ? + return righttoleft_code, true + elseif direction == "l" then + return lefttoright_code, true end - return 0, "TLT", false end + return lefttoright_code, false end local function resolve_explicit(list,size,baselevel) @@ -480,16 +485,17 @@ local function resolve_explicit(list,size,baselevel) end -- X7 elseif direction == "pdf" then - if nofstack < maximum_stack then + if nofstack > 0 then local stacktop = stack[nofstack] - nofstack = nofstack - 1 level = stacktop[1] override = stacktop[2] + nofstack = nofstack - 1 entry.level = level entry.direction = "bn" entry.remove = true elseif trace_directions then - report_directions("stack overflow at position %a with direction %a",i,direction) + report_directions("stack underflow at position %a with direction %a", + i, direction) end -- X6 else @@ -688,33 +694,6 @@ local function resolve_neutral(list,size,start,limit,orderbefore,orderafter) end end --- local function resolve_implicit(list,size,start,limit,orderbefore,orderafter) --- -- I1 --- for i=start,limit do --- local entry = list[i] --- local level = entry.level --- if level % 2 ~= 1 then -- not odd(level) --- local direction = entry.direction --- if direction == "r" then --- entry.level = level + 1 --- elseif direction == "an" or direction == "en" then --- entry.level = level + 2 --- end --- end --- end --- -- I2 --- for i=start,limit do --- local entry = list[i] --- local level = entry.level --- if level % 2 == 1 then -- odd(level) --- local direction = entry.direction --- if direction == "l" or direction == "en" or direction == "an" then --- entry.level = level + 1 --- end --- end --- end --- end - local function resolve_implicit(list,size,start,limit,orderbefore,orderafter,baselevel) for i=start,limit do local entry = list[i] @@ -814,52 +793,6 @@ local function resolve_levels(list,size,baselevel,analyze_fences) end end --- local function insert_dir_points(list,size) --- -- L2, but no actual reversion is done, we simply annotate where --- -- begindir/endddir node will be inserted. --- local maxlevel = 0 --- local finaldir = false --- for i=1,size do --- local level = list[i].level --- if level > maxlevel then --- maxlevel = level --- end --- end --- for level=0,maxlevel do --- local started = false --- local begindir = nil --- local enddir = nil --- if level % 2 == 1 then --- begindir = "+TRT" --- enddir = "-TRT" --- else --- begindir = "+TLT" --- enddir = "-TLT" --- end --- for i=1,size do --- local entry = list[i] --- if entry.level >= level then --- if not started then --- entry.begindir = begindir --- started = true --- end --- else --- if started then --- list[i-1].enddir = enddir --- started = false --- end --- end --- end --- -- make sure to close the run at end of line --- if started then --- finaldir = enddir --- end --- end --- if finaldir then --- list[size].enddir = finaldir --- end --- end - local function insert_dir_points(list,size) -- L2, but no actual reversion is done, we simply annotate where -- begindir/endddir node will be inserted. @@ -877,12 +810,12 @@ local function insert_dir_points(list,size) local enddir -- = nil local prev -- = nil if toggle then - begindir = "+TLT" - enddir = "-TLT" + begindir = lefttoright_code + enddir = lefttoright_code toggle = false else - begindir = "+TRT" - enddir = "-TRT" + begindir = righttoleft_code + enddir = righttoleft_code toggle = true end for i=1,size do @@ -922,7 +855,7 @@ local function insert_dir_points(list,size) if trace_list and n > 1 then report_directions("unbalanced list") end - last.enddir = s[n] == "+TRT" and "-TRT" or "-TLT" + last.enddir = s[n] == righttoleft_code and righttoleft_code or lefttoright_code end end end @@ -930,7 +863,6 @@ end local function apply_to_list(list,size,head,pardir) local index = 1 local current = head - local done = false if trace_list then report_directions("start run") end @@ -964,34 +896,31 @@ local function apply_to_list(list,size,head,pardir) setcolor(current,direction,false,mirror) end elseif id == hlist_code or id == vlist_code then - setdir(current,pardir) -- is this really needed? + setdirection(current,pardir) -- is this really needed? elseif id == glue_code then if enddir and getsubtype(current) == parfillskip_code then -- insert the last enddir before \parfillskip glue - local d = new_textdir(enddir) - setprop(d,"directions",true) + local d = new_direction(enddir,true) + -- setprop(d,"directions",true) -- setattrlist(d,current) head = insert_node_before(head,current,d) enddir = false - done = true end elseif begindir then - if id == localpar_code then + if id == localpar_code and getsubtype(current) == 0 then -- localpar should always be the 1st node - local d = new_textdir(begindir) - setprop(d,"directions",true) + local d = new_direction(begindir) + -- setprop(d,"directions",true) -- setattrlist(d,current) head, current = insert_node_after(head,current,d) begindir = nil - done = true end end if begindir then - local d = new_textdir(begindir) - setprop(d,"directions",true) + local d = new_direction(begindir) + -- setprop(d,"directions",true) -- setattrlist(d,current) head = insert_node_before(head,current,d) - done = true end local skip = entry.skip if skip and skip > 0 then @@ -1001,18 +930,16 @@ local function apply_to_list(list,size,head,pardir) end end if enddir then - local d = new_textdir(enddir) - setprop(d,"directions",true) + local d = new_direction(enddir,true) + -- setprop(d,"directions",true) -- setattrlist(d,current) head, current = insert_node_after(head,current,d) - done = true end if not entry.remove then current = getnext(current) elseif remove_controls then -- X9 head, current = remove_node(head,current,true) - done = true else current = getnext(current) end @@ -1021,17 +948,16 @@ local function apply_to_list(list,size,head,pardir) if trace_list then report_directions("stop run") end - return head, done + return head end -local function process(head) - head = tonut(head) +local function process(head,direction,only_one,where) -- for the moment a whole paragraph property local attr = getattr(head,a_directions) local analyze_fences = getfences(attr) -- local list, size = build_list(head) - local baselevel, pardir, dirfound = get_baselevel(head,list,size) -- we always have an inline dir node in context + local baselevel, dirfound = get_baselevel(head,list,size,direction) if not dirfound and trace_details then report_directions("no initial direction found, gambling") end @@ -1045,8 +971,7 @@ local function process(head) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - local head, done = apply_to_list(list,size,head,pardir) - return tonode(head), done + return apply_to_list(list,size,head,baselevel) end directions.installhandler(interfaces.variables.two,process) diff --git a/tex/context/base/mkiv/typo-duc.lua b/tex/context/base/mkiv/typo-duc.lua index 520740190..f91fc4d64 100644 --- a/tex/context/base/mkiv/typo-duc.lua +++ b/tex/context/base/mkiv/typo-duc.lua @@ -7,8 +7,6 @@ if not modules then modules = { } end modules ['typo-duc'] = { comment = "Unicode bidi (sort of) variant c", } --- Will be replaced by typo-duc-new.lua! - -- This is a follow up on typo-uda which itself is a follow up on t-bidi by Khaled Hosny which -- in turn is based on minibidi.c from Arabeyes. This is a further optimizations, as well as -- an update on some recent unicode bidi developments. There is (and will) also be more control @@ -58,8 +56,6 @@ local mirrordata = characters.mirrors local textclassdata = characters.textclasses local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getid = nuts.getid @@ -68,11 +64,12 @@ local getlist = nuts.getlist local getchar = nuts.getchar local getattr = nuts.getattr local getprop = nuts.getprop -local getdir = nuts.getdir +local getdirection = nuts.getdirection +local isglyph = nuts.isglyph local setprop = nuts.setprop local setchar = nuts.setchar -local setdir = nuts.setdir +local setdirection = nuts.setdirection local setattrlist = nuts.setattrlist local properties = nodes.properties.data @@ -82,10 +79,10 @@ local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local nodepool = nuts.pool -local new_textdir = nodepool.textdir +local new_direction = nodepool.direction local nodecodes = nodes.nodecodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local glyph_code = nodecodes.glyph local glue_code = nodecodes.glue @@ -94,25 +91,30 @@ local vlist_code = nodecodes.vlist local math_code = nodecodes.math local dir_code = nodecodes.dir local localpar_code = nodecodes.localpar -local parfillskip_code = skipcodes.parfillskip -local maximum_stack = 0xFF -- unicode: 60, will be jumped to 125, we don't care too much +local parfillskip_code = gluecodes.parfillskip + +local dirvalues = nodes.dirvalues +local lefttoright_code = dirvalues.lefttoright +local righttoleft_code = dirvalues.righttoleft + +local maximum_stack = 0xFF + +local a_directions = attributes.private('directions') local directions = typesetters.directions local setcolor = directions.setcolor local getfences = directions.getfences -local a_directions = attributes.private('directions') - local remove_controls = true directives.register("typesetters.directions.removecontrols",function(v) remove_controls = v end) ----- analyze_fences = true directives.register("typesetters.directions.analyzefences", function(v) analyze_fences = v end) -local trace_directions = false trackers.register("typesetters.directions.three", function(v) trace_directions = v end) -local trace_details = false trackers.register("typesetters.directions.three.details", function(v) trace_details = v end) -local trace_list = false trackers.register("typesetters.directions.three.list", function(v) trace_list = v end) - local report_directions = logs.reporter("typesetting","directions three") +local trace_directions = false trackers.register("typesetters.directions", function(v) trace_directions = v end) +local trace_details = false trackers.register("typesetters.directions.details", function(v) trace_details = v end) +local trace_list = false trackers.register("typesetters.directions.list", function(v) trace_list = v end) + -- strong (old): -- -- l : left to right @@ -122,7 +124,7 @@ local report_directions = logs.reporter("typesetting","directions three") -- lre : left to right embedding -- rle : left to left embedding -- al : right to legt arabic (esp punctuation issues) - +-- -- weak: -- -- en : english number @@ -132,23 +134,23 @@ local report_directions = logs.reporter("typesetting","directions three") -- cs : common number separator -- nsm : nonspacing mark -- bn : boundary neutral - +-- -- neutral: -- -- b : paragraph separator -- s : segment separator -- ws : whitespace -- on : other neutrals - +-- -- interesting: this is indeed better (and more what we expect i.e. we already use this split -- in the old original (also these isolates) - +-- -- strong (new): -- -- l : left to right -- r : right to left -- al : right to left arabic (esp punctuation issues) - +-- -- explicit: (new) -- -- lro : left to right override @@ -241,20 +243,20 @@ end -- keeping the list and overwriting doesn't save much runtime, only a few percent -- char is only used for mirror, so in fact we can as well only store it for -- glyphs only - +-- -- tracking what direction is used and skipping tests is not faster (extra kind of -- compensates gain) -local mt_space = { __index = { char = 0x0020, direction = "ws", original = "ws", level = 0 } } -local mt_lre = { __index = { char = 0x202A, direction = "lre", original = "lre", level = 0 } } -local mt_rle = { __index = { char = 0x202B, direction = "rle", original = "rle", level = 0 } } -local mt_pdf = { __index = { char = 0x202C, direction = "pdf", original = "pdf", level = 0 } } -local mt_object = { __index = { char = 0xFFFC, direction = "on", original = "on", level = 0 } } +local mt_space = { __index = { char = 0x0020, direction = "ws", original = "ws", level = 0, skip = 0 } } +local mt_lre = { __index = { char = 0x202A, direction = "lre", original = "lre", level = 0, skip = 0 } } +local mt_rle = { __index = { char = 0x202B, direction = "rle", original = "rle", level = 0, skip = 0 } } +local mt_pdf = { __index = { char = 0x202C, direction = "pdf", original = "pdf", level = 0, skip = 0 } } +local mt_object = { __index = { char = 0xFFFC, direction = "on", original = "on", level = 0, skip = 0 } } local stack = table.setmetatableindex("table") -- shared local list = { } -- shared -local function build_list(head) -- todo: store node pointer ... saves loop +local function build_list(head,where) -- P1 local current = head local size = 0 @@ -263,6 +265,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop local id = getid(current) local p = properties[current] if p and p.directions then + -- tricky as dirs can be injected in between local skip = 0 local last = id current = getnext(current) @@ -285,6 +288,7 @@ local function build_list(head) -- todo: store node pointer ... saves loop elseif id == glyph_code then local chr = getchar(current) local dir = directiondata[chr] + -- could also be a metatable list[size] = { char = chr, direction = dir, original = dir, level = 0 } current = getnext(current) -- if not list[dir] then list[dir] = true end -- not faster when we check for usage @@ -292,13 +296,11 @@ local function build_list(head) -- todo: store node pointer ... saves loop list[size] = setmetatable({ },mt_space) current = getnext(current) elseif id == dir_code then - local dir = getdir(current) - if dir == "+TLT" then - list[size] = setmetatable({ },mt_lre) - elseif dir == "+TRT" then - list[size] = setmetatable({ },mt_rle) - elseif dir == "-TLT" or dir == "-TRT" then - list[size] = setmetatable({ },mt_pdf) + local dir, pop = getdirection(current) + if dir == lefttoright_code then + list[size] = setmetatable({ },pop and mt_pdf or mt_lre) + elseif dir == righttoleft_code then + list[size] = setmetatable({ },pop and mt_pdf or mt_rle) else list[size] = setmetatable({ id = id },mt_object) end @@ -351,6 +353,8 @@ end -- ש ( ל ( א ) כ ) 2-8,4-6 -- ש ( ל [ א ] כ ) 2-8,4-6 +local fencestack = table.setmetatableindex("table") + local function resolve_fences(list,size,start,limit) -- N0: funny effects, not always better, so it's an option local nofstack = 0 @@ -365,15 +369,14 @@ local function resolve_fences(list,size,start,limit) entry.class = class if class == "open" then nofstack = nofstack + 1 - local stacktop = stack[nofstack] + local stacktop = fencestack[nofstack] stacktop[1] = mirror stacktop[2] = i - stacktop[3] = false -- not used elseif nofstack == 0 then -- skip elseif class == "close" then while nofstack > 0 do - local stacktop = stack[nofstack] + local stacktop = fencestack[nofstack] if stacktop[1] == char then local open = stacktop[2] local close = i @@ -407,25 +410,31 @@ end -- the action local function get_baselevel(head,list,size,direction) - if not direction and getid(head) == localpar_code then - direction = getdir(head) + if direction == lefttoright_code or direction == righttoleft_code then + return direction, true + elseif getid(head) == localpar_code and getsubtype(head) == 0 then + direction = getdirection(head) + if direction == lefttoright_code or direction == righttoleft_code then + return direction, true + end end - if direction == "TRT" then - return 1, "TRT", true - elseif direction == "TLT" then - return 0, "TLT", true + -- for old times sake we we handle strings too + if direction == "TLT" then + return lefttoright_code, true + elseif direction == "TRT" then + return righttoleft_code, true end - -- P2, P3: + -- P2, P3 for i=1,size do local entry = list[i] local direction = entry.direction if direction == "r" or direction == "al" then -- and an ? - return 1, "TRT", true + return righttoleft_code, true elseif direction == "l" then - return 0, "TLT", true + return lefttoright_code, true end end - return 0, "TLT", false + return lefttoright_code, false end local function resolve_explicit(list,size,baselevel) @@ -499,7 +508,7 @@ local function resolve_explicit(list,size,baselevel) end -- X7 elseif direction == "pdf" then - if nofstack < maximum_stack then + if nofstack > 0 then local stacktop = stack[nofstack] level = stacktop[1] override = stacktop[2] @@ -508,7 +517,11 @@ local function resolve_explicit(list,size,baselevel) entry.direction = "bn" entry.remove = true elseif trace_directions then - report_directions("stack overflow at position %a with direction %a",i,direction) + report_directions("stack underflow at position %a with direction %a", + i, direction) + else + report_directions("stack underflow at position %a with direction %a: %s", + i, direction, show_list(list,size)) end -- X6 else @@ -518,11 +531,6 @@ local function resolve_explicit(list,size,baselevel) end end end --- else --- for i=1,size do --- list[i].level = baselevel --- end --- end -- X8 (reset states and overrides after paragraph) end @@ -726,33 +734,6 @@ local function resolve_neutral(list,size,start,limit,orderbefore,orderafter) end end --- local function resolve_implicit(list,size,start,limit,orderbefore,orderafter) --- -- I1 --- for i=start,limit do --- local entry = list[i] --- local level = entry.level --- if level % 2 ~= 1 then -- not odd(level) --- local direction = entry.direction --- if direction == "r" then --- entry.level = level + 1 --- elseif direction == "an" or direction == "en" then --- entry.level = level + 2 --- end --- end --- end --- -- I2 --- for i=start,limit do --- local entry = list[i] --- local level = entry.level --- if level % 2 == 1 then -- odd(level) --- local direction = entry.direction --- if direction == "l" or direction == "en" or direction == "an" then --- entry.level = level + 1 --- end --- end --- end --- end - local function resolve_implicit(list,size,start,limit,orderbefore,orderafter,baselevel) for i=start,limit do local entry = list[i] @@ -852,60 +833,6 @@ local function resolve_levels(list,size,baselevel,analyze_fences) end end --- local function insert_dir_points(list,size) --- -- L2, but no actual reversion is done, we simply annotate where --- -- begindir/endddir node will be inserted. --- local maxlevel = 0 --- local finaldir = false --- local toggle = true --- for i=1,size do --- local level = list[i].level --- if level > maxlevel then --- maxlevel = level --- end --- end --- for level=0,maxlevel do --- local started -- = false --- local begindir -- = nil --- local enddir -- = nil --- local prev -- = nil --- if toggle then --- begindir = "+TLT" --- enddir = "-TLT" --- toggle = false --- else --- begindir = "+TRT" --- enddir = "-TRT" --- toggle = true --- end --- for i=1,size do --- local entry = list[i] --- if entry.level >= level then --- if not started then --- entry.begindir = begindir --- started = true --- end --- else --- if started then --- prev.enddir = enddir --- started = false --- end --- end --- prev = entry --- end --- -- make sure to close the run at end of line --- if started then --- finaldir = enddir --- end --- end --- if finaldir then --- list[size].enddir = finaldir --- end --- for i=1,size do --- print("<",i,list[i].level,list[i].begindir,list[i].enddir) --- end --- end - local stack = { } local function insert_dir_points(list,size) @@ -925,12 +852,12 @@ local function insert_dir_points(list,size) local enddir -- = nil local prev -- = nil if toggle then - begindir = "+TLT" - enddir = "-TLT" + begindir = lefttoright_code + enddir = lefttoright_code toggle = false else - begindir = "+TRT" - enddir = "-TRT" + begindir = righttoleft_code + enddir = righttoleft_code toggle = true end for i=1,size do @@ -969,15 +896,18 @@ local function insert_dir_points(list,size) if trace_list and n > 1 then report_directions("unbalanced list") end - last.enddir = stack[n] == "+TRT" and "-TRT" or "-TLT" + last.enddir = stack[n] end end end +-- We flag nodes that can be skipped when we see them again but because whatever +-- mechanism can injetc dir nodes that then are not flagged, we don't flag dir +-- nodes that we inject here. + local function apply_to_list(list,size,head,pardir) local index = 1 local current = head - local done = false if trace_list then report_directions("start run") end @@ -990,7 +920,12 @@ local function apply_to_list(list,size,head,pardir) local entry = list[index] local begindir = entry.begindir local enddir = entry.enddir - local p = properties[current] if p then p.directions = true else properties[current] = { directions = true } end + local p = properties[current] + if p then + p.directions = true + else + properties[current] = { directions = true } + end if id == glyph_code then local mirror = entry.mirror if mirror then @@ -1011,55 +946,43 @@ local function apply_to_list(list,size,head,pardir) setcolor(current,direction,false,mirror) end elseif id == hlist_code or id == vlist_code then - setdir(current,pardir) -- is this really needed? + setdirection(current,pardir) -- is this really needed? elseif id == glue_code then if enddir and getsubtype(current) == parfillskip_code then -- insert the last enddir before \parfillskip glue - local d = new_textdir(enddir) - local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setattrlist(d,current) - head = insert_node_before(head,current,d) + head = insert_node_before(head,current,new_direction(enddir,true)) enddir = false - done = true end elseif begindir then - if id == localpar_code then + if id == localpar_code and getsubtype(current) == 0 then -- localpar should always be the 1st node - local d = new_textdir(begindir) - local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setattrlist(d,current) - head, current = insert_node_after(head,current,d) + head, current = insert_node_after(head,current,new_direction(begindir)) begindir = nil - done = true end end if begindir then - local d = new_textdir(begindir) - local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setattrlist(d,current) - head = insert_node_before(head,current,d) - done = true + head = insert_node_before(head,current,new_direction(begindir)) end local skip = entry.skip if skip and skip > 0 then for i=1,skip do current = getnext(current) - local p = properties[current] if p then p.directions = true else properties[current] = { directions = true } end + local p = properties[current] + if p then + p.directions = true + else + properties[current] = { directions = true } + end end end if enddir then - local d = new_textdir(enddir) - local p = properties[d] if p then p.directions = true else properties[d] = { directions = true } end - -- setattrlist(d,current) - head, current = insert_node_after(head,current,d) - done = true + head, current = insert_node_after(head,current,new_direction(enddir,true)) end if not entry.remove then current = getnext(current) elseif remove_controls then -- X9 head, current = remove_node(head,current,true) - done = true else current = getnext(current) end @@ -1068,7 +991,7 @@ local function apply_to_list(list,size,head,pardir) if trace_list then report_directions("stop run") end - return head, done + return head end -- If needed we can optimize for only_one. There is no need to do anything @@ -1077,16 +1000,15 @@ end -- have more than one node. Actually, we only enter this function when we -- do have a glyph! -local function process(head,direction,only_one) - head = tonut(head) +local function process(head,direction,only_one,where) -- for the moment a whole paragraph property local attr = getattr(head,a_directions) local analyze_fences = getfences(attr) -- - local list, size = build_list(head) - local baselevel, pardir, dirfound = get_baselevel(head,list,size,direction) -- we always have an inline dir node in context + local list, size = build_list(head,where) + local baselevel, dirfound = get_baselevel(head,list,size,direction) if trace_details then - report_directions("analyze: direction %a, baselevel %a",dirfound and pardir or "unknown",baselevel or 1) + report_directions("analyze: baselevel %a",baselevel == righttoleft_code and "r2l" or "l2r") report_directions("before : %s",show_list(list,size,"original")) end resolve_explicit(list,size,baselevel) @@ -1096,8 +1018,12 @@ local function process(head,direction,only_one) report_directions("after : %s",show_list(list,size,"direction")) report_directions("result : %s",show_done(list,size)) end - local head, done = apply_to_list(list,size,head,pardir) - return tonode(head), done + return apply_to_list(list,size,head,baselevel) end -directions.installhandler(interfaces.variables.three,process) +local variables = interfaces.variables + +directions.installhandler(variables.one, process) -- for old times sake +directions.installhandler(variables.two, process) -- for old times sake +directions.installhandler(variables.three, process) -- for old times sake +directions.installhandler(variables.unicode,process) diff --git a/tex/context/base/mkiv/typo-fkr.lua b/tex/context/base/mkiv/typo-fkr.lua index a1135d0f3..1fd08526c 100644 --- a/tex/context/base/mkiv/typo-fkr.lua +++ b/tex/context/base/mkiv/typo-fkr.lua @@ -7,12 +7,10 @@ if not modules then modules = { } end modules ['typo-fkr'] = { } local nuts = nodes.nuts -local tonut = nuts.tonut local getid = nuts.getid local getnext = nuts.getnext -local getchar = nuts.getchar -local getfont = nuts.getfont local getattr = nuts.getattr +local isglyph = nuts.isglyph local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph @@ -32,20 +30,15 @@ local a_extrakern = attributes.private("extrafontkern") typesetters.fontkerns = { } function typesetters.fontkerns.handler(head) - local kepthead = head - local head = tonut(head) local current = head local lastfont = nil local lastchar = nil local lastdata = nil - local done = false while current do - local id = getid(current) - if id == glyph_code then + local char, font = isglyph(current) + if char then local a = getattr(current,a_extrakern) if a then - local char = getchar(current) - local font = getfont(current) if font ~= lastfont then if a > 0 and lastchar then if not lastdata then @@ -64,7 +57,6 @@ function typesetters.fontkerns.handler(head) end if kern ~= 0 then head, current = insert_before(head,current,new_kern(kern)) - done = true end lastdata = data else @@ -77,7 +69,6 @@ function typesetters.fontkerns.handler(head) local kern = getkernpair(lastdata,lastchar,char) if kern ~= 0 then head, current = insert_before(head,current,new_kern(kern)) - done = true end end lastchar = char @@ -94,7 +85,7 @@ function typesetters.fontkerns.handler(head) end current = getnext(current) end - return kepthead, done + return head end if context then diff --git a/tex/context/base/mkiv/typo-fln.lua b/tex/context/base/mkiv/typo-fln.lua index 4fb82ce44..048980732 100644 --- a/tex/context/base/mkiv/typo-fln.lua +++ b/tex/context/base/mkiv/typo-fln.lua @@ -30,7 +30,6 @@ local context = context local implement = interfaces.implement local nuts = nodes.nuts -local tonut = nuts.tonut local tonode = nuts.tonode local getnext = nuts.getnext @@ -38,7 +37,6 @@ local getprev = nuts.getprev local getboth = nuts.getboth local setboth = nuts.setboth local getid = nuts.getid -local getsubtype = nuts.getsubtype local getwidth = nuts.getwidth local getlist = nuts.getlist local setlist = nuts.setlist @@ -58,14 +56,16 @@ local glue_code = nodecodes.glue local spaceskip_code = nodes.gluecodes.spaceskip -local traverse_id = nuts.traverse_id +local nextglyph = nuts.traversers.glyph +local nextdisc = nuts.traversers.disc + local flush_node_list = nuts.flush_list local flush_node = nuts.flush_node local copy_node_list = nuts.copy_list local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local remove_node = nuts.remove -local list_dimensions = nuts.dimensions +local getdimensions = nuts.dimensions local hpack_node_list = nuts.hpack local nodepool = nuts.pool @@ -136,7 +136,7 @@ actions[v_line] = function(head,setting) local linebreaks = { } local function set(head) - for g in traverse_id(glyph_code,head) do + for g in nextglyph, head do if dynamic > 0 then setattr(g,0,dynamic) end @@ -146,7 +146,7 @@ actions[v_line] = function(head,setting) set(temp) - for g in traverse_id(disc_code,temp) do + for g in nextdisc, temp do local pre, post, replace = getdisc(g) if pre then set(pre) @@ -173,17 +173,13 @@ actions[v_line] = function(head,setting) local function list_dimensions(list,start) local temp = copy_node_list(list,start) - temp = tonode(temp) temp = nodes.handlers.characters(temp) temp = nodes.injections.handler(temp) -- temp = typesetters.fontkerns.handler(temp) -- maybe when enabled - -- nodes.handlers.protectglyphs(temp) -- not needed as we discard + -- nodes.handlers.protectglyphs(temp) -- not needed as we discard -- temp = typesetters.spacings.handler(temp) -- maybe when enabled -- temp = typesetters.kerns.handler(temp) -- maybe when enabled - temp = tonut(temp) - temp = hpack_node_list(temp) - local width = getwidth(temp) - flush_node_list(temp) + local width = getdimensions(temp) return width end @@ -206,7 +202,7 @@ actions[v_line] = function(head,setting) while start do local id = getid(start) if id == glyph_code then - n = n + 1 + -- go on elseif id == disc_code then -- this could be an option n = n + 1 @@ -218,7 +214,8 @@ actions[v_line] = function(head,setting) end elseif id == kern_code then -- todo: fontkern -- this could be an option - elseif n > 0 then + elseif id == glue_code then + n = n + 1 if try() then break end @@ -255,7 +252,6 @@ actions[v_line] = function(head,setting) local id = getid(start) local ok = false if id == glyph_code then - n = n + 1 update(start) elseif id == disc_code then n = n + 1 @@ -264,7 +260,7 @@ actions[v_line] = function(head,setting) if linebreak == n then local p, n = getboth(start) if pre then - for current in traverse_id(glyph_code,pre) do + for current in nextglyph, pre do update(current) end setlink(pretail,n) @@ -284,7 +280,7 @@ actions[v_line] = function(head,setting) else local p, n = getboth(start) if replace then - for current in traverse_id(glyph_code,replace) do + for current in nextglyph, replace do update(current) end setlink(replacetail,n) @@ -299,22 +295,30 @@ actions[v_line] = function(head,setting) setdisc(disc,pre,post,replace) flush_node(disc) elseif id == glue_code then - head = insert_node_before(head,start,newpenalty(10000)) -- nobreak + n = n + 1 + if linebreak ~= n then + head = insert_node_before(head,start,newpenalty(10000)) -- nobreak + end end + local next = getnext(start) if linebreak == n then - if trace_firstlines then - head, start = insert_node_after(head,start,newpenalty(10000)) -- nobreak - head, start = insert_node_after(head,start,newkern(-65536)) - head, start = insert_node_after(head,start,tracerrule(65536,4*65536,2*65536,"darkblue")) + if start ~= head then + local where = id == glue_code and getprev(start) or start + if trace_firstlines then + head, where = insert_node_after(head,where,newpenalty(10000)) -- nobreak + head, where = insert_node_after(head,where,newkern(-65536)) + head, where = insert_node_after(head,where,tracerrule(65536,4*65536,2*65536,"darkblue")) + end + head, where = insert_node_after(head,where,newpenalty(-10000)) -- break end - head, start = insert_node_after(head,start,newpenalty(-10000)) -- break + start = next break end - start = getnext(start) + start = next end end - return head, true + return head end actions[v_word] = function(head,setting) @@ -359,13 +363,12 @@ actions[v_word] = function(head,setting) end start = getnext(start) end - return head, true + return head end actions[v_default] = actions[v_line] function firstlines.handler(head) - head = tonut(head) local start = head local attr = nil while start do @@ -388,11 +391,10 @@ function firstlines.handler(head) if trace_firstlines then report_firstlines("processing firstlines, alternative %a",alternative) end - local head, done = action(head,settings) - return tonode(head), done + return action(head,settings) end end - return tonode(head), false + return head end -- goodie @@ -401,7 +403,7 @@ local function applytofirstcharacter(box,what) local tbox = getbox(box) -- assumes hlist local list = getlist(tbox) local done = nil - for n in traverse_id(glyph_code,list) do + for n in nextglyph, list do list = remove_node(list,n) done = n break diff --git a/tex/context/base/mkiv/typo-fln.mkiv b/tex/context/base/mkiv/typo-fln.mkiv index 37348be29..533c197cd 100644 --- a/tex/context/base/mkiv/typo-fln.mkiv +++ b/tex/context/base/mkiv/typo-fln.mkiv @@ -91,7 +91,7 @@ \kern\zeropoint % we need a node % \hskip\zeropoint\s!plus\emwidth\relax % can be an option \endgroup - \globallet\typo_firstline_handle\relax} + \glet\typo_firstline_handle\relax} \let\typo_firstline_handle\relax diff --git a/tex/context/base/mkiv/typo-itc.lua b/tex/context/base/mkiv/typo-itc.lua index 328bf1406..2683eecc3 100644 --- a/tex/context/base/mkiv/typo-itc.lua +++ b/tex/context/base/mkiv/typo-itc.lua @@ -29,13 +29,9 @@ local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts local nodepool = nuts.pool -local tonode = nuts.tonode -local tonut = nuts.tonut - local getprev = nuts.getprev local getnext = nuts.getnext local getid = nuts.getid -local getfont = nuts.getfont local getchar = nuts.getchar local getdisc = nuts.getdisc local getattr = nuts.getattr @@ -128,14 +124,22 @@ local function okay(data,current,font,prevchar,previtalic,char,what) return false end if threshold then - local ht = getheight(current) - local ex = exheights[font] - local th = threshold * ex - if ht <= th then - if trace_italics then - report_italics("ignoring correction between %s italic %C and regular %C, height %p less than threshold %p",prevchar,what,char,ht,th) + -- if getid(current) == glyph_code then + while current and getid(current) ~= glyph_code do + current = getprev(current) + end + if current then + local ht = getheight(current) + local ex = exheights[font] + local th = threshold * ex + if ht <= th then + if trace_italics then + report_italics("ignoring correction between %s italic %C and regular %C, height %p less than threshold %p",prevchar,what,char,ht,th) + end + return false end - return false + else + -- maybe backtrack to glyph end end if trace_italics then @@ -177,7 +181,7 @@ local textokay = false local enablemath = false local enabletext = false -local function domath(head,current, done) +local function domath(head,current) current = end_of_math(current) local next = getnext(current) if next then @@ -200,8 +204,7 @@ local function domath(head,current, done) a = a + 100 end local i = getkern(kern) - local f = getfont(glyph) - local c = getchar(glyph) + local c, f = isglyph(glyph) if getheight(next) < 1.25*exheights[f] then if i == 0 then if trace_italics then @@ -212,7 +215,6 @@ local function domath(head,current, done) report_italics("%s italic between math %C and punctuation %C","removing",i,c,char) end setkern(kern,0) -- or maybe a small value or half the ic - done = true end elseif i == 0 then local d = chardata[f][c] @@ -226,7 +228,6 @@ local function domath(head,current, done) if trace_italics then report_italics("%s italic %p between math %C and punctuation %C","setting",i,c,char) end - done = true end elseif trace_italics then report_italics("%s italic %p between math %C and punctuation %C","keeping",k,c,char) @@ -251,34 +252,31 @@ local function domath(head,current, done) report_italics("%s italic %p between math %C and non punctuation %C","adding",a,getchar(glyph),char) end insert_node_after(head,glyph,correction_kern(a,glyph)) - done = true end end end end end end - return current, done + return current end local function mathhandler(head) - local nuthead = tonut(head) - local current = nuthead - local done = false + local current = head while current do if getid(current) == math_code then - current, done = domath(nuthead,current,done) + current = domath(head,current) end current = getnext(current) end - return head, done + return head end local function texthandler(head) local prev = nil local prevchar = nil - local prevhead = tonut(head) + local prevhead = head local previtalic = 0 local previnserted = nil @@ -300,20 +298,18 @@ local function texthandler(head) local replaceinserted = nil local current = prevhead - local done = false local lastfont = nil local lastattr = nil while current do local char, id = isglyph(current) if char then - local font = getfont(current) + local font = id local data = italicsdata[font] if font ~= lastfont then if previtalic ~= 0 then if okay(data,current,font,prevchar,previtalic,char,"glyph") then insert_node_after(prevhead,prev,correction_kern(previtalic,current)) - done = true end elseif previnserted and data then if trace_italics then @@ -325,7 +321,6 @@ local function texthandler(head) if replaceitalic ~= 0 then if okay(data,replace,font,replacechar,replaceitalic,char,"replace") then insert_node_after(replacehead,replace,correction_kern(replaceitalic,current)) - done = true end replaceitalic = 0 elseif replaceinserted and data then @@ -338,7 +333,6 @@ local function texthandler(head) if postitalic ~= 0 then if okay(data,post,font,postchar,postitalic,char,"post") then insert_node_after(posthead,post,correction_kern(postitalic,current)) - done = true end postitalic = 0 elseif postinserted and data then @@ -395,7 +389,7 @@ local function texthandler(head) while current do local char, id = isglyph(current) if char then - local font = getfont(current) + local font = id local data = italicsdata[font] if data then local attr = forcedvariant or getattr(current,a_italics) @@ -431,7 +425,7 @@ local function texthandler(head) while current do local char, id = isglyph(current) if char then - local font = getfont(current) + local font = id local data = italicsdata[font] if data then local attr = forcedvariant or getattr(current,a_italics) @@ -479,7 +473,6 @@ local function texthandler(head) end previnserted = correction_glue(previtalic,current) -- maybe just add ? else problem with penalties previtalic = 0 - done = true insert_node_after(prevhead,prev,previnserted) else if replaceitalic ~= 0 then @@ -488,7 +481,6 @@ local function texthandler(head) end replaceinserted = correction_kern(replaceitalic,current) -- needs to be a kern replaceitalic = 0 - done = true insert_node_after(replacehead,replace,replaceinserted) end if postitalic ~= 0 then @@ -497,7 +489,6 @@ local function texthandler(head) end postinserted = correction_kern(postitalic,current) -- needs to be a kern postitalic = 0 - done = true insert_node_after(posthead,post,postinserted) end end @@ -510,7 +501,7 @@ local function texthandler(head) postinserted = nil postitalic = 0 if mathokay then - current, done = domath(head,current,done) + current = domath(head,current) else current = end_of_math(current) end @@ -526,7 +517,6 @@ local function texthandler(head) replaceitalic = 0 postinserted = nil postitalic = 0 - done = true else if replaceitalic ~= 0 then if trace_italics then @@ -539,7 +529,6 @@ local function texthandler(head) replaceitalic = 0 postinserted = nil postitalic = 0 - done = true end if postitalic ~= 0 then if trace_italics then @@ -552,7 +541,6 @@ local function texthandler(head) replaceitalic = 0 postinserted = nil postitalic = 0 - done = true end end end @@ -564,25 +552,22 @@ local function texthandler(head) report_italics("inserting %p between %s italic %C and end of list",previtalic,"glyph",prevchar) end insert_node_after(prevhead,prev,correction_kern(previtalic,current)) - done = true else if replaceitalic ~= 0 then if trace_italics then report_italics("inserting %p between %s italic %C and end of list",replaceitalic,"replace",replacechar) end insert_node_after(replacehead,replace,correction_kern(replaceitalic,current)) - done = true end if postitalic ~= 0 then if trace_italics then report_italics("inserting %p between %s italic %C and end of list",postitalic,"post",postchar) end insert_node_after(posthead,post,correction_kern(postitalic,current)) - done = true end end end - return head, done + return head end function italics.handler(head) diff --git a/tex/context/base/mkiv/typo-krn.lua b/tex/context/base/mkiv/typo-krn.lua index 71d9736a4..c26004a49 100644 --- a/tex/context/base/mkiv/typo-krn.lua +++ b/tex/context/base/mkiv/typo-krn.lua @@ -21,9 +21,6 @@ local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts local nodepool = nuts.pool -local tonode = nuts.tonode -local tonut = nuts.tonut - -- check what is used local find_node_tail = nuts.tail @@ -32,6 +29,7 @@ local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after local end_of_math = nuts.end_of_math local use_components = nuts.use_components +local copy_node = nuts.copy local getnext = nuts.getnext local getprev = nuts.getprev @@ -43,10 +41,12 @@ local getdisc = nuts.getdisc local getglue = nuts.getglue local getkern = nuts.getkern local isglyph = nuts.isglyph +local setchar = nuts.setchar local setfield = nuts.setfield local getattr = nuts.getattr local takeattr = nuts.takeattr +local setattr = nuts.setattr local setlink = nuts.setlink local setdisc = nuts.setdisc local setglue = nuts.setglue @@ -62,7 +62,7 @@ local new_glue = nodepool.glue local nodecodes = nodes.nodecodes local kerncodes = nodes.kerncodes -local skipcodes = nodes.skipcodes +local gluecodes = nodes.gluecodes local disccodes = nodes.disccodes local listcodes = nodes.listcodes @@ -74,17 +74,18 @@ local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local math_code = nodecodes.math -local box_list_code = listcodes.box -local user_list_code = listcodes.unknown +local boxlist_code = listcodes.box +local unknownlist_code = listcodes.unknown -local discretionary_code = disccodes.discretionary -local automatic_code = disccodes.automatic +local discretionarydisc_code = disccodes.discretionary +local automaticdisc_code = disccodes.automatic local fontkern_code = kerncodes.fontkern local userkern_code = kerncodes.userkern -local userskip_code = skipcodes.userskip -local spaceskip_code = skipcodes.spaceskip -local xspaceskip_code = skipcodes.xspaceskip + +local userskip_code = gluecodes.userskip +local spaceskip_code = gluecodes.spaceskip +local xspaceskip_code = gluecodes.xspaceskip local fonthashes = fonts.hashes local chardata = fonthashes.characters @@ -132,9 +133,6 @@ local factors = kerns.factors local gluefactor = 4 -- assumes quad = .5 enspace -kerns.keepligature = false -- just for fun (todo: control setting with key/value) -kerns.keeptogether = false -- just for fun (todo: control setting with key/value) - -- red : kept by dynamic feature -- green : kept by static feature -- blue : keep by goodie @@ -257,7 +255,7 @@ end local function inject_end(boundary,next,keeptogether,krn,ok) local tail = find_node_tail(boundary) - local char, id = getid(tail) + local char, id = isglyph(tail) if id == kern_code then if getsubtype(tail) == fontkern_code then local inject = true @@ -301,7 +299,7 @@ local function process_list(head,keeptogether,krn,font,okay) local char, id = isglyph(start) if char then if not font then - font = getfont(start) + font = id -- getfont(start) mark = markdata[font] kern = quaddata[font]*krn end @@ -354,19 +352,223 @@ local function closest_bound(b,get) while b do if not getattr(b,a_kerns) then break - elseif getid(b) == glyph_code then - return b, getfont(b) else - b = get(b) + local c, f = isglyph(b) + if c then + return b, f + else + b = get(b) + end end end end end +-- function kerns.handler(head) +-- local start = head +-- local lastfont = nil +-- local keepligature = kerns.keepligature +-- local keeptogether = kerns.keeptogether +-- local fillup = false +-- local bound = false +-- local prev = nil +-- local previd = nil +-- local prevchar = nil +-- local prevfont = nil +-- local prevmark = nil +-- while start do +-- -- fontkerns don't get the attribute but they always sit between glyphs so +-- -- are always valid bound .. disc nodes also somtimes don't get them +-- local id = getid(start) +-- local attr = takeattr(start,a_kerns) +-- if attr and attr > 0 then +-- local krn = mapping[attr] +-- if krn == v_max then +-- krn = .25 +-- fillup = true +-- else +-- fillup = false +-- end +-- if not krn or krn == 0 then +-- bound = false +-- elseif id == glyph_code then +-- if keepligature and keepligature(start) then +-- -- keep 'm +-- else +-- -- we could use the subtype ligature but that's also a call +-- -- todo: check tounicode and use that information to split +-- head, start = use_components(head,start) +-- end +-- local char, font = isglyph(start) +-- local mark = markdata[font] +-- if not bound then +-- -- yet +-- elseif mark[char] then +-- -- skip +-- elseif previd == kern_code then +-- if getsubtype(prev) == fontkern_code then +-- local inject = true +-- if keeptogether then +-- if previd == glyph_code and keeptogether(prev,start) then +-- inject = false +-- end +-- end +-- if inject then +-- -- not yet ok, as injected kerns can be overlays (from node-inj.lua) +-- setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code) +-- end +-- end +-- elseif previd == glyph_code then +-- if prevfont == font then +-- if keeptogether and keeptogether(prev,start) then +-- -- keep 'm +-- else +-- local data = chardata[font][prevchar] +-- local kerns = data and data.kerns +-- local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn +-- insert_node_before(head,start,kern_injector(fillup,kern)) +-- end +-- else +-- insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn)) +-- end +-- end +-- prev = start +-- prevchar = char +-- prevfont = font +-- prevmark = mark +-- previd = id +-- bound = true +-- elseif id == disc_code then +-- local prev, next, pglyph, nglyph -- delayed till needed +-- local subtype = getsubtype(start) +-- -- if subtype == automaticdisc_code then +-- -- -- this is kind of special, as we have already injected the +-- -- -- previous kern +-- -- local prev = getprev(start) +-- -- local pglyph = prev and getid(prev) == glyph_code +-- -- languages.expand(start,pglyph and prev) +-- -- -- we can have a different start now +-- -- elseif subtype ~= discretionarydisc_code then +-- -- prev = getprev(start) +-- -- pglyph = prev and getid(prev) == glyph_code +-- -- languages.expand(start,pglyph and prev) +-- -- end +-- local pre, post, replace = getdisc(start) +-- local indeed = false +-- if pre then +-- local okay = false +-- if not prev then +-- prev = getprev(start) +-- pglyph = prev and getid(prev) == glyph_code +-- end +-- if pglyph then +-- pre, okay = inject_begin(pre,prev,keeptogether,krn,okay) +-- end +-- pre, okay = process_list(pre,keeptogether,krn,false,okay) +-- if okay then +-- indeed = true +-- end +-- end +-- if post then +-- local okay = false +-- if not next then +-- next = getnext(start) +-- nglyph = next and getid(next) == glyph_code +-- end +-- if nglyph then +-- post, okay = inject_end(post,next,keeptogether,krn,okay) +-- end +-- post, okay = process_list(post,keeptogether,krn,false,okay) +-- if okay then +-- indeed = true +-- end +-- end +-- if replace then +-- local okay = false +-- if not prev then +-- prev = getprev(start) +-- pglyph = prev and getid(prev) == glyph_code +-- end +-- if pglyph then +-- replace, okay = inject_begin(replace,prev,keeptogether,krn,okay) +-- end +-- if not next then +-- next = getnext(start) +-- nglyph = next and getid(next) == glyph_code +-- end +-- if nglyph then +-- replace, okay = inject_end(replace,next,keeptogether,krn,okay) +-- end +-- replace, okay = process_list(replace,keeptogether,krn,false,okay) +-- if okay then +-- indeed = true +-- end +-- elseif prevfont then +-- replace = new_kern(quaddata[prevfont]*krn) +-- indeed = true +-- end +-- if indeed then +-- setdisc(start,pre,post,replace) +-- end +-- bound = false +-- elseif id == kern_code then +-- bound = getsubtype(start) == fontkern_code +-- prev = start +-- previd = id +-- elseif id == glue_code then +-- local subtype = getsubtype(start) +-- if subtype == userskip_code or subtype == xspaceskip_code or subtype == spaceskip_code then +-- local width, stretch, shrink, stretch_order, shrink_order = getglue(start) +-- if width > 0 then +-- local w = width + gluefactor * width * krn +-- stretch = stretch * w / width +-- shrink = shrink * w / width +-- if fillup then +-- stretch = 2 * stretch +-- shrink = 2 * shrink +-- stretch_order = 1 +-- -- shrink_order = 1 ? +-- end +-- setglue(start,w,stretch,shrink,stretch_order,shrink_order) +-- end +-- end +-- bound = false +-- elseif id == hlist_code or id == vlist_code then +-- local subtype = getsubtype(start) +-- if subtype == unknownlist_code or subtype == boxlist_code then +-- -- special case +-- local b, f = closest_bound(start,getprev) +-- if b then +-- insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn)) +-- end +-- local b, f = closest_bound(start,getnext) +-- if b then +-- insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn)) +-- end +-- end +-- bound = false +-- elseif id == math_code then +-- start = end_of_math(start) +-- bound = false +-- end +-- if start then +-- start = getnext(start) +-- end +-- elseif id == kern_code then +-- bound = getsubtype(start) == fontkern_code +-- prev = start +-- previd = id +-- start = getnext(start) +-- else +-- bound = false +-- start = getnext(start) +-- end +-- end +-- return head +-- end + function kerns.handler(head) - local head = tonut(head) local start = head - local done = false local lastfont = nil local keepligature = kerns.keepligature local keeptogether = kerns.keeptogether @@ -379,10 +581,10 @@ function kerns.handler(head) local prevmark = nil while start do -- fontkerns don't get the attribute but they always sit between glyphs so - -- are always valid bound .. disc nodes also somtimes don't get them - local id = getid(start) + -- are always valid bound .. disc nodes also sometimes don't get them local attr = takeattr(start,a_kerns) if attr and attr > 0 then + local char, id = isglyph(start) local krn = mapping[attr] if krn == v_max then krn = .25 @@ -392,17 +594,34 @@ function kerns.handler(head) end if not krn or krn == 0 then bound = false - elseif id == glyph_code then + elseif char then -- id == glyph_code + local font = id -- more readable + local mark = markdata[font] if keepligature and keepligature(start) then -- keep 'm else - -- we could use the subtype ligature but that's also a call - -- todo: check tounicode and use that information to split - head, start = use_components(head,start) + -- head, start = use_components(head,start) + -- beware, these are not kerned so we mighty need a kern only pass + -- maybe some day .. anyway, one should disable ligaturing + local data = chardata[font][char] + if data then + local unicode = data.unicode -- can be cached + if type(unicode) == "table" then + char = unicode[1] + local s = start + setchar(s,char) + for i=2,#unicode do + local n = copy_node(s) + if i == 2 then + setattr(n,a_kerns,attr) -- we took away the attr + end + setchar(n,unicode[i]) + insert_node_after(head,s,n) + s = n + end + end + end end - local char = getchar(start) - local font = getfont(start) - local mark = markdata[font] if not bound then -- yet elseif mark[char] then @@ -418,7 +637,6 @@ function kerns.handler(head) if inject then -- not yet ok, as injected kerns can be overlays (from node-inj.lua) setkern(prev,getkern(prev) + quaddata[font]*krn,userkern_code) - done = true end end elseif previd == glyph_code then @@ -426,34 +644,33 @@ function kerns.handler(head) if keeptogether and keeptogether(prev,start) then -- keep 'm else + -- hm, only basemode ... will go away ... local data = chardata[font][prevchar] local kerns = data and data.kerns local kern = (kerns and kerns[char] or 0) + quaddata[font]*krn insert_node_before(head,start,kern_injector(fillup,kern)) - done = true end else insert_node_before(head,start,kern_injector(fillup,quaddata[font]*krn)) - done = true end end prev = start prevchar = char prevfont = font prevmark = mark - previd = id + previd = glyph_code -- id bound = true elseif id == disc_code then local prev, next, pglyph, nglyph -- delayed till needed local subtype = getsubtype(start) - -- if subtype == automatic_code then + -- if subtype == automaticdisc_code then -- -- this is kind of special, as we have already injected the -- -- previous kern -- local prev = getprev(start) -- local pglyph = prev and getid(prev) == glyph_code -- languages.expand(start,pglyph and prev) -- -- we can have a different start now - -- elseif subtype ~= discretionary_code then + -- elseif subtype ~= discretionarydisc_code then -- prev = getprev(start) -- pglyph = prev and getid(prev) == glyph_code -- languages.expand(start,pglyph and prev) @@ -514,7 +731,6 @@ function kerns.handler(head) end if indeed then setdisc(start,pre,post,replace) - done = true end bound = false elseif id == kern_code then @@ -536,23 +752,20 @@ function kerns.handler(head) -- shrink_order = 1 ? end setglue(start,w,stretch,shrink,stretch_order,shrink_order) - done = true end end bound = false elseif id == hlist_code or id == vlist_code then local subtype = getsubtype(start) - if subtype == user_list_code or subtype == box_list_code then + if subtype == unknownlist_code or subtype == boxlist_code then -- special case local b, f = closest_bound(start,getprev) if b then insert_node_before(head,start,kern_injector(fillup,quaddata[f]*krn)) - done = true end local b, f = closest_bound(start,getnext) if b then insert_node_after(head,start,kern_injector(fillup,quaddata[f]*krn)) - done = true end end bound = false @@ -563,17 +776,20 @@ function kerns.handler(head) if start then start = getnext(start) end - elseif id == kern_code then - bound = getsubtype(start) == fontkern_code - prev = start - previd = id - start = getnext(start) else - bound = false - start = getnext(start) + local id = getid(start) + if id == kern_code then + bound = getsubtype(start) == fontkern_code + prev = start + previd = id + start = getnext(start) + else + bound = false + start = getnext(start) + end end end - return tonode(head), done + return head end local enabled = false diff --git a/tex/context/base/mkiv/typo-lin.lua b/tex/context/base/mkiv/typo-lin.lua index ebf748a82..8393ea65b 100644 --- a/tex/context/base/mkiv/typo-lin.lua +++ b/tex/context/base/mkiv/typo-lin.lua @@ -64,7 +64,7 @@ local listcodes = nodes.listcodes local hlist_code = nodecodes.hlist local glue_code = nodecodes.glue local kern_code = nodecodes.kern -local line_code = listcodes.line +local linelist_code = listcodes.line ----- localpar_code = nodecodes.localpar local leftskip_code = gluecodes.leftskip local rightskip_code = gluecodes.rightskip @@ -73,7 +73,7 @@ local parfillskip_code = gluecodes.parfillskip local tonut = nodes.tonut local tonode = nodes.tonode -local traverse_id = nuts.traverse_id +local nexthlist = nuts.traversers.hlist local insert_before = nuts.insert_before local insert_after = nuts.insert_after local find_tail = nuts.tail @@ -90,7 +90,7 @@ local getboth = nuts.getboth local setlink = nuts.setlink local setkern = nuts.setkern local getkern = nuts.getkern -local getdir = nuts.getdir +local getdirection = nuts.getdirection local getshift = nuts.getshift local setshift = nuts.setshift local getwidth = nuts.getwidth @@ -109,6 +109,8 @@ local new_hlist = nodepool.hlist local new_rule = nodepool.rule local new_glue = nodepool.glue +local righttoleft_code = nodes.dirvalues.righttoleft + local texgetcount = tex.getcount local texgetglue = tex.getglue local setmetatableindex = table.setmetatableindex @@ -127,22 +129,12 @@ local noflines = 0 -- This is the third version, a mix between immediate (prestice lines) and delayed -- as we don't want anchors that are not used. --- if reverse then delta = - delta end --- head = insert_before(head,head,nodepool.textdir("-TLT")) --- .... --- head = insert_before(head,head,nodepool.textdir("TLT")) - --- todo: figure out metatable mess ... when we copy we also need to copy --- anchors ... use rawgets - --- problem: what if a box is copied ... we could check an attribute - local function finalize(prop,key) -- delayed calculations local line = prop.line local hsize = prop.hsize local width = prop.width local shift = getshift(line) -- dangerous as it can be vertical as well - local reverse = getdir(line) == "TRT" or false + local reverse = getdirection(line) == righttoleft_code or false local pack = new_hlist() local head = getlist(line) local delta = 0 @@ -248,49 +240,47 @@ function paragraphs.normalize(head,islocal) return head, false end -- this can become a separate handler but it makes sense to integrate it here - local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip") - if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then - local last = nil -- a nut - local done = false - for line in traverse_id(hlist_code,tonut(head)) do - if getsubtype(line) == line_code and not getprop(line,"line") then - if done then - last = line - else - done = true + local mode = texgetcount("parfillleftmode") + if mode > 0 then + local l_width, l_stretch, l_shrink = texgetglue("parfillleftskip") + if l_width ~= 0 or l_stretch ~= 0 or l_shrink ~= 0 then + local last = nil -- a nut + local done = mode == 2 -- false + for line, subtype in nexthlist, head do + if subtype == linelist_code and not getprop(line,"line") then + if done then + last = line + else + done = true + end end end - end - if last then -- only if we have more than one line - local head = getlist(last) - local current = head - if current then - if getid(current) == glue_code and getsubtype(current,leftskip_code) then - current = getnext(current) - end + if last then -- only if we have more than one line + local head = getlist(last) + local current = head if current then - head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink)) - if head == current then - setlist(last,head) + if getid(current) == glue_code and getsubtype(current,leftskip_code) then + current = getnext(current) + end + if current then + head, current = insert_before(head,current,new_glue(l_width,l_stretch,l_shrink)) + if head == current then + setlist(last,head) + end + -- can be a 'rehpack(h )' + rehpack(last) end - -- can be a 'rehpack(h )' - rehpack(last) end end end end -- normalizer - for line in traverse_id(hlist_code,tonut(head)) do - if getsubtype(line) == line_code and not getprop(line,"line") then + for line, subtype in nexthlist, head do + if subtype == linelist_code and not getprop(line,"line") then normalize(line) - if done then - last = line - else - done = true - end end end - return head, true + return head, true -- true is obsolete end -- print(nodes.idstostring(head)) @@ -418,12 +408,17 @@ function paragraphs.moveinline(n,blob,dx,dy) end end -local lateluafunction = nodepool.lateluafunction -local setposition = job.positions.set -local t_anchor = { x = true, c = true } +local latelua = nodepool.latelua +local setposition = jobpositions.setspec +local t_anchor = { x = true, c = true } -- needs checking local function setanchor(h_anchor) - return lateluafunction(function() setposition("md:h",h_anchor,t_anchor) end) + return latelua { + action = setposition, + name = "md:h", + index = h_anchor, + value = t_anchor, -- really shared ? + } end function paragraphs.calculatedelta(n,width,delta,atleft,islocal,followshape,area) diff --git a/tex/context/base/mkiv/typo-mar.lua b/tex/context/base/mkiv/typo-mar.lua index bc9c408c1..f8665e0b0 100644 --- a/tex/context/base/mkiv/typo-mar.lua +++ b/tex/context/base/mkiv/typo-mar.lua @@ -62,13 +62,11 @@ local nuts = nodes.nuts local nodepool = nuts.pool local tonode = nuts.tonode -local tonut = nuts.tonut local hpack_nodes = nuts.hpack local traverse_id = nuts.traverse_id local flush_node_list = nuts.flush_list -local getfield = nuts.getfield local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid @@ -84,6 +82,9 @@ local setshift = nuts.setshift local getwidth = nuts.getwidth local setwidth = nuts.setwidth local getheight = nuts.getheight +local getprop = nuts.getprop + +local setattrlist = nuts.setattrlist local getbox = nuts.getbox local takebox = nuts.takebox @@ -93,7 +94,6 @@ local getprop = nuts.getprop local nodecodes = nodes.nodecodes local listcodes = nodes.listcodes -local gluecodes = nodes.gluecodes local whatsitcodes = nodes.whatsitcodes local hlist_code = nodecodes.hlist @@ -103,17 +103,17 @@ local userdefined_code = whatsitcodes.userdefined local nodepool = nuts.pool -local new_usernumber = nodepool.usernumber +local new_usernode = nodepool.usernode local new_hlist = nodepool.hlist -local lateluafunction = nodepool.lateluafunction +local latelua = nodepool.latelua local texgetdimen = tex.getdimen local texgetcount = tex.getcount local texget = tex.get local isleftpage = layouts.status.isleftpage -local registertogether = builders.paragraphs.registertogether -- tonode +local registertogether = builders.paragraphs.registertogether local paragraphs = typesetters.paragraphs local addtoline = paragraphs.addtoline @@ -299,7 +299,9 @@ function margins.save(t) -- -- t.realpageno = texgetcount("realpageno") if inline then - context(tonode(new_usernumber(inline_mark,nofsaved))) -- or use a normal node + local n = new_usernode(inline_mark,nofsaved) + setattrlist(n,true) + context(tonode(n)) -- or use a normal node store[nofsaved] = t -- no insert nofinlined = nofinlined + 1 else @@ -448,8 +450,9 @@ end -- anchors are only set for lines that have a note -local function sa(tag) -- maybe l/r keys ipv left/right keys - local p = cache[tag] +local function sa(specification) -- maybe l/r keys ipv left/right keys + local tag = specification.tag + local p = cache[tag] if p then if trace_marginstack then report_margindata("updating anchor %a",tag) @@ -462,11 +465,13 @@ local function sa(tag) -- maybe l/r keys ipv left/right keys end local function setanchor(v_anchor) -- freezes the global here - return lateluafunction(function() sa(v_anchor) end) + return latelua { action = sa, tag = v_anchor } end -local function aa(tag,n) -- maybe l/r keys ipv left/right keys - local p = jobpositions.gettobesaved('md:v',tag) +local function aa(specification) -- maybe l/r keys ipv left/right keys + local tag = specification.tag + local n = specification.n + local p = jobpositions.gettobesaved('md:v',tag) if p then if trace_marginstack then report_margindata("updating injected %a",tag) @@ -483,7 +488,7 @@ local function aa(tag,n) -- maybe l/r keys ipv left/right keys end local function addtoanchor(v_anchor,n) -- freezes the global here - return lateluafunction(function() aa(v_anchor,n) end) + return latelua { action = aa, tag = v_anchor, n = n } end local function markovershoot(current) -- todo: alleen als offset > line @@ -717,8 +722,8 @@ local function flushinline(parent,head) while current and nofinlined > 0 do local id = getid(current) if id == whatsit_code then - if getsubtype(current) == userdefined_code and getfield(current,"user_id") == inline_mark then - local n = getfield(current,"value") + if getsubtype(current) == userdefined_code and getprop(current,"id") == inline_mark then + local n = getprop(current,"data") local candidate = inlinestore[n] if candidate then -- no vpack, as we want to realign inlinestore[n] = nil @@ -812,9 +817,8 @@ local function handler(scope,head,group) if trace_margindata then report_margindata("flushing stage one, stored %s, scope %s, delayed %s, group %a",nofstored,scope,nofdelayed,group) end - head = tonut(head) local current = head - local done = false + local done = false -- for tracing only while current do local id = getid(current) if (id == vlist_code or id == hlist_code) and getprop(current,"margindata") == nil then @@ -839,11 +843,9 @@ local function handler(scope,head,group) report_margindata("flushing stage one, nothing done, %s left",nofstored) end end -resetstacked() - return tonode(head), done - else - return head, false + resetstacked() end + return head end local trialtypesetting = context.trialtypesetting @@ -854,7 +856,7 @@ local trialtypesetting = context.trialtypesetting function margins.localhandler(head,group) -- sometimes group is "" which is weird if trialtypesetting() then - return head, false + return head end local inhibit = conditionals.inhibitmargindata @@ -862,15 +864,15 @@ function margins.localhandler(head,group) -- sometimes group is "" which is weir if trace_margingroup then report_margindata("ignored 3, group %a, stored %s, inhibit %a",group,nofstored,inhibit) end - return head, false - elseif nofstored > 0 then + return head + end + if nofstored > 0 then return handler(v_local,head,group) - else - if trace_margingroup then - report_margindata("ignored 4, group %a, stored %s, inhibit %a",group,nofstored,inhibit) - end - return head, false end + if trace_margingroup then + report_margindata("ignored 4, group %a, stored %s, inhibit %a",group,nofstored,inhibit) + end + return head end function margins.globalhandler(head,group) -- check group @@ -884,7 +886,7 @@ function margins.globalhandler(head,group) -- check group if trace_margingroup then report_margindata("ignored 1, group %a, stored %s, inhibit %a",group,nofstored,inhibit) end - return head, false + return head elseif group == "hmode_par" then return handler(v_global,head,group) elseif group == "vmode_par" then -- experiment (for alignments) @@ -899,22 +901,20 @@ function margins.globalhandler(head,group) -- check group if trace_margingroup then report_margindata("ignored 2, group %a, stored %s, inhibit %a",group,nofstored,inhibit) end - return head, false + return head end end local function finalhandler(head) if nofdelayed > 0 then local current = head - local done = false - while current and nofdelayed > 0 do + while current and nofdelayed > 0 do -- traverse_list local id = getid(current) if id == hlist_code then -- only lines? local a = getprop(current,"margindata") if not a then finalhandler(getlist(current)) elseif realigned(current,a) then - done = true if nofdelayed == 0 then return head, true end @@ -924,10 +924,8 @@ local function finalhandler(head) end current = getnext(current) end - return head, done - else - return head, false end + return head end function margins.finalhandler(head) @@ -935,16 +933,12 @@ function margins.finalhandler(head) if trace_margindata then report_margindata("flushing stage two, instore: %s, delayed: %s",nofstored,nofdelayed) end - head = tonut(head) - local head, done = finalhandler(head) --- resetstacked(true) -resetstacked(nofdelayed==0) - head = tonode(head) - return head, done + head = finalhandler(head) + resetstacked(nofdelayed==0) else resetstacked() - return head, false end + return head end -- Somehow the vbox builder (in combinations) gets pretty confused and decides to @@ -996,6 +990,7 @@ interfaces.implement { { "align" }, { "option" }, { "line", "integer" }, + { "index", "integer" }, { "stackname" }, { "stack" }, } diff --git a/tex/context/base/mkiv/typo-mar.mkiv b/tex/context/base/mkiv/typo-mar.mkiv index f265f173c..921f1f230 100644 --- a/tex/context/base/mkiv/typo-mar.mkiv +++ b/tex/context/base/mkiv/typo-mar.mkiv @@ -155,6 +155,7 @@ \forgetall \tf \resetallattributes % \deactivatecolor % needed, but maybe we should switch to maintextcolor: \onlyinheritmaintextcolor + \pickupattributes \to \everymargindatacontent % trialtypesetting: no need for margin stuff while trialing as @@ -200,11 +201,17 @@ \let\margindatahbox\naturalhbox % \hbox +\newcount\c_typo_margins_n + +\ifdefined\dotagmarginanchor \else \let\dotagmarginanchor\gobbleoneargument \fi +\ifdefined\dotagmargintext \else \let\dotagmargintext \gobbleoneargument \fi + \unexpanded\def\typo_margins_data_yes_indeed[#dataparameters][#textparameters]#content% {\iffirstargument \setupcurrentmargindata[#dataparameters]% \fi \doifelsenothing{#content}\donefalse\donetrue + \global\advance\c_typo_margins_n\plusone \ifdone \edef\currentmarginreference{\margindataparameter\c!reference}% \ifx\currentmarginreference\empty \else @@ -212,6 +219,7 @@ \fi \edef\currentmargindatastrut{\margindataparameter\c!strut}% \dostarttaggedchained\t!margintext\currentmargindata\??margindata + \dotagmargintext\c_typo_margins_n \ifcsname\currentmarginframedhash\s!parent\endcsname \setbox\nextbox\margindatahbox \currentmarginreference \bgroup \the\everymargindatacontent @@ -271,6 +279,8 @@ \ifdone \edef\p_anchor{\margindataparameter\c!anchor}% \anch_positions_initialize % we use positions at the lua end + \dostarttagged\t!marginanchor\empty + \dotagmarginanchor\c_typo_margins_n \clf_savemargindata location {\margindataparameter\c!location}% method {\margindataparameter\c!method}% @@ -306,7 +316,9 @@ line \numexpr\margindataparameter\c!line\relax stackname {\margindataparameter\c!stackname}% stack {\margindataparameter\c!stack}% + index \c_typo_margins_n \relax + \dostoptagged \else \clf_savemargindata location {\margindataparameter\c!location}% diff --git a/tex/context/base/mkiv/typo-pag.lua b/tex/context/base/mkiv/typo-pag.lua index b5759a097..05513e20c 100644 --- a/tex/context/base/mkiv/typo-pag.lua +++ b/tex/context/base/mkiv/typo-pag.lua @@ -26,7 +26,6 @@ local unsetvalue = attributes.unsetvalue local a_keeptogether = attributes.private("keeptogether") local nuts = nodes.nuts -local tonut = nuts.tonut local getnext = nuts.getnext local getprev = nuts.getprev @@ -187,8 +186,8 @@ end -- also look at first non glue/kern node e.g for a dropped caps function parbuilders.keeptogether(head) - local done = false - local current = tonut(head) + local done = false + local current = head while current do if getid(current) == hlist_code then local a = takeattr(current,a_keeptogether) diff --git a/tex/context/base/mkiv/typo-par.mkiv b/tex/context/base/mkiv/typo-par.mkiv index 3db0ffa45..066dc6a69 100644 --- a/tex/context/base/mkiv/typo-par.mkiv +++ b/tex/context/base/mkiv/typo-par.mkiv @@ -23,7 +23,7 @@ \unprotect -\registerctxluafile{node-ltp}{} +\registerctxluafile{node-ltp}{optimize} \registerctxluafile{trac-par}{} \protect \endinput diff --git a/tex/context/base/mkiv/typo-pnc.lua b/tex/context/base/mkiv/typo-pnc.lua index 1ed8d9940..732970884 100644 --- a/tex/context/base/mkiv/typo-pnc.lua +++ b/tex/context/base/mkiv/typo-pnc.lua @@ -9,7 +9,6 @@ if not modules then modules = { } end modules ['typo-pnc'] = { local nodes = nodes local fonts = fonts -local prependaction = nodes.tasks.prependaction local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts @@ -23,7 +22,8 @@ local spaceskip_code = gluecodes.spaceskip local new_kern = nuts.pool.kern local insert_after = nuts.insert_after -local traverse_id = nuts.traverse_id + +local nextglyph = nuts.traversers.glyph local getchar = nuts.getchar local getfont = nuts.getfont @@ -68,10 +68,8 @@ local mapping = periodkerns.mapping local factors = periodkerns.factors function periodkerns.handler(head) - local done = false - local hnut = tonut(head) - for current in traverse_id(glyph_code,tonut(hnut)) do - if getchar(current) == period then + for current, char, font in nextglyph, head do + if char == period then local a = getattr(current,a_periodkern) if a then local factor = mapping[a] @@ -79,10 +77,10 @@ function periodkerns.handler(head) local prev, next = getboth(current) if prev and next and getid(prev) == glyph_code and getid(next) == glyph_code then local pchar = getchar(prev) - local pcode = categories[getchar(prev)] + local pcode = categories[pchar] if pcode == "lu" or pcode == "ll" then local nchar = getchar(next) - local ncode = categories[getchar(next)] + local ncode = categories[nchar] if ncode == "lu" or ncode == "ll" then local next2 = getnext(next) if next2 and getid(next2) == glyph_code and getchar(next2) == period then @@ -91,11 +89,10 @@ function periodkerns.handler(head) if factor ~= 0 then fontspace = parameters[getfont(current)].space -- can be sped up inserted = factor * fontspace - insert_after(hnut,current,new_kern(inserted)) + insert_after(head,current,new_kern(inserted)) if trace then report("inserting space at %C . [%p] %C .",pchar,inserted,nchar) end - done = true end local next3 = getnext(next2) if next3 and getid(next3) == glue_code and getsubtype(next3) == spaceskip_code then @@ -115,7 +112,6 @@ function periodkerns.handler(head) end end setwidth(next3,space) - done = true else if trace then if inserted then @@ -136,7 +132,7 @@ function periodkerns.handler(head) end end end - return head, done + return head end local enabled = false @@ -144,7 +140,6 @@ local enabled = false function periodkerns.set(factor) factor = tonumber(factor) or 0 if not enabled then - prependaction("processors","normalizers","typesetters.periodkerns.handler") enableaction("processors","typesetters.periodkerns.handler") enabled = true end diff --git a/tex/context/base/mkiv/typo-rep.lua b/tex/context/base/mkiv/typo-rep.lua index b6aae0cae..d29eb17b8 100644 --- a/tex/context/base/mkiv/typo-rep.lua +++ b/tex/context/base/mkiv/typo-rep.lua @@ -21,8 +21,6 @@ local nodes = nodes local enableaction = nodes.tasks.enableaction local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getchar = nuts.getchar @@ -81,9 +79,8 @@ local function process(what,head,current,char) return head, current end -function nodes.handlers.stripping(head) - head = tonut(head) - local current, done = head, false +function nodes.handlers.stripping(head) -- use loop + local current = head while current do local char, id = isglyph(current) if char then @@ -93,7 +90,6 @@ function nodes.handlers.stripping(head) local what = glyphs[char] if what then head, current = process(what,head,current,char) - done = true else -- handling of spacing etc has to be done elsewhere current = getnext(current) end @@ -104,7 +100,7 @@ function nodes.handlers.stripping(head) current = getnext(current) end end - return tonode(head), done + return head end local enabled = false diff --git a/tex/context/base/mkiv/typo-rub.lua b/tex/context/base/mkiv/typo-rub.lua index 8c41a5611..da63d7b64 100644 --- a/tex/context/base/mkiv/typo-rub.lua +++ b/tex/context/base/mkiv/typo-rub.lua @@ -33,8 +33,6 @@ local v_auto = variables.auto local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode local getid = nuts.getid local getsubtype = nuts.getsubtype local getattr = nuts.getattr @@ -53,7 +51,9 @@ local setwidth = nuts.setwidth local hpack = nuts.hpack local insert_after = nuts.insert_after local takebox = nuts.takebox -local traverse_id = nuts.traverse_id + +local nexthlist = nuts.traversers.hlist +local nextvlist = nuts.traversers.vlist local nodecodes = nodes.nodecodes local glyph_code = nodecodes.glyph @@ -63,14 +63,11 @@ local glue_code = nodecodes.glue local penalty_code = nodecodes.penalty local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist -local whatsit_code = nodecodes.whatsit local localpar_code = nodecodes.localpar - -local whatsitcodes = nodes.whatsitcodes ------ late_luacode = whatsitcodes.latelua +local dir_code = nodecodes.dir local kerncodes = nodes.kerncodes -local font_code = kerncodes.font +local fontkern_code = kerncodes.font local nodepool = nuts.pool local new_kern = nodepool.kern @@ -194,7 +191,6 @@ do end function rubies.check(head) - local head = tonut(head) local current = head local start = nil local stop = nil @@ -208,7 +204,7 @@ function rubies.check(head) setprev(start) setnext(stop) local h = hpack(start) - if prev == head then + if start == head then head = h else setlink(prev,h) @@ -247,20 +243,21 @@ function rubies.check(head) start = current stop = current end - elseif id == kern_code and getsubtype(current,font_code) then + -- go on + elseif id == kern_code and getsubtype(current,fontkern_code) then -- go on elseif found and id == disc_code then -- go on (todo: look into disc) elseif found then - flush("flush 4") + flush("flush 3") found = nil end current = nx end if found then - flush("flush 5") + flush("flush 4") end - return tonode(head), true + return head, true -- no need for true end local attach @@ -309,11 +306,11 @@ local function whatever(current) local c = getprev(current) while c do local id = getid(c) - if id == glue_code or id == penalty_code or id == kern_code or (id == whatsit_code and getsubtype(current,localpar_code)) then + if id == glue_code or id == penalty_code or id == kern_code then -- go on elseif id == hlist_code and getwidth(c) == 0 then -- go on - elseif id == whatsit_code or id == localpar_code then + elseif id == whatsit_code or id == localpar_code or id == dir_code then -- go on else l = false @@ -371,20 +368,17 @@ local function whatever(current) end end -attach = function(head) - for current in traverse_id(hlist_code,head) do +attach = function(head) -- traverse_list + for current in nexthlist, head do whatever(current) end - for current in traverse_id(vlist_code,head) do + for current in nextvlist, head do whatever(current) end - return head, true + return head end -function rubies.attach(head) - local h, d = attach(tonut(head)) - return tonode(h), d -end +rubies.attach = attach -- for now there is no need to be compact diff --git a/tex/context/base/mkiv/typo-rub.mkiv b/tex/context/base/mkiv/typo-rub.mkiv index d51c53aa4..cc1571ad7 100644 --- a/tex/context/base/mkiv/typo-rub.mkiv +++ b/tex/context/base/mkiv/typo-rub.mkiv @@ -26,6 +26,7 @@ \installcorenamespace {ruby} \installcorenamespace {rubyanalyze} \installcorenamespace {rubyplacement} +\installcorenamespace {rubynumber} \installcommandhandler \??ruby {ruby} \??ruby @@ -135,6 +136,14 @@ \c!hoffset=\zeropoint, \c!voffset=-2\exheight] +%D Experiment too: + +\unexpanded\def\numberedruby[#1]#2% + {\doifnotcounter{\??rubynumber#1}{\definecounter[\??rubynumber#1]\setcounter[\??rubynumber#1][1]}% + \ruby[#1]{#2}{\convertedcounter[\??rubynumber#1]}% + \incrementcounter[\??rubynumber#1]% + \relax} + \protect \endinput % \usemodule[art-01]\setupbodyfont[dejavu,12pt] diff --git a/tex/context/base/mkiv/typo-scr.mkiv b/tex/context/base/mkiv/typo-scr.mkiv index d4881b80a..0dfd111ae 100644 --- a/tex/context/base/mkiv/typo-scr.mkiv +++ b/tex/context/base/mkiv/typo-scr.mkiv @@ -142,8 +142,8 @@ \unexpanded\def\typo_scripts_lowhigh_indeed[#1]#2#3% todo: align .. [#1] is compatible hack {\dostarttagged\t!subsup\currentlowhigh - \setbox\plusfour\hbox{\typo_scripts_lowhigh_low_high\lower\c!down\t!sub{#2}}% - \setbox\plussix \hbox{\typo_scripts_lowhigh_low_high\raise\c!up \t!sup{#3}}% + \setbox\plusfour\hpack{\typo_scripts_lowhigh_low_high\lower\c!down\t!sub{#2}}% + \setbox\plussix \hpack{\typo_scripts_lowhigh_low_high\raise\c!up \t!sup{#3}}% \doif{#1}{\v!left} {\ifdim\wd\plusfour<\wd\plussix \setbox\plusfour\hpack to \wd\plussix {\hss\box\plusfour}% @@ -166,7 +166,7 @@ {\dontleavehmode \begingroup \kern\lowhighparameter\c!distance\relax - \setbox\scratchbox\hbox\bgroup + \setbox\scratchbox\hpack\bgroup #1\lowhighparameter#2\hbox\bgroup \ifx\fontsize\empty \ifmmode diff --git a/tex/context/base/mkiv/typo-spa.lua b/tex/context/base/mkiv/typo-spa.lua index bda139719..78fc22964 100644 --- a/tex/context/base/mkiv/typo-spa.lua +++ b/tex/context/base/mkiv/typo-spa.lua @@ -23,12 +23,9 @@ local unsetvalue = attributes.unsetvalue local v_reset = interfaces.variables.reset local nuts = nodes.nuts -local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev -local getfont = nuts.getfont local takeattr = nuts.takeattr local isglyph = nuts.isglyph @@ -73,8 +70,6 @@ end -- todo cache lastattr function spacings.handler(head) - head = tonut(head) - local done = false local start = head -- head is always begin of par (whatsit), so we have at least two prev nodes -- penalty followed by glue @@ -87,10 +82,11 @@ function spacings.handler(head) if data then local map = data.characters[char] if map then + local font = id local left = map.left local right = map.right local alternative = map.alternative - local quad = quaddata[getfont(start)] + local quad = quaddata[font] local prev = getprev(start) if left and left ~= 0 and prev then local ok = false @@ -122,7 +118,6 @@ function spacings.handler(head) end insert_node_before(head,start,new_penalty(10000)) insert_node_before(head,start,new_glue(left*quad)) - done = true end end local next = getnext(start) @@ -159,7 +154,6 @@ function spacings.handler(head) end insert_node_after(head,start,new_glue(right*quad)) insert_node_after(head,start,new_penalty(10000)) - done = true end end end @@ -172,7 +166,7 @@ function spacings.handler(head) start = getnext(start) end end - return tonode(head), done + return head end local enabled = false diff --git a/tex/context/base/mkiv/typo-sus.lua b/tex/context/base/mkiv/typo-sus.lua index 2d3037bdc..6c02b9291 100644 --- a/tex/context/base/mkiv/typo-sus.lua +++ b/tex/context/base/mkiv/typo-sus.lua @@ -40,8 +40,6 @@ local hlist_code = nodecodes.hlist local vlist_code = nodecodes.vlist local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode local getid = nuts.getid local getprev = nuts.getprev @@ -164,7 +162,6 @@ local colors = { local found = 0 function typesetters.marksuspects(head) - local head = tonut(head) local current = head local lastdone = nil while current do @@ -254,7 +251,7 @@ function typesetters.marksuspects(head) current = getnext(current) end end - return tonode(head), found > 0 + return head end local function showsuspects(head) @@ -289,9 +286,9 @@ end function typesetters.showsuspects(head) if found > 0 then - return tonode(showsuspects(tonut(head))), true + return showsuspects(head) else - return head, false + return head end end diff --git a/tex/context/base/mkiv/typo-tal.lua b/tex/context/base/mkiv/typo-tal.lua index 870d006cc..8cf298329 100644 --- a/tex/context/base/mkiv/typo-tal.lua +++ b/tex/context/base/mkiv/typo-tal.lua @@ -34,7 +34,6 @@ local v_number = variables.number local nuts = nodes.nuts local tonut = nuts.tonut -local tonode = nuts.tonode local getnext = nuts.getnext local getprev = nuts.getprev @@ -50,8 +49,8 @@ local setchar = nuts.setchar local insert_node_before = nuts.insert_before local insert_node_after = nuts.insert_after -local traverse_list_by_id = nuts.traverse_id -local list_dimensions = nuts.dimensions +local nextglyph = nuts.traversers.glyph +local getdimensions = nuts.dimensions local first_glyph = nuts.first_glyph local setglue = nuts.setglue @@ -171,23 +170,22 @@ local function traced_kern(w) return tracedrule(w,nil,nil,"darkgray") end -function characteralign.handler(originalhead,where) +function characteralign.handler(head,where) if not datasets then - return originalhead, false + return head end - local head = tonut(originalhead) -- local first = first_glyph(head) -- we could do that once local first - for n in traverse_list_by_id(glyph_code,head) do + for n in nextglyph, head do first = n break end if not first then - return originalhead, false + return head end local a = getattr(first,a_characteralign) if not a or a == 0 then - return originalhead, false + return head end local column = div(a,0xFFFF) local row = a % 0xFFFF @@ -210,7 +208,7 @@ function characteralign.handler(originalhead,where) while current do local char, id = isglyph(current) if char then - local font = getfont(current) + local font = id --- nicer local data = fontcharacters[font][char] local unicode = data and data.unicode or char -- ignore tables if not unicode then -- type(unicode) ~= "number" @@ -234,8 +232,9 @@ function characteralign.handler(originalhead,where) if not b_start then if sign then b_start = sign - local new = validsigns[getchar(sign)] - if char == new or not fontcharacters[getfont(sign)][new] then + local c, f = isglyph(sign) + local new = validsigns[c] + if char == new or not fontcharacters[f][new] then if trace_split then setcolor(sign,"darkyellow") end @@ -285,7 +284,7 @@ function characteralign.handler(originalhead,where) while current do local char, id = isglyph(current) if char then - local font = getfont(current) + local font = id -- nicer -- local unicode = unicodes[font][char] local unicode = fontcharacters[font][char].unicode or char -- ignore tables if not unicode then @@ -322,21 +321,21 @@ function characteralign.handler(originalhead,where) local predefined = dataset.predefined local before, after if predefined then - before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0 - after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0 + before = b_start and getdimensions(b_start,getnext(b_stop)) or 0 + after = a_start and getdimensions(a_start,getnext(a_stop)) or 0 else local entry = list[row] if entry then before = entry.before or 0 after = entry.after or 0 else - before = b_start and list_dimensions(b_start,getnext(b_stop)) or 0 - after = a_start and list_dimensions(a_start,getnext(a_stop)) or 0 + before = b_start and getdimensions(b_start,getnext(b_stop)) or 0 + after = a_start and getdimensions(a_start,getnext(a_stop)) or 0 list[row] = { before = before, after = after, } - return tonode(head), true + return head, true end if not dataset.collected then -- print("[maxbefore] [maxafter]") @@ -404,5 +403,5 @@ function characteralign.handler(originalhead,where) insert_node_after(head,c,new_kern(maxafter)) end end - return tonode(head), true + return head end diff --git a/tex/context/base/mkiv/typo-wrp.lua b/tex/context/base/mkiv/typo-wrp.lua index 07e34cd6c..9fb544152 100644 --- a/tex/context/base/mkiv/typo-wrp.lua +++ b/tex/context/base/mkiv/typo-wrp.lua @@ -8,65 +8,80 @@ if not modules then modules = { } end modules ['typo-wrp'] = { -- begin/end par wrapping stuff ... more to come -local nodecodes = nodes.nodecodes +local nodecodes = nodes.nodecodes +local gluecodes = nodes.gluecodes +local penaltycodes = nodes.penaltycodes +local boundarycodes = nodes.boundarycodes -local glue_code = nodecodes.glue -local penalty_code = nodecodes.penalty -local parfill_skip_code = nodes.gluecodes.parfillskip -local user_penalty_code = nodes.penaltycodes.userpenalty +local glue_code = nodecodes.glue +local penalty_code = nodecodes.penalty +local boundary_code = nodecodes.boundary -local nuts = nodes.nuts -local tonut = nodes.tonut -local tonode = nodes.tonode +local parfillskip_code = gluecodes.parfillskip -local find_node_tail = nuts.tail -local getprev = nuts.getprev -local getid = nuts.getid -local getsubtype = nuts.getsubtype -local getpenalty = nuts.getpenalty -local remove = nuts.remove +local userpenalty_code = penaltycodes.userpenalty +local linepenalty_code = penaltycodes.linepenalty +local linebreakpenalty_code = penaltycodes.linebreakpenalty -local enableaction = nodes.tasks.enableaction +local wordboundary_code = boundarycodes.word -local wrappers = { } -typesetters.wrappers = wrappers +local nuts = nodes.nuts -local trace_wrappers = trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end) +local find_node_tail = nuts.tail +local getprev = nuts.getprev +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getpenalty = nuts.getpenalty +local remove = nuts.remove -local report = logs.reporter("paragraphs","wrappers") +local enableaction = nodes.tasks.enableaction + +local wrappers = { } +typesetters.wrappers = wrappers + +local trace_wrappers = trackers.register("typesetters.wrappers",function(v) trace_wrappers = v end) + +local report = logs.reporter("paragraphs","wrappers") -- we really need to pass tail too ... but then we need to check all the plugins -- bah ... slowdown +-- This check is very tight to the crlf definition. We check for: +-- +-- [break -10000] [wordboundary] [line(break)penalty] [parfillskip] +-- +-- If needed we can extend this checker for other cases but then we will also +-- use attributes. + local function remove_dangling_crlf(head,tail) - if tail and getid(tail) == glue_code and getsubtype(tail) == parfill_skip_code then + if head and tail and getid(tail) == glue_code and getsubtype(tail) == parfillskip_code then tail = getprev(tail) - if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getpenalty(tail) == 10000 then - tail = getprev(tail) - if tail and getid(tail) == penalty_code and getsubtype(tail) == user_penalty_code and getpenalty(tail) == -10000 then - if tail == head then - -- can't happen - else - if trace_wrappers then - report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno) + if tail and getid(tail) == penalty_code then + local subtype = getsubtype(tail) + if subtype == linepenalty_code or subtype == linebreakpenalty_code then + tail = getprev(tail) + if tail and getid(tail) == boundary_code and getsubtype(tail) == wordboundary_code then + tail = getprev(tail) + if tail ~= head and getid(tail) == penalty_code and getsubtype(tail) == userpenalty_code and getpenalty(tail) == -10000 then + if trace_wrappers then + report("removing a probably unwanted end-of-par break in line %s (guess)",tex.inputlineno) + end + remove(head,tail,true) + return head, tail end - remove(head,tail,true) - return head, tail, true end end end end - return head, tail, false + return head, tail end function wrappers.handler(head) - local head = tonut(head) if head then local tail = find_node_tail(head) - local done = false - head, tail, done = remove_dangling_crlf(head,tail) -- will be action chain + head, tail = remove_dangling_crlf(head,tail) -- will be action chain end - return head, true + return head end interfaces.implement { diff --git a/tex/context/base/mkiv/typo-wrp.mkiv b/tex/context/base/mkiv/typo-wrp.mkiv index 0e010515b..4e9ecf2e1 100644 --- a/tex/context/base/mkiv/typo-wrp.mkiv +++ b/tex/context/base/mkiv/typo-wrp.mkiv @@ -40,18 +40,21 @@ \unexpanded\def\spac_crlf {\clf_enablecrlf % once \unskip - \prewordbreak % here or in \spac_crlf_placeholder \spac_crlf_placeholder \ifcase\raggedstatus\hfil\or\or\or\hfil\fi + % in bad usage this can lead to: [break -10000] [wordboundary] [line(break)penalty] [parfillskip] \break - \hskip\zeropoint % new so that the next word also hyphenates + \wordboundary + % which we then remove (maybe we should flag the wordboundary with an attribute but not now \ignorespaces} \unexpanded\def\spac_crlf_placeholder {\strut} \unexpanded\def\spac_crlf_placeholder_show - {\hbox to \zeropoint{\strut{\infofont\kern.25\emwidth}\lohi{\infofont CR}{\infofont LF}\hss}} + {\wordboundary + %\nobreak + \hpack to \zeropoint{\strut{\infofont\kern.25\emwidth}\lohi{\infofont CR}{\infofont LF}\hss}} \unexpanded\def\settestcrlf {\let\spac_crlf_placeholder\spac_crlf_placeholder_show} diff --git a/tex/context/base/mkiv/util-deb.lua b/tex/context/base/mkiv/util-deb.lua index b8db0c583..6932e8804 100644 --- a/tex/context/base/mkiv/util-deb.lua +++ b/tex/context/base/mkiv/util-deb.lua @@ -10,9 +10,6 @@ if not modules then modules = { } end modules ['util-deb'] = { -- bound to a variable, like node.new, node.copy etc (contrary to for instance -- node.has_attribute which is bound to a has_attribute local variable in mkiv) -local debug = require "debug" - -local getinfo, sethook = debug.getinfo, debug.sethook local type, next, tostring, tonumber = type, next, tostring, tonumber local format, find, sub, gsub = string.format, string.find, string.sub, string.gsub local insert, remove, sort = table.insert, table.remove, table.sort @@ -98,7 +95,7 @@ end setmetatableindex(names,function(t,name) local v = setmetatableindex(function(t,source) local v = setmetatableindex(function(t,line) - local v = { total = 0, count = 0 } + local v = { total = 0, count = 0, nesting = 0 } t[line] = v return v end) @@ -109,6 +106,9 @@ setmetatableindex(names,function(t,name) return v end) +local getinfo = nil +local sethook = nil + local function hook(where) local f = getinfo(2,"nSl") if f then @@ -128,12 +128,24 @@ local function hook(where) end local data = names[name][source][line] if where == "call" then - data.count = data.count + 1 - insert(data,ticks()) + local nesting = data.nesting + if nesting == 0 then + data.count = data.count + 1 + insert(data,ticks()) + data.nesting = 1 + else + data.nesting = nesting + 1 + end elseif where == "return" then - local t = remove(data) - if t then - data.total = data.total + ticks() - t + local nesting = data.nesting + if nesting == 1 then + local t = remove(data) + if t then + data.total = data.total + ticks() - t + end + data.nesting = 0 + else + data.nesting = nesting - 1 end end end @@ -228,6 +240,27 @@ function debugger.showstats(printer,threshold) -- table.save("luatex-profile.lua",names) end +local function getdebug() + if sethook and getinfo then + return + end + if not debug then + local okay + okay, debug = pcall(require,"debug") + end + if type(debug) ~= "table" then + return + end + getinfo = debug.getinfo + sethook = debug.sethook + if type(getinfo) ~= "function" then + getinfo = nil + end + if type(sethook) ~= "function" then + sethook = nil + end +end + function debugger.savestats(filename,threshold) local f = io.open(filename,'w') if f then @@ -237,7 +270,8 @@ function debugger.savestats(filename,threshold) end function debugger.enable() - if nesting == 0 then + getdebug() + if sethook and getinfo and nesting == 0 then running = true if initialize then initialize() @@ -259,7 +293,7 @@ function debugger.disable() if nesting > 0 then nesting = nesting - 1 end - if nesting == 0 then + if sethook and getinfo and nesting == 0 then sethook() end end @@ -282,20 +316,25 @@ end -- from the lua book: local function showtraceback(rep) -- from lua site / adapted - local level = 2 -- we don't want this function to be reported - local reporter = rep or report - while true do - local info = getinfo(level, "Sl") - if not info then - break - elseif info.what == "C" then - reporter("%2i : %s",level-1,"C function") - else - reporter("%2i : %s : %s",level-1,info.short_src,info.currentline) + getdebug() + if getinfo then + local level = 2 -- we don't want this function to be reported + local reporter = rep or report + while true do + local info = getinfo(level, "Sl") + if not info then + break + elseif info.what == "C" then + reporter("%2i : %s",level-1,"C function") + else + reporter("%2i : %s : %s",level-1,info.short_src,info.currentline) + end + level = level + 1 end - level = level + 1 end end debugger.showtraceback = showtraceback -- debug.showtraceback = showtraceback + +-- showtraceback() diff --git a/tex/context/base/mkiv/util-env.lua b/tex/context/base/mkiv/util-env.lua index 064bd513a..dde765874 100644 --- a/tex/context/base/mkiv/util-env.lua +++ b/tex/context/base/mkiv/util-env.lua @@ -72,20 +72,16 @@ end -- dirty tricks (we will replace the texlua call by luatex --luaonly) local validengines = allocate { - ["luatex"] = true, - ["luajittex"] = true, - -- ["luatex.exe"] = true, - -- ["luajittex.exe"] = true, + ["luatex"] = true, + ["luajittex"] = true, } local basicengines = allocate { - ["luatex"] = "luatex", - ["texlua"] = "luatex", - ["texluac"] = "luatex", - ["luajittex"] = "luajittex", - ["texluajit"] = "luajittex", - -- ["texlua.exe"] = "luatex", - -- ["texluajit.exe"] = "luajittex", + ["luatex"] = "luatex", + ["texlua"] = "luatex", -- obsolete + ["texluac"] = "luatex", -- obsolete + ["luajittex"] = "luajittex", + ["texluajit"] = "luajittex", -- obsolete } local luaengines = allocate { @@ -154,8 +150,11 @@ environment.sortedflags = nil -- 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 + local arguments = { } + local files = { } + environment.arguments = arguments + environment.files = files + environment.sortedflags = nil for index=1,#arg do local argument = arg[index] if index > 0 then @@ -174,6 +173,11 @@ function environment.initializearguments(arg) end end end + if not environment.ownname then + if os.selfpath and os.selfname then + environment.ownname = file.addsuffix(file.join(os.selfpath,os.selfname),"lua") + end + end environment.ownname = file.reslash(environment.ownname or arg[0] or 'unknown.lua') end @@ -281,13 +285,20 @@ if arg then for index=1,#arg do local argument = arg[index] if find(argument,"^\"") then - newarg[#newarg+1] = gsub(argument,"^\"","") - if not find(argument,"\"$") then + if find(argument,"\"$") then + newarg[#newarg+1] = gsub(argument,"^\"(.-)\"$","%1") + instring = false + else + newarg[#newarg+1] = gsub(argument,"^\"","") instring = true end elseif find(argument,"\"$") then - newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") - instring = false + if instring then + newarg[#newarg] = newarg[#newarg] .. " " .. gsub(argument,"\"$","") + instring = false + else + newarg[#newarg+1] = argument + end elseif instring then newarg[#newarg] = newarg[#newarg] .. " " .. argument else diff --git a/tex/context/base/mkiv/util-evo.lua b/tex/context/base/mkiv/util-evo.lua index 7f0b59ac4..dfb395e08 100644 --- a/tex/context/base/mkiv/util-evo.lua +++ b/tex/context/base/mkiv/util-evo.lua @@ -161,15 +161,22 @@ local function loadedtable(filename) for i=1,10 do local t = loadtable(filename) if t then + report("file %a loaded",filename) return t else ossleep(1/4) end end end + report("file %a not loaded",filename) return { } end +local function savedtable(filename,data) + savetable(filename,data) + report("file %a saved",filename) +end + local function loadpresets(filename) local presets = loadtable(filename) if presets then @@ -194,6 +201,13 @@ local function loadeverything(filename) return loadedtable(filename) end +local function loadlatest(filename) + if type(filename) == "table" and validpresets(filename) then + filename = filename.files and filename.files.latest + end + return loadedtable(filename) +end + local function result(t,fmt,a,b,c) if t then report(fmt,a or "done",b or "done",c or "done","done") @@ -365,6 +379,21 @@ local function findzone(presets,name) return usedzones and usedzones[name] end +local function getzonenames(presets) + if not presets then + return { } + end + local data = presets.data + if not data then + return { } + end + local t = sortedkeys(data.zones or { }) + for i=1,#t do + t[i] = lower(t[i]) + end + return t +end + local function gettargets(zone) -- maybe also for a day local schedule = zone.schedule local min = false @@ -503,7 +532,7 @@ local function geteverything(presets,noschedules) end end end - savetable(presets.files.everything,data) + savedtable(presets.files.everything,data) return result(data,"getting everything, %s") end end @@ -521,26 +550,29 @@ local function gettemperatures(presets) for i=1,#data do local gateways = data[i].gateways local locationinfo = data[i].locationInfo - local locationid = locationinfo.locationId - if gateways then - local status = getstatus(presets,locationid,locationinfo.name) - if status then - for i=1,#gateways do - local g = status.gateways[i] - local gateway = gateways[i] - local systems = gateway.temperatureControlSystems - if systems then - local s = g.temperatureControlSystems - for i=1,#systems do - local zones = systems[i].zones - if zones then - local z = s[i].zones - for i=1,#zones do - if validzonetypes[zone.zoneType] then - local z = z[i] - if z.name == zone.name then - zone.temperatureStatus = z.temperatureStatus - updated = true + if locationinfo then + local locationid = locationinfo.locationId + if gateways then + local status = getstatus(presets,locationid,locationinfo.name) + if status then + for i=1,#gateways do + local g = status.gateways[i] + local gateway = gateways[i] + local systems = gateway.temperatureControlSystems + if systems then + local s = g.temperatureControlSystems + for i=1,#systems do + local zones = systems[i].zones + if zones then + local z = s[i].zones + for i=1,#zones do + local zone = zones[i] + if validzonetypes[zone.zoneType] then + local z = z[i] + if z.name == zone.name then + zone.temperatureStatus = z.temperatureStatus + updated = true + end end end end @@ -548,12 +580,16 @@ local function gettemperatures(presets) end end end + else + report("no gateways") end + else + report("no location info") end end if updated then data.time = ostime() - savetable(presets.files.latest,data) + savedtable(presets.files.latest,data) end return result(data,"getting temperatures, %s") end @@ -601,7 +637,10 @@ end local function loadtemperatures(presets) if validpresets(presets) then - local status = loadeverything(presets) + local status = loadlatest(presets) + if not status or not next(status) then + status = loadeverything(presets) + end if status then local usedgateways = presets.data.gateways for i=1,#status do @@ -637,9 +676,10 @@ end local function updatetemperatures(presets) if validpresets(presets) then local everythingname = presets.files.everything + local latestname = presets.files.latest local historyname = presets.files.history - if everythingname and historyname then - gettemperatures(presets,everythingname) + if (everythingname or latestname) and historyname then + gettemperatures(presets) local t = loadtemperatures(presets) if t then local data = { } @@ -649,7 +689,7 @@ local function updatetemperatures(presets) end local history = loadhistory(historyname) or { } setmoment(history,ostime(),data) - savetable(historyname,history) + savedtable(historyname,history) return result(t,"updating temperatures, %s") end end @@ -747,10 +787,10 @@ local function off(presets,name) end end -local function on(presets,name) +local function on(presets,name,temperature) local zone = presets and getzonestate(presets,name) if zone then - setzonestate(presets,name,zone.highest) + setzonestate(presets,name,temperature or zone.highest) end end @@ -787,7 +827,7 @@ local function settask(presets,when,tag,action) else list[tag] = nil end - savetable(presets.files.schedules,list) + savedtable(presets.files.schedules,list) end end @@ -832,7 +872,7 @@ local function checktasks(presets) for k, v in next, q do list[q] = nil end - savetable(presets.files.schedules,list) + savedtable(presets.files.schedules,list) end return list end @@ -954,10 +994,10 @@ end evohome = { helpers = { - getaccesstoken = getaccesstoken, -- presets - getuserinfo = getuserinfo, -- presets - getlocationinfo = getlocationinfo, -- presets - getschedule = getschedule, -- presets, name + getaccesstoken = getaccesstoken, -- presets + getuserinfo = getuserinfo, -- presets + getlocationinfo = getlocationinfo, -- presets + getschedule = getschedule, -- presets, name -- geteverything = geteverything, -- presets, noschedules gettemperatures = gettemperatures, -- presets @@ -965,6 +1005,7 @@ evohome = { setzonestate = setzonestate, -- presets, name, temperature resetzonestate = resetzonestate, -- presets, name getzonedata = findzone, -- presets, name + getzonenames = getzonenames, -- presets -- loadpresets = loadpresets, -- filename loadhistory = loadhistory, -- presets | filename diff --git a/tex/context/base/mkiv/util-fil.lua b/tex/context/base/mkiv/util-fil.lua index 0e8ed4e57..9f96a01b9 100644 --- a/tex/context/base/mkiv/util-fil.lua +++ b/tex/context/base/mkiv/util-fil.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['util-fil'] = { license = "see context related readme files" } +local tonumber = tonumber local byte = string.byte local char = string.char @@ -196,41 +197,23 @@ function files.readinteger4le(f) end end --- function files.readfixed2(f) --- local a, b = byte(f:read(2),1,2) --- if a >= 0x80 then --- return (0x100 * a + b - 0x10000)/256.0 --- else --- return (0x100 * a + b)/256.0 --- end --- end - function files.readfixed2(f) local a, b = byte(f:read(2),1,2) if a >= 0x80 then - return (a - 0x100) + b/0x100 + tonumber((a - 0x100) .. "." .. b) else - return (a ) + b/0x100 + tonumber(( a ) .. "." .. b) end end --- (real) (n>>16) + ((n&0xffff)/65536.0)) - --- function files.readfixed4(f) --- local a, b, c, d = byte(f:read(4),1,4) --- if a >= 0x80 then --- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d - 0x100000000)/65536.0 --- else --- return (0x1000000 * a + 0x10000 * b + 0x100 * c + d)/65536.0 --- end --- end +-- (real) (n>>16) + ((n&0xffff)/65536.0)) but no cast in lua (we could use unpack) function files.readfixed4(f) local a, b, c, d = byte(f:read(4),1,4) if a >= 0x80 then - return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000 + tonumber((0x100 * a + b - 0x10000) .. "." .. (0x100 * c + d)) else - return (0x100 * a + b ) + (0x100 * c + d)/0x10000 + tonumber((0x100 * a + b ) .. "." .. (0x100 * c + d)) end end @@ -343,3 +326,40 @@ if fio and fio.readcardinal1 then end end + +if fio and fio.readcardinaltable then + + files.readcardinaltable = fio.readcardinaltable + files.readintegertable = fio.readintegertable + +else + + local readcardinal1 = files.readcardinal1 + local readcardinal2 = files.readcardinal2 + local readcardinal3 = files.readcardinal3 + local readcardinal4 = files.readcardinal4 + + function files.readcardinaltable(f,n,b) + local t = { } + if b == 1 then for i=1,n do t[i] = readcardinal1(f) end + elseif b == 2 then for i=1,n do t[i] = readcardinal2(f) end + elseif b == 3 then for i=1,n do t[i] = readcardinal3(f) end + elseif b == 4 then for i=1,n do t[i] = readcardinal4(f) end end + return t + end + + local readinteger1 = files.readinteger1 + local readinteger2 = files.readinteger2 + local readinteger3 = files.readinteger3 + local readinteger4 = files.readinteger4 + + function files.readintegertable(f,n,b) + local t = { } + if b == 1 then for i=1,n do t[i] = readinteger1(f) end + elseif b == 2 then for i=1,n do t[i] = readinteger2(f) end + elseif b == 3 then for i=1,n do t[i] = readinteger3(f) end + elseif b == 4 then for i=1,n do t[i] = readinteger4(f) end end + return t + end + +end diff --git a/tex/context/base/mkiv/util-fmt.lua b/tex/context/base/mkiv/util-fmt.lua index 371a5dfce..fe80c6420 100644 --- a/tex/context/base/mkiv/util-fmt.lua +++ b/tex/context/base/mkiv/util-fmt.lua @@ -35,10 +35,17 @@ function formatters.formatcolumns(result,between) for j=1,n do local rj = r[j] local tj = type(rj) +-- if tj == "number" then +-- numbers[j] = true +-- end +-- if tj ~= "string" then +-- rj = tostring(rj) +-- r[j] = rj +-- end if tj == "number" then numbers[j] = true - end - if tj ~= "string" then + rj = tostring(rj) + elseif tj ~= "string" then rj = tostring(rj) r[j] = rj end diff --git a/tex/context/base/mkiv/util-jsn.lua b/tex/context/base/mkiv/util-jsn.lua index e5f83e06c..acbf16090 100644 --- a/tex/context/base/mkiv/util-jsn.lua +++ b/tex/context/base/mkiv/util-jsn.lua @@ -14,10 +14,12 @@ if not modules then modules = { } end modules ['util-jsn'] = { -- -- Reminder for me: check usage in framework and extend when needed. Also document -- it in the cld lib documentation. +-- +-- Upgraded for handling the somewhat more fax server templates. local P, V, R, S, C, Cc, Cs, Ct, Cf, Cg = lpeg.P, lpeg.V, lpeg.R, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cf, lpeg.Cg local lpegmatch = lpeg.match -local format = string.format +local format, gsub = string.format, string.gsub local utfchar = utf.char local concat = table.concat @@ -26,9 +28,6 @@ local tonumber, tostring, rawset, type, next = tonumber, tostring, rawset, type, local json = utilities.json or { } utilities.json = json --- moduledata = moduledata or { } --- moduledata.json = json - -- \\ \/ \b \f \n \r \t \uHHHH local lbrace = P("{") @@ -43,16 +42,19 @@ local whitespace = lpeg.patterns.whitespace local optionalws = whitespace^0 local escapes = { - -- ["\\"] = "\\", -- lua will escape these - -- ["/"] = "/", -- no need to escape this one - ["b"] = "\010", - ["f"] = "\014", - ["n"] = "\n", - ["r"] = "\r", - ["t"] = "\t", + ["b"] = "\010", + ["f"] = "\014", + ["n"] = "\n", + ["r"] = "\r", + ["t"] = "\t", } -local escape_un = C(P("\\u") / "0x" * S("09","AF","af")) / function(s) return utfchar(tonumber(s)) end +-- todo: also handle larger utf16 + +local escape_un = P("\\u")/"" * (C(R("09","AF","af")^-4) / function(s) + return utfchar(tonumber(s,16)) +end) + local escape_bs = P([[\]]) / "" * (P(1) / escapes) -- if not found then P(1) is returned i.e. the to be escaped char local jstring = dquote * Cs((escape_un + escape_bs + (1-dquote))^0) * dquote @@ -85,7 +87,9 @@ function json.tolua(str) return lpegmatch(jsonconverter,str) end -local function tojson(value,t) -- we could optimize #t +local escaper + +local function tojson(value,t,n) -- we could optimize #t local kind = type(value) if kind == "table" then local done = false @@ -93,60 +97,75 @@ local function tojson(value,t) -- we could optimize #t if size == 0 then for k, v in next, value do if done then - t[#t+1] = "," + n = n + 1 ; t[n] = "," else - t[#t+1] = "{" + n = n + 1 ; t[n] = "{" done = true end - t[#t+1] = format("%q:",k) - tojson(v,t) + n = n + 1 ; t[n] = format("%q:",k) + t, n = tojson(v,t,n) end if done then - t[#t+1] = "}" + n = n + 1 ; t[n] = "}" else - t[#t+1] = "{}" + n = n + 1 ; t[n] = "{}" end elseif size == 1 then -- we can optimize for non tables - t[#t+1] = "[" - tojson(value[1],t) - t[#t+1] = "]" + n = n + 1 ; t[n] = "[" + t, n = tojson(value[1],t,n) + n = n + 1 ; t[n] = "]" else for i=1,size do if done then - t[#t+1] = "," + n = n + 1 ; t[n] = "," else - t[#t+1] = "[" + n = n + 1 ; t[n] = "[" done = true end - tojson(value[i],t) + t, n = tojson(value[i],t,n) end - t[#t+1] = "]" + n = n + 1 ; t[n] = "]" end elseif kind == "string" then - t[#t+1] = format("%q",value) + n = n + 1 ; t[n] = '"' + n = n + 1 ; t[n] = lpegmatch(escaper,value) or value + n = n + 1 ; t[n] = '"' elseif kind == "number" then - t[#t+1] = value + n = n + 1 ; t[n] = value elseif kind == "boolean" then - t[#t+1] = tostring(value) + n = n + 1 ; t[n] = tostring(value) end - return t + return t, n end function json.tostring(value) -- todo optimize for non table local kind = type(value) if kind == "table" then - return concat(tojson(value,{}),"") + if not escaper then + local escapes = { + ["\\"] = "\\u005C", + ["\""] = "\\u0022", + } + for i=0,0x20 do + escapes[utfchar(i)] = format("\\u%04X",i) + end + escaper = Cs( ( + (R('\0\x20') + S('\"\\')) / escapes + + P(1) + )^1 ) + + end + return concat((tojson(value,{},0))) elseif kind == "string" or kind == "number" then - return value + return lpegmatch(escaper,value) or value else return tostring(value) end end --- local tmp = [[ { "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]] - +-- local tmp = [[ { "t" : "foobar", "a" : true, "b" : [ 123 , 456E-10, { "a" : true, "b" : [ 123 , 456 ] } ] } ]] -- tmp = json.tolua(tmp) -- inspect(tmp) -- tmp = json.tostring(tmp) @@ -155,7 +174,6 @@ end -- inspect(tmp) -- tmp = json.tostring(tmp) -- inspect(tmp) - -- inspect(json.tostring(true)) function json.load(filename) @@ -165,4 +183,11 @@ function json.load(filename) end end +-- local s = [[\foo"bar"]] +-- local j = json.tostring { s = s } +-- local l = json.tolua(j) +-- inspect(j) +-- inspect(l) +-- print(s==l.s) + return json diff --git a/tex/context/base/mkiv/util-lib.lua b/tex/context/base/mkiv/util-lib.lua index 714cfd4c7..fb65a566e 100644 --- a/tex/context/base/mkiv/util-lib.lua +++ b/tex/context/base/mkiv/util-lib.lua @@ -237,7 +237,7 @@ local function locate(required,version,trace,report,action) report("stored library: %a",required) end end - return library + return library or nil end do @@ -352,7 +352,7 @@ We use the same lookup logic for ffi loading. trackers.register("resolvers.ffilib", function(v) trace_ffilib = v end) -- pushlibpath(pathpart(name)) - -- local message, library = pcall(savedffiload,nameonly(name)) + -- local state, library = pcall(savedffiload,nameonly(name)) -- poplibpath() local loaded = { } @@ -361,11 +361,11 @@ We use the same lookup logic for ffi loading. name = removesuffix(name) local l = loaded[name] if l == nil then - local message, library = pcall(savedffiload,name) - if type(message) == "userdata" then - l = message - elseif type(library) == "userdata" then + local state, library = pcall(savedffiload,name) + if type(library) == "userdata" then l = library + elseif type(state) == "userdata" then + l = state else l = false end @@ -376,6 +376,20 @@ We use the same lookup logic for ffi loading. return l end + local function getlist(required) + local list = directives.value("system.librarynames" ) + if type(list) == "table" then + list = list[required] + if type(list) == "table" then + if trace then + report("using lookup list for library %a: % | t",required,list) + end + return list + end + end + return { required } + end + function ffilib(name,version) name = removesuffix(name) local l = loaded[name] @@ -384,23 +398,45 @@ We use the same lookup logic for ffi loading. report_ffilib("reusing already loaded %a",name) end return l - elseif version == "system" then - return locateindeed(name) + end + local list = getlist(name) + if version == "system" then + for i=1,#list do + local library = locateindeed(list[i]) + if type(library) == "userdata" then + return library + end + end else - return locate(name,version,trace_ffilib,report_ffilib,locateindeed) + for i=1,#list do + local library = locate(list[i],version,trace_ffilib,report_ffilib,locateindeed) + if type(library) == "userdata" then + return library + end + end end end function ffi.load(name) - local library = ffilib(name) - if type(library) == "userdata" then - return library + local list = getlist(name) + for i=1,#list do + local library = ffilib(list[i]) + if type(library) == "userdata" then + return library + end end if trace_ffilib then report_ffilib("trying to load %a using normal loader",name) end -- so here we don't store - return savedffiload(name) + for i=1,#list do + local state, library = pcall(savedffiload,list[i]) + if type(library) == "userdata" then + return library + elseif type(state) == "userdata" then + return library + end + end end end diff --git a/tex/context/base/mkiv/util-lua.lua b/tex/context/base/mkiv/util-lua.lua index b7de11936..1199301f4 100644 --- a/tex/context/base/mkiv/util-lua.lua +++ b/tex/context/base/mkiv/util-lua.lua @@ -88,6 +88,7 @@ function luautilities.loadedluacode(fullname,forcestrip,name,macros) code() else report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message") + code, message = loadfile(fullname) end if forcestrip and luautilities.stripcode then if type(forcestrip) == "function" then @@ -114,7 +115,7 @@ function luautilities.strippedloadstring(code,name,forcestrip) -- not executed end if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then register(name) - return load(dump(code,true)), 0 -- not yet executes + return load(dump(code,true)), 0 -- not yet executed else return code, 0 end @@ -198,12 +199,12 @@ function luautilities.checkmemory(previous,threshold,trace) -- threshold in MB collectgarbage("collect") local afterwards = collectgarbage("count") if trace or tracememory then - report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB, afterwards %i MB", + report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB, afterwards %r MB", previous/1024,current/1024,delta/1024,threshold,afterwards) end return afterwards elseif trace or tracememory then - report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB", + report_mem("previous %r MB, current %r MB, delta %r MB, threshold %r MB", previous/1024,current/1024,delta/1024,threshold) end end diff --git a/tex/context/base/mkiv/util-mrg.lua b/tex/context/base/mkiv/util-mrg.lua index 690188ef8..bc835bf56 100644 --- a/tex/context/base/mkiv/util-mrg.lua +++ b/tex/context/base/mkiv/util-mrg.lua @@ -113,6 +113,7 @@ local pack = digit * space^1 * operator4 * optionalspacing + optionalspaces * separator * optionalspaces local lines = emptyline^2 / "\n" local spaces = (space * space) / " " +local spaces = (space * space * space * space) / " " ----- spaces = ((space+eol)^1 ) / " " local compact = Cs ( ( diff --git a/tex/context/base/mkiv/util-prs.lua b/tex/context/base/mkiv/util-prs.lua index 48d59a9f3..08401f222 100644 --- a/tex/context/base/mkiv/util-prs.lua +++ b/tex/context/base/mkiv/util-prs.lua @@ -31,6 +31,7 @@ utilities.parsers.hashes = hashes local digit = R("09") local space = P(' ') local equal = P("=") +local colon = P(":") local comma = P(",") local lbrace = P("{") local rbrace = P("}") @@ -72,11 +73,13 @@ lpegpatterns.nested = nestedbraces -- no capture lpegpatterns.argument = argument -- argument after e.g. = lpegpatterns.content = content -- rest after e.g = -local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace) + C((nestedbraces + (1-comma))^0) +local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace + + C((nestedbraces + (1-comma))^0) local key = C((1-equal-comma)^1) local pattern_a = (space+comma)^0 * (key * equal * value + key * C("")) local pattern_c = (space+comma)^0 * (key * equal * value) +local pattern_d = (space+comma)^0 * (key * (equal+colon) * value + key * C("")) local key = C((1-space-equal-comma)^1) local pattern_b = spaces * comma^0 * spaces * (key * ((spaces * equal * spaces * value) + C(""))) @@ -92,10 +95,12 @@ 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 +local pattern_d_s = (pattern_d/set)^1 patterns.settings_to_hash_a = pattern_a_s patterns.settings_to_hash_b = pattern_b_s patterns.settings_to_hash_c = pattern_c_s +patterns.settings_to_hash_d = pattern_d_s function parsers.make_settings_to_hash_pattern(set,how) if how == "strict" then @@ -126,6 +131,18 @@ function parsers.settings_to_hash(str,existing) end end +function parsers.settings_to_hash_colon_too(str) + if not str or str == "" then + return { } + elseif type(str) == "table" then + return str + else + hash = { } + lpegmatch(pattern_d_s,str) + return hash + end +end + function parsers.settings_to_hash_tolerant(str,existing) if not str or str == "" then return { } @@ -165,7 +182,7 @@ function parsers.settings_to_hash_strict(str,existing) end local separator = comma * space^0 -local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace) +local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace + C((nestedbraces + (1-comma))^0) local pattern = spaces * Ct(value*(separator*value)^0) @@ -210,7 +227,7 @@ function parsers.settings_to_numbers(str) return str end -local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace) +local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace + C((nestedbraces + nestedbrackets + nestedparents + (1-comma))^0) local pattern = spaces * Ct(value*(separator*value)^0) @@ -242,7 +259,7 @@ function parsers.groupedsplitat(symbol,withaction) if not pattern then local symbols = S(symbol) local separator = space^0 * symbols * space^0 - local value = P(lbrace * C((nobrace + nestedbraces)^0) * rbrace) + local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace + C((nestedbraces + (1-(space^0*(symbols+P(-1)))))^0) if withaction then local withvalue = Carg(1) * value / function(f,s) return f(s) end @@ -291,7 +308,9 @@ end function parsers.hash_to_string(h,separator,yes,no,strict,omit) if h then - local t, tn, s = { }, 0, sortedkeys(h) + local t = { } + local tn = 0 + local s = sortedkeys(h) omit = omit and tohash(omit) for i=1,#s do local key = s[i] @@ -357,7 +376,8 @@ end) getmetatable(hashes.settings_to_set).__mode = "kv" -- could be an option (maybe sharing makes sense) function parsers.simple_hash_to_string(h, separator) - local t, tn = { }, 0 + local t = { } + local tn = 0 for k, v in sortedhash(h) do if v then tn = tn + 1 @@ -398,7 +418,8 @@ local function repeater(n,str) if n == 1 then return unpack(s) else - local t, tn = { }, 0 + local t = { } + local tn = 0 for i=1,n do for j=1,#s do tn = tn + 1 diff --git a/tex/context/base/mkiv/util-sac.lua b/tex/context/base/mkiv/util-sac.lua index b509d9a9b..dc8ba72f1 100644 --- a/tex/context/base/mkiv/util-sac.lua +++ b/tex/context/base/mkiv/util-sac.lua @@ -10,15 +10,23 @@ if not modules then modules = { } end modules ['util-sac'] = { -- with bytes) local byte, sub = string.byte, string.sub -local extract = bit32 and bit32.extract +local tonumber = tonumber utilities = utilities or { } local streams = { } utilities.streams = streams function streams.open(filename,zerobased) - local f = io.loaddata(filename) - return { f, 1, #f, zerobased or false } + local f = filename and io.loaddata(filename) + if f then + return { f, 1, #f, zerobased or false } + end +end + +function streams.openstring(f,zerobased) + if f then + return { f, 1, #f, zerobased or false } + end end function streams.close() @@ -233,31 +241,31 @@ function streams.readinteger4le(f) end end -function streams.readfixed4(f) +function streams.readfixed2(f) local i = f[2] - local j = i + 3 + local j = i + 1 f[2] = j + 1 - local a, b, c, d = byte(f[1],i,j) + local a, b = byte(f[1],i,j) if a >= 0x80 then - return (0x100 * a + b - 0x10000) + (0x100 * c + d)/0x10000 + tonumber((a - 0x100) .. "." .. b) else - return (0x100 * a + b ) + (0x100 * c + d)/0x10000 + tonumber((a ) .. "." .. b) end end -function streams.readfixed2(f) +function streams.readfixed4(f) local i = f[2] - local j = i + 1 + local j = i + 3 f[2] = j + 1 - local a, b = byte(f[1],i,j) + local a, b, c, d = byte(f[1],i,j) if a >= 0x80 then - return (a - 0x100) + b/0x100 + tonumber((0x100 * a + b - 0x10000) .. "." .. (0x100 * c + d)) else - return (a ) + b/0x100 + tonumber((0x100 * a + b ) .. "." .. (0x100 * c + d)) end end -if extract then +if bit32 then local extract = bit32.extract local band = bit32.band @@ -386,3 +394,80 @@ if sio and sio.readcardinal2 then streams.readinteger = streams.readinteger1 end + +if sio and sio.readcardinaltable then + + local readcardinaltable = sio.readcardinaltable + local readintegertable = sio.readintegertable + + function utilities.streams.readcardinaltable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readcardinaltable(f[1],i,n,b) + end + + function utilities.streams.readintegertable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + return readintegertable(f[1],i,n,b) + end + +else + + local readcardinal1 = streams.readcardinal1 + local readcardinal2 = streams.readcardinal2 + local readcardinal3 = streams.readcardinal3 + local readcardinal4 = streams.readcardinal4 + + function streams.readcardinaltable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + local t = { } + if b == 1 then for i=1,n do t[i] = readcardinal1(f[1],i) end + elseif b == 2 then for i=1,n do t[i] = readcardinal2(f[1],i) end + elseif b == 3 then for i=1,n do t[i] = readcardinal3(f[1],i) end + elseif b == 4 then for i=1,n do t[i] = readcardinal4(f[1],i) end end + return t + end + + local readinteger1 = streams.readinteger1 + local readinteger2 = streams.readinteger2 + local readinteger3 = streams.readinteger3 + local readinteger4 = streams.readinteger4 + + function streams.readintegertable(f,n,b) + local i = f[2] + local s = f[3] + local p = i + n * b + if p > s then + f[2] = s + 1 + else + f[2] = p + end + local t = { } + if b == 1 then for i=1,n do t[i] = readinteger1(f[1],i) end + elseif b == 2 then for i=1,n do t[i] = readinteger2(f[1],i) end + elseif b == 3 then for i=1,n do t[i] = readinteger3(f[1],i) end + elseif b == 4 then for i=1,n do t[i] = readinteger4(f[1],i) end end + return t + end + +end diff --git a/tex/context/base/mkiv/util-seq.lua b/tex/context/base/mkiv/util-seq.lua index d302ff276..e7a503faf 100644 --- a/tex/context/base/mkiv/util-seq.lua +++ b/tex/context/base/mkiv/util-seq.lua @@ -17,26 +17,39 @@ use locals to refer to them when compiling the chain.

-- todo: protect groups (as in tasks) -local gsub, concat, gmatch = string.gsub, table.concat, string.gmatch -local type, load = type, load +local gsub, gmatch = string.gsub, string.gmatch +local concat, sortedkeys = table.concat, table.sortedkeys +local type, load, next, tostring = type, load, next, tostring -utilities = utilities or { } -local tables = utilities.tables -local allocate = utilities.storage.allocate +utilities = utilities or { } +local tables = utilities.tables +local allocate = utilities.storage.allocate -local formatters = string.formatters +local formatters = string.formatters +local replacer = utilities.templates.replacer -local sequencers = { } -utilities.sequencers = sequencers +local trace_used = false +local trace_detail = false +local report = logs.reporter("sequencer") +local usedcount = 0 +local usednames = { } -local functions = allocate() -sequencers.functions = functions +trackers.register("sequencers.used", function(v) trace_used = true end) +trackers.register("sequencers.detail",function(v) trace_detail = true end) + +local sequencers = { } +utilities.sequencers = sequencers + +local functions = allocate() +sequencers.functions = functions local removevalue = tables.removevalue local replacevalue = tables.replacevalue local insertaftervalue = tables.insertaftervalue local insertbeforevalue = tables.insertbeforevalue +local usedsequences = { } + local function validaction(action) if type(action) == "string" then local g = _G @@ -63,9 +76,11 @@ function sequencers.new(t) -- was reset gskip = { }, dirty = true, runner = nil, + steps = 0, } if t then s.arguments = t.arguments + s.templates = t.templates s.returnvalues = t.returnvalues s.results = t.results local name = t.name @@ -86,120 +101,142 @@ function sequencers.new(t) -- was reset end function sequencers.prependgroup(t,group,where) - t = known[t] - if t then - local order = t.order - removevalue(order,group) - insertbeforevalue(order,where,group) - t.list[group] = { } - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + local order = t.order + removevalue(order,group) + insertbeforevalue(order,where,group) + t.list[group] = { } + t.dirty = true + t.runner = nil + end end end function sequencers.appendgroup(t,group,where) - t = known[t] - if t then - local order = t.order - removevalue(order,group) - insertaftervalue(order,where,group) - t.list[group] = { } - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + local order = t.order + removevalue(order,group) + insertaftervalue(order,where,group) + t.list[group] = { } + t.dirty = true + t.runner = nil + end end end function sequencers.prependaction(t,group,action,where,kind,force) - t = known[t] - if t then - local g = t.list[group] - if g and (force or validaction(action)) then - removevalue(g,action) - insertbeforevalue(g,where,action) - t.kind[action] = kind - t.dirty = true - t.runner = nil + if t and group and action then + t = known[t] + if t then + local g = t.list[group] + if g and (force or validaction(action)) then + removevalue(g,action) + insertbeforevalue(g,where,action) + t.kind[action] = kind + t.dirty = true + t.runner = nil + end end end end function sequencers.appendaction(t,group,action,where,kind,force) - t = known[t] - if t then - local g = t.list[group] - if g and (force or validaction(action)) then - removevalue(g,action) - insertaftervalue(g,where,action) - t.kind[action] = kind - t.dirty = true - t.runner = nil + if t and group and action then + t = known[t] + if t then + local g = t.list[group] + if g and (force or validaction(action)) then + removevalue(g,action) + insertaftervalue(g,where,action) + t.kind[action] = kind + t.dirty = true + t.runner = nil + end end end end function sequencers.enableaction(t,action) - t = known[t] - if t then - t.askip[action] = false - t.dirty = true - t.runner = nil + if t and action then + t = known[t] + if t then + t.askip[action] = false + t.dirty = true + t.runner = nil + end end end function sequencers.disableaction(t,action) - t = known[t] - if t then - t.askip[action] = true - t.dirty = true - t.runner = nil + if t and action then + t = known[t] + if t then + t.askip[action] = true + t.dirty = true + t.runner = nil + end end end function sequencers.enablegroup(t,group) - t = known[t] - if t then - t.gskip[action] = false - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + t.gskip[group] = false + t.dirty = true + t.runner = nil + end end end function sequencers.disablegroup(t,group) - t = known[t] - if t then - t.gskip[action] = true - t.dirty = true - t.runner = nil + if t and group then + t = known[t] + if t then + t.gskip[group] = true + t.dirty = true + t.runner = nil + end end end function sequencers.setkind(t,action,kind) - t = known[t] - if t then - t.kind[action] = kind - t.dirty = true - t.runner = nil + if t and action then + t = known[t] + if t then + t.kind[action] = kind + t.dirty = true + t.runner = nil + end end end function sequencers.removeaction(t,group,action,force) - t = known[t] - local g = t and t.list[group] - if g and (force or validaction(action)) then - removevalue(g,action) - t.dirty = true - t.runner = nil + if t and group and action then + t = known[t] + local g = t and t.list[group] + if g and (force or validaction(action)) then + removevalue(g,action) + t.dirty = true + t.runner = nil + end end end function sequencers.replaceaction(t,group,oldaction,newaction,force) - t = known[t] - if t then - local g = t.list[group] - if g and (force or validaction(oldaction)) then - replacevalue(g,oldaction,newaction) - t.dirty = true - t.runner = nil + if t and group and oldaction and newaction then + t = known[t] + if t then + local g = t.list[group] + if g and (force or validaction(oldaction)) then + replacevalue(g,oldaction,newaction) + t.dirty = true + t.runner = nil + end end end end @@ -209,9 +246,19 @@ local function localize(str) end local function construct(t) - local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip - local arguments, returnvalues, results = t.arguments or "...", t.returnvalues, t.results - local variables, calls, n = { }, { }, 0 + local list = t.list + local order = t.order + local kind = t.kind + local gskip = t.gskip + local askip = t.askip + local name = t.name or "?" + local arguments = t.arguments or "..." + local returnvalues = t.returnvalues + local results = t.results + local variables = { } + local calls = { } + local n = 0 + usedcount = usedcount + 1 for i=1,#order do local group = order[i] if not gskip[group] then @@ -219,6 +266,11 @@ local function construct(t) for i=1,#actions do local action = actions[i] if not askip[action] then + if trace_used then + local action = tostring(action) + report("%02i: category %a, group %a, action %a",usedcount,name,group,action) + usednames[action] = true + end local localized if type(action) == "function" then local name = localize(tostring(action)) @@ -242,6 +294,7 @@ local function construct(t) end end t.dirty = false + t.steps = n if n == 0 then t.compiled = "" else @@ -253,30 +306,27 @@ local function construct(t) t.compiled = formatters["%s\nreturn function(%s)\n%s\nend"](variables,arguments,calls) end end --- print(t.compiled) return t.compiled -- also stored so that we can trace end sequencers.tostring = construct sequencers.localize = localize -compile = function(t,compiler,n) -- already referred to in sequencers.new +compile = function(t,compiler,...) -- already referred to in sequencers.new local compiled if not t or type(t) == "string" then - -- weird ... t.compiled = t .. so return false end if compiler then - compiled = compiler(t,n) + compiled = compiler(t,...) t.compiled = compiled else - compiled = construct(t,n) + compiled = construct(t,...) end local runner if compiled == "" then runner = false else --- inspect(compiled) runner = compiled and load(compiled)() -- we can use loadstripped here end t.runner = runner @@ -285,52 +335,45 @@ end sequencers.compile = compile --- we used to deal with tail as well but now that the lists are always --- double linked and the kernel function no longer expect tail as --- argument we stick to head and done (done can probably also go --- as luatex deals with return values efficiently now .. in the --- past there was some copying involved, but no longer) - --- todo: use sequencer (can have arguments and returnvalues etc now) - -local template_yes_state = [[ -%s -return function(head%s) - local ok, done = false, false -%s - return head, done -end]] - -local template_yes_nostate = [[ -%s -return function(head%s) -%s - return head, true -end]] - -local template_nop = [[ -return function() - return false, false -end]] - -function sequencers.nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug into tostring - local list, order, kind, gskip, askip = t.list, t.order, t.kind, t.gskip, t.askip - local nostate = t.nostate - local vars, calls, args, n = { }, { }, nil, 0 - if nofarguments == 0 then - args = "" - elseif nofarguments == 1 then - args = ",one" - elseif nofarguments == 2 then - args = ",one,two" - elseif nofarguments == 3 then -- from here on probably slower than ... - args = ",one,two,three" - elseif nofarguments == 4 then - args = ",one,two,three,four" - elseif nofarguments == 5 then - args = ",one,two,three,four,five" - else - args = ",..." +function sequencers.nodeprocessor(t,nofarguments) + -- + local templates = nofarguments + -- + if type(templates) ~= "table" then + return "" + end + -- + local replacers = { } + for k, v in next, templates do + replacers[k] = replacer(v) + end + -- + local construct = replacers.process + local step = replacers.step + if not construct or not step then + return "" + end + -- + local calls = { } + local aliases = { } + local ncalls = 0 + local naliases = 0 + local f_alias = formatters["local %s = %s"] + -- + local list = t.list + local order = t.order + local kind = t.kind + local gskip = t.gskip + local askip = t.askip + local name = t.name or "?" + local steps = 0 + usedcount = usedcount + 1 + -- + if trace_detail then + naliases = naliases + 1 + aliases[naliases] = formatters["local report = logs.reporter('sequencer',%q)"](name) + ncalls = ncalls + 1 + calls[ncalls] = [[report("start")]] end for i=1,#order do local group = order[i] @@ -339,28 +382,47 @@ function sequencers.nodeprocessor(t,nofarguments) -- todo: handle 'kind' in plug for i=1,#actions do local action = actions[i] if not askip[action] then - local localized = localize(action) - n = n + 1 - vars[n] = formatters["local %s = %s"](localized,action) - -- only difference with tostring is kind and rets (why no return) - if nostate then - if kind[action] == "nohead" then - calls[n] = formatters[" %s(head%s)"](localized,args) - else - calls[n] = formatters[" head = %s(head%s)"](localized,args) - end - else - if kind[action] == "nohead" then - calls[n] = formatters[" ok = %s(head%s) if ok then done = true end"](localized,args) - else - calls[n] = formatters[" head, ok = %s(head%s) if ok then done = true end"](localized,args) - end + steps = steps + 1 + if trace_used or trace_detail then + local action = tostring(action) + report("%02i: category %a, group %a, action %a",usedcount,name,group,action) + usednames[action] = true end + if trace_detail then + ncalls = ncalls + 1 + calls[ncalls] = formatters[ [[report(" step %a, action %a")]] ](steps,tostring(action)) + end + local localized = localize(action) + local onestep = replacers[kind[action]] or step + naliases = naliases + 1 + ncalls = ncalls + 1 + aliases[naliases] = f_alias(localized,action) + calls [ncalls] = onestep { action = localized } end end end end - local processor = #calls > 0 and formatters[nostate and template_yes_nostate or template_yes_state](concat(vars,"\n"),args,concat(calls,"\n")) or template_nop + t.steps = steps + local processor + if steps == 0 then + processor = templates.default or construct { } + else + if trace_detail then + ncalls = ncalls + 1 + calls[ncalls] = [[report("stop")]] + end + processor = construct { + localize = concat(aliases,"\n"), + actions = concat(calls,"\n"), + } + end + -- processor = "print('running : " .. (t.name or "?") .. "')\n" .. processor -- print(processor) return processor end + +statistics.register("used sequences",function() + if next(usednames) then + return concat(sortedkeys(usednames)," ") + end +end) diff --git a/tex/context/base/mkiv/util-sha.lua b/tex/context/base/mkiv/util-sha.lua index 3e786a834..d84e46975 100644 --- a/tex/context/base/mkiv/util-sha.lua +++ b/tex/context/base/mkiv/util-sha.lua @@ -8,6 +8,13 @@ if not modules then modules = { } end modules ['util-sha'] = { comment3 = "due to bit operators this code only works in lua(tex) 5.3", } +if sha2 then + if utilities then + utilities.sha2 = sha2 + end + return sha2 +end + -- This doesn't work in luajittex ... maybe some day it will have bit operators too. -- I'm not really in the mood for making this module aware (by compiling the -- function depending on the engine that I use but I probably won't use luajittex in @@ -277,10 +284,10 @@ digest[224] = digest[256] digest[384] = digest[512] local finalize = { - [224] = function(hash,tohex) return tohex(packstring(">I4I4I4I4I4I4I4", unpack(hash))) end, -- # 56 - [256] = function(hash,tohex) return tohex(packstring(">I4I4I4I4I4I4I4I4",unpack(hash))) end, -- # 64 - [384] = function(hash,tohex) return tohex(packstring(">I8I8I8I8I8I8", unpack(hash))) end, -- # 96 - [512] = function(hash,tohex) return tohex(packstring(">I8I8I8I8I8I8I8I8",unpack(hash))) end, -- # 128 + [224] = function(hash,tohex) local s = packstring(">I4I4I4I4I4I4I4", unpack(hash)) return tohex and tohex(s) or s end, -- # 56 + [256] = function(hash,tohex) local s = packstring(">I4I4I4I4I4I4I4I4",unpack(hash)) return tohex and tohex(s) or s end, -- # 64 + [384] = function(hash,tohex) local s = packstring(">I8I8I8I8I8I8", unpack(hash)) return tohex and tohex(s) or s end, -- # 96 + [512] = function(hash,tohex) local s = packstring(">I8I8I8I8I8I8I8I8",unpack(hash)) return tohex and tohex(s) or s end, -- # 128 } local hash = { } @@ -293,14 +300,18 @@ local function hashed(str,method,tohex) end local sha2 = { - hash224 = function(str) return hashed(str,224,tohex) end, - hash256 = function(str) return hashed(str,256,tohex) end, - hash384 = function(str) return hashed(str,384,tohex) end, - hash512 = function(str) return hashed(str,512,tohex) end, - HASH224 = function(str) return hashed(str,224,toHEX) end, - HASH256 = function(str) return hashed(str,256,toHEX) end, - HASH384 = function(str) return hashed(str,384,toHEX) end, - HASH512 = function(str) return hashed(str,512,toHEX) end, + digest224 = function(str) return hashed(str,224) end, + digest256 = function(str) return hashed(str,256) end, + digest384 = function(str) return hashed(str,384) end, + digest512 = function(str) return hashed(str,512) end, + hash224 = function(str) return hashed(str,224,tohex) end, + hash256 = function(str) return hashed(str,256,tohex) end, + hash384 = function(str) return hashed(str,384,tohex) end, + hash512 = function(str) return hashed(str,512,tohex) end, + HASH224 = function(str) return hashed(str,224,toHEX) end, + HASH256 = function(str) return hashed(str,256,toHEX) end, + HASH384 = function(str) return hashed(str,384,toHEX) end, + HASH512 = function(str) return hashed(str,512,toHEX) end, } -- local setmetatableindex = table.setmetatableindex diff --git a/tex/context/base/mkiv/util-soc-imp-copas.lua b/tex/context/base/mkiv/util-soc-imp-copas.lua new file mode 100644 index 000000000..3e66e5888 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-copas.lua @@ -0,0 +1,931 @@ +-- original file : copas.lua +-- for more into : see util-soc.lua + +local socket = socket or require("socket") +local ssl = ssl or nil -- only loaded upon demand + +local WATCH_DOG_TIMEOUT = 120 +local UDP_DATAGRAM_MAX = 8192 + +local type, next, pcall, getmetatable, tostring = type, next, pcall, getmetatable, tostring +local min, max, random = math.min, math.max, math.random +local find = string.find +local insert, remove = table.insert, table.remove + +local gettime = socket.gettime +local selectsocket = socket.select + +local createcoroutine = coroutine.create +local resumecoroutine = coroutine.resume +local yieldcoroutine = coroutine.yield +local runningcoroutine = coroutine.running + +-- Redefines LuaSocket functions with coroutine safe versions (this allows the use +-- of socket.http from within copas). + +-- Meta information is public even if beginning with an "_" + +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("copas") + report(fmt,first,...) + elseif fmt then + fmt = "copas: " .. fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end + +local copas = { + + _COPYRIGHT = "Copyright (C) 2005-2016 Kepler Project", + _DESCRIPTION = "Coroutine Oriented Portable Asynchronous Services", + _VERSION = "Copas 2.0.1", + + autoclose = true, + running = false, + + report = report, + +} + +local function statushandler(status, ...) + if status then + return ... + end + local err = (...) + if type(err) == "table" then + err = err[1] + end + report("error: %s",tostring(err)) + return nil, err +end + +function socket.protect(func) + return function(...) + return statushandler(pcall(func,...)) + end +end + +function socket.newtry(finalizer) + return function (...) + local status = (...) + if not status then + local detail = select(2,...) + pcall(finalizer,detail) + report("error: %s",tostring(detail)) + return + end + return ... + end +end + +-- Simple set implementation based on LuaSocket's tinyirc.lua example +-- adds a FIFO queue for each value in the set + +local function newset() + local reverse = { } + local set = { } + local queue = { } + setmetatable(set, { + __index = { + insert = + function(set, value) + if not reverse[value] then + local n = #set +1 + set[n] = value + reverse[value] = n + end + end, + remove = + function(set, value) + local index = reverse[value] + if index then + reverse[value] = nil + local n = #set + local top = set[n] + set[n] = nil + if top ~= value then + reverse[top] = index + set[index] = top + end + end + end, + push = + function (set, key, itm) + local entry = queue[key] + if entry == nil then -- hm can it be false then? + queue[key] = { itm } + else + entry[#entry + 1] = itm + end + end, + pop = + function (set, key) + local top = queue[key] + if top ~= nil then + local ret = remove(top,1) + if top[1] == nil then + queue[key] = nil + end + return ret + end + end + } + } ) + return set +end + +local _sleeping = { + times = { }, -- list with wake-up times + cos = { }, -- list with coroutines, index matches the 'times' list + lethargy = { }, -- list of coroutines sleeping without a wakeup time + + insert = + function() + end, + remove = + function() + end, + push = + function(self, sleeptime, co) + if not co then + return + end + if sleeptime < 0 then + --sleep until explicit wakeup through copas.wakeup + self.lethargy[co] = true + return + else + sleeptime = gettime() + sleeptime + end + local t = self.times + local c = self.cos + local i = 1 + local n = #t + while i <= n and t[i] <= sleeptime do + i = i + 1 + end + insert(t,i,sleeptime) + insert(c,i,co) + end, + getnext = + -- returns delay until next sleep expires, or nil if there is none + function(self) + local t = self.times + local delay = t[1] and t[1] - gettime() or nil + return delay and max(delay, 0) or nil + end, + pop = + -- find the thread that should wake up to the time + function(self, time) + local t = self.times + local c = self.cos + if #t == 0 or time < t[1] then + return + end + local co = c[1] + remove(t,1) + remove(c,1) + return co + end, + wakeup = + function(self, co) + local let = self.lethargy + if let[co] then + self:push(0, co) + let[co] = nil + else + local c = self.cos + local t = self.times + for i=1,#c do + if c[i] == co then + remove(c,i) + remove(t,i) + self:push(0, co) + return + end + end + end + end +} + +local _servers = newset() -- servers being handled +local _reading = newset() -- sockets currently being read +local _writing = newset() -- sockets currently being written + +local _reading_log = { } +local _writing_log = { } + +local _is_timeout = { -- set of errors indicating a timeout + timeout = true, -- default LuaSocket timeout + wantread = true, -- LuaSec specific timeout + wantwrite = true, -- LuaSec specific timeout +} + +-- Coroutine based socket I/O functions. + +local function isTCP(socket) + return not find(tostring(socket),"^udp") +end + +-- Reads a pattern from a client and yields to the reading set on timeouts UDP: a +-- UDP socket expects a second argument to be a number, so it MUST be provided as +-- the 'pattern' below defaults to a string. Will throw a 'bad argument' error if +-- omitted. + +local function copasreceive(client, pattern, part) + if not pattern or pattern == "" then + pattern = "*l" + end + local current_log = _reading_log + local s, err + repeat + s, err, part = client:receive(pattern, part) + if s or (not _is_timeout[err]) then + current_log[client] = nil + return s, err, part + end + if err == "wantwrite" then + current_log = _writing_log + current_log[client] = gettime() + yieldcoroutine(client, _writing) + else + current_log = _reading_log + current_log[client] = gettime() + yieldcoroutine(client, _reading) + end + until false +end + +-- Receives data from a client over UDP. Not available for TCP. (this is a copy of +-- receive() method, adapted for receivefrom() use). + +local function copasreceivefrom(client, size) + local s, err, port + if not size or size == 0 then + size = UDP_DATAGRAM_MAX + end + repeat + -- upon success err holds ip address + s, err, port = client:receivefrom(size) + if s or err ~= "timeout" then + _reading_log[client] = nil + return s, err, port + end + _reading_log[client] = gettime() + yieldcoroutine(client, _reading) + until false +end + +-- Same as above but with special treatment when reading chunks, unblocks on any +-- data received. + +local function copasreceivepartial(client, pattern, part) + if not pattern or pattern == "" then + pattern = "*l" + end + local logger = _reading_log + local queue = _reading + local s, err + repeat + s, err, part = client:receive(pattern, part) + if s or (type(pattern) == "number" and part ~= "" and part) or not _is_timeout[err] then + logger[client] = nil + return s, err, part + end + if err == "wantwrite" then + logger = _writing_log + queue = _writing + else + logger = _reading_log + queue = _reading + end + logger[client] = gettime() + yieldcoroutine(client, queue) + until false +end + +-- Sends data to a client. The operation is buffered and yields to the writing set +-- on timeouts Note: from and to parameters will be ignored by/for UDP sockets + +local function copassend(client, data, from, to) + if not from then + from = 1 + end + local lastIndex = from - 1 + local logger = _writing_log + local queue = _writing + local s, err + repeat + s, err, lastIndex = client:send(data, lastIndex + 1, to) + -- Adds extra coroutine swap and garantees that high throughput doesn't take + -- other threads to starvation. + if random(100) > 90 then + logger[client] = gettime() + yieldcoroutine(client, queue) + end + if s or not _is_timeout[err] then + logger[client] = nil + return s, err,lastIndex + end + if err == "wantread" then + logger = _reading_log + queue = _reading + else + logger = _writing_log + queue = _writing + end + logger[client] = gettime() + yieldcoroutine(client, queue) + until false +end + +-- Sends data to a client over UDP. Not available for TCP. (this is a copy of send() +-- method, adapted for sendto() use). + +local function copassendto(client, data, ip, port) + repeat + local s, err = client:sendto(data, ip, port) + -- Adds extra coroutine swap and garantees that high throughput doesn't + -- take other threads to starvation. + if random(100) > 90 then + _writing_log[client] = gettime() + yieldcoroutine(client, _writing) + end + if s or err ~= "timeout" then + _writing_log[client] = nil + return s, err + end + _writing_log[client] = gettime() + yieldcoroutine(client, _writing) + until false +end + +-- Waits until connection is completed. + +local function copasconnect(skt, host, port) + skt:settimeout(0) + local ret, err, tried_more_than_once + repeat + ret, err = skt:connect (host, port) + -- A non-blocking connect on Windows results in error "Operation already in + -- progress" to indicate that it is completing the request async. So + -- essentially it is the same as "timeout". + if ret or (err ~= "timeout" and err ~= "Operation already in progress") then + -- Once the async connect completes, Windows returns the error "already + -- connected" to indicate it is done, so that error should be ignored. + -- Except when it is the first call to connect, then it was already + -- connected to something else and the error should be returned. + if not ret and err == "already connected" and tried_more_than_once then + ret = 1 + err = nil + end + _writing_log[skt] = nil + return ret, err + end + tried_more_than_once = tried_more_than_once or true + _writing_log[skt] = gettime() + yieldcoroutine(skt, _writing) + until false +end + +-- Peforms an (async) ssl handshake on a connected TCP client socket. Replacec all +-- previous socket references, with the returned new ssl wrapped socket Throws error +-- and does not return nil+error, as that might silently fail in code like this. + +local function copasdohandshake(skt, sslt) -- extra ssl parameters + if not ssl then + ssl = require("ssl") + end + if not ssl then + report("error: no ssl library") + return + end + local nskt, err = ssl.wrap(skt, sslt) + if not nskt then + report("error: %s",tostring(err)) + return + end + nskt:settimeout(0) + local queue + repeat + local success, err = nskt:dohandshake() + if success then + return nskt + elseif err == "wantwrite" then + queue = _writing + elseif err == "wantread" then + queue = _reading + else + report("error: %s",tostring(err)) + return + end + yieldcoroutine(nskt, queue) + until false +end + +-- Flushes a client write buffer. + +local function copasflush(client) +end + +-- Public. + +copas.connect = copassconnect +copas.send = copassend +copas.sendto = copassendto +copas.receive = copasreceive +copas.receivefrom = copasreceivefrom +copas.copasreceivepartial = copasreceivepartial +copas.copasreceivePartial = copasreceivepartial +copas.dohandshake = copasdohandshake +copas.flush = copasflush + +-- Wraps a TCP socket to use Copas methods (send, receive, flush and settimeout). + +local function _skt_mt_tostring(self) + return tostring(self.socket) .. " (copas wrapped)" +end + +local _skt_mt_tcp_index = { + send = + function(self, data, from, to) + return copassend (self.socket, data, from, to) + end, + receive = + function (self, pattern, prefix) + if self.timeout == 0 then + return copasreceivePartial(self.socket, pattern, prefix) + else + return copasreceive(self.socket, pattern, prefix) + end + end, + + flush = + function (self) + return copasflush(self.socket) + end, + + settimeout = + function (self, time) + self.timeout = time + return true + end, + -- TODO: socket.connect is a shortcut, and must be provided with an alternative + -- if ssl parameters are available, it will also include a handshake + connect = + function(self, ...) + local res, err = copasconnect(self.socket, ...) + if res and self.ssl_params then + res, err = self:dohandshake() + end + return res, err + end, + close = + function(self, ...) + return self.socket:close(...) + end, + -- TODO: socket.bind is a shortcut, and must be provided with an alternative + bind = + function(self, ...) + return self.socket:bind(...) + end, + -- TODO: is this DNS related? hence blocking? + getsockname = + function(self, ...) + return self.socket:getsockname(...) + end, + getstats = + function(self, ...) + return self.socket:getstats(...) + end, + setstats = + function(self, ...) + return self.socket:setstats(...) + end, + listen = + function(self, ...) + return self.socket:listen(...) + end, + accept = + function(self, ...) + return self.socket:accept(...) + end, + setoption = + function(self, ...) + return self.socket:setoption(...) + end, + -- TODO: is this DNS related? hence blocking? + getpeername = + function(self, ...) + return self.socket:getpeername(...) + end, + shutdown = + function(self, ...) + return self.socket:shutdown(...) + end, + dohandshake = + function(self, sslt) + self.ssl_params = sslt or self.ssl_params + local nskt, err = copasdohandshake(self.socket, self.ssl_params) + if not nskt then + return nskt, err + end + self.socket = nskt + return self + end, +} + +local _skt_mt_tcp = { + __tostring = _skt_mt_tostring, + __index = _skt_mt_tcp_index, +} + +-- wraps a UDP socket, copy of TCP one adapted for UDP. + +local _skt_mt_udp_index = { + -- UDP sending is non-blocking, but we provide starvation prevention, so replace + -- anyway. + sendto = + function (self, ...) + return copassendto(self.socket,...) + end, + receive = + function (self, size) + return copasreceive(self.socket, size or UDP_DATAGRAM_MAX) + end, + receivefrom = + function (self, size) + return copasreceivefrom(self.socket, size or UDP_DATAGRAM_MAX) + end, + -- TODO: is this DNS related? hence blocking? + setpeername = + function(self, ...) + return self.socket:getpeername(...) + end, + setsockname = + function(self, ...) + return self.socket:setsockname(...) + end, + -- do not close client, as it is also the server for udp. + close = + function(self, ...) + return true + end +} + +local _skt_mt_udp = { + __tostring = _skt_mt_tostring, + __index = _skt_mt_udp_index, +} + +for k, v in next, _skt_mt_tcp_index do + if not _skt_mt_udp_index[k] then + _skt_mt_udp_index[k] = v + end +end + +-- Wraps a LuaSocket socket object in an async Copas based socket object. + +-- @param skt the socket to wrap +-- @sslt (optional) Table with ssl parameters, use an empty table to use ssl with defaults +-- @return wrapped socket object + +local function wrap(skt, sslt) + if getmetatable(skt) == _skt_mt_tcp or getmetatable(skt) == _skt_mt_udp then + return skt -- already wrapped + end + skt:settimeout(0) + if isTCP(skt) then + return setmetatable ({ socket = skt, ssl_params = sslt }, _skt_mt_tcp) + else + return setmetatable ({ socket = skt }, _skt_mt_udp) + end +end + +copas.wrap = wrap + +-- Wraps a handler in a function that deals with wrapping the socket and doing +-- the optional ssl handshake. + +function copas.handler(handler, sslparams) + return function (skt,...) + skt = wrap(skt) + if sslparams then + skt:dohandshake(sslparams) + end + return handler(skt,...) + end +end + +-- Error handling (a handler per coroutine). + +local _errhandlers = { } + +function copas.setErrorHandler(err) + local co = runningcoroutine() + if co then + _errhandlers[co] = err + end +end + +local function _deferror (msg, co, skt) + report("%s (%s) (%s)", msg, tostring(co), tostring(skt)) +end + +-- Thread handling + +local function _doTick (co, skt, ...) + if not co then + return + end + + local ok, res, new_q = resumecoroutine(co, skt, ...) + + if ok and res and new_q then + new_q:insert(res) + new_q:push(res, co) + else + if not ok then + pcall(_errhandlers[co] or _deferror, res, co, skt) + end + -- Do not auto-close UDP sockets, as the handler socket is also the server socket. + if skt and copas.autoclose and isTCP(skt) then + skt:close() + end + _errhandlers[co] = nil + end +end + +-- Accepts a connection on socket input. + +local function _accept(input, handler) + local client = input:accept() + if client then + client:settimeout(0) + local co = createcoroutine(handler) + _doTick (co, client) + -- _reading:insert(client) + end + return client +end + +-- Handle threads on a queue. + +local function _tickRead(skt) + _doTick(_reading:pop(skt), skt) +end + +local function _tickWrite(skt) + _doTick(_writing:pop(skt), skt) +end + +-- Adds a server/handler pair to Copas dispatcher. + +local function addTCPserver(server, handler, timeout) + server:settimeout(timeout or 0) + _servers[server] = handler + _reading:insert(server) +end + +local function addUDPserver(server, handler, timeout) + server:settimeout(timeout or 0) + local co = createcoroutine(handler) + _reading:insert(server) + _doTick(co, server) +end + +function copas.addserver(server, handler, timeout) + if isTCP(server) then + addTCPserver(server, handler, timeout) + else + addUDPserver(server, handler, timeout) + end +end + +function copas.removeserver(server, keep_open) + local s = server + local mt = getmetatable(server) + if mt == _skt_mt_tcp or mt == _skt_mt_udp then + s = server.socket + end + _servers[s] = nil + _reading:remove(s) + if keep_open then + return true + end + return server:close() +end + +-- Adds an new coroutine thread to Copas dispatcher. Create a coroutine that skips +-- the first argument, which is always the socket passed by the scheduler, but `nil` +-- in case of a task/thread + +function copas.addthread(handler, ...) + local thread = createcoroutine(function(_, ...) return handler(...) end) + _doTick(thread, nil, ...) + return thread +end + +-- tasks registering + +local _tasks = { } + +-- Lets tasks call the default _tick(). + +local function addtaskRead(task) + task.def_tick = _tickRead + _tasks[task] = true +end + +-- Lets tasks call the default _tick(). + +local function addtaskWrite(task) + task.def_tick = _tickWrite + _tasks[task] = true +end + +local function tasks() + return next, _tasks +end + +-- A task to check ready to read events. + +local _readable_t = { + events = + function(self) + local i = 0 + return function () + i = i + 1 + return self._evs[i] + end + end, + tick = + function(self, input) + local handler = _servers[input] + if handler then + input = _accept(input, handler) + else + _reading:remove(input) + self.def_tick(input) + end + end +} + +addtaskRead(_readable_t) + +-- A task to check ready to write events. + +local _writable_t = { + events = + function(self) + local i = 0 + return function() + i = i + 1 + return self._evs[i] + end + end, + tick = + function(self, output) + _writing:remove(output) + self.def_tick(output) + end +} + +addtaskWrite(_writable_t) + +--sleeping threads task + +local _sleeping_t = { + tick = function(self, time, ...) + _doTick(_sleeping:pop(time), ...) + end +} + +-- yields the current coroutine and wakes it after 'sleeptime' seconds. +-- If sleeptime<0 then it sleeps until explicitly woken up using 'wakeup' +function copas.sleep(sleeptime) + yieldcoroutine((sleeptime or 0), _sleeping) +end + +-- Wakes up a sleeping coroutine 'co'. + +function copas.wakeup(co) + _sleeping:wakeup(co) +end + +-- Checks for reads and writes on sockets + +local last_cleansing = 0 + +local function _select(timeout) + + local now = gettime() + + local r_evs, w_evs, err = selectsocket(_reading, _writing, timeout) + + _readable_t._evs = r_evs + _writable_t._evs = w_evs + + if (last_cleansing - now) > WATCH_DOG_TIMEOUT then + + last_cleansing = now + + -- Check all sockets selected for reading, and check how long they have been + -- waiting for data already, without select returning them as readable. + + for skt, time in next, _reading_log do + + if not r_evs[skt] and (time - now) > WATCH_DOG_TIMEOUT then + + -- This one timedout while waiting to become readable, so move it in + -- the readable list and try and read anyway, despite not having + -- been returned by select. + + local n = #r_evs + 1 + _reading_log[skt] = nil + r_evs[n] = skt + r_evs[skt] = n + end + end + + -- Do the same for writing. + + for skt, time in next, _writing_log do + if not w_evs[skt] and (time - now) > WATCH_DOG_TIMEOUT then + local n = #w_evs + 1 + _writing_log[skt] = nil + w_evs[n] = skt + w_evs[skt] = n + end + end + + end + + if err == "timeout" and #r_evs + #w_evs > 0 then + return nil + else + return err + end + +end + +-- Check whether there is something to do. It returns false if there are no sockets +-- for read/write nor tasks scheduled (which means Copas is in an empty spin). + +local function copasfinished() + return not (next(_reading) or next(_writing) or _sleeping:getnext()) +end + +-- Dispatcher loop step. It listens to client requests and handles them and returns +-- false if no data was handled (timeout), or true if there was data handled (or nil +-- + error message). + +local function copasstep(timeout) + _sleeping_t:tick(gettime()) + + local nextwait = _sleeping:getnext() + if nextwait then + timeout = timeout and min(nextwait,timeout) or nextwait + elseif copasfinished() then + return false + end + + local err = _select(timeout) + if err then + if err == "timeout" then + return false + end + return nil, err + end + + for task in tasks() do + for event in task:events() do + task:tick(event) + end + end + return true +end + +copas.finished = copasfinished +copas.step = copasstep + +-- Dispatcher endless loop. It listens to client requests and handles them forever. + +function copas.loop(timeout) + copas.running = true + while not copasfinished() do + copasstep(timeout) + end + copas.running = false +end + +-- _G.copas = copas + +package.loaded["copas"] = copas + +return copas diff --git a/tex/context/base/mkiv/util-soc-imp-ftp.lua b/tex/context/base/mkiv/util-soc-imp-ftp.lua new file mode 100644 index 000000000..124c8d4ee --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-ftp.lua @@ -0,0 +1,402 @@ +-- original file : ftp.lua +-- for more into : see util-soc.lua + +local setmetatable, type, next = setmetatable, type, next +local find, format, gsub, match = string.find, string.format, string.gsub, string.match +local concat = table.concat +local mod = math.mod + +local socket = socket or require("socket") +local url = socket.url or require("socket.url") +local tp = socket.tp or require("socket.tp") +local ltn12 = ltn12 or require("ltn12") + +local tcpsocket = socket.tcp +local trysocket = socket.try +local skipsocket = socket.skip +local sinksocket = socket.sink +local selectsocket = socket.select +local bindsocket = socket.bind +local newtrysocket = socket.newtry +local sourcesocket = socket.source +local protectsocket = socket.protect + +local parseurl = url.parse +local unescapeurl = url.unescape + +local pumpall = ltn12.pump.all +local pumpstep = ltn12.pump.step +local sourcestring = ltn12.source.string +local sinktable = ltn12.sink.table + +local ftp = { + TIMEOUT = 60, + USER = "ftp", + PASSWORD = "anonymous@anonymous.org", +} + +socket.ftp = ftp + +local PORT = 21 + +local methods = { } +local mt = { __index = methods } + +function ftp.open(server, port, create) + local tp = trysocket(tp.connect(server, port or PORT, ftp.TIMEOUT, create)) + local f = setmetatable({ tp = tp }, metat) + f.try = newtrysocket(function() f:close() end) + return f +end + +function methods.portconnect(self) + local try = self.try + local server = self.server + try(server:settimeout(ftp.TIMEOUT)) + self.data = try(server:accept()) + try(self.data:settimeout(ftp.TIMEOUT)) +end + +function methods.pasvconnect(self) + local try = self.try + self.data = try(tcpsocket()) + self(self.data:settimeout(ftp.TIMEOUT)) + self(self.data:connect(self.pasvt.address, self.pasvt.port)) +end + +function methods.login(self, user, password) + local try = self.try + local tp = self.tp + try(tp:command("user", user or ftp.USER)) + local code, reply = try(tp:check{"2..", 331}) + if code == 331 then + try(tp:command("pass", password or ftp.PASSWORD)) + try(tp:check("2..")) + end + return 1 +end + +function methods.pasv(self) + local try = self.try + local tp = self.tp + try(tp:command("pasv")) + local code, reply = try(self.tp:check("2..")) + local pattern = "(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)%D(%d+)" + local a, b, c, d, p1, p2 = skipsocket(2, find(reply, pattern)) + try(a and b and c and d and p1 and p2, reply) + local address = format("%d.%d.%d.%d", a, b, c, d) + local port = p1*256 + p2 + local server = self.server + self.pasvt = { + address = address, + port = port, + } + if server then + server:close() + self.server = nil + end + return address, port +end + +function methods.epsv(self) + local try = self.try + local tp = self.tp + try(tp:command("epsv")) + local code, reply = try(tp:check("229")) + local pattern = "%((.)(.-)%1(.-)%1(.-)%1%)" + local d, prt, address, port = match(reply, pattern) + try(port, "invalid epsv response") + local address = tp:getpeername() + local server = self.server + self.pasvt = { + address = address, + port = port, + } + if self.server then + server:close() + self.server = nil + end + return address, port +end + +function methods.port(self, address, port) + local try = self.try + local tp = self.tp + self.pasvt = nil + if not address then + address, port = try(tp:getsockname()) + self.server = try(bindsocket(address, 0)) + address, port = try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local pl = mod(port,256) + local ph = (port - pl)/256 + local arg = gsub(format("%s,%d,%d", address, ph, pl), "%.", ",") + try(tp:command("port", arg)) + try(tp:check("2..")) + return 1 +end + +function methods.eprt(self, family, address, port) + local try = self.try + local tp = self.tp + self.pasvt = nil + if not address then + address, port = try(tp:getsockname()) + self.server = try(bindsocket(address, 0)) + address, port = try(self.server:getsockname()) + try(self.server:settimeout(ftp.TIMEOUT)) + end + local arg = format("|%s|%s|%d|", family, address, port) + try(tp:command("eprt", arg)) + try(tp:check("2..")) + return 1 +end + +function methods.send(self, sendt) + local try = self.try + local tp = self.tp + -- so we try a table or string ? + try(self.pasvt or self.server, "need port or pasv first") + if self.pasvt then + self:pasvconnect() + end + local argument = sendt.argument or unescapeurl(gsub(sendt.path or "", "^[/\\]", "")) + if argument == "" then + argument = nil + end + local command = sendt.command or "stor" + try(tp:command(command, argument)) + local code, reply = try(tp:check{"2..", "1.."}) + if not self.pasvt then + self:portconnect() + end + local step = sendt.step or pumpstep + local readt = { tp } + local checkstep = function(src, snk) + local readyt = selectsocket(readt, nil, 0) + if readyt[tp] then + code = try(tp:check("2..")) + end + return step(src, snk) + end + local sink = sinksocket("close-when-done", self.data) + try(pumpall(sendt.source, sink, checkstep)) + if find(code, "1..") then + try(tp:check("2..")) + end + self.data:close() + local sent = skipsocket(1, self.data:getstats()) + self.data = nil + return sent +end + +function methods.receive(self, recvt) + local try = self.try + local tp = self.tp + try(self.pasvt or self.server, "need port or pasv first") + if self.pasvt then self:pasvconnect() end + local argument = recvt.argument or unescapeurl(gsub(recvt.path or "", "^[/\\]", "")) + if argument == "" then + argument = nil + end + local command = recvt.command or "retr" + try(tp:command(command, argument)) + local code,reply = try(tp:check{"1..", "2.."}) + if code >= 200 and code <= 299 then + recvt.sink(reply) + return 1 + end + if not self.pasvt then + self:portconnect() + end + local source = sourcesocket("until-closed", self.data) + local step = recvt.step or pumpstep + try(pumpall(source, recvt.sink, step)) + if find(code, "1..") then + try(tp:check("2..")) + end + self.data:close() + self.data = nil + return 1 +end + +function methods.cwd(self, dir) + local try = self.try + local tp = self.tp + try(tp:command("cwd", dir)) + try(tp:check(250)) + return 1 +end + +function methods.type(self, typ) + local try = self.try + local tp = self.tp + try(tp:command("type", typ)) + try(tp:check(200)) + return 1 +end + +function methods.greet(self) + local try = self.try + local tp = self.tp + local code = try(tp:check{"1..", "2.."}) + if find(code, "1..") then + try(tp:check("2..")) + end + return 1 +end + +function methods.quit(self) + local try = self.try + try(self.tp:command("quit")) + try(self.tp:check("2..")) + return 1 +end + +function methods.close(self) + local data = self.data + if data then + data:close() + end + local server = self.server + if server then + server:close() + end + local tp = self.tp + if tp then + tp:close() + end +end + +local function override(t) + if t.url then + local u = parseurl(t.url) + for k, v in next, t do + u[k] = v + end + return u + else + return t + end +end + +local function tput(putt) + putt = override(putt) + local host = putt.host + trysocket(host, "missing hostname") + local f = ftp.open(host, putt.port, putt.create) + f:greet() + f:login(putt.user, putt.password) + local typ = putt.type + if typ then + f:type(typ) + end + f:epsv() + local sent = f:send(putt) + f:quit() + f:close() + return sent +end + +local default = { + path = "/", + scheme = "ftp", +} + +local function genericform(u) + local t = trysocket(parseurl(u, default)) + trysocket(t.scheme == "ftp", "wrong scheme '" .. t.scheme .. "'") + trysocket(t.host, "missing hostname") + local pat = "^type=(.)$" + if t.params then + local typ = skipsocket(2, find(t.params, pat)) + t.type = typ + trysocket(typ == "a" or typ == "i", "invalid type '" .. typ .. "'") + end + return t +end + +ftp.genericform = genericform + +local function sput(u, body) + local putt = genericform(u) + putt.source = sourcestring(body) + return tput(putt) +end + +ftp.put = protectsocket(function(putt, body) + if type(putt) == "string" then + return sput(putt, body) + else + return tput(putt) + end +end) + +local function tget(gett) + gett = override(gett) + local host = gett.host + trysocket(host, "missing hostname") + local f = ftp.open(host, gett.port, gett.create) + f:greet() + f:login(gett.user, gett.password) + if gett.type then + f:type(gett.type) + end + f:epsv() + f:receive(gett) + f:quit() + return f:close() +end + +local function sget(u) + local gett = genericform(u) + local t = { } + gett.sink = sinktable(t) + tget(gett) + return concat(t) +end + +ftp.command = protectsocket(function(cmdt) + cmdt = override(cmdt) + local command = cmdt.command + local argument = cmdt.argument + local check = cmdt.check + local host = cmdt.host + trysocket(host, "missing hostname") + trysocket(command, "missing command") + local f = ftp.open(host, cmdt.port, cmdt.create) + local try = f.try + local tp = f.tp + f:greet() + f:login(cmdt.user, cmdt.password) + if type(command) == "table" then + local argument = argument or { } + for i=1,#command do + local cmd = command[i] + try(tp:command(cmd, argument[i])) + if check and check[i] then + try(tp:check(check[i])) + end + end + else + try(tp:command(command, argument)) + if check then + try(tp:check(check)) + end + end + f:quit() + return f:close() +end) + +ftp.get = protectsocket(function(gett) + if type(gett) == "string" then + return sget(gett) + else + return tget(gett) + end +end) + +package.loaded["socket.ftp"] = ftp + +return ftp diff --git a/tex/context/base/mkiv/util-soc-imp-headers.lua b/tex/context/base/mkiv/util-soc-imp-headers.lua new file mode 100644 index 000000000..ef51910a5 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-headers.lua @@ -0,0 +1,145 @@ +-- original file : headers.lua +-- for more into : see util-soc.lua + +local next = next +local lower = string.lower +local concat = table.concat + +local socket = socket or require("socket") + +local headers = { } +socket.headers = headers + +local canonic = { + ["accept"] = "Accept", + ["accept-charset"] = "Accept-Charset", + ["accept-encoding"] = "Accept-Encoding", + ["accept-language"] = "Accept-Language", + ["accept-ranges"] = "Accept-Ranges", + ["action"] = "Action", + ["alternate-recipient"] = "Alternate-Recipient", + ["age"] = "Age", + ["allow"] = "Allow", + ["arrival-date"] = "Arrival-Date", + ["authorization"] = "Authorization", + ["bcc"] = "Bcc", + ["cache-control"] = "Cache-Control", + ["cc"] = "Cc", + ["comments"] = "Comments", + ["connection"] = "Connection", + ["content-description"] = "Content-Description", + ["content-disposition"] = "Content-Disposition", + ["content-encoding"] = "Content-Encoding", + ["content-id"] = "Content-ID", + ["content-language"] = "Content-Language", + ["content-length"] = "Content-Length", + ["content-location"] = "Content-Location", + ["content-md5"] = "Content-MD5", + ["content-range"] = "Content-Range", + ["content-transfer-encoding"] = "Content-Transfer-Encoding", + ["content-type"] = "Content-Type", + ["cookie"] = "Cookie", + ["date"] = "Date", + ["diagnostic-code"] = "Diagnostic-Code", + ["dsn-gateway"] = "DSN-Gateway", + ["etag"] = "ETag", + ["expect"] = "Expect", + ["expires"] = "Expires", + ["final-log-id"] = "Final-Log-ID", + ["final-recipient"] = "Final-Recipient", + ["from"] = "From", + ["host"] = "Host", + ["if-match"] = "If-Match", + ["if-modified-since"] = "If-Modified-Since", + ["if-none-match"] = "If-None-Match", + ["if-range"] = "If-Range", + ["if-unmodified-since"] = "If-Unmodified-Since", + ["in-reply-to"] = "In-Reply-To", + ["keywords"] = "Keywords", + ["last-attempt-date"] = "Last-Attempt-Date", + ["last-modified"] = "Last-Modified", + ["location"] = "Location", + ["max-forwards"] = "Max-Forwards", + ["message-id"] = "Message-ID", + ["mime-version"] = "MIME-Version", + ["original-envelope-id"] = "Original-Envelope-ID", + ["original-recipient"] = "Original-Recipient", + ["pragma"] = "Pragma", + ["proxy-authenticate"] = "Proxy-Authenticate", + ["proxy-authorization"] = "Proxy-Authorization", + ["range"] = "Range", + ["received"] = "Received", + ["received-from-mta"] = "Received-From-MTA", + ["references"] = "References", + ["referer"] = "Referer", + ["remote-mta"] = "Remote-MTA", + ["reply-to"] = "Reply-To", + ["reporting-mta"] = "Reporting-MTA", + ["resent-bcc"] = "Resent-Bcc", + ["resent-cc"] = "Resent-Cc", + ["resent-date"] = "Resent-Date", + ["resent-from"] = "Resent-From", + ["resent-message-id"] = "Resent-Message-ID", + ["resent-reply-to"] = "Resent-Reply-To", + ["resent-sender"] = "Resent-Sender", + ["resent-to"] = "Resent-To", + ["retry-after"] = "Retry-After", + ["return-path"] = "Return-Path", + ["sender"] = "Sender", + ["server"] = "Server", + ["smtp-remote-recipient"] = "SMTP-Remote-Recipient", + ["status"] = "Status", + ["subject"] = "Subject", + ["te"] = "TE", + ["to"] = "To", + ["trailer"] = "Trailer", + ["transfer-encoding"] = "Transfer-Encoding", + ["upgrade"] = "Upgrade", + ["user-agent"] = "User-Agent", + ["vary"] = "Vary", + ["via"] = "Via", + ["warning"] = "Warning", + ["will-retry-until"] = "Will-Retry-Until", + ["www-authenticate"] = "WWW-Authenticate", + ["x-mailer"] = "X-Mailer", +} + +headers.canonic = setmetatable(canonic, { + __index = function(t,k) + socket.report("invalid header: %s",k) + t[k] = k + return k + end +}) + +function headers.normalize(headers) + if not headers then + return { } + end + local normalized = { } + for k, v in next, headers do + normalized[#normalized+1] = canonic[k] .. ": " .. v + end + normalized[#normalized+1] = "" + normalized[#normalized+1] = "" + return concat(normalized,"\r\n") +end + +function headers.lower(lowered,headers) + if not lowered then + return { } + end + if not headers then + lowered, headers = { }, lowered + end + for k, v in next, headers do + lowered[lower(k)] = v + end + return lowered +end + +socket.headers = headers + +package.loaded["socket.headers"] = headers + +return headers diff --git a/tex/context/base/mkiv/util-soc-imp-http.lua b/tex/context/base/mkiv/util-soc-imp-http.lua new file mode 100644 index 000000000..c3a28be82 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-http.lua @@ -0,0 +1,436 @@ +-- original file : http.lua +-- for more into : see util-soc.lua + +local tostring, tonumber, setmetatable, next, type = tostring, tonumber, setmetatable, next, type +local find, lower, format, gsub, match = string.find, string.lower, string.format, string.gsub, string.match +local concat = table.concat + +local socket = socket or require("socket") +local url = socket.url or require("socket.url") +local ltn12 = ltn12 or require("ltn12") +local mime = mime or require("mime") +local headers = socket.headers or require("socket.headers") + +local normalizeheaders = headers.normalize + +local parseurl = url.parse +local buildurl = url.build +local absoluteurl = url.absolute +local unescapeurl = url.unescape + +local skipsocket = socket.skip +local sinksocket = socket.sink +local sourcesocket = socket.source +local trysocket = socket.try +local tcpsocket = socket.tcp +local newtrysocket = socket.newtry +local protectsocket = socket.protect + +local emptysource = ltn12.source.empty +local stringsource = ltn12.source.string +local rewindsource = ltn12.source.rewind +local pumpstep = ltn12.pump.step +local pumpall = ltn12.pump.all +local sinknull = ltn12.sink.null +local sinktable = ltn12.sink.table + +local lowerheaders = headers.lower + +local mimeb64 = mime.b64 + +-- todo: localize ltn12 + +local http = { + TIMEOUT = 60, -- connection timeout in seconds + USERAGENT = socket._VERSION, -- user agent field sent in request +} + +socket.http = http + +local PORT = 80 +local SCHEMES = { + http = true, +} + +-- Reads MIME headers from a connection, unfolding where needed + +local function receiveheaders(sock, headers) + if not headers then + headers = { } + end + -- get first line + local line, err = sock:receive() + if err then + return nil, err + end + -- headers go until a blank line is found + while line ~= "" do + -- get field-name and value + local name, value = skipsocket(2, find(line, "^(.-):%s*(.*)")) + if not (name and value) then + return nil, "malformed reponse headers" + end + name = lower(name) + -- get next line (value might be folded) + line, err = sock:receive() + if err then + return nil, err + end + -- unfold any folded values + while find(line, "^%s") do + value = value .. line + line = sock:receive() + if err then + return nil, err + end + end + -- save pair in table + local found = headers[name] + if found then + value = found .. ", " .. value + end + headers[name] = value + end + return headers +end + +-- Extra sources and sinks + +socket.sourcet["http-chunked"] = function(sock, headers) + return setmetatable ( + { + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end, + }, { + __call = function() + local line, err = sock:receive() + if err then + return nil, err + end + local size = tonumber(gsub(line, ";.*", ""), 16) + if not size then + return nil, "invalid chunk size" + end + if size > 0 then + local chunk, err, part = sock:receive(size) + if chunk then + sock:receive() + end + return chunk, err + else + headers, err = receiveheaders(sock, headers) + if not headers then + return nil, err + end + end + end + } + ) +end + +socket.sinkt["http-chunked"] = function(sock) + return setmetatable( + { + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end, + }, + { + __call = function(self, chunk, err) + if not chunk then + chunk = "" + end + return sock:send(format("%X\r\n%s\r\n",#chunk,chunk)) + end + }) +end + +-- Low level HTTP API + +local methods = { } +local mt = { __index = methods } + +local function openhttp(host, port, create) + local c = trysocket((create or tcpsocket)()) + local h = setmetatable({ c = c }, mt) + local try = newtrysocket(function() h:close() end) + h.try = try + try(c:settimeout(http.TIMEOUT)) + try(c:connect(host, port or PORT)) + return h +end + +http.open = openhttp + +function methods.sendrequestline(self, method, uri) + local requestline = format("%s %s HTTP/1.1\r\n", method or "GET", uri) + return self.try(self.c:send(requestline)) +end + +function methods.sendheaders(self,headers) + self.try(self.c:send(normalizeheaders(headers))) + return 1 +end + +function methods.sendbody(self, headers, source, step) + if not source then + source = emptysource() + end + if not step then + step = pumpstep + end + local mode = "http-chunked" + if headers["content-length"] then + mode = "keep-open" + end + return self.try(pumpall(source, sinksocket(mode, self.c), step)) +end + +function methods.receivestatusline(self) + local try = self.try + local status = try(self.c:receive(5)) + if status ~= "HTTP/" then + return nil, status -- HTTP/0.9 + end + status = try(self.c:receive("*l", status)) + local code = skipsocket(2, find(status, "HTTP/%d*%.%d* (%d%d%d)")) + return try(tonumber(code), status) +end + +function methods.receiveheaders(self) + return self.try(receiveheaders(self.c)) +end + +function methods.receivebody(self, headers, sink, step) + if not sink then + sink = sinknull() + end + if not step then + step = pumpstep + end + local length = tonumber(headers["content-length"]) + local encoding = headers["transfer-encoding"] -- shortcut + local mode = "default" -- connection close + if encoding and encoding ~= "identity" then + mode = "http-chunked" + elseif length then + mode = "by-length" + end + --hh: so length can be nil + return self.try(pumpall(sourcesocket(mode, self.c, length), sink, step)) +end + +function methods.receive09body(self, status, sink, step) + local source = rewindsource(sourcesocket("until-closed", self.c)) + source(status) + return self.try(pumpall(source, sink, step)) +end + +function methods.close(self) + return self.c:close() +end + +-- High level HTTP API + +local function adjusturi(request) + if not request.proxy and not http.PROXY then + request = { + path = trysocket(request.path, "invalid path 'nil'"), + params = request.params, + query = request.query, + fragment = request.fragment, + } + end + return buildurl(request) +end + +local function adjustheaders(request) + local headers = { + ["user-agent"] = http.USERAGENT, + ["host"] = gsub(request.authority, "^.-@", ""), + ["connection"] = "close, TE", + ["te"] = "trailers" + } + local username = request.user + local password = request.password + if username and password then + headers["authorization"] = "Basic " .. (mimeb64(username .. ":" .. unescapeurl(password))) + end + local proxy = request.proxy or http.PROXY + if proxy then + proxy = parseurl(proxy) + local username = proxy.user + local password = proxy.password + if username and password then + headers["proxy-authorization"] = "Basic " .. (mimeb64(username .. ":" .. password)) + end + end + local requestheaders = request.headers + if requestheaders then + headers = lowerheaders(headers,requestheaders) + end + return headers +end + +-- default url parts + +local default = { + host = "", + port = PORT, + path = "/", + scheme = "http" +} + +local function adjustrequest(originalrequest) + local url = originalrequest.url + local request = url and parseurl(url,default) or { } + for k, v in next, originalrequest do + request[k] = v + end + local host = request.host + local port = request.port + local uri = request.uri + if not host or host == "" then + trysocket(nil, "invalid host '" .. tostring(host) .. "'") + end + if port == "" then + request.port = PORT + end + if not uri or uri == "" then + request.uri = adjusturi(request) + end + request.headers = adjustheaders(request) + local proxy = request.proxy or http.PROXY + if proxy then + proxy = parseurl(proxy) + request.host = proxy.host + request.port = proxy.port or 3128 + end + return request +end + +local maxredericts = 4 +local validredirects = { [301] = true, [302] = true, [303] = true, [307] = true } +local validmethods = { [false] = true, GET = true, HEAD = true } + +local function shouldredirect(request, code, headers) + local location = headers.location + if not location then + return false + end + location = gsub(location, "%s", "") + if location == "" then + return false + end + local scheme = match(location, "^([%w][%w%+%-%.]*)%:") + if scheme and not SCHEMES[scheme] then + return false + end + local method = request.method + local redirect = request.redirect + local redirects = request.nredirects or 0 + return redirect and validredirects[code] and validmethods[method] and redirects <= maxredericts +end + +local function shouldreceivebody(request, code) + if request.method == "HEAD" then + return nil + end + if code == 204 or code == 304 then + return nil + end + if code >= 100 and code < 200 then + return nil + end + return 1 +end + +local tredirect, trequest, srequest + +tredirect = function(request, location) + local result, code, headers, status = trequest { + url = absoluteurl(request.url,location), + source = request.source, + sink = request.sink, + headers = request.headers, + proxy = request.proxy, + nredirects = (request.nredirects or 0) + 1, + create = request.create, + } + if not headers then + headers = { } + end + if not headers.location then + headers.location = location + end + return result, code, headers, status +end + +trequest = function(originalrequest) + local request = adjustrequest(originalrequest) + local connection = openhttp(request.host, request.port, request.create) + local headers = request.headers + connection:sendrequestline(request.method, request.uri) + connection:sendheaders(headers) + if request.source then + connection:sendbody(headers, request.source, request.step) + end + local code, status = connection:receivestatusline() + if not code then + connection:receive09body(status, request.sink, request.step) + return 1, 200 + end + while code == 100 do + headers = connection:receiveheaders() + code, status = connection:receivestatusline() + end + headers = connection:receiveheaders() + if shouldredirect(request, code, headers) and not request.source then + connection:close() + return tredirect(originalrequest,headers.location) + end + if shouldreceivebody(request, code) then + connection:receivebody(headers, request.sink, request.step) + end + connection:close() + return 1, code, headers, status +end + +-- turns an url and a body into a generic request + +local function genericform(url, body) + local buffer = { } + local request = { + url = url, + sink = sinktable(buffer), + target = buffer, + } + if body then + request.source = stringsource(body) + request.method = "POST" + request.headers = { + ["content-length"] = #body, + ["content-type"] = "application/x-www-form-urlencoded" + } + end + return request +end + +http.genericform = genericform + +srequest = function(url, body) + local request = genericform(url, body) + local _, code, headers, status = trequest(request) + return concat(request.target), code, headers, status +end + +http.request = protectsocket(function(request, body) + if type(request) == "string" then + return srequest(request, body) + else + return trequest(request) + end +end) + +package.loaded["socket.http"] = http + +return http diff --git a/tex/context/base/mkiv/util-soc-imp-ltn12.lua b/tex/context/base/mkiv/util-soc-imp-ltn12.lua new file mode 100644 index 000000000..54110ab7a --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-ltn12.lua @@ -0,0 +1,387 @@ +-- original file : ltn12.lua +-- for more into : see util-soc.lua + +local select, unpack = select, unpack +local insert, remove = table.insert, table.remove +local sub = string.sub + +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("ltn12") + report(fmt,first,...) + elseif fmt then + fmt = "ltn12: " .. fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end + +local filter = { } +local source = { } +local sink = { } +local pump = { } + +local ltn12 = { + + _VERSION = "LTN12 1.0.3", + + BLOCKSIZE = 2048, + + filter = filter, + source = source, + sink = sink, + pump = pump, + + report = report, + +} + +-- returns a high level filter that cycles a low-level filter + +function filter.cycle(low, ctx, extra) + if low then + return function(chunk) + return (low(ctx, chunk, extra)) + end + end +end + +-- chains a bunch of filters together + +function filter.chain(...) + local arg = { ... } + local n = select('#',...) + local top = 1 + local index = 1 + local retry = "" + return function(chunk) + retry = chunk and retry + while true do + local action = arg[index] + if index == top then + chunk = action(chunk) + if chunk == "" or top == n then + return chunk + elseif chunk then + index = index + 1 + else + top = top + 1 + index = top + end + else + chunk = action(chunk or "") + if chunk == "" then + index = index - 1 + chunk = retry + elseif chunk then + if index == n then + return chunk + else + index = index + 1 + end + else + report("error: filter returned inappropriate 'nil'") + return + end + end + end + end +end + +-- create an empty source + +local function empty() + return nil +end + +function source.empty() + return empty +end + +-- returns a source that just outputs an error + +local function sourceerror(err) + return function() + return nil, err + end +end + +source.error = sourceerror + +-- creates a file source + +function source.file(handle, io_err) + if handle then + local blocksize = ltn12.BLOCKSIZE + return function() + local chunk = handle:read(blocksize) + if not chunk then + handle:close() + end + return chunk + end + else + return sourceerror(io_err or "unable to open file") + end +end + +-- turns a fancy source into a simple source + +function source.simplify(src) + return function() + local chunk, err_or_new = src() + if err_or_new then + src = err_or_new + end + if chunk then + return chunk + else + return nil, err_or_new + end + end +end + +-- creates string source + +function source.string(s) + if s then + local blocksize = ltn12.BLOCKSIZE + local i = 1 + return function() + local nexti = i + blocksize + local chunk = sub(s, i, nexti - 1) + i = nexti + if chunk ~= "" then + return chunk + else + return nil + end + end + else return source.empty() end +end + +-- creates rewindable source + +function source.rewind(src) + local t = { } + return function(chunk) + if chunk then + insert(t, chunk) + else + chunk = remove(t) + if chunk then + return chunk + else + return src() + end + end + end +end + +-- chains a source with one or several filter(s) + +function source.chain(src, f, ...) + if ... then + f = filter.chain(f, ...) + end + local last_in = "" + local last_out = "" + local state = "feeding" + local err + return function() + if not last_out then + report("error: source is empty") + return + end + while true do + if state == "feeding" then + last_in, err = src() + if err then + return nil, err + end + last_out = f(last_in) + if not last_out then + if last_in then + report("error: filter returned inappropriate 'nil'") + end + return nil + elseif last_out ~= "" then + state = "eating" + if last_in then + last_in = "" + end + return last_out + end + else + last_out = f(last_in) + if last_out == "" then + if last_in == "" then + state = "feeding" + else + report("error: filter returned nothing") + return + end + elseif not last_out then + if last_in then + report("filter returned inappropriate 'nil'") + end + return nil + else + return last_out + end + end + end + end +end + +-- creates a source that produces contents of several sources, one after the +-- other, as if they were concatenated + +function source.cat(...) + local arg = { ... } + local src = remove(arg,1) + return function() + while src do + local chunk, err = src() + if chunk then + return chunk + end + if err then + return nil, err + end + src = remove(arg,1) + end + end +end + +-- creates a sink that stores into a table + +function sink.table(t) + if not t then + t = { } + end + local f = function(chunk, err) + if chunk then + insert(t, chunk) + end + return 1 + end + return f, t +end + +-- turns a fancy sink into a simple sink + +function sink.simplify(snk) + return function(chunk, err) + local ret, err_or_new = snk(chunk, err) + if not ret then + return nil, err_or_new + end + if err_or_new then + snk = err_or_new + end + return 1 + end +end + +-- creates a sink that discards data + +local function null() + return 1 +end + +function sink.null() + return null +end + +-- creates a sink that just returns an error + +local function sinkerror(err) + return function() + return nil, err + end +end + +sink.error = sinkerror + +-- creates a file sink + +function sink.file(handle, io_err) + if handle then + return function(chunk, err) + if not chunk then + handle:close() + return 1 + else + return handle:write(chunk) + end + end + else + return sinkerror(io_err or "unable to open file") + end +end + +-- chains a sink with one or several filter(s) + +function sink.chain(f, snk, ...) + if ... then + local args = { f, snk, ... } + snk = remove(args, #args) + f = filter.chain(unpack(args)) + end + return function(chunk, err) + if chunk ~= "" then + local filtered = f(chunk) + local done = chunk and "" + while true do + local ret, snkerr = snk(filtered, err) + if not ret then + return nil, snkerr + end + if filtered == done then + return 1 + end + filtered = f(done) + end + else + return 1 + end + end +end + +-- pumps one chunk from the source to the sink + +function pump.step(src, snk) + local chunk, src_err = src() + local ret, snk_err = snk(chunk, src_err) + if chunk and ret then + return 1 + else + return nil, src_err or snk_err + end +end + +-- pumps all data from a source to a sink, using a step function + +function pump.all(src, snk, step) + if not step then + step = pump.step + end + while true do + local ret, err = step(src, snk) + if not ret then + if err then + return nil, err + else + return 1 + end + end + end +end + +package.loaded["ltn12"] = ltn12 + +return ltn12 diff --git a/tex/context/base/mkiv/util-soc-imp-mime.lua b/tex/context/base/mkiv/util-soc-imp-mime.lua new file mode 100644 index 000000000..4b5d2baff --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-mime.lua @@ -0,0 +1,104 @@ +-- original file : mime.lua +-- for more into : see util-soc.lua + +local type, tostring = type, tostring + +local mime = require("mime.core") +local ltn12 = ltn12 or require("ltn12") + +local filtercycle = ltn12.filter.cycle + +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("mime") + report(fmt,first,...) + elseif fmt then + fmt = "mime: " .. fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end + +mime.report = report + +local encodet = { } +local decodet = { } +local wrapt = { } + +mime.encodet = encodet +mime.decodet = decodet +mime.wrapt = wrapt + +local mime_b64 = mime.b64 +local mime_qp = mime.qp +local mime_unb64 = mime.unb64 +local mime_unqp = mime.unqp +local mime_wrp = mime.wrp +local mime_qpwrp = mime.qpwrp +local mime_eol = mime_eol +local mime_dot = mime_dot + +encodet['base64'] = function() + return filtercycle(mime_b64,"") +end + +encodet['quoted-printable'] = function(mode) + return filtercycle(mime_qp, "", mode == "binary" and "=0D=0A" or "\r\n") +end + +decodet['base64'] = function() + return filtercycle(mime_unb64, "") +end + +decodet['quoted-printable'] = function() + return filtercycle(mime_unqp, "") +end + +local wraptext = function(length) + if not length then + length = 76 + end + return filtercycle(mime_wrp, length, length) +end + +local wrapquoted = function() + return filtercycle(mime_qpwrp, 76, 76) +end + +wrapt['text'] = wraptext +wrapt['base64'] = wraptext +wrapt['default'] = wraptext +wrapt['quoted-printable'] = wrapquoted + +function mime.normalize(marker) + return filtercycle(mime_eol, 0, marker) +end + +function mime.stuff() + return filtercycle(mime_dot, 2) +end + +local function choose(list) + return function(name, opt1, opt2) + if type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local filter = list[name or "nil"] + if filter then + return filter(opt1, opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end + +mime.encode = choose(encodet) +mime.decode = choose(decodet) +mime.wrap = choose(wrapt) + +package.loaded["mime"] = mime + +return mime diff --git a/tex/context/base/mkiv/util-soc-imp-reset.lua b/tex/context/base/mkiv/util-soc-imp-reset.lua new file mode 100644 index 000000000..a4a489b0f --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-reset.lua @@ -0,0 +1,13 @@ +local loaded = package.loaded + +loaded["socket"] = nil +loaded["copas"] = nil +loaded["ltn12"] = nil +loaded["mbox"] = nil +loaded["mime"] = nil +loaded["socket.url"] = nil +loaded["socket.headers"] = nil +loaded["socket.tp"] = nil +loaded["socket.http"] = nil +loaded["socket.ftp"] = nil +loaded["socket.smtp"] = nil diff --git a/tex/context/base/mkiv/util-soc-imp-smtp.lua b/tex/context/base/mkiv/util-soc-imp-smtp.lua new file mode 100644 index 000000000..621d1b6e3 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-smtp.lua @@ -0,0 +1,267 @@ +-- original file : smtp.lua +-- for more into : see util-soc.lua + +local type, setmetatable, next = type, setmetatable, next +local find, lower, format = string.find, string.lower, string.format +local osdate, osgetenv = os.date, os.getenv +local random = math.random + +local socket = socket or require("socket") +local headers = socket.headers or require("socket.headers") +local ltn12 = ltn12 or require("ltn12") +local tp = socket.tp or require("socket.tp") +local mime = mime or require("mime") + +local mimeb64 = mime.b64 +local mimestuff = mime.stuff + +local skipsocket = socket.skip +local trysocket = socket.try +local newtrysocket = socket.newtry +local protectsocket = socket.protect + +local normalizeheaders = headers.normalize +local lowerheaders = headers.lower + +local createcoroutine = coroutine.create +local resumecoroutine = coroutine.resume +local yieldcoroutine = coroutine.resume + +local smtp = { + TIMEOUT = 60, + SERVER = "localhost", + PORT = 25, + DOMAIN = osgetenv("SERVER_NAME") or "localhost", + ZONE = "-0000", +} + +socket.smtp = smtp + +local methods = { } +local mt = { __index = methods } + +function methods.greet(self, domain) + local try = self.try + local tp = self.tp + try(tp:check("2..")) + try(tp:command("EHLO", domain or _M.DOMAIN)) + return skipsocket(1, try(tp:check("2.."))) +end + +function methods.mail(self, from) + local try = self.try + local tp = self.tp + try(tp:command("MAIL", "FROM:" .. from)) + return try(tp:check("2..")) +end + +function methods.rcpt(self, to) + local try = self.try + local tp = self.tp + try(tp:command("RCPT", "TO:" .. to)) + return try(tp:check("2..")) +end + +function methods.data(self, src, step) + local try = self.try + local tp = self.tp + try(tp:command("DATA")) + try(tp:check("3..")) + try(tp:source(src, step)) + try(tp:send("\r\n.\r\n")) + return try(tp:check("2..")) +end + +function methods.quit(self) + local try = self.try + local tp = self.tp + try(tp:command("QUIT")) + return try(tp:check("2..")) +end + +function methods.close(self) + return self.tp:close() +end + +function methods.login(self, user, password) + local try = self.try + local tp = self.tp + try(tp:command("AUTH", "LOGIN")) + try(tp:check("3..")) + try(tp:send(mimeb64(user) .. "\r\n")) + try(tp:check("3..")) + try(tp:send(mimeb64(password) .. "\r\n")) + return try(tp:check("2..")) +end + +function methods.plain(self, user, password) + local try = self.try + local tp = self.tp + local auth = "PLAIN " .. mimeb64("\0" .. user .. "\0" .. password) + try(tp:command("AUTH", auth)) + return try(tp:check("2..")) +end + +function methods.auth(self, user, password, ext) + if not user or not password then + return 1 + end + local try = self.try + if find(ext, "AUTH[^\n]+LOGIN") then + return self:login(user,password) + elseif find(ext, "AUTH[^\n]+PLAIN") then + return self:plain(user,password) + else + try(nil, "authentication not supported") + end +end + +function methods.send(self, mail) + self:mail(mail.from) + local receipt = mail.rcpt + if type(receipt) == "table" then + for i=1,#receipt do + self:rcpt(receipt[i]) + end + elseif receipt then + self:rcpt(receipt) + end + self:data(ltn12.source.chain(mail.source, mimestuff()), mail.step) +end + +local function opensmtp(self, server, port, create) + if not server or server == "" then + server = smtp.SERVER + end + if not port or port == "" then + port = smtp.PORT + end + local s = { + tp = trysocket(tp.connect(server, port, smtp.TIMEOUT, create)), + try = newtrysocket(function() + s:close() + end), + } + setmetatable(s, mt) + return s +end + +smtp.open = opensmtp + +local nofboundaries = 0 + +local function newboundary() + nofboundaries = nofboundaries + 1 + return format('%s%05d==%05u', osdate('%d%m%Y%H%M%S'), random(0,99999), nofboundaries) +end + +local send_message + +local function send_headers(headers) + yieldcoroutine(normalizeheaders(headers)) +end + +local function send_multipart(message) + local boundary = newboundary() + local headers = lowerheaders(message.headers) + local body = message.body + local preamble = body.preamble + local epilogue = body.epilogue + local content = headers['content-type'] or 'multipart/mixed' + headers['content-type'] = content .. '; boundary="' .. boundary .. '"' + send_headers(headers) + if preamble then + yieldcoroutine(preamble) + yieldcoroutine("\r\n") + end + for i=1,#body do + yieldcoroutine("\r\n--" .. boundary .. "\r\n") + send_message(body[i]) + end + yieldcoroutine("\r\n--" .. boundary .. "--\r\n\r\n") + if epilogue then + yieldcoroutine(epilogue) + yieldcoroutine("\r\n") + end +end + +local default_content_type = 'text/plain; charset="UTF-8"' + +local function send_source(message) + local headers = lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type'] = default_content_type + end + send_headers(headers) + local getchunk = message.body + while true do + local chunk, err = getchunk() + if err then + yieldcoroutine(nil, err) + elseif chunk then + yieldcoroutine(chunk) + else + break + end + end +end + +local function send_string(message) + local headers = lowerheaders(message.headers) + if not headers['content-type'] then + headers['content-type'] = default_content_type + end + send_headers(headers) + yieldcoroutine(message.body) +end + +function send_message(message) + local body = message.body + if type(body) == "table" then + send_multipart(message) + elseif type(body) == "function" then + send_source(message) + else + send_string(message) + end +end + +local function adjust_headers(message) + local headers = lowerheaders(message.headers) + if not headers["date"] then + headers["date"] = osdate("!%a, %d %b %Y %H:%M:%S ") .. (message.zone or smtp.ZONE) + end + if not headers["x-mailer"] then + headers["x-mailer"] = socket._VERSION + end + headers["mime-version"] = "1.0" + return headers +end + +function smtp.message(message) + message.headers = adjust_headers(message) + local action = createcoroutine(function() + send_message(message) + end) + return function() + local ret, a, b = resumecoroutine(action) + if ret then + return a, b + else + return nil, a + end + end +end + +smtp.send = protectsocket(function(mail) + local snd = opensmtp(smtp,mail.server, mail.port, mail.create) + local ext = snd:greet(mail.domain) + snd:auth(mail.user, mail.password, ext) + snd:send(mail) + snd:quit() + return snd:close() +end) + +package.loaded["socket.smtp"] = smtp + +return smtp diff --git a/tex/context/base/mkiv/util-soc-imp-socket.lua b/tex/context/base/mkiv/util-soc-imp-socket.lua new file mode 100644 index 000000000..3da155749 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-socket.lua @@ -0,0 +1,193 @@ +-- original file : socket.lua +-- for more into : see util-soc.lua + +local type, tostring, setmetatable = type, tostring, setmetatable +local min = math.min +local format = string.format + +local socket = require("socket.core") + +local connect = socket.connect +local tcp4 = socket.tcp4 +local tcp6 = socket.tcp6 +local getaddrinfo = socket.dns.getaddrinfo + +local defaulthost = "0.0.0.0" + +local function report(fmt,first,...) + if logs then + report = logs and logs.reporter("socket") + report(fmt,first,...) + elseif fmt then + fmt = "socket: " .. fmt + if first then + print(format(fmt,first,...)) + else + print(fmt) + end + end +end + +socket.report = report + +function socket.connect4(address, port, laddress, lport) + return connect(address, port, laddress, lport, "inet") +end + +function socket.connect6(address, port, laddress, lport) + return connect(address, port, laddress, lport, "inet6") +end + +function socket.bind(host, port, backlog) + if host == "*" or host == "" then + host = defaulthost + end + local addrinfo, err = getaddrinfo(host) + if not addrinfo then + return nil, err + end + for i=1,#addrinfo do + local alt = addrinfo[i] + local sock, err = (alt.family == "inet" and tcp4 or tcp6)() + if not sock then + return nil, err or "unknown error" + end + sock:setoption("reuseaddr", true) + local res, err = sock:bind(alt.addr, port) + if res then + res, err = sock:listen(backlog) + if res then + return sock + else + sock:close() + end + else + sock:close() + end + end + return nil, "invalid address" +end + +socket.try = socket.newtry() + +function socket.choose(list) + return function(name, opt1, opt2) + if type(name) ~= "string" then + name, opt1, opt2 = "default", name, opt1 + end + local f = list[name or "nil"] + if f then + return f(opt1, opt2) + else + report("error: unknown key '%s'",tostring(name)) + end + end +end + +local sourcet = { } +local sinkt = { } + +socket.sourcet = sourcet +socket.sinkt = sinkt + +socket.BLOCKSIZE = 2048 + +sinkt["close-when-done"] = function(sock) + return setmetatable ( + { + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end, + }, + { + __call = function(self, chunk, err) + if chunk then + return sock:send(chunk) + else + sock:close() + return 1 -- why 1 + end + end + } + ) +end + +sinkt["keep-open"] = function(sock) + return setmetatable ( + { + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end, + }, { + __call = function(self, chunk, err) + if chunk then + return sock:send(chunk) + else + return 1 -- why 1 + end + end + } + ) +end + +sinkt["default"] = sinkt["keep-open"] + +socket.sink = socket.choose(sinkt) + +sourcet["by-length"] = function(sock, length) + local blocksize = socket.BLOCKSIZE + return setmetatable ( + { + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end, + }, + { + __call = function() + if length <= 0 then + return nil + end + local chunk, err = sock:receive(min(blocksize,length)) + if err then + return nil, err + end + length = length - #chunk + return chunk + end + } + ) +end + +sourcet["until-closed"] = function(sock) + local blocksize = socket.BLOCKSIZE + local done = false + return setmetatable ( + { + getfd = function() return sock:getfd() end, + dirty = function() return sock:dirty() end, + }, { + __call = function() + if done then + return nil + end + local chunk, status, partial = sock:receive(blocksize) + if not status then + return chunk + elseif status == "closed" then + sock:close() + done = true + return partial + else + return nil, status + end + end + } + ) +end + +sourcet["default"] = sourcet["until-closed"] + +socket.source = socket.choose(sourcet) + +_G.socket = socket -- for now global + +package.loaded["socket"] = socket + +return socket diff --git a/tex/context/base/mkiv/util-soc-imp-tp.lua b/tex/context/base/mkiv/util-soc-imp-tp.lua new file mode 100644 index 000000000..e651e44f7 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-tp.lua @@ -0,0 +1,144 @@ +-- original file : tp.lua +-- for more into : see util-soc.lua + +local setmetatable, next, type, tonumber = setmetatable, next, type, tonumber +local find, upper = string.find, string.upper + +local socket = socket or require("socket") +local ltn12 = ltn12 or require("ltn12") + +local skipsocket = socket.skip +local sinksocket = socket.sink +local tcpsocket = socket.tcp + +local ltn12pump = ltn12.pump +local pumpall = ltn12pump.all +local pumpstep = ltn12pump.step + +local tp = { + TIMEOUT = 60, +} + +socket.tp = tp + +local function get_reply(c) + local line, err = c:receive() + local reply = line + if err then return + nil, err + end + local code, sep = skipsocket(2, find(line, "^(%d%d%d)(.?)")) + if not code then + return nil, "invalid server reply" + end + if sep == "-" then + local current + repeat + line, err = c:receive() + if err then + return nil, err + end + current, sep = skipsocket(2, find(line, "^(%d%d%d)(.?)")) + reply = reply .. "\n" .. line + until code == current and sep == " " + end + return code, reply +end + +local methods = { } +local mt = { __index = methods } + +function methods.getpeername(self) + return self.c:getpeername() +end + +function methods.getsockname(self) + return self.c:getpeername() +end + +function methods.check(self, ok) + local code, reply = get_reply(self.c) + if not code then + return nil, reply + end + local c = tonumber(code) + local t = type(ok) + if t == "function" then + return ok(c,reply) + elseif t == "table" then + for i=1,#ok do + if find(code,ok[i]) then + return c, reply + end + end + return nil, reply + elseif find(code, ok) then + return c, reply + else + return nil, reply + end +end + +function methods.command(self, cmd, arg) + cmd = upper(cmd) + if arg then + cmd = cmd .. " " .. arg .. "\r\n" + else + cmd = cmd .. "\r\n" + end + return self.c:send(cmd) +end + +function methods.sink(self, snk, pat) + local chunk, err = self.c:receive(pat) + return snk(chunk, err) +end + +function methods.send(self, data) + return self.c:send(data) +end + +function methods.receive(self, pat) + return self.c:receive(pat) +end + +function methods.getfd(self) + return self.c:getfd() +end + +function methods.dirty(self) + return self.c:dirty() +end + +function methods.getcontrol(self) + return self.c +end + +function methods.source(self, source, step) + local sink = sinksocket("keep-open", self.c) + local ret, err = pumpall(source, sink, step or pumpstep) + return ret, err +end + +function methods.close(self) + self.c:close() + return 1 +end + +function tp.connect(host, port, timeout, create) + local c, e = (create or tcpsocket)() + if not c then + return nil, e + end + c:settimeout(timeout or tp.TIMEOUT) + local r, e = c:connect(host, port) + if not r then + c:close() + return nil, e + end + return setmetatable({ c = c }, mt) +end + +package.loaded["socket.tp"] = tp + +return tp diff --git a/tex/context/base/mkiv/util-soc-imp-url.lua b/tex/context/base/mkiv/util-soc-imp-url.lua new file mode 100644 index 000000000..fa472b650 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-url.lua @@ -0,0 +1,268 @@ +-- original file : url.lua +-- for more into : see util-soc.lua + +local tonumber, tostring, type = tonumber, tostring, type + +local gsub, sub, match, find, format, byte, char = string.gsub, string.sub, string.match, string.find, string.format, string.byte, string.char +local insert = table.insert + +local socket = socket or require("socket") + +local url = { + _VERSION = "URL 1.0.3", +} + +socket.url = url + +function url.escape(s) + return (gsub(s, "([^A-Za-z0-9_])", function(c) + return format("%%%02x", byte(c)) + end)) +end + +local function make_set(t) -- table.tohash + local s = { } + for i=1,#t do + s[t[i]] = true + end + return s +end + +local segment_set = make_set { + "-", "_", ".", "!", "~", "*", "'", "(", + ")", ":", "@", "&", "=", "+", "$", ",", +} + +local function protect_segment(s) + return gsub(s, "([^A-Za-z0-9_])", function(c) + if segment_set[c] then + return c + else + return format("%%%02X", byte(c)) + end + end) +end + +function url.unescape(s) + return (gsub(s, "%%(%x%x)", function(hex) + return char(tonumber(hex,16)) + end)) +end + +local function absolute_path(base_path, relative_path) + if find(relative_path,"^/") then + return relative_path + end + local path = gsub(base_path, "[^/]*$", "") + path = path .. relative_path + path = gsub(path, "([^/]*%./)", function (s) + if s ~= "./" then + return s + else + return "" + end + end) + path = gsub(path, "/%.$", "/") + local reduced + while reduced ~= path do + reduced = path + path = gsub(reduced, "([^/]*/%.%./)", function (s) + if s ~= "../../" then + return "" + else + return s + end + end) + end + path = gsub(reduced, "([^/]*/%.%.)$", function (s) + if s ~= "../.." then + return "" + else + return s + end + end) + return path +end + +function url.parse(url, default) + local parsed = { } + for k, v in next, default or parsed do + parsed[k] = v + end + if not url or url == "" then + return nil, "invalid url" + end + url = gsub(url, "#(.*)$", function(f) + parsed.fragment = f + return "" + end) + url = gsub(url, "^([%w][%w%+%-%.]*)%:", function(s) + parsed.scheme = s + return "" + end) + url = gsub(url, "^//([^/]*)", function(n) + parsed.authority = n + return "" + end) + url = gsub(url, "%?(.*)", function(q) + parsed.query = q + return "" + end) + url = gsub(url, "%;(.*)", function(p) + parsed.params = p + return "" + end) + if url ~= "" then + parsed.path = url + end + local authority = parsed.authority + if not authority then + return parsed + end + authority = gsub(authority,"^([^@]*)@", function(u) + parsed.userinfo = u + return "" + end) + authority = gsub(authority, ":([^:%]]*)$", function(p) + parsed.port = p + return "" + end) + if authority ~= "" then + parsed.host = match(authority, "^%[(.+)%]$") or authority + end + local userinfo = parsed.userinfo + if not userinfo then + return parsed + end + userinfo = gsub(userinfo, ":([^:]*)$", function(p) + parsed.password = p + return "" + end) + parsed.user = userinfo + return parsed +end + +function url.build(parsed) + local url = parsed.path or "" + if parsed.params then + url = url .. ";" .. parsed.params + end + if parsed.query then + url = url .. "?" .. parsed.query + end + local authority = parsed.authority + if parsed.host then + authority = parsed.host + if find(authority, ":") then -- IPv6? + authority = "[" .. authority .. "]" + end + if parsed.port then + authority = authority .. ":" .. tostring(parsed.port) + end + local userinfo = parsed.userinfo + if parsed.user then + userinfo = parsed.user + if parsed.password then + userinfo = userinfo .. ":" .. parsed.password + end + end + if userinfo then authority = userinfo .. "@" .. authority end + end + if authority then + url = "//" .. authority .. url + end + if parsed.scheme then + url = parsed.scheme .. ":" .. url + end + if parsed.fragment then + url = url .. "#" .. parsed.fragment + end + return url +end + +function url.absolute(base_url, relative_url) + local base_parsed + if type(base_url) == "table" then + base_parsed = base_url + base_url = url.build(base_parsed) + else + base_parsed = url.parse(base_url) + end + local relative_parsed = url.parse(relative_url) + if not base_parsed then + return relative_url + elseif not relative_parsed then + return base_url + elseif relative_parsed.scheme then + return relative_url + else + relative_parsed.scheme = base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority = base_parsed.authority + if not relative_parsed.path then + relative_parsed.path = base_parsed.path + if not relative_parsed.params then + relative_parsed.params = base_parsed.params + if not relative_parsed.query then + relative_parsed.query = base_parsed.query + end + end + else + relative_parsed.path = absolute_path(base_parsed.path or "", relative_parsed.path) + end + end + return url.build(relative_parsed) + end +end + +function url.parse_path(path) + local parsed = { } + path = path or "" + gsub(path, "([^/]+)", function (s) + insert(parsed, s) + end) + for i=1,#parsed do + parsed[i] = url.unescape(parsed[i]) + end + if sub(path, 1, 1) == "/" then + parsed.is_absolute = 1 + end + if sub(path, -1, -1) == "/" then + parsed.is_directory = 1 + end + return parsed +end + +function url.build_path(parsed, unsafe) + local path = "" + local n = #parsed + if unsafe then + for i = 1, n-1 do + path = path .. parsed[i] .. "/" + end + if n > 0 then + path = path .. parsed[n] + if parsed.is_directory then + path = path .. "/" + end + end + else + for i = 1, n-1 do + path = path .. protect_segment(parsed[i]) .. "/" + end + if n > 0 then + path = path .. protect_segment(parsed[n]) + if parsed.is_directory then + path = path .. "/" + end + end + end + if parsed.is_absolute then + path = "/" .. path + end + return path +end + +package.loaded["socket.url"] = url + +return url diff --git a/tex/context/base/mkiv/util-soc.lua b/tex/context/base/mkiv/util-soc.lua index 3a52ee86d..590287a25 100644 --- a/tex/context/base/mkiv/util-soc.lua +++ b/tex/context/base/mkiv/util-soc.lua @@ -6,6 +6,29 @@ if not modules then modules = { } end modules ['util-soc'] = { license = "see context related readme files" } +--[[-- + +In LuaTeX we provide the socket library that is more or less the standard one for +Lua. It has been around for a while and seems to be pretty stable. The binary +module is copmpiled into LuaTeX and the accompanying .lua files are preloaded. +These files are mostly written by Diego Nehab, Andre Carregal, Javier Guerra, and +Fabio Mascarenhas with contributions from Diego Nehab, Mike Pall, David Burgess, +Leonardo Godinho, Thomas Harning Jr., and Gary NG. The originals are part of and +copyrighted by the Kepler project. + +Here we reload a slightly reworked version of these .lua files. We keep the same +(documented) interface but streamlined some fo the code. No more modules, no more +pre 5.2 Lua, etc. Also, as it loads into the ConTeXt ecosystem, we plug in some +logging. (and maybe tracing in the future). As we don't support serial ports in +LuaTeX, related code has been dropped. + +The files are reformatted so that we can more easilly add additional features +and/or tracing options. Any error introduced there is our fault! The url module +might be replaced by the one in ConTeXt. When we need mbox a suitable variant +will be provided. + +--]]-- + local format = string.format local smtp = require("socket.smtp") @@ -95,3 +118,12 @@ function mail.send(specification) return true end end + +-- for now we have this here: + +if socket then + + math.initialseed = tonumber(string.sub(string.reverse(tostring(math.ceil(socket.gettime()*10000))),1,6)) + math.randomseed(math.initialseed) + +end diff --git a/tex/context/base/mkiv/util-sql-imp-ffi.lua b/tex/context/base/mkiv/util-sql-imp-ffi.lua index 2a2bc6569..3731933f1 100644 --- a/tex/context/base/mkiv/util-sql-imp-ffi.lua +++ b/tex/context/base/mkiv/util-sql-imp-ffi.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['util-sql-imp-ffi'] = { -- I looked at luajit-mysql to see how the ffi mapping was done but it didn't work -- out that well (at least not on windows) but I got the picture. As I have somewhat --- different demands I simplified / redid the ffi bti and just took the swiglib +-- different demands I simplified / redid the ffi bit and just took the swiglib -- variant and adapted that. local tonumber = tonumber @@ -17,6 +17,7 @@ local format, byte = string.format, string.byte local lpegmatch = lpeg.match local setmetatable, type = setmetatable, type local sleep = os.sleep +local formatters = string.formatters local trace_sql = false trackers.register("sql.trace", function(v) trace_sql = v end) local trace_queries = false trackers.register("sql.queries",function(v) trace_queries = v end) @@ -33,6 +34,9 @@ ffi.cdef [[ a query. The rest is handled already in the Lua code elsewhere. */ + void free(void*ptr); + void * malloc(size_t size); + typedef void MYSQL_instance; typedef void MYSQL_result; typedef char **MYSQL_row; @@ -115,6 +119,14 @@ ffi.cdef [[ MYSQL_result *result ); + unsigned int mysql_affected_rows ( + MYSQL_instance *mysql + ); + + unsigned int mysql_field_count ( + MYSQL_instance *mysql + ); + unsigned int mysql_num_fields ( MYSQL_result *res ); @@ -163,12 +175,14 @@ local dataprepared = helpers.preparetemplate local serialize = sql.serialize local deserialize = sql.deserialize -local mysql_initialize = mysql.mysql_init +local mysql_open_session = mysql.mysql_init local mysql_open_connection = mysql.mysql_real_connect local mysql_execute_query = mysql.mysql_real_query local mysql_close_connection = mysql.mysql_close +local mysql_affected_rows = mysql.mysql_affected_rows +local mysql_field_count = mysql.mysql_field_count local mysql_field_seek = mysql.mysql_field_seek local mysql_num_fields = mysql.mysql_num_fields local mysql_fetch_fields = mysql.mysql_fetch_fields @@ -180,6 +194,7 @@ local mysql_init = mysql.mysql_init local mysql_store_result = mysql.mysql_store_result local mysql_free_result = mysql.mysql_free_result +local mysql_error_number = mysql.mysql_errno local mysql_error_message = mysql.mysql_error local NULL = ffi.cast("MYSQL_result *",0) @@ -187,325 +202,361 @@ local NULL = ffi.cast("MYSQL_result *",0) local ffi_tostring = ffi.string local ffi_gc = ffi.gc ------ mysqldata = ffi.cast("MYSQL_instance*",mysql.malloc(1024*1024)) -local instance = mysql.mysql_init(nil) -- (mysqldata) +local instance = mysql.mysql_init(nil) local mysql_constant_false = false local mysql_constant_true = true -local function finish(t) - local r = t._result_ - if r then - ffi_gc(r,mysql_free_result) +local wrapresult do + + local function collect(t) + local result = t._result_ + if result then + ffi_gc(result,mysql_free_result) + end end -end -local function getcolnames(t) - return t.names -end + local function finish(t) + local result = t._result_ + if result then + t._result_ = nil + ffi_gc(result,mysql_free_result) + end + end -local function getcoltypes(t) - return t.types -end + local function getcoldata(t) + local result = t._result_ + local nofrows = t.nofrows + local noffields = t.noffields + local names = { } + local types = { } + local fields = mysql_fetch_fields(result) + for i=1,noffields do + local field = fields[i-1] + names[i] = ffi_tostring(field.name) + types[i] = tonumber(field.type) -- todo + end + t.names = names + t.types = types + end -local function numrows(t) - return tonumber(t.nofrows) -end + local function getcolnames(t) + local names = t.names + if names then + return names + end + getcoldata(t) + return t.names + end -local function list(t) - local result = t._result_ - if result then - local row = mysql_fetch_row(result) - -- local len = mysql_fetch_lengths(result) - local result = { } - for i=1,t.noffields do - result[i] = ffi_tostring(row[i-1]) + local function getcoltypes(t) + local types = t.types + if types then + return types end - return result + getcoldata(t) + return t.types end -end -local function hash(t) - local result = t._result_ - local fields = t.names - if result then - local row = mysql_fetch_row(result) - -- local len = mysql_fetch_lengths(result) - local result = { } - for i=1,t.noffields do - result[fields[i]] = ffi_tostring(row[i-1]) + local function numrows(t) + return t.nofrows + end + + -- local function fetch(t) + -- local + -- local row = mysql_fetch_row(result) + -- local result = { } + -- for i=1,t.noffields do + -- result[i] = ffi_tostring(row[i-1]) + -- end + -- return unpack(result) + -- end + + local mt = { + __gc = collect, + __index = { + _result_ = nil, + close = finish, + numrows = numrows, + getcolnames = getcolnames, + getcoltypes = getcoltypes, + -- fetch = fetch, -- not efficient + } + } + + wrapresult = function(connection) + local result = mysql_store_result(connection) + if result ~= NULL then + mysql_field_seek(result,0) + local t = { + _result_ = result, + nofrows = tonumber(mysql_num_rows (result) or 0) or 0, + noffields = tonumber(mysql_num_fields(result) or 0) or 0, + } + return setmetatable(t,mt) + elseif tonumber(mysql_field_count(connection) or 0) or 0 > 0 then + return tonumber(mysql_affected_rows(connection)) end - return result end -end -local function wholelist(t) - return fetch_all_rows(t._result_) end -local mt = { __index = { - -- regular - finish = finish, - list = list, - hash = hash, - wholelist = wholelist, - -- compatibility - numrows = numrows, - getcolnames = getcolnames, - getcoltypes = getcoltypes, - -- fallback - _result_ = nil, - names = { }, - types = { }, - noffields = 0, - nofrows = 0, - } -} +local initializesession do -local nt = setmetatable({},mt) + -- timeouts = [ connect_timeout |wait_timeout | interactive_timeout ] --- session + local timeout -- = 3600 -- to be tested -local function close(t) - mysql_close_connection(t._connection_) -end + -- connection -local function execute(t,query) - if query and query ~= "" then - local connection = t._connection_ - local result = mysql_execute_query(connection,query,#query) - if result == 0 then - local result = mysql_store_result(connection) - if result ~= NULL then - mysql_field_seek(result,0) - local nofrows = tonumber(mysql_num_rows(result) or 0) - local noffields = tonumber(mysql_num_fields(result)) - local names = { } - local types = { } - local fields = mysql_fetch_fields(result) - for i=1,noffields do - local field = fields[i-1] - names[i] = ffi_tostring(field.name) - types[i] = tonumber(field.type) -- todo - end - local t = { - _result_ = result, - names = names, - types = types, - noffields = noffields, - nofrows = nofrows, - } - return setmetatable(t,mt) + local function close(t) + -- just a struct ? + end + + local function execute(t,query) + if query and query ~= "" then + local connection = t._connection_ + local result = mysql_execute_query(connection,query,#query) + if result == 0 then + return wrapresult(connection) else - return nt + -- mysql_error_number(connection) + return false, ffi_tostring(mysql_error_message(connection)) end end + return false end - return false -end -local mt = { __index = { - close = close, - execute = execute, + local mt = { + __index = { + close = close, + execute = execute, + } } -} -local function open(t,database,username,password,host,port) - local connection = mysql_open_connection( - t._session_, - host or "localhost", - username or "", - password or "", - database or "", - port or 0, - NULL, - 0 - ) - if connection ~= NULL then - local t = { - _connection_ = connection, - } - return setmetatable(t,mt) + -- session + + local function open(t,database,username,password,host,port) + local connection = mysql_open_connection( + t._session_, + host or "localhost", + username or "", + password or "", + database or "", + port or 0, + NULL, + 0 + ) + if connection ~= NULL then + if timeout then + execute(connection,formatters["SET SESSION connect_timeout=%s ;"](timeout)) + end + local t = { + _connection_ = connection, + } + return setmetatable(t,mt) + end end -end -local function message(t) - return mysql_error_message(t._session_) -end - -local function close(t) - -- dummy, as we have a global session -end + local function message(t) + return mysql_error_message(t._session_) + end -local mt = { - __index = { - connect = open, - close = close, - message = message, - } -} + local function close(t) + local connection = t._connection_ + if connection and connection ~= NULL then + ffi_gc(connection, mysql_close) + t.connection = nil + end + end -local function initialize() - local session = { - _session_ = mysql_initialize(instance) -- maybe share, single thread anyway + local mt = { + __index = { + connect = open, + close = close, + message = message, + }, } - return setmetatable(session,mt) -end --- -- -- -- + initializesession = function() + local session = { + _session_ = mysql_open_session(instance) -- maybe share, single thread anyway + } + return setmetatable(session,mt) + end -local function connect(session,specification) - return session:connect( - specification.database or "", - specification.username or "", - specification.password or "", - specification.host or "", - specification.port - ) end -local function error_in_connection(specification,action) - report_state("error in connection: [%s] user %s into %s at %s:%s", - action or "unknown", - specification.username or "no username", - specification.database or "no database", - specification.host or "no host", - specification.port or "no port" - ) -end +local executequery do -local function datafetched(specification,query,converter) - if not query or query == "" then - report_state("no valid query") - return { }, { } + local function connect(session,specification) + return session:connect( + specification.database or "", + specification.username or "", + specification.password or "", + specification.host or "", + specification.port + ) end - local id = specification.id - local session, connection - if id then - local c = cache[id] - if c then - session = c.session - connection = c.connection + + local function fetched(specification,query,converter) + if not query or query == "" then + report_state("no valid query") + return false end - if not connection then - session = initialize() - connection = connect(session,specification) + local id = specification.id + local session, connection + if id then + local c = cache[id] + if c then + session = c.session + connection = c.connection + end if not connection then - for i=1,nofretries do - sleep(retrydelay) - report_state("retrying to connect: [%s.%s] %s@%s to %s:%s", - id,i, - specification.database or "no database", - specification.username or "no username", - specification.host or "no host", - specification.port or "no port" - ) - connection = connect(session,specification) - if connection then - break - end + session = initializesession() + if not session then + return formatters["no session for %a"](id) end - end - if connection then - cache[id] = { session = session, connection = connection } - end - end - else - session = initialize() - connection = connect(session,specification) - if not connection then - for i=1,nofretries do - sleep(retrydelay) - report_state("retrying to connect: [%s] %s@%s to %s:%s", - i, - specification.database or "no database", - specification.username or "no username", - specification.host or "no host", - specification.port or "no port" - ) connection = connect(session,specification) - if connection then - break + if not connection then + return formatters["no connection for %a"](id) end + cache[id] = { session = session, connection = connection } + end + else + session = initializesession() + if not session then + return "no session" + end + connection = connect(session,specification) + if not connection then + return "no connection" end end - end - if not connection then - report_state("error in connection: %s@%s to %s:%s", + if not connection then + report_state("error in connection: %s@%s to %s:%s", specification.database or "no database", specification.username or "no username", specification.host or "no host", specification.port or "no port" ) - return { }, { } - end - query = lpegmatch(querysplitter,query) - local result, message, okay - for i=1,#query do - local q = query[i] - local r, m = connection:execute(q) - if m then - report_state("error in query, stage: %s",string.collapsespaces(q or "?")) - message = message and format("%s\n%s",message,m) or m + return "no connection" end - if type(r) == "table" then - result = r - okay = true - elseif not m then - okay = true + query = lpegmatch(querysplitter,query) + local result, okay + for i=1,#query do + local q = query[i] + local r, m = connection:execute(q) + if m then + report_state("error in query to host %a: %s",specification.host,string.collapsespaces(q or "?")) + if m then + report_state("message: %s",m) + end + end + local t = type(r) + if t == "table" then + result = r + okay = true + elseif t == "number" then + okay = true + end end - end - local data, keys - if result then - if converter then - data = converter.ffi(result) - else - keys = result.names - data = { } - for i=1,result.nofrows do - data[i] = result:hash() + if not okay then -- can go + -- why do we close a session + if connection then + connection:close() + end + if session then + session:close() end + if id then + cache[id] = nil + end + return "execution error" end - result:finish() -- result:close() - elseif message then - report_state("message %s",message) - end - if not keys then - keys = { } - end - if not data then - data = { } - end - if not id then - connection:close() - session:close() + local data, keys + if result then + if converter then + data = converter.ffi(result) + else + local _result_ = result._result_ + local noffields = result.noffields + local nofrows = result.nofrows + keys = result:getcolnames() + data = { } + if noffields > 0 and nofrows > 0 then + for i=1,nofrows do + local cells = { } + local row = mysql_fetch_row(_result_) + for j=1,noffields do + local s = row[j-1] + local k = keys[j] + if s == NULL then + cells[k] = "" + else + cells[k] = ffi_tostring(s) + end + end + data[i] = cells + end + end + end + result:close() + end + -- + if not id then + if connection then + connection:close() + end + if session then + session:close() + end + end + return false, data, keys end - return data, keys -end -local function execute(specification) - if trace_sql then - report_state("executing library") - end - if not validspecification(specification) then - report_state("error in specification") - return - end - local query = dataprepared(specification) - if not query then - report_state("error in preparation") - return - end - local data, keys = datafetched(specification,query,specification.converter) - if not data then - report_state("error in fetching") - return + local function datafetched(specification,query,converter) + local callokay, connectionerror, data, keys = pcall(fetched,specification,query,converter) + if not callokay then + report_state("call error, retrying") + callokay, connectionerror, data, keys = pcall(fetched,specification,query,converter) + elseif connectionerror then + report_state("error: %s, retrying",connectionerror) + callokay, connectionerror, data, keys = pcall(fetched,specification,query,converter) + end + if not callokay then + report_state("persistent call error") + elseif connectionerror then + report_state("persistent error: %s",connectionerror) + end + return data or { }, keys or { } end - local one = data[1] - if one then - setmetatable(data,{ __index = one } ) + + executequery = function(specification) + if trace_sql then + report_state("executing library") + end + if not validspecification(specification) then + report_state("error in specification") + return + end + local query = dataprepared(specification) + if not query then + report_state("error in preparation") + return + end + local data, keys = datafetched(specification,query,specification.converter) + if not data then + report_state("error in fetching") + return + end + local one = data[1] + if one then + setmetatable(data,{ __index = one } ) + end + return data, keys end - return data, keys + end local wraptemplate = [[ @@ -530,13 +581,14 @@ return function(result) if not result then return { } end - local nofrows = result.nofrows or 0 + local nofrows = result.nofrows if nofrows == 0 then return { } end - local noffields = result.noffields or 0 - local _result_ = result._result_ + local noffields = result.noffields local target = { } -- no %s needed here + local _result_ = result._result_ + -- we can share cells for i=1,nofrows do local cells = { } local row = mysql_fetch_row(_result_) @@ -552,7 +604,7 @@ return function(result) %s } end - result:finish() -- result:close() + result:close() return target end ]] @@ -560,9 +612,9 @@ end local celltemplate = "cells[%s]" methods.ffi = { - runner = function() end, -- never called - execute = execute, - initialize = initialize, -- returns session + runner = function() end, -- never called + execute = executequery, + initialize = initializesession, -- returns session usesfiles = false, wraptemplate = wraptemplate, celltemplate = celltemplate, diff --git a/tex/context/base/mkiv/util-sql-imp-library.lua b/tex/context/base/mkiv/util-sql-imp-library.lua index a2b692e45..dbbeb32cc 100644 --- a/tex/context/base/mkiv/util-sql-imp-library.lua +++ b/tex/context/base/mkiv/util-sql-imp-library.lua @@ -156,13 +156,13 @@ local function fetched(specification,query,converter) okay = true end end - if not okay then -- can go - if session then - session:close() - end + if not okay then if connection then connection:close() end + if session then + session:close() + end if id then cache[id] = nil end diff --git a/tex/context/base/mkiv/util-sql-imp-sqlite.lua b/tex/context/base/mkiv/util-sql-imp-sqlite.lua index 04d5ced3a..cf4a3a8b0 100644 --- a/tex/context/base/mkiv/util-sql-imp-sqlite.lua +++ b/tex/context/base/mkiv/util-sql-imp-sqlite.lua @@ -132,7 +132,6 @@ setmetatable(cache, { local f_preamble = formatters[ [[ ATTACH `%s` AS `%s` ; PRAGMA `%s`.synchronous = normal ; -PRAGMA journal_mode = truncate ; ]] ] local function execute(specification) @@ -211,17 +210,19 @@ local function execute(specification) else local column = { } callback = function(data,nofcolumns,values,fields) - for i=0,nofcolumns-1 do + for i=1,nofcolumns do local field if keysdone then - field = keys[i+1] + field = keys[i] else -- field = get_list_item(fields,i) - field = ffi_tostring(fields[i]) + field = ffi_tostring(fields[i-1]) keys[i+1] = field end - -- column[field] = get_list_item(values,i) - column[field] = ffi_tostring(values[i]) + if field then + -- column[field] = get_list_item(values,i) + column[field] = ffi_tostring(values[i-1]) + end end nofrows = nofrows + 1 keysdone = true diff --git a/tex/context/base/mkiv/util-sql-logins.lua b/tex/context/base/mkiv/util-sql-logins.lua index dcb48fb35..c19bfbdf8 100644 --- a/tex/context/base/mkiv/util-sql-logins.lua +++ b/tex/context/base/mkiv/util-sql-logins.lua @@ -211,9 +211,10 @@ end logins.userpurge = userpurge local function verdict(okay,...) - if not trace_logins then - -- no tracing - elseif okay then +-- if not trace_logins then +-- -- no tracing +-- else + if okay then report_logins("%s, granted",formatter(...)) else report_logins("%s, blocked",formatter(...)) @@ -244,6 +245,11 @@ function logins.userpermitted(db,name) } end if not data or not data.name then + if not data then + report_logins("no user data for %a",name) + else + report_logins("no name entry for %a",name) + end local d = { name = name, state = 0, diff --git a/tex/context/base/mkiv/util-sql-users.lua b/tex/context/base/mkiv/util-sql-users.lua index 7204fb310..57c99b2a7 100644 --- a/tex/context/base/mkiv/util-sql-users.lua +++ b/tex/context/base/mkiv/util-sql-users.lua @@ -25,12 +25,16 @@ local trace_sql = false trackers.register("sql.users.trace", function(v) trace_ local report = logs.reporter("sql","users") local split = lpeg.splitat(":") + local valid = nil local hash = function(s) return "MD5:" .. sumHEXA(s) end +local sha2 = sha2 or (utilities and utilities.sha2) -if LUAVERSION >= 5.3 then +if not sha2 and LUAVERSION >= 5.3 then + sha2 = require("util-sha") +end - local sha2 = require("util-sha") +if sha2 then local HASH224 = sha2.HASH224 local HASH256 = sha2.HASH256 @@ -238,9 +242,7 @@ function users.valid(db,username,password,address) name = username, }, } - local data = data and data[1] - if not data then return false, "unknown user" elseif not data.enabled then diff --git a/tex/context/base/mkiv/util-sta.lua b/tex/context/base/mkiv/util-sta.lua index d140cacdc..7819395f6 100644 --- a/tex/context/base/mkiv/util-sta.lua +++ b/tex/context/base/mkiv/util-sta.lua @@ -289,24 +289,24 @@ end -- -- local concat = table.concat -- --- local pdfpageliteral = nodes.pool.pdfpageliteral +-- local pageliteral = nodes.pool.pageliteral -- -- function demostacker.start(s,t,first,last) -- local n = whatever[t[last]] -- -- s.report("start: %s",n) --- return pdfpageliteral(n) +-- return pageliteral(n) -- end -- -- function demostacker.stop(s,t,first,last) -- local n = whatever[false] -- -- s.report("stop: %s",n) --- return pdfpageliteral(n) +-- return pageliteral(n) -- end -- -- function demostacker.change(s,t1,first1,last1,t2,first2,last2) -- local n = whatever[t2[last2]] -- -- s.report("change: %s",n) --- return pdfpageliteral(n) +-- return pageliteral(n) -- end -- -- demostacker.mode = "switch" @@ -325,7 +325,7 @@ end -- r[#r+1] = whatever[t[i]] -- end -- -- s.report("start: %s",concat(r," ")) --- return pdfpageliteral(concat(r," ")) +-- return pageliteral(concat(r," ")) -- end -- -- function demostacker.stop(s,t,first,last) @@ -334,7 +334,7 @@ end -- r[#r+1] = whatever[false] -- end -- -- s.report("stop: %s",concat(r," ")) --- return pdfpageliteral(concat(r," ")) +-- return pageliteral(concat(r," ")) -- end -- -- function demostacker.change(s,t1,first1,last1,t2,first2,last2) @@ -346,7 +346,7 @@ end -- r[#r+1] = whatever[t2[i]] -- end -- -- s.report("change: %s",concat(r," ")) --- return pdfpageliteral(concat(r," ")) +-- return pageliteral(concat(r," ")) -- end -- -- demostacker.mode = "stack" diff --git a/tex/context/base/mkiv/util-sto.lua b/tex/context/base/mkiv/util-sto.lua index 5b6915eaf..a08d25ced 100644 --- a/tex/context/base/mkiv/util-sto.lua +++ b/tex/context/base/mkiv/util-sto.lua @@ -196,6 +196,19 @@ function table.getmetatablekey(t,key,value) return m and m[key] end +function table.makeweak(t) + if not t then + t = { } + end + local m = getmetatable(t) + if m then + m.__mode = "v" + else + setmetatable(t,{ __mode = "v" }) + end + return t +end + -- Problem: we have no __next (which is ok as it would probably slow down lua) so -- we cannot loop over the keys. diff --git a/tex/context/base/mkiv/util-str.lua b/tex/context/base/mkiv/util-str.lua index 05ff9f304..713c294eb 100644 --- a/tex/context/base/mkiv/util-str.lua +++ b/tex/context/base/mkiv/util-str.lua @@ -22,46 +22,72 @@ local utfchar, utfbyte, utflen = utf.char, utf.byte, utf.len ----- loadstripped = utilities.lua.loadstripped ----- setmetatableindex = table.setmetatableindex -local loadstripped = nil -local oldfashioned = LUAVERSION < 5.2 - -if oldfashioned then - - loadstripped = function(str,shortcuts) - return load(str) - end - -else - - loadstripped = function(str,shortcuts) - if shortcuts then - return load(dump(load(str),true),nil,nil,shortcuts) - else - return load(dump(load(str),true)) - end +local loadstripped = function(str,shortcuts) + if shortcuts then + return load(dump(load(str),true),nil,nil,shortcuts) + else + return load(dump(load(str),true)) end - end -- todo: make a special namespace for the formatter if not number then number = { } end -- temp hack for luatex-fonts -local stripper = patterns.stripzeros +local stripzero = patterns.stripzero +local stripzeros = patterns.stripzeros local newline = patterns.newline local endofstring = patterns.endofstring +local anything = patterns.anything local whitespace = patterns.whitespace +local space = patterns.space local spacer = patterns.spacer local spaceortab = patterns.spaceortab +local digit = patterns.digit +local sign = patterns.sign +local period = patterns.period + +-- local function points(n) +-- n = tonumber(n) +-- return (not n or n == 0) and "0pt" or lpegmatch(stripzeros,format("%.5fpt",n/65536)) +-- end + +-- local function basepoints(n) +-- n = tonumber(n) +-- return (not n or n == 0) and "0bp" or lpegmatch(stripzeros,format("%.5fbp", n*(7200/7227)/65536)) +-- end + +local ptf = 1 / 65536 +local bpf = (7200/7227) / 65536 local function points(n) + if n == 0 then + return "0pt" + end n = tonumber(n) - return (not n or n == 0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) + if not n or n == 0 then + return "0pt" + end + n = n * ptf + if n % 1 == 0 then + return format("%ipt",n) + end + return lpegmatch(stripzeros,format("%.5fpt",n)) -- plural as we need to keep the pt end local function basepoints(n) + if n == 0 then + return "0pt" + end n = tonumber(n) - return (not n or n == 0) and "0bp" or lpegmatch(stripper,format("%.5fbp", n*(7200/7227)/65536)) + if not n or n == 0 then + return "0pt" + end + n = n * bpf + if n % 1 == 0 then + return format("%ibp",n) + end + return lpegmatch(stripzeros,format("%.5fbp",n)) -- plural as we need to keep the pt end number.points = points @@ -72,7 +98,6 @@ number.basepoints = basepoints local rubish = spaceortab^0 * newline local anyrubish = spaceortab + newline -local anything = patterns.anything local stripped = (spaceortab^1 / "") * newline local leading = rubish^0 / "" local trailing = (anyrubish^1 * endofstring) / "" @@ -140,7 +165,7 @@ local pattern = + newline * Cp() / function(position) extra, start = 0, position end - + patterns.anything + + anything )^1) function strings.tabtospace(str,tab) @@ -183,27 +208,31 @@ end -- return str -- end -local space = spacer^0 -local nospace = space/"" -local endofline = nospace * newline +local optionalspace = spacer^0 +local nospace = optionalspace/"" +local endofline = nospace * newline -local stripend = (whitespace^1 * endofstring)/"" +local stripend = (whitespace^1 * endofstring)/"" -local normalline = (nospace * ((1-space*(newline+endofstring))^1) * nospace) +local normalline = (nospace * ((1-optionalspace*(newline+endofstring))^1) * nospace) -local stripempty = endofline^1/"" -local normalempty = endofline^1 -local singleempty = endofline * (endofline^0/"") -local doubleempty = endofline * endofline^-1 * (endofline^0/"") +local stripempty = endofline^1/"" +local normalempty = endofline^1 +local singleempty = endofline * (endofline^0/"") +local doubleempty = endofline * endofline^-1 * (endofline^0/"") +local stripstart = stripempty^0 -local stripstart = stripempty^0 +local intospace = whitespace^1/" " +local noleading = whitespace^1/"" +local notrailing = noleading * endofstring -local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 ) -local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 ) -local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 ) -local p_retain_normal = Cs ( ( normalline + normalempty )^0 ) -local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 ) -local p_retain_noempty = Cs ( ( normalline + singleempty )^0 ) +local p_prune_normal = Cs ( stripstart * ( stripend + normalline + normalempty )^0 ) +local p_prune_collapse = Cs ( stripstart * ( stripend + normalline + doubleempty )^0 ) +local p_prune_noempty = Cs ( stripstart * ( stripend + normalline + singleempty )^0 ) +local p_prune_intospace = Cs ( noleading * ( notrailing + intospace + 1 )^0 ) +local p_retain_normal = Cs ( ( normalline + normalempty )^0 ) +local p_retain_collapse = Cs ( ( normalline + doubleempty )^0 ) +local p_retain_noempty = Cs ( ( normalline + singleempty )^0 ) -- function striplines(str,prune,collapse,noempty) -- if prune then @@ -229,10 +258,11 @@ local striplinepatterns = { ["prune"] = p_prune_normal, ["prune and collapse"] = p_prune_collapse, -- default ["prune and no empty"] = p_prune_noempty, + ["prune and to space"] = p_prune_intospace, ["retain"] = p_retain_normal, ["retain and collapse"] = p_retain_collapse, ["retain and no empty"] = p_retain_noempty, - ["collapse"] = patterns.collapser, -- how about: stripper fullstripper + ["collapse"] = patterns.collapser, } setmetatable(striplinepatterns,{ __index = function(t,k) return p_prune_collapse end }) @@ -243,6 +273,10 @@ function strings.striplines(str,how) return str and lpegmatch(striplinepatterns[how],str) or str end +function strings.collapse(str) -- maybe also in strings + return str and lpegmatch(p_prune_intospace,str) or str +end + -- also see: string.collapsespaces strings.striplong = strings.striplines -- for old times sake @@ -258,13 +292,14 @@ strings.striplong = strings.striplines -- for old times sake -- " zus wim jet", -- " ", -- }, "\n") - +-- -- local str = table.concat( { -- " aaaa", -- " bb", -- " cccccc", +-- " ", -- }, "\n") - +-- -- for k, v in table.sortedhash(utilities.strings.striplinepatterns) do -- logs.report("stripper","method: %s, result: [[%s]]",k,utilities.strings.striplines(str,k)) -- end @@ -335,6 +370,7 @@ end -- automatic %...a 'whatever' (string, table, ...) -- automatic %...A "whatever" (string, table, ...) -- zap %...z skip +-- stripped %...N %...N -- comma/period real %...m -- period/comma real %...M -- formatted float %...k n.m @@ -410,27 +446,45 @@ end -- maybe to util-num -local digit = patterns.digit -local period = patterns.period -local three = digit * digit * digit +local two = digit * digit +local three = two * digit +local prefix = (Carg(1) * three)^1 local splitter = Cs ( - (((1 - (three^1 * period))^1 + C(three)) * (Carg(1) * three)^1 + C((1-period)^1)) - * (P(1)/"" * Carg(2)) * C(2) + (((1 - (three^1 * period))^1 + C(three)) * prefix + C((1-period)^1)) + * (anything/"" * Carg(2)) * C(2) +) + +local splitter3 = Cs ( + three * prefix * endofstring + + two * prefix * endofstring + + digit * prefix * endofstring + + three + + two + + digit ) patterns.formattednumber = splitter function number.formatted(n,sep1,sep2) - local s = type(s) == "string" and n or format("%0.2f",n) - if sep1 == true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1 == "." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1 == "," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") + if sep1 == false then + if type(n) == "number" then + n = tostring(n) + end + return lpegmatch(splitter3,n,1,sep2 or ".") else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") + if type(n) == "number" then + n = format("%0.2f",n) + end + if sep1 == true then + return lpegmatch(splitter,n,1,".",",") + elseif sep1 == "." then + return lpegmatch(splitter,n,1,sep1,sep2 or ",") + elseif sep1 == "," then + return lpegmatch(splitter,n,1,sep1,sep2 or ".") + else + return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".") + end end end @@ -443,14 +497,22 @@ end -- print(number.formatted(1234567)) -- print(number.formatted(12345678)) -- print(number.formatted(12345678,true)) +-- print(number.formatted(1,false)) +-- print(number.formatted(12,false)) +-- print(number.formatted(123,false)) +-- print(number.formatted(1234,false)) +-- print(number.formatted(12345,false)) +-- print(number.formatted(123456,false)) +-- print(number.formatted(1234567,false)) +-- print(number.formatted(12345678,false)) -- print(number.formatted(1234.56,"!","?")) local p = Cs( P("-")^0 * (P("0")^1/"")^0 - * (1-P("."))^0 - * (P(".") * P("0")^1 * P(-1)/"" + P(".")^0) - * P(1-P("0")^1*P(-1))^0 + * (1-period)^0 + * (period * P("0")^1 * endofstring/"" + period^0) + * P(1-P("0")^1*endofstring)^0 ) function number.compactfloat(n,fmt) @@ -469,12 +531,11 @@ end local zero = P("0")^1 / "" local plus = P("+") / "" local minus = P("-") -local separator = S(".") -local digit = R("09") +local separator = period local trailing = zero^1 * #S("eE") -local exponent = (S("eE") * (plus + Cs((minus * zero^0 * P(-1))/"") + minus) * zero^0 * (P(-1) * Cc("0") + P(1)^1)) +local exponent = (S("eE") * (plus + Cs((minus * zero^0 * endofstring)/"") + minus) * zero^0 * (endofstring * Cc("0") + anything^1)) local pattern_a = Cs(minus^0 * digit^1 * (separator/"" * trailing + separator * (trailing + digit)^0) * exponent) -local pattern_b = Cs((exponent + P(1))^0) +local pattern_b = Cs((exponent + anything)^0) function number.sparseexponent(f,n) if not n then @@ -524,62 +585,36 @@ local template = [[ return function(%s) return %s end ]] -local preamble, environment = "", { } - -if oldfashioned then - - preamble = [[ -local lpeg=lpeg -local type=type -local tostring=tostring -local tonumber=tonumber -local format=string.format -local concat=table.concat -local signed=number.signed -local points=number.points -local basepoints= number.basepoints -local utfchar=utf.char -local utfbyte=utf.byte -local lpegmatch=lpeg.match -local nspaces=string.nspaces -local utfpadding=string.utfpadding -local tracedchar=string.tracedchar -local autosingle=string.autosingle -local autodouble=string.autodouble -local sequenced=table.sequenced -local formattednumber=number.formatted -local sparseexponent=number.sparseexponent -local formattedfloat=number.formattedfloat - ]] - -else - - environment = { - global = global or _G, - lpeg = lpeg, - type = type, - tostring = tostring, - tonumber = tonumber, - format = string.format, - concat = table.concat, - signed = number.signed, - points = number.points, - basepoints = number.basepoints, - utfchar = utf.char, - utfbyte = utf.byte, - lpegmatch = lpeg.match, - nspaces = string.nspaces, - utfpadding = string.utfpadding, - tracedchar = string.tracedchar, - autosingle = string.autosingle, - autodouble = string.autodouble, - sequenced = table.sequenced, - formattednumber = number.formatted, - sparseexponent = number.sparseexponent, - formattedfloat = number.formattedfloat, - } - -end +local preamble = "" + +local environment = { + global = global or _G, + lpeg = lpeg, + type = type, + tostring = tostring, + tonumber = tonumber, + format = string.format, + concat = table.concat, + signed = number.signed, + points = number.points, + basepoints = number.basepoints, + utfchar = utf.char, + utfbyte = utf.byte, + lpegmatch = lpeg.match, + nspaces = string.nspaces, + utfpadding = string.utfpadding, + tracedchar = string.tracedchar, + autosingle = string.autosingle, + autodouble = string.autodouble, + sequenced = table.sequenced, + formattednumber = number.formatted, + sparseexponent = number.sparseexponent, + formattedfloat = number.formattedfloat, + stripzero = lpeg.patterns.stripzero, + stripzeros = lpeg.patterns.stripzeros, + + FORMAT = string.f9, +} -- -- -- @@ -593,10 +628,10 @@ setmetatable(arguments, { __index = end }) -local prefix_any = C((S("+- .") + R("09"))^0) -local prefix_sub = (C((S("+-") + R("09"))^0) + Cc(0)) - * P(".") - * (C((S("+-") + R("09"))^0) + Cc(0)) +local prefix_any = C((sign + space + period + digit)^0) +local prefix_sub = (C((sign + digit)^0) + Cc(0)) + * period + * (C((sign + digit)^0) + Cc(0)) local prefix_tab = P("{") * C((1-P("}"))^0) * P("}") + C((1-R("az","AZ","09","%%"))^0) -- we've split all cases as then we can optimize them (let's omit the fuzzy u) @@ -697,6 +732,17 @@ local format_F = function(f) -- beware, no cast to number end end +-- if string.f9 then +-- format_F = function(f) -- beware, no cast to number +-- n = n + 1 +-- if not f or f == "" then +-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or FORMAT(a%s))",n,n,n,n,n) +-- else +-- return format("((a%s %% 1 == 0) and format('%%i',a%s) or FORMAT(a%s,'%%%sf'))",n,n,n,f) +-- end +-- end +-- end + local format_k = function(b,a) -- slow n = n + 1 return format("formattedfloat(a%s,%i,%i)",n,b or 0, a or 0) @@ -840,9 +886,43 @@ local format_L = function() return format("(a%s and 'TRUE' or 'FALSE')",n) end -local format_N = function() -- strips leading zeros +local format_n = function() -- strips leading and trailing zeros and removes .0 + n = n + 1 + return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) +end + +-- local format_N = function() -- strips leading and trailing zeros (also accepts string) +-- n = n + 1 +-- return format("tostring(tonumber(a%s) or a%s)",n,n) +-- end + +-- local format_N = function(f) -- strips leading and trailing zeros +-- n = n + 1 +-- -- stripzero (singular) as we only have a number +-- if not f or f == "" then +-- return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or ((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n) +-- else +-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) +-- end +-- end + +-- local format_N = function(f) -- strips leading and trailing zeros +-- n = n + 1 +-- -- stripzero (singular) as we only have a number +-- if not f or f == "" then +-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or ((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or lpegmatch(stripzero,format('%%.9f',a%s)))",n,n,n,n,n) +-- else +-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) +-- end +-- end + +local format_N = function(f) -- strips leading and trailing zeros n = n + 1 - return format("tostring(tonumber(a%s) or a%s)",n,n) + -- stripzero (singular) as we only have a number + if not f or f == "" then + f = ".9" + end -- always a leading number ! + return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) end local format_a = function(f) @@ -882,7 +962,11 @@ local format_m = function(f) if not f or f == "" then f = "," end - return format([[formattednumber(a%s,%q,".")]],n,f) + if f == "0" then + return format([[formattednumber(a%s,false)]],n) + else + return format([[formattednumber(a%s,%q,".")]],n,f) + end end local format_M = function(f) @@ -890,7 +974,11 @@ local format_M = function(f) if not f or f == "" then f = "." end - return format([[formattednumber(a%s,%q,",")]],n,f) + if f == "0" then + return format([[formattednumber(a%s,false)]],n) + else + return format([[formattednumber(a%s,%q,",")]],n,f) + end end -- @@ -902,42 +990,100 @@ end -- +-- local strip +-- +-- local format_Z = function(f) +-- n = n + 1 +-- if not f or f == "" then +-- f = ".9" +-- end +-- return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or (strip and lpegmatch(stripzero,format('%%%sf',a%s))) or format('%%%sf',a%s))",n,n,f,n,f,n) +-- end +-- +-- function strings.stripformatterzeros() +-- strip = true +-- end + +-- add(formatters,"texexp", [[texexp(...)]], "local texexp = metapost.texexp") +-- +-- add(formatters,"foo:bar",[[foo(...)]], { foo = function(...) print(...) return "!" end }) +-- print(string.formatters["foo %3!foo:bar! bar"](1,2,3)) + + local format_rest = function(s) return format("%q",s) -- catches " and \n and such end +-- local format_extension = function(extensions,f,name) +-- local extension = extensions[name] or "tostring(%s)" +-- local f = tonumber(f) or 1 +-- local w = find(extension,"%.%.%.") +-- if f == 0 then +-- if w then +-- extension = gsub(extension,"%.%.%.","") +-- end +-- return extension +-- elseif f == 1 then +-- if w then +-- extension = gsub(extension,"%.%.%.","%%s") +-- end +-- n = n + 1 +-- local a = "a" .. n +-- return format(extension,a,a) -- maybe more times? +-- elseif f < 0 then +-- local a = "a" .. (n + f + 1) +-- return format(extension,a,a) +-- else +-- if w then +-- extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s") +-- end +-- -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we +-- -- cache we don't save much and there are hardly any extensions anyway +-- local t = { } +-- for i=1,f do +-- n = n + 1 +-- -- t[#t+1] = "a" .. n +-- t[i] = "a" .. n +-- end +-- return format(extension,unpack(t)) +-- end +-- end + local format_extension = function(extensions,f,name) local extension = extensions[name] or "tostring(%s)" local f = tonumber(f) or 1 local w = find(extension,"%.%.%.") - if f == 0 then - if w then + if w then + -- we have a wildcard + if f == 0 then extension = gsub(extension,"%.%.%.","") - end - return extension - elseif f == 1 then - if w then + return extension + elseif f == 1 then extension = gsub(extension,"%.%.%.","%%s") - end - n = n + 1 - local a = "a" .. n - return format(extension,a,a) -- maybe more times? - elseif f < 0 then - local a = "a" .. (n + f + 1) - return format(extension,a,a) - else - if w then + n = n + 1 + local a = "a" .. n + return format(extension,a,a) -- maybe more times? + elseif f < 0 then + local a = "a" .. (n + f + 1) + return format(extension,a,a) + else extension = gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s") + -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we + -- cache we don't save much and there are hardly any extensions anyway + local t = { } + for i=1,f do + n = n + 1 + -- t[#t+1] = "a" .. n + t[i] = "a" .. n + end + return format(extension,unpack(t)) end - -- we could fill an array and then n = n + 1 unpack(t,n,n+f) but as we - -- cache we don't save much and there are hardly any extensions anyway - local t = { } - for i=1,f do + else + extension = gsub(extension,"%%s",function() n = n + 1 - -- t[#t+1] = "a" .. n - t[i] = "a" .. n - end - return format(extension,unpack(t)) + return "a" .. n + end) + return extension end end @@ -962,6 +1108,7 @@ local builder = Cs { "start", + V("C") + V("S") -- new + V("Q") -- new + + V("n") -- new + V("N") -- new + V("k") -- new -- @@ -986,7 +1133,7 @@ local builder = Cs { "start", ) + V("*") ) - * (P(-1) + Carg(1)) + * (endofstring + Carg(1)) )^0, -- ["s"] = (prefix_any * P("s")) / format_s, -- %s => regular %s (string) @@ -1005,7 +1152,8 @@ local builder = Cs { "start", -- ["S"] = (prefix_any * P("S")) / format_S, -- %S => %s (tostring) ["Q"] = (prefix_any * P("Q")) / format_Q, -- %Q => %q (tostring) - ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading zeros) + ["n"] = (prefix_any * P("n")) / format_n, -- %n => tonumber (strips leading and trailing zeros, as well as .0, expects number) + ["N"] = (prefix_any * P("N")) / format_N, -- %N => tonumber (strips leading and trailing zeros, also takes string) ["k"] = (prefix_sub * P("k")) / format_k, -- %k => like f but with n.m ["c"] = (prefix_any * P("c")) / format_c, -- %c => utf character (extension to regular) ["C"] = (prefix_any * P("C")) / format_C, -- %c => U+.... utf character @@ -1029,10 +1177,11 @@ local builder = Cs { "start", ["j"] = (prefix_any * P("j")) / format_j, -- %j => %e (float) stripped exponent (irrational) ["J"] = (prefix_any * P("J")) / format_J, -- %J => %E (float) stripped exponent (irrational) -- - ["m"] = (prefix_tab * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .) - ["M"] = (prefix_tab * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,) + ["m"] = (prefix_any * P("m")) / format_m, -- %m => xxx.xxx.xxx,xx (optional prefix instead of .) + ["M"] = (prefix_any * P("M")) / format_M, -- %M => xxx,xxx,xxx.xx (optional prefix instead of ,) -- ["z"] = (prefix_any * P("z")) / format_z, -- %z => skip n arguments + -- ["Z"] = (prefix_any * P("Z")) / format_Z, -- %Z => optionally strip zeros -- ["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring) ["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring) @@ -1057,7 +1206,7 @@ local preset = { } local direct = - P("%") * (S("+- .") + R("09"))^0 * S("sqidfgGeExXo") * P(-1) + P("%") * (sign + space + period + digit)^0 * S("sqidfgGeExXo") * endofstring / [[local format = string.format return function(str) return format("%0",str) end]] local function make(t,str) @@ -1134,36 +1283,22 @@ strings.formatters = { } -- _connector_ is an experiment -if oldfashioned then - - function strings.formatters.new(noconcat) - local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = preamble, _environment_ = { } } - setmetatable(t, { __index = make, __call = use }) - return t +function strings.formatters.new(noconcat) + local e = { } -- better make a copy as we can overload + for k, v in next, environment do + e[k] = v end - -else - - function strings.formatters.new(noconcat) - local e = { } -- better make a copy as we can overload - for k, v in next, environment do - e[k] = v - end - local t = { _type_ = "formatter", _connector_ = noconcat and "," or "..", _extensions_ = { }, _preamble_ = "", _environment_ = e } - setmetatable(t, { __index = make, __call = use }) - return t - end - + local t = { + _type_ = "formatter", + _connector_ = noconcat and "," or "..", + _extensions_ = { }, + _preamble_ = "", + _environment_ = e, + } + setmetatable(t, { __index = make, __call = use }) + return t end --- function strings.formatters.new() --- local t = { _extensions_ = { }, _preamble_ = "", _type_ = "formatter", _n_ = 0 } --- local m = { _t_ = t } --- setmetatable(t, { __index = m, __call = use }) --- setmetatable(m, { __index = make }) --- return t --- end - local formatters = strings.formatters.new() -- the default instance string.formatters = formatters -- in the main string namespace @@ -1186,27 +1321,17 @@ strings.formatters.add = add -- registered in the default instance (should we fall back on this one?) -patterns.xmlescape = Cs((P("<")/"<" + P(">")/">" + P("&")/"&" + P('"')/""" + P(1))^0) -patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + P(1))^0) +patterns.xmlescape = Cs((P("<")/"<" + P(">")/">" + P("&")/"&" + P('"')/""" + anything)^0) +patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + anything)^0) patterns.luaescape = Cs(((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0) -- maybe also \0 patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0 * Cc('"')) -- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but -- faster again when other q-escapables are found (the ones we don't need to escape) -if oldfashioned then - - add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape") - add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape") - add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape") - -else - - add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape }) - add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape }) - add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape }) - -end +add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape = lpeg.patterns.xmlescape }) +add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape = lpeg.patterns.texescape }) +add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape = lpeg.patterns.luaescape }) -- -- yes or no: -- @@ -1243,7 +1368,6 @@ end local dquote = patterns.dquote -- P('"') local equote = patterns.escaped + dquote / '\\"' + 1 -local space = patterns.space local cquote = Cc('"') local pattern = @@ -1277,3 +1401,11 @@ function strings.newcollector() end end end + +-- + +local f_16_16 = formatters["%0.5N"] + +function number.to16dot16(n) + return f_16_16(n/65536.0) +end diff --git a/tex/context/base/mkiv/util-tab.lua b/tex/context/base/mkiv/util-tab.lua index 1b069e2ae..b51c6589a 100644 --- a/tex/context/base/mkiv/util-tab.lua +++ b/tex/context/base/mkiv/util-tab.lua @@ -22,7 +22,8 @@ local utftoeight = utf.toeight local splitter = lpeg.tsplitat(".") function utilities.tables.definetable(target,nofirst,nolast) -- defines undefined tables - local composed, t = nil, { } + local composed = nil + local t = { } local snippets = lpegmatch(splitter,target) for i=1,#snippets - (nolast and 1 or 0) do local name = snippets[i] @@ -819,3 +820,54 @@ if setinspector then end end) end + +-- ordered hashes (for now here but in the table namespace): + +-- local t = table.orderedhash() +-- +-- t["1"] = { "a", "b" } +-- t["2"] = { } +-- t["2a"] = { "a", "c", "d" } +-- +-- for k, v in table.ordered(t) do +-- ... +-- end + +local mt = { + __newindex = function(t,k,v) + local n = t.last + 1 + t.last = n + t.list[n] = k + t.hash[k] = v + end, + __index = function(t,k) + return t.hash[k] + end, + __len = function(t) + return t.last + end, +} + +function table.orderedhash() + return setmetatable({ list = { }, hash = { }, last = 0 }, mt) +end + +function table.ordered(t) + local n = t.last + if n > 0 then + local l = t.list + local i = 1 + local h = t.hash + local f = function() + if i <= n then + local k = i + local v = h[l[k]] + i = i + 1 + return k, v + end + end + return f, 1, h[l[1]] + else + return function() end + end +end diff --git a/tex/context/base/mkiv/util-you.lua b/tex/context/base/mkiv/util-you.lua index 32a7e07d4..5802e7d7a 100644 --- a/tex/context/base/mkiv/util-you.lua +++ b/tex/context/base/mkiv/util-you.lua @@ -30,7 +30,6 @@ utilities.youless = youless local lpegmatch = lpeg.match local formatters = string.formatters -local sortedhash = table.sortedhash local tonumber, type, next = tonumber, type, next diff --git a/tex/context/fonts/mkiv/type-imp-cambria.mkiv b/tex/context/fonts/mkiv/type-imp-cambria.mkiv index f5679fd92..06781a8d0 100644 --- a/tex/context/fonts/mkiv/type-imp-cambria.mkiv +++ b/tex/context/fonts/mkiv/type-imp-cambria.mkiv @@ -20,6 +20,8 @@ % microsoft: cambria.ttc cambriab.ttf cambriai.ttf cambriaz.ttf % ascender : cambmath.ttf cambria.ttf cambriab.ttf cambriai.ttf cambriaz.ttf + \doifunknownfontfeature {cambria-math-bold} {\definefontfeature[cambria-math-bold][boldened]} + \starttypescript [\s!math,\s!serif] [cambria,cambria-x,cambria-y] % whatever matches \definefontsynonym [CambriaMath] [\s!name:cambriamath] @@ -42,15 +44,18 @@ \starttypescript [\s!math] [cambria,cambria-m,cambria-a] [\s!name] \loadfontgoodies[cambria-math] - \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=cambria-math] + \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=cambria-math] + \definefontsynonym [\s!MathRomanBold] [CambriaMath] [\s!features={\s!math\mathsizesuffix,cambria-math-bold,mathextra},\s!goodies=cambria-math] \stoptypescript \starttypescript [\s!math] [cambria-x] [\s!name] \loadfontgoodies[cambria-math] - \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math,mathextra},\s!goodies=cambria-math] + \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math,mathextra},\s!goodies=cambria-math] + \definefontsynonym [\s!MathRomanBold] [CambriaMath] [\s!features={\s!math,cambria-math-bold,mathextra},\s!goodies=cambria-math] \stoptypescript \starttypescript [\s!math] [cambria-y] [\s!name] \loadfontgoodies[cambria-math] - \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math-nostack\mathsizesuffix,mathextra},\s!goodies=cambria-math] + \definefontsynonym [\s!MathRoman] [CambriaMath] [\s!features={\s!math-nostack\mathsizesuffix,mathextra},\s!goodies=cambria-math] + \definefontsynonym [\s!MathRomanBold] [CambriaMath] [\s!features={\s!math-nostack\mathsizesuffix,cambria-math-bold,mathextra},\s!goodies=cambria-math] \stoptypescript \starttypescript [\s!serif] [cambria,cambria-m,cambria-a] [\s!name] diff --git a/tex/context/fonts/mkiv/type-imp-dejavu.mkiv b/tex/context/fonts/mkiv/type-imp-dejavu.mkiv index 582d8a764..3af9d2d17 100644 --- a/tex/context/fonts/mkiv/type-imp-dejavu.mkiv +++ b/tex/context/fonts/mkiv/type-imp-dejavu.mkiv @@ -15,6 +15,8 @@ \starttypescriptcollection[dejavu] + \doifunknownfontfeature {dejavu-math-bold} {\definefontfeature[dejavu-math-bold][boldened]} + \starttypescript [\s!serif] [dejavu] [\s!name] \setups[\s!font:\s!fallback:\s!serif] \definefontsynonym [\s!Serif] [\s!name:dejavuserif] [\s!features=\s!default,\s!fallbacks=\s!Serif] @@ -41,7 +43,8 @@ \starttypescript [\s!math][dejavu][\s!name] \loadfontgoodies[dejavu-math] - \definefontsynonym[\s!MathRoman][file:texgyredejavu-math][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=dejavu-math] + \definefontsynonym[\s!MathRoman] [file:texgyredejavu-math][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=dejavu-math] + \definefontsynonym[\s!MathRomanBold][file:texgyredejavu-math][\s!features={\s!math\mathsizesuffix,dejavu-math-bold,mathextra},\s!goodies=schola-math] \stoptypescript \starttypescript[dejavu] diff --git a/tex/context/fonts/mkiv/type-imp-firacode.mkiv b/tex/context/fonts/mkiv/type-imp-firacode.mkiv new file mode 100644 index 000000000..a4cec3af5 --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-firacode.mkiv @@ -0,0 +1,54 @@ +%D \module +%D [ file=type-imp-firacode, +%D version=2018.08.24, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Firacode, +%D author=Taco Hoekwater \& 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. + + +\starttypescriptcollection[firacode] + + \usetypescriptfile[dejavu] + + \definefontfeature + [firacode] + [mode=node,script=dflt,language=dflt, + calt=yes,mark=yes,mkmk=yes] + + \starttypescript [\s!mono] [firacode] + \definefontsynonym[FiraRetina] [\s!name:firacoderetina] [\s!features=firacode] + \definefontsynonym[FiraLight] [\s!name:firacodelight] [\s!features=firacode] + \definefontsynonym[FiraRegular][\s!name:firacoderegular][\s!features=firacode] + \definefontsynonym[FiraMedium] [\s!name:firacodemedium] [\s!features=firacode] + \definefontsynonym[FiraBold] [\s!name:firacodebold] [\s!features=firacode] + \stoptypescript + + \starttypescript [\s!mono] [firacode-light] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym[\s!Mono] [FiraLight] + \definefontsynonym[\s!MonoBold][FiraMedium] + \stoptypescript + + \starttypescript [\s!mono] [firacode] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym[\s!Mono] [FiraRegular] + \definefontsynonym[\s!MonoBold][FiraBold] + \stoptypescript + + \starttypescript[firacode] + \definetypeface[firacode][\s!rm][\s!serif][dejavu] [\s!default] + \definetypeface[firacode][\s!ss][\s!sans] [dejavu] [\s!default] + \definetypeface[firacode][\s!mm][\s!math] [dejavu] [\s!default] + \definetypeface[firacode][\s!tt][\s!mono] [firacode][\s!default] + \stoptypescript + +\stoptypescriptcollection + +% \setupbodyfont[firacode,12pt] + diff --git a/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv b/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv index 63f74027b..cc9559d8b 100644 --- a/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv +++ b/tex/context/fonts/mkiv/type-imp-latinmodern.mkiv @@ -28,6 +28,8 @@ \starttypescriptcollection[latinmodern] + \doifunknownfontfeature {lm-math-bold} {\definefontfeature[lm-math-bold][boldened]} + \starttypescript [\s!serif] [simple] [\s!name] \definefontsynonym [\s!Simple] [\s!file:lmmonoproplt10-regular] [\s!features=\s!default] \stoptypescript @@ -180,7 +182,7 @@ \starttypescript [\s!math] [modern,latin-modern] \loadfontgoodies[lm] \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,mathextra},\s!goodies=lm] - \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,mathextra},\s!goodies=lm] + \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math-bold,lm-math,mathextra},\s!goodies=lm] \stoptypescript \starttypescript [modern-designsize-virtual] diff --git a/tex/context/fonts/mkiv/type-imp-lato.mkiv b/tex/context/fonts/mkiv/type-imp-lato.mkiv index 4a0dbeb36..359c2285f 100644 --- a/tex/context/fonts/mkiv/type-imp-lato.mkiv +++ b/tex/context/fonts/mkiv/type-imp-lato.mkiv @@ -58,7 +58,7 @@ \definefontsynonym [\s!SansItalic] [\s!file:lato-bolditalic] [\s!features=\s!default] \definefontsynonym [\s!SansBoldItalic] [\s!file:lato-heavyitalic] [\s!features=\s!default] \stoptypescript - + \starttypescript [\s!sans] [lato-black] [\s!name] \setups[\s!font:\s!fallback:\s!sans] \definefontsynonym [\s!Sans] [\s!file:lato-heavy] [\s!features=\s!default] @@ -98,6 +98,7 @@ \definefontsynonym [\s!SansItalic] [\s!file:lato-italic] [\s!features=\s!default] \definefontsynonym [\s!SansBoldItalic] [\s!file:lato-semibolditalic] [\s!features=\s!default] \stoptypescript + \starttypescript[lato,lato-light,lato-dark,lato-black,lato-hairline,lato-thin,lato-medium,lato-semibold] \definetypeface [\typescriptone] [\s!ss] [\s!sans] [\typescriptone] [\s!default] \definetypeface [\typescriptone] [\s!rm] [\s!serif] [dejavu] [\s!default] diff --git a/tex/context/fonts/mkiv/type-imp-lucida-typeone.mkiv b/tex/context/fonts/mkiv/type-imp-lucida-typeone.mkiv index 5f28b9eed..59d167a1b 100644 --- a/tex/context/fonts/mkiv/type-imp-lucida-typeone.mkiv +++ b/tex/context/fonts/mkiv/type-imp-lucida-typeone.mkiv @@ -11,6 +11,8 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. +\writestatus{fonts}{Lucida Type 1 support can be broken due to wrong files!} + \starttypescriptcollection[lucida-typeone] \starttypescript [\s!serif] [lucida] diff --git a/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv b/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv index a3f4762f1..2494d1af2 100644 --- a/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv +++ b/tex/context/fonts/mkiv/type-imp-modernlatin.mkiv @@ -13,50 +13,52 @@ \starttypescriptcollection[modernlatin] - \definefontfeature[lm-rm-regular][effect={width=0.15,delta=1.00}] - \definefontfeature[lm-rm-bold] [effect={width=0.30,delta=1.00}] - \definefontfeature[lm-ss-regular][effect={width=0.10,delta=1.00}] - \definefontfeature[lm-ss-bold] [effect={width=0.20,delta=1.00}] - \definefontfeature[lm-tt-regular][effect={width=0.20,delta=1.00}] - \definefontfeature[lm-tt-bold] [effect={width=0.30,delta=1.00}] + \doifunknownfontfeature {lm-serif-regular} {\definefontfeature[lm-serif-regular][boldened-15]} + \doifunknownfontfeature {lm-serif-bold} {\definefontfeature[lm-serif-bold] [boldened-30]} + \doifunknownfontfeature {lm-sans-regular} {\definefontfeature[lm-sans-regular] [boldened-10]} + \doifunknownfontfeature {lm-sans-bold} {\definefontfeature[lm-sans-bold] [boldened-20]} + \doifunknownfontfeature {lm-mono-regular} {\definefontfeature[lm-mono-regular] [boldened-20]} + \doifunknownfontfeature {lm-mono-bold} {\definefontfeature[lm-mono-bold] [boldened-30]} + \doifunknownfontfeature {lm-math-regular} {\definefontfeature[lm-math-regular] [boldened-15]} + \doifunknownfontfeature {lm-math-bold} {\definefontfeature[lm-math-bold] [boldened-30]} \starttypescript [\s!serif] [modern-latin] % \loadfontgoodies[lm] - \definefontsynonym [Serif] [\s!file:lmroman10-regular] [\s!features={\s!default,lm-rm-regular}] - \definefontsynonym [SerifItalic] [\s!file:lmroman10-italic] [\s!features={\s!default,lm-rm-regular}] - \definefontsynonym [SerifSlanted] [\s!file:lmromanslant10-regular] [\s!features={\s!default,lm-rm-regular}] - \definefontsynonym [SerifBold] [\s!file:lmroman10-regular] [\s!features={\s!default,lm-rm-bold}] - \definefontsynonym [SerifBoldItalic] [\s!file:lmroman10-italic] [\s!features={\s!default,lm-rm-bold}] - \definefontsynonym [SerifBoldSlanted][\s!file:lmromanslant10-regular] [\s!features={\s!default,lm-rm-bold}] + \definefontsynonym [Serif] [\s!file:lmroman10-regular] [\s!features={\s!default,lm-serif-regular}] + \definefontsynonym [SerifItalic] [\s!file:lmroman10-italic] [\s!features={\s!default,lm-serif-regular}] + \definefontsynonym [SerifSlanted] [\s!file:lmromanslant10-regular] [\s!features={\s!default,lm-serif-regular}] + \definefontsynonym [SerifBold] [\s!file:lmroman10-regular] [\s!features={\s!default,lm-serif-bold}] + \definefontsynonym [SerifBoldItalic] [\s!file:lmroman10-italic] [\s!features={\s!default,lm-serif-bold}] + \definefontsynonym [SerifBoldSlanted][\s!file:lmromanslant10-regular] [\s!features={\s!default,lm-serif-bold}] \stoptypescript \starttypescript [\s!sans] [modern-latin] % \loadfontgoodies[lm] - \definefontsynonym [Sans] [\s!file:lmsans10-regular] [\s!features={\s!default,lm-ss-regular}] - \definefontsynonym [SansItalic] [\s!file:lmsans10-oblique] [\s!features={\s!default,lm-ss-regular}] - \definefontsynonym [SansSlanted] [\s!file:lmsans10-oblique] [\s!features={\s!default,lm-ss-regular}] - \definefontsynonym [SansBold] [\s!file:lmsans10-regular] [\s!features={\s!default,lm-ss-bold}] - \definefontsynonym [SansBoldItalic] [\s!file:lmsans10-oblique] [\s!features={\s!default,lm-ss-bold}] - \definefontsynonym [SansBoldSlanted][\s!file:lmsans10-oblique] [\s!features={\s!default,lm-ss-bold}] + \definefontsynonym [Sans] [\s!file:lmsans10-regular] [\s!features={\s!default,lm-sans-regular}] + \definefontsynonym [SansItalic] [\s!file:lmsans10-oblique] [\s!features={\s!default,lm-sans-regular}] + \definefontsynonym [SansSlanted] [\s!file:lmsans10-oblique] [\s!features={\s!default,lm-sans-regular}] + \definefontsynonym [SansBold] [\s!file:lmsans10-regular] [\s!features={\s!default,lm-sans-bold}] + \definefontsynonym [SansBoldItalic] [\s!file:lmsans10-oblique] [\s!features={\s!default,lm-sans-bold}] + \definefontsynonym [SansBoldSlanted][\s!file:lmsans10-oblique] [\s!features={\s!default,lm-sans-bold}] \stoptypescript \starttypescript [\s!mono] [modern-latin] % \loadfontgoodies[lm] - \definefontsynonym [Mono] [\s!file:lmmono10-regular] [\s!features={\s!default,lm-tt-regular}] - \definefontsynonym [MonoItalic] [\s!file:lmmono10-italic] [\s!features={\s!default,lm-tt-regular}] - \definefontsynonym [MonoSlanted] [\s!file:lmmonoslant10-regular] [\s!features={\s!default,lm-tt-regular}] - \definefontsynonym [MonoBold] [\s!file:lmmono10-regular] [\s!features={\s!default,lm-tt-bold}] - \definefontsynonym [MonoBoldItalic] [\s!file:lmmono10-italic] [\s!features={\s!default,lm-tt-bold}] - \definefontsynonym [MonoBoldSlanted][\s!file:lmmonoslant10-regular] [\s!features={\s!default,lm-tt-bold}] + \definefontsynonym [Mono] [\s!file:lmmono10-regular] [\s!features={\s!default,lm-mono-regular}] + \definefontsynonym [MonoItalic] [\s!file:lmmono10-italic] [\s!features={\s!default,lm-mono-regular}] + \definefontsynonym [MonoSlanted] [\s!file:lmmonoslant10-regular] [\s!features={\s!default,lm-mono-regular}] + \definefontsynonym [MonoBold] [\s!file:lmmono10-regular] [\s!features={\s!default,lm-mono-bold}] + \definefontsynonym [MonoBoldItalic] [\s!file:lmmono10-italic] [\s!features={\s!default,lm-mono-bold}] + \definefontsynonym [MonoBoldSlanted][\s!file:lmmonoslant10-regular] [\s!features={\s!default,lm-mono-bold}] \stoptypescript \starttypescript [\s!math] [modern-latin] \loadfontgoodies[lm] - \definefontsynonym [LMMathRoman-Regular] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,mathextra},\s!goodies=lm] - \definefontsynonym [LMMathRoman-Bold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,mathextra},\s!goodies=lm] + \definefontsynonym [MathRoman] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,lm-math-regular,mathextra},\s!goodies=lm] + \definefontsynonym [MathRomanBold] [\v!file:latinmodern-math-regular.otf] [\s!features={\s!math\mathsizesuffix,lm-math,lm-math-bold,mathextra},\s!goodies=lm] \stoptypescript - \starttypescript [modern-latin] + \starttypescript [modern-latin,modernlatin] \definetypeface [\typescriptone] [\s!rm] [\s!serif] [modern-latin] [\s!default] \definetypeface [\typescriptone] [\s!ss] [\s!sans] [modern-latin] [\s!default] \definetypeface [\typescriptone] [\s!tt] [\s!mono] [modern-latin] [\s!default] diff --git a/tex/context/fonts/mkiv/type-imp-opendyslexic.mkiv b/tex/context/fonts/mkiv/type-imp-opendyslexic.mkiv index 770d43c6c..c3b8a3ef2 100644 --- a/tex/context/fonts/mkiv/type-imp-opendyslexic.mkiv +++ b/tex/context/fonts/mkiv/type-imp-opendyslexic.mkiv @@ -29,10 +29,15 @@ \definefontsynonym [\s!SansBoldItalic] [\s!file:opendyslexicalta-bolditalic.otf] [\s!features=\s!default] \stoptypescript + \starttypescript [\s!mono] [opendyslexic] [\s!name] + \setups[\s!font:\s!fallback:\s!mono] + \definefontsynonym [\s!Mono] [\s!file:opendyslexicmono-regular.otf] [\s!features=\s!none] + \stoptypescript + \starttypescript[opendyslexic] \definetypeface [opendyslexic] [\s!rm] [\s!serif] [opendyslexic] [\s!default] \definetypeface [opendyslexic] [\s!ss] [\s!sans] [opendyslexic] [\s!default] - \definetypeface [opendyslexic] [\s!tt] [\s!mono] [dejavu] [\s!default]% [rscale=1.065] + \definetypeface [opendyslexic] [\s!tt] [\s!mono] [opendyslexic] [\s!default]% [rscale=1.065] \definetypeface [opendyslexic] [\s!mm] [\s!math] [xits] [\s!default]% [rscale=1.020] \stoptypescript diff --git a/tex/context/fonts/mkiv/type-imp-plex.mkiv b/tex/context/fonts/mkiv/type-imp-plex.mkiv new file mode 100644 index 000000000..44334bcbd --- /dev/null +++ b/tex/context/fonts/mkiv/type-imp-plex.mkiv @@ -0,0 +1,370 @@ +%D \module +%D [ file=type-imp-plex, +%D version=2018.09.11, +%D title=\CONTEXT\ Typescript Macros, +%D subtitle=Plex fonts, +%D author={Hans Hagen & Taco Hoekwater}, +%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. + +% Taco will make a special (more verbose) one for the ConTeXt journal! That setup will also have +% adapted interline spacing matching the larger ascenders. + +% thin, extralight, light, regular, text, medium, semibold, bold + +% [IBMPlexMono|IBMPlexSans|IBMPlexSerif|IBMPlexSansCondensed]-[Thin|ExtraLight|Light||Text|Medium|SemiBold|Bold].otf +% [IBMPlexMono|IBMPlexSans|IBMPlexSerif|IBMPlexSansCondensed]-[Thin|ExtraLight|Light||Text|Medium|SemiBold|Bold]Italic.otf + +% [IBMPlexSans][Hebrew]-[Thin|Light||Text|Medium|SemiBold|Bold|].otf + +\loadtypescriptfile[bookman] + +\starttypescriptcollection[plex] + + \definetypescriptprefix [n:plexserif] [IBMPlexSerif] + \definetypescriptprefix [n:plexsans] [IBMPlexSans] + \definetypescriptprefix [n:plexmono] [IBMPlexMono] + + \definetypescriptprefix [n:narrowplexserif] [IBMPlexSerif] + \definetypescriptprefix [n:narrowplexsans] [IBMPlexSansCondensed] + \definetypescriptprefix [n:narrowplexmono] [IBMPlexMono] + + \definetypescriptprefix [f:plexserif] [\s!default] + \definetypescriptprefix [f:plexsans] [\s!default] + \definetypescriptprefix [f:plexmono] [\s!none] + + \definetypescriptprefix [f:narrowplexserif] [\s!default] + \definetypescriptprefix [f:narrowplexsans] [\s!default] + \definetypescriptprefix [f:narrowplexmono] [\s!none] + + % thin + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-thin] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-thin] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-thinitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % extralight + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-extralight] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-regular] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-italic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % light + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-light] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-lightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-text] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % regular + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-regular] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-italic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-medium] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-mediumitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % text + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-text] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-text] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % medium + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-medium] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-medium] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-mediumitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-bold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % semibold + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-semibold] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-extra] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-extraitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % bold + + \starttypescript [\s!sans,\s!serif,\s!mono] [plex-bold] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-bold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-bold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \stoptypescript + + % done + + \starttypescript[plex,plex-thin,plex-extralight,plex-light,plex,plex-text,plex-medium,plex-semibold,plex-bold] + \definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!ss] [\s!sans] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!tt] [\s!mono] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!mm] [\s!math] [bookman] [\s!default] [\s!rscale=1.03] + \stoptypescript + + % Here's Taco's variant as used in the ConTeXt Group Journal. + + \definefontfeature[plexwidened][extend=\luaexpr{1/0.85}] % An odd floating point number to correct monospace. + + \definetypescriptprefix [f:scplexserif] [\s!default,plexwidened] + \definetypescriptprefix [f:scplexsans] [\s!default,plexwidened] + \definetypescriptprefix [f:scplexmono] [plexwidened] + + \definetypescriptprefix [f:scnarrowplexserif] [\s!default,plexwidened] + \definetypescriptprefix [f:scnarrowplexsans] [\s!default,plexwidened] + \definetypescriptprefix [f:scnarrowplexmono] [plexwidened] + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-thin] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-thin] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-thinitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-text] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-textitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:plex\typescriptone}-thin] [\s!features=\typescriptprefix{f:scplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:plex\typescriptone}-thin] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-extralight] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-medium] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-mediumitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight] [\s!features=\typescriptprefix{f:scplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex-light] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-lightitalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] [\s!features=\typescriptprefix{f:scplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplex] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-regular] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:plex\typescriptone}-italic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-bold] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:plex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:plex\typescriptone}-regular] [\s!features=\typescriptprefix{f:scplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:plex\typescriptone}-regular] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + % narrow + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow-thin] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thinitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-text] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-textitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin] [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow-extralight] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralightitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-medium] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-mediumitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight] [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow-light] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-lightitalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-semibold] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-semibolditalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light] [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + \starttypescript [\s!sans,\s!serif,\s!mono] [ibmplexnarrow] [\s!name] + \setups[\s!font:\s!fallback:\typescriptone] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Italic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-italic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-bold] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!BoldItalic] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-bolditalic] [\s!features=\typescriptprefix{f:narrowplex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Widened] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular] [\s!features=\typescriptprefix{f:scnarrowplex\typescriptone}] + \definefontfallback[Fake\typescriptprefix{\typescriptone}Caps] [\typescriptprefix{\typescriptone}Widened] [0x0000-0xFFFF] [\s!rscale=0.85,method=uppercase] + \definefontsynonym [\typescriptprefix{\typescriptone}Caps] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular] [\s!fallbacks=Fake\typescriptprefix{\typescriptone}Caps] + \stoptypescript + + + % For now, as some day plex will have cjk, hebrew, devanagari and arabic. The abstraction is not needed but + % this way we can add more id needed without much code. + + \definetypescriptprefix [tf:plexsans] [SansHebrewFallback] + \definetypescriptprefix [bf:plexsans] [SansHebrewFallbackBold] + + \definetypescriptprefix [n:plexsans-hebrew] [IBMPlexSansHebrew] + + \definefontfallback [SansHebrewFallback] [SansHebrew] [0x0590-0x05ff] [check=yes,force=no] + \definefontfallback [SansHebrewFallbackBold] [SansHebrewBold] [0x0590-0x05ff] [check=yes,force=no] + + \starttypescript [\s!sans] [ibmplex-thin] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-thin] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-text] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-thin] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-text] + [\s!features=hebrew] + \stoptypescript + + \starttypescript [\s!sans] [ibmplex-extralight] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-extralight] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-medium] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-extralight] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-medium] + [\s!features=hebrew] + \stoptypescript + + \starttypescript [\s!sans] [ibmplex-light] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-light] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-semibold] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-light] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-semibold] + [\s!features=hebrew] + \stoptypescript + + \starttypescript [\s!sans] [ibmplex] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:plex\typescriptone}-regular] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone}-bold] + [\s!features=\typescriptprefix{f:plex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-regular] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:plex\typescriptone-hebrew}-bold] + [\s!features=hebrew] + \stoptypescript + + % narrow + + \starttypescript [\s!sans] [ibmplexnarrow-thin] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-thin] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-text] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-thin] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-text] + [\s!features=hebrew] + \stoptypescript + + \starttypescript [\s!sans] [ibmplexnarrow-extralight] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-extralight] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-medium] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-extralight] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-medium] + [\s!features=hebrew] + \stoptypescript + + \starttypescript [\s!sans] [ibmplexnarrow-light] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-light] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-semibold] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-light] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-semibold] + [\s!features=hebrew] + \stoptypescript + + \starttypescript [\s!sans] [ibmplexnarrow] [\s!name] + \definefontsynonym [\typescriptprefix{\typescriptone}] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-regular] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{tf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone}-bold] + [\s!features=\typescriptprefix{f:narrowplex\typescriptone}, + \s!fallbacks=\typescriptprefix{bf:plex\typescriptone}] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-regular] + [\s!features=hebrew] + \definefontsynonym [\typescriptprefix{\typescriptone}Hebrew\s!Bold] [\s!file:\typescriptprefix{n:narrowplex\typescriptone-hebrew}-bold] + [\s!features=hebrew] + \stoptypescript + + % The main definition, inspired by discussion at the 2018 ConTeXt meeting after a talk by Taco. Here + % we default to sans serif. Taco: take your choice of math! + + \starttypescript[ibmplex,ibmplex-thin,ibmplex-extralight,ibmplex-light] + \definetypeface [\typescriptone] [\s!ss] [\s!sans] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!tt] [\s!mono] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!mm] [\s!math] [bookman] [\s!default] [\s!rscale=1.03] + \stoptypescript + + \starttypescript[ibmplexnarrow,ibmplexnarrow-thin,ibmplexnarrow-extralight,ibmplexnarrow-light] + \definetypeface [\typescriptone] [\s!ss] [\s!sans] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!rm] [\s!serif] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!tt] [\s!mono] [\typescriptone] [\s!default] + \definetypeface [\typescriptone] [\s!mm] [\s!math] [bookman] [\s!default] [\s!rscale=1.03] + \stoptypescript + +\stoptypescriptcollection diff --git a/tex/context/fonts/mkiv/type-imp-source.mkiv b/tex/context/fonts/mkiv/type-imp-source.mkiv index 91396f965..ab94727e8 100644 --- a/tex/context/fonts/mkiv/type-imp-source.mkiv +++ b/tex/context/fonts/mkiv/type-imp-source.mkiv @@ -17,38 +17,38 @@ \starttypescript [\s!serif] [source] [\s!name] \setups[\s!font:\s!fallback:\s!serif] - \definefontsynonym [\s!Serif] [\s!file:SourceSerifPro-Regular.ttf] [\s!features=\s!default] - \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Bold.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Semibold.ttf] [\s!features=\s!default] - \definefontsynonym [\s!SerifItalic] [\s!file:SourceSerifPro-Regular.ttf] [\s!features={\s!default,source-serif-slanted}] - \definefontsynonym [\s!SerifBoldItalic] [\s!file:SourceSerifPro-Bold.ttf] [\s!features={\s!default,source-serif-slanted}] + \definefontsynonym [\s!Serif] [\s!file:SourceSerifPro-Regular] [\s!features=\s!default] + \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Bold] [\s!features=\s!default] + % \definefontsynonym [\s!SerifBold] [\s!file:SourceSerifPro-Semibold] [\s!features=\s!default] + \definefontsynonym [\s!SerifItalic] [\s!file:SourceSerifPro-Regular] [\s!features={\s!default,source-serif-slanted}] + \definefontsynonym [\s!SerifBoldItalic] [\s!file:SourceSerifPro-Bold] [\s!features={\s!default,source-serif-slanted}] \stoptypescript \starttypescript [\s!sans] [source] [\s!name] \setups[\s!font:\s!fallback:\s!sans] - % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-ExtraLight.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Light.ttf] [\s!features=\s!default] - \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Regular.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Semibold.ttf] [\s!features=\s!default] - \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Bold.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Black.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-ExtraLightItalic.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-LightItalic.ttf] [\s!features=\s!default] - \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-Italic.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-SemiboldItalic.ttf] [\s!features=\s!default] - \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BoldItalic.ttf] [\s!features=\s!default] - % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BlackItalic.ttf] [\s!features=\s!default] + % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-ExtraLight] [\s!features=\s!default] + % \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Light] [\s!features=\s!default] + \definefontsynonym [\s!Sans] [\s!file:SourceSansPro-Regular] [\s!features=\s!default] + % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Semibold] [\s!features=\s!default] + \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Bold] [\s!features=\s!default] + % \definefontsynonym [\s!SansBold] [\s!file:SourceSansPro-Black] [\s!features=\s!default] + % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-ExtraLightItalic] [\s!features=\s!default] + % \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-LightItalic] [\s!features=\s!default] + \definefontsynonym [\s!SansItalic] [\s!file:SourceSansPro-Italic] [\s!features=\s!default] + % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-SemiboldItalic] [\s!features=\s!default] + \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BoldItalic] [\s!features=\s!default] + % \definefontsynonym [\s!SansBoldItalic] [\s!file:SourceSansPro-BlackItalic] [\s!features=\s!default] \stoptypescript \starttypescript [\s!mono] [source] [\s!name] \setups[\s!font:\s!fallback:\s!mono] - % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-ExtraLight.ttf] [\s!features=\s!none] - % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Light.ttf] [\s!features=\s!none] - \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Regular.ttf] [\s!features=\s!none] - % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Medium.ttf] [\s!features=\s!none] - % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Semibold.ttf] [\s!features=\s!none] - \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Bold.ttf] [\s!features=\s!none] - % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Black.ttf] [\s!features=\s!none] + % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-ExtraLight] [\s!features=\s!none] + % \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Light] [\s!features=\s!none] + \definefontsynonym [\s!Mono] [\s!file:SourceCodePro-Regular] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Medium] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Semibold] [\s!features=\s!none] + \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Bold] [\s!features=\s!none] + % \definefontsynonym [\s!MonoBold] [\s!file:SourceCodePro-Black] [\s!features=\s!none] \stoptypescript \starttypescript [\s!math][source][\s!name] diff --git a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv index 2bec4c2a8..583da77c1 100644 --- a/tex/context/fonts/mkiv/type-imp-texgyre.mkiv +++ b/tex/context/fonts/mkiv/type-imp-texgyre.mkiv @@ -20,6 +20,11 @@ \starttypescriptcollection[texgyre] + \doifunknownfontfeature {pagella-math-bold} {\definefontfeature[pagella-math-bold][boldened]} + \doifunknownfontfeature {schola-math-bold} {\definefontfeature[schola-math-bold] [boldened]} + \doifunknownfontfeature {bonum-math-bold} {\definefontfeature[bonum-math-bold] [boldened]} + \doifunknownfontfeature {termes-math-bold} {\definefontfeature[termes-math-bold] [boldened]} + \definetypescriptprefix [f:pagella] [pagella] \definetypescriptprefix [f:termes] [termes] \definetypescriptprefix [f:heros] [heros] @@ -242,7 +247,8 @@ \starttypescript [\s!math][times,termes][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-termes-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=termes-math] + \definefontsynonym[\s!MathRoman] [file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=termes-math] + \definefontsynonym[\s!MathRomanBold][file:texgyretermes-math.otf][\s!features={\s!math\mathsizesuffix,termes-math-bold,mathextra},\s!goodies=schola-math] \stoptypescript \stoptypescriptcollection @@ -270,7 +276,8 @@ \starttypescript [\s!math][palatino,pagella][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-pagella-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=pagella-math] + \definefontsynonym[\s!MathRoman] [file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=pagella-math] + \definefontsynonym[\s!MathRomanBold][file:texgyrepagella-math.otf][\s!features={\s!math\mathsizesuffix,pagella-math-bold,mathextra},\s!goodies=schola-math] \stoptypescript \stoptypescriptcollection @@ -282,7 +289,8 @@ \starttypescript [\s!math][bookman,bonum][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-bonum-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=bonum-math] + \definefontsynonym[\s!MathRoman] [file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=bonum-math] + \definefontsynonym[\s!MathRomanBold][file:texgyrebonum-math.otf][\s!features={\s!math\mathsizesuffix,bonum-math-bold,mathextra},\s!goodies=schola-math] \stoptypescript \stoptypescriptcollection @@ -292,7 +300,8 @@ \starttypescript [\s!math][schoolbook,schola][\s!all] % \loadfontgoodies[texgyre] % \definefontsynonym[\s!MathRoman][file:texgyre-schola-math-regular.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=texgyre] - \definefontsynonym[\s!MathRoman][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=schola-math] + \definefontsynonym[\s!MathRoman] [file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=schola-math] + \definefontsynonym[\s!MathRomanBold][file:texgyreschola-math.otf][\s!features={\s!math\mathsizesuffix,schola-math-bold,mathextra},\s!goodies=schola-math] \stoptypescript \stoptypescriptcollection diff --git a/tex/context/interface/mkii/keys-cs.xml b/tex/context/interface/mkii/keys-cs.xml index 521393c17..f4e65c527 100644 --- a/tex/context/interface/mkii/keys-cs.xml +++ b/tex/context/interface/mkii/keys-cs.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -589,6 +590,7 @@ + @@ -859,7 +861,7 @@ - + @@ -1033,6 +1035,7 @@ + @@ -1246,6 +1249,7 @@ + @@ -1274,12 +1278,14 @@ + + diff --git a/tex/context/interface/mkii/keys-de.xml b/tex/context/interface/mkii/keys-de.xml index f399f128a..701dc246b 100644 --- a/tex/context/interface/mkii/keys-de.xml +++ b/tex/context/interface/mkii/keys-de.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -589,6 +590,7 @@ + @@ -1033,6 +1035,7 @@ + @@ -1246,6 +1249,7 @@ + @@ -1274,12 +1278,14 @@ + + diff --git a/tex/context/interface/mkii/keys-en.xml b/tex/context/interface/mkii/keys-en.xml index dccff3a98..a3606e38b 100644 --- a/tex/context/interface/mkii/keys-en.xml +++ b/tex/context/interface/mkii/keys-en.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -1033,6 +1034,7 @@ + @@ -1246,6 +1248,7 @@ + @@ -1274,12 +1277,14 @@ + + diff --git a/tex/context/interface/mkii/keys-fr.xml b/tex/context/interface/mkii/keys-fr.xml index ab256770c..452f3316a 100644 --- a/tex/context/interface/mkii/keys-fr.xml +++ b/tex/context/interface/mkii/keys-fr.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -1033,6 +1034,7 @@ + @@ -1246,6 +1248,7 @@ + @@ -1274,12 +1277,14 @@ + + diff --git a/tex/context/interface/mkii/keys-it.xml b/tex/context/interface/mkii/keys-it.xml index da7970619..2ebcb4a9d 100644 --- a/tex/context/interface/mkii/keys-it.xml +++ b/tex/context/interface/mkii/keys-it.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -589,6 +590,7 @@ + @@ -1033,6 +1035,7 @@ + @@ -1246,6 +1249,7 @@ + @@ -1274,12 +1278,14 @@ + + diff --git a/tex/context/interface/mkii/keys-nl.xml b/tex/context/interface/mkii/keys-nl.xml index 212685d44..1104e14c1 100644 --- a/tex/context/interface/mkii/keys-nl.xml +++ b/tex/context/interface/mkii/keys-nl.xml @@ -140,6 +140,7 @@ + @@ -188,6 +189,7 @@ + @@ -800,7 +802,7 @@ - + @@ -855,6 +857,7 @@ + @@ -1031,6 +1034,7 @@ + @@ -1081,6 +1085,7 @@ + @@ -1166,8 +1171,10 @@ + + @@ -1241,6 +1248,7 @@ + @@ -1269,12 +1277,14 @@ + + diff --git a/tex/context/interface/mkii/keys-pe.xml b/tex/context/interface/mkii/keys-pe.xml index e587e1d6e..bd42a83dd 100644 --- a/tex/context/interface/mkii/keys-pe.xml +++ b/tex/context/interface/mkii/keys-pe.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -1033,6 +1034,7 @@ + @@ -1246,6 +1248,7 @@ + @@ -1274,12 +1277,14 @@ + + diff --git a/tex/context/interface/mkii/keys-ro.xml b/tex/context/interface/mkii/keys-ro.xml index c0308086c..5f165f88b 100644 --- a/tex/context/interface/mkii/keys-ro.xml +++ b/tex/context/interface/mkii/keys-ro.xml @@ -140,6 +140,7 @@ + @@ -421,7 +422,7 @@ - + @@ -589,6 +590,7 @@ + @@ -1033,6 +1035,7 @@ + @@ -1246,6 +1249,7 @@ + @@ -1274,12 +1278,14 @@ + + diff --git a/tex/context/interface/mkiv/context-en.xml b/tex/context/interface/mkiv/context-en.xml index 4cfb3c7fe..73af42a96 100644 --- a/tex/context/interface/mkiv/context-en.xml +++ b/tex/context/interface/mkiv/context-en.xml @@ -780,6 +780,7 @@ + @@ -793,6 +794,7 @@ + @@ -864,23 +866,23 @@ - + - - + + - - - - - - - + + + + + + + - - + + @@ -1444,9 +1446,31 @@ + + + + + + + + + + + + + + + + + + + + + + @@ -1467,6 +1491,11 @@ + + + + + @@ -1537,6 +1566,13 @@ + + + + + + + @@ -1571,6 +1607,7 @@ + @@ -1885,6 +1922,17 @@ + + + + + + + + + + + @@ -2975,6 +3023,10 @@ + + + + @@ -2993,7 +3045,7 @@ - + @@ -3012,7 +3064,7 @@ - + @@ -3740,6 +3792,13 @@ + + + + + + + @@ -3796,8 +3855,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3811,6 +3896,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4681,7 +4791,7 @@ - + @@ -4787,7 +4897,7 @@ - + @@ -5111,10 +5221,10 @@ - + - + @@ -5147,7 +5257,7 @@ - + @@ -5654,6 +5764,16 @@ + + + + + + + + + + @@ -6627,6 +6747,7 @@ + @@ -7211,6 +7332,7 @@ + @@ -7458,6 +7580,7 @@ + @@ -7541,6 +7664,10 @@ + + + + @@ -7958,6 +8085,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -8054,7 +8227,7 @@ - + @@ -8191,6 +8364,7 @@ + @@ -8274,6 +8448,10 @@ + + + + @@ -9537,6 +9715,21 @@ + + + + + + + + + + + + + + + @@ -10099,10 +10292,10 @@ - + - + @@ -10118,6 +10311,7 @@ + @@ -10131,7 +10325,7 @@ - + @@ -10153,6 +10347,7 @@ + @@ -10192,6 +10387,13 @@ + + + + + + + @@ -10247,26 +10449,27 @@ + - + - + - + - + @@ -10930,6 +11133,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -11201,12 +11451,20 @@ + + + + + + + + @@ -11461,7 +11719,7 @@ - + @@ -11575,6 +11833,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -12119,7 +12416,7 @@ - + @@ -13273,6 +13570,9 @@ + + + @@ -13311,6 +13611,9 @@ + + + @@ -13320,6 +13623,9 @@ + + + @@ -13535,21 +13841,25 @@ + + + + @@ -13566,6 +13876,8 @@ + + @@ -13613,6 +13925,9 @@ + + + @@ -14055,6 +14370,17 @@ + + + + + + + + + + + @@ -14360,6 +14686,16 @@ + + + + + + + + + + @@ -14678,6 +15014,20 @@ + + + + + + + + + + + + + + @@ -14694,6 +15044,7 @@ + @@ -14924,6 +15275,12 @@ + + + + + + @@ -15151,6 +15508,7 @@ + @@ -15189,10 +15547,12 @@ + + @@ -16457,6 +16817,7 @@ + @@ -17890,6 +18251,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -17994,6 +18389,7 @@ + @@ -18078,6 +18474,10 @@ + + + + @@ -18361,6 +18761,9 @@ + + + @@ -18385,6 +18788,7 @@ + @@ -18517,6 +18921,13 @@ + + + + + + + @@ -19120,6 +19531,7 @@ + @@ -19313,7 +19725,7 @@ - + @@ -19323,7 +19735,7 @@ - + @@ -19334,6 +19746,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -19825,7 +20338,6 @@ - @@ -20022,6 +20534,7 @@ + @@ -20152,7 +20665,7 @@ - + @@ -20162,7 +20675,55 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -20172,7 +20733,7 @@ - + @@ -20183,7 +20744,7 @@ - + @@ -20197,7 +20758,7 @@ - + @@ -20211,7 +20772,7 @@ - + @@ -21617,6 +22178,7 @@ + @@ -21692,6 +22254,17 @@ + + + + + + + + + + + @@ -22302,6 +22875,9 @@ + + + @@ -22558,6 +23134,14 @@ + + + + + + + + @@ -24807,6 +25391,10 @@ + + + + @@ -25165,6 +25753,7 @@ + @@ -26052,6 +26641,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -26118,7 +26782,7 @@ - + @@ -26127,14 +26791,15 @@ - + - + + @@ -26173,43 +26838,27 @@ - + - + - + - + - - - - - - - - - - - - - - - - + - - + @@ -26218,11 +26867,11 @@ - + - + @@ -26248,24 +26897,24 @@ - + - + - + - + @@ -26274,11 +26923,11 @@ - + - + @@ -26318,7 +26967,7 @@ - + @@ -26328,7 +26977,7 @@ - + @@ -26344,7 +26993,7 @@ - + @@ -26840,6 +27489,18 @@ + + + + + + + + + + + + @@ -26899,19 +27560,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + + + + + + + + + + + + + + + @@ -32655,6 +33362,7 @@ + @@ -32831,6 +33539,10 @@ + + + + @@ -32865,6 +33577,7 @@ + @@ -32970,6 +33683,12 @@ + + + + + + @@ -33034,6 +33753,10 @@ + + + + @@ -33068,6 +33791,7 @@ + @@ -33173,6 +33897,12 @@ + + + + + + @@ -33740,6 +34470,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -33786,6 +34599,7 @@ + @@ -33793,6 +34607,7 @@ + @@ -33800,6 +34615,7 @@ + @@ -33925,6 +34741,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -34026,6 +34868,7 @@ + @@ -34928,6 +35771,16 @@ + + + + + + + + + + @@ -35688,10 +36541,7 @@ - - - - + @@ -35907,6 +36757,7 @@ + @@ -36084,6 +36935,11 @@ + + + + + @@ -37719,6 +38575,13 @@ + + + + + + + @@ -38653,7 +39516,7 @@ - + @@ -38666,7 +39529,7 @@ - + @@ -38870,6 +39733,24 @@ + + + + + + + + + + + + + + + + + + @@ -41112,6 +41993,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -41391,6 +42302,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -41556,7 +42535,7 @@ - + @@ -41631,6 +42610,13 @@ + + + + + + + @@ -42043,7 +43029,7 @@ - + @@ -42055,7 +43041,7 @@ - + @@ -42067,7 +43053,7 @@ - + @@ -42079,7 +43065,7 @@ - + @@ -42091,7 +43077,7 @@ - + @@ -42511,6 +43497,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -43240,6 +44264,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -44106,7 +45232,7 @@ - + @@ -44119,7 +45245,7 @@ - + @@ -44419,19 +45545,19 @@ - + - - - + + + @@ -44440,7 +45566,11 @@ - + + + + + @@ -44449,6 +45579,8 @@ + + @@ -44565,6 +45697,7 @@ + @@ -44653,6 +45786,20 @@ + + + + + + + + + + + + + + @@ -44686,7 +45833,7 @@ - + @@ -44695,7 +45842,7 @@ - + @@ -44703,6 +45850,7 @@ + @@ -45671,6 +46819,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -46057,6 +47244,25 @@ + + + + + + + + + + + + + + + + + + + @@ -46116,6 +47322,20 @@ + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-attribute.xml b/tex/context/interface/mkiv/i-attribute.xml index 96a680e19..0ea4ce7c0 100644 --- a/tex/context/interface/mkiv/i-attribute.xml +++ b/tex/context/interface/mkiv/i-attribute.xml @@ -30,6 +30,7 @@ + @@ -42,6 +43,7 @@ + diff --git a/tex/context/interface/mkiv/i-backend.xml b/tex/context/interface/mkiv/i-backend.xml index 5db77b5bd..d0bdb4853 100644 --- a/tex/context/interface/mkiv/i-backend.xml +++ b/tex/context/interface/mkiv/i-backend.xml @@ -18,23 +18,23 @@ - + - - + + - - - - - - - + + + + + + + - - + + @@ -86,4 +86,4 @@ - + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-block.xml b/tex/context/interface/mkiv/i-block.xml index fa5262506..3416a96ee 100644 --- a/tex/context/interface/mkiv/i-block.xml +++ b/tex/context/interface/mkiv/i-block.xml @@ -24,9 +24,25 @@ + + + + + + + + + + + + + + + + @@ -47,6 +63,7 @@ + @@ -103,4 +120,10 @@ - \ No newline at end of file + + + + + + + diff --git a/tex/context/interface/mkiv/i-boxes.xml b/tex/context/interface/mkiv/i-boxes.xml index dd5c30529..e89be4fd0 100644 --- a/tex/context/interface/mkiv/i-boxes.xml +++ b/tex/context/interface/mkiv/i-boxes.xml @@ -246,6 +246,19 @@ + + + + + + + + + + + + + @@ -1128,4 +1141,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-buffer.xml b/tex/context/interface/mkiv/i-buffer.xml index 2ec89f571..f08cb8ca4 100644 --- a/tex/context/interface/mkiv/i-buffer.xml +++ b/tex/context/interface/mkiv/i-buffer.xml @@ -65,6 +65,10 @@ + + + + @@ -81,7 +85,7 @@ - + @@ -97,7 +101,7 @@ - + diff --git a/tex/context/interface/mkiv/i-character.xml b/tex/context/interface/mkiv/i-character.xml index c391836d5..61d6a32a6 100644 --- a/tex/context/interface/mkiv/i-character.xml +++ b/tex/context/interface/mkiv/i-character.xml @@ -87,6 +87,12 @@ + + + + + + @@ -141,4 +147,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-characteralign.xml b/tex/context/interface/mkiv/i-characteralign.xml index 3e9f81722..b95ff8487 100644 --- a/tex/context/interface/mkiv/i-characteralign.xml +++ b/tex/context/interface/mkiv/i-characteralign.xml @@ -24,9 +24,32 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -42,4 +65,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-color.xml b/tex/context/interface/mkiv/i-color.xml index 80da11f3b..4dd76d0b3 100644 --- a/tex/context/interface/mkiv/i-color.xml +++ b/tex/context/interface/mkiv/i-color.xml @@ -263,7 +263,7 @@ - + @@ -366,7 +366,7 @@ - + diff --git a/tex/context/interface/mkiv/i-columns.xml b/tex/context/interface/mkiv/i-columns.xml index 9fdd209c0..bbc022ac6 100644 --- a/tex/context/interface/mkiv/i-columns.xml +++ b/tex/context/interface/mkiv/i-columns.xml @@ -34,10 +34,10 @@ - + - + @@ -73,7 +73,7 @@ - + @@ -108,4 +108,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-commandhandler.xml b/tex/context/interface/mkiv/i-commandhandler.xml index 40da525f3..6accac865 100644 --- a/tex/context/interface/mkiv/i-commandhandler.xml +++ b/tex/context/interface/mkiv/i-commandhandler.xml @@ -311,4 +311,16 @@ + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-common-keyword.xml b/tex/context/interface/mkiv/i-common-keyword.xml index 97ac50caa..8469dab2f 100644 --- a/tex/context/interface/mkiv/i-common-keyword.xml +++ b/tex/context/interface/mkiv/i-common-keyword.xml @@ -792,4 +792,21 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-common-value.xml b/tex/context/interface/mkiv/i-common-value.xml index c362779c4..a6884185f 100644 --- a/tex/context/interface/mkiv/i-common-value.xml +++ b/tex/context/interface/mkiv/i-common-value.xml @@ -100,6 +100,7 @@ + @@ -314,6 +315,41 @@ + @@ -683,4 +719,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf index 39538aa7b..7f468c416 100644 Binary files a/tex/context/interface/mkiv/i-context.pdf and b/tex/context/interface/mkiv/i-context.pdf differ diff --git a/tex/context/interface/mkiv/i-context.xml b/tex/context/interface/mkiv/i-context.xml index ba09abcba..01adac436 100644 --- a/tex/context/interface/mkiv/i-context.xml +++ b/tex/context/interface/mkiv/i-context.xml @@ -116,6 +116,7 @@ + @@ -151,6 +152,7 @@ + @@ -187,6 +189,7 @@ + @@ -224,6 +227,7 @@ + @@ -234,4 +238,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-contextname.xml b/tex/context/interface/mkiv/i-contextname.xml new file mode 100644 index 000000000..3e289f3f5 --- /dev/null +++ b/tex/context/interface/mkiv/i-contextname.xml @@ -0,0 +1,2353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + comment="contextname=eth" level="document" category="characters" file="char-def.lua"/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-delimitedtext.xml b/tex/context/interface/mkiv/i-delimitedtext.xml index c34052644..ce1767b1c 100644 --- a/tex/context/interface/mkiv/i-delimitedtext.xml +++ b/tex/context/interface/mkiv/i-delimitedtext.xml @@ -16,7 +16,10 @@ - + + + + diff --git a/tex/context/interface/mkiv/i-description.xml b/tex/context/interface/mkiv/i-description.xml index f2cf33e82..9d71bd1a1 100644 --- a/tex/context/interface/mkiv/i-description.xml +++ b/tex/context/interface/mkiv/i-description.xml @@ -55,6 +55,7 @@ + @@ -129,6 +130,10 @@ + + + + diff --git a/tex/context/interface/mkiv/i-document.xml b/tex/context/interface/mkiv/i-document.xml index fcd9e040b..178f7e9fe 100644 --- a/tex/context/interface/mkiv/i-document.xml +++ b/tex/context/interface/mkiv/i-document.xml @@ -218,4 +218,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-effect.xml b/tex/context/interface/mkiv/i-effect.xml index d20a62cd4..b71306fff 100644 --- a/tex/context/interface/mkiv/i-effect.xml +++ b/tex/context/interface/mkiv/i-effect.xml @@ -26,7 +26,7 @@ - + diff --git a/tex/context/interface/mkiv/i-enumeration.xml b/tex/context/interface/mkiv/i-enumeration.xml index 149f4f613..0f286b8b5 100644 --- a/tex/context/interface/mkiv/i-enumeration.xml +++ b/tex/context/interface/mkiv/i-enumeration.xml @@ -101,6 +101,7 @@ + @@ -175,6 +176,10 @@ + + + + diff --git a/tex/context/interface/mkiv/i-file.xml b/tex/context/interface/mkiv/i-file.xml index df649e8e0..bf12e5825 100644 --- a/tex/context/interface/mkiv/i-file.xml +++ b/tex/context/interface/mkiv/i-file.xml @@ -407,4 +407,4 @@ - + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-filler.xml b/tex/context/interface/mkiv/i-filler.xml index 69cc37fca..d9a43378e 100644 --- a/tex/context/interface/mkiv/i-filler.xml +++ b/tex/context/interface/mkiv/i-filler.xml @@ -99,6 +99,20 @@ + + + + + + + + + + + + + + @@ -207,4 +221,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-fittingpage.xml b/tex/context/interface/mkiv/i-fittingpage.xml index 8c2003568..7fc3a6cff 100644 --- a/tex/context/interface/mkiv/i-fittingpage.xml +++ b/tex/context/interface/mkiv/i-fittingpage.xml @@ -100,4 +100,4 @@ - + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-floats.xml b/tex/context/interface/mkiv/i-floats.xml index 0ecb99c16..77a0f00a1 100644 --- a/tex/context/interface/mkiv/i-floats.xml +++ b/tex/context/interface/mkiv/i-floats.xml @@ -186,10 +186,10 @@ - + - + @@ -206,6 +206,7 @@ + @@ -231,9 +232,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --> - + @@ -253,6 +396,7 @@ + @@ -292,7 +436,12 @@ - + + + + + + @@ -347,24 +496,39 @@ + - + - + - + + + - + @@ -796,4 +960,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-fonts.xml b/tex/context/interface/mkiv/i-fonts.xml index 1e6e169a4..721bfca63 100644 --- a/tex/context/interface/mkiv/i-fonts.xml +++ b/tex/context/interface/mkiv/i-fonts.xml @@ -31,12 +31,20 @@ + + + + + + + + @@ -332,7 +340,7 @@ - + @@ -421,7 +429,6 @@ - @@ -430,6 +437,29 @@ + + + + + + + + + + + + + + + + + + + + + + + @@ -935,7 +965,7 @@ - + diff --git a/tex/context/interface/mkiv/i-formula.xml b/tex/context/interface/mkiv/i-formula.xml index 07127a629..72693fb6c 100644 --- a/tex/context/interface/mkiv/i-formula.xml +++ b/tex/context/interface/mkiv/i-formula.xml @@ -274,6 +274,7 @@ + @@ -303,12 +304,14 @@ + + diff --git a/tex/context/interface/mkiv/i-framed.xml b/tex/context/interface/mkiv/i-framed.xml index a4667dd2e..5e96ba80d 100644 --- a/tex/context/interface/mkiv/i-framed.xml +++ b/tex/context/interface/mkiv/i-framed.xml @@ -57,21 +57,25 @@ + + + + @@ -88,6 +92,8 @@ + + @@ -132,6 +138,9 @@ + + + @@ -627,4 +636,12 @@ + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-graphics.xml b/tex/context/interface/mkiv/i-graphics.xml index d90be9e7b..a71291a2a 100644 --- a/tex/context/interface/mkiv/i-graphics.xml +++ b/tex/context/interface/mkiv/i-graphics.xml @@ -236,6 +236,16 @@ + + + + + + + + + + @@ -524,4 +534,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-grid.xml b/tex/context/interface/mkiv/i-grid.xml index bd96388f3..9b072127b 100644 --- a/tex/context/interface/mkiv/i-grid.xml +++ b/tex/context/interface/mkiv/i-grid.xml @@ -18,6 +18,7 @@ + @@ -174,6 +175,12 @@ + + + + + + @@ -186,4 +193,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-hspace.xml b/tex/context/interface/mkiv/i-hspace.xml index c1626e7b1..31c215864 100644 --- a/tex/context/interface/mkiv/i-hspace.xml +++ b/tex/context/interface/mkiv/i-hspace.xml @@ -35,6 +35,7 @@ + @@ -92,6 +93,8 @@ + + @@ -100,6 +103,8 @@ + + @@ -162,4 +167,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-interactionscreen.xml b/tex/context/interface/mkiv/i-interactionscreen.xml index bf26cd962..7ead396b8 100644 --- a/tex/context/interface/mkiv/i-interactionscreen.xml +++ b/tex/context/interface/mkiv/i-interactionscreen.xml @@ -47,6 +47,7 @@ + diff --git a/tex/context/interface/mkiv/i-kerning.xml b/tex/context/interface/mkiv/i-kerning.xml index b45e916f2..64a2513b9 100644 --- a/tex/context/interface/mkiv/i-kerning.xml +++ b/tex/context/interface/mkiv/i-kerning.xml @@ -90,4 +90,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-label.xml b/tex/context/interface/mkiv/i-label.xml index a09360aa7..a1d36ef43 100644 --- a/tex/context/interface/mkiv/i-label.xml +++ b/tex/context/interface/mkiv/i-label.xml @@ -101,6 +101,7 @@ + @@ -176,6 +177,10 @@ + + + + diff --git a/tex/context/interface/mkiv/i-language.xml b/tex/context/interface/mkiv/i-language.xml index 357061321..de8835a79 100644 --- a/tex/context/interface/mkiv/i-language.xml +++ b/tex/context/interface/mkiv/i-language.xml @@ -37,6 +37,9 @@ + + + @@ -61,6 +64,7 @@ + @@ -174,6 +178,12 @@ + + + + + + diff --git a/tex/context/interface/mkiv/i-layout.xml b/tex/context/interface/mkiv/i-layout.xml index 19b233988..4370cc4f5 100644 --- a/tex/context/interface/mkiv/i-layout.xml +++ b/tex/context/interface/mkiv/i-layout.xml @@ -197,6 +197,7 @@ + @@ -367,14 +368,14 @@ - + - + diff --git a/tex/context/interface/mkiv/i-linefiller.xml b/tex/context/interface/mkiv/i-linefiller.xml new file mode 100644 index 000000000..ab53e64b0 --- /dev/null +++ b/tex/context/interface/mkiv/i-linefiller.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-list.xml b/tex/context/interface/mkiv/i-list.xml index 8d4863dd2..a3ae22676 100644 --- a/tex/context/interface/mkiv/i-list.xml +++ b/tex/context/interface/mkiv/i-list.xml @@ -55,7 +55,9 @@ - + @@ -386,7 +388,7 @@ - + @@ -395,7 +397,55 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -404,7 +454,7 @@ - + @@ -416,7 +466,7 @@ - + @@ -431,7 +481,7 @@ - + @@ -446,7 +496,7 @@ - + diff --git a/tex/context/interface/mkiv/i-math.xml b/tex/context/interface/mkiv/i-math.xml index af9d87cb8..ae8fa1c3e 100644 --- a/tex/context/interface/mkiv/i-math.xml +++ b/tex/context/interface/mkiv/i-math.xml @@ -35,6 +35,7 @@ + @@ -109,6 +110,17 @@ + + + + + + + + + + + @@ -499,4 +511,4 @@ - + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-mathfence.xml b/tex/context/interface/mkiv/i-mathfence.xml index 76151fae4..5e1abec2b 100644 --- a/tex/context/interface/mkiv/i-mathfence.xml +++ b/tex/context/interface/mkiv/i-mathfence.xml @@ -43,6 +43,9 @@ + + + diff --git a/tex/context/interface/mkiv/i-mathmatrix.xml b/tex/context/interface/mkiv/i-mathmatrix.xml index bd1452cdc..581a6928a 100644 --- a/tex/context/interface/mkiv/i-mathmatrix.xml +++ b/tex/context/interface/mkiv/i-mathmatrix.xml @@ -90,6 +90,15 @@ --> + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-mathname.xml b/tex/context/interface/mkiv/i-mathname.xml new file mode 100644 index 000000000..63dab0991 --- /dev/null +++ b/tex/context/interface/mkiv/i-mathname.xml @@ -0,0 +1,1091 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-narrow.xml b/tex/context/interface/mkiv/i-narrow.xml index 5133b6302..a229a2112 100644 --- a/tex/context/interface/mkiv/i-narrow.xml +++ b/tex/context/interface/mkiv/i-narrow.xml @@ -75,7 +75,7 @@ - + @@ -100,7 +100,7 @@ - + @@ -118,7 +118,7 @@ - + diff --git a/tex/context/interface/mkiv/i-note.xml b/tex/context/interface/mkiv/i-note.xml index 9bcf43d5b..03e53a0e3 100644 --- a/tex/context/interface/mkiv/i-note.xml +++ b/tex/context/interface/mkiv/i-note.xml @@ -183,6 +183,10 @@ + + + + @@ -467,6 +471,8 @@ + + diff --git a/tex/context/interface/mkiv/i-pagecolumns.xml b/tex/context/interface/mkiv/i-pagecolumns.xml new file mode 100644 index 000000000..07ab20abb --- /dev/null +++ b/tex/context/interface/mkiv/i-pagecolumns.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-pagegrid.xml b/tex/context/interface/mkiv/i-pagegrid.xml index 8e53ef8fc..f25e72f72 100644 --- a/tex/context/interface/mkiv/i-pagegrid.xml +++ b/tex/context/interface/mkiv/i-pagegrid.xml @@ -4,19 +4,84 @@ - + + + - + - + + + - + + + + @@ -27,6 +92,7 @@ + @@ -34,6 +100,7 @@ + @@ -55,57 +122,121 @@ - + + + - + - + - + - + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + --> - + - + - + + + @@ -129,32 +260,111 @@ - + + + - + - + + + - + + + - + - + + + @@ -192,14 +402,38 @@ - + + + - + + + @@ -208,7 +442,20 @@ - + + + diff --git a/tex/context/interface/mkiv/i-pagemarks.xml b/tex/context/interface/mkiv/i-pagemarks.xml index 036f518b9..4d41bbfdd 100644 --- a/tex/context/interface/mkiv/i-pagemarks.xml +++ b/tex/context/interface/mkiv/i-pagemarks.xml @@ -4,16 +4,28 @@ - + - + - + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-pagestate.xml b/tex/context/interface/mkiv/i-pagestate.xml index 941068399..e705ba7e7 100644 --- a/tex/context/interface/mkiv/i-pagestate.xml +++ b/tex/context/interface/mkiv/i-pagestate.xml @@ -4,6 +4,17 @@ + + + + + + + + + + + @@ -56,4 +67,32 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf index ee6712cfd..a0a875e51 100644 Binary files a/tex/context/interface/mkiv/i-readme.pdf and b/tex/context/interface/mkiv/i-readme.pdf differ diff --git a/tex/context/interface/mkiv/i-register.xml b/tex/context/interface/mkiv/i-register.xml index 4d8010559..7ba3a0f7c 100644 --- a/tex/context/interface/mkiv/i-register.xml +++ b/tex/context/interface/mkiv/i-register.xml @@ -49,6 +49,10 @@ + + + + @@ -162,6 +166,12 @@ + + + + + + @@ -215,6 +225,10 @@ + + + + @@ -328,6 +342,12 @@ + + + + + + @@ -544,7 +564,7 @@ - + @@ -664,4 +684,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-ruby.xml b/tex/context/interface/mkiv/i-ruby.xml index 10bcff22e..4422029b8 100644 --- a/tex/context/interface/mkiv/i-ruby.xml +++ b/tex/context/interface/mkiv/i-ruby.xml @@ -22,6 +22,7 @@ + diff --git a/tex/context/interface/mkiv/i-scale.xml b/tex/context/interface/mkiv/i-scale.xml index 3d26ed76f..36a46479e 100644 --- a/tex/context/interface/mkiv/i-scale.xml +++ b/tex/context/interface/mkiv/i-scale.xml @@ -44,6 +44,7 @@ + @@ -51,6 +52,7 @@ + @@ -58,6 +60,7 @@ + diff --git a/tex/context/interface/mkiv/i-script.xml b/tex/context/interface/mkiv/i-script.xml index 9af017492..affa2658b 100644 --- a/tex/context/interface/mkiv/i-script.xml +++ b/tex/context/interface/mkiv/i-script.xml @@ -47,15 +47,19 @@ - - - - - - - - - + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-section.xml b/tex/context/interface/mkiv/i-section.xml index f3cf13d3e..b4229d5fd 100644 --- a/tex/context/interface/mkiv/i-section.xml +++ b/tex/context/interface/mkiv/i-section.xml @@ -518,4 +518,4 @@ - + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-setups.xml b/tex/context/interface/mkiv/i-setups.xml index df7281e74..a3773e8f7 100644 --- a/tex/context/interface/mkiv/i-setups.xml +++ b/tex/context/interface/mkiv/i-setups.xml @@ -64,6 +64,13 @@ + + + + + + + @@ -221,4 +228,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-startstop.xml b/tex/context/interface/mkiv/i-startstop.xml index c7780488c..ba0abb0b7 100644 --- a/tex/context/interface/mkiv/i-startstop.xml +++ b/tex/context/interface/mkiv/i-startstop.xml @@ -57,10 +57,32 @@ - - - - + + + diff --git a/tex/context/interface/mkiv/i-strut.xml b/tex/context/interface/mkiv/i-strut.xml index 0653dd214..d686d6ee0 100644 --- a/tex/context/interface/mkiv/i-strut.xml +++ b/tex/context/interface/mkiv/i-strut.xml @@ -52,6 +52,8 @@ + + diff --git a/tex/context/interface/mkiv/i-symbol.xml b/tex/context/interface/mkiv/i-symbol.xml index 123e98cbf..498684cad 100644 --- a/tex/context/interface/mkiv/i-symbol.xml +++ b/tex/context/interface/mkiv/i-symbol.xml @@ -119,6 +119,11 @@ + + + + + diff --git a/tex/context/interface/mkiv/i-system.xml b/tex/context/interface/mkiv/i-system.xml index 44def10e0..c8abff238 100644 --- a/tex/context/interface/mkiv/i-system.xml +++ b/tex/context/interface/mkiv/i-system.xml @@ -1007,6 +1007,12 @@ + + + + + + @@ -1641,7 +1647,7 @@ - + @@ -1656,7 +1662,7 @@ - + @@ -1834,6 +1840,22 @@ + + + + + + + + + + + + + + + + @@ -3601,6 +3623,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3643,4 +3690,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-tabulation.xml b/tex/context/interface/mkiv/i-tabulation.xml index 3efc34f42..6768b9b4c 100644 --- a/tex/context/interface/mkiv/i-tabulation.xml +++ b/tex/context/interface/mkiv/i-tabulation.xml @@ -38,6 +38,27 @@ + + + + + + + + + + + + + + + + + + + + + @@ -276,4 +297,4 @@ --> - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-tagging.xml b/tex/context/interface/mkiv/i-tagging.xml index 3e0d49d80..d07b32ec1 100644 --- a/tex/context/interface/mkiv/i-tagging.xml +++ b/tex/context/interface/mkiv/i-tagging.xml @@ -25,7 +25,7 @@ - + @@ -72,4 +72,10 @@ - \ No newline at end of file + + + + + + + diff --git a/tex/context/interface/mkiv/i-texts.xml b/tex/context/interface/mkiv/i-texts.xml index bd1b128b3..f0f515fbc 100644 --- a/tex/context/interface/mkiv/i-texts.xml +++ b/tex/context/interface/mkiv/i-texts.xml @@ -165,6 +165,75 @@ + + @@ -173,7 +242,7 @@ - + @@ -186,7 +255,7 @@ - + @@ -199,7 +268,7 @@ - + @@ -212,7 +281,7 @@ - + @@ -225,7 +294,7 @@ - + diff --git a/tex/context/interface/mkiv/i-token.xml b/tex/context/interface/mkiv/i-token.xml index 129f472ba..09e2ad3d6 100644 --- a/tex/context/interface/mkiv/i-token.xml +++ b/tex/context/interface/mkiv/i-token.xml @@ -28,4 +28,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-unit.xml b/tex/context/interface/mkiv/i-unit.xml index 9efa452eb..c8092a4ed 100644 --- a/tex/context/interface/mkiv/i-unit.xml +++ b/tex/context/interface/mkiv/i-unit.xml @@ -125,4 +125,16 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-userdata.xml b/tex/context/interface/mkiv/i-userdata.xml new file mode 100644 index 000000000..e9617f0bc --- /dev/null +++ b/tex/context/interface/mkiv/i-userdata.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-verbatim.xml b/tex/context/interface/mkiv/i-verbatim.xml index e8abc1f66..830b8bb11 100644 --- a/tex/context/interface/mkiv/i-verbatim.xml +++ b/tex/context/interface/mkiv/i-verbatim.xml @@ -321,7 +321,7 @@ - + @@ -329,7 +329,7 @@ - + diff --git a/tex/context/interface/mkiv/i-visualizer.xml b/tex/context/interface/mkiv/i-visualizer.xml index daaad28cd..81d02f4fb 100644 --- a/tex/context/interface/mkiv/i-visualizer.xml +++ b/tex/context/interface/mkiv/i-visualizer.xml @@ -112,19 +112,19 @@ - + - - - + + + @@ -133,7 +133,11 @@ - + + + + + @@ -148,6 +152,10 @@ + + + + @@ -156,4 +164,4 @@ - \ No newline at end of file + diff --git a/tex/context/interface/mkiv/i-vspace.xml b/tex/context/interface/mkiv/i-vspace.xml index ce6d5ac08..5e970d317 100644 --- a/tex/context/interface/mkiv/i-vspace.xml +++ b/tex/context/interface/mkiv/i-vspace.xml @@ -24,52 +24,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -121,51 +76,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -213,4 +124,20 @@ + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-whitespace.xml b/tex/context/interface/mkiv/i-whitespace.xml index f1a8ce84e..a44b08f1d 100644 --- a/tex/context/interface/mkiv/i-whitespace.xml +++ b/tex/context/interface/mkiv/i-whitespace.xml @@ -39,7 +39,7 @@ - + @@ -50,7 +50,7 @@ - + @@ -59,4 +59,6 @@ + + \ No newline at end of file diff --git a/tex/context/interface/mkiv/i-xml.xml b/tex/context/interface/mkiv/i-xml.xml index d09913f7c..1786e1bf6 100644 --- a/tex/context/interface/mkiv/i-xml.xml +++ b/tex/context/interface/mkiv/i-xml.xml @@ -664,6 +664,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tex/context/interface/mkiv/i-xtable.xml b/tex/context/interface/mkiv/i-xtable.xml index c921e1a8d..7ee0df3f2 100644 --- a/tex/context/interface/mkiv/i-xtable.xml +++ b/tex/context/interface/mkiv/i-xtable.xml @@ -77,6 +77,25 @@ + + + + + + + + + + + + + + + + + + + @@ -136,6 +155,33 @@ + + + + + + + + + + + + + + + + @@ -244,4 +290,4 @@ - \ No newline at end of file + diff --git a/tex/context/modules/common/s-abbreviations-logos.tex b/tex/context/modules/common/s-abbreviations-logos.tex index c14265cc0..00719a668 100644 --- a/tex/context/modules/common/s-abbreviations-logos.tex +++ b/tex/context/modules/common/s-abbreviations-logos.tex @@ -157,6 +157,7 @@ \logo [LINUX] {linux} \logo [LISP] {Lisp} \logo [LMX] {lmx} +\logo [LMTX] {lmtx} \logo [LPEG] {lpeg} \logo [LUA] {Lua} \logo [LUAJIT] {LuaJIT} @@ -205,6 +206,7 @@ \logo [OTEX] {Oriental \TeXsuffix} \logo [OTF] {otf} \logo [OTP] {otp} +\logo [OSX] {os-x} \logo [OVF] {ovf} \logo [PASCAL] {Pascal} \logo [PCTEX] {pc\TeXsuffix} @@ -233,6 +235,7 @@ \logo [PSTOPAGE] {pstopage} \logo [PSTOPDF] {pstopdf} \logo [PSTRICKS] {pstricks} +\logo [PYTHON] {Python} \logo [RAID] {raid} \logo [RAM] {ram} \logo [RCA] {RCA} diff --git a/tex/context/modules/mkiv/m-asymptote.lua b/tex/context/modules/mkiv/m-asymptote.lua index de8d032c8..39a0d987b 100644 --- a/tex/context/modules/mkiv/m-asymptote.lua +++ b/tex/context/modules/mkiv/m-asymptote.lua @@ -1,6 +1,6 @@ if not modules then modules = { } end modules ['m-asymptote'] = { version = 1.001, - comment = "companion to m-pstricks.mkiv", + comment = "companion to m-asymptote.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" diff --git a/tex/context/modules/mkiv/m-asymptote.mkiv b/tex/context/modules/mkiv/m-asymptote.mkiv index c236ceee5..9cd4037fb 100644 --- a/tex/context/modules/mkiv/m-asymptote.mkiv +++ b/tex/context/modules/mkiv/m-asymptote.mkiv @@ -76,51 +76,51 @@ \starttext \startasymptote[demo-1] -settings.prc=true; +settings.prc = true ; -import graph3; -import palette; +import graph3 ; +import palette ; -size(6cm,6cm); -size3(5cm,0); +size(6cm,6cm) ; +size3(5cm,0) ; -currentprojection=orthographic(3,-6,12); -currentlight=light(8,10,2); +currentprojection = orthographic(3,-6,12) ; +currentlight = light(8,10,2) ; -real g(pair z) {return 1-z.x^2-z.y^2;} -real f(pair z) {return -2z.x+2;} +real g(pair z) { return 1-z.x^2-z.y^2 ; } +real f(pair z) { return -2z.x+2 ; } -real x(real t) {return t;} -real y(real t) {return 0;} -real z(real t) {return 1-t^2;} -real a(real t) {return 1;} -real b(real t) {return t;} -real c(real t) {return -t^2;} +real x(real t) { return t ; } +real y(real t) { return 0 ; } +real z(real t) { return 1-t^2 ; } +real a(real t) { return 1 ; } +real b(real t) { return t ; } +real c(real t) { return -t^2 ; } -path3 p=graph(x,y,z,-2,2,operator ..); -path3 o=graph(a,b,c,-2,2,operator ..); +path3 p=graph(x,y,z,-2,2,operator ..) ; +path3 o=graph(a,b,c,-2,2,operator ..) ; -surface r=surface(f,(0,-1),(2,1),nx=3,Spline); -surface s=surface(g,(-2,-2),(2,2),nx=5,Spline); +surface r = surface(f, (0,-1), (2,1), nx = 3, Spline) ; +surface s = surface(g, (-2,-2), (2,2), nx = 5, Spline) ; -path3 q=(-2,-2,-7)--(2,-2,-7)--(2,2,-7)--(-2,2,-7)--cycle; +path3 q = (-2,-2,-7) -- (2,-2,-7) -- (2,2,-7) -- (-2,2,-7) -- cycle ; -draw(q); +draw(q) ; -draw(p,blue+thick(),Arrow3); -draw(o,blue+thick(),Arrow3); +draw(p, blue+thick(), Arrow3) ; +draw(o, blue+thick(), Arrow3) ; -draw(s,lightgray+opacity(0.8),nolight,meshpen=black+thick()); -draw(r,lightgray+opacity(0.8),nolight,meshpen=black+thick()); +draw(s, lightgray + opacity(0.8), nolight, meshpen = black + thick()) ; +draw(r, lightgray + opacity(0.8), nolight, meshpen = black + thick()) ; -draw((1,0,0)--(2,0,-2),black,Arrow3); -draw((1,0,0)--(1,1,0),black,Arrow3); +draw((1,0,0) -- (2,0,-2), black, Arrow3) ; +draw((1,0,0) -- (1,1,0), black, Arrow3) ; \stopasymptote \startasymptote[demo-2] -size(6cm,6cm); +size(6cm,6cm) ; -fill((1cm,2cm)--(3cm,3cm)--(4cm,0cm)--cycle); +fill((1cm,2cm) -- (3cm,3cm) -- (4cm,0cm) -- cycle); \stopasymptote % see end of grph-inc.mkiv for some more options: diff --git a/tex/context/modules/mkiv/m-chart.lua b/tex/context/modules/mkiv/m-chart.lua index bcf80bdfc..cde563fb3 100644 --- a/tex/context/modules/mkiv/m-chart.lua +++ b/tex/context/modules/mkiv/m-chart.lua @@ -926,18 +926,16 @@ local function getchart(settings,forced_x,forced_y,forced_nx,forced_ny) return chart end -local function makechart(chart) +local function makechart_indeed(chart) local settings = chart.settings local chartsettings = settings.chart -- - context.begingroup() - context.forgetall() - -- local g = ctx_startgraphic { instance = "metafun", format = "metafun", method = "scaled", definitions = "", + wrapped = true, } -- ctx_tographic(g,"if unknown context_flow : input mp-char.mpiv ; fi ;") @@ -1012,7 +1010,16 @@ local function makechart(chart) ctx_tographic(g,"flow_end_chart ;") ctx_stopgraphic(g) -- - context.endgroup() +end + +-- We need to wrap because of tex.runtoks! + +local function makechart(chart) + context.hbox() + context.bgroup() + context.forgetall() + context(function() makechart_indeed(chart) end) + context.egroup() end local function splitchart(chart) diff --git a/tex/context/modules/mkiv/m-chart.mkvi b/tex/context/modules/mkiv/m-chart.mkvi index 0463e4acd..4c5ea7e02 100644 --- a/tex/context/modules/mkiv/m-chart.mkvi +++ b/tex/context/modules/mkiv/m-chart.mkvi @@ -185,11 +185,14 @@ {\dodoubleempty\module_charts_process} \def\module_charts_process[#name][#settings]% - {\bgroup % \vbox removed +% {\hpack\bgroup % \vbox removed, \hpack prevents issues with tex.runtoks + {\bgroup % \vbox removed, \hpack prevents issues with tex.runtoks \insidefloattrue \dontcomplain \setupFLOWchart[#settings]% \usebodyfontparameter\FLOWchartparameter +% \meta_process_graphic_start +% \meta_start_current_graphic \clf_flow_make_chart chart { name {#name} @@ -248,6 +251,8 @@ after {} } \relax +% \meta_stop_current_graphic +% \meta_process_graphic_stop \egroup} \unexpanded\def\FLOWcharts diff --git a/tex/context/modules/mkiv/m-format.mkiv b/tex/context/modules/mkiv/m-format.mkiv index f9dd348a4..3a0a5bebd 100644 --- a/tex/context/modules/mkiv/m-format.mkiv +++ b/tex/context/modules/mkiv/m-format.mkiv @@ -217,7 +217,7 @@ \doglobal\newcounter\formatlinesubcounter \reshapebox {\doglobal\increment\formatlinesubcounter} - \global\let\formatlinemaxcounter\formatlinesubcounter + \glet\formatlinemaxcounter\formatlinesubcounter \reshapebox {\doglobal\decrement\formatlinesubcounter \ifnum\formatlinesubcounter=\zerocount @@ -303,7 +303,7 @@ \doglobal\newcounter\formatlinesubcounter \reshapebox {\doglobal\increment\formatlinesubcounter}% - \global\let\formatlinemaxcounter\formatlinesubcounter + \glet\formatlinemaxcounter\formatlinesubcounter \reshapebox {\doglobal\decrement\formatlinesubcounter \ifnum\formatlinesubcounter=\zerocount diff --git a/tex/context/modules/mkiv/m-matrix.mkiv b/tex/context/modules/mkiv/m-matrix.mkiv index 9cac69672..4a0bd712d 100644 --- a/tex/context/modules/mkiv/m-matrix.mkiv +++ b/tex/context/modules/mkiv/m-matrix.mkiv @@ -23,6 +23,8 @@ \startluacode +local tonumber, type = tonumber, type + local settings_to_hash = utilities.parsers.settings_to_hash local formatters = string.formatters local copy = table.copy @@ -114,7 +116,7 @@ function matrix.typeset(m,options) if type(m[1]) ~= "table" then m = { copy(m) } end - for i=1, #m do + for i=1,#m do local mi = m[i] for j=1,#mi do context.NC() @@ -164,9 +166,11 @@ function matrix.swapcolumns(t, i, j) return t end -matrix.swapC = matrix.swapcolumns -matrix.swapR = matrix.swaprows -matrix.swap = matrix.swaprows +matrix.swapC = matrix.swapcolumns +matrix.swapR = matrix.swaprows +matrix.swapcolumns = matrix.swapcolumns +matrix.swaprows = matrix.swaprows +matrix.swap = matrix.swaprows -- replace i-th row with factor * (i-th row) @@ -299,7 +303,7 @@ local function determinant(m) end return s*d else - return "error: not a square matrix" -- not context(..) + return "error: not a square matrix" end end @@ -371,7 +375,7 @@ matrix.rowEchelon = rowechelon -- make matrices until its determinant is not 0 -function matrix.make(m,n,low,high) -- m and n swapped +local function make(m,n,low,high) -- m and n swapped if not n then n = 10 end @@ -401,6 +405,9 @@ function matrix.make(m,n,low,high) -- m and n swapped end end +matrix.make = make +matrix.makeR = matrix.make + -- extract submatrix by using local function submatrix(t,i,j) @@ -420,10 +427,11 @@ local function submatrix(t,i,j) end matrix.submatrix = submatrix +matrix.subMatrix = submatrix -- calculating determinant using Laplace Expansion -function matrix.laplace(t) -- not sure if this is the most effient but +local function laplace(t) -- not sure if this is the most effient but local factors = { 1 } -- it's not used for number crunching anyway local data = copy(t) local det = 0 @@ -461,6 +469,8 @@ function matrix.laplace(t) -- not sure if this is the most effient but return det end +matrix.laplace = laplace + -- solve the linear equation m X = c local function solve(m,c) @@ -518,6 +528,74 @@ end matrix.inverse = inverse +-- create zero and identity matrix + +local function makeM(k,v) + local tt = { } + for i=1,k do + local temp = { } + for j=1,k do + temp[j] = 0 + end + tt[i] = temp + end + if v and v > 0 then + for i=1,k do + tt[i][i] = 1 + end + end + return tt +end + +matrix.makeM = makeM +matrix.makeidentity = makeM +matrix.makezero = makeM + +-- append the rows of the second matrix to the bottom of the first matrix + +local function joinrows(t1, t2) + local nt1 = #t1 + local nt2 = #t2 + if (nt1*nt2 > 0) and (#t1[1] ~= #t2[1]) then + return "error: different number of columns" + else + for i=1,nt2 do + t1[nt1+i] = t2[i] + end + return t1 + end +end + +matrix.joinrows = joinrows +matrix.joinRows = joinrows + +-- append the columns of the second matrix to the right of the first matrix + +local function joincolumns(t1, t2) + local nt1 = #t1 + local nt2 = #t2 + if nt1 == 0 then + return t2 + end + if nt2 == 0 then + return t1 + end + if nt1 ~= nt2 then + return "error: different number of rows" + end + nt3 = #t2[1] + for i=1,nt1 do + local temp = t2[i] + for j= 1, nt3 do + insert(t1[i],temp[j]) + end + end + return t1 +end + +matrix.joincolumns = joincolumns +matrix.joinColumns = joincolumns + \stopluacode \stopmodule @@ -570,6 +648,7 @@ document.DemoMatrixC = { \startbuffer \ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n"))} +$\qquad\qquad$ \ctxmodulematrix{typeset(moduledata.matrix.symbolic("a", "m", "n", 4, 8))} \stopbuffer @@ -581,9 +660,10 @@ document.DemoMatrixC = { \startbuffer \startluacode - moduledata.matrix.typeset(moduledata.matrix.make(4,3, 0,5)) + moduledata.matrix.typeset(moduledata.matrix.makeR(4,3, 0,5)) context.qquad() - moduledata.matrix.typeset(moduledata.matrix.make(5,5,-1,5)) + context("\\qquad") + moduledata.matrix.typeset(moduledata.matrix.makeR(5,5,-1,5)) \stopluacode \stopbuffer @@ -591,7 +671,7 @@ document.DemoMatrixC = { \stopsubject -\startsubject[title={Swap two rows (2 and 4)}] +\startsubject[title={Swap two rows (ex: 2 and 4)}] \startbuffer \startluacode @@ -605,13 +685,13 @@ document.DemoMatrixC = { \stopsubject -\startsubject[title={Swap two columns (2 and 4)}] +\startsubject[title={Swap two columns (ex: 1 and 3)}] \startbuffer \startluacode moduledata.matrix.typeset(document.DemoMatrixA) context("$\\qquad \\Rightarrow \\qquad$") - moduledata.matrix.typeset(moduledata.matrix.swapcolumns(document.DemoMatrixA,2, 4)) + moduledata.matrix.typeset(moduledata.matrix.swapcolumns(document.DemoMatrixA,1, 3)) \stopluacode \stopbuffer @@ -726,7 +806,7 @@ context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 })) } moduledata.matrix.typeset(m, {fences="bars"}) context("$\\qquad = \\qquad$") - moduledata.matrix.determinant(m) + context(moduledata.matrix.determinant(m)) \stopluacode \stopbuffer @@ -864,4 +944,51 @@ context(moduledata.matrix.inner({ 1, 2, 3 }, { 3, 1, 2, 4 })) \stopsubject +\startsubject[title={make matrices(zero, identiry, random}] + +\startbuffer +\startluacode + moduledata.matrix.typeset(moduledata.matrix.makeM(3, 0)) + context.qquad() + moduledata.matrix.typeset(moduledata.matrix.makeM(3, 1)) + context.qquad() + moduledata.matrix.typeset(moduledata.matrix.makeR(4,3)) +\stopluacode +\stopbuffer + +\getbuffer[demo] + +\stopsubject + +\startsubject[title={join rows, join columns}] + +\startbuffer +\startluacode + local mat1 = moduledata.matrix.makeR(3, 4) + local mat2 = moduledata.matrix.makeR(4, 3) + + context("Appending as columns: ") + context.blank() + moduledata.matrix.typeset(mat1) + context("$\\&$") + moduledata.matrix.typeset(mat1) + context("\\quad $\\Rightarrow$ \\quad") + moduledata.matrix.joinColumns(mat1, mat1) + moduledata.matrix.typeset(mat1) + context.blank() + context("Appending as rows: ") + context.blank() + moduledata.matrix.typeset(mat2) + context("$\\&$") + moduledata.matrix.typeset(mat2) + context("\\quad $\\Rightarrow$ \\quad") + moduledata.matrix.joinRows(mat2, mat2) + moduledata.matrix.typeset(mat2) +\stopluacode +\stopbuffer + +\getbuffer[demo] + +\stopsubject + \stoptext diff --git a/tex/context/modules/mkiv/m-maybe.mkiv b/tex/context/modules/mkiv/m-maybe.mkiv new file mode 100644 index 000000000..d019828f5 --- /dev/null +++ b/tex/context/modules/mkiv/m-maybe.mkiv @@ -0,0 +1,57 @@ +%D \module +%D [ file=m-maybe, +%D version=2018.07.26, +%D title=\CONTEXT\ Extra Modules, +%D subtitle=Maybe some day, +%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. + +%D The code here is not in the core and might never be as it's probably not +%D of much use and|/|or can interfere. + +\unprotect + +% \showframe +% \starttext +% \tweakpagegoal[-\lineheight] +% \dorecurse{40}{\inleftmargin{!}\input ward\par} +% \stoptext + +\def\page_scale_text_box_indeed#1% + {\scratchheight\ht#1\relax + \scratchwidth \wd#1\relax + \setbox#1\vpack\bgroup + \hpack\bgroup + \scale + [\c!height=\dimexpr\textheight-\d_page_adapts_delta\relax, + \c!width=\scratchwidth] + {\box#1}% + \egroup + \egroup + \global\d_page_adapts_delta\zeropoint + \glet\page_scale_text_box\gobbleoneargument + \ht#1\scratchheight + \wd#1\scratchwidth} + +\unexpanded\def\tweakpagegoal[#1]% + {\ifx\currentoutputroutine\s!singlecolumn + \global\d_page_adapts_delta\dimexpr#1\relax + \ifdim\d_page_adapts_delta=\zeropoint + \glet\page_scale_text_box\gobbleoneargument + \else + \glet\page_scale_text_box\page_scale_text_box_indeed + \fi + \else + \global\d_page_adapts_delta\zeropoint + \glet\page_scale_text_box\gobbleoneargument + \fi + \page_otr_command_set_vsize} + +\protect + +\endinput diff --git a/tex/context/modules/mkiv/m-old-columnsets.mkiv b/tex/context/modules/mkiv/m-old-columnsets.mkiv new file mode 100644 index 000000000..d840cbc91 --- /dev/null +++ b/tex/context/modules/mkiv/m-old-columnsets.mkiv @@ -0,0 +1,7 @@ +\writeline +\writestatus{system}{Using old columnset mechanism.} +\writeline + +\input page-set.mkiv + +\endinput diff --git a/tex/context/modules/mkiv/m-old-multicolumns.mkiv b/tex/context/modules/mkiv/m-old-multicolumns.mkiv new file mode 100644 index 000000000..a2fb1503b --- /dev/null +++ b/tex/context/modules/mkiv/m-old-multicolumns.mkiv @@ -0,0 +1,7 @@ +\writeline +\writestatus{system}{Using old multicolumn mechanism.} +\writeline + +\input page-mul.mkiv + +\endinput diff --git a/tex/context/modules/mkiv/m-oldfun.mkiv b/tex/context/modules/mkiv/m-oldfun.mkiv index 3f2ec0263..7ec779c41 100644 --- a/tex/context/modules/mkiv/m-oldfun.mkiv +++ b/tex/context/modules/mkiv/m-oldfun.mkiv @@ -355,14 +355,14 @@ \ifdim\wd2=\zeropoint \setbox0\emptybox \setbox2\emptybox - \@EA\grabfirstline + \expandafter\grabfirstline \else\ifdim\wd2>\hsize \hbox to \hsize{\strut\unhbox0}#2\egroup \break##1\ \egroup \else \setbox0\box2 - \@EAEAEA\grabfirstline + \doubleexpandafter\grabfirstline \fi\fi}% \grabfirstline} diff --git a/tex/context/modules/mkiv/m-oldnum.mkiv b/tex/context/modules/mkiv/m-oldnum.mkiv index 382c56eb6..a240cdb58 100644 --- a/tex/context/modules/mkiv/m-oldnum.mkiv +++ b/tex/context/modules/mkiv/m-oldnum.mkiv @@ -189,28 +189,15 @@ %D Although we could do with one pass, a second pass for %D handling the stored sequence is more readable. -\ifnum\texengine=\luatexengine +\def\dohandledigits + {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded + \expandafter\handletokens\collecteddigits\with\scandigits + \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} - \def\dohandledigits - {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded - \expandafter\handletokens\collecteddigits\with\scandigits - \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} - - \chardef\mathaxisfontid\zerocount - -\else - - \def\dohandledigits - {\mathcode`\,="013B \mathcode`\.="013A % pretty hard coded - \expandafter\handletokens\collecteddigits\with\scandigits - \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi} - - \chardef\mathaxisfontid\plustwo - -\fi +\chardef\mathaxisfontid\zerocount \def\doscandigit#1% - {\ifcase\skipdigit\@EA\hbox\else\@EA\hphantom\fi\bgroup + {\ifcase\skipdigit\expandafter\hbox\else\expandafter\hphantom\fi\bgroup \mathematics % brr, needed because of stored punctuation {\ifnum\digitinputmode=#1\relax \ifcase\digitoutputmode diff --git a/tex/context/modules/mkiv/m-punk.mkiv b/tex/context/modules/mkiv/m-punk.mkiv index 08a066359..29a6d8cca 100644 --- a/tex/context/modules/mkiv/m-punk.mkiv +++ b/tex/context/modules/mkiv/m-punk.mkiv @@ -104,19 +104,20 @@ function metapost.characters.process(mpxformat, name, instances, scalefactor) for i=1,instances do characters = { } descriptions = { } - metapost.process( - mpxformat, - { + metapost.process { + mpx = mpxformat, + -- trialrun = false, + flusher = flusher, + -- multipass = false, + -- isextrapass = false, + askedfig = "all", + -- incontext = false, + data = { "randomseed := " .. i*10 .. ";", "scale_factor := " .. scalefactor .. " ;", data }, - false, - flusher, - false, - false, - "all" - ) + } lists[i] = { characters = characters, descriptions = descriptions, @@ -210,18 +211,18 @@ metapost.characters.flusher = flusher statistics.register("metapost font generation", function() local time = statistics.elapsedtime(flusher) if total > 0 then - return string.format("%i glyphs, %.3f seconds runtime, %0.3f glyphs/second", total, time, total/time) + return string.format("%i glyphs, %s seconds runtime, %0.3f glyphs/second", total, time, total/tonumber(time)) else - return string.format("%i glyphs, %.3f seconds runtime", total, time) + return string.format("%i glyphs, %s seconds runtime", total, time) end end) statistics.register("metapost font loading",function() local time = statistics.elapsedtime(metapost.characters) if variants > 0 then - return string.format("%.3f seconds, %i instances, %0.3f instances/second", time, variants, variants/time) + return string.format("%s seconds, %i instances, %0.3f instances/second", time, variants, variants/tonumber(time)) else - return string.format("%.3f seconds, %i instances", time, variants) + return string.format("%s seconds, %i instances", time, variants) end end) \stopluacode diff --git a/tex/context/modules/mkiv/m-scite.mkiv b/tex/context/modules/mkiv/m-scite.mkiv index 48f1022ad..9182fa2ec 100644 --- a/tex/context/modules/mkiv/m-scite.mkiv +++ b/tex/context/modules/mkiv/m-scite.mkiv @@ -102,7 +102,8 @@ local function exportcolors() local function black(f) return (f[1] == f[2]) and (f[2] == f[3]) and (f[3] == 0) end - local result, r = { f_mapping }, 1 +-- local result, r = { f_mapping }, 1 +local result, r = { }, 0 for k, v in table.sortedhash(lexer.context.styles) do local fore = v.fore if fore and not black(fore) then @@ -226,7 +227,7 @@ local function lexdata(data,lexname) end data = indent(data) end -io.savedata("temp.logs ",data) + -- io.savedata("temp.log",data) assignbuffer("lex",data) end @@ -288,6 +289,7 @@ visualizers.register("cld", visualizer) visualizers.register("tex", visualizer) visualizers.register("lua", visualizer) visualizers.register("mps", visualizer) +visualizers.register("pdf", visualizer) visualizers.register("xml", visualizer) visualizers.register("bibtex",visualizer) visualizers.register("btx", visualizer) @@ -296,6 +298,7 @@ visualizers.register("cpp", visualizer) visualizers.register("txt", visualizer) visualizers.register("bnf", visualizer) visualizers.register("sql", visualizer) +visualizers.register("json", visualizer) \stopluacode @@ -304,11 +307,13 @@ visualizers.register("sql", visualizer) \definetyping[BTX] [option=bibtex] \definetyping[MPS] [option=mps] \definetyping[MP] [option=mps] +\definetyping[PDF] [option=pdf] \definetyping[CPP] [option=web] \definetyping[WEB] [option=web] \definetyping[TXT] [option=txt] \definetyping[BNF] [option=bnf] % I might use this in the metafun manual. \definetyping[SQL] [option=sql] % To be tested in an upcoming manual. +\definetyping[JSON][option=json] % To be tested in an upcoming manual. \definetyping[NONE][option=none] % This is a preliminary interface. @@ -319,11 +324,11 @@ visualizers.register("sql", visualizer) \unexpanded\def\buff_scite_slxb#1% {\hangindent\numexpr#1+2\relax\scitespaceskip - \hskip#1\scitespaceskip + \begstrut\hskip#1\scitespaceskip \hangafter 1\relax} \unexpanded\def\buff_scite_slxe - {\par} + {\endstrut\par} \unexpanded\def\buff_scite_slxs {\hskip\scitespaceskip\relax} \unexpanded\def\buff_scite_slxf#1{\hskip#1\scitespaceskip\relax} @@ -332,6 +337,7 @@ visualizers.register("sql", visualizer) {\scitespaceskip\interwordspace % \fontcharwd\font`0\relax % brrrrr \let\slxb\gobbleoneargument \let\slxe\space + \let\slxbreak\relax \let\installscitecommandsinline\relax} \unexpanded\def\installscitecommandsdisplay @@ -342,10 +348,24 @@ visualizers.register("sql", visualizer) \clf_sciteinstallcommands -\installscitecommandsinline - -\let\slxS\buff_scite_slxs -\let\slxF\buff_scite_slxf +\let\slxb \gobbleoneargument +\let\slxe \space +\let\slxbreak\relax + +\let\slxL \letterleftbrace +\let\slxR \letterrightbrace +\let\slxM \letterdollar +\let\slxV \letterbar +\let\slxU \letterhat +\let\slxD \letterunderscore +\let\slxH \letterhash +\let\slxB \letterbackslash +\let\slxP \letterpercent +\let\slxT \lettertilde +\let\slxS \fixedspace + +\let\slxS \buff_scite_slxs +\let\slxF \buff_scite_slxf \def\module_scite_inherit_typing {\buff_verbatim_initialize_typing_one diff --git a/tex/context/modules/mkiv/m-units.mkiv b/tex/context/modules/mkiv/m-units.mkiv index f85a8ba8a..4f25fffc6 100644 --- a/tex/context/modules/mkiv/m-units.mkiv +++ b/tex/context/modules/mkiv/m-units.mkiv @@ -212,7 +212,7 @@ \setbox2\hbox{m}% \ifdim\wd0=\wd2 \endgroup - \@EAEAEA\gobbleoneargument + \doubleexpandafter\gobbleoneargument \else \endgroup \fi @@ -220,8 +220,8 @@ \unexpanded\def\dimension#1% {\begingroup - \global\let\savedthedimensionprefix\thedimensionprefix - \global\let\savedthedimensionpower\thedimensionpower + \glet\savedthedimensionprefix\thedimensionprefix + \glet\savedthedimensionpower\thedimensionpower \unexpanded\def\dimension##1{\global\nesteddimensiontrue}% \let\dimensionprefix\dimension \let\dimensionmidfix\dimension @@ -229,8 +229,8 @@ \let\dimensionpower \dimension \global\nesteddimensionfalse \setbox\scratchbox\hbox{\ustartmathmode#1\ustopmathmode}% pre-roll - \global\let\thedimensionprefix\savedthedimensionprefix - \global\let\thedimensionpower \savedthedimensionpower + \glet\thedimensionprefix\savedthedimensionprefix + \glet\thedimensionpower \savedthedimensionpower \endgroup \ifnesteddimension#1\else\dodimension{#1}\fi} @@ -278,8 +278,8 @@ \else \hskip\dimensionpowersignal \fi - \global\let\thedimensionprefix\empty - \global\let\thedimensionpower\empty} + \glet\thedimensionprefix\empty + \glet\thedimensionpower\empty} %D \macros %D {dontbreakdimension, diff --git a/tex/context/modules/mkiv/ppchtex.mkiv b/tex/context/modules/mkiv/ppchtex.mkiv index d1167d414..5348d2e1a 100644 --- a/tex/context/modules/mkiv/ppchtex.mkiv +++ b/tex/context/modules/mkiv/ppchtex.mkiv @@ -1747,7 +1747,7 @@ \def\dosimplechemicalA#1#2#3% % evt: {#1,\relax} {\let\chemicalspace=\relax - \@EA\dosimplechemical\@EA{\@@chemicalchemicaloffset,#1}{#2}{#3}% + \expandafter\dosimplechemical\expandafter{\@@chemicalchemicaloffset,#1}{#2}{#3}% \egroup} \def\dosimplechemicalB#1#2#3% @@ -1849,9 +1849,9 @@ \setevalue{\??chemical\c!text\the\levchemical}{\the\txtchemical}% \txtchemical=0 \dodochemical[#1][#2]% - % \@EA\txtchemical\@EA\csname\??chemical\c!text\the\levchemical\endcsname + % \expandafter\txtchemical\expandafter\csname\??chemical\c!text\the\levchemical\endcsname \txtchemical\csname\??chemical\c!text\the\levchemical\endcsname - \@EA\let\@EA\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname + \expandafter\let\expandafter\unknownchemical\csname\??chemical\s!unknown\the\levchemical\endcsname \advance\levchemical -1 %\egroup \ignorespaces} @@ -2099,7 +2099,7 @@ \verchemical=\getvalue{\s!chemical y1}\relax \else \restorechemicalvalues{\getvalue{\s!chemical n\the\chemicalstack}}% - %\@EA\let\@EA\@@chemicalpostponed\@EA=\csname\s!chemical p\the\chemicalstack\endcsname + %\expandafter\let\expandafter\@@chemicalpostponed\expandafter=\csname\s!chemical p\the\chemicalstack\endcsname \let\@@chemicalpostponed=\relax \horchemical=\getvalue{\s!chemical x\the\chemicalstack}\relax \verchemical=\getvalue{\s!chemical y\the\chemicalstack}\relax diff --git a/tex/context/modules/mkiv/s-article-basic.mkiv b/tex/context/modules/mkiv/s-article-basic.mkiv index 69a577961..677867381 100644 --- a/tex/context/modules/mkiv/s-article-basic.mkiv +++ b/tex/context/modules/mkiv/s-article-basic.mkiv @@ -11,6 +11,21 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. + +% \usemodule[article-basic,article-titletop] +% \usemodule[article-basic,article-titlepage] +% +% \startdocument +% [title={Some title}, +% subject={Some Subject}, +% author={Hans \& Ton}, +% affiliation={PRAGMA ADE}, +% date=\currentdate] +% +% \samplefile{ward} +% +% \stopdocument + \startmodule[article-basic] \unprotect @@ -70,6 +85,10 @@ \setuplist [\c!interaction=\v!all] +\setupdocument + [\c!before=\directsetup{document:titlepage}] + \protect \stopmodule + diff --git a/tex/context/modules/mkiv/s-article-titlepage.mkiv b/tex/context/modules/mkiv/s-article-titlepage.mkiv new file mode 100644 index 000000000..abfb957c2 --- /dev/null +++ b/tex/context/modules/mkiv/s-article-titlepage.mkiv @@ -0,0 +1,65 @@ +%D \module +%D [ file=s-article-titlepage, +%D version=2018.05.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Article Title Page, +%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. + +\startmodule[article-titlepage] + +\unprotect + +% \startalignment[middle] +% \let\\=\par +% \bfb +% \setupinterlinespace +% \documentvariable {subject} +% \par +% \stopalignment + +\defineframed + [titlepageframed] + [\c!frame=\v!off, + \c!align=\v!middle] + +\startsetups document:titlepage + \startstandardmakeup[\c!align=\v!middle] + \doifdocumentvariable {title} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfd\setupinterlinespace] + {\documentvariable {title}} + } + \doifdocumentvariable {subject} { + \blank[2*\v!big] + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfb\setupinterlinespace] + {\documentvariable {subject}} + } + \doifdocumentvariable {author} { + \blank[4*\v!big] + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfa\setupinterlinespace] + {\documentvariable {author}} + } + \vfill + \doifdocumentvariable {affiliation} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfa\setupinterlinespace] + {\documentvariable {affiliation}} + } + \doifdocumentvariable {date} { + \blank[\v!big] + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfa\setupinterlinespace] + {\documentvariable {date}} + } + \stopstandardmakeup +\stopsetups + +\stopmodule diff --git a/tex/context/modules/mkiv/s-article-titletop.mkiv b/tex/context/modules/mkiv/s-article-titletop.mkiv new file mode 100644 index 000000000..e68bed79b --- /dev/null +++ b/tex/context/modules/mkiv/s-article-titletop.mkiv @@ -0,0 +1,68 @@ +%D \module +%D [ file=s-article-titletop, +%D version=2018.05.20, +%D title=\CONTEXT\ Style File, +%D subtitle=Article Top Title, +%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. + +\startmodule[article-titletop] + +\unprotect + +\defineframed + [titlepageframed] + [\c!frame=\v!off, + \c!align=\v!middle] + +\startsetups document:titlepage + \setupheader[\c!state=\v!high] + \start + \forgetall + \startalignment[\v!middle] + \doifdocumentvariable {title} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfd\setupinterlinespace] + {\documentvariable {title}} + \par + } + \doifdocumentvariable {subject} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfb\setupinterlinespace] + {\documentvariable {subject}} + \par + } + \doifdocumentvariable {author} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfa\setupinterlinespace] + {\documentvariable {author}} + \par + } + \doifdocumentvariable {affiliation} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfa\setupinterlinespace] + {\documentvariable {affiliation}} + \par + } + \doifdocumentvariable {date} { + \dontleavehmode \titlepageframed + [\c!foregroundstyle=\bfa\setupinterlinespace] + {\documentvariable {date}} + \par + } + \blank[3*\v!big] + \stopalignment + \stop +\stopsetups + +\setupdocument + [\c!before=\directsetup{document:titlepage}] + +\protect + +\stopmodule diff --git a/tex/context/modules/mkiv/s-cgj.mkiv b/tex/context/modules/mkiv/s-cgj.mkiv new file mode 100644 index 000000000..2950a799d --- /dev/null +++ b/tex/context/modules/mkiv/s-cgj.mkiv @@ -0,0 +1,714 @@ +%D \module +%D [file=s-cgj.mkiv, +%D version=2018.09.28, +%D title=Context group style file, +%D subtitle=CG-journal base style, +%D author={Adrian Egger, W. Egger, Taco Hoekwater}, +%D date=\currentdate, +%D copyright={Context Group}] + +%D \type {\enablemode[draft]} has to come before loading the style. Maybe some +%D day I'll make something more official and then some \type {everydraft} or so. + +% Fixme and todo ... + +\startmodule[cgj] + +\definecolor[NoteColor][g=1,r=.25,b=.25] +\definecolor[WarnColor][r=1,g=.25,b=.25] + +\unexpanded\def\todo#1% + {\startframedtext[background=color,backgroundcolor=NoteColor] + \dontleavehmode\start\bf TODO:\stop~~#1\par + \stopframedtext} + +\unexpanded\def\fixme#1% + {\startframedtext[background=color,backgroundcolor=WarnColor] + \dontleavehmode\start\bf FIXME:\stop~~#1\par + \stopframedtext } + +%D Base set of variables. The actual values are set in the file +%D CG-journal. + +\setvariables + [CG-Journal] + [Title={Journal}, + RunningTitle={Journal}, + SubTitle={From the base set of variables}, + Version=1.0, + NOFColumns=2] + +\startmode[onecolumn,fullwidth] + \setvariables + [CG-Journal] + [NOFColumns=1] +\stopmode + +% Fonts setup. + +\usetypescriptfile[plex] + +\starttypescript [cgj] + \definetypeface [cgj] [rm] [serif][ibmplex-light] [default] + \definetypeface [cgj] [ss] [sans] [ibmplex-light] [default] + \definetypeface [cgj] [mm] [math] [palatino] [default] + \definetypeface [cgj] [tt] [mono] [ibmplex] [default][rscale=0.9] +\stoptypescript + +\starttypescript [cgj-light] + \definetypeface [cgj-light] [rm] [serif][ibmplex-extralight] [default] + \definetypeface [cgj-light] [ss] [sans] [ibmplex-extralight] [default] + \definetypeface [cgj-light] [mm] [math] [palatino] [default] + \definetypeface [cgj-light] [tt] [mono] [ibmplex-extralight] [default][rscale=0.9] +\stoptypescript + +\starttypescript [cgj-extralight] + \definetypeface [cgj-extralight] [rm] [serif][ibmplex-thin] [default] + \definetypeface [cgj-extralight] [ss] [sans] [ibmplex-thin] [default] + \definetypeface [cgj-extralight] [mm] [math] [palatino] [default] + \definetypeface [cgj-extralight] [tt] [mono] [ibmplex-thin] [default][rscale=0.9] +\stoptypescript + +\usebodyfont + [cgj-light,cgj-extralight] + +\setupbodyfont + [cgj,ss,10pt] + +\definebodyfontenvironment[10pt][interlinespace=13pt] +\definebodyfontenvironment[12pt][interlinespace=16pt] +\definebodyfontenvironment[16pt][interlinespace=20pt] + +\setupinterlinespace + [line=13pt] + +\let\sl\it + +%D Path to the logos + +\setupexternalfigures + [directory=./Logos, + location={global,local,default}] + +%D Logos: black logo only. + +\useexternalfigure + [Logo] + [cg_corp_logo_loop_black_cmyk] + [width=30mm, + height=19mm] + +%D Black logo with text + +\useexternalfigure + [LogoText] + [cg_corp_logo_text_black_cmyk] + [width=50mm, + height=35.2mm] + +%D Colors + +\definecolor[CGlightblue][c=1,m=.15,y=0,k=0] +\definecolor[CGdeepblue] [c=1,m=.8,y=0,k=.3] +\definecolor[CGgray] [c=0,m=0,y=0,k=.1] + +%D Article styles + +\definealternativestyle + [Articleheading] + [{\switchtobodyfont[16pt,ss]\bf}] + +\definealternativestyle + [Articlesubheading] + [{\switchtobodyfont[16pt,ss]\tf}] + +\definealternativestyle + [Authorname] + [{\switchtobodyfont[12pt,ss]\it}] + +\definealternativestyle + [Sectionheading] + [{\switchtobodyfont[12pt,ss]\bf\setupinterlinespace[line=12pt]}] + +\definealternativestyle + [Subsectionheading] + [{\switchtobodyfont[cgj-light,10pt,ss]\bf\setupinterlinespace[line=10pt]}] + +\definealternativestyle + [IntroCopy] + [{\switchtobodyfont[12pt,ss]\tf}] + +\definealternativestyle + [PagenumberStyle] + [{\switchtobodyfont[cgj-light,10pt,ss]\bf}] + +%D Headerstyles:Breadcrumbs + +\definealternativestyle + [BreadcrumbMd] + [{\switchtobodyfont[cgj-light,10pt,ss]\bf}] + +\definealternativestyle + [BreadcrumbRg] + [{\switchtobodyfont[cgj,10pt,ss]}] + +\definealternativestyle + [BreadcrumbLt] + [{\switchtobodyfont[10pt,ss]\tf}] + +\definealternativestyle + [BreadcrumbTh] + [{\switchtobodyfont[cgj-light,10pt,ss]\tf}] + +%D Captionstyles + +\definealternativestyle + [Captionheading] + [{\switchtobodyfont[8pt,ss]\bf\setupinterlinespace[line=8pt]}] + +\definealternativestyle + [Captiontext] + [{\switchtobodyfont[8pt,ss]\tf\setupinterlinespace[line=8pt]}] + +%D Article signature + +\definealternativestyle + [Signaturestyle] + [{\switchtobodyfont[10pt,ss]\it}] + +%D Article footnotes + +\definealternativestyle + [Articlefootnotes] + [{\switchtobodyfont[8pt,ss]\tf}] + +%D Index and TOC styles + +\definealternativestyle + [IndexContents] + [{\switchtobodyfont[16pt,ss]\bf\setupinterlinespace[line=18pt]}] + +\definealternativestyle + [IndexArticleTitle] + [{\switchtobodyfont[12pt,ss]\tf\setupinterlinespace[line=20pt]}] + +\definealternativestyle + [IndexNumber] + [{\switchtobodyfont[12pt,ss]\bf\setupinterlinespace[line=20pt]}] + +\definealternativestyle + [IndexAuthor] + [{\switchtobodyfont[12pt,ss]\it\setupinterlinespace[line=20pt]}] + +%D Math: still missing. + +%D Verbatim + +\definealternativestyle + [DisplayMonospaced] + [\tt] + +\definealternativestyle + [DisplayMonospacedX] + [{\switchtobodyfont[8pt,tt]}] + +\definealternativestyle + [DisplayMonospacedS] + [{\switchtobodyfont[9pt,tt]\setupinterlinespace[line=10pt]}] + +%D Blank adjustment + +\defineblank[CGblank] [6pt] +\defineblank[BigCGblank] [24pt] +\defineblank[MediumCGblank][12pt] + +%D Paper definition + +\definepapersize + [Journal] + [width=210mm, + height=266mm] + +\setuppapersize + [Journal] + [Journal] + +%D General layout + +\definelayout + [General] + [topspace=18mm, + backspace=28mm, + header=5mm, + headerdistance=7mm, + footer=5mm, + footerdistance=5mm, + width=157mm, + height=224mm, + marking=on] + +\definelayout + [Content] + [topspace=18mm, + backspace=28mm, + header=5mm, + headerdistance=7mm, + footer=0mm, + footerdistance=0mm, + width=157mm, + height=224mm, + margindistance=4mm, + rightmargin=21mm, + leftmargin=21mm, + marking=on] + +\definelayout + [Imprint] + [topspace=18mm, + backspace=28mm, + header=5mm, + headerdistance=7mm, + footer=5mm, + footerdistance=5mm, + width=107mm, + height=224mm, + margindistance=4mm, + rightmargin=45.3mm, + leftmargin=21mm, + marking=on] + +\definelayout + [SingleColumn] + [topspace=18mm, + backspace=55mm, + header=5mm, + headerdistance=7mm, + footer=5mm, + footerdistance=5mm, + width=130mm, + height=224mm, + margindistance=4mm, + leftmargin=48mm, + rightmargin=21mm, + marking=on] + +%D Pagenumbering: Pagenumber is set in the footer + +\setuppagenumbering + [location=, + alternative=doublesided] + +%D Head-definitions + +\setuphead + [title] + [style=Articleheading, + after={\blank[BigCGblank]}, + page=yes] + +\setuphead + [part] + [placehead=no, + after=, + before=, + page=no, + numbercommand=, + expansion=yes] + +\setuphead + [section] + [style=Sectionheading, + before={\blank[BigCGblank]}, + after={\blank[CGblank]}, + sectionstopper={.}, + distance=4pt, + align={flushleft,nothyphenated}, + resetnumber=yes, + continue=yes] + +\setuphead + [subsection] + [style=Subsectionheading, + before={\blank[CGblank]}, + after={\blank[CGblank]}, + sectionstopper=, + distance=4pt, + align={flushleft,nothyphenated}, + resetnumber=yes, + continue=yes] + +\setuphead + [subject] + [style=Sectionheading, + before={\blank[BigCGblank]}, + after=] + +\setuphead + [subsubject] + [style=Subsectionheading, + before={\blank[CGblank]}, + after={\blank[CGblank]}, + sectionstopper=] + +%D A special head for the footnote section in multicolumn mode excuse the low-level +%D rule, I wanted it to look like the start of footnotes in single column mode. (TH) + +\definehead + [footnotesubject] + [subject] + +\setuphead + [footnotesubject] + [style=Sectionheading, + before={\kern -13pt}, + after={\smash{\lower 13pt\hbox{\vrule width 2.5cm height 1pt depth 0pt}}}] + + +%D The setup of the columns is done at the moment columns are started (see end +%D of file) + +%D Index/TOC page setups + +\definelistalternative + [CGJ:Index] + [renderingsetup=CGJ:Indexheading] + +\definelistalternative + [CGJ:Index:Chapter] + [renderingsetup=CGJ:Indexheading:Chapter] + +\startsetups[CGJ:Indexheading:Chapter] + \listparameter{before} + \vbox \listboxproperties{all} { + \forgetall + \dontleavehmode + \listrenderingsynchronize + \hbox to 15mm{ + \bgroup + \useliststyleandcolor{numberstyle}{numbercolor} + \currentlistentrypagenumber + \egroup} + \bgroup + \useliststyleandcolor{textstyle}{textcolor} + \smash{\currentlistentrytitle}% + \egroup + } + \par + \listparameter{after} +\stopsetups + +\startsetups[CGJ:Indexheading] + \listparameter{before} + \vbox \listboxproperties{all} { + \forgetall + \dontleavehmode + \listrenderingsynchronize + \hbox to 15mm{ + \bgroup + \useliststyleandcolor{numberstyle}{numbercolor} + \currentlistentrypagenumber + \egroup} + \bgroup + \useliststyleandcolor{textstyle}{textcolor} + \currentlistentrytitle + \egroup + \par + } + \par + \listparameter{after} +\stopsetups + +\setuplist + [part] + [before={\blank[CGblank]}, + after=, + style=IndexContents, + numberstyle=\IndexNumber, + textstyle=\IndexArticleTitle, + prefix=no, + alternative=CGJ:Index:Chapter] + +%D Captions + +\setupcaptions + [suffix={.}, + headstyle=\Captionheading, + style=\Captiontext, + distance=6pt] + +\setupcaption[figure][way=bypart] +\setupcaption[table] [way=bypart] + +%D Datacollection: article parameters (other fields and defaults) + +\unexpanded\def\CGJBibData[#1]% + {\getparameters + [CGJ] + [SubTitle=, + RunningAuthor=, + RunningTitle=Example, + Email=, + Address=, + Page=1, + Title={My Article}, + Author={Example Author}, + Period=, + Number=, + Year=, + TocAuthor=, + TocTitle=, + #1]% + \doifnothing + {\CGJRunningTitle} + {\let\CGJRunningTitle\CGJTitle}% + \doifnothing + {\CGJRunningAuthor} + {\let\CGJRunningAuthor\CGJAuthor}% + \doifnothing + {\CGJTocAuthor} + {\let\CGJTocAuthor\CGJAuthor}% + \doifnothing + {\CGJTocTitle} + {\let\CGJTocTitle\CGJTitle}% + \setvariables + [CGJToc] + [Author=\CGJTocAuthor, + Title=\CGJTocTitle]% for TOC + } + +\unexpanded\def\dostartArticle[#1] + {\CGJBibData[#1] + \doifelse + {\getvariable{CG-Journal}{NOFColumns}} + {1} + {\doifmodeelse{fullwidth} + {\setuplayout[General]} + {\setuplayout[SingleColumn]}} + {\setupnotes[location=none] + \setuplayout[General]}% + \bgroup + {\switchtobodyfont[16pt]\Articleheading\CGJTitle\par} + {\doifsomething{\CGJSubTitle} + {\switchtobodyfont[16pt]\Articlesubheading\CGJSubTitle\par}} + {\doifsomething{\CGJAuthor} + {\switchtobodyfont[12pt]\Authorname \CGJAuthor}\par} + \part + {\getvariable{CGJToc}{Title}% + \doifsomething{\getvariable{CGJToc}{Author}}{ \emdash\ }% + \IndexAuthor\getvariable{CGJToc}{Author}} + \godown[13pt]% + \egroup + \par + \hyphenpenalty1000\relax} + +\unexpanded\def\startArticle + {\dosingleempty\dostartArticle} + +\def\signArticle + {} + +%D In multicolumn mode, footnotes come are at the end of the article: + +\startsetups article:after + \startfootnotesubject[title=] + \placefootnotes + \stopfootnotesubject +\stopsetups + +\unexpanded\def\stopArticle + {\doifelse{\getvariable{CG-Journal}{NOFColumns}}{1} + {\par + \signArticle} + {\setups{article:after} + \par + \signArticle + \stoppagecolumns} + \page} + +\unexpanded\def\startAbstract + {\bgroup + \switchtobodyfont[12pt] + \IntroCopy} + +\unexpanded\def\stopAbstract + {\par + \egroup + \finishAbstract} + +\unexpanded\def\finishAbstract + {\doifelse {\getvariable{CG-Journal}{NOFColumns}} {1} + {\blank[BigCGblank]} + {\vbox{\blank[BigCGblank]}% + \par + \startpagecolumns[balance=yes,distance=12pt,page=no,n=\getvariable{CG-Journal}{NOFColumns}] + \setupitemgroup[itemize][packed] + \setuplayout[grid=yes]} % grid mode only in columns + } + + +\unexpanded\def\noAbstract + {\kern -24pt + \finishAbstract} + +%D Headertexts + +\startsetups[Header:texts] + \setupheadertexts + [] [{{\BreadcrumbLt\CGJRunningTitle}{\BreadcrumbTh\doifsomething{\CGJRunningAuthor}{\ > }\CGJRunningAuthor}}] %odd + [{\BreadcrumbMd contextgroup}{\BreadcrumbRg\ > \getvariable{CG-Journal}{RunningTitle}}] [] %even +\stopsetups + +%D Footertexts + +\startsetups[Footer:texts] + \setupfootertexts + [] [\PagenumberStyle\pagenumber] + [\PagenumberStyle\pagenumber] [] +\stopsetups + +%D Setup tolerance, stretch. + +\setuptolerance + [tolerant,stretch] + +%D Setting up footnotes. + +\setupnotation + [footnote] + [way=bypart, + rule=on] + +%D Adjustments to the container containing the footnotes. + +\setupnote + [footnote] + [frame=off, + topframe=off , + framecolor=black, + background=, + rulecolor=black, %% the line above the inserts + rulethickness=1pt, + next={ }, + split=verystrict, + scope=page, + style=Articlefootnotes] + +\doifmodeelse {draft} {\setupnote[footnote][frame=on]} + +% Setup typing. + +\setupnarrower + [middle=3mm, + left=5mm] + +\definetextbackground + [verbatim] + [frame=off, + background=color, + backgroundcolor=CGgray, + leftoffset=2mm,rightoffset=2mm, + topoffset=2mm,bottomoffset=2mm, + location=paragraph, + align=flushleft] + +\doifmodeelse {draft} {\definetextbackground[verbatim][frame=on]} + +\definetextbackground + [verbatimitem] + [verbatim] + +\setuptextbackground + [verbatimitem] + [before=, + after=, + width=\the\dimexpr\hsize-10.5mm\relax] + +\startsetups typing:before + \blank[MediumCGblank] + \starttextbackground[verbatim] +\stopsetups + +\startsetups typing:before:small + \blank[MediumCGblank] + \starttextbackground[verbatim] +\stopsetups + +\startsetups typing:after + \stoptextbackground + \blank[MediumCGblank] +\stopsetups + +\startsetups typing:before:item + \starttextbackground[verbatimitem] +\stopsetups + +\startsetups typing:after:item + \stoptextbackground +\stopsetups + +\setuptyping + [typing] + [style=DisplayMonospaced, + before=\setups{typing:before}, + after=\setups{typing:after}] + +\setuptype + [style=DisplayMonospaced] + +%D When verbatim becomes too large: + +\definetyping + [smalltyping] + +\setuptyping + [smalltyping] + [style=DisplayMonospacedX, + before=\setups{typing:before:small}, + after=\setups{typing:after}] + +\unexpanded\def\smalltypefile{\typefile[smalltyping][]} + +%D Bullet lists. + +\setupitemgroup + [itemize] + [each] + [] + [symbol=1, + indentnext=no, + align=right, + before={\blank[MediumCGblank]\startnarrower[left]}, + after={\stopnarrower\blank[MediumCGblank]}, + inbetween={\blank[CGblank]}] + +\definedescription + [description] + [location=hanging, + width=broad, + before={\blank}, + after={\blank}] + +\setupformula + [align=flushleft, + margin=5mm] + +\setupquotation + [before={\blank[CGblank]\switchtobodyfont[10pt]}, + after={\blank[CGblank]}] + +\setupwhitespace + [medium] + +\usemodule[abr-02,abr-03,abr-04] + +\unexpanded\def\Href#1{\underbar{\hyphenatedurl{#1}}} +\unexpanded\def\CG {\ConTeXt\ group} + +\setnewconstant\kindofpagetextareas\plusone % partial page. HH: low level, no high level switch (yet) + +%D There is a draft mode, which enables all frames: + +\doifmode {draft} {\showframe} + +\stopmodule + diff --git a/tex/context/modules/mkiv/s-evohome.mkiv b/tex/context/modules/mkiv/s-evohome.mkiv index 1577517e5..06fd6fb76 100644 --- a/tex/context/modules/mkiv/s-evohome.mkiv +++ b/tex/context/modules/mkiv/s-evohome.mkiv @@ -198,13 +198,19 @@ function moduledata.evohome.history(specification) local m = 0 for minute, d in next, hour do local v = d[where] - a = a + v - n = n + 1 - if v > m then - m = v + if v then + a = a + v + n = n + 1 + if v > m then + m = v + end end end - a = a / n + if n > 0 then + a = a / n + else + a = 0 + end local dx = xoffset + h local dy = a/scale local dm = m/scale diff --git a/tex/context/modules/mkiv/s-fonts-basics.mkiv b/tex/context/modules/mkiv/s-fonts-basics.mkiv index e9d0a21a2..370be3598 100644 --- a/tex/context/modules/mkiv/s-fonts-basics.mkiv +++ b/tex/context/modules/mkiv/s-fonts-basics.mkiv @@ -1,5 +1,5 @@ %D \module -%D [ file=s-fnt-01, +%D [ file=s-fonts-basics, % was s-fnt-01, %D version=2006.10.10, % guess %D title=\CONTEXT\ Style File, %D subtitle=Listing Glyphs in Large Fonts, diff --git a/tex/context/modules/mkiv/s-fonts-charts.mkiv b/tex/context/modules/mkiv/s-fonts-charts.mkiv index e94b52a2e..3123cc0d0 100644 --- a/tex/context/modules/mkiv/s-fonts-charts.mkiv +++ b/tex/context/modules/mkiv/s-fonts-charts.mkiv @@ -15,7 +15,7 @@ % % title : show unicode blocks % -% comment : show charts of a given fgont +% comment : show charts of a given font % % end info @@ -87,7 +87,7 @@ local settings = utilities.parsers.settings_to_hash(settings) - local filename = settings.filename or "" + local filename = settings.filename or settings.name or "" local fontid = true local newpage = settings.page == interfaces.variables.yes @@ -169,36 +169,40 @@ \starttext - \showfontchart[filename=LucidaBrightOT.otf,page=yes] - \showfontchart[filename=LucidaBrightOT-Demi.otf,page=yes] - \showfontchart[filename=LucidaBrightOT-DemiItalic.otf,page=yes] - \showfontchart[filename=LucidaBrightOT-Italic.otf,page=yes] - - \showfontchart[filename=LucidaSansOT.otf,page=yes] - \showfontchart[filename=LucidaSansOT-Demi.otf,page=yes] - \showfontchart[filename=LucidaSansOT-DemiItalic.otf,page=yes] - \showfontchart[filename=LucidaSansOT-Italic.otf,page=yes] - - \showfontchart[filename=LucidaSansTypewriterOT.otf,page=yes] - \showfontchart[filename=LucidaSansTypewriterOT-Bold.otf,page=yes] - \showfontchart[filename=LucidaSansTypewriterOT-BoldOblique.otf,page=yes] - \showfontchart[filename=LucidaSansTypewriterOT-Oblique.otf,page=yes] - - \showfontchart[filename=LucidaConsoleDK.otf,page=yes] - \showfontchart[filename=LucidaConsoleDK-Bold.otf,page=yes] - \showfontchart[filename=LucidaConsoleDK-BoldItalic.otf,page=yes] - \showfontchart[filename=LucidaConsoleDK-Italic.otf,page=yes] - - \showfontchart[filename=LucidaGrandeMonoDK.otf,page=yes] - \showfontchart[filename=LucidaGrandeMonoDK-Bold.otf,page=yes] - \showfontchart[filename=LucidaGrandeMonoDK-BoldItalic.otf,page=yes] - \showfontchart[filename=LucidaGrandeMonoDK-Italic.otf,page=yes] - - \showfontchart[filename=LucidaBrightMathOT.otf,page=yes] - \showfontchart[filename=LucidaBrightMathOT-Demi.otf,page=yes] - - \showfontchart[filename=LucidaBlackletterOT.otf,page=yes] - \showfontchart[filename=LucidaCalligraphyOT.otf,page=yes] - \showfontchart[filename=LucidaHandwritingOT.otf,page=yes] + \showfontchart[filename=aegean,page=yes] +% \showfontchart[filename=veramono.ttf,page=yes] +% \showfontchart[filename=CoelacanthSubhdHeavy.otf,page=yes] + +% \showfontchart[filename=LucidaBrightOT.otf,page=yes] +% \showfontchart[filename=LucidaBrightOT-Demi.otf,page=yes] +% \showfontchart[filename=LucidaBrightOT-DemiItalic.otf,page=yes] +% \showfontchart[filename=LucidaBrightOT-Italic.otf,page=yes] + +% \showfontchart[filename=LucidaSansOT.otf,page=yes] +% \showfontchart[filename=LucidaSansOT-Demi.otf,page=yes] +% \showfontchart[filename=LucidaSansOT-DemiItalic.otf,page=yes] +% \showfontchart[filename=LucidaSansOT-Italic.otf,page=yes] + +% \showfontchart[filename=LucidaSansTypewriterOT.otf,page=yes] +% \showfontchart[filename=LucidaSansTypewriterOT-Bold.otf,page=yes] +% \showfontchart[filename=LucidaSansTypewriterOT-BoldOblique.otf,page=yes] +% \showfontchart[filename=LucidaSansTypewriterOT-Oblique.otf,page=yes] + +% \showfontchart[filename=LucidaConsoleDK.otf,page=yes] +% \showfontchart[filename=LucidaConsoleDK-Bold.otf,page=yes] +% \showfontchart[filename=LucidaConsoleDK-BoldItalic.otf,page=yes] +% \showfontchart[filename=LucidaConsoleDK-Italic.otf,page=yes] + +% \showfontchart[filename=LucidaGrandeMonoDK.otf,page=yes] +% \showfontchart[filename=LucidaGrandeMonoDK-Bold.otf,page=yes] +% \showfontchart[filename=LucidaGrandeMonoDK-BoldItalic.otf,page=yes] +% \showfontchart[filename=LucidaGrandeMonoDK-Italic.otf,page=yes] + +% \showfontchart[filename=LucidaBrightMathOT.otf,page=yes] +% \showfontchart[filename=LucidaBrightMathOT-Demi.otf,page=yes] + +% \showfontchart[filename=LucidaBlackletterOT.otf,page=yes] +% \showfontchart[filename=LucidaCalligraphyOT.otf,page=yes] +% \showfontchart[filename=LucidaHandwritingOT.otf,page=yes] \stoptext diff --git a/tex/context/modules/mkiv/s-fonts-complete.mkiv b/tex/context/modules/mkiv/s-fonts-complete.mkiv index afdd79b4c..83aa708df 100644 --- a/tex/context/modules/mkiv/s-fonts-complete.mkiv +++ b/tex/context/modules/mkiv/s-fonts-complete.mkiv @@ -29,23 +29,36 @@ local descriptions = tfmdata.descriptions or { } local data = characters.data -- context.setuptabulate { header = "repeat" } - context.starttabulatehead() - NC() bold("unicode") - NC() bold("visual") - NC() bold("index") - NC() bold("glyph") - NC() bold("adobe") - NC() bold("context") - NC() NR() - context.stoptabulatehead() - context.starttabulate { "|l|c|l|p|p|p|" } + -- context.starttabulatehead() + -- NC() bold("unicode") + -- NC() bold("visual") + -- NC() bold("index") + -- NC() bold("tounicode") + -- NC() bold("unicodes") + -- NC() bold("glyph") + -- NC() bold("adobe") + -- NC() bold("context") + -- NC() NR() + -- context.stoptabulatehead() + context.starttabulate { "|l|c|p(8em)|l|l|p|p|p|" } + NC() bold("unicode") + NC() bold("visual") + NC() bold("unicodes") + NC() bold("tounicode") + NC() bold("index") + NC() bold("glyph") + NC() bold("adobe") + NC() bold("context") + NC() NR() for unicode, chr in fonts.iterators.characters(tfmdata) do local des, dat = descriptions[unicode], data[unicode] - local index = chr.index or 0 - local cname = (dat and dat.contextname) or "" - local aname = (dat and dat.adobename) or "" - local gname = (des and des.name) or "" - local mname = dat and dat.mathname + local index = chr.index or 0 + local tounicode = chr.tounicode + local isunicode = chr.unicode + local cname = (dat and dat.contextname) or "" + local aname = (dat and dat.adobename) or "" + local gname = (des and des.name) or "" + local mname = dat and dat.mathname if type(mname) ~= "string" then mname = "" end @@ -70,12 +83,52 @@ cname = mname end end - NC() tttf() context("U+%05X",unicode) - NC() char(unicode) - NC() tttf() context("%05X",index) - NC() if gname ~= "" then tttf() escaped(gname) end - NC() if aname ~= "" then tttf() context(aname) end - NC() if cname ~= "" then tttf() context(cname) end + NC() + tttf() + context("%05X",unicode) + NC() + char(unicode) + NC() + if isunicode then + tttf() + if type(isunicode) == "table" then + for i=1,#isunicode do + if i > 1 then + if i % 2 ~= 0 then + context.crlf() + else + context.space() + end + end + context("%05X",isunicode[i]) + end + else + context("%05X",isunicode) + end + end + NC() + if tounicode then + tttf() + context(tounicode) + end + NC() + tttf() + context("%05X",index) + NC() + if gname ~= "" then + tttf() + escaped(gname) + end + NC() + if aname ~= "" then + tttf() + context(aname) + end + NC() + if cname ~= "" then + tttf() + context(cname) + end NC() NR() end context.stoptabulate() @@ -100,14 +153,13 @@ \font\TestFont=#1 at #2 \setuplayout[style=\TestFont] \setupheadertexts[] - \setupfootertexts[#1 -- \pagenumber] - \setupfootertexts[pagenumber] + \setupfootertexts[#1\space\endash\space\pagenumber] \setuplayout[width=middle,height=middle,topspace=1cm,backspace=1cm] \TestFont \nonknuthmode \startcolumns[n=#3] - \TestFont - \ctxlua { moduledata.fonts.complete.all() } + \TestFont + \ctxlua { moduledata.fonts.complete.all() } \stopcolumns \page \endgroup} @@ -125,14 +177,16 @@ \TestFontB \setupinterlinespace[line=1.2\dimexpr#2\relax] \raggedcenter \nonknuthmode \startcolumns[n=#3] - \TestFontB - \ctxlua { moduledata.fonts.complete.glyphs() } + \TestFontB + \ctxlua { moduledata.fonts.complete.glyphs() } \stopcolumns \page \endgroup} \continueifinputfile{s-fonts-complete.mkiv} +\usemodule[art-01] \setuplayout[overview] \setupbodyfont[8pt] + \starttext % \ShowCompleteFont{name:dejavusansmono}{10pt}{1} @@ -140,7 +194,7 @@ % \ShowCompleteFont{name:officinasansbookitcregular}{10pt}{2} % \ShowCompleteFont{name:officinaserifbookitcregular}{10pt}{2} % \ShowCompleteFont{name:serpentineserifeflight}{10pt}{2} -\ShowCompleteFont{name:lmroman10-regular}{10pt}{1} +% \ShowCompleteFont{name:lmroman10-regular}{10pt}{1} % \ShowCompleteFont{name:lmtypewriter10-regular}{10pt}{2} % \ShowCompleteFont{lt55485}{10pt}{2} % \ShowCompleteFont{lmr10}{10pt}{2} @@ -157,4 +211,13 @@ % \ShowCompleteFont{name:palatinonovaregular}{11pt}{2} % \ShowCompleteFont{pirat.ttf}{12pt}{1} +\setuplayout[overview][footer=1cm] \setuplayout[overview]% \setupheadertexts[aegean.ttf] + +\ShowCompleteFont{file:aegean} {8pt}{1} +% \ShowCompleteFont{file:tsukurimashouminchops}{8pt}{1} +% \ShowCompleteFont{file:tsukurimashoumincho} {8pt}{1} +% \ShowCompleteFont{file:tsukurimashoukakups} {8pt}{1} +% \ShowCompleteFont{file:tsukurimashoukaku} {8pt}{1} +% \ShowCompleteFont{file:akkadian} {8pt}{1} + \stoptext diff --git a/tex/context/modules/mkiv/s-fonts-effects.mkiv b/tex/context/modules/mkiv/s-fonts-effects.mkiv new file mode 100644 index 000000000..9b712938b --- /dev/null +++ b/tex/context/modules/mkiv/s-fonts-effects.mkiv @@ -0,0 +1,59 @@ +%D \module +%D [ file=s-fonts-basics, % was s-fnt-01, +%D version=2006.10.10, % guess +%D title=\CONTEXT\ Style File, +%D subtitle=Listing Glyphs in Large Fonts, +%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. + +%D This module is just a check for \type {luatex-basics-prepare}. + +\startmodule[fonts-effects] + +\startluacode +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.effects = moduledata.fonts.effects or { } + +function moduledata.fonts.effects.showfonteffect() + local effect = fonts.hashes.properties[true].effect + if effect then + local context = context + local BC, NC, EQ, NR = context.BC, context.NC, context.EQ, context.NR + context.starttabulate { "||||||||" } + BC() context("id") EQ() context(font.current()) + BC() context("factor") EQ() context(effect.factor) + BC() context("wdelta") EQ() context(effect.wdelta) + NC() NR() + BC() context("effect") EQ() context(effect.effect) + BC() context("hfactor") EQ() context(effect.hfactor) + BC() context("hdelta") EQ() context(effect.hdelta) + NC() NR() + BC() context("width") EQ() context(effect.width) + BC() context("vfactor") EQ() context(effect.vfactor) + BC() context("ddelta") EQ() context(effect.ddelta) + NC() NR() + context.stoptabulate() + end +end +\stopluacode + +\installmodulecommandluasingle \showfonteffect {moduledata.fonts.effects.showfonteffect} + +\stopmodule + +\continueifinputfile{s-fonts-effects.mkiv} + +\usemodule[art-01] + +\starttext + + \definedfont[Serif*default,boldened] An example. + + \showfonteffect + +\stopmodule diff --git a/tex/context/modules/mkiv/s-fonts-features.lua b/tex/context/modules/mkiv/s-fonts-features.lua index 6f4032948..6c676ce2d 100644 --- a/tex/context/modules/mkiv/s-fonts-features.lua +++ b/tex/context/modules/mkiv/s-fonts-features.lua @@ -11,7 +11,7 @@ moduledata.fonts.features = moduledata.fonts.features or { } -- for the moment only otf -local sortedhash = table.sortedhash +local insert, remove, sortedhash = table.insert, table.remove, table.sortedhash local v_yes = interfaces.variables.yes local v_no = interfaces.variables.no @@ -87,66 +87,35 @@ local function collectkerns(tfmdata,feature) local lookuphash = resources.lookuphash local feature = feature or "kern" if sequences then - - if true then - - for i=1,#sequences do - local sequence = sequences[i] - if sequence.features and sequence.features[feature] then - local steps = sequence.steps - for i=1,#steps do - local step = steps[i] - local format = step.format - for unicode, hash in table.sortedhash(step.coverage) do - local kerns = combinations[unicode] - if not kerns then - kerns = { } - combinations[unicode] = kerns - end - for otherunicode, kern in table.sortedhash(hash) do - if format == "pair" then - local f = kern[1] - local s = kern[2] - if f then - if s then - -- todo - else - if not kerns[otherunicode] and f[3] ~= 0 then - kerns[otherunicode] = f[3] - end - end - elseif s then - -- todo - end - elseif format == "kern" then - if not kerns[otherunicode] and kern ~= 0 then - kerns[otherunicode] = kern - end - end - end - end - end - end - end - end - - else -- old loader - for i=1,#sequences do local sequence = sequences[i] if sequence.features and sequence.features[feature] then - local lookuplist = sequence.subtables - if lookuplist then - for l=1,#lookuplist do - local lookupname = lookuplist[l] - local lookupdata = lookuphash[lookupname] - for unicode, data in next, lookupdata do - local kerns = combinations[unicode] - if not kerns then - kerns = { } - combinations[unicode] = kerns - end - for otherunicode, kern in next, data do + local steps = sequence.steps + for i=1,#steps do + local step = steps[i] + local format = step.format + for unicode, hash in table.sortedhash(step.coverage) do + local kerns = combinations[unicode] + if not kerns then + kerns = { } + combinations[unicode] = kerns + end + for otherunicode, kern in table.sortedhash(hash) do + if format == "pair" then + local f = kern[1] + local s = kern[2] + if f then + if s then + -- todo + else + if not kerns[otherunicode] and f[3] ~= 0 then + kerns[otherunicode] = f[3] + end + end + elseif s then + -- todo + end + elseif format == "kern" then if not kerns[otherunicode] and kern ~= 0 then kerns[otherunicode] = kern end @@ -156,7 +125,6 @@ local function collectkerns(tfmdata,feature) end end end - end return combinations @@ -230,3 +198,90 @@ function moduledata.fonts.features.showfeatureset(specification) end end end + +local function collectligatures(tfmdata) + local sequences = tfmdata.resources.sequences + + if not sequences then + return + end + + local series = { } + local stack = { } + local max = 0 + + local function make(tree) + for k, v in sortedhash(tree) do + if k == "ligature" then + local n = #stack + if n > max then + max = n + end + series[#series+1] = { v, unpack(stack) } + else + insert(stack,k) + make(v) + remove(stack) + end + end + end + + for i=1,#sequences do + local sequence = sequences[i] + if sequence.type == "gsub_ligature" then + local steps = sequence.steps + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + make(coverage) + end + end + end + end + + return series, max +end + +function moduledata.fonts.features.showallligatures(specification) + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"") + local tfmdata = fonts.hashes.identifiers[id] + local allligatures, + max = collectligatures(tfmdata) + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + if #allligatures > 0 then + context.starttabulate { "|T|" .. string.rep("|",max) .. "|T|T|" } + for i=1,#allligatures do + local s = allligatures[i] + local n = #s + local u = s[1] + local c = characters[u] + local d = descriptions[u] + NC() + context("%U",u) + NC() + context("\\setfontid%i\\relax",id) + context.char(u) + NC() + context("\\setfontid%i\\relax",id) + for i=2,n do + context.char(s[i]) + NC() + end + for i=n+1,max do + NC() + end + context(d.name) + NC() + context(c.tounicode) + NC() + NR() + end + context.stoptabulate() + else + context("no ligatures found") + context.par() + end +end diff --git a/tex/context/modules/mkiv/s-fonts-features.mkiv b/tex/context/modules/mkiv/s-fonts-features.mkiv index 2dca059ff..2390c44df 100644 --- a/tex/context/modules/mkiv/s-fonts-features.mkiv +++ b/tex/context/modules/mkiv/s-fonts-features.mkiv @@ -18,6 +18,7 @@ \installmodulecommandluasingle \showusedfeatures {moduledata.fonts.features.showused} \installmodulecommandluasingle \showallkerns {moduledata.fonts.features.showallkerns} \installmodulecommandluasingle \showbasekerns {moduledata.fonts.features.showbasekerns} +\installmodulecommandluasingle \showallligatures {moduledata.fonts.features.showallligatures} \installmodulecommandluasingle \showfeatureset {moduledata.fonts.features.showfeatureset} \def\kernpairheight{.8\strutht} diff --git a/tex/context/modules/mkiv/s-fonts-shapes.lua b/tex/context/modules/mkiv/s-fonts-shapes.lua index 748c5a92a..868c22da1 100644 --- a/tex/context/modules/mkiv/s-fonts-shapes.lua +++ b/tex/context/modules/mkiv/s-fonts-shapes.lua @@ -38,39 +38,6 @@ local function special(id,specials) end end -function moduledata.fonts.shapes.showlist(specification) -- todo: ranges - specification = interfaces.checkedspecification(specification) - local id, cs = fonts.definers.internal(specification,"") - local chrs = fontdata[id].characters - context.begingroup() - context.tt() - context.starttabulate { "|l|c|c|c|c|l|l|" } - context.FL() - NC() context.bold("unicode") - NC() context.bold("glyph") - NC() context.bold("shape") - NC() context.bold("lower") - NC() context.bold("upper") - NC() context.bold("specials") - NC() context.bold("description") - NC() NR() - context.TL() - for k, v in next, characters.data do - if chrs[k] then - NC() context("0x%05X",k) - NC() char(id,k) -- getvalue(cs) context.char(k) - NC() char(id,v.shcode) - NC() char(id,v.lccode or k) - NC() char(id,v.uccode or k) - NC() special(id,v.specials) - NC() context.tx(v.description) - NC() NR() - end - end - context.stoptabulate() - context.endgroup() -end - function moduledata.fonts.shapes.showlist(specification) -- todo: ranges specification = interfaces.checkedspecification(specification) local id, cs = fonts.definers.internal(specification,"") @@ -107,220 +74,177 @@ end local descriptions = nil local characters = nil + local function showglyphshape(specification) - specification = interfaces.checkedspecification(specification) - local id, cs = fonts.definers.internal(specification,"") - local tfmdata = fontdata[id] - local charnum = tonumber(specification.character) or fonts.helpers.nametoslot(specification.character) - local characters = tfmdata.characters - local descriptions = tfmdata.descriptions - local parameters = tfmdata.parameters - local c = characters[charnum] - local d = descriptions[charnum] - if d then - local factor = (parameters.size/parameters.units)*((7200/7227)/65536) - local llx, lly, urx, ury = unpack(d.boundingbox) - llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor - local width, italic = (d.width or 0)*factor, (d.italic or 0)*factor - local top_accent, bot_accent = (d.top_accent or 0)*factor, (d.bot_accent or 0)*factor - local anchors, math = d.anchors, d.math - context.start() - context.dontleavehmode() - context.obeyMPboxdepth() - context.startMPcode() - context("numeric lw ; lw := .125bp ;") - context("pickup pencircle scaled lw ;") - if width < 0.01 then - -- catches zero width marks - context('picture p ; p := textext.drt("\\hskip5sp\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,charnum) - else - context('picture p ; p := textext.drt("\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,charnum) - end - context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury) - context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0) - context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;') - context("defaultscale := 0.05 ; ") - -- inefficient but non critical - local slant = { - function(v,dx,dy,txt,xsign,ysign,loc,labloc) - local n = #v - if n > 0 then - local l = { } - for i=1,n do - local c = v[i] - local h = c.height or 0 - local k = c.kern or 0 - l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) - end - context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1]) --- context("draw laddered (%s) withcolor .5white ;",table.concat(l,"..")) - context("draw laddered (%..t) withcolor .5white ;",l) - context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l]) - for i=1,n do - context("draw %s withcolor blue withpen pencircle scaled 2lw ;",l[i]) - end - end - end, - function(v,dx,dy,txt,xsign,ysign,loc,labloc) - local n = #v - if n > 0 then - local l = { } - for i=1,n do - local c = v[i] - local h = c.height or 0 - local k = c.kern or 0 - l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) - end - if loc == "top" then - context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[n]) - else - context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1]) + -- + local specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"") + local tfmdata = fontdata[id] + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local parameters = tfmdata.parameters + local anchors = fonts.helpers.collectanchors(tfmdata) + + local function showonecharacter(unicode) + local c = characters [unicode] + local d = descriptions[unicode] + if c and d then + local factor = (parameters.size/parameters.units)*((7200/7227)/65536) + local llx, lly, urx, ury = unpack(d.boundingbox) + llx, lly, urx, ury = llx*factor, lly*factor, urx*factor, ury*factor + local width = (d.width or 0)*factor + context.start() + context.dontleavehmode() + context.obeyMPboxdepth() + context.startMPcode() + context("numeric lw ; lw := .125bp ;") + context("pickup pencircle scaled lw ;") + if width < 0.01 then + -- catches zero width marks + context('picture p ; p := textext.drt("\\hskip5sp\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,unicode) + else + context('picture p ; p := textext.drt("\\getuvalue{%s}\\gray\\char%s"); draw p ;',cs,unicode) + end + context('draw (%s,%s)--(%s,%s)--(%s,%s)--(%s,%s)--cycle withcolor green ;',llx,lly,urx,lly,urx,ury,llx,ury) + context('draw (%s,%s)--(%s,%s) withcolor green ;',llx,0,urx,0) + context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;') + context("defaultscale := 0.05 ; ") + -- inefficient but non critical + local slant = { + function(v,dx,dy,txt,xsign,ysign,loc,labloc) + local n = #v + if n > 0 then + local l = { } + for i=1,n do + local c = v[i] + local h = c.height or 0 + local k = c.kern or 0 + l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) + end + context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[1].kern*factor,lly,dx,dy,l[1]) + context("draw laddered (%..t) withcolor .5white ;",l) -- why not "--" + context("draw ((%s,%s) shifted (%s,%s))--%s dashed (evenly scaled 1/16) withcolor .5white;", xsign*v[#v].kern*factor,ury,dx,dy,l[#l]) + for i=1,n do + context("draw %s withcolor blue withpen pencircle scaled 2lw ;",l[i]) + end end - for i=1,n do - local c = v[i] - local h = c.height or 0 - local k = c.kern or 0 - context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[i]) + end, + function(v,dx,dy,txt,xsign,ysign,loc,labloc) + local n = #v + if n > 0 then + local l = { } + for i=1,n do + local c = v[i] + local h = c.height or 0 + local k = c.kern or 0 + l[i] = formatters["((%s,%s) shifted (%s,%s))"](xsign*k*factor,ysign*h*factor,dx,dy) + end + if loc == "top" then + context('label.%s("\\type{%s}",%s shifted (0,-1bp)) ;',loc,txt,l[n]) + else + context('label.%s("\\type{%s}",%s shifted (0,2bp)) ;',loc,txt,l[1]) + end + for i=1,n do + local c = v[i] + local h = c.height or 0 + local k = c.kern or 0 + context('label.top("(%s,%s)",%s shifted (0,-2bp));',k,h,l[i]) + end end - end - end, - } - if math then - local kerns = math.kerns - if kerns then - for i=1,#slant do - local s = slant[i] - for k, v in next, kerns do - if k == "topright" then - s(v,width+italic,0,k,1,1,"top","ulft") - elseif k == "bottomright" then - s(v,width,0,k,1,1,"bot","lrt") - elseif k == "topleft" then - s(v,0,0,k,-1,1,"top","ulft") - elseif k == "bottomleft" then - s(v,0,0,k,-1,1,"bot","lrt") + end, + } + -- + local math = d.math + if math then + local kerns = math.kerns + if kerns then + for i=1,#slant do + local s = slant[i] + for k, v in next, kerns do + if k == "topright" then + -- s(v,width+italic,0,k,1,1,"top","ulft") + s(v,width,0,k,1,1,"top","ulft") + elseif k == "bottomright" then + s(v,width,0,k,1,1,"bot","lrt") + elseif k == "topleft" then + s(v,0,0,k,-1,1,"top","ulft") + elseif k == "bottomleft" then + s(v,0,0,k,-1,1,"bot","lrt") + end end end end - end - end - local function show(x,y,txt) - local xx, yy = x*factor, y*factor - context("draw (%s,%s) withcolor blue withpen pencircle scaled 2lw ;",xx,yy) - context('label.top("\\type{%s}",(%s,%s-2bp)) ;',txt,xx,yy) - context('label.bot("(%s,%s)",(%s,%s+2bp)) ;',x,y,xx,yy) - end - if anchors then - local a = anchors.baselig - if a then - for k, v in next, a do - for i=1,#v do - local p = v[i] - show(p[1],p[2],k .. ":" .. i) - end + local accent = math.accent + if accent and accent ~= 0 then + local a = accent * factor + context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',a,ury,a,ury) + context('label.bot("\\type{%s}",(%s,%s+1bp));',"accent",a,ury) + context('label.top("%s",(%s,%s-1bp));',math.accent,a,ury) end end - local a = anchors.mark - if a then - for k, v in next, a do - show(v[1],v[2],k) - end - end - local a = anchors.basechar - if a then - for k, v in next, a do - show(v[1],v[2],k) + -- + local anchordata = anchors[unicode] + if anchordata then + local function show(txt,list) + if list then + for i=1,#list do + local li = list[i] + local x, y = li[1], li[2] + local xx, yy = x*factor, y*factor + context("draw (%s,%s) withcolor blue withpen pencircle scaled 2lw ;",xx,yy) + context('label.top("\\infofont %s",(%s,%s-2.75bp)) ;',txt .. i,xx,yy) + context('label.bot("\\infofont (%s,%s)",(%s,%s+2.75bp)) ;',x,y,xx,yy) + end + end end + -- + show("b",anchordata.base) + show("m",anchordata.mark) + show("l",anchordata.ligature) + show("e",anchordata.entry) + show("x",anchordata.exit) end - local ba = anchors.centry - if a then - for k, v in next, a do - show(v[1],v[2],k) - end + -- + local italic = d.italic + if italic and italic ~= 0 then + local i = italic * factor + context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width,ury,width,ury) + context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width+i,ury,width+i,ury) + context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue ;',width,ury,width+i,ury) + context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury) + context('label.rt("%s",(%s-2bp,%s-1bp));',italic,width+i,ury) end - local a = anchors.cexit - if a then - for k, v in next, a do - show(v[1],v[2],k) - end - end - end - if italic ~= 0 then - context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width,ury,width,ury) - context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue ;',width+italic,ury,width+italic,ury) - context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue ;',width,ury,width+italic,ury) - context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,ury) - context('label.rt("%s",(%s-2bp,%s-1bp));',d.italic,width+italic,ury) - end - if top_accent ~= 0 then - context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,ury) - context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,ury) - context('label.top("%s",(%s,%s-1bp));',d.top_accent,top_accent,ury) - end - if bot_accent ~= 0 then - context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,lly) - context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,ury) - context('label.bot("%s",(%s,%s+1bp));',d.bot_accent,bot_accent,lly) + context('draw origin withcolor red withpen pencircle scaled 2lw;') + context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;") + context("currentpicture := currentpicture scaled 8 ;") + context.stopMPcode() + context.stop() end - context('draw origin withcolor red withpen pencircle scaled 2lw;') - context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;") - context("currentpicture := currentpicture scaled 8 ;") - context.stopMPcode() - context.stop() - -- elseif c then - -- lastdata, lastunicode = nil, nil - -- local factor = (7200/7227)/65536 - -- context.startMPcode() - -- context("pickup pencircle scaled .25bp ; ") - -- context('picture p ; p := image(draw textext.drt("\\gray\\char%s");); draw p ;',charnum) - -- context('draw boundingbox p withcolor .2white withpen pencircle scaled .065bp ;') - -- context("defaultscale := 0.05 ; ") - -- local italic, top_accent, bot_accent = (c.italic or 0)*factor, (c.top_accent or 0)*factor, (c.bot_accent or 0)*factor - -- local width, height, depth = (c.width or 0)*factor, (c.height or 0)*factor, (c.depth or 0)*factor - -- local ury = height - -- if italic ~= 0 then - -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width,ury,width,ury) - -- context('draw (%s,%s-1bp)--(%s,%s-0.5bp) withcolor blue;',width+italic,ury,width+italic,ury) - -- context('draw (%s,%s-1bp)--(%s,%s-1bp) withcolor blue;',width,ury,width+italic,height) - -- context('label.lft("\\type{%s}",(%s+2bp,%s-1bp));',"italic",width,height) - -- context('label.rt("%6.3f bp",(%s-2bp,%s-1bp));',italic,width+italic,height) - -- end - -- if top_accent ~= 0 then - -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',top_accent,ury,top_accent,height) - -- context('label.bot("\\type{%s}",(%s,%s+1bp));',"top_accent",top_accent,height) - -- context('label.top("%6.3f bp",(%s,%s-1bp));',top_accent,top_accent,height) - -- end - -- if bot_accent ~= 0 then - -- context('draw (%s,%s+1bp)--(%s,%s-1bp) withcolor blue;',bot_accent,lly,bot_accent,height) - -- context('label.top("\\type{%s}",(%s,%s-1bp));',"bot_accent",top_accent,height) - -- context('label.bot("%6.3f bp",(%s,%s+1bp));',bot_accent,bot_accent,height) - -- end - -- context('draw origin withcolor red withpen pencircle scaled 1bp;') - -- context("setbounds currentpicture to boundingbox currentpicture enlarged 1bp ;") - -- context("currentpicture := currentpicture scaled 8 ;") - -- context.stopMPcode() - else - -- lastdata, lastunicode = nil, nil - -- context("no such shape: 0x%05X",charnum) end -end -moduledata.fonts.shapes.showglyphshape = showglyphshape + local unicode = tonumber(specification.character) or + fonts.helpers.nametoslot(specification.character) -function moduledata.fonts.shapes.showallglypshapes(specification) - specification = interfaces.checkedspecification(specification) - local id, cs = fonts.definers.internal(specification,"") - local descriptions = fontdata[id].descriptions - for unicode, description in fonts.iterators.descriptions(tfmdata) do - if unicode >= 0x110000 then - break + if unicode then + showonecharacter(unicode) + else + context.modulefontsstartshowglyphshapes() + for unicode, description in fonts.iterators.descriptions(tfmdata) do + if unicode >= 0x110000 then + break + end + context.modulefontsstartshowglyphshape(unicode,description.name or "",description.index or 0) + showonecharacter(unicode) + context.modulefontsstopshowglyphshape() end - context.modulefontsstartshowglyphshape(unicode,description.name or "",description.index or 0) - showglyphshape { number = id, character = unicode } - context.modulefontsstopshowglyphshape() + context.modulefontsstopshowglyphshapes() end + end +moduledata.fonts.shapes.showglyphshape = showglyphshape +moduledata.fonts.shapes.showallglypshapes = showglyphshape + function moduledata.fonts.shapes.showlastglyphshapefield(unicode,name) if not descriptions then -- bad news diff --git a/tex/context/modules/mkiv/s-fonts-shapes.mkiv b/tex/context/modules/mkiv/s-fonts-shapes.mkiv index 53ed1b426..90b9c1f64 100644 --- a/tex/context/modules/mkiv/s-fonts-shapes.mkiv +++ b/tex/context/modules/mkiv/s-fonts-shapes.mkiv @@ -30,7 +30,7 @@ \startsetups module:showallglyphshapes:start \unexpanded\def\modulefontsstartshowglyphshape##1##2##3{ - \startTEXpage[\c!offset=\exheight] + \startTEXpage[\c!offset=\exheight] % ,\c!frame=\v!on] \edef\lastshownglyphshapefieldunicode{##1}% \edef\lastshownglyphshapefieldname {##2}% \edef\lastshownglyphshapefieldindex {##3}% @@ -58,6 +58,15 @@ \stopsetups +\startsetups module:showallglyphshapes:stop + + % nothing + +\stopsetups + +\unexpanded\def\modulefontsstartshowglyphshapes{\setups[module:showallglyphshapes:start]} +\unexpanded\def\modulefontsstopshowglyphshapes {\setups[module:showallglyphshapes:stop]} + \protect % downward compatibility: @@ -97,6 +106,9 @@ % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{0xF0299} \stopTEXpage % \startTEXpage \ShowGlyphShape{simplenaskhi}{100bp}{NameMe.1190} \stopTEXpage + \startTEXpage[offset=0pt]\ShowGlyphShape{file:stix2math.otf}{20bp}{0x1D44A}\stopTEXpage + \startTEXpage[offset=0pt]\ShowGlyphShape{file:stix2math.otf}{20bp}{0x1D44C}\stopTEXpage + % \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x00066}\stopTEXpage % \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x1D453}\stopTEXpage % \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{20bp}{0x1D43F}\stopTEXpage @@ -109,10 +121,13 @@ % \startTEXpage[offset=0pt]\ShowGlyphShape{name:cambria-math}{50bp}{0x1D45D}\stopTEXpage % \page -\startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0xF034A}\stopTEXpage -\startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0x006DD}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0xF034A}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0x006DD}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{file:husayninotebold.ttf}{50bp}{0x006DD}\stopTEXpage +% \startTEXpage[offset=0pt]\ShowGlyphShape{file:arabtype.ttf}{50bp}{0x0FCA1}\stopTEXpage % \showallglyphshapes[name=name:cambria-math,size=100bp] +% \showallglyphshapes[name=name:arabtype,size=100bp] % \showallglyphshapes[name=file:husayninotebold.ttf,size=100bp] % \showallglyphshapes[name=name:dejavuserif,size=100bp] diff --git a/tex/context/modules/mkiv/s-fonts-statistics.mkiv b/tex/context/modules/mkiv/s-fonts-statistics.mkiv new file mode 100644 index 000000000..3b5cddd3c --- /dev/null +++ b/tex/context/modules/mkiv/s-fonts-statistics.mkiv @@ -0,0 +1,80 @@ +%D \module +%D [ file=s-fonts-statistics, +%D version=2018.03.21, % guess +%D title=\CONTEXT\ Style File, +%D subtitle=Listing font statistics, +%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. + +\startmodule[fonts-statistics] + +\startluacode + +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.statistics = moduledata.fonts.statistics or { } + +local context = context +local ctx_NC, ctx_BC, ctx_NR = context.NC, context.BC, context.NR + +function moduledata.fonts.statistics.showusage() + local t = table.load(tex.jobname.."-fonts-usage.lua") + if t then + local totalinstances = 0 + local totalfilesize = 0 + local totalfilenames = #t + if totalfilenames > 0 then + context.starttabulate { "|r|r|c||" } + context.FL() + ctx_BC() context("used") + ctx_BC() context("filesize") + ctx_BC() context("version") + ctx_BC() context("filename") + ctx_NR() + context.ML() + for i=1,#t do + local ti = t[i] + local version = tonumber(string.match(ti.version or "","^.-([%d%.]+)")) + local instances = ti.instances or 1 + local filename = file.basename(ti.filename) or "unknown" + local filesize = ti.size or 0 + totalinstances = totalinstances + instances + totalfilesize = totalfilesize + filesize + ctx_NC() context(instances) + ctx_NC() context("%0m",filesize) + ctx_NC() if version then context("%0.3f",version) end + ctx_NC() context.type(filename) + ctx_NR() + end + context.LL() + ctx_BC() context(totalinstances) + ctx_BC() context("%0m",totalfilesize) + ctx_BC() context() + ctx_BC() context("%i files loaded",totalfilenames) + ctx_NR() + context.stoptabulate() + end + end +end + +\stopluacode + +\installmodulecommandluasingle \showfontusage {moduledata.fonts.statistics.showusage} + +\stopmodule + +\continueifinputfile{s-fonts-statistics.mkiv} + +\enabletrackers[fonts.usage] + +\starttext + + \input klein + + \showfontusage + +\stoptext diff --git a/tex/context/modules/mkiv/s-fonts-system.lua b/tex/context/modules/mkiv/s-fonts-system.lua index 5b58a4a53..dc0f2e6a3 100644 --- a/tex/context/modules/mkiv/s-fonts-system.lua +++ b/tex/context/modules/mkiv/s-fonts-system.lua @@ -30,14 +30,19 @@ if not modules then modules = { } end modules ['s-fonts-system'] = { moduledata.fonts = moduledata.fonts or { } moduledata.fonts.system = moduledata.fonts.system or { } -local lower = string.lower - local context = context local NC, NR, HL = context.NC, context.NR, context.HL -local bold = context.bold +local ctx_bold = context.bold +local ctx_verbatim = context.verbatim +local lpegmatch = lpeg.match +local sortedhash = table.sortedhash +local formatters = string.formatters +local concat = table.concat +local lower = string.lower +local gsub = string.gsub +local find = string.find -function moduledata.fonts.system.showinstalled(specification) - specification = interfaces.checkedspecification(specification) +local function allfiles(specification) local pattern = lower(specification.pattern or "") local list = fonts.names.list(pattern,false,true) if list then @@ -45,14 +50,22 @@ function moduledata.fonts.system.showinstalled(specification) for k, v in next, list do files[file.basename(string.lower(v.filename))] = v end + return files + end +end + +function moduledata.fonts.system.showinstalled(specification) + specification = interfaces.checkedspecification(specification) + local files = allfiles(specification) + if files then context.starttabulate { "|Tl|Tl|Tl|Tl|Tl|Tl|" } HL() - NC() bold("filename") - NC() bold("fontname") - NC() bold("subfamily") - NC() bold("variant") - NC() bold("weight") - NC() bold("width") + NC() ctx_bold("filename") + NC() ctx_bold("fontname") + NC() ctx_bold("subfamily") + NC() ctx_bold("variant") + NC() ctx_bold("weight") + NC() ctx_bold("width") NC() NR() HL() for filename, data in table.sortedpairs(files) do @@ -67,3 +80,242 @@ function moduledata.fonts.system.showinstalled(specification) context.stoptabulate() end end + +function moduledata.fonts.system.cacheinstalled(specification) + specification = interfaces.checkedspecification(specification) + local files = allfiles(specification) + if files then + local threshold = tonumber(specification.threshold) + local suffixes = specification.suffixes + if suffixes then + suffixes = utilities.parsers.settings_to_set(suffixes) + else + suffixes = { otf = true, ttf = true } + end + for filename, data in table.sortedpairs(files) do + if string.find(filename," ") then + -- skip this one + elseif suffixes[file.suffix(filename)] then + local fullname = resolvers.findfile(filename) + context.start() + context.type(fullname) + context.par() + if threshold and file.size(fullname) > threshold then + logs.report("fonts","ignoring : %s",fullname) + else + logs.report("fonts","caching : %s",fullname) + context.definedfont { filename } + end + context.stop() + end + end + end +end + +local splitter = lpeg.splitat(lpeg.S("._"),true) + +local method = 4 + +function moduledata.fonts.system.showinstalledglyphnames(specification) + specification = interfaces.checkedspecification(specification) + local paths = caches.getreadablepaths() + local files = { } + local names = table.setmetatableindex("table") + local f_u = formatters["%04X"] + for i=1,#paths do + local list = dir.glob(paths[i].."/fonts/o*/**.tmc") + for i=1,#list do + files[list[i]] = true + end + end + for filename in table.sortedhash(files) do + local fontname = file.nameonly(filename) + logs.report("system","fontfile: %s",fontname) + local data = table.load(filename) + if data then + if method == 1 then + local unicodes = data.resources.unicodes + if unicodes then + for n, u in sortedhash(unicodes) do + if u >= 0xF0000 or (u >= 0xE000 and u <= 0xF8FF) then + -- skip + else + local f = lpegmatch(splitter,n) or n + if #f > 0 then + local t = names[f] + t[u] = (t[u] or 0) + 1 + end + end + end + end + elseif method == 2 then + local unicodes = data.resources.unicodes + if unicodes then + for n, u in sortedhash(unicodes) do + if u >= 0xF0000 or (u >= 0xE000 and u <= 0xF8FF) then + -- skip + else + local t = names[n] + t[u] = (t[u] or 0) + 1 + end + end + end + elseif method == 3 then + local descriptions = data.descriptions + if descriptions then + for u, d in sortedhash(descriptions) do + local n = d.name + local u = d.unicode + if n and u then + if type(u) == "table" then + local t = { } + for i=1,#u do + t[i] = f_u(u[i]) + end + u = concat(t," ") + end + local t = names[n] + t[u] = (t[u] or 0) + 1 + end + end + end + elseif method == 4 then + local descriptions = data.descriptions + if descriptions then + for u, d in sortedhash(descriptions) do + local n = d.name + local u = d.unicode + if n and not u and not find(n,"^%.") then + local n = names[n] + n[#n+1] = fontname + end + end + end + else + -- nothing + end + end + end + -- names[".notdef"] = nil + -- names[".null"] = nil + if method == 4 then + if next(names) then + context.starttabulate { "|l|pl|" } + local f_u = formatters["%04X~(%i)"] + local f_s = formatters["%s~(%i)"] + for k, v in sortedhash(names) do + NC() ctx_verbatim(k) + NC() context("% t",v) + NC() NR() + end + context.stoptabulate() + end + table.save("s-fonts-system-glyph-unknowns.lua",names) + else + if next(names) then + context.starttabulate { "|l|pl|" } + local f_u = formatters["%04X~(%i)"] + local f_s = formatters["%s~(%i)"] + for k, v in sortedhash(names) do + local t = { } + for k, v in sortedhash(v) do + if type(k) == "string" then + t[#t+1] = f_s(k,v) + else + t[#t+1] = f_u(k,v) + end + end + NC() ctx_verbatim(k) + NC() context("%, t",t) + NC() NR() + end + context.stoptabulate() + end + table.save("s-fonts-system-glyph-names.lua",names) + end +end + +-- -- -- + +-- local skip = { +-- "adobeblank", +-- "veramo", +-- "unitedstates", +-- "tirek", +-- "svbasicmanual", +-- "sahel", +-- "prsprorg", +-- "piratdia", +-- "notoserifthai", +-- "coelacanthsubhdheavy", +-- } + +-- local function bad(name) +-- name = lower(name) +-- for i=1,#skip do +-- if find(name,skip[i]) then +-- return true +-- end +-- end +-- end + +-- function moduledata.fonts.system.showprivateglyphnames(specification) +-- specification = interfaces.checkedspecification(specification) +-- local paths = caches.getreadablepaths() +-- local files = { } +-- local names = table.setmetatableindex("table") +-- local f_u = formatters["%04X"] +-- for i=1,#paths do +-- local list = dir.glob(paths[i].."/fonts/o*/**.tmc") +-- for i=1,#list do +-- files[list[i]] = true +-- end +-- end +-- for filename in table.sortedhash(files) do +-- logs.report("system","fontfile: %s",file.nameonly(filename)) +-- local data = table.load(filename) +-- if data and data.format == "truetype" or data.format == "opentype" then +-- local basename = file.basename(data.resources.filename) +-- local cleanname = gsub(basename," ","") +-- if not bad(cleanname) then +-- local descriptions = data.descriptions +-- if descriptions then +-- local done = 0 +-- for u, d in sortedhash(descriptions) do +-- local dn = d.name +-- local du = d.unicode +-- if dn and du and (u >= 0xF0000 or (u >= 0xE000 and u <= 0xF8FF)) and not find(dn,"notdef") then +-- if type(du) == "table" then +-- local t = { } +-- for i=1,#du do +-- t[i] = f_u(du[i]) +-- end +-- du = concat(t," ") +-- end +-- if done == 0 then +-- logs.report("system","basename: %s",basename) +-- context.starttitle { title = basename } +-- context.start() +-- context.definefont( { "tempfont" }, { "file:" .. cleanname }) +-- context.starttabulate { "|T||T|T|" } +-- end +-- NC() context("%U",u) +-- NC() context.tempfont() context.char(u) -- could be getglyph +-- NC() ctx_verbatim(dn) +-- NC() context(du) +-- NC() NR() +-- done = done + 1 +-- end +-- end +-- if done > 0 then +-- logs.report("system","privates: %i",done) +-- context.stoptabulate() +-- context.stop() +-- context.stoptitle() +-- end +-- end +-- end +-- end +-- end +-- end + diff --git a/tex/context/modules/mkiv/s-fonts-system.mkiv b/tex/context/modules/mkiv/s-fonts-system.mkiv index 6d9082a6b..9a0f7485d 100644 --- a/tex/context/modules/mkiv/s-fonts-system.mkiv +++ b/tex/context/modules/mkiv/s-fonts-system.mkiv @@ -24,16 +24,27 @@ \registerctxluafile{s-fonts-system}{} -\installmodulecommandluasingle \showinstalledfonts {moduledata.fonts.system.showinstalled} +\installmodulecommandluasingle \showinstalledfonts {moduledata.fonts.system.showinstalled} +\installmodulecommandluasingle \cacheinstalledfonts {moduledata.fonts.system.cacheinstalled} +\installmodulecommandluasingle \showinstalledglyphnames {moduledata.fonts.system.showinstalledglyphnames} +%installmodulecommandluasingle \showprivateglyphnames {moduledata.fonts.system.showprivateglyphnames} \stopmodule \continueifinputfile{s-fonts-system.mkiv} -\usemodule[art-01] \setuplayout[overview] \setupbodyfont[7pt] +\usemodule[art-01] \setuplayout[overview] \setupbodyfont[6pt] \starttext - \showinstalledfonts +% \showinstalledfonts + +% \enabletrackers[otf.keepnames] + +% \cacheinstalledfonts[suffixes={otf,ttf,afm}] +% \cacheinstalledfonts[threshold=4000000,suffixes={otf,ttf,afm}] +% \cacheinstalledfonts[threshold=2000000,suffixes={otf,ttf,afm}] + + \showinstalledglyphnames \stoptext diff --git a/tex/context/modules/mkiv/s-fonts-tables.lua b/tex/context/modules/mkiv/s-fonts-tables.lua index c32f4628c..33cbc924c 100644 --- a/tex/context/modules/mkiv/s-fonts-tables.lua +++ b/tex/context/modules/mkiv/s-fonts-tables.lua @@ -6,18 +6,45 @@ if not modules then modules = { } end modules ['s-fonts-tables'] = { license = "see context related readme files" } -moduledata.fonts = moduledata.fonts or { } -moduledata.fonts.tables = moduledata.fonts.tables or { } - -local setmetatableindex = table.setmetatableindex -local sortedhash = table.sortedhash -local sortedkeys = table.sortedkeys -local format = string.format -local concat = table.concat - -local tabletracers = moduledata.fonts.tables - -local context = context +moduledata.fonts = moduledata.fonts or { } +moduledata.fonts.tables = moduledata.fonts.tables or { } + +local setmetatableindex = table.setmetatableindex +local sortedhash = table.sortedhash +local sortedkeys = table.sortedkeys +local concat = table.concat +local insert = table.insert +local remove = table.remove +local formatters = string.formatters + +local tabletracers = moduledata.fonts.tables + +local new_glyph = nodes.pool.glyph +local copy_node = nodes.copy +local setlink = nodes.setlink +local hpack = nodes.hpack +local applyvisuals = nodes.applyvisuals + +local handle_positions = fonts.handlers.otf.datasetpositionprocessor +local handle_injections = nodes.injections.handler + +local context = context +local ctx_sequence = context.formatted.sequence +local ctx_char = context.char +local ctx_setfontid = context.setfontid +local ctx_type = context.formatted.type +local ctx_dontleavehmode = context.dontleavehmode +local ctx_startPair = context.startPair +local ctx_stopPair = context.stopPair +local ctx_startSingle = context.startSingle +local ctx_stopSingle = context.stopSingle +local ctx_startSingleKern = context.startSingleKern +local ctx_stopSingleKern = context.stopSingleKern +local ctx_startPairKern = context.startPairKern +local ctx_stopPairKern = context.stopPairKern + +local ctx_NC = context.NC +local ctx_NR = context.NR local digits = { dflt = { @@ -106,53 +133,73 @@ setmetatableindex(digits.dflt, function(t,k) return rawget(t,"dflt") end) setmetatableindex(symbols.dflt, function(t,k) return rawget(t,"dflt") end) setmetatableindex(punctuation.dflt, function(t,k) return rawget(t,"dflt") end) -local function typesettable(t,keys,synonyms,nesting,prefix) - if t then +-- scaled boolean string scale string float cardinal + +local function checked(specification) + specification = interfaces.checkedspecification(specification) + local id, cs = fonts.definers.internal(specification,"") + local tfmdata = fonts.hashes.identifiers[id] + local resources = tfmdata.resources + return tfmdata, id, resources +end + +local function nothing() + context("no entries") + context.par() +end + +local function typesettable(t,keys,synonyms,nesting,prefix,depth) + if t and next(keys) then if not prefix then context.starttabulate { "|Tl|Tl|Tl|" } end for k, v in sortedhash(keys) do if k == "synonyms" then elseif type(v) ~= "table" then - context.NC() + ctx_NC() if prefix then context("%s.%s",prefix,k) else context(k) end - context.NC() + ctx_NC() + -- print(v) local tk = t[k] - if v == "boolean" then + if v == "" then context(tostring(tk or false)) elseif not tk then context("") - elseif v == "filename" then + elseif k == "filename" then context(file.basename(tk)) - elseif v == "basepoints" then - context("%sbp",tk) - elseif v == "scaledpoints" then + -- elseif v == "basepoints" then + -- context("%sbp",tk) + elseif v == "" then context("%p",tk) - elseif v == "table" then + elseif v == "" then context("
") - else -- if v == "integerscale" then + else context(tostring(tk)) end - context.NC() - local synonym = (not prefix and synonyms[k]) or (prefix and synonyms[format("%s.%s",prefix,k)]) + ctx_NC() + local synonym = (not prefix and synonyms[k]) or (prefix and synonyms[formatters["%s.%s"](prefix,k)]) if synonym then - context(format("(%s)",concat(synonym," "))) + context("(% t)",synonym) end - context.NC() - context.NR() + ctx_NC() + ctx_NR() elseif nesting == false then context("
") - else -- true or nil - typesettable(t[k],v,synonyms,nesting,k) + elseif next(v) then + typesettable(t[k],v,synonyms,nesting,k,true) end end if not prefix then context.stoptabulate() end + return + end + if not depth then + nothing() end end @@ -175,51 +222,342 @@ end tabletracers.typeset = typeset -function tabletracers.showproperties(nesting) - local tfmdata = fonts.hashes.identifiers[font.current()] - typeset(tfmdata.properties,fonts.constructors.keys.properties,nesting) +-- function tabletracers.showproperties(nesting) +-- local tfmdata = fonts.hashes.identifiers[true] +-- typeset(tfmdata.properties,fonts.constructors.keys.properties,nesting) +-- end + +-- function tabletracers.showparameters(nesting) +-- local tfmdata = fonts.hashes.identifiers[true] +-- typeset(tfmdata.parameters,fonts.constructors.keys.parameters,nesting) +-- end + +function tabletracers.showproperties(specification) + local tfmdata = checked(specification) + if tfmdata then + typeset(tfmdata.properties,fonts.constructors.keys.properties) + else + nothing() + end +end + +function tabletracers.showparameters(specification) + local tfmdata = checked(specification) + if tfmdata then + typeset(tfmdata.parameters,fonts.constructors.keys.parameters) + else + nothing() + end end -function tabletracers.showparameters(nesting) - local tfmdata = fonts.hashes.identifiers[font.current()] - typeset(tfmdata.parameters,fonts.constructors.keys.parameters,nesting) +local f_u = formatters["%U"] +local f_p = formatters["%p"] + +local function morept(t) + local r = { } + for i=1,t do + r[i] = f_p(t[i]) + end + return concat(r," ") end -function tabletracers.showpositionings() - local tfmdata = fonts.hashes.resources[font.current()] - local resources = tfmdata.resources +local function noprefix(kind) + kind = string.gsub(kind,"^gpos_","") + kind = string.gsub(kind,"^gsub_","") + return kind +end + +local function banner(index,i,format,kind,order,chain) + if chain then + ctx_sequence("sequence: %i, step %i, format: %s, kind: %s, features: % t, chain: %s", + index,i,format,noprefix(kind),order,noprefix(chain)) + else + ctx_sequence("sequence: %i, step %i, format: %s, kind: %s, features: % t", + index,i,format,noprefix(kind),order) + end +end + +function tabletracers.showpositionings(specification) + + local tfmdata, fontid, resources = checked(specification) + if resources then - local features = resources.features - if features then - local gpos = features.gpos - if gpos and next(gpos) then - context.starttabulate { "|Tl|Tl|Tlp|" } - for feature, scripts in sortedhash(gpos) do - for script, languages in sortedhash(scripts) do - context.NC() - context(feature) - context.NC() - context(script) - context.NC() - context(concat(sortedkeys(languages)," ")) - context.NC() - context.NR() + + local direction = "TLT" + + local sequences = resources.sequences + local marks = resources.marks + + if tonumber(direction) == -1 or direction == "TRT" then + direction = "TRT" + else + direction = "TLT" + end + + local visuals = "fontkern,glyph,box" + + local datasets = fonts.handlers.otf.dataset(tfmdata,fontid,0) + + local function process(dataset,sequence,kind,order,chain) + local steps = sequence.steps + local order = sequence.order or order + local index = sequence.index + for i=1,#steps do + local step = steps[i] + local format = step.format + banner(index,i,format,kind,order,chain) + if kind == "gpos_pair" then + local format = step.format + if "kern" or format == "move" then + for first, seconds in sortedhash(step.coverage) do + local done = false + local zero = 0 + for second, kern in sortedhash(seconds) do + if kern == 0 then + zero = zero + 1 + else + if not done then + ctx_startPairKern() + end + local one = new_glyph(fontid,first) + local two = new_glyph(fontid,second) + local raw = setlink(copy_node(one),copy_node(two)) + local pos = setlink(done and one or copy_node(one),copy_node(two)) + pos, okay = handle_positions(pos,fontid,direction,dataset) + pos = handle_injections(pos) + applyvisuals(raw,visuals) + applyvisuals(pos,visuals) + pos = hpack(pos,"exact",nil,direction) + raw = hpack(raw,"exact",nil,direction) + ctx_NC() if not done then context(f_u(first)) end + ctx_NC() if not done then ctx_dontleavehmode() context(one) end + ctx_NC() context(f_u(second)) + ctx_NC() ctx_dontleavehmode() context(two) + ctx_NC() context("%p",kern) + ctx_NC() ctx_dontleavehmode() context(raw) + ctx_NC() ctx_dontleavehmode() context(pos) + ctx_NC() ctx_NR() + done = true + end + end + if done then + ctx_stopPairKern() + end + if zero > 0 then + ctx_type("zero: %s",zero) + end + end + elseif format == "pair" then + for first, seconds in sortedhash(step.coverage) do + local done = false + local allnull = 0 + local allzero = 0 + local zeronull = 0 + local nullzero = 0 + for second, pair in sortedhash(seconds) do + local pfirst = pair[1] + local psecond = pair[2] + if not pfirst and not psecond then + allnull = allnull + 1 + elseif pfirst == true and psecond == true then + allzero = allzero + 1 + elseif pfirst == true and not psecond then + zeronull = zeronull + 1 + elseif not pfirst and psecond == true then + nullzero = nullzero + 1 + else + if pfirst == true then + pfirst = "all zero" + elseif pfirst then + pfirst = morept(pfirst) + else + pfirst = "no first" + end + if psecond == true then + psecond = "all zero" + elseif psecond then + psecond = morept(psecond) + else + psecond = "no second" + end + if not done then + ctx_startPair() + end + local one = new_glyph(fontid,first) + local two = new_glyph(fontid,second) + local raw = setlink(copy_node(one),copy_node(two)) + local pos = setlink(done and one or copy_node(one),copy_node(two)) + pos, okay = handle_positions(pos,fontid,direction,dataset) + pos = handle_injections(pos) + applyvisuals(raw,visuals) + applyvisuals(pos,visuals) + pos = hpack(pos,"exact",nil,direction) + raw = hpack(raw,"exact",nil,direction) + ctx_NC() if not done then context(f_u(first)) end + ctx_NC() if not done then ctx_dontleavehmode() context(one) end + ctx_NC() context(f_u(second)) + ctx_NC() ctx_dontleavehmode() context(two) + ctx_NC() context(pfirst) + ctx_NC() context(psecond) + ctx_NC() ctx_dontleavehmode() context(raw) + ctx_NC() ctx_dontleavehmode() context(pos) + ctx_NC() ctx_NR() + done = true + end + end + if done then + ctx_stopPair() + end + if allnull > 0 or allzero > 0 or zeronull > 0 or nullzero > 0 then + ctx_type("both null: %s, both zero: %s, zero and null: %s, null and zero: %s", + allnull,allzero,zeronull,nullzero) + end + end + else + -- maybe + end + elseif kind == "gpos_single" then + local format = step.format + if format == "kern" or format == "move" then + local done = false + local zero = 0 + for first, kern in sortedhash(step.coverage) do + if kern == 0 then + zero = zero + 1 + else + if not done then + ctx_startSingleKern() + end + local one = new_glyph(fontid,first) + local raw = copy_node(one) + local pos = copy_node(one) + pos, okay = handle_positions(pos,fontid,direction,dataset) + pos = handle_injections(pos) + applyvisuals(raw,visuals) + applyvisuals(pos,visuals) + pos = hpack(pos,"exact",nil,direction) + raw = hpack(raw,"exact",nil,direction) + ctx_NC() context(f_u(first)) + ctx_NC() ctx_dontleavehmode() context(one) + ctx_NC() context("%p",kern) + ctx_NC() ctx_dontleavehmode() context(raw) + ctx_NC() ctx_dontleavehmode() context(pos) + ctx_NC() ctx_NR() + done = true + end + end + if done then + ctx_stopSingleKern() + end + if zero > 0 then + ctx_type("zero: %i",zero) + end + elseif format == "single" then + local done = false + local zero = 0 + local null = 0 + for first, single in sortedhash(step.coverage) do + if single == false then + null = null + 1 + elseif single == true then + zero = zero + 1 + else + single = morept(single) + if not done then + ctx_startSingle() + end + local one = new_glyph(fontid,first) + local raw = copy_node(one) + local pos = copy_node(one) + pos, okay = handle_positions(pos,fontid,direction,dataset) + pos = handle_injections(pos) + applyvisuals(raw,visuals) + applyvisuals(pos,visuals) + raw = hpack(raw,"exact",nil,direction) + pos = hpack(pos,"exact",nil,direction) + ctx_NC() context(f_u(first)) + ctx_NC() ctx_dontleavehmode() context(one) + ctx_NC() context(single) + ctx_NC() ctx_dontleavehmode() context(raw) + ctx_NC() ctx_dontleavehmode() context(pos) + ctx_NC() ctx_NR() + done = true + end + end + if done then + ctx_stopSingle() + end + if null > 0 then + if zero > 0 then + ctx_type("null: %i, zero: %i",null,zero) + else + ctx_type("null: %i",null) + end + else + if null > 0 then + ctx_type("both zero: %i",zero) + end + end + else + -- todo end end - context.stoptabulate() - else - context("no entries") - context.par() end end + + local done = false + + for d=1,#datasets do + local dataset = datasets[d] + local sequence = dataset[3] + local kind = sequence.type + if kind == "gpos_contextchain" or kind == "gpos_context" then + local steps = sequence.steps + for i=1,#steps do + local step = steps[i] + local rules = step.rules + if rules then + for i=1,#rules do + local rule = rules[i] + local lookups = rule.lookups + if lookups then + for i=1,#lookups do + local lookup = lookups[i] + if lookup then + local look = lookup[1] + local dnik = look.type + if dnik == "gpos_pair" or dnik == "gpos_single" then + process(dataset,look,dnik,sequence.order,kind) + end + end + end + end + end + end + end + done = true + elseif kind == "gpos_pair" or kind == "gpos_single" then + process(dataset,sequence,kind) + done = true + end + end + + if done then + return + end + end + + nothing() + end local dynamics = true -function tabletracers.showsubstitutions() - local tfmdata = fonts.hashes.identifiers[font.current()] - local resources = tfmdata.resources +function tabletracers.showsubstitutions(specification) + + local tfmdata, fontid, resources = checked(specification) + if resources then local features = resources.features if features then @@ -229,8 +567,8 @@ function tabletracers.showsubstitutions() for feature, scripts in sortedhash(gsub) do for script, languages in sortedhash(scripts) do for language in sortedhash(languages) do - local tag = format("dummy-%s-%s-%s",feature,script,language) - local fnt = format("file:%s*%s",file.basename(tfmdata.properties.filename),tag) + local tag = formatters["dummy-%s-%s-%s"](feature,script,language) + local fnt = formatters["file:%s*%s"](file.basename(tfmdata.properties.filename),tag) context.definefontfeature ( { tag }, { @@ -259,13 +597,13 @@ function tabletracers.showsubstitutions() local data = makes_sense[i] local script = data.script local language = data.language - context.NC() + ctx_NC() context(data.feature) - context.NC() + ctx_NC() context(script) - context.NC() + ctx_NC() context(language) - context.NC() + ctx_NC() if not dynamics then context.startfont { data.fontname } else @@ -279,85 +617,160 @@ function tabletracers.showsubstitutions() if not dynamics then context.stopfont() end - context.NC() - context.NR() + ctx_NC() + ctx_NR() end context.stoptabulate() - else - context("no entries") - context.par() + return end end end end + + nothing() + end -function tabletracers.showunicodevariants() +function tabletracers.showunicodevariants(specification) + + local tfmdata, fontid, resources = checked(specification) - local variants = fonts.hashes.variants[true] + if resources then - if variants then - context.starttabulate { "|c|c|c|c|c|c|c|" } - for selector, unicodes in sortedhash(variants) do - local done = false - for unicode, variant in sortedhash(unicodes) do - context.NC() - if not done then - context("%U",selector) - done = true + local variants = fonts.hashes.variants[fontid] + + if variants then + context.starttabulate { "|c|c|c|c|c|c|c|" } + for selector, unicodes in sortedhash(variants) do + local done = false + for unicode, variant in sortedhash(unicodes) do + ctx_NC() + if not done then + context("%U",selector) + done = true + end + ctx_NC() + context("%U",unicode) + ctx_NC() + context("%c",unicode) + ctx_NC() + context("%U",variant) + ctx_NC() + context("%c",variant) + ctx_NC() + context("%c%c",unicode,selector) + ctx_NC() + context.startoverlay() + context("{\\color[trace:r]{%c}}{\\color[trace:ds]{%c}}",unicode,variant) + context.stopoverlay() + ctx_NC() + ctx_NR() end - context.NC() - context("%U",unicode) - context.NC() - context("%c",unicode) - context.NC() - context("%U",variant) - context.NC() - context("%c",variant) - context.NC() - context("%c%c",unicode,selector) - context.NC() - context.startoverlay() - context("{\\color[trace:r]{%c}}{\\color[trace:ds]{%c}}",unicode,variant) - context.stopoverlay() - context.NC() - context.NR() end + context.stoptabulate() + return end - context.stoptabulate() + end + nothing() + end -function tabletracers.showall(specification) -- not interfaced - specification = interfaces.checkedspecification(specification) - if specification.title then - context.starttitle { title = specification.title } +local function collectligatures(steps) + + local series = { } + local stack = { } + local max = 0 + + local function make(tree) + for k, v in sortedhash(tree) do + if k == "ligature" then + local n = #stack + if n > max then + max = n + end + series[#series+1] = { v, unpack(stack) } + else + insert(stack,k) + make(v) + remove(stack) + end + end end - context.startsubject { title = "Properties" } - tabletracers.showproperties() - context.stopsubject() + for i=1,#steps do + local step = steps[i] + local coverage = step.coverage + if coverage then + make(coverage) + end + end - context.startsubject { title = "Parameters" } - tabletracers.showparameters() - context.stopsubject() + return series, max +end - context.startsubject { title = "Positioning features" } - tabletracers.showpositionings() - context.stopsubject() +local function banner(index,kind,order) + ctx_sequence("sequence: %i, kind: %s, features: % t",index,noprefix(kind),order) +end + +function tabletracers.showligatures(specification) - context.startsubject { title = "Substitution features" } - tabletracers.showsubstitutions() - context.stopsubject() + local tfmdata, fontid, resources = checked(specification) - context.startsubject { title = "Unicode variants" } - tabletracers.showunicodevariants() - context.stopsubject() + if resources then - if title then - context.stoptitle() + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local sequences = resources.sequences + if sequences then + local done = true + for index=1,#sequences do + local sequence = sequences[index] + local kind = sequence.type + if kind == "gsub_ligature" then + local list, max = collectligatures(sequence.steps) + if #list > 0 then + banner(index,kind,sequence.order or { }) + context.starttabulate { "|T|" .. string.rep("|",max) .. "|T|T|" } + for i=1,#list do + local s = list[i] + local n = #s + local u = s[1] + local c = characters[u] + local d = descriptions[u] + ctx_NC() + context("%U",u) + ctx_NC() + ctx_setfontid(fontid) + ctx_char(u) + ctx_NC() + ctx_setfontid(fontid) + for i=2,n do + ctx_char(s[i]) + ctx_NC() + end + for i=n+1,max do + ctx_NC() + end + context(d.name) + ctx_NC() + context(c.tounicode) + ctx_NC() + ctx_NR() + end + context.stoptabulate() + done = true + end + end + end + if done then + return + end + end end + nothing() + end diff --git a/tex/context/modules/mkiv/s-fonts-tables.mkiv b/tex/context/modules/mkiv/s-fonts-tables.mkiv index 64fe76f0e..f1340c3ea 100644 --- a/tex/context/modules/mkiv/s-fonts-tables.mkiv +++ b/tex/context/modules/mkiv/s-fonts-tables.mkiv @@ -17,10 +17,28 @@ \registerctxluafile{s-fonts-tables}{} -\installmodulecommandluasingle \showfonttables {moduledata.fonts.tables.showall} +\definetabulate[Pair] [|T|cw(3em)|T|cw(3em)|Tw(10em)|Tw(10em)|cw(4em)|cw(4em)|] +\definetabulate[Single] [|T|cw(3em)|Tw(10em)|cw(4em)|cw(4em)|] +\definetabulate[SingleKern][|T|cw(3em)|Trw(5em)|cw(4em)|cw(4em)|] +\definetabulate[PairKern] [|T|cw(3em)|T|cw(3em)|Trw(5em)|cw(4em)|cw(4em)|] + +\definehead + [sequence] + [subsubject] + [style=\ttbf] + +\definecolor + [bbcolor] + [t=.5,a=1,s=.5] + +\definefontfeature + [boundingbox] + [boundingbox={background,bbcolor}] + \installmodulecommandluasingle \showfontproperties {moduledata.fonts.tables.showproperties} \installmodulecommandluasingle \showfontparameters {moduledata.fonts.tables.showparameters} \installmodulecommandluasingle \showfontpositionings {moduledata.fonts.tables.showpositionings} +\installmodulecommandluasingle \showfontligatures {moduledata.fonts.tables.showligatures} \installmodulecommandluasingle \showfontsubstitutions {moduledata.fonts.tables.showsubstitutions} \installmodulecommandluasingle \showfontunicodevariants{moduledata.fonts.tables.showunicodevariants} @@ -34,5 +52,5 @@ [cambria] \starttext - \showfonttables[title=Cambria] + \showfontproperties[name=cambria] \stoptext diff --git a/tex/context/modules/mkiv/s-fonts-variable.mkiv b/tex/context/modules/mkiv/s-fonts-variable.mkiv index d1bf8b69d..2cd612c75 100644 --- a/tex/context/modules/mkiv/s-fonts-variable.mkiv +++ b/tex/context/modules/mkiv/s-fonts-variable.mkiv @@ -72,28 +72,28 @@ \char983040\relax\par \stopbuffer - \showfontvariations - [font=file:adobevfprototype.otf] +% \showfontvariations +% [font=file:adobevfprototype.otf] - \showfontvariations - [font=file:avenirnextvariable.ttf] +% \showfontvariations +% [font=file:avenirnextvariable.ttf] - \showfontvariations - [font=file:DecoVar-VF.ttf] +% \showfontvariations +% [font=file:DecoVar-VF.ttf] % \showfontvariations % [font=file:VotoSerifGX.ttf, % max=15] - \showfontvariations - [font=file:Selawik-Variable.ttf] +% \showfontvariations +% [font=file:Selawik-Variable.ttf] - \showfontvariations - [font=file:LibreFranklinGX-Romans.ttf] +% \showfontvariations +% [font=file:LibreFranklinGX-Romans.ttf] - \showfontvariations - [font=file:Zycon.ttf, - sample={\getbuffer[zycon]}] + % \showfontvariations + % [font=file:Zycon.ttf, + % sample={\getbuffer[zycon]}] % \showfontvariations % [font=file:kairossansvariable.ttf] @@ -104,8 +104,8 @@ % \showfontvariations % [font=file:AmstelvarAlpha-VF.ttf] - \showfontvariations - [font=file:bahnschrift.ttf] + % \showfontvariations + % [font=file:bahnschrift.ttf] % \showfontvariations % [font=file:sitka.ttc] diff --git a/tex/context/modules/mkiv/s-languages-hyphenation.lua b/tex/context/modules/mkiv/s-languages-hyphenation.lua index 6d3cf3d3e..65fd1ab14 100644 --- a/tex/context/modules/mkiv/s-languages-hyphenation.lua +++ b/tex/context/modules/mkiv/s-languages-hyphenation.lua @@ -29,7 +29,8 @@ local newrule = nodepool.rule local newglue = nodepool.glue local insert_node_after = nuts.insert_after -local traverse_by_id = nuts.traverse_id + +local nextglyph = nuts.traversers.glyph local tonut = nodes.tonut local tonode = nodes.tonode @@ -129,7 +130,7 @@ end local function getlanguage(head,l,left,right) local t = { } - for n in traverse_by_id(glyph_code,tonut(head)) do + for n in nextglyph, tonut(head) do t[n] = { getlang(n), getfield(n,"left"), @@ -148,7 +149,7 @@ function moduledata.languages.hyphenation.showhyphens(head) local marked = { } local cached = { } -- somehow assigning -1 fails - for n in traverse_by_id(glyph_code,tonut(head)) do + for n in nextglyph, tonut(head) do cached[n] = { getlang(n), getfield(n,"left"), diff --git a/tex/context/modules/mkiv/s-languages-system.lua b/tex/context/modules/mkiv/s-languages-system.lua index 3b422db9f..d18050577 100644 --- a/tex/context/modules/mkiv/s-languages-system.lua +++ b/tex/context/modules/mkiv/s-languages-system.lua @@ -19,7 +19,7 @@ local ctx_bold = context.bold function moduledata.languages.system.loadinstalled() context.start() - for k, v in table.sortedhash(registered) do + for k, v in sortedhash(registered) do context.language{ k } end context.stop() diff --git a/tex/context/modules/mkiv/s-maps.mkiv b/tex/context/modules/mkiv/s-maps.mkiv index c7541babc..28e88af98 100644 --- a/tex/context/modules/mkiv/s-maps.mkiv +++ b/tex/context/modules/mkiv/s-maps.mkiv @@ -135,11 +135,11 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% 3 versions of layout with matching headers -\definepapersize +\definepapersize [maps] [width=21cm,height=26.5cm] -\setuppapersize +\setuppapersize [maps][maps] \setuplayout[ @@ -360,9 +360,9 @@ \xdef\MapsNumber{\the\numexpr (\the\year-1990)*2+1\relax}% \fi }% \doifnothing\MapsRunningAuthor - {\global\let\MapsRunningAuthor\MapsAuthor}% + {\glet\MapsRunningAuthor\MapsAuthor}% \doifnothing\MapsRunningTitle - {\global\let\MapsRunningTitle\MapsTitle}}% + {\glet\MapsRunningTitle\MapsTitle}}% \def\dostartArticle[#1]{% \MapsBibData[#1] diff --git a/tex/context/modules/mkiv/s-present-dark.mkiv b/tex/context/modules/mkiv/s-present-dark.mkiv new file mode 100644 index 000000000..a3b6f6e14 --- /dev/null +++ b/tex/context/modules/mkiv/s-present-dark.mkiv @@ -0,0 +1,357 @@ +%D \module +%D [ file=s-present-dark, % tug-2001 +%D version=2018.09.25, % 2000.*.* +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Dark, +%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. + +\startmodule[present-dark] + +%D The original document dates from 2000 and was meant for a presentation at \TUG\ +%D 2001. It used widgets and in particular check fields and push buttons. +%D \JAVASCRIPT\ was used to show or hide them when rolling over, and appearances +%D changed in a subtle way. It actually worked quite well at that time. +%D +%D However, over time these widgets proved to be sort of unstable. For instance we +%D used the parent|-|child model of which (inheritance and appearance) behaviour +%D changed over time. We're talking of a few decades ago when \TEX\ was one of the +%D few (maybe only) tools that could actually support everything that the manual +%D introduced: the \quote {standard} seemed to be ahead of the viewer. Anyway, we +%D adapted but it meant that old document in principle were not always future proof. +%D +%D We used in this document a push button in the background of the menu so that it +%D could become visible when rolled over. There were no layers in \PDF\ at that +%D time! Nowadays such a trick doesn't work well because of the way a viewer +%D intercepts regions. One gets kind of erratic behaviour when applying \JAVASCRIPT. +%D +%D I spent quite some time to test if we could still do the same without side +%D effects and in the process also noticed that some functionality in \JAVASCRIPT\ +%D seems broken (or changed due to maybe security issues). So, in the end I decided +%D to simplify the approach and use layers to pop up the menu when the mouse goes +%D over it but no longer hide it when the mouse leaves that area. It just doesn't +%D work too well otherwise. + +%D We start with the layout. We basically have three areas: edge, margin and text. +%D Each are more or less the same width. + +\setuppapersize + [S6][S6] + +\setuplayout + [backspace=380pt, + topspace=20pt, + leftedge=100pt, + leftedgedistance=10pt, + leftmargin=230pt, + leftmargindistance=20pt, + header=0pt, + footer=0pt, + width=200pt, + backspace=360pt, + width=220pt, + leftmargin=210pt, + height=middle] + +%D The bodyfont is the Latin Modern Variable (of course at that time we used +%D the Computer Modern predecessors). We still apply protrusion and expansion. +%D The new \quotation {Modern Latin} look also works ok on screen. + +\definefontfeature + [default] + [default] + [expansion=pure, + protrusion=pure] + +\setupalign + [verytolerant,stretch,hanging] % space + +\setupbodyfont + [modernvariable,11pt] + +% \setupbodyfont +% [modernlatin,11pt] + +\setupinmargin + [style=, + color=] + +%D We use some predefined \JAVASCRIPT\ functions. These are rather old helpers. +%D Normally only the libraries (sets of functions) that are used will be +%D embedded. + +\useJSscripts[fld] +\useJSscripts[nav] + +%D The remarks that will pop up. By default they are not visible. Clicking +%D on the page (or menu item) will show them step by step. + +\newcounter\bofremarks +\newcounter\nofremarks + +\setupfield + [remark] + [offset=overlay, + option={readonly,hidden}, + color=, + style=, + frame=off] + +\defineframed + [remarkable] + [frame=off, + backgroundcolor=white, + background=RollBackground] + +\starttexdefinition unexpanded remark #1#2 + + \doglobal\increment\nofremarks + + \definesymbol + [remark:x:\nofremarks] + [\remarkable{#1}] + + \definesymbol + [remark:y:\nofremarks] + [\remarkable{#2}] + + \definefield + [remark:x:\nofremarks][check][remark] + [remark:x:\nofremarks] + [remark:x:\nofremarks] + + \definefield + [remark:y:\nofremarks][check][remark] + [remark:y:\nofremarks] + [remark:y:\nofremarks] + + \inleft + [scope=local] + { + \hpack to \hsize { + \hss + \linebox { + \fitfield[remark:y:\nofremarks] + } + } + } + + \bgroup + + \setbox\scratchbox\hbox { + #1 + } + + \hpack to \wd\scratchbox { + \wd\scratchbox\zeropoint + \box\scratchbox + \hss + \linebox { + \fitfield[remark:x:\nofremarks] + } + \hss + } + + \egroup + +\stoptexdefinition + +%D We use lots of backgrounds. The \METAPOST\ graphics are a bit overkill +%D but we keep them. + +\setupbackgrounds + [text] + [background=StepFields] + +\defineoverlay + [StepFields] + [\directsetup{syncrefs}\overlaybutton{ShowRemark}] + +\setupbackgrounds + [page] + [background=PageBackground] + +%D Just look in \type {java-imp-fld.mkiv} how \type {HideFields} and +%D alike are defined. They are defined references to \JAVASCRIPT\ calls. + +\setupinteraction + [state=start, + click=no, + menu=on, + style=, + color=, + frame=off, + contrastcolor=] + +\setupinteractionscreen + [option=max] + +\setupbackgrounds + [paper] + [background=color, + backgroundcolor=black] + +\defineoverlay + [PageBackground] + [\useMPgraphic{PageBackground}] + +\startuseMPgraphic{PageBackground} + StartPage ; + numeric w ; w := 1.25 * PaperWidth ; + numeric n ; n := 2.50 * PageNumber ; + numeric d ; d := (1 + (PageNumber-1)/5) * 5pt ; + fill Page + withcolor black ; + for i=1 upto 500 : + draw + center Page + randomized w + rotatedaround(center Page,n) + withpen pencircle + scaled (uniformdeviate d) + withcolor + (yellow randomized (.3,.8)) + ; + endfor ; + StopPage ; +\stopuseMPgraphic + +\defineoverlay + [TextBackground] + [\uniqueMPgraphic{TextBackground}] + +\startuniqueMPgraphic{TextBackground} + fill + OverlayBox + withcolor black ; + draw + OverlayBox + withpen pencircle scaled 1pt + withcolor OverlayColor ; +\stopuniqueMPgraphic + +\defineoverlay + [RollBackground] + [\uniqueMPgraphic{RollBackground}] + +\startuniqueMPgraphic{RollBackground} + fill + OverlayBox + withcolor black ; + draw + OverlayBox + withpen pencircle scaled 1pt + withcolor OverlayColor ; +\stopuniqueMPgraphic + +\setupinteractionmenu + [left] + [state=start, + width=\leftedgewidth, + frame=on, + framecolor=white, + rulethickness=1pt, + foregroundcolor=white, + background=RollBackground] + +\startsetups syncrefs + \normalexpanded { + \definereference + [ShowRemark] + [StepFields{remark:x,\bofremarks,\nofremarks}, + StepFields{remark:y,\bofremarks,\nofremarks}] + } +\stopsetups + +%D The menu buttons used to be rollover buttons but are now normal simple +%D ones (more predictable). + +\defineviewerlayer + [buttons] + +\startinteractionmenu[left] + \vfill + \directsetup{syncrefs} + \startviewerlayer[buttons] + \startbut [previouspage,HideFields] Previous \stopbut + \startbut [nextpage,HideFields] Next \stopbut + \startbut [ShowRemark] Remark \stopbut + \startbut [HideFields] Reset \stopbut + \startbut [CloseDocument,HideFields] Quit \stopbut + \stopviewerlayer +\stopinteractionmenu + +\setupinteraction + [closeaction=ForgetChanges, + openpageaction={HideFields,HideLayer{buttons}}, + closepageaction={HideFields,HideLayer{buttons}}] + +\defineoverlay + [ShowMenu] + [\overlayrollbutton{VideLayer{buttons}}{}] + +\setupbackgrounds + [text][leftedge] + [backgroundoffset=10pt, + background=ShowMenu] + +%D The environment has been adapted a bit. Instead of taking two +%D arguments we now use a key|-|value approach. The remark is shown +%D when one rolls over the title (author). + +\defineframedtext + [MainText] + [frame=off, + offset=10pt, + width=\textwidth, + before=, + after=, + color=, + foregroundcolor=white, + background=TextBackground, + backgroundcolor=white] + +\starttexdefinition unexpanded StartIdea + \dosingleempty{\texdefinition{StartIdeaIndeed}} +\stoptexdefinition + +\starttexdefinition StartIdeaIndeed [#1] + \let\bofremarks\nofremarks + \increment\bofremarks + \startstandardmakeup + \setvariables[Idea][#1] + \startMainText + \setupalign[verytolerant,stretch,hanging] +\stoptexdefinition + +\starttexdefinition unexpanded StopIdea + \doifvariable {Idea} {text} { + \blank + \rightaligned { + \doifelsevariable {Idea} {remark} { + \tooltip + [left] + {\getvariable{Idea}{title}} + {\getvariable{Idea}{remark}} + } { + \getvariable{Idea}{title} + } + } + } + \stopMainText + \vfill + \stopstandardmakeup +\stoptexdefinition + +\stopmodule + +\continueifinputfile{s-present-dark.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{tug/2001/tug-2001-ideas.tex} diff --git a/tex/context/modules/mkiv/s-present-steps.mkiv b/tex/context/modules/mkiv/s-present-steps.mkiv new file mode 100644 index 000000000..432650a5e --- /dev/null +++ b/tex/context/modules/mkiv/s-present-steps.mkiv @@ -0,0 +1,177 @@ +%D \module +%D [ file=s-present-steps, +%D version=2018.05.17, +%D title=\CONTEXT\ Style File, +%D subtitle=Presentation Environment Repeated Steps, +%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. + +%D This a preliminary module, a quick hack and not entirely proper \CONTEXT, but +%D let's see what more is needed. + +\startmodule[present-steps] + +\startluacode + +moduledata.steps = moduledata.steps or { } + +local steps = moduledata.steps +local data = { } +local name = "unknown" +local set = 0 +local settings = nil + +function steps.startsteps(buffername) + set = set + 1 + data = { } + name = buffername +end + +function steps.stopsteps() + local n = 0 + for i=1,#data do + local state = "once" + local done = 0 + while true do + context.startprocessingsteps() + for j=1,i do + local step = data[j] + local nested = step.nested + local content = step.content + local last = (i == #data) and (j == i) and 1 or 0 + local option = step.option + local flush = true + if option == interfaces.variables["title"] then + if i > 1 then + flush = false + end + elseif option == interfaces.variables["repeat"] then + if i == 1 then + flush = false + end + end + if flush then + if j < i or nested == 0 then + context(function() + buffers.assign("step",content) + context.processstep("step",i,0,last) + -- context.writestatus("step a",string.formatters["%i %i %i"](i,0,last)) + end) + state = "done" + else + done = done + 1 + local d = done + context(function() + buffers.assign("step",content) + context.processstep("step",i,d,last) + -- context.writestatus("step b",string.formatters["%i %i %i"](i,d,last)) + end) + if done == nested then + state = "done" + n = n + nested + else + state = "busy" + end + end + end + end + context.stopprocessingsteps() + if state == "done" then + break + end + end + end +end + +function steps.startstep(str) + settings = utilities.parsers.settings_to_hash(str) +end + +function steps.stopstep() + settings.content = buffers.getcontent(name) + settings.nested = tonumber(settings.n) or 0 + data[#data+1] = settings +end + +function steps.startsubstep(str) + local d = data[#data] + d.nested = d.nested + 1 +end + +function steps.stopsubstep() +end + +\stopluacode + +\definebuffer + [step] + +\def\currentstep {0} +\def\currentsubstep{0} + +\unexpanded\def\startprocessingsteps + {\global\wantedsubstep\zerocount} + +\unexpanded\def\stopprocessingsteps + {} + +\unexpanded\def\processstep#1#2#3#4% + {\par + \edef\currentstep {#2}% + \edef\currentsubstep{#3}% + \ifcase#4\relax + \setupreferencing[prefix=#2:#3] + \getbuffer[#1]% + \par + \else + \setupreferencing[prefix=] + \getbuffer[#1]% + \page + \fi} + +\let\normalstartstep\startstep + +\newcount\wantedsubstep + +\unexpanded\def\startsteps + {\ctxlua{moduledata.steps.startsteps("\thedefinedbuffer{step}")}} + +\unexpanded\def\stopsteps + {\ctxlua{moduledata.steps.stopsteps()}} + +\unexpanded\def\startstep + {\dosingleempty\startstepindeed} + +\def\startstepindeed[#1]% + {\ctxlua{moduledata.steps.startstep("#1")}% + \normalstartstep} + +\unexpanded\def\stopstep + {\ctxlua{moduledata.steps.stopstep()}} + +\let\stopsubstep\relax + +\unexpanded\def\startsubstep#1\stopsubstep + {\ctxlua{moduledata.steps.startsubstep()}% + \ifcase\currentsubstep\relax + #1% + \else + \global\advance\wantedsubstep\plusone + \ifnum\currentsubstep>\wantedsubstep\else + #1% + \fi + \fi + \ctxlua{moduledata.steps.stopsubstep()}} + +\stopmodule + +\continueifinputfile{s-present-steps.mkiv} + +\usemodule[present-common] + +\inputpresentationfile{examples/present-steps-001.tex} diff --git a/tex/context/modules/mkiv/s-references-identify.mkiv b/tex/context/modules/mkiv/s-references-identify.mkiv new file mode 100644 index 000000000..85187be9d --- /dev/null +++ b/tex/context/modules/mkiv/s-references-identify.mkiv @@ -0,0 +1,69 @@ +%D \module +%D [ file=s-references-identity, +%D version=2018.09.15, +%D title=\CONTEXT\ Style File, +%D subtitle=Analyze References, +%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. + +% begin info +% +% title : analyze reference +% +% comment : show the building blocks of a reference (list) +% +% end info + +\startmodule[references-identify] + +\startluacode + +moduledata.references = moduledata.references or { } + +local context = context +local NC, NR = context.NC, context.NR +local bold = context.bold +local text = context + +function moduledata.references.show(str) + local t = structures.references.identify(str) + context.starttabulate { "|T|T|T|" } + for i=1,#t do + if i == 1 then + context.FL() + else + context.ML() + end + local ti = t[i] + NC() bold(i) NC() bold("reference") NC() bold(ti.reference) NC() NR() + NC() NC() text("kind") NC() text(ti.kind) NC() NR() + NC() NC() text("operation") NC() text(ti.operation) NC() NR() + NC() NC() text("arguments") NC() text(ti.arguments) NC() NR() + NC() NC() text("special") NC() text(ti.special) NC() NR() + end + context.LL() + context.stoptabulate() +end + +\stopluacode + +\installmodulecommandluasingle \showreference {moduledata.references.show} + +\stopmodule + +\continueifinputfile{s-references-identify.mkiv} + +\usemodule[art-01] + +\starttext + + \showreference[page(123),StartMovie{mymovie}] + \showreference[JS(Forget_Changes),CloseDocument] + \showreference[manual::contents] + +\stoptext diff --git a/tex/context/modules/mkiv/s-xml-analyzers.lua b/tex/context/modules/mkiv/s-xml-analyzers.lua index 6e7f7f2ba..93c6c37b6 100644 --- a/tex/context/modules/mkiv/s-xml-analyzers.lua +++ b/tex/context/modules/mkiv/s-xml-analyzers.lua @@ -230,6 +230,12 @@ local f_template = formatters [ [[ %% setups +\xmlregistersetup{xml:presets:all} + +\starttext + \xmlprocessfile{main}{somefile.xml}{} +\stoptext + %s ]] ] diff --git a/tex/context/modules/mkiv/s-youless.mkiv b/tex/context/modules/mkiv/s-youless.mkiv index d8b6e2ff6..e218e6110 100644 --- a/tex/context/modules/mkiv/s-youless.mkiv +++ b/tex/context/modules/mkiv/s-youless.mkiv @@ -33,7 +33,26 @@ moduledata.youless = { } - local function process(specification) + local defaults = { + electricity = { + unit = "watt", + maxunit = "maxwatt", + }, + watt = { + unit = "watt", + maxunit = "maxwatt", + }, + pulse = { + unit = "watt", + maxunit = "maxwatt", + }, + gas = { + unit = "liters", + maxunit = "maxliters", + }, + } + + local function process(specification,thevariant) local data, message = utilities.youless.analyze(specification.filename or "youless-electricity.lua") @@ -42,12 +61,32 @@ return end - local year = tonumber(specification.year) or os.today().year - local years = data.years local variant = data.variant local unit = specification.unit local maxunit = specification.maxunit + if thevariant then + if variant ~= thevariant then + context("invalid variant") + return + end + elseif variant then + local d = defaults[variant] + if d then + unit = d.unit + maxunit = d.maxunit + else + context("unknown variant") + return + end + else + context("invalid variant") + return + end + + local year = tonumber(specification.year) or os.today().year + local month = tonumber(specification.month) + local years = data.years local max = specification[maxunit] if not max then @@ -60,16 +99,19 @@ end end + local firstmonth = month or 1 + local lastmonth = month or 12 + local max = max local delta = round(max/10) local scale = round(delta/20) local mark = 3 for y=year,year do - local year = years[y] + local year = years[y] if year then local grand = 0 - for m=1,12 do + for m=firstmonth,lastmonth do local month = year.months[m] if month then context.startMPpage { offset = "10pt" } @@ -167,7 +209,7 @@ function moduledata.youless.electricity(specification) specification.unit = "watt" specification.maxunit = "maxwatt" - process(specification) + process(specification,"electricity") end moduledata.youless.watt = moduledata.youless.electricity @@ -175,12 +217,16 @@ function moduledata.youless.gas(specification) specification.unit = "liters" specification.maxunit = "maxliters" - process(specification) + process(specification,"gas") end function moduledata.youless.pulse(specification) specification.unit = "watt" specification.maxunit = "maxwatt" + process(specification,"pulse") + end + + function moduledata.youless.graphics(specification) process(specification) end diff --git a/tex/context/modules/mkiv/x-asciimath.lua b/tex/context/modules/mkiv/x-asciimath.lua index b0d45659e..677ab0ce5 100644 --- a/tex/context/modules/mkiv/x-asciimath.lua +++ b/tex/context/modules/mkiv/x-asciimath.lua @@ -132,6 +132,12 @@ local reserved = { ["overbar"] = { false, "\\overline", "unary" }, ["overline"] = { false, "\\overline", "unary" }, ["underline"] = { false, "\\underline", "unary" }, + ["overbrace"] = { false, "\\overbrace", "unary" }, + ["underbrace"]= { false, "\\underbrace", "unary" }, + ["overset"] = { false, "\\overset", "unary" }, + ["underset"] = { false, "\\underset", "unary" }, + ["obrace"] = { false, "\\overbrace", "unary" }, + ["ubrace"] = { false, "\\underbrace", "unary" }, ["ul"] = { false, "\\underline", "unary" }, ["vec"] = { false, "\\overrightarrow", "unary" }, ["dot"] = { false, "\\dot", "unary" }, -- 0x2D9 @@ -143,6 +149,7 @@ local reserved = { ["-"] = { true, "-" }, ["*"] = { true, "⋅" }, ["**"] = { true, "⋆" }, + ["////"] = { true, "⁄⁄" }, -- crap ["//"] = { true, "⁄" }, -- \slash ["\\"] = { true, "\\" }, ["xx"] = { true, "×" }, @@ -749,11 +756,14 @@ end reserved.P = nil reserved.S = nil + local isbinary = { ["\\frac"] = true, ["\\root"] = true, ["\\asciimathroot"] = true, ["\\asciimathstackrel"] = true, + ["\\overset"] = true, + ["\\underset"] = true, } local isunary = { -- can be taken from reserved @@ -772,6 +782,10 @@ local isunary = { -- can be taken from reserved ["\\dot"] = true, -- ["\\ddot"] = true, -- + ["\\overbrace"] = true, + ["\\underbrace"] = true, + ["\\obrace"] = true, + ["\\ubrace"] = true, } local isfunny = { @@ -1715,8 +1729,14 @@ local function collapse_fractions_2(t) while i < n do local current = t[i] if current == "⁄" and i > 1 then -- \slash - t[m] = "{" .. s_left .. t[i-1] .. s_mslash .. t[i+1] .. s_right .. "}" - i = i + 2 + if i < n and t[i+1] == "⁄" then + -- crap for + t[m] = "{" .. s_left .. t[i-1] .. s_mslash .. s_mslash .. t[i+2] .. s_right .. "}" + i = i + 3 + else + t[m] = "{" .. s_left .. t[i-1] .. s_mslash .. t[i+1] .. s_right .. "}" + i = i + 2 + end if i < n then m = m + 1 t[m] = t[i] diff --git a/tex/context/modules/mkiv/x-mathml.mkiv b/tex/context/modules/mkiv/x-mathml.mkiv index ea7f7d2e9..adc494314 100644 --- a/tex/context/modules/mkiv/x-mathml.mkiv +++ b/tex/context/modules/mkiv/x-mathml.mkiv @@ -350,7 +350,7 @@ % % \def\postponedMMLactions % {\global\setfalse\somepostponedMMLactions -% \@EA\global\@EA\@@postponedMMLactions\@EA\emptytoks +% \expandafter\global\expandafter\@@postponedMMLactions\expandafter\emptytoks % \the\@@postponedMMLactions} \startxmlsetups mml:apply diff --git a/tex/context/modules/mkiv/x-setups-basics.mkiv b/tex/context/modules/mkiv/x-setups-basics.mkiv index be96466b8..51c925397 100644 --- a/tex/context/modules/mkiv/x-setups-basics.mkiv +++ b/tex/context/modules/mkiv/x-setups-basics.mkiv @@ -66,6 +66,13 @@ \unprotect +% We might apply this locally! + +\setupxml + [\c!entities=\v!yes] + +% So far. + \defineregister [texmacro] @@ -510,14 +517,11 @@ {\doifelsenextoptionalcs\cmd_show_setup_yes\cmd_show_setup_nop} \def\cmd_show_setup_yes[#1]% - {\iffirstargument - \cmd_show_setup_nop{#1}% - \else - \expandafter\cmd_show_setup_nop - \fi} + {\cmd_show_setup_nop{#1}} \def\cmd_show_setup_nop#1% this will trigger 'used' - {\registersort[texcommand][#1]% + {\begingroup + \registersort[texcommand][#1]% \ifconditional\c_cmd_show_setup \writestatus{setup}{#1 / \rawsynonymname{texcommand}{#1}}% \fi @@ -534,7 +538,8 @@ \let\m_cmd_instance\empty \fi \stopelement - \stopelement} + \stopelement + \endgroup} \unexpanded\def\placesetup {\placelistofsorts[texcommand][\c!criterium=\v!used]} \unexpanded\def\placeallsetups{\placelistofsorts[texcommand][\c!criterium=\v!all ]} diff --git a/tex/context/modules/mkiv/x-setups-overview.mkiv b/tex/context/modules/mkiv/x-setups-overview.mkiv index f6dff12f5..512db3bd1 100644 --- a/tex/context/modules/mkiv/x-setups-overview.mkiv +++ b/tex/context/modules/mkiv/x-setups-overview.mkiv @@ -102,8 +102,9 @@ numeric h, w; boolean mapping ; path p, q, r ; color f, d ; pair s ; h := OverlayHeight ; w := 2*OverlayWidth ; r := unitsquare xyscaled (w,h) ; - fill r withcolor \MPcolor{lightgray} ; - mapping := lua.mp.processingmode("setups:mapping") ; + fill r withcolor resolvedcolor("lightgray") ; + % mapping := lua.mp.processingmode("setups:mapping") ; + mapping := lua.mp("processingmode","setups:mapping") ; if mapping : set_grid(w,h,w/8,w/160) ; pickup pensquare yscaled (w/80) ; @@ -114,8 +115,8 @@ forever : s := center r randomized (w,h) ; if new_on_grid(xpart s, ypart s) : - d := .5[\MPcolor{LocalColor},\MPcolor{lightgray}] randomized (.5,.9) ; - f := \MPcolor{lightgray} randomized (.5,.9) ; + d := .5[resolvedcolor("LocalColor"),resolvedcolor("lightgray")] randomized (.5,.9) ; + f := resolvedcolor("lightgray") randomized (.5,.9) ; s := (dx,dy) ; if mapping : p := (-w/4,0) -- (w/4,0) ; diff --git a/tex/context/patterns/common/lang-agr.rme b/tex/context/patterns/common/lang-agr.rme index 72692b849..39c557d16 100644 --- a/tex/context/patterns/common/lang-agr.rme +++ b/tex/context/patterns/common/lang-agr.rme @@ -1,17 +1,34 @@ % generated by mtxrun --script pattern --convert -% **************************************************************** -% -% File name: hyph-grc.tex -% -% Created: June 6, 2008 -% Last modified: Sept. 12, 2011 -% -% Unicode hyphenation patterns for Ancient Greek. -% -% Author: Dimitrios Filippou, (c) 2008-2011 -% Licence: LaTeX Project Public Licence -% +% title: Unicode hyphenation patterns for Ancient Greek. +% copyright: Dimitrios Filippou, (c) 2008-2016 +% notice: > +% This file is part of the hyph-utf8 package. +% See http://www.hyphenation.org for more information. +% language: +% name: Ancient Greek +% tag: grc +% licence: +% name: LPPL +% url: http://www.latex-project.org/lppl/ +% changes: +% - +% date: 2016-05-12 +% author: Arthur Reutenauer +% description: added support for curly beta +% - +% date: 2011-09-12 +% author: Dimitrios Filippou +% description: updated headers and added the LPPL licence statement +% - +% date: 2008-06-06 +% author: Dimitrios Filippou +% description: removed guillemets (») +% - +% date: 2008-05-27 +% author: Dimitrios Filippou +% +% ========================================== % This file was first created by mechanical translation from % GRAhyph5.tex via "elhyph-utf8 -a -c" (version 0.1 by Peter % Heslin -- p.j.heslin at durham dot ac dot uk). Some additions diff --git a/tex/context/patterns/common/lang-bg.rme b/tex/context/patterns/common/lang-bg.rme index 6229f0647..25a3e2ca5 100644 --- a/tex/context/patterns/common/lang-bg.rme +++ b/tex/context/patterns/common/lang-bg.rme @@ -1,85 +1,890 @@ % generated by mtxrun --script pattern --convert -% copyright: Copyright (c) 1994-2008, Georgi Boshnakov +% copyright: Copyright (C) 2000, 2004, 2017 by Anton Zinoviev % title: Bulgarian hyphenation patterns -% version: 1.7, July 2008 +% version: 21 October 2017 % language: % name: Bulgarian -% code: bg +% tag: bg % notice: > % This file is part of the hyph-utf8 package. % See http://www.hyphenation.org for more information. % authors: -% - -% name: Georgi Boshnakov -% contact: manchester.ac.uk:georgi.boshnakov +% - +% name: Anton Zinoviev +% contact: anton:lml.bas.bg % licence: -% - This file is available under any of these licences: -% - -% name: LPPL -% version: 1.0 -% later_authorised: true -% url: https://latex-project.org/lppl/lppl-1-0.html -% - -% name: MIT -% url: https://opensource.org/licenses/MIT % text: > -% Permission is hereby granted, free of charge, to any person -% obtaining a copy of this software and associated documentation -% files (the "Software"), to deal in the Software without -% restriction, including without limitation the rights to use, -% copy, modify, merge, publish, distribute, sublicense, and/or sell -% copies of the Software, and to permit persons to whom the -% Software is furnished to do so, subject to the following -% conditions: -% -% The above copyright notice and this permission notice shall be -% included in all copies or substantial portions of the Software. -% -% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -% OTHER DEALINGS IN THE SOFTWARE. +% This software may be used, modified, copied, distributed, and sold, +% both in source and binary form provided that the above copyright +% notice and these terms are retained. The name of the author may not +% be used to endorse or promote products derived from this software +% without prior permission. THIS SOFTWARE IS PROVIDES "AS IS" AND +% ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. IN NO EVENT +% SHALL THE AUTHOR BE LIABLE FOR ANY DAMAGES ARISING IN ANY WAY OUT +% OF THE USE OF THIS SOFTWARE. % hyphenmins: -% for_typesetting: +% typesetting: % left: 2 % right: 2 -% changes: -% - -% date: 2008-06 -% description: Changed encoding to UTF-8 -% - -% date: 2006-05 -% description: Added copyright notice -% - -% date: 2000-06 -% description: Minor changes -% - -% date: 1994 -% description: First version +% changes: See below % ========================================== -% Note: The original name of this file was 'bghyphsi.tex' which is -% part of the package 'bghyphen'. The package 'bghyphen' is now -% obsolete but it is still available on CTAN and currently (June 2008) -% gives the same hyphenation results. -% +% Copyright (C) 2000,2004,2017 by Anton Zinoviev % +% This software may be used, modified, copied, distributed, and sold, +% both in source and binary form provided that the above copyright +% notice and these terms are retained. The name of the author may not +% be used to endorse or promote products derived from this software +% without prior permission. THIS SOFTWARE IS PROVIDES "AS IS" AND +% ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. IN NO EVENT +% SHALL THE AUTHOR BE LIABLE FOR ANY DAMAGES ARISING IN ANY WAY OUT +% OF THE USE OF THIS SOFTWARE. % -% To make TeX use these patterns: +% Bulgarian hyphenation patterns % -% (1) Make sure that the hyph-utf8 package is present in your TeX -% system. +% Generated by ./hyph-bg.sh --safe-morphology --standalone-tex % -% (2) generate the necessary formats (TeX, LaTeX, pdfLaTeX, etc), -% instructing TeX to load 'loadhyph-bg.tex' for Bulgarian -% hyphenation. -% -% The LaTeX babel package sets \lefthyphenmin and \righthyphenmin to 2 -% when the language is switched to Bulgarian. Developers who write -% support for Bulgarian outside LaTeX and/or babel need to take care -% of this. +% Both left and right hyphenmins should be set to 2. % +% % Automated Bulgarian Hyphenation +% % Anton Zinoviev +% % 21 October 2017 +% +% Principles of the Bulgarian hyphenation +% ======================================= +% +% One specificity of the Bulgarian language is that the average length +% of the words is greater than in English. When typesetting a Bulgarian +% text, hyphenation is more important than when typesetting an English +% text. Knuth's algorithm for line-breaking is such that in most +% English paragraphs no hyphenation will be used. With a Bulgarian +% text, however, even the Knuth's algorithm will use hyphenation in most +% paragraphs. Hyphenation becomes an absolute necessity if we want to +% obtain nice, justified paragraphs when using a software with dumb +% line-breaking algorithm, such as LibreOffice. +% +% According to Decree 936 of the Council of Ministers promulgated on 27 +% November 1950, the Institute for Bulgarian Language at the Bulgarian +% Academy of Sciences is authorised to publish the rules of the +% orthography of the Bulgarian language (within certain limits). +% +% Hyphenation rules between 1945 and 1983 +% --------------------------------------- +% +% Between 1945 and 1983 Bulgarian used syllable hyphenation with two +% morphological exceptions: hyphenation is preferred between a prefix +% and a stem and at the boundary of compound words. The following were +% the rules governing the hyphenation: +% +% 1. One letter does not stay alone. Words of one syllable can not be +% hyphenated. +% 2. No hyphenation before or after ь. +% 3. In a sequence of vowels at least one vowel stays before the +% hyphen. +% 4. A single consonant between two vowels links with the second vowel. +% For example по-ле /po-le/, ра-бо-та /ra-bo-ta/. +% 5. In a sequence of consonants between two vowels, at least one +% consonant stays with the second vowel. For example те-сто /te-sto/ +% or тес-то /tes-to/.[^b] +% 6. In a sequence of consonants between two vowels, if the first +% consonant is sonorant (й /y/, л /l/, м /m/, н /n/, р /r/), then it +% stays with the first vowel. For example гер-дан /ger-dan/, сен-ки +% /sen-ki/. +% 7. The hyphenation separates two successive equal consonants. For +% example времен-но /vremen-no/, пролет-та /prolet-ta/. +% 8. When the letters дж /dzh/ and дз /dz/ denote a single consonant, +% then they are not separated. For example боя-джия /boya-dzhiya/ +% but not бояд-жия /boyad-zhiya/. When these letters denote two +% consonants, then the normal rules apply: над-живявам +% /nad-zhivyavam/. +% 9. Word prefixes may not be broken. Compound words are hyphenated +% either at the boundary of the components or the hyphenation rules +% are applied to each of the components separately. For example: +% пред-упреждавам /pred-uprezhdavam/ (not пре-дупреждавам +% /pre-duprezhdavam/), пред-известие /pred-izvestie/ (not +% пре-дизвестие /pre-dizvestie/), за-движвам /za-dvizhvam/ (not +% зад-вижвам /zad-vizhvam/), авто-клуб /avto-klub/ (not авток-луб +% /avtok-lub/), вакуум-апарат /vakuum-aparat/ (not вакуу-мапарат +% /vakuu-maparat/). +% +% In some rare cases the proper application of rule 9 depends on the +% semantics of the word. For example пре-дреша /pre-dresha/ 'change +% clothes' but пред-реша /pred-resha/ 'predetermine' or прес-пите +% /pres-pite/ 'the snow-drifts' but пре-спите /pre-spite/ 'sleep for a +% while/overnight'. +% +% [^b]: In several publications this rule is formulated with the +% additional restriction that the sequence of consonants begins with +% an obstruent. I believe this restriction is unintentional. It +% makes no sense to forbid a hyphenation of the form AB-A but to +% permit ABB-A (A denotes a vowel and B – a consonant). +% +% Hyphenation rules between 1983 and 2012 +% --------------------------------------- +% +% The Orthographic dictionary published by the Institute for Bulgarian +% language in 1983 introduced new hyphenation rules. The complexity of +% the previous rules was the main reason for the change. The new rules +% aimed at two objectives: simplicity and unambiguity. +% +% The new rules are: +% +% 1. A consonant between two vowels links with the second vowel. For +% example ви-со-чи-на /vi-so-chi-na/. +% 2. In a sequence of two or more consonants between two vowels, at +% least one consonant stays with first vowel and at least one with +% the second vowel. For example сес-тра /ses-tra/ and сест-ра +% /sest-ra/. +% 3. Two equal consonants are separated. For example плен-ник +% /plen-nik/. +% 4. In a sequence of two or more vowels, the first vowel stays before +% the hyphen. For example пре-одолея /pre-odoleya/ and прео-долея +% /preo-doleya/. +% 5. In a sequence of three or more vowels, the last vowel stays after +% the hyphen. For example мао-изъм /mao-izam/ but not маои-зъм +% /maoi-zam/. +% 6. The letter й /y/ between a vowel and a consonant stays with the +% vowel. For example май-ка /may-ka/. +% 7. When a sequence of two or more consonants follows й /y/ then at +% least one consonant links with й /y/. For example айс-берг +% /ays-berg/ (not ай-сберг /ay-sberg/). +% 8. The letter й /y/ between two vowels links with the second vowel. +% For example ма-йор /ma-yor/. +% 9. No hyphenation before or after ь. +% 10. When the letters дж /dzh/ denote a single consonant, then they are +% not separated. For example су-джук /su-dzhuk/ (not суд-жук +% /sud-zhuk/) but над-живея /nad-zhiveya/. +% 11. There must be at least one vowel before and after the hyphen. +% 12. One letter does not stay alone. +% +% The total disregard of the morphology by these rules leads to some +% strange results. For example пре-дизвестие /pre-dizvestie/ is +% permitted and пред-известие /pred-izvestie/ is forbidden, зад-вижвам +% /zad-vizhvam/ is permitted and за-движвам /za-dvizhvam/ is forbidden, +% авток-луб /avtok-lub/ is permitted and авто-клуб /avto-klub/ is +% forbidden, вакуу-мапарат /vakuu-maparat/ is permitted and +% вакуум-апарат /vakuum-aparat/ is forbidden. Because of this, the new +% rules were not universally accepted. The old rules are still +% mentioned in various places in Internet, they are included even in +% some grammar books published by the publishing houses of the Ministry +% of Education and of Sofia University. The software developers, +% however, soon came into love with the new hyphenation rules. +% +% Hyphenation rules after 2012 +% ---------------------------- +% +% In 2012 new rules came into force. There are two differences with +% respect to the previous rules: +% +% 1. Rule 5 of the previous rules is revoked. For example маои-зъм +% /maoi-zam/ becomes a valid hyphenation. +% 2. The new rules permit morphologically based hyphenation (however it +% is not obligatory). For example пред-известие /pred-izvestie/, +% за-движвам /za-dvizhvam/, авто-клуб /avto-klub/, вакуум-апарат +% /vakuum-aparat/ are valid hyphenations. +% +% Good hyphenation is a complex matter and it seems the linguists at the +% Institute for Bulgarian Language have recognised this. They no longer +% attempt to provide universal rules about everything. Instead, they +% provide some very permissible rules while the good application of +% these rules is leaved to the discretion and the experience of the +% printers and the developers of hyphenation software. +% +% It makes sense to use at least two different sets of hyphenation rules +% for Bulgarian. In most cases a more restrictive version should be +% used, one which attempts to eliminate the controversial cases of +% hyphenation. When typesetting a Bulgarian text in a narrow newspaper +% column, however, it will be appropriate to use more liberal +% hyphenation rules. It should be noted that one of the reasons for the +% hyphenation reform in 1983 was the desire to fix the chaotic +% hyphenation in the Bulgarian newspapers at that time. +% +% Computer implementations +% ======================== +% +% Mathematical analysis of the Bulgarian hyphenation +% -------------------------------------------------- +% +% The earliest mathematical analysis of the Bulgarian hyphenation rules +% belongs to Veska Noncheva.[^1] In 1988 she proposed a mathematical +% formalisation of the hyphenation rules in a table with 22 rows.[^2] +% +% [^1]: +% +% [^2]: Нончева В. Алгоритъм за автоматично пренасяне на думи в +% българския език. Математика и математическо +% образование. Сб. доклади на 17. ПК на СМБ. С., БАН, 1988, 479-482. +% +% In the same year Eugene Belogay[^3] proposed an alternative +% formalisation with only 9 rules.[^4] Belogay proved that his rules are +% consistent and that they form a minimal set. The rules of Belogay +% have negative character – every hyphenation which is not forbidden by +% a rule is possible hyphenation. +% +% [^3]: +% +% [^4]: Белогай Е. Алгоритъм за автоматично пренасяне на думи. Компютър +% за вас (1988) 3, 12-14. +% +% The following are the first 7 rules, as formulated by Belogay: +% +% 1. Б-А +% 2. А-ББ +% 3. Б-ТТ, ТТ-Б +% 4. ААА-Б +% 5. й-ББ +% 6. Б-ь +% 7. д-ж +% +% Here А denotes an arbitrary vowel letter, Б denotes an arbitrary +% consonant letter (including ь and й), ТТ denotes a sequence of two +% equal consonant letters and the letters й, ь, д and ж denote +% themselves. For example the rule "Б-А" says that we are not permitted +% to separate a consonant letter from immediately following vowel +% letter. +% +% The eighth rule of Belogay says that hyphenation is forbidden before +% the first and after the last vowel letter. The ninth rule of Belogay +% says that hyphenation is forbidden immediately after the first or +% immediately before the last letter of the word. +% +% Notice that is is very easy to translate the rules of Belogay in the +% form, required for the hyphenation algorithm of Knuth and Liang used +% in TeX.[^a] Let us remind that this algorithm matches the word with a +% set of string patterns in which the odd numbers say hyphenation is +% permitted in this position and even numbers say the hyphenation is +% forbidden. When two patterns give conflicting numbers for the same +% position, then the greater number wins. +% +% First, since the rules of Belogay are negative (they say where +% hyphenation is forbidden, not where it is permitted), we have to +% permit the hyphenation everywhere: +% +% 1. А1 +% 2. Б1 +% +% Then, the first seven rules of Belogay obtain the form: +% +% 1. Б2А +% 2. А2ББ +% 3. Б2ТТ ТТ2Б +% 4. ААА2Б +% 5. й2ББ +% 6. Б2ь +% 7. д2ж +% +% Since no Bulgarian word starts with more that four consonants and no +% Bulgarian word ends with more than three consonants, the eighth rule +% of Belogay can be translated in the following way: +% +% 1. .Б2 +% 2. .ББ2 +% 3. .БББ2 +% 4. 2Б. +% 5. 2ББ. +% +% The ninth rule of Belogay means that left and right hyphen mins should +% be set to 2. +% +% The work of Eugene Belogay was not limited to merely a mathematical +% analysis of the Bulgarian hyphenation rules. In his paper he +% published a short algorithm in Pascal which implements these rules. +% It didn't take long for this algorithm to be used in various text +% processing software. The algorithm of Belogay was famous for many +% years. Even as late as 1997 in one book about TeX, the author didn't +% care to give any explanations but simply wrote about "the algorithm of +% Belogay" as something well known to the reader.[^5] +% +% [^a]: Liang, Franklin Mark. Word Hy-phen-a-tion by +% Com-put-er (Doctoral Dissertation). Stanford University, 1983 +% +% [^5]: Василев В. Ултимативният ТеХ. Удоволствието да правим +% предпечатна подготовка сами. София, Интела, 1997, 36 +% +% Bulgarian hyphenation in TeX +% ---------------------------- +% +% One unfortunate design decision of Knuth was that the hyphenation +% algorithm of TeX applied the hyphenation patterns not to the input +% character codes but to the internal codes of the glyphs in the font. +% This created a problem for the Cyrillic languages because in TeX the +% Cyrillic fonts did not have standardised encoding. Perhaps this is +% one of the reasons why the earliest implementations of the Bulgarian +% hyphenation in TeX did not rely on the internal hyphenation algorithm +% of TeX. Instead, external tools were used to insert soft hyphens in +% all Bulgarian words. For example such a tool would replace the word +% сричкопренасяне /srichkoprenasyane/ with +% срич\\-коп\\-ре\\-на\\-ся\\-не /srich\\-kop\\-re\\-na\\-sya\\-ne/. +% The saying "To every disadvantage there is a corresponding advantage" +% is true – since Cyrillic and Latin letters use different character +% codes, an external tool could easily insert soft hyphens in all +% Bulgarian words while leaving the TeX commands intact. +% +% The earliest known attempt to use the hyphenation algorithm of TeX for +% Bulgarian was made by Ognyan Tonev in 1990.[^6] He described his work +% as "a not very good translation of the rules. I work in this +% direction. But I don't have a 100% working complect of patterns. So, +% the copy I send to you[^7] is only a beta-version." The hyphenation +% patterns of Tonev don't work correctly and it seems he never completed +% his work. +% +% [^6]: The author of this text was unable to find current information +% about Ognyan Tonev in Internet. Apparently in 1990 he worked in +% the Center of Informatics and Computer Technology of the Bulgarian +% Academy of Sciences. +% +% [^7]: To Yannis Haralambous, +% +% +% The first usable Bulgarian hyphenation patterns for TeX were developed +% by Georgi Boshnakov[^8] in 1994. In order to solve the encoding +% problem, Boshnakov had developed TeX fonts supporting the MIK encoding +% (the prevalent encoding at that time in Bulgaria). This allowed him +% to introduce a fully working implementation only a few months after +% LaTeX2e became the official LaTeX version. Later Boshnakov modified +% his work with the Babel system. The hyphenation patterns of Boshnakov +% did their job well enough, so that for almost quarter a century after +% their initial creation, they remained the only Bulgarian hyphenation +% patterns in the standard distributions of TeX and CTAN. +% +% [^8]: +% +% There are some similarities between the patterns of Boshnakov and the +% patterns of Belogay. The following are the main differences. +% +% First, Boshnakov used an ingenious and more compact implementation of +% the second and the third rule. Instead of {А2ББ, Б2ТТ, ТТ2Б}, or +% 8×22×22+22×22+22×22=4840 patterns in total, Boshnakov has patterns of +% the form 2Б3Б2 and 4Т3Т4, or only 22×22=484 in total, with the same +% effect. +% +% The second main difference between the patterns of Boshnakov and the +% patterns of Belogay concerns the letter combination дж /dzh/. In +% Bulgarian this letter combination can denote either a single +% consonant, or a sequence of two consonants and the hyphenation rules +% change respectively. Unfortunately, it is impossible to know the +% meaning of дж /dzh/ without a vocabulary. The solution of Belogay was +% a cautious one – his rules do the hyphenation in a way which will be +% correct regardless of whether дж /dzh/ is a single consonant or a +% sequence of two consonant. On the other hand, the approach of +% Boshnakov is a bold one – since дж /dzh/ is more often a single +% consonant, his rules assume that it is always a single consonant. The +% number of the cases when this decision leads to bad hyphenations is +% insignificant in comparison with the cases in which we obtain improved +% hyphenation. +% +% The third main difference between the patterns of Boshnakov and the +% patterns of Belogay concerns the eighth rule – its implementation in +% the rules of Boshnakov is rather limited which leads to wrong +% hyphenations like бри-дж /bri-dzh/. A full implementation of this +% rule would require 11660 patterns in total and this would be too much +% for the computers in 1994. +% +% Later developments +% ------------------ +% +% In 1995 Atanas Topalov defended a Masters thesis in the Faculty of +% Mathematics and Informatics at Sofia University titled "Algorithms and +% software about text processing".[^9] One of the main topics in his +% thesis was the Bulgarian hyphenation. Topalov criticised vehemently +% the official hyphenation rules and their total disregard of the +% morphology. He wrote: +% +% > If we look at the history of the problems of the hyphenation, we +% > will discover something very strange. Instead of the expected +% > involvement with the depths and aspiration for more admissible and +% > satisfactory style, we can find a growing tendency for +% > simplification. One unpleasant discovery is that the development of +% > the hyphenation software stays firmly on the principle "let us do +% > the easiest thing". The earliest works which have been studied are +% > from 1978. It turned out that they present the best approach +% > concerning the automated hyphenation. The authors have chosen the +% > most difficult but the most correct (from literary point of view) +% > method for hyphenation, namely the morphological approach. +% +% Topalov proposed his own hyphenation algorithm. The hyphenation it +% generated was smooth and easy to read. One obvious defect of the +% algorithm of Topalov was that it contradicted the official hyphenation +% rules at that time. One can argue, however, that his algorithm is +% compatible with the current hyphenation rules. +% +% [^9]: The thesis of Atanas Topalov can be accessed at the author's +% website +% +% In 1999 Svetla Koeva[^10] wrote a paper about the automated Bulgarian +% hyphenation.[^11] At that time she was a junior member of the +% Department of Computational Linguistics at the Institute for Bulgarian +% Language but now she is a director of the whole institute. The paper +% of Koeva contains a list of hyphenation patterns which can be used as +% a basis of automated hyphenation. In 2004 with the help of Stoyan +% Mihov[^12] the rules of Koeva were formalised with regular relations +% and rewriting rules. They were implemented in a software product +% named ItaEst which provided Bulgarian hyphenation and grammar checking +% for various software products of Microsoft and Apple. +% +% [^10]: +% +% [^11]: Коева, Светла. Правила за пренасяне на части от думите на нов +% ред. Български език. 1999/2000, 1, 84-86 +% +% [^12]: +% +% The main differences between the hyphenation of Koeva and the official +% hyphenation rules effective after 2012 is that the separation of a +% long sequence of consonants between two vowels is done according to +% the rules valid before 1983. For example се-стра /se-stra/ and +% ай-сберг /ay-sberg/ are permitted. The main difference between the +% hyphenation of Koeva and the official hyphenation rules effective +% before 1983 is that the rules of Koeva disregard the morphology of the +% words. The following rule of Koeva is specific: in a sequence of two +% sonorant consonants between two vowels, we are permitted to separate +% the first vowel from the first consonant, for example материа-лна +% /materia-lna/. +% +% In 2000 Anton Zinoviev[^13] created new hyphenation patterns for TeX. +% He didn't know about the previous work of Boshnakov and he didn't +% bother to make his work available in the various TeX distributions and +% CTAN. His work was used mostly by the local Linux enthusiasts and the +% colleagues of Zinoviev. In 2001 Radostin Radnev[^14] created a free +% grammar dictionary of Bulgarian[^15] where he used the hyphenation +% patterns of Zinoviev. From there the work of Zinoviev propagated to +% OpenOffice, LibreOffice and various online dictionaries, including +% and . +% +% [^13]: The author of this text. +% +% [^14]: +% +% [^15]: +% +% The following are the main differences between the hyphenation of +% Zinoviev and the hyphenation of Boshnakov. +% +% First, the eighth rule of Belogay is fully implemented. +% +% Second, the rules of Zinoviev try to detect when the letters дж /dzh/ +% (and дз /dz/) denote a single consonant and when they denote a +% sequence of two consonants. By default, however, Zinoviev (like +% Boshnakov) assumes that дж /dzh/ is a single consonant and hyphenates +% accordingly. +% +% Third, the rules of Zinoviev disable some cases of unpleasant +% hyphenations: +% +% 1. In a consonant sequence like тст /tst/, the two equal consonants т +% /t/ are separated. For example братст-во /bratst-vo/ is forbidden +% while братс-тво /brats-tvo/ and брат-ство /brat-stvo/ are +% permitted. +% 2. The hyphenation is forbidden after a sonorant consonant following +% an obstruent consonant. For example отм-ра /otm-ra/ is forbidden +% and от-мра /ot-mra/ is permitted. +% 3. The hyphenation separates two consecutive kindred voiced/voiceless +% consonants. For example субп-родукт /subp-roduct/ is forbidden and +% суб-продукт /sub-product/ is permitted. +% +% At the start of his work on the Bulgarian hyphenation, Zinoviev had +% the opportunity to discuss the hyphenation with Svetla Koeva. He +% remembers that some cases of unpleasant hyphenation were suggested to +% him by Koeva. Unfortunately, he hasn't taken notes so now he doesn't +% know which cases of unpleasant hyphenation have been suggested to him +% by Koeva and which are his own findings. +% +% The present work +% ================ +% +% Motivation +% ---------- +% +% The present work was carried out on the initiative of the leader of +% the Bulgarian localisation team of Mozilla, who contacted Zinoviev, +% Boshnakov and the maintainers of the TeX hyphenation patterns.[^17] +% This work pursues the following main objectives: +% +% 1. to update the hyphenation patterns in accordance with the current +% hyphenation rules; +% 2. to generate the hyphenation patterns by a publicly available +% script; +% 3. to make the hyphenation patterns customisable; +% 4. to provide documentation for the future developers. +% +% [^16]: +% +% [^17]: +% +% The current official hyphenating rules for Bulgarian are rather +% liberal. Very often, in a long sequence of consonants we are +% permitted to split the word at any position, for example аген-т-с-т-во +% /agen-t-s-t-vo/. This is prone to many unusual and unexpected results +% that interrupt the attention of the reader or deceive his expectations +% during the movement of his eyes to the next line. On the other hand, +% in order to produce nice justified paragraphs there is no need for so +% many hyphenation possibilities. It would be sufficient even if only +% one possible separation between any two syllables was permitted. +% +% Therefore, it makes sense to use a more restrictive version of the +% Bulgarian hyphenation, one which eliminates the controversial cases of +% hyphenation. Only when typesetting a Bulgarian text in a very narrow +% newspaper column it will be appropriate to use a more liberal version. +% It should be noted that some specialised English dictionaries also +% separate the word-division positions into two categories – preferred +% positions and less recommended positions. +% +% There are two methods to determine the optimal division within a +% sequence of consonants between two vowels: +% +% * we can hyphenate according to the syllables in the word or +% * we can hyphenate morphologically. +% +% Hyphenation according to the syllables in the word +% -------------------------------------------------- +% +% Let us look at the properties of the Bulgarian syllables. All +% syllables have the following structure: +% +% > onset - nucleus - code +% +% The nucleus in Bulgarian is always a vowel. Both the onset and the +% code are (possibly empty) sequences of consonants. +% +% The Bulgarian syllables adhere to the Sonority Sequencing Principle. +% According to this principle, the consonants within the onset have +% raising sonority and the consonants within the code have decreasing +% sonority. +% +% Several grammar books agree that the following sonority scale is valid +% for Bulgarian: +% +% > voiceless obtrusive < voiced obtrusive < sonorant consonant < vowel +% +% According to the investigations of the author, the only exception to +% this law is due to the letter в /v/ which is a voiced obtrusive but it +% can be used also as a voiceless obtrusive. This exception is due to a +% spelling particularity of the Bulgarian language. Whenever the letter +% в /v/ seemingly violates the Sonority Sequencing Principle, in the +% spoken language this letter is read as ф /f/, that is as a voiceless +% obtrusive (for example the word отвсякъде /otvsyakade/ is read as +% отфсякъде /otfsyakade/).[^18] +% +% [^18]: No Primitive Slavonic word contains the phoneme ф /f/. +% Therefore, we can safely assume that in the Primitive Slavonic +% language the consonant ф /f/ was a positional variant of the consonant +% в /v/. +% +% The author has found that the sonorant consonants in Bulgarian have +% their own sonority scale: +% +% > м /m/ < н /n/ < л /l/ < р /r/ < й /y/ +% +% Only a few words such as жанр /zhanr/ and химн /himn/ violate this +% scale. Such words are always loan-words and their pronunciation is +% somewhat problematic for the native Bulgarian speakers. +% +% In addition to the Sonority Sequencing Principle, the consonant +% clusters within the Bulgarian syllable adhere to the following +% additional principles: +% +% 1. Both in the onset and in the code, the labial and dorsal plosives +% precede the coronal plosives and affricates. +% 2. If the onset or the code contains two plosives or affricates, then +% there are no fricatives between them. Few words with the Latin +% root 'text' are exceptions: контекст /kontekst/. +% 3. If the onset or the code contains two fricatives other than в /v/, +% then there are no plosives or affricates between them. +% 4. If the onset or the code contains two plosives or affricates, then +% they both have equal sonority (both are voiced, or both are +% voiceless). +% 5. If the onset or the code contains two fricatives other than в /v/, +% then they both have equal sonority (both are voiced, or both are +% voiceless). +% 6. Neither the onset, nor the code may contain two labial plosives, or +% two coronal plosives or affricates or two dorsal plosives. +% 7. Neither the onset, nor the code may contain two equal consonants +% with the exception of в /v/ (for example втвърди /vtvardi/).[^19] +% +% [^19]: Actually, the letter в /v/ is not a real exception because in +% all such cases this letter denotes two different consonants – в /v/ +% and ф /f/. Only in the Russian loan-word взвод /vzvod/ the two +% letters в /v/ denote a repeating consonant в /v/. +% +% From all these properties of the Bulgarian syllable we can deduce the +% following hyphenation rules: +% +% 1. In a sequence МК where М is a consonant with higher sonority than +% K, we are not permitted to hyphenate before М. Exception: when М +% is в /v/ and К is a voiceless consonant. +% 2. In a sequence КМ where М is a consonant with higher sonority than +% K, we are not permitted to hyphenate after М. +% 3. In a sequence KBT where K and T are plosives or affricates and B is +% fricative, we separate K from T. +% 4. In a sequence CKB where K is a plosive or affricate and C and B are +% fricatives other than в /v/, we separate C from B. +% 5. If in a consonant sequence a coronal plosive or affricate Т is +% followed by a labial or dorsal plosive К, then we separate Т from К. +% 6. If a consonant sequence contains two plosives or affricates, one +% voiced and one voiceless, then we separate them. +% 7. If a consonant sequence contains two fricatives other than в /v/, +% one voiced and one voiceless, then we separate them. +% 8. If a consonant sequence contains two labial plosives or two coronal +% plosives or affricates or two dorsal plosives then they are +% separated. +% 9. If a consonant sequence contains two equal consonants (not +% necessarily consecutive), then they are separated. +% +% With so many prohibitive rules, a question arises: if we apply all +% these rules, aren't we going to eliminate too many hyphenation +% possibilities? The answer is no. It can be demonstrated that between +% any two consecutive syllables at least one separation point will be +% permitted. +% +% +% Hyphenation according to the morphology +% --------------------------------------- +% +% Between 1983 and 2012 the official orthographic rules of the +% Bulgarian language forbade morphologically based hyphenation. After +% 2012 such hyphenation is permitted (but not obligatory). +% +% The most important case when it is very desirable to use +% morphologically based hyphenation is the case of the compound words. +% Divisions such as авток-луб /avtok-lub/ and вакуу-мапарат +% /vakuu-maparat/ are extremely irritating even if they are formally +% correct. Unfortunately, we do not have a vocabulary of the compound +% Bulgarian words that would permit us to produce rules for automated +% hyphenation. Therefore, the current Bulgarian hyphenation patterns do +% not attempt to apply morphological hyphenation to such words. +% +% Second in importance (but far more significant in terms of numbers) is +% the case with the word prefixes. While the eyes of the reader still +% look at the start of the word, the word is still unknown to him. At +% this point, it is very important not to deceive his expectations. For +% example, when the reader sees над- /nad-/ at the end of the line, he +% will expect that this is the prefix над- /nad-/ with semantics 'attain +% more than'. This expectation will be fooled if this wasn't really a +% prefix, but a deceiving (while formally correct) hyphenation of the +% word надремя /nadremya/ 'have dozed enough' where the real prefix is +% not над- /nad-/ but на- /na-/ with semantics 'achieve a state after +% accumulation'. Such hyphenation distracts the reader and makes the +% reading more difficult. +% +% Third in importance is the case with the word suffixes. With respect +% to the hyphenation rules we can divide the suffixes into three +% categories: +% +% 1. Suffixes starting with a vowel, for example -ар /-ar/. It is not +% appropriate to follow the morphology with such suffixes because +% this will contradict the whole hyphenation tradition of the +% Bulgarian language. For example крав-ар /krav-ar/ is unwarranted. +% 2. Suffixes starting with one consonant, for example -ка /-ka/. +% Usually with such suffixes the syllable boundary in the word +% coincides with morpheme boundary so no specific cares are +% necessary, for example кравар-ка /kravar-ka/. The exceptions are +% rare, for example: обек-тната /obek-tnata/ instead of обект-ната +% /obekt-nata/. +% 3. Suffixes starting with more than one consonant (-ски /-ski/, -ство +% /-stvo/). It is possible to use morphological hyphenation rules +% with such suffixes. +% +% Even if it is possible to use morphological hyphenation with the +% suffixes of the third category, it turns out, this is not as useful as +% it is with the case of the prefixes. When the eyes of the reader have +% reached this part of the word, the word is already more or less known +% to the reader. Therefore, at this point the morphological hyphenation +% does not provide any significant advantages in comparison to the +% simpler hyphenation based only on the syllables in the word. Consider +% for example the word геройс-тво /geroys-tvo/ with suffix -ство +% /-stvo/. When the reader sees геройс- /geroys-/ at the end of the +% line this will give him an early clue that the suffix of the word is +% -ство /-stvo/. Such non-morphological hyphenation does not deceive +% the expectations of the reader. On the contrary, it makes the reading +% easier because it gives clues to the reader about what follows on the +% next line. +% +% Because of these considerations, the current Bulgarian hyphenation +% patterns do not attempt to use morphological hyphenation with respect +% to the suffixes of the words. Though it would be useful to implement +% rules about the suffixes of the second cateogory. Hopefully, some +% future version will have such rules. +% +% Occasionally,[^20] a fourth morphological requirement is stated: that +% hyphenation should conform with the boundary between the word and the +% definitive articles -та /-ta/ and -те /-te/ (postfixed in Bulgarian). +% There is no need to pay attention to this rule because it seems to be +% satisfied by its own nature. The author has searched in a dictionary +% with over 860000 Bulgarian words for cases when the hyphenation rules +% would hyphenate badly with respect to the definitive article. He was +% unable to find even one such case with the hyphenation rules valid +% after 1983 and only about 10 cases with the rules valid before 1983 +% (one of them is живопи-ста /zhivopi-sta/ instead of живопис-та +% /zhivopis-ta/). +% +% One unavoidable characteristic of any morphologically based automated +% hyphenation is that it can create wrong hyphenations. Because of +% this, one useful option is to use the morphology in a safe way – to +% use it in order to forbid bad hyphenations but to create no new +% hyphenation possibilities solely on the basis of the morphology. +% +% Take for example the word дозрея /dozreya/ 'ripen fully'. According +% to the phonological rules, we should hyphenate it as доз-рея +% /doz-reya/. According to the morphology, however, we should hyphenate +% as до-зрея /do-zreyq/ because this word is formed with the prefix до- +% /do-/ with semantics 'complete or supplement' and this semantics would +% be lost if the reader sees доз- /doz-/ at the end of the line. +% Therefore, there are three methods to hyphenate this word: +% +% 1. доз-рея /doz-reya/ when morphology is not used; +% 2. до-зрея /do-zreya/ when morphology is fully used; +% 3. дозрея /dozreya/ (no hyphenation) when morphology is used in a safe +% way. +% +% The option to use the morphology in a safe way is very attractive when +% the software uses a smart line-breaking algorithm which can produce +% good results even with less hyphenation possibilities. TeX is one +% such software. It should be noted that this option does not eliminate +% too many hyphenation possibilities because the morpheme boundaries +% most of the time are also syllable boundaries. +% +% [^20]: Правописен и правоговорен наръчник. Състав. Иван Хаджов, +% Цв. Минков; Ред. Ив. Хаджов и др. София, Бълг. кн., 1945 +% +% The following are results of a statistics about the quality of the +% morphological rules (the number after the sign ± is the expected +% standard deviation of our estimations): +% +% With the option `--morphology`: +% +% * in 0.1% ±0.3% of the dictionary words the morphological patterns +% create very wrong hyphenation; +% * in 89.8% ±0.1% of the dictionary words the morphological patterns +% hyphenate identically with the case when no morphology patterns are +% used; +% * in 0.3% ±0.2% of the dictionary words the morphological patterns +% hyphenate differently in comparison to the case when no morphology +% patterns are used and the word is hyphenated in a way which +% contradicts the morphology; +% * in 0.6% ±0.1% of the dictionary words the morphological patterns +% hyphenate differently in comparison to the case when no morphology +% patterns are used and there is a possible hyphenation which is +% compatible with the word morphology but which is nevertheless +% forbidden by the morphology patterns. +% +% With the option `--safe-morphology`: +% +% * in 0% of the dictionary words the morphological patterns create very +% wrong hyphenation; +% * in 90.0% ±0.1% of the dictionary words the morphological patterns +% hyphenate identically with the case when no morphology patterns are +% used; +% * in 0.3% ±0.2% of the dictionary words the morphological patterns +% hyphenate differently in comparison to the case when no morphology +% patterns are used and the word is hyphenated in a way which +% contradicts the morphology; +% * in 0.6% ±0.1% of the dictionary words the morphological patterns +% hyphenate differently in comparison to the case when no morphology +% patterns are used and there is a possible hyphenation which is +% compatible both with the word morphology and with the syllable +% boundaries but which is nevertheless forbidden by the morphology +% patterns. +% +% Notice that the morphological patterns create a different hyphenation +% only in about 10% of the words. The following explanation can be +% given for this surprising fact. First, the natural evolution of the +% human languages tends to simplify the complex sequences of consonants. +% Therefore, no morpheme contains a complex sequence of consonants. And +% second, the Bulgarian orthography is morphological. This means that +% the morphemes are written according to their actual pronunciation, +% however the simplifications in the spoken languages which take place +% at the morpheme boundaries are not taken into account in the +% orthography. The independent operation of these two factors leads to +% the result that most of the time the morpheme boundaries coincide with +% the conventional syllable boundaries. The main exception to this is +% when a morpheme starts with a vowel, in this case its syllable will +% include one or more consonants of the preceeding morpheme. The second +% exception is when a morpheme ends with a vowel and the next morpheme +% starts with a sequence of two or more consonants. +% +% Usage of the script `hyph-bg.sh` +% -------------------------------- +% +% The `hyph-bg.sh` is all-in-one script which can generate both +% documentation (this text) and Bulgarian hyphenation patterns. When +% given the option `--help` the script gives short usage instructions: +% +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +% hyph-bg.sh --help +% Show this info +% hyph-bg.sh [--doc-html | --doc-latex | --doc-txt] +% Print documentation in various formats +% hyph-bg.sh [other options] +% Generate Bulgarian hyphenation patterns +% +% Options when generating hyphenation patterns: +% +% --standalone-tex +% Produce hyphenation patterns for TeX with \patterns{ ... }. +% +% --no-hyphen-mins +% Hyphenation patterns which do not require hyphen mins. +% Otherwise: both left and right hyphen mins should be set to 2. +% +% --safe-dz +% Do not try to guess whether DZ is a single consonant or not. +% Only use hyphenation which will be correct in both cases. +% +% --permissible +% Permit any formally correct hyphenation, including unnatural +% divisions, such as studen-tstvo. Useful for educational tools +% or when typesetting Bulgarian text in a very short column. +% +% --morphology +% Apply morphology when hyphenating, for example: za-dvizhvam. +% May hyphenate incorrectly in some cases. +% +% --safe-morphology +% Apply morphology when hyphenating. Never hyphenates incorrectly +% but may prohibit some correct hyphenations. +% +% --no-morphology +% Disregard the morphology. Default. +% +% --1945 +% Hyphenate according to the rules effective between 1945 and 1982 +% +% --1983 +% Hyphenate according to the rules effective between 1983 and 2011 +% +% --2012 +% Hyphenate according to the rules effective after 2012. Default. +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +% +% The following are the recommended ways to generate hyphenation +% patterns by this script: +% +% `hyph-bg.sh --standalone-tex --safe-morphology` +% : For TeX. Apply the morphology in a safe way when the software +% uses a smart line-breaking algorithm. +% +% `hyph-bg.sh` +% : For most other software. +% +% `hyph-bg.sh --no-hyphen-mins` +% : The current versions of Mozilla (as of 2017) seem to ignore the +% hyphen mins in words that contain a dash. +% +% `hyph-bg.sh --morphology` +% : For professional typography with human proof-reader. +% +% `hyph-bg.sh --permissible` +% : For educational tools and online dictionaries which can show only one +% kind of hyphenation. +% +% Notice that some specialised English dictionaries separate the +% word-division positions into two categories – preferred positions and +% less recommended positions. It would be best if the Bulgarian online +% dictionaries could do the same. For example hyphen "-" can be used to +% display the preferred positions and dot "." – the less recommended +% positions. If a word-division position is permitted only by the +% patterns of `hyph-bg.sh --permissible`, then this position is less +% recommended. +% + +\message{Bulgarian hyphenation patterns (options: --safe-morphology --standalone-tex, version 21 October 2017)} diff --git a/tex/context/patterns/common/lang-de.rme b/tex/context/patterns/common/lang-de.rme index d1b549fc7..241a9312c 100644 --- a/tex/context/patterns/common/lang-de.rme +++ b/tex/context/patterns/common/lang-de.rme @@ -1,23 +1,64 @@ % generated by mtxrun --script pattern --convert -% dehyphn-x-2014-05-21.pat - -\message{German Hyphenation Patterns (Reformed Orthography, 2006) `dehyphn-x' 2014-05-21 (WL)} - -% TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung +% title: German Hyphenation Patterns (Reformed Orthography, 2006) +% +% notice: TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung +% +% version: 2018-03-31 +% +% authors: +% - +% name: Deutschsprachige Trennmustermannschaft +% contact: trennmuster@dante.de % +% copyright: Copyright (c) 2013-2018 +% Stephan Hennig, Werner Lemberg, Günter Milde, +% Sander van Geloven, Georg Pfeiffer, Gisbert W. Selke, +% Tobias Wendorf % -% Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013, 2014 Werner Lemberg +% licence: +% name: MIT +% url: http://opensource.org/licenses/mit-license.php +% text: > +% Permission is hereby granted, free of charge, to any person +% obtaining a copy of this software and associated documentation +% files (the “Software”), to deal in the Software without +% restriction, including without limitation the rights to use, +% copy, modify, merge, publish, distribute, sublicense, and/or +% sell copies of the Software, and to permit persons to whom the +% Software is furnished to do so, subject to the following +% conditions: % -% This program can be redistributed and/or modified under the terms -% of the LaTeX Project Public License Distributed from CTAN -% archives in directory macros/latex/base/lppl.txt; either -% version 1 of the License, or any later version. +% The above copyright notice and this permission notice shall be +% included in all copies or substantial portions of the Software. % +% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +% OTHER DEALINGS IN THE SOFTWARE. % -% The word list is available from +% source: http://repo.or.cz/w/wortliste.git?a=commit;h=8b9a428c271e064f0047a364c532308f0fd4051f % -% http://repo.or.cz/w/wortliste.git?a=commit;h=3a97953c0ddd099a1785ea7927cbf24e639090b0 +% language: +% name: German, reformed spelling +% tag: de-1996 +% +% hyphenmins: +% generation: +% left: 2 +% right: 2 +% typesetting: +% left: 2 +% right: 2 +% +% =========================================================================== + +\message{German Hyphenation Patterns (Reformed Orthography, 2006) `dehyphn-x' 2018-03-31 (WL)} + % % The used patgen parameters are % diff --git a/tex/context/patterns/common/lang-deo.rme b/tex/context/patterns/common/lang-deo.rme index c4fed1009..87bf0b9ae 100644 --- a/tex/context/patterns/common/lang-deo.rme +++ b/tex/context/patterns/common/lang-deo.rme @@ -1,23 +1,64 @@ % generated by mtxrun --script pattern --convert -% dehypht-x-2014-05-21.pat - -\message{German Hyphenation Patterns (Traditional Orthography) `dehypht-x' 2014-05-21 (WL)} - -% TeX-Trennmuster für die traditionelle deutsche Rechtschreibung +% title: German Hyphenation Patterns (Traditional Orthography) +% +% notice: TeX-Trennmuster für die traditionelle deutsche Rechtschreibung +% +% version: 2018-03-31 +% +% authors: +% - +% name: Deutschsprachige Trennmustermannschaft +% contact: trennmuster@dante.de % +% copyright: Copyright (c) 2013-2018 +% Stephan Hennig, Werner Lemberg, Günter Milde, +% Sander van Geloven, Georg Pfeiffer, Gisbert W. Selke, +% Tobias Wendorf % -% Copyright (C) 2008, 2009, 2011, 2012, 2013, 2014 Werner Lemberg +% licence: +% name: MIT +% url: http://opensource.org/licenses/mit-license.php +% text: > +% Permission is hereby granted, free of charge, to any person +% obtaining a copy of this software and associated documentation +% files (the “Software”), to deal in the Software without +% restriction, including without limitation the rights to use, +% copy, modify, merge, publish, distribute, sublicense, and/or +% sell copies of the Software, and to permit persons to whom the +% Software is furnished to do so, subject to the following +% conditions: % -% This program can be redistributed and/or modified under the terms -% of the LaTeX Project Public License Distributed from CTAN -% archives in directory macros/latex/base/lppl.txt; either -% version 1 of the License, or any later version. +% The above copyright notice and this permission notice shall be +% included in all copies or substantial portions of the Software. % +% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +% OTHER DEALINGS IN THE SOFTWARE. % -% The word list is available from +% source: http://repo.or.cz/w/wortliste.git?a=commit;h=8b9a428c271e064f0047a364c532308f0fd4051f % -% http://repo.or.cz/w/wortliste.git?a=commit;h=3a97953c0ddd099a1785ea7927cbf24e639090b0 +% language: +% name: German, traditional spelling +% tag: de-1901 +% +% hyphenmins: +% generation: +% left: 2 +% right: 2 +% typesetting: +% left: 2 +% right: 2 +% +% =========================================================================== + +\message{German Hyphenation Patterns (Traditional Orthography) `dehypht-x' 2018-03-31 (WL)} + % % The used patgen parameters are % diff --git a/tex/context/patterns/common/lang-fr.rme b/tex/context/patterns/common/lang-fr.rme index 2ee36d062..7ca6aa035 100644 --- a/tex/context/patterns/common/lang-fr.rme +++ b/tex/context/patterns/common/lang-fr.rme @@ -1,12 +1,15 @@ % generated by mtxrun --script pattern --convert -% copyright: Daniel Flipo, Bernard Gaulle 1994-2002 +% copyright: Daniel Flipo and Bernard Gaulle 1994-2002, Arthur Reutenauer 2016 % title: French hyphenation patterns -% version: V2.12 2002/12/11 +% version: V2.13 2016/05/12 +% language: +% name: French +% tag: fr % notice: > % This file is part of the hyph-utf8 package. % See http://www.hyphenation.org for more information. -% license: +% licence: % name: MIT % url: https://opensource.org/licenses/MIT % text: > diff --git a/tex/context/patterns/common/lang-la.rme b/tex/context/patterns/common/lang-la.rme index 9929f463e..98435331f 100644 --- a/tex/context/patterns/common/lang-la.rme +++ b/tex/context/patterns/common/lang-la.rme @@ -1,34 +1,78 @@ % generated by mtxrun --script pattern --convert -% -% ********** hyph-la.tex ************* -% -% Copyright 1999-2014 Claudio Beccari -% [latin hyphenation patterns] -% -% ----------------------------------------------------------------- -% IMPORTANT NOTICE: -% -% This program can be redistributed and/or modified under the terms -% of the LaTeX Project Public License Distributed from CTAN -% archives in directory macros/latex/base/lppl.txt; either -% version 1 of the License, or any later version. -% ----------------------------------------------------------------- -% +% title: Hyphenation patterns for modern and medieval Latin +% copyright: Copyright (c) 1999-2016 Claudio Beccari +% e-mail claudio dot beccari at gmail dot com +% notice: This file is part of the hyph-utf8 package. +% See http://www.hyphenation.org for more information. +% language: +% name: Latin +% tag: la +% version: 3.201 2016-08-28 +% licence: +% - This file is available under any of the following licences: +% - +% name: MIT +% url: https://opensource.org/licenses/MIT +% text: > +% Permission is hereby granted, free of charge, to any person +% obtaining a copy of this software and associated documentation +% files (the “Software”), to deal in the Software without +% restriction, including without limitation the rights to use, +% copy, modify, merge, publish, distribute, sublicense, and/or sell +% copies of the Software, and to permit persons to whom the +% Software is furnished to do so, subject to the following +% conditions: +% +% The above copyright notice and this permission notice shall be +% included in all copies or substantial portions of the Software. +% +% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +% OTHER DEALINGS IN THE SOFTWARE. +% - +% name: LPPL +% version: 1 +% or_later: true +% url: https://latex-project.org/lppl/ +% changes: +% - +% date: 1999 +% version: 1.0 +% author: Claudio Beccari +% description: First public release +% - +% date: 2007-04-16 +% version: 3.1 +% author: Claudio Beccari +% - +% date: 2010-05-31 +% author: Claudio Beccari +% description: Removal of OT1 support +% - +% date: 2010-06-01 +% version: 3.2 +% author: Claudio Beccari +% description: Removal of pattern 2'2 +% - +% date: 2016-08-28 +% version: 3.201 +% author: Claudio Beccari +% description: updated header with MIT licence notice; +% added few missing patterns +% +% ========================================== % Patterns for the latin language mainly in modern spelling % (u when u is needed and v when v is needed); medieval spelling % with the ligatures \ae and \oe and the (uncial) lowercase `v' % written as a `u' is also supported; apparently there is no conflict % between the patterns of modern Latin and those of medieval Latin. % -% -% Prepared by Claudio Beccari -% Politecnico di Torino -% Torino, Italy -% e-mail claudio dot beccari at gmail.com -% -% \versionnumber{3.2a} \versiondate{2014/06/04} -% % For more information please read the babel-latin documentation. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -98,11 +142,7 @@ % Read the documentation coming with the discription of the Latin language % interface of Babel in order to see the shortcuts and the facilities % introduced in order to facilitate the insertion of "compound word marks" -% which are very useful for inserting etimological break points. +% which are very useful for inserting etymological break points. % % Happy Latin and multilingual typesetting! % -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -% -% \message{Latin Hyphenation Patterns Version 3.2a <2014/06/04>} -% diff --git a/tex/context/patterns/common/lang-th.rme b/tex/context/patterns/common/lang-th.rme index 306a3d972..69b66fa75 100644 --- a/tex/context/patterns/common/lang-th.rme +++ b/tex/context/patterns/common/lang-th.rme @@ -1,21 +1,20 @@ % generated by mtxrun --script pattern --convert -% Thai hyphenation patterns -% -% Copyright 2012-2013 Theppitak Karoonboonyanan -% -% This work may be distributed and/or modified under the -% conditions of the LaTeX Project Public License, either version 1.3 -% of this license or (at your option) any later version. -% The latest version of this license is in -% http://www.latex-project.org/lppl.txt -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. -% -% This work has the LPPL maintenance status `maintained'. -% -% The Current Maintainer of this work is Theppitak Karoonboonyanan. -% -% http://linux.thai.net/projects/thailatex -% http://linux.thai.net/svn/software/thailatex/trunk +% title: Hyphenation patterns for Thai +% copyright: Copyright 2012-2013 Theppitak Karoonboonyanan +% notice: This file is part of the hyph-utf8 package. +% See http://www.hyphenation.org for more information. +% language: +% name: Thai +% tag: th +% licence: +% name: LPPL +% version: 1.3 +% or_later: true +% status: maintained +% maintainer: Theppitak Karoonboonyanan +% url: https://latex-project.org/lppl/ +% ========================================== +% https://linux.thai.net/projects/thailatex +% https://github.com/tlwg/thailatex % diff --git a/tex/context/patterns/mkii/lang-agr.pat b/tex/context/patterns/mkii/lang-agr.pat index 521cdf3b6..4064ae883 100644 --- a/tex/context/patterns/mkii/lang-agr.pat +++ b/tex/context/patterns/mkii/lang-agr.pat @@ -2,7 +2,7 @@ % for comment and copyright, see lang-agr.rme -% used: ' ʼ ΐ ά έ ή ί ΰ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω ϊ ϋ ό ύ ώ ϲ ἀ ἁ ἂ ἃ ἄ ἅ ἆ ἇ ἐ ἑ ἒ ἓ ἔ ἕ ἠ ἡ ἢ ἣ ἤ ἥ ἦ ἧ ἰ ἱ ἲ ἳ ἴ ἵ ἶ ἷ ὀ ὁ ὂ ὃ ὄ ὅ ὐ ὑ ὒ ὓ ὔ ὕ ὖ ὗ ὠ ὡ ὢ ὣ ὤ ὥ ὦ ὧ ὰ ά ὲ έ ὴ ή ὶ ί ὸ ό ὺ ύ ὼ ώ ᾀ ᾁ ᾂ ᾃ ᾄ ᾅ ᾆ ᾇ ᾐ ᾑ ᾒ ᾓ ᾔ ᾕ ᾖ ᾗ ᾠ ᾡ ᾢ ᾣ ᾤ ᾥ ᾦ ᾧ ᾲ ᾳ ᾴ ᾶ ᾷ ᾽ ᾿ ῂ ῃ ῄ ῆ ῇ ῒ ΐ ῖ ῗ ῢ ΰ ῤ ῥ ῦ ῧ ῲ ῳ ῴ ῶ ῷ +% used: ' ʼ ΐ ά έ ή ί ΰ α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω ϊ ϋ ό ύ ώ ϐ ϲ ἀ ἁ ἂ ἃ ἄ ἅ ἆ ἇ ἐ ἑ ἒ ἓ ἔ ἕ ἠ ἡ ἢ ἣ ἤ ἥ ἦ ἧ ἰ ἱ ἲ ἳ ἴ ἵ ἶ ἷ ὀ ὁ ὂ ὃ ὄ ὅ ὐ ὑ ὒ ὓ ὔ ὕ ὖ ὗ ὠ ὡ ὢ ὣ ὤ ὥ ὦ ὧ ὰ ά ὲ έ ὴ ή ὶ ί ὸ ό ὺ ύ ὼ ώ ᾀ ᾁ ᾂ ᾃ ᾄ ᾅ ᾆ ᾇ ᾐ ᾑ ᾒ ᾓ ᾔ ᾕ ᾖ ᾗ ᾠ ᾡ ᾢ ᾣ ᾤ ᾥ ᾦ ᾧ ᾲ ᾳ ᾴ ᾶ ᾷ ᾽ ᾿ ῂ ῃ ῄ ῆ ῇ ῒ ΐ ῖ ῗ ῢ ΰ ῤ ῥ ῦ ῧ ῲ ῳ ῴ ῶ ῷ \patterns{ α1 @@ -283,6 +283,7 @@ ο3υί ο3υῖ 4β. +4ϐ. 4γ. 4δ. 4ζ. @@ -302,6 +303,7 @@ 4ψ. 4' 4β' +4ϐ' 4γ' 4δ' 4ζ' @@ -319,6 +321,7 @@ 4χ' 4ψ' .β4 +.ϐ4 .γ4 .δ4 .ζ4 @@ -336,6 +339,7 @@ .χ4 .ψ4 2β1β +2ϐ1ϐ 2γ1γ 2δ1δ 2ζ1ζ @@ -353,17 +357,29 @@ 2χ1χ 2ψ1ψ 2β1γ +2ϐ1γ 2β1ζ +2ϐ1ζ 2β1θ +2ϐ1θ 2β1κ +2ϐ1κ 2β1ξ +2ϐ1ξ 2β1π +2ϐ1π 2β1σ +2ϐ1σ 2β1τ +2ϐ1τ 2β1φ +2ϐ1φ 2β1χ +2ϐ1χ 2β1ψ +2ϐ1ψ 2γ1β +2γ1ϐ 2γ1ζ 2γ1θ 2γ1κ @@ -375,6 +391,7 @@ 2γ1χ 2γ1ψ 2δ1β +2δ1ϐ 2δ1γ 2δ1ζ 2δ1θ @@ -388,6 +405,7 @@ 2δ1χ 2δ1ψ 2ζ1β +2ζ1ϐ 2ζ1γ 2ζ1δ 2ζ1θ @@ -404,6 +422,7 @@ 2ζ1χ 2ζ1ψ 2θ1β +2θ1ϐ 2θ1γ 2θ1δ 2θ1ζ @@ -416,6 +435,7 @@ 2θ1χ 2θ1ψ 2κ1β +2κ1ϐ 2κ1γ 2κ1δ 2κ1ζ @@ -427,6 +447,7 @@ 2κ1χ 2κ1ψ 2λ1β +2λ1ϐ 2λ1γ 2λ1δ 2λ1ζ @@ -443,6 +464,7 @@ 2λ1χ 2λ1ψ 2μ1β +2μ1ϐ 2μ1γ 2μ1δ 2μ1ζ @@ -458,6 +480,7 @@ 2μ1χ 2μ1ψ 2ν1β +2ν1ϐ 2ν1γ 2ν1δ 2ν1ζ @@ -475,6 +498,7 @@ 2ν1χ 2ν1ψ 2ξ1β +2ξ1ϐ 2ξ1γ 2ξ1δ 2ξ1ζ @@ -491,6 +515,7 @@ 2ξ1χ 2ξ1ψ 2π1β +2π1ϐ 2π1γ 2π1δ 2π1ζ @@ -502,6 +527,7 @@ 2π1χ 2π1ψ 2ρ1β +2ρ1ϐ 2ρ1γ 2ρ1δ 2ρ1ζ @@ -525,6 +551,7 @@ 2σ1ρ 2σ1ψ 2τ1β +2τ1ϐ 2τ1γ 2τ1δ 2τ1ζ @@ -537,6 +564,7 @@ 2τ1χ 2τ1ψ 2φ1β +2φ1ϐ 2φ1γ 2φ1δ 2φ1ζ @@ -548,6 +576,7 @@ 2φ1χ 2φ1ψ 2χ1β +2χ1ϐ 2χ1γ 2χ1δ 2χ1ζ @@ -559,6 +588,7 @@ 2χ1φ 2χ1ψ 2ψ1β +2ψ1ϐ 2ψ1γ 2ψ1δ 2ψ1ζ @@ -575,10 +605,15 @@ 2ψ1φ 2ψ1χ 4βδ' +4ϐδ' 4βλ' +4ϐλ' 4βμ' +4ϐμ' 4βν' +4ϐν' 4βρ' +4ϐρ' 4γδ' 4γλ' 4γμ' @@ -588,6 +623,7 @@ 4δν' 4δρ' 4ζβ' +4ζϐ' 4θλ' 4λμ' 4θν' @@ -604,6 +640,7 @@ 4πρ' 4πτ' 4σβ' +4σϐ' 4σγ' 4σδ' 4σθ' @@ -640,7 +677,10 @@ ἀμπαλι2ν1 ἀμφί2σ1β ἀμφί2σ1β +ἀμφί2σ1ϐ +ἀμφί2σ1ϐ ἀμφι2σ1β +ἀμφι2σ1ϐ ἀμφί2σ1ω ἀμφί2σ1ω ἀμφι2σ1ώ @@ -871,7 +911,10 @@ ἀ2ν1απαυδ ἀ2ν1απόβ ἀ2ν1απόβ +ἀ2ν1απόϐ +ἀ2ν1απόϐ ἀ2ν1αποβ +ἀ2ν1αποϐ ἀ2ν1απόγ ἀ2ν1απόγ ἀ2ν1απογ @@ -950,6 +993,8 @@ ἀ2ν1αστεί ἀ3ν2αστείβ ἀ3ν2αστείβ +ἀ3ν2αστείϐ +ἀ3ν2αστείϐ ἀ3ν2άστειρ ἀ3ν2άστειρ ἀ3ν2αστείρ @@ -1168,7 +1213,10 @@ ἀ2ν1ελύτρ ἀ2ν1έμβ ἀ2ν1έμβ +ἀ2ν1έμϐ +ἀ2ν1έμϐ ἀ2ν1εμβ +ἀ2ν1εμϐ ἀ2ν1έμετ ἀ2ν1έμετ ἀ2ν1εμέτ @@ -1524,13 +1572,22 @@ ἀ3ν2ολο ἀ2ν1ομβρί ἀ2ν1ομβρί +ἀ2ν1ομϐρί +ἀ2ν1ομϐρί ἀ2ν1ομβρῖ +ἀ2ν1ομϐρῖ ἄ2ν1ομβρο +ἄ2ν1ομϐρο ἀ2ν1όμβρο ἀ2ν1όμβρο +ἀ2ν1όμϐρο +ἀ2ν1όμϐρο ἀ2ν1όμβρω ἀ2ν1όμβρω +ἀ2ν1όμϐρω +ἀ2ν1όμϐρω ἄ2ν1ομβρα +ἄ2ν1ομϐρα ἀ2ν1ομήλ ἀ2ν1ομήλ ἀ2ν1ομηλ @@ -1715,6 +1772,7 @@ .γερα2σ1φ .δα2σ1π .διαμφι2σ1β +.διαμφι2σ1ϐ .διέ2κ1ρο .διέ2κ1ρο .διε2κ1ρό @@ -1924,7 +1982,10 @@ δύ3σ2εο. .δυσεί2σ1β .δυσεί2σ1β +.δυσεί2σ1ϐ +.δυσεί2σ1ϐ .δυσει2σ1β +.δυσει2σ1ϐ .δυσέ2κ1 .δυσέ2κ1 .δυσε2κ1 @@ -2178,6 +2239,8 @@ ἐ3κ2ρύψ ἐ3κ2ρύβ ἐ3κ2ρύβ +ἐ3κ2ρύϐ +ἐ3κ2ρύϐ ἐ3κ2ρύφ ἐ3κ2ρύφ ἐ3κ2ρυσ @@ -2461,6 +2524,7 @@ ἐπέ2κ1τρ ἐπε2ξ1 ἐπε2σ1β +ἐπε2σ1ϐ ἐπιπρό2σ1θ ἐπιπρό2σ1θ ἐπιπρο2σ1θ @@ -2563,7 +2627,10 @@ .κυνό2σ1α .κυνό2σ1β .κυνό2σ1β +.κυνό2σ1ϐ +.κυνό2σ1ϐ .κυνο2σ1β +.κυνο2σ1ϐ .κυνό2σ1ο .κυνό2σ1ο .κυνο2σ1ο @@ -2760,7 +2827,10 @@ .προ2σ1 .προ3σ2άβ .προ3σ2άβ +.προ3σ2άϐ +.προ3σ2άϐ .προ3σ2αβ +.προ3σ2αϐ .προσει2σ1 .προ3σ2εί .προ3σ2εί diff --git a/tex/context/patterns/mkii/lang-bg.pat b/tex/context/patterns/mkii/lang-bg.pat index 2a0a8a0f1..ceba66813 100644 --- a/tex/context/patterns/mkii/lang-bg.pat +++ b/tex/context/patterns/mkii/lang-bg.pat @@ -2,1666 +2,6892 @@ % for comment and copyright, see lang-bg.rme -% used: а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ь ю я +% used: а б в г д е ж з и й к л м н о п р с т у ф х ц ч ш щ ъ ю я \patterns{ -1а1 -1б1 -1в1 -1г1 -1д1 -1е1 -1ж1 -1з1 -1и1 -1й1 -1к1 -1л1 -1м1 -1н1 -1о1 -1п1 -1р1 -1с1 -1т1 -1у1 -1ф1 -1х1 -1ц1 -1ч1 -1ш1 -1щ1 -1ъ1 -0ь0 -1ю1 -1я1 -б4а -б4е -б4и -б4о -б4у -б4ъ -б4ю -б4я -в4а -в4е -в4и -в4о -в4у -в4ъ -в4ю -в4я -г4а -г4е -г4и -г4о -г4у -г4ъ -г4ю -г4я -д4а -д4е -д4и -д4о -д4у -д4ъ -д4ю -д4я -ж4а -ж4е -ж4и -ж4о -ж4у -ж4ъ -ж4ю -ж4я -з4а -з4е -з4и -з4о -з4у -з4ъ -з4ю -з4я -й4а -й4е -й4и -й4о -й4у -й4ъ -й4ю -й4я -к4а -к4е -к4и -к4о -к4у -к4ъ -к4ю -к4я -л4а -л4е -л4и -л4о -л4у -л4ъ -л4ю -л4я -м4а -м4е -м4и -м4о -м4у -м4ъ -м4ю -м4я -н4а -н4е -н4и -н4о -н4у -н4ъ -н4ю -н4я -п4а -п4е -п4и -п4о -п4у -п4ъ -п4ю -п4я -р4а -р4е -р4и -р4о -р4у -р4ъ -р4ю -р4я -с4а -с4е -с4и -с4о -с4у -с4ъ -с4ю -с4я -т4а -т4е -т4и -т4о -т4у -т4ъ -т4ю -т4я -ф4а -ф4е -ф4и -ф4о -ф4у -ф4ъ -ф4ю -ф4я -х4а -х4е -х4и -х4о -х4у -х4ъ -х4ю -х4я -ц4а -ц4е -ц4и -ц4о -ц4у -ц4ъ -ц4ю -ц4я -ч4а -ч4е -ч4и -ч4о -ч4у -ч4ъ -ч4ю -ч4я -ш4а -ш4е -ш4и -ш4о -ш4у -ш4ъ -ш4ю -ш4я -щ4а -щ4е -щ4и -щ4о -щ4у -щ4ъ -щ4ю -щ4я -ь4а -ь4е -ь4и -ь4о -ь4у -ь4ъ -ь4ю -ь4я +.антиа4 +.антиб4 +.антив4 +.антиг4 +.антид4 +.антие4 +.антиж4 +.антиз4 +.антии4 +.антий4 +.антик4 +.антил4 +.антим4 +.антин4 +.антио4 +.антип4 +.антир4 +.антис4 +.антит4 +.антиу4 +.антиф4 +.антих4 +.антиц4 +.антиш4 +.антищ4 +.антиъ4 +.антию4 +.антия4 +.бб8 +.бв8 +.бг8 +.бд8 +.бж8 +.бз8 +.бк8 +.бл8 +.бм8 +.бн8 +.бп8 +.бр8 +.бс8 +.бт8 +.бф8 +.бх8 +.бц8 +.бч8 +.бш8 +.бщ8 +.вб8 +.вбб8 +.вбв8 +.вбг8 +.вбд8 +.вбж8 +.вбз8 +.вбк8 +.вбл8 +.вбм8 +.вбн8 +.вбп8 +.вбр8 +.вбс8 +.вбт8 +.вбф8 +.вбх8 +.вбц8 +.вбч8 +.вбш8 +.вбщ8 +.вв8 +.ввб8 +.ввв8 +.ввг8 +.ввд8 +.ввж8 +.ввз8 +.ввк8 +.ввл8 +.ввм8 +.ввн8 +.ввп8 +.ввр8 +.ввс8 +.ввт8 +.ввф8 +.ввх8 +.ввц8 +.ввч8 +.ввш8 +.ввщ8 +.вг8 +.вгб8 +.вгв8 +.вгг8 +.вгд8 +.вгж8 +.вгз8 +.вгк8 +.вгл8 +.вгм8 +.вгн8 +.вгп8 +.вгр8 +.вгс8 +.вгт8 +.вгф8 +.вгх8 +.вгц8 +.вгч8 +.вгш8 +.вгщ8 +.вд8 +.вдб8 +.вдв8 +.вдг8 +.вдд8 +.вдж8 +.вдз8 +.вдк8 +.вдл8 +.вдм8 +.вдн8 +.вдп8 +.вдр8 +.вдс8 +.вдт8 +.вдф8 +.вдх8 +.вдц8 +.вдч8 +.вдш8 +.вдщ8 +.вж8 +.вжб8 +.вжв8 +.вжг8 +.вжд8 +.вжж8 +.вжз8 +.вжк8 +.вжл8 +.вжм8 +.вжн8 +.вжп8 +.вжр8 +.вжс8 +.вжт8 +.вжф8 +.вжх8 +.вжц8 +.вжч8 +.вжш8 +.вжщ8 +.вз8 +.взб8 +.взв8 +.взг8 +.взд8 +.взж8 +.взз8 +.взк8 +.взл8 +.взм8 +.взн8 +.взп8 +.взр8 +.взс8 +.взт8 +.взф8 +.взх8 +.взц8 +.взч8 +.взш8 +.взщ8 +.вк8 +.вкб8 +.вкв8 +.вкг8 +.вкд8 +.вкж8 +.вкз8 +.вкк8 +.вкл8 +.вкм8 +.вкн8 +.вкп8 +.вкр8 +.вкс8 +.вкт8 +.вкф8 +.вкх8 +.вкц8 +.вкч8 +.вкш8 +.вкщ8 +.вл8 +.влб8 +.влв8 +.влг8 +.влд8 +.влж8 +.влз8 +.влк8 +.влл8 +.влм8 +.влн8 +.влп8 +.влр8 +.влс8 +.влт8 +.влф8 +.влх8 +.влц8 +.влч8 +.влш8 +.влщ8 +.вм8 +.вмб8 +.вмв8 +.вмг8 +.вмд8 +.вмж8 +.вмз8 +.вмк8 +.вмл8 +.вмм8 +.вмн8 +.вмп8 +.вмр8 +.вмс8 +.вмт8 +.вмф8 +.вмх8 +.вмц8 +.вмч8 +.вмш8 +.вмщ8 +.вн8 +.внб8 +.внв8 +.внг8 +.внд8 +.внж8 +.внз8 +.внк8 +.внл8 +.внм8 +.внн8 +.внп8 +.внр8 +.внс8 +.внт8 +.внф8 +.внх8 +.внц8 +.внч8 +.внш8 +.внщ8 +.вп8 +.впб8 +.впв8 +.впг8 +.впд8 +.впж8 +.впз8 +.впк8 +.впл8 +.впм8 +.впн8 +.впп8 +.впр8 +.впс8 +.впт8 +.впф8 +.впх8 +.впц8 +.впч8 +.впш8 +.впщ8 +.вр8 +.врб8 +.врв8 +.врг8 +.врд8 +.врж8 +.врз8 +.врк8 +.врл8 +.врм8 +.врн8 +.врп8 +.врр8 +.врс8 +.врт8 +.врф8 +.врх8 +.врц8 +.врч8 +.врш8 +.врщ8 +.вс8 +.всб8 +.всв8 +.всг8 +.всд8 +.всж8 +.всз8 +.вск8 +.всл8 +.всм8 +.всн8 +.всп8 +.вср8 +.всс8 +.вст8 +.всф8 +.всх8 +.всц8 +.всч8 +.всш8 +.всщ8 +.вт8 +.втб8 +.втв8 +.втг8 +.втд8 +.втж8 +.втз8 +.втк8 +.втл8 +.втм8 +.втн8 +.втп8 +.втр8 +.втс8 +.втт8 +.втф8 +.втх8 +.втц8 +.втч8 +.втш8 +.втщ8 +.вф8 +.вфб8 +.вфв8 +.вфг8 +.вфд8 +.вфж8 +.вфз8 +.вфк8 +.вфл8 +.вфм8 +.вфн8 +.вфп8 +.вфр8 +.вфс8 +.вфт8 +.вфф8 +.вфх8 +.вфц8 +.вфч8 +.вфш8 +.вфщ8 +.вх8 +.вхб8 +.вхв8 +.вхг8 +.вхд8 +.вхж8 +.вхз8 +.вхк8 +.вхл8 +.вхм8 +.вхн8 +.вхп8 +.вхр8 +.вхс8 +.вхт8 +.вхф8 +.вхх8 +.вхц8 +.вхч8 +.вхш8 +.вхщ8 +.вц8 +.вцб8 +.вцв8 +.вцг8 +.вцд8 +.вцж8 +.вцз8 +.вцк8 +.вцл8 +.вцм8 +.вцн8 +.вцп8 +.вцр8 +.вцс8 +.вцт8 +.вцф8 +.вцх8 +.вцц8 +.вцч8 +.вцш8 +.вцщ8 +.вч8 +.вчб8 +.вчв8 +.вчг8 +.вчд8 +.вчж8 +.вчз8 +.вчк8 +.вчл8 +.вчм8 +.вчн8 +.вчп8 +.вчр8 +.вчс8 +.вчт8 +.вчф8 +.вчх8 +.вчц8 +.вчч8 +.вчш8 +.вчщ8 +.вш8 +.вшб8 +.вшв8 +.вшг8 +.вшд8 +.вшж8 +.вшз8 +.вшк8 +.вшл8 +.вшм8 +.вшн8 +.вшп8 +.вшр8 +.вшс8 +.вшт8 +.вшф8 +.вшх8 +.вшц8 +.вшч8 +.вшш8 +.вшщ8 +.вщ8 +.вщб8 +.вщв8 +.вщг8 +.вщд8 +.вщж8 +.вщз8 +.вщк8 +.вщл8 +.вщм8 +.вщн8 +.вщп8 +.вщр8 +.вщс8 +.вщт8 +.вщф8 +.вщх8 +.вщц8 +.вщч8 +.вщш8 +.вщщ8 +.въ2за4 +.въ2зб4 +.въ2зв4 +.въ2зг4 +.въ2зд4 +.въ2зе4 +.въ5з4ел +.въ5з4е5ла +.въ5з4е5лът +.въ2зж4 +.въ2зз4 +.въ2зи4 +.въ2зй4 +.въ2зк4 +.въ2зл4 +.въ2зм4 +.въ2зн4 +.въ2зо4 +.въ2зп4 +.въ2зр4 +.въ2зс4 +.въ2зт4 +.въ2зу4 +.въ2зф4 +.въ2зх4 +.въ2зц4 +.въ2зч4 +.въ2зш4 +.въ2зщ4 +.въ2зъ4 +.въ2зю4 +.въ2зя4 +.гб8 +.гв8 +.гг8 +.гд8 +.гж8 +.гз8 +.гк8 +.гл8 +.гм8 +.гн8 +.гп8 +.гр8 +.гс8 +.гт8 +.гф8 +.гх8 +.гц8 +.гч8 +.гш8 +.гщ8 +.дб8 +.дв8 +.дг8 +.дд8 +.дж8 +.дз8 +.дк8 +.дл8 +.дм8 +.дн8 +.доа4 +.доб4 +.до4б5лест +.до4б5р +.до4б6ро +.дов4 +.дог4 +.до4г5м +.дод4 +.дое4 +.дож4 +.доз4 +.дои4 +.док4 +.до4к5л +.до4к5т +.дол4 +.до4л5н +.до4л5ч +.дом4 +.дон4 +.до4н5г +.до4н5д +.до4н5ж +.до4н5к +.до4н5с +.до4н5ч +.доо4 +.доп4 +.дор4 +.дос4 +.до4с5то +.дот4 +.доу4 +.доф4 +.дох4 +.доц4 +.доч4 +.дош4 +.дощ4 +.доъ4 +.дою4 +.доя4 +.дп8 +.др8 +.дс8 +.дт8 +.дф8 +.дх8 +.дц8 +.дч8 +.дш8 +.дщ8 +.жб8 +.жв8 +.жг8 +.жд8 +.жж8 +.жз8 +.жк8 +.жл8 +.жм8 +.жн8 +.жп8 +.жр8 +.жс8 +.жт8 +.жф8 +.жх8 +.жц8 +.жч8 +.жш8 +.жщ8 +.заа4 +.заб4 +.зав4 +.заг4 +.зад4 +.за4д5гран +.за4д5гроб +.за4д5кулис +.за4д5мин +.за4д5мор +.за4д5н +.зае4 +.заж4 +.заз4 +.заи4 +.зак4 +.зал4 +.за4л5п +.зам4 +.зан4 +.за4н5д +.зао4 +.зап4 +.за4п5т +.зар4 +.за4р5з +.зас4 +.зат4 +.зау4 +.заф4 +.зах4 +.зац4 +.зач4 +.заш4 +.защ4 +.заъ4 +.заю4 +.зая4 +.зб8 +.зв8 +.зг8 +.зд8 +.зж8 +.зз8 +.зк8 +.зл8 +.зм8 +.зн8 +.зп8 +.зр8 +.зс8 +.зт8 +.зф8 +.зх8 +.зц8 +.зч8 +.зш8 +.зщ8 +.иза4 +.изб4 +.изв4 +.изг4 +.изд4 +.изе4 +.изж4 +.изз4 +.изи4 +.изй4 +.изк4 +.изл4 +.изм4 +.изн4 +.изо2бб4 +.изо2бв4 +.изо2бг4 +.изо2бд4 +.изо2бж4 +.изо2бз4 +.изо4би +.изо2бк4 +.изо2бл4 +.изо2бм4 +.изо2бн4 +.изо2бп4 +.изо2бр4 +.изо2бс4 +.изо2бт4 +.изо2бф4 +.изо2бх4 +.изо2бц4 +.изо2бч4 +.изо2бш4 +.изо2бщ4 +.изохк +.изп4 +.изпоа4 +.изпоб4 +.изпов4 +.изпог4 +.изпод4 +.изпое4 +.изпож4 +.изпоз4 +.изпои4 +.изпой4 +.изпок4 +.изпол4 +.изпо4л5з +.изпом4 +.изпо4м5п +.изпон4 +.изпоо4 +.изпоп4 +.изпор4 +.изпо4р5т +.изпос4 +.изпот4 +.изпоу4 +.изпоф4 +.изпох4 +.изпоц4 +.изпоч4 +.изпош4 +.изпощ4 +.изпоъ4 +.изпою4 +.изпоя4 +.изр4 +.изс4 +.изт4 +.изу4 +.изф4 +.изх4 +.изц4 +.изч4 +.изш4 +.изщ4 +.изъ4 +.изю4 +.изя4 +.кб8 +.кв8 +.кг8 +.кд8 +.кж8 +.кз8 +.кк8 +.кл8 +.км8 +.кн8 +.кп8 +.кр8 +.кс8 +.кт8 +.кф8 +.кх8 +.кц8 +.кч8 +.кш8 +.кщ8 +.лб8 +.лв8 +.лг8 +.лд8 +.лж8 +.лз8 +.лк8 +.лл8 +.лм8 +.лн8 +.лп8 +.лр8 +.лс8 +.лт8 +.лф8 +.лх8 +.лц8 +.лч8 +.лш8 +.лщ8 +.мб8 +.мв8 +.мг8 +.мд8 +.мж8 +.мз8 +.мк8 +.мл8 +.мм8 +.мн8 +.мп8 +.мр8 +.мс8 +.мт8 +.мф8 +.мх8 +.мц8 +.мч8 +.мш8 +.мщ8 +.наа4 +.наб4 +.нав4 +.наг4 +.на4г5ло +.на2дб4 +.на2дв4 +.на2дг4 +.на2дд4 +.на2д3ж4 +.на3д4жав +.на3д4жас +.на2дз4 +.на4ди4гр +.на2дк4 +.на2дл4 +.на2дм4 +.на2дн4 +.на2дп4 +.на2др4 +.над4ращ +.над4реб +.над4рем +.над4роб +.над4рус +.над4рън +.над4рям +.на2дс4 +.на2дт4 +.на2дф4 +.на2дх4 +.на2дц4 +.на2дч4 +.на2дш4 +.на2дщ4 +.нае4 +.наж4 +.наз4 +.наи4 +.нак4 +.нал4 +.нам4 +.нан4 +.нао4 +.нап4 +.нар4 +.на4р5г +.на4р5к +.нас4 +.нат4 +.нау4 +.наф4 +.нах4 +.нац4 +.нач4 +.наш4 +.нащ4 +.наъ4 +.наю4 +.ная4 +.нб8 +.нв8 +.нг8 +.нд8 +.нж8 +.нз8 +.нк8 +.нл8 +.нм8 +.нн8 +.нп8 +.нр8 +.нс8 +.нт8 +.нф8 +.нх8 +.нц8 +.нч8 +.нш8 +.нщ8 +.оа4 +.оа5зис +.оба4гн +.обб4 +.обв4 +.обг4 +.обд4 +.обж4 +.обз4 +.оби4гр +.обк4 +.обл4 +.об4лаго +.об4лаж +.обм4 +.обн4 +.обо4бщ +.обоз4н +.обоз4р +.обос4н +.обособ +.обп4 +.обр4 +.об4рем +.об4рул +.об4ръс +.обс4 +.обт4 +.обу4зд +.обусл +.обф4 +.обх4 +.обц4 +.обч4 +.обш4 +.общ4 +.об4щ5н +.обя4сн +.ов4 +.ов4дов +.ов4лад +.ов5ц +.ов5ч +.ог4 +.ог5н +.од4 +.ое4 +.ож4 +.оз4 +.озд4р +.ои4 +.ой4 +.ок4 +.ок5си +.ок5т +.ол4 +.ол5тар +.ом4 +.ом5лет +.ом5ни +.он4 +.он5баш +.он5дул +.он5зи +.он5ко +.он5лайн +.он5то +.оо4 +.оп4 +.оп5т +.оп5ци +.ор4 +.ор5б +.ор5г +.ор5д +.ор5к +.ор5л +.ор5н +.ор5т +.ор5ф +.ор5х +.ос4 +.ос5ман +.ос5мин +.ос5миц +.ос5мич +.ос5мо +.ос5те +.ос5тро +.ос5ци +.отб4 +.отв4 +.отг4 +.отд4 +.отж4 +.отз4 +.оти4в +.оти4д +.отк4 +.отл4 +.отм4 +.отн4 +.отп4 +.отр4 +.отс4 +.отт4 +.оту4ч +.отф4 +.отх4 +.отц4 +.отч4 +.отш4 +.отщ4 +.оу4 +.оф4 +.ох4 +.ох5ва +.ох5ка +.ох5на +.оц4 +.оч4 +.ош4 +.ощ4 +.оъ4 +.ою4 +.оя4 +.пб8 +.пв8 +.пг8 +.пд8 +.пж8 +.пз8 +.пк8 +.пл8 +.пм8 +.пн8 +.поа4 +.поб4 +.пов4 +.пог4 +.по2дб4 +.по2дв4 +.под4воу +.по2дг4 +.по2дд4 +.по2д3ж4 +.по3д4жав +.по3д4жур +.по2дз4 +.по2ди4гр +.по2ди4зр +.по2дк4 +.по2дл4 +.по2дм4 +.по2дн4 +.по2до4паш +.по2до4стр +.по2до4тд +.по2до4тч +.по2до4ф +.по2дп4 +.по2др4 +.под4рем +.под4рън +.под4ръп +.под4рям +.по2дс4 +.по2дт4 +.по2ду4пр +.по2ду4ч +.по2дф4 +.по2дх4 +.по2дц4 +.по2дч4 +.по2дш4 +.по2дщ4 +.пое4 +.пож4 +.поз4 +.позаа4 +.позаб4 +.позав4 +.позаг4 +.позад4 +.позае4 +.позаж4 +.позаз4 +.позаи4 +.позай4 +.позак4 +.позал4 +.позам4 +.позан4 +.позао4 +.позап4 +.позар4 +.позас4 +.позат4 +.позау4 +.позаф4 +.позах4 +.позац4 +.позач4 +.позаш4 +.позащ4 +.позаъ4 +.позаю4 +.позая4 +.пои4 +.пои2за4 +.пои2зб4 +.пои2зв4 +.пои2зг4 +.пои2зд4 +.пои2зе4 +.пои2зж4 +.пои2зз4 +.пои2зи4 +.пои2зй4 +.пои2зк4 +.пои2зл4 +.пои2зм4 +.пои2зн4 +.пои2зо4 +.пои2зп4 +.пои2зр4 +.пои2зс4 +.пои2зт4 +.пои2зу4 +.пои2зф4 +.пои2зх4 +.пои2зц4 +.пои2зч4 +.пои2зш4 +.пои2зщ4 +.пои2зъ4 +.пои2зю4 +.пои2зя4 +.пой4 +.пок4 +.пол4 +.по4л5з +.по4л5к +.по4л5с +.пом4 +.по4м5п +.пон4 +.понаа4 +.понаб4 +.понав4 +.понаг4 +.пона2дб4 +.пона2дв4 +.пона2дг4 +.пона2дд4 +.пона2дж4 +.пона2дз4 +.пона2ди4гр +.пона2дк4 +.пона2дл4 +.пона2дм4 +.пона2дн4 +.пона2дп4 +.пона2др4 +.понад4ращ +.понад4реб +.понад4рем +.понад4роб +.понад4рус +.понад4рън +.понад4рям +.пона2дс4 +.пона2дт4 +.пона2дф4 +.пона2дх4 +.пона2дц4 +.пона2дч4 +.пона2дш4 +.пона2дщ4 +.понае4 +.понаж4 +.поназ4 +.понаи4 +.понай4 +.понак4 +.понал4 +.понам4 +.понан4 +.понао4 +.понап4 +.понар4 +.понас4 +.понат4 +.понау4 +.понаф4 +.понах4 +.понац4 +.понач4 +.понаш4 +.понащ4 +.понаъ4 +.понаю4 +.поная4 +.по4н5т +.пооа4 +.поо4бад +.поо4бажд +.поо2бб4 +.поо2бв4 +.поо2бг4 +.поо2бд4 +.поо2бж4 +.поо2бз4 +.поо2би4гр +.поо4бик +.поо2бк4 +.поо2бл4 +.поо2бм4 +.поо2бн4 +.поо2бп4 +.поо2бр4 +.поо2бс4 +.поо2бт4 +.поо2бф4 +.поо2бх4 +.поо2бц4 +.поо2бч4 +.поо2бш4 +.поо2бщ4 +.поо2бя4сн +.поов4 +.поог4 +.поод4 +.поое4 +.поож4 +.пооз4 +.поои4 +.поой4 +.поок4 +.поол4 +.поом4 +.поон4 +.пооо4 +.пооп4 +.поор4 +.поос4 +.поо2тб4 +.поо2тв4 +.поо2тг4 +.поо2тд4 +.поо2тж4 +.поо2тз4 +.поо2тк4 +.поо2тл4 +.поо2тм4 +.поо2тн4 +.поо2тп4 +.поо2тр4 +.поо2тс4 +.поо2тт4 +.поо2ту4ч +.поо2тф4 +.поо2тх4 +.поо2тц4 +.поо2тч4 +.поо2тш4 +.поо2тщ4 +.пооу4 +.пооф4 +.поох4 +.пооц4 +.пооч4 +.поош4 +.поощ4 +.поо4щ5р +.пооъ4 +.поою4 +.пооя4 +.поп4риа4 +.поп4риб4 +.поп4рив4 +.поп4риг4 +.поп4рид4 +.поп4рие4 +.поп4риж4 +.поп4риз4 +.поп4рии4 +.поп4рий4 +.поп4рик4 +.поп4рил4 +.поп4рим4 +.поп4рин4 +.поп4рио4 +.поп4рип4 +.поп4рир4 +.поп4рис4 +.поп4рит4 +.поп4риу4 +.поп4риф4 +.поп4рих4 +.поп4риц4 +.поп4рич4 +.поп4риш4 +.поп4рищ4 +.поп4риъ4 +.поп4рию4 +.поп4рия4 +.пор4 +.по4р5н +.по4р5т +.по4р5ф +.по4р5ц +.пос4 +.по4с4т +.пот4 +.по4т5н +.поу4 +.поф4 +.пох4 +.поц4 +.пош4 +.пощ4 +.поъ4 +.пою4 +.поя4 +.пп8 +.пр8 +.преа4 +.преб4 +.прев4 +.превъ2за4 +.превъ2зб4 +.превъ2зв4 +.превъ2зг4 +.превъ2зд4 +.превъ2зе4 +.превъ2зж4 +.превъ2зз4 +.превъ2зи4 +.превъ2зй4 +.превъ2зк4 +.превъ2зл4 +.превъ2зм4 +.превъ2зн4 +.превъ2зо4 +.превъ2зп4 +.превъ2зр4 +.превъ2зс4 +.превъ2зт4 +.превъ2зу4 +.превъ2зф4 +.превъ2зх4 +.превъ2зц4 +.превъ2зч4 +.превъ2зш4 +.превъ2зщ4 +.превъ2зъ4 +.превъ2зю4 +.превъ2зя4 +.прег4 +.пре2дб4 +.пре2дв4 +.пре2дг4 +.пре2дд4 +.пре2дж4 +.пре2дз4 +.пре2ди4зб4 +.пре2ди4зв4 +.пре2ди4нфар +.пре2ди4стор +.пре2дк4 +.пре2дл4 +.пре2дм4 +.пре2дн4 +.пре2до4бед +.пре2до4ктом +.пре2доп4ред +.пре2дос4воб +.пре2до2та4 +.пре2до2тб4 +.пре2до2тв4 +.пре2до2тг4 +.пре2до2тд4 +.пре2до2те4 +.пре2до2тж4 +.пре2до2тз4 +.пре2до2ти4 +.пре2до2тй4 +.пре2до2тк4 +.пре2до2тл4 +.пре2до2тм4 +.пре2до2тн4 +.пре2до2то4 +.пре2до2тп4 +.пре2до2тр4 +.пре2до2тс4 +.пре2до2тт4 +.пре2до2ту4 +.пре2до2тф4 +.пре2до2тх4 +.пре2до2тц4 +.пре2до2тч4 +.пре2до2тш4 +.пре2до2тщ4 +.пре2до2тъ4 +.пре2до2тю4 +.пре2до2тя4 +.пре2дох4р +.пре2дп4 +.пре2др4 +.пред4рем +.пре2д4реш +.пред4рям +.пре2дс4 +.пре2дт4 +.пре2ду4бед +.пре2ду4бежд +.пре2дугад +.пре2думис +.пре2думиш +.пре2ду4пр +.пре2дусе +.пре2дус4л +.пре2ду4трин +.пре2ду4чил +.пре2дф4 +.пре2дх4 +.пре2дц4 +.пре2дч4 +.пре2дш4 +.пре2дщ4 +.пре2дя4в +.пре2дя4ст +.прее4 +.преж4 +.пре4ж5д +.презаа4 +.презаб4 +.презав4 +.презаг4 +.презад4 +.презае4 +.презаж4 +.презаз4 +.презаи4 +.презай4 +.презак4 +.презал4 +.презам4 +.презан4 +.презао4 +.презап4 +.презар4 +.презас4 +.презат4 +.презау4 +.презаф4 +.презах4 +.презац4 +.презач4 +.презаш4 +.презащ4 +.презаъ4 +.презаю4 +.презая4 +.пре2зб4 +.пре2зв4 +.пре2зг4 +.пре2зд4 +.пре2зж4 +.пре2зз4 +.пре2зк4 +.пре2зл4 +.пре2зм4 +.пре2зн4 +.пре4з5о4кеан +.пре2зп4 +.през4р +.пре4з5рам +.пре4з5ред +.пре2зс4 +.пре2зт4 +.пре2зф4 +.пре2зх4 +.пре2зц4 +.пре2зч4 +.пре2зш4 +.пре2зщ4 +.преи4 +.преи2за4 +.преи2зб4 +.преи2зв4 +.преи2зг4 +.преи2зд4 +.преи2зе4 +.преи2зж4 +.преи2зз4 +.преи2зи4 +.преи2зй4 +.преи2зк4 +.преи2зл4 +.преи2зм4 +.преи2зн4 +.преи2зо4 +.преи2зп4 +.преи2зр4 +.преи2зс4 +.преи2зт4 +.преи2зу4 +.преи2зф4 +.преи2зх4 +.преи2зц4 +.преи2зч4 +.преи2зш4 +.преи2зщ4 +.преи2зъ4 +.преи2зю4 +.преи2зя4 +.прей4 +.прек4 +.прел4 +.прем4 +.прен4 +.пренаа4 +.пренаб4 +.пренав4 +.пренаг4 +.пренад4 +.пренае4 +.пренаж4 +.преназ4 +.пренаи4 +.пренай4 +.пренак4 +.пренал4 +.пренам4 +.пренан4 +.пренао4 +.пренап4 +.пренар4 +.пренас4 +.пренат4 +.пренау4 +.пренаф4 +.пренах4 +.пренац4 +.пренач4 +.пренаш4 +.пренащ4 +.пренаъ4 +.пренаю4 +.преная4 +.прео4 +.преп4 +.прер4 +.прес4 +.пре4с5но +.пре4с5па +.пре4с4пи +.пре4с5ц +.прет4 +.преу4 +.преф4 +.прех4 +.прец4 +.преч4 +.пре4ч5к +.прещ4 +.преъ4 +.прею4 +.прея4 +.приа4 +.приб4 +.прив4 +.приг4 +.прид4 +.прие4 +.приж4 +.приз4 +.при4з5м +.прии4 +.прий4 +.прик4 +.прил4 +.прим4 +.при4м5к +.прин4 +.при4н5т +.при4н5ц +.прио4 +.прип4 +.при4п5в +.при4п5к +.при4п5н +.прир4 +.прис4 +.прит4 +.при4т5ч +.приу4 +.приф4 +.прих4 +.при4х5н +.приц4 +.прич4 +.приш4 +.при4ш5к +.прищ4 +.приъ4 +.прию4 +.прия4 +.проа4 +.проб4 +.про4б5в +.про4б5к +.про4б5лем +.пров4 +.прог4 +.прод4 +.прое4 +.прож4 +.проз4 +.прои4 +.прок4 +.про4к5с +.прол4 +.пром4 +.прон4 +.проо4 +.проп4 +.прор4 +.прос4 +.про4с5б +.про4с4т +.про4с5ф +.прот4 +.проу4 +.прох4 +.проц4 +.проч4 +.прош4 +.прощ4 +.проъ4 +.прою4 +.проя4 +.пс8 +.пт8 +.пф8 +.пх8 +.пц8 +.пч8 +.пш8 +.пщ8 +.ра2за4 +.ра2зб4 +.ра2зв4 +.ра2зг4 +.ра2зд4 +.ра2зе4 +.ра2зж4 +.ра2зз4 +.ра2зи4 +.ра2зй4 +.ра2зк4 +.ра2зл4 +.ра2зм4 +.ра2зн4 +.ра2зо4 +.ра2зп4 +.ра2зр4 +.ра2зс4 +.ра2зт4 +.ра2зу4 +.ра2зф4 +.ра2зх4 +.ра2зц4 +.ра2зч4 +.ра2зш4 +.ра2зщ4 +.ра2зъ4 +.ра2зю4 +.ра2зя4 +.рб8 +.рв8 +.рг8 +.рд8 +.рж8 +.рз8 +.рк8 +.рл8 +.рм8 +.рн8 +.рп8 +.рр8 +.рс8 +.рт8 +.рф8 +.рх8 +.рц8 +.рч8 +.рш8 +.рщ8 +.сб8 +.св8 +.сг8 +.сд8 +.сж8 +.сз8 +.ск8 +.сл8 +.см8 +.сн8 +.сп8 +.ср8 +.сс8 +.ст8 +.сф8 +.сх8 +.сц8 +.сч8 +.сш8 +.сщ8 +.тб8 +.тв8 +.тг8 +.тд8 +.тж8 +.тз8 +.тк8 +.тл8 +.тм8 +.тн8 +.тп8 +.тр8 +.тс8 +.тт8 +.тф8 +.тх8 +.тц8 +.тч8 +.тш8 +.тщ8 +.уа4 +.уб4 +.ув4 +.уг4 +.уд4 +.уе4 +.уж4 +.уж5ки +.уз4 +.уз5бе +.уи4 +.уй4 +.уй5дис +.уй5ду +.ук4 +.ул4 +.ул5т +.ун4 +.ун5гар +.ун5ци +.уо4 +.уп4 +.ур4 +.ур5ба +.ур5в +.ур5н +.ур5суз +.ур5ти +.ус4 +.ус5та +.ус5те +.ус5ти +.ут4 +.ут5ре. +.ут5реш +.ут5рин +.ут4ро +.уу4 +.уф4 +.ух4 +.уц4 +.уч4 +.уч5тив +.уш4 +.уш5но +.ущ4 +.уъ4 +.ую4 +.ую5те +.уя4 +.фб8 +.фв8 +.фг8 +.фд8 +.фж8 +.фз8 +.фк8 +.фл8 +.фм8 +.фн8 +.фп8 +.фр8 +.фс8 +.фт8 +.фф8 +.фх8 +.фц8 +.фч8 +.фш8 +.фщ8 +.хб8 +.хв8 +.хг8 +.хд8 +.хж8 +.хз8 +.хк8 +.хл8 +.хм8 +.хн8 +.хп8 +.хр8 +.хс8 +.хт8 +.хф8 +.хх8 +.хц8 +.хч8 +.хш8 +.хщ8 +.цб8 +.цв8 +.цг8 +.цд8 +.цж8 +.цз8 +.цк8 +.цл8 +.цм8 +.цн8 +.цп8 +.цр8 +.цс8 +.цт8 +.цф8 +.цх8 +.цц8 +.цч8 +.цш8 +.цщ8 +.чб8 +.чв8 +.чг8 +.чд8 +.чж8 +.чз8 +.чк8 +.чл8 +.чм8 +.чн8 +.чп8 +.чр8 +.чс8 +.чт8 +.чф8 +.чх8 +.чц8 +.чч8 +.чш8 +.чщ8 +.шб8 +.шв8 +.шг8 +.шд8 +.шж8 +.шз8 +.шк8 +.шл8 +.шм8 +.шн8 +.шп8 +.шр8 +.шс8 +.шт8 +.шф8 +.шх8 +.шц8 +.шч8 +.шш8 +.шщ8 +.щб8 +.щв8 +.щг8 +.щд8 +.щж8 +.щз8 +.щк8 +.щл8 +.щм8 +.щн8 +.щп8 +.щр8 +.щс8 +.щт8 +.щф8 +.щх8 +.щц8 +.щч8 +.щш8 +.щщ8 +а1 4б3б4 -2б3в2 -2б3г2 -2б3д2 -2б3ж2 -2б3з2 -2б3й2 -2б3к2 -2б3л2 -2б3м2 -2б3н2 -2б3п2 -2б3р2 -2б3с2 -2б3т2 -2б3ф2 -2б3х2 -2б3ц2 -2б3ч2 -2б3ш2 -2б3щ2 -2в3б2 +8бб. +4ббб4 +ббв4 +ббг4 +ббд4 +ббж4 +ббз4 +4ббк4 +ббл4 +ббм4 +ббн4 +4ббп4 +ббр4 +ббс4 +4ббт4 +ббф4 +ббх4 +4ббц4 +4ббч4 +ббш4 +ббщ4 +2б3в +8бв. +4бвб4 +4бвв +4бвг4 +4бвд4 +4бвк4 +4бвп4 +4бвт4 +4бвф +4бвц4 +4бвч4 +2б3г +8бг. +4бгб4 +4бгг +4бгк4 +4бгп4 +4бгт4 +4бгц4 +4бгч4 +2б3д +8бд. +4бдб4 +4бдг +4бдд +4бдк4 +4бдп4 +4бдт4 +4бдц4 +4бдч4 +2б3ж +8бж. +4бжб4 +4бжг4 +4бжд4 +4бжж +4бжк4 +4бжп4 +4бжс +4бжт4 +4бжф +4бжх +4бжц4 +4бжч4 +4бжш +2б3з +8бз. +4бзб4 +4бзг4 +4бзд4 +4бзз +4бзк4 +4бзп4 +4бзс +4бзт4 +4бзф +4бзх +4бзц4 +4бзч4 +4бзш +бй4 +4б3к4 +8бк. +4бкб4 +бкв4 +4бкг4 +4бкд4 +бкж4 +бкз4 +4бкк4 +бкл4 +бкм4 +бкн4 +4бкп4 +бкр4 +бкс4 +4бкт4 +бкф4 +бкх4 +4бкц4 +4бкч4 +бкш4 +бкщ4 +2б3л4 +8бл. +4блб4 +4блк4 +4блл +4блп4 +4блт4 +4блц4 +4блч4 +2б3м4 +8бм. +4бмб4 +4бмк4 +4бмм +4бмп4 +4бмт4 +4бмц4 +4бмч4 +2б3н4 +8бн. +4бнб4 +4бнк4 +4бнн +4бнп4 +4бнт4 +4бнц4 +4бнч4 +4б3п4 +8бп. +4бпб4 +бпв4 +4бпг4 +4бпд4 +бпж4 +бпз4 +4бпк4 +бпл4 +бпм4 +бпн4 +4бпп4 +бпр4 +бпс4 +4бпт4 +бпф4 +бпх4 +4бпц4 +4бпч4 +бпш4 +бпщ4 +2б3р4 +8бр. +4брб4 +4брк4 +4брп4 +4брр +4брт4 +4брц4 +4брч4 +4б3с +8бс. +4бсб4 +4бсг4 +4бсд4 +4бсж +4бсз +4бск4 +4бсп4 +4бсс +4бст4 +4бсц4 +4бсч4 +4б3т4 +8бт. +4бтб4 +бтв4 +4бтг4 +4бтд4 +бтж4 +бтз4 +4бтк4 +бтл4 +бтм4 +бтн4 +4бтп4 +бтр4 +бтс4 +4бтт4 +бтф4 +бтх4 +4бтц4 +4бтч4 +бтш4 +бтщ4 +4б3ф +8бф. +4бфб4 +4бфв +4бфг4 +4бфд4 +4бфж +4бфз +4бфк4 +4бфп4 +4бфт4 +4бфф +4бфц4 +4бфч4 +4б3х +8бх. +4бхб4 +4бхг4 +4бхд4 +4бхж +4бхз +4бхк4 +4бхп4 +4бхт4 +4бхх +4бхц4 +4бхч4 +4б3ц4 +8бц. +4бцб4 +бцв4 +4бцг4 +4бцд4 +бцж4 +бцз4 +4бцк4 +бцл4 +бцм4 +бцн4 +4бцп4 +бцр4 +бцс4 +4бцт4 +бцф4 +бцх4 +4бцц4 +4бцч4 +бцш4 +бцщ4 +4б3ч4 +8бч. +4бчб4 +бчв4 +4бчг4 +4бчд4 +бчж4 +бчз4 +4бчк4 +бчл4 +бчм4 +бчн4 +4бчп4 +бчр4 +бчс4 +4бчт4 +бчф4 +бчх4 +4бчц4 +4бчч4 +бчш4 +бчщ4 +4б3ш +8бш. +4бшб4 +4бшг4 +4бшд4 +4бшж +4бшз +4бшк4 +4бшп4 +4бшт4 +4бшц4 +4бшч4 +4бшш +4б3щ +8бщ. +4бщб4 +4бщк4 +4бщп4 +4бщт4 +4бщц4 +4бщч4 +4бщщ +2в3б +8вб. +4вбб +4вбв4 +4вбк +4вбп +4вбт +4вбф4 +4вбц +4вбч 4в3в4 -2в3г2 -2в3д2 -2в3ж2 -2в3з2 -2в3й2 -2в3к2 -2в3л2 -2в3м2 -2в3н2 -2в3п2 -2в3р2 -2в3с2 -2в3т2 -2в3ф2 -2в3х2 -2в3ц2 -2в3ч2 -2в3ш2 -2в3щ2 -2г3б2 -2г3в2 +8вв. +ввб4 +4ввв4 +ввг4 +ввд4 +ввж4 +ввз4 +ввк4 +ввл4 +ввм4 +ввн4 +ввп4 +ввр4 +ввс4 +ввт4 +4ввф4 +ввх4 +ввц4 +ввч4 +ввш4 +ввщ4 +2в3г +8вг. +4вгв4 +4вгг +4вгк +4вгп +4вгт +4вгф4 +4вгц +4вгч +2в3д +8вд. +4вдб +4вдв4 +4вдг +4вдд +4вдк +4вдп +4вдт +4вдф4 +4вдц +4вдч +2в3ж +8вж. +4вжв4 +4вжж +4вжс +4вжф4 +4вжх +4вжш +2в3з +8вз. +4взв4 +4взз +4взс +4взф4 +4взх +4взш +вй4 +2в3к +8вк. +4вкб +4вкв4 +4вкг +4вкд +4вкк +4вкф4 +2в3л4 +8вл. +4влв4 +4влл +4влф4 +2в3м4 +8вм. +4вмв4 +4вмм +4вмф4 +2в3н4 +8вн. +4внв4 +4внн +4внф4 +2в3п +8вп. +4впб +4впв4 +4впг +4впд +4впп +4впф4 +2в3р4 +8вр. +4врв4 +4врр +4врф4 +2в3с +8вс. +4всв4 +4всж +4всз +4всс +4всф4 +2в3т +8вт. +4втб +4втв4 +4втг +4втд +4втк +4втп +4втт +4втф4 +4втц +4втч +4в3ф4 +8вф. +вфб4 +4вфв4 +вфг4 +вфд4 +4вфж4 +4вфз4 +вфк4 +вфл4 +вфм4 +вфн4 +вфп4 +вфр4 +вфс4 +вфт4 +4вфф4 +вфх4 +вфц4 +вфч4 +вфш4 +вфщ4 +2в3х +8вх. +4вхв4 +4вхж +4вхз +4вхф4 +4вхх +2в3ц +8вц. +4вцб +4вцв4 +4вцг +4вцд +4вцк +4вцп +4вцт +4вцф4 +4вцц +4вцч +2в3ч +8вч. +4вчб +4вчв4 +4вчг +4вчд +4вчк +4вчп +4вчт +4вчф4 +4вчц +4вчч +2в3ш +8вш. +4вшв4 +4вшж +4вшз +4вшф4 +4вшш +2в3щ +8вщ. +4вщв4 +4вщф4 +4вщщ +2г3б +8гб. +4гбб +4гбг4 +4гбк4 +4гбп4 +4гбт4 +4гбц4 +4гбч4 +2г3в +8гв. +4гвб4 +4гвв +4гвг4 +4гвд4 +4гвк4 +4гвп4 +4гвт4 +4гвф +4гвц4 +4гвч4 4г3г4 -2г3д2 -2г3ж2 -2г3з2 -2г3й2 -2г3к2 -2г3л2 -2г3м2 -2г3н2 -2г3п2 -2г3р2 -2г3с2 -2г3т2 -2г3ф2 -2г3х2 -2г3ц2 -2г3ч2 -2г3ш2 -2г3щ2 -2д3б2 -2д3в2 -2д3г2 +8гг. +ггб4 +ггв4 +4ггг4 +ггд4 +ггж4 +ггз4 +4ггк4 +ггл4 +ггм4 +ггн4 +4ггп4 +ггр4 +ггс4 +4ггт4 +ггф4 +ггх4 +4ггц4 +4ггч4 +ггш4 +ггщ4 +2г3д +8гд. +4гдб +4гдг4 +4гдд +4гдк4 +4гдп4 +4гдт4 +4гдц4 +4гдч4 +2г3ж +8гж. +4гжб4 +4гжг4 +4гжд4 +4гжж +4гжк4 +4гжп4 +4гжс +4гжт4 +4гжф +4гжх +4гжц4 +4гжч4 +4гжш +2г3з +8гз. +4гзб4 +4гзг4 +4гзд4 +4гзз +4гзк4 +4гзп4 +4гзс +4гзт4 +4гзф +4гзх +4гзц4 +4гзч4 +4гзш +гй4 +4г3к4 +8гк. +4гкб4 +гкв4 +4гкг4 +4гкд4 +гкж4 +гкз4 +4гкк4 +гкл4 +гкм4 +гкн4 +4гкп4 +гкр4 +гкс4 +4гкт4 +гкф4 +гкх4 +4гкц4 +4гкч4 +гкш4 +гкщ4 +2г3л4 +8гл. +4глг4 +4глк4 +4глл +4глп4 +4глт4 +4глц4 +4глч4 +2г3м4 +8гм. +4гмг4 +4гмк4 +4гмм +4гмп4 +4гмт4 +4гмц4 +4гмч4 +2г3н4 +8гн. +4гнг4 +4гнк4 +4гнн +4гнп4 +4гнт4 +4гнц4 +4гнч4 +4г3п4 +8гп. +4гпб4 +гпв4 +4гпг4 +4гпд4 +гпж4 +гпз4 +4гпк4 +гпл4 +гпм4 +гпн4 +4гпп4 +гпр4 +гпс4 +4гпт4 +гпф4 +гпх4 +4гпц4 +4гпч4 +гпш4 +гпщ4 +2г3р4 +8гр. +4грг4 +4грк4 +4грп4 +4грр +4грт4 +4грц4 +4грч4 +4г3с +8гс. +4гсб4 +4гсг4 +4гсд4 +4гсж +4гсз +4гск4 +4гсп4 +4гсс +4гст4 +4гсц4 +4гсч4 +4г3т4 +8гт. +4гтб4 +гтв4 +4гтг4 +4гтд4 +гтж4 +гтз4 +4гтк4 +гтл4 +гтм4 +гтн4 +4гтп4 +гтр4 +гтс4 +4гтт4 +гтф4 +гтх4 +4гтц4 +4гтч4 +гтш4 +гтщ4 +4г3ф +8гф. +4гфб4 +4гфв +4гфг4 +4гфд4 +4гфж +4гфз +4гфк4 +4гфп4 +4гфт4 +4гфф +4гфц4 +4гфч4 +4г3х +8гх. +4гхб4 +4гхг4 +4гхд4 +4гхж +4гхз +4гхк4 +4гхп4 +4гхт4 +4гхх +4гхц4 +4гхч4 +4г3ц4 +8гц. +4гцб4 +гцв4 +4гцг4 +4гцд4 +гцж4 +гцз4 +4гцк4 +гцл4 +гцм4 +гцн4 +4гцп4 +гцр4 +гцс4 +4гцт4 +гцф4 +гцх4 +4гцц4 +4гцч4 +гцш4 +гцщ4 +4г3ч4 +8гч. +4гчб4 +гчв4 +4гчг4 +4гчд4 +гчж4 +гчз4 +4гчк4 +гчл4 +гчм4 +гчн4 +4гчп4 +гчр4 +гчс4 +4гчт4 +гчф4 +гчх4 +4гчц4 +4гчч4 +гчш4 +гчщ4 +4г3ш +8гш. +4гшб4 +4гшг4 +4гшд4 +4гшж +4гшз +4гшк4 +4гшп4 +4гшт4 +4гшц4 +4гшч4 +4гшш +4г3щ +8гщ. +4гщг4 +4гщк4 +4гщп4 +4гщт4 +4гщц4 +4гщч4 +4гщщ +4д3б4 +8дб. +4дбб4 +дбв4 +4дбг4 +4дбд4 +дбж4 +дбз4 +4дбк4 +дбл4 +дбм4 +дбн4 +4дбп4 +дбр4 +дбс4 +4дбт4 +дбф4 +дбх4 +4дбц4 +4дбч4 +дбш4 +дбщ4 +2д3в +8дв. +4двб4 +4двв +4двг4 +4двд4 +4двк4 +4двп4 +4двт4 +4двф +4двц4 +4двч4 +4д3г4 +8дг. +4дгб4 +дгв4 +4дгг4 +4дгд4 +дгж4 +дгз4 +4дгк4 +дгл4 +дгм4 +дгн4 +4дгп4 +дгр4 +дгс4 +4дгт4 +дгф4 +дгх4 +4дгц4 +4дгч4 +дгш4 +дгщ4 4д3д4 -3д4ж -2д3з2 -2д3й2 -2д3к2 -2д3л2 -2д3м2 -2д3н2 -2д3п2 -2д3р2 -2д3с2 -2д3т2 -2д3ф2 -2д3х2 -2д3ц2 -2д3ч2 -2д3ш2 -2д3щ2 -2ж3б2 -2ж3в2 -2ж3г2 -2ж3д2 +8дд. +4ддб4 +ддв4 +4ддг4 +4ддд4 +ддж4 +ддз4 +4ддк4 +ддл4 +ддм4 +ддн4 +4ддп4 +ддр4 +ддс4 +4ддт4 +ддф4 +ддх4 +4ддц4 +4ддч4 +ддш4 +ддщ4 +8дж. +4джб4 +2джв +4джг4 +4джд4 +4джж +2джз +4джк4 +2джл +2джм +2джн +4джп4 +2джр +4джс +4джт4 +4джф +4джх +4джц4 +4джч4 +4джш +2джщ +8дз. +4дзб4 +2дзв +4дзг4 +4дзд4 +2дзж +4дзз +4дзк4 +2дзл +2дзм +2дзн +4дзп4 +2дзр +4дзс +4дзт4 +4дзф +4дзх +4дзц4 +4дзч4 +4дзш +2дзщ +дй4 +4д3к4 +8дк. +4дкб4 +дкв4 +4дкг4 +4дкд4 +дкж4 +дкз4 +4дкк4 +дкл4 +дкм4 +дкн4 +4дкп4 +дкр4 +дкс4 +4дкт4 +дкф4 +дкх4 +4дкц4 +4дкч4 +дкш4 +дкщ4 +2д3л4 +8дл. +4длб4 +4длг4 +4длд4 +4длк4 +4длл +4длп4 +4длт4 +4длц4 +4длч4 +2д3м4 +8дм. +4дмб4 +4дмг4 +4дмд4 +4дмк4 +4дмм +4дмп4 +4дмт4 +4дмц4 +4дмч4 +2д3н4 +8дн. +4днб4 +4днг4 +4днд4 +4днк4 +4днн +4днп4 +4днт4 +4днц4 +4днч4 +4д3п4 +8дп. +4дпб4 +дпв4 +4дпг4 +4дпд4 +дпж4 +дпз4 +4дпк4 +дпл4 +дпм4 +дпн4 +4дпп4 +дпр4 +дпс4 +4дпт4 +дпф4 +дпх4 +4дпц4 +4дпч4 +дпш4 +дпщ4 +2д3р4 +8др. +4дрб4 +4дрг4 +4дрд4 +4дрк4 +4дрп4 +4дрр +4дрт4 +4дрц4 +4дрч4 +4д3с +8дс. +4дсб4 +4дсг4 +4дсд4 +4дсж +4дсз +4дск4 +4дсп4 +4дсс +4дст4 +4дсц4 +4дсч4 +4д3т4 +8дт. +4дтб4 +дтв4 +4дтг4 +4дтд4 +дтж4 +дтз4 +4дтк4 +дтл4 +дтм4 +дтн4 +4дтп4 +дтр4 +дтс4 +4дтт4 +дтф4 +дтх4 +4дтц4 +4дтч4 +дтш4 +дтщ4 +4д3ф +8дф. +4дфб4 +4дфв +4дфг4 +4дфд4 +4дфж +4дфз +4дфк4 +4дфп4 +4дфт4 +4дфф +4дфц4 +4дфч4 +4д3х +8дх. +4дхб4 +4дхг4 +4дхд4 +4дхж +4дхз +4дхк4 +4дхп4 +4дхт4 +4дхх +4дхц4 +4дхч4 +4д3ц4 +8дц. +4дцб4 +дцв4 +4дцг4 +4дцд4 +дцж4 +дцз4 +4дцк4 +дцл4 +дцм4 +дцн4 +4дцп4 +дцр4 +дцс4 +4дцт4 +дцф4 +дцх4 +4дцц4 +4дцч4 +дцш4 +дцщ4 +4д3ч4 +8дч. +4дчб4 +дчв4 +4дчг4 +4дчд4 +дчж4 +дчз4 +4дчк4 +дчл4 +дчм4 +дчн4 +4дчп4 +дчр4 +дчс4 +4дчт4 +дчф4 +дчх4 +4дчц4 +4дчч4 +дчш4 +дчщ4 +4д3ш +8дш. +4дшб4 +4дшг4 +4дшд4 +4дшж +4дшз +4дшк4 +4дшп4 +4дшт4 +4дшц4 +4дшч4 +4дшш +4д3щ +8дщ. +4дщб4 +4дщг4 +4дщд4 +4дщк4 +4дщп4 +4дщт4 +4дщц4 +4дщч4 +4дщщ +е1 +2ж3б +8жб. +4жбб +4жбж4 +4жбз4 +4жбк +4жбп +4жбс4 +4жбт +4жбф4 +4жбх4 +4жбц +4жбч +4жбш4 +2ж3в +8жв. +4жвв +4жвж4 +4жвс4 +4жвф4 +4жвх4 +4жвш4 +2ж3г +8жг. +4жгг +4жгж4 +4жгз4 +4жгк +4жгп +4жгс4 +4жгт +4жгф4 +4жгх4 +4жгц +4жгч +4жгш4 +2ж3д +8жд. +4ждб +4ждг +4ждд +4ждж4 +4ждз4 +4ждк +4ждп +4ждс4 +4ждт +4ждф4 +4ждх4 +4ждц +4ждч +4ждш4 4ж3ж4 -2ж3з2 -2ж3й2 -2ж3к2 -2ж3л2 -2ж3м2 -2ж3н2 -2ж3п2 -2ж3р2 -2ж3с2 -2ж3т2 -2ж3ф2 -2ж3х2 -2ж3ц2 -2ж3ч2 -2ж3ш2 -2ж3щ2 -2з3б2 -2з3в2 -2з3г2 -2з3д2 -2з3ж2 +8жж. +жжб4 +жжв4 +жжг4 +жжд4 +4жжж4 +жжз4 +жжк4 +жжл4 +жжм4 +жжн4 +жжп4 +жжр4 +4жжс4 +жжт4 +4жжф4 +4жжх4 +жжц4 +жжч4 +4жжш4 +жжщ4 +2ж3з +8жз. +4жзж4 +4жзз +4жзс4 +4жзф4 +4жзх4 +4жзш4 +жй4 +4ж3к +8жк. +4жкб +4жкг +4жкд +4жкж4 +4жкз4 +4жкк +4жкс4 +4жкф4 +4жкх4 +4жкш4 +2ж3л4 +8жл. +4жлж4 +4жлл +4жлс4 +4жлф4 +4жлх4 +4жлш4 +2ж3м4 +8жм. +4жмж4 +4жмм +4жмс4 +4жмф4 +4жмх4 +4жмш4 +2ж3н4 +8жн. +4жнж4 +4жнн +4жнс4 +4жнф4 +4жнх4 +4жнш4 +4ж3п +8жп. +4жпб +4жпг +4жпд +4жпж4 +4жпз4 +4жпп +4жпс4 +4жпф4 +4жпх4 +4жпш4 +2ж3р4 +8жр. +4жрж4 +4жрр +4жрс4 +4жрф4 +4жрх4 +4жрш4 +4ж3с4 +8жс. +жсб4 +жсв4 +жсг4 +жсд4 +4жсж4 +4жсз4 +жск4 +жсл4 +жсм4 +жсн4 +жсп4 +жср4 +4жсс4 +жст4 +4жсф4 +4жсх4 +жсц4 +жсч4 +4жсш4 +жсщ4 +4ж3т +8жт. +4жтб +4жтг +4жтд +4жтж4 +4жтз4 +4жтк +4жтп +4жтс4 +4жтт +4жтф4 +4жтх4 +4жтц +4жтч +4жтш4 +4ж3ф4 +8жф. +жфб4 +4жфв4 +жфг4 +жфд4 +4жфж4 +4жфз4 +жфк4 +жфл4 +жфм4 +жфн4 +жфп4 +жфр4 +4жфс4 +жфт4 +4жфф4 +4жфх4 +жфц4 +жфч4 +4жфш4 +жфщ4 +4ж3х4 +8жх. +жхб4 +жхв4 +жхг4 +жхд4 +4жхж4 +4жхз4 +жхк4 +жхл4 +жхм4 +жхн4 +жхп4 +жхр4 +4жхс4 +жхт4 +4жхф4 +4жхх4 +жхц4 +жхч4 +4жхш4 +жхщ4 +4ж3ц +8жц. +4жцб +4жцг +4жцд +4жцж4 +4жцз4 +4жцк +4жцп +4жцс4 +4жцт +4жцф4 +4жцх4 +4жцц +4жцч +4жцш4 +4ж3ч +8жч. +4жчб +4жчг +4жчд +4жчж4 +4жчз4 +4жчк +4жчп +4жчс4 +4жчт +4жчф4 +4жчх4 +4жчц +4жчч +4жчш4 +4ж3ш4 +8жш. +жшб4 +жшв4 +жшг4 +жшд4 +4жшж4 +4жшз4 +жшк4 +жшл4 +жшм4 +жшн4 +жшп4 +жшр4 +4жшс4 +жшт4 +4жшф4 +4жшх4 +жшц4 +жшч4 +4жшш4 +жшщ4 +4ж3щ +8жщ. +4жщж4 +4жщс4 +4жщф4 +4жщх4 +4жщш4 +4жщщ +2з3б +8зб. +4збб +4збж4 +4збз4 +4збк +4збп +4збс4 +4збт +4збф4 +4збх4 +4збц +4збч +4збш4 +2з3в +8зв. +4звв +4звз4 +4звс4 +4звф4 +4звх4 +4звш4 +2з3г +8зг. +4згг +4згж4 +4згз4 +4згк +4згп +4згс4 +4згт +4згф4 +4згх4 +4згц +4згч +4згш4 +2з3д +8зд. +4здб +4здг +4здд +4здж4 +4здз4 +4здк +4здп +4здс4 +4здт +4здф4 +4здх4 +4здц +4здч +4здш4 +2з3ж +8зж. +4зжж +4зжз4 +4зжс4 +4зжф4 +4зжх4 +4зжш4 4з3з4 -2з3й2 -2з3к2 -2з3л2 -2з3м2 -2з3н2 -2з3п2 -2з3р2 -2з3с2 -2з3т2 -2з3ф2 -2з3х2 -2з3ц2 -2з3ч2 -2з3ш2 -2з3щ2 -2й3б2 -2й3в2 -2й3г2 -2й3д2 -2й3ж2 -2й3з2 -4й3й4 -2й3к2 -2й3л2 -2й3м2 -2й3н2 -2й3п2 -2й3р2 -2й3с2 -2й3т2 -2й3ф2 -2й3х2 -2й3ц2 -2й3ч2 -2й3ш2 -2й3щ2 -2к3б2 -2к3в2 -2к3г2 -2к3д2 -2к3ж2 -2к3з2 -2к3й2 +8зз. +ззб4 +ззв4 +ззг4 +ззд4 +ззж4 +4ззз4 +ззк4 +ззл4 +ззм4 +ззн4 +ззп4 +ззр4 +4ззс4 +ззт4 +4ззф4 +4ззх4 +ззц4 +ззч4 +4ззш4 +ззщ4 +зй4 +4з3к +8зк. +4зкб +4зкг +4зкд +4зкж4 +4зкз4 +4зкк +4зкс4 +4зкф4 +4зкх4 +4зкш4 +2з3л4 +8зл. +4злз4 +4злл +4злс4 +4злф4 +4злх4 +4злш4 +2з3м4 +8зм. +4змз4 +4змм +4змс4 +4змф4 +4змх4 +4змш4 +2з3н4 +8зн. +4знз4 +4знн +4знс4 +4знф4 +4знх4 +4знш4 +4з3п +8зп. +4зпб +4зпг +4зпд +4зпж4 +4зпз4 +4зпп +4зпс4 +4зпф4 +4зпх4 +4зпш4 +2з3р4 +8зр. +4зрз4 +4зрр +4зрс4 +4зрф4 +4зрх4 +4зрш4 +4з3с4 +8зс. +зсб4 +зсв4 +зсг4 +зсд4 +4зсж4 +4зсз4 +зск4 +зсл4 +зсм4 +зсн4 +зсп4 +зср4 +4зсс4 +зст4 +4зсф4 +4зсх4 +зсц4 +зсч4 +4зсш4 +зсщ4 +4з3т +8зт. +4зтб +4зтг +4зтд +4зтж4 +4зтз4 +4зтк +4зтп +4зтс4 +4зтт +4зтф4 +4зтх4 +4зтц +4зтч +4зтш4 +4з3ф4 +8зф. +зфб4 +4зфв4 +зфг4 +зфд4 +4зфж4 +4зфз4 +зфк4 +зфл4 +зфм4 +зфн4 +зфп4 +зфр4 +4зфс4 +зфт4 +4зфф4 +4зфх4 +зфц4 +зфч4 +4зфш4 +зфщ4 +4з3х4 +8зх. +зхб4 +зхв4 +зхг4 +зхд4 +4зхж4 +4зхз4 +зхк4 +зхл4 +зхм4 +зхн4 +зхп4 +зхр4 +4зхс4 +зхт4 +4зхф4 +4зхх4 +зхц4 +зхч4 +4зхш4 +зхщ4 +4з3ц +8зц. +4зцб +4зцг +4зцд +4зцж4 +4зцз4 +4зцк +4зцп +4зцс4 +4зцт +4зцф4 +4зцх4 +4зцц +4зцч +4зцш4 +4з3ч +8зч. +4зчб +4зчг +4зчд +4зчж4 +4зчз4 +4зчк +4зчп +4зчс4 +4зчт +4зчф4 +4зчх4 +4зчц +4зчч +4зчш4 +4з3ш4 +8зш. +зшб4 +зшв4 +зшг4 +зшд4 +4зшж4 +4зшз4 +зшк4 +зшл4 +зшм4 +зшн4 +зшп4 +зшр4 +4зшс4 +зшт4 +4зшф4 +4зшх4 +зшц4 +зшч4 +4зшш4 +зшщ4 +4з3щ +8зщ. +4зщз4 +4зщс4 +4зщф4 +4зщх4 +4зщш4 +4зщщ +и1 +4й1б +4й1в +4й1г +4й1д +4й1ж +4й1з +4й1к +4й1л +4й1м +4й1н +4й1п +4й1р +4й1с +4й1т +4й1ф +4й1х +4й1ц +4й1ч +4й1ш +4й1щ +4к3б4 +8кб. +4кбб4 +кбв4 +4кбг4 +4кбд4 +кбж4 +кбз4 +4кбк4 +кбл4 +кбм4 +кбн4 +4кбп4 +кбр4 +кбс4 +4кбт4 +кбф4 +кбх4 +4кбц4 +4кбч4 +кбш4 +кбщ4 +2к3в4 +8кв. +4квб4 +4квв +4квг4 +4квд4 +4квк4 +4квп4 +4квт4 +4квф +4квц4 +4квч4 +4к3г4 +8кг. +4кгб4 +кгв4 +4кгг4 +4кгд4 +кгж4 +кгз4 +4кгк4 +кгл4 +кгм4 +кгн4 +4кгп4 +кгр4 +кгс4 +4кгт4 +кгф4 +кгх4 +4кгц4 +4кгч4 +кгш4 +кгщ4 +4к3д4 +8кд. +4кдб4 +кдв4 +4кдг4 +4кдд4 +кдж4 +кдз4 +4кдк4 +кдл4 +кдм4 +кдн4 +4кдп4 +кдр4 +кдс4 +4кдт4 +кдф4 +кдх4 +4кдц4 +4кдч4 +кдш4 +кдщ4 +2к3ж4 +8кж. +4кжб4 +4кжг4 +4кжд4 +4кжж +4кжк4 +4кжп4 +4кжс +4кжт4 +4кжф +4кжх +4кжц4 +4кжч4 +4кжш +2к3з4 +8кз. +4кзб4 +4кзг4 +4кзд4 +4кзз +4кзк4 +4кзп4 +4кзс +4кзт4 +4кзф +4кзх +4кзц4 +4кзч4 +4кзш +кй4 4к3к4 -2к3л2 -2к3м2 -2к3н2 -2к3п2 -2к3р2 -2к3с2 -2к3т2 -2к3ф2 -2к3х2 -2к3ц2 -2к3ч2 -2к3ш2 -2к3щ2 -2л3б2 -2л3в2 -2л3г2 -2л3д2 -2л3ж2 -2л3з2 -2л3й2 -2л3к2 +8кк. +4ккб4 +ккв4 +4ккг4 +4ккд4 +ккж4 +ккз4 +4ккк4 +ккл4 +ккм4 +ккн4 +ккп4 +ккр4 +ккс4 +ккт4 +ккф4 +ккх4 +ккц4 +ккч4 +ккш4 +ккщ4 +2к3л4 +8кл. +4клб4 +4клг4 +4клд4 +4клк4 +4клл +2к3м4 +8км. +4кмб4 +4кмг4 +4кмд4 +4кмк4 +4кмм +2к3н4 +8кн. +4кнб4 +4кнг4 +4кнд4 +4кнк4 +4кнн +2к3п +8кп. +4кпб4 +4кпг4 +4кпд4 +4кпк4 +4кпп +2к3р4 +8кр. +4крб4 +4крг4 +4крд4 +4крк4 +4крр +2к3с +8кс. +4ксб4 +4ксг4 +4ксд4 +4ксж +4ксз +4кск4 +4ксп4 +4ксс +4кст4 +4ксц4 +4ксч4 +2к3т +8кт. +4ктб4 +4ктг4 +4ктд4 +4ктк4 +4ктп +4ктт +4ктц +4ктч +2к3ф +8кф. +4кфб4 +4кфв +4кфг4 +4кфд4 +4кфж +4кфз +4кфк4 +4кфп4 +4кфт4 +4кфф +4кфц4 +4кфч4 +2к3х +8кх. +4кхб4 +4кхг4 +4кхд4 +4кхж +4кхз +4кхк4 +4кхп4 +4кхт4 +4кхх +4кхц4 +4кхч4 +2к3ц +8кц. +4кцб4 +4кцг4 +4кцд4 +4кцк4 +4кцп +4кцт +4кцц +4кцч +2к3ч +8кч. +4кчб4 +4кчг4 +4кчд4 +4кчк4 +4кчп +4кчт +4кчц +4кчч +2к3ш +8кш. +4кшб4 +4кшг4 +4кшд4 +4кшж +4кшз +4кшк4 +4кшп4 +4кшт4 +4кшц4 +4кшч4 +4кшш +2к3щ +8кщ. +4кщб4 +4кщг4 +4кщд4 +4кщк4 +4кщщ +4л3б +8лб. +4лбб +4лбк +4лбл4 +4лбп +4лбт +4лбц +4лбч +4л3в +8лв. +4лвв +4лвл4 +4лвф +4л3г +8лг. +4лгг +4лгк +4лгл4 +4лгп +4лгт +4лгц +4лгч +4л3д +8лд. +4лдб +4лдг +4лдд +4лдк +4лдл4 +4лдп +4лдт +4лдц +4лдч +4л3ж +8лж. +4лжж +4лжл4 +4лжс +4лжф +4лжх +4лжш +4л3з +8лз. +4лзз +4лзл4 +4лзс +4лзф +4лзх +4лзш +4л3к +8лк. +4лкб +4лкг +4лкд +4лкк +4лкл4 4л3л4 -2л3м2 -2л3н2 -2л3п2 -2л3р2 -2л3с2 -2л3т2 -2л3ф2 -2л3х2 -2л3ц2 -2л3ч2 -2л3ш2 -2л3щ2 -2м3б2 -2м3в2 -2м3г2 -2м3д2 -2м3ж2 -2м3з2 -2м3й2 -2м3к2 -2м3л2 +8лл. +ллб4 +ллв4 +ллг4 +ллд4 +ллж4 +ллз4 +ллк4 +4ллл4 +ллм4 +ллн4 +ллп4 +ллр4 +ллс4 +ллт4 +ллф4 +ллх4 +ллц4 +ллч4 +ллш4 +ллщ4 +4л3м +8лм. +4лмл4 +4лмм +4л3н +8лн. +4лнл4 +4лнн +4л3п +8лп. +4лпб +4лпг +4лпд +4лпл4 +4лпп +2л3р4 +8лр. +4лрл4 +4лрр +4л3с +8лс. +4лсж +4лсз +4лсл4 +4лсс +4л3т +8лт. +4лтб +4лтг +4лтд +4лтк +4лтл4 +4лтп +4лтт +4лтц +4лтч +4л3ф +8лф. +4лфв +4лфж +4лфз +4лфл4 +4лфф +4л3х +8лх. +4лхж +4лхз +4лхл4 +4лхх +4л3ц +8лц. +4лцб +4лцг +4лцд +4лцк +4лцл4 +4лцп +4лцт +4лцц +4лцч +4л3ч +8лч. +4лчб +4лчг +4лчд +4лчк +4лчл4 +4лчп +4лчт +4лчц +4лчч +4л3ш +8лш. +4лшж +4лшз +4лшл4 +4лшш +4л3щ +8лщ. +4лщл4 +4лщщ +4м3б +8мб. +4мбб +4мбк +4мбм4 +4мбп +4мбт +4мбц +4мбч +4м3в +8мв. +4мвв +4мвм4 +4мвф +4м3г +8мг. +4мгг +4мгк +4мгм4 +4мгп +4мгт +4мгц +4мгч +4м3д +8мд. +4мдб +4мдг +4мдд +4мдк +4мдм4 +4мдп +4мдт +4мдц +4мдч +4м3ж +8мж. +4мжж +4мжм4 +4мжс +4мжф +4мжх +4мжш +4м3з +8мз. +4мзз +4мзм4 +4мзс +4мзф +4мзх +4мзш +4м3к +8мк. +4мкб +4мкг +4мкд +4мкк +4мкм4 +2м3л4 +8мл. +4млл +4млм4 4м3м4 -2м3н2 -2м3п2 -2м3р2 -2м3с2 -2м3т2 -2м3ф2 -2м3х2 -2м3ц2 -2м3ч2 -2м3ш2 -2м3щ2 -2н3б2 -2н3в2 -2н3г2 -2н3д2 -2н3ж2 -2н3з2 -2н3й2 -2н3к2 -2н3л2 -2н3м2 +8мм. +ммб4 +ммв4 +ммг4 +ммд4 +ммж4 +ммз4 +ммк4 +ммл4 +4ммм4 +ммн4 +ммп4 +ммр4 +ммс4 +ммт4 +ммф4 +ммх4 +ммц4 +ммч4 +ммш4 +ммщ4 +2м3н4 +8мн. +4мнм4 +4мнн +4м3п +8мп. +4мпб +4мпг +4мпд +4мпм4 +4мпп +2м3р4 +8мр. +4мрм4 +4мрр +4м3с +8мс. +4мсж +4мсз +4мсм4 +4мсс +4м3т +8мт. +4мтб +4мтг +4мтд +4мтк +4мтм4 +4мтп +4мтт +4мтц +4мтч +4м3ф +8мф. +4мфв +4мфж +4мфз +4мфм4 +4мфф +4м3х +8мх. +4мхж +4мхз +4мхм4 +4мхх +4м3ц +8мц. +4мцб +4мцг +4мцд +4мцк +4мцм4 +4мцп +4мцт +4мцц +4мцч +4м3ч +8мч. +4мчб +4мчг +4мчд +4мчк +4мчм4 +4мчп +4мчт +4мчц +4мчч +4м3ш +8мш. +4мшж +4мшз +4мшм4 +4мшш +4м3щ +8мщ. +4мщм4 +4мщщ +на2д3з +4н3б +8нб. +4нбб +4нбк +4нбн4 +4нбп +4нбт +4нбц +4нбч +4н3в +8нв. +4нвв +4нвн4 +4нвф +4н3г +8нг. +4нгг +4нгк +4нгн4 +4нгп +4нгт +4нгц +4нгч +4н3д +8нд. +4ндб +4ндг +4ндд +4ндк +4ндн4 +4ндп +4ндт +4ндц +4ндч +4н3ж +8нж. +4нжж +4нжн4 +4нжс +4нжф +4нжх +4нжш +4н3з +8нз. +4нзз +4нзн4 +4нзс +4нзф +4нзх +4нзш +4н3к +8нк. +4нкб +4нкг +4нкд +4нкк +4нкн4 +2н3л4 +8нл. +4нлл +4нлн4 +4н3м +8нм. +4нмм +4нмн4 4н3н4 -2н3п2 -2н3р2 -2н3с2 -2н3т2 -2н3ф2 -2н3х2 -2н3ц2 -2н3ч2 -2н3ш2 -2н3щ2 -2п3б2 -2п3в2 -2п3г2 -2п3д2 -2п3ж2 -2п3з2 -2п3й2 -2п3к2 -2п3л2 -2п3м2 -2п3н2 +8нн. +ннб4 +ннв4 +ннг4 +ннд4 +ннж4 +ннз4 +ннк4 +ннл4 +ннм4 +4ннн4 +ннп4 +ннр4 +ннс4 +ннт4 +ннф4 +ннх4 +ннц4 +ннч4 +ннш4 +ннщ4 +4н3п +8нп. +4нпб +4нпг +4нпд +4нпн4 +4нпп +2н3р4 +8нр. +4нрн4 +4нрр +4н3с +8нс. +4нсж +4нсз +4нсн4 +4нсс +4н3т +8нт. +4нтб +4нтг +4нтд +4нтк +4нтн4 +4нтп +4нтт +4нтц +4нтч +4н3ф +8нф. +4нфв +4нфж +4нфз +4нфн4 +4нфф +4н3х +8нх. +4нхж +4нхз +4нхн4 +4нхх +4н3ц +8нц. +4нцб +4нцг +4нцд +4нцк +4нцн4 +4нцп +4нцт +4нцц +4нцч +4н3ч +8нч. +4нчб +4нчг +4нчд +4нчк +4нчн4 +4нчп +4нчт +4нчц +4нчч +4н3ш +8нш. +4ншж +4ншз +4ншн4 +4ншш +4н3щ +8нщ. +4нщн4 +4нщщ +о1 +4п3б4 +8пб. +4пбб4 +пбв4 +4пбг4 +4пбд4 +пбж4 +пбз4 +4пбк4 +пбл4 +пбм4 +пбн4 +4пбп4 +пбр4 +пбс4 +4пбт4 +пбф4 +пбх4 +4пбц4 +4пбч4 +пбш4 +пбщ4 +2п3в4 +8пв. +4пвб4 +4пвв +4пвг4 +4пвд4 +4пвк4 +4пвп4 +4пвт4 +4пвф +4пвц4 +4пвч4 +4п3г4 +8пг. +4пгб4 +пгв4 +4пгг4 +4пгд4 +пгж4 +пгз4 +4пгк4 +пгл4 +пгм4 +пгн4 +4пгп4 +пгр4 +пгс4 +4пгт4 +пгф4 +пгх4 +4пгц4 +4пгч4 +пгш4 +пгщ4 +4п3д4 +8пд. +4пдб4 +пдв4 +4пдг4 +4пдд4 +пдж4 +пдз4 +4пдк4 +пдл4 +пдм4 +пдн4 +4пдп4 +пдр4 +пдс4 +4пдт4 +пдф4 +пдх4 +4пдц4 +4пдч4 +пдш4 +пдщ4 +2п3ж4 +8пж. +4пжб4 +4пжг4 +4пжд4 +4пжж +4пжк4 +4пжп4 +4пжс +4пжт4 +4пжф +4пжх +4пжц4 +4пжч4 +4пжш +2п3з4 +8пз. +4пзб4 +4пзг4 +4пзд4 +4пзз +4пзк4 +4пзп4 +4пзс +4пзт4 +4пзф +4пзх +4пзц4 +4пзч4 +4пзш +пй4 +2п3к +8пк. +4пкб4 +4пкг4 +4пкд4 +4пкк +4пкп4 +2п3л4 +8пл. +4плб4 +4плг4 +4плд4 +4плл +4плп4 +2п3м4 +8пм. +4пмб4 +4пмг4 +4пмд4 +4пмм +4пмп4 +2п3н4 +8пн. +4пнб4 +4пнг4 +4пнд4 +4пнн +4пнп4 +по2д3з 4п3п4 -2п3р2 -2п3с2 -2п3т2 -2п3ф2 -2п3х2 -2п3ц2 -2п3ч2 -2п3ш2 -2п3щ2 -2р3б2 -2р3в2 -2р3г2 -2р3д2 -2р3ж2 -2р3з2 -2р3й2 -2р3к2 -2р3л2 -2р3м2 -2р3н2 -2р3п2 +8пп. +4ппб4 +ппв4 +4ппг4 +4ппд4 +ппж4 +ппз4 +ппк4 +ппл4 +ппм4 +ппн4 +4ппп4 +ппр4 +ппс4 +ппт4 +ппф4 +ппх4 +ппц4 +ппч4 +ппш4 +ппщ4 +2п3р4 +8пр. +4прб4 +4прг4 +4прд4 +пре2д2ж +пре2д3з +4прп4 +4прр +2п3с +8пс. +4псб4 +4псг4 +4псд4 +4псж +4псз +4пск4 +4псп4 +4псс +4пст4 +4псц4 +4псч4 +2п3т +8пт. +4птб4 +4птг4 +4птд4 +4птк +4птп4 +4птт +4птц +4птч +2п3ф +8пф. +4пфб4 +4пфв +4пфг4 +4пфд4 +4пфж +4пфз +4пфк4 +4пфп4 +4пфт4 +4пфф +4пфц4 +4пфч4 +2п3х +8пх. +4пхб4 +4пхг4 +4пхд4 +4пхж +4пхз +4пхк4 +4пхп4 +4пхт4 +4пхх +4пхц4 +4пхч4 +2п3ц +8пц. +4пцб4 +4пцг4 +4пцд4 +4пцк +4пцп4 +4пцт +4пцц +4пцч +2п3ч +8пч. +4пчб4 +4пчг4 +4пчд4 +4пчк +4пчп4 +4пчт +4пчц +4пчч +2п3ш +8пш. +4пшб4 +4пшг4 +4пшд4 +4пшж +4пшз +4пшк4 +4пшп4 +4пшт4 +4пшц4 +4пшч4 +4пшш +2п3щ +8пщ. +4пщб4 +4пщг4 +4пщд4 +4пщп4 +4пщщ +4р3б +8рб. +4рбб +4рбк +4рбп +4рбр4 +4рбт +4рбц +4рбч +4р3в +8рв. +4рвв +4рвр4 +4рвф +4р3г +8рг. +4ргг +4ргк +4ргп +4ргр4 +4ргт +4ргц +4ргч +4р3д +8рд. +4рдб +4рдг +4рдд +4рдк +4рдп +4рдр4 +4рдт +4рдц +4рдч +4р3ж +8рж. +4ржж +4ржр4 +4ржс +4ржф +4ржх +4ржш +4р3з +8рз. +4рзз +4рзр4 +4рзс +4рзф +4рзх +4рзш +4р3к +8рк. +4ркб +4ркг +4ркд +4ркк +4ркр4 +4р3л +8рл. +4рлл +4рлр4 +4р3м +8рм. +4рмм +4рмр4 +4р3н +8рн. +4рнн +4рнр4 +4р3п +8рп. +4рпб +4рпг +4рпд +4рпп +4рпр4 4р3р4 -2р3с2 -2р3т2 -2р3ф2 -2р3х2 -2р3ц2 -2р3ч2 -2р3ш2 -2р3щ2 -2с3б2 -2с3в2 -2с3г2 -2с3д2 -2с3ж2 -2с3з2 -2с3й2 -2с3к2 -2с3л2 -2с3м2 -2с3н2 -2с3п2 -2с3р2 +8рр. +ррб4 +ррв4 +ррг4 +ррд4 +ррж4 +ррз4 +ррк4 +ррл4 +ррм4 +ррн4 +ррп4 +4ррр4 +ррс4 +ррт4 +ррф4 +ррх4 +ррц4 +ррч4 +ррш4 +ррщ4 +4р3с +8рс. +4рсж +4рсз +4рср4 +4рсс +4р3т +8рт. +4ртб +4ртг +4ртд +4ртк +4ртп +4ртр4 +4ртт +4ртц +4ртч +4р3ф +8рф. +4рфв +4рфж +4рфз +4рфр4 +4рфф +4р3х +8рх. +4рхж +4рхз +4рхр4 +4рхх +4р3ц +8рц. +4рцб +4рцг +4рцд +4рцк +4рцп +4рцр4 +4рцт +4рцц +4рцч +4р3ч +8рч. +4рчб +4рчг +4рчд +4рчк +4рчп +4рчр4 +4рчт +4рчц +4рчч +4р3ш +8рш. +4ршж +4ршз +4ршр4 +4ршш +4р3щ +8рщ. +4рщр4 +4рщщ +2с3б4 +8сб. +4сбб +4сбж4 +4сбз4 +4сбк +4сбп +4сбс4 +4сбт +4сбф4 +4сбх4 +4сбц +4сбч +4сбш4 +2с3в4 +8св. +4свв +4свж4 +4свз4 +4свс4 +4свф +2с3г4 +8сг. +4сгг +4сгж4 +4сгз4 +4сгк +4сгп +4сгс4 +4сгт +4сгф4 +4сгх4 +4сгц +4сгч +4сгш4 +2с3д4 +8сд. +4сдб +4сдг +4сдд +4сдж4 +4сдз4 +4сдк +4сдп +4сдс4 +4сдт +4сдф4 +4сдх4 +4сдц +4сдч +4сдш4 +4с3ж4 +8сж. +сжб4 +сжв4 +сжг4 +сжд4 +4сжж4 +4сжз4 +сжк4 +сжл4 +сжм4 +сжн4 +сжп4 +сжр4 +4сжс4 +сжт4 +4сжф4 +4сжх4 +сжц4 +сжч4 +4сжш4 +сжщ4 +4с3з4 +8сз. +сзб4 +сзв4 +сзг4 +сзд4 +4сзж4 +4сзз4 +сзк4 +сзл4 +сзм4 +сзн4 +сзп4 +сзр4 +4сзс4 +сзт4 +4сзф4 +4сзх4 +сзц4 +сзч4 +4сзш4 +сзщ4 +сй4 +2с3к +8ск. +4скб +4скг +4скд +4скж4 +4скз4 +4скк +4скс4 +4скф4 +4скх4 +4скш4 +2с3л4 +8сл. +4слж4 +4слз4 +4слл +4слс4 +2с3м4 +8см. +4смж4 +4смз4 +4смм +4смс4 +2с3н4 +8сн. +4снж4 +4снз4 +4снн +4снс4 +2с3п +8сп. +4спб +4спг +4спд +4спж4 +4спз4 +4спп +4спс4 +4спф4 +4спх4 +4спш4 +2с3р4 +8ср. +4срж4 +4срз4 +4срр +4срс4 4с3с4 -2с3т2 -2с3ф2 -2с3х2 -2с3ц2 -2с3ч2 -2с3ш2 -2с3щ2 -2т3б2 -2т3в2 -2т3г2 -2т3д2 -2т3ж2 -2т3з2 -2т3й2 -2т3к2 -2т3л2 -2т3м2 -2т3н2 -2т3п2 -2т3р2 -2т3с2 +8сс. +ссб4 +ссв4 +ссг4 +ссд4 +4ссж4 +4ссз4 +сск4 +ссл4 +ссм4 +ссн4 +ссп4 +сср4 +4ссс4 +сст4 +ссф4 +ссх4 +ссц4 +ссч4 +ссш4 +ссщ4 +2с3т +8ст. +4стб +4стг +4стд +4стж4 +4стз4 +4стк +4стп +4стс4 +4стт +4стф4 +4стх4 +4стц +4стч +4стш4 +2с3ф +8сф. +4сфв +4сфж4 +4сфз4 +4сфс4 +4сфф +2с3х +8сх. +4схж4 +4схз4 +4схс4 +4схх +2с3ц +8сц. +4сцб +4сцг +4сцд +4сцж4 +4сцз4 +4сцк +4сцп +4сцс4 +4сцт +4сцф4 +4сцх4 +4сцц +4сцч +4сцш4 +2с3ч +8сч. +4счб +4счг +4счд +4счж4 +4счз4 +4счк +4счп +4счс4 +4счт +4счф4 +4счх4 +4счц +4счч +4счш4 +2с3ш +8сш. +4сшж4 +4сшз4 +4сшс4 +4сшш +2с3щ +8сщ. +4сщж4 +4сщз4 +4сщс4 +4сщщ +4т3б4 +8тб. +4тбб4 +тбв4 +4тбг4 +4тбд4 +тбж4 +тбз4 +4тбк4 +тбл4 +тбм4 +тбн4 +4тбп4 +тбр4 +тбс4 +4тбт4 +тбф4 +тбх4 +4тбц4 +4тбч4 +тбш4 +тбщ4 +2т3в4 +8тв. +4твб4 +4твв +4твг4 +4твд4 +4твк4 +4твп4 +4твт4 +4твф +4твц4 +4твч4 +4т3г4 +8тг. +4тгб4 +тгв4 +4тгг4 +4тгд4 +тгж4 +тгз4 +4тгк4 +тгл4 +тгм4 +тгн4 +4тгп4 +тгр4 +тгс4 +4тгт4 +тгф4 +тгх4 +4тгц4 +4тгч4 +тгш4 +тгщ4 +4т3д4 +8тд. +4тдб4 +тдв4 +4тдг4 +4тдд4 +тдж4 +тдз4 +4тдк4 +тдл4 +тдм4 +тдн4 +4тдп4 +тдр4 +тдс4 +4тдт4 +тдф4 +тдх4 +4тдц4 +4тдч4 +тдш4 +тдщ4 +2т3ж4 +8тж. +4тжб4 +4тжг4 +4тжд4 +4тжж +4тжк4 +4тжп4 +4тжс +4тжт4 +4тжф +4тжх +4тжц4 +4тжч4 +4тжш +2т3з4 +8тз. +4тзб4 +4тзг4 +4тзд4 +4тзз +4тзк4 +4тзп4 +4тзс +4тзт4 +4тзф +4тзх +4тзц4 +4тзч4 +4тзш +тй4 +4т3к4 +8тк. +4ткб4 +ткв4 +4ткг4 +4ткд4 +ткж4 +ткз4 +4ткк4 +ткл4 +ткм4 +ткн4 +4ткп4 +ткр4 +ткс4 +4ткт4 +ткф4 +ткх4 +4ткц4 +4ткч4 +ткш4 +ткщ4 +2т3л4 +8тл. +4тлб4 +4тлг4 +4тлд4 +4тлк4 +4тлл +4тлп4 +4тлт4 +4тлц4 +4тлч4 +2т3м4 +8тм. +4тмб4 +4тмг4 +4тмд4 +4тмк4 +4тмм +4тмп4 +4тмт4 +4тмц4 +4тмч4 +2т3н4 +8тн. +4тнб4 +4тнг4 +4тнд4 +4тнк4 +4тнн +4тнп4 +4тнт4 +4тнц4 +4тнч4 +4т3п4 +8тп. +4тпб4 +тпв4 +4тпг4 +4тпд4 +тпж4 +тпз4 +4тпк4 +тпл4 +тпм4 +тпн4 +4тпп4 +тпр4 +тпс4 +4тпт4 +тпф4 +тпх4 +4тпц4 +4тпч4 +тпш4 +тпщ4 +2т3р4 +8тр. +4трб4 +4трг4 +4трд4 +4трк4 +4трп4 +4трр +4трт4 +4трц4 +4трч4 +2т3с +8тс. +4тсб4 +4тсг4 +4тсд4 +4тсж +4тсз +4тск4 +4тсп4 +4тсс +4тст4 +4тсц4 +4тсч4 4т3т4 -2т3ф2 -2т3х2 -2т3ц2 -2т3ч2 -2т3ш2 -2т3щ2 -2ф3б2 -2ф3в2 -2ф3г2 -2ф3д2 -2ф3ж2 -2ф3з2 -2ф3й2 -2ф3к2 -2ф3л2 -2ф3м2 -2ф3н2 -2ф3п2 -2ф3р2 -2ф3с2 -2ф3т2 +8тт. +4ттб4 +ттв4 +4ттг4 +4ттд4 +ттж4 +ттз4 +4ттк4 +ттл4 +ттм4 +ттн4 +4ттп4 +ттр4 +ттс4 +4ттт4 +ттф4 +ттх4 +4ттц4 +4ттч4 +ттш4 +ттщ4 +2т3ф +8тф. +4тфб4 +4тфв +4тфг4 +4тфд4 +4тфж +4тфз +4тфк4 +4тфп4 +4тфт4 +4тфф +4тфц4 +4тфч4 +2т3х +8тх. +4тхб4 +4тхг4 +4тхд4 +4тхж +4тхз +4тхк4 +4тхп4 +4тхт4 +4тхх +4тхц4 +4тхч4 +4т3ц4 +8тц. +4тцб4 +тцв4 +4тцг4 +4тцд4 +тцж4 +тцз4 +4тцк4 +тцл4 +тцм4 +тцн4 +4тцп4 +тцр4 +тцс4 +4тцт4 +тцф4 +тцх4 +4тцц4 +4тцч4 +тцш4 +тцщ4 +4т3ч4 +8тч. +4тчб4 +тчв4 +4тчг4 +4тчд4 +тчж4 +тчз4 +4тчк4 +тчл4 +тчм4 +тчн4 +4тчп4 +тчр4 +тчс4 +4тчт4 +тчф4 +тчх4 +4тчц4 +4тчч4 +тчш4 +тчщ4 +2т3ш +8тш. +4тшб4 +4тшг4 +4тшд4 +4тшж +4тшз +4тшк4 +4тшп4 +4тшт4 +4тшц4 +4тшч4 +4тшш +2т3щ +8тщ. +4тщб4 +4тщг4 +4тщд4 +4тщк4 +4тщп4 +4тщт4 +4тщц4 +4тщч4 +4тщщ +у1 +2ф3б4 +8фб. +4фбб +4фбв4 +4фбж4 +4фбз4 +4фбк +4фбп +4фбс4 +4фбт +4фбф4 +4фбх4 +4фбц +4фбч +4фбш4 +4ф3в4 +8фв. +фвб4 +4фвв4 +фвг4 +фвд4 +4фвж4 +4фвз4 +фвк4 +фвл4 +фвм4 +фвн4 +фвп4 +фвр4 +фвс4 +фвт4 +4фвф4 +фвх4 +фвц4 +фвч4 +фвш4 +фвщ4 +2ф3г4 +8фг. +4фгв4 +4фгг +4фгж4 +4фгз4 +4фгк +4фгп +4фгс4 +4фгт +4фгф4 +4фгх4 +4фгц +4фгч +4фгш4 +2ф3д4 +8фд. +4фдб +4фдв4 +4фдг +4фдд +4фдж4 +4фдз4 +4фдк +4фдп +4фдс4 +4фдт +4фдф4 +4фдх4 +4фдц +4фдч +4фдш4 +4ф3ж4 +8фж. +фжб4 +4фжв4 +фжг4 +фжд4 +4фжж4 +4фжз4 +фжк4 +фжл4 +фжм4 +фжн4 +фжп4 +фжр4 +4фжс4 +фжт4 +4фжф4 +4фжх4 +фжц4 +фжч4 +4фжш4 +фжщ4 +4ф3з4 +8фз. +фзб4 +4фзв4 +фзг4 +фзд4 +4фзж4 +4фзз4 +фзк4 +фзл4 +фзм4 +фзн4 +фзп4 +фзр4 +4фзс4 +фзт4 +4фзф4 +4фзх4 +фзц4 +фзч4 +4фзш4 +фзщ4 +фй4 +2ф3к +8фк. +4фкб +4фкв4 +4фкг +4фкд +4фкж4 +4фкз4 +4фкк +4фкс4 +4фкф4 +4фкх4 +4фкш4 +2ф3л4 +8фл. +4флв4 +4флж4 +4флз4 +4флл +4флф4 +2ф3м4 +8фм. +4фмв4 +4фмж4 +4фмз4 +4фмм +4фмф4 +2ф3н4 +8фн. +4фнв4 +4фнж4 +4фнз4 +4фнн +4фнф4 +2ф3п +8фп. +4фпб +4фпв4 +4фпг +4фпд +4фпж4 +4фпз4 +4фпп +4фпс4 +4фпф4 +4фпх4 +4фпш4 +2ф3р4 +8фр. +4фрв4 +4фрж4 +4фрз4 +4фрр +4фрф4 +2ф3с +8фс. +4фсв4 +4фсж4 +4фсз4 +4фсс +4фсф4 +2ф3т +8фт. +4фтб +4фтв4 +4фтг +4фтд +4фтж4 +4фтз4 +4фтк +4фтп +4фтс4 +4фтт +4фтф4 +4фтх4 +4фтц +4фтч +4фтш4 4ф3ф4 -2ф3х2 -2ф3ц2 -2ф3ч2 -2ф3ш2 -2ф3щ2 -2х3б2 -2х3в2 -2х3г2 -2х3д2 -2х3ж2 -2х3з2 -2х3й2 -2х3к2 -2х3л2 -2х3м2 -2х3н2 -2х3п2 -2х3р2 -2х3с2 -2х3т2 -2х3ф2 +8фф. +ффб4 +4ффв4 +ффг4 +ффд4 +4ффж4 +4ффз4 +ффк4 +ффл4 +ффм4 +ффн4 +ффп4 +ффр4 +ффс4 +ффт4 +4ффф4 +ффх4 +ффц4 +ффч4 +ффш4 +ффщ4 +2ф3х +8фх. +4фхв4 +4фхж4 +4фхз4 +4фхф4 +4фхх +2ф3ц +8фц. +4фцб +4фцв4 +4фцг +4фцд +4фцж4 +4фцз4 +4фцк +4фцп +4фцс4 +4фцт +4фцф4 +4фцх4 +4фцц +4фцч +4фцш4 +2ф3ч +8фч. +4фчб +4фчв4 +4фчг +4фчд +4фчж4 +4фчз4 +4фчк +4фчп +4фчс4 +4фчт +4фчф4 +4фчх4 +4фчц +4фчч +4фчш4 +2ф3ш +8фш. +4фшв4 +4фшж4 +4фшз4 +4фшф4 +4фшш +2ф3щ +8фщ. +4фщв4 +4фщж4 +4фщз4 +4фщф4 +4фщщ +2х3б4 +8хб. +4хбб +4хбж4 +4хбз4 +4хбк +4хбп +4хбс4 +4хбт +4хбф4 +4хбх4 +4хбц +4хбч +4хбш4 +2х3в4 +8хв. +4хвв +4хвж4 +4хвз4 +4хвф +4хвх4 +2х3г4 +8хг. +4хгг +4хгж4 +4хгз4 +4хгк +4хгп +4хгс4 +4хгт +4хгф4 +4хгх4 +4хгц +4хгч +4хгш4 +2х3д4 +8хд. +4хдб +4хдг +4хдд +4хдж4 +4хдз4 +4хдк +4хдп +4хдс4 +4хдт +4хдф4 +4хдх4 +4хдц +4хдч +4хдш4 +4х3ж4 +8хж. +хжб4 +хжв4 +хжг4 +хжд4 +4хжж4 +4хжз4 +хжк4 +хжл4 +хжм4 +хжн4 +хжп4 +хжр4 +4хжс4 +хжт4 +4хжф4 +4хжх4 +хжц4 +хжч4 +4хжш4 +хжщ4 +4х3з4 +8хз. +хзб4 +хзв4 +хзг4 +хзд4 +4хзж4 +4хзз4 +хзк4 +хзл4 +хзм4 +хзн4 +хзп4 +хзр4 +4хзс4 +хзт4 +4хзф4 +4хзх4 +хзц4 +хзч4 +4хзш4 +хзщ4 +хй4 +2х3к +8хк. +4хкб +4хкг +4хкд +4хкж4 +4хкз4 +4хкк +4хкс4 +4хкф4 +4хкх4 +4хкш4 +2х3л4 +8хл. +4хлж4 +4хлз4 +4хлл +4хлх4 +2х3м4 +8хм. +4хмж4 +4хмз4 +4хмм +4хмх4 +2х3н4 +8хн. +4хнж4 +4хнз4 +4хнн +4хнх4 +2х3п +8хп. +4хпб +4хпг +4хпд +4хпж4 +4хпз4 +4хпп +4хпс4 +4хпф4 +4хпх4 +4хпш4 +2х3р4 +8хр. +4хрж4 +4хрз4 +4хрр +4хрх4 +2х3с +8хс. +4хсж4 +4хсз4 +4хсс +4хсх4 +2х3т +8хт. +4хтб +4хтг +4хтд +4хтж4 +4хтз4 +4хтк +4хтп +4хтс4 +4хтт +4хтф4 +4хтх4 +4хтц +4хтч +4хтш4 +2х3ф +8хф. +4хфв +4хфж4 +4хфз4 +4хфф +4хфх4 4х3х4 -2х3ц2 -2х3ч2 -2х3ш2 -2х3щ2 -2ц3б2 -2ц3в2 -2ц3г2 -2ц3д2 -2ц3ж2 -2ц3з2 -2ц3й2 -2ц3к2 -2ц3л2 -2ц3м2 -2ц3н2 -2ц3п2 -2ц3р2 -2ц3с2 -2ц3т2 -2ц3ф2 -2ц3х2 +8хх. +ххб4 +ххв4 +ххг4 +ххд4 +4ххж4 +4ххз4 +ххк4 +ххл4 +ххм4 +ххн4 +ххп4 +ххр4 +ххс4 +ххт4 +ххф4 +4ххх4 +ххц4 +ххч4 +ххш4 +ххщ4 +2х3ц +8хц. +4хцб +4хцг +4хцд +4хцж4 +4хцз4 +4хцк +4хцп +4хцс4 +4хцт +4хцф4 +4хцх4 +4хцц +4хцч +4хцш4 +2х3ч +8хч. +4хчб +4хчг +4хчд +4хчж4 +4хчз4 +4хчк +4хчп +4хчс4 +4хчт +4хчф4 +4хчх4 +4хчц +4хчч +4хчш4 +2х3ш +8хш. +4хшж4 +4хшз4 +4хшх4 +4хшш +2х3щ +8хщ. +4хщж4 +4хщз4 +4хщх4 +4хщщ +4ц3б4 +8цб. +4цбб4 +цбв4 +4цбг4 +4цбд4 +цбж4 +цбз4 +4цбк4 +цбл4 +цбм4 +цбн4 +4цбп4 +цбр4 +цбс4 +4цбт4 +цбф4 +цбх4 +4цбц4 +4цбч4 +цбш4 +цбщ4 +2ц3в4 +8цв. +4цвб4 +4цвв +4цвг4 +4цвд4 +4цвк4 +4цвп4 +4цвт4 +4цвф +4цвц4 +4цвч4 +4ц3г4 +8цг. +4цгб4 +цгв4 +4цгг4 +4цгд4 +цгж4 +цгз4 +4цгк4 +цгл4 +цгм4 +цгн4 +4цгп4 +цгр4 +цгс4 +4цгт4 +цгф4 +цгх4 +4цгц4 +4цгч4 +цгш4 +цгщ4 +4ц3д4 +8цд. +4цдб4 +цдв4 +4цдг4 +4цдд4 +цдж4 +цдз4 +4цдк4 +цдл4 +цдм4 +цдн4 +4цдп4 +цдр4 +цдс4 +4цдт4 +цдф4 +цдх4 +4цдц4 +4цдч4 +цдш4 +цдщ4 +2ц3ж4 +8цж. +4цжб4 +4цжг4 +4цжд4 +4цжж +4цжк4 +4цжп4 +4цжс +4цжт4 +4цжф +4цжх +4цжц4 +4цжч4 +4цжш +2ц3з4 +8цз. +4цзб4 +4цзг4 +4цзд4 +4цзз +4цзк4 +4цзп4 +4цзс +4цзт4 +4цзф +4цзх +4цзц4 +4цзч4 +4цзш +цй4 +4ц3к4 +8цк. +4цкб4 +цкв4 +4цкг4 +4цкд4 +цкж4 +цкз4 +4цкк4 +цкл4 +цкм4 +цкн4 +4цкп4 +цкр4 +цкс4 +4цкт4 +цкф4 +цкх4 +4цкц4 +4цкч4 +цкш4 +цкщ4 +2ц3л4 +8цл. +4цлб4 +4цлг4 +4цлд4 +4цлк4 +4цлл +4цлп4 +4цлт4 +4цлц4 +4цлч4 +2ц3м4 +8цм. +4цмб4 +4цмг4 +4цмд4 +4цмк4 +4цмм +4цмп4 +4цмт4 +4цмц4 +4цмч4 +2ц3н4 +8цн. +4цнб4 +4цнг4 +4цнд4 +4цнк4 +4цнн +4цнп4 +4цнт4 +4цнц4 +4цнч4 +4ц3п4 +8цп. +4цпб4 +цпв4 +4цпг4 +4цпд4 +цпж4 +цпз4 +4цпк4 +цпл4 +цпм4 +цпн4 +4цпп4 +цпр4 +цпс4 +4цпт4 +цпф4 +цпх4 +4цпц4 +4цпч4 +цпш4 +цпщ4 +2ц3р4 +8цр. +4црб4 +4црг4 +4црд4 +4црк4 +4црп4 +4црр +4црт4 +4црц4 +4црч4 +2ц3с +8цс. +4цсб4 +4цсг4 +4цсд4 +4цсж +4цсз +4цск4 +4цсп4 +4цсс +4цст4 +4цсц4 +4цсч4 +4ц3т4 +8цт. +4цтб4 +цтв4 +4цтг4 +4цтд4 +цтж4 +цтз4 +4цтк4 +цтл4 +цтм4 +цтн4 +4цтп4 +цтр4 +цтс4 +4цтт4 +цтф4 +цтх4 +4цтц4 +4цтч4 +цтш4 +цтщ4 +2ц3ф +8цф. +4цфб4 +4цфв +4цфг4 +4цфд4 +4цфж +4цфз +4цфк4 +4цфп4 +4цфт4 +4цфф +4цфц4 +4цфч4 +2ц3х +8цх. +4цхб4 +4цхг4 +4цхд4 +4цхж +4цхз +4цхк4 +4цхп4 +4цхт4 +4цхх +4цхц4 +4цхч4 4ц3ц4 -2ц3ч2 -2ц3ш2 -2ц3щ2 -2ч3б2 -2ч3в2 -2ч3г2 -2ч3д2 -2ч3ж2 -2ч3з2 -2ч3й2 -2ч3к2 -2ч3л2 -2ч3м2 -2ч3н2 -2ч3п2 -2ч3р2 -2ч3с2 -2ч3т2 -2ч3ф2 -2ч3х2 -2ч3ц2 +8цц. +4ццб4 +ццв4 +4ццг4 +4ццд4 +ццж4 +ццз4 +4ццк4 +ццл4 +ццм4 +ццн4 +4ццп4 +ццр4 +ццс4 +4ццт4 +ццф4 +ццх4 +4ццц4 +4ццч4 +ццш4 +ццщ4 +4ц3ч4 +8цч. +4цчб4 +цчв4 +4цчг4 +4цчд4 +цчж4 +цчз4 +4цчк4 +цчл4 +цчм4 +цчн4 +4цчп4 +цчр4 +цчс4 +4цчт4 +цчф4 +цчх4 +4цчц4 +4цчч4 +цчш4 +цчщ4 +2ц3ш +8цш. +4цшб4 +4цшг4 +4цшд4 +4цшж +4цшз +4цшк4 +4цшп4 +4цшт4 +4цшц4 +4цшч4 +4цшш +2ц3щ +8цщ. +4цщб4 +4цщг4 +4цщд4 +4цщк4 +4цщп4 +4цщт4 +4цщц4 +4цщч4 +4цщщ +4ч3б4 +8чб. +4чбб4 +чбв4 +4чбг4 +4чбд4 +чбж4 +чбз4 +4чбк4 +чбл4 +чбм4 +чбн4 +4чбп4 +чбр4 +чбс4 +4чбт4 +чбф4 +чбх4 +4чбц4 +4чбч4 +чбш4 +чбщ4 +2ч3в4 +8чв. +4чвб4 +4чвв +4чвг4 +4чвд4 +4чвк4 +4чвп4 +4чвт4 +4чвф +4чвц4 +4чвч4 +4ч3г4 +8чг. +4чгб4 +чгв4 +4чгг4 +4чгд4 +чгж4 +чгз4 +4чгк4 +чгл4 +чгм4 +чгн4 +4чгп4 +чгр4 +чгс4 +4чгт4 +чгф4 +чгх4 +4чгц4 +4чгч4 +чгш4 +чгщ4 +4ч3д4 +8чд. +4чдб4 +чдв4 +4чдг4 +4чдд4 +чдж4 +чдз4 +4чдк4 +чдл4 +чдм4 +чдн4 +4чдп4 +чдр4 +чдс4 +4чдт4 +чдф4 +чдх4 +4чдц4 +4чдч4 +чдш4 +чдщ4 +2ч3ж4 +8чж. +4чжб4 +4чжг4 +4чжд4 +4чжж +4чжк4 +4чжп4 +4чжс +4чжт4 +4чжф +4чжх +4чжц4 +4чжч4 +4чжш +2ч3з4 +8чз. +4чзб4 +4чзг4 +4чзд4 +4чзз +4чзк4 +4чзп4 +4чзс +4чзт4 +4чзф +4чзх +4чзц4 +4чзч4 +4чзш +чй4 +4ч3к4 +8чк. +4чкб4 +чкв4 +4чкг4 +4чкд4 +чкж4 +чкз4 +4чкк4 +чкл4 +чкм4 +чкн4 +4чкп4 +чкр4 +чкс4 +4чкт4 +чкф4 +чкх4 +4чкц4 +4чкч4 +чкш4 +чкщ4 +2ч3л4 +8чл. +4члб4 +4члг4 +4члд4 +4члк4 +4члл +4члп4 +4члт4 +4члц4 +4члч4 +2ч3м4 +8чм. +4чмб4 +4чмг4 +4чмд4 +4чмк4 +4чмм +4чмп4 +4чмт4 +4чмц4 +4чмч4 +2ч3н4 +8чн. +4чнб4 +4чнг4 +4чнд4 +4чнк4 +4чнн +4чнп4 +4чнт4 +4чнц4 +4чнч4 +4ч3п4 +8чп. +4чпб4 +чпв4 +4чпг4 +4чпд4 +чпж4 +чпз4 +4чпк4 +чпл4 +чпм4 +чпн4 +4чпп4 +чпр4 +чпс4 +4чпт4 +чпф4 +чпх4 +4чпц4 +4чпч4 +чпш4 +чпщ4 +2ч3р4 +8чр. +4чрб4 +4чрг4 +4чрд4 +4чрк4 +4чрп4 +4чрр +4чрт4 +4чрц4 +4чрч4 +2ч3с +8чс. +4чсб4 +4чсг4 +4чсд4 +4чсж +4чсз +4чск4 +4чсп4 +4чсс +4чст4 +4чсц4 +4чсч4 +4ч3т4 +8чт. +4чтб4 +чтв4 +4чтг4 +4чтд4 +чтж4 +чтз4 +4чтк4 +чтл4 +чтм4 +чтн4 +4чтп4 +чтр4 +чтс4 +4чтт4 +чтф4 +чтх4 +4чтц4 +4чтч4 +чтш4 +чтщ4 +2ч3ф +8чф. +4чфб4 +4чфв +4чфг4 +4чфд4 +4чфж +4чфз +4чфк4 +4чфп4 +4чфт4 +4чфф +4чфц4 +4чфч4 +2ч3х +8чх. +4чхб4 +4чхг4 +4чхд4 +4чхж +4чхз +4чхк4 +4чхп4 +4чхт4 +4чхх +4чхц4 +4чхч4 +4ч3ц4 +8чц. +4чцб4 +чцв4 +4чцг4 +4чцд4 +чцж4 +чцз4 +4чцк4 +чцл4 +чцм4 +чцн4 +4чцп4 +чцр4 +чцс4 +4чцт4 +чцф4 +чцх4 +4чцц4 +4чцч4 +чцш4 +чцщ4 4ч3ч4 -2ч3ш2 -2ч3щ2 -2ш3б2 -2ш3в2 -2ш3г2 -2ш3д2 -2ш3ж2 -2ш3з2 -2ш3й2 -2ш3к2 -2ш3л2 -2ш3м2 -2ш3н2 -2ш3п2 -2ш3р2 -2ш3с2 -2ш3т2 -2ш3ф2 -2ш3х2 -2ш3ц2 -2ш3ч2 +8чч. +4ччб4 +ччв4 +4ччг4 +4ччд4 +ччж4 +ччз4 +4ччк4 +ччл4 +ччм4 +ччн4 +4ччп4 +ччр4 +ччс4 +4ччт4 +ччф4 +ччх4 +4ччц4 +4ччч4 +ччш4 +ччщ4 +2ч3ш +8чш. +4чшб4 +4чшг4 +4чшд4 +4чшж +4чшз +4чшк4 +4чшп4 +4чшт4 +4чшц4 +4чшч4 +4чшш +2ч3щ +8чщ. +4чщб4 +4чщг4 +4чщд4 +4чщк4 +4чщп4 +4чщт4 +4чщц4 +4чщч4 +4чщщ +2ш3б4 +8шб. +4шбб +4шбж4 +4шбз4 +4шбк +4шбп +4шбс4 +4шбт +4шбф4 +4шбх4 +4шбц +4шбч +4шбш4 +2ш3в4 +8шв. +4швв +4швж4 +4швз4 +4швф +4швш4 +2ш3г4 +8шг. +4шгг +4шгж4 +4шгз4 +4шгк +4шгп +4шгс4 +4шгт +4шгф4 +4шгх4 +4шгц +4шгч +4шгш4 +2ш3д4 +8шд. +4шдб +4шдг +4шдд +4шдж4 +4шдз4 +4шдк +4шдп +4шдс4 +4шдт +4шдф4 +4шдх4 +4шдц +4шдч +4шдш4 +4ш3ж4 +8шж. +шжб4 +шжв4 +шжг4 +шжд4 +4шжж4 +4шжз4 +шжк4 +шжл4 +шжм4 +шжн4 +шжп4 +шжр4 +4шжс4 +шжт4 +4шжф4 +4шжх4 +шжц4 +шжч4 +4шжш4 +шжщ4 +4ш3з4 +8шз. +шзб4 +шзв4 +шзг4 +шзд4 +4шзж4 +4шзз4 +шзк4 +шзл4 +шзм4 +шзн4 +шзп4 +шзр4 +4шзс4 +шзт4 +4шзф4 +4шзх4 +шзц4 +шзч4 +4шзш4 +шзщ4 +шй4 +2ш3к +8шк. +4шкб +4шкг +4шкд +4шкж4 +4шкз4 +4шкк +4шкс4 +4шкф4 +4шкх4 +4шкш4 +2ш3л4 +8шл. +4шлж4 +4шлз4 +4шлл +4шлш4 +2ш3м4 +8шм. +4шмж4 +4шмз4 +4шмм +4шмш4 +2ш3н4 +8шн. +4шнж4 +4шнз4 +4шнн +4шнш4 +2ш3п +8шп. +4шпб +4шпг +4шпд +4шпж4 +4шпз4 +4шпп +4шпс4 +4шпф4 +4шпх4 +4шпш4 +2ш3р4 +8шр. +4шрж4 +4шрз4 +4шрр +4шрш4 +2ш3с +8шс. +4шсж4 +4шсз4 +4шсс +4шсш4 +2ш3т +8шт. +4штб +4штг +4штд +4штж4 +4штз4 +4штк +4штп +4штс4 +4штт +4штф4 +4штх4 +4штц +4штч +4штш4 +2ш3ф +8шф. +4шфв +4шфж4 +4шфз4 +4шфф +4шфш4 +2ш3х +8шх. +4шхж4 +4шхз4 +4шхх +4шхш4 +2ш3ц +8шц. +4шцб +4шцг +4шцд +4шцж4 +4шцз4 +4шцк +4шцп +4шцс4 +4шцт +4шцф4 +4шцх4 +4шцц +4шцч +4шцш4 +2ш3ч +8шч. +4шчб +4шчг +4шчд +4шчж4 +4шчз4 +4шчк +4шчп +4шчс4 +4шчт +4шчф4 +4шчх4 +4шчц +4шчч +4шчш4 4ш3ш4 -2ш3щ2 -2щ3б2 -2щ3в2 -2щ3г2 -2щ3д2 -2щ3ж2 -2щ3з2 -2щ3й2 -2щ3к2 -2щ3л2 -2щ3м2 -2щ3н2 -2щ3п2 -2щ3р2 -2щ3с2 -2щ3т2 -2щ3ф2 -2щ3х2 -2щ3ц2 -2щ3ч2 -2щ3ш2 +8шш. +шшб4 +шшв4 +шшг4 +шшд4 +4шшж4 +4шшз4 +шшк4 +шшл4 +шшм4 +шшн4 +шшп4 +шшр4 +шшс4 +шшт4 +шшф4 +шшх4 +шшц4 +шшч4 +4шшш4 +шшщ4 +2ш3щ +8шщ. +4шщж4 +4шщз4 +4шщш4 +4шщщ +2щ3б4 +8щб. +4щбб +4щбк +4щбп +4щбт +4щбц +4щбч +4щбщ4 +2щ3в4 +8щв. +4щвв +4щвф +4щвщ4 +2щ3г4 +8щг. +4щгг +4щгк +4щгп +4щгт +4щгц +4щгч +4щгщ4 +2щ3д4 +8щд. +4щдб +4щдг +4щдд +4щдк +4щдп +4щдт +4щдц +4щдч +4щдщ4 +2щ3ж4 +8щж. +4щжж +4щжс +4щжф +4щжх +4щжш +4щжщ4 +2щ3з4 +8щз. +4щзз +4щзс +4щзф +4щзх +4щзш +4щзщ4 +щй4 +2щ3к +8щк. +4щкб +4щкг +4щкд +4щкк +4щкщ4 +2щ3л4 +8щл. +4щлл +4щлщ4 +2щ3м4 +8щм. +4щмм +4щмщ4 +2щ3н4 +8щн. +4щнн +4щнщ4 +2щ3п +8щп. +4щпб +4щпг +4щпд +4щпп +4щпщ4 +2щ3р4 +8щр. +4щрр +4щрщ4 +2щ3с +8щс. +4щсж +4щсз +4щсс +4щсщ4 +2щ3т +8щт. +4щтб +4щтг +4щтд +4щтк +4щтп +4щтт +4щтц +4щтч +4щтщ4 +2щ3ф +8щф. +4щфв +4щфж +4щфз +4щфф +4щфщ4 +2щ3х +8щх. +4щхж +4щхз +4щхх +4щхщ4 +2щ3ц +8щц. +4щцб +4щцг +4щцд +4щцк +4щцп +4щцт +4щцц +4щцч +4щцщ4 +2щ3ч +8щч. +4щчб +4щчг +4щчд +4щчк +4щчп +4щчт +4щчц +4щчч +4щчщ4 +2щ3ш +8щш. +4щшж +4щшз +4щшш +4щшщ4 4щ3щ4 -ааа4 -аае4 -ааи4 -аао4 -аау4 -ааъ4 -ааю4 -аая4 -аеа4 -аее4 -аеи4 -аео4 -аеу4 -аеъ4 -аею4 -аея4 -аиа4 -аие4 -аии4 -аио4 -аиу4 -аиъ4 -аию4 -аия4 -аоа4 -аое4 -аои4 -аоо4 -аоу4 -аоъ4 -аою4 -аоя4 -ауа4 -ауе4 -ауи4 -ауо4 -ауу4 -ауъ4 -аую4 -ауя4 -аъа4 -аъе4 -аъи4 -аъо4 -аъу4 -аъъ4 -аъю4 -аъя4 -аюа4 -аюе4 -аюи4 -аюо4 -аюу4 -аюъ4 -аюю4 -аюя4 -аяа4 -аяе4 -аяи4 -аяо4 -аяу4 -аяъ4 -аяю4 -аяя4 -еаа4 -еае4 -еаи4 -еао4 -еау4 -еаъ4 -еаю4 -еая4 -ееа4 -еее4 -ееи4 -еео4 -ееу4 -ееъ4 -еею4 -еея4 -еиа4 -еие4 -еии4 -еио4 -еиу4 -еиъ4 -еию4 -еия4 -еоа4 -еое4 -еои4 -еоо4 -еоу4 -еоъ4 -еою4 -еоя4 -еуа4 -еуе4 -еуи4 -еуо4 -еуу4 -еуъ4 -еую4 -еуя4 -еъа4 -еъе4 -еъи4 -еъо4 -еъу4 -еъъ4 -еъю4 -еъя4 -еюа4 -еюе4 -еюи4 -еюо4 -еюу4 -еюъ4 -еюю4 -еюя4 -еяа4 -еяе4 -еяи4 -еяо4 -еяу4 -еяъ4 -еяю4 -еяя4 -иаа4 -иае4 -иаи4 -иао4 -иау4 -иаъ4 -иаю4 -иая4 -иеа4 -иее4 -иеи4 -иео4 -иеу4 -иеъ4 -иею4 -иея4 -ииа4 -иие4 -иии4 -иио4 -ииу4 -ииъ4 -иию4 -иия4 -иоа4 -иое4 -иои4 -иоо4 -иоу4 -иоъ4 -иою4 -иоя4 -иуа4 -иуе4 -иуи4 -иуо4 -иуу4 -иуъ4 -иую4 -иуя4 -иъа4 -иъе4 -иъи4 -иъо4 -иъу4 -иъъ4 -иъю4 -иъя4 -июа4 -июе4 -июи4 -июо4 -июу4 -июъ4 -июю4 -июя4 -ияа4 -ияе4 -ияи4 -ияо4 -ияу4 -ияъ4 -ияю4 -ияя4 -оаа4 -оае4 -оаи4 -оао4 -оау4 -оаъ4 -оаю4 -оая4 -оеа4 -оее4 -оеи4 -оео4 -оеу4 -оеъ4 -оею4 -оея4 -оиа4 -оие4 -оии4 -оио4 -оиу4 -оиъ4 -оию4 -оия4 -ооа4 -оое4 -оои4 -ооо4 -ооу4 -ооъ4 -оою4 -ооя4 -оуа4 -оуе4 -оуи4 -оуо4 -оуу4 -оуъ4 -оую4 -оуя4 -оъа4 -оъе4 -оъи4 -оъо4 -оъу4 -оъъ4 -оъю4 -оъя4 -оюа4 -оюе4 -оюи4 -оюо4 -оюу4 -оюъ4 -оюю4 -оюя4 -ояа4 -ояе4 -ояи4 -ояо4 -ояу4 -ояъ4 -ояю4 -ояя4 -уаа4 -уае4 -уаи4 -уао4 -уау4 -уаъ4 -уаю4 -уая4 -уеа4 -уее4 -уеи4 -уео4 -уеу4 -уеъ4 -уею4 -уея4 -уиа4 -уие4 -уии4 -уио4 -уиу4 -уиъ4 -уию4 -уия4 -уоа4 -уое4 -уои4 -уоо4 -уоу4 -уоъ4 -уою4 -уоя4 -ууа4 -ууе4 -ууи4 -ууо4 -ууу4 -ууъ4 -уую4 -ууя4 -уъа4 -уъе4 -уъи4 -уъо4 -уъу4 -уъъ4 -уъю4 -уъя4 -уюа4 -уюе4 -уюи4 -уюо4 -уюу4 -уюъ4 -уюю4 -уюя4 -уяа4 -уяе4 -уяи4 -уяо4 -уяу4 -уяъ4 -уяю4 -уяя4 -ъаа4 -ъае4 -ъаи4 -ъао4 -ъау4 -ъаъ4 -ъаю4 -ъая4 -ъеа4 -ъее4 -ъеи4 -ъео4 -ъеу4 -ъеъ4 -ъею4 -ъея4 -ъиа4 -ъие4 -ъии4 -ъио4 -ъиу4 -ъиъ4 -ъию4 -ъия4 -ъоа4 -ъое4 -ъои4 -ъоо4 -ъоу4 -ъоъ4 -ъою4 -ъоя4 -ъуа4 -ъуе4 -ъуи4 -ъуо4 -ъуу4 -ъуъ4 -ъую4 -ъуя4 -ъъа4 -ъъе4 -ъъи4 -ъъо4 -ъъу4 -ъъъ4 -ъъю4 -ъъя4 -ъюа4 -ъюе4 -ъюи4 -ъюо4 -ъюу4 -ъюъ4 -ъюю4 -ъюя4 -ъяа4 -ъяе4 -ъяи4 -ъяо4 -ъяу4 -ъяъ4 -ъяю4 -ъяя4 -юаа4 -юае4 -юаи4 -юао4 -юау4 -юаъ4 -юаю4 -юая4 -юеа4 -юее4 -юеи4 -юео4 -юеу4 -юеъ4 -юею4 -юея4 -юиа4 -юие4 -юии4 -юио4 -юиу4 -юиъ4 -юию4 -юия4 -юоа4 -юое4 -юои4 -юоо4 -юоу4 -юоъ4 -юою4 -юоя4 -юуа4 -юуе4 -юуи4 -юуо4 -юуу4 -юуъ4 -юую4 -юуя4 -юъа4 -юъе4 -юъи4 -юъо4 -юъу4 -юъъ4 -юъю4 -юъя4 -ююа4 -ююе4 -ююи4 -ююо4 -ююу4 -ююъ4 -ююю4 -ююя4 -юяа4 -юяе4 -юяи4 -юяо4 -юяу4 -юяъ4 -юяю4 -юяя4 -яаа4 -яае4 -яаи4 -яао4 -яау4 -яаъ4 -яаю4 -яая4 -яеа4 -яее4 -яеи4 -яео4 -яеу4 -яеъ4 -яею4 -яея4 -яиа4 -яие4 -яии4 -яио4 -яиу4 -яиъ4 -яию4 -яия4 -яоа4 -яое4 -яои4 -яоо4 -яоу4 -яоъ4 -яою4 -яоя4 -яуа4 -яуе4 -яуи4 -яуо4 -яуу4 -яуъ4 -яую4 -яуя4 -яъа4 -яъе4 -яъи4 -яъо4 -яъу4 -яъъ4 -яъю4 -яъя4 -яюа4 -яюе4 -яюи4 -яюо4 -яюу4 -яюъ4 -яюю4 -яюя4 -яяа4 -яяе4 -яяи4 -яяо4 -яяу4 -яяъ4 -яяю4 -яяя4 -й4бб -й4бв -й4бг -й4бд -й4бж -й4бз -й4бй -й4бк -й4бл -й4бм -й4бн -й4бп -й4бр -й4бс -й4бт -й4бф -й4бх -й4бц -й4бч -й4бш -й4бщ -й4вб -й4вв -й4вг -й4вд -й4вж -й4вз -й4вй -й4вк -й4вл -й4вм -й4вн -й4вп -й4вр -й4вс -й4вт -й4вф -й4вх -й4вц -й4вч -й4вш -й4вщ -й4гб -й4гв -й4гг -й4гд -й4гж -й4гз -й4гй -й4гк -й4гл -й4гм -й4гн -й4гп -й4гр -й4гс -й4гт -й4гф -й4гх -й4гц -й4гч -й4гш -й4гщ -й4дб -й4дв -й4дг -й4дд -й4дж -й4дз -й4дй -й4дк -й4дл -й4дм -й4дн -й4дп -й4др -й4дс -й4дт -й4дф -й4дх -й4дц -й4дч -й4дш -й4дщ -й4жб -й4жв -й4жг -й4жд -й4жж -й4жз -й4жй -й4жк -й4жл -й4жм -й4жн -й4жп -й4жр -й4жс -й4жт -й4жф -й4жх -й4жц -й4жч -й4жш -й4жщ -й4зб -й4зв -й4зг -й4зд -й4зж -й4зз -й4зй -й4зк -й4зл -й4зм -й4зн -й4зп -й4зр -й4зс -й4зт -й4зф -й4зх -й4зц -й4зч -й4зш -й4зщ -й4йб -й4йв -й4йг -й4йд -й4йж -й4йз -й4йй -й4йк -й4йл -й4йм -й4йн -й4йп -й4йр -й4йс -й4йт -й4йф -й4йх -й4йц -й4йч -й4йш -й4йщ -й4кб -й4кв -й4кг -й4кд -й4кж -й4кз -й4кй -й4кк -й4кл -й4км -й4кн -й4кп -й4кр -й4кс -й4кт -й4кф -й4кх -й4кц -й4кч -й4кш -й4кщ -й4лб -й4лв -й4лг -й4лд -й4лж -й4лз -й4лй -й4лк -й4лл -й4лм -й4лн -й4лп -й4лр -й4лс -й4лт -й4лф -й4лх -й4лц -й4лч -й4лш -й4лщ -й4мб -й4мв -й4мг -й4мд -й4мж -й4мз -й4мй -й4мк -й4мл -й4мм -й4мн -й4мп -й4мр -й4мс -й4мт -й4мф -й4мх -й4мц -й4мч -й4мш -й4мщ -й4нб -й4нв -й4нг -й4нд -й4нж -й4нз -й4нй -й4нк -й4нл -й4нм -й4нн -й4нп -й4нр -й4нс -й4нт -й4нф -й4нх -й4нц -й4нч -й4нш -й4нщ -й4пб -й4пв -й4пг -й4пд -й4пж -й4пз -й4пй -й4пк -й4пл -й4пм -й4пн -й4пп -й4пр -й4пс -й4пт -й4пф -й4пх -й4пц -й4пч -й4пш -й4пщ -й4рб -й4рв -й4рг -й4рд -й4рж -й4рз -й4рй -й4рк -й4рл -й4рм -й4рн -й4рп -й4рр -й4рс -й4рт -й4рф -й4рх -й4рц -й4рч -й4рш -й4рщ -й4сб -й4св -й4сг -й4сд -й4сж -й4сз -й4сй -й4ск -й4сл -й4см -й4сн -й4сп -й4ср -й4сс -й4ст -й4сф -й4сх -й4сц -й4сч -й4сш -й4сщ -й4тб -й4тв -й4тг -й4тд -й4тж -й4тз -й4тй -й4тк -й4тл -й4тм -й4тн -й4тп -й4тр -й4тс -й4тт -й4тф -й4тх -й4тц -й4тч -й4тш -й4тщ -й4фб -й4фв -й4фг -й4фд -й4фж -й4фз -й4фй -й4фк -й4фл -й4фм -й4фн -й4фп -й4фр -й4фс -й4фт -й4фф -й4фх -й4фц -й4фч -й4фш -й4фщ -й4хб -й4хв -й4хг -й4хд -й4хж -й4хз -й4хй -й4хк -й4хл -й4хм -й4хн -й4хп -й4хр -й4хс -й4хт -й4хф -й4хх -й4хц -й4хч -й4хш -й4хщ -й4цб -й4цв -й4цг -й4цд -й4цж -й4цз -й4цй -й4цк -й4цл -й4цм -й4цн -й4цп -й4цр -й4цс -й4цт -й4цф -й4цх -й4цц -й4цч -й4цш -й4цщ -й4чб -й4чв -й4чг -й4чд -й4чж -й4чз -й4чй -й4чк -й4чл -й4чм -й4чн -й4чп -й4чр -й4чс -й4чт -й4чф -й4чх -й4чц -й4чч -й4чш -й4чщ -й4шб -й4шв -й4шг -й4шд -й4шж -й4шз -й4шй -й4шк -й4шл -й4шм -й4шн -й4шп -й4шр -й4шс -й4шт -й4шф -й4шх -й4шц -й4шч -й4шш -й4шщ -й4щб -й4щв -й4щг -й4щд -й4щж -й4щз -й4щй -й4щк -й4щл -й4щм -й4щн -й4щп -й4щр -й4щс -й4щт -й4щф -й4щх -й4щц -й4щч -й4щш -й4щщ -б4ь -в4ь -г4ь -д4ь -ж4ь -з4ь -й4ь -к4ь -л4ь -м4ь -н4ь -п4ь -р4ь -с4ь -т4ь -ф4ь -х4ь -ц4ь -ч4ь -ш4ь -щ4ь -ь4ь -.дз4в -.дж4р -.дж4л -.вг4л -.вд4л -.вг4р -.вг4н -.вп4л -.вк4л -.вк4р -.вт4р -.сг4л -.зд4р -.сг4р -.сб4р -.сд4р -.жд4р -.ск4л -.сп4л -.сп4р -.ст4р -.ск4р -.шп4р -.ск4в -.вз4р -.вс4л -.вс4м -.вс4р -.св4р -.сх4л -.сх4р -.хв4р -.вс4т -.сх4в -.см4р -н4кт. -н4кс. -к4ст.} \ No newline at end of file +8щщ. +щщб4 +щщв4 +щщг4 +щщд4 +щщж4 +щщз4 +щщк4 +щщл4 +щщм4 +щщн4 +щщп4 +щщр4 +щщс4 +щщт4 +щщф4 +щщх4 +щщц4 +щщч4 +щщш4 +4щщщ4 +ъ1 +ю1 +я1} \ No newline at end of file diff --git a/tex/context/patterns/mkii/lang-de.pat b/tex/context/patterns/mkii/lang-de.pat index a5e2e1633..86885faac 100644 --- a/tex/context/patterns/mkii/lang-de.pat +++ b/tex/context/patterns/mkii/lang-de.pat @@ -6,2178 +6,3493 @@ \patterns{ .ab1a -.abi4 .ab3l .abo2 .ab3ol .ab1or -.ack2 -.ag4n +.ab3s2 +.ab3u +.ade3n +.ae3 +.aft2 .ag4r .ag2u .ai2s .akt2a .al2e .al3k -.al5l4en +.al3lei +.al5len +.al3li +.al3se .al4tei -.alt3s +.al4tel +.alter6s5 +.alt3s4 +.al4tu .ampe4 -.amt2s +.amt2s1 .amt4sc +.ana1c +.an4a3t .an3d2 .anden6k -.and4ri +.an1er .ang2 -.an3gli +.an3g4li +.an3go .angs4 .angst3 +.ani2s +.an3k4 +.an3na .an3s2 .an4si. -.an4tag -.an3th +.an4tar .an3z2 -.apo1 .ap5p6le. -.aps2 .ari1e -.ark2a +.ar3k2a .ar4m3ac +.ar4mun .ar2sc +.ar4tan .ar4t3ei .arter4 .ar6t5erh -.as3t +.ar2t1r +.arz2 +.asbe2 .as4ta -.at4h +.as3tr +.ata1 +.at2h +.at4r .au3d .au4f3 -.au4s3 -.ausch3 -.ax4 +.au2s3 +.auß2 +.ax2 .äm3 .är6schl +.ät2h .ät2s +.bahn3 +.bah6ner +.bal3t +.baus4 .be3erb +.beige4 +.bel2a .be3r2a -.be3r2e -.berg3a -.ber6gab +.ber2e +.ber4g3a .ber6g5e6b -.ber4gl .ber4g3r +.ber4tr +.bi4os +.bi2t +.bit1a +.blau3 .boge2 +.bogen3 +.bogens6 .bo4s3k .bu4ser +.bu3ta .by4t -.ch2 +.ca2s3t +.ce2ra +.ch6 +.char8mes .chi3er .dab4 .da2r1 -.da4rin +.dar3in .dar2m1 .da4te. .da4tes .de2al .de1i -.de4in. +.dein2 +.de3lo .de8ments +.de3na +.den4ka +.den4kl +.den4ko .de1o2 .de3r4en .de1s -.des2e .de3sk .des2t +.di3el +.di4en .dien4e +.dien6st +.dienst7a8d +.do3b .do2mo .do1pe -.dorf1 -.dü1b -.dys1 +.dor2f1 +.do2tr +.dy2s3 .ebe2r1 +.eg2o +.eh2e .ehe1i -.ei4ds +.ehe5n .ei3e2 +.ei3f2e +.ei3k .ei4na -.einen6g +.ein3d +.ei2ne2 +.ein3eb +.ein6erl +.ein3sp +.eise4 .ei2sp -.ei4st +.eis3s2 +.ei2s5t .ei4tr .eke2 +.ek3li .el2a .el2bi +.el2bl .elb3s +.el4fei +.el2fl .em3m2 .en1 -.en4d3er -.en5der. +.en4da +.en4d3er4 .en2d3r .end3s +.en4dü +.en3ga .en2gl +.enk2 .enn2 .enns3 -.en2t3 +.ent3 +.en2ta .en4tei -.en4tr +.en7thalp +.en4tio +.en4t1r +.en5trop +.ents4 +.er4bei .er8brecht -.erb3s .er2bu -.er2da .er4dan -.er4dar -.er4dei .erden6k -.er4der +.er4d3er .er1e .ere3c +.er2em .erf4 .er1i +.ers2 .er8stein .erster6 .er8stritt. .er8stritten. +.er4z3el .er4zen4 -.esel4s .es3p -.es3ta -.es5t4e -.est2h -.es3to -.es5tr +.es3ta2 +.est6e +.es3th +.es3t3r .et2s -.eu1 -.eu3g4 -.eu3t -.eve4r +.eu3 +.eug4 +.eur4 .ext4 -.fe4i +.fe3la .fer4no +.fi3d .fi3est .fi4le. .fi4len .fi2s -.flug1 -.for2t +.flu2g1 .fs4 .fu2sc +.ga2me +.gan4ga +.ga2s1 +.gas3e +.ga4sp .ga4t .gd2 +.gebe4a .geb2l +.gee4 +.gel4b3r .gel2d1 +.ge3lu +.ge3m .ge5nar -.ge3n2e +.ge3n4e .gene7cke -.ge3r2a -.ge3r2e -.ge3u +.ge3n2o +.ge3r4a +.ger2e +.ge3ro +.ger4s +.ge3sa +.glan2 +.glanz3 +.gol6der .gs4 -.guss1 +.gus2 +.halt4e .hau2t1 .he2 +.he4bei .he3fe -.her3an +.he3le +.he4r3an +.he3rat +.her6b5ra +.he3rer .he3ri .he6r5inn -.hi4n .hin3u -.hi2s +.hips4 +.hi4s +.hof1 +.ho4fen .ho4met .ia4 .im2a .ima4ge .im5m2 .in1 -.in3e +.ind2 .in3gl -.ink4 -.inn2e +.ink2 +.in3n2e +.in3sk +.in3t2 .inu1 +.io4d .ioni1 .ire3 .is2a -.ka2b5l +.is3ta +.it2h +.iv2 +.joni1 +.ka2b3l .ka2i -.kamp2 -.ka4t3io +.kal2a +.ka3le +.ka3t2a +.kat3i +.ka4ti4o .ki4e -.kle4i +.klang3 +.ko3b .kopf1 -.ks2 +.kor4da +.kraf2 +.ks4 .kus2 +.la3be +.lan8de8mi .le4ar +.le4gas +.le3n2i .lich8t7er8s .li2f -.li4tu .li4ve. .lo4g3in +.lo2sc +.los3s4 +.lo2tr .lo3ver +.luster6 .lus4tr +.lut2h +.ly2s3 .ma3d -.ma3la +.ma3ge .mal4e .ma2st +.mat4c +.ma5tr +.matu3 .md2 .mel2a +.me3ne .me3no .men8schl .men8schw -.men3t4 +.mes4sp +.mi2f +.mik4 +.mil2z1 +.mi2s .mi4t1 .mm2 +.mutter5 +.na3no +.na3t .näs1c -.ne4s +.nebe4n +.ner2f +.ne1ro +.ne2s +.nich2 +.nicht5e .ni4e -.nob4 -.no4th +.ni3k4l +.no2th +.nul2 .nus2 .oa3 .ob1a .obe2 +.ober5ei +.ob3i4t +.och3 +.of2e .oper4 .or2a +.ord4e +.or3g +.or3k2 .ort2 .orts3e -.os5t6alg +.os3s +.os4ta4 .oste2 .ost5end .os8ten8de .oste6re -.ost3r +.os8terwe +.os4tes +.os2t3i +.os4tig +.os4t3r +.os4tu +.ot1a +.ou2t +.ou4te .ozo4 .öd2 -.pa4r1e -.par3t4h +.öl3l +.pab4 +.part4h .pe2c -.pes4te +.pe3la +.pe3le +.pe3na .pf4 -.ph2 +.ph4 .poka2 +.po4st +.postei6 .pro1 .ps2 .rabe4 +.ra3ch4e .ra3me -.ram3s +.rau2m +.rau8schl +.räu3sc +.re3ale .reb3s2 .re3cha -.rein4t +.re5insz +.reis6e5i +.rei4s5t .reli1 -.reli3e .res6tr -.ri2as -.rich5te +.ri4as +.richt6e .ro4a -.ro3m2a -.rö2s1 +.ro3be +.ro2e +.ro2h +.ro3m +.rom4a +.ro2st +.ro2t3r +.rö2s +.ruf3s +.ruh2r1 .runder6 .rü1b .rü6cker6 +.sa3br .sali3e -.sami3 +.sami1 +.sau1c +.sau4er +.sau5er. .sch4 +.schaf8t7end +.scheiner8 .se3ck -.sen3s -.ser2u +.se2e +.seein4 +.se2ha +.sen4f +.sen5s +.se3re +.se1ro .se2t1 .sha2 +.si4en +.si3gn .si4te .ski1e +.skis2 +.sour2 +.spani7er. .spiege8lei -.st6 +.st4 +.stau8be8cken. +.ste2i +.steiner8k .sto4re +.stro6ma .sucher6 .tage4s +.ta3mi +.tan4k3a .tan4k3l +.ta3ra +.tar3t2 +.ta2t1h .ta2to +.ta4tor +.ta2t1u .te2e .te2f +.tehe3 +.teiler8s +.tei8l7ersc +.te3le .te3no +.te1ra .te2s .te4st +.test3r .th4 .ti2a -.tid1 .ti2e -.ti4me. +.ti2me .ti4mes +.ti3r .ti2s -.ti5ta +.tischen8 +.ti8sch7end +.tite4 +.tode4 +.to4der +.todes3 +.to2n +.to4nat +.ton3i .to4nin +.tons2 .to4pl +.to2pr .to2w .tri3es .tro2s -.ts2 +.ts4 +.tse3 +.tu3ra .tu3ri -.uf2e2 -.ufer1 +.turm1 +.tur4ma +.ub2 +.ufe2 +.ufer3 +.ul2b3 .um3 +.uma2 +.ume2 .umo2 .un3a2 .un3d -.une2 -.un3g +.un3g2 .uni4t .un3s .uns4t -.ur1 -.ur2i -.urin4s -.ur3o2m -.uro2p +.ur3a2d +.uran6fa +.ur1c +.ur1e +.ur4inf +.ur3o4m +.ur1o2p .ur3s2 .ut2a .ut3r -.übe4 .ve5n2e -.vi2e +.voll1 .vo4r .wah4l .wa2s +.weg5s +.weine4 .wei4ta .welter8e .welter8k +.wer6ker +.wer4kr +.wer4tr +.wetterer8 .wi4e .wor2 .wort5en6 .wor8tend .wor4tu +.wur2f1 .xe3 .ya4l -.za2s +.zel4la +.zelle4 +.zel6leb +.zeug4i .zi2e +.zie4l3u +.zin4ka +.zin4s3c .zin4st +.zuch2 +.zug3l +.zu4gra +.zu2pf .zwe2 +.zweigen8 +.zwei8g7end a1ab aa2be aa1c +a1a2ce aa2gr -2a1a2n +a1akt +aals2t +a1a2n +a2ans +a1aq 2a2ar -aa2r1a -aar3f4 +aa2r3a +aar3b +aar3d +aa3rea +aa2rei +aarf4 +aar3g2 aar3k4 -aar5sc +aart4 +1aas aas5t aata2 aa2th -aa2t3r +aa4t3r aat4s3 2a3au a1ä a1b 2aba -ab4am -ab1auf +3abad +abais4 +ab1alt +a3b2am +ab2ant +ab1au ab1ä +ab2är ab2äu +2abbat +2abbin 1abd -ab1eb -abe1e -abei1 +2a3be. +2a3bec +2abee +ab1eic +abe3i4d ab1eil -4abel +ab1ein +2ab2el abe2la2 -a3ber +2a3ben. +1abent +2aber +a2berd +a3bere +a3beri ab1er2k ab1er2r ab1er2z +4abes +abe2s1e ab3esse 2abet 2abew 1abf -3abfi 1abg +3abga 1abh 2abi +4abil ab1ins ab1ir +abi3st ab1it +abi4tur 1abk ab1l 1a2bla +a3blat 1a2blä -2able -ab4le. +a2b3led +3ab3lei +a3blem +2ablet ab3li -ab4lo -3a2blö +a2blin +ab4lit +2ablo +1a2blö a2blu 1abn -a2bo. +2abo +3a2bo. ab2of -1a2bon -2a3bor +3a2bon +4abot +2abö ab3r -a3bra a4brä -2abrü -1abs -2abs. -abs2a -2absar -ab3s2i -ab3s2p +a2bre +ab4ros +2abrö +a4bs +1ab5sc +1ab3s2p abst2 -2abst. -ab3ste +3absta +1abstu ab3sz 1abtei -2a3bu +abte2s +3abtr +2abu +abu3g4 +a2bum ab1ur 2abü 1abw 2aby aby4t -1abz -2aca -2ac1c +3abz +2ac. +2a3ca +1ac1c +2acci a1cem -2ach. +a1cen +a2ceo ach1a a1chal +a3chari +ach3as ach3au 2achb 2a1che -a2ch1e2c +a2ch1e4c ach1ei +ach4ei. +a2chep a4cherf -a4cherk +ach5erfa +a4ch3erh +a4ch3erl a4cherö a4ch3erw -a1chi +2achf +2a1chi +a2chim ach3l -ach3m +2ach3m ach3n a1cho a3cho. -ach1o2b -ach1or -ach3ö -ach3r +a2cho2r +ach3öf +4ach3r +2achsc +achs4el ach3s2i +ach3skr +achs4or ach3su a4cht -acht7ersc -ach2t1o +ach4tak +ach6terf +ach8tersp +ach6t5erw +ach4t1o +acht5rat ach8traum ach8träume. ach8träumen. ach6trit +acht6s5al +ach4tum a1chu ach1u2f ach3ü 2achv -2ach1w +4ach1w +a2chy a1ci -ac1in -2ack. a1ckar +a3ckel a2ckin -ack2se -ack3sl -ack3sta4 -a1cl +ack2sp +acksta4 +2a1cl acon4n 2acu a1ç a1d +2ad. 2ada. -a3d2ab +4adab +ad2abr ad2ag -ada2m -ad3ama -a2d1an -3a4dap -a3d2ar3 -4adav +ad1an +3adap +4a3d2a2r3 +2adas +2adat +a2d1au +a3dau. 1a2dä ad1c 1add 2ade. ade2al -adefi4 -a2dein -2aden -ade1r2a -a2deri +a3dec +a3dee +adefi2 +2adeg +a3dell +4a3den +aden1a +ade4nat +adeo2 +ade1ra +a2d1erk 4ade1s ade3s2p ades4s -ade5str 2adf -2adh -4a3di +4adh +4adi adi3en -5adj -2ado +adi3er. +adie4sc +adi4st +3adj +2adli +3admi +4admu ad2ob +ado2n +ado4na +a2dop +ad2os 2adp 2adq +a2dre 2ad3rec -ad4res +ad3rei +ad3run 2ads2 ad3st ad3sz -ad2t1 -adta2 -ad4te -ad4tr -2adu -2a1e +2ad2t1 +ad4te2 +1adv +2a3dy +2a1e1 ae2b -ae2c -a3e2d -a3ei +a2ec +ae2ck +ae2d +ae2i a2ek +a2el a3el. -a2ela -a2ele -a2eli +a4ela +a4ele +a4eli a3els +ae2m ae2o3 -a3e2p -ae1r +aeop2 +ae2p +a3er. 3a2er2o1 -ae2s -ae4sc +aes2a +ae2sc aes5t -a2et a2ew ae2x -af1a -a2fak -a2fan +2afa +af1ab +a2f1a2n a3far -af4at -a2fau +a2f1au +2afä +a2f1än 2afe a2f1ec -a2fent -af1erl -a2fex -af2fei +a4fentl +a4f1ep +aff4a af2f3l -af4flu +aff2s +aff4th 2afi +afi6kanz +afi4kat +afi2t 2af3l +af1la +a1f4lu +2afo +a2f3oc +a2ford +a2f1ort afo1s -a2fö -af3ra +2afra +af3rau af3rä af3re +2afro af3rö +af4rü af3s2a +af3s2h +af2si af2sp -2aft +afs4t af2t1a +af3tat af2tei -af4t3erl +af2te2l +aft4erk af2t1o -af2t3r -af4t5re +af2tö +aft3r +af2tra +aft5rei +aft4stä af2tur a2f3ur +2afü +afür3 a1g +2ag. 2aga ag1a2b ag1a2d ag1ar -ag1au -ag2di +a2g1au +ag2del +ag2dr ag2du -2age. -age1i -age4na +4age. +age4l3ei +age4ler +4a3gen. age4neb a2gent -a4gentu -ag2er -age4ral 2ages -age2sa -age4sel -age4si -age2s3p -ag3esse -age4s3ti -ag3gl +age4sam +age4s3in +ages3p +ages6sen +ages3ti 3aggr -3a2git +a2g1id +a2gim 2a2gl -ag6la +ag4lan +ag4las +ag3le a4glö +2agm ag2n -a2gna +ag4nat +a4gnä ag4ne. ag4nu +ago3b +ag3rat a2g3re -a2g3ri -ag4ro -agsa2 +a2gri +ag3rie +ag3rin +2ags ag3s2ah ag4sam -ag4set -ags3p -ag4spo -ag3sta -ag3ste +ag3s4eid +ag7s8porta +agst2 +ag1ste +ag3stö 2agt ag2th +2agu a2gund 2ah. 2a1ha +ah2an ah4at +a1hä 2a1he ahe1in -a2h1erh +a2h1er2h ahe1s +ahe3u a1h2i ahin3 -ahl3a2 -ah4l1ei +ah2l3a2 +ah2l1ä +ah2l1ei +ah2lel +ahle4na +ah4l3erd ah4l3erh +ahl1o2 ah2lö ahl3sz -ah4n1a +ahme1i +ahme3s +ah3mu +ah4n3a +ah3nee +ah2nef +ahn3el +ah4nerd ahner4e -ahnt2 -1ahor +ahner6le +ahner4n +ah2nin +ah2no +1a2hor ah1os -a2h3ö +ah3ös +4ahr ahr1a -ah3re -ahre4s3 -ah3ri -ahrta4 -ahr6tri +ah3r2e +ahren6sc +ahre4s +ahr6tage +ahr6teng +ahr2ti +ahr4tro +ahr4tun ah2ta -aht3h -ah4t5r -aht3s +ah2te2l +ah2t1ex +ah4t3r +aht3s6 a1hu ah1w a1hy -ai3a -aian3 +2ai. +ai1a4 +a1ia. +2aib +ai2bl aid2s -ai1e2 -aien3 +ai1e4 +ai3en3 aif4 ai1fr -ai3g4 +a4i3g4 a3ik. ai3ke -aik4r -a2il +ai2lar +ail3d4 +ai2lei +ail3g ai2lo -aim2o +4ain ain2a a1ind -ain4e -a1ing -ain3sp -2ais +ai5n4e +ain3s +ains2p +3airb ai2sa a3isch. +ai5schw ai3s2e +ais4se. ait4 a3iv. a3ivl a3ivs a1j +a2jat aje2 ajekt4o 2ak. -1a2k4ad +2aka. +2aka3b +akab4r +a2kad 2akal 2a3kam +2akan 2akar ak4at -1a2kaz +akat1a +aka4tak +1akaz +4akä 2akb 2akc 2akd 2a1ke a2kef -aken2n +a2k1em +a2kent +a2kes +ak2et a2keu 2a1ki +ak1ins +aki1s +1akku 2ak3l +a1k4la ak4li -4ako +3aklö +a1kna +2ako 2a1kr 4akra -ak3rau +ak3res +a3k4ri 3akro +ak3rü 2aks ak3sh -2akta -ak5tan +ak2t1a2b 2aktb +ak2tel +akt2er +2aktg 2aktik +2aktis +2aktm +ak2to4b +ak2tö ak2t3r ak5t4ri 2aktsi +2aktsp 2aktst -2a1ku -a2kun -4a3kü +2aktw +a1ku +2akun +a2kup +2akur +aku2s +4akü 1akz +3akze a1la 2ala. -al1ab -al3abs -ala3ch2 +2alabo al1af -ala2g al1age -a3lal +2alai +al1akr al1am -al3ame -alami5 -al3amp al1ana -a2l1ang -al1ans +2aland +a2lang al1anz -a2lar +al1app a3lar. +al3arc a3lare -al2arm -al3arr -ala4s +2al1arr +a2lart +ala2s al1asi al1ass -2alat +a3lat. +al4atm +alat3z al1au al3aug a1lä -al1äm -alb3ein +a2l1äm +al1än +al1ärm +al1äu +3albat +al2bär +alber4e al4berh al4b3er4w al2b1l -alb3li al2boh -al2br +al2bon alb3ru -alb3s +alb3st +al4dan al2dä -al2dr -alds2t +al4d3erl +al4d3ern +alde2s +ald3inn +al2dra +al2drä +alds2 2ale -ale4a -3a2l1e2b -3a4l1ef -a4l1eh +4a3le. +ale4ar +a2l1e2b +al1eck +a4l1ef a2l1ei +a3l2eic a4lein a2l1el -alen1 -al3ends +3a2lema +a2l1e2mi +4a3len. +alende4 +al3endr +a4l3ends a2leng -a3lentf +al2enn ale2p al1epo -al1erf -a2l1erh -al3erl -3alerm +4aler. +a2l1erb +aler2e +a2l1erf +a2l1er2h +aler4kl +a2l3erl +al1erm +aler4mi +a2l1er4r +al2ers a2l1ert -3alerz -a2l1esk -ale4t -al1eta -al1eth +3a4l3erwä +4ales +a2l1e4sk +a2less +a4leth a2l1eu -a4leur -3a2lex alf4r 3algi al2gli +al3glo +1algo +3algor +alg4r 2ali -ali4ene +al2imb +al1imm ali4nal +al1ind +alin4ge +a2l1in2q al1ins -a2linv -alk1ar +alken1 +al2klö al2kne +al2kof 1alkoh alk3s2 alks4t -al2l1a2b -al2l3a4r -al2l1au +al2lab +al3lad +al2l1an +al2l1a2r +al3le. +al4lec +3allee al3lend -all5erfa +all3erk +aller4z al3les -1allgä +al2lid alli5er. alli7ers. al2lob +al2lop +al2löf +al2map al4m3ast -3almb -2alo -a2l1o2b +almo6de. +2alo. +a2l1ob 3a2loe +a2l1of +4alog alo2ga -al1orc +alo2gr +al1ont +al1ort +2alos a2l1ö -al3öf al2ös +3alp. 3alpe. 1alph -al3skl +al2pho +alrat4 +al3sak +al6schei +alsch3s +al3ska al5s6terb -al3sun -al4tak +al2stu +al2sum +al2t1ak +alt3alg al3tam -al3tar -alt3eig -al4t3er3f -al3ti +al2tan +al2tat +al2tau +1altä +alt3eis +alt3elt +al4temu +al4t3er5f +al2teu +al2tid +al2tin alt1op -al4tö -al2tri -alt3ric -al2tro -alt2se +al2tö +al4t3rat +al2tre +al4t3ri +al2t3ro alt4stü a1lu -al2uf +alu3b4 +al2u3f +alu3g +al1u2k a2lum al1umb -al1ur +a2l1ur +a3lus 4aly -alzer4z +al2zar +al2zau +al3zen +alz4erk al2zw 2am. -2am2a -amab4 -amad2 +am2a +ama2ba +ama3d2 ama3g +a2malg +2a3m4an +1a2maz 2amä -2am4e 4ame. a2meb -ame2n1 -amer2a -am5erf -a2meri -ame3ru +2amel +am4e4n1 +amen6spr +ame3r2a +amera3u +a2m1erf +1a2meri +ame5r2u +2ame1s a4mesh -a3met -a2mew +2a3met 2amf -2amir -ami3ta -ami3ti +a3mi. +a3mie +ami2k +am4ing +2a3mir +2a3mis +2amit 2amk 2aml -4amm. +2amm. +am2mab +am2m1ac 2ammal +am4mant am2mar am2mei +ammes3 +am2mid +ammi2e am2min -2amml -2ammt +am2mor +am2m1ö ammu2 amni1 a2mö -amp2fa2 +2ampe. +2ampen +am4pf +amp2f1a2 +2am2ple +2ampo am3pr +amp3s2 2am2s am3sa +4amsc am4schl -am3str +3amse +am3s2h +am3so +am3sp +am3su 1amt. -am2t1a +am2t1a2 +am4tau am2t1ä +am2tei +amt3eig am4tel -2amtem +am2tem +amter4 +am4terh am4t3ern -am4tö +am2t1ex +am2tis +am2tit +am2to +am6tou +am2tö am2t3r am4tre -am2tu +am4tri +am2t1u +2amtv 2amu +3a2mul 2ana. 2anab ana3c -anadi3 -a3nak +4an2ad +anadi1 +an2ag +2a3nak an1alg ana4lin 2anam +an2a3ma 2anan -2ana1s4 -an1ath -an4atm -an1äs +an4and +2ana1s +a5nat. +ana4th +a5n4atm +a2nato +ana4tr +a5nats +an3aug +1a2n1äs 1anb +2anbas +2anbö 2anbu an3ch 2and. 3an3d2ac -an4d3ei -ande2s -an2dex -an4drau -an2d3rü +and3arm +and3ei +anden6ga +an4d3ent +and5erob +ande4sc +an2d1ex and4sas +and4seh +and2so +and6spar and6spas -and3ste and2su -2andu -and1ur +4andu2 +an2d1ur +andy1 2ane an3e2c a3nee an2ei. an3eif -an1e4k -3a4n1erb +3aneig +a4neis +3a2n1e4k +ane2l +an1e2mi +a2nemo +aner4fa +a3nerg +an2erh +a4nerke +4anern +a4nerz. +an4erze an1eth +3anex 1anf +2anf. +2anfab +3anfä +an3fe 2anfi +an4fj +anf3le +4anfors +anf5rau +2anfs an3f2u 4ang. +1anga +2anga. an2g1ar -3angeb +2angas +2ange. +1angeb an2g1ei an4g3erf -an4g3erl -an4gerw +an4g3er4h +an4g3er4w an4g3erz -2angf 2angh 2angie ang1l an2gla -2ango +ang5n ang1r -an4g3ra -4angs. -ang4s3po +ang3ra +1an3gri +2angs. +ang4sto +angt2 1anh 2a3ni an2i3d ani3els ani5ers. +anig2 +ani3ke 3a4nim -a4nins +a4nind +ani2o +an3i4on +a4niso 2anj 2ank. -an2k1an -3ankä +an2kab +an2k1ak +an2kan an2kei -an3kl -an4klö +2an3ken +ank5erfa +an3kes +2anki +an2kid +an2klö an2klu -an2k3no +ank3no +an4k3opf +an2kor ank1r ank3ra +an4kras ank3rä -ankt4 +an2kro +2anks +ank3se +anks2p +2ankt4 1anl +2anlad +3anlag +2anmo 1anmu -2ann -3an3na -ann2ab -3annä -an3n2e -ann4sto -an1od -a3nol +2ann. +1annah +an2nar +an3ne +an4nef +an4nei +an4nene +annen3s4 +ann2er +2anns +ann4s3p +2annt +2ano. +1an1od +2anof +2anog +2a3nol +ano2la +1a2nom +a3nom. +2anoo a2n1or -a3nos +ano2ri +2a3nos 2a1nö -2anpr +2anpu 1anr +2anrö +an4same +an3sar 1an3s2ä -1ansc -ans2en -an2seu -2ansk +3anschr an3skr -an3s1pa +ans1pa +ans3pon 1anspr +1anst an3s2z 2ant. -an2t3a4r +ant3ar +anta4re +an3t2ä 1antá -1antei -3antenn -an3t4he -1anthr -an3ti -2anto +3antei +an3tha +2antie +3antise +anton2 1antr ant3rin -an2tro 1antw -2a1nu +2anu +anu3r anu1s a1nü 1anw -2anwet +2anwi +an2zä 2anzb +2anzd 1anzei +anz3elf anze2n +2anzes 2anzg +2anzh +anzi2d an2z1i4n +2anzk +2anzm +2anzr 2anzs +2anzt 1anzü +3anzün +2anzv 2anzw -an2zwa an2zwi +2anzy 2ao -ao1i +aof4 +ao3i a1op +aopf4 a1or -a1os3 -ao3t2 +a1os5 +aost2 a3ot. -a1ö +ao3t4s +2a1ö2 a1p -2ap. -2apa -2ape -a2pef +4ap. +ap4a +apa3b +a2pe. a3pel a2pé a2pf -a3p2fa +ap2fa +1apfel +2apfes a3pfl -a3phä -a2ph3t -2ap3l +a2pht +2api +2apl +ap4la +a3plä +ap3le +ap3li ap2n +3a2pos a2pot -ap2pf -3appl ap3pu 2apr -3apri +ap2so +aps4ter +ap5t2 2a3pu -2aq 2ar. a1ra a3ra. ar2ab +2ar3abb +ar3abf ar3abt ara3d2 -a2r3al +ar3adr +ara3ge +2a2r3al +a3r4ale a3rali +a3ralo 2aran a2r1ang -a2r1ans a2r1anz -a2r3app +2arap +a4r3app 2a2rar +ara2st +ar2asy +4arat a2r1au a1rä +ar1äs 1arb 2arb. -4arba +2arba +ar2bak +ar2b3at ar2bau -ar2bec +4arbef +ar4b3ein 2arbek 2arben +2arber +arb3erl 4arbi -ar2bl -2arbr -ar2bre +2ar2bl +2arbo +2arb1r 2arbs2 -2arbt +arb3sk +arb3so +2arb3t2 2arbu -ar2b3un 1ar1c -ar2dro -2are +2archl +2archr +ar2dau +arde4i +ar2dop +ar2d3r +ar2du a2rea +are5aler +a2reb4 +aree2 ar1eff -a4reg +a2reh ar1ehr +2arei +a3rei. +ar1eid +a3reie +a3reih +areim3 a2rein -a4rek +arein4b +arein4s +arein4t +a2rele 4arem -a3ren 4aren. +aren6sem are3r2a -ar2erf -a2r1erh +arer2e +a4r3erei +a2rerg +a2rer3h a2reri +a2rerk +a2rerl +a2rert +ar2erw +2ares +ar2et are3u -ar2ew -2arf -ar2fä +a2rev arf1r -ar2f3ra +arf3ra +arf2sp +4arg. +ar3gan ar2gl -ar2gn +ar4gn +2arg4o ar3g4r +arg4s 2arh 2ari ar2ia -ari3e4n +a2rid +ari3e2n ari3erd ari3erg -ar1im arin3it -arin5s4 +arin3s4 ar1int +a3r4io +ar2ir +ar4is +ari2su a3riu ar2kal -ark3amt ar2k1ar ark3aue -ar2k3l +arker2 +ar2kil +2ark3l ar4klag +ar2kle +ar2klo +ark4lö +ar2koa ar2kor -ar4k3ri -ark3sa +ark3s4a +ark2se ark3she ark4tre ar2les -2arma +ar3mad +arm1au ar3m2ä -ar3m2or +ar2m1eg +ar2m1ei +arm2or +ar2mum +4armü +4arn ar2nan -arn2e -2a1ro -ar1ob -a2r1o2d -a2r1of +arn2el +ar3ni +a1ro +arob2 +4aroc +aro8ckeng +ar1o2d +ar1of +aro2fe +2a3rol +aro3m a2r1op a2ror +aros3 +aro4st +1a2rou +a2r1ö4 2arp -2arr -ar2r3ad -ar3re -arre4n +arr1ac +ar2r1ad +ar2r1as +arre4n1 ar2rh -arr3he -2arsa -ar4schl -arse3 +2arri +ar2r3or +ar3se ar3s2h -2arsi -ar2st +ar3s2i +ars3ka +ars4kat ar3sta +ar2tau +2artb ar3t2e -ar2the -ar3ti -artin2 +2artei +2artex +ar3t2i 2arto -ar4t3ram -art3re +art3r +art4res +ar2tri 2arts +art3ske +art2sp 2artuc +2arty 2aru -ar1uh +a2r1uh ar1um +a3rumm a2rü 2arv arwa2 -2ary +2a3r2y +2arza +ar2zau ar2zä 2arze +2arzi +ar2zö 1arzt +arz4tei +arz4tem +arz4ti +arz2t3r +2arzu ar2z1w -as1ala -as3au -a2s1ä -a2sca +2asa +a4s3aa +a2s3af +a3sag +a3s2al +asal2t1 +as1am +as3art +asa2s +as3at +asau4f +a4s3aug +a2sä +as3ät +asbes2 +a6sca a4schec -a3schi -asch1l +a4schef +a4sch3ei +a6scher6g +a3s4chi a2schm +2ascht a3schu -4as2e +a4schum +2asd +4ase a2seb -a2s3e2m -a3s4es -2asg -4ash +a2sec +a2s1ef +as1eie +as1emi +a3sen. +ase4na +ase4n3o +asen6sem +as2er +as4erd +ase2re +aser6geb +a4s3erke +as4es +ase4t +a2sex +2asf +asges4 +2ash a3s2hi +as3hir +2asig +a2s3i2k +2asim asin2g -4asis +as1inn +2asis aska3s -a3skop -a2s1o2f +as3ku +2aso +as3ob +as1of +a3sol +a3som +as1o2p as1or +a4soz a2sö a2s1p aspek6to as2ph -as2pi -as2po -a3spu -as3s2a -as3s2e -as4s3ei -as3s2i -as2s1p +a3s2pi +as3pik +as3pio +a4spir +2aspr +as2pra +2as3sa +ass2a3b +ass6aus. +ass2e +ass3ein +asse3le +ass2i +as3ski +as3so +as2spo +as2spr as2st -ass3ti +as3sta +as3stei +as3sti as3str as3stu -2as3ta -a1s4tas -as4tau +2asta +a3stad +a1stas +as3tat +a3stä as3te +ast2el +ast2er +as4t3ese +as4tex as2th -as3ti +ast2id +as3tie +as3til as3to as4tof -2astr -as4trau -ast3räu -as6t3re -asu2s +ast3orc +a1str +ast3re +as3t4ren +as6t5ritt +ast5roll +as3tub +2asu +as2ur +asu4s3 a2sü aswa2s -3a2syl +1asy +3asyl +2asys a1ß -aße2 -aßen3 +aße4 +aß2en3 2a1t -ata1 -at1ab -at2af -at4ag -a2t1akt -ata3l +4ata +at1abe +at1abr +at2a1f +a5ta3g +at2ago +ata3la a3tam at1apf -at1au -a2taus -a2tä +at2ast +at3att +a2t1au at1än +4atb at2c a2teb -a3te1c -ateien4 +a3tec +ateien6d at1eig -a2teli +3a2teli +3a2temg at2en +ate4na +aten3s4e a2tep -ater3s2 +4ater +ate3r4al +ate3ran +at4ere +atern2 +ater3st ate2ru -at2h -at3ha -athe1 +4ates +ates4sa +a3tet +at2eu +a2tew +4atha +at3hag +at3hal +a3t2heb +ath3in. 3athl a4thr +at2hu +at3hü 4a3ti -atil4s -ati2st +ati4kab +ati6k5erw +a4tinf +at2is +ati2sa +ati2se +a4tiso +atis3s +ati6v5erf +3atla +4atli 3atm +4atma +4atmä 4atmus -ato4man -4ator -a2t1ort -at1ö -4atr +a2t1ob +3a2t4om +atom1e +ato2mo +at1op +at1ort +a3to3s atra4t -at3rä +a2t3rau +a2t3rä at3re +at3rin at3rom +at4ron +at3rot at3rü at2sa at4schn at2se -at4set +ats1e2h at2si -at2so +ats1in +at2s1o at2s1p +ats3tät +at2su at3ta 3attac -at4tak -att3ang +at4tad +at4t1ak +atta2l +at4tale +at4tals +at4tang +at4tar at4tau at2tä +4atte. +at2t3ec at2tei -at3t4hä +at3t2el +4at5ter +at3thä +at3ti +4atto +at2tob at2t3rä -att3s +att3s2 +at3t2u +4atu a3tub atu2n a3tü -atz1er -at4zerk -at4zerw +atze4l +atz3ela +atz3elt +at2zem +at2z1er +a3tzere at2z1in -at2zo atz3t2 at2z1w a2u 2au. -2au1a2 +2au3a2 2aub au2bab +au2ban +au2b1au aube4n +au2beu +au2blä au2bli au2blo -4auc -auch3ta +au2blu +aub2si +2auc au2dr 2aue aue2b -au5erein +au2ere +aue3rei auer3ö +au5erst. +au3ert aue2s au2fa +auf1ak auf1an 2aufe. 2aufeh +4aufen. +3aufent auf1er -au4ferk +au4fer4k +au2feu auff4 -3aufn -auft2 +auf3ind +1aufla +1aufn +2aufo +auf3ski +auf3t2 2auft. 2aug +au2ga +au3g2ar +4augeb 4augeh -4au1i +4augel +aug2er +4augl +4augr +au3gu +au3h +2au1i au2is -2auj +4auj +auk3t aule2s +aul4les au3lü 4aum au2mal -aum2ei -au2m1e4r1 +aume4n +au4m3ent +au2m1e2r1 aum3eri +au2m1id +au4mil +au4mit au2m1o +aumo2r aum3p2 aum3s6 +au4mun 4aun au3n2a aun2e -au4nei +au4n3ei au2nio -au1nu +au2no +au3nu a4unz -au1o 2aup2 -aup4ter -2au3r2 +2aur2 +au1rh +aurü3 au2s1ah ausan8ne. +au2sas au2sau -4ausc -au4schm +2ausc +au6schmi 1ausd +2ause. +au4s1eh 2ausen +au4s3erb +au4serf +au4s3erk aus3erp -au4s3erw -3ausf +au4serw 1ausg +au2sin +au2sis 1ausl au2so +aus1or au2spr 1ausr +auss2 3aussag -auss2e aus4se. -auss2t +aus3st +aust2a 2auste +au5stein aust2o aus5tri -1ausü +3ausü +1ausw 1ausz +auße2 2aut. +au2tab au2t1äu +2autb 2aute +au4t1e2l au4ten4g au4t3erh +aut5ero +2autg +au2thy 1auto au4trö 2auts 2auu +2auv +auve4 2auw 2aux 2auz auz2w 2a1ü -2a1v -a3v4a -ava3t4 -a2vr +a1v +av2a +a3vang +avas4 +ava3t2 +avener4 +2avi +a2v3r 2a1w awi3e +a2wr a1x -ax4am -ax2e +ax2am +a2xans +a3x2e +a3xid +a2xio +axis1 2a1ya a1yeu -ays4 +ayma4 +ay1of +ays2 aysi1 ay3t -2a1z -a3z2a -aza3d -az2i +a1z +az4a +a3za3d +3azal +a3z2i az2o -az2u +a3z2u +az2zen +az2zw ä1a -äand4 -ä1b +1ää +2ä1b ä2b3l äb2s +äbte1 +ä1ce ä1che äche1e +äche4n ä1chi äch3l ä2chr +äch4sa +äch2s1o äch2sp -äch4st +äch2st +ächt4e ä1chu ä1ck -ä3ck2e ä1d ä2da +äde1s2 ä2d1ia -ä2dr +ä2d3r äd2s +äd3te 2ä1e -äf2e +äe4k +ä3eu +äe2x äfe4n -äf2f3l +äf2fl +äfig3 äf3l äf3r äf4ro äf2s +äf3t2e äft4s3 ä1g -äge1i -äge2ra +ä2g1a +1ä2gä +ägd2 +ägen4e +äge2r3a äge3s ä2g3l äg2n ä2g3r äg4ra +ägst2 +äg3sta äg3str 1ä2gy äh1a 2ä3he -ä3hi +ä4h1ei +äher8gebn +äher5t +ä1hi +äh1in ähl1a äh3l2e äh4l3e4be +äh5ler 2ähm äh3na äh3ne 1ähnl 2ähr +äh2rel äh3ri 2ähs -2äh3t +2äht ä1hu äh1w 2äi ä1im -ä1is. +ä2is +ä3is. ä3isch. -ä1isk +ä3isk ä1j ä1k -ä2k3l +äka2la +äk3l +ä2kle +äk4li ä2k3r ä1la älbe2 -äl2bl -2äle +äl4bl +älk3 +älks4 äl2l1a äl2p3 äl4schl äl2st +ält2e +älte1i ä1lu +2äm4a3 +ä3me +ämer2s ämi3en 2äml ämoni3e 2ämp +ämp7f4e äm2s ämt2e +ämter3 2än. -än5de än2dr -2äne +2än2e äne2n1 äne1s -än2f5 +2än2f5 änft2 -2änge -2än2g3l +4än3g2e +änge4ra +2än2gl +äng3le än2gr äng3se 2ä3ni -änk2e +än3k2e än2k3l än2kr änk2s -änn4e2 -äno3 +2änn +än3n4e2 2äns +än4s1a än2s1c äns2e -änse3h 2änz ä1on +äo3s2 ä1pa +1äpfel äp2pl äp2pr äp2s1c äp4st 1äq -ä2r3a2 +ä2r3a4 är4af är1ä är2b3le är1c -4äre +2ärd +ärde4s +2äre ä2r1ei +ä2r1e2l +äre2m +är1emi äre2n -ä2r1ene -är2gr +ä2rene +ä2rerh +är2es +ärf2s +är3ge +ärg4s +ä2r1ind är1int -är2k3l +är3ke ärk2s -är4ment +ärm3arm +ärm3at +ärme1e +ärm3ent ärm2s -är1o2 +är1ob +är1of ä1rö +är3re ärse2 -är4si +är2seb +är4seh +ärs1er +är2si +är3spu är2st +är3str +2ärt ärt4e är2th ärt2s3 ä2rü +1ärz +är2zu är2zw -ä5s4e -äse3g2 +2ä3s2e +äse3g +äse1i4 +äse5ref äser4ei äse4ren äser2i -äse3t -äskop2 -äskopf3 ä3s2kr ä2s1p -äs6s1c +2äs2s1c äss2e -äs4s3erk +äss5erkr +äss5ersa +äss3erw +äs2sp äs2s3t -ä4s3t2 +ä4s3t +äst4e +1ästh äs4tr ä3su ä1ß äß1erk -ä2t1a2 -ä3te +äß1ers +ä2t3a2 +2ä3te +äte3a +äte1e äte1i -ätein2 +äte3l2 äte2n -ät2h +äteo2 +äter4bl +ät2et +ät1id ät1ob ä2t3r -ät2sa +ät4s3a ät2sä ät4schl ät4schr -ät2s1i +ät2s1i2 äts3l +äts1or ät2s1p ät2s3t +ät2su ät2tei +ätte4n ät4tr +ätze3l ät2zw +2äub äu2b3l äu2br äu1c +äu3d äude3 -äu3el -ä2uf -äuf2e +äuder2 +2ä2uf 1äug äug3l -4äul +2äul 2äum äu2ma +äum3p +äumpf4 äum4s5 2ä2un äun2e -äu1nu -2äu3r +äu3nu +2äu3r2 +äure1 2ä3us. +2äusc +äu4schi äu4schm -äu3se +äu3s2e +äuse1i ä3usg ä3usk ä3usn -äu2sp +äu2s1p äus2s1c 1äuß +äut2e äu2tr -4ä1v +ä1v +ä2vi 1äx ä1z +ä3ze â1t á1n +3ba. +b2aa +b3a2ba +2babf +2babg ba2bl -2babs -bach5t4e -backs4 +ba2br +2b1abs +bach7t4e +ba4ck3er +back3s4 +ba3d2e +bade1i +2b1adel +2b1adl +2b1adm b1a2dr +ba2du 2b1af 3bah -bah2nu -bahr2e +bah6nene +bai3d bais2 +b2ak ba2ka ba2k1er ba2k1i -bak1l -bak1r -ba2kra -3bal -bal2a +ba2k5l +ba2k3r +ba2lab +ba2l1ak +ba3lal +ba2lau +baler2 +ba4l3erk +balk4a +balke4 bal4l3eh +bal4l3ei bal6lerg -2b3am +ball6erk +2b1am +b2a3ma ba2me +4bamt ban2a 3b2and +band1a +ban4dal +ban4dan +ban4dar +ban6deng ban2dr ba3n2e +2banf b1ang ban3gl -ban2k1a -ban4kl +ban4k1a +banker4 +ban2kl +ban2kn ban2kr +ban2ku 2banl +b1anna +ban2o 2b1ans -ban3t +b1ant +2banw b1anz -bar3b +ba2r3ab +ba2rad +bar3ast +ba2rat bar3de ba2rei -bar2en -bar3ins -bar3n +ba3r2en +barer5ei +barer4t +barf4 +3bar2s +bar3sc +b1arz bar3zw -3bas -ba3s2a +3b2as +ba3sa ba2sc +bas2i +bas4sa +bas4st ba2st ba4t3ent +bat2o +3bau. +bau3b bauer4l bauer4s -bau3g +bauer4w +bau1fl +bau1fr +bau3g2 +b2auk +bau3r bau1s bau3s2k -bau3sp baus4t +b1a2x ba1yo 3b2ä1c -b2är +3b2äd +2b1äh +b2äl +2bärz b2äs +2bäug 4b1b b3be -bben3 +bbe4n3 bbens2 bbe4p -bb3ler +bb3le. bb2lö +b3brec b3bru bbru2c bb2s bbu1 -2b1c -2b3d4 +4b1c +2b5d2 +bdä4 +bdän3 bde1s +bdome4 1be. 3bea +be3ab be3an -be3ar +beat2m +be3au +be4au. 3beb -b2ebe +b1ebb 1be1c -be2del +2becht +2b1e2del bedi4 -be1eh +be1e2h +bee2l +be3ela +bee4rei +be1erh be1erl +be1ert be1eta -3bef4 -be3g2 +bef4 +2b1eff +be3g4 +be2he. +beh5ri +bei3b 2b1eier bei1f4 bei4ge. -beik4 -beil2 -bei3la +beige4l +beige4p +bei3k4 +bei3l2a 2b1eime -b2ein be1ind -be1in2h +be1inh +bein6hal +bein4hi bei3sc beis2e bei1s4t +beit4e beit2s +beit4sk +beits3p 3bek 3bel +be3lag be3las bel3d be3lec -be3lei +4be2lek be2l1en +bel3ere be2let -be3li +bel3f +beli4e bel3la -be2l3ö +belle4n3 +bel3li +bel3om +be2löf bel3sz -bel3t4 -1bem -1ben. +belt2 +bel4un +1bem4 +3b2em. +3b2e3ma +2b1emp +2bemul +1ben +be5nabe ben3ar be4nas -be4nä -ben3dor +be4nat +be2nä +b2ene be3nei +be4n3end +be4ners +ben2eu 3beng -be3n2i +be2nid +be4nis ben3n -ben2se -ben4spa +5benp +b2ens +ben4s3pa ben4spr benst4 -ben2su -2bentb -b2enti +3bensz +2b1entb +2bentd +4benteu +2bentf +ben3th +ben6thei ben5t4r -b1ents -2bentw +2b1ents +2b3entw ben3un -ben3z2 +b2en3z2 be1o +2b1epi +2bepoc be1ra -be2rab +be2rak +be2r3am be2ran +bera2s berb2 -berd4 -ber4ei. +berbla4 +ber3d +be2r1e2b +be4reck be4r3eiw -be4rerk -bere4s -ber6gan. +bere2m +be4rene +ber4erg +ber4erw +bere4sc +bere4t +berf4 +ber4g3af +ber4gal +ber4gli ber4hab +beri2d ber4in. +be5r6inne +berin4s +be2ri4o ber3iss -ber3na +ber3ko +ber3kr +ber3n2a +bern2e b1ernt -be1rop +be2rö +3bers. +ber5se ber3st4a -be3rum +bert2a +bert2e +bert2i +berz2 +ber3ze ber2zö -3be1s -bes2a +3b2e1s +be3sa +bes4abb +bes2am +bes2an +be4sap +be4sar +bes2au +be2sep be2s1er -be3slo +be2s1id bes2po +bes3sa bess4e b3esst. bes3sz +be4stab beste2 be6stein -be4s3tol +bester4 +bes6terh +be4s5tol +bes4t3o4r +bes3tos best4r +be4s3trä +be4s3tur +be2sur be3s4ze 3bet -be2tap +be3tam be3tha +be3thi +bet2sp +be1un be1ur -3b2ew -2b1ex -1bez -4b5f4 +3bev +3b2ew2 +2b3e2x +3b2ez +2b5f4 bfal2 +bfal3t 2b1g2 +b5ga bge3 +bgel2e +bge5n bges4 2b1h2 -bhut2 +b5hä 1bi -bi3ak -bib2 +bi1ak +bi2ar +3bib2 bibe2 +biber1 +bi2c +bi3do bien3s +bieres4 bie2s +biet2s 3bietu +biga1 bik2a bi2ke. bi2kes +bi2kre 3bil -bil2a -bi2lau -4b1illu +bil2an +bil3ans +bil4deb +bi2lei +4billu bi2lu +2bimp 2b1inb bin2e -2b1inf -bin3gl +bine4n +b1inf +bin4fo +bin2g3a 2b1inh +bi2n3ok +bin4ol 2b1int -bi2o1 -bio3d -bi3on +2b1inv +bi2o3 +bioi2 biri1 -bi3se +3bis +bi3si b1iso -bi2sol bi2sp bis2s1c -bi2s5t +bi2st +bi3sta +bi1s4tr b2it. -b2it2a +b2ita b2ite -bi3ti +b2iti +bit4r bi2tu -b2i3tus -biz2 +bi3z2 4b1j bjek4to -2b1k4 -bl2 +2b5k4 +bl4 2bl. bla3b4 +2b1lac b3lad -b5lag b2lanc -3blat +blas3er b2latt +b2lau. +b3laus4 2b3law +2b1län b2läse +3blät b2le -3blea +3ble2a b3leb 3blec -2b3leg -2bleh +b3leg +4bleh +b4lei. 2b3leid -4b3lein -blei7sc -3blem -3ble4n +2bleih +b3lein +blei3sc +2bleit +ble3l +ble2n +b3lenk b3lese -ble3sz -b4let +2blesu +ble3s4z +3blet b3leu 2blich 3blick b2lie -2blig -bling4 -b4lis +2blief +4blig +b2lind +2b5ling4 +b2lis +2blis. b2lit -3blitz +b3lite b2lo -b4loc +b4lo. +3b4loc +b4loi b3los +3b4lum 2blun +b2lus 3blut +blu4tem +blut1o 3blü 2b1m -4b3n2 +4b5n2 +bnas4 bni2 bnis1 bo4a bo5as -b1ob3 -bo2bl -bo2br +b1o2b +bo3ben +bob3r bo2c bo3ch2 bo3d2 boe1 -bo2ei +bo2e3i 2b1of bo3fe +bo3he +boh2ra +boh3rer +boh2u bo1is -bo2l1an +bo2lan +bo2lau +bol5le 3bon. -bond1 -bon2de +bo3n2a +bon2da +bon2d1e bo2ne 3bons +boo4l +boo2ti b1op -bo1r2a +3bor. +bo1ra +bor2an +bo2r3as +bo2rau bo4rä +bor2da bor2d3r bo2rei bo4rig +bor3m bor2s b1ort -bor2t3r +bor4ter +bor6t5rat +bo4ruh bo2sc +bo3se bo4s3p +bos3t +3bot bote3n4e bo3th bot2st +bot5t +bo2xo +b1oz bö2b3 2böf -b1öl -2b1p2 +2b1öl +bölk3 +2b1p4 bpa2g 2b1q b2r4 2br. b4ra. 2b3rad -b4rah +2b4rah b4ra3k -bra1st4 +brast4 +2b3rat. +brat3er4 +bra6terg +2b3ratg 3brä +4bräd brä4u 2bre. -3brea 6b5rechte +2b3red 2b3ref 2breg b3reif -3brem +2brek +breli1 +b4rem +b4ren. +2b3rent +2breo 2b3rep b4rer +b4res. +b3rest +b4ret +bret6t5en +b4rez +bri2da +brie4fa 2b3riem +b4rien bri2er +b3ries +2brigk +b4rina +2b3rind b4rio -b3roh +b4risc +b3ritt +brob2 +2b3roh 2b3rol +bro2ma b4ron +2b3rost +bro4tr +brot3t4 +2b3rou +3b4rö b4ruc -bru4s -brust1 +2bruf +b4rum +2b3rund +brus4 +brust3 bru2th 3brü -4b1s +4b3rüb +2b1s b2s1ad -bs3ar -bsat2 -b3sä -b4sär -bs2äu -b5sc -bs2ca +bs2am +bs3amb +b4s3amt +bsau2r +b4s3är +b3s2äu +b3sc bsch2 -b6schan +b4schan b6schef -bs4cu -b3se. +bs2chi +b4sco +bs2cu bse2b b3sel. bse2n1 -b4s1erf +b3sen. +b2s1ent +bs1erf +bs1erg bs3e4r3in bs1erk -b4s1ers +bs1ers b3s2es +b2sim bsi4t +b4ski bs2ku -b4sl b2s1of +b3s2oh +b3sol +b4sop bso2r b2sö b3s2pi bs2pl -b3s2pu +bs2pu bss2 bs2t bst1a2b -bst3ac bst1ak +bst3ank +bs4t1as +b3stä bs3tät +bst3emi bst1er +bst1h +bst3ink b2stip b3sto -b4s4tob +b4stob b4stod +bs4tol +b4stor b3stö b4strac b2s3trä -bs3treu +b4s3treu bs4tri bst3ro b3stü b4stüb b2s1un -4b3t +bs2zep +bs2zi +4b1t +b3t2a +bta2s btast3r b5te -b4th -btil4 +b2t1h +bt2i +bti2s bt4r -b4ts2 -btü1 +btran2 +bts2 +b3tü1 +buche4 +bu4chec +bucher4 +bu6ch5ers bu2chi +buch3s4p bu2e3 bu2f bug3 -bul2la +bu2gr +bul2l3a +2bumf 2b3umk +2buml +2b3umr +bun4a +bun4d3er bunde4s +b1une bung4 -b3ungn +b3un3gn +2b1unh +bur1c +b2ure b2urg -bu3r4i -4burn +burg1a +bur4gan +bur4gar +bur4gin +bur2gr +bu3r2i +2burn +b3ursa +burts3 bu2sa -bu4s3cha -bu4schl -bu4sch3m -bu4schw -bus1er +bu2sc +bus3cha +bu3sche +bu6schei +bu6sch5el +busch3w +bu3shi bu2sin bu2s1p -bu2s1u -bu3tan +buster4 +bu2su +but2a +buto3re +2büb bü1c bügel3e 2b1v -2b1w -by1 -by3p -bys2 -2b1z2 +4b5w +3b2y1 +bya2 +byo2 +by3p2 +bys4 +2b1z4 +b5ze bzeit1 -1ca -2c1ab -ca2ch +1c2a +cab4 +ca3bl +3ca2c ca2e3 -ca3g4 +ca3g2 ca1h +cal2a +cala3b +cal2f3 cal3t 3cam -c4an +2can +cana3 ca2pe -3car -car3n +car5n2 carri1 +car2s ca3s2a3 -cas3t -ca3t4h +cas5to +ca3t2h ca1y2 cä3 cäs2 +c1b 2cc c1ce c1ch2 c2d2 c3do 2cec -ceco4 1ced ce2dr 2cef ce1i +ce3in 2cek -1cen +3cels +cen3a +ce3nu +cen3un +ceo2 1cer -cere3 -ce3s2h +cer3a +cere1 +cere3u +ce3r2i +ce4ris +ce1ro +ce3s4h 1cet -2ceta2 +ceta2 +cet1am ce1u 1cé -2c1f -c4h +c1f +c1g4 +c2h 4ch. 2chab -ch3a2bi +ch3a2b3i cha2ck 2chaf +2ch1a2g 2ch1ak -ch2anb +chal6l5ei +chan4a 3chanc +chan3f ch1ang -ch3anst +4chanl 4chanz -1chao +3chao 4char. -1chara +3chara +3chard 3charta cha2sc -3chato -4chatu +chasi1 +1chato +2chatt +ch5austr +chau3t +ch1äh ch1ärm ch1äs 1châ 2chb 2chc 2chd +che3b4 ch3e4ben +ch3echt +ch1edi +che2el 1chef 3chef. che4fer -3chefi 3chefs +2cheh 2chei ch1eim 4chelem che4ler +3chemi +2chemp +che4neb +che4nid +che2no 4chents 4chentw -cher3a -che3rei +che2r3a +4ch3erbs 6chergeb +4cherke cher6zie -ch3ess -2cheta +ch3es4s +ches5t +4ch1e4ta 2ch3e4x 1ché 2chf 2chg 2chh -1ch1ia -2chic +1chia chi3na 4chind 3chines 2chinf 2chinh -ch1ins -ch1int +2ch1ins +2ch1int 2ch1inv +1chip. 1chiru +2chiso 2chj 2chk -2chl2 +2chl4 ch2le +chle2i +ch3lein +ch4len +4chli ch2lu -4ch2m +4ch2m4 4chn4 chner8ei. 2chob cho2f ch1off +chof4s ch1oh -chol2a +cho3l2a ch1orc +cho4rei +ch1ori +ch2os +ch3öl +3chör 2chp ch2r4 -4chre -chre3s +2chra +ch3rad +2chre ch3rh -1chron +4chrit +3chromo +3chron +ch5ros 4chs -chst3ri +ch2spo +ch4stal 2cht +ch2tru 2chuf 2chuh 2chum 2ch1unf +2chunm 2chunt +2chur +ch1urs +2chut +chut4t 4chü 2chv 4chw @@ -2185,2255 +3500,3604 @@ chst3ri 2chz ci1c ci1es -ci2s +c1ind +cins2 +c1int +ci2s1 +1ci3t2 c1j -c4k +c2k 4ck. -ck1a +c4k1a 1cka. -2ckac +2cka2b +2cka2c +ck2ad +1ck2ag 2ckal -2ck3an +cka2m +2ckan +2ckap cka4r1 +1ckat ck1ä 2ckb 2ckc 2ckd 1cke +2cke2c +2ck1ef 4ckeff -2ckeh -ck1ehe +2ck1eh 4ck1ei -4ckense +2ckemp +cke4na +6ckensem 4ckentf 4ckentw cke2ra ck2ere 6ckergeb -ck1erh -4ckerhö -4ckerke +4ck3er4hö +ckerk4 +cker6lau ck2ern -2ckero -2ck1er2r -2ckerz -2ck1ese -2ckex +2cke2ro +ck1err +6ckerzeu +4ckese +ck2et +4ckex 2ckf 2ckg 2ckh 1cki -2ck1id -ck1im +2ck1i2d ck1in -3ckis +4ckint +3ck4is 2ckk 2ck3l 2ckm -2ck3n -ck1o2 +2ck5n +2ck3o2 +ckos6t +ck3ö2 2ckp 2ck3r 4cks -ck4stro +cks2al +ck4spen 2ckt -ckt2e +ck3te ck3t2i 1cku -2ck1um3 +2ck1uh +ck1um 2ckunt 2ck1up +2ckü 2ckv 2ckw 1cky 2ckz -c4l2 +c2l2 cle4a clet4 -clo1 +clin2g +cli2p1 +clip3a +clo1c clo2ck +clo3f 1clu +clu4b c2m2 -3co +c3me +c3mu +1c2o co2c co3ch co2d2 co3di -coff4 -coi2 +cof3f2 +coi4 co1it co2ke -co2le -col2o +co3la3 +co2leu +co3l2o com4te. comtes4 con2ne -co2pe +co2o +coo1p +co1p co1ra -cor3d -co3re +cor2da +co4re +cor3t cos3t co4te +cou3si cô4 2cp 2c1q -1c4r2 -cre2 +1c2r2 +c3rä +c4re2 cre4mes -cry2 +3crew +2cri +cros4 +2cry 2cs cs2a -c2si +cs4f +c4si +cst2 +c1s2ti c1s4tr -4c1t -cte3e -c3ti2 -cti4o +4c5t +cti2 +cti4o2 +ction3 ctur6 -3cu +c6tz +1c4u +2cua +cu2e cu2p3 +cup1e cussi4 +c1w +2cx 1cy -2c1z +c1z 3da. da1a 2d1ab +d3a2bak d2abä -da2ben -3d2abl -da2bre -dab4rü -2d1ac -d2ac. +d2abe +d3a2ben +d3a2bi +da3blu +d3a2bo +dab4ra +da2bri +da3brie +d2ab4rü +d1ac dach3a da2cho -dach1s 4d3achse +2d1ad +da2de +da2do +da2d4r d1af +2daff +da1f4l +dafo4n d1ag -dagi2 +dagi4 +dag2o +da1h dah3l -da1ho -3d2ai +dail5 da1in +2d1air da1is +da2kro dal2a -2d1alar +2d1a2lar dal3b2 +4d1all +da2lop da3lö -d1alt +2d1alp +d1al3t +2dalte +da1lü +3dam +da2mei d1amma -2d1ammä +4d1ammä damo3 -d4amp -dampf8erf -2d1amt -d2an. -2d1ana +d2amp +damp7f8erf +4d1amt +3d2an. +d1ana +da2nan +da4n4at +2danb dan4ce. -2d1an3d2 -d3anei +d1and2 +2danda +d2andy +3dane +4d3anei +2danf d1ang -2dange -3dank -dan4kl -dan5kla +2danh +dan2kl dan2k1o dan2kr +2danl +d1ann +2danna +d1a2no 2d1ans -4dantw +2dantw 2danw +d1anz d2anz. -4danzi +2danzi +2danzü 2d1ap +d2apa d2aph +da2po +da3pos 4dapp -da2r3a +d3apte +4daq +da4r1a 2darb2 -dark4 -3d2arl -dar2ma +2d3arc +dar2d1e +dare2 +daren1 +dar3g +dark2a +3darl +dar2m1a dar2m1i -da2ro -d3arr -3d2ar3s -d1art -2dart. +dar4mu +da2r3o +3dars +2d1art +dar2th +dar2tr da2ru -d2arw d1arz -da1s -dasch2 -da3s2h +da1s2 +da3sh +d1as3p +das3s das4t -3dat -dat2a -da3t2e2 +dat2e2 +da3tei +4d3a2tel date4n -4d3atl -4d1atm -3dau3e -4d1au2f -d3aug -4d1aus3 -2d1ax +da2th +2d3atl +4datm +d3ato +dat2st +2d3atta +3daub +2daud +dau3e2 +dauer3e +daue6rei +2d3au2f +2d3aug +2dauk +da3unt +2d1aus3 +dau2ß +3daw +d1ax +3däc +2d1äg 2d1äh 2d1ämt +dän3a 2d1änd -2d1äng 2d1äp -2d1ärz +2däq +2därz 2d1ä2u dä3us -2d1b4 +2däx +4d1b4 +dbau2c +dbauch3 +dbe2e dbu2c 2dc -d1ch -dco4r -2d1d2 -ddar2 +d3ch +4d1d2 +d3da d3dä +d3de d3dh -d5do 1de -de2ad +dea2d +de3ar de3a2t -3deb4 -4d1e2ben -3de1c +deb4 +3debü +de1c de4ca. de2cka -de3e4 +de2del +de2dit +2de3e4 +def4a +de2fa. 2d1eff +def4l deg2 +degene7 de3gl +deh2a dehe2 +3dehn de3ho 2d1ehr d1ei 3d2eic -3d2e1im +de3i4den +de3il +3d2eim +4deime dein2d -dein2s de3inse -de2l1a4g +de3inst +dein6sta +dein6sti +4d3einw +de3io +2deise +d4e1ism +dei2sp +2dekz +de2l1ac +del4ade +de3lak de4l3aug -del1än +del3änd +del3b2 +del3d del1ec +3de3leg delei4g 2delek 2delem -deler4 +de2len +deler2 +deler4r +2delf. 2delfm +3delik +del2la +dell3au +del2l1ä delle2 del4l3eb del4lei +del4l3er de2l1ob de2lop -de3lor -de2lö -del2s5e +del2se del2so del2s1p -del5ster del3t4 dem2ar +2d1emb dement4 de6mentg +dem5ents +de3min +2d1emot 2d1emp -d2en. +d2emu +d4en. +den2am dend2 +de2n1e2d de4n3end +de2nep 4denerg +de3n2es 4d3en4ge. -d2enh de2ni -den4k3li -den2kn +denk3li +dens4am +den6scho +dense2 4den4sem -den4sen +den6sere den6s5tau +2dentd +2dentf +2dentg den3th +2dentn 2dentw -de1nu +2dentz +den6zers +de2ob 2deol -de1on -depi2 +dep4l +2depoc d4er. -de1rad -de2rap +der3af +de2rak +dera2n +de3rand +de2r3ap +de1r2a4s +de4r3asi der2bl +4d1erbs 2derdb -de2re2b +de2r1e2b de4reck de4r3ei4s -derer3 -de3r4erb -de3r4erf -de4r3ero +5d4erem +d4eren +de4r3end +5d4erer +der4erf +derer3n +der3ero derer4t derer6ze -d4erfi -d2erh -4der4höh -d4erhü -3derie +5d4eres +de2r3eu +derf4 +d4erfl +d3erheb +d2erhü +de2r3id derin4f +de6rinnu +derin8teg +der3k2 4derklä -derm2 -4derneu +d2erm de1ro -de2rop -4der4sat -der4spa -der3tau -der6t5en6d +derö2 +der3r +derst2 +der3sta +dert7ende. +derter6e dert4ra -6der6trag -de3ru +6dertrag +der8trage +3de3ru de4ruh de4rum -des1 +2d1erz. +2d1erzv d2es. de2sa -desa4g +des1ah de4sam -des2äc +de2s1än de2seb -de4seh +de4se2h de2sei +de4seil +2d1esel des3elt -de2sen1 -de4set +de3sem +de3s4end +desen3e +de2set de2sin +des1o de2sor -de2sp +de2s1p de3spe -des3s2 +de3spu +dess2 +dess4t dest5alt -de2sto +des6temp +de5stern +des4tex +de1sto dest5rat -de4stre +de3stri des4tum de2su +des1un +3desw det2 +de3ta deten4t +2d1e2th 2d1etw +2d1eul de1un de1url de3us -devil4 -d1exi +2d1e2vid +devil2 +de1x2a +de2xer de2xis -2dexp -2d1f4 +2dexpe +2dexpo +2d1f6 2d1g2 -dga2 +dgas3tr d2ge. +dger2 +dge3s +d2gesh +dge2t3a dge4t1e 2d1h2 dha1s4 -d2his +4dho +d3hu 1di -di4ab -di2ad -di4am +di4ap +di2a3s4 +diat4 di4ath 3dic di1ce -dich1 +di3chl +dicht6er +di4ck3el +4d3i2co +3dida +d1ide +2didee +di2den +2didy di2e -di3e2d +di3e4d +di3enb die4neb -di3eni -di3ens. -di3ern -die2s3c -diet3 -die2th -dige4s +diener6l +di3e2ni +dienst5r +die2p +di3ers. +dies1c +di3e4th +3dif +3dig +dige2s +dig4n dik2a -dil2s5 +dil2s3 2d1imb -2d1imp -din2a +2dimp +din4a 2d1ind +di3n2e 2d1inf +3ding 2d1inh -2d1in1it -4d3inner +di3ni +2d1inj +2d1ink 2d1ins -2d1int -di2ob -dion3s -di1p +2d3int +2d1inv +di2o3b +dion3in +dion3s4 +di3ora +dios2 +di2osk +di1p2 +di3pt +d1i2ra di4re. di2ren +di2rin di2ris 2d1irl +2d1irr di2s1a2 +2d1iso di2sp di3s4per 2d1isr dist2 -di2ste +di1s4ta +di2s3te di4stra +di4sz di2ta -di4teng +dite1c di4t3erl di4t3erm di4t3ers -di2th +di1the +di2tin +di2tob di4t3r dit3s -di2tu -di5v +di2t1u +di5v2 di3z2 2d1j +d2jar 2d1k4 4d1l2 d3la +dla3g +dlap4 d3le dle2ra -dli2f +dli4f dl3m dl3s 2d3m2 -4d5n2 +4d3n2 dni2 dnis1 -d1ob -d2oba -2dobe -dob4l -d2obr -2d1o2f +do5at +2d1ob +3d2oba +dob2s +d1of +do2fe +2d1oh +do3ha dole4 -doll2a +doll2 +dol3la +d3o2ly +3dom +do2mal do2mar -do5na -donau1 +domen1 +do4ming +4domn +do2mu +don2a +do3nan doni1e -do2o +4dony 2dope 2d1opf -d2opp -d2o3r4a -2dorc +do1r4a +2d1orc 2d1ord dor2f1a dor2fä +dor2f1i dor2fl +dor2fo dor2fr +dor2f3u 2d1org -dori1 +d2orn 2dort -dor2ta dor4ter +dor4tr +d1os2 d2os. +2d3osm dos3s -dost1 -dot6h -do2t1o +dos4t1 +dost3a +dosten4 +do4stu +do3ta +do2tof do3un +dow2s +d2o3x2 d1ö dö2d -dö2l1 +dö2f +döl1 +döll2 d2ön 3d2ör dö2s1c -2d3p2 +4d3p2 +dpass3 +dpol4n +dpost1 2d1q d2r4 3d4ra. -2d3rad -drag4 +3d4rab +4d3rad 2drahm -d3rai -3d4ram +2d3rak +3d4ral +d3ramp d3rand +dran3k 2d3rast -d3raub +dra4tin +2draub 2d3rauc +d4rauf +2draum 2draup 2dräd d4räh 2d3rät 2d3räu -4d5re. +4dre. +2d3rea d4rea. d4reas 3d4reck -2dref -2dreg +2d3ref +4dreg 3d4reh +dre2ha 2d3reic +3d4reie d4reiv +d4rej +dreli1 4drem 4d3ren -2d3rep +d4reo +4d3rep 4d3rer 4dres. d4resc +dres6sei +dres6sel +d4rew +2drez 2d3rh -d3ri -d4ri. -3d4ria -2d5ric -d4rid -d4rif -d4rik -d4rin. -d4risc -3d4rit -4dritu -d3rob -d3roc -2d3rod -d4roi +d4ria +4d3ric +d3rieg +3drif +4d3riff +d4rift +4d3rind +2d3rip +2d3risi +2driss +2d3ritu +2d3rob +d3rod +2drogg +2drohr +3d4rohu +2d3roll 2d3rose +d4ross 2d3rost 2d3rot -d3rou +2d3rou 2d3rov -d3rö -drö2s1 +d3row +drö2sc d5rub 3d4ruc 2d3rud 2d3ruh -2d3rui -4drund -drunge3 2d5rut drü1b drü5cke +3d4rüs 2d1s 4ds. +4dsa +ds3ab +d2s1ad +ds1al +d2salk +d2sall d4s1amt d2san +ds3ane ds3assi -d2sau2 +dsau2 +d2saut ds1än +ds2äu 4dsb d4schef d4schin +d3s4co +d2scr d2s1e2b +dse2e d2s1ef ds1ehr -d3sei -ds2eig -d4seins +ds4eign +d2sein +d2s1emb +dsen3er d2s1eng d2s1ent d2s1erf d2serh d2s1erk +d2s1erl ds1err -d2s1erz +d2s1ers +d2s1ert +d2serz dse4t -d4s1eta -d3s2ha +d2s1eta +d2s1ev +d2sex +d3sha2 +ds2hak +d4shal d3sho +d4shor +4dsi d2sid d2s1im d3s2inf -d3s2kan -d3skul +ds2kal +d3s2kel +d4sko 4dsl -d2s1op +d4sli +d3soh +d2sop dso2r ds1ori d2sö -d2s1par ds1pas +d2s1pat d2spä -ds2po +d2s1pec +ds2pen +d4speri +d2s3ph +d3s2pi +ds2por +d6sporto d3spri d2spro ds2pu dss4 -dst4 -d4stabe +dst2 d4stag +d2stas ds3tauf d4s3täti d2ste -d4stea +d3stec d3stei -d3stell +d4steil +d5stell d4stem +d4sten d3s4tern ds2ti ds4til -ds4tip -ds2tu -ds1ums +d4stoch +ds4tol +d5strei +d3s4tro +ds2tur +dsu2m d2sun +ds1url ds2zen 2d1t +dta2be +d3t2ac +dtach3 dta2d +dt2ag +dta2n +dt3ane +d3t2as +dt2ax d5tea +dte3mo +dt2et d2th d4thei -dt3ho -dto2 +d3to2 +d4tob +dt2op d3tö dt3r dtran2 -dt5s2 +dt3sa +dt5st +dtt4 +dt2un +d3t2ur d3tü +d3ty 1du du1alv du1ar -dub3l -du2bli +du2b3li +du1ce +duel3la du2f 2d1ufe +duf4ter +duf4to +duf2tr 2d1uh du1i +du2in +du2kr +dul3art 2d1umb 2dumd 2d1u2m1e 2dumf 2dumg -2d3umk +4d3umk 2duml d2ump 2dumr -d1ums +2d1ums d2ums. 2d1umv -2d1un3d -dund2a +du2n +2d3und 2d1unf dung4 -2d1ungl +2dungl +2d1uni dun3ke dun2kl 2dunr dun2s +2dunsi dunst3r 2dunt 2dunw -du1o +2d3unz +du1os +dup4 dur2 dur3au -5durc +durch3 +2d1urk 2d1url -2dursa +2d1urn +2d1ursa +2d1ur3t du4schn du4schr -du4schw -dus3t +du4sch3w +1dü 2düb +d3über 2d1v2 -4d1w +2d1w dwa2 +dwa4r +dwer3te +dwes2 dwest1 -dy2s -2d3z2 +1dy +dy2l1 +dym3 +3dyn +dy2s1c +dy2sp +4d3z2 2e1a -e3a2b -eab3l +ea2be +ea2b3l +ea4br ea2c -ea3der eadli4 -ea2dr -ea2g4 -ea3ga -ea4ge -ea3gl +e3a2dr +ea2g +ea3ga4 +ea3g4l eakt2 +e2akta e3akto ea2la e3alei +e4alem +ea4l3ent +ealen4z ealer2 -e4aler. -ealer4t +e3a4lerg +e3alex +e3a2lin +eal1o +ea2lon +ea2lop e2alti2 +eal3tr +ea2l3u2 eam3 +e2am4e eam1o -ea2na +eamt2 +ea4na +ean3a2r +e3anf e2ano e3ar. ea2ra +ea3rat +e2are e4are. +ea2r1ei ea4rene e4arer e4ares -ea2sc +ea2ro +e3arz +e3a2sc +e3asf +easin4 +ea4sp eas3s -eat4e2 +eate2 eater1 -e3ath +eat4mes +eat2mu +eat4mun ea5tr eat3s2 -e3at5t4 -e3au2f -e3aug -eau1st +e3at5t2 +eatu2 +e3aue +e3auf +eau2fe +eau4fl +e4aufo +eau3n +e2av +e2az e3ä2 e1b 2eba -e3b2ak -2ebed -ebe2i -2ebel -eb2en -ebens3e -ebe4rel +e3bak +eba2p +e3bän +2ebec +ebe1er +ebein7h +eb2el +ebe4ler +ebe2lo +ebels4t +ebel5ste +ebenen3 +ebe4ras ebert4 +ebese2 +ebe4s3eh +ebe2so 2ebet +ebet4s +2ebh +2ebi 2ebl +e3blä +eb3le. eb3ler eb4leu e3blie eb3lo eb2lö -2eb2o +2ebo +e2bob ebot2 ebö2s 2ebr -eb3rei -eb4ru +e5brau +eb4rea eb2s1 -eb6sche +eb4sche ebse2 -ebs3pa -eb3sta +ebs7panne +ebs3tau eb4stät ebs3tem ebs3t2h +ebs3ti eb3str -2e3bu -ebu2t1 +2ebu +e2bunt +ebu2t3 +eby4t 2e3ca -e1ce +2e3ce +ech1am ech1ä 2e1che ech1ei +ech2en1 e6ch5erzi +e1chi ech3l ech3m ech3n e2cho. -ech1o2b -e2ch3r +ech3ö2 +ech3r +ech4ri +echs4er +echst5re +ech3tab ech3t4ei +ech6terh +echter8ha e1chu -ech1uh ech1w +2echz e1ci -eci6a -e1cka -eck3se +eci2a +ec4k +ecke4n1 +e4ckerr +eck3ser eck4sta 2eckt +3eckty 2e1cl 2eco -eco3d -e3cr +2e3cr ec1s 2ect e1d -e3d2a +ed2a ed2dr -ed2e +ed4e ede2al -ede3n2e +ede3n4er edens1 +eden4sa eden4se eden4sp +edeo2 ede2r +eder3a +ede3rat eder3t2 -edi4al +edes2t +ed2i +e3di. 2edip +edi6teng e3d2o ed2ö -eds2ä +e3drei +ed4rö +ed2sal ed4seh ed2s1es +ed2si ed2s1o ed2s1p +ed2sto ed2s3tr -ed2su -edu2s +ed2s1u +edun3 +edund2 e3dy3 -4ee -ee3a2 +edys4 +2ee +ee3a4 eeb2l -ee2ce -ee1ch +ee1c +ee4ce ee2cho -ee2ck +e1e2ck eede3 +eede1s eed3s2 -ee1e +ee1e2 e1eff eef4l -eeg2 +eeg4 e1ei -ee1im +ee2i3e eein4se +eei4sc +eeis3s +e2ela eel2e -ee2lek -ee5len +e3e2lek +eele4n +eel2ö +e2e3m2a +e1emb +ee3min e1emp e1en -eena2 -ee4nag +eena2g e2enä e2enc -e2eno +een1e +e3eng +ee3ni +e3enk +e3enl +e2eno4 een3s -e1e2pi -ee2r3as +een2z +ee3o +e2ep +ee3po +eer4at e1erbt e1erd -ee3r2e +ee3re +eer1ei ee4r3en4g -eere2s +eer2e2s +eere2t +eer3eti +e1ermä ee1ro ee1rö +e1eröf eer2ös -eert2 -e1ertr -ee3r2u +ee3r2un e1erz -ee3s2 +ee1s2 +ee3sh ees3k -ee3ta +ee3sp +ee3s4t +e2et. +ee3t2a ee4tat -ee1u -eeu2f +ee2th +eet2i +ee3t4r +ee2tu +ee1u2 eewa4r e1e2x e1f -2ef. -2efa -e2f1a2d +e2f1ad +e3fah ef1ana ef1ar +e2farc +ef3arm e2fat +2efä +ef2äl e2fäu 2efe -e3fe. e2f1e2b -efell4 +e3fef +efe4l3ei ef1em +e2femi +efe2n1 +3e2f1ene e2fent -ef2er +efer5f +eferin6d efeuil4 -2eff. 3effek 1effi ef2fl +ef3flu 2efi ef1id e2f1ins efi2s -1efku 2efl +ef4le e3f4lu +e3flü 2e3f2o -e3fra -ef3rea +2efr +ef4reih ef3rol ef3rom +ef4ru ef4rü efs2 +efs4c ef3so ef3sp ef2tan ef2tei +ef2tro 2efu e2fum -2efü e1g -egas3 -eg1d4 +ega2m +e3g2anz +egd4 e3ge +egein3 +ege4lan +ege4l3au +ege8l7ei8er ege4ler -ege4n3a4 -ege4nec +ege2lo +eg2en +ege4n1a +ege6nero ege2ra -ege4str +ege5stal +ege4s3tr ege1u +2egi +2egl e2glo e2glu e2gn eg3nä eg3ni +ego1p eg4sal -eg4san -eg4se4r1 +egsau3g +eg3se +eg4sei +egse3l +eg3si +eg4sk +egst2 eg4sto eg2th egung4 egus3 2e1ha eh1ach +eh1ad +eh2ade +e3h2ah eh2al -e2hap -eh2aus -2e1hä +ehalt4s +e3hand +e2harz +e3haut +e1hä e1he -eh4ec eh1eff -eh2el -ehe5na -ehen6t3 +eh1ein +eh1elt +e4hense +e4h3ente +ehen6tr +ehe3o 1e2hep -e3her +2eher ehe1ra +e2h1er2f +e2h1er2l ehe3str -e1hi -eh1int +2e1hi +eh3im eh1lam +eh2l3au eh1lä ehl3ein eh4lent eh5l2er -eh2lin -eh3lo +ehlo2 +ehl1or +eh2lö ehl2se ehls2t 2ehm +eh2mab +eh4mant eh3mu -e1ho -e3hol -ehr1a2 +eh3na +eh3no +2e1ho +eho2f +eho2l +eh3oly +2e3hö +ehö4rer +eh2r1a2 ehr1ä ehr1e2c eh2rei -ehr4erf +eh2rel ehr6erle +ehr4ern ehre3s -eh3ri -eh1ro2 -ehr1ob +eh4rin +eh1roc ehr1of +eh1rö ehs2 eh3sh -eh3sp eh1ste -2eht -e1hu -e2hunt +2eh3t2 +eht3h +eht4r +2e1hu +e2hum +eh1unf +e2huni +e3hur e1hü eh3üb eh1w e1hy 2ei3a2 +eia4t ei2bar -ei2bl +ei2bli +ei4blu eibu4t ei4b3ute +e4ic +ei1ce ei2cho -eich5te e2id ei2d1a ei3de -eid4ein -ei4d3er4r +ei4deis +eid5erre 2eidn -ei3dra -eid3sc +ei3do +ei3dr ei1e -ei3el -4ei3en3 +eie2b +eie2d +ei3e2l +eie2m +4ei3e2n3 eienge4 -eif2e +ei3es +eie2t +4eif. +ei1flo 1eifr -ei3g2a +eif3t +2eig. +2eiga +eig2ar +2eigä +2eige. +2eigeb +2eigeh 4eigeno -eig2er +5eigensc +4eig2er 2eiges 2eigew -ei3gl +2eigi 1ei2g3n +ei2go +ei4g3rat +2eigre +2eigrö 2eigru +2eigrü +2eigs 2eigt 2eigu +4eih +ei2hum +ei2kab +ei2kak +eik4am eik2ar -ei3kau -eik4la -e4il -2eil. +eik2i +eik2l +ei3k4la +ei3klä +eik2o +e2il +4eil. +ei4l3ab +ei2lam +eila2n +ei4l3ane +ei4lang +ei4lanz ei2lar -ei2lau 2eilb -eil3d +eil3d4 ei4lein -eilen1 +eile2n1 +ei2let eil3f4 -eil3ins -2eiln -1eilzu -ei2m1a4g +eilm2 +ei2lob +eil2ö +2eim. +ei2mab +ei2m1ag eim3all -ei2mor -e1imp -eim2pl +eim3alp +ei2m1or +2eimö +2eimp +eim2p4l +eim3sa +ei2mur e4i2n1a -ein3a2d -ei4nas -ei4nä -ein3dr -2eindu -ei4neng +ei4na2d +ei4nae +ei4n3an +ei4na4s +ei4n3at +ei2n3ä +ein3d2e +ein6derk +e1indu +2eineb +einen4e +ei4n3en4g +ei6nen6se +ein5erbe +ei4nerf +ei4nerk +ein5er6la +einer6sc ei2neu +ein4fiz 2einfo ein4fo. ein4fos ein3g2 -ein4hab +3einger +e2ingr +e2inhä +ei2nie e1init -eink4 +ein3k4 ein6karn 3einkä -3einkom -einn2 -1einna +e2inl +ein3n2 +3einna ei2n1o2 -e4insa +1einri +e6insa 3einsat -e3insta +e2insc +5einschä ein6stal -ein4sz +ein6terv +3eintö 1einu -e4inver -ei3o2 +ei3o +eio2p +eio4s ei1p eip2f 2eir +eir2c ei3re e1irr -e2is. -ei2sa4 +e4is. +ei2sa +ei3sas +ei6schwu +e4ise +ei4ser4g +ei4s3er4l +ei6s5erst ei4s3erw +1eisho +ei3s2ky +ei2so eis2pe -eis4tel -eis4th -ei1sto +e2iss +eisser6s +4ei1sto ei2sum -e4it -ei2tab -ei2tan +ei2sur +1eiswo +e2it +ei2t1a2b +ei2tal +ei2t1an +ei2tap ei2tar +ei4tat 2eitä -ei3te -ei2th -ei2tor -ei2tro -eitt4 -eit3um -2eiu -2e1j +ei2tän +eite4ra +ei4tess +ei2t1h +ei2tin +eito2 +ei4trau +ei4tro +eitsa4g +eit3t4 +4eitu +ei4t1um +ei2t1ur +eit3z2 +eiv2 +eive4 +ei2zar +eiz1in +2e3j e1k -ek2a +2ek. +2e3k2a 1ekd +ek2e e3ke. -e3ken +e3ke4n e3kes e3key e3k2l -ek3lip +ek4lo ek4n -ek2o -2ek4r -2ekt -ekt4ant +e3k2o +ekor4da +2e3kr +ek4s1p +4ekt +ek2tan +ek5t6ante +ekt3at +ek2t1ä +ek2te2l ekt3erf -ekt3erg +ekt3erk ek4t3er4z ekt2o +ek2t3o4b ek5tri -ek2u +2e3ku +ekur2a e3k2w +1ekz e1la -ela4ben -el3abi el2abt -ela2c +el3abu +ela2ck el3ader el1af -ela2h +ela4h e2l1ak -el3al -e2l3a2m -el4ami -el4amp -e6landa +e2l1a2m +el2a3mi +e3lamp +el1ana +e4landa e2lanm -el1ans +e4l1ans +e2l1ant +e4lanw el1anz 2elao e2l1ap -e2l1a2r -el3ari -ela4s -el1asi +e2l1ar +el3a2ri +ela2s +el1a4si el1asp -el2ast +ela3su +el3aufw 2e1lä -3elbis -el2da -eld3erh +2elbil +2elbr +2eld +elda2r +eld3ari +eld4arm +el4d3erf elder4p +elder4s eld5erst el3des -eld3s2 -e3lea2 -ele2c +elds2 +4e3le. +2e3lea +elea2r +2e3leb +4ele2c +el1ech +1elefa +eleg3s +4eleh +el3ehe. 2elei -e6l5ei6er. e6l5ei6ern -el1ein -e4leinf -e4leing -e4leinh +e2l1ein +e3leine +e5leit 1elek +2eleko e2l1el 1e2lem -e3lem. -el1emp +2e3lem. +e3lema +ele2mi +e3lemm +2el1emp 2e3len. +elen4k3l e4lense -e4l1ent +e2l1ent e3lep -e2l1erd +2eler +e3ler. +eler2a +el1erd +e6lereig el1erf e4ler4fa -e2l1erg +e4lerfi +e2lerg +el1erh el1erk -el1erl -e4ler4la +e2l1erl e4l3ernä -e4ler2ö +eler2ö e2l1err -eles2 -el1ess -e4l1e4ta -e3leu -2elev -ele2x +el3eru +el1erw +e2l1ess +e2l1e4ta +ele2ti +elet4ta +2el1ex +e3lex. 1elf. -el3fe -elf4l +elf2er 1elfm +elf4r 1elft -elg2a elgi5er. elgi5ers +el3g2l elg4r e2l1id -e3lie +2e3lie +eli3ef. +2elig e2lim -el1ita +elin3a +eli3no +el1ins 2elk -elk3s2c -el3lan -el3le +el4larb +ellar4t +el3lär el5le. +ell2ei ell3ein ell3eis +el4lel +el5lend +ellenen5 +ell2er +eller8fas +eller7g +ell3erh +el3les el2lim -el3lin +1ellip +el2lor +ell2ö ell3sp +el3ma +elm2e +elm3ein 2eln -el5na +el3na 2elo +e2l3oa e2lof e2lol -elon2 +e2lom +e2lonk +el1opf e2l1or +e3lore elo2ri +e3lot +e3l2ov +2elö elö2s +el3p4 +el4s5ein +el3sen +els4tri el2sum +el4tans +elte4m el5ten. +el4t3ent elter4b -3eltern -elter4s -elto2 -elt3r -elt3s2k -elts2p +elter4f +elt3erh +elter6le +3elter4n +elt5ero +elter6sc +elte2s +el4tesc +elt3eth +el3the +el5tri +elts3pa 2e1lu -el1ur +el1uf +e2l1um +e2l3u2r +elu2s el3use +elu2t +el3uto e1lü +2ely e2lya -2elz +el3z2ac el2zar -elz2e +el4zene +elz1in el2zwa +2elzy e1m -2ema -em1ad -ema2k -e2m3anf -e2m1ans -3emanz -e3mäs -em4d3a2 -e3m2en +e2m3a2b +e2m1alk +em3anf +e2m1ano +em1ans +1emanz +e4m1a4s3p +em1au +2e3mä +em2äh +1emba +1embo +1embry +em2dä +emd1r +em2dra +2eme +e2m1e2b +e2mef +eme2i +e2mele +em2en emen6gel emen4t3h -e2m1erw -eme2s -1e2meti -e2m1im -emi5na +eme3r2i +e2m1er2l +em1erw +e4mesu +3e2meti +e2m1i2d +emi2ei +e2mig +emik2 +em1im +2emin +emi3n2a +e3mind em1int -emi3ti -2emm +1e2mir +e3misc +emi3tr emma3u em2m1ei -e2mop +e2moa +e3mol +emo3s 1empf4 em3pfl +em3po +empo1s em2sa +em4scha +em4sei +em2sim em2spr em2st +ems5tr +ems3tro em3t2 -1emul +1e2mul +3emuls +emune7 +e3mur 2emü -e2n1a +e2na 4ena. -2en2a2c -en3ack -e3nad +e4na2b +en3aba +en3abo +4ena2c +en3ache +e4n3ack +enadi4 e4naf 4enah -e4n3a2k +en3ak +en1al +enal2a +e4nalb +e3nale +en2alg ena3l2i +e4nalk +e4nalm +e4nalo enal3p -4enam -en4ame +4en1am +ena4n e4nand -en3ang +en3ane +e4nant e4nanz +en1ap +ena2pa en3are -ena4sc -4enat -en3att -e3naue +en3ark +en3aro +en1as +ena2sc +e4nast +2enat +4e5nati +e4natl +enat4s +e4n3att +4enatu +e4nau2f +en3aug +e4n3aur +e6nausta +e4naut +en1a2x +en1a4z en1ä +en3äb +e3näi e2när -en4ce. -en3d2ac +en2ä3s +en3äst +en2ce. +end2ac en2dal -en4d3ess -end4ort -end3rom +en4dang +2endel +ende4lä +en4d3es4s +en2dex +en2did +en3d4ort +end3s4au +end3s2l end3s2p end3sz -end2um +en3d2um +en3d2ü 2ene. -ene4ben +en3e4ben en1e2c e2neff +ene2h en2eid e3neien +e4neige +4eneigu e4nein +e4neis e2n1el ene4le -2enem +2ene2m +e2n1emi 2enen +e4nense e4n1ent en4entr +en3envi +en1ep 4e3ner. +en2era e2n1erd +en3erei e2nerf -1e2nerg -e4nerh -e4nerk +en4erfr +1energ +e2nerh +e2nerk e2n1erl +e4nermi e4n3ermo 4enern +e4n3erne +ene2ro e2n1err -e2n1ers +en1ers +4eners. e2n1ert +en4ert. e2n3eru e2n1erw -e4nerz 2enes -e4n3ess +e3nes. +e2n1e2sc +e2n1esk +e2n1ess +en1eta +e2n1eth +en1eul +e2n1e2v +e4ne2x en3f -enf2a enf2u 1engad -3engag -enge3ra +1engag +en3g2al +enge3r4a en3g2i -en3glo en3gn +en3g2o 1engp +eng4ra eng3se 2eni e3ni. e3nic -e2nid -e3nie +4e3nie eni3er. +eni3erp eni5ers. -e2n1i4m +en3i2ko +en3ill +eni4m +en1ima +en1imi e2n1in e3nio eni2ö -e3nit +e2nir +eni4sa +e4n3iso +e3nit2 +e3niv +enk3aus +3enkeli +enk3erg +en4k3erk en3k2ü -e2n1o2b -enob4le +en2nef +en2nel +en4ner4f +enn3erg +en4n3erl +enn2i +enni6ger +2enniv +enns2 +enn3ste +e2n3oa +e2n1ob +e3nobel +eno2br e2nof -en1oh -e3nol +en3olm eno2ma -en1on +eno4n e2n1op e2n1o2r -enost3 -e3not +en2ora +eno4ri +4enorm +e2n1ost +4e3not eno2w 2e1nö en1ö2d -en3sac -en2sau +en3sabb +en2san en5sche en2seb -3ensem -ensen1 -en2sep -en4seta -en3ska -en3sp -ens2po +1ensem +ensen3e +ens3ere +en3spo +ens4por enst5alt en4s3tät +ens4tel +ens6temp ens2th 2ensto -e4nt -ent4ag -ent4ark +enst2ü +en5t2ag +en4tanm +en4tanw +en3t4ark 1entd -en2teb +en3t2el +ente2n +3entera en4terb 1entf 2entfo -1entga +1entg 3entgeg en2thi +1enthu +1enthü +en4t1id 3entla 1entn +en2tob +entopf3 +en2t1os +2entö en4t3rol -3entspr +1entsc +1entso +ent4sto 1entw 4entwet +3entwic 1entz -en1u -2enut +e2n1u +e3nu. +e4nu4r +2enu4t +e4nuto e1nü enü1st 4enwü -e1ny -enz1ec -en4z3erf -en4z3erg +2e1ny +en3zare +enz2äp +1enzep +enz3erg en4z3erk +en4zerl +en4z3erm +enz5ersc +enzi2d +enzlan4 +enzo2l +1enzy e1ñ -2eo +4eo e1o2b1 +eo3ben +eo3bl +eo3bo +eo3br +eo1c +eoch2 +eo3dr e1of -eo2fe +eo3g2 e1oh -eo3m -e1on. -e1ond -e1onf -e1onh -e1onl -e1onr -e1ons -e1ope +eo3la +e3o2ly +e1on +e3o2nat +eo1o e1opf -eop4t +eop4r e1or e3or. +eo1ra e3orb +eorgi1 e3ors +eort2 e3orw eo1s2 e3os. -eota2 -eo3ul -e1ov -e1ö2 +eo3se +e1oste +e1ou4 +eo1ul +e1ö4 e1p +2ep2a epa2g +epas6ser +2eper e3p2f4 -e2pis -1episo -2epl +e5pfi +1e2pid +e2pig +e2pik +1e2pile +e3pio +1epis +2epist +1e2pit ep3le -1e2poc -ep2pa -ep2pf -ep4pl +1epoc +eport4 +1e2pos. +ep2p1a +eppe3l +ep2pl ep2pr -ept2a +2epr +ep3sh ep2tal +ept2an +ep2tau 2e3pu epu2s -e1q +4e3q er1a e3ra. era2be +e2r3a2ch e3rad. -er3adm +e3radi +e2radj +e2radm +e4radmi +e4r3adr eraf4a era2g +e1rah e1rai er3aic -e2rak -e1ral -er3all +e3rake +e1rald +eral4eb +er3alke +e2r3all +er2an. +era4n4a eran3d -e3rane -er3anf +e3rand. +e4rangr e2ranh -er3anm +e2rano e1rap +er3apa er3apf e2rar +er3are e3rari -e1ras -e2r3a4si -er4ast +e3ras. +era2si +e1rast era2ß -e2rath -e3rati -e2ratm +e4ratel +e2ratl e1raub +e1rauc er3aue erau2f er3aug +e2ra2v e1raw +e2r3ax e1raz e1rä +er1äf er1äh -er1äm +er1ä2m +er1äp e2r1äs +er1ätz +3erbarm +erb2au erb2e -erb4sp +2erbru +erb2sp er1c er3chl +erch2o +erd2am erda3me 1erdb -er3de 2erdec -erde3in +2erdel er4d3en4g erd3erw -erd3s +erdes4t +erdeu2 +1erdg +erd3st +2erdy 4ere. -er1eb -e3rech +er3e4ben +e3r2ech er3echs er1e2ck er1edi ere4dit er1eff -er1e2h +e2r1e2h +ere4i 4e3rei. +e3reib er1eig -e2rein -e4r3eis. -ere2l -er1ele +4ereih +e4r3eime +e4reink +er3eis. +er5eisar +er3eisb +er3eisf +er3eisr +erei5str +e4rek +er1e2l +e2rele ere3lev -2e3rem +ereli1 +2erem +4erem. +er1emi +ere4mis e2remp 2eren 4e3ren. e3rena +eren1e e4rense -e4rentf e4rentn +e4rents e3renz eren8z7en8d -er1ep -2erer +er1epe 4erer. -e2r3erf -e2r1erh -4erern -e3rero -er1err +2ererb +erer3fa +e4r3erfo +e2rerh +e2rerk +e2rer2l +erer5lau +4erern. +e4rerne +e2rer2o +erer4ri er1ers +4erers. +e8rersche e2rert -er1erw +2ererv +2ererw 2eres +4eres. +ere2sp er1ess -e4r3e4ti -er1eul +eres3sk +er1eta +er1eu ere4vid erf2e -er3f4r +4erform +erf4r 4erfür +er4g3are +4ergebi 3ergebn +4ergebü +4ergeha 4ergehä -erg3el4s3 -1ergol +ergel4s3 +erg5elst +4ergeni +2ergn +er2gop 4ergrem -erg3s +erg1s +erg3s2o +ergs2p ergs4t -e2rh +e4rh 1erhab +er3hag +2erhai 4erhals -er3he -4erhöhe +2erham +2erhan +2erhas +er3hei +2erher er3hu -2erhü 2eri e2riat e3rib 4e3ric -er1i2de +e4r3ico +er1id 4e3rie -eri3e4n3 -e3ri3k4 +eri3en1 +e3ri3k +erik4l 4e3rin. -er1inb +e2r1ind e2r1ini er1ink -er1ins +er1inl er1int -e3rio +er1inz +e2ri2on +4eris +e2riso +e2risr er1ita +3eritr +e3riv 2erk. +2erkaj +er3ker 1erklä -er3ko +2erkm 2erkre -erk3t +erk5t4 +er2kum +2erl. 2erlag 3erlebn -4erln -erm2e +4erleh +2erln +er3m2 ermen4s -erm3ers +er4m3ers +er4n3alt +er3ne +er4nene +er4nerf er4nerk +3erneue +er2nob +erno2r ern1os -e1ro. -er3oa -er1o2b +2e1ro. +e1roa +er1ob +ero2bl +ero2br e2r1o2f e1rog -e1r1oh +e1roh e1rok e1rol +er3oly e1rom -e3ron -er3ony -er1o2p -e4ro2r +er3omb +2e3ron +e2r1oo +er1op +2e4ro4r +eror2a e1ros +1erosi +e3rosit e1rou e1row -er1ox -e1roz +er1o2x +er1oz erö2d -2erök +2eröh +erö4l er1ös -er3p4 +erö2sc +er3p er3rä +2erren +er3ro 2errü -ersch2 +er3s2a +ers4ana +ersch4 er5schn -er3se -ers2i +4ersei +ers2el +er3sen +er5s2i er3sk -er3smo -er3sn -er3sp -er5stel +4ersted +er3stel +erst5ers +4erstil +ers4tod +ers6tr +er3swi er3sz -ert2ak -er6terei +ert1ab +er3tat er4t3erf +er4t3er4g er4ter4h +er4ter4k er4ters -er2t3ho -4er3ti -ert3ins +ert1h +er2tho +4ertö +er5tri +4ertru erts2e -2ertür +erts2p 2eru -eruf4s -er1u2m +eruf4s3 +e4r3uhr +er1u2m1 er1und +e4rundu erung4 -er1uns -er3uz +er1up. +er3ur +er3use +e2r3uz erü4b 3erweck +er4zerk +er4z3ers es3ab -e3sac +e4sabe e2s1a2d +e3saf es3ak -es4ank +e4s3all +es1ami +es3ampl +es2ank +es2anm +es2anr es3anz -e3s2as -e4s3ato -es3av +e3sap +es2apa +esa2ra +e3sa2s +es2ast +esa2v +es1ax 2esb esbi5er. -es2c -es3cap -e3sce +e3s2ce esch2 -e3scha -e2s3ein +es4chi +e2s3ec +es1ehr +esein4s es2el -es3eva +ese4nal +ese4neu +esen3o +es2ens +esen3sk +esen3th +eser4at +ese4r1u2 +eses2k +e2s3e2x 2esf -4esh +2esh es2har -es2id -e2sil -es1ini -es3int -es2ir -es2is +es3he +2esi +esi1er +e2s3i2k +e2s1il +esi2st es2kat -e4ske -es3kl +e4s3ke +e4s3kl es3ku -e4sky +e4s3ky es3l -es4log 2esm +e2s3oa +e4s3ob +e2s1od +es2oh eso2r +es1ora +eso3re es2ort -es2ö -2esp +e3sot +e3s2ö +4esp +e3spal +es4park es2pek -e3spi +e4spers +e2sph +e3s2pi e3s2por -e3s4pra 2esr +2ess. +es2s1ag essali3 -es2sau -es3sc -es3se -4essem -ess4e3re +essau4s +1essay +2essä +2es3sc +ess6ere +ess4erf ess3erg +ess5er6la +2essk 2esso es2sof +2essp es2s1pa es2spu +es4stab +ess3tie es3stu estab4b -es4t1ak +esta3ge +est1ak +es4tanb +es4tang +e4stant +e1st4ap e1star e4starb -1e2stas +e2st1a4s e1stat -e1s2tec -e3stel +e4stat. +e4staum +e4staus +es2tec +este4i +est5eing +est5eink +est5einl +e1ste2l +es4t3emi +e4sten es4t3eng -es4t3erh +est5entr +est5erha +es4ter4ö +es4t3erz es4t3ess +es2th +es2tid +e4stig e1stil e2stip +es2tis estmo6de -est3ori -e1str +1estn +e2stom +e3strec es4tri -es3trop +e1strö e1stu -e1s4tü +est3ums +es2tur +e1s6tü +e3sty +e3suh e2s1um es3ums -es3w +es3unt +es1ur +esu4s +2es3w e3sy es3z -e1ß -eße3r2e +es4zene +2e1ß +e2ß1el +e2ßent +eße3re +e2ß1er2g +e2ß1erl +eß3t e1t etab4 -et1am -eta2mi -3etap +eta2c +2e3taf +2etal +et1ami +et4an. et4at +etat3r et1äh 2e3te +ete2e +e4t1ef e4t1ein ete3ke -et2en eten3d2 ete2o eter4hö +ete1ro eter4tr -et2h -et3hal -ethi1 -et3hü -e3ti +ete2s +2eth. +et2ha +e4t3hal +e3the +et2hi +e4thik +3ethn +et2hu +e4t1i2d eti2m +etin1 +et1ini +et2it eti2ta -2eto -eto2b -e2t1of +eti2th +et3l +2e3to +e2tob +e4t1o2f +et4on +eto4n3al etons4 -e2torg -e3tö +e4torg +eto2s 2etr +et3rad e4traum -e6t3rec -e2tres -et4rig +et3rec +e2t3res +et4ros +ets2c +etscher7e etsch3w -ets2p -et3su +ets1p +et2spe +et2ste ett1a -et2tab +et2ta2b et2tad -et2t3au +et2tak +et4tans +ett2as +et2tau et2tei ette4n1 -et2th +ett4er +et2t1h et2t3r -et4tro -ett3sz -et4t1um +et2t1um +3e2tui +e3tur e3tü etwa4r +1e2tym 2etz -et2zä -et4z3ent -etze4s et2zw eu1a2 eu3b4 -euen2g -eu3erei -eue6reif -euer4ri +2euc +euch4ta +2eud +eude1s +eudi4e +2eue +eu2eb +eue6r5eif +eue6reis +euerer6s +euerer6t +eu3eri +eu3erk +eu3err eu2esc -2euf +4euf eu2fer -eu2ga -eu4gent +eu2g1a +euge4mi +eu6gense eu3g2er +eugin2 +eugin4f +eu4gin4g +eu2gre +eu2gri eugs4 -eu1in -1euk +eug3sp +eu3h +eu1id +eu1in1 +e4uk +1eukal eu2kä -e1um +eulan2 +euland3 +eu3l2e +eul2i +2e1um e3um. +eu3m4a e3umb +e3umf e3uml -e3um2s -eum4sc -eums1p -eum3st +e3um2s1 +eum5st +e3umw 2eun +eu2na eun2e eu4nei -eun4er e3un2g eu2nio +eu4nis +eunk2 eun3ka eu1o2 -eu3p2 -e2u3r2e +eu1p +e1up. +eu3p2f +e3upg +eu4r1an +eu4r3ast +eura3t +eu2rau +eur1c +e2ure +euren2 +eu4rens +eur4er +eur3f4 1euro -eu2rys -eu4sis +2eus +e3usar +eusch4o +eus2i +eu4sk eu3sp eust4 eu1sta eu1sto -eu1str +eu1s4tr 2eut +eut2e eut2h +3eu3tha +eut2i +eu5t2o +eut6scha eut6schn +eut6schr 2eux +eu2za eu2zo eu2z1w e3ü -2e1v -e2vela -e2vent -4ever -eve5r2i -e3vo +e1v +e2vak +e3var +eva4s3 +2ev2e +eve5ri +evie3le +2e3vor e1w -2ewa -e3wä ewä2s -2ewe e2we. -ewinde3 +ewei4sc +ewert4 +ewer3te e3wir ewi2s e3wit -ew2s 2ex. +1exam ex3at -1e2xem +2exc +2exd +e2xel ex1er +2exes e1xi -2exie +2exik +e2xil e2x1in +e3xio 1exis ex3l -3exp +1exp +2expu +2exs 2ext. +2ex2ta ex2tin -ex2tu +1extr +2extu +2extv 2exu -2e3xy -ey1 -ey4n +e2xum +2e1xy +2ey1 +eyl2 +ey2n +ey3no eys4 e1z e3z2a +ez2ä e2z1enn e3zi ezi2s +e3z2o ez2w +ez3z2 é1b é1c é1g +égi2 é1h -é1l +é1l2 élu2 +é1m2 +é1n é1o é1p -é1r +é1r2 é1s -é1t2 +ési2s +é1t é1u2 é1v é1z2 è1c è1m -è1n +ène1 +ènes4 è1r +1ën +ë1t ê1p ê4t 1fa fab4 -f1abe +2f1ab5b fa2ben -2f1a2bl -fab5s +2fabf +2fabg +2f1a2b5l +2fabn +3f2abr +2f1ab5s +2fabw fa4cheb +fa4chel fa2ch1i fa2cho +fach3s4p +fa2dan +fa2del f1ader +fa2di fa2dr -f4ah -faib4 +fa3e +fah6l5ent +3fahre +5fahrt +fai3b +f1a2ka fa2ke -f2al -fa3l2a +f3aktio +f4akto +3f2aku +fa3la +fa3le fal2kl -fal6l5er6k +fal2l1a +fal4l3ei +fall5ent +fal6lerk +faller6s fal6scha fal6schl fal6schm -fal3te +fal2tr +fa2mei +f1amp f1amt -2fanb -2fanf +3f2an. +fa2nar +fand2a +f2anf +fan2ga fan2gr -2f1ank +2f1an3k 2fanl +4fann f1anp 2fanr -fan3s 2fanw -f1an3z -2f1ap +2f1an3z +2f1a2p f2ar -far2br -farb3s -2f3arc -3fari +far2b1a +far4bel +far4b3er +far4bin +farb1l +far2bo +far2b3r +far2b3u +f3arc +3fa5ri +far2r1a farr3s -f3art +2f3art 2f3arz fa3s4a fa3sh +fa2st +2f1astr +fa2ß f3at +f4at. fa2to +f4ats 2f1auf f3aug +fau2s f1ausb +faus4t3r 3f4av fa2xa 1fä -fä1c -fäh2r1u +3fä1c +fäh4rin +fäh2ru f1älte +2fäq +3färb 2f1ärm -f1ärz +2färz +fässer4 +fäs6serk +fäs6serw fä2ßer -2f1b2 +2f1ätz +2fäug +2fäx +4f1b4 +fbau1 +fber2 2f1c +f3ch 2f3d4 -fdie2 +fdien2 1fe +3fe. featu4 fe2c f2ech fe3che -2f1eck +fe2del fe2dr -fe2ei +fe2e1i +feein5 fe1em -fef4l +2f1e2he +fehle2 feh4lei -f4eie +f2eie +f2eind 2f1eing -4f1einh -fe1ini +fe3ini +fe3ins. +fei4nu 2f1einw f1eis -fek2ta -fe2l1a -fel4da +fek4tin +fe2l3a2 +fe2l1ä +fel2da +felde4m +feld6erh fel2dr 2fe2lek +2felem fe2l1er fe2les -fel4lei fe2l1o -fel4soh +fel4s3oh fels2t -fel3t4 +felt4 +6fel6tern f2em. +2femb fem4m 2femp -fen3a2 +fen3a fe2nä +fend2 +4fenerg +fe2ni fe2no fen3s2a -fens2c +fen5s2c fenst2 f1ent +fen3t2a +2f3entf +f2enti +4fentla +f2ento +2f3entw +4f3entz 3fep +fe2pi f2er. fe1ra -fer2an +fe2rab +fer3a2d +fe2ral fe4rang -fe4r3anz +fer4ant +fe4ranz fe2rau fe2r1ä -ferde3 +2ferd. +fer3da +fer3d2e3 f2ere -fer2er -fer3erz -f1erfa -fe2rid -3ferk -f2erl. -4ferneu -fe1ro +fe2r1e2b +fe2rec +3fer2ei +4f3ereig +fer3eis +f4erel +fer3ell +fe4rer4g +fer4fah +fer4fol +ferg4 +f4ergr +feri2d +ferie4n3 +feri4on +4fer4leb +f2ern. +fer4nei +fe2rö f4erpa +f4erpf +f4erpl +f4erra +fer4reg +ferri2 f2ers. f2ert -f1erw -fer8zeuge +fert4r +f2erz +fess2e fe2st -fest1a +fest3a4b +fest3an fest3ei -2f1eta +fes4tel +fes4t1o +fes4t3r +2f1e2ta fe4tag 3fete -fet2t3a -feuer3e -feu4ru +fe2th +fet4t3a +fetti3s +2feu. +feuer3ö 3few -f1ex -2fexp +2f1ex +fe1y2 3fez 1fé -2f1f +4f1f +ffab6s +ff1a2d +f3f2ak ff3ar -ff4art +f3fas +ffa2t ff1au -ff2e +f2f1e2b ffe2e -f2f3ef -ff3ei -ffe1in -ffe2m -f2f3emi -ff4en -f2fex +f2f1ef +f2f1ei +ffe3in. +f5fek +ff1e2m +f2femi +ff2en +ff3erle fff4 -ff3lag +ffi3k +f2fim +ffin3s +ff1lag +ff3le ff3li -f3flu f3flü +ffo2r +ff1ox f3f4rä -ff2s -ffs3tan +ff3ro +ffs2am +ff2s1p +ffs3tie +ffs3tut +ff3stü +ff3t2 +ffus3s +f2fy 4f3g2 +fgeb2 fge3s -2f1h2 +fglim2 +4f3h2 1fi 3fi. +fi4ak +fi2ar fi3at -fid2 +fid4 +fi2do +f2ie +fi2e1i fien3 fi1er2f +fi2gr +fi2k1as +fi2kel fi2kin -fi3kl -fik1o2 -fi2kob -fi2kr +fi2kn +fi2k1o4 +fi4k3r +f2il fi2l1an -fil4auf fil3d fi2les +fil2et filg4 fi3li fi4lin fil2ip -f2ina -fing4s +fil2ma +fil2mä +fil4med +fil4mei +fi2lo +2fimp +3f2in2a +fin2e +2f1inf +fing2 +fing4s4 fi3ni +f2ink fin2s fin3sc -fin3sp +fin3sti 2f1int fi2o fi3ol fi2r fi3ra fi4re -3fis -fis2a -fisch3a +fir3me +fi3s2a +fi4sch3a +fi6schei fisch3o -fisch3w +fi4schr +fi4sch3w +fi3s2h +2f1iso fis2p -fi2st +fi2s3t +fite2 +fi2tin fit1o2 -fi2tor -fi3tu -3fiz +fi4tor +five4 +fi2xel +fi2za 2f1j +3f2jo 4f1k4 +fka4t3 f2l2 2fl. f3lad -flan3d +f5land +f4lans f3lap +f4lasc +f3lats +flauma4 1flä 3f4läc -2f5läd -f3län +4fläd +2fläh +2f3län +2flär 2f3läu +f5le. 2f3leb -2f3lein +f4lee +2f5lein +flek3 +flekt2 f3ler +f4lex f3li. 3f4lim +f3lind fli4ne +f3ling +2f3lins 2f5lon 1f4lop +1floß 1f4lot flo2w f3lö -4f5löf +4flöf +f4lög +3f4luc +f3luf 1f4lug -flu4ger +1f4luss +f4lut +flut1o f4lü f5lüm -2f1m2 +fly1 +4f3m2 +fma5che fma2d -2f3n2 +4f3n2 fni2s 1fo +f1ob +fo2be +2fober fob2l 2f1o2f -foli3 -fol2k1 +5foli3 fo2na +fo4nan fon3au -fon2e +fon3dr +fo4n3in +fo2nop +fons4 fo2nu 2f1op -fo1ra 4f3org -fo3rin 3form for4m3a4g +for4mas +for4m3ei +for4min forni7er. +for6schl for4st -fort3 -for4tei -for2th -for2t1r +for4t3ei +for4ter +for2t1h +for2t3r +fort3s2 for3tu -f1o2x +for2u +fot4r 1fö 2fö2f 2f1ök -2f1öl -för2s -4f1p2 +4f1öl +för4s5 +4f3p4 2f1q -f2r2 -f4rac +f2r4 +f3ra. frach6tr -2f5rad +2f3rad +2f3rah fra4m f3rand f5rap +fras3ta +f3rat +1frau. +f3rauc +2fräd 1f4rän 2fre. f3rec f3red -2freg +2fref +f4rei. f3reic -freik2 -frein2 -f3rep +f4reie +frei1f +f4reig +frei3k2 +2frein +2frek +2f3rep +2frest 3f4reu 2f3ric +fricht6e fri3d fri2e 2frig +f4ri3k +f3rip 1fris f4risc -f3roc -1f4ron -fro2na +f4rist +2f3roc +2frol +1f4ro2n +fro4n1a +f4rop fro2s f3rot +frös2 f3ru +f4ruc f3rü 4f1s -fs1all -fs4amm -f2san -fs3ar -f2s1as -f2sauf -f2saus +f2s1al +f2sa2n +fs3ane +f4s3ar +f2s1a2s +fsa2t +fs3ate f2saut +fs2än f3sc +f4sca f4sce f4schan f4schef -fs4co -fs1e2b +f4schro +f4scr +f2s1e2b +fse2ei f4s1ehr -f2s1em +fse2n +fs1en1e f2s1ent f2s1er fse4t -f4s1eta -f3si -f2si2d -f3s2kie +f2s1eta +f2s1i4d +f3s2ky f2s1o2 -f3span +f3soh +f3sol +f3spann f2s1pas -fs1pen f2sph -f3spi f3s2pl f3s2por -fs1pr f2spre -fs2pri f2spro -fs2pru +fs2pul fs3s4 fs2t +fst2a fs3tak f2stas -f4s3täti -f3stei -f3s4tel +f3stat +fs3tät +f4stäti +f3stel f3stern fs3th f2stip -f3st4r +fs4tol +fs4tor +fst4r f4s3tres fs3trü -f3stü -f4s3tüte +f4stüte f2s1un f3sy 4f1t f4ta. -f2tab ft1a2be +ft1abl ft1af -f2t1al +ft2ag +ft1ala ft1an -ft1ar -f3tat +f2t1ap +ft1a2r +ft3att f2t1äu -ft1e2h +fte2c +ft1eck +ft1edi +ft1eh +fte2he ft1eig ft1ein ft1eis +ft1eli +fte3ma +ft1emi f4t1ent -f4t1e4ti -f2th -f4thei -ft3ho +ft3erfü +ft1erk +f2t1erl +f2t1erz +f2t1e2ti +f2t1ex +f2t1h +f4t3hei f2t1id -ft1op +f3tik +f2tim +f2t1in +ft2ing +fto2 +f2t1of f2t3ot -f3tö -f2t3ro -f2trö -f3t4ru +f3t4ran +f2t3res +f3treu +ft4rit +ft3ro +ft3ruh ft2s1 -ftsa4g ft4sam ft3s2c ft4sche -ftse4 +ftse2 ft4seh +ftsen1 ft3st -ft4s3tan -ft4s3tä -fts2ti -ft4stri +ft4staf +fts3tät +ft4stei +ft4stem +ft6stier +ft6s5treu +ftstro4 +ft4stru f2tum +ft1urk ft1url f3tü ftwa4 +ftwa6r ft3z2 +ftze3d 1fu 3fuc 3fug -3f2uh -f1um +f2uh +fuku3 +fulb4 +f1um1 +fu2mei +f2umm +fund3er +fun6derg +fun6derh 2f1unf fung4 +2fungl 2f1u2ni fun2kl fun2ko fun2k3r +fun2ku 2f1unm +2funr 2funt f2ur +furch2 fu4re. +2f3url fus2sa fus2s1p fus2st @@ -4441,479 +7105,782 @@ fu2ß1er 3fut 1fü 2füb +fühl4sc +fün2 fü2r 2f1v -2f1w -1fy -2f1z +4f1w +f1y +4f1z fz2a fzeiten6 -fzei8tend +fzei8t7end fz2ö -fzu3 -fzu4ga -f3z2w +fzu2ga +fz2w 3ga. 2gabf -ga2b5l -gab4r +2gabg +2g1a2b3l +gab2o +g1abr +gab4ri +2gabsc +g2abt. +2gabtr +ga3bu +2gabw 2gabz ga1c -2gadl -2ga2dr +gade2r +ga3d2i +gadi4e +ga2dr +gae2 ga1fl -ga3ge -5gai +5gag. ga1k ga2ka +ga2ku gal2a -2g1a2lau -g1amb -g4amo +ga3laf +ga2lar +2g1alau +2g1alb +2g1alg +gal3lo +2g1alp +2g1alta +2g1altd +g1a2lu +ga2mec +ga3mel +gam3ma +5g4amo 2g1amt -2ganb -gan3d +g1a2na +2ganal +gan3d4 +2ganf +2ganga 4gangeb gan2gr -2ganh -2g3anku +gang4sp +gan2g1u +2g1ank 2ganl -g3anla +2ganmu 3g2ano +ga2nob +2ganr +gans2 +g2ans. +2g1ansi +2ganst 2ganw ga1ny +2g1anz +ga3pe +2g1app +ga1q 3gar. -2garb +g2ara 2garc -3gard -2g1arm +3g2ard +ga3ret +ga3r2i +2g3arm ga3r2o -3g2ars +gar2s 2g1arti ga3ru 2g1arz +g2as. ga2sa -gas3ei +ga4s3al +ga4sam +gasche4 +gase2 +ga2sei +ga2sel +ga2se4m ga2si ga2sor -ga3sp -ga4spe -ga4spr -gas3s -gas4ta -gas5tan +gas3s2 +5g4asse. +g3asses +6gassess +ga2st ga4ste gas4t3el -gat2a -2g1atm +ga4str +gast3rä +ga3t2a +2gatm gat4r gau1c 2g1auf 2g3aug g2auk -g1aus +gau5ne +2g1aus 2g1aut +ga3z 2g1äp -2g1ärz -gäs5 +gär3th +2gärz gä4u -2g1b2 +2g5b4 gber2 gbi2 gby4t 2g1c 2gd g1da +g3d2ad +gda3de +g2d1ak +g2d1an +g2d1ar g2d1au +g1dä1 +g2dei4 +gd1els +g2dent g2d1er -gd1in +g2d1et +g2d1in g1do +g2dop g1dö -gd3r +g1dr +gd3re +gd3ru gd3s2 gdt4 -gd1ur -1ge ge3a2 +ge4ate geb2a -gebe4am ge3ble -geb4r +geb4lin +geb4lo +gebot4 +3gebü ge1c -ged4 +ge3ck ge1e2 ge3ec ge2es -gef4 +geest3 +ge5fa +3gefä +4g1eff +gef4l +gef4r +ge3fu +g4eg +gege2n1 +gegene4 +gegen3s4 ge3g2l -ge3ha +geg4r +geher3l +ge3ho +2g1eid +ge4ie2 ge4ig -ge1im -ge2in. +g2eil +ge1in1 +ge2inf +gein4h +2g1einr gein2s -ge2int gein2v ge1ir -ge2is -2g1eise2 +2g1eise gei3sh +geis4s3c +gei2st +geist3r 2gek. ge4lanz gelb1r gel4b3ra +gelb3s +gel4den gelder4 +gel6derh gel6ders -ge3le -2ge4lek +ge3lec +gele5cke +ge2lef +2ge2lek +2gelem +gelen1 +ge4lene +gel3ere +ge4lerk geler3ö ge4l3ers -ge4less -gell2a -ge3lor +ge2l1ev +gel3f +gel1i4m +gel3la +gell2i +gel2ö gel3sa gels2p gels2t gel3ste gel3sz -gel3t2a -ge3lü -gelz2 +gel3ta +gelt4r +gel3z2 gem2 -gem4e -ge3mi -3gen +ge4ma. +gem6e +4g1emp +ge3mu +g4en. ge3na -ge4n3ac +ge4n1ac +ge4nad +ge4nak +ge4n3al ge4nam +ge4nap ge4nar -gen2as +ge4nat gen4aug -gen2d1r -gen1eb -ge3nec +4genda. +gend3in3 +4g3endmo +gen2d3r gen3eid -gen3ern +gener4f +4generg +ge4n3ern gen6erwe gener4z +ge2nim +gen3k4 gen3n +ge2noc gen4sam +gen6semb +gen3sk gen3sz +gen3tä 2gentf -gen3th -4gentw -geo2r -ge1ou -ge3p4 +gen3t2h +gen5tr +2gentw +gen3zw +ge1oo +geo2ri +g2ep4 +ge3pl +ge3po ge1ra ge2rab -4g3ereig +ge2rak +ge2r3al +ge3rann +ge4rant +ge4r3a2r +ger2as +2gerdg +ge3rem +ge4rene ge4reng ge4ren4s ge4r3ent ger2er +gerin4d gerin4f ger4inn gerin4t +4ger4klä +g3erlas +ger5me ger3no +2g1ernt ge1ro +ge2rob ge1r2ö -ger4sto +ger4sat +4g3er4seh ge3r2u -g1erwa -4g3erwer -g2e1s2 +ge1s2 +g4es. ges3auf +3ge3sc +gesch4 +ge6sche. +ge2s3eb +4g3e4sel. ges3elt ge2s3er +ge3sha ge3si +ge3so +ge3spa ges4pi -ges3s2t +ges3se +ges3s4t gest2 -ge3ste +gest4a +ge3stak +ges4tan +ge3st6e ge4s3ter ges3th +ges6tier +ge4s3tur ge3t2a -2getap -ge5tr -ge3t4u +ge4tang +ge4tant +g1etap +ge2thi +ge5trei +ge5tri +ge5t4u 2g1e1ul -2g1ex -2g1f4 -4g1g +ge3unk +ge1urt +ge3u4t +4g1e2x +2g5f4 +gfi2l +2g1g gga4t -g3ge +g5ge gge2ne -g2g3l -gg4lo +gg2l +g3gla +g3glo g2g3n gg4r +ggs2 2g1h 4gh. +gh2a 3ghale gh2e 3g2het 3g2hie gh1l 3gh2r +ghs4 +gh3sc g2hu gh1w gi3alo +gich2 +gicht1 gie3g gi2e1i -gi2el -gien2e1 +gi2e3l +giel2a +gie5n2e +gi4eno +gie3res gie1st gift5s gi2gu -gi2m +gi2kel +2g1ill +gi2me. gi4mes -2g1ind +gi2met +2gimp +2gin2d gi3ne -g1inf -gin2ga +2g1inf +2gin4h 2g1ins +gin2sa +2g3int +2gin2v +gi2ob 2giok 2g3isel -gi3t2a +git2a +gitt4e gi3tu gi4us 2g1j -4g3k2 +4g5k4 +gl2 4gl. -gl2a 4g1lab -g1lac -g2lade +2g1lac +2gladu 2g1lag +2g1lam 2gland +gla2s1c +glas3t4 3g2laub -4g1lauf +2g1lauf +2gländ 2gläuf +gl3b g2l4e -2gle. -3gle3a +2g3le. +3glea 2g3leb g3lec -g3leg +4g3led +g3lee +2g3leg 2gleh -3gleic +g4leic 4g3lein +gleiter8s glei4t5r g3len +4glenk 4g3ler +glerei4 2gles +3gles. g3lese -g4lia +g2lia 2glib 3g2lid -g2lie +3g2lie +4g3lieb 2glif g2lik -2glil +4glil g2lim -4glin +2glin g2lio 2glis -g3lisc -3g2lit +g2lit +g3lite g2liz -3g2loa -3g2lob -4g3loch -glo3g -3g4lok +g3lize +g2loa +g2lob +g2loc +2g3loch +g2lok g2lom -3g2lop -g2lor -3g2lot +g2lop +2glorb +2glos +g2lot +2glöch 2glös +2glöw 2gls g1lu 2g3luf -2glun -4glus +2gluk +2g3lun g2lut -g1lüg -g2ly +3g2lü +g3lüg +2glw +3g2ly 2g1m2 +gmen4tr +gmi2s g1n 2gn. g2n2a g4na. -4gnah -3g4nat +2gnac +g4nad +2g5nah +gn4al +gna4l3er3 +2gnanl 3g2nä +2gnb +2gnc +2gnd gn2e g3neh -2gnel +2gn3ent gne2tr -2gneu +gneu1 +2gnf 2gng +2gnh g2nie g2nif g4nin -2gni2s1 +2gnint +2gni4s3 +gnise2 +2gnk +2gnl +2gnm g2no +3g4non gno1r g3not 2gnp +2gnr 2gns 2gnt 2gnu 3g2num. g2nü +2gnv +2gnw g2ny 2gnz go4a goa3li +g1ob +gobe3l +2gobj +g2ob2l +gob2s 2g1o2f 2gog -2g1oh +2g1oh2 +goh3ren go1i gol2a -2gonis -2g1ope -2g1opf -g2o1ra +gol2da +gol2fr +3gon. +go4nat +gon2e +3gons +3g2opa +gopf4 +go2pos +2gopt +gor2a 2g1ord -2gorg -go2s1 -go3st -go3th +2g1org +go2si +go2s3p +go1ste +2g1osz +go3t2h +got6terb got6t5erg +gotte4s +3gou go1y -2g1p2 +gö2f +g1öl +3göt +2g3p4 2g1q g2r4 +g4rab +gra2ba gra2bi -gra2bl +gra4bl 2g3radl 2g3rah -4g3rak +2g3rak +gram1 grammen6 gram8m7end +gram6mer +g3rand. +2gra2r +grar1e +gra4s3a +gra4sh +gra4sp +gra2st +2g3raub grau3f +2graum +grau3sk +2gräd gräs1c -2g3räu +g3räu 2g5re. g4reb 2g3rec -2g3rede +g3rede g4re2e +2g3ref +gre2fr +2grege 2g3reic -2greim -2g3rein +grei4fr +2g3reih +g3rein g3reit -g4rem -2g3renn +3g4rem +3gren +4g3renn gre3no gren6z5ei +grenz3w g4rer +2grese +gres6ser6 g3ret g3rev 2g3ric gri2e +2g3riem g3riese -3grif 2grig -2g3ring +gril4la +4g3ring +4g3rinn +gro2b3a +gro3ber gro2bl +gro2b3r 2groc 2groh -gron4 +2g3rol 2g3rose +g4ross gros6sel -gro4u +g4rot 2gröh -g4ruf -2g3rui +2gruf. +g4ruft +2g3ruh +g3rui 2g3rum grun2g -3g4rup -2grut +3grup +3grus +3gruß +2g3rut 2g3rüc -3g4rün 4g2s1 +gs3a2b +g4sac +g5sack gsa2d -g4s3a2k +gs3a2k g3sal -gs3all +g4s3alb +g4sall +g4salm g4salt -gs3ama -gs3an -gs3ar +gs2am +g4s3ama +gs3amb +g4s3amp +gs3a4p +gs3a2r +g3sat +gsau2g +gsau4r +gsa2v +g3säu g3s2c g4sca g4s3ce gsch4 g4schef +gs4chi g4sco -g4s3cr gse2 -gse3e -gs2eh -g3s2eil +gs2e3h +gs4eil +gse4kl g3sel. +g4sela g3seln +gs3em gsen1 -gs3er -gser5f -gs5erk +g4s3ent +g4s3er +g3sere +gser1i +g4se4s gse4t -g4seta +g4seu +gsfi2l +gsgene4 +gs3ha gsi2d +gs3i2k g3sil -g4s3l +gs3io +g4s3ita +gs2ki1e +gs3kr gso2 -gsp4 +g4s3o4b +g3sol +gs4on +g4s3op +g5s4orge +gs4pant +g4s3pas +g3spei g3s2pek -g3spi -gs4pie -g4spin +g3s2pi +g5s6pie g4s3pl -g3s2por -g4spru +g5s6port. +g4s3pru gsrat4 gsrü2c -gs5s4 +gs3s4 gs3ta +g3s4tad +g4stag g3s4tan -g3s4tar -g3s4tati -g4s3tä -g5stäm -g3stel -gst3ent +g4stanz +g3star +gs4tati +gs3tä +g3steh +g3s4tein +g3st2el +gs4tell +gste2r gst3err g1steu -gst2he +gs2thy +g3stif +g3stil +g3stim g3stir g3sto -g4stol -gs3top -g4s3tor -g3stö +g4stoch +g4stod +g4stor +gs3tö +gs4tör gs3tr gst4ra -g3s4tras +gs4tras gs4trat gst5reit -gst4ri -gs4t5rit -gs4t3ros -g3stu -g4stur +gst4res +g4streu +gst3rit +gst3ros +g3stun gs3tü -g4sw +gs3un g3sy 2g1t g3te -g3ti +gtei3s +gt1h +gt2hy +gt2i gti2m +g3to gt4r -gt2s +gt4s g3tü -1gu +gu4ale +gu3am gu1an. gu1ant gu1as @@ -4924,400 +7891,660 @@ gu2e guet4 2g1u2f 2g1uh -gu1ins +gu3ins gu1is +gum2e 3gumm +gummi1 +gun2e 2g1unf -g2ung. gunge2 4gungew -2g1ungl +2gungl +2g1u2ni 2g3unk -g2un4s -2gunt2 -2g1url +2gunr +gun2s +2gunt +3gur +gure4 +4g1url +gur2t3h +gur2tr gurt3s -gu2s3a +guru1 +gu2s +gu4s3a +gu3sc guschi5 -gus4ser +gu3se +guss1o gus2sp gus2st gu4st +gust3a4b +gus3te +gus6t5en6d +gus6terl +gus4tr gu2t gut1a -gu4t3erh -gut3h +gut3er4h +gut1h +gut2s3p 2güb -gür1 -güs3 +3gür3 +gü2s3 2g1v 2g1w +gy3n +gy4na 2g3z2 -3haa +gzeu4gi +2ha. hab2a hab2e +h3abf +hab2i +h1ablu 2habn -hab2st +h1a2br +h1abs +2habw +ha4ch3en ha2cho +hacks4 +2hada ha2del -ha4din +hade2n h1adle +h1a2dr +ha3dri +2hae +ha3el +ha4far +haf2e +h1affä haf3f4l +h2aft +haf4to +haf2tr +haf4tre haft4s3p +hag2a +h2agg h1ah +ha3ha h2ahs h2ai -ha3ia +3hai. h2aj 2haka ha1kl 2h2al. +ha3l2al halan4c +h1a2lar ha2lau hal2ba -hal4bei -hal4b3r +hal4bel +hal4bin +hal2b3r +hal2bu 2hale -hal2la -hal6lerf -h1alp -hal2st -hal4t5r -h1amt +2halh +hal2i +hal2l1a +hal6lere +haller6f +hal6lerg +ha3lo +4halp +hal4sk +hal2sp +hal4tal +hal4tei +hal2t3r +hamot4 +2h1amt h2an. +2hana +ha2nal +ha2nan +han2au 2hanb +h2anbe h2and han2da +han4d3er +han2d3r hand3s -han2kr -h4ann +ha2nem +han2f1 +han6g5end +han4gro +han2k1 +2hanl +2hano 2hanr -2hant -h1ap +h1ansc +2hanz +2h1ap +3h2ape ha2pl +ha2po ha2pr h2a3ra +ha4rab 2harb +2harc h2ard +har2fr h1arm. har3ma +h2arme har4me. -har4mes +har4ne +ha2rom +2hars +hart4e har2th h1arti +har4tr +har2za h2as +2has. 2ha3sa -hasi1 +has4c +has2h3 +has4sa +hasser4 +has4s3t +ha2str +h1a2ß +ha2ta +hat2i +h3atl +ha2t3r +2hats hat5t2 +h3attr +h1audi +h1aufb hau5f6lie +hau3f4lo 2h1aufm +h1aufs +h3au3g2 h1aukt hau2sa hau4san -hau2sc +hau2s1c +h2ause +hau4sel +hau6s5ent hau4spa -hau5stei -hau6terk -2hauto -hau2tr +hau4spe +haussen6 +hau4sur +hau2t1a +hau4t3r +ha2ve. +häde2 h1äff -h1ärz +2häi +hä2kl +2härz hä6s5chen +2h1äst +2häug häu2s1c hä3usp -2h3b2 -hba2r3a +2h3b4 +hba4ras +hber2e 2h1c -2h3d4 +2h3d2 hdan2 2hea he2ad he3be -he4b1ei -he2bl +heb3eis +he2b3l he3br -he1ch +he3bu he3ch2e -h3echt +he3chi +he1cho +h3echs he3cke hed2g -he3di -he2e3l -hee4s +he2dit +he1e4m +hee2n +hee2s +he1e2t +h2ef. he2fan -he2fä +he2fau he2f1ei +he3f2em hef3erm 2heff he2fid -he4f3ing -he2f3l -he2fr -he3fri +he4f3in4g +he2f5le +2hefr +hef4ra +he2fre +3heft he2fu he3gu +he2hel +hei4a h4eib h1eie h1eif h1eig he2im +hei4mal +hei4man +hei4mar +hei4mei heim3p hei4mu 2hein +hei4na heine2 -4heio -he1ism +hei4n3eb +hei6nene +hei4n3er +h3eintr +2heio +2he1ism he1ist +h2eit heit4s3 h1eiw -he2l3a +hekt3a +he2la +he3lag +hel1an +hel3au hel1ec -h3e2lek -he3len -hel3ers +he2lek +h3elem +he2len +h2elf he3li +hell2a hel4l3au hel4mei he3lo he4lof +hel2or he2lö -3hemd -he3mi -3hemm -4h3emp +4helt +h4em. +2hema +hem2b +1hemd +2heme2 +h2e3m2i +he4mia +h3e4miss +1hemm +2h3emp h2en. -he4na2 -hen3a4g +he4n3a2 he2nä -hend2s -he2n1e2b +hen3ebe +henen1 hen3end +he4nene +he4nens hen3erg -he2net -heng2 -2heni -he2no -hen3sk +he4nerm +he2n1e4t +2henga +hen4gag +hen4kan +hen4kau +2heno +heno3t +hen4sem henst2 hen3str +hent2a +hen3te +hen4ter hen5tr +hen4tri h1ents 2h3entw -hen3z -4he2o +h3entz +he4n3u +hen3z2 +2he2o he3on he3op he3pa he3ph +h1e2pi +hept2 h2er. her3a2b -he2ral +he2rad 2herap -he3ras -herb1r -her4b3ra +he4r3a2r +herau2 +herb2 +he2r1e2b he4reck -4hereig -he4r3eis +her4eif +4he3reig +he6reis. +her7eises he2rel +he4rene +he6rersc he4rerw -h1er2fo -h3erfü -herg2 -her2ho -4herif +h1erfo +her4fol +6hergebn +2herif +herin4d herin4f he6rin6nu herin4s -herin8ter h1erke -h3erlau +her4klä +h5er6kran +h6erlad 2herm he3ro -he4r3o4b -h1erö -hert2 +he4r3o2b +he4rof +he4rop +he4rot +h1erör +hert4 her3th +her3um +her4zap +her6zeng +h3erzeu her2z1w -he1sta -he2s5tr +he3s4a +2hese +he3si +he3s2p +hes6tä he2tap +he3tä heter2 he3th het2i he3t4s -h2e2u +he2u heu3g +he3unt 3heusc he3x -he1x4a -he1y2 +he1x2a +2hexp +hey2 +he1ye 1hè 2h3f4 -hfell1 -hfel6ler +hfaller6 +hfan2 +hfel2l3 hfi2s -2h3g2 -hget4 +hflei2 +2h3g4 +hga2s1 2h1h2 hhoh2 4hi. 2hia -hi2ac -hi2ang -h2ias +hi2ar +h1iat +2hic hi1ce -hich6ter -2hi3d -h2ide -h1i4di +hich6t5er +hicht6sp +hi3d +hid4e +hi4dio +2hido hi2e hi3ens -hier1i +hie4rei +hier3i hie4rin hiers2 hif3f4r -hi2kr +hi2k3r hi2l3a4 +hile3n2 hil2fr +h2im +2hima +h3i4mit +h4imm +h3impe hi2n -h1indu +hi3nak +hi3nam +hi3nap +hi5n2as +h2inde +hine2i hi3nel -hin2en +hin2en5 h1inf h1inh -hi3n2i +2hi3n2i hin3n2 -hi3no +hi3n2o hin3s2 -hin4t1a +hin2t1a 2hio +hi3ob hi4on -hi3or -2hip1 -hip3f -hi2ph -hi2pi -h2i2r +hi2p3 +hi4pl +hips2 +hi4pu +hi2r hi3ra 2hi3re hi3ri +hir2m1a +hir2mi hirn1 hir4ner -hi3ro hir2s +1hirt +2his. his2a -hi2se -hi2st +hi4se +h1i2so +hi3tac +hi2tan +hi2tel hi1th -hi3ti -2hiu +hi3t2i +hit1r +hi2tro +hit3z2e +hi2v1o 2h1j 2h1k4 +hkamp2 +h2keu +hki2n1 +h3kö 2hl +h4laf hl2ag -hla2n +hla2gr +hlan4d3a +hl1ans hl1anz h1las h1lat h1laut +h1lay h3läche -h3läd -hl1är h1läs h1läu hlb4 hl3d4 +h3le. +hle3a h3leb +h3led hle3e -h3lein h2leis +h3leist +hl1el h5len. -hl2eng +hle4nas +hlenen3 hl2enn +h4l3entr +h4lents +hl2enz h3ler -hle2ra -h2l1erg +hle2r3a +hl4ere +h2lerg +hler4hö +hl2erk h6l3er4nä hle3run hl1erw h4lerz h3les h4lesi -h3lex +h4leud +hlf4 hlg4 h2lie +h3lied h2lif h2lim hl1ind +hling4s3 h2lip h2lis -h3list -h2lit +h2lit1 +hl3l2 +hl3m2 h2lo +hl1ob h3loc -hl1of -hl1op +hl1o2f +h3log h4lor -hlo2re +hlo2ra +h3los. h3losi +h4loss +hlos4st h2lös -hl3sku -hl3slo -hlst4 -hl3str +hl4sar +hl2ser +hl3ska +hl3s2lo +hl5s6tern +hls3tie +hl5str +hl2su hl3t2 h3luf h3luk h3lumpe h1lüf +hlz2 2h1m -h2mab +hm2a +hm3abl h3mad h3mag +h3mak h3man +h2mant h3mar +h4m3arc h3mä h4mäc h4mäh h4mäl +hm2e h3me. -hme1e -hme1in +h3med +hme1e4 +hmeer4s +h3mein +h3meld +hme3le h3men hmen2s -hme2ra +hme4ran +hme4rei +hme1s2t +h3mex +hmi2e +h3mind +h3mini +h3minz +h3mirr h2mo -h4mon -h3mö -hm3p4 +h3mop +h3mot +h3m2ö +h4möl +hm3p2 hm2s hm3sa hms1p h2mu h3mul +hmut4s 2hn h2na hna2c +h3nag h3nam -hn1an +h4nar +hn3a2te +h4natt h3nau. h2nä hn1äh -hn1är +h3näs hn3d4 hn2e hne3b -hne2e +hne2e3 +hn3eff hn3eig hn3ein h2nel -hne4n1 +hne4n +hn4eng hne4pf h3ner +hner4de hner3ei -h4nersa +h4n3e2ro +h4n3ersa hn3ex +hn3f4 +hnflei4 hnhof8stras h2nic h2nid @@ -5325,104 +8552,149 @@ h2nie hn1im hn1in h2nip -hn3k4 -h2nor -hn3s2k +hni4sa +hnk4 +hnno2 +h2no2r +hnra2 +hn3sa +hn3s2p +hnst2 +hns4to hnsuch4 -hn3ti hnts2 -h1nu -h2nuc h2nul -hn1unf -h3nunge -ho2bl +h2n1unf +hn3z2 +ho4ar +ho3bern +ho2b3l ho2ch3 +ho4cha +hoche2 ho2cka ho6ckerl hock3t 2hod -hoe2 -ho2ef -ho2fa -hof3fa +2ho2e +hoe3n +ho3er +ho2f1a2 +ho2fä +ho2fed +ho2feu +hof3f4a +ho2f3l +ho2f1o ho2f3r +ho2fu 2hoi -hol1au -3hole +ho2l1a2 +hol3ar +1hole ho2l1ei +ho2lem hol3g4 -ho4lor -3hol3s -h1o2ly -3holz +hol3k +holl4 +hol3s +2holy +h3olym +1holz hol6zene hom2e +ho2me. ho2mec ho2med h2on -hond4 -hono3 -2hoo +hon2er +ho1on +hoo2r 2hop ho1ra -hor3d +h1o2r2an +ho2rau +h1or3d +2hore +ho4rens +ho3ret 2h1org -ho4sei +hor3ta +hor4ter +h1ortu +h2os. +hose2 +ho2sei ho3sl +ho4sla ho2sp -ho4st +ho3spr +ho4ßene 2hot. ho3th -hotli4 -2hots2 -3hov +2hotr +2hot3s2 +1hou +hou4s 2ho2w1 -h1o2x +h1ox ho1y2 1h2ö +2hö. hö2c hö3ck -3höhe -h4ör -hö2s1 +5höhe +2hö2s1 h3öst -2h3p2 +2h3p4 h1q 2hr hra2b -hr1ac +hr3a2c hr3ad +hr1a2g +h1r4ah h1rai h1rane +hr3ap h3räu +hrb4 hr1c hr3d h2rec -h3rech +h3r2ech h3red h3ref +hr3eff +h2r1eh h4rei. hrei4ba +hrei4br h3reic -h4r1eig -h3rel -h3ren +h3reif +h4r3eig +hr4eini +h4reinl +hrei3th +hreli1 h3rep -hr4erbe -hr4erbu -hr2erg +hrer6geb +hr2erh hr2erk -h4rer4la -h3rerle +h4rerla h6rer6leb -hr6erlei hr2erm +hrer3s +hrer4sa +hr2erw hr2erz -h3re2s1 +h3re2s3 +hress2 +hrest2 hre2t h2r1eta -h3rev +h2r1eu +h2rev hrg2 h2ri h3ric @@ -5430,43 +8702,49 @@ h4rick hri4e h3riesl h3rin -h4rinh -hr1ins +h4r1ind +hr1int h4rist +h5ritter hr3l -hrm2 -h2rob -h2rof +hr3m2 +h3rog h3roh -h3rol +h1ro2l +h4romat h4rome h4romi +h4romo h4ron -h2ror +h1ropa +hro4r h3rou +h3rö2s hrr4 -hr2s1ac -hr4s3an -hr2s3au +hr4s1ac +hr4s3and hr3schl -hr2s1en -hr2ser -hr4set -hr4s1in +hr2s1em +hr2sen +hr2s1er +hr2set +hr4sh +hr2sin hrs3k +hrs3l hr4s1of +hrst2 hr2su -hr4sw -hr2t5ab +hr2tab hr2tan +hr2te2l hr2th -hr2tor -hrt3ri -hr2tro -hrt2sa -hrt2se +hr2top +hrt3ric +hrt2s h3ruh hr1ums +h3rut h3rü h4rüb h4ry @@ -5474,401 +8752,665 @@ hrz2 4hs h4s3acht h2s1a2d +h2s1alk +h2sall h4samt h2san -h2sau -h2s1äh +hs3and +h2s1as +h2sath +h2sato +h2saud +h4s3aur +h2saut +h2säh +h2säug h4schan -h2s1ec -hse4ler +hs2cr +h2s3ec +hse4e +h4s1ehr +h2s1eie +h4seind +h6seinst +h3sele +hse4lin +hs1emi +h4sendw +hsen5erg +h2s1ent +h2s1erf +hs1erg +h2serh +h4serkl h2s1erl -h3s2ex +hs1ern +h4sernä +hs4erne +h2serö +h2s1erw +h2serz +h2sex +h3s2ext +hsha2k +h2s1i2d +hs2im h2s1ing -h2s1o2f +h3s4inni +h4s3ita +hs2kal +h3skand +hs1of +h2sop +hs1org h2spac +h4s3pani h2s1par -h2spel -h2sper +h2s1pat +h3spec +h3spei +h3sperb h2sph -hs2por +h3spoi h2sprä h2spro -hss2 -h1sta +hss4 +h1st2a +hs3tabl +h3stad h2staf hst3alt -hst2an +h3stan +hst3arb h2s3tau +h2s3täu h1stec -h3stein -h5stell +h1stei +h1stel +h4stele h3s4terb -hst2he +h3s4tern h1s2ti +h2stit h1sto +h2stol h2stor -h1s4tr -hst3ran +h1str +h4s3treu +hstro2 +hs3tum h1stun h1stü h2s1u hs2ung 4h1t ht1a -h2tak -h3t4akt. -ht2al +h2tab +hta2bl +h2ta2d +ht2ag +ht4akt. +ht4akte +h2tall h4talo -ht3alt -h4t3a2m -h2ta4n +h2talp +h2talt +h4ta2m +h2ta2n ht3ane -h3tank -h3tann -h2tar -ht2as -h2t3ass +ht2ank +h2tap +h2ta2r +ht2a2s +h2t3asi h2tasy -h2t3a2t +h2t3at +h3tat. +h3tate h2tau -ht3aug +h3taum h4tax -h2t1är +ht1ä +h2tär +ht3e4ber ht1e2c -h2t1ef -ht1eh -hte2he +hte3cha +h2t1e2d +ht1eff +ht1e2he h2teif -h4teilz +h2t1eig +h4t3eilz h2t1eim ht1ein h2t1eis h2t1eke +h4t3elas +hte6l5ei. +h4telek +h4t3elfe h4t3elit +hte4m +h2t1emi h2temp +h4tenga +h4t3engl +h4t3enta h4tentf -h4t3ents +h4tents hter6de. +hterer6s +ht3erfo ht3erfü +h6terfül +h6tergeb ht3ergr -h2t1er2h -ht5erken -h4terkl +hter6gri +ht1erh +hter6häl +hter8höhu +h6terleb h6t5erleu h6terneu -h4t3er4re -h6t5er6spa -h4t3er4st -ht6erste -h2t1erz -hte2s -h4t1ese +ht5erspa +hter8spar +ht3erst +h6tersta +hter6tra +ht3erwä +ht3erze +h4t1e2se h4t1ess -hte3sta +h2teta +hte4th h2t1eu -h2t1ex -h2th +h4textr +h2t1h h4thei -hthe3u +h3thera +h3thes +h4tho +h2t1i2d h2t1im -h2t1in -hto2 -h2toly -h2torg -h3töp -h4t3rak +h2t1i6n3 +ht3ine +h2t1is +hti5t2 +htni2 +h2t1ob +hto4d1 +h2t1o2f +h4t3oly +h2tope +h4tord +ht3rak +h3tran ht3rand -h2t3ras -h2t3rat +h4t3ras +ht6rates ht3rau h4traub ht6raume -h5trec -h4tref -ht3reif -ht3reit -ht4ri -h4t5rieg -h4t5rin +ht3rec +h5treck +ht3rei +h2t3res +ht3ric +h4t3rieg +h4t3rin h2t3rol h2t3ros -ht3rös -h2t3ru +ht3röm +ht3ru h2t3rü h4ts -ht4s3an +ht2sah +ht2sal +ht4s3a4n +ht2scr +ht4sein +ht2sel ht4s3end -ht2so +ht4seng +htse2r1 +ht4s3eri +htsha2 +ht3s4hak +hts3kr +ht2s1o ht2sp -ht4spin -ht3spri -ht4stab -hts2ti +hts3par +hts3tät hts4tie +hts5trau ht4s3tur ht4s3tür +ht2su htt4 htti2 +h3tub +htu2e h2t1urs h3tü ht3z2 hu2b1a -hu2b3ei -hu2b1en +hu2b1ei +hu4bel +hu2b1en2 +hu2bi hu2b3l -hu4b3r +hu4b5r hu2bu hu1c -hu2h1a +hu2fa +hu2h3a hu2h1i +h1uhr +h1uhu +hu2kä +hu2k1in huko1 huk3t4 -hu2l3a +hu2l3a2 +hu4lab hu2lä -hu2l3ei -hu4leng +hule2 +hu2l1eb +hu2l1ei +hu2lem +hu4l3eng hu4lent -hu2ler +hu2l1er hu2let +hu2lid hu2l1in +hul3l2 hu2lo +hu2lö +hul3s2 hu3m2a +h1umh h1ums hu2n h1una +hun3d2e +hunde3i +hunde3s +hun2e +2hunf +hung2 +hun3ge hung4s -hu3ni1 +hungsa4 +h1uni +h1unm +2hunt h1ups -2h2ur -hurg2 +2hur +hur3g2 +hur2t3h hu3sa hu2so -hus4sa +hus2s3a +hus3se +hus4ser4 +hus2s1o hus2sp +hus2st hu2tab -hu3t2h hu2ti +hu2t1o +hu2t3r hut2t +hut3te hut4zen hut4z3er +hut2zu h2ü +h3über h4übs h3übu +hüf2 +hüft1 hühne4 hüs3 2h1v -hvi2 -hvil4 -2hw +hvil2 +2hw2 h2wall hwe1c h1weib h1weih -3hyg -3hyp +hweins3 +hwein6sa +h2wirr +1hyd4 +hy3dr +hy2lor +1hymn +h1yo +hy3os +1hyp hy2pe. 2hy2t 2h1z hz2a -hz2o +h3z2o hzug4 -i1a -2ia. -i4aa -i2ab -iab4l -2iac -i2af +h3z2w +i3ad. +iad2a +i1adn +ia3do iaf4l -i4a3g2 -i2ah -i3ai -i2aj -i2ak +i2ago +ia1h2 +i1ai i3ak. -i3akt -2ial -i5al. -ia2l1a4 +i3ake +ia2kei +ia2kr +i1akt +i1al +ia2l1a2 +ial3ar +ial3as ia2lä -ial3b -ial3d +ial3b4 +ial3d4 +i3aleb +i3alef i3alei +ia3lek +i3alel +i3aleng i3alent -i3a4lerf +i3alerb +i3aler4f i3alerh -ia4l3erm -i3a2let -i3a4lia -ialk2 -i3all -ial3la -ia2lor -ial3t4 -ia2lu +i3a4lerm +i3a2l1et +i3alex +i3a2lia +i3alim +i3a2lin +i3al3l +ial4ler +iall2i +i2alo +ia2lon +ia2lop +ia2l1o2r +ial3p +ial3t2 +ia2l3u4 ial3z2 -i2am -i4amo -2ian +i3am. +ia3ma +iampe4 +i1ams +i1an. +i1an2a ia2nal +ian3alt +ia2nau +i1anc i3and2 -ian2e -i3ann -i2ano +i3a2n1e2b +ian2er +i1ann +i1ans +ian2s1p i3ant i3anz -i2ap +ianza4 +ia1o +ia2op +ia3p ia1q +i1ar i3ar. ia2ra -i2asc +i2are +iar3r +i1as +i3as. ia3sh i2asi -i2a3sp +ia3s2p ias3s iast4 i3at. -i3a4ta -i4ate -i3at4h +i3at2h +i4athe 1iatr i3ats i3au ia3un -2iav +i2az 2iä -i1äm +i1ä2m i1äp iär2 i1är. +iär3m i1ärs -i1ät. -i1äta -i1ät3s4 -2i1b +iär3z +i1ät +i3ä4tem +iä2ti +iä4tr +iät5s4 +i1äv +4i1b ib1art i2b1auf +i2b1aus +i2baut ib2bli -ib1ei -i2beig -i2beis -ibela2 -ibe4n -iben3a -ibi2k -i3bla -i4blad -i3blä -i3ble -i4bleu -ib2o +i2b1eig +i2b1eis +ibe4n1 +i6ber6geb +i4b3er4la +ibe1ro +i2bim +i2b1in +i2blad +i2bleu +i3blu +i3b2o i2bö -i4brä -ib3ren +i2b3rau +ib3ric +i2b3roc ib2ser ib4ste -i2bunk -i2bunt -ibu2s1 +ib2un +i2b3unk +i2b3unt +ibus1c 2ic +i3ca ic1c ice1 -ich1a +ich1a2 +ich6art. ich1ä i1che ich1ei +ich2er +icherin5 i1chi -i2chin -ich3l -i3chlo -ich3m +ich1l +ich3le +ich3li +i3ch6lo +ich5m +ich3n i1cho +ich3ort i2ch3r -ich3ter +ich6sele +ich2s1i +ich4spe +ich6stie ich2tr i1chu ich1w i1ci i3cke +ickt2 i1cl +ic3la +ic3ra +i3cu i1d -id2ab4 +2ida +id2ab i3d2ac -i3dam +id4al +id1a2n +i3d2ans +i3d4at id1au -1i2dee -idein3 -i4deis -idel2ä +id2ax +idä1 +id2e +2i3de. +i2dea +1idee +id3eis +2idel +idel4ä +i4demul +4i3den. +ide4n1o +iden4se +ide3ran +iderin8nu +ide1rö +ider6reg +2i3des +ide5sa ide3so -1i2dio +ides2p +1i2di2o +idi4on +i4diot +2idk idni3 +id2o i2dol -1idol. -2i2dr -i3d2sc +2idoo +i2dö +i2d3r +id4rä +id4rit +id4ro +id4ru id2s1p -id3str idt4 1i2dy -ie3a4 +ie3a2 ie2bä ie2bl -ie2bre +ieb3re ie2bri +ie4b3rü ieb4sto -ieb4str ie1c ie2cho +iech3t ie2ck +ie2d3an +ie3de ie2dr ie1e2 -ie2f1ak +ief3akt ie2f1an +ie2far ie2fau +ie2fäh +iefe2m ief3f4 ief2i ie2f3l +ie4fonk +ief1r ie2fro -ie4g5l +ie2gl +ieg5li ie3g4n -ie2g3r -ie3g4ra -ieg4s3c +ie2g3re +ieg4s5c +ieg4se +ieg4si ieg4st +ie3her +ie2h1in +ieh3r2 i1ei +ie1ind i2e2l1a -ie3las -iel3d +iela2r +ie2läs +iel3d4 i2ele +ie4l1e2b iel1ec -ie3lerd +iel3eid +ie2lek +i4elen +ie4lene +ie4leng +ieler4e +ieler6fi ieler8geb -ie4less +ieler6ke +ieler6la +ieler8lebn +iel4erw +ieles2 i2eli -i1ell -ielo4b +ieli2d +i1ell2 +ie2lo2b +ie2lop +ie6lor i2els2 iel3sz -iel3ta -2i1en +ielt2 +iem2e +iemis2 +i1en i3en. i3ena -iena2b -ie4n3a4g -i3e2nä -i3en3d +ien1ag +ien4am +ie4nas +i3enä +i3end i2ene ien1eb -ie3ner -ien4erf -ie4n3erg +i3enec +i3e2n1e4k +iener6fo +ien3er4g +iener6la +i3enex i3enf -i3eng +i3eng4 ienge4f +ienge4z i3enh +ie2nid +ie2nim +ie4n3in i3enj i3enk +i3enla +i3enle i3enm i3enn i3e2no @@ -5876,1846 +9418,2965 @@ i3enö i3enp i3enr ien2s -ien3sc -ien3s2e +i3ens. +i3ensa +i3en3sc +i3en3s2e ien3si -iens2k +ien3s2k +i3en3s2p iens6t5er -iens4tr ienst5rä -ien3sz -ie1nu +i3en3sz +ien4t3ar +i3enth +ien3tr +i3enty +ie3nu +ie4num i3env i3enw i3enz -ie1o2 -ier3a2 +ie1o4 +ier3a +ie2ra2d ie2rap +ierb4 +i3erbun +ier3d i2ere -ie3red +ie4reck +iere5ins +ie4r3eis ie3r2er -ie4rerf +ierer3k ie4r3erz -ie3res -i3ereu ierf4 +ierg4 +i1ergi i4eri -ierin3 -ier3k2 +ierk2 i1ern i3ern. -i4erna -i2er5ni +iern2a +i2erni ie2rö -ier4seh +ier4re. +ier4s3eh +ier3sei iers2t ier3sta ier3ste ier3te +iert2i +ier3z2 +2ies +ie2san +i2esc +i2ese iesen3s4 +ie3s4pa +ies2pe ie2spu -ies2sp -ies2s3t -ie1sta +ies6ser6g +ies6serl +ies2st iest6e +ie4stin +ie1str ie3su -ie2t1a +ie4t1ag +ie2t1ak +ie2tan +ie2t1ap +ie2tat +ie2tau +ie4tent ie4t3erh ie4t3ert -ie2t3ho -ie2t1o -ie4t1ö4 -ie2tri +i4ethe +iet3her +ie2t1ho +ie2thy +ie4tob +ie2t1ö4s +ie2t3ri ie2t3ru iet2se i1ett +iet3zw ieu2e ie1un ie2w3u -i1ex +i1e2x 2if +if3ange if1ar i2f3arm if4at -if1au +i2f1au +if1än i2fec -ife2i -if2en +i2f1ef +ife4i +if1ein +if2e4n +i2f1erg if1erh -if2fl -iff4st +if2far +if2f3l +if2fro +iff2s +iff4ste if3l -i1f4la +if1lac if4lä +iflo4 +if4los i1flü if3r -if4ra -i1frau i1fre -if4rei -if4rü +i2freg +if4rev if2s if3sa if3se if3sp -if2ta -ift3erk -if2top +if3sta +if2t3a +if2ted +if2t3ef +if4t1ei +if2te2l +if2tep +if4terk +ifte2s +if4t3esc +if4th +if2t1op +if2t1r if4t3ri ift3sp ifts2t ift3sz +if2tur +i1fy 2i1g -iga3i -i2g1ang +i2ganb +i2garb ig1art -iga1s4 +iga1s +i2g3att +igd2 +i6gebrau i4gefar +ige4füg +3i2gel. +ige5lau +i2geln +ige4me +ige4mis ige4na +ige6nene +ige4nid +ige2o +ige2pa ige2ra -ige3ran +ig5erwer ig1erz -i2g1im +iger4ze +ige4sel +i2g1ess +ige4tra +ige4tre +ige4woh +i2gim i2gl -ig1lä -i4glo +ig1lau +i3glä +i3gle +ig3lim ig4na i4gnä i3g4neu -i3g4no -i3go -ig4ra -ig3rei -ig3s2a +ig4no +igo1p +ig3rad +i2g3re +ig4ren +i2grou +ig3s2ag ig4sal -igsau4g ig3sä -ig4se -ig3so +ig4schr +ig3s2o ig3sp ig4spa ig3stei +ig4sti ig4s3to -ig4stö ig3str -igs4tra -ig4stre +ig6stras ig3s4tü igung4 2i1h -i2h1am i2har i3he ihe1e +ih1elt ihe4n +ihe3u ih3m ih3n -ih3r +ih3r2 ihs2 -i2h1um +ih1um. ih1w ii2 ii3a4 i1ie -i3i4g +i3ig i1im -i1in +i3in i1i4s i2is. ii3t +i1it. i1j +1i2js 2i1k -ik1ak -ika4ka -ik1amt -i2k1ano +ika2ge +ik1aka +ikaken3 +i2k1akt +ik3amt +i2k1ang +i6kantei ikanten8n -ik1anz -i4kanze ik1art ik3att i2k1au -i2k1är +i3kaz +ik1äh +i2kär 4ike +i2keb +ik1ebe +ike2c +i2k1ed +i2k1ef i2k1ei -ik2e2l1 +ike4l1 +ike2n1 +ik1en2s +ik1ent +ike2ra i2k1e4r2e -ik1erf -iker6fah +i2k1er2f +i5kerfam i2k1er2h i2ker2l +i2kero +i2ke3ru i2k1eta +4iki i3ki. +ik1i2d +i3kie ik1in -i2kind +i2kins +iki1s i2k3l -i3kla -i3k4lä -i2kn -ik3no -ik2o3p4 +ik4län +i3k4leri +i3k4let +ik4lim +i3klu +i2kne +ik3nu +iko3be +i2k1off +iko1p2 +ik1or +iko2ri iko1s i2köl -ik3ra ik3rä ik3re +i2kres +ik4ris +i3kro +i2krö iks2 -ik3so +ik3sa +ik3ste ik3sz -ikt2e ikt3erk -ikt3r -ik2tre +ik4t3esk +ik2t3re +ikt2u +i2k1uh +i2kup i3kus +i2kü i1la -i2l3ab -il1a2d +i2lab +i2l1ac i2l1ak -i2l3a2m +il1a2ma +il1ang +i2l1anm +i2lano il1ans +ilan6zer +i2larb il1asp -il1au -il4aufb -il3aus -i2laut +i2l1au +i3laub +i3l4aufb i1lä1 -6ilb +i2lär +2ilb +ilb4l il2c +il5chen il2da -il4dac +il2dä +ild3ebe il4d3en4t -il3d2er +il3der +ild4erp +ilde2s +ildi2 ild1o il2dor il2dr +4ile il1e2c il1ein il1el +i2lemb +i2l1e2mi +il1ent +i4lentl i4lents -i2l1erf -i2l1erg -i2l1err -il2erz +i2l1erd +iler4ei +i6lereig +il1erf +iler4fo +i2ler2g +i2l1er2h +i4ler4kl +il1err +i4lerri +i3l2erz +ile4th +il1ex +ilf2 +ilfe3s il2f3l il2f3re ilf4s3 -ilg2a il2gl -ili3e4n1 -ilig1a2 -ili4gab +2ilh +2ili +ili3e4n3 +iliga2 +ili4g3ab +ilik4 i2l1ind +i4l3init +il1ins i2l1ip -i3lip. -i3lips -2ill. -il3l2a +ili1pf +il3la +ill2an +il4lenn il3l2er -ill2i -2ills +1illu il2mak -il4mang -il2m3at +il2m1ap il2m1au +ilm1ei il2min +il2mor 2ilo -i2l1or +il1ob +il2oh +il2op +i2l1o2r +i3lou +i3lov +il1ox +ils3ent +ils4to ilt2 il3th -il3tr -i1lu2 +i1lu i2lum ilung4 +i2l1ur i3lus -ilv4 +ilü4 +2ilv4 il2zar +il2zau ilz3erk -2im. -i2manw +il2zwa +imad2 +ima1i +im2al +i2m3anh +im1ans +i2marc +im3aren i2m1arm +i2m1art +im2as im4at ima2tr imat5sc ima4tur -2ime +im1aus +i2maut +im3b +1imbi +i2meg +im1ein i2mej +i2mek i2mele i2melf -i3men -i2m1erf -i2m1erz -i4mesh +im2en +i2m1er2f +i2m1er2l +i2m1er2z +i4me3sh imes3s i2meti -i2m1inf +i2mew +imhau2 +i2mid +im1i2de +i2mim +i2m1ind +i2minf i2m1ins +im2mä im2mei -im4m3ent +immen1 +imm3ent +im6menth 1immo +im2mor 2imo -im1org +i2m1ob +i2mo2p +imo3re +i2mö +1imp imp2fa -1impo -imp4s +im3pf2o +imp2s im3pse -1impu -im2st -im3sta +im4set +im3sph 2imt +imt2e +im3t2i imt3s2 -2imu +imtu2 +4imu +im2um +im1urk +2in. +ina2be +in3abu in1a2c -in3ach. i4nack -i2n1ad -in2af -in3am -i3nap -in2ars -in2art -ina4s -i2n3au -in1äh +in1ad +i3nald +inaler4 +ina6lere +in2alp +i2n1am +in2an +in3an. +in3ana +in3ann +i2narb +in3att +i2n3au2 +2inä +i2n1äh +in2är in1äs +2ind. +inda2 +ind2ac in2dal in2dan -in3dau +2indä +2inde. +2inden +ind5erke +inder3t +inde3sp 1index -in3do +ind2i +1indik +in3dö 2indr -ind4ri -in3drü +ind3se 1indus in3d2ü 2ine -i2n1e2be -in1ehe -i2n1eng -in3erbe -i4nerbi -in2erh +in1e2c +i3nee +i2neff +in4elen +ine2n1 +ine3nä +i4nen4zy +i5ner. +i4n3erbi +in4erha +i4ner4he +i3nerk +i3n3erle +i6ner6leb iner4lö i4n3er4tr +i3nes i4nesk +in2et in1eu ine3un -ine2x -in3f -1info. -1infos +in3f4 +1infek +1infiz +1info 2inga -ing1af -in2g1a4g -in2gl -ing4sam -ings3pr +in2g1af +in2g1ag +in2g1al +in2gam +ing1ar +2ingä +3ingeni +in3g2er +in4g3er4w +inges4 +2in2gl +in3gla +in3glä +ing4s3am +ings6por 1inhab 2inhar 2inhau -4inhe -in2i3d -i3nie +2inhe +2ini. +in2id +ini3de +2inie 2inig -ini3kr -in2ir +inig2a +ini3k4r 2inis ini3se +init2 i3nitz 3inkarn +1inkas +inkels6t +in4k3ent +ink4er +in2kro in3k2ü inma4le 2inn. -in4n3erm +inne4n +in4ner4m 2innl in2nor -inn4sta 1innta 2ino in1od +ino3e4 in3ols in1or -ino1s4 -ino3t +ino1s +i3no3t +i2n1ou i1nö in1ö2d -2inp 2inr +2ins. ins2am +in6samt. insch2 +2inse. in2seb +2insed 2insen -ins3ert -in3skan -in3skr +2insk +in3sof +3instal in4s3tät -in3stel -ins4tip -in3su +4inst2e +in3s4tip +3instit +ins4to +4instra +in4strü 1insuf -in4s3um -in3s2z +ins3umz +in2sur +in3sz 2inta +2inte. 1integ -int2h -in3t4r +in3tei +2intep +2int2h +inthi1 +int2o +2intö +2in3t4r +4inträ in5tri +3intrig int3s -in1u -i3n2um +i2n1u +i4nuh in3unz -invil4 -i1ny +4inverm +invil2 +i1ny2 +in3z2e +inzel8ler +in3z2i +in3z2sc +inz2u +in3zw i1ñ 2i1o +iob2l io1c io2d -i2oda -io3e2 +io3da +io3e4 +i2of iof4l -i2o3h -io2i3d -io3k4 +i2oh +io1i +io3k6r i3ol. +i3ols i3om. +io3me i3oms ion2 i3on. -ional3a +ion3an io2n3au -ion3d +ion3d2 +io4nee +i3ono +io2nor i3ons3 -ion4spi -ion4stä -ion3t +ion4sa +ion4sen i2ony +i2oo i2o1p -io4pf -i3ops +i3o4pf i3opt i2or i3or. i3orc +ior2e iore4n +io1r2h i3orp i3ors i3ort -io3s2 -i2ost +4ios +i3os. +io3sh +ios2p +i2o1st +ios2u +i2o3sz +io3t i3ot. +iote3l +iot4r i3ots i2ou i2ov -io2x +i3ox +i2oz i3oz. i1ö2k i1ön i1ös. -2ip. +i1öst i1pa +ip2an i1pe -ipen3 +i3ped i3per +2ipf2 +i3pfan +ipfe2 iph2 2i1pi +ipi3a ipi3el ipi3en -i3p4l -ip2pf -ip2pl +ip4lu +ip2pan +ip3pe +ipp1f +ip4pl ip3pu i1pr -2ips +ip2sa +ip2sei +ip2sp +ips3t +ip4sta +ip4stü +ipt2a +ipt2i +ipt2u 2ipu 2i1q -i1r2a -i3rad -1i2rak -irat2 +i1r4a +i3ra. +2i3rad +i3ras +irat4 i1rä ir1äh -ir2bl +ir2b3l ir1c -ir2e +ir2ch1o +ir4e i3ree 2irek -2iré -ir2gl -irg4s +ire4na +i3ré +irg4 ir2he ir2i -2irig +2i5rig 2irk +irke4n +ir4kene ir2k3l +irk4s3c +ir3k2u irli4n +ir2m1ag ir2mak -ir2mau +irm1au ir2mä ir2m1ei +irme4n1 +ir2m1o2 +irm4th ir2mum -ir4m3unt +ir4munt 2irn -ir2nar +ir2n3a +ir4nat ir2no -i1ro -1iron -iro2s +i3ro i1rö -irpla4 +irpla2 irre4l -irr2h +ir2rh +ir3sche ir4schl ir4schm +ir4sch3r ir4sch3w -ir3se -ir3sh +ir3se3 +ir3s2h ir2st irt2s3t 2iru +ir1u2m iru2s1 -i3sac +i3r2ü +i2sac +isa2m3 +i4samp i4s1amt is2ap +isa2r is3are +i3sat +is3att i2sau +is3auf +isau2g +i2säh i2s1än 2isb i2sca +i4schar i3s2che i4schef i4sch3e4h -i4sch3ei +isch3ei +ische4m +i6schemi +i6scher6z i4schin i5sching -i2sch1l -isch3le +i2sch3l i2schm isch3ma -isch3ob -isch3re +i4schna +i4sch3re isch3ru +i3schu +i4schüb +i4schwa +i6schwir i4schwo isch3wu -i2s3cr +i4schwü +i2scr 2ise -ise3e -ise3ha +ise3a +ise1e +iseh2a ise3hi -ise3inf -i4seint +is4eind +is4eli +i6sel6ter ise2n1 -ise4n3a +ise4na is2end +i4senho isen3s +ise4r3ei +is1erg i2serh +iser4he i2s1erm -iser2u -i2s1ess +i2s1es4s +i3s2et i4s3etat -is2has +i3s2eu +2isf +4ish +2isi isi2a -i2s1id -i2s1of -iso2n +i2s1i2d +isi4de +isik2 +i2sim +isin3g4 +isi1s +i4ski +i4sku +is3la +3islam +2isma +2ismi +ismu2 +is1of +i3soh +1i2sol +2is4o2n1 isonen4 iso6nend -is1op -3i2sot +isono2 +i2sop +is1ort +3isot +i2s1ou +2isp is1pa i2spar +is2pat is1pe is1pic -is2pit is2por i2spro is3sa is4s1ac is4sau -is4s3che -is4sper +is6s5chen +isser4f +iss2po is2st is3sta is3sto iss3tr +is3strä is3stu is2sum -is3t is4tab -ist3ac -is5taf -is4tam +ist3a2c ist2an -i1s4tat +is3tang +i1stat +is3täu +ist4e +i1stel iste4n istes3 -i1s4teu -i1s4til +i1steu +i1stil +istin4f +is3t6o is4toc -is4tö -is5tör +is3tör +is3tr ist4ra -ist3re -i1s4tü +is4tro +is4tru +i1stü +i3suf +isu2m isum3p i2sü +2isy i1ß -iß1ers +ißer2s +iß3ersc it1ab. +it1abs ital1a it1alt -it1a2m -it1an -it2an. -it3a4re +it1am +ita3ne +it3anr +it1app +it1a2re it1art i3tat it1au i3tauc -i4t1ax +i2taut 4itä +it1änd i2t1äs ität2 +it1eff i2t1ei -i4teig -it2eil -i4tein +it2eic 2itel -ite2la -ite4n +ite4l1a +i4telek +i2t1emi +i2temp +ite2n iten3s2 -i4tepo -i2tex +i4tents +i2tepo +i6tereig +i4t3er4fo +iterin6d +iter6klä +it2erö +i8t7ersche +i4t1esk +i2t1ex +i3text i5thr +i2thy +i5tic i2t1id +i5tig 1itii -iti4kan -iti3k2e -i2t1in1 -it2inn -ition4 -i6tl +it1in1 +i3tis +i4tiso +iti3sp +iti2v5a +it5le itmen2 +4ito +it1ob i5toc +ito3d i2t1of -i3tö +ito2p +it2os +4itr +i2t3rad +i3tradi it3raf -it3ran it3ras it3rau it3räu it3re +i4tren +it4ret +it3rob it3rom -it4ron -i3tru -it3run +i2t3run +it3rut +2its it2sa -its1a4g -it2s1e4 -its3er1 -it2so -it2s1pe -it2s3to +its1ag +it2s1e +it4se2h +it4s3e2r1 +it4sh +its1or +it6stras +it2sur +2itt +it2tan it2teb +itt3hä +it2tob +it2top it4tri +itt3ric +itt6schi +itt4se4h +itt4sei +itt4sor itt2sp +itt4sti it1uh -i2t1um +it1ums +it2ung i2tuns +ituran4 it1urg itut4 i3tü -2itz -it2zä -it4z3er4g +4ity1 +ityl2 +it2ze2c +itz2er +itz3erg +it6zergr +it4z3erl +it2zö it2z1w 2i3u2 -ium1 -i1ü +i4u3l +iu4m3 +iuma2 +ium4se +ium4ste +iun2 +i4up +iu4r +ius3t +i1ü4 2i1v +i2v1ad i2v1ak -iv1ang +i2v1am +iv1an +i2v1ä i2veb +i2v1ef +iv1ei iv1elt ive4n iv1ene i2v1ent +i2v1ep +ive3re +iv1erh +iver4kl iv1erl +iver3s +ive3s +i2v1ex +i2v1im +i2v1ind +iv1int +i3vol +ivo3re +i2v1r +i2vun i2v1ur +i2vü 2i1w -iwur2 2i1x i2xa ix2em i3xi ixt2 +i1y 4i1z -iz1ap -iz1au +iz1a +iz2ac +i2zag +i2zan +i2zap +i3z2as +i2zau +i2zä +i3ze iz2ei izei3c +izeits4 +i2zele ize2n -i2z1ene -iz4er -i2z1ir -izo2b +i4zener +i4zentz +i4z1erl +izid3 +iz1ir +izo2f i2zö +i2zuna i2z1w +i3z2wi í1l +j2a +jab4 ja1c -jah4rei -jahr4s -ja3l2a +jah4r3ei +jahr2s +ja3l +jal2a ja3ne jani1 jani3t4 +ja5ru +jas2o ja1st -2jat +jat2 +2j1d4 +jda3 je2a jean2s -je1c je2g +jek4ta jek4ter +jek4tin +jekt3o2 jektor4 -jek2tr +jek6t3r je3na je2p -je4s3t +je3r +jer2e +jes3t je2t1a -je2t3h +je4t3h +je2tin +je4tor je2t3r jet3s2 jet3t je2t1u2 -je3w -ji2a -jit3 +je3v +je3wo ji2v +2j1m joa3 jo2b1 job3r +jo2da jo2i -joni1 -jo1ra -jord2 +jol2a +jong2 +jo2p3 +jo1r2a +jor3d2 +jo1s4 jo2sc -jou4l +jost2 +3jou +jou2l +2j1t +jty1 j2u -ju2bl -jugen2 +ju2b3l +jugen6 jugend3 +ju1i ju2k +jul2i jung3s4 ju3ni +ju3r +jur4a jur2o -jus3 -jute1 +jus3t +ju3t2e1 2j1v 1ka 3ka. -k1a2a ka3ar +2k1abb kab2bl -ka2ben +2kabd +2k1a2ben +2kabf +2kabg 2kabh -2kabla -2kablä -2k1a2bo -ka3b4r -2kabs +2kabn +2k3a2bo +2k1abs 2k1abt +2kabw +2kabz ka1c -k2ad -2k3ada +kade2r +2k1adm 2k3a2dr +3kadu +2kadv ka1f4l ka1fr kaf3t2 -k2ag +kag2 +kaga3 +2k1age +3kah +ka1ho ka1in -ka3ka -kaken4 -ka1k4l -2kakt +kaken2 +ka1kl +2k1akt. 2kala. +kala3b +ka2l1a2d ka2lan -ka3lei -ka3len. +kal3d +ka4l1eh ka4lens kal3eri -kal2ka +3k2alk +kal2k1a +kal4kan kal2k3l -kal2kr -k1all -kalo5 -kal2tr +kall2i +2k1allt +ka2lop +ka2l1os +kal4tex +kal4th ka2lu -k3ama -kamp8ferf -kan2al -ka4n1a4s +k2amt +kan4al +ka4n1a2s ka2nau -kand4 +2kanb +kan3d2 2kanda +2kandä kan2e -2k1ang +2kanf +2kanim kank4 2kanl -2k1anna -k1ans +2kanom +2k1anor +2k1ans k2ans. -6kantenn -ka3nu3 +kan4tar +6k5antenn +2k1anth +ka3nu +kan2um 2kanw -k2anz. -ka2o -2k1apf +2k1anzu +2kanzü +ka2o1 +3kape +ka3po 3kara -2karb +2karbe +2karc k2ard +kar3d2a +k1area k2arg -ka3ri +ka3r2i kari3es k2ark 2k1arm -karp3 kar2pf k2ars -kar3t -k2arta -2k1arti +k2ar3ta +k1arti +4kartik karu2 k2arw -3kas -ka3se +3k2asc +kas2e +kase1i kasi1 -kas3s +kas2o +ka4sp ka2s3t -ka3tan -ka3t4h +2k1ast. +ka4ste +kas6tras +3kasu +ka3sz +ka2tan +3kateg +k3atel +ka3t2h ka4t3r -2katt +2katt4 +kau4fer kau2f1o -4kaufr +kauf6s5ag kauf4sp -kaufs5te -k1aus +kaufs7tem +kauf6sti +k2aus. +2k1auss +kau2st +2kausw kau3t2 2kauto +ka3ve +2kaz 1kä -k1äh -k1ä2mi -k1än +käl3 +k1ämi +2k1änd kär2 +2k1ärg kä2s1c käse3 -2k3b2 +4k3b4 kbo4n kbu2s kby4 2k3c -2k3d2 -kdamp2 +2k3d4 +ke2ben 2k1e1c -k1eff -kefi4 +ke2di +2k1eff +kefi2 kege2 ke2gl ke2he. +ke2hen +kehrer4 kehr2s kehr4s3o 2k1eic 2k1eig -k1ein -ke1in2d -2keinh -kei1s -2k1eise +kei2li +ke2im +2k1ein +kein4du +kein4e +k1ei1s +2keise keit2 +keits1 ke2l1a ke3l2ag +ke4l3am ke2lä -kel3b4 +kelb4 +keld4 +kel3eis 2ke2lek -ke2len +ke2l1en ke2l1er -2kelet -kell4e -kel3s2k +kel7l4e +kell2i +ke2l1o2 +ke2lö +kel3sk +kel7s8tern k4elt +kelt4e +2k1e2mi 2k1emp k2en. -ken3a -ke4nac +ken1a +ken3au ke2nä kend4 ken3dr +ke2n1e2b +kenen1 +ke4nene +ke4nens +kener4n +kene4t 4ken4gag -2kenlä +k5en6gel. +ke2nim +ken3in +4kenlad +4kenläd +kenn2a +kenn2e ke2no -ken4sem -kens2k -ken5stei +k2ensa +4ken4sem +ken3si +ken3s2k +ken5s6tei ken3sz k3en4te. -k3en4ten +ken6ten. +2kentf +2kentg ken3th +2kentl 2k1ents 2kentw 2kentz -2keo2 +ke3ny +k2en3z2 +2ke1o2 +2kep ke2pl k2er. -ke1rad +ke1ra +ke2ran +ke2rau +ke2r1ä +ker4ble k2erc +2kerd +ke2r1e2b +ke2rec ke3reig +ker3ein 4kerfah k4erfam +ker2fo k3ergeb -ker6gebn -k3er2hö +2kergu ke6rin6nu kerin6st kerin4t -ker4ken +k3erken k2erko -k2erl -k4erl. -ker4lau +k3erlau k3er4leb k6erlebe -k4erlö -ker4neu +ker2na +ker4nei +4k3er4neu +kern5eur k1ero +k2e1rod +2keros ker4reg k2ers. +2kersa +kert2 +ker6werb kerz2 k1erz. ker4zeu 2k1er2zi -k6es. +k2es. +ke2sa +k2esc +k1ese ke2sel +kes2sa ke4t1a -ke2t3h -ket3s -ke1up +ket2ag +kete4 +ke4t1eb +ke4tel +2k1e2th +ket3ha +ke2tu keu6schl +2k1e2va 2k1e2x -2k3f4 -2k1g2 +4k3f4 +2k3g2 +kga2s1 +kge3s 2k1h4 +k3he kho3m -ki3a4 +k3hu +ki1a +ki2ad +ki2ag +ki3ak +ki3a2r ki1c -2k1i2de -ki3dr +ki3d4r +k2ids +2kidy ki2el -kie2l3o +kie4lei +kiel3o +2kiern +kier2s +kier4st +kie4z ki1f4l ki1f4r ki3k4 -2kil2a -ki3lo -k2imi -k2in. +2ki3l2a +2kilä +2kim +3kin. +ki2nä +4kindex +2k1indi +2k1indu +2k1inf k2ing +kin2ga +king3s 2kinh -k2ini +k2ini3 +kinik2 k2inn ki3n4o3 +kinos2 kin3s 2k1inse +k1inst 2k1int ki3or kio4s 3kir +2k1i2so kis2p kis3s kist2 kis4to kiv2 +kive4 2kiz -ki3zi 2k3j 2k1k4 +kkab4 kl4 4kl. 4kla. -4kland +2k1lac +klan2 +2kland +klan3du k4lar -4k1last +k1last +k1lauf k3laug +2kläd +k2lär k2le -4kle. +4k3le. kle2br -k3lee -4kleh -k4leid -4k3leit +k3leg +2kleh +klei2e +k3leit k3lem. +kle2o 2k3ler kle2ra 2k3leu kle3us 2klic +k2lien +k2lif 2klig -k2lim +3k2lim k2lin +k3lin. +3k4lina +k4link k2lip k2lir k2lisc 2klist klit2s -4kliz +2k3liz 2k3loc -klo2i3 +2klok +3k4lop k3lor -2klos. klost6 -k2löt +2klöc +2klöf +k2löst +k4löt k1lu +klu4b k2lud -kluf2 k2lug +k2lum klung4 -k1lüc +2klux +2k1lüc 2kly 2k1m +4kma +kma2la k2n2 -3knab +k4nac +2k5nach +2k3nad +2knah +2k3nam +2k3näp k3ne k4nec -k4nei +kne1e 2knes -kno4bl -2k5nor -k3nu -3knü +2knetz +2k5neu +4kney +2k3niv +kno2b3l +k4nol +2knorm +2knov +2k3num 1ko +ko5ad ko2al +kobal2 2kobj -2k1o2fe -koff4 +kob4s +kof3f2 +koffe3i +kohl2e +kohle3i koh3lu -ko1i2 -kol4a +koka3 +ko3l2a ko3le -kol2k5 +kol2k3 3kom +komer3 +4komn ko4mu k2on -ko3n2e +kone2 +ko2nem kon3s4 -ko3nu +kont6e +ko2nu +ko3on 2kop. ko1pe +2koper +kopfa2 kop4fen -2kops -2kopz -ko1r2a +kop6f5err +kop3s +ko3pte +ko3r2a +kor2ba +kor2bl +kor2br 2k1orc +korder4 kor6derg -ko3ri -kor4n1a +ko2rel +2k1org +kor2k1a +kor3m +kor4nac +kor2n3ä +kor4no2 +2korpi k2os +k4os. +ko4sk ko2sp -ko3ta -kots2 +3k4ost +ko2stü +ko4ter +ko3ti +kot4r +kot3s2 kot4tak -2k1ou +k1ou +ko3un 3kow ko2we -k1o2x +2k1ox 1kö -kö2f +köde2 +k2öf k1öl 2k1p2 2k3q -k2r4 +k2r2 2k3rad +2k3rah k4ral k3rats 2kraum +k4raw k4raz k4räc +2kräd k4rän -2k3rät 2k3räum -2kre. +2k5re. +2k3reak +2k3real +k4reb 2k3rec 2kred. 2k3rede +2kredn +2kredu 2k3ref 2kreg -k3reic +2k3reic kre1i2e4 kreier4 -k3reih +k3reif +2k3reih +2kreim +krei6sei +krei4st +kreli1 +k3ren +2kresu 2k3rh 2krib 2k3ric -k3ries +2k3ries 2krip -3kris -3k4ron +k3risi +krob4 +k4roch +4k3roh +k4rok +k4ron +k4rop +2krot +3kroth +k3rou +2kröh 2kruf -krü1b -2k1s +2k3run +4k1s +ks3a2b +ksa2k k4s1amt k2san -ks4ana -ks3ar +ks3a2r +ksa2s k2sau -k4s1äl -ks2än +ksau2f +k2sav +k2säh +k3s2c ksch4 -ks1e2b -k2sent -ks1erl -k2s1ers -k2s1erw +k2s1e2b +k2s1ec +k3s2ed +ks1ei +ks2eid +ks2eif +k4seind +kse2le +k2s1eng +k2s1ent +ks1er +ks2ere +k2serf +k2serg +k2serk +k2serl +k2sers +k2serw +k2s1e2v +k2sex ks3ha -k3shi -k2s1id +k4s1i2d +ks2im k2s1in -k2s1o2 +k2s1is +k3s2ke +ks3kl +ks1o +ks4on +k2sop +k2so2r +k2sö ks1pa -ks2pat +k2spal +k3s2pat +k2spä k3spe +ks2pel +ks2pen +k2sph ks2por -ks2pu -ks3s2 -kst4 +ks2pul +ks3s4 +kst2 k2stal k4s3tanz k3stat4 -k2stea -ks2ti +k3stäl +ks4tel +ks2tep +k4stier +k2stit +ks4tol k2stor -k2strä +k4strop +k2stuc k2stum +k2stur +k2stüt k2s1u +k3sul ks2zen 4k1t +kt1abr +kt1abs k2t1ad kt1akt k3tal kt1am kt1an -k2t3a2r +kt2and +k2t1a2r kta4re -k2t3au +kta3ri +k2t1au +kt3aug ktä3s -kte3e -kt1ei -k2temp +kt1ein +k2tek +k4t1ela +kte4n1 +kten3s2 k2tent +k4tentf +k4tents +kten3z +kte2ra +kte3ran +kt4ere k4t3erfo +kt1erg k2t1erh +k2terö kte3ru k2tex -k2th -kt3ho -k2t1id -kt1im -k2t1ing -kt1ins -ktion4 +k2t1h +k2t1i2d +kti2me +kt3ind +kt1ing +kt1ini +kt3inn +k2tint +kti2s1e +k2tiso kti4ter +kto3b k2t1of -k3top -k4torga -kt3orie -kt4ran +kto5ren. +k3t4ran kt3ras +k2t3rau k4tref -kt4ro ktro1s kt3run -kt3s2 -kts4t +kt3rü +kt3s4a +kt3sä +kt3se +kts2el +ktsen1 +kt3si +kts1o +kt2sor +kt3s2z ktt2 +k3tub +kt1ums k2tuns k3tü -kt3z +kt3z2 +ku2al ku1c -ku2h3 +kud4r +3kug +ku2h 2k1uhr -kul2a +ku3la ku3l2e ku3l2i 4kulp -2k3uml -kum2s1 +kul4to +kul2tr +k2um. +k2um4e +2kumg +2kuml +kum2sa +kum2sp k2u3n2a +kun3da +kund2e +kunden3 kung4 kun4s4 kunst3 2kunt 2kunw -2k1up. +4k1up. kur2bl ku2rei kuri2e kuri4er +2k1urk ku2ro +kurs1c kur2sp kur2st +2k1urt4 +kur3tsc +kus3a2r ku4schl ku2sp -kus3t +2ku2s3t2 ku2su +2kut. +kut2a +kuto3 1kü kü1c +3küne +3kür kür4s -2k1v +2k3v 2k1w +k3wa 2k3z2 kze3l 3la. +la3ar +l1ab 3l2ab. -la3ba +lab2a +la2bad +l2abä 2labb lab2br -4l3aben -2labf +2labd +lab2e +4la2ben +4labf 2labg 2labh -4l1a2bl -lab2o -l2abr -lab4ra -lab4ri +3labi +l3a2bit +2la2b3l +2labn +3lab2o +4labo. +la3b4ra +lab4res +la2bri 2labs -l1abt -3labu +la2bus 2labw +2labz la1ce la2ce. +l4a3che +lachter8f +lacks2 1lad -lad2i -l1adl +2l1ad2a +2ladd +3laden +la3d2i +2ladj +2l1adl 2ladm 2l1a2dr -3ladu -l1adv +3l2adu 2laf la2fa +la2f1ei +la2f1er +laf1r laf3s -laf3t -la2ga +laf3t4 +la2fu +la2g1a +lag3d +l2ager +lagerin5 +4lagg la2gio -la2gn -lago2 -la2g1ob -lag3s2e -2la1ho -1lai -la2kes -la2k1i +lag3l +la4g3n +lago4 +la2gob +lag3str +2la3ho +3lai +lake2 +la2kin l2akk la1k4l +la2kro +lak3t2 2l1al -4lalp -l2ami -la3min +la2la +3lala. +3lali +4lalt +lami3t +lam2m1a 1lammf +la2mor l2amp -4l1amt +2l1amt lamt4s la4mun -l1anal -la2nau -2lanb -5l2and -lan2d1a2 -lan4d3au +la2na +la3nan +la4n4at +la4nau +2la2nä +3l2and +l4and. +lan2da +lan4dam +land3au +l4ande +lan6derh lan6d5erw lan6d5erz -lan2dr -lan4ds -laner2 +lan6d5inn +l4an2dr +lan3dri +land3rü +lan3erd +laner4f 2lanf -lan2gl +lan4gan +lan6g5esc lang3s4 -2lanhä +2lanha l2anhe -2lanl -4lanli -2l3ann -l1anp +3lan2i +4lanl +2l1ann +l1ano +la2nof +2l1anp 2lans2 -4lansä +l1ansi 2lantr +2lantw +2lanw lan2z1w 3lao 2l1apf -l1a2po2 -lap4pl +la2ph +2l1a2po +lap2pl la2r1an +2larc +lar1e2b la2r1ei +la2rel la4rene -3l2ar3g +larf4 +lar3g lar3ini -l2armi -lar3s -2l1ar3t +4l1a2rom +l1art +2lart. +lart2h l3arti -la2ru -la2sau +lart4r +3laru +l2as. +la2sa +la4sam +la4sä +lasche4 4lasd -la3se -3lasg +la3seb +la2sei +la2s1e2l 2lash -2lasi +la2sin +la2sis la2so -2lasp +2la4sp 3lasser -last1o -lat2a +l2a2st +las4t3an +la4ste +last3ri +la4stu la3t2e -la4tel -2l3ath +2l3a4tel +la5t2i +2l3atl +2latm +lat2o +la2tö la2t3ra +lat4ri lat2s -2lat2t1a +lat3st +2lat2ta lat4tan +lat4tex lat4t3in lat2t3r +latzer4 1laub. +lauben6s5 +lau2b3r laub4se -lauf1i lau4fin +2laufn lau2fo +lau4fri 1laug -l2aus. +lau3gl +2laun. +la4us +3l2aus. +2l1ausb +lau6scha +2lausd +2l1ausf +2lausg 2lausl 2lausr 2l1auss +lau2st +2lausw +2lausz 2lauto +lau2tr +la3va +lave4n 1law lawa4 -lay1 +1l2ax +la4xel +l2ay +lay1s lä1c -1läd -2läf +3läd +4läf 2l1ähn 2lämt 1länd -lär2m1a -l1ärz +2l1äpf +2läq +lär2ma +l1ärme +2lärz lä2s1c -4lät +2lät 2läub 2läuc 2läue 1läuf +2läug +2läx 1là 2l1b l3bac -lbb2 -l2b1ede -lb3eise -l4beta +l2bant +lb3a2ri +lbau1c +lb1ärm +lbb4 +lbby4 +lb2ei +l4b3eink +l4b3eise +lbe4ral +lberin5 +lbe7s +l4b1e4ta l2b1id l2b1ins -lb2lat +lb4lad +l3b2lat l3blä lb3le -l2bli +l2bled +l2blic l3blo -l3brec -lb3rit +l3b2lö +l3b2lu +l2b1o2ra +lb3rea lb2s lb3sa lb3se -lb4sh lb3si -lb4sk lb3sp -lbs6t -lbst1e -lb4sto -lb2u -l2b3uf +lbs4t +lbst3ac +lbst3ei +lbst1u +l2b1uf +l3bum +lbu4n lbzei2 2l1c +l3ca l3che l4chei -l5chen +l4chent l3chi -lch3l -lch3m +lch3le +lch3li +l3chlo lch3n lch3r +lch3s2 lch3ü lch1w +l2ck l3cl +l3co 4l1d ld3a2b1 -l3d2ac +ld2ac ld3a2ck -l2d1a2d -lda4g +l2daf +lda2g +l2d1ah +lda2i l2d1ak -ld1al -l3dam -ld1amm -l2d1a2n -ld3ane -l2d1a2r -ld3ari -l3das -ld1au +l2d1al +l2d3a4n +ld1arm +ld1ass +l2d1au +ld3aus +l3däm ld1är +ld1äs +ld1ät l3de. -l2deh +lde4ben l2dei -l2dele +ldein7 +l2d1elf +l2d1e2mi +l2d1ems +lde4na +lden5erg +l4dentl l3der. +l4d3er4fa +l6der6geb +ld1erh +l4der4he l3d2erl +l6d5erlas l3d2ern l2d1er2p lder4tr -l2d1e2se +lde3sa +l2d1es2s l2dex l2d1id -l2d1im -l2dob +ld1i4mi +l2d3ion +ldo2b +ld2on +l2dop ldo2r +l2d1ori ld2os +ldos5t ld2ö2 ld3r +ld4ram l2dran -ld4ros -l3d4ru -ld4rü +l2dre +l3d4ris +ld4ru +l2drüc ld3sa +lds4an +ld3ska ld3st ldt4 ld3th +ldt5s +ld3tu +l2d1ul l2d1um +ldwes4 +ldy2 1le -3le. -le2a -le3an +le2ad le3ar +le2as +3leba leben4s3 le2bl +3lebr +le2b3re +lebs2 2lec -lech5t4e -3led -4ledd +lech1a +le2chi +lech7t6e +le2dr le2er -lef2a -le2g1as -le2gau +lee4ret +le3f2a +2l1eff +lef4o +le2g1ab +leg1as le2gä le2gl leg4r +legs4 3leh -leh3re +4lehe. +leh3r2e 4lehs 4leht -lei4bl -lei2br -l2eic +lei4ble l2eid -4l1eig -le2im -l2ein. +lei3ere +lei4fan +lei4fei +leifer6g +leif3s +2l1eig +lei3gl +3leih +lei4hau +lei3l2 +leim3p +3l2ein. l2eind lein4du -l2eine +l4eine lei6nerb -4leink -l2eint +le2inf +le2ini +2leink +4l3einsa +2leint l2einu -lei6schw +le2is +leisch5a +lei8schei +lei6scho +lei6sern +l1eisf leis6s5er l4eist +lei4str lei4ßer l2eit lei2ta -lei8t7er8sc +lei4to lei5tri leit3s2 -lekt2a +leits4t +3leko 2lektr +2lekz 3l2ela -2le2lek +le2le +le3lei +2lelek +4leleme +le3len +leler2 +leler4s +le3les +2lelf. +2l1elfe l2eli -lel3s +l2em. +le3mal +le2mau +le2m1ei 3lemes -le2m1o2 -4lemp +3lemet +lem1o2 +le2mor +2lemp lem3s -l1emu -l2en. -le4nad +le2mu +le4mun +l4en. +len1a +len3ab +le4na2d +le4n3an +le4n3a4t le2nä 4lendet -2lendu +l1endp 4lendun -le4n3end +le2n1ed 4lenerg -l1engl -le3ni -l2enk -2l1enni -le2no -len4sem +le4neur +4leneuv +len4gag +len4kau +len4k3lo +len4klu +l1enni +len6sein +4len4sem +len3ska len3sz -2lentf -l1ents -2l3entw +2lentg +2l1entk +4lentla +2lentn +4l3en4tro +4l3entw lent4wä 5lentwet -len2zi -le1os +2lentz +2lenzy +leo2f +le1o2s 2lep -3lepa 3lepf +4l1e2pi +4lepoc 3lepr l2er. l2e1ra -le2ra4g -le2rap +le2rag +le2r3ap +le2ra2s le2rau -lerb4 -l3erei4g -ler6eign +le2r1ä +le2r1e2b +ler2e3c +l3ereig le4r3ei4m +le4r3eis +le2rel +le4reng +le4rerg le4rers +le2re4t +4l3erfas 2l1erfo l2erfr l2erfü -l3ergeb +l1erg +l2erga +l4ergef 3lergeh -l3ergen +6lergen. +l4erger +l4erges 3l4ergew -2l1ergi +2lergi +l2ergl +l2ergr +4ler4heb +4lerhol lerin4s lerk2 l2erka +2lerke +l1erkl +4lerklä +l4erkle l2erko -l4erlei -le1ro -le2rob +ler3kr +ler3l +5l6erlebe +3l4erlei +2lermä +ler4nal +ler4nar +3l4erne +ler4nei 2l1erö 3l2erra +ler4ric l4ers. -lers2k +l1ersa lers2t +ler4sto +lert2 +ler4trä +le2rup l4erwa -2lerwo +ler4wer +2ler2wo 2l1erz -l2erza -ler2zi +ler2zä +l3erzeu +ler2zo +l4es. les2am les2e +lese1i 2l1esel -le3ser -le3sh +le3s4h lesi1 -le3sk -les2ko +le3s2k +les4ki +le3so le2spo -les2t -leste3 +lest6 +le1sta +les2te3 +lester6i le1sto +le1str +3lesu 4lesw 2lesy -le2tat -2le3th -let4tu +le2tab +2le2tap +2le2tat +l1e2th +le3tha +2lethi +let2i +letsche6 +let4top +lett1r +letts2 le2u -4leud +4leue +3le3u2f +2l1eul +le3unt 2leuro 3leut -2lexe +l1e2vol +2lex +3lexd +3lexik le2xis -2lexz +1lé 2l1f l3fah -lfang3 +lf4at l2f1ec lfe1e -l4feis +lf3einh +l2feis +lf2en +l4ferei +lfe4rel +lf1erl +l3fi l3f4lä -lf3lo +lf3led +lf4lö l3f4lu lf3ram -lf2s -lf4spe -lf2tr -lf4u +lf3res +lf4ru +lf4rü +lf2spe +lf2sti +lf2su lfun2 lfur1 -l3fü 2l1g -lg1art l3gas lga3t -lg1d4 lgen2a -lge3ra +lgene2 lgeräu3 l2geti +l3g2i lg2lö l3go +lg4p +l3gra lg3re l3gro +lgung4 2l3h2 +4lhe 3lhi. +4lhu 1li -3lia -li3ac +li1a +lia2b li2ad -li3ak -li3ar -lia1s -lib4 -libi3 +li4am. +lian2g +li2ast +3lib4 +libi1 li1c -li3chi +lich4ta +lich4to 4lick li2cka -lid2 -li3da -2l1ido -li4ds -lid3sc -l2ie +li2cl +li3d2a +l1ido +l2idy 3lie. -liebe4s +liebe4s3 +lie2br +li1efa +3liefer +li1efk +li3efl +lie4n1a2 li3ene lien3s -lie2s3c -lie2st +lien3t +lie4rei +lier4sp +lie2s1c 3lig +liga3s +li4g3ers +li4gl lig4n -li2gre -li3ke +li3ker +lik2o +likop4 lik2sp lik4ter +lik2ti +lik4t1o2 +lik2u li3l lil2a -li3m2a +li3m2a1 +limas4 +lima3t4 +2limm 3limo 2limp -li3n2a -lin3al +lin2a +li3nar +2lindi 2l1indu li2nef li2neh li2nep li2nes 2l1inf -lings5 2l1inh -2l1in1it +li5nie +lin1it 2l1inj -lin2k1a +lin4kan +lin4kar link2s li2nol -l2ins. l2insa -l2insc +4linsel 2linsp 2linst +2linsu +2linsz 2l1int -li1nu -l1inv +li3n2u +2l1inv 2linz li2o li4om -li3os. -li2p3a +li3o2st +3lipf 3lipt 3lis. li3s2a +li3schm li4schu +lis2h +li3shi +3lisk 2l1isl -2l1i4so +2l1i2so li2sp -liss2 -lit2a -li2tal -li3te -lit2h +liss4 +3list +lit4a +l1i2tal +li3t2ä +l2i3t2e +3liter +li4t3r lit1s2 +lit3se lit3sz li3tu +li6tun +li4tur +litz4er 3liu liv2e -livi1 +li2vea +li2ves +livi3e +li3vr 2lixi -li2za +li4z3ä lizei3 -4l1j +2l3j 2l1k +l3kale lk1alp l3k2an +l3kap l3kar. -lken3t +lk1erd +lke3r2e lk2l lk3lad +l3k4las lk3lic -l2k3lö l3k4lu -l3k2me +lk2men lk4ne lk5ner +lko2f +lk1ofe lkor2b1 -lk4ra -l2k3ru +lk3roc lk2s1 -lk3sä +lk3sän +lk3si +lk4spe lks3t -lk4stä +lkt2 lk2ü 4l1l -ll1abb -lla4ben +l2labk l2labt -ll1akt -l3l2al +l3labu +l3lage +lla3gl l2l1am -ll3a2ma -lla2n -ll2anw +lla2ma +l3lame +ll2ami +ll2anb +lla4ner +l4lani +l3lans. +ll4anwa ll1anz -l3l2ap +l4l3appl ll1arm -ll3aug +l4latm +ll3att +ll3aufg ll1aus -l4lausf ll1äm +l2lär llb4 llch4 ll3d4 +ll5ebene +l3lec ll1ech +lle3er l2l1ef +ll1eic ll1eim -ll2em +ll2eis +l4leise +lle2la +lle2m +l2l1emi l3len. -lle4n3a +lle4na llen3dr -ll3en4du -ll2eng +ll5en6dun +l4lentf l4lents +l3lep l3ler. lle2ra -l6lereig +ll2ere +l6ler6eig ller4fo ller6geb -l6lergen +l8lergene l4lergo -ll3ernt +ll3erho +l4l3ermi +l4l3ernt ll3ertr ll2es -l2lex -llf4 +lle4th +ll1exe llg4 -llik4 -ll1imb -ll1imp +lli4gan +l2limb l2l1ind +l4linf ll1ins -llk4 +ll3k4 ll3l2 -ll5m -lln2 +ll5m2 +ll3n2 ll1ob l2lobe -l2l1of +l2l1o2f +ll3ol +l2lope ll1opf -l2l1o2r -l3lor. -l3lore +ll1or +l6lorb +llor2g +l2lo2ri l2l1ou l3low -ll3sä -ll3sh -ll3s2k +ll1ox +ll2säu +ll2s1es +ll3ska ll2spr ll3t +llt2e +llt2i llti2m ll5t4r llts2 -llu2f ll1ur llus5t6 +l3ly ll3z2 2l1m -l3ma. l2m3a2b -l2marc +l2m1ad +lm1a2ge +lm1aka +l2m1a2m +l3mana +lm1apf lm1art +lm3att lm1äst +lmbu2 lm1c -lm2ei -lm3eins -lme4na +lmd2 +lm3e4dit +l2m1ef +l2ment l2m1e2p +lmer2 +l2m1erf +l2m1erl l2m1erz +l4messa +l2m1i2d lm1ind lm1ins -l2möl -lm3p +l2mof +lm1orc +lm3p2 lmpf4 +lm3s2k lms2t lm3ste lm3s2z -lm3t -4ln -lna4r +lm3t4 +l2mum +l4munt +2ln +ln2ab +lna2r ln3are lnd2 l3n2e -l3ni -l1nu +lnes2s +l2n1in +lnus2 l1nü +l1ny 1lo lo4ak -3l2ob. -lo2ber +3lob. +l2oba +3lobb +lobe2s 2lobj -2l1o2bl +l1o2bl l2obr lob4ri -l1o2fe -lo1fl -lof4r -lo2gau -lo3h2e -2l1ohr +lo4chel +l1ofe +lo2fen +lo4gh +lo2gl +lo2gor +lo2gre +lo3ha +loh2e +4l1ohr loi4r 3lok +4l3okk lo2k3r -lol2a -l1o2ly +5loks +l4ole +2l3o2ly +lomä3 lo2min +lo2ner +lo4nin lo2n1o lo2o 2lopf +lop2p1a 2lopt -lo1ra -lo2rak +lor3am +lor2an lo4rä 5lorb -2lorc -l1ord -lo3ren -2l1or3g2 -3lorq -3los. +2l1orc +2l1ord +lo3r2en +2l1org2 +lori4di +2lort2 +l2os. lo4sa 3lose lo4ske lo2spe -loss2e +lo2spr +los3t lo4ste -los3t4r +lo2st4r +4loß lo2ta lo3tha loti4o @@ -7726,246 +12387,407 @@ lo2ve lö2b3 2löck 2löd -l2ö2f +lö2f 2l3öfe -4lög -l1öhr -2l1ö4l3 +2l1öhr +2lök +2l1öl3 +2löp +3lösc +3lösu 4löß +4löz 2l1p -l3pa -lpe2n3 +lp2ar +lpar2k1 +l4p1är lp2f -l2p1ho -lp3t4 +lph4 +l3phä +l2phir +lp1ho +l3phr +lpt4 l3pu 2l1q 2l3r2 -lrat4s -lre1s -lrut4 -lrü1b +lrau2s +lrebs2 +lro2h +lrö2 4l1s -l3sac +ls3a2b l2s1a2d -l3s2al +ls2al l4s1amb -l4samt -l2sang -l2sann -l2sanz +l4samp +ls2amt +l2san +ls3ane l3sare -l2sau -ls2äm +ls3a2ri +l3sark +lsau2 +lsau4m +lsau4r +l3s2äm +ls2äug +ls1äus +ls2c l4schin l4schmü +lschs2 l2s1e2b -l2s1ec -l2s1em -ls1ere -ls1erg +ls2ele +ls1eli +l2sent +ls1er +l2serf +l2serg l2serh -ls1erl -l2s1ers -l2s1erw -l3s2ex -l4s3ha +l2serk +l2serl +l2sers +l2serw +lse2t +ls1eta +ls2ext +ls3ha l2s1id -l2s1imp -ls2log -ls3ohne +l2simp +ls2kal +l3s4kele +ls2ky +lso4b +l2sop l4s3ort. -ls2ö +l3s2öl l2spac -l3s2pi +ls2pe +l2s3ph +l2s1pir +l3s2pit ls2po +l3spri ls2pu l3spul -ls3s2 +ls3s4 lst2a lstab6 +ls3tabl ls4taf +lstahl3 +l2stas +l4stat. +l4state l4s3täti l2ste +l3stea l3stec +l3steh l3stei +l4steil l3stel -l4stem -ls6terne -ls6terns +l3stemp +l4sten +ls4t3erk +l5s6terne +l5s6terns ls2tie l2stit -ls4tr +l4stoch +ls4toi +ls4tol +ls4tru +l2s3trü ls2tu +ls4tüm +l3suf ls1um -l2sun +l2s1un +ls2und +ls3unk 4l1t l2tab +lt1abs ltag4 -lt1ak lt1am -l4t3ame -lt3and -lt1ang -l4tarm +l4tame +ltampe4 +l3tan. +ltan3d +l2t1ap +lt1ara +ltar8beitn +l3tark lt1art -l2t3ato -l2t1au +ltar6tik +l3tartu +lt1au +l4tauf +lt3aut +lt1äh +ltbau1 +lte2c lt1eh +l3tehu +lt1eig lt1ein -l2t1eis -l4te4lem +lte3mi lt2en lten6gel -lter3a -lter2f -lt2erg +lten4sp +lt3ents +lte4ral +lter4fa +l3t2erg +l4terhe lter6ken -lter6leb +lter4ku lter4nä +lte2ro lt2erö -l4t1e4sk -lte2th -l2t1eu -l2th +lter4se +l4t1es3k +lt2est +lte3str +lt2et +l2t1h +lt3hag l3thas -lt3ho -l3thu +l4t3hei +lthol2 +l3t2hu +lt1ide ltimo4 -l2tob -l2t1of -l2t1o2ri +l3tine +l2tiso +l3t2i3t +l2t1ob +l2t1o2f +l4tord +l4torg +l4t1o2ri lto2w -l3tö lt1öl lt1ös -lt1öt +l4t1öt ltra3l lt3räu -l2t3re -lt4rie -lt3roc -lt3ros +lt3rec +lt3rei +lt3ris +lt3rol l2t3rö +l2t3rus l4ts -lt2so -lt4stab -ltt2 +lt2se2l +lt4s3ort +lt2s1pe +lt3s2ph +lt2sti +lt3t +l3tub lt1uh l2t1um -ltu4ran +lturan4 +lturen4 ltu2ri l3tü lu1an -4lu4b3 +4lu2b3 luba2 lubs2 lu2dr +lu2ec lu2es -1luf +lu2et +1lu2f2 2l1ufe 2luff -luf2t1a -luf2t1e -luf2tr +lu3fo +luft1a +luft3e +luf4tei +luft3r lu2g1a lu2g1e2b +lu2gei +lugen1 lu2gi -lu4g3l +lug3l lu2go lu2g3r lug3sp lu2gu 2l1uh lu1id. -lume2 +lu4ig +lu1is. +lul2ö +2lumd +lume4 2lumf -2l1umj +2lumg +2l1umh 2lumk 2luml +l2ump +1lumpe +lum2ph +2lumr 2l1ums -l1umw +lu3mu +2l1umw +2lumz 1lu2n 2l1una +lund4 2l1unf lung4sc 2l1uni +2lunr +2l1uns 2lunt 2lunw 4luo -2lur +l2ura +lu2r1an +lu2rat +lu2rei +2lurg +l2uri +lu2ris l1urn +lu2ro +2lurs l1urt +lu4ru +lu3sak 2luse +lu3si lu2sp lus4s3a lus2s1c -lus6serf -lus6serk -lus6sers +lus4sel +lus4s3er4 lus2s1o -lus2s1p +lus4s1p lus2s3t lus4stä -1lu4st -lus4t1a +luss5tr +1lu2st +lus6terl +lus4t1o2 lust3re lu2s1u -lu2t1a +lu2t1a4 +lu4tas +lu4t3au lu2tä -lu4teg +lu2t1e4g +lu2tel luter2 lu4t3erg +luter4s +lu6t5ersa +lu2thy +2luto +lu2tob lu2t1o2f lu2top +lu4t1or lu4t3r lut5schl -3lux 2lüb +3lübd +lück4e2 +lücker3 5lüd +lüf3te +lü2hel lüh1l -2l1v -4l3w +2l1v2 +lva3 +l3vl +lv3r +4l3w4 2lx 1ly -ly1ar +ly1a2 ly3c +ly3es +ly1l 2lymp 3lyn ly3no ly1o +ly3t ly1u 2l1z -l2z3ac -l3z2an +l2z1ac +l2z1ag +l2zan l2z1ap -lz1ar -l2z1är -l3zen -lz2erk -lz1ind +l2zat +lz1aus +l2zäp +l2zär +lze2l +l2zele +l4z3enth +l2z1ep +l2z1er2h +l2zerz +l2z1id +lzi4m +lz1imi lz3l lzo2f l2zö lz3t2 l2z1u4fe +lzvol2 lz1w lz2wec +l2zwu 1ma +3ma. +maa2 m1ab +m3a2bar +m2abä +2m3abb m2abe +2m3abf +2mabg +2mabh 2mabk -3m2ab4r +m2abli +2mabm +ma2br +m2a3b4ra 2mabs +2mabt +2mabz ma3chan +mach2e +mach8terh +mach8t7ers mach4tr ma2ci -ma3da -m2ade -2madm -ma2d4r +mack2s +2m1act +mada2m +m2adä +ma2del +ma3dj +2m1adm +2m1a2d4r ma4d2s -ma1f +mae4 +ma1f4 +mag2a ma2ge. ma2geb ma2gef @@ -7979,449 +12801,725 @@ ma2gew 2m1agg magi5er. magi5ers +ma3gl ma3g4n 2m1ago -mai4se +ma3ha +mahl4st +ma1ho +mai4s3e +ma2ke. 2m1akt +mal2ag mal1ak ma4lakt ma2lan -ma4l3at ma2lau +ma2lär +2mal2de +m2aldi ma3le +ma4leb mal2er +ma4lex mali1e mal3lo 2mallt +ma2lon +ma2lop +m2alp +mal3t malu4 ma2l3ut +3malv +ma2mid mam3m -2m1anal +2m1a2nal +ma2nar +2m1a4n4at ma2nau +2m1anä 2manb -man4ce. -man3d2 -man3ers +man2ce +3man3d4 ma2net m2anf +mang2 +2man3ga +m4angel 2m1angr m2anh +3manip 2manl -m4ann -2mansa +m2anle +3m2ann +2manod +2m1ansa 2mansä -2mantw +man2t1h +2mantr manu3 +ma4n1ut +2manw 2manz +m1anza ma2or -2m1apf -m2app +ma2phr +ma2po +ma1q +m2ara +4marag +mar2an 2marb mar3g2 +3ma1rh ma3r2i -4ma3r2o +m2ark +mar2kr +4mar2o maro3d 4marr +mar6schl mar6schm mar6schr +mar2sp +mar2su +2m1arti ma3r2u m1arz 3mas -ma3s2pa -4m1aspe -massen3 +ma3s4a +mas2e +ma3s2p +masse4n3 +mas4ta mas4tel -ma1s4tr +mas2ti +mas4to +mas4tr +ma4s3z 3maß ma2ta2b ma2tan -mat4c -ma2tel +ma2tä +m3a2tel ma4t3erd -ma5tri +ma4t3erz +m4atme +2matmo +ma2to +ma4tort mat3se mat3sp +matt4r mat3url 2m1au2f 3maul ma3un -2mausg +mau3r +2maus +mau2ta m4ay ma1yo 1mä 2m1ähn -mä1i2 -2m1änd +mäh1r +4m1änd 2mäo -m1ärg -3mäß +2m1äp +2mäq +mär1 +mär2kl +mär2z1 mä3t4r mäu2s1c 2m1b2 mbe2e -mb6l -m3b4r +mber2e +mbe3ri +mbert4 +mbi3er. +mb4l +mble1i +mb4r +mbu3sc mby4t 2mc m3ch -2m1d -md1a -m2d1ä +4m1d +m2dan +m2d1a2s +md1är +mde2a m2dei -mds2e +mde2m +m2d1emi +m2d1ent +mder2 +m2d1erl +md2ö +md3ras +md3s2e +mdt4 m2d1um 1me +me3an +me3at meb4 me2ben -m2e1c -medi3 -medie4 -medien3 -2medy -me1ef -mee2n1 +3mebr +me1c +medi3e4 +me1e2m +mee2n mee4r3ei -mega1 +2m1eff +mega3 +me4gel 3meh +meh6l3er +mehrer4 2m1eif 2m1eig -mei3l2 +m2ei3l2 mein4da -me1i4so -3meist +meinde3 +meiner6k +mei6nerl +3m2einu +3m2eist me3lam -me2lau -3meld +me3l4ant +me2l1au +melb2 +mel3d2 +melde3i me2lek +2melem me2ler melet4 2melf. +3melk +mel4k3ei mell2 +3melo +me2lob mel2se mel5t4 6mel6tern -2m1e2mi +2m1e2mis 2m1emp +2m1e2mu m2en. -mena2b -me3nal +men3ab +me3nage +me4n3an men3ar +me4nas men3au -2mendl +2m1endl +menen1 +4men4gag men3ge -m4ens -men4sk +me2nim +men3k4 +men2on +men4se. +men4sem +6mensemb +men4sen +men4ser +men4ses +mensi4d men2so -men3ta -men6tanz +menst4 +m4enta +men4t3ak +m4entei +ment5eig +men6t5ers 2mentn ment4sp -4m3entwi me1o 2meou 2meö -3m2er. +2mepa +2m1e2pi +3m4er. me1ra -mera1f -me2r3ap +mera3l +mer2a3s4 +me2r1e2b me4rens -mer2er -4m3ergän +mer4err +mer4erw +4m3er4gän merin4d merin4t +4mer4klä +mern3s2 m4ersh -merz4en +mer5sm +mer6stel +mer4sto +mert4r +merz6eng 3mes -mes1a me2sal me4sä 4meser -2me3sh -4m1essa +mes2po +mes1pr +2mes4sa +mess3an mes6ser6g -mes2s1o -mes2s1p +mes4s1o +mes2sp mes2st -meste2 +mes3ta me1sto -4mesu -m2et -me3t2a +me3su +me3sze +me3ta +meta1s me3th +meto1 +me2tö +me4trig +met6t5en6d +me3tu meu1 2m1ex +me2xe 1mé 2m1f4 -mfi4l -2m1g2 -2m1h4 +mfi2le +4m1g2 +mgang4 +mglim2 +4m1h2 1mi -mi2ad -mi3ak +mi1a +mia2b +mi2am +2m1iat +mi1ä mibi1 -mi1c +mic1e +mi1ch +mi2ci mi3da +mi2di. +mi3dr +2midy mie3dr -mi2e1i -mie3l +mi3ele +mi4e3no mien3s -mi2er mierer4 -mi4et -mie4ti -3mig -mi2kar -mi2ki +mie1s +mie2ti +mie4to +mie2tr +mi1f4 +3mige +mi3h +mik1an +mi3ke +mi4kel +mi4kens +mi3k4l mi2ku +3mil mi3l2a -3milb -3milc milch1 mil4che mild4s -2m1imp +mi3l2i +mi3l2u +4milz +m2im2a +2m1imm +2mimp +min2ac +mi3nak +min5anze +m2inde minde4s -min2en +2m1indu +mi2nef +miner1 +mi4n3e4ri min2eu +2minfo min2ga -ming3s4 +ming3s +2minh mi3ni -min2o -mi1nu -3minz -mi2o +mini3k4 +mi3nod +mi2nof +2m1inse +m1inst +mi3nu mioni1 +mi1p 3mir. -mi3ra 3miri 3mirs 3mirw +3mirz +3mis. mi2sa mi4scha -mi4schn -mi4sch3w -mise1 -mi2ste +misch3w +mi3se1 +2m1i2so +mis2pa +mi2spe +mis5sar +mis4ser +mis4st +mis3te +mi1sto +mi1s4tr +3misu 3mit mi2ta -mi2th -mi2t1r +mi2t1h +mi2to +mi2tr mit3s2 mit5sa -mi5tsu +mit3ta +mit3t2e +mitte3s mi2t1u 4mitz +mi3v2 2m1j 4m1k4 -m3ka -mk5re. +m3kn 4m1l2 ml3c +m3le +ml3f +ml3k +m3lo +ml3p ml3s -2m1m -m2mab +4m1m +mma3a m2m1ak m2m1al -mm1ang m2m1ans mm1anz +m2m1ap mm1art -m2m1au +mma1st +mm1aus +mm1äu mmd2 +m2m1e2b +m2m1ef mm1ein +mme2l1a2 mme4lin -mme4na +mm2ene +mmen6te. +mmen6ten +m4mentl +m4ments m4mentw -mme2ra +mme2r3a mme4rec -mme2sa +mmer6geb +mme2s +mme3sc +mme4sz +m2m1eu +mmi3el mm1inb -mm1inf mm1inh -mm1ins +m2m1ins mm1int +mm2is mmi3sc +mmisch4 mmi1s4t -m2m1ö +mmi5tw +mm3m2 mm3p2 mmpf4 mm2s -mm3si -mm3sp +mm3sa +mm3s2i +mm3so +mm3s2p mm3sta -mm3str +mm3sti mm3te m2mum +mm2un +mmu3r mmül2 mmüll1 2m3n2 m4nesi 1mo -moa3 +2m1o2be +3mobi 2mobj 3m2od -mode3s +mo3de +mode1s mo2dr -4mog. -mo2gal -3moh -mo2i3 +m1of +mo2fe +3mog +2mog. +mo2g1al +3m2oh +moh2a +moi3r mo2k1l +mol3d 3mom mom2e 3m2on +mo2nan mo2nä -mo3ne -mo4n1er +mon4dac +mon4del +mon2do +mond3r +mo2ner mon2s3 -mon3su -3mo2o -2m1ope +mon3sa +mons4e +mon3s4u +mont2a +mon3th +mo1ny +3m2o2o +2mo1pe +mo2per +2m1opf 2mopt mo1ra -mo2rar -2m1orc -mor4d3a +mor2an +mor2d3a mor2dr -mo2rer +mo2rei +mor3g morgen5s6 +mor3t2 3mos -mo3s4ta +mo4ska +mos3s moster4 -3mot -mo3ti -m1o2x +mos2ti +mo3t2h +mo5to +mot4r +mous4 +2m1ox mo1y 1mö +möbe2 mö2c +2mö2f 4mök -m1öl +2m1öl 4m1p mpa3ne +mpe2la +mpe4lin +mpe2n +m2p1ene m2pf -mp4f3erg +mpf1ef +mp4f3erf +mpf3erg +mp6fer6ge mpf3erp -mpf3err -mp4f3erz +mp6ferpr +mp4f3err +mp4f3er4z mp2f3l mpf1or +mp2fr +mp1haf mp1hos -m3pi -mpi3as. +mpin2 +m3plä +mp3lei m4p3lem. m2p3len m2p3les +mp4lis m3pon -mp3ta +mpor6tag +mpor6ter6 +mp3sh +mp3str m3pu 2m1q -2m3r2 -2m1s +2m3r4 +4m1s +m2sam m2san -ms3and m4sap ms1as +m3sat m2sau +msau3e m3sä +m4s1än m3sc msch2 m4sco m3se +m4s1e2d m4s1ef -ms1erw +m4seig +m4sein +m4se2le +mse2n +m4s1ene +m4sent +ms1erf +ms2erh +mse2t +m4s1eu m4sex -ms1ini +m2s1o2d mso2r ms1ori m2spä m2sped +m4spl ms2po m2spot m2spro ms2pu -ms3s2 -m4stag +ms3s4 +mst2 +m6stag +m3stä +m3steh +m3stei m3stel -m3s2ti -m3sto -ms4tr +ms2ti +m2stit +m3s4to +m3s4tr ms5trä -ms5tren m3s2tu ms4tü m2sü +m4sw m3sy -2m1t +m4szi +4m1t mt1ab mt1ak -m3tam +mta2m mt1ar -mt3are +mt3aug +m2t1e2d mt1ein +mt1eis mt1elt +mt1emi +m4tenga +m4t3engl +m4tentf +m4tentg +m4t3en4tr +m4tents +mter2 +m2t1erb +m4t3erei m2t1erf -m4t1erg +m2t1erg +mt1erh +m2t3e2r4i +m2t1erk m2t1erl +mter4n m2t1ers m2t1ert -m4t1eta +m2teta m2t1eu -m2th +m2t1ev +m2t1h mt3ho -m3ti -m4t1im -m4t1ins -m4tint +m2t1i2d +m2tim +m2t1in +m2t1i2r mti2s mtmen2 -m3tö -m4töl +mt1ob +mt1op +m2t1öl mt1ös +m2t3ro m2trö -m4ts1 +m4ts mt2sa -mt2se +mt3sco +mt2s1e +mt3send mt3s2ka -mt2spr -mt4s3tät -mtt2 +mt3s4kel +mts3tät +mt3stu +mtt4 mt1um -mt1urt +mtu3re m3tü mt3z 1mu mu1a mu3cke -2m3uh +mu4ckel +2m1uh mu3la -2muls +3muld +mul4lau +3mult +3mumi +m1ums +mum2s1p 3mun -mun2d1a -4m3unf +mundan4 +mun6derf +mu2ner2 +4m1unf 4m3ungeb mu3ni -m4unk -m2unr -munt2 +mu4nin +4mu4niv +4munw 4munz -mu3ra mu4r1u2f -m4us -3mus. +3m4us mu4s1a -3musc -3musi mu2s1o mu2sp -mus3t +mu2s3t2 +4must. +must4e mu2su mut1au -muts3t -mut4str +mut2st 1mü 2müb 3müh mü2her +mühl1a mül4len 3mün 3müt @@ -8431,831 +13529,1383 @@ mvoll1 2m1w2 mwa2 mwa4r +mweg4s mwel4 mwelt3 mwu1 -1my -my4s -2m1z +3my +my1al +my2s3 +2m1z2 +mzug4 1na 3na. 2n1ab +3naba na2bä -4nabg -4nabh -na2bl -n2abo +naben3s4 +n3abh +3nabi +n3abk +na2b3l +na2bor na2br -4n3abs -4nabt +nab4rü +4n3abs2 +na2bus 3nac +n4ac. na2ch1 -na3chen -nach3s -nach8ters +nachen6 +na5chen. +n3achse +nach3sp +nach8t7ersc nacht8raum -4nadd -n2ade -4n1a2dr -n1af -na1f4r -3n2ag +n1ada +na3dab +3nade +na3de. +nadel1 +na2der +4n1adl +4n3adm +n1a2dr +3nae +na3el +2n1af +na1fra +nag2a +na3ge. na2gem +4n1agg +n1a2gi +na3gin +na3g4r 3n2ah na2h1a n4ahm -n3ahn +4n3ahn +4n3aho 3nai nai2e n1aig +4n3air +nai4re +n2ais 2n1ak -na2ka +3nakä 3nako +na2kro +4nakt n2al. na2l1a2 -na4lal +nal3am +na4lar na2lä -3n2ald -n4ale -na4lent -na2let -nal3l2a -nalmo2 +2n1albk +n2ald +nal3da +nal3ei +na4l3ent +na6lerei +na4ler4g +na4lerm +na4l3erw +nales2 +nal1et +nal1ex +nalg2 +na2lid na2lop nal2ph n2als. -nal3t4 +nal3t +nalt2a +nal5tr +n2alty na2lu 2naly -n4am. +na2mat 3name na3me. -n4amen -namen4s3 -4n3a2mer +4na2mei +n4a3men +namens3 +4n1a2mer +na2mid +na2min na3m4n -3namo +3n2amo +n1amp +nam4sp 2n1amt namt4s -2n1an. -4n1a2na -4nanb -n1and2 -4n1ang -2nanh +na4my +n1an +4na2n4a +na4nat +n3a2nä +4n3anb +n3and2 +nan1eu +4n3anf +4n3ang +4nanh 2nani -4nank -2nanl -3nann -na3no -n1anp +4n3ank +4n3anl +3n2ann +4n3anna +4nano +nan2o3b +4n3anp 2nanr -4n1ans +4n3ans 2nantr 2nanw -nap2si +n2anz. +nanzen4 +nan6zene +nan6zeng +nanzer4 +na3ot +na2per +n1apfe +4napfel +n3a2pr +n1aq n1ar 5nar. na2r1a 2narc n2ard -4narg +n2are +n4are. 3nari n2ark n2arle 2narm -4nart -n3arti +n2aro +na2rom +n2arr +n2ars +2nart +n2arta +n2arth na3r2u 3nas -n2as. +n4as. +na3sä na4schw -4nasp -4n1a2sy +4n1a4sp +nas2s1c +4n1assi +nas4ta +na2str +4na2sy nasyl2 3nat -n4ata -n3a3t4h -na4the -4n1atm -nats1 +n4at. +na4t3au +nat1ei +na2tem +na2t2h +4natm +nat2o +4natom +5nator +nat1r nat4sa -nat4sc -4natt +nats1e +na3tu n1au -4nauf nauf4fr -n3aug +nau2fr 5naui 3n2aul 4nausb +4nausd +4nausf 4nausg +4nausl n2auso -4nauss +4nausr +4n3auss 4nausw +4nausz +3nav +nave4 navi5er. navi5ers 1nä -3n2äc +2näb +3n4äc 3näe +2n1äf +3näg +nä2hi +3nähm 2n1ähn -3näi +nä2hu 2n1ä2m 2n1än -när4s5 -n1ärz -3näs +4näpfel +2näq +när4s5t nä2sc n2äss 2näu 3nä1um 2n3b4 +nbais4 nbe2in -nbe3n -nbe3r2e +nber2e nbes4 -nbu2s nby4 2n1c -n3ce2n3 +n2c3ab +n3can +n3ce4n +n3ces. +n3chl nch3m n2ck -2n1d +ncor2 +n3cr +n3cu +4n1d +nda1f nd2ag +n3dai n2d1ak -n2danl -nd1ann -n2d1anz -ndat2 -n2d1au +n2dana +n2dani +n2danz +nd1arr +n3dat +nd3att +nd1au +n2daut +n2dax +nd1äng nd1c nde4al. +n2d1ede +n3dee n2dei -nde4län +nd3elfe +ndel3l +ndel4s3a +ndel6s5en +ndel7ster +nde4mot +nden3sk n4dentl -n4d3ents +n4dents +nde3o2 +n5der. +n5deren +nd2erh +n5deri nder6läs nde4rob +n4de4ros +n6der6sat nder5ste +n3d2es1 nde2se -nde4spe +ndes3s ndi2a3 -n2dob -ndo2be +nd1imm ndo1c -nd1op +n2dof +ndo2n3a +n2dopt nd1or -ndo2ri +n2do2ri +nd2os +ndo1st +n2d3ott n2dö +nd2ös +nd4ram n2d3rat +nd3rau n2d3re -n2drob -nd3rol -n2drö +n2drif +n2d3roc +n2drod +n2d3rö +n2drui n2d3run -nd2sor +nd4sene nd2spr nd3th -nd3ti ndt4r n2duns +ndwa5re ndy3 1ne 3ne. ne2ap +3neas ne3at +ne3au +4n3ebene ne2bl 2n1ebn +neb4r 2nec 3neca -3ned -2nee3 -ne2e2i4 +3nece +ne2ch +ne1ck +neck2a +ne2dit +2nee +neei2 ne3ein +ne3eis +neen2 +nee1r +neer2e n1ef -neg4 +n2ef. +n2e3f2a +2nefr +2n1egg +neg4l +n1e2go +neg4r +n1ehe 2ne2he. +2nehem 2nehen2 +nehe2r 3nehm -4n1ehr +4n3ehr 2n1ei +3neia +4neic +nei4dei +nei4dr 4neier -4neif 3neigt -4n3eing -4n3eink +3neigu +nei4la +4neing +4neinh +4neink +4neinl +4neinz +4neip +neiss4 ne2ke -nek3t4 -ne2l -3nela +2n1eks +nek3t2 +2nekz +ne2la nel3b -2n1ele +n1e2le 4nelek 4nelem ne3len -ne3li +ne3lex +nel2i +ne3lid +ne2lit 3nelk n2ell -nel4la -3ne3lo -3ne3lu -n2em. -2n1emb -nem4e -n1e2mi -2n3emp +nel2l1a +nel4lei +neller6f +3ne3l2o +3nelu +3n2em. +4n1emb +4n3emp 2n1ems +4nemu 3nen n4en. -n2en3a4 +n2en3a +nen4am +ne4nan ne2nä n2enb n2enc +nen4dar 4n1endb 4n1endd 4n1endf n1endg 4n1endh 4n1endk +n1endl 4n1endp 4n1endt 4n1endw -ne2n1e2b +nene2b nen3ei +nene4m nenen1 ne4nene +nen3erb +ne2n3eu n2enf -4nengb -nen4ge. +4n1engb nen4gen -4nengs -4nengt +4n1engs +4n1engt +n1engu n2enh -ne2ni +ne4n3i n2enj -nen3k -ne2no -n2ens -nens4e +n2enk2 +n2enm +nen4nar +ne2no4 +nen3s4e nen3sk +nen3s2p 5n2en3t2a -n1entb +4n1entb +4nentd +4nentf +5n2enti 4n1entl 4nentn 5nentr -n1ents +4n1ents 4n3entw 4nentz -ne2n3u +ne4n3u n2env n2enw -n2enz -ne2ob -ne1os +nenz4er +ne2o3b +ne2oh +ne2or +neos4 +ne2pen 2nepf -2n1epo +2ne2pi +2nepo ne2pos -n2er. +nept4 +n4er. ne1ra ne2rab +ne2rac ne2r3af +ne2rag ne3r4al -ne2r3am +ne2ram ne2ran -ne2rap +ne2r3ap +n2erat +ne6ratio +ne3rato ne2rau -nerb2 -4nerbe. -4nerben -n1erbi +n2erb2a +4n3erbe. +4n3erben +2nerdb +ner4dig nere2 -ne2reb +ne2r1eb +ne2rec n1erf -4n5erfo -nerfor4 +4nerfas +3nerfr 2nerfü +2ner3g4 3nergr n1erh 4n3erhö 3neri n2erj n1erk +5nerka +n2erkö n2erli 2n1erlö -ner4mit -n2ern. -n1ernä -ner4neu -4n1ernt +n1ermi +2n1ernä +4n3erneu +2n1ernt +n1eros +n1eröf ne1rös -n2erp -3n2ers. -n3ersa -n2ert. +n2ers. +2n1ersa +3nerse +ner4sk +4n3ersts +nert4 +3nert. ne2rup -n2erv +3n2erv +4nerwar 2n1erz -3n2es -n4es. -nes4c +n2es. +ne2sal +nes2an +n4ese ne2sei -ne2sev -nesi1 +ne2s1ev +2ne3sh +ne3si ne3ska -nes1o -ne2sor +ne2s1of +ne2s1or ne2s1pa -4n3essi +4n1es2si +nes4sig ne1sta +ne2ste nes3ti -ne2tad -ne2t1ak +2n1est3r +4nesyn +3neß +ne2tab +2ne4tag +net1ak ne2t1an -ne2tap -n1etat -ne2tau +2ne2tap +2ne2tat +ne4te2l ne2th net3ha -nett4sc -n1e2tu -net2zi +ne3ti +ne4tin +ne4tob +n2ett +net3ta +net3te +net3tr +2n1e2tu +net4zer +net2z1i ne2u neu1c +neu4ere neuer4f neuer4k +neuer4r neuer4s neuer4w -neu3g +neu3g4 2n1eup neur2 +neu2ra +neu3t +3n2evi n2ew +ne3wa 2n1ex +ne2xi +5ney 3nez -1né +3né 2n1f -nf1ak +n3f2al nfalt4 -n3far +n3f2ang +nf4ar +n3f2ä +nfe2i +n3f2en +n3f2er +nf2es +n4fex +nff4 n3fi nfi4le. -nf4l -nf5lin +nf4le nf2o nfo1s nf4r -nf3s +nf3s2 nf2tan -nft2o nf2t3r nft4st +nfts3tr +nf3tu n2f1u 4n1g -ng2abs -n2g1ac -ng1ad +n3gabe +ng1abt +n2g1a2c +n2g1ad n2g1ak -n2g3a2m -n2g1and -ng2anf -ng1anz +ng1a2me +ng3anda +n2ganh +n4ganl +ng1ans +ng1ant +ng1are +n3g2ars +n2g1a2v n2g1äl -ng3d4 -n3gef +ng3d +n2g1eif n2g1ein -ng2en -ngen2a -n3ger +ngelb4 +nge3l4ei +ngelt2 +n3g4en +n5gene +nge5nerw +ngen3sa nge4ram -n4g3erse -nge4zän -ng3g4 +n2g1erg +nger4zä +n3g4es +nge3sa +nge5t +ngg3s ng3hu -n2g1i2d +n2g1id +ng2lad +ng2läs n2glic -n2glo -n3g2loc +ng4lok +n3glot n2gn ng3ne -ng1or -n3gra -ng3rat +n4g3ni +ng4nom +ng2nu +ng2ob +n2g1op +n2g1or +ngo2ri +n2gö +n2g3rai +ng4ran +n2g3rat ng3roc -ngsa4g -ngs3au -ngs3c +ng3rost +ng4s3au +ng4scr ng4s3e4h -ngs3pa +ng4sek +ng4sens +ng4spar +ngs5tan +ngs4teu +n4gt ng3ts n2gum -2n1h4 -n3han -n3har -n3hau -n3hä -n3he +ngung4 +ngzei4t +4n3h2 nhe2r -n3hu 1ni -3nia -nib4l -nich1s -nicht5er -nich8ters +3n2ia +ni3alo +ni2ar +nibb4 +nic4 +ni1ce n1id 3n2id. +ni3da ni2de -ni3dr -n4ie +2nidea +ni3d4r +2n3idy +n2ie nie3b ni1el nie3l2a nie4n3 ni3ene -ni1ero -nifes3 -nig2a -2n3i2gel +ni3eni +nie4rei +ni4erna +nie2sa +ni2eu +nife4s3 +ni1fl +niga2 +ni2g1ab +ni2g1am +ni2g1an +4n3i2gel +n4igen 2niget -nig3r -ni2gre +ni4gl +nig3li +ni2gn nig4sp -3nik -ni2kal +nihi3 ni2kar -ni3ker -ni4k3ing -ni3kl -ni2kr +3nike +ni2kel +ni3kerh +ni2ki +nik3ing +ni2kor +ni2k3r +nik3t4 3n2il -nim2o -4n1imp +ni3l2a +ni3l2i +4nimp nin1 -3n2in. -n2in2a -4n3ind +3nin. +3n2ina +nin2ac +ni2nal +3n2inb +2n1ind 2ninf -3n2ing4 -4n1inh +3n2ing +ning4s +2n1inh +4n1ink2 +3nino ni2nor +3n2inp 2n1ins -n2ins. 4ninse +4ninsu 4n1int -2n1inv +ni3nu +4n1inv +3n2inw ni2ob ni3ok -ni3ol +ni3ora n2ip -ni3ra +ni4ron +n1irr 3n2is +ni4sam +ni2san +ni2sä +nis3cha ni4schw ni2s1e -ni3se. -ni2s1p +4n3isol +ni2som +4nisot +ni2sp ni3spi nis3s4 +nis3tha ni2s1u 2nit +3nita ni2ti -nit4r -nitts1 +4ni4tia +nit2o +3nitr +nit3s +nit6ter6g +nit6t5er6k +nit4tra nitt4sa -ni3tu -ni3v +3niu +ni3v2 3nix -n1j -2n1k -n2k3ad -n2k1ak -n3k2al -n4k3alg -nk2am -n2kans -n2k3aus -n2käh +2n1j +4n1k +nk1abr +n2k1ac +nka2ge +n3kal +n4kalg +nk1ang +nk1apf +nk3art. +nka3sc +n2katm +n2kato +nk1aus +n2kaut +n2k1äh n2k1äp nke2c +nk1ei +nk2eil nke4lei -n3k2er -n4k3erfa -nk4erg +n4kelem +nke4na +nken4te +n4k3erle +nke4ros +nk3ersa +n3kesc +nke2t +nk1eti +n2ketu +nk1i2d +n2kide nk1inh n2k1ins -nk3len +n4klade +n3klag +nk3leis +n2k3len nk3les n3klin nk2lo -nk4na +nk4neb +n2knis +n2knit +n2knu +n2k1o4be +n2kopt +nko2r +nkord2 +nk1ori n2k1ort -nk2öf n2köl -n2k3ro -nk2s1al -nks2ei +nk4rab +nk3rät +n4kre. +n2k3rel +n2kren +nk3rep +n2krez +nk3ro +n2krol +nk2sal +nk2se +nk3sen +nk2so +nks2ti nk3s2z nk2tak nk2tan +nk4tau +nk4tent +nk4terg +nk4t3ern +nkte3sk +nkt2et +nk2tin nkt1it -nk4top +nk2top +nkt1r +nkt3ric +nk2tro nk2tru +nkt4sen +n2k1um +nku2n +nk1urh n2küb 2n3l2 -2n3m4 +nla3ge +nle2ga +2n1m2 +n3ma +n3mä nmen2s +n5mi 4n1n -nna2be n2nada -n4n1all -n2n1an -n5nat +nna2g +n2nalg +n2n1all +nna3m +n2nan +nna3st n2nau -nn3d -nn4ens -n4nents +n3nec +nn2ei. +n3nelb +nne4le +nne4na +nn2ens +nner4ei +n6n5ereig nner4fü +nner6geb +nn4ergr nn2erh nn2erk +nner4la +nn2ero nne2rö -n4n3er4wa +nn3erwa +nner6war nner2z -nne2s1e -nne4st +nne4s1e +nn2eu nn2ex nn3f nng4 n3ni +nnk2 +nn2o3b +nn3obl +nn3obs n2nof -nn1o2r -nn3sc -nn3se +n2nop +nno2r +nn1ori +nn4sam +nn3ser nn3s2p -nn4s3pe nnst4 +nn4stoc +nn2stö +nn5t2a nn2th n2n1uf n2n1unf nn1ur nnvoll4 +nnvol5le 1no 3no. +no5at +3n2oba +n2obel +2nobj no2bla -n2o3ble +n2oble 3noblo +3noblö 2n1ob2s +nobu2 +nobut3 +3noby no1c +noche4 noch4r -2no2d -no3dr +2nod +no2de +no2ed n1of -2n3o2fe +no2fe +2noff +2n1oh +3n2ohe +no2kel +2n3okk +no3kr n3ole no2leu -n2on. +no4lig +no2liv +2n3o2ly +3no3me3 +no3mi +3nomp +non2e +n1onk +nons4 +n1ont +2nony +no2o 3n2opa +3nopä +no2per +2n1o2pi +2n1ops +no3p2te 3nor. nor2a no2rad -n2o1rak +n2o3rak no3ral +no3rar 2norc nor4da -nor2d5r +3nordb +nor4des +nor2d3r +no3r2e +2n1org 3norh +3n2orl 3norm +norm2a +nor3mal +3norö 3nors -n1ort +2n1ort 3n2os. +nos2e1 no3sh +no5s2k no2s3p -n2oste +2no2sti nost1r 2nostv nos2u -no3tab +no2tan +no3tart no2tä -no4t1ei -no2tel -no3t3h -no4tha +no4t1e2i +no6t5entr +no4ter2 +noterb3 +no4tex +not1h +no2tho no2t3in -no2top -no2tr +no2t3op +no2t3r 3nov -3now 2n1o2x 3noz 2nöd -2nö2f -2n1ök -4n1ö4l +4nö2f +4n1ök +4n1öl +n2ör 1n2öt -2n3p4 -npa2g +4n3p4 +npa2ge +npa2s npf4 npro1 npsy3 2n1q -4n3r2 +6n3r2 +nran2 +nrau4ma nräu3s -nre3sz -nrö2s1 -6n1s +nrebe2 +nreli1 +nre3s4z +nro2h +nrö2s +nrücker6 +4n1s +n3sabo n2s1a2d -n2s1all -n2sang -n2sant -n3s2arg -n2saus +n2s1a2gi +nsa2kr +n2sall +ns4alp +n2salt +ns4anat +ns3ane +n2sanm +nsa2r +ns2arg +n3sark +nsa2s +ns4ath +nsau4r +nsau2s +n2saut +ns2av +ns2ax n2s1än +ns2äug n2s1äus -ns2ca +n3sche. +n4schef +nsch5eul n4schl. +nsch2o +nscht4 n3schu nsch7werd +ns2cr ns1eb +nse4ein +ns2eh nse2ha2 nseh5ere +n4seinf +ns2ele +ns3elem +n2sem. +n2sene nsen4sp -ns1ent -ns1erf -ns1erg +n2sepo +n2s1erf +n2s1erg n2serh n2s1erk -n2s1erö +ns4erko +ns1erl +n4serle +n4s3erne +n2serö ns1ers +n4sersc +ns3ertr n2s1erw -n2s1erz -n3sex -nsfi4l -n3sil -n2simp -n2s1ini -nsinn4s +n2serz +n2sety +n2s1eu +ns2ext +nsfi2l +ns3iden +n3sim +n4simp +ns2inf +n2sini +nsinn2 +nsinns3 +n3sis +n4siso nsi4te nsi2tr -ns2kal -ns2kel +n3s2kal +n3s2kel +ns2kis +n3skle +n3s2ky +n5smara +n2s1o2d +ns1of +n4soff +ns4om +n4s3ont n2s1op n4s3ort. -nsp4 -n2spat +ns2pac +nspa2g +ns4pek +ns2pel n5s4pen n4speri -n4spers -n4sph +n2sph n3s2pi ns4pie +ns4pir n2spo -ns3pon n2sprä n4s3prie -n4spro +n2spro +n2sput nsrü2 -ns3s2 +ns3s4 +ns3tabl +n3stad +ns8tagent nst1ak -n3star +n4stale +ns4ta2n1 +n3stand +nst3ane +n3s4tar n2stas -n3stat n4stat. -n4s3tate -nst3eif -n3stemm +n6staten +ns4tati +n4stats +n3stäm +n3s4tän +nst5eife +nst7einhe ns4tent -ns6terbe +ns2tep +nst5erge n5s6terne n5s6terns +ns4teu ns2ti -ns4tic -ns4tob +n3s4tic +n3stif +n4stilg +n3stim +n2stob nst5opfe ns4tor -n4strac n4strie -nst4ru +n4strik +ns4trip ns4trun ns2tu -nst2ü -nstü1b -n2sty +nst3u4t +ns4tüm +n3suf ns2um -n2s1un +ns1un ns2ung -ns4unr -ns4uns +ns4unk +ns2unw +ns4unz +ns1urs +n2s1ut n3sy -n4s3zi +ns4zene 2n1t -nt3abs n3t2a3c -n3t2al -nt1ang +ntak4ta +ntal1a +nta4lin +n4t1all +nta2lo +nt2alp +n3ta3m +n3t2anb +nta3ne +n4tansp +nt1ant n4tanza -nt2arb +n3t2arb nt1ark -nt4at +n3t2arm +nt1art +ntar6tik +nt3artu +n2t1ass +n2tath +n3tatl nt1äm n2t1äu nte3au -nte2b -nt1ebe nte1e nte3g6 nt1eh +n3tehe +n2teig nt1ein -nte5lei -nt2en -nt4ene +n2t1eis +nte4lin +n2t1emo +nt4en +nte4na nten6te. -n3ter -nte4ras +ntera2 +nte6r5eis nt4erh +nt4erk +nt4erm nt4ern +ntern4e nt4ers nt4ert -n4t1ess +nte3sa +n4t1es4s +nte2st +n6testri +n2te4ta nteu3 +nteu6eri nte3v -nt2her -n2t3ho -n3t4hu +nt1hel +nt1hie +n2thot +n3thr +nt4hu +n2t5hum +nt4hy +n3t2i nti3c -nti3k4l -n2tinf -n2t1inh +ntim3p +n4t3ind +n4t3inf +n4t3inh ntini1 -n3ti1t -nt4lem +n5t2lem ntmen2 -ntmo2 -n3to -nton2s1 -n3tö +ntmo4 +ntni2 +ntnis1 +nto3re +n4torg +n4t3o4rie +n2t1öl +nt4ral +nt1rau +nt4raum +nt3rea nt3rec n5t4ree nt3reif n5trep -nt4rig -n5trop +nt4repr +nt3rich +n4t3rieg +n2troh +n3trop +n4tropi n2t3rü n4ts -nts2o -nt4spar +nts2ah +nt3s2p +nts3par +nt5spe nts2t -nt2s3to -nt3su -n3tu -3n4tu. -ntum4 -ntu2ra +nt2sur +ntt2 +n3tub ntu4re. -ntu4res +ntu1s n3tü nt3z -1nu. -1nu1a +1nu +3nu1a nu4ale -nu3ar +nu3a2r3 nubi1 -1nu1c -1nud +2nu1c +3nud +nude2 3nue nu2es -nuf2 nu2fe -1nug +3nug 2n1uh -1nui -nu3k4 +3nuhi +3nui +n2uk4 +nu3kl +n3u2kr +null1a +nulle2 +null3eb n2um. 2n3umb +n2ume 2numf -2numg -3numm -2numr +4numg +2numl +3n2umm +4numr 2n1ums +2n1umv 2n3umz -nu2n -2nuna -nunf2 -1n2ung4 -3nung. -n3ungl -2n1uni -2nunt -1nuo +nu4n +4nuna +2n1une +3n2ung4 +4n3ungl +4n1uni +n3unk +2nunr +nun3s +4nunt +4nunv +3nunz +3nuo 2nup -2nur +2nu2r +nur2i +nur3s +nur2z 3nu2s nu3sc nu3se -nus1i -nu3sl -1nut -nu2ta +nus1p +nu3spo +nuss3er4 +nus6serl +3nut +nu2t1a +n3uto +nu4top nu4t3r -1nuu -1nux -1nuz +3nuu +3nux +3nuz 3nü. 2nü4b nür1c @@ -9263,753 +14913,1218 @@ nür1c 1nüt 2n1v2 n3ver -nvol7ler -4n1w +n3vl +nvoran4 +2n3w 1ny. +2n1ya +n2ya. 1nyh -2nymu n1yo 1nyr 1nys 1nyw -2n1z -n2z1a4g +4n1z +n2zac +n2z1a2g +n2z3a2k n2zan +nz3a4ne +n3zani +n2zar +nza2s +n2zat n2z1au -nz1än -n2z1är -nzdi1s -nze6l3a +n2zän +n2zär +nze4la +nzel6lig +n6zenerg +n3zeni n4zense -n4zentw -n4zentz -nz3erwe +n4zentl +n4zents +nz3erem +n2z1erh +nz1erl +nzer4lö +n5z4err +nz5erste +nzer6tra +n3z4es +nze3sk +nze2t +nz1eta +nze3u4t +n2z1id nzi2ga -nzig4s -nz1ini +n2zinh +n2z1ini +nz1int +nz1inv nz3le -n2zor -nz2öl -nz3s -n2zurk -nz1wa +n2z1op +n2zöl +nz3st +nzt4r +n2z1wa n2z1wä -n4zwir +n2zwet +n2zwir n2zwö n2z1wu ño1 +ñor2 2o3a2 -o4abi +o4a3bi o4ac oa3che oa3chi o4ad oa3de -oa4g -o4a3i -oa3ke -oa4k1l +oad4st +oa3in +o4a3ke +oa4k5l o4a3la o4a3mi +oa4n +oan4a +o4a3q +o2a4r o2as 3oa3se +o5ass o4at +oa4tr o5au -o1ä +2o1ä o1b -ob2al -obal2t1 -2oban -o3bar +2ob. +o3b2al +ob2am +ob2ar +ob1auf 2o3b2ä 2obb ob2e -2o3be. +2obe. 2obea -ob3ein -obel2i -2o3b4en +2o3bec +2obef +o2b3ein +2oben +obe4na oben3d4 -oben3se -ober3in4 +1o2ber +2o3ber. +ober5eis +ober3in +oberin6g obe4ris -2obew +2obev +2obez 2o3b2i -obi4t -ob3ite -1obj -ob1l +3obj +ob1la ob3lei -1o2b3li -2o3blo2 -2o3bo -o2b3re +1ob3li +2oblo2 +2ob2lö +ob2lu +2obo +ob1or +2obö +ob3rei +2obrü +o4bs ob3s2h ob3sk obs2p -ob2sta ob3sz 2o3bu +o4bunt obu2s 2o3bü -2oby4 +o4büb +2oby +oby4t 2oc o3ca oc1c +3occl o1ce och1a ocha2b +ocha2r o1che oche4b -o2ch1ec +o2ch1e4c +och1eh och1ei +oche2l ocher4k +ochi4d och3l och3m och1o -och3ö2 +ochö2f och3r och1s ocht4 -och3te o1chu ochu2f +och3u4t och1w o1ci -o1ck +o1c4k o2ckar +o2ckau o3cke -ock2er +o6ck5er6sc o3cki -o2cko ock3sz +ock3ta o1cl +o3cu o1ç o1d -o3d2a +2od2a +od3ak od2dr -o3d2e1i +o3dec +o3d2e3i odein3 +ode4l3ag +ode4man ode2n1 -odene2 -odesi1 +o3der +ode2s1e ode3sp +od2et o3dex +od2i 2o3dia -odi4er -o3dir -o3div +2odi3c +2odif +2o3dir +2odn +od2o o2don +o2d3op odo4s +od2ö 2odr o2dre odt4 2o3du o3dy -2o1e -oe2b -o2ec -oe2d -oe2h -oe2l -oe2n1 -o4es -o2et +ody2m +2o1e2 +oe3di +oe4m +oen1e +oe3ri +o2e3s +oe4sc +o2e3t2 o3et. o3ets -oe2x -o1ë 2ofa -of1a2c +ofa2c +of1a2d +of1a2g +of2an of1au +2ofä +o2f1e2b +o2f1ec +2ofee o2f1ei -of2en -o3fer +2ofem +o2fent +2o3fer +o4ferb +2o3f2es +o2f1e2t +2ofeu +of3eun of2f1a +off3erz of2f1in 1offiz of2f3l -of2fo +of2f1o of2f3r offs2 off3sh +off3si +off3sp of2fu 2ofi -of3l -of1la -of4lä +ofi3e2i +ofi3k4l +ofi3s4 +2o1fl +of3le +of3li of4lö 2ofo -2o1f1r -of3ra +2ofö +2o1fr of3rä of4rü -ofs1a +of2s1 of4sam -of2spe -of2spr -of2s1u +of3sä +ofs2ch +of4sen +of3sta +of4staf +of3str 2oft +oft2a of2tei of3th +oft4r +2ofu +of3ur 2o1g o2g1ab +o2g1ac oga3d -og1ala og1ang -o2g1ei -oge2l1i +og1ans +o2g1e2i +oge2li +ogener4 +ogerätein8 +o2g1eth +og2gl o3gh ogi2er +ogin1 +o2g1ini +og3ins +og1l +og3le og2lo -og4n -ogo4i -og3s2p +o3g4n +og1o2ri +ogs2 +og3sp og1ste -o1ha +og3sti +2o1ha +oh1alk o1hä o1he -o2h1eis +o3he. +oh1eis +o3hem +o3hen. ohen3s -o2h1er4t -o2h1er2z -o1hi +o3her. +o3here +oh1er4t +oh1er2z +o3hes +2o1hi +2ohl ohl1a +oh2la2d +oh2lä oh3lec ohl1ei -oh3len oh3lep +ohler2 oh4lerg oh4l3erh oh4lerw oh3lo +ohl1o2r ohls2e oh2lu -oh4n1ac +1ohmi +ohn1a +oh4nac oh3nee -3ohng oh2ni 1ohnm oh2n1o -o1ho -oho2la +ohn3sk +2o1ho +oho2l1e +ohol1o oh1o2p -o2h3ö +2ohö +oh3öl ohr3a +oh2rel +oh2rem +ohren3s +ohrer2 +oh4rerg +oh3ri oh4rin -oh1ro +oh2rol +ohr5t4r oh1s +oh3sa +oh3t o1hu oh1w 2o1hy 2oi -o1i2d +o1id. +o3i2da +o1ids o3ie -o1im -oimmu4 +o1i2m o1in -oi2ra -oi2re -o2isc +o4ine +oi2r o3isch. +o4ische o1ism oiss2 oi1th +o1i4tu 2o1j +ojek8tori 2o1k +ok2a +oka3b2 +o2k3ac +oka3i oka2la -okale4 -3o2kel -oki2o +okale2 +oka6lere +okas4t +ok2e +oki4o +ok2la +ok3lau ok1lä ok2li -ok4n -4okr +ok2o +oko4pt +ok2so ok2s1p -okt4 +ok5t2 +3okw 2ol o1la -o2lab -o2l1ak +ol3abu +olaf4 +o2l1a2m +ol1ant ol2ar -olars2 -ol1auf -o1lä -ol4dam -ol4dr +olar3s2 +o3l2as +olast4 +ol1a2v +4o1lä +ol1ät +ol2chr +ol4d1am +ol2dä +ol2d1ed +ol4d3eng +old5ersa +olde2s +ol2deu +ol2dim +ol2d3o +ol2dr +4o3le. +o2l1ef ol1eie -ol1eis +o2l1eis +ol1emb oler2 +ol1erk +ol1er3t ole3s -ol1ex -o1lé +ol1ess +ole2st +ole4sti +ole3u2 +ol1exz ol2fa -ol2fl +ol2fem +olf3ere +ol2f3l olf1r -ol2fra -olf3sp +ol2f3ra +olft4 +olgege3 +olge4ne ol2gl ol2gr ol2i +olie4n1 +oli2er oli3k4 +oli5tu +3oliv +ol3ke ol2kl -olk3r -ol2kre -ol2lak +ol2k3re +ol2kro +olks3 +olk4sc +olk4si +ol2l1ac +ol2l1ad +ol2l1ak +oll3am +ol4lang ol2l1au -oll1e2c +ol2l1e2b +ol4l1e2c ol2l1ei ol2lel -oll5ends -ol4lerk -oll3erw +ol4l3erh +ol4ler4k +oll3erl +ol4l3erw +ol4l3ess +ol2lop +oll3s2a oll3sp -o3lo +4olo ol2of -olo3p2 +olo1p ol1ort -ol2str +ol2ov +ol3s2k +ol4ster +ol3t2h o1lu -3oly -1olym -ol2z1a +olu2th +ol2y +4o3lys +ol2z1a2 +ol3zan ol4z3ern -ol2zin +ol2zim +ol2zo ol2zw +ol2zy 2om o2mab -oma4ner -om2anw -om1art +oma2bl +o2m1a2ge +om1alg +om1all +oma4n3er +o2m1ang +om2anr +om3ansc +o4mante +o2m1ap +o2m1ar4s +o2m1art +omar4te +o4ma2sy +omat2i +o4matom o2m1au o2meb om1ebe -ome3c +o2m1ef o2m1ei -o3m2eis o2mel -o2mene -o2mep +o3meld +omen5t6an +o4mep omer2 +om1erh o2meru om1erz -om2es +omi2c3 omiet1 -o2m1ind +o3mig +om1ind om1ing om1ins o2m1int om3ma -om1org +omm2e +3o4mn +4omo +o2m3oa +o2m1org +om1o2ri om3pf oms2 -omtu3 +om3sk +om3t2 +o2mum o4munt -omy1 2ona -ona2b -o2nae +on3a2b +on2ac +ona3g o3nal -on1ap -o2narb -on4at +on3ann +onan6z5ei +o2n1ap +o2n3arb +ona3th +4onatol +onat2s +o4n3at4t on2au 2onä on1äh -onbe3 2onc -onderer5 +on2dan +onde8rers +onderer7t +ond1r +on2dra +on4drin +ond3sk 2one -one4i -one2n3 -onens2 +on1ec +one2ck +o3nee +o2nef +o3neig +on3ein +on1ema +one2n1 +o4n3ends +on2eng +onen3s2 +on1ep +o3ner. on1erb o2n1erd -on1erg -on1erö +oner4fa +o2nerh +on4erka +on1ers +o3nes o3nett +on2eu on3f2 -on3g2l +on3gl +ong4le ong4r -ong3s +ong3s2 +on2gue 4o3ni on2i3d +onie3g +oni2ga +on4ik o4nikr -o4n1im -on3ing -on3k2 +o4nim +o4nind +o4ninh +o4nins +on3k4 +3onke onli4 onlo2c +onna2 on3n2an on3n2e -ono1 +2ono1 o3nod -o2noke +o2nof +ono2i +o2n3oke +o3nom on1orc +on3ord ono3s +ono3t2 +onrad3 ons1a -onsa4g on4sam on2seb -onse2l -onsi2 +onsen1 +onse4t +onsi2d +ons3ing ons3l ons1p -onst2h -on3t2a -ont3ant -on4t3end -ont3erw -on4t3ri -o1nu +on4spin +onst2a +onst4r +ons5tri +on3ta +on2t1eb +on2te2l +ont5end +on4t3erl +on2th +on4t3rat 2onuk +o3nur +2onut on3v 1ony -on3z +o3ny. +on3z2 +onze3in o1ñ -oof2 +oo1c +ooch2 +oo2gl oo2k3l +oo2kn +oo2mo +oo2ne o1op +oop2s o1or +oor3d oo4sk oos3s4 oo2su +oo2t1a +oo4t1ei +oo2t1h oo2tr +oot2st +oot3t +oo2tur 2o1ö2 +2op. o1pa -opab4 -o2p3ad -op3akt -o3pan +op3adr +op1akt +opa2le +op1ang opa5s +opa3s4t +2opä +1ope o1pec -o1pei -o1pe4n -1oper +2o1ped +op1ef +2o1pei +o1pek +2opel +2open +2opep +o2pera +op1erh +o1pes 2opf. op2f3a op3fah +op2fä o2pfe -op4ferd -opf5erde -opf1l +op2fem +op2fin opf3la op1flü +op2fo 4oph2 o3phe o1pi opi5a4 opi3er. opi5ers. +opie4r3u opin2 -op5lag -o2p3le -op3li -2o3po +2opl +op3lag +o2p5le +o3p2n +2opo +opo2la +op2pan op4pl +1oppo op2p3r +2oppt 2o1pr -1opsi +3o4psi op3sz -1op3t4 -o1q +1opt4 +2opte +op3th +o2pum +2opy +2o1q 2or. or1a -or3a2b -o1rad -2o1ral -o2r3alm +2ora. +o1raa +2or3a2b +o2rabb +o2r3add +or3adr +o1r2ag +o2rak +1orake +o1ral +o4r3alm or4alt -3oram -or2and -o2ranh -or3arb -o1ras -or3att +or2am +or3a2mi +o1ran3d +or4ane +oran2f +oran2m +oran4ze +or3ap +2orar +o1r2as +o2ratt +2orau4 +oraus6wa +or2av +2o1raw +o1ray o3rä or1änd or1ät -or2bar orb2l or1c 2orca or2ce +2ord. 4orda -or2d3am -or4dar -or4dau -or4d3eng +ord1am +or2dar +or2dau +2ordb +ord3eng +orde4s or2deu or4d3ing or2d1ir or2dit 1ordn -or2do +or2do2 2ordr -2ords ord3s2t -or2dum +ord3t +2ordu 2ordw 2ore ore2a -ore2b +o2r1e2b o2r1e2ck -o2r1ef +ore2di +o5ree +o3ref +or1eff ore2h -or1eig -o2rein -or1er -o2rerf -or1eth +or1ei +o3rei. +o3reie +o3r2eif +o3r2eis +oreli1 +orems2 +o3renn +o3rep +o2r1er +o3r2ere +o3r2ero +ore4th o2r1eu 2orf -orf3s4 -or3ga +or2fac +or2far +org4a +org2e 2orget -or3g2h +or3ghi 2orgia -orgi1e or2gl +or3gla or3gle or2gn +or3gne +2orgr 2orh -2o3ric -4orie. -o4rient +2o3ria +2o3r2id +orid3i +4o3rie. +o3rien. +o6rienti o3rier -4oril -4orin1 -or1ins -ork2a -or2k3ar +o3ril +or1ima +ori4mi +2o3rin1 +o4r1ind +o4rins +2or4io +o2riso +2orit +2ork ork4r ork2s +ork3sh 2orm +or2mam +or4mang or4mans -or4ment -2orn -or2na2c -or2n3ar -or2n3ä +orm3asp +or2m1eb +or4m3erf +or4m3er4g +or2mor +orm3ord +or2mum +ormu4n +or4muni +or4munt +ormwa5 +or2n1a2c +or2nal +or2nan +or2nar or5ne. -or3n2o1 +or3ni +or4nin +or3no1 2o1ro -or1o2b +o2r1ob +or3oly oro3n2a +or1opf +o2ro2r +o3rou +or1ox 2o1rö 2orp 2orq 2orr orr4a -or3re -or3rh +or3r2e 2ors2 -or3sa +or3s4a or3sh +or3si +or3sk +ors4tin or3sz or2t1ak -or4t1an -or2t1au -or2tär +or2t1an +orta2r or2tef -or4t3ent -ort2er +orte4n +or4ten5g +ort3erb or4t3ere ort3erf -ort3erk -ort5ersc -or2t3ev +ort3erg +or4terk +or4t3erl +orter6sc +or2t3e2v or2the -ort3ins +or2tin or4t3off -or2tor -or4tö +or4t1o2r +or2tö +ort3rad or4trau or4t3räu -ort3ric +ort3re or2t1um -o3ru +2o3ru or2uf +or1uh +orum4s o4r3un -o2r3ü -o2rya +oru2r +o5rus +o2rü +or3z2e +orzel5 +or2zw 2o3s2a os3ad -os4an +osal2 +o4s3ami osa1s -o4sca +2osc +o4s3ca osch3ar o3sche osch3le os4co -2o3se -ose3e -o2s1ei +2ose +ose1e +ose1in2 +os2el ose2n -o4sents +o2s1er2k os2ex 2osh o3s2hi -o1sho +os2ho +os4hu 2osi +os4it o3sk -o4ska -os3ke +os2kal o4ski -2oskl +2os2kl 2os2ko -os2lo +o4skr +o4sky +1osm +os4mog 2oso +osol1 +o2sö 2os1p +os2pac os2pe os3pec +os3pero +o3sphä o3s2po +os4pot +os2pra +2oss os2sa -oss1a2c +os6s3a2c +os3sag +oss3ala oss3and os4sä os2sei -os4s3en4k +oss5enke os4s3enz -os2s3o +os2s1ep +os4s3er4b +osser4e +os4ser4f +os4sik +os4sim +os2s1o2 os4son -os2s3p +os2sp +oss1pa os2s3t -ost1a2b -os4t3am +ost1a ost3ang -os3tarr -osta4s -ost1au -os4tei +os5tarr +ost4art +os4tat +ost3aut +os4tä +oste2c +oste2n oster3e -os6t5er6we -os2t3h +ost5erwe +oster8wei +ostes5s +os4teu +ost3eur +os2t1h +os2tid os3til -os3to -os4tob +os4tim +os2tin +os3tina +os2tit +os3toc +os4tor ost3ran ost3rä ost3re ost3rot ost3uf +os2tug +os4tüc 2osu4 os1um 2o3sy -o3s2ze +o3s4ze +2oß o2ß1el -o2ß1en2k -o2ß1enz +o2ß1ent +o2ß1en2z +oßer2 +o2ß1erb o2ß1ere o2ß1erf +oß1is 2o1t -ota2go +o3tabe +o2t3abi +o2t1ah +o2t1ak +o3tal +o3tam +ot1ant o3tark +o2tarz +ota2s +ot1ast o2t1au -ot3aug +o3tau. ot1ä -o2teb -o3tei +o3te +o4teb +ote1i o4t1eib -ote1i4n -ote3ine -ote2l1a -ote4lei -ot2em3 -otemp2 -o2t1erw -ote2s -4ot2h -ot4he -ot5hel -o4t3hi -ot3ho +o4t1eic +otei4n +o4t1eis +ot2el +ote4l1a +ote4lin +otel3s2 +o4t1emi +ot2em3p2 +ote4na +o4tentb +ot1erb +o4t1er2l +o4t1erw +ot2e2s +ot2har +o2them +o2t1hi o2thr +4oti o2til o2t1i2m ot2in -otli2 -ot4ol -ot1opf -ot2or -oto2ra -oto1s -o3tra -o2t3re +ot3inh +otli4 +ot2o +oto3b4 +ot3off +oto2ph +o2t1ö +otra3c +o3t4ran +ot3rat +ot4rau +ot3re +ot3ric +ot4rig ot3rin -ot2sa -ot3sc +ot3rus +ot2s3at +ot3sch +ots2en +ots1o ots1p -ot4spa ots2pe ot2spr +ots3tau +ot3sti +ot3stra +ot2su ott1a -ot2tan +ot4tan +ot4ta2s ot2teb ot4terh -ot4terk -ot2th +ot4ter4k +otte2s +ot2t1h +ot2tim +ott2o ot2t3r ot3t4ra ot4tri +ot3t4ru +ot1url o3tü -o2u -oub4 -ou2ce +ouff6 ou1f4l oug2 -ou2ge +ou4ge ou3gl -o3uh -ou4le. -o3um -o3unds +o1uh +ou1is. +2oul +ou2le. +ou2les +ou4li +2o1um +2o2u2n oun4ge. -2our +4our +oure2 +ou2ret ouri4 +ourie4 +ourme4 our4ne. -ou3s2i -outu4 -2ouv +ou3sa +ous2i +ou3ti +3outp +out3s2 +ou3tu4 2o1ü o1v +ov2a +2ovel +o3ven ove3s -2ovi oviso3 2ovo 2o1w +o2w3al o3wec -owe2r1 +o2wh o3wi -o1x +o2wu 2ox. -ox2a -ox2e +o1x2a +2oxe +o2x1el +2oxk ox3l -o2xu -1oxy +o1xo +o2x1u +1o2xy o1yo -oy1s4 -2o1z -o3z2a -oz2e +oy1s2 +o1z2 +o3za +1ozea +2o3zen ozen4ta -o3zi -ozon1 +ozes4sc +4o3zi +ozir3 +ozon1a +2ozy +oz3z +ór3 órd2 ö1b -öbe2la -öbe4li +ö3b4a öb2l -ö2ble +ö2b3le ö2b3r öb2s3 ö1c öch1l ö2chr öch2s +öch4ste +öchst5ei +öchst3r öchs4tu +ö3cke ö1d +ödel3l +öde1r ödi3 ödien3 öd2st @@ -10018,37 +16133,45 @@ ozon1 1öf öf2fl öf3l +ö1g +öge3le ögen2s1 -ög3l -ög3r +ö2g3l +ö2g3r ö1he -öh3l2e +öhe4n1 +öhl2e4 +öhre4 öh3ri ö1hu ö3ig. ö3isch. ö1ke -ö2ko1 +1ö2k2o3 ök3r ök2s +ö2l 3öl. öl1a2 öl1ei öl1em öl4en öl2f1ei -ölf3s -öl1im +ölf2er öl1in +ölk4e öl2k3l -öl3la +ölks4 +öll1a +öl3le +3ölm öl2nar öl1o2 öls2 öl3sa öl3sz -ö2l1u -öl2ung +öl3tu +1ölu ölz2w ö1m öm2s @@ -10059,10 +16182,10 @@ ozon1 ön2s ön3sc ön3sp -ö1nu öo1 -öot2 +öo2ta öoti1 +2öp ö1pe öpf3l öp4s3t @@ -10070,449 +16193,701 @@ ozon1 ör2b3l ör1c ör2dr -ö2r3ec +ör3dra +ö2r1ec ö2r1ei ö2r1e2l -ör2erg -ör2erk -örer2l +ö2r1e2m +öre2n +ö2r1ene +ö2rent +ö3r2erb +ö2r1er2e +ö2rer2f +ö2rer2g +ör2erh +ö2rer2l +ör2err +ör2erw ö3r2erz +ör1ess ör2f3l ör2gl -ö2r1im +ö2rim ör2kl örn2e -ör1o2 +örner4v +ör1o +örpe2 örs2e -ör3s2k +ör3sk ört2e +ör5tri öru4 ö2r1une ö2sa -ö2scha +2ösc +ö2sch3a +ösche2 ö4sch3ei -ö2schl +öscher4 +ö6sch5erf +ö6sch5eri +ö2schi +ö2sch1l ö2sch3m +ö2schn ö2schw -ö2s1ei +ös1ei +ö2sein +öse3str +ö3set +2ösl ö2sp ös2s1c ös2st ö2st +öst1a2 ös3te ös2th ös3tr ö3su ö1ß +ößen3 +öß2ti ö1t -ö2t3a -öte4n3 -öt2h +ö4t3a +öte4n1 +ö2t3r öts2 öt2sc öt2tr -ö1v +ö1v2 ö1w ö1z öze3 özes4 -p2a 1pa. 1paa +p1ab +p2abe +pab2l +pab4rü +2pabw 1pac -pa3da -pa2dr -pa1f4r -pag4 +1p2ad +pae2 +pa3el +pa2es +pa1fr +1pag4 pa3gh pa1ho 1pak -pa1k4l -pak2to +pa3ke +pa1kl +pak4to 3pala pala3t -1palä -pa3li +3palä +3pal2e +pa3l2i +1palm pal2ma pal2mä pal2m1o 2palt +pal2t1a +pal4tei +pal2tr +pa2m3a pa2nar -pa4nat +pa4n3at pan3d +pand2a pan4ds pa2neu +panf4 +pang4 +pa4nisl pank4 2panl 2pann +panne2 +pan4n3eb +4pannu 1pa2no pan3sl -pant2 -panz4 +pan3t2h +1panto +2pantr +panz2 +pan3ze 1pap papi2 papieren8 papie8r7end +pap2pr +pap4s +papst1 +pa1q 1para -pa2r3af +pa4r3aff par3akt -1parc -pa5reg -pa5rek -2par2er -2parg +pa4rant +pa3rap +pa2rä +2parb +1p2arc +par3d +parer8geb +1parf +2parfö pargel6d 1park. -par4kam +park3am par4kau -par2kr -1paro +par4kr +1parks +par3m2 +par3ne +1pa2ro 2parp +2parr +4parta +3partei +1parti 1partn -1party -par3z2 -pa3s2p +3party +par3z +pas2e +pa3sp +pa4spe +passer4 +pas6serg +pas2s1p pa4st 2paß pat1a pat4c -pate2 +pa5t4e2 +2patel +1pat2h 1pati 1pa5t4r 1pau -p3auf +2p1auf pa3uni +2pausz +1pav 1pä 3pä2c +pä3cke +pä4ck3er 3päd +päde2 +pä2d1er 3pär 3päs pä4t1e2h -pä4t3ent -pä2t3h +pä4tent +pä4tep +pä4t3erb +pä2t1h pä2to +pä4tr pät3s4 2p1b 2p3c 2p1d2 pda4 -p2e 1pe. -pe2a +pe2a2 pea4r +p1e2b pech1 -1ped +1peda +1peel pe2en -pef4 +2pef +4p1eff +1peg +pege2l pei1 -2peic -pe1im -pekt4s -2peku -1pel -pe2l1a4 -pe4lein +4peic +1peil +p2eim +2peis +1peit +pekt2i +1p4el +3pel. +pe4l3ab +pe4lai +pe2l1au +pe2l3ax +pe2l1ä +pelb2 +pel3d4 +3pele +pe4l1e2h +pe2l1er pe2let -pe4leu -pe2lex -pe3li4n +pe2leu +peli2d +peli4n pe4l3ink +pel3inn +pel4ins pel3k +pel3l2a pell4e -pel3t +pell2i +pe2lob +3pels2 +pel3sp +pel3t2a +pel4zin 1pem -pena4 -pe3n2al +1pen +pena2r +pe4nas pe2nä -pen3da -pe4nen -1penn +pen3d2a +pe4nen1 +pe4ni2t pe2n1o -3pensi -1pensu -penz2 +pens2a +3pen3si +pen3s2o3 +pens2p +pen3sz +pent2a +2pentw +penty2 +penu2 +pen3z 1pep +pe3pi pe1ra -per2an +pe2rak +per2am +pe2rau +pe2r1ä +per1e2b +perer2 +perer3z +pe3r2id +3pe3r4io 1perle -per4na -3pero -per2r1a +1perlh +per4r3an 1pers 2perse 2persi 3perso +3persp +peru2 +pe3run 1perü -perwa4 -pe3sa -pes3s2 +perwa4r +pe3s2a +pese2n +1pes5s2 pe2st -pes2th +pes4ter +pest1o 3pet +pet4r 1pé 4pf. -p2fab +p2f1ab p2fad p2faf pf1ai p2f1ak +pf1am pf1ans -p2fa4r +p2fa2r pf3are p2f1au -4p3fe. +1pfä +p2fär +p2f1äu +4pfe. +p2fef p2fei pf1eim pf1ein +pf1e2m p3fen. -p2fent -p3fer. -pf2erw -p3f2es +p4fener +p3fens +p3fent +p4f1ep +pfer5a +p4ferde +pfer6pro +pf4es +p2f1et pff4 +p2f1i2d +pf1inn p2f1in3s +pfi2s +pf1lam pf4lan -p2f3lä pf4leg pf3lei pf3lo +pfo2 +p2fob +p2fom p2for +pf1ori pf3r pf1ra -3pf4ro +pf4rü 2pfs2 +pf3sa +pf3se pf3sl +pfs4ti pf3sz -2pf3t -2pfü -2p1g +2pf3t2 +pft4r +p2fum +2p3g2 pgra2 1ph 4ph. -2phä -2phb +ph2a +phal4te4 +p1hand +3pha1s +p1hau +phä1 +3phän +4phär +4phb 2phd 2p1hei -phen3d -phen3s +phen3d2 +phe4n1e +phen3s2 2ph1ers -2phf -2phg -phien3 -phi2ka +4phf +4phg +p2hid +phik1a +phi4kan 2phk ph2l -2phm +4phm 2phn -p3hop +p2ho. +p2hob 2phö -ph4r -2phs -pht2 -2ph3the +ph2r +4phs +ph3t2 +2phthe phu4s +phu3t 2p1hü -2phz -pi2a3 +3p2hy +4phz +p2i2a1 +piab4 +pia3k +pi4ali +pia3n piap2 -pias4 -pi3chl -p4id2 -piegelei8 +pi1ce +pid2 +pi2e1i pi2el -piela2 -pie4lei +piel3a 3pier -3pik +pie2ra +pie4reb +pie4rei +pi3gl 1pil pi3le +3pilo pil4zer -2pind -pin2e +pil2zw +p2im +3pin. +pi2nad +3ping pingen4 ping3s +3pins. 3pinse +pin3s2p pi2o -pi3oi +pi3oide pi3onu -3pip +pi3os +1pip pi2pe +3pirate pi3ri 3pirin -3pis -4piso -pi3t2a -pi1th +1pis +2piso +pit2a +pi3t2h pit2s -2pitz +pit3z2e pi2z1in -p1j +2p1j 2p1k2 pku2 -pkur1 -1p2l4 -4pl. -3p4la -p5la. -p5lad -plan3g -3plä -2ple. +1p2l2 +2pl. +3pla +4p3lad +p1lah +pla3na +p4lau +pla2y1 +2p3le. ple1c ple2e p4leg -ple5n2 +ple3n2 2p3ler +p4leu 2plig -p4lik +3p4lik p4liz -p4lo +plo3n 2p3lu -2p1m2 -2p1n +plu2s +2p3m2 +2p1n2 1p2o -po3b4 -po1c +pob2 +2po1c +3pock 3pod +3poe +po2el 2poh po2i -po3id +po3id. +po3ids 3poin -3pok -3p4ol -po2lau +3pol +po2lan +po2l1au +pold2e po3li -po4lor +po3lo3p +pol3z2 +pom2ph 2pond -po1o2b -po2p3ak -po2p3ar -po1pe -po2pl -po3pt +pont2 +po1ob +po2p1ak +po2p1ar +po2p3l +po3p2t po1rau porf4 por3s -por4tin +3portal +por2t1h +3portio +3porto. +3portos +3portr por4tre -por6tri -pos2e -po4sta -pos4t3ag -po4stä -po2s3te +3posi +poss2 +po2sta +pos4tag +po2stä post3ei -po2sto -pos6tr +pos3tel +pos4tem +pos4tr post3ra -po3ta +po2ta +pot1ar +3potä 3pote +pot2h +po2t3in +pott1r po2t1u +po3un po2w +powe2 po3x pö2bl pö2c -2p1p -p2p3a2b -pp3anl -ppe1e +4p1p +p2pab +pp1ans +p2pat +pp1au +ppe3e +p2p1ei +ppe2l1a ppeli5ne -ppe2n1 -ppf4 +ppel3s +pp2e2n1 +p2p1erz +p2pf4 pp1fr p2p1h -p3p2ho -p2p1ia +pp3he pp3l -pp1lä +p4p1lac +p4plan +p2p1lä p2ple pp3oh -ppp2 +p2p1ö4 +pp3p4 p2p3ra +p2p5rä p2pri -pp3sa -ppt2 -p2r2 +pp3rol +pp3rot +p2p3ru +p4ps +pp3s4a +pps2p +pp3sy +ppt4 +p4p1um +ppyl2 +p2r4 1prak 1prax p4rä 1präd +1präf 1präg +1präl 3präm +1präp 3präs +1präv 2pre. 2prec 3pred -pre2e1 +2pree1 +pre2ei +2preg 1prei 3preis prei4s3c +prei6sei +prei4s5t 2preiz +1prem +pren4ga 2p3rer -3p4res +1pres +pre3sa +press4e pri4e 2prig -3prinz +pri2l1 +2pring +prings4 +1prinz pri2t1 priter4 +prit5t4 2pritz -1p4ro +1priv +1pro 3prob +pro3be 2proc -3prod -3prog +7p4rod +3p4rog 3proj -2pross +4pross pro1st -3prot +prot2e +3proto +2prott +pro3x +2prö 1prüf +1prüg 2prüh 2prün 2p1s 4ps. -ps4an -p3se -p3s2h -ps1id +ps1ad +ps2hi +ps1od p2sö -ps2po +ps4pi +pss4 p2st p3sta +pst1au +p3stä p3stea p3stel +ps2th p3s2ti -pst3re +ps4to +p3stö ps2tu p3stü 3p2sy +4psys ps2ze 2p1t pt1a pt2ab -pt3alb -pt3at -p3te -p4t3ec -p4t1ei -pte4l -p4tele +pta2g +p2t3a4t +p2t1e2b +pt3ec +pt1ef +pt1ei +pt1emi +4pten +p4t1en2g p4t1ent -p4t1ep +pt1ep pt3erei -p4t1erw -p4t1erz -p2th +pt1erw +pt1erz +p3tet +p4teta +p4t1e2ti +p2t1h +pt1id +pti2de pt1in1 -p4tos +pto2mo +pto4na +pto2p pto2w -p2t3r +pt3r +p2tro pt3s2 -ptt2 +pt4sl +pts4t +pt1uh pt1um pt1urs ptü4 3p2ty -pt3z +pt3z2 1pu pu1a pub4 @@ -10520,2388 +16895,3897 @@ pub4 pu2dr 2p1uh 2puk +pu2kl +pu2k1o +pu2lin pul2sp -2pund -3punk +pul2st +2pulw +pum2pl +3pun +4pund +pun2e pun2s -2punt +4punt 2pur -pu3ri +pu2ra +pu2rei +pus2h +pu3she pu2s3t -3put -put2s +pu5t2e +3put2s +3putz +puzi3 1püf 2pül +pül3l2 2p1v 2p1w pwa4r -3py1 -pys4 +3p4y1 +py3s py3t -2p1z +2p1z2 qu4 +que3rel +quer5n que4te. 1queu 1ra. -2r1aa +r1aa ra2ab -3ra3ar -3raau +2raac +2raal +ra3ar +r2a1as r1ab -ra2bar -rab2bl +ra2b1ar +r2abä +1rabbi +rab2b3l 2rabd -r2ab2er +rabdru4 +ra2bei +rab2er +rab3erd 2rabf 2rabg -1r4abi -ra2br -2rabs +2rabh +1rabi +2rabk +r2able +ra2bli +ra4b5lo +2ra2br +2rabs4 2rabt -ra2bü 2r3abw 1raby -ra1ce +2rabz +ra2ce 2r1acet ra4cheb -ra4chin -racht3r -rach6trä +ra2cho +2rachs +rach6t5rä ra2chu r2ack -r2ad +1r2ad r4ad. -ra2dam +rada2 +ra2dac +ra4d1am +ra2dan 2radap +3radar +ra2de4i 3radf -r3a2d3r +3radh +3radio +4radit +3rado +3radp +ra4d1r +rad3ri rad5t4 -1ra2e -ra3er r2af +raf3ahn raf3ar -ra2fer -ra3ge -ra3gle +rafe2 +ra2f1er +raf3r +raft5s +rag2a +ragein4 +rages4 +2ragg +ra3g4le +4ragm ra2gn -3r2ahm -2raho +r2ago +rahle4n +5r4ahm +r1ahn +2ra1ho 4raht r2ai 2raic -rail4l +rail2l 2r3air +raka3 +1r4a3ke +2rakk 3ra1k4l ra2kre ra2kro 2rakti -3rakü +1rakü +2rakz r2al r4al. ra2la2 -ral3ab -rala4g -r3alar -ral3b +ra4l3ab +ral1ak +rala4s +ra2lä +ral3b4 3r4ald -ra3le -2ralg +ra4l3end +ra4lent +ra4l5ern +ra3lex r4ali -rali5er. -rali5ers -ralk2 -ral3la -rall2e -2rallg +ra2lid +rali3er +ra4lin4d +ra4l3ing +ralin6sp +ralin4t +2r3alk. 2r3alm. -r3alp. -2ralpe +2ralp. +4ralpe r4als +ral3sk +ral3su r3alt -2ralta -r4al5t2h -ra2lu +3r4al5t2h +ra2l3u 3raly rama3s +ra2mei ra2mer -1r2ami +r2ami +r2amm ram4man +ram6mens ram6m5ers -ram4mu +ram4m3u +2ramn +3ramsc 2r1amt ramt4s -r2an. -ra5nat +2ramu +2rana +ran1ad +ran3ade +r1a2nal +ra2nan +ra2nar +ra2nau 2ranb r2anbe -4ranc r4anda r4ande ran4dep ran4d3er +3r2andi rand3s -4r3anei -r4aner +1raner 2ranf -1rangi -rani1e +2ranga +ran6g5e6be +3rangi +r2angl +rangs2 +rang3sp +rang5ste +rani3e +r3a4nil +ran3ka ran2kr -2ranl +ran2kü +4ranl 2r1anm +r2anmi r2anmu +2ranna +ran5ne 2r1anp 2ranr +2rans r2ans. -r2ansp +r1ansc ran4spa -ran2th +4r5antei +r1anth +r2anto 2rantr -2r3anw +1ranu +2ranw +r2anz. r2ap +2rapa +ra2par 2rapf -ra2pri +2rapo +ra2pok +rap2pr +2r3a2pri +2r1aq r1ar -r2ara +r2ar1a 2rarb -3rarei -rar3f4 -ra2r1in +r2are +3r4arei +raren1 +rar3et +rar1e2v +r2arf4 +ra3rie +rar3in +ra3ris +r3a4rist +4r3arit r2ark -2r3arz -r2as +raro2 +ra2rom +2rart +2rarz +rar3zw r4as. ras2a +ra3san ra4schl -2rasph +r2asm +ra3spr +r2ast +ra2sta +ras4t3ei +r3asth +ras4to +2rasyl 2raß 1rat r4at. -ra2t1a +ra2t1an +ra2t1ei +r3a2tel +ra4tid +2ratm rat2o +2ratom +ra5tor rat4r -2r3atta +r3att +2ratta +2rattr 4ratz +rat3ze 4rau. 3raub. -4raud -rau3e2n +rau3e4n 2rauf -2raug +rau3fä +2rau3g2 3raum rau4m3ag -rau4man +rau5mes rau2mi 3raup 4raur 2rausb +3raus2c +2rausd +rau3se +2rausf 2rausg +raus8gewä +2raush +2rausl rau2sp +2rauss +raus8sche raus5se +2rausv +2rausw +rau3ße +2rauto +raut1r +rau4tra +rau4tro raut5s 1raü r2ax -raxe3 +raxi2 +r3axt +r2ay +ray1o +r2az +räch2s 3r2äd 4räf rä1fr 4räg 2räh -2räm +4räm 3rän. 3räni 3räns +2räp +2räq 2r1är r2är. rä3ra -rä4sc +rä1ro +rä2sc +räse2 +räte1s 3rätse +4rätz rä2u 4räue -4räun räu2s -räu5sche +räus4c +räu7schen. +2räuss +2räuß 4räut +2räx 4r1b -r2b1ab -r2b1a2de -r2bak -rbal3a -rba3re +r2b3a2b1 +r3bac +rba4del +rb2al +r3bam +r2bang +r2bant rb1art +r2barz rb1auf rbb2 rb1ech -rbeid4 +rbe3erf +rbei3d2 +rbe3inf +rb3einh +rbe3int r4belä -r4belis +rbel2o r3ben. -rb1ent rbe3r2e -rber4gl -rbla2d +rber6gin +rbe3rum +rbe3sl +r2bim +r2binf +r3bit +rbit2a +rbi3tu +rb4la2d r2blan r8blasser r4b3last -r3blä -r2ble. +r3blat +r3blau +r2b3le. +r3blen rb3ler r2bleu rb2lin rb2lö -rb2o -rb4ri -rb2s -rb3se -rb4sei -rb3ska -rbs1o -rb3sp +rb2ob +r2bonk +rb3ras +rb3rea +r8b7rechts +rb4sam +rb2sei +rb2ser +rb2s1o rb4stä +rb2su rb2u -rbu2sc +rbü4b rby4t 2rc r1ce r1che. r1chen -r1chi +r1ch2i rch3l +r3chlo rch3m rch3r -rch1s2 +rch4ro +rch1s4 rch3sp -rchst4 rch3t2a -rch6terg -rch6terw +rchter6r rch1w r1ci r2ck r1cl r1ç -2r1d -r3da -r4dab +4r1d rd2ac -r4daf -r4d1ak -r4d1al -rd2am +r2daf +r2d1ak +r2d1a2l +rd2amm rdani1 +r2dann rd1ant -rd1anz -r4dap +rd1ara +rd1ark +r2darz +rdär2 +r3de. +r3dee r2dei rd2ei. -r4deis r2d1elb -r3den +r2de2le +r2delf +rdem6 rden3d -rde3re -rder4er +r4dengl +r4dents +rde3ob +rde3ono +rde3r4er rderin6s r4d3ernt +r3des rde3sp -rdgas3 -rdi3a2 -rdia4l +r2d1e2x r2d1inn -rd1it -rdo2be +rd1iri +rd1ita +r2dof r3don -rd1os +rd3oss +rdo4st +r2d1oz r2dö rd3rat -rd4ri +r2drau +rd3ris +rd4rö +r3d4rü +rd2sän +rd3s2k +rd3s2z rdt4 -rd3ta +rd3t2a rd3th -rdwa4 +rdt2s +r2d1uk +rdwa6r 1re 3re. -re3aler -re2am +rea2d +rea6l5erw +4re2am re3at. re3ats +reatu3 2reä re2b1a re2b1l reb1r reb3ra -re2bü -r2ech +reb3so rech3ar 4rechs 2reck. -re2cka 2recki 3red. +re3da 4redd 2redi +re2dik +3redn +3redu +re1ebe re1el +re1em +ree4mi re1er 3refe -2reff +4reff +r2eff. 3refl 3refo 3reg -5reg. rege4l3ä -2reh +regene7ra +4r1egg +re3gi re2hac +re2h1ar +re4hen4e re4h3ent -re2h1i -rehl4 -reh3n +re2hi +reh1l4 re2h1o +re3hol +3rehö +reh4th +re2hü r2ei. +r2eib +rei4bel +rei4ble +r2eic +2reid r2eie +4reier. +rei4fei +4reifel 2reig +3reigä +3reigeh +r4eigel +6reigens +3reigi +4reign +3reigru rei3l2a rei3l2i +2r1eilt 3reim reim2p r1ein -4reinb -rei3nec -4reing -r3eink -4reinr +2rein2a +rei3nal +2reinb +rein4du +rei3n4e3c +reinen5 +2reinf +rein4fe +re4info +2reing +2reinh +4reinn +4r3einr +2reins +4reinsa +rein6sel rein8s7tre +rein4sz +2reint +rein6teg re1in2v +2reinw +2reinz +4reisar +4reisb +reises4 +2reisf +2reish +2reisr reister6 +4reisu +2reisw +reit3s2 3rek 4re2ke -re3la -2r1elb +4rekk +5rekn +2rekz +r2el. +r2ela +re3lat +2relb rel2e -re3lei -2re2lek -2r1elf +relea4 +re5lei +re2lek +4relem +r2elev +2relf +2relit +2relix +r2ell +rel4lar +rel4lei re3lo -2r1elt +r2els +2relt relu2 -r4em. -r2emi -4rempf -4remu -r4en. +3r2em. +2r1emb +rem2da +re2m1ei +re3men +2remi +re3mig +2rempf +rems1c +rem4str +2rem2u +r2en. r2ena -rena2b +2rena. +re4nac +re3nad re3nal +re4n3an re2nä +2r1endg 3rendi ren3dr -re4n3end -ren2gl +4renerg +4rengag +ren4gan 2rengp +3renh re2ni +3renm ren4nar -ren3sau -2r1entg +ren6nene +renrü2 +ren6sein +rens2p +2rentd +6rentera +2rentf +3rentfo +2rentg +r3enthä 2r1entl 2r1ents -2rentw -4rentz +2r3entw +2rentz r2enz +ren6z5er6f +renzer6l +ren6z5er6s +renzer6w +ren4z3in ren2zw +re2ob re3or 3repe -re4pis -3repo +4re2pen +2repi +re2pis +2repoc +2r1e2pos 4repp -3r4er. +3repu +3r2er. +rera2 2r1erb +3r4erber rer2bi -r4erbil -r2erbr 2r1erd +rere2 +4r3ereig +r1erek +re2r1ep +r2erer r1erf -r2erfe -r2erfl +r3erfa +4rerfah +2rerfi +2rerfo +r2erfr +rer2fü r1erg +4r3ergeb +5rergebü r4ergen +3r4erges +2rer2go +rer2gr +r4ergru +r1erh +rer2hö r1erk +rer4kan +rer2ke 4r3erken -r2erki -2rerkl -2r1erl -5rerlag +3r2erki +3r2erko +r1erl +2r3er2la +5r4erlag +r3erleb +r2erli +2rerlö 2r1erm rer2n 2r1ernä +r1erne +2r1erni 4r3erns -4r3ernt -r2e1ro +4r1ernt +re1ro re2rob -r1erö -3r2ers. +re4rosi +2r1er2ö +r1erre +rer4reg +rer4rei +r1erri +5r2ers. 2r1ersa +rer3sc +r6erschi r2erse 2rersp -r1ert +rer2st +r6erstad +2rer4su +r1ert4 r2erte 2rertr +r1erw +2rerwa +rer4wac +rer4wec +r4erwes 2r1erz -rer5ze -r2erzy -3r4es. +rer2zä +3r2erzy +3r2es. re2sa +re4sam +resche4 re4schw 3rese -3reso +re4se2h +re2s1of +3resol +3reson +re2spa +res2po 2ress -ress2e +4resse +res3sei res6s5erw -3rest +4ressu re1sta -re2s2tu +res4tas +res6tent +res4tex +2res4tu 3resu -re2thy +re2t1ak +2re2tap +re2tau +ret2e +2r1e2th +re2tra +re4trol re2u +reu4eri reu3g2 2reul re3uni -2r1eur +2reur +4reuu 2reü -2r3evid -r1ew +4r3eva +2r1evid rewa4r re2wi -4r3e2x1 +2rewo +2r1e2x1 3rez -4rezi +2rezi 1ré -2r1f +4r1f +rf1a2ck +r3fam +rfe2i r2fent -rf2es +r3f2es +rff2 +rf3fe rfi4le. -r2flan +r4fland +r3f4lä rf3lic -rf3lin rf4lö r3flü +r2fo2b rfolg4s -r3for +r4frauc rf4ru rf4rü rf2sa +rf4sam rf2s1ä -rf4s1id -rf2spr -rf2s3t +rf2su rf2ta -rf3t4r +rft4r rf2u -4r1g -rg2ab +rfzu3 +2r1g r2g1a2d r2g1ah r2g1ak -rg2an +rga4ner +r2g1ap +r2garb +rg3art. +r2g1ask +rgd2 rge4an rge2bl -rg2el +r2g1e2c +r3gel +r4gelef rge4l3er rgen4z3w -rge4ral -rge4tap +r4ge4tap r2geto rgi4sel -r3gla r2glan +r3glanz +rg5le. r2gleu r2glig -rg2lö +r2g3lit +rg2log rg2lu -r2gna -r2gno -r2g1ob +r2g3na +r2gne +r2g3ni +r2g3no +r2g3oa +r2gob +r3gog +rg3op +r2g1or rgö2 r2g1öd r2g3ral +rg4rau r2greg -r2gres +r2g3res r2gret rg3rin +r3grun +rg3rüs +rg3sä +rg3se +rgs2ei +rg4sel +rg3s2i rg3sp -rgs2ti +rgs2pe +rgs2po +rg3st rgs4tr -rg5s2tu +rgs2tu +rg3su r1h4 2rh. -2rha -r2ha. -r3hals -2rhä -3r4he. -2r3her -r2hoe -r3hof -rho2i3 +r2hag +2rhah +2rhak +r4haltb +r3han +2rhau +2r3hä +3r2he. +r3hea +2rheb +2rhef +2rhi 2rhol -2rhö +r3hop +2rhot +2rhöl 2rhs rhu2s +2rhü 1ri -ri3am +ri3ams +ri1an +ri2ano ria1s -ri3at +ri2ast rib2bl ri1ce ri1cha -ri2dan +ri3chl +richt8spo +3richtu +ri2con ri2dau -rid2g +2ride +ri2d3e2l +ri4dent +r2i3di 2ridol 2ridy r2ie -rie2fr +4riefm +rie2f3r +rieg4s3 +ri2e1i +riein1 ri1el +rie3l2a ri3els -riene4 +ri4enä +riene2 ri3eni rien3s -rie2nu +rie4nu ri1er. -ri4ere +rie3r2e +riere4n ri3ers. -ri3esti +rie3sa ri1eu ri2f1a -ri2f1ei -ri2f1er +ri2fä +ri2fei +ri2fer +rif6f5end +rif4fer ri2f1o ri2fr rif3s rif4ter 3rig +4riga +4r3i2gel ri4gene +4rigg 5rigj rig1l +ri4glä +ri3g2o3 4rigr -rik1l -ri4kla -r2imb +4rij +ri2kar +ri2kä +ri2kin +ri2kn +ri4kone +rik2op +ri2kor +2rima +ri2mag ri2me. -2rimp +2rimm +4rimp rim2s rim4sc -r2i3na -2r1ind -rin4dex -rin4diz +rim4st +ri3na +r1inbe +rin2c +2r1indu ri3n2e rine1i 2r1inf rin2fo +3r2infr +r2ing rin2ga -ring3l +ring3le rin2gr +ring3sp 2r1inh 2rinit -2rink +4rinj +4rink rin2kl -3rinn +rin2ko +rin2kr +2rinl 6r5innenm 4r3inner -4rinnta +2r1innr r1innu -2rins -3r4ins. -rin4so -rin2sp +2r1in2q +2r1ins +rin4si +rin2so r4inspi +3r2insy 2rint -rin4teg -rin4t5r +4rinte +rin6tent +rin4t5re 2r1inv +rin2va +2rinz +ri2ob +r3ion +ri3o2st +ri2pl +ri3po 4r1ir r2is ris2a -ri4scho +ri3san +ri4sch3o ri4schw 3risik -rismu2 -ri3so -ri4s1p +ri3s2ko +r3iso +ri4s3p +r3isr 3riss -ri4st +ri4s3t ris6t5ers +ris4th +rist3r r2it r3i2tal -ri3t2i -ri3t4r -rit2tr -5ritu +rit3ant +rit2i +2ri3t4r +ritt3a +rit4tau +rit6ter6f +rit4to +rit2t3r +rit2u +r1i4tum rix1 1rí 2r1j 2r1k +rka2b3l +rk1ah +r2k1ak +rk1all rk2am -rk4ap +rk1are +rk1asp rkauf4s -r2käh -r3kla +r2k1äh +r3kel +r4kelem +rke2n1 +rken4er +rken3s4t +r2k1er2l +rk5ersta +r2k1er4w +r3k2es +r3ket +rk1im rk4las rk4lau +rk4lim r2klis rk2lo rk2lu -rk4n -r2k5nu +rk4ne +r2kob +r3kol +r3kon +rk2op +rk1o2ri +r2kou +rk2ö rk3räu -r2k3rea r3kri -rk2s1e +rk3rin +r2k3rom +r2krou +rk2sal +rk2sei +rk2sel +rk2ser +rk2so rk2sp rkstati6 rk4stec +rk4stoc rk2ta +rk2tel rk4t3eng +rk4tent rk4t3erf +rk4terg +rk4t3erl rkt3ers rk6tersc rk4t3erw rk4t3erz -rk2tin -rk2t1o2 +rk4teta +rkt2i +rk2t3in +rk4t1o2 +rkto4b rk2t3r -rk3tra rk4tri -rk2um +rk2tum +rk1ums rku2n -rk1uni -4r1l +r3kup +rkur3s +r3kus +rku2sa +r2küb +2r1l rl2ab -r5lag -r5lan +r3lag +r5land +rlan4d3i r2l1ar -r2l1a4sc +r2l1a2sc r2l3aug -rl2e -rle4a +rle2a r3lec -rle4i -r3let +r5lei. +r3lep +rl2et +r3lex +rlg4 r3l2i +rli4ne. rli2s r3l2o +rlou1 +rl2ö rlös3s -rl2s1p +rls2a +rl2spr rl3ste -rl2s3to +rl2s5to rl3t -r3lu +r3l2u +r3ly rlz2 4r1m r2mab -r3m2ag +r2m1ad rma2la -r2m1ald +rm1ald +rm1ami r2m1ank -rm1ans rm1anz -rm1a2p -r2maph +r4m3aph +r2marc +r2marz +rma4s3pe +rmas3se +rmat2o +rm2är rm3d2 -r2m1ef +rm1ef +r4m3einh +rme4na +rm2ene +r2ment r2meo +rmer4fo +r2m1erh +r2m1erl r2m1erp +r2m1erw rm2es +rme1st +rmes4z +rmeta2 r2mide -r2m1im -r2m1o2ri +rmi6nanz +rminen4 +rmi6neng +r4mn +r2m1ob +rmon3s4 +rm1o2ri rmo1s +rm3p2 rm3sa -rm3sta +rm3s2k +rm3t rmt2a -rm2u -rm3ums +rmu2n +r4muna +r2muni 4rn rna2b +r3nad +rn4ade +r3nage +r2n1all rna4n -rn2and +rn4and rn3ani -r2n1anz +r2nanz rna2r -rn2arb rn3are -rn3ari +r4n3ari +r4n1ast +r4n3att r2nau +rn3aug rnd4 +rn3de rn3dr -r3ne -rn3e4ben r4nef -rn2ei -rn3eif -r4n3eis +rn2eid +r4neif +r4neis +rn1ema rne2n -r4n1ene -r4nerf +r2n1ene +rn2eng +r4n1e2p r4n1erg rn4erhi +rner4ke +rner4ku +r4n1erl r4n1ert -rner4ve +r4n1erw +r4nerz r5nes -rn2et +rn2e2t +rnet1e +rne4tem +rne4ter +rne4to +rn2eu rne3uf r4nex rn3f -rng2 -r3ni -r4n1in +rn3g2 +rngene4 +r2nid +r2n1in +r4ninf +r3nit +rnk2 +rnn2 r3nod +rn2oh r2n1op r2n1or rn1ö +rnö2d rn3sa rn3s2ä -rn3s2p +rnse4ha +rn3s4p +rns2u rn3s2z +rn3t2a rn3t2e -r1nu rn1ur r1nü r1ny -ro2bei +rnz2 +r2oba 2robj 1robo +ro2bo2r +2robr +ro2bre 2robs ro1c +roch2a 3rock. r2o3de -ro3e4 -roh1l -3r2ohr -3roi +rod4r +roe4 +2roff +ro3fl +4rog. +ro3g2a +3rogg +ro2h1in +roh1l2 +4rohn +ro2hö +3rohr +1roi +ro3in ro1ir +rok2l ro3le +ro2liv rol4lan -rol3l4en +rolle4 +rol6lerg +rolls2 rol3s 2roly 4rom. ro2mad -ro2mer +ro2mal +3roman. +2romb +romen3e +ro2m1er 4romm +2romn +rom3s 4romt r2on +ro3n4ab +ro2nan +3rond ro4nerb +4ronk 3ronn rons2 ron4tan -4ro1ny -ro1pe +ron6tend +ron4t3r +ron2t1u +ro1ny +ro1o2f +rop2a +2rope 2ropf -ro3ph +1ropl +2ropt r1or -r2ora ro2r3al ro2rat -ro2rei -ro2r1o +2rorc +ro2rel +ro2ro ror3th +rort2s +ror2ü ro3sh -ro3s2i -ro3smo +ro5s2i +ros4ko +ros4sal ros4san ros2s1c -ro3sta -rost1r +ros6senk +ros4st +ro1sta +ros6t1r +ro2sum +4r3osz 4roß -ro2ßu -ro4tag +roßen2 +ro4ßenk +ro2ßi +ro2tan +ro4tas +ro4t3au ro2tä -ro2tei -ro2tho -ro4tri +ro2te3i +ro2t1ho +ro2tru +rot3s rots2o rot2ta -ro3t2u +ro3tu +3roul ro3unt 3rout +2ro1x +4roy rö2b3l rö2du 2rö2f 3röh -r1ök +2r1ök 1röl +2röl. +rö3le +röl2l +r1ölp 3römi -4röp r1ör r2ös. +rös1c r2öse +1rösl 3rötu 2r1p2 -r3p4a -r3p4e -rpe2re -rpe4r3in +r3pa +r3pe +rper3in rpf4 r2pli +rp4lu +r3po rpro1 +rp3se rps3t -rp3t +r4p3t r3pu 2r1q -2r1r +4r1r rr2ab -rr2ar +rr4at rrat2s +rr1auf rr1äm rrb2 rr1c -rr2e -rre4ale r5rega -r5rei +r5regi +rr2ei rre2le rre2pa +rrer2 +r2rerh +r2rerl rrer4s -rre2st +r3res rre2ve -r2rew -rr2he -r3r4hen -rrik2 -rr2n3a -r3r2o -r4r3ob +r4rezi +r3r2hen +rr2hos +r3r4i +rri3k2 +rrm2 +rrn3au +rr2o +rr3obs rro3m +rro2re +rrr2 rr2st +rr3str rr3stu rr2th -r3ru +r3r2u r3r2ü -rrü1b -4r1s +rrz2 +6r1s +r3sabo r2s1a2d +rs2al r4samp r4s1amt rs2an +r4sanf r2s3ang -rs3anp +rs3anm +r4sanp rs3ant -rs2au -r3sche +rs3anz +rs3ar +rs4ark +r4sarm +r4sch3e4b r6scherl r3schu -r3schw +r2s1ebe +rse2e +r2s1ef r2sein -rse2n1 +rse2n rs2end rse4ne +r2sepi rs1ere -rs1erö +r2serh rs1ers -rs1erz +r2serz rse2t rs1eta +rs2ext +r3s2hav +r3shir r3sho -r3si -r4sins -rs2kal -rs2kan -rs2kie -rs2kis +rs2hor +r4shu +rs2il +rs2ka +rs2kel +rs2ki +r4skir rs2kl -r4sko -r4skr -r4sku -rs3l -rs4no +r4skor +r3s4kri +r4sky +rs4mog +r3s4no r3so r4sob -rson4e +rs4om r4s1op -r4sord +r4sorie r4s3ort. -rs2p4 -rs4pel +rso2s +rs1ost +rs2p +r3span +r3spe r2s3ph -r5spi +r3spi +r3spl +rs4por +r2sput rs3s2 +rst3abl +r3stad +rst3ala +r4stale +r4stans r4stant -r5statu -r6st5eing +r2stas +r7stati +r7statu +r3stä +rst5eing +r6st5eint +rst3emi rs4temp rster2 -rs4terb -rs4t3erw -rs2th +rs4t4erb +rst3erl +r3s4tern +rst3erw +rs2tev +rs2t1h rs2ti -r3stie -r5stim +r3s4tie r2stin rst3ing r3stink r2stip +r2stit r3sto rs4tob +rs4tol +rs4tor r4stot -r3stö -r3s4tr -rst3ran +rs4tr +r3stra r6strang -r4strun +rs5tren rs2tu +rs4tuc r3s4tü -r2sumf -r3swi +rsuch4s +r3suf +rs2ums r3sy +r1ß 4r1t -rt4abl -rtal2 -r2t1alm -rtals1 +r2tabo +rt1abs +rta2ck +r2t1a2d +r2t3ae +rt1akr +r4t3albe +rta3l2e +r2t1all +rtal4s3e rt1am -rt1ang +rt2ame rt1ann rt1ant +r2tanw r2t1ar -rt3a4re -r2t3att -rt1är +rt3att +r2taut +rt3äh +rt1änd +rt1ärm rte1e2 -rtei3la +r3teh rt1ein -rtei1s4 +rt4eind +r4t3einh +rte2i1s4 r2telf +rtels4t r2temo rte2n1 rte4na -rten3s2 +rten3s4 +r4t3ents +rten3z +rteo2 rt3erei -r4terfa -r4terfo +r6tereig +r4ter4fa +r4ter4fo rt1erh +rt1erk r4t3er4la rter6mit r4t3ernä +r2ter2ö rter4re rt1ers -rte3s2k -r2thi +rt4ersp +rt1erz +rte3sk +rt1he +r2thel +r2t1hi rt2hum r2t1id +rtik2 r2t1ima -r2tinf -rt4is -rto1p -rt1or -rto2ri -r3tö -r4t3rak +r4t3inf +rt2is +rt2it +rt3l +rt3m +r2t1ob +rto1pf +rt1orc +r4torg +r4trak +rt3rams +rt3rand +rt3rati rt3rec -r5tri -rt3ros +rtre1s +r4t3ris +rt3rol +rt3roma +r3trop +r2trou rtrü2c -r4ts +rt3sc rt4s1eh -rt2so -rt2spa +rts2el +rt3sex +rts3ing +rts1o +rts1pa +rt4s3tan +rts4tie +rt2su rt3t4 +rt1umb +rt2u3na r2t1urt +rtu4t +r2t3ute r3tü -rt3z -rtz2a +rty1 +rt3z2 1ru ru1a +ru4ale ru3a2r3 -rube2 -ruch3st +rube4 +ruben3 +rubens4 +rub2i +rucht3s4 ru6ckerl ru2cku rude2a ru2dr +ru2et 3ruf -ru2fa -ruf2s3 +ru2f1a +ruff4 +ruf2s ruf4ter +ru2g3r +3ruhm 2r1uhr -ru1ins +3ruin +ru3ins ru1is 2rum -4rumf +ruma2 +4r3umd +4r3umf +4r3umg ru2mi -4ruml -r2ums. +4r3uml +4r3umsa +4r3umw 4rumz 2r1una 2rund -run2d1a -r2unde -rund3er -run6derf -run6der6l -run6ders -run6derw -2r1unf +run4d1a +runden5e +run4d3er +run2e +runei2 +4r1unf +run2ga 2rungl -2r1u2ni -4r3unio +4r1u2ni +r3unio +ru4nis. run2kr -2r1unl +4r1unl 2r1unm 4runn +4runr +r1unse 4r3unt -2runw +4runw +2rupd ru3pr -4r3ur +4r1ur ru2ra ru2r1e 5ruro +r4us. ru2si +rus2p rus2s1p rus4st ru2st -ru3sta -3rut +ru2tab +rute4 ru4tei -rut3h -ru2t1o2 +ru4t1el +ru2t1er +ru4t1o2 ru2t3r +rut6scha 4ruz -ru2zw +ru2z1w 1rü 2rüb -rü1ben +4rübu rü1ch -rück5sta +rü4ckel +rü2hel +rüher2 +rüh1l 4rümm rün3z 2r1v +r3ve +rv2el rve4n1e +rvenen4 +r4ventz +rve3s +r3v2o 2r1w -r5wei +rwe4gel +r3wei +rwelt4s +r5werk +r5wert +r2wo. +r3woh +r3wort rwun3s 4r1x 1ry +2r1ya ry2c +rygi3 +ry1la +ry2le +ry1os +ry3sth rysti1 2r1z rz2an +rz3ant r2zar -r2zas -r3ze. -rz1eck +r2zat +rz2än r5zene rz1eng -r4z3ents +r4zents +rze2p +rze2ra +r2z1erd r2z1erf r2z1erg -r2z1erk +rz1erk +r2z1erl r2z1erw +r2z1ess rz1id +rz1int +rzir3 r3z2of -rz2ö +r2z3ot +rz2tan rz3te rz2th -rz2t3ro -rzug2u -r3zü -r3zwä +rzu4g3l +r2zwä r3z2wec +r2zwir 1sa 3sa. 3s2aa 2s1ab +sab2ä +4sabd sa2be 3sabet +sa2bit sa2bl -sa3ble +4sabm +sa2bor sa2br -4sabs +4s3abs +3sac +4sacc 5sache -sa2cho2 +sa2cho +sachs2 sach3t -5sack. +s2ack 2s1ada +sa2der s1adm 2s1a2dr 3safa -sa2fe -2s3aff -3safi +sa4fe +4s3aff sa1f4r +3s2aft +saf4tr 3saga -sa4gent +sag2e +5sage. +5sagen. +4s3agent +2s1agg +sa2gio sag4n -sa2gr +s1a2gr +s2ahs 3s2ai sa3i2k1 sail2 +sai4r 2s1ak sa2ka +sak2e 3saki -3sakr +4sakk +3sako 4sakt 3s2al. -4s1alar -sa4l3erb +3s2al2a +sa2l3an +sa2lar +sa3lat +3s2alb +sal3bl +3s2ald +sa4lerk +3sali sa2l1id -3salo +s1all +sal3la +sal4le. +3sal2o +sal3or sal2se -2s1alt -3s2alz +s1alt +s2al3t2h +3salz 3sam -s3ameri +4s1a2mat +4s1a2mei +s2amen +sa2min 5samm 6s1amma 4s1amn s1am3p4 -sam2to +4samph +sam4ta +sam4to +samt3st s1an s2an. 2s3a2na -s3anb +san4at +sa2nä +2s3anb s2an2c 3s2and s4and. -san4dar -san4dri +san4dan +san4d3ri +sand3s +sa2ner 3sang. +4sanga 2s3anh 3sani +3sanken 2s3anl +2sa2no +2s3anp 2s3ans +s4anse san4sk +san3sp +4santei 4s3antr -2s3anw +4s3anw +2sanz 2s1ap +sa2pe s2aph -sa2po +sap3p 3sapr +2s1aq 2s1ar -3sar. -3s2ara +3s4ar. +3sara 4s3arb 3s2ard -3sari -s3arr -3s2ars -4sarti -s1asp -4s3a2sy -3sat +s2are +s3area +3sarg +sar2ga +sa3rin +s2ark +sa2rom +s2ars +4sart +sa4r1u2 +3sas. +sas2a +s1asc +s1a4si +2s1a4sp +sas2tu +4sa2sy sat2a -4s3ath +satan4 +sa4t3ant +sat1ei +2s3a4tem +s3ath +3sat2i 4s3atl -4s1atm +4satm +sat2o +sa4tol sa2tr sa3ts +s3atta +4s3attr +3satz +5satza +sat4zel sat4z3en -s1a4u -3s4au. +s1au +3sau. 3sauc -3saue -sau8erste -2s3aufb +3sau2e +2sauf +4s3aufb +3saug +saug3le sau2gr 3saum 3saur sauri1 -2s3ausb -s3ausw -sa2vo +2saus +3saus. +4s3ausb +4s3ausf +4sausg +sau2sp +4sauss +3sauste +4s3ausw +2sauß +s1av +sa2ve +sa2xi +sa2y1 1sä -s3ähn +3säb +3s2äc +3s2äg +s1äh +4s3ähn 3säl 4s1ält 2s1äm -2s1änd +4s3änd +4s3äp +2säq 2s1är +3s2ärg 3s2ät 3säul -2säuß +4säuß 4s3b4 -sba4n -sbe3r2e +sba4ne +sbau6men +sber2e 1sc 2sc. +2scab +2scac +2scal 2scam -s2cap 2scar +2scat 2s1ce -6sch. -2schak -s4ch2al +4s3cei +4sch. +3s4chal +sch3ana 4schanc 4schang -2schao -s4chä +4schao +4schara +4sch3ar5m +s2chä +2schäq 4schb 4schc 2schd sch2e -3sche. +4schech +sche2f 6schef. +6schefi 6schefs -sch3ei. +s4chei +4sch3ei. +sch6ein. +s4chema 4schemp +sch5erfü +sch5erla 3sches 4schess 4schex 2schf 2schg 2schh +schi4d schi4e -s4chil 4schiru 3schis 2schk s4chl +sch4lac sch4lag 4schle. 6schlein +4schloc +4schlöc 4schmas +4schmed 2schmö 4schmüh +2schmy 2schn. +4schneb 4schobj -2schox -s4chö -2schp +4schorc +4schör +4schp 2schq +4schrad 4schre. 4schrin +4s3chris sch3rom 4schron 4schrou -6schs +4schs schs2e sch3s2k -sch3sta +schs4ti 4sch3t scht2a -scht4r +scht2i s4chu 4schunt -3schü 2schv -4schwaa +sch4web +4schweg +6schwerk 4schwet -sch4wil +4schwid +3schwu 2schz 2scj 4s3cl -2sco -3s4cop -3sco4r -s2cr +2s3co +4scoa +3s4co2p +scre4m 2scs 2scu +2scy 4s3d2 sda3me -sde1s +sde1s2 sdien4e -sd4r +sdi1st 1se +3se. se3at. +seb2 +3sebä 2s1e2ben -seb4r 2s1echo -s1echt +sech4st +2s1echt 2s1e2ck se2dik 3see -se1ec -se2e1i4 +see1i2 see3ig -seein2 -se1er. +se2el +see3len +se3en. +see3n2e +se3enp +se3er. +see1ra +seer2e +se1erf +se3e2r1i se1erk -se1erö -2s1eff +se1ers +see3s4 +2s3eff sef4l -se2gal +3s2eg +4s3e2gal se2gl seg4r 3seh seh1a -se2ha4g -se2han -se3he -se4h1ei -se4hel +se2hag +se2hak +se2hel +seher4e se4herk -se2hin -seh1l +se2h1in +seh3l +se4h3ö +seh3ra seh3re +seh5r2i seh1s -seh3t se2hüb -2s1ei. -2s1eie +2sei. +2s1eic +2s1eid. +sei3da +4s3eifer 2s1eig -sei3le +3seil +s2eim s1ein 5s4ein. 2seinb sein4du -sei3n2e +2sei3n2e +seine3i +4seinfl sein4fo -4seing -2seinh -4seink +2seing +2s3einh +2seini +2seink 2seinl 2seinn -4seinr +sein4ne +2s3einr s4eins. -4seinsa +4seinsc 4seinsp -4seinst +sein8stit +sein6str +2seint +sein4to +4seintr 2seinw -4s1eis +2s3einz +2s1eis +3s2eism 3s2eit +seit2s 3sek -4s1e2ke +4s1e2kel +4sekz s2el. se2l1a -se3lad -sela4g -se3lam +3s2elb +sel3d4 sel1ec -4selem -se4lerl +se2lef +2s3e2leg +6selektr +2selem +se2ler sel3ers 2self. -s1elix -se2l3ö +selin4s +s3e2lit +2s1elix +s2ell +se2lob s2els sel3sz -sel3tr -s4e3ma -2s1emp -3s2en. -se4nag +selt2e +selz2 +sem2e +2s1e2mis +2s3emp +s4en. +3sena +se4nad +se3nal +se4nas +sen3au se2nä -2s1endl -3seni -3senk +s2enb +4s1endl +sen3d4r +s1endw +senen1 +4senerg +se4ners +s2enf +3s4eni +se2nid +se2n1im +3s2enk +sen6keli se2no -3s2ens -s2ent. -sen3ta +se4nott +se4noz +3sens +s2ensa +sen4s3e4h +4sensem +s4ensi +sen4si4d +senst2 +sen8s7turm +sent2a +sen3tä +2sentd 4sentf -2s3entg -s2enti -2s1ents +2sentg +4sentla +2sentn +s2ento +sen3tr +4s1ents 2sentw -2sentz -se2n3u +4sentwu +4sentwü +4sentz +se4n3u2 +sen3za +sen4zer +sen3zw seo2r -4s1e2pos +se2pen 3seq -3s4er. -3sera -ser3a2d -se2r3al -s3ereig +s4er. +se2r3a2d +ser3al +se3rand +ser3äus +serb2 +s3erbe. +serd2 +se2r1e2b +se3reie 6sereign se4r3eim +se4rein +sere2m +5s4eren se4r3enk -ser2er -2s1erfo +s4erfe +s1erfo s2erfr s3erfü -4ser4fül -s4ergr +4serfül +serg2 +ser3ga +ser3gl +s2ergr s1erh 2serhö 3seri +5serie serk4 -4s3erken +4s3ermit s2ern. +s3erneu 2s3ernt -se1rot -4s3eröf -ser3r +sero4b +2s1e2ros +s1erot +s1erö +2seröf s2ers. 2sersa 4serseh -s4ert. -s2erta -seru2 -se4r1uf -se3rum -se3rund -3s4erv -5ses. +ser6sehn +4ser4set +se3ru +se4ruh +ser2um +s3e4rup +5s4er3v +s1erz +3s4es. +se3s4a se2sel se3sk +2s1essa se1sta +se3stec +se3stei +se5stemp +sest3ri se3su -3set -4se4tap +4s3e4tap se2tat -4s1e2th +2s1e2th +set2i +4s1e2tik +3setz +3seuc +2s1eul +seum4 se1u2n -2s1ex +s1ex +3sex. +2sexa se2xe +sex3en +s2exi +s2exo 4sexp -sex3t2 +sex3t4r +2sexz 1sé 4s3f4 sfal6l5er -sflo4 -4s3g2 +4s3g4 +sgang4 +sge3sa +sge5t 2s1h 4sh. sh2a -3s2ha. -sha2k -4s3han -1shas +3sha. +shal4li +shalt2 +shalt4s +4shan s3hä -s3h2e +sh2e +sh2i 3shi. -3shid -4shil +s2hip shi4r sh3n -s3hoc -4shof +4s3hoc +4s3hof +4shom 3shop sho4re -3show -s3hö -sh4r +3s4how +4s3hö +sh4r2 4shs +s3hu 1si +3si. si3ach. -si2ad -si3am. 2siat -sib4 -5si1c +5s4i1c +si2cha +2s1idea +2sidee 2s1ideo -s2ido +si3der +s2i3do +2sidy 3s4ie +sie2bu siege4s -sieh1e -sie4hes sien3 si3ene si1err -sie2s si1f4 3s4ig si2g1a2 +si2g1ei sig4n -si3gnu si2g3r sig4st si2k1ab si2kak +si2kar si2k1ä +si2k1el +si4kens sik3erl -si2ki -si4k1l -si2kr +si2k3i +sikin1 +si2k3n +si2k3r sik3s -sik3t4 +sik3t2 si2ku +3silb sil2br +sil2e +3sili +s1ill 3silo 2s1imm +sim4st +3simu si3n4a 2s1ind 2s1inf +4s3infe +s3infor sing1a -sin3gl -sing4le -sin4gr +sin3g4le +sin2g3r +sings2 sing3sa -4s1inh -sin1i +sing3so +2s1inh +s1in1i sini1e -2s1inq +s2ink +sinner4 +2s1inno +4s1inq 2s1ins -s2ins. +4sinso +4sinst 2s1int 4s1inv -3sio sion4 +sirn4 +2sirr 3siru -3sis si2sa +si4sam +s2isc si4schu -si2s1e -si2s1o -si2s1p -sis3s +si2s1e2 +si2si +s1i2so +sis1or +si2s3p +sis3s4 +3s4ist +si2su 3s2it +si2tal si2tau -sit3r si2tra -si3tu -siv1a +sit2u +si2va sive3 -si2vr +siver2 +si4v3erf +si2vin +siv1o4 +si2vor +siz2 1sí -2s1j +4s3j 2s1k2 4sk. -3skala -4skam -4skanz -s3kar -4skas -skas4tr +sk4a +4s3kab +s3kad +4skalk +s3kalt +4s3kam +4skana +4skanä +3skanda +4skann +4skap +4s3kar +4s3kas ska4te. 4skateg ska4tes -4skä +ska4to +4skau +4s3kä 4skb -s4kep +ske2li +4sken +3skep +4sker +4s3ket +s3kh 3s2ki. -s2kif -s2kig +3s2kif 3s2kik -4skir +s3kim +s3kin ski1s +s2kis. 3skiz sk4l 4s3klas 3s2klav +4s3klu 4sk4n +4skoh +4skol 4skom -4skor +4s3kon +3skop. +sko2pr +4skos 4skow -4skö -s3kro +4s3kö +sk4r +4s3kra +s3kre +4s3kro 4sks -4sk3t +4sk3t2 +skto2 3skulp +4skun +sku2s1 +4skü +4skv 2s1l2 +sl4a +s3lab 3slal -4slan +sla2ma sla2ve s2law s3lä sl3b -s3le +4s3le sler3s s3li 3s4lip -sli4tu -s3lo. slo3be -s3loe -2s3m2 +s3loc +s4loga +3s2low +s3ly +4s3m4 +sma3b4 +sma3sc +sme3na +smi2t3 2s3n2 -4s5na snab4 +sni4a sni3er. sni3ers 4s5not -4snö 1so 3so. -so4a +2s3oas 2s1o2b +3s2o3ba +4sobj +4s3obo so1c +so2di +so2do so3et +2s1o2fe +2soffi 3soft 3sog +sog4l s1o2he -4sohng +3sohl +sohle2 +2s3ohng 2s1ohr -3sol +3soi2 +so3id +2s3ok +3sol. so3la +so4lau +3sold +3sole so2l1ei +so3li +sol2la sol4ler -4so2ly -3som +so3l2o +4s3o2ly +3somm 3s2on +son2a son3au sone2 -son3end +son4gl son3sä son2s1o so3o -2sopf +2sope +2s1opf +3sopr sop3s -3sor. -s1orc -2s3ord +4s3ord +sore2 so2rei -so3ren -2s1orga -5s2orge +so2rel +4s1orga +so1rh 2s1o2rie so2ro -3sors +3sorp +3s2orti so4ru 3sos -s4os. -4s1ost -3soß +s2os. +4so4sk +4sosm +4so1st +4s1osz +3so3ß +2sot +so3t2h +3sott +soun2 +sound1 +so3unds so3unt +2s1out 3sov -4s1o2ve 3sow -2s1ox +2s1o2x 3soz +s1oze 1sö sö2c -sö2f +2s1ö2d +2sö2f 2s1ök -s1ö2l -s1ös +2s1öl +2s1ös 1sp2 2sp. 4spaa -4spak +s2pace +2spack +2spag +2spak 2spala -spani7er. -4spap +2spalä +3spalt +spa2m +s2pan. +3spannu +s2pans +3spant +2spanz +2spap 2s3para -4sparo +2sparo 5s6parten -3sparu +4spartn +4sparty 3spaß +3spat. +2spati 4spatr -4spau -s2paz +2spau +3s2paz s2pä +2späd 3späh 2spär +2späs 2s3pe. -s3pel +2speg +4spein 4spensi spe3p4 s2pera +3s2perg s1peri +4sperle 2spero s2perr 2spers +2sperü 4spet -3s2pez -4s3pf +3s4pez +4s3pf4 2spha -s4phä +s2phä +3sphär s3phe +s4phin 3s2pi4e -4spier4 +4spier +spier4r spi2k -4spil +4s3pil 3spio -4spip -4spis -2spl +4s3pip +4s3pis +2sp4l 4spla -4splä +4s3plä 4sple +sp5le. 3s2pli -s3p4lu -s3pn +4s3plu +2s3pn 2spod +4spoe 2spog s2poi -4spok +4s3pok 4spol +s2pons +4spoo +2spop +s2pore +3s2porn +spor6tag 4s3pos -s2pott +4spote 4spr. -s2prac -s2pran -4sprax +3s2prac +2sprak +2sprax 2spräm 4spräs 3s4prec 4spred -s2pren -2spres +4spreis +5s2pren +2s3pres s2pric +3spring +4sprinz 2sprob -2sprop +2sprog +4sproj +4sprop 3spross -3spru -4sprüf -2s3ps -2s4pt +2sprot +2sproz +3sprö +3s2pru +3sprüc +2sprüf +3sprün +4s3ps +2s4p3t +2spub +2spud 3spuk +3s2pule 2spun 2spup -3spur -4sput -4spy +3s4pur +spu4rer +2spy 2s1q 4s3r4 srat2s -srat4sc -sret3 -srö2s1 +sre3cha +sreli1 +sro2h +srö2s srücker6 6s1s +ss3abi ssa3bo -s5saf -s3sag +s5sack +ss4agi ss1aj s3sal -s4s1alb -s4s3amt -s4s3ang -s2sano +ss3alba +s4sall +s4samt +s2sanf +s4sang +s4sano s4sans ss2ant -s4s3anz -s3sa1s2 -ss3att +s4sanz +ss2ara +ss2arg +s3sars +ssa1s +s2s3att +ssau3e +ssau4r s3s2ä s4sce ssch2 +sschanker8 +s3schw s4sco +s2scr +sse3a ss1ec -s2s1ega -sse3inf -sse3in4t -sse6r5att -ss1erö +sse1ec +sseh2a +s2sein +ss4eind +sse3int +sse2lö +s3sen +ssen6kel +ssen6sem +ss1epe +sse6ratt +ss5ereig +ss4ergr +sser4hö +sser6mit +sser4öf ss3erse -s3s2es +ss4eru +sser6wei +sses4sa +s4s3estr +s3set sse3ta +s3si +ss3i2ko +s4sill +s4simp +s4sind +s4sinf +ssing3s +s4sint +s4s1isr +s3skala ss3l +ssmut4 ss1off ssoi4 -s2s1op -ss1ori -s2söl -s3spe -ss2po +s3sol +s4sop +ss2pen +ss2phi +s3spi +s3sprä +s3spri s2spro ssquet4 ss3s4 +sssau4 sst2a +s3stad +s4stag +ss3tak +s3stä +sst2e s3stel -ss2th -ss2ti -ss4tip -s3s4tras +s3s2tep +s3s4tern +ss4teu +sst2i +ss2tie +ss2t3in +s3stof +s3stop +ss4tör +s3stran +ss4tras +s3s4trat s3strec +s3strom +s3strö ss2tur s3stü -ss1ums +s2sumg +s2sumr +ss2ur +s3sy s1t 4st. s2ta -4sta. +2sta. 3staa +3stab. 2stabb -s4t2ac -sta2ck -3s4tad -3staff +4stabel +4stabit +2stabl +4stabt +st2ac +1stadt +1staff 2stag -3stah +3stagl +3s4tagr +3s4tah 2stak -2stale -s3ta3li +3staks +2stala +sta3lak +2stalb +s3ta3l2i 2stalk -st1alm st1alp -st1a2mi -4stan. -sta4na -3stand -2stani -4s3tann -2stans +st1alr +st1ami +1stamm +1stan +2stanb +s6tand +2stanf +st2ang +2stanl +s4tanm +4st1ann +s4tano +st3ansp 2stanw +sta3po1 +stapos4 +st1app s4tar. +sta6rens 4stari -s4tars -st1asi -2s3tat. +s4tark +s4t2ars +s4tart +sta4sie +stast4 +s3tat. +2statb +3stati +s4tatis +7statth s4tau. 2stauf -2staum -3staur -2staus -2stax -3s2tä +3s4taur +4stausb +4stausg +4stausr +4stauss +s4taut +s4t1a2ve +4stax +1s2tä +3stäb +3städ 4stäg -4stält -s4tänd -5stätt -s3täus +4stäp +5s4tär +3stätt +2s3täus 2stb 2st3c 2std 4s5te. +4steam 4stechn -s2ted -4stee +s2te2d +st1edi +2stee 3s2teg -ste2gr -3s4teh -s2te4i +ste2g3r +1steh +s2tei +st4ei. +4steic st1eid 3steig -4steil -3steilh -steil4z +stei4gr +2steil stei4na -1s2t2el +6steinga +s4teins +stein6sp +s2tel 2stel. -stel4l3ä +st1elb +s3tele +s3telf +st2ell +stel6l5än 2steln 2stels 2stem -4stem. ste4mar -4sten +ste6ment +3stemm +2sten s5ten. ste4na s4t3ends -st2ens +s5t2ens s4tentf -s2tep +s4tents +st1e2po 2ster -6s5ter. -st5erbie -ste4rec -ste6rers +4s5ter. +ste2r3a +s6terben +3sterbo +s3teren +3stereo st3erfü -st5ergeb +3steril 4sterm -3sternc -4stes -ste2se -stes6se. -ste4st +3s4ternb +ster4zo +4ste2s1 +ste3sc +stes4se +s4testn 2stet -s4teti +ste4tab +ste4tag +3s2teti 3s4tett 3s2teu 1steue 4steuf -st3ev +st3eun +st1ev +s2tew 4stex +s2texa 2stf 2stg -4sth -s4thä -s3them -s4thi -s2t3ho +2sth +st2hen +s2t1hi +st3ho s2thu +st1hy 2stia 2stib -3stic +s2tic +1stich +st1i2d 2stie. -s2tieg -s2tiel +4stief. +4stiefl 2stien -3s2tif +1s2tif 2stig -2stik -s2til -3s4tim -s4tinf +sti4gel +3s4tigm +2s3tik +s2t2il +1s2tim +3stimm +4stimma +2stimp +st1inb +2s4tinf s3tinn -st1ins +s2tins +2s2tint 2stio -1s2ti2r -2stis -st1i4so +2stip. +2stipp +s2ti2r +st1ira +st1iri +st1iro +4stis +2stite 1stitu 2stiv 2stj 2stk 4stl -4stm +st3le +2stm 2stn s2to 2sto. -s3tob -2sto3d +sto2bl +4stocht +2stod 4stod. 1stof s4toff -s4t3om -4ston +2stok +4stole +s4toll +sto3mi +2s3ton +4stona +3s4to4ne +4stonl 4stoo -s4tope 2stopo -2stor. +4stor. +s4torb 2store -2storg +2storf +2s4torg 2stori +2storp 2stors -s3tort -2stose -sto3s2t +2stort +stos2t 1stoß 4stote +2stotr 4stou 2stow 2stoz -1stö -2stöch +1s2tö +4stöch 2s3töl +2stön +3stör 2stöt 2stp 2stq s2tr -2strad -2s3trag -1strah +2strac +4s3trad +st4rade +stra4fa +4s3trag +3strah 4strahi 4strai 4strak -2stral +2s5tral +s3trank 4strans -5straß -4s3traum +1strap +3stras +3straß +4straum +4sträc 4s5träg 4sträne -4s5tref -4s5treib -5st4reif -st3renn +2stre. +s4trea +4stref +4streib +3st6reif +2strep +2stret +4streuh 2strib +strie3s4 2s4trig -1s4tri2k +1s4trik 2s5tris -st3roll -stro4ma +1stro +s3troc +s3trog +3s4troh +s4trome +4stropf +2stros +st4ross 2ströp 1stru 2strua -2strug +2strub +s4trud 3struk -2st3run -2strup -2s4t3s2 -sts4k +2strun +4strup +2strut +1strü +4s4t3s2 +stsi4d +sts4t 2st3t4 st2u -5stub -4stuc +1stub +4stuch 3s4tud 2stue 3stuf -5stuh +2stug +st3uga +3stuh +s2t3uk +2stumo 2stum2s stum4sc 2stumt -stu2n 2stun. -3s4tund +st3una +5stund +2stune +2stung s2t3uni 4stunn -2s3tuns +2stuns 2stunt -stu3re -st3url -2sturn +2stuö +stu3ra +stu5re +2st3url +4sturn 2st3urt -2s3tus +3s2turz +2stus +1s2tut 1stüc -2stüch -2stür. -3stüt +4stüch +3s4tück +3stüh +4stür. +4stüre +3stürz +1stüt +2stütc 2stv 2stw -3s2tyl -4st3z +stwor2 +2sty +4sty. +1s2tyl +4styp +4stys +2st3z2 1su su1an 3su2b3 -su4ba2 +su4ba 4subi +su4br 3su1c su2cha -such4st +su2cho +3sud +su2eb 2s1u2f +su3fi 2s1uh su1is su1it. -sul2a -sul2i -sult2 +su2k +su3l2i +3sulta +sum1a +su2man su2mar -su2mau 3s2ume +su2mei su2mel -su6m5ents -s3umfe -3summ +sument4 +su6ments +su2m1et +2s3umf +su2m1id +su2min +3s2umm sum1o2 su2mor s2ump +s1ums s3umsa -s3umst +2sumse +s2umsp +2s3umst +2s3umwa su2n 3sun. +2s1una sunder4 sun6d5erh su4ne -s1unf -2s1uni -4sunt -3s2up +2s1unf +6sungena +2sungl +sung4s +4s1uni +2s1unm +2s1uns +s4uns. +s4unst +2sunt +2sunw +s4unwa +3sup +4supd sup3p4 su2ra -2s1url +sure4 +su2rei +su2rer +3surf +2s1urk +su2r1o +2surs s1urt -s4us1 -su2sp -sus3s +su2s +su3s2a +sus1e +sus3i +s3u2t +su4te +su3tr 3suv +suz2 1sü -2sü2b +2sü4b 3süc sü2d1 -süden2 +süden4 +3süf 3sün 3s2üs 3süß -4s3v +4s3v2 +svoran4 2s1w -s3wa -s3we +4s3we +swe6gers sweh2 4swie 4swil +4swink +4swis +4swit +s3wü 1s4y -syl1 +2syl1 +sy2lo +sy2lu sym3 sy2n3 -sy4na -sy4nä +3synd +sy4no +3sy4s3 2s1z2 4s3za 4szä 4s3zei -s2zena -3s4zene -4s3zent +4szel +3s2zena +3s2ze3n2e +4szent +4szer s2zes -4s3zet -s2zis +4szet +4szeu +3s2zew +4s3zie +4s3zo +s3zs 4s3zu -s3zü -4s3zw -2ß1a2 -2ß1b2 +4s3zü +4szw +2ß3a4 +2ß1ä +2ß1b4 2ß1c -2ß1d +2ß1d2 1ße +2ß1e2b 2ß1ec +2ß1ef 2ß1e2g 2ß1ei -ße2l1a +2ß1ek +ße2la +ße2le +2ßelek +2ß1emp +ße4n3a2 +4ßenerg ße2ni +ß1enke ße2no +3ß2ente 2ßentz -ß2ers. -2ßerse +2ß1e2p +ßer3b +ßer2ei +ßer2la +2ß1er4se ßer3t -2ß1f +ß1erw +2ß1es2s +2ß1est3r +2ß1ex +2ß1f4 2ß3g2 ßge2bl 2ß1h 1ßi ßi2g1a2 ßig4s +2ß3i2k +2ß1il +2ß1im 2ß1in -ß1j -2ß1k4 +2ß1j +2ß3k4 2ß1l -ßler3 +ßler3s 2ß1m -2ß1n2 -ß1o2 +ßmut4 +2ß3n2 +2ß3o2 ßos2 +2ß1ö2 2ß1p2 +ß1q 2ß3r2 +ßrö2 2ß3s4 +ßsau4 ßsch2 ßst2 2ß1t -1ßu +ßt1in +ß3tü 2ß1um -2ß1ü +ß1unf +2ßunt +2ß1ü4 2ß1v 2ß1w -2ß1z +2ß3z2 1ta 3ta. 4taa 5taan -2tab. -ta2b1an +4tab. +3taba +ta2b3an 2t1abb +4tabd 3tabel 2taben -ta4bend 2tabf 2tabg 2tabh +2t3a2bit 2tabk -3t6able +2tabla +4tabm 2t3abn -ta2br +2ta4br 4tabs +t1abst 2t3abt -ta2bü -2tabw -2tabz +3tabu +4tabw +4tabz 2t1ac +4tachs 3tacu t1ada +2tadd +ta2der tadi3 +tadi5o4 +t1adm +ta2dol 2t1a2dr ta3d2s +4tadt +tad4tr +ta2er 3taf. -3taf2e +3tafe +4tafet 4taff t1afg -t1af4r -3t2ag +t1afr +3tag ta2ga -ta2g1ei -4t3a4gent +ta2g1e2i +t3agent +tage2s +4t1agg 4ta3gl -t3ago +4t1a2go +tag4san +tags3c tag4st tah2 -tah3le -tahl3sk -t2ai +tahls4t ta3i2k -tai2l +tai2l1 ta1ins tai4r ta1ir. -t1a2ka +ta1i2s +2t1a2ka +ta3kes +2t1akk ta2kro -tak6ta -3taktb -3takts -3t2aktu +tak4t1o2 +t2aktu 2takz 3t2al. ta2la +ta3lad ta3lag -ta3lak tal3au -t1alb. -t1albk -tal3d -3t4ale +3talbr +tald4 +3tale tal2en -ta4lens +ta4l3end +tal3eng +ta4l3ens +taler2 +ta4ler3g +ta2let tal2ga +tali6ene +tal4l3ac +tall3ei tal2l1ö4 +tall3s2 +2t1alm. 3talo -ta2l1op -2talt +ta2lop +ta2l1o2r +t1alta +tal3th +talt4r +ta2lu 2tam +3tam. 3tame -ta2mer +t2amen +t1a2mer +ta2mi +tamm1a +tam4m3er t1ampl -t1amt -3tan. +3tams +4t1amt t1a2na +tan3ab +4tanal +ta4nat +2t1a2nä 2tanb -4t2and -tand4ar -ta3ne +3tanc +tan3d4ar +tan2d3r +tand4st +ta4nerf 4tanf -2tang -3tani -t2ank -t3ankl -4tanl +2t1ang +3tang. +t3angeh +t2ango +tan4gra +2tanh +t2anho +t4ani +3tanj +3tank +tan2kl +4tankr +4t3anl t1anm -2tanme -4t1anna -t2ano +2t1anna +3t2anne +t1ano +2tanom +2tanp t1ans -3t2ans. -4t3ansi -4t3ansp +t2ans. +4tansi +tan4tan +t4ante. +4tantei +2tantr 2tanwa 2tanwä t2anz. t1anza -tan6zerh -t1anzu +4tanzei +3tanzk +3tanzr +2t1anzu +2tanzü tan2z1w +tao2 ta3or -ta2pe. +t4ape ta2pes 2tapf ta2pl -2tappa +ta4poka t2appe +ta2ra +2tarab +3tarabb +ta3rak +3tar5al +2taram +tar3ap +ta3ras +t2arau 2tarb -ta4ren4s -ta4r3ere -5t4a3ri +3tarba +3tarbek +3tarber +3tarbi +3tar3bl +2tarc +3tarchl +3tarchr +3t2ard +ta2rel +ta2r1er +tar3g +ta1r2h +3tari 2tark +3tark4l +3t2arko +t2arl 2t1arm +t2armä +ta2rom +2tarot 2tart +3t2arta +3tartei +tar6ter6e +3tartex +3t2arth t1arti -tar2to +3t4artis +tar4to +tar2tr +3tarty ta2ru -2t1arz -3tas. -ta3sa +t1arz +2tarzt +3t2as. +ta3s2a 3tasc -t1asp +4t1asp +2t3assi 3tast +tas4tem +tas4to +t2asy +t4at. ta2ta2b ta2tan -ta2tau +3tatb +t4ate tat1ei +t5a2tel ta2tem +3taten ta2t1er -ta2th -tat3he -t3atl -t4atm -ta2tom -4tatue -ta2t1um +2t3atl +2tatom +2ta2tr +3tatsa +2tatt +tau2b1a +3taubh +tau2bl +tau2b3r +tauchs4 +tauch5sp 4taud 2t1auf -4taufg +3taufe. +4taufk +4t3aufl tau3f4li -4taufn +4taufm +t3au2f1o +4taufp +taufs2 +4taufw +3taug +4t3auge t1auk -3taum -t1ausb +3taume +4t1ausb 3tausc +tau6scha +tau6schm tau6schr tau6schw -t2ause +2tausd +t2aus2e +4t1ausf 4t3ausg t1ausk 4tausl +2tausr 4t3auss -4t1ausw +2tausü +2t5ausw +4t3ausz +4tauu 3tav +4tava +ta2van 3tax -ta3xi -taxi3s +4t1axt +3taz 1tä -3täa +2tää 4täb tä1c 4täd -3täe +t2äf 3täg +4tägä 4tägy 2täh +4täll 2t1ält -4täm +4tä2m t1ämt t1ängs 3tänz -t1äp -t2är. +4t1äp +2täq +tä4reng tä2ru +2tärz tä2s t2ät +3tätigk 4tätt 2täug 2täuß 2täx 1tà -4t3b2 +4t3b4 tbauer4 -tbe3r2e -tblock5e +tber2e tblocken8 +tby4t 4t1c t3cha t3che tch2i tch3l +t3chr t2ch1u tch1w t4ck t3cl +tcor2 t3cr -4t3d4 +4t3d2 +tdar2m1 tdun2 1te 3te. te2a2 +te3ab +tea3c +te3ag 2teak te3al +3team te3an +te3ar +tea4s 3teba -3t4ebb -4t1e2ben +t4ebb +2t1e2ben t2ech -te3cha +2techd 2teche +2techk +2techm 3techn 2techt te2chu 2teck -te2cka -teck2e +te3cker te2cki -te2de +2t1ecu +te2dit te1em -te2en3 +teen1 +te2er. te1erw te2es +3tefa 2teff 2t1egg -teg3re 2teh 3teha +te2hac 3tehä +3tehi +te2him +3tehö +t1ehr +te3hu 3tei. +3teic +tei1fl 2teign teik4 -3teil -4teilhe +3t2eil +tei6lent +teim2 2tein -tein3e4c -t3einge -t3einla -4teinn -t1eis. +teinen4 +tei6nens +tein6hab +t3einkü +2t1eis. t1eisb +te5isch. +teit4 +t1eiw +tei3z te2kel -tekt2 +3teko +tekt4 3tel. -3tela -te2l3ab -te2l1ac -te2l1au +3te2la +tel3ab +tel1ac +te3lan +te4lant +tel1au +te2lä telb4 -tel3d4 -3te3le -tel1eb -tele4be -te4l1ec -te4l1eh -te4lein +3telbr +3tel3d4 +tel1ec +tel3ehr 2telem -te4lerd -te4leu +tel3eng +te2ler +tele3s +te2leu 4t3elf. 3telg -te2l1in +3telh +tel1in te2lit 3telk -tell2e +tel3le tel6lein +tel3li 4tellu 3teln +te2lob +te3lom te4lost te2l1ö 3telp @@ -12909,1132 +20793,1844 @@ te2l1ö tel3s2k 3telt4 tel3ta -tel3th +3telw 3tem. +3t2ema +te2man +te2m1ap +te2mau +2tem2bo te2m1ei -te2min -2temme -te2m1o2r +te2m1er +te2mi +tem3i2m +tem3ing +2temm +te2mo +tem1o2r 3temper 2tempf -tem3s -te4m1u +4tempfi +tem3s6 +te2mu +te4mun 3ten t6en. -tena2b -te4n3a2d -te4n3a4g +ten1a2 +te4nad +te4n3an +ten3ar te4nas -te4n3au -te2nä -ten3äh -t4enb +te4nat +ten3au +te2n3ä ten3da -4t3endf -t6endi +4t3endal +tend4an +4tendap +4t5endf 4t1endl t6endo -4t3endp +4t5endp ten3d4r te2n1e2b te2nef +te2neh ten3ei te3n4ei. -4tenerg -te2net +tenei4d +tene4m +tenen1 +te4n3end +te4nene +te4neng +te4nens +4t3energ +te4n3ern +tenf4 4t1eng. +teng2a ten4gag 4t3engla -t4enh te2ni +te4nil +ten1im te4n3in -t4enj -t4enm -ten3n -tens2e -4tensem +tenk4 +ten3n2 +te2nol +te2nos +te3nö +6t3ensem +tens2p tens3th -t4enta t1entb 4tentd -t4ente -4tentn -tent3ri -4t3entw +4t3entl +4t3entn +t1ents +4t5entw 4tentz -ten6zerh -ten3zw -t1e2pi -3t6er. +t2enz +ten4z3er +teo2f +2tep. +2t1e2pi +2teppu +tept2 +3t4er. +t4era ter3a2c -te1raf -ter3am -te3ran. -te3rand -ter3a4s -4terbs -4terbt +te2rad +te1ral +ter3alg +te3r4ane +te2r3ap +tera4s +4terbos +2t1erbs +2t1erbt 3terc 4t3erde. -te2re2b -te4r3eif -te2rel -ter3end +ter3d2s +3tere. +te2r1e2b +te2rec +t3ereig +te5rek +3tere2m +te4rema +te4r3end +te4rene te4reng -te4rerk -terer4z -4t3erfol +te4r3ent +teren5th +2tereo +3terer +terer3k +terer6ku +terer3l +te4r3erp +te4rers +te4rerw +3teres t4erfr -4terfül -3terg2 +terg2 ter3ga -6ter6grei +6tergebn +t6ergem +t6erges +t6ergew +ter3gl +6tergrei t4ergru -t4eri +t6erhall +t6erhau +t4erhäu +t4erhei +7t2erhi +t2erho +6terhöhu +t2erhu te3ria -te2rid -ter3k -5terkla +4terii +ter3iko +2teril +teri4o +te2r3it +teri4ta 4terklä -2t3erlö -ter4mer -3termi -ter4n3ar -2ternc -t3erneu +t4erlä +t4erli +ter4lös +3term +t2ern. +ter4nar +2t6ernc t4ero -t1erö +te1rob +ter4obe +2teros +t1e2r1ö +t4erp +t4erra ter4re. +t4erro t4ers. -ter3sc -ter4ser -terst4 +t2erse t4erst. -5t4ersti -5t4erstu +t6erstad +ter6stat +t4erstä +t4ersti +t4erstr +t4erstu +t4erstü tert2 -teru2 +ter3ta +ter4trä +t4eru2 te4r1uf -ter3za +te3rung +t4erv +4t3erwäh +ter3z2a 2t1erzb -3t2erzu +t4erzei +4terzeu +ter3zw 3tes -tesa2c -te2san -4t1e2sel -te2sep -tes1er +t2es. +tesa2k +tes2c +tes2ka +tes4pen te2spr -tes3si -t2est +2t1essa tes3tan -test3ei +te3stei +tes4tel tester4 tes6terg +tes6t5erh tes6terk -testes4 +2testn +testo3 +t3est3ri te2su -3tet2 -t2et. -te2tat -4teth +tet2 +3tet. +t1eta +te4tabl +2te2tap +2te2tat +3tete +teten3 +2t1e2th +te3tho 4tetl -teu3ere -teu3eri +tet3ti 3teuf 3teum -te1un +3te1u2n +4teunu +2t1eup 3teur. -teu2r3a -5teus +te2va te2vi -te1xa +tewa2s +3tewo +2texam 2t1e2xe 2t1e2xi 4texp -3text +tex4ta 2t1exz -4t1f4 -tfi2l +tè2 +4t3f6 4t1g2 -tger2 -t1h +tga4s3er +tga2su +t3ge +tge4nen3 +tger2a +tger2i +tg4r 4th. -2th4a -3t4ha. -t2hag -t3hai -t2hak +2t1h2a +3tha. +3t2hag +4thak 3thal. +3thalh +t4hali +t2hals +t2han. +t3hand +t3hap 4t3hau -2t3hä +2t1hä +3thäi +4thäl +2thb th2e -1t2he. -3thea -2theb -t2hec -2t3hei -t4hein +1the. +3t4hea +2t1heb +2t1hef +2t1hei +the1in +4theit t2hek -t2hem +3thema +2themd +2themm 1then -t4hene -t4heni +t1henn 3theo -t2hes -3these +t1herd +thero1 +t1herr +2t1herz +4t1hess t2heu -1thi -thi3er -t2hik -2t3hil -2t3him -t3hir +2thf +1th2i +3thi. +thic3k4 +thi3er. +2t1hil +2t1him +2t1hin +thi3nu +2t1hir 2thk -4th3l +2th3l 4th3m -2th3n -1t2ho -t4ho. -2t3hoc -t3hof -2t3hoh -t4hol. -t4holo -t3hor -2t3hot -thou2 -2thov -4t3hö +thmu2 +2th3n2 +1tho +2t1hob +tho3chr +t1hof +2t1hoh +t1holt +2tholz +t2hon +4thops +tho1s +t1hose +t1hot +4thote +2thou +t1hov +4thö 2thp 1th2r2 2ths +2tht2 +t1hu 2thub -4thun -2thü +2thuh +4t3hun +2thut +2t1hü 2thv -t2hy 1ti -ti2ad -ti3a2m -3tib4 -2tic +t4ia +ti3ac +ti1ag +tial2l +ti3alo +ti1a2m +3tib +3ticc ti1ce -tiden2 -ti4dend +3ticket +t2id. +2tidee +ti4d3en4d +ti3dy 3tief. +4tiefel +3tiefl tie2fr -tieg4 +2tieg4 2tieh +ti2e1i ti1el ti2el. tiel3a -ti3e4n3 +ti3e4n1 +tien3s 3tier -tie4rec +tie4rei +tie4reu ti2ern -ti1et +tie3s2t +2tieß ti1eu 3tif. -ti1fr -4tift -3t4ig +ti3fe +ti1f4r +tifter6k +3tig ti4gerz -3tik +ti2git +tigs4tr +tih2 +3tij ti2kam ti2kar +tiken2 +ti4kent +ti3k4ere +ti3kerl ti2kin +ti4klu +ti2kn +ti2kop +tik1r ti2kra ti2krä -ti2kü +ti4krei +tik5t ti2lar -ti2lau +til3d ti2lei ti2lel 3tilg -ti2l3ö -til3s +2tillu +ti2lö tilt4 ti2lu ti2ma2g -t2imi -tim2m1a -4t1imp -3t2in. -ti3na -t1inb -4t1ind -ti3n2e -t1inf -tin2g1a +tim4man +t3immat +timmer4 +tim6merg +3timo +2timp +tim2s +3tin. +t4ina +ti3naf +ti3nak +ti2n3an +t1ind +ti5n2e +tine1i +2t1inf +3ting +tin2ga ting3l ting3s +2t1inh +3tinis t1in1it -2t1inj +t1inka tin2k1l -3t2ins. -4t1inse -2t1int -ti1nu +tin2kn +tin2kr +t1inku +t2inn +ti2nor +t1ins +3tins. +t3insa +t2insä +4t3inse +tin4spa +tin4sum +t1int +3tinte. +ti3nu +tin2um 4t1inv 3tio -3tip +ti2osk +tioxi3 +3tip. +2tipe +ti3p4l +3tipp +3tips ti4que. +3tirad ti1rh -3tis -ti4scha +ti4ron +3t2isc +ti6schei +ti4schu tisch3w ti2sei +tis2el +ti3sk +2t1isl +t1iso ti2sp -ti1sta -3ti3t2e -ti3ti +t1isr +tiss4 +ti3s2th +tis3ti +ti1s4tr +ti2s1u +t1it2a +ti2tal +3ti3te +ti1th +3titi 2ti3tu -tiu4 -tium2 +3tiu +tium4s 3tiv ti2van -tive3 ti2vel ti4vene tiver2 +ti4verh +ti4verk ti4verl ti2v1o -ti2v3r +ti4v3r ti2za +ti2zir 2t1j 4t3k4 -4t3l +4t1l2 +tlan2g tl4e -5tlem -tle2r3a -6t5li +t2lef +tlei6der +tle2ra +6t3li +tlings5 +tlit1 +t3lo +t5lö tlung4 -4t3m2 +4t1m4 tmal2 -tmen6t3 +tma2st +tmen8schl +tmen6t5 +tments4 +t3mo tmo4des -4t3n2 +4t3n4 t5na tnes2 1to 3to. to4as to5at +t2oba 4tobj tob2l t1obs +3tobt to1c t3ochs 3tocht -to6ckent -3tod -tode2 -4to2d1er -tode4s -to4d1u +to6ck5ent +3t4od +tod1er2 +to4dun +tof4fa +tof6f5ent +tof4f3er +2toffi +toff3s +3tog +2t3ohr +3toi +4toi. toi4r -3tok -to3la -3tole +4toiz +5toj +3tok4 +3tol +to3le +4tolp 4tolz -tom1e2 -2tomg -3ton -to2nau -to2neh +tomar4b +to4mene +3tomi +to2min +3tomo +to2m1u +to4mun +to2nan +ton3au +tond2 +to2n2eh +toner6ke +to2nob +2tony 3too +3top. +to2pad to2pak +to2pan +to3pas to2pat +top1hi 3topo -2topt -3tor. -to1ra -to2rau +2to4pt +3tor +t4or. +tora2g to4rän 4torc t1ord -3tore +t2ordi +4t3ordn +t4ore +to2rei to2rel -t1org -t3orga -3torin +to2rem +to6renna +tor4fan +t1or3g +4torga +t5orient +torin4s tor3int +5tork to2rö -3tors -t1ort. -to2ru -t2orw +t4ors +4t1ort. +tor3t2a +t1orth +4tortn +4tort2s +to4ru +to3rü +to4rüb +4tory to3sc -3tose -to3sh -to4sk -tos2p +to3s2e +to3s2h +to4ska +to3s2p 4toss -3tost4 -to1sta +3to1st2 4toß -3to3te +to1ßu +to2tä +3tote to2tho 3totr tots2 -3t4ou -touil4 +5t2ou +touil2 to3un 3tow -2tö +to1x +3toz +1tö 3töch -4töf +4töck +2t1ö2d +2tö2f 4t1ök -tö4l -5tön +2töl. +3tön +t2ör t1öst -4töß 3töt -4t3p2 +2t3p4 tpf4 +tpi2n 2t1q 1t2r4 2tr. 5tra. 3trac tra3cha -t3rad. +tra3chl +2t3rad. +2trade tra4dem +4t3radie +tra4fah tra4far +t4rag 3trahi 4trahl -6trahm +2trahm 5t4rai 3trak +4t3rake +t4rakt 3tral -2t3rams +tral3l 3t4ran. -2trand -3trank -t1rann -3trans -t3rase -t3rasi +4trand +4trang +t3rann +5t4rans +tra2st 4traß +4traub. +4trauc t4raue +t4rauf 2traup +4trauß 5träc +2träd 3träg 3träne +4träng 4träs 4träß +2träuc +4träus +4träuß 4t5re. -tre4ale +2trea +t3reak 4treb tre2br 4trec t3rech t4reck -6t3red +5treck. +tre5cke +2t3red 3tref 4trefe +5treff +4trefl 4trefo 4treg +t3reh t4rei. 3t4reib 4treic -2treif -t3reig +4treif +2t3reig 2t3reih -t3rein +2treim +4t3rein 2t3reis -6treit +tre7isch. +4treit t3reiz 2trek -6t3rel +4t3rel t4rem t4ren. 3trend 4trendi +3trennu t3rent 2trepe -2trepo -t4repr +2t3repo +3trepp +t3repr t4rer -t4res. -t4ret -tre2t3r -t5rett -t4reu +5t4res. +tre2ta +t4rete +tret3r +2t3rett 3treuh -2t3rev -2trez +4t3rev +t4rex +4trez 5t4ré 2t3rh 3tri +t4rib 4tric +t4rick +t4rid2 5trieb -2trieg +trie3fr +tri4ena tri2er tri4ers +trie1s +4trig. 5trigg -t3rind +tri3gl +t4rik +tri4ke. +tri4kes +5triko +4t3rind 4tring tri3ni -4trinn +4t3rinn t4rip 4tript -t4rit +4t3riv tri2x trizi1 -3tro. +5tro. +tro3b4 4trock. 3troe -t4roi -tro2ke -4trom. +tro4kes +trol4la +6trom. +tro4men tro2mi +4tromk +4troms +4tromv 3tron -2t3roo +tro3na t4rop +tro1pe 3tropf +5tros. +tro5sm +3trost +t1rot. +2trout 3troy -t3röc +4t3röc 2tröh +6tröm 3tröp 3trös -4tröss +4t3röss 3tröt 3trua -2truf +3trub +2t3ruc +4truf 4truk trum2 +t3rumä trums1 -2t3rund -3t4runk +t3rund +3trunk 5t4rup +t3russ +2trut1 tru2th +4truw trü1be trü1bu 2t3rüc trücker6 t4rüg +3trümm try1 2ts -tsa4b -t3s2ac +4ts. +ts3ab +t4sachs t2s1a2d -t2s1ah -ts1al -t4s1amt4 +ts1ahn +t2sall +t2salt +t4samp +t4s1amt t2san -ts3ar -ts1as +ts3ane +tsa2r +ts3are +ts3ari +t2s1a2s3 t2sau -t2s1äh -t2s1än -t3s2cha -t4schar +ts2av +t2säh +ts1än +ts1äus +t4scham +t6schart t3sche t4schef -ts4chem +t3schl tsch4li t4schro +t3schü ts4cor t2s1e2b -t3seil -t4seind -ts1em -tse2n1 -t2s1eng +tse2e +t2sef +tse4he. +ts2eil +t3seme +ts1eng +ts2ens t2s1ent +t2s1ep t2s1er t6s5essen +tse2t +ts1eta +t2s1eti +t2s1e2v +t2sex +t3sexi +ts3he t2s1i2d +t2s3i2k +t2sim tsing4 -ts1ini -t2s1ir -ts3kr +t2sini +ts1ir +4tsk +t3skal +ts4kele +tski2 +t4s3ko t1slal -ts1o +ts1off +t2s1op tso2r -t3sou +ts1orc +t2s1ori +ts3ort. t2sö -t3spal -ts1par -ts4pare +t2spac +t2spal +ts1pas +t2spat +ts3pate t2spä -ts2ped -t3spek +t3sped +t3spei +t3s2pek +ts4pend t2sph t3s2pi -ts2pon +t4s3pic +t4spins +ts3ple +t2spo +t3s2pon t3s2por -t4sprei +t2spro +ts2pul +ts2put ts3s4 -t1st4 +4t1st4 +t4stabe t2staf t4stag ts3tak -ts4tal -ts3täti +t4stale +t4s3tanz +t4stas +t4stat. +t4s3täti t2stea -t2s3tep +t3stein +ts4terb t3s4tern t3s4tero -t2stip +t4sth +t3stif +t3stim t4stit -ts3trad -t2s3trä -t4streu -t2stri -tstro2 -t4strop -t2s3trü +t4stoch +t4stoi +ts4tol +t4ston +t3strec +t4stren +t4strie ts2tu -t2s1u -1tsub -t3sy4 +t5stub +ts4tüm +t4sty +ts1u +t2su. +5tsubi +t2sumg +t2sums +t2sumv +t2sumz +t2s3un +tswa2s +t3sy 4t1t tt1ab -tta2be tt2ac -tta6gess -tt1ak +tt3achs +tt1ad +tt2ag +tta6g5ess +t4t1ah +tta2ke tt2al -tt3ank +t4tan4a +t2tanm tt2ant +t4t1ap tt1art -tta1s +tt3atr +tt1äh tt1ebe tt1eif tt1ein -tt1eis -t3tel -tte2la -tte4leb +t2t1eis +tte4l1a2 +tte4l3e4b tte4len +tte4lin ttel1o -tte4rec -ttes1 -tte4sa -tte2sä4 +ttels4t +ttel5ste +t2temu +tte4na +tten6sem +t4tentb +tten3te +t4tentf +t4tents +tten3z +t2teo +tt4ere +tt3erfo +tte4rik +tte2ro +tt2erö +tt4es1 +tte4s3a2 +tte4s3ä2 +tte2so +ttest4r tt2häu -t2t3ho -t3ti -t3to -tto1s -t3tö -t3tro +tt1hi +t2t1ho +t2ti4d +t4t3igi +t2tins +tt2int +t2tiso +t6t3la +t4torg +t2trou tt3rü +ttschi4 +tts1eh tt2sen -tt2sor tts1p tt2spe tt2spr -tt2sti -tt5t -t3tu -tt2un +tt4s3tät +tt2sum +tt3s2z +tt5t2 +tt1u2f t3tü +tt3z2 1tu +3tua +tu4ale tu1alm -tu3an +tu1alv +tu3ant 2tub2 tuba3b 3tuc tu2chi +tu1cho 2tud +tudie4n3 3tue -4tuf +tu2ere +2tuf tuf2e tu3fen t3u2fer -tuff3 +3tuff +tu2gan 4tuh -tu2is -2tuk -t3u2kr -tul2a -t2um. -3t2ume -2t3umf +tuh4ler +tu1ist +tu2kr +tul2i +3tum. +tum2b5l +3tume +4t3umf 2t3umg 2t1umh 2t3umk +2tuml +3t2umo 2t3umr +4t3umsat +2t1umsc tum2si tum2so -tums5tr +tum4s5tr 2t3umt 2t1umw 2t3umz 3tun. 2t1una 2t1und -3t4une +tund2e +tun2en 2t3unf 3tung t3unga tung4s5 2tunif -2t1u2nio -2t3unt -t1up. -tu2r1a4g +2tu2nio +2tuniv +2t1unm +3tunn +t1u2no +t3uns +3tuns. +4t3unt +2t1unv +2t1up. +t1upg +tu2r1ag +tu2ran +turan4l +tu2ras +tu2rau tu2rä tur1c -tu2re. +tu2r1e2b tu2rei +tur3eis +tu4rene tu2r1er -tu2res -tu2r1e4t -turin1 +tu4res +tu2re4t +tu2r3e2v +tur3f4 +tur3g2 +tur1in1 +tur4mun 3turn -tu2ro +tu2r3o tu4ru +3tus tu2sa tu4schl +tu2se tu2so -tu3ta +tu3t2a +tuto5 +tuto3re 2tü 4tüb +tü3ber. 3tüch tück2s 3tüf +4tüh 3tüm 3tür. tür1c 3türe 3türg 3tür3s -3tüten +3türw +4türz +3tütc +3tüte 4tütz -4t3v -4t3w -twa2 +4t1v2 +t3vo +tvoran4 +4t3w4 +t5wa2 twi4e -1ty1 +t4wist +1ty +2t1ya 3typ -ty2pa -tys4 -6t1z -t2za4 +ty2p1a +ty1s2 +2t1z +t2za2 tz1ag -tz1al -tz1ar +tz3ar tz1au -tz1ä -t3ze. -t2z1e2c +t2z1ä +t3zäh +tz1ec +t2z1e2d +tz1ehr t2z1eie -t2z1eis +t4z1eis +tze2m +tz1emi tze4n1 tz2ene -tz3ents -tz1erl -tz2ers -t3ze2s -tz1ind -t2zor -tz2ö +tzen5s4t +tzen3ta +t4zentg +t4zentl +t4zents +tze4reb +tzer6gre +tz1erw +tz2er3z +tz3erzi +tze2s3 +tz1e2t +t2z1i2d +tzi4m +tz1imi +tz1int +tz1inv +t2z3om +t2zop tz2th -tz2tin +tz4tin +tzu2gu +t2zuni +tzwan4d3 tz1wä tz1wi +t3zwie tz1wu 2ua -u1a2b +u3a2b u3a2c -uad4 +ua2dan +uad4r +ua2g u1al. -ua2lau +u1a2l1a +u1a2l1ä u1alb -u3alet +u1ald +u3aleb +u3a4lent +u3aler2 +ua4lerg +ual3erk +u3a2let u1alf -u3a2lo +u1alg +u1alh +u3a2lid +u1aln +ua2l1o2 +u1alp u1alr u1als -u1alt +u1al5t4 ua2lu +u1alw u1alz -u3am +u1am +uan2a u1ans u3ar. uara2b u1ars +uar4t3an ua3sa +uasi1 ua2th uat2i +uat2o u3au u1ay u1äm +uä2s u1äu 2u1b -u8be8cken. -u3b4i -ubi3os. +u2barb +ubb4l +ube2be +ube2e +u2b1ehe +u4b3eins +u2b1e2m +ube4n1a +uben3o +ub2er +u4b3erde +ubert4 +ub4es +ub1eul +u3bit ub2l +ub3läu ub3lic -u2b3lu +ub3lu +ub4lut +u2bob u2bop -ub3rä +u2boz u2b3rit +ub4rü ub2san +ubsau2 +ub4s3che ub2s1o -ub2spa -u2büb -2uc +ub2sp +ubst2 +ub3t2h +4uc uc1c -u1ce uch1a u1cha. uch1ä u1che -u2ch1e4c +uch1ec +u2ched uch1ei +ucherin8t u3ches u1chi -uch1il +uch3im uch1in uch3l uch3m uch3n +uch1op u2ch3r +uch4sel uch2so -uch4spr -uchst4 -uch4tor -uch2t3r +uch2sp +uch2ta +uch3tan +uch6t5erf +uch6t5ert u1chu uch3ü uch1w u1ci +uck3elf u2ckem u4ckent uck2er -uck3erl -u3ckerr -u2cki +ucker8geb +u2ck3i +uck4sti u1cl 2u1d -u3d2a +u3d4a +uda3d +ud2e +ude3i4 +udein7 +ude2n1 +uden3e uden3s2 -uder2e udert4 +udes2 udi3en uditi4 -u2don +ud2o +u3dob +u2d3on ud3ra u3dru -2u1e +4u1e +ueb4l +ue1ch ue2ck u2ed -ue2en +ue2en4 u2eg +u2eh +ue2ke u4ela -ue2le +ue2lek ueli4 +uel2la +u3eln ue2mi uen1 +u3en. +ue4n3a2 ue2nä +u3end +uene2 +ue2neb ue2ner -uenge4 +uen4gag +uenge2 +uenge4m +uengene7 +uenge4s uen2gl u3e2ni +uenk4 ue2no +uen6zene uen2zu u2ep -ue2r3a +ue2r3a2 +uera4t ue2r1ä +uerb2 uer6baut -u2ere2 -u3e2rec -u3ered -u3ereh -ue3reig -u3erer -ue4rerg +uer3d2 +uere2 +ue2rec +u5ereinn +uer3eis +uer3ela +u3eremp +u3e4r3ent +ue3r4erb +u3ererf +ue4rer4g +uerer4h +uerer4k +uerer4m +ue6rersc +uerer6sp +ue6rerst +uer3esk +ue2re4t u3erex uer3g2 +uer4geb u3erh -u4erinn +ueri2d +ue2r1i4m u3erin4t +u3erl. +u3ern uer4nan -uer2ne -uer4ner +uer4nar +uer4ne uern3s4t -uer3o +ue2r3o4 uer2ö -u3err +u3errü uer3sc +uerst6 uer3t2 +u3eruh u3erum u3erunf u3erunt +uer3z2 ue2ta ue4tek +ue2tik +uety2 +u2ev +ue2x1 +uf1ab u3fac ufa2ck u3fah -uf1ak u3fal -uf3ar +ufall4 +u3fam +ufa2n +uf3ane +u2f3a2r u3fas +uf1aß +ufa2t uf1au +u2f1än u2f1äs u2f1ä2ß u2f1ei +ufel4s3a u2f1em +4ufen u3fen. u2fent +u2ferf u2f1erh +u4ferla u4ferle -uf2ern +u4ferne +u2f1et 2uff +uf3fe uff4l uf2fro +u2f1id +u2fim +u2f1ins uf3l u2fob ufo2r uf1ori uf3r -uf3sä -uf4sin -uf4so +uf5sä uf2spo -uf2t1eb +uf4stab +2uft +ufta2b +uft1eb uft3erd -uft3s2 +uft3er4g +ufter4l +uft3s4 u2fum 2u1g +ug2abe u4gabte -ug1af +ug1a2d ug1ak -u2g1ap -uga4s +u2gana +u2ganb +u2gani +u2g1ans +u2gant +ug1ap +u2g1ar +uga2s ug1au ug3d2 -u2g1ei +u3ge. +u2g1ec +ug1e2i +u2geig +u2gein +uge4lob +ug1emi +ugene2 +ugen3s2 u2g1erf u2g1erl -ug4es +u2gerr +u2gerv +u3ges. +u2g1esk +ug2et +ugg2 ugge4st +ug2gl +ugg4t ug3hu +u2g1i2d +u2gim +ug1in u2g1l -ug3lad +u4glä +u6gleitb +u6gleitu +u4glic +u4glis +ug3liz u4g3lo -u3g2lö u4glu -u2g3n +u4g3n ugo3 -ug1or +u2go4b +ug3oc +u3gon +ugo4p +ug1o4r +u3gos u2gö +u2g3rä +u2greg u4g3reis +u2gres +u2g3rie ug3ro -u2grol -ug4ros +u2grou ug3rüs -ug3se -ug4ser -ug3si -ug3spa +ug3span +ug4spe +ugs4por ug4spr ug4spu -ug5stä -ug3str +ugst2 +ug3sta +ug3stä +ugs4to +ug3s4tr +ug3stu +ug4stur ug3s4tü +u2gum +ugu3te u2gü u1h -uhe3s6 +uh2a +2u3he +uhe3a2 +uhe1e2 +uhe1s +2uhi +2uhl uh1la +uh2lar uh1lä +uh4l3ent +uhl3erb uh2li -uhme4 +uhl2ö +2uhm +uhme2 uhr1a -uh2rer -uh3ri +uhrei4s +uh2r3er3 +2uh3ri uh4rin -uhrt4 +uh2r3o uh2ru uh4rü uhs4 +uh3t2 +u2hu +2uhü uh1w 2ui -ui2ch +ui2a +ui1ch +ui2che ui4cker +u1idd u1ie ui1em u3ig u4ige uil4les -u1in. -u1is. +u1im +u3in. u3isch. u3ischs +uis2e uisi4n -ui4s5t +uis3t +uit3s u1j +uji3 uk2a +ukä2 +uk1äh u3käu -u1ke +u1k2e +uke2n1 u1ki u1k2l -ukle1i +ukle1 uk4n +u2k1ob +uko2m1 +ukom3a uk2ö u1k4r uk2ta -uk2t1in -uk2t3r +uk2t1el +uk4tent +uk2t1er +uk2tin +uk4t3o4ri +uk4t3r +uk2tum u1ku uku2s uk2ü u1l -ul1ab3 ul1am +ulan2e +ul2ar ula2s ul1äm -ulb4 +ulb4l +ul4dan ul2dr uld2se 2ule u2l1el +ul1emb ule4n -ul1erf ul1er2h -ul1erw -ule2sa ules3t ule2t ul1eta -u2lex -ul3f4 +2ul3f4 ulg4 +2uli +ul1id uli2k ul1ins +uli1p ul3ka ul2kn -ul2les -ull3s +ull1au +ul3len +ul3l2i +ul2lo +ull3s2 +ulm2e +ulni2 ulo2i -ul1or -ul2p1h +u2lop +u2l1or +ulp1h +ul2pha ul2sa ul4sam +ul2s1ec +ul2sei +ul2ser uls2th -2ulta +ul2sum +4ult2a +ul3tan +ult3ar +ul2tau +ulter4m +ul3ti ul4tri ult3s u2lü ul2vr ulz2w -u2m3a2k +2uma. +u2maa3 +u2mab +u2m1ad +u2m1a2k um1all +um1ang um1anz -u2m1art -u2m1aus +u2m1ap +um1ar +u2marc +u2marm +u2mart +u2matl +u2matm +um1aus u2maut u2m1äh -1um3d2 -um2en -ument4s +1umd2 +u3me. +u2m1ef +u2m1ein +ume2n1e +um5engel umer2a -um1erf +u2m1erf um1erg -um1erl +u3merk +u2m1erl um1erw +umes2t 1umf +4umfi 1umg +um1ind um1inh -u2m1ins um1ir +umi2t +um1ite 1umk 1uml -2umm -umm2a -u2möl +2umme +um2mei +um3mi +um1ob +u3mol +um3ot +ump2fa +ump4fin umpf4li um2pho -um2p3le 1umr -um4san -3umsat -um4ser +um4s3an +1umsat +um4s1er um2sim +um4sk um2s1pe -um2s1u +um2sum um3t2 -um2un -u2m1ur +u2mum +u2m1u2r 1umz un1 4un. -4una. +2una. 1unab -un4al +un2a3br +un2ag +un2al u3n2am u2n3an -4un2as +u2nap +u2narb +2un2a1s4 un3at -1unda -un4dab +un2är +2und. +un2da +unda2b +un2dän 1undd +2unde un3de. -un4dei +underer6 und3erf +und3erö +underten8 +under8tend +und3erz un2dex 1undf 2undg un2did +un2dim 1undn +undo2b +un2dop un2dor -un2d3r +4un2d3r +und3s 4unds. -und3sp -und3st +2undsc un2d1um undü4 1undv 1undz -u3ne -une2b -une2d -une2h -un2ei. +u3ne2 +un3eid un3ein -un3eis +un2emi +une4n1 unen2t -u4n3erz -unes4 +une3re +une3ri +u4nerk +u4n3erz. +un2es4 +unf2 +un3fa unft4s +un2gab +un2gam +un2gat +3ungena +unger4e 1unget 1ungew ung5h -1unglü -un3gn +1ungl +un2glu +un2go un2gr ung3ri +ungs3 ung4sa ungs5tr +u3nic un2id un3ide -1u2nif -unik4 +4unie +3u2nif +uni3k4 un2im -uni2r -2unis +1unio +un2ir +un3iro un3isl u3n2it -3u2niv +1u2niv 2unk un2k1a2 -un2kei +un3ker +un2k1es +un2ket un2kne -unks2 +un2ko2p +un2kro +unk3s2 unk4tit -unk2t3r -3unku +unk2tr unlö2 unna2 -un2n3ad -un3n2e +un4n1ad +unn2e +unne4n +u2nob uno4r un2os 1unr @@ -14044,219 +22640,389 @@ unsch5el un3se 1un3si un3sk +un4ski un3sp +unsta4g +unste4c uns4t1r +4unsy +4unsz 1unt un3ta +un3te unte4ri -2unth -2unto +4unti un3tr unt3s 2untu +3unty +2u2nu +u3nuc unvol2 unvoll3 1unw +4unwä +3unwe +u2ny 2unz +un3z2a +unz2e 2uo u1o2b u3of +u1or u3or. -u1or3c +uo2r3a +uor3c +u3oret +uo2ris u3ors +uor5t uos2 u1os. uote2 +u1ox +uö2d +u1ök u1pa +3upd u1pe2 uper1 +uperer4 up2fa -u2pf2e -u2pf1i -u3pi +u2pfe2 +u2pfi +up2fu +u3p4i up4lu +u3po +2upp up2pl u1pr -upt3a2 +upra3 +u2p3ras +up4t3a2 +upten1 +up4tene upt3erf upt3erg -upt1o +upt3erk +upt3ers +up4tin +up4t1o up4tr u1q -2ur. +4ur. u1ra u2rab u3raba ura2be -ural4t -u2r1a2m -ur3ame -u2r1ana -uran4fa -uran4fo -u2r1ang +u2r1akt +u2ral4t +u2r1am +ura4na +u3rand +uran6fän +ur1ang uran4ge ur2anh -u2r1an5s -u2rar -ur3a4ren -u2r3att -u2r1au +uran5s +ur1anz +ur3ap +u2r3ar +ura4ri +u3rasc +ur1asp +ura4str +ur4ate +u2r1att +ur1au 2u1rä +ur1äl +ur1ä2m ur1än ur3b2a +2urc urch1 +urcht3e urd2 +ur3da ur3di +ure1e ur1eff +ur1eig u2rele -ure4n -u4r1ep -ur1erh -ur1erw +ure2n +ure4na +u4ren4se +u4rentn +u2r1ep +urer3h +urer3k +ur2ert +u2rerw +ur1eta +ur2e3th +ure3u 2urf +ur2f3l +ur2fro +urf4spr urf3t +ur6gense +urg3inn +urg1l +ur2gla ur2gri urgros4 -urg3s4 +urg1s4 uri2c -u2r1im -ur1ini -ur3ins -ur1int -urk2s +ur1ide +uri3en +u2r1ind +urin6sek +urin8stin +u2ri2so +ur3ku ur3l ur4matt -4u1ro -u3rol -uro1s -u1rö -ur3p +ur2m1au +urm2ei +ur4mern +urmet1 +ur2mum +ur2mun +ur3n2e +2u1ro +urob2l +ur1off +uroh2 +uro1s4 +urost2 +2u1rö +ur3p4 +2urr ur3re -ur3sac +ur2rh +3ursac ur2san -ur2s3au -ur2ser -urst4r -ur4sw -ur3s2ze +ursau4 +ur2s1er +ur4s1of +ur2spa +ur3sze urt2 -ur3ti +2urta +ur2tai +urt3ein +ur2tro +urts2c u3ru +uruf4 urü2 ur2z1a2 ur2zä -ur2zec +ur2z1ec +ur2zep ur2zi -ur2z1o +ur2z1op +urzt4 ur2z1w 2us -u2saf -us4ann -u6schent -u5schmu +us3a2b +usa2gi +u4s1amb +u4samt +u2sang +us2ann +us3ark +usa2s3 +us1ast +u2säh +u2s1äs +u4schab +u4schak +u3sche. +u4schef +usch5eic +u4sch3eu +u3schi +usch3mü +u3schu usch5wer +u3s2e3b u2s1ec +use2ei u2s1ei -u3seid +u4sen4se +u4sentl u3sep -use1ra +use4rec +u2s1erl u2serp +us1erw u2s1ese +u2sex +u2sid usi3er. usi5ers. -us1is. +u3sik +usi4kat +us1inn us3kl us3oc -u3soh -u2s1op +us1oh +u3sol +u2sop +us1orc us1ou u2spac us3part u2s1pas -u2spat -us1pe -u3s2pek +u3spec +u3spek +u2sph us1pic -u5s4piz +u3spit +u3s4piz u2spo us2por u2spu +usrich7 +us2s1ad +us2s3eb usse4g -uss5erfa -usser6kl -uss5er6su +usse4n +us2sep +us5ser. +uss3erf +usser4z +us4sesp us2sez +uss3k us2sof -ust3abe +us2sum +u1stad u1stal us3tau +us4tein +u1stel +ust3erl us2th -ust2in +us3ther +us3tin us3tr -u5s4tras +us4tras us6tris u1stu u2stun u2stur -us2ur +u2sumd +u2sumg +u2sumz +u3sur +3usus u2sü 2uß +uß1u 2u1t -ut1alt -ut3a2m +4ut. +u3taf +u2t1alt +u4t1a2m +ut2ans u2t1ap u2t1ar -u2t1är -u3te -u4t1ed -ut1e4ge +uta2s +u2taut +ut1äh +u2tär +ut3c +ut1e2d +u3teh ut1ei. ut1eie +ut1ein +u3tek +ut1ela +u3tem ute2n1 +uten2a u2tent -uter4er -u4t3er4sa +u4tentf +utera2 +ute4ral +ute5r4er +ute6ring +uter3k +ute4ros ut2es ut2et -u4tev -u4t1ex -utfi4 -ut2he -u2thi -u2t3ho +u2t2ev +u2t1ex +utfi2 +ut3hal +ut3hei +ut1hel +u2t1hi +u2t1ho u2thu +u2t1id +u4tigel +uti2vi utli4n -uto1 -uto4ber uto3c -ut1opf +u5to3m +uto1p +uto3pa u2tops -ut4or -utos4 -u3tö +utor2a +u4tord +uto2re +uto4rin +uto3s2 +4utou +u2töl +4utr ut3rea +u2trou ut3rü -ut3s2a -ut2s1ä +4uts +utsau2 +ut2säu ut4schl ut4schm +ut4scho ut4schö -ut3si -ut2spa -utt4an -ut3te -ut5t4l +ut3ser +ut3s2k +uts2p +ut3sta +utt4er +ut5t2l utts2 +utu2b +u2tum +utu4n +u2t1une utu4re +utu3ro utu5ru u3tü +u6tz +ut2zeh utz3eng +utz2er +ut2zet ut2z1in -ut2zo +ut2zis +ut2zö ut2z1w -2u1u2 +2u1u4 uufe2 +uum1 +uuma4 +uume2 u1ü2 2u1v4 u2ve. @@ -14265,292 +23031,441 @@ u1w 2u1x ux2e ux2o -ux3t -u1ya +ux3oe +ux3t4 +u1y +u2yo 2u1z +uze2 +u2z1ec +u2z1ene +uz2er +uzo2f uz3ot uz1we -uz3z4 +uz3z2 1üb üb1ä 2übc 2übd übe2 übe3c -übe4n3 -über3 +übe3le +übe4na +übe3ne +über1 ü4bet üb3l -üb3r +üb5r üb2s3t 2üc ü1che üch3l üch2s1c -üch5t4e -ü3cken +ücht4e +ü3cke4n ück1er ück3eri +ücker6ke ü4ckers -ück4spe -2üd +ü2ckin +ü2ckum ü4d3a4 +üde2c +üde2l ü3den. üden2g ü3d2ens -üd1o4 +üd3o4 üd3r üd3s2 -üdsa1 üd3t4 -üdwes2 +üdu2 +üe2 +üeb3 +ü1ei +2üf ü2f1a +ü2f1ä ü2f1ei +ü2fent üfer2 ü2f1erg üf2fl ü2f1i üf3l -üf2to +ü2fo +ü2fum ü1g +üg2e +üge2l1a2 +üge2lä +üge4lec üge6lei6s +üge2lo +ügen3s ü2g3l ü2gn -üg3s -üg4st -üh1a +üg3s2 +üg4s3t +üh3a2 ü1he ü2h1ei +ü2h3e4m +ü3hem. ü2h1eng -üh1erf +ü2h1ent +ü2h1erf ü2h1er2k ü2h1er2z -üh1i +ü2hex +üh1i4 ühla2 -ühl1ac -üh1lam -üh3l2e -ühl2se +üh1lä +üh2lel +ühl2er +üh2lö +ühl4sk +ühl4sta +ühl4sti üh3mo üh3ne ühn2s -üh1o +üh1o2 üh3r2e ühr3ei. +ühre2n1 +ühren3s4 üh1ro ühr3ta üh1s ühs2p üh3t -üh4th +üht2a üht4r ü1hu üh1w ü1k2 ül1a ül2c -ü3l4e -ül2l1a +ü3l2e +ü4l3ef +üle2r3a2 +ül2l1a2 ül2l1ei +üll2er +ül2lid ül2lo ül2lö +ülls2 +ü2lö ü1lu +ü2ma ü2ment -4ün -ü2n1a +üme2ra +ü2m1id +ü2m1in +ü2m1u +2ün +ü4n3a2 ün2da ün2dr ünd3s -ünen3 -ün2f1a -ün2f1ei -ün2fli -ün2fr +ü2n1erd +ünf1 +ünf3li ün2g3l -ünn2s ün2s ün3sc ün3se ün3sp +ün3sta +ünster3 ün3str -ünt2 -ü1nu ün2za +ün2z1i +ünzu2 +ün2zun ün2zw ü1pe üpf3l ü1pi üp2pl +2ür ür1a ü2r1ei +ü2r1e2l +ür2f1er ür2fl ür2fr ür4g3en4g -ü1r2o3 +ürge4ra +ürk2e +ü3r2o3 +ürom2 +üror2 ürr2 ür2s ür3sc ür3se +ür3si ür3sp +ür3sta +ürte2l3 ürt2h +ür2z1in ür2zö -ür2zw +ür2z1w üs2a ü2schl -üse3h -üse3l +ü3s2e +üse1e2 +üse3l2 +üse4n +üse3r4 üse1s +üs4s3a üs2s1c üss2e +üs4s3o üs2st -ü2st +üst3a +üste2n 2ü1ß 2üt ü2t1al +üte3m +üte4n +üten3s +ütent4 +üten3z2 +üte2ra +üte2r1e +üterich6 +üter3n +ü2t1h ü2t3r -üt2s1 +üt2se +üt2st +ütte4n üt2tr +üt3zen +üt2zw ü1v ü1z +3va. 2v1ab +vab4r va1c -val2s +va1f4 +va3g +vag2a +va4gh +va2la +2valu +v2an. +2vanb 2vang +v2ans 2varb -va1s +v1arm +vas2 +2v1ass +va1st v4at -va2t3a4 +va2t1a4 +va6tag +va4tan va2tei +va4t3eng +va4tess va2t3h -vatik2 +va4tid +vati3k2 +va4tim va4t1in vati8ons. -va2t3r +va4tord +va4t3r vat3s4 va2t1u 2v1au 2v1b -2v1d +2v1c +2v1d2 1ve2 +ve3an ve3ar -ve3b -ve3c +veau3 +veau1s +ve3b4 ve3d +ve3fa ve3g -ve3h -ve4i -2v1ein -veit4 +ve3h2 +2veig +v2eil +2vein +veit2 veits3 ve3la +2velan +vel2ar ve4l1au -ve3le -ve3li +v1ele +ve3lei +ve3l2i ve3lo +vel2o1p ve3ma -2ve3mu +ve3me +2v1emp +2vemu ve3nal +ve4nas ven2c ve3ne -venen4d ve3ni +ve4nin ve3nö -ve3o +ven6t3ag +vent4sk +2veo +ve3of +ve4pi ver1 ver3a ve3rad +2veral ve3rand -ve3ras -ver3b2 -ver5d2 +ve3r4ane +vera4s +ver6bart +ver3b2l +ver3d2 vere2 -ve4rek verf4 -verg4 +ver3g4 ve3ri ve4rin ver3k -ver3st -vert2 +vern2 +ver4sep +vert4 ver5te -ver3u +ver3u4 +ve3rus ves1 -2ve3sc +ve3sa +2ve3s2c 2ve3s2e ves3ti ve3ta vete1 -ve3to +vete3r +ve3ti ve3tr +ve3t2s 2veü ve3v -ve3x2 +ve3w 2v1f4 2v1g 2v1h +vi1an vi3ar vi4a3t +vi2ä vi2c vi3de vid3s2t -vie2h3a +3vie +vie2h1a vi2el -vi3en +viela2 +viele2 +vi2er vie4rec vie2w1 vig2 2vii +v2il vi2l1a +vi2lä vi4l1e2h +vi2lei +viler4 +vi4lers vi2l1in -2v1i2m -vima2 +vi2ma2 vi4na -vin2s -2v1int +vin3d +ving3 +vings4 +v1ins vi3sa vise4 +vi3s2i vi3s2o vi2sp vis2u +viv2 +viz2 +vize5 2v1k -2v1l2 +2v1l4 +v3le +v2lie 2v1m -2v1n +vm2e +2v1n2 +1vo 2v1ob -vo3ga +vo2be +vob4l +voge2l3 vo2gu -3vol -voll1a -vollen4 -vol6l5end -voller4 -vol6lerw +vol2a +vol4l1a +vollen6 +vol6lend +vol6ler6t vol2li 2v1op vo2r1 -vor3a -vor3e +vo4r3a +voran8schl vor3g vo3ri +vo4rie vo5rig +vorm2 vormen4 -3voy +vor3o +vort4 +vot2a +voy1 vö2c 2v1p -v2r -2v3ra -v3re -v4ree -2v3ro +vr2 +v1ra +v2ree +3v2ri 2vs +vs2c vs2e +vs2p v1sta v1steu v3s2z -2v3t +2v1t +vue3 +vu2enu vu2et 2vumf +2vumg +2vumk +v1ü 2v1v 2v1w 2v1z @@ -14558,189 +23473,296 @@ w2a 1waa wab2bl wa3che -wach6stu +wach8stub wach4t4r +1wack waffe2 waffel3 1wag wa5ge -3wagen +3wage4n wa2g3n wa3go 1wah wahl5ent wah4ler -wah2li -wai2b +wah2l1i 1wal +wa2lar 2walb -wal4da +wal4d3a +wal4din +wal2dr wa2les -2walm -wal2ta -wal2to -walt4st +wa3li +wal2m1 +wals2 +walt1a +wal6tere +wal6terl +wal4to +wal4tur 3walz wa3na +wan2d1a2 wandels6 +wan2dr w3anf +2wang +wan3g2e wang4s 1wann wan6z5en6d +wan4zer wa2p 1war2e ware1i -war3ste +wa5ren +1warn +war4ni wart4e +war2th +war2za 1was wa3sa +was2c wa4scha wa3sche +wa4sch3l +wa4schw wa3se wa3sh -wass4e +was3s +wass4e2 +wa3su +w2ä 1wäh 1wäl 2wäng 1wäs wäs2c +wäss4e +2w3äu 2w1b2 wbu2 2w1c 2w1d we2a -we2ba -4webeb -we2bl -web3s +we2b1a +webe1i +we2b3l +we2bo +we2b3r +webs2c we3cke. we5cken. we3ckes -we2e4 +we2e2 weed3 we2fl 1weg we2g1a -we2g3l +we4g1ei +weg5ersc +we4g3l we4gn -we2g3r -weg3s4 +we2g1o2 +we4g3r +weg3s2 +wegs4t 1weh -we4i -wei4bl +weh4r3er4 +wei2bl +weib4r 2weie weifel6d -weik4 +wei4fre +wei2gr +weigs4 +wei3k4 3weil +weinsau6 wei3sc -weis4s3p -weis4t -wei3str -wei4tr +weis6sel +weis6spi +wei2t1r +wei5ze +wel5le4 wel6schl wel6schr wel2t1 -wel4t3a4 +wel4t3a2 +welte4 wel6t5en6d -wen3a4 +wel4th +welt3i +wel4to +wel6t3r +wen3a2 +wendes4 wen2gl -we3ni +we3n2i +wen2ka +wen4kla wen4k3ri -we2r3a +we2r3a2 +wer5be +werbe3i wer2bl +werb2s 1werbu -werd2 +wer3d2 5werdens 1werdu werer2 wer2fl -wer4gel -we4r3io +2werg +wer2ga +wer6gels +wer2g3o +wer2gr +werin2 +we3rins +we2ri4o 1werk. -wer2ka +wer2k1a 1werke -wer2kl +wer2ki +wer2k3l +wer2kn +wer2k3o +wer4k3re wer2ku we2rö wer2s +wer3sp wer2t1a -wer4t3ei +wer2tä +wert3ei +wer6teig wer6t5erm -wer2to -1wese -we2s1p +wer2th +wer4tin +wer4t1o2 +wer4tre +wer6t3ri +wer4tum +1wes2e +we2sp we4st -west1a +wes4t1a +weste2 west3ei -wes2th -west1o2 -west3r +wes6ten6d +wes4tex +wes2ti +wes4t1o2 +wes4t3r wes4tu 1wet -wet2s +2wets wett3s -2w1ey +2w3ey +2w1f 2w1g -2w3h +whi4 +w3ho +w2i +wicht4s wi1cka 1wid wi2e +2wieb +1wied wie3l -wien2e -wie2st +wie3n2e wik2 -1wil +1wild wim2ma -wim4mu +wim6ment +wim4m3u +win2a win4d3e4c -win2dr -win2e +win3del +win6d5erz +1win2d3r 2wing +win2g3r +win2kl win8n7er8sc +win2no +win3s +wint2 1wi4r -wi3s2e +wire3 +wi5s2e wi2sp 1wiss +wiss4z wi3th +1witz. 1witzl +wiz2 2w1k 2w1l 2w1m 2wn -wn3s +wns2a +wn3sh 1wo1c wo2cha -woche4 +woch2e4 1woh woh4lei +woh4na 1wolf -wolf4s3 +wolf2s3 +wol2la wol4ler wor3a -wo2r3i -wor2t3r +wor3d +wo4r3i +worn2 +wort1a +wor4tel +wor6terh +wor4t3r +wort3s2 wo4r3u +wor3ü +3wos wot2 1wöc +wöl2fo wört2h 2w1p w2r +w3re w3ro 2w1s +ws2e +w3s2h w3s2k ws2t +w4s1u 2w1t wti2 w2u 1wuc wuch4sc +wuch4st +w3u2f wul2 wul3se -wun2da -wun4g3r +wund4e +wung3r +wungs4 wun2s +wunsch5l 4wur. wur2fa +wur2f1o +wur2fr wur2s 1wurst wus2 @@ -14749,466 +23771,773 @@ wus3te 1wüh wül2 wün3 +1würf +1würst 2w1w 2w1z x1a 1xa. 2xa2b +1x2ac 1x2ad 1xae xa1fl -1x2ag -x3a2m -xand4 +1x2a3g2 +2xal +xal2l +xa2m +1xane +1xani +x2an3t2 x2anz +xa2r 1x2as -2x1b -2xc +xa2z +2x1b4 x1ce x1ch x1cl 4x1d +xda4 +xdy2 1xe -x1e4g +3xe. +2x1e4g 2xek xe2l +3xel. +x1ele +xe3lei x1em 3x2em. +2xemp +x2ems x2en +3xen. xen3s2 -x2er. +3x2er. x2ere +2x1erl +xer2la +x2ern xers2 +x2ers. 3xes -2x3eu +2x1eu +2x1ex 2x1f 2x1g 2x1h -xib4 xi1c xich2 2xid +xi2dan xide2 -xi2d1em +xi2dei +xi2d3em x1i2do +3x2ie xie3l xi3g -xil1 -xil2a +xi2ler +xili3a xi2lo -xi2lu +xi2l1u +xim2 xin3s2 -x2i2s1 -xi3s2c -xiso2 -xis3s +x2is +xi2sa +xi2s1e +xi2sp +xis3s2 +xis3t xis4tä -x1i2tu +xi2su +3xit +xi3te +x1i4tu +xive4 x1j -2x1k2 +4x1k2 +xkal2 4x2l2 x3lä x3le 2x1m 2x1n -x1or +2xod +2xoe4 +x1o2r +xos2 +2x1ö2 4x1p xpor6ter +xpor4t3r x1q -2x1r +x1r 2x3s2 4x1t -x2t1a -x3t2as -xt1ä -x2tän +xt1a +xta2b3 +x3tan +xt2ant +x3tas +x2t1ä +x3tät xtblo4 +xtblock5 x2t1e2d -x2t1ei +xt1ein +x2t1el x4tent x2t1er2f -x2t3ev -xtfi4 -x2t1il2l +x2t1ev +xtfi2 +x2t1h +x2t1id +xti2la +x2til2l +x2t1o4 +x4tor xtra3b4 x2t3ran +x2trau +xt3rec xt3s2 -xt1u -x3t2ur +x2t1um +x2t1un 1xu xu1a -x1u2n -xu2s +xu2n +2xunt +xu2s3 +xusa2 +xuss4 2xv 2x1w -2xy 3xy. -3xys x1z 2y1ab -1yac +1ya2c +y2ach +ya1h y1al. -y1a2m yan2g y1ank +ya1q +ya3ra +yas2 +yas3t y1ät y1b -y1c2 +ybe2r +y1c y2chi y3chis ych3n -y1d4 +y1d +yd2o +ydri2 +ydrid3 +ydro3 y1e +y2ec +ye2d y2ef +y2el2 yen4n +yera2 y2ere -y2es. +yer2n1 +y2es +y4es. yes2p ye2th y1f2 y1g ygi2 -ygie5 +ygie3 yg2l y1h +y3ho yhr2 -y1i4 +2y1i4 y1j y1k2 yke3n +yk4l yk3s2 -y1l -y2l3a2m +yl1a2 +yl2a3g +y1l2ak +yla4l +y2lam +yl3ane +y1lant yl4ante +yl4anti +yl2as +ylau2 yl3c -y4le. +yle2 +y2le. +yl1em +y2l1es3 +y2l1e4t yli4n +ylo1i2 +yloid3 yloni1 +yl2op +yl1ora yl3s2 -y2l1u -yma4t +yl5t +ym2a +ym4an +ym4ar +ym4as +ym4e ymp4 ym2pha -ympi1 -y2n1o -yno4d -ynt2 -y1nu -y1of +ympi1e +ynä4r +yn2eu +ynk2 +y2n1o2 +yno4t +yn2oz +yn3t2 +yob2 +y2od +yoga3 yom2 -yon4i +yon2a y1ont -y1os +yo2pe +yo1s +y2ost y1ou -y1p -ypa2 -yp3an -ype2 +2y1p +ypa2b3 +ypa2n +yp2e2 +ype4r3o2 y2pf -y3ph +y2p1i2d y2p1in -ypo3 +y2plo +y3po3 y4p3s +yp3th +ypu2 +y2p1um +y1q y1r y3r2e y3ri -yri2a yri1e -y3r4o +yri3en +y3ro +yros3t yrr2 +2ys ys2an -ys2c -yse1 -y3s2h +ysch4 +ys2e1 +ysein2 y4s3l ysme3 ys2po ys1pr -ys3t2 -y1s4ty -y2s1u2 +yst2e +yst2h +ys2the +ys3to +ys3tr +ys4tra +y4stro +y3s2ty +ysu2 +y2s1ur y3s2z -y1t2 +y1t y2te. y2tes +yt2h +ythe1 y3to1 +ytos2 +y4t3r yu2r -yure3 +yur2e3 y1v y1w y1y y1z2 -2z3a2b +yze3r2i +2z1a2b zab3l za1c +2z1ach +zach2s 2z1a2d 2z1af za3gr 3z2ah -zah4ner -2z3a2k -2z1all -2z1am -z1an -za2na +zah3len +zah4ner4 +z1ak +4z3akk +2z1al +4z3ald +3zali +2z1a2m +z1a2n +4z3a4n4a +2z3anb +za3ne 2z3anf -3zani +2z3angs 3z2ank -zan4kl -2z3anl +zan2ka +z3anl +2z3anr zanti1 +za4pf +z1aq +z1ar +3zar. 2zarb -2zarc -2z1arm -z1arti -zar2tr -2z1arz -z1as -za1st4 -2z3at3 +za3re +2zarm +3z2aro +z2arr +zar2t1r +2z1as +za2sc +zast4 +z3at +zat2e +za2to 3zaub -z1au2f -z3aug +2z1au2f +2z3aug 3zaun +z3aur +2z1aut zä2 -2z1ä4c -3z2äh +2z1äc +z2äh +zä3hi +3zähn 2z1äm -2zängs -2z1äp -z1ärg -z1ärm -4z1b4 +z1än +z1äp +z1är +2z1äus +2zäuß +4z3b4 +zber2e zbü1b zbübe3 2z3c 2z3d2 zdan2 zdä1 +zdi1st +3ze. +2zea 2z1e2ben -2zecho -ze1e +ze1c +2z1e2cho +ze1e2 +zeeu3 2z1eff +z1e2ga zehe4 zehen1 zeh2l +ze3ho +zei1f4 zeik4 +zeil2 zei3la zeile4 2z1ein -zei1s6 +ze3in. +z2e1ind +zei4ne +4z3einh +ze3inse +ze2i1s4 zei3sk -zeist4 +3zeit zei2t1a -zeit5end zei4t3er +zei4to zei2tr zeit3ri -ze2l1a2 +zek4 +ze2l1a +zela2d +zel3a2n +ze2l1ä +zel3d4 +4ze2lek +4zelem ze2len ze2l1er ze2l1in -zell2a +2z1e2lit +zel3la +zel4lab +zel4l3ac +zel4lar +zel6lein +zel6ler6t +zeller6z +zell3s2 +zelm4 +ze2l1o zels2 +zel3sa zel3sz -zel3t2h -zel3tr -zelu2 +zel2ti +zembe2 2z1emp 5zen. -ze4n3ac +ze4n1ac +ze4nas +zen3au ze2nä +ze3n2em +zenen1 +4zenge. +z4engl +2zengp +2zeni +ze2nid +zenk2 zen3n -ze2no -zens2e -zen4sem -zen5s4tr -zent3s +ze2n3o +ze4not +4zen4sem +zen4ser +zens2p +z2entn +z1ents +2zentw +2zentz zen4z3er -z2er. -ze2r3a -ze2re2b +zen2zw +zeo4r +3z2er. +ze2rad +ze1ral +ze2rat +z2ere +ze5rek +zer2em +z2erfe +z3erfül 2z1ergä 4z3ergeb -z3erhal -2zerhö -zerin4t -zerk2 -z2erl. +z4erges +z4ergl +zer4gon +4z1ergu +3z2erhe +2z3erhö +zerin6te +z2erko +3zerl. +zer4lau +zer4le. +4zerleb +zer4len 2zerlö -z2ern -zer4neb -zer4n3ei +3z2ern +zer4nan +zer4n3e4b +zer4nei +2z1erö +zer2öf 2z1erq +4z3erreg zers2 -2z1ersa -4z3erste -4z3erstr -3zert -zert1a4 +z2ers. +2z1er4sa +zerta2 zer4t3ag zert4an +zer6teng zer6tere zer6terl zer4tin +zer2to +6z5ertrag zer6trau +z1erwe 4zerwei -2z1erz -3z2erza +z1erz +zer2ze +3z2es. ze2sä -ze3sc -ze3sku +ze3sch +zes1e ze2sp +ze4spo +zes2sa zessen4 zes6s5end +zes6sent +zes4ser4 zes2sp zes2st -ze2s3t -ze3sta +ze1sta +ze3stau +ze1str +z2et. +2zeta +2ze2th ze2tr 2zetts -2z1ex -2z1f4 -2z1g2 +zeu4gem +zeu2g3r +2z1eul +ze1ur +2z1e2x1 +4z3f4 +zfeue2 +2z3g4 zger2a -2z1h +zger4s3 +2z1h2 z2hen zhir3 zi3alo -zi3ar +zi2ar +zich2o zi2dei -zid3r -zie4lei +zie4ler +zie2l1i +zien3s zi1erh -ziers1 -zi1es. +zi1es +zi3ess +zig4s +z2il zil2e -2z1imp +2zimp zim4t3 +2z1ind zin2e zin3ei -zin4er 2z1inf -2z1inh +z1inh +zi4n3in zin1it +2z1inj +zin4na +zin4o zin2sa zin4ser 4zinsuf -z1int -2z1inv +2zint zi2o3 -zi3op zirk2 zirk6s +z1iso +zi2sp +zisse4 zi3s2z -zi1t2h -zi2t1o2 +zi1th +zithe2 +zi4t1o2 +zit2u ziv2 2z1j -2z1k4 +4z1k4 2z1l2 -2z1m2 +zlei3ti +zle1s +z3ly +2z3m2 +zme2e 2z3n2 +z3oas 2z1ob 2z1of zo2gl +zog4s3 2z1oh -3zol -zon4ter +zol2la +zoller4 +zol6lerl +zol6lert +zonal2 +zon3au +zon5s4 +zon4t3er zo2o -2z1ope -z1or -zo2ri +2zope +2z1o2r +zo3re +3z2orn zor4ne 2z1osz +2z1ou +2z1o2z 2zö2f 2z1ök z1öl +2zöl. +3z2öll +2zöls 2zön -2z3p4 +4z3p4 2z1q -2z3r2 -4z1s2 +4z3r2 +2z1s4 z3sa +zsau2 z3sh z3sk +zspor2 +4zst2 z3sz 2z1t +zta2n +zt3ane z2t1au z4tehe +ztein1 +zt3eins +zt2el +zte3ma +z4t1ent +z4t1erz +zte3str +zt2et +zt1he +z3them z3t2her +zt1hi zt3ho -z3tic -zt1ins -z3tö +z3thr +z3thy +z3ti zt3rec +zt3ric zt3s2 z3tü zu1 zu3a -zu3b4 +zub4 3zuc -zu4ch -zu3cke +zuch2e +zucht3r zud4 zudi4 zu2el +zu3e2r1 +zue2t zu3f4 -zu2g1ar +zug2em zu4gent +zug2i zu3gl -zug1un +zu4gla +zu4glö +zu2go 2z1uhr +zu3hu +zui2 zu3k +zul2 2z1um. +zum2a +2z1umb zumen2 2zumf 2zumg +zum2i +2zumk 2zuml 2zumr 2z1ums +zum2u +2zunab zun2e +2z1unem +zunf4 zung4 +4zunget +2zungl +z1uni +2zu2nio +2zuniv +2zunr +2z1uns 2zunt +zuo2 zup2fi +zu3pl zu3r2a -z1urk +2z1urk 2z1url +2z1urn 2z1urs 2z1urt zu3s4 -zu5t -zut2a +zusch4 +zu5t2 +zut4r +zut4u +zut3z zuz2 -2züb +2zü4b +3züc zür1c 2z1v zw2 z1wac 2zwag -2zwah -zwan2d1 -z2wang +4zwah +4zwap z1war -2zwas -4zwäl +2zwa2s +2zwäs +2z1wed 2zweg 2zweh z2weig +2zweil +zweiter6 2z1wel 2z1wen 2z1wer -z2werg 2z1wes -2zwet -2zwir +z2wic +zwi4e +3zwing +2zwirt +z2wisc +2zwiss z2wit 2z1wo z1wör z1wur 2z1wü -4z1z -z3z4a +zy1an. +zy2le +2z1z +z3z2a +zza3b4 +z4z3al +zz4at +z2z1id +z2z1in1 zzi1s4 -z3z2o -zz2ö} \ No newline at end of file +zz2ö +zzug4s} \ No newline at end of file diff --git a/tex/context/patterns/mkii/lang-deo.pat b/tex/context/patterns/mkii/lang-deo.pat index ef5ac5c4d..cc2d7f1e1 100644 --- a/tex/context/patterns/mkii/lang-deo.pat +++ b/tex/context/patterns/mkii/lang-deo.pat @@ -10,7 +10,11 @@ .abo2 .ab3ol .ab1or -.ack2 +.ab3s2 +.ab3u +.ade3n +.ae3 +.aft2 .ag2a .ag4r .ag2u @@ -18,115 +22,174 @@ .akt2a .al2e .al3k -.al5l4en +.al3lei +.al5len +.al3se .al4tei -.alt3s +.al4tel +.alter6s5 +.alt1s +.al2tu .ampe4 -.amt4s1 +.amt2s +.amt4sc +.ana1c +.an4a3t .an3d2 .anden6k .and4ri +.an1er .ang2 .an3gli +.an3go .ang4s2 .angst3 +.ani2s +.an3k4 +.an3na .an3s2 .an4si. -.an4tag -.an3th +.an4tar .an3z2 .aos4 .ap5p6le. -.aps2 .ari1e -.ark2a +.ar3k2a .ar4m3ac +.ar4mun .ar2sc +.ar4tan .ar4t3ei .arter4 .ar6t5erh +.ar2t1r +.arz2 .as6sest .as2t .ata1 -.at4h +.at2h +.at4r .au3d .au4f3 .aufs2 .au2s1 -.ausch3 .au6stes +.auß2 .ax2 .äm3 .är6schl +.ät2h .ät2s .äu3 +.bahn3 +.bah6ner +.bal3t +.baus4 .be3erb +.beige4 +.bel2a .be3r2a -.be3r2e -.berg3a -.ber6gab +.ber2e +.ber4g3a +.berga6s .ber6g5e6b -.ber4gl .ber4g3r +.ber4tr +.bi4os +.bi2t +.bit1a .boge2 .bo4s3k .bu4ser .bus3se -.bu7s8ser. -.ch2 +.bussy4 +.bu3ta +.ce2ra +.ch6 +.char8mes .chi3er .dab4 .da2r1 -.da4rin +.dar3in .dar2m1 .da4te. .da4tes .de2al .de1i -.de4in. +.dein2 .de8ments +.de3na +.den4ka +.den4kl +.den4ko .de1o2 .de3r4en .derma3 .dermas6 .de3sk -.dien2 +.di3el +.di4en2 +.dienst7a8d +.do3b .do2mo .do1pe -.dorf1 -.dü1b +.dor2f1 +.do2tr +.dys3 .ebe2r1 +.eh2e .ehe1i -.ei4ds +.ehe5n .ei3e2 +.ei3f2e +.ei3k .ei4na -.einen6g +.einbus6 +.ein3d +.ei2ne2 +.ein3eb +.ein6erl +.eins2 +.ein3sp +.eise4 .ei2sp +.eis3s2 .ei4s1t .ei2tr .eke2 -.el2a +.ek3li .el2bi +.el2bl +.el4fei +.el2fl .em3m2 .en1 -.en4d3er -.en5der. +.en4da +.en4d3er4 .en2d3r +.en4dü +.en3ga .en2gl +.enk2 .enn2 -.en2t3 +.ent3 +.en2ta +.en4tei +.en7thalp +.en4tio +.en2t1r +.ents2 .epi1 .ep3p +.er4bei .er8brecht .er2bu -.er2da .er4dan -.er4dar -.er4dei .erden6k -.er4der +.er4d3er .er1e .ere3c +.er2em .erf4 .er1i .ers2 @@ -135,247 +198,429 @@ .er8sterb .er8stritt. .er8stritten. +.ert2 +.er4z3el .er4zen4 -.esel4s .es3p .es2st .es2t -.est4e -.est2h +.esta2 +.est6e +.est3r .et2s -.eu1 -.eu3g4 -.eu3t -.eve4r +.eu3 +.eug4 +.eur4 .ext4 -.fe4i +.fäs3se +.fe3la .fer4no -.fe4sta -.fid2 +.fi3d4 .fi4le. .fi4len .fi2s .flö8s7se. .flö8s7sen. -.flö8sses +.flö8s7ses +.flu2g1 .fs4 .fu2sc +.ga2me +.gan4ga +.gangs4 +.ga4s3e +.ga6sten +.ga4su .ga2t .gd2 +.gebe4a .geb2l +.gel4b3r .gel2d1 +.ge3lu +.ge3m .ge5nar -.ge3n2e -.ge3r2a -.ge3r2e +.ge3n4e +.ge3n2o +.gente4 +.ge3r4a +.ger2e +.ge3ro .ge3s2 -.get4 -.ge3u +.glan2 +.glanz3 +.gla4s3t +.gol6der .grif8fes -.guss1 +.gus2 .haft3s -.hal2s +.hal5le +.halt4e .hau2t1 .he2 +.he4bei .he3fe -.her3an +.he3le +.he4r3an +.he3rat +.her6b5ra +.he3rer .he3ri .he6r5inn -.hi4n .hin3u +.hof1 +.ho4fen .ho4met +.höch2 .ia2 .il3 .im2a .ima4ge .im5m2 .in1 -.in3e +.ind2 .in3gl -.ink4 -.inn2e +.ink2 +.in3n2e +.in3sk +.in3t2 .inu1 +.io4d .ioni1 .ire3 .is2a -.ka2b5l +.it2h +.iv2 +.joni1 +.ka2b3l .ka2i -.kamp2 -.ka4t3io +.kal2a +.ka3le +.ka3t2a +.kat3i +.ka4ti4o .ken6num .ker3s .ki4e -.kle4i +.klang3 +.ko3b .kopf1 -.ks2 +.kor4da +.kraf2 +.ks4 .kus2 +.la3be +.lan8de8mi .le4ar +.le4gas +.le3n2i .lich8t7er8s .li2f +.li3po .li4ve. .lo4g3in +.lo2sc +.los3s2 +.lo2tr .lo3ver .lö4ss -.lös3se +.lus2 +.luster6 .lu4str +.lut2h +.ly2s3 .ma3d -.ma3la +.ma3ge .mal4e +.mas8sen. .ma4str +.mat4c +.matu3 .md2 .mel2a +.me3ne .me3no .men8schl .men8schw -.men3t4 -.mi2t -.mi4ti +.mes4sp +.mi2f +.mik4 +.mil2z1 +.mi2t1 .mm2 +.na3no +.na3t .näs5c +.nebe4n +.ner2f +.ne1ro +.nich2 +.nicht5e .ni2e -.nob4 +.ni3k4l .no2c .no2s -.no4th +.no2th .nul2 .nus2 +.oa5s .ob1a .obe2 +.ober5ei +.ob3i2t +.och3 +.of2e .ohr5s .oper4 .or2a +.ord4e +.or3g +.or3k2 .ort2 .orts3e -.ort4st -.os5t6alg +.os3s +.osta4 .oste2 .ost5end .osten8de .oste6re +.ost3i .ost3r +.ot1a +.ou2t .ozo4 .öl3l -.pa4r1e -.par3t4h +.pab4 +.part4h .pe2c +.pe3la +.pe3le +.pe3na .pe4ste .pf4 -.ph2 +.ph4 .poka2 +.postei6 +.po8steig +.po4sto .po4str .ps2 .rabe4 +.ra3ch4e .ra3me .ra4sp .ra4s3s -.reb3s2 +.rau2m +.rau8schl +.räu3sc +.re3ale +.rebs2 .re3cha -.rein4t -.reli1 -.reli3e -.ri2as -.rich5te +.re5insz +.reis6e5i +.rei6str +.res2t +.re4stu +.ri4as +.richt6e +.ri4f .ro4a -.ro3m4a -.rö2s1c +.ro3be +.ro2e +.ro2ha +.ro3m +.rom4a +.ro2t3r +.ro3tu +.rö2sc .rö4ss .rös3se +.ruf3s +.ruh2r1 .runder6 .ru5s6ses .rü1b .rücker6 .rü4ss +.sa3br .sali1 -.sami3 +.sali3e +.sami1 .sas2 -.sa3sse -.säs4 +.sa5sse +.sau1c +.sau4er +.sau5er. +.sä5s4 .sch4 +.schaf8t7end +.scheiner8 .scho7s8se. .scho7s8ses. +.se2e +.seein4 +.se2ha +.sein2 +.sen4f .sen3s -.ser2u +.se3re +.se1ro .se2t1 .sha2 +.si4en +.si3gn +.sini3 .si2te .ski1e -.spas4 +.sour2 +.spani7er. .spä5s4 .spiege8lei -.st6 +.st4 +.stau8becken. +.ste2i +.steiner8k .sto4re .stras4 +.stro6ma .sucher6 +.sy5s +.tage4s +.ta3mi +.tan4k3a .tan4k3l +.ta3ra +.tar3t2 +.ta2t1h .ta2to +.ta4tor +.ta2t1u .te2e .te2f +.tehe3 +.teiler8s +.tei8l7ersc +.te3le .te3no +.te1ra +.tes4t +.te6stei +.te6stel +.test3r .th4 .ti2a -.tid1 .ti2e -.ti4me. +.ti2me .ti4mes +.ti3r .ti2s +.tischen8 +.ti8sch7end +.tite4 +.tode2 +.to4der +.todes3 +.to2n +.to4nat +.to3nes +.ton3i .to4nin +.tons2 .to4pl +.to2pr .to2w .tras3 .tra4ss .tri3e4s -.ts2 +.trockenmas8 +.ts4 +.tse3 +.tu3ra .tu3ri -.uf2e2 -.ufer1 +.turm1 +.tur4ma +.ub2 +.ufe2 +.ufer3 +.ul2b3 .um3 +.ume2 .umo2 .ums2 .un3a2 .un3d .une4 -.un3g +.un3g2 .uni2t -.ur1 +.ur3a2d .ural4 -.ur2i -.urin4s -.ur3o2m -.uro2p +.uran6fa +.ur1c +.ur1e +.ur4inf +.ur3o4m +.ur1o2p .ur3s2 .ut2a .ut3r -.übe4 .ve5n2e -.vi2e +.vol2 .vo4r .wah4l .wa2s .weg5s +.weine4 +.wei4ta .welter8e .welter8k +.wer6ker +.wer4kr +.wer4tr +.wetterer8 .wi4e .wor2 .wort5en6 +.wur2f1 .xe3 .ya4l .zeit3s .zel4la4 .zelle4 .zel6lei +.zel4li +.zeug4i .zi2e +.zie4l3u +.zin4ka +.zin4s3c .zin4st .zol2 +.zuch2 +.zug3l +.zu4gra +.zu2pf +.zweigen8 +.zwei8g7end a1ab aa2be aa1c +a1a2ce aa2gr -2a1a2n +a1akt +a1a2n +a2ans +a1aq 2a2ar -aa2r1a -aar3f4 +aa2r3a +aar3b +aar3d +aa3rea +aa2rei +aarf4 +aar3g2 aar3k4 -aar5sc +aart4 +1aas aas1t aa2th aa2t3r @@ -384,975 +629,1533 @@ aat4s1 a1ä a1b 2aba -ab1auf +3abad +ab1alt +a3b2am +ab2ant +ab1au +ab2aut ab1ä +ab2är ab2äu +2abbat +2abbin 1abd -ab1eb -abe1e +2a3be. +2a3bec +2abee +ab1eic +abe3i4d ab1eil -4abel +ab1ein +2ab2el abe2la +abela4d +abe2le +2aben. +1abent +2aber +a2berd a3beri ab1er2k ab1er2r ab1er2z +4abes +abe2s1e ab3esse abes2t ab1eß 2abet 2abew 1abf -3abfi 1abg +3abga 1abh 2abi +4abil ab1ins ab1ir ab1it 1abk ab1l 1a2bla +a3blat 1a2blä -2able -ab4le. +a2b3led +3ab3lei +a3blem +2ablet ab3li -ab4lo -3a2blö +a2blin +ab4lit +2ablo +1a2blö a2blu abma3s 1abn -a2bo. +2abo +3a2bo. ab2of -1a2bon -2abor +3a2bon +4abot +2abö ab3r -a3bra a4brä -2abrü -1abs -2abs. -abs2a -2absar -ab3s2i -ab3s2p -abs4t2 -2abst. -ab3sz +a2bre +ab4ros +2abrö +a4bs +1absc +1ab3s2p +abs2t2 +1abstu 1abtei -2a3bu +3abtr +2abu +abu3g4 +a2bum ab1ur 2abü 1abw 2aby -1abz -2aca -2ac1c +3abz +2ac. +2a3ca +1ac1c +2acci +ace1 a1cem -2ach. +a1cen +a1cet ach1a a1chal +a3chari +ach3as ach3au 2achb -2a1che +a1che a2ch1e2c ach1ei +ach4ei. +a2chep a4cherf -a4cherk +ach5erfa +a4ch3erh +a4ch3erl a4cherö a4ch3erw -a1chi +2achf +2a1chi +a2chim ach3l -ach3m +2ach3m ach3n a1cho a3cho. -ach1o2b -ach1or -ach3ö -ach3r +a2cho2r +ach3öf +4ach3r +2achsc +achs4el ach3s2i +ach3skr +achs4or ach3su a4cht -acht7ersc +ach4tak +ach6terf +ach8tersp +ach6t5erw ach2t1o +acht5rat ach8traum ach8träume. ach8träumen. ach6trit +acht6s5al +ach4tum a1chu ach1u2f ach3ü 2achv -2ach1w +4ach1w +a2chy a1ci -ac1in -2ack. ackmu4 ackmus3 -ack2se -ack3sl -ack3sta4 -a1cl +ack2sp +acksta4 +2a1cl a3co acon4n 2acu a1ç a1d +2ad. 2ada. -a3d2ab +4adab +ad2abr ad2ag adai4 -ada2m -ad3ama -a2d1an -3a4dap -a3d2ar3 -4adav +ad1an +3adap +4a3d2a2r3 +2adas +2adat +a2d1au +a3dau. 1a2dä ad1c 1add 2ade. ade2al -adefi4 -a2dein -2aden -ade1r2a -a2deri +a3dec +a3dee +adefi2 +2adeg +a3dell +4aden +a3den1a +ade4nat +adeo2 +ade1ra +a2d1erk 4ades2 ade3sp -ades6s +ades4s 2adf -2adh -4a3di +4adh +4adi adi3en -5adj -2ado +adi3er. +adie4sc +3adj +2adli +4admu ad2ob +ado2n +ado4na +a2dop 2adp 2adq +a2dre 2ad3rec -ad4res +ad3rei +ad3run 2ads2 ad3sz -ad2t1 -adta2 -2adu +2ad2t1 +adte2 +ad4tor +1adv +2a3dy 2a1e1 ae2b -a3e2d -a3e2i +a2ec +ae2d4 +ae2i a2ek +a2el a3el. -a2ela -a2ele -a2eli +a4ela +a4ele +a4eli a3els +ae2m ae2o3 -a3e2p -3a2er2o -ae4sc -a2et +aeop2 +ae2p +3a4er2o +a2es2 +ae2sc +ae2ta a2ew ae2x -af1a -a2fak -a2fan +2afa +af1ab +a2f1a2n a3far -af4at -a2fau4 +a2f1au +2afä +a2f1än 2afe a2f1ec -a2fent -af1erl -a2fex -af2fei +a4fentl +a4f1ep +aff4a af2f3l -af4flu +aff4th 2afi +afi6kanz +afi4kat +afi2t 2af3l -a2fö -af3ra +af1la +a1f4lu +2afo +a2f3oc +a2ford +a2f1ort +2afra +af3rau af3rä af3re +2afro af3rö +af4rü af3s2a +af3sh +af2si af2sp -2aft af2t1a +af3tat af2tei -af4t3erl +af2te2l +aft4erk af2t1o -af2t3r -aft5re +af2tö +aft3r +af2tra +aft5rei af2tur a2f3ur +2afü a1g +2ag. 2aga ag1a2b ag1a2d ag1am ag1ar -ag1au -ag2di +a2g1au +ag2del +ag2dr ag2du -2age. -age1i -age4na +4age. +age4l3ei +age4ler +2agen. age4neb a2gent -a4gentu -ag2er -age4ral 2ages -age2sa -age4sel -age4si -age2s3p +age4sam +age4s3in +age4so +ages3p ages5s -ag3esse -age6stem -ag3gl +ages6sen +age4s3ti 3aggr -3a2git +a2g1id +a2gim 2a2gl -ag4la +ag4lan +ag4las +ag3le a4glö +2agm ag2n -a2gna +ag4nat +a4gnä ag4ne. ag4nu +ago3b +ag3rat a2g3re -a2g3ri -ag4ro -agsa2 +a2gri +ag3rie +ag3rin +2ags ag3sah ag4sam -ag3sc -ags3p -ag6spo -ag4sti +ag3s4eid +ag2sp +ag7s8porta ag2s1tr 2agt ag2th +2agu a2gund 2ah. 2a1ha +ah2an ah4at +a1hä 2a1he ahe1in -a2h1erh +a2h1er2h +ahe3u a1h2i ahin3 -ahl3a4 -ah4l1ei +ah2l3a2 +ah2l1ä +ah2l1ei +ah2lel +ahle4na +ah4l3erd ah4l3erh +ahl1o2 ah2lö ahl3sz -ah4n1a +ahme1i +ah3mu +ah4n3a +ah2nä +ah3nee +ah2nef +ahn3el +ah4nerd ahner4e -ahnt2 -1ahor -ah1o2s -a2h3ö +ahner6le +ahner4n +ah2nin +ah2no +1a2hor +ah1os +ah3ös +4ahr ahr1a -ah3re +ah3r2e +ahren6sc ahre4s3 -ah3ri -ahrta4 +ahr2ti ahr4tri +ahr4tro +ahr4tun ah2ta -aht3h -ah2t5r +ah2te2l +ah2t1ex +ah2t3r aht1s a1hu ah1w a1hy -2ai -ai3a4 -aian3 +2ai. +ai1a4 +a1ia. +2aib +ai2bl aid4s aids1t -ai1e2 +ai1e4 +ai3en1 aif4 ai1fr -ai3g4 +a4i3g4 a3ik. ai3ke -aik4r +ai2lar +ail3d4 +ai2lei +ail3g ai2lo -aim2o +4ain ain2a a1ind -ain4e -a1ing -ain3sp +ai5n4e +ain3s +ains2p 3airb ai2sa a3isch. +ai5schw ai3s2e -aiss2 ais3sen ais5st +ai2sti ait4 a3iv. a3ivl a3ivs a1j +a2jat ajekt4o 2ak. -1a2k4ad +2aka. +2aka3b +akab4r +a2kad 2akal 2a3kam +2akan 2akar ak4at -1a2kaz +akat1a +aka4tak +1akaz +4akä 2akb 2akc 2akd 2a1ke a2kef -aken2n +a2k1em +a2kent +a2kes +ak2et a2keu 2a1ki +ak1ins +1akku 2ak3l +a1k4la ak4li -4ako +3aklö +a1kna +2ako 2a1kr -ak3rau +ak3res +a3k4ri 3akro3 +ak3rü 2aks ak3sh -2akta +ak2t1a2b +ak4tag +ak3tan 2aktb -ak3te -ak4tei +ak2tel +ak3ten +akt2er +2aktg 2aktik +2aktis +2aktm +ak2to4b +ak2tö ak2t3r ak3t4ri 2aktsi +2aktsp 2aktst -2a1ku -a2kun -2a3kü +2aktw +a1ku +2akun +a2kup +2akur +2akü 1akz +3akze a1la -2a5la. -al1ab -ala3ch2 +2ala. +2alabo al1af -ala2g al1age -a3lal +2alai +al1akr al1am -alami5 -al3amp al1ana -a2l1ang -al1ans +2aland +a2lang al1anz -a2lar +al1app a3lar. +al3arc a3lare -al2arm -al3arr +2al1arr +a2lart ala2s al1asi al1ass -2alat +a3lat. +al4atm +alat5t +alat3z al1au al3aug a1lä -al1äm -alb3ein +a2l1äm +al1än +al1ärm +al1äu +3albat +al2bär +alber4e al4berh al4b3er4w al2b1l -alb3li al2boh -al2br +al2bon alb3ru -alb3s +alb5st +al4dan al2dä -al2dr +al4d3erl +al4d3ern +alde2s +ald3inn +al2dra +al2drä +alds2 2ale -ale4a -3a2l1e2b -3a4l1ef -a4l1eh +4a3le. +ale4ar +a2l1e2b +al1eck +a4l1ef a2l1ei +a3l2eic a4lein a2l1el -alen1 -al3ends +5a2lema +a2l1e2mi +4a3len. +alende4 +al3endr +a4l3ends a2leng -a3lentf +al2enn ale2p al1epo -al1erf -a2l1erh -al3erl -3alerm +4aler. +a2l1erb +aler2e +a2l1erf +a2l1er2h +aler4kl +a2l3erl +al1erm +aler4mi +a2l1er4r +al2ers a2l1ert -3alerz -a2l1esk -ale4t -al1eta -al1eth +3a4l3erwä +4ales +a2l1e4sk +a2less +a4leth a2l1eu -a4leur -3a2lex alf4r 3algi al2gli +al3glo 1algo +3algor +alg4r 2ali -ali4ene al2imb +al1imm ali4nal +al1ind +alin4ge +a2l1in2q al1ins -a2linv -alk1ar +alken1 +al2klö al2kne +al2kof 1alkoh alk3s2 -al2l1ab -alla3d +al2lab +al3la3d +alla4me al2lan -al2l3a4r +al2l1a2r al6later -al2län +al2lä al3läu +al3le. al4lec +3allee alle4gi al4leh -al5lein al3lend -all5erfa +all3erk +aller4z al3les alle3se al2leu -1allgä +al2lid alli5er. alli7ers. al2lob al2lo2c -al2lo2k -al4lo2s +al2lop +al2lo2s al2lö2 all3öse al2luf allu4s al2lü4s +al2map +al3mas al4m3ast -3almb -2alo -a2l1o2b +almo6de. +2alo. +a2l1ob 3a2loe +a2l1of +4alog alo2ga -al1orc +alo2gr +al1ont +al1ort +2alos a2l1ö -al3öf al2ös +3alp. 3alpe. 1alph +al2pho +alrat4 +al3sak +al6schei +al4sh al3skl -als2to +al2stu al2sum -al3sun -al4tak -al3tar -alt3eig -al4t3er3f +al2t1ak +alt3alg +al2t1an +al2tat +al2tau +1altä +alt3eis +alt3elt +al4temu +al4t3er5f +al2teu +al2tid +al2tin alt1op al2tö -al2tri -alt3ric -al2tro -alt2se +al4t3rat +al2tre +al2t3ri +al2t3ro alt4stü a1lu -al2uf +alu3b4 +al2u3f +alu3g +al1u2k a2lum al1umb -al1ur +a2l1ur +a3lus 4aly -alzer4z +al2zar +al2zau +al3zen +alz4erk al2zw -2am. -2am2a -amab4 -amad2 +am2a +ama2ba +ama3d2 ama3g +2amah +a2malg +2a3m4an +2amar +ama4sta +1a2maz 2amä -am2e -2ame. +4ame. a2meb 2amel -am4e2n1 -amer2a -am3erf -a2meri -ame3ru +am2e4n1 +amen6s5pr +ame3r2a +amera3u +a2m1erf +3a2meri +ame5r2u +2ames a4mesh -a3met -a2mew -2amir -ami3t2a -ami3ti +2a3met +2amf +a3mi. +a3mie +ami2k +2a3mir +2a3mis +2amit +2amk 2aml 2amm. +am2mab am2ma2c 2ammal -amma4n +amma2n am2mar am2mas amma4sc am2maß am4ma4te -am2mä ammen8ge. +ammes3 +am2mid +ammi2e am2min am2mit -2amml -am4mod -2ammt +am4mo2d +am2m1ö ammu2 +amm3unt +am4mus am4mü amni1 a2mö -amp2fa2 +2ampe. +2ampen +amp2f1a2 +2am2ple +2ampo am3pr -2ams +4amsc am4schl +1amse +am3sh 1amt. -am2t1a +am2t1a2 am2t1ä +am2tei +amt3eig am2tel +2amtem +am4terh am4t3ern +am2t1ex +am2tis +am2tit +am2to +am4tou am2tö am2t3r -am2tu +am2t1u +2amtv 2amu +3a2mul 2ana. 2anab ana3c -anadi3 -a3nak +an2ad +anadi1 +an2ag +2a3nak an1alg ana4lin 2anam +an2a3ma 2anan +an4and 2anas -an1ath -an4atm -an1äs +a5nat. +ana4th +a5n4atm +a2nato +ana2tr +a5nats +an3aug +1a2n1äs 1anb +2anbas +2anbö 2anbu an3ch 2and. 3an3d2ac -an4d3ei -ande4sc -an2dex -an4drau -an2d3rü +and3arm +and3ei +anden6ga +an4d3ent +and5erob +ande2s +an2d1ex and4sas +and4seh +and2so +and6spar and6spas and6s5paß and2su -2andu -and1ur +4andu2 +an2d1ur 2ane an3ec a3nee an2ei. an3eif -an1e4k -3a4n1erb +3aneig +a4neis +3a2n1e4k +ane2l +an1e2mi +a2nemo +aner4fa +a3nerg +an2erh +a4nerke +4anern +a4nerz. +an4erze an1eth +3anex 1anf +2anf. +2anfab +3anfä +an3fe 2anfi -anft3s +an4fj +anf3le +4anfors +anf5rau +2anfs an3f2u 4ang. +1anga +2anga. an2g1ar -3angeb +2angas +2ange. +1angeb +1angeh an2g1ei an4g3erf -an4g3erl -an4gerw +an4g3er4h +an4g3er4w an4g3erz -2angf 2angh 2angie ang1l an2gla -2ango +ang5n ang1r -an4g3ra +ang3ra +1an3gri 4angs. -ang3sc -ang6s3po +ang4sto +angt2 1anh 2a3ni an2i3d +4anie ani3els ani5ers. +anig2 +ani3ke 3a4nim -a4nins +a4nind +ani2o +an3i4on +a4niso +anis2t 2anj 2ank. -an2k1an -3ankä +an2kab +an2k1ak +an2kan an2kei -an3kl -an4klö +2an3ken +ank5erfa +an3kes +2anki +an2kid +an2klö an2klu -an2k3no +ank3no +an4k3opf +an2kor ank1r ank3ra +an4kras ank3rä -ankt4 +an2kro +2anks2 +ank3se +2ankt4 +3ankü 1anl +2anlad +3anlag anma3s2 +2anmo 1anmu -2ann -3an3na -ann2ab -3annä -an3n2e -ann4sto -an1od -a3nol +2ann. +1annah +an2nar +an3ne +an4nef +an4nei +an4nene +ann2er +2anns +ann4s3p +2annt +2ano. +1an1od +2anof +2anog +2a3nol +ano2la +1a2nom +a3nom. +2anoo a2n1or -a3nos +ano2ri +2a3nos 2a1nö +2anpu 1anr +2anrö +an4same +an3s4ar 1an3s2ä 1ansc -ans2en -an2seu -2ansk an3skr -an3s1pa +ans1pa +ans3pon 1anspr +1anst an3s2z 2ant. -an2t3a4r +ant3ar +anta4re +an3t2ä 1antá -1antei -3antenn -an3t4he -1anthr -2anto -anton4 +3antei +an3tha +2antie +3antise +anton2 3antr ant3rin -an2tro 1antw -2a1nu -anu1s +2anu +anu3r +anu3s +anus3s a1nü 1anw -2anwet +2anwi +an2zä 2anzb +2anzd 1anzei +anz3elf anze2n +2anzes 2anzg +2anzh +anzi2d an2z1i4n +2anzk +2anzm +2anzr 2anzs +2anzt 1anzü +3anzün +2anzv 2anzw -an2zwa an2zwi +2anzy 2ao -ao1i4 +aof4 +ao3i4 a1op +aopf4 a1or a1os3 -ao3t2 +aost2 a3ot. -a1ö +ao3t2s +2a1ö2 a1p -2ap. -2a3pa -2ape -a2pef +4ap. +ap4a +apa3b +a2pe. a3pel a2pé a2pf ap2fa +1apfel +2apfes a3pfl -a3phä -a2ph3t -2ap3l +a2pht +2api +2apl ap4la +a3plä +ap3le +ap3li ap2n +3a2pos a2pot -ap2pf -3appl +1appro 2apr -3apri -ap2str +ap2so +ap4ster +ap3t2 2a3pu -2aq 2ar. a1ra a3ra. ar2ab +2ar3abb +ar3abf ar3abt ara3d2 -a2r3al +ar3adr +ara3ge +2a2r3al +a3rale a3ra3li +a3ralo 2aran a2r1ang -a2r1ans a2r1anz -a2r3app +2arap +a4r3app 2a2rar +ar2asy +4arat a2r1au a1rä +ar1äs 1arb 2arb. -4arba +2arba +ar2bak +ar2b3at ar2bau -ar2bec +4arbef +ar4b3ein 2arbek 2arben +2arber 4arbi -ar2bl -2arbr -ar2bre +2ar2bl +2arbo +2arb1r 2arbs2 -2arbt +arb3se +arb3sk +arb3so +2arb3t2 2arbu -ar2b3un 1ar1c -ar2dro -2are +2archl +2archr +ar2dau +arde4i +ar2dop +ar2d3r +ar2du +2are. a2rea +are5aler +a2reb4 +aree2 ar1eff -a4reg +a2reh ar1ehr +2arei +a3rei. +ar1eid +a3reie +a3reih +areim3 a2rein +arein4b +arein4s +arein4t +a2rele 4arem -a3ren 4aren. +aren6sem are3r2a -ar2erf -a2r1erh +arer2e +a4r3erei +a2rerg +a2rer3h a2reri +a2rerk +a2rerl +a2rert +ar2erw +2ares +ar2et are3u -ar2ew -2arf -ar2fä +a2rev arf1r -ar2f3ra +arf3ra +arf2sp +4arg. +ar3gan ar2gl -ar2gn +ar4gn +2arg4o ar3g4r 2arh -2a3ri +2ari ar2ia -ari3e4n +a2rid +ari3e2n ari3erd ari3erg -ari5ers. -ar1im arin3it -a4r1int -a4rinw +ar1int +a3r4io +ar2ir +ar4is +ari2su +a3riu ar2kal -ark3amt ar2k1ar ark3aue -ar2k3l +arker2 +ar2kil +2ark3l ar4klag +ar2kle +ar2klo +ark4lö +ar2koa ar2kor -ar4k3ri -ark3sa +ark3s2a +ark2se ark3she +arku2 ar2les -2arma +ar3mad +arm1au ar3m2ä -ar3m2or +ar2m1eg +ar2m1ei +arm2or +ar2mum +4armü +4arn ar2nan -arn2e -2a1ro -ar1ob -a2r1o2d -a2r1of +arn2el +ar3ni +a1ro +arob2 +4aroc +ar1o2d +ar1of +aro2fe +2a3rol +aro3m a2r1op a2ror +1a2rou +a2r1ö4 2arp -2arr +arr1ac ar2r3ad -ar2rek -arre4n +ar2r1as +ar4rek +arre4n1 ar2rh -arr3he -2arsa -ar4schl -arse3 +2arri +ar2r3or ar3s2h -2arsi +ar3s2i +ar3sse +ar2tau +2artb ar3t2e +2artei artel6li6 -ar2the -artin2 +2artex +art2i 2arto -ar4t3ram -art3re +art3r +art4res +ar2tri 2arts +art3ske 2artuc +2arty 2aru -ar1uh +a2r1uh ar1um +a3rumm a2rü 2arv arwa2 -2ary +2a3r2y +2arza +ar2zau ar2zä 2arze +2arzi +ar2zö 1arzt +arz2t3r +2arzu ar2z1w +2asa +a4s3aa as2ad -as1ala -asas2 +a4s3af +a3s2al +asal2t1 +as1am +as3art +asa2s2 asa3sse -as3au +as3at +asau4f +a4s3aug asau2s1 +as3ät a2sca a4schec -asch3la +a4schef +a4sch3ei +a6scher6g +as4chi a2schm +2ascht a3schu -4a3s2e +a4schum +2asd +4a3se a4seb -as3e2m -a5s4es +a4sec +a4s1ef +as1eie +a5sen. +ase4na +ase4n3o +asens2 +asen6sem +as1ent +as2er +as4erd +ase2re +aser6geb +a4s3erke +as4es +ase2t +as1eta a4sex -2asg -4ash +2asf +2ash a4s3ha -as4hi +as2hi +as3hir +2asig +a2s3i2k +2asim asin2g -4a5sis -asi4st -a3skop +as1inn +2asis +as3ku a4s3l a4sn -a1so1 -as1o2f +2a1so +as3ob +as1of a3sol +a3som +aso2p as1or +a4soz as1p +as3pe aspek6to +a4spel a4s2ph as2pi +as3pik +as4pin +as3pio +a4spir a4spl -as2po -a1spu -as3s2a +2aspr +as2pra +as3sa +ass2a3b +ass6aus. ass2e -as2s3ei +ass3ein as3sel +asse3le as3ser asserma6 -as3s2i -as2s1p +a4ss2i +as3sin +as3ski +as3so +as2spo +as2spr as4st -ass1ti -ass1to +as5sta +as5stei as5str as5stu 2asta -a4stec +a4stab +a3stä +a4s1tec +as2tee +ast2el +a4stemp a4s3tep -as2ter -a4stese -2astr +ast2er +a4st3ese +as2tex +a4s2th +ast2id +as2to +a2stoc +ast3orc as4trau -a4strä -ast3räu -a2s2t3re +a2st3re +ast4ren +a6stritt +a3stro a4strol +ast5roll +a4s1tub +a4stuf a2stum -a3su -asu2s +2a1su +as2ur +a3su4s3 a4sw aswa2s -3a2syl -aße2 -aßen3 +1asy +3a4syl +2asys +as3z +aße4 +aß2en3 +a2ß1er +aß2th 2a1t -at1ab +4ata +at1abe +at1abr at2a1f -at4ag -a2t1akt -ata3l +a3ta3g +at2ago +a3tah +ata3la a3tam +at1ang +at3ank at1apf -at1au -a2taus -a2tä +at2ast +at3att +a2t1au at1än +4atb at2c a2teb -ate1c -ateien4 +ateien6d at1eig -a4teli +3a2teli +a3tell +3atemg at2en +ate4na +atens4 a2tep +4ater +ate3r4al +ate3ran +at4ere +atern2 ate2ru -atex3 -at2h -at3ha -athe1 +at2eu +a2tew +4atha +at3hag +at3hal +a3t2heb +ath3in. 3athl a4thr +at2hu +at3hü 4a3ti -atingma5 +ati4kab +ati6k5erw +a4tinf +at2is +ati2sa +ati2se +a4tiso +atis3s +ati6v5erf +3atla +4atli 3atm +4atma +4atmä +at3mu 4atmus -ato4man -4ator -a2t1ort -a2t1ö -4atr -atra4t -at3rä +a2t1ob +a3tod +a3tog +a3tol +3a2t4om +atom1e +ato2mo +at1op +a3tor +at1ort +a3tos +a3tra. +atra2t +a2t3rau +a2t3rä at3re +at3rin at3rom +a3t4ron +at3rot at3rü at2sa at4schn at2se -at4set +ats1e2h at2si +ats1in +at2s1o ats1p +ats3tät at3ta 3attac -at4tak +at4tad +at2ta2g +at4t1ak at2ta2l -att3ang +at4tang +at4tar at4tau at2tä -at4tec +4atte. +at2tec at2tei -at3t4hä +at3t2el +at4temp +4at5ter +attes2 +at3thä +4atto +at2tob at2t3rä -att3s -at3tu +att3s2 +at3t2u +at2ty2 +at4typ +4atu atu2n -atz1er -at4zerk -at4zerw -at2zi -atz1in -at2zo +atze4l +atz3ela +atz3elt +at2zem +at2z1er +a3tzere +at2z1i atz3t2 at2z1w a2u @@ -1360,146 +2163,225 @@ a2u 2au1a2 2aub au2bab +au2ban +au2b1au +au2bei aube4n +au2beu +au2blä au2bli au2blo -4auc -auch3ta +au2blu +aub2si +aubu4s +2auc au2dr 2aue aue2b -au3en. au2ere -au5erein +aue3rei auer3ö +au5erst. +au3ert au2fa +auf1ak auf1an +aufas2 3aufber 2aufe. 2aufeh +4aufen. +3aufent auf1er -au4ferk +au4fer4k +au2feu auff4 -3aufn -auft2 +auf3ind +1aufla +1aufn +2aufo +auf3ski +auf3t2 2auft. +5aufzeic +3aufzug +1aufzü 2aug +au2ga +au3g2ar +4augeb 4augeh +4augel +aug2er +4augl +4augr +au3gu 2auh au3ha -au2hu -4au1i +auh1u +2au1i au2is -2auj +4auj +auk3t aule2s +aul4les au3lü 2aum au2mal -aum2ei -au2m1e4r1 +aume4n +au4m3ent +au2m1e2r1 aum3eri +au2m1id +au4mil +au4mit au2m1o +aumo2r aum3p2 aum3s2 +au4mun 4aun au3n2a aun2e -au4nei +au4n3ei au2nio -au1nu +au2no +au3nu a4unz 2aup2 -aup4ter -2au3r2 +2aur2 +au1rh +au4sag au2s1ah ausan8ne. +au2sas au2sau -4ausc -au4schm +2ausc +au6schmi 1ausd -2ausen +2ause. +au4s1eh +2au3sen +au4s3erb +au4serf +au4s3erk aus3erp -au4s3erw -1ausf +au4serw 1ausg +au2sin +au4sis 1ausl au2so +aus1or au2spr 1ausr -1auss2 +auss2 +3aussag au3sse aus4se. au8ssende aus4ser -au2sta +aus4ses +au2st2a +aus3tau 2auste au4stec aus3tie aust2o +au2stö aus3tri -1ausü +3ausü +1ausw 1ausz -au3ße +auße2 a4ut +au2tab au2t1äu -au4ten4g +2autb +au2t1e2l +au3ten. +auten4g au4t3erh +aut5ero +au3tet +2autg +au2thy 1auto au2trö 2auts 2auu +2auv +auve4 2auw 2aux 2auz auz2w 2a1ü -2a1v -a3v4a -ava3t4 -a3vi -a2vr +a1v +av2a +a3vang +ava3t2 +avener4 +2avi +a2v3r av2s 2a1w -awi3 -awi1e +awi3e +a2wr a1x ax2am -ax2e -axi2s +a2xans +a3x2e +a3xid +a2xio +axi2s1 2a1ya a1yeu +ayma2 +ay1of aysi1 ay3t -2a1z -a3z2a3 -az2i +a1z +az4a +a3za3d +3azal +a3z2i az2o -az2u +a3z2u +az2zen +az2zw ä1a -äand4 -ä1b -ä5be +1ää +2ä1b ä2b3l äb2s +äbte3 +ä1ce ä1che äche1e +äche4n ächenma5 ächenmas8 ä1chi äch3l ä2chr +äch4sa +äch2s1o äch2sp +ächt4e ä1chu -äck2e ä1d ä2da ä2d1ia ä2dr äd2s +äd3te 2ä1e -äf2e +äe4k +ä3eu +äe2x äfe4n -äf2f3l +äf2fl äf3l äf3r äf4ro @@ -1507,180 +2389,246 @@ az2u äft2 äft4s ä1g +ä2g1a +1ä2gä +ägd2 ä5ge -äge1i -äge2ra +ägen4e +äge2r3a ä2g3l äg2n ä2g3r äg4ra äg2s -äg3sc +äg3sta äg3str 1ä2gy äh1a -2ä3he +2ä1he +äh1ein +äher8gebn +äher3t ä1hi +äh1in ähl1a äh3l2e äh4l3e4be -2ähm +äh5ler +4ähm äh3na äh3ne 1ähnl 2ähr +äh2rel äh3ri 2äh2s -2äh3t +2äht ä1hu äh1w 2äi ä1im -ä1is. +ä2is +ä3is. ä3isch. -ä1isk +ä3isk ä1j ä1k -ä2k3l +äka2la +äk3l +ä2kle +äk4li ä2k3r ä1la älbe2 -äl2bl -ä5le +äl4bl +älk3 +älks2 äl2l1a äl2p3 äl4schl +ält2e +älte1i ä1lu +2äm4a3 +ämer2s ämi3en 2äml äm2ma4 ämmas2 ämoni3e 2ämp +ämp7f4e äm2s ämt2e +ämter3 2än. -än5de än2dr -2äne +2än2e äne2n1 -än2f5 +2än2f3 änft2 -2änge -2än2g3l +4än3g2e +änge4ra +2än2gl +äng3le än2gr +ängs2 äng3se 2ä3ni -änk2e +än3k2e än2k3l än2kr -änn4e2 -äno3 +2änn +än3n4e2 2äns +än4s1a än2s1c äns2e -änse3h 2änz ä1on +äo3s2 ä1pa +1äpfel äp2pl äp2pr äp2s1c 1äq -ä2r3a2 +ä2r3a4 är4af är1ä är2b3le är1c -4äre +2ärd +ärde4s +2äre ä2r1ei +ä2r1e2l +äre2m +är1emi äre2n -ä2r1ene -är2gr +ä2rene +ä2rerh +är2es +är3ge +ä2r1ind är1int -är2k3l -är4ment -ärme3s -är1o +är3ke +ärm3arm +ärm3at +ärme1e +ärm3ent +ärno2 +är1ob +är1of +är1op ä1rö +är3re ärse2 är2seb +är4seh +ärs1er är2si +är3spu +2ärt ärt4e är2th ärt4s1 ä2rü +1ärz +ärz3te +är2zu är2zw ä1s äs4c -ä3s4e -äse3g2 +2ä3s2e +äse3g +äse1i4 +äse5ref äser4ei äse4ren äser2i -äse3t ä5si -äskop2 -äskopf3 ä3s2kr ä2s1p ä3s2s -äs4s1c +2äs4s1c äss2e -äss3erk +äss5erkr +äs3sern +äss5ersa +äss3erw ä5sses +äs4sh äs4s1t -äst2 -äs2te +äs4t4e +1ästh ä2str ä1ß +2äßc äß1erk -ä2t1a2 -ä3te +äß1ers +ä2t3a2 +2ä3te +äte3a +äte1e äte1i -ätein2 +äte3l2 äte2n -ä2t2h +äteo2 +äter4bl +äte3se +ät2et +ä2th ä1ti +ät1id ä1to ät1ob ät3r -ät2sa +ät4sa +äts3au ät2sä ät4schl ät4schr -ät2s1i +ät2s1i2 äts3l +äts1or äts1p -ät2s1t -ät4s3te -ät4sti +ät4s1t +äts3te ät2tei +ätte4n ät2tr ä1tu +ätze3l ät2zw äu2b3l äu2br äu1c +äu3d äude3 -äu3el -ä2uf -äuf2e +äuder2 +2ä2uf 1äug äu4g3l 2äul 2äum äu2ma +äum3p +äumpf4 äum2s1 2ä2un äun2e -äu1nu -2äu3r +äu3nu +2äu3r2 +äure1 äu1s 2ä3us. -äu4schä +2äusc +äu4schi äu4schm -äu3se +äu6schü +äu3s2e +äuse1i ä3usg ä3usk ä3usn @@ -1688,534 +2636,843 @@ az2u äu3s2s äuss1c 1äuß +äut2e äu2tr -4ä1v +ä1v +ä2vi 1äx ä1z +ä3ze â1t á1n +5ba. +b2aa +b3a2ba +2babf +2babg ba2bl -2babs -bach5t4e -backs2 +ba2br +2b1abs +bach7t4e +back3er +back3s2 +ba3d2e +bade1i +2b1adel +2b1adl +2b1adm b1a2dr +ba2du 2b1af -bah2nu -bahr2e +3bah +bah6nene +bai3d bais2 +b2ak ba2ka ba2k1er ba2k1i -bak1l -bak1r -ba2kra -3bal -bal2a +ba2k5l +ba2k3r +ba2lab +ba2l1ak +ba3lal +ba2lau +baler2 +ba4l3erk +balk4a +balke4 bal4lan balle4b +bal4l3ei bal6lerg +ball6erk bal4li4g -bal4lok -bal3lö3 +bal4lo4k +ballö3s 2b1am +b2a3ma ba2me +4bamt ban2a 3b2and +band1a +ban4dal +ban4dan +ban4dar +ban6deng ban2dr ba3n2e +2banf b1ang ban3gl -ban2k1a -ban4kl +ban4k1a +banker4 +ban2kl +ban2kn ban2kr +ban2ku 2banl +b1anna +ban2o 2b1ans -ban3t +b1ant +2banw b1anz -bar3b +ba2r3ab +ba2rad +bar3ast +ba2rat bar3de ba2rei -bar2en -ba4r3ins -bar3n +ba3r2en +barer5ei +barer4t +barf4 +3bars +b1arz bar3zw -3bas +3b2as ba3s2a ba2sc +bas2i +bas4sa +bas6st +bas4t ba2str +ba2ß1 ba4t3ent +bat2o +3bau. +bau3b bauer4l bauer4s -bau3g +bauer4w +bau3fa +bau1fl +bau1fr +bau3g2 +b2auk +bau3r bau3s2k -bau3sp +bau3sta +b1a2x ba1yo 3b2äc bä1ch -b2är +3b2äd +2b1äh +b2äl +2bärz b2ä4s3 +2bäug 4b1b +bbe4n bbe4p b4be2se -bb3ler +bb3le. bb2lö +b3brec b3bru bbru2c bb2s bbu1 -2b1c -bch2 -2b3d4 +4b1c +2b5d4 +bdä4 +bdän3 +bdome4 1be. 3bea +be3ab be3an -be3ar +beat2m +be3au +be4au. 3beb -b2ebe +b1ebb 1bec be1ch -be2del +2becht +2b1e2del bedi4 -be1eh +be1e2h +bee2l +be3ela +bee4rei +be1erh be1erl +be1ert be1eta -3bef4 -be3g2 +bef4 +2b1eff +be3g4 +be2he. +beh5ri +bei3b 2b1eier bei1f4 bei4ge. -beik4 -beil2 -bei3la +beige4l +beige4p +bei3k4 +bei3l2a 2b1eime -be1imm -b2ein be1ind -be1in2h +be1inh +bein6hal +bein4hi bei3s2 +bei5st +beit4e beit2s +beit4sk +beit4sp 3bek 3bel +be3lag be3las bel3d be3lec -be3lei +4be2lek be2l1en +bel3ere be2let -be3li +bel3f bel3la -bel3lä +belle4n3 bel3li -be2l3ö +bel3om +be2lor +be2löf bel3sz -bel3t4 -1bem -bema5sse -bemas8sen -1ben. +belt2 +bel4un +1bem4 +3b2em. +3b2e3ma +2b1emp +2bemul +1ben +3ben. +be5nabe ben3ar be4nas -be4nä -ben3dor +be4nat +be2nä4 +bend3s2 +b2ene be3nei +be4n3end +be4ners +ben2eu 3beng -be3n2i +be2nid +be4nis ben3n -ben2se -ben4spa +5benp +b2ens +ben4s3pa ben4spr benst4 -ben2su 3bensv -2bentb -b2enti +3bensz +2b1entb +2bentd +4benteu +2bentf +ben3th +ben6thei bent4r -b1ents -2bentw +2b1ents +2b3entw +be2nu ben3un -ben3z2 +b2en3z2 be1o +2b1epi +2bepoc be1ra -be2rab +be2rak +be2r3am be2ran -beras4s +bera4s berb2 -berd4 -ber4ei. +berbla4 +ber3d +be2r1e2b +be4reck be4r3eiw -be4rerk -bere4s -ber6gan. +bere2m +be4rene +ber4erg +ber4erw +bere4sc +bere2t +berf4 +ber4g3af +ber4gal +ber4gli ber4hab +beri2d ber4in. +be5r6inne +berin4s +be2ri4o ber3iss +ber3ko +ber3kr bermas4 berma7sse -ber3na +ber3n2a +bern2e b1ernt -be1rop -berö4 +be2rö4 +3bers. +ber5se ber3st4a -be3rum +ber3t2a +bert2e +bert2i +berz2 +ber3ze ber2zö -3bes -bes2a +3b2es +be3sa +bes4abb +bes2am +be4sap +be4sar +bes2au +be2sep be2s1er -be5slo +be2s1id bes2po +bes3sa bess4e b3esst. bes3sz beste2 be6stein +bester4 +be6sterh be4s3tol -be4stor +be4st3o4r best4r +be4strä +be4s3tur +be2sur be3s2ze 3bet -be2tap +be3tam be3tha +be3thi bet2to +be1un be1ur -3b2ew -2b1ex -1bez -4b5f4 +3bev +3b2ew2 +2b3e2x +3b2ez +2b5f4 bfal2 bflö4 bflös3 2b1g2 +b5ga bgas1 bga4st +bga4su bge3 +bgel2e +bge5n bges2 2b1h2 -bhut2 +b5hä 1bi -bi3ak -bib2 +bi1ak +bi2ar +3bib2 bibe2 +biber1 +bi2c +bi3do +bieres4 bie4str +biet4s 3bietu +biga1 bik2a bi2ke. bi2kes +bi2kre 3bil -bil2a -bi2lau -4b1illu +bil4deb +bi2lei +4billu bi2lu +2bimp 2b1inb bin2e -2b1inf -bin3gl +bine4n +b1inf +bin4fo +bin2g3a 2b1inh +bi2n3ok +bin4ol 2b1int -bi2o1 -bio3d -bi3on +2b1inv +bi2o3 +bioi2 biri1 -bi3se +3bis +bis2a +bi3si b1iso -bi2sol bi2sp bis4s1c -bis3si +bi3sta +bi2s1to +bi3str bi2stu bi2stü b2it. b2ita b2ite -bit4ta4 +b2iti +bit4r +bit2ta2 bi2tu bi3tum -b2i3tus -biz2 -4b1j +bi3z2 +2b1j bjek4to -2b1k4 -bl2 +2b5k4 +bl4 2bl. bla3b4 +2b3lac b3lad -b5lag b2lanc -3blat +blas3er b2latt +b2lau. +b3laus 2b3law +2b1län b2läse +3blät b2le -3blea +3ble2a b3leb 3blec -2b3leg -2bleh +b3leg +4bleh +b4lei. 2b3leid -4b3lein -blei7s -3blem -3ble4n +2bleih +b3lein +blei3s +2bleit +ble3l +ble2n +b3lenk b3lese +2blesu ble3sz -b4let +3blet b3leu 2blich 3blick b2lie -2blig -b4lis +2blief +4blig +b2lind +2b5ling4 +b2lis +2blis. b2lit -3blitz +b3lite b2lo -b4loc +b4lo. +3b4loc +b4loi b3los2 blo3sse -blös4s +3b4lum 2blun +b2lus 3blut +blut1o 3blü 2b1m bmas2 -4b3n2 +4b5n2 +bnas4 bni2 bnis1 bo4a bo5as -b1ob3 -bo2bl -bo2br +b1o2b +bo3ben +bob3r bo1ch2 bo3d2 boe1 -bo2ei +bo2e3i 2b1of bo3fe +bo3he +boh2ra +boh3rer +boh2u bo1is -bo2l1an +bo2lan +bo2lau +bol3le 3bon. -bond1 -bon2de +bo3n2a +bon2da +bon2d1e bo2ne 3bons +boo4l +boo2ti b1op -bo1r2a +3bor. +bo1ra +bor2an +bo2r3as bo4rä +bor2da bor2d3r bo2rei bo4rig +bor3m b1ort -bor2t3r +bor4ter +bor6t5rat +bo4ruh bo2sc bo3se bo4s3p +3bot bote3n4e bo3th +bot2so bot2st +bot3t +bo2xo +b1oz bö2b3 2böf -b1öl -2b1p2 +2b1öl +2b1p4 bpa2g 2b1q b2r4 2br. b4ra. 2b3rad -b4rah +2b4rah b4ra3k -bra4sp bra4ss brast4 +2b3rat. +brat3er4 +bra6terg +2b3ratg 3brä +4bräd brä4u 2bre. -3brea 6b5rechte +2b3red 2b3ref 2breg b3reif -b3rek -3brem +2brek +b4rem +b4ren. +2b3rent +2breo 2b3rep b4rer +b4res. +b3rest +b4ret +bret6t5en +b4rez +bri2da +brie4fa 2b3riem +b4rien bri2er +b3ries +2brigk +b4rina +2b3rind b4rio -bro1 -b3roh +b4risc +2briß +b3ritt +brob2 +2b3roh 2b3rol +bro2ma b4ron +2b3rost +bro2tr +brot3t4 +2b3rou +3b4rö b4ruc +2bruf +b4rum +2b3rund bru4s -brust1 +brust3 bru2th 3brü +4b3rüb brü4ss -4b1s +2b1s b2sad -bs3ar +bs1amb +b4samt bsas2 bsa3sse -bsat2z -b3sä -b4sär +bsau2r +b4s3är +b3säu b5sc -bs2ca +bsch2a b6schan b6schef -bs4cu +b6sco b3se. bs1e2b b3sel. -bs1ele bse2n1 b3sen. -bs1ent +b2s1ent bs1er -b2serf bs3e4r3in -b2sers b3ses -b3set +b2sim bsi2t -b4sl +b4s3ki +bs3kr b2s1of -bs1op +b3s2oh +b3sol +b4sop bso2r b2sö b3s2pi bs2pl -b3s2pu -b4ss2 -bs2t +bs2pu +bss2 bst1a2b -bst3ac -bs3tag -bst1ak -bs3tät +bs2t1ak +bst3ank +bs2t1a4s +bs2tau +b3stä +bs1tät +bst3emi bst1er b4stern -b2s3tip +bs2t1h +bst3ink +b2stip b3sto b4stob b4stod +b4stor b3stö +bs2tr b3stra b2s3trä -bs3treu -b2st3ro +b4s3treu +bst3ro +bs2tu b3stü b4stüb b2s1un +b3sz +bs2zep +bs2zi 4b1t b3ta bta4st3r b5te -b2th +b2t1h +bt2i +bti2s bt4r +btran2 bts2 btü1 +bu4chec +bucher4 +bu6ch5ers bu3ches bu2chi +buch3s4p bu2e3 bu2f bug3 +bu2gr +bull3a +2bumf 2b3umk +2buml +2b3umr +bun4a +bun4d3er bunde4s -b3ungn +b1une +b3un3gn +2b1unh +bur1c +b2ure b2urg -bu3r4i -4burn +burg1a +bur4gan +bur4gar +bur4gin +bur2gr +bu3r2i +2burn +b3ursa burt4s bu2sa -bu4s3cha -bu4schl -bu4sch3m -bu4schw -bus1er +bu2sc +bus3cha +bu3sche +bu6schei +bu6sch5el +busch3w +bu3shi bu2si bu2s1p -bu4s3ses +bu4sses +bussy2 +buster4 bu6s5term bu2s1tr -bu2s1u -bu3tan +bu2su +but2a +buto3re +2büb bü1c bügel3e bü3s4 2b1v -2b1w -bwel3 -by1 -by3p +4b5w +3b2y1 +bya4 +byo2 +by3p2 bys2 -2b1z2 +2b1z4 +b5ze bzeit1 bzu1 -1ca -2c1ab -ca2ch +1c2a +cab4 +ca3bl +3ca2c ca2e3 -ca3g4 +ca3g2 ca1h -cal3t -c4an +cal2a +cala3b +cal2f3 +cal3t2 +2can +cana3 ca2pe -3car -car3n +car3n2 carri1 +car3tr ca3s2a3 -cas2t -ca3t4h +ca3t2h ca1y2 cä3 cäs2 +c1b 2cc c1ce c1ch2 c2d2 c3do 2cec -ceco4 1ced ce2dr +ce1e 2cef ce1i +ce3in 2cek -1cen -ce1nu +3cels +cen3a +ce3nu +cen3un +ceo2 1cer -cere3 +cer3a +cere1 +cere3u +ce3r2i +ce4ris ce1ro -ce3s2h -1cet -2ceta +ce3s4h +cet1am ce1u 1cé c1f -c4h +c1g4 +c2h 4ch. 2chab -ch3a2bi +ch3a2b3i +2chac +2ch1a2g +ch1ah 2ch1ak -ch2anb +chan4a 3chanc +chan3f ch1ang -ch3anst +4chanl 2chanz 1chao 2char. 1chara +3chard 3charta cha2sc +chasi1 1chato +2chatt +2chatu +ch5austr +chau3t +ch1äh ch1ärm ch1äs 1châ 2chb 6chc 2chd +che3b4 ch3e4ben +ch3echt +ch1edi +che2el 1chef 3chef. che4fer @@ -2224,2839 +3481,4516 @@ che4fer ch1eim 4chelem che4ler +1chemi +3chemik +2chemp +che4neb +che4nid +che2no 4chents 4chentw -cher3a -che3rei +che2r3a +4ch3erbs 6chergeb +4cherke cher6zie -ch3ess -2cheta +ch3es2s +4ch1e2ta 2ch3e4x 1ché 2chf 2chg 2chh -1ch1ia +1chia chi3na 4chind 3chines 2chinf 2chinh -ch1ins -ch1int +2ch1ins +2ch1int 2ch1inv +1chip. 1chiru +2chiso 2chj 2chk -2chl2 +2chl4 ch2le +chle2i +ch3lein +4chli ch2lu -4ch2m +4ch2m4 2chn4 chner8ei. ch2neu 2chob cho2f ch1off +chof2s ch1oh -chol2a +cho3l2a ch1orc +cho4rei +ch1ori +ch2os +ch3öl +2chön +3chör 2chp ch2r4 +2chra +ch3rad +chra3g 2chre chre3s ch3rh -1chron +2chrit +3chromo +3chron +ch5ros 4chs ch4stal -chst3ri 2cht +ch2tru 2chuf 2chuh 2ch1unf +2chunm 2chunt +2chur +ch1urs +2chut 2chü 2chv 2chw -5chy +1chy 2chz ci1c ci1es -cil3l -ci2s +c1ind +cins2 +c1int +ci2s1 +1ci3t2 c1j -4c4k -ck1a -ck3an +4c2k +c4k1a +cka2b +ck2ad +ck2ag +cka2m cka4r1 ck1ä -ck1ehe +ck1ef +ck1eh ck1ei +cke4na cke2ra ck2ere -ck1erh +ck3er4hö +ckerk4 +cker6lau ck2ern -ck1er2r -ck1ese -ck1id -ck1im +cke2ro +ck1err +ck2et +cket2t +ck1i2d ck1in +ck4is ck3l -ck3n -ck1o2 +ck5n +ck3o4 +ck3ö2 ck3r -ck4stro -ckt2e -ckt2i -ck1um3 +cks2al +ck4spen +ck3te +ck3t2i +ck1uh +ck1um ck1up -c4l2 +c2l2 cle4a clet2 -clo1 +clin2g +cli2p1 +clip3a +clo1c +clo3f 1clu +clu4b c2m2 +c3me +c3mu 1co co1ch -co2d2 +3co2d2 +co4de. co3di -coff4 -coi2 +cof3f2 +coi4 co1it co2ke -co2le -col2o +co3la1 +co2leu +co3l2o com4te. comtes4 con2ne -co2pe +co2o +coo1p +co1p co1ra -cor3d -co3re +cor2da +co4re cor3t cos4 co2te +cou3si 2cp c1q -1c4r2 -cre2 -cre4mes -cry2 +1c2r2 +cra4s +c3rä +c4re2 +2cree +cre4me +2cri +cros4 +2cry 2c1s2 -c2si +cs4f +c4si +cst2 4c1t -cte3e cti2 -cti4o +cti4o2 +ction5 ctur6 -3cu +1c4u +2cua +cu2e cu2p3 +cup1e cussi4 -1cy +c1w +2cx +3cy c1z 3da. da1a 2d1ab +d3a2bak d2abä -da2ben -3d2abl -da2bre -dab4rü -2d1ac -d2ac. +d2abe +d3a2ben +d3a2bi +da3blu +d3a2bo +dab4ra +da2bri +da3brie +d2ab4rü +d1ac dach3a da2cho 4d3achse +2d1ad +da2de +da2do +da2d4r d1af +2daff +da1f4l +dafo4n d1ag -dagi2o +dagi4o +dag2o +da1h dah3l -da1ho -3dai2 +dail5 da1in +2d1air da1is +da2kro dal2a -2d1alar +2d1a2lar dal3b2 +4d1all +da2lop da3lö -d1alt +2d1alp +d1al3t2 +2dalte +da1lü +3dam +da2mei d1amma -2d1ammä +4d1ammä damo3 d2amp -dampf8erf -2d1amt -d2an. -2d1ana +damp7f8erf +4d1amt +3d2an. +d1ana +da2nan +da4n4at +2danb dan4ce. -2d1an3d2 -d3anei +d1and2 +2danda +d2andy +3dane +4d3anei +2danf d1ang -2dange -3dank -dan4kl -dan5kla +2danh +dan2kl dan2k1o dan2kr +2danl +d1ann +2danna +d1a2no 2d1ans -4dantw +2dantw 2danw +d1anz d2anz. -4danzi +2danzi +2danzü 2d1ap +d2apa d2aph +da2po +da3pos 4dapp -da2r3a +d3apte +2daq +da4r1a +dara4s 2darb2 -dark4 -3d2arl -dar2ma +2d3arc +dar2d1e +dare2 +daren1 +dar3g +dark2a +3darl +dar2m1a dar2m1i -da2ro -d3arr -3d2ars -d1art -2dart. +dar4mu +da2r3o +3dars4 +2d1art +dar2th +dar2tr da2ru -d2arw d1arz -dasch4 -da3s2h -3dat -dat2a +das2 +da3sh +d1asp +das3s dat2e2 da3tei +4d3a2tel date4n -4d3atl -4d1atm -3dau3e -4d1au2f -d3aug -4d1aus -2d1ax +da2th +2d3atl +4datm +d3ato +dat2st +2d3atta +3daub +2daud +dau3e2 +dauer3e +daue6rei +2d3au2f +2d3aug +2dauk +da3unt +2d1aus +dau4ss +dau2ß +3daw +d1ax +3däc +2d1äg 2d1äh 2d1ämt +dän3a 2d1änd -2d1äng 2d1äp -2d1ärz +2däq +2därz 2d1ä2u dä3us -2d1b4 +2däx +4d1b4 +dbau2c +dbauch3 +dbe2e dbu2c dbu3s 2dc -d1ch -dco4r -2d1d2 -ddar2m +d3ch +4d1d2 +d3da d3dä +d3de d3dh d5do 1de -de2ad +dea2d +de3ar de3a2t -3deb4 -4d1e2ben -3dec +deb4 +3debü de1ch -de3e4 +deco3 +de2del +de2dit +2de3e4 +def4a +de2fa. 2d1eff +def4l deg2 +degene7 de3gl +deh2a dehe2 +3dehn de3ho 2d1ehr d1ei 3d2eic -3d2e1im +de3i4den +de3il +3d2eim +4deime dein2d -dein2s de3inse -de2l1a4g +de3inst +dein6sta +dein6sti +4d3einw +de3io +2deise +d4e1ism +dei2sp +2dekz +de2l1ac +del4ade +de3lak de4l3aug -del1än +del3änd +del3b2 +del3d del1ec +3de3leg delei4g -2d1elek +2delek 2delem -deler4 +de2len +deler2 +deler4r +2delf. 2delfm +3delik +della3d del4lan +del4lar +dell3au +del2l1ä dell3eb del4lei del4ler del2lö2 de2l1ob de2lop -de3lor -de2lö -del2s5e +del2se del2so del2s1p -del3t4 +del3t dem2ar +2d1emb dement4 de6mentg +dem5ents +de3min +2d1emot 2d1emp -d2en. +d2emu +d4en. +den2am +de2n1e2d de4n3end +de2nep 4denerg +de3n2es 4d3en4ge. -d2enh de2ni -den4k3li -den2kn +denk3li +deno2s +deno4st +dens4am +den6s5cho +dense2 4den4sem -den4s3en +den6sere den6s5tau +2dentd +den3te +2dentf +2dentg den3th +2dentn 2dentw -de1nu +2dentz +den6zers +de2ob 2deol -de1on -depi4so +dep4l +2depoc d4er. -de1rad -de2rap +der3af +de2rak +dera2n +de3rand +de2r3ap +de1r2as +de4r3asi der2bl +4d1erbs 2derdb -de2re2b +de2r1e2b de4reck +de3reie de4r3ei4s -derer3 -de3r4erb -de3r4erf -de4r3ero +5d4erem +d4eren +de4r3end +5d4erer +der4erf +derer3n +der3ero derer4t -derer6ze -d4erfi -d2erh -4der4höh -d4erhü -3derie +5d4eres +de2r3eu +derf4 +d4erfl +d3erheb +d2erhü +de2r3id derin4f +de6rinnu +derin8teg +der3k2 4derklä -der3m2 -4derneu +d4erlan +d2erm de1ro -de2rop derö4 der3r -4der4sat -der4spa -der6t5en6d +derst2 +der3sta +dert7ende. +derter6e dert4ra -6der6trag -de3ru +6dertrag +der8trage +3de3ru de4ruh de4rum +2d1erz. +2d1erzv d2es. -de2s1a -de4sa4g -de4sam +de2sa +de4s1ag +des1ah +de4s1am des3an -des1än -de4seh -des1en1 -des1et -des1in +de2s1än +de2seb +de4s1e2h +de2sei +de4s3eil +2d1esel +des3elt +de3sem +de3s4end +desen3e +de3sens +des3erm +de2s1et +de2s1in 3desk des1o de2sor de2s1p de3spe -des5s2 -dest5alt -de4stam +dess2 +des3se +des5st +de6st5alt de6stant -de4stei +de8steige +de8steins +des4tex de4stit -dest5rat -de3stri -de3stro -de2s1u +de6st5rat +de4stre +de2su +des1un +3desw +de3ta deten4t +2d1e2th 2d1etw +2d1eul +deum3 de1un de1url de3us -devil4 -d1exi +2d1e2vid +devil2 +de1x2a +de2xer de2xis -2dexp -2d1f4 +2dexpe +2dexpo +2d1f6 2d1g2 +dga4s3tr d2ge. -dge2ta +dger2 +dge3s +d2gesh +dge2t3a dge4t1e 2d1h2 -d2his +4dho +d3hu 1di -di4ab -di2ad -di4am +di4ap +di2a3s +diat4 di4ath 3dic di1ce -dich1 -dich5ter +di3chl +dicht6er +dick3el +4d3i2co +3dida +d1ide +2didee +di2den +2didy di2e -di3e2d +di3e4d +di3enb di3end die4neb -di3eni -di3ens. -di3ern -die4s3c -diet3 -die2th -dige4s +diener6l +di3e2ni +dienst5r +die2p +di3ers. +dies3c +di3e4th +3dif +3dig +dig4n dik2a -dil2s3 +dil2s1 2d1imb -2d1imp -din2a +2dimp +din4a 2d1ind +di3n2e 2d1inf +3ding 2d1inh -2d1in1it -4d3inner +di3ni +2d1inj +2d1ink 2d1ins -2d1int -di2ob -dion5s -di1p +2d3int +2d1inv +di2o3b +dion3in +dion5s2 +di3ora +dios2 +di2osk +di1p2 +di3pt +d1i2ra di4re. di2ren +di2rin di2ris 2d1irl +2d1irr di4s1a2 +2d1iso di2sp di3s4per 2d1isr dist2 di2s1to di4s3tra +di4sz di2ta -di4teng +dite1c di4t3erl di4t3erm di4t3ers +di2tin +di2tob di2t3r -dit1s -di2tu -di5v +dit3s +di2t1u +di5v2 diz2 2d1j +d2jar 2d1k4 4d1l2 +dla3g +dlap4 d3le dle2ra -dli2f +dli4f dl3m dl3s 2d3m2 -4d5n2 +4d3n2 dni2 dnis1 dni3v -d1ob -d2oba -2dobe -dob4l -d2obr +do5at +2d1ob +3d2oba do1chi -2d1o2f -doll2a +d1of +do2fe +2d1oh +do3ha +doll2 +dol3la +d3oly +3dom +do2mal do2mar -do5na +domen1 +do3mi +do4ming +4domn +do2mu +do3n2a +do5nan doni1 -do2o -2dope +4dony +2d1ope 2d1opf -d2opp -d2o3r4a -2dorc +do1r4a +2d1orc 2d1ord dor2f1a dor2fä +dor2f1i dor2fl +dor2fo dor2fr +dor2f3u 2d1org -dori1 +d2orn 2dort -dor2ta dor4ter +dor2tr d2os. -dos3s +do3se +dos2k +2dosm dost1 -do4sta -dot6h -do2t1o +dost3a +dosten4 +do3ta +do2tof do3un +dow2s +d2o3x2 d1ö dö2d -dö2l3 +dö2f +döl3 dölla3 d2ön 3d2ör dö2s1c 2d3p2 +dpass3 +dpol4n +dpo4st1 2d1q d2r4 3d4ra. -2d3rad +3d4rab +4d3rad 2drahm -d3rai -3d4ram +2d3rak +3d4ral +d3ramp d3rand +dran3k +dra4s3s 2d3rast -d3raub +dra4tin +2draub 2d3rauc +d4rauf +2draum 2draup 2dräd d4räh 2d3rät 2d3räu -4d5re. +4dre. +2d3rea d4rea. d4reas 3d4reck -2dref -2dreg +2d3ref +4dreg 3d4reh +dre2ha 2d3reic +3d4reie +drei3s d4reiv +d4rej 4drem 4d3ren -2d3rep +d4reo +4d3rep 4d3rer 4dres. d4resc +dres6sei +dres6sel +d4rew +2drez 2d3rh d3ri 3d4ri. -3d4ria -2d5ric +d4ria +d4rib +4d5ric d4rid -d4rif +d4rie +d5rieg +3drif +4driff +d4rift d4rik +d4ril d4rin. +4d5rind +2drip d4risc +2drisi +2driss 2driß -3d4rit -4dritu -d3rob -d3roc -2d3rod -d4roi +d4rit +2d5ritu +d4rix +2d3rob +d3rod +2drogg +2drohr +3d4rohu +2d3roll 2d3rose +d4ross 2d3rost 2d3rot -d3rou +2d3rou 2d3rov -d3rö -drö2s1 +d3row +drö2sc d5rub 3d4ruc 2d3rud 2d3ruh -2d3rui -4drund -drunge3 2d5rut drü1b +3d4rüs 2d1s 4ds. +ds3ab +d2sad +ds1al +d2salk +d2sall d4s1amt d2san +ds3ane ds3assi -d2sau2 +dsau2 +d2saut ds1än +ds2äu 4dsb d4schef d4schin +d3s2co +d2scr d2s1e2b +dse2e d2s1ef ds1ehr -d3sei -ds2eig -d4seins +ds4eign +d2sein +d2s1emb +dsen3er d2s1eng d2s1ent d2s1erf d2serh d2s1erk +d2s1erl ds1err -d2s1erz +d2s1ers +d2s1ert +d2serz dse2t d2s1eta -d3s2ha +d2s1ev +d2sex +d3sha2 +ds2hak +d4shal d3sho +d4shor d2sid d2s1im d3s2inf -d3s2kan -d3skul +d3s2kal +d3s2kel 4dsl -d2s1op +d4sli +d3soh +d2sop dso2r ds1ori d2sö -d2s1par -ds1pa4s +ds1pa4s3 +d2s1pat d2spä -ds2pe -ds2po +d2s1pec +ds2pen +d4speri +d2s3ph +d3s2pi +ds2por +d6sporto d3spri d2spro ds2pu dss2 -ds3si -dst4 +dst2 d4stabe +d2stas ds3tauf d4s3täti d4stea +d4stele ds2til -ds2tip d2s1tis +d4stoch d2stod dstras4 -ds1ums +d4stren +d3s2tro +dsu2m d2sun ds2zen 2d1t +dta2be +d3t2ac +dtach3 dta2d -dtam3m +d3t2ag +dta2n +dt3ane +d3t2as +dt2ax d3tea +dte3mo +dt2et d2th d4thei -dt3ho -dto2 +d3to2 +d4tob +dt2op +d3tö dt3r dtran2 -dt5s2 +dt1s +dt3sa +dt5st +dtt4 +dt2un +d3t2ur +d3ty 1du du1alv du1ar -dub3l -du2bli +du2b3li +du1ce +duel3la du2f 2d1ufe +duf4ter +duf2to +duf2tr 2d1uh du1i +du2in +du2kr +dul3art 2d1umb 2dumd 2d1u2m1e 2dumf 2dumg -2d3umk +4d3umk 2duml d2ump 2dumr -d1ums +2d1ums d2ums. 2d1umv -2d1un3d -dund2a +du2n +2d3und 2d1unf -2d1ungl +2dungl +2d1uni dun3ke dun2kl 2dunr +2dunsi dun4st3r 2dunt 2dunw -du1o -5dur2c +2d3unz +du1os +dup4 +dur2c +durch3 +2d1urk 2d1url -2dursa +2d1urn +2d1ursa +2d1urt du4schn du4schr -du4schw +du4sch3w +dus2t +1dü 2düb -3düf -3dün +d3über 2d1v2 -4d1w +2d1w dwa2 -dwest1 -dy1 +dwa4r +dwer3te +dwe2s +dwe4st1 +1dy +dy2l1 +dym3 +3dyn dy2s1 -2d3z2 +4d3z2 2e1a -e3a2b -eab3l -ea3der +ea2be +ea2b3l +ea4br eadli4 -ea2dr -ea2g4 -ea3ga -ea4ge -ea3gl +e3a2dr +ea2g +ea3ga2 +ea3g4l eakt2 +e2akta e3akto ea2la e3alei +e4alem +ea4l3ent +ealen4z ealer2 -e4aler. +e3a4lerg +e3alex +e3a2lin eal5le eal3lö eallö3s +eal1o +ea2lon +ea2lop e2alti2 +eal3tr +ea2l3u2 +eam3a e2ame -eam3m eam1o -eam3t -ea2na +eams2 +eam3t2 +ea4na +ean3a2r +e3anf e2ano e3ar. ea2ra +ea3rat +e2are e4are. +ea2r1ei ea4rene e4arer e4ares -ea2sc +ea2ro +e3arz +e3a2sc +e3asf +easin4 +ea2sp eas5s -eat4e2 +eate2 +ea3te. +ea3ten eater1 -e3ath -eat3s2 +eat4mes +eat2mu +eat4mun +eat3s e3at3t4 -e3au2f -e3aug +eatu2 +e3aue +e3auf +eau2fe +eau4fl +e4aufo +eau3n eaus3s -eau3st +e2av +e2az e3ä4 e1b 2eba -e3b2ak -2ebed -ebe2i -2ebel -eb2en -e3ben. -ebens3e +e3bak +eba2p +e3bän +2ebec +ebe1er +ebein7h +eb2el +ebe4ler +ebe2lo +ebenen3 e3ber -ebe4rel +ebe4ras ebert4 +ebese2 +ebe4s3eh +ebe2so 2ebet +ebet4s +2ebh +2ebi 2ebl eb2laß +e3blä +eb3le. eb3ler eb4leu e3blie eb3lo eb2lö -2eb2o +2ebo +e2bob ebö2s 2ebr -eb3rei -eb4ru +e5brau +eb4rea eb2s eb6sche ebse2 -ebs1i +ebs1in ebs1o ebs1p -ebs3pa +ebs7panne +ebs3tau eb4stät ebs3t2h -eb4s3ti -eb4s3tot +ebs1ti +eb4stot eb3str -ebs1u -2e3bu +eb4sz +2ebu +e2bunt ebus3s -ebu2t1 +ebu2t3 2eca -e1ce +2e1ce +ech1am ech1ä 2e1che ech1ei +ech2en1 e6ch5erzi +e1chi ech3l ech3m ech3n e2cho. -ech1o2b -e2ch3r +ech3ö2 +ech3r +ech4ri +echs4er +echst5re +ech3tab ech3t4ei +ech6terh +echter8ha e1chu -ech1uh ech1w +2echz e1ci -eci6a -eck3se +eci2a +ec4k +ecke4n1 +eck3ser eck4sta 2eckt +3eckty 2e1cl 2eco -eco3d +2e3cr 2ect e1d -e3d2a +ed2a ed2dr -ed2e +ed4e ede2al -ede3n2e -eden4se +ede3n4er +eden4sa +eden4s3e eden4s3p +edeo2 ede2r +eder3a +ede3rat +ederer4 edert2 -edi4al +ed2i +e3di. 2edip edma3 edmas2 e3d2o ed2ö -eds2ä +e3drei +ed2sal ed4seh ed2s1es +ed2si ed2s1o ed2s1p -ed2s3tr -ed2su -edu2s +ed2sto +ed2s1tr +ed2s1u +edun3 +edund2 e3dy3 -4ee -ee3a2 +edys2 +2ee +ee3a4 eeb2l +ee1c ee2ce -ee1ch ee2cho -eede3 +e1eck eed3s2 -ee1e +ee1e2 e1eff eef4l -eeg2 +eeg4 e1ei -ee1im +ee2i3e eein4se -eei5se +eei4sc +eei3se +eeis3s +e2ela eel2e -e1e2lek -ee5len +e3e2lek +eele4n +eel2ö +e2e3m2a +eemas3s +e1emb +ee3min e1emp e1en -eena2 -ee4nag +eena2g e2enä e2enc +een1e +e3eng +ee3ni +e3enk +e3enl e2eno een3s -e1e2pi -eera4 -ee2r3as +een2z +ee3o +e2ep +ee3po +eer4at e1erbt e1erd -ee3r2e +ee3re2 +eer1ei ee4r3en4g -eere4s1 +eer2e4s1 +eer3eti +e1ermä ee1ro ee1rö +e1eröf eer2ös -eert2 -e1ertr -ee3r2u +ee3r2un e1erz -ees2 ee3sh -ees3k -ee3ta +ee3sp +ees2t +e2et. +ee3t2a ee4tat -ee1u -eeu2f +ee2th +eet2i +ee3t4r +ee2tu +ee1u2 eewa4r +eeweis4 e1e2x e1f -2ef. -2efa -e2f1a2d +e2f1ad +e3fah ef1ana ef1ar +e2farc +ef3arm e2fat -efäs4 +2efä +ef2äl efä5sse e2fäu 2efe -e3fe. e2f1e2b -efell4 +e3fef +efe4l3ei ef1em +e2femi +efe2n1 +3e2f1ene e2fent -ef2er +efer5f +eferin6d +efer5r efeuil4 -2eff. ef2fä2 3effek 1effi ef2fl +ef3flu 2efi ef1id e2f1ins efi2s -1efku 2efl +ef4le e3f4lu +e3flü 2e3f2o -e3fra -ef3rea +2efr +ef4reih ef3rol ef3rom +ef4ru ef4rü efs2 +ef3sc ef3so ef3sp ef2tan ef2tei +ef2tro 2efu e2fum -2efü e1g -eg1d4 +ega2m +e3g2anz +egd4 e3ge +egein3 +ege4lan +ege4l3au +ege8l7ei8er ege4ler -ege4n3a4 -ege4nec +ege2lo +eg2en +ege4n1a +ege6nero ege2ra +ege5stal ege4s3to -ege4str +ege4s3tr ege1u +2egi +e3gio +2egl e2glo e2glu e2gn eg3nä eg3ni +ego1p egro5sse eg4sal -eg4san +egsau3g eg3se eg4sei -egs3e4r1 +egs2e3l +eg3si +egs2of egs2pe +egst2 eg4sto -egs3tü eg2th 2e1ha eh1ach +eh1ad +eh2ade +e3h2ah eh2al -e2hap -eh2aus -2e1hä +ehalt4s +e3hand +e2harz +e3haut +e1hä ehäs3 e1he -eh4ec eh1eff -eh2el -ehe5na -ehen2t3 +eh1ein +eh1elt +e4hense +e4h3ente +ehen4tr +ehe3o 1e2hep -e3her +2eher ehe1ra -e1hi -eh1int +e2h1er2f +e2h1er2l +2e1hi +eh3im ehis4 +ehl1a eh1lam +eh2l3au eh1lä ehl3ein eh4lent eh5l2er -eh2lin -eh3lo +ehlo2 +ehl1or +eh2lö ehl2se 2ehm +eh2mab +eh4mant eh3mu -e1ho -e3hol -ehr1a2 +eh3na +eh3no +2e1ho +eho2f +eho2l +eh3oly +2e3hö +ehö4rer +eh2r1a4 ehr1ä ehr1ec eh2rei -ehr4erf +eh2rel ehr6erle +ehr4ern ehre3s -eh3ri -eh1ro2 -ehr1ob +eh4rin +eh1roc ehr1of +eh1rö eh2s2 +eh3sa eh3se eh3sh eh3si eh3so eh3sp +ehst2 eh3sta -2eht -e1hu -e2hunt +eh3sto +eh3str +2eh3t2 +eht3h +eht4r +2e1hu +e2hum +eh1unf +e2huni +e3hur e1hü eh3üb eh1w e1hy 2ei3a2 +eia4t ei2bar -ei2bl -eibu4t +ei2bli +ei4blu +eibu2t ei4b3ute +e4ic +ei1ce ei2cho -eich5te e2id ei2d1a ei3de -eid4ein -ei4d3er4r +ei4deis +eid5erre 2eidn -ei3dra +ei3do +ei3dr ei1e -ei3el -4ei3en +eie2b +eie2d +ei3e2l +eie2m +4ei3e2n1 eienge4 -eie4s -eif2e +ei3e4s +eie2t +4eif. +ei1flo 1eifr -ei3g2a +eif3t +2eig. +2eiga +eig2ar +2eigä +2eige. +2eigeb +2eigeh 4eigeno -eig2er +5eigensc +4eig2er 2eiges 2eigew -ei3gl +2eigi 1ei2g3n +ei2go +ei4g3rat +2eigre +2eigrö 2eigru +2eigrü +2eigs 2eigt 2eigu +4eih +ei2hum +ei2kab +ei2kak +eik4am eik2ar -ei3kau -eik4la -e4il +eik2i +eik2l +ei3k4la +ei3klä +eik2o +e2il 2eil. +ei4l3ab +ei2lam +eila2n +ei4l3ane +ei4lang +ei4l3anz ei2lar -ei2lau 2eilb -eil3d +eil3d4 ei4lein -eilen1 +eile2n1 +ei2let eil3f4 -ei4l3ins -2eiln -1eilzu -ei2m1a4g +eilm2 +ei2lob +eil2ö +2eim. +ei2mab +ei2m1ag eim3all -ei2mor -e1imp -eim2pl +eim3alp +eima4to +ei2m1or +2eimö +2eimp +eim2p4l +eim3sa +ei2mur e4i2n1a -ein3a2d -ei4nas -ei4nä -ein3dr -2eindu -ei4neng +ei4na2d +ei4nae +ei4n3an +ei4na4s +ei4n3at +ei2n3ä +ein3d2e +ein6derk +e1indu +2eineb +einen4e +ei4n3en4g +ei6nen6se +ein5erbe +ei4nerf +ei4nerk +ein5er6la +einer6sc ei2neu +ein4fiz +5einflus +5einfluß 2einfo ein4fo. ein4fos ein3g2 -ein4hab +3einger +e2ingr +e2inhä +ei2nie e1init -eink4 +ein3k4 ein6karn 3einkä -3einkom +e2inl ein3n2 -1einna -ei2n1o2 +ei2n1o4 1einri -e4insa -einsas4 +e6insa +einsas6s einsa7sse 3einsat -e3insta +e2insc +5einschä ein6stal -ein4sz +ein6terv +3eintö +3einträ 1einu -e4inver -ei3o2 +ei3o +eio2p +eio2s ei1p eip2f 2eir +eir2c ei3re e1irr -e2is. -ei2sa4 -ei6schin +e4is. +ei2sa +ei3sas +ei6schwu +e4ise +ei4ser4g +ei4s3er4l +ei6s5erst ei4s3erw +1eisho +ei3s2ky +ei2so eis2pe -ei3spru -ei3s2s -ei2str +e2i3s2s +eisser6s +4eisto eistra6s ei2sum -e4it -ei2tab +ei2sur +1eiswo +e2it +ei2t1a2b +ei2tal ei2t1an +ei2tap ei2tar +ei4tat 2eitä -ei3te -ei2th -ei2tor +ei2tän +ei3tei +eite4ra +ei2t1h +ei2tin +eito2 +ei4trau ei2tro -eitt4 -eit3um -2eiu -2e1j +eit4sa4g +eit3t4 +ei2t1um +ei2t1ur +eit3z2 +eiv2 +eive4 +ei2zar +ei2z1in +2e3j e1k -ek2a +2ek. +2e3k2a 1ekd +ek2e e3ke. -e3ken +e3ke4n e3kes e3key e3k2l -ek3lip +ek4lo ek4n -ek2o -2ek4r +e3k2o +ekor4da +e3kr +ek4s1p 2ekt -ekt4ant +ek5t6ante +ekt3at +ek2t1ä +ek2te2l ekt3erf -ekt3erg +ekt3erk ek4t3er4z ekt2o -ek2u +ek2t3o4b +2e3ku +ekur2a e3k2w +1ekz e1la -ela4ben -el3abi el2abt -el3a4der -e3ladu +el3abu +el3ader el1af -ela2h +ela4h e2l1ak -el3al e2l1a2m +el2a3mi +e3lamp +el1ana e4landa e2lanm -el1ans +e4lans +e2l1ant +e4lanw el1anz 2elao e2l1ap -e2l1a4r -el3ari -el1asi +e2l1ar +el3a2ri +el1a4si el1asp -el2ast +el3aufw 2e1lä -3elbis -el2da -eld3erh +e3läd +2elbil +2elbr +2eld +elda2r +eld3ari +eld4arm +el4d3erf +eld3erl elder4p +elder4s eld5erst el3des -eld3s2 -e3lea +elds2 +4e3le. +2e3lea +elea2r +2e3leb +4ele2c +el1ech +1elefa +4eleh +el3ehe. 2elei -e6l5ei6er. e6l5ei6ern -el1ein -e4leinf -e4leing -e4leinh +e2l1ein +e3leine +e5leit +1elek +2eleko e2l1el 1e2lem -e3lem. -el1emp +2e3lem. +e3lema +ele2mi +e3lemm +2el1emp 2e3len. +elen4k3l e4lense -e4l1ent +e2l1ent e3lep -e2l1erd +2eler +e3ler. +eler2a +el1erd +e6lereig el1erf e4ler4fa -e2l1erg +e4lerfi +e2lerg +el1erh el1erk -el1erl -e4ler4la +e2l1erl e4l3ernä -e4ler2ö +eler2ö e2l1err -eles2 -el1ess -e4l1e2ta -e3leu -2elev -ele2x +el3eru +el1erw +e2l1ess +e2l1e2ta +ele2ti +elet4ta +2el1ex +e3lex. 1elf. -el3fe -elf4l +elf2er 1elfm +elf4r 1elft -elg2a elgi5er. elgi5ers +el3g2l elg4r e2l1id -e3lie +2e3lie +elif3 +2elig e2lim -el1ita +elin3a +eli3no +el1ins 2elk elks2 -elk3sc -ella3d -el3lan +ella5den el2lap +el4larb +ellar4t ella2s -el2lä -el3läd +el3le. +ell2ei ell3ein -el3ler -el2leu +el4lel +ellenen5 +ell2er +eller8fas +eller7g +ell3erh el3lie el2lil -el3l2in -el2log +1ellip +el2lo2g +el2lor el2lot +ell2ö ell3sp -el2lu2m +ellu2m el2lü +el3m2a +elm2e +elm3ein 2eln -el5na +el3na 2elo +e2l3oa e2lof e2lol -elon2 -e2l1or +e2lom +e2lonk +el1opf +el1or elo2ri +e3lot +e3l2ov +2elö +el3p4 +el4s5ein +el3sent el2sum -elt2ak +el4tans el3te. +elte4m el5ten. +el4t3ent elter4b -3eltern -elter4s -el3tes -elto2 -elt3r -elt1s2 +elter4f +elt3erh +elter6le +3elter4n +elt5ero +elter6sc +elt3eth +el3the +elt1r elt3se -elt3sk 2e1lu -el1ur +el1uf +e2l1um +e2l3u2r el3use +elu2t +el3uto e1lü +2ely e2lya -2elz +el3z2ac el2zar -elz2e +el4zene +elz1in el2zwa +2elzy e1m -2ema -em1ad -ema2k -e2m3anf +e2m3a2b +e2m1alk +em3anf +e2m1ano e2m1ans -3emanz -emas8sens -em4d3a2 -e3m2en +1emanz +e4m3a2sp +emas2s +ema3sse +e3maß +em1au +2e3mä +em2äh +1emba +1embo +1embry +em2dä +emd1r +em2dra +2eme +e2m1e2b +e2mef +eme2i +e2mele +em2en emen6gel emen4t3h -e2m1erw -1e2meti -e2m1im -emi5na +eme3r2i +e2m1er2l +em1erw +3e2meti +e2m1i2d +emi2ei +e2mig +emik2 +em1im +2emin +emi3n2a +e3mind em1int -emi3ti -2emm -em2map +1e2mir +e3misc emma3u -e2mop +em2mec +e2moa +e3mol +emo3s 1empf4 em3pfl +em3po em2sa -em3se +em4scha +em2sim em2spr +ems1tr em3t2 -1emul +1e2mul +3emuls +emune7 +e3mur +e3mus 2emü -emü3s4 -e2n1a +emü3s2 +e2na 4ena. -2en2ac -en3ack -e3nad +e4na2b +en3aba +en3abo +4enac +e4n3ack +enadi4 e4naf 4enah -e4n3a2k +en3ak +en1al +enal2a +e4nalb +e3nale +en2alg ena3l2i +e4nalk +e4nalm +e4nalo enal3p -4enam -en2ame +4en1am +ena4n e4nand -en3ang +en3ane +e4nant e4nanz +en1ap +ena2pa en3are -ena4sc -4enat -en3att -e3naue +en3ark +en3aro +en1as +ena2sc +e4na4st +2enat +4e5nati +e4natl +enat4s +e4n3att +4enatu +e4nau2f +en3aug +e4n3aur +e6nausta +e4naut +en1a2x +en1a4z en1ä +en3äb +e3näi e2när -enä4s +en2ä3s +en3äst enbu4s3 en2ce. -en3d2ac +end2ac en2dal +en4dang +2endel +ende4lä endermas8 -en4d3ess -end4ort +en4d3es4s +en2dex +en2did +en3d4ort end3rom +end3s2l end3s2p end3sz -end2um +en3d2um +en3d2ü 2ene. -ene4ben +en3e4ben en1ec e2neff +ene2h en2eid e3neien +e4neige +4eneigu e4nein +e4neis e2n1el ene4le -2enem +2ene2m +e2n1emi 2enen +e4nense e4n1ent en4entr +en3envi +en1ep 4e3ner. +en2era e2n1erd +en3erei e2nerf -1e2nerg -e4nerh -e4nerk +en4erfr +1energ +e2nerh +e2nerk e2n1erl +e4nermi e4n3ermo 4enern +e4n3erne +ene2ro e2n1err -e2n1ers +en1ers +4eners. e2n1ert +en4ert. e2n3eru e2n1erw -e4nerz 2enes -e2n3ess +e3nes. +e2n1e2sc +e2n1esk +e2n1ess +en1eta +e2n1eth +en1eul +e2n1e2v +e4ne2x en3f -enf2a +enft2 enf2u 1engad -3engag -enge3ra +1engag +en3g2al +enge3r4a en3g2i -en3glo en3gn +en3g2o 1engp -eng1s -eng3sc +eng4ra +eng1s2 eng3se 2eni e3ni. e3nic -e2nid -e3nie +4e3nie eni3er. +eni3erp eni5ers. -e2n1i4m +en3i2ko +en3ill +eni4m +en1ima +en1imi e2n1in e3nio eni2ö -e3nit +e2nir +eni4sa +e4n3iso +e3nit2 +e3niv +enk3aus +3enkeli +enk3erg +en4k3erk en3k2ü -e2n1o2b -enob4le +en2nef +en2nel +en4ner4f +enn3erg +en4n3erl +enn2i +enni6ger +2enniv +e2n3oa +e2n1ob +e3nobel +eno2br e2nof -en1oh -e3nol +en3oli +en3olm eno2ma -en1on +eno4n e2n1op e2n1o2r -eno2s -enost3 -e3not +en2ora +eno4ri +4enorm +e2n1ost +4e3not eno2w 2e1nö en1ö2d -en3sac -ensas2 +en3sabb +en2san +ensas4s ensa5sse -en2sau en5sche en2seb -3ensem -ensen1 -en2sep -en3ska -en3s2po +1ensem +en4sen3e +ens3ere +en3spo +ens4por +ens4tak enst5alt en4s3tät +ens4tel +en6stele en6s5test 2ensto -ens5trie -e4nt -ent4ag -ent4ark +enst2ü +en2sun +en3t2ag +2entan +en4tanm +en4tanw +en3t4ark 1entd -en2teb +en3t2el +ente2n +3entera en4terb en3tes 1entf 2entfo -1entga +1entg 3entgeg en2thi +1enthu +1enthü +en2t1id 3entla 1entn +en2tob +entopf3 +en2t1os +2entö en4t3rol -3entspr +1entsc +1entso +ent4sto 1entw 4entwet +3entwic 1entz en1u -2enut +e2nuf +e2num +enu4r +2enu2t +e4nuto e1nü 4enwü -e1ny -enz1ec -en4z3erf -en4z3erg +2e1ny +en3zare +enz2äp +1enzep +enz3erg en4z3erk +en4zerl +en4z3erm +enz5ersc +enzi2d +enzlan4 +enzo2l +1enzy e1ñ -2eo +4eo e1o2b1 +eo3ben +eo3bl +eo3bo +eo3br +eo1c +eoch2 +eo3dr e1of -eo2fe +eo3g2 e1oh -eo3m -e1on. -e1ond -e1onf -e1onh -e1onl -e1onr -e1ons +eo3la +e3o2ly +e1on +e3o2nat +eo1o e1ope e1opf -eop4t +eop4r e1or e3or. +eo1ra e3orb +eorgi1 e3ors +eort4 e3orw eos2 e3os. -eota2 -eo3ul -e1ov +eo3se +e1o4ste +e1ou2 +eo1ul e1ö2 e1p +2ep2a epa2g +epas6ser +2eper e3p2f4 -e2pis -1episo -2epl +e5pfi +eph2 +1e2pid +e2pig +e2pik +1e2pile +e3pio +1epis +2epist +1e2pit ep3le -1e2poc +1epoc +eport4 +1e2pos. ep2pa -ep2pf +eppe3l ep2pin -ep4pl +ep2pl ep2pr -ept2a +2epr +ep3sh ep2tal +ept2an +ep2tau 2e3pu epu2s -e1q +2e3q er1a e3ra. era2be +era3ber +era2c +e2rach e3rad. -er3adm +e3radi +e2radj +e2r3adm +e4radmi +e4r3adr eraf4a era2g +e1rah e1rai er3aic -e2rak -e1ral -er3all -eran3d -e3rane -er3anf +e3rake +e1rald +eral4eb +er3alke +e2r3all +era4mat +er2an. +era4n4a +eran3d4 +e3rand. +e4rangr e2ranh -er3anm +e2rano e1rap +er3apa er3apf e2rar +er3are e3rari -e1ras -e2r3a6si -era4sp +e3ras. +era2si +era4sie +era2sp era4s3s -er4ast +e1rast era2ß -e2rath -e3rati -e2ratm +e4ratel e1raub +e1rauc er3aue erau2f er3aug +e2ra2v e1raw +e2r3ax e1raz e1rä +er1äf er1äh -er1äm +er1ä2m +er1äp e2r1ä4s +er1ätz +3erbarm +erb2au erb2e +2erbru erb2sp er1c er3chl +erch2o +erd4am erda3me 1erdb -er3de 2erdec -erde3in +2erdel er4d3en4g erd3erw +erdeu2 +1erdg +2erdy 4ere. -er1eb -e3rech +er3e4ben +e3r2ech er3echs er1eck er1edi ere4dit er1eff -er1e2h -2e3rei. +e2r1e2h +ere4i +4e3rei. +e3reib er1eig -e2rein -e4r3eis. -ere2l -er1ele +4ereih +e3reik +e4r3eime +e4reink +er3eis. +er5eisar +er3eisb +er3eisf +er3eisr +erei5str +e4rek +er1e2l +e2rele ere3lev -2e3rem +2erem +4erem. +er1emi +ere4mis e2remp 2eren -e3ren. +4e3ren. e3rena +eren1e e4rense -e4rentf e4rentn +e4rents e3renz eren8z7en8d -er1ep -2erer. -e2r3erf -e2r1erh -2erern -e3rero -er1err +er1epe +4erer. +2ererb +e4r3erfo +e2rerh +e2rerk +e2rer2l +erer5lau +4erern. +e4rerne +e2rer2o +erer4ri er1ers +4erers. +e8rersche e2rert -er1erw +2ererv +2ererw 2eres +4eres. er1ess +eres3sk er1eß -e4r3e4ti -er1eul +er1eta +er1eu ere4vid erf2e -er3f4r +4erform +erf4r 4erfür +er4g3are +4ergebi 3ergebn +4ergebü +4ergeha 4ergehä -erg3els -1ergol +erg5elst +4ergeni +2ergn +er2gop 4ergrem -e2rh +erg1s2o +ergs2p +e4rh 1erhab +er3hag +2erhai 4erhals -er3he -4erhöhe +2erham +2erhan +2erhas +er3hei +2erher er3hu -2erhü 2eri e2riat e3rib 4e3ric -er1i2de -e3rie -eri3e4n3 -eri5ers. -e3ri3k4 +e4r3ico +er1id +4e3rie +eri3en1 +erien7s +e3ri3k +erik4l 4e3rin. -er1inb +e2r1ind e2r1ini er1ink -er1ins +er1inl er1int -e3rio +er1inz +e2ri2on +4eris +e2riso +e2risr er1ita +3eritr +e3riv 2erk. +2erkaj +er3ker 1erklä -2erkli -er3ko +2erkm 2erkre -erk3t +erk3t4 +er2kum +2erl. 2erlag 3erlebn -4erln -erm2e +4erleh +2erln +er3m2 ermen4s -erm3ers +er4m3ers +er4n3alt +er3ne +er4nene +er4nerf er4nerk +3erneue +er2nob +erno2r ern1os -e1ro. -er3oa -er1o2b +2e1ro. +e1roa +er1ob +ero2bl +ero2br e2r1o2f e1rog -e1r1oh +e1roh e1rok e1rol +er3oly e1rom -e3ron -er3ony +er3omb +2e3ron +e2r1oo er1op -e4ro2r +2e4ro4r +eror2a e1ros +1erosi +e3rosit e1rou e1row -er1ox -e1roz +er1o2x +er1oz erö2d -2erök -er1ös -er3p4 +2eröh +erö4l +er1ö2s +er3p +er4rade er3rä -er5rei -erri3er +2erren +er3ro 2errü -ers2a -ersch2 +er3s2a +ers4ana +ersch4 er5schn -er3se -er5sen -er3s2i +4ersei +ers2el +er5s2i er3sk ersma3s4 -er5smo -er3sn -er3sp -er3sto +4ersted +er6st5ers +4erstil +er3swi er3sz -ert2ak -er6terei +er2t1ab +er3tat er4t3erf +er4t3er4g er4ter4h +er4ter4k er4ters -er2t3ho -4erti -ert3ins +ert1h +er2tho +4ertö +4ertru ert3s2e -2ertür +ert1s2p 2eru eruf4s -er1u2m +e4r3uhr +er1u2m1 er1und -er1uns -er3uz +e4rundu +er1up. +er3ur +er3use +e2r3uz erü4b 3erweck +er4zerk +er4z3ers e1s -e4s3ab +es3ab +es2abb +e4sabe e3sac esa2d +e3saf +e4sall +es1ami es2an es4and -es4ank +es3anf es3ant -e3s2as -esa3sse -esas6sen -esa6sset -e4s3ato -es3av +esa2ra +e3sa1s2 +esa3ss +esa5sse +esa2v +es1ax esäs4 es2äu 2esb esbi5er. -e3sc -es2ca -es3cap -es2ce +e3s2ce +es2chi esch2l esch2n e4sco -e4scu e3se. es1ebe +e2s1ec es1ehr -e2sein -es3eva +esein4s +es2el +ese4nal +ese4neu +e3senk +esen3o +esen3sk +esen3th +eser4at +ese4r1u2 +eses2k +es3e2x 2esf -4esh +2esh es3ha +es4ham es4har -e3sig +es3he +2esi +esi1er +e4s3i2k e2s1il -es1ini e4s3ins -es3int +e4siso es2kat e4s3ke -e4sky +e4s3kl +e4s3ky e4s3l -es4log 2esm e4sn +e2s3oa +e4sob +e2s1od +es2oh +es2opa eso2r +es1ora +eso3re es2ort -es2ö -2esp +e3sot +e3s2ö +4esp +e3spal +es4park es2pek -e3spi +e4spers +e4sph +e3s2pi e3s2por -e3s4pra e3s2pu 2esr +2ess. +es4s1ag essali3 -es2sau -4essem -ess4e3re -ess3erg -es3si +essau4s +1essay +2essä +2essc +e4ssel +e4ssent +ess6ere +ess4erf +e4ss3erg +es4serh +e4sserl +ess5er6la +2essk 2esso es2sof +2essp es2s1pa es2spu +es4stab es4ste estab4b +e4stabs +esta3ge est1ak -e3stan +es2tan +est4ap e4starb -1e2stas +es2t1a4s +e3stat es2tau -es2te +e4staum +es2te. este2c +este4i +est5eing +e6st5eink +e6st5einl +este2l +e4stele +e4st3emi e4st3eng -e4st3erh +est5entr +est5erha +e4ster4ö +e4st3erz +estes2 e4st3ess -e5stev e3sti +e4stid e4stip estmo6de +1estn e2stod -est3ori -2estro -es3trop +e4strad +es3trak +e5strec +e5strick es2tu +est3ums e3s2tü -es2ty +e3s2ty +e3suh e2s1um es1ur -e4sw +esu4s +2e4sw e3sy -eße3r2e +e2ß1el +e2ßent +eße3re +e2ß1erg +e2ß1erl e1t e3ta. etab4 -etal4la4 +et2a2c +2e3taf +2etal +etalla4 +etal6lag etal6li6n -et1am -eta2mi -1etap -etari1 +et1ami +e3t4an. et4at +etat3r et1äh 2e3te +ete2e +e4t1ef e4t1ein ete3ke -et2en eten3d2 ete2o eter4hö +ete1ro eter4tr -et2h -et3hal -ethi1 -et3hü -e3ti +ete4sp +2eth. +et2ha +e4t3hal +e3the +et2hi +e4thik +3ethn +et2hu +e4t1i2d eti2m +etin1 +et1ini +et2it eti2ta -2eto -eto2b -e2t1of -e2torg +eti2th +2e3to +e2tob +e4t1o2f +et4on +eto4n3al +etons4 +e4torg 2etr +et3rad e4traum et3rec -e4tres +e2t3res +et4ros +ets2c +etscher7e etsch3w -et1s2p +ets1p et1su -etta2 -et2tab +ett1a +et2ta2b et2tad -etta3ge -et2ta4s +et2tak +ett2as et2tau et2tä et2tei ette4n1 -et4teu et4th et2tö4 et2t3r -et4tro -ett3sz et2t1um et2tur et2tü4 +3e2tui +e3tur etwa4r +1e2tym 2etz -et2zä -et4z3ent etze4s et2zw eu1a2 eu3b4 -euen2g -eue6reif -euer4ri +2euc +euch4ta +2eud +eudi4e +2eue +eu2eb +eue6r5eif +eue6reis +eueren4 +euerer6s +euerer6t +eu3eri +eu3erk +eu3err +eue3s eu2e5sc -2euf +4euf eu2fer -eu2ga -eu4gent +eu2g1a +euge4mi +eu6gense eu3g2er +eugin2 +eugin4f +eu4gin4g +eu2gre +eu2gri eug1s2 -eu1in -1euk +eu3h +eu1id +eu1in1 +e4uk +1eukal eu2kä -e1um +eulan2 +euland3 +eu3l2e +eul2i +2e1um e3um. +eu3m4a +euma3s2 e3umb +e3umf e3uml e3um2s eums1p eum3st +e3umw 2eun +eu2na eun2e eu4nei -eun4er e3un2g eu2nio +eu4nis +eunk2 eun3ka eu1o2 -eu1p2 -e2u3r2e +eu1p +e1up. +eup2f +e3upg +eu4r1an +eu4r3ast +eura3t +eu2rau +eur1c +e2ure +euren2 +eu4rens +eur4er +eur3f4 1euro -eu2rys -eu1s4 -eu4sis +2eu1s4 +e3usar +eusch4o +eu4s5k eu3sp eu3ss eust4 2eut +eut2e +eu5ted eut2h +3eu3tha +eut2i +eu3t2o +eut6scha eut6schn +eut6schr 2eux +eu2za eu2zo eu2z1w e3ü -2e1v -e2vela -e2vent -4ever -eve5r2i -e3vo +e1v +e2vak +e3var +2ev2e +eve5ri +evie3le +2e3vor ev2s e1w -2ewa -e3wä4 +ewä4 ewä6s -2ewe e2we. +ewei4sc +ewert4 +ewer3te e3wir ewi2s e3wit -ew2s 2ex. +1exam ex3at -1e2xem +2exc +2exd +e2xel ex1er +2exes e1xi -2exie +2exik +e2xil e2x1in +e3xio 1exis ex3l -3exp +1exp +2expu +2exs 2ext. +2ex2ta ex2tin -ex2tu +1extr +2extu +2extv 2exu -2e3xy +e2xum +2e1xy +ey1l2 ey2n +ey3no eys2 e1z e3z2a +ez2ä e2z1enn e3zi ezi2s +e3z2o ez2w +ez3z2 é1b é1c é1g +égi2 é1h -é1l +é1l2 élu2 +é1m2 +é1n é1o é1p -é1r +é1r2 é1s -é1t2 +é1t é1u2 é1v é1z2 è1c è1m -è1n è1r +1ën +ë1t ê1p 1fa -3fa. fab4 -f1abe +2f1ab5b fa2ben -2f1a2bl -fab5s +2fabf +2fabg +2f1a2b5l +2fabn +f2abr +2f1ab5s +2fabw fa4cheb +fa4chel fa2ch1i fa2cho +fachs2 +fach3sp fa2ci +fa2dan +fa2del f1ader +fa2di fa2dr -f4ah -faib4 +fa3e +fah6l5ent +fai3b +f1a2ka fa2ke -f2al -fa3l2a +f3aktio +f4akto +3f2aku +fa3la +fa3le fal2kl -falla2 +falla4g fal4lei fal6lenk -fal6l5er6k -fal2li4 +fall5ent +fal6lerk +faller6s +falli4 +fal6lini +fal4lis fal6scha fal6schl fal6schm fal3te +fal4tei +fal2tr 3fam +fa2mei +f1amp f1amt -2fanb -2fanf +3f2an. +fa2nar +fand2a +f2anf +fan2ga fan2gr -2f1ank +2f1an3k 2fanl +4fann f1anp 2fanr -fan3s 2fanw -f1an3z -2f1ap +2f1an3z +2f1a2p f2ar -far2br -2f3arc -3fari +far2b1a +far4bel +far4b3er +far4bin +farb3l +far2bo +far2b3r +far2b3u +f3arc +3fa5ri +far2r1a farre2 far4rec far4reg -f3art +2f3art 2f3arz 3fas. fa3s4a fa3sh +f1assi +fas2t +2f1a4str +fa2ß +f1aße f3at +f4at. fa2to +f4ats 2f1auf f3aug fau2s f1ausb +faust3r 3f4av fa2xa 1fä -fä1c -fäh2r1u +3fä1c +fäh4rin +fäh2ru f1älte +2fäq +3färb 2f1ärm -f1ärz +2färz fä4s -fä6s3ser +fä6sser4 +3fäßc fä2ßer -2f1b2 +2f1ätz +2fäug +2fäx +4f1b4 +fbau1 +fber2 2f1c +f3ch 2f3d4 -fdie2 +fdien4e 1fe +3fe. featu4 f2ech -2f1eck +fe2del fe2dr -fe2ei +fe2e1i +feein5 fe1em -fef4l +2f1e2he +fehle2 feh4lei -f4eie +f2eie +f2eind 2f1eing -4f1einh -fe1ini +fe3ini +fe3ins. 2f1einw -f1ei3s -fek2ta -fe2l1a -fel4da +f1eis +fek4tin +fe2l3a2 +fe2l1ä +fel2da +felde4m +feld6erh fel2dr -2f1e2lek +feld5ri +2fe2lek +2felem fe2l1er fe2les fel3la -fel4lei +fel4lan +fel2lä fe2l1o -fel4soh -fels2t -fel3t +fel4s3oh +6fel6tern +felt4r +fel3tu f2em. +2femb fem4m 2femp -fen3a2 +fen3a fe2nä +fend2a +4fenerg +fe2ni fe2no fen3s2a -fens2c -fens2t2 +fen5s2c +fenst2 fen6stri f1ent +fen3t2a +2f3entf +f2enti +4fentla +f2ento +2f3entw +4f3entz +fe2nu 3fep +fe2pi f2er. fe1ra -fer2an +fe2rab +fer3a2d +fe2ral fe4rang -fe4r3anz +fer4ant +fe4ranz fe2rau fe2r1ä -ferde3 +2ferd. +fer3da +fer3d2e3 f2ere -fer2er -fer3erz -f1erfa -fe2rid -3ferk -f2erl. -4ferneu -fe1ro +fe2r1e2b +fe2rec +3fer2ei +4f3ereig +fer3eis +f4erel +fer3ell +fe4rer4g +fer4fah +fer4fol +ferg4 +f4ergr +feri2d +ferie4n3 +feri4on +4fer4leb +f2ern. +fer4nei +fe2rö f4erpa +f4erpf +f4erpl +f4erra +fer4reg +ferri2 f2ers. -fers2t f2ert -f1erw -fer8zeuge +fert4r +f2erz +fess2e fes4t -fe2st1a +fe2sta +fest3a4b +fest3an fe4st3ei -fe2str -2f1eta -fe2tag +fe4stin +fe2st1o +fe2st3r +2f1e2ta 3fete -fet2t3a -feuer3e -feu4ru +fe2th +fet4t3a +fetti3s +2feu. +feuer3ö 3few -f1ex -2fexp +2f1ex +fe1y2 3fez 1fé -2f1f +4f1f +f3fa. ffa2b ffa2ce +ff1a2d +f3fak f3fal +ff1alt ff1ans ff3ar ff4arb -ff4art ffa4s +ffa2t ff1au -ffa2z -ff2e +ffa4z +f2f1e2b ffe2e -f2f3ef -ff3ei -ffe1in +f2f1ef +f2f1ei +ffe3in. +f5fek ffel3l -ffe2m -f2f3emi +ff1e2m +f2femi +ff2en +ff3erle f2fetz -f2fex +fff4 +ffi3k f2fil -ffi2xi -ff3lag +f2fim +ffi4xi +ff1lag +ff3le ff3li -f3flu f3flü ffo2 +ff1ori +ff1ox f2fö f3f4rä -ff2sa -ff2sp -ffs3tan +ff3ro +ffs2am +ff3sch +ff2s1p +ffs4tau +ffs3tie +ffs3tut +ff3stü +ff3t2 +ffus3s +f2fy 4f3g2 -fge3s -2f1h2 +fgeb2 +fge3s2 +fglim2 +4f3h2 1fi 3fi. +fi4ak +fi2ar fi3at +fiden2 +fi2do +f2ie +fi2e1i fi1er2f +fi2gr +fi2k1as +fi2kel fi2kin -fi3kl -fik1o2 -fi2kob -fi2kr -fi2l1an -fil4auf +fi2kn +fi2k1o4 +fi4k3r +f2il +fi2l3an fil3d fi2les +fil2et filg4 fi3li fi4lin fil2ip -f2ina +fil2ma +fil2mä +fil4med +fil4mei +fi2lo +2fimp +3f2in2a +fin2e +2f1inf +fing2 +fings2 fi3ni +f2ink +fin2sp 2f1int fi2o fi3ol fi2r fi3ra fi4re -3fis -fis4a -fisch3a +fir3me +fi3s4a +fi4sch3a +fi6schei +fisch3l fisch3o -fisch3w -fi3so +fi4schr +fi4sch3w +fi3s2h +2f1iso fis2p +fite2 +fi2tin fit1o2 fi2tor -fi3tu -3fiz +five4 +fi2xel +fi2za 2f1j +3f2jo 4f1k4 +fka4t3 f2l2 2fl. f3lad -f5lan3d +f5land +f4lans f3lap +f4lasc +f3lats +flauma4 1flä 3f4läc -2f5läd -f3län +4f3läd +2fläh +2f3län +2flär +2fläß 2f3läu +f5le. 2f3leb -2f3lein +f4lee +2f5lein +flek3 +flekt2 f3ler +f4lex f3li. 3f4lim +f3lind fli4ne +f3ling +2f3lins 2f5lon 1f4lop flo7s8ses. +1f4loß 1f4lot flo2w f3lö -4f5löf +4flöf +3f4luc +f3luf 1f4lug -flu4ger +1f4luss +1fluß +f4lut +flut1o f4lü f5lüd f5lüm -2f1m2 +4f3m2 +fma5che fma2d fmas2s fma3sse -2f3n2 +4f3n2 fni2s 1fo +f1ob +fo2be +2fober fob2l 2f1o2f foli3 -fol2k1 fo2na +fo4nan fon3au -fon2e +fon3dr +fo4n3in +fo2nop +fons2 fo2nu 2f1op -fo1ra 4f3org -fo3rin for4m3a4g +for4mas +for4m3ei +for4min forni7er. +for6schl for4sta for4sti -fort3 -for4tei -for2th -for2t1r -fort1s +for4t3ei +for4ter5 +for2t1h +for2t3r +fort3s2 for3tu -f1o2x +for2u +fot4r 1fö 2fö2f 2f1ök -2f1öl -4f1p2 +4f1öl +4f3p4 2f1q -f2r2 -f4rac +f2r4 +f3ra. frach6tr -2f5rad +2f3rad +2f3rah fra4m f3rand f5rap +f3rat +1frau. +f3rauc +2fräd 1f4rän 2fre. f3rec f3red -2freg +2fref +f4rei. f3reic -freik2 -frein2 -f3rep +f4reie +frei1f +f4reig +frei3k2 +2frein +2frek +2f3rep +2frest 3f4reu 2f3ric +fricht6e fri3d fri2e 2frig +f4ri3k +f3rip 1fris f4risc +f4rist fri6ster -f3roc -1f4ron -fro2na +2f3roc +2frol +1f4ro2n +fro4n1a +f4rop fro2sc f3rot +frös2 f3ru +f4ruc f3rü 4f1s -fs2amm -f2san -fs3ar -f2s1as -f2sauf -f2saus +f3sac +f2s1al +f2sa2n +fs3ane +f4s3ar +f2s1a4s +fsa2t +fs3ate f2saut -fsä4 -f3sc +fs2än +f2sca f4sce f4schan f4schef +f4schro +f2scr f2s1e2b +fse2ei f4sehr -f2s1em +fse2n +fs1en1e f2s1ent f2s1er fse2t f2s1eta -fsi2d -f3s2kie +f2s1i4d +f3s2ky f2s1o2 -f3span +f3soh +f3sol +fsp4 +f3spann f2s1pas f2sph -f3spi +fs2pie f3s2pl f3s2por -fs1pr f2spre -fs2pri f2spro -fs2pru -fs3s4 +fs2pul +fs3s2 +fs2tal f2stas +f3s2tat f4s3täti -f5stel f2stip f2s1tis fst4r f4s3tres fs1trü -f3stü -f4s3tüte -f2sty +f4stüte f2s1un f3sy 4f1t f2ta. -f2tab ft1a2be +ft1abl ft1af -f2t1al +f3t2ag +ft1ala ft1an -ft1ar -f3tat +f2t1ap +ft1a2r +ft3att f2t1äu -ft1e2h +f3te. +ft1eck +ft1edi +ft1eh +fte2he ft1eig ft1ein ft1eis +ft1eli +fte3ma +ft1emi f2t1ent -f2t1e4ti -f2th -f4thei -ft3ho +ft3erfü +ft1erk +f2t1erl +f2t1erz +f2t1e2ti +f2t1ex +f2t1h +f4t3hei f2t1id +f4tim +f2t1in +f3t2ing +fto2 +f2t1of +fton1 ft1op +f3tor. f2t3ot -f2t3ro -f2trö -f3t4ru +f3t4ran +f2t3res +f3treu +ft4rit +ft3ro +ft3ruh fts1 -ft2sa -ft4sa4g +ft2sa2 +ft4sag ft4sam +ft2sän fts2c ft4sche -ft2se4 +ft2se2 ft4seh +ftsen1 ft2si -ft4stä +ft2so +fts3tei +ft4stem ft4ster ft4stes -fts2ti +ft3stie +ft6stier +ft3stri fttra4 f2tum +ft1urk ft1url ftwa4 +ftwa6r ft3z2 +ftze3d 1fu 3fuc 3fug -3f2uh -f1um +f2uh +fuku3 +fulb4 +f1um1 +fu2mei +f2umm +fund3er +fun6derg +fun6derh 2f1unf +2fungl 2f1u2ni fun2kl fun2ko fun2k3r +fun2ku 2f1unm +2funr 2funt f2ur +furch2 fu4re. +2f3url fus2 fu3sse fus6sen fu4sser fuss1p -fus4s1t +fuss1t +fus4ste fu2ß1er 3fut 1fü 2füb +fühl4sc +fün2 fü2r -fü3s4 +fü3s2 2f1v -2f1w -1fy -2f1z +4f1w +f1y +4f1z fz2a fzeiten6 -fzei8tend +fzei8t7end fz2ö -fzu3 -fzu4ga -f3z2w +fzu2ga +fz2w 3ga. 2gabf -ga2b5l -gab4r +2gabg +2g1a2b3l +gab2o +g1abr +gab4ri +2gabsc +g2abt. +2gabtr +ga3bu +2gabw 2gabz -ga1ch -2gadl -2ga2dr +gade2r +ga3d2i +gadi4e +ga2dr +gae2 ga1fl +5gag. ga1k ga2ka +ga2ku gal2a -2g1a4lau -g4amo +ga3laf +ga2lar +2g1alau +2g1alb +2g1alg +gall4e +gal3lo +2g1alp +2g1alta +2g1altd +g1a2lu +ga2mec +ga3mel +gam3ma +5g4amo 2g1amt -2ganb -gan3d +g1a2na +2ganal +gan3d4 +2ganf +2ganga 4gangeb gan2gr -2ganh -2g3anku +gang4sp +gan2g1u +2g1ank 2ganl -g3anla +2ganmu 3g2ano +ga2nob +2ganr gans2 +2g1ansi +2ganst 2ganw ga1ny +2g1anz +ga3pe +2g1app +ga1q 3gar. -2garb +g2ara 2garc -3gard -2g1arm +3g2ard +ga3ret +ga3r2i +2g3arm ga3r2o -3g2ars 2g1arti ga3ru 2g1arz ga2s -ga3sc -gas3ei -ga4sem -ga3sp -ga4spe -ga4spr -gas5s -ga3s6ses -gas3tan +g2as. +ga4s3al +ga4sam +gasche4 +gase2 +ga5se. +ga4sei +ga4sel +ga4s1e4m +ga5ses +ga4set +gas5s2 +5g4asse. +g3asses +6gassess +ga5ssest ga4st3el -ga3str -ga4stra4 -gastras5 -gas4trä -ga4stre +ga3sti +ga4stin +gastra4 +ga6stras5 +gas4t3rä +ga3stri +ga6strom gas1tu -gat2a -2g1atm +ga3sun +ga3t2a +2gatm gat4r gau1c 2g1auf 2g3aug g2auk -g1aus +gau5ne +2g1au4s 2g1aut +ga3z 2g1äp -2g1ärz -gäs2 +gär3th +2gärz +gä3s2 +gä5st gä4u -2g3b2 +2g3b4 gbau5s gber2 gbi2 2g1c 2gd g1da +g3d2ad +gda3de +g2d1ak +g2d1an +g2d1ar g2d1au +g1dä1 +g2dei4 +gd1els +g2dent g2d1er -gd1in +g2d1et +g2d1in g1do +g2dop g1dö -gd3r +g1dr +gd3re +gd3ru gd3s2 gdt4 -gd1ur 1ge ge3a2 +ge4ate geb2a -gebe4am ge3ble -geb4r -ge1c +geb4lin +geb4lo +gebot2 +3gebü +ge1ch ged4 ge1e2 ge3ec ge2es -gef4 +geest3 +ge5fa +3gefä +4g1eff +gef4l +gef4r +ge3fu +g4eg +gege2n1 +gegene4 ge3g2l -ge3ha +geg4r +geher3l +ge3ho +2g1eid +ge4ie2 ge4ig -ge1im -ge2in. +g2eil +ge1in1 +ge2inf +gein4h +2g1einr gein2s -ge2int gein2v ge1ir -ge2is4 -2g1eise2 +geis4 +2g1eise gei3sh +geiss3c gei4sta +geist3r 2gek. ge4lanz gelb1r gel4b3ra +gelb5s +gel4den gelder4 +gel6derh gel6ders -ge3le -2g1e4lek +ge3lec +ge2lef +2ge2lek +2gelem +gelen1 +ge4lene +gel3ere +ge4lerk geler3ö ge4l3ers -ge4less +ge2l1ev +gel3f +gel1i4m gel3l2a gel3le -ge3lor -gel3sa +gell2i +gel2ö +gel3s2a gels2p -gels2t gel3sz -gel3t2a -ge3lü -gelz2 +gel3ta +gelt4r +gel3z2 gem2 -gem4e -ge3mi -3gen +ge4ma. +gem6e +4g1emp +gem3s +ge3mu ge3na -ge4n3ac +ge4n1ac +ge4nad +ge4nak +ge4n3al ge4nam +ge4nap ge4nar -gen2as +ge4nat gen4aug -gen2d1r -gen1eb -ge3nec +4genda. +gend3in3 +4g3endmo +gen2dr gen3eid -gen3ern +gener4f +4generg +ge4n3ern gen6erwe gener4z +ge2nim +gen3k4 genma7sse. gen3n +ge2noc +gen6semb +gen3sk gen3sz +gen3tä 2gentf -gen3th -4gentw -geo2r -ge1ou -ge3p4 +gen3t2h +gen3tr +2gentw +ge2nun +genzma3 +genzmas6 +gen3zw +ge1oo +geo2ri +g2ep4 +ge3pl +ge3po ge1ra ge2rab -4g3ereig +ge2rak +ge2r3al +ge3rann +ge4rant +ge4r3a2r +ger2as +2gerdg +ge3rem +ge4rene ge4reng ge4ren4s ge4r3ent ger2er +gerin4d gerin4f ger4inn gerin4t +4ger4klä +g3erlas germas6s +ger5me ger3no +2g1ernt ge1ro +ge2rob ge1r2ö -ger4sto +ger4sat +4g3er4seh ge3r2u -g1erwa -4g3erwer -ges2c +g6es. +3ge3s2c +ge6sche. +ge2seb +4g3e4sel. ges3elt ge2s1er +ge3sha ge3s2i +ge3so ges2p +ge3spa ges4pi gess2t gest2 +gest4a +gest6e +ge4s3tur get2a -ge3tan -2getap +g1etap +ge2thi +ge5trei +get1s ge3t4u 2g1e1ul -2g1ex -2g1f4 -4g1g +ge3unk +ge1urt +ge3u2t +4g1e2x +2g3f4 +gfi2l +2g1g gga2t -g3ge +g5ge gge2ne -g2g3l -gg4lo +gg2l +g3gla +g3glo g2g3n gg4r 2g1h 4gh. +gh2a 3ghale gh2e 3g2het 3g2hie gh1l 3gh2r +ghs2 g2hu gh1w gi3alo gia2s +gich2 +gicht1 gie3g gi2e1i -gi2el -gien2e1 +gi2e3l +giel2a +gie5n2e +gi4eno +gie3res +gies4 gift5s gi2gu -gi2m +gi2kel +2g1ill +3gime +gi2me. gi4mes -2g1ind +gi2met +2gimp +2gin2d gi3ne -g1inf -gin2ga +2g1inf +2gin4h 2g1ins +gin2sa +2g3int +2gin2v +gi2ob 2giok 2g3isel -gi3t2a +git2a +gitt6e gi4us 2g1j -4g3k2 +4g3k4 +gl2 4gl. -gl2a 4g1lab -g1lac -g2lade +2g1lac +2gladu 2g1lag +2g1lam 2gland -gla4s3ti +gla2s1c +glast4 +gla4str gla4stu 3g2laub -4g1lauf +2g1lauf +g1läd +2gländ +3gläs g1läß 2gläuf +gl3b g2l4e -2gle. -3gle3a +2g3le. +3glea 2g3leb g3lec -g3leg +4g3led +g3lee +2g3leg 2gleh -3gleic +g4leic 4g3lein +gleiter8s glei4t5r g3len +4glenk 4g3ler +glerei4 2gles +3gles. g3lese -g4lia +g2lia 2glib 3g2lid -g2lie +3g2lie +4g3lieb 2glif g2lik -2glil +4glil g2lim -4glin +2glin g2lio 2glis -g3lisc -3g2lit +g2lit +g3lite g2liz -3g2loa -3g2lob -4g3loch -glo3g -3g4lok +g3lize +g2loa +g2lob +g2loc +2g3loch +g2lok g2lom -3g2lop -g2lor -3g2lot +g2lop +2glorb +2glos +g2lot +2glöch 2glös +2glöw 2gls -g1lu2 +g1lu 2g3luf -2glun -4glu3s +2gluk +2g3lun g2lut -g1lüg -g2ly +3g2lü +g3lüg +2glw +3g2ly 2g1m2 -gmül3 +gmen4tr +gmi2s g1n 2gn. g2n2a g4na. -4gnah -3g4nat +2gnac +g4nad +2g5nah +gn4al +gna4l3er3 +2gnanl 3g2nä +2gnb +2gnc +2gnd gn2e g3neh -2gnel +2gn3ent gne2tr -2gneu +2gnf 2gng +2gnh g2nie g2nif g4nin -2gni2s1 +2gnint +2gni2s3 +gnise2 +2gnk +2gnl +2gnm g2no1 +3g4non g3not 2gnp +2gnr 2gns 2gnt 2gnu 3g2num. g2nü +2gnv +2gnw g2ny 2gnz go4a goa3li +g1ob +gobe3l +2gobj +g2ob2l 2g1o2f 2gog -2g1oh +2g1oh2 +goh3ren go1i2 gol2a -2gonis -2g1ope -2g1opf -g2o1ra +gol2da +gol2fr +3gon. +go4nat +gon2e +3gons +3g2opa +gopf4 +go2pos +2gopt +gor2a 2g1ord -2gorg -go2s -go3th +2g1org +go2si +go3sl +go2sp +2g1osz +3goß +go3t2h +got6terb got6t5erg +3gou go1y -2g1p2 +gö2f +g1öl +3göt +2g3p4 2g1q g2r4 +g4rab +gra2ba gra2bi -gra2bl +gra4bl 2g3radl 2g3rah -4g3rak +2g3rak +gram1 grammen6 gram8m7end +gram6mer +g3rand. +2gra2r +grar1e +gra4s3a +gra4sh +gra4sp +gra4str +2g3raub grau3f +2graum +grau3sk +2gräd gräs5c -2g3räu +g3räu 2g5re. g4reb 2g3rec -2g3rede +g3rede g4re2e +2g3ref +gre2fr +2grege 2g3reic -2greim -2g3rein +grei4fr +2g3reih +g3rein g3reit -g3rek -g4rem -2g3renn +3g4rem +3gren +4g3renn gre3no gren6z5ei +grenz3w g4rer +2grese +gres6ser6 g3ret g3rev 2g3ric gri2e +2g3riem g3riese -3grif 2grig -2g3ring +gril4la +4g3ring +4g3rinn +gro2b3a +gro3ber gro2bl +gro2b3r 2groc 2groh -gron4 -gros2 +2g3rol +gros4 2g3rose +g4ross gro5sse. gro7ssen. gro7sser. -gro5sses +gro7sses. g4roß -gro4u +g4rot 2gröh -g4ruf -2g3rui +2gruf. +g4ruft +2g3ruh +g3rui 2g3rum grun2g -3g4rup +3grup +3grus grus2s gru3sse -2grut +3gruß +2g3rut 2g3rüc -3g4rün +grüs2 4gs g2sa -gs1ac +gs3a2b +gs3ach +g3sack gsa2d -gs1af -gs1ag -g4s3a2k -g3sal -gs3all +gs3a2k +g3s1al +g4s3alb +g4sall +g4salm g4salt -gs3ama -g4s1amb -gs3an -gs3ar +g4sama +gs1amb +g4samp +gs3ane +gs3a4p +gs3a2r gs1as +g3sat +gs3ato +gsau2g +gsau4r +gsa2v gs1ä +g3sc g4sca g4sce gsch4 g4schef -g5schü -gs3cr +g5s2chi +g5schn +g4sco +gs3d g2s1e2 -gse3e -gs2eh -g3s2eil +gs2e3h +g5s2eil +gse4kl g3sel. +g4s3ela g3seln +gs3em gsen1 +gs2enk +g4sent g4ser -gser5f +g3sere +gs3er1i +g4se4s g4seu +gsfi2l +gsgene4 +gs3ha g2s1i gsi2d g3sig -g5sil -gs3l +gs3i2k +g3sil +g4s3io +g4sis +g4sita +gs2ki1e +gsmas8sen gs1o2 +gso4b +g5son +g2s3op +g5s4orge +g5soz gs1p4 +gs2pac +gs4pant +g5spei g3s2pek -gs4pie +g3s2pi +g5spie gs3pl -g5s2por +g5s6port. +g4s3pru gsrat4 -gs3s2 -g3star -gs1tau -g4s1tä -g5stäm -g5stel +gs3s4 +g2s1tab +g3stad +g2staf +g2s1tät +gs2te. +g5stein +gst2el +g5stell +gs4tem. g4stemp -gst3ent +gs4ten. +gste2r +gs4ter. +gs4tere +g6sterei g4sterm gst3err -g4s3test -gst2he -g3sti -gs1tis +gs4tes. +g4stest +g5steu +gs2thy +g3s2ti +gs3tie +gs3tis g3sto -g4ston -gs1top -g4s1tor +g4stoch +g4stod +g4stor gs1tot gst4ra gst5reit -gst4ri -gst5rit +gst4res +g4s3treu +gst3rit gst3ros +g2stru gs1trü -g3stun -gs1tü -gs2tüc +gs1tur gs1u +gs3un +gsü3s g3sy 4g1t g3te +gt1h +gt2hy +gt2i gti2m +g3to gt4r gt2se 1gu +gu4ale gu1an. gu1ant gu1as @@ -5066,372 +8000,600 @@ gu2e guet2 2g1u2f 2g1uh -gu1ins +gu3ins gu1i4s +gum2e 3gumm +gummi1 +gun2e 2g1unf -g2ung. gunge2 4gungew -2g1ungl +2gungl +2g1u2ni 2g3unk -g2uns -2gunt2 +2gunr +2gunt 3gur +gure4 4g1url +gur2t3h +gur2tr gurt3s -gu2s3a +gu4s3a +gu2sä guschi5 +gus3se. +gus3ses +guss1o gus2sp gus4st +gust3a4b +gu4stap +gu6stein +gu6st5en6d gu3sti +gu2str gu2ß1 +gußt2 gu2t gut1a -gu4t3erh -gut3h +gu3te +gu4t3er4h +gut1h +gut2s3p 2güb -gür1 +3gür3 gü3st -2g1v +2g3v 2g1w +gy3n +gy4na 2g3z2 -3haa +gzeu4gi +2ha. hab2a hab2e +hab2i +h1ablu 2habn +h1a2br +h1abs +2habw +ha4ch3en ha2cho +2hada ha2del -ha4din +hade2n h1adle +h1a2dr +ha3dri +2hae +ha3el +ha4far +haf2e +h1affä haf3f4l +h2aft +haf2tr haft2s hafts3p -h1ah +hag2a +h2agg +ha3ha h2ahs -ha3ia +h2ai +3hai. h2aj 2haka ha1kl 2h2al. +ha3l2al halan4c +h1a2lar ha2lau hal2ba -hal4bei -hal4b3r +hal4bel +hal4bin +hal2b3r +hal2bu 2hale +2halh +hal2i +2halk hal4lei -hal6lerf +hal6lere +haller6f +hal6lerg hal4leu -hal4lok -h1alp -halt5r -h1amt +hal4lo4k +ha3lo +4halp +hal2sp +hal4tal +hal4tei +hal2t3r +hamot2 +2h1amt +ham3te h2an. +2hana +ha2nal +ha2nan +han2au 2hanb +h2anbe h2and han2da -han2kr -h4ann +han4d3er +han2d3r +ha2nem +han2f1 +han6g5end +han4gro +hang3s +han2k1 +2hanl +2hano 2hanr -2hant +2hanz hao2s -h1ap +2h1ap +3h2ape ha2pl +ha2po ha2pr h2a3ra +ha4rab 2harb +2harc h2ard +har2fr h1arm. har3ma +h2arme har4me. -har4mes +har4ne +ha2rom +2hars +hart4e har2th h1arti +har2za h2as +2has. 2ha3sa -hasi1 +has2c +has4h3 +has4sa +hasser4 +hass1t +ha4str ha2ß1 +h1aße +ha2ta +hat2i +h3atl +ha2t3r +2hats hatt2 +h3attr +h1audi +h1aufb hau5f6lie +hau3f4lo 2h1aufm +h1aufs +h3au3g2 h1aukt hau2sa hau4san -hau2sc +hau2s1c +h2ause +hau4sel +hau6s5ent hau4spa +hau4spe hau4ss -haus5sen +haus5sen6 hau4s3ti hau4sto +hau4sur h2aut. -hau6terk -2hauto -hau2tr +hau2t1a +hau2t3r +ha2ve. +häde2 h1äff -h1ärz +2häi +hä2kl +2härz hä4s hä5sc hä6s5chen +2h1äst +2häug häu2s1c hä3usp -2h1b2 -hba2r3a +2h1b4 +hba4ras +hber2e 2h1c 2h3d4 hdan2 2hea he2ad -hea5t he3be -he4b1ei -he2bl +heb3eis +he2b3l he3br -he1ch +he3bu he3ch2e -h3echt +he3chi +he1cho +h3echs hed2g -he3di -he2e3l +he2dit +he1e4m +hee2n hee2s +he1e2t +h2ef. +he3fab he2fan -he2fä +he2fau he2f1ei +he3f2em hef3erm 2heff he2fid -he4f3ing -he2f3l -he2fr -he3fri +he4f3in4g +he2f5le +2hefr +hef4ra +he2fre +3heft he2fu he3gu +he2hel +hei4a h4eib h1eie h1eif h1eig he2im +hei4mal +hei4mar +hei4mei heim3p hei4mu 2hein +hei4na heine2 -4heio -he1ism +hei4n3eb +hei6nene +hei4n3er +h3eintr +2heio +2he1ism +heis4s he1i4st +h2eit heit4s1 h1eiw -he2l3a +hekt3a +he2la +he3lag +hel1an +hel3au hel1ec -h3e2lek -he3len -hel3ers +he2lek +h3elem +he2len +h2elf he3li +hell2a hell3au +hel4lic hel4mei -he3lo -he4lof +he3l2or he2lö -3hemd -he3mi -3hemm -4h3emp +4helt +h4em. +2hema +hema4s3 +hem2b +1hemd +2heme2 +h2e3m2i +he4mia +h3e4miss +1hemm +2h3emp h2en. -he4na2 -hen3a4g +he4n3a2 he2nä -he2n1e2b +hen3ebe +henen1 hen3end +he4nene +he4nens hen3erg -he2net -heng2 -2heni -he2no -hen3sk -hen3s2t2 +he4nerm +he2n1e4t +2henga +hen4gag +hen4kan +hen4kau +2heno +heno3t +hen4sem +hen3st2 +hent2a +hen3te +hen4ter +hen3tr h1ents 2h3entw -hen3z -4he2o +h3entz +he4n3u +hen3z2 +2he2o he3on he3op he3pa he3ph +h1e2pi +hept2 h2er. her3a2b -he2ral +he2rad 2herap -he3ras +he4r3a2r herau2 -herb1r -her4b3ra +herb2 +he2r1e2b he4reck -4hereig -he4r3eis +her4eif +4he3reig +he6reis. +her7eises he2rel +he4rene +he6rersc he4rerw -h1er2fo -h3erfü -herg2 -her2ho -4herif +h1erfo +her4fol +6hergebn +2herif +herin4d herin4f he6rin6nu herin4s -herin8ter h1erke -h3erlau +her4klä +h5er6kran +h6erlad 2herm herma3s he3ro he4r3o4b -h1erö -hers2t -hert2 +he4rof +he4rop +he4rot +h1erör +her3sta +hert4 her3th +her3um +her4zap +her6zeng +4h3erzeu her2z1w +he3sa +2hese +he3si +he3s2p +hes2t he2tap +he3tä heter2 he3th het2i he3t4s -h2e2u +he2u heu3g +he3unt 3heusc he3x he1x2a -he1y2 +2hexp +hey2 +he1ye 1hè -2h1f4 -hfell1 -hfel6ler +4h1f4 +hfaller6 +hfan2 +hfel2l3 hfi2s -2h3g2 -hget4 +hflei2 +2h3g4 +hgas1 +hga4sen 2h1h2 hhoh2 4hi. 2hia -hi2ac -hi2ang -h2ias +hi2ar +h1iat +2hic hi1ce -hich6ter -2hi3d -h2ide -h1i4di +hich6t5er +hicht6sp +hi3d +hid4e +hi4dio +2hido hi2e hi3ens -hier1i +hie4rei +hier3i hie4rin +hiers2 hif3f4r -hi2kr +hi2k3r hi2l3a4 +hile3n2 hil2fr +h2im +2hima +h1imb +h3i4mit +h4imm +h3impe hi2n -h1indu +hi3nak +hi3nam +hi3nap +hi5n2as +h2inde +hine2i hi3nel -hin2en +hin2en5 h1inf h1inh -hi3n2i +2hi3n2i hin3n2 -hi3no +hi3n2o3 hin2t1a 2hio +hi3ob hi4on -hi3or -2hip1 -hip3f -hi2ph -hi2pi -h2i2r +hi2p3 +hi4pl +hi2r hi3ra -2hi3re +hi3re hi3ri +hir2m1a +hir2mi hirn1 hir4ner -hi3ro hir2s +1hirt +2his. his2a hi2se +h1i2so hi2spa -hi3ti -2hiu +hi3tac +hi2tan +hi2tel +hi3t2i +hit1r +hi2tro +hit3z2e +hi2v1o 2h1j 2h1k4 +hkamp2 +h2keu +hki2n1 hklo3s -4hl +2hl hl2ag +hla2gr hlam8meng -hla2n -hl1anz +hlan4d3a h1las h1lat h1laut +h1lay h3läche h3läd -hl1är h1läs h1läß h1läu hlb4 hl3d4 +h3le. +hle3a h3leb +h3led hle3e -h3lein h2leis +h3leist +hl1el h5len. -hl2eng +hle4nas +hlenen3 hl2enn +h4l3entr +h4lents +hl2enz h3ler -hle2ra -h2l1erg +hle2r3a +hl4ere +h2lerg +hler4hö +hl2erk h6l3er4nä hle3run hl1erw h4lerz h3les h4lesi -h3lex +hlf4 hlg4 h2lie +h3lied h2lif h2lim hl1ind +hling4s3 h2lip h2lis h3list -h2lit -hl3l +h2lit1 +hl3l2 hlle3b +hl3m2 hlma3s2 h2lo +hl1ob h3loc -hl1of +hl1o2f +h3log hl1op h4lor -hlo2re +hlo2ra +h3los. h3losi +hlos4st +hlo2ß1 h2lös3 hlö4ss +hl4sar hl2ser -hl3sku -hl3slo -hlst4 -hls2te -hl2sto +hl3ska +hl3s2lo +hls3tie hl3str +hl2su hl3t2 h3luf h3luk h3lumpe h1lüf +hlz2 2h1m -h2mab h3mad h3mag +h3mak h3man +h2mant h3mar +h4marc h3mas hma3sse h3maß @@ -5439,43 +8601,64 @@ h3mä h4mäc h4mäh h4mäl +hm2e h3me. -hme1e -hme1in +h3med +hme1e4 +hmeer4s +h3mein h3meist +h3meld +hme3le h3men hmen2s -hme2ra +hme4ran +hme4rei +h3mex +hmi2e +h3mind +h3mini +h3minz +h3mirr h2mo -h4mon -h3mö -hm3p4 +h3mop +h3mot +h3m2ö +h4möl +hm3p2 hm2s1p h2mu h3mul -h3musc h3musi +hmut4s 2hn h2na +h3nag h3nam -hn1an +h4nar +hn3a2te +h4natt h3nau. -h2nä hn1äh -hn1är hn3d4 hn2e hne3b -hne2e +hne2e3 +hn3eff hn3eig hn3ein h2nel -hne4n1 +hne4n +hn4eng hne4pf h3ner +hner4de hner3ei -h4nersa +h4n3e2ro +h4n3ersa hn3ex +hn3f4 +hnflei4 hnhof8stra8s h2nic h2nid @@ -5483,67 +8666,98 @@ h2nie hn1im hn1in h2nip -hn3k4 -h2nor -hn3s2k +hni4sa +hnk4 +hnno2 +h2no2r +hnra2 +hn3sa +hn3s2p hns2t hnsuch4 hntra4 hnts2 -h1nu -h2nuc h2nul -hn1unf -h3nunge -ho2bl +h2n1unf +hn3z2 +ho4ar +ho3bern +ho2b3l ho2c hoch3 +hoche2 hock3t 2hod -hoe4 -ho2ef -ho4fa -hof3fa +2ho2e +hoe3n +ho3er +ho4f1a4 +ho2fä +ho2fed +ho2feu +hof3f4a +ho2f3l +ho2f1o ho2f3r +ho2fu 2hoi -3hole +ho2l1a +hol3ar +1hole ho2l1ei +ho2lem hol3g4 -ho4lor -3hols -h1o2ly -3holz +hol3k +holl4 +2holy +h3olym +1holz hol6zene hom2e +ho2me. ho2mec ho2med h2on hond4 -hono3 -2hoo +hon2er +ho1on +hoo2r 2hop +h1ope ho1ra -hor3d +h1o2r2an +ho2rau +h1or3d +2hore +ho4rens +ho3ret 2h1org -ho3se +hor3ta +hor4ter +hort3s +h1ortu +h2os. +ho3se2 ho4sei ho3sl -ho4sta +ho4sla ho2str +ho4ßene 2hot. ho3th -hotli4 +2hotr 2hot1s2 -3hov +1hou +hou4s 2ho2w1 -h1o2x +h1ox ho1y2 hô1 1h2ö +2hö. hö2c -3höhe -h4ör -hö4s +5höhe +2hö4s hös1c hös3se h3öst @@ -5551,84 +8765,105 @@ h3öst h1q 2hr hra2b -hr1ac +hr3ac hr3ad +hr1a2g +h1r4ah h1rai h1rane +hr3ap +hras3s h3räu +hrb4 hr1c hr3d h2rec -h3rech +h3r2ech h3red h3ref +hr3eff +h2r1eh h4rei. hrei4ba +hrei4br h3reic -h4r1eig -h3rel -h3ren +h3reif +h4r3eig +hr4eini +h4reinl +hrei3th h3rep -hr4erbe -hr4erbu -hr2erg +hrer6geb +hr2erh hr2erk -h4rer4la -h3rerle +h4rerla h6rer6leb -hr6erlei hr2erm +hrer4sa +hrer5st +hr2erw hr2erz h3re2s1 +hres5s2 +hrest2 hre2t h2r1eta -h3rev +h2r1eu +h2rev hrg2 +hrga4 +hrgu4 h2ri h3ric h4rick hri4e h3riesl h3rin -h4rinh -hr1ins +h4r1ind +hr1int h4rist hr3l -hrm2 -h2rob -h2rof +hr3m2 +h3rog h3roh -h3rol +h1ro2l +h4romat h4rome h4romi +h4romo h4ron -h2ror +h1ropa +hro4r h3rou -hrr4 +h3rö2s hr2s1ac -hr4s3an -hr2sau +hr4s3and hr3sch -hr2s1en -hr2ser +hr2s1em +hr2sen +hr3sena +hr2s1er hr2set -hr2s1in +hr4sh +hr2sin hrs3k +hrs3l hr2s1of +hrst2 hr4stec +hr6stele hr2su -hr4sw -hr2t5ab +hr2tab hr2tan +hr2te2l hr2th -hr2tor -hrt3ri -hr2tro -hrt2sa -hrt2se +hr2top +hrt3ric +hrt2s hrt4ste h3ruh hr1ums +h3rut h3rü h4rüb h4ry @@ -5636,43 +8871,88 @@ hrz2 4h1s h4s3acht h2sa2d +h2s1alk +h2sall h4samt h2san -h2sau +hs3and +h2s1as +h2sath +h2sato +h2saud +h4s3aur +h2saut h2säh -hsä4s +h2säug h3sc h4schan -h2s1ec -hse4ler +hs2cr +h3se. +h2s3ec +hse4e +h4s1ehr +h2s1eie +h4seind +h6seinst +h3sele +hse4lin +hs1emi +hsen5erg +h2s1ent +h2s1erf +hs1erg +h2serh +h4serkl h2s1erl -h3s2ex +hs1ern +hs4erne +h2serö +h2s1erw +h2serz +h2sex +h3s2ext +hsha2k +h2s1i2d +hs2im h2s1ing -h2s1o2f +h3s4inni +h4s1ita +hs2kal +h3skand +hs1of +h2sofe +h2sop +hs1org h2spac +h4s3pani h2s1par -hs2pen +h2s1pat +h3spec +h3spei h2sper h2sph -hs2por +h2spo +h3spoi h2sprä h2spro hss2 h2staf hst3alt hst2an -h4starb h2stau h2stäl +h2stäu h4stea -h5stel -hst2he -hs1tie +h4stele +h4sterm +hs3tier h2stin +h2stit +h2s1tol h2s1tor h3stö -h3str -hst3ran +h4s3treu +hstro2 h2stu h3stun h3stü @@ -5681,96 +8961,150 @@ hs2ung h3sy 4h1t ht1a -h2tak -h3t4akt. -ht2al +h2tab +hta2bl +h2ta2d +ht2ag +ht4akt. +ht4akte +h2tall h2talo -ht3alt +h2talp +h2talt hta2m -h2ta4n +h2ta2n ht3ane h3tank -h3tann -h2tar +h2tap +h2ta2r ht2as -h2t3ass +h2t3asi h2tasy -h2t3a2t +h2t3at +h3tat. +h3tate h2tau -ht3aug -h2tax -h2t1är +h3taug +h4tax +ht1ä +h2tär h3te. +ht3e4ber ht1ec -h2t1ef -ht1eh -h3teha -h3tehä -hte2he +hte3cha +h2t1e2d +ht1eff +ht1e2he h2teif -h4teilz +h2t1eig +h4t3eilz h2t1eim ht1ein h2t1eis h2t1eke +ht3elas +hte6l5ei. +h4telek +h4t3elfe h4t3elit +hte4m +ht1emi h2temp +h3ten. +ht3engl +ht3enta h4tentf -h4t3ents hter6de. +hterer6s +ht3erfo ht3erfü +h6terfül +h6tergeb ht3ergr -h2t1er2h -ht5erken -h4terkl +hter6gri +ht1erh +hter6häl +hter8höhu +h6terleb h6t5erleu -h4t3er4re -h6t5er6spa -h4t3er4st -ht6erste -h2t1erz +h6terneu +ht5erspa +hter8spar +ht3erst +h6tersta +hter6tra +ht3erwä +ht3erze h2t1ese h2t1ess +h2teta +hte4th h2t1eu -h2t1ex -h2th +h3teum +h3teun +h4textr +h2t1h h4thei -hthe3u +h3thera +h3thes +h4tho +h2t1i2d +h3tig h2t1im -h2t1in -h4tl +h2t1i6n3 +ht3ine +h2t1is +h3tisc +hti3t4 htni2 -hto2 -h2toly -h2torg +h2t1ob +hto2d1 +h2t1o2f +h2t3oly +h2tope +h2tord ht3rak +h3tran ht3rand -h2t3ras -h2t3rat +h4t3ras +ht6rates ht3rau h4traub ht6raume -h3trec -ht3reif -ht3reit -ht4ri -ht5rieg -h2t5rin +ht3rec +h3treck +ht3rei +h2t3res +ht3ric +h4t3rieg +h2t3rin h3trit -ht3ro -h2trol -h2tros -ht4rot -ht3rös -h2t3ru +h2t3rol +h2t3ros +h2t3roß +ht3röm +ht3ru h2t3rü h4ts -ht4s3an +ht2sah +ht2sal +ht4s3a4n +ht2scr +ht4sein +ht2sel ht4s3end -ht4spin -ht3spri -ht4stab -hts2ti +ht4seng +htse2r1 +hts3eri +htsha2 +ht3s4hak +hts3kr +ht2s1o +hts3par +hts3tät +ht4s3tem +hts4tie +ht4stip ht4s3tur ht4s3tür htt4 @@ -5781,268 +9115,418 @@ ht3z2 hu2a hu2b1a hu2bei -hu2b1en +hu4bel +hu2b1en2 +hu2bi hu2b3l -hu4b3r +hu4b5r hu2bu -hu2h1a +hu2fa +hu2h3a hu2h1i +h1uhr +h1uhu +hu2kä +hu2k1in huk3t4 -hu2l3a +hu2l3a2 +hu4lab hu2lä -hu2l3ei -hu4leng +hule2 +hu2l1eb +hu2l1ei +hu2lem +hu4l3eng hu4lent -hu4ler +hu2l1er hu2let +hu2lid hu2l1in -hul3l +hul3l2 hu2lo +hu2lö +hul3s hu3m2a +h1umh h1ums hu2n h1una -hu3ni1 +h2und +hun3d2e +hunde3i +hun2e +2hunf +hung2 +hun3ge +hungsa4 +h1uni +h1unm +2hunt h1ups -2h2ur -hurg2 -hu3sa +2hur +hur3g2 +hur2t3h +hu3s2a +hus3h hu2so -hus4sa +hus2s3a hus3se +hus4ser4 +hus2s1o hus2sp hus4st +hu2ß1 hu2tab -hu3t2h hu2ti +hu2t1o +hu2t3r hut2t hut4zen hut4z3er +hut2zu h2ü +h3über h4übs h3übu +hüf2 +hüft1 hühne4 2h1v -hvi2 -hvil4 -2hw +hvil2 +2hw2 h2wall hwe1c h1weib h1weih +hweins3 +hwein6sa +hweis4s h2wirr -3hyg -hyl4 -3hyp +1hyd +hy3dr +hy2lor +1hymn +h1yo +hy3os +1hyp hy2pe. 2hy2t 2h1z hz2a -hz2o +h3z2o hzug4 -i1a -2ia. -i4aa -i2ab -iab4l -2iac -i2af +h3z2w +i3ad. +iad2a +i1adn +ia3do iaf4l -i4a3g2 -i2ah -i3ai -i2aj -i2ak +i2ago +ia1h2 +i1ai i3ak. -i3akt -2ial -i5al. -ia2l1a4 +i3ake +ia2kei +ia2kr +i1akt +i1al +ia2l1a2 +ial3ar +ial3as ia2lä -ial3b -ial3d +ial3b4 +ial3d4 +i3aleb +i3alef i3alei +ia3lek +i3alel +i3aleng i3alent -i3a4lerf +i3alerb +i3aler4f i3alerh -ia4l3erm -i3a2let -i3a4lia -ialk2 -i3al5l -ia2lor +i3a4lerm +i3a2l1et +i3alex +i3a2lia +i3alim +i3a2lin +i3al3l +ial4ler +iall2i +i2alo +ia2lon +ia2lop +ia2l1o2r +ial3p ial3s -ial3t4 -ia2lu +ial3t2 +ia2l3u2 ial3z2 -i2am4 -i4amo -2ian +i1am. +ia3ma +iampe4 +i1ams +i1an. +i1an2a ia2nal +ian3alt +ia2nau +i1anc i3and2 -ian2e -i3ann -i2a3no +i3a2n1e2b +ian2er +i1ann +i1ans +ian2s1p i3ant i3anz -i2ap -ia3pf +ianza4 +ia1o +ia2op +ia3p ia1q +i1ar i3ar. ia2ra -i2asc +i2are +iar3r +i1as +i3as. ia3sh i2asi -i2a1sp +ia1s2p ias5s iast4 i3at. -i3a2ta -i4ate -i3at4h +i3at2h +i4athe 1iatr i3ats i3au ia3un iau2s1 -2iav +i2az 2iä -i1äm +i1ä2m i1äp i1är. i1ärs -i1ät. -i1äta -i1ät3s4 -2i1b +i1ät +i3ä4tem +iä2ti +iät5s2 +i1äv +4i1b ib1art i2b1auf +i2b1aus +i2baut ib3be ib2bli -ib1ei -i2beig -i2beis -ibe4n -iben3a -ibi2k -i3bla -i4blad -i3blä -i3ble -i4bleu -ib2o +i2b1eig +i2b1eis +ibe4n1 +i6ber6geb +i4b3er4la +ibe1ro +i2bim +i2b1in +i2blad +i2bleu +i3blu +i3b2o i2bö -i4brä -ib3ren +i2b3rau +ib3ric +i2b3roc ib2ser ib4ste -i2bunk -i2bunt +ib2un +i2b3unk +i2b3unt +ibus3 ibus1c -ibus3s 2ic +i3ca ic1c -ich1a +ich1a2 +ich6art. ich1ä i1che ich1ei +ich2er +icherin5 ichermas8 ichgro3 i1chi -i2chin -ich3l -i3chlo -ich3m +ich1l +ich3le +ich3li +i3ch6lo +ich5m ichmas4 +ich3n i1cho +ich3ort i2ch3r -ich3ter +ich6sele +ich2s1i +ich6stie ich2tr i1chu ich1w i1ci -icks2 +ickt2 i1cl +ic3la +ic3ra +i3cu i1d -id2ab4 +2ida +id2ab i3d2ac -i3dam +id4al +id2am +id1a2n +i3d2ans +i3d4at id1au +id2ax +idä1 idbu4 -1i2dee -idein3 -i4deis -idel2ä +id2e +2i3de. +i2dea +1idee +id3eis +2idel +idel4ä +i4demul +4i3den. +ide4n1o +iden4se +ide3ran +iderin8nu +ide1rö +ider6reg +2i3des +ide5sa ide3so -1i2dio +ides2p +1i2di2o +idi4on +i4diot +2idk idni3 +id2o i2dol -1idol. -2i2dr -i3dsc +2idoo +i2dö +i2dr +id4ro id2s1p idt4 1i2dy -ie3a4 +ie3a2 ie2bä ie2bl -ie2bre +ieb3re ie2bri +ie4b3rü ieb4sto -ieb4str ie1c ie2cho +iech3t +ie2d3an +ie3de ie2dr ie1e2 -ie2f1ak +ief3akt ie2f1an +ie2far ie2fau +ie2fäh +iefe2m ief3f4 ief2i ie2f3l +ie4fonk +ief1r ie2fro -ie4g3l +ie2gl +ieg5li ie3g4n -ie2g3r -ie3g4ra +ie2g3re ieg2s -iegs1c +ieg6s3c ieg4se -ieg4s1t +ieg4si +ieg6s1t +ie3her +ie2h1in +ieh3r2 i1ei +ie1ind i2e2l1a -ie3las -iel3d +iela2r +ie2läs +iel3d4 i2ele +ie4l1e2b iel1ec -ie3lerd +iel3eid +ie2lek +i4elen +ie4lene +ie4leng +ieler4e +ieler6fi ieler8geb -ie4less +ieler6ke +ieler6la +ieler8lebn +iel4erw +ieles2 i2eli +ieli2d i1ell -iel3lä -ielo4b +ie2lo4b +ie2lop +ie6lor i2els2 iel3sz -iel3ta -2i1en +ielt2 +iem2e +iemis2 +i1en i3en. i3ena -iena2b -ie4n3a4g -i3e2nä -ien3d +ien1ag +ien2am +ie4nas +i3enä i2ene ien1eb -ie3ner -ien4erf -ie4n3erg +i3enec +i3e2n1e4k +iener6fo +ien3er4g +iener6la +i3enex i3enf -i3eng +i3eng4 ienge4f +ienge4z i3enh +ie2nid +ie2nim +ie4n3in i3enj i3enk +i3enla +i3enle i3enm ienma3s4 i3enn @@ -6050,566 +9534,905 @@ i3e2no i3enö i3enp i3enr -ien3s2e -iens2k +i3ens. +i3ensa +i3ensc +i3ens2e +ien3s2k +i3ens2p ien6st5er ien6stop iens4tr ienst5rä -ien3sz -ie1nu +i3en3sz +ien4t3ar +ien3te +i3enth +ien3tr +i3enty i3env i3enw i3enz -ie1o2 -iera2 -ier3ad +ie1o4 +ie2r3a2d +ier3al ier3an ie2r3ap +ierb4 +i3erbun +ier3d i2ere -ie3red +ie4reck +iere5ins +ie4r3eis ie3r2er -ie4rerf +ierer3k ie4r3erz -ie3res -i3ereu ierf4 +ierg4 +i1ergi i4eri -ierin3 -ier3k4 +ierk4 ierken4 ierma6ss i1ern i3ern. -i4erna -i2er5ni +iern2a +i2erni ie2rö -iers2e +ier4re. ier4s3eh +ier3sei ier3sta ier3te -ie3s2 +iert2i +ier3z2 +2ie3s2 +ie4san +i2esc +i2ese ie4sh ie4s3k +ies3o +ie4sof ie4spu -ies4s -iess1t -ie4stas +iesser6g +ie5sset +iess3ti iest6e -ie2t1a +ie4stin +ießer4g +ie2t1ag +ie2t1ak +ie2tan +ie2t1ap +ie2tat +ie2tau +ie4tent ie4t3erh ie4t3ert -ie2t3ho -ie2t1o -ie2t3ö2 -ie2tri +i4ethe +iet3her +ie2t1ho +ie2thy +ie4tob +ie2t1ö2s +ie2t3ri ie2t3ru iet2se i1ett +iet3zw ieu2e ie1un ie2w3u -i1ex +i1e2x 2if +if1ab +if3ange if1ar i2f3arm if4at -if1au +i2f1au +if1än i2fec -ife2i -if2en +i2f1ef +ife4i +if1ein +if2e4n +i2f1erg if1erh if2fa iffe4s if6feste -if2fl +if2f3l if4form +if2fro iff2s +iff4ste if3l -i1f4la +if1lac if4lä +iflo4 +if4los i1flü if3r -if4ra -i1frau i1fre -if4rei -if4rü +i2freg +if4rev +ifrü4 if3sa -if2ta -ift3erk +if2t3a +if2ted +if2t3ef +if2t1ei +if2te2l +if2tep +if4terk +ifte4s +if4t3esc +if4th if2top -if2t3ri +if2t1r +ift3ri ift1sp ifts2t ift3sz +if2tur +i1fy 2i1g -iga1i -i2g1ang +i2ganb +i2garb ig1art iga3s +i2g3att +igd2 +i6gebrau i4gefar +ige4füg +3i2gel. +ige5lau +i2geln +ige4me +ige4mis ige4na +ige6nene +ige4nid +igen5s +ige2o +ige2pa ige2ra -ige3ran igerma3 +ig5erwer ig1erz -i2g1im +iger4ze +ige4sel +i2g1ess +ige4tra +ige4tre +ige4woh +i2gim i2gl -ig1lä -i4glo +ig1lau +i3gle +ig3lim ig4na i4gnä i3g4neu ig4no -i3go -ig4ra -ig3rei +igo1p +ig3rad +i2g3re +ig4ren igro3 -ig3s2a +i2grou ig4sal -igsau4g -ig1so +ig3sä +ig4schr +ig1s2o ig1sp ig2spa ig4sti ig4s1to ig2stö -ig4s3tre +ig6stra6s +ig4stur 2i1h -i2h1am i2har i3he ihe1e +ih1elt ihe4n +ihe3u ih3m ih3n -ih3r +ih3r2 ih2s ih3sp -i2h1um +ih3sti +ih1um. ih1w ii2 ii3a4 i1ie -i3i4g +i3ig i1im -i1in +i3in i1i4s i2is. ii3t +i1it. i1j +1i2js 2i1k -ik1ak -ika4ka -ik1amt -i2k1ano +ika2ge +ik1aka +ikaken3 +i2k1akt +ik3amt +i2k1ang +i6kantei ikanten8n -ik1anz -i4kanze ik1art ik3att i2k1au -i2k1är +i3kaz +ik1äh +i2k1än +i2kär 4ike +i2keb +ik1ebe +i2k1ed +i2k1ef i2k1ei -ik2e2l1 +ike4l1 +ike2n1 +ik1en2s +ik1ent +ike2ra i2k1e4r2e -ik1erf -iker6fah +i2k1er2f +i5kerfam i2k1er2h i2ker2l +i2kero +i2ke3ru i2k1eta +4iki i3ki. +ik1i2d +i3kie ik1in -i2kind +i2kins i2k3l -i3kla -i3k4lä -i2kn -ik3no -ik2o3p4 +ik4län +i3k4leri +i3k4let +ik4lim +i3klu +i2kne +ik3nu +iko3be +i2k1off +iko1p2 +ik1or +iko2ri ikot3t i2köl -ik3ra ik3rä ik3re -ikro3 -ik3so +i2kres +ik4ris +i3kro +ikro3s +i2krö +ik3sa ik3s2z -ikt2e +ik3ta ikt3erk -ikt3r -ik2tre +ik4t3esk +ik2t3re +ikt2u +i2k1uh +i2kup i3kus +i2kü i1la -i2l3ab -il1a2d +i2lab +i2l1ac i2l1ak -i2l3a2m -il1ans +il1a2ma +il1ang +i2l1anm +i2lano +il2anz +ilan6zer +i2larb il1asp -il1au -il4aufb -il3aus -i2laut +i2l1au +i3laub +i3l4aufb +ilau2s1 i1lä1 -4ilb +i2lär +2ilb +ilb4l il2c +il5chen il2da -il4dac +il2dä +ild3ebe il4d3en4t -il3d2er +il3der +ild4erp +ildi2 ild1o il2dor il2dr +4ile il1ec ileid4 il1ein il1el +i2lemb +i2l1e2mi +il1ent +i4lentl i4lents -i2l1erf -i2l1erg -i2l1err -il2erz +i2l1erd +iler4ei +i6lereig +il1erf +iler4fo +i2ler2g +i2l1er2h +i4ler4kl +il1err +i4lerri +i3l2erz +ile4th +il1ex +ilf2 il2f3l il2f3re ilf4s1 -ilg2a il2gl -ili3e4n1 -ilig1a2 -ili4gab +2ilh +2ili +ili3e4n3 +iliga2 +ili4g3ab +ilik4 i2l1ind +i4l3init +il1ins i2l1ip -i3lip. -i3lips -2ill. -il3l2a +ili1pf +il3la il4lad -ill4an +ill2an +ill4ant il2lä2 il2leg ille4ge +il4lenn il3l2er -ill2i -2ills +1illu il2mak -il4mang -il2m3at +il2m1ap il2m1au +ilm1ei il2min +il2mor 2ilo -i2l1or +il1ob +il2oh +il4on +il2op +i2l1o2r +i3lou +i3lov +il1ox +ils3ent +ils2to ilt2 il3th -il3tr -i1lu2 +i1lu +iluf4 i2lum +i2l1ur i3lus -ilv4 +ilü4 +2ilv4 il2zar +il2zau ilz3erk -2im. -i2manw +il2zwa +imad2 +ima1i +im2al +i2m3anh +i2mans +i2marc +im3aren i2m1arm +i2m1art im4at ima2tr imat5sc ima4tur -2ime +im1aus +i2maut +im3b +i2meg +im1ein i2mej -i2m1ele +i2mek +i2mele i2melf -i3men -i2m1erf -i2m1erz -i4mesh +im2en +i2m1er2f +i2m1er2l +i2m1er2z +i4me3sh +imes3s i2meti -i2m1inf +i2mew +imhau2 +i2mid +im1i2de +i2mim +i2m1ind +i2minf i2m1ins -im4m3ent -im4mit -im4mod +3immatr +immen1 +imm3ent +im6menth +im2mit +1immo +im4mo2d +im2mö imni2 2imo -im1org +i2m1ob +i2m1o2p +imo3re +i2mö +1imp imp2fa -1impo -imp4s +im3pf2o +imp2s im3pse -1impu -im2str 2imt +imt2e +im3t2i imtu2 2imu +im2um +im1urk +2in. +ina2be +in3abu in1ac -in3ach. i4nack -i2n1ad -in2af -ina4lin -in1am -i3nap -in2ars -in2art -ina4s +in1ad +i3nald +inaler4 +ina6lere +in2alp +i2n1am +in2an +in3an. +in3ana +in3ann +i2narb +in3att i2n3au2 inaus1 -in1äh +2inä +i2n1äh +in2är in1äs -inbus2 +2ind. +inda2 +ind2ac in2dal in2dan -in3dau +2indä +2inde. +2inden +ind5erke +inde3sp indes4t 1index -in3do +ind2i +1indik +in3dö 2indr ind4ri -in3drü +ind3se 1indus in3d2ü 2ine -i2n1e2be -in1ehe -i2n1eng -in3erbe -i4nerbi -in2erh +in1ec +i3nee +i2neff +in4elen +ine2n1 +ine3nä +i4nen4zy +i5ner. +i4n3erbi +in4erha +i4ner4he +i3nerk +i3n3erle +i6ner6leb iner4lö i4n3er4tr i3nes -i4nesk +in2et in1eu ine3un -ine2x -in3f -1info. -1infos +in3f4 +1infek +1infiz +1info 2inga -ing1af -in2g1a4g -in2gl +in2g1af +in2g1ag +in2g1al +in2gam +ing1ar +2ingä +3ingeni +in3g2er +in4g3er4w +2in2gl +in3gla ingmas4 -ing3sc -ing4sto +ing4sam +ings6por 1inhab 2inhar 2inhau -4inhe -in2i3d +2inhe +2ini. +in2id +ini3de +2inie 2inig -ini3kr -in2ir +inig2a +ini3k4r 2inis ini3se +init2 i3nitz 3inkarn +1inkas +in4k3ent +ink4er +in2kro +inks1t ink4ste in3k2ü inma4le 2inn. -in4n3erm +inne4n +in4ner4m in2neu in4ni2v 2innl in2nor -inn4sta 1innta 2ino in1od +ino3e4 in3ols in1or -ino3t +i3no3t +i2n1ou i1nö in1ö2d -2inp 2inr +2ins. ins2am +in6samt. insch2 2inse. in2seb +2insed 2insen -ins3ert -in3skan -in3skr +2insk +3instal in4s3tät -ins2te -ins2ti -in3su +4inst2e +3instit +4instra +in4strü 1insuf -in4s3um -in3s2z -i4nt +ins3umz +in2sur +in3sz 2inta +2inte. 1integ -int2h -in3t4r +in3tei +2intep +2int2h +inthi1 +in3ti +int2o +2intö +2in3t4r +4inträ +3intrig int3s -in1u -i3n2um +i2n1u +i4nuh in3unz -invil4 -i1ny +inu3t +4inverm +invil2 +i1ny2 +in3z2e +inzel8ler +in3z2i +in3z2sc +inz2u +in3zw i1ñ 2i1o ioa4 +iob2l io1c io2d -i2oda +io3da io3du -io3e2 +io3e4 +i2of iof4l -i2o3h -io2i3d -io3k4 +i2oh +io1i +io3k6r i3ol. +i3ols i3om. +io3me i3oms ion2 i3on. -ional3a +ion3an io2n3au -ion3d +ion3d2 +io4nee +i3ono +io2nor i3on4s1 -ions3p -ion3t +ions3a +ions3el i2ony +i2oo i2o1p -io4pf -i3ops +i3o4pf i3opt i2or i3or. i3orc +ior2e iore4n +io1r2h i3orp i3ors i3ort -io3s +4ios +i3os. +io3sh i2ost ios2u +i2o3sz +io3t i3ot. +iote3l +iot4r i3ots i2ou i2ov -io2x +i3ox +i2oz i3oz. i1ö2k i1ön i1ös. -2ip. +i1ö4st i1pa +ip2an i1pe -ipen3 +i3ped i3per +2ipf2 +ip5fam +i3pfan +ipfe2 iph2 2i1pi +ipi3a ipi3el ipi3en -i3p4l -ip2pf -ip2pl +ip4lu +i2poi +ip2pan +ip3pe +ipp1f +ip4pl i1pr -2ips +ip2sa +ip2sei +ip2sp +ip2sta +ip4stü +ipt2a +ipt2i +ipt2u 2ipu 2i1q -i1r2a -i3rad -1i2rak -ira4s -irat2 +i1r4a +i3ra. +2i3rad +i3ras +irat4 i1rä ir1äh -ir2bl +ir2b3l ir1c -ir2e +ir2ch1o +ir4e i3ree 2irek +ire4na +i3ré irg2 -ir2gl irg4s ir2he ir2i -2irig +2i5rig 2irk +irke4n +ir4kene ir2k3l +irk4s3c +ir3k2u irli4n +ir2m1ag ir2mak -ir2mau +irm1au ir2mä ir2m1ei +irme4n1 +ir2m1o2 +irm4th ir2mum -ir4m3unt +ir4munt 2irn -ir2nar +ir2n3a +ir4nat ir2no -i1ro -1iron +i3ro i1rö irpla2 ir2rei irre4l ir4reli -irr2h +ir2rh +irs2 +ir3sche ir4schl ir4schm +ir4sch3r ir4sch3w -ir3se +ir3se3 ir3sh -irt4s1t +irt2s1t 2iru +ir1u2m iru2s1 +iru3te +i3r2ü i1s i3sac +isa2m3 +i4samp i4s1amt is2ap -is3are +isa2r +i3sat +is3att i2sau +is3auf +isau2g +i2säh i2s1än 2isb i2sca +i2sce +i4schar i3s2che i4schef i4sch3e4h -i4sch3ei -i2sch1l -isch3le +isch3ei +ische4m +i6schemi +i6scher6z +i4schin +i5sching +i2schl i2schm isch3ma -isch3ob -isch3re +i4schna +i4sch3re isch3ru +i6schüb +i4schwa +i6schwir i4schwo isch3wu -i2s3cr +i4schwü +i2scr 2ise -ise3e -ise3ha +ise3a +ise1e +iseh2a ise3hi -ise3inf -i4seint +is4eind +is2el +ise3lad +i6sel6ter ise2n1 -ise4n3a +ise4na is2end +i4senho isen3s +ise4r3ei +is1erg i2serh +iser4he i2s1erm -iser2u -i2s1ess +i2s1es2s +i3s2et i4s3etat +i3s2eu +2isf +4ish +2isi isi2a -i2s1id -i2s1of -iso2n +i2s1i2d +isi4de +isik2 +i2sim +i3sin3g4 +i4ski +i4sku +is3la +3islam +2isma +2ismi +ismu2 +is1of +i3soh +1i2sol +2is4o2n1 isonen4 iso6nend -is1op -3i2sot +isono2 +i2sop +is1ort +3isot +i2s1ou 2isp is1pa i2spar +is2pat is1pe is1pic is2por @@ -6618,1353 +10441,2156 @@ is3sa is4s1ac is4sau is3sc -is4s3che +iss5chen is3senk +isser4f issermas8 is3so -is3spa -is4sper -is3spo -is2s1t +is3sp +iss2po +is2st is3sta is4ste is3sto +iss1tr +is3strä is3stu is2su i2stab ist3ac +is4tal i4stam ist2an +i4s3tang +ist4e i4stea +i4s1tec iste4n -is2ter +istin4f +ist6o ist4ra is3tras3 -ist3re -is1trü +i2strä +i2stre +is5tromm i2stur is1tüm -i2sty +i3suf +isu2m isum3p i2sü +2isy i1ß -iß1ers +ißer4s +iß3ersc i1ta it1ab. -i3tag +it1abs +i3t2ag ital1a ital5l it1alt -it1a2m +it1am +ita3ne it1ang -it3a4re +it3anr +it1app +it1a2re it1art i3tat it1au i3tauc i2tauf -i2t1ax +i2taut 4i1tä +it1änd i2t1äs ität2 i1te -i2tei -i4t1eig -i4t1ein +it1eff +i2t1ei +it2eic +i4teig +i4tein +i4teis 2itel -ite2la -ite4n -itens2 -i4tepo -i2tex +ite4l1a +i4telek +it1emi +i2temp +ite2n +i3ten. +i4tents +i2tepo +i6tereig +i4t3er4fo +iterin6d +iter6klä +it2erö +i8t7ersche +i2t1es2k +i2t1ex +i3text i3thr i1ti +i3tic i2t1id +i3tig 1itii -iti4kan -iti3k2e -i2t1in1 -it2inn +it1in1 i3tis -it3iss +i4tiso +iti3sp +i4tiss i3tiv -i4tl +iti2v5a +it5le itmen2 -i1to +4i1to +i3to. +it1ob i3toc +ito3d i2t1of +ito2p +it2os i1tö -i1tr -i3tra. +4i1tr +i2t3rad +i3tradi it3raf -it3ran it3ras it3rau it3räu it3re +it4ret +i3trie +it3rob it3rom -it4ron -i3tru -it3run +i2t3run +i2t3rut +2its it2sa -it4s1a4g -it2s1e4 -its3er1 -it4set +its1ag +it2s1e +it4se2h +its3e2r1 +it4sh +its1or +it3spen it4stec it4s3tem +it4sten it4s3tes -it2sti -it4stie -it2s1to it6stra6s +2itt it2teb it4temp +it3ter +itt5erfo +itt3hä +it2tob +it2top it2tri +itt3ric +itt6schi +itt4se4h +itt4sei +itt4sor +itt4sti i1tu it1uh -i2t1um +it1ums +it2ung i2tuns +ituran4 it1urg +i3tus itut4 i1tü +4ity1 +ityl2 2itz -it2zä -it4z3er4g +it2zec +itz2er +itz3erg +it6zergr +it4z3erl +it2zö it2z1w 2i3u2 -ium1 +i4u3l +ium3 +iuma2 +ium4se +iun2 +iungs3 +i4up +iu4r ius1t -i1ü +i1ü4 2i1v +i2v1ad i2v1ak -iv1ang +i2v1am +iv1an +i2v1ä i2veb +i2v1ef +iv1ei iv1elt ive4n iv1ene i2v1ent +i2v1ep +ive3re +iv1erh +iver4kl iv1erl +iver3s +i2v1ex +ivil3l +i2v1im +i2v1ind +iv1int +i3vol +ivo3re +i2v1r +i2vun i2v1ur +i2vü 2i1w -iwur2 2i1x i2xa ix2em ixt2 +i1y 4i1z -iz1ap -iz1au +iz1a +iz2ac +i2zag +i2zan +i2zap +i3z2as +i2zau +i2zä +i3ze iz2ei izei3c +izeit3s4 +i2zele ize2n -i2z1ene -iz4er -i2z1ir -izo2b +i4zener +i4zentz +iz1erg +i4z1erl +izid3 +iz1ir +izo2f i2zö +i2zuna i2z1w +i3z2wi í1l -jah4rei +j2a +jab4 +jah4r3ei jahr4s -ja3l2a +ja3l +jal2a ja3ne jani1 -jani3t2 -2jat +jani3t4 +ja5ru +jas2o +jat2 +2j1d4 +jda3 je2a jean2s je2g +jek2t3a jek4ter +jek4tin +jekt3o2 jektor4 -jek2tr +jek2t3r je3na je2p +je3r +jer2e je2t1a -je2t3h +je4t3h +je2tin +je4tor je2t3r jet3t je2t1u2 -ji2a ji2v +2j1m joa3 jo2b1 job3r +jo2da jo2i -joni1 -jo1ra -jord2 +jol2a +jong2 +jo2p3 +jo1r2a +jor3d2 jo2sc -jou4l +jost2 +3jou +jou2l +2j1t +jty1 j2u -ju2bl -jugen2 +ju2b3l +jude2 +jugen6 jugend3 +ju1i ju2k -jung5s +jul2i +jung5s2 ju3ni +ju3r +jur4a jur2o -jute1 +ju3t2e1 2j1v 1ka 3ka. -k1a2a ka3ar +2k1abb kab2bl -ka2ben +2kabd +2k1a2ben +2kabf +2kabg 2kabh -2kabla -2kablä -2k1a2bo -ka3b4r -2kabs +2kabn +2k3a2bo +2k1abs 2k1abt +2kabw +2kabz ka1c -k2ad -2k3ada +kade2r +2k1adm 2k3a2dr +3kadu +2kadv +ka3e ka1f4l ka1fr kaf3t2 -k2ag +kag2 +2k1age +3kah +ka1ho ka1in -ka3ka -kaken4 -ka1k4l -2kakt +kaken2 +ka1kl +2k1akt. 2kala. +kala3b +ka2l1a2d ka2lan -ka3lei -ka3len. +kal3d +ka4l1eh ka4lens kal3eri -kal2ka +3k2alk +kal2k1a +kal4kan kal2k3l -kal2kr -k1all -kal3lö3 -kalo5 -kal2tr +kal3l +kall2i +kallö3 +2k1allt +ka2lop +ka2l1os +kals2 +kal4tex +kal4th ka2lu -k3ama -kamp8ferf -kan2al -ka4n1a4s +k2amt +3kana +kan4al +ka4n1a2s ka2nau -kand4 +2kanb +kan3d2 2kanda +2kandä kan2e -2k1ang +2kanf +2kanim kank4 2kanl -2k1anna -k1ans +2kanom +2k1anor +2k1ans k2ans. -6kantenn -ka3nu3 +kan4tar +6k5antenn +2k1anth +ka3nu +kan2um 2kanw -k2anz. -ka2o -2k1apf +2k1anzu +2kanzü +ka2o1 +3kape +ka3po 3kara -2karb +2karbe +2karc k2ard +kar3d2a +k1area k2arg +ka3r2i kari3es k2ark 2k1arm -karp3 kar2pf k2ars -kar3t -k2arta -2k1arti +k2ar3ta +k1arti +4kartik karu2 k2arw +3k2asc +kas2e +kase1i kasi1 +kas2o ka2sp -kas3s -ka3tan -ka3t4h +kas2t +2k1ast. +ka3sta +ka4ster +3kasu +ka3sz +ka2tan +3kateg +k3atel +ka3t2h ka2t3r kat3se -2katt +2katt4 +kau4fer kau2f1o -4kaufr +kauf6s5ag kauf4sp -kauf6s5te -k1aus +kauf8s7tem +kauf6sti +k2aus. +2k1auss +2kausw kau3t2 2kauto +ka3ve +2kaz 1kä -k1äh +käl3 k1ä2mi -k1än kär2 +2k1ärg kä2s5c käse3 kä3th -2k3b2 +4k3b4 kbe1 kbo4n kby2 2k3c -2k3d2 -kdamp2 +2k3d4 +ke2ben 2k1ec -k1eff -kefi4 +ke2di +2k1eff +kefi2 kege2 ke2gl ke2he. +ke2hen +kehrer4 kehr2s kehrs3o -kehr4st 2k1eic 2k1eig -k1ein -ke1in2d -2keinh -2k1eise +kei2li +2k1ein +kein4du +kein4e +k1eis +2keise +keit2 ke2l1a +ke3lade ke3l2ag +ke4l3am ke2lä -kel3b4 -2k1e2lek -ke2len +kelb4 +keld4 +kel3eis +2ke2lek +ke2l1en ke2l1er -2kelet kel3la -kell4e -kel3li -kel3s2k +kel7l4e +kell2i +ke2l1o2 +ke2lö +kel3sk k4elt +kelt4e +2k1e2mi 2k1emp k2en. -ken3a -ke4nac +ken1a +ken3au ke2nä -kenbu5s4 ken3dr +ke2n1e2b +kenen1 +ke4nene +ke4nens +kener4n +kene4t 4ken4gag -2kenlä +k5en6gel. +ke2nim +ken3in +4kenlad +4kenläd +kenn2a +kenn2e ke2no -ken4sem -kens2k +k2ensa +4ken4sem +ken3s2i +ken3s2k ken5s4te ken3sz k3en4te. -k3en4ten +ken6ten. +4kentf +2kentg ken3th +2kentl 2k1ents 2kentw 2kentz -2keo2 +ke3ny +k2en3z2 +2ke1o2 +2kep ke2pl k2er. -ke1rad +ke1ra +ke2ran +ke2rau +ke2r1ä +ker4ble k2erc +4kerd +ke2r1e2b +ke2rec ke3reig +ker3ein 4kerfah k4erfam +ker2fo k3ergeb -ker6gebn -k3er2hö +2kergu ke6rin6nu kerin6st kerin4t -ker4ken +k3erken k2erko -k2erl -k4erl. -ker4lau +k3erlau k3er4leb k6erlebe -k4erlö -ker4neu +ker2na +ker4nei +4k3er4neu +kern5eur k1ero +k2e1rod +2keros ker4reg k2ers. +2kersa +kert2i +ker6werb kerz2 k1erz. ker4zeu 2k1er2zi -k6es. +k2es. +ke2s3a +k2esc +k1ese ke2sel +kes2sa ke2t1a -ke2t3h +ket2ag +kete4 +ke4t1eb +ke4tel +2k1e2th +ket3ha ket3s -ke1up +ketta4s +kett1h +ke2tu keu6schl +2k1e2va 2k1e2x -2k3f4 -2k1g2 +4k3f4 +2k3g2 +kga4s1 +kge3s2 2k1h4 +k3he kho3m -ki3a4 +k3hu +ki1a +ki2ad +ki2ag +ki3ak +ki3a2r ki1ch -2k1i2de ki3dr +k2ids +2kidy ki2el -kie2l3o +kie4lei +kiel3o +2kiern +kier2s +kie4sa +kie4z ki1f4l ki1f4r ki3k4 -2kil2a -ki3lo -k2imi -k2in. +2ki3l2a +2kilä +2kim +3kin. +ki2nä +4kindex +2k1indi +2k1indu +2k1inf k2ing +kin2ga +king3s 2kinh -k2ini +k2ini3 +kinik2 k2inn ki3n4o kin3s 2k1inse +k1inst 2k1int ki3or kio4s -5kir +3kir +2k1i2so kis2p kis5s kist2 kiv2 +kive4 2kiz -ki3zi 2k3j 2k1k4 +kkab4 kl4 4kl. 4kla. -4kland +2k1lac +klan2 +2kland +klan3du k4lar -4k1last +k1last +k1lauf k3laug +2k1läd +k2lär k2le -4kle. +4k3le. kle2br -k3lee -4kleh -k4leid -4k3leit +k3leg +2kleh +klei2e +k3leit k3lem. +kle2o 2k3ler kle2ra 2k3leu kle3us 2klic +k2lien +k2lif 2klig -k2lim +3k2lim k2lin +k3lin. +3k4lina +k4link k2lip k2lir k2lisc 2klist klit2s -4kliz +2k3liz 2k3loc -klo2i3 +2klok +3k4lop k3lor klos2 -2klos. klo3sse klost6 -k2löt +2klöc +2klöf +k2löst +k4löt k1lu +klu4b k2lud -kluf2 k2lug -k1lüc +k2lum +2klux +2k1lüc 2kly -2k1m +2k1m2 +4kma +kma2la kmas2 +kma3sse k2n2 -3knab +k4nac +2k5nach +2k3nad +2knah +2k3nam +2k3näp k3ne k4nec -k4nei +kne1e 2knes +kne3tu +2knetz +2k5neu +4kney kni4e -kno4bl -2k5nor -k3nu -3knü +2k3niv +kno2b3l +k4nol +2knorm +2knov +2k3num 1ko +ko5ad ko2al +kobal2 2kobj -2k1o2fe -koff4 +kob4s +kof3f2 +koffe3i +kohl2e +kohle3i koh3lu -ko1i2 -kol2a +ko3l2a ko3le -kol2k5 +kol2k3 3kom +komer3 +4komn ko4mu k2on -ko3n2e -kons4 -ko3nu +kone2 +ko2nem +kon3s4 +kont6e +ko2nu +ko3on 2kop. ko1pe +2koper +kopfa2 kop4fen -2kops -2kopz -ko1r2a +kop6f5err +ko3pte +ko3r2a +kor2ba +kor2bl +kor2br 2k1orc +korder4 kor6derg -ko3ri -kor4n1a +ko2rel +2k1org +kor2k1a +kor3m +kor4nac +kor2n3ä +kor4no2 +2korpi k2os +k4os. +ko4sk ko2s1p -ko3ta +3k4ost +ko2ter +ko3ti +kot4r kot1s2 kot4tak -2k1ou +k1ou +ko3un 3kow ko2we -k1o2x +2k1ox 1kö -kö2f +köde2 +k2öf k1öl 2k1p2 2k3q -k2r4 +k2r2 2k3rad +2k3rah k4ral -kra4s3 +kras3 +kra4ss k3rats 2kraum +k4raw k4raz k4räc +2kräd k4rän -2k3rät 2k3räum -2kre. +2k5re. +2k3reak +2k3real +k4reb 2k3rec 2kred. 2k3rede +2kredn +2kredu 2k3ref 2kreg -k3reic +2k3reic kre1i2e4 kreier4 -k3reih +k3reif +2k3reih +2kreim +krei6sei +k3ren +2kresu 2k3rh 2krib 2k3ric -k3ries +2k3ries 2krip -3kris -3k4ron +k3risi +krob4 +k4roch +4k3roh +k4rok +k4ron +k4rop kro4ss +2krot +3kroth +k3rou +2kröh 2kruf -krü1b -2k1s +2k3run +4k1s +ks3a2b +k3sac +ksa2k k4s1amt k2san -ks4ana +ks3a2r +ksa4s k2sau -k2s1äl -ks2än +ksau2f +k2sav +k2säh +k3s2c ksch4 -ks1e2b -k2sent -ks1erl -k2s1ers -k2s1erw -k3shi -k2s1id +k2s1e2b +k2s1ec +k3s2ed +ks1ei +ks2eid +ks2eif +k4seind +kse2le +k2s1eng +k2s1ent +ks1er +ks2ere +k2serf +k2serg +k2serk +k2serl +k2sers +k2serw +k2s1e2v +k2sex +k4s1i2d +ks2im k2s1in -k2s1o2 +k4s1is +k3s2ke +ks3kl +kso2 +ks4on +k2sop +k2s1or +k2sö ks1pa -ks2pat -k3s2pe +k2spal +k3s2pat +k2spä +k3spe +ks2pel +ks2pen +k2sph ks2por -ks2pu -kss2 -kst4 +ks2pul +ks5s2 +kst2 k2stal k4s3tanz kstat4 -k4stea +ks3tat. +k3stäl +ks4tel +ks1tie +k4stier k2s1tis +k2stit k2s1tor -k2strä +k4strop +k2stuc k2stum +k2s1tur +k2stüt k2s1u +k3sul ks2zen 4k1t +kt1abr +kt1abs k2t1ad k3tag kt1akt k3tal kt1am -kt1an -k2t3a2r -kta4re -k2t3au +k2t1an +kt2and +k2t1a2r +kt3a4re +kta3ri +k2t1au +kt3aug ktau2s ktä3s -kte3e -kt1ei -k2temp -k2tent +kt1ein +k2tek +k2t1ela +kte3li +kte4n1 +k2t1ent +k4tentl +kten3z +kte2ra +kte3ran +kt4ere k4t3erfo +kt1erg k2t1erh +k2terö kte3ru +ktes2 k2tex -k2th -kt3ho -k2t1id -kt1im -k2t1ing -kt1ins +k2t1h +k2t1i2d +kti2me +kt3ind +kt1ing +kt1ini +kt3inn +k2tint +kti2s1e +k2tiso +kti2st kti4ter +kto3b k2t1of -k3top -k4torga -kt3orie -kt4ran +kto5ren. +k3t4ran kt3ras -kt4ro +k2t3rau +ktro3me kt3run -kt3s2 +kt3rü +kt1s +kt3s4a +kt3sä +kt3se +kts2el +ktsen1 +kt3si +kts1o +kt2sor +kt3s2z ktt2 +kt1ums k2tuns -kt3z +kt3z2 +ku2al ku1c -ku2h3 +kud4r +3kug +ku2h 2k1uhr -kul2a -ku3l2e +kuh3s +ku3la +ku3l2e2 ku3l2i 2kulp -2k3uml -kum2s +kul2to +kul2tr +k2um. +k2um4e +2kumg +2kuml +kum2sp k2u3n2a +kun3da +kund2e kun4s kunst3 2kunt 2kunw -2k1up. +4k1up. kur2bl ku2rei kuri2e +kuri4er +2k1urk ku2ro +kurs1c kur2sp -kur4st +kur2st +kur4ste +2k1urt4 +kur3tsc +kusa2r ku4schl ku2sp kus3ses +2kust +kus3ta ku2su ku2ß +2kut. +kut2a +kuto3 1kü kü1c +3küne +künf3 +3kür kür2s -2k1v +2k3v 2k1w +k3wa 2k3z2 kze3l 3la. +la3ar +l1ab 3l2ab. -la3ba +lab2a +la2bad +l2abä 2labb lab2br -4l3aben -2labf +2labd +lab2e +4la2ben +4labf 2labg 2labh -2l1a2bl -lab2o -l2abr -lab4ra -lab4ri +3labi +l3a2bit +2la2b3l +2labn +3lab2o +4labo. +la3b4ra +lab4res +la2bri 2labs -l1abt -3labu +la2bus 2labw -la1ce -la2ce. +2labz +la1ceb +l4a3che +lachter8f +lacks2 1lad -lad2i -l1adl +2l1ad2a +2ladd +la3de. +la3d2i +2ladj +2l1adl 2ladm -2l1a4dr -l1adv +l1adop +2l1a2dr +3l2adu 2laf la2fa -laf3t +la2f1ei +la2f1er +laf1r +laf3t4 +la2fu la2ga +lag3d +l2ager +lagerin5 +4lagg la2gio -la2gn -lago2 -la2g1ob -lag5s2e -2la1ho -1lai +lag3l +la4g3n +lago4 +la2gob +lag3str +2la3ho +3lai lai4s1t -la2kes -la2k1i +lake2 +la2kin l2akk la1k4l +la2kro +lak3t2 2l1al -4lalp -l2ami -la3min +la2la +3lala. +3lali +4lalt +l2am. +lami3t +lam2m1a lammen8ge 1lammf +la2mor l2amp -4l1amt +l3ampu +2l1amt lamt4s la4mun +la2na l1anal -la2nau -2lanb +la3nan +la4n4at +la4nau +2la2nä 3l2and -lan2d1a2 -lan4d3au +l4and. +lan2da +lan4dam +land3au +l4ande +lan6derh lan6d5erw lan6d5erz -lan2dr -lan4ds -laner2 +lan6d5inn +l4an2d3r +lan3dri +lan3erd +laner4f 2lanf -lan2gl +lan4gan +lan6g5esc lang3s2 +2lanha l2anhe -2lanl -4lanli -2l3ann -l1anp +3lan2i +4lanl +2l1ann +l1ano +la2nof +2l1anp 2lans2 -4lansä +l1ansi 2lantr +2lantw +2lanw lan2z1w 3lao 2l1apf -l1a2po -lap4pl +la2ph +2l1a2po +lap2pl la2r1an +2larc +lar1e2b la2r1ei +la2rel la4rene -3l2ar3g +larf4 +lar3g lar3ini -l2armi -2l1ar3t +4l1a2rom +l1art +2lart. +lart2h l3arti -la2ru -la2sau +lart4r +3laru +l2as. +la2sa +la4sam +la4sä +lasche4 4lasd -la5se -3lasg +la5seb +la4sei +la4s1e2l 2lash -2lasi +la2sin +la4sis la2so 2la2sp 3lasser -la2sta -last1o +l2ast +la4sta +last3an +la4steu la2str +last3ri +las3tro las3tur la2stü 1la2ß3 -lat2a la3t2e -la4tel -2l3ath +2l3a4tel +la5t2i +2l3atl +2latm +lat2o +la2tö la2t3ra +lat4ri lat2s -2lat2ta -lat4tal -lat4tan +lat3st +2lat4ta +lat4tex lat4t3in lat2t3r +latzer4 1laub. +lauben6s5 +lau2b3r laub4se -lauf1i +laub4st lau4fin +2laufn lau2fo +lau4fri 1laug +lau3gl 3laun -l2aus. +4laun. +la4us +3l2aus. +2l1ausb +lau6scha +2lausd +2l1ausf +2lausg 2lausl 2lausr -2lauss +2l1auss +2lausz 2lauto +lau2tr +la3va +lave4n 1law lawa4 +1l2ax +la4xel +l2ay lä1c -2läf 2l1ähn 1länd -lär2m1a -l1ärz +l1äpf +2läq +lär2ma +l1ärme +2lärz lä2s5c lä4s3s -4lät +2lät 2läub 2läuc 2läue 1läuf +2läug +2läx 1là 4l1b l3bac -lbb2 -l2b1ede -lb3eise -l4beta +l2bant +lb3a2ri +lbau1c +lb1ärm +lbb4 +lb2ei +l4b3eink +l4b3eise +lbe4ral +lberin5 +lbe7s +l4b1e2ta l2b1id l2b1ins -lb2lat +lb4lad +l3b2lat l3blä lb3le -l2bli +l2bled +l2blic l3blo -l3brec -lb3rit +l3b2lö +l3b2lu +l2b1o2ra +lb3rea lb2s lb3sa lb3se -lb4sh lb3si -lb4sk lb3sp -lb4st1e -lb4sto -lb2u -l2b3uf +lbs2t +lbst3ac +lb4ste +lbst3ei +lbst1u +l2b1uf +l3bum +lbu4n lbus3s lbzei2 2l1c -lch2au +l3ca l3che l4chei -l5chen +l4chent lchermas8 l3chi -lch3l -lch3m +lch3le +lch3li +l3chlo lch3n lch3r -lch3s +lch3s2 lch3ü lch1w l3cl l3co 4l1d ld3a2b1 -l3d2ac +ld2ac ld3ack -l2d1a2d -lda4g +l2daf +lda2g +l2d1ah +lda2i l2d1ak -ld1al -l3dam -ld1amm -l2d1a2n -ld3ane -l2d1a4r -ld3ari -l3das -ld1au +l2d1al +l2d3a4n +ld1arm +ld1ass +l2d1au +ld3au4s +l3däm ld1är +ld1äs +ld1ät ldbus2 l3de. -l2deh +lde4ben l2dei -l2dele +ldein7 +l2d1elf +l2d1e2mi +l2d1ems +lde4na +lden5erg +l4dentl l3der. +l4d3er4fa +l6der6geb +ld1erh +l4der4he l3d2erl +l6derlas +l6derlaß l3d2ern l2d1er2p lder4tr -l2d1e2se +lde3sa +lde4sel +l2d1es2s l2dex ldi2c l2d1id -l2d1im -l2dob +ld1i4mi +l2d3ion +ldo2b +ld2on +l2dop ldo2r +l2d1ori ld2os ld2ö2 ld3r +ld4ram l2dran -ld4ros -l3d4ru -ld4rü +l2dre +ld5rie +l3d4ris +ld4ru +l2drüc ld3sa -lds2t +ld3ska ldt4 ld3th +ldt5s +ld3tu +l2d1ul l2d1um -ldy3 -ldys2 1le -3le. -le2a -le3an +le2ad le3ar +le2as 3le3ba -leben4s +leben4s3 le2bl +3lebr +le2b3re 2lec -lech5t4e -3led -4ledd +lech1a +le2chi +lech7t6e +le2dr le2er -lef2a -le2g1as -le2gau +lee4ret +le3f2a +2l1eff +lef4o +le2g1ab +leg1as le2gä le2gl 3leg4r 3leh -leh3re +4lehe. +leh3r2e 4lehs 4leht -lei4bl -lei2br -l2eic +lei4ble l2eid -4l1eig -le2im -l2ein. +lei3ere +lei4fan +lei4fei +leifer6g +2l1eig +lei3gl +3leih +lei4hau +lei3l2 +leim3p +3l2ein. leinbu4 leinbus5 -l2eind +3l2eind lein4du -l2eine +l4eine lei6nerb -4leink +le2inf +le2ini +2leink l1einn -l2eint +l3einsa +2leint l2einu -lei6schw +le2is +leisch5a +lei8schei +lei6scho +lei6sern +l1eisf lei6ss5er +leis3st lei4str lei4ßer l2eit lei2ta -lei8t7er8sc -lekt2a +lei2to +leit3s2 +3leko 2lektr +2lekz 3l2ela -2l1e2lek +le2le +le3lei +2lelek +6leleme +le3len +leler2 +leler4s +le3les +2lelf. +2l1elfe l2eli lel3s +l2em. +le3mal +le2mau +le2m1ei 3lemes -le2m1o2 -4lemp -l1emu -l2en. -le4nad +3lemet +lem1o2 +le2mor +2lemp +le2mu +le4mun +l4en. +len1a +len3ab +le4na2d +le4n3an +le4n3a4t le2nä -4lendet -2lendu +l1endp 4lendun -le4n3end +l4endur +le2n1ed 4lenerg -l1engl -le3ni -l2enk -2l1enni -le2no -len4sem +le4neur +4leneuv +len4gag +len4kau +len4k3lo +len4klu +l1enni +len6sein +4len4sem +len6serk +len3ska len3sz -2lentf -l1ents -2l3entw +2lentg +2l1entk +4lentla +2lentn +4l3en4tro +4l3entw lent4wä 5lentwet -len2zi -le1os +2lentz +2lenzy +leo2f +le1o4s 2lep 3lepa 3lepf +4l1e2pi +4lepoc lep4pi 3lepr l2er. l2e1ra -le2ra4g -le2rap +le2rag +le2r3ap +le2ra4s le2rau -lerb4 -l3erei4g -ler6eign +le2r1ä +le2r1e2b +ler2ec +l3ereig le4r3ei4m +le4r3eis +le2rel +le4reng +le4rerg le4rers +le2re2t +4l3erfas 2l1erfo l2erfr l2erfü -l3ergeb +l1erg +l2erga +l4ergef 3lergeh -l3ergen +6lergen. +l4erger +l4erges 3l4ergew -2l1ergi +2lergi +l2ergl +l2ergr lergro3 +4ler4heb +4lerhol lerin4s lerk2 l2erka +2lerke +l1erkl +4lerklä +l4erkle l2erko -l4erlei -le1ro -le2rob +ler3kr +ler3l +5l6erlebe +3l4erlei +2lermä +3lerna +ler4nal +ler4nar +3l4erne +ler4nei 2l1erö 3l2erra +ler4ric l4ers. -lers2k -3lerw +l1ersa +ler4sto +lert2 +le2rup l4erwa -2lerwo +ler4wer +2ler2wo 2l1erz -l2erza -ler2zi +ler2zä +l3erzeu +ler2zo +l4es. les2am les2e +le3seb +lese1i 2l1esel -le3sh +le5s4h lesi1 -le3sk -les2ko +le3s2k +les4ki +le3so le2spo -les3s +lest6 leste3 +lester6i +3lesu 4lesw 2lesy -le2tat -2le3th +le2tab +2le2tap +2le2tat +l1e2th +le3tha +2lethi +let2i +letsche6 let2to2 +lett1r +lett1s4 le2u -4leud +4leue +3le3u2f +2l1eul +le3unt 3leut -2lexe +l1e2vol +2lex +3lexd +3lexik le2xis -2lexz +3ley +1lé 2l1f l3fah +lf4at lfäs3 l2f1ec lfe1e -l4feis +lf3einh +l2feis +lf2en +l4ferei +lfe4rel +lf1erl +l3fi l3f4lä -lf3lo +lf3led +lflo7sses +lf4lö l3f4lu lf3ram -lf2s -lf4spe -lf4s1ti -lf2tr -lf4u +lf3res +lf4ru +lf4rü +lf2spe +lf2s1ti +lf2su lfun2 lfur1 -l3fü 2l1g -lg1art l3gas lga3t -lg1d4 lgen2a -lge3ra +lgene2 lgeräu3 l2geti +l3g2i lg2lö l3go lgoa3 +lg4p +l3gra lg3re l3gro lgro3s lg2s -lg4s1t -2l3h2 -3lhi. +lg4s3t +4l3h2 +5lhi. 1li -3l4ia -li3ac +l4i1a +lia2b li2ad -li3ak -li3ar -lib4 +li2am. +li2ams +lian2g +li2ast +3lib4 libi3 li1c -3lic. -li3chi +lich4ta +lich4to 4lick +li2cl li3d2a -2l1ido -li4ds -l2ie -liebe4s +l1ido +l2idy +liebe4s3 +lie2br +3liefer +li3efl +lie4n1a2 li3ene +lien3t +li2er +lie4rei +li3ern lie4s3c lie4sta +lif4fes lif2fo +lif3ti 3lig +li4g3ers lig4n -li2gre ligs2 -li3ke -li3ko +li3ker +li3k2o lik2sp +lik4tau lik4ter -li3l2a -li3li +lik2ti +lik2t1o2 +lik2u +li3l +lil2a li3m2a +lima1c +lima3t4 2l1imb +2limm 3limo 2limp -li3n2a -lin3al +lin2a +li3nar +2lindi 2l1indu -li4ned li2nef li2neh li2nep +li5ner li2nes 2l1inf -ling4s3 2l1inh -2l1in1it +lin1it 2l1inj -lin2k1a +lin4kan +lin4kar link2s li2nol -l2ins. l2insa -l2insc +4linsel 2linsp +2linst +2linsu +2linsz 2l1int -li1nu -l1inv +li3n2u +2l1inv 2linz li2o li4om lion5s -li3os. -li2p3a -2li2po +li3o2st +3lipf 3lipt 3lis. li3s2a +li3schm li4schu +lis2h +li3shi +3lisk 2l1isl 2l1i2so +3lison li2sp -liss2 +liss4 2liß -li2tal -li3te -li1t2h +lit4a +l1i2tal +li3t2ä +l2i3t2e +3liter +li1th +li2t3r lit1s2 +lit3se lit3sz +li4tun li2tur +litz4er 3liu liv2e -livi1 +li2vea +li2ves +livi3e +li3vr 2lixi -li2za +li4z3ä lizei3 -4l1j +4l3j 2l1k +l3kale lk1alp l3k2an +l3kap l3kar. -lken3t +l3ke +lk1erd +lke3r2e lk2l lk3lad +l3k4las lk3lic -l2k3lö l3k4lu -l3k2me +lk2men lk4ne lk5ner -lkor2b1 -lk4ra -l2k3ru +lk3nu +lko2f +lk1ofe +lkor2b +lk3roc lk2s1 -lk3sä -lk4stä +lk3sän +lk4set +lk3si +lk4spe +lkt2 lk2ü -2l1l -ll1abb +4l1l lla2be +l2labk l2labt +l3labu +ll3acht lla2de ll1aff -ll1akt -l3l2al -l2l1a2m -ll3ama -lla2n -ll2anw +lla3gl +l2l1am +lla2ma +ll2ami +ll2anb +lla4ner +l4lani +l3lans. +ll4anwa ll1anz +l4l3appl ll1arm lla6tern +l2lath +l4latm +l2l3att l2lau ll3aufg ll3aufk -ll3aug -ll1aus +ll1au2s1 l4lausf l2la2w -l2läd l2l1äm +l3läs l2läu llb4 llch4 ll3d4 l2le2b +ll5ebene l3lec ll1ech +lle3er l2l1ef lle2gu lle2he l2leib +ll1eic ll1eim -ll3eise -ll2em +l4l3eise +lle2la +lle2m +l2l1emi l3len. -lle4n3a +lle4na ll3endl llen3dr -ll3en4du -ll2eng +ll3endu +llen6dun +l4lentf l4lents +l3lep l3ler. lle2ra -l6lereig +l3lere +l6ler6eig ller4fo ller6geb -l6lergen +l8lergene l4lergo -ll3ernt +ll3erho +l4l3ermi +l4l3ernt ll3ertr ll6erwei ll2es +l3les. l2le2se +lle4th l2leuc l3leur. -l2lex -llf4 +ll1exe llg4 -l2lic l2lieb l2lieg -l3lik4 +lli4gan +l3lik lli4la -ll1imp l2l1ind -l2l1ins +l4linf +ll1ins llin6sen -llk4 -ll5m -lln2 +l2lipo +ll3k4 +ll5m2 +ll3n2 ll1ob l2lobe -l2lo2d -l2l1of -llo2gi +l2lo2d4 +l2l1o2f +llo2ge +ll3ol +l2lope ll1opf -l2l1o2r -l3lor. -l3lore +ll1or +l6lorb +llor2g +l2lo2ri llo2te l2l1ou +l3low +ll1ox +llö2g l3löh -ll3sä -ll3sh -ll3s2k +ll2säu +ll2s1es +ll3ska ll2spr ll4stor ll3t +llt2e +llt2i llti2m llt4r llts2 llu2d -llu2f -llu2me +l2lu2me +l3lung l2lu2p ll1ur llust6 +l3lut l2lüc llü2d +l2lü2g +l3ly ll3z2 4l1m -l3ma. l2m3a2b -l2marc +l2m1ad +lm1a2ge +lm1aka +l2m1a2m +l3mana +lm1apf lm1art +lm3att lmä2s lm1ä4st lm1c -lm2ei -lm3eins -lme4na +lmd2 +lm3e4dit +l2m1ef +l2ment l2m1e2p +lmer2 +l2m1erf +l2m1erl l2m1erz +l4messa +l2m1i2d lm1ind lm1ins lm3m -l2möl -lm3p +l2mof +lm1orc +lm3p2 lmpf4 +lm3s2k +lms2t +lm3str lm3s2z -lm3t +lm3t4 +l2mum +l4munt 4ln -lna4r +ln2ab +lna2r ln3are l3n2e -l3ni -l1nu +lnes2 +l2n1in +lnus2 l1nü +l1ny 1lo lo4ak -3l2ob. -lo2ber +3lob. +l2oba +3lobb +lobe4s 2lobj -2l1o2bl +l1o2bl l2obr lob4ri +lo4chel 3lodr -l1o2fe -lo1fl -lof4r -lo2gau +lo3dri +l1ofe +lo2fen +lo4gh +lo2gl +lo2gor +lo2gre +lo3ha lo3h2e -2l1ohr +4l1ohr loi4r 3lok +4l3okk lo2k3r -lol2a -l1o2ly +5loks +l4ole +2l3o2ly +lomä3 lo2min -l4on +lo2ner +lo4nin lo2n1o lo2o +l1ope 2lopf +lop2p1a lop2pr 2lopt -lo1ra -lo2rak +lor3am +lor2an lo4rä 5lorb -2lorc -l1ord -lo3ren -2l1or3g2 -3los. +2l1orc +2l1ord +lo3r2en +2l1org2 +lori4di +2lort4 +l2os. lo4sa 3lose lo4ske lo2spe -loss2e +lo2s1pr +los3ta +lo4stel lo4steu lo2s3to lo2s3t4r lo2ßu -lo2ta +lo2t1a lo3tha loti4o +lots2 2l1ov lo2ve 2lox @@ -7972,257 +12598,407 @@ lo2ve lö2b3 2löck 2löd -l2ö2f +lö2f 2l3öfe 4lög -l1öhr -2l1ö4l +2l1öhr +2lök +2l1öl +2löp +3lösc 4löß +4löz 2l1p -l3pa -lpe2n3 +lp2ar +lpar2k1 +l4p1är lp2f -l2p1ho -lp3t4 +lph4 +l3phä +l2phir +lp1ho +l3phr +lpt4 l3pu 2l1q 2l3r2 lra4ss -lrat4s +lrau2s +lrebs2 +lro2h lrö4 lrös3 -lrut4 -lrü1b 4l1s +ls3a2b l3sac l2sa2d -l3s2al +ls2al l4s1amb -l4samt -l2sanf -l2sang -l2sann -l2sanz +l4samp +l2san +ls3ane l3sare -l2sau2 -ls2äm -lsä4s +ls3a2ri +l3sark +lsau2 +lsau4m +lsau4r +l3s2äm +lsä6s +ls2äug +ls1äus +ls2c l4schin l4schmü -l3se. l2s1e2b -l2s1ec -l2s1em -ls1ere -ls1erg -ls1erl -l2s1ers -l2s1erw -l3ses -l3s2ex -l4s3ha +ls2ele +ls1eli +l2sent +ls1er +l2serf +l2serg +l2serh +l2serk +l2serl +l2sers +l2serw +lse2t +ls1eta +ls3ha l2s1id -l2s1imp -ls2log -ls3ohne +l2simp +ls2kal +l3s4kele +l4skla +l4sko +ls2ky +lso4b +l2sop l4s3ort. -ls2ö +l3sos +l3s2öl l2spac ls2pe -l3s2pi +l2s3ph +l2s1pir ls2po +l3spri ls2pu l3spul -ls3pun -ls3s2 +l2spun +l4s3s2 lst2a lstab6 ls2taf +l2stas +l4s3tat. +l4state +l3stau l4s3täti +l4st3erk +l4s3terr l2s1tis l2stit +l4stoch ls1tor l4stor. l4store l4stors -ls2tr +l2s1trü +l3suf ls1um -l2sun -6l1t +l2s1un +ls2und +ls3unk +4l1t +l3ta. l2tab +lt1abs ltag4 -lt1ak lt1am l3tami -lt3and -lt1ang -l4tarm +ltampe4 +l3t2an. +ltan3d +l2t1ap +lt1ara +ltar8beitn +l3tark lt1art -l2t3ato -l2t1au +ltar6tik +l3tartu +lt1au +l4tauf +lt3aut +lt1äh +ltbau1 lt1eh +lt1eig lt1ein -l2t1eis -lte4lem +lte3mi l3t2en lten6gel -lter3a -lter2f +lten4sp +l4tentl +lt3ents +lte4ral +lter4fa l3t2erg +l4terhe lter6ken -lter6leb +lter4ku lter4nä +lte2ro lt2erö -lte3se +lter4se l2t1esk -lte3str +l3t2est +lte3sta +lt2et l3tet. -lte2th -l2t1eu -l2th +l2t1h +lt3hag l3thas -lt3ho -l3thu +l4t3hei +lthol2 +l3t2hu +lt1ide ltimo4 -l2tob -l2t1of +l3tin. +l3tine +l2tiso +l3t2i3t +l2t1ob +l2t1o2f +l2tord +l2torg l2t1o2ri lto2w lt1öl l3tön lt1ös lt1öt -lt4rak ltra3l lt3räu -l2t3re -lt4rie -lt3roc -lt3ros +lt3rec +lt3rei +lt3ris +lt1roc +lt3rol l2t3rö +l2t3rus l4ts -lt1spa -lt4stab -lt5ste -ltt2 +lt2se2l +lt4s3ort +lts1pe +lt1s2ph +lt4stec +lt2sti +lt3t lt1uh l2t1um -ltu4ran +lt2um. +lturan4 +lturen4 ltu2ri lu1an -4lu4b3 +4lu2b3 luba2 -lubs2 +lub5s2 lu2dr +lu2ec lu2es -1luf +lu2et +1lu2f2 2l1ufe 2luff -luf2t1a -luf2t1e -luf2tr +lu3fo +luft1a +luft3e +luft3r lu2g1a lu2g1e2b -lug3erp +lu2gei +lugen1 lu2gi -lu4g3l +lug3l lu2go lu2g3r +lug3se lu2gu 2l1uh lu1id. -lume2 +lu4ig +lu1is. +lul2ö +lume4 2lumf -2l1umj +2lumg +l1umh 2lumk 2luml +l2ump 1lumpe +lum2ph +2lumr 2l1ums -l1umw +lu3mu +2l1umw +2lumz 1lu2n 2l1una +lund4 2l1unf -4l1uni +2l1uni +2lunr +2l1uns 2lunt 2lunw -4lu2o +4luo lu2pf -2lur +l2ura +lu2r1an +lu2rat +lu2rei +2lurg +l2uri +lu2ris l1urn +lu2ro +2lurs l1urt +lu4ru +lu3sak +lu2san 2luse lu2sp lus4s3a lus2s1c +lus4sel lus3sen +luss3er6 lus2s1o lus2s1p lus4s1t -1lus2t -lu2st1a -lu4stä +1lust +lu2sta +lu2stä +lu6sterl +lu2st1o2 lu3str lust3re lu2s1u 4lu2ß1 -lu2t1a -lu4teg +lu2t1a4 +lut3au +lu2tä +lu2t1e4g +lu2tel luter2 -lu4t3erg -lut1o2f +lut3erg +luter4s +lu6t5ersa +lu2thy +2luto +lu2tob +lu2t1o2f lu2top +lu2t1or lu2t3r lut5schl -3lux 2lüb +3lübd +lück4e2 +lücker3 2lüd +lüf3te +lü2hel lüh1l -2l1v -4l3w +2l1v2 +lva3 +l3vl +l3vo +lv3r +4l3w4 +lweis4s 2lx 1ly -ly1ar +ly1a2 ly3c +ly3es +ly1l 2lymp 3lyn ly3no ly1o lys2 -ly3te +ly3t ly1u 2l1z -l2z3ac -l3z2an +lza2 +l2z1ac +l2z1ag +l2zan l2z1ap -lz1ar -l2z1är -l3zen -lz2erk -lz1ind +l2zat +lz1aus +l2zäp +l2zär +lze2l +l2zele +l4z3enth +l2z1ep +l2z1er2h +l2zerz +l2z1id +lzi4m +lz1imi lz3l lzo2f l2zö lz3t2 l2z1u4fe lzug4s +lzvol2 lz1w lz2wec +l2zwu 1ma +3ma. maa2 m1ab +m3a2bar +m2abä +2mabb m2abe +2m3abf +2mabg +2mabh 2mabk -3m2ab4r +m2abli +2mabm +ma2br +m2a3b4ra 2mabs +2mabt +2mabz ma3chan +mach2e +mach8terh +mach8t7ers mach4tr ma2ci -ma3da -m2ade -2madm -ma2d4r +mack2s +2m1act +mada2m +m2adä +ma2del +ma3dj +2m1adm +2m1a2d4r ma4d2s -ma1f +ma1f4 +mag2a ma2ge. ma2geb ma2gef @@ -8236,1463 +13012,2317 @@ ma2gew 2m1agg magi5er. magi5ers +ma3gl 2magm ma3g4n 2m1ago -mai4se +ma3ha +mahl2s +ma1ho +mai4s3e +ma2ke. 2m1akt +mal2ag mal1ak ma4lakt ma2lan -ma4l3at ma2lau +ma2lär +2mal2de +m2aldi ma3le +ma4leb mal2er +ma4lex mali1 -mal3l -mallö3 +mali3e +mal3lo +mal3lö3 2mallt -malu4 +ma2lon +ma2lop +m2alp +mal3t +malu2 ma2l3ut +3malv +ma2mid mam3m -2m1anal +2m1a2nal +ma2nar +2m1a4n4at ma2nau +2m1anä 2manb -man4ce. -man3d2 -man3ers +man2ce +3man3d4 ma2net m2anf +mang2 +2man3ga +m4angel 2m1angr m2anh +3manip 2manl -m4ann +m2anle +3mann +2manod man3s -2mansa +2m1ansa 2mansä -2mansc man4sh -2mantw -manu3 +man2t1h +2mantr +ma4n1ut +2manw 2manz +m1anza ma2or -2m1apf -m2app +ma2phr +ma2po +ma1q +m2ara +4marag +mar2an 2m3arb mar3g2 -mar2i -4ma3r2o +3ma1rh +ma3r2i +m2ark +mar2kr +4mar2o maro3d 4marr +mar6schl mar6schm mar6schr +mar2sp +mar2su +2m1arti ma3r2u -m3arz -3mas. -ma1s2pa -2m1aspe +m1arz +m2as +ma3s4a +mas2e +3ma1s2p +masse4n ma3sses mas6ses. mas6sest -ma6sset +ma5sset +mass1t ma3s2su 3mas2t +ma2sti +ma4sz ma2ta2b ma2tan -mat4c -ma2tel +ma2tä +m3a2tel ma4t3erd +ma4t3erz +m4atme +2matmo +ma2to +ma4tort mat3se mat1sp +matta3g +matt4r mat3url 2m1au2f 3maul ma3un -2mausg +mau3r +2maus +mau2ta m4ay ma1yo 1mä +3mäc +mä3he 2m1ähn -mä1i2 +mäh1r +3män 4m1änd -3männ 2mäo -m1ärg +2m1äp +mär1 +mär2kl +mär2z1 mä1t4r mäu2s1c 2m1b2 mbe2e -mb6l -m3b4r +mber2e +mbe3ri +mbert4 +mbi3er. +mb4l +mble1i +mb4r +mbu3sc 2mc m3ch -2m1d -md1a -m2d1ä +4m1d +m2dan +m2d1a2s +md1är +mde2a m2dei -mds2e +mde2m +m2d1emi +m2d1ent +mder2 +m2d1erl +md2ö +md3ras +md3s2e +mdt4 m2d1um 1me +me3an +me3at +meau2 meb4 me2ben -m2e1c -medi3 -medie4 -medien3 -2medy -me1ef -mee2n1 +3mebr +me1c +medi3e4 +me1e2m +mee2n mee4r3ei +2m1eff mega3 +me4gel 3meh +meh6l3er +mehrer4 2m1eif 2m1eig -mei3l2 +m2ei3l2 mein4da -m2eis2 -me1i2so +meiner6k +mei6nerl +3m2einu +m2eist me3lam -me2lau -3meld +me3l4ant +me2l1au +melb2 +mel3d2 +melde3i me2lek +2melem me2ler melet2 2melf. +3melk +mel4k3ei +mell2i +3melo +me2lob mel2se -mel2sp -mel3t4 +melt4 6mel6tern -2m1e2mi +2m1e2mis 2m1emp +2m1e2mu m2en. -mena2b -me3nal +men3ab +me3nage +me4n3an men3ar +me4nas men3au -2mendl +2m1endl +menen1 +4men4gag men3ge -m4ens -men4sk +me2nim +men3k4 +men2on +men4se. +men4sem +6mensemb +men4sen +men4ser +men4ses +mensi4d men2so -men3ta +menst4 +m4enta +men4t3ak +m4entei +ment5eig +men6t5ers 2mentn ment4sp -4m3entwi me1o 2meou 2meö +2mepa +2m1e2pi 3m2er. me1ra -mera1f -me2r3ap +mera3l +mer2as +me2r1e2b me4rens -mer2er -4m3ergän +mer4err +mer4erw +4m3er4gän merin4d merin4t +4mer4klä m4ersh -merz4en +mer5sm +mer6stel +mert4r +merz6eng 3mes me2sal me2sä mes2e 4meser -2me3sh -4m1essa +mes2po +2mes2sa +mess3an mes6ser6g -mes2s1o -mes2s1p -meste2 +mes4s1o +mes2sp +mes2s1t +mes1ta me2str -4mesu -3me2ß1 -m2et -me3t2a +me3su +me3sze +3me2ß3 +me3ta me3th -me3tr +meto1 +me2tö +me4trig +met6t5en6d meu1 2m1ex +me2xe 1mé 2m1f4 -mfi4l -2m1g2 -2m1h4 +mfi2le +4m1g2 +mgang4 +mglim2 +4m1h2 1mi -mi2ad -mi3ak +mi1a +mia2b +mi2am +2m1iat +mi1ä mibi1 +mic1e mi1ch +mi2ci mi3da +mi2di. +mi3dr +2midy mie3dr -mi2e1i -mie3l -mi2er +mi3ele +mi4e3no mierer4 -mi2et -mie4ti -3mig -mi2kar -mi2ki +mie2ti +mie4to +mie2tr +mi1f4 +3mige +mi3h +mik1an +mi3ke +mi4kel +mi4kens +mi3k4l mi2ku -mi3l2a -3milb -3milc +3mil +mi3la milch1 mil4che -2m1imp -min2en +mi3l2i +mil3le +mi3l2u +4milz +m2im2a +2m1imm +2mimp +min2ac +mi3nak +min5anze +m2inde +2m1indu +mi2nef +miner1 +mi4n3e4ri min2eu +2minfo min2ga +mings2 +2minh mi3ni -min2o -mi1nu -3minz -mi2o +mini3k4 +mi3nod +mi2nof +2m1inse +m1inst +mi3nu mioni1 +mi1p 3mir. -mi3ra 3miri 3mirs 3mirw +3mirz +3mis. mi2sa mi4scha -mi4schn +mi4schr mi4sch3w mise1 +2m1i2so +mis2pa +mi2spe +mis5sar mis4ser -mis3si mis4st mi2sta +mi3str +3misu mi2ß1 -3mit1 -mi2ta -mi2th +3mit +mi2t1a +mi2t1h +mi2to mi2tr +mi3tra mit3s2 mit5sa -mi3tsu mit3ta -mi2tu +mit3t2e +mitte3s +mi2t1u 4mitz +mi3v2 2m1j -2m1k4 -m3ka -mk5re. -2m1l2 +4m1k4 +m3kn +4m1l2 ml3c +m3le +ml3f +ml3k +m3lo +ml3p ml3s -2m1m -m2mab +4m1m +mma3a +mm3achs m2m1ak m2m1al -mm1ang -m2m1ans +m2mans mm1anz +m2m1ap +mm2app mm1art +mmas4p mma2ß -m2m1au -mmä4 +mm1aus +m2mä4 +mm1äu mmd2 -m2me2c +m2m1e2b +mme2c +m2m1ef m4meh m2mei mm1ein mm3eise +mme2l1a2 mme4lin -mme4na +mm2ene +mmen6te. +mmen6ten +m4mentl +m4ments m4mentw m2me2nü -mme2ra +mme2r3a mme4rec -mme2s3a +mmer6geb +mme2s1 +mmes3a +mme3sc +mme4sz m2me4te +m2m1eu +mmga4s +mmi3el +mmi3m mm1inb -mm1inf mm1inh -mm1ins +m2m1ins mm1int +mm2is mmi3sc m4mita -mmo2du +mmi5tw m2mo2l m2mor -m2m1ö mm3p2 mmpf4 mms2 +mm3sa +mm3si mm3te m2mum +mm2un +mmu3r m2mus +mmül2 2m3n2 m4nesi 1mo -moa3 +2m1o2be +3mobi 2mobj 3m2od -mode3s +mo3de mo2dr -4mog. -mo2gal -3moh -mo2i3 +m1of +mo2fe +3mog +2mog. +mo2g1al +3m2oh +moh2a +moi3r mo2k1l 2mol. +mol3d 3mom mom2e 3m2on +mo2nan mo2nä -mo3ne -mo4n1er -mon3s -3mo2o -2m1ope +mon4dac +mon4del +mon2do +mo2ner +mon3s2 +mont2a +mon3th +mo1ny +3m2o2o +2m1o1pe +mo2per +2m1opf 2mopt mo1ra -mo2rar -2m1orc -mor4d3a +mor2an +mor2d3a mor2dr -mo2rer +mo2rei +mor3g +mor3t2 3mos -mo3se +mo4ska moster4 -3mot -m1o2x +mo2sto +mo3t2h +mot4r +mous2 +2m1ox mo1y 1mö +möbe2 mö2c +2mö2f 4mök -m1öl +2m1öl 4m1p mpa3ne +mpe2la +mpe4lin +mpe2n +m2p1ene m2pf -mp4f3erg +mpf1ef +mp4f3erf +mpf3erg +mp6fer6ge mpf3erp -mpf3err -mp4f3erz +mp6ferpr +mp4f3err +mp4f3er4z mp2f3l mpf1or +mp2fr +mp1haf mp1hos -mpi3as. +mpin2 +m3plä +mp3lei m4p3lem. m2p3len m2p3les -mp4lif m3pon +mpor6ter mpot2 -mp3ta +mps2 +mp3sh m3pu 2m1q -2m3r2 -2m1s +2m3r4 +4m1s m2san -ms3and ms1as -m3sä +m3sat +msau3e +m2s1än msch2 -m4s1ef +m3se. +m2s1e2d +m2s1ef +m2sein +m2se2le +mse2n +m2s1ene +m2sent ms1erf -ms1erw -ms1ini +ms2erh +mse2t +ms1eti +m2s1eu +m2sex +m2s1o2d mso2r +ms1orc ms1ori m2spä m2sped +m4spl ms2por m2spot m2spro ms2pu -ms3s2 +m4s3s4 m4stag m2stal +m2stit m2sü -2m1t +m4sw +m4szi +4m1t mt1ab mt1ak -m3tam +mta2m mt1ar -mt3are +mt3aug +m2t1e2d +m3tei. mt1ein +mt1eis mt1elt +mt1emi +m4tenga +m4t3engl +m4tentf +m4tentg +m4t3en4tr +m4tents +mter2 +m2t1erb +m4t3erei m2t1erf m2t1erg +mt1erh +m2t3e2r4i +m2t1erk m2t1erl +mter4n m2t1ers m2t1ert -m2t1eta +m2teta m2t1eu -m2th +m2t1ev +m2t1h mt3ho -m2t1im -m2t1ins -m2tint +m2t1i2d +m2tim +m2t1in +m2t1i2r mti2s mtmen2 -m2töl +mt1ob +mt1op +m2t1öl mt1ös mtra4s3 +m2t3ro m2trö m4ts mt2sa +mts3chi +mt3sco mt2s1e +mt3send mt3s2ka -mts1p -mt1spa -mtt2 +mt3s4kel +mts3tät +mtt4 mt1um -mt1urt +mtu3re mt3z 1mu mu1a -2m3uh +2m1uh mu3la -2muls +3muld +3mult +3mumi +m1ums +mum2s1p 3mun -mun2d1a -4m3unf +mundan4 +mun6derf +mu2ner2 +4m1unf 4m3ungeb mu3ni -m4unk -m2unr -munt2 +mu4nin +4mu4niv +4munw 4munz -mu3ra mu4r1u2f 3mus. mu4s1a +3musc mu2s1o mu2sp mu3s4se. mu3s4ses +mus4ste +must4e mu2s1to mu2str mu2su muße3 -muts3t -mut4str +mut1au +mut2st 1mü 2müb 3müh mü2her -mül2 -mül3lu +mühl1a +mül4len 3mün -mü3s4si +mü3s2si 3müt 2m1v mvoll1 2m1w2 mwa2 mwa4r +mweg2 mwel4t3 mwu1 -1my -2m1z +3my +my1al +2m1z2 +mzel4li +mzu1 mzug4 1na 3na. 2n1ab +3naba na2bä -na3ber -4nabg -4nabh -na2bl -n2abo +n3abh +3nabi +n3abk +na2b3l +na2bor na2br -4n3abs -4nabt +nab4rü +4n3abs2 +na2bus 3na2c +n4ac. nach1 -na3chen -nach3s -nach8ters +nachen4 +na5chen. +n3achse +nach3sp +nach8t7ersc nacht8raum -4nadd -n2ade -4n1a2dr -n1af -na1f4r -3n2ag +n1ada +na3dab +3nade +na3de. +nadel1 +na3den +na2der +4n1adl +4n3adm +n1a2dr +3na3e +2n1af +na1fra +nag2a +na3ge. na2gem +4n1agg +n1a2gi +na3gin +na3g4r 3n2ah na2h1a n4ahm -n3ahn +4n3ahn +4n3aho2 3nai nai2e -n3aig -n3air +n1aig +4n3air +nai4re +n2ais 2n1ak -na2ka +3nakä 3nako +na2kro +4nakt n2al. na2l1a2 -na4lal +nal3am +na4lar na2lä -3n2ald -n4ale -na4lent -na2let +2n1albk +n2ald +nal3da +nal3ei +na4l3ent +na6lerei +na4ler4g +na4lerm +na4l3erw +nales2 +nal1et +nal1ex +nalg2 +na2lid nal3la -nalmo2 na2lop nal2ph +nal3s n2als. -nal3t4 +nal3t2 +n2alty na2lu 2naly +n2am. +na2mat 3name na3me. -n2amen -namen4s3 +4na2mei +n4a3men 4n1a2mer +na2mid +na2min na3m4n -3namo +3n2amo +n1amp nam2sp 2n1amt namt4s -2n1an. -4n1a2na -4nanb -n1and2 -4n1ang -2nanh +na4my +n1an +4na2n4a +na4nat +n3a2nä +4n3anb +n3and2 +nan1eu +4n3anf +4n3ang +4nanh 2nani -4nank -2nanl -3nann -na3no -n1anp +4n3ank +4n3anl +3n2ann +4n3anna +4nano +nan2o3b +4n3anp 2nanr -4n1ans +4n3ans 2nantr 2nanw -nap2si +n2anz. +nanzen4 +nan6zene +nan6zeng +nanzer4 +na3ot +na2per +n1apfe +4napfel +n3a2pr +n1aq n1ar 5nar. na2r1a 2narc n2ard -4narg +n2are +n4are. 3nari n2ark n2arle 2narm -4nart -n3arti +n2aro +na2rom +n2arr +n2ars +2nart +n2arta +n2arth na3r2u 3nas -n2as. +n4as. na4schw -4nasp -4n1a2sy +4n1a2sp +nas2s1c +4n1assi +na2str +4na2sy nasyl2 3naß 3nat -n4ata -n3a3t4h -na4the -4n1atm -nats1 +n4at. +nat3au +nat1ei +na3ten +na2t2h +4natm +nat2o +4natom +5nator +nat1r nat4sa -nat4sc -4natt +nats1e +na3tu n1au -4nauf nauf4fr -n3aug +nau2fr 5naui 3n2aul 4nausb +4nausd +4nausf 4nausg +4nausl n2auso -4nauss +4nausr +4n3auss 4nausw +4nausz +nau3te +3nav +nave4 navi5er. navi5ers 1nä -3n2äc +2näb +3n4äc 3näe +2n1äf +3näg +nä2hi +3nähm 2n1ähn -3näi +nä2hu 2n1ä2m 2n1än -n1ärz -3näs +2näp +2näq nä2sc n2ä6s3s -3näß 2näu 3nä1um 2n3b4 nbe2in -nbe3n -nbe3r2e +nber2e nbu3s nby2 2n1c -n3ce2n3 +n2c3ab +n3can +n3ce4n +n3ces. +n3chl nch3m +ncor2 +n3cr +n3cu 2n1d +nda1f nd2ag +n3dai n2d1ak -n2danl -nd1ann -n2d1anz -ndat2 -n2d1au +n2dana +n2dani +n2danz +nd1arr +n3dat +nd3att +nd1au +n2daut +n2dax +nd1äng nd1c nde4al. +n2d1ede +n3dee n2dei -nde4län +nd3elfe +ndel3l +ndel4sa +ndels5en +nde4mot +nden3sk n4dentl -n4d3ents -nder6laß +n4dents +nde3o2 +n5der. +n5deren +nd2erh +n5deri nder6läs nde4rob -nde2s -ndes1e -nde4spe +n4de4ros +n6der6sat +n3d2es +nde2se +ndes3s ndi2a3 -n2dob -ndo2be -nd1op +nd1imm +n2dof +ndo4n3a +n2dopt nd1or -ndo2ri +n2do2ri +n2d3ott n2dö +nd2ös +nd4ram n2d3rat +nd3rau n2d3re -n2drob -nd3rol -n2drö +n2drif +n2d3roc +n2drod +n2d3rö +n2drui n2d3run -nd2sor +nd4sene nd2spr nd3th ndt4r n2duns -n2dü +ndwa5re ndy3 +ndys2p 1ne 3ne. ne2ap -nea4s +3nea4s ne3at +ne3au +4n3ebene ne2bl 2n1ebn +neb4r 2nec 3neca -3ned -2nee3 -ne2e2i4 +3nece +ne2ch +neck2a +ne2dit +2nee +neei2 ne3ein +ne3eis +neema4 +neen2 +nee1r +neer2e n1ef -neg4 +n2ef. +n2e3f2a +2nefr +2n1egg +neg4l +n1e2go +neg4r +n1ehe 2ne2he. +2nehem 2nehen2 +nehe2r 3nehm -4n1ehr +4n3ehr 2n1ei +3neia +4neic +nei4dei +nei4dr 4neier -4neif 3neigt -4n3eing -4n3eink +3neigu +nei4la +4neing +4neinh +4neink +4neinl +4neinz +4neip +neiss4 ne2ke -nek3t4 -ne2l -3nela +2n1eks +nek3t2 +2nekz +ne2la nel3b -2n1ele +n1e2le 4nelek 4nelem ne3len -ne3li +ne3lex +nel2i +ne3lid +ne2lit 3nelk n2ell nel4la4 +nel4lei +neller6f nel4lif -3ne3lo -3ne3lu -n2em. -2n1emb -nem4e -n1e2mi -2n3emp +3nel2o +3nelu +3n2em. +ne3mas +4n1emb +4n3emp 2n1ems +4nemu 3nen -n2en. -n2en3a2 +n4en. +n2en3a +nen4am +ne4nan ne2nä n2enb n2enc +nen4dar 4n1endb 4n1endd 4n1endf n1endg 4n1endh 4n1endk +n1endl 4n1endp 4n1endt 4n1endw -ne2n1e2b +nene2b nen3ei +nene4m nenen1 ne4nene +nen3erb +ne2n3eu n2enf -4nengb -nen4ge. +4n1engb nen4gen -4nengs -4nengt +4n1engs +4n1engt +n1engu +nen4gun n2enh -ne2ni +ne4n3i n2enj -nen3k -ne2no -n2ens -nens4e +n2enk2 +n2enm +nen4nar +ne2no4 +nen3s4e nen3sk +nen3s2p 5n2en3t2a -n1entb +4n1entb +4nentd +4nentf +5n2enti 4n1entl 4nentn +nen3to 5nentr -n1ents +4n1ents 4n3entw 4nentz -ne2n3u +ne4n3u n2env n2enw -n2enz -ne2ob -ne1os +nenz4er +ne2o3b +ne2oh +ne2or +ne2pen 2nepf -2n1epo +2ne2pi +2nepo ne2pos -n2er. +nept4 +n4er. ne1ra ne2rab +ne2rac ne2r3af +ne2rag ne3r4al -ne2r3am +ne2ram ne2ran -ne2rap +ne2r3ap +n2erat +ne6ratio +ne3rato ne2rau -nerb2 -4nerbe. -4nerben -n1erbi -nere2 -ne2reb +n2erb2a +4n3erbe. +4n3erben +2nerdb +ner4dig +ne2r1e2b +ne2rec n1erf -4n5erfo -nerfor4 +4nerfas +3nerfr 2nerfü +2ner3g4 3nergr n1erh 4n3erhö 3neri n2erj n1erk +5nerka +n2erkö n2erli 2n1erlö nerma3 nermas4 -ner4mit -n2ern. -n1ernä -ner4neu -4n1ernt +n1ermi +2n1ernä +4n3erneu +2n1ernt +n1eros +n1eröf ne1rös -n2erp -3n2ers. -n3ersa -n2ert. +n2ers. +2n1ersa +3nerse +ner4sk +4n3ersts +nert4 +3nert. ne2rup -n2erv +3n2erv +4nerwar 2n1erz -n2es -n4es. -nes2c +n2es. +ne2sal ne2sei -ne2sev -nesi1 +ne2s1ev +2ne3sh ne3ska -nes1o -ne2sor +ne2s1of +ne2s1or ne2s1pa -4n3essi -ne2tad -ne2t1ak +4n1es2si +2n1e2st3r +4nesyn +3n2eß +ne2tab +2ne2tag +net1ak ne2t1an -ne2tap -n1etat +2ne2tap +2ne2tat ne2tau +ne4te2l ne2th net3ha -nett4sc -n1e2tu -net2zi +ne3ti +ne4tin +ne4tob +net1s2 +n2ett +net3ta +net3te +net3tr +2n1e2tu +net4zer +net2z1i ne2u neu1c +neu4ere neuer4f neuer4k +neuer4r neuer4s neuer4w -neu3g +neu3g4 2n1eup neur2 +neu2ra +neu3t +3n2evi n2ew +ne3wa 2n1ex +ne2xi +5ney 3nez -1né +3né 2n1f -nf1ak +n3f2al nfalt2 -n3far +n3f2ang +nf4ar +n3f2ä +nfäs3 +nfe2i +n3f2en +n3f2er +nf2es +n4fex +nff4 n3fi nfi4le. -nf4l -nf5lin -nflös4 +nf4le nf2o nf4r +nf3s2 nf2tan -nft2o +nf3tei nf2t3r -nft2s +nft2st nft4ste n2f1u 4n1g -ng2abs +n3gabe +ng1abt n2g1ac -ng1ad +n2g1ad n2g1ak -n2g1a2m -n2g1and -ng2anf -ng1anz +ng1a2me +ng3anda +ngang6st +n2ganh +n4ganl +ng1ant +ng1are +n3g2ars +n2g1a2v n2g1äl ng3d4 -n3gef +n2g1eif n2g1ein -ng2en -ngen2a -ngens2 -n3ger +ngelb4 +nge3l4ei +n3g4en +n5gene +nge5nerw +ngenmas6 +ngen3s2 nge4ram -n4g3erse -ng6es -nges2t -nge4zän -ng3g4 +n2g1erg +nger4zä +n3g4es +nge3s2a ng3hu -n2g1i2d +n2g1id +ng2lad +ng2läs n2glic -n2glo -n3g2loc -ng3m +ng4lok +n3glot +ngma7sse. n2gn ng3ne -ng1or -n3gra -ng3rat +n4g3ni +ng4nom +ng2nu +ng2ob +n2g1op +n2g1or +ngo2ri +n2gö +n2g3rai +ng4ran +n2g3rat ng3roc ngro3s -ng2s -ngsa4g -ngs1ah -ngs3au +ng3rost +ng2s1 +ngs3an +ng4s3au +ng5schr ng4s3e4h ngs3pa +ng4spar +ng4stec ng3ts n2gum -2n1h2 -n3han -n3har -n3hau -n3hä -n3he +ngzei4t +4n3h2 nhe2r -n3hu 1ni -3nia -nib4l -nibu2 -nicht5er -nich8ters +3n2ia +ni3alo +ni2ar +nibb4 +nic4 +ni1ce n1id 3n2id. +ni3da ni2de +2nidea ni3dr -n4ie +2n3idy +n2ie nie3b ni1el nie3l2a nie4n ni3ene -ni1ero -nig2a -2n3i2gel +ni3eni +nie4rei +ni4erna +nie4sa +nie5sse +ni2eu +ni1fl +niga2 +ni2g1ab +ni2g1am +ni2g1an +4n3i2gel +n4igen 2niget -nig3r -ni2gre -nig2sp -3nik -ni2kal +ni4gl +nig3li +ni2gn +nig4sp +nihi3 ni2kar -ni3ker -ni4k3ing -ni3kl -nikma3 -ni2kr +3nike +ni2kel +ni3kerh +ni2ki +nik3ing +ni2kor +ni2k3r +nik3t4 3n2il -nim2o -4n1imp +ni3l2a +ni3l2i +nil3l +4nimp nin1 -3n2in. -n2in2a -4n3ind +3nin. +3n2ina +nin2ac +ni2nal +3n2inb +2n1ind 2ninf -3n2ing4 -4n1inh +3n2ing +ning4s +2n1inh +4n1ink2 +3nino ni2nor +3n2inp 2n1ins -n2ins. 4ninse +4ninsu 4n1int -2n1inv +ni3nu +4n1inv +3n2inw ni2ob ni3ok -ni3ol +ni3ora n2ip -ni3ra +ni4ron +n1irr 3n2is +ni4sam +ni2san +ni2sä +nis3cha ni4schw ni2s1e ni3se. -ni2s1p -nis5s2 +nis3el +4n3isol +ni2som +4nisot +ni2sp +ni3spi +nis5s4 +nis3tha ni2stu ni3stun ni2s1u 2nit +3nita ni1th ni2ti -nit4r +4ni4tia +nit2o +3nitr +nit3s nit4tec +nit6tell +nit6ter6g +nit6t5er6k nit4tie +nit4tra nitt4sa -ni3tu +3niu +niv2 3nix -n1j -2n1k -n2k3ad -n2k1ak -n3k2al -n4k3alg -nk2am -n2kans -n2k3au4s -n2käh +2n1j +4n1k +nk1abr +n2k1ac +nka2ge +n3kal +n4kalg +nk1ang +nk1apf +nk3art. +nka3sc +n2katm +n2kato +nk1aus +n2kaut +n2k1äh n2k1äp +nk1ei +nk2eil nke4lei +n4kelem nkelma3 nkelmas6 -n3k2er -n4k3erfa -nk4erg +nke4na +nken4te +n4k3erle +nke4ros +nk3ersa +n3kesc +nke2t +nk1eti +n2ketu +nk1i2d +n2kide nk1inh n2k1ins -nk3len +n4klade +n3klag +nk3leis +n2k3len nk3les n3klin nk2lo -nk4na +nk4neb +n2knis +n2knit +n2knu +n2k1o4be +nk1ope +n2kopt +nko2r +nkord2 +nk1ori n2k1ort -nk2öf n2köl -n2k3ro +nk4rab +nk3rät +n4kre. +n2k3rel +n2kren +nk3rep +n2krez +nk3ro +n2krol nk2sal -nks2ei +nk2se +nk3sen +nk2so +nks2ti nk3s2z nk2tak -nk2tan +nk4terg +nk4t3ern +nkte3sk +nkt2et +nk2tin nkt1it -nk4top +nk2top +nkt1r +nkt3ric +nk2tro nk2tru +nkt4sen +n2k1um +nku2n +nk1urh n2küb 2n3l2 -2n3m4 +nla3ge +nle2ga +nli4ne +2n1m2 +n3ma +n3mä nmen2s -nmül3 +n5mi 4n1n -nna2be n2nada -n4n1all -n2n1an -n5nat +nna2g +n2nalg +n2n1all +nna3m +n2nan +nna3st n2nau -nn3d -nn4ens -n4nents +n3nä +n3nec +nn2ei. +n3nelb +nne4le +nne4na +nn2ens +nner4ei +n6n5ereig nner4fü +nner6geb +nn4ergr nn2erh nn2erk +nner4la +nn2ero nne2rö4 -n4n3er4wa +nn3erwa +nner6war nner2z -nne2s1e +nne4s1e n2ness +nn2eu nn2ex nn3f nng4 n3ni +nnk2 +nn2o3b +nn3obl +nn3obs n2nof -nn1o2r -nn3se +n2n1op +nno2r +nn1ori +nn4sam +nn3ser nn3s2p -nn4s3pe nnst4 +nns3tat +nn4stoc +nn2stö +nn3t2a nn2th n2n1uf n2n1unf nn1ur 1no 3no. +no5at +3n2oba +n2obel +2nobj no2bla -n2o3ble +n2oble 3noblo +3noblö 2n1obs +nobu2 +nobut3 +3noby no1c +noche4 noch4r -2no2d -no3dr +2nod +no2de +no2ed n1of -2n3o2fe +no2fe +2noff +2n1oh +3n2ohe +no2kel +2n3okk +no3kr n3ole no2leu -n2on. +no4lig +no2liv +2n3o2ly +3no3me3 +no3mi +3nomp +non2e +n1onk +n1ont +2nony +no2o 3n2opa +3nopä +no2per +2n1o2pi +2n1ops +no3p2te 3nor. nor2a no2rad -n2o1rak +n2o3rak no3ral +no3rar 2norc nor4da +3nordb +nor4des nor2d5r +no3r2e +2n1org 3norh +3n2orl 3norm +norm2a +nor3mal +3norö 3nors -n1ort +2n1ort 3n2os. -no3se +nos2e1 no3sh +no5s2k no2sp -no4ss -n2oste +2nosti nost1r 2nostv nos2u -no3tab +no2tan +no3tart no2tä -no4t1ei -no2tel -no3t3h -no4tha +not1e2i +no6t5entr +no2ter2 +noterb3 +no2tex +not1h +no2tho no2t3in -no2top -no2tr +no2t3op +no2t3r +not3tr 3nov -3now 2n1o2x 3noz 2nöd -2nö2f -2n1ök -4n1ö4l +4nö2f +4n1ök +4n1öl +n2ör nö4s3s 1n2öt -2n3p4 -npa2g +4n3p4 +npa2ge npf4 npsy3 2n1q -4n3r2 +6n3r2 +nran2 nra4s3s +nrau4ma nräu3s +nrebe2 nre3sz -nrö2s1 -6n1s +nro2h +nrö2s +nrücker6 +4n1s +n3sabo n2sa2d +n4s1a2gi n2sall -n2sang -n2sant -n3s2arg -n2saus +n2salt +ns3ane +nsa2r +ns2arg +ns3ari +n3sark +nsa4s +ns4ath +nsau4r +nsau4se +n2saut +ns2av +ns2ax n2s1än -nsä4s +ns2äug n2s1äus -ns2ca +n3sche. +n4schef +nsch5eul n4schl. +nsch2o +nscht4 n3schu nsch7werd +ns2cr ns1eb +nse4ein +ns2eh nse2ha2 nseh5ere -n3senk +n4seinf +ns2ele +ns3elem +n2sem. nsen4sp -ns1ent -ns1erf -n4serfo -ns1erg +n2sepo +n2s1erf +n2s1erg n2serh n3seri -n2s1erk -n2s1erö +ns1erk +ns1erl +n4serle +n4s3erne +n2serö ns1ers +n4sersc +ns3ertr n2s1erw -n2s1erz -n3sex -nsfi4l -n2simp -n2s1ini -nsinn4s +n2serz +n4sety +n2s1eu +nsfi2l +ns3hor +ns3iden +n5sim +n6simp +n2sini +nsinn2 nsi2te nsi2tr -ns2kal -ns2kel -n2s1op +n3s2kal +n3s2kel +ns2kis +n3skle +n3s2ky +n5smara +n2s1o2d +ns1of +n2soff +ns4om +n4s3ont +n2sop n4s3ort. nsp4 -nspas2 -n2spat -n5s2pen +ns2pac +ns2pek +ns2pel +n5s4pen n4speri n2sph ns2pi +n5spie n2spo -ns3pon n2sprä n4s3prie -n4spro +n2spro +n2sput ns3s2 -ns2t1ak +nst1ak +n4stale +ns4ta2n1 +nst3ane +ns4tar n2stas -n4stat. -n4s3tate +n4s3tat. +n6staten +n4stats ns2tau n5s2te. -n4st3eif -n5stel +n4steif +nst5eife +nst7einhe ns4tem. ns4ten. n4stent -ns2ter -ns3term +ns4ter. +nst5erge ns4tes. n5steu -ns2tob -n6stoffi +n5s2tic +n4stilg +n2stob +n4stole nst5opfe ns2tor n4strac +n4strad n6strieb -nst4ru +n4strik +ns4trun ns2tum -nst2ü -nstü1b -n2sty +nst3u2t +n3suf ns2um -n2s1un +ns1un ns2ung -ns2unr -n4s3zi +n2s1urs +n2sut +n3sy +ns2zin 2n1t -nt3abs n3t2a3c -n3t2al +ntak4ta +ntal1a +nta4lin +n4t1all +nta2lo +nt2alp +n3ta3m +nt2anb +nta3ne nt1ang +n4tansp +nt1ant n4tanza -nt2arb +n3t2arb nt1ark -nt4at +n3t2arm +nt1art +ntar6tik +nt3artu +n2t1ass +n2tath +n3tatl n2tauf nt1äm n2t1äu -n3te. nte3au -nte2b -nt1ebe nte1e nte3g6 -nt1eh +n2t1eh +n3tehe +n2teig nt1ein -nte5lei -n3t2en -nt4ene +n2t1eis +nt1emo +nt4en +nte4na nten6te. -n3ter ntera4 -nte4ras +nte6r5eis nt4erh +nt4erk +nt4erm nt4ern +ntern4e nt4ers nt4ert +ntes2 +nte3sa n2t1ess -n3tet +n6testri +n2te2ta +nteu3 +nteu6eri nte3v -nt2her -n2t3ho -n3t4hu -nti3k4l -n2tinf -n2t1inh +nt1hel +nt1hie +n2thot +n3thr +nt4hu +n2t5hum +nt4hy +nt2i +ntim3p +n2t3ind +nt3inf +nt3inh ntini1 -n3tit -nt4lem +n3t4lem ntmen2 -ntmo2 -n3to -nton2s1 +ntmo4 +ntni2 +ntnis1 +nto3re +n2torg +n4t3o4rie +n2t1öl +nt4ral ntras3s +nt1rau +nt4raum +nt3rea nt3rec n3t4ree nt3reif n3trep -nt4rig +nt4repr +nt3rich +n4t3rieg +n2troh n3trop n2t3rü n4t1s -nts2o +nts2ah nts2p -nt4s3par +nts3par +nt5spe nts2ti -nt4s1to +nt2sur +ntt2 nttü3 -3n4tu. -ntum2 -ntu2ra ntu4re. -ntu4res nt3z -1nu. -1nu1a -nu4ale -nu3ar +1nu +3nu1a +nu3a2r3 nubi1 -1nuc -1nud +2nuc +nude2 3nue nu2es -nuf2 nu2fe -1nug 2n1uh -1nui -nu3k4 +3nuhi +3nui +n2uk4 +nu3kl +n3u2kr +null3eb +nul4lin n2um. 2n3umb +n2ume 2numf 2numg -3numm -2numr +2numl +3n2umm +4numr 2n1ums +2n1umv 2n3umz -nu2n +nu4n 2nuna -nunf2 -1n2ung -3nung. -n3ungl -2n1uni +2n1une +3n2ung +4n3ungl +4n1uni +n3unk +2nunr 2nunt -1nuo +2nunv +2nunw +3nuo 2nup -2nur +2nu2r +nur2i +nurs2 +nur2z 3nu2s nu3sc nu3se -nus1i -nu3sl +nu4si nus1p +nu4ss +nuss3er4 nu4s1t -1nu2ß -1nut -nu2ta +nu2ß1 +3nut +nu2t1a +n3uto +nu2top nu2t3r -1nuu -1nux -1nuz +3nuu +3nux +3nuz 2nü4b nür1c 1nüt 2n1v2 n3ver -nvol7ler -4n1w +n3vl +nvoran4 +2n3w nwei4st -2nx 1ny. +2n1ya +n2ya. 1nyh -2nymu n1yo 1nyr 1nys 1nyw -2n1z -n2z1a4g +4n1z +n2zac +n2z1a2g +n2z3a2k n2zan +nz3a4ne +n3zani +n2zar +nza4s +n2zat n2z1au -nz1än -n2z1är -nze4l3a +n2zän +n2zär +nze4la nzel3l +nzel6lig +n6zenerg +n3zeni n4zense -n4zentw -n4zentz -nz3erwe +n4zentl +n4zents +nz3erem +n2z1erh +nz1erl +nzer4lö +n5z4err +nz5erste +nzer6tra +n3z4es +nze3sk +nze2t +nz1eta +nze3u2t +n2z1id nzi2ga n2zinh -nz1ini +n2z1ini +nz1int +nz1inv nz3le -n2zor -nz2öl +nzlei3 +n2z1op +n2zöl +nzt4r nzug2s -n2zurk -nz1wa +n2z1wa n2z1wä -n4zwir +n2zwet +n2zwir n2zwö n2z1wu ño1 +ñor2 2o3a2 -o4abi +o4a3bi o4ac oa3che oa3chi o4ad oa3de -oa4g -o4a3i -oa3ke -oak1l +oa3in +o4a3ke +oak5l o4a3la o4a3mi +oa4n +oan4a +o4a3q +o2a4r o2a3s 3oase oa4si +oa4sp +o5ass o4at oa3te o5au -o1ä +2o1ä2 o1b -ob2al -obal2t1 -2oban -o3bar +2ob. +o3b2al +obal3l +ob2am +ob2ar +ob1auf 2o3b2ä 2obb ob2e -2o3be. +2obe. 2obea -ob3ein -obel2i -2o3b4en +2o3bec +2obef +o2b3ein +2oben +obe4na oben3d4 -oben3se -ober3in4 +1o2ber +2o3ber. +ober5eis +ober3in +oberin6g obe4ris -2obew +2obev +2obez 2o3b2i -obi2t -ob3ite -1obj -ob1l +3obj +ob1la ob3lei -1o2b3li -2o3blo -2o3bo -o2b3re -obs2 +1ob3li +2oblo +2ob2lö +ob2lu +2obo +ob1or +2obö +ob3rei +2obrü +o4bs2 ob3sh ob3sk -ob2sta -ob3sz 2o3bu +o4bunt obus3s 2o3bü -2oby2 +o4büb +2oby 2oc +o3ca oc1c +3occl o1ce och1a ocha2b +ocha2r o1che oche4b o2ch1ec +och1eh och1ei +oche2l ocher4k +ochi4d och3l och3m och1o -och3ö2 +ochö2f och3r ocht4 -och3te o1chu ochu2f +och3u2t och1w o3ci -ock2er +oc4k +ock5er6sc ock3sz +ock3ta o1cl o3co o1ç o1d -o3d2a +2od2a +od3ak od2dr -ode2c -o3d2e1i +o3de2c +o3d2e3i odein3 +ode4l3ag ode2n1 -odene2 -odesi1 +ode2s1e ode3sp +od2et o3dex +od2i 2o3dia -odi4er -o3dir -o3div +2odi3c +2odif +2o3dir +2odn o2don +o2d1op odo4s +od2ö 2odr o2dre odt4 2odu o3dy -2o1e +ody2m +2o1e2 oe4b -o2ec -oe2d -oe2h -oe2l -oe2n1 -o4es -o2et +oe3di +oe4m +oen1e +oe3ri +o2e3s +oe4sc +o2e3t2 o3et. o3ets -oe2x -o1ë 2ofa -of1ac +of1a2d +of1a2g +of2an of1au +2ofä +o2f1e2b +o2f1ec +2ofee o2f1ei -of2en -o3fer -of2fa +2ofem +o2fent +2o3fer +o4ferb +2o3f2es +o2f1e2t +2ofeu +of3eun +of2fa4 +of4fal +of4fam +off3erz of2f1in of2fir of2fix @@ -9702,286 +15332,481 @@ of2fo of2f3r offs2 off3sh +off3si +off3sp of2fu of2fü 2ofi -of3l -of1la -of4lä +ofi3e2i +ofi3k4l +2o1fl +of3le +of3li of4lö 2ofo -2o1f1r -of3ra +2ofö +2o1fr of3rä of4rü -ofs1a +ofs1 +of2sa of4sam -of2spe -of2spr +ofs2ch +of2se +of2si +of2sp +of4staf +of2sto +ofs2tr ofstra8ssen -of2s1u +of2su 2oft +oft2a of2tei of3th +oft4r +2ofu +of3ur 2o1g o2g1ab +o2g1ac oga3d -og1ala og1ang -o2g1ei -oge2l1i +o2g1e2i +ogel3dr +oge2li +ogener4 ogenmas6 +ogerätein8 +o2g1eth +og2gl o3gh ogi2er -o3gis +ogin1 +o2g1ini +og3ins +og1l +og3le og2lo -og4n -ogo4i3 +o3g4n +ogoi3 +og1o2ri og2s -og3sc og3si og3s2p -o1ha +ogs1t +2o1ha +oh1alk o1hä o1he o2h1eis o2h1er2t -o2h1er2z -o1hi +oh1er2z +2o1hi +2ohl ohl1a +oh2la2d +oh2lä oh3lec ohl1ei -oh3len oh3lep +ohler2 oh4lerg oh4l3erh oh4lerw -oh3lo -ohls2e +oh3lo2 +ohl1or +ohls2 oh2lu -oh4n1ac +ohm2a +1ohmi +oh3mu +ohn1a +oh4nac oh3nee -3ohng oh2ni 1ohnm oh2n1o -o1ho -oho2la +ohn3sk +2o1ho +oho2l1e +ohol1o oh1o2p -o2h3ö +2ohö +oh3öl ohr3a +oh2rel +oh2rem +ohren3s +ohrer2 +oh4rerg +oh3ri oh4rin -oh1ro +ohr1o +oh2rol +ohrt4r +ohs2 +oh3sa +oh3t o1hu oh1w 2o1hy 2oi -o1i2d +o1id. +o3i2da +o1ids o3ie -o1im -oimmu4 +o1i2m o1in -oi2ra -oi2re -o2isc +o4ine +oi2r o3isch. +o4ische oi3se o1ism oiss2 oi4st +o1i4tu 2o1j 2o1k +ok2a +oka3b2 +o2k3ac +oka3i oka2la -okale4 -o3kat -3o2kel -oki2o +okale2 +oka6lere +ok2e +oki4o +ok2la +ok3lau ok1lä ok2li -ok4n -4okr +ok2o +oko4pt +ok2so ok2s1p -okt4 +ok3t2 +o3ku +3okw 2ol o1la -o2lab -o2l1ak +ol3abu +olaf4 +o2l1a2m +ol1ant ol2ar -ol1auf -o1lä -ol4dam -ol4dr +o3l2a3s +olast4 +ol1a2v +4o1lä +ol1ät +ol2chr +ol4d1am +ol2dä +ol2d1ed +ol4d3eng +old5ersa +ol2deu +ol2dim +ol2d3o +ol2dr +4o3le. +o2l1ef ol1eie -ol1eis +o2l1eis +ol1emb oler2 -ol1ex -o1lé +ol1erk +ol1er3t +ol1ess +ole3u2 +ol1exz ol2fa -ol2fl +ol2fem +olf3ere +ol2f3l olf1r -ol2fra -olf3sp -olf3st +ol2f3ra +olft4 +olgege3 +olge4ne ol2gl ol2gr ol2i +olie4n1 +oli4er oli3k4 oli3tu +3oliv ol2kl -olk3r -ol2kre -ol2la2d -ol2lak -oll3ans -ol2las +olk3re +ol2kro +olks3 +olk4sc +olk4si +oll1ac +ol4la4d +ol2l1ak +ol4lang +ol4lau ollä2 +ol2läd +ol3le. +oll1eb ol4l1ec -ol4lei +ol2lei oll3ein -ol2l1el -oll5ends -ol4lerk +ol3lem +oll3erh +oller4k +oll3erl oll3erw +oll3ess +ol2lic ol4li4st ol2lo2c -ol2log +ol2lo2g +ol2lop ol2lö2 +olls2 +oll3sa oll3sp ol2lu ol3lus -o3lo +4olo ol2of -olo1p2 +olo1p ol1ort -ols2t -ol2str +olo3st +ol2ov +ol3s2k +ol3te +ol3t2h +ol3ti o1lu -3oly -1olym +olu2th +ol2y +4o3lys ol2z1a +ol3zan ol4z3ern -ol2zin +ol2zim +ol2zo ol2zw +ol2zy 2om o2mab -oma4ner -om2anw -om1art +oma2bl +o2m1a2ge +om1alg +om1all +oma4n3er +o2m1ang +om2anr +o4mante +o2m1ap +o2m1ar2s +o2m1art +omar4te +o2m3a2sy +omat2i +o4matom o2m1au +o3mä o2meb om1ebe -ome3c +o2m1ef o2m1ei -o3meis o2mel -o2mene -o2mep +o3meld +omen5t6an +o4mep omer2 +om1erh o2meru om1erz -om2es +omi2c3 omiet1 -omil3l -o2m1ind +o3mig +om1ind om1ing om1ins o2m1int om3ma -om3me +om3mä +om3m2e om3mu -om1org +3omn +4omo +o2m3oa +o2m1org +om1o2ri om3pf -omp4l oms2 -omtu3 +om3sk +om3t2 +o2mum o4munt -omy1 +o3mus 2ona -ona2b -o2nae +on3a2b +on2ac +ona3g o3nal -ona4lin -on1ap -o2narb -on4at +on3ann +onan6z5ei +o2n1ap +o2n3arb +ona3th +4onatol +onat2s +o4n3at4t on2au 2onä on1äh -onbe3 2onc -onderer5 +on2dan +onde8rers +onderer7t +ond1r +on2dra +on4drin +ond3sk 2one -one4i +on1ec +o3nee +o2nef +o3neig +on3ein +on1ema one2n1 +o4n3ends +on2eng +on1ep +o3ner. on1erb o2n1erd -on1erg -on1erö +oner4fa +o2nerh +on4erka +on1ers o3nett +on2eu on3f2 -on3g2l +on3gl +ong4le ong4r ong3s +on2gue 4o3ni on2i3d +onie3g +oni2ga +on4ik o4nikr -o4n1im -on3ing -on3k2 -onli4n +o4nim +o4nind +o4ninh +o4nins +on3k4 +3onke +onli2 +onli6n onlo2c +onna2 +onna3g on3n2an on3n2e -ono1 +2ono1 o3nod -o2noke +o2nof +ono2i +o2n3oke +o3nom +on1ope on1orc +on3ord ono3s -ons1a -onsa4g +ono3t2 +onrad3 +ons1a2 on2seb -onse2l -on4sh +onsen1 +onse2t +on4sho onsi2d +ons3ing ons3l ons1p -onst2h -on3t2a -on4t3end -ont3erw -on2t3ri -o1nu +onst2a +ons3tie +onst4r +on3ta +on2t1eb +on2te2l +ont5end +on4t3erl +on2th +on4t3rat 2onuk +o3nur +2onut on3v 1ony -on3z +o3ny. +on3z2 +onze3in o1ñ +oo1c +ooch2 +oofs2 +oo2gl oo2k3l +oo2kn +oo2mo +oo2ne o1op +oop2s o1or +oor3d oo4sk -oos5s oo2su +oo2t1a +oot1ei +oo2t1h oo2tr +oot2s1t +oot3t +oo2tur 2o1ö2 +2op. o1pa -opab4 -o2p3ad -op3akt -o3pan +op3adr +op1akt +opa2le +op1ang +2opax +2opä o1pec +o1ped +op1ef o1pei -ope4n -1oper +o1pek +2open +o2pera +op1erh o1pes 2opf. op2f3a op3fah -op4ferd -opf5erde -opf1l +op2fä +o2pfe +op2fem +op2fin opf3la op1flü +op2fo op3for 4oph2 o3phe @@ -9989,318 +15814,472 @@ o1pi opi5a2 opi3er. opi5ers. +opie4r3u opin2 +2opl op3lag -o2p3le -op3li -2o3po +o2p5le +o3p2n +2opo +opo2la +op2pan op4pl +1oppo +2oppt 2o1pr -1opsi +3o4psi op3sz -1op3t4 -o1q +1opt4 +2opte +op3th +o2pum +2opy +2o1q 2or. or1a -or3a2b -o1rad -2o1ral -o2r3alm +2ora. +o1raa +2or3a2b +o2rabb +o2r3add +or3adr +o1r2ag +o2rak +1orake +o1ral +oral5l +o4r3alm or4alt -3or2am -or2and -o2ranh -or3arb -o1ras -or3att -orau4 +or2am +or3a2mi +o1ran3d4 +or4ane +oran2f +oran2m +oran4ze +or3ap +2orar +o1r2as +o2ratt +2orau4 orau2s +oraus6wa +or2av +2o1raw +o1ray o3rä or1änd or1ät -or2bar orb2l or1c 2orca or2ce +2ord. 2orda -or2d1am -or4dar -or4dau -or4d3eng +ord1am +or2dar +or2dau +2ordb +ord3eng +orde4s or2deu or4d3ing or2d1ir or2dit 1ordn -or2do +or2do4 2ordr -2ords -or2dum +ord3t +2ordu 2ordw 2ore ore2a -ore2b +o2r1e2b o2r1eck -o2r1ef +ore2di +o5ree +o3ref +or1eff ore2h -or1eig -o2rein -or1er -o2rerf -or1eth +or1ei +o3rei. +o3reie +o3r2eif +o3r2eis +orems2 +o3renn +o3rep +o2r1er +o3r2ere +o3r2ero +ore4th o2r1eu 2orf -orf3s2 -or3g4a +or2fac +or2far +org4a +org2e 2orget -or3g2h +or3ghi 2orgia -orgi1e or2gl +or3gla or3gle or2gn +or3gne +2orgr 2orh -2o3ric -4orie. -o4rient +2o3ria +2o3r2id +orid3i +4o3rie. +o3rien. +o6rienti o3rier -4oril -4orin1 -or1ins -ork2a -or2k3ar +o3ril +or1ima +ori4mi +2o3rin1 +o4r1ind +o4rins +2or4io +o2riso +2orit +2ork ork4r +ork3s 2orm +or2mam +or4mang or4mans -or4ment -2orn -or2nac -or2n3ar -or2n3ä +orm3asp +or2m1eb +or4m3erf +or4m3er4g +or2mor +orm3ord +or2mum +ormu4n +or4muni +or4munt +ormvol4 +ormwa5 +or2n1ac +or2nal +or2nan +or2nar or5ne. -or3n2o +or3ni +or4nin +or3no 2o1ro -or1o2b +o2r1ob +or3oly oro3n2a +or1ope +or1opf +o2ro2r +o3rou +or1ox 2o1rö 2orp 2orq 2orr orr4a -or3re -or3rh +or3r2e 2ors2 or3s4a or3sh or3si +or3sk or3sz or2t1ak -or2t1an -or2tau -or2tär +or2tan +orta2r +or2t1au or2tef -or4t3ent -ort2er +orte4n +or4ten5g +ort3erb or4t3ere ort3erf -ort3erk -ort5ersc -or2t3ev +ort3erg +or4terk +or4t3erl +or2t3e2v or2the or2tin -ort3ins or4t3off -or2tor +or2t1o2r or2tö +ort3rad or4trau or4t3räu -ort3ric +ort3re or2t1um -o3ru +2o3ru or2uf +or1uh +orum4s o4r3un -orus3 -o2r3ü -o2rya +oru2r +o5rus3 +o2rü +or3z2e +orzel5 +or2zw o1s 2o3s2a os3ad -os4an +osal2 +o4s3ami +2osc o4s3ca osch3ar -o4schä o3sche osch3le 2ose -ose3e -o2s1ei +ose1e +ose1in2 +os2el ose2n +o2s1er2k os2ex 2osh o3s2hi +os4hu 2osi +os2im o3sk -o4s3ka +os2kal o4ski 2os2kl 2os2ko -os2lo -2oso +o4skr +o4sky +1osm +os4mog +2os2o +osol1 +o2sö 2osp os1pec +os3pero o3s2po -os2sa -oss1ac +2oss +os6s3ac +oss3ala oss3and os4sä o6ssel -o3ssem -oss3en4k +o3ssem. +oss5enke o3ssent oss3enz -os3si -os2s3o -os4son -os2s3p -os4s1t +oss1ep +oss3er4b +osser4e +osser4f +o4ssi +os2s1o2 +os2sp +oss1pa +os2s1t os2su os2t -o2st1a2b +ost1a o3stal. -o4st1am -ost3ang -osta4s -ost1au +ost4art +ost3aut +oste2n +o4s3tep o4sterd oster3e -ost5er6we -ost3h +ost5erwe +oster8wei +ost3eur +ost1h +o2stid o2stin -o4s3ton. +os3ton +osto4s ost3ran o2st3rä ost3re -os3tri ost3rot +os4tru ost3uf 2osu4 os1um 2o3sy -o3s2ze +o3s4ze +2oß o2ß1el -o2ß1en2k -o2ß1enz +o2ß1ent +o2ß1en2z +oßer2 +o2ß1erb o2ß1ere o2ß1erf -oß3t +oß1is +oß1u 2o1t -ota2go +o2t3abi +ot1ah +o2t1ak +o3tal +o3tam +ot1ant o3tark +o2tarz +ota4s +ot1ast o2t1au -ot3aug -o3tax +o3tau. +ot2ax ot1ä o2teb -o3tei +ote1i o4t1eib -ote1i4n -ote3ine -ote2l1a -ote4lei -ot2em3 -otemp2 -otens2 -o2t1erw -4ot2h -ot4he -ot5hel -o4t3hi -ot3ho +o4t1eic +otei4n +o4t1eis +ot2el +ote4l1a +o3tem +o4t1emi +ot2em3p2 +ote4na +o4tentb +ot1erb +o4t1er2l +o4t1erw +ot2es +ot2har +o2them +o2t1hi o2thr +4oti o2til o2t1i2m ot2in +ot3inh o4tl -otli2 -ot4ol -ot1opf -ot2or -oto2ra -o3tra -o2t3re +otli4 +ot2o +oto3b4 +ot3off +oto2ph +o2t1ö +otra3c +o3t4ran +otra4s3 +ot3rat +ot4rau +ot3re +ot3ric +ot4rig ot3rin -ot2sa +ot3rus +ot2s3at +ots1o ots1p -ot2spa ots2pe -ott1a -ot2tan +ot3s4tra +ott3akt +ott3an +ot2t1a2s ot2tau ot2teb ot4terh -ot4terk -ot2th +ot4ter4k +ot2t1h +ot2tim +ott2o ot2t3r ot3t4ra -o2u -oub4 -ou2ce +ot3t4ru +ot1url +ouff6 ou1f4l oug2 -ou2ge +ou4ge ou3gl -o3uh -ou4le. -o3um -o3unds +o1uh +ou1is. +2oul +ou2le. +ou2les +ou4li +2o1um +2o2u2n oung5 oun4ge. oungs2 o4up -2our -ouri2e +4our +oure2 +ou2ret +ouri4e4 +ourme4 our4ne. -ou3s2i -ous2t +ou3sa +ous2i +ou2s2t +o4ut +ou3ti +3outp +out3s2 outu4 -2ouv 2o1ü o1v -2ovi +ov2a +2ovel +o3ven oviso3 2ovo 2o1w +o2w3al o3wec -owe2r1 -o3wi -o1x +o2wh +o5wi +o2wu 2ox. -ox2a -ox2e +o1x2a +2oxe +o2x1el +2oxk ox3l -o2xu -1oxy +o1xo +o2x1u +1o2xy o1yo -2o1z -o3z2a -oz2e +o1z2 +o3za +1ozea +2o3zen ozen4ta -o3zi -ozon1 +ozes4sc +2o3zi +ozir3 +ozon1a +2ozy +oz3z +ór3 órd2 ö1b -öbe2la -öbe4li +ö3b4a öb2l -ö2ble +ö2b3le ö2b3r ö1ch -öch1l +öch3l ö2chr öchs2t -öch4str +öch6st5ei +öchst3r ö1d +öde1r ödi3 1ödu ö1e @@ -10308,38 +16287,44 @@ ozon1 öf2fa öf2fl öf3l +öge3le ögen4s1 ög3l ög3r ög2s ö1he -öh3l2e +öhe4n1 +öhl2e4 +öhre4 öh3ri öh2s ö1hu ö3ig. ö3isch. ö1ke -ö2ko +1ö2k2o3 ök3r ök2s +ö2l 3öl. öl1a2 öl1ei öl1em öl2f1ei -ölf3s -öl1im +ölf2er öl1in +ölk4e öl2k3l öl2la2 +öll1an +3ölm öl2nar öl1o2 öls2 öl3sa öl3sz -ö2l1u -öl2ung +öl3tu +1ölu ölz2w ö1m öm2s @@ -10347,192 +16332,302 @@ ozon1 ö3ni önizi1 önn2e -ö1nu öo1 -öot2 +öo2ta öoti1 +2öp ö1pe öpf3l ör3a2 +örb2e ör2b3l ör1c ör2dr -ö2r3ec +ör3dra +ö2r1ec ö2r1ei ö2r1e2l -ör2erg -ör2erk -örer2l +ö2r1e2m +öre2n +ö2r1ene +ö2rent +ö3r2erb +ö2r1er2e +ö2rer2f +ö2rer2g +ör2erh +ö2rer2l +ör2err +ör2erw ö3r2erz +ör1ess ör2f3l ör2gl -ö2r1im +ö2rim ör2kl örn2e +örner4v ör1o +örpe2 örs2e -ör3s2k +ör3sk ört2e öru4 ö2r1une ö1s ö2sa -ö2scha +2ösc +ö2sch3a +ösche2 ö4sch3ei -ö2schl +öscher4 +ö6sch5erf +ö6sch5eri +ö2schi +ö2sch1l ö2sch3m +ö2schn ö2schw -2öse -ö2s1ei +ös1ei +ö2sein ös4en ös4es +2ösl +ös2o ö2sp ö3s2s ös4s1c -ös3ses -ö4s3set +ös3set ös4st ös4t -ö2sta +ö2st1a2 ös4u ö1ß +ößen3 +öß2ti ö1t ö2t3a -öte4n3 -öt2h +öte4n1 +ö2t3r öt2sc öt2tr -ö1v +ö1v2 ö1w ö1z öze3 özes4 -p2a 1pa. 1paa +p1ab +p2abe +pab2l +pab4rü +2pabw 1pac -pa3da -pa2dr -pa1f4r -pag4 +1p2ad +pa3el +pa1fr +1pag4 pa3gh pa1ho 1pak -pa1k4l +pa3ke +pa1kl pak2to 3pala pala3t -1palä -pa3li +3palä +3pal2e +pa3l2i +1palm pal2ma pal2mä pal2m1o 2palt +pal2t1a +pal4tei +pal2tr +pa2m3a pa2nar -pa4nat +pa4n3at pan3d +pand2a pan4ds pa2neu +panf4 +pang4 +pa4nisl pank4 2panl 2pann +panne2 +pan4n3eb +4pannu 1pa2no pan3sl -pant2 -panz4 +pan3t2h +1panto +2pantr +panz2 +pan3ze 1pap papi2 papieren8 papie8r7end +pap2pr +pap2s +papst1 +pa1q 1para -pa2r3af +pa4r3aff par3akt -1parc -pa5reg -2par2er -2parg +pa4rant +pa3rap +pa2rä +2parb +1p2arc +par3d +parer8geb +1parf +2parfö pargel6d 1park. -par4kam +park3am par4kau -par2kr -1paro +par4kr +1parks +par3m2 +par3ne +1pa2ro 2parp +2parr +4parta +3partei +1parti 1partn -1party -par3z2 -pa1s2p +3party +par3z +pa1sp +pa2spe +passer4 +pas6serg +pas2s1p +pas2t pa2ßu pat1a pat4c -pate2 +pa3t4e2 +2patel +1pat2h 1pati 1pat4r 1pau -p3auf +2p1auf pa3uni +2pausz +1pav 1pä 3päc +päck3er 3päd +päde2 +pä2d1er 3pär 3pä4s3 pä4t1e2h -pä4t3ent -pät3h +pä4tent +pä4tep +pä4t3erb +pät1h pä2to -pät3s +pä2tr +pät5s 2p1b pbe1 2p3c 2p1d2 pda2 -p2e 1pe. -pe2a +pe2a2 pea4r +pea4s +p1e2b pech1 -1ped +1peda +1peel pe2en -pef4 +2pef +4p1eff +1peg +pege2l pei1 2peic -pe1im +1peil +p2eim +2peis 1peit -pekt4s -1pel -pe2l1a4 -pe4lein +pekt2i +1p4el +3pel. +pe4l3ab +pe4lai +pe2l1au +pe2l3ax +pe2l1ä +pelb2 +pel3d4 +3pele +pe4l1e2h +pe2l1er pe2let -pe4leu -pe2lex -pe3li4n +pe2leu +peli2d +peli4n pe4l3ink +pel3inn +pel4ins pel3k -pel3la +pel3l2a pel3lä pel3l4e -pel3li -pel3t +pell2i +pe2lob +3pels4 +pel3sp +pel3ta +pel4zin 1pem 1pen -pena4 -pe3n2al +pena2 +pe4nas pe2nä -pen3da -pe4nen -pe2n1o +pen3d2a +pe4nen1 +pe4ni2t +pe2n1o2 pens2 -3pensi -penz2 +3pen3si +pen3so3 +pen3sz +pent2a +2pentw +penty2 +pe2nu2 +pen3z 1pep +pe3pi pe1ra -per2an -1perio +pe2rak +per2am +pe2r1ä +per1e2b +perer4f +pe3r2id +3pe3r4io 1perle -per4na -1pero -per2ra2 -perr3an +1perlh +perra2 +per4r3an per4rä2 per4ric per6rieg @@ -10540,280 +16635,409 @@ per6rieg 2perse 2persi 3perso +3persp +peru2 +pe3run 1perü -perwa4 -pe3sa -pes3s2 +perwa4r +pe3s2a +pese2n +1pes5s2 pes2t +pest1o +pe4stop 3pet +pet4r 1pé 4pf. -p2fab +p2f1ab p2fad p2faf -pf3ai +pf1ai p2f1ak +p4f1am pf1ans -p2fa4r +p2fa2r pf3are p2f1au -4p3fe. +1pfä +p2fär +p2f1äu +4pfe. +p2fef p2fei pf1eim pf1ein +pf1e2m p3fen. -p2fent -p3fer. -pf2erw -p3f2es +p4fener +p3fens +p3fent +p4f1ep +pfer5a +p4ferde +pfer6pro +pf4es +p2f1et pff4 pffa3 +p2f1i2d +pf1inn p2f1ins +pf1lam pf4lan -p2f3lä pf4leg pf3lei pf3lo -p2for +p2fob +p2fom +p2fo2r +pf1ori pf3r pf1ra -3pf4ro +pf4rü pfs2 +pf3sa +pf3se pf3sl pf3sz -pf3t -2pfü -2p1g +pf3t2 +pft4r +p2fum +2p3g2 pgra2 1ph 4ph. -2phä -2phb +phal4te +p1hand +3phas +p1hau +phä1 +3phän +4phb 2phd 2p1hei phen3d2 +phe4n1e phen3s 2ph1ers -2phf -2phg -phi2ka +4phf +4phg +p2hid +phik1a +phi4kan 2phk ph2l -2phm +4phm 2phn -p3hop +p2ho. +p2hob pho2s 2phö -ph4r -2phs -pht2 -2ph3the +ph2r +4phs +ph3t2 +2phthe phu4s +phu3t 2p1hü -2phz -pi2a1 +3p2hy +4phz +p2i2a1 +piab4 pia3k +pi4ali +pia3n piap2 pia3s -pi3chl -p4id -piegelei8 +pi1ce +pi2e1i pi2el -piela2 -pie4lei +piel3a 1pier +pie2ra +pie4reb +pie4rei +pies4 1pig -3pik +pi3gl 1pil pi3le +3pilo pil4zer -2pind -pin2e +pil2zw +p2im +3pin. +pi2nad +3ping pingen4 ping3s +3pins. 3pinse +pin3s2p pi2o -pi3oi +pi3oide pi3onu -3pip +pi3os +1pip pi2pe +3pirate pi3ri 3pirin -3pis -4piso +1pis +2piso pis2t -pi3t2a +pi3sto +pit2a +pi3t2h pit2s +pit3z2e pi2z1in -p1j +2p1j 2p1k2 pku2 -pkur1 -1p2l4 -4pl. +1p2l2 +2pl. 3pla -p3lad -plan3g -3plä -2ple. +4p3lad +p1lah +pla3na +p4lau +pla2y1 +2p3le. ple1c ple2e p4leg -ple5n2 +ple3n2 2p3ler -p3lic -p3lif +p4leu 2plig -p4lo +3p4lik +p4liz +plo3n 2p3lu -2p1m2 -pma1 -2p1n +2p3m2 +2p1n2 1p2o -po3b4 -po1c +pob2 +2po1c +3pock 3pod +3poe +po2el 2poh po2i -po3id +po3id. +po3ids 3poin -3pok -3p4ol -po2lau +3pol +po2lan +po2l1au +pold2e po3li pol3lo -po4lor +po3lo3p +pol3z2 +pom2ph 2pond -po1o2b -po2p3ak -po2p3ar -po2pl -po3pt +pont2 +po1ob +po2p1ak +po2p1ar +po2p3l +po3p2t po1rau porf4 +3portal +por2t1h +3portio +3porto. +3portos +3portr por4tre -por4tri -po3s2e +por6tric +3posi +pos3s2 pos4t po2sta -post3ag -po4stä -po4st3ei +po2stä +post3ei +po6stein +po4stem post3ra -po3ta +po2ta +pot1ar +3potä 3pote +pot2h +po2t3in +pott1r po2t1u +po3un po2w +powe2 po3x pö2bl pö2c -2p1p -p2p3a2b -pp3anl +4p1p +p2pab +pp1ang +pp1ans ppa2p -ppe1e +p2pat +pp1au +ppe3e +p2p1ei +ppe2l1a ppeli5ne -ppe2n1 -ppf4 +pp2e2n1 +p2p1erz +p2pf4 pp1fr p2p1h -p3p2ho -p2p1ia -pp3lä -p2p3le +pp3he +pp3l +p4p1lac +p4plan +p2p1lä +p2ple pp3oh -ppp2 +p2p1ö2 +pp3p4 p2p3ra +p2p5rä pp3ren p2pri +pp3rol +pp3rot +p2p3ru +p4ps2 pp3sa -ppt2 -pp3ta +pp3sy +ppt4 p3puc p2pul +p2p1um p2punk p3pur -p2r2 +ppyl2 +p2r4 1prak pra4s3 +pra5sp 1prax p4rä 1präd +1präf 1präg +1präl 3präm +1präp 3präs +1präv 2pre. 2prec 3pred -pre2e1 +2pree1 +pre2ei 2preg 1prei 3preis prei4s3c -prei4s3s +prei6sei +prei4ss +prei4s3t 2preiz +1prem +pren4ga 2p3rer -3p4res +1pres +pre3sa +press4e 1preß pri4e 2prig -3prinz +pri2l1 +2pring +prings4 +1prinz pri2t1 priter4 -1p4ro1 +prit3t4 +1priv +1pro1 3prob +pro3be 2proc -3prod +7prod 3prog 3proj 2pross 2proß -3prot +prot2e +3proto +2prott +pro3x +2prö 1prüf +1prüg 2prüh 2prün 2p1s 4ps. -ps4an -p3se -p3s2h -ps1id +ps3k +ps1od p2sö -ps2po -ps2te -pst3re +ps4pi +pss2 +pst1au p2stu 3p2sy +4psys ps2ze 2p1t pt1a pt2ab -pt3alb -pt3at -p3te -p4t3ec -p4t1ei -pte4l -p4tele +pta2g +p2t3a4t +p3te. +p2t1e2b +pt3ec +pt1ef +pt1ei +pt1emi +4p3ten +p4t1en2g p4t1ent -p4t1ep +pt1ep pt3erei -p4t1erw -p4t1erz -p2th +pt1erw +pt1erz +p3tes +p3tet +p4teta +p4t1e2ti +p2t1h +pt1id +pti2de pt1in1 -p4tos +pto2mo +pto4na +pto2p pto2w ptpo4 -p2t3r +pt3r +p2tro pt1s2 -ptt2 +pt3si +pts4t +pt1uh pt1um p3tung pt1urs p2tü4 3p2ty -pt3z +pt3z2 1pu pu1a pub4 @@ -10821,327 +17045,503 @@ pub4 pu2dr 2p1uh 2puk +pu2kl +pu2k1o +pu2lin pul2sp +pul2s1t 3pulv -2pund +2pulw +pum2pl +4pund +pun2e pun2s 2punt +3pup 2pur -pu3ri -3put -put2s +pu2ra +pu2rei +pus2h +pu3she +pu5t2e +3put2s +3putz +puzi3 1püf pül3l 2p1v 2p1w pwa4r -3py1 +3p4y1 +py3s py3t -2p1z +2p1z2 qu4 quel4la +que3rel +quer5n que4te. 1queu -qui3s 1ra. -2r1aa +r1aa ra2ab -3ra3ar -3raau +2raac +2raal +ra3ar +r2a1as r1ab -ra2bar -rab2bl +ra2b1ar +r2abä +1rabbi +rab2b3l 2rabd -r2a3b2er +ra2bei +rab2er +rab3erd 2rabf 2rabg -1r4abi -ra2br -2rabs +2rabh +1rabi +2rabk +r2able +ra2bli +ra4b5lo +2ra2br +2rabs2 2rabt -ra2bü 2r3abw 1raby -ra1ce +2rabz +ra2ce 2r1acet ra4cheb -ra4chin -racht3r -rach6trä +ra2cho +2rachs +rach6t5rä ra2chu r2ack -r2ad +1r2ad r4ad. -ra2dam +rada2 +ra2dac +ra4d1am +ra2dan 2radap +3radar +ra2de4i +rade5s 3radf -r3a2d3r +3radh +3radio +4radit +3rado +3radp +ra4d1r +rad5ri rad3t4 -1ra2e -ra3er r2af +raf3ahn raf3ar -ra2fer -ra3ge -ra3gle +rafe2 +ra2f1er +raf3r +rag2a +ragein4 +rages4 +2ragg +ra3g4le +4ragm ra2gn -3r2ahm -2raho +r2ago +rahle4n +5r2ahm +r1ahn +2ra1ho 4raht +r2ai 2raic -rail4l +rail2l 2r3air +raka3 +1ra3ke +2rakk 3ra1k4l ra2kre ra2kro 2rakti -3rakü +1rakü +2rakz r2al r4al. -ra2la4 -ral3ab -r3alar -ral3b +ra2la2 +ra4l3ab +ral1ak +rala4s +ra2lä +ral3b4 3r4ald -ra3le -2ralg +r4ale +ra4l3end +ra4lent +ra4l5ern +ra3lex r4ali -rali5er. -rali5ers -ralk2 -ral3la -ral5l2e -2rallg +ra2lid +rali3er +ra4lin4d +ra4l3ing +ralin6sp +ralin4t +2r3alk. 2r3alm. -r3alp. -2ralpe +2ralp. +4ralpe r4als +ral3su r3alt -2ralta -r4al3t2h -ra2lu +3r4al3t2h +ra2l3u 3raly -r2ame +ra2mei ra2mer -1r2ami +r2ami +r2amm ram4man +ram6mens ram6m5ers ram4mit ram4mu +2ramn +3ramsc 2r1amt ramt4s -r2an. -ra5nat +2ramu +2rana +ran1ad +ran3ade +r1a2nal +ra2nan +ra2nar +ra2nau 2ranb r2anbe -4ranc r4anda r4ande ran4dep ran4d3er -4r3anei -r4aner +3r2andi +rand3s +1raner 2ranf -1rangi -rani1e +2ranga +ran6g5e6be +3rangi +r2angl +rangs2 +rang3sp +rani3e +r3a4nil +ran3ka ran2kr -2ranl +ran2kü +4ranl 2r1anm +r2anmi r2anmu +2ranna +ran5ne 2r1anp 2ranr +2rans r2ans. -r2ansp ran4spa -ran2th +4r5antei +r1anth +r2anto 2rantr -2r3anw +1ranu +2ranw +r2anz. r2ap +2rapa +ra2par 2rapf -ra2pri +2rapo +ra2pok +rap2pr +2r3a2pri +2r1aq r1ar -r2ara +r2ar1a 2rarb -3rarei -rar3f4 -ra4r1in +r2are +3r4arei +raren1 +rar3et +rar1e2v +r2arf4 +ra3rie +rar3in +ra3ris +r3a4rist +4r3arit r2ark -2r3arz -r2a3s2 +raro2 +ra2rom +2rart +2rarz +rar3zw +ra3s2 r4as. -ras4a ra4schl -ra5sen -ra5si ra4sk -2rasph -ra4ssi +r2asm +ras3si +ras3sp +r2ast +ra4st3ei +r3asth +ra4sto +ras3tri +2rasyl 2raß 1rat -ra2t1a -ra3ta. -ra3te +ra2t1an +ra2t1ei +r3a2tel +ra4tid +2ratla +2ratm rat2o +2ratom rat4r -2r3atta +r3att +2ratta +2rattr 4ratz +rat3ze 4rau. 3raub. -4raud 4raue -rau3e2n +rau3e4n 2rauf -2raug +rau3fä +2rau3g2 3raum rau4m3ag -rau4man +rau5mes rau2mi 3raup 4raur 2rausb +3raus2c +2rausd +rau3se +2rausf 2rausg +raus8gewä +2raush +2rausl rau2sp +2rauss +raus8sche raus3tr -4raut +2rausv +2rausw +rau3ße +2raut +raut1r +rau4tra +rau4tro raut5s 1raü r2ax -raxe3 -raxi4s1 +raxi4s +r3axt +r2ay +ray1o +r2az räch4s 3r2äd 4räf rä1fr 4räg 2räh -2räm +4räm 3rän. 3räni 3räns +2räp +2räq 2r1är r2är. rä3ra -rä4sc +rä1ro +rä2sc +räse2 +rä5sse rä2st 3rätse +4rätz rä2u 4räue -4räun räu2s -räu5sche +räus2c +räu7schen. +2räuss +2räuß 4räut +2räx 4r1b -r2b1ab -r2b1a2de -r2bak -rbal3a -rba3re +r2b3a2b1 +r3bac +rba4del +rb2al +r3bam +r2bang +r2bant rb1art +r2barz rb1auf rbb2 rb1ech -rbeid2 +rbe3erf +rbei3d2 +rbe3inf +rb3einh +rbe3int r4belä -r4belis -r3ben. -rb1ent +rbel2o rbe3r2e -rber4gl +rber6gin +rb1erl +rbe3rum +rbe5sl +r2bim +r2binf +r3bit +rbit2a +rbi3tu rb2la -rbla2d +rb4la2d r2blan r8blasser r4b3last -r3blä -r2ble. +r3blat +r3blau +r2b3le. +r3blen rb3ler r2bleu rb2lin rb2lö +rb3lös rbmas3 -rb2o -rb4ri -rb2sa +rb2ob +r2bonk +rb3ras +rb3rea +r8b7rechts +rb4sam rb2sei -rb3ska +rb2ser rb2s1o -rb2sta rb4stä -rb2stu +rbs3tri rb2su +rb4sz rb2u -rbu2sc +rbü4b 2rc r1ce r1che. r1chen -r1chi +r1ch2i rch3l +r3chlo rch3m rch3r -rchs2 +rch4ro +rchs4 rch3sp -rchst4 rch3t2a -rch6terg -rch6terw +rchter6r rch1w r1ci r1cl r1ç 2r1d -r3da -r4dab rd2ac -r4daf -r4d1ak -r4d1al +r2daf +r2d1ak +r2d1a2l +rd2amm rdani1 +r2dann rd1ant -rd1anz -r4dap +rd1ara +rd1ark +r2darz +rdär2 +r3de. +r3dee r2dei rd2ei. -r4deis r2d1elb -r3den +r2de2le +r2delf +rdels2 +rdem6 rden3d2 -rde3re -rder4er +r4dengl +r4dents +rde3ob +rde3ono +rde3r4er rderin6s r4d3ernt +r3des rde3sp -rdga4 -rdgas3 -rdi3a2 -rdia4l +r2d1e2x r2d1inn -rd1it -rdo2be +rd1iri +rd1ita +rdo2 +r2dof r3don rd1os -rdo4st +rd3oss +r2d1oz r2dö rd3rat +r2drau rd4ri -rdrü4 +rd5ris +rd4rö +r3d4rü +rd2sän +rd3s2k +rd3s2z rdt4 rd3ta rd3th -rdwa4 +rdt2s +r2d1uk +rdwa6r 1re 3re. -re3aler -re2am +rea2d +rea6l5erw +4re2am re3at. re3ats +reatu3 2reä re2b1a re2b1l reb1r reb3ra -re2bü -r2ech +reb3so rech3ar 4rechs 2reck. @@ -11149,1511 +17549,2455 @@ rech3ar 3red. 4redd 2redi +re2dik +3redn +3redu +re1ebe re1el +re1em +ree4mi re1er 3refe -2reff +4reff +r2eff. 3refl 3refo 3reg -5reg. rege4l3ä -2reh +regene7ra +4r1egg re2hac +re2h1ar +re4hen4e re4h3ent -re2h1i -rehl4 -reh3n +re2hi +reh1l4 re2h1o +re3hol +3rehö +reh4th +re2hü r2ei. +r2eib +rei4bel +rei4ble +r2eic +2reid r2eie +4reier. +rei4fei +4reifel 2reig +3reigä +3reigeh +r4eigel +6reigens +3reigi +4reign +3reigru rei3l2a rei3l2i +2r1eilt 3reim reim2p r1ein -4reinb -rei3nec -4reing -r3eink -4reinr +2rein2a +rei3nal +2reinb +rein4du +rei3n4ec +reinen5 +2reinf +rein4fe +re4info +2reing +2reinh +4reinn +4r3einr +2reins +4reinsa +rein6sel rein8s7tre +rein4sz +2reint +rein6teg re1in2v +2reinw +2reinz +4reisar +4reisb +2reisf +2reish +2reisr reister6 -reis5tro -re2ke -re3la -2r1elb +4reisu +2reisw +reit3s2 +3rek +4re2ke +4rekk +5rekn +2rekz +r2el. +r2ela +re3lat +2relb rel2e relea4 -re3lei -2re2lek -2r1elf +re5lei +re2lek +4relem +r2elev +2relf +reli1 +2relit +2relix +r2ell +rel4lar +rel4lei re3lo -2r1elt +r2els +2relt relu2 -r4em. -r2emi -4rempf -4remu -r4en. +3r2em. +2r1emb +rem2da +re2m1ei +re5men +2remi +re3mig +2rempf +rems1c +rem4str +2rem2u +r2en. r2ena -rena2b +2rena. +re4nac +re3nad re3nal +re4n3an re2nä +r1endg 3rendi ren3dr -re4n3end -ren2gl +4renerg +4rengag +ren4gan 2rengp +3renh re2ni +3renm ren4nar -ren3sau -2r1entg +ren6nene +ren6sein +rens2p +2rentd +6rentera +2rentf +3rentfo +2rentg +r3enthä 2r1entl 2r1ents -2rentw -4rentz +2r3entw +2rentz r2enz +ren6z5er6f +renzer6l +ren6z5er6s +renzer6w +ren4z3in ren2zw +re2ob re3or 3repe -re4pis -3repo +4re2pen +2repi +re2pis +2repoc +2r1e2pos 4repp -3r4er. +3repu +3r2er. +rera2 2r1erb +3r4erber rer2bi -r4erbil -r2erbr 2r1erd +rere2 +4r3ereig +r1erek +re2r1ep r2erer r1erf -r2erfe -r2erfl +r3erfa +4rerfah +2rerfi +2rerfo +r2erfr +rer2fü r1erg +4r3ergeb +5rergebü r4ergen +3r4erges +2rer2go +rer2gr +r4ergru +r1erh +rer2hö re3ri +re4rid r1erk +rer4kan +rer2ke 4r3erken -r2erki -2rerkl -2r1erl -5rerlag +3r2erki +3r2erko +r1erl +2r3er2la +5r4erlag +r3erleb +r2erli +2rerlö 2r1erm rer2n 2r1ernä +r1erne +2r1erni 4r3erns -4r3ernt -r2e1ro +4r1ernt +re1ro re2rob -r1erö -3r2ers. +re4rosi +2r1er2ö +r1erre +rer4reg +rer4rei +r1erri +5r2ers. 2r1ersa +r6erschi r2erse 2rersp -r1ert +rer4sta +r6erstad +2rer6su +r1er3t4 r2erte 2rertr +r1erw +rer4wac +rer4wec +r4erwes 2r1erz -rer5ze -r2erzy -3r4es. +rer2zä +3r2erzy +3r2es. re2sa -res3an +re4sam +resche4 re4schw 3rese -3reso +re4se2h +res1of +3resol +3reson +res2po 2ress -ress2e +4resse +res3sei res6s5erw -3rest -res3tem -re2stu +res4sto +4ressu +resten4 +re6stent +re4stra +2restu 3resu 2re2ß1 -re2thy +re2t1ak +2re2tap +re2tau +ret2e +2r1e2th +re2tra +re4trol re2u +reu4eri reu3g2 2reul re3uni -2r1eur +2reur +4reuu 2reü -2r3evid -r1ew +4r3eva +2r1evid rewa4r re2wi -4r3e2x1 +2rewo +2r1e2x1 3rez -4rezi +2rezi 1ré -2r1f +4r1f +rf1ack +r3fahre +r5fahrt rfall4s rfäs3 +rfe2i r2fent -rf2es +r3f2es +rff2 +rffa3 +rf3fe rfi4le. -r2flan +r4fland +r3f4lä rf3lic -rf3lin rf4lö r3flü -r3for +r2fo2b +rfolg4s +r5foli +r4frauc rf4ru rf4rü rf2sa +rf4sam rf2s1ä -rf2s1id -rf2spr +rf2su rf2ta -rf3t4r +rft4r rf2u -4r1g -rg2ab +rfzu3 +2r1g r2g1a2d r2g1ah r2g1ak -rg2an -rga5ssen +rga4ner +r2g1ap +r2garb +rg3art. +r2g1ask rgas2t -rga4str +rga5stes +rgd2 rge4an rge2bl -rg2el +r2g1e2c +r3gel +r4gelef rge4l3er rgen4z3w -rge4ral -rge4tap +r4ge4tap r2geto rgi4sel -r3gla +rg2lad r2glan +r3glanz rgleich8s7 r2gleu r2glig -rg2lö +r2g3lit +rg2log rg2lu -r2gna -r2gno -r2g1ob +r2g3na +r2gne +r2g3ni +r2g3no +r2g3oa +r2gob +r3gog +rg3op +r2g1or rgö2 r2g1öd r2g3ral +rg4rau r2greg -r2gres +r2g3res r2gret rg3rin rgro5sse +r3grun +rg3rüs +rg3se +rgs2ei +rg4sel +rg3s2i +rg1sp +rgs2pe +rgs2po +rgs4ti +rgs2tu +rg1su r1h4 2rh. -2rha -r2ha. -r3hals -2rhä -3r4he. -2r3her -r2hoe -r3hof -rho2i3 +r2hag +2rhah +2rhak +r4haltb +r3han +2rhau +2r3hä +3r2he. +r3hea +2rheb +2rhef +2rhi 2rhol -2rhö +r3hop +2rhot +2rhöl 2rhs +2rhü 1ri -ri3am -ri3at +ri1an +ri2ano +ri2ast rib2bl ri1ce ri1cha -ri2dan +ri3chl +richt8spo +3richtu +ri2con ri2dau -rid2g +2ride +ri2d3e2l +ri4dent +r2i3di 2ridol +rid3r 2ridy r2ie -rieb4s3t -rie2fr +rieb6ste +4riefm +rie2f3r +rieg4s3 +ri2e1i +riein1 ri1el +rie3l2a ri3els -riene4 +ri4enä +riene2 ri3eni rie2nu ri1er. -ri4ere -ri3e4sti +rie3r2e +riere4n +ri3ers. ri1eu ri2f1a -ri2f1ei -ri2f1er +ri2fä +ri2fei +ri2fer +rif6f5end +rif4fer ri2f1o ri2fr rif4ter 3rig +4riga +4r3i2gel ri4gene +4rigg 5rigj rig1l +ri4glä +ri3g2o3 4rigr -rik1l -ri4kla -r2imb +4rij +ri2kar +ri2kä +ri2kin +ri2kn +ri4kone +ri2kor +2rima +ri2mag ri2me. +2rimm 4rimp rim2s -r2i3na -2r1ind -rin4dex -rin4diz -4rindu +ri3na +r1inbe +rin2c +2r1indu ri3n2e rine1i 2r1inf rin2fo +3r2infr +r2ing rin2ga -ring3l +ring3le rin2gr +ring3sp 2r1inh -4rinit -2rink +2rinit +4rinj +4rink rin2kl -3rinn +rin2ko +rin2kr +2rinl 6r5innenm 4r3inner -4rinnta +2r1innr r1innu -2rins2 -3r4ins. +4r1in2q +2r1ins +rin2si rin2so -rin2sp r4inspi +3r2insy 2rint -rin4teg -rin4t5r +4rinte +rin6tent +rin4t5re 2r1inv +rin2va +2rinz +ri2ob +r3ion +ri3o2st +ri2pl +ri3po 4r1ir r2is -ris4a -ri4scho +ris2a +ri3s4an +ri4sch3o ri4schw 3risik -rismu2 -ri3so -ri2s1p +ri3s2ko +r3iso +ri4s3p +r3isr 3riss -ris3si +ris2t rist5ers ristes4 -ri6stess -ri2ß1 +ri2st3r +3ri2ß1 r2it r3i2tal -ri3t2i -ri3t4r +rit3ant +rit2i +2ri3t4r +rit1s +rit4t3au rit4tei -rit2tr -5ritu +3ritter +rit6ter6f +rit2to +rit2t3r +rit2u +r1i2tum rix1 ri3xi 1rí 2r1j 4r1k +rka2b3l +rk1ah +r2k1ak +rk1all rk2am -rk4ap +rk1are +rk1asp rkauf4s -r2käh -r3kla +r2k1äh +r3kel +r4kelem +rke2n1 +rken4er +r2k1er2l +rk5ersta +r2k1er4w +r3k2es +r3ket +rk1im rk4las rk4lau +rk4lim r2klis rk2lo rk2lu -rk4n -r2k5nu +rk4ne +r2kob +r3kol +r3kon +rk2op +rk1o2ri +r2kou +rk2ö rk3räu -r2k3rea r3kri -rk2s1e +rk3rin +r2k3rom +r2krou +rk2sal +rk2sei +rk2sel +rk2ser +rk2so rk2sp +rk3spi rkstati6 rk4stec +rk4stoc rk2ta +rk2tel rk4t3eng rk4t3erf +rk4terg +rk4t3erl rkt3ers rk6tersc rk4t3erw rk4t3erz -rk2tin +rk4teta +rkt2i +rk2t3in rk2t1o2 +rkto4b rk2t3r -rk3tra -rk2um +rk2tum +rk1ums rku2n -rk1uni +r3kup +r3kus +rku2sa rkus3s -rku4s1t -4r1l +rku2s1t +r2küb +2r1l rl2ab -r5lag -r5lan +r3lag +r5land +rlan4d3i r2l1ar -r2l1a4sc +r2l1a2sc +rlas2t r2l3aug -rl2e -rle4a +rle2a r3lec -rle4i -rle2st -r3let +r5lei. +r3lep +rl2et +r3lex +rlg4 r3l2i +rli4ne. r3l2o +rlou1 +rl2ö rlös5s -rl2s1p +rls2a +rl2spr rl2sto rl3t -r3lu +r3l2u +rlus2t +rlu6ster rlu4str +r3ly rlz2 4r1m r2mab -r3m2ag +r2m1ad rma2la -r2m1ald +rm1ald +rm1ami r2m1ank -rm1ans rm1anz -rm1a2p -r2maph +r4m3aph +r2marc +r2marz +r3mas +rma4spe +rmas3se rma5ssen rmas8sens +rmat2o +rm2är rm3d2 -r2m1ef +r4m3einh +rme4na +rm2ene +r2ment r2meo +rmer4fo +r2m1erh +r2m1erl r2m1erp +r2m1erw rm2es +rme3sa +rme3st +rmeta2 r2mide -r2m1im +rmi6nanz +rminen4 +rmi6neng rm3m -rmmo3 -r2m1o2ri +r4mn +r2m1ob +rm1o2ri +rm3p2 +rms2 rm3sa -rms2t +rm3sk rm3sta +rm3t rmt2a -rm2u -rm3ums -4rn +rmu2n +r4muna +r2muni +2rn rna2b +r3nad +rn4ade +r3nage +r2n1all rna4n -rn2and +rn4and rn3ani -r2n1anz -rna4r -rn2arb +r2nanz +rna2r rn3are -rn3ari +r4n3ari +r4n1a4st +r4n3att r2nau +rn3aug +rn3de rn3d4r -r3ne -rn3e4ben r4nef -rn2ei -rn3eif -r4n3eis +rn2eid +r4neif +r4neis +rn1ema rne2n -r4n1ene -r4nerf +r2n1ene +rn2eng +r4n1e2p r4n1erg rn4erhi +rner4ke +rner4ku +r4n1erl r4n1ert -rner4ve +r4n1erw +r4nerz r5nes -rn2et +rn2e2t +rnet1e +rne4tem +rne4ter +rne4to +rn2eu rne3uf r4nex rn3f -rng2 -r3ni -r4n1in +rn3g2 +rngene4 +r2nid +r2n1in +r4ninf +r3nit +rnk2 +rnn2 r3nod +rn2oh r2n1op r2n1or rn1ö +rnö2d rn3sa rn3s2ä -rn3s2p +rnse4ha +rn3s4p +rns2u rn3s2z +rn3t2a rn3t2e -r1nu rn1ur r1nü r1ny -ro2bei +rnz2 +r2oba 2robj 1robo +ro2bo2r +2robr +ro2bre 2robs ro1ch +roch2a 3rock. -4rockn r2o3de -ro3e2 +rod4r +roe4 +2roff +ro3fl 4rog. -4rogs -roh1l -3r2ohr -3roi +ro3g2a +3rogg +ro2h1in +roh1l2 +4rohn +ro2hö +3rohr +1roi +ro3in +rok2l ro3le +ro2liv rol4lan -rol3l4en +rolle4 +roll4en +rol6lerg +rol6lerw rolli4n rol6lini 2roly 4rom. ro2mad -ro2mer +ro2mal +3roman. +2romb +romen3e +ro2m1er 4romm +2romn 4romt r2on +ro3n4ab +ro2nan +3rond ro4nerb +4ronk 3ronn rons2 ron4tan -4ro1ny +ron6tend +ron2t3r +ron2t1u +ro1ny +ro1o2f +rop2a +2rope 2ro2pf -ro3ph +1ropl +2ropt r1or -r2ora ro2r3al ro2rat -ro2rei -ro2r1o +2rorc +ro2rel +ro2ro ror3th -ro3se +rort4s +ror2ü ro3sh -ro5s2i -ro5smo -ros6san +ro3s2i +ros2p ross1c +ros4st ro3sta +ros3tel ro2st1r +ro2sum +4r3osz +roßen2 +ro4ßenk +ro2ßi ro2ßu -ro2tag +ro2tan +rot3au ro2tä -ro2tei -ro2tho -ro2tri +ro3te +ro2te3i +ro2t1ho +ro2tru rot1s rots2o -ro3t2u +3roul ro3unt 3rout +2ro1x +4roy rö2b3l rö2du 2rö2f 3röh -r1ök +2r1ök 1röl -rölla4 +2röl. +rö3le +r1ölp 3römi -4röp r1ör r2ös. +rös1c +r2ö3se +1rösl 3rötu 2r1p2 -r3p4a -r3p4e -rpe2re -rpe4r3in +r3pa +r3pe +rperer5 +rper3in rpf4 r2pli +rp4lu +r3po rpo4str +rp3se rps1t -rp3t +r4p3t r3pu 2r1q -2r1r +4r1r rr2ab -rr2ar rra4s3s +rr4at rrat2s +rr1auf rr1äm rrb2 rr1c -rr2e -rre4ale r5rega +rr2ei rre2le rre2pa -rrer4s +rrer2 +r2rerh +r2rerl r3res +rres2t rre2ve -r2rew -rr2he -r3r4hen -rrik2 -rr2n3a -r3r2o -r4r3ob +r4rezi +r3r2hen +rr2hos +rr4i +rri3k2 +rrm2 +rrn3au +rr2o +rr3obs rro3m +rro2re rr2th -r3ru +r3r2u r3r2ü -rrü1b -4r1s -rs3ab +rrz2 +6r1s +r3sabo r2sa2d +rs2al r4samp r4s1amt rs2an +rs3ana +r4sanf r2s3ang -rs3anp +rs3anm +r4sanp rs3ar -r3sche +rs4ark +r4sarm +r4sch3e4b r6scherl -rs1ebe +r5schu +r5schwu +r5schwü +r2s1ebe +rse2e +r2s1ef r2sein -rse2n1 +rse2n rs2end rse4ne +r2sepi rs1ere -rs1erö +r2serh rs1ers -rs1erz +r2serz rse2t rs1eta +rs2ext +r3s2hav +r3shir r3sho -rs2kal -rs2kan -rs2kie -rs2kis +rs2hor +r4shu +rs2il +rs2ka +rs2kel +rs2ki +r4skir rs2kl -r4sko -r4skr -r4sku -rs3l -rs4no -rson4e -r2s1op +r4skor +r3s4kri +r4sky +rs4mog +r3s4no +rs4om +r2sop r4s3ort. +rso4s +rs1ost rs2p4 -rspa3s2 -rs4pel +r3span +rspa3s r2s3ph -r5spi -r4s3s2 +r3spi +r3spl +rs4por +r2spun +r2sput +rs3s2 +rst3abl r5stad +rst3ala +r4stale +r4stans r4stant +r2stas +r3stat rs2tau -r6st5eing +rs2tea +rs2tee +rst5eing +r6st5eint +r4st3emi rster2 +rst4erb r6sterbt +r4st3erl +r4sterö r4st3erw -rs2th -r5stim +rs2t1h rst3ing r2stip +r2stit +rs2tob r2s1tot -rs2tr -rst3ran r6strang +r4stris rs2tu -r2sumf +rsuch4s +r3suf +rs2ums rsü3s -r3swi +r3sy +rs2zin +r1ß 4r1t -rt4abl -r2t1alm -rtals1 +rt1abs +r2t1a2d +r2t3ae +rt1akr +r4t3albe +rta3l2e +r2t1all +rtal4s3e rt1am -rt1ang -rt1ann -rt1ant +r3t2ame +rt1an +r2tanw r2t1ar -rt3a4re -r2t3att -rt1är +rt3att +r4tauft +rt3äh +rt1änd +rt1ärm r3te. rte1e2 -rtei3la rt1ein +rt4eind +r4t3einh +rte2is r2telf +rte3li rtel6lei -r4tempf rte2n1 r3ten. rte4na -rtens2 +rten3s2 +r4t3ents +rten3z +rteo2 rt3erei -r4terfa -r4terfo +r6tereig +r4ter4fa +r4ter4fo rt1erh +rt1erk r4t3er4la rter6mit r4t3ernä +r2ter2ö rter4re -rt1ers +rt1er4s +rt4er5sp +rt1erz r3tes2 rte3sk -r2thi +rt1he +r2thel +r2t1hi rt2hum r2t1id +rtik2 r2t1ima -rt4is -rto1p -rt1or -rto2ri -r2t3rak +rt3inf +rt2is +rt2it +rt3m +r2t1ob +r3top. +rto1pf +rt1orc +r2torg +r3tork +rt3rams +rt3rand rtra4s3 +rt3rati rt3rec -rt3ros -r4ts +rt3ris +rt3rol +rt3roma +r3trop +r2trou +rt3sc rt4s1eh -rt1s2pe +rts2el +rt3sex +rts3ing +rts1o +rts1pa +rt1spe +rt4s3tan +rts4tie rt3t4 +rt1umb +rt2u3na +r4tunt r2t1urt -rt3z -rtz2a +rtu2t +r2t3ute +rty1 +rt3z2 1ru ru1a +ru4ale ru3a2r3 -rube2 +rube4 +rub2i ru3ches +rucht3s4 rude2a ru2dr +ru2et 3ruf -ru2fa +ru2f1a +ruff4 ruf2s1 -ruf4st ruf4ter +ru2g3r +3ruhm 2r1uhr -ru1ins +3ruin +ru3ins ru1is 2rum -4rumf +ruma2 +4r3umd +4r3umf +4r3umg ru2mi -4ruml -r2ums. +4r3uml +4r3umsa +4r3umw 4rumz 2r1una 2rund -run2d1a -r2unde -rund3er -run6derf -run6der6l -run6ders -run6derw -2r1unf +run4d1a +runden5e +run4d3er +run2e +runei2 +4r1unf +run2ga 2rungl -2r1u2ni -4r3unio +4r1u2ni +r3unio +ru4nis. run2kr -2r1unl +4r1unl 2r1unm 4runn +4runr +r1unse 4r3unt -2runw +4runw +2rupd ru3pr -4r3ur +4r1ur ru2ra ru2r1e 5ruro +r4us. ru2si +rus2p rus3sen rus2s1p -rus6s3t -3rut -ru4tei -rut3h +rus6st +rus2t +ru2tab +rute4 +ru2tei +ru2t1el +ru2t1er ru2t1o2 ru2t3r +rut6scha 4ruz -ru2zw +ru2z1w 1rü 2rüb -rü1ben +4rübu rü1ch +rücks2 rück5sta +rü2hel +rüher2 +rüh1l 4rümm rün3z -rü3s2s +rü3ss +rü4ssi 2r1v +r3ve +rv2el rve4n1e +rvenen4 +r4ventz rve5s +r3v2o rv2s 2r1w -r5wei +rwe4gel +r3wei +rwelt4s +r5werk +r5wert +r2wo. +r3woh +r3wort rwun3s 4r1x 1ry +2r1ya ry2c -rys2t +rygi3 +ry1la +ry2le +ry1os +ry3s2t rysti1 2r1z rz2an +rz3ant r2zar -r2zas -r3ze. -rz1eck +r2zat +rz2än +rzell4a r5zene rz1eng -r4z3ents +r4zents +rze2p +rze2ra +r2z1erd r2z1erf r2z1erg -r2z1erk +rz1erk +r2z1erl r2z1erw +rzes2 +r2z1ess rz1id +rz1int +rzir3 r3z2of -rz2ö -rz3te +r2z3ot +rz2tan rz2th -rz2t3ro -rzug2u -r3zü -r3zwä +rzu4g3l +r2zwä r3z2wec +r2zwir 1sa 3sa. 3s2aa 2s1ab +sab2ä +4sabd sa2be 3sabet +sa2bit sa2bl -sa3ble +4sabm sa2br -4sabs -5sache -sa2cho2 +4s3abs +4sacc +5s2ache +sa2cho +sachs2 sach3t -5sack. +s2ack s1ad 2s3ada -s3adm +sa2der +2s3adm 2s3a2dr -sa2fe -2s3aff -3safi +sa4fe +4s3aff sa1f4r 3saft +saf2tr 3sag -sa4gent +sag2e +5sage. +5sagen. +4s3agent +4s1agg sag4n 4s1a2gr -3sai +3sahs +3s2ai sa3i2k1 -sail2 +sail4 +sai4r 2s1ak sa2ka +sak2e 3saki -3sakr -4s3akt -3sal. -4s1alar -sa4l3erb +4sakk +3sako +4sakt +3s2al. +s2al2a +sa2l3an +sa2lar +sa3lat +3s2alb +sal3bl +3s2ald +sa4lerk +3sali sa2l1id s1all -sal5lo3 -3salo +sal3la +sal4le. +sallo3 +3sal2o +sal3or sal2se -2s1alt -3s2alz +s1alt +s2al3t2h +3salz 3sam +s2am. +s1ama +4sa2mat s2ame -s3ameri -5samm -6s1amma +4s3a2mei +sa3men +sa2min +5s2amm +6s3amma 4s1amn s1am3p4 -sam2to +4samph +s2ams s1an s2an. -2s3a2na +2sa2na +san4at +sa2nä 2s3anb s2an2c 3s2and -s4and. -san4dar +san4dan san4dri +sand3s +sa2ner 3sang. -sang4s +4sanga 2s3anh -3s4ani +3sani +3sanken 2s3anl -2sanp +2sanm +2sa2no +2s3anp 2s3ans +s4anse san4sk +san3sp +4santei 4santr -2s3anw -s3anz +4s3anw +2s3anz +s4anz. +s4anzt 2s1ap +sa2pe s2aph -sa2po +sap3p 3sapr +2s1aq 2s1ar 3s4ar. -3s2ara +3sara 4s3arb 3s2ard -3sari -s3arr -3s2ars -4sarti -s1a2sp -sas6sest -4s3a2sy -3sat +3sarg +sar2ga +sa3rin +s2ark +sa2rom +s2ars +4sart +sa4r1u2 +s1asc +2s1a4si +2s1a2sp +4sa2sy +3saß sat2a -4s3ath +satan2 +sa4t3ant +sat1ei +2s3a2tem +s3ath +3sat2i 4s3atl -4s1atm +4satm +sat2o +sa4tol sa2tr sa3ts +s3atta +4s3attr +3satz +5satza +sat4zel sat4z3en -s1a4u +s1au 3sau. 3sauc -3saue -sau8erste -2s3aufb +3sau2e +2sauf +4s3aufb +3saug +saug3le sau2gr +sau3h 3saum 3saur sauri1 -2s3ausb -sa2vo -3säc +2saus +3saus. +4s3ausb +4sausf +4sausg +sau2sp +4sauss +3sauste +4s3ausw +2sauß +s1av +sa2ve +sa2xi +sa3xo +sa2y1 +1säb +3s2äc +3s2äg s1äh -s3ähn +4s3ähn 2s1ält 2s1äm -2s1änd +4s3änd +4s3äp +2säq 2s1är -sä2s3 +3s2ärg +sä4s3 +sä5sse 3s2ät 1säu 2säuß 4s3b4 -sba4n -sbe3r2e +sba4ne +sbau6men +sber2e sbus3 1sc -4sc. +2sc. +2scab +2scac +2scaf +2scal 2scam -s2cap -4scar -2s1ce +2scar +2scat +s1ce +4s3cei 6sch. -sch2ab -3schaf -2schak -sch2al +5schaf +5s2chal +sch3ana 4schanc 4schang 5schanz 4schao -s2chau -3s2chä +4s3chara +4sch3ar5m +s2chä +2schäq 2schb 2schc 2schd sch2e -3sche. +4schech +sche2f 6schef. +6schefi 6schefs -sch3ei. +4sch3ei. +sch6ein. 4schemp +sch5erfü +sch5erla 3sches 4schess 4schex -4schf -4schg +2schf +2schg 2schh +schi4d schi4e -3sching 4schiru 3schis 2schk -sch4lag +sch4lac 4schle. 6schlein +4schloc +4schlöc 4schmas +4schmed 2schmö 4schmüh +2schmy 2schn. +4schneb +4schnut 4schobj +4schorc 2schox -3schö -4schöl +4schör 4schp 2schq +4schrad 4schre. 4schrin +s3chris sch3rom 4schron 4schrou -6schs2 +6schs4 sch3sk 6sch3t scht2a -scht4r -s2chu +scht2i +scht1s +s4chu 4schunt -3schü +5schü 2schv -4schwaa +sch4web +4schweg +6schwerk 4schwet -sch4wil +4schwid +3schwü +s5chy 2schz 2scj 6s1cl 2sco -3s2cop -3sco4r -s2cr +4scoa +3s2co2p 2scs 2scu -4s3d2 +2scy +4s1d2 +sd4a sda3me +sdes4 sdien4e +s3do sd4r 1se se3at. seau4 +seb2 +5sebä 2s1e2ben -seb4r 2s1echo -s1echt +sech6str +2s1echt 2s1eck se2dik 3see -se1ec -se2e1i4 +see1i2 see3ig -seein2 -se1er. +se2el +see3len +se3en. +see3n2e +se3enp +se3er. +see1ra +seer2e +se1erf +se3e2r1i se1erk -se1erö -2s1eff +se1ers +see5s2 +2s3eff sef4l -3seg -se2gal +3s2eg +s3e2gal se2gl seg4r 3seh seh1a -se2ha4g -se2han -se3he -se4h1ei -se4hel +se2hag +se2hak +se2hel +seher4e se4herk -se2hin -seh1l +se2h1in +seh3l +se4h3ö +seh3ra seh3re +seh5r2i seh3s -seh3t se2hüb -2s1ei. -2s1eie +2sei. +2s1eic +2s1eid. +sei3da +4s3eifer 2s1eig -sei3le +3seil +s2eim s1ein 5s2ein. 2seinb +seinbus6 sein4du -sei3n2e +2sei3ne +seine3i +4seinfl sein4fo 2seing -2seinh -4seink +2s3einh +2seini +2seink 2seinl 2seinn +sein4ne 2seinr s4eins. -4seinsa +4seinsc 4seinsp -4seinst +sein8stit +sein6str +2seint +4seintr 2seinw +2s3einz 2s1eis +3s2eism 5s2eit +seits1 3sek -4s1e2ke +4s1e2kel +4sekz s2el. se2l1a -se3lad -sela4g -se3lam -3selb +3s2elb +sel3d4 sel1ec +se2lef +2s3e2leg +6selektr 2selem -se4lerl +se2ler sel3ers 2self. -s1elix -3selk +selin4s +s1e2lit +2s1elix +s2ell sel3le -se2l3ö +se2lob s2els sel3sz -sel3tr -s4e3ma -2s1emp -s2en. -se4nag +selt2e +selz2 +sem2e +2s1e2mis +2s3emp +s4en. +se4nad +se3nal +se4nas +sen3au se2nä +s2enb 3sendet 4s1endl +sen3d4r +2s1endw +senen1 +4senerg +se4ners +s2enf 5seni +se2nid +se2n1im +sen6keli 3senku se2no -s2ens -s2ent. -sen3ta +se4nott +se4noz +s2ensa +sen4s3e4h +4sensem +sen4si4d +s2enso +senst2 +sen8s7turm +sent2a +sen3tan +sen3tä +2sentd 2sentf -4s3entg -s2enti +4sentg +4sentn +s2ento +sen3tr 2s1ents 2sentw 2sentz -se2n3u +se4n3u2 3senva +sen3za +sen4zer +sen3zw +5seo seo2r -4s1e2pos -3seq +se2pen +5seq s4er. -ser3a2d -se2r3al -s3ereig +se2r3a2d +ser3al +se3rand +ser3äus +serb2 +s3erbe. +serd2 +se2r1e2b +se3reie se4r3eim +se4rein +sere2m +s4eren se4r3enk -ser2er +s4erfe s1erfo s2erfr s3erfü -4ser4fül +4serfül +ser3g2a s1ergä -s4ergr +ser3gl +s2ergr s1erh 5serie serk4 -s3erken -s1erkl 3serl. +4s3ermit s2ern. -s1ernä +2s1ernä +s3erneu 4s3ernt -se1rot -s3eröf +sero4b +s1e2ros +s1erot +s1erö s2ers. 2sersa -sers2t -s4ert. -seru2 -se4r1uf -se3rum -se3rund -3s4erv +ser6sehn +4ser4set +se3ru +se4ruh +ser2um +s3e4rup +3s4er3v +s1erz +s4es. +se3s2a se2sel 2sesh se3sk +s1essa +sest3ri se3su -2se4tap +2s1e4tap se2tat -s1e2th +2s1e2th +set2i +2s1e2tik +set1s +se3tun +3sety 3setz +3seuc +4s3eul se1u2n -2s1ex +s1ex +5sex. +2sexa se2xe +sex3en +s2exi +s2exo 4sexp -sex3t2 +sex3t4r +2sexz 6s3f4 sfal6l5er -sflo4 -4s3g2 -sges2 +4s3g4 +sgang4 +sge3s2 sgro3 2s1h 4sh. sh2a -3s2ha. -sha2k -4s3han +3sha. +shal4li +shalt2 +shalt4s +4shan 4shc -s3h2e +sh2e +1shen +4shf +sh2i 3shi. -3shid -4shil -shi4r +1shid +s4hig +s2hip +s2hi4r 4shk sh3n +4shoc 4shof +4shom 3shop sho4re -3show -sh4r +5show +4s3hö +sh4r2 4shs 4sht +s3hu 4s3hü 1si +3si. si3ach. -si2ad -si3am. +sial5l sia4s 2siat -sib4 5si1c +si2cha +2s1idea +2sidee 2s1ideo -s2ido +si3der +s2i3do +2sidy 3s4ie +sie2bu siege4s -sieh1 -sie4hes si3ene si1err si1f4 si2g1a -3sigh +si2g1ei sig4n -si3gnu si2g3r +sigs2 si2k1ab si2kak +si2kar si2k1ä +si2k1el +si4kens sik3erl -si2ki -si4k1l -si2kr +si2k3i +sikin1 +si2k3n +si2k3r sik3s2 -sik3t4 +3sik3t2 si2ku sil2br +sil2e +3sili +s1ill 3silo 2s1imm +sim2st +3simu si3n4a 2s1ind 2s1inf +4sinfe sing1a -sin3gl -sing4le -sin4gr -sing3sa +sin3g4le +sin2g3r +sing3s2 2s1inh -sin1i1 -4s1inq +s1in1i1 +s2ink +sinner4 +2s1inno +2s1inq 2s1ins -s2ins. -4sinso -4sinst 2s1int -4s1inv +2s1inv 3sio +sirn4 +2sirr 3siru 3sis si2sa +si4sam si4schu -si2s1e -si2s1o -si2s1p +si2s1e2 +si2si +si4sis +s1i2so +sis1or +si2s3p sis3s2 +5s2ist +si4star +si3sto si2stu -3s2it +si2su +3sit +si2tal si2tau -sit3r si2tra -si3tu -siv1a +s2it2u +3siu +si2va sive3 -si2vr +siver2 +si4v3erf +si2vin +siv1o4 +si2vor +siz2 1sí 4s3j 2s1k2 4sk. +sk4a +4s3kab +s3kad 1skala -4skam -4skanz -4skas +4skalk +s3kalt +4s3kam +4skana +4s3kanä +3skanda +4skann +4skap +4s3kar +4s3kas ska4te. 4skateg ska4tes -4skä +ska4to +4skau +4s3kä 4skb -s2kep +ske2li +4sken +3skep +4sker +4s3ket +s3kh 3s2ki. -s2kif -s2kig +3s2kif 3s2kik -4skir +s3kim +s3kin +s2kis. 3skiz sk4l 4s3klas 3s2klav +4s3klu 4sk4n +4skoh +4skol 4skom -4skor +4skon +3skop. +sko2pr +4skos 4skow -4skö +4s3kö +sk4r +4s3kra +4skro 4sks -4sk3t +4sk3t2 +skto2 3skulp -skus3 +4skun +sku2s3 +4skü +4skv 2s1l2 4sl. +s3lab 3slal -4slan +sla2ma +4slar sla2ve s2law sl3b -s5le +4s5le s3li 3s4lip 4sln -s3lo. slo3be -s3loe +s3loc +s4loga +3s2low s3lu -4s3m2 +s3ly +4s3m4 +sma3b4 +sma3sc +smas4p +sme3na +smi2t3 2s3n2 -4s5na snab4 +sni4a sni3er. sni3ers 4s5not -4snö +s5ny 3so. -so4a +2s3oas 2s1o2b +3s2o3ba +4sobj +4s3obo +so1ch +so2di +so2do so3et +s1o2fe 3soft 3sog +sog4l s1o2he -6sohng +3sohl +sohle2 +2s3ohng 2s1ohr +3soi2 +so3id +2s3ok 1sol +3sol. so3la +so4lau +3sold +3sole so2l1ei -sol2la4 +so3li +sol2la2 sol4ler -2so2ly -3som +so3l2o +4s3o2ly +1somm 3s2on +son2a son3au sone2 -son3end +son4gl son3sä son2s1o so3o -2s1opf -3sor. -s1orc +s1op +2sope +2sopf +3sopr 2s1ord +sore2 so2rei -so3ren +so2rel 2s1orga -5s2orge +1sorge +so1rh 2s1o2rie so2ro -3sors +3sorp +3s2orti so4ru -3so3s2 -s4os. -4s1ost -3soß -1sou +1so3s2 +3s2os. +3sosc +so4sk +2sosm +2sost +so4sth +s1o4sz +3so3ß +2sot +so3t2h +3sott +soun2 +sound1 +so3unds so3unt +2s1out 3sov -4s1o2ve 3sow -2s1ox -5soz -sö2f +2s1o2x +3soz +s1oze +2s1ö2d +2sö2f 2s1ök -s1ö2l -s1ö4s +2s1öl +2s1ö4s sp2 2sp. 2spaa +s2pace +2spack +2spag +spa2ge 2spak 2spala -spani7er. +2spalä +3spalt +spa2m +1span +s2pan. +3spannu 2spano +s2pans +3spant +2spanz 4spap 2s3para 1spare 2sparo +1sparr 5s6parten -3sparu +4spartn +spas2 spa3sse -spa3ssi -3s2paß +spa5ssi +1spat. +2spati +2spatr 2spau -s2paz +3s2paz s2pä +2späd +3späh 2spär +2späs 2spe. -2s3pel +2speg +1spei +4spein 4spensi spe3p4 s2pera +3sperb +3s2perg +s1peri +4sperle 2spero s2perr +sper4ra 2spers 4spet -1s2pez -2s3pf -2spha +3s4pez +2s3pf4 +4spha +s2phä +3sphär s3phe 1spi -3s2pi4e -4s3pier4 +3spi4e +4s3pier +spier4r spi2k -4spil -3spio -4spip -4spis +4s3pil +2s3pip +4s3pis 3s2pit 3s2piz 2spl 4spla -4splä +4s3plä 3s2pli -s3p4lu +4s3p4lu s3pn 2spod -2spog +4spoe s2poi -2spok +2s3pok 4spol 1spon +s2pons +4spoo +2spop 1spor -2s3pos -s2pott +s2pore +3s2porn +4s3pos +4spote 4spr. -s2prac +3s2prac +2sprak s2pran 2sprax 2spräm -4spräs -3s4prec +s2prän +2spräs +3sprec 2spred -s2pren -2spres +5s2pren +2s3pres +3spring +4sprinz s2prit -2sprob +4sprob +4sprod +2sprog +4sproj 2sprop 5spross -1spru +2sprot +2sproz +3sprö +3s2pru +3sprüc 2sprüf -3sprün +1sprün 2s3ps -2spt +2sp3t +2spub +2spud 1spuk -2spup +3s2pule +s3pun +4spup 3spur -4sput +spu4rer 1spü -4spy +2spy 2s1q 4s3r4 sra4s3s srat2s -srat4sc -sret3 +sre3cha +sro2h +sro3tu srö2s -srös1c srücker6 2s1s 6ss. 4ssa +s3saba +ss3abi ssa3bo +s5sack ss2ad -ss1aj -s3sal -s4s1alb -s4s3amt -s5sand -s4s3ang -s2sano +ss4agi +s2s1aj +ss3alba +s2sall +s4samt +s2sanf +s4sang +s4sano s4sans ss2ant s4sanz -s3sas -ss3att +ss2ara +ss2arg +s3sars +s2s3att +ssau3e +ssau4r 4s3s2ä 4ssb 6ssc +s2sce ssch2 +sschanker8 +s2scr 4ssd +sse3a 4ss1ec 4ssee +sse1ec +4ssef 4sseg -s4s1ega 4sseh +sseh2a 4ssei -sse3inf -sse3in4t +s2sein +ss4eind +sse3int 4ssek +4sselek +sse2lö +4ssemp 6ssendet 4s3sendu +6ssenerg +ssen6kel ssenmas6 +ssen6sem +4ssentl +4ssents 4ssentz -sse6r5att -s2s1erö +ss1epe +sse6ratt +ss5ereig +ss4ergr +sser4hö +sser6mit +s2serö +sser4öf 4ss3erse -ss2es +ss4eru +sser6wei 4ssesc 3ssesh +sses4sa +4ss3e4str +4sset sse3ta +s3seth 4ssez 4ssf 4ssg 4ssh +ss3hi 4ssic -4ssie -s2sig -s4sind -s4sinf -s4sint -4ssio +ss3i2ko +s2simp +6ssio +ss1isr 4ssit +4ssj 4ssk s3skala 4s4s3l 4ssm +ssmut2 4ssn 4sso ss1off ssoi4 -s2s1op -ss1ori -s2söl +s3sol +s4sop +4ssö 4ssp -s3spe ss2pen -ss2po -s3spru +ss2phi +s3sprä +s3spri ssquet4 4ssr -4s4s3s2 +4s4s3s4 +sssau4 4sst sst2a s5stad -ss2tar -ss1te +s6stag +s3stä +ss1t2e s4ste. s5stel -s4sten +s5s2tep +s5stern s4stes s4stet s5steu -ss2th -ss2tip +sst2i +sst3in ss1tis -ss2top -s3strec -ss2tur -s3s2tü +s5stop +ss1tor +s3s4trat +s3strö +s3stü 4ssum -ss1ums +s2sumg +s2sumr +4ssunt 4ssup +ss2ur +s3sus 4ssü 4ssv 4ssw @@ -12661,552 +20005,824 @@ ss1ums 4ssz 1st 6st. -s4ta. -3staa +3s4ta. +5staa +5stab. 2stabb +4stabel +2stabg 2stabh -s2tabi +4stabit +2stabl +2stabn 2stabt 2stabz st2ac -3s2tad -4stada -4stadr +s2tad +2stada 3staff 2stag +3s2tagr 3stah 2stak -2stal. -2stale -3sta3li +2stala +sta3lak +2stalb +2stalg +3sta3l2i 2stalk -st1alm st1alp +st1alr 3stam -st1a2mi +st1ami +stam4ma +4stampl 4stamt -sta4na -3stand +2stanb +3s2tand 4stanf +6stangeh +4stanh 4stanl -4stann +4st1ann +st3ansp +4stanst +3stant +4stantr 2stanw 4stanza +sta3po +2st1app s2tar. -s2tars -3start -st1asi -3stat -2stat. -5statu -s4tau. +sta6rens +s2t2ars +s4tart +2stasc +sta4sie +stast4 +2statb +7s2tati +7statth +7statu 2stauf -2staum 5staur 2staus +st1a2ve 2stax -3stä -4stäg -4stält -4stämt -s2tär -5stätt -4stäus +3stäb +3städ +2stäg +2stält +2stämt +3ständ +4stäp +5s2tär +3stätt +2stäus 4stb 2st3c 4std 3ste +4steam s2tean 4stechn -4stee -ste2gr -ste4i +ste2d +st1edi +ste2g3r +s2teh +4stehr +st4ei. +4steic 4st1eid -5s2teig -4s3teil -steil4z +5s4teig +stei4gr +4steil +s3teilc stei4na -s2t2el -s3telem -5stell -stel4l3ä +6steinga +6steinhe +stein6sp +s2tel +st1elb +s3tele +st2ell +stel6l5än ste4mar +ste6ment +6stemper 4stempf ste4na 4st3ends +st2ens 4stentf +4stentl +4stents 4stentw 4stepi -st5erbie -ste4rec -ste6rers +st1e2po +ste2r3a +s2terb +4sterbs +6stereig +s2terf st3erfü st2erg -st5ergeb +s2terh +s2terj +s2terk sterma7sse s2tern 6sterras s2ters +ster4zo +ste4s1e stes3ta -ste4stä +4stestb +4stestn 4stests +4steta +ste4tab +ste4tag s2teu 4steuf -4st3ev +st3eun +st1ev 4stex +s2texa 4stf 2stg -4sth +2sth +st2hen +st1hi st3ho -5s2tic -3stie +st1hy +st1i2d 4stief. -3stim -2stinb -2stinf -2st1ins +4stiefl +5s4tiel +5stif +sti4gel +st2il +3stimm +4stimma +2stimp +2st1inb +4stinf +3sting +4stinh +2stins +4stint s4tio +2stip. +4stipps sti2r -st3i2so +st1ira +st1iri +st1iro +2stite 2stj 2stk 4stl 4stm stma3s2 2stn -2stob -3stoc -sto3d +sto2bl +4stocht s2tode -s2tof +3s2tof stoffen6 stof8fens -2st3om +6stoffiz +sto3mi +2stomn +2ston +4stona +3s2to4ne +4stonl 2stope 2stopo 2stord +2storf 2storg s2tory -3stos 4stou -2stöch +4stöch 2stöl -2stön 5s2tör +2stöst 2stöt 4stp 2stq -3s2traf +st4rade +stra4fa 2strag -3strah -4strai +s2trah +2strai 3s2tral 4strans 3s2tras 3straß 4straum -s2träf +2sträc 2s3träg -s2trän 4sträne 2stre. 4strech -4stred -4stref -4streg -s3treib -3st4reif -4streis -st3renn +2stref +2streg +4streib +5st6reif 2strep 2stret 2strev -2stri. 3s4tria 2strib 4strig -stri2k 4strisi -2stroc +4stroc 3s2trof +3s2troh 3s2trok -st3roll -stro4ma +4stropf +3s4tropo +st4ross +4strost +3stroy 2ströp -4ströt +2strub 3struk -2st3run +s2trum +2strun 2strup +2strut 4st3s2 stsas2 -sts4k +stsi4d +sts4p 2st3t4 st2u -5s2tub -4stuc +3stub +4stuch 3stud 2stue 3stuf -5stuh +2stug +st3uga +3stuh 2stuk +2stumo 2stumr -stum2s +2stum2s +s3tumsc +2stumt 2stumz -stu2n 2stun. +2st3una +2stune 2stunf 2st3uni 2stuns 2stunt 3stuö -stu3re -st3url +stu3ra +stu5re +2st3url 2s3turn 2st3urt +3s2turz 4stüch -s4tück +3s2tück +3stüh 2stür. 2stüre 2stürg 2stürs +2stürw +2stütc 2stv 2stw -2sty. -2stys -4st3z -1su. +stwor2 +2sty +4sty. +4styp +4stys +2st3z2 su1an 3su2b3 -su4ba2 +su4ba 4subi +su4br +subs4 5su1c su2cha -such4st +su2cho +3sud +su2eb 2s1u2f -4s1uh +su3fi +2s1uh +1sui su1is su1it. -sul2a -sul2i -sult2 +su2k +su3l2i +sum1a +su2man su2mar -su2mau 3s2ume -su2m1el -su6m5ents -s3umfa -s3umfe -3summ +su2mei +su2mel +sument4 +su6ments +su2m1et +2s3umf +su2m1id +su2min +3s2umm sum1o2 su2mor s2ump +s1ums s3umsa -s3umst +2sumse +s2umsp +2s3umst +2s3umwa su2n +2s1una sunder4 sun6d5erh su4ne -s1unf -s3ungl -2s1uni -4sunt -3s2up +4s1unf +6sungena +2s3ungl +4s1uni +2s1unm +s1uns +2sunt +3sup +4supd sup3p4 su2ra -2s1url +sure4 +su2rei +su2rer +3surf +2s1urk +s1url +su2r1o s1urt +su2s +su3s2a sus1e -su2sp -sus3s -2sü2b +sus3i +s3u2t +su3tr +suz2 +2sü4b 3süc sü2d1 -süden2 +süden4 sü3den. +1süf 3sün 1süs4 sü3sse sü3ssi 1süß -4s3v -2s1w -s3we +4s3v2 +svoran4 +2s3w +swe6gers sweh2 +swe5s 4swie 4swil -s3wö -s3wu +4swink +4swis +4swit 1s2y -syl1 +2syl1 +sy2lo +sy2lu sym3 sy2n3 -sy4na -sy4nä -sy5s +3synd +sy4no +3sys 2s1z2 4s3za 4szä 4s3zei -s2zena -5s2zene -4s3zent +4szel +3s2zena +3s2ze3n2e +4szent +4szer s2zes s2zeß -s3zet -s2zis +s4zew +4s3zie +s3zins +4s3zo +s3zs sz3ta 4s3zu -4s3zw -2ß3a2 -ß1ä -2ß1b2 +4szü +4szw +4szy +2ß3a4 +ßan1 +ßat3 +2ß1ä +2ß1b4 ßbus3 2ß1c 2ß1d4 -ßdie3 1ße +2ß1e2b 2ß1ec +2ß1ef 2ß1e2g 2ß1ei -ße2l1a -ße2le +2ß1ek +ße2l +2ßelek +ße3lu +2ß1emp +ße4n3a4 +4ßenerg ße2ni +ß1enke ße2no +3ß2en3te 2ßentz -ß2ers. -2ßerse +ße2nu +2ß1e2p +3ß2er. +ßer3b +ßer2ei +ßer2la +ße2ro +2ß1erse ßer3t +ß1erw ße2s +2ß1es2s +2ß1est3r ße2t -ß1ex -2ß1f +2ß1ex +2ß1f4 2ß3g2 ßge2bl -2ß1h2 +2ß1h 1ßi ßi2g1a +2ß3i2k +2ß1il +2ß1im 2ß1in ß1j -2ß1k4 +2ß3k4 2ß1l2 -2ß1m -2ß1n2 -ß1o2 -ß1ö +2ß1m2 +ßmut2 +2ß3n2 +2ß3o4 +ß1ö4 2ß1p2 2ß1q ßquet2 4ß3r2 +ßrö2 ßrus3 -2ß3s2 +2ß3s4 +ßsau4 ßsch2 -ßst2 2ß1t -ß2th +ßt1h +ßt1in ßts2 1ßu2 ß1uf 2ß1uh 2ß1um +ß2ung ß1uni -ß1ü +2ßunt +ß1ü4 2ß1v 2ß1w -2ß1z2 +2ß3z2 +2taa 2tab. -ta2b1an +3taba +ta2b3an 2t1abb +4tabd 1tabel -2taben -ta4bend 2tabf 2tabg 2tabh +2t3a2bit 2tabk -1t6able +2tabla +1table +4tabm 2t3abn -ta2br +2ta4br 4tabs +t1abst 2t3abt -ta2bü -2tabw -2tabz +3tabu +4tabw +4tabz 2t1ac +t2ache 3tacu t1ada +2tadd +ta2der tadi3 +tadi5o4 +tadi4s +t1adm +ta2dol 2t1a2dr ta3d2s -1taf2e -2taff +ta2er +1tafe +2tafet t1afg -t1af4r -1t2ag -3tag. +t1afr +1tag ta2ga -ta2g1ei -4t3a4gent +ta2g1e2i +4t3agent +tage2s +2t1agg ta3gl -t3ago -tag2s +2t1a2go +tag2s1 +tag4san tag4st -tah2li -tahl3sk +2tah2 +3tai ta3i2k -tai2l +tai2l1 ta1ins tai4r ta1ir. +ta1i2s 1tak -t3a2ka +2t1a2ka +ta3kes +2t1akk ta2kro -tak2ta -3taktb -3takts -3t2aktu +2taks +tak2t1o2 +t2aktu 2takz 3t2al. ta2la +ta3lad ta3lag -ta3lak tal3au -t1alb. -t1albk +1talbr 1talbu -tal3d -1t4ale +tald4 +1tale tal2en -ta4lens +ta4l3end +tal3eng +ta4l3ens +taler2 +ta4ler3g +ta2let tal2ga +tali6ene +tal4l3ac tal4leg tal4lei tal4let tal6leut -tallin6s +tal6lin6s +tal4los +tall2ö +tall3s tal4lus -ta2l1op -tal2se -2talt +2t1alm. +ta2lop +ta2l1o2r +t1al3ta +tal3th +talt4r +ta2lu 2tam -ta2mer +3t2am. +t2amen +t1a2mer +ta2mi tam2ma2 +tam4m3er tam4mi tam4mut t1ampl -t1amt +3t2ams +4t1amt t1a2na -2tanb -t2and -tand4ar -ta3ne +tan3ab +4tanal +ta4nat +2t1a2nä +tan3d4ar +tan2dr +ta4nerf 4tanf 2tang -t2ank -t3ankl -2tanl +tan4gra +2tanh +t2anho +t4ani +3tanj +1t2ank +tan2kl +4t3anl t1anm -2tanme -4t1anna +2t1anna +3t2anne +t1ano +2tanom t1ans t2ans. -4t3ansi -2t3ansp +4tansi +tan4tan +t4ante. +4tantei +2tantr +tanu4 2tanwa 2tanwä t2anz. t1anza 4tanzei -tan6zerh +3tanzk +3tanzr t1anzu tan2z1w +tao2 ta3or -ta2pe. +t4ape ta2pes 2tapf ta2pl -2tappa +ta4poka t2appe +ta2ra +2tarab +3tarabb +ta3rak +3tar5al +2taram +tar3ap +ta3ras +t2arau 2tarb -ta4ren4s -ta4r3ere -3t4ari +3tarba +3tarbek +3tarber +3tarbi +3tar3bl +2tarc +3tarchl +3tarchr +t2ard +ta2rel +ta2r1er +tar3g +ta1r2h +3tari 2tark +3tark4l +3t2arko +t2arl 2t1arm +t2armä +ta2rom +2tarot 2tart -tar2ta +3t2arta +3tartei +tar6ter6e +3tartex +3t2arth t1arti +3t4artis tar2to +tar2tr +3tarty ta2ru -2t1arz -ta3sa +t1arz +2tarzt +t2as. +ta3s2a 1tasc -t1asp -1tas2t +4t1asp +2t3assi +1tast +ta4stem +ta2sto ta3str -1tat. +t2asy +t4at. ta2ta2b ta2tan -ta2tau +3tatb +t4ate tat1ei +t5a2tel ta2tem +1taten ta2t1er -ta2th -tat3he -t3atl -t4atm -ta2tom -1tats -ta2t1um -4taud +2t3atl +2tatom +2ta2tr +1tatsa +2tatt +tau2b1a +1taubh +tau2bl +tau2b3r +tauchs4 +tauch5sp +2taud t1auf -4taufg +3taufe. tau3f4li -4taufn -2taufw +4taufm +2taufn +t3au2f1o +4taufp +taufs2 +4taufw 1taug +4t3auge t1auk 3taum +4tauma +1taume 1taus -2taus. -t1ausb +4t1ausb +tau6scha +tau6schm tau6schr tau6schw -t2ause +2tausd +t2aus2e +2t1ausf t3ausg t1ausk 2tausl +2tausr 2t3auss -4t1ausw -1tax -ta3xi +2t5ausw +2tausz +ta2van +3tax taxi3s -3täa +4t1axt +2tää +2täb tä1c 2täd -3täe +t2äf 1täg 2tägy 2täh +3täle +2täll 2t1ält -2täm +2tä2m t1ämt t1ängs 1tänz -t1äp -t2är. +2t1äp +2täq +tä4reng tä2ru +2tärz tä2s t2ät -2tätt +3tätigk +4tätt 2täug 1täus 2täuß 2täx 1tà -4t3b2 +4t3b4 tbauer4 -tbe3r2e -tblock5e +tber2e tblocken8 tbus3 2t1c @@ -13214,563 +20830,852 @@ t3cha t3che tch2i tch3l +t3chr t2ch1u tch1w t3cl +tcor2 t3cr -2t3d4 +4t3d4 +tdar2m1 tdun2 -1te2a4 +1te2a2 +te3ab +tea3c +te3ag +2teak te3al -teamma5 +teamma3 te3an -3t4ebb -4t1e2ben -1t2ech -te1cha -3techn +te3ar +tea4s +3teba +t4ebb +2t1e2ben +t2ech +1techn te2chu 2teck -teck2e -te2de +t1ecu +te2dit 1tee te1em -te2en3 +teen1 +te2er. te1erw te2es +3tefa 2teff 2t1egg -teg3re -2teh +te2hac +2tehe +te2him +2t1ehr +te3hu +1teic +tei1fl 2teign teik4 -1teil +1t2eil +tei6lent +teim2 2tein -tein3ec -t3einge -t3einla -4teinn -t1eis. +teinbus6 +teinen4 +tei6nens +tein6hab +t3einkü +2t1eis. t1eisb -tei3st +tei3sc +te5isch. +teit4 +t1eiw +tei3z te2kel -tek3t2 -tela4 -te2l3ab -te2l1ac -te2l1au +3teko +tek3t4 +te2la +tel3ab +tel1ac +te3lan +te4lant +tel1au +te2lä telb4 tel3d4 -te3le -tel1eb -tele4be -te4l1ec -3telef -3teleg -te4l1eh -te4lein +tel1ec +1telef +1teleg +tel3ehr 2telem -te4lerd -te4leu +tel3eng +te2ler +te2leu 4t3elf. +te4lim te2l1in te2lit -tel3lau -tel3lä -tel3l2e +tel3le tel6lein +tel3li tel6li6st +te2lob +te3lom te4lost te2l1ö tel3s2k tel3ta -tel3th -tel3t4r -te3mä +telt4r +t2ema +te2man +te2m1ap +te2mau +2tem2bo te2m1ei -te2min -2temo -te2m1o2r +te2m1er +2temg +2te2mi +tem3i2m +tem3ing +2teml +2temn +2te2mo +tem1o2r 3temper +2tempf 1tempo -te4m1u +tems2 +te2mu +te4mun t6en. -tena2b -te4n3a2d -te4n3a4g +ten1a2 +te4nad +te4n3an +ten3ar te4nas -te4n3au -te2nä -ten3äh -t4enb +te4nat +ten3au +te2n3ä4 ten3da -4t3endf -t6endi +t3endal +tend4an +4tendap +2t5endf 2t1endl t6endo -4t3endp +2t5endp ten3d4r te2n1e2b te2nef +te2neh ten3ei te3n4ei. -4tenerg -te2net -4t1eng. -ten4gag +tenei4d +tene4m +tenen1 +te4n3end +te4nene +te4neng +te4nens +4t3energ +te4n3ern +tenf4 +t1eng. +teng2a +4ten4gag t3engla -t4enh te2ni +te4nil +ten1im te4n3in -t4enj -t2enk -t2enl -t4enm -ten3n -t2eno -t2ens -tens2e -4tensem -t4enta +tenk4 +ten3n2 +te2nol +te2nos +te3nö +4t3ensem +1tenso +tens2p +t2enta t1entb 2tentd -t4ente -4tentn -ten4t3ri -4t3entw -4tentz +2t3entl +2t3entn +ten6tric +t1ents +4t5entw +2tentz +te2nu t2enz -ten6zerh -ten3zw -t1e2pi -t6er. +ten4z3er +teo2f +2t1e2pi +tept2 +t4er. +t4era ter3ac -te1raf -ter3am -te3ran. -te3rand -ter3as -4terbs -4terbt +te2rad +te1ral +ter3alg +te3r4ane +te2r3ap +2t1erbs +2t1erbt 4t3erde. -te2re2b -te4r3eif -te2rel -ter3end +ter3d2s +te2r1e2b +te2rec +t3ereig +te5rek +tere2m +te4rema +te4r3end +te4rene te4reng -te4rerk -terer4z -4t3erfol +te4r3ent +teren5th +terer3k +terer6ku +terer3l +te4r3erp +te4rers +te4rerw t4erfr -4terfül terg2 ter3ga -6ter6grei +6tergebn +t6ergem +t6erges +t6ergew +ter3gl +6tergrei t4ergru 2t1ergu -4tergü -t4eri +2tergü +t6erhall +t6erhau +t4erhäu +t4erhei +t2erhi +t2erho +6terhöhu +t2erhu te3ria -te2rid -ter3k +4terii +ter3iko +teri4o +te2r3it +teri4ta 4terklä -2t3erlö -1term +t4erlä +t4erli +ter4lös termas4 -ter4mer -ter4n3ar -4t3erneu +1termi +t2ern. +ter4nar +t6ernc t4ero -t1erö +te1rob +ter4obe +2teros +t1e2r1ö +t4erp +t4erra 3terras ter4re. -1terro +t4erro t4ers. -ter3sc -ter4ser -terst4 +t2erse t4erst. +t6erstad +ter6stat +t4erstä t4ersti +t4erstr t4erstu -tert4a -tert2o -teru2 +t4erstü +ter3t4a +ter4trä +t4eru2 te4r1uf -ter3za +te3rung +t4erv +4t3erwäh +ter3z2a 2t1erzb -t2erzu +t4erzei +4terzeu +ter3zw te2s -tes1ac +t2es. +tesa2k te3sä -t1esel -tes1er +te3sc +tes3eli +te3ser te3si te3so te3sp +tes1pe +te4sper te4spr -3tesse. -t2es2t +2t1essa +tes3si +tes2t tes3tät -te4st3ei +1testb tester4 te6sterg +te6st5erh te6sterk -testes4 +te3sto +tes3tra +t3est3ri 1tests -t2et. +t1eta +te4tabl +2te2tap te2tat +teten3 +2t1e2th +te3tho 4tetl 3teuf -te1un -teu2r3a4 +te1u2n +2t1eup +te2va te2vi +tewa2s +3tewo 1tex -te1xa -t1e2xe +2texam +2t1e2xe 2t1e2xi 4texp -3text +tex4ta 2t1exz -2t1f4 +tè2 +2t3f6 tfäs3 -tfi2l -2t1g2 -tger2 +4t1g2 +tga4s3er +tga4su +t3ge +tge4nen3 +tger2a +tger2i +tg4r tgro3 -t1h 4th. -2th2a -3t4ha. -t2hag -t3hai -t2hak +2t1h2a +3tha. +3t2hag +4thak 3thal. +3thalh +t4hali +1t2hals +t2han. +t3hand +t3hap 4t3hau -2t3hä +2t1hä +3thäi +4thäl +2thb 4thc 1th2e -t2he. -3thea -2theb -t2hec -2t3hei -t4hein +3t4hea +2t1heb +2t1hef +2t1hei +the1in +4theit t2hek -t2hem -t4hene -t4heni +2themd +2themm +t1henn 3theo -2therr -t2hes -3these +t1herd +thero1 +2t1herr +2t1herz +4t1hess t2heu -1thi. -thi3er -t2hik -2t3hil -2t3him -t3hir +2thf +th2i +3thi. +thic3k4 +thi3er. +2t1hil +2t1him +2t1hin +thi3nu +2t1hir 2thk -4th3l -4th3m -2th3n -t2ho -t4ho. -2t3hoc -t3hof -2t3hoh -t4hol. -t4holo -t3hor -2t3hot -thou2 -2thov -2t3hö +2th3l +4th3m2 +thmu2 +2th3n2 +2t1hob +tho3chr +t1hof +2t1hoh +t1holt +2tholz +t2hon +4thops +t1hose +t1hot +4thote +2thou +t1hov +2thö 2thp 1th2r2 2ths +2tht2 +t1hu 2thub -4thun -2thü +2thuh +4t3hun +2thut +2t1hü 2thv -t2hy -ti2ad -ti3a2m -tib4 +t4ia +ti3ac +ti1ag +tial2l +ti3alo +ti1a2m ti1ce ti3chr -tiden2 -ti4dend -t2ie +3ticket +t2id. +2tidee +ti4d3en4d +ti3dy 1tief. +4tiefel +1tiefl tie2fr +tieg4 +ti2e1i ti1el ti2el. tiel3a -ti3e4n1 -tie4rec +ti3e2n1 +tie4rei +tie4reu +tiermas6 ti2ern 1tierr -2tieß -ti1et +tie5sse ti1eu -1tif. +ti3fe tif3f -ti1fr -t4ig +ti1f4r +tifter6k ti4gerz +ti2git +tih2 tihi4 ti2kam ti2kar +tiken2 +ti4kent +ti3k4ere +ti3kerl ti2kin +ti4klu +ti2kn +ti2k1op +tik1r ti2kra ti2krä +ti4krei tiks2 -ti2kü ti2lar -ti2lau +til3d ti2lei ti2lel 1tilg +3tilgu tille4b -ti2l3ö +2tillu +ti2lö tilt4 ti2lu ti2ma2g -t2imi -tim2ma2 -4t1imp -t2in. -ti3na -t1inb -4t1ind -ti3n2e -t1inf -tin2g1a +tim4man +tim6ma6te +timmer4 +tim6merg +tim4mit +2timp +t4ina +ti3naf +ti3nak +ti2n3an +t1ind +ti5n2e +tine1i +2t1inf +tin2ga ting3l -ting3s +ting3s2 +2t1inh +3tinis t1in1it -2t1inj +t1inka tin2k1l -t2ins. -4t1inse +tin2kn +tin2kr +t1inku +t2inn +ti2nor +t1ins +t3insa +t2insä +4t3inse +tin4spa +tin4sum t1int -ti1nu +3tinte. +ti3nu +tin2um 4t1inv 3tio -1tip -3tip. +ti2osk +tioxi3 +1tip. +ti3p4l +1tipp +3tips ti4que. +1tirad ti1rh -t2is -ti4scha +ti4ron +t2isc +ti6schei +tisch3l tisch3w ti2sei +ti3sk +t1isl +t1iso ti2sp +t1isr +ti3s2th +ti4s3tic +ti2su +2t1iß +t1it2a +ti2tal 3ti3te -tium2 +3tiu +tium4s ti2van -tive3 ti2vel ti4vene tiver2 +ti4verh +ti4verk ti4verl ti2v1o -ti2v3r +ti4v3r ti2za +ti2zir 2t1j -2t3k4 -2t3l +4t3k4 +2t3l2 +tlan2g tl4e -3tlem -tle2r3a +tlei6der +t4lep +tle2ra 4t5li -tli3ni -2t1m2 +tlings3 +tli5ni +tlit1 +t5lö +4t1m2 tmal2 -tmen4t3 +tmen8schl +tmen4t5 +tments4 tmo4des -t3mu -2t3n2 +2t3n4 t5na tnes4 +tni3v to4as to5a4t -1tob -2tobj +t2oba +4tobj tob2l t1obs +1tobt to1ch -t3ochs -3tocht +2t3ochs +1tocht 2tock -1tod +tock5ent +1t4od 3tod. -tode2 -to2d1er -tode4s1 -to2d1u +tod1er2 +to2dun +tof6f5ent +tof4f3er +2toffi +2t3ohr toi4r -to3la -tom1e2 -2tomg +tok4 +to3le +1toler +tomar4b +to4mene +3tomi +to2min +1tomo +to2m1u +to4mun 1ton -to2nau -to2neh +to2nan +ton3au +tond2 +to2n2eh +toner6ke +to2nob +2tony 3too +to2pad to2pak +to2pan +to3pas to2pat +t1ope +top1hi 1topo -2topt -to1ra -to2rau +2to4pt +t4or. +tora2g to4rän -2torc t1ord -to2r1el -t1org -t3orga +t2ordi +2t3ordn +t4ore +to2rei +to2rel +to2rem +to6renna +1torf +tor4fan +t1or3g +2torga +6t5orient +torin4s tor3int to2rö +1torp +t4ors 1tort -t1ort. -to2ru -t2orw +2t1ort. +tor3t2a +t1orth +4tortn +4tort4s +to4ru +to3rü +to4rüb to3s2 -to4sk -tost4 +to4s3ka +tost2 +to2tä 1toten to2tho -tots2 -3t4ou -touil4 +3t2ou +touil2 to3un +to1x tö2c 1töch -2töf -2t1ök -1tö4l +2töck +2t1ö2d +2tö2f +4t1ök +1töl +2töl. 1tön +t2ör t1ö4st 1töt -2t3p2 +2t3p4 tpf4 +tpi2n 2t1q t2r4 2tr. 1trac tra3cha -t3rad. +tra3chl +2t3rad. +2trade tra4dem +1tradi +t3radie +tra4fah tra4far -1trag +2traff +1t4rag +tra5gen 2trahm 3t4rai -tra4lin +2t3rake +t4rakt +tral3l 1tram -2t3rams 3t4ran. -2trand +4trand +2trang 1trank -t1rann -1trans -t3rase -t3rasi +t3rann +5t4rans +1trapp +tra4sta tra4str 2traß +t1raub +4traub. +4trauc +t4rauf 1traum 2traup traus2 -1trä -2träh -3träne -2träs -2träß -2träus -2träuß +1träc +2träd +1träg +1träne +2träng +2träuc +1träum 4t5re. -tre4ale +2trea +t3reak +2treb tre2br 2trec t3rech t4reck +3treck. 2t3red 1tref 2trefe -3t4reff +2trefl 2trefo 2treg +t3reh t4rei. 1t4reib 2treif -t3reig +2t3reig 2t3reih -t3rein +2treim +2t3rein 2t3reis +tre7isch. 2treit t3reiz -2t3rek +2trek 2t3rel t4rem t4ren. 1trend +1trenn t3rent -1trep 2trepe -2trepo -t4repr +2t3repo +1trepp +t3repr t4rer t4res. -1t4ret -tre2t3r -t5rett -t4reu +1tret +tre2ta +t4rete +tret3r +tre4tri +2t3rett 2t3rev +t4rex 2trez 3t4ré 2t3rh -1trib -3trieb. -3triebs -6trieg +3t4rib +t4rick +t4rid2 +1trieb +trie3fr +tri4ena tri2er -1trigg +tri4ers +2trig. +tri3gl +t4rik +tri4ke. +tri4kes +1triko +1tril 1trin t3rind 2tring tri3ni +t3rinn 3trio t4rip -t3riß -t4rit +2triß 1triu +2t3riv tri2x trizi1 +tro3b4 1troc 4trock. -t4roi -tro2ke +tro4kes +trol4la +2trom. +tro4men tro2mi -2t3roo +2tromk +tro3na t4rop tro1pe 3tropf -2troß -t3röc +tro5sm +1trost +t1rot. +2trout +4t3röc 2tröh 2tröm 1tröp -2trö4s3s +2t3rö4s3s 1tröt -2truf +1trub +2t3ruc +4truf 1trug 2truk trum2 +t3rumä trums1 -2t3rund -1t4runk +t3rund +1trunk 3t4rup -t3ruß +t3russ +2t3ruß +1trut1 tru2th trü1be trü1bu @@ -13780,150 +21685,255 @@ t4rüg 3trümm try1 2ts -t3s2ac +4ts. +ts3ab +t3sac +tsa3che +t4sachs t2sa2d -t2s1ah -ts1al -t4s1amt4 +ts1ahn +t2sall +t2salt +t4samp +t4s1amt t2san -ts3ar -ts1as -tsa3sse +ts3ane +tsa2r +ts3ari +t2s1a4s +tsa5ssen t2sau +ts2av t1sä t2säh -t2s1än -t4schar +ts1än +ts1äus +t2sce +t4scham +t6schart t3sche t4schef t3schl tsch4li +t3schra t4schro +t3schü ts2cor t2s1e2b -t3seil -t4seind -ts1em -tse2n1 -t2s1eng -t3sens +tse2e +t2sef +tse4he. +ts2eil +t3seme +ts1eng +t3s2ens t2s1ent +t2s1ep t2s1er t6s5essen -t3set -t4seth +tse2t +ts1eta +t2s1eti +t2s1e2v +t2sex +t3sexi +ts3he t2s1i2d +t2s3i2k +t2sim tsing4 -ts1ini -t2s1ir -t3skala -ts3kr -ts1o +t2sini +ts1ir +4tsk +t3skal +ts4kele +tski2 +t4s3ko +tsmas4s +tsma5sse +t1so +ts1off +t2sop tso2r -t1spal -t1span -ts1par -ts4pare -t1spas -ts2ped -t1spek +ts1orc +t2s1ori +ts3ort. +t3sos +ts3part +ts1pas +ts3pate +t1sped +t1s2pek +ts4pend ts2pi +t2s3pic +t4spins ts3ple ts2pon ts2por -ts3s2 -tst4 +ts2put +ts5s4 +4tst4 +t4stabe t2staf -ts2tat -ts2tau -ts3täti -t4stea +t4stale +t4s3tanz +t2stas +t4s3tat. +t4s3täti +t4stee t4s1tep t4sterm t4s3terr ts1tie +t3s2til +t3stim t2s1tis t2stit -t2ston -t4s3trad -t2strä -t2s1tri -ts2tro -t4strop -t2s1trü +t4stoch +t2stoi +t2stor +t4strac +t4strad +t3s4traf +t3strec +t4stren +ts4tric +t4strie +ts2tro2 +ts2tub +ts2tüm ts1u -1tsub +3tsubi +t2sumz +ts3un t1sü +tsü3s +tswa2s 4t1t tt1ab tt2ac -tta6gess -tt1ak -t4tals -tt3ank -t2tanz +tt3achs +tt1ad +tt2ag +tta6g5ess +t4t1ah +tta2ke +tt2al +t2tan +ttan4a +tt4anke +t3t2ant +t4t1ap tt1art +tt3atr +tt1äh t2tän tt1ebe +tt3echs tt1eif tt1ein -tt1eis -tte2la -tte4leb +t2t1eis +tte4l1a2 +tte4l3e4b t4te4leg tte4len ttel3l ttel1o -t3ter -tte4rec +t2temu +tte4na +ttens2 +tten6sem +t4tentb +tten3te +t4tentf +t4tents +tten3z +t2teo +t3t4ere tt2erg +tte4rik ttermas7s -tte4sa -tte4s1ä +tter3nä +tte2ro +tt2erö +tt4es +tte4s3a +tte4s3ä +tte4s1o +t3tess +ttest4r +t4teuf tt2häu -t2t3ho +tt1hi +t2t1ho +t2ti4d +t2t3igi +t2tins +tt2int +t2tiso +t4t5la t3to. +t2torg t3tos ttras3s -t3tro -tt3rü +t2trou +tt3rü1 +ttschi4 +tts1eh tt2sen tts1p +tt4s3tät tt4s3tem tt4ster -tt4sti +tt3s2z ttu2 +ttu3b t2tuc -tt2un +tt1uf +t4tunt t2tu4s ttü2 +tt3z2 +3tua +tu4ale tu1alm -tu3an +tu1alv +tu3ant tub2 tuba3b 1tuc tu2chi -1tue +tu1cho +tudie4n3 +3tue tu3en tu2ere 2tuf tuf2e tu3fen t3u2fer +3tuff tuf4fel +tu2gan +3tuge 2tuh -tu2is +tuh4ler +tu1ist t3u2kr -tul2a +tul2i 1tum -t2um. -t2ume -2t3umf +tum2b5l +4t3umf 2t3umg 2t1umh 2t3umk +2tuml +3t2umo 2tump 2t3umr +4t3umsat +2t1umsc tum2si tum2so 2t3umt @@ -13932,106 +21942,170 @@ t3umz 1tun. 2t1una 2t1und -t4une +tund2e +1tune +tun2en 2t3unf t3unga -tung6s 2tunif -2t1u2nio -1tunn -1tuns +2tu2nio +2tuniv +2t1unm +3tunn +t1u2no +t3uns +1tuns. 2t3unt -t1up. -tu2r1a4g +2t1unv +2t1up. +t1upg +tu2r1ag +tu2ran +turan4l +tu2ras +tu2rau tu2rä tur1c -tu2re. +tu2r1e2b tu2rei +tur3eis +tu4rene tu2r1er -tu2res -tu2r1e2t -turin1 +tu4res +tu2re2t +tu2r3e2v +tur3f4 +tur3g2 +tur1in1 +tur4mun 1turn -tu2ro -tur3s +tu2r3o +tur3s2 tu4ru tu2sa tu4schl +tu2se tu2so -tu3ta +tu3t2a +tuto5 +tuto3re 2tüb +tü3ber. 1tüch tück2s 1tüf +2tüh 1tür. tür1c 1türe 1türg 1türs -1tüten +1türw +2türz +1tütc +1tüte 2tütz -2t3v -4t3w -twa2 +4t1v2 +t3vo +tvoran4 +4t3w4 +t5wa2 twä4 +twegs2 twi4e +t4wist 1ty 3ty. +2t1ya 3typ -ty2pa +ty2p1a 3tys -4t1z -t2za4 +2t1z +t2za2 tz1ag -tz1al -tz1ar +tz3ar tz1au -tz1ä -t3ze. -t2z1ec +t2z1ä +t3zäh +tz1ec +t2z1e2d +tz1ehr t2z1eie -t2z1eis +t4z1eis +tze2m +tz1emi tze4n1 tz2ene -tz3ents -tz1erl -tz2ers -t3zes1 -tzes3t -tz1ind -t2zor -tz2ö +tzen3ta +t4zentg +t4zentl +t4zents +tzer6gre +tz1erw +tz2er3z +tz3erzi +tzes1 +tz1e2t +tz1i2d +tzi4m +tz1imi +tz1int +tz1inv +t2z3om +t2zop tz2th tz2tin +tzu2gu +t2zuni +tzwan4d3 tz1wä tz1wi +t3zwie tz1wu 2ua -u1a2b -u3a2c -uad4 +u3a2b +u1a2c +ua2dan +uad4r +u1a2g u1ah u1al. -ua2lau +u1a2l1a +u1a2l1ä u1alb -u3alet +u1ald +u3aleb +u3a4lent +u3aler2 +ua4lerg +ual3erk +u3a2let u1alf +u1alg +u1alh +u3a2lid ual3l ualle2 -u3a2lo +u1aln +ua2l1o2 +u1alp u1alr u1als -u1al3t +u1al3t4 ua2lu +u1alw u1alz -u3am +u1am +uan2a u1ans u3ar. uara2b u1ars -ua3sa +uar4t3an +ua3s2a ua2th uat2i +uat2o u3au uau2s u1ay @@ -14040,624 +22114,1018 @@ u1än uäs4 u1äu 2u1b -u8becken. -ub3ein -u3b4i -ubi3os. +u2barb +ubb4l +ube2be +ube2e +u2b1ehe +ub1ein +u2b1e2m +ube4n1a +uben3o +ub2er +u4b3erde +ubert4 +ub4es +ub1eul +u3bit ub2l +ub3läu ub3lic -u2b3lu +ub3lu +ub4lut +u2bob u2bop -ub3rä +u2boz u2b3rit +ub4rü ub2san +ubsau2 +ub6s3che ub2s1o -ub2spa -ubus3 -u2büb +ub2sp +ubst2 +ub4sz +ub3t2h +ubu3s 2uc uc1c -u1ce4 -uces3 uch1a u1cha. uch1ä u1che -u2ch1ec +uch1ec +u2ched uch1ei +ucherin8t ucherma8s u1chi -uch1il +uch3im uch1in uch3l uch3m uchma6ss uch3n +uch1op u2ch3r +uch4sel uch2so -uch4spr -uchst4 -uch4tor -uch2t3r +uch2sp +uchst2 +uch2ta +uch3tan +uch6t5erf +uch6t5ert u1chu u2chum uch3ü uch1w u1ci +uck3elf uck2er -uck3erl +ucker8geb +uck3i +uck4sti +uck3t u1cl 2u1d -u3d2a -uder2e +u3d4a +uda3d +ud2e +ude3i4 +udein7 +udel3se +uden1 +uden3e udert4 udi3en uditi4 +u3d2ob u2don ud3ra u3dru -2u1e +4u1e +ueb4l +ue1ch u2ed -ue2en +ue2en4 u2eg -u4ela -ue2le +u2eh +ue2ke +u2ela +ue2lek ueli4 uel2la +uel2lä +u3eln ue2mi uen1 +u3en. +ue4n3a2 ue2nä +u3end +uene2 +ue2neb ue2ner -uenge4 +uen4gag +uenge2 +uenge4m +uengene7 +uenge4s uen2gl u3e2ni +uenk4 ue2no -uen2sa +ue2nu +uen6zene uen2zu u2ep -ue2r3a +ue2r3a2 ue2r1ä +uerb2 uer6baut +uer3d2 uere2 ue2rec -ue3reig +u5ereinn +uer3eis +uer3ela u3eremp -u3erent -ue4rerg +u3e4r3ent +ue3r4erb +u3ererf +ue4rer4g +uerer4h +uerer4k +uerer4m +ue6rersc +uerer6sp +ue6rerst +uer3esk +ue2ret +u3erex uer3g2 +uer4geb u3erh -u3erinf +ueri2d +ue2r1i4m u3erin4t +u3erl. uerma6s +u3ern uer4nan -uer2ne -uer4ner -uer3o +uer4nar +uer4ne +ue2r3o4 uer2ö -u3err +uer3r +u3errü uer3sc +uerst6 uer3t2 +u3eruh u3erum u3erunf u3erunt -u3erur +uer3z2 ue4s ue5se ue5sp ue2ta ue4tek +ue2tik +uety2 +u2ev +ue2x1 +uf1ab u3fac u3fah -uf1ak u3fal -uf3ar +ufall4 +ufa2n +uf3ane +u2f3a2r +ufa2t uf1au +u2f1än u2f1ä6s u2f1ä2ß u2f1ei +ufel4s3a u2f1em +4ufen u3fen. u2fent +u2ferf u2f1erh +u4ferla u4ferle -uf2ern +u4ferne u2f1eß +u2f1et 2uff +uf3fe uffel2 uff4l uf2fro +u2f1id +u2fim +u2f1ins uf3l u2fob ufo2r uf1ori uf3r -uf3sä +uf5sä +uf3sc uf2spo +uf4stab uf4ster -uf2t1eb +2uft +ufta2b +uft1eb uf3ten uft3erd +uft3er4g +ufter4l +uf3ti +uf4tin uft3s2 u2fum 2u1g +ug2abe u4gabte -ug1af +ug1a2d ug1ak +u2gana +u2ganb ugang4 -u2g1ap -uga4s +u2gani +u2gans +u2gant +ug1ap +u2g1ar ug1au ug3d2 -u2g1ei +u3ge. +u2g1ec +ug1e2i +u2geig +u2gein +uge4lob +ug1emi +ugene2 ugenma3 ugenmas6 u2g1erf u2g1erl -ug4es +u2gerr +u2gerv +uges2 +u3ges. +u2g1esk +ug2et +ugg2 +ug2gl +ug5g4t ug3hu +u2g1i2d +u2gim +ug1in u2g1l -ug3lad +u4glä +u6gleitb +u6gleitu +u4glic +u4glis +ug3liz u4g3lo -u3g2lö u4glu -u2g3n -ugo3 -ug1or +u4g3n +u2gob +ug3oc +u3gon +ug1op +ug1o2r +u3gos u2gö +u2g3rä +u2greg u4g3reis +u2gres +u2g3rie ug3ro -u2grol -ug4ro3s +ugro3s +u2grou ug3rüs -ug3sc -ug3se -ug3si ugsma3 ugsmas4 -ug1spa -ug5stä +ug6spe +ugs4por +ug3stä +ugs1te +ug4stur +u2gum +ugu6ster u2gü u1h -uh2au +uh2a +2u3he +uhe3a +uhe1e2 +2uhi +2uhl uh1la +uh2lar uh1lä +uh4l3ent +uhl3erb uh2li +uhl2ö +2uhm uhme4 uhr1a -uh2rer -uh3ri +uhrei4s +uh2r3er5 +2uh3ri uh4rin -uhrt4 +uh2r3o uh2ru uh4rü -uh1un +uhs4 +uh3t2 +u2hu +2uhü uh1w 2ui -ui2c +ui2a +ui1ch +ui2che +u1idd u1ie ui1em u3ig u4ige uil4les u1im -u1in. +u3in. uin3n -u1is. u3isch. u3ischs +uis2e uisi4n ui2st +ui3sta +uit3s u1j +uji3 uk2a +uk1äh u3käu -u1ke +u1k2e +uke2n1 u1ki u1k2l -ukle1i +ukle1 u1k4n -u3ko +u2k1ob +uko2m1 +ukom3a uk2ö u1k4r uk2ta -uk2t1in +uk2t1el +uk2t1er +uk2tin +uk4t3o4ri uk2t3r +ukts4 +uk2tum u1ku uku2s uk2ü u1l -ul1ab3 ul1am +ulan2e +ul2ar +ula2sc ul1äm -ulb4 +ulb4l +ul4dan ul2dr uld2se 2ule u2l1el +ul1emb ule4n -ul1erf ul1er2h -ul1erw -ule2sa -ule4s3t +ule4s1t ule2t ul1eta -u2lex -ulf4 +2ulf4 ulg4 +2uli +ul1id uli2k ul1ins +uli1p ul3ka ul2kn ulla2g +ull1au ul2lä ul3len -ul2les +ul3l2i ulli2n +ul2lo ul2lö2 +ull3s2 +ulm2e +ulni2 ulo2i -ul1or -ul2p1h +u2l1op +u2l1or +ulp1h +ul2pha ul2sa ul4sam -uls2t -2ulta +ul2s1ec +ul2sei +ul2ser +ul2sum +2ult2a +ul3tan +ult3ar +ul2tau +ulter4m ul2tri ult3s u2lü ul2vr ulz2w -u2m3a2k +2uma. +u2maa +u2mab +u2m1ad +u2m1a2k um1all +um1ang um1anz -u2m1art -u2maus +u2m1ap +um1ar +u2marc +u2marm +u2mart +u2matl +u2matm +um1aus u2maut u2m1äh -1um3d2 -um2en -ument4s +1umd2 +u3me. +u2m1ef +u2m1ein +ume2n1e +um5engel umer2a -um1erf +u2m1erf um1erg -um1erl +u3merk +u2m1erl um1erw -u5mes +ume4s 1umf +4umfi 1umg +um1ind um1inh -u2m1ins um1ir +umi2t +um1ite 1umk 1uml -2umm -umm2a +umm4a +2umme um4mess -u2möl +um3mi +um1ob +u3mol +um3ot +ump2fa +ump4fin umpf4li um2pho -um2p3le 1umr -um4san -3umsat -um2sau -um2ser +um4sam +um4s3an +1umsat +um2s1er um2sim +um4sk um2s1pe um4stem -um2s1u +um2sum um3t2 -um2un -u2m1ur +u2mum +u2m1u2r 1umz un1 2un. -4una. +2una. 1unab -un4al +3unabh +un2a3br +un2ag +un2al u3n2am u2n3an -4un2as +u2nap +u2narb +2un2as un3at unau2s -1unda -un4dab +un2är +2und. +un2da +unda2b +un2dän 1undd +2unde un3de. -un4dei +underer6 und3erf +und3erö +underten8 +under8tend +und3erz un2dex 1undf 2undg un2did +un2dim 1undn +undo2b +un2dop un2dor -un2d3r +2un2d3r 4unds. +2undsc und3sp un2d1um undü4 1undv 1undz -u3ne -une2b -une2d -une2h -un2ei. +u3ne2 +un3eid un3ein -un3eis +un2emi +une4n1 unen2t -u4n3erz -unes2 +une3re +une3ri +u4nerk +u4n3erz. +un2es2 +unf2 +un3fa +unft2s +un2gab +un2gam +un2gat +3ungena +unger4e 1unget 1ungew -1unglü -un3gn +1ungl +un2glu +un2go un2gr ung3ri -ung4s1 +ung4s +ungs3tr +ungstra8s7 +u3nic un2id un3ide -1u2nif -unik4 +4unie +3u2nif +uni3k4 un2im -uni2r -2unis +1unio +un2ir +un3iro un3isl u3n2it -3u2niv +1u2niv 2unk un2k1a2 -un2kei +un3ker +un2k1es +un2ket un2kne -unks2 +un2ko2p +un2kro +unk3s2 unk4tit -unk2t3r -3unku +unk2tr unlö2 -un2n3a2d -un3n2e +un4n1ad +unn2e +unne4n +u2nob uno4r un2os 1unr uns2 2uns. unsch5el -un3se 1unsi un3sk +un4ski un3sp +uns4t +unsta4g unst1r +2unsy +2unsz 1unt un3ta +un3te unte4ri -2unth -2unto +2unti un3tr unt3s 2untu +3unty +2u2nu +u3nuc u1nü unvol2 unvoll3 1unw +2unwä +u2ny 2unz +un3z2a +unz2e 2uo u1o2b u3of u1op u1or u3or. -u3or3c +uo2r3a +uor3c +u3oret +uo2ris u3ors u1os. uote2 +u1ox +u1ö2d +u1ök u1pa +3upd u1pe2 uper1 +uperer4 up2fa -upf2e -upf1i +upfe2 u1pfl -u3pi +u1p2fu +u3p4i up4lu +u3po +2upp up2pl u1pr -upt3a2 +upra3 +u2p3ras +up4t3a2 +upten1 +up4tene upt3erf upt3erg +upt3erk +upt3ers upt1o u1q -2ur. +4ur. u1ra u2rab u3raba ura2be -ural2t -ural4ta -u2r1a2m -ur3ame -u2r1ana -uran4fa -uran4fo -u2r1ang +u2r1akt +u2ral2t +u2r1am +ura4na +u3rand +uran6fän +ur1ang uran4ge ur2anh -u2r1an5s -u2rar -ur3a4ren -u2r3att -u2r1au +uran5s +ur1anz +ur3ap +u2r3ar +ura4ri +u3rasc +ur1a4sp +ura4str +ur4a3te +u2r1att +ur1au 2u1rä +ur1äl +ur1ä2m ur1än ur3b2a +2urc urch1 +urchas4 +urcht3e +ur3d2a ur3d2i +ure1e ur1eff +ur1eig u2rele -ure4n -u4r1ep -ur1erh -ur1erw +ure2n +ure4na +u4ren4se +u4rentn +u2r1ep +urer3h +urer3k +ur2ert +u2rerw +ur1eta +ur2e3th +ure3u 2urf +ur2f3l +ur2fro +urf4spr urf3t +ur6gense +urg3inn +urg1l +ur2gla ur2gri uri2c -u2r1im -ur1ini -ur3ins -ur1int -urk3se +ur1ide +uri3en +u2r1ind +urin6sek +urin8stin +u2ri2so +2urli ur4matt -4u1ro -u3rol -u1rö -ur3p +ur2m1au +urm2ei +ur4mern +urmet1 +ur2mum +ur2mun +ur3n2e +2u1ro +urob2l +ur1off +uroh2 +uros4 +urost2 +2u1rö +ur3p4 2urr ur3re +ur2rh +3ursac ur2san -ur2sau -ur2ser -urst4r -ur4sw -urs2ze +ursau4 +ur2s1er +ur2s1of +ur2spa +ur2sun urt2 +2urta +ur4tai +urt3ein +ur2tro +urts2c +urts1t u3ru -ury5 ur2z1a ur2zä -ur2zec +ur2z1ec +ur2zep ur2zi -ur2z1o +ur2z1op +urzt4 ur2z1w 2us -u2s1af -us4ann +us3a2b +usa2gi +u4s1amb +u4samt +u2sang +us2ann +us3ark us5art +usa4s +us1ast +us3ate u1sä -u6schent -u5schmu +u2säh +u2s1äs +u2sce +u4schab +u4schak +u3sche. +u4schef +usch5eic +u4sch3eu +u3schi +usch3mü +u3schu usch5wer +u3se. +u3s2e3b u2s1ec +use2ei u2s1ei -u3seid +u4sen4se +u4sentl u3sep -use1ra +use4rec +u2s1erl u2serp +us1erw u2s1ese +u2sex +u2sid usi3er. usi5ers. u3sig -us5is. +usi4kat +us1inn us3kl +u4sko usmas2 usma5sse u1so us3oc -u3soh +us1oh u3sol -u2s1op +u2sop +us1orc us1ou u1sö u1sp u2spac us3part u2s1pas -u2spat +u3spec u3spek +u2sph us1pic u2spo us2por u2spu +usrich7 +us2s3ad +us2s3eb usse4g u4s3sel -us2sen +us2se4n us5sende us6seni -ussenma7s +us2sep us2ser us3ser. -uss5erfa -usser6kl -uss5er6su -u4sset +uss3erf +usser4z us2sez -u3ssig +u3s2sig +uss3k us2sof +us2sum u2stab -ust3abe +u3stad u3stal -us2tat us2ten -us2ter -us2th -ust2in +us4ter +ust3erl u3stis u2s1tor -u2strä +u2s3trä u4strit -u3s4trop +us2tum u2s1tur -u2sty u1su -us2ur +u2sumd +u2sumg +u2sumz +3usus 2uß u2ß1u 2u1t +4ut. u3ta. -ut1alt -ut3a2m +u3taf +u2t1alt +ut1a2m +ut2ans u2t1ap u2t1ar -u2t1är -u3te -u4t1ed -ut1e4ge +u2taut +ut1äh +u2tär +ut3c +u3te. +u4t1e2d ut1ei. ut1eie +ut1ein +ut1ela ute2n1 +uten2a u2tent -uter4er -u4t3er4sa -ut2es +ute4ral +ute5r4er +ute6ring +uter3k +ute4ros +u3t2es ut2et -u4tev -u4t1ex -utfi4 -ut2he -u2thi -u2t3ho +u2t2ev +u2t1ex +utfi2 +ut3hal +ut3hei +ut1hel +u2t1hi +u2t1ho u2thu +u2t1id +u4tigel +uti2vi utli4n utmas2 utma5sse u3to. -uto4ber uto3c -u3tom -ut1opf +u5to3m +uto1p +uto3pa u2tops -ut4or +utor2a +u2tord +uto2re +uto4rin +4utou +u2töl +4utr ut3rea +u2trou ut3rü -ut3s2a -ut2s1ä +utsau2 +ut2säu ut4schl ut4schm +ut4scho ut4schö -ut3si +ut3ser +ut3s2k ut1s2p -ut2s3pa -utt4an -ut3te +ut3sta +ut3sto +ut3tan ut3t4l utt1s2 +utu2b +u2tum +utu4n +u2t1une utu4re +utu3ro utu5ru +u4tz +utze2 +ut2zeh utz3eng +utz2er +ut2zet ut2z1in -ut2zo +ut2zis +ut2zö ut2z1w -2u1u2 -u1ü2 +2u1u4 +uum1 +uum3a2 +uume2 +uungsma5 +uungsmas8 +u1ü4 u1v4 u2ve. uve3rä @@ -14665,132 +23133,196 @@ u1w 2u1x ux2e ux2o -ux3t -u1ya +ux3oe +uxt4 +u1y +u2yo 2u1z +uze2 +u2z1ec +u2z1ene +uz2er +uzo2f uz3ot uz1we -uz3z4 +uz3z2 1üb üb1ä 2übc 2übd übe2 -übe4n3 -über3 +übe3le +übe4na +übe3ne +über1 +überas4 ü4bet üb3l -üb3r +üb5r 2üc ü1che üch3l üch4s1c -üch5t4e +ücht4e +ücke4n ück1er ück3eri -ück4spe +ücker6ke ü4d3a4 +üde2l üden2g ü3d2ens -üd1o4 +üd3o4 üdö4 üd3r üd3s2 -üdsa1 üd3t4 -üdwe2 +üdu2 +üdwe4 +üe2 +üeb3 +ü1ei ü4f1a +ü2f1ä ü2f1ei +ü2fent üfer2 ü2f1erg üf2fl ü2f1i üf3l -üf2to +ü2fo +üf3ten +ü2fum ü1g +üg2e +üge2l1a2 +üge2lä +üge4lec üge6lei6s +üge2lo +ügen3s ü2g3l ü2gn üg3s -üh1a +üh3a2 ü1he ü2h1ei +ü2h3e4m +ü3hem. ü2h1eng -üh1erf +ü2h1ent +ü2h1erf ü2h1er2k ü2h1er2z -üh1i -ühl1ac -üh1lam -üh3l2e +ü2hex +üh1i4 +üh1lä +üh2lel +ühl2er +üh2lö +ühl4sk +ühl4sta +ühl4sti üh3mo üh3ne -üh1o +üh1o2 üh3r2e ühr3ei. +ühre2n1 üh1ro ühr3ta ühs2 +üh3sp üh3stu üh3t -üh4th +üht2a üht4r ü1hu üh1w ü1k2 -2ül ül1a ül2c -ü3l4e -ülla4 +ü3l2e +ü4l3ef +üle2r3a2 +ül2la4 +üll1ad üll1au ül2lei -ül3ler +üll2er ül4leu +ül2lic +ül2lid +ül2li2n ül2lo +ül2lö +ülls2 +ü2lö ü1lu +ü2ma ü2ment -4ün -ü2n1a +üme2ra +ü2m1id +ü2m1in +ü2m1u +2ün +ü4n3a ün2da ün2dr -ünen3 -ün2f1a -ün2f1ei -ün2fli -ün2fr +ü2n1erd +ünf1 +ünf3li ün2g3l -ünt2 -ü1nu +üngs2 +ünster3 ün2za +ün2z1i +ünzu2 +ün2zun ün2zw ü1pe üpf3l ü1pi üp2pl +2ür ür1a ü2r1ei +ü2r1e2l +ür2f1er ür2fl ür2fr ür4g3en4g -ü1r2o3 +ürge4ra +ürk2e +ü3r2o3 +ürom2 +üror2 ür4ster +ürte2l1 ürt2h +ür2z1in ür2zö -ür2zw +ür2z1w üs2a ü2schl -ü5se -üse3h -üse3l +ü3s2e +üse1e2 +üse3l2 +üse4n +üse3r4 ü1sp +üs4s3a üs2s1c üss2e ü4s3sel -üs3si +üs4s3o üs4st üs2su -ü2sta +üs4t +ü2st3a +ü4stei +üste2n ü2str ü1su ü1ß @@ -14798,80 +23330,137 @@ uz3z4 ü1ta ü2t1al ü1te +üte3m +üte4n +üten3s +ütent4 +üten3z2 +üte2ra +üte2r1e +üterich6 +üter3n +ü2t1h ü1ti üt3r -üt4s1 +üt2se +üt2s1t +ütte4n üt2tr ü1tu +üt3zen +üt2zw ü1v ü1z +3va. 2v1ab +vab4r va1c -val2s +va1f4 +va3g +vag2a +va4gh +va2la +2valu +v2an. +2vanb 2vang +v2ans 2varb +v1arm vas2 +2v1ass +va2s3to v4at -va2t3a4 +va2t1a4 +va4tag va2tei +va4t3eng +vates2 va2t3h -vatik2 +va4tid +vati3k2 +va4tim va4t1in vati8ons. +va4tord +va4torg va2t3r -vat3s4 +vat3s2 va2t1u vat3z 2v1au vä1 2v1b -2v1d +2v1c +2v1d2 1ve2 +ve3an ve3ar -ve3b +veau3 +ve3b4 ve3c ve3d +ve3fa ve3g ve3h -ve4i -2v1ein -veit4 +2veig +v2eil +2vein +veit2 veits1 ve3la +2velan +vel2ar ve4l1au -ve3le -ve3li -vel3l +v1ele +ve3lei +ve3l2i ve3lo +vel2o1p ve3ma +ve3me +2v1emp 2ve3mu ve3nal +ve4nas ven2c ve3ne -venen4d ve3ni +ve4nin ve3nö +ven5st +ven4t3ag +vent4sk ve3nü -ve3o +2veo +ve3of +ve4pi ver1 ver3a ve3rad +2veral ve3rand -ve3ras -ver3b2 -ver5d2 +ve3r4ane +vera4s +ver6bart +ver3b2l +ver3d2 vere2 verf4 -verg4 +ver3g4 vergas6 +verga7sse ve3ri ve4rin ver3k vermas8sen +vern2 +ver4sep ver3sta -vert2 +vert4 ver5te -ver3u +ver3u4 +ve3rus ve3s 2vesc 2vese @@ -14880,76 +23469,104 @@ ve4s1p ves4t ve3ta vete1 -ve3to +vete3r +ve3ti ve3tr +ve3t2s 2veü ve3v -ve3x2 +ve3w 2v1f4 2v1g 2v1h +vi1an vi3ar vi4a3t -vi2c +vi2ä vi3de -vie2h3a +3vie +vie2h1a vi2el -vi3en +viela2 +viele2 +vi2er vie4rec vie2w1 vig2 2vii +v2il vi2l1a +vi2lä vi4l1e2h +vi2lei +viler4 +vi4lers vi2l1in -vil3l -2v1i2m -vima2 +vi2ma2 vi4na -vin2s -2v1int +vin3d +ving3 +vings2 +v1ins vi3sa vise4 +vi3s2i vi3s2o vi2sp vis2u +viv2 +viz2 +vize5 2v1k -2v1l2 +2v1l4 +v3le +v2lie 2v1m -2v1n +vm2e +2v1n2 +1vo 2v1ob -vo3ga +vo2be +vob4l +voge2l1 vo2gu -3vol -vol2la +vol2a +vol4la +voll3ar voll7auf. -vollen4 -vol6l5end -voller4 -vol6lerw -vol2li +vollen6 +voll5end +voller6t 2v1op vo2r1 -vor3a -vor3e +vo4r3a +voran8schl vor3g vo3ri +vo4rie vo5rig +vorm2 vormen4 +vor3o vorö4 -3voy +vort4 +vot2a +voy1 2v1p -v2r -2v3ra -v3re -v4ree -2v3ro -2v1s -vs2e -v3s2z +vr2 +v1ra +v2ree +3v2ri +2v1s2 +v3sz 2v1t +vue3 +vu2enu vu2et 2vumf +2vumg +2vumk +v1ü 2v1v 2v1w 2v1z @@ -14957,44 +23574,67 @@ w2a 1waa wab2bl wa3che -wach6stu +wach8stub wach4t4r +1wack waffe2 waffel3 1wag wa5ge +wage4n wa2g3n wa3go 1wah wahl5ent wah4ler -wah2li -wai2b +wah2l1i 1wal +wa2lar 2walb -wal4da +wal4d3a +wal4din +wal2dr wa2les +wa3li wal4li4n -2walm -wal2ta +wal2m1 +wals2 +walt1a +wal6tere +wal6terl wal2to -walt4st +wal4tur wa3na +wan2d1a2 +wan2dr w3anf +2wang +wan3g2e wang4s 1wann wan6z5en6d +wan4zer wa2p 1war2e ware1i +wa5ren +1warn +war4ni wart4e +war2th +war2za 1was wa3sa +was2c wa4scha wa3sche wa3schi +wa4sch3l +wa4schw wa3sh -wass4e +wass4e2 +wa3su +w2ä 1wäh 1wäl wäm3 @@ -15002,630 +23642,997 @@ wäm3 1wäs3 wä5sc wä4ss +wäss4e +2w3äu3 2w1b2 wbu2 2w1c 2w1d we2a -we2ba -4webeb -we2bl -web3s -we2e4 +we2b1a +webe1i +we2b3l +we2bo +we2b3r +we2e2 weed3 we2fl 1weg we2g1a -we2g3l +we4g1ei +weg5ersc +we4g3l we4gn -we2g3r +we2g1o2 +we4g3r weg1s -weg3sa +weg3s2a 1weh -we4i -wei4bl +weh4r3er4 +wei2bl +weib4r 2weie weifel6d -weik4 +wei4fre +wei2gr +wei3k4 1weil +weinsau6 wei3sc -weiss3p -wei4tr +wei2t1r weit1s +wei5ze +welle4 wel6schl wel6schr wel2t1 -welt3a4 +welt3a2 +welte4 wel6t5en6d +wel4th +welt3i +welt3r wem2ma2 -wen3a4 +wen3a2 wen2gl -we3ni +we3n2i +wen2ka +wen4kla wen4k3ri -we2r3a +we2r3a2 +wer5be +werbe3i wer2bl +werb2s 1werbu -werd2 +wer3d2 5werdens 1werdu werer2 wer2fl -wer4gel -we4r3io +2werg +wer2ga +wer6gels +wer2g3o +wer2gr +werin2 +we3rins +we2ri4o 1werk. -wer2ka +wer4k1a 1werke -wer2kl +wer2ki +wer2k3l +wer2kn +wer2k3o +wer4k3re wer2ku we2rö wer4sta -wer2t1a -wer4t3ei +wer2ta +wer2tä +wert3ei +wer6teig wer6t5erm -wer2to -1wese +wer2th +wer4tin +wer2t1o2 +wer4tre +wer4t3ri +wer4tum +1we3s2e wesen4s3 we2sp -wes2t -we2st1a +wes4t +we4st1a we4st3ei +we5sten. +we6sten6d +we5stens we4steu we4sti -we2st1o2 -we2stö +we2st1o4 we2st3r we4stu 1wet -wet2s +2wets wett3s 2w1ey +2w1f 2w1g -2w3h +whi2 +w3ho +w2i +wicht4s 1wid wi2e +2wieb +1wied wie3l2 -wien2e +wie3n2e wie4st wik2 -1wil +1wild wim2ma -wim4mu +wim6ment +wim4m3u +win2a win4d3ec -win2dr -win2e -2wing +win3del +win6d5erz +1win2d5r +4wing +win2g3r +win2kl win8n7er8sc +win2no win4num +win3s +wint2 1wi4r +wire3 +wisch3l wi3s2e wi2sp 1wiss +wiss4z wi3st wi3th +1witz. 1witzl +wiz2 2w1k 2w1l 2w1m 2wn -wn3s +wns2a +wn3sh 1wo1c wo2cha -woche4 +woch2e4 1woh woh4lei +woh4na 1wolf -wolf4s1 +wolf2s wol4la wol2lä wol4ler wor3a -wo2r3i +wor3d +wo4r3i +worn2 +wort1a +wor4tel +wor6terh wor2t3r +worts2 wo4r3u +wor3ü wot2 1wöc +wöl2fo wört2h 2w1p w2r +w3re w3ro 2w1s +ws2e +w3s2h w3s2k +w4s1u 2w1t wti2 w2u 1wuc wuch4sc +wuch4st +w3u2f wuls2 -wun2da -wun4g3r +wul3se +wund4e +wung3r +wung5s2 wun2s +wunsch5l 4wur. wur2fa +wur2f1o +wur2fr +wurs4 1wurst wus4 -1wu4t1 +1wu2t1 1wüh +1würf +1würst wüs4 2w1w 2w1z x1a 1xa. 2xa2b +1x2ac 1x2ad 1xae xa1fl -1x2ag +1x2a3g2 +2xal +xal2l xa2m xand4 +1xane +1xani +x2an3t2 x2anz +xa2r 1x2as xau3 xaus2 -2x1b -2xc +xa2z +2x1b4 x1ce x1ch x1cl 4x1d +xda2 1xe -x1e4g +3xe. +2x1e4g 2xek xe2l +3xel. +x1ele +xe3lei x1em 3x2em. -xemp4 +2xemp +x2ems x2en +3xen. xen3s2 -x2er. +3x2er. x2ere +2x1erl +xer2la +x2ern xers2 +x2ers. 3xes -2x3eu +2x1eu +2x1ex 2x1f 2x1g 2x1h -xib4 xi1c xich2 2xid +xi2dan xide2 -xi2d1em +xi2dei +xi2d3em x1i2do +3x2ie xie3l xi3g -xil1 -xil2a +xi2ler +xili3a xi2lo -xi2lu +xi2l1u +xim2 xin3s2 x2is +xi2sa xi2s1e -xi2s1o2 -xis5s +xi2sp +xis5s2 +xi3s2tä xi2su -x1i2tu +3xit +x1i4tu +xive4 x1j -2x1k2 +4x1k2 +xkal2 4x2l2 x3lä x3le 2x1m 2x1n -x1or +2xod +2xoe4 +x1o2r +xos2 +2x1ö2 4x1p xpor6ter +xpor4t3r x1q -2x1r +x1r 2x3s2 4x1t -x2t1a +xt1a x3ta. -x3t2as -xt1ä -x2tän +xta2b3 +x3tan +xt2ant +x3tas +x2t1ä +x3tät +xtblock5 x2t1e2d -x2t1ei +xt1ein +x2t1el x2tent x2t1er2f -x2t3ev -xtfi4 -x2t1il2l +x2t1ev +xtfi2 +x2t1h +x2t1id +xti2la +x2til2l +x2t1o4 xtra3b4 x2t3ran -xt1s2 -xt1u -x3t2ur +x2trau +xt3rec +xt3s2 +x2t1um +x2t1un 1xu xu1a -x1u2n -xu2s +xu2n +2xunt +xu2s3 +xusa2 +xuss2 2xv 2x1w -2xy 3xy. -3xys x1z 2y1ab -1yac +1ya2c +y2ach +ya1h y1al. -y1a2m yan2g y1ank +ya1q +ya3ra y1ät y1b -y1c2 +ybe2r +y1c y2chi y3chis ych3n -y1d4 +y1d +yd4r +ydri2 +ydrid3 +ydro3 y1e +y2ec +ye2d y2ef +y2el2 yen4n +yera2 y2ere -yes2 -y2es. +yer2n1 +y2e2s +y4es. +ye3s2p ye4st ye2th y1f2 y1g ygi2 -ygie5 +ygie3 yg2l y1h +y3ho yhr2 -y1i4 +2y1i4 y1j y1k2 yke3n -yk3s2 -y1l -y2l3a2m +yk3s +yl1a2 +yl2a3g +y1l2ak +yla4l +y2lam +yl3ane +y1lant yl4ante -yl5b +yl4anti +yl2as +ylau2 yl3c -y4le. +yle4 +y2le. +yl1em +y2l1es +y2l1et yli4n -yllo2 -yllö2 +yl4lo2s +yl2lö2 +ylo1i2 +yloid3 yloni1 -y2l1u -yma2t +yl2op +yl1ora +ym2a +ym4an +ym4ar +ym4as +ym4e ymp2 ym2pha -ympi1 -y2n1o -yno4d -ynt2 -y1of +ympi1e +ynä4r +yn2eu +ynk2 +y2n1o2 +yn2oz +yn3t2 +yob2 +y2od +yoga3 yom2 -yon4i +yon2a y1ont -y1os +y1o2pe +y2ost y1ou -y1p -ypa2 -yp3an -ype2 +2y1p +ypa2b3 +ypa2n +yp2e2 +ype4r3o2 y2pf -y3ph +y2p1i2d y2p1in -ypo3 +y2plo +y3po3 y4p3s +yp3th +ypu2 +y2p1um +y1q y1r y3r2e y3ri -yri2a yri1e -y3r4o +yri3en +y3ro +yro4ste yrr2 -y1s +2y1s ys2an -ys2c -yse1 -y3s2h +ysch4 +ys2e1 +ysein2 +ys1er y4s3l ysme3 -ys2pa -yst2 -y2s1u2 +ys2o +ys2pi +yst2e +yst2h +ys2tra +y4stro +y3s2ty +ysu2 y3s2z -y1t2 +y1t y2te. y2tes +yt2h +ythe1 y3to +y4t3r yu2r -yure3 +yur2e3 y1v y1w y1y y1z2 -za2 -2z3ab +yzer2i +2z1a2b zab3l -za3cha -za3chä -2z1ad +2z1ach +za1cha +za1chä +zach2s +2z1a2d 2z1af -za3ge za3gr 3z2ah -zah4ner -2z3ak -za3li -2z1all -2z1am -z1an +zah3len +zah4ner4 +z1ak +4z3akk +2z1al +4z3ald +3zali +2z1a2m +z1a2n +4z3a4n4a +2z3anb za3ne 2z3anf -3zani +2z3angs 3z2ank -zan4kl -2z3anl -za3no +zan2ka +z3anl +2z3anr zanti1 -za3ra +za4pf +z1aq +z1ar +3zar. 2zarb -2zarc za3re -2z1arm -za3ro -z1arti -zar2tr -2z1arz -z1as -zast4 -2z3at3 +2zarm +3z2aro +z2arr +zar2t1r +2z1as +za3st4 +2z1aß +z3at +zat2e +za2to 3zaub -z1au2f -z3aug +2z1au2f +2z3aug 3zaun +z3aur +2z1aut 2z1äc -3z2äh +z2äh +3zähn 2z1äm -2zängs -2z1äp -z1ärg -z1ärm -4z1b4 +z1än +z1äp +z1är +2z1äus +2zäuß +4z3b4 +zber2e zbü1b zbübe3 2z3c 2z3d2 zdan2 zdä1 +3ze. +2zea zeau3 zeaus4 2z1e2ben -2zecho -ze1e +2z1echo +ze1e2 +zeeu3 2z1eff +z1e2ga zehe4 zehen1 zeh2l +ze3ho +zei1f4 zeik4 +zeil2 zei3la zeile4 2z1ein -zei3s2 -zeist4 +ze3in. +zeinbus6 +z2e1ind +zei4ne +4z3einh +ze3inse +ze2i3s2 +3zeit zei2t1a -zeit5end zei4t3er +zei2to zei2tr zeit3ri -ze2l1a2 +zek4 +ze2l1a +zela2d +zel3a2n zelau2 +ze2l1ä +zel3d4 +4ze2lek +4zelem ze2len ze2l1er ze2l1in -zel3l2a +2z1e2lit +zel3la +zel4lab +zel4l3ac +zel4lar +zel2lä zel4leh -zel4li4n +zel6lein +zel6ler6t +zeller6z +zelli4n +zel4lum +zelm4 +ze2l1o zels2 +zel3sa zel3sz -zel3t2h -zel3tr +zel2ti zelu2 +zembe2 2z1emp 5zen. -ze4n3ac +ze4n1ac +ze4nas +zen3au ze2nä +ze3n2em +zenen1 +4zenge. +z4engl +2zengp +2zeni +ze2nid +zenk2 zen3n -ze2no -zens2e -zen4sem -zent3s +ze2n3o +ze4not +4zen4sem +zen4ser +zens2p +z2entn +z1ents +2zentw +2zentz +ze2nu zen4z3er -z2er. -ze2r3a -ze2re2b +zen2zw +zeo4r +3z2er. +zer3a +ze1ral +ze2rat +z2ere +ze5rek +zer2em +z2erfe +z3erfül +z2erga 2z1ergä 4z3ergeb -z3erhal -2zerhö -zerin4t -zerk2 -z2erl. +z4erges +z4ergl +zer4gon +4zergu +3z2erhe +2z3erhö +ze3ri +zerin6te +z2erko +3zerl. +zer4lau +zer4le. +4zerleb +zer4len 2zerlö -z2ern -zer4neb -zer4n3ei +3z2ern +zer4nan +zer4n3e4b +zer4nei +2z1erö +zer2öf 2z1erq -zers2 -2z1ersa -4z3erste -4z3erstr -3zert -zert1a4 +4z3erreg +z2ers. +2z1er4sa +zerta2 zer4t3ag zert4an +zer4tau zer6tere zer6terl zer4tin +zer2to +6z5ertrag zer6trau +z1erwe 4zerwei -2z1erz -3z2erza +z1erz +zer2ze ze2s -zes2c -ze3sku +3z2es. +ze3sc +zes1e +zes3er +ze4s3po +zes2sa zessen4 zes6s5end +zes4ser4 zes2sp -ze3stau +ze3sta +zes2th +ze3str ze2ß1 +z2et. +2zeta +2ze2th ze2tr 2zetts -2z1ex -2z1f4 +zeu4gem +zeu2g3r +2z1eul +ze1ur +2z1e2x1 +2z3f4 zfäs3 -2z1g2 +zfeue2 +2z3g4 +zgang5 zger2a -2z1h +zger2s1 +2z1h2 z2hen zhir3 3zi. +zial5l zi3alo -zi3ar +zi2ar +zich2o zi2dei zid3r -zie4lei +zie4ler +zie2l1i zi1erh -zi1es. +zi1es +zi3ess 3zig +3z2il zil2e -zil3l -2z1imp +z2imm +2zimp zim2t3 +2z1ind zin2e zin3ei -zin4er 2z1inf z1inh +zi4n3in zin1it +2z1inj +zin4na +zin4o zin2sa zin4ser 4zinsuf -z1int -z1inv zi2o3 -zi3op zirk2 -zirk6s1 +zirk6s +z1iso +zi2sp +zisse4 zis4t zistras6 zi3s2z -zit2h +zite4 +zithe2 zi2t1o2 +zit2u ziv2 2z1j -2z1k4 +4z1k4 2z1l2 -2z1m2 +z3ly +2z3m2 +zmas6sen +zme2e 2z3n2 +z3oas 2z1ob 2z1of zo2gl +zog4s 2z1oh -3zol zolla2 -zol3le +zol3len +zoller4 zol2li2 -zol3lu -zon4ter +zonal2 +zon3au +zon5s4 +zon4t3er zo2o 2z1ope -z1or -zo2ri +2z1o2r +zo3re +3z2orn zor4ne -zo3se 2z1osz +2z1ou +2z1o2z 2zö2f 2z1ök z1öl +2zöl. +3z2öll +2zöls 2zön 2z3p4 2z1q 2z3r2 -4z1s2 +2z1s2 z3sa +zsau2 z3sh z3sk +zspor2 +4zst z3str z3sz 2z1t +zta2n +zt3ane z2t1au -z4tehe +ztein1 +zt3eins +zt2el +zte3ma +z2t1ent +z2t1erz +z3tes zte3str +zt2et +zt1he +z3them z3t2her +zt1hi zt3ho -zt1ins +z3thr +z3thy zt3rec -zt3s2 +zt3ric +zt3s zu3a -zu3b4 -3zu4c +zu1ä2 +zub4 +zubus2 +3zuc +zuch2e +zucht3r zud4 zudi4 zu2el +zu3e2r1 +zue2t zu3f4 -zu2g1ar +zug2em zu4gent +zug2i zu3gl +zu4gla +zu4glö +zu2go zug4ste -zug1un 2z1uhr -zuh2u -zu1i +zu3hu +zu1i2 zu3k +zul2 2z1um. +zum2a +2z1umb zumen2 2zumf 2zumg +zum2i +2zumk 2zuml 2zumr 2z1ums +zum2u +2zunab zun2e +2z1unem +4zunget +2zungl +z1uni +2zu2nio +2zuniv +2zunr +2z1uns 2zunt +zuo2 zup2fi +zu3pl zu3r2a -z1urk +2z1urk 2z1url +2z1urn 2z1urs 2z1urt zu3s2 -zu3t2a +zusch4 +zu3t2 +zut4r +zut4u +zut3z zuz2 -2züb +2zü4b +3züc zür1c 2z1v zw2 z1wac 2zwag -2zwah -zwan2d1 -z2wang +4zwah +4zwap z1war -2zwas -4zwäl +2zwa2s +2zwäs +2z1wed 2zweg 2zweh z2weig -zwei3s +2zweil +zweiter6 2z1wel 2z1wen 2z1wer -z2werg 2z1wes -2zwet -2zwir +z2wic +zwi4e +3zwing +2zwirt +z2wisc +2zwiss z2wit 2z1wo z1wör z1wur 2z1wü +zy1an. +zy2le 2z1z -z3z4a +z3z2a +zza3b4 +z4z3al +zz4at zze3s -z3z2o -zz2ö} \ No newline at end of file +z2z1id +z2z1in1 +zz2ö +zzug4s} \ No newline at end of file diff --git a/tex/context/patterns/mkii/lang-fr.pat b/tex/context/patterns/mkii/lang-fr.pat index 540785c6e..7aee5604c 100644 --- a/tex/context/patterns/mkii/lang-fr.pat +++ b/tex/context/patterns/mkii/lang-fr.pat @@ -18,12 +18,14 @@ a1è2dre .ae3s4ch 'ae3s4ch 1alcool +'2alcool a2l1algi .amino1a2c 'amino1a2c .ana3s4tr 'ana3s4tr 1a2nesthési +'2a2nesthési .anti1a2 'anti1a2 .anti1e2 @@ -454,6 +456,7 @@ uevil4l uvil4l xil3l 1informat +'2informat .in1a2 'in1a2 .in2a3nit @@ -725,6 +728,7 @@ n1x .ô4 o2b3long 1octet +'2octet o1d2l o1è2dre o1ioni diff --git a/tex/context/patterns/mkii/lang-la.pat b/tex/context/patterns/mkii/lang-la.pat index e6cabb9dc..40cec82b6 100644 --- a/tex/context/patterns/mkii/lang-la.pat +++ b/tex/context/patterns/mkii/lang-la.pat @@ -39,6 +39,7 @@ o1iu uo3u 1b 2bb +2bc 2bd b2l 2bm diff --git a/tex/context/patterns/mkii/lang-th.pat b/tex/context/patterns/mkii/lang-th.pat index 5b0ad206b..c1d20cf64 100644 --- a/tex/context/patterns/mkii/lang-th.pat +++ b/tex/context/patterns/mkii/lang-th.pat @@ -5,6 +5,7 @@ % used: ก ข ฃ ค ฅ ฆ ง จ ฉ ช ซ ฌ ญ ฎ ฏ ฐ ฑ ฒ ณ ด ต ถ ท ธ น บ ป ผ ฝ พ ฟ ภ ม ย ร ฤ ล ฦ ว ศ ษ ส ห ฬ อ ฮ ะ ั า ำ ิ ี ึ ื ุ ู ฺ เ แ โ ใ ไ ๅ ็ ่ ้ ๊ ๋ ์ ํ ๎ \patterns{ +.กัน3 .ชี5วั .ทัศนู5 .ที่3 @@ -66,7 +67,6 @@ ก1ฟ ก1ม ก4มม -กม5ลา ก4มส ก4มเ กย5มุ @@ -77,12 +77,12 @@ 1ก4รร กร5รา กร5ลา +กร5วร ก5ราค ก5รินท ก4รู กร5ไฟ กล5นค -กล5บิ กล5มห ก2ว ก5วัต @@ -108,6 +108,7 @@ กา5น้ กา5บอ กา5ฝา +กา5รอ กา5ร่ กำ5ด้ กำ5ทอ @@ -156,9 +157,9 @@ ข่5หง ข้าว3 ค1ค +ค1ช คช5สี -คช5เช -คช5เม +ค4ชเ ค4ณิ ค4ทร คท5รี @@ -175,7 +176,6 @@ คร5นอ คร5นี คร5พน -คร5ฟิ คร5มเ คร5ร้ คร5ลิ @@ -206,7 +206,6 @@ คำ5ดี คำ5โอ คำ5ไก -คี5รี 1คุ คุ5ณู คุ5ลี @@ -231,6 +230,7 @@ ง1ค ง4คจ ง4คช +ง5คชาติ ง4คญ ง4คธ ง4คบ @@ -290,14 +290,15 @@ จด5จ่ จต5จำ จต5มู +จต5ริ จป4ก +จฟ5ฟร จมบ5พ 3จริ จอ5งอ 1จั 1จา จา5มร -จา5มี จา5รึ จำ5ทว จำ5อว @@ -307,6 +308,7 @@ จี5ดี จุ5ฑา จุ5สม +จู5ปิ จ1เ ฉ2 ฉก5ฉว @@ -321,8 +323,10 @@ ช1ฌ ช4ฌก ช4ฌฆ +ชด5ช้ ช5นีก 4ชน์ +ช1บ ชฟ5รอ ชฟ5โร ชร5กล @@ -331,6 +335,7 @@ ชร5หล ชร5หึ ชร5อุ +ช3รา ชว4โ ชอง4 1ชั @@ -349,16 +354,18 @@ ชี5ผ้ ชี5ฟอ ชี5รณ -3ชีว +1ชีว ชี5วน ชุ5ติ ชุ5ลด ชู5ปก ชู5ปถ ชู5ปโ +ช1เ ช่5อิ ช้5สอ ช้5ได +ซก5ซอ ซน5ทร ซ5ราม ซล5ฟี @@ -368,15 +375,14 @@ ซา5มู 1ซิ ซิ5ตร -ซิ5ฟิ ซิ5แล ซี5ดี ซี5นี ซี5รา ซี5ริ -ซี5รี ซี5ร็ ซี5ลี +3ซึม ซู5ซู ซู5บิ ซู5ริ @@ -403,6 +409,7 @@ ญ1ญ ญประ4 1ญา +ญา5ญ่ ญา4ต ญ่5บ้ ฏ1ฐ @@ -441,11 +448,11 @@ ณย5รั ณ1ร ณ4วา -ณสม4 ณห5พล ณห5ภู 1ณา ณา5ปี +ณา5วร 1ณิ 1ณี ณี5สง @@ -460,8 +467,6 @@ ด1ค ดง4ค ดง5ออ -ด1ช -ด4ชน ด5ชนะ ด1ด ด4ดเ @@ -469,13 +474,16 @@ ด1ท ด1ป ด1พ +ดม5คต ดร5ลิ +ด4รู ด3ร้ +4ดร์ ด1ส ด4สก +ดส4เ ด1ห 1ดั -ดัส5ต 1ดา ดา5มุ ดา5รก @@ -486,6 +494,7 @@ ดิ4บ ดิ5วร ดิ5ศว +4ดิ์ ดี5ดี 3ดีน ดี5ฝ่ @@ -504,6 +513,7 @@ ด1โ ด้5ยิ 2ด์ +ด์5ปร ด์5สป 2ตก ตก5ร้ @@ -512,6 +522,7 @@ 2ต1ต ต4ตภ ต4ตส +ตต5สด ต4ตโ ต5ถกะ ตถ5กิ @@ -523,7 +534,6 @@ 2ตน ตน5ฟอ ตน5วร -ต4นาธ 2ต1บ ต4บช ตบ5ชว @@ -542,16 +552,15 @@ ตร5พล ตร5รง ตร5ลด +4ตรศ ต5ริยา ต4รู 2ตร์ ตฤ5ตี ตล5รั -ต1ส -ต4สค ตส5วา ตส4เ -ต4สแ +ตส5เซ ตส5แต ตอ5ม่ ตะ5ใภ @@ -568,15 +577,15 @@ ตา5มอ ตา5มะ ตา5ฬี -3ติก. +1ติก. ติ5จู ติ5ช่ +ติ5ซอ ติ5ทิ ติ5นร ติ5บอ -ติ5มศ -ติ5มส -ติ5มอ +ติ3ม +ติ5ยภ ติ5ยม 4ติ์ ตี5ขล @@ -643,6 +652,7 @@ ท5ธิร ท5ธิฤ ท5ธิศ +ท5ธิส ท5ธิโ ทธ5เจ ทพ5ธิ @@ -652,12 +662,12 @@ ท5ยาน ทร5คต ทร5คร -ทร5ชิ ทร5ธน 3ทรร ทร5สโ ทร5หว ทร5หึ +3ทรั 1ทรา ท5ราก 4ท5ราห @@ -667,7 +677,6 @@ ทศ5ทิ ทศ5วร ทสน5ท -ทส5โก ทห5วั ทห5ฬิ 1ทั @@ -675,6 +684,7 @@ ทา5ฐิ ทา5ฒิ ทา5นอ +ทา5มต ทา5มร ทา5รพ ทำ5ขว @@ -687,24 +697,26 @@ ทิ5พา ทิ5วง ที5นว +ที5นอ ที5นี ที5รา ทุ5คต +ทุ5ติ ทุ5ลั ทุ5ศี 1ทู ทู5น่ ท1เ +2ท์ ท์5ดอ 1ธร 4ธรส 4ธรั 1ธา -ธา1รณ +ธา5รณา ธิ5ฤท ธิ5ศี ธิ5สม -ธี5รี ธุ5ดง ธุ5ลี ธู5ปน @@ -724,7 +736,6 @@ น4ชญ น1ซ น1ด -น4ดร น1ต นต5กว น5ตกะ @@ -750,8 +761,6 @@ นท5ผล นท4ย น5ทรง -น5ทรล -น5ทรั น5ทรุ นท5ฤก น5ทลา @@ -793,10 +802,9 @@ น1ศ นษ5กร น1ส -น4สซ -น4สส +นส5ฟอ นส5แด -น4สโ +นส5แต น1ห นอ5กะ 3นอน @@ -827,8 +835,6 @@ นิ5สถ นิ5สี นิ5แด -นี5มี -นี5มู 1นุ นุ5พย 1นู @@ -849,7 +855,7 @@ บ4คท บค5ที บ4คโ -1บดี +1บดี. บ1ท บบ5ฉบ บบ5ฝึ @@ -857,6 +863,7 @@ บ1ป บ1พ บร5มี +บ5รัด บ1ส บ4สบ บส4เ @@ -876,7 +883,9 @@ บา5รน บา5รอ บา5สม +บิ5ก้ บิ5ชอ +3บิน บี5คิ บี5ร่ 1บุ @@ -900,7 +909,6 @@ ปฐ5พี ปต5ถก ปต5พล -ป4ทา ป1ป ป4ปเ ปม5ด้ @@ -912,8 +920,10 @@ ปร5ผั ปร5ษณ 1ประ +ป5ริค ปร5แก ปร5แท +ปร5ไบ ปร5ไฟ ปล5ญว ป4วา @@ -932,7 +942,6 @@ ปิ5ยอ ปิ5หก ปี5ชี -ปี5มะ ปี5ฬก ปี่3 ปุ5คล @@ -955,12 +964,11 @@ ผี5ห่ ผ้า3 3ฝอย -ฝี5มะ ฝ่5ฝั 3พจน พจ5นี พช5ฉล -พช5รา +พ3ติ พท5ริ พทัก4 พน5ทะ @@ -1008,8 +1016,14 @@ พ้5ท้ 2พ์ พ์5ดี +ฟซ5ติ +ฟซ5ทิ +ฟร5ติ +ฟส5ติ +ฟส5ทิ 1ฟั 1ฟา +1ฟิ ฟิ4ลา ฟี5ฟ่ ฟู5ฟ่ @@ -1030,6 +1044,7 @@ ภิ5มห ภิ3ร ภิ5สม +ภี5ษม ภุ5ชง 1ภู ภู5ฏา @@ -1039,9 +1054,7 @@ ม4กษ ม1ข ม4ขล -ม1ค -ม4คค -ม4คอ +ม3คร มค5อิ 1มงคล มง5ฟอ @@ -1055,6 +1068,7 @@ มณ5พร มณ5เฑ มณ5เพ +มด5ชม มด5ยอ มด5ลู ม1ต @@ -1070,6 +1084,7 @@ มบ4พ ม1ป มป4ช +มป4ท มป5ฤด มป5ฤๅ ม4ป์ @@ -1084,17 +1099,17 @@ มย5รา 3มรร ม3รั -ม3ริ +ม1ริ มฤ5คิ มฤ5เค มล5ทิ +ม3ลา ม3ลิ ม3ล้ ม1ว มว5มอ ม4วล ม1ส -มส4เ มห5กร ม3หน มห5ภา @@ -1115,9 +1130,9 @@ 1มั ม4ั่ 1มา -มา4ก มา5ดร มา5นร +มา5นอ มา5ป่ มา5พจ มา5มก @@ -1160,6 +1175,7 @@ ม1โ ม1ไ ม4่า +ม้ม4 3ม้า ม์5ภิ ยก5ย่ @@ -1186,11 +1202,12 @@ ย1ย ยย4ส ยร5ถี -ย5รบั +ย5ร4บั ยล5ไท ยว5ข้ ยว5จ๊ ยว5ดอ +ย5วดี ยว5นี ยว5ย่ ยว5รั @@ -1213,6 +1230,7 @@ ยา5ณว ยา5ถ่ ยา5บร +ยา5รช ยา5สล ยา5สี ยา5ฬั @@ -1224,8 +1242,10 @@ 4ยุภ ยุ5แย ยุ5แห +ยู5คล ยู5ถิ ยู5ฟ่ +ยู5ยิ ยู5ริ ยู5ไน ย1เ @@ -1237,7 +1257,6 @@ ย์5หน 2รก รก5ซอ -รก5ซึ รก5ซ้ ร1กร รก5รา @@ -1246,6 +1265,11 @@ รง5พย รง5รอ รจ5ถร +ร1ช +ร4ชก +ร4ชช +ร4ชน +ร4ชย รณ5คด รณ5ตร รณ5ถั @@ -1277,7 +1301,6 @@ ร4บถ รบ5ถ้ ร4บม -ร4บั ร4บไ รบ5ไก ร1ป @@ -1295,7 +1318,6 @@ รร5คา รร5จถ รร5จว -รร5ชิ รร5ณึ รร5ถา รร5ยง @@ -1306,7 +1328,6 @@ รร5แส รร5ไก รร5ไต -รล5ออ รศ5นี รษ5ฐิ รษ5ตร @@ -1314,7 +1335,7 @@ ร4สก ร4สช ร4สเ -ร4สโ +ร4ส4โ ร3หิ ระ1 ระ5สา @@ -1338,7 +1359,6 @@ รำ5งั รำ5จว ริ5กอ -ริ5ซึ ริ5ตร ริ5ทึ 4ริพ @@ -1353,7 +1373,6 @@ รี5ดู รี5ตร รี5ตอ -รี5มู รี5รั รี5รา รี5ริ @@ -1418,11 +1437,11 @@ ลบ5ล้ ลบ5ไส ลป5ตอ +ลม5ค้ ลม5งว ล3มอ 2ลย ล1ล -ล4ล์ ล3วี ลว5ไห ลส5ไต @@ -1437,20 +1456,17 @@ ลา5บร ลา5ป๋ ลา5พอ -ลา5มี 3ลาร ลา5รอ ลา5ร้ ลา5ฤก ลา5ส้ +ลิ5กอ ลิ5ก่ ลิ5จู -ลิ5ซึ ลิ5ตอ ลิ5นอ ลิ5น่ -ลิ4บ -ลิ5บา ลิ5ฟอ ลิ5มู ลี5ตะ @@ -1464,9 +1480,10 @@ ลูก1 ลู5ซี ลู5ที -ลู5มิ +ลู3มิ ลู5ลอ ลู5ออ +ลู5แบ 2ล1เ 2ล1แ ล1โ @@ -1475,6 +1492,7 @@ ล่5หล ล่5ออ ล้5โพ +2ล์ ล์5สต ว3กร วก5ว่ @@ -1519,7 +1537,8 @@ วร5มณ วร5มห ว4รย -1วรร4 +วรร4 +3วรรณ ว4ร์ วล5ระ วส5ปอ @@ -1584,11 +1603,12 @@ ว้5ลา ว์5ลิ ศ1จ +ศต5วร ศน5อุ ศพิ4 3ศรี -ศ2วร ศษ5ซ้ +ศษ5วร ศษ5เก ศษ5เห 1ศั @@ -1628,10 +1648,10 @@ สข5บุ สง5ขล ส1ซ -ส5ดิก -ส5ดิน -ส5ดิภ -ส5ดิม +สด5ชื +ส4ดุ +ส5ดุภ +ส4ตท สต5ทิ ส3ตรา 2สต์ @@ -1643,8 +1663,8 @@ ส4นุ สนูป5 ส4ปา -สพ5ติ ส2ม +สม5คว สม5ดุ 3สมบ สม5ผส @@ -1662,7 +1682,6 @@ สล5บร สว4ก สว5ยม -ส4วร สว5ริ ส4วา 4สวิ @@ -1688,7 +1707,6 @@ 4สาธ สา5นึ สา5มน -สา5มี สา5วพ สำ5ออ สำ5โร @@ -1715,7 +1733,6 @@ สุ5คร สุ5นี สุ5บร -สุ5บิ สุ5ปร สุ5มน สุ5สง @@ -1725,7 +1742,6 @@ ส1เ ส4เฟ ส1โ -ส4โก ส4โค 3ส่ว ส่5ไค @@ -1753,6 +1769,7 @@ หา5พร หา5รื หา5ฤก +หา5วร หิ5รก หิ5ศว หุ5คู @@ -1788,12 +1805,12 @@ อง4คม อง5ถิ อง5บร -อง5บิ อง5ฟอ อง5ฟุ อง5ระ อง5อุ อง5อ้ +อด5ช่ อด5ถอ อด5น่ อด5ฝา @@ -1806,16 +1823,16 @@ อ3ดิ อต5ดอ อต5ด็ +อต5สว อต5ไว อ1ท อ4ทค อท5คอ อน5ง้ -อน5ดร +อน5จอ อน5ทำ อน5ผั อน5ฝู -อน5ฟิ อน5ย้ อ4นา อ4นุ1 @@ -1832,14 +1849,17 @@ อป5วา อป5โล อพ5ริ -อฟ5ฟิ อฟ5ฟี อฟ5ริ +อฟ5โร อฟ5ไล อ4ภั +อม5คล +อม5ค้ อม5ฎอ อม5ดอ อม5ถอ +อม5ฟอ อม5ยิ อม5รา อม5ร่ @@ -1856,7 +1876,6 @@ อย5อิ อ4ยา อย5ได -อร5ชุ อร5มน อ3รอ อ1รั @@ -1873,6 +1892,7 @@ อ1ลิ อว5รุ อศ5กร +อศ5คร อษ5ฐช อษ5ฐภ อส5กา @@ -1886,8 +1906,10 @@ อส5แอ อส5ไพ อ1ห +3ออน ออ5อว อะ5ธี +อะ5ฮั 1อั 1อา อา5ค5เ @@ -1915,6 +1937,7 @@ อิ5ดะ อิ5ระ อิ5ศว +อี5คิ อี5จู อี5ซู อี5ยิ @@ -1941,6 +1964,7 @@ อุ5ลก อุ5แว อู5คู +อู5มา อู5รา อู5ลา อ1เ @@ -1950,7 +1974,6 @@ อเห5ต อ1แ อ1โ -อโร3 อ1ไ 3อ่อ อ่5อว @@ -1961,6 +1984,7 @@ อ้5โล ฮก5ฮา ฮก5ฮื +ฮช5แท ฮน5รี ฮฟ5วี ฮล5ดิ @@ -1974,6 +1998,7 @@ ฮู5ลา ฮู5ล่ ฮ1เ +ฮ1โ ฮ่5กึ ะ1ก ะ1ข @@ -2017,6 +2042,7 @@ ัก3ล ัก5วิ ัก5ษร +ัก5ษอ ัก5อิ ัก5อี ัก5อ่ @@ -2040,12 +2066,12 @@ ัช5นี ัช5พย ัช5พื -ัช5รา ัช5ริ +ัช5สก ัช5สม -ัช5เร ัช5แพ ัช5โญ +ัช5โย ัญ1 ัฏ5ทุ ัฏ5สง @@ -2059,6 +2085,7 @@ ัณ5เฑ ัณ5โร ัด1 +ัด5รู ัต5ดึ ัต5ถล ัต5ถั @@ -2069,6 +2096,7 @@ ัต5รี ัต5ฤก ัต5ลั +ัต3ส ัต5หล ัต5หี ัท5คี @@ -2088,14 +2116,12 @@ ัน5ถธ ัน5ทึ ัน5ทุ -ัน5ท่ ัน4ธ ัน5ธา ัน5ธิ ัน5ผว ัน5ฝร ัน5ฝ่ -ัน5ภิ ัน5ยะ ัน5ย่ ับ1 @@ -2110,10 +2136,8 @@ ัพ5ยา ัพ5โพ ัพ5โห -ัฟ5ฟิ ัฟ5ริ ัม4ช -ัม5ลา ัม5หม ัย5มร ัย5รุ @@ -2121,7 +2145,6 @@ ัล5ปน ัล5ปพ ัล5ปิ -ัล5ฟิ ัล5มุ ัล5ออ ัล5ไซ @@ -2131,26 +2154,16 @@ ัศ5มี ัศ5เจ ัศ5ไน +ัส1 ัส5กา -ัส5ดง -ัส5ดน -ัส5ดี -ัส5ติ -ัส5ถา -ัส5ปู ัส5มั ัส5มิ -ัส5ยิ -ัส5รั -ัส5ลิ -ัส5วด -ัส5วร +ัส5วา าก5ถา าก5ฝร าก5ฝั า1กร -า5กรร -าก5รุ +า4ก5รุ า3กอ าก5ฮอ า3กี @@ -2169,7 +2182,6 @@ า5ครี าง5บำ าง5ฝี -าง5ฟิ าง5ออ าง5อิ า1จ @@ -2192,8 +2204,6 @@ าช5อง า1ชิ า3ชี -าช5เป -าช5เล าช5โอ า1ซ าญ5รอ @@ -2222,11 +2232,11 @@ าท5บร าท5สก าท5หล -า4ท์ า1ธ า4ธน า2ธย าธ5ยม +าธา1 าน5ญ่ าน5ผู าน5รว @@ -2251,18 +2261,20 @@ าพ5ลว าฟ5ต้ าฟ5ริ -า3ฟิ า1ภ า4ภป า4ภล าภ5ลอ +าม5คิ าม5ง่ าม4น4 +าม5นิ าม5สก าม2ห าม5หม าม5หล าม5หา +า3มี าย5กล าย5กอ าย5ขว @@ -2290,12 +2302,11 @@ าย5ไห าร5กำ าร3ค -าร5ชุ +า5รณะ าร5ณู าร5ตร า5รทะ าร5ธุ -าร5บั าร5ผจ าร5พร า5รภย @@ -2311,7 +2322,7 @@ า1ริ า5ริก า5ริยะ -า3รี +า1รี า1รุ า1ล า4ลก @@ -2328,7 +2339,6 @@ า4ลส าล5อุ า4ลโ -า4ล์ าว5ก่ าว5ข้ า3วดี @@ -2339,6 +2349,7 @@ าว5ยื า5วรณ าว5รภ +า5วรร าว5รา า5ว5รี าว5รุ @@ -2353,6 +2364,7 @@ าษ5รา าษ5แก าส5กา +าส5คอ าส5ด้ าส5ต้ าส5นี @@ -2379,7 +2391,6 @@ ำ1พ ำ1ม ำม5รง -ำม5ลา ำ1ร ำ1ล ำ1ส @@ -2414,10 +2425,11 @@ ิช4น ิช5ลิ ิ3ชิ -ิช5เช ิญ5หน ิญ5โญ ิด5ฉิ +ิด5ชอ +ิด5ชิ ิด5นี ิด5ผน ิด5รอ @@ -2431,8 +2443,10 @@ ิต5ลด ิต5ลา ิต5วส +ิต5สม ิ1ติ ิ3ตุ +ิท5คอ ิท5ธั ิท5สน ิ3ธี @@ -2461,6 +2475,7 @@ ิป5ผล ิ3ปร ิป5สต +ิป5สเ ิป5ฮอ ิป5โป ิป5โย @@ -2471,10 +2486,8 @@ ิฟ5ฟอ ิ1ภ ิม5ฝี -ิม5ลา ิ1มุ ิย5มิ -ิร5ชร ิร5วด ิ1รั ิ1รา @@ -2488,10 +2501,11 @@ ิว5ทร ิว5บิ ิว5ยอ +ิว5ยิ +ิ3วรร ิว5ริ ิว5ลิ ิว5ลึ -ิว5ออ ิวา5ส ิศ5พร ิศ5ร้ @@ -2503,6 +2517,7 @@ ิส5กี ิ5สตร ิส5ติ +ิส5ต้ ิส5ที ิส5นี ิส5บอ @@ -2526,23 +2541,27 @@ ีช5คณ ีซ5สถ ีด5ฆ่ +ี5ดิย ีต5กว ีต5ปฏ ี1ท ีท4น -ีบ5รั ีบ5รุ ีบ5ร้ ี1ป ี1พ ี4พจ +ี1ม ีย5กถ ีย5รย ีย5รอ ีย5ระ ีย5รั ี5ยวน +ีย5ไต ีร5ณั +ี3รี +ีรี5บ ีล5จุ ี4วั ีวา4 @@ -2572,10 +2591,13 @@ ี้5กร ี้5จ้ ี้5ตะ +ี้5ฟู ี้5ริ ี้5ลั ี้5ลุ ี๊5กร +ี๊5ด๊ +ี๊5ต่ ี๋5จ้ ี๋5อ๋ ึก5ซึ @@ -2600,7 +2622,6 @@ ือ5ตร ือ5ถื ือ5นำ -ือ5บิ ือ5ปล ือ5ปื ือ5ป่ @@ -2639,8 +2660,6 @@ ุง5ถุ ุจ5ลิ ุจ5หน -ุช5รา -ุช5เช ุญ5จน ุญ5ฤท ุญ5แจ @@ -2648,7 +2667,6 @@ ุฑ5พ่ ุณ5ค่ ุณ5ฑก -ุณสม5 ุณ5หญ ุณ5หา ุณ5หิ @@ -2664,6 +2682,7 @@ ุ5ตระ ุ5ตริ ุต5ลุ +ุต5ส่ ุ3ทก ุท5ธั ุ5ทริ @@ -2680,7 +2699,6 @@ ุป5กร ุป5จา ุป5ถั -ุป5ทา ุป5ยุ ุป3รา ุ5ปริ @@ -2724,10 +2742,12 @@ ุล5ชี ุล5ธิ ุล5มุ +ุล5วร ุล5สต ุล5สแ ุ3ลา ุ3ลิ +ุศ5เร ุศ5โล ุษ5จี ุษ5ฎี @@ -2799,6 +2819,7 @@ ู๋5อี เ2 เก5ยู +เก5รล เก5วั เก5ศว เก5อิ @@ -2810,6 +2831,7 @@ เ4จร เจ5ลิ เจ5โต +เจ5โร เซ5ทิ เซ5นอ เซ5รุ @@ -2838,7 +2860,7 @@ 4เนย เน5ระ เน5รั -เน4ส +เน2ส เน5สา เน5เว เบ5ต้ @@ -2859,7 +2881,10 @@ เภ5ทุ เม5ฆิ เม5ดิ -เม5ลา +เม5ลอ +เม5ล่ +เม4ส +เม5สุ เร5กอ เร5กะ เร5มอ @@ -2868,6 +2893,7 @@ เล5กร เล5คอ เล5ดี +เล5พอ เล5วร เล5วู เล5หล @@ -2897,8 +2923,6 @@ เอ5ฬก เฮ5ละ เฮ5ลิ -เฮ5โม -เฮ5โร แก5วั แค5รอ แค5ริ @@ -2906,19 +2930,21 @@ แค5ลิ แค5แต แค5แส -แช5บ๊ -แช5เช แซ5ยิ +แซ5หว แด5รี แต5แต แน2 แบ4ค +แบ5ริ แ4ปร 3แพท แฟ5รี แ4ฟ้ แม2 +แม5กา แม5ชี +แม5ริ แม5รี แม5เร แม่3 @@ -2941,18 +2967,20 @@ โค5ริ โค5ลอ โค5ลั +โค5ลี โค5ล่ โค5ออ โค5อะ โค5แท โค5ไซ โจ5ปก +โจ5อี โฉ5เบ +โช5ฎึ โช5ดึ โช5ห่ โซ5กร โซ5นี -โซ5ฟิ โซ5ยู โซ5ลู โซ5สเ @@ -2967,8 +2995,11 @@ โต5รา โต5ริ โต5ลิ +โต5สเ +โต5ไค โท5กร โท5คอ +โท5ดอ โท5พล โท5รอ โท5แอ @@ -2992,6 +3023,7 @@ โบ5ไฮ โป5กส โป5ลิ +โป5แต โป5แล โป5โป โป5โล @@ -3004,7 +3036,9 @@ โพ5แท โพ5ไซ โฟ5กร +โฟ5ตอ โฟ5นี +โฟ5ลิ โภ5คิ โภ5ไค โม5ฆี @@ -3016,15 +3050,19 @@ โร5กะ โร5คิ โร5งั -โร5ชิ โร5ธนะ +โร5พล +โร5ฟอ +โร5ฟี โร5รา +โร5ร่ โร5ล่ โรส4 โร5สเ โร5หน โร5อี โร5ฮิ +โร5ฮี โร5แม โร5ไล โล5กร @@ -3035,6 +3073,7 @@ โล5รา โล5วะ โล5หิ +โล5ไม โว5นอ โศ5ธน โศ5ภิ @@ -3042,8 +3081,8 @@ โส5ติ โส5ธน โส5ภิ +โส5รั โส5ลิ -โส5วร โส5หุ โส5โค โห5ฐา @@ -3059,7 +3098,6 @@ โอ5ละ โอ5สถ โอ5อิ -โฮ5โล 3ใช้ 1ให ไก5ลา @@ -3076,16 +3114,20 @@ ไซ5บอ ไซ5บี ไซ5ปร -ไซ5ออ +ไซ5รั +ไซ5แน ได5ฟุ ได5ฟู ได5ลิ ได5ออ +ไต5รี +ไท5กร ไท5ฟอ ไท5รอ ไท5แท ไป5ริ ไพ5ชย +ไพ5ทอ ไพ5ธอ ไพ5รั ไพ5ริ @@ -3107,6 +3149,7 @@ ไห5หม ไห5หล ไอ5กร +ไอ5คิ ไอ5ซี ไอ5ดอ ไอ5ติ @@ -3115,7 +3158,6 @@ ไอ5ศว ไอ5ศุ ไอ5ศู -ไอ5ออ ไฮ1 ็ก5ซี ็จ5ขบ @@ -3124,7 +3166,6 @@ ็ด5อร ็ด5อึ ็น5ฉ่ -็น5ทร ็น5รอ ็น5วู ็น5อย @@ -3156,6 +3197,7 @@ ่ว5ช้ ่ว5ถึ ่ว5ยว +่ว5ฮ้ ่ว5ไห ่อ5กร ่อ5กว @@ -3208,6 +3250,7 @@ ้น5ท้ ้น5รุ ้น5ร่ +้ม5คล ้ม5งว ้ม5ฉุ ้ม5น้ @@ -3276,7 +3319,9 @@ ์ค5สเ ์ค5แล ์ต5ไท +์4ทเ ์ท5ไท +์1น ์1บ ์1พ ์1ร @@ -3722,7 +3767,6 @@ ค6ตะ ร6ตะ สร7ตะ -า7มี มิ7ผ า7กิ า7กล @@ -3744,7 +3788,6 @@ ิ5ลี ุ5ลี า7ลี -โค7ลี โม7ลี ท7ลี ร7ลี @@ -3765,7 +3808,6 @@ เปรี6ยะ มโห5 ิ7รี -ี7รี ู7รี หา7รี ม7รี. @@ -4291,6 +4333,17 @@ เก6ตุ. ส7ตุ ลิ7บง -ฮ7โ 7อุ. -ิศ7รา} \ No newline at end of file +ิศ7รา +ษ7อร +ช6รา. +ด7ชะ +โบ7ริ +ป6ทา. +ล7มี +ม7คด +ี7สป +ร7ละ +ทส7ลา +ส7โซ +ซ7ฟี} \ No newline at end of file diff --git a/tex/context/patterns/mkiv/lang-agr.lua b/tex/context/patterns/mkiv/lang-agr.lua index 81f8e9ad5..311502a66 100644 --- a/tex/context/patterns/mkiv/lang-agr.lua +++ b/tex/context/patterns/mkiv/lang-agr.lua @@ -6,18 +6,35 @@ return { ["metadata"]={ ["mnemonic"]="agr", ["source"]="hyph-grc", - ["texcomment"]="% ****************************************************************\ -%\ -% File name: hyph-grc.tex\ -%\ -% Created: June 6, 2008\ -% Last modified: Sept. 12, 2011\ -%\ -% Unicode hyphenation patterns for Ancient Greek.\ -%\ -% Author: Dimitrios Filippou, (c) 2008-2011\ -% Licence: LaTeX Project Public Licence\ + ["texcomment"]="% title: Unicode hyphenation patterns for Ancient Greek.\ +% copyright: Dimitrios Filippou, (c) 2008-2016\ +% notice: >\ +% This file is part of the hyph-utf8 package.\ +% See http://www.hyphenation.org for more information.\ +% language:\ +% name: Ancient Greek\ +% tag: grc\ +% licence:\ +% name: LPPL\ +% url: http://www.latex-project.org/lppl/\ +% changes:\ +% -\ +% date: 2016-05-12\ +% author: Arthur Reutenauer\ +% description: added support for curly beta\ +% -\ +% date: 2011-09-12\ +% author: Dimitrios Filippou\ +% description: updated headers and added the LPPL licence statement\ +% -\ +% date: 2008-06-06\ +% author: Dimitrios Filippou\ +% description: removed guillemets (»)\ +% -\ +% date: 2008-05-27\ +% author: Dimitrios Filippou\ %\ +% ==========================================\ % This file was first created by mechanical translation from\ % GRAhyph5.tex via \"elhyph-utf8 -a -c\" (version 0.1 by Peter\ % Heslin -- p.j.heslin at durham dot ac dot uk). Some additions\ @@ -49,11 +66,11 @@ return { % ", }, ["patterns"]={ - ["characters"]="'ʼΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϲἀἁἂἃἄἅἆἇἐἑἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀὁὂὃὄὅὐὑὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾲᾳᾴᾶᾷ᾽᾿ῂῃῄῆῇῒΐῖῗῢΰῤῥῦῧῲῳῴῶῷ’", - ["data"]="α1 ε1 η1 ι1 ο1 υ1 ω1 ϊ1 ϋ1 ἀ1 ἁ1 ἂ1 ἃ1 ἄ1 ἅ1 ἆ1 ἇ1 ἐ1 ἑ1 ἒ1 ἓ1 ἔ1 ἕ1 ἠ1 ἡ1 ἢ1 ἣ1 ἤ1 ἥ1 ἦ1 ἧ1 ἰ1 ἱ1 ἲ1 ἳ1 ἴ1 ἵ1 ἶ1 ἷ1 ὀ1 ὁ1 ὂ1 ὃ1 ὄ1 ὅ1 ὐ1 ὑ1 ὒ1 ὓ1 ὔ1 ὕ1 ὖ1 ὗ1 ὠ1 ὡ1 ὢ1 ὣ1 ὤ1 ὥ1 ὦ1 ὧ1 ὰ1 ὲ1 ὴ1 ὶ1 ὸ1 ὺ1 ὼ1 ᾀ1 ᾁ1 ᾂ1 ᾃ1 ᾄ1 ᾅ1 ᾆ1 ᾇ1 ᾐ1 ᾑ1 ᾒ1 ᾓ1 ᾔ1 ᾕ1 ᾖ1 ᾗ1 ᾠ1 ᾡ1 ᾢ1 ᾣ1 ᾤ1 ᾥ1 ᾦ1 ᾧ1 ᾲ1 ᾳ1 ᾴ1 ᾶ1 ᾷ1 ῂ1 ῃ1 ῄ1 ῆ1 ῇ1 ῒ1 ῖ1 ῗ1 ῢ1 ῦ1 ῧ1 ῲ1 ῳ1 ῴ1 ῶ1 ῷ1 ά1 έ1 ή1 ί1 ό1 ύ1 ώ1 ΐ1 ΰ1 ά1 έ1 ή1 ί1 ό1 ύ1 ώ1 ΐ1 ΰ1 α2ι α2ί α2ί α2ὶ α2ῖ α2ἰ α2ἴ α2ἲ α2ἶ α2ἱ α2ἵ α2ἳ α2ἷ ά3ι ά3ι ᾶ3ι ἀ3ι ἁ3ι α2υ α2ύ α2ύ α2ὺ α2ῦ α2ὐ α2ὔ α2ὒ α2ὖ α2ὑ α2ὕ α2ὓ α2ὗ ά3υ ά3υ ᾶ3υ ἀ3υ ἁ3υ ε2ι ε2ί ε2ί ε2ὶ ε2ῖ ε2ἰ ε2ἴ ε2ἲ ε2ἶ ε2ἱ ε2ἵ ε2ἳ ε2ἷ έ3ι έ3ι ἐ3ι ἑ3ι ε2υ ε2ύ ε2ύ ε2ὺ ε2ῦ ε2ὐ ε2ὔ ε2ὒ ε2ὖ ε2ὑ ε2ὕ ε2ὓ ε2ὗ έ3υ έ3υ ἑ3υ ἐ3υ η2υ η2ύ η2ύ η2ὺ η2ῦ η2ὐ η2ὔ η2ὒ η2ὖ η2ὑ η2ὕ η2ὓ η2ὗ ή3υ ή3υ ῆ3υ ἠ3υ ἡ3υ ο2ι ο2ί ο2ί ο2ὶ ο2ῖ ο2ἰ ο2ἴ ο2ἲ ο2ἶ ο2ἱ ο2ἵ ο2ἳ ο2ἷ ό3ι ό3ι ὀ3ι ὁ3ι ο2υ ο2ύ ο2ύ ο2ὺ ο2ῦ ο2ὐ ο2ὔ ο2ὒ ο2ὖ ο2ὑ ο2ὕ ο2ὓ ο2ὗ ό3υ ό3υ ὀ3υ ὁ3υ υ2ι υ2ί υ2ί υ2ὶ υ2ῖ υ2ἰ υ2ἴ υ2ἲ υ2ἶ υ2ἱ υ2ἵ υ2ἳ υ2ἷ ύ3ι ύ3ι ῦ3ι ὐ3ι ὑ3ι ου3ι όυ4ι όυ4ι ὀυ4ι ὁυ4ι ο3υί ο3υί ο3υῖ 4β. 4γ. 4δ. 4ζ. 4θ. 4κ. 4λ. 4μ. 4ν. 4ξ. 4π. 4ρ. 4σ. 4ϲ. 4ς. 4τ. 4φ. 4χ. 4ψ. 4' 4ʼ 4᾿ 4β' 4βʼ 4β᾿ 4γ' 4γʼ 4γ᾿ 4δ' 4δʼ 4δ᾿ 4ζ' 4ζʼ 4ζ᾿ 4θ' 4θʼ 4θ᾿ 4κ' 4κʼ 4κ᾿ 4λ' 4λʼ 4λ᾿ 4μ' 4μʼ 4μ᾿ 4ν' 4νʼ 4ν᾿ 4ξ' 4ξʼ 4ξ᾿ 4π' 4πʼ 4π᾿ 4ρ' 4ρʼ 4ρ᾿ 4σ' 4σʼ 4σ᾿ 4ϲ' 4ϲʼ 4ϲ᾿ 4τ' 4τʼ 4τ᾿ 4φ' 4φʼ 4φ᾿ 4χ' 4χʼ 4χ᾿ 4ψ' 4ψʼ 4ψ᾿ .β4 .γ4 .δ4 .ζ4 .θ4 .κ4 .λ4 .μ4 .ν4 .ξ4 .π4 .ρ4 .σ4 .ϲ4 .τ4 .φ4 .χ4 .ψ4 2β1β 2γ1γ 2δ1δ 2ζ1ζ 2θ1θ 2κ1κ 2λ1λ 2μ1μ 2ν1ν 2π1π 2ρ1ρ 2ῤ1ῥ 2σ1σ 2ϲ1ϲ 2τ1τ 2φ1φ 2χ1χ 2ψ1ψ 2β1γ 2β1ζ 2β1θ 2β1κ 2β1ξ 2β1π 2β1σ 2β1ϲ 2β1τ 2β1φ 2β1χ 2β1ψ 2γ1β 2γ1ζ 2γ1θ 2γ1κ 2γ1ξ 2γ1π 2γ1σ 2γ1ϲ 2γ1τ 2γ1φ 2γ1χ 2γ1ψ 2δ1β 2δ1γ 2δ1ζ 2δ1θ 2δ1κ 2δ1λ 2δ1ξ 2δ1π 2δ1σ 2δ1ϲ 2δ1τ 2δ1φ 2δ1χ 2δ1ψ 2ζ1β 2ζ1γ 2ζ1δ 2ζ1θ 2ζ1κ 2ζ1λ 2ζ1μ 2ζ1ν 2ζ1ξ 2ζ1π 2ζ1ρ 2ζ1σ 2ζ1ϲ 2ζ1τ 2ζ1φ 2ζ1χ 2ζ1ψ 2θ1β 2θ1γ 2θ1δ 2θ1ζ 2θ1κ 2θ1ξ 2θ1π 2θ1σ 2θ1ϲ 2θ1τ 2θ1φ 2θ1χ 2θ1ψ 2κ1β 2κ1γ 2κ1δ 2κ1ζ 2κ1θ 2κ1ξ 2κ1π 2κ1σ 2κ1ϲ 2κ1φ 2κ1χ 2κ1ψ 2λ1β 2λ1γ 2λ1δ 2λ1ζ 2λ1θ 2λ1κ 2λ1μ 2λ1ν 2λ1ξ 2λ1π 2λ1ρ 2λ1σ 2λ1ϲ 2λ1τ 2λ1φ 2λ1χ 2λ1ψ 2μ1β 2μ1γ 2μ1δ 2μ1ζ 2μ1θ 2μ1κ 2μ1λ 2μ1ξ 2μ1π 2μ1ρ 2μ1σ 2μ1ϲ 2μ1τ 2μ1φ 2μ1χ 2μ1ψ 2ν1β 2ν1γ 2ν1δ 2ν1ζ 2ν1θ 2ν1κ 2ν1λ 2ν1μ 2ν1ξ 2ν1π 2ν1ρ 2ν1σ 2ν1ϲ 2νς. 2νϲ. 2ν1τ 2ν1φ 2ν1χ 2ν1ψ 2ξ1β 2ξ1γ 2ξ1δ 2ξ1ζ 2ξ1θ 2ξ1κ 2ξ1λ 2ξ1μ 2ξ1ν 2ξ1π 2ξ1ρ 2ξ1σ 2ξ1ϲ 2ξ1τ 2ξ1φ 2ξ1χ 2ξ1ψ 2π1β 2π1γ 2π1δ 2π1ζ 2π1θ 2π1κ 2π1ξ 2π1σ 2π1ϲ 2π1φ 2π1χ 2π1ψ 2ρ1β 2ρ1γ 2ρ1δ 2ρ1ζ 2ρ1θ 2ρ1κ 2ρ1λ 2ρ1μ 2ρ1ν 2ρ1ξ 2ρ1π 2ρ1σ 2ρ1ϲ 2ρ1τ 2ρ1φ 2ρ1χ 2ρ1ψ 2σ1δ 2ϲ1δ 2σ1ζ 2ϲ1ζ 2σ1λ 2ϲ1λ 2σ1ν 2ϲ1ν 2σ1ξ 2ϲ1ξ 2σ1ρ 2ϲ1ρ 2σ1ψ 2ϲ1ψ 2τ1β 2τ1γ 2τ1δ 2τ1ζ 2τ1θ 2τ1κ 2τ1ξ 2τ1π 2τ1σ 2τ1ϲ 2τ1φ 2τ1χ 2τ1ψ 2φ1β 2φ1γ 2φ1δ 2φ1ζ 2φ1κ 2φ1ξ 2φ1π 2φ1σ 2φ1ϲ 2φ1τ 2φ1χ 2φ1ψ 2χ1β 2χ1γ 2χ1δ 2χ1ζ 2χ1κ 2χ1ξ 2χ1π 2χ1σ 2χ1ϲ 2χ1τ 2χ1φ 2χ1ψ 2ψ1β 2ψ1γ 2ψ1δ 2ψ1ζ 2ψ1θ 2ψ1κ 2ψ1λ 2ψ1μ 2ψ1ν 2ψ1ξ 2ψ1π 2ψ1ρ 2ψ1σ 2ψ1ϲ 2ψ1τ 2ψ1φ 2ψ1χ 4βδ' 4βδ’ 4βδʼ 4βδ᾽ 4βδ᾿ 4βλ' 4βλ’ 4βλʼ 4βλ᾽ 4βλ᾿ 4βμ' 4βμ’ 4βμʼ 4βμ᾽ 4βμ᾿ 4βν' 4βν’ 4βνʼ 4βν᾽ 4βν᾿ 4βρ' 4βρ’ 4βρʼ 4βρ᾽ 4βρ᾿ 4γδ' 4γδ’ 4γδʼ 4γδ᾽ 4γδ᾿ 4γλ' 4γλ’ 4γλʼ 4γλ᾽ 4γλ᾿ 4γμ' 4γμ’ 4γμʼ 4γμ᾽ 4γμ᾿ 4γν' 4γν’ 4γνʼ 4γν᾽ 4γν᾿ 4γρ' 4γρ’ 4γρʼ 4γρ᾽ 4γρ᾿ 4δμ' 4δμ’ 4δμʼ 4δμ᾽ 4δμ᾿ 4δν' 4δν’ 4δνʼ 4δν᾽ 4δν᾿ 4δρ' 4δρ’ 4δρʼ 4δρ᾽ 4δρ᾿ 4ζβ' 4ζβ’ 4ζβʼ 4ζβ᾽ 4ζβ᾿ 4θλ' 4θλ’ 4θλʼ 4θλ᾽ 4θλ᾿ 4λμ' 4λμ’ 4λμʼ 4λμ᾽ 4λμ᾿ 4θν' 4θν’ 4θνʼ 4θν᾽ 4θν᾿ 4θρ' 4θρ’ 4θρʼ 4θρ᾽ 4θρ᾿ 4κλ' 4κλ’ 4κλʼ 4κλ᾽ 4κλ᾿ 4κμ' 4κμ’ 4κμʼ 4κμ᾽ 4κμ᾿ 4κν' 4κν’ 4κνʼ 4κν᾽ 4κν᾿ 4κρ' 4κρ’ 4κρʼ 4κρ᾽ 4κρ᾿ 4κτ' 4κτ’ 4κτʼ 4κτ᾽ 4κτ᾿ 4μν' 4μν’ 4μνʼ 4μν᾽ 4μν᾿ 4πλ' 4πλ’ 4πλʼ 4πλ᾽ 4πλ᾿ 4πμ' 4πμ’ 4πμʼ 4πμ᾽ 4πμ᾿ 4πν' 4πν’ 4πνʼ 4πν᾽ 4πν᾿ 4πρ' 4πρ’ 4πρʼ 4πρ᾽ 4πρ᾿ 4πτ' 4πτ’ 4πτʼ 4πτ᾽ 4πτ᾿ 4σβ' 4σβ’ 4σβʼ 4σβ᾽ 4σβ᾿ 4ϲβ' 4ϲβ’ 4ϲβʼ 4ϲβ᾽ 4ϲβ᾿ 4σγ' 4σγ’ 4σγʼ 4σγ᾽ 4σγ᾿ 4ϲγ' 4ϲγ’ 4ϲγʼ 4ϲγ᾽ 4ϲγ᾿ 4σδ' 4σδ’ 4σδʼ 4σδ᾽ 4σδ᾿ 4ϲδ' 4ϲδ’ 4ϲδʼ 4ϲδ᾽ 4ϲδ᾿ 4σθ' 4σθ’ 4σθʼ 4σθ᾽ 4σθ᾿ 4ϲθ' 4ϲθ’ 4ϲθʼ 4ϲθ᾽ 4ϲθ᾿ 4σκ' 4σκ’ 4σκʼ 4σκ᾽ 4σκ᾿ 4ϲκ' 4ϲκ’ 4ϲκʼ 4ϲκ᾽ 4ϲκ᾿ 4σμ' 4σμ’ 4σμʼ 4σμ᾽ 4σμ᾿ 4ϲμ' 4ϲμ’ 4ϲμʼ 4ϲμ᾽ 4ϲμ᾿ 4σπ' 4σπ’ 4σπʼ 4σπ᾽ 4σπ᾿ 4ϲπ' 4ϲπ’ 4ϲπʼ 4ϲπ᾽ 4ϲπ᾿ 4στ' 4στ’ 4στʼ 4στ᾽ 4στ᾿ 4ϲτ' 4ϲτ’ 4ϲτʼ 4ϲτ᾽ 4ϲτ᾿ 4σφ' 4σφ’ 4σφʼ 4σφ᾽ 4σφ᾿ 4ϲφ' 4ϲφ’ 4ϲφʼ 4ϲφ᾽ 4ϲφ᾿ 4σχ' 4σχ’ 4σχʼ 4σχ᾽ 4σχ᾿ 4ϲχ' 4ϲχ’ 4ϲχʼ 4ϲχ᾽ 4ϲχ᾿ 4φθ' 4φθ’ 4φθʼ 4φθ᾽ 4φθ᾿ 4φλ' 4φλ’ 4φλʼ 4φλ᾽ 4φλ᾿ 4φμ' 4φμ’ 4φμʼ 4φμ᾽ 4φμ᾿ 4φν' 4φν’ 4φνʼ 4φν᾽ 4φν᾿ 4φρ' 4φρ’ 4φρʼ 4φρ᾽ 4φρ᾿ 4χθ' 4χθ’ 4χθʼ 4χθ᾽ 4χθ᾿ 4χλ' 4χλ’ 4χλʼ 4χλ᾽ 4χλ᾿ 4χμ' 4χμ’ 4χμʼ 4χμ᾽ 4χμ᾿ 4χν' 4χν’ 4χνʼ 4χν᾽ 4χν᾿ 4χρ' 4χρ’ 4χρʼ 4χρ᾽ 4χρ᾿ ἀγω2ν1άρ ἀγω2ν1άρ ἀγω2ν1αρ ἀδιέ2ξ1 ἀδιέ2ξ1 ἀδιε2ξ1 ἀδυ2σ1ώ ἀδυ2σ1ώ ἀδυ2ϲ1ώ ἀδυ2ϲ1ώ ἀδυ2σ1ω ἀδυ2ϲ1ω ἁλό2σ1 ἁλό2σ1 ἁλό2ϲ1 ἁλό2ϲ1 ἁλο2σ1 ἁλο2ϲ1 ἀμπαλί2ν1 ἀμπαλί2ν1 ἀμπαλι2ν1 ἀμφί2σ1β ἀμφί2σ1β ἀμφί2ϲ1β ἀμφί2ϲ1β ἀμφι2σ1β ἀμφι2ϲ1β ἀμφί2σ1ω ἀμφί2σ1ω ἀμφί2ϲ1ω ἀμφί2ϲ1ω ἀμφι2σ1ώ ἀμφι2σ1ώ ἀμφι2ϲ1ώ ἀμφι2ϲ1ώ ἀ2ν1αγής. ἀ2ν1αγής. ἀ2ν1αγήϲ. ἀ2ν1αγήϲ. ἀ2ν1αγὴς. ἀ2ν1αγὴϲ. ἀ2ν1αγήσ. ἀ2ν1αγήσ. ἀ2ν1αγὴσ. ἀ2ν1αγο ἀ2ν1αγεῖ. ἀ2ν1αγῆ. ἀ2ν1αγές. ἀ2ν1αγές. ἀ2ν1αγέϲ. ἀ2ν1αγέϲ. ἀ2ν1αγὲς. ἀ2ν1αγὲϲ. ἀ2ν1αγέσ. ἀ2ν1αγέσ. ἀ2ν1αγὲσ. ἀ2ν1αγεῖς. ἀ2ν1αγεῖϲ. ἀ2ν1αγεῖσ. ἀ2ν1αγῶν. ἀ2ν1αγέσι ἀ2ν1αγέσι ἀ2ν1αγέϲι ἀ2ν1αγέϲι ἀ2ν1αγῆ ἀ2ν1άγκυ ἀ2ν1άγκυ ἀ2ν1αγκύ ἀ2ν1αγκύ ἄ2ν1αγν ἀ2ν1άγν ἀ2ν1άγν ἀ2ν1αγν ἀ3ν2αγνά ἀ3ν2αγνά ἀ3ν2αγνω ἀ3ν2άγνω ἀ3ν2άγνω ἀ3ν2αγνώ ἀ3ν2αγνώ ἀ2ν1αγρί ἀ2ν1αγρί ἀ2ν1αγρῖ ἀ2ν1αγρι ἀ2ν1άγωγ ἀ2ν1άγωγ ἀ2ν1αγώγ ἀ2ν1αγώγ ἀ3ν2αγώγι ἀ3ν2αγώγι ἀ3ν2αγωγί ἀ3ν2αγωγί ἀ4ν3αγωγία ἀ4ν3αγωγία ἀ2ν1άδελ ἀ2ν1άδελ ἀ2ν1αδέλ ἀ2ν1αδέλ ἀ2ν1άελπ ἀ2ν1άελπ ἀ2ν1αέλπ ἀ2ν1αέλπ ἄ2ν1αθλ ἀ2ν1άθλ ἀ2ν1άθλ ἀ2ν1αίδ ἀ2ν1αίδ ἀ2ν1αιδ ἄ2ν1αιμ ἀ2ν1αίμ ἀ2ν1αίμ ἀ2ν1αιμ ἀ2ν1αίσθ ἀ2ν1αίσθ ἀ2ν1αίϲθ ἀ2ν1αίϲθ ἀ2ν1αισθ ἀ2ν1αιϲθ ἀ2ν1αισι ἀ2ν1αιϲι ἀ2ν1αισί ἀ2ν1αισί ἀ2ν1αιϲί ἀ2ν1αιϲί ἀ2ν1αίσχ ἀ2ν1αίσχ ἀ2ν1αίϲχ ἀ2ν1αίϲχ ἀ2ν1αισχ ἀ2ν1αιϲχ ἀ2ν1αίτ ἀ2ν1αίτ ἀ2ν1αιτ ἀ2ν1άκαν ἀ2ν1άκαν ἀ2ν1ακάν ἀ2ν1ακάν ἀ2ν1ακόλο ἀ2ν1ακόλο ἀ2ν1ακολο ἀ2ν1αλγ ἀ2ν1αλδ ἀ3ν2αλδα ἀ3ν2αλδήσκ ἀ3ν2αλδήσκ ἀ3ν2αλδήϲκ ἀ3ν2αλδήϲκ ἀ2ν1άλειπ ἀ2ν1άλειπ ἀ2ν1αλείπ ἀ2ν1αλείπ ἀ2ν1αλειφ ἀ2ν1άλειφ ἀ2ν1άλειφ ἀ2ν1αλείφ ἀ2ν1αλείφ ἀ2ν1αλήθ ἀ2ν1αλήθ ἀ2ν1αληθ ἀ2ν1άλθ ἀ2ν1άλθ ἀ2ν1αλθ ἀ2ν1άλιπ ἀ2ν1άλιπ ἀ2ν1αλίπ ἀ2ν1αλίπ ἀ2ν1άλιστ ἀ2ν1άλιστ ἀ2ν1άλιϲτ ἀ2ν1άλιϲτ ἀ2ν1αλίστ ἀ2ν1αλίστ ἀ2ν1αλίϲτ ἀ2ν1αλίϲτ ἀ2ν1αλκ ἄ2ν1αλκ ἀ2ν1άλκ ἀ2ν1άλκ ἀ2ν1άλλ ἀ2ν1άλλ ἀ2ν1αλλ ἀ3ν2άλλο ἀ3ν2άλλο ἀ3ν2άλλε ἀ3ν2άλλε ἄ2ν1αλμ ἀ2ν1άλμ ἀ2ν1άλμ ἀ2ν1αλμ ἄ2ν1αλο ἀ2ν1άλου ἀ2ν1άλου ἀ2ν1άλῳ. ἀ2ν1άλῳ. ἄ2ν1αλε. ἀ2ν1άλοι ἀ2ν1άλοι ἀ2ν1άλων. ἀ2ν1άλων. ἄ2ν1αλτ ἀ2ν1άλτ ἀ2ν1άλτ ἀ2ν1αμάξ ἀ2ν1αμάξ ἀ2ν1αμαξ ἀ2ν1αμάρτ ἀ2ν1αμάρτ ἀ2ν1αμαρτ ἀ2ν1αμέλγ ἀ2ν1αμέλγ ἀ2ν1αμελγ ἀ2ν1αμπ ἀ2ν1άμπ ἀ2ν1άμπ ἀ2ν1αμφ ἀναμφι2σ1 ἀναμφι2ϲ1 ἀ2ν1ανάγκ ἀ2ν1ανάγκ ἀ2ν1αναγκ ἄ2ν1ανδ ἀ2ν1άνδ ἀ2ν1άνδ ἀ2ν1ανθ ἀ3ν2ανθέ ἀ3ν2ανθέ ἀ4ν3ανθές. ἀ4ν3ανθές. ἀ4ν3ανθέϲ. ἀ4ν3ανθέϲ. ἀ4ν3ανθὲς. ἀ4ν3ανθὲϲ. ἀ4ν3ανθέσ. ἀ4ν3ανθέσ. ἀ4ν3ανθὲσ. ἀ4ν3ανθέσι ἀ4ν3ανθέσι ἀ4ν3ανθέϲι ἀ4ν3ανθέϲι ἀ2ν1άνιο ἀ2ν1άνιο ἀ2ν1ανίο ἀ2ν1ανίο ἀ2ν1ανίω ἀ2ν1ανίω ἀ2ν1ανταγ ἀ2ν1ανταπ ἀ2ν1αντί ἀ2ν1αντί ἀ2ν1αντι ἀνα2ξ1αγ ἀνά2ξ1αν ἀνά2ξ1αν ἀνα2ξ1άν ἀνα2ξ1άν ἀνα2ξ1αν ἀνά2ξ1αρ ἀνά2ξ1αρ ἀνα2ξ1άρ ἀνα2ξ1άρ ἀνά2ξ1ιπ ἀνά2ξ1ιπ ἀνα2ξ1ίπ ἀνα2ξ1ίπ ἀ2ν1αξιόλ ἀ2ν1αξιόλ ἀ2ν1αξιολ ἀ2ν1αξιόπ ἀ2ν1αξιόπ ἀ2ν1αξιοπ ἀ2ν1άξιο ἀ2ν1άξιο ἀ2ν1αξίο ἀ2ν1αξίο ἀ2ν1αξίω ἀ2ν1αξίω ἀ2ν1αξία ἀ2ν1αξία ἀ2ν1αξῖα ἀ2ν1απάλλα ἀ2ν1απάλλα ἀ2ν1απαλλά ἀ2ν1απαλλά ἀ2ν1απάρτ ἀ2ν1απάρτ ἀ2ν1απαρτ ἀ2ν1απαύδ ἀ2ν1απαύδ ἀ2ν1απαυδ ἀ2ν1απόβ ἀ2ν1απόβ ἀ2ν1αποβ ἀ2ν1απόγ ἀ2ν1απόγ ἀ2ν1απογ ἀ2ν1αποδή ἀ2ν1αποδή ἀ2ν1αποδη ἀ2ν1απόδο ἀ2ν1απόδο ἀ2ν1αποδό ἀ2ν1αποδό ἀ2ν1απόδρ ἀ2ν1απόδρ ἀ2ν1αποδρ ἀ2ν1απόλαυ ἀ2ν1απόλαυ ἀ2ν1απολαύ ἀ2ν1απολαύ ἀ2ν1απολό ἀ2ν1απολό ἀ2ν1απολο ἀ2ν1απόλυ ἀ2ν1απόλυ ἀ2ν1απολύ ἀ2ν1απολύ ἀ2ν1απόν ἀ2ν1απόν ἀ2ν1απον ἀ2ν1απόπ ἀ2ν1απόπ ἀ2ν1αποπ ἀ2ν1απόσ ἀ2ν1απόσ ἀ2ν1απόϲ ἀ2ν1απόϲ ἀ2ν1αποσ ἀ2ν1αποϲ ἀ2ν1απότε ἀ2ν1απότε ἀ2ν1αποτε ἀ2ν1απότμ ἀ2ν1απότμ ἀ2ν1αποτμ ἀ2ν1απότρ ἀ2ν1απότρ ἀ2ν1αποτρ ἀ2ν1αρά ἀ2ν1αρά ἀ2ν1αρα ἀ2ν1άρ ἀ2ν1άρ ἀ2ν1αρ ἄ2ν1αρ ἀ3ν2αρίτ ἀ3ν2αρίτ ἀ3ν2αρῖτ ἀ3ν2αριτ ἀ3ν2αρπ ἀ3ν2άρρ ἀ3ν2άρρ ἀ3ν2αρρ ἀ4ν3αρραγ ἀ3ν2αρτ ἀ3ν2αρύτ ἀ3ν2αρύτ ἀ2ν1άσκη ἀ2ν1άσκη ἀ2ν1άϲκη ἀ2ν1άϲκη ἀ2ν1ασκή ἀ2ν1ασκή ἀ2ν1αϲκή ἀ2ν1αϲκή ἄ2ν1ασπι ἄ2ν1αϲπι ἀ2ν1ασπί ἀ2ν1ασπί ἀ2ν1αϲπί ἀ2ν1αϲπί ἀ2ν1άσσατ ἀ2ν1άσσατ ἀ2ν1άϲϲατ ἀ2ν1άϲϲατ ἀ2ν1ασσάτ ἀ2ν1ασσάτ ἀ2ν1αϲϲάτ ἀ2ν1αϲϲάτ ἀ2ν1άστει ἀ2ν1άστει ἀ2ν1άϲτει ἀ2ν1άϲτει ἀ2ν1αστεί ἀ2ν1αστεί ἀ2ν1αϲτεί ἀ2ν1αϲτεί ἀ3ν2αστείβ ἀ3ν2αστείβ ἀ3ν2αϲτείβ ἀ3ν2αϲτείβ ἀ3ν2άστειρ ἀ3ν2άστειρ ἀ3ν2άϲτειρ ἀ3ν2άϲτειρ ἀ3ν2αστείρ ἀ3ν2αστείρ ἀ3ν2αϲτείρ ἀ3ν2αϲτείρ ἀ3ν2άστειχ ἀ3ν2άστειχ ἀ3ν2άϲτειχ ἀ3ν2άϲτειχ ἀ3ν2αστείχ ἀ3ν2αστείχ ἀ3ν2αϲτείχ ἀ3ν2αϲτείχ ἀ2ν1ατεὶ. ἀ2ν1ατεί. ἀ2ν1ατεί. ἀ2ν1ατὶ. ἀ2ν1ατί. ἀ2ν1ατί. ἄ2ν1ατος. ἄ2ν1ατοϲ. ἄ2ν1ατοσ. ἀ2ν1άτου. ἀ2ν1άτου. ἀ2ν1άτω ἀ2ν1άτω ἄ2ν1ατον. ἄ2ν1ατε ἄ2ν1ατοι. ἀ2ν1άτοις. ἀ2ν1άτοις. ἀ2ν1άτοιϲ. ἀ2ν1άτοιϲ. ἀ2ν1άτοισ. ἀ2ν1άτοισ. ἀ2ν1άττ ἀ2ν1άττ ἀ2ν1αττ ἀ2ν1αύγ ἀ2ν1αύγ ἀ2ν1αυγ ἀ2ν1αύδ ἀ2ν1αύδ ἀ2ν1αυδ ἀ3ν2αυδί ἀ3ν2αυδί ἀ3ν2αυδι ἄ2ν1αυδ ἄ2ν1αυλ ἀ2ν1αύλ ἀ2ν1αύλ ἀ2ν1αύξ ἀ2ν1αύξ ἀ2ν1αυξ ἀ2ν1αύχ ἀ2ν1αύχ ἀ2ν1αυχ ἀ2ν1αφαίρ ἀ2ν1αφαίρ ἀ2ν1αφαιρ ἀ2ν1αφή ἀ2ν1αφή ἀ2ν1αφὴ ἀ2ν1αφοῦ ἀ2ν1αφῆ ἀ2ν1αφεῖ ἀ2ν1αφοῖ ἀ2ν1εφῶν. ἀ2ν1αφέ ἀ2ν1αφέ ἀ2ν1αφὲ ἀ3ν2αφῆν ἀ2ν1αφρόδ ἀ2ν1αφρόδ ἀ2ν1αφροδ ἄ2ν1αφρ ἀ2ν1άφρ ἀ2ν1άφρ ἀ2ν1αχύρ ἀ2ν1αχύρ ἀ2ν1αχυρ ἀνδρό2σ1α ἀνδρό2σ1α ἀνδρό2ϲ1α ἀνδρό2ϲ1α ἀνδρο2σ1α ἀνδρο2ϲ1α ἀ2ν1έγγ ἀ2ν1έγγ ἀ2ν1εγγ ἀ2ν1έγερτ ἀ2ν1έγερτ ἀ2ν1εγέρτ ἀ2ν1εγέρτ ἀ2ν1εγκ ἀ2ν1έγκ ἀ2ν1έγκ ἀ2ν1εγχ ἀ2ν1εδά ἀ2ν1εδά ἀ2ν1εδα ἀ2ν1έδεσ ἀ2ν1έδεσ ἀ2ν1έδεϲ ἀ2ν1έδεϲ ἀ2ν1εδέσ ἀ2ν1εδέσ ἀ2ν1εδέϲ ἀ2ν1εδέϲ ἀ2ν1έδρασ ἀ2ν1έδρασ ἀ2ν1έδραϲ ἀ2ν1έδραϲ ἀ2ν1εδράσ ἀ2ν1εδράσ ἀ2ν1εδράϲ ἀ2ν1εδράϲ ἀ2ν1εέρ ἀ2ν1εέρ ἀ2ν1εερ ἀ2ν1εθέλ ἀ2ν1εθέλ ἀ2ν1εθελ ἀ2ν1έθι ἀ2ν1έθι ἀ2ν1εθί ἀ2ν1εθί ἀ2ν1είδε ἀ2ν1είδε ἀ2ν1ειδέ ἀ2ν1ειδέ ἀ2ν1είδω ἀ2ν1είδω ἀ2ν1ειδώ ἀ2ν1ειδώ ἀ2ν1είκα ἀ2ν1είκα ἀ2ν1εικά ἀ2ν1εικά ἀ2ν1εικό ἀ2ν1εικό ἀ2ν1εικο ἀ2ν1ειλεί ἀ2ν1ειλεί ἀ2ν1ειλει ἀ2ν1είμα ἀ2ν1είμα ἀ2ν1εί2σ1ακ ἀ2ν1εί2σ1ακ ἀ2ν1εί2ϲ1ακ ἀ2ν1εί2ϲ1ακ ἀ2ν1ει2σ1άκ ἀ2ν1ει2σ1άκ ἀ2ν1ει2ϲ1άκ ἀ2ν1ει2ϲ1άκ ἀ2ν1εί2σ1ο ἀ2ν1εί2σ1ο ἀ2ν1εί2ϲ1ο ἀ2ν1εί2ϲ1ο ἀ2ν1ει2σ1ό ἀ2ν1ει2σ1ό ἀ2ν1ει2ϲ1ό ἀ2ν1ει2ϲ1ό ἀ2ν1ει2σ1φορ ἀ2ν1ει2ϲ1φορ ἀ2ν1εί2σ1φορ ἀ2ν1εί2σ1φορ ἀ2ν1εί2ϲ1φορ ἀ2ν1εί2ϲ1φορ ἀ2ν1ει2σ1φόρ ἀ2ν1ει2σ1φόρ ἀ2ν1ει2ϲ1φόρ ἀ2ν1ει2ϲ1φόρ ἀ2ν1έκ ἀ2ν1έκ ἀ2ν1εκ ἀ3ν2έκα ἀ3ν2έκα ἀ3ν2εκάς. ἀ3ν2εκάς. ἀ3ν2εκάϲ. ἀ3ν2εκάϲ. ἀ3ν2εκὰς. ἀ3ν2εκὰϲ. ἀ3ν2εκάσ. ἀ3ν2εκάσ. ἀ3ν2εκὰσ. ἀ3ν2εκτ ἀ4ν3έ2κ1τιτ ἀ4ν3έ2κ1τιτ ἀ4ν3ε2κ1τίτ ἀ4ν3ε2κ1τίτ ἀνε2κ1λιπ ἀνε2κ1λό ἀνε2κ1λό ἀνε2κ1λο ἀ2ν1έλαι ἀ2ν1έλαι ἀ2ν1ελαι ἀ2ν1ελάτ ἀ2ν1ελάτ ἀ2ν1ελατ ἀ2ν1έλεγκ ἀ2ν1έλεγκ ἀ2ν1ελέγκ ἀ2ν1ελέγκ ἀ2ν1ελεγξ ἀ2ν1ελέη ἀ2ν1ελέη ἀ2ν1ελεή ἀ2ν1ελεή ἀ2ν1έλεο ἀ2ν1έλεο ἀ2ν1ελέο ἀ2ν1ελέο ἀ2ν1ελέω ἀ2ν1ελέω ἀ2ν1έλεε ἀ2ν1έλεε ἀ2ν1ελκή ἀ2ν1ελκή ἀ2ν1ελκὴ ἀ2ν1ελκο ἀ2ν1ελκῆ ἀ2ν1ελκές. ἀ2ν1ελκές. ἀ2ν1ελκέϲ. ἀ2ν1ελκέϲ. ἀ2ν1ελκὲς. ἀ2ν1ελκὲϲ. ἀ2ν1ελκέσ. ἀ2ν1ελκέσ. ἀ2ν1ελκὲσ. ἀ2ν1ελκε ἀ2ν1ελκῶ ἀ2ν1ελκέσ ἀ2ν1ελκέσ ἀ2ν1ελκέϲ ἀ2ν1ελκέϲ ἄ2ν1ελκτ ἀ2ν1έλκτ ἀ2ν1έλκτ ἀ2ν1έλκω ἀ2ν1έλκω ἀ2ν1ελκώ ἀ2ν1ελκώ ἀ2ν1έλλ ἀ2ν1έλλ ἀ2ν1έλπι ἀ2ν1έλπι ἀ2ν1ελπί ἀ2ν1ελπί ἀ2ν1έλυτρ ἀ2ν1έλυτρ ἀ2ν1ελύτρ ἀ2ν1ελύτρ ἀ2ν1έμβ ἀ2ν1έμβ ἀ2ν1εμβ ἀ2ν1έμετ ἀ2ν1έμετ ἀ2ν1εμέτ ἀ2ν1εμέτ ἀ2ν1έμπ ἀ2ν1έμπ ἀ2ν1εμπ ἀ2ν1έμφ ἀ2ν1έμφ ἀ2ν1εμφ ἀ2ν1έν ἀ2ν1έν ἀ2ν1εν ἀ3ν2ένει ἀ3ν2ένει ἀ3ν2ενή ἀ3ν2ενή ἀ3ν2έντες. ἀ3ν2έντες. ἀ3ν2έντεϲ. ἀ3ν2έντεϲ. ἀ3ν2έντεσ. ἀ3ν2έντεσ. ἀ2ν1ε2ξ1 ἀ3ν2ε3ξ2ίκα ἀ3ν2ε3ξ2ίκα ἀ3ν2ε3ξ2ικά ἀ3ν2ε3ξ2ικά ἀ2ν1έορ ἀ2ν1έορ ἀ2ν1εόρ ἀ2ν1εόρ ἀ2ν1επ ἀ3ν2επν ἀ3ν2επτ ἀ2ν1εραστ ἀ2ν1εραϲτ ἀ2ν1έραστ ἀ2ν1έραστ ἀ2ν1έραϲτ ἀ2ν1έραϲτ ἀ2ν1εράστ ἀ2ν1εράστ ἀ2ν1εράϲτ ἀ2ν1εράϲτ ἀ2ν1εργ ἄ2ν1εργ ἀ2ν1έργ ἀ2ν1έργ ἀ2ν1έρεικ ἀ2ν1έρεικ ἀ2ν1ερείκ ἀ2ν1ερείκ ἀ2ν1έρεισ ἀ2ν1έρεισ ἀ2ν1έρειϲ ἀ2ν1έρειϲ ἀ2ν1ερείσ ἀ2ν1ερείσ ἀ2ν1ερείϲ ἀ2ν1ερείϲ ἀ2ν1ερεύνητ ἀ2ν1ερεύνητ ἀ2ν1ερευνήτ ἀ2ν1ερευνήτ ἀ2ν1ερί ἀ2ν1ερί ἀ2ν1ερι ἀ2ν1ερυθρίαστ ἀ2ν1ερυθρίαστ ἀ2ν1ερυθρίαϲτ ἀ2ν1ερυθρίαϲτ ἀ2ν1ερυθριάστ ἀ2ν1ερυθριάστ ἀ2ν1ερυθριάϲτ ἀ2ν1ερυθριάϲτ ἀ2ν1έστι ἀ2ν1έστι ἀ2ν1έϲτι ἀ2ν1έϲτι ἀ2ν1εστί ἀ2ν1εστί ἀ2ν1εϲτί ἀ2ν1εϲτί ἀ2ν1έται ἀ2ν1έται ἀ2ν1εταί ἀ2ν1εταί ἀ2ν1έτοι ἀ2ν1έτοι ἀ2ν1ετοί ἀ2ν1ετοί ἀ2ν1ετυ ἀ2ν1έτυ ἀ2ν1έτυ ἀ2ν1ετύ ἀ2ν1ετύ ἀ2ν1εύθ ἀ2ν1εύθ ἀ2ν1ευθ ἄ2ν1ευκ ἀ2ν1εύκ ἀ2ν1εύκ ἀ2ν1ευλ ἀ2ν1εύρετ ἀ2ν1εύρετ ἀ2ν1ευρέτ ἀ2ν1ευρέτ ἀ2ν1ευφήμητ ἀ2ν1ευφήμητ ἀ2ν1ευφημήτ ἀ2ν1ευφημήτ ἀ2ν1εύχ ἀ2ν1εύχ ἀ2ν1ευχ ἀ2ν1εύξ ἀ2ν1εύξ ἀ2ν1ευξ ἀ2ν1ηυξ ἀ2ν1ηῦγ ἀ2ν1ηυγ ἀ2ν1ευκτ ἀ2ν1έφ ἀ2ν1έφ ἀ2ν1εφ ἀ3ν2εφάλ ἀ3ν2εφάλ ἀ3ν2έφελ ἀ3ν2έφελ ἀ3ν2εφέλ ἀ3ν2εφέλ ἀ2ν1εχέ ἀ2ν1εχέ ἀ2ν1εχε ἀ2ν1έψα ἀ2ν1έψα ἀ2ν1εψά ἀ2ν1εψά ἀ2ν1ηγεμ ἀ2ν1ήδ ἀ2ν1ήδ ἀ2ν1ηδ ἀ2ν1ήκεσ ἀ2ν1ήκεσ ἀ2ν1ήκεϲ ἀ2ν1ήκεϲ ἀ2ν1ηκέσ ἀ2ν1ηκέσ ἀ2ν1ηκέϲ ἀ2ν1ηκέϲ ἀ2ν1ήκο ἀ2ν1ήκο ἀ2ν1ηκό ἀ2ν1ηκό ἀ2ν1ηκο ἀ2ν1ηλάκ ἀ2ν1ηλάκ ἀ2ν1ηλακ ἀ2ν1ήλατος. ἀ2ν1ήλατος. ἀ2ν1ήλατοϲ. ἀ2ν1ήλατοϲ. ἀ2ν1ήλατοσ. ἀ2ν1ήλατοσ. ἀ2ν1ηλάτου ἀ2ν1ηλάτου ἀ2ν1ηλάτω ἀ2ν1ηλάτω ἀ2ν1ήλατον. ἀ2ν1ήλατον. ἀ2ν1ήλατε. ἀ2ν1ήλατε. ἀ2ν1ηλάτοι ἀ2ν1ηλάτοι ἀ2ν1ήλατοι ἀ2ν1ήλατοι ἀ2ν1ήλατα ἀ2ν1ήλατα ἀ2ν1ηλεγ ἀ2ν1ηλεή ἀ2ν1ηλεή ἀ2ν1ηλεὴ ἀ2ν1ηλεο ἀ2ν1ηλεε ἀ2ν1ηλεῶ ἀ2ν1ηλεέ ἀ2ν1ηλεέ ἀ2ν1ηλεὲ ἀ2ν1ηλεῆ ἀ2ν1ηλέη ἀ2ν1ηλέη ἀ2ν1ήλειπ ἀ2ν1ήλειπ ἀ2ν1ηλείπ ἀ2ν1ηλείπ ἀ2ν1ηλή ἀ2ν1ηλή ἀ2ν1ηλὴ ἀ2ν1ηλοῦ ἀ2ν1ηλεῖ ἀ2ν1ηλῆ ἀ2ν1ηλέ ἀ2ν1ηλέ ἀ2ν1ηλὲ ἀ2ν1ηλοῖ ἀ2ν1ηλῶ ἀ2ν1ήλικ ἀ2ν1ήλικ ἀ2ν1ηλίκ ἀ2ν1ηλίκ ἀ2ν1ήλιο ἀ2ν1ήλιο ἀ2ν1ηλίο ἀ2ν1ηλίο ἀ2ν1ηλίω ἀ2ν1ηλίω ἀ2ν1ήλια ἀ2ν1ήλια ἀ2ν1ήλιπ ἀ2ν1ήλιπ ἀ2ν1ηλίπ ἀ2ν1ηλίπ ἀ2ν1ηλιφ ἀ2ν1ήμ ἀ2ν1ήμ ἀ2ν1ημ ἀ2ν1ήνυ ἀ2ν1ήνυ ἀ2ν1ηνύ ἀ2ν1ηνύ ἀ2ν1ήρει ἀ2ν1ήρει ἀ2ν1ηρεί ἀ2ν1ηρεί ἀ2ν1ηρέμ ἀ2ν1ηρέμ ἀ2ν1ηρεμ ἀ2ν1ηρεφ ἀ2ν1ήρι ἀ2ν1ήρι ἀ2ν1ηρί ἀ2ν1ηρί ἀ2ν1ήροτ ἀ2ν1ήροτ ἀ2ν1ηρότ ἀ2ν1ηρότ ἀ2ν1ήσσ ἀ2ν1ήσσ ἀ2ν1ήϲϲ ἀ2ν1ήϲϲ ἀ2ν1ησσ ἀ2ν1ηϲϲ ἀ2ν1ήττ ἀ2ν1ήττ ἀ2ν1ηττ ἀ2ν1ήφα ἀ2ν1ήφα ἀ2ν1ηφα ἀ2ν1ίατ ἀ2ν1ίατ ἀ2ν1ιάτ ἀ2ν1ιάτ ἀ2ν1ίδιο ἀ2ν1ίδιο ἀ2ν1ιδίο ἀ2ν1ιδίο ἀ2ν1ιδίω ἀ2ν1ιδίω ἀ2ν1ίδια ἀ2ν1ίδια ἀ2ν1ιδιτ ἄ2ν1ιδρος ἄ2ν1ιδροϲ ἄ2ν1ιδροσ ἀ2ν1ίδρου ἀ2ν1ίδρου ἀ2ν1ίδρω ἀ2ν1ίδρω ἄ2ν1ιδρον ἄ2ν1ιδρε ἀ2ν1ίδροι ἀ2ν1ίδροι ἄ2ν1ιδροι ἀ2ν1ίδρυτ ἀ2ν1ίδρυτ ἀ2ν1ιδρύτ ἀ2ν1ιδρύτ ἀ2ν1ιδρωτ ἀ2ν1ιδρώτ ἀ2ν1ιδρώτ ἀ2ν1ίερ ἀ2ν1ίερ ἀ2ν1ιέρ ἀ2ν1ιέρ ἀ2ν1ιεράτ ἀ2ν1ιεράτ ἀ3ν2ιέρω ἀ3ν2ιέρω ἀ2ν1ίκ ἀ2ν1ίκ ἀ2ν1ικ ἄ2ν1ικ ἀ3ν2ίκη ἀ3ν2ίκη ἀ3ν2ική ἀ3ν2ική ἀ2ν1ίλ ἀ2ν1ίλ ἀ2ν1ιλ ἀ2ν1ίμαστ ἀ2ν1ίμαστ ἀ2ν1ίμαϲτ ἀ2ν1ίμαϲτ ἀ2ν1ιμάστ ἀ2ν1ιμάστ ἀ2ν1ιμάϲτ ἀ2ν1ιμάϲτ ἀ2ν1ίου ἀ2ν1ίου ἀ2ν1ιού ἀ2ν1ιού ἄ2ν1ιππ ἀ2ν1ίππ ἀ2ν1ίππ ἀ2ν1ισ ἀ2ν1ιϲ ἄ2ν1ισ ἄ2ν1ιϲ ἀ2ν1ίσ ἀ2ν1ίσ ἀ2ν1ίϲ ἀ2ν1ίϲ ἀ3ν2ισᾶτ ἀ3ν2ιϲᾶτ ἀ3ν2ισάτ ἀ3ν2ισάτ ἀ3ν2ιϲάτ ἀ3ν2ιϲάτ ἀ3ν2ίστ ἀ3ν2ίστ ἀ3ν2ίϲτ ἀ3ν2ίϲτ ἀ3ν2ιστ ἀ3ν2ιϲτ ἀ4ν3ιστορη ἀ4ν3ιϲτορη ἀ4ν3ιστόρη ἀ4ν3ιστόρη ἀ4ν3ιϲτόρη ἀ4ν3ιϲτόρη ἀ4ν3ιστορή ἀ4ν3ιστορή ἀ4ν3ιϲτορή ἀ4ν3ιϲτορή ἀ3ν2ίσχ ἀ3ν2ίσχ ἀ3ν2ίϲχ ἀ3ν2ίϲχ ἀ4ν3ίσχυ ἀ4ν3ίσχυ ἀ4ν3ίϲχυ ἀ4ν3ίϲχυ ἄ2ν1ιχ ἀ2ν1ίχ ἀ2ν1ίχ ἀ2ν1ιχνεύτ ἀ2ν1ιχνεύτ ἀ2ν1ίψ ἀ2ν1ίψ ἀ2ν1ιψ ἀ2ν1όδε ἀ2ν1όδε ἀ2ν1οδέ ἀ2ν1οδέ ἄ2ν1οζ ἀ2ν1όζ ἀ2ν1όζ ἀ2ν1οικε ἀ2ν1οικον ἄ2ν1οικ ἀ2ν1οίκ ἀ2ν1οίκ ἀ2ν1οικτί ἀ2ν1οικτί ἄ2ν1οικτ ἀ2ν1οίκτ ἀ2ν1οίκτ ἀ2ν1οίμωκ ἀ2ν1οίμωκ ἀ2ν1οιμώκ ἀ2ν1οιμώκ ἀ2ν1οιμωκ ἀ2ν1οιν ἄ2ν1οιν ἀ2ν1οίν ἀ2ν1οίν ἄ2ν1οιστρ ἄ2ν1οιϲτρ ἀ2ν1οίστρ ἀ2ν1οίστρ ἀ2ν1οίϲτρ ἀ2ν1οίϲτρ ἀ2ν1όλ ἀ2ν1όλ ἀ2ν1ολ ἄ2ν1ολ ἀ3ν2ολκ ἀ3ν2ολο ἀ2ν1ομβρί ἀ2ν1ομβρί ἀ2ν1ομβρῖ ἄ2ν1ομβρο ἀ2ν1όμβρο ἀ2ν1όμβρο ἀ2ν1όμβρω ἀ2ν1όμβρω ἄ2ν1ομβρα ἀ2ν1ομήλ ἀ2ν1ομήλ ἀ2ν1ομηλ ἀ2ν1ομίλ ἀ2ν1ομίλ ἀ2ν1ομιλ ἀ2ν1όμιχ ἀ2ν1όμιχ ἀ2ν1ομιχ ἀ2ν1όμο ἀ2ν1όμο ἀ2ν1ομό ἀ2ν1ομό ἀ2ν1ομο ἀ3ν2ομοθ ἀ3ν2όμου. ἀ3ν2όμου. ἀ3ν2όμῳ. ἀ3ν2όμῳ. ἀ3ν2όμω. ἀ3ν2όμω. ἀ2ν2όμοιν. ἀ2ν2όμοιν. ἀ3ν2όμων. ἀ3ν2όμων. ἀ3ν2όμοις. ἀ3ν2όμοις. ἀ3ν2όμοιϲ. ἀ3ν2όμοιϲ. ἀ3ν2όμοισ. ἀ3ν2όμοισ. ἀ3ν2όμους. ἀ3ν2όμους. ἀ3ν2όμουϲ. ἀ3ν2όμουϲ. ἀ3ν2όμουσ. ἀ3ν2όμουσ. ἀ2ν1όν ἀ2ν1όν ἀ2ν1ον ἄ2ν1οπ ἀ2ν1όπ ἀ2ν1όπ ἀ2ν1όρ ἀ2ν1όρ ἀ2ν1ορ ἄ2ν1ορ ἀ3ν2οργάζ ἀ3ν2οργάζ ἄ3ν2ορθ ἀ3ν2όρθ ἀ3ν2όρθ ἀ3ν2ορμά ἀ3ν2ορμά ἀ3ν2ορτ ἀ3ν2ορύ ἀ3ν2ορύ ἀ2ν1όσι ἀ2ν1όσι ἀ2ν1όϲι ἀ2ν1όϲι ἀ2ν1οσί ἀ2ν1οσί ἀ2ν1οϲί ἀ2ν1οϲί ἀ2ν1οσι ἀ2ν1οϲι ἄ2ν1οσμ ἄ2ν1οϲμ ἀ2ν1όσμ ἀ2ν1όσμ ἀ2ν1όϲμ ἀ2ν1όϲμ ἀ2ν1όσφρ ἀ2ν1όσφρ ἀ2ν1όϲφρ ἀ2ν1όϲφρ ἀ2ν1οσφρ ἀ2ν1οϲφρ ἀ2ν1ούα ἀ2ν1ούα ἀ2ν1ουά ἀ2ν1ουά ἀ2ν1ούσι ἀ2ν1ούσι ἀ2ν1ούϲι ἀ2ν1ούϲι ἀ2ν1ουσί ἀ2ν1ουσί ἀ2ν1ουϲί ἀ2ν1ουϲί ἀ2ν1ούτ ἀ2ν1ούτ ἀ2ν1ουτ ἀ2ν1οφθ ἀ2ν1όχευτ ἀ2ν1όχευτ ἀ2ν1οχεύτ ἀ2ν1οχεύτ ἄ2ν1οχλ ἀ2ν1όχλ ἀ2ν1όχλ ἀ2ν1οψ ἄ2ν1οψ ἀ2ν1όψ ἀ2ν1όψ ἀντα2ν1ισ ἀντα2ν1ιϲ ἀντα2ν1ίσ ἀντα2ν1ίσ ἀντα2ν1ίϲ ἀντα2ν1ίϲ ἀντει2σ1 ἀντει2ϲ1 ἀντε2κ1 ἀντε2ν1 ἀντε2ξ1 ἀντιδυ2σ1 ἀντιδυ2ϲ1 ἀντιπαρε2κ1 ἀντιπαρε2ξ1 ἀντιπρο2σ1 ἀντιπρο2ϲ1 ἀντιπροσ3κ2υ ἀντιπροϲ3κ2υ ἀντισύ2ν1 ἀντισύ2ν1 ἀντιϲύ2ν1 ἀντιϲύ2ν1 ἀντισυ2ν1 ἀντιϲυ2ν1 ἀ2ν1ύ ἀ2ν1ύ ἀ2ν1υ ἀ3ν2υμ ἀ3ν2ύσ ἀ3ν2ύσ ἀ3ν2ύϲ ἀ3ν2ύϲ ἀ3ν2υσ ἀ3ν2υϲ ἀ2ν1υπέ2ρ1 ἀ2ν1υπέ2ρ1 ἀ2ν1υπε2ρ1 ἄ2ν1ῳδ ἀ2ν1ῴδ ἀ2ν1ώδυ ἀ2ν1ώδυ ἀ2ν1ωδύ ἀ2ν1ωδύ ἀ2ν1ώι ἀ2ν1ώι ἀ2ν1ωί ἀ2ν1ωί ἀ2ν1ώλ ἀ2ν1ώλ ἀ2ν1ωλ ἀ2ν1ώμ ἀ2ν1ώμ ἀ2ν1ωμ ἀ2ν1ών ἀ2ν1ών ἀ2ν1ων ἀ2ν1ωρ ἄ2ν1ωρ ἀ2ν1ώρ ἀ2ν1ώρ ἄ2ν1ωτο ἀ2ν1ώτο ἀ2ν1ώτο ἀ2ν1ωφέλ ἀ2ν1ωφέλ ἀ2ν1ωφελ ἀ2ν1ώχυ ἀ2ν1ώχυ ἀ2ν1ωχύ ἀ2ν1ωχύ ἀπα2ν1αι ἀπά2ν1ου ἀπά2ν1ου ἀπα2ν1ούρ ἀπα2ν1ούρ ἁπα2ξ1 ἀπε2κ1λ ἁπε2ρ1 ἀποσυ2ν1 ἀποϲυ2ν1 ἀπρό2σ1 ἀπρό2σ1 ἀπρό2ϲ1 ἀπρό2ϲ1 ἀπρο2σ1 ἀπρο2ϲ1 ἀπρό3σ2κε ἀπρό3σ2κε ἀπρό3ϲ2κε ἀπρό3ϲ2κε ἀπρο3σ2κέ ἀπρο3σ2κέ ἀπρο3ϲ2κέ ἀπρο3ϲ2κέ ἀπρό3σ2κο ἀπρό3σ2κο ἀπρό3ϲ2κο ἀπρό3ϲ2κο ἀπρο3σ2κό ἀπρο3σ2κό ἀπρο3ϲ2κό ἀπρο3ϲ2κό ἀπρο3σ2τ ἀπρο3ϲ2τ ἁρπα2ξ1 ἀρρε2ν1ω ἀρχισυ2ν1 ἀρχιϲυ2ν1 ἀστε2ρ1ω ἀϲτε2ρ1ω ἀσύ2ν1 ἀσύ2ν1 ἀϲύ2ν1 ἀϲύ2ν1 ἀσυ2ν1 ἀϲυ2ν1 ἀξύ2ν1 ἀξύ2ν1 ἀξυ2ν1 αὐτέ2κ1μ αὐτέ2κ1μ αὐτε2κ1μ αὐτε2ξ1 ἀω2σ1φ ἀω2ϲ1φ .γερα2σ1φ .γερα2ϲ1φ .δα2σ1π .δα2ϲ1π .διαμφι2σ1β .διαμφι2ϲ1β .διέ2κ1ρο .διέ2κ1ρο .διε2κ1ρό .διε2κ1ρό .διέ2ξ1 .διέ2ξ1 .διε2ξ1 .δικα2σ1π .δικα2ϲ1π .διό2σ1κ .διό2σ1κ .διό2ϲ1κ .διό2ϲ1κ .διο2σ1κ .διο2ϲ1κ .διό2σ1π .διό2σ1π .διό2ϲ1π .διό2ϲ1π .διο2σ1π .διο2ϲ1π .δί2σ1α .δί2σ1α .δί2ϲ1α .δί2ϲ1α .δι2σ1ά .δι2σ1ά .δι2ϲ1ά .δι2ϲ1ά .δί2σ1η .δί2σ1η .δί2ϲ1η .δί2ϲ1η .δι2σ1ή .δι2σ1ή .δι2ϲ1ή .δι2ϲ1ή .δί2σ1ε .δί2σ1ε .δί2ϲ1ε .δί2ϲ1ε .δι2σ1ε .δι2ϲ1ε .δι2σ1θ .δι2ϲ1θ .δύ2σ1 .δύ2σ1 .δύ2ϲ1 .δύ2ϲ1 .δυ2σ1 .δυ2ϲ1 δύ3σ2ω. δύ3σ2ω. δύ3ϲ2ω. δύ3ϲ2ω. δύ3σ2εις. δύ3σ2εις. δύ3ϲ2ειϲ. δύ3ϲ2ειϲ. δύ3σ2εισ. δύ3σ2εισ. δύ3σ2ει. δύ3σ2ει. δύ3ϲ2ει. δύ3ϲ2ει. .δύ3σ2ετ .δύ3σ2ετ .δύ3ϲ2ετ .δύ3ϲ2ετ δύ3σ2ομεν. δύ3σ2ομεν. δύ3ϲ2ομεν. δύ3ϲ2ομεν. δύ3σ2ουσιν. δύ3σ2ουσιν. δύ3ϲ2ουϲιν. δύ3ϲ2ουϲιν. δύ3σ2οιμι. δύ3σ2οιμι. δύ3ϲ2οιμι. δύ3ϲ2οιμι. δύ3σ2οις. δύ3σ2οις. δύ3ϲ2οιϲ. δύ3ϲ2οιϲ. δύ3σ2οισ. δύ3σ2οισ. δύ3σ2οι. δύ3σ2οι. δύ3ϲ2οι. δύ3ϲ2οι. δύ3σ2οιτον. δύ3σ2οιτον. δύ3ϲ2οιτον. δύ3ϲ2οιτον. δυ3σ2οίτην. δυ3σ2οίτην. δυ3ϲ2οίτην. δυ3ϲ2οίτην. δύ3σ2οιμεν. δύ3σ2οιμεν. δύ3ϲ2οιμεν. δύ3ϲ2οιμεν. δύ3σ2οιτε. δύ3σ2οιτε. δύ3ϲ2οιτε. δύ3ϲ2οιτε. δύ3σ2οιεν. δύ3σ2οιεν. δύ3ϲ2οιεν. δύ3ϲ2οιεν. δύ3σ2ειν. δύ3σ2ειν. δύ3ϲ2ειν. δύ3ϲ2ειν. δύ3σ2ων. δύ3σ2ων. δύ3ϲ2ων. δύ3ϲ2ων. δύ3σ2ον δύ3σ2ον δύ3ϲ2ον δύ3ϲ2ον δυ3σ2όν δυ3σ2όν δυ3ϲ2όν δυ3ϲ2όν δύ3σ2ουσ δύ3σ2ουσ δύ3ϲ2ουϲ δύ3ϲ2ουϲ δυ3σ2ούσ δυ3σ2ούσ δυ3ϲ2ούϲ δυ3ϲ2ούϲ δύ3σ2ῃ δύ3σ2ῃ δύ3ϲ2ῃ δύ3ϲ2ῃ δύ3σ2ητον. δύ3σ2ητον. δύ3ϲ2ητον. δύ3ϲ2ητον. δύ3σ2ωμεν. δύ3σ2ωμεν. δύ3ϲ2ωμεν. δύ3ϲ2ωμεν. δύ3σ2ωσι. δύ3σ2ωσι. δύ3ϲ2ωϲι. δύ3ϲ2ωϲι. δύ3σ2αιμι. δύ3σ2αιμι. δύ3ϲ2αιμι. δύ3ϲ2αιμι. δύ3σ2αις. δύ3σ2αις. δύ3ϲ2αιϲ. δύ3ϲ2αιϲ. δύ3σ2ειας. δύ3σ2ειας. δύ3ϲ2ειαϲ. δύ3ϲ2ειαϲ. δύ3σ2αισ. δύ3σ2αισ. δύ3σ2ειασ. δύ3σ2ειασ. δύ3σ2αι. δύ3σ2αι. δύ3ϲ2αι. δύ3ϲ2αι. δύ3σ2ειε. δύ3σ2ειε. δύ3ϲ2ειε. δύ3ϲ2ειε. δύ3σ2αιτον. δύ3σ2αιτον. δύ3ϲ2αιτον. δύ3ϲ2αιτον. δυ3σ2αίτην. δυ3σ2αίτην. δυ3ϲ2αίτην. δυ3ϲ2αίτην. δύ3σ2αιμεν. δύ3σ2αιμεν. δύ3ϲ2αιμεν. δύ3ϲ2αιμεν. δύ3σ2αιτε. δύ3σ2αιτε. δύ3ϲ2αιτε. δύ3ϲ2αιτε. δύ3σ2αιεν δύ3σ2αιεν δύ3ϲ2αιεν δύ3ϲ2αιεν δύ3σ2ειαν. δύ3σ2ειαν. δύ3ϲ2ειαν. δύ3ϲ2ειαν. δύ3σ2ον. δύ3σ2ον. δύ3ϲ2ον. δύ3ϲ2ον. δυ3σ2άτω. δυ3σ2άτω. δυ3ϲ2άτω. δυ3ϲ2άτω. δύ3σ2ατον. δύ3σ2ατον. δύ3ϲ2ατον. δύ3ϲ2ατον. δυ3σ2άτων. δυ3σ2άτων. δυ3ϲ2άτων. δυ3ϲ2άτων. δύ3σ2ατε. δύ3σ2ατε. δύ3ϲ2ατε. δύ3ϲ2ατε. δυ3σ2άντων. δυ3σ2άντων. δυ3ϲ2άντων. δυ3ϲ2άντων. δύ3σ2ας. δύ3σ2ας. δύ3ϲ2αϲ. δύ3ϲ2αϲ. δύ3σ2αν. δύ3σ2αν. δύ3ϲ2αν. δύ3ϲ2αν. δύ3σ2αντ δύ3σ2αντ δύ3ϲ2αντ δύ3ϲ2αντ δυ3σ2άντ δυ3σ2άντ δυ3ϲ2άντ δυ3ϲ2άντ δύ3σ2ασ δύ3σ2ασ δύ3ϲ2αϲ δύ3ϲ2αϲ δυ3σ2άσ δυ3σ2άσ δυ3ϲ2άϲ δυ3ϲ2άϲ δύ3σ2ομαι. δύ3σ2ομαι. δύ3ϲ2ομαι. δύ3ϲ2ομαι. .δύ3σ2εσ .δύ3σ2εσ .δύ3ϲ2εϲ .δύ3ϲ2εϲ δυ3σ2όμεθα. δυ3σ2όμεθα. δυ3ϲ2όμεθα. δυ3ϲ2όμεθα. δύ3σ2ονται. δύ3σ2ονται. δύ3ϲ2ονται. δύ3ϲ2ονται. δυ3σ2οίμην. δυ3σ2οίμην. δυ3ϲ2οίμην. δυ3ϲ2οίμην. δύ3σ2οιο. δύ3σ2οιο. δύ3ϲ2οιο. δύ3ϲ2οιο. δύ3σ2οιτο. δύ3σ2οιτο. δύ3ϲ2οιτο. δύ3ϲ2οιτο. δύ3σ2οισθον. δύ3σ2οισθον. δύ3ϲ2οιϲθον. δύ3ϲ2οιϲθον. δυ3σ2οίσθην. δυ3σ2οίσθην. δυ3ϲ2οίϲθην. δυ3ϲ2οίϲθην. δυ3σ2οίμεθα. δυ3σ2οίμεθα. δυ3ϲ2οίμεθα. δυ3ϲ2οίμεθα. δύ3σ2οισθε. δύ3σ2οισθε. δύ3ϲ2οιϲθε. δύ3ϲ2οιϲθε. δύ3σ2οιντο. δύ3σ2οιντο. δύ3ϲ2οιντο. δύ3ϲ2οιντο. δύ3σ2εσθαι. δύ3σ2εσθαι. δύ3ϲ2εϲθαι. δύ3ϲ2εϲθαι. .δυ3σ2όμεν .δυ3σ2όμεν .δυ3ϲ2όμεν .δυ3ϲ2όμεν .δυ3σ2ομέν .δυ3σ2ομέν .δυ3ϲ2ομέν .δυ3ϲ2ομέν δύ3σ2ωμαι. δύ3σ2ωμαι. δύ3ϲ2ωμαι. δύ3ϲ2ωμαι. δύ3σ2ηται. δύ3σ2ηται. δύ3ϲ2ηται. δύ3ϲ2ηται. δυ3σ2ώμεθα δυ3σ2ώμεθα δυ3ϲ2ώμεθα δυ3ϲ2ώμεθα δύ3σ2ησθε. δύ3σ2ησθε. δύ3ϲ2ηϲθε. δύ3ϲ2ηϲθε. δυ3σ2αίμην. δυ3σ2αίμην. δυ3ϲ2αίμην. δυ3ϲ2αίμην. δύ3σ2αιο. δύ3σ2αιο. δύ3ϲ2αιο. δύ3ϲ2αιο. δύ3σ2αιτο. δύ3σ2αιτο. δύ3ϲ2αιτο. δύ3ϲ2αιτο. δύ3σ2αισθον. δύ3σ2αισθον. δύ3ϲ2αιϲθον. δύ3ϲ2αιϲθον. δυ3σ2αίσθην. δυ3σ2αίσθην. δυ3ϲ2αίϲθην. δυ3ϲ2αίϲθην. δυ3σ2αίμεθα. δυ3σ2αίμεθα. δυ3ϲ2αίμεθα. δυ3ϲ2αίμεθα. δύ3σ2αισθαι. δύ3σ2αισθαι. δύ3ϲ2αιϲθαι. δύ3ϲ2αιϲθαι. δύ3σ2αιντο. δύ3σ2αιντο. δύ3ϲ2αιντο. δύ3ϲ2αιντο. δυ3σ2άσθω. δυ3σ2άσθω. δυ3ϲ2άϲθω. δυ3ϲ2άϲθω. δύ3σ2ασθον. δύ3σ2ασθον. δύ3ϲ2αϲθον. δύ3ϲ2αϲθον. δυ3σ2άσθων. δυ3σ2άσθων. δυ3ϲ2άϲθων. δυ3ϲ2άϲθων. δύ3σ2ασθε. δύ3σ2ασθε. δύ3ϲ2αϲθε. δύ3ϲ2αϲθε. δύ3σ2ασθαι. δύ3σ2ασθαι. δύ3ϲ2αϲθαι. δύ3ϲ2αϲθαι. δυ3σ2άμεν δυ3σ2άμεν δυ3ϲ2άμεν δυ3ϲ2άμεν δυσ3σ2αμέν δυσ3σ2αμέν δυϲ3ϲ2αμέν δυϲ3ϲ2αμέν δύ3σ2ατο. δύ3σ2ατο. δύ3ϲ2ατο. δύ3ϲ2ατο. δύ3σ2ετο. δύ3σ2ετο. δύ3ϲ2ετο. δύ3ϲ2ετο. δύ3σ2αντο. δύ3σ2αντο. δύ3ϲ2αντο. δύ3ϲ2αντο. δύ3σ2εο. δύ3σ2εο. δύ3ϲ2εο. δύ3ϲ2εο. .δυσεί2σ1β .δυσεί2σ1β .δυϲεί2ϲ1β .δυϲεί2ϲ1β .δυσει2σ1β .δυϲει2ϲ1β .δυσέ2κ1 .δυσέ2κ1 .δυϲέ2κ1 .δυϲέ2κ1 .δυσε2κ1 .δυϲε2κ1 .δυσέ2ξ1 .δυσέ2ξ1 .δυϲέ2ξ1 .δυϲέ2ξ1 .δυσε2ξ1 .δυϲε2ξ1 .δυ3σ2ιθ .δυ3ϲ2ιθ δύ3σ2ις. δύ3σ2ις. δύ3ϲ2ιϲ. δύ3ϲ2ιϲ. δύ3σ2ισ. δύ3σ2ισ. δύ3σ2εω δύ3σ2εω δύ3ϲ2εω δύ3ϲ2εω δύ3σ2ιν. δύ3σ2ιν. δύ3ϲ2ιν. δύ3ϲ2ιν. δύ3σ2ι. δύ3σ2ι. δύ3ϲ2ι. δύ3ϲ2ι. δυ3σ2έοιν. δυ3σ2έοιν. δυ3ϲ2έοιν. δυ3ϲ2έοιν. δύ3σ2εσι. δύ3σ2εσι. δύ3ϲ2εϲι. δύ3ϲ2εϲι. δύ3σ2εσιν. δύ3σ2εσιν. δύ3ϲ2εϲιν. δύ3ϲ2εϲιν. .δύ3σ2κε .δύ3σ2κε .δύ3ϲ2κε .δύ3ϲ2κε .δυ3σ2μή. .δυ3σ2μή. .δυ3ϲ2μή. .δυ3ϲ2μή. .δυ3σ2μὴ. .δυ3ϲ2μὴ. .δυ3σ2μῆς. .δυ3ϲ2μῆϲ. .δυ3σ2μῆσ. .δυ3σ2μῇ .δυ3ϲ2μῇ .δυ3σ2μῆ. .δυ3ϲ2μῆ. .δυ3σ2μᾶ .δυ3ϲ2μᾶ .δυ3σ2μα .δυ3ϲ2μα .δυ3σ2μῶ .δυ3ϲ2μῶ .δυσξύ2ν1 .δυσξύ2ν1 .δυϲξύ2ν1 .δυϲξύ2ν1 .δυσξυ2ν1 .δυϲξυ2ν1 .δύ3σ2ταν .δύ3σ2ταν .δύ3ϲ2ταν .δύ3ϲ2ταν .δυ3σ2τάν .δυ3σ2τάν .δυ3ϲ2τάν .δυ3ϲ2τάν .δυ3σ2την .δυ3ϲ2την .δυ3σ2τήν .δυ3σ2τήν .δυ3ϲ2τήν .δυ3ϲ2τήν ἐδυ2σ1τ ἐδυ2ϲ1τ εἰ2ν1όδ εἰ2ν1όδ εἰ2ν1οδ εἰ2σ1 εἰ2ϲ1 εἴ2σ1 εἴ2ϲ1 εἰ3σ2ί. εἰ3σ2ί. εἰ3ϲ2ί. εἰ3ϲ2ί. εἰ3σ2ὶ. εἰ3ϲ2ὶ. εἰ3σ2ι. εἰ3ϲ2ι. εἰ3σ2ίν. εἰ3σ2ίν. εἰ3ϲ2ίν. εἰ3ϲ2ίν. εἰ3σ2ὶν. εἰ3ϲ2ὶν. εἰ3σ2ιν. εἰ3ϲ2ιν. εἴ3σ2ομ εἴ3ϲ2ομ εἴ3σ2ῃ. εἴ3ϲ2ῃ. εἴσει. εἴϲει. εἴ3σ2εται. εἴ3ϲ2εται. εἴ3σ2εσθον. εἴ3ϲ2εϲθον. εἰ3σ2όμ εἰ3σ2όμ εἰ3ϲ2όμ εἰ3ϲ2όμ εἴ3σ2εσθε. εἴ3ϲ2εϲθε. εἴ3σ2ονται εἴ3ϲ2ονται εἰ3σ2οίμην εἰ3σ2οίμην εἰ3ϲ2οίμην εἰ3ϲ2οίμην εἴ3σ2οιο εἴ3ϲ2οιο εἴ3σ2οιτο εἴ3ϲ2οιτο εἴ3σ2οισθον εἴ3ϲ2οιϲθον εἰ3σ2οίσθην εἰ3σ2οίσθην εἰ3ϲ2οίϲθην εἰ3ϲ2οίϲθην εἰ3σ2οίμεθα εἰ3σ2οίμεθα εἰ3ϲ2οίμεθα εἰ3ϲ2οίμεθα εἴ3σ2οισθε εἴ3ϲ2οιϲθε εἴ3σ2οιντο εἴ3ϲ2οιντο εἴ3σ2εσθαι εἴ3ϲ2εϲθαι εἰ3σ2όμεν εἰ3σ2όμεν εἰ3ϲ2όμεν εἰ3ϲ2όμεν εἰ3σ2ομέν εἰ3σ2ομέν εἰ3ϲ2ομέν εἰ3ϲ2ομέν εἴ3σ2άμην. εἴ3σ2άμην. εἴ3ϲ2άμην. εἴ3ϲ2άμην. εἴ3σ2ω εἴ3ϲ2ω εἴ3σ2ατο εἴ3ϲ2ατο εἴ3σ2ασθον εἴ3ϲ2αϲθον εἰ3σ2άσθην εἰ3σ2άσθην εἰ3ϲ2άϲθην εἰ3ϲ2άϲθην εἰ3σ2άμεθα εἰ3σ2άμεθα εἰ3ϲ2άμεθα εἰ3ϲ2άμεθα εἴ3σ2ασθε εἴ3ϲ2αϲθε εἴ3σ2αντο εἴ3ϲ2αντο εἴ3σ2ωμαι εἴ3ϲ2ωμαι εἴ3σ2ησθον εἴ3ϲ2ηϲθον εἰ3σ2ώμεθα εἰ3σ2ώμεθα εἰ3ϲ2ώμεθα εἰ3ϲ2ώμεθα εἴ3σ2ησθε εἴ3ϲ2ηϲθε εἴ3σ2ωνται εἴ3ϲ2ωνται εἰ3σ2αίμην εἰ3σ2αίμην εἰ3ϲ2αίμην εἰ3ϲ2αίμην εἴ3σ2αιο εἴ3ϲ2αιο εἴ3σ2αιτο εἴ3ϲ2αιτο εἴ3σ2αισθον εἴ3ϲ2αιϲθον εἴ3σ2αίσθην εἴ3σ2αίσθην εἴ3ϲ2αίϲθην εἴ3ϲ2αίϲθην εἰ3σ2αίμεθα εἰ3σ2αίμεθα εἰ3ϲ2αίμεθα εἰ3ϲ2αίμεθα εἴ3σ2αισθε εἴ3ϲ2αιϲθε εἴ3σ2αιντο εἴ3ϲ2αιντο εἰ3σ2άσθω εἰ3σ2άσθω εἰ3ϲ2άϲθω εἰ3ϲ2άϲθω εἰ3σ2άσθων εἰ3σ2άσθων εἰ3ϲ2άϲθων εἰ3ϲ2άϲθων εἴ3σ2ασθαι εἴ3ϲ2αϲθαι εἰ3σ2άμεν εἰ3σ2άμεν εἰ3ϲ2άμεν εἰ3ϲ2άμεν εἰ3σ2αμέν εἰ3σ2αμέν εἰ3ϲ2αμέν εἰ3ϲ2αμέν ἐ2κ1λ ἐ3κ2λήθη ἐ3κ2λήθη ἐ3κ2λάζ ἐ3κ2λάζ ἐ3κ2λάγ ἐ3κ2λάγ ἐ3κ2λάο ἐ3κ2λάο ἐ3κ2λάσ ἐ3κ2λάσ ἐ3κ2λάϲ ἐ3κ2λάϲ ἐ3κ2λαί ἐ3κ2λαί ἐ3κ2λαύ ἐ3κ2λαύ ἐ3κ2λεί ἐ3κ2λεί ἐ4κ3λείπ ἐ4κ3λείπ ἐ4κ3λείψ ἐ4κ3λείψ ἐ3κ2λῄ ἐ3κ2κλέπ ἐ3κ2κλέπ ἐ3κ2κλέψ ἐ3κ2κλέψ ἐ3κ2λάπ ἐ3κ2λάπ ἐ3κ2λαπ ἐ4κ3λάπτ ἐ4κ3λάπτ ἐ4κ3λαπτ ἐ3κ2λέφ ἐ3κ2λέφ ἐ3κ2λεφ ἐ3κ2λήρ ἐ3κ2λήρ ἐ3κ2ληρ ἐ3κ2λίν ἐ3κ2λίν ἐ3κ2λιν ἐ3κ2λύ ἐ3κ2λύ ἐ4κ3λύσεω ἐ4κ3λύσεω ἐ4κ3λύϲεω ἐ4κ3λύϲεω ἐ4κ3λύσει ἐ4κ3λύσει ἐ4κ3λύϲει ἐ4κ3λύϲει ἐ4κ3λύσεοι ἐ4κ3λύσεοι ἐ4κ3λύϲεοι ἐ4κ3λύϲεοι ἐ4κ3λύσεσι ἐ4κ3λύσεσι ἐ4κ3λύϲεϲι ἐ4κ3λύϲεϲι ἐ3κ2λόμ ἐ3κ2λόμ ἐ3κ2κλώσ ἐ3κ2κλώσ ἐ3κ2κλώϲ ἐ3κ2κλώϲ ἔ2κ1λει ἔ3κ2λεισ ἔ3κ2λειϲ ἔ2κ1λυσ ἔ2κ1λυϲ ἐ2κ1μ ἔ2κ1μ ἐ2κ1ν ἔ2κ1ν ἔ3κ2ναι ἐ3κ2ναί ἐ3κ2ναί ἔ3κ2νησ ἔ3κ2νηϲ ἐ3κ2νήσ ἐ3κ2νήσ ἐ3κ2νήϲ ἐ3κ2νήϲ ἐ3κ2νυ ἐ2κ1ρ ἔ2κ1ρ ἐ3κ2ράδ ἐ3κ2ράδ ἐ3κ2ραδ ἔ3κ2ραζ ἐ3κ2ράζ ἐ3κ2ράζ ἔ3κ2ραγ ἐ3κ2ράγ ἐ3κ2ράγ ἐ3κ2ράτ ἐ3κ2ράτ ἐ3κ2ρατ ἐ3κ2ραύγ ἐ3κ2ραύγ ἐ3κ2ραυγ ἔ3κ2ραι ἐ3κ2ραί ἐ3κ2ραί ἔ3κ2ραν ἐ3κ2ράν ἐ3κ2ράν ἐ3κ2ρήη ἐ3κ2ρήη ἐ3κ2ράα ἐ3κ2ράα ἐ3κ2ραά ἐ3κ2ραά ἐ3κ2ράθ ἐ3κ2ράθ ἐ3κ2ραθ ἔ3κ2ρεκ ἐ3κ2ρέκ ἐ3κ2ρέκ ἔ3κ2ρεξ ἐ3κ2ρέξ ἐ3κ2ρέξ ἐ3κ2ρέμ ἐ3κ2ρέμ ἐ3κ2ρεμ ἐ3κ2ρήμ ἐ3κ2ρήμ ἐ3κ2ρημ ἔ3κ2ριν ἐ3κ2ρίν ἐ3κ2ρίν ἐ3κ2ρίθ ἐ3κ2ρίθ ἐ3κ2ρότ ἐ3κ2ρότ ἐ3κ2ροτ ἔ3κ2ρου ἐ3κ2ρού ἐ3κ2ρού ἔ3κ2ρυπ ἐ3κ2ρύπ ἐ3κ2ρύπ ἔ3κ2ρυψ ἐ3κ2ρύψ ἐ3κ2ρύψ ἐ3κ2ρύβ ἐ3κ2ρύβ ἐ3κ2ρύφ ἐ3κ2ρύφ ἐ3κ2ρυσ ἐ3κ2ρυϲ ἔ3κ2ρωζ ἐ3κ2ρώζ ἐ3κ2ρώζ ἔ3κ2ρωξ ἐ3κ2ρώξ ἐ3κ2ρώξ ἐ2κ1ταθ ἔ2κ1ταμε. ἐ2κ1τάμν ἐ2κ1τάμν ἐ2κ1ταν ἐ2κ1ταρ ἐ2κ1τάσ ἐ2κ1τάσ ἐ2κ1τάϲ ἐ2κ1τάϲ ἐ2κ1τε ἐ2κ1τέ ἐ2κ1τέ ἐ3κ2τείν ἐ3κ2τείν ἐ2κ1τήκ ἐ2κ1τήκ ἐ2κ1τι ἔ2κ1τι ἐ2κ1τί ἐ2κ1τί ἔ3κ2τιζ ἐ3κ2τίζ ἐ3κ2τίζ ἔ3κ2τισα ἔ3κ2τιϲα ἐ3κ2τίσα ἐ3κ2τίσα ἐ3κ2τίϲα ἐ3κ2τίϲα ἐ2κ1τό ἐ2κ1τό ἐ2κ1το ἔ2κ1το ἐ3κ2τός. ἐ3κ2τός. ἐ3κ2τόϲ. ἐ3κ2τόϲ. ἐ3κ2τὸς. ἐ3κ2τὸϲ. ἐ3κ2τόσ. ἐ3κ2τόσ. ἐ3κ2τὸσ. ἐ2κ1τρ ἔ2κ1τυπο ἐ2κ1τύπου. ἐ2κ1τύπου. ἐ2κ1τύπῳ. ἐ2κ1τύπῳ. ἔ2κ1τυπε. ἐ2κ1τύπω. ἐ2κ1τύπω. ἐ2κτύποι. ἐ2κτύποι. ἐ2κ1τύπων. ἐ2κ1τύπων. ἐ2κ1τύποις. ἐ2κ1τύποις. ἐ2κ1τύποιϲ. ἐ2κ1τύποιϲ. ἐ2κ1τύποισ. ἐ2κ1τύποισ. ἐ2κ1τύπους. ἐ2κ1τύπους. ἐ2κ1τύπουϲ. ἐ2κ1τύπουϲ. ἐ2κ1τύπουσ. ἐ2κ1τύπουσ. ἔ2κ1τυπα. ἐ2κ1τυ ἑλλή2σ1π ἑλλή2σ1π ἑλλή2ϲ1π ἑλλή2ϲ1π ἑλλη2σ1π ἑλλη2ϲ1π ἐ2ν1 ἔ2ν1 ἐ3ν2άκις ἐ3ν2άκις ἐ3ν2άκιϲ ἐ3ν2άκιϲ ἐ3ν2ακισ ἐ3ν2ακιϲ ἐ3ν2ακόσ ἐ3ν2ακόσ ἐ3ν2ακόϲ ἐ3ν2ακόϲ ἐ3ν2ακοσ ἐ3ν2ακοϲ ἔ3ν2αρα. ἐ3ν2άρων. ἐ3ν2άρων. ἐ3ν2άροις. ἐ3ν2άροις. ἐ3ν2άροιϲ. ἐ3ν2άροιϲ. ἐ3ν2άροισ. ἐ3ν2άροισ. ἐ3ν2αρηφ ἐ4ν3αραρ ἐ3ν2άρεε ἐ3ν2άρεε ἐ3ν2αρέω ἐ3ν2αρέω ἐ3ν2αρέα ἐ3ν2αρέα ἐ3ν2αρεά ἐ3ν2αρεά ἐ3ν2άριε ἐ3ν2άριε ἐ3ν2αρίω ἐ3ν2αρίω ἐ3ν2αρία ἐ3ν2αρία ἐ3ν2αριά ἐ3ν2αριά ἔ3ν2ασσ ἔ3ν2αϲϲ ἐ3ν2άσσ ἐ3ν2άσσ ἐ3ν2άϲϲ ἐ3ν2άϲϲ ἐ3ν2άσθ ἐ3ν2άσθ ἐ3ν2άϲθ ἐ3ν2άϲθ ἐ3ν2ασθ ἐ3ν2αϲθ ἔ3ν2ατ ἐ3ν2άτ ἐ3ν2άτ ἐνδυ2σ1τ ἐνδυ2ϲ1τ ἐ3ν2έγκ ἐ3ν2έγκ ἐ3ν2εγκ ἔ3ν2εικ ἐ3ν2εῖκ ἐ3ν2εικ ἐ3ν2είκ ἐ3ν2είκ ἔ3ν2ειμ ἐ3ν2είμ ἐ3ν2είμ ἐ3ν2εμέσσ ἐ3ν2εμέσσ ἐ3ν2εμέϲϲ ἐ3ν2εμέϲϲ ἐ3ν2εμήθ ἐ3ν2εμήθ ἐ3ν2ενή ἐ3ν2ενή ἐ3ν2εό ἐ3ν2εό ἐ3ν2εὸ ἐ3ν2εο ἐ3ν2εῶ ἐ3ν2εά ἐ3ν2εά ἐ3ν2εὰ ἐ3ν2εᾶ ἐ3ν2έπει ἐ3ν2έπει ἔ3ν2ερθε ἔ3ν2ευσ ἔ3ν2ευϲ ἐ3ν2εύσ ἐ3ν2εύσ ἐ3ν2εύϲ ἐ3ν2εύϲ ἐ3ν2έχθ ἐ3ν2έχθ ἐ3ν2εχθ ἔ3ν2ησ ἔ3ν2ηϲ ἐ3ν2ήσ ἐ3ν2ήσ ἐ3ν2ήϲ ἐ3ν2ήϲ ἐ3ν2ηή ἐ3ν2ηή ἐ3ν2ηὴ ἔ3ν2ην. ἐ3ν2ηεί ἐ3ν2ηεί ἐ3ν2ηο ἐ3ν2ηῶ ἐ3νηέ ἐ3νηέ ἐ3ν2ήνο ἐ3ν2ήνο ἐ3ν2ί ἐ3ν2ί ἐ3ν2ι ἔ3ν2ι ἐ4ν3ιαύ ἐ4ν3ιαύ ἐ5ν4ιαύσ ἐ5ν4ιαύσ ἐ5ν4ιαύϲ ἐ5ν4ιαύϲ ἐ5ν4ιαυσ ἐ5ν4ιαυϲ ἐ4ν3ιδρ ἐ4ν3ίδρ ἐ4ν3ίδρ ἐ4ν3ίζ ἐ4ν3ίζ ἐ4ν3ίη ἐ4ν3ίη ἐ4ν3ιέτον. ἐ4ν3ιέτον. ἐ4ν3ίεμεν. ἐ4ν3ίεμεν. ἐ4ν3ίω. ἐ4ν3ίω. ἐ4ν3ιππ ἐ4ν3ίππ ἐ4ν3ίππ ἐ4ν3ίπτ ἐ4ν3ίπτ ἐ4ν3ίψ ἐ4ν3ίψ ἐ4ν3ίσσ ἐ4ν3ίσσ ἐ4ν3ίϲϲ ἐ4ν3ίϲϲ ἐ4ν3ίστ ἐ4ν3ίστ ἐ4ν3ίϲτ ἐ4ν3ίϲτ ἐ4ν3ιστ ἐ4ν3ιϲτ ἐ4ν3ισχ ἐ4ν3ιϲχ ἐ4ν3ίσχ ἐ4ν3ίσχ ἐ4ν3ίϲχ ἐ4ν3ίϲχ ἔ3ν2ος. ἔ3ν2οϲ. ἔ3ν2οσ. ἔ3ν2ου. ἔ3ν2ον. ἔ3ν2ω ἔ3ν2οι. ἔ3ν2οις. ἔ3ν2οιϲ. ἔ3ν2οισ. ἔ3ν2ης. ἔ3ν2ηϲ. ἔ3ν2ησ. ἔ3ν2ῃ. ἔ3ν2η. ἔ3ν2οσι ἔ3ν2οϲι ἐ3ν2όσε ἐ3ν2όσε ἐ3ν2όϲε ἐ3ν2όϲε ἐ3ν2υάλ ἐ3ν2υάλ ἐ3ν2υαλ ἔ3ν2υξ ἐ3ν2υξ ἐ3ν2ύξ ἐ3ν2ύξ ἐ3ν2ύσ ἐ3ν2ύσ ἐ3ν2ύϲ ἐ3ν2ύϲ ἐ3ν2υσ ἐ3ν2υϲ ἐ3ν2υώ ἐ3ν2υώ ἐ3ν2υὼ ἐ3ν2υόο ἐ3ν2υόο ἐ3ν2υοῦς ἐ3ν2υοῦϲ ἐ2ξ1 ἔ2ξ1 ἐ3ξ2ήρ ἐ3ξ2ήρ ἐ3ξ2ηρ ἐ3ξ2υ2ν1 ἐ3ξ2υρ ἐ3ξ2ύρ ἐ3ξ2ύρ ἔ3ξ2υσ ἔ3ξ2υϲ ἔ3ξ2ω. ἑ2ξ1ήρετμ ἑ2ξ1ήρετμ ἑ2ξ1ηρέτμ ἑ2ξ1ηρέτμ ἐπεί2σ1 ἐπεί2σ1 ἐπεί2ϲ1 ἐπεί2ϲ1 ἐπει2σ1 ἐπει2ϲ1 ἐπεί3σ2ατον. ἐπεί3σ2ατον. ἐπεί3ϲ2ατον. ἐπεί3ϲ2ατον. ἐπει3σ2άτην. ἐπει3σ2άτην. ἐπει3ϲ2άτην. ἐπει3ϲ2άτην. ἐπεί3σ2αμεν. ἐπεί3σ2αμεν. ἐπεί3ϲ2αμεν. ἐπεί3ϲ2αμεν. ἐπεί3σ2ατε ἐπεί3σ2ατε ἐπεί3ϲ2ατε ἐπεί3ϲ2ατε ἐπει3σ2άμην. ἐπει3σ2άμην. ἐπει3ϲ2άμην. ἐπει3ϲ2άμην. ἐπεί3σ2ω. ἐπεί3σ2ω. ἐπεί3ϲ2ω. ἐπεί3ϲ2ω. ἐπεί3σ2ατο ἐπεί3σ2ατο ἐπεί3ϲ2ατο ἐπεί3ϲ2ατο ἐπεί3σ2ασθον. ἐπεί3σ2ασθον. ἐπεί3ϲ2αϲθον. ἐπεί3ϲ2αϲθον. ἐπει3σ2άμεθα. ἐπει3σ2άμεθα. ἐπει3ϲ2άμεθα. ἐπει3ϲ2άμεθα. ἐπεί3σ2ασθε. ἐπεί3σ2ασθε. ἐπεί3ϲ2αϲθε. ἐπεί3ϲ2αϲθε. ἐπεί3σ2αντο. ἐπεί3σ2αντο. ἐπεί3ϲ2αντο. ἐπεί3ϲ2αντο. ἐπεί3σ2θ ἐπεί3σ2θ ἐπεί3ϲ2θ ἐπεί3ϲ2θ ἐπει3σ2θ ἐπει3ϲ2θ ἐπε2κ1τεί ἐπε2κ1τεί ἐπέ2κ1τει ἐπέ2κ1τει ἐπε2κ1τρ ἐπέ2κ1τρ ἐπέ2κ1τρ ἐπε2ξ1 ἐπε2σ1β ἐπε2ϲ1β ἐπιπρό2σ1θ ἐπιπρό2σ1θ ἐπιπρό2ϲ1θ ἐπιπρό2ϲ1θ ἐπιπρο2σ1θ ἐπιπρο2ϲ1θ ἐπισυ2ν1 ἐπιϲυ2ν1 ἐ2σ1 ἐ2ϲ1 ἐ3σ2άω ἐ3σ2άω ἐ3ϲ2άω ἐ3ϲ2άω ἐ3σ2ημ ἐ3ϲ2ημ ἐ3σ2θ ἐ3ϲ2θ ἐ4σ3θέσ ἐ4σ3θέσ ἐ4ϲ3θέϲ ἐ4ϲ3θέϲ ἐ3σ2ιγ ἐ3ϲ2ιγ ἐ3σ2κ ἐ3ϲ2κ ἐ4σ3κά ἐ4σ3κά ἐ4ϲ3κά ἐ4ϲ3κά ἐ4σ3κα ἐ4ϲ3κα ἐ3σ2μὲν. ἐ3ϲ2μὲν. ἐ3σ2μέν. ἐ3σ2μέν. ἐ3ϲ2μέν. ἐ3ϲ2μέν. ἐ3σ2τ ἐ3ϲ2τ ἐ3σ2όμεθα ἐ3σ2όμεθα ἐ3ϲ2όμεθα ἐ3ϲ2όμεθα ἐ3σ2οίμην ἐ3σ2οίμην ἐ3ϲ2οίμην ἐ3ϲ2οίμην ἐ3σ2όμ ἐ3σ2όμ ἐ3ϲ2όμ ἐ3ϲ2όμ ἐ3σ2ομ ἐ3ϲ2ομ ἐ3σ2οῦ ἐ3ϲ2οῦ ἐ3σ2ού ἐ3σ2ού ἐ3ϲ2ού ἐ3ϲ2ού ἐ3σ2ου ἐ3ϲ2ου ἐ3σ2υ ἐ3ϲ2υ ἐ3σ2ύ ἐ3σ2ύ ἐ3ϲ2ύ ἐ3ϲ2ύ ἐσύ2ν1 ἐσύ2ν1 ἐϲύ2ν1 ἐϲύ2ν1 ἐσυ2ν1 ἐϲυ2ν1 ἐ3σ2χ ἐ3ϲ2χ ἐ4σ3χέ ἐ4σ3χέ ἐ4ϲ3χέ ἐ4ϲ3χέ ἐ3σ2ώ ἐ3σ2ώ ἐ3ϲ2ώ ἐ3ϲ2ώ ἐ3σ2ω ἐ3ϲ2ω ἔ2σ1οπ ἔ2ϲ1οπ εὐε2ξ1 εὐε3ξ2ί εὐε3ξ2ί εὐε3ξ2ι εὐπρό2σ1 εὐπρό2σ1 εὐπρό2ϲ1 εὐπρό2ϲ1 εὐπρο2σ1 εὐπρο2ϲ1 εὐσύ2ν1 εὐσύ2ν1 εὐϲύ2ν1 εὐϲύ2ν1 εὐσυ2ν1 εὐϲυ2ν1 εὐξύ2ν1 εὐξύ2ν1 εὐξυ2ν1 ἐω2σ1φ ἐω2ϲ1φ ἤ2ν1οψ. ἤ2ν1οπ ἠ2ν1όπ ἠ2ν1όπ .θεμι2σ1κρ .θεμι2ϲ1κρ .θεό2σ1δ .θεό2σ1δ .θεό2ϲ1δ .θεό2ϲ1δ .θεο2σ1δ .θεο2ϲ1δ .θεοι2σ1εχθρ .θεοι2ϲ1εχθρ .θη2ρ1αγρ .θυο2σ1κ .θυο2ϲ1κ .καθυπε2ρ1 .καλω2σ1ορ .καλω2ϲ1ορ .καλω2σ1όρ .καλω2σ1όρ .καλω2ϲ1όρ .καλω2ϲ1όρ .κα2ν1είς. .κα2ν1είς. .κα2ν1είϲ. .κα2ν1είϲ. .κα2ν1εὶς. .κα2ν1εὶϲ. .κα2ν1είσ. .κα2ν1είσ. .κα2ν1εὶσ. .κα2ν1εν .κα2ν1έν .κα2ν1έν .καταδυ2σ1ωπ .καταδυ2ϲ1ωπ .κατεδυ2σ1ώπ .κατεδυ2σ1ώπ .κατεδυ2ϲ1ώπ .κατεδυ2ϲ1ώπ .κατει2σ1 .κατει2ϲ1 .κατε2ν1αί .κατε2ν1αί .κατε2ν1ή .κατε2ν1ή .κατε2ξ1α2ν1ί .κατε2ξ1α2ν1ί .κατε2ξ1α2ν1έσ .κατε2ξ1α2ν1έσ .κατε2ξ1α2ν1έϲ .κατε2ξ1α2ν1έϲ .κερα2σ1φ .κερα2ϲ1φ .κρά2σ1π .κρά2σ1π .κρά2ϲ1π .κρά2ϲ1π .κρα2σ1π .κρα2ϲ1π .κυνό2σ1α .κυνό2σ1α .κυνό2ϲ1α .κυνό2ϲ1α .κυνό2σ1β .κυνό2σ1β .κυνό2ϲ1β .κυνό2ϲ1β .κυνο2σ1β .κυνο2ϲ1β .κυνό2σ1ο .κυνό2σ1ο .κυνό2ϲ1ο .κυνό2ϲ1ο .κυνο2σ1ο .κυνο2ϲ1ο .κυνο2σ1φ .κυνο2ϲ1φ .μελα2ν1άγ .μελα2ν1άγ .μελα2ν1αγ .μελα2ν1άε .μελα2ν1άε .μελα2ν1αέ .μελα2ν1αέ .μελα2ν1αθ .μελα2ν1αιγ .μελα2ν1αυγ .μελα2ν1είμ .μελα2ν1είμ .μελα2ν1εῖμ .μελά2ν1ιππ .μελά2ν1ιππ .μελα2ν1ίππ .μελα2ν1ίππ .μελα2ν1όμμ .μελα2ν1όμμ .μελα2ν1ομμ .μελά2ν1οσσ .μελά2ν1οσσ .μελά2ν1οϲϲ .μελά2ν1οϲϲ .μελα2ν1όσσ .μελα2ν1όσσ .μελα2ν1όϲϲ .μελα2ν1όϲϲ .μελά2ν1οστ .μελά2ν1οστ .μελά2ν1οϲτ .μελά2ν1οϲτ .μελα2ν1όστ .μελα2ν1όστ .μελα2ν1όϲτ .μελα2ν1όϲτ .μελά2ν1ουρ .μελά2ν1ουρ .μελα2ν1ούρ .μελα2ν1ούρ .μελα2ν1ουρ .μελά2ν1υ .μελά2ν1υ .μελα2ν1ύ .μελα2ν1ύ .μετε2ξ1α .μετε2ξ1έ .μετε2ξ1έ .μετε2ξ1ε .μογι2σ1 .μογι2ϲ1 .μογο2σ1τ .μογο2ϲ1τ .μυ2σ1π .μυ2ϲ1π .μυ2σ1επ .μυ2ϲ1επ .νεώ2σ1οικ .νεώ2σ1οικ .νεώ2ϲ1οικ .νεώ2ϲ1οικ .νεω2σ1οίκ .νεω2σ1οίκ .νεω2ϲ1οίκ .νεω2ϲ1οίκ .νου2ν1ε .ξυ2ν1αγ .ξυ2ν1ε .ξυ2ν1έ .ξυ2ν1έ .ξύ2ν1ε .ξύ2ν1ε .ξυ3ν2εώ .ξυ3ν2εώ .ξυ3ν2εῶ .ξυ2ν1ῆκ .ξύ2ν1ι .ξύ2ν1ι .ξυ2ν1ί .ξυ2ν1ί οἱο2ν1εί. οἱο2ν1εί. οἱο2ν1εὶ. οἱό2σ1 οἱό2σ1 οἱό2ϲ1 οἱό2ϲ1 οἰ2σ1πώτ οἰ2σ1πώτ οἰ2ϲ1πώτ οἰ2ϲ1πώτ οἰ2σ1πωτ οἰ2ϲ1πωτ ὁλο2ν1έν. ὁλο2ν1έν. ὁλο2ν1ὲν. ὁπω2σ1 ὁπω2ϲ1 ὅ2σ1γε. ὅ2ϲ1γε. ὁσο2ν1ῶν. ὁϲο2ν1ῶν. ὅ2σ1περ. ὅ2ϲ1περ. ὅ2σ1τις ὅ2ϲ1τιϲ οἷ2σ1τισι οἷ2ϲ1τιϲι οὕ2σ1τινας οὕ2ϲ1τιναϲ ἧ2σ1τινος ἧ2ϲ1τινοϲ αἷ2σ1τισι αἷ2ϲ1τιϲι ἅ2σ1τινας ἅ2ϲ1τιναϲ ὁ2σ1τι2σ1οῦν. ὁ2ϲ1τι2ϲ1οῦν. ἡτι2σ1οῦν. ἡτι2ϲ1οῦν. ὁποιου2σ1τινα2σ1οῦν. ὁποιου2ϲ1τινα2ϲ1οῦν. οὐδενό2σ1ω οὐδενό2σ1ω οὐδενό2ϲ1ω οὐδενό2ϲ1ω οὐδενο2σ1ώ οὐδενο2σ1ώ οὐδενο2ϲ1ώ οὐδενο2ϲ1ώ .παλι2ν1 .παλί2ν1 .παλί2ν1 .πα2ν1 .πά2ν1 .πά2ν1 .πα3ν2ός. .πα3ν2ός. .πα3ν2όϲ. .πα3ν2όϲ. .πα3ν2ὸς. .πα3ν2ὸϲ. .πα3ν2όσ. .πα3ν2όσ. .πα3ν2ὸσ. .πα3ν2ί. .πα3ν2ί. .πα3ν2ὶ. .πάνα. .πάνα. .πα3ν2ῶν. .πα3ν2ικ .πα3ν2ίσδ .πα3ν2ίσδ .πα3ν2ίϲδ .πα3ν2ίϲδ .πα3ν2ισδ .πα3ν2ιϲδ .πα3ν2οῦ. .πα3ν2ῷ. .πα3ν2ό. .πα3ν2ό. .πα3ν2ὸ. .πα3ν2όν. .πα3ν2όν. .πα3ν2ὸν. .πα3ν2έ. .πα3ν2έ. .πα3ν2ὲ. .πα3ν2οί. .πα3ν2οί. .πα3ν2οὶ. .πα3ν2οῖς. .πα3ν2οῖϲ. .πα3ν2οῖσ. .πα3ν2ούς. .πα3ν2ούς. .πα3ν2ούϲ. .πα3ν2ούϲ. .πα3ν2οὺς. .πα3ν2οὺϲ. .πα3ν2ούσ. .πα3ν2ούσ. .πα3ν2οὺσ. .παρα2ν1ίσχ .παρα2ν1ίσχ .παρα2ν1ίϲχ .παρα2ν1ίϲχ .παρεί2σ1 .παρεί2σ1 .παρεί2ϲ1 .παρεί2ϲ1 .παρει2σ1 .παρει2ϲ1 .παρε2κ1λ .παρε2κ1τρ .παρε2ν1εῖ .παρε2ν1ο .παρε2ξ1 .παρέ2ξ1 .παρέ2ξ1 παρέ3ξ2ω. παρέ3ξ2ω. παρέ3ξ2εις. παρέ3ξ2εις. παρέ3ξ2ειϲ. παρέ3ξ2ειϲ. παρέ3ξ2εισ. παρέ3ξ2εισ. παρέ3ξ2ει. παρέ3ξ2ει. παρέ3ξ2ετον. παρέ3ξ2ετον. παρε3ξ2έτην. παρε3ξ2έτην. παρέ3ξ2ομεν. παρέ3ξ2ομεν. παρέ3ξ2ετε. παρέ3ξ2ετε. παρέ3ξ2ουσι. παρέ3ξ2ουσι. παρέ3ξ2ουϲι. παρέ3ξ2ουϲι. παρέ3ξ2ομαι παρέ3ξ2ομαι παρέ3ξ2ῃ παρέ3ξ2ῃ παρέ3ξ2εται. παρέ3ξ2εται. παρέ3ξ2εσθον. παρέ3ξ2εσθον. παρέ3ξ2εϲθον. παρέ3ξ2εϲθον. παρε3ξ2όμεθα. παρε3ξ2όμεθα. παρέ3ξ2εσθε. παρέ3ξ2εσθε. παρέ3ξ2εϲθε. παρέ3ξ2εϲθε. παρέ3ξ2ονται. παρέ3ξ2ονται. .πλεο2ν1έ .πλεο2ν1έ .πλεο2ν1ε .προει2σ1 .προει2ϲ1 .προε2κ1 .προε2ν1 .προε2ξ1 .προέ2ξ1 .προέ2ξ1 .προ2σ1 .προ2ϲ1 .προ3σ2άβ .προ3σ2άβ .προ3ϲ2άβ .προ3ϲ2άβ .προ3σ2αβ .προ3ϲ2αβ .προσει2σ1 .προϲει2ϲ1 .προ3σ2εί .προ3σ2εί .προ3ϲ2εί .προ3ϲ2εί .προ3σ2έσει .προ3σ2έσει .προ3ϲ2έϲει .προ3ϲ2έϲει .προ3σ2εσεί .προ3σ2εσεί .προ3ϲ2εϲεί .προ3ϲ2εϲεί .προσε2ν1 .προϲε2ν1 .προσε2ξ1 .προϲε2ξ1 .πρό3σ2θι .πρό3σ2θι .πρό3ϲ2θι .πρό3ϲ2θι .προ3σ2θί .προ3σ2θί .προ3ϲ2θί .προ3ϲ2θί .προ4σ3θιγ .προ4ϲ3θιγ .πρό3σ2κοπ .πρό3σ2κοπ .πρό3ϲ2κοπ .πρό3ϲ2κοπ .προ3σ2κόπ .προ3σ2κόπ .προ3ϲ2κόπ .προ3ϲ2κόπ .προ3σ2τασ .προ3ϲ2ταϲ .προ3σ2τάτ .προ3σ2τάτ .προ3ϲ2τάτ .προ3ϲ2τάτ .προ3σ2τατ .προ3ϲ2τατ .προ3σ2ταυ .προ3ϲ2ταυ .προ3σ2τεί .προ3σ2τεί .προ3ϲ2τεί .προ3ϲ2τεί .προ3σ2τεν .προ3ϲ2τεν .προ3σ2τέν .προ3σ2τέν .προ3ϲ2τέν .προ3ϲ2τέν .προ3σ2τερν .προ3ϲ2τερν .πρό3σ2τερν .πρό3σ2τερν .πρό3ϲ2τερν .πρό3ϲ2τερν .προ3σ2τέρν .προ3σ2τέρν .προ3ϲ2τέρν .προ3ϲ2τέρν .προ3σ2τήσ .προ3σ2τήσ .προ3ϲ2τήϲ .προ3ϲ2τήϲ .προ3σ2τόμ .προ3σ2τόμ .προ3ϲ2τόμ .προ3ϲ2τόμ .προ3σ2τομ .προ3ϲ2τομ .πρό3σ2τῳ .πρό3σ2τῳ .πρό3ϲ2τῳ .πρό3ϲ2τῳ .προ3σ2τῴ .προ3ϲ2τῴ .προ3σ2υγ .προ3ϲ2υγ .προ3σ2υμ .προ3ϲ2υμ .προ3σ2υ2ν1 .προ3ϲ2υ2ν1 .πρό3σ2φαγμ .πρό3σ2φαγμ .πρό3ϲ2φαγμ .πρό3ϲ2φαγμ .προ3σ2φάγμ .προ3σ2φάγμ .προ3ϲ2φάγμ .προ3ϲ2φάγμ .προ3σ2φάζ .προ3σ2φάζ .προ3ϲ2φάζ .προ3ϲ2φάζ .προ3σ2φάττ .προ3σ2φάττ .προ3ϲ2φάττ .προ3ϲ2φάττ .πρό3σ2χημ .πρό3σ2χημ .πρό3ϲ2χημ .πρό3ϲ2χημ .προ3σ2χήμ .προ3σ2χήμ .προ3ϲ2χήμ .προ3ϲ2χήμ .πρό3σ2ω. .πρό3σ2ω. .πρό3ϲ2ω. .πρό3ϲ2ω. .πρό3σ2ωθεν. .πρό3σ2ωθεν. .πρό3ϲ2ωθεν. .πρό3ϲ2ωθεν. .προ3σ2ώτ .προ3σ2ώτ .προ3ϲ2ώτ .προ3ϲ2ώτ .προ3σ2ωτ .προ3ϲ2ωτ .προϋπε2ξ1 .πυ2ρ1άγ .πυ2ρ1άγ .πυ2ρ1αγ .πυ2ρ1αίθ .πυ2ρ1αίθ .πυ2ρ1αιθ .πυ2ρ1ῆθ .πυ2ρ1ηθ .πυ2ρ1ήθ .πυ2ρ1ήθ .πυ2ρ1ακ .πύ2ρ1αυ .πύ2ρ1αυ .πυ2ρ1αύ .πυ2ρ1αύ .πυ2ρ1αυ .πυ2ρ1ήνεμ .πυ2ρ1ήνεμ .πυ2ρ1ηνέμ .πυ2ρ1ηνέμ .πυ2ρ1ωπ .σελα2σ1φό .σελα2σ1φό .ϲελα2ϲ1φό .ϲελα2ϲ1φό .σελα2σ1φο .ϲελα2ϲ1φο .συμπαρει2σ1 .ϲυμπαρει2ϲ1 .συ2ν1 .ϲυ2ν1 .σύ2ν1 .σύ2ν1 .ϲύ2ν1 .ϲύ2ν1 .συνδιέ2ξ1 .συνδιέ2ξ1 .ϲυνδιέ2ξ1 .ϲυνδιέ2ξ1 .συνδιε2ξ1 .ϲυνδιε2ξ1 .συνδυ2σ1 .ϲυνδυ2ϲ1 .συνε2ξ1 .ϲυνε2ξ1 .τεσσαρε2σ1κ .τεϲϲαρε2ϲ1κ .τρει2σ1κ .τρει2ϲ1κ .τρι2σ1 .τρι2ϲ1 .τρι3σ2μό .τρι3σ2μό .τρι3ϲ2μό .τρι3ϲ2μό .τρι3σ2μο .τρι3ϲ2μο .τρι3σ2μῶ .τρι3ϲ2μῶ .τρι3σ2π .τρι3ϲ2π .τρί3σ2τ .τρί3σ2τ .τρί3ϲ2τ .τρί3ϲ2τ .τρι3σ2τ .τρι3ϲ2τ .τρι3σ2ώ .τρι3σ2ώ .τρι3ϲ2ώ .τρι3ϲ2ώ .τρι3σ2ω .τρι3ϲ2ω ὑο2σ1κ ὑο2ϲ1κ ὑπεί2σ1 ὑπεί2σ1 ὑπεί2ϲ1 ὑπεί2ϲ1 ὑπει2σ1 ὑπει2ϲ1 ὑπεί3σ2ας ὑπεί3σ2ας ὑπεί3ϲ2αϲ ὑπεί3ϲ2αϲ ὑπεί3σ2ασ ὑπεί3σ2ασ ὑπεί3σ2αν ὑπεί3σ2αν ὑπεί3ϲ2αν ὑπεί3ϲ2αν ὑπει3σ2άν ὑπει3σ2άν ὑπει3ϲ2άν ὑπει3ϲ2άν ὑπει3σ2άσ ὑπει3σ2άσ ὑπει3ϲ2άϲ ὑπει3ϲ2άϲ ὑπε2κ1λαμ ὑπε2κ1λήψ ὑπε2κ1λήψ ὑπε2κ1τ ὑπε2ν1 ὑπε2ξ1 ὑπε2ρ1 ὑπέ2ρ1 ὑπέ2ρ1 ὑπέ3ρ2α. ὑπέ3ρ2α. ὑπέ3ρ2ης. ὑπέ3ρ2ης. ὑπέ3ρ2ηϲ. ὑπέ3ρ2ηϲ. ὑπέ3ρ2ησ. ὑπέ3ρ2ησ. ὑπέ3ρ2ᾳ. ὑπέ3ρ2ᾳ. ὑπέ3ρ2αν. ὑπέ3ρ2αν. ὑπέ3ρ2αι. ὑπέ3ρ2αι. ὑπε3ρ2ῶν. ὑπέ3ρ2αις. ὑπέ3ρ2αις. ὑπέ3ρ2αιϲ. ὑπέ3ρ2αιϲ. ὑπέ3ρ2αισ. ὑπέ3ρ2αισ. ὑπέ3ρ2ας. ὑπέ3ρ2ας. ὑπέ3ρ2αϲ. ὑπέ3ρ2αϲ. ὑπέ3ρ2ασ. ὑπέ3ρ2ασ. ὑπε3ρ2εθ ὑπε3ρ2έθ ὑπε3ρ2έθ ὑπε3ρ2εί ὑπε3ρ2εί ὑπέ3ρ2υθ ὑπέ3ρ2υθ ὑπε3ρ2ύθ ὑπε3ρ2ύθ ὑπε3ρ2υθ ὑπερε2κ1τε ὑπερε2κ1τί ὑπερε2κ1τί ὑπε3ρ2έπτ ὑπε3ρ2έπτ ὑπε3ρ2επτ ὑπε3ρ2έψ ὑπε3ρ2έψ ὑπε3ρ2εψ ὑπε3ρ2έω ὑπε3ρ2έω ὑπε3ρ2ῶ ὑπε3ρ2έε ὑπε3ρ2έε ὑπε3ρ2εῖς. ὑπε3ρ2εῖϲ. ὑπε3ρ2εῖσ. ὑπε3ρ2εῖ. ὑπε3ρ2έο ὑπε3ρ2έο ὑπε3ρ2οῦ ὑπε3ρ2εῖτ ὑπε3ρ2ώ ὑπε3ρ2ώ ὑπε3ρ2ω ὕ2σ1τρ ὕ2ϲ1τρ ὑ2σ1τρ ὑ2ϲ1τρ .φαε2σ1φ .φαε2ϲ1φ .φω2σ1φ .φω2ϲ1φ .χαρι2σ1ανδρ .χαρι2ϲ1ανδρ .χαρι2σ1άνδρ .χαρι2σ1άνδρ .χαρι2ϲ1άνδρ .χαρι2ϲ1άνδρ .χει2ρ1άγ .χει2ρ1άγ .χει2ρ1αγ .χει2ρ1απ .χει2ρ1αψ .χει2ρ1ου .χει2ρ1ῶν .χει2ρ1άν .χει2ρ1άν .χει2ρ1αν .χη2ν1ναλ ὡ2σ1α2ν1εί. ὡ2σ1α2ν1εί. ὡ2ϲ1α2ν1εί. ὡ2ϲ1α2ν1εί. ὡ2σ1α2ν1εὶ. ὡ2ϲ1α2ν1εὶ. ὡ2σ1αύτως. ὡ2σ1αύτως. ὡ2ϲ1αύτωϲ. ὡ2ϲ1αύτωϲ. ὡ2σ1αύτωσ. ὡ2σ1αύτωσ. ὡ2σ1εί. ὡ2σ1εί. ὡ2ϲ1εί. ὡ2ϲ1εί. ὡ2σ1εὶ. ὡ2ϲ1εὶ. ὥ2σ1περ. ὥ2ϲ1περ. ὡ2σ1πε2ρ1εί. ὡ2σ1πε2ρ1εί. ὡ2ϲ1πε2ρ1εί. ὡ2ϲ1πε2ρ1εί. ὡ2σ1πε2ρ1εὶ. ὡ2ϲ1πε2ρ1εὶ. ὥ2σ1τε ὥ2ϲ1τε ι2σ1χίλιοι. ι2σ1χίλιοι. ι2ϲ1χίλιοι. ι2ϲ1χίλιοι. ι2σ1χιλίων. ι2σ1χιλίων. ι2ϲ1χιλίων. ι2ϲ1χιλίων. ι2σ1χιλίοις. ι2σ1χιλίοις. ι2ϲ1χιλίοιϲ. ι2ϲ1χιλίοιϲ. ι2σ1χιλίοισ. ι2σ1χιλίοισ. ι2σ1χιλίους. ι2σ1χιλίους. ι2ϲ1χιλίουϲ. ι2ϲ1χιλίουϲ. ι2σ1χιλίουσ. ι2σ1χιλίουσ. ι2σ1χίλιαι. ι2σ1χίλιαι. ι2ϲ1χίλιαι. ι2ϲ1χίλιαι. ι2σ1χιλίαις. ι2σ1χιλίαις. ι2ϲ1χιλίαιϲ. ι2ϲ1χιλίαιϲ. ι2σ1χιλίαισ. ι2σ1χιλίαισ. ι2σ1χιλίας. ι2σ1χιλίας. ι2ϲ1χιλίαϲ. ι2ϲ1χιλίαϲ. ι2σ1χιλίασ. ι2σ1χιλίασ. ι2σ1χίλια. ι2σ1χίλια. ι2ϲ1χίλια. ι2ϲ1χίλια. ι2σ1μύριοι. ι2σ1μύριοι. ι2ϲ1μύριοι. ι2ϲ1μύριοι. ι2σ1μυρίων. ι2σ1μυρίων. ι2ϲ1μυρίων. ι2ϲ1μυρίων. ι2σ1μυρίοις. ι2σ1μυρίοις. ι2ϲ1μυρίοιϲ. ι2ϲ1μυρίοιϲ. ι2σ1μυρίοισ. ι2σ1μυρίοισ. ι2σ1μυρίους. ι2σ1μυρίους. ι2ϲ1μυρίουϲ. ι2ϲ1μυρίουϲ. ι2σ1μυρίουσ. ι2σ1μυρίουσ. ι2σ1μύριαι. ι2σ1μύριαι. ι2ϲ1μύριαι. ι2ϲ1μύριαι. ι2σ1μυρίαις. ι2σ1μυρίαις. ι2ϲ1μυρίαιϲ. ι2ϲ1μυρίαιϲ. ι2σ1μυρίαισ. ι2σ1μυρίαισ. ι2σ1μυρίας. ι2σ1μυρίας. ι2ϲ1μυρίαϲ. ι2ϲ1μυρίαϲ. ι2σ1μυρίασ. ι2σ1μυρίασ. ι2σ1μύρια. ι2σ1μύρια. ι2ϲ1μύρια. ι2ϲ1μύρια. ι2σ1χιλιοστ ι2ϲ1χιλιοϲτ ι2σ1μυριοστ ι2ϲ1μυριοϲτ ι2σ1χιλιάκις. ι2σ1χιλιάκις. ι2ϲ1χιλιάκιϲ. ι2ϲ1χιλιάκιϲ. ι2σ1χιλιάκισ. ι2σ1χιλιάκισ. ι2σ1μυριάκις. ι2σ1μυριάκις. ι2ϲ1μυριάκιϲ. ι2ϲ1μυριάκιϲ. ι2σ1μυριάκισ. ι2σ1μυριάκισ.", + ["characters"]="'ʼΐάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώϐϲἀἁἂἃἄἅἆἇἐἑἒἓἔἕἠἡἢἣἤἥἦἧἰἱἲἳἴἵἶἷὀὁὂὃὄὅὐὑὒὓὔὕὖὗὠὡὢὣὤὥὦὧὰάὲέὴήὶίὸόὺύὼώᾀᾁᾂᾃᾄᾅᾆᾇᾐᾑᾒᾓᾔᾕᾖᾗᾠᾡᾢᾣᾤᾥᾦᾧᾲᾳᾴᾶᾷ᾽᾿ῂῃῄῆῇῒΐῖῗῢΰῤῥῦῧῲῳῴῶῷ’", + ["data"]="α1 ε1 η1 ι1 ο1 υ1 ω1 ϊ1 ϋ1 ἀ1 ἁ1 ἂ1 ἃ1 ἄ1 ἅ1 ἆ1 ἇ1 ἐ1 ἑ1 ἒ1 ἓ1 ἔ1 ἕ1 ἠ1 ἡ1 ἢ1 ἣ1 ἤ1 ἥ1 ἦ1 ἧ1 ἰ1 ἱ1 ἲ1 ἳ1 ἴ1 ἵ1 ἶ1 ἷ1 ὀ1 ὁ1 ὂ1 ὃ1 ὄ1 ὅ1 ὐ1 ὑ1 ὒ1 ὓ1 ὔ1 ὕ1 ὖ1 ὗ1 ὠ1 ὡ1 ὢ1 ὣ1 ὤ1 ὥ1 ὦ1 ὧ1 ὰ1 ὲ1 ὴ1 ὶ1 ὸ1 ὺ1 ὼ1 ᾀ1 ᾁ1 ᾂ1 ᾃ1 ᾄ1 ᾅ1 ᾆ1 ᾇ1 ᾐ1 ᾑ1 ᾒ1 ᾓ1 ᾔ1 ᾕ1 ᾖ1 ᾗ1 ᾠ1 ᾡ1 ᾢ1 ᾣ1 ᾤ1 ᾥ1 ᾦ1 ᾧ1 ᾲ1 ᾳ1 ᾴ1 ᾶ1 ᾷ1 ῂ1 ῃ1 ῄ1 ῆ1 ῇ1 ῒ1 ῖ1 ῗ1 ῢ1 ῦ1 ῧ1 ῲ1 ῳ1 ῴ1 ῶ1 ῷ1 ά1 έ1 ή1 ί1 ό1 ύ1 ώ1 ΐ1 ΰ1 ά1 έ1 ή1 ί1 ό1 ύ1 ώ1 ΐ1 ΰ1 α2ι α2ί α2ί α2ὶ α2ῖ α2ἰ α2ἴ α2ἲ α2ἶ α2ἱ α2ἵ α2ἳ α2ἷ ά3ι ά3ι ᾶ3ι ἀ3ι ἁ3ι α2υ α2ύ α2ύ α2ὺ α2ῦ α2ὐ α2ὔ α2ὒ α2ὖ α2ὑ α2ὕ α2ὓ α2ὗ ά3υ ά3υ ᾶ3υ ἀ3υ ἁ3υ ε2ι ε2ί ε2ί ε2ὶ ε2ῖ ε2ἰ ε2ἴ ε2ἲ ε2ἶ ε2ἱ ε2ἵ ε2ἳ ε2ἷ έ3ι έ3ι ἐ3ι ἑ3ι ε2υ ε2ύ ε2ύ ε2ὺ ε2ῦ ε2ὐ ε2ὔ ε2ὒ ε2ὖ ε2ὑ ε2ὕ ε2ὓ ε2ὗ έ3υ έ3υ ἑ3υ ἐ3υ η2υ η2ύ η2ύ η2ὺ η2ῦ η2ὐ η2ὔ η2ὒ η2ὖ η2ὑ η2ὕ η2ὓ η2ὗ ή3υ ή3υ ῆ3υ ἠ3υ ἡ3υ ο2ι ο2ί ο2ί ο2ὶ ο2ῖ ο2ἰ ο2ἴ ο2ἲ ο2ἶ ο2ἱ ο2ἵ ο2ἳ ο2ἷ ό3ι ό3ι ὀ3ι ὁ3ι ο2υ ο2ύ ο2ύ ο2ὺ ο2ῦ ο2ὐ ο2ὔ ο2ὒ ο2ὖ ο2ὑ ο2ὕ ο2ὓ ο2ὗ ό3υ ό3υ ὀ3υ ὁ3υ υ2ι υ2ί υ2ί υ2ὶ υ2ῖ υ2ἰ υ2ἴ υ2ἲ υ2ἶ υ2ἱ υ2ἵ υ2ἳ υ2ἷ ύ3ι ύ3ι ῦ3ι ὐ3ι ὑ3ι ου3ι όυ4ι όυ4ι ὀυ4ι ὁυ4ι ο3υί ο3υί ο3υῖ 4β. 4ϐ. 4γ. 4δ. 4ζ. 4θ. 4κ. 4λ. 4μ. 4ν. 4ξ. 4π. 4ρ. 4σ. 4ϲ. 4ς. 4τ. 4φ. 4χ. 4ψ. 4' 4ʼ 4᾿ 4β' 4βʼ 4β᾿ 4ϐ' 4ϐʼ 4ϐ᾿ 4γ' 4γʼ 4γ᾿ 4δ' 4δʼ 4δ᾿ 4ζ' 4ζʼ 4ζ᾿ 4θ' 4θʼ 4θ᾿ 4κ' 4κʼ 4κ᾿ 4λ' 4λʼ 4λ᾿ 4μ' 4μʼ 4μ᾿ 4ν' 4νʼ 4ν᾿ 4ξ' 4ξʼ 4ξ᾿ 4π' 4πʼ 4π᾿ 4ρ' 4ρʼ 4ρ᾿ 4σ' 4σʼ 4σ᾿ 4ϲ' 4ϲʼ 4ϲ᾿ 4τ' 4τʼ 4τ᾿ 4φ' 4φʼ 4φ᾿ 4χ' 4χʼ 4χ᾿ 4ψ' 4ψʼ 4ψ᾿ .β4 .ϐ4 .γ4 .δ4 .ζ4 .θ4 .κ4 .λ4 .μ4 .ν4 .ξ4 .π4 .ρ4 .σ4 .ϲ4 .τ4 .φ4 .χ4 .ψ4 2β1β 2ϐ1ϐ 2γ1γ 2δ1δ 2ζ1ζ 2θ1θ 2κ1κ 2λ1λ 2μ1μ 2ν1ν 2π1π 2ρ1ρ 2ῤ1ῥ 2σ1σ 2ϲ1ϲ 2τ1τ 2φ1φ 2χ1χ 2ψ1ψ 2β1γ 2ϐ1γ 2β1ζ 2ϐ1ζ 2β1θ 2ϐ1θ 2β1κ 2ϐ1κ 2β1ξ 2ϐ1ξ 2β1π 2ϐ1π 2β1σ 2β1ϲ 2ϐ1σ 2ϐ1ϲ 2β1τ 2ϐ1τ 2β1φ 2ϐ1φ 2β1χ 2ϐ1χ 2β1ψ 2ϐ1ψ 2γ1β 2γ1ϐ 2γ1ζ 2γ1θ 2γ1κ 2γ1ξ 2γ1π 2γ1σ 2γ1ϲ 2γ1τ 2γ1φ 2γ1χ 2γ1ψ 2δ1β 2δ1ϐ 2δ1γ 2δ1ζ 2δ1θ 2δ1κ 2δ1λ 2δ1ξ 2δ1π 2δ1σ 2δ1ϲ 2δ1τ 2δ1φ 2δ1χ 2δ1ψ 2ζ1β 2ζ1ϐ 2ζ1γ 2ζ1δ 2ζ1θ 2ζ1κ 2ζ1λ 2ζ1μ 2ζ1ν 2ζ1ξ 2ζ1π 2ζ1ρ 2ζ1σ 2ζ1ϲ 2ζ1τ 2ζ1φ 2ζ1χ 2ζ1ψ 2θ1β 2θ1ϐ 2θ1γ 2θ1δ 2θ1ζ 2θ1κ 2θ1ξ 2θ1π 2θ1σ 2θ1ϲ 2θ1τ 2θ1φ 2θ1χ 2θ1ψ 2κ1β 2κ1ϐ 2κ1γ 2κ1δ 2κ1ζ 2κ1θ 2κ1ξ 2κ1π 2κ1σ 2κ1ϲ 2κ1φ 2κ1χ 2κ1ψ 2λ1β 2λ1ϐ 2λ1γ 2λ1δ 2λ1ζ 2λ1θ 2λ1κ 2λ1μ 2λ1ν 2λ1ξ 2λ1π 2λ1ρ 2λ1σ 2λ1ϲ 2λ1τ 2λ1φ 2λ1χ 2λ1ψ 2μ1β 2μ1ϐ 2μ1γ 2μ1δ 2μ1ζ 2μ1θ 2μ1κ 2μ1λ 2μ1ξ 2μ1π 2μ1ρ 2μ1σ 2μ1ϲ 2μ1τ 2μ1φ 2μ1χ 2μ1ψ 2ν1β 2ν1ϐ 2ν1γ 2ν1δ 2ν1ζ 2ν1θ 2ν1κ 2ν1λ 2ν1μ 2ν1ξ 2ν1π 2ν1ρ 2ν1σ 2ν1ϲ 2νς. 2νϲ. 2ν1τ 2ν1φ 2ν1χ 2ν1ψ 2ξ1β 2ξ1ϐ 2ξ1γ 2ξ1δ 2ξ1ζ 2ξ1θ 2ξ1κ 2ξ1λ 2ξ1μ 2ξ1ν 2ξ1π 2ξ1ρ 2ξ1σ 2ξ1ϲ 2ξ1τ 2ξ1φ 2ξ1χ 2ξ1ψ 2π1β 2π1ϐ 2π1γ 2π1δ 2π1ζ 2π1θ 2π1κ 2π1ξ 2π1σ 2π1ϲ 2π1φ 2π1χ 2π1ψ 2ρ1β 2ρ1ϐ 2ρ1γ 2ρ1δ 2ρ1ζ 2ρ1θ 2ρ1κ 2ρ1λ 2ρ1μ 2ρ1ν 2ρ1ξ 2ρ1π 2ρ1σ 2ρ1ϲ 2ρ1τ 2ρ1φ 2ρ1χ 2ρ1ψ 2σ1δ 2ϲ1δ 2σ1ζ 2ϲ1ζ 2σ1λ 2ϲ1λ 2σ1ν 2ϲ1ν 2σ1ξ 2ϲ1ξ 2σ1ρ 2ϲ1ρ 2σ1ψ 2ϲ1ψ 2τ1β 2τ1ϐ 2τ1γ 2τ1δ 2τ1ζ 2τ1θ 2τ1κ 2τ1ξ 2τ1π 2τ1σ 2τ1ϲ 2τ1φ 2τ1χ 2τ1ψ 2φ1β 2φ1ϐ 2φ1γ 2φ1δ 2φ1ζ 2φ1κ 2φ1ξ 2φ1π 2φ1σ 2φ1ϲ 2φ1τ 2φ1χ 2φ1ψ 2χ1β 2χ1ϐ 2χ1γ 2χ1δ 2χ1ζ 2χ1κ 2χ1ξ 2χ1π 2χ1σ 2χ1ϲ 2χ1τ 2χ1φ 2χ1ψ 2ψ1β 2ψ1ϐ 2ψ1γ 2ψ1δ 2ψ1ζ 2ψ1θ 2ψ1κ 2ψ1λ 2ψ1μ 2ψ1ν 2ψ1ξ 2ψ1π 2ψ1ρ 2ψ1σ 2ψ1ϲ 2ψ1τ 2ψ1φ 2ψ1χ 4βδ' 4βδ’ 4βδʼ 4βδ᾽ 4βδ᾿ 4ϐδ' 4ϐδ’ 4ϐδʼ 4ϐδ᾽ 4ϐδ᾿ 4βλ' 4βλ’ 4βλʼ 4βλ᾽ 4βλ᾿ 4ϐλ' 4ϐλ’ 4ϐλʼ 4ϐλ᾽ 4ϐλ᾿ 4βμ' 4βμ’ 4βμʼ 4βμ᾽ 4βμ᾿ 4ϐμ' 4ϐμ’ 4ϐμʼ 4ϐμ᾽ 4ϐμ᾿ 4βν' 4βν’ 4βνʼ 4βν᾽ 4βν᾿ 4ϐν' 4ϐν’ 4ϐνʼ 4ϐν᾽ 4ϐν᾿ 4βρ' 4βρ’ 4βρʼ 4βρ᾽ 4βρ᾿ 4ϐρ' 4ϐρ’ 4ϐρʼ 4ϐρ᾽ 4ϐρ᾿ 4γδ' 4γδ’ 4γδʼ 4γδ᾽ 4γδ᾿ 4γλ' 4γλ’ 4γλʼ 4γλ᾽ 4γλ᾿ 4γμ' 4γμ’ 4γμʼ 4γμ᾽ 4γμ᾿ 4γν' 4γν’ 4γνʼ 4γν᾽ 4γν᾿ 4γρ' 4γρ’ 4γρʼ 4γρ᾽ 4γρ᾿ 4δμ' 4δμ’ 4δμʼ 4δμ᾽ 4δμ᾿ 4δν' 4δν’ 4δνʼ 4δν᾽ 4δν᾿ 4δρ' 4δρ’ 4δρʼ 4δρ᾽ 4δρ᾿ 4ζβ' 4ζβ’ 4ζβʼ 4ζβ᾽ 4ζβ᾿ 4ζϐ' 4ζϐ’ 4ζϐʼ 4ζϐ᾽ 4ζϐ᾿ 4θλ' 4θλ’ 4θλʼ 4θλ᾽ 4θλ᾿ 4λμ' 4λμ’ 4λμʼ 4λμ᾽ 4λμ᾿ 4θν' 4θν’ 4θνʼ 4θν᾽ 4θν᾿ 4θρ' 4θρ’ 4θρʼ 4θρ᾽ 4θρ᾿ 4κλ' 4κλ’ 4κλʼ 4κλ᾽ 4κλ᾿ 4κμ' 4κμ’ 4κμʼ 4κμ᾽ 4κμ᾿ 4κν' 4κν’ 4κνʼ 4κν᾽ 4κν᾿ 4κρ' 4κρ’ 4κρʼ 4κρ᾽ 4κρ᾿ 4κτ' 4κτ’ 4κτʼ 4κτ᾽ 4κτ᾿ 4μν' 4μν’ 4μνʼ 4μν᾽ 4μν᾿ 4πλ' 4πλ’ 4πλʼ 4πλ᾽ 4πλ᾿ 4πμ' 4πμ’ 4πμʼ 4πμ᾽ 4πμ᾿ 4πν' 4πν’ 4πνʼ 4πν᾽ 4πν᾿ 4πρ' 4πρ’ 4πρʼ 4πρ᾽ 4πρ᾿ 4πτ' 4πτ’ 4πτʼ 4πτ᾽ 4πτ᾿ 4σβ' 4σβ’ 4σβʼ 4σβ᾽ 4σβ᾿ 4ϲβ' 4ϲβ’ 4ϲβʼ 4ϲβ᾽ 4ϲβ᾿ 4σϐ' 4σϐ’ 4σϐʼ 4σϐ᾽ 4σϐ᾿ 4ϲϐ' 4ϲϐ’ 4ϲϐʼ 4ϲϐ᾽ 4ϲϐ᾿ 4σγ' 4σγ’ 4σγʼ 4σγ᾽ 4σγ᾿ 4ϲγ' 4ϲγ’ 4ϲγʼ 4ϲγ᾽ 4ϲγ᾿ 4σδ' 4σδ’ 4σδʼ 4σδ᾽ 4σδ᾿ 4ϲδ' 4ϲδ’ 4ϲδʼ 4ϲδ᾽ 4ϲδ᾿ 4σθ' 4σθ’ 4σθʼ 4σθ᾽ 4σθ᾿ 4ϲθ' 4ϲθ’ 4ϲθʼ 4ϲθ᾽ 4ϲθ᾿ 4σκ' 4σκ’ 4σκʼ 4σκ᾽ 4σκ᾿ 4ϲκ' 4ϲκ’ 4ϲκʼ 4ϲκ᾽ 4ϲκ᾿ 4σμ' 4σμ’ 4σμʼ 4σμ᾽ 4σμ᾿ 4ϲμ' 4ϲμ’ 4ϲμʼ 4ϲμ᾽ 4ϲμ᾿ 4σπ' 4σπ’ 4σπʼ 4σπ᾽ 4σπ᾿ 4ϲπ' 4ϲπ’ 4ϲπʼ 4ϲπ᾽ 4ϲπ᾿ 4στ' 4στ’ 4στʼ 4στ᾽ 4στ᾿ 4ϲτ' 4ϲτ’ 4ϲτʼ 4ϲτ᾽ 4ϲτ᾿ 4σφ' 4σφ’ 4σφʼ 4σφ᾽ 4σφ᾿ 4ϲφ' 4ϲφ’ 4ϲφʼ 4ϲφ᾽ 4ϲφ᾿ 4σχ' 4σχ’ 4σχʼ 4σχ᾽ 4σχ᾿ 4ϲχ' 4ϲχ’ 4ϲχʼ 4ϲχ᾽ 4ϲχ᾿ 4φθ' 4φθ’ 4φθʼ 4φθ᾽ 4φθ᾿ 4φλ' 4φλ’ 4φλʼ 4φλ᾽ 4φλ᾿ 4φμ' 4φμ’ 4φμʼ 4φμ᾽ 4φμ᾿ 4φν' 4φν’ 4φνʼ 4φν᾽ 4φν᾿ 4φρ' 4φρ’ 4φρʼ 4φρ᾽ 4φρ᾿ 4χθ' 4χθ’ 4χθʼ 4χθ᾽ 4χθ᾿ 4χλ' 4χλ’ 4χλʼ 4χλ᾽ 4χλ᾿ 4χμ' 4χμ’ 4χμʼ 4χμ᾽ 4χμ᾿ 4χν' 4χν’ 4χνʼ 4χν᾽ 4χν᾿ 4χρ' 4χρ’ 4χρʼ 4χρ᾽ 4χρ᾿ ἀγω2ν1άρ ἀγω2ν1άρ ἀγω2ν1αρ ἀδιέ2ξ1 ἀδιέ2ξ1 ἀδιε2ξ1 ἀδυ2σ1ώ ἀδυ2σ1ώ ἀδυ2ϲ1ώ ἀδυ2ϲ1ώ ἀδυ2σ1ω ἀδυ2ϲ1ω ἁλό2σ1 ἁλό2σ1 ἁλό2ϲ1 ἁλό2ϲ1 ἁλο2σ1 ἁλο2ϲ1 ἀμπαλί2ν1 ἀμπαλί2ν1 ἀμπαλι2ν1 ἀμφί2σ1β ἀμφί2σ1β ἀμφί2ϲ1β ἀμφί2ϲ1β ἀμφί2σ1ϐ ἀμφί2σ1ϐ ἀμφί2ϲ1ϐ ἀμφί2ϲ1ϐ ἀμφι2σ1β ἀμφι2ϲ1β ἀμφι2σ1ϐ ἀμφι2ϲ1ϐ ἀμφί2σ1ω ἀμφί2σ1ω ἀμφί2ϲ1ω ἀμφί2ϲ1ω ἀμφι2σ1ώ ἀμφι2σ1ώ ἀμφι2ϲ1ώ ἀμφι2ϲ1ώ ἀ2ν1αγής. ἀ2ν1αγής. ἀ2ν1αγήϲ. ἀ2ν1αγήϲ. ἀ2ν1αγὴς. ἀ2ν1αγὴϲ. ἀ2ν1αγήσ. ἀ2ν1αγήσ. ἀ2ν1αγὴσ. ἀ2ν1αγο ἀ2ν1αγεῖ. ἀ2ν1αγῆ. ἀ2ν1αγές. ἀ2ν1αγές. ἀ2ν1αγέϲ. ἀ2ν1αγέϲ. ἀ2ν1αγὲς. ἀ2ν1αγὲϲ. ἀ2ν1αγέσ. ἀ2ν1αγέσ. ἀ2ν1αγὲσ. ἀ2ν1αγεῖς. ἀ2ν1αγεῖϲ. ἀ2ν1αγεῖσ. ἀ2ν1αγῶν. ἀ2ν1αγέσι ἀ2ν1αγέσι ἀ2ν1αγέϲι ἀ2ν1αγέϲι ἀ2ν1αγῆ ἀ2ν1άγκυ ἀ2ν1άγκυ ἀ2ν1αγκύ ἀ2ν1αγκύ ἄ2ν1αγν ἀ2ν1άγν ἀ2ν1άγν ἀ2ν1αγν ἀ3ν2αγνά ἀ3ν2αγνά ἀ3ν2αγνω ἀ3ν2άγνω ἀ3ν2άγνω ἀ3ν2αγνώ ἀ3ν2αγνώ ἀ2ν1αγρί ἀ2ν1αγρί ἀ2ν1αγρῖ ἀ2ν1αγρι ἀ2ν1άγωγ ἀ2ν1άγωγ ἀ2ν1αγώγ ἀ2ν1αγώγ ἀ3ν2αγώγι ἀ3ν2αγώγι ἀ3ν2αγωγί ἀ3ν2αγωγί ἀ4ν3αγωγία ἀ4ν3αγωγία ἀ2ν1άδελ ἀ2ν1άδελ ἀ2ν1αδέλ ἀ2ν1αδέλ ἀ2ν1άελπ ἀ2ν1άελπ ἀ2ν1αέλπ ἀ2ν1αέλπ ἄ2ν1αθλ ἀ2ν1άθλ ἀ2ν1άθλ ἀ2ν1αίδ ἀ2ν1αίδ ἀ2ν1αιδ ἄ2ν1αιμ ἀ2ν1αίμ ἀ2ν1αίμ ἀ2ν1αιμ ἀ2ν1αίσθ ἀ2ν1αίσθ ἀ2ν1αίϲθ ἀ2ν1αίϲθ ἀ2ν1αισθ ἀ2ν1αιϲθ ἀ2ν1αισι ἀ2ν1αιϲι ἀ2ν1αισί ἀ2ν1αισί ἀ2ν1αιϲί ἀ2ν1αιϲί ἀ2ν1αίσχ ἀ2ν1αίσχ ἀ2ν1αίϲχ ἀ2ν1αίϲχ ἀ2ν1αισχ ἀ2ν1αιϲχ ἀ2ν1αίτ ἀ2ν1αίτ ἀ2ν1αιτ ἀ2ν1άκαν ἀ2ν1άκαν ἀ2ν1ακάν ἀ2ν1ακάν ἀ2ν1ακόλο ἀ2ν1ακόλο ἀ2ν1ακολο ἀ2ν1αλγ ἀ2ν1αλδ ἀ3ν2αλδα ἀ3ν2αλδήσκ ἀ3ν2αλδήσκ ἀ3ν2αλδήϲκ ἀ3ν2αλδήϲκ ἀ2ν1άλειπ ἀ2ν1άλειπ ἀ2ν1αλείπ ἀ2ν1αλείπ ἀ2ν1αλειφ ἀ2ν1άλειφ ἀ2ν1άλειφ ἀ2ν1αλείφ ἀ2ν1αλείφ ἀ2ν1αλήθ ἀ2ν1αλήθ ἀ2ν1αληθ ἀ2ν1άλθ ἀ2ν1άλθ ἀ2ν1αλθ ἀ2ν1άλιπ ἀ2ν1άλιπ ἀ2ν1αλίπ ἀ2ν1αλίπ ἀ2ν1άλιστ ἀ2ν1άλιστ ἀ2ν1άλιϲτ ἀ2ν1άλιϲτ ἀ2ν1αλίστ ἀ2ν1αλίστ ἀ2ν1αλίϲτ ἀ2ν1αλίϲτ ἀ2ν1αλκ ἄ2ν1αλκ ἀ2ν1άλκ ἀ2ν1άλκ ἀ2ν1άλλ ἀ2ν1άλλ ἀ2ν1αλλ ἀ3ν2άλλο ἀ3ν2άλλο ἀ3ν2άλλε ἀ3ν2άλλε ἄ2ν1αλμ ἀ2ν1άλμ ἀ2ν1άλμ ἀ2ν1αλμ ἄ2ν1αλο ἀ2ν1άλου ἀ2ν1άλου ἀ2ν1άλῳ. ἀ2ν1άλῳ. ἄ2ν1αλε. ἀ2ν1άλοι ἀ2ν1άλοι ἀ2ν1άλων. ἀ2ν1άλων. ἄ2ν1αλτ ἀ2ν1άλτ ἀ2ν1άλτ ἀ2ν1αμάξ ἀ2ν1αμάξ ἀ2ν1αμαξ ἀ2ν1αμάρτ ἀ2ν1αμάρτ ἀ2ν1αμαρτ ἀ2ν1αμέλγ ἀ2ν1αμέλγ ἀ2ν1αμελγ ἀ2ν1αμπ ἀ2ν1άμπ ἀ2ν1άμπ ἀ2ν1αμφ ἀναμφι2σ1 ἀναμφι2ϲ1 ἀ2ν1ανάγκ ἀ2ν1ανάγκ ἀ2ν1αναγκ ἄ2ν1ανδ ἀ2ν1άνδ ἀ2ν1άνδ ἀ2ν1ανθ ἀ3ν2ανθέ ἀ3ν2ανθέ ἀ4ν3ανθές. ἀ4ν3ανθές. ἀ4ν3ανθέϲ. ἀ4ν3ανθέϲ. ἀ4ν3ανθὲς. ἀ4ν3ανθὲϲ. ἀ4ν3ανθέσ. ἀ4ν3ανθέσ. ἀ4ν3ανθὲσ. ἀ4ν3ανθέσι ἀ4ν3ανθέσι ἀ4ν3ανθέϲι ἀ4ν3ανθέϲι ἀ2ν1άνιο ἀ2ν1άνιο ἀ2ν1ανίο ἀ2ν1ανίο ἀ2ν1ανίω ἀ2ν1ανίω ἀ2ν1ανταγ ἀ2ν1ανταπ ἀ2ν1αντί ἀ2ν1αντί ἀ2ν1αντι ἀνα2ξ1αγ ἀνά2ξ1αν ἀνά2ξ1αν ἀνα2ξ1άν ἀνα2ξ1άν ἀνα2ξ1αν ἀνά2ξ1αρ ἀνά2ξ1αρ ἀνα2ξ1άρ ἀνα2ξ1άρ ἀνά2ξ1ιπ ἀνά2ξ1ιπ ἀνα2ξ1ίπ ἀνα2ξ1ίπ ἀ2ν1αξιόλ ἀ2ν1αξιόλ ἀ2ν1αξιολ ἀ2ν1αξιόπ ἀ2ν1αξιόπ ἀ2ν1αξιοπ ἀ2ν1άξιο ἀ2ν1άξιο ἀ2ν1αξίο ἀ2ν1αξίο ἀ2ν1αξίω ἀ2ν1αξίω ἀ2ν1αξία ἀ2ν1αξία ἀ2ν1αξῖα ἀ2ν1απάλλα ἀ2ν1απάλλα ἀ2ν1απαλλά ἀ2ν1απαλλά ἀ2ν1απάρτ ἀ2ν1απάρτ ἀ2ν1απαρτ ἀ2ν1απαύδ ἀ2ν1απαύδ ἀ2ν1απαυδ ἀ2ν1απόβ ἀ2ν1απόβ ἀ2ν1απόϐ ἀ2ν1απόϐ ἀ2ν1αποβ ἀ2ν1αποϐ ἀ2ν1απόγ ἀ2ν1απόγ ἀ2ν1απογ ἀ2ν1αποδή ἀ2ν1αποδή ἀ2ν1αποδη ἀ2ν1απόδο ἀ2ν1απόδο ἀ2ν1αποδό ἀ2ν1αποδό ἀ2ν1απόδρ ἀ2ν1απόδρ ἀ2ν1αποδρ ἀ2ν1απόλαυ ἀ2ν1απόλαυ ἀ2ν1απολαύ ἀ2ν1απολαύ ἀ2ν1απολό ἀ2ν1απολό ἀ2ν1απολο ἀ2ν1απόλυ ἀ2ν1απόλυ ἀ2ν1απολύ ἀ2ν1απολύ ἀ2ν1απόν ἀ2ν1απόν ἀ2ν1απον ἀ2ν1απόπ ἀ2ν1απόπ ἀ2ν1αποπ ἀ2ν1απόσ ἀ2ν1απόσ ἀ2ν1απόϲ ἀ2ν1απόϲ ἀ2ν1αποσ ἀ2ν1αποϲ ἀ2ν1απότε ἀ2ν1απότε ἀ2ν1αποτε ἀ2ν1απότμ ἀ2ν1απότμ ἀ2ν1αποτμ ἀ2ν1απότρ ἀ2ν1απότρ ἀ2ν1αποτρ ἀ2ν1αρά ἀ2ν1αρά ἀ2ν1αρα ἀ2ν1άρ ἀ2ν1άρ ἀ2ν1αρ ἄ2ν1αρ ἀ3ν2αρίτ ἀ3ν2αρίτ ἀ3ν2αρῖτ ἀ3ν2αριτ ἀ3ν2αρπ ἀ3ν2άρρ ἀ3ν2άρρ ἀ3ν2αρρ ἀ4ν3αρραγ ἀ3ν2αρτ ἀ3ν2αρύτ ἀ3ν2αρύτ ἀ2ν1άσκη ἀ2ν1άσκη ἀ2ν1άϲκη ἀ2ν1άϲκη ἀ2ν1ασκή ἀ2ν1ασκή ἀ2ν1αϲκή ἀ2ν1αϲκή ἄ2ν1ασπι ἄ2ν1αϲπι ἀ2ν1ασπί ἀ2ν1ασπί ἀ2ν1αϲπί ἀ2ν1αϲπί ἀ2ν1άσσατ ἀ2ν1άσσατ ἀ2ν1άϲϲατ ἀ2ν1άϲϲατ ἀ2ν1ασσάτ ἀ2ν1ασσάτ ἀ2ν1αϲϲάτ ἀ2ν1αϲϲάτ ἀ2ν1άστει ἀ2ν1άστει ἀ2ν1άϲτει ἀ2ν1άϲτει ἀ2ν1αστεί ἀ2ν1αστεί ἀ2ν1αϲτεί ἀ2ν1αϲτεί ἀ3ν2αστείβ ἀ3ν2αστείβ ἀ3ν2αϲτείβ ἀ3ν2αϲτείβ ἀ3ν2αστείϐ ἀ3ν2αστείϐ ἀ3ν2αϲτείϐ ἀ3ν2αϲτείϐ ἀ3ν2άστειρ ἀ3ν2άστειρ ἀ3ν2άϲτειρ ἀ3ν2άϲτειρ ἀ3ν2αστείρ ἀ3ν2αστείρ ἀ3ν2αϲτείρ ἀ3ν2αϲτείρ ἀ3ν2άστειχ ἀ3ν2άστειχ ἀ3ν2άϲτειχ ἀ3ν2άϲτειχ ἀ3ν2αστείχ ἀ3ν2αστείχ ἀ3ν2αϲτείχ ἀ3ν2αϲτείχ ἀ2ν1ατεὶ. ἀ2ν1ατεί. ἀ2ν1ατεί. ἀ2ν1ατὶ. ἀ2ν1ατί. ἀ2ν1ατί. ἄ2ν1ατος. ἄ2ν1ατοϲ. ἄ2ν1ατοσ. ἀ2ν1άτου. ἀ2ν1άτου. ἀ2ν1άτω ἀ2ν1άτω ἄ2ν1ατον. ἄ2ν1ατε ἄ2ν1ατοι. ἀ2ν1άτοις. ἀ2ν1άτοις. ἀ2ν1άτοιϲ. ἀ2ν1άτοιϲ. ἀ2ν1άτοισ. ἀ2ν1άτοισ. ἀ2ν1άττ ἀ2ν1άττ ἀ2ν1αττ ἀ2ν1αύγ ἀ2ν1αύγ ἀ2ν1αυγ ἀ2ν1αύδ ἀ2ν1αύδ ἀ2ν1αυδ ἀ3ν2αυδί ἀ3ν2αυδί ἀ3ν2αυδι ἄ2ν1αυδ ἄ2ν1αυλ ἀ2ν1αύλ ἀ2ν1αύλ ἀ2ν1αύξ ἀ2ν1αύξ ἀ2ν1αυξ ἀ2ν1αύχ ἀ2ν1αύχ ἀ2ν1αυχ ἀ2ν1αφαίρ ἀ2ν1αφαίρ ἀ2ν1αφαιρ ἀ2ν1αφή ἀ2ν1αφή ἀ2ν1αφὴ ἀ2ν1αφοῦ ἀ2ν1αφῆ ἀ2ν1αφεῖ ἀ2ν1αφοῖ ἀ2ν1εφῶν. ἀ2ν1αφέ ἀ2ν1αφέ ἀ2ν1αφὲ ἀ3ν2αφῆν ἀ2ν1αφρόδ ἀ2ν1αφρόδ ἀ2ν1αφροδ ἄ2ν1αφρ ἀ2ν1άφρ ἀ2ν1άφρ ἀ2ν1αχύρ ἀ2ν1αχύρ ἀ2ν1αχυρ ἀνδρό2σ1α ἀνδρό2σ1α ἀνδρό2ϲ1α ἀνδρό2ϲ1α ἀνδρο2σ1α ἀνδρο2ϲ1α ἀ2ν1έγγ ἀ2ν1έγγ ἀ2ν1εγγ ἀ2ν1έγερτ ἀ2ν1έγερτ ἀ2ν1εγέρτ ἀ2ν1εγέρτ ἀ2ν1εγκ ἀ2ν1έγκ ἀ2ν1έγκ ἀ2ν1εγχ ἀ2ν1εδά ἀ2ν1εδά ἀ2ν1εδα ἀ2ν1έδεσ ἀ2ν1έδεσ ἀ2ν1έδεϲ ἀ2ν1έδεϲ ἀ2ν1εδέσ ἀ2ν1εδέσ ἀ2ν1εδέϲ ἀ2ν1εδέϲ ἀ2ν1έδρασ ἀ2ν1έδρασ ἀ2ν1έδραϲ ἀ2ν1έδραϲ ἀ2ν1εδράσ ἀ2ν1εδράσ ἀ2ν1εδράϲ ἀ2ν1εδράϲ ἀ2ν1εέρ ἀ2ν1εέρ ἀ2ν1εερ ἀ2ν1εθέλ ἀ2ν1εθέλ ἀ2ν1εθελ ἀ2ν1έθι ἀ2ν1έθι ἀ2ν1εθί ἀ2ν1εθί ἀ2ν1είδε ἀ2ν1είδε ἀ2ν1ειδέ ἀ2ν1ειδέ ἀ2ν1είδω ἀ2ν1είδω ἀ2ν1ειδώ ἀ2ν1ειδώ ἀ2ν1είκα ἀ2ν1είκα ἀ2ν1εικά ἀ2ν1εικά ἀ2ν1εικό ἀ2ν1εικό ἀ2ν1εικο ἀ2ν1ειλεί ἀ2ν1ειλεί ἀ2ν1ειλει ἀ2ν1είμα ἀ2ν1είμα ἀ2ν1εί2σ1ακ ἀ2ν1εί2σ1ακ ἀ2ν1εί2ϲ1ακ ἀ2ν1εί2ϲ1ακ ἀ2ν1ει2σ1άκ ἀ2ν1ει2σ1άκ ἀ2ν1ει2ϲ1άκ ἀ2ν1ει2ϲ1άκ ἀ2ν1εί2σ1ο ἀ2ν1εί2σ1ο ἀ2ν1εί2ϲ1ο ἀ2ν1εί2ϲ1ο ἀ2ν1ει2σ1ό ἀ2ν1ει2σ1ό ἀ2ν1ει2ϲ1ό ἀ2ν1ει2ϲ1ό ἀ2ν1ει2σ1φορ ἀ2ν1ει2ϲ1φορ ἀ2ν1εί2σ1φορ ἀ2ν1εί2σ1φορ ἀ2ν1εί2ϲ1φορ ἀ2ν1εί2ϲ1φορ ἀ2ν1ει2σ1φόρ ἀ2ν1ει2σ1φόρ ἀ2ν1ει2ϲ1φόρ ἀ2ν1ει2ϲ1φόρ ἀ2ν1έκ ἀ2ν1έκ ἀ2ν1εκ ἀ3ν2έκα ἀ3ν2έκα ἀ3ν2εκάς. ἀ3ν2εκάς. ἀ3ν2εκάϲ. ἀ3ν2εκάϲ. ἀ3ν2εκὰς. ἀ3ν2εκὰϲ. ἀ3ν2εκάσ. ἀ3ν2εκάσ. ἀ3ν2εκὰσ. ἀ3ν2εκτ ἀ4ν3έ2κ1τιτ ἀ4ν3έ2κ1τιτ ἀ4ν3ε2κ1τίτ ἀ4ν3ε2κ1τίτ ἀνε2κ1λιπ ἀνε2κ1λό ἀνε2κ1λό ἀνε2κ1λο ἀ2ν1έλαι ἀ2ν1έλαι ἀ2ν1ελαι ἀ2ν1ελάτ ἀ2ν1ελάτ ἀ2ν1ελατ ἀ2ν1έλεγκ ἀ2ν1έλεγκ ἀ2ν1ελέγκ ἀ2ν1ελέγκ ἀ2ν1ελεγξ ἀ2ν1ελέη ἀ2ν1ελέη ἀ2ν1ελεή ἀ2ν1ελεή ἀ2ν1έλεο ἀ2ν1έλεο ἀ2ν1ελέο ἀ2ν1ελέο ἀ2ν1ελέω ἀ2ν1ελέω ἀ2ν1έλεε ἀ2ν1έλεε ἀ2ν1ελκή ἀ2ν1ελκή ἀ2ν1ελκὴ ἀ2ν1ελκο ἀ2ν1ελκῆ ἀ2ν1ελκές. ἀ2ν1ελκές. ἀ2ν1ελκέϲ. ἀ2ν1ελκέϲ. ἀ2ν1ελκὲς. ἀ2ν1ελκὲϲ. ἀ2ν1ελκέσ. ἀ2ν1ελκέσ. ἀ2ν1ελκὲσ. ἀ2ν1ελκε ἀ2ν1ελκῶ ἀ2ν1ελκέσ ἀ2ν1ελκέσ ἀ2ν1ελκέϲ ἀ2ν1ελκέϲ ἄ2ν1ελκτ ἀ2ν1έλκτ ἀ2ν1έλκτ ἀ2ν1έλκω ἀ2ν1έλκω ἀ2ν1ελκώ ἀ2ν1ελκώ ἀ2ν1έλλ ἀ2ν1έλλ ἀ2ν1έλπι ἀ2ν1έλπι ἀ2ν1ελπί ἀ2ν1ελπί ἀ2ν1έλυτρ ἀ2ν1έλυτρ ἀ2ν1ελύτρ ἀ2ν1ελύτρ ἀ2ν1έμβ ἀ2ν1έμβ ἀ2ν1έμϐ ἀ2ν1έμϐ ἀ2ν1εμβ ἀ2ν1εμϐ ἀ2ν1έμετ ἀ2ν1έμετ ἀ2ν1εμέτ ἀ2ν1εμέτ ἀ2ν1έμπ ἀ2ν1έμπ ἀ2ν1εμπ ἀ2ν1έμφ ἀ2ν1έμφ ἀ2ν1εμφ ἀ2ν1έν ἀ2ν1έν ἀ2ν1εν ἀ3ν2ένει ἀ3ν2ένει ἀ3ν2ενή ἀ3ν2ενή ἀ3ν2έντες. ἀ3ν2έντες. ἀ3ν2έντεϲ. ἀ3ν2έντεϲ. ἀ3ν2έντεσ. ἀ3ν2έντεσ. ἀ2ν1ε2ξ1 ἀ3ν2ε3ξ2ίκα ἀ3ν2ε3ξ2ίκα ἀ3ν2ε3ξ2ικά ἀ3ν2ε3ξ2ικά ἀ2ν1έορ ἀ2ν1έορ ἀ2ν1εόρ ἀ2ν1εόρ ἀ2ν1επ ἀ3ν2επν ἀ3ν2επτ ἀ2ν1εραστ ἀ2ν1εραϲτ ἀ2ν1έραστ ἀ2ν1έραστ ἀ2ν1έραϲτ ἀ2ν1έραϲτ ἀ2ν1εράστ ἀ2ν1εράστ ἀ2ν1εράϲτ ἀ2ν1εράϲτ ἀ2ν1εργ ἄ2ν1εργ ἀ2ν1έργ ἀ2ν1έργ ἀ2ν1έρεικ ἀ2ν1έρεικ ἀ2ν1ερείκ ἀ2ν1ερείκ ἀ2ν1έρεισ ἀ2ν1έρεισ ἀ2ν1έρειϲ ἀ2ν1έρειϲ ἀ2ν1ερείσ ἀ2ν1ερείσ ἀ2ν1ερείϲ ἀ2ν1ερείϲ ἀ2ν1ερεύνητ ἀ2ν1ερεύνητ ἀ2ν1ερευνήτ ἀ2ν1ερευνήτ ἀ2ν1ερί ἀ2ν1ερί ἀ2ν1ερι ἀ2ν1ερυθρίαστ ἀ2ν1ερυθρίαστ ἀ2ν1ερυθρίαϲτ ἀ2ν1ερυθρίαϲτ ἀ2ν1ερυθριάστ ἀ2ν1ερυθριάστ ἀ2ν1ερυθριάϲτ ἀ2ν1ερυθριάϲτ ἀ2ν1έστι ἀ2ν1έστι ἀ2ν1έϲτι ἀ2ν1έϲτι ἀ2ν1εστί ἀ2ν1εστί ἀ2ν1εϲτί ἀ2ν1εϲτί ἀ2ν1έται ἀ2ν1έται ἀ2ν1εταί ἀ2ν1εταί ἀ2ν1έτοι ἀ2ν1έτοι ἀ2ν1ετοί ἀ2ν1ετοί ἀ2ν1ετυ ἀ2ν1έτυ ἀ2ν1έτυ ἀ2ν1ετύ ἀ2ν1ετύ ἀ2ν1εύθ ἀ2ν1εύθ ἀ2ν1ευθ ἄ2ν1ευκ ἀ2ν1εύκ ἀ2ν1εύκ ἀ2ν1ευλ ἀ2ν1εύρετ ἀ2ν1εύρετ ἀ2ν1ευρέτ ἀ2ν1ευρέτ ἀ2ν1ευφήμητ ἀ2ν1ευφήμητ ἀ2ν1ευφημήτ ἀ2ν1ευφημήτ ἀ2ν1εύχ ἀ2ν1εύχ ἀ2ν1ευχ ἀ2ν1εύξ ἀ2ν1εύξ ἀ2ν1ευξ ἀ2ν1ηυξ ἀ2ν1ηῦγ ἀ2ν1ηυγ ἀ2ν1ευκτ ἀ2ν1έφ ἀ2ν1έφ ἀ2ν1εφ ἀ3ν2εφάλ ἀ3ν2εφάλ ἀ3ν2έφελ ἀ3ν2έφελ ἀ3ν2εφέλ ἀ3ν2εφέλ ἀ2ν1εχέ ἀ2ν1εχέ ἀ2ν1εχε ἀ2ν1έψα ἀ2ν1έψα ἀ2ν1εψά ἀ2ν1εψά ἀ2ν1ηγεμ ἀ2ν1ήδ ἀ2ν1ήδ ἀ2ν1ηδ ἀ2ν1ήκεσ ἀ2ν1ήκεσ ἀ2ν1ήκεϲ ἀ2ν1ήκεϲ ἀ2ν1ηκέσ ἀ2ν1ηκέσ ἀ2ν1ηκέϲ ἀ2ν1ηκέϲ ἀ2ν1ήκο ἀ2ν1ήκο ἀ2ν1ηκό ἀ2ν1ηκό ἀ2ν1ηκο ἀ2ν1ηλάκ ἀ2ν1ηλάκ ἀ2ν1ηλακ ἀ2ν1ήλατος. ἀ2ν1ήλατος. ἀ2ν1ήλατοϲ. ἀ2ν1ήλατοϲ. ἀ2ν1ήλατοσ. ἀ2ν1ήλατοσ. ἀ2ν1ηλάτου ἀ2ν1ηλάτου ἀ2ν1ηλάτω ἀ2ν1ηλάτω ἀ2ν1ήλατον. ἀ2ν1ήλατον. ἀ2ν1ήλατε. ἀ2ν1ήλατε. ἀ2ν1ηλάτοι ἀ2ν1ηλάτοι ἀ2ν1ήλατοι ἀ2ν1ήλατοι ἀ2ν1ήλατα ἀ2ν1ήλατα ἀ2ν1ηλεγ ἀ2ν1ηλεή ἀ2ν1ηλεή ἀ2ν1ηλεὴ ἀ2ν1ηλεο ἀ2ν1ηλεε ἀ2ν1ηλεῶ ἀ2ν1ηλεέ ἀ2ν1ηλεέ ἀ2ν1ηλεὲ ἀ2ν1ηλεῆ ἀ2ν1ηλέη ἀ2ν1ηλέη ἀ2ν1ήλειπ ἀ2ν1ήλειπ ἀ2ν1ηλείπ ἀ2ν1ηλείπ ἀ2ν1ηλή ἀ2ν1ηλή ἀ2ν1ηλὴ ἀ2ν1ηλοῦ ἀ2ν1ηλεῖ ἀ2ν1ηλῆ ἀ2ν1ηλέ ἀ2ν1ηλέ ἀ2ν1ηλὲ ἀ2ν1ηλοῖ ἀ2ν1ηλῶ ἀ2ν1ήλικ ἀ2ν1ήλικ ἀ2ν1ηλίκ ἀ2ν1ηλίκ ἀ2ν1ήλιο ἀ2ν1ήλιο ἀ2ν1ηλίο ἀ2ν1ηλίο ἀ2ν1ηλίω ἀ2ν1ηλίω ἀ2ν1ήλια ἀ2ν1ήλια ἀ2ν1ήλιπ ἀ2ν1ήλιπ ἀ2ν1ηλίπ ἀ2ν1ηλίπ ἀ2ν1ηλιφ ἀ2ν1ήμ ἀ2ν1ήμ ἀ2ν1ημ ἀ2ν1ήνυ ἀ2ν1ήνυ ἀ2ν1ηνύ ἀ2ν1ηνύ ἀ2ν1ήρει ἀ2ν1ήρει ἀ2ν1ηρεί ἀ2ν1ηρεί ἀ2ν1ηρέμ ἀ2ν1ηρέμ ἀ2ν1ηρεμ ἀ2ν1ηρεφ ἀ2ν1ήρι ἀ2ν1ήρι ἀ2ν1ηρί ἀ2ν1ηρί ἀ2ν1ήροτ ἀ2ν1ήροτ ἀ2ν1ηρότ ἀ2ν1ηρότ ἀ2ν1ήσσ ἀ2ν1ήσσ ἀ2ν1ήϲϲ ἀ2ν1ήϲϲ ἀ2ν1ησσ ἀ2ν1ηϲϲ ἀ2ν1ήττ ἀ2ν1ήττ ἀ2ν1ηττ ἀ2ν1ήφα ἀ2ν1ήφα ἀ2ν1ηφα ἀ2ν1ίατ ἀ2ν1ίατ ἀ2ν1ιάτ ἀ2ν1ιάτ ἀ2ν1ίδιο ἀ2ν1ίδιο ἀ2ν1ιδίο ἀ2ν1ιδίο ἀ2ν1ιδίω ἀ2ν1ιδίω ἀ2ν1ίδια ἀ2ν1ίδια ἀ2ν1ιδιτ ἄ2ν1ιδρος ἄ2ν1ιδροϲ ἄ2ν1ιδροσ ἀ2ν1ίδρου ἀ2ν1ίδρου ἀ2ν1ίδρω ἀ2ν1ίδρω ἄ2ν1ιδρον ἄ2ν1ιδρε ἀ2ν1ίδροι ἀ2ν1ίδροι ἄ2ν1ιδροι ἀ2ν1ίδρυτ ἀ2ν1ίδρυτ ἀ2ν1ιδρύτ ἀ2ν1ιδρύτ ἀ2ν1ιδρωτ ἀ2ν1ιδρώτ ἀ2ν1ιδρώτ ἀ2ν1ίερ ἀ2ν1ίερ ἀ2ν1ιέρ ἀ2ν1ιέρ ἀ2ν1ιεράτ ἀ2ν1ιεράτ ἀ3ν2ιέρω ἀ3ν2ιέρω ἀ2ν1ίκ ἀ2ν1ίκ ἀ2ν1ικ ἄ2ν1ικ ἀ3ν2ίκη ἀ3ν2ίκη ἀ3ν2ική ἀ3ν2ική ἀ2ν1ίλ ἀ2ν1ίλ ἀ2ν1ιλ ἀ2ν1ίμαστ ἀ2ν1ίμαστ ἀ2ν1ίμαϲτ ἀ2ν1ίμαϲτ ἀ2ν1ιμάστ ἀ2ν1ιμάστ ἀ2ν1ιμάϲτ ἀ2ν1ιμάϲτ ἀ2ν1ίου ἀ2ν1ίου ἀ2ν1ιού ἀ2ν1ιού ἄ2ν1ιππ ἀ2ν1ίππ ἀ2ν1ίππ ἀ2ν1ισ ἀ2ν1ιϲ ἄ2ν1ισ ἄ2ν1ιϲ ἀ2ν1ίσ ἀ2ν1ίσ ἀ2ν1ίϲ ἀ2ν1ίϲ ἀ3ν2ισᾶτ ἀ3ν2ιϲᾶτ ἀ3ν2ισάτ ἀ3ν2ισάτ ἀ3ν2ιϲάτ ἀ3ν2ιϲάτ ἀ3ν2ίστ ἀ3ν2ίστ ἀ3ν2ίϲτ ἀ3ν2ίϲτ ἀ3ν2ιστ ἀ3ν2ιϲτ ἀ4ν3ιστορη ἀ4ν3ιϲτορη ἀ4ν3ιστόρη ἀ4ν3ιστόρη ἀ4ν3ιϲτόρη ἀ4ν3ιϲτόρη ἀ4ν3ιστορή ἀ4ν3ιστορή ἀ4ν3ιϲτορή ἀ4ν3ιϲτορή ἀ3ν2ίσχ ἀ3ν2ίσχ ἀ3ν2ίϲχ ἀ3ν2ίϲχ ἀ4ν3ίσχυ ἀ4ν3ίσχυ ἀ4ν3ίϲχυ ἀ4ν3ίϲχυ ἄ2ν1ιχ ἀ2ν1ίχ ἀ2ν1ίχ ἀ2ν1ιχνεύτ ἀ2ν1ιχνεύτ ἀ2ν1ίψ ἀ2ν1ίψ ἀ2ν1ιψ ἀ2ν1όδε ἀ2ν1όδε ἀ2ν1οδέ ἀ2ν1οδέ ἄ2ν1οζ ἀ2ν1όζ ἀ2ν1όζ ἀ2ν1οικε ἀ2ν1οικον ἄ2ν1οικ ἀ2ν1οίκ ἀ2ν1οίκ ἀ2ν1οικτί ἀ2ν1οικτί ἄ2ν1οικτ ἀ2ν1οίκτ ἀ2ν1οίκτ ἀ2ν1οίμωκ ἀ2ν1οίμωκ ἀ2ν1οιμώκ ἀ2ν1οιμώκ ἀ2ν1οιμωκ ἀ2ν1οιν ἄ2ν1οιν ἀ2ν1οίν ἀ2ν1οίν ἄ2ν1οιστρ ἄ2ν1οιϲτρ ἀ2ν1οίστρ ἀ2ν1οίστρ ἀ2ν1οίϲτρ ἀ2ν1οίϲτρ ἀ2ν1όλ ἀ2ν1όλ ἀ2ν1ολ ἄ2ν1ολ ἀ3ν2ολκ ἀ3ν2ολο ἀ2ν1ομβρί ἀ2ν1ομβρί ἀ2ν1ομϐρί ἀ2ν1ομϐρί ἀ2ν1ομβρῖ ἀ2ν1ομϐρῖ ἄ2ν1ομβρο ἄ2ν1ομϐρο ἀ2ν1όμβρο ἀ2ν1όμβρο ἀ2ν1όμϐρο ἀ2ν1όμϐρο ἀ2ν1όμβρω ἀ2ν1όμβρω ἀ2ν1όμϐρω ἀ2ν1όμϐρω ἄ2ν1ομβρα ἄ2ν1ομϐρα ἀ2ν1ομήλ ἀ2ν1ομήλ ἀ2ν1ομηλ ἀ2ν1ομίλ ἀ2ν1ομίλ ἀ2ν1ομιλ ἀ2ν1όμιχ ἀ2ν1όμιχ ἀ2ν1ομιχ ἀ2ν1όμο ἀ2ν1όμο ἀ2ν1ομό ἀ2ν1ομό ἀ2ν1ομο ἀ3ν2ομοθ ἀ3ν2όμου. ἀ3ν2όμου. ἀ3ν2όμῳ. ἀ3ν2όμῳ. ἀ3ν2όμω. ἀ3ν2όμω. ἀ2ν2όμοιν. ἀ2ν2όμοιν. ἀ3ν2όμων. ἀ3ν2όμων. ἀ3ν2όμοις. ἀ3ν2όμοις. ἀ3ν2όμοιϲ. ἀ3ν2όμοιϲ. ἀ3ν2όμοισ. ἀ3ν2όμοισ. ἀ3ν2όμους. ἀ3ν2όμους. ἀ3ν2όμουϲ. ἀ3ν2όμουϲ. ἀ3ν2όμουσ. ἀ3ν2όμουσ. ἀ2ν1όν ἀ2ν1όν ἀ2ν1ον ἄ2ν1οπ ἀ2ν1όπ ἀ2ν1όπ ἀ2ν1όρ ἀ2ν1όρ ἀ2ν1ορ ἄ2ν1ορ ἀ3ν2οργάζ ἀ3ν2οργάζ ἄ3ν2ορθ ἀ3ν2όρθ ἀ3ν2όρθ ἀ3ν2ορμά ἀ3ν2ορμά ἀ3ν2ορτ ἀ3ν2ορύ ἀ3ν2ορύ ἀ2ν1όσι ἀ2ν1όσι ἀ2ν1όϲι ἀ2ν1όϲι ἀ2ν1οσί ἀ2ν1οσί ἀ2ν1οϲί ἀ2ν1οϲί ἀ2ν1οσι ἀ2ν1οϲι ἄ2ν1οσμ ἄ2ν1οϲμ ἀ2ν1όσμ ἀ2ν1όσμ ἀ2ν1όϲμ ἀ2ν1όϲμ ἀ2ν1όσφρ ἀ2ν1όσφρ ἀ2ν1όϲφρ ἀ2ν1όϲφρ ἀ2ν1οσφρ ἀ2ν1οϲφρ ἀ2ν1ούα ἀ2ν1ούα ἀ2ν1ουά ἀ2ν1ουά ἀ2ν1ούσι ἀ2ν1ούσι ἀ2ν1ούϲι ἀ2ν1ούϲι ἀ2ν1ουσί ἀ2ν1ουσί ἀ2ν1ουϲί ἀ2ν1ουϲί ἀ2ν1ούτ ἀ2ν1ούτ ἀ2ν1ουτ ἀ2ν1οφθ ἀ2ν1όχευτ ἀ2ν1όχευτ ἀ2ν1οχεύτ ἀ2ν1οχεύτ ἄ2ν1οχλ ἀ2ν1όχλ ἀ2ν1όχλ ἀ2ν1οψ ἄ2ν1οψ ἀ2ν1όψ ἀ2ν1όψ ἀντα2ν1ισ ἀντα2ν1ιϲ ἀντα2ν1ίσ ἀντα2ν1ίσ ἀντα2ν1ίϲ ἀντα2ν1ίϲ ἀντει2σ1 ἀντει2ϲ1 ἀντε2κ1 ἀντε2ν1 ἀντε2ξ1 ἀντιδυ2σ1 ἀντιδυ2ϲ1 ἀντιπαρε2κ1 ἀντιπαρε2ξ1 ἀντιπρο2σ1 ἀντιπρο2ϲ1 ἀντιπροσ3κ2υ ἀντιπροϲ3κ2υ ἀντισύ2ν1 ἀντισύ2ν1 ἀντιϲύ2ν1 ἀντιϲύ2ν1 ἀντισυ2ν1 ἀντιϲυ2ν1 ἀ2ν1ύ ἀ2ν1ύ ἀ2ν1υ ἀ3ν2υμ ἀ3ν2ύσ ἀ3ν2ύσ ἀ3ν2ύϲ ἀ3ν2ύϲ ἀ3ν2υσ ἀ3ν2υϲ ἀ2ν1υπέ2ρ1 ἀ2ν1υπέ2ρ1 ἀ2ν1υπε2ρ1 ἄ2ν1ῳδ ἀ2ν1ῴδ ἀ2ν1ώδυ ἀ2ν1ώδυ ἀ2ν1ωδύ ἀ2ν1ωδύ ἀ2ν1ώι ἀ2ν1ώι ἀ2ν1ωί ἀ2ν1ωί ἀ2ν1ώλ ἀ2ν1ώλ ἀ2ν1ωλ ἀ2ν1ώμ ἀ2ν1ώμ ἀ2ν1ωμ ἀ2ν1ών ἀ2ν1ών ἀ2ν1ων ἀ2ν1ωρ ἄ2ν1ωρ ἀ2ν1ώρ ἀ2ν1ώρ ἄ2ν1ωτο ἀ2ν1ώτο ἀ2ν1ώτο ἀ2ν1ωφέλ ἀ2ν1ωφέλ ἀ2ν1ωφελ ἀ2ν1ώχυ ἀ2ν1ώχυ ἀ2ν1ωχύ ἀ2ν1ωχύ ἀπα2ν1αι ἀπά2ν1ου ἀπά2ν1ου ἀπα2ν1ούρ ἀπα2ν1ούρ ἁπα2ξ1 ἀπε2κ1λ ἁπε2ρ1 ἀποσυ2ν1 ἀποϲυ2ν1 ἀπρό2σ1 ἀπρό2σ1 ἀπρό2ϲ1 ἀπρό2ϲ1 ἀπρο2σ1 ἀπρο2ϲ1 ἀπρό3σ2κε ἀπρό3σ2κε ἀπρό3ϲ2κε ἀπρό3ϲ2κε ἀπρο3σ2κέ ἀπρο3σ2κέ ἀπρο3ϲ2κέ ἀπρο3ϲ2κέ ἀπρό3σ2κο ἀπρό3σ2κο ἀπρό3ϲ2κο ἀπρό3ϲ2κο ἀπρο3σ2κό ἀπρο3σ2κό ἀπρο3ϲ2κό ἀπρο3ϲ2κό ἀπρο3σ2τ ἀπρο3ϲ2τ ἁρπα2ξ1 ἀρρε2ν1ω ἀρχισυ2ν1 ἀρχιϲυ2ν1 ἀστε2ρ1ω ἀϲτε2ρ1ω ἀσύ2ν1 ἀσύ2ν1 ἀϲύ2ν1 ἀϲύ2ν1 ἀσυ2ν1 ἀϲυ2ν1 ἀξύ2ν1 ἀξύ2ν1 ἀξυ2ν1 αὐτέ2κ1μ αὐτέ2κ1μ αὐτε2κ1μ αὐτε2ξ1 ἀω2σ1φ ἀω2ϲ1φ .γερα2σ1φ .γερα2ϲ1φ .δα2σ1π .δα2ϲ1π .διαμφι2σ1β .διαμφι2ϲ1β .διαμφι2σ1ϐ .διαμφι2ϲ1ϐ .διέ2κ1ρο .διέ2κ1ρο .διε2κ1ρό .διε2κ1ρό .διέ2ξ1 .διέ2ξ1 .διε2ξ1 .δικα2σ1π .δικα2ϲ1π .διό2σ1κ .διό2σ1κ .διό2ϲ1κ .διό2ϲ1κ .διο2σ1κ .διο2ϲ1κ .διό2σ1π .διό2σ1π .διό2ϲ1π .διό2ϲ1π .διο2σ1π .διο2ϲ1π .δί2σ1α .δί2σ1α .δί2ϲ1α .δί2ϲ1α .δι2σ1ά .δι2σ1ά .δι2ϲ1ά .δι2ϲ1ά .δί2σ1η .δί2σ1η .δί2ϲ1η .δί2ϲ1η .δι2σ1ή .δι2σ1ή .δι2ϲ1ή .δι2ϲ1ή .δί2σ1ε .δί2σ1ε .δί2ϲ1ε .δί2ϲ1ε .δι2σ1ε .δι2ϲ1ε .δι2σ1θ .δι2ϲ1θ .δύ2σ1 .δύ2σ1 .δύ2ϲ1 .δύ2ϲ1 .δυ2σ1 .δυ2ϲ1 δύ3σ2ω. δύ3σ2ω. δύ3ϲ2ω. δύ3ϲ2ω. δύ3σ2εις. δύ3σ2εις. δύ3ϲ2ειϲ. δύ3ϲ2ειϲ. δύ3σ2εισ. δύ3σ2εισ. δύ3σ2ει. δύ3σ2ει. δύ3ϲ2ει. δύ3ϲ2ει. .δύ3σ2ετ .δύ3σ2ετ .δύ3ϲ2ετ .δύ3ϲ2ετ δύ3σ2ομεν. δύ3σ2ομεν. δύ3ϲ2ομεν. δύ3ϲ2ομεν. δύ3σ2ουσιν. δύ3σ2ουσιν. δύ3ϲ2ουϲιν. δύ3ϲ2ουϲιν. δύ3σ2οιμι. δύ3σ2οιμι. δύ3ϲ2οιμι. δύ3ϲ2οιμι. δύ3σ2οις. δύ3σ2οις. δύ3ϲ2οιϲ. δύ3ϲ2οιϲ. δύ3σ2οισ. δύ3σ2οισ. δύ3σ2οι. δύ3σ2οι. δύ3ϲ2οι. δύ3ϲ2οι. δύ3σ2οιτον. δύ3σ2οιτον. δύ3ϲ2οιτον. δύ3ϲ2οιτον. δυ3σ2οίτην. δυ3σ2οίτην. δυ3ϲ2οίτην. δυ3ϲ2οίτην. δύ3σ2οιμεν. δύ3σ2οιμεν. δύ3ϲ2οιμεν. δύ3ϲ2οιμεν. δύ3σ2οιτε. δύ3σ2οιτε. δύ3ϲ2οιτε. δύ3ϲ2οιτε. δύ3σ2οιεν. δύ3σ2οιεν. δύ3ϲ2οιεν. δύ3ϲ2οιεν. δύ3σ2ειν. δύ3σ2ειν. δύ3ϲ2ειν. δύ3ϲ2ειν. δύ3σ2ων. δύ3σ2ων. δύ3ϲ2ων. δύ3ϲ2ων. δύ3σ2ον δύ3σ2ον δύ3ϲ2ον δύ3ϲ2ον δυ3σ2όν δυ3σ2όν δυ3ϲ2όν δυ3ϲ2όν δύ3σ2ουσ δύ3σ2ουσ δύ3ϲ2ουϲ δύ3ϲ2ουϲ δυ3σ2ούσ δυ3σ2ούσ δυ3ϲ2ούϲ δυ3ϲ2ούϲ δύ3σ2ῃ δύ3σ2ῃ δύ3ϲ2ῃ δύ3ϲ2ῃ δύ3σ2ητον. δύ3σ2ητον. δύ3ϲ2ητον. δύ3ϲ2ητον. δύ3σ2ωμεν. δύ3σ2ωμεν. δύ3ϲ2ωμεν. δύ3ϲ2ωμεν. δύ3σ2ωσι. δύ3σ2ωσι. δύ3ϲ2ωϲι. δύ3ϲ2ωϲι. δύ3σ2αιμι. δύ3σ2αιμι. δύ3ϲ2αιμι. δύ3ϲ2αιμι. δύ3σ2αις. δύ3σ2αις. δύ3ϲ2αιϲ. δύ3ϲ2αιϲ. δύ3σ2ειας. δύ3σ2ειας. δύ3ϲ2ειαϲ. δύ3ϲ2ειαϲ. δύ3σ2αισ. δύ3σ2αισ. δύ3σ2ειασ. δύ3σ2ειασ. δύ3σ2αι. δύ3σ2αι. δύ3ϲ2αι. δύ3ϲ2αι. δύ3σ2ειε. δύ3σ2ειε. δύ3ϲ2ειε. δύ3ϲ2ειε. δύ3σ2αιτον. δύ3σ2αιτον. δύ3ϲ2αιτον. δύ3ϲ2αιτον. δυ3σ2αίτην. δυ3σ2αίτην. δυ3ϲ2αίτην. δυ3ϲ2αίτην. δύ3σ2αιμεν. δύ3σ2αιμεν. δύ3ϲ2αιμεν. δύ3ϲ2αιμεν. δύ3σ2αιτε. δύ3σ2αιτε. δύ3ϲ2αιτε. δύ3ϲ2αιτε. δύ3σ2αιεν δύ3σ2αιεν δύ3ϲ2αιεν δύ3ϲ2αιεν δύ3σ2ειαν. δύ3σ2ειαν. δύ3ϲ2ειαν. δύ3ϲ2ειαν. δύ3σ2ον. δύ3σ2ον. δύ3ϲ2ον. δύ3ϲ2ον. δυ3σ2άτω. δυ3σ2άτω. δυ3ϲ2άτω. δυ3ϲ2άτω. δύ3σ2ατον. δύ3σ2ατον. δύ3ϲ2ατον. δύ3ϲ2ατον. δυ3σ2άτων. δυ3σ2άτων. δυ3ϲ2άτων. δυ3ϲ2άτων. δύ3σ2ατε. δύ3σ2ατε. δύ3ϲ2ατε. δύ3ϲ2ατε. δυ3σ2άντων. δυ3σ2άντων. δυ3ϲ2άντων. δυ3ϲ2άντων. δύ3σ2ας. δύ3σ2ας. δύ3ϲ2αϲ. δύ3ϲ2αϲ. δύ3σ2αν. δύ3σ2αν. δύ3ϲ2αν. δύ3ϲ2αν. δύ3σ2αντ δύ3σ2αντ δύ3ϲ2αντ δύ3ϲ2αντ δυ3σ2άντ δυ3σ2άντ δυ3ϲ2άντ δυ3ϲ2άντ δύ3σ2ασ δύ3σ2ασ δύ3ϲ2αϲ δύ3ϲ2αϲ δυ3σ2άσ δυ3σ2άσ δυ3ϲ2άϲ δυ3ϲ2άϲ δύ3σ2ομαι. δύ3σ2ομαι. δύ3ϲ2ομαι. δύ3ϲ2ομαι. .δύ3σ2εσ .δύ3σ2εσ .δύ3ϲ2εϲ .δύ3ϲ2εϲ δυ3σ2όμεθα. δυ3σ2όμεθα. δυ3ϲ2όμεθα. δυ3ϲ2όμεθα. δύ3σ2ονται. δύ3σ2ονται. δύ3ϲ2ονται. δύ3ϲ2ονται. δυ3σ2οίμην. δυ3σ2οίμην. δυ3ϲ2οίμην. δυ3ϲ2οίμην. δύ3σ2οιο. δύ3σ2οιο. δύ3ϲ2οιο. δύ3ϲ2οιο. δύ3σ2οιτο. δύ3σ2οιτο. δύ3ϲ2οιτο. δύ3ϲ2οιτο. δύ3σ2οισθον. δύ3σ2οισθον. δύ3ϲ2οιϲθον. δύ3ϲ2οιϲθον. δυ3σ2οίσθην. δυ3σ2οίσθην. δυ3ϲ2οίϲθην. δυ3ϲ2οίϲθην. δυ3σ2οίμεθα. δυ3σ2οίμεθα. δυ3ϲ2οίμεθα. δυ3ϲ2οίμεθα. δύ3σ2οισθε. δύ3σ2οισθε. δύ3ϲ2οιϲθε. δύ3ϲ2οιϲθε. δύ3σ2οιντο. δύ3σ2οιντο. δύ3ϲ2οιντο. δύ3ϲ2οιντο. δύ3σ2εσθαι. δύ3σ2εσθαι. δύ3ϲ2εϲθαι. δύ3ϲ2εϲθαι. .δυ3σ2όμεν .δυ3σ2όμεν .δυ3ϲ2όμεν .δυ3ϲ2όμεν .δυ3σ2ομέν .δυ3σ2ομέν .δυ3ϲ2ομέν .δυ3ϲ2ομέν δύ3σ2ωμαι. δύ3σ2ωμαι. δύ3ϲ2ωμαι. δύ3ϲ2ωμαι. δύ3σ2ηται. δύ3σ2ηται. δύ3ϲ2ηται. δύ3ϲ2ηται. δυ3σ2ώμεθα δυ3σ2ώμεθα δυ3ϲ2ώμεθα δυ3ϲ2ώμεθα δύ3σ2ησθε. δύ3σ2ησθε. δύ3ϲ2ηϲθε. δύ3ϲ2ηϲθε. δυ3σ2αίμην. δυ3σ2αίμην. δυ3ϲ2αίμην. δυ3ϲ2αίμην. δύ3σ2αιο. δύ3σ2αιο. δύ3ϲ2αιο. δύ3ϲ2αιο. δύ3σ2αιτο. δύ3σ2αιτο. δύ3ϲ2αιτο. δύ3ϲ2αιτο. δύ3σ2αισθον. δύ3σ2αισθον. δύ3ϲ2αιϲθον. δύ3ϲ2αιϲθον. δυ3σ2αίσθην. δυ3σ2αίσθην. δυ3ϲ2αίϲθην. δυ3ϲ2αίϲθην. δυ3σ2αίμεθα. δυ3σ2αίμεθα. δυ3ϲ2αίμεθα. δυ3ϲ2αίμεθα. δύ3σ2αισθαι. δύ3σ2αισθαι. δύ3ϲ2αιϲθαι. δύ3ϲ2αιϲθαι. δύ3σ2αιντο. δύ3σ2αιντο. δύ3ϲ2αιντο. δύ3ϲ2αιντο. δυ3σ2άσθω. δυ3σ2άσθω. δυ3ϲ2άϲθω. δυ3ϲ2άϲθω. δύ3σ2ασθον. δύ3σ2ασθον. δύ3ϲ2αϲθον. δύ3ϲ2αϲθον. δυ3σ2άσθων. δυ3σ2άσθων. δυ3ϲ2άϲθων. δυ3ϲ2άϲθων. δύ3σ2ασθε. δύ3σ2ασθε. δύ3ϲ2αϲθε. δύ3ϲ2αϲθε. δύ3σ2ασθαι. δύ3σ2ασθαι. δύ3ϲ2αϲθαι. δύ3ϲ2αϲθαι. δυ3σ2άμεν δυ3σ2άμεν δυ3ϲ2άμεν δυ3ϲ2άμεν δυσ3σ2αμέν δυσ3σ2αμέν δυϲ3ϲ2αμέν δυϲ3ϲ2αμέν δύ3σ2ατο. δύ3σ2ατο. δύ3ϲ2ατο. δύ3ϲ2ατο. δύ3σ2ετο. δύ3σ2ετο. δύ3ϲ2ετο. δύ3ϲ2ετο. δύ3σ2αντο. δύ3σ2αντο. δύ3ϲ2αντο. δύ3ϲ2αντο. δύ3σ2εο. δύ3σ2εο. δύ3ϲ2εο. δύ3ϲ2εο. .δυσεί2σ1β .δυσεί2σ1β .δυϲεί2ϲ1β .δυϲεί2ϲ1β .δυσεί2σ1ϐ .δυσεί2σ1ϐ .δυϲεί2ϲ1ϐ .δυϲεί2ϲ1ϐ .δυσει2σ1β .δυϲει2ϲ1β .δυσει2σ1ϐ .δυϲει2ϲ1ϐ .δυσέ2κ1 .δυσέ2κ1 .δυϲέ2κ1 .δυϲέ2κ1 .δυσε2κ1 .δυϲε2κ1 .δυσέ2ξ1 .δυσέ2ξ1 .δυϲέ2ξ1 .δυϲέ2ξ1 .δυσε2ξ1 .δυϲε2ξ1 .δυ3σ2ιθ .δυ3ϲ2ιθ δύ3σ2ις. δύ3σ2ις. δύ3ϲ2ιϲ. δύ3ϲ2ιϲ. δύ3σ2ισ. δύ3σ2ισ. δύ3σ2εω δύ3σ2εω δύ3ϲ2εω δύ3ϲ2εω δύ3σ2ιν. δύ3σ2ιν. δύ3ϲ2ιν. δύ3ϲ2ιν. δύ3σ2ι. δύ3σ2ι. δύ3ϲ2ι. δύ3ϲ2ι. δυ3σ2έοιν. δυ3σ2έοιν. δυ3ϲ2έοιν. δυ3ϲ2έοιν. δύ3σ2εσι. δύ3σ2εσι. δύ3ϲ2εϲι. δύ3ϲ2εϲι. δύ3σ2εσιν. δύ3σ2εσιν. δύ3ϲ2εϲιν. δύ3ϲ2εϲιν. .δύ3σ2κε .δύ3σ2κε .δύ3ϲ2κε .δύ3ϲ2κε .δυ3σ2μή. .δυ3σ2μή. .δυ3ϲ2μή. .δυ3ϲ2μή. .δυ3σ2μὴ. .δυ3ϲ2μὴ. .δυ3σ2μῆς. .δυ3ϲ2μῆϲ. .δυ3σ2μῆσ. .δυ3σ2μῇ .δυ3ϲ2μῇ .δυ3σ2μῆ. .δυ3ϲ2μῆ. .δυ3σ2μᾶ .δυ3ϲ2μᾶ .δυ3σ2μα .δυ3ϲ2μα .δυ3σ2μῶ .δυ3ϲ2μῶ .δυσξύ2ν1 .δυσξύ2ν1 .δυϲξύ2ν1 .δυϲξύ2ν1 .δυσξυ2ν1 .δυϲξυ2ν1 .δύ3σ2ταν .δύ3σ2ταν .δύ3ϲ2ταν .δύ3ϲ2ταν .δυ3σ2τάν .δυ3σ2τάν .δυ3ϲ2τάν .δυ3ϲ2τάν .δυ3σ2την .δυ3ϲ2την .δυ3σ2τήν .δυ3σ2τήν .δυ3ϲ2τήν .δυ3ϲ2τήν ἐδυ2σ1τ ἐδυ2ϲ1τ εἰ2ν1όδ εἰ2ν1όδ εἰ2ν1οδ εἰ2σ1 εἰ2ϲ1 εἴ2σ1 εἴ2ϲ1 εἰ3σ2ί. εἰ3σ2ί. εἰ3ϲ2ί. εἰ3ϲ2ί. εἰ3σ2ὶ. εἰ3ϲ2ὶ. εἰ3σ2ι. εἰ3ϲ2ι. εἰ3σ2ίν. εἰ3σ2ίν. εἰ3ϲ2ίν. εἰ3ϲ2ίν. εἰ3σ2ὶν. εἰ3ϲ2ὶν. εἰ3σ2ιν. εἰ3ϲ2ιν. εἴ3σ2ομ εἴ3ϲ2ομ εἴ3σ2ῃ. εἴ3ϲ2ῃ. εἴσει. εἴϲει. εἴ3σ2εται. εἴ3ϲ2εται. εἴ3σ2εσθον. εἴ3ϲ2εϲθον. εἰ3σ2όμ εἰ3σ2όμ εἰ3ϲ2όμ εἰ3ϲ2όμ εἴ3σ2εσθε. εἴ3ϲ2εϲθε. εἴ3σ2ονται εἴ3ϲ2ονται εἰ3σ2οίμην εἰ3σ2οίμην εἰ3ϲ2οίμην εἰ3ϲ2οίμην εἴ3σ2οιο εἴ3ϲ2οιο εἴ3σ2οιτο εἴ3ϲ2οιτο εἴ3σ2οισθον εἴ3ϲ2οιϲθον εἰ3σ2οίσθην εἰ3σ2οίσθην εἰ3ϲ2οίϲθην εἰ3ϲ2οίϲθην εἰ3σ2οίμεθα εἰ3σ2οίμεθα εἰ3ϲ2οίμεθα εἰ3ϲ2οίμεθα εἴ3σ2οισθε εἴ3ϲ2οιϲθε εἴ3σ2οιντο εἴ3ϲ2οιντο εἴ3σ2εσθαι εἴ3ϲ2εϲθαι εἰ3σ2όμεν εἰ3σ2όμεν εἰ3ϲ2όμεν εἰ3ϲ2όμεν εἰ3σ2ομέν εἰ3σ2ομέν εἰ3ϲ2ομέν εἰ3ϲ2ομέν εἴ3σ2άμην. εἴ3σ2άμην. εἴ3ϲ2άμην. εἴ3ϲ2άμην. εἴ3σ2ω εἴ3ϲ2ω εἴ3σ2ατο εἴ3ϲ2ατο εἴ3σ2ασθον εἴ3ϲ2αϲθον εἰ3σ2άσθην εἰ3σ2άσθην εἰ3ϲ2άϲθην εἰ3ϲ2άϲθην εἰ3σ2άμεθα εἰ3σ2άμεθα εἰ3ϲ2άμεθα εἰ3ϲ2άμεθα εἴ3σ2ασθε εἴ3ϲ2αϲθε εἴ3σ2αντο εἴ3ϲ2αντο εἴ3σ2ωμαι εἴ3ϲ2ωμαι εἴ3σ2ησθον εἴ3ϲ2ηϲθον εἰ3σ2ώμεθα εἰ3σ2ώμεθα εἰ3ϲ2ώμεθα εἰ3ϲ2ώμεθα εἴ3σ2ησθε εἴ3ϲ2ηϲθε εἴ3σ2ωνται εἴ3ϲ2ωνται εἰ3σ2αίμην εἰ3σ2αίμην εἰ3ϲ2αίμην εἰ3ϲ2αίμην εἴ3σ2αιο εἴ3ϲ2αιο εἴ3σ2αιτο εἴ3ϲ2αιτο εἴ3σ2αισθον εἴ3ϲ2αιϲθον εἴ3σ2αίσθην εἴ3σ2αίσθην εἴ3ϲ2αίϲθην εἴ3ϲ2αίϲθην εἰ3σ2αίμεθα εἰ3σ2αίμεθα εἰ3ϲ2αίμεθα εἰ3ϲ2αίμεθα εἴ3σ2αισθε εἴ3ϲ2αιϲθε εἴ3σ2αιντο εἴ3ϲ2αιντο εἰ3σ2άσθω εἰ3σ2άσθω εἰ3ϲ2άϲθω εἰ3ϲ2άϲθω εἰ3σ2άσθων εἰ3σ2άσθων εἰ3ϲ2άϲθων εἰ3ϲ2άϲθων εἴ3σ2ασθαι εἴ3ϲ2αϲθαι εἰ3σ2άμεν εἰ3σ2άμεν εἰ3ϲ2άμεν εἰ3ϲ2άμεν εἰ3σ2αμέν εἰ3σ2αμέν εἰ3ϲ2αμέν εἰ3ϲ2αμέν ἐ2κ1λ ἐ3κ2λήθη ἐ3κ2λήθη ἐ3κ2λάζ ἐ3κ2λάζ ἐ3κ2λάγ ἐ3κ2λάγ ἐ3κ2λάο ἐ3κ2λάο ἐ3κ2λάσ ἐ3κ2λάσ ἐ3κ2λάϲ ἐ3κ2λάϲ ἐ3κ2λαί ἐ3κ2λαί ἐ3κ2λαύ ἐ3κ2λαύ ἐ3κ2λεί ἐ3κ2λεί ἐ4κ3λείπ ἐ4κ3λείπ ἐ4κ3λείψ ἐ4κ3λείψ ἐ3κ2λῄ ἐ3κ2κλέπ ἐ3κ2κλέπ ἐ3κ2κλέψ ἐ3κ2κλέψ ἐ3κ2λάπ ἐ3κ2λάπ ἐ3κ2λαπ ἐ4κ3λάπτ ἐ4κ3λάπτ ἐ4κ3λαπτ ἐ3κ2λέφ ἐ3κ2λέφ ἐ3κ2λεφ ἐ3κ2λήρ ἐ3κ2λήρ ἐ3κ2ληρ ἐ3κ2λίν ἐ3κ2λίν ἐ3κ2λιν ἐ3κ2λύ ἐ3κ2λύ ἐ4κ3λύσεω ἐ4κ3λύσεω ἐ4κ3λύϲεω ἐ4κ3λύϲεω ἐ4κ3λύσει ἐ4κ3λύσει ἐ4κ3λύϲει ἐ4κ3λύϲει ἐ4κ3λύσεοι ἐ4κ3λύσεοι ἐ4κ3λύϲεοι ἐ4κ3λύϲεοι ἐ4κ3λύσεσι ἐ4κ3λύσεσι ἐ4κ3λύϲεϲι ἐ4κ3λύϲεϲι ἐ3κ2λόμ ἐ3κ2λόμ ἐ3κ2κλώσ ἐ3κ2κλώσ ἐ3κ2κλώϲ ἐ3κ2κλώϲ ἔ2κ1λει ἔ3κ2λεισ ἔ3κ2λειϲ ἔ2κ1λυσ ἔ2κ1λυϲ ἐ2κ1μ ἔ2κ1μ ἐ2κ1ν ἔ2κ1ν ἔ3κ2ναι ἐ3κ2ναί ἐ3κ2ναί ἔ3κ2νησ ἔ3κ2νηϲ ἐ3κ2νήσ ἐ3κ2νήσ ἐ3κ2νήϲ ἐ3κ2νήϲ ἐ3κ2νυ ἐ2κ1ρ ἔ2κ1ρ ἐ3κ2ράδ ἐ3κ2ράδ ἐ3κ2ραδ ἔ3κ2ραζ ἐ3κ2ράζ ἐ3κ2ράζ ἔ3κ2ραγ ἐ3κ2ράγ ἐ3κ2ράγ ἐ3κ2ράτ ἐ3κ2ράτ ἐ3κ2ρατ ἐ3κ2ραύγ ἐ3κ2ραύγ ἐ3κ2ραυγ ἔ3κ2ραι ἐ3κ2ραί ἐ3κ2ραί ἔ3κ2ραν ἐ3κ2ράν ἐ3κ2ράν ἐ3κ2ρήη ἐ3κ2ρήη ἐ3κ2ράα ἐ3κ2ράα ἐ3κ2ραά ἐ3κ2ραά ἐ3κ2ράθ ἐ3κ2ράθ ἐ3κ2ραθ ἔ3κ2ρεκ ἐ3κ2ρέκ ἐ3κ2ρέκ ἔ3κ2ρεξ ἐ3κ2ρέξ ἐ3κ2ρέξ ἐ3κ2ρέμ ἐ3κ2ρέμ ἐ3κ2ρεμ ἐ3κ2ρήμ ἐ3κ2ρήμ ἐ3κ2ρημ ἔ3κ2ριν ἐ3κ2ρίν ἐ3κ2ρίν ἐ3κ2ρίθ ἐ3κ2ρίθ ἐ3κ2ρότ ἐ3κ2ρότ ἐ3κ2ροτ ἔ3κ2ρου ἐ3κ2ρού ἐ3κ2ρού ἔ3κ2ρυπ ἐ3κ2ρύπ ἐ3κ2ρύπ ἔ3κ2ρυψ ἐ3κ2ρύψ ἐ3κ2ρύψ ἐ3κ2ρύβ ἐ3κ2ρύβ ἐ3κ2ρύϐ ἐ3κ2ρύϐ ἐ3κ2ρύφ ἐ3κ2ρύφ ἐ3κ2ρυσ ἐ3κ2ρυϲ ἔ3κ2ρωζ ἐ3κ2ρώζ ἐ3κ2ρώζ ἔ3κ2ρωξ ἐ3κ2ρώξ ἐ3κ2ρώξ ἐ2κ1ταθ ἔ2κ1ταμε. ἐ2κ1τάμν ἐ2κ1τάμν ἐ2κ1ταν ἐ2κ1ταρ ἐ2κ1τάσ ἐ2κ1τάσ ἐ2κ1τάϲ ἐ2κ1τάϲ ἐ2κ1τε ἐ2κ1τέ ἐ2κ1τέ ἐ3κ2τείν ἐ3κ2τείν ἐ2κ1τήκ ἐ2κ1τήκ ἐ2κ1τι ἔ2κ1τι ἐ2κ1τί ἐ2κ1τί ἔ3κ2τιζ ἐ3κ2τίζ ἐ3κ2τίζ ἔ3κ2τισα ἔ3κ2τιϲα ἐ3κ2τίσα ἐ3κ2τίσα ἐ3κ2τίϲα ἐ3κ2τίϲα ἐ2κ1τό ἐ2κ1τό ἐ2κ1το ἔ2κ1το ἐ3κ2τός. ἐ3κ2τός. ἐ3κ2τόϲ. ἐ3κ2τόϲ. ἐ3κ2τὸς. ἐ3κ2τὸϲ. ἐ3κ2τόσ. ἐ3κ2τόσ. ἐ3κ2τὸσ. ἐ2κ1τρ ἔ2κ1τυπο ἐ2κ1τύπου. ἐ2κ1τύπου. ἐ2κ1τύπῳ. ἐ2κ1τύπῳ. ἔ2κ1τυπε. ἐ2κ1τύπω. ἐ2κ1τύπω. ἐ2κτύποι. ἐ2κτύποι. ἐ2κ1τύπων. ἐ2κ1τύπων. ἐ2κ1τύποις. ἐ2κ1τύποις. ἐ2κ1τύποιϲ. ἐ2κ1τύποιϲ. ἐ2κ1τύποισ. ἐ2κ1τύποισ. ἐ2κ1τύπους. ἐ2κ1τύπους. ἐ2κ1τύπουϲ. ἐ2κ1τύπουϲ. ἐ2κ1τύπουσ. ἐ2κ1τύπουσ. ἔ2κ1τυπα. ἐ2κ1τυ ἑλλή2σ1π ἑλλή2σ1π ἑλλή2ϲ1π ἑλλή2ϲ1π ἑλλη2σ1π ἑλλη2ϲ1π ἐ2ν1 ἔ2ν1 ἐ3ν2άκις ἐ3ν2άκις ἐ3ν2άκιϲ ἐ3ν2άκιϲ ἐ3ν2ακισ ἐ3ν2ακιϲ ἐ3ν2ακόσ ἐ3ν2ακόσ ἐ3ν2ακόϲ ἐ3ν2ακόϲ ἐ3ν2ακοσ ἐ3ν2ακοϲ ἔ3ν2αρα. ἐ3ν2άρων. ἐ3ν2άρων. ἐ3ν2άροις. ἐ3ν2άροις. ἐ3ν2άροιϲ. ἐ3ν2άροιϲ. ἐ3ν2άροισ. ἐ3ν2άροισ. ἐ3ν2αρηφ ἐ4ν3αραρ ἐ3ν2άρεε ἐ3ν2άρεε ἐ3ν2αρέω ἐ3ν2αρέω ἐ3ν2αρέα ἐ3ν2αρέα ἐ3ν2αρεά ἐ3ν2αρεά ἐ3ν2άριε ἐ3ν2άριε ἐ3ν2αρίω ἐ3ν2αρίω ἐ3ν2αρία ἐ3ν2αρία ἐ3ν2αριά ἐ3ν2αριά ἔ3ν2ασσ ἔ3ν2αϲϲ ἐ3ν2άσσ ἐ3ν2άσσ ἐ3ν2άϲϲ ἐ3ν2άϲϲ ἐ3ν2άσθ ἐ3ν2άσθ ἐ3ν2άϲθ ἐ3ν2άϲθ ἐ3ν2ασθ ἐ3ν2αϲθ ἔ3ν2ατ ἐ3ν2άτ ἐ3ν2άτ ἐνδυ2σ1τ ἐνδυ2ϲ1τ ἐ3ν2έγκ ἐ3ν2έγκ ἐ3ν2εγκ ἔ3ν2εικ ἐ3ν2εῖκ ἐ3ν2εικ ἐ3ν2είκ ἐ3ν2είκ ἔ3ν2ειμ ἐ3ν2είμ ἐ3ν2είμ ἐ3ν2εμέσσ ἐ3ν2εμέσσ ἐ3ν2εμέϲϲ ἐ3ν2εμέϲϲ ἐ3ν2εμήθ ἐ3ν2εμήθ ἐ3ν2ενή ἐ3ν2ενή ἐ3ν2εό ἐ3ν2εό ἐ3ν2εὸ ἐ3ν2εο ἐ3ν2εῶ ἐ3ν2εά ἐ3ν2εά ἐ3ν2εὰ ἐ3ν2εᾶ ἐ3ν2έπει ἐ3ν2έπει ἔ3ν2ερθε ἔ3ν2ευσ ἔ3ν2ευϲ ἐ3ν2εύσ ἐ3ν2εύσ ἐ3ν2εύϲ ἐ3ν2εύϲ ἐ3ν2έχθ ἐ3ν2έχθ ἐ3ν2εχθ ἔ3ν2ησ ἔ3ν2ηϲ ἐ3ν2ήσ ἐ3ν2ήσ ἐ3ν2ήϲ ἐ3ν2ήϲ ἐ3ν2ηή ἐ3ν2ηή ἐ3ν2ηὴ ἔ3ν2ην. ἐ3ν2ηεί ἐ3ν2ηεί ἐ3ν2ηο ἐ3ν2ηῶ ἐ3νηέ ἐ3νηέ ἐ3ν2ήνο ἐ3ν2ήνο ἐ3ν2ί ἐ3ν2ί ἐ3ν2ι ἔ3ν2ι ἐ4ν3ιαύ ἐ4ν3ιαύ ἐ5ν4ιαύσ ἐ5ν4ιαύσ ἐ5ν4ιαύϲ ἐ5ν4ιαύϲ ἐ5ν4ιαυσ ἐ5ν4ιαυϲ ἐ4ν3ιδρ ἐ4ν3ίδρ ἐ4ν3ίδρ ἐ4ν3ίζ ἐ4ν3ίζ ἐ4ν3ίη ἐ4ν3ίη ἐ4ν3ιέτον. ἐ4ν3ιέτον. ἐ4ν3ίεμεν. ἐ4ν3ίεμεν. ἐ4ν3ίω. ἐ4ν3ίω. ἐ4ν3ιππ ἐ4ν3ίππ ἐ4ν3ίππ ἐ4ν3ίπτ ἐ4ν3ίπτ ἐ4ν3ίψ ἐ4ν3ίψ ἐ4ν3ίσσ ἐ4ν3ίσσ ἐ4ν3ίϲϲ ἐ4ν3ίϲϲ ἐ4ν3ίστ ἐ4ν3ίστ ἐ4ν3ίϲτ ἐ4ν3ίϲτ ἐ4ν3ιστ ἐ4ν3ιϲτ ἐ4ν3ισχ ἐ4ν3ιϲχ ἐ4ν3ίσχ ἐ4ν3ίσχ ἐ4ν3ίϲχ ἐ4ν3ίϲχ ἔ3ν2ος. ἔ3ν2οϲ. ἔ3ν2οσ. ἔ3ν2ου. ἔ3ν2ον. ἔ3ν2ω ἔ3ν2οι. ἔ3ν2οις. ἔ3ν2οιϲ. ἔ3ν2οισ. ἔ3ν2ης. ἔ3ν2ηϲ. ἔ3ν2ησ. ἔ3ν2ῃ. ἔ3ν2η. ἔ3ν2οσι ἔ3ν2οϲι ἐ3ν2όσε ἐ3ν2όσε ἐ3ν2όϲε ἐ3ν2όϲε ἐ3ν2υάλ ἐ3ν2υάλ ἐ3ν2υαλ ἔ3ν2υξ ἐ3ν2υξ ἐ3ν2ύξ ἐ3ν2ύξ ἐ3ν2ύσ ἐ3ν2ύσ ἐ3ν2ύϲ ἐ3ν2ύϲ ἐ3ν2υσ ἐ3ν2υϲ ἐ3ν2υώ ἐ3ν2υώ ἐ3ν2υὼ ἐ3ν2υόο ἐ3ν2υόο ἐ3ν2υοῦς ἐ3ν2υοῦϲ ἐ2ξ1 ἔ2ξ1 ἐ3ξ2ήρ ἐ3ξ2ήρ ἐ3ξ2ηρ ἐ3ξ2υ2ν1 ἐ3ξ2υρ ἐ3ξ2ύρ ἐ3ξ2ύρ ἔ3ξ2υσ ἔ3ξ2υϲ ἔ3ξ2ω. ἑ2ξ1ήρετμ ἑ2ξ1ήρετμ ἑ2ξ1ηρέτμ ἑ2ξ1ηρέτμ ἐπεί2σ1 ἐπεί2σ1 ἐπεί2ϲ1 ἐπεί2ϲ1 ἐπει2σ1 ἐπει2ϲ1 ἐπεί3σ2ατον. ἐπεί3σ2ατον. ἐπεί3ϲ2ατον. ἐπεί3ϲ2ατον. ἐπει3σ2άτην. ἐπει3σ2άτην. ἐπει3ϲ2άτην. ἐπει3ϲ2άτην. ἐπεί3σ2αμεν. ἐπεί3σ2αμεν. ἐπεί3ϲ2αμεν. ἐπεί3ϲ2αμεν. ἐπεί3σ2ατε ἐπεί3σ2ατε ἐπεί3ϲ2ατε ἐπεί3ϲ2ατε ἐπει3σ2άμην. ἐπει3σ2άμην. ἐπει3ϲ2άμην. ἐπει3ϲ2άμην. ἐπεί3σ2ω. ἐπεί3σ2ω. ἐπεί3ϲ2ω. ἐπεί3ϲ2ω. ἐπεί3σ2ατο ἐπεί3σ2ατο ἐπεί3ϲ2ατο ἐπεί3ϲ2ατο ἐπεί3σ2ασθον. ἐπεί3σ2ασθον. ἐπεί3ϲ2αϲθον. ἐπεί3ϲ2αϲθον. ἐπει3σ2άμεθα. ἐπει3σ2άμεθα. ἐπει3ϲ2άμεθα. ἐπει3ϲ2άμεθα. ἐπεί3σ2ασθε. ἐπεί3σ2ασθε. ἐπεί3ϲ2αϲθε. ἐπεί3ϲ2αϲθε. ἐπεί3σ2αντο. ἐπεί3σ2αντο. ἐπεί3ϲ2αντο. ἐπεί3ϲ2αντο. ἐπεί3σ2θ ἐπεί3σ2θ ἐπεί3ϲ2θ ἐπεί3ϲ2θ ἐπει3σ2θ ἐπει3ϲ2θ ἐπε2κ1τεί ἐπε2κ1τεί ἐπέ2κ1τει ἐπέ2κ1τει ἐπε2κ1τρ ἐπέ2κ1τρ ἐπέ2κ1τρ ἐπε2ξ1 ἐπε2σ1β ἐπε2ϲ1β ἐπε2σ1ϐ ἐπε2ϲ1ϐ ἐπιπρό2σ1θ ἐπιπρό2σ1θ ἐπιπρό2ϲ1θ ἐπιπρό2ϲ1θ ἐπιπρο2σ1θ ἐπιπρο2ϲ1θ ἐπισυ2ν1 ἐπιϲυ2ν1 ἐ2σ1 ἐ2ϲ1 ἐ3σ2άω ἐ3σ2άω ἐ3ϲ2άω ἐ3ϲ2άω ἐ3σ2ημ ἐ3ϲ2ημ ἐ3σ2θ ἐ3ϲ2θ ἐ4σ3θέσ ἐ4σ3θέσ ἐ4ϲ3θέϲ ἐ4ϲ3θέϲ ἐ3σ2ιγ ἐ3ϲ2ιγ ἐ3σ2κ ἐ3ϲ2κ ἐ4σ3κά ἐ4σ3κά ἐ4ϲ3κά ἐ4ϲ3κά ἐ4σ3κα ἐ4ϲ3κα ἐ3σ2μὲν. ἐ3ϲ2μὲν. ἐ3σ2μέν. ἐ3σ2μέν. ἐ3ϲ2μέν. ἐ3ϲ2μέν. ἐ3σ2τ ἐ3ϲ2τ ἐ3σ2όμεθα ἐ3σ2όμεθα ἐ3ϲ2όμεθα ἐ3ϲ2όμεθα ἐ3σ2οίμην ἐ3σ2οίμην ἐ3ϲ2οίμην ἐ3ϲ2οίμην ἐ3σ2όμ ἐ3σ2όμ ἐ3ϲ2όμ ἐ3ϲ2όμ ἐ3σ2ομ ἐ3ϲ2ομ ἐ3σ2οῦ ἐ3ϲ2οῦ ἐ3σ2ού ἐ3σ2ού ἐ3ϲ2ού ἐ3ϲ2ού ἐ3σ2ου ἐ3ϲ2ου ἐ3σ2υ ἐ3ϲ2υ ἐ3σ2ύ ἐ3σ2ύ ἐ3ϲ2ύ ἐ3ϲ2ύ ἐσύ2ν1 ἐσύ2ν1 ἐϲύ2ν1 ἐϲύ2ν1 ἐσυ2ν1 ἐϲυ2ν1 ἐ3σ2χ ἐ3ϲ2χ ἐ4σ3χέ ἐ4σ3χέ ἐ4ϲ3χέ ἐ4ϲ3χέ ἐ3σ2ώ ἐ3σ2ώ ἐ3ϲ2ώ ἐ3ϲ2ώ ἐ3σ2ω ἐ3ϲ2ω ἔ2σ1οπ ἔ2ϲ1οπ εὐε2ξ1 εὐε3ξ2ί εὐε3ξ2ί εὐε3ξ2ι εὐπρό2σ1 εὐπρό2σ1 εὐπρό2ϲ1 εὐπρό2ϲ1 εὐπρο2σ1 εὐπρο2ϲ1 εὐσύ2ν1 εὐσύ2ν1 εὐϲύ2ν1 εὐϲύ2ν1 εὐσυ2ν1 εὐϲυ2ν1 εὐξύ2ν1 εὐξύ2ν1 εὐξυ2ν1 ἐω2σ1φ ἐω2ϲ1φ ἤ2ν1οψ. ἤ2ν1οπ ἠ2ν1όπ ἠ2ν1όπ .θεμι2σ1κρ .θεμι2ϲ1κρ .θεό2σ1δ .θεό2σ1δ .θεό2ϲ1δ .θεό2ϲ1δ .θεο2σ1δ .θεο2ϲ1δ .θεοι2σ1εχθρ .θεοι2ϲ1εχθρ .θη2ρ1αγρ .θυο2σ1κ .θυο2ϲ1κ .καθυπε2ρ1 .καλω2σ1ορ .καλω2ϲ1ορ .καλω2σ1όρ .καλω2σ1όρ .καλω2ϲ1όρ .καλω2ϲ1όρ .κα2ν1είς. .κα2ν1είς. .κα2ν1είϲ. .κα2ν1είϲ. .κα2ν1εὶς. .κα2ν1εὶϲ. .κα2ν1είσ. .κα2ν1είσ. .κα2ν1εὶσ. .κα2ν1εν .κα2ν1έν .κα2ν1έν .καταδυ2σ1ωπ .καταδυ2ϲ1ωπ .κατεδυ2σ1ώπ .κατεδυ2σ1ώπ .κατεδυ2ϲ1ώπ .κατεδυ2ϲ1ώπ .κατει2σ1 .κατει2ϲ1 .κατε2ν1αί .κατε2ν1αί .κατε2ν1ή .κατε2ν1ή .κατε2ξ1α2ν1ί .κατε2ξ1α2ν1ί .κατε2ξ1α2ν1έσ .κατε2ξ1α2ν1έσ .κατε2ξ1α2ν1έϲ .κατε2ξ1α2ν1έϲ .κερα2σ1φ .κερα2ϲ1φ .κρά2σ1π .κρά2σ1π .κρά2ϲ1π .κρά2ϲ1π .κρα2σ1π .κρα2ϲ1π .κυνό2σ1α .κυνό2σ1α .κυνό2ϲ1α .κυνό2ϲ1α .κυνό2σ1β .κυνό2σ1β .κυνό2ϲ1β .κυνό2ϲ1β .κυνό2σ1ϐ .κυνό2σ1ϐ .κυνό2ϲ1ϐ .κυνό2ϲ1ϐ .κυνο2σ1β .κυνο2ϲ1β .κυνο2σ1ϐ .κυνο2ϲ1ϐ .κυνό2σ1ο .κυνό2σ1ο .κυνό2ϲ1ο .κυνό2ϲ1ο .κυνο2σ1ο .κυνο2ϲ1ο .κυνο2σ1φ .κυνο2ϲ1φ .μελα2ν1άγ .μελα2ν1άγ .μελα2ν1αγ .μελα2ν1άε .μελα2ν1άε .μελα2ν1αέ .μελα2ν1αέ .μελα2ν1αθ .μελα2ν1αιγ .μελα2ν1αυγ .μελα2ν1είμ .μελα2ν1είμ .μελα2ν1εῖμ .μελά2ν1ιππ .μελά2ν1ιππ .μελα2ν1ίππ .μελα2ν1ίππ .μελα2ν1όμμ .μελα2ν1όμμ .μελα2ν1ομμ .μελά2ν1οσσ .μελά2ν1οσσ .μελά2ν1οϲϲ .μελά2ν1οϲϲ .μελα2ν1όσσ .μελα2ν1όσσ .μελα2ν1όϲϲ .μελα2ν1όϲϲ .μελά2ν1οστ .μελά2ν1οστ .μελά2ν1οϲτ .μελά2ν1οϲτ .μελα2ν1όστ .μελα2ν1όστ .μελα2ν1όϲτ .μελα2ν1όϲτ .μελά2ν1ουρ .μελά2ν1ουρ .μελα2ν1ούρ .μελα2ν1ούρ .μελα2ν1ουρ .μελά2ν1υ .μελά2ν1υ .μελα2ν1ύ .μελα2ν1ύ .μετε2ξ1α .μετε2ξ1έ .μετε2ξ1έ .μετε2ξ1ε .μογι2σ1 .μογι2ϲ1 .μογο2σ1τ .μογο2ϲ1τ .μυ2σ1π .μυ2ϲ1π .μυ2σ1επ .μυ2ϲ1επ .νεώ2σ1οικ .νεώ2σ1οικ .νεώ2ϲ1οικ .νεώ2ϲ1οικ .νεω2σ1οίκ .νεω2σ1οίκ .νεω2ϲ1οίκ .νεω2ϲ1οίκ .νου2ν1ε .ξυ2ν1αγ .ξυ2ν1ε .ξυ2ν1έ .ξυ2ν1έ .ξύ2ν1ε .ξύ2ν1ε .ξυ3ν2εώ .ξυ3ν2εώ .ξυ3ν2εῶ .ξυ2ν1ῆκ .ξύ2ν1ι .ξύ2ν1ι .ξυ2ν1ί .ξυ2ν1ί οἱο2ν1εί. οἱο2ν1εί. οἱο2ν1εὶ. οἱό2σ1 οἱό2σ1 οἱό2ϲ1 οἱό2ϲ1 οἰ2σ1πώτ οἰ2σ1πώτ οἰ2ϲ1πώτ οἰ2ϲ1πώτ οἰ2σ1πωτ οἰ2ϲ1πωτ ὁλο2ν1έν. ὁλο2ν1έν. ὁλο2ν1ὲν. ὁπω2σ1 ὁπω2ϲ1 ὅ2σ1γε. ὅ2ϲ1γε. ὁσο2ν1ῶν. ὁϲο2ν1ῶν. ὅ2σ1περ. ὅ2ϲ1περ. ὅ2σ1τις ὅ2ϲ1τιϲ οἷ2σ1τισι οἷ2ϲ1τιϲι οὕ2σ1τινας οὕ2ϲ1τιναϲ ἧ2σ1τινος ἧ2ϲ1τινοϲ αἷ2σ1τισι αἷ2ϲ1τιϲι ἅ2σ1τινας ἅ2ϲ1τιναϲ ὁ2σ1τι2σ1οῦν. ὁ2ϲ1τι2ϲ1οῦν. ἡτι2σ1οῦν. ἡτι2ϲ1οῦν. ὁποιου2σ1τινα2σ1οῦν. ὁποιου2ϲ1τινα2ϲ1οῦν. οὐδενό2σ1ω οὐδενό2σ1ω οὐδενό2ϲ1ω οὐδενό2ϲ1ω οὐδενο2σ1ώ οὐδενο2σ1ώ οὐδενο2ϲ1ώ οὐδενο2ϲ1ώ .παλι2ν1 .παλί2ν1 .παλί2ν1 .πα2ν1 .πά2ν1 .πά2ν1 .πα3ν2ός. .πα3ν2ός. .πα3ν2όϲ. .πα3ν2όϲ. .πα3ν2ὸς. .πα3ν2ὸϲ. .πα3ν2όσ. .πα3ν2όσ. .πα3ν2ὸσ. .πα3ν2ί. .πα3ν2ί. .πα3ν2ὶ. .πάνα. .πάνα. .πα3ν2ῶν. .πα3ν2ικ .πα3ν2ίσδ .πα3ν2ίσδ .πα3ν2ίϲδ .πα3ν2ίϲδ .πα3ν2ισδ .πα3ν2ιϲδ .πα3ν2οῦ. .πα3ν2ῷ. .πα3ν2ό. .πα3ν2ό. .πα3ν2ὸ. .πα3ν2όν. .πα3ν2όν. .πα3ν2ὸν. .πα3ν2έ. .πα3ν2έ. .πα3ν2ὲ. .πα3ν2οί. .πα3ν2οί. .πα3ν2οὶ. .πα3ν2οῖς. .πα3ν2οῖϲ. .πα3ν2οῖσ. .πα3ν2ούς. .πα3ν2ούς. .πα3ν2ούϲ. .πα3ν2ούϲ. .πα3ν2οὺς. .πα3ν2οὺϲ. .πα3ν2ούσ. .πα3ν2ούσ. .πα3ν2οὺσ. .παρα2ν1ίσχ .παρα2ν1ίσχ .παρα2ν1ίϲχ .παρα2ν1ίϲχ .παρεί2σ1 .παρεί2σ1 .παρεί2ϲ1 .παρεί2ϲ1 .παρει2σ1 .παρει2ϲ1 .παρε2κ1λ .παρε2κ1τρ .παρε2ν1εῖ .παρε2ν1ο .παρε2ξ1 .παρέ2ξ1 .παρέ2ξ1 παρέ3ξ2ω. παρέ3ξ2ω. παρέ3ξ2εις. παρέ3ξ2εις. παρέ3ξ2ειϲ. παρέ3ξ2ειϲ. παρέ3ξ2εισ. παρέ3ξ2εισ. παρέ3ξ2ει. παρέ3ξ2ει. παρέ3ξ2ετον. παρέ3ξ2ετον. παρε3ξ2έτην. παρε3ξ2έτην. παρέ3ξ2ομεν. παρέ3ξ2ομεν. παρέ3ξ2ετε. παρέ3ξ2ετε. παρέ3ξ2ουσι. παρέ3ξ2ουσι. παρέ3ξ2ουϲι. παρέ3ξ2ουϲι. παρέ3ξ2ομαι παρέ3ξ2ομαι παρέ3ξ2ῃ παρέ3ξ2ῃ παρέ3ξ2εται. παρέ3ξ2εται. παρέ3ξ2εσθον. παρέ3ξ2εσθον. παρέ3ξ2εϲθον. παρέ3ξ2εϲθον. παρε3ξ2όμεθα. παρε3ξ2όμεθα. παρέ3ξ2εσθε. παρέ3ξ2εσθε. παρέ3ξ2εϲθε. παρέ3ξ2εϲθε. παρέ3ξ2ονται. παρέ3ξ2ονται. .πλεο2ν1έ .πλεο2ν1έ .πλεο2ν1ε .προει2σ1 .προει2ϲ1 .προε2κ1 .προε2ν1 .προε2ξ1 .προέ2ξ1 .προέ2ξ1 .προ2σ1 .προ2ϲ1 .προ3σ2άβ .προ3σ2άβ .προ3ϲ2άβ .προ3ϲ2άβ .προ3σ2άϐ .προ3σ2άϐ .προ3ϲ2άϐ .προ3ϲ2άϐ .προ3σ2αβ .προ3ϲ2αβ .προ3σ2αϐ .προ3ϲ2αϐ .προσει2σ1 .προϲει2ϲ1 .προ3σ2εί .προ3σ2εί .προ3ϲ2εί .προ3ϲ2εί .προ3σ2έσει .προ3σ2έσει .προ3ϲ2έϲει .προ3ϲ2έϲει .προ3σ2εσεί .προ3σ2εσεί .προ3ϲ2εϲεί .προ3ϲ2εϲεί .προσε2ν1 .προϲε2ν1 .προσε2ξ1 .προϲε2ξ1 .πρό3σ2θι .πρό3σ2θι .πρό3ϲ2θι .πρό3ϲ2θι .προ3σ2θί .προ3σ2θί .προ3ϲ2θί .προ3ϲ2θί .προ4σ3θιγ .προ4ϲ3θιγ .πρό3σ2κοπ .πρό3σ2κοπ .πρό3ϲ2κοπ .πρό3ϲ2κοπ .προ3σ2κόπ .προ3σ2κόπ .προ3ϲ2κόπ .προ3ϲ2κόπ .προ3σ2τασ .προ3ϲ2ταϲ .προ3σ2τάτ .προ3σ2τάτ .προ3ϲ2τάτ .προ3ϲ2τάτ .προ3σ2τατ .προ3ϲ2τατ .προ3σ2ταυ .προ3ϲ2ταυ .προ3σ2τεί .προ3σ2τεί .προ3ϲ2τεί .προ3ϲ2τεί .προ3σ2τεν .προ3ϲ2τεν .προ3σ2τέν .προ3σ2τέν .προ3ϲ2τέν .προ3ϲ2τέν .προ3σ2τερν .προ3ϲ2τερν .πρό3σ2τερν .πρό3σ2τερν .πρό3ϲ2τερν .πρό3ϲ2τερν .προ3σ2τέρν .προ3σ2τέρν .προ3ϲ2τέρν .προ3ϲ2τέρν .προ3σ2τήσ .προ3σ2τήσ .προ3ϲ2τήϲ .προ3ϲ2τήϲ .προ3σ2τόμ .προ3σ2τόμ .προ3ϲ2τόμ .προ3ϲ2τόμ .προ3σ2τομ .προ3ϲ2τομ .πρό3σ2τῳ .πρό3σ2τῳ .πρό3ϲ2τῳ .πρό3ϲ2τῳ .προ3σ2τῴ .προ3ϲ2τῴ .προ3σ2υγ .προ3ϲ2υγ .προ3σ2υμ .προ3ϲ2υμ .προ3σ2υ2ν1 .προ3ϲ2υ2ν1 .πρό3σ2φαγμ .πρό3σ2φαγμ .πρό3ϲ2φαγμ .πρό3ϲ2φαγμ .προ3σ2φάγμ .προ3σ2φάγμ .προ3ϲ2φάγμ .προ3ϲ2φάγμ .προ3σ2φάζ .προ3σ2φάζ .προ3ϲ2φάζ .προ3ϲ2φάζ .προ3σ2φάττ .προ3σ2φάττ .προ3ϲ2φάττ .προ3ϲ2φάττ .πρό3σ2χημ .πρό3σ2χημ .πρό3ϲ2χημ .πρό3ϲ2χημ .προ3σ2χήμ .προ3σ2χήμ .προ3ϲ2χήμ .προ3ϲ2χήμ .πρό3σ2ω. .πρό3σ2ω. .πρό3ϲ2ω. .πρό3ϲ2ω. .πρό3σ2ωθεν. .πρό3σ2ωθεν. .πρό3ϲ2ωθεν. .πρό3ϲ2ωθεν. .προ3σ2ώτ .προ3σ2ώτ .προ3ϲ2ώτ .προ3ϲ2ώτ .προ3σ2ωτ .προ3ϲ2ωτ .προϋπε2ξ1 .πυ2ρ1άγ .πυ2ρ1άγ .πυ2ρ1αγ .πυ2ρ1αίθ .πυ2ρ1αίθ .πυ2ρ1αιθ .πυ2ρ1ῆθ .πυ2ρ1ηθ .πυ2ρ1ήθ .πυ2ρ1ήθ .πυ2ρ1ακ .πύ2ρ1αυ .πύ2ρ1αυ .πυ2ρ1αύ .πυ2ρ1αύ .πυ2ρ1αυ .πυ2ρ1ήνεμ .πυ2ρ1ήνεμ .πυ2ρ1ηνέμ .πυ2ρ1ηνέμ .πυ2ρ1ωπ .σελα2σ1φό .σελα2σ1φό .ϲελα2ϲ1φό .ϲελα2ϲ1φό .σελα2σ1φο .ϲελα2ϲ1φο .συμπαρει2σ1 .ϲυμπαρει2ϲ1 .συ2ν1 .ϲυ2ν1 .σύ2ν1 .σύ2ν1 .ϲύ2ν1 .ϲύ2ν1 .συνδιέ2ξ1 .συνδιέ2ξ1 .ϲυνδιέ2ξ1 .ϲυνδιέ2ξ1 .συνδιε2ξ1 .ϲυνδιε2ξ1 .συνδυ2σ1 .ϲυνδυ2ϲ1 .συνε2ξ1 .ϲυνε2ξ1 .τεσσαρε2σ1κ .τεϲϲαρε2ϲ1κ .τρει2σ1κ .τρει2ϲ1κ .τρι2σ1 .τρι2ϲ1 .τρι3σ2μό .τρι3σ2μό .τρι3ϲ2μό .τρι3ϲ2μό .τρι3σ2μο .τρι3ϲ2μο .τρι3σ2μῶ .τρι3ϲ2μῶ .τρι3σ2π .τρι3ϲ2π .τρί3σ2τ .τρί3σ2τ .τρί3ϲ2τ .τρί3ϲ2τ .τρι3σ2τ .τρι3ϲ2τ .τρι3σ2ώ .τρι3σ2ώ .τρι3ϲ2ώ .τρι3ϲ2ώ .τρι3σ2ω .τρι3ϲ2ω ὑο2σ1κ ὑο2ϲ1κ ὑπεί2σ1 ὑπεί2σ1 ὑπεί2ϲ1 ὑπεί2ϲ1 ὑπει2σ1 ὑπει2ϲ1 ὑπεί3σ2ας ὑπεί3σ2ας ὑπεί3ϲ2αϲ ὑπεί3ϲ2αϲ ὑπεί3σ2ασ ὑπεί3σ2ασ ὑπεί3σ2αν ὑπεί3σ2αν ὑπεί3ϲ2αν ὑπεί3ϲ2αν ὑπει3σ2άν ὑπει3σ2άν ὑπει3ϲ2άν ὑπει3ϲ2άν ὑπει3σ2άσ ὑπει3σ2άσ ὑπει3ϲ2άϲ ὑπει3ϲ2άϲ ὑπε2κ1λαμ ὑπε2κ1λήψ ὑπε2κ1λήψ ὑπε2κ1τ ὑπε2ν1 ὑπε2ξ1 ὑπε2ρ1 ὑπέ2ρ1 ὑπέ2ρ1 ὑπέ3ρ2α. ὑπέ3ρ2α. ὑπέ3ρ2ης. ὑπέ3ρ2ης. ὑπέ3ρ2ηϲ. ὑπέ3ρ2ηϲ. ὑπέ3ρ2ησ. ὑπέ3ρ2ησ. ὑπέ3ρ2ᾳ. ὑπέ3ρ2ᾳ. ὑπέ3ρ2αν. ὑπέ3ρ2αν. ὑπέ3ρ2αι. ὑπέ3ρ2αι. ὑπε3ρ2ῶν. ὑπέ3ρ2αις. ὑπέ3ρ2αις. ὑπέ3ρ2αιϲ. ὑπέ3ρ2αιϲ. ὑπέ3ρ2αισ. ὑπέ3ρ2αισ. ὑπέ3ρ2ας. ὑπέ3ρ2ας. ὑπέ3ρ2αϲ. ὑπέ3ρ2αϲ. ὑπέ3ρ2ασ. ὑπέ3ρ2ασ. ὑπε3ρ2εθ ὑπε3ρ2έθ ὑπε3ρ2έθ ὑπε3ρ2εί ὑπε3ρ2εί ὑπέ3ρ2υθ ὑπέ3ρ2υθ ὑπε3ρ2ύθ ὑπε3ρ2ύθ ὑπε3ρ2υθ ὑπερε2κ1τε ὑπερε2κ1τί ὑπερε2κ1τί ὑπε3ρ2έπτ ὑπε3ρ2έπτ ὑπε3ρ2επτ ὑπε3ρ2έψ ὑπε3ρ2έψ ὑπε3ρ2εψ ὑπε3ρ2έω ὑπε3ρ2έω ὑπε3ρ2ῶ ὑπε3ρ2έε ὑπε3ρ2έε ὑπε3ρ2εῖς. ὑπε3ρ2εῖϲ. ὑπε3ρ2εῖσ. ὑπε3ρ2εῖ. ὑπε3ρ2έο ὑπε3ρ2έο ὑπε3ρ2οῦ ὑπε3ρ2εῖτ ὑπε3ρ2ώ ὑπε3ρ2ώ ὑπε3ρ2ω ὕ2σ1τρ ὕ2ϲ1τρ ὑ2σ1τρ ὑ2ϲ1τρ .φαε2σ1φ .φαε2ϲ1φ .φω2σ1φ .φω2ϲ1φ .χαρι2σ1ανδρ .χαρι2ϲ1ανδρ .χαρι2σ1άνδρ .χαρι2σ1άνδρ .χαρι2ϲ1άνδρ .χαρι2ϲ1άνδρ .χει2ρ1άγ .χει2ρ1άγ .χει2ρ1αγ .χει2ρ1απ .χει2ρ1αψ .χει2ρ1ου .χει2ρ1ῶν .χει2ρ1άν .χει2ρ1άν .χει2ρ1αν .χη2ν1ναλ ὡ2σ1α2ν1εί. ὡ2σ1α2ν1εί. ὡ2ϲ1α2ν1εί. ὡ2ϲ1α2ν1εί. ὡ2σ1α2ν1εὶ. ὡ2ϲ1α2ν1εὶ. ὡ2σ1αύτως. ὡ2σ1αύτως. ὡ2ϲ1αύτωϲ. ὡ2ϲ1αύτωϲ. ὡ2σ1αύτωσ. ὡ2σ1αύτωσ. ὡ2σ1εί. ὡ2σ1εί. ὡ2ϲ1εί. ὡ2ϲ1εί. ὡ2σ1εὶ. ὡ2ϲ1εὶ. ὥ2σ1περ. ὥ2ϲ1περ. ὡ2σ1πε2ρ1εί. ὡ2σ1πε2ρ1εί. ὡ2ϲ1πε2ρ1εί. ὡ2ϲ1πε2ρ1εί. ὡ2σ1πε2ρ1εὶ. ὡ2ϲ1πε2ρ1εὶ. ὥ2σ1τε ὥ2ϲ1τε ι2σ1χίλιοι. ι2σ1χίλιοι. ι2ϲ1χίλιοι. ι2ϲ1χίλιοι. ι2σ1χιλίων. ι2σ1χιλίων. ι2ϲ1χιλίων. ι2ϲ1χιλίων. ι2σ1χιλίοις. ι2σ1χιλίοις. ι2ϲ1χιλίοιϲ. ι2ϲ1χιλίοιϲ. ι2σ1χιλίοισ. ι2σ1χιλίοισ. ι2σ1χιλίους. ι2σ1χιλίους. ι2ϲ1χιλίουϲ. ι2ϲ1χιλίουϲ. ι2σ1χιλίουσ. ι2σ1χιλίουσ. ι2σ1χίλιαι. ι2σ1χίλιαι. ι2ϲ1χίλιαι. ι2ϲ1χίλιαι. ι2σ1χιλίαις. ι2σ1χιλίαις. ι2ϲ1χιλίαιϲ. ι2ϲ1χιλίαιϲ. ι2σ1χιλίαισ. ι2σ1χιλίαισ. ι2σ1χιλίας. ι2σ1χιλίας. ι2ϲ1χιλίαϲ. ι2ϲ1χιλίαϲ. ι2σ1χιλίασ. ι2σ1χιλίασ. ι2σ1χίλια. ι2σ1χίλια. ι2ϲ1χίλια. ι2ϲ1χίλια. ι2σ1μύριοι. ι2σ1μύριοι. ι2ϲ1μύριοι. ι2ϲ1μύριοι. ι2σ1μυρίων. ι2σ1μυρίων. ι2ϲ1μυρίων. ι2ϲ1μυρίων. ι2σ1μυρίοις. ι2σ1μυρίοις. ι2ϲ1μυρίοιϲ. ι2ϲ1μυρίοιϲ. ι2σ1μυρίοισ. ι2σ1μυρίοισ. ι2σ1μυρίους. ι2σ1μυρίους. ι2ϲ1μυρίουϲ. ι2ϲ1μυρίουϲ. ι2σ1μυρίουσ. ι2σ1μυρίουσ. ι2σ1μύριαι. ι2σ1μύριαι. ι2ϲ1μύριαι. ι2ϲ1μύριαι. ι2σ1μυρίαις. ι2σ1μυρίαις. ι2ϲ1μυρίαιϲ. ι2ϲ1μυρίαιϲ. ι2σ1μυρίαισ. ι2σ1μυρίαισ. ι2σ1μυρίας. ι2σ1μυρίας. ι2ϲ1μυρίαϲ. ι2ϲ1μυρίαϲ. ι2σ1μυρίασ. ι2σ1μυρίασ. ι2σ1μύρια. ι2σ1μύρια. ι2ϲ1μύρια. ι2ϲ1μύρια. ι2σ1χιλιοστ ι2ϲ1χιλιοϲτ ι2σ1μυριοστ ι2ϲ1μυριοϲτ ι2σ1χιλιάκις. ι2σ1χιλιάκις. ι2ϲ1χιλιάκιϲ. ι2ϲ1χιλιάκιϲ. ι2σ1χιλιάκισ. ι2σ1χιλιάκισ. ι2σ1μυριάκις. ι2σ1μυριάκις. ι2ϲ1μυριάκιϲ. ι2ϲ1μυριάκιϲ. ι2σ1μυριάκισ. ι2σ1μυριάκισ.", ["lefthyphenmin"]=1, - ["length"]=63005, - ["n"]=4296, + ["length"]=64406, + ["n"]=4418, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/patterns/mkiv/lang-bg.lua b/tex/context/patterns/mkiv/lang-bg.lua index 46874dedb..7bcc69108 100644 --- a/tex/context/patterns/mkiv/lang-bg.lua +++ b/tex/context/patterns/mkiv/lang-bg.lua @@ -6,97 +6,902 @@ return { ["metadata"]={ ["mnemonic"]="bg", ["source"]="hyph-bg", - ["texcomment"]="% copyright: Copyright (c) 1994-2008, Georgi Boshnakov\ + ["texcomment"]="% copyright: Copyright (C) 2000, 2004, 2017 by Anton Zinoviev \ % title: Bulgarian hyphenation patterns\ -% version: 1.7, July 2008\ +% version: 21 October 2017\ % language:\ % name: Bulgarian\ -% code: bg\ +% tag: bg\ % notice: >\ % This file is part of the hyph-utf8 package.\ % See http://www.hyphenation.org for more information.\ % authors:\ -% -\ -% name: Georgi Boshnakov\ -% contact: manchester.ac.uk:georgi.boshnakov\ +% -\ +% name: Anton Zinoviev\ +% contact: anton:lml.bas.bg\ % licence:\ -% - This file is available under any of these licences:\ -% -\ -% name: LPPL\ -% version: 1.0\ -% later_authorised: true\ -% url: https://latex-project.org/lppl/lppl-1-0.html\ -% -\ -% name: MIT\ -% url: https://opensource.org/licenses/MIT\ % text: >\ -% Permission is hereby granted, free of charge, to any person\ -% obtaining a copy of this software and associated documentation\ -% files (the \"Software\"), to deal in the Software without\ -% restriction, including without limitation the rights to use,\ -% copy, modify, merge, publish, distribute, sublicense, and/or sell\ -% copies of the Software, and to permit persons to whom the\ -% Software is furnished to do so, subject to the following\ -% conditions:\ -%\ -% The above copyright notice and this permission notice shall be\ -% included in all copies or substantial portions of the Software.\ -%\ -% THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\ -% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\ -% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\ -% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\ -% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\ -% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\ -% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\ -% OTHER DEALINGS IN THE SOFTWARE.\ +% This software may be used, modified, copied, distributed, and sold,\ +% both in source and binary form provided that the above copyright\ +% notice and these terms are retained. The name of the author may not\ +% be used to endorse or promote products derived from this software\ +% without prior permission. THIS SOFTWARE IS PROVIDES \"AS IS\" AND\ +% ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. IN NO EVENT\ +% SHALL THE AUTHOR BE LIABLE FOR ANY DAMAGES ARISING IN ANY WAY OUT\ +% OF THE USE OF THIS SOFTWARE.\ % hyphenmins:\ -% for_typesetting:\ +% typesetting:\ % left: 2\ % right: 2\ -% changes:\ -% -\ -% date: 2008-06\ -% description: Changed encoding to UTF-8\ -% -\ -% date: 2006-05\ -% description: Added copyright notice\ -% -\ -% date: 2000-06\ -% description: Minor changes\ -% -\ -% date: 1994\ -% description: First version\ +% changes: See below\ % ==========================================\ -% Note: The original name of this file was 'bghyphsi.tex' which is\ -% part of the package 'bghyphen'. The package 'bghyphen' is now\ -% obsolete but it is still available on CTAN and currently (June 2008)\ -% gives the same hyphenation results.\ -%\ -%\ +% Copyright (C) 2000,2004,2017 by Anton Zinoviev \ %\ -% To make TeX use these patterns:\ +% This software may be used, modified, copied, distributed, and sold,\ +% both in source and binary form provided that the above copyright\ +% notice and these terms are retained. The name of the author may not\ +% be used to endorse or promote products derived from this software\ +% without prior permission. THIS SOFTWARE IS PROVIDES \"AS IS\" AND\ +% ANY EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED. IN NO EVENT\ +% SHALL THE AUTHOR BE LIABLE FOR ANY DAMAGES ARISING IN ANY WAY OUT\ +% OF THE USE OF THIS SOFTWARE.\ %\ -% (1) Make sure that the hyph-utf8 package is present in your TeX\ -% system.\ +% Bulgarian hyphenation patterns\ %\ -% (2) generate the necessary formats (TeX, LaTeX, pdfLaTeX, etc),\ -% instructing TeX to load 'loadhyph-bg.tex' for Bulgarian\ -% hyphenation.\ +% Generated by ./hyph-bg.sh --safe-morphology --standalone-tex\ %\ -% The LaTeX babel package sets \\lefthyphenmin and \\righthyphenmin to 2\ -% when the language is switched to Bulgarian. Developers who write\ -% support for Bulgarian outside LaTeX and/or babel need to take care\ -% of this.\ +% Both left and right hyphenmins should be set to 2.\ %\ +% % Automated Bulgarian Hyphenation\ +% % Anton Zinoviev\ +% % 21 October 2017\ +% \ +% Principles of the Bulgarian hyphenation\ +% =======================================\ +% \ +% One specificity of the Bulgarian language is that the average length\ +% of the words is greater than in English. When typesetting a Bulgarian\ +% text, hyphenation is more important than when typesetting an English\ +% text. Knuth's algorithm for line-breaking is such that in most\ +% English paragraphs no hyphenation will be used. With a Bulgarian\ +% text, however, even the Knuth's algorithm will use hyphenation in most\ +% paragraphs. Hyphenation becomes an absolute necessity if we want to\ +% obtain nice, justified paragraphs when using a software with dumb\ +% line-breaking algorithm, such as LibreOffice.\ +% \ +% According to Decree 936 of the Council of Ministers promulgated on 27\ +% November 1950, the Institute for Bulgarian Language at the Bulgarian\ +% Academy of Sciences is authorised to publish the rules of the\ +% orthography of the Bulgarian language (within certain limits).\ +% \ +% Hyphenation rules between 1945 and 1983\ +% ---------------------------------------\ +% \ +% Between 1945 and 1983 Bulgarian used syllable hyphenation with two\ +% morphological exceptions: hyphenation is preferred between a prefix\ +% and a stem and at the boundary of compound words. The following were\ +% the rules governing the hyphenation:\ +% \ +% 1. One letter does not stay alone. Words of one syllable can not be\ +% hyphenated.\ +% 2. No hyphenation before or after ь.\ +% 3. In a sequence of vowels at least one vowel stays before the\ +% hyphen.\ +% 4. A single consonant between two vowels links with the second vowel.\ +% For example по-ле /po-le/, ра-бо-та /ra-bo-ta/.\ +% 5. In a sequence of consonants between two vowels, at least one\ +% consonant stays with the second vowel. For example те-сто /te-sto/\ +% or тес-то /tes-to/.[^b]\ +% 6. In a sequence of consonants between two vowels, if the first\ +% consonant is sonorant (й /y/, л /l/, м /m/, н /n/, р /r/), then it\ +% stays with the first vowel. For example гер-дан /ger-dan/, сен-ки\ +% /sen-ki/.\ +% 7. The hyphenation separates two successive equal consonants. For\ +% example времен-но /vremen-no/, пролет-та /prolet-ta/.\ +% 8. When the letters дж /dzh/ and дз /dz/ denote a single consonant,\ +% then they are not separated. For example боя-джия /boya-dzhiya/\ +% but not бояд-жия /boyad-zhiya/. When these letters denote two\ +% consonants, then the normal rules apply: над-живявам\ +% /nad-zhivyavam/.\ +% 9. Word prefixes may not be broken. Compound words are hyphenated\ +% either at the boundary of the components or the hyphenation rules\ +% are applied to each of the components separately. For example:\ +% пред-упреждавам /pred-uprezhdavam/ (not пре-дупреждавам\ +% /pre-duprezhdavam/), пред-известие /pred-izvestie/ (not\ +% пре-дизвестие /pre-dizvestie/), за-движвам /za-dvizhvam/ (not\ +% зад-вижвам /zad-vizhvam/), авто-клуб /avto-klub/ (not авток-луб\ +% /avtok-lub/), вакуум-апарат /vakuum-aparat/ (not вакуу-мапарат\ +% /vakuu-maparat/).\ +% \ +% In some rare cases the proper application of rule 9 depends on the\ +% semantics of the word. For example пре-дреша /pre-dresha/ 'change\ +% clothes' but пред-реша /pred-resha/ 'predetermine' or прес-пите\ +% /pres-pite/ 'the snow-drifts' but пре-спите /pre-spite/ 'sleep for a\ +% while/overnight'.\ +% \ +% [^b]: In several publications this rule is formulated with the\ +% additional restriction that the sequence of consonants begins with\ +% an obstruent. I believe this restriction is unintentional. It\ +% makes no sense to forbid a hyphenation of the form AB-A but to\ +% permit ABB-A (A denotes a vowel and B – a consonant).\ +% \ +% Hyphenation rules between 1983 and 2012\ +% ---------------------------------------\ +% \ +% The Orthographic dictionary published by the Institute for Bulgarian\ +% language in 1983 introduced new hyphenation rules. The complexity of\ +% the previous rules was the main reason for the change. The new rules\ +% aimed at two objectives: simplicity and unambiguity.\ +% \ +% The new rules are:\ +% \ +% 1. A consonant between two vowels links with the second vowel. For\ +% example ви-со-чи-на /vi-so-chi-na/.\ +% 2. In a sequence of two or more consonants between two vowels, at\ +% least one consonant stays with first vowel and at least one with\ +% the second vowel. For example сес-тра /ses-tra/ and сест-ра\ +% /sest-ra/.\ +% 3. Two equal consonants are separated. For example плен-ник\ +% /plen-nik/.\ +% 4. In a sequence of two or more vowels, the first vowel stays before\ +% the hyphen. For example пре-одолея /pre-odoleya/ and прео-долея\ +% /preo-doleya/.\ +% 5. In a sequence of three or more vowels, the last vowel stays after\ +% the hyphen. For example мао-изъм /mao-izam/ but not маои-зъм\ +% /maoi-zam/.\ +% 6. The letter й /y/ between a vowel and a consonant stays with the\ +% vowel. For example май-ка /may-ka/.\ +% 7. When a sequence of two or more consonants follows й /y/ then at\ +% least one consonant links with й /y/. For example айс-берг\ +% /ays-berg/ (not ай-сберг /ay-sberg/).\ +% 8. The letter й /y/ between two vowels links with the second vowel.\ +% For example ма-йор /ma-yor/.\ +% 9. No hyphenation before or after ь.\ +% 10. When the letters дж /dzh/ denote a single consonant, then they are\ +% not separated. For example су-джук /su-dzhuk/ (not суд-жук\ +% /sud-zhuk/) but над-живея /nad-zhiveya/.\ +% 11. There must be at least one vowel before and after the hyphen.\ +% 12. One letter does not stay alone.\ +% \ +% The total disregard of the morphology by these rules leads to some\ +% strange results. For example пре-дизвестие /pre-dizvestie/ is\ +% permitted and пред-известие /pred-izvestie/ is forbidden, зад-вижвам\ +% /zad-vizhvam/ is permitted and за-движвам /za-dvizhvam/ is forbidden,\ +% авток-луб /avtok-lub/ is permitted and авто-клуб /avto-klub/ is\ +% forbidden, вакуу-мапарат /vakuu-maparat/ is permitted and\ +% вакуум-апарат /vakuum-aparat/ is forbidden. Because of this, the new\ +% rules were not universally accepted. The old rules are still\ +% mentioned in various places in Internet, they are included even in\ +% some grammar books published by the publishing houses of the Ministry\ +% of Education and of Sofia University. The software developers,\ +% however, soon came into love with the new hyphenation rules.\ +% \ +% Hyphenation rules after 2012\ +% ----------------------------\ +% \ +% In 2012 new rules came into force. There are two differences with\ +% respect to the previous rules:\ +% \ +% 1. Rule 5 of the previous rules is revoked. For example маои-зъм\ +% /maoi-zam/ becomes a valid hyphenation.\ +% 2. The new rules permit morphologically based hyphenation (however it\ +% is not obligatory). For example пред-известие /pred-izvestie/,\ +% за-движвам /za-dvizhvam/, авто-клуб /avto-klub/, вакуум-апарат\ +% /vakuum-aparat/ are valid hyphenations.\ +% \ +% Good hyphenation is a complex matter and it seems the linguists at the\ +% Institute for Bulgarian Language have recognised this. They no longer\ +% attempt to provide universal rules about everything. Instead, they\ +% provide some very permissible rules while the good application of\ +% these rules is leaved to the discretion and the experience of the\ +% printers and the developers of hyphenation software.\ +% \ +% It makes sense to use at least two different sets of hyphenation rules\ +% for Bulgarian. In most cases a more restrictive version should be\ +% used, one which attempts to eliminate the controversial cases of\ +% hyphenation. When typesetting a Bulgarian text in a narrow newspaper\ +% column, however, it will be appropriate to use more liberal\ +% hyphenation rules. It should be noted that one of the reasons for the\ +% hyphenation reform in 1983 was the desire to fix the chaotic\ +% hyphenation in the Bulgarian newspapers at that time.\ +% \ +% Computer implementations\ +% ========================\ +% \ +% Mathematical analysis of the Bulgarian hyphenation\ +% --------------------------------------------------\ +% \ +% The earliest mathematical analysis of the Bulgarian hyphenation rules\ +% belongs to Veska Noncheva.[^1] In 1988 she proposed a mathematical\ +% formalisation of the hyphenation rules in a table with 22 rows.[^2]\ +% \ +% [^1]: \ +% \ +% [^2]: Нончева В. Алгоритъм за автоматично пренасяне на думи в\ +% българския език. Математика и математическо\ +% образование. Сб. доклади на 17. ПК на СМБ. С., БАН, 1988, 479-482.\ +% \ +% In the same year Eugene Belogay[^3] proposed an alternative\ +% formalisation with only 9 rules.[^4] Belogay proved that his rules are\ +% consistent and that they form a minimal set. The rules of Belogay\ +% have negative character – every hyphenation which is not forbidden by\ +% a rule is possible hyphenation.\ +% \ +% [^3]: \ +% \ +% [^4]: Белогай Е. Алгоритъм за автоматично пренасяне на думи. Компютър\ +% за вас (1988) 3, 12-14.\ +% \ +% The following are the first 7 rules, as formulated by Belogay:\ +% \ +% 1. Б-А\ +% 2. А-ББ\ +% 3. Б-ТТ, ТТ-Б\ +% 4. ААА-Б\ +% 5. й-ББ\ +% 6. Б-ь\ +% 7. д-ж\ +% \ +% Here А denotes an arbitrary vowel letter, Б denotes an arbitrary\ +% consonant letter (including ь and й), ТТ denotes a sequence of two\ +% equal consonant letters and the letters й, ь, д and ж denote\ +% themselves. For example the rule \"Б-А\" says that we are not permitted\ +% to separate a consonant letter from immediately following vowel\ +% letter.\ +% \ +% The eighth rule of Belogay says that hyphenation is forbidden before\ +% the first and after the last vowel letter. The ninth rule of Belogay\ +% says that hyphenation is forbidden immediately after the first or\ +% immediately before the last letter of the word.\ +% \ +% Notice that is is very easy to translate the rules of Belogay in the\ +% form, required for the hyphenation algorithm of Knuth and Liang used\ +% in TeX.[^a] Let us remind that this algorithm matches the word with a\ +% set of string patterns in which the odd numbers say hyphenation is\ +% permitted in this position and even numbers say the hyphenation is\ +% forbidden. When two patterns give conflicting numbers for the same\ +% position, then the greater number wins.\ +% \ +% First, since the rules of Belogay are negative (they say where\ +% hyphenation is forbidden, not where it is permitted), we have to\ +% permit the hyphenation everywhere:\ +% \ +% 1. А1\ +% 2. Б1\ +% \ +% Then, the first seven rules of Belogay obtain the form:\ +% \ +% 1. Б2А\ +% 2. А2ББ\ +% 3. Б2ТТ ТТ2Б\ +% 4. ААА2Б\ +% 5. й2ББ\ +% 6. Б2ь\ +% 7. д2ж\ +% \ +% Since no Bulgarian word starts with more that four consonants and no\ +% Bulgarian word ends with more than three consonants, the eighth rule\ +% of Belogay can be translated in the following way:\ +% \ +% 1. .Б2\ +% 2. .ББ2\ +% 3. .БББ2\ +% 4. 2Б.\ +% 5. 2ББ.\ +% \ +% The ninth rule of Belogay means that left and right hyphen mins should\ +% be set to 2.\ +% \ +% The work of Eugene Belogay was not limited to merely a mathematical\ +% analysis of the Bulgarian hyphenation rules. In his paper he\ +% published a short algorithm in Pascal which implements these rules.\ +% It didn't take long for this algorithm to be used in various text\ +% processing software. The algorithm of Belogay was famous for many\ +% years. Even as late as 1997 in one book about TeX, the author didn't\ +% care to give any explanations but simply wrote about \"the algorithm of\ +% Belogay\" as something well known to the reader.[^5]\ +% \ +% [^a]: Liang, Franklin Mark. Word Hy-phen-a-tion by\ +% Com-put-er (Doctoral Dissertation). Stanford University, 1983\ +% \ +% [^5]: Василев В. Ултимативният ТеХ. Удоволствието да правим\ +% предпечатна подготовка сами. София, Интела, 1997, 36\ +% \ +% Bulgarian hyphenation in TeX\ +% ----------------------------\ +% \ +% One unfortunate design decision of Knuth was that the hyphenation\ +% algorithm of TeX applied the hyphenation patterns not to the input\ +% character codes but to the internal codes of the glyphs in the font.\ +% This created a problem for the Cyrillic languages because in TeX the\ +% Cyrillic fonts did not have standardised encoding. Perhaps this is\ +% one of the reasons why the earliest implementations of the Bulgarian\ +% hyphenation in TeX did not rely on the internal hyphenation algorithm\ +% of TeX. Instead, external tools were used to insert soft hyphens in\ +% all Bulgarian words. For example such a tool would replace the word\ +% сричкопренасяне /srichkoprenasyane/ with\ +% срич\\\\-коп\\\\-ре\\\\-на\\\\-ся\\\\-не /srich\\\\-kop\\\\-re\\\\-na\\\\-sya\\\\-ne/.\ +% The saying \"To every disadvantage there is a corresponding advantage\"\ +% is true – since Cyrillic and Latin letters use different character\ +% codes, an external tool could easily insert soft hyphens in all\ +% Bulgarian words while leaving the TeX commands intact.\ +% \ +% The earliest known attempt to use the hyphenation algorithm of TeX for\ +% Bulgarian was made by Ognyan Tonev in 1990.[^6] He described his work\ +% as \"a not very good translation of the rules. I work in this\ +% direction. But I don't have a 100% working complect of patterns. So,\ +% the copy I send to you[^7] is only a beta-version.\" The hyphenation\ +% patterns of Tonev don't work correctly and it seems he never completed\ +% his work.\ +% \ +% [^6]: The author of this text was unable to find current information\ +% about Ognyan Tonev in Internet. Apparently in 1990 he worked in\ +% the Center of Informatics and Computer Technology of the Bulgarian\ +% Academy of Sciences.\ +% \ +% [^7]: To Yannis Haralambous,\ +% \ +% \ +% The first usable Bulgarian hyphenation patterns for TeX were developed\ +% by Georgi Boshnakov[^8] in 1994. In order to solve the encoding\ +% problem, Boshnakov had developed TeX fonts supporting the MIK encoding\ +% (the prevalent encoding at that time in Bulgaria). This allowed him\ +% to introduce a fully working implementation only a few months after\ +% LaTeX2e became the official LaTeX version. Later Boshnakov modified\ +% his work with the Babel system. The hyphenation patterns of Boshnakov\ +% did their job well enough, so that for almost quarter a century after\ +% their initial creation, they remained the only Bulgarian hyphenation\ +% patterns in the standard distributions of TeX and CTAN.\ +% \ +% [^8]: \ +% \ +% There are some similarities between the patterns of Boshnakov and the\ +% patterns of Belogay. The following are the main differences.\ +% \ +% First, Boshnakov used an ingenious and more compact implementation of\ +% the second and the third rule. Instead of {А2ББ, Б2ТТ, ТТ2Б}, or\ +% 8×22×22+22×22+22×22=4840 patterns in total, Boshnakov has patterns of\ +% the form 2Б3Б2 and 4Т3Т4, or only 22×22=484 in total, with the same\ +% effect.\ +% \ +% The second main difference between the patterns of Boshnakov and the\ +% patterns of Belogay concerns the letter combination дж /dzh/. In\ +% Bulgarian this letter combination can denote either a single\ +% consonant, or a sequence of two consonants and the hyphenation rules\ +% change respectively. Unfortunately, it is impossible to know the\ +% meaning of дж /dzh/ without a vocabulary. The solution of Belogay was\ +% a cautious one – his rules do the hyphenation in a way which will be\ +% correct regardless of whether дж /dzh/ is a single consonant or a\ +% sequence of two consonant. On the other hand, the approach of\ +% Boshnakov is a bold one – since дж /dzh/ is more often a single\ +% consonant, his rules assume that it is always a single consonant. The\ +% number of the cases when this decision leads to bad hyphenations is\ +% insignificant in comparison with the cases in which we obtain improved\ +% hyphenation.\ +% \ +% The third main difference between the patterns of Boshnakov and the\ +% patterns of Belogay concerns the eighth rule – its implementation in\ +% the rules of Boshnakov is rather limited which leads to wrong\ +% hyphenations like бри-дж /bri-dzh/. A full implementation of this\ +% rule would require 11660 patterns in total and this would be too much\ +% for the computers in 1994.\ +% \ +% Later developments\ +% ------------------\ +% \ +% In 1995 Atanas Topalov defended a Masters thesis in the Faculty of\ +% Mathematics and Informatics at Sofia University titled \"Algorithms and\ +% software about text processing\".[^9] One of the main topics in his\ +% thesis was the Bulgarian hyphenation. Topalov criticised vehemently\ +% the official hyphenation rules and their total disregard of the\ +% morphology. He wrote:\ +% \ +% > If we look at the history of the problems of the hyphenation, we\ +% > will discover something very strange. Instead of the expected\ +% > involvement with the depths and aspiration for more admissible and\ +% > satisfactory style, we can find a growing tendency for\ +% > simplification. One unpleasant discovery is that the development of\ +% > the hyphenation software stays firmly on the principle \"let us do\ +% > the easiest thing\". The earliest works which have been studied are\ +% > from 1978. It turned out that they present the best approach\ +% > concerning the automated hyphenation. The authors have chosen the\ +% > most difficult but the most correct (from literary point of view)\ +% > method for hyphenation, namely the morphological approach.\ +% \ +% Topalov proposed his own hyphenation algorithm. The hyphenation it\ +% generated was smooth and easy to read. One obvious defect of the\ +% algorithm of Topalov was that it contradicted the official hyphenation\ +% rules at that time. One can argue, however, that his algorithm is\ +% compatible with the current hyphenation rules.\ +% \ +% [^9]: The thesis of Atanas Topalov can be accessed at the author's\ +% website \ +% \ +% In 1999 Svetla Koeva[^10] wrote a paper about the automated Bulgarian\ +% hyphenation.[^11] At that time she was a junior member of the\ +% Department of Computational Linguistics at the Institute for Bulgarian\ +% Language but now she is a director of the whole institute. The paper\ +% of Koeva contains a list of hyphenation patterns which can be used as\ +% a basis of automated hyphenation. In 2004 with the help of Stoyan\ +% Mihov[^12] the rules of Koeva were formalised with regular relations\ +% and rewriting rules. They were implemented in a software product\ +% named ItaEst which provided Bulgarian hyphenation and grammar checking\ +% for various software products of Microsoft and Apple.\ +% \ +% [^10]: \ +% \ +% [^11]: Коева, Светла. Правила за пренасяне на части от думите на нов\ +% ред. Български език. 1999/2000, 1, 84-86\ +% \ +% [^12]: \ +% \ +% The main differences between the hyphenation of Koeva and the official\ +% hyphenation rules effective after 2012 is that the separation of a\ +% long sequence of consonants between two vowels is done according to\ +% the rules valid before 1983. For example се-стра /se-stra/ and\ +% ай-сберг /ay-sberg/ are permitted. The main difference between the\ +% hyphenation of Koeva and the official hyphenation rules effective\ +% before 1983 is that the rules of Koeva disregard the morphology of the\ +% words. The following rule of Koeva is specific: in a sequence of two\ +% sonorant consonants between two vowels, we are permitted to separate\ +% the first vowel from the first consonant, for example материа-лна\ +% /materia-lna/.\ +% \ +% In 2000 Anton Zinoviev[^13] created new hyphenation patterns for TeX.\ +% He didn't know about the previous work of Boshnakov and he didn't\ +% bother to make his work available in the various TeX distributions and\ +% CTAN. His work was used mostly by the local Linux enthusiasts and the\ +% colleagues of Zinoviev. In 2001 Radostin Radnev[^14] created a free\ +% grammar dictionary of Bulgarian[^15] where he used the hyphenation\ +% patterns of Zinoviev. From there the work of Zinoviev propagated to\ +% OpenOffice, LibreOffice and various online dictionaries, including\ +% and .\ +% \ +% [^13]: The author of this text.\ +% \ +% [^14]: \ +% \ +% [^15]: \ +% \ +% The following are the main differences between the hyphenation of\ +% Zinoviev and the hyphenation of Boshnakov.\ +% \ +% First, the eighth rule of Belogay is fully implemented.\ +% \ +% Second, the rules of Zinoviev try to detect when the letters дж /dzh/\ +% (and дз /dz/) denote a single consonant and when they denote a\ +% sequence of two consonants. By default, however, Zinoviev (like\ +% Boshnakov) assumes that дж /dzh/ is a single consonant and hyphenates\ +% accordingly.\ +% \ +% Third, the rules of Zinoviev disable some cases of unpleasant\ +% hyphenations:\ +% \ +% 1. In a consonant sequence like тст /tst/, the two equal consonants т\ +% /t/ are separated. For example братст-во /bratst-vo/ is forbidden\ +% while братс-тво /brats-tvo/ and брат-ство /brat-stvo/ are\ +% permitted.\ +% 2. The hyphenation is forbidden after a sonorant consonant following\ +% an obstruent consonant. For example отм-ра /otm-ra/ is forbidden\ +% and от-мра /ot-mra/ is permitted.\ +% 3. The hyphenation separates two consecutive kindred voiced/voiceless\ +% consonants. For example субп-родукт /subp-roduct/ is forbidden and\ +% суб-продукт /sub-product/ is permitted.\ +% \ +% At the start of his work on the Bulgarian hyphenation, Zinoviev had\ +% the opportunity to discuss the hyphenation with Svetla Koeva. He\ +% remembers that some cases of unpleasant hyphenation were suggested to\ +% him by Koeva. Unfortunately, he hasn't taken notes so now he doesn't\ +% know which cases of unpleasant hyphenation have been suggested to him\ +% by Koeva and which are his own findings.\ +% \ +% The present work\ +% ================\ +% \ +% Motivation\ +% ----------\ +% \ +% The present work was carried out on the initiative of the leader of\ +% the Bulgarian localisation team of Mozilla, who contacted Zinoviev,\ +% Boshnakov and the maintainers of the TeX hyphenation patterns.[^17]\ +% This work pursues the following main objectives:\ +% \ +% 1. to update the hyphenation patterns in accordance with the current\ +% hyphenation rules;\ +% 2. to generate the hyphenation patterns by a publicly available\ +% script;\ +% 3. to make the hyphenation patterns customisable;\ +% 4. to provide documentation for the future developers.\ +% \ +% [^16]: \ +% \ +% [^17]: \ +% \ +% The current official hyphenating rules for Bulgarian are rather\ +% liberal. Very often, in a long sequence of consonants we are\ +% permitted to split the word at any position, for example аген-т-с-т-во\ +% /agen-t-s-t-vo/. This is prone to many unusual and unexpected results\ +% that interrupt the attention of the reader or deceive his expectations\ +% during the movement of his eyes to the next line. On the other hand,\ +% in order to produce nice justified paragraphs there is no need for so\ +% many hyphenation possibilities. It would be sufficient even if only\ +% one possible separation between any two syllables was permitted.\ +% \ +% Therefore, it makes sense to use a more restrictive version of the\ +% Bulgarian hyphenation, one which eliminates the controversial cases of\ +% hyphenation. Only when typesetting a Bulgarian text in a very narrow\ +% newspaper column it will be appropriate to use a more liberal version.\ +% It should be noted that some specialised English dictionaries also\ +% separate the word-division positions into two categories – preferred\ +% positions and less recommended positions.\ +% \ +% There are two methods to determine the optimal division within a\ +% sequence of consonants between two vowels:\ +% \ +% * we can hyphenate according to the syllables in the word or\ +% * we can hyphenate morphologically.\ +% \ +% Hyphenation according to the syllables in the word\ +% --------------------------------------------------\ +% \ +% Let us look at the properties of the Bulgarian syllables. All\ +% syllables have the following structure:\ +% \ +% > onset - nucleus - code\ +% \ +% The nucleus in Bulgarian is always a vowel. Both the onset and the\ +% code are (possibly empty) sequences of consonants.\ +% \ +% The Bulgarian syllables adhere to the Sonority Sequencing Principle.\ +% According to this principle, the consonants within the onset have\ +% raising sonority and the consonants within the code have decreasing\ +% sonority.\ +% \ +% Several grammar books agree that the following sonority scale is valid\ +% for Bulgarian:\ +% \ +% > voiceless obtrusive < voiced obtrusive < sonorant consonant < vowel\ +% \ +% According to the investigations of the author, the only exception to\ +% this law is due to the letter в /v/ which is a voiced obtrusive but it\ +% can be used also as a voiceless obtrusive. This exception is due to a\ +% spelling particularity of the Bulgarian language. Whenever the letter\ +% в /v/ seemingly violates the Sonority Sequencing Principle, in the\ +% spoken language this letter is read as ф /f/, that is as a voiceless\ +% obtrusive (for example the word отвсякъде /otvsyakade/ is read as\ +% отфсякъде /otfsyakade/).[^18]\ +% \ +% [^18]: No Primitive Slavonic word contains the phoneme ф /f/.\ +% Therefore, we can safely assume that in the Primitive Slavonic\ +% language the consonant ф /f/ was a positional variant of the consonant\ +% в /v/.\ +% \ +% The author has found that the sonorant consonants in Bulgarian have\ +% their own sonority scale:\ +% \ +% > м /m/ < н /n/ < л /l/ < р /r/ < й /y/\ +% \ +% Only a few words such as жанр /zhanr/ and химн /himn/ violate this\ +% scale. Such words are always loan-words and their pronunciation is\ +% somewhat problematic for the native Bulgarian speakers.\ +% \ +% In addition to the Sonority Sequencing Principle, the consonant\ +% clusters within the Bulgarian syllable adhere to the following\ +% additional principles:\ +% \ +% 1. Both in the onset and in the code, the labial and dorsal plosives\ +% precede the coronal plosives and affricates.\ +% 2. If the onset or the code contains two plosives or affricates, then\ +% there are no fricatives between them. Few words with the Latin\ +% root 'text' are exceptions: контекст /kontekst/.\ +% 3. If the onset or the code contains two fricatives other than в /v/,\ +% then there are no plosives or affricates between them.\ +% 4. If the onset or the code contains two plosives or affricates, then\ +% they both have equal sonority (both are voiced, or both are\ +% voiceless).\ +% 5. If the onset or the code contains two fricatives other than в /v/,\ +% then they both have equal sonority (both are voiced, or both are\ +% voiceless).\ +% 6. Neither the onset, nor the code may contain two labial plosives, or\ +% two coronal plosives or affricates or two dorsal plosives.\ +% 7. Neither the onset, nor the code may contain two equal consonants\ +% with the exception of в /v/ (for example втвърди /vtvardi/).[^19]\ +% \ +% [^19]: Actually, the letter в /v/ is not a real exception because in\ +% all such cases this letter denotes two different consonants – в /v/\ +% and ф /f/. Only in the Russian loan-word взвод /vzvod/ the two\ +% letters в /v/ denote a repeating consonant в /v/.\ +% \ +% From all these properties of the Bulgarian syllable we can deduce the\ +% following hyphenation rules:\ +% \ +% 1. In a sequence МК where М is a consonant with higher sonority than\ +% K, we are not permitted to hyphenate before М. Exception: when М\ +% is в /v/ and К is a voiceless consonant.\ +% 2. In a sequence КМ where М is a consonant with higher sonority than\ +% K, we are not permitted to hyphenate after М.\ +% 3. In a sequence KBT where K and T are plosives or affricates and B is\ +% fricative, we separate K from T.\ +% 4. In a sequence CKB where K is a plosive or affricate and C and B are\ +% fricatives other than в /v/, we separate C from B.\ +% 5. If in a consonant sequence a coronal plosive or affricate Т is\ +% followed by a labial or dorsal plosive К, then we separate Т from К.\ +% 6. If a consonant sequence contains two plosives or affricates, one\ +% voiced and one voiceless, then we separate them.\ +% 7. If a consonant sequence contains two fricatives other than в /v/,\ +% one voiced and one voiceless, then we separate them.\ +% 8. If a consonant sequence contains two labial plosives or two coronal\ +% plosives or affricates or two dorsal plosives then they are\ +% separated.\ +% 9. If a consonant sequence contains two equal consonants (not\ +% necessarily consecutive), then they are separated.\ +% \ +% With so many prohibitive rules, a question arises: if we apply all\ +% these rules, aren't we going to eliminate too many hyphenation\ +% possibilities? The answer is no. It can be demonstrated that between\ +% any two consecutive syllables at least one separation point will be\ +% permitted.\ +% \ +% \ +% Hyphenation according to the morphology\ +% ---------------------------------------\ +% \ +% Between 1983 and 2012 the official orthographic rules of the\ +% Bulgarian language forbade morphologically based hyphenation. After\ +% 2012 such hyphenation is permitted (but not obligatory).\ +% \ +% The most important case when it is very desirable to use\ +% morphologically based hyphenation is the case of the compound words.\ +% Divisions such as авток-луб /avtok-lub/ and вакуу-мапарат\ +% /vakuu-maparat/ are extremely irritating even if they are formally\ +% correct. Unfortunately, we do not have a vocabulary of the compound\ +% Bulgarian words that would permit us to produce rules for automated\ +% hyphenation. Therefore, the current Bulgarian hyphenation patterns do\ +% not attempt to apply morphological hyphenation to such words.\ +% \ +% Second in importance (but far more significant in terms of numbers) is\ +% the case with the word prefixes. While the eyes of the reader still\ +% look at the start of the word, the word is still unknown to him. At\ +% this point, it is very important not to deceive his expectations. For\ +% example, when the reader sees над- /nad-/ at the end of the line, he\ +% will expect that this is the prefix над- /nad-/ with semantics 'attain\ +% more than'. This expectation will be fooled if this wasn't really a\ +% prefix, but a deceiving (while formally correct) hyphenation of the\ +% word надремя /nadremya/ 'have dozed enough' where the real prefix is\ +% not над- /nad-/ but на- /na-/ with semantics 'achieve a state after\ +% accumulation'. Such hyphenation distracts the reader and makes the\ +% reading more difficult.\ +% \ +% Third in importance is the case with the word suffixes. With respect\ +% to the hyphenation rules we can divide the suffixes into three\ +% categories:\ +% \ +% 1. Suffixes starting with a vowel, for example -ар /-ar/. It is not\ +% appropriate to follow the morphology with such suffixes because\ +% this will contradict the whole hyphenation tradition of the\ +% Bulgarian language. For example крав-ар /krav-ar/ is unwarranted.\ +% 2. Suffixes starting with one consonant, for example -ка /-ka/.\ +% Usually with such suffixes the syllable boundary in the word\ +% coincides with morpheme boundary so no specific cares are\ +% necessary, for example кравар-ка /kravar-ka/. The exceptions are\ +% rare, for example: обек-тната /obek-tnata/ instead of обект-ната\ +% /obekt-nata/.\ +% 3. Suffixes starting with more than one consonant (-ски /-ski/, -ство\ +% /-stvo/). It is possible to use morphological hyphenation rules\ +% with such suffixes.\ +% \ +% Even if it is possible to use morphological hyphenation with the\ +% suffixes of the third category, it turns out, this is not as useful as\ +% it is with the case of the prefixes. When the eyes of the reader have\ +% reached this part of the word, the word is already more or less known\ +% to the reader. Therefore, at this point the morphological hyphenation\ +% does not provide any significant advantages in comparison to the\ +% simpler hyphenation based only on the syllables in the word. Consider\ +% for example the word геройс-тво /geroys-tvo/ with suffix -ство\ +% /-stvo/. When the reader sees геройс- /geroys-/ at the end of the\ +% line this will give him an early clue that the suffix of the word is\ +% -ство /-stvo/. Such non-morphological hyphenation does not deceive\ +% the expectations of the reader. On the contrary, it makes the reading\ +% easier because it gives clues to the reader about what follows on the\ +% next line.\ +% \ +% Because of these considerations, the current Bulgarian hyphenation\ +% patterns do not attempt to use morphological hyphenation with respect\ +% to the suffixes of the words. Though it would be useful to implement\ +% rules about the suffixes of the second cateogory. Hopefully, some\ +% future version will have such rules.\ +% \ +% Occasionally,[^20] a fourth morphological requirement is stated: that\ +% hyphenation should conform with the boundary between the word and the\ +% definitive articles -та /-ta/ and -те /-te/ (postfixed in Bulgarian).\ +% There is no need to pay attention to this rule because it seems to be\ +% satisfied by its own nature. The author has searched in a dictionary\ +% with over 860000 Bulgarian words for cases when the hyphenation rules\ +% would hyphenate badly with respect to the definitive article. He was\ +% unable to find even one such case with the hyphenation rules valid\ +% after 1983 and only about 10 cases with the rules valid before 1983\ +% (one of them is живопи-ста /zhivopi-sta/ instead of живопис-та\ +% /zhivopis-ta/).\ +% \ +% One unavoidable characteristic of any morphologically based automated\ +% hyphenation is that it can create wrong hyphenations. Because of\ +% this, one useful option is to use the morphology in a safe way – to\ +% use it in order to forbid bad hyphenations but to create no new\ +% hyphenation possibilities solely on the basis of the morphology.\ +% \ +% Take for example the word дозрея /dozreya/ 'ripen fully'. According\ +% to the phonological rules, we should hyphenate it as доз-рея\ +% /doz-reya/. According to the morphology, however, we should hyphenate\ +% as до-зрея /do-zreyq/ because this word is formed with the prefix до-\ +% /do-/ with semantics 'complete or supplement' and this semantics would\ +% be lost if the reader sees доз- /doz-/ at the end of the line.\ +% Therefore, there are three methods to hyphenate this word:\ +% \ +% 1. доз-рея /doz-reya/ when morphology is not used;\ +% 2. до-зрея /do-zreya/ when morphology is fully used;\ +% 3. дозрея /dozreya/ (no hyphenation) when morphology is used in a safe\ +% way.\ +% \ +% The option to use the morphology in a safe way is very attractive when\ +% the software uses a smart line-breaking algorithm which can produce\ +% good results even with less hyphenation possibilities. TeX is one\ +% such software. It should be noted that this option does not eliminate\ +% too many hyphenation possibilities because the morpheme boundaries\ +% most of the time are also syllable boundaries.\ +% \ +% [^20]: Правописен и правоговорен наръчник. Състав. Иван Хаджов,\ +% Цв. Минков; Ред. Ив. Хаджов и др. София, Бълг. кн., 1945\ +% \ +% The following are results of a statistics about the quality of the\ +% morphological rules (the number after the sign ± is the expected\ +% standard deviation of our estimations):\ +% \ +% With the option `--morphology`:\ +% \ +% * in 0.1% ±0.3% of the dictionary words the morphological patterns\ +% create very wrong hyphenation;\ +% * in 89.8% ±0.1% of the dictionary words the morphological patterns\ +% hyphenate identically with the case when no morphology patterns are\ +% used;\ +% * in 0.3% ±0.2% of the dictionary words the morphological patterns\ +% hyphenate differently in comparison to the case when no morphology\ +% patterns are used and the word is hyphenated in a way which\ +% contradicts the morphology;\ +% * in 0.6% ±0.1% of the dictionary words the morphological patterns\ +% hyphenate differently in comparison to the case when no morphology\ +% patterns are used and there is a possible hyphenation which is\ +% compatible with the word morphology but which is nevertheless\ +% forbidden by the morphology patterns.\ +% \ +% With the option `--safe-morphology`:\ +% \ +% * in 0% of the dictionary words the morphological patterns create very\ +% wrong hyphenation;\ +% * in 90.0% ±0.1% of the dictionary words the morphological patterns\ +% hyphenate identically with the case when no morphology patterns are\ +% used;\ +% * in 0.3% ±0.2% of the dictionary words the morphological patterns\ +% hyphenate differently in comparison to the case when no morphology\ +% patterns are used and the word is hyphenated in a way which\ +% contradicts the morphology;\ +% * in 0.6% ±0.1% of the dictionary words the morphological patterns\ +% hyphenate differently in comparison to the case when no morphology\ +% patterns are used and there is a possible hyphenation which is\ +% compatible both with the word morphology and with the syllable\ +% boundaries but which is nevertheless forbidden by the morphology\ +% patterns.\ +% \ +% Notice that the morphological patterns create a different hyphenation\ +% only in about 10% of the words. The following explanation can be\ +% given for this surprising fact. First, the natural evolution of the\ +% human languages tends to simplify the complex sequences of consonants.\ +% Therefore, no morpheme contains a complex sequence of consonants. And\ +% second, the Bulgarian orthography is morphological. This means that\ +% the morphemes are written according to their actual pronunciation,\ +% however the simplifications in the spoken languages which take place\ +% at the morpheme boundaries are not taken into account in the\ +% orthography. The independent operation of these two factors leads to\ +% the result that most of the time the morpheme boundaries coincide with\ +% the conventional syllable boundaries. The main exception to this is\ +% when a morpheme starts with a vowel, in this case its syllable will\ +% include one or more consonants of the preceeding morpheme. The second\ +% exception is when a morpheme ends with a vowel and the next morpheme\ +% starts with a sequence of two or more consonants.\ +% \ +% Usage of the script `hyph-bg.sh`\ +% --------------------------------\ +% \ +% The `hyph-bg.sh` is all-in-one script which can generate both\ +% documentation (this text) and Bulgarian hyphenation patterns. When\ +% given the option `--help` the script gives short usage instructions:\ +% \ +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ +% hyph-bg.sh --help\ +% Show this info\ +% hyph-bg.sh [--doc-html | --doc-latex | --doc-txt]\ +% Print documentation in various formats\ +% hyph-bg.sh [other options]\ +% Generate Bulgarian hyphenation patterns\ +% \ +% Options when generating hyphenation patterns:\ +% \ +% --standalone-tex\ +% Produce hyphenation patterns for TeX with \\patterns{ ... }.\ +% \ +% --no-hyphen-mins\ +% Hyphenation patterns which do not require hyphen mins.\ +% Otherwise: both left and right hyphen mins should be set to 2.\ +% \ +% --safe-dz\ +% Do not try to guess whether DZ is a single consonant or not.\ +% Only use hyphenation which will be correct in both cases.\ +% \ +% --permissible\ +% Permit any formally correct hyphenation, including unnatural\ +% divisions, such as studen-tstvo. Useful for educational tools\ +% or when typesetting Bulgarian text in a very short column.\ +% \ +% --morphology\ +% Apply morphology when hyphenating, for example: za-dvizhvam.\ +% May hyphenate incorrectly in some cases.\ +% \ +% --safe-morphology\ +% Apply morphology when hyphenating. Never hyphenates incorrectly\ +% but may prohibit some correct hyphenations.\ +% \ +% --no-morphology\ +% Disregard the morphology. Default.\ +% \ +% --1945\ +% Hyphenate according to the rules effective between 1945 and 1982\ +% \ +% --1983\ +% Hyphenate according to the rules effective between 1983 and 2011\ +% \ +% --2012\ +% Hyphenate according to the rules effective after 2012. Default.\ +% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\ +% \ +% The following are the recommended ways to generate hyphenation\ +% patterns by this script:\ +% \ +% `hyph-bg.sh --standalone-tex --safe-morphology`\ +% : For TeX. Apply the morphology in a safe way when the software\ +% uses a smart line-breaking algorithm.\ +% \ +% `hyph-bg.sh`\ +% : For most other software.\ +% \ +% `hyph-bg.sh --no-hyphen-mins`\ +% : The current versions of Mozilla (as of 2017) seem to ignore the\ +% hyphen mins in words that contain a dash.\ +% \ +% `hyph-bg.sh --morphology`\ +% : For professional typography with human proof-reader.\ +% \ +% `hyph-bg.sh --permissible`\ +% : For educational tools and online dictionaries which can show only one\ +% kind of hyphenation.\ +% \ +% Notice that some specialised English dictionaries separate the\ +% word-division positions into two categories – preferred positions and\ +% less recommended positions. It would be best if the Bulgarian online\ +% dictionaries could do the same. For example hyphen \"-\" can be used to\ +% display the preferred positions and dot \".\" – the less recommended\ +% positions. If a word-division position is permitted only by the\ +% patterns of `hyph-bg.sh --permissible`, then this position is less\ +% recommended.\ +% \ +% \ +% \\message{Bulgarian hyphenation patterns (options: --safe-morphology --standalone-tex, version 21 October 2017)}\ % ", }, ["patterns"]={ - ["characters"]="абвгдежзийклмнопрстуфхцчшщъьюя", - ["data"]="1а1 1б1 1в1 1г1 1д1 1е1 1ж1 1з1 1и1 1й1 1к1 1л1 1м1 1н1 1о1 1п1 1р1 1с1 1т1 1у1 1ф1 1х1 1ц1 1ч1 1ш1 1щ1 1ъ1 0ь0 1ю1 1я1 б4а б4е б4и б4о б4у б4ъ б4ю б4я в4а в4е в4и в4о в4у в4ъ в4ю в4я г4а г4е г4и г4о г4у г4ъ г4ю г4я д4а д4е д4и д4о д4у д4ъ д4ю д4я ж4а ж4е ж4и ж4о ж4у ж4ъ ж4ю ж4я з4а з4е з4и з4о з4у з4ъ з4ю з4я й4а й4е й4и й4о й4у й4ъ й4ю й4я к4а к4е к4и к4о к4у к4ъ к4ю к4я л4а л4е л4и л4о л4у л4ъ л4ю л4я м4а м4е м4и м4о м4у м4ъ м4ю м4я н4а н4е н4и н4о н4у н4ъ н4ю н4я п4а п4е п4и п4о п4у п4ъ п4ю п4я р4а р4е р4и р4о р4у р4ъ р4ю р4я с4а с4е с4и с4о с4у с4ъ с4ю с4я т4а т4е т4и т4о т4у т4ъ т4ю т4я ф4а ф4е ф4и ф4о ф4у ф4ъ ф4ю ф4я х4а х4е х4и х4о х4у х4ъ х4ю х4я ц4а ц4е ц4и ц4о ц4у ц4ъ ц4ю ц4я ч4а ч4е ч4и ч4о ч4у ч4ъ ч4ю ч4я ш4а ш4е ш4и ш4о ш4у ш4ъ ш4ю ш4я щ4а щ4е щ4и щ4о щ4у щ4ъ щ4ю щ4я ь4а ь4е ь4и ь4о ь4у ь4ъ ь4ю ь4я 4б3б4 2б3в2 2б3г2 2б3д2 2б3ж2 2б3з2 2б3й2 2б3к2 2б3л2 2б3м2 2б3н2 2б3п2 2б3р2 2б3с2 2б3т2 2б3ф2 2б3х2 2б3ц2 2б3ч2 2б3ш2 2б3щ2 2в3б2 4в3в4 2в3г2 2в3д2 2в3ж2 2в3з2 2в3й2 2в3к2 2в3л2 2в3м2 2в3н2 2в3п2 2в3р2 2в3с2 2в3т2 2в3ф2 2в3х2 2в3ц2 2в3ч2 2в3ш2 2в3щ2 2г3б2 2г3в2 4г3г4 2г3д2 2г3ж2 2г3з2 2г3й2 2г3к2 2г3л2 2г3м2 2г3н2 2г3п2 2г3р2 2г3с2 2г3т2 2г3ф2 2г3х2 2г3ц2 2г3ч2 2г3ш2 2г3щ2 2д3б2 2д3в2 2д3г2 4д3д4 3д4ж 2д3з2 2д3й2 2д3к2 2д3л2 2д3м2 2д3н2 2д3п2 2д3р2 2д3с2 2д3т2 2д3ф2 2д3х2 2д3ц2 2д3ч2 2д3ш2 2д3щ2 2ж3б2 2ж3в2 2ж3г2 2ж3д2 4ж3ж4 2ж3з2 2ж3й2 2ж3к2 2ж3л2 2ж3м2 2ж3н2 2ж3п2 2ж3р2 2ж3с2 2ж3т2 2ж3ф2 2ж3х2 2ж3ц2 2ж3ч2 2ж3ш2 2ж3щ2 2з3б2 2з3в2 2з3г2 2з3д2 2з3ж2 4з3з4 2з3й2 2з3к2 2з3л2 2з3м2 2з3н2 2з3п2 2з3р2 2з3с2 2з3т2 2з3ф2 2з3х2 2з3ц2 2з3ч2 2з3ш2 2з3щ2 2й3б2 2й3в2 2й3г2 2й3д2 2й3ж2 2й3з2 4й3й4 2й3к2 2й3л2 2й3м2 2й3н2 2й3п2 2й3р2 2й3с2 2й3т2 2й3ф2 2й3х2 2й3ц2 2й3ч2 2й3ш2 2й3щ2 2к3б2 2к3в2 2к3г2 2к3д2 2к3ж2 2к3з2 2к3й2 4к3к4 2к3л2 2к3м2 2к3н2 2к3п2 2к3р2 2к3с2 2к3т2 2к3ф2 2к3х2 2к3ц2 2к3ч2 2к3ш2 2к3щ2 2л3б2 2л3в2 2л3г2 2л3д2 2л3ж2 2л3з2 2л3й2 2л3к2 4л3л4 2л3м2 2л3н2 2л3п2 2л3р2 2л3с2 2л3т2 2л3ф2 2л3х2 2л3ц2 2л3ч2 2л3ш2 2л3щ2 2м3б2 2м3в2 2м3г2 2м3д2 2м3ж2 2м3з2 2м3й2 2м3к2 2м3л2 4м3м4 2м3н2 2м3п2 2м3р2 2м3с2 2м3т2 2м3ф2 2м3х2 2м3ц2 2м3ч2 2м3ш2 2м3щ2 2н3б2 2н3в2 2н3г2 2н3д2 2н3ж2 2н3з2 2н3й2 2н3к2 2н3л2 2н3м2 4н3н4 2н3п2 2н3р2 2н3с2 2н3т2 2н3ф2 2н3х2 2н3ц2 2н3ч2 2н3ш2 2н3щ2 2п3б2 2п3в2 2п3г2 2п3д2 2п3ж2 2п3з2 2п3й2 2п3к2 2п3л2 2п3м2 2п3н2 4п3п4 2п3р2 2п3с2 2п3т2 2п3ф2 2п3х2 2п3ц2 2п3ч2 2п3ш2 2п3щ2 2р3б2 2р3в2 2р3г2 2р3д2 2р3ж2 2р3з2 2р3й2 2р3к2 2р3л2 2р3м2 2р3н2 2р3п2 4р3р4 2р3с2 2р3т2 2р3ф2 2р3х2 2р3ц2 2р3ч2 2р3ш2 2р3щ2 2с3б2 2с3в2 2с3г2 2с3д2 2с3ж2 2с3з2 2с3й2 2с3к2 2с3л2 2с3м2 2с3н2 2с3п2 2с3р2 4с3с4 2с3т2 2с3ф2 2с3х2 2с3ц2 2с3ч2 2с3ш2 2с3щ2 2т3б2 2т3в2 2т3г2 2т3д2 2т3ж2 2т3з2 2т3й2 2т3к2 2т3л2 2т3м2 2т3н2 2т3п2 2т3р2 2т3с2 4т3т4 2т3ф2 2т3х2 2т3ц2 2т3ч2 2т3ш2 2т3щ2 2ф3б2 2ф3в2 2ф3г2 2ф3д2 2ф3ж2 2ф3з2 2ф3й2 2ф3к2 2ф3л2 2ф3м2 2ф3н2 2ф3п2 2ф3р2 2ф3с2 2ф3т2 4ф3ф4 2ф3х2 2ф3ц2 2ф3ч2 2ф3ш2 2ф3щ2 2х3б2 2х3в2 2х3г2 2х3д2 2х3ж2 2х3з2 2х3й2 2х3к2 2х3л2 2х3м2 2х3н2 2х3п2 2х3р2 2х3с2 2х3т2 2х3ф2 4х3х4 2х3ц2 2х3ч2 2х3ш2 2х3щ2 2ц3б2 2ц3в2 2ц3г2 2ц3д2 2ц3ж2 2ц3з2 2ц3й2 2ц3к2 2ц3л2 2ц3м2 2ц3н2 2ц3п2 2ц3р2 2ц3с2 2ц3т2 2ц3ф2 2ц3х2 4ц3ц4 2ц3ч2 2ц3ш2 2ц3щ2 2ч3б2 2ч3в2 2ч3г2 2ч3д2 2ч3ж2 2ч3з2 2ч3й2 2ч3к2 2ч3л2 2ч3м2 2ч3н2 2ч3п2 2ч3р2 2ч3с2 2ч3т2 2ч3ф2 2ч3х2 2ч3ц2 4ч3ч4 2ч3ш2 2ч3щ2 2ш3б2 2ш3в2 2ш3г2 2ш3д2 2ш3ж2 2ш3з2 2ш3й2 2ш3к2 2ш3л2 2ш3м2 2ш3н2 2ш3п2 2ш3р2 2ш3с2 2ш3т2 2ш3ф2 2ш3х2 2ш3ц2 2ш3ч2 4ш3ш4 2ш3щ2 2щ3б2 2щ3в2 2щ3г2 2щ3д2 2щ3ж2 2щ3з2 2щ3й2 2щ3к2 2щ3л2 2щ3м2 2щ3н2 2щ3п2 2щ3р2 2щ3с2 2щ3т2 2щ3ф2 2щ3х2 2щ3ц2 2щ3ч2 2щ3ш2 4щ3щ4 ааа4 аае4 ааи4 аао4 аау4 ааъ4 ааю4 аая4 аеа4 аее4 аеи4 аео4 аеу4 аеъ4 аею4 аея4 аиа4 аие4 аии4 аио4 аиу4 аиъ4 аию4 аия4 аоа4 аое4 аои4 аоо4 аоу4 аоъ4 аою4 аоя4 ауа4 ауе4 ауи4 ауо4 ауу4 ауъ4 аую4 ауя4 аъа4 аъе4 аъи4 аъо4 аъу4 аъъ4 аъю4 аъя4 аюа4 аюе4 аюи4 аюо4 аюу4 аюъ4 аюю4 аюя4 аяа4 аяе4 аяи4 аяо4 аяу4 аяъ4 аяю4 аяя4 еаа4 еае4 еаи4 еао4 еау4 еаъ4 еаю4 еая4 ееа4 еее4 ееи4 еео4 ееу4 ееъ4 еею4 еея4 еиа4 еие4 еии4 еио4 еиу4 еиъ4 еию4 еия4 еоа4 еое4 еои4 еоо4 еоу4 еоъ4 еою4 еоя4 еуа4 еуе4 еуи4 еуо4 еуу4 еуъ4 еую4 еуя4 еъа4 еъе4 еъи4 еъо4 еъу4 еъъ4 еъю4 еъя4 еюа4 еюе4 еюи4 еюо4 еюу4 еюъ4 еюю4 еюя4 еяа4 еяе4 еяи4 еяо4 еяу4 еяъ4 еяю4 еяя4 иаа4 иае4 иаи4 иао4 иау4 иаъ4 иаю4 иая4 иеа4 иее4 иеи4 иео4 иеу4 иеъ4 иею4 иея4 ииа4 иие4 иии4 иио4 ииу4 ииъ4 иию4 иия4 иоа4 иое4 иои4 иоо4 иоу4 иоъ4 иою4 иоя4 иуа4 иуе4 иуи4 иуо4 иуу4 иуъ4 иую4 иуя4 иъа4 иъе4 иъи4 иъо4 иъу4 иъъ4 иъю4 иъя4 июа4 июе4 июи4 июо4 июу4 июъ4 июю4 июя4 ияа4 ияе4 ияи4 ияо4 ияу4 ияъ4 ияю4 ияя4 оаа4 оае4 оаи4 оао4 оау4 оаъ4 оаю4 оая4 оеа4 оее4 оеи4 оео4 оеу4 оеъ4 оею4 оея4 оиа4 оие4 оии4 оио4 оиу4 оиъ4 оию4 оия4 ооа4 оое4 оои4 ооо4 ооу4 ооъ4 оою4 ооя4 оуа4 оуе4 оуи4 оуо4 оуу4 оуъ4 оую4 оуя4 оъа4 оъе4 оъи4 оъо4 оъу4 оъъ4 оъю4 оъя4 оюа4 оюе4 оюи4 оюо4 оюу4 оюъ4 оюю4 оюя4 ояа4 ояе4 ояи4 ояо4 ояу4 ояъ4 ояю4 ояя4 уаа4 уае4 уаи4 уао4 уау4 уаъ4 уаю4 уая4 уеа4 уее4 уеи4 уео4 уеу4 уеъ4 уею4 уея4 уиа4 уие4 уии4 уио4 уиу4 уиъ4 уию4 уия4 уоа4 уое4 уои4 уоо4 уоу4 уоъ4 уою4 уоя4 ууа4 ууе4 ууи4 ууо4 ууу4 ууъ4 уую4 ууя4 уъа4 уъе4 уъи4 уъо4 уъу4 уъъ4 уъю4 уъя4 уюа4 уюе4 уюи4 уюо4 уюу4 уюъ4 уюю4 уюя4 уяа4 уяе4 уяи4 уяо4 уяу4 уяъ4 уяю4 уяя4 ъаа4 ъае4 ъаи4 ъао4 ъау4 ъаъ4 ъаю4 ъая4 ъеа4 ъее4 ъеи4 ъео4 ъеу4 ъеъ4 ъею4 ъея4 ъиа4 ъие4 ъии4 ъио4 ъиу4 ъиъ4 ъию4 ъия4 ъоа4 ъое4 ъои4 ъоо4 ъоу4 ъоъ4 ъою4 ъоя4 ъуа4 ъуе4 ъуи4 ъуо4 ъуу4 ъуъ4 ъую4 ъуя4 ъъа4 ъъе4 ъъи4 ъъо4 ъъу4 ъъъ4 ъъю4 ъъя4 ъюа4 ъюе4 ъюи4 ъюо4 ъюу4 ъюъ4 ъюю4 ъюя4 ъяа4 ъяе4 ъяи4 ъяо4 ъяу4 ъяъ4 ъяю4 ъяя4 юаа4 юае4 юаи4 юао4 юау4 юаъ4 юаю4 юая4 юеа4 юее4 юеи4 юео4 юеу4 юеъ4 юею4 юея4 юиа4 юие4 юии4 юио4 юиу4 юиъ4 юию4 юия4 юоа4 юое4 юои4 юоо4 юоу4 юоъ4 юою4 юоя4 юуа4 юуе4 юуи4 юуо4 юуу4 юуъ4 юую4 юуя4 юъа4 юъе4 юъи4 юъо4 юъу4 юъъ4 юъю4 юъя4 ююа4 ююе4 ююи4 ююо4 ююу4 ююъ4 ююю4 ююя4 юяа4 юяе4 юяи4 юяо4 юяу4 юяъ4 юяю4 юяя4 яаа4 яае4 яаи4 яао4 яау4 яаъ4 яаю4 яая4 яеа4 яее4 яеи4 яео4 яеу4 яеъ4 яею4 яея4 яиа4 яие4 яии4 яио4 яиу4 яиъ4 яию4 яия4 яоа4 яое4 яои4 яоо4 яоу4 яоъ4 яою4 яоя4 яуа4 яуе4 яуи4 яуо4 яуу4 яуъ4 яую4 яуя4 яъа4 яъе4 яъи4 яъо4 яъу4 яъъ4 яъю4 яъя4 яюа4 яюе4 яюи4 яюо4 яюу4 яюъ4 яюю4 яюя4 яяа4 яяе4 яяи4 яяо4 яяу4 яяъ4 яяю4 яяя4 й4бб й4бв й4бг й4бд й4бж й4бз й4бй й4бк й4бл й4бм й4бн й4бп й4бр й4бс й4бт й4бф й4бх й4бц й4бч й4бш й4бщ й4вб й4вв й4вг й4вд й4вж й4вз й4вй й4вк й4вл й4вм й4вн й4вп й4вр й4вс й4вт й4вф й4вх й4вц й4вч й4вш й4вщ й4гб й4гв й4гг й4гд й4гж й4гз й4гй й4гк й4гл й4гм й4гн й4гп й4гр й4гс й4гт й4гф й4гх й4гц й4гч й4гш й4гщ й4дб й4дв й4дг й4дд й4дж й4дз й4дй й4дк й4дл й4дм й4дн й4дп й4др й4дс й4дт й4дф й4дх й4дц й4дч й4дш й4дщ й4жб й4жв й4жг й4жд й4жж й4жз й4жй й4жк й4жл й4жм й4жн й4жп й4жр й4жс й4жт й4жф й4жх й4жц й4жч й4жш й4жщ й4зб й4зв й4зг й4зд й4зж й4зз й4зй й4зк й4зл й4зм й4зн й4зп й4зр й4зс й4зт й4зф й4зх й4зц й4зч й4зш й4зщ й4йб й4йв й4йг й4йд й4йж й4йз й4йй й4йк й4йл й4йм й4йн й4йп й4йр й4йс й4йт й4йф й4йх й4йц й4йч й4йш й4йщ й4кб й4кв й4кг й4кд й4кж й4кз й4кй й4кк й4кл й4км й4кн й4кп й4кр й4кс й4кт й4кф й4кх й4кц й4кч й4кш й4кщ й4лб й4лв й4лг й4лд й4лж й4лз й4лй й4лк й4лл й4лм й4лн й4лп й4лр й4лс й4лт й4лф й4лх й4лц й4лч й4лш й4лщ й4мб й4мв й4мг й4мд й4мж й4мз й4мй й4мк й4мл й4мм й4мн й4мп й4мр й4мс й4мт й4мф й4мх й4мц й4мч й4мш й4мщ й4нб й4нв й4нг й4нд й4нж й4нз й4нй й4нк й4нл й4нм й4нн й4нп й4нр й4нс й4нт й4нф й4нх й4нц й4нч й4нш й4нщ й4пб й4пв й4пг й4пд й4пж й4пз й4пй й4пк й4пл й4пм й4пн й4пп й4пр й4пс й4пт й4пф й4пх й4пц й4пч й4пш й4пщ й4рб й4рв й4рг й4рд й4рж й4рз й4рй й4рк й4рл й4рм й4рн й4рп й4рр й4рс й4рт й4рф й4рх й4рц й4рч й4рш й4рщ й4сб й4св й4сг й4сд й4сж й4сз й4сй й4ск й4сл й4см й4сн й4сп й4ср й4сс й4ст й4сф й4сх й4сц й4сч й4сш й4сщ й4тб й4тв й4тг й4тд й4тж й4тз й4тй й4тк й4тл й4тм й4тн й4тп й4тр й4тс й4тт й4тф й4тх й4тц й4тч й4тш й4тщ й4фб й4фв й4фг й4фд й4фж й4фз й4фй й4фк й4фл й4фм й4фн й4фп й4фр й4фс й4фт й4фф й4фх й4фц й4фч й4фш й4фщ й4хб й4хв й4хг й4хд й4хж й4хз й4хй й4хк й4хл й4хм й4хн й4хп й4хр й4хс й4хт й4хф й4хх й4хц й4хч й4хш й4хщ й4цб й4цв й4цг й4цд й4цж й4цз й4цй й4цк й4цл й4цм й4цн й4цп й4цр й4цс й4цт й4цф й4цх й4цц й4цч й4цш й4цщ й4чб й4чв й4чг й4чд й4чж й4чз й4чй й4чк й4чл й4чм й4чн й4чп й4чр й4чс й4чт й4чф й4чх й4чц й4чч й4чш й4чщ й4шб й4шв й4шг й4шд й4шж й4шз й4шй й4шк й4шл й4шм й4шн й4шп й4шр й4шс й4шт й4шф й4шх й4шц й4шч й4шш й4шщ й4щб й4щв й4щг й4щд й4щж й4щз й4щй й4щк й4щл й4щм й4щн й4щп й4щр й4щс й4щт й4щф й4щх й4щц й4щч й4щш й4щщ б4ь в4ь г4ь д4ь ж4ь з4ь й4ь к4ь л4ь м4ь н4ь п4ь р4ь с4ь т4ь ф4ь х4ь ц4ь ч4ь ш4ь щ4ь ь4ь .дз4в .дж4р .дж4л .вг4л .вд4л .вг4р .вг4н .вп4л .вк4л .вк4р .вт4р .сг4л .зд4р .сг4р .сб4р .сд4р .жд4р .ск4л .сп4л .сп4р .ст4р .ск4р .шп4р .ск4в .вз4р .вс4л .вс4м .вс4р .св4р .сх4л .сх4р .хв4р .вс4т .сх4в .см4р н4кт. н4кс. к4ст.", + ["characters"]="абвгдежзийклмнопрстуфхцчшщъюя", + ["data"]=".антиа4 .антиб4 .антив4 .антиг4 .антид4 .антие4 .антиж4 .антиз4 .антии4 .антий4 .антик4 .антил4 .антим4 .антин4 .антио4 .антип4 .антир4 .антис4 .антит4 .антиу4 .антиф4 .антих4 .антиц4 .антиш4 .антищ4 .антиъ4 .антию4 .антия4 .бб8 .бв8 .бг8 .бд8 .бж8 .бз8 .бк8 .бл8 .бм8 .бн8 .бп8 .бр8 .бс8 .бт8 .бф8 .бх8 .бц8 .бч8 .бш8 .бщ8 .вб8 .вбб8 .вбв8 .вбг8 .вбд8 .вбж8 .вбз8 .вбк8 .вбл8 .вбм8 .вбн8 .вбп8 .вбр8 .вбс8 .вбт8 .вбф8 .вбх8 .вбц8 .вбч8 .вбш8 .вбщ8 .вв8 .ввб8 .ввв8 .ввг8 .ввд8 .ввж8 .ввз8 .ввк8 .ввл8 .ввм8 .ввн8 .ввп8 .ввр8 .ввс8 .ввт8 .ввф8 .ввх8 .ввц8 .ввч8 .ввш8 .ввщ8 .вг8 .вгб8 .вгв8 .вгг8 .вгд8 .вгж8 .вгз8 .вгк8 .вгл8 .вгм8 .вгн8 .вгп8 .вгр8 .вгс8 .вгт8 .вгф8 .вгх8 .вгц8 .вгч8 .вгш8 .вгщ8 .вд8 .вдб8 .вдв8 .вдг8 .вдд8 .вдж8 .вдз8 .вдк8 .вдл8 .вдм8 .вдн8 .вдп8 .вдр8 .вдс8 .вдт8 .вдф8 .вдх8 .вдц8 .вдч8 .вдш8 .вдщ8 .вж8 .вжб8 .вжв8 .вжг8 .вжд8 .вжж8 .вжз8 .вжк8 .вжл8 .вжм8 .вжн8 .вжп8 .вжр8 .вжс8 .вжт8 .вжф8 .вжх8 .вжц8 .вжч8 .вжш8 .вжщ8 .вз8 .взб8 .взв8 .взг8 .взд8 .взж8 .взз8 .взк8 .взл8 .взм8 .взн8 .взп8 .взр8 .взс8 .взт8 .взф8 .взх8 .взц8 .взч8 .взш8 .взщ8 .вк8 .вкб8 .вкв8 .вкг8 .вкд8 .вкж8 .вкз8 .вкк8 .вкл8 .вкм8 .вкн8 .вкп8 .вкр8 .вкс8 .вкт8 .вкф8 .вкх8 .вкц8 .вкч8 .вкш8 .вкщ8 .вл8 .влб8 .влв8 .влг8 .влд8 .влж8 .влз8 .влк8 .влл8 .влм8 .влн8 .влп8 .влр8 .влс8 .влт8 .влф8 .влх8 .влц8 .влч8 .влш8 .влщ8 .вм8 .вмб8 .вмв8 .вмг8 .вмд8 .вмж8 .вмз8 .вмк8 .вмл8 .вмм8 .вмн8 .вмп8 .вмр8 .вмс8 .вмт8 .вмф8 .вмх8 .вмц8 .вмч8 .вмш8 .вмщ8 .вн8 .внб8 .внв8 .внг8 .внд8 .внж8 .внз8 .внк8 .внл8 .внм8 .внн8 .внп8 .внр8 .внс8 .внт8 .внф8 .внх8 .внц8 .внч8 .внш8 .внщ8 .вп8 .впб8 .впв8 .впг8 .впд8 .впж8 .впз8 .впк8 .впл8 .впм8 .впн8 .впп8 .впр8 .впс8 .впт8 .впф8 .впх8 .впц8 .впч8 .впш8 .впщ8 .вр8 .врб8 .врв8 .врг8 .врд8 .врж8 .врз8 .врк8 .врл8 .врм8 .врн8 .врп8 .врр8 .врс8 .врт8 .врф8 .врх8 .врц8 .врч8 .врш8 .врщ8 .вс8 .всб8 .всв8 .всг8 .всд8 .всж8 .всз8 .вск8 .всл8 .всм8 .всн8 .всп8 .вср8 .всс8 .вст8 .всф8 .всх8 .всц8 .всч8 .всш8 .всщ8 .вт8 .втб8 .втв8 .втг8 .втд8 .втж8 .втз8 .втк8 .втл8 .втм8 .втн8 .втп8 .втр8 .втс8 .втт8 .втф8 .втх8 .втц8 .втч8 .втш8 .втщ8 .вф8 .вфб8 .вфв8 .вфг8 .вфд8 .вфж8 .вфз8 .вфк8 .вфл8 .вфм8 .вфн8 .вфп8 .вфр8 .вфс8 .вфт8 .вфф8 .вфх8 .вфц8 .вфч8 .вфш8 .вфщ8 .вх8 .вхб8 .вхв8 .вхг8 .вхд8 .вхж8 .вхз8 .вхк8 .вхл8 .вхм8 .вхн8 .вхп8 .вхр8 .вхс8 .вхт8 .вхф8 .вхх8 .вхц8 .вхч8 .вхш8 .вхщ8 .вц8 .вцб8 .вцв8 .вцг8 .вцд8 .вцж8 .вцз8 .вцк8 .вцл8 .вцм8 .вцн8 .вцп8 .вцр8 .вцс8 .вцт8 .вцф8 .вцх8 .вцц8 .вцч8 .вцш8 .вцщ8 .вч8 .вчб8 .вчв8 .вчг8 .вчд8 .вчж8 .вчз8 .вчк8 .вчл8 .вчм8 .вчн8 .вчп8 .вчр8 .вчс8 .вчт8 .вчф8 .вчх8 .вчц8 .вчч8 .вчш8 .вчщ8 .вш8 .вшб8 .вшв8 .вшг8 .вшд8 .вшж8 .вшз8 .вшк8 .вшл8 .вшм8 .вшн8 .вшп8 .вшр8 .вшс8 .вшт8 .вшф8 .вшх8 .вшц8 .вшч8 .вшш8 .вшщ8 .вщ8 .вщб8 .вщв8 .вщг8 .вщд8 .вщж8 .вщз8 .вщк8 .вщл8 .вщм8 .вщн8 .вщп8 .вщр8 .вщс8 .вщт8 .вщф8 .вщх8 .вщц8 .вщч8 .вщш8 .вщщ8 .въ2за4 .въ2зб4 .въ2зв4 .въ2зг4 .въ2зд4 .въ2зе4 .въ5з4ел .въ5з4е5ла .въ5з4е5лът .въ2зж4 .въ2зз4 .въ2зи4 .въ2зй4 .въ2зк4 .въ2зл4 .въ2зм4 .въ2зн4 .въ2зо4 .въ2зп4 .въ2зр4 .въ2зс4 .въ2зт4 .въ2зу4 .въ2зф4 .въ2зх4 .въ2зц4 .въ2зч4 .въ2зш4 .въ2зщ4 .въ2зъ4 .въ2зю4 .въ2зя4 .гб8 .гв8 .гг8 .гд8 .гж8 .гз8 .гк8 .гл8 .гм8 .гн8 .гп8 .гр8 .гс8 .гт8 .гф8 .гх8 .гц8 .гч8 .гш8 .гщ8 .дб8 .дв8 .дг8 .дд8 .дж8 .дз8 .дк8 .дл8 .дм8 .дн8 .доа4 .доб4 .до4б5лест .до4б5р .до4б6ро .дов4 .дог4 .до4г5м .дод4 .дое4 .дож4 .доз4 .дои4 .док4 .до4к5л .до4к5т .дол4 .до4л5н .до4л5ч .дом4 .дон4 .до4н5г .до4н5д .до4н5ж .до4н5к .до4н5с .до4н5ч .доо4 .доп4 .дор4 .дос4 .до4с5то .дот4 .доу4 .доф4 .дох4 .доц4 .доч4 .дош4 .дощ4 .доъ4 .дою4 .доя4 .дп8 .др8 .дс8 .дт8 .дф8 .дх8 .дц8 .дч8 .дш8 .дщ8 .жб8 .жв8 .жг8 .жд8 .жж8 .жз8 .жк8 .жл8 .жм8 .жн8 .жп8 .жр8 .жс8 .жт8 .жф8 .жх8 .жц8 .жч8 .жш8 .жщ8 .заа4 .заб4 .зав4 .заг4 .зад4 .за4д5гран .за4д5гроб .за4д5кулис .за4д5мин .за4д5мор .за4д5н .зае4 .заж4 .заз4 .заи4 .зак4 .зал4 .за4л5п .зам4 .зан4 .за4н5д .зао4 .зап4 .за4п5т .зар4 .за4р5з .зас4 .зат4 .зау4 .заф4 .зах4 .зац4 .зач4 .заш4 .защ4 .заъ4 .заю4 .зая4 .зб8 .зв8 .зг8 .зд8 .зж8 .зз8 .зк8 .зл8 .зм8 .зн8 .зп8 .зр8 .зс8 .зт8 .зф8 .зх8 .зц8 .зч8 .зш8 .зщ8 .иза4 .изб4 .изв4 .изг4 .изд4 .изе4 .изж4 .изз4 .изи4 .изй4 .изк4 .изл4 .изм4 .изн4 .изо2бб4 .изо2бв4 .изо2бг4 .изо2бд4 .изо2бж4 .изо2бз4 .изо4би .изо2бк4 .изо2бл4 .изо2бм4 .изо2бн4 .изо2бп4 .изо2бр4 .изо2бс4 .изо2бт4 .изо2бф4 .изо2бх4 .изо2бц4 .изо2бч4 .изо2бш4 .изо2бщ4 .изохк .изп4 .изпоа4 .изпоб4 .изпов4 .изпог4 .изпод4 .изпое4 .изпож4 .изпоз4 .изпои4 .изпой4 .изпок4 .изпол4 .изпо4л5з .изпом4 .изпо4м5п .изпон4 .изпоо4 .изпоп4 .изпор4 .изпо4р5т .изпос4 .изпот4 .изпоу4 .изпоф4 .изпох4 .изпоц4 .изпоч4 .изпош4 .изпощ4 .изпоъ4 .изпою4 .изпоя4 .изр4 .изс4 .изт4 .изу4 .изф4 .изх4 .изц4 .изч4 .изш4 .изщ4 .изъ4 .изю4 .изя4 .кб8 .кв8 .кг8 .кд8 .кж8 .кз8 .кк8 .кл8 .км8 .кн8 .кп8 .кр8 .кс8 .кт8 .кф8 .кх8 .кц8 .кч8 .кш8 .кщ8 .лб8 .лв8 .лг8 .лд8 .лж8 .лз8 .лк8 .лл8 .лм8 .лн8 .лп8 .лр8 .лс8 .лт8 .лф8 .лх8 .лц8 .лч8 .лш8 .лщ8 .мб8 .мв8 .мг8 .мд8 .мж8 .мз8 .мк8 .мл8 .мм8 .мн8 .мп8 .мр8 .мс8 .мт8 .мф8 .мх8 .мц8 .мч8 .мш8 .мщ8 .наа4 .наб4 .нав4 .наг4 .на4г5ло .на2дб4 .на2дв4 .на2дг4 .на2дд4 .на2д3ж4 .на3д4жав .на3д4жас .на2дз4 .на4ди4гр .на2дк4 .на2дл4 .на2дм4 .на2дн4 .на2дп4 .на2др4 .над4ращ .над4реб .над4рем .над4роб .над4рус .над4рън .над4рям .на2дс4 .на2дт4 .на2дф4 .на2дх4 .на2дц4 .на2дч4 .на2дш4 .на2дщ4 .нае4 .наж4 .наз4 .наи4 .нак4 .нал4 .нам4 .нан4 .нао4 .нап4 .нар4 .на4р5г .на4р5к .нас4 .нат4 .нау4 .наф4 .нах4 .нац4 .нач4 .наш4 .нащ4 .наъ4 .наю4 .ная4 .нб8 .нв8 .нг8 .нд8 .нж8 .нз8 .нк8 .нл8 .нм8 .нн8 .нп8 .нр8 .нс8 .нт8 .нф8 .нх8 .нц8 .нч8 .нш8 .нщ8 .оа4 .оа5зис .оба4гн .обб4 .обв4 .обг4 .обд4 .обж4 .обз4 .оби4гр .обк4 .обл4 .об4лаго .об4лаж .обм4 .обн4 .обо4бщ .обоз4н .обоз4р .обос4н .обособ .обп4 .обр4 .об4рем .об4рул .об4ръс .обс4 .обт4 .обу4зд .обусл .обф4 .обх4 .обц4 .обч4 .обш4 .общ4 .об4щ5н .обя4сн .ов4 .ов4дов .ов4лад .ов5ц .ов5ч .ог4 .ог5н .од4 .ое4 .ож4 .оз4 .озд4р .ои4 .ой4 .ок4 .ок5си .ок5т .ол4 .ол5тар .ом4 .ом5лет .ом5ни .он4 .он5баш .он5дул .он5зи .он5ко .он5лайн .он5то .оо4 .оп4 .оп5т .оп5ци .ор4 .ор5б .ор5г .ор5д .ор5к .ор5л .ор5н .ор5т .ор5ф .ор5х .ос4 .ос5ман .ос5мин .ос5миц .ос5мич .ос5мо .ос5те .ос5тро .ос5ци .отб4 .отв4 .отг4 .отд4 .отж4 .отз4 .оти4в .оти4д .отк4 .отл4 .отм4 .отн4 .отп4 .отр4 .отс4 .отт4 .оту4ч .отф4 .отх4 .отц4 .отч4 .отш4 .отщ4 .оу4 .оф4 .ох4 .ох5ва .ох5ка .ох5на .оц4 .оч4 .ош4 .ощ4 .оъ4 .ою4 .оя4 .пб8 .пв8 .пг8 .пд8 .пж8 .пз8 .пк8 .пл8 .пм8 .пн8 .поа4 .поб4 .пов4 .пог4 .по2дб4 .по2дв4 .под4воу .по2дг4 .по2дд4 .по2д3ж4 .по3д4жав .по3д4жур .по2дз4 .по2ди4гр .по2ди4зр .по2дк4 .по2дл4 .по2дм4 .по2дн4 .по2до4паш .по2до4стр .по2до4тд .по2до4тч .по2до4ф .по2дп4 .по2др4 .под4рем .под4рън .под4ръп .под4рям .по2дс4 .по2дт4 .по2ду4пр .по2ду4ч .по2дф4 .по2дх4 .по2дц4 .по2дч4 .по2дш4 .по2дщ4 .пое4 .пож4 .поз4 .позаа4 .позаб4 .позав4 .позаг4 .позад4 .позае4 .позаж4 .позаз4 .позаи4 .позай4 .позак4 .позал4 .позам4 .позан4 .позао4 .позап4 .позар4 .позас4 .позат4 .позау4 .позаф4 .позах4 .позац4 .позач4 .позаш4 .позащ4 .позаъ4 .позаю4 .позая4 .пои4 .пои2за4 .пои2зб4 .пои2зв4 .пои2зг4 .пои2зд4 .пои2зе4 .пои2зж4 .пои2зз4 .пои2зи4 .пои2зй4 .пои2зк4 .пои2зл4 .пои2зм4 .пои2зн4 .пои2зо4 .пои2зп4 .пои2зр4 .пои2зс4 .пои2зт4 .пои2зу4 .пои2зф4 .пои2зх4 .пои2зц4 .пои2зч4 .пои2зш4 .пои2зщ4 .пои2зъ4 .пои2зю4 .пои2зя4 .пой4 .пок4 .пол4 .по4л5з .по4л5к .по4л5с .пом4 .по4м5п .пон4 .понаа4 .понаб4 .понав4 .понаг4 .пона2дб4 .пона2дв4 .пона2дг4 .пона2дд4 .пона2дж4 .пона2дз4 .пона2ди4гр .пона2дк4 .пона2дл4 .пона2дм4 .пона2дн4 .пона2дп4 .пона2др4 .понад4ращ .понад4реб .понад4рем .понад4роб .понад4рус .понад4рън .понад4рям .пона2дс4 .пона2дт4 .пона2дф4 .пона2дх4 .пона2дц4 .пона2дч4 .пона2дш4 .пона2дщ4 .понае4 .понаж4 .поназ4 .понаи4 .понай4 .понак4 .понал4 .понам4 .понан4 .понао4 .понап4 .понар4 .понас4 .понат4 .понау4 .понаф4 .понах4 .понац4 .понач4 .понаш4 .понащ4 .понаъ4 .понаю4 .поная4 .по4н5т .пооа4 .поо4бад .поо4бажд .поо2бб4 .поо2бв4 .поо2бг4 .поо2бд4 .поо2бж4 .поо2бз4 .поо2би4гр .поо4бик .поо2бк4 .поо2бл4 .поо2бм4 .поо2бн4 .поо2бп4 .поо2бр4 .поо2бс4 .поо2бт4 .поо2бф4 .поо2бх4 .поо2бц4 .поо2бч4 .поо2бш4 .поо2бщ4 .поо2бя4сн .поов4 .поог4 .поод4 .поое4 .поож4 .пооз4 .поои4 .поой4 .поок4 .поол4 .поом4 .поон4 .пооо4 .пооп4 .поор4 .поос4 .поо2тб4 .поо2тв4 .поо2тг4 .поо2тд4 .поо2тж4 .поо2тз4 .поо2тк4 .поо2тл4 .поо2тм4 .поо2тн4 .поо2тп4 .поо2тр4 .поо2тс4 .поо2тт4 .поо2ту4ч .поо2тф4 .поо2тх4 .поо2тц4 .поо2тч4 .поо2тш4 .поо2тщ4 .пооу4 .пооф4 .поох4 .пооц4 .пооч4 .поош4 .поощ4 .поо4щ5р .пооъ4 .поою4 .пооя4 .поп4риа4 .поп4риб4 .поп4рив4 .поп4риг4 .поп4рид4 .поп4рие4 .поп4риж4 .поп4риз4 .поп4рии4 .поп4рий4 .поп4рик4 .поп4рил4 .поп4рим4 .поп4рин4 .поп4рио4 .поп4рип4 .поп4рир4 .поп4рис4 .поп4рит4 .поп4риу4 .поп4риф4 .поп4рих4 .поп4риц4 .поп4рич4 .поп4риш4 .поп4рищ4 .поп4риъ4 .поп4рию4 .поп4рия4 .пор4 .по4р5н .по4р5т .по4р5ф .по4р5ц .пос4 .по4с4т .пот4 .по4т5н .поу4 .поф4 .пох4 .поц4 .пош4 .пощ4 .поъ4 .пою4 .поя4 .пп8 .пр8 .преа4 .преб4 .прев4 .превъ2за4 .превъ2зб4 .превъ2зв4 .превъ2зг4 .превъ2зд4 .превъ2зе4 .превъ2зж4 .превъ2зз4 .превъ2зи4 .превъ2зй4 .превъ2зк4 .превъ2зл4 .превъ2зм4 .превъ2зн4 .превъ2зо4 .превъ2зп4 .превъ2зр4 .превъ2зс4 .превъ2зт4 .превъ2зу4 .превъ2зф4 .превъ2зх4 .превъ2зц4 .превъ2зч4 .превъ2зш4 .превъ2зщ4 .превъ2зъ4 .превъ2зю4 .превъ2зя4 .прег4 .пре2дб4 .пре2дв4 .пре2дг4 .пре2дд4 .пре2дж4 .пре2дз4 .пре2ди4зб4 .пре2ди4зв4 .пре2ди4нфар .пре2ди4стор .пре2дк4 .пре2дл4 .пре2дм4 .пре2дн4 .пре2до4бед .пре2до4ктом .пре2доп4ред .пре2дос4воб .пре2до2та4 .пре2до2тб4 .пре2до2тв4 .пре2до2тг4 .пре2до2тд4 .пре2до2те4 .пре2до2тж4 .пре2до2тз4 .пре2до2ти4 .пре2до2тй4 .пре2до2тк4 .пре2до2тл4 .пре2до2тм4 .пре2до2тн4 .пре2до2то4 .пре2до2тп4 .пре2до2тр4 .пре2до2тс4 .пре2до2тт4 .пре2до2ту4 .пре2до2тф4 .пре2до2тх4 .пре2до2тц4 .пре2до2тч4 .пре2до2тш4 .пре2до2тщ4 .пре2до2тъ4 .пре2до2тю4 .пре2до2тя4 .пре2дох4р .пре2дп4 .пре2др4 .пред4рем .пре2д4реш .пред4рям .пре2дс4 .пре2дт4 .пре2ду4бед .пре2ду4бежд .пре2дугад .пре2думис .пре2думиш .пре2ду4пр .пре2дусе .пре2дус4л .пре2ду4трин .пре2ду4чил .пре2дф4 .пре2дх4 .пре2дц4 .пре2дч4 .пре2дш4 .пре2дщ4 .пре2дя4в .пре2дя4ст .прее4 .преж4 .пре4ж5д .презаа4 .презаб4 .презав4 .презаг4 .презад4 .презае4 .презаж4 .презаз4 .презаи4 .презай4 .презак4 .презал4 .презам4 .презан4 .презао4 .презап4 .презар4 .презас4 .презат4 .презау4 .презаф4 .презах4 .презац4 .презач4 .презаш4 .презащ4 .презаъ4 .презаю4 .презая4 .пре2зб4 .пре2зв4 .пре2зг4 .пре2зд4 .пре2зж4 .пре2зз4 .пре2зк4 .пре2зл4 .пре2зм4 .пре2зн4 .пре4з5о4кеан .пре2зп4 .през4р .пре4з5рам .пре4з5ред .пре2зс4 .пре2зт4 .пре2зф4 .пре2зх4 .пре2зц4 .пре2зч4 .пре2зш4 .пре2зщ4 .преи4 .преи2за4 .преи2зб4 .преи2зв4 .преи2зг4 .преи2зд4 .преи2зе4 .преи2зж4 .преи2зз4 .преи2зи4 .преи2зй4 .преи2зк4 .преи2зл4 .преи2зм4 .преи2зн4 .преи2зо4 .преи2зп4 .преи2зр4 .преи2зс4 .преи2зт4 .преи2зу4 .преи2зф4 .преи2зх4 .преи2зц4 .преи2зч4 .преи2зш4 .преи2зщ4 .преи2зъ4 .преи2зю4 .преи2зя4 .прей4 .прек4 .прел4 .прем4 .прен4 .пренаа4 .пренаб4 .пренав4 .пренаг4 .пренад4 .пренае4 .пренаж4 .преназ4 .пренаи4 .пренай4 .пренак4 .пренал4 .пренам4 .пренан4 .пренао4 .пренап4 .пренар4 .пренас4 .пренат4 .пренау4 .пренаф4 .пренах4 .пренац4 .пренач4 .пренаш4 .пренащ4 .пренаъ4 .пренаю4 .преная4 .прео4 .преп4 .прер4 .прес4 .пре4с5но .пре4с5па .пре4с4пи .пре4с5ц .прет4 .преу4 .преф4 .прех4 .прец4 .преч4 .пре4ч5к .прещ4 .преъ4 .прею4 .прея4 .приа4 .приб4 .прив4 .приг4 .прид4 .прие4 .приж4 .приз4 .при4з5м .прии4 .прий4 .прик4 .прил4 .прим4 .при4м5к .прин4 .при4н5т .при4н5ц .прио4 .прип4 .при4п5в .при4п5к .при4п5н .прир4 .прис4 .прит4 .при4т5ч .приу4 .приф4 .прих4 .при4х5н .приц4 .прич4 .приш4 .при4ш5к .прищ4 .приъ4 .прию4 .прия4 .проа4 .проб4 .про4б5в .про4б5к .про4б5лем .пров4 .прог4 .прод4 .прое4 .прож4 .проз4 .прои4 .прок4 .про4к5с .прол4 .пром4 .прон4 .проо4 .проп4 .прор4 .прос4 .про4с5б .про4с4т .про4с5ф .прот4 .проу4 .прох4 .проц4 .проч4 .прош4 .прощ4 .проъ4 .прою4 .проя4 .пс8 .пт8 .пф8 .пх8 .пц8 .пч8 .пш8 .пщ8 .ра2за4 .ра2зб4 .ра2зв4 .ра2зг4 .ра2зд4 .ра2зе4 .ра2зж4 .ра2зз4 .ра2зи4 .ра2зй4 .ра2зк4 .ра2зл4 .ра2зм4 .ра2зн4 .ра2зо4 .ра2зп4 .ра2зр4 .ра2зс4 .ра2зт4 .ра2зу4 .ра2зф4 .ра2зх4 .ра2зц4 .ра2зч4 .ра2зш4 .ра2зщ4 .ра2зъ4 .ра2зю4 .ра2зя4 .рб8 .рв8 .рг8 .рд8 .рж8 .рз8 .рк8 .рл8 .рм8 .рн8 .рп8 .рр8 .рс8 .рт8 .рф8 .рх8 .рц8 .рч8 .рш8 .рщ8 .сб8 .св8 .сг8 .сд8 .сж8 .сз8 .ск8 .сл8 .см8 .сн8 .сп8 .ср8 .сс8 .ст8 .сф8 .сх8 .сц8 .сч8 .сш8 .сщ8 .тб8 .тв8 .тг8 .тд8 .тж8 .тз8 .тк8 .тл8 .тм8 .тн8 .тп8 .тр8 .тс8 .тт8 .тф8 .тх8 .тц8 .тч8 .тш8 .тщ8 .уа4 .уб4 .ув4 .уг4 .уд4 .уе4 .уж4 .уж5ки .уз4 .уз5бе .уи4 .уй4 .уй5дис .уй5ду .ук4 .ул4 .ул5т .ун4 .ун5гар .ун5ци .уо4 .уп4 .ур4 .ур5ба .ур5в .ур5н .ур5суз .ур5ти .ус4 .ус5та .ус5те .ус5ти .ут4 .ут5ре. .ут5реш .ут5рин .ут4ро .уу4 .уф4 .ух4 .уц4 .уч4 .уч5тив .уш4 .уш5но .ущ4 .уъ4 .ую4 .ую5те .уя4 .фб8 .фв8 .фг8 .фд8 .фж8 .фз8 .фк8 .фл8 .фм8 .фн8 .фп8 .фр8 .фс8 .фт8 .фф8 .фх8 .фц8 .фч8 .фш8 .фщ8 .хб8 .хв8 .хг8 .хд8 .хж8 .хз8 .хк8 .хл8 .хм8 .хн8 .хп8 .хр8 .хс8 .хт8 .хф8 .хх8 .хц8 .хч8 .хш8 .хщ8 .цб8 .цв8 .цг8 .цд8 .цж8 .цз8 .цк8 .цл8 .цм8 .цн8 .цп8 .цр8 .цс8 .цт8 .цф8 .цх8 .цц8 .цч8 .цш8 .цщ8 .чб8 .чв8 .чг8 .чд8 .чж8 .чз8 .чк8 .чл8 .чм8 .чн8 .чп8 .чр8 .чс8 .чт8 .чф8 .чх8 .чц8 .чч8 .чш8 .чщ8 .шб8 .шв8 .шг8 .шд8 .шж8 .шз8 .шк8 .шл8 .шм8 .шн8 .шп8 .шр8 .шс8 .шт8 .шф8 .шх8 .шц8 .шч8 .шш8 .шщ8 .щб8 .щв8 .щг8 .щд8 .щж8 .щз8 .щк8 .щл8 .щм8 .щн8 .щп8 .щр8 .щс8 .щт8 .щф8 .щх8 .щц8 .щч8 .щш8 .щщ8 а1 4б3б4 8бб. 4ббб4 ббв4 ббг4 ббд4 ббж4 ббз4 4ббк4 ббл4 ббм4 ббн4 4ббп4 ббр4 ббс4 4ббт4 ббф4 ббх4 4ббц4 4ббч4 ббш4 ббщ4 2б3в 8бв. 4бвб4 4бвв 4бвг4 4бвд4 4бвк4 4бвп4 4бвт4 4бвф 4бвц4 4бвч4 2б3г 8бг. 4бгб4 4бгг 4бгк4 4бгп4 4бгт4 4бгц4 4бгч4 2б3д 8бд. 4бдб4 4бдг 4бдд 4бдк4 4бдп4 4бдт4 4бдц4 4бдч4 2б3ж 8бж. 4бжб4 4бжг4 4бжд4 4бжж 4бжк4 4бжп4 4бжс 4бжт4 4бжф 4бжх 4бжц4 4бжч4 4бжш 2б3з 8бз. 4бзб4 4бзг4 4бзд4 4бзз 4бзк4 4бзп4 4бзс 4бзт4 4бзф 4бзх 4бзц4 4бзч4 4бзш бй4 4б3к4 8бк. 4бкб4 бкв4 4бкг4 4бкд4 бкж4 бкз4 4бкк4 бкл4 бкм4 бкн4 4бкп4 бкр4 бкс4 4бкт4 бкф4 бкх4 4бкц4 4бкч4 бкш4 бкщ4 2б3л4 8бл. 4блб4 4блк4 4блл 4блп4 4блт4 4блц4 4блч4 2б3м4 8бм. 4бмб4 4бмк4 4бмм 4бмп4 4бмт4 4бмц4 4бмч4 2б3н4 8бн. 4бнб4 4бнк4 4бнн 4бнп4 4бнт4 4бнц4 4бнч4 4б3п4 8бп. 4бпб4 бпв4 4бпг4 4бпд4 бпж4 бпз4 4бпк4 бпл4 бпм4 бпн4 4бпп4 бпр4 бпс4 4бпт4 бпф4 бпх4 4бпц4 4бпч4 бпш4 бпщ4 2б3р4 8бр. 4брб4 4брк4 4брп4 4брр 4брт4 4брц4 4брч4 4б3с 8бс. 4бсб4 4бсг4 4бсд4 4бсж 4бсз 4бск4 4бсп4 4бсс 4бст4 4бсц4 4бсч4 4б3т4 8бт. 4бтб4 бтв4 4бтг4 4бтд4 бтж4 бтз4 4бтк4 бтл4 бтм4 бтн4 4бтп4 бтр4 бтс4 4бтт4 бтф4 бтх4 4бтц4 4бтч4 бтш4 бтщ4 4б3ф 8бф. 4бфб4 4бфв 4бфг4 4бфд4 4бфж 4бфз 4бфк4 4бфп4 4бфт4 4бфф 4бфц4 4бфч4 4б3х 8бх. 4бхб4 4бхг4 4бхд4 4бхж 4бхз 4бхк4 4бхп4 4бхт4 4бхх 4бхц4 4бхч4 4б3ц4 8бц. 4бцб4 бцв4 4бцг4 4бцд4 бцж4 бцз4 4бцк4 бцл4 бцм4 бцн4 4бцп4 бцр4 бцс4 4бцт4 бцф4 бцх4 4бцц4 4бцч4 бцш4 бцщ4 4б3ч4 8бч. 4бчб4 бчв4 4бчг4 4бчд4 бчж4 бчз4 4бчк4 бчл4 бчм4 бчн4 4бчп4 бчр4 бчс4 4бчт4 бчф4 бчх4 4бчц4 4бчч4 бчш4 бчщ4 4б3ш 8бш. 4бшб4 4бшг4 4бшд4 4бшж 4бшз 4бшк4 4бшп4 4бшт4 4бшц4 4бшч4 4бшш 4б3щ 8бщ. 4бщб4 4бщк4 4бщп4 4бщт4 4бщц4 4бщч4 4бщщ 2в3б 8вб. 4вбб 4вбв4 4вбк 4вбп 4вбт 4вбф4 4вбц 4вбч 4в3в4 8вв. ввб4 4ввв4 ввг4 ввд4 ввж4 ввз4 ввк4 ввл4 ввм4 ввн4 ввп4 ввр4 ввс4 ввт4 4ввф4 ввх4 ввц4 ввч4 ввш4 ввщ4 2в3г 8вг. 4вгв4 4вгг 4вгк 4вгп 4вгт 4вгф4 4вгц 4вгч 2в3д 8вд. 4вдб 4вдв4 4вдг 4вдд 4вдк 4вдп 4вдт 4вдф4 4вдц 4вдч 2в3ж 8вж. 4вжв4 4вжж 4вжс 4вжф4 4вжх 4вжш 2в3з 8вз. 4взв4 4взз 4взс 4взф4 4взх 4взш вй4 2в3к 8вк. 4вкб 4вкв4 4вкг 4вкд 4вкк 4вкф4 2в3л4 8вл. 4влв4 4влл 4влф4 2в3м4 8вм. 4вмв4 4вмм 4вмф4 2в3н4 8вн. 4внв4 4внн 4внф4 2в3п 8вп. 4впб 4впв4 4впг 4впд 4впп 4впф4 2в3р4 8вр. 4врв4 4врр 4врф4 2в3с 8вс. 4всв4 4всж 4всз 4всс 4всф4 2в3т 8вт. 4втб 4втв4 4втг 4втд 4втк 4втп 4втт 4втф4 4втц 4втч 4в3ф4 8вф. вфб4 4вфв4 вфг4 вфд4 4вфж4 4вфз4 вфк4 вфл4 вфм4 вфн4 вфп4 вфр4 вфс4 вфт4 4вфф4 вфх4 вфц4 вфч4 вфш4 вфщ4 2в3х 8вх. 4вхв4 4вхж 4вхз 4вхф4 4вхх 2в3ц 8вц. 4вцб 4вцв4 4вцг 4вцд 4вцк 4вцп 4вцт 4вцф4 4вцц 4вцч 2в3ч 8вч. 4вчб 4вчв4 4вчг 4вчд 4вчк 4вчп 4вчт 4вчф4 4вчц 4вчч 2в3ш 8вш. 4вшв4 4вшж 4вшз 4вшф4 4вшш 2в3щ 8вщ. 4вщв4 4вщф4 4вщщ 2г3б 8гб. 4гбб 4гбг4 4гбк4 4гбп4 4гбт4 4гбц4 4гбч4 2г3в 8гв. 4гвб4 4гвв 4гвг4 4гвд4 4гвк4 4гвп4 4гвт4 4гвф 4гвц4 4гвч4 4г3г4 8гг. ггб4 ггв4 4ггг4 ггд4 ггж4 ггз4 4ггк4 ггл4 ггм4 ггн4 4ггп4 ггр4 ггс4 4ггт4 ггф4 ггх4 4ггц4 4ггч4 ггш4 ггщ4 2г3д 8гд. 4гдб 4гдг4 4гдд 4гдк4 4гдп4 4гдт4 4гдц4 4гдч4 2г3ж 8гж. 4гжб4 4гжг4 4гжд4 4гжж 4гжк4 4гжп4 4гжс 4гжт4 4гжф 4гжх 4гжц4 4гжч4 4гжш 2г3з 8гз. 4гзб4 4гзг4 4гзд4 4гзз 4гзк4 4гзп4 4гзс 4гзт4 4гзф 4гзх 4гзц4 4гзч4 4гзш гй4 4г3к4 8гк. 4гкб4 гкв4 4гкг4 4гкд4 гкж4 гкз4 4гкк4 гкл4 гкм4 гкн4 4гкп4 гкр4 гкс4 4гкт4 гкф4 гкх4 4гкц4 4гкч4 гкш4 гкщ4 2г3л4 8гл. 4глг4 4глк4 4глл 4глп4 4глт4 4глц4 4глч4 2г3м4 8гм. 4гмг4 4гмк4 4гмм 4гмп4 4гмт4 4гмц4 4гмч4 2г3н4 8гн. 4гнг4 4гнк4 4гнн 4гнп4 4гнт4 4гнц4 4гнч4 4г3п4 8гп. 4гпб4 гпв4 4гпг4 4гпд4 гпж4 гпз4 4гпк4 гпл4 гпм4 гпн4 4гпп4 гпр4 гпс4 4гпт4 гпф4 гпх4 4гпц4 4гпч4 гпш4 гпщ4 2г3р4 8гр. 4грг4 4грк4 4грп4 4грр 4грт4 4грц4 4грч4 4г3с 8гс. 4гсб4 4гсг4 4гсд4 4гсж 4гсз 4гск4 4гсп4 4гсс 4гст4 4гсц4 4гсч4 4г3т4 8гт. 4гтб4 гтв4 4гтг4 4гтд4 гтж4 гтз4 4гтк4 гтл4 гтм4 гтн4 4гтп4 гтр4 гтс4 4гтт4 гтф4 гтх4 4гтц4 4гтч4 гтш4 гтщ4 4г3ф 8гф. 4гфб4 4гфв 4гфг4 4гфд4 4гфж 4гфз 4гфк4 4гфп4 4гфт4 4гфф 4гфц4 4гфч4 4г3х 8гх. 4гхб4 4гхг4 4гхд4 4гхж 4гхз 4гхк4 4гхп4 4гхт4 4гхх 4гхц4 4гхч4 4г3ц4 8гц. 4гцб4 гцв4 4гцг4 4гцд4 гцж4 гцз4 4гцк4 гцл4 гцм4 гцн4 4гцп4 гцр4 гцс4 4гцт4 гцф4 гцх4 4гцц4 4гцч4 гцш4 гцщ4 4г3ч4 8гч. 4гчб4 гчв4 4гчг4 4гчд4 гчж4 гчз4 4гчк4 гчл4 гчм4 гчн4 4гчп4 гчр4 гчс4 4гчт4 гчф4 гчх4 4гчц4 4гчч4 гчш4 гчщ4 4г3ш 8гш. 4гшб4 4гшг4 4гшд4 4гшж 4гшз 4гшк4 4гшп4 4гшт4 4гшц4 4гшч4 4гшш 4г3щ 8гщ. 4гщг4 4гщк4 4гщп4 4гщт4 4гщц4 4гщч4 4гщщ 4д3б4 8дб. 4дбб4 дбв4 4дбг4 4дбд4 дбж4 дбз4 4дбк4 дбл4 дбм4 дбн4 4дбп4 дбр4 дбс4 4дбт4 дбф4 дбх4 4дбц4 4дбч4 дбш4 дбщ4 2д3в 8дв. 4двб4 4двв 4двг4 4двд4 4двк4 4двп4 4двт4 4двф 4двц4 4двч4 4д3г4 8дг. 4дгб4 дгв4 4дгг4 4дгд4 дгж4 дгз4 4дгк4 дгл4 дгм4 дгн4 4дгп4 дгр4 дгс4 4дгт4 дгф4 дгх4 4дгц4 4дгч4 дгш4 дгщ4 4д3д4 8дд. 4ддб4 ддв4 4ддг4 4ддд4 ддж4 ддз4 4ддк4 ддл4 ддм4 ддн4 4ддп4 ддр4 ддс4 4ддт4 ддф4 ддх4 4ддц4 4ддч4 ддш4 ддщ4 8дж. 4джб4 2джв 4джг4 4джд4 4джж 2джз 4джк4 2джл 2джм 2джн 4джп4 2джр 4джс 4джт4 4джф 4джх 4джц4 4джч4 4джш 2джщ 8дз. 4дзб4 2дзв 4дзг4 4дзд4 2дзж 4дзз 4дзк4 2дзл 2дзм 2дзн 4дзп4 2дзр 4дзс 4дзт4 4дзф 4дзх 4дзц4 4дзч4 4дзш 2дзщ дй4 4д3к4 8дк. 4дкб4 дкв4 4дкг4 4дкд4 дкж4 дкз4 4дкк4 дкл4 дкм4 дкн4 4дкп4 дкр4 дкс4 4дкт4 дкф4 дкх4 4дкц4 4дкч4 дкш4 дкщ4 2д3л4 8дл. 4длб4 4длг4 4длд4 4длк4 4длл 4длп4 4длт4 4длц4 4длч4 2д3м4 8дм. 4дмб4 4дмг4 4дмд4 4дмк4 4дмм 4дмп4 4дмт4 4дмц4 4дмч4 2д3н4 8дн. 4днб4 4днг4 4днд4 4днк4 4днн 4днп4 4днт4 4днц4 4днч4 4д3п4 8дп. 4дпб4 дпв4 4дпг4 4дпд4 дпж4 дпз4 4дпк4 дпл4 дпм4 дпн4 4дпп4 дпр4 дпс4 4дпт4 дпф4 дпх4 4дпц4 4дпч4 дпш4 дпщ4 2д3р4 8др. 4дрб4 4дрг4 4дрд4 4дрк4 4дрп4 4дрр 4дрт4 4дрц4 4дрч4 4д3с 8дс. 4дсб4 4дсг4 4дсд4 4дсж 4дсз 4дск4 4дсп4 4дсс 4дст4 4дсц4 4дсч4 4д3т4 8дт. 4дтб4 дтв4 4дтг4 4дтд4 дтж4 дтз4 4дтк4 дтл4 дтм4 дтн4 4дтп4 дтр4 дтс4 4дтт4 дтф4 дтх4 4дтц4 4дтч4 дтш4 дтщ4 4д3ф 8дф. 4дфб4 4дфв 4дфг4 4дфд4 4дфж 4дфз 4дфк4 4дфп4 4дфт4 4дфф 4дфц4 4дфч4 4д3х 8дх. 4дхб4 4дхг4 4дхд4 4дхж 4дхз 4дхк4 4дхп4 4дхт4 4дхх 4дхц4 4дхч4 4д3ц4 8дц. 4дцб4 дцв4 4дцг4 4дцд4 дцж4 дцз4 4дцк4 дцл4 дцм4 дцн4 4дцп4 дцр4 дцс4 4дцт4 дцф4 дцх4 4дцц4 4дцч4 дцш4 дцщ4 4д3ч4 8дч. 4дчб4 дчв4 4дчг4 4дчд4 дчж4 дчз4 4дчк4 дчл4 дчм4 дчн4 4дчп4 дчр4 дчс4 4дчт4 дчф4 дчх4 4дчц4 4дчч4 дчш4 дчщ4 4д3ш 8дш. 4дшб4 4дшг4 4дшд4 4дшж 4дшз 4дшк4 4дшп4 4дшт4 4дшц4 4дшч4 4дшш 4д3щ 8дщ. 4дщб4 4дщг4 4дщд4 4дщк4 4дщп4 4дщт4 4дщц4 4дщч4 4дщщ е1 2ж3б 8жб. 4жбб 4жбж4 4жбз4 4жбк 4жбп 4жбс4 4жбт 4жбф4 4жбх4 4жбц 4жбч 4жбш4 2ж3в 8жв. 4жвв 4жвж4 4жвс4 4жвф4 4жвх4 4жвш4 2ж3г 8жг. 4жгг 4жгж4 4жгз4 4жгк 4жгп 4жгс4 4жгт 4жгф4 4жгх4 4жгц 4жгч 4жгш4 2ж3д 8жд. 4ждб 4ждг 4ждд 4ждж4 4ждз4 4ждк 4ждп 4ждс4 4ждт 4ждф4 4ждх4 4ждц 4ждч 4ждш4 4ж3ж4 8жж. жжб4 жжв4 жжг4 жжд4 4жжж4 жжз4 жжк4 жжл4 жжм4 жжн4 жжп4 жжр4 4жжс4 жжт4 4жжф4 4жжх4 жжц4 жжч4 4жжш4 жжщ4 2ж3з 8жз. 4жзж4 4жзз 4жзс4 4жзф4 4жзх4 4жзш4 жй4 4ж3к 8жк. 4жкб 4жкг 4жкд 4жкж4 4жкз4 4жкк 4жкс4 4жкф4 4жкх4 4жкш4 2ж3л4 8жл. 4жлж4 4жлл 4жлс4 4жлф4 4жлх4 4жлш4 2ж3м4 8жм. 4жмж4 4жмм 4жмс4 4жмф4 4жмх4 4жмш4 2ж3н4 8жн. 4жнж4 4жнн 4жнс4 4жнф4 4жнх4 4жнш4 4ж3п 8жп. 4жпб 4жпг 4жпд 4жпж4 4жпз4 4жпп 4жпс4 4жпф4 4жпх4 4жпш4 2ж3р4 8жр. 4жрж4 4жрр 4жрс4 4жрф4 4жрх4 4жрш4 4ж3с4 8жс. жсб4 жсв4 жсг4 жсд4 4жсж4 4жсз4 жск4 жсл4 жсм4 жсн4 жсп4 жср4 4жсс4 жст4 4жсф4 4жсх4 жсц4 жсч4 4жсш4 жсщ4 4ж3т 8жт. 4жтб 4жтг 4жтд 4жтж4 4жтз4 4жтк 4жтп 4жтс4 4жтт 4жтф4 4жтх4 4жтц 4жтч 4жтш4 4ж3ф4 8жф. жфб4 4жфв4 жфг4 жфд4 4жфж4 4жфз4 жфк4 жфл4 жфм4 жфн4 жфп4 жфр4 4жфс4 жфт4 4жфф4 4жфх4 жфц4 жфч4 4жфш4 жфщ4 4ж3х4 8жх. жхб4 жхв4 жхг4 жхд4 4жхж4 4жхз4 жхк4 жхл4 жхм4 жхн4 жхп4 жхр4 4жхс4 жхт4 4жхф4 4жхх4 жхц4 жхч4 4жхш4 жхщ4 4ж3ц 8жц. 4жцб 4жцг 4жцд 4жцж4 4жцз4 4жцк 4жцп 4жцс4 4жцт 4жцф4 4жцх4 4жцц 4жцч 4жцш4 4ж3ч 8жч. 4жчб 4жчг 4жчд 4жчж4 4жчз4 4жчк 4жчп 4жчс4 4жчт 4жчф4 4жчх4 4жчц 4жчч 4жчш4 4ж3ш4 8жш. жшб4 жшв4 жшг4 жшд4 4жшж4 4жшз4 жшк4 жшл4 жшм4 жшн4 жшп4 жшр4 4жшс4 жшт4 4жшф4 4жшх4 жшц4 жшч4 4жшш4 жшщ4 4ж3щ 8жщ. 4жщж4 4жщс4 4жщф4 4жщх4 4жщш4 4жщщ 2з3б 8зб. 4збб 4збж4 4збз4 4збк 4збп 4збс4 4збт 4збф4 4збх4 4збц 4збч 4збш4 2з3в 8зв. 4звв 4звз4 4звс4 4звф4 4звх4 4звш4 2з3г 8зг. 4згг 4згж4 4згз4 4згк 4згп 4згс4 4згт 4згф4 4згх4 4згц 4згч 4згш4 2з3д 8зд. 4здб 4здг 4здд 4здж4 4здз4 4здк 4здп 4здс4 4здт 4здф4 4здх4 4здц 4здч 4здш4 2з3ж 8зж. 4зжж 4зжз4 4зжс4 4зжф4 4зжх4 4зжш4 4з3з4 8зз. ззб4 ззв4 ззг4 ззд4 ззж4 4ззз4 ззк4 ззл4 ззм4 ззн4 ззп4 ззр4 4ззс4 ззт4 4ззф4 4ззх4 ззц4 ззч4 4ззш4 ззщ4 зй4 4з3к 8зк. 4зкб 4зкг 4зкд 4зкж4 4зкз4 4зкк 4зкс4 4зкф4 4зкх4 4зкш4 2з3л4 8зл. 4злз4 4злл 4злс4 4злф4 4злх4 4злш4 2з3м4 8зм. 4змз4 4змм 4змс4 4змф4 4змх4 4змш4 2з3н4 8зн. 4знз4 4знн 4знс4 4знф4 4знх4 4знш4 4з3п 8зп. 4зпб 4зпг 4зпд 4зпж4 4зпз4 4зпп 4зпс4 4зпф4 4зпх4 4зпш4 2з3р4 8зр. 4зрз4 4зрр 4зрс4 4зрф4 4зрх4 4зрш4 4з3с4 8зс. зсб4 зсв4 зсг4 зсд4 4зсж4 4зсз4 зск4 зсл4 зсм4 зсн4 зсп4 зср4 4зсс4 зст4 4зсф4 4зсх4 зсц4 зсч4 4зсш4 зсщ4 4з3т 8зт. 4зтб 4зтг 4зтд 4зтж4 4зтз4 4зтк 4зтп 4зтс4 4зтт 4зтф4 4зтх4 4зтц 4зтч 4зтш4 4з3ф4 8зф. зфб4 4зфв4 зфг4 зфд4 4зфж4 4зфз4 зфк4 зфл4 зфм4 зфн4 зфп4 зфр4 4зфс4 зфт4 4зфф4 4зфх4 зфц4 зфч4 4зфш4 зфщ4 4з3х4 8зх. зхб4 зхв4 зхг4 зхд4 4зхж4 4зхз4 зхк4 зхл4 зхм4 зхн4 зхп4 зхр4 4зхс4 зхт4 4зхф4 4зхх4 зхц4 зхч4 4зхш4 зхщ4 4з3ц 8зц. 4зцб 4зцг 4зцд 4зцж4 4зцз4 4зцк 4зцп 4зцс4 4зцт 4зцф4 4зцх4 4зцц 4зцч 4зцш4 4з3ч 8зч. 4зчб 4зчг 4зчд 4зчж4 4зчз4 4зчк 4зчп 4зчс4 4зчт 4зчф4 4зчх4 4зчц 4зчч 4зчш4 4з3ш4 8зш. зшб4 зшв4 зшг4 зшд4 4зшж4 4зшз4 зшк4 зшл4 зшм4 зшн4 зшп4 зшр4 4зшс4 зшт4 4зшф4 4зшх4 зшц4 зшч4 4зшш4 зшщ4 4з3щ 8зщ. 4зщз4 4зщс4 4зщф4 4зщх4 4зщш4 4зщщ и1 4й1б 4й1в 4й1г 4й1д 4й1ж 4й1з 4й1к 4й1л 4й1м 4й1н 4й1п 4й1р 4й1с 4й1т 4й1ф 4й1х 4й1ц 4й1ч 4й1ш 4й1щ 4к3б4 8кб. 4кбб4 кбв4 4кбг4 4кбд4 кбж4 кбз4 4кбк4 кбл4 кбм4 кбн4 4кбп4 кбр4 кбс4 4кбт4 кбф4 кбх4 4кбц4 4кбч4 кбш4 кбщ4 2к3в4 8кв. 4квб4 4квв 4квг4 4квд4 4квк4 4квп4 4квт4 4квф 4квц4 4квч4 4к3г4 8кг. 4кгб4 кгв4 4кгг4 4кгд4 кгж4 кгз4 4кгк4 кгл4 кгм4 кгн4 4кгп4 кгр4 кгс4 4кгт4 кгф4 кгх4 4кгц4 4кгч4 кгш4 кгщ4 4к3д4 8кд. 4кдб4 кдв4 4кдг4 4кдд4 кдж4 кдз4 4кдк4 кдл4 кдм4 кдн4 4кдп4 кдр4 кдс4 4кдт4 кдф4 кдх4 4кдц4 4кдч4 кдш4 кдщ4 2к3ж4 8кж. 4кжб4 4кжг4 4кжд4 4кжж 4кжк4 4кжп4 4кжс 4кжт4 4кжф 4кжх 4кжц4 4кжч4 4кжш 2к3з4 8кз. 4кзб4 4кзг4 4кзд4 4кзз 4кзк4 4кзп4 4кзс 4кзт4 4кзф 4кзх 4кзц4 4кзч4 4кзш кй4 4к3к4 8кк. 4ккб4 ккв4 4ккг4 4ккд4 ккж4 ккз4 4ккк4 ккл4 ккм4 ккн4 ккп4 ккр4 ккс4 ккт4 ккф4 ккх4 ккц4 ккч4 ккш4 ккщ4 2к3л4 8кл. 4клб4 4клг4 4клд4 4клк4 4клл 2к3м4 8км. 4кмб4 4кмг4 4кмд4 4кмк4 4кмм 2к3н4 8кн. 4кнб4 4кнг4 4кнд4 4кнк4 4кнн 2к3п 8кп. 4кпб4 4кпг4 4кпд4 4кпк4 4кпп 2к3р4 8кр. 4крб4 4крг4 4крд4 4крк4 4крр 2к3с 8кс. 4ксб4 4ксг4 4ксд4 4ксж 4ксз 4кск4 4ксп4 4ксс 4кст4 4ксц4 4ксч4 2к3т 8кт. 4ктб4 4ктг4 4ктд4 4ктк4 4ктп 4ктт 4ктц 4ктч 2к3ф 8кф. 4кфб4 4кфв 4кфг4 4кфд4 4кфж 4кфз 4кфк4 4кфп4 4кфт4 4кфф 4кфц4 4кфч4 2к3х 8кх. 4кхб4 4кхг4 4кхд4 4кхж 4кхз 4кхк4 4кхп4 4кхт4 4кхх 4кхц4 4кхч4 2к3ц 8кц. 4кцб4 4кцг4 4кцд4 4кцк4 4кцп 4кцт 4кцц 4кцч 2к3ч 8кч. 4кчб4 4кчг4 4кчд4 4кчк4 4кчп 4кчт 4кчц 4кчч 2к3ш 8кш. 4кшб4 4кшг4 4кшд4 4кшж 4кшз 4кшк4 4кшп4 4кшт4 4кшц4 4кшч4 4кшш 2к3щ 8кщ. 4кщб4 4кщг4 4кщд4 4кщк4 4кщщ 4л3б 8лб. 4лбб 4лбк 4лбл4 4лбп 4лбт 4лбц 4лбч 4л3в 8лв. 4лвв 4лвл4 4лвф 4л3г 8лг. 4лгг 4лгк 4лгл4 4лгп 4лгт 4лгц 4лгч 4л3д 8лд. 4лдб 4лдг 4лдд 4лдк 4лдл4 4лдп 4лдт 4лдц 4лдч 4л3ж 8лж. 4лжж 4лжл4 4лжс 4лжф 4лжх 4лжш 4л3з 8лз. 4лзз 4лзл4 4лзс 4лзф 4лзх 4лзш 4л3к 8лк. 4лкб 4лкг 4лкд 4лкк 4лкл4 4л3л4 8лл. ллб4 ллв4 ллг4 ллд4 ллж4 ллз4 ллк4 4ллл4 ллм4 ллн4 ллп4 ллр4 ллс4 ллт4 ллф4 ллх4 ллц4 ллч4 ллш4 ллщ4 4л3м 8лм. 4лмл4 4лмм 4л3н 8лн. 4лнл4 4лнн 4л3п 8лп. 4лпб 4лпг 4лпд 4лпл4 4лпп 2л3р4 8лр. 4лрл4 4лрр 4л3с 8лс. 4лсж 4лсз 4лсл4 4лсс 4л3т 8лт. 4лтб 4лтг 4лтд 4лтк 4лтл4 4лтп 4лтт 4лтц 4лтч 4л3ф 8лф. 4лфв 4лфж 4лфз 4лфл4 4лфф 4л3х 8лх. 4лхж 4лхз 4лхл4 4лхх 4л3ц 8лц. 4лцб 4лцг 4лцд 4лцк 4лцл4 4лцп 4лцт 4лцц 4лцч 4л3ч 8лч. 4лчб 4лчг 4лчд 4лчк 4лчл4 4лчп 4лчт 4лчц 4лчч 4л3ш 8лш. 4лшж 4лшз 4лшл4 4лшш 4л3щ 8лщ. 4лщл4 4лщщ 4м3б 8мб. 4мбб 4мбк 4мбм4 4мбп 4мбт 4мбц 4мбч 4м3в 8мв. 4мвв 4мвм4 4мвф 4м3г 8мг. 4мгг 4мгк 4мгм4 4мгп 4мгт 4мгц 4мгч 4м3д 8мд. 4мдб 4мдг 4мдд 4мдк 4мдм4 4мдп 4мдт 4мдц 4мдч 4м3ж 8мж. 4мжж 4мжм4 4мжс 4мжф 4мжх 4мжш 4м3з 8мз. 4мзз 4мзм4 4мзс 4мзф 4мзх 4мзш 4м3к 8мк. 4мкб 4мкг 4мкд 4мкк 4мкм4 2м3л4 8мл. 4млл 4млм4 4м3м4 8мм. ммб4 ммв4 ммг4 ммд4 ммж4 ммз4 ммк4 ммл4 4ммм4 ммн4 ммп4 ммр4 ммс4 ммт4 ммф4 ммх4 ммц4 ммч4 ммш4 ммщ4 2м3н4 8мн. 4мнм4 4мнн 4м3п 8мп. 4мпб 4мпг 4мпд 4мпм4 4мпп 2м3р4 8мр. 4мрм4 4мрр 4м3с 8мс. 4мсж 4мсз 4мсм4 4мсс 4м3т 8мт. 4мтб 4мтг 4мтд 4мтк 4мтм4 4мтп 4мтт 4мтц 4мтч 4м3ф 8мф. 4мфв 4мфж 4мфз 4мфм4 4мфф 4м3х 8мх. 4мхж 4мхз 4мхм4 4мхх 4м3ц 8мц. 4мцб 4мцг 4мцд 4мцк 4мцм4 4мцп 4мцт 4мцц 4мцч 4м3ч 8мч. 4мчб 4мчг 4мчд 4мчк 4мчм4 4мчп 4мчт 4мчц 4мчч 4м3ш 8мш. 4мшж 4мшз 4мшм4 4мшш 4м3щ 8мщ. 4мщм4 4мщщ на2д3з 4н3б 8нб. 4нбб 4нбк 4нбн4 4нбп 4нбт 4нбц 4нбч 4н3в 8нв. 4нвв 4нвн4 4нвф 4н3г 8нг. 4нгг 4нгк 4нгн4 4нгп 4нгт 4нгц 4нгч 4н3д 8нд. 4ндб 4ндг 4ндд 4ндк 4ндн4 4ндп 4ндт 4ндц 4ндч 4н3ж 8нж. 4нжж 4нжн4 4нжс 4нжф 4нжх 4нжш 4н3з 8нз. 4нзз 4нзн4 4нзс 4нзф 4нзх 4нзш 4н3к 8нк. 4нкб 4нкг 4нкд 4нкк 4нкн4 2н3л4 8нл. 4нлл 4нлн4 4н3м 8нм. 4нмм 4нмн4 4н3н4 8нн. ннб4 ннв4 ннг4 ннд4 ннж4 ннз4 ннк4 ннл4 ннм4 4ннн4 ннп4 ннр4 ннс4 ннт4 ннф4 ннх4 ннц4 ннч4 ннш4 ннщ4 4н3п 8нп. 4нпб 4нпг 4нпд 4нпн4 4нпп 2н3р4 8нр. 4нрн4 4нрр 4н3с 8нс. 4нсж 4нсз 4нсн4 4нсс 4н3т 8нт. 4нтб 4нтг 4нтд 4нтк 4нтн4 4нтп 4нтт 4нтц 4нтч 4н3ф 8нф. 4нфв 4нфж 4нфз 4нфн4 4нфф 4н3х 8нх. 4нхж 4нхз 4нхн4 4нхх 4н3ц 8нц. 4нцб 4нцг 4нцд 4нцк 4нцн4 4нцп 4нцт 4нцц 4нцч 4н3ч 8нч. 4нчб 4нчг 4нчд 4нчк 4нчн4 4нчп 4нчт 4нчц 4нчч 4н3ш 8нш. 4ншж 4ншз 4ншн4 4ншш 4н3щ 8нщ. 4нщн4 4нщщ о1 4п3б4 8пб. 4пбб4 пбв4 4пбг4 4пбд4 пбж4 пбз4 4пбк4 пбл4 пбм4 пбн4 4пбп4 пбр4 пбс4 4пбт4 пбф4 пбх4 4пбц4 4пбч4 пбш4 пбщ4 2п3в4 8пв. 4пвб4 4пвв 4пвг4 4пвд4 4пвк4 4пвп4 4пвт4 4пвф 4пвц4 4пвч4 4п3г4 8пг. 4пгб4 пгв4 4пгг4 4пгд4 пгж4 пгз4 4пгк4 пгл4 пгм4 пгн4 4пгп4 пгр4 пгс4 4пгт4 пгф4 пгх4 4пгц4 4пгч4 пгш4 пгщ4 4п3д4 8пд. 4пдб4 пдв4 4пдг4 4пдд4 пдж4 пдз4 4пдк4 пдл4 пдм4 пдн4 4пдп4 пдр4 пдс4 4пдт4 пдф4 пдх4 4пдц4 4пдч4 пдш4 пдщ4 2п3ж4 8пж. 4пжб4 4пжг4 4пжд4 4пжж 4пжк4 4пжп4 4пжс 4пжт4 4пжф 4пжх 4пжц4 4пжч4 4пжш 2п3з4 8пз. 4пзб4 4пзг4 4пзд4 4пзз 4пзк4 4пзп4 4пзс 4пзт4 4пзф 4пзх 4пзц4 4пзч4 4пзш пй4 2п3к 8пк. 4пкб4 4пкг4 4пкд4 4пкк 4пкп4 2п3л4 8пл. 4плб4 4плг4 4плд4 4плл 4плп4 2п3м4 8пм. 4пмб4 4пмг4 4пмд4 4пмм 4пмп4 2п3н4 8пн. 4пнб4 4пнг4 4пнд4 4пнн 4пнп4 по2д3з 4п3п4 8пп. 4ппб4 ппв4 4ппг4 4ппд4 ппж4 ппз4 ппк4 ппл4 ппм4 ппн4 4ппп4 ппр4 ппс4 ппт4 ппф4 ппх4 ппц4 ппч4 ппш4 ппщ4 2п3р4 8пр. 4прб4 4прг4 4прд4 пре2д2ж пре2д3з 4прп4 4прр 2п3с 8пс. 4псб4 4псг4 4псд4 4псж 4псз 4пск4 4псп4 4псс 4пст4 4псц4 4псч4 2п3т 8пт. 4птб4 4птг4 4птд4 4птк 4птп4 4птт 4птц 4птч 2п3ф 8пф. 4пфб4 4пфв 4пфг4 4пфд4 4пфж 4пфз 4пфк4 4пфп4 4пфт4 4пфф 4пфц4 4пфч4 2п3х 8пх. 4пхб4 4пхг4 4пхд4 4пхж 4пхз 4пхк4 4пхп4 4пхт4 4пхх 4пхц4 4пхч4 2п3ц 8пц. 4пцб4 4пцг4 4пцд4 4пцк 4пцп4 4пцт 4пцц 4пцч 2п3ч 8пч. 4пчб4 4пчг4 4пчд4 4пчк 4пчп4 4пчт 4пчц 4пчч 2п3ш 8пш. 4пшб4 4пшг4 4пшд4 4пшж 4пшз 4пшк4 4пшп4 4пшт4 4пшц4 4пшч4 4пшш 2п3щ 8пщ. 4пщб4 4пщг4 4пщд4 4пщп4 4пщщ 4р3б 8рб. 4рбб 4рбк 4рбп 4рбр4 4рбт 4рбц 4рбч 4р3в 8рв. 4рвв 4рвр4 4рвф 4р3г 8рг. 4ргг 4ргк 4ргп 4ргр4 4ргт 4ргц 4ргч 4р3д 8рд. 4рдб 4рдг 4рдд 4рдк 4рдп 4рдр4 4рдт 4рдц 4рдч 4р3ж 8рж. 4ржж 4ржр4 4ржс 4ржф 4ржх 4ржш 4р3з 8рз. 4рзз 4рзр4 4рзс 4рзф 4рзх 4рзш 4р3к 8рк. 4ркб 4ркг 4ркд 4ркк 4ркр4 4р3л 8рл. 4рлл 4рлр4 4р3м 8рм. 4рмм 4рмр4 4р3н 8рн. 4рнн 4рнр4 4р3п 8рп. 4рпб 4рпг 4рпд 4рпп 4рпр4 4р3р4 8рр. ррб4 ррв4 ррг4 ррд4 ррж4 ррз4 ррк4 ррл4 ррм4 ррн4 ррп4 4ррр4 ррс4 ррт4 ррф4 ррх4 ррц4 ррч4 ррш4 ррщ4 4р3с 8рс. 4рсж 4рсз 4рср4 4рсс 4р3т 8рт. 4ртб 4ртг 4ртд 4ртк 4ртп 4ртр4 4ртт 4ртц 4ртч 4р3ф 8рф. 4рфв 4рфж 4рфз 4рфр4 4рфф 4р3х 8рх. 4рхж 4рхз 4рхр4 4рхх 4р3ц 8рц. 4рцб 4рцг 4рцд 4рцк 4рцп 4рцр4 4рцт 4рцц 4рцч 4р3ч 8рч. 4рчб 4рчг 4рчд 4рчк 4рчп 4рчр4 4рчт 4рчц 4рчч 4р3ш 8рш. 4ршж 4ршз 4ршр4 4ршш 4р3щ 8рщ. 4рщр4 4рщщ 2с3б4 8сб. 4сбб 4сбж4 4сбз4 4сбк 4сбп 4сбс4 4сбт 4сбф4 4сбх4 4сбц 4сбч 4сбш4 2с3в4 8св. 4свв 4свж4 4свз4 4свс4 4свф 2с3г4 8сг. 4сгг 4сгж4 4сгз4 4сгк 4сгп 4сгс4 4сгт 4сгф4 4сгх4 4сгц 4сгч 4сгш4 2с3д4 8сд. 4сдб 4сдг 4сдд 4сдж4 4сдз4 4сдк 4сдп 4сдс4 4сдт 4сдф4 4сдх4 4сдц 4сдч 4сдш4 4с3ж4 8сж. сжб4 сжв4 сжг4 сжд4 4сжж4 4сжз4 сжк4 сжл4 сжм4 сжн4 сжп4 сжр4 4сжс4 сжт4 4сжф4 4сжх4 сжц4 сжч4 4сжш4 сжщ4 4с3з4 8сз. сзб4 сзв4 сзг4 сзд4 4сзж4 4сзз4 сзк4 сзл4 сзм4 сзн4 сзп4 сзр4 4сзс4 сзт4 4сзф4 4сзх4 сзц4 сзч4 4сзш4 сзщ4 сй4 2с3к 8ск. 4скб 4скг 4скд 4скж4 4скз4 4скк 4скс4 4скф4 4скх4 4скш4 2с3л4 8сл. 4слж4 4слз4 4слл 4слс4 2с3м4 8см. 4смж4 4смз4 4смм 4смс4 2с3н4 8сн. 4снж4 4снз4 4снн 4снс4 2с3п 8сп. 4спб 4спг 4спд 4спж4 4спз4 4спп 4спс4 4спф4 4спх4 4спш4 2с3р4 8ср. 4срж4 4срз4 4срр 4срс4 4с3с4 8сс. ссб4 ссв4 ссг4 ссд4 4ссж4 4ссз4 сск4 ссл4 ссм4 ссн4 ссп4 сср4 4ссс4 сст4 ссф4 ссх4 ссц4 ссч4 ссш4 ссщ4 2с3т 8ст. 4стб 4стг 4стд 4стж4 4стз4 4стк 4стп 4стс4 4стт 4стф4 4стх4 4стц 4стч 4стш4 2с3ф 8сф. 4сфв 4сфж4 4сфз4 4сфс4 4сфф 2с3х 8сх. 4схж4 4схз4 4схс4 4схх 2с3ц 8сц. 4сцб 4сцг 4сцд 4сцж4 4сцз4 4сцк 4сцп 4сцс4 4сцт 4сцф4 4сцх4 4сцц 4сцч 4сцш4 2с3ч 8сч. 4счб 4счг 4счд 4счж4 4счз4 4счк 4счп 4счс4 4счт 4счф4 4счх4 4счц 4счч 4счш4 2с3ш 8сш. 4сшж4 4сшз4 4сшс4 4сшш 2с3щ 8сщ. 4сщж4 4сщз4 4сщс4 4сщщ 4т3б4 8тб. 4тбб4 тбв4 4тбг4 4тбд4 тбж4 тбз4 4тбк4 тбл4 тбм4 тбн4 4тбп4 тбр4 тбс4 4тбт4 тбф4 тбх4 4тбц4 4тбч4 тбш4 тбщ4 2т3в4 8тв. 4твб4 4твв 4твг4 4твд4 4твк4 4твп4 4твт4 4твф 4твц4 4твч4 4т3г4 8тг. 4тгб4 тгв4 4тгг4 4тгд4 тгж4 тгз4 4тгк4 тгл4 тгм4 тгн4 4тгп4 тгр4 тгс4 4тгт4 тгф4 тгх4 4тгц4 4тгч4 тгш4 тгщ4 4т3д4 8тд. 4тдб4 тдв4 4тдг4 4тдд4 тдж4 тдз4 4тдк4 тдл4 тдм4 тдн4 4тдп4 тдр4 тдс4 4тдт4 тдф4 тдх4 4тдц4 4тдч4 тдш4 тдщ4 2т3ж4 8тж. 4тжб4 4тжг4 4тжд4 4тжж 4тжк4 4тжп4 4тжс 4тжт4 4тжф 4тжх 4тжц4 4тжч4 4тжш 2т3з4 8тз. 4тзб4 4тзг4 4тзд4 4тзз 4тзк4 4тзп4 4тзс 4тзт4 4тзф 4тзх 4тзц4 4тзч4 4тзш тй4 4т3к4 8тк. 4ткб4 ткв4 4ткг4 4ткд4 ткж4 ткз4 4ткк4 ткл4 ткм4 ткн4 4ткп4 ткр4 ткс4 4ткт4 ткф4 ткх4 4ткц4 4ткч4 ткш4 ткщ4 2т3л4 8тл. 4тлб4 4тлг4 4тлд4 4тлк4 4тлл 4тлп4 4тлт4 4тлц4 4тлч4 2т3м4 8тм. 4тмб4 4тмг4 4тмд4 4тмк4 4тмм 4тмп4 4тмт4 4тмц4 4тмч4 2т3н4 8тн. 4тнб4 4тнг4 4тнд4 4тнк4 4тнн 4тнп4 4тнт4 4тнц4 4тнч4 4т3п4 8тп. 4тпб4 тпв4 4тпг4 4тпд4 тпж4 тпз4 4тпк4 тпл4 тпм4 тпн4 4тпп4 тпр4 тпс4 4тпт4 тпф4 тпх4 4тпц4 4тпч4 тпш4 тпщ4 2т3р4 8тр. 4трб4 4трг4 4трд4 4трк4 4трп4 4трр 4трт4 4трц4 4трч4 2т3с 8тс. 4тсб4 4тсг4 4тсд4 4тсж 4тсз 4тск4 4тсп4 4тсс 4тст4 4тсц4 4тсч4 4т3т4 8тт. 4ттб4 ттв4 4ттг4 4ттд4 ттж4 ттз4 4ттк4 ттл4 ттм4 ттн4 4ттп4 ттр4 ттс4 4ттт4 ттф4 ттх4 4ттц4 4ттч4 ттш4 ттщ4 2т3ф 8тф. 4тфб4 4тфв 4тфг4 4тфд4 4тфж 4тфз 4тфк4 4тфп4 4тфт4 4тфф 4тфц4 4тфч4 2т3х 8тх. 4тхб4 4тхг4 4тхд4 4тхж 4тхз 4тхк4 4тхп4 4тхт4 4тхх 4тхц4 4тхч4 4т3ц4 8тц. 4тцб4 тцв4 4тцг4 4тцд4 тцж4 тцз4 4тцк4 тцл4 тцм4 тцн4 4тцп4 тцр4 тцс4 4тцт4 тцф4 тцх4 4тцц4 4тцч4 тцш4 тцщ4 4т3ч4 8тч. 4тчб4 тчв4 4тчг4 4тчд4 тчж4 тчз4 4тчк4 тчл4 тчм4 тчн4 4тчп4 тчр4 тчс4 4тчт4 тчф4 тчх4 4тчц4 4тчч4 тчш4 тчщ4 2т3ш 8тш. 4тшб4 4тшг4 4тшд4 4тшж 4тшз 4тшк4 4тшп4 4тшт4 4тшц4 4тшч4 4тшш 2т3щ 8тщ. 4тщб4 4тщг4 4тщд4 4тщк4 4тщп4 4тщт4 4тщц4 4тщч4 4тщщ у1 2ф3б4 8фб. 4фбб 4фбв4 4фбж4 4фбз4 4фбк 4фбп 4фбс4 4фбт 4фбф4 4фбх4 4фбц 4фбч 4фбш4 4ф3в4 8фв. фвб4 4фвв4 фвг4 фвд4 4фвж4 4фвз4 фвк4 фвл4 фвм4 фвн4 фвп4 фвр4 фвс4 фвт4 4фвф4 фвх4 фвц4 фвч4 фвш4 фвщ4 2ф3г4 8фг. 4фгв4 4фгг 4фгж4 4фгз4 4фгк 4фгп 4фгс4 4фгт 4фгф4 4фгх4 4фгц 4фгч 4фгш4 2ф3д4 8фд. 4фдб 4фдв4 4фдг 4фдд 4фдж4 4фдз4 4фдк 4фдп 4фдс4 4фдт 4фдф4 4фдх4 4фдц 4фдч 4фдш4 4ф3ж4 8фж. фжб4 4фжв4 фжг4 фжд4 4фжж4 4фжз4 фжк4 фжл4 фжм4 фжн4 фжп4 фжр4 4фжс4 фжт4 4фжф4 4фжх4 фжц4 фжч4 4фжш4 фжщ4 4ф3з4 8фз. фзб4 4фзв4 фзг4 фзд4 4фзж4 4фзз4 фзк4 фзл4 фзм4 фзн4 фзп4 фзр4 4фзс4 фзт4 4фзф4 4фзх4 фзц4 фзч4 4фзш4 фзщ4 фй4 2ф3к 8фк. 4фкб 4фкв4 4фкг 4фкд 4фкж4 4фкз4 4фкк 4фкс4 4фкф4 4фкх4 4фкш4 2ф3л4 8фл. 4флв4 4флж4 4флз4 4флл 4флф4 2ф3м4 8фм. 4фмв4 4фмж4 4фмз4 4фмм 4фмф4 2ф3н4 8фн. 4фнв4 4фнж4 4фнз4 4фнн 4фнф4 2ф3п 8фп. 4фпб 4фпв4 4фпг 4фпд 4фпж4 4фпз4 4фпп 4фпс4 4фпф4 4фпх4 4фпш4 2ф3р4 8фр. 4фрв4 4фрж4 4фрз4 4фрр 4фрф4 2ф3с 8фс. 4фсв4 4фсж4 4фсз4 4фсс 4фсф4 2ф3т 8фт. 4фтб 4фтв4 4фтг 4фтд 4фтж4 4фтз4 4фтк 4фтп 4фтс4 4фтт 4фтф4 4фтх4 4фтц 4фтч 4фтш4 4ф3ф4 8фф. ффб4 4ффв4 ффг4 ффд4 4ффж4 4ффз4 ффк4 ффл4 ффм4 ффн4 ффп4 ффр4 ффс4 ффт4 4ффф4 ффх4 ффц4 ффч4 ффш4 ффщ4 2ф3х 8фх. 4фхв4 4фхж4 4фхз4 4фхф4 4фхх 2ф3ц 8фц. 4фцб 4фцв4 4фцг 4фцд 4фцж4 4фцз4 4фцк 4фцп 4фцс4 4фцт 4фцф4 4фцх4 4фцц 4фцч 4фцш4 2ф3ч 8фч. 4фчб 4фчв4 4фчг 4фчд 4фчж4 4фчз4 4фчк 4фчп 4фчс4 4фчт 4фчф4 4фчх4 4фчц 4фчч 4фчш4 2ф3ш 8фш. 4фшв4 4фшж4 4фшз4 4фшф4 4фшш 2ф3щ 8фщ. 4фщв4 4фщж4 4фщз4 4фщф4 4фщщ 2х3б4 8хб. 4хбб 4хбж4 4хбз4 4хбк 4хбп 4хбс4 4хбт 4хбф4 4хбх4 4хбц 4хбч 4хбш4 2х3в4 8хв. 4хвв 4хвж4 4хвз4 4хвф 4хвх4 2х3г4 8хг. 4хгг 4хгж4 4хгз4 4хгк 4хгп 4хгс4 4хгт 4хгф4 4хгх4 4хгц 4хгч 4хгш4 2х3д4 8хд. 4хдб 4хдг 4хдд 4хдж4 4хдз4 4хдк 4хдп 4хдс4 4хдт 4хдф4 4хдх4 4хдц 4хдч 4хдш4 4х3ж4 8хж. хжб4 хжв4 хжг4 хжд4 4хжж4 4хжз4 хжк4 хжл4 хжм4 хжн4 хжп4 хжр4 4хжс4 хжт4 4хжф4 4хжх4 хжц4 хжч4 4хжш4 хжщ4 4х3з4 8хз. хзб4 хзв4 хзг4 хзд4 4хзж4 4хзз4 хзк4 хзл4 хзм4 хзн4 хзп4 хзр4 4хзс4 хзт4 4хзф4 4хзх4 хзц4 хзч4 4хзш4 хзщ4 хй4 2х3к 8хк. 4хкб 4хкг 4хкд 4хкж4 4хкз4 4хкк 4хкс4 4хкф4 4хкх4 4хкш4 2х3л4 8хл. 4хлж4 4хлз4 4хлл 4хлх4 2х3м4 8хм. 4хмж4 4хмз4 4хмм 4хмх4 2х3н4 8хн. 4хнж4 4хнз4 4хнн 4хнх4 2х3п 8хп. 4хпб 4хпг 4хпд 4хпж4 4хпз4 4хпп 4хпс4 4хпф4 4хпх4 4хпш4 2х3р4 8хр. 4хрж4 4хрз4 4хрр 4хрх4 2х3с 8хс. 4хсж4 4хсз4 4хсс 4хсх4 2х3т 8хт. 4хтб 4хтг 4хтд 4хтж4 4хтз4 4хтк 4хтп 4хтс4 4хтт 4хтф4 4хтх4 4хтц 4хтч 4хтш4 2х3ф 8хф. 4хфв 4хфж4 4хфз4 4хфф 4хфх4 4х3х4 8хх. ххб4 ххв4 ххг4 ххд4 4ххж4 4ххз4 ххк4 ххл4 ххм4 ххн4 ххп4 ххр4 ххс4 ххт4 ххф4 4ххх4 ххц4 ххч4 ххш4 ххщ4 2х3ц 8хц. 4хцб 4хцг 4хцд 4хцж4 4хцз4 4хцк 4хцп 4хцс4 4хцт 4хцф4 4хцх4 4хцц 4хцч 4хцш4 2х3ч 8хч. 4хчб 4хчг 4хчд 4хчж4 4хчз4 4хчк 4хчп 4хчс4 4хчт 4хчф4 4хчх4 4хчц 4хчч 4хчш4 2х3ш 8хш. 4хшж4 4хшз4 4хшх4 4хшш 2х3щ 8хщ. 4хщж4 4хщз4 4хщх4 4хщщ 4ц3б4 8цб. 4цбб4 цбв4 4цбг4 4цбд4 цбж4 цбз4 4цбк4 цбл4 цбм4 цбн4 4цбп4 цбр4 цбс4 4цбт4 цбф4 цбх4 4цбц4 4цбч4 цбш4 цбщ4 2ц3в4 8цв. 4цвб4 4цвв 4цвг4 4цвд4 4цвк4 4цвп4 4цвт4 4цвф 4цвц4 4цвч4 4ц3г4 8цг. 4цгб4 цгв4 4цгг4 4цгд4 цгж4 цгз4 4цгк4 цгл4 цгм4 цгн4 4цгп4 цгр4 цгс4 4цгт4 цгф4 цгх4 4цгц4 4цгч4 цгш4 цгщ4 4ц3д4 8цд. 4цдб4 цдв4 4цдг4 4цдд4 цдж4 цдз4 4цдк4 цдл4 цдм4 цдн4 4цдп4 цдр4 цдс4 4цдт4 цдф4 цдх4 4цдц4 4цдч4 цдш4 цдщ4 2ц3ж4 8цж. 4цжб4 4цжг4 4цжд4 4цжж 4цжк4 4цжп4 4цжс 4цжт4 4цжф 4цжх 4цжц4 4цжч4 4цжш 2ц3з4 8цз. 4цзб4 4цзг4 4цзд4 4цзз 4цзк4 4цзп4 4цзс 4цзт4 4цзф 4цзх 4цзц4 4цзч4 4цзш цй4 4ц3к4 8цк. 4цкб4 цкв4 4цкг4 4цкд4 цкж4 цкз4 4цкк4 цкл4 цкм4 цкн4 4цкп4 цкр4 цкс4 4цкт4 цкф4 цкх4 4цкц4 4цкч4 цкш4 цкщ4 2ц3л4 8цл. 4цлб4 4цлг4 4цлд4 4цлк4 4цлл 4цлп4 4цлт4 4цлц4 4цлч4 2ц3м4 8цм. 4цмб4 4цмг4 4цмд4 4цмк4 4цмм 4цмп4 4цмт4 4цмц4 4цмч4 2ц3н4 8цн. 4цнб4 4цнг4 4цнд4 4цнк4 4цнн 4цнп4 4цнт4 4цнц4 4цнч4 4ц3п4 8цп. 4цпб4 цпв4 4цпг4 4цпд4 цпж4 цпз4 4цпк4 цпл4 цпм4 цпн4 4цпп4 цпр4 цпс4 4цпт4 цпф4 цпх4 4цпц4 4цпч4 цпш4 цпщ4 2ц3р4 8цр. 4црб4 4црг4 4црд4 4црк4 4црп4 4црр 4црт4 4црц4 4црч4 2ц3с 8цс. 4цсб4 4цсг4 4цсд4 4цсж 4цсз 4цск4 4цсп4 4цсс 4цст4 4цсц4 4цсч4 4ц3т4 8цт. 4цтб4 цтв4 4цтг4 4цтд4 цтж4 цтз4 4цтк4 цтл4 цтм4 цтн4 4цтп4 цтр4 цтс4 4цтт4 цтф4 цтх4 4цтц4 4цтч4 цтш4 цтщ4 2ц3ф 8цф. 4цфб4 4цфв 4цфг4 4цфд4 4цфж 4цфз 4цфк4 4цфп4 4цфт4 4цфф 4цфц4 4цфч4 2ц3х 8цх. 4цхб4 4цхг4 4цхд4 4цхж 4цхз 4цхк4 4цхп4 4цхт4 4цхх 4цхц4 4цхч4 4ц3ц4 8цц. 4ццб4 ццв4 4ццг4 4ццд4 ццж4 ццз4 4ццк4 ццл4 ццм4 ццн4 4ццп4 ццр4 ццс4 4ццт4 ццф4 ццх4 4ццц4 4ццч4 ццш4 ццщ4 4ц3ч4 8цч. 4цчб4 цчв4 4цчг4 4цчд4 цчж4 цчз4 4цчк4 цчл4 цчм4 цчн4 4цчп4 цчр4 цчс4 4цчт4 цчф4 цчх4 4цчц4 4цчч4 цчш4 цчщ4 2ц3ш 8цш. 4цшб4 4цшг4 4цшд4 4цшж 4цшз 4цшк4 4цшп4 4цшт4 4цшц4 4цшч4 4цшш 2ц3щ 8цщ. 4цщб4 4цщг4 4цщд4 4цщк4 4цщп4 4цщт4 4цщц4 4цщч4 4цщщ 4ч3б4 8чб. 4чбб4 чбв4 4чбг4 4чбд4 чбж4 чбз4 4чбк4 чбл4 чбм4 чбн4 4чбп4 чбр4 чбс4 4чбт4 чбф4 чбх4 4чбц4 4чбч4 чбш4 чбщ4 2ч3в4 8чв. 4чвб4 4чвв 4чвг4 4чвд4 4чвк4 4чвп4 4чвт4 4чвф 4чвц4 4чвч4 4ч3г4 8чг. 4чгб4 чгв4 4чгг4 4чгд4 чгж4 чгз4 4чгк4 чгл4 чгм4 чгн4 4чгп4 чгр4 чгс4 4чгт4 чгф4 чгх4 4чгц4 4чгч4 чгш4 чгщ4 4ч3д4 8чд. 4чдб4 чдв4 4чдг4 4чдд4 чдж4 чдз4 4чдк4 чдл4 чдм4 чдн4 4чдп4 чдр4 чдс4 4чдт4 чдф4 чдх4 4чдц4 4чдч4 чдш4 чдщ4 2ч3ж4 8чж. 4чжб4 4чжг4 4чжд4 4чжж 4чжк4 4чжп4 4чжс 4чжт4 4чжф 4чжх 4чжц4 4чжч4 4чжш 2ч3з4 8чз. 4чзб4 4чзг4 4чзд4 4чзз 4чзк4 4чзп4 4чзс 4чзт4 4чзф 4чзх 4чзц4 4чзч4 4чзш чй4 4ч3к4 8чк. 4чкб4 чкв4 4чкг4 4чкд4 чкж4 чкз4 4чкк4 чкл4 чкм4 чкн4 4чкп4 чкр4 чкс4 4чкт4 чкф4 чкх4 4чкц4 4чкч4 чкш4 чкщ4 2ч3л4 8чл. 4члб4 4члг4 4члд4 4члк4 4члл 4члп4 4члт4 4члц4 4члч4 2ч3м4 8чм. 4чмб4 4чмг4 4чмд4 4чмк4 4чмм 4чмп4 4чмт4 4чмц4 4чмч4 2ч3н4 8чн. 4чнб4 4чнг4 4чнд4 4чнк4 4чнн 4чнп4 4чнт4 4чнц4 4чнч4 4ч3п4 8чп. 4чпб4 чпв4 4чпг4 4чпд4 чпж4 чпз4 4чпк4 чпл4 чпм4 чпн4 4чпп4 чпр4 чпс4 4чпт4 чпф4 чпх4 4чпц4 4чпч4 чпш4 чпщ4 2ч3р4 8чр. 4чрб4 4чрг4 4чрд4 4чрк4 4чрп4 4чрр 4чрт4 4чрц4 4чрч4 2ч3с 8чс. 4чсб4 4чсг4 4чсд4 4чсж 4чсз 4чск4 4чсп4 4чсс 4чст4 4чсц4 4чсч4 4ч3т4 8чт. 4чтб4 чтв4 4чтг4 4чтд4 чтж4 чтз4 4чтк4 чтл4 чтм4 чтн4 4чтп4 чтр4 чтс4 4чтт4 чтф4 чтх4 4чтц4 4чтч4 чтш4 чтщ4 2ч3ф 8чф. 4чфб4 4чфв 4чфг4 4чфд4 4чфж 4чфз 4чфк4 4чфп4 4чфт4 4чфф 4чфц4 4чфч4 2ч3х 8чх. 4чхб4 4чхг4 4чхд4 4чхж 4чхз 4чхк4 4чхп4 4чхт4 4чхх 4чхц4 4чхч4 4ч3ц4 8чц. 4чцб4 чцв4 4чцг4 4чцд4 чцж4 чцз4 4чцк4 чцл4 чцм4 чцн4 4чцп4 чцр4 чцс4 4чцт4 чцф4 чцх4 4чцц4 4чцч4 чцш4 чцщ4 4ч3ч4 8чч. 4ччб4 ччв4 4ччг4 4ччд4 ччж4 ччз4 4ччк4 ччл4 ччм4 ччн4 4ччп4 ччр4 ччс4 4ччт4 ччф4 ччх4 4ччц4 4ччч4 ччш4 ччщ4 2ч3ш 8чш. 4чшб4 4чшг4 4чшд4 4чшж 4чшз 4чшк4 4чшп4 4чшт4 4чшц4 4чшч4 4чшш 2ч3щ 8чщ. 4чщб4 4чщг4 4чщд4 4чщк4 4чщп4 4чщт4 4чщц4 4чщч4 4чщщ 2ш3б4 8шб. 4шбб 4шбж4 4шбз4 4шбк 4шбп 4шбс4 4шбт 4шбф4 4шбх4 4шбц 4шбч 4шбш4 2ш3в4 8шв. 4швв 4швж4 4швз4 4швф 4швш4 2ш3г4 8шг. 4шгг 4шгж4 4шгз4 4шгк 4шгп 4шгс4 4шгт 4шгф4 4шгх4 4шгц 4шгч 4шгш4 2ш3д4 8шд. 4шдб 4шдг 4шдд 4шдж4 4шдз4 4шдк 4шдп 4шдс4 4шдт 4шдф4 4шдх4 4шдц 4шдч 4шдш4 4ш3ж4 8шж. шжб4 шжв4 шжг4 шжд4 4шжж4 4шжз4 шжк4 шжл4 шжм4 шжн4 шжп4 шжр4 4шжс4 шжт4 4шжф4 4шжх4 шжц4 шжч4 4шжш4 шжщ4 4ш3з4 8шз. шзб4 шзв4 шзг4 шзд4 4шзж4 4шзз4 шзк4 шзл4 шзм4 шзн4 шзп4 шзр4 4шзс4 шзт4 4шзф4 4шзх4 шзц4 шзч4 4шзш4 шзщ4 шй4 2ш3к 8шк. 4шкб 4шкг 4шкд 4шкж4 4шкз4 4шкк 4шкс4 4шкф4 4шкх4 4шкш4 2ш3л4 8шл. 4шлж4 4шлз4 4шлл 4шлш4 2ш3м4 8шм. 4шмж4 4шмз4 4шмм 4шмш4 2ш3н4 8шн. 4шнж4 4шнз4 4шнн 4шнш4 2ш3п 8шп. 4шпб 4шпг 4шпд 4шпж4 4шпз4 4шпп 4шпс4 4шпф4 4шпх4 4шпш4 2ш3р4 8шр. 4шрж4 4шрз4 4шрр 4шрш4 2ш3с 8шс. 4шсж4 4шсз4 4шсс 4шсш4 2ш3т 8шт. 4штб 4штг 4штд 4штж4 4штз4 4штк 4штп 4штс4 4штт 4штф4 4штх4 4штц 4штч 4штш4 2ш3ф 8шф. 4шфв 4шфж4 4шфз4 4шфф 4шфш4 2ш3х 8шх. 4шхж4 4шхз4 4шхх 4шхш4 2ш3ц 8шц. 4шцб 4шцг 4шцд 4шцж4 4шцз4 4шцк 4шцп 4шцс4 4шцт 4шцф4 4шцх4 4шцц 4шцч 4шцш4 2ш3ч 8шч. 4шчб 4шчг 4шчд 4шчж4 4шчз4 4шчк 4шчп 4шчс4 4шчт 4шчф4 4шчх4 4шчц 4шчч 4шчш4 4ш3ш4 8шш. шшб4 шшв4 шшг4 шшд4 4шшж4 4шшз4 шшк4 шшл4 шшм4 шшн4 шшп4 шшр4 шшс4 шшт4 шшф4 шшх4 шшц4 шшч4 4шшш4 шшщ4 2ш3щ 8шщ. 4шщж4 4шщз4 4шщш4 4шщщ 2щ3б4 8щб. 4щбб 4щбк 4щбп 4щбт 4щбц 4щбч 4щбщ4 2щ3в4 8щв. 4щвв 4щвф 4щвщ4 2щ3г4 8щг. 4щгг 4щгк 4щгп 4щгт 4щгц 4щгч 4щгщ4 2щ3д4 8щд. 4щдб 4щдг 4щдд 4щдк 4щдп 4щдт 4щдц 4щдч 4щдщ4 2щ3ж4 8щж. 4щжж 4щжс 4щжф 4щжх 4щжш 4щжщ4 2щ3з4 8щз. 4щзз 4щзс 4щзф 4щзх 4щзш 4щзщ4 щй4 2щ3к 8щк. 4щкб 4щкг 4щкд 4щкк 4щкщ4 2щ3л4 8щл. 4щлл 4щлщ4 2щ3м4 8щм. 4щмм 4щмщ4 2щ3н4 8щн. 4щнн 4щнщ4 2щ3п 8щп. 4щпб 4щпг 4щпд 4щпп 4щпщ4 2щ3р4 8щр. 4щрр 4щрщ4 2щ3с 8щс. 4щсж 4щсз 4щсс 4щсщ4 2щ3т 8щт. 4щтб 4щтг 4щтд 4щтк 4щтп 4щтт 4щтц 4щтч 4щтщ4 2щ3ф 8щф. 4щфв 4щфж 4щфз 4щфф 4щфщ4 2щ3х 8щх. 4щхж 4щхз 4щхх 4щхщ4 2щ3ц 8щц. 4щцб 4щцг 4щцд 4щцк 4щцп 4щцт 4щцц 4щцч 4щцщ4 2щ3ч 8щч. 4щчб 4щчг 4щчд 4щчк 4щчп 4щчт 4щчц 4щчч 4щчщ4 2щ3ш 8щш. 4щшж 4щшз 4щшш 4щшщ4 4щ3щ4 8щщ. щщб4 щщв4 щщг4 щщд4 щщж4 щщз4 щщк4 щщл4 щщм4 щщн4 щщп4 щщр4 щщс4 щщт4 щщф4 щщх4 щщц4 щщч4 щщш4 4щщщ4 ъ1 ю1 я1", ["lefthyphenmin"]=1, - ["length"]=12830, - ["n"]=1660, + ["length"]=61486, + ["n"]=6886, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/patterns/mkiv/lang-de.lua b/tex/context/patterns/mkiv/lang-de.lua index 96db70082..6cba95f53 100644 --- a/tex/context/patterns/mkiv/lang-de.lua +++ b/tex/context/patterns/mkiv/lang-de.lua @@ -6,24 +6,65 @@ return { ["metadata"]={ ["mnemonic"]="de", ["source"]="hyph-de-1996", - ["texcomment"]="% dehyphn-x-2014-05-21.pat\ -% \ -% \\message{German Hyphenation Patterns (Reformed Orthography, 2006) `dehyphn-x' 2014-05-21 (WL)}\ -% \ -% TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung\ + ["texcomment"]="% title: German Hyphenation Patterns (Reformed Orthography, 2006)\ +%\ +% notice: TeX-Trennmuster für die reformierte (2006) deutsche Rechtschreibung\ +%\ +% version: 2018-03-31\ +%\ +% authors:\ +% -\ +% name: Deutschsprachige Trennmustermannschaft\ +% contact: trennmuster@dante.de\ %\ +% copyright: Copyright (c) 2013-2018\ +% Stephan Hennig, Werner Lemberg, Günter Milde,\ +% Sander van Geloven, Georg Pfeiffer, Gisbert W. Selke,\ +% Tobias Wendorf\ %\ -% Copyright (C) 2007, 2008, 2009, 2011, 2012, 2013, 2014 Werner Lemberg \ +% licence:\ +% name: MIT\ +% url: http://opensource.org/licenses/mit-license.php\ +% text: >\ +% Permission is hereby granted, free of charge, to any person\ +% obtaining a copy of this software and associated documentation\ +% files (the “Software”), to deal in the Software without\ +% restriction, including without limitation the rights to use,\ +% copy, modify, merge, publish, distribute, sublicense, and/or\ +% sell copies of the Software, and to permit persons to whom the\ +% Software is furnished to do so, subject to the following\ +% conditions:\ %\ -% This program can be redistributed and/or modified under the terms\ -% of the LaTeX Project Public License Distributed from CTAN\ -% archives in directory macros/latex/base/lppl.txt; either\ -% version 1 of the License, or any later version.\ +% The above copyright notice and this permission notice shall be\ +% included in all copies or substantial portions of the Software.\ %\ +% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,\ +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\ +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\ +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\ +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\ +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\ +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\ +% OTHER DEALINGS IN THE SOFTWARE.\ %\ -% The word list is available from\ +% source: http://repo.or.cz/w/wortliste.git?a=commit;h=8b9a428c271e064f0047a364c532308f0fd4051f\ %\ -% http://repo.or.cz/w/wortliste.git?a=commit;h=3a97953c0ddd099a1785ea7927cbf24e639090b0\ +% language:\ +% name: German, reformed spelling\ +% tag: de-1996\ +%\ +% hyphenmins:\ +% generation:\ +% left: 2\ +% right: 2\ +% typesetting:\ +% left: 2\ +% right: 2\ +%\ +% ===========================================================================\ +% \ +% \\message{German Hyphenation Patterns (Reformed Orthography, 2006) `dehyphn-x' 2018-03-31 (WL)}\ +% \ %\ % The used patgen parameters are\ %\ @@ -40,10 +81,10 @@ return { }, ["patterns"]={ ["characters"]="abcdefghijklmnopqrstuvwxyzßàáâäçèéêëíñóôöü", - ["data"]=".ab1a .abi4 .ab3l .abo2 .ab3ol .ab1or .ack2 .ag4n .ag4r .ag2u .ai2s .akt2a .al2e .al3k .al5l4en .al4tei .alt3s .ampe4 .amt2s .amt4sc .an3d2 .anden6k .and4ri .ang2 .an3gli .angs4 .angst3 .an3s2 .an4si. .an4tag .an3th .an3z2 .apo1 .ap5p6le. .aps2 .ari1e .ark2a .ar4m3ac .ar2sc .ar4t3ei .arter4 .ar6t5erh .as3t .as4ta .at4h .au3d .au4f3 .au4s3 .ausch3 .ax4 .äm3 .är6schl .ät2s .be3erb .be3r2a .be3r2e .berg3a .ber6gab .ber6g5e6b .ber4gl .ber4g3r .boge2 .bo4s3k .bu4ser .by4t .ch2 .chi3er .dab4 .da2r1 .da4rin .dar2m1 .da4te. .da4tes .de2al .de1i .de4in. .de8ments .de1o2 .de3r4en .de1s .des2e .de3sk .des2t .dien4e .do2mo .do1pe .dorf1 .dü1b .dys1 .ebe2r1 .ehe1i .ei4ds .ei3e2 .ei4na .einen6g .ei2sp .ei4st .ei4tr .eke2 .el2a .el2bi .elb3s .em3m2 .en1 .en4d3er .en5der. .en2d3r .end3s .en2gl .enn2 .enns3 .en2t3 .en4tei .en4tr .er8brecht .erb3s .er2bu .er2da .er4dan .er4dar .er4dei .erden6k .er4der .er1e .ere3c .erf4 .er1i .er8stein .erster6 .er8stritt. .er8stritten. .er4zen4 .esel4s .es3p .es3ta .es5t4e .est2h .es3to .es5tr .et2s .eu1 .eu3g4 .eu3t .eve4r .ext4 .fe4i .fer4no .fi3est .fi4le. .fi4len .fi2s .flug1 .for2t .fs4 .fu2sc .ga4t .gd2 .geb2l .gel2d1 .ge5nar .ge3n2e .gene7cke .ge3r2a .ge3r2e .ge3u .gs4 .guss1 .hau2t1 .he2 .he3fe .her3an .he3ri .he6r5inn .hi4n .hin3u .hi2s .ho4met .ia4 .im2a .ima4ge .im5m2 .in1 .in3e .in3gl .ink4 .inn2e .inu1 .ioni1 .ire3 .is2a .ka2b5l .ka2i .kamp2 .ka4t3io .ki4e .kle4i .kopf1 .ks2 .kus2 .le4ar .lich8t7er8s .li2f .li4tu .li4ve. .lo4g3in .lo3ver .lus4tr .ma3d .ma3la .mal4e .ma2st .md2 .mel2a .me3no .men8schl .men8schw .men3t4 .mi4t1 .mm2 .näs1c .ne4s .ni4e .nob4 .no4th .nus2 .oa3 .ob1a .obe2 .oper4 .or2a .ort2 .orts3e .os5t6alg .oste2 .ost5end .os8ten8de .oste6re .ost3r .ozo4 .öd2 .pa4r1e .par3t4h .pe2c .pes4te .pf4 .ph2 .poka2 .pro1 .ps2 .rabe4 .ra3me .ram3s .reb3s2 .re3cha .rein4t .reli1 .reli3e .res6tr .ri2as .rich5te .ro4a .ro3m2a .rö2s1 .runder6 .rü1b .rü6cker6 .sali3e .sami3 .sch4 .se3ck .sen3s .ser2u .se2t1 .sha2 .si4te .ski1e .spiege8lei .st6 .sto4re .sucher6 .tage4s .tan4k3l .ta2to .te2e .te2f .te3no .te2s .te4st .th4 .ti2a .tid1 .ti2e .ti4me. .ti4mes .ti2s .ti5ta .to4nin .to4pl .to2w .tri3es .tro2s .ts2 .tu3ri .uf2e2 .ufer1 .um3 .umo2 .un3a2 .un3d .une2 .un3g .uni4t .un3s .uns4t .ur1 .ur2i .urin4s .ur3o2m .uro2p .ur3s2 .ut2a .ut3r .übe4 .ve5n2e .vi2e .vo4r .wah4l .wa2s .wei4ta .welter8e .welter8k .wi4e .wor2 .wort5en6 .wor8tend .wor4tu .xe3 .ya4l .za2s .zi2e .zin4st .zwe2 a1ab aa2be aa1c aa2gr 2a1a2n 2a2ar aa2r1a aar3f4 aar3k4 aar5sc aas5t aata2 aa2th aa2t3r aat4s3 2a3au a1ä a1b 2aba ab4am ab1auf ab1ä ab2äu 1abd ab1eb abe1e abei1 ab1eil 4abel abe2la2 a3ber ab1er2k ab1er2r ab1er2z ab3esse 2abet 2abew 1abf 3abfi 1abg 1abh 2abi ab1ins ab1ir ab1it 1abk ab1l 1a2bla 1a2blä 2able ab4le. ab3li ab4lo 3a2blö a2blu 1abn a2bo. ab2of 1a2bon 2a3bor ab3r a3bra a4brä 2abrü 1abs 2abs. abs2a 2absar ab3s2i ab3s2p abst2 2abst. ab3ste ab3sz 1abtei 2a3bu ab1ur 2abü 1abw 2aby aby4t 1abz 2aca 2ac1c a1cem 2ach. ach1a a1chal ach3au 2achb 2a1che a2ch1e2c ach1ei a4cherf a4cherk a4cherö a4ch3erw a1chi ach3l ach3m ach3n a1cho a3cho. ach1o2b ach1or ach3ö ach3r ach3s2i ach3su a4cht acht7ersc ach2t1o ach8traum ach8träume. ach8träumen. ach6trit a1chu ach1u2f ach3ü 2achv 2ach1w a1ci ac1in 2ack. a1ckar a2ckin ack2se ack3sl ack3sta4 a1cl acon4n 2acu a1ç a1d 2ada. a3d2ab ad2ag ada2m ad3ama a2d1an 3a4dap a3d2ar3 4adav 1a2dä ad1c 1add 2ade. ade2al adefi4 a2dein 2aden ade1r2a a2deri 4ade1s ade3s2p ades4s ade5str 2adf 2adh 4a3di adi3en 5adj 2ado ad2ob 2adp 2adq 2ad3rec ad4res 2ads2 ad3st ad3sz ad2t1 adta2 ad4te ad4tr 2adu 2a1e ae2b ae2c a3e2d a3ei a2ek a3el. a2ela a2ele a2eli a3els ae2o3 a3e2p ae1r 3a2er2o1 ae2s ae4sc aes5t a2et a2ew ae2x af1a a2fak a2fan a3far af4at a2fau 2afe a2f1ec a2fent af1erl a2fex af2fei af2f3l af4flu 2afi 2af3l afo1s a2fö af3ra af3rä af3re af3rö af3s2a af2sp 2aft af2t1a af2tei af4t3erl af2t1o af2t3r af4t5re af2tur a2f3ur a1g 2aga ag1a2b ag1a2d ag1ar ag1au ag2di ag2du 2age. age1i age4na age4neb a2gent a4gentu ag2er age4ral 2ages age2sa age4sel age4si age2s3p ag3esse age4s3ti ag3gl 3aggr 3a2git 2a2gl ag6la a4glö ag2n a2gna ag4ne. ag4nu a2g3re a2g3ri ag4ro agsa2 ag3s2ah ag4sam ag4set ags3p ag4spo ag3sta ag3ste 2agt ag2th a2gund 2ah. 2a1ha ah4at 2a1he ahe1in a2h1erh ahe1s a1h2i ahin3 ahl3a2 ah4l1ei ah4l3erh ah2lö ahl3sz ah4n1a ahner4e ahnt2 1ahor ah1os a2h3ö ahr1a ah3re ahre4s3 ah3ri ahrta4 ahr6tri ah2ta aht3h ah4t5r aht3s a1hu ah1w a1hy ai3a aian3 aid2s ai1e2 aien3 aif4 ai1fr ai3g4 a3ik. ai3ke aik4r a2il ai2lo aim2o ain2a a1ind ain4e a1ing ain3sp 2ais ai2sa a3isch. ai3s2e ait4 a3iv. a3ivl a3ivs a1j aje2 ajekt4o 2ak. 1a2k4ad 2akal 2a3kam 2akar ak4at 1a2kaz 2akb 2akc 2akd 2a1ke a2kef aken2n a2keu 2a1ki 2ak3l ak4li 4ako 2a1kr 4akra ak3rau 3akro 2aks ak3sh 2akta ak5tan 2aktb 2aktik ak2t3r ak5t4ri 2aktsi 2aktst 2a1ku a2kun 4a3kü 1akz a1la 2ala. al1ab al3abs ala3ch2 al1af ala2g al1age a3lal al1am al3ame alami5 al3amp al1ana a2l1ang al1ans al1anz a2lar a3lar. a3lare al2arm al3arr ala4s al1asi al1ass 2alat al1au al3aug a1lä al1äm alb3ein al4berh al4b3er4w al2b1l alb3li al2boh al2br alb3ru alb3s al2dä al2dr alds2t 2ale ale4a 3a2l1e2b 3a4l1ef a4l1eh a2l1ei a4lein a2l1el alen1 al3ends a2leng a3lentf ale2p al1epo al1erf a2l1erh al3erl 3alerm a2l1ert 3alerz a2l1esk ale4t al1eta al1eth a2l1eu a4leur 3a2lex alf4r 3algi al2gli 2ali ali4ene ali4nal al1ins a2linv alk1ar al2kne 1alkoh alk3s2 alks4t al2l1a2b al2l3a4r al2l1au al3lend all5erfa al3les 1allgä alli5er. alli7ers. al2lob al4m3ast 3almb 2alo a2l1o2b 3a2loe alo2ga al1orc a2l1ö al3öf al2ös 3alpe. 1alph al3skl al5s6terb al3sun al4tak al3tam al3tar alt3eig al4t3er3f al3ti alt1op al4tö al2tri alt3ric al2tro alt2se alt4stü a1lu al2uf a2lum al1umb al1ur 4aly alzer4z al2zw 2am. 2am2a amab4 amad2 ama3g 2amä 2am4e 4ame. a2meb ame2n1 amer2a am5erf a2meri ame3ru a4mesh a3met a2mew 2amf 2amir ami3ta ami3ti 2amk 2aml 4amm. 2ammal am2mar am2mei am2min 2amml 2ammt ammu2 amni1 a2mö amp2fa2 am3pr 2am2s am3sa am4schl am3str 1amt. am2t1a am2t1ä am4tel 2amtem am4t3ern am4tö am2t3r am4tre am2tu 2amu 2ana. 2anab ana3c anadi3 a3nak an1alg ana4lin 2anam 2anan 2ana1s4 an1ath an4atm an1äs 1anb 2anbu an3ch 2and. 3an3d2ac an4d3ei ande2s an2dex an4drau an2d3rü and4sas and6spas and3ste and2su 2andu and1ur 2ane an3e2c a3nee an2ei. an3eif an1e4k 3a4n1erb an1eth 1anf 2anfi an3f2u 4ang. an2g1ar 3angeb an2g1ei an4g3erf an4g3erl an4gerw an4g3erz 2angf 2angh 2angie ang1l an2gla 2ango ang1r an4g3ra 4angs. ang4s3po 1anh 2a3ni an2i3d ani3els ani5ers. 3a4nim a4nins 2anj 2ank. an2k1an 3ankä an2kei an3kl an4klö an2klu an2k3no ank1r ank3ra ank3rä ankt4 1anl 1anmu 2ann 3an3na ann2ab 3annä an3n2e ann4sto an1od a3nol a2n1or a3nos 2a1nö 2anpr 1anr 1an3s2ä 1ansc ans2en an2seu 2ansk an3skr an3s1pa 1anspr an3s2z 2ant. an2t3a4r 1antá 1antei 3antenn an3t4he 1anthr an3ti 2anto 1antr ant3rin an2tro 1antw 2a1nu anu1s a1nü 1anw 2anwet 2anzb 1anzei anze2n 2anzg an2z1i4n 2anzs 1anzü 2anzw an2zwa an2zwi 2ao ao1i a1op a1or a1os3 ao3t2 a3ot. a1ö a1p 2ap. 2apa 2ape a2pef a3pel a2pé a2pf a3p2fa a3pfl a3phä a2ph3t 2ap3l ap2n a2pot ap2pf 3appl ap3pu 2apr 3apri 2a3pu 2aq 2ar. a1ra a3ra. ar2ab ar3abt ara3d2 a2r3al a3rali 2aran a2r1ang a2r1ans a2r1anz a2r3app 2a2rar a2r1au a1rä 1arb 2arb. 4arba ar2bau ar2bec 2arbek 2arben 4arbi ar2bl 2arbr ar2bre 2arbs2 2arbt 2arbu ar2b3un 1ar1c ar2dro 2are a2rea ar1eff a4reg ar1ehr a2rein a4rek 4arem a3ren 4aren. are3r2a ar2erf a2r1erh a2reri are3u ar2ew 2arf ar2fä arf1r ar2f3ra ar2gl ar2gn ar3g4r 2arh 2ari ar2ia ari3e4n ari3erd ari3erg ar1im arin3it arin5s4 ar1int a3riu ar2kal ark3amt ar2k1ar ark3aue ar2k3l ar4klag ar2kor ar4k3ri ark3sa ark3she ark4tre ar2les 2arma ar3m2ä ar3m2or ar2nan arn2e 2a1ro ar1ob a2r1o2d a2r1of a2r1op a2ror 2arp 2arr ar2r3ad ar3re arre4n ar2rh arr3he 2arsa ar4schl arse3 ar3s2h 2arsi ar2st ar3sta ar3t2e ar2the ar3ti artin2 2arto ar4t3ram art3re 2arts 2artuc 2aru ar1uh ar1um a2rü 2arv arwa2 2ary ar2zä 2arze 1arzt ar2z1w as1ala as3au a2s1ä a2sca a4schec a3schi asch1l a2schm a3schu 4as2e a2seb a2s3e2m a3s4es 2asg 4ash a3s2hi asin2g 4asis aska3s a3skop a2s1o2f as1or a2sö a2s1p aspek6to as2ph as2pi as2po a3spu as3s2a as3s2e as4s3ei as3s2i as2s1p as2st ass3ti as3str as3stu 2as3ta a1s4tas as4tau as3te as2th as3ti as3to as4tof 2astr as4trau ast3räu as6t3re asu2s a2sü aswa2s 3a2syl a1ß aße2 aßen3 2a1t ata1 at1ab at2af at4ag a2t1akt ata3l a3tam at1apf at1au a2taus a2tä at1än at2c a2teb a3te1c ateien4 at1eig a2teli at2en a2tep ater3s2 ate2ru at2h at3ha athe1 3athl a4thr 4a3ti atil4s ati2st 3atm 4atmus ato4man 4ator a2t1ort at1ö 4atr atra4t at3rä at3re at3rom at3rü at2sa at4schn at2se at4set at2si at2so at2s1p at3ta 3attac at4tak att3ang at4tau at2tä at2tei at3t4hä at2t3rä att3s a3tub atu2n a3tü atz1er at4zerk at4zerw at2z1in at2zo atz3t2 at2z1w a2u 2au. 2au1a2 2aub au2bab aube4n au2bli au2blo 4auc auch3ta au2dr 2aue aue2b au5erein auer3ö aue2s au2fa auf1an 2aufe. 2aufeh auf1er au4ferk auff4 3aufn auft2 2auft. 2aug 4augeh 4au1i au2is 2auj aule2s au3lü 4aum au2mal aum2ei au2m1e4r1 aum3eri au2m1o aum3p2 aum3s6 4aun au3n2a aun2e au4nei au2nio au1nu a4unz au1o 2aup2 aup4ter 2au3r2 au2s1ah ausan8ne. au2sau 4ausc au4schm 1ausd 2ausen aus3erp au4s3erw 3ausf 1ausg 1ausl au2so au2spr 1ausr 3aussag auss2e aus4se. auss2t 2auste aust2o aus5tri 1ausü 1ausz 2aut. au2t1äu 2aute au4ten4g au4t3erh 1auto au4trö 2auts 2auu 2auw 2aux 2auz auz2w 2a1ü 2a1v a3v4a ava3t4 a2vr 2a1w awi3e a1x ax4am ax2e 2a1ya a1yeu ays4 aysi1 ay3t 2a1z a3z2a aza3d az2i az2o az2u ä1a äand4 ä1b ä2b3l äb2s ä1che äche1e ä1chi äch3l ä2chr äch2sp äch4st ä1chu ä1ck ä3ck2e ä1d ä2da ä2d1ia ä2dr äd2s 2ä1e äf2e äfe4n äf2f3l äf3l äf3r äf4ro äf2s äft4s3 ä1g äge1i äge2ra äge3s ä2g3l äg2n ä2g3r äg4ra äg3str 1ä2gy äh1a 2ä3he ä3hi ähl1a äh3l2e äh4l3e4be 2ähm äh3na äh3ne 1ähnl 2ähr äh3ri 2ähs 2äh3t ä1hu äh1w 2äi ä1im ä1is. ä3isch. ä1isk ä1j ä1k ä2k3l ä2k3r ä1la älbe2 äl2bl 2äle äl2l1a äl2p3 äl4schl äl2st ä1lu ämi3en 2äml ämoni3e 2ämp äm2s ämt2e 2än. än5de än2dr 2äne äne2n1 äne1s än2f5 änft2 2änge 2än2g3l än2gr äng3se 2ä3ni änk2e än2k3l än2kr änk2s änn4e2 äno3 2äns än2s1c äns2e änse3h 2änz ä1on ä1pa äp2pl äp2pr äp2s1c äp4st 1äq ä2r3a2 är4af är1ä är2b3le är1c 4äre ä2r1ei äre2n ä2r1ene är2gr är1int är2k3l ärk2s är4ment ärm2s är1o2 ä1rö ärse2 är4si är2st ärt4e är2th ärt2s3 ä2rü är2zw ä5s4e äse3g2 äser4ei äse4ren äser2i äse3t äskop2 äskopf3 ä3s2kr ä2s1p äs6s1c äss2e äs4s3erk äs2s3t ä4s3t2 äs4tr ä3su ä1ß äß1erk ä2t1a2 ä3te äte1i ätein2 äte2n ät2h ät1ob ä2t3r ät2sa ät2sä ät4schl ät4schr ät2s1i äts3l ät2s1p ät2s3t ät2tei ät4tr ät2zw äu2b3l äu2br äu1c äude3 äu3el ä2uf äuf2e 1äug äug3l 4äul 2äum äu2ma äum4s5 2ä2un äun2e äu1nu 2äu3r 2ä3us. äu4schm äu3se ä3usg ä3usk ä3usn äu2sp äus2s1c 1äuß äu2tr 4ä1v 1äx ä1z â1t á1n ba2bl 2babs bach5t4e backs4 b1a2dr 2b1af 3bah bah2nu bahr2e bais2 ba2ka ba2k1er ba2k1i bak1l bak1r ba2kra 3bal bal2a bal4l3eh bal6lerg 2b3am ba2me ban2a 3b2and ban2dr ba3n2e b1ang ban3gl ban2k1a ban4kl ban2kr 2banl 2b1ans ban3t b1anz bar3b bar3de ba2rei bar2en bar3ins bar3n bar3zw 3bas ba3s2a ba2sc ba2st ba4t3ent bauer4l bauer4s bau3g bau1s bau3s2k bau3sp baus4t ba1yo 3b2ä1c b2är b2äs 4b1b b3be bben3 bbens2 bbe4p bb3ler bb2lö b3bru bbru2c bb2s bbu1 2b1c 2b3d4 bde1s 1be. 3bea be3an be3ar 3beb b2ebe 1be1c be2del bedi4 be1eh be1erl be1eta 3bef4 be3g2 2b1eier bei1f4 bei4ge. beik4 beil2 bei3la 2b1eime b2ein be1ind be1in2h bei3sc beis2e bei1s4t beit2s 3bek 3bel be3las bel3d be3lec be3lei be2l1en be2let be3li bel3la be2l3ö bel3sz bel3t4 1bem 1ben. ben3ar be4nas be4nä ben3dor be3nei 3beng be3n2i ben3n ben2se ben4spa ben4spr benst4 ben2su 2bentb b2enti ben5t4r b1ents 2bentw ben3un ben3z2 be1o be1ra be2rab be2ran berb2 berd4 ber4ei. be4r3eiw be4rerk bere4s ber6gan. ber4hab ber4in. ber3iss ber3na b1ernt be1rop ber3st4a be3rum ber2zö 3be1s bes2a be2s1er be3slo bes2po bess4e b3esst. bes3sz beste2 be6stein be4s3tol best4r be3s4ze 3bet be2tap be3tha be1ur 3b2ew 2b1ex 1bez 4b5f4 bfal2 2b1g2 bge3 bges4 2b1h2 bhut2 1bi bi3ak bib2 bibe2 bien3s bie2s 3bietu bik2a bi2ke. bi2kes 3bil bil2a bi2lau 4b1illu bi2lu 2b1inb bin2e 2b1inf bin3gl 2b1inh 2b1int bi2o1 bio3d bi3on biri1 bi3se b1iso bi2sol bi2sp bis2s1c bi2s5t b2it. b2it2a b2ite bi3ti bi2tu b2i3tus biz2 4b1j bjek4to 2b1k4 bl2 2bl. bla3b4 b3lad b5lag b2lanc 3blat b2latt 2b3law b2läse b2le 3blea b3leb 3blec 2b3leg 2bleh 2b3leid 4b3lein blei7sc 3blem 3ble4n b3lese ble3sz b4let b3leu 2blich 3blick b2lie 2blig bling4 b4lis b2lit 3blitz b2lo b4loc b3los 2blun 3blut 3blü 2b1m 4b3n2 bni2 bnis1 bo4a bo5as b1ob3 bo2bl bo2br bo2c bo3ch2 bo3d2 boe1 bo2ei 2b1of bo3fe bo1is bo2l1an 3bon. bond1 bon2de bo2ne 3bons b1op bo1r2a bo4rä bor2d3r bo2rei bo4rig bor2s b1ort bor2t3r bo2sc bo4s3p bote3n4e bo3th bot2st bö2b3 2böf b1öl 2b1p2 bpa2g 2b1q b2r4 2br. b4ra. 2b3rad b4rah b4ra3k bra1st4 3brä brä4u 2bre. 3brea 6b5rechte 2b3ref 2breg b3reif 3brem 2b3rep b4rer 2b3riem bri2er b4rio b3roh 2b3rol b4ron b4ruc bru4s brust1 bru2th 3brü 4b1s b2s1ad bs3ar bsat2 b3sä b4sär bs2äu b5sc bs2ca bsch2 b6schan b6schef bs4cu b3se. bse2b b3sel. bse2n1 b4s1erf bs3e4r3in bs1erk b4s1ers b3s2es bsi4t bs2ku b4sl b2s1of bso2r b2sö b3s2pi bs2pl b3s2pu bss2 bs2t bst1a2b bst3ac bst1ak bs3tät bst1er b2stip b3sto b4s4tob b4stod b3stö b4strac b2s3trä bs3treu bs4tri bst3ro b3stü b4stüb b2s1un 4b3t btast3r b5te b4th btil4 bt4r b4ts2 btü1 bu2chi bu2e3 bu2f bug3 bul2la 2b3umk bunde4s bung4 b3ungn b2urg bu3r4i 4burn bu2sa bu4s3cha bu4schl bu4sch3m bu4schw bus1er bu2sin bu2s1p bu2s1u bu3tan bü1c bügel3e 2b1v 2b1w by1 by3p bys2 2b1z2 bzeit1 1ca 2c1ab ca2ch ca2e3 ca3g4 ca1h cal3t 3cam c4an ca2pe 3car car3n carri1 ca3s2a3 cas3t ca3t4h ca1y2 cä3 cäs2 2cc c1ce c1ch2 c2d2 c3do 2cec ceco4 1ced ce2dr 2cef ce1i 2cek 1cen 1cer cere3 ce3s2h 1cet 2ceta2 ce1u 1cé 2c1f c4h 4ch. 2chab ch3a2bi cha2ck 2chaf 2ch1ak ch2anb 3chanc ch1ang ch3anst 4chanz 1chao 4char. 1chara 3charta cha2sc 3chato 4chatu ch1ärm ch1äs 1châ 2chb 2chc 2chd ch3e4ben 1chef 3chef. che4fer 3chefi 3chefs 2chei ch1eim 4chelem che4ler 4chents 4chentw cher3a che3rei 6chergeb cher6zie ch3ess 2cheta 2ch3e4x 1ché 2chf 2chg 2chh 1ch1ia 2chic chi3na 4chind 3chines 2chinf 2chinh ch1ins ch1int 2ch1inv 1chiru 2chj 2chk 2chl2 ch2le ch2lu 4ch2m 4chn4 chner8ei. 2chob cho2f ch1off ch1oh chol2a ch1orc 2chp ch2r4 4chre chre3s ch3rh 1chron 4chs chst3ri 2cht 2chuf 2chuh 2chum 2ch1unf 2chunt 4chü 2chv 4chw 1chy 2chz ci1c ci1es ci2s c1j c4k 4ck. ck1a 1cka. 2ckac 2ckal 2ck3an cka4r1 ck1ä 2ckb 2ckc 2ckd 1cke 4ckeff 2ckeh ck1ehe 4ck1ei 4ckense 4ckentf 4ckentw cke2ra ck2ere 6ckergeb ck1erh 4ckerhö 4ckerke ck2ern 2ckero 2ck1er2r 2ckerz 2ck1ese 2ckex 2ckf 2ckg 2ckh 1cki 2ck1id ck1im ck1in 3ckis 2ckk 2ck3l 2ckm 2ck3n ck1o2 2ckp 2ck3r 4cks ck4stro 2ckt ckt2e ck3t2i 1cku 2ck1um3 2ckunt 2ck1up 2ckv 2ckw 1cky 2ckz c4l2 cle4a clet4 clo1 clo2ck 1clu c2m2 3co co2c co3ch co2d2 co3di coff4 coi2 co1it co2ke co2le col2o com4te. comtes4 con2ne co2pe co1ra cor3d co3re cos3t co4te cô4 2cp 2c1q 1c4r2 cre2 cre4mes cry2 2cs cs2a c2si c1s4tr 4c1t cte3e c3ti2 cti4o ctur6 3cu cu2p3 cussi4 1cy 2c1z 3da. da1a 2d1ab d2abä da2ben 3d2abl da2bre dab4rü 2d1ac d2ac. dach3a da2cho dach1s 4d3achse d1af d1ag dagi2 dah3l da1ho 3d2ai da1in da1is dal2a 2d1alar dal3b2 da3lö d1alt d1amma 2d1ammä damo3 d4amp dampf8erf 2d1amt d2an. 2d1ana dan4ce. 2d1an3d2 d3anei d1ang 2dange 3dank dan4kl dan5kla dan2k1o dan2kr 2d1ans 4dantw 2danw d2anz. 4danzi 2d1ap d2aph 4dapp da2r3a 2darb2 dark4 3d2arl dar2ma dar2m1i da2ro d3arr 3d2ar3s d1art 2dart. da2ru d2arw d1arz da1s dasch2 da3s2h das4t 3dat dat2a da3t2e2 date4n 4d3atl 4d1atm 3dau3e 4d1au2f d3aug 4d1aus3 2d1ax 2d1äh 2d1ämt 2d1änd 2d1äng 2d1äp 2d1ärz 2d1ä2u dä3us 2d1b4 dbu2c 2dc d1ch dco4r 2d1d2 ddar2 d3dä d3dh d5do 1de de2ad de3a2t 3deb4 4d1e2ben 3de1c de4ca. de2cka de3e4 2d1eff deg2 de3gl dehe2 de3ho 2d1ehr d1ei 3d2eic 3d2e1im dein2d dein2s de3inse de2l1a4g de4l3aug del1än del1ec delei4g 2delek 2delem deler4 2delfm delle2 del4l3eb del4lei de2l1ob de2lop de3lor de2lö del2s5e del2so del2s1p del5ster del3t4 dem2ar dement4 de6mentg 2d1emp d2en. dend2 de4n3end 4denerg 4d3en4ge. d2enh de2ni den4k3li den2kn 4den4sem den4sen den6s5tau den3th 2dentw de1nu 2deol de1on depi2 d4er. de1rad de2rap der2bl 2derdb de2re2b de4reck de4r3ei4s derer3 de3r4erb de3r4erf de4r3ero derer4t derer6ze d4erfi d2erh 4der4höh d4erhü 3derie derin4f 4derklä derm2 4derneu de1ro de2rop 4der4sat der4spa der3tau der6t5en6d dert4ra 6der6trag de3ru de4ruh de4rum des1 d2es. de2sa desa4g de4sam des2äc de2seb de4seh de2sei des3elt de2sen1 de4set de2sin de2sor de2sp de3spe des3s2 dest5alt de2sto dest5rat de4stre des4tum de2su det2 deten4t 2d1etw de1un de1url de3us devil4 d1exi de2xis 2dexp 2d1f4 2d1g2 dga2 d2ge. dge4t1e 2d1h2 dha1s4 d2his 1di di4ab di2ad di4am di4ath 3dic di1ce dich1 di2e di3e2d die4neb di3eni di3ens. di3ern die2s3c diet3 die2th dige4s dik2a dil2s5 2d1imb 2d1imp din2a 2d1ind 2d1inf 2d1inh 2d1in1it 4d3inner 2d1ins 2d1int di2ob dion3s di1p di4re. di2ren di2ris 2d1irl di2s1a2 di2sp di3s4per 2d1isr dist2 di2ste di4stra di2ta di4teng di4t3erl di4t3erm di4t3ers di2th di4t3r dit3s di2tu di5v di3z2 2d1j 2d1k4 4d1l2 d3la d3le dle2ra dli2f dl3m dl3s 2d3m2 4d5n2 dni2 dnis1 d1ob d2oba 2dobe dob4l d2obr 2d1o2f dole4 doll2a do2mar do5na donau1 doni1e do2o 2dope 2d1opf d2opp d2o3r4a 2dorc 2d1ord dor2f1a dor2fä dor2fl dor2fr 2d1org dori1 2dort dor2ta dor4ter d2os. dos3s dost1 dot6h do2t1o do3un d1ö dö2d dö2l1 d2ön 3d2ör dö2s1c 2d3p2 2d1q d2r4 3d4ra. 2d3rad drag4 2drahm d3rai 3d4ram d3rand 2d3rast d3raub 2d3rauc 2draup 2dräd d4räh 2d3rät 2d3räu 4d5re. d4rea. d4reas 3d4reck 2dref 2dreg 3d4reh 2d3reic d4reiv 4drem 4d3ren 2d3rep 4d3rer 4dres. d4resc 2d3rh d3ri d4ri. 3d4ria 2d5ric d4rid d4rif d4rik d4rin. d4risc 3d4rit 4dritu d3rob d3roc 2d3rod d4roi 2d3rose 2d3rost 2d3rot d3rou 2d3rov d3rö drö2s1 d5rub 3d4ruc 2d3rud 2d3ruh 2d3rui 4drund drunge3 2d5rut drü1b drü5cke 2d1s 4ds. d4s1amt d2san ds3assi d2sau2 ds1än 4dsb d4schef d4schin d2s1e2b d2s1ef ds1ehr d3sei ds2eig d4seins d2s1eng d2s1ent d2s1erf d2serh d2s1erk ds1err d2s1erz dse4t d4s1eta d3s2ha d3sho d2sid d2s1im d3s2inf d3s2kan d3skul 4dsl d2s1op dso2r ds1ori d2sö d2s1par ds1pas d2spä ds2po d3spri d2spro ds2pu dss4 dst4 d4stabe d4stag ds3tauf d4s3täti d2ste d4stea d3stei d3stell d4stem d3s4tern ds2ti ds4til ds4tip ds2tu ds1ums d2sun ds2zen 2d1t dta2d d5tea d2th d4thei dt3ho dto2 d3tö dt3r dtran2 dt5s2 d3tü 1du du1alv du1ar dub3l du2bli du2f 2d1ufe 2d1uh du1i 2d1umb 2dumd 2d1u2m1e 2dumf 2dumg 2d3umk 2duml d2ump 2dumr d1ums d2ums. 2d1umv 2d1un3d dund2a 2d1unf dung4 2d1ungl dun3ke dun2kl 2dunr dun2s dunst3r 2dunt 2dunw du1o dur2 dur3au 5durc 2d1url 2dursa du4schn du4schr du4schw dus3t 2düb 2d1v2 4d1w dwa2 dwest1 dy2s 2d3z2 2e1a e3a2b eab3l ea2c ea3der eadli4 ea2dr ea2g4 ea3ga ea4ge ea3gl eakt2 e3akto ea2la e3alei ealer2 e4aler. ealer4t e2alti2 eam3 eam1o ea2na e2ano e3ar. ea2ra e4are. ea4rene e4arer e4ares ea2sc eas3s eat4e2 eater1 e3ath ea5tr eat3s2 e3at5t4 e3au2f e3aug eau1st e3ä2 e1b 2eba e3b2ak 2ebed ebe2i 2ebel eb2en ebens3e ebe4rel ebert4 2ebet 2ebl eb3ler eb4leu e3blie eb3lo eb2lö 2eb2o ebot2 ebö2s 2ebr eb3rei eb4ru eb2s1 eb6sche ebse2 ebs3pa eb3sta eb4stät ebs3tem ebs3t2h eb3str 2e3bu ebu2t1 2e3ca e1ce ech1ä 2e1che ech1ei e6ch5erzi ech3l ech3m ech3n e2cho. ech1o2b e2ch3r ech3t4ei e1chu ech1uh ech1w e1ci eci6a e1cka eck3se eck4sta 2eckt 2e1cl 2eco eco3d e3cr ec1s 2ect e1d e3d2a ed2dr ed2e ede2al ede3n2e edens1 eden4se eden4sp ede2r eder3t2 edi4al 2edip e3d2o ed2ö eds2ä ed4seh ed2s1es ed2s1o ed2s1p ed2s3tr ed2su edu2s e3dy3 4ee ee3a2 eeb2l ee2ce ee1ch ee2cho ee2ck eede3 eed3s2 ee1e e1eff eef4l eeg2 e1ei ee1im eein4se eel2e ee2lek ee5len e1emp e1en eena2 ee4nag e2enä e2enc e2eno een3s e1e2pi ee2r3as e1erbt e1erd ee3r2e ee4r3en4g eere2s ee1ro ee1rö eer2ös eert2 e1ertr ee3r2u e1erz ee3s2 ees3k ee3ta ee4tat ee1u eeu2f eewa4r e1e2x e1f 2ef. 2efa e2f1a2d ef1ana ef1ar e2fat e2fäu 2efe e3fe. e2f1e2b efell4 ef1em e2fent ef2er efeuil4 2eff. 3effek 1effi ef2fl 2efi ef1id e2f1ins efi2s 1efku 2efl e3f4lu 2e3f2o e3fra ef3rea ef3rol ef3rom ef4rü efs2 ef3so ef3sp ef2tan ef2tei 2efu e2fum 2efü e1g egas3 eg1d4 e3ge ege4ler ege4n3a4 ege4nec ege2ra ege4str ege1u e2glo e2glu e2gn eg3nä eg3ni eg4sal eg4san eg4se4r1 eg4sto eg2th egung4 egus3 2e1ha eh1ach eh2al e2hap eh2aus 2e1hä e1he eh4ec eh1eff eh2el ehe5na ehen6t3 1e2hep e3her ehe1ra ehe3str e1hi eh1int eh1lam eh1lä ehl3ein eh4lent eh5l2er eh2lin eh3lo ehl2se ehls2t 2ehm eh3mu e1ho e3hol ehr1a2 ehr1ä ehr1e2c eh2rei ehr4erf ehr6erle ehre3s eh3ri eh1ro2 ehr1ob ehr1of ehs2 eh3sh eh3sp eh1ste 2eht e1hu e2hunt e1hü eh3üb eh1w e1hy 2ei3a2 ei2bar ei2bl eibu4t ei4b3ute ei2cho eich5te e2id ei2d1a ei3de eid4ein ei4d3er4r 2eidn ei3dra eid3sc ei1e ei3el 4ei3en3 eienge4 eif2e 1eifr ei3g2a 4eigeno eig2er 2eiges 2eigew ei3gl 1ei2g3n 2eigru 2eigt 2eigu eik2ar ei3kau eik4la e4il 2eil. ei2lar ei2lau 2eilb eil3d ei4lein eilen1 eil3f4 eil3ins 2eiln 1eilzu ei2m1a4g eim3all ei2mor e1imp eim2pl e4i2n1a ein3a2d ei4nas ei4nä ein3dr 2eindu ei4neng ei2neu 2einfo ein4fo. ein4fos ein3g2 ein4hab e1init eink4 ein6karn 3einkä 3einkom einn2 1einna ei2n1o2 e4insa 3einsat e3insta ein6stal ein4sz 1einu e4inver ei3o2 ei1p eip2f 2eir ei3re e1irr e2is. ei2sa4 ei4s3erw eis2pe eis4tel eis4th ei1sto ei2sum e4it ei2tab ei2tan ei2tar 2eitä ei3te ei2th ei2tor ei2tro eitt4 eit3um 2eiu 2e1j e1k ek2a 1ekd e3ke. e3ken e3kes e3key e3k2l ek3lip ek4n ek2o 2ek4r 2ekt ekt4ant ekt3erf ekt3erg ek4t3er4z ekt2o ek5tri ek2u e3k2w e1la ela4ben el3abi el2abt ela2c el3ader el1af ela2h e2l1ak el3al e2l3a2m el4ami el4amp e6landa e2lanm el1ans el1anz 2elao e2l1ap e2l1a2r el3ari ela4s el1asi el1asp el2ast 2e1lä 3elbis el2da eld3erh elder4p eld5erst el3des eld3s2 e3lea2 ele2c 2elei e6l5ei6er. e6l5ei6ern el1ein e4leinf e4leing e4leinh 1elek e2l1el 1e2lem e3lem. el1emp 2e3len. e4lense e4l1ent e3lep e2l1erd el1erf e4ler4fa e2l1erg el1erk el1erl e4ler4la e4l3ernä e4ler2ö e2l1err eles2 el1ess e4l1e4ta e3leu 2elev ele2x 1elf. el3fe elf4l 1elfm 1elft elg2a elgi5er. elgi5ers elg4r e2l1id e3lie e2lim el1ita 2elk elk3s2c el3lan el3le el5le. ell3ein ell3eis el2lim el3lin ell3sp 2eln el5na 2elo e2lof e2lol elon2 e2l1or elo2ri elö2s el2sum el5ten. elter4b 3eltern elter4s elto2 elt3r elt3s2k elts2p 2e1lu el1ur el3use e1lü e2lya 2elz el2zar elz2e el2zwa e1m 2ema em1ad ema2k e2m3anf e2m1ans 3emanz e3mäs em4d3a2 e3m2en emen6gel emen4t3h e2m1erw eme2s 1e2meti e2m1im emi5na em1int emi3ti 2emm emma3u em2m1ei e2mop 1empf4 em3pfl em2sa em2spr em2st em3t2 1emul 2emü e2n1a 4ena. 2en2a2c en3ack e3nad e4naf 4enah e4n3a2k ena3l2i enal3p 4enam en4ame e4nand en3ang e4nanz en3are ena4sc 4enat en3att e3naue en1ä e2när en4ce. en3d2ac en2dal en4d3ess end4ort end3rom end3s2p end3sz end2um 2ene. ene4ben en1e2c e2neff en2eid e3neien e4nein e2n1el ene4le 2enem 2enen e4n1ent en4entr 4e3ner. e2n1erd e2nerf 1e2nerg e4nerh e4nerk e2n1erl e4n3ermo 4enern e2n1err e2n1ers e2n1ert e2n3eru e2n1erw e4nerz 2enes e4n3ess en3f enf2a enf2u 1engad 3engag enge3ra en3g2i en3glo en3gn 1engp eng3se 2eni e3ni. e3nic e2nid e3nie eni3er. eni5ers. e2n1i4m e2n1in e3nio eni2ö e3nit en3k2ü e2n1o2b enob4le e2nof en1oh e3nol eno2ma en1on e2n1op e2n1o2r enost3 e3not eno2w 2e1nö en1ö2d en3sac en2sau en5sche en2seb 3ensem ensen1 en2sep en4seta en3ska en3sp ens2po enst5alt en4s3tät ens2th 2ensto e4nt ent4ag ent4ark 1entd en2teb en4terb 1entf 2entfo 1entga 3entgeg en2thi 3entla 1entn en4t3rol 3entspr 1entw 4entwet 1entz en1u 2enut e1nü enü1st 4enwü e1ny enz1ec en4z3erf en4z3erg en4z3erk e1ñ 2eo e1o2b1 e1of eo2fe e1oh eo3m e1on. e1ond e1onf e1onh e1onl e1onr e1ons e1ope e1opf eop4t e1or e3or. e3orb e3ors e3orw eo1s2 e3os. eota2 eo3ul e1ov e1ö2 e1p epa2g e3p2f4 e2pis 1episo 2epl ep3le 1e2poc ep2pa ep2pf ep4pl ep2pr ept2a ep2tal 2e3pu epu2s e1q er1a e3ra. era2be e3rad. er3adm eraf4a era2g e1rai er3aic e2rak e1ral er3all eran3d e3rane er3anf e2ranh er3anm e1rap er3apf e2rar e3rari e1ras e2r3a4si er4ast era2ß e2rath e3rati e2ratm e1raub er3aue erau2f er3aug e1raw e1raz e1rä er1äh er1äm e2r1äs erb2e erb4sp er1c er3chl erda3me 1erdb er3de 2erdec erde3in er4d3en4g erd3erw erd3s 4ere. er1eb e3rech er3echs er1e2ck er1edi ere4dit er1eff er1e2h 4e3rei. er1eig e2rein e4r3eis. ere2l er1ele ere3lev 2e3rem e2remp 2eren 4e3ren. e3rena e4rense e4rentf e4rentn e3renz eren8z7en8d er1ep 2erer 4erer. e2r3erf e2r1erh 4erern e3rero er1err er1ers e2rert er1erw 2eres er1ess e4r3e4ti er1eul ere4vid erf2e er3f4r 4erfür 3ergebn 4ergehä erg3el4s3 1ergol 4ergrem erg3s ergs4t e2rh 1erhab 4erhals er3he 4erhöhe er3hu 2erhü 2eri e2riat e3rib 4e3ric er1i2de 4e3rie eri3e4n3 e3ri3k4 4e3rin. er1inb e2r1ini er1ink er1ins er1int e3rio er1ita 2erk. 1erklä er3ko 2erkre erk3t 2erlag 3erlebn 4erln erm2e ermen4s erm3ers er4nerk ern1os e1ro. er3oa er1o2b e2r1o2f e1rog e1r1oh e1rok e1rol e1rom e3ron er3ony er1o2p e4ro2r e1ros e1rou e1row er1ox e1roz erö2d 2erök er1ös er3p4 er3rä 2errü ersch2 er5schn er3se ers2i er3sk er3smo er3sn er3sp er5stel er3sz ert2ak er6terei er4t3erf er4ter4h er4ters er2t3ho 4er3ti ert3ins erts2e 2ertür 2eru eruf4s er1u2m er1und erung4 er1uns er3uz erü4b 3erweck es3ab e3sac e2s1a2d es3ak es4ank es3anz e3s2as e4s3ato es3av 2esb esbi5er. es2c es3cap e3sce esch2 e3scha e2s3ein es2el es3eva 2esf 4esh es2har es2id e2sil es1ini es3int es2ir es2is es2kat e4ske es3kl es3ku e4sky es3l es4log 2esm eso2r es2ort es2ö 2esp es2pek e3spi e3s2por e3s4pra 2esr essali3 es2sau es3sc es3se 4essem ess4e3re ess3erg 2esso es2sof es2s1pa es2spu es3stu estab4b es4t1ak e1star e4starb 1e2stas e1stat e1s2tec e3stel es4t3eng es4t3erh es4t3ess e1stil e2stip estmo6de est3ori e1str es4tri es3trop e1stu e1s4tü e2s1um es3ums es3w e3sy es3z e1ß eße3r2e e1t etab4 et1am eta2mi 3etap et4at et1äh 2e3te e4t1ein ete3ke et2en eten3d2 ete2o eter4hö eter4tr et2h et3hal ethi1 et3hü e3ti eti2m eti2ta 2eto eto2b e2t1of etons4 e2torg e3tö 2etr e4traum e6t3rec e2tres et4rig etsch3w ets2p et3su ett1a et2tab et2tad et2t3au et2tei ette4n1 et2th et2t3r et4tro ett3sz et4t1um e3tü etwa4r 2etz et2zä et4z3ent etze4s et2zw eu1a2 eu3b4 euen2g eu3erei eue6reif euer4ri eu2esc 2euf eu2fer eu2ga eu4gent eu3g2er eugs4 eu1in 1euk eu2kä e1um e3um. e3umb e3uml e3um2s eum4sc eums1p eum3st 2eun eun2e eu4nei eun4er e3un2g eu2nio eun3ka eu1o2 eu3p2 e2u3r2e 1euro eu2rys eu4sis eu3sp eust4 eu1sta eu1sto eu1str 2eut eut2h eut6schn 2eux eu2zo eu2z1w e3ü 2e1v e2vela e2vent 4ever eve5r2i e3vo e1w 2ewa e3wä ewä2s 2ewe e2we. ewinde3 e3wir ewi2s e3wit ew2s 2ex. ex3at 1e2xem ex1er e1xi 2exie e2x1in 1exis ex3l 3exp 2ext. ex2tin ex2tu 2exu 2e3xy ey1 ey4n eys4 e1z e3z2a e2z1enn e3zi ezi2s ez2w é1b é1c é1g é1h é1l élu2 é1o é1p é1r é1s é1t2 é1u2 é1v é1z2 è1c è1m è1n è1r ê1p ê4t 1fa fab4 f1abe fa2ben 2f1a2bl fab5s fa4cheb fa2ch1i fa2cho f1ader fa2dr f4ah faib4 fa2ke f2al fa3l2a fal2kl fal6l5er6k fal6scha fal6schl fal6schm fal3te f1amt 2fanb 2fanf fan2gr 2f1ank 2fanl f1anp 2fanr fan3s 2fanw f1an3z 2f1ap f2ar far2br farb3s 2f3arc 3fari farr3s f3art 2f3arz fa3s4a fa3sh f3at fa2to 2f1auf f3aug f1ausb 3f4av fa2xa 1fä fä1c fäh2r1u f1älte 2f1ärm f1ärz fä2ßer 2f1b2 2f1c 2f3d4 fdie2 1fe featu4 fe2c f2ech fe3che 2f1eck fe2dr fe2ei fe1em fef4l feh4lei f4eie 2f1eing 4f1einh fe1ini 2f1einw f1eis fek2ta fe2l1a fel4da fel2dr 2fe2lek fe2l1er fe2les fel4lei fe2l1o fel4soh fels2t fel3t4 f2em. fem4m 2femp fen3a2 fe2nä fe2no fen3s2a fens2c fenst2 f1ent 3fep f2er. fe1ra fer2an fe4rang fe4r3anz fe2rau fe2r1ä ferde3 f2ere fer2er fer3erz f1erfa fe2rid 3ferk f2erl. 4ferneu fe1ro f4erpa f2ers. f2ert f1erw fer8zeuge fe2st fest1a fest3ei 2f1eta fe4tag 3fete fet2t3a feuer3e feu4ru 3few f1ex 2fexp 3fez 1fé 2f1f ff3ar ff4art ff1au ff2e ffe2e f2f3ef ff3ei ffe1in ffe2m f2f3emi ff4en f2fex fff4 ff3lag ff3li f3flu f3flü f3f4rä ff2s ffs3tan 4f3g2 fge3s 2f1h2 1fi 3fi. fi3at fid2 fien3 fi1er2f fi2kin fi3kl fik1o2 fi2kob fi2kr fi2l1an fil4auf fil3d fi2les filg4 fi3li fi4lin fil2ip f2ina fing4s fi3ni fin2s fin3sc fin3sp 2f1int fi2o fi3ol fi2r fi3ra fi4re 3fis fis2a fisch3a fisch3o fisch3w fis2p fi2st fit1o2 fi2tor fi3tu 3fiz 2f1j 4f1k4 f2l2 2fl. f3lad flan3d f3lap 1flä 3f4läc 2f5läd f3län 2f3läu 2f3leb 2f3lein f3ler f3li. 3f4lim fli4ne 2f5lon 1f4lop 1f4lot flo2w f3lö 4f5löf 1f4lug flu4ger f4lü f5lüm 2f1m2 fma2d 2f3n2 fni2s 1fo fob2l 2f1o2f foli3 fol2k1 fo2na fon3au fon2e fo2nu 2f1op fo1ra 4f3org fo3rin 3form for4m3a4g forni7er. for4st fort3 for4tei for2th for2t1r for3tu f1o2x 1fö 2fö2f 2f1ök 2f1öl för2s 4f1p2 2f1q f2r2 f4rac frach6tr 2f5rad fra4m f3rand f5rap 1f4rän 2fre. f3rec f3red 2freg f3reic freik2 frein2 f3rep 3f4reu 2f3ric fri3d fri2e 2frig 1fris f4risc f3roc 1f4ron fro2na fro2s f3rot f3ru f3rü 4f1s fs1all fs4amm f2san fs3ar f2s1as f2sauf f2saus f2saut f3sc f4sce f4schan f4schef fs4co fs1e2b f4s1ehr f2s1em f2s1ent f2s1er fse4t f4s1eta f3si f2si2d f3s2kie f2s1o2 f3span f2s1pas fs1pen f2sph f3spi f3s2pl f3s2por fs1pr f2spre fs2pri f2spro fs2pru fs3s4 fs2t fs3tak f2stas f4s3täti f3stei f3s4tel f3stern fs3th f2stip f3st4r f4s3tres fs3trü f3stü f4s3tüte f2s1un f3sy 4f1t f4ta. f2tab ft1a2be ft1af f2t1al ft1an ft1ar f3tat f2t1äu ft1e2h ft1eig ft1ein ft1eis f4t1ent f4t1e4ti f2th f4thei ft3ho f2t1id ft1op f2t3ot f3tö f2t3ro f2trö f3t4ru ft2s1 ftsa4g ft4sam ft3s2c ft4sche ftse4 ft4seh ft3st ft4s3tan ft4s3tä fts2ti ft4stri f2tum ft1url f3tü ftwa4 ft3z2 1fu 3fuc 3fug 3f2uh f1um 2f1unf fung4 2f1u2ni fun2kl fun2ko fun2k3r 2f1unm 2funt f2ur fu4re. fus2sa fus2s1p fus2st fu2ß1er 3fut 1fü 2füb fü2r 2f1v 2f1w 1fy 2f1z fz2a fzeiten6 fzei8tend fz2ö fzu3 fzu4ga f3z2w 3ga. 2gabf ga2b5l gab4r 2gabz ga1c 2gadl 2ga2dr ga1fl ga3ge 5gai ga1k ga2ka gal2a 2g1a2lau g1amb g4amo 2g1amt 2ganb gan3d 4gangeb gan2gr 2ganh 2g3anku 2ganl g3anla 3g2ano 2ganw ga1ny 3gar. 2garb 2garc 3gard 2g1arm ga3r2o 3g2ars 2g1arti ga3ru 2g1arz ga2sa gas3ei ga2si ga2sor ga3sp ga4spe ga4spr gas3s gas4ta gas5tan ga4ste gas4t3el gat2a 2g1atm gat4r gau1c 2g1auf 2g3aug g2auk g1aus 2g1aut 2g1äp 2g1ärz gäs5 gä4u 2g1b2 gber2 gbi2 gby4t 2g1c 2gd g1da g2d1au g2d1er gd1in g1do g1dö gd3r gd3s2 gdt4 gd1ur 1ge ge3a2 geb2a gebe4am ge3ble geb4r ge1c ged4 ge1e2 ge3ec ge2es gef4 ge3g2l ge3ha ge4ig ge1im ge2in. gein2s ge2int gein2v ge1ir ge2is 2g1eise2 gei3sh 2gek. ge4lanz gelb1r gel4b3ra gelder4 gel6ders ge3le 2ge4lek geler3ö ge4l3ers ge4less gell2a ge3lor gel3sa gels2p gels2t gel3ste gel3sz gel3t2a ge3lü gelz2 gem2 gem4e ge3mi 3gen ge3na ge4n3ac ge4nam ge4nar gen2as gen4aug gen2d1r gen1eb ge3nec gen3eid gen3ern gen6erwe gener4z gen3n gen4sam gen3sz 2gentf gen3th 4gentw geo2r ge1ou ge3p4 ge1ra ge2rab 4g3ereig ge4reng ge4ren4s ge4r3ent ger2er gerin4f ger4inn gerin4t ger3no ge1ro ge1r2ö ger4sto ge3r2u g1erwa 4g3erwer g2e1s2 ges3auf ges3elt ge2s3er ge3si ges4pi ges3s2t gest2 ge3ste ge4s3ter ges3th ge3t2a 2getap ge5tr ge3t4u 2g1e1ul 2g1ex 2g1f4 4g1g gga4t g3ge gge2ne g2g3l gg4lo g2g3n gg4r 2g1h 4gh. 3ghale gh2e 3g2het 3g2hie gh1l 3gh2r g2hu gh1w gi3alo gie3g gi2e1i gi2el gien2e1 gie1st gift5s gi2gu gi2m gi4mes 2g1ind gi3ne g1inf gin2ga 2g1ins 2giok 2g3isel gi3t2a gi3tu gi4us 2g1j 4g3k2 4gl. gl2a 4g1lab g1lac g2lade 2g1lag 2gland 3g2laub 4g1lauf 2gläuf g2l4e 2gle. 3gle3a 2g3leb g3lec g3leg 2gleh 3gleic 4g3lein glei4t5r g3len 4g3ler 2gles g3lese g4lia 2glib 3g2lid g2lie 2glif g2lik 2glil g2lim 4glin g2lio 2glis g3lisc 3g2lit g2liz 3g2loa 3g2lob 4g3loch glo3g 3g4lok g2lom 3g2lop g2lor 3g2lot 2glös 2gls g1lu 2g3luf 2glun 4glus g2lut g1lüg g2ly 2g1m2 g1n 2gn. g2n2a g4na. 4gnah 3g4nat 3g2nä gn2e g3neh 2gnel gne2tr 2gneu 2gng g2nie g2nif g4nin 2gni2s1 g2no gno1r g3not 2gnp 2gns 2gnt 2gnu 3g2num. g2nü g2ny 2gnz go4a goa3li 2g1o2f 2gog 2g1oh go1i gol2a 2gonis 2g1ope 2g1opf g2o1ra 2g1ord 2gorg go2s1 go3st go3th got6t5erg go1y 2g1p2 2g1q g2r4 gra2bi gra2bl 2g3radl 2g3rah 4g3rak grammen6 gram8m7end grau3f gräs1c 2g3räu 2g5re. g4reb 2g3rec 2g3rede g4re2e 2g3reic 2greim 2g3rein g3reit g4rem 2g3renn gre3no gren6z5ei g4rer g3ret g3rev 2g3ric gri2e g3riese 3grif 2grig 2g3ring gro2bl 2groc 2groh gron4 2g3rose gros6sel gro4u 2gröh g4ruf 2g3rui 2g3rum grun2g 3g4rup 2grut 2g3rüc 3g4rün 4g2s1 gsa2d g4s3a2k g3sal gs3all g4salt gs3ama gs3an gs3ar g3s2c g4sca g4s3ce gsch4 g4schef g4sco g4s3cr gse2 gse3e gs2eh g3s2eil g3sel. g3seln gsen1 gs3er gser5f gs5erk gse4t g4seta gsi2d g3sil g4s3l gso2 gsp4 g3s2pek g3spi gs4pie g4spin g4s3pl g3s2por g4spru gsrat4 gsrü2c gs5s4 gs3ta g3s4tan g3s4tar g3s4tati g4s3tä g5stäm g3stel gst3ent gst3err g1steu gst2he g3stir g3sto g4stol gs3top g4s3tor g3stö gs3tr gst4ra g3s4tras gs4trat gst5reit gst4ri gs4t5rit gs4t3ros g3stu g4stur gs3tü g4sw g3sy 2g1t g3te g3ti gti2m gt4r gt2s g3tü 1gu gu1an. gu1ant gu1as gu1c gu4d3r gu2e 2gued guet4 2g1u2f 2g1uh gu1ins gu1is 3gumm 2g1unf g2ung. gunge2 4gungew 2g1ungl 2g3unk g2un4s 2gunt2 2g1url gurt3s gu2s3a guschi5 gus4ser gus2sp gus2st gu4st gu2t gut1a gu4t3erh gut3h 2güb gür1 güs3 2g1v 2g1w 2g3z2 3haa hab2a hab2e 2habn hab2st ha2cho ha2del ha4din h1adle haf3f4l haft4s3p h1ah h2ahs h2ai ha3ia h2aj 2haka ha1kl 2h2al. halan4c ha2lau hal2ba hal4bei hal4b3r 2hale hal2la hal6lerf h1alp hal2st hal4t5r h1amt h2an. 2hanb h2and han2da hand3s han2kr h4ann 2hanr 2hant h1ap ha2pl ha2pr h2a3ra 2harb h2ard h1arm. har3ma har4me. har4mes har2th h1arti h2as 2ha3sa hasi1 hat5t2 hau5f6lie 2h1aufm h1aukt hau2sa hau4san hau2sc hau4spa hau5stei hau6terk 2hauto hau2tr h1äff h1ärz hä6s5chen häu2s1c hä3usp 2h3b2 hba2r3a 2h1c 2h3d4 hdan2 2hea he2ad he3be he4b1ei he2bl he3br he1ch he3ch2e h3echt he3cke hed2g he3di he2e3l hee4s he2fan he2fä he2f1ei hef3erm 2heff he2fid he4f3ing he2f3l he2fr he3fri he2fu he3gu h4eib h1eie h1eif h1eig he2im heim3p hei4mu 2hein heine2 4heio he1ism he1ist heit4s3 h1eiw he2l3a hel1ec h3e2lek he3len hel3ers he3li hel4l3au hel4mei he3lo he4lof he2lö 3hemd he3mi 3hemm 4h3emp h2en. he4na2 hen3a4g he2nä hend2s he2n1e2b hen3end hen3erg he2net heng2 2heni he2no hen3sk henst2 hen3str hen5tr h1ents 2h3entw hen3z 4he2o he3on he3op he3pa he3ph h2er. her3a2b he2ral 2herap he3ras herb1r her4b3ra he4reck 4hereig he4r3eis he2rel he4rerw h1er2fo h3erfü herg2 her2ho 4herif herin4f he6rin6nu herin4s herin8ter h1erke h3erlau 2herm he3ro he4r3o4b h1erö hert2 her3th her2z1w he1sta he2s5tr he2tap heter2 he3th het2i he3t4s h2e2u heu3g 3heusc he3x he1x4a he1y2 1hè 2h3f4 hfell1 hfel6ler hfi2s 2h3g2 hget4 2h1h2 hhoh2 4hi. 2hia hi2ac hi2ang h2ias hi1ce hich6ter 2hi3d h2ide h1i4di hi2e hi3ens hier1i hie4rin hiers2 hif3f4r hi2kr hi2l3a4 hil2fr hi2n h1indu hi3nel hin2en h1inf h1inh hi3n2i hin3n2 hi3no hin3s2 hin4t1a 2hio hi4on hi3or 2hip1 hip3f hi2ph hi2pi h2i2r hi3ra 2hi3re hi3ri hirn1 hir4ner hi3ro hir2s his2a hi2se hi2st hi1th hi3ti 2hiu 2h1j 2h1k4 2hl hl2ag hla2n hl1anz h1las h1lat h1laut h3läche h3läd hl1är h1läs h1läu hlb4 hl3d4 h3leb hle3e h3lein h2leis h5len. hl2eng hl2enn h3ler hle2ra h2l1erg h6l3er4nä hle3run hl1erw h4lerz h3les h4lesi h3lex hlg4 h2lie h2lif h2lim hl1ind h2lip h2lis h3list h2lit h2lo h3loc hl1of hl1op h4lor hlo2re h3losi h2lös hl3sku hl3slo hlst4 hl3str hl3t2 h3luf h3luk h3lumpe h1lüf 2h1m h2mab h3mad h3mag h3man h3mar h3mä h4mäc h4mäh h4mäl h3me. hme1e hme1in h3men hmen2s hme2ra h2mo h4mon h3mö hm3p4 hm2s hm3sa hms1p h2mu h3mul 2hn h2na hna2c h3nam hn1an h3nau. h2nä hn1äh hn1är hn3d4 hn2e hne3b hne2e hn3eig hn3ein h2nel hne4n1 hne4pf h3ner hner3ei h4nersa hn3ex hnhof8stras h2nic h2nid h2nie hn1im hn1in h2nip hn3k4 h2nor hn3s2k hnsuch4 hn3ti hnts2 h1nu h2nuc h2nul hn1unf h3nunge ho2bl ho2ch3 ho2cka ho6ckerl hock3t 2hod hoe2 ho2ef ho2fa hof3fa ho2f3r 2hoi hol1au 3hole ho2l1ei hol3g4 ho4lor 3hol3s h1o2ly 3holz hol6zene hom2e ho2mec ho2med h2on hond4 hono3 2hoo 2hop ho1ra hor3d 2h1org ho4sei ho3sl ho2sp ho4st 2hot. ho3th hotli4 2hots2 3hov 2ho2w1 h1o2x ho1y2 1h2ö hö2c hö3ck 3höhe h4ör hö2s1 h3öst 2h3p2 h1q 2hr hra2b hr1ac hr3ad h1rai h1rane h3räu hr1c hr3d h2rec h3rech h3red h3ref h4rei. hrei4ba h3reic h4r1eig h3rel h3ren h3rep hr4erbe hr4erbu hr2erg hr2erk h4rer4la h3rerle h6rer6leb hr6erlei hr2erm hr2erz h3re2s1 hre2t h2r1eta h3rev hrg2 h2ri h3ric h4rick hri4e h3riesl h3rin h4rinh hr1ins h4rist hr3l hrm2 h2rob h2rof h3roh h3rol h4rome h4romi h4ron h2ror h3rou hrr4 hr2s1ac hr4s3an hr2s3au hr3schl hr2s1en hr2ser hr4set hr4s1in hrs3k hr4s1of hr2su hr4sw hr2t5ab hr2tan hr2th hr2tor hrt3ri hr2tro hrt2sa hrt2se h3ruh hr1ums h3rü h4rüb h4ry hrz2 4hs h4s3acht h2s1a2d h4samt h2san h2sau h2s1äh h4schan h2s1ec hse4ler h2s1erl h3s2ex h2s1ing h2s1o2f h2spac h2s1par h2spel h2sper h2sph hs2por h2sprä h2spro hss2 h1sta h2staf hst3alt hst2an h2s3tau h1stec h3stein h5stell h3s4terb hst2he h1s2ti h1sto h2stor h1s4tr hst3ran h1stun h1stü h2s1u hs2ung 4h1t ht1a h2tak h3t4akt. ht2al h4talo ht3alt h4t3a2m h2ta4n ht3ane h3tank h3tann h2tar ht2as h2t3ass h2tasy h2t3a2t h2tau ht3aug h4tax h2t1är ht1e2c h2t1ef ht1eh hte2he h2teif h4teilz h2t1eim ht1ein h2t1eis h2t1eke h4t3elit h2temp h4tentf h4t3ents hter6de. ht3erfü ht3ergr h2t1er2h ht5erken h4terkl h6t5erleu h6terneu h4t3er4re h6t5er6spa h4t3er4st ht6erste h2t1erz hte2s h4t1ese h4t1ess hte3sta h2t1eu h2t1ex h2th h4thei hthe3u h2t1im h2t1in hto2 h2toly h2torg h3töp h4t3rak ht3rand h2t3ras h2t3rat ht3rau h4traub ht6raume h5trec h4tref ht3reif ht3reit ht4ri h4t5rieg h4t5rin h2t3rol h2t3ros ht3rös h2t3ru h2t3rü h4ts ht4s3an ht4s3end ht2so ht2sp ht4spin ht3spri ht4stab hts2ti hts4tie ht4s3tur ht4s3tür htt4 htti2 h2t1urs h3tü ht3z2 hu2b1a hu2b3ei hu2b1en hu2b3l hu4b3r hu2bu hu1c hu2h1a hu2h1i huko1 huk3t4 hu2l3a hu2lä hu2l3ei hu4leng hu4lent hu2ler hu2let hu2l1in hu2lo hu3m2a h1ums hu2n h1una hung4s hu3ni1 h1ups 2h2ur hurg2 hu3sa hu2so hus4sa hus2sp hu2tab hu3t2h hu2ti hut2t hut4zen hut4z3er h2ü h4übs h3übu hühne4 hüs3 2h1v hvi2 hvil4 2hw h2wall hwe1c h1weib h1weih 3hyg 3hyp hy2pe. 2hy2t 2h1z hz2a hz2o hzug4 i1a 2ia. i4aa i2ab iab4l 2iac i2af iaf4l i4a3g2 i2ah i3ai i2aj i2ak i3ak. i3akt 2ial i5al. ia2l1a4 ia2lä ial3b ial3d i3alei i3alent i3a4lerf i3alerh ia4l3erm i3a2let i3a4lia ialk2 i3all ial3la ia2lor ial3t4 ia2lu ial3z2 i2am i4amo 2ian ia2nal i3and2 ian2e i3ann i2ano i3ant i3anz i2ap ia1q i3ar. ia2ra i2asc ia3sh i2asi i2a3sp ias3s iast4 i3at. i3a4ta i4ate i3at4h 1iatr i3ats i3au ia3un 2iav 2iä i1äm i1äp iär2 i1är. i1ärs i1ät. i1äta i1ät3s4 2i1b ib1art i2b1auf ib2bli ib1ei i2beig i2beis ibela2 ibe4n iben3a ibi2k i3bla i4blad i3blä i3ble i4bleu ib2o i2bö i4brä ib3ren ib2ser ib4ste i2bunk i2bunt ibu2s1 2ic ic1c ice1 ich1a ich1ä i1che ich1ei i1chi i2chin ich3l i3chlo ich3m i1cho i2ch3r ich3ter ich2tr i1chu ich1w i1ci i3cke i1cl i1d id2ab4 i3d2ac i3dam id1au 1i2dee idein3 i4deis idel2ä ide3so 1i2dio idni3 i2dol 1idol. 2i2dr i3d2sc id2s1p id3str idt4 1i2dy ie3a4 ie2bä ie2bl ie2bre ie2bri ieb4sto ieb4str ie1c ie2cho ie2ck ie2dr ie1e2 ie2f1ak ie2f1an ie2fau ief3f4 ief2i ie2f3l ie2fro ie4g5l ie3g4n ie2g3r ie3g4ra ieg4s3c ieg4st i1ei i2e2l1a ie3las iel3d i2ele iel1ec ie3lerd ieler8geb ie4less i2eli i1ell ielo4b i2els2 iel3sz iel3ta 2i1en i3en. i3ena iena2b ie4n3a4g i3e2nä i3en3d i2ene ien1eb ie3ner ien4erf ie4n3erg i3enf i3eng ienge4f i3enh i3enj i3enk i3enm i3enn i3e2no i3enö i3enp i3enr ien2s ien3sc ien3s2e ien3si iens2k iens6t5er iens4tr ienst5rä ien3sz ie1nu i3env i3enw i3enz ie1o2 ier3a2 ie2rap i2ere ie3red ie3r2er ie4rerf ie4r3erz ie3res i3ereu ierf4 i4eri ierin3 ier3k2 i1ern i3ern. i4erna i2er5ni ie2rö ier4seh iers2t ier3sta ier3ste ier3te iesen3s4 ie2spu ies2sp ies2s3t ie1sta iest6e ie3su ie2t1a ie4t3erh ie4t3ert ie2t3ho ie2t1o ie4t1ö4 ie2tri ie2t3ru iet2se i1ett ieu2e ie1un ie2w3u i1ex 2if if1ar i2f3arm if4at if1au i2fec ife2i if2en if1erh if2fl iff4st if3l i1f4la if4lä i1flü if3r if4ra i1frau i1fre if4rei if4rü if2s if3sa if3se if3sp if2ta ift3erk if2top if4t3ri ift3sp ifts2t ift3sz 2i1g iga3i i2g1ang ig1art iga1s4 i4gefar ige4na ige2ra ige3ran ig1erz i2g1im i2gl ig1lä i4glo ig4na i4gnä i3g4neu i3g4no i3go ig4ra ig3rei ig3s2a ig4sal igsau4g ig3sä ig4se ig3so ig3sp ig4spa ig3stei ig4s3to ig4stö ig3str igs4tra ig4stre ig3s4tü igung4 2i1h i2h1am i2har i3he ihe1e ihe4n ih3m ih3n ih3r ihs2 i2h1um ih1w ii2 ii3a4 i1ie i3i4g i1im i1in i1i4s i2is. ii3t i1j 2i1k ik1ak ika4ka ik1amt i2k1ano ikanten8n ik1anz i4kanze ik1art ik3att i2k1au i2k1är 4ike i2k1ei ik2e2l1 i2k1e4r2e ik1erf iker6fah i2k1er2h i2ker2l i2k1eta i3ki. ik1in i2kind i2k3l i3kla i3k4lä i2kn ik3no ik2o3p4 iko1s i2köl ik3ra ik3rä ik3re iks2 ik3so ik3sz ikt2e ikt3erk ikt3r ik2tre i3kus i1la i2l3ab il1a2d i2l1ak i2l3a2m il1ans il1asp il1au il4aufb il3aus i2laut i1lä1 6ilb il2c il2da il4dac il4d3en4t il3d2er ild1o il2dor il2dr il1e2c il1ein il1el i4lents i2l1erf i2l1erg i2l1err il2erz il2f3l il2f3re ilf4s3 ilg2a il2gl ili3e4n1 ilig1a2 ili4gab i2l1ind i2l1ip i3lip. i3lips 2ill. il3l2a il3l2er ill2i 2ills il2mak il4mang il2m3at il2m1au il2min 2ilo i2l1or ilt2 il3th il3tr i1lu2 i2lum ilung4 i3lus ilv4 il2zar ilz3erk 2im. i2manw i2m1arm im4at ima2tr imat5sc ima4tur 2ime i2mej i2mele i2melf i3men i2m1erf i2m1erz i4mesh imes3s i2meti i2m1inf i2m1ins im2mei im4m3ent 1immo 2imo im1org imp2fa 1impo imp4s im3pse 1impu im2st im3sta 2imt imt3s2 2imu in1a2c in3ach. i4nack i2n1ad in2af in3am i3nap in2ars in2art ina4s i2n3au in1äh in1äs in2dal in2dan in3dau 1index in3do 2indr ind4ri in3drü 1indus in3d2ü 2ine i2n1e2be in1ehe i2n1eng in3erbe i4nerbi in2erh iner4lö i4n3er4tr i4nesk in1eu ine3un ine2x in3f 1info. 1infos 2inga ing1af in2g1a4g in2gl ing4sam ings3pr 1inhab 2inhar 2inhau 4inhe in2i3d i3nie 2inig ini3kr in2ir 2inis ini3se i3nitz 3inkarn in3k2ü inma4le 2inn. in4n3erm 2innl in2nor inn4sta 1innta 2ino in1od in3ols in1or ino1s4 ino3t i1nö in1ö2d 2inp 2inr ins2am insch2 in2seb 2insen ins3ert in3skan in3skr in4s3tät in3stel ins4tip in3su 1insuf in4s3um in3s2z 2inta 1integ int2h in3t4r in5tri int3s in1u i3n2um in3unz invil4 i1ny i1ñ 2i1o io1c io2d i2oda io3e2 iof4l i2o3h io2i3d io3k4 i3ol. i3om. i3oms ion2 i3on. ional3a io2n3au ion3d i3ons3 ion4spi ion4stä ion3t i2ony i2o1p io4pf i3ops i3opt i2or i3or. i3orc iore4n i3orp i3ors i3ort io3s2 i2ost i3ot. i3ots i2ou i2ov io2x i3oz. i1ö2k i1ön i1ös. 2ip. i1pa i1pe ipen3 i3per iph2 2i1pi ipi3el ipi3en i3p4l ip2pf ip2pl ip3pu i1pr 2ips 2ipu 2i1q i1r2a i3rad 1i2rak irat2 i1rä ir1äh ir2bl ir1c ir2e i3ree 2irek 2iré ir2gl irg4s ir2he ir2i 2irig 2irk ir2k3l irli4n ir2mak ir2mau ir2mä ir2m1ei ir2mum ir4m3unt 2irn ir2nar ir2no i1ro 1iron iro2s i1rö irpla4 irre4l irr2h ir4schl ir4schm ir4sch3w ir3se ir3sh ir2st irt2s3t 2iru iru2s1 i3sac i4s1amt is2ap is3are i2sau i2s1än 2isb i2sca i3s2che i4schef i4sch3e4h i4sch3ei i4schin i5sching i2sch1l isch3le i2schm isch3ma isch3ob isch3re isch3ru i4schwo isch3wu i2s3cr 2ise ise3e ise3ha ise3hi ise3inf i4seint ise2n1 ise4n3a is2end isen3s i2serh i2s1erm iser2u i2s1ess i4s3etat is2has isi2a i2s1id i2s1of iso2n isonen4 iso6nend is1op 3i2sot is1pa i2spar is1pe is1pic is2pit is2por i2spro is3sa is4s1ac is4sau is4s3che is4sper is2st is3sta is3sto iss3tr is3stu is2sum is3t is4tab ist3ac is5taf is4tam ist2an i1s4tat iste4n istes3 i1s4teu i1s4til is4toc is4tö is5tör ist4ra ist3re i1s4tü isum3p i2sü i1ß iß1ers it1ab. ital1a it1alt it1a2m it1an it2an. it3a4re it1art i3tat it1au i3tauc i4t1ax 4itä i2t1äs ität2 i2t1ei i4teig it2eil i4tein 2itel ite2la ite4n iten3s2 i4tepo i2tex i5thr i2t1id 1itii iti4kan iti3k2e i2t1in1 it2inn ition4 i6tl itmen2 i5toc i2t1of i3tö it3raf it3ran it3ras it3rau it3räu it3re it3rom it4ron i3tru it3run it2sa its1a4g it2s1e4 its3er1 it2so it2s1pe it2s3to it2teb it4tri itt2sp it1uh i2t1um i2tuns it1urg itut4 i3tü 2itz it2zä it4z3er4g it2z1w 2i3u2 ium1 i1ü 2i1v i2v1ak iv1ang i2veb iv1elt ive4n iv1ene i2v1ent iv1erl i2v1ur 2i1w iwur2 2i1x i2xa ix2em i3xi ixt2 4i1z iz1ap iz1au iz2ei izei3c ize2n i2z1ene iz4er i2z1ir izo2b i2zö i2z1w í1l ja1c jah4rei jahr4s ja3l2a ja3ne jani1 jani3t4 ja1st 2jat je2a jean2s je1c je2g jek4ter jektor4 jek2tr je3na je2p je4s3t je2t1a je2t3h je2t3r jet3s2 jet3t je2t1u2 je3w ji2a jit3 ji2v joa3 jo2b1 job3r jo2i joni1 jo1ra jord2 jo2sc jou4l j2u ju2bl jugen2 jugend3 ju2k jung3s4 ju3ni jur2o jus3 jute1 2j1v 1ka 3ka. k1a2a ka3ar kab2bl ka2ben 2kabh 2kabla 2kablä 2k1a2bo ka3b4r 2kabs 2k1abt ka1c k2ad 2k3ada 2k3a2dr ka1f4l ka1fr kaf3t2 k2ag ka1in ka3ka kaken4 ka1k4l 2kakt 2kala. ka2lan ka3lei ka3len. ka4lens kal3eri kal2ka kal2k3l kal2kr k1all kalo5 kal2tr ka2lu k3ama kamp8ferf kan2al ka4n1a4s ka2nau kand4 2kanda kan2e 2k1ang kank4 2kanl 2k1anna k1ans k2ans. 6kantenn ka3nu3 2kanw k2anz. ka2o 2k1apf 3kara 2karb k2ard k2arg ka3ri kari3es k2ark 2k1arm karp3 kar2pf k2ars kar3t k2arta 2k1arti karu2 k2arw 3kas ka3se kasi1 kas3s ka2s3t ka3tan ka3t4h ka4t3r 2katt kau2f1o 4kaufr kauf4sp kaufs5te k1aus kau3t2 2kauto 1kä k1äh k1ä2mi k1än kär2 kä2s1c käse3 2k3b2 kbo4n kbu2s kby4 2k3c 2k3d2 kdamp2 2k1e1c k1eff kefi4 kege2 ke2gl ke2he. kehr2s kehr4s3o 2k1eic 2k1eig k1ein ke1in2d 2keinh kei1s 2k1eise keit2 ke2l1a ke3l2ag ke2lä kel3b4 2ke2lek ke2len ke2l1er 2kelet kell4e kel3s2k k4elt 2k1emp k2en. ken3a ke4nac ke2nä kend4 ken3dr 4ken4gag 2kenlä ke2no ken4sem kens2k ken5stei ken3sz k3en4te. k3en4ten ken3th 2k1ents 2kentw 2kentz 2keo2 ke2pl k2er. ke1rad k2erc ke3reig 4kerfah k4erfam k3ergeb ker6gebn k3er2hö ke6rin6nu kerin6st kerin4t ker4ken k2erko k2erl k4erl. ker4lau k3er4leb k6erlebe k4erlö ker4neu k1ero ker4reg k2ers. kerz2 k1erz. ker4zeu 2k1er2zi k6es. ke2sel ke4t1a ke2t3h ket3s ke1up keu6schl 2k1e2x 2k3f4 2k1g2 2k1h4 kho3m ki3a4 ki1c 2k1i2de ki3dr ki2el kie2l3o ki1f4l ki1f4r ki3k4 2kil2a ki3lo k2imi k2in. k2ing 2kinh k2ini k2inn ki3n4o3 kin3s 2k1inse 2k1int ki3or kio4s 3kir kis2p kis3s kist2 kis4to kiv2 2kiz ki3zi 2k3j 2k1k4 kl4 4kl. 4kla. 4kland k4lar 4k1last k3laug k2le 4kle. kle2br k3lee 4kleh k4leid 4k3leit k3lem. 2k3ler kle2ra 2k3leu kle3us 2klic 2klig k2lim k2lin k2lip k2lir k2lisc 2klist klit2s 4kliz 2k3loc klo2i3 k3lor 2klos. klost6 k2löt k1lu k2lud kluf2 k2lug klung4 k1lüc 2kly 2k1m k2n2 3knab k3ne k4nec k4nei 2knes kno4bl 2k5nor k3nu 3knü 1ko ko2al 2kobj 2k1o2fe koff4 koh3lu ko1i2 kol4a ko3le kol2k5 3kom ko4mu k2on ko3n2e kon3s4 ko3nu 2kop. ko1pe kop4fen 2kops 2kopz ko1r2a 2k1orc kor6derg ko3ri kor4n1a k2os ko2sp ko3ta kots2 kot4tak 2k1ou 3kow ko2we k1o2x 1kö kö2f k1öl 2k1p2 2k3q k2r4 2k3rad k4ral k3rats 2kraum k4raz k4räc k4rän 2k3rät 2k3räum 2kre. 2k3rec 2kred. 2k3rede 2k3ref 2kreg k3reic kre1i2e4 kreier4 k3reih 2k3rh 2krib 2k3ric k3ries 2krip 3kris 3k4ron 2kruf krü1b 2k1s k4s1amt k2san ks4ana ks3ar k2sau k4s1äl ks2än ksch4 ks1e2b k2sent ks1erl k2s1ers k2s1erw ks3ha k3shi k2s1id k2s1in k2s1o2 ks1pa ks2pat k3spe ks2por ks2pu ks3s2 kst4 k2stal k4s3tanz k3stat4 k2stea ks2ti k2stor k2strä k2stum k2s1u ks2zen 4k1t k2t1ad kt1akt k3tal kt1am kt1an k2t3a2r kta4re k2t3au ktä3s kte3e kt1ei k2temp k2tent k4t3erfo k2t1erh kte3ru k2tex k2th kt3ho k2t1id kt1im k2t1ing kt1ins ktion4 kti4ter k2t1of k3top k4torga kt3orie kt4ran kt3ras k4tref kt4ro ktro1s kt3run kt3s2 kts4t ktt2 k2tuns k3tü kt3z ku1c ku2h3 2k1uhr kul2a ku3l2e ku3l2i 4kulp 2k3uml kum2s1 k2u3n2a kung4 kun4s4 kunst3 2kunt 2kunw 2k1up. kur2bl ku2rei kuri2e kuri4er ku2ro kur2sp kur2st ku4schl ku2sp kus3t ku2su 1kü kü1c kür4s 2k1v 2k1w 2k3z2 kze3l 3la. 3l2ab. la3ba 2labb lab2br 4l3aben 2labf 2labg 2labh 4l1a2bl lab2o l2abr lab4ra lab4ri 2labs l1abt 3labu 2labw la1ce la2ce. 1lad lad2i l1adl 2ladm 2l1a2dr 3ladu l1adv 2laf la2fa laf3s laf3t la2ga la2gio la2gn lago2 la2g1ob lag3s2e 2la1ho 1lai la2kes la2k1i l2akk la1k4l 2l1al 4lalp l2ami la3min 1lammf l2amp 4l1amt lamt4s la4mun l1anal la2nau 2lanb 5l2and lan2d1a2 lan4d3au lan6d5erw lan6d5erz lan2dr lan4ds laner2 2lanf lan2gl lang3s4 2lanhä l2anhe 2lanl 4lanli 2l3ann l1anp 2lans2 4lansä 2lantr lan2z1w 3lao 2l1apf l1a2po2 lap4pl la2r1an la2r1ei la4rene 3l2ar3g lar3ini l2armi lar3s 2l1ar3t l3arti la2ru la2sau 4lasd la3se 3lasg 2lash 2lasi la2so 2lasp 3lasser last1o lat2a la3t2e la4tel 2l3ath la2t3ra lat2s 2lat2t1a lat4tan lat4t3in lat2t3r 1laub. laub4se lauf1i lau4fin lau2fo 1laug l2aus. 2lausl 2lausr 2l1auss 2lauto 1law lawa4 lay1 lä1c 1läd 2läf 2l1ähn 2lämt 1länd lär2m1a l1ärz lä2s1c 4lät 2läub 2läuc 2läue 1läuf 1là 2l1b l3bac lbb2 l2b1ede lb3eise l4beta l2b1id l2b1ins lb2lat l3blä lb3le l2bli l3blo l3brec lb3rit lb2s lb3sa lb3se lb4sh lb3si lb4sk lb3sp lbs6t lbst1e lb4sto lb2u l2b3uf lbzei2 2l1c l3che l4chei l5chen l3chi lch3l lch3m lch3n lch3r lch3ü lch1w l3cl 4l1d ld3a2b1 l3d2ac ld3a2ck l2d1a2d lda4g l2d1ak ld1al l3dam ld1amm l2d1a2n ld3ane l2d1a2r ld3ari l3das ld1au ld1är l3de. l2deh l2dei l2dele l3der. l3d2erl l3d2ern l2d1er2p lder4tr l2d1e2se l2dex l2d1id l2d1im l2dob ldo2r ld2os ld2ö2 ld3r l2dran ld4ros l3d4ru ld4rü ld3sa ld3st ldt4 ld3th l2d1um 1le 3le. le2a le3an le3ar leben4s3 le2bl 2lec lech5t4e 3led 4ledd le2er lef2a le2g1as le2gau le2gä le2gl leg4r 3leh leh3re 4lehs 4leht lei4bl lei2br l2eic l2eid 4l1eig le2im l2ein. l2eind lein4du l2eine lei6nerb 4leink l2eint l2einu lei6schw leis6s5er l4eist lei4ßer l2eit lei2ta lei8t7er8sc lei5tri leit3s2 lekt2a 2lektr 3l2ela 2le2lek l2eli lel3s 3lemes le2m1o2 4lemp lem3s l1emu l2en. le4nad le2nä 4lendet 2lendu 4lendun le4n3end 4lenerg l1engl le3ni l2enk 2l1enni le2no len4sem len3sz 2lentf l1ents 2l3entw lent4wä 5lentwet len2zi le1os 2lep 3lepa 3lepf 3lepr l2er. l2e1ra le2ra4g le2rap le2rau lerb4 l3erei4g ler6eign le4r3ei4m le4rers 2l1erfo l2erfr l2erfü l3ergeb 3lergeh l3ergen 3l4ergew 2l1ergi lerin4s lerk2 l2erka l2erko l4erlei le1ro le2rob 2l1erö 3l2erra l4ers. lers2k lers2t l4erwa 2lerwo 2l1erz l2erza ler2zi les2am les2e 2l1esel le3ser le3sh lesi1 le3sk les2ko le2spo les2t leste3 le1sto 4lesw 2lesy le2tat 2le3th let4tu le2u 4leud 2leuro 3leut 2lexe le2xis 2lexz 2l1f l3fah lfang3 l2f1ec lfe1e l4feis l3f4lä lf3lo l3f4lu lf3ram lf2s lf4spe lf2tr lf4u lfun2 lfur1 l3fü 2l1g lg1art l3gas lga3t lg1d4 lgen2a lge3ra lgeräu3 l2geti lg2lö l3go lg3re l3gro 2l3h2 3lhi. 1li 3lia li3ac li2ad li3ak li3ar lia1s lib4 libi3 li1c li3chi 4lick li2cka lid2 li3da 2l1ido li4ds lid3sc l2ie 3lie. liebe4s li3ene lien3s lie2s3c lie2st 3lig lig4n li2gre li3ke lik2sp lik4ter li3l lil2a li3m2a 3limo 2limp li3n2a lin3al 2l1indu li2nef li2neh li2nep li2nes 2l1inf lings5 2l1inh 2l1in1it 2l1inj lin2k1a link2s li2nol l2ins. l2insa l2insc 2linsp 2linst 2l1int li1nu l1inv 2linz li2o li4om li3os. li2p3a 3lipt 3lis. li3s2a li4schu 2l1isl 2l1i4so li2sp liss2 lit2a li2tal li3te lit2h lit1s2 lit3sz li3tu 3liu liv2e livi1 2lixi li2za lizei3 4l1j 2l1k lk1alp l3k2an l3kar. lken3t lk2l lk3lad lk3lic l2k3lö l3k4lu l3k2me lk4ne lk5ner lkor2b1 lk4ra l2k3ru lk2s1 lk3sä lks3t lk4stä lk2ü 4l1l ll1abb lla4ben l2labt ll1akt l3l2al l2l1am ll3a2ma lla2n ll2anw ll1anz l3l2ap ll1arm ll3aug ll1aus l4lausf ll1äm llb4 llch4 ll3d4 ll1ech l2l1ef ll1eim ll2em l3len. lle4n3a llen3dr ll3en4du ll2eng l4lents l3ler. lle2ra l6lereig ller4fo ller6geb l6lergen l4lergo ll3ernt ll3ertr ll2es l2lex llf4 llg4 llik4 ll1imb ll1imp l2l1ind ll1ins llk4 ll3l2 ll5m lln2 ll1ob l2lobe l2l1of ll1opf l2l1o2r l3lor. l3lore l2l1ou l3low ll3sä ll3sh ll3s2k ll2spr ll3t llti2m ll5t4r llts2 llu2f ll1ur llus5t6 ll3z2 2l1m l3ma. l2m3a2b l2marc lm1art lm1äst lm1c lm2ei lm3eins lme4na l2m1e2p l2m1erz lm1ind lm1ins l2möl lm3p lmpf4 lms2t lm3ste lm3s2z lm3t 4ln lna4r ln3are lnd2 l3n2e l3ni l1nu l1nü 1lo lo4ak 3l2ob. lo2ber 2lobj 2l1o2bl l2obr lob4ri l1o2fe lo1fl lof4r lo2gau lo3h2e 2l1ohr loi4r 3lok lo2k3r lol2a l1o2ly lo2min lo2n1o lo2o 2lopf 2lopt lo1ra lo2rak lo4rä 5lorb 2lorc l1ord lo3ren 2l1or3g2 3lorq 3los. lo4sa 3lose lo4ske lo2spe loss2e lo4ste los3t4r lo2ta lo3tha loti4o 2l1ov lo2ve 2lox 1lö lö2b3 2löck 2löd l2ö2f 2l3öfe 4lög l1öhr 2l1ö4l3 4löß 2l1p l3pa lpe2n3 lp2f l2p1ho lp3t4 l3pu 2l1q 2l3r2 lrat4s lre1s lrut4 lrü1b 4l1s l3sac l2s1a2d l3s2al l4s1amb l4samt l2sang l2sann l2sanz l3sare l2sau ls2äm l4schin l4schmü l2s1e2b l2s1ec l2s1em ls1ere ls1erg l2serh ls1erl l2s1ers l2s1erw l3s2ex l4s3ha l2s1id l2s1imp ls2log ls3ohne l4s3ort. ls2ö l2spac l3s2pi ls2po ls2pu l3spul ls3s2 lst2a lstab6 ls4taf l4s3täti l2ste l3stec l3stei l3stel l4stem ls6terne ls6terns ls2tie l2stit ls4tr ls2tu ls1um l2sun 4l1t l2tab ltag4 lt1ak lt1am l4t3ame lt3and lt1ang l4tarm lt1art l2t3ato l2t1au lt1eh lt1ein l2t1eis l4te4lem lt2en lten6gel lter3a lter2f lt2erg lter6ken lter6leb lter4nä lt2erö l4t1e4sk lte2th l2t1eu l2th l3thas lt3ho l3thu ltimo4 l2tob l2t1of l2t1o2ri lto2w l3tö lt1öl lt1ös lt1öt ltra3l lt3räu l2t3re lt4rie lt3roc lt3ros l2t3rö l4ts lt2so lt4stab ltt2 lt1uh l2t1um ltu4ran ltu2ri l3tü lu1an 4lu4b3 luba2 lubs2 lu2dr lu2es 1luf 2l1ufe 2luff luf2t1a luf2t1e luf2tr lu2g1a lu2g1e2b lu2gi lu4g3l lu2go lu2g3r lug3sp lu2gu 2l1uh lu1id. lume2 2lumf 2l1umj 2lumk 2luml 2l1ums l1umw 1lu2n 2l1una 2l1unf lung4sc 2l1uni 2lunt 2lunw 4luo 2lur l1urn l1urt 2luse lu2sp lus4s3a lus2s1c lus6serf lus6serk lus6sers lus2s1o lus2s1p lus2s3t lus4stä 1lu4st lus4t1a lust3re lu2s1u lu2t1a lu2tä lu4teg luter2 lu4t3erg lu2t1o2f lu2top lu4t3r lut5schl 3lux 2lüb 5lüd lüh1l 2l1v 4l3w 2lx 1ly ly1ar ly3c 2lymp 3lyn ly3no ly1o ly1u 2l1z l2z3ac l3z2an l2z1ap lz1ar l2z1är l3zen lz2erk lz1ind lz3l lzo2f l2zö lz3t2 l2z1u4fe lz1w lz2wec 1ma m1ab m2abe 2mabk 3m2ab4r 2mabs ma3chan mach4tr ma2ci ma3da m2ade 2madm ma2d4r ma4d2s ma1f ma2ge. ma2geb ma2gef ma2geg ma2gek ma2gep ma4ges. ma2get ma2gev ma2gew 2m1agg magi5er. magi5ers ma3g4n 2m1ago mai4se 2m1akt mal1ak ma4lakt ma2lan ma4l3at ma2lau ma3le mal2er mali1e mal3lo 2mallt malu4 ma2l3ut mam3m 2m1anal ma2nau 2manb man4ce. man3d2 man3ers ma2net m2anf 2m1angr m2anh 2manl m4ann 2mansa 2mansä 2mantw manu3 2manz ma2or 2m1apf m2app 2marb mar3g2 ma3r2i 4ma3r2o maro3d 4marr mar6schm mar6schr ma3r2u m1arz 3mas ma3s2pa 4m1aspe massen3 mas4tel ma1s4tr 3maß ma2ta2b ma2tan mat4c ma2tel ma4t3erd ma5tri mat3se mat3sp mat3url 2m1au2f 3maul ma3un 2mausg m4ay ma1yo 1mä 2m1ähn mä1i2 2m1änd 2mäo m1ärg 3mäß mä3t4r mäu2s1c 2m1b2 mbe2e mb6l m3b4r mby4t 2mc m3ch 2m1d md1a m2d1ä m2dei mds2e m2d1um 1me meb4 me2ben m2e1c medi3 medie4 medien3 2medy me1ef mee2n1 mee4r3ei mega1 3meh 2m1eif 2m1eig mei3l2 mein4da me1i4so 3meist me3lam me2lau 3meld me2lek me2ler melet4 2melf. mell2 mel2se mel5t4 6mel6tern 2m1e2mi 2m1emp m2en. mena2b me3nal men3ar men3au 2mendl men3ge m4ens men4sk men2so men3ta men6tanz 2mentn ment4sp 4m3entwi me1o 2meou 2meö 3m2er. me1ra mera1f me2r3ap me4rens mer2er 4m3ergän merin4d merin4t m4ersh merz4en 3mes mes1a me2sal me4sä 4meser 2me3sh 4m1essa mes6ser6g mes2s1o mes2s1p mes2st meste2 me1sto 4mesu m2et me3t2a me3th meu1 2m1ex 1mé 2m1f4 mfi4l 2m1g2 2m1h4 1mi mi2ad mi3ak mibi1 mi1c mi3da mie3dr mi2e1i mie3l mien3s mi2er mierer4 mi4et mie4ti 3mig mi2kar mi2ki mi2ku mi3l2a 3milb 3milc milch1 mil4che mild4s 2m1imp minde4s min2en min2eu min2ga ming3s4 mi3ni min2o mi1nu 3minz mi2o mioni1 3mir. mi3ra 3miri 3mirs 3mirw mi2sa mi4scha mi4schn mi4sch3w mise1 mi2ste 3mit mi2ta mi2th mi2t1r mit3s2 mit5sa mi5tsu mi2t1u 4mitz 2m1j 4m1k4 m3ka mk5re. 4m1l2 ml3c ml3s 2m1m m2mab m2m1ak m2m1al mm1ang m2m1ans mm1anz mm1art m2m1au mmd2 mm1ein mme4lin mme4na m4mentw mme2ra mme4rec mme2sa mm1inb mm1inf mm1inh mm1ins mm1int mmi3sc mmi1s4t m2m1ö mm3p2 mmpf4 mm2s mm3si mm3sp mm3sta mm3str mm3te m2mum mmül2 mmüll1 2m3n2 m4nesi 1mo moa3 2mobj 3m2od mode3s mo2dr 4mog. mo2gal 3moh mo2i3 mo2k1l 3mom mom2e 3m2on mo2nä mo3ne mo4n1er mon2s3 mon3su 3mo2o 2m1ope 2mopt mo1ra mo2rar 2m1orc mor4d3a mor2dr mo2rer morgen5s6 3mos mo3s4ta moster4 3mot mo3ti m1o2x mo1y 1mö mö2c 4mök m1öl 4m1p mpa3ne m2pf mp4f3erg mpf3erp mpf3err mp4f3erz mp2f3l mpf1or mp1hos m3pi mpi3as. m4p3lem. m2p3len m2p3les m3pon mp3ta m3pu 2m1q 2m3r2 2m1s m2san ms3and m4sap ms1as m2sau m3sä m3sc msch2 m4sco m3se m4s1ef ms1erw m4sex ms1ini mso2r ms1ori m2spä m2sped ms2po m2spot m2spro ms2pu ms3s2 m4stag m3stel m3s2ti m3sto ms4tr ms5trä ms5tren m3s2tu ms4tü m2sü m3sy 2m1t mt1ab mt1ak m3tam mt1ar mt3are mt1ein mt1elt m2t1erf m4t1erg m2t1erl m2t1ers m2t1ert m4t1eta m2t1eu m2th mt3ho m3ti m4t1im m4t1ins m4tint mti2s mtmen2 m3tö m4töl mt1ös m2trö m4ts1 mt2sa mt2se mt3s2ka mt2spr mt4s3tät mtt2 mt1um mt1urt m3tü mt3z 1mu mu1a mu3cke 2m3uh mu3la 2muls 3mun mun2d1a 4m3unf 4m3ungeb mu3ni m4unk m2unr munt2 4munz mu3ra mu4r1u2f m4us 3mus. mu4s1a 3musc 3musi mu2s1o mu2sp mus3t mu2su mut1au muts3t mut4str 1mü 2müb 3müh mü2her mül4len 3mün 3müt mütter3 2m1v mvoll1 2m1w2 mwa2 mwa4r mwel4 mwelt3 mwu1 1my my4s 2m1z 1na 3na. 2n1ab na2bä 4nabg 4nabh na2bl n2abo na2br 4n3abs 4nabt 3nac na2ch1 na3chen nach3s nach8ters nacht8raum 4nadd n2ade 4n1a2dr n1af na1f4r 3n2ag na2gem 3n2ah na2h1a n4ahm n3ahn 3nai nai2e n1aig 2n1ak na2ka 3nako n2al. na2l1a2 na4lal na2lä 3n2ald n4ale na4lent na2let nal3l2a nalmo2 na2lop nal2ph n2als. nal3t4 na2lu 2naly n4am. 3name na3me. n4amen namen4s3 4n3a2mer na3m4n 3namo 2n1amt namt4s 2n1an. 4n1a2na 4nanb n1and2 4n1ang 2nanh 2nani 4nank 2nanl 3nann na3no n1anp 2nanr 4n1ans 2nantr 2nanw nap2si n1ar 5nar. na2r1a 2narc n2ard 4narg 3nari n2ark n2arle 2narm 4nart n3arti na3r2u 3nas n2as. na4schw 4nasp 4n1a2sy nasyl2 3nat n4ata n3a3t4h na4the 4n1atm nats1 nat4sa nat4sc 4natt n1au 4nauf nauf4fr n3aug 5naui 3n2aul 4nausb 4nausg n2auso 4nauss 4nausw navi5er. navi5ers 1nä 3n2äc 3näe 2n1ähn 3näi 2n1ä2m 2n1än när4s5 n1ärz 3näs nä2sc n2äss 2näu 3nä1um 2n3b4 nbe2in nbe3n nbe3r2e nbes4 nbu2s nby4 2n1c n3ce2n3 nch3m n2ck 2n1d nd2ag n2d1ak n2danl nd1ann n2d1anz ndat2 n2d1au nd1c nde4al. n2dei nde4län n4dentl n4d3ents nder6läs nde4rob nder5ste nde2se nde4spe ndi2a3 n2dob ndo2be ndo1c nd1op nd1or ndo2ri n2dö n2d3rat n2d3re n2drob nd3rol n2drö n2d3run nd2sor nd2spr nd3th nd3ti ndt4r n2duns ndy3 1ne 3ne. ne2ap ne3at ne2bl 2n1ebn 2nec 3neca 3ned 2nee3 ne2e2i4 ne3ein n1ef neg4 2ne2he. 2nehen2 3nehm 4n1ehr 2n1ei 4neier 4neif 3neigt 4n3eing 4n3eink ne2ke nek3t4 ne2l 3nela nel3b 2n1ele 4nelek 4nelem ne3len ne3li 3nelk n2ell nel4la 3ne3lo 3ne3lu n2em. 2n1emb nem4e n1e2mi 2n3emp 2n1ems 3nen n4en. n2en3a4 ne2nä n2enb n2enc 4n1endb 4n1endd 4n1endf n1endg 4n1endh 4n1endk 4n1endp 4n1endt 4n1endw ne2n1e2b nen3ei nenen1 ne4nene n2enf 4nengb nen4ge. nen4gen 4nengs 4nengt n2enh ne2ni n2enj nen3k ne2no n2ens nens4e nen3sk 5n2en3t2a n1entb 4n1entl 4nentn 5nentr n1ents 4n3entw 4nentz ne2n3u n2env n2enw n2enz ne2ob ne1os 2nepf 2n1epo ne2pos n2er. ne1ra ne2rab ne2r3af ne3r4al ne2r3am ne2ran ne2rap ne2rau nerb2 4nerbe. 4nerben n1erbi nere2 ne2reb n1erf 4n5erfo nerfor4 2nerfü 3nergr n1erh 4n3erhö 3neri n2erj n1erk n2erli 2n1erlö ner4mit n2ern. n1ernä ner4neu 4n1ernt ne1rös n2erp 3n2ers. n3ersa n2ert. ne2rup n2erv 2n1erz 3n2es n4es. nes4c ne2sei ne2sev nesi1 ne3ska nes1o ne2sor ne2s1pa 4n3essi ne1sta nes3ti ne2tad ne2t1ak ne2t1an ne2tap n1etat ne2tau ne2th net3ha nett4sc n1e2tu net2zi ne2u neu1c neuer4f neuer4k neuer4s neuer4w neu3g 2n1eup neur2 n2ew 2n1ex 3nez 1né 2n1f nf1ak nfalt4 n3far n3fi nfi4le. nf4l nf5lin nf2o nfo1s nf4r nf3s nf2tan nft2o nf2t3r nft4st n2f1u 4n1g ng2abs n2g1ac ng1ad n2g1ak n2g3a2m n2g1and ng2anf ng1anz n2g1äl ng3d4 n3gef n2g1ein ng2en ngen2a n3ger nge4ram n4g3erse nge4zän ng3g4 ng3hu n2g1i2d n2glic n2glo n3g2loc n2gn ng3ne ng1or n3gra ng3rat ng3roc ngsa4g ngs3au ngs3c ng4s3e4h ngs3pa ng3ts n2gum 2n1h4 n3han n3har n3hau n3hä n3he nhe2r n3hu 1ni 3nia nib4l nich1s nicht5er nich8ters n1id 3n2id. ni2de ni3dr n4ie nie3b ni1el nie3l2a nie4n3 ni3ene ni1ero nifes3 nig2a 2n3i2gel 2niget nig3r ni2gre nig4sp 3nik ni2kal ni2kar ni3ker ni4k3ing ni3kl ni2kr 3n2il nim2o 4n1imp nin1 3n2in. n2in2a 4n3ind 2ninf 3n2ing4 4n1inh ni2nor 2n1ins n2ins. 4ninse 4n1int 2n1inv ni2ob ni3ok ni3ol n2ip ni3ra 3n2is ni4schw ni2s1e ni3se. ni2s1p ni3spi nis3s4 ni2s1u 2nit ni2ti nit4r nitts1 nitt4sa ni3tu ni3v 3nix n1j 2n1k n2k3ad n2k1ak n3k2al n4k3alg nk2am n2kans n2k3aus n2käh n2k1äp nke2c nke4lei n3k2er n4k3erfa nk4erg nk1inh n2k1ins nk3len nk3les n3klin nk2lo nk4na n2k1ort nk2öf n2köl n2k3ro nk2s1al nks2ei nk3s2z nk2tak nk2tan nkt1it nk4top nk2tru n2küb 2n3l2 2n3m4 nmen2s 4n1n nna2be n2nada n4n1all n2n1an n5nat n2nau nn3d nn4ens n4nents nner4fü nn2erh nn2erk nne2rö n4n3er4wa nner2z nne2s1e nne4st nn2ex nn3f nng4 n3ni n2nof nn1o2r nn3sc nn3se nn3s2p nn4s3pe nnst4 nn2th n2n1uf n2n1unf nn1ur nnvoll4 1no 3no. no2bla n2o3ble 3noblo 2n1ob2s no1c noch4r 2no2d no3dr n1of 2n3o2fe n3ole no2leu n2on. 3n2opa 3nor. nor2a no2rad n2o1rak no3ral 2norc nor4da nor2d5r 3norh 3norm 3nors n1ort 3n2os. no3sh no2s3p n2oste nost1r 2nostv nos2u no3tab no2tä no4t1ei no2tel no3t3h no4tha no2t3in no2top no2tr 3nov 3now 2n1o2x 3noz 2nöd 2nö2f 2n1ök 4n1ö4l 1n2öt 2n3p4 npa2g npf4 npro1 npsy3 2n1q 4n3r2 nräu3s nre3sz nrö2s1 6n1s n2s1a2d n2s1all n2sang n2sant n3s2arg n2saus n2s1än n2s1äus ns2ca n4schl. n3schu nsch7werd ns1eb nse2ha2 nseh5ere nsen4sp ns1ent ns1erf ns1erg n2serh n2s1erk n2s1erö ns1ers n2s1erw n2s1erz n3sex nsfi4l n3sil n2simp n2s1ini nsinn4s nsi4te nsi2tr ns2kal ns2kel n2s1op n4s3ort. nsp4 n2spat n5s4pen n4speri n4spers n4sph n3s2pi ns4pie n2spo ns3pon n2sprä n4s3prie n4spro nsrü2 ns3s2 nst1ak n3star n2stas n3stat n4stat. n4s3tate nst3eif n3stemm ns4tent ns6terbe n5s6terne n5s6terns ns2ti ns4tic ns4tob nst5opfe ns4tor n4strac n4strie nst4ru ns4trun ns2tu nst2ü nstü1b n2sty ns2um n2s1un ns2ung ns4unr ns4uns n3sy n4s3zi 2n1t nt3abs n3t2a3c n3t2al nt1ang n4tanza nt2arb nt1ark nt4at nt1äm n2t1äu nte3au nte2b nt1ebe nte1e nte3g6 nt1eh nt1ein nte5lei nt2en nt4ene nten6te. n3ter nte4ras nt4erh nt4ern nt4ers nt4ert n4t1ess nteu3 nte3v nt2her n2t3ho n3t4hu nti3c nti3k4l n2tinf n2t1inh ntini1 n3ti1t nt4lem ntmen2 ntmo2 n3to nton2s1 n3tö nt3rec n5t4ree nt3reif n5trep nt4rig n5trop n2t3rü n4ts nts2o nt4spar nts2t nt2s3to nt3su n3tu 3n4tu. ntum4 ntu2ra ntu4re. ntu4res n3tü nt3z 1nu. 1nu1a nu4ale nu3ar nubi1 1nu1c 1nud 3nue nu2es nuf2 nu2fe 1nug 2n1uh 1nui nu3k4 n2um. 2n3umb 2numf 2numg 3numm 2numr 2n1ums 2n3umz nu2n 2nuna nunf2 1n2ung4 3nung. n3ungl 2n1uni 2nunt 1nuo 2nup 2nur 3nu2s nu3sc nu3se nus1i nu3sl 1nut nu2ta nu4t3r 1nuu 1nux 1nuz 3nü. 2nü4b nür1c 3nüs 1nüt 2n1v2 n3ver nvol7ler 4n1w 1ny. 1nyh 2nymu n1yo 1nyr 1nys 1nyw 2n1z n2z1a4g n2zan n2z1au nz1än n2z1är nzdi1s nze6l3a n4zense n4zentw n4zentz nz3erwe nzi2ga nzig4s nz1ini nz3le n2zor nz2öl nz3s n2zurk nz1wa n2z1wä n4zwir n2zwö n2z1wu ño1 2o3a2 o4abi o4ac oa3che oa3chi o4ad oa3de oa4g o4a3i oa3ke oa4k1l o4a3la o4a3mi o2as 3oa3se o4at o5au o1ä o1b ob2al obal2t1 2oban o3bar 2o3b2ä 2obb ob2e 2o3be. 2obea ob3ein obel2i 2o3b4en oben3d4 oben3se ober3in4 obe4ris 2obew 2o3b2i obi4t ob3ite 1obj ob1l ob3lei 1o2b3li 2o3blo2 2o3bo o2b3re ob3s2h ob3sk obs2p ob2sta ob3sz 2o3bu obu2s 2o3bü 2oby4 2oc o3ca oc1c o1ce och1a ocha2b o1che oche4b o2ch1ec och1ei ocher4k och3l och3m och1o och3ö2 och3r och1s ocht4 och3te o1chu ochu2f och1w o1ci o1ck o2ckar o3cke ock2er o3cki o2cko ock3sz o1cl o1ç o1d o3d2a od2dr o3d2e1i odein3 ode2n1 odene2 odesi1 ode3sp o3dex 2o3dia odi4er o3dir o3div o2don odo4s 2odr o2dre odt4 2o3du o3dy 2o1e oe2b o2ec oe2d oe2h oe2l oe2n1 o4es o2et o3et. o3ets oe2x o1ë 2ofa of1a2c of1au o2f1ei of2en o3fer of2f1a of2f1in 1offiz of2f3l of2fo of2f3r offs2 off3sh of2fu 2ofi of3l of1la of4lä of4lö 2ofo 2o1f1r of3ra of3rä of4rü ofs1a of4sam of2spe of2spr of2s1u 2oft of2tei of3th 2o1g o2g1ab oga3d og1ala og1ang o2g1ei oge2l1i o3gh ogi2er og2lo og4n ogo4i og3s2p og1ste o1ha o1hä o1he o2h1eis ohen3s o2h1er4t o2h1er2z o1hi ohl1a oh3lec ohl1ei oh3len oh3lep oh4lerg oh4l3erh oh4lerw oh3lo ohls2e oh2lu oh4n1ac oh3nee 3ohng oh2ni 1ohnm oh2n1o o1ho oho2la oh1o2p o2h3ö ohr3a oh4rin oh1ro oh1s o1hu oh1w 2o1hy 2oi o1i2d o3ie o1im oimmu4 o1in oi2ra oi2re o2isc o3isch. o1ism oiss2 oi1th 2o1j 2o1k oka2la okale4 3o2kel oki2o ok1lä ok2li ok4n 4okr ok2s1p okt4 2ol o1la o2lab o2l1ak ol2ar olars2 ol1auf o1lä ol4dam ol4dr ol1eie ol1eis oler2 ole3s ol1ex o1lé ol2fa ol2fl olf1r ol2fra olf3sp ol2gl ol2gr ol2i oli3k4 ol2kl olk3r ol2kre ol2lak ol2l1au oll1e2c ol2l1ei ol2lel oll5ends ol4lerk oll3erw oll3sp o3lo ol2of olo3p2 ol1ort ol2str o1lu 3oly 1olym ol2z1a ol4z3ern ol2zin ol2zw 2om o2mab oma4ner om2anw om1art o2m1au o2meb om1ebe ome3c o2m1ei o3m2eis o2mel o2mene o2mep omer2 o2meru om1erz om2es omiet1 o2m1ind om1ing om1ins o2m1int om3ma om1org om3pf oms2 omtu3 o4munt omy1 2ona ona2b o2nae o3nal on1ap o2narb on4at on2au 2onä on1äh onbe3 2onc onderer5 2one one4i one2n3 onens2 on1erb o2n1erd on1erg on1erö o3nett on3f2 on3g2l ong4r ong3s 4o3ni on2i3d o4nikr o4n1im on3ing on3k2 onli4 onlo2c on3n2an on3n2e ono1 o3nod o2noke on1orc ono3s ons1a onsa4g on4sam on2seb onse2l onsi2 ons3l ons1p onst2h on3t2a ont3ant on4t3end ont3erw on4t3ri o1nu 2onuk on3v 1ony on3z o1ñ oof2 oo2k3l o1op o1or oo4sk oos3s4 oo2su oo2tr 2o1ö2 o1pa opab4 o2p3ad op3akt o3pan opa5s o1pec o1pei o1pe4n 1oper 2opf. op2f3a op3fah o2pfe op4ferd opf5erde opf1l opf3la op1flü 4oph2 o3phe o1pi opi5a4 opi3er. opi5ers. opin2 op5lag o2p3le op3li 2o3po op4pl op2p3r 2o1pr 1opsi op3sz 1op3t4 o1q 2or. or1a or3a2b o1rad 2o1ral o2r3alm or4alt 3oram or2and o2ranh or3arb o1ras or3att o3rä or1änd or1ät or2bar orb2l or1c 2orca or2ce 4orda or2d3am or4dar or4dau or4d3eng or2deu or4d3ing or2d1ir or2dit 1ordn or2do 2ordr 2ords ord3s2t or2dum 2ordw 2ore ore2a ore2b o2r1e2ck o2r1ef ore2h or1eig o2rein or1er o2rerf or1eth o2r1eu 2orf orf3s4 or3ga 2orget or3g2h 2orgia orgi1e or2gl or3gle or2gn 2orh 2o3ric 4orie. o4rient o3rier 4oril 4orin1 or1ins ork2a or2k3ar ork4r ork2s 2orm or4mans or4ment 2orn or2na2c or2n3ar or2n3ä or5ne. or3n2o1 2o1ro or1o2b oro3n2a 2o1rö 2orp 2orq 2orr orr4a or3re or3rh 2ors2 or3sa or3sh or3sz or2t1ak or4t1an or2t1au or2tär or2tef or4t3ent ort2er or4t3ere ort3erf ort3erk ort5ersc or2t3ev or2the ort3ins or4t3off or2tor or4tö or4trau or4t3räu ort3ric or2t1um o3ru or2uf o4r3un o2r3ü o2rya 2o3s2a os3ad os4an osa1s o4sca osch3ar o3sche osch3le os4co 2o3se ose3e o2s1ei ose2n o4sents os2ex 2osh o3s2hi o1sho 2osi o3sk o4ska os3ke o4ski 2oskl 2os2ko os2lo 2oso 2os1p os2pe os3pec o3s2po os2sa oss1a2c oss3and os4sä os2sei os4s3en4k os4s3enz os2s3o os4son os2s3p os2s3t ost1a2b os4t3am ost3ang os3tarr osta4s ost1au os4tei oster3e os6t5er6we os2t3h os3til os3to os4tob ost3ran ost3rä ost3re ost3rot ost3uf 2osu4 os1um 2o3sy o3s2ze o2ß1el o2ß1en2k o2ß1enz o2ß1ere o2ß1erf 2o1t ota2go o3tark o2t1au ot3aug ot1ä o2teb o3tei o4t1eib ote1i4n ote3ine ote2l1a ote4lei ot2em3 otemp2 o2t1erw ote2s 4ot2h ot4he ot5hel o4t3hi ot3ho o2thr o2til o2t1i2m ot2in otli2 ot4ol ot1opf ot2or oto2ra oto1s o3tra o2t3re ot3rin ot2sa ot3sc ots1p ot4spa ots2pe ot2spr ott1a ot2tan ot2teb ot4terh ot4terk ot2th ot2t3r ot3t4ra ot4tri o3tü o2u oub4 ou2ce ou1f4l oug2 ou2ge ou3gl o3uh ou4le. o3um o3unds oun4ge. 2our ouri4 our4ne. ou3s2i outu4 2ouv 2o1ü o1v ove3s 2ovi oviso3 2ovo 2o1w o3wec owe2r1 o3wi o1x 2ox. ox2a ox2e ox3l o2xu 1oxy o1yo oy1s4 2o1z o3z2a oz2e ozen4ta o3zi ozon1 órd2 ö1b öbe2la öbe4li öb2l ö2ble ö2b3r öb2s3 ö1c öch1l ö2chr öch2s öchs4tu ö1d ödi3 ödien3 öd2st 1ödu ö1e 1öf öf2fl öf3l ögen2s1 ög3l ög3r ö1he öh3l2e öh3ri ö1hu ö3ig. ö3isch. ö1ke ö2ko1 ök3r ök2s 3öl. öl1a2 öl1ei öl1em öl4en öl2f1ei ölf3s öl1im öl1in öl2k3l öl3la öl2nar öl1o2 öls2 öl3sa öl3sz ö2l1u öl2ung ölz2w ö1m öm2s ön2e ö3ni önizi1 önn2e ön2s ön3sc ön3sp ö1nu öo1 öot2 öoti1 ö1pe öpf3l öp4s3t ör3a2 ör2b3l ör1c ör2dr ö2r3ec ö2r1ei ö2r1e2l ör2erg ör2erk örer2l ö3r2erz ör2f3l ör2gl ö2r1im ör2kl örn2e ör1o2 örs2e ör3s2k ört2e öru4 ö2r1une ö2sa ö2scha ö4sch3ei ö2schl ö2sch3m ö2schw ö2s1ei ö2sp ös2s1c ös2st ö2st ös3te ös2th ös3tr ö3su ö1ß ö1t ö2t3a öte4n3 öt2h öts2 öt2sc öt2tr ö1v ö1w ö1z öze3 özes4 p2a 1pa. 1paa 1pac pa3da pa2dr pa1f4r pag4 pa3gh pa1ho 1pak pa1k4l pak2to 3pala pala3t 1palä pa3li pal2ma pal2mä pal2m1o 2palt pa2nar pa4nat pan3d pan4ds pa2neu pank4 2panl 2pann 1pa2no pan3sl pant2 panz4 1pap papi2 papieren8 papie8r7end 1para pa2r3af par3akt 1parc pa5reg pa5rek 2par2er 2parg pargel6d 1park. par4kam par4kau par2kr 1paro 2parp 1partn 1party par3z2 pa3s2p pa4st 2paß pat1a pat4c pate2 1pati 1pa5t4r 1pau p3auf pa3uni 1pä 3pä2c 3päd 3pär 3päs pä4t1e2h pä4t3ent pä2t3h pä2to pät3s4 2p1b 2p3c 2p1d2 pda4 p2e 1pe. pe2a pea4r pech1 1ped pe2en pef4 pei1 2peic pe1im pekt4s 2peku 1pel pe2l1a4 pe4lein pe2let pe4leu pe2lex pe3li4n pe4l3ink pel3k pell4e pel3t 1pem pena4 pe3n2al pe2nä pen3da pe4nen 1penn pe2n1o 3pensi 1pensu penz2 1pep pe1ra per2an 1perle per4na 3pero per2r1a 1pers 2perse 2persi 3perso 1perü perwa4 pe3sa pes3s2 pe2st pes2th 3pet 1pé 4pf. p2fab p2fad p2faf pf1ai p2f1ak pf1ans p2fa4r pf3are p2f1au 4p3fe. p2fei pf1eim pf1ein p3fen. p2fent p3fer. pf2erw p3f2es pff4 p2f1in3s pf4lan p2f3lä pf4leg pf3lei pf3lo p2for pf3r pf1ra 3pf4ro 2pfs2 pf3sl pf3sz 2pf3t 2pfü 2p1g pgra2 1ph 4ph. 2phä 2phb 2phd 2p1hei phen3d phen3s 2ph1ers 2phf 2phg phien3 phi2ka 2phk ph2l 2phm 2phn p3hop 2phö ph4r 2phs pht2 2ph3the phu4s 2p1hü 2phz pi2a3 piap2 pias4 pi3chl p4id2 piegelei8 pi2el piela2 pie4lei 3pier 3pik 1pil pi3le pil4zer 2pind pin2e pingen4 ping3s 3pinse pi2o pi3oi pi3onu 3pip pi2pe pi3ri 3pirin 3pis 4piso pi3t2a pi1th pit2s 2pitz pi2z1in p1j 2p1k2 pku2 pkur1 1p2l4 4pl. 3p4la p5la. p5lad plan3g 3plä 2ple. ple1c ple2e p4leg ple5n2 2p3ler 2plig p4lik p4liz p4lo 2p3lu 2p1m2 2p1n 1p2o po3b4 po1c 3pod 2poh po2i po3id 3poin 3pok 3p4ol po2lau po3li po4lor 2pond po1o2b po2p3ak po2p3ar po1pe po2pl po3pt po1rau porf4 por3s por4tin por4tre por6tri pos2e po4sta pos4t3ag po4stä po2s3te post3ei po2sto pos6tr post3ra po3ta 3pote po2t1u po2w po3x pö2bl pö2c 2p1p p2p3a2b pp3anl ppe1e ppeli5ne ppe2n1 ppf4 pp1fr p2p1h p3p2ho p2p1ia pp3l pp1lä p2ple pp3oh ppp2 p2p3ra p2pri pp3sa ppt2 p2r2 1prak 1prax p4rä 1präd 1präg 3präm 3präs 2pre. 2prec 3pred pre2e1 1prei 3preis prei4s3c 2preiz 2p3rer 3p4res pri4e 2prig 3prinz pri2t1 priter4 2pritz 1p4ro 3prob 2proc 3prod 3prog 3proj 2pross pro1st 3prot 1prüf 2prüh 2prün 2p1s 4ps. ps4an p3se p3s2h ps1id p2sö ps2po p2st p3sta p3stea p3stel p3s2ti pst3re ps2tu p3stü 3p2sy ps2ze 2p1t pt1a pt2ab pt3alb pt3at p3te p4t3ec p4t1ei pte4l p4tele p4t1ent p4t1ep pt3erei p4t1erw p4t1erz p2th pt1in1 p4tos pto2w p2t3r pt3s2 ptt2 pt1um pt1urs ptü4 3p2ty pt3z 1pu pu1a pub4 2puc pu2dr 2p1uh 2puk pul2sp 2pund 3punk pun2s 2punt 2pur pu3ri pu2s3t 3put put2s 1püf 2pül 2p1v 2p1w pwa4r 3py1 pys4 py3t 2p1z qu4 que4te. 1queu 1ra. 2r1aa ra2ab 3ra3ar 3raau r1ab ra2bar rab2bl 2rabd r2ab2er 2rabf 2rabg 1r4abi ra2br 2rabs 2rabt ra2bü 2r3abw 1raby ra1ce 2r1acet ra4cheb ra4chin racht3r rach6trä ra2chu r2ack r2ad r4ad. ra2dam 2radap 3radf r3a2d3r rad5t4 1ra2e ra3er r2af raf3ar ra2fer ra3ge ra3gle ra2gn 3r2ahm 2raho 4raht r2ai 2raic rail4l 2r3air 3ra1k4l ra2kre ra2kro 2rakti 3rakü r2al r4al. ra2la2 ral3ab rala4g r3alar ral3b 3r4ald ra3le 2ralg r4ali rali5er. rali5ers ralk2 ral3la rall2e 2rallg 2r3alm. r3alp. 2ralpe r4als r3alt 2ralta r4al5t2h ra2lu 3raly rama3s ra2mer 1r2ami ram4man ram6m5ers ram4mu 2r1amt ramt4s r2an. ra5nat 2ranb r2anbe 4ranc r4anda r4ande ran4dep ran4d3er rand3s 4r3anei r4aner 2ranf 1rangi rani1e ran2kr 2ranl 2r1anm r2anmu 2r1anp 2ranr r2ans. r2ansp ran4spa ran2th 2rantr 2r3anw r2ap 2rapf ra2pri r1ar r2ara 2rarb 3rarei rar3f4 ra2r1in r2ark 2r3arz r2as r4as. ras2a ra4schl 2rasph 2raß 1rat r4at. ra2t1a rat2o rat4r 2r3atta 4ratz 4rau. 3raub. 4raud rau3e2n 2rauf 2raug 3raum rau4m3ag rau4man rau2mi 3raup 4raur 2rausb 2rausg rau2sp raus5se raut5s 1raü r2ax raxe3 3r2äd 4räf rä1fr 4räg 2räh 2räm 3rän. 3räni 3räns 2r1är r2är. rä3ra rä4sc 3rätse rä2u 4räue 4räun räu2s räu5sche 4räut 4r1b r2b1ab r2b1a2de r2bak rbal3a rba3re rb1art rb1auf rbb2 rb1ech rbeid4 r4belä r4belis r3ben. rb1ent rbe3r2e rber4gl rbla2d r2blan r8blasser r4b3last r3blä r2ble. rb3ler r2bleu rb2lin rb2lö rb2o rb4ri rb2s rb3se rb4sei rb3ska rbs1o rb3sp rb4stä rb2u rbu2sc rby4t 2rc r1ce r1che. r1chen r1chi rch3l rch3m rch3r rch1s2 rch3sp rchst4 rch3t2a rch6terg rch6terw rch1w r1ci r2ck r1cl r1ç 2r1d r3da r4dab rd2ac r4daf r4d1ak r4d1al rd2am rdani1 rd1ant rd1anz r4dap r2dei rd2ei. r4deis r2d1elb r3den rden3d rde3re rder4er rderin6s r4d3ernt rde3sp rdgas3 rdi3a2 rdia4l r2d1inn rd1it rdo2be r3don rd1os r2dö rd3rat rd4ri rdt4 rd3ta rd3th rdwa4 1re 3re. re3aler re2am re3at. re3ats 2reä re2b1a re2b1l reb1r reb3ra re2bü r2ech rech3ar 4rechs 2reck. re2cka 2recki 3red. 4redd 2redi re1el re1er 3refe 2reff 3refl 3refo 3reg 5reg. rege4l3ä 2reh re2hac re4h3ent re2h1i rehl4 reh3n re2h1o r2ei. r2eie 2reig rei3l2a rei3l2i 3reim reim2p r1ein 4reinb rei3nec 4reing r3eink 4reinr rein8s7tre re1in2v reister6 3rek 4re2ke re3la 2r1elb rel2e re3lei 2re2lek 2r1elf re3lo 2r1elt relu2 r4em. r2emi 4rempf 4remu r4en. r2ena rena2b re3nal re2nä 3rendi ren3dr re4n3end ren2gl 2rengp re2ni ren4nar ren3sau 2r1entg 2r1entl 2r1ents 2rentw 4rentz r2enz ren2zw re3or 3repe re4pis 3repo 4repp 3r4er. 2r1erb rer2bi r4erbil r2erbr 2r1erd r1erf r2erfe r2erfl r1erg r4ergen r1erk 4r3erken r2erki 2rerkl 2r1erl 5rerlag 2r1erm rer2n 2r1ernä 4r3erns 4r3ernt r2e1ro re2rob r1erö 3r2ers. 2r1ersa r2erse 2rersp r1ert r2erte 2rertr 2r1erz rer5ze r2erzy 3r4es. re2sa re4schw 3rese 3reso 2ress ress2e res6s5erw 3rest re1sta re2s2tu 3resu re2thy re2u reu3g2 2reul re3uni 2r1eur 2reü 2r3evid r1ew rewa4r re2wi 4r3e2x1 3rez 4rezi 1ré 2r1f r2fent rf2es rfi4le. r2flan rf3lic rf3lin rf4lö r3flü rfolg4s r3for rf4ru rf4rü rf2sa rf2s1ä rf4s1id rf2spr rf2s3t rf2ta rf3t4r rf2u 4r1g rg2ab r2g1a2d r2g1ah r2g1ak rg2an rge4an rge2bl rg2el rge4l3er rgen4z3w rge4ral rge4tap r2geto rgi4sel r3gla r2glan r2gleu r2glig rg2lö rg2lu r2gna r2gno r2g1ob rgö2 r2g1öd r2g3ral r2greg r2gres r2gret rg3rin rg3sp rgs2ti rgs4tr rg5s2tu r1h4 2rh. 2rha r2ha. r3hals 2rhä 3r4he. 2r3her r2hoe r3hof rho2i3 2rhol 2rhö 2rhs rhu2s 1ri ri3am ria1s ri3at rib2bl ri1ce ri1cha ri2dan ri2dau rid2g 2ridol 2ridy r2ie rie2fr ri1el ri3els riene4 ri3eni rien3s rie2nu ri1er. ri4ere ri3ers. ri3esti ri1eu ri2f1a ri2f1ei ri2f1er ri2f1o ri2fr rif3s rif4ter 3rig ri4gene 5rigj rig1l 4rigr rik1l ri4kla r2imb ri2me. 2rimp rim2s rim4sc r2i3na 2r1ind rin4dex rin4diz ri3n2e rine1i 2r1inf rin2fo rin2ga ring3l rin2gr 2r1inh 2rinit 2rink rin2kl 3rinn 6r5innenm 4r3inner 4rinnta r1innu 2rins 3r4ins. rin4so rin2sp r4inspi 2rint rin4teg rin4t5r 2r1inv 4r1ir r2is ris2a ri4scho ri4schw 3risik rismu2 ri3so ri4s1p 3riss ri4st ris6t5ers r2it r3i2tal ri3t2i ri3t4r rit2tr 5ritu rix1 1rí 2r1j 2r1k rk2am rk4ap rkauf4s r2käh r3kla rk4las rk4lau r2klis rk2lo rk2lu rk4n r2k5nu rk3räu r2k3rea r3kri rk2s1e rk2sp rkstati6 rk4stec rk2ta rk4t3eng rk4t3erf rkt3ers rk6tersc rk4t3erw rk4t3erz rk2tin rk2t1o2 rk2t3r rk3tra rk4tri rk2um rku2n rk1uni 4r1l rl2ab r5lag r5lan r2l1ar r2l1a4sc r2l3aug rl2e rle4a r3lec rle4i r3let r3l2i rli2s r3l2o rlös3s rl2s1p rl3ste rl2s3to rl3t r3lu rlz2 4r1m r2mab r3m2ag rma2la r2m1ald r2m1ank rm1ans rm1anz rm1a2p r2maph rm3d2 r2m1ef r2meo r2m1erp rm2es r2mide r2m1im r2m1o2ri rmo1s rm3sa rm3sta rmt2a rm2u rm3ums 4rn rna2b rna4n rn2and rn3ani r2n1anz rna2r rn2arb rn3are rn3ari r2nau rnd4 rn3dr r3ne rn3e4ben r4nef rn2ei rn3eif r4n3eis rne2n r4n1ene r4nerf r4n1erg rn4erhi r4n1ert rner4ve r5nes rn2et rne3uf r4nex rn3f rng2 r3ni r4n1in r3nod r2n1op r2n1or rn1ö rn3sa rn3s2ä rn3s2p rn3s2z rn3t2e r1nu rn1ur r1nü r1ny ro2bei 2robj 1robo 2robs ro1c 3rock. r2o3de ro3e4 roh1l 3r2ohr 3roi ro1ir ro3le rol4lan rol3l4en rol3s 2roly 4rom. ro2mad ro2mer 4romm 4romt r2on ro4nerb 3ronn rons2 ron4tan 4ro1ny ro1pe 2ropf ro3ph r1or r2ora ro2r3al ro2rat ro2rei ro2r1o ror3th ro3sh ro3s2i ro3smo ros4san ros2s1c ro3sta rost1r 4roß ro2ßu ro4tag ro2tä ro2tei ro2tho ro4tri rots2o rot2ta ro3t2u ro3unt 3rout rö2b3l rö2du 2rö2f 3röh r1ök 1röl 3römi 4röp r1ör r2ös. r2öse 3rötu 2r1p2 r3p4a r3p4e rpe2re rpe4r3in rpf4 r2pli rpro1 rps3t rp3t r3pu 2r1q 2r1r rr2ab rr2ar rrat2s rr1äm rrb2 rr1c rr2e rre4ale r5rega r5rei rre2le rre2pa rrer4s rre2st rre2ve r2rew rr2he r3r4hen rrik2 rr2n3a r3r2o r4r3ob rro3m rr2st rr3stu rr2th r3ru r3r2ü rrü1b 4r1s r2s1a2d r4samp r4s1amt rs2an r2s3ang rs3anp rs3ant rs2au r3sche r6scherl r3schu r3schw r2sein rse2n1 rs2end rse4ne rs1ere rs1erö rs1ers rs1erz rse2t rs1eta r3sho r3si r4sins rs2kal rs2kan rs2kie rs2kis rs2kl r4sko r4skr r4sku rs3l rs4no r3so r4sob rson4e r4s1op r4sord r4s3ort. rs2p4 rs4pel r2s3ph r5spi rs3s2 r4stant r5statu r6st5eing rs4temp rster2 rs4terb rs4t3erw rs2th rs2ti r3stie r5stim r2stin rst3ing r3stink r2stip r3sto rs4tob r4stot r3stö r3s4tr rst3ran r6strang r4strun rs2tu r3s4tü r2sumf r3swi r3sy 4r1t rt4abl rtal2 r2t1alm rtals1 rt1am rt1ang rt1ann rt1ant r2t1ar rt3a4re r2t3att rt1är rte1e2 rtei3la rt1ein rtei1s4 r2telf r2temo rte2n1 rte4na rten3s2 rt3erei r4terfa r4terfo rt1erh r4t3er4la rter6mit r4t3ernä rter4re rt1ers rte3s2k r2thi rt2hum r2t1id r2t1ima r2tinf rt4is rto1p rt1or rto2ri r3tö r4t3rak rt3rec r5tri rt3ros rtrü2c r4ts rt4s1eh rt2so rt2spa rt3t4 r2t1urt r3tü rt3z rtz2a 1ru ru1a ru3a2r3 rube2 ruch3st ru6ckerl ru2cku rude2a ru2dr 3ruf ru2fa ruf2s3 ruf4ter 2r1uhr ru1ins ru1is 2rum 4rumf ru2mi 4ruml r2ums. 4rumz 2r1una 2rund run2d1a r2unde rund3er run6derf run6der6l run6ders run6derw 2r1unf 2rungl 2r1u2ni 4r3unio run2kr 2r1unl 2r1unm 4runn 4r3unt 2runw ru3pr 4r3ur ru2ra ru2r1e 5ruro ru2si rus2s1p rus4st ru2st ru3sta 3rut ru4tei rut3h ru2t1o2 ru2t3r 4ruz ru2zw 1rü 2rüb rü1ben rü1ch rück5sta 4rümm rün3z 2r1v rve4n1e 2r1w r5wei rwun3s 4r1x 1ry ry2c rysti1 2r1z rz2an r2zar r2zas r3ze. rz1eck r5zene rz1eng r4z3ents r2z1erf r2z1erg r2z1erk r2z1erw rz1id r3z2of rz2ö rz3te rz2th rz2t3ro rzug2u r3zü r3zwä r3z2wec 1sa 3sa. 3s2aa 2s1ab sa2be 3sabet sa2bl sa3ble sa2br 4sabs 5sache sa2cho2 sach3t 5sack. 2s1ada s1adm 2s1a2dr 3safa sa2fe 2s3aff 3safi sa1f4r 3saga sa4gent sag4n sa2gr 3s2ai sa3i2k1 sail2 2s1ak sa2ka 3saki 3sakr 4sakt 3s2al. 4s1alar sa4l3erb sa2l1id 3salo sal2se 2s1alt 3s2alz 3sam s3ameri 5samm 6s1amma 4s1amn s1am3p4 sam2to s1an s2an. 2s3a2na s3anb s2an2c 3s2and s4and. san4dar san4dri 3sang. 2s3anh 3sani 2s3anl 2s3ans san4sk 4s3antr 2s3anw 2s1ap s2aph sa2po 3sapr 2s1ar 3sar. 3s2ara 4s3arb 3s2ard 3sari s3arr 3s2ars 4sarti s1asp 4s3a2sy 3sat sat2a 4s3ath 4s3atl 4s1atm sa2tr sa3ts sat4z3en s1a4u 3s4au. 3sauc 3saue sau8erste 2s3aufb sau2gr 3saum 3saur sauri1 2s3ausb s3ausw sa2vo 1sä s3ähn 3säl 4s1ält 2s1äm 2s1änd 2s1är 3s2ät 3säul 2säuß 4s3b4 sba4n sbe3r2e 1sc 2sc. 2scam s2cap 2scar 2s1ce 6sch. 2schak s4ch2al 4schanc 4schang 2schao s4chä 4schb 4schc 2schd sch2e 3sche. 6schef. 6schefs sch3ei. 4schemp 3sches 4schess 4schex 2schf 2schg 2schh schi4e s4chil 4schiru 3schis 2schk s4chl sch4lag 4schle. 6schlein 4schmas 2schmö 4schmüh 2schn. 4schobj 2schox s4chö 2schp 2schq 4schre. 4schrin sch3rom 4schron 4schrou 6schs schs2e sch3s2k sch3sta 4sch3t scht2a scht4r s4chu 4schunt 3schü 2schv 4schwaa 4schwet sch4wil 2schz 2scj 4s3cl 2sco 3s4cop 3sco4r s2cr 2scs 2scu 4s3d2 sda3me sde1s sdien4e sd4r 1se se3at. 2s1e2ben seb4r 2s1echo s1echt 2s1e2ck se2dik 3see se1ec se2e1i4 see3ig seein2 se1er. se1erk se1erö 2s1eff sef4l se2gal se2gl seg4r 3seh seh1a se2ha4g se2han se3he se4h1ei se4hel se4herk se2hin seh1l seh3re seh1s seh3t se2hüb 2s1ei. 2s1eie 2s1eig sei3le s1ein 5s4ein. 2seinb sein4du sei3n2e sein4fo 4seing 2seinh 4seink 2seinl 2seinn 4seinr s4eins. 4seinsa 4seinsp 4seinst 2seinw 4s1eis 3s2eit 3sek 4s1e2ke s2el. se2l1a se3lad sela4g se3lam sel1ec 4selem se4lerl sel3ers 2self. s1elix se2l3ö s2els sel3sz sel3tr s4e3ma 2s1emp 3s2en. se4nag se2nä 2s1endl 3seni 3senk se2no 3s2ens s2ent. sen3ta 4sentf 2s3entg s2enti 2s1ents 2sentw 2sentz se2n3u seo2r 4s1e2pos 3seq 3s4er. 3sera ser3a2d se2r3al s3ereig 6sereign se4r3eim se4r3enk ser2er 2s1erfo s2erfr s3erfü 4ser4fül s4ergr s1erh 2serhö 3seri serk4 4s3erken s2ern. 2s3ernt se1rot 4s3eröf ser3r s2ers. 2sersa 4serseh s4ert. s2erta seru2 se4r1uf se3rum se3rund 3s4erv 5ses. se2sel se3sk se1sta se3su 3set 4se4tap se2tat 4s1e2th se1u2n 2s1ex se2xe 4sexp sex3t2 1sé 4s3f4 sfal6l5er sflo4 4s3g2 2s1h 4sh. sh2a 3s2ha. sha2k 4s3han 1shas s3hä s3h2e 3shi. 3shid 4shil shi4r sh3n s3hoc 4shof 3shop sho4re 3show s3hö sh4r 4shs 1si si3ach. si2ad si3am. 2siat sib4 5si1c 2s1ideo s2ido 3s4ie siege4s sieh1e sie4hes sien3 si3ene si1err sie2s si1f4 3s4ig si2g1a2 sig4n si3gnu si2g3r sig4st si2k1ab si2kak si2k1ä sik3erl si2ki si4k1l si2kr sik3s sik3t4 si2ku sil2br 3silo 2s1imm si3n4a 2s1ind 2s1inf sing1a sin3gl sing4le sin4gr sing3sa 4s1inh sin1i sini1e 2s1inq 2s1ins s2ins. 2s1int 4s1inv 3sio sion4 3siru 3sis si2sa si4schu si2s1e si2s1o si2s1p sis3s 3s2it si2tau sit3r si2tra si3tu siv1a sive3 si2vr 1sí 2s1j 2s1k2 4sk. 3skala 4skam 4skanz s3kar 4skas skas4tr ska4te. 4skateg ska4tes 4skä 4skb s4kep 3s2ki. s2kif s2kig 3s2kik 4skir ski1s 3skiz sk4l 4s3klas 3s2klav 4sk4n 4skom 4skor 4skow 4skö s3kro 4sks 4sk3t 3skulp 2s1l2 3slal 4slan sla2ve s2law s3lä sl3b s3le sler3s s3li 3s4lip sli4tu s3lo. slo3be s3loe 2s3m2 2s3n2 4s5na snab4 sni3er. sni3ers 4s5not 4snö 1so 3so. so4a 2s1o2b so1c so3et 3soft 3sog s1o2he 4sohng 2s1ohr 3sol so3la so2l1ei sol4ler 4so2ly 3som 3s2on son3au sone2 son3end son3sä son2s1o so3o 2sopf sop3s 3sor. s1orc 2s3ord so2rei so3ren 2s1orga 5s2orge 2s1o2rie so2ro 3sors so4ru 3sos s4os. 4s1ost 3soß so3unt 3sov 4s1o2ve 3sow 2s1ox 3soz 1sö sö2c sö2f 2s1ök s1ö2l s1ös 1sp2 2sp. 4spaa 4spak 2spala spani7er. 4spap 2s3para 4sparo 5s6parten 3sparu 3spaß 4spatr 4spau s2paz s2pä 3späh 2spär 2s3pe. s3pel 4spensi spe3p4 s2pera s1peri 2spero s2perr 2spers 4spet 3s2pez 4s3pf 2spha s4phä s3phe 3s2pi4e 4spier4 spi2k 4spil 3spio 4spip 4spis 2spl 4spla 4splä 4sple 3s2pli s3p4lu s3pn 2spod 2spog s2poi 4spok 4spol 4s3pos s2pott 4spr. s2prac s2pran 4sprax 2spräm 4spräs 3s4prec 4spred s2pren 2spres s2pric 2sprob 2sprop 3spross 3spru 4sprüf 2s3ps 2s4pt 3spuk 2spun 2spup 3spur 4sput 4spy 2s1q 4s3r4 srat2s srat4sc sret3 srö2s1 srücker6 6s1s ssa3bo s5saf s3sag ss1aj s3sal s4s1alb s4s3amt s4s3ang s2sano s4sans ss2ant s4s3anz s3sa1s2 ss3att s3s2ä s4sce ssch2 s4sco ss1ec s2s1ega sse3inf sse3in4t sse6r5att ss1erö ss3erse s3s2es sse3ta ss3l ss1off ssoi4 s2s1op ss1ori s2söl s3spe ss2po s2spro ssquet4 ss3s4 sst2a s3stel ss2th ss2ti ss4tip s3s4tras s3strec ss2tur s3stü ss1ums s1t 4st. s2ta 4sta. 3staa 2stabb s4t2ac sta2ck 3s4tad 3staff 2stag 3stah 2stak 2stale s3ta3li 2stalk st1alm st1alp st1a2mi 4stan. sta4na 3stand 2stani 4s3tann 2stans 2stanw s4tar. 4stari s4tars st1asi 2s3tat. s4tau. 2stauf 2staum 3staur 2staus 2stax 3s2tä 4stäg 4stält s4tänd 5stätt s3täus 2stb 2st3c 2std 4s5te. 4stechn s2ted 4stee 3s2teg ste2gr 3s4teh s2te4i st1eid 3steig 4steil 3steilh steil4z stei4na 1s2t2el 2stel. stel4l3ä 2steln 2stels 2stem 4stem. ste4mar 4sten s5ten. ste4na s4t3ends st2ens s4tentf s2tep 2ster 6s5ter. st5erbie ste4rec ste6rers st3erfü st5ergeb 4sterm 3sternc 4stes ste2se stes6se. ste4st 2stet s4teti 3s4tett 3s2teu 1steue 4steuf st3ev 4stex 2stf 2stg 4sth s4thä s3them s4thi s2t3ho s2thu 2stia 2stib 3stic 2stie. s2tieg s2tiel 2stien 3s2tif 2stig 2stik s2til 3s4tim s4tinf s3tinn st1ins 2stio 1s2ti2r 2stis st1i4so 1stitu 2stiv 2stj 2stk 4stl 4stm 2stn s2to 2sto. s3tob 2sto3d 4stod. 1stof s4toff s4t3om 4ston 4stoo s4tope 2stopo 2stor. 2store 2storg 2stori 2stors s3tort 2stose sto3s2t 1stoß 4stote 4stou 2stow 2stoz 1stö 2stöch 2s3töl 2stöt 2stp 2stq s2tr 2strad 2s3trag 1strah 4strahi 4strai 4strak 2stral 4strans 5straß 4s3traum 4s5träg 4sträne 4s5tref 4s5treib 5st4reif st3renn 2strib 2s4trig 1s4tri2k 2s5tris st3roll stro4ma 2ströp 1stru 2strua 2strug 3struk 2st3run 2strup 2s4t3s2 sts4k 2st3t4 st2u 5stub 4stuc 3s4tud 2stue 3stuf 5stuh 2stum2s stum4sc 2stumt stu2n 2stun. 3s4tund s2t3uni 4stunn 2s3tuns 2stunt stu3re st3url 2sturn 2st3urt 2s3tus 1stüc 2stüch 2stür. 3stüt 2stv 2stw 3s2tyl 4st3z 1su su1an 3su2b3 su4ba2 4subi 3su1c su2cha such4st 2s1u2f 2s1uh su1is su1it. sul2a sul2i sult2 su2mar su2mau 3s2ume su2mel su6m5ents s3umfe 3summ sum1o2 su2mor s2ump s3umsa s3umst su2n 3sun. sunder4 sun6d5erh su4ne s1unf 2s1uni 4sunt 3s2up sup3p4 su2ra 2s1url s1urt s4us1 su2sp sus3s 3suv 1sü 2sü2b 3süc sü2d1 süden2 3sün 3s2üs 3süß 4s3v 2s1w s3wa s3we sweh2 4swie 4swil 1s4y syl1 sym3 sy2n3 sy4na sy4nä 2s1z2 4s3za 4szä 4s3zei s2zena 3s4zene 4s3zent s2zes 4s3zet s2zis 4s3zu s3zü 4s3zw 2ß1a2 2ß1b2 2ß1c 2ß1d 1ße 2ß1ec 2ß1e2g 2ß1ei ße2l1a ße2ni ße2no 2ßentz ß2ers. 2ßerse ßer3t 2ß1f 2ß3g2 ßge2bl 2ß1h 1ßi ßi2g1a2 ßig4s 2ß1in ß1j 2ß1k4 2ß1l ßler3 2ß1m 2ß1n2 ß1o2 ßos2 2ß1p2 2ß3r2 2ß3s4 ßsch2 ßst2 2ß1t 1ßu 2ß1um 2ß1ü 2ß1v 2ß1w 2ß1z 1ta 3ta. 4taa 5taan 2tab. ta2b1an 2t1abb 3tabel 2taben ta4bend 2tabf 2tabg 2tabh 2tabk 3t6able 2t3abn ta2br 4tabs 2t3abt ta2bü 2tabw 2tabz 2t1ac 3tacu t1ada tadi3 2t1a2dr ta3d2s 3taf. 3taf2e 4taff t1afg t1af4r 3t2ag ta2ga ta2g1ei 4t3a4gent 4ta3gl t3ago tag4st tah2 tah3le tahl3sk t2ai ta3i2k tai2l ta1ins tai4r ta1ir. t1a2ka ta2kro tak6ta 3taktb 3takts 3t2aktu 2takz 3t2al. ta2la ta3lag ta3lak tal3au t1alb. t1albk tal3d 3t4ale tal2en ta4lens tal2ga tal2l1ö4 3talo ta2l1op 2talt 2tam 3tame ta2mer t1ampl t1amt 3tan. t1a2na 2tanb 4t2and tand4ar ta3ne 4tanf 2tang 3tani t2ank t3ankl 4tanl t1anm 2tanme 4t1anna t2ano t1ans 3t2ans. 4t3ansi 4t3ansp 2tanwa 2tanwä t2anz. t1anza tan6zerh t1anzu tan2z1w ta3or ta2pe. ta2pes 2tapf ta2pl 2tappa t2appe 2tarb ta4ren4s ta4r3ere 5t4a3ri 2tark 2t1arm 2tart t1arti tar2to ta2ru 2t1arz 3tas. ta3sa 3tasc t1asp 3tast ta2ta2b ta2tan ta2tau tat1ei ta2tem ta2t1er ta2th tat3he t3atl t4atm ta2tom 4tatue ta2t1um 4taud 2t1auf 4taufg tau3f4li 4taufn t1auk 3taum t1ausb 3tausc tau6schr tau6schw t2ause 4t3ausg t1ausk 4tausl 4t3auss 4t1ausw 3tav 3tax ta3xi taxi3s 1tä 3täa 4täb tä1c 4täd 3täe 3täg 4tägy 2täh 2t1ält 4täm t1ämt t1ängs 3tänz t1äp t2är. tä2ru tä2s t2ät 4tätt 2täug 2täuß 2täx 1tà 4t3b2 tbauer4 tbe3r2e tblock5e tblocken8 4t1c t3cha t3che tch2i tch3l t2ch1u tch1w t4ck t3cl t3cr 4t3d4 tdun2 1te 3te. te2a2 2teak te3al te3an 3teba 3t4ebb 4t1e2ben t2ech te3cha 2teche 3techn 2techt te2chu 2teck te2cka teck2e te2cki te2de te1em te2en3 te1erw te2es 2teff 2t1egg teg3re 2teh 3teha 3tehä 3tei. 2teign teik4 3teil 4teilhe 2tein tein3e4c t3einge t3einla 4teinn t1eis. t1eisb te2kel tekt2 3tel. 3tela te2l3ab te2l1ac te2l1au telb4 tel3d4 3te3le tel1eb tele4be te4l1ec te4l1eh te4lein 2telem te4lerd te4leu 4t3elf. 3telg te2l1in te2lit 3telk tell2e tel6lein 4tellu 3teln te4lost te2l1ö 3telp 3tels tel3s2k 3telt4 tel3ta tel3th 3tem. te2m1ei te2min 2temme te2m1o2r 3temper 2tempf tem3s te4m1u 3ten t6en. tena2b te4n3a2d te4n3a4g te4nas te4n3au te2nä ten3äh t4enb ten3da 4t3endf t6endi 4t1endl t6endo 4t3endp ten3d4r te2n1e2b te2nef ten3ei te3n4ei. 4tenerg te2net 4t1eng. ten4gag 4t3engla t4enh te2ni te4n3in t4enj t4enm ten3n tens2e 4tensem tens3th t4enta t1entb 4tentd t4ente 4tentn tent3ri 4t3entw 4tentz ten6zerh ten3zw t1e2pi 3t6er. ter3a2c te1raf ter3am te3ran. te3rand ter3a4s 4terbs 4terbt 3terc 4t3erde. te2re2b te4r3eif te2rel ter3end te4reng te4rerk terer4z 4t3erfol t4erfr 4terfül 3terg2 ter3ga 6ter6grei t4ergru t4eri te3ria te2rid ter3k 5terkla 4terklä 2t3erlö ter4mer 3termi ter4n3ar 2ternc t3erneu t4ero t1erö ter4re. t4ers. ter3sc ter4ser terst4 t4erst. 5t4ersti 5t4erstu tert2 teru2 te4r1uf ter3za 2t1erzb 3t2erzu 3tes tesa2c te2san 4t1e2sel te2sep tes1er te2spr tes3si t2est tes3tan test3ei tester4 tes6terg tes6terk testes4 te2su 3tet2 t2et. te2tat 4teth 4tetl teu3ere teu3eri 3teuf 3teum te1un 3teur. teu2r3a 5teus te2vi te1xa 2t1e2xe 2t1e2xi 4texp 3text 2t1exz 4t1f4 tfi2l 4t1g2 tger2 t1h 4th. 2th4a 3t4ha. t2hag t3hai t2hak 3thal. 4t3hau 2t3hä th2e 1t2he. 3thea 2theb t2hec 2t3hei t4hein t2hek t2hem 1then t4hene t4heni 3theo t2hes 3these t2heu 1thi thi3er t2hik 2t3hil 2t3him t3hir 2thk 4th3l 4th3m 2th3n 1t2ho t4ho. 2t3hoc t3hof 2t3hoh t4hol. t4holo t3hor 2t3hot thou2 2thov 4t3hö 2thp 1th2r2 2ths 2thub 4thun 2thü 2thv t2hy 1ti ti2ad ti3a2m 3tib4 2tic ti1ce tiden2 ti4dend 3tief. tie2fr tieg4 2tieh ti1el ti2el. tiel3a ti3e4n3 3tier tie4rec ti2ern ti1et ti1eu 3tif. ti1fr 4tift 3t4ig ti4gerz 3tik ti2kam ti2kar ti2kin ti2kra ti2krä ti2kü ti2lar ti2lau ti2lei ti2lel 3tilg ti2l3ö til3s tilt4 ti2lu ti2ma2g t2imi tim2m1a 4t1imp 3t2in. ti3na t1inb 4t1ind ti3n2e t1inf tin2g1a ting3l ting3s t1in1it 2t1inj tin2k1l 3t2ins. 4t1inse 2t1int ti1nu 4t1inv 3tio 3tip ti4que. ti1rh 3tis ti4scha tisch3w ti2sei ti2sp ti1sta 3ti3t2e ti3ti 2ti3tu tiu4 tium2 3tiv ti2van tive3 ti2vel ti4vene tiver2 ti4verl ti2v1o ti2v3r ti2za 2t1j 4t3k4 4t3l tl4e 5tlem tle2r3a 6t5li tlung4 4t3m2 tmal2 tmen6t3 tmo4des 4t3n2 t5na tnes2 1to 3to. to4as to5at 4tobj tob2l t1obs to1c t3ochs 3tocht to6ckent 3tod tode2 4to2d1er tode4s to4d1u toi4r 3tok to3la 3tole 4tolz tom1e2 2tomg 3ton to2nau to2neh 3too to2pak to2pat 3topo 2topt 3tor. to1ra to2rau to4rän 4torc t1ord 3tore to2rel t1org t3orga 3torin tor3int to2rö 3tors t1ort. to2ru t2orw to3sc 3tose to3sh to4sk tos2p 4toss 3tost4 to1sta 4toß 3to3te to2tho 3totr tots2 3t4ou touil4 to3un 3tow 2tö 3töch 4töf 4t1ök tö4l 5tön t1öst 4töß 3töt 4t3p2 tpf4 2t1q 1t2r4 2tr. 5tra. 3trac tra3cha t3rad. tra4dem tra4far 3trahi 4trahl 6trahm 5t4rai 3trak 3tral 2t3rams 3t4ran. 2trand 3trank t1rann 3trans t3rase t3rasi 4traß t4raue 2traup 5träc 3träg 3träne 4träs 4träß 4t5re. tre4ale 4treb tre2br 4trec t3rech t4reck 6t3red 3tref 4trefe 4trefo 4treg t4rei. 3t4reib 4treic 2treif t3reig 2t3reih t3rein 2t3reis 6treit t3reiz 2trek 6t3rel t4rem t4ren. 3trend 4trendi t3rent 2trepe 2trepo t4repr t4rer t4res. t4ret tre2t3r t5rett t4reu 3treuh 2t3rev 2trez 5t4ré 2t3rh 3tri 4tric 5trieb 2trieg tri2er tri4ers 5trigg t3rind 4tring tri3ni 4trinn t4rip 4tript t4rit tri2x trizi1 3tro. 4trock. 3troe t4roi tro2ke 4trom. tro2mi 3tron 2t3roo t4rop 3tropf 3troy t3röc 2tröh 3tröp 3trös 4tröss 3tröt 3trua 2truf 4truk trum2 trums1 2t3rund 3t4runk 5t4rup tru2th trü1be trü1bu 2t3rüc trücker6 t4rüg try1 2ts tsa4b t3s2ac t2s1a2d t2s1ah ts1al t4s1amt4 t2san ts3ar ts1as t2sau t2s1äh t2s1än t3s2cha t4schar t3sche t4schef ts4chem tsch4li t4schro ts4cor t2s1e2b t3seil t4seind ts1em tse2n1 t2s1eng t2s1ent t2s1er t6s5essen t2s1i2d tsing4 ts1ini t2s1ir ts3kr t1slal ts1o tso2r t3sou t2sö t3spal ts1par ts4pare t2spä ts2ped t3spek t2sph t3s2pi ts2pon t3s2por t4sprei ts3s4 t1st4 t2staf t4stag ts3tak ts4tal ts3täti t2stea t2s3tep t3s4tern t3s4tero t2stip t4stit ts3trad t2s3trä t4streu t2stri tstro2 t4strop t2s3trü ts2tu t2s1u 1tsub t3sy4 4t1t tt1ab tta2be tt2ac tta6gess tt1ak tt2al tt3ank tt2ant tt1art tta1s tt1ebe tt1eif tt1ein tt1eis t3tel tte2la tte4leb tte4len ttel1o tte4rec ttes1 tte4sa tte2sä4 tt2häu t2t3ho t3ti t3to tto1s t3tö t3tro tt3rü tt2sen tt2sor tts1p tt2spe tt2spr tt2sti tt5t t3tu tt2un t3tü 1tu tu1alm tu3an 2tub2 tuba3b 3tuc tu2chi 2tud 3tue 4tuf tuf2e tu3fen t3u2fer tuff3 4tuh tu2is 2tuk t3u2kr tul2a t2um. 3t2ume 2t3umf 2t3umg 2t1umh 2t3umk 2t3umr tum2si tum2so tums5tr 2t3umt 2t1umw 2t3umz 3tun. 2t1una 2t1und 3t4une 2t3unf 3tung t3unga tung4s5 2tunif 2t1u2nio 2t3unt t1up. tu2r1a4g tu2rä tur1c tu2re. tu2rei tu2r1er tu2res tu2r1e4t turin1 3turn tu2ro tu4ru tu2sa tu4schl tu2so tu3ta 2tü 4tüb 3tüch tück2s 3tüf 3tüm 3tür. tür1c 3türe 3türg 3tür3s 3tüten 4tütz 4t3v 4t3w twa2 twi4e 1ty1 3typ ty2pa tys4 6t1z t2za4 tz1ag tz1al tz1ar tz1au tz1ä t3ze. t2z1e2c t2z1eie t2z1eis tze4n1 tz2ene tz3ents tz1erl tz2ers t3ze2s tz1ind t2zor tz2ö tz2th tz2tin tz1wä tz1wi tz1wu 2ua u1a2b u3a2c uad4 u1al. ua2lau u1alb u3alet u1alf u3a2lo u1alr u1als u1alt ua2lu u1alz u3am u1ans u3ar. uara2b u1ars ua3sa ua2th uat2i u3au u1ay u1äm u1äu 2u1b u8be8cken. u3b4i ubi3os. ub2l ub3lic u2b3lu u2bop ub3rä u2b3rit ub2san ub2s1o ub2spa u2büb 2uc uc1c u1ce uch1a u1cha. uch1ä u1che u2ch1e4c uch1ei u3ches u1chi uch1il uch1in uch3l uch3m uch3n u2ch3r uch2so uch4spr uchst4 uch4tor uch2t3r u1chu uch3ü uch1w u1ci u2ckem u4ckent uck2er uck3erl u3ckerr u2cki u1cl 2u1d u3d2a uden3s2 uder2e udert4 udi3en uditi4 u2don ud3ra u3dru 2u1e ue2ck u2ed ue2en u2eg u4ela ue2le ueli4 ue2mi uen1 ue2nä ue2ner uenge4 uen2gl u3e2ni ue2no uen2zu u2ep ue2r3a ue2r1ä uer6baut u2ere2 u3e2rec u3ered u3ereh ue3reig u3erer ue4rerg u3erex uer3g2 u3erh u4erinn u3erin4t uer4nan uer2ne uer4ner uern3s4t uer3o uer2ö u3err uer3sc uer3t2 u3erum u3erunf u3erunt ue2ta ue4tek u3fac ufa2ck u3fah uf1ak u3fal uf3ar u3fas uf1au u2f1äs u2f1ä2ß u2f1ei u2f1em u3fen. u2fent u2f1erh u4ferle uf2ern 2uff uff4l uf2fro uf3l u2fob ufo2r uf1ori uf3r uf3sä uf4sin uf4so uf2spo uf2t1eb uft3erd uft3s2 u2fum 2u1g u4gabte ug1af ug1ak u2g1ap uga4s ug1au ug3d2 u2g1ei u2g1erf u2g1erl ug4es ugge4st ug3hu u2g1l ug3lad u4g3lo u3g2lö u4glu u2g3n ugo3 ug1or u2gö u4g3reis ug3ro u2grol ug4ros ug3rüs ug3se ug4ser ug3si ug3spa ug4spr ug4spu ug5stä ug3str ug3s4tü u2gü u1h uhe3s6 uh1la uh1lä uh2li uhme4 uhr1a uh2rer uh3ri uh4rin uhrt4 uh2ru uh4rü uhs4 uh1w 2ui ui2ch ui4cker u1ie ui1em u3ig u4ige uil4les u1in. u1is. u3isch. u3ischs uisi4n ui4s5t u1j uk2a u3käu u1ke u1ki u1k2l ukle1i uk4n uk2ö u1k4r uk2ta uk2t1in uk2t3r u1ku uku2s uk2ü u1l ul1ab3 ul1am ula2s ul1äm ulb4 ul2dr uld2se 2ule u2l1el ule4n ul1erf ul1er2h ul1erw ule2sa ules3t ule2t ul1eta u2lex ul3f4 ulg4 uli2k ul1ins ul3ka ul2kn ul2les ull3s ulo2i ul1or ul2p1h ul2sa ul4sam uls2th 2ulta ul4tri ult3s u2lü ul2vr ulz2w u2m3a2k um1all um1anz u2m1art u2m1aus u2maut u2m1äh 1um3d2 um2en ument4s umer2a um1erf um1erg um1erl um1erw 1umf 1umg um1inh u2m1ins um1ir 1umk 1uml 2umm umm2a u2möl umpf4li um2pho um2p3le 1umr um4san 3umsat um4ser um2sim um2s1pe um2s1u um3t2 um2un u2m1ur 1umz un1 4un. 4una. 1unab un4al u3n2am u2n3an 4un2as un3at 1unda un4dab 1undd un3de. un4dei und3erf un2dex 1undf 2undg un2did 1undn un2dor un2d3r 4unds. und3sp und3st un2d1um undü4 1undv 1undz u3ne une2b une2d une2h un2ei. un3ein un3eis unen2t u4n3erz unes4 unft4s 1unget 1ungew ung5h 1unglü un3gn un2gr ung3ri ung4sa ungs5tr un2id un3ide 1u2nif unik4 un2im uni2r 2unis un3isl u3n2it 3u2niv 2unk un2k1a2 un2kei un2kne unks2 unk4tit unk2t3r 3unku unlö2 unna2 un2n3ad un3n2e uno4r un2os 1unr uns2 2uns. unsch5el un3se 1un3si un3sk un3sp uns4t1r 1unt un3ta unte4ri 2unth 2unto un3tr unt3s 2untu unvol2 unvoll3 1unw 2unz 2uo u1o2b u3of u3or. u1or3c u3ors uos2 u1os. uote2 u1pa u1pe2 uper1 up2fa u2pf2e u2pf1i u3pi up4lu up2pl u1pr upt3a2 upt3erf upt3erg upt1o up4tr u1q 2ur. u1ra u2rab u3raba ura2be ural4t u2r1a2m ur3ame u2r1ana uran4fa uran4fo u2r1ang uran4ge ur2anh u2r1an5s u2rar ur3a4ren u2r3att u2r1au 2u1rä ur1än ur3b2a urch1 urd2 ur3di ur1eff u2rele ure4n u4r1ep ur1erh ur1erw 2urf urf3t ur2gri urgros4 urg3s4 uri2c u2r1im ur1ini ur3ins ur1int urk2s ur3l ur4matt 4u1ro u3rol uro1s u1rö ur3p ur3re ur3sac ur2san ur2s3au ur2ser urst4r ur4sw ur3s2ze urt2 ur3ti u3ru urü2 ur2z1a2 ur2zä ur2zec ur2zi ur2z1o ur2z1w 2us u2saf us4ann u6schent u5schmu usch5wer u2s1ec u2s1ei u3seid u3sep use1ra u2serp u2s1ese usi3er. usi5ers. us1is. us3kl us3oc u3soh u2s1op us1ou u2spac us3part u2s1pas u2spat us1pe u3s2pek us1pic u5s4piz u2spo us2por u2spu usse4g uss5erfa usser6kl uss5er6su us2sez us2sof ust3abe u1stal us3tau us2th ust2in us3tr u5s4tras us6tris u1stu u2stun u2stur us2ur u2sü 2uß 2u1t ut1alt ut3a2m u2t1ap u2t1ar u2t1är u3te u4t1ed ut1e4ge ut1ei. ut1eie ute2n1 u2tent uter4er u4t3er4sa ut2es ut2et u4tev u4t1ex utfi4 ut2he u2thi u2t3ho u2thu utli4n uto1 uto4ber uto3c ut1opf u2tops ut4or utos4 u3tö ut3rea ut3rü ut3s2a ut2s1ä ut4schl ut4schm ut4schö ut3si ut2spa utt4an ut3te ut5t4l utts2 utu4re utu5ru u3tü utz3eng ut2z1in ut2zo ut2z1w 2u1u2 uufe2 u1ü2 2u1v4 u2ve. uve3rä u1w 2u1x ux2e ux2o ux3t u1ya 2u1z uz3ot uz1we uz3z4 1üb üb1ä 2übc 2übd übe2 übe3c übe4n3 über3 ü4bet üb3l üb3r üb2s3t 2üc ü1che üch3l üch2s1c üch5t4e ü3cken ück1er ück3eri ü4ckers ück4spe 2üd ü4d3a4 ü3den. üden2g ü3d2ens üd1o4 üd3r üd3s2 üdsa1 üd3t4 üdwes2 ü2f1a ü2f1ei üfer2 ü2f1erg üf2fl ü2f1i üf3l üf2to ü1g üge6lei6s ü2g3l ü2gn üg3s üg4st üh1a ü1he ü2h1ei ü2h1eng üh1erf ü2h1er2k ü2h1er2z üh1i ühla2 ühl1ac üh1lam üh3l2e ühl2se üh3mo üh3ne ühn2s üh1o üh3r2e ühr3ei. üh1ro ühr3ta üh1s ühs2p üh3t üh4th üht4r ü1hu üh1w ü1k2 ül1a ül2c ü3l4e ül2l1a ül2l1ei ül2lo ül2lö ü1lu ü2ment 4ün ü2n1a ün2da ün2dr ünd3s ünen3 ün2f1a ün2f1ei ün2fli ün2fr ün2g3l ünn2s ün2s ün3sc ün3se ün3sp ün3str ünt2 ü1nu ün2za ün2zw ü1pe üpf3l ü1pi üp2pl ür1a ü2r1ei ür2fl ür2fr ür4g3en4g ü1r2o3 ürr2 ür2s ür3sc ür3se ür3sp ürt2h ür2zö ür2zw üs2a ü2schl üse3h üse3l üse1s üs2s1c üss2e üs2st ü2st 2ü1ß 2üt ü2t1al ü2t3r üt2s1 üt2tr ü1v ü1z 2v1ab va1c val2s 2vang 2varb va1s v4at va2t3a4 va2tei va2t3h vatik2 va4t1in vati8ons. va2t3r vat3s4 va2t1u 2v1au 2v1b 2v1d 1ve2 ve3ar ve3b ve3c ve3d ve3g ve3h ve4i 2v1ein veit4 veits3 ve3la ve4l1au ve3le ve3li ve3lo ve3ma 2ve3mu ve3nal ven2c ve3ne venen4d ve3ni ve3nö ve3o ver1 ver3a ve3rad ve3rand ve3ras ver3b2 ver5d2 vere2 ve4rek verf4 verg4 ve3ri ve4rin ver3k ver3st vert2 ver5te ver3u ves1 2ve3sc 2ve3s2e ves3ti ve3ta vete1 ve3to ve3tr 2veü ve3v ve3x2 2v1f4 2v1g 2v1h vi3ar vi4a3t vi2c vi3de vid3s2t vie2h3a vi2el vi3en vie4rec vie2w1 vig2 2vii vi2l1a vi4l1e2h vi2l1in 2v1i2m vima2 vi4na vin2s 2v1int vi3sa vise4 vi3s2o vi2sp vis2u 2v1k 2v1l2 2v1m 2v1n 2v1ob vo3ga vo2gu 3vol voll1a vollen4 vol6l5end voller4 vol6lerw vol2li 2v1op vo2r1 vor3a vor3e vor3g vo3ri vo5rig vormen4 3voy vö2c 2v1p v2r 2v3ra v3re v4ree 2v3ro 2vs vs2e v1sta v1steu v3s2z 2v3t vu2et 2vumf 2v1v 2v1w 2v1z w2a 1waa wab2bl wa3che wach6stu wach4t4r waffe2 waffel3 1wag wa5ge 3wagen wa2g3n wa3go 1wah wahl5ent wah4ler wah2li wai2b 1wal 2walb wal4da wa2les 2walm wal2ta wal2to walt4st 3walz wa3na wandels6 w3anf wang4s 1wann wan6z5en6d wa2p 1war2e ware1i war3ste wart4e 1was wa3sa wa4scha wa3sche wa3se wa3sh wass4e 1wäh 1wäl 2wäng 1wäs wäs2c 2w1b2 wbu2 2w1c 2w1d we2a we2ba 4webeb we2bl web3s we3cke. we5cken. we3ckes we2e4 weed3 we2fl 1weg we2g1a we2g3l we4gn we2g3r weg3s4 1weh we4i wei4bl 2weie weifel6d weik4 3weil wei3sc weis4s3p weis4t wei3str wei4tr wel6schl wel6schr wel2t1 wel4t3a4 wel6t5en6d wen3a4 wen2gl we3ni wen4k3ri we2r3a wer2bl 1werbu werd2 5werdens 1werdu werer2 wer2fl wer4gel we4r3io 1werk. wer2ka 1werke wer2kl wer2ku we2rö wer2s wer2t1a wer4t3ei wer6t5erm wer2to 1wese we2s1p we4st west1a west3ei wes2th west1o2 west3r wes4tu 1wet wet2s wett3s 2w1ey 2w1g 2w3h wi1cka 1wid wi2e wie3l wien2e wie2st wik2 1wil wim2ma wim4mu win4d3e4c win2dr win2e 2wing win8n7er8sc 1wi4r wi3s2e wi2sp 1wiss wi3th 1witzl 2w1k 2w1l 2w1m 2wn wn3s 1wo1c wo2cha woche4 1woh woh4lei 1wolf wolf4s3 wol4ler wor3a wo2r3i wor2t3r wo4r3u wot2 1wöc wört2h 2w1p w2r w3ro 2w1s w3s2k ws2t 2w1t wti2 w2u 1wuc wuch4sc wul2 wul3se wun2da wun4g3r wun2s 4wur. wur2fa wur2s 1wurst wus2 wus3te 1wu4t1 1wüh wül2 wün3 2w1w 2w1z x1a 1xa. 2xa2b 1x2ad 1xae xa1fl 1x2ag x3a2m xand4 x2anz 1x2as 2x1b 2xc x1ce x1ch x1cl 4x1d 1xe x1e4g 2xek xe2l x1em 3x2em. x2en xen3s2 x2er. x2ere xers2 3xes 2x3eu 2x1f 2x1g 2x1h xib4 xi1c xich2 2xid xide2 xi2d1em x1i2do xie3l xi3g xil1 xil2a xi2lo xi2lu xin3s2 x2i2s1 xi3s2c xiso2 xis3s xis4tä x1i2tu x1j 2x1k2 4x2l2 x3lä x3le 2x1m 2x1n x1or 4x1p xpor6ter x1q 2x1r 2x3s2 4x1t x2t1a x3t2as xt1ä x2tän xtblo4 x2t1e2d x2t1ei x4tent x2t1er2f x2t3ev xtfi4 x2t1il2l xtra3b4 x2t3ran xt3s2 xt1u x3t2ur 1xu xu1a x1u2n xu2s 2xv 2x1w 2xy 3xy. 3xys x1z 2y1ab 1yac y1al. y1a2m yan2g y1ank y1ät y1b y1c2 y2chi y3chis ych3n y1d4 y1e y2ef yen4n y2ere y2es. yes2p ye2th y1f2 y1g ygi2 ygie5 yg2l y1h yhr2 y1i4 y1j y1k2 yke3n yk3s2 y1l y2l3a2m yl4ante yl3c y4le. yli4n yloni1 yl3s2 y2l1u yma4t ymp4 ym2pha ympi1 y2n1o yno4d ynt2 y1nu y1of yom2 yon4i y1ont y1os y1ou y1p ypa2 yp3an ype2 y2pf y3ph y2p1in ypo3 y4p3s y1r y3r2e y3ri yri2a yri1e y3r4o yrr2 ys2an ys2c yse1 y3s2h y4s3l ysme3 ys2po ys1pr ys3t2 y1s4ty y2s1u2 y3s2z y1t2 y2te. y2tes y3to1 yu2r yure3 y1v y1w y1y y1z2 2z3a2b zab3l za1c 2z1a2d 2z1af za3gr 3z2ah zah4ner 2z3a2k 2z1all 2z1am z1an za2na 2z3anf 3zani 3z2ank zan4kl 2z3anl zanti1 2zarb 2zarc 2z1arm z1arti zar2tr 2z1arz z1as za1st4 2z3at3 3zaub z1au2f z3aug 3zaun zä2 2z1ä4c 3z2äh 2z1äm 2zängs 2z1äp z1ärg z1ärm 4z1b4 zbü1b zbübe3 2z3c 2z3d2 zdan2 zdä1 2z1e2ben 2zecho ze1e 2z1eff zehe4 zehen1 zeh2l zeik4 zei3la zeile4 2z1ein zei1s6 zei3sk zeist4 zei2t1a zeit5end zei4t3er zei2tr zeit3ri ze2l1a2 ze2len ze2l1er ze2l1in zell2a zels2 zel3sz zel3t2h zel3tr zelu2 2z1emp 5zen. ze4n3ac ze2nä zen3n ze2no zens2e zen4sem zen5s4tr zent3s zen4z3er z2er. ze2r3a ze2re2b 2z1ergä 4z3ergeb z3erhal 2zerhö zerin4t zerk2 z2erl. 2zerlö z2ern zer4neb zer4n3ei 2z1erq zers2 2z1ersa 4z3erste 4z3erstr 3zert zert1a4 zer4t3ag zert4an zer6tere zer6terl zer4tin zer6trau 4zerwei 2z1erz 3z2erza ze2sä ze3sc ze3sku ze2sp zessen4 zes6s5end zes2sp zes2st ze2s3t ze3sta ze2tr 2zetts 2z1ex 2z1f4 2z1g2 zger2a 2z1h z2hen zhir3 zi3alo zi3ar zi2dei zid3r zie4lei zi1erh ziers1 zi1es. zil2e 2z1imp zim4t3 zin2e zin3ei zin4er 2z1inf 2z1inh zin1it zin2sa zin4ser 4zinsuf z1int 2z1inv zi2o3 zi3op zirk2 zirk6s zi3s2z zi1t2h zi2t1o2 ziv2 2z1j 2z1k4 2z1l2 2z1m2 2z3n2 2z1ob 2z1of zo2gl 2z1oh 3zol zon4ter zo2o 2z1ope z1or zo2ri zor4ne 2z1osz 2zö2f 2z1ök z1öl 2zön 2z3p4 2z1q 2z3r2 4z1s2 z3sa z3sh z3sk z3sz 2z1t z2t1au z4tehe z3t2her zt3ho z3tic zt1ins z3tö zt3rec zt3s2 z3tü zu1 zu3a zu3b4 3zuc zu4ch zu3cke zud4 zudi4 zu2el zu3f4 zu2g1ar zu4gent zu3gl zug1un 2z1uhr zu3k 2z1um. zumen2 2zumf 2zumg 2zuml 2zumr 2z1ums zun2e zung4 2zunt zup2fi zu3r2a z1urk 2z1url 2z1urs 2z1urt zu3s4 zu5t zut2a zuz2 2züb zür1c 2z1v zw2 z1wac 2zwag 2zwah zwan2d1 z2wang z1war 2zwas 4zwäl 2zweg 2zweh z2weig 2z1wel 2z1wen 2z1wer z2werg 2z1wes 2zwet 2zwir z2wit 2z1wo z1wör z1wur 2z1wü 4z1z z3z4a zzi1s4 z3z2o zz2ö", + ["data"]=".ab1a .ab3l .abo2 .ab3ol .ab1or .ab3s2 .ab3u .ade3n .ae3 .aft2 .ag4r .ag2u .ai2s .akt2a .al2e .al3k .al3lei .al5len .al3li .al3se .al4tei .al4tel .alter6s5 .alt3s4 .al4tu .ampe4 .amt2s1 .amt4sc .ana1c .an4a3t .an3d2 .anden6k .an1er .ang2 .an3g4li .an3go .angs4 .angst3 .ani2s .an3k4 .an3na .an3s2 .an4si. .an4tar .an3z2 .ap5p6le. .ari1e .ar3k2a .ar4m3ac .ar4mun .ar2sc .ar4tan .ar4t3ei .arter4 .ar6t5erh .ar2t1r .arz2 .asbe2 .as4ta .as3tr .ata1 .at2h .at4r .au3d .au4f3 .au2s3 .auß2 .ax2 .äm3 .är6schl .ät2h .ät2s .bahn3 .bah6ner .bal3t .baus4 .be3erb .beige4 .bel2a .be3r2a .ber2e .ber4g3a .ber6g5e6b .ber4g3r .ber4tr .bi4os .bi2t .bit1a .blau3 .boge2 .bogen3 .bogens6 .bo4s3k .bu4ser .bu3ta .by4t .ca2s3t .ce2ra .ch6 .char8mes .chi3er .dab4 .da2r1 .dar3in .dar2m1 .da4te. .da4tes .de2al .de1i .dein2 .de3lo .de8ments .de3na .den4ka .den4kl .den4ko .de1o2 .de3r4en .de1s .de3sk .des2t .di3el .di4en .dien4e .dien6st .dienst7a8d .do3b .do2mo .do1pe .dor2f1 .do2tr .dy2s3 .ebe2r1 .eg2o .eh2e .ehe1i .ehe5n .ei3e2 .ei3f2e .ei3k .ei4na .ein3d .ei2ne2 .ein3eb .ein6erl .ein3sp .eise4 .ei2sp .eis3s2 .ei2s5t .ei4tr .eke2 .ek3li .el2a .el2bi .el2bl .elb3s .el4fei .el2fl .em3m2 .en1 .en4da .en4d3er4 .en2d3r .end3s .en4dü .en3ga .en2gl .enk2 .enn2 .enns3 .ent3 .en2ta .en4tei .en7thalp .en4tio .en4t1r .en5trop .ents4 .er4bei .er8brecht .er2bu .er4dan .erden6k .er4d3er .er1e .ere3c .er2em .erf4 .er1i .ers2 .er8stein .erster6 .er8stritt. .er8stritten. .er4z3el .er4zen4 .es3p .es3ta2 .est6e .es3th .es3t3r .et2s .eu3 .eug4 .eur4 .ext4 .fe3la .fer4no .fi3d .fi3est .fi4le. .fi4len .fi2s .flu2g1 .fs4 .fu2sc .ga2me .gan4ga .ga2s1 .gas3e .ga4sp .ga4t .gd2 .gebe4a .geb2l .gee4 .gel4b3r .gel2d1 .ge3lu .ge3m .ge5nar .ge3n4e .gene7cke .ge3n2o .ge3r4a .ger2e .ge3ro .ger4s .ge3sa .glan2 .glanz3 .gol6der .gs4 .gus2 .halt4e .hau2t1 .he2 .he4bei .he3fe .he3le .he4r3an .he3rat .her6b5ra .he3rer .he3ri .he6r5inn .hin3u .hips4 .hi4s .hof1 .ho4fen .ho4met .ia4 .im2a .ima4ge .im5m2 .in1 .ind2 .in3gl .ink2 .in3n2e .in3sk .in3t2 .inu1 .io4d .ioni1 .ire3 .is2a .is3ta .it2h .iv2 .joni1 .ka2b3l .ka2i .kal2a .ka3le .ka3t2a .kat3i .ka4ti4o .ki4e .klang3 .ko3b .kopf1 .kor4da .kraf2 .ks4 .kus2 .la3be .lan8de8mi .le4ar .le4gas .le3n2i .lich8t7er8s .li2f .li4ve. .lo4g3in .lo2sc .los3s4 .lo2tr .lo3ver .luster6 .lus4tr .lut2h .ly2s3 .ma3d .ma3ge .mal4e .ma2st .mat4c .ma5tr .matu3 .md2 .mel2a .me3ne .me3no .men8schl .men8schw .mes4sp .mi2f .mik4 .mil2z1 .mi2s .mi4t1 .mm2 .mutter5 .na3no .na3t .näs1c .nebe4n .ner2f .ne1ro .ne2s .nich2 .nicht5e .ni4e .ni3k4l .no2th .nul2 .nus2 .oa3 .ob1a .obe2 .ober5ei .ob3i4t .och3 .of2e .oper4 .or2a .ord4e .or3g .or3k2 .ort2 .orts3e .os3s .os4ta4 .oste2 .ost5end .os8ten8de .oste6re .os8terwe .os4tes .os2t3i .os4tig .os4t3r .os4tu .ot1a .ou2t .ou4te .ozo4 .öd2 .öl3l .pab4 .part4h .pe2c .pe3la .pe3le .pe3na .pf4 .ph4 .poka2 .po4st .postei6 .pro1 .ps2 .rabe4 .ra3ch4e .ra3me .rau2m .rau8schl .räu3sc .re3ale .reb3s2 .re3cha .re5insz .reis6e5i .rei4s5t .reli1 .res6tr .ri4as .richt6e .ro4a .ro3be .ro2e .ro2h .ro3m .rom4a .ro2st .ro2t3r .rö2s .ruf3s .ruh2r1 .runder6 .rü1b .rü6cker6 .sa3br .sali3e .sami1 .sau1c .sau4er .sau5er. .sch4 .schaf8t7end .scheiner8 .se3ck .se2e .seein4 .se2ha .sen4f .sen5s .se3re .se1ro .se2t1 .sha2 .si4en .si3gn .si4te .ski1e .skis2 .sour2 .spani7er. .spiege8lei .st4 .stau8be8cken. .ste2i .steiner8k .sto4re .stro6ma .sucher6 .tage4s .ta3mi .tan4k3a .tan4k3l .ta3ra .tar3t2 .ta2t1h .ta2to .ta4tor .ta2t1u .te2e .te2f .tehe3 .teiler8s .tei8l7ersc .te3le .te3no .te1ra .te2s .te4st .test3r .th4 .ti2a .ti2e .ti2me .ti4mes .ti3r .ti2s .tischen8 .ti8sch7end .tite4 .tode4 .to4der .todes3 .to2n .to4nat .ton3i .to4nin .tons2 .to4pl .to2pr .to2w .tri3es .tro2s .ts4 .tse3 .tu3ra .tu3ri .turm1 .tur4ma .ub2 .ufe2 .ufer3 .ul2b3 .um3 .uma2 .ume2 .umo2 .un3a2 .un3d .un3g2 .uni4t .un3s .uns4t .ur3a2d .uran6fa .ur1c .ur1e .ur4inf .ur3o4m .ur1o2p .ur3s2 .ut2a .ut3r .ve5n2e .voll1 .vo4r .wah4l .wa2s .weg5s .weine4 .wei4ta .welter8e .welter8k .wer6ker .wer4kr .wer4tr .wetterer8 .wi4e .wor2 .wort5en6 .wor8tend .wor4tu .wur2f1 .xe3 .ya4l .zel4la .zelle4 .zel6leb .zeug4i .zi2e .zie4l3u .zin4ka .zin4s3c .zin4st .zuch2 .zug3l .zu4gra .zu2pf .zwe2 .zweigen8 .zwei8g7end a1ab aa2be aa1c a1a2ce aa2gr a1akt aals2t a1a2n a2ans a1aq 2a2ar aa2r3a aar3b aar3d aa3rea aa2rei aarf4 aar3g2 aar3k4 aart4 1aas aas5t aata2 aa2th aa4t3r aat4s3 2a3au a1ä a1b 2aba 3abad abais4 ab1alt a3b2am ab2ant ab1au ab1ä ab2är ab2äu 2abbat 2abbin 1abd 2a3be. 2a3bec 2abee ab1eic abe3i4d ab1eil ab1ein 2ab2el abe2la2 2a3ben. 1abent 2aber a2berd a3bere a3beri ab1er2k ab1er2r ab1er2z 4abes abe2s1e ab3esse 2abet 2abew 1abf 1abg 3abga 1abh 2abi 4abil ab1ins ab1ir abi3st ab1it abi4tur 1abk ab1l 1a2bla a3blat 1a2blä a2b3led 3ab3lei a3blem 2ablet ab3li a2blin ab4lit 2ablo 1a2blö a2blu 1abn 2abo 3a2bo. ab2of 3a2bon 4abot 2abö ab3r a4brä a2bre ab4ros 2abrö a4bs 1ab5sc 1ab3s2p abst2 3absta 1abstu ab3sz 1abtei abte2s 3abtr 2abu abu3g4 a2bum ab1ur 2abü 1abw 2aby aby4t 3abz 2ac. 2a3ca 1ac1c 2acci a1cem a1cen a2ceo ach1a a1chal a3chari ach3as ach3au 2achb 2a1che a2ch1e4c ach1ei ach4ei. a2chep a4cherf ach5erfa a4ch3erh a4ch3erl a4cherö a4ch3erw 2achf 2a1chi a2chim ach3l 2ach3m ach3n a1cho a3cho. a2cho2r ach3öf 4ach3r 2achsc achs4el ach3s2i ach3skr achs4or ach3su a4cht ach4tak ach6terf ach8tersp ach6t5erw ach4t1o acht5rat ach8traum ach8träume. ach8träumen. ach6trit acht6s5al ach4tum a1chu ach1u2f ach3ü 2achv 4ach1w a2chy a1ci a1ckar a3ckel a2ckin ack2sp acksta4 2a1cl acon4n 2acu a1ç a1d 2ad. 2ada. 4adab ad2abr ad2ag ad1an 3adap 4a3d2a2r3 2adas 2adat a2d1au a3dau. 1a2dä ad1c 1add 2ade. ade2al a3dec a3dee adefi2 2adeg a3dell 4a3den aden1a ade4nat adeo2 ade1ra a2d1erk 4ade1s ade3s2p ades4s 2adf 4adh 4adi adi3en adi3er. adie4sc adi4st 3adj 2adli 3admi 4admu ad2ob ado2n ado4na a2dop ad2os 2adp 2adq a2dre 2ad3rec ad3rei ad3run 2ads2 ad3st ad3sz 2ad2t1 ad4te2 1adv 2a3dy 2a1e1 ae2b a2ec ae2ck ae2d ae2i a2ek a2el a3el. a4ela a4ele a4eli a3els ae2m ae2o3 aeop2 ae2p a3er. 3a2er2o1 aes2a ae2sc aes5t a2ew ae2x 2afa af1ab a2f1a2n a3far a2f1au 2afä a2f1än 2afe a2f1ec a4fentl a4f1ep aff4a af2f3l aff2s aff4th 2afi afi6kanz afi4kat afi2t 2af3l af1la a1f4lu 2afo a2f3oc a2ford a2f1ort afo1s 2afra af3rau af3rä af3re 2afro af3rö af4rü af3s2a af3s2h af2si af2sp afs4t af2t1a af3tat af2tei af2te2l aft4erk af2t1o af2tö aft3r af2tra aft5rei aft4stä af2tur a2f3ur 2afü afür3 a1g 2ag. 2aga ag1a2b ag1a2d ag1ar a2g1au ag2del ag2dr ag2du 4age. age4l3ei age4ler 4a3gen. age4neb a2gent 2ages age4sam age4s3in ages3p ages6sen ages3ti 3aggr a2g1id a2gim 2a2gl ag4lan ag4las ag3le a4glö 2agm ag2n ag4nat a4gnä ag4ne. ag4nu ago3b ag3rat a2g3re a2gri ag3rie ag3rin 2ags ag3s2ah ag4sam ag3s4eid ag7s8porta agst2 ag1ste ag3stö 2agt ag2th 2agu a2gund 2ah. 2a1ha ah2an ah4at a1hä 2a1he ahe1in a2h1er2h ahe1s ahe3u a1h2i ahin3 ah2l3a2 ah2l1ä ah2l1ei ah2lel ahle4na ah4l3erd ah4l3erh ahl1o2 ah2lö ahl3sz ahme1i ahme3s ah3mu ah4n3a ah3nee ah2nef ahn3el ah4nerd ahner4e ahner6le ahner4n ah2nin ah2no 1a2hor ah1os ah3ös 4ahr ahr1a ah3r2e ahren6sc ahre4s ahr6tage ahr6teng ahr2ti ahr4tro ahr4tun ah2ta ah2te2l ah2t1ex ah4t3r aht3s6 a1hu ah1w a1hy 2ai. ai1a4 a1ia. 2aib ai2bl aid2s ai1e4 ai3en3 aif4 ai1fr a4i3g4 a3ik. ai3ke ai2lar ail3d4 ai2lei ail3g ai2lo 4ain ain2a a1ind ai5n4e ain3s ains2p 3airb ai2sa a3isch. ai5schw ai3s2e ais4se. ait4 a3iv. a3ivl a3ivs a1j a2jat aje2 ajekt4o 2ak. 2aka. 2aka3b akab4r a2kad 2akal 2a3kam 2akan 2akar ak4at akat1a aka4tak 1akaz 4akä 2akb 2akc 2akd 2a1ke a2kef a2k1em a2kent a2kes ak2et a2keu 2a1ki ak1ins aki1s 1akku 2ak3l a1k4la ak4li 3aklö a1kna 2ako 2a1kr 4akra ak3res a3k4ri 3akro ak3rü 2aks ak3sh ak2t1a2b 2aktb ak2tel akt2er 2aktg 2aktik 2aktis 2aktm ak2to4b ak2tö ak2t3r ak5t4ri 2aktsi 2aktsp 2aktst 2aktw a1ku 2akun a2kup 2akur aku2s 4akü 1akz 3akze a1la 2ala. 2alabo al1af al1age 2alai al1akr al1am al1ana 2aland a2lang al1anz al1app a3lar. al3arc a3lare 2al1arr a2lart ala2s al1asi al1ass a3lat. al4atm alat3z al1au al3aug a1lä a2l1äm al1än al1ärm al1äu 3albat al2bär alber4e al4berh al4b3er4w al2b1l al2boh al2bon alb3ru alb3st al4dan al2dä al4d3erl al4d3ern alde2s ald3inn al2dra al2drä alds2 2ale 4a3le. ale4ar a2l1e2b al1eck a4l1ef a2l1ei a3l2eic a4lein a2l1el 3a2lema a2l1e2mi 4a3len. alende4 al3endr a4l3ends a2leng al2enn ale2p al1epo 4aler. a2l1erb aler2e a2l1erf a2l1er2h aler4kl a2l3erl al1erm aler4mi a2l1er4r al2ers a2l1ert 3a4l3erwä 4ales a2l1e4sk a2less a4leth a2l1eu alf4r 3algi al2gli al3glo 1algo 3algor alg4r 2ali al2imb al1imm ali4nal al1ind alin4ge a2l1in2q al1ins alken1 al2klö al2kne al2kof 1alkoh alk3s2 alks4t al2lab al3lad al2l1an al2l1a2r al3le. al4lec 3allee al3lend all3erk aller4z al3les al2lid alli5er. alli7ers. al2lob al2lop al2löf al2map al4m3ast almo6de. 2alo. a2l1ob 3a2loe a2l1of 4alog alo2ga alo2gr al1ont al1ort 2alos a2l1ö al2ös 3alp. 3alpe. 1alph al2pho alrat4 al3sak al6schei alsch3s al3ska al5s6terb al2stu al2sum al2t1ak alt3alg al3tam al2tan al2tat al2tau 1altä alt3eis alt3elt al4temu al4t3er5f al2teu al2tid al2tin alt1op al2tö al4t3rat al2tre al4t3ri al2t3ro alt4stü a1lu alu3b4 al2u3f alu3g al1u2k a2lum al1umb a2l1ur a3lus 4aly al2zar al2zau al3zen alz4erk al2zw 2am. am2a ama2ba ama3d2 ama3g a2malg 2a3m4an 1a2maz 2amä 4ame. a2meb 2amel am4e4n1 amen6spr ame3r2a amera3u a2m1erf 1a2meri ame5r2u 2ame1s a4mesh 2a3met 2amf a3mi. a3mie ami2k am4ing 2a3mir 2a3mis 2amit 2amk 2aml 2amm. am2mab am2m1ac 2ammal am4mant am2mar am2mei ammes3 am2mid ammi2e am2min am2mor am2m1ö ammu2 amni1 a2mö 2ampe. 2ampen am4pf amp2f1a2 2am2ple 2ampo am3pr amp3s2 2am2s am3sa 4amsc am4schl 3amse am3s2h am3so am3sp am3su 1amt. am2t1a2 am4tau am2t1ä am2tei amt3eig am4tel am2tem amter4 am4terh am4t3ern am2t1ex am2tis am2tit am2to am6tou am2tö am2t3r am4tre am4tri am2t1u 2amtv 2amu 3a2mul 2ana. 2anab ana3c 4an2ad anadi1 an2ag 2a3nak an1alg ana4lin 2anam an2a3ma 2anan an4and 2ana1s a5nat. ana4th a5n4atm a2nato ana4tr a5nats an3aug 1a2n1äs 1anb 2anbas 2anbö 2anbu an3ch 2and. 3an3d2ac and3arm and3ei anden6ga an4d3ent and5erob ande4sc an2d1ex and4sas and4seh and2so and6spar and6spas and2su 4andu2 an2d1ur andy1 2ane an3e2c a3nee an2ei. an3eif 3aneig a4neis 3a2n1e4k ane2l an1e2mi a2nemo aner4fa a3nerg an2erh a4nerke 4anern a4nerz. an4erze an1eth 3anex 1anf 2anf. 2anfab 3anfä an3fe 2anfi an4fj anf3le 4anfors anf5rau 2anfs an3f2u 4ang. 1anga 2anga. an2g1ar 2angas 2ange. 1angeb an2g1ei an4g3erf an4g3er4h an4g3er4w an4g3erz 2angh 2angie ang1l an2gla ang5n ang1r ang3ra 1an3gri 2angs. ang4sto angt2 1anh 2a3ni an2i3d ani3els ani5ers. anig2 ani3ke 3a4nim a4nind ani2o an3i4on a4niso 2anj 2ank. an2kab an2k1ak an2kan an2kei 2an3ken ank5erfa an3kes 2anki an2kid an2klö an2klu ank3no an4k3opf an2kor ank1r ank3ra an4kras ank3rä an2kro 2anks ank3se anks2p 2ankt4 1anl 2anlad 3anlag 2anmo 1anmu 2ann. 1annah an2nar an3ne an4nef an4nei an4nene annen3s4 ann2er 2anns ann4s3p 2annt 2ano. 1an1od 2anof 2anog 2a3nol ano2la 1a2nom a3nom. 2anoo a2n1or ano2ri 2a3nos 2a1nö 2anpu 1anr 2anrö an4same an3sar 1an3s2ä 3anschr an3skr ans1pa ans3pon 1anspr 1anst an3s2z 2ant. ant3ar anta4re an3t2ä 1antá 3antei an3tha 2antie 3antise anton2 1antr ant3rin 1antw 2anu anu3r anu1s a1nü 1anw 2anwi an2zä 2anzb 2anzd 1anzei anz3elf anze2n 2anzes 2anzg 2anzh anzi2d an2z1i4n 2anzk 2anzm 2anzr 2anzs 2anzt 1anzü 3anzün 2anzv 2anzw an2zwi 2anzy 2ao aof4 ao3i a1op aopf4 a1or a1os5 aost2 a3ot. ao3t4s 2a1ö2 a1p 4ap. ap4a apa3b a2pe. a3pel a2pé a2pf ap2fa 1apfel 2apfes a3pfl a2pht 2api 2apl ap4la a3plä ap3le ap3li ap2n 3a2pos a2pot ap3pu 2apr ap2so aps4ter ap5t2 2a3pu 2ar. a1ra a3ra. ar2ab 2ar3abb ar3abf ar3abt ara3d2 ar3adr ara3ge 2a2r3al a3r4ale a3rali a3ralo 2aran a2r1ang a2r1anz 2arap a4r3app 2a2rar ara2st ar2asy 4arat a2r1au a1rä ar1äs 1arb 2arb. 2arba ar2bak ar2b3at ar2bau 4arbef ar4b3ein 2arbek 2arben 2arber arb3erl 4arbi 2ar2bl 2arbo 2arb1r 2arbs2 arb3sk arb3so 2arb3t2 2arbu 1ar1c 2archl 2archr ar2dau arde4i ar2dop ar2d3r ar2du a2rea are5aler a2reb4 aree2 ar1eff a2reh ar1ehr 2arei a3rei. ar1eid a3reie a3reih areim3 a2rein arein4b arein4s arein4t a2rele 4arem 4aren. aren6sem are3r2a arer2e a4r3erei a2rerg a2rer3h a2reri a2rerk a2rerl a2rert ar2erw 2ares ar2et are3u a2rev arf1r arf3ra arf2sp 4arg. ar3gan ar2gl ar4gn 2arg4o ar3g4r arg4s 2arh 2ari ar2ia a2rid ari3e2n ari3erd ari3erg arin3it arin3s4 ar1int a3r4io ar2ir ar4is ari2su a3riu ar2kal ar2k1ar ark3aue arker2 ar2kil 2ark3l ar4klag ar2kle ar2klo ark4lö ar2koa ar2kor ark3s4a ark2se ark3she ark4tre ar2les ar3mad arm1au ar3m2ä ar2m1eg ar2m1ei arm2or ar2mum 4armü 4arn ar2nan arn2el ar3ni a1ro arob2 4aroc aro8ckeng ar1o2d ar1of aro2fe 2a3rol aro3m a2r1op a2ror aros3 aro4st 1a2rou a2r1ö4 2arp arr1ac ar2r1ad ar2r1as arre4n1 ar2rh 2arri ar2r3or ar3se ar3s2h ar3s2i ars3ka ars4kat ar3sta ar2tau 2artb ar3t2e 2artei 2artex ar3t2i 2arto art3r art4res ar2tri 2arts art3ske art2sp 2artuc 2arty 2aru a2r1uh ar1um a3rumm a2rü 2arv arwa2 2a3r2y 2arza ar2zau ar2zä 2arze 2arzi ar2zö 1arzt arz4tei arz4tem arz4ti arz2t3r 2arzu ar2z1w 2asa a4s3aa a2s3af a3sag a3s2al asal2t1 as1am as3art asa2s as3at asau4f a4s3aug a2sä as3ät asbes2 a6sca a4schec a4schef a4sch3ei a6scher6g a3s4chi a2schm 2ascht a3schu a4schum 2asd 4ase a2seb a2sec a2s1ef as1eie as1emi a3sen. ase4na ase4n3o asen6sem as2er as4erd ase2re aser6geb a4s3erke as4es ase4t a2sex 2asf asges4 2ash a3s2hi as3hir 2asig a2s3i2k 2asim asin2g as1inn 2asis aska3s as3ku 2aso as3ob as1of a3sol a3som as1o2p as1or a4soz a2sö a2s1p aspek6to as2ph a3s2pi as3pik as3pio a4spir 2aspr as2pra 2as3sa ass2a3b ass6aus. ass2e ass3ein asse3le ass2i as3ski as3so as2spo as2spr as2st as3sta as3stei as3sti as3str as3stu 2asta a3stad a1stas as3tat a3stä as3te ast2el ast2er as4t3ese as4tex as2th ast2id as3tie as3til as3to as4tof ast3orc a1str ast3re as3t4ren as6t5ritt ast5roll as3tub 2asu as2ur asu4s3 a2sü aswa2s 1asy 3asyl 2asys a1ß aße4 aß2en3 2a1t 4ata at1abe at1abr at2a1f a5ta3g at2ago ata3la a3tam at1apf at2ast at3att a2t1au at1än 4atb at2c a2teb a3tec ateien6d at1eig 3a2teli 3a2temg at2en ate4na aten3s4e a2tep 4ater ate3r4al ate3ran at4ere atern2 ater3st ate2ru 4ates ates4sa a3tet at2eu a2tew 4atha at3hag at3hal a3t2heb ath3in. 3athl a4thr at2hu at3hü 4a3ti ati4kab ati6k5erw a4tinf at2is ati2sa ati2se a4tiso atis3s ati6v5erf 3atla 4atli 3atm 4atma 4atmä 4atmus a2t1ob 3a2t4om atom1e ato2mo at1op at1ort a3to3s atra4t a2t3rau a2t3rä at3re at3rin at3rom at4ron at3rot at3rü at2sa at4schn at2se ats1e2h at2si ats1in at2s1o at2s1p ats3tät at2su at3ta 3attac at4tad at4t1ak atta2l at4tale at4tals at4tang at4tar at4tau at2tä 4atte. at2t3ec at2tei at3t2el 4at5ter at3thä at3ti 4atto at2tob at2t3rä att3s2 at3t2u 4atu a3tub atu2n a3tü atze4l atz3ela atz3elt at2zem at2z1er a3tzere at2z1in atz3t2 at2z1w a2u 2au. 2au3a2 2aub au2bab au2ban au2b1au aube4n au2beu au2blä au2bli au2blo au2blu aub2si 2auc au2dr 2aue aue2b au2ere aue3rei auer3ö au5erst. au3ert aue2s au2fa auf1ak auf1an 2aufe. 2aufeh 4aufen. 3aufent auf1er au4fer4k au2feu auff4 auf3ind 1aufla 1aufn 2aufo auf3ski auf3t2 2auft. 2aug au2ga au3g2ar 4augeb 4augeh 4augel aug2er 4augl 4augr au3gu au3h 2au1i au2is 4auj auk3t aule2s aul4les au3lü 4aum au2mal aume4n au4m3ent au2m1e2r1 aum3eri au2m1id au4mil au4mit au2m1o aumo2r aum3p2 aum3s6 au4mun 4aun au3n2a aun2e au4n3ei au2nio au2no au3nu a4unz 2aup2 2aur2 au1rh aurü3 au2s1ah ausan8ne. au2sas au2sau 2ausc au6schmi 1ausd 2ause. au4s1eh 2ausen au4s3erb au4serf au4s3erk aus3erp au4serw 1ausg au2sin au2sis 1ausl au2so aus1or au2spr 1ausr auss2 3aussag aus4se. aus3st aust2a 2auste au5stein aust2o aus5tri 3ausü 1ausw 1ausz auße2 2aut. au2tab au2t1äu 2autb 2aute au4t1e2l au4ten4g au4t3erh aut5ero 2autg au2thy 1auto au4trö 2auts 2auu 2auv auve4 2auw 2aux 2auz auz2w 2a1ü a1v av2a a3vang avas4 ava3t2 avener4 2avi a2v3r 2a1w awi3e a2wr a1x ax2am a2xans a3x2e a3xid a2xio axis1 2a1ya a1yeu ayma4 ay1of ays2 aysi1 ay3t a1z az4a a3za3d 3azal a3z2i az2o a3z2u az2zen az2zw ä1a 1ää 2ä1b ä2b3l äb2s äbte1 ä1ce ä1che äche1e äche4n ä1chi äch3l ä2chr äch4sa äch2s1o äch2sp äch2st ächt4e ä1chu ä1ck ä1d ä2da äde1s2 ä2d1ia ä2d3r äd2s äd3te 2ä1e äe4k ä3eu äe2x äfe4n äf2fl äfig3 äf3l äf3r äf4ro äf2s äf3t2e äft4s3 ä1g ä2g1a 1ä2gä ägd2 ägen4e äge2r3a äge3s ä2g3l äg2n ä2g3r äg4ra ägst2 äg3sta äg3str 1ä2gy äh1a 2ä3he ä4h1ei äher8gebn äher5t ä1hi äh1in ähl1a äh3l2e äh4l3e4be äh5ler 2ähm äh3na äh3ne 1ähnl 2ähr äh2rel äh3ri 2ähs 2äht ä1hu äh1w 2äi ä1im ä2is ä3is. ä3isch. ä3isk ä1j ä1k äka2la äk3l ä2kle äk4li ä2k3r ä1la älbe2 äl4bl älk3 älks4 äl2l1a äl2p3 äl4schl äl2st ält2e älte1i ä1lu 2äm4a3 ä3me ämer2s ämi3en 2äml ämoni3e 2ämp ämp7f4e äm2s ämt2e ämter3 2än. än2dr 2än2e äne2n1 äne1s 2än2f5 änft2 4än3g2e änge4ra 2än2gl äng3le än2gr äng3se 2ä3ni än3k2e än2k3l än2kr änk2s 2änn än3n4e2 2äns än4s1a än2s1c äns2e 2änz ä1on äo3s2 ä1pa 1äpfel äp2pl äp2pr äp2s1c äp4st 1äq ä2r3a4 är4af är1ä är2b3le är1c 2ärd ärde4s 2äre ä2r1ei ä2r1e2l äre2m är1emi äre2n ä2rene ä2rerh är2es ärf2s är3ge ärg4s ä2r1ind är1int är3ke ärk2s ärm3arm ärm3at ärme1e ärm3ent ärm2s är1ob är1of ä1rö är3re ärse2 är2seb är4seh ärs1er är2si är3spu är2st är3str 2ärt ärt4e är2th ärt2s3 ä2rü 1ärz är2zu är2zw 2ä3s2e äse3g äse1i4 äse5ref äser4ei äse4ren äser2i ä3s2kr ä2s1p 2äs2s1c äss2e äss5erkr äss5ersa äss3erw äs2sp äs2s3t ä4s3t äst4e 1ästh äs4tr ä3su ä1ß äß1erk äß1ers ä2t3a2 2ä3te äte3a äte1e äte1i äte3l2 äte2n äteo2 äter4bl ät2et ät1id ät1ob ä2t3r ät4s3a ät2sä ät4schl ät4schr ät2s1i2 äts3l äts1or ät2s1p ät2s3t ät2su ät2tei ätte4n ät4tr ätze3l ät2zw 2äub äu2b3l äu2br äu1c äu3d äude3 äuder2 2ä2uf 1äug äug3l 2äul 2äum äu2ma äum3p äumpf4 äum4s5 2ä2un äun2e äu3nu 2äu3r2 äure1 2ä3us. 2äusc äu4schi äu4schm äu3s2e äuse1i ä3usg ä3usk ä3usn äu2s1p äus2s1c 1äuß äut2e äu2tr ä1v ä2vi 1äx ä1z ä3ze â1t á1n 3ba. b2aa b3a2ba 2babf 2babg ba2bl ba2br 2b1abs bach7t4e ba4ck3er back3s4 ba3d2e bade1i 2b1adel 2b1adl 2b1adm b1a2dr ba2du 2b1af 3bah bah6nene bai3d bais2 b2ak ba2ka ba2k1er ba2k1i ba2k5l ba2k3r ba2lab ba2l1ak ba3lal ba2lau baler2 ba4l3erk balk4a balke4 bal4l3eh bal4l3ei bal6lerg ball6erk 2b1am b2a3ma ba2me 4bamt ban2a 3b2and band1a ban4dal ban4dan ban4dar ban6deng ban2dr ba3n2e 2banf b1ang ban3gl ban4k1a banker4 ban2kl ban2kn ban2kr ban2ku 2banl b1anna ban2o 2b1ans b1ant 2banw b1anz ba2r3ab ba2rad bar3ast ba2rat bar3de ba2rei ba3r2en barer5ei barer4t barf4 3bar2s bar3sc b1arz bar3zw 3b2as ba3sa ba2sc bas2i bas4sa bas4st ba2st ba4t3ent bat2o 3bau. bau3b bauer4l bauer4s bauer4w bau1fl bau1fr bau3g2 b2auk bau3r bau1s bau3s2k baus4t b1a2x ba1yo 3b2ä1c 3b2äd 2b1äh b2äl 2bärz b2äs 2bäug 4b1b b3be bbe4n3 bbens2 bbe4p bb3le. bb2lö b3brec b3bru bbru2c bb2s bbu1 4b1c 2b5d2 bdä4 bdän3 bde1s bdome4 1be. 3bea be3ab be3an beat2m be3au be4au. 3beb b1ebb 1be1c 2becht 2b1e2del bedi4 be1e2h bee2l be3ela bee4rei be1erh be1erl be1ert be1eta bef4 2b1eff be3g4 be2he. beh5ri bei3b 2b1eier bei1f4 bei4ge. beige4l beige4p bei3k4 bei3l2a 2b1eime be1ind be1inh bein6hal bein4hi bei3sc beis2e bei1s4t beit4e beit2s beit4sk beits3p 3bek 3bel be3lag be3las bel3d be3lec 4be2lek be2l1en bel3ere be2let bel3f beli4e bel3la belle4n3 bel3li bel3om be2löf bel3sz belt2 bel4un 1bem4 3b2em. 3b2e3ma 2b1emp 2bemul 1ben be5nabe ben3ar be4nas be4nat be2nä b2ene be3nei be4n3end be4ners ben2eu 3beng be2nid be4nis ben3n 5benp b2ens ben4s3pa ben4spr benst4 3bensz 2b1entb 2bentd 4benteu 2bentf ben3th ben6thei ben5t4r 2b1ents 2b3entw ben3un b2en3z2 be1o 2b1epi 2bepoc be1ra be2rak be2r3am be2ran bera2s berb2 berbla4 ber3d be2r1e2b be4reck be4r3eiw bere2m be4rene ber4erg ber4erw bere4sc bere4t berf4 ber4g3af ber4gal ber4gli ber4hab beri2d ber4in. be5r6inne berin4s be2ri4o ber3iss ber3ko ber3kr ber3n2a bern2e b1ernt be2rö 3bers. ber5se ber3st4a bert2a bert2e bert2i berz2 ber3ze ber2zö 3b2e1s be3sa bes4abb bes2am bes2an be4sap be4sar bes2au be2sep be2s1er be2s1id bes2po bes3sa bess4e b3esst. bes3sz be4stab beste2 be6stein bester4 bes6terh be4s5tol bes4t3o4r bes3tos best4r be4s3trä be4s3tur be2sur be3s4ze 3bet be3tam be3tha be3thi bet2sp be1un be1ur 3bev 3b2ew2 2b3e2x 3b2ez 2b5f4 bfal2 bfal3t 2b1g2 b5ga bge3 bgel2e bge5n bges4 2b1h2 b5hä 1bi bi1ak bi2ar 3bib2 bibe2 biber1 bi2c bi3do bien3s bieres4 bie2s biet2s 3bietu biga1 bik2a bi2ke. bi2kes bi2kre 3bil bil2an bil3ans bil4deb bi2lei 4billu bi2lu 2bimp 2b1inb bin2e bine4n b1inf bin4fo bin2g3a 2b1inh bi2n3ok bin4ol 2b1int 2b1inv bi2o3 bioi2 biri1 3bis bi3si b1iso bi2sp bis2s1c bi2st bi3sta bi1s4tr b2it. b2ita b2ite b2iti bit4r bi2tu bi3z2 4b1j bjek4to 2b5k4 bl4 2bl. bla3b4 2b1lac b3lad b2lanc blas3er b2latt b2lau. b3laus4 2b3law 2b1län b2läse 3blät b2le 3ble2a b3leb 3blec b3leg 4bleh b4lei. 2b3leid 2bleih b3lein blei3sc 2bleit ble3l ble2n b3lenk b3lese 2blesu ble3s4z 3blet b3leu 2blich 3blick b2lie 2blief 4blig b2lind 2b5ling4 b2lis 2blis. b2lit b3lite b2lo b4lo. 3b4loc b4loi b3los 3b4lum 2blun b2lus 3blut blu4tem blut1o 3blü 2b1m 4b5n2 bnas4 bni2 bnis1 bo4a bo5as b1o2b bo3ben bob3r bo2c bo3ch2 bo3d2 boe1 bo2e3i 2b1of bo3fe bo3he boh2ra boh3rer boh2u bo1is bo2lan bo2lau bol5le 3bon. bo3n2a bon2da bon2d1e bo2ne 3bons boo4l boo2ti b1op 3bor. bo1ra bor2an bo2r3as bo2rau bo4rä bor2da bor2d3r bo2rei bo4rig bor3m bor2s b1ort bor4ter bor6t5rat bo4ruh bo2sc bo3se bo4s3p bos3t 3bot bote3n4e bo3th bot2st bot5t bo2xo b1oz bö2b3 2böf 2b1öl bölk3 2b1p4 bpa2g 2b1q b2r4 2br. b4ra. 2b3rad 2b4rah b4ra3k brast4 2b3rat. brat3er4 bra6terg 2b3ratg 3brä 4bräd brä4u 2bre. 6b5rechte 2b3red 2b3ref 2breg b3reif 2brek breli1 b4rem b4ren. 2b3rent 2breo 2b3rep b4rer b4res. b3rest b4ret bret6t5en b4rez bri2da brie4fa 2b3riem b4rien bri2er b3ries 2brigk b4rina 2b3rind b4rio b4risc b3ritt brob2 2b3roh 2b3rol bro2ma b4ron 2b3rost bro4tr brot3t4 2b3rou 3b4rö b4ruc 2bruf b4rum 2b3rund brus4 brust3 bru2th 3brü 4b3rüb 2b1s b2s1ad bs2am bs3amb b4s3amt bsau2r b4s3är b3s2äu b3sc bsch2 b4schan b6schef bs2chi b4sco bs2cu bse2b b3sel. bse2n1 b3sen. b2s1ent bs1erf bs1erg bs3e4r3in bs1erk bs1ers b3s2es b2sim bsi4t b4ski bs2ku b2s1of b3s2oh b3sol b4sop bso2r b2sö b3s2pi bs2pl bs2pu bss2 bs2t bst1a2b bst1ak bst3ank bs4t1as b3stä bs3tät bst3emi bst1er bst1h bst3ink b2stip b3sto b4stob b4stod bs4tol b4stor b3stö b4strac b2s3trä b4s3treu bs4tri bst3ro b3stü b4stüb b2s1un bs2zep bs2zi 4b1t b3t2a bta2s btast3r b5te b2t1h bt2i bti2s bt4r btran2 bts2 b3tü1 buche4 bu4chec bucher4 bu6ch5ers bu2chi buch3s4p bu2e3 bu2f bug3 bu2gr bul2l3a 2bumf 2b3umk 2buml 2b3umr bun4a bun4d3er bunde4s b1une bung4 b3un3gn 2b1unh bur1c b2ure b2urg burg1a bur4gan bur4gar bur4gin bur2gr bu3r2i 2burn b3ursa burts3 bu2sa bu2sc bus3cha bu3sche bu6schei bu6sch5el busch3w bu3shi bu2sin bu2s1p buster4 bu2su but2a buto3re 2büb bü1c bügel3e 2b1v 4b5w 3b2y1 bya2 byo2 by3p2 bys4 2b1z4 b5ze bzeit1 1c2a cab4 ca3bl 3ca2c ca2e3 ca3g2 ca1h cal2a cala3b cal2f3 cal3t 3cam 2can cana3 ca2pe car5n2 carri1 car2s ca3s2a3 cas5to ca3t2h ca1y2 cä3 cäs2 c1b 2cc c1ce c1ch2 c2d2 c3do 2cec 1ced ce2dr 2cef ce1i ce3in 2cek 3cels cen3a ce3nu cen3un ceo2 1cer cer3a cere1 cere3u ce3r2i ce4ris ce1ro ce3s4h 1cet ceta2 cet1am ce1u 1cé c1f c1g4 c2h 4ch. 2chab ch3a2b3i cha2ck 2chaf 2ch1a2g 2ch1ak chal6l5ei chan4a 3chanc chan3f ch1ang 4chanl 4chanz 3chao 4char. 3chara 3chard 3charta cha2sc chasi1 1chato 2chatt ch5austr chau3t ch1äh ch1ärm ch1äs 1châ 2chb 2chc 2chd che3b4 ch3e4ben ch3echt ch1edi che2el 1chef 3chef. che4fer 3chefs 2cheh 2chei ch1eim 4chelem che4ler 3chemi 2chemp che4neb che4nid che2no 4chents 4chentw che2r3a 4ch3erbs 6chergeb 4cherke cher6zie ch3es4s ches5t 4ch1e4ta 2ch3e4x 1ché 2chf 2chg 2chh 1chia chi3na 4chind 3chines 2chinf 2chinh 2ch1ins 2ch1int 2ch1inv 1chip. 1chiru 2chiso 2chj 2chk 2chl4 ch2le chle2i ch3lein ch4len 4chli ch2lu 4ch2m4 4chn4 chner8ei. 2chob cho2f ch1off chof4s ch1oh cho3l2a ch1orc cho4rei ch1ori ch2os ch3öl 3chör 2chp ch2r4 2chra ch3rad 2chre ch3rh 4chrit 3chromo 3chron ch5ros 4chs ch2spo ch4stal 2cht ch2tru 2chuf 2chuh 2chum 2ch1unf 2chunm 2chunt 2chur ch1urs 2chut chut4t 4chü 2chv 4chw 1chy 2chz ci1c ci1es c1ind cins2 c1int ci2s1 1ci3t2 c1j c2k 4ck. c4k1a 1cka. 2cka2b 2cka2c ck2ad 1ck2ag 2ckal cka2m 2ckan 2ckap cka4r1 1ckat ck1ä 2ckb 2ckc 2ckd 1cke 2cke2c 2ck1ef 4ckeff 2ck1eh 4ck1ei 2ckemp cke4na 6ckensem 4ckentf 4ckentw cke2ra ck2ere 6ckergeb 4ck3er4hö ckerk4 cker6lau ck2ern 2cke2ro ck1err 6ckerzeu 4ckese ck2et 4ckex 2ckf 2ckg 2ckh 1cki 2ck1i2d ck1in 4ckint 3ck4is 2ckk 2ck3l 2ckm 2ck5n 2ck3o2 ckos6t ck3ö2 2ckp 2ck3r 4cks cks2al ck4spen 2ckt ck3te ck3t2i 1cku 2ck1uh ck1um 2ckunt 2ck1up 2ckü 2ckv 2ckw 1cky 2ckz c2l2 cle4a clet4 clin2g cli2p1 clip3a clo1c clo2ck clo3f 1clu clu4b c2m2 c3me c3mu 1c2o co2c co3ch co2d2 co3di cof3f2 coi4 co1it co2ke co3la3 co2leu co3l2o com4te. comtes4 con2ne co2o coo1p co1p co1ra cor2da co4re cor3t cos3t co4te cou3si cô4 2cp 2c1q 1c2r2 c3rä c4re2 cre4mes 3crew 2cri cros4 2cry 2cs cs2a cs4f c4si cst2 c1s2ti c1s4tr 4c5t cti2 cti4o2 ction3 ctur6 c6tz 1c4u 2cua cu2e cu2p3 cup1e cussi4 c1w 2cx 1cy c1z 3da. da1a 2d1ab d3a2bak d2abä d2abe d3a2ben d3a2bi da3blu d3a2bo dab4ra da2bri da3brie d2ab4rü d1ac dach3a da2cho 4d3achse 2d1ad da2de da2do da2d4r d1af 2daff da1f4l dafo4n d1ag dagi4 dag2o da1h dah3l dail5 da1in 2d1air da1is da2kro dal2a 2d1a2lar dal3b2 4d1all da2lop da3lö 2d1alp d1al3t 2dalte da1lü 3dam da2mei d1amma 4d1ammä damo3 d2amp damp7f8erf 4d1amt 3d2an. d1ana da2nan da4n4at 2danb dan4ce. d1and2 2danda d2andy 3dane 4d3anei 2danf d1ang 2danh dan2kl dan2k1o dan2kr 2danl d1ann 2danna d1a2no 2d1ans 2dantw 2danw d1anz d2anz. 2danzi 2danzü 2d1ap d2apa d2aph da2po da3pos 4dapp d3apte 4daq da4r1a 2darb2 2d3arc dar2d1e dare2 daren1 dar3g dark2a 3darl dar2m1a dar2m1i dar4mu da2r3o 3dars 2d1art dar2th dar2tr da2ru d1arz da1s2 da3sh d1as3p das3s das4t dat2e2 da3tei 4d3a2tel date4n da2th 2d3atl 4datm d3ato dat2st 2d3atta 3daub 2daud dau3e2 dauer3e daue6rei 2d3au2f 2d3aug 2dauk da3unt 2d1aus3 dau2ß 3daw d1ax 3däc 2d1äg 2d1äh 2d1ämt dän3a 2d1änd 2d1äp 2däq 2därz 2d1ä2u dä3us 2däx 4d1b4 dbau2c dbauch3 dbe2e dbu2c 2dc d3ch 4d1d2 d3da d3dä d3de d3dh 1de dea2d de3ar de3a2t deb4 3debü de1c de4ca. de2cka de2del de2dit 2de3e4 def4a de2fa. 2d1eff def4l deg2 degene7 de3gl deh2a dehe2 3dehn de3ho 2d1ehr d1ei 3d2eic de3i4den de3il 3d2eim 4deime dein2d de3inse de3inst dein6sta dein6sti 4d3einw de3io 2deise d4e1ism dei2sp 2dekz de2l1ac del4ade de3lak de4l3aug del3änd del3b2 del3d del1ec 3de3leg delei4g 2delek 2delem de2len deler2 deler4r 2delf. 2delfm 3delik del2la dell3au del2l1ä delle2 del4l3eb del4lei del4l3er de2l1ob de2lop del2se del2so del2s1p del3t4 dem2ar 2d1emb dement4 de6mentg dem5ents de3min 2d1emot 2d1emp d2emu d4en. den2am dend2 de2n1e2d de4n3end de2nep 4denerg de3n2es 4d3en4ge. de2ni denk3li dens4am den6scho dense2 4den4sem den6sere den6s5tau 2dentd 2dentf 2dentg den3th 2dentn 2dentw 2dentz den6zers de2ob 2deol dep4l 2depoc d4er. der3af de2rak dera2n de3rand de2r3ap de1r2a4s de4r3asi der2bl 4d1erbs 2derdb de2r1e2b de4reck de4r3ei4s 5d4erem d4eren de4r3end 5d4erer der4erf derer3n der3ero derer4t derer6ze 5d4eres de2r3eu derf4 d4erfl d3erheb d2erhü de2r3id derin4f de6rinnu derin8teg der3k2 4derklä d2erm de1ro derö2 der3r derst2 der3sta dert7ende. derter6e dert4ra 6dertrag der8trage 3de3ru de4ruh de4rum 2d1erz. 2d1erzv d2es. de2sa des1ah de4sam de2s1än de2seb de4se2h de2sei de4seil 2d1esel des3elt de3sem de3s4end desen3e de2set de2sin des1o de2sor de2s1p de3spe de3spu dess2 dess4t dest5alt des6temp de5stern des4tex de1sto dest5rat de3stri des4tum de2su des1un 3desw det2 de3ta deten4t 2d1e2th 2d1etw 2d1eul de1un de1url de3us 2d1e2vid devil2 de1x2a de2xer de2xis 2dexpe 2dexpo 2d1f6 2d1g2 dgas3tr d2ge. dger2 dge3s d2gesh dge2t3a dge4t1e 2d1h2 dha1s4 4dho d3hu 1di di4ap di2a3s4 diat4 di4ath 3dic di1ce di3chl dicht6er di4ck3el 4d3i2co 3dida d1ide 2didee di2den 2didy di2e di3e4d di3enb die4neb diener6l di3e2ni dienst5r die2p di3ers. dies1c di3e4th 3dif 3dig dige2s dig4n dik2a dil2s3 2d1imb 2dimp din4a 2d1ind di3n2e 2d1inf 3ding 2d1inh di3ni 2d1inj 2d1ink 2d1ins 2d3int 2d1inv di2o3b dion3in dion3s4 di3ora dios2 di2osk di1p2 di3pt d1i2ra di4re. di2ren di2rin di2ris 2d1irl 2d1irr di2s1a2 2d1iso di2sp di3s4per 2d1isr dist2 di1s4ta di2s3te di4stra di4sz di2ta dite1c di4t3erl di4t3erm di4t3ers di1the di2tin di2tob di4t3r dit3s di2t1u di5v2 di3z2 2d1j d2jar 2d1k4 4d1l2 d3la dla3g dlap4 d3le dle2ra dli4f dl3m dl3s 2d3m2 4d3n2 dni2 dnis1 do5at 2d1ob 3d2oba dob2s d1of do2fe 2d1oh do3ha dole4 doll2 dol3la d3o2ly 3dom do2mal do2mar domen1 do4ming 4domn do2mu don2a do3nan doni1e 4dony 2dope 2d1opf do1r4a 2d1orc 2d1ord dor2f1a dor2fä dor2f1i dor2fl dor2fo dor2fr dor2f3u 2d1org d2orn 2dort dor4ter dor4tr d1os2 d2os. 2d3osm dos3s dos4t1 dost3a dosten4 do4stu do3ta do2tof do3un dow2s d2o3x2 d1ö dö2d dö2f döl1 döll2 d2ön 3d2ör dö2s1c 4d3p2 dpass3 dpol4n dpost1 2d1q d2r4 3d4ra. 3d4rab 4d3rad 2drahm 2d3rak 3d4ral d3ramp d3rand dran3k 2d3rast dra4tin 2draub 2d3rauc d4rauf 2draum 2draup 2dräd d4räh 2d3rät 2d3räu 4dre. 2d3rea d4rea. d4reas 3d4reck 2d3ref 4dreg 3d4reh dre2ha 2d3reic 3d4reie d4reiv d4rej dreli1 4drem 4d3ren d4reo 4d3rep 4d3rer 4dres. d4resc dres6sei dres6sel d4rew 2drez 2d3rh d4ria 4d3ric d3rieg 3drif 4d3riff d4rift 4d3rind 2d3rip 2d3risi 2driss 2d3ritu 2d3rob d3rod 2drogg 2drohr 3d4rohu 2d3roll 2d3rose d4ross 2d3rost 2d3rot 2d3rou 2d3rov d3row drö2sc d5rub 3d4ruc 2d3rud 2d3ruh 2d5rut drü1b drü5cke 3d4rüs 2d1s 4ds. 4dsa ds3ab d2s1ad ds1al d2salk d2sall d4s1amt d2san ds3ane ds3assi dsau2 d2saut ds1än ds2äu 4dsb d4schef d4schin d3s4co d2scr d2s1e2b dse2e d2s1ef ds1ehr ds4eign d2sein d2s1emb dsen3er d2s1eng d2s1ent d2s1erf d2serh d2s1erk d2s1erl ds1err d2s1ers d2s1ert d2serz dse4t d2s1eta d2s1ev d2sex d3sha2 ds2hak d4shal d3sho d4shor 4dsi d2sid d2s1im d3s2inf ds2kal d3s2kel d4sko 4dsl d4sli d3soh d2sop dso2r ds1ori d2sö ds1pas d2s1pat d2spä d2s1pec ds2pen d4speri d2s3ph d3s2pi ds2por d6sporto d3spri d2spro ds2pu dss4 dst2 d4stag d2stas ds3tauf d4s3täti d2ste d3stec d3stei d4steil d5stell d4stem d4sten d3s4tern ds2ti ds4til d4stoch ds4tol d5strei d3s4tro ds2tur dsu2m d2sun ds1url ds2zen 2d1t dta2be d3t2ac dtach3 dta2d dt2ag dta2n dt3ane d3t2as dt2ax d5tea dte3mo dt2et d2th d4thei d3to2 d4tob dt2op d3tö dt3r dtran2 dt3sa dt5st dtt4 dt2un d3t2ur d3tü d3ty 1du du1alv du1ar du2b3li du1ce duel3la du2f 2d1ufe duf4ter duf4to duf2tr 2d1uh du1i du2in du2kr dul3art 2d1umb 2dumd 2d1u2m1e 2dumf 2dumg 4d3umk 2duml d2ump 2dumr 2d1ums d2ums. 2d1umv du2n 2d3und 2d1unf dung4 2dungl 2d1uni dun3ke dun2kl 2dunr dun2s 2dunsi dunst3r 2dunt 2dunw 2d3unz du1os dup4 dur2 dur3au durch3 2d1urk 2d1url 2d1urn 2d1ursa 2d1ur3t du4schn du4schr du4sch3w 1dü 2düb d3über 2d1v2 2d1w dwa2 dwa4r dwer3te dwes2 dwest1 1dy dy2l1 dym3 3dyn dy2s1c dy2sp 4d3z2 2e1a ea2be ea2b3l ea4br ea2c eadli4 e3a2dr ea2g ea3ga4 ea3g4l eakt2 e2akta e3akto ea2la e3alei e4alem ea4l3ent ealen4z ealer2 e3a4lerg e3alex e3a2lin eal1o ea2lon ea2lop e2alti2 eal3tr ea2l3u2 eam3 e2am4e eam1o eamt2 ea4na ean3a2r e3anf e2ano e3ar. ea2ra ea3rat e2are e4are. ea2r1ei ea4rene e4arer e4ares ea2ro e3arz e3a2sc e3asf easin4 ea4sp eas3s eate2 eater1 eat4mes eat2mu eat4mun ea5tr eat3s2 e3at5t2 eatu2 e3aue e3auf eau2fe eau4fl e4aufo eau3n e2av e2az e3ä2 e1b 2eba e3bak eba2p e3bän 2ebec ebe1er ebein7h eb2el ebe4ler ebe2lo ebels4t ebel5ste ebenen3 ebe4ras ebert4 ebese2 ebe4s3eh ebe2so 2ebet ebet4s 2ebh 2ebi 2ebl e3blä eb3le. eb3ler eb4leu e3blie eb3lo eb2lö 2ebo e2bob ebot2 ebö2s 2ebr e5brau eb4rea eb2s1 eb4sche ebse2 ebs7panne ebs3tau eb4stät ebs3tem ebs3t2h ebs3ti eb3str 2ebu e2bunt ebu2t3 eby4t 2e3ca 2e3ce ech1am ech1ä 2e1che ech1ei ech2en1 e6ch5erzi e1chi ech3l ech3m ech3n e2cho. ech3ö2 ech3r ech4ri echs4er echst5re ech3tab ech3t4ei ech6terh echter8ha e1chu ech1w 2echz e1ci eci2a ec4k ecke4n1 e4ckerr eck3ser eck4sta 2eckt 3eckty 2e1cl 2eco 2e3cr ec1s 2ect e1d ed2a ed2dr ed4e ede2al ede3n4er edens1 eden4sa eden4se eden4sp edeo2 ede2r eder3a ede3rat eder3t2 edes2t ed2i e3di. 2edip edi6teng e3d2o ed2ö e3drei ed4rö ed2sal ed4seh ed2s1es ed2si ed2s1o ed2s1p ed2sto ed2s3tr ed2s1u edun3 edund2 e3dy3 edys4 2ee ee3a4 eeb2l ee1c ee4ce ee2cho e1e2ck eede3 eede1s eed3s2 ee1e2 e1eff eef4l eeg4 e1ei ee2i3e eein4se eei4sc eeis3s e2ela eel2e e3e2lek eele4n eel2ö e2e3m2a e1emb ee3min e1emp e1en eena2g e2enä e2enc een1e e3eng ee3ni e3enk e3enl e2eno4 een3s een2z ee3o e2ep ee3po eer4at e1erbt e1erd ee3re eer1ei ee4r3en4g eer2e2s eere2t eer3eti e1ermä ee1ro ee1rö e1eröf eer2ös ee3r2un e1erz ee1s2 ee3sh ees3k ee3sp ee3s4t e2et. ee3t2a ee4tat ee2th eet2i ee3t4r ee2tu ee1u2 eewa4r e1e2x e1f e2f1ad e3fah ef1ana ef1ar e2farc ef3arm e2fat 2efä ef2äl e2fäu 2efe e2f1e2b e3fef efe4l3ei ef1em e2femi efe2n1 3e2f1ene e2fent efer5f eferin6d efeuil4 3effek 1effi ef2fl ef3flu 2efi ef1id e2f1ins efi2s 2efl ef4le e3f4lu e3flü 2e3f2o 2efr ef4reih ef3rol ef3rom ef4ru ef4rü efs2 efs4c ef3so ef3sp ef2tan ef2tei ef2tro 2efu e2fum e1g ega2m e3g2anz egd4 e3ge egein3 ege4lan ege4l3au ege8l7ei8er ege4ler ege2lo eg2en ege4n1a ege6nero ege2ra ege5stal ege4s3tr ege1u 2egi 2egl e2glo e2glu e2gn eg3nä eg3ni ego1p eg4sal egsau3g eg3se eg4sei egse3l eg3si eg4sk egst2 eg4sto eg2th egung4 egus3 2e1ha eh1ach eh1ad eh2ade e3h2ah eh2al ehalt4s e3hand e2harz e3haut e1hä e1he eh1eff eh1ein eh1elt e4hense e4h3ente ehen6tr ehe3o 1e2hep 2eher ehe1ra e2h1er2f e2h1er2l ehe3str 2e1hi eh3im eh1lam eh2l3au eh1lä ehl3ein eh4lent eh5l2er ehlo2 ehl1or eh2lö ehl2se ehls2t 2ehm eh2mab eh4mant eh3mu eh3na eh3no 2e1ho eho2f eho2l eh3oly 2e3hö ehö4rer eh2r1a2 ehr1ä ehr1e2c eh2rei eh2rel ehr6erle ehr4ern ehre3s eh4rin eh1roc ehr1of eh1rö ehs2 eh3sh eh1ste 2eh3t2 eht3h eht4r 2e1hu e2hum eh1unf e2huni e3hur e1hü eh3üb eh1w e1hy 2ei3a2 eia4t ei2bar ei2bli ei4blu eibu4t ei4b3ute e4ic ei1ce ei2cho e2id ei2d1a ei3de ei4deis eid5erre 2eidn ei3do ei3dr ei1e eie2b eie2d ei3e2l eie2m 4ei3e2n3 eienge4 ei3es eie2t 4eif. ei1flo 1eifr eif3t 2eig. 2eiga eig2ar 2eigä 2eige. 2eigeb 2eigeh 4eigeno 5eigensc 4eig2er 2eiges 2eigew 2eigi 1ei2g3n ei2go ei4g3rat 2eigre 2eigrö 2eigru 2eigrü 2eigs 2eigt 2eigu 4eih ei2hum ei2kab ei2kak eik4am eik2ar eik2i eik2l ei3k4la ei3klä eik2o e2il 4eil. ei4l3ab ei2lam eila2n ei4l3ane ei4lang ei4lanz ei2lar 2eilb eil3d4 ei4lein eile2n1 ei2let eil3f4 eilm2 ei2lob eil2ö 2eim. ei2mab ei2m1ag eim3all eim3alp ei2m1or 2eimö 2eimp eim2p4l eim3sa ei2mur e4i2n1a ei4na2d ei4nae ei4n3an ei4na4s ei4n3at ei2n3ä ein3d2e ein6derk e1indu 2eineb einen4e ei4n3en4g ei6nen6se ein5erbe ei4nerf ei4nerk ein5er6la einer6sc ei2neu ein4fiz 2einfo ein4fo. ein4fos ein3g2 3einger e2ingr e2inhä ei2nie e1init ein3k4 ein6karn 3einkä e2inl ein3n2 3einna ei2n1o2 1einri e6insa 3einsat e2insc 5einschä ein6stal ein6terv 3eintö 1einu ei3o eio2p eio4s ei1p eip2f 2eir eir2c ei3re e1irr e4is. ei2sa ei3sas ei6schwu e4ise ei4ser4g ei4s3er4l ei6s5erst ei4s3erw 1eisho ei3s2ky ei2so eis2pe e2iss eisser6s 4ei1sto ei2sum ei2sur 1eiswo e2it ei2t1a2b ei2tal ei2t1an ei2tap ei2tar ei4tat 2eitä ei2tän eite4ra ei4tess ei2t1h ei2tin eito2 ei4trau ei4tro eitsa4g eit3t4 4eitu ei4t1um ei2t1ur eit3z2 eiv2 eive4 ei2zar eiz1in 2e3j e1k 2ek. 2e3k2a 1ekd ek2e e3ke. e3ke4n e3kes e3key e3k2l ek4lo ek4n e3k2o ekor4da 2e3kr ek4s1p 4ekt ek2tan ek5t6ante ekt3at ek2t1ä ek2te2l ekt3erf ekt3erk ek4t3er4z ekt2o ek2t3o4b ek5tri 2e3ku ekur2a e3k2w 1ekz e1la el2abt el3abu ela2ck el3ader el1af ela4h e2l1ak e2l1a2m el2a3mi e3lamp el1ana e4landa e2lanm e4l1ans e2l1ant e4lanw el1anz 2elao e2l1ap e2l1ar el3a2ri ela2s el1a4si el1asp ela3su el3aufw 2e1lä 2elbil 2elbr 2eld elda2r eld3ari eld4arm el4d3erf elder4p elder4s eld5erst el3des elds2 4e3le. 2e3lea elea2r 2e3leb 4ele2c el1ech 1elefa eleg3s 4eleh el3ehe. 2elei e6l5ei6ern e2l1ein e3leine e5leit 1elek 2eleko e2l1el 1e2lem 2e3lem. e3lema ele2mi e3lemm 2el1emp 2e3len. elen4k3l e4lense e2l1ent e3lep 2eler e3ler. eler2a el1erd e6lereig el1erf e4ler4fa e4lerfi e2lerg el1erh el1erk e2l1erl e4l3ernä eler2ö e2l1err el3eru el1erw e2l1ess e2l1e4ta ele2ti elet4ta 2el1ex e3lex. 1elf. elf2er 1elfm elf4r 1elft elgi5er. elgi5ers el3g2l elg4r e2l1id 2e3lie eli3ef. 2elig e2lim elin3a eli3no el1ins 2elk el4larb ellar4t el3lär el5le. ell2ei ell3ein ell3eis el4lel el5lend ellenen5 ell2er eller8fas eller7g ell3erh el3les el2lim 1ellip el2lor ell2ö ell3sp el3ma elm2e elm3ein 2eln el3na 2elo e2l3oa e2lof e2lol e2lom e2lonk el1opf e2l1or e3lore elo2ri e3lot e3l2ov 2elö elö2s el3p4 el4s5ein el3sen els4tri el2sum el4tans elte4m el5ten. el4t3ent elter4b elter4f elt3erh elter6le 3elter4n elt5ero elter6sc elte2s el4tesc elt3eth el3the el5tri elts3pa 2e1lu el1uf e2l1um e2l3u2r elu2s el3use elu2t el3uto e1lü 2ely e2lya el3z2ac el2zar el4zene elz1in el2zwa 2elzy e1m e2m3a2b e2m1alk em3anf e2m1ano em1ans 1emanz e4m1a4s3p em1au 2e3mä em2äh 1emba 1embo 1embry em2dä emd1r em2dra 2eme e2m1e2b e2mef eme2i e2mele em2en emen6gel emen4t3h eme3r2i e2m1er2l em1erw e4mesu 3e2meti e2m1i2d emi2ei e2mig emik2 em1im 2emin emi3n2a e3mind em1int 1e2mir e3misc emi3tr emma3u em2m1ei e2moa e3mol emo3s 1empf4 em3pfl em3po empo1s em2sa em4scha em4sei em2sim em2spr em2st ems5tr ems3tro em3t2 1e2mul 3emuls emune7 e3mur 2emü e2na 4ena. e4na2b en3aba en3abo 4ena2c en3ache e4n3ack enadi4 e4naf 4enah en3ak en1al enal2a e4nalb e3nale en2alg ena3l2i e4nalk e4nalm e4nalo enal3p 4en1am ena4n e4nand en3ane e4nant e4nanz en1ap ena2pa en3are en3ark en3aro en1as ena2sc e4nast 2enat 4e5nati e4natl enat4s e4n3att 4enatu e4nau2f en3aug e4n3aur e6nausta e4naut en1a2x en1a4z en1ä en3äb e3näi e2när en2ä3s en3äst en2ce. end2ac en2dal en4dang 2endel ende4lä en4d3es4s en2dex en2did en3d4ort end3s4au end3s2l end3s2p end3sz en3d2um en3d2ü 2ene. en3e4ben en1e2c e2neff ene2h en2eid e3neien e4neige 4eneigu e4nein e4neis e2n1el ene4le 2ene2m e2n1emi 2enen e4nense e4n1ent en4entr en3envi en1ep 4e3ner. en2era e2n1erd en3erei e2nerf en4erfr 1energ e2nerh e2nerk e2n1erl e4nermi e4n3ermo 4enern e4n3erne ene2ro e2n1err en1ers 4eners. e2n1ert en4ert. e2n3eru e2n1erw 2enes e3nes. e2n1e2sc e2n1esk e2n1ess en1eta e2n1eth en1eul e2n1e2v e4ne2x en3f enf2u 1engad 1engag en3g2al enge3r4a en3g2i en3gn en3g2o 1engp eng4ra eng3se 2eni e3ni. e3nic 4e3nie eni3er. eni3erp eni5ers. en3i2ko en3ill eni4m en1ima en1imi e2n1in e3nio eni2ö e2nir eni4sa e4n3iso e3nit2 e3niv enk3aus 3enkeli enk3erg en4k3erk en3k2ü en2nef en2nel en4ner4f enn3erg en4n3erl enn2i enni6ger 2enniv enns2 enn3ste e2n3oa e2n1ob e3nobel eno2br e2nof en3olm eno2ma eno4n e2n1op e2n1o2r en2ora eno4ri 4enorm e2n1ost 4e3not eno2w 2e1nö en1ö2d en3sabb en2san en5sche en2seb 1ensem ensen3e ens3ere en3spo ens4por enst5alt en4s3tät ens4tel ens6temp ens2th 2ensto enst2ü en5t2ag en4tanm en4tanw en3t4ark 1entd en3t2el ente2n 3entera en4terb 1entf 2entfo 1entg 3entgeg en2thi 1enthu 1enthü en4t1id 3entla 1entn en2tob entopf3 en2t1os 2entö en4t3rol 1entsc 1entso ent4sto 1entw 4entwet 3entwic 1entz e2n1u e3nu. e4nu4r 2enu4t e4nuto e1nü enü1st 4enwü 2e1ny en3zare enz2äp 1enzep enz3erg en4z3erk en4zerl en4z3erm enz5ersc enzi2d enzlan4 enzo2l 1enzy e1ñ 4eo e1o2b1 eo3ben eo3bl eo3bo eo3br eo1c eoch2 eo3dr e1of eo3g2 e1oh eo3la e3o2ly e1on e3o2nat eo1o e1opf eop4r e1or e3or. eo1ra e3orb eorgi1 e3ors eort2 e3orw eo1s2 e3os. eo3se e1oste e1ou4 eo1ul e1ö4 e1p 2ep2a epa2g epas6ser 2eper e3p2f4 e5pfi 1e2pid e2pig e2pik 1e2pile e3pio 1epis 2epist 1e2pit ep3le 1epoc eport4 1e2pos. ep2p1a eppe3l ep2pl ep2pr 2epr ep3sh ep2tal ept2an ep2tau 2e3pu epu2s 4e3q er1a e3ra. era2be e2r3a2ch e3rad. e3radi e2radj e2radm e4radmi e4r3adr eraf4a era2g e1rah e1rai er3aic e3rake e1rald eral4eb er3alke e2r3all er2an. era4n4a eran3d e3rand. e4rangr e2ranh e2rano e1rap er3apa er3apf e2rar er3are e3rari e3ras. era2si e1rast era2ß e4ratel e2ratl e1raub e1rauc er3aue erau2f er3aug e2ra2v e1raw e2r3ax e1raz e1rä er1äf er1äh er1ä2m er1äp e2r1äs er1ätz 3erbarm erb2au erb2e 2erbru erb2sp er1c er3chl erch2o erd2am erda3me 1erdb 2erdec 2erdel er4d3en4g erd3erw erdes4t erdeu2 1erdg erd3st 2erdy 4ere. er3e4ben e3r2ech er3echs er1e2ck er1edi ere4dit er1eff e2r1e2h ere4i 4e3rei. e3reib er1eig 4ereih e4r3eime e4reink er3eis. er5eisar er3eisb er3eisf er3eisr erei5str e4rek er1e2l e2rele ere3lev ereli1 2erem 4erem. er1emi ere4mis e2remp 2eren 4e3ren. e3rena eren1e e4rense e4rentn e4rents e3renz eren8z7en8d er1epe 4erer. 2ererb erer3fa e4r3erfo e2rerh e2rerk e2rer2l erer5lau 4erern. e4rerne e2rer2o erer4ri er1ers 4erers. e8rersche e2rert 2ererv 2ererw 2eres 4eres. ere2sp er1ess eres3sk er1eta er1eu ere4vid erf2e 4erform erf4r 4erfür er4g3are 4ergebi 3ergebn 4ergebü 4ergeha 4ergehä ergel4s3 erg5elst 4ergeni 2ergn er2gop 4ergrem erg1s erg3s2o ergs2p ergs4t e4rh 1erhab er3hag 2erhai 4erhals 2erham 2erhan 2erhas er3hei 2erher er3hu 2eri e2riat e3rib 4e3ric e4r3ico er1id 4e3rie eri3en1 e3ri3k erik4l 4e3rin. e2r1ind e2r1ini er1ink er1inl er1int er1inz e2ri2on 4eris e2riso e2risr er1ita 3eritr e3riv 2erk. 2erkaj er3ker 1erklä 2erkm 2erkre erk5t4 er2kum 2erl. 2erlag 3erlebn 4erleh 2erln er3m2 ermen4s er4m3ers er4n3alt er3ne er4nene er4nerf er4nerk 3erneue er2nob erno2r ern1os 2e1ro. e1roa er1ob ero2bl ero2br e2r1o2f e1rog e1roh e1rok e1rol er3oly e1rom er3omb 2e3ron e2r1oo er1op 2e4ro4r eror2a e1ros 1erosi e3rosit e1rou e1row er1o2x er1oz erö2d 2eröh erö4l er1ös erö2sc er3p er3rä 2erren er3ro 2errü er3s2a ers4ana ersch4 er5schn 4ersei ers2el er3sen er5s2i er3sk 4ersted er3stel erst5ers 4erstil ers4tod ers6tr er3swi er3sz ert1ab er3tat er4t3erf er4t3er4g er4ter4h er4ter4k er4ters ert1h er2tho 4ertö er5tri 4ertru erts2e erts2p 2eru eruf4s3 e4r3uhr er1u2m1 er1und e4rundu erung4 er1up. er3ur er3use e2r3uz erü4b 3erweck er4zerk er4z3ers es3ab e4sabe e2s1a2d e3saf es3ak e4s3all es1ami es3ampl es2ank es2anm es2anr es3anz e3sap es2apa esa2ra e3sa2s es2ast esa2v es1ax 2esb esbi5er. e3s2ce esch2 es4chi e2s3ec es1ehr esein4s es2el ese4nal ese4neu esen3o es2ens esen3sk esen3th eser4at ese4r1u2 eses2k e2s3e2x 2esf 2esh es2har es3he 2esi esi1er e2s3i2k e2s1il esi2st es2kat e4s3ke e4s3kl es3ku e4s3ky es3l 2esm e2s3oa e4s3ob e2s1od es2oh eso2r es1ora eso3re es2ort e3sot e3s2ö 4esp e3spal es4park es2pek e4spers e2sph e3s2pi e3s2por 2esr 2ess. es2s1ag essali3 essau4s 1essay 2essä 2es3sc ess6ere ess4erf ess3erg ess5er6la 2essk 2esso es2sof 2essp es2s1pa es2spu es4stab ess3tie es3stu estab4b esta3ge est1ak es4tanb es4tang e4stant e1st4ap e1star e4starb e2st1a4s e1stat e4stat. e4staum e4staus es2tec este4i est5eing est5eink est5einl e1ste2l es4t3emi e4sten es4t3eng est5entr est5erha es4ter4ö es4t3erz es4t3ess es2th es2tid e4stig e1stil e2stip es2tis estmo6de 1estn e2stom e3strec es4tri e1strö e1stu est3ums es2tur e1s6tü e3sty e3suh e2s1um es3ums es3unt es1ur esu4s 2es3w e3sy es3z es4zene 2e1ß e2ß1el e2ßent eße3re e2ß1er2g e2ß1erl eß3t e1t etab4 eta2c 2e3taf 2etal et1ami et4an. et4at etat3r et1äh 2e3te ete2e e4t1ef e4t1ein ete3ke eten3d2 ete2o eter4hö ete1ro eter4tr ete2s 2eth. et2ha e4t3hal e3the et2hi e4thik 3ethn et2hu e4t1i2d eti2m etin1 et1ini et2it eti2ta eti2th et3l 2e3to e2tob e4t1o2f et4on eto4n3al etons4 e4torg eto2s 2etr et3rad e4traum et3rec e2t3res et4ros ets2c etscher7e etsch3w ets1p et2spe et2ste ett1a et2ta2b et2tad et2tak et4tans ett2as et2tau et2tei ette4n1 ett4er et2t1h et2t3r et2t1um 3e2tui e3tur e3tü etwa4r 1e2tym 2etz et2zw eu1a2 eu3b4 2euc euch4ta 2eud eude1s eudi4e 2eue eu2eb eue6r5eif eue6reis euerer6s euerer6t eu3eri eu3erk eu3err eu2esc 4euf eu2fer eu2g1a euge4mi eu6gense eu3g2er eugin2 eugin4f eu4gin4g eu2gre eu2gri eugs4 eug3sp eu3h eu1id eu1in1 e4uk 1eukal eu2kä eulan2 euland3 eu3l2e eul2i 2e1um e3um. eu3m4a e3umb e3umf e3uml e3um2s1 eum5st e3umw 2eun eu2na eun2e eu4nei e3un2g eu2nio eu4nis eunk2 eun3ka eu1o2 eu1p e1up. eu3p2f e3upg eu4r1an eu4r3ast eura3t eu2rau eur1c e2ure euren2 eu4rens eur4er eur3f4 1euro 2eus e3usar eusch4o eus2i eu4sk eu3sp eust4 eu1sta eu1sto eu1s4tr 2eut eut2e eut2h 3eu3tha eut2i eu5t2o eut6scha eut6schn eut6schr 2eux eu2za eu2zo eu2z1w e3ü e1v e2vak e3var eva4s3 2ev2e eve5ri evie3le 2e3vor e1w ewä2s e2we. ewei4sc ewert4 ewer3te e3wir ewi2s e3wit 2ex. 1exam ex3at 2exc 2exd e2xel ex1er 2exes e1xi 2exik e2xil e2x1in e3xio 1exis ex3l 1exp 2expu 2exs 2ext. 2ex2ta ex2tin 1extr 2extu 2extv 2exu e2xum 2e1xy 2ey1 eyl2 ey2n ey3no eys4 e1z e3z2a ez2ä e2z1enn e3zi ezi2s e3z2o ez2w ez3z2 é1b é1c é1g égi2 é1h é1l2 élu2 é1m2 é1n é1o é1p é1r2 é1s ési2s é1t é1u2 é1v é1z2 è1c è1m ène1 ènes4 è1r 1ën ë1t ê1p ê4t 1fa fab4 2f1ab5b fa2ben 2fabf 2fabg 2f1a2b5l 2fabn 3f2abr 2f1ab5s 2fabw fa4cheb fa4chel fa2ch1i fa2cho fach3s4p fa2dan fa2del f1ader fa2di fa2dr fa3e fah6l5ent 3fahre 5fahrt fai3b f1a2ka fa2ke f3aktio f4akto 3f2aku fa3la fa3le fal2kl fal2l1a fal4l3ei fall5ent fal6lerk faller6s fal6scha fal6schl fal6schm fal2tr fa2mei f1amp f1amt 3f2an. fa2nar fand2a f2anf fan2ga fan2gr 2f1an3k 2fanl 4fann f1anp 2fanr 2fanw 2f1an3z 2f1a2p f2ar far2b1a far4bel far4b3er far4bin farb1l far2bo far2b3r far2b3u f3arc 3fa5ri far2r1a farr3s 2f3art 2f3arz fa3s4a fa3sh fa2st 2f1astr fa2ß f3at f4at. fa2to f4ats 2f1auf f3aug fau2s f1ausb faus4t3r 3f4av fa2xa 1fä 3fä1c fäh4rin fäh2ru f1älte 2fäq 3färb 2f1ärm 2färz fässer4 fäs6serk fäs6serw fä2ßer 2f1ätz 2fäug 2fäx 4f1b4 fbau1 fber2 2f1c f3ch 2f3d4 fdien2 1fe 3fe. featu4 fe2c f2ech fe3che fe2del fe2dr fe2e1i feein5 fe1em 2f1e2he fehle2 feh4lei f2eie f2eind 2f1eing fe3ini fe3ins. fei4nu 2f1einw f1eis fek4tin fe2l3a2 fe2l1ä fel2da felde4m feld6erh fel2dr 2fe2lek 2felem fe2l1er fe2les fe2l1o fel4s3oh fels2t felt4 6fel6tern f2em. 2femb fem4m 2femp fen3a fe2nä fend2 4fenerg fe2ni fe2no fen3s2a fen5s2c fenst2 f1ent fen3t2a 2f3entf f2enti 4fentla f2ento 2f3entw 4f3entz 3fep fe2pi f2er. fe1ra fe2rab fer3a2d fe2ral fe4rang fer4ant fe4ranz fe2rau fe2r1ä 2ferd. fer3da fer3d2e3 f2ere fe2r1e2b fe2rec 3fer2ei 4f3ereig fer3eis f4erel fer3ell fe4rer4g fer4fah fer4fol ferg4 f4ergr feri2d ferie4n3 feri4on 4fer4leb f2ern. fer4nei fe2rö f4erpa f4erpf f4erpl f4erra fer4reg ferri2 f2ers. f2ert fert4r f2erz fess2e fe2st fest3a4b fest3an fest3ei fes4tel fes4t1o fes4t3r 2f1e2ta fe4tag 3fete fe2th fet4t3a fetti3s 2feu. feuer3ö 3few 2f1ex fe1y2 3fez 1fé 4f1f ffab6s ff1a2d f3f2ak ff3ar f3fas ffa2t ff1au f2f1e2b ffe2e f2f1ef f2f1ei ffe3in. f5fek ff1e2m f2femi ff2en ff3erle fff4 ffi3k f2fim ffin3s ff1lag ff3le ff3li f3flü ffo2r ff1ox f3f4rä ff3ro ffs2am ff2s1p ffs3tie ffs3tut ff3stü ff3t2 ffus3s f2fy 4f3g2 fgeb2 fge3s fglim2 4f3h2 1fi 3fi. fi4ak fi2ar fi3at fid4 fi2do f2ie fi2e1i fien3 fi1er2f fi2gr fi2k1as fi2kel fi2kin fi2kn fi2k1o4 fi4k3r f2il fi2l1an fil3d fi2les fil2et filg4 fi3li fi4lin fil2ip fil2ma fil2mä fil4med fil4mei fi2lo 2fimp 3f2in2a fin2e 2f1inf fing2 fing4s4 fi3ni f2ink fin2s fin3sc fin3sti 2f1int fi2o fi3ol fi2r fi3ra fi4re fir3me fi3s2a fi4sch3a fi6schei fisch3o fi4schr fi4sch3w fi3s2h 2f1iso fis2p fi2s3t fite2 fi2tin fit1o2 fi4tor five4 fi2xel fi2za 2f1j 3f2jo 4f1k4 fka4t3 f2l2 2fl. f3lad f5land f4lans f3lap f4lasc f3lats flauma4 1flä 3f4läc 4fläd 2fläh 2f3län 2flär 2f3läu f5le. 2f3leb f4lee 2f5lein flek3 flekt2 f3ler f4lex f3li. 3f4lim f3lind fli4ne f3ling 2f3lins 2f5lon 1f4lop 1floß 1f4lot flo2w f3lö 4flöf f4lög 3f4luc f3luf 1f4lug 1f4luss f4lut flut1o f4lü f5lüm fly1 4f3m2 fma5che fma2d 4f3n2 fni2s 1fo f1ob fo2be 2fober fob2l 2f1o2f 5foli3 fo2na fo4nan fon3au fon3dr fo4n3in fo2nop fons4 fo2nu 2f1op 4f3org 3form for4m3a4g for4mas for4m3ei for4min forni7er. for6schl for4st for4t3ei for4ter for2t1h for2t3r fort3s2 for3tu for2u fot4r 1fö 2fö2f 2f1ök 4f1öl för4s5 4f3p4 2f1q f2r4 f3ra. frach6tr 2f3rad 2f3rah fra4m f3rand f5rap fras3ta f3rat 1frau. f3rauc 2fräd 1f4rän 2fre. f3rec f3red 2fref f4rei. f3reic f4reie frei1f f4reig frei3k2 2frein 2frek 2f3rep 2frest 3f4reu 2f3ric fricht6e fri3d fri2e 2frig f4ri3k f3rip 1fris f4risc f4rist 2f3roc 2frol 1f4ro2n fro4n1a f4rop fro2s f3rot frös2 f3ru f4ruc f3rü 4f1s f2s1al f2sa2n fs3ane f4s3ar f2s1a2s fsa2t fs3ate f2saut fs2än f3sc f4sca f4sce f4schan f4schef f4schro f4scr f2s1e2b fse2ei f4s1ehr fse2n fs1en1e f2s1ent f2s1er fse4t f2s1eta f2s1i4d f3s2ky f2s1o2 f3soh f3sol f3spann f2s1pas f2sph f3s2pl f3s2por f2spre f2spro fs2pul fs3s4 fs2t fst2a fs3tak f2stas f3stat fs3tät f4stäti f3stel f3stern fs3th f2stip fs4tol fs4tor fst4r f4s3tres fs3trü f4stüte f2s1un f3sy 4f1t f4ta. ft1a2be ft1abl ft1af ft2ag ft1ala ft1an f2t1ap ft1a2r ft3att f2t1äu fte2c ft1eck ft1edi ft1eh fte2he ft1eig ft1ein ft1eis ft1eli fte3ma ft1emi f4t1ent ft3erfü ft1erk f2t1erl f2t1erz f2t1e2ti f2t1ex f2t1h f4t3hei f2t1id f3tik f2tim f2t1in ft2ing fto2 f2t1of f2t3ot f3t4ran f2t3res f3treu ft4rit ft3ro ft3ruh ft2s1 ft4sam ft3s2c ft4sche ftse2 ft4seh ftsen1 ft3st ft4staf fts3tät ft4stei ft4stem ft6stier ft6s5treu ftstro4 ft4stru f2tum ft1urk ft1url f3tü ftwa4 ftwa6r ft3z2 ftze3d 1fu 3fuc 3fug f2uh fuku3 fulb4 f1um1 fu2mei f2umm fund3er fun6derg fun6derh 2f1unf fung4 2fungl 2f1u2ni fun2kl fun2ko fun2k3r fun2ku 2f1unm 2funr 2funt f2ur furch2 fu4re. 2f3url fus2sa fus2s1p fus2st fu2ß1er 3fut 1fü 2füb fühl4sc fün2 fü2r 2f1v 4f1w f1y 4f1z fz2a fzeiten6 fzei8t7end fz2ö fzu2ga fz2w 3ga. 2gabf 2gabg 2g1a2b3l gab2o g1abr gab4ri 2gabsc g2abt. 2gabtr ga3bu 2gabw 2gabz ga1c gade2r ga3d2i gadi4e ga2dr gae2 ga1fl 5gag. ga1k ga2ka ga2ku gal2a ga3laf ga2lar 2g1alau 2g1alb 2g1alg gal3lo 2g1alp 2g1alta 2g1altd g1a2lu ga2mec ga3mel gam3ma 5g4amo 2g1amt g1a2na 2ganal gan3d4 2ganf 2ganga 4gangeb gan2gr gang4sp gan2g1u 2g1ank 2ganl 2ganmu 3g2ano ga2nob 2ganr gans2 g2ans. 2g1ansi 2ganst 2ganw ga1ny 2g1anz ga3pe 2g1app ga1q 3gar. g2ara 2garc 3g2ard ga3ret ga3r2i 2g3arm ga3r2o gar2s 2g1arti ga3ru 2g1arz g2as. ga2sa ga4s3al ga4sam gasche4 gase2 ga2sei ga2sel ga2se4m ga2si ga2sor gas3s2 5g4asse. g3asses 6gassess ga2st ga4ste gas4t3el ga4str gast3rä ga3t2a 2gatm gat4r gau1c 2g1auf 2g3aug g2auk gau5ne 2g1aus 2g1aut ga3z 2g1äp gär3th 2gärz gä4u 2g5b4 gber2 gbi2 gby4t 2g1c 2gd g1da g3d2ad gda3de g2d1ak g2d1an g2d1ar g2d1au g1dä1 g2dei4 gd1els g2dent g2d1er g2d1et g2d1in g1do g2dop g1dö g1dr gd3re gd3ru gd3s2 gdt4 ge3a2 ge4ate geb2a ge3ble geb4lin geb4lo gebot4 3gebü ge1c ge3ck ge1e2 ge3ec ge2es geest3 ge5fa 3gefä 4g1eff gef4l gef4r ge3fu g4eg gege2n1 gegene4 gegen3s4 ge3g2l geg4r geher3l ge3ho 2g1eid ge4ie2 ge4ig g2eil ge1in1 ge2inf gein4h 2g1einr gein2s gein2v ge1ir 2g1eise gei3sh geis4s3c gei2st geist3r 2gek. ge4lanz gelb1r gel4b3ra gelb3s gel4den gelder4 gel6derh gel6ders ge3lec gele5cke ge2lef 2ge2lek 2gelem gelen1 ge4lene gel3ere ge4lerk geler3ö ge4l3ers ge2l1ev gel3f gel1i4m gel3la gell2i gel2ö gel3sa gels2p gels2t gel3ste gel3sz gel3ta gelt4r gel3z2 gem2 ge4ma. gem6e 4g1emp ge3mu g4en. ge3na ge4n1ac ge4nad ge4nak ge4n3al ge4nam ge4nap ge4nar ge4nat gen4aug 4genda. gend3in3 4g3endmo gen2d3r gen3eid gener4f 4generg ge4n3ern gen6erwe gener4z ge2nim gen3k4 gen3n ge2noc gen4sam gen6semb gen3sk gen3sz gen3tä 2gentf gen3t2h gen5tr 2gentw gen3zw ge1oo geo2ri g2ep4 ge3pl ge3po ge1ra ge2rab ge2rak ge2r3al ge3rann ge4rant ge4r3a2r ger2as 2gerdg ge3rem ge4rene ge4reng ge4ren4s ge4r3ent ger2er gerin4d gerin4f ger4inn gerin4t 4ger4klä g3erlas ger5me ger3no 2g1ernt ge1ro ge2rob ge1r2ö ger4sat 4g3er4seh ge3r2u ge1s2 g4es. ges3auf 3ge3sc gesch4 ge6sche. ge2s3eb 4g3e4sel. ges3elt ge2s3er ge3sha ge3si ge3so ge3spa ges4pi ges3se ges3s4t gest2 gest4a ge3stak ges4tan ge3st6e ge4s3ter ges3th ges6tier ge4s3tur ge3t2a ge4tang ge4tant g1etap ge2thi ge5trei ge5tri ge5t4u 2g1e1ul ge3unk ge1urt ge3u4t 4g1e2x 2g5f4 gfi2l 2g1g gga4t g5ge gge2ne gg2l g3gla g3glo g2g3n gg4r ggs2 2g1h 4gh. gh2a 3ghale gh2e 3g2het 3g2hie gh1l 3gh2r ghs4 gh3sc g2hu gh1w gi3alo gich2 gicht1 gie3g gi2e1i gi2e3l giel2a gie5n2e gi4eno gie3res gie1st gift5s gi2gu gi2kel 2g1ill gi2me. gi4mes gi2met 2gimp 2gin2d gi3ne 2g1inf 2gin4h 2g1ins gin2sa 2g3int 2gin2v gi2ob 2giok 2g3isel git2a gitt4e gi3tu gi4us 2g1j 4g5k4 gl2 4gl. 4g1lab 2g1lac 2gladu 2g1lag 2g1lam 2gland gla2s1c glas3t4 3g2laub 2g1lauf 2gländ 2gläuf gl3b g2l4e 2g3le. 3glea 2g3leb g3lec 4g3led g3lee 2g3leg 2gleh g4leic 4g3lein gleiter8s glei4t5r g3len 4glenk 4g3ler glerei4 2gles 3gles. g3lese g2lia 2glib 3g2lid 3g2lie 4g3lieb 2glif g2lik 4glil g2lim 2glin g2lio 2glis g2lit g3lite g2liz g3lize g2loa g2lob g2loc 2g3loch g2lok g2lom g2lop 2glorb 2glos g2lot 2glöch 2glös 2glöw 2gls g1lu 2g3luf 2gluk 2g3lun g2lut 3g2lü g3lüg 2glw 3g2ly 2g1m2 gmen4tr gmi2s g1n 2gn. g2n2a g4na. 2gnac g4nad 2g5nah gn4al gna4l3er3 2gnanl 3g2nä 2gnb 2gnc 2gnd gn2e g3neh 2gn3ent gne2tr gneu1 2gnf 2gng 2gnh g2nie g2nif g4nin 2gnint 2gni4s3 gnise2 2gnk 2gnl 2gnm g2no 3g4non gno1r g3not 2gnp 2gnr 2gns 2gnt 2gnu 3g2num. g2nü 2gnv 2gnw g2ny 2gnz go4a goa3li g1ob gobe3l 2gobj g2ob2l gob2s 2g1o2f 2gog 2g1oh2 goh3ren go1i gol2a gol2da gol2fr 3gon. go4nat gon2e 3gons 3g2opa gopf4 go2pos 2gopt gor2a 2g1ord 2g1org go2si go2s3p go1ste 2g1osz go3t2h got6terb got6t5erg gotte4s 3gou go1y gö2f g1öl 3göt 2g3p4 2g1q g2r4 g4rab gra2ba gra2bi gra4bl 2g3radl 2g3rah 2g3rak gram1 grammen6 gram8m7end gram6mer g3rand. 2gra2r grar1e gra4s3a gra4sh gra4sp gra2st 2g3raub grau3f 2graum grau3sk 2gräd gräs1c g3räu 2g5re. g4reb 2g3rec g3rede g4re2e 2g3ref gre2fr 2grege 2g3reic grei4fr 2g3reih g3rein g3reit 3g4rem 3gren 4g3renn gre3no gren6z5ei grenz3w g4rer 2grese gres6ser6 g3ret g3rev 2g3ric gri2e 2g3riem g3riese 2grig gril4la 4g3ring 4g3rinn gro2b3a gro3ber gro2bl gro2b3r 2groc 2groh 2g3rol 2g3rose g4ross gros6sel g4rot 2gröh 2gruf. g4ruft 2g3ruh g3rui 2g3rum grun2g 3grup 3grus 3gruß 2g3rut 2g3rüc 4g2s1 gs3a2b g4sac g5sack gsa2d gs3a2k g3sal g4s3alb g4sall g4salm g4salt gs2am g4s3ama gs3amb g4s3amp gs3a4p gs3a2r g3sat gsau2g gsau4r gsa2v g3säu g3s2c g4sca g4s3ce gsch4 g4schef gs4chi g4sco gse2 gs2e3h gs4eil gse4kl g3sel. g4sela g3seln gs3em gsen1 g4s3ent g4s3er g3sere gser1i g4se4s gse4t g4seu gsfi2l gsgene4 gs3ha gsi2d gs3i2k g3sil gs3io g4s3ita gs2ki1e gs3kr gso2 g4s3o4b g3sol gs4on g4s3op g5s4orge gs4pant g4s3pas g3spei g3s2pek g3s2pi g5s6pie g4s3pl g5s6port. g4s3pru gsrat4 gsrü2c gs3s4 gs3ta g3s4tad g4stag g3s4tan g4stanz g3star gs4tati gs3tä g3steh g3s4tein g3st2el gs4tell gste2r gst3err g1steu gs2thy g3stif g3stil g3stim g3stir g3sto g4stoch g4stod g4stor gs3tö gs4tör gs3tr gst4ra gs4tras gs4trat gst5reit gst4res g4streu gst3rit gst3ros g3stun gs3tü gs3un g3sy 2g1t g3te gtei3s gt1h gt2hy gt2i gti2m g3to gt4r gt4s g3tü gu4ale gu3am gu1an. gu1ant gu1as gu1c gu4d3r gu2e 2gued guet4 2g1u2f 2g1uh gu3ins gu1is gum2e 3gumm gummi1 gun2e 2g1unf gunge2 4gungew 2gungl 2g1u2ni 2g3unk 2gunr gun2s 2gunt 3gur gure4 4g1url gur2t3h gur2tr gurt3s guru1 gu2s gu4s3a gu3sc guschi5 gu3se guss1o gus2sp gus2st gu4st gust3a4b gus3te gus6t5en6d gus6terl gus4tr gu2t gut1a gut3er4h gut1h gut2s3p 2güb 3gür3 gü2s3 2g1v 2g1w gy3n gy4na 2g3z2 gzeu4gi 2ha. hab2a hab2e h3abf hab2i h1ablu 2habn h1a2br h1abs 2habw ha4ch3en ha2cho hacks4 2hada ha2del hade2n h1adle h1a2dr ha3dri 2hae ha3el ha4far haf2e h1affä haf3f4l h2aft haf4to haf2tr haf4tre haft4s3p hag2a h2agg h1ah ha3ha h2ahs h2ai 3hai. h2aj 2haka ha1kl 2h2al. ha3l2al halan4c h1a2lar ha2lau hal2ba hal4bel hal4bin hal2b3r hal2bu 2hale 2halh hal2i hal2l1a hal6lere haller6f hal6lerg ha3lo 4halp hal4sk hal2sp hal4tal hal4tei hal2t3r hamot4 2h1amt h2an. 2hana ha2nal ha2nan han2au 2hanb h2anbe h2and han2da han4d3er han2d3r hand3s ha2nem han2f1 han6g5end han4gro han2k1 2hanl 2hano 2hanr h1ansc 2hanz 2h1ap 3h2ape ha2pl ha2po ha2pr h2a3ra ha4rab 2harb 2harc h2ard har2fr h1arm. har3ma h2arme har4me. har4ne ha2rom 2hars hart4e har2th h1arti har4tr har2za h2as 2has. 2ha3sa has4c has2h3 has4sa hasser4 has4s3t ha2str h1a2ß ha2ta hat2i h3atl ha2t3r 2hats hat5t2 h3attr h1audi h1aufb hau5f6lie hau3f4lo 2h1aufm h1aufs h3au3g2 h1aukt hau2sa hau4san hau2s1c h2ause hau4sel hau6s5ent hau4spa hau4spe haussen6 hau4sur hau2t1a hau4t3r ha2ve. häde2 h1äff 2häi hä2kl 2härz hä6s5chen 2h1äst 2häug häu2s1c hä3usp 2h3b4 hba4ras hber2e 2h1c 2h3d2 hdan2 2hea he2ad he3be heb3eis he2b3l he3br he3bu he3ch2e he3chi he1cho h3echs he3cke hed2g he2dit he1e4m hee2n hee2s he1e2t h2ef. he2fan he2fau he2f1ei he3f2em hef3erm 2heff he2fid he4f3in4g he2f5le 2hefr hef4ra he2fre 3heft he2fu he3gu he2hel hei4a h4eib h1eie h1eif h1eig he2im hei4mal hei4man hei4mar hei4mei heim3p hei4mu 2hein hei4na heine2 hei4n3eb hei6nene hei4n3er h3eintr 2heio 2he1ism he1ist h2eit heit4s3 h1eiw hekt3a he2la he3lag hel1an hel3au hel1ec he2lek h3elem he2len h2elf he3li hell2a hel4l3au hel4mei he3lo he4lof hel2or he2lö 4helt h4em. 2hema hem2b 1hemd 2heme2 h2e3m2i he4mia h3e4miss 1hemm 2h3emp h2en. he4n3a2 he2nä hen3ebe henen1 hen3end he4nene he4nens hen3erg he4nerm he2n1e4t 2henga hen4gag hen4kan hen4kau 2heno heno3t hen4sem henst2 hen3str hent2a hen3te hen4ter hen5tr hen4tri h1ents 2h3entw h3entz he4n3u hen3z2 2he2o he3on he3op he3pa he3ph h1e2pi hept2 h2er. her3a2b he2rad 2herap he4r3a2r herau2 herb2 he2r1e2b he4reck her4eif 4he3reig he6reis. her7eises he2rel he4rene he6rersc he4rerw h1erfo her4fol 6hergebn 2herif herin4d herin4f he6rin6nu herin4s h1erke her4klä h5er6kran h6erlad 2herm he3ro he4r3o2b he4rof he4rop he4rot h1erör hert4 her3th her3um her4zap her6zeng h3erzeu her2z1w he3s4a 2hese he3si he3s2p hes6tä he2tap he3tä heter2 he3th het2i he3t4s he2u heu3g he3unt 3heusc he3x he1x2a 2hexp hey2 he1ye 1hè 2h3f4 hfaller6 hfan2 hfel2l3 hfi2s hflei2 2h3g4 hga2s1 2h1h2 hhoh2 4hi. 2hia hi2ar h1iat 2hic hi1ce hich6t5er hicht6sp hi3d hid4e hi4dio 2hido hi2e hi3ens hie4rei hier3i hie4rin hiers2 hif3f4r hi2k3r hi2l3a4 hile3n2 hil2fr h2im 2hima h3i4mit h4imm h3impe hi2n hi3nak hi3nam hi3nap hi5n2as h2inde hine2i hi3nel hin2en5 h1inf h1inh 2hi3n2i hin3n2 hi3n2o hin3s2 hin2t1a 2hio hi3ob hi4on hi2p3 hi4pl hips2 hi4pu hi2r hi3ra 2hi3re hi3ri hir2m1a hir2mi hirn1 hir4ner hir2s 1hirt 2his. his2a hi4se h1i2so hi3tac hi2tan hi2tel hi1th hi3t2i hit1r hi2tro hit3z2e hi2v1o 2h1j 2h1k4 hkamp2 h2keu hki2n1 h3kö 2hl h4laf hl2ag hla2gr hlan4d3a hl1ans hl1anz h1las h1lat h1laut h1lay h3läche h1läs h1läu hlb4 hl3d4 h3le. hle3a h3leb h3led hle3e h2leis h3leist hl1el h5len. hle4nas hlenen3 hl2enn h4l3entr h4lents hl2enz h3ler hle2r3a hl4ere h2lerg hler4hö hl2erk h6l3er4nä hle3run hl1erw h4lerz h3les h4lesi h4leud hlf4 hlg4 h2lie h3lied h2lif h2lim hl1ind hling4s3 h2lip h2lis h2lit1 hl3l2 hl3m2 h2lo hl1ob h3loc hl1o2f h3log h4lor hlo2ra h3los. h3losi h4loss hlos4st h2lös hl4sar hl2ser hl3ska hl3s2lo hl5s6tern hls3tie hl5str hl2su hl3t2 h3luf h3luk h3lumpe h1lüf hlz2 2h1m hm2a hm3abl h3mad h3mag h3mak h3man h2mant h3mar h4m3arc h3mä h4mäc h4mäh h4mäl hm2e h3me. h3med hme1e4 hmeer4s h3mein h3meld hme3le h3men hmen2s hme4ran hme4rei hme1s2t h3mex hmi2e h3mind h3mini h3minz h3mirr h2mo h3mop h3mot h3m2ö h4möl hm3p2 hm2s hm3sa hms1p h2mu h3mul hmut4s 2hn h2na hna2c h3nag h3nam h4nar hn3a2te h4natt h3nau. h2nä hn1äh h3näs hn3d4 hn2e hne3b hne2e3 hn3eff hn3eig hn3ein h2nel hne4n hn4eng hne4pf h3ner hner4de hner3ei h4n3e2ro h4n3ersa hn3ex hn3f4 hnflei4 hnhof8stras h2nic h2nid h2nie hn1im hn1in h2nip hni4sa hnk4 hnno2 h2no2r hnra2 hn3sa hn3s2p hnst2 hns4to hnsuch4 hnts2 h2nul h2n1unf hn3z2 ho4ar ho3bern ho2b3l ho2ch3 ho4cha hoche2 ho2cka ho6ckerl hock3t 2hod 2ho2e hoe3n ho3er ho2f1a2 ho2fä ho2fed ho2feu hof3f4a ho2f3l ho2f1o ho2f3r ho2fu 2hoi ho2l1a2 hol3ar 1hole ho2l1ei ho2lem hol3g4 hol3k holl4 hol3s 2holy h3olym 1holz hol6zene hom2e ho2me. ho2mec ho2med h2on hon2er ho1on hoo2r 2hop ho1ra h1o2r2an ho2rau h1or3d 2hore ho4rens ho3ret 2h1org hor3ta hor4ter h1ortu h2os. hose2 ho2sei ho3sl ho4sla ho2sp ho3spr ho4ßene 2hot. ho3th 2hotr 2hot3s2 1hou hou4s 2ho2w1 h1ox ho1y2 1h2ö 2hö. hö2c hö3ck 5höhe 2hö2s1 h3öst 2h3p4 h1q 2hr hra2b hr3a2c hr3ad hr1a2g h1r4ah h1rai h1rane hr3ap h3räu hrb4 hr1c hr3d h2rec h3r2ech h3red h3ref hr3eff h2r1eh h4rei. hrei4ba hrei4br h3reic h3reif h4r3eig hr4eini h4reinl hrei3th hreli1 h3rep hrer6geb hr2erh hr2erk h4rerla h6rer6leb hr2erm hrer3s hrer4sa hr2erw hr2erz h3re2s3 hress2 hrest2 hre2t h2r1eta h2r1eu h2rev hrg2 h2ri h3ric h4rick hri4e h3riesl h3rin h4r1ind hr1int h4rist h5ritter hr3l hr3m2 h3rog h3roh h1ro2l h4romat h4rome h4romi h4romo h4ron h1ropa hro4r h3rou h3rö2s hrr4 hr4s1ac hr4s3and hr3schl hr2s1em hr2sen hr2s1er hr2set hr4sh hr2sin hrs3k hrs3l hr4s1of hrst2 hr2su hr2tab hr2tan hr2te2l hr2th hr2top hrt3ric hrt2s h3ruh hr1ums h3rut h3rü h4rüb h4ry hrz2 4hs h4s3acht h2s1a2d h2s1alk h2sall h4samt h2san hs3and h2s1as h2sath h2sato h2saud h4s3aur h2saut h2säh h2säug h4schan hs2cr h2s3ec hse4e h4s1ehr h2s1eie h4seind h6seinst h3sele hse4lin hs1emi h4sendw hsen5erg h2s1ent h2s1erf hs1erg h2serh h4serkl h2s1erl hs1ern h4sernä hs4erne h2serö h2s1erw h2serz h2sex h3s2ext hsha2k h2s1i2d hs2im h2s1ing h3s4inni h4s3ita hs2kal h3skand hs1of h2sop hs1org h2spac h4s3pani h2s1par h2s1pat h3spec h3spei h3sperb h2sph h3spoi h2sprä h2spro hss4 h1st2a hs3tabl h3stad h2staf hst3alt h3stan hst3arb h2s3tau h2s3täu h1stec h1stei h1stel h4stele h3s4terb h3s4tern h1s2ti h2stit h1sto h2stol h2stor h1str h4s3treu hstro2 hs3tum h1stun h1stü h2s1u hs2ung 4h1t ht1a h2tab hta2bl h2ta2d ht2ag ht4akt. ht4akte h2tall h4talo h2talp h2talt h4ta2m h2ta2n ht3ane ht2ank h2tap h2ta2r ht2a2s h2t3asi h2tasy h2t3at h3tat. h3tate h2tau h3taum h4tax ht1ä h2tär ht3e4ber ht1e2c hte3cha h2t1e2d ht1eff ht1e2he h2teif h2t1eig h4t3eilz h2t1eim ht1ein h2t1eis h2t1eke h4t3elas hte6l5ei. h4telek h4t3elfe h4t3elit hte4m h2t1emi h2temp h4tenga h4t3engl h4t3enta h4tentf h4tents hter6de. hterer6s ht3erfo ht3erfü h6terfül h6tergeb ht3ergr hter6gri ht1erh hter6häl hter8höhu h6terleb h6t5erleu h6terneu ht5erspa hter8spar ht3erst h6tersta hter6tra ht3erwä ht3erze h4t1e2se h4t1ess h2teta hte4th h2t1eu h4textr h2t1h h4thei h3thera h3thes h4tho h2t1i2d h2t1im h2t1i6n3 ht3ine h2t1is hti5t2 htni2 h2t1ob hto4d1 h2t1o2f h4t3oly h2tope h4tord ht3rak h3tran ht3rand h4t3ras ht6rates ht3rau h4traub ht6raume ht3rec h5treck ht3rei h2t3res ht3ric h4t3rieg h4t3rin h2t3rol h2t3ros ht3röm ht3ru h2t3rü h4ts ht2sah ht2sal ht4s3a4n ht2scr ht4sein ht2sel ht4s3end ht4seng htse2r1 ht4s3eri htsha2 ht3s4hak hts3kr ht2s1o ht2sp hts3par hts3tät hts4tie hts5trau ht4s3tur ht4s3tür ht2su htt4 htti2 h3tub htu2e h2t1urs h3tü ht3z2 hu2b1a hu2b1ei hu4bel hu2b1en2 hu2bi hu2b3l hu4b5r hu2bu hu1c hu2fa hu2h3a hu2h1i h1uhr h1uhu hu2kä hu2k1in huko1 huk3t4 hu2l3a2 hu4lab hu2lä hule2 hu2l1eb hu2l1ei hu2lem hu4l3eng hu4lent hu2l1er hu2let hu2lid hu2l1in hul3l2 hu2lo hu2lö hul3s2 hu3m2a h1umh h1ums hu2n h1una hun3d2e hunde3i hunde3s hun2e 2hunf hung2 hun3ge hung4s hungsa4 h1uni h1unm 2hunt h1ups 2hur hur3g2 hur2t3h hu3sa hu2so hus2s3a hus3se hus4ser4 hus2s1o hus2sp hus2st hu2tab hu2ti hu2t1o hu2t3r hut2t hut3te hut4zen hut4z3er hut2zu h2ü h3über h4übs h3übu hüf2 hüft1 hühne4 hüs3 2h1v hvil2 2hw2 h2wall hwe1c h1weib h1weih hweins3 hwein6sa h2wirr 1hyd4 hy3dr hy2lor 1hymn h1yo hy3os 1hyp hy2pe. 2hy2t 2h1z hz2a h3z2o hzug4 h3z2w i3ad. iad2a i1adn ia3do iaf4l i2ago ia1h2 i1ai i3ak. i3ake ia2kei ia2kr i1akt i1al ia2l1a2 ial3ar ial3as ia2lä ial3b4 ial3d4 i3aleb i3alef i3alei ia3lek i3alel i3aleng i3alent i3alerb i3aler4f i3alerh i3a4lerm i3a2l1et i3alex i3a2lia i3alim i3a2lin i3al3l ial4ler iall2i i2alo ia2lon ia2lop ia2l1o2r ial3p ial3t2 ia2l3u4 ial3z2 i3am. ia3ma iampe4 i1ams i1an. i1an2a ia2nal ian3alt ia2nau i1anc i3and2 i3a2n1e2b ian2er i1ann i1ans ian2s1p i3ant i3anz ianza4 ia1o ia2op ia3p ia1q i1ar i3ar. ia2ra i2are iar3r i1as i3as. ia3sh i2asi ia3s2p ias3s iast4 i3at. i3at2h i4athe 1iatr i3ats i3au ia3un i2az 2iä i1ä2m i1äp iär2 i1är. iär3m i1ärs iär3z i1ät i3ä4tem iä2ti iä4tr iät5s4 i1äv 4i1b ib1art i2b1auf i2b1aus i2baut ib2bli i2b1eig i2b1eis ibe4n1 i6ber6geb i4b3er4la ibe1ro i2bim i2b1in i2blad i2bleu i3blu i3b2o i2bö i2b3rau ib3ric i2b3roc ib2ser ib4ste ib2un i2b3unk i2b3unt ibus1c 2ic i3ca ic1c ice1 ich1a2 ich6art. ich1ä i1che ich1ei ich2er icherin5 i1chi ich1l ich3le ich3li i3ch6lo ich5m ich3n i1cho ich3ort i2ch3r ich6sele ich2s1i ich4spe ich6stie ich2tr i1chu ich1w i1ci i3cke ickt2 i1cl ic3la ic3ra i3cu i1d 2ida id2ab i3d2ac id4al id1a2n i3d2ans i3d4at id1au id2ax idä1 id2e 2i3de. i2dea 1idee id3eis 2idel idel4ä i4demul 4i3den. ide4n1o iden4se ide3ran iderin8nu ide1rö ider6reg 2i3des ide5sa ide3so ides2p 1i2di2o idi4on i4diot 2idk idni3 id2o i2dol 2idoo i2dö i2d3r id4rä id4rit id4ro id4ru id2s1p idt4 1i2dy ie3a2 ie2bä ie2bl ieb3re ie2bri ie4b3rü ieb4sto ie1c ie2cho iech3t ie2ck ie2d3an ie3de ie2dr ie1e2 ief3akt ie2f1an ie2far ie2fau ie2fäh iefe2m ief3f4 ief2i ie2f3l ie4fonk ief1r ie2fro ie2gl ieg5li ie3g4n ie2g3re ieg4s5c ieg4se ieg4si ieg4st ie3her ie2h1in ieh3r2 i1ei ie1ind i2e2l1a iela2r ie2läs iel3d4 i2ele ie4l1e2b iel1ec iel3eid ie2lek i4elen ie4lene ie4leng ieler4e ieler6fi ieler8geb ieler6ke ieler6la ieler8lebn iel4erw ieles2 i2eli ieli2d i1ell2 ie2lo2b ie2lop ie6lor i2els2 iel3sz ielt2 iem2e iemis2 i1en i3en. i3ena ien1ag ien4am ie4nas i3enä i3end i2ene ien1eb i3enec i3e2n1e4k iener6fo ien3er4g iener6la i3enex i3enf i3eng4 ienge4f ienge4z i3enh ie2nid ie2nim ie4n3in i3enj i3enk i3enla i3enle i3enm i3enn i3e2no i3enö i3enp i3enr ien2s i3ens. i3ensa i3en3sc i3en3s2e ien3si ien3s2k i3en3s2p iens6t5er ienst5rä i3en3sz ien4t3ar i3enth ien3tr i3enty ie3nu ie4num i3env i3enw i3enz ie1o4 ier3a ie2ra2d ie2rap ierb4 i3erbun ier3d i2ere ie4reck iere5ins ie4r3eis ie3r2er ierer3k ie4r3erz ierf4 ierg4 i1ergi i4eri ierk2 i1ern i3ern. iern2a i2erni ie2rö ier4re. ier4s3eh ier3sei iers2t ier3sta ier3ste ier3te iert2i ier3z2 2ies ie2san i2esc i2ese iesen3s4 ie3s4pa ies2pe ie2spu ies6ser6g ies6serl ies2st iest6e ie4stin ie1str ie3su ie4t1ag ie2t1ak ie2tan ie2t1ap ie2tat ie2tau ie4tent ie4t3erh ie4t3ert i4ethe iet3her ie2t1ho ie2thy ie4tob ie2t1ö4s ie2t3ri ie2t3ru iet2se i1ett iet3zw ieu2e ie1un ie2w3u i1e2x 2if if3ange if1ar i2f3arm if4at i2f1au if1än i2fec i2f1ef ife4i if1ein if2e4n i2f1erg if1erh if2far if2f3l if2fro iff2s iff4ste if3l if1lac if4lä iflo4 if4los i1flü if3r i1fre i2freg if4rev if2s if3sa if3se if3sp if3sta if2t3a if2ted if2t3ef if4t1ei if2te2l if2tep if4terk ifte2s if4t3esc if4th if2t1op if2t1r if4t3ri ift3sp ifts2t ift3sz if2tur i1fy 2i1g i2ganb i2garb ig1art iga1s i2g3att igd2 i6gebrau i4gefar ige4füg 3i2gel. ige5lau i2geln ige4me ige4mis ige4na ige6nene ige4nid ige2o ige2pa ige2ra ig5erwer ig1erz iger4ze ige4sel i2g1ess ige4tra ige4tre ige4woh i2gim i2gl ig1lau i3glä i3gle ig3lim ig4na i4gnä i3g4neu ig4no igo1p ig3rad i2g3re ig4ren i2grou ig3s2ag ig4sal ig3sä ig4schr ig3s2o ig3sp ig4spa ig3stei ig4sti ig4s3to ig3str ig6stras ig3s4tü igung4 2i1h i2har i3he ihe1e ih1elt ihe4n ihe3u ih3m ih3n ih3r2 ihs2 ih1um. ih1w ii2 ii3a4 i1ie i3ig i1im i3in i1i4s i2is. ii3t i1it. i1j 1i2js 2i1k ika2ge ik1aka ikaken3 i2k1akt ik3amt i2k1ang i6kantei ikanten8n ik1art ik3att i2k1au i3kaz ik1äh i2kär 4ike i2keb ik1ebe ike2c i2k1ed i2k1ef i2k1ei ike4l1 ike2n1 ik1en2s ik1ent ike2ra i2k1e4r2e i2k1er2f i5kerfam i2k1er2h i2ker2l i2kero i2ke3ru i2k1eta 4iki i3ki. ik1i2d i3kie ik1in i2kins iki1s i2k3l ik4län i3k4leri i3k4let ik4lim i3klu i2kne ik3nu iko3be i2k1off iko1p2 ik1or iko2ri iko1s i2köl ik3rä ik3re i2kres ik4ris i3kro i2krö iks2 ik3sa ik3ste ik3sz ikt3erk ik4t3esk ik2t3re ikt2u i2k1uh i2kup i3kus i2kü i1la i2lab i2l1ac i2l1ak il1a2ma il1ang i2l1anm i2lano il1ans ilan6zer i2larb il1asp i2l1au i3laub i3l4aufb i1lä1 i2lär 2ilb ilb4l il2c il5chen il2da il2dä ild3ebe il4d3en4t il3der ild4erp ilde2s ildi2 ild1o il2dor il2dr 4ile il1e2c il1ein il1el i2lemb i2l1e2mi il1ent i4lentl i4lents i2l1erd iler4ei i6lereig il1erf iler4fo i2ler2g i2l1er2h i4ler4kl il1err i4lerri i3l2erz ile4th il1ex ilf2 ilfe3s il2f3l il2f3re ilf4s3 il2gl 2ilh 2ili ili3e4n3 iliga2 ili4g3ab ilik4 i2l1ind i4l3init il1ins i2l1ip ili1pf il3la ill2an il4lenn il3l2er 1illu il2mak il2m1ap il2m1au ilm1ei il2min il2mor 2ilo il1ob il2oh il2op i2l1o2r i3lou i3lov il1ox ils3ent ils4to ilt2 il3th i1lu i2lum ilung4 i2l1ur i3lus ilü4 2ilv4 il2zar il2zau ilz3erk il2zwa imad2 ima1i im2al i2m3anh im1ans i2marc im3aren i2m1arm i2m1art im2as im4at ima2tr imat5sc ima4tur im1aus i2maut im3b 1imbi i2meg im1ein i2mej i2mek i2mele i2melf im2en i2m1er2f i2m1er2l i2m1er2z i4me3sh imes3s i2meti i2mew imhau2 i2mid im1i2de i2mim i2m1ind i2minf i2m1ins im2mä im2mei immen1 imm3ent im6menth 1immo im2mor 2imo i2m1ob i2mo2p imo3re i2mö 1imp imp2fa im3pf2o imp2s im3pse im4set im3sph 2imt imt2e im3t2i imt3s2 imtu2 4imu im2um im1urk 2in. ina2be in3abu in1a2c i4nack in1ad i3nald inaler4 ina6lere in2alp i2n1am in2an in3an. in3ana in3ann i2narb in3att i2n3au2 2inä i2n1äh in2är in1äs 2ind. inda2 ind2ac in2dal in2dan 2indä 2inde. 2inden ind5erke inder3t inde3sp 1index ind2i 1indik in3dö 2indr ind3se 1indus in3d2ü 2ine in1e2c i3nee i2neff in4elen ine2n1 ine3nä i4nen4zy i5ner. i4n3erbi in4erha i4ner4he i3nerk i3n3erle i6ner6leb iner4lö i4n3er4tr i3nes i4nesk in2et in1eu ine3un in3f4 1infek 1infiz 1info 2inga in2g1af in2g1ag in2g1al in2gam ing1ar 2ingä 3ingeni in3g2er in4g3er4w inges4 2in2gl in3gla in3glä ing4s3am ings6por 1inhab 2inhar 2inhau 2inhe 2ini. in2id ini3de 2inie 2inig inig2a ini3k4r 2inis ini3se init2 i3nitz 3inkarn 1inkas inkels6t in4k3ent ink4er in2kro in3k2ü inma4le 2inn. inne4n in4ner4m 2innl in2nor 1innta 2ino in1od ino3e4 in3ols in1or ino1s i3no3t i2n1ou i1nö in1ö2d 2inr 2ins. ins2am in6samt. insch2 2inse. in2seb 2insed 2insen 2insk in3sof 3instal in4s3tät 4inst2e in3s4tip 3instit ins4to 4instra in4strü 1insuf ins3umz in2sur in3sz 2inta 2inte. 1integ in3tei 2intep 2int2h inthi1 int2o 2intö 2in3t4r 4inträ in5tri 3intrig int3s i2n1u i4nuh in3unz 4inverm invil2 i1ny2 in3z2e inzel8ler in3z2i in3z2sc inz2u in3zw i1ñ 2i1o iob2l io1c io2d io3da io3e4 i2of iof4l i2oh io1i io3k6r i3ol. i3ols i3om. io3me i3oms ion2 i3on. ion3an io2n3au ion3d2 io4nee i3ono io2nor i3ons3 ion4sa ion4sen i2ony i2oo i2o1p i3o4pf i3opt i2or i3or. i3orc ior2e iore4n io1r2h i3orp i3ors i3ort 4ios i3os. io3sh ios2p i2o1st ios2u i2o3sz io3t i3ot. iote3l iot4r i3ots i2ou i2ov i3ox i2oz i3oz. i1ö2k i1ön i1ös. i1öst i1pa ip2an i1pe i3ped i3per 2ipf2 i3pfan ipfe2 iph2 2i1pi ipi3a ipi3el ipi3en ip4lu ip2pan ip3pe ipp1f ip4pl ip3pu i1pr ip2sa ip2sei ip2sp ips3t ip4sta ip4stü ipt2a ipt2i ipt2u 2ipu 2i1q i1r4a i3ra. 2i3rad i3ras irat4 i1rä ir1äh ir2b3l ir1c ir2ch1o ir4e i3ree 2irek ire4na i3ré irg4 ir2he ir2i 2i5rig 2irk irke4n ir4kene ir2k3l irk4s3c ir3k2u irli4n ir2m1ag ir2mak irm1au ir2mä ir2m1ei irme4n1 ir2m1o2 irm4th ir2mum ir4munt 2irn ir2n3a ir4nat ir2no i3ro i1rö irpla2 irre4l ir2rh ir3sche ir4schl ir4schm ir4sch3r ir4sch3w ir3se3 ir3s2h ir2st irt2s3t 2iru ir1u2m iru2s1 i3r2ü i2sac isa2m3 i4samp i4s1amt is2ap isa2r is3are i3sat is3att i2sau is3auf isau2g i2säh i2s1än 2isb i2sca i4schar i3s2che i4schef i4sch3e4h isch3ei ische4m i6schemi i6scher6z i4schin i5sching i2sch3l i2schm isch3ma i4schna i4sch3re isch3ru i3schu i4schüb i4schwa i6schwir i4schwo isch3wu i4schwü i2scr 2ise ise3a ise1e iseh2a ise3hi is4eind is4eli i6sel6ter ise2n1 ise4na is2end i4senho isen3s ise4r3ei is1erg i2serh iser4he i2s1erm i2s1es4s i3s2et i4s3etat i3s2eu 2isf 4ish 2isi isi2a i2s1i2d isi4de isik2 i2sim isin3g4 isi1s i4ski i4sku is3la 3islam 2isma 2ismi ismu2 is1of i3soh 1i2sol 2is4o2n1 isonen4 iso6nend isono2 i2sop is1ort 3isot i2s1ou 2isp is1pa i2spar is2pat is1pe is1pic is2por i2spro is3sa is4s1ac is4sau is6s5chen isser4f iss2po is2st is3sta is3sto iss3tr is3strä is3stu is2sum is4tab ist3a2c ist2an is3tang i1stat is3täu ist4e i1stel iste4n istes3 i1steu i1stil istin4f is3t6o is4toc is3tör is3tr ist4ra is4tro is4tru i1stü i3suf isu2m isum3p i2sü 2isy i1ß ißer2s iß3ersc it1ab. it1abs ital1a it1alt it1am ita3ne it3anr it1app it1a2re it1art i3tat it1au i3tauc i2taut 4itä it1änd i2t1äs ität2 it1eff i2t1ei it2eic 2itel ite4l1a i4telek i2t1emi i2temp ite2n iten3s2 i4tents i2tepo i6tereig i4t3er4fo iterin6d iter6klä it2erö i8t7ersche i4t1esk i2t1ex i3text i5thr i2thy i5tic i2t1id i5tig 1itii it1in1 i3tis i4tiso iti3sp iti2v5a it5le itmen2 4ito it1ob i5toc ito3d i2t1of ito2p it2os 4itr i2t3rad i3tradi it3raf it3ras it3rau it3räu it3re i4tren it4ret it3rob it3rom i2t3run it3rut 2its it2sa its1ag it2s1e it4se2h it4s3e2r1 it4sh its1or it6stras it2sur 2itt it2tan it2teb itt3hä it2tob it2top it4tri itt3ric itt6schi itt4se4h itt4sei itt4sor itt2sp itt4sti it1uh it1ums it2ung i2tuns ituran4 it1urg itut4 i3tü 4ity1 ityl2 it2ze2c itz2er itz3erg it6zergr it4z3erl it2zö it2z1w 2i3u2 i4u3l iu4m3 iuma2 ium4se ium4ste iun2 i4up iu4r ius3t i1ü4 2i1v i2v1ad i2v1ak i2v1am iv1an i2v1ä i2veb i2v1ef iv1ei iv1elt ive4n iv1ene i2v1ent i2v1ep ive3re iv1erh iver4kl iv1erl iver3s ive3s i2v1ex i2v1im i2v1ind iv1int i3vol ivo3re i2v1r i2vun i2v1ur i2vü 2i1w 2i1x i2xa ix2em i3xi ixt2 i1y 4i1z iz1a iz2ac i2zag i2zan i2zap i3z2as i2zau i2zä i3ze iz2ei izei3c izeits4 i2zele ize2n i4zener i4zentz i4z1erl izid3 iz1ir izo2f i2zö i2zuna i2z1w i3z2wi í1l j2a jab4 ja1c jah4r3ei jahr2s ja3l jal2a ja3ne jani1 jani3t4 ja5ru jas2o ja1st jat2 2j1d4 jda3 je2a jean2s je2g jek4ta jek4ter jek4tin jekt3o2 jektor4 jek6t3r je3na je2p je3r jer2e jes3t je2t1a je4t3h je2tin je4tor je2t3r jet3s2 jet3t je2t1u2 je3v je3wo ji2v 2j1m joa3 jo2b1 job3r jo2da jo2i jol2a jong2 jo2p3 jo1r2a jor3d2 jo1s4 jo2sc jost2 3jou jou2l 2j1t jty1 j2u ju2b3l jugen6 jugend3 ju1i ju2k jul2i jung3s4 ju3ni ju3r jur4a jur2o jus3t ju3t2e1 2j1v 1ka 3ka. ka3ar 2k1abb kab2bl 2kabd 2k1a2ben 2kabf 2kabg 2kabh 2kabn 2k3a2bo 2k1abs 2k1abt 2kabw 2kabz ka1c kade2r 2k1adm 2k3a2dr 3kadu 2kadv ka1f4l ka1fr kaf3t2 kag2 kaga3 2k1age 3kah ka1ho ka1in kaken2 ka1kl 2k1akt. 2kala. kala3b ka2l1a2d ka2lan kal3d ka4l1eh ka4lens kal3eri 3k2alk kal2k1a kal4kan kal2k3l kall2i 2k1allt ka2lop ka2l1os kal4tex kal4th ka2lu k2amt kan4al ka4n1a2s ka2nau 2kanb kan3d2 2kanda 2kandä kan2e 2kanf 2kanim kank4 2kanl 2kanom 2k1anor 2k1ans k2ans. kan4tar 6k5antenn 2k1anth ka3nu kan2um 2kanw 2k1anzu 2kanzü ka2o1 3kape ka3po 3kara 2karbe 2karc k2ard kar3d2a k1area k2arg ka3r2i kari3es k2ark 2k1arm kar2pf k2ars k2ar3ta k1arti 4kartik karu2 k2arw 3k2asc kas2e kase1i kasi1 kas2o ka4sp ka2s3t 2k1ast. ka4ste kas6tras 3kasu ka3sz ka2tan 3kateg k3atel ka3t2h ka4t3r 2katt4 kau4fer kau2f1o kauf6s5ag kauf4sp kaufs7tem kauf6sti k2aus. 2k1auss kau2st 2kausw kau3t2 2kauto ka3ve 2kaz 1kä käl3 k1ämi 2k1änd kär2 2k1ärg kä2s1c käse3 4k3b4 kbo4n kbu2s kby4 2k3c 2k3d4 ke2ben 2k1e1c ke2di 2k1eff kefi2 kege2 ke2gl ke2he. ke2hen kehrer4 kehr2s kehr4s3o 2k1eic 2k1eig kei2li ke2im 2k1ein kein4du kein4e k1ei1s 2keise keit2 keits1 ke2l1a ke3l2ag ke4l3am ke2lä kelb4 keld4 kel3eis 2ke2lek ke2l1en ke2l1er kel7l4e kell2i ke2l1o2 ke2lö kel3sk kel7s8tern k4elt kelt4e 2k1e2mi 2k1emp k2en. ken1a ken3au ke2nä kend4 ken3dr ke2n1e2b kenen1 ke4nene ke4nens kener4n kene4t 4ken4gag k5en6gel. ke2nim ken3in 4kenlad 4kenläd kenn2a kenn2e ke2no k2ensa 4ken4sem ken3si ken3s2k ken5s6tei ken3sz k3en4te. ken6ten. 2kentf 2kentg ken3th 2kentl 2k1ents 2kentw 2kentz ke3ny k2en3z2 2ke1o2 2kep ke2pl k2er. ke1ra ke2ran ke2rau ke2r1ä ker4ble k2erc 2kerd ke2r1e2b ke2rec ke3reig ker3ein 4kerfah k4erfam ker2fo k3ergeb 2kergu ke6rin6nu kerin6st kerin4t k3erken k2erko k3erlau k3er4leb k6erlebe ker2na ker4nei 4k3er4neu kern5eur k1ero k2e1rod 2keros ker4reg k2ers. 2kersa kert2 ker6werb kerz2 k1erz. ker4zeu 2k1er2zi k2es. ke2sa k2esc k1ese ke2sel kes2sa ke4t1a ket2ag kete4 ke4t1eb ke4tel 2k1e2th ket3ha ke2tu keu6schl 2k1e2va 2k1e2x 4k3f4 2k3g2 kga2s1 kge3s 2k1h4 k3he kho3m k3hu ki1a ki2ad ki2ag ki3ak ki3a2r ki1c ki3d4r k2ids 2kidy ki2el kie4lei kiel3o 2kiern kier2s kier4st kie4z ki1f4l ki1f4r ki3k4 2ki3l2a 2kilä 2kim 3kin. ki2nä 4kindex 2k1indi 2k1indu 2k1inf k2ing kin2ga king3s 2kinh k2ini3 kinik2 k2inn ki3n4o3 kinos2 kin3s 2k1inse k1inst 2k1int ki3or kio4s 3kir 2k1i2so kis2p kis3s kist2 kis4to kiv2 kive4 2kiz 2k3j 2k1k4 kkab4 kl4 4kl. 4kla. 2k1lac klan2 2kland klan3du k4lar k1last k1lauf k3laug 2kläd k2lär k2le 4k3le. kle2br k3leg 2kleh klei2e k3leit k3lem. kle2o 2k3ler kle2ra 2k3leu kle3us 2klic k2lien k2lif 2klig 3k2lim k2lin k3lin. 3k4lina k4link k2lip k2lir k2lisc 2klist klit2s 2k3liz 2k3loc 2klok 3k4lop k3lor klost6 2klöc 2klöf k2löst k4löt k1lu klu4b k2lud k2lug k2lum klung4 2klux 2k1lüc 2kly 2k1m 4kma kma2la k2n2 k4nac 2k5nach 2k3nad 2knah 2k3nam 2k3näp k3ne k4nec kne1e 2knes 2knetz 2k5neu 4kney 2k3niv kno2b3l k4nol 2knorm 2knov 2k3num 1ko ko5ad ko2al kobal2 2kobj kob4s kof3f2 koffe3i kohl2e kohle3i koh3lu koka3 ko3l2a ko3le kol2k3 3kom komer3 4komn ko4mu k2on kone2 ko2nem kon3s4 kont6e ko2nu ko3on 2kop. ko1pe 2koper kopfa2 kop4fen kop6f5err kop3s ko3pte ko3r2a kor2ba kor2bl kor2br 2k1orc korder4 kor6derg ko2rel 2k1org kor2k1a kor3m kor4nac kor2n3ä kor4no2 2korpi k2os k4os. ko4sk ko2sp 3k4ost ko2stü ko4ter ko3ti kot4r kot3s2 kot4tak k1ou ko3un 3kow ko2we 2k1ox 1kö köde2 k2öf k1öl 2k1p2 2k3q k2r2 2k3rad 2k3rah k4ral k3rats 2kraum k4raw k4raz k4räc 2kräd k4rän 2k3räum 2k5re. 2k3reak 2k3real k4reb 2k3rec 2kred. 2k3rede 2kredn 2kredu 2k3ref 2kreg 2k3reic kre1i2e4 kreier4 k3reif 2k3reih 2kreim krei6sei krei4st kreli1 k3ren 2kresu 2k3rh 2krib 2k3ric 2k3ries 2krip k3risi krob4 k4roch 4k3roh k4rok k4ron k4rop 2krot 3kroth k3rou 2kröh 2kruf 2k3run 4k1s ks3a2b ksa2k k4s1amt k2san ks3a2r ksa2s k2sau ksau2f k2sav k2säh k3s2c ksch4 k2s1e2b k2s1ec k3s2ed ks1ei ks2eid ks2eif k4seind kse2le k2s1eng k2s1ent ks1er ks2ere k2serf k2serg k2serk k2serl k2sers k2serw k2s1e2v k2sex ks3ha k4s1i2d ks2im k2s1in k2s1is k3s2ke ks3kl ks1o ks4on k2sop k2so2r k2sö ks1pa k2spal k3s2pat k2spä k3spe ks2pel ks2pen k2sph ks2por ks2pul ks3s4 kst2 k2stal k4s3tanz k3stat4 k3stäl ks4tel ks2tep k4stier k2stit ks4tol k2stor k4strop k2stuc k2stum k2stur k2stüt k2s1u k3sul ks2zen 4k1t kt1abr kt1abs k2t1ad kt1akt k3tal kt1am kt1an kt2and k2t1a2r kta4re kta3ri k2t1au kt3aug ktä3s kt1ein k2tek k4t1ela kte4n1 kten3s2 k2tent k4tentf k4tents kten3z kte2ra kte3ran kt4ere k4t3erfo kt1erg k2t1erh k2terö kte3ru k2tex k2t1h k2t1i2d kti2me kt3ind kt1ing kt1ini kt3inn k2tint kti2s1e k2tiso kti4ter kto3b k2t1of kto5ren. k3t4ran kt3ras k2t3rau k4tref ktro1s kt3run kt3rü kt3s4a kt3sä kt3se kts2el ktsen1 kt3si kts1o kt2sor kt3s2z ktt2 k3tub kt1ums k2tuns k3tü kt3z2 ku2al ku1c kud4r 3kug ku2h 2k1uhr ku3la ku3l2e ku3l2i 4kulp kul4to kul2tr k2um. k2um4e 2kumg 2kuml kum2sa kum2sp k2u3n2a kun3da kund2e kunden3 kung4 kun4s4 kunst3 2kunt 2kunw 4k1up. kur2bl ku2rei kuri2e kuri4er 2k1urk ku2ro kurs1c kur2sp kur2st 2k1urt4 kur3tsc kus3a2r ku4schl ku2sp 2ku2s3t2 ku2su 2kut. kut2a kuto3 1kü kü1c 3küne 3kür kür4s 2k3v 2k1w k3wa 2k3z2 kze3l 3la. la3ar l1ab 3l2ab. lab2a la2bad l2abä 2labb lab2br 2labd lab2e 4la2ben 4labf 2labg 2labh 3labi l3a2bit 2la2b3l 2labn 3lab2o 4labo. la3b4ra lab4res la2bri 2labs la2bus 2labw 2labz la1ce la2ce. l4a3che lachter8f lacks2 1lad 2l1ad2a 2ladd 3laden la3d2i 2ladj 2l1adl 2ladm 2l1a2dr 3l2adu 2laf la2fa la2f1ei la2f1er laf1r laf3s laf3t4 la2fu la2g1a lag3d l2ager lagerin5 4lagg la2gio lag3l la4g3n lago4 la2gob lag3str 2la3ho 3lai lake2 la2kin l2akk la1k4l la2kro lak3t2 2l1al la2la 3lala. 3lali 4lalt lami3t lam2m1a 1lammf la2mor l2amp 2l1amt lamt4s la4mun la2na la3nan la4n4at la4nau 2la2nä 3l2and l4and. lan2da lan4dam land3au l4ande lan6derh lan6d5erw lan6d5erz lan6d5inn l4an2dr lan3dri land3rü lan3erd laner4f 2lanf lan4gan lan6g5esc lang3s4 2lanha l2anhe 3lan2i 4lanl 2l1ann l1ano la2nof 2l1anp 2lans2 l1ansi 2lantr 2lantw 2lanw lan2z1w 3lao 2l1apf la2ph 2l1a2po lap2pl la2r1an 2larc lar1e2b la2r1ei la2rel la4rene larf4 lar3g lar3ini 4l1a2rom l1art 2lart. lart2h l3arti lart4r 3laru l2as. la2sa la4sam la4sä lasche4 4lasd la3seb la2sei la2s1e2l 2lash la2sin la2sis la2so 2la4sp 3lasser l2a2st las4t3an la4ste last3ri la4stu la3t2e 2l3a4tel la5t2i 2l3atl 2latm lat2o la2tö la2t3ra lat4ri lat2s lat3st 2lat2ta lat4tan lat4tex lat4t3in lat2t3r latzer4 1laub. lauben6s5 lau2b3r laub4se lau4fin 2laufn lau2fo lau4fri 1laug lau3gl 2laun. la4us 3l2aus. 2l1ausb lau6scha 2lausd 2l1ausf 2lausg 2lausl 2lausr 2l1auss lau2st 2lausw 2lausz 2lauto lau2tr la3va lave4n 1law lawa4 1l2ax la4xel l2ay lay1s lä1c 3läd 4läf 2l1ähn 2lämt 1länd 2l1äpf 2läq lär2ma l1ärme 2lärz lä2s1c 2lät 2läub 2läuc 2läue 1läuf 2läug 2läx 1là 2l1b l3bac l2bant lb3a2ri lbau1c lb1ärm lbb4 lbby4 lb2ei l4b3eink l4b3eise lbe4ral lberin5 lbe7s l4b1e4ta l2b1id l2b1ins lb4lad l3b2lat l3blä lb3le l2bled l2blic l3blo l3b2lö l3b2lu l2b1o2ra lb3rea lb2s lb3sa lb3se lb3si lb3sp lbs4t lbst3ac lbst3ei lbst1u l2b1uf l3bum lbu4n lbzei2 2l1c l3ca l3che l4chei l4chent l3chi lch3le lch3li l3chlo lch3n lch3r lch3s2 lch3ü lch1w l2ck l3cl l3co 4l1d ld3a2b1 ld2ac ld3a2ck l2daf lda2g l2d1ah lda2i l2d1ak l2d1al l2d3a4n ld1arm ld1ass l2d1au ld3aus l3däm ld1är ld1äs ld1ät l3de. lde4ben l2dei ldein7 l2d1elf l2d1e2mi l2d1ems lde4na lden5erg l4dentl l3der. l4d3er4fa l6der6geb ld1erh l4der4he l3d2erl l6d5erlas l3d2ern l2d1er2p lder4tr lde3sa l2d1es2s l2dex l2d1id ld1i4mi l2d3ion ldo2b ld2on l2dop ldo2r l2d1ori ld2os ldos5t ld2ö2 ld3r ld4ram l2dran l2dre l3d4ris ld4ru l2drüc ld3sa lds4an ld3ska ld3st ldt4 ld3th ldt5s ld3tu l2d1ul l2d1um ldwes4 ldy2 1le le2ad le3ar le2as 3leba leben4s3 le2bl 3lebr le2b3re lebs2 2lec lech1a le2chi lech7t6e le2dr le2er lee4ret le3f2a 2l1eff lef4o le2g1ab leg1as le2gä le2gl leg4r legs4 3leh 4lehe. leh3r2e 4lehs 4leht lei4ble l2eid lei3ere lei4fan lei4fei leifer6g leif3s 2l1eig lei3gl 3leih lei4hau lei3l2 leim3p 3l2ein. l2eind lein4du l4eine lei6nerb le2inf le2ini 2leink 4l3einsa 2leint l2einu le2is leisch5a lei8schei lei6scho lei6sern l1eisf leis6s5er l4eist lei4str lei4ßer l2eit lei2ta lei4to lei5tri leit3s2 leits4t 3leko 2lektr 2lekz 3l2ela le2le le3lei 2lelek 4leleme le3len leler2 leler4s le3les 2lelf. 2l1elfe l2eli l2em. le3mal le2mau le2m1ei 3lemes 3lemet lem1o2 le2mor 2lemp lem3s le2mu le4mun l4en. len1a len3ab le4na2d le4n3an le4n3a4t le2nä 4lendet l1endp 4lendun le2n1ed 4lenerg le4neur 4leneuv len4gag len4kau len4k3lo len4klu l1enni len6sein 4len4sem len3ska len3sz 2lentg 2l1entk 4lentla 2lentn 4l3en4tro 4l3entw lent4wä 5lentwet 2lentz 2lenzy leo2f le1o2s 2lep 3lepf 4l1e2pi 4lepoc 3lepr l2er. l2e1ra le2rag le2r3ap le2ra2s le2rau le2r1ä le2r1e2b ler2e3c l3ereig le4r3ei4m le4r3eis le2rel le4reng le4rerg le4rers le2re4t 4l3erfas 2l1erfo l2erfr l2erfü l1erg l2erga l4ergef 3lergeh 6lergen. l4erger l4erges 3l4ergew 2lergi l2ergl l2ergr 4ler4heb 4lerhol lerin4s lerk2 l2erka 2lerke l1erkl 4lerklä l4erkle l2erko ler3kr ler3l 5l6erlebe 3l4erlei 2lermä ler4nal ler4nar 3l4erne ler4nei 2l1erö 3l2erra ler4ric l4ers. l1ersa lers2t ler4sto lert2 ler4trä le2rup l4erwa ler4wer 2ler2wo 2l1erz ler2zä l3erzeu ler2zo l4es. les2am les2e lese1i 2l1esel le3s4h lesi1 le3s2k les4ki le3so le2spo lest6 le1sta les2te3 lester6i le1sto le1str 3lesu 4lesw 2lesy le2tab 2le2tap 2le2tat l1e2th le3tha 2lethi let2i letsche6 let4top lett1r letts2 le2u 4leue 3le3u2f 2l1eul le3unt 2leuro 3leut l1e2vol 2lex 3lexd 3lexik le2xis 1lé 2l1f l3fah lf4at l2f1ec lfe1e lf3einh l2feis lf2en l4ferei lfe4rel lf1erl l3fi l3f4lä lf3led lf4lö l3f4lu lf3ram lf3res lf4ru lf4rü lf2spe lf2sti lf2su lfun2 lfur1 2l1g l3gas lga3t lgen2a lgene2 lgeräu3 l2geti l3g2i lg2lö l3go lg4p l3gra lg3re l3gro lgung4 2l3h2 4lhe 3lhi. 4lhu 1li li1a lia2b li2ad li4am. lian2g li2ast 3lib4 libi1 li1c lich4ta lich4to 4lick li2cka li2cl li3d2a l1ido l2idy 3lie. liebe4s3 lie2br li1efa 3liefer li1efk li3efl lie4n1a2 li3ene lien3s lien3t lie4rei lier4sp lie2s1c 3lig liga3s li4g3ers li4gl lig4n li3ker lik2o likop4 lik2sp lik4ter lik2ti lik4t1o2 lik2u li3l lil2a li3m2a1 limas4 lima3t4 2limm 3limo 2limp lin2a li3nar 2lindi 2l1indu li2nef li2neh li2nep li2nes 2l1inf 2l1inh li5nie lin1it 2l1inj lin4kan lin4kar link2s li2nol l2insa 4linsel 2linsp 2linst 2linsu 2linsz 2l1int li3n2u 2l1inv 2linz li2o li4om li3o2st 3lipf 3lipt 3lis. li3s2a li3schm li4schu lis2h li3shi 3lisk 2l1isl 2l1i2so li2sp liss4 3list lit4a l1i2tal li3t2ä l2i3t2e 3liter li4t3r lit1s2 lit3se lit3sz li3tu li6tun li4tur litz4er 3liu liv2e li2vea li2ves livi3e li3vr 2lixi li4z3ä lizei3 2l3j 2l1k l3kale lk1alp l3k2an l3kap l3kar. lk1erd lke3r2e lk2l lk3lad l3k4las lk3lic l3k4lu lk2men lk4ne lk5ner lko2f lk1ofe lkor2b1 lk3roc lk2s1 lk3sän lk3si lk4spe lks3t lkt2 lk2ü 4l1l l2labk l2labt l3labu l3lage lla3gl l2l1am lla2ma l3lame ll2ami ll2anb lla4ner l4lani l3lans. ll4anwa ll1anz l4l3appl ll1arm l4latm ll3att ll3aufg ll1aus ll1äm l2lär llb4 llch4 ll3d4 ll5ebene l3lec ll1ech lle3er l2l1ef ll1eic ll1eim ll2eis l4leise lle2la lle2m l2l1emi l3len. lle4na llen3dr ll5en6dun l4lentf l4lents l3lep l3ler. lle2ra ll2ere l6ler6eig ller4fo ller6geb l8lergene l4lergo ll3erho l4l3ermi l4l3ernt ll3ertr ll2es lle4th ll1exe llg4 lli4gan l2limb l2l1ind l4linf ll1ins ll3k4 ll3l2 ll5m2 ll3n2 ll1ob l2lobe l2l1o2f ll3ol l2lope ll1opf ll1or l6lorb llor2g l2lo2ri l2l1ou l3low ll1ox ll2säu ll2s1es ll3ska ll2spr ll3t llt2e llt2i llti2m ll5t4r llts2 ll1ur llus5t6 l3ly ll3z2 2l1m l2m3a2b l2m1ad lm1a2ge lm1aka l2m1a2m l3mana lm1apf lm1art lm3att lm1äst lmbu2 lm1c lmd2 lm3e4dit l2m1ef l2ment l2m1e2p lmer2 l2m1erf l2m1erl l2m1erz l4messa l2m1i2d lm1ind lm1ins l2mof lm1orc lm3p2 lmpf4 lm3s2k lms2t lm3ste lm3s2z lm3t4 l2mum l4munt 2ln ln2ab lna2r ln3are lnd2 l3n2e lnes2s l2n1in lnus2 l1nü l1ny 1lo lo4ak 3lob. l2oba 3lobb lobe2s 2lobj l1o2bl l2obr lob4ri lo4chel l1ofe lo2fen lo4gh lo2gl lo2gor lo2gre lo3ha loh2e 4l1ohr loi4r 3lok 4l3okk lo2k3r 5loks l4ole 2l3o2ly lomä3 lo2min lo2ner lo4nin lo2n1o lo2o 2lopf lop2p1a 2lopt lor3am lor2an lo4rä 5lorb 2l1orc 2l1ord lo3r2en 2l1org2 lori4di 2lort2 l2os. lo4sa 3lose lo4ske lo2spe lo2spr los3t lo4ste lo2st4r 4loß lo2ta lo3tha loti4o 2l1ov lo2ve 2lox 1lö lö2b3 2löck 2löd lö2f 2l3öfe 2l1öhr 2lök 2l1öl3 2löp 3lösc 3lösu 4löß 4löz 2l1p lp2ar lpar2k1 l4p1är lp2f lph4 l3phä l2phir lp1ho l3phr lpt4 l3pu 2l1q 2l3r2 lrau2s lrebs2 lro2h lrö2 4l1s ls3a2b l2s1a2d ls2al l4s1amb l4samp ls2amt l2san ls3ane l3sare ls3a2ri l3sark lsau2 lsau4m lsau4r l3s2äm ls2äug ls1äus ls2c l4schin l4schmü lschs2 l2s1e2b ls2ele ls1eli l2sent ls1er l2serf l2serg l2serh l2serk l2serl l2sers l2serw lse2t ls1eta ls2ext ls3ha l2s1id l2simp ls2kal l3s4kele ls2ky lso4b l2sop l4s3ort. l3s2öl l2spac ls2pe l2s3ph l2s1pir l3s2pit ls2po l3spri ls2pu l3spul ls3s4 lst2a lstab6 ls3tabl ls4taf lstahl3 l2stas l4stat. l4state l4s3täti l2ste l3stea l3stec l3steh l3stei l4steil l3stel l3stemp l4sten ls4t3erk l5s6terne l5s6terns ls2tie l2stit l4stoch ls4toi ls4tol ls4tru l2s3trü ls2tu ls4tüm l3suf ls1um l2s1un ls2und ls3unk 4l1t l2tab lt1abs ltag4 lt1am l4tame ltampe4 l3tan. ltan3d l2t1ap lt1ara ltar8beitn l3tark lt1art ltar6tik l3tartu lt1au l4tauf lt3aut lt1äh ltbau1 lte2c lt1eh l3tehu lt1eig lt1ein lte3mi lt2en lten6gel lten4sp lt3ents lte4ral lter4fa l3t2erg l4terhe lter6ken lter4ku lter4nä lte2ro lt2erö lter4se l4t1es3k lt2est lte3str lt2et l2t1h lt3hag l3thas l4t3hei lthol2 l3t2hu lt1ide ltimo4 l3tine l2tiso l3t2i3t l2t1ob l2t1o2f l4tord l4torg l4t1o2ri lto2w lt1öl lt1ös l4t1öt ltra3l lt3räu lt3rec lt3rei lt3ris lt3rol l2t3rö l2t3rus l4ts lt2se2l lt4s3ort lt2s1pe lt3s2ph lt2sti lt3t l3tub lt1uh l2t1um lturan4 lturen4 ltu2ri l3tü lu1an 4lu2b3 luba2 lubs2 lu2dr lu2ec lu2es lu2et 1lu2f2 2l1ufe 2luff lu3fo luft1a luft3e luf4tei luft3r lu2g1a lu2g1e2b lu2gei lugen1 lu2gi lug3l lu2go lu2g3r lug3sp lu2gu 2l1uh lu1id. lu4ig lu1is. lul2ö 2lumd lume4 2lumf 2lumg 2l1umh 2lumk 2luml l2ump 1lumpe lum2ph 2lumr 2l1ums lu3mu 2l1umw 2lumz 1lu2n 2l1una lund4 2l1unf lung4sc 2l1uni 2lunr 2l1uns 2lunt 2lunw 4luo l2ura lu2r1an lu2rat lu2rei 2lurg l2uri lu2ris l1urn lu2ro 2lurs l1urt lu4ru lu3sak 2luse lu3si lu2sp lus4s3a lus2s1c lus4sel lus4s3er4 lus2s1o lus4s1p lus2s3t lus4stä luss5tr 1lu2st lus6terl lus4t1o2 lust3re lu2s1u lu2t1a4 lu4tas lu4t3au lu2tä lu2t1e4g lu2tel luter2 lu4t3erg luter4s lu6t5ersa lu2thy 2luto lu2tob lu2t1o2f lu2top lu4t1or lu4t3r lut5schl 2lüb 3lübd lück4e2 lücker3 5lüd lüf3te lü2hel lüh1l 2l1v2 lva3 l3vl lv3r 4l3w4 2lx 1ly ly1a2 ly3c ly3es ly1l 2lymp 3lyn ly3no ly1o ly3t ly1u 2l1z l2z1ac l2z1ag l2zan l2z1ap l2zat lz1aus l2zäp l2zär lze2l l2zele l4z3enth l2z1ep l2z1er2h l2zerz l2z1id lzi4m lz1imi lz3l lzo2f l2zö lz3t2 l2z1u4fe lzvol2 lz1w lz2wec l2zwu 1ma 3ma. maa2 m1ab m3a2bar m2abä 2m3abb m2abe 2m3abf 2mabg 2mabh 2mabk m2abli 2mabm ma2br m2a3b4ra 2mabs 2mabt 2mabz ma3chan mach2e mach8terh mach8t7ers mach4tr ma2ci mack2s 2m1act mada2m m2adä ma2del ma3dj 2m1adm 2m1a2d4r ma4d2s mae4 ma1f4 mag2a ma2ge. ma2geb ma2gef ma2geg ma2gek ma2gep ma4ges. ma2get ma2gev ma2gew 2m1agg magi5er. magi5ers ma3gl ma3g4n 2m1ago ma3ha mahl4st ma1ho mai4s3e ma2ke. 2m1akt mal2ag mal1ak ma4lakt ma2lan ma2lau ma2lär 2mal2de m2aldi ma3le ma4leb mal2er ma4lex mali1e mal3lo 2mallt ma2lon ma2lop m2alp mal3t malu4 ma2l3ut 3malv ma2mid mam3m 2m1a2nal ma2nar 2m1a4n4at ma2nau 2m1anä 2manb man2ce 3man3d4 ma2net m2anf mang2 2man3ga m4angel 2m1angr m2anh 3manip 2manl m2anle 3m2ann 2manod 2m1ansa 2mansä man2t1h 2mantr manu3 ma4n1ut 2manw 2manz m1anza ma2or ma2phr ma2po ma1q m2ara 4marag mar2an 2marb mar3g2 3ma1rh ma3r2i m2ark mar2kr 4mar2o maro3d 4marr mar6schl mar6schm mar6schr mar2sp mar2su 2m1arti ma3r2u m1arz 3mas ma3s4a mas2e ma3s2p masse4n3 mas4ta mas4tel mas2ti mas4to mas4tr ma4s3z 3maß ma2ta2b ma2tan ma2tä m3a2tel ma4t3erd ma4t3erz m4atme 2matmo ma2to ma4tort mat3se mat3sp matt4r mat3url 2m1au2f 3maul ma3un mau3r 2maus mau2ta m4ay ma1yo 1mä 2m1ähn mäh1r 4m1änd 2mäo 2m1äp 2mäq mär1 mär2kl mär2z1 mä3t4r mäu2s1c 2m1b2 mbe2e mber2e mbe3ri mbert4 mbi3er. mb4l mble1i mb4r mbu3sc mby4t 2mc m3ch 4m1d m2dan m2d1a2s md1är mde2a m2dei mde2m m2d1emi m2d1ent mder2 m2d1erl md2ö md3ras md3s2e mdt4 m2d1um 1me me3an me3at meb4 me2ben 3mebr me1c medi3e4 me1e2m mee2n mee4r3ei 2m1eff mega3 me4gel 3meh meh6l3er mehrer4 2m1eif 2m1eig m2ei3l2 mein4da meinde3 meiner6k mei6nerl 3m2einu 3m2eist me3lam me3l4ant me2l1au melb2 mel3d2 melde3i me2lek 2melem me2ler melet4 2melf. 3melk mel4k3ei mell2 3melo me2lob mel2se mel5t4 6mel6tern 2m1e2mis 2m1emp 2m1e2mu m2en. men3ab me3nage me4n3an men3ar me4nas men3au 2m1endl menen1 4men4gag men3ge me2nim men3k4 men2on men4se. men4sem 6mensemb men4sen men4ser men4ses mensi4d men2so menst4 m4enta men4t3ak m4entei ment5eig men6t5ers 2mentn ment4sp me1o 2meou 2meö 2mepa 2m1e2pi 3m4er. me1ra mera3l mer2a3s4 me2r1e2b me4rens mer4err mer4erw 4m3er4gän merin4d merin4t 4mer4klä mern3s2 m4ersh mer5sm mer6stel mer4sto mert4r merz6eng 3mes me2sal me4sä 4meser mes2po mes1pr 2mes4sa mess3an mes6ser6g mes4s1o mes2sp mes2st mes3ta me1sto me3su me3sze me3ta meta1s me3th meto1 me2tö me4trig met6t5en6d me3tu meu1 2m1ex me2xe 1mé 2m1f4 mfi2le 4m1g2 mgang4 mglim2 4m1h2 1mi mi1a mia2b mi2am 2m1iat mi1ä mibi1 mic1e mi1ch mi2ci mi3da mi2di. mi3dr 2midy mie3dr mi3ele mi4e3no mien3s mierer4 mie1s mie2ti mie4to mie2tr mi1f4 3mige mi3h mik1an mi3ke mi4kel mi4kens mi3k4l mi2ku 3mil mi3l2a milch1 mil4che mild4s mi3l2i mi3l2u 4milz m2im2a 2m1imm 2mimp min2ac mi3nak min5anze m2inde minde4s 2m1indu mi2nef miner1 mi4n3e4ri min2eu 2minfo min2ga ming3s 2minh mi3ni mini3k4 mi3nod mi2nof 2m1inse m1inst mi3nu mioni1 mi1p 3mir. 3miri 3mirs 3mirw 3mirz 3mis. mi2sa mi4scha misch3w mi3se1 2m1i2so mis2pa mi2spe mis5sar mis4ser mis4st mis3te mi1sto mi1s4tr 3misu 3mit mi2ta mi2t1h mi2to mi2tr mit3s2 mit5sa mit3ta mit3t2e mitte3s mi2t1u 4mitz mi3v2 2m1j 4m1k4 m3kn 4m1l2 ml3c m3le ml3f ml3k m3lo ml3p ml3s 4m1m mma3a m2m1ak m2m1al m2m1ans mm1anz m2m1ap mm1art mma1st mm1aus mm1äu mmd2 m2m1e2b m2m1ef mm1ein mme2l1a2 mme4lin mm2ene mmen6te. mmen6ten m4mentl m4ments m4mentw mme2r3a mme4rec mmer6geb mme2s mme3sc mme4sz m2m1eu mmi3el mm1inb mm1inh m2m1ins mm1int mm2is mmi3sc mmisch4 mmi1s4t mmi5tw mm3m2 mm3p2 mmpf4 mm2s mm3sa mm3s2i mm3so mm3s2p mm3sta mm3sti mm3te m2mum mm2un mmu3r mmül2 mmüll1 2m3n2 m4nesi 1mo 2m1o2be 3mobi 2mobj 3m2od mo3de mode1s mo2dr m1of mo2fe 3mog 2mog. mo2g1al 3m2oh moh2a moi3r mo2k1l mol3d 3mom mom2e 3m2on mo2nan mo2nä mon4dac mon4del mon2do mond3r mo2ner mon2s3 mon3sa mons4e mon3s4u mont2a mon3th mo1ny 3m2o2o 2mo1pe mo2per 2m1opf 2mopt mo1ra mor2an mor2d3a mor2dr mo2rei mor3g morgen5s6 mor3t2 3mos mo4ska mos3s moster4 mos2ti mo3t2h mo5to mot4r mous4 2m1ox mo1y 1mö möbe2 mö2c 2mö2f 4mök 2m1öl 4m1p mpa3ne mpe2la mpe4lin mpe2n m2p1ene m2pf mpf1ef mp4f3erf mpf3erg mp6fer6ge mpf3erp mp6ferpr mp4f3err mp4f3er4z mp2f3l mpf1or mp2fr mp1haf mp1hos mpin2 m3plä mp3lei m4p3lem. m2p3len m2p3les mp4lis m3pon mpor6tag mpor6ter6 mp3sh mp3str m3pu 2m1q 2m3r4 4m1s m2sam m2san m4sap ms1as m3sat m2sau msau3e m3sä m4s1än m3sc msch2 m4sco m3se m4s1e2d m4s1ef m4seig m4sein m4se2le mse2n m4s1ene m4sent ms1erf ms2erh mse2t m4s1eu m4sex m2s1o2d mso2r ms1ori m2spä m2sped m4spl ms2po m2spot m2spro ms2pu ms3s4 mst2 m6stag m3stä m3steh m3stei m3stel ms2ti m2stit m3s4to m3s4tr ms5trä m3s2tu ms4tü m2sü m4sw m3sy m4szi 4m1t mt1ab mt1ak mta2m mt1ar mt3aug m2t1e2d mt1ein mt1eis mt1elt mt1emi m4tenga m4t3engl m4tentf m4tentg m4t3en4tr m4tents mter2 m2t1erb m4t3erei m2t1erf m2t1erg mt1erh m2t3e2r4i m2t1erk m2t1erl mter4n m2t1ers m2t1ert m2teta m2t1eu m2t1ev m2t1h mt3ho m2t1i2d m2tim m2t1in m2t1i2r mti2s mtmen2 mt1ob mt1op m2t1öl mt1ös m2t3ro m2trö m4ts mt2sa mt3sco mt2s1e mt3send mt3s2ka mt3s4kel mts3tät mt3stu mtt4 mt1um mtu3re m3tü mt3z 1mu mu1a mu3cke mu4ckel 2m1uh mu3la 3muld mul4lau 3mult 3mumi m1ums mum2s1p 3mun mundan4 mun6derf mu2ner2 4m1unf 4m3ungeb mu3ni mu4nin 4mu4niv 4munw 4munz mu4r1u2f 3m4us mu4s1a mu2s1o mu2sp mu2s3t2 4must. must4e mu2su mut1au mut2st 1mü 2müb 3müh mü2her mühl1a mül4len 3mün 3müt mütter3 2m1v mvoll1 2m1w2 mwa2 mwa4r mweg4s mwel4 mwelt3 mwu1 3my my1al my2s3 2m1z2 mzug4 1na 3na. 2n1ab 3naba na2bä naben3s4 n3abh 3nabi n3abk na2b3l na2bor na2br nab4rü 4n3abs2 na2bus 3nac n4ac. na2ch1 nachen6 na5chen. n3achse nach3sp nach8t7ersc nacht8raum n1ada na3dab 3nade na3de. nadel1 na2der 4n1adl 4n3adm n1a2dr 3nae na3el 2n1af na1fra nag2a na3ge. na2gem 4n1agg n1a2gi na3gin na3g4r 3n2ah na2h1a n4ahm 4n3ahn 4n3aho 3nai nai2e n1aig 4n3air nai4re n2ais 2n1ak 3nakä 3nako na2kro 4nakt n2al. na2l1a2 nal3am na4lar na2lä 2n1albk n2ald nal3da nal3ei na4l3ent na6lerei na4ler4g na4lerm na4l3erw nales2 nal1et nal1ex nalg2 na2lid na2lop nal2ph n2als. nal3t nalt2a nal5tr n2alty na2lu 2naly na2mat 3name na3me. 4na2mei n4a3men namens3 4n1a2mer na2mid na2min na3m4n 3n2amo n1amp nam4sp 2n1amt namt4s na4my n1an 4na2n4a na4nat n3a2nä 4n3anb n3and2 nan1eu 4n3anf 4n3ang 4nanh 2nani 4n3ank 4n3anl 3n2ann 4n3anna 4nano nan2o3b 4n3anp 2nanr 4n3ans 2nantr 2nanw n2anz. nanzen4 nan6zene nan6zeng nanzer4 na3ot na2per n1apfe 4napfel n3a2pr n1aq n1ar 5nar. na2r1a 2narc n2ard n2are n4are. 3nari n2ark n2arle 2narm n2aro na2rom n2arr n2ars 2nart n2arta n2arth na3r2u 3nas n4as. na3sä na4schw 4n1a4sp nas2s1c 4n1assi nas4ta na2str 4na2sy nasyl2 3nat n4at. na4t3au nat1ei na2tem na2t2h 4natm nat2o 4natom 5nator nat1r nat4sa nats1e na3tu n1au nauf4fr nau2fr 5naui 3n2aul 4nausb 4nausd 4nausf 4nausg 4nausl n2auso 4nausr 4n3auss 4nausw 4nausz 3nav nave4 navi5er. navi5ers 1nä 2näb 3n4äc 3näe 2n1äf 3näg nä2hi 3nähm 2n1ähn nä2hu 2n1ä2m 2n1än 4näpfel 2näq när4s5t nä2sc n2äss 2näu 3nä1um 2n3b4 nbais4 nbe2in nber2e nbes4 nby4 2n1c n2c3ab n3can n3ce4n n3ces. n3chl nch3m n2ck ncor2 n3cr n3cu 4n1d nda1f nd2ag n3dai n2d1ak n2dana n2dani n2danz nd1arr n3dat nd3att nd1au n2daut n2dax nd1äng nd1c nde4al. n2d1ede n3dee n2dei nd3elfe ndel3l ndel4s3a ndel6s5en ndel7ster nde4mot nden3sk n4dentl n4dents nde3o2 n5der. n5deren nd2erh n5deri nder6läs nde4rob n4de4ros n6der6sat nder5ste n3d2es1 nde2se ndes3s ndi2a3 nd1imm ndo1c n2dof ndo2n3a n2dopt nd1or n2do2ri nd2os ndo1st n2d3ott n2dö nd2ös nd4ram n2d3rat nd3rau n2d3re n2drif n2d3roc n2drod n2d3rö n2drui n2d3run nd4sene nd2spr nd3th ndt4r n2duns ndwa5re ndy3 1ne 3ne. ne2ap 3neas ne3at ne3au 4n3ebene ne2bl 2n1ebn neb4r 2nec 3neca 3nece ne2ch ne1ck neck2a ne2dit 2nee neei2 ne3ein ne3eis neen2 nee1r neer2e n1ef n2ef. n2e3f2a 2nefr 2n1egg neg4l n1e2go neg4r n1ehe 2ne2he. 2nehem 2nehen2 nehe2r 3nehm 4n3ehr 2n1ei 3neia 4neic nei4dei nei4dr 4neier 3neigt 3neigu nei4la 4neing 4neinh 4neink 4neinl 4neinz 4neip neiss4 ne2ke 2n1eks nek3t2 2nekz ne2la nel3b n1e2le 4nelek 4nelem ne3len ne3lex nel2i ne3lid ne2lit 3nelk n2ell nel2l1a nel4lei neller6f 3ne3l2o 3nelu 3n2em. 4n1emb 4n3emp 2n1ems 4nemu 3nen n4en. n2en3a nen4am ne4nan ne2nä n2enb n2enc nen4dar 4n1endb 4n1endd 4n1endf n1endg 4n1endh 4n1endk n1endl 4n1endp 4n1endt 4n1endw nene2b nen3ei nene4m nenen1 ne4nene nen3erb ne2n3eu n2enf 4n1engb nen4gen 4n1engs 4n1engt n1engu n2enh ne4n3i n2enj n2enk2 n2enm nen4nar ne2no4 nen3s4e nen3sk nen3s2p 5n2en3t2a 4n1entb 4nentd 4nentf 5n2enti 4n1entl 4nentn 5nentr 4n1ents 4n3entw 4nentz ne4n3u n2env n2enw nenz4er ne2o3b ne2oh ne2or neos4 ne2pen 2nepf 2ne2pi 2nepo ne2pos nept4 n4er. ne1ra ne2rab ne2rac ne2r3af ne2rag ne3r4al ne2ram ne2ran ne2r3ap n2erat ne6ratio ne3rato ne2rau n2erb2a 4n3erbe. 4n3erben 2nerdb ner4dig nere2 ne2r1eb ne2rec n1erf 4nerfas 3nerfr 2nerfü 2ner3g4 3nergr n1erh 4n3erhö 3neri n2erj n1erk 5nerka n2erkö n2erli 2n1erlö n1ermi 2n1ernä 4n3erneu 2n1ernt n1eros n1eröf ne1rös n2ers. 2n1ersa 3nerse ner4sk 4n3ersts nert4 3nert. ne2rup 3n2erv 4nerwar 2n1erz n2es. ne2sal nes2an n4ese ne2sei ne2s1ev 2ne3sh ne3si ne3ska ne2s1of ne2s1or ne2s1pa 4n1es2si nes4sig ne1sta ne2ste nes3ti 2n1est3r 4nesyn 3neß ne2tab 2ne4tag net1ak ne2t1an 2ne2tap 2ne2tat ne4te2l ne2th net3ha ne3ti ne4tin ne4tob n2ett net3ta net3te net3tr 2n1e2tu net4zer net2z1i ne2u neu1c neu4ere neuer4f neuer4k neuer4r neuer4s neuer4w neu3g4 2n1eup neur2 neu2ra neu3t 3n2evi n2ew ne3wa 2n1ex ne2xi 5ney 3nez 3né 2n1f n3f2al nfalt4 n3f2ang nf4ar n3f2ä nfe2i n3f2en n3f2er nf2es n4fex nff4 n3fi nfi4le. nf4le nf2o nfo1s nf4r nf3s2 nf2tan nf2t3r nft4st nfts3tr nf3tu n2f1u 4n1g n3gabe ng1abt n2g1a2c n2g1ad n2g1ak ng1a2me ng3anda n2ganh n4ganl ng1ans ng1ant ng1are n3g2ars n2g1a2v n2g1äl ng3d n2g1eif n2g1ein ngelb4 nge3l4ei ngelt2 n3g4en n5gene nge5nerw ngen3sa nge4ram n2g1erg nger4zä n3g4es nge3sa nge5t ngg3s ng3hu n2g1id ng2lad ng2läs n2glic ng4lok n3glot n2gn ng3ne n4g3ni ng4nom ng2nu ng2ob n2g1op n2g1or ngo2ri n2gö n2g3rai ng4ran n2g3rat ng3roc ng3rost ng4s3au ng4scr ng4s3e4h ng4sek ng4sens ng4spar ngs5tan ngs4teu n4gt ng3ts n2gum ngung4 ngzei4t 4n3h2 nhe2r 1ni 3n2ia ni3alo ni2ar nibb4 nic4 ni1ce n1id 3n2id. ni3da ni2de 2nidea ni3d4r 2n3idy n2ie nie3b ni1el nie3l2a nie4n3 ni3ene ni3eni nie4rei ni4erna nie2sa ni2eu nife4s3 ni1fl niga2 ni2g1ab ni2g1am ni2g1an 4n3i2gel n4igen 2niget ni4gl nig3li ni2gn nig4sp nihi3 ni2kar 3nike ni2kel ni3kerh ni2ki nik3ing ni2kor ni2k3r nik3t4 3n2il ni3l2a ni3l2i 4nimp nin1 3nin. 3n2ina nin2ac ni2nal 3n2inb 2n1ind 2ninf 3n2ing ning4s 2n1inh 4n1ink2 3nino ni2nor 3n2inp 2n1ins 4ninse 4ninsu 4n1int ni3nu 4n1inv 3n2inw ni2ob ni3ok ni3ora n2ip ni4ron n1irr 3n2is ni4sam ni2san ni2sä nis3cha ni4schw ni2s1e 4n3isol ni2som 4nisot ni2sp ni3spi nis3s4 nis3tha ni2s1u 2nit 3nita ni2ti 4ni4tia nit2o 3nitr nit3s nit6ter6g nit6t5er6k nit4tra nitt4sa 3niu ni3v2 3nix 2n1j 4n1k nk1abr n2k1ac nka2ge n3kal n4kalg nk1ang nk1apf nk3art. nka3sc n2katm n2kato nk1aus n2kaut n2k1äh n2k1äp nke2c nk1ei nk2eil nke4lei n4kelem nke4na nken4te n4k3erle nke4ros nk3ersa n3kesc nke2t nk1eti n2ketu nk1i2d n2kide nk1inh n2k1ins n4klade n3klag nk3leis n2k3len nk3les n3klin nk2lo nk4neb n2knis n2knit n2knu n2k1o4be n2kopt nko2r nkord2 nk1ori n2k1ort n2köl nk4rab nk3rät n4kre. n2k3rel n2kren nk3rep n2krez nk3ro n2krol nk2sal nk2se nk3sen nk2so nks2ti nk3s2z nk2tak nk2tan nk4tau nk4tent nk4terg nk4t3ern nkte3sk nkt2et nk2tin nkt1it nk2top nkt1r nkt3ric nk2tro nk2tru nkt4sen n2k1um nku2n nk1urh n2küb 2n3l2 nla3ge nle2ga 2n1m2 n3ma n3mä nmen2s n5mi 4n1n n2nada nna2g n2nalg n2n1all nna3m n2nan nna3st n2nau n3nec nn2ei. n3nelb nne4le nne4na nn2ens nner4ei n6n5ereig nner4fü nner6geb nn4ergr nn2erh nn2erk nner4la nn2ero nne2rö nn3erwa nner6war nner2z nne4s1e nn2eu nn2ex nn3f nng4 n3ni nnk2 nn2o3b nn3obl nn3obs n2nof n2nop nno2r nn1ori nn4sam nn3ser nn3s2p nnst4 nn4stoc nn2stö nn5t2a nn2th n2n1uf n2n1unf nn1ur nnvoll4 nnvol5le 1no 3no. no5at 3n2oba n2obel 2nobj no2bla n2oble 3noblo 3noblö 2n1ob2s nobu2 nobut3 3noby no1c noche4 noch4r 2nod no2de no2ed n1of no2fe 2noff 2n1oh 3n2ohe no2kel 2n3okk no3kr n3ole no2leu no4lig no2liv 2n3o2ly 3no3me3 no3mi 3nomp non2e n1onk nons4 n1ont 2nony no2o 3n2opa 3nopä no2per 2n1o2pi 2n1ops no3p2te 3nor. nor2a no2rad n2o3rak no3ral no3rar 2norc nor4da 3nordb nor4des nor2d3r no3r2e 2n1org 3norh 3n2orl 3norm norm2a nor3mal 3norö 3nors 2n1ort 3n2os. nos2e1 no3sh no5s2k no2s3p 2no2sti nost1r 2nostv nos2u no2tan no3tart no2tä no4t1e2i no6t5entr no4ter2 noterb3 no4tex not1h no2tho no2t3in no2t3op no2t3r 3nov 2n1o2x 3noz 2nöd 4nö2f 4n1ök 4n1öl n2ör 1n2öt 4n3p4 npa2ge npa2s npf4 npro1 npsy3 2n1q 6n3r2 nran2 nrau4ma nräu3s nrebe2 nreli1 nre3s4z nro2h nrö2s nrücker6 4n1s n3sabo n2s1a2d n2s1a2gi nsa2kr n2sall ns4alp n2salt ns4anat ns3ane n2sanm nsa2r ns2arg n3sark nsa2s ns4ath nsau4r nsau2s n2saut ns2av ns2ax n2s1än ns2äug n2s1äus n3sche. n4schef nsch5eul n4schl. nsch2o nscht4 n3schu nsch7werd ns2cr ns1eb nse4ein ns2eh nse2ha2 nseh5ere n4seinf ns2ele ns3elem n2sem. n2sene nsen4sp n2sepo n2s1erf n2s1erg n2serh n2s1erk ns4erko ns1erl n4serle n4s3erne n2serö ns1ers n4sersc ns3ertr n2s1erw n2serz n2sety n2s1eu ns2ext nsfi2l ns3iden n3sim n4simp ns2inf n2sini nsinn2 nsinns3 n3sis n4siso nsi4te nsi2tr n3s2kal n3s2kel ns2kis n3skle n3s2ky n5smara n2s1o2d ns1of n4soff ns4om n4s3ont n2s1op n4s3ort. ns2pac nspa2g ns4pek ns2pel n5s4pen n4speri n2sph n3s2pi ns4pie ns4pir n2spo n2sprä n4s3prie n2spro n2sput nsrü2 ns3s4 ns3tabl n3stad ns8tagent nst1ak n4stale ns4ta2n1 n3stand nst3ane n3s4tar n2stas n4stat. n6staten ns4tati n4stats n3stäm n3s4tän nst5eife nst7einhe ns4tent ns2tep nst5erge n5s6terne n5s6terns ns4teu ns2ti n3s4tic n3stif n4stilg n3stim n2stob nst5opfe ns4tor n4strie n4strik ns4trip ns4trun ns2tu nst3u4t ns4tüm n3suf ns2um ns1un ns2ung ns4unk ns2unw ns4unz ns1urs n2s1ut n3sy ns4zene 2n1t n3t2a3c ntak4ta ntal1a nta4lin n4t1all nta2lo nt2alp n3ta3m n3t2anb nta3ne n4tansp nt1ant n4tanza n3t2arb nt1ark n3t2arm nt1art ntar6tik nt3artu n2t1ass n2tath n3tatl nt1äm n2t1äu nte3au nte1e nte3g6 nt1eh n3tehe n2teig nt1ein n2t1eis nte4lin n2t1emo nt4en nte4na nten6te. ntera2 nte6r5eis nt4erh nt4erk nt4erm nt4ern ntern4e nt4ers nt4ert nte3sa n4t1es4s nte2st n6testri n2te4ta nteu3 nteu6eri nte3v nt1hel nt1hie n2thot n3thr nt4hu n2t5hum nt4hy n3t2i nti3c ntim3p n4t3ind n4t3inf n4t3inh ntini1 n5t2lem ntmen2 ntmo4 ntni2 ntnis1 nto3re n4torg n4t3o4rie n2t1öl nt4ral nt1rau nt4raum nt3rea nt3rec n5t4ree nt3reif n5trep nt4repr nt3rich n4t3rieg n2troh n3trop n4tropi n2t3rü n4ts nts2ah nt3s2p nts3par nt5spe nts2t nt2sur ntt2 n3tub ntu4re. ntu1s n3tü nt3z 1nu 3nu1a nu4ale nu3a2r3 nubi1 2nu1c 3nud nude2 3nue nu2es nu2fe 3nug 2n1uh 3nuhi 3nui n2uk4 nu3kl n3u2kr null1a nulle2 null3eb n2um. 2n3umb n2ume 2numf 4numg 2numl 3n2umm 4numr 2n1ums 2n1umv 2n3umz nu4n 4nuna 2n1une 3n2ung4 4n3ungl 4n1uni n3unk 2nunr nun3s 4nunt 4nunv 3nunz 3nuo 2nup 2nu2r nur2i nur3s nur2z 3nu2s nu3sc nu3se nus1p nu3spo nuss3er4 nus6serl 3nut nu2t1a n3uto nu4top nu4t3r 3nuu 3nux 3nuz 3nü. 2nü4b nür1c 3nüs 1nüt 2n1v2 n3ver n3vl nvoran4 2n3w 1ny. 2n1ya n2ya. 1nyh n1yo 1nyr 1nys 1nyw 4n1z n2zac n2z1a2g n2z3a2k n2zan nz3a4ne n3zani n2zar nza2s n2zat n2z1au n2zän n2zär nze4la nzel6lig n6zenerg n3zeni n4zense n4zentl n4zents nz3erem n2z1erh nz1erl nzer4lö n5z4err nz5erste nzer6tra n3z4es nze3sk nze2t nz1eta nze3u4t n2z1id nzi2ga n2zinh n2z1ini nz1int nz1inv nz3le n2z1op n2zöl nz3st nzt4r n2z1wa n2z1wä n2zwet n2zwir n2zwö n2z1wu ño1 ñor2 2o3a2 o4a3bi o4ac oa3che oa3chi o4ad oa3de oad4st oa3in o4a3ke oa4k5l o4a3la o4a3mi oa4n oan4a o4a3q o2a4r o2as 3oa3se o5ass o4at oa4tr o5au 2o1ä o1b 2ob. o3b2al ob2am ob2ar ob1auf 2o3b2ä 2obb ob2e 2obe. 2obea 2o3bec 2obef o2b3ein 2oben obe4na oben3d4 1o2ber 2o3ber. ober5eis ober3in oberin6g obe4ris 2obev 2obez 2o3b2i 3obj ob1la ob3lei 1ob3li 2oblo2 2ob2lö ob2lu 2obo ob1or 2obö ob3rei 2obrü o4bs ob3s2h ob3sk obs2p ob3sz 2o3bu o4bunt obu2s 2o3bü o4büb 2oby oby4t 2oc o3ca oc1c 3occl o1ce och1a ocha2b ocha2r o1che oche4b o2ch1e4c och1eh och1ei oche2l ocher4k ochi4d och3l och3m och1o ochö2f och3r och1s ocht4 o1chu ochu2f och3u4t och1w o1ci o1c4k o2ckar o2ckau o3cke o6ck5er6sc o3cki ock3sz ock3ta o1cl o3cu o1ç o1d 2od2a od3ak od2dr o3dec o3d2e3i odein3 ode4l3ag ode4man ode2n1 o3der ode2s1e ode3sp od2et o3dex od2i 2o3dia 2odi3c 2odif 2o3dir 2odn od2o o2don o2d3op odo4s od2ö 2odr o2dre odt4 2o3du o3dy ody2m 2o1e2 oe3di oe4m oen1e oe3ri o2e3s oe4sc o2e3t2 o3et. o3ets 2ofa ofa2c of1a2d of1a2g of2an of1au 2ofä o2f1e2b o2f1ec 2ofee o2f1ei 2ofem o2fent 2o3fer o4ferb 2o3f2es o2f1e2t 2ofeu of3eun of2f1a off3erz of2f1in 1offiz of2f3l of2f1o of2f3r offs2 off3sh off3si off3sp of2fu 2ofi ofi3e2i ofi3k4l ofi3s4 2o1fl of3le of3li of4lö 2ofo 2ofö 2o1fr of3rä of4rü of2s1 of4sam of3sä ofs2ch of4sen of3sta of4staf of3str 2oft oft2a of2tei of3th oft4r 2ofu of3ur 2o1g o2g1ab o2g1ac oga3d og1ang og1ans o2g1e2i oge2li ogener4 ogerätein8 o2g1eth og2gl o3gh ogi2er ogin1 o2g1ini og3ins og1l og3le og2lo o3g4n og1o2ri ogs2 og3sp og1ste og3sti 2o1ha oh1alk o1hä o1he o3he. oh1eis o3hem o3hen. ohen3s o3her. o3here oh1er4t oh1er2z o3hes 2o1hi 2ohl ohl1a oh2la2d oh2lä oh3lec ohl1ei oh3lep ohler2 oh4lerg oh4l3erh oh4lerw oh3lo ohl1o2r ohls2e oh2lu 1ohmi ohn1a oh4nac oh3nee oh2ni 1ohnm oh2n1o ohn3sk 2o1ho oho2l1e ohol1o oh1o2p 2ohö oh3öl ohr3a oh2rel oh2rem ohren3s ohrer2 oh4rerg oh3ri oh4rin oh2rol ohr5t4r oh1s oh3sa oh3t o1hu oh1w 2o1hy 2oi o1id. o3i2da o1ids o3ie o1i2m o1in o4ine oi2r o3isch. o4ische o1ism oiss2 oi1th o1i4tu 2o1j ojek8tori 2o1k ok2a oka3b2 o2k3ac oka3i oka2la okale2 oka6lere okas4t ok2e oki4o ok2la ok3lau ok1lä ok2li ok2o oko4pt ok2so ok2s1p ok5t2 3okw 2ol o1la ol3abu olaf4 o2l1a2m ol1ant ol2ar olar3s2 o3l2as olast4 ol1a2v 4o1lä ol1ät ol2chr ol4d1am ol2dä ol2d1ed ol4d3eng old5ersa olde2s ol2deu ol2dim ol2d3o ol2dr 4o3le. o2l1ef ol1eie o2l1eis ol1emb oler2 ol1erk ol1er3t ole3s ol1ess ole2st ole4sti ole3u2 ol1exz ol2fa ol2fem olf3ere ol2f3l olf1r ol2f3ra olft4 olgege3 olge4ne ol2gl ol2gr ol2i olie4n1 oli2er oli3k4 oli5tu 3oliv ol3ke ol2kl ol2k3re ol2kro olks3 olk4sc olk4si ol2l1ac ol2l1ad ol2l1ak oll3am ol4lang ol2l1au ol2l1e2b ol4l1e2c ol2l1ei ol2lel ol4l3erh ol4ler4k oll3erl ol4l3erw ol4l3ess ol2lop oll3s2a oll3sp 4olo ol2of olo1p ol1ort ol2ov ol3s2k ol4ster ol3t2h o1lu olu2th ol2y 4o3lys ol2z1a2 ol3zan ol4z3ern ol2zim ol2zo ol2zw ol2zy 2om o2mab oma2bl o2m1a2ge om1alg om1all oma4n3er o2m1ang om2anr om3ansc o4mante o2m1ap o2m1ar4s o2m1art omar4te o4ma2sy omat2i o4matom o2m1au o2meb om1ebe o2m1ef o2m1ei o2mel o3meld omen5t6an o4mep omer2 om1erh o2meru om1erz omi2c3 omiet1 o3mig om1ind om1ing om1ins o2m1int om3ma omm2e 3o4mn 4omo o2m3oa o2m1org om1o2ri om3pf oms2 om3sk om3t2 o2mum o4munt 2ona on3a2b on2ac ona3g o3nal on3ann onan6z5ei o2n1ap o2n3arb ona3th 4onatol onat2s o4n3at4t on2au 2onä on1äh 2onc on2dan onde8rers onderer7t ond1r on2dra on4drin ond3sk 2one on1ec one2ck o3nee o2nef o3neig on3ein on1ema one2n1 o4n3ends on2eng onen3s2 on1ep o3ner. on1erb o2n1erd oner4fa o2nerh on4erka on1ers o3nes o3nett on2eu on3f2 on3gl ong4le ong4r ong3s2 on2gue 4o3ni on2i3d onie3g oni2ga on4ik o4nikr o4nim o4nind o4ninh o4nins on3k4 3onke onli4 onlo2c onna2 on3n2an on3n2e 2ono1 o3nod o2nof ono2i o2n3oke o3nom on1orc on3ord ono3s ono3t2 onrad3 ons1a on4sam on2seb onsen1 onse4t onsi2d ons3ing ons3l ons1p on4spin onst2a onst4r ons5tri on3ta on2t1eb on2te2l ont5end on4t3erl on2th on4t3rat 2onuk o3nur 2onut on3v 1ony o3ny. on3z2 onze3in o1ñ oo1c ooch2 oo2gl oo2k3l oo2kn oo2mo oo2ne o1op oop2s o1or oor3d oo4sk oos3s4 oo2su oo2t1a oo4t1ei oo2t1h oo2tr oot2st oot3t oo2tur 2o1ö2 2op. o1pa op3adr op1akt opa2le op1ang opa5s opa3s4t 2opä 1ope o1pec 2o1ped op1ef 2o1pei o1pek 2opel 2open 2opep o2pera op1erh o1pes 2opf. op2f3a op3fah op2fä o2pfe op2fem op2fin opf3la op1flü op2fo 4oph2 o3phe o1pi opi5a4 opi3er. opi5ers. opie4r3u opin2 2opl op3lag o2p5le o3p2n 2opo opo2la op2pan op4pl 1oppo op2p3r 2oppt 2o1pr 3o4psi op3sz 1opt4 2opte op3th o2pum 2opy 2o1q 2or. or1a 2ora. o1raa 2or3a2b o2rabb o2r3add or3adr o1r2ag o2rak 1orake o1ral o4r3alm or4alt or2am or3a2mi o1ran3d or4ane oran2f oran2m oran4ze or3ap 2orar o1r2as o2ratt 2orau4 oraus6wa or2av 2o1raw o1ray o3rä or1änd or1ät orb2l or1c 2orca or2ce 2ord. 4orda ord1am or2dar or2dau 2ordb ord3eng orde4s or2deu or4d3ing or2d1ir or2dit 1ordn or2do2 2ordr ord3s2t ord3t 2ordu 2ordw 2ore ore2a o2r1e2b o2r1e2ck ore2di o5ree o3ref or1eff ore2h or1ei o3rei. o3reie o3r2eif o3r2eis oreli1 orems2 o3renn o3rep o2r1er o3r2ere o3r2ero ore4th o2r1eu 2orf or2fac or2far org4a org2e 2orget or3ghi 2orgia or2gl or3gla or3gle or2gn or3gne 2orgr 2orh 2o3ria 2o3r2id orid3i 4o3rie. o3rien. o6rienti o3rier o3ril or1ima ori4mi 2o3rin1 o4r1ind o4rins 2or4io o2riso 2orit 2ork ork4r ork2s ork3sh 2orm or2mam or4mang or4mans orm3asp or2m1eb or4m3erf or4m3er4g or2mor orm3ord or2mum ormu4n or4muni or4munt ormwa5 or2n1a2c or2nal or2nan or2nar or5ne. or3ni or4nin or3no1 2o1ro o2r1ob or3oly oro3n2a or1opf o2ro2r o3rou or1ox 2o1rö 2orp 2orq 2orr orr4a or3r2e 2ors2 or3s4a or3sh or3si or3sk ors4tin or3sz or2t1ak or2t1an orta2r or2tef orte4n or4ten5g ort3erb or4t3ere ort3erf ort3erg or4terk or4t3erl orter6sc or2t3e2v or2the or2tin or4t3off or4t1o2r or2tö ort3rad or4trau or4t3räu ort3re or2t1um 2o3ru or2uf or1uh orum4s o4r3un oru2r o5rus o2rü or3z2e orzel5 or2zw 2o3s2a os3ad osal2 o4s3ami osa1s 2osc o4s3ca osch3ar o3sche osch3le os4co 2ose ose1e ose1in2 os2el ose2n o2s1er2k os2ex 2osh o3s2hi os2ho os4hu 2osi os4it o3sk os2kal o4ski 2os2kl 2os2ko o4skr o4sky 1osm os4mog 2oso osol1 o2sö 2os1p os2pac os2pe os3pec os3pero o3sphä o3s2po os4pot os2pra 2oss os2sa os6s3a2c os3sag oss3ala oss3and os4sä os2sei oss5enke os4s3enz os2s1ep os4s3er4b osser4e os4ser4f os4sik os4sim os2s1o2 os4son os2sp oss1pa os2s3t ost1a ost3ang os5tarr ost4art os4tat ost3aut os4tä oste2c oste2n oster3e ost5erwe oster8wei ostes5s os4teu ost3eur os2t1h os2tid os3til os4tim os2tin os3tina os2tit os3toc os4tor ost3ran ost3rä ost3re ost3rot ost3uf os2tug os4tüc 2osu4 os1um 2o3sy o3s4ze 2oß o2ß1el o2ß1ent o2ß1en2z oßer2 o2ß1erb o2ß1ere o2ß1erf oß1is 2o1t o3tabe o2t3abi o2t1ah o2t1ak o3tal o3tam ot1ant o3tark o2tarz ota2s ot1ast o2t1au o3tau. ot1ä o3te o4teb ote1i o4t1eib o4t1eic otei4n o4t1eis ot2el ote4l1a ote4lin otel3s2 o4t1emi ot2em3p2 ote4na o4tentb ot1erb o4t1er2l o4t1erw ot2e2s ot2har o2them o2t1hi o2thr 4oti o2til o2t1i2m ot2in ot3inh otli4 ot2o oto3b4 ot3off oto2ph o2t1ö otra3c o3t4ran ot3rat ot4rau ot3re ot3ric ot4rig ot3rin ot3rus ot2s3at ot3sch ots2en ots1o ots1p ots2pe ot2spr ots3tau ot3sti ot3stra ot2su ott1a ot4tan ot4ta2s ot2teb ot4terh ot4ter4k otte2s ot2t1h ot2tim ott2o ot2t3r ot3t4ra ot4tri ot3t4ru ot1url o3tü ouff6 ou1f4l oug2 ou4ge ou3gl o1uh ou1is. 2oul ou2le. ou2les ou4li 2o1um 2o2u2n oun4ge. 4our oure2 ou2ret ouri4 ourie4 ourme4 our4ne. ou3sa ous2i ou3ti 3outp out3s2 ou3tu4 2o1ü o1v ov2a 2ovel o3ven ove3s oviso3 2ovo 2o1w o2w3al o3wec o2wh o3wi o2wu 2ox. o1x2a 2oxe o2x1el 2oxk ox3l o1xo o2x1u 1o2xy o1yo oy1s2 o1z2 o3za 1ozea 2o3zen ozen4ta ozes4sc 4o3zi ozir3 ozon1a 2ozy oz3z ór3 órd2 ö1b ö3b4a öb2l ö2b3le ö2b3r öb2s3 ö1c öch1l ö2chr öch2s öch4ste öchst5ei öchst3r öchs4tu ö3cke ö1d ödel3l öde1r ödi3 ödien3 öd2st 1ödu ö1e 1öf öf2fl öf3l ö1g öge3le ögen2s1 ö2g3l ö2g3r ö1he öhe4n1 öhl2e4 öhre4 öh3ri ö1hu ö3ig. ö3isch. ö1ke 1ö2k2o3 ök3r ök2s ö2l 3öl. öl1a2 öl1ei öl1em öl4en öl2f1ei ölf2er öl1in ölk4e öl2k3l ölks4 öll1a öl3le 3ölm öl2nar öl1o2 öls2 öl3sa öl3sz öl3tu 1ölu ölz2w ö1m öm2s ön2e ö3ni önizi1 önn2e ön2s ön3sc ön3sp öo1 öo2ta öoti1 2öp ö1pe öpf3l öp4s3t ör3a2 ör2b3l ör1c ör2dr ör3dra ö2r1ec ö2r1ei ö2r1e2l ö2r1e2m öre2n ö2r1ene ö2rent ö3r2erb ö2r1er2e ö2rer2f ö2rer2g ör2erh ö2rer2l ör2err ör2erw ö3r2erz ör1ess ör2f3l ör2gl ö2rim ör2kl örn2e örner4v ör1o örpe2 örs2e ör3sk ört2e ör5tri öru4 ö2r1une ö2sa 2ösc ö2sch3a ösche2 ö4sch3ei öscher4 ö6sch5erf ö6sch5eri ö2schi ö2sch1l ö2sch3m ö2schn ö2schw ös1ei ö2sein öse3str ö3set 2ösl ö2sp ös2s1c ös2st ö2st öst1a2 ös3te ös2th ös3tr ö3su ö1ß ößen3 öß2ti ö1t ö4t3a öte4n1 ö2t3r öts2 öt2sc öt2tr ö1v2 ö1w ö1z öze3 özes4 1pa. 1paa p1ab p2abe pab2l pab4rü 2pabw 1pac 1p2ad pae2 pa3el pa2es pa1fr 1pag4 pa3gh pa1ho 1pak pa3ke pa1kl pak4to 3pala pala3t 3palä 3pal2e pa3l2i 1palm pal2ma pal2mä pal2m1o 2palt pal2t1a pal4tei pal2tr pa2m3a pa2nar pa4n3at pan3d pand2a pan4ds pa2neu panf4 pang4 pa4nisl pank4 2panl 2pann panne2 pan4n3eb 4pannu 1pa2no pan3sl pan3t2h 1panto 2pantr panz2 pan3ze 1pap papi2 papieren8 papie8r7end pap2pr pap4s papst1 pa1q 1para pa4r3aff par3akt pa4rant pa3rap pa2rä 2parb 1p2arc par3d parer8geb 1parf 2parfö pargel6d 1park. park3am par4kau par4kr 1parks par3m2 par3ne 1pa2ro 2parp 2parr 4parta 3partei 1parti 1partn 3party par3z pas2e pa3sp pa4spe passer4 pas6serg pas2s1p pa4st 2paß pat1a pat4c pa5t4e2 2patel 1pat2h 1pati 1pa5t4r 1pau 2p1auf pa3uni 2pausz 1pav 1pä 3pä2c pä3cke pä4ck3er 3päd päde2 pä2d1er 3pär 3päs pä4t1e2h pä4tent pä4tep pä4t3erb pä2t1h pä2to pä4tr pät3s4 2p1b 2p3c 2p1d2 pda4 1pe. pe2a2 pea4r p1e2b pech1 1peda 1peel pe2en 2pef 4p1eff 1peg pege2l pei1 4peic 1peil p2eim 2peis 1peit pekt2i 1p4el 3pel. pe4l3ab pe4lai pe2l1au pe2l3ax pe2l1ä pelb2 pel3d4 3pele pe4l1e2h pe2l1er pe2let pe2leu peli2d peli4n pe4l3ink pel3inn pel4ins pel3k pel3l2a pell4e pell2i pe2lob 3pels2 pel3sp pel3t2a pel4zin 1pem 1pen pena2r pe4nas pe2nä pen3d2a pe4nen1 pe4ni2t pe2n1o pens2a 3pen3si pen3s2o3 pens2p pen3sz pent2a 2pentw penty2 penu2 pen3z 1pep pe3pi pe1ra pe2rak per2am pe2rau pe2r1ä per1e2b perer2 perer3z pe3r2id 3pe3r4io 1perle 1perlh per4r3an 1pers 2perse 2persi 3perso 3persp peru2 pe3run 1perü perwa4r pe3s2a pese2n 1pes5s2 pe2st pes4ter pest1o 3pet pet4r 1pé 4pf. p2f1ab p2fad p2faf pf1ai p2f1ak pf1am pf1ans p2fa2r pf3are p2f1au 1pfä p2fär p2f1äu 4pfe. p2fef p2fei pf1eim pf1ein pf1e2m p3fen. p4fener p3fens p3fent p4f1ep pfer5a p4ferde pfer6pro pf4es p2f1et pff4 p2f1i2d pf1inn p2f1in3s pfi2s pf1lam pf4lan pf4leg pf3lei pf3lo pfo2 p2fob p2fom p2for pf1ori pf3r pf1ra pf4rü 2pfs2 pf3sa pf3se pf3sl pfs4ti pf3sz 2pf3t2 pft4r p2fum 2p3g2 pgra2 1ph 4ph. ph2a phal4te4 p1hand 3pha1s p1hau phä1 3phän 4phär 4phb 2phd 2p1hei phen3d2 phe4n1e phen3s2 2ph1ers 4phf 4phg p2hid phik1a phi4kan 2phk ph2l 4phm 2phn p2ho. p2hob 2phö ph2r 4phs ph3t2 2phthe phu4s phu3t 2p1hü 3p2hy 4phz p2i2a1 piab4 pia3k pi4ali pia3n piap2 pi1ce pid2 pi2e1i pi2el piel3a 3pier pie2ra pie4reb pie4rei pi3gl 1pil pi3le 3pilo pil4zer pil2zw p2im 3pin. pi2nad 3ping pingen4 ping3s 3pins. 3pinse pin3s2p pi2o pi3oide pi3onu pi3os 1pip pi2pe 3pirate pi3ri 3pirin 1pis 2piso pit2a pi3t2h pit2s pit3z2e pi2z1in 2p1j 2p1k2 pku2 1p2l2 2pl. 3pla 4p3lad p1lah pla3na p4lau pla2y1 2p3le. ple1c ple2e p4leg ple3n2 2p3ler p4leu 2plig 3p4lik p4liz plo3n 2p3lu plu2s 2p3m2 2p1n2 1p2o pob2 2po1c 3pock 3pod 3poe po2el 2poh po2i po3id. po3ids 3poin 3pol po2lan po2l1au pold2e po3li po3lo3p pol3z2 pom2ph 2pond pont2 po1ob po2p1ak po2p1ar po2p3l po3p2t po1rau porf4 por3s 3portal por2t1h 3portio 3porto. 3portos 3portr por4tre 3posi poss2 po2sta pos4tag po2stä post3ei pos3tel pos4tem pos4tr post3ra po2ta pot1ar 3potä 3pote pot2h po2t3in pott1r po2t1u po3un po2w powe2 po3x pö2bl pö2c 4p1p p2pab pp1ans p2pat pp1au ppe3e p2p1ei ppe2l1a ppeli5ne ppel3s pp2e2n1 p2p1erz p2pf4 pp1fr p2p1h pp3he pp3l p4p1lac p4plan p2p1lä p2ple pp3oh p2p1ö4 pp3p4 p2p3ra p2p5rä p2pri pp3rol pp3rot p2p3ru p4ps pp3s4a pps2p pp3sy ppt4 p4p1um ppyl2 p2r4 1prak 1prax p4rä 1präd 1präf 1präg 1präl 3präm 1präp 3präs 1präv 2pre. 2prec 3pred 2pree1 pre2ei 2preg 1prei 3preis prei4s3c prei6sei prei4s5t 2preiz 1prem pren4ga 2p3rer 1pres pre3sa press4e pri4e 2prig pri2l1 2pring prings4 1prinz pri2t1 priter4 prit5t4 2pritz 1priv 1pro 3prob pro3be 2proc 7p4rod 3p4rog 3proj 4pross pro1st prot2e 3proto 2prott pro3x 2prö 1prüf 1prüg 2prüh 2prün 2p1s 4ps. ps1ad ps2hi ps1od p2sö ps4pi pss4 p2st p3sta pst1au p3stä p3stea p3stel ps2th p3s2ti ps4to p3stö ps2tu p3stü 3p2sy 4psys ps2ze 2p1t pt1a pt2ab pta2g p2t3a4t p2t1e2b pt3ec pt1ef pt1ei pt1emi 4pten p4t1en2g p4t1ent pt1ep pt3erei pt1erw pt1erz p3tet p4teta p4t1e2ti p2t1h pt1id pti2de pt1in1 pto2mo pto4na pto2p pto2w pt3r p2tro pt3s2 pt4sl pts4t pt1uh pt1um pt1urs ptü4 3p2ty pt3z2 1pu pu1a pub4 2puc pu2dr 2p1uh 2puk pu2kl pu2k1o pu2lin pul2sp pul2st 2pulw pum2pl 3pun 4pund pun2e pun2s 4punt 2pur pu2ra pu2rei pus2h pu3she pu2s3t pu5t2e 3put2s 3putz puzi3 1püf 2pül pül3l2 2p1v 2p1w pwa4r 3p4y1 py3s py3t 2p1z2 qu4 que3rel quer5n que4te. 1queu 1ra. r1aa ra2ab 2raac 2raal ra3ar r2a1as r1ab ra2b1ar r2abä 1rabbi rab2b3l 2rabd rabdru4 ra2bei rab2er rab3erd 2rabf 2rabg 2rabh 1rabi 2rabk r2able ra2bli ra4b5lo 2ra2br 2rabs4 2rabt 2r3abw 1raby 2rabz ra2ce 2r1acet ra4cheb ra2cho 2rachs rach6t5rä ra2chu r2ack 1r2ad r4ad. rada2 ra2dac ra4d1am ra2dan 2radap 3radar ra2de4i 3radf 3radh 3radio 4radit 3rado 3radp ra4d1r rad3ri rad5t4 r2af raf3ahn raf3ar rafe2 ra2f1er raf3r raft5s rag2a ragein4 rages4 2ragg ra3g4le 4ragm ra2gn r2ago rahle4n 5r4ahm r1ahn 2ra1ho 4raht r2ai 2raic rail2l 2r3air raka3 1r4a3ke 2rakk 3ra1k4l ra2kre ra2kro 2rakti 1rakü 2rakz r2al r4al. ra2la2 ra4l3ab ral1ak rala4s ra2lä ral3b4 3r4ald ra4l3end ra4lent ra4l5ern ra3lex r4ali ra2lid rali3er ra4lin4d ra4l3ing ralin6sp ralin4t 2r3alk. 2r3alm. 2ralp. 4ralpe r4als ral3sk ral3su r3alt 3r4al5t2h ra2l3u 3raly rama3s ra2mei ra2mer r2ami r2amm ram4man ram6mens ram6m5ers ram4m3u 2ramn 3ramsc 2r1amt ramt4s 2ramu 2rana ran1ad ran3ade r1a2nal ra2nan ra2nar ra2nau 2ranb r2anbe r4anda r4ande ran4dep ran4d3er 3r2andi rand3s 1raner 2ranf 2ranga ran6g5e6be 3rangi r2angl rangs2 rang3sp rang5ste rani3e r3a4nil ran3ka ran2kr ran2kü 4ranl 2r1anm r2anmi r2anmu 2ranna ran5ne 2r1anp 2ranr 2rans r2ans. r1ansc ran4spa 4r5antei r1anth r2anto 2rantr 1ranu 2ranw r2anz. r2ap 2rapa ra2par 2rapf 2rapo ra2pok rap2pr 2r3a2pri 2r1aq r1ar r2ar1a 2rarb r2are 3r4arei raren1 rar3et rar1e2v r2arf4 ra3rie rar3in ra3ris r3a4rist 4r3arit r2ark raro2 ra2rom 2rart 2rarz rar3zw r4as. ras2a ra3san ra4schl r2asm ra3spr r2ast ra2sta ras4t3ei r3asth ras4to 2rasyl 2raß 1rat r4at. ra2t1an ra2t1ei r3a2tel ra4tid 2ratm rat2o 2ratom ra5tor rat4r r3att 2ratta 2rattr 4ratz rat3ze 4rau. 3raub. rau3e4n 2rauf rau3fä 2rau3g2 3raum rau4m3ag rau5mes rau2mi 3raup 4raur 2rausb 3raus2c 2rausd rau3se 2rausf 2rausg raus8gewä 2raush 2rausl rau2sp 2rauss raus8sche raus5se 2rausv 2rausw rau3ße 2rauto raut1r rau4tra rau4tro raut5s 1raü r2ax raxi2 r3axt r2ay ray1o r2az räch2s 3r2äd 4räf rä1fr 4räg 2räh 4räm 3rän. 3räni 3räns 2räp 2räq 2r1är r2är. rä3ra rä1ro rä2sc räse2 räte1s 3rätse 4rätz rä2u 4räue räu2s räus4c räu7schen. 2räuss 2räuß 4räut 2räx 4r1b r2b3a2b1 r3bac rba4del rb2al r3bam r2bang r2bant rb1art r2barz rb1auf rbb2 rb1ech rbe3erf rbei3d2 rbe3inf rb3einh rbe3int r4belä rbel2o r3ben. rbe3r2e rber6gin rbe3rum rbe3sl r2bim r2binf r3bit rbit2a rbi3tu rb4la2d r2blan r8blasser r4b3last r3blat r3blau r2b3le. r3blen rb3ler r2bleu rb2lin rb2lö rb2ob r2bonk rb3ras rb3rea r8b7rechts rb4sam rb2sei rb2ser rb2s1o rb4stä rb2su rb2u rbü4b rby4t 2rc r1ce r1che. r1chen r1ch2i rch3l r3chlo rch3m rch3r rch4ro rch1s4 rch3sp rch3t2a rchter6r rch1w r1ci r2ck r1cl r1ç 4r1d rd2ac r2daf r2d1ak r2d1a2l rd2amm rdani1 r2dann rd1ant rd1ara rd1ark r2darz rdär2 r3de. r3dee r2dei rd2ei. r2d1elb r2de2le r2delf rdem6 rden3d r4dengl r4dents rde3ob rde3ono rde3r4er rderin6s r4d3ernt r3des rde3sp r2d1e2x r2d1inn rd1iri rd1ita r2dof r3don rd3oss rdo4st r2d1oz r2dö rd3rat r2drau rd3ris rd4rö r3d4rü rd2sän rd3s2k rd3s2z rdt4 rd3t2a rd3th rdt2s r2d1uk rdwa6r 1re 3re. rea2d rea6l5erw 4re2am re3at. re3ats reatu3 2reä re2b1a re2b1l reb1r reb3ra reb3so rech3ar 4rechs 2reck. 2recki 3red. re3da 4redd 2redi re2dik 3redn 3redu re1ebe re1el re1em ree4mi re1er 3refe 4reff r2eff. 3refl 3refo 3reg rege4l3ä regene7ra 4r1egg re3gi re2hac re2h1ar re4hen4e re4h3ent re2hi reh1l4 re2h1o re3hol 3rehö reh4th re2hü r2ei. r2eib rei4bel rei4ble r2eic 2reid r2eie 4reier. rei4fei 4reifel 2reig 3reigä 3reigeh r4eigel 6reigens 3reigi 4reign 3reigru rei3l2a rei3l2i 2r1eilt 3reim reim2p r1ein 2rein2a rei3nal 2reinb rein4du rei3n4e3c reinen5 2reinf rein4fe re4info 2reing 2reinh 4reinn 4r3einr 2reins 4reinsa rein6sel rein8s7tre rein4sz 2reint rein6teg re1in2v 2reinw 2reinz 4reisar 4reisb reises4 2reisf 2reish 2reisr reister6 4reisu 2reisw reit3s2 3rek 4re2ke 4rekk 5rekn 2rekz r2el. r2ela re3lat 2relb rel2e relea4 re5lei re2lek 4relem r2elev 2relf 2relit 2relix r2ell rel4lar rel4lei re3lo r2els 2relt relu2 3r2em. 2r1emb rem2da re2m1ei re3men 2remi re3mig 2rempf rems1c rem4str 2rem2u r2en. r2ena 2rena. re4nac re3nad re3nal re4n3an re2nä 2r1endg 3rendi ren3dr 4renerg 4rengag ren4gan 2rengp 3renh re2ni 3renm ren4nar ren6nene renrü2 ren6sein rens2p 2rentd 6rentera 2rentf 3rentfo 2rentg r3enthä 2r1entl 2r1ents 2r3entw 2rentz r2enz ren6z5er6f renzer6l ren6z5er6s renzer6w ren4z3in ren2zw re2ob re3or 3repe 4re2pen 2repi re2pis 2repoc 2r1e2pos 4repp 3repu 3r2er. rera2 2r1erb 3r4erber rer2bi 2r1erd rere2 4r3ereig r1erek re2r1ep r2erer r1erf r3erfa 4rerfah 2rerfi 2rerfo r2erfr rer2fü r1erg 4r3ergeb 5rergebü r4ergen 3r4erges 2rer2go rer2gr r4ergru r1erh rer2hö r1erk rer4kan rer2ke 4r3erken 3r2erki 3r2erko r1erl 2r3er2la 5r4erlag r3erleb r2erli 2rerlö 2r1erm rer2n 2r1ernä r1erne 2r1erni 4r3erns 4r1ernt re1ro re2rob re4rosi 2r1er2ö r1erre rer4reg rer4rei r1erri 5r2ers. 2r1ersa rer3sc r6erschi r2erse 2rersp rer2st r6erstad 2rer4su r1ert4 r2erte 2rertr r1erw 2rerwa rer4wac rer4wec r4erwes 2r1erz rer2zä 3r2erzy 3r2es. re2sa re4sam resche4 re4schw 3rese re4se2h re2s1of 3resol 3reson re2spa res2po 2ress 4resse res3sei res6s5erw 4ressu re1sta res4tas res6tent res4tex 2res4tu 3resu re2t1ak 2re2tap re2tau ret2e 2r1e2th re2tra re4trol re2u reu4eri reu3g2 2reul re3uni 2reur 4reuu 2reü 4r3eva 2r1evid rewa4r re2wi 2rewo 2r1e2x1 3rez 2rezi 1ré 4r1f rf1a2ck r3fam rfe2i r2fent r3f2es rff2 rf3fe rfi4le. r4fland r3f4lä rf3lic rf4lö r3flü r2fo2b rfolg4s r4frauc rf4ru rf4rü rf2sa rf4sam rf2s1ä rf2su rf2ta rft4r rf2u rfzu3 2r1g r2g1a2d r2g1ah r2g1ak rga4ner r2g1ap r2garb rg3art. r2g1ask rgd2 rge4an rge2bl r2g1e2c r3gel r4gelef rge4l3er rgen4z3w r4ge4tap r2geto rgi4sel r2glan r3glanz rg5le. r2gleu r2glig r2g3lit rg2log rg2lu r2g3na r2gne r2g3ni r2g3no r2g3oa r2gob r3gog rg3op r2g1or rgö2 r2g1öd r2g3ral rg4rau r2greg r2g3res r2gret rg3rin r3grun rg3rüs rg3sä rg3se rgs2ei rg4sel rg3s2i rg3sp rgs2pe rgs2po rg3st rgs4tr rgs2tu rg3su r1h4 2rh. r2hag 2rhah 2rhak r4haltb r3han 2rhau 2r3hä 3r2he. r3hea 2rheb 2rhef 2rhi 2rhol r3hop 2rhot 2rhöl 2rhs rhu2s 2rhü 1ri ri3ams ri1an ri2ano ria1s ri2ast rib2bl ri1ce ri1cha ri3chl richt8spo 3richtu ri2con ri2dau 2ride ri2d3e2l ri4dent r2i3di 2ridol 2ridy r2ie 4riefm rie2f3r rieg4s3 ri2e1i riein1 ri1el rie3l2a ri3els ri4enä riene2 ri3eni rien3s rie4nu ri1er. rie3r2e riere4n ri3ers. rie3sa ri1eu ri2f1a ri2fä ri2fei ri2fer rif6f5end rif4fer ri2f1o ri2fr rif3s rif4ter 3rig 4riga 4r3i2gel ri4gene 4rigg 5rigj rig1l ri4glä ri3g2o3 4rigr 4rij ri2kar ri2kä ri2kin ri2kn ri4kone rik2op ri2kor 2rima ri2mag ri2me. 2rimm 4rimp rim2s rim4sc rim4st ri3na r1inbe rin2c 2r1indu ri3n2e rine1i 2r1inf rin2fo 3r2infr r2ing rin2ga ring3le rin2gr ring3sp 2r1inh 2rinit 4rinj 4rink rin2kl rin2ko rin2kr 2rinl 6r5innenm 4r3inner 2r1innr r1innu 2r1in2q 2r1ins rin4si rin2so r4inspi 3r2insy 2rint 4rinte rin6tent rin4t5re 2r1inv rin2va 2rinz ri2ob r3ion ri3o2st ri2pl ri3po 4r1ir r2is ris2a ri3san ri4sch3o ri4schw 3risik ri3s2ko r3iso ri4s3p r3isr 3riss ri4s3t ris6t5ers ris4th rist3r r2it r3i2tal rit3ant rit2i 2ri3t4r ritt3a rit4tau rit6ter6f rit4to rit2t3r rit2u r1i4tum rix1 1rí 2r1j 2r1k rka2b3l rk1ah r2k1ak rk1all rk2am rk1are rk1asp rkauf4s r2k1äh r3kel r4kelem rke2n1 rken4er rken3s4t r2k1er2l rk5ersta r2k1er4w r3k2es r3ket rk1im rk4las rk4lau rk4lim r2klis rk2lo rk2lu rk4ne r2kob r3kol r3kon rk2op rk1o2ri r2kou rk2ö rk3räu r3kri rk3rin r2k3rom r2krou rk2sal rk2sei rk2sel rk2ser rk2so rk2sp rkstati6 rk4stec rk4stoc rk2ta rk2tel rk4t3eng rk4tent rk4t3erf rk4terg rk4t3erl rkt3ers rk6tersc rk4t3erw rk4t3erz rk4teta rkt2i rk2t3in rk4t1o2 rkto4b rk2t3r rk4tri rk2tum rk1ums rku2n r3kup rkur3s r3kus rku2sa r2küb 2r1l rl2ab r3lag r5land rlan4d3i r2l1ar r2l1a2sc r2l3aug rle2a r3lec r5lei. r3lep rl2et r3lex rlg4 r3l2i rli4ne. rli2s r3l2o rlou1 rl2ö rlös3s rls2a rl2spr rl3ste rl2s5to rl3t r3l2u r3ly rlz2 4r1m r2mab r2m1ad rma2la rm1ald rm1ami r2m1ank rm1anz r4m3aph r2marc r2marz rma4s3pe rmas3se rmat2o rm2är rm3d2 rm1ef r4m3einh rme4na rm2ene r2ment r2meo rmer4fo r2m1erh r2m1erl r2m1erp r2m1erw rm2es rme1st rmes4z rmeta2 r2mide rmi6nanz rminen4 rmi6neng r4mn r2m1ob rmon3s4 rm1o2ri rmo1s rm3p2 rm3sa rm3s2k rm3t rmt2a rmu2n r4muna r2muni 4rn rna2b r3nad rn4ade r3nage r2n1all rna4n rn4and rn3ani r2nanz rna2r rn3are r4n3ari r4n1ast r4n3att r2nau rn3aug rnd4 rn3de rn3dr r4nef rn2eid r4neif r4neis rn1ema rne2n r2n1ene rn2eng r4n1e2p r4n1erg rn4erhi rner4ke rner4ku r4n1erl r4n1ert r4n1erw r4nerz r5nes rn2e2t rnet1e rne4tem rne4ter rne4to rn2eu rne3uf r4nex rn3f rn3g2 rngene4 r2nid r2n1in r4ninf r3nit rnk2 rnn2 r3nod rn2oh r2n1op r2n1or rn1ö rnö2d rn3sa rn3s2ä rnse4ha rn3s4p rns2u rn3s2z rn3t2a rn3t2e rn1ur r1nü r1ny rnz2 r2oba 2robj 1robo ro2bo2r 2robr ro2bre 2robs ro1c roch2a 3rock. r2o3de rod4r roe4 2roff ro3fl 4rog. ro3g2a 3rogg ro2h1in roh1l2 4rohn ro2hö 3rohr 1roi ro3in ro1ir rok2l ro3le ro2liv rol4lan rolle4 rol6lerg rolls2 rol3s 2roly 4rom. ro2mad ro2mal 3roman. 2romb romen3e ro2m1er 4romm 2romn rom3s 4romt r2on ro3n4ab ro2nan 3rond ro4nerb 4ronk 3ronn rons2 ron4tan ron6tend ron4t3r ron2t1u ro1ny ro1o2f rop2a 2rope 2ropf 1ropl 2ropt r1or ro2r3al ro2rat 2rorc ro2rel ro2ro ror3th rort2s ror2ü ro3sh ro5s2i ros4ko ros4sal ros4san ros2s1c ros6senk ros4st ro1sta ros6t1r ro2sum 4r3osz 4roß roßen2 ro4ßenk ro2ßi ro2tan ro4tas ro4t3au ro2tä ro2te3i ro2t1ho ro2tru rot3s rots2o rot2ta ro3tu 3roul ro3unt 3rout 2ro1x 4roy rö2b3l rö2du 2rö2f 3röh 2r1ök 1röl 2röl. rö3le röl2l r1ölp 3römi r1ör r2ös. rös1c r2öse 1rösl 3rötu 2r1p2 r3pa r3pe rper3in rpf4 r2pli rp4lu r3po rpro1 rp3se rps3t r4p3t r3pu 2r1q 4r1r rr2ab rr4at rrat2s rr1auf rr1äm rrb2 rr1c r5rega r5regi rr2ei rre2le rre2pa rrer2 r2rerh r2rerl rrer4s r3res rre2ve r4rezi r3r2hen rr2hos r3r4i rri3k2 rrm2 rrn3au rr2o rr3obs rro3m rro2re rrr2 rr2st rr3str rr3stu rr2th r3r2u r3r2ü rrz2 6r1s r3sabo r2s1a2d rs2al r4samp r4s1amt rs2an r4sanf r2s3ang rs3anm r4sanp rs3ant rs3anz rs3ar rs4ark r4sarm r4sch3e4b r6scherl r3schu r2s1ebe rse2e r2s1ef r2sein rse2n rs2end rse4ne r2sepi rs1ere r2serh rs1ers r2serz rse2t rs1eta rs2ext r3s2hav r3shir r3sho rs2hor r4shu rs2il rs2ka rs2kel rs2ki r4skir rs2kl r4skor r3s4kri r4sky rs4mog r3s4no r3so r4sob rs4om r4s1op r4sorie r4s3ort. rso2s rs1ost rs2p r3span r3spe r2s3ph r3spi r3spl rs4por r2sput rs3s2 rst3abl r3stad rst3ala r4stale r4stans r4stant r2stas r7stati r7statu r3stä rst5eing r6st5eint rst3emi rs4temp rster2 rs4t4erb rst3erl r3s4tern rst3erw rs2tev rs2t1h rs2ti r3s4tie r2stin rst3ing r3stink r2stip r2stit r3sto rs4tob rs4tol rs4tor r4stot rs4tr r3stra r6strang rs5tren rs2tu rs4tuc r3s4tü rsuch4s r3suf rs2ums r3sy r1ß 4r1t r2tabo rt1abs rta2ck r2t1a2d r2t3ae rt1akr r4t3albe rta3l2e r2t1all rtal4s3e rt1am rt2ame rt1ann rt1ant r2tanw r2t1ar rt3att r2taut rt3äh rt1änd rt1ärm rte1e2 r3teh rt1ein rt4eind r4t3einh rte2i1s4 r2telf rtels4t r2temo rte2n1 rte4na rten3s4 r4t3ents rten3z rteo2 rt3erei r6tereig r4ter4fa r4ter4fo rt1erh rt1erk r4t3er4la rter6mit r4t3ernä r2ter2ö rter4re rt1ers rt4ersp rt1erz rte3sk rt1he r2thel r2t1hi rt2hum r2t1id rtik2 r2t1ima r4t3inf rt2is rt2it rt3l rt3m r2t1ob rto1pf rt1orc r4torg r4trak rt3rams rt3rand rt3rati rt3rec rtre1s r4t3ris rt3rol rt3roma r3trop r2trou rtrü2c rt3sc rt4s1eh rts2el rt3sex rts3ing rts1o rts1pa rt4s3tan rts4tie rt2su rt3t4 rt1umb rt2u3na r2t1urt rtu4t r2t3ute r3tü rty1 rt3z2 1ru ru1a ru4ale ru3a2r3 rube4 ruben3 rubens4 rub2i rucht3s4 ru6ckerl ru2cku rude2a ru2dr ru2et 3ruf ru2f1a ruff4 ruf2s ruf4ter ru2g3r 3ruhm 2r1uhr 3ruin ru3ins ru1is 2rum ruma2 4r3umd 4r3umf 4r3umg ru2mi 4r3uml 4r3umsa 4r3umw 4rumz 2r1una 2rund run4d1a runden5e run4d3er run2e runei2 4r1unf run2ga 2rungl 4r1u2ni r3unio ru4nis. run2kr 4r1unl 2r1unm 4runn 4runr r1unse 4r3unt 4runw 2rupd ru3pr 4r1ur ru2ra ru2r1e 5ruro r4us. ru2si rus2p rus2s1p rus4st ru2st ru2tab rute4 ru4tei ru4t1el ru2t1er ru4t1o2 ru2t3r rut6scha 4ruz ru2z1w 1rü 2rüb 4rübu rü1ch rü4ckel rü2hel rüher2 rüh1l 4rümm rün3z 2r1v r3ve rv2el rve4n1e rvenen4 r4ventz rve3s r3v2o 2r1w rwe4gel r3wei rwelt4s r5werk r5wert r2wo. r3woh r3wort rwun3s 4r1x 1ry 2r1ya ry2c rygi3 ry1la ry2le ry1os ry3sth rysti1 2r1z rz2an rz3ant r2zar r2zat rz2än r5zene rz1eng r4zents rze2p rze2ra r2z1erd r2z1erf r2z1erg rz1erk r2z1erl r2z1erw r2z1ess rz1id rz1int rzir3 r3z2of r2z3ot rz2tan rz3te rz2th rzu4g3l r2zwä r3z2wec r2zwir 1sa 3sa. 3s2aa 2s1ab sab2ä 4sabd sa2be 3sabet sa2bit sa2bl 4sabm sa2bor sa2br 4s3abs 3sac 4sacc 5sache sa2cho sachs2 sach3t s2ack 2s1ada sa2der s1adm 2s1a2dr 3safa sa4fe 4s3aff sa1f4r 3s2aft saf4tr 3saga sag2e 5sage. 5sagen. 4s3agent 2s1agg sa2gio sag4n s1a2gr s2ahs 3s2ai sa3i2k1 sail2 sai4r 2s1ak sa2ka sak2e 3saki 4sakk 3sako 4sakt 3s2al. 3s2al2a sa2l3an sa2lar sa3lat 3s2alb sal3bl 3s2ald sa4lerk 3sali sa2l1id s1all sal3la sal4le. 3sal2o sal3or sal2se s1alt s2al3t2h 3salz 3sam 4s1a2mat 4s1a2mei s2amen sa2min 5samm 6s1amma 4s1amn s1am3p4 4samph sam4ta sam4to samt3st s1an s2an. 2s3a2na san4at sa2nä 2s3anb s2an2c 3s2and s4and. san4dan san4d3ri sand3s sa2ner 3sang. 4sanga 2s3anh 3sani 3sanken 2s3anl 2sa2no 2s3anp 2s3ans s4anse san4sk san3sp 4santei 4s3antr 4s3anw 2sanz 2s1ap sa2pe s2aph sap3p 3sapr 2s1aq 2s1ar 3s4ar. 3sara 4s3arb 3s2ard s2are s3area 3sarg sar2ga sa3rin s2ark sa2rom s2ars 4sart sa4r1u2 3sas. sas2a s1asc s1a4si 2s1a4sp sas2tu 4sa2sy sat2a satan4 sa4t3ant sat1ei 2s3a4tem s3ath 3sat2i 4s3atl 4satm sat2o sa4tol sa2tr sa3ts s3atta 4s3attr 3satz 5satza sat4zel sat4z3en s1au 3sau. 3sauc 3sau2e 2sauf 4s3aufb 3saug saug3le sau2gr 3saum 3saur sauri1 2saus 3saus. 4s3ausb 4s3ausf 4sausg sau2sp 4sauss 3sauste 4s3ausw 2sauß s1av sa2ve sa2xi sa2y1 1sä 3säb 3s2äc 3s2äg s1äh 4s3ähn 3säl 4s1ält 2s1äm 4s3änd 4s3äp 2säq 2s1är 3s2ärg 3s2ät 3säul 4säuß 4s3b4 sba4ne sbau6men sber2e 1sc 2sc. 2scab 2scac 2scal 2scam 2scar 2scat 2s1ce 4s3cei 4sch. 3s4chal sch3ana 4schanc 4schang 4schao 4schara 4sch3ar5m s2chä 2schäq 4schb 4schc 2schd sch2e 4schech sche2f 6schef. 6schefi 6schefs s4chei 4sch3ei. sch6ein. s4chema 4schemp sch5erfü sch5erla 3sches 4schess 4schex 2schf 2schg 2schh schi4d schi4e 4schiru 3schis 2schk s4chl sch4lac sch4lag 4schle. 6schlein 4schloc 4schlöc 4schmas 4schmed 2schmö 4schmüh 2schmy 2schn. 4schneb 4schobj 4schorc 4schör 4schp 2schq 4schrad 4schre. 4schrin 4s3chris sch3rom 4schron 4schrou 4schs schs2e sch3s2k schs4ti 4sch3t scht2a scht2i s4chu 4schunt 2schv sch4web 4schweg 6schwerk 4schwet 4schwid 3schwu 2schz 2scj 4s3cl 2s3co 4scoa 3s4co2p scre4m 2scs 2scu 2scy 4s3d2 sda3me sde1s2 sdien4e sdi1st 1se 3se. se3at. seb2 3sebä 2s1e2ben 2s1echo sech4st 2s1echt 2s1e2ck se2dik 3see see1i2 see3ig se2el see3len se3en. see3n2e se3enp se3er. see1ra seer2e se1erf se3e2r1i se1erk se1ers see3s4 2s3eff sef4l 3s2eg 4s3e2gal se2gl seg4r 3seh seh1a se2hag se2hak se2hel seher4e se4herk se2h1in seh3l se4h3ö seh3ra seh3re seh5r2i seh1s se2hüb 2sei. 2s1eic 2s1eid. sei3da 4s3eifer 2s1eig 3seil s2eim s1ein 5s4ein. 2seinb sein4du 2sei3n2e seine3i 4seinfl sein4fo 2seing 2s3einh 2seini 2seink 2seinl 2seinn sein4ne 2s3einr s4eins. 4seinsc 4seinsp sein8stit sein6str 2seint sein4to 4seintr 2seinw 2s3einz 2s1eis 3s2eism 3s2eit seit2s 3sek 4s1e2kel 4sekz s2el. se2l1a 3s2elb sel3d4 sel1ec se2lef 2s3e2leg 6selektr 2selem se2ler sel3ers 2self. selin4s s3e2lit 2s1elix s2ell se2lob s2els sel3sz selt2e selz2 sem2e 2s1e2mis 2s3emp s4en. 3sena se4nad se3nal se4nas sen3au se2nä s2enb 4s1endl sen3d4r s1endw senen1 4senerg se4ners s2enf 3s4eni se2nid se2n1im 3s2enk sen6keli se2no se4nott se4noz 3sens s2ensa sen4s3e4h 4sensem s4ensi sen4si4d senst2 sen8s7turm sent2a sen3tä 2sentd 4sentf 2sentg 4sentla 2sentn s2ento sen3tr 4s1ents 2sentw 4sentwu 4sentwü 4sentz se4n3u2 sen3za sen4zer sen3zw seo2r se2pen 3seq s4er. se2r3a2d ser3al se3rand ser3äus serb2 s3erbe. serd2 se2r1e2b se3reie 6sereign se4r3eim se4rein sere2m 5s4eren se4r3enk s4erfe s1erfo s2erfr s3erfü 4serfül serg2 ser3ga ser3gl s2ergr s1erh 2serhö 3seri 5serie serk4 4s3ermit s2ern. s3erneu 2s3ernt sero4b 2s1e2ros s1erot s1erö 2seröf s2ers. 2sersa 4serseh ser6sehn 4ser4set se3ru se4ruh ser2um s3e4rup 5s4er3v s1erz 3s4es. se3s4a se2sel se3sk 2s1essa se1sta se3stec se3stei se5stemp sest3ri se3su 4s3e4tap se2tat 2s1e2th set2i 4s1e2tik 3setz 3seuc 2s1eul seum4 se1u2n s1ex 3sex. 2sexa se2xe sex3en s2exi s2exo 4sexp sex3t4r 2sexz 1sé 4s3f4 sfal6l5er 4s3g4 sgang4 sge3sa sge5t 2s1h 4sh. sh2a 3sha. shal4li shalt2 shalt4s 4shan s3hä sh2e sh2i 3shi. s2hip shi4r sh3n 4s3hoc 4s3hof 4shom 3shop sho4re 3s4how 4s3hö sh4r2 4shs s3hu 1si 3si. si3ach. 2siat 5s4i1c si2cha 2s1idea 2sidee 2s1ideo si3der s2i3do 2sidy 3s4ie sie2bu siege4s sien3 si3ene si1err si1f4 3s4ig si2g1a2 si2g1ei sig4n si2g3r sig4st si2k1ab si2kak si2kar si2k1ä si2k1el si4kens sik3erl si2k3i sikin1 si2k3n si2k3r sik3s sik3t2 si2ku 3silb sil2br sil2e 3sili s1ill 3silo 2s1imm sim4st 3simu si3n4a 2s1ind 2s1inf 4s3infe s3infor sing1a sin3g4le sin2g3r sings2 sing3sa sing3so 2s1inh s1in1i sini1e s2ink sinner4 2s1inno 4s1inq 2s1ins 4sinso 4sinst 2s1int 4s1inv sion4 sirn4 2sirr 3siru si2sa si4sam s2isc si4schu si2s1e2 si2si s1i2so sis1or si2s3p sis3s4 3s4ist si2su 3s2it si2tal si2tau si2tra sit2u si2va sive3 siver2 si4v3erf si2vin siv1o4 si2vor siz2 1sí 4s3j 2s1k2 4sk. sk4a 4s3kab s3kad 4skalk s3kalt 4s3kam 4skana 4skanä 3skanda 4skann 4skap 4s3kar 4s3kas ska4te. 4skateg ska4tes ska4to 4skau 4s3kä 4skb ske2li 4sken 3skep 4sker 4s3ket s3kh 3s2ki. 3s2kif 3s2kik s3kim s3kin ski1s s2kis. 3skiz sk4l 4s3klas 3s2klav 4s3klu 4sk4n 4skoh 4skol 4skom 4s3kon 3skop. sko2pr 4skos 4skow 4s3kö sk4r 4s3kra s3kre 4s3kro 4sks 4sk3t2 skto2 3skulp 4skun sku2s1 4skü 4skv 2s1l2 sl4a s3lab 3slal sla2ma sla2ve s2law s3lä sl3b 4s3le sler3s s3li 3s4lip slo3be s3loc s4loga 3s2low s3ly 4s3m4 sma3b4 sma3sc sme3na smi2t3 2s3n2 snab4 sni4a sni3er. sni3ers 4s5not 1so 3so. 2s3oas 2s1o2b 3s2o3ba 4sobj 4s3obo so1c so2di so2do so3et 2s1o2fe 2soffi 3soft 3sog sog4l s1o2he 3sohl sohle2 2s3ohng 2s1ohr 3soi2 so3id 2s3ok 3sol. so3la so4lau 3sold 3sole so2l1ei so3li sol2la sol4ler so3l2o 4s3o2ly 3somm 3s2on son2a son3au sone2 son4gl son3sä son2s1o so3o 2sope 2s1opf 3sopr sop3s 4s3ord sore2 so2rei so2rel 4s1orga so1rh 2s1o2rie so2ro 3sorp 3s2orti so4ru 3sos s2os. 4so4sk 4sosm 4so1st 4s1osz 3so3ß 2sot so3t2h 3sott soun2 sound1 so3unds so3unt 2s1out 3sov 3sow 2s1o2x 3soz s1oze 1sö sö2c 2s1ö2d 2sö2f 2s1ök 2s1öl 2s1ös 1sp2 2sp. 4spaa s2pace 2spack 2spag 2spak 2spala 2spalä 3spalt spa2m s2pan. 3spannu s2pans 3spant 2spanz 2spap 2s3para 2sparo 5s6parten 4spartn 4sparty 3spaß 3spat. 2spati 4spatr 2spau 3s2paz s2pä 2späd 3späh 2spär 2späs 2s3pe. 2speg 4spein 4spensi spe3p4 s2pera 3s2perg s1peri 4sperle 2spero s2perr 2spers 2sperü 4spet 3s4pez 4s3pf4 2spha s2phä 3sphär s3phe s4phin 3s2pi4e 4spier spier4r spi2k 4s3pil 3spio 4s3pip 4s3pis 2sp4l 4spla 4s3plä 4sple sp5le. 3s2pli 4s3plu 2s3pn 2spod 4spoe 2spog s2poi 4s3pok 4spol s2pons 4spoo 2spop s2pore 3s2porn spor6tag 4s3pos 4spote 4spr. 3s2prac 2sprak 2sprax 2spräm 4spräs 3s4prec 4spred 4spreis 5s2pren 2s3pres s2pric 3spring 4sprinz 2sprob 2sprog 4sproj 4sprop 3spross 2sprot 2sproz 3sprö 3s2pru 3sprüc 2sprüf 3sprün 4s3ps 2s4p3t 2spub 2spud 3spuk 3s2pule 2spun 2spup 3s4pur spu4rer 2spy 2s1q 4s3r4 srat2s sre3cha sreli1 sro2h srö2s srücker6 6s1s ss3abi ssa3bo s5sack ss4agi ss1aj s3sal ss3alba s4sall s4samt s2sanf s4sang s4sano s4sans ss2ant s4sanz ss2ara ss2arg s3sars ssa1s s2s3att ssau3e ssau4r s3s2ä s4sce ssch2 sschanker8 s3schw s4sco s2scr sse3a ss1ec sse1ec sseh2a s2sein ss4eind sse3int sse2lö s3sen ssen6kel ssen6sem ss1epe sse6ratt ss5ereig ss4ergr sser4hö sser6mit sser4öf ss3erse ss4eru sser6wei sses4sa s4s3estr s3set sse3ta s3si ss3i2ko s4sill s4simp s4sind s4sinf ssing3s s4sint s4s1isr s3skala ss3l ssmut4 ss1off ssoi4 s3sol s4sop ss2pen ss2phi s3spi s3sprä s3spri s2spro ssquet4 ss3s4 sssau4 sst2a s3stad s4stag ss3tak s3stä sst2e s3stel s3s2tep s3s4tern ss4teu sst2i ss2tie ss2t3in s3stof s3stop ss4tör s3stran ss4tras s3s4trat s3strec s3strom s3strö ss2tur s3stü s2sumg s2sumr ss2ur s3sy s1t 4st. s2ta 2sta. 3staa 3stab. 2stabb 4stabel 4stabit 2stabl 4stabt st2ac 1stadt 1staff 2stag 3stagl 3s4tagr 3s4tah 2stak 3staks 2stala sta3lak 2stalb s3ta3l2i 2stalk st1alp st1alr st1ami 1stamm 1stan 2stanb s6tand 2stanf st2ang 2stanl s4tanm 4st1ann s4tano st3ansp 2stanw sta3po1 stapos4 st1app s4tar. sta6rens 4stari s4tark s4t2ars s4tart sta4sie stast4 s3tat. 2statb 3stati s4tatis 7statth s4tau. 2stauf 3s4taur 4stausb 4stausg 4stausr 4stauss s4taut s4t1a2ve 4stax 1s2tä 3stäb 3städ 4stäg 4stäp 5s4tär 3stätt 2s3täus 2stb 2st3c 2std 4s5te. 4steam 4stechn s2te2d st1edi 2stee 3s2teg ste2g3r 1steh s2tei st4ei. 4steic st1eid 3steig stei4gr 2steil stei4na 6steinga s4teins stein6sp s2tel 2stel. st1elb s3tele s3telf st2ell stel6l5än 2steln 2stels 2stem ste4mar ste6ment 3stemm 2sten s5ten. ste4na s4t3ends s5t2ens s4tentf s4tents st1e2po 2ster 4s5ter. ste2r3a s6terben 3sterbo s3teren 3stereo st3erfü 3steril 4sterm 3s4ternb ster4zo 4ste2s1 ste3sc stes4se s4testn 2stet ste4tab ste4tag 3s2teti 3s4tett 3s2teu 1steue 4steuf st3eun st1ev s2tew 4stex s2texa 2stf 2stg 2sth st2hen s2t1hi st3ho s2thu st1hy 2stia 2stib s2tic 1stich st1i2d 2stie. 4stief. 4stiefl 2stien 1s2tif 2stig sti4gel 3s4tigm 2s3tik s2t2il 1s2tim 3stimm 4stimma 2stimp st1inb 2s4tinf s3tinn s2tins 2s2tint 2stio 2stip. 2stipp s2ti2r st1ira st1iri st1iro 4stis 2stite 1stitu 2stiv 2stj 2stk 4stl st3le 2stm 2stn s2to 2sto. sto2bl 4stocht 2stod 4stod. 1stof s4toff 2stok 4stole s4toll sto3mi 2s3ton 4stona 3s4to4ne 4stonl 4stoo 2stopo 4stor. s4torb 2store 2storf 2s4torg 2stori 2storp 2stors 2stort stos2t 1stoß 4stote 2stotr 4stou 2stow 2stoz 1s2tö 4stöch 2s3töl 2stön 3stör 2stöt 2stp 2stq s2tr 2strac 4s3trad st4rade stra4fa 4s3trag 3strah 4strahi 4strai 4strak 2s5tral s3trank 4strans 1strap 3stras 3straß 4straum 4sträc 4s5träg 4sträne 2stre. s4trea 4stref 4streib 3st6reif 2strep 2stret 4streuh 2strib strie3s4 2s4trig 1s4trik 2s5tris 1stro s3troc s3trog 3s4troh s4trome 4stropf 2stros st4ross 2ströp 1stru 2strua 2strub s4trud 3struk 2strun 4strup 2strut 1strü 4s4t3s2 stsi4d sts4t 2st3t4 st2u 1stub 4stuch 3s4tud 2stue 3stuf 2stug st3uga 3stuh s2t3uk 2stumo 2stum2s stum4sc 2stumt 2stun. st3una 5stund 2stune 2stung s2t3uni 4stunn 2stuns 2stunt 2stuö stu3ra stu5re 2st3url 4sturn 2st3urt 3s2turz 2stus 1s2tut 1stüc 4stüch 3s4tück 3stüh 4stür. 4stüre 3stürz 1stüt 2stütc 2stv 2stw stwor2 2sty 4sty. 1s2tyl 4styp 4stys 2st3z2 1su su1an 3su2b3 su4ba 4subi su4br 3su1c su2cha su2cho 3sud su2eb 2s1u2f su3fi 2s1uh su1is su1it. su2k su3l2i 3sulta sum1a su2man su2mar 3s2ume su2mei su2mel sument4 su6ments su2m1et 2s3umf su2m1id su2min 3s2umm sum1o2 su2mor s2ump s1ums s3umsa 2sumse s2umsp 2s3umst 2s3umwa su2n 3sun. 2s1una sunder4 sun6d5erh su4ne 2s1unf 6sungena 2sungl sung4s 4s1uni 2s1unm 2s1uns s4uns. s4unst 2sunt 2sunw s4unwa 3sup 4supd sup3p4 su2ra sure4 su2rei su2rer 3surf 2s1urk su2r1o 2surs s1urt su2s su3s2a sus1e sus3i s3u2t su4te su3tr 3suv suz2 1sü 2sü4b 3süc sü2d1 süden4 3süf 3sün 3s2üs 3süß 4s3v2 svoran4 2s1w 4s3we swe6gers sweh2 4swie 4swil 4swink 4swis 4swit s3wü 1s4y 2syl1 sy2lo sy2lu sym3 sy2n3 3synd sy4no 3sy4s3 2s1z2 4s3za 4szä 4s3zei 4szel 3s2zena 3s2ze3n2e 4szent 4szer s2zes 4szet 4szeu 3s2zew 4s3zie 4s3zo s3zs 4s3zu 4s3zü 4szw 2ß3a4 2ß1ä 2ß1b4 2ß1c 2ß1d2 1ße 2ß1e2b 2ß1ec 2ß1ef 2ß1e2g 2ß1ei 2ß1ek ße2la ße2le 2ßelek 2ß1emp ße4n3a2 4ßenerg ße2ni ß1enke ße2no 3ß2ente 2ßentz 2ß1e2p ßer3b ßer2ei ßer2la 2ß1er4se ßer3t ß1erw 2ß1es2s 2ß1est3r 2ß1ex 2ß1f4 2ß3g2 ßge2bl 2ß1h 1ßi ßi2g1a2 ßig4s 2ß3i2k 2ß1il 2ß1im 2ß1in 2ß1j 2ß3k4 2ß1l ßler3s 2ß1m ßmut4 2ß3n2 2ß3o2 ßos2 2ß1ö2 2ß1p2 ß1q 2ß3r2 ßrö2 2ß3s4 ßsau4 ßsch2 ßst2 2ß1t ßt1in ß3tü 2ß1um ß1unf 2ßunt 2ß1ü4 2ß1v 2ß1w 2ß3z2 1ta 3ta. 4taa 5taan 4tab. 3taba ta2b3an 2t1abb 4tabd 3tabel 2taben 2tabf 2tabg 2tabh 2t3a2bit 2tabk 2tabla 4tabm 2t3abn 2ta4br 4tabs t1abst 2t3abt 3tabu 4tabw 4tabz 2t1ac 4tachs 3tacu t1ada 2tadd ta2der tadi3 tadi5o4 t1adm ta2dol 2t1a2dr ta3d2s 4tadt tad4tr ta2er 3taf. 3tafe 4tafet 4taff t1afg t1afr 3tag ta2ga ta2g1e2i t3agent tage2s 4t1agg 4ta3gl 4t1a2go tag4san tags3c tag4st tah2 tahls4t ta3i2k tai2l1 ta1ins tai4r ta1ir. ta1i2s 2t1a2ka ta3kes 2t1akk ta2kro tak4t1o2 t2aktu 2takz 3t2al. ta2la ta3lad ta3lag tal3au 3talbr tald4 3tale tal2en ta4l3end tal3eng ta4l3ens taler2 ta4ler3g ta2let tal2ga tali6ene tal4l3ac tall3ei tal2l1ö4 tall3s2 2t1alm. 3talo ta2lop ta2l1o2r t1alta tal3th talt4r ta2lu 2tam 3tam. 3tame t2amen t1a2mer ta2mi tamm1a tam4m3er t1ampl 3tams 4t1amt t1a2na tan3ab 4tanal ta4nat 2t1a2nä 2tanb 3tanc tan3d4ar tan2d3r tand4st ta4nerf 4tanf 2t1ang 3tang. t3angeh t2ango tan4gra 2tanh t2anho t4ani 3tanj 3tank tan2kl 4tankr 4t3anl t1anm 2t1anna 3t2anne t1ano 2tanom 2tanp t1ans t2ans. 4tansi tan4tan t4ante. 4tantei 2tantr 2tanwa 2tanwä t2anz. t1anza 4tanzei 3tanzk 3tanzr 2t1anzu 2tanzü tan2z1w tao2 ta3or t4ape ta2pes 2tapf ta2pl ta4poka t2appe ta2ra 2tarab 3tarabb ta3rak 3tar5al 2taram tar3ap ta3ras t2arau 2tarb 3tarba 3tarbek 3tarber 3tarbi 3tar3bl 2tarc 3tarchl 3tarchr 3t2ard ta2rel ta2r1er tar3g ta1r2h 3tari 2tark 3tark4l 3t2arko t2arl 2t1arm t2armä ta2rom 2tarot 2tart 3t2arta 3tartei tar6ter6e 3tartex 3t2arth t1arti 3t4artis tar4to tar2tr 3tarty ta2ru t1arz 2tarzt 3t2as. ta3s2a 3tasc 4t1asp 2t3assi 3tast tas4tem tas4to t2asy t4at. ta2ta2b ta2tan 3tatb t4ate tat1ei t5a2tel ta2tem 3taten ta2t1er 2t3atl 2tatom 2ta2tr 3tatsa 2tatt tau2b1a 3taubh tau2bl tau2b3r tauchs4 tauch5sp 4taud 2t1auf 3taufe. 4taufk 4t3aufl tau3f4li 4taufm t3au2f1o 4taufp taufs2 4taufw 3taug 4t3auge t1auk 3taume 4t1ausb 3tausc tau6scha tau6schm tau6schr tau6schw 2tausd t2aus2e 4t1ausf 4t3ausg t1ausk 4tausl 2tausr 4t3auss 2tausü 2t5ausw 4t3ausz 4tauu 3tav 4tava ta2van 3tax 4t1axt 3taz 1tä 2tää 4täb tä1c 4täd t2äf 3täg 4tägä 4tägy 2täh 4täll 2t1ält 4tä2m t1ämt t1ängs 3tänz 4t1äp 2täq tä4reng tä2ru 2tärz tä2s t2ät 3tätigk 4tätt 2täug 2täuß 2täx 1tà 4t3b4 tbauer4 tber2e tblocken8 tby4t 4t1c t3cha t3che tch2i tch3l t3chr t2ch1u tch1w t4ck t3cl tcor2 t3cr 4t3d2 tdar2m1 tdun2 1te 3te. te2a2 te3ab tea3c te3ag 2teak te3al 3team te3an te3ar tea4s 3teba t4ebb 2t1e2ben t2ech 2techd 2teche 2techk 2techm 3techn 2techt te2chu 2teck te3cker te2cki 2t1ecu te2dit te1em teen1 te2er. te1erw te2es 3tefa 2teff 2t1egg 2teh 3teha te2hac 3tehä 3tehi te2him 3tehö t1ehr te3hu 3tei. 3teic tei1fl 2teign teik4 3t2eil tei6lent teim2 2tein teinen4 tei6nens tein6hab t3einkü 2t1eis. t1eisb te5isch. teit4 t1eiw tei3z te2kel 3teko tekt4 3tel. 3te2la tel3ab tel1ac te3lan te4lant tel1au te2lä telb4 3telbr 3tel3d4 tel1ec tel3ehr 2telem tel3eng te2ler tele3s te2leu 4t3elf. 3telg 3telh tel1in te2lit 3telk tel3le tel6lein tel3li 4tellu 3teln te2lob te3lom te4lost te2l1ö 3telp 3tels tel3s2k 3telt4 tel3ta 3telw 3tem. 3t2ema te2man te2m1ap te2mau 2tem2bo te2m1ei te2m1er te2mi tem3i2m tem3ing 2temm te2mo tem1o2r 3temper 2tempf 4tempfi tem3s6 te2mu te4mun 3ten t6en. ten1a2 te4nad te4n3an ten3ar te4nas te4nat ten3au te2n3ä ten3da 4t3endal tend4an 4tendap 4t5endf 4t1endl t6endo 4t5endp ten3d4r te2n1e2b te2nef te2neh ten3ei te3n4ei. tenei4d tene4m tenen1 te4n3end te4nene te4neng te4nens 4t3energ te4n3ern tenf4 4t1eng. teng2a ten4gag 4t3engla te2ni te4nil ten1im te4n3in tenk4 ten3n2 te2nol te2nos te3nö 6t3ensem tens2p tens3th t1entb 4tentd 4t3entl 4t3entn t1ents 4t5entw 4tentz t2enz ten4z3er teo2f 2tep. 2t1e2pi 2teppu tept2 3t4er. t4era ter3a2c te2rad te1ral ter3alg te3r4ane te2r3ap tera4s 4terbos 2t1erbs 2t1erbt 3terc 4t3erde. ter3d2s 3tere. te2r1e2b te2rec t3ereig te5rek 3tere2m te4rema te4r3end te4rene te4reng te4r3ent teren5th 2tereo 3terer terer3k terer6ku terer3l te4r3erp te4rers te4rerw 3teres t4erfr terg2 ter3ga 6tergebn t6ergem t6erges t6ergew ter3gl 6tergrei t4ergru t6erhall t6erhau t4erhäu t4erhei 7t2erhi t2erho 6terhöhu t2erhu te3ria 4terii ter3iko 2teril teri4o te2r3it teri4ta 4terklä t4erlä t4erli ter4lös 3term t2ern. ter4nar 2t6ernc t4ero te1rob ter4obe 2teros t1e2r1ö t4erp t4erra ter4re. t4erro t4ers. t2erse t4erst. t6erstad ter6stat t4erstä t4ersti t4erstr t4erstu t4erstü tert2 ter3ta ter4trä t4eru2 te4r1uf te3rung t4erv 4t3erwäh ter3z2a 2t1erzb t4erzei 4terzeu ter3zw 3tes t2es. tesa2k tes2c tes2ka tes4pen te2spr 2t1essa tes3tan te3stei tes4tel tester4 tes6terg tes6t5erh tes6terk 2testn testo3 t3est3ri te2su tet2 3tet. t1eta te4tabl 2te2tap 2te2tat 3tete teten3 2t1e2th te3tho 4tetl tet3ti 3teuf 3teum 3te1u2n 4teunu 2t1eup 3teur. te2va te2vi tewa2s 3tewo 2texam 2t1e2xe 2t1e2xi 4texp tex4ta 2t1exz tè2 4t3f6 4t1g2 tga4s3er tga2su t3ge tge4nen3 tger2a tger2i tg4r 4th. 2t1h2a 3tha. 3t2hag 4thak 3thal. 3thalh t4hali t2hals t2han. t3hand t3hap 4t3hau 2t1hä 3thäi 4thäl 2thb th2e 1the. 3t4hea 2t1heb 2t1hef 2t1hei the1in 4theit t2hek 3thema 2themd 2themm 1then t1henn 3theo t1herd thero1 t1herr 2t1herz 4t1hess t2heu 2thf 1th2i 3thi. thic3k4 thi3er. 2t1hil 2t1him 2t1hin thi3nu 2t1hir 2thk 2th3l 4th3m thmu2 2th3n2 1tho 2t1hob tho3chr t1hof 2t1hoh t1holt 2tholz t2hon 4thops tho1s t1hose t1hot 4thote 2thou t1hov 4thö 2thp 1th2r2 2ths 2tht2 t1hu 2thub 2thuh 4t3hun 2thut 2t1hü 2thv 1ti t4ia ti3ac ti1ag tial2l ti3alo ti1a2m 3tib 3ticc ti1ce 3ticket t2id. 2tidee ti4d3en4d ti3dy 3tief. 4tiefel 3tiefl tie2fr 2tieg4 2tieh ti2e1i ti1el ti2el. tiel3a ti3e4n1 tien3s 3tier tie4rei tie4reu ti2ern tie3s2t 2tieß ti1eu 3tif. ti3fe ti1f4r tifter6k 3tig ti4gerz ti2git tigs4tr tih2 3tij ti2kam ti2kar tiken2 ti4kent ti3k4ere ti3kerl ti2kin ti4klu ti2kn ti2kop tik1r ti2kra ti2krä ti4krei tik5t ti2lar til3d ti2lei ti2lel 3tilg 2tillu ti2lö tilt4 ti2lu ti2ma2g tim4man t3immat timmer4 tim6merg 3timo 2timp tim2s 3tin. t4ina ti3naf ti3nak ti2n3an t1ind ti5n2e tine1i 2t1inf 3ting tin2ga ting3l ting3s 2t1inh 3tinis t1in1it t1inka tin2k1l tin2kn tin2kr t1inku t2inn ti2nor t1ins 3tins. t3insa t2insä 4t3inse tin4spa tin4sum t1int 3tinte. ti3nu tin2um 4t1inv 3tio ti2osk tioxi3 3tip. 2tipe ti3p4l 3tipp 3tips ti4que. 3tirad ti1rh ti4ron 3t2isc ti6schei ti4schu tisch3w ti2sei tis2el ti3sk 2t1isl t1iso ti2sp t1isr tiss4 ti3s2th tis3ti ti1s4tr ti2s1u t1it2a ti2tal 3ti3te ti1th 3titi 2ti3tu 3tiu tium4s 3tiv ti2van ti2vel ti4vene tiver2 ti4verh ti4verk ti4verl ti2v1o ti4v3r ti2za ti2zir 2t1j 4t3k4 4t1l2 tlan2g tl4e t2lef tlei6der tle2ra 6t3li tlings5 tlit1 t3lo t5lö tlung4 4t1m4 tmal2 tma2st tmen8schl tmen6t5 tments4 t3mo tmo4des 4t3n4 t5na tnes2 1to 3to. to4as to5at t2oba 4tobj tob2l t1obs 3tobt to1c t3ochs 3tocht to6ck5ent 3t4od tod1er2 to4dun tof4fa tof6f5ent tof4f3er 2toffi toff3s 3tog 2t3ohr 3toi 4toi. toi4r 4toiz 5toj 3tok4 3tol to3le 4tolp 4tolz tomar4b to4mene 3tomi to2min 3tomo to2m1u to4mun to2nan ton3au tond2 to2n2eh toner6ke to2nob 2tony 3too 3top. to2pad to2pak to2pan to3pas to2pat top1hi 3topo 2to4pt 3tor t4or. tora2g to4rän 4torc t1ord t2ordi 4t3ordn t4ore to2rei to2rel to2rem to6renna tor4fan t1or3g 4torga t5orient torin4s tor3int 5tork to2rö t4ors 4t1ort. tor3t2a t1orth 4tortn 4tort2s to4ru to3rü to4rüb 4tory to3sc to3s2e to3s2h to4ska to3s2p 4toss 3to1st2 4toß to1ßu to2tä 3tote to2tho 3totr tots2 5t2ou touil2 to3un 3tow to1x 3toz 1tö 3töch 4töck 2t1ö2d 2tö2f 4t1ök 2töl. 3tön t2ör t1öst 3töt 2t3p4 tpf4 tpi2n 2t1q 1t2r4 2tr. 5tra. 3trac tra3cha tra3chl 2t3rad. 2trade tra4dem 4t3radie tra4fah tra4far t4rag 3trahi 4trahl 2trahm 5t4rai 3trak 4t3rake t4rakt 3tral tral3l 3t4ran. 4trand 4trang t3rann 5t4rans tra2st 4traß 4traub. 4trauc t4raue t4rauf 2traup 4trauß 5träc 2träd 3träg 3träne 4träng 4träs 4träß 2träuc 4träus 4träuß 4t5re. 2trea t3reak 4treb tre2br 4trec t3rech t4reck 5treck. tre5cke 2t3red 3tref 4trefe 5treff 4trefl 4trefo 4treg t3reh t4rei. 3t4reib 4treic 4treif 2t3reig 2t3reih 2treim 4t3rein 2t3reis tre7isch. 4treit t3reiz 2trek 4t3rel t4rem t4ren. 3trend 4trendi 3trennu t3rent 2trepe 2t3repo 3trepp t3repr t4rer 5t4res. tre2ta t4rete tret3r 2t3rett 3treuh 4t3rev t4rex 4trez 5t4ré 2t3rh 3tri t4rib 4tric t4rick t4rid2 5trieb trie3fr tri4ena tri2er tri4ers trie1s 4trig. 5trigg tri3gl t4rik tri4ke. tri4kes 5triko 4t3rind 4tring tri3ni 4t3rinn t4rip 4tript 4t3riv tri2x trizi1 5tro. tro3b4 4trock. 3troe tro4kes trol4la 6trom. tro4men tro2mi 4tromk 4troms 4tromv 3tron tro3na t4rop tro1pe 3tropf 5tros. tro5sm 3trost t1rot. 2trout 3troy 4t3röc 2tröh 6tröm 3tröp 3trös 4t3röss 3tröt 3trua 3trub 2t3ruc 4truf 4truk trum2 t3rumä trums1 t3rund 3trunk 5t4rup t3russ 2trut1 tru2th 4truw trü1be trü1bu 2t3rüc trücker6 t4rüg 3trümm try1 2ts 4ts. ts3ab t4sachs t2s1a2d ts1ahn t2sall t2salt t4samp t4s1amt t2san ts3ane tsa2r ts3are ts3ari t2s1a2s3 t2sau ts2av t2säh ts1än ts1äus t4scham t6schart t3sche t4schef t3schl tsch4li t4schro t3schü ts4cor t2s1e2b tse2e t2sef tse4he. ts2eil t3seme ts1eng ts2ens t2s1ent t2s1ep t2s1er t6s5essen tse2t ts1eta t2s1eti t2s1e2v t2sex t3sexi ts3he t2s1i2d t2s3i2k t2sim tsing4 t2sini ts1ir 4tsk t3skal ts4kele tski2 t4s3ko t1slal ts1off t2s1op tso2r ts1orc t2s1ori ts3ort. t2sö t2spac t2spal ts1pas t2spat ts3pate t2spä t3sped t3spei t3s2pek ts4pend t2sph t3s2pi t4s3pic t4spins ts3ple t2spo t3s2pon t3s2por t2spro ts2pul ts2put ts3s4 4t1st4 t4stabe t2staf t4stag ts3tak t4stale t4s3tanz t4stas t4stat. t4s3täti t2stea t3stein ts4terb t3s4tern t3s4tero t4sth t3stif t3stim t4stit t4stoch t4stoi ts4tol t4ston t3strec t4stren t4strie ts2tu t5stub ts4tüm t4sty ts1u t2su. 5tsubi t2sumg t2sums t2sumv t2sumz t2s3un tswa2s t3sy 4t1t tt1ab tt2ac tt3achs tt1ad tt2ag tta6g5ess t4t1ah tta2ke tt2al t4tan4a t2tanm tt2ant t4t1ap tt1art tt3atr tt1äh tt1ebe tt1eif tt1ein t2t1eis tte4l1a2 tte4l3e4b tte4len tte4lin ttel1o ttels4t ttel5ste t2temu tte4na tten6sem t4tentb tten3te t4tentf t4tents tten3z t2teo tt4ere tt3erfo tte4rik tte2ro tt2erö tt4es1 tte4s3a2 tte4s3ä2 tte2so ttest4r tt2häu tt1hi t2t1ho t2ti4d t4t3igi t2tins tt2int t2tiso t6t3la t4torg t2trou tt3rü ttschi4 tts1eh tt2sen tts1p tt2spe tt2spr tt4s3tät tt2sum tt3s2z tt5t2 tt1u2f t3tü tt3z2 1tu 3tua tu4ale tu1alm tu1alv tu3ant 2tub2 tuba3b 3tuc tu2chi tu1cho 2tud tudie4n3 3tue tu2ere 2tuf tuf2e tu3fen t3u2fer 3tuff tu2gan 4tuh tuh4ler tu1ist tu2kr tul2i 3tum. tum2b5l 3tume 4t3umf 2t3umg 2t1umh 2t3umk 2tuml 3t2umo 2t3umr 4t3umsat 2t1umsc tum2si tum2so tum4s5tr 2t3umt 2t1umw 2t3umz 3tun. 2t1una 2t1und tund2e tun2en 2t3unf 3tung t3unga tung4s5 2tunif 2tu2nio 2tuniv 2t1unm 3tunn t1u2no t3uns 3tuns. 4t3unt 2t1unv 2t1up. t1upg tu2r1ag tu2ran turan4l tu2ras tu2rau tu2rä tur1c tu2r1e2b tu2rei tur3eis tu4rene tu2r1er tu4res tu2re4t tu2r3e2v tur3f4 tur3g2 tur1in1 tur4mun 3turn tu2r3o tu4ru 3tus tu2sa tu4schl tu2se tu2so tu3t2a tuto5 tuto3re 2tü 4tüb tü3ber. 3tüch tück2s 3tüf 4tüh 3tüm 3tür. tür1c 3türe 3türg 3tür3s 3türw 4türz 3tütc 3tüte 4tütz 4t1v2 t3vo tvoran4 4t3w4 t5wa2 twi4e t4wist 1ty 2t1ya 3typ ty2p1a ty1s2 2t1z t2za2 tz1ag tz3ar tz1au t2z1ä t3zäh tz1ec t2z1e2d tz1ehr t2z1eie t4z1eis tze2m tz1emi tze4n1 tz2ene tzen5s4t tzen3ta t4zentg t4zentl t4zents tze4reb tzer6gre tz1erw tz2er3z tz3erzi tze2s3 tz1e2t t2z1i2d tzi4m tz1imi tz1int tz1inv t2z3om t2zop tz2th tz4tin tzu2gu t2zuni tzwan4d3 tz1wä tz1wi t3zwie tz1wu 2ua u3a2b u3a2c ua2dan uad4r ua2g u1al. u1a2l1a u1a2l1ä u1alb u1ald u3aleb u3a4lent u3aler2 ua4lerg ual3erk u3a2let u1alf u1alg u1alh u3a2lid u1aln ua2l1o2 u1alp u1alr u1als u1al5t4 ua2lu u1alw u1alz u1am uan2a u1ans u3ar. uara2b u1ars uar4t3an ua3sa uasi1 ua2th uat2i uat2o u3au u1ay u1äm uä2s u1äu 2u1b u2barb ubb4l ube2be ube2e u2b1ehe u4b3eins u2b1e2m ube4n1a uben3o ub2er u4b3erde ubert4 ub4es ub1eul u3bit ub2l ub3läu ub3lic ub3lu ub4lut u2bob u2bop u2boz u2b3rit ub4rü ub2san ubsau2 ub4s3che ub2s1o ub2sp ubst2 ub3t2h 4uc uc1c uch1a u1cha. uch1ä u1che uch1ec u2ched uch1ei ucherin8t u3ches u1chi uch3im uch1in uch3l uch3m uch3n uch1op u2ch3r uch4sel uch2so uch2sp uch2ta uch3tan uch6t5erf uch6t5ert u1chu uch3ü uch1w u1ci uck3elf u2ckem u4ckent uck2er ucker8geb u2ck3i uck4sti u1cl 2u1d u3d4a uda3d ud2e ude3i4 udein7 ude2n1 uden3e uden3s2 udert4 udes2 udi3en uditi4 ud2o u3dob u2d3on ud3ra u3dru 4u1e ueb4l ue1ch ue2ck u2ed ue2en4 u2eg u2eh ue2ke u4ela ue2lek ueli4 uel2la u3eln ue2mi uen1 u3en. ue4n3a2 ue2nä u3end uene2 ue2neb ue2ner uen4gag uenge2 uenge4m uengene7 uenge4s uen2gl u3e2ni uenk4 ue2no uen6zene uen2zu u2ep ue2r3a2 uera4t ue2r1ä uerb2 uer6baut uer3d2 uere2 ue2rec u5ereinn uer3eis uer3ela u3eremp u3e4r3ent ue3r4erb u3ererf ue4rer4g uerer4h uerer4k uerer4m ue6rersc uerer6sp ue6rerst uer3esk ue2re4t u3erex uer3g2 uer4geb u3erh ueri2d ue2r1i4m u3erin4t u3erl. u3ern uer4nan uer4nar uer4ne uern3s4t ue2r3o4 uer2ö u3errü uer3sc uerst6 uer3t2 u3eruh u3erum u3erunf u3erunt uer3z2 ue2ta ue4tek ue2tik uety2 u2ev ue2x1 uf1ab u3fac ufa2ck u3fah u3fal ufall4 u3fam ufa2n uf3ane u2f3a2r u3fas uf1aß ufa2t uf1au u2f1än u2f1äs u2f1ä2ß u2f1ei ufel4s3a u2f1em 4ufen u3fen. u2fent u2ferf u2f1erh u4ferla u4ferle u4ferne u2f1et 2uff uf3fe uff4l uf2fro u2f1id u2fim u2f1ins uf3l u2fob ufo2r uf1ori uf3r uf5sä uf2spo uf4stab 2uft ufta2b uft1eb uft3erd uft3er4g ufter4l uft3s4 u2fum 2u1g ug2abe u4gabte ug1a2d ug1ak u2gana u2ganb u2gani u2g1ans u2gant ug1ap u2g1ar uga2s ug1au ug3d2 u3ge. u2g1ec ug1e2i u2geig u2gein uge4lob ug1emi ugene2 ugen3s2 u2g1erf u2g1erl u2gerr u2gerv u3ges. u2g1esk ug2et ugg2 ugge4st ug2gl ugg4t ug3hu u2g1i2d u2gim ug1in u2g1l u4glä u6gleitb u6gleitu u4glic u4glis ug3liz u4g3lo u4glu u4g3n ugo3 u2go4b ug3oc u3gon ugo4p ug1o4r u3gos u2gö u2g3rä u2greg u4g3reis u2gres u2g3rie ug3ro u2grou ug3rüs ug3span ug4spe ugs4por ug4spr ug4spu ugst2 ug3sta ug3stä ugs4to ug3s4tr ug3stu ug4stur ug3s4tü u2gum ugu3te u2gü u1h uh2a 2u3he uhe3a2 uhe1e2 uhe1s 2uhi 2uhl uh1la uh2lar uh1lä uh4l3ent uhl3erb uh2li uhl2ö 2uhm uhme2 uhr1a uhrei4s uh2r3er3 2uh3ri uh4rin uh2r3o uh2ru uh4rü uhs4 uh3t2 u2hu 2uhü uh1w 2ui ui2a ui1ch ui2che ui4cker u1idd u1ie ui1em u3ig u4ige uil4les u1im u3in. u3isch. u3ischs uis2e uisi4n uis3t uit3s u1j uji3 uk2a ukä2 uk1äh u3käu u1k2e uke2n1 u1ki u1k2l ukle1 uk4n u2k1ob uko2m1 ukom3a uk2ö u1k4r uk2ta uk2t1el uk4tent uk2t1er uk2tin uk4t3o4ri uk4t3r uk2tum u1ku uku2s uk2ü u1l ul1am ulan2e ul2ar ula2s ul1äm ulb4l ul4dan ul2dr uld2se 2ule u2l1el ul1emb ule4n ul1er2h ules3t ule2t ul1eta 2ul3f4 ulg4 2uli ul1id uli2k ul1ins uli1p ul3ka ul2kn ull1au ul3len ul3l2i ul2lo ull3s2 ulm2e ulni2 ulo2i u2lop u2l1or ulp1h ul2pha ul2sa ul4sam ul2s1ec ul2sei ul2ser uls2th ul2sum 4ult2a ul3tan ult3ar ul2tau ulter4m ul3ti ul4tri ult3s u2lü ul2vr ulz2w 2uma. u2maa3 u2mab u2m1ad u2m1a2k um1all um1ang um1anz u2m1ap um1ar u2marc u2marm u2mart u2matl u2matm um1aus u2maut u2m1äh 1umd2 u3me. u2m1ef u2m1ein ume2n1e um5engel umer2a u2m1erf um1erg u3merk u2m1erl um1erw umes2t 1umf 4umfi 1umg um1ind um1inh um1ir umi2t um1ite 1umk 1uml 2umme um2mei um3mi um1ob u3mol um3ot ump2fa ump4fin umpf4li um2pho 1umr um4s3an 1umsat um4s1er um2sim um4sk um2s1pe um2sum um3t2 u2mum u2m1u2r 1umz un1 4un. 2una. 1unab un2a3br un2ag un2al u3n2am u2n3an u2nap u2narb 2un2a1s4 un3at un2är 2und. un2da unda2b un2dän 1undd 2unde un3de. underer6 und3erf und3erö underten8 under8tend und3erz un2dex 1undf 2undg un2did un2dim 1undn undo2b un2dop un2dor 4un2d3r und3s 4unds. 2undsc un2d1um undü4 1undv 1undz u3ne2 un3eid un3ein un2emi une4n1 unen2t une3re une3ri u4nerk u4n3erz. un2es4 unf2 un3fa unft4s un2gab un2gam un2gat 3ungena unger4e 1unget 1ungew ung5h 1ungl un2glu un2go un2gr ung3ri ungs3 ung4sa ungs5tr u3nic un2id un3ide 4unie 3u2nif uni3k4 un2im 1unio un2ir un3iro un3isl u3n2it 1u2niv 2unk un2k1a2 un3ker un2k1es un2ket un2kne un2ko2p un2kro unk3s2 unk4tit unk2tr unlö2 unna2 un4n1ad unn2e unne4n u2nob uno4r un2os 1unr uns2 2uns. unsch5el un3se 1un3si un3sk un4ski un3sp unsta4g unste4c uns4t1r 4unsy 4unsz 1unt un3ta un3te unte4ri 4unti un3tr unt3s 2untu 3unty 2u2nu u3nuc unvol2 unvoll3 1unw 4unwä 3unwe u2ny 2unz un3z2a unz2e 2uo u1o2b u3of u1or u3or. uo2r3a uor3c u3oret uo2ris u3ors uor5t uos2 u1os. uote2 u1ox uö2d u1ök u1pa 3upd u1pe2 uper1 uperer4 up2fa u2pfe2 u2pfi up2fu u3p4i up4lu u3po 2upp up2pl u1pr upra3 u2p3ras up4t3a2 upten1 up4tene upt3erf upt3erg upt3erk upt3ers up4tin up4t1o up4tr u1q 4ur. u1ra u2rab u3raba ura2be u2r1akt u2ral4t u2r1am ura4na u3rand uran6fän ur1ang uran4ge ur2anh uran5s ur1anz ur3ap u2r3ar ura4ri u3rasc ur1asp ura4str ur4ate u2r1att ur1au 2u1rä ur1äl ur1ä2m ur1än ur3b2a 2urc urch1 urcht3e urd2 ur3da ur3di ure1e ur1eff ur1eig u2rele ure2n ure4na u4ren4se u4rentn u2r1ep urer3h urer3k ur2ert u2rerw ur1eta ur2e3th ure3u 2urf ur2f3l ur2fro urf4spr urf3t ur6gense urg3inn urg1l ur2gla ur2gri urgros4 urg1s4 uri2c ur1ide uri3en u2r1ind urin6sek urin8stin u2ri2so ur3ku ur3l ur4matt ur2m1au urm2ei ur4mern urmet1 ur2mum ur2mun ur3n2e 2u1ro urob2l ur1off uroh2 uro1s4 urost2 2u1rö ur3p4 2urr ur3re ur2rh 3ursac ur2san ursau4 ur2s1er ur4s1of ur2spa ur3sze urt2 2urta ur2tai urt3ein ur2tro urts2c u3ru uruf4 urü2 ur2z1a2 ur2zä ur2z1ec ur2zep ur2zi ur2z1op urzt4 ur2z1w 2us us3a2b usa2gi u4s1amb u4samt u2sang us2ann us3ark usa2s3 us1ast u2säh u2s1äs u4schab u4schak u3sche. u4schef usch5eic u4sch3eu u3schi usch3mü u3schu usch5wer u3s2e3b u2s1ec use2ei u2s1ei u4sen4se u4sentl u3sep use4rec u2s1erl u2serp us1erw u2s1ese u2sex u2sid usi3er. usi5ers. u3sik usi4kat us1inn us3kl us3oc us1oh u3sol u2sop us1orc us1ou u2spac us3part u2s1pas u3spec u3spek u2sph us1pic u3spit u3s4piz u2spo us2por u2spu usrich7 us2s1ad us2s3eb usse4g usse4n us2sep us5ser. uss3erf usser4z us4sesp us2sez uss3k us2sof us2sum u1stad u1stal us3tau us4tein u1stel ust3erl us2th us3ther us3tin us3tr us4tras us6tris u1stu u2stun u2stur u2sumd u2sumg u2sumz u3sur 3usus u2sü 2uß uß1u 2u1t 4ut. u3taf u2t1alt u4t1a2m ut2ans u2t1ap u2t1ar uta2s u2taut ut1äh u2tär ut3c ut1e2d u3teh ut1ei. ut1eie ut1ein u3tek ut1ela u3tem ute2n1 uten2a u2tent u4tentf utera2 ute4ral ute5r4er ute6ring uter3k ute4ros ut2es ut2et u2t2ev u2t1ex utfi2 ut3hal ut3hei ut1hel u2t1hi u2t1ho u2thu u2t1id u4tigel uti2vi utli4n uto3c u5to3m uto1p uto3pa u2tops utor2a u4tord uto2re uto4rin uto3s2 4utou u2töl 4utr ut3rea u2trou ut3rü 4uts utsau2 ut2säu ut4schl ut4schm ut4scho ut4schö ut3ser ut3s2k uts2p ut3sta utt4er ut5t2l utts2 utu2b u2tum utu4n u2t1une utu4re utu3ro utu5ru u3tü u6tz ut2zeh utz3eng utz2er ut2zet ut2z1in ut2zis ut2zö ut2z1w 2u1u4 uufe2 uum1 uuma4 uume2 u1ü2 2u1v4 u2ve. uve3rä u1w 2u1x ux2e ux2o ux3oe ux3t4 u1y u2yo 2u1z uze2 u2z1ec u2z1ene uz2er uzo2f uz3ot uz1we uz3z2 1üb üb1ä 2übc 2übd übe2 übe3c übe3le übe4na übe3ne über1 ü4bet üb3l üb5r üb2s3t 2üc ü1che üch3l üch2s1c ücht4e ü3cke4n ück1er ück3eri ücker6ke ü4ckers ü2ckin ü2ckum ü4d3a4 üde2c üde2l ü3den. üden2g ü3d2ens üd3o4 üd3r üd3s2 üd3t4 üdu2 üe2 üeb3 ü1ei 2üf ü2f1a ü2f1ä ü2f1ei ü2fent üfer2 ü2f1erg üf2fl ü2f1i üf3l ü2fo ü2fum ü1g üg2e üge2l1a2 üge2lä üge4lec üge6lei6s üge2lo ügen3s ü2g3l ü2gn üg3s2 üg4s3t üh3a2 ü1he ü2h1ei ü2h3e4m ü3hem. ü2h1eng ü2h1ent ü2h1erf ü2h1er2k ü2h1er2z ü2hex üh1i4 ühla2 üh1lä üh2lel ühl2er üh2lö ühl4sk ühl4sta ühl4sti üh3mo üh3ne ühn2s üh1o2 üh3r2e ühr3ei. ühre2n1 ühren3s4 üh1ro ühr3ta üh1s ühs2p üh3t üht2a üht4r ü1hu üh1w ü1k2 ül1a ül2c ü3l2e ü4l3ef üle2r3a2 ül2l1a2 ül2l1ei üll2er ül2lid ül2lo ül2lö ülls2 ü2lö ü1lu ü2ma ü2ment üme2ra ü2m1id ü2m1in ü2m1u 2ün ü4n3a2 ün2da ün2dr ünd3s ü2n1erd ünf1 ünf3li ün2g3l ün2s ün3sc ün3se ün3sp ün3sta ünster3 ün3str ün2za ün2z1i ünzu2 ün2zun ün2zw ü1pe üpf3l ü1pi üp2pl 2ür ür1a ü2r1ei ü2r1e2l ür2f1er ür2fl ür2fr ür4g3en4g ürge4ra ürk2e ü3r2o3 ürom2 üror2 ürr2 ür2s ür3sc ür3se ür3si ür3sp ür3sta ürte2l3 ürt2h ür2z1in ür2zö ür2z1w üs2a ü2schl ü3s2e üse1e2 üse3l2 üse4n üse3r4 üse1s üs4s3a üs2s1c üss2e üs4s3o üs2st üst3a üste2n 2ü1ß 2üt ü2t1al üte3m üte4n üten3s ütent4 üten3z2 üte2ra üte2r1e üterich6 üter3n ü2t1h ü2t3r üt2se üt2st ütte4n üt2tr üt3zen üt2zw ü1v ü1z 3va. 2v1ab vab4r va1c va1f4 va3g vag2a va4gh va2la 2valu v2an. 2vanb 2vang v2ans 2varb v1arm vas2 2v1ass va1st v4at va2t1a4 va6tag va4tan va2tei va4t3eng va4tess va2t3h va4tid vati3k2 va4tim va4t1in vati8ons. va4tord va4t3r vat3s4 va2t1u 2v1au 2v1b 2v1c 2v1d2 1ve2 ve3an ve3ar veau3 veau1s ve3b4 ve3d ve3fa ve3g ve3h2 2veig v2eil 2vein veit2 veits3 ve3la 2velan vel2ar ve4l1au v1ele ve3lei ve3l2i ve3lo vel2o1p ve3ma ve3me 2v1emp 2vemu ve3nal ve4nas ven2c ve3ne ve3ni ve4nin ve3nö ven6t3ag vent4sk 2veo ve3of ve4pi ver1 ver3a ve3rad 2veral ve3rand ve3r4ane vera4s ver6bart ver3b2l ver3d2 vere2 verf4 ver3g4 ve3ri ve4rin ver3k vern2 ver4sep vert4 ver5te ver3u4 ve3rus ves1 ve3sa 2ve3s2c 2ve3s2e ves3ti ve3ta vete1 vete3r ve3ti ve3tr ve3t2s 2veü ve3v ve3w 2v1f4 2v1g 2v1h vi1an vi3ar vi4a3t vi2ä vi2c vi3de vid3s2t 3vie vie2h1a vi2el viela2 viele2 vi2er vie4rec vie2w1 vig2 2vii v2il vi2l1a vi2lä vi4l1e2h vi2lei viler4 vi4lers vi2l1in vi2ma2 vi4na vin3d ving3 vings4 v1ins vi3sa vise4 vi3s2i vi3s2o vi2sp vis2u viv2 viz2 vize5 2v1k 2v1l4 v3le v2lie 2v1m vm2e 2v1n2 1vo 2v1ob vo2be vob4l voge2l3 vo2gu vol2a vol4l1a vollen6 vol6lend vol6ler6t vol2li 2v1op vo2r1 vo4r3a voran8schl vor3g vo3ri vo4rie vo5rig vorm2 vormen4 vor3o vort4 vot2a voy1 vö2c 2v1p vr2 v1ra v2ree 3v2ri 2vs vs2c vs2e vs2p v1sta v1steu v3s2z 2v1t vue3 vu2enu vu2et 2vumf 2vumg 2vumk v1ü 2v1v 2v1w 2v1z w2a 1waa wab2bl wa3che wach8stub wach4t4r 1wack waffe2 waffel3 1wag wa5ge 3wage4n wa2g3n wa3go 1wah wahl5ent wah4ler wah2l1i 1wal wa2lar 2walb wal4d3a wal4din wal2dr wa2les wa3li wal2m1 wals2 walt1a wal6tere wal6terl wal4to wal4tur 3walz wa3na wan2d1a2 wandels6 wan2dr w3anf 2wang wan3g2e wang4s 1wann wan6z5en6d wan4zer wa2p 1war2e ware1i wa5ren 1warn war4ni wart4e war2th war2za 1was wa3sa was2c wa4scha wa3sche wa4sch3l wa4schw wa3se wa3sh was3s wass4e2 wa3su w2ä 1wäh 1wäl 2wäng 1wäs wäs2c wäss4e 2w3äu 2w1b2 wbu2 2w1c 2w1d we2a we2b1a webe1i we2b3l we2bo we2b3r webs2c we3cke. we5cken. we3ckes we2e2 weed3 we2fl 1weg we2g1a we4g1ei weg5ersc we4g3l we4gn we2g1o2 we4g3r weg3s2 wegs4t 1weh weh4r3er4 wei2bl weib4r 2weie weifel6d wei4fre wei2gr weigs4 wei3k4 3weil weinsau6 wei3sc weis6sel weis6spi wei2t1r wei5ze wel5le4 wel6schl wel6schr wel2t1 wel4t3a2 welte4 wel6t5en6d wel4th welt3i wel4to wel6t3r wen3a2 wendes4 wen2gl we3n2i wen2ka wen4kla wen4k3ri we2r3a2 wer5be werbe3i wer2bl werb2s 1werbu wer3d2 5werdens 1werdu werer2 wer2fl 2werg wer2ga wer6gels wer2g3o wer2gr werin2 we3rins we2ri4o 1werk. wer2k1a 1werke wer2ki wer2k3l wer2kn wer2k3o wer4k3re wer2ku we2rö wer2s wer3sp wer2t1a wer2tä wert3ei wer6teig wer6t5erm wer2th wer4tin wer4t1o2 wer4tre wer6t3ri wer4tum 1wes2e we2sp we4st wes4t1a weste2 west3ei wes6ten6d wes4tex wes2ti wes4t1o2 wes4t3r wes4tu 1wet 2wets wett3s 2w3ey 2w1f 2w1g whi4 w3ho w2i wicht4s wi1cka 1wid wi2e 2wieb 1wied wie3l wie3n2e wik2 1wild wim2ma wim6ment wim4m3u win2a win4d3e4c win3del win6d5erz 1win2d3r 2wing win2g3r win2kl win8n7er8sc win2no win3s wint2 1wi4r wire3 wi5s2e wi2sp 1wiss wiss4z wi3th 1witz. 1witzl wiz2 2w1k 2w1l 2w1m 2wn wns2a wn3sh 1wo1c wo2cha woch2e4 1woh woh4lei woh4na 1wolf wolf2s3 wol2la wol4ler wor3a wor3d wo4r3i worn2 wort1a wor4tel wor6terh wor4t3r wort3s2 wo4r3u wor3ü 3wos wot2 1wöc wöl2fo wört2h 2w1p w2r w3re w3ro 2w1s ws2e w3s2h w3s2k ws2t w4s1u 2w1t wti2 w2u 1wuc wuch4sc wuch4st w3u2f wul2 wul3se wund4e wung3r wungs4 wun2s wunsch5l 4wur. wur2fa wur2f1o wur2fr wur2s 1wurst wus2 wus3te 1wu4t1 1wüh wül2 wün3 1würf 1würst 2w1w 2w1z x1a 1xa. 2xa2b 1x2ac 1x2ad 1xae xa1fl 1x2a3g2 2xal xal2l xa2m 1xane 1xani x2an3t2 x2anz xa2r 1x2as xa2z 2x1b4 x1ce x1ch x1cl 4x1d xda4 xdy2 1xe 3xe. 2x1e4g 2xek xe2l 3xel. x1ele xe3lei x1em 3x2em. 2xemp x2ems x2en 3xen. xen3s2 3x2er. x2ere 2x1erl xer2la x2ern xers2 x2ers. 3xes 2x1eu 2x1ex 2x1f 2x1g 2x1h xi1c xich2 2xid xi2dan xide2 xi2dei xi2d3em x1i2do 3x2ie xie3l xi3g xi2ler xili3a xi2lo xi2l1u xim2 xin3s2 x2is xi2sa xi2s1e xi2sp xis3s2 xis3t xis4tä xi2su 3xit xi3te x1i4tu xive4 x1j 4x1k2 xkal2 4x2l2 x3lä x3le 2x1m 2x1n 2xod 2xoe4 x1o2r xos2 2x1ö2 4x1p xpor6ter xpor4t3r x1q x1r 2x3s2 4x1t xt1a xta2b3 x3tan xt2ant x3tas x2t1ä x3tät xtblo4 xtblock5 x2t1e2d xt1ein x2t1el x4tent x2t1er2f x2t1ev xtfi2 x2t1h x2t1id xti2la x2til2l x2t1o4 x4tor xtra3b4 x2t3ran x2trau xt3rec xt3s2 x2t1um x2t1un 1xu xu1a xu2n 2xunt xu2s3 xusa2 xuss4 2xv 2x1w 3xy. x1z 2y1ab 1ya2c y2ach ya1h y1al. yan2g y1ank ya1q ya3ra yas2 yas3t y1ät y1b ybe2r y1c y2chi y3chis ych3n y1d yd2o ydri2 ydrid3 ydro3 y1e y2ec ye2d y2ef y2el2 yen4n yera2 y2ere yer2n1 y2es y4es. yes2p ye2th y1f2 y1g ygi2 ygie3 yg2l y1h y3ho yhr2 2y1i4 y1j y1k2 yke3n yk4l yk3s2 yl1a2 yl2a3g y1l2ak yla4l y2lam yl3ane y1lant yl4ante yl4anti yl2as ylau2 yl3c yle2 y2le. yl1em y2l1es3 y2l1e4t yli4n ylo1i2 yloid3 yloni1 yl2op yl1ora yl3s2 yl5t ym2a ym4an ym4ar ym4as ym4e ymp4 ym2pha ympi1e ynä4r yn2eu ynk2 y2n1o2 yno4t yn2oz yn3t2 yob2 y2od yoga3 yom2 yon2a y1ont yo2pe yo1s y2ost y1ou 2y1p ypa2b3 ypa2n yp2e2 ype4r3o2 y2pf y2p1i2d y2p1in y2plo y3po3 y4p3s yp3th ypu2 y2p1um y1q y1r y3r2e y3ri yri1e yri3en y3ro yros3t yrr2 2ys ys2an ysch4 ys2e1 ysein2 y4s3l ysme3 ys2po ys1pr yst2e yst2h ys2the ys3to ys3tr ys4tra y4stro y3s2ty ysu2 y2s1ur y3s2z y1t y2te. y2tes yt2h ythe1 y3to1 ytos2 y4t3r yu2r yur2e3 y1v y1w y1y y1z2 yze3r2i 2z1a2b zab3l za1c 2z1ach zach2s 2z1a2d 2z1af za3gr 3z2ah zah3len zah4ner4 z1ak 4z3akk 2z1al 4z3ald 3zali 2z1a2m z1a2n 4z3a4n4a 2z3anb za3ne 2z3anf 2z3angs 3z2ank zan2ka z3anl 2z3anr zanti1 za4pf z1aq z1ar 3zar. 2zarb za3re 2zarm 3z2aro z2arr zar2t1r 2z1as za2sc zast4 z3at zat2e za2to 3zaub 2z1au2f 2z3aug 3zaun z3aur 2z1aut zä2 2z1äc z2äh zä3hi 3zähn 2z1äm z1än z1äp z1är 2z1äus 2zäuß 4z3b4 zber2e zbü1b zbübe3 2z3c 2z3d2 zdan2 zdä1 zdi1st 3ze. 2zea 2z1e2ben ze1c 2z1e2cho ze1e2 zeeu3 2z1eff z1e2ga zehe4 zehen1 zeh2l ze3ho zei1f4 zeik4 zeil2 zei3la zeile4 2z1ein ze3in. z2e1ind zei4ne 4z3einh ze3inse ze2i1s4 zei3sk 3zeit zei2t1a zei4t3er zei4to zei2tr zeit3ri zek4 ze2l1a zela2d zel3a2n ze2l1ä zel3d4 4ze2lek 4zelem ze2len ze2l1er ze2l1in 2z1e2lit zel3la zel4lab zel4l3ac zel4lar zel6lein zel6ler6t zeller6z zell3s2 zelm4 ze2l1o zels2 zel3sa zel3sz zel2ti zembe2 2z1emp 5zen. ze4n1ac ze4nas zen3au ze2nä ze3n2em zenen1 4zenge. z4engl 2zengp 2zeni ze2nid zenk2 zen3n ze2n3o ze4not 4zen4sem zen4ser zens2p z2entn z1ents 2zentw 2zentz zen4z3er zen2zw zeo4r 3z2er. ze2rad ze1ral ze2rat z2ere ze5rek zer2em z2erfe z3erfül 2z1ergä 4z3ergeb z4erges z4ergl zer4gon 4z1ergu 3z2erhe 2z3erhö zerin6te z2erko 3zerl. zer4lau zer4le. 4zerleb zer4len 2zerlö 3z2ern zer4nan zer4n3e4b zer4nei 2z1erö zer2öf 2z1erq 4z3erreg zers2 z2ers. 2z1er4sa zerta2 zer4t3ag zert4an zer6teng zer6tere zer6terl zer4tin zer2to 6z5ertrag zer6trau z1erwe 4zerwei z1erz zer2ze 3z2es. ze2sä ze3sch zes1e ze2sp ze4spo zes2sa zessen4 zes6s5end zes6sent zes4ser4 zes2sp zes2st ze1sta ze3stau ze1str z2et. 2zeta 2ze2th ze2tr 2zetts zeu4gem zeu2g3r 2z1eul ze1ur 2z1e2x1 4z3f4 zfeue2 2z3g4 zger2a zger4s3 2z1h2 z2hen zhir3 zi3alo zi2ar zich2o zi2dei zie4ler zie2l1i zien3s zi1erh zi1es zi3ess zig4s z2il zil2e 2zimp zim4t3 2z1ind zin2e zin3ei 2z1inf z1inh zi4n3in zin1it 2z1inj zin4na zin4o zin2sa zin4ser 4zinsuf 2zint zi2o3 zirk2 zirk6s z1iso zi2sp zisse4 zi3s2z zi1th zithe2 zi4t1o2 zit2u ziv2 2z1j 4z1k4 2z1l2 zlei3ti zle1s z3ly 2z3m2 zme2e 2z3n2 z3oas 2z1ob 2z1of zo2gl zog4s3 2z1oh zol2la zoller4 zol6lerl zol6lert zonal2 zon3au zon5s4 zon4t3er zo2o 2zope 2z1o2r zo3re 3z2orn zor4ne 2z1osz 2z1ou 2z1o2z 2zö2f 2z1ök z1öl 2zöl. 3z2öll 2zöls 2zön 4z3p4 2z1q 4z3r2 2z1s4 z3sa zsau2 z3sh z3sk zspor2 4zst2 z3sz 2z1t zta2n zt3ane z2t1au z4tehe ztein1 zt3eins zt2el zte3ma z4t1ent z4t1erz zte3str zt2et zt1he z3them z3t2her zt1hi zt3ho z3thr z3thy z3ti zt3rec zt3ric zt3s2 z3tü zu1 zu3a zub4 3zuc zuch2e zucht3r zud4 zudi4 zu2el zu3e2r1 zue2t zu3f4 zug2em zu4gent zug2i zu3gl zu4gla zu4glö zu2go 2z1uhr zu3hu zui2 zu3k zul2 2z1um. zum2a 2z1umb zumen2 2zumf 2zumg zum2i 2zumk 2zuml 2zumr 2z1ums zum2u 2zunab zun2e 2z1unem zunf4 zung4 4zunget 2zungl z1uni 2zu2nio 2zuniv 2zunr 2z1uns 2zunt zuo2 zup2fi zu3pl zu3r2a 2z1urk 2z1url 2z1urn 2z1urs 2z1urt zu3s4 zusch4 zu5t2 zut4r zut4u zut3z zuz2 2zü4b 3züc zür1c 2z1v zw2 z1wac 2zwag 4zwah 4zwap z1war 2zwa2s 2zwäs 2z1wed 2zweg 2zweh z2weig 2zweil zweiter6 2z1wel 2z1wen 2z1wer 2z1wes z2wic zwi4e 3zwing 2zwirt z2wisc 2zwiss z2wit 2z1wo z1wör z1wur 2z1wü zy1an. zy2le 2z1z z3z2a zza3b4 z4z3al zz4at z2z1id z2z1in1 zzi1s4 zz2ö zzug4s", ["lefthyphenmin"]=1, - ["length"]=101488, - ["n"]=15207, + ["length"]=169219, + ["n"]=24536, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/patterns/mkiv/lang-deo.lua b/tex/context/patterns/mkiv/lang-deo.lua index 4e437f839..46516245a 100644 --- a/tex/context/patterns/mkiv/lang-deo.lua +++ b/tex/context/patterns/mkiv/lang-deo.lua @@ -6,24 +6,65 @@ return { ["metadata"]={ ["mnemonic"]="deo", ["source"]="hyph-de-1901", - ["texcomment"]="% dehypht-x-2014-05-21.pat\ -% \ -% \\message{German Hyphenation Patterns (Traditional Orthography) `dehypht-x' 2014-05-21 (WL)}\ -% \ -% TeX-Trennmuster für die traditionelle deutsche Rechtschreibung\ + ["texcomment"]="% title: German Hyphenation Patterns (Traditional Orthography)\ +%\ +% notice: TeX-Trennmuster für die traditionelle deutsche Rechtschreibung\ +%\ +% version: 2018-03-31\ +%\ +% authors:\ +% -\ +% name: Deutschsprachige Trennmustermannschaft\ +% contact: trennmuster@dante.de\ %\ +% copyright: Copyright (c) 2013-2018\ +% Stephan Hennig, Werner Lemberg, Günter Milde,\ +% Sander van Geloven, Georg Pfeiffer, Gisbert W. Selke,\ +% Tobias Wendorf\ %\ -% Copyright (C) 2008, 2009, 2011, 2012, 2013, 2014 Werner Lemberg \ +% licence:\ +% name: MIT\ +% url: http://opensource.org/licenses/mit-license.php\ +% text: >\ +% Permission is hereby granted, free of charge, to any person\ +% obtaining a copy of this software and associated documentation\ +% files (the “Software”), to deal in the Software without\ +% restriction, including without limitation the rights to use,\ +% copy, modify, merge, publish, distribute, sublicense, and/or\ +% sell copies of the Software, and to permit persons to whom the\ +% Software is furnished to do so, subject to the following\ +% conditions:\ %\ -% This program can be redistributed and/or modified under the terms\ -% of the LaTeX Project Public License Distributed from CTAN\ -% archives in directory macros/latex/base/lppl.txt; either\ -% version 1 of the License, or any later version.\ +% The above copyright notice and this permission notice shall be\ +% included in all copies or substantial portions of the Software.\ %\ +% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,\ +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\ +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\ +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\ +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\ +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\ +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\ +% OTHER DEALINGS IN THE SOFTWARE.\ %\ -% The word list is available from\ +% source: http://repo.or.cz/w/wortliste.git?a=commit;h=8b9a428c271e064f0047a364c532308f0fd4051f\ %\ -% http://repo.or.cz/w/wortliste.git?a=commit;h=3a97953c0ddd099a1785ea7927cbf24e639090b0\ +% language:\ +% name: German, traditional spelling\ +% tag: de-1901\ +%\ +% hyphenmins:\ +% generation:\ +% left: 2\ +% right: 2\ +% typesetting:\ +% left: 2\ +% right: 2\ +%\ +% ===========================================================================\ +% \ +% \\message{German Hyphenation Patterns (Traditional Orthography) `dehypht-x' 2018-03-31 (WL)}\ +% \ %\ % The used patgen parameters are\ %\ @@ -40,10 +81,10 @@ return { }, ["patterns"]={ ["characters"]="abcdefghijklmnopqrstuvwxyzßàáâäçèéêëíñóôöü", - ["data"]=".ab1a .ab3l .abo2 .ab3ol .ab1or .ack2 .ag2a .ag4r .ag2u .ai2s .akt2a .al2e .al3k .al5l4en .al4tei .alt3s .ampe4 .amt4s1 .an3d2 .anden6k .and4ri .ang2 .an3gli .ang4s2 .angst3 .an3s2 .an4si. .an4tag .an3th .an3z2 .aos4 .ap5p6le. .aps2 .ari1e .ark2a .ar4m3ac .ar2sc .ar4t3ei .arter4 .ar6t5erh .as6sest .as2t .ata1 .at4h .au3d .au4f3 .aufs2 .au2s1 .ausch3 .au6stes .ax2 .äm3 .är6schl .ät2s .äu3 .be3erb .be3r2a .be3r2e .berg3a .ber6gab .ber6g5e6b .ber4gl .ber4g3r .boge2 .bo4s3k .bu4ser .bus3se .bu7s8ser. .ch2 .chi3er .dab4 .da2r1 .da4rin .dar2m1 .da4te. .da4tes .de2al .de1i .de4in. .de8ments .de1o2 .de3r4en .derma3 .dermas6 .de3sk .dien2 .do2mo .do1pe .dorf1 .dü1b .ebe2r1 .ehe1i .ei4ds .ei3e2 .ei4na .einen6g .ei2sp .ei4s1t .ei2tr .eke2 .el2a .el2bi .em3m2 .en1 .en4d3er .en5der. .en2d3r .en2gl .enn2 .en2t3 .epi1 .ep3p .er8brecht .er2bu .er2da .er4dan .er4dar .er4dei .erden6k .er4der .er1e .ere3c .erf4 .er1i .ers2 .er8stein .erster6 .er8sterb .er8stritt. .er8stritten. .er4zen4 .esel4s .es3p .es2st .es2t .est4e .est2h .et2s .eu1 .eu3g4 .eu3t .eve4r .ext4 .fe4i .fer4no .fe4sta .fid2 .fi4le. .fi4len .fi2s .flö8s7se. .flö8s7sen. .flö8sses .fs4 .fu2sc .ga2t .gd2 .geb2l .gel2d1 .ge5nar .ge3n2e .ge3r2a .ge3r2e .ge3s2 .get4 .ge3u .grif8fes .guss1 .haft3s .hal2s .hau2t1 .he2 .he3fe .her3an .he3ri .he6r5inn .hi4n .hin3u .ho4met .ia2 .il3 .im2a .ima4ge .im5m2 .in1 .in3e .in3gl .ink4 .inn2e .inu1 .ioni1 .ire3 .is2a .ka2b5l .ka2i .kamp2 .ka4t3io .ken6num .ker3s .ki4e .kle4i .kopf1 .ks2 .kus2 .le4ar .lich8t7er8s .li2f .li4ve. .lo4g3in .lo3ver .lö4ss .lös3se .lu4str .ma3d .ma3la .mal4e .ma4str .md2 .mel2a .me3no .men8schl .men8schw .men3t4 .mi2t .mi4ti .mm2 .näs5c .ni2e .nob4 .no2c .no2s .no4th .nul2 .nus2 .ob1a .obe2 .ohr5s .oper4 .or2a .ort2 .orts3e .ort4st .os5t6alg .oste2 .ost5end .osten8de .oste6re .ost3r .ozo4 .öl3l .pa4r1e .par3t4h .pe2c .pe4ste .pf4 .ph2 .poka2 .po4str .ps2 .rabe4 .ra3me .ra4sp .ra4s3s .reb3s2 .re3cha .rein4t .reli1 .reli3e .ri2as .rich5te .ro4a .ro3m4a .rö2s1c .rö4ss .rös3se .runder6 .ru5s6ses .rü1b .rücker6 .rü4ss .sali1 .sami3 .sas2 .sa3sse .säs4 .sch4 .scho7s8se. .scho7s8ses. .sen3s .ser2u .se2t1 .sha2 .si2te .ski1e .spas4 .spä5s4 .spiege8lei .st6 .sto4re .stras4 .sucher6 .tan4k3l .ta2to .te2e .te2f .te3no .th4 .ti2a .tid1 .ti2e .ti4me. .ti4mes .ti2s .to4nin .to4pl .to2w .tras3 .tra4ss .tri3e4s .ts2 .tu3ri .uf2e2 .ufer1 .um3 .umo2 .ums2 .un3a2 .un3d .une4 .un3g .uni2t .ur1 .ural4 .ur2i .urin4s .ur3o2m .uro2p .ur3s2 .ut2a .ut3r .übe4 .ve5n2e .vi2e .vo4r .wah4l .wa2s .weg5s .welter8e .welter8k .wi4e .wor2 .wort5en6 .xe3 .ya4l .zeit3s .zel4la4 .zelle4 .zel6lei .zi2e .zin4st .zol2 a1ab aa2be aa1c aa2gr 2a1a2n 2a2ar aa2r1a aar3f4 aar3k4 aar5sc aas1t aa2th aa2t3r aat4s1 2a3au a1ä a1b 2aba ab1auf ab1ä ab2äu 1abd ab1eb abe1e ab1eil 4abel abe2la a3beri ab1er2k ab1er2r ab1er2z ab3esse abes2t ab1eß 2abet 2abew 1abf 3abfi 1abg 1abh 2abi ab1ins ab1ir ab1it 1abk ab1l 1a2bla 1a2blä 2able ab4le. ab3li ab4lo 3a2blö a2blu abma3s 1abn a2bo. ab2of 1a2bon 2abor ab3r a3bra a4brä 2abrü 1abs 2abs. abs2a 2absar ab3s2i ab3s2p abs4t2 2abst. ab3sz 1abtei 2a3bu ab1ur 2abü 1abw 2aby 1abz 2aca 2ac1c a1cem 2ach. ach1a a1chal ach3au 2achb 2a1che a2ch1e2c ach1ei a4cherf a4cherk a4cherö a4ch3erw a1chi ach3l ach3m ach3n a1cho a3cho. ach1o2b ach1or ach3ö ach3r ach3s2i ach3su a4cht acht7ersc ach2t1o ach8traum ach8träume. ach8träumen. ach6trit a1chu ach1u2f ach3ü 2achv 2ach1w a1ci ac1in 2ack. ackmu4 ackmus3 ack2se ack3sl ack3sta4 a1cl a3co acon4n 2acu a1ç a1d 2ada. a3d2ab ad2ag adai4 ada2m ad3ama a2d1an 3a4dap a3d2ar3 4adav 1a2dä ad1c 1add 2ade. ade2al adefi4 a2dein 2aden ade1r2a a2deri 4ades2 ade3sp ades6s 2adf 2adh 4a3di adi3en 5adj 2ado ad2ob 2adp 2adq 2ad3rec ad4res 2ads2 ad3sz ad2t1 adta2 2adu 2a1e1 ae2b a3e2d a3e2i a2ek a3el. a2ela a2ele a2eli a3els ae2o3 a3e2p 3a2er2o ae4sc a2et a2ew ae2x af1a a2fak a2fan a3far af4at a2fau4 2afe a2f1ec a2fent af1erl a2fex af2fei af2f3l af4flu 2afi 2af3l a2fö af3ra af3rä af3re af3rö af3s2a af2sp 2aft af2t1a af2tei af4t3erl af2t1o af2t3r aft5re af2tur a2f3ur a1g 2aga ag1a2b ag1a2d ag1am ag1ar ag1au ag2di ag2du 2age. age1i age4na age4neb a2gent a4gentu ag2er age4ral 2ages age2sa age4sel age4si age2s3p ages5s ag3esse age6stem ag3gl 3aggr 3a2git 2a2gl ag4la a4glö ag2n a2gna ag4ne. ag4nu a2g3re a2g3ri ag4ro agsa2 ag3sah ag4sam ag3sc ags3p ag6spo ag4sti ag2s1tr 2agt ag2th a2gund 2ah. 2a1ha ah4at 2a1he ahe1in a2h1erh a1h2i ahin3 ahl3a4 ah4l1ei ah4l3erh ah2lö ahl3sz ah4n1a ahner4e ahnt2 1ahor ah1o2s a2h3ö ahr1a ah3re ahre4s3 ah3ri ahrta4 ahr4tri ah2ta aht3h ah2t5r aht1s a1hu ah1w a1hy 2ai ai3a4 aian3 aid4s aids1t ai1e2 aif4 ai1fr ai3g4 a3ik. ai3ke aik4r ai2lo aim2o ain2a a1ind ain4e a1ing ain3sp 3airb ai2sa a3isch. ai3s2e aiss2 ais3sen ais5st ait4 a3iv. a3ivl a3ivs a1j ajekt4o 2ak. 1a2k4ad 2akal 2a3kam 2akar ak4at 1a2kaz 2akb 2akc 2akd 2a1ke a2kef aken2n a2keu 2a1ki 2ak3l ak4li 4ako 2a1kr ak3rau 3akro3 2aks ak3sh 2akta 2aktb ak3te ak4tei 2aktik ak2t3r ak3t4ri 2aktsi 2aktst 2a1ku a2kun 2a3kü 1akz a1la 2a5la. al1ab ala3ch2 al1af ala2g al1age a3lal al1am alami5 al3amp al1ana a2l1ang al1ans al1anz a2lar a3lar. a3lare al2arm al3arr ala2s al1asi al1ass 2alat al1au al3aug a1lä al1äm alb3ein al4berh al4b3er4w al2b1l alb3li al2boh al2br alb3ru alb3s al2dä al2dr 2ale ale4a 3a2l1e2b 3a4l1ef a4l1eh a2l1ei a4lein a2l1el alen1 al3ends a2leng a3lentf ale2p al1epo al1erf a2l1erh al3erl 3alerm a2l1ert 3alerz a2l1esk ale4t al1eta al1eth a2l1eu a4leur 3a2lex alf4r 3algi al2gli 1algo 2ali ali4ene al2imb ali4nal al1ins a2linv alk1ar al2kne 1alkoh alk3s2 al2l1ab alla3d al2lan al2l3a4r al6later al2län al3läu al4lec alle4gi al4leh al5lein al3lend all5erfa al3les alle3se al2leu 1allgä alli5er. alli7ers. al2lob al2lo2c al2lo2k al4lo2s al2lö2 all3öse al2luf allu4s al2lü4s al4m3ast 3almb 2alo a2l1o2b 3a2loe alo2ga al1orc a2l1ö al3öf al2ös 3alpe. 1alph al3skl als2to al2sum al3sun al4tak al3tar alt3eig al4t3er3f alt1op al2tö al2tri alt3ric al2tro alt2se alt4stü a1lu al2uf a2lum al1umb al1ur 4aly alzer4z al2zw 2am. 2am2a amab4 amad2 ama3g 2amä am2e 2ame. a2meb 2amel am4e2n1 amer2a am3erf a2meri ame3ru a4mesh a3met a2mew 2amir ami3t2a ami3ti 2aml 2amm. am2ma2c 2ammal amma4n am2mar am2mas amma4sc am2maß am4ma4te am2mä ammen8ge. am2min am2mit 2amml am4mod 2ammt ammu2 am4mü amni1 a2mö amp2fa2 am3pr 2ams am4schl 1amt. am2t1a am2t1ä am2tel am4t3ern am2tö am2t3r am2tu 2amu 2ana. 2anab ana3c anadi3 a3nak an1alg ana4lin 2anam 2anan 2anas an1ath an4atm an1äs 1anb 2anbu an3ch 2and. 3an3d2ac an4d3ei ande4sc an2dex an4drau an2d3rü and4sas and6spas and6s5paß and2su 2andu and1ur 2ane an3ec a3nee an2ei. an3eif an1e4k 3a4n1erb an1eth 1anf 2anfi anft3s an3f2u 4ang. an2g1ar 3angeb an2g1ei an4g3erf an4g3erl an4gerw an4g3erz 2angf 2angh 2angie ang1l an2gla 2ango ang1r an4g3ra 4angs. ang3sc ang6s3po 1anh 2a3ni an2i3d ani3els ani5ers. 3a4nim a4nins 2anj 2ank. an2k1an 3ankä an2kei an3kl an4klö an2klu an2k3no ank1r ank3ra ank3rä ankt4 1anl anma3s2 1anmu 2ann 3an3na ann2ab 3annä an3n2e ann4sto an1od a3nol a2n1or a3nos 2a1nö 1anr 1an3s2ä 1ansc ans2en an2seu 2ansk an3skr an3s1pa 1anspr an3s2z 2ant. an2t3a4r 1antá 1antei 3antenn an3t4he 1anthr 2anto anton4 3antr ant3rin an2tro 1antw 2a1nu anu1s a1nü 1anw 2anwet 2anzb 1anzei anze2n 2anzg an2z1i4n 2anzs 1anzü 2anzw an2zwa an2zwi 2ao ao1i4 a1op a1or a1os3 ao3t2 a3ot. a1ö a1p 2ap. 2a3pa 2ape a2pef a3pel a2pé a2pf ap2fa a3pfl a3phä a2ph3t 2ap3l ap4la ap2n a2pot ap2pf 3appl 2apr 3apri ap2str 2a3pu 2aq 2ar. a1ra a3ra. ar2ab ar3abt ara3d2 a2r3al a3ra3li 2aran a2r1ang a2r1ans a2r1anz a2r3app 2a2rar a2r1au a1rä 1arb 2arb. 4arba ar2bau ar2bec 2arbek 2arben 4arbi ar2bl 2arbr ar2bre 2arbs2 2arbt 2arbu ar2b3un 1ar1c ar2dro 2are a2rea ar1eff a4reg ar1ehr a2rein 4arem a3ren 4aren. are3r2a ar2erf a2r1erh a2reri are3u ar2ew 2arf ar2fä arf1r ar2f3ra ar2gl ar2gn ar3g4r 2arh 2a3ri ar2ia ari3e4n ari3erd ari3erg ari5ers. ar1im arin3it a4r1int a4rinw ar2kal ark3amt ar2k1ar ark3aue ar2k3l ar4klag ar2kor ar4k3ri ark3sa ark3she ar2les 2arma ar3m2ä ar3m2or ar2nan arn2e 2a1ro ar1ob a2r1o2d a2r1of a2r1op a2ror 2arp 2arr ar2r3ad ar2rek arre4n ar2rh arr3he 2arsa ar4schl arse3 ar3s2h 2arsi ar3t2e artel6li6 ar2the artin2 2arto ar4t3ram art3re 2arts 2artuc 2aru ar1uh ar1um a2rü 2arv arwa2 2ary ar2zä 2arze 1arzt ar2z1w as2ad as1ala asas2 asa3sse as3au asau2s1 a2sca a4schec asch3la a2schm a3schu 4a3s2e a4seb as3e2m a5s4es a4sex 2asg 4ash a4s3ha as4hi asin2g 4a5sis asi4st a3skop a4s3l a4sn a1so1 as1o2f a3sol as1or as1p aspek6to a4s2ph as2pi a4spl as2po a1spu as3s2a ass2e as2s3ei as3sel as3ser asserma6 as3s2i as2s1p as4st ass1ti ass1to as5str as5stu 2asta a4stec a4s3tep as2ter a4stese 2astr as4trau a4strä ast3räu a2s2t3re a4strol a2stum a3su asu2s a4sw aswa2s 3a2syl aße2 aßen3 2a1t at1ab at2a1f at4ag a2t1akt ata3l a3tam at1apf at1au a2taus a2tä at1än at2c a2teb ate1c ateien4 at1eig a4teli at2en a2tep ate2ru atex3 at2h at3ha athe1 3athl a4thr 4a3ti atingma5 3atm 4atmus ato4man 4ator a2t1ort a2t1ö 4atr atra4t at3rä at3re at3rom at3rü at2sa at4schn at2se at4set at2si ats1p at3ta 3attac at4tak at2ta2l att3ang at4tau at2tä at4tec at2tei at3t4hä at2t3rä att3s at3tu atu2n atz1er at4zerk at4zerw at2zi atz1in at2zo atz3t2 at2z1w a2u 2au. 2au1a2 2aub au2bab aube4n au2bli au2blo 4auc auch3ta au2dr 2aue aue2b au3en. au2ere au5erein auer3ö au2fa auf1an 3aufber 2aufe. 2aufeh auf1er au4ferk auff4 3aufn auft2 2auft. 2aug 4augeh 2auh au3ha au2hu 4au1i au2is 2auj aule2s au3lü 2aum au2mal aum2ei au2m1e4r1 aum3eri au2m1o aum3p2 aum3s2 4aun au3n2a aun2e au4nei au2nio au1nu a4unz 2aup2 aup4ter 2au3r2 au2s1ah ausan8ne. au2sau 4ausc au4schm 1ausd 2ausen aus3erp au4s3erw 1ausf 1ausg 1ausl au2so au2spr 1ausr 1auss2 au3sse aus4se. au8ssende aus4ser au2sta 2auste au4stec aus3tie aust2o aus3tri 1ausü 1ausz au3ße a4ut au2t1äu au4ten4g au4t3erh 1auto au2trö 2auts 2auu 2auw 2aux 2auz auz2w 2a1ü 2a1v a3v4a ava3t4 a3vi a2vr av2s 2a1w awi3 awi1e a1x ax2am ax2e axi2s 2a1ya a1yeu aysi1 ay3t 2a1z a3z2a3 az2i az2o az2u ä1a äand4 ä1b ä5be ä2b3l äb2s ä1che äche1e ächenma5 ächenmas8 ä1chi äch3l ä2chr äch2sp ä1chu äck2e ä1d ä2da ä2d1ia ä2dr äd2s 2ä1e äf2e äfe4n äf2f3l äf3l äf3r äf4ro äf2s äft2 äft4s ä1g ä5ge äge1i äge2ra ä2g3l äg2n ä2g3r äg4ra äg2s äg3sc äg3str 1ä2gy äh1a 2ä3he ä1hi ähl1a äh3l2e äh4l3e4be 2ähm äh3na äh3ne 1ähnl 2ähr äh3ri 2äh2s 2äh3t ä1hu äh1w 2äi ä1im ä1is. ä3isch. ä1isk ä1j ä1k ä2k3l ä2k3r ä1la älbe2 äl2bl ä5le äl2l1a äl2p3 äl4schl ä1lu ämi3en 2äml äm2ma4 ämmas2 ämoni3e 2ämp äm2s ämt2e 2än. än5de än2dr 2äne äne2n1 än2f5 änft2 2änge 2än2g3l än2gr äng3se 2ä3ni änk2e än2k3l än2kr änn4e2 äno3 2äns än2s1c äns2e änse3h 2änz ä1on ä1pa äp2pl äp2pr äp2s1c 1äq ä2r3a2 är4af är1ä är2b3le är1c 4äre ä2r1ei äre2n ä2r1ene är2gr är1int är2k3l är4ment ärme3s är1o ä1rö ärse2 är2seb är2si ärt4e är2th ärt4s1 ä2rü är2zw ä1s äs4c ä3s4e äse3g2 äser4ei äse4ren äser2i äse3t ä5si äskop2 äskopf3 ä3s2kr ä2s1p ä3s2s äs4s1c äss2e äss3erk ä5sses äs4s1t äst2 äs2te ä2str ä1ß äß1erk ä2t1a2 ä3te äte1i ätein2 äte2n ä2t2h ä1ti ä1to ät1ob ät3r ät2sa ät2sä ät4schl ät4schr ät2s1i äts3l äts1p ät2s1t ät4s3te ät4sti ät2tei ät2tr ä1tu ät2zw äu2b3l äu2br äu1c äude3 äu3el ä2uf äuf2e 1äug äu4g3l 2äul 2äum äu2ma äum2s1 2ä2un äun2e äu1nu 2äu3r äu1s 2ä3us. äu4schä äu4schm äu3se ä3usg ä3usk ä3usn äu2s1p äu3s2s äuss1c 1äuß äu2tr 4ä1v 1äx ä1z â1t á1n ba2bl 2babs bach5t4e backs2 b1a2dr 2b1af bah2nu bahr2e bais2 ba2ka ba2k1er ba2k1i bak1l bak1r ba2kra 3bal bal2a bal4lan balle4b bal6lerg bal4li4g bal4lok bal3lö3 2b1am ba2me ban2a 3b2and ban2dr ba3n2e b1ang ban3gl ban2k1a ban4kl ban2kr 2banl 2b1ans ban3t b1anz bar3b bar3de ba2rei bar2en ba4r3ins bar3n bar3zw 3bas ba3s2a ba2sc ba2str ba4t3ent bauer4l bauer4s bau3g bau3s2k bau3sp ba1yo 3b2äc bä1ch b2är b2ä4s3 4b1b bbe4p b4be2se bb3ler bb2lö b3bru bbru2c bb2s bbu1 2b1c bch2 2b3d4 1be. 3bea be3an be3ar 3beb b2ebe 1bec be1ch be2del bedi4 be1eh be1erl be1eta 3bef4 be3g2 2b1eier bei1f4 bei4ge. beik4 beil2 bei3la 2b1eime be1imm b2ein be1ind be1in2h bei3s2 beit2s 3bek 3bel be3las bel3d be3lec be3lei be2l1en be2let be3li bel3la bel3lä bel3li be2l3ö bel3sz bel3t4 1bem bema5sse bemas8sen 1ben. ben3ar be4nas be4nä ben3dor be3nei 3beng be3n2i ben3n ben2se ben4spa ben4spr benst4 ben2su 3bensv 2bentb b2enti bent4r b1ents 2bentw ben3un ben3z2 be1o be1ra be2rab be2ran beras4s berb2 berd4 ber4ei. be4r3eiw be4rerk bere4s ber6gan. ber4hab ber4in. ber3iss bermas4 berma7sse ber3na b1ernt be1rop berö4 ber3st4a be3rum ber2zö 3bes bes2a be2s1er be5slo bes2po bess4e b3esst. bes3sz beste2 be6stein be4s3tol be4stor best4r be3s2ze 3bet be2tap be3tha bet2to be1ur 3b2ew 2b1ex 1bez 4b5f4 bfal2 bflö4 bflös3 2b1g2 bgas1 bga4st bge3 bges2 2b1h2 bhut2 1bi bi3ak bib2 bibe2 bie4str 3bietu bik2a bi2ke. bi2kes 3bil bil2a bi2lau 4b1illu bi2lu 2b1inb bin2e 2b1inf bin3gl 2b1inh 2b1int bi2o1 bio3d bi3on biri1 bi3se b1iso bi2sol bi2sp bis4s1c bis3si bi2stu bi2stü b2it. b2ita b2ite bit4ta4 bi2tu bi3tum b2i3tus biz2 4b1j bjek4to 2b1k4 bl2 2bl. bla3b4 b3lad b5lag b2lanc 3blat b2latt 2b3law b2läse b2le 3blea b3leb 3blec 2b3leg 2bleh 2b3leid 4b3lein blei7s 3blem 3ble4n b3lese ble3sz b4let b3leu 2blich 3blick b2lie 2blig b4lis b2lit 3blitz b2lo b4loc b3los2 blo3sse blös4s 2blun 3blut 3blü 2b1m bmas2 4b3n2 bni2 bnis1 bo4a bo5as b1ob3 bo2bl bo2br bo1ch2 bo3d2 boe1 bo2ei 2b1of bo3fe bo1is bo2l1an 3bon. bond1 bon2de bo2ne 3bons b1op bo1r2a bo4rä bor2d3r bo2rei bo4rig b1ort bor2t3r bo2sc bo3se bo4s3p bote3n4e bo3th bot2st bö2b3 2böf b1öl 2b1p2 bpa2g 2b1q b2r4 2br. b4ra. 2b3rad b4rah b4ra3k bra4sp bra4ss brast4 3brä brä4u 2bre. 3brea 6b5rechte 2b3ref 2breg b3reif b3rek 3brem 2b3rep b4rer 2b3riem bri2er b4rio bro1 b3roh 2b3rol b4ron b4ruc bru4s brust1 bru2th 3brü brü4ss 4b1s b2sad bs3ar bsas2 bsa3sse bsat2z b3sä b4sär b5sc bs2ca b6schan b6schef bs4cu b3se. bs1e2b b3sel. bs1ele bse2n1 b3sen. bs1ent bs1er b2serf bs3e4r3in b2sers b3ses b3set bsi2t b4sl b2s1of bs1op bso2r b2sö b3s2pi bs2pl b3s2pu b4ss2 bs2t bst1a2b bst3ac bs3tag bst1ak bs3tät bst1er b4stern b2s3tip b3sto b4stob b4stod b3stö b3stra b2s3trä bs3treu b2st3ro b3stü b4stüb b2s1un 4b1t b3ta bta4st3r b5te b2th bt4r bts2 btü1 bu3ches bu2chi bu2e3 bu2f bug3 2b3umk bunde4s b3ungn b2urg bu3r4i 4burn burt4s bu2sa bu4s3cha bu4schl bu4sch3m bu4schw bus1er bu2si bu2s1p bu4s3ses bu6s5term bu2s1tr bu2s1u bu3tan bü1c bügel3e bü3s4 2b1v 2b1w bwel3 by1 by3p bys2 2b1z2 bzeit1 bzu1 1ca 2c1ab ca2ch ca2e3 ca3g4 ca1h cal3t c4an ca2pe 3car car3n carri1 ca3s2a3 cas2t ca3t4h ca1y2 cä3 cäs2 2cc c1ce c1ch2 c2d2 c3do 2cec ceco4 1ced ce2dr 2cef ce1i 2cek 1cen ce1nu 1cer cere3 ce1ro ce3s2h 1cet 2ceta ce1u 1cé c1f c4h 4ch. 2chab ch3a2bi 2ch1ak ch2anb 3chanc ch1ang ch3anst 2chanz 1chao 2char. 1chara 3charta cha2sc 1chato ch1ärm ch1äs 1châ 2chb 6chc 2chd ch3e4ben 1chef 3chef. che4fer 3chefs 2chei ch1eim 4chelem che4ler 4chents 4chentw cher3a che3rei 6chergeb cher6zie ch3ess 2cheta 2ch3e4x 1ché 2chf 2chg 2chh 1ch1ia chi3na 4chind 3chines 2chinf 2chinh ch1ins ch1int 2ch1inv 1chiru 2chj 2chk 2chl2 ch2le ch2lu 4ch2m 2chn4 chner8ei. ch2neu 2chob cho2f ch1off ch1oh chol2a ch1orc 2chp ch2r4 2chre chre3s ch3rh 1chron 4chs ch4stal chst3ri 2cht 2chuf 2chuh 2ch1unf 2chunt 2chü 2chv 2chw 5chy 2chz ci1c ci1es cil3l ci2s c1j 4c4k ck1a ck3an cka4r1 ck1ä ck1ehe ck1ei cke2ra ck2ere ck1erh ck2ern ck1er2r ck1ese ck1id ck1im ck1in ck3l ck3n ck1o2 ck3r ck4stro ckt2e ckt2i ck1um3 ck1up c4l2 cle4a clet2 clo1 1clu c2m2 1co co1ch co2d2 co3di coff4 coi2 co1it co2ke co2le col2o com4te. comtes4 con2ne co2pe co1ra cor3d co3re cor3t cos4 co2te 2cp c1q 1c4r2 cre2 cre4mes cry2 2c1s2 c2si 4c1t cte3e cti2 cti4o ctur6 3cu cu2p3 cussi4 1cy c1z 3da. da1a 2d1ab d2abä da2ben 3d2abl da2bre dab4rü 2d1ac d2ac. dach3a da2cho 4d3achse d1af d1ag dagi2o dah3l da1ho 3dai2 da1in da1is dal2a 2d1alar dal3b2 da3lö d1alt d1amma 2d1ammä damo3 d2amp dampf8erf 2d1amt d2an. 2d1ana dan4ce. 2d1an3d2 d3anei d1ang 2dange 3dank dan4kl dan5kla dan2k1o dan2kr 2d1ans 4dantw 2danw d2anz. 4danzi 2d1ap d2aph 4dapp da2r3a 2darb2 dark4 3d2arl dar2ma dar2m1i da2ro d3arr 3d2ars d1art 2dart. da2ru d2arw d1arz dasch4 da3s2h 3dat dat2a dat2e2 da3tei date4n 4d3atl 4d1atm 3dau3e 4d1au2f d3aug 4d1aus 2d1ax 2d1äh 2d1ämt 2d1änd 2d1äng 2d1äp 2d1ärz 2d1ä2u dä3us 2d1b4 dbu2c dbu3s 2dc d1ch dco4r 2d1d2 ddar2m d3dä d3dh d5do 1de de2ad de3a2t 3deb4 4d1e2ben 3dec de1ch de3e4 2d1eff deg2 de3gl dehe2 de3ho 2d1ehr d1ei 3d2eic 3d2e1im dein2d dein2s de3inse de2l1a4g de4l3aug del1än del1ec delei4g 2d1elek 2delem deler4 2delfm del4lan dell3eb del4lei del4ler del2lö2 de2l1ob de2lop de3lor de2lö del2s5e del2so del2s1p del3t4 dem2ar dement4 de6mentg 2d1emp d2en. de4n3end 4denerg 4d3en4ge. d2enh de2ni den4k3li den2kn 4den4sem den4s3en den6s5tau den3th 2dentw de1nu 2deol de1on depi4so d4er. de1rad de2rap der2bl 2derdb de2re2b de4reck de4r3ei4s derer3 de3r4erb de3r4erf de4r3ero derer4t derer6ze d4erfi d2erh 4der4höh d4erhü 3derie derin4f 4derklä der3m2 4derneu de1ro de2rop derö4 der3r 4der4sat der4spa der6t5en6d dert4ra 6der6trag de3ru de4ruh de4rum d2es. de2s1a de4sa4g de4sam des3an des1än de4seh des1en1 des1et des1in 3desk des1o de2sor de2s1p de3spe des5s2 dest5alt de4stam de6stant de4stei de4stit dest5rat de3stri de3stro de2s1u deten4t 2d1etw de1un de1url de3us devil4 d1exi de2xis 2dexp 2d1f4 2d1g2 d2ge. dge2ta dge4t1e 2d1h2 d2his 1di di4ab di2ad di4am di4ath 3dic di1ce dich1 dich5ter di2e di3e2d di3end die4neb di3eni di3ens. di3ern die4s3c diet3 die2th dige4s dik2a dil2s3 2d1imb 2d1imp din2a 2d1ind 2d1inf 2d1inh 2d1in1it 4d3inner 2d1ins 2d1int di2ob dion5s di1p di4re. di2ren di2ris 2d1irl di4s1a2 di2sp di3s4per 2d1isr dist2 di2s1to di4s3tra di2ta di4teng di4t3erl di4t3erm di4t3ers di2t3r dit1s di2tu di5v diz2 2d1j 2d1k4 4d1l2 d3le dle2ra dli2f dl3m dl3s 2d3m2 4d5n2 dni2 dnis1 dni3v d1ob d2oba 2dobe dob4l d2obr do1chi 2d1o2f doll2a do2mar do5na doni1 do2o 2dope 2d1opf d2opp d2o3r4a 2dorc 2d1ord dor2f1a dor2fä dor2fl dor2fr 2d1org dori1 2dort dor2ta dor4ter d2os. dos3s dost1 do4sta dot6h do2t1o do3un d1ö dö2d dö2l3 dölla3 d2ön 3d2ör dö2s1c 2d3p2 2d1q d2r4 3d4ra. 2d3rad 2drahm d3rai 3d4ram d3rand 2d3rast d3raub 2d3rauc 2draup 2dräd d4räh 2d3rät 2d3räu 4d5re. d4rea. d4reas 3d4reck 2dref 2dreg 3d4reh 2d3reic d4reiv 4drem 4d3ren 2d3rep 4d3rer 4dres. d4resc 2d3rh d3ri 3d4ri. 3d4ria 2d5ric d4rid d4rif d4rik d4rin. d4risc 2driß 3d4rit 4dritu d3rob d3roc 2d3rod d4roi 2d3rose 2d3rost 2d3rot d3rou 2d3rov d3rö drö2s1 d5rub 3d4ruc 2d3rud 2d3ruh 2d3rui 4drund drunge3 2d5rut drü1b 2d1s 4ds. d4s1amt d2san ds3assi d2sau2 ds1än 4dsb d4schef d4schin d2s1e2b d2s1ef ds1ehr d3sei ds2eig d4seins d2s1eng d2s1ent d2s1erf d2serh d2s1erk ds1err d2s1erz dse2t d2s1eta d3s2ha d3sho d2sid d2s1im d3s2inf d3s2kan d3skul 4dsl d2s1op dso2r ds1ori d2sö d2s1par ds1pa4s d2spä ds2pe ds2po d3spri d2spro ds2pu dss2 ds3si dst4 d4stabe ds3tauf d4s3täti d4stea ds2til ds2tip d2s1tis d2stod dstras4 ds1ums d2sun ds2zen 2d1t dta2d dtam3m d3tea d2th d4thei dt3ho dto2 dt3r dtran2 dt5s2 1du du1alv du1ar dub3l du2bli du2f 2d1ufe 2d1uh du1i 2d1umb 2dumd 2d1u2m1e 2dumf 2dumg 2d3umk 2duml d2ump 2dumr d1ums d2ums. 2d1umv 2d1un3d dund2a 2d1unf 2d1ungl dun3ke dun2kl 2dunr dun4st3r 2dunt 2dunw du1o 5dur2c 2d1url 2dursa du4schn du4schr du4schw 2düb 3düf 3dün 2d1v2 4d1w dwa2 dwest1 dy1 dy2s1 2d3z2 2e1a e3a2b eab3l ea3der eadli4 ea2dr ea2g4 ea3ga ea4ge ea3gl eakt2 e3akto ea2la e3alei ealer2 e4aler. eal5le eal3lö eallö3s e2alti2 e2ame eam3m eam1o eam3t ea2na e2ano e3ar. ea2ra e4are. ea4rene e4arer e4ares ea2sc eas5s eat4e2 eater1 e3ath eat3s2 e3at3t4 e3au2f e3aug eaus3s eau3st e3ä4 e1b 2eba e3b2ak 2ebed ebe2i 2ebel eb2en e3ben. ebens3e e3ber ebe4rel ebert4 2ebet 2ebl eb2laß eb3ler eb4leu e3blie eb3lo eb2lö 2eb2o ebö2s 2ebr eb3rei eb4ru eb2s eb6sche ebse2 ebs1i ebs1o ebs1p ebs3pa eb4stät ebs3t2h eb4s3ti eb4s3tot eb3str ebs1u 2e3bu ebus3s ebu2t1 2eca e1ce ech1ä 2e1che ech1ei e6ch5erzi ech3l ech3m ech3n e2cho. ech1o2b e2ch3r ech3t4ei e1chu ech1uh ech1w e1ci eci6a eck3se eck4sta 2eckt 2e1cl 2eco eco3d 2ect e1d e3d2a ed2dr ed2e ede2al ede3n2e eden4se eden4s3p ede2r edert2 edi4al 2edip edma3 edmas2 e3d2o ed2ö eds2ä ed4seh ed2s1es ed2s1o ed2s1p ed2s3tr ed2su edu2s e3dy3 4ee ee3a2 eeb2l ee2ce ee1ch ee2cho eede3 eed3s2 ee1e e1eff eef4l eeg2 e1ei ee1im eein4se eei5se eel2e e1e2lek ee5len e1emp e1en eena2 ee4nag e2enä e2enc e2eno een3s e1e2pi eera4 ee2r3as e1erbt e1erd ee3r2e ee4r3en4g eere4s1 ee1ro ee1rö eer2ös eert2 e1ertr ee3r2u e1erz ees2 ee3sh ees3k ee3ta ee4tat ee1u eeu2f eewa4r e1e2x e1f 2ef. 2efa e2f1a2d ef1ana ef1ar e2fat efäs4 efä5sse e2fäu 2efe e3fe. e2f1e2b efell4 ef1em e2fent ef2er efeuil4 2eff. ef2fä2 3effek 1effi ef2fl 2efi ef1id e2f1ins efi2s 1efku 2efl e3f4lu 2e3f2o e3fra ef3rea ef3rol ef3rom ef4rü efs2 ef3so ef3sp ef2tan ef2tei 2efu e2fum 2efü e1g eg1d4 e3ge ege4ler ege4n3a4 ege4nec ege2ra ege4s3to ege4str ege1u e2glo e2glu e2gn eg3nä eg3ni egro5sse eg4sal eg4san eg3se eg4sei egs3e4r1 egs2pe eg4sto egs3tü eg2th 2e1ha eh1ach eh2al e2hap eh2aus 2e1hä ehäs3 e1he eh4ec eh1eff eh2el ehe5na ehen2t3 1e2hep e3her ehe1ra e1hi eh1int ehis4 eh1lam eh1lä ehl3ein eh4lent eh5l2er eh2lin eh3lo ehl2se 2ehm eh3mu e1ho e3hol ehr1a2 ehr1ä ehr1ec eh2rei ehr4erf ehr6erle ehre3s eh3ri eh1ro2 ehr1ob ehr1of eh2s2 eh3se eh3sh eh3si eh3so eh3sp eh3sta 2eht e1hu e2hunt e1hü eh3üb eh1w e1hy 2ei3a2 ei2bar ei2bl eibu4t ei4b3ute ei2cho eich5te e2id ei2d1a ei3de eid4ein ei4d3er4r 2eidn ei3dra ei1e ei3el 4ei3en eienge4 eie4s eif2e 1eifr ei3g2a 4eigeno eig2er 2eiges 2eigew ei3gl 1ei2g3n 2eigru 2eigt 2eigu eik2ar ei3kau eik4la e4il 2eil. ei2lar ei2lau 2eilb eil3d ei4lein eilen1 eil3f4 ei4l3ins 2eiln 1eilzu ei2m1a4g eim3all ei2mor e1imp eim2pl e4i2n1a ein3a2d ei4nas ei4nä ein3dr 2eindu ei4neng ei2neu 2einfo ein4fo. ein4fos ein3g2 ein4hab e1init eink4 ein6karn 3einkä 3einkom ein3n2 1einna ei2n1o2 1einri e4insa einsas4 einsa7sse 3einsat e3insta ein6stal ein4sz 1einu e4inver ei3o2 ei1p eip2f 2eir ei3re e1irr e2is. ei2sa4 ei6schin ei4s3erw eis2pe ei3spru ei3s2s ei2str eistra6s ei2sum e4it ei2tab ei2t1an ei2tar 2eitä ei3te ei2th ei2tor ei2tro eitt4 eit3um 2eiu 2e1j e1k ek2a 1ekd e3ke. e3ken e3kes e3key e3k2l ek3lip ek4n ek2o 2ek4r 2ekt ekt4ant ekt3erf ekt3erg ek4t3er4z ekt2o ek2u e3k2w e1la ela4ben el3abi el2abt el3a4der e3ladu el1af ela2h e2l1ak el3al e2l1a2m e4landa e2lanm el1ans el1anz 2elao e2l1ap e2l1a4r el3ari el1asi el1asp el2ast 2e1lä 3elbis el2da eld3erh elder4p eld5erst el3des eld3s2 e3lea 2elei e6l5ei6er. e6l5ei6ern el1ein e4leinf e4leing e4leinh e2l1el 1e2lem e3lem. el1emp 2e3len. e4lense e4l1ent e3lep e2l1erd el1erf e4ler4fa e2l1erg el1erk el1erl e4ler4la e4l3ernä e4ler2ö e2l1err eles2 el1ess e4l1e2ta e3leu 2elev ele2x 1elf. el3fe elf4l 1elfm 1elft elg2a elgi5er. elgi5ers elg4r e2l1id e3lie e2lim el1ita 2elk elks2 elk3sc ella3d el3lan el2lap ella2s el2lä el3läd ell3ein el3ler el2leu el3lie el2lil el3l2in el2log el2lot ell3sp el2lu2m el2lü 2eln el5na 2elo e2lof e2lol elon2 e2l1or elo2ri el2sum elt2ak el3te. el5ten. elter4b 3eltern elter4s el3tes elto2 elt3r elt1s2 elt3se elt3sk 2e1lu el1ur el3use e1lü e2lya 2elz el2zar elz2e el2zwa e1m 2ema em1ad ema2k e2m3anf e2m1ans 3emanz emas8sens em4d3a2 e3m2en emen6gel emen4t3h e2m1erw 1e2meti e2m1im emi5na em1int emi3ti 2emm em2map emma3u e2mop 1empf4 em3pfl em2sa em3se em2spr em3t2 1emul 2emü emü3s4 e2n1a 4ena. 2en2ac en3ack e3nad e4naf 4enah e4n3a2k ena3l2i enal3p 4enam en2ame e4nand en3ang e4nanz en3are ena4sc 4enat en3att e3naue en1ä e2när enä4s enbu4s3 en2ce. en3d2ac en2dal endermas8 en4d3ess end4ort end3rom end3s2p end3sz end2um 2ene. ene4ben en1ec e2neff en2eid e3neien e4nein e2n1el ene4le 2enem 2enen e4n1ent en4entr 4e3ner. e2n1erd e2nerf 1e2nerg e4nerh e4nerk e2n1erl e4n3ermo 4enern e2n1err e2n1ers e2n1ert e2n3eru e2n1erw e4nerz 2enes e2n3ess en3f enf2a enf2u 1engad 3engag enge3ra en3g2i en3glo en3gn 1engp eng1s eng3sc eng3se 2eni e3ni. e3nic e2nid e3nie eni3er. eni5ers. e2n1i4m e2n1in e3nio eni2ö e3nit en3k2ü e2n1o2b enob4le e2nof en1oh e3nol eno2ma en1on e2n1op e2n1o2r eno2s enost3 e3not eno2w 2e1nö en1ö2d en3sac ensas2 ensa5sse en2sau en5sche en2seb 3ensem ensen1 en2sep en3ska en3s2po enst5alt en4s3tät en6s5test 2ensto ens5trie e4nt ent4ag ent4ark 1entd en2teb en4terb en3tes 1entf 2entfo 1entga 3entgeg en2thi 3entla 1entn en4t3rol 3entspr 1entw 4entwet 1entz en1u 2enut e1nü 4enwü e1ny enz1ec en4z3erf en4z3erg en4z3erk e1ñ 2eo e1o2b1 e1of eo2fe e1oh eo3m e1on. e1ond e1onf e1onh e1onl e1onr e1ons e1ope e1opf eop4t e1or e3or. e3orb e3ors e3orw eos2 e3os. eota2 eo3ul e1ov e1ö2 e1p epa2g e3p2f4 e2pis 1episo 2epl ep3le 1e2poc ep2pa ep2pf ep2pin ep4pl ep2pr ept2a ep2tal 2e3pu epu2s e1q er1a e3ra. era2be e3rad. er3adm eraf4a era2g e1rai er3aic e2rak e1ral er3all eran3d e3rane er3anf e2ranh er3anm e1rap er3apf e2rar e3rari e1ras e2r3a6si era4sp era4s3s er4ast era2ß e2rath e3rati e2ratm e1raub er3aue erau2f er3aug e1raw e1raz e1rä er1äh er1äm e2r1ä4s erb2e erb2sp er1c er3chl erda3me 1erdb er3de 2erdec erde3in er4d3en4g erd3erw 4ere. er1eb e3rech er3echs er1eck er1edi ere4dit er1eff er1e2h 2e3rei. er1eig e2rein e4r3eis. ere2l er1ele ere3lev 2e3rem e2remp 2eren e3ren. e3rena e4rense e4rentf e4rentn e3renz eren8z7en8d er1ep 2erer. e2r3erf e2r1erh 2erern e3rero er1err er1ers e2rert er1erw 2eres er1ess er1eß e4r3e4ti er1eul ere4vid erf2e er3f4r 4erfür 3ergebn 4ergehä erg3els 1ergol 4ergrem e2rh 1erhab 4erhals er3he 4erhöhe er3hu 2erhü 2eri e2riat e3rib 4e3ric er1i2de e3rie eri3e4n3 eri5ers. e3ri3k4 4e3rin. er1inb e2r1ini er1ink er1ins er1int e3rio er1ita 2erk. 1erklä 2erkli er3ko 2erkre erk3t 2erlag 3erlebn 4erln erm2e ermen4s erm3ers er4nerk ern1os e1ro. er3oa er1o2b e2r1o2f e1rog e1r1oh e1rok e1rol e1rom e3ron er3ony er1op e4ro2r e1ros e1rou e1row er1ox e1roz erö2d 2erök er1ös er3p4 er3rä er5rei erri3er 2errü ers2a ersch2 er5schn er3se er5sen er3s2i er3sk ersma3s4 er5smo er3sn er3sp er3sto er3sz ert2ak er6terei er4t3erf er4ter4h er4ters er2t3ho 4erti ert3ins ert3s2e 2ertür 2eru eruf4s er1u2m er1und er1uns er3uz erü4b 3erweck e1s e4s3ab e3sac esa2d es2an es4and es4ank es3ant e3s2as esa3sse esas6sen esa6sset e4s3ato es3av esäs4 es2äu 2esb esbi5er. e3sc es2ca es3cap es2ce esch2l esch2n e4sco e4scu e3se. es1ebe es1ehr e2sein es3eva 2esf 4esh es3ha es4har e3sig e2s1il es1ini e4s3ins es3int es2kat e4s3ke e4sky e4s3l es4log 2esm e4sn eso2r es2ort es2ö 2esp es2pek e3spi e3s2por e3s4pra e3s2pu 2esr essali3 es2sau 4essem ess4e3re ess3erg es3si 2esso es2sof es2s1pa es2spu es4ste estab4b est1ak e3stan e4starb 1e2stas es2tau es2te este2c e4st3eng e4st3erh e4st3ess e5stev e3sti e4stip estmo6de e2stod est3ori 2estro es3trop es2tu e3s2tü es2ty e2s1um es1ur e4sw e3sy eße3r2e e1t e3ta. etab4 etal4la4 etal6li6n et1am eta2mi 1etap etari1 et4at et1äh 2e3te e4t1ein ete3ke et2en eten3d2 ete2o eter4hö eter4tr et2h et3hal ethi1 et3hü e3ti eti2m eti2ta 2eto eto2b e2t1of e2torg 2etr e4traum et3rec e4tres etsch3w et1s2p et1su etta2 et2tab et2tad etta3ge et2ta4s et2tau et2tä et2tei ette4n1 et4teu et4th et2tö4 et2t3r et4tro ett3sz et2t1um et2tur et2tü4 etwa4r 2etz et2zä et4z3ent etze4s et2zw eu1a2 eu3b4 euen2g eue6reif euer4ri eu2e5sc 2euf eu2fer eu2ga eu4gent eu3g2er eug1s2 eu1in 1euk eu2kä e1um e3um. e3umb e3uml e3um2s eums1p eum3st 2eun eun2e eu4nei eun4er e3un2g eu2nio eun3ka eu1o2 eu1p2 e2u3r2e 1euro eu2rys eu1s4 eu4sis eu3sp eu3ss eust4 2eut eut2h eut6schn 2eux eu2zo eu2z1w e3ü 2e1v e2vela e2vent 4ever eve5r2i e3vo ev2s e1w 2ewa e3wä4 ewä6s 2ewe e2we. e3wir ewi2s e3wit ew2s 2ex. ex3at 1e2xem ex1er e1xi 2exie e2x1in 1exis ex3l 3exp 2ext. ex2tin ex2tu 2exu 2e3xy ey2n eys2 e1z e3z2a e2z1enn e3zi ezi2s ez2w é1b é1c é1g é1h é1l élu2 é1o é1p é1r é1s é1t2 é1u2 é1v é1z2 è1c è1m è1n è1r ê1p 1fa 3fa. fab4 f1abe fa2ben 2f1a2bl fab5s fa4cheb fa2ch1i fa2cho fa2ci f1ader fa2dr f4ah faib4 fa2ke f2al fa3l2a fal2kl falla2 fal4lei fal6lenk fal6l5er6k fal2li4 fal6scha fal6schl fal6schm fal3te 3fam f1amt 2fanb 2fanf fan2gr 2f1ank 2fanl f1anp 2fanr fan3s 2fanw f1an3z 2f1ap f2ar far2br 2f3arc 3fari farre2 far4rec far4reg f3art 2f3arz 3fas. fa3s4a fa3sh f3at fa2to 2f1auf f3aug fau2s f1ausb 3f4av fa2xa 1fä fä1c fäh2r1u f1älte 2f1ärm f1ärz fä4s fä6s3ser fä2ßer 2f1b2 2f1c 2f3d4 fdie2 1fe featu4 f2ech 2f1eck fe2dr fe2ei fe1em fef4l feh4lei f4eie 2f1eing 4f1einh fe1ini 2f1einw f1ei3s fek2ta fe2l1a fel4da fel2dr 2f1e2lek fe2l1er fe2les fel3la fel4lei fe2l1o fel4soh fels2t fel3t f2em. fem4m 2femp fen3a2 fe2nä fe2no fen3s2a fens2c fens2t2 fen6stri f1ent 3fep f2er. fe1ra fer2an fe4rang fe4r3anz fe2rau fe2r1ä ferde3 f2ere fer2er fer3erz f1erfa fe2rid 3ferk f2erl. 4ferneu fe1ro f4erpa f2ers. fers2t f2ert f1erw fer8zeuge fes4t fe2st1a fe4st3ei fe2str 2f1eta fe2tag 3fete fet2t3a feuer3e feu4ru 3few f1ex 2fexp 3fez 1fé 2f1f ffa2b ffa2ce f3fal ff1ans ff3ar ff4arb ff4art ffa4s ff1au ffa2z ff2e ffe2e f2f3ef ff3ei ffe1in ffel3l ffe2m f2f3emi f2fetz f2fex f2fil ffi2xi ff3lag ff3li f3flu f3flü ffo2 f2fö f3f4rä ff2sa ff2sp ffs3tan 4f3g2 fge3s 2f1h2 1fi 3fi. fi3at fi1er2f fi2kin fi3kl fik1o2 fi2kob fi2kr fi2l1an fil4auf fil3d fi2les filg4 fi3li fi4lin fil2ip f2ina fi3ni 2f1int fi2o fi3ol fi2r fi3ra fi4re 3fis fis4a fisch3a fisch3o fisch3w fi3so fis2p fit1o2 fi2tor fi3tu 3fiz 2f1j 4f1k4 f2l2 2fl. f3lad f5lan3d f3lap 1flä 3f4läc 2f5läd f3län 2f3läu 2f3leb 2f3lein f3ler f3li. 3f4lim fli4ne 2f5lon 1f4lop flo7s8ses. 1f4lot flo2w f3lö 4f5löf 1f4lug flu4ger f4lü f5lüd f5lüm 2f1m2 fma2d fmas2s fma3sse 2f3n2 fni2s 1fo fob2l 2f1o2f foli3 fol2k1 fo2na fon3au fon2e fo2nu 2f1op fo1ra 4f3org fo3rin for4m3a4g forni7er. for4sta for4sti fort3 for4tei for2th for2t1r fort1s for3tu f1o2x 1fö 2fö2f 2f1ök 2f1öl 4f1p2 2f1q f2r2 f4rac frach6tr 2f5rad fra4m f3rand f5rap 1f4rän 2fre. f3rec f3red 2freg f3reic freik2 frein2 f3rep 3f4reu 2f3ric fri3d fri2e 2frig 1fris f4risc fri6ster f3roc 1f4ron fro2na fro2sc f3rot f3ru f3rü 4f1s fs2amm f2san fs3ar f2s1as f2sauf f2saus f2saut fsä4 f3sc f4sce f4schan f4schef f2s1e2b f4sehr f2s1em f2s1ent f2s1er fse2t f2s1eta fsi2d f3s2kie f2s1o2 f3span f2s1pas f2sph f3spi f3s2pl f3s2por fs1pr f2spre fs2pri f2spro fs2pru fs3s4 f2stas f4s3täti f5stel f2stip f2s1tis fst4r f4s3tres fs1trü f3stü f4s3tüte f2sty f2s1un f3sy 4f1t f2ta. f2tab ft1a2be ft1af f2t1al ft1an ft1ar f3tat f2t1äu ft1e2h ft1eig ft1ein ft1eis f2t1ent f2t1e4ti f2th f4thei ft3ho f2t1id ft1op f2t3ot f2t3ro f2trö f3t4ru fts1 ft2sa ft4sa4g ft4sam fts2c ft4sche ft2se4 ft4seh ft2si ft4stä ft4ster ft4stes fts2ti fttra4 f2tum ft1url ftwa4 ft3z2 1fu 3fuc 3fug 3f2uh f1um 2f1unf 2f1u2ni fun2kl fun2ko fun2k3r 2f1unm 2funt f2ur fu4re. fus2 fu3sse fus6sen fu4sser fuss1p fus4s1t fu2ß1er 3fut 1fü 2füb fü2r fü3s4 2f1v 2f1w 1fy 2f1z fz2a fzeiten6 fzei8tend fz2ö fzu3 fzu4ga f3z2w 3ga. 2gabf ga2b5l gab4r 2gabz ga1ch 2gadl 2ga2dr ga1fl ga1k ga2ka gal2a 2g1a4lau g4amo 2g1amt 2ganb gan3d 4gangeb gan2gr 2ganh 2g3anku 2ganl g3anla 3g2ano gans2 2ganw ga1ny 3gar. 2garb 2garc 3gard 2g1arm ga3r2o 3g2ars 2g1arti ga3ru 2g1arz ga2s ga3sc gas3ei ga4sem ga3sp ga4spe ga4spr gas5s ga3s6ses gas3tan ga4st3el ga3str ga4stra4 gastras5 gas4trä ga4stre gas1tu gat2a 2g1atm gat4r gau1c 2g1auf 2g3aug g2auk g1aus 2g1aut 2g1äp 2g1ärz gäs2 gä4u 2g3b2 gbau5s gber2 gbi2 2g1c 2gd g1da g2d1au g2d1er gd1in g1do g1dö gd3r gd3s2 gdt4 gd1ur 1ge ge3a2 geb2a gebe4am ge3ble geb4r ge1c ged4 ge1e2 ge3ec ge2es gef4 ge3g2l ge3ha ge4ig ge1im ge2in. gein2s ge2int gein2v ge1ir ge2is4 2g1eise2 gei3sh gei4sta 2gek. ge4lanz gelb1r gel4b3ra gelder4 gel6ders ge3le 2g1e4lek geler3ö ge4l3ers ge4less gel3l2a gel3le ge3lor gel3sa gels2p gels2t gel3sz gel3t2a ge3lü gelz2 gem2 gem4e ge3mi 3gen ge3na ge4n3ac ge4nam ge4nar gen2as gen4aug gen2d1r gen1eb ge3nec gen3eid gen3ern gen6erwe gener4z genma7sse. gen3n gen3sz 2gentf gen3th 4gentw geo2r ge1ou ge3p4 ge1ra ge2rab 4g3ereig ge4reng ge4ren4s ge4r3ent ger2er gerin4f ger4inn gerin4t germas6s ger3no ge1ro ge1r2ö ger4sto ge3r2u g1erwa 4g3erwer ges2c ges3elt ge2s1er ge3s2i ges2p ges4pi gess2t gest2 get2a ge3tan 2getap ge3t4u 2g1e1ul 2g1ex 2g1f4 4g1g gga2t g3ge gge2ne g2g3l gg4lo g2g3n gg4r 2g1h 4gh. 3ghale gh2e 3g2het 3g2hie gh1l 3gh2r g2hu gh1w gi3alo gia2s gie3g gi2e1i gi2el gien2e1 gift5s gi2gu gi2m gi4mes 2g1ind gi3ne g1inf gin2ga 2g1ins 2giok 2g3isel gi3t2a gi4us 2g1j 4g3k2 4gl. gl2a 4g1lab g1lac g2lade 2g1lag 2gland gla4s3ti gla4stu 3g2laub 4g1lauf g1läß 2gläuf g2l4e 2gle. 3gle3a 2g3leb g3lec g3leg 2gleh 3gleic 4g3lein glei4t5r g3len 4g3ler 2gles g3lese g4lia 2glib 3g2lid g2lie 2glif g2lik 2glil g2lim 4glin g2lio 2glis g3lisc 3g2lit g2liz 3g2loa 3g2lob 4g3loch glo3g 3g4lok g2lom 3g2lop g2lor 3g2lot 2glös 2gls g1lu2 2g3luf 2glun 4glu3s g2lut g1lüg g2ly 2g1m2 gmül3 g1n 2gn. g2n2a g4na. 4gnah 3g4nat 3g2nä gn2e g3neh 2gnel gne2tr 2gneu 2gng g2nie g2nif g4nin 2gni2s1 g2no1 g3not 2gnp 2gns 2gnt 2gnu 3g2num. g2nü g2ny 2gnz go4a goa3li 2g1o2f 2gog 2g1oh go1i2 gol2a 2gonis 2g1ope 2g1opf g2o1ra 2g1ord 2gorg go2s go3th got6t5erg go1y 2g1p2 2g1q g2r4 gra2bi gra2bl 2g3radl 2g3rah 4g3rak grammen6 gram8m7end grau3f gräs5c 2g3räu 2g5re. g4reb 2g3rec 2g3rede g4re2e 2g3reic 2greim 2g3rein g3reit g3rek g4rem 2g3renn gre3no gren6z5ei g4rer g3ret g3rev 2g3ric gri2e g3riese 3grif 2grig 2g3ring gro2bl 2groc 2groh gron4 gros2 2g3rose gro5sse. gro7ssen. gro7sser. gro5sses g4roß gro4u 2gröh g4ruf 2g3rui 2g3rum grun2g 3g4rup grus2s gru3sse 2grut 2g3rüc 3g4rün 4gs g2sa gs1ac gsa2d gs1af gs1ag g4s3a2k g3sal gs3all g4salt gs3ama g4s1amb gs3an gs3ar gs1as gs1ä g4sca g4sce gsch4 g4schef g5schü gs3cr g2s1e2 gse3e gs2eh g3s2eil g3sel. g3seln gsen1 g4ser gser5f g4seu g2s1i gsi2d g3sig g5sil gs3l gs1o2 gs1p4 g3s2pek gs4pie gs3pl g5s2por gsrat4 gs3s2 g3star gs1tau g4s1tä g5stäm g5stel g4stemp gst3ent g4sterm gst3err g4s3test gst2he g3sti gs1tis g3sto g4ston gs1top g4s1tor gs1tot gst4ra gst5reit gst4ri gst5rit gst3ros gs1trü g3stun gs1tü gs2tüc gs1u g3sy 4g1t g3te gti2m gt4r gt2se 1gu gu1an. gu1ant gu1as gu4d3r gu2e 2gued guet2 2g1u2f 2g1uh gu1ins gu1i4s 3gumm 2g1unf g2ung. gunge2 4gungew 2g1ungl 2g3unk g2uns 2gunt2 3gur 4g1url gurt3s gu2s3a guschi5 gus2sp gus4st gu3sti gu2ß1 gu2t gut1a gu4t3erh gut3h 2güb gür1 gü3st 2g1v 2g1w 2g3z2 3haa hab2a hab2e 2habn ha2cho ha2del ha4din h1adle haf3f4l haft2s hafts3p h1ah h2ahs ha3ia h2aj 2haka ha1kl 2h2al. halan4c ha2lau hal2ba hal4bei hal4b3r 2hale hal4lei hal6lerf hal4leu hal4lok h1alp halt5r h1amt h2an. 2hanb h2and han2da han2kr h4ann 2hanr 2hant hao2s h1ap ha2pl ha2pr h2a3ra 2harb h2ard h1arm. har3ma har4me. har4mes har2th h1arti h2as 2ha3sa hasi1 ha2ß1 hatt2 hau5f6lie 2h1aufm h1aukt hau2sa hau4san hau2sc hau4spa hau4ss haus5sen hau4s3ti hau4sto h2aut. hau6terk 2hauto hau2tr h1äff h1ärz hä4s hä5sc hä6s5chen häu2s1c hä3usp 2h1b2 hba2r3a 2h1c 2h3d4 hdan2 2hea he2ad hea5t he3be he4b1ei he2bl he3br he1ch he3ch2e h3echt hed2g he3di he2e3l hee2s he2fan he2fä he2f1ei hef3erm 2heff he2fid he4f3ing he2f3l he2fr he3fri he2fu he3gu h4eib h1eie h1eif h1eig he2im heim3p hei4mu 2hein heine2 4heio he1ism he1i4st heit4s1 h1eiw he2l3a hel1ec h3e2lek he3len hel3ers he3li hell3au hel4mei he3lo he4lof he2lö 3hemd he3mi 3hemm 4h3emp h2en. he4na2 hen3a4g he2nä he2n1e2b hen3end hen3erg he2net heng2 2heni he2no hen3sk hen3s2t2 h1ents 2h3entw hen3z 4he2o he3on he3op he3pa he3ph h2er. her3a2b he2ral 2herap he3ras herau2 herb1r her4b3ra he4reck 4hereig he4r3eis he2rel he4rerw h1er2fo h3erfü herg2 her2ho 4herif herin4f he6rin6nu herin4s herin8ter h1erke h3erlau 2herm herma3s he3ro he4r3o4b h1erö hers2t hert2 her3th her2z1w he2tap heter2 he3th het2i he3t4s h2e2u heu3g 3heusc he3x he1x2a he1y2 1hè 2h1f4 hfell1 hfel6ler hfi2s 2h3g2 hget4 2h1h2 hhoh2 4hi. 2hia hi2ac hi2ang h2ias hi1ce hich6ter 2hi3d h2ide h1i4di hi2e hi3ens hier1i hie4rin hif3f4r hi2kr hi2l3a4 hil2fr hi2n h1indu hi3nel hin2en h1inf h1inh hi3n2i hin3n2 hi3no hin2t1a 2hio hi4on hi3or 2hip1 hip3f hi2ph hi2pi h2i2r hi3ra 2hi3re hi3ri hirn1 hir4ner hi3ro hir2s his2a hi2se hi2spa hi3ti 2hiu 2h1j 2h1k4 hklo3s 4hl hl2ag hlam8meng hla2n hl1anz h1las h1lat h1laut h3läche h3läd hl1är h1läs h1läß h1läu hlb4 hl3d4 h3leb hle3e h3lein h2leis h5len. hl2eng hl2enn h3ler hle2ra h2l1erg h6l3er4nä hle3run hl1erw h4lerz h3les h4lesi h3lex hlg4 h2lie h2lif h2lim hl1ind h2lip h2lis h3list h2lit hl3l hlle3b hlma3s2 h2lo h3loc hl1of hl1op h4lor hlo2re h3losi h2lös3 hlö4ss hl2ser hl3sku hl3slo hlst4 hls2te hl2sto hl3str hl3t2 h3luf h3luk h3lumpe h1lüf 2h1m h2mab h3mad h3mag h3man h3mar h3mas hma3sse h3maß h3mä h4mäc h4mäh h4mäl h3me. hme1e hme1in h3meist h3men hmen2s hme2ra h2mo h4mon h3mö hm3p4 hm2s1p h2mu h3mul h3musc h3musi 2hn h2na h3nam hn1an h3nau. h2nä hn1äh hn1är hn3d4 hn2e hne3b hne2e hn3eig hn3ein h2nel hne4n1 hne4pf h3ner hner3ei h4nersa hn3ex hnhof8stra8s h2nic h2nid h2nie hn1im hn1in h2nip hn3k4 h2nor hn3s2k hns2t hnsuch4 hntra4 hnts2 h1nu h2nuc h2nul hn1unf h3nunge ho2bl ho2c hoch3 hock3t 2hod hoe4 ho2ef ho4fa hof3fa ho2f3r 2hoi 3hole ho2l1ei hol3g4 ho4lor 3hols h1o2ly 3holz hol6zene hom2e ho2mec ho2med h2on hond4 hono3 2hoo 2hop ho1ra hor3d 2h1org ho3se ho4sei ho3sl ho4sta ho2str 2hot. ho3th hotli4 2hot1s2 3hov 2ho2w1 h1o2x ho1y2 hô1 1h2ö hö2c 3höhe h4ör hö4s hös1c hös3se h3öst 2h3p2 h1q 2hr hra2b hr1ac hr3ad h1rai h1rane h3räu hr1c hr3d h2rec h3rech h3red h3ref h4rei. hrei4ba h3reic h4r1eig h3rel h3ren h3rep hr4erbe hr4erbu hr2erg hr2erk h4rer4la h3rerle h6rer6leb hr6erlei hr2erm hr2erz h3re2s1 hre2t h2r1eta h3rev hrg2 h2ri h3ric h4rick hri4e h3riesl h3rin h4rinh hr1ins h4rist hr3l hrm2 h2rob h2rof h3roh h3rol h4rome h4romi h4ron h2ror h3rou hrr4 hr2s1ac hr4s3an hr2sau hr3sch hr2s1en hr2ser hr2set hr2s1in hrs3k hr2s1of hr4stec hr2su hr4sw hr2t5ab hr2tan hr2th hr2tor hrt3ri hr2tro hrt2sa hrt2se hrt4ste h3ruh hr1ums h3rü h4rüb h4ry hrz2 4h1s h4s3acht h2sa2d h4samt h2san h2sau h2säh hsä4s h3sc h4schan h2s1ec hse4ler h2s1erl h3s2ex h2s1ing h2s1o2f h2spac h2s1par hs2pen h2sper h2sph hs2por h2sprä h2spro hss2 h2staf hst3alt hst2an h4starb h2stau h2stäl h4stea h5stel hst2he hs1tie h2stin h2s1tor h3stö h3str hst3ran h2stu h3stun h3stü h2s1u hs2ung h3sy 4h1t ht1a h2tak h3t4akt. ht2al h2talo ht3alt hta2m h2ta4n ht3ane h3tank h3tann h2tar ht2as h2t3ass h2tasy h2t3a2t h2tau ht3aug h2tax h2t1är h3te. ht1ec h2t1ef ht1eh h3teha h3tehä hte2he h2teif h4teilz h2t1eim ht1ein h2t1eis h2t1eke h4t3elit h2temp h4tentf h4t3ents hter6de. ht3erfü ht3ergr h2t1er2h ht5erken h4terkl h6t5erleu h4t3er4re h6t5er6spa h4t3er4st ht6erste h2t1erz h2t1ese h2t1ess h2t1eu h2t1ex h2th h4thei hthe3u h2t1im h2t1in h4tl htni2 hto2 h2toly h2torg ht3rak ht3rand h2t3ras h2t3rat ht3rau h4traub ht6raume h3trec ht3reif ht3reit ht4ri ht5rieg h2t5rin h3trit ht3ro h2trol h2tros ht4rot ht3rös h2t3ru h2t3rü h4ts ht4s3an ht4s3end ht4spin ht3spri ht4stab hts2ti ht4s3tur ht4s3tür htt4 htti2 htu2e h2t1urs ht3z2 hu2a hu2b1a hu2bei hu2b1en hu2b3l hu4b3r hu2bu hu2h1a hu2h1i huk3t4 hu2l3a hu2lä hu2l3ei hu4leng hu4lent hu4ler hu2let hu2l1in hul3l hu2lo hu3m2a h1ums hu2n h1una hu3ni1 h1ups 2h2ur hurg2 hu3sa hu2so hus4sa hus3se hus2sp hus4st hu2tab hu3t2h hu2ti hut2t hut4zen hut4z3er h2ü h4übs h3übu hühne4 2h1v hvi2 hvil4 2hw h2wall hwe1c h1weib h1weih h2wirr 3hyg hyl4 3hyp hy2pe. 2hy2t 2h1z hz2a hz2o hzug4 i1a 2ia. i4aa i2ab iab4l 2iac i2af iaf4l i4a3g2 i2ah i3ai i2aj i2ak i3ak. i3akt 2ial i5al. ia2l1a4 ia2lä ial3b ial3d i3alei i3alent i3a4lerf i3alerh ia4l3erm i3a2let i3a4lia ialk2 i3al5l ia2lor ial3s ial3t4 ia2lu ial3z2 i2am4 i4amo 2ian ia2nal i3and2 ian2e i3ann i2a3no i3ant i3anz i2ap ia3pf ia1q i3ar. ia2ra i2asc ia3sh i2asi i2a1sp ias5s iast4 i3at. i3a2ta i4ate i3at4h 1iatr i3ats i3au ia3un iau2s1 2iav 2iä i1äm i1äp i1är. i1ärs i1ät. i1äta i1ät3s4 2i1b ib1art i2b1auf ib3be ib2bli ib1ei i2beig i2beis ibe4n iben3a ibi2k i3bla i4blad i3blä i3ble i4bleu ib2o i2bö i4brä ib3ren ib2ser ib4ste i2bunk i2bunt ibus1c ibus3s 2ic ic1c ich1a ich1ä i1che ich1ei ichermas8 ichgro3 i1chi i2chin ich3l i3chlo ich3m ichmas4 i1cho i2ch3r ich3ter ich2tr i1chu ich1w i1ci icks2 i1cl i1d id2ab4 i3d2ac i3dam id1au idbu4 1i2dee idein3 i4deis idel2ä ide3so 1i2dio idni3 i2dol 1idol. 2i2dr i3dsc id2s1p idt4 1i2dy ie3a4 ie2bä ie2bl ie2bre ie2bri ieb4sto ieb4str ie1c ie2cho ie2dr ie1e2 ie2f1ak ie2f1an ie2fau ief3f4 ief2i ie2f3l ie2fro ie4g3l ie3g4n ie2g3r ie3g4ra ieg2s iegs1c ieg4se ieg4s1t i1ei i2e2l1a ie3las iel3d i2ele iel1ec ie3lerd ieler8geb ie4less i2eli i1ell iel3lä ielo4b i2els2 iel3sz iel3ta 2i1en i3en. i3ena iena2b ie4n3a4g i3e2nä ien3d i2ene ien1eb ie3ner ien4erf ie4n3erg i3enf i3eng ienge4f i3enh i3enj i3enk i3enm ienma3s4 i3enn i3e2no i3enö i3enp i3enr ien3s2e iens2k ien6st5er ien6stop iens4tr ienst5rä ien3sz ie1nu i3env i3enw i3enz ie1o2 iera2 ier3ad ier3an ie2r3ap i2ere ie3red ie3r2er ie4rerf ie4r3erz ie3res i3ereu ierf4 i4eri ierin3 ier3k4 ierken4 ierma6ss i1ern i3ern. i4erna i2er5ni ie2rö iers2e ier4s3eh ier3sta ier3te ie3s2 ie4sh ie4s3k ie4spu ies4s iess1t ie4stas iest6e ie2t1a ie4t3erh ie4t3ert ie2t3ho ie2t1o ie2t3ö2 ie2tri ie2t3ru iet2se i1ett ieu2e ie1un ie2w3u i1ex 2if if1ar i2f3arm if4at if1au i2fec ife2i if2en if1erh if2fa iffe4s if6feste if2fl if4form iff2s if3l i1f4la if4lä i1flü if3r if4ra i1frau i1fre if4rei if4rü if3sa if2ta ift3erk if2top if2t3ri ift1sp ifts2t ift3sz 2i1g iga1i i2g1ang ig1art iga3s i4gefar ige4na ige2ra ige3ran igerma3 ig1erz i2g1im i2gl ig1lä i4glo ig4na i4gnä i3g4neu ig4no i3go ig4ra ig3rei igro3 ig3s2a ig4sal igsau4g ig1so ig1sp ig2spa ig4sti ig4s1to ig2stö ig4s3tre 2i1h i2h1am i2har i3he ihe1e ihe4n ih3m ih3n ih3r ih2s ih3sp i2h1um ih1w ii2 ii3a4 i1ie i3i4g i1im i1in i1i4s i2is. ii3t i1j 2i1k ik1ak ika4ka ik1amt i2k1ano ikanten8n ik1anz i4kanze ik1art ik3att i2k1au i2k1är 4ike i2k1ei ik2e2l1 i2k1e4r2e ik1erf iker6fah i2k1er2h i2ker2l i2k1eta i3ki. ik1in i2kind i2k3l i3kla i3k4lä i2kn ik3no ik2o3p4 ikot3t i2köl ik3ra ik3rä ik3re ikro3 ik3so ik3s2z ikt2e ikt3erk ikt3r ik2tre i3kus i1la i2l3ab il1a2d i2l1ak i2l3a2m il1ans il1asp il1au il4aufb il3aus i2laut i1lä1 4ilb il2c il2da il4dac il4d3en4t il3d2er ild1o il2dor il2dr il1ec ileid4 il1ein il1el i4lents i2l1erf i2l1erg i2l1err il2erz il2f3l il2f3re ilf4s1 ilg2a il2gl ili3e4n1 ilig1a2 ili4gab i2l1ind i2l1ip i3lip. i3lips 2ill. il3l2a il4lad ill4an il2lä2 il2leg ille4ge il3l2er ill2i 2ills il2mak il4mang il2m3at il2m1au il2min 2ilo i2l1or ilt2 il3th il3tr i1lu2 i2lum i3lus ilv4 il2zar ilz3erk 2im. i2manw i2m1arm im4at ima2tr imat5sc ima4tur 2ime i2mej i2m1ele i2melf i3men i2m1erf i2m1erz i4mesh i2meti i2m1inf i2m1ins im4m3ent im4mit im4mod imni2 2imo im1org imp2fa 1impo imp4s im3pse 1impu im2str 2imt imtu2 2imu in1ac in3ach. i4nack i2n1ad in2af ina4lin in1am i3nap in2ars in2art ina4s i2n3au2 inaus1 in1äh in1äs inbus2 in2dal in2dan in3dau indes4t 1index in3do 2indr ind4ri in3drü 1indus in3d2ü 2ine i2n1e2be in1ehe i2n1eng in3erbe i4nerbi in2erh iner4lö i4n3er4tr i3nes i4nesk in1eu ine3un ine2x in3f 1info. 1infos 2inga ing1af in2g1a4g in2gl ingmas4 ing3sc ing4sto 1inhab 2inhar 2inhau 4inhe in2i3d 2inig ini3kr in2ir 2inis ini3se i3nitz 3inkarn ink4ste in3k2ü inma4le 2inn. in4n3erm in2neu in4ni2v 2innl in2nor inn4sta 1innta 2ino in1od in3ols in1or ino3t i1nö in1ö2d 2inp 2inr ins2am insch2 2inse. in2seb 2insen ins3ert in3skan in3skr in4s3tät ins2te ins2ti in3su 1insuf in4s3um in3s2z i4nt 2inta 1integ int2h in3t4r int3s in1u i3n2um in3unz invil4 i1ny i1ñ 2i1o ioa4 io1c io2d i2oda io3du io3e2 iof4l i2o3h io2i3d io3k4 i3ol. i3om. i3oms ion2 i3on. ional3a io2n3au ion3d i3on4s1 ions3p ion3t i2ony i2o1p io4pf i3ops i3opt i2or i3or. i3orc iore4n i3orp i3ors i3ort io3s i2ost ios2u i3ot. i3ots i2ou i2ov io2x i3oz. i1ö2k i1ön i1ös. 2ip. i1pa i1pe ipen3 i3per iph2 2i1pi ipi3el ipi3en i3p4l ip2pf ip2pl i1pr 2ips 2ipu 2i1q i1r2a i3rad 1i2rak ira4s irat2 i1rä ir1äh ir2bl ir1c ir2e i3ree 2irek irg2 ir2gl irg4s ir2he ir2i 2irig 2irk ir2k3l irli4n ir2mak ir2mau ir2mä ir2m1ei ir2mum ir4m3unt 2irn ir2nar ir2no i1ro 1iron i1rö irpla2 ir2rei irre4l ir4reli irr2h ir4schl ir4schm ir4sch3w ir3se ir3sh irt4s1t 2iru iru2s1 i1s i3sac i4s1amt is2ap is3are i2sau i2s1än 2isb i2sca i3s2che i4schef i4sch3e4h i4sch3ei i2sch1l isch3le i2schm isch3ma isch3ob isch3re isch3ru i4schwo isch3wu i2s3cr 2ise ise3e ise3ha ise3hi ise3inf i4seint ise2n1 ise4n3a is2end isen3s i2serh i2s1erm iser2u i2s1ess i4s3etat isi2a i2s1id i2s1of iso2n isonen4 iso6nend is1op 3i2sot 2isp is1pa i2spar is1pe is1pic is2por i2spro is3sa is4s1ac is4sau is3sc is4s3che is3senk issermas8 is3so is3spa is4sper is3spo is2s1t is3sta is4ste is3sto is3stu is2su i2stab ist3ac i4stam ist2an i4stea iste4n is2ter ist4ra is3tras3 ist3re is1trü i2stur is1tüm i2sty isum3p i2sü i1ß iß1ers i1ta it1ab. i3tag ital1a ital5l it1alt it1a2m it1ang it3a4re it1art i3tat it1au i3tauc i2tauf i2t1ax 4i1tä i2t1äs ität2 i1te i2tei i4t1eig i4t1ein 2itel ite2la ite4n itens2 i4tepo i2tex i3thr i1ti i2t1id 1itii iti4kan iti3k2e i2t1in1 it2inn i3tis it3iss i3tiv i4tl itmen2 i1to i3toc i2t1of i1tö i1tr i3tra. it3raf it3ran it3ras it3rau it3räu it3re it3rom it4ron i3tru it3run it2sa it4s1a4g it2s1e4 its3er1 it4set it4stec it4s3tem it4s3tes it2sti it4stie it2s1to it6stra6s it2teb it4temp it2tri i1tu it1uh i2t1um i2tuns it1urg itut4 i1tü 2itz it2zä it4z3er4g it2z1w 2i3u2 ium1 ius1t i1ü 2i1v i2v1ak iv1ang i2veb iv1elt ive4n iv1ene i2v1ent iv1erl i2v1ur 2i1w iwur2 2i1x i2xa ix2em ixt2 4i1z iz1ap iz1au iz2ei izei3c ize2n i2z1ene iz4er i2z1ir izo2b i2zö i2z1w í1l jah4rei jahr4s ja3l2a ja3ne jani1 jani3t2 2jat je2a jean2s je2g jek4ter jektor4 jek2tr je3na je2p je2t1a je2t3h je2t3r jet3t je2t1u2 ji2a ji2v joa3 jo2b1 job3r jo2i joni1 jo1ra jord2 jo2sc jou4l j2u ju2bl jugen2 jugend3 ju2k jung5s ju3ni jur2o jute1 2j1v 1ka 3ka. k1a2a ka3ar kab2bl ka2ben 2kabh 2kabla 2kablä 2k1a2bo ka3b4r 2kabs 2k1abt ka1c k2ad 2k3ada 2k3a2dr ka1f4l ka1fr kaf3t2 k2ag ka1in ka3ka kaken4 ka1k4l 2kakt 2kala. ka2lan ka3lei ka3len. ka4lens kal3eri kal2ka kal2k3l kal2kr k1all kal3lö3 kalo5 kal2tr ka2lu k3ama kamp8ferf kan2al ka4n1a4s ka2nau kand4 2kanda kan2e 2k1ang kank4 2kanl 2k1anna k1ans k2ans. 6kantenn ka3nu3 2kanw k2anz. ka2o 2k1apf 3kara 2karb k2ard k2arg kari3es k2ark 2k1arm karp3 kar2pf k2ars kar3t k2arta 2k1arti karu2 k2arw kasi1 ka2sp kas3s ka3tan ka3t4h ka2t3r kat3se 2katt kau2f1o 4kaufr kauf4sp kauf6s5te k1aus kau3t2 2kauto 1kä k1äh k1ä2mi k1än kär2 kä2s5c käse3 kä3th 2k3b2 kbe1 kbo4n kby2 2k3c 2k3d2 kdamp2 2k1ec k1eff kefi4 kege2 ke2gl ke2he. kehr2s kehrs3o kehr4st 2k1eic 2k1eig k1ein ke1in2d 2keinh 2k1eise ke2l1a ke3l2ag ke2lä kel3b4 2k1e2lek ke2len ke2l1er 2kelet kel3la kell4e kel3li kel3s2k k4elt 2k1emp k2en. ken3a ke4nac ke2nä kenbu5s4 ken3dr 4ken4gag 2kenlä ke2no ken4sem kens2k ken5s4te ken3sz k3en4te. k3en4ten ken3th 2k1ents 2kentw 2kentz 2keo2 ke2pl k2er. ke1rad k2erc ke3reig 4kerfah k4erfam k3ergeb ker6gebn k3er2hö ke6rin6nu kerin6st kerin4t ker4ken k2erko k2erl k4erl. ker4lau k3er4leb k6erlebe k4erlö ker4neu k1ero ker4reg k2ers. kerz2 k1erz. ker4zeu 2k1er2zi k6es. ke2sel ke2t1a ke2t3h ket3s ke1up keu6schl 2k1e2x 2k3f4 2k1g2 2k1h4 kho3m ki3a4 ki1ch 2k1i2de ki3dr ki2el kie2l3o ki1f4l ki1f4r ki3k4 2kil2a ki3lo k2imi k2in. k2ing 2kinh k2ini k2inn ki3n4o kin3s 2k1inse 2k1int ki3or kio4s 5kir kis2p kis5s kist2 kiv2 2kiz ki3zi 2k3j 2k1k4 kl4 4kl. 4kla. 4kland k4lar 4k1last k3laug k2le 4kle. kle2br k3lee 4kleh k4leid 4k3leit k3lem. 2k3ler kle2ra 2k3leu kle3us 2klic 2klig k2lim k2lin k2lip k2lir k2lisc 2klist klit2s 4kliz 2k3loc klo2i3 k3lor klos2 2klos. klo3sse klost6 k2löt k1lu k2lud kluf2 k2lug k1lüc 2kly 2k1m kmas2 k2n2 3knab k3ne k4nec k4nei 2knes kni4e kno4bl 2k5nor k3nu 3knü 1ko ko2al 2kobj 2k1o2fe koff4 koh3lu ko1i2 kol2a ko3le kol2k5 3kom ko4mu k2on ko3n2e kons4 ko3nu 2kop. ko1pe kop4fen 2kops 2kopz ko1r2a 2k1orc kor6derg ko3ri kor4n1a k2os ko2s1p ko3ta kot1s2 kot4tak 2k1ou 3kow ko2we k1o2x 1kö kö2f k1öl 2k1p2 2k3q k2r4 2k3rad k4ral kra4s3 k3rats 2kraum k4raz k4räc k4rän 2k3rät 2k3räum 2kre. 2k3rec 2kred. 2k3rede 2k3ref 2kreg k3reic kre1i2e4 kreier4 k3reih 2k3rh 2krib 2k3ric k3ries 2krip 3kris 3k4ron kro4ss 2kruf krü1b 2k1s k4s1amt k2san ks4ana k2sau k2s1äl ks2än ksch4 ks1e2b k2sent ks1erl k2s1ers k2s1erw k3shi k2s1id k2s1in k2s1o2 ks1pa ks2pat k3s2pe ks2por ks2pu kss2 kst4 k2stal k4s3tanz kstat4 k4stea k2s1tis k2s1tor k2strä k2stum k2s1u ks2zen 4k1t k2t1ad k3tag kt1akt k3tal kt1am kt1an k2t3a2r kta4re k2t3au ktau2s ktä3s kte3e kt1ei k2temp k2tent k4t3erfo k2t1erh kte3ru k2tex k2th kt3ho k2t1id kt1im k2t1ing kt1ins kti4ter k2t1of k3top k4torga kt3orie kt4ran kt3ras kt4ro kt3run kt3s2 ktt2 k2tuns kt3z ku1c ku2h3 2k1uhr kul2a ku3l2e ku3l2i 2kulp 2k3uml kum2s k2u3n2a kun4s kunst3 2kunt 2kunw 2k1up. kur2bl ku2rei kuri2e ku2ro kur2sp kur4st ku4schl ku2sp kus3ses ku2su ku2ß 1kü kü1c kür2s 2k1v 2k1w 2k3z2 kze3l 3la. 3l2ab. la3ba 2labb lab2br 4l3aben 2labf 2labg 2labh 2l1a2bl lab2o l2abr lab4ra lab4ri 2labs l1abt 3labu 2labw la1ce la2ce. 1lad lad2i l1adl 2ladm 2l1a4dr l1adv 2laf la2fa laf3t la2ga la2gio la2gn lago2 la2g1ob lag5s2e 2la1ho 1lai lai4s1t la2kes la2k1i l2akk la1k4l 2l1al 4lalp l2ami la3min lammen8ge 1lammf l2amp 4l1amt lamt4s la4mun l1anal la2nau 2lanb 3l2and lan2d1a2 lan4d3au lan6d5erw lan6d5erz lan2dr lan4ds laner2 2lanf lan2gl lang3s2 l2anhe 2lanl 4lanli 2l3ann l1anp 2lans2 4lansä 2lantr lan2z1w 3lao 2l1apf l1a2po lap4pl la2r1an la2r1ei la4rene 3l2ar3g lar3ini l2armi 2l1ar3t l3arti la2ru la2sau 4lasd la5se 3lasg 2lash 2lasi la2so 2la2sp 3lasser la2sta last1o la2str las3tur la2stü 1la2ß3 lat2a la3t2e la4tel 2l3ath la2t3ra lat2s 2lat2ta lat4tal lat4tan lat4t3in lat2t3r 1laub. laub4se lauf1i lau4fin lau2fo 1laug 3laun l2aus. 2lausl 2lausr 2lauss 2lauto 1law lawa4 lä1c 2läf 2l1ähn 1länd lär2m1a l1ärz lä2s5c lä4s3s 4lät 2läub 2läuc 2läue 1läuf 1là 4l1b l3bac lbb2 l2b1ede lb3eise l4beta l2b1id l2b1ins lb2lat l3blä lb3le l2bli l3blo l3brec lb3rit lb2s lb3sa lb3se lb4sh lb3si lb4sk lb3sp lb4st1e lb4sto lb2u l2b3uf lbus3s lbzei2 2l1c lch2au l3che l4chei l5chen lchermas8 l3chi lch3l lch3m lch3n lch3r lch3s lch3ü lch1w l3cl l3co 4l1d ld3a2b1 l3d2ac ld3ack l2d1a2d lda4g l2d1ak ld1al l3dam ld1amm l2d1a2n ld3ane l2d1a4r ld3ari l3das ld1au ld1är ldbus2 l3de. l2deh l2dei l2dele l3der. l3d2erl l3d2ern l2d1er2p lder4tr l2d1e2se l2dex ldi2c l2d1id l2d1im l2dob ldo2r ld2os ld2ö2 ld3r l2dran ld4ros l3d4ru ld4rü ld3sa lds2t ldt4 ld3th l2d1um ldy3 ldys2 1le 3le. le2a le3an le3ar 3le3ba leben4s le2bl 2lec lech5t4e 3led 4ledd le2er lef2a le2g1as le2gau le2gä le2gl 3leg4r 3leh leh3re 4lehs 4leht lei4bl lei2br l2eic l2eid 4l1eig le2im l2ein. leinbu4 leinbus5 l2eind lein4du l2eine lei6nerb 4leink l1einn l2eint l2einu lei6schw lei6ss5er lei4str lei4ßer l2eit lei2ta lei8t7er8sc lekt2a 2lektr 3l2ela 2l1e2lek l2eli lel3s 3lemes le2m1o2 4lemp l1emu l2en. le4nad le2nä 4lendet 2lendu 4lendun le4n3end 4lenerg l1engl le3ni l2enk 2l1enni le2no len4sem len3sz 2lentf l1ents 2l3entw lent4wä 5lentwet len2zi le1os 2lep 3lepa 3lepf lep4pi 3lepr l2er. l2e1ra le2ra4g le2rap le2rau lerb4 l3erei4g ler6eign le4r3ei4m le4rers 2l1erfo l2erfr l2erfü l3ergeb 3lergeh l3ergen 3l4ergew 2l1ergi lergro3 lerin4s lerk2 l2erka l2erko l4erlei le1ro le2rob 2l1erö 3l2erra l4ers. lers2k 3lerw l4erwa 2lerwo 2l1erz l2erza ler2zi les2am les2e 2l1esel le3sh lesi1 le3sk les2ko le2spo les3s leste3 4lesw 2lesy le2tat 2le3th let2to2 le2u 4leud 3leut 2lexe le2xis 2lexz 2l1f l3fah lfäs3 l2f1ec lfe1e l4feis l3f4lä lf3lo l3f4lu lf3ram lf2s lf4spe lf4s1ti lf2tr lf4u lfun2 lfur1 l3fü 2l1g lg1art l3gas lga3t lg1d4 lgen2a lge3ra lgeräu3 l2geti lg2lö l3go lgoa3 lg3re l3gro lgro3s lg2s lg4s1t 2l3h2 3lhi. 1li 3l4ia li3ac li2ad li3ak li3ar lib4 libi3 li1c 3lic. li3chi 4lick li3d2a 2l1ido li4ds l2ie liebe4s li3ene lie4s3c lie4sta lif2fo 3lig lig4n li2gre ligs2 li3ke li3ko lik2sp lik4ter li3l2a li3li li3m2a 2l1imb 3limo 2limp li3n2a lin3al 2l1indu li4ned li2nef li2neh li2nep li2nes 2l1inf ling4s3 2l1inh 2l1in1it 2l1inj lin2k1a link2s li2nol l2ins. l2insa l2insc 2linsp 2l1int li1nu l1inv 2linz li2o li4om lion5s li3os. li2p3a 2li2po 3lipt 3lis. li3s2a li4schu 2l1isl 2l1i2so li2sp liss2 2liß li2tal li3te li1t2h lit1s2 lit3sz li2tur 3liu liv2e livi1 2lixi li2za lizei3 4l1j 2l1k lk1alp l3k2an l3kar. lken3t lk2l lk3lad lk3lic l2k3lö l3k4lu l3k2me lk4ne lk5ner lkor2b1 lk4ra l2k3ru lk2s1 lk3sä lk4stä lk2ü 2l1l ll1abb lla2be l2labt lla2de ll1aff ll1akt l3l2al l2l1a2m ll3ama lla2n ll2anw ll1anz ll1arm lla6tern l2lau ll3aufg ll3aufk ll3aug ll1aus l4lausf l2la2w l2läd l2l1äm l2läu llb4 llch4 ll3d4 l2le2b l3lec ll1ech l2l1ef lle2gu lle2he l2leib ll1eim ll3eise ll2em l3len. lle4n3a ll3endl llen3dr ll3en4du ll2eng l4lents l3ler. lle2ra l6lereig ller4fo ller6geb l6lergen l4lergo ll3ernt ll3ertr ll6erwei ll2es l2le2se l2leuc l3leur. l2lex llf4 llg4 l2lic l2lieb l2lieg l3lik4 lli4la ll1imp l2l1ind l2l1ins llin6sen llk4 ll5m lln2 ll1ob l2lobe l2lo2d l2l1of llo2gi ll1opf l2l1o2r l3lor. l3lore llo2te l2l1ou l3löh ll3sä ll3sh ll3s2k ll2spr ll4stor ll3t llti2m llt4r llts2 llu2d llu2f llu2me l2lu2p ll1ur llust6 l2lüc llü2d ll3z2 4l1m l3ma. l2m3a2b l2marc lm1art lmä2s lm1ä4st lm1c lm2ei lm3eins lme4na l2m1e2p l2m1erz lm1ind lm1ins lm3m l2möl lm3p lmpf4 lm3s2z lm3t 4ln lna4r ln3are l3n2e l3ni l1nu l1nü 1lo lo4ak 3l2ob. lo2ber 2lobj 2l1o2bl l2obr lob4ri 3lodr l1o2fe lo1fl lof4r lo2gau lo3h2e 2l1ohr loi4r 3lok lo2k3r lol2a l1o2ly lo2min l4on lo2n1o lo2o 2lopf lop2pr 2lopt lo1ra lo2rak lo4rä 5lorb 2lorc l1ord lo3ren 2l1or3g2 3los. lo4sa 3lose lo4ske lo2spe loss2e lo4steu lo2s3to lo2s3t4r lo2ßu lo2ta lo3tha loti4o 2l1ov lo2ve 2lox 1lö lö2b3 2löck 2löd l2ö2f 2l3öfe 4lög l1öhr 2l1ö4l 4löß 2l1p l3pa lpe2n3 lp2f l2p1ho lp3t4 l3pu 2l1q 2l3r2 lra4ss lrat4s lrö4 lrös3 lrut4 lrü1b 4l1s l3sac l2sa2d l3s2al l4s1amb l4samt l2sanf l2sang l2sann l2sanz l3sare l2sau2 ls2äm lsä4s l4schin l4schmü l3se. l2s1e2b l2s1ec l2s1em ls1ere ls1erg ls1erl l2s1ers l2s1erw l3ses l3s2ex l4s3ha l2s1id l2s1imp ls2log ls3ohne l4s3ort. ls2ö l2spac ls2pe l3s2pi ls2po ls2pu l3spul ls3pun ls3s2 lst2a lstab6 ls2taf l4s3täti l2s1tis l2stit ls1tor l4stor. l4store l4stors ls2tr ls1um l2sun 6l1t l2tab ltag4 lt1ak lt1am l3tami lt3and lt1ang l4tarm lt1art l2t3ato l2t1au lt1eh lt1ein l2t1eis lte4lem l3t2en lten6gel lter3a lter2f l3t2erg lter6ken lter6leb lter4nä lt2erö lte3se l2t1esk lte3str l3tet. lte2th l2t1eu l2th l3thas lt3ho l3thu ltimo4 l2tob l2t1of l2t1o2ri lto2w lt1öl l3tön lt1ös lt1öt lt4rak ltra3l lt3räu l2t3re lt4rie lt3roc lt3ros l2t3rö l4ts lt1spa lt4stab lt5ste ltt2 lt1uh l2t1um ltu4ran ltu2ri lu1an 4lu4b3 luba2 lubs2 lu2dr lu2es 1luf 2l1ufe 2luff luf2t1a luf2t1e luf2tr lu2g1a lu2g1e2b lug3erp lu2gi lu4g3l lu2go lu2g3r lu2gu 2l1uh lu1id. lume2 2lumf 2l1umj 2lumk 2luml 1lumpe 2l1ums l1umw 1lu2n 2l1una 2l1unf 4l1uni 2lunt 2lunw 4lu2o lu2pf 2lur l1urn l1urt 2luse lu2sp lus4s3a lus2s1c lus3sen lus2s1o lus2s1p lus4s1t 1lus2t lu2st1a lu4stä lu3str lust3re lu2s1u 4lu2ß1 lu2t1a lu4teg luter2 lu4t3erg lut1o2f lu2top lu2t3r lut5schl 3lux 2lüb 2lüd lüh1l 2l1v 4l3w 2lx 1ly ly1ar ly3c 2lymp 3lyn ly3no ly1o lys2 ly3te ly1u 2l1z l2z3ac l3z2an l2z1ap lz1ar l2z1är l3zen lz2erk lz1ind lz3l lzo2f l2zö lz3t2 l2z1u4fe lzug4s lz1w lz2wec 1ma maa2 m1ab m2abe 2mabk 3m2ab4r 2mabs ma3chan mach4tr ma2ci ma3da m2ade 2madm ma2d4r ma4d2s ma1f ma2ge. ma2geb ma2gef ma2geg ma2gek ma2gep ma4ges. ma2get ma2gev ma2gew 2m1agg magi5er. magi5ers 2magm ma3g4n 2m1ago mai4se 2m1akt mal1ak ma4lakt ma2lan ma4l3at ma2lau ma3le mal2er mali1 mal3l mallö3 2mallt malu4 ma2l3ut mam3m 2m1anal ma2nau 2manb man4ce. man3d2 man3ers ma2net m2anf 2m1angr m2anh 2manl m4ann man3s 2mansa 2mansä 2mansc man4sh 2mantw manu3 2manz ma2or 2m1apf m2app 2m3arb mar3g2 mar2i 4ma3r2o maro3d 4marr mar6schm mar6schr ma3r2u m3arz 3mas. ma1s2pa 2m1aspe ma3sses mas6ses. mas6sest ma6sset ma3s2su 3mas2t ma2ta2b ma2tan mat4c ma2tel ma4t3erd mat3se mat1sp mat3url 2m1au2f 3maul ma3un 2mausg m4ay ma1yo 1mä 2m1ähn mä1i2 4m1änd 3männ 2mäo m1ärg mä1t4r mäu2s1c 2m1b2 mbe2e mb6l m3b4r 2mc m3ch 2m1d md1a m2d1ä m2dei mds2e m2d1um 1me meb4 me2ben m2e1c medi3 medie4 medien3 2medy me1ef mee2n1 mee4r3ei mega3 3meh 2m1eif 2m1eig mei3l2 mein4da m2eis2 me1i2so me3lam me2lau 3meld me2lek me2ler melet2 2melf. mel2se mel2sp mel3t4 6mel6tern 2m1e2mi 2m1emp m2en. mena2b me3nal men3ar men3au 2mendl men3ge m4ens men4sk men2so men3ta 2mentn ment4sp 4m3entwi me1o 2meou 2meö 3m2er. me1ra mera1f me2r3ap me4rens mer2er 4m3ergän merin4d merin4t m4ersh merz4en 3mes me2sal me2sä mes2e 4meser 2me3sh 4m1essa mes6ser6g mes2s1o mes2s1p meste2 me2str 4mesu 3me2ß1 m2et me3t2a me3th me3tr meu1 2m1ex 1mé 2m1f4 mfi4l 2m1g2 2m1h4 1mi mi2ad mi3ak mibi1 mi1ch mi3da mie3dr mi2e1i mie3l mi2er mierer4 mi2et mie4ti 3mig mi2kar mi2ki mi2ku mi3l2a 3milb 3milc milch1 mil4che 2m1imp min2en min2eu min2ga mi3ni min2o mi1nu 3minz mi2o mioni1 3mir. mi3ra 3miri 3mirs 3mirw mi2sa mi4scha mi4schn mi4sch3w mise1 mis4ser mis3si mis4st mi2sta mi2ß1 3mit1 mi2ta mi2th mi2tr mit3s2 mit5sa mi3tsu mit3ta mi2tu 4mitz 2m1j 2m1k4 m3ka mk5re. 2m1l2 ml3c ml3s 2m1m m2mab m2m1ak m2m1al mm1ang m2m1ans mm1anz mm1art mma2ß m2m1au mmä4 mmd2 m2me2c m4meh m2mei mm1ein mm3eise mme4lin mme4na m4mentw m2me2nü mme2ra mme4rec mme2s3a m2me4te mm1inb mm1inf mm1inh mm1ins mm1int mmi3sc m4mita mmo2du m2mo2l m2mor m2m1ö mm3p2 mmpf4 mms2 mm3te m2mum m2mus 2m3n2 m4nesi 1mo moa3 2mobj 3m2od mode3s mo2dr 4mog. mo2gal 3moh mo2i3 mo2k1l 2mol. 3mom mom2e 3m2on mo2nä mo3ne mo4n1er mon3s 3mo2o 2m1ope 2mopt mo1ra mo2rar 2m1orc mor4d3a mor2dr mo2rer 3mos mo3se moster4 3mot m1o2x mo1y 1mö mö2c 4mök m1öl 4m1p mpa3ne m2pf mp4f3erg mpf3erp mpf3err mp4f3erz mp2f3l mpf1or mp1hos mpi3as. m4p3lem. m2p3len m2p3les mp4lif m3pon mpot2 mp3ta m3pu 2m1q 2m3r2 2m1s m2san ms3and ms1as m3sä msch2 m4s1ef ms1erf ms1erw ms1ini mso2r ms1ori m2spä m2sped ms2por m2spot m2spro ms2pu ms3s2 m4stag m2stal m2sü 2m1t mt1ab mt1ak m3tam mt1ar mt3are mt1ein mt1elt m2t1erf m2t1erg m2t1erl m2t1ers m2t1ert m2t1eta m2t1eu m2th mt3ho m2t1im m2t1ins m2tint mti2s mtmen2 m2töl mt1ös mtra4s3 m2trö m4ts mt2sa mt2s1e mt3s2ka mts1p mt1spa mtt2 mt1um mt1urt mt3z 1mu mu1a 2m3uh mu3la 2muls 3mun mun2d1a 4m3unf 4m3ungeb mu3ni m4unk m2unr munt2 4munz mu3ra mu4r1u2f 3mus. mu4s1a mu2s1o mu2sp mu3s4se. mu3s4ses mu2s1to mu2str mu2su muße3 muts3t mut4str 1mü 2müb 3müh mü2her mül2 mül3lu 3mün mü3s4si 3müt 2m1v mvoll1 2m1w2 mwa2 mwa4r mwel4t3 mwu1 1my 2m1z mzug4 1na 3na. 2n1ab na2bä na3ber 4nabg 4nabh na2bl n2abo na2br 4n3abs 4nabt 3na2c nach1 na3chen nach3s nach8ters nacht8raum 4nadd n2ade 4n1a2dr n1af na1f4r 3n2ag na2gem 3n2ah na2h1a n4ahm n3ahn 3nai nai2e n3aig n3air 2n1ak na2ka 3nako n2al. na2l1a2 na4lal na2lä 3n2ald n4ale na4lent na2let nal3la nalmo2 na2lop nal2ph n2als. nal3t4 na2lu 2naly 3name na3me. n2amen namen4s3 4n1a2mer na3m4n 3namo nam2sp 2n1amt namt4s 2n1an. 4n1a2na 4nanb n1and2 4n1ang 2nanh 2nani 4nank 2nanl 3nann na3no n1anp 2nanr 4n1ans 2nantr 2nanw nap2si n1ar 5nar. na2r1a 2narc n2ard 4narg 3nari n2ark n2arle 2narm 4nart n3arti na3r2u 3nas n2as. na4schw 4nasp 4n1a2sy nasyl2 3naß 3nat n4ata n3a3t4h na4the 4n1atm nats1 nat4sa nat4sc 4natt n1au 4nauf nauf4fr n3aug 5naui 3n2aul 4nausb 4nausg n2auso 4nauss 4nausw navi5er. navi5ers 1nä 3n2äc 3näe 2n1ähn 3näi 2n1ä2m 2n1än n1ärz 3näs nä2sc n2ä6s3s 3näß 2näu 3nä1um 2n3b4 nbe2in nbe3n nbe3r2e nbu3s nby2 2n1c n3ce2n3 nch3m 2n1d nd2ag n2d1ak n2danl nd1ann n2d1anz ndat2 n2d1au nd1c nde4al. n2dei nde4län n4dentl n4d3ents nder6laß nder6läs nde4rob nde2s ndes1e nde4spe ndi2a3 n2dob ndo2be nd1op nd1or ndo2ri n2dö n2d3rat n2d3re n2drob nd3rol n2drö n2d3run nd2sor nd2spr nd3th ndt4r n2duns n2dü ndy3 1ne 3ne. ne2ap nea4s ne3at ne2bl 2n1ebn 2nec 3neca 3ned 2nee3 ne2e2i4 ne3ein n1ef neg4 2ne2he. 2nehen2 3nehm 4n1ehr 2n1ei 4neier 4neif 3neigt 4n3eing 4n3eink ne2ke nek3t4 ne2l 3nela nel3b 2n1ele 4nelek 4nelem ne3len ne3li 3nelk n2ell nel4la4 nel4lif 3ne3lo 3ne3lu n2em. 2n1emb nem4e n1e2mi 2n3emp 2n1ems 3nen n2en. n2en3a2 ne2nä n2enb n2enc 4n1endb 4n1endd 4n1endf n1endg 4n1endh 4n1endk 4n1endp 4n1endt 4n1endw ne2n1e2b nen3ei nenen1 ne4nene n2enf 4nengb nen4ge. nen4gen 4nengs 4nengt n2enh ne2ni n2enj nen3k ne2no n2ens nens4e nen3sk 5n2en3t2a n1entb 4n1entl 4nentn 5nentr n1ents 4n3entw 4nentz ne2n3u n2env n2enw n2enz ne2ob ne1os 2nepf 2n1epo ne2pos n2er. ne1ra ne2rab ne2r3af ne3r4al ne2r3am ne2ran ne2rap ne2rau nerb2 4nerbe. 4nerben n1erbi nere2 ne2reb n1erf 4n5erfo nerfor4 2nerfü 3nergr n1erh 4n3erhö 3neri n2erj n1erk n2erli 2n1erlö nerma3 nermas4 ner4mit n2ern. n1ernä ner4neu 4n1ernt ne1rös n2erp 3n2ers. n3ersa n2ert. ne2rup n2erv 2n1erz n2es n4es. nes2c ne2sei ne2sev nesi1 ne3ska nes1o ne2sor ne2s1pa 4n3essi ne2tad ne2t1ak ne2t1an ne2tap n1etat ne2tau ne2th net3ha nett4sc n1e2tu net2zi ne2u neu1c neuer4f neuer4k neuer4s neuer4w neu3g 2n1eup neur2 n2ew 2n1ex 3nez 1né 2n1f nf1ak nfalt2 n3far n3fi nfi4le. nf4l nf5lin nflös4 nf2o nf4r nf2tan nft2o nf2t3r nft2s nft4ste n2f1u 4n1g ng2abs n2g1ac ng1ad n2g1ak n2g1a2m n2g1and ng2anf ng1anz n2g1äl ng3d4 n3gef n2g1ein ng2en ngen2a ngens2 n3ger nge4ram n4g3erse ng6es nges2t nge4zän ng3g4 ng3hu n2g1i2d n2glic n2glo n3g2loc ng3m n2gn ng3ne ng1or n3gra ng3rat ng3roc ngro3s ng2s ngsa4g ngs1ah ngs3au ng4s3e4h ngs3pa ng3ts n2gum 2n1h2 n3han n3har n3hau n3hä n3he nhe2r n3hu 1ni 3nia nib4l nibu2 nicht5er nich8ters n1id 3n2id. ni2de ni3dr n4ie nie3b ni1el nie3l2a nie4n ni3ene ni1ero nig2a 2n3i2gel 2niget nig3r ni2gre nig2sp 3nik ni2kal ni2kar ni3ker ni4k3ing ni3kl nikma3 ni2kr 3n2il nim2o 4n1imp nin1 3n2in. n2in2a 4n3ind 2ninf 3n2ing4 4n1inh ni2nor 2n1ins n2ins. 4ninse 4n1int 2n1inv ni2ob ni3ok ni3ol n2ip ni3ra 3n2is ni4schw ni2s1e ni3se. ni2s1p nis5s2 ni2stu ni3stun ni2s1u 2nit ni1th ni2ti nit4r nit4tec nit4tie nitt4sa ni3tu 3nix n1j 2n1k n2k3ad n2k1ak n3k2al n4k3alg nk2am n2kans n2k3au4s n2käh n2k1äp nke4lei nkelma3 nkelmas6 n3k2er n4k3erfa nk4erg nk1inh n2k1ins nk3len nk3les n3klin nk2lo nk4na n2k1ort nk2öf n2köl n2k3ro nk2sal nks2ei nk3s2z nk2tak nk2tan nkt1it nk4top nk2tru n2küb 2n3l2 2n3m4 nmen2s nmül3 4n1n nna2be n2nada n4n1all n2n1an n5nat n2nau nn3d nn4ens n4nents nner4fü nn2erh nn2erk nne2rö4 n4n3er4wa nner2z nne2s1e n2ness nn2ex nn3f nng4 n3ni n2nof nn1o2r nn3se nn3s2p nn4s3pe nnst4 nn2th n2n1uf n2n1unf nn1ur 1no 3no. no2bla n2o3ble 3noblo 2n1obs no1c noch4r 2no2d no3dr n1of 2n3o2fe n3ole no2leu n2on. 3n2opa 3nor. nor2a no2rad n2o1rak no3ral 2norc nor4da nor2d5r 3norh 3norm 3nors n1ort 3n2os. no3se no3sh no2sp no4ss n2oste nost1r 2nostv nos2u no3tab no2tä no4t1ei no2tel no3t3h no4tha no2t3in no2top no2tr 3nov 3now 2n1o2x 3noz 2nöd 2nö2f 2n1ök 4n1ö4l nö4s3s 1n2öt 2n3p4 npa2g npf4 npsy3 2n1q 4n3r2 nra4s3s nräu3s nre3sz nrö2s1 6n1s n2sa2d n2sall n2sang n2sant n3s2arg n2saus n2s1än nsä4s n2s1äus ns2ca n4schl. n3schu nsch7werd ns1eb nse2ha2 nseh5ere n3senk nsen4sp ns1ent ns1erf n4serfo ns1erg n2serh n3seri n2s1erk n2s1erö ns1ers n2s1erw n2s1erz n3sex nsfi4l n2simp n2s1ini nsinn4s nsi2te nsi2tr ns2kal ns2kel n2s1op n4s3ort. nsp4 nspas2 n2spat n5s2pen n4speri n2sph ns2pi n2spo ns3pon n2sprä n4s3prie n4spro ns3s2 ns2t1ak n2stas n4stat. n4s3tate ns2tau n5s2te. n4st3eif n5stel ns4tem. ns4ten. n4stent ns2ter ns3term ns4tes. n5steu ns2tob n6stoffi nst5opfe ns2tor n4strac n6strieb nst4ru ns2tum nst2ü nstü1b n2sty ns2um n2s1un ns2ung ns2unr n4s3zi 2n1t nt3abs n3t2a3c n3t2al nt1ang n4tanza nt2arb nt1ark nt4at n2tauf nt1äm n2t1äu n3te. nte3au nte2b nt1ebe nte1e nte3g6 nt1eh nt1ein nte5lei n3t2en nt4ene nten6te. n3ter ntera4 nte4ras nt4erh nt4ern nt4ers nt4ert n2t1ess n3tet nte3v nt2her n2t3ho n3t4hu nti3k4l n2tinf n2t1inh ntini1 n3tit nt4lem ntmen2 ntmo2 n3to nton2s1 ntras3s nt3rec n3t4ree nt3reif n3trep nt4rig n3trop n2t3rü n4t1s nts2o nts2p nt4s3par nts2ti nt4s1to nttü3 3n4tu. ntum2 ntu2ra ntu4re. ntu4res nt3z 1nu. 1nu1a nu4ale nu3ar nubi1 1nuc 1nud 3nue nu2es nuf2 nu2fe 1nug 2n1uh 1nui nu3k4 n2um. 2n3umb 2numf 2numg 3numm 2numr 2n1ums 2n3umz nu2n 2nuna nunf2 1n2ung 3nung. n3ungl 2n1uni 2nunt 1nuo 2nup 2nur 3nu2s nu3sc nu3se nus1i nu3sl nus1p nu4s1t 1nu2ß 1nut nu2ta nu2t3r 1nuu 1nux 1nuz 2nü4b nür1c 1nüt 2n1v2 n3ver nvol7ler 4n1w nwei4st 2nx 1ny. 1nyh 2nymu n1yo 1nyr 1nys 1nyw 2n1z n2z1a4g n2zan n2z1au nz1än n2z1är nze4l3a nzel3l n4zense n4zentw n4zentz nz3erwe nzi2ga n2zinh nz1ini nz3le n2zor nz2öl nzug2s n2zurk nz1wa n2z1wä n4zwir n2zwö n2z1wu ño1 2o3a2 o4abi o4ac oa3che oa3chi o4ad oa3de oa4g o4a3i oa3ke oak1l o4a3la o4a3mi o2a3s 3oase oa4si o4at oa3te o5au o1ä o1b ob2al obal2t1 2oban o3bar 2o3b2ä 2obb ob2e 2o3be. 2obea ob3ein obel2i 2o3b4en oben3d4 oben3se ober3in4 obe4ris 2obew 2o3b2i obi2t ob3ite 1obj ob1l ob3lei 1o2b3li 2o3blo 2o3bo o2b3re obs2 ob3sh ob3sk ob2sta ob3sz 2o3bu obus3s 2o3bü 2oby2 2oc oc1c o1ce och1a ocha2b o1che oche4b o2ch1ec och1ei ocher4k och3l och3m och1o och3ö2 och3r ocht4 och3te o1chu ochu2f och1w o3ci ock2er ock3sz o1cl o3co o1ç o1d o3d2a od2dr ode2c o3d2e1i odein3 ode2n1 odene2 odesi1 ode3sp o3dex 2o3dia odi4er o3dir o3div o2don odo4s 2odr o2dre odt4 2odu o3dy 2o1e oe4b o2ec oe2d oe2h oe2l oe2n1 o4es o2et o3et. o3ets oe2x o1ë 2ofa of1ac of1au o2f1ei of2en o3fer of2fa of2f1in of2fir of2fix 1offiz of2f3l of2fo of2f3r offs2 off3sh of2fu of2fü 2ofi of3l of1la of4lä of4lö 2ofo 2o1f1r of3ra of3rä of4rü ofs1a of4sam of2spe of2spr ofstra8ssen of2s1u 2oft of2tei of3th 2o1g o2g1ab oga3d og1ala og1ang o2g1ei oge2l1i ogenmas6 o3gh ogi2er o3gis og2lo og4n ogo4i3 og2s og3sc og3si og3s2p o1ha o1hä o1he o2h1eis o2h1er2t o2h1er2z o1hi ohl1a oh3lec ohl1ei oh3len oh3lep oh4lerg oh4l3erh oh4lerw oh3lo ohls2e oh2lu oh4n1ac oh3nee 3ohng oh2ni 1ohnm oh2n1o o1ho oho2la oh1o2p o2h3ö ohr3a oh4rin oh1ro o1hu oh1w 2o1hy 2oi o1i2d o3ie o1im oimmu4 o1in oi2ra oi2re o2isc o3isch. oi3se o1ism oiss2 oi4st 2o1j 2o1k oka2la okale4 o3kat 3o2kel oki2o ok1lä ok2li ok4n 4okr ok2s1p okt4 2ol o1la o2lab o2l1ak ol2ar ol1auf o1lä ol4dam ol4dr ol1eie ol1eis oler2 ol1ex o1lé ol2fa ol2fl olf1r ol2fra olf3sp olf3st ol2gl ol2gr ol2i oli3k4 oli3tu ol2kl olk3r ol2kre ol2la2d ol2lak oll3ans ol2las ollä2 ol4l1ec ol4lei oll3ein ol2l1el oll5ends ol4lerk oll3erw ol4li4st ol2lo2c ol2log ol2lö2 oll3sp ol2lu ol3lus o3lo ol2of olo1p2 ol1ort ols2t ol2str o1lu 3oly 1olym ol2z1a ol4z3ern ol2zin ol2zw 2om o2mab oma4ner om2anw om1art o2m1au o2meb om1ebe ome3c o2m1ei o3meis o2mel o2mene o2mep omer2 o2meru om1erz om2es omiet1 omil3l o2m1ind om1ing om1ins o2m1int om3ma om3me om3mu om1org om3pf omp4l oms2 omtu3 o4munt omy1 2ona ona2b o2nae o3nal ona4lin on1ap o2narb on4at on2au 2onä on1äh onbe3 2onc onderer5 2one one4i one2n1 on1erb o2n1erd on1erg on1erö o3nett on3f2 on3g2l ong4r ong3s 4o3ni on2i3d o4nikr o4n1im on3ing on3k2 onli4n onlo2c on3n2an on3n2e ono1 o3nod o2noke on1orc ono3s ons1a onsa4g on2seb onse2l on4sh onsi2d ons3l ons1p onst2h on3t2a on4t3end ont3erw on2t3ri o1nu 2onuk on3v 1ony on3z o1ñ oo2k3l o1op o1or oo4sk oos5s oo2su oo2tr 2o1ö2 o1pa opab4 o2p3ad op3akt o3pan o1pec o1pei ope4n 1oper o1pes 2opf. op2f3a op3fah op4ferd opf5erde opf1l opf3la op1flü op3for 4oph2 o3phe o1pi opi5a2 opi3er. opi5ers. opin2 op3lag o2p3le op3li 2o3po op4pl 2o1pr 1opsi op3sz 1op3t4 o1q 2or. or1a or3a2b o1rad 2o1ral o2r3alm or4alt 3or2am or2and o2ranh or3arb o1ras or3att orau4 orau2s o3rä or1änd or1ät or2bar orb2l or1c 2orca or2ce 2orda or2d1am or4dar or4dau or4d3eng or2deu or4d3ing or2d1ir or2dit 1ordn or2do 2ordr 2ords or2dum 2ordw 2ore ore2a ore2b o2r1eck o2r1ef ore2h or1eig o2rein or1er o2rerf or1eth o2r1eu 2orf orf3s2 or3g4a 2orget or3g2h 2orgia orgi1e or2gl or3gle or2gn 2orh 2o3ric 4orie. o4rient o3rier 4oril 4orin1 or1ins ork2a or2k3ar ork4r 2orm or4mans or4ment 2orn or2nac or2n3ar or2n3ä or5ne. or3n2o 2o1ro or1o2b oro3n2a 2o1rö 2orp 2orq 2orr orr4a or3re or3rh 2ors2 or3s4a or3sh or3si or3sz or2t1ak or2t1an or2tau or2tär or2tef or4t3ent ort2er or4t3ere ort3erf ort3erk ort5ersc or2t3ev or2the or2tin ort3ins or4t3off or2tor or2tö or4trau or4t3räu ort3ric or2t1um o3ru or2uf o4r3un orus3 o2r3ü o2rya o1s 2o3s2a os3ad os4an o4s3ca osch3ar o4schä o3sche osch3le 2ose ose3e o2s1ei ose2n os2ex 2osh o3s2hi 2osi o3sk o4s3ka o4ski 2os2kl 2os2ko os2lo 2oso 2osp os1pec o3s2po os2sa oss1ac oss3and os4sä o6ssel o3ssem oss3en4k o3ssent oss3enz os3si os2s3o os4son os2s3p os4s1t os2su os2t o2st1a2b o3stal. o4st1am ost3ang osta4s ost1au o4sterd oster3e ost5er6we ost3h o2stin o4s3ton. ost3ran o2st3rä ost3re os3tri ost3rot ost3uf 2osu4 os1um 2o3sy o3s2ze o2ß1el o2ß1en2k o2ß1enz o2ß1ere o2ß1erf oß3t 2o1t ota2go o3tark o2t1au ot3aug o3tax ot1ä o2teb o3tei o4t1eib ote1i4n ote3ine ote2l1a ote4lei ot2em3 otemp2 otens2 o2t1erw 4ot2h ot4he ot5hel o4t3hi ot3ho o2thr o2til o2t1i2m ot2in o4tl otli2 ot4ol ot1opf ot2or oto2ra o3tra o2t3re ot3rin ot2sa ots1p ot2spa ots2pe ott1a ot2tan ot2tau ot2teb ot4terh ot4terk ot2th ot2t3r ot3t4ra o2u oub4 ou2ce ou1f4l oug2 ou2ge ou3gl o3uh ou4le. o3um o3unds oung5 oun4ge. oungs2 o4up 2our ouri2e our4ne. ou3s2i ous2t outu4 2ouv 2o1ü o1v 2ovi oviso3 2ovo 2o1w o3wec owe2r1 o3wi o1x 2ox. ox2a ox2e ox3l o2xu 1oxy o1yo 2o1z o3z2a oz2e ozen4ta o3zi ozon1 órd2 ö1b öbe2la öbe4li öb2l ö2ble ö2b3r ö1ch öch1l ö2chr öchs2t öch4str ö1d ödi3 1ödu ö1e 1öf öf2fa öf2fl öf3l ögen4s1 ög3l ög3r ög2s ö1he öh3l2e öh3ri öh2s ö1hu ö3ig. ö3isch. ö1ke ö2ko ök3r ök2s 3öl. öl1a2 öl1ei öl1em öl2f1ei ölf3s öl1im öl1in öl2k3l öl2la2 öl2nar öl1o2 öls2 öl3sa öl3sz ö2l1u öl2ung ölz2w ö1m öm2s ön2e ö3ni önizi1 önn2e ö1nu öo1 öot2 öoti1 ö1pe öpf3l ör3a2 ör2b3l ör1c ör2dr ö2r3ec ö2r1ei ö2r1e2l ör2erg ör2erk örer2l ö3r2erz ör2f3l ör2gl ö2r1im ör2kl örn2e ör1o örs2e ör3s2k ört2e öru4 ö2r1une ö1s ö2sa ö2scha ö4sch3ei ö2schl ö2sch3m ö2schw 2öse ö2s1ei ös4en ös4es ö2sp ö3s2s ös4s1c ös3ses ö4s3set ös4st ös4t ö2sta ös4u ö1ß ö1t ö2t3a öte4n3 öt2h öt2sc öt2tr ö1v ö1w ö1z öze3 özes4 p2a 1pa. 1paa 1pac pa3da pa2dr pa1f4r pag4 pa3gh pa1ho 1pak pa1k4l pak2to 3pala pala3t 1palä pa3li pal2ma pal2mä pal2m1o 2palt pa2nar pa4nat pan3d pan4ds pa2neu pank4 2panl 2pann 1pa2no pan3sl pant2 panz4 1pap papi2 papieren8 papie8r7end 1para pa2r3af par3akt 1parc pa5reg 2par2er 2parg pargel6d 1park. par4kam par4kau par2kr 1paro 2parp 1partn 1party par3z2 pa1s2p pa2ßu pat1a pat4c pate2 1pati 1pat4r 1pau p3auf pa3uni 1pä 3päc 3päd 3pär 3pä4s3 pä4t1e2h pä4t3ent pät3h pä2to pät3s 2p1b pbe1 2p3c 2p1d2 pda2 p2e 1pe. pe2a pea4r pech1 1ped pe2en pef4 pei1 2peic pe1im 1peit pekt4s 1pel pe2l1a4 pe4lein pe2let pe4leu pe2lex pe3li4n pe4l3ink pel3k pel3la pel3lä pel3l4e pel3li pel3t 1pem 1pen pena4 pe3n2al pe2nä pen3da pe4nen pe2n1o pens2 3pensi penz2 1pep pe1ra per2an 1perio 1perle per4na 1pero per2ra2 perr3an per4rä2 per4ric per6rieg 1pers 2perse 2persi 3perso 1perü perwa4 pe3sa pes3s2 pes2t 3pet 1pé 4pf. p2fab p2fad p2faf pf3ai p2f1ak pf1ans p2fa4r pf3are p2f1au 4p3fe. p2fei pf1eim pf1ein p3fen. p2fent p3fer. pf2erw p3f2es pff4 pffa3 p2f1ins pf4lan p2f3lä pf4leg pf3lei pf3lo p2for pf3r pf1ra 3pf4ro pfs2 pf3sl pf3sz pf3t 2pfü 2p1g pgra2 1ph 4ph. 2phä 2phb 2phd 2p1hei phen3d2 phen3s 2ph1ers 2phf 2phg phi2ka 2phk ph2l 2phm 2phn p3hop pho2s 2phö ph4r 2phs pht2 2ph3the phu4s 2p1hü 2phz pi2a1 pia3k piap2 pia3s pi3chl p4id piegelei8 pi2el piela2 pie4lei 1pier 1pig 3pik 1pil pi3le pil4zer 2pind pin2e pingen4 ping3s 3pinse pi2o pi3oi pi3onu 3pip pi2pe pi3ri 3pirin 3pis 4piso pis2t pi3t2a pit2s pi2z1in p1j 2p1k2 pku2 pkur1 1p2l4 4pl. 3pla p3lad plan3g 3plä 2ple. ple1c ple2e p4leg ple5n2 2p3ler p3lic p3lif 2plig p4lo 2p3lu 2p1m2 pma1 2p1n 1p2o po3b4 po1c 3pod 2poh po2i po3id 3poin 3pok 3p4ol po2lau po3li pol3lo po4lor 2pond po1o2b po2p3ak po2p3ar po2pl po3pt po1rau porf4 por4tre por4tri po3s2e pos4t po2sta post3ag po4stä po4st3ei post3ra po3ta 3pote po2t1u po2w po3x pö2bl pö2c 2p1p p2p3a2b pp3anl ppa2p ppe1e ppeli5ne ppe2n1 ppf4 pp1fr p2p1h p3p2ho p2p1ia pp3lä p2p3le pp3oh ppp2 p2p3ra pp3ren p2pri pp3sa ppt2 pp3ta p3puc p2pul p2punk p3pur p2r2 1prak pra4s3 1prax p4rä 1präd 1präg 3präm 3präs 2pre. 2prec 3pred pre2e1 2preg 1prei 3preis prei4s3c prei4s3s 2preiz 2p3rer 3p4res 1preß pri4e 2prig 3prinz pri2t1 priter4 1p4ro1 3prob 2proc 3prod 3prog 3proj 2pross 2proß 3prot 1prüf 2prüh 2prün 2p1s 4ps. ps4an p3se p3s2h ps1id p2sö ps2po ps2te pst3re p2stu 3p2sy ps2ze 2p1t pt1a pt2ab pt3alb pt3at p3te p4t3ec p4t1ei pte4l p4tele p4t1ent p4t1ep pt3erei p4t1erw p4t1erz p2th pt1in1 p4tos pto2w ptpo4 p2t3r pt1s2 ptt2 pt1um p3tung pt1urs p2tü4 3p2ty pt3z 1pu pu1a pub4 2puc pu2dr 2p1uh 2puk pul2sp 3pulv 2pund pun2s 2punt 2pur pu3ri 3put put2s 1püf pül3l 2p1v 2p1w pwa4r 3py1 py3t 2p1z qu4 quel4la que4te. 1queu qui3s 1ra. 2r1aa ra2ab 3ra3ar 3raau r1ab ra2bar rab2bl 2rabd r2a3b2er 2rabf 2rabg 1r4abi ra2br 2rabs 2rabt ra2bü 2r3abw 1raby ra1ce 2r1acet ra4cheb ra4chin racht3r rach6trä ra2chu r2ack r2ad r4ad. ra2dam 2radap 3radf r3a2d3r rad3t4 1ra2e ra3er r2af raf3ar ra2fer ra3ge ra3gle ra2gn 3r2ahm 2raho 4raht 2raic rail4l 2r3air 3ra1k4l ra2kre ra2kro 2rakti 3rakü r2al r4al. ra2la4 ral3ab r3alar ral3b 3r4ald ra3le 2ralg r4ali rali5er. rali5ers ralk2 ral3la ral5l2e 2rallg 2r3alm. r3alp. 2ralpe r4als r3alt 2ralta r4al3t2h ra2lu 3raly r2ame ra2mer 1r2ami ram4man ram6m5ers ram4mit ram4mu 2r1amt ramt4s r2an. ra5nat 2ranb r2anbe 4ranc r4anda r4ande ran4dep ran4d3er 4r3anei r4aner 2ranf 1rangi rani1e ran2kr 2ranl 2r1anm r2anmu 2r1anp 2ranr r2ans. r2ansp ran4spa ran2th 2rantr 2r3anw r2ap 2rapf ra2pri r1ar r2ara 2rarb 3rarei rar3f4 ra4r1in r2ark 2r3arz r2a3s2 r4as. ras4a ra4schl ra5sen ra5si ra4sk 2rasph ra4ssi 2raß 1rat ra2t1a ra3ta. ra3te rat2o rat4r 2r3atta 4ratz 4rau. 3raub. 4raud 4raue rau3e2n 2rauf 2raug 3raum rau4m3ag rau4man rau2mi 3raup 4raur 2rausb 2rausg rau2sp raus3tr 4raut raut5s 1raü r2ax raxe3 raxi4s1 räch4s 3r2äd 4räf rä1fr 4räg 2räh 2räm 3rän. 3räni 3räns 2r1är r2är. rä3ra rä4sc rä2st 3rätse rä2u 4räue 4räun räu2s räu5sche 4räut 4r1b r2b1ab r2b1a2de r2bak rbal3a rba3re rb1art rb1auf rbb2 rb1ech rbeid2 r4belä r4belis r3ben. rb1ent rbe3r2e rber4gl rb2la rbla2d r2blan r8blasser r4b3last r3blä r2ble. rb3ler r2bleu rb2lin rb2lö rbmas3 rb2o rb4ri rb2sa rb2sei rb3ska rb2s1o rb2sta rb4stä rb2stu rb2su rb2u rbu2sc 2rc r1ce r1che. r1chen r1chi rch3l rch3m rch3r rchs2 rch3sp rchst4 rch3t2a rch6terg rch6terw rch1w r1ci r1cl r1ç 2r1d r3da r4dab rd2ac r4daf r4d1ak r4d1al rdani1 rd1ant rd1anz r4dap r2dei rd2ei. r4deis r2d1elb r3den rden3d2 rde3re rder4er rderin6s r4d3ernt rde3sp rdga4 rdgas3 rdi3a2 rdia4l r2d1inn rd1it rdo2be r3don rd1os rdo4st r2dö rd3rat rd4ri rdrü4 rdt4 rd3ta rd3th rdwa4 1re 3re. re3aler re2am re3at. re3ats 2reä re2b1a re2b1l reb1r reb3ra re2bü r2ech rech3ar 4rechs 2reck. 2recki 3red. 4redd 2redi re1el re1er 3refe 2reff 3refl 3refo 3reg 5reg. rege4l3ä 2reh re2hac re4h3ent re2h1i rehl4 reh3n re2h1o r2ei. r2eie 2reig rei3l2a rei3l2i 3reim reim2p r1ein 4reinb rei3nec 4reing r3eink 4reinr rein8s7tre re1in2v reister6 reis5tro re2ke re3la 2r1elb rel2e relea4 re3lei 2re2lek 2r1elf re3lo 2r1elt relu2 r4em. r2emi 4rempf 4remu r4en. r2ena rena2b re3nal re2nä 3rendi ren3dr re4n3end ren2gl 2rengp re2ni ren4nar ren3sau 2r1entg 2r1entl 2r1ents 2rentw 4rentz r2enz ren2zw re3or 3repe re4pis 3repo 4repp 3r4er. 2r1erb rer2bi r4erbil r2erbr 2r1erd r2erer r1erf r2erfe r2erfl r1erg r4ergen re3ri r1erk 4r3erken r2erki 2rerkl 2r1erl 5rerlag 2r1erm rer2n 2r1ernä 4r3erns 4r3ernt r2e1ro re2rob r1erö 3r2ers. 2r1ersa r2erse 2rersp r1ert r2erte 2rertr 2r1erz rer5ze r2erzy 3r4es. re2sa res3an re4schw 3rese 3reso 2ress ress2e res6s5erw 3rest res3tem re2stu 3resu 2re2ß1 re2thy re2u reu3g2 2reul re3uni 2r1eur 2reü 2r3evid r1ew rewa4r re2wi 4r3e2x1 3rez 4rezi 1ré 2r1f rfall4s rfäs3 r2fent rf2es rfi4le. r2flan rf3lic rf3lin rf4lö r3flü r3for rf4ru rf4rü rf2sa rf2s1ä rf2s1id rf2spr rf2ta rf3t4r rf2u 4r1g rg2ab r2g1a2d r2g1ah r2g1ak rg2an rga5ssen rgas2t rga4str rge4an rge2bl rg2el rge4l3er rgen4z3w rge4ral rge4tap r2geto rgi4sel r3gla r2glan rgleich8s7 r2gleu r2glig rg2lö rg2lu r2gna r2gno r2g1ob rgö2 r2g1öd r2g3ral r2greg r2gres r2gret rg3rin rgro5sse r1h4 2rh. 2rha r2ha. r3hals 2rhä 3r4he. 2r3her r2hoe r3hof rho2i3 2rhol 2rhö 2rhs 1ri ri3am ri3at rib2bl ri1ce ri1cha ri2dan ri2dau rid2g 2ridol 2ridy r2ie rieb4s3t rie2fr ri1el ri3els riene4 ri3eni rie2nu ri1er. ri4ere ri3e4sti ri1eu ri2f1a ri2f1ei ri2f1er ri2f1o ri2fr rif4ter 3rig ri4gene 5rigj rig1l 4rigr rik1l ri4kla r2imb ri2me. 4rimp rim2s r2i3na 2r1ind rin4dex rin4diz 4rindu ri3n2e rine1i 2r1inf rin2fo rin2ga ring3l rin2gr 2r1inh 4rinit 2rink rin2kl 3rinn 6r5innenm 4r3inner 4rinnta r1innu 2rins2 3r4ins. rin2so rin2sp r4inspi 2rint rin4teg rin4t5r 2r1inv 4r1ir r2is ris4a ri4scho ri4schw 3risik rismu2 ri3so ri2s1p 3riss ris3si rist5ers ristes4 ri6stess ri2ß1 r2it r3i2tal ri3t2i ri3t4r rit4tei rit2tr 5ritu rix1 ri3xi 1rí 2r1j 4r1k rk2am rk4ap rkauf4s r2käh r3kla rk4las rk4lau r2klis rk2lo rk2lu rk4n r2k5nu rk3räu r2k3rea r3kri rk2s1e rk2sp rkstati6 rk4stec rk2ta rk4t3eng rk4t3erf rkt3ers rk6tersc rk4t3erw rk4t3erz rk2tin rk2t1o2 rk2t3r rk3tra rk2um rku2n rk1uni rkus3s rku4s1t 4r1l rl2ab r5lag r5lan r2l1ar r2l1a4sc r2l3aug rl2e rle4a r3lec rle4i rle2st r3let r3l2i r3l2o rlös5s rl2s1p rl2sto rl3t r3lu rlu4str rlz2 4r1m r2mab r3m2ag rma2la r2m1ald r2m1ank rm1ans rm1anz rm1a2p r2maph rma5ssen rmas8sens rm3d2 r2m1ef r2meo r2m1erp rm2es r2mide r2m1im rm3m rmmo3 r2m1o2ri rm3sa rms2t rm3sta rmt2a rm2u rm3ums 4rn rna2b rna4n rn2and rn3ani r2n1anz rna4r rn2arb rn3are rn3ari r2nau rn3d4r r3ne rn3e4ben r4nef rn2ei rn3eif r4n3eis rne2n r4n1ene r4nerf r4n1erg rn4erhi r4n1ert rner4ve r5nes rn2et rne3uf r4nex rn3f rng2 r3ni r4n1in r3nod r2n1op r2n1or rn1ö rn3sa rn3s2ä rn3s2p rn3s2z rn3t2e r1nu rn1ur r1nü r1ny ro2bei 2robj 1robo 2robs ro1ch 3rock. 4rockn r2o3de ro3e2 4rog. 4rogs roh1l 3r2ohr 3roi ro3le rol4lan rol3l4en rolli4n rol6lini 2roly 4rom. ro2mad ro2mer 4romm 4romt r2on ro4nerb 3ronn rons2 ron4tan 4ro1ny 2ro2pf ro3ph r1or r2ora ro2r3al ro2rat ro2rei ro2r1o ror3th ro3se ro3sh ro5s2i ro5smo ros6san ross1c ro3sta ro2st1r ro2ßu ro2tag ro2tä ro2tei ro2tho ro2tri rot1s rots2o ro3t2u ro3unt 3rout rö2b3l rö2du 2rö2f 3röh r1ök 1röl rölla4 3römi 4röp r1ör r2ös. 3rötu 2r1p2 r3p4a r3p4e rpe2re rpe4r3in rpf4 r2pli rpo4str rps1t rp3t r3pu 2r1q 2r1r rr2ab rr2ar rra4s3s rrat2s rr1äm rrb2 rr1c rr2e rre4ale r5rega rre2le rre2pa rrer4s r3res rre2ve r2rew rr2he r3r4hen rrik2 rr2n3a r3r2o r4r3ob rro3m rr2th r3ru r3r2ü rrü1b 4r1s rs3ab r2sa2d r4samp r4s1amt rs2an r2s3ang rs3anp rs3ar r3sche r6scherl rs1ebe r2sein rse2n1 rs2end rse4ne rs1ere rs1erö rs1ers rs1erz rse2t rs1eta r3sho rs2kal rs2kan rs2kie rs2kis rs2kl r4sko r4skr r4sku rs3l rs4no rson4e r2s1op r4s3ort. rs2p4 rspa3s2 rs4pel r2s3ph r5spi r4s3s2 r5stad r4stant rs2tau r6st5eing rster2 r6sterbt r4st3erw rs2th r5stim rst3ing r2stip r2s1tot rs2tr rst3ran r6strang rs2tu r2sumf rsü3s r3swi 4r1t rt4abl r2t1alm rtals1 rt1am rt1ang rt1ann rt1ant r2t1ar rt3a4re r2t3att rt1är r3te. rte1e2 rtei3la rt1ein r2telf rtel6lei r4tempf rte2n1 r3ten. rte4na rtens2 rt3erei r4terfa r4terfo rt1erh r4t3er4la rter6mit r4t3ernä rter4re rt1ers r3tes2 rte3sk r2thi rt2hum r2t1id r2t1ima rt4is rto1p rt1or rto2ri r2t3rak rtra4s3 rt3rec rt3ros r4ts rt4s1eh rt1s2pe rt3t4 r2t1urt rt3z rtz2a 1ru ru1a ru3a2r3 rube2 ru3ches rude2a ru2dr 3ruf ru2fa ruf2s1 ruf4st ruf4ter 2r1uhr ru1ins ru1is 2rum 4rumf ru2mi 4ruml r2ums. 4rumz 2r1una 2rund run2d1a r2unde rund3er run6derf run6der6l run6ders run6derw 2r1unf 2rungl 2r1u2ni 4r3unio run2kr 2r1unl 2r1unm 4runn 4r3unt 2runw ru3pr 4r3ur ru2ra ru2r1e 5ruro ru2si rus3sen rus2s1p rus6s3t 3rut ru4tei rut3h ru2t1o2 ru2t3r 4ruz ru2zw 1rü 2rüb rü1ben rü1ch rück5sta 4rümm rün3z rü3s2s 2r1v rve4n1e rve5s rv2s 2r1w r5wei rwun3s 4r1x 1ry ry2c rys2t rysti1 2r1z rz2an r2zar r2zas r3ze. rz1eck r5zene rz1eng r4z3ents r2z1erf r2z1erg r2z1erk r2z1erw rz1id r3z2of rz2ö rz3te rz2th rz2t3ro rzug2u r3zü r3zwä r3z2wec 1sa 3sa. 3s2aa 2s1ab sa2be 3sabet sa2bl sa3ble sa2br 4sabs 5sache sa2cho2 sach3t 5sack. s1ad 2s3ada s3adm 2s3a2dr sa2fe 2s3aff 3safi sa1f4r 3saft 3sag sa4gent sag4n 4s1a2gr 3sai sa3i2k1 sail2 2s1ak sa2ka 3saki 3sakr 4s3akt 3sal. 4s1alar sa4l3erb sa2l1id s1all sal5lo3 3salo sal2se 2s1alt 3s2alz 3sam s2ame s3ameri 5samm 6s1amma 4s1amn s1am3p4 sam2to s1an s2an. 2s3a2na 2s3anb s2an2c 3s2and s4and. san4dar san4dri 3sang. sang4s 2s3anh 3s4ani 2s3anl 2sanp 2s3ans san4sk 4santr 2s3anw s3anz 2s1ap s2aph sa2po 3sapr 2s1ar 3s4ar. 3s2ara 4s3arb 3s2ard 3sari s3arr 3s2ars 4sarti s1a2sp sas6sest 4s3a2sy 3sat sat2a 4s3ath 4s3atl 4s1atm sa2tr sa3ts sat4z3en s1a4u 3sau. 3sauc 3saue sau8erste 2s3aufb sau2gr 3saum 3saur sauri1 2s3ausb sa2vo 3säc s1äh s3ähn 2s1ält 2s1äm 2s1änd 2s1är sä2s3 3s2ät 1säu 2säuß 4s3b4 sba4n sbe3r2e sbus3 1sc 4sc. 2scam s2cap 4scar 2s1ce 6sch. sch2ab 3schaf 2schak sch2al 4schanc 4schang 5schanz 4schao s2chau 3s2chä 2schb 2schc 2schd sch2e 3sche. 6schef. 6schefs sch3ei. 4schemp 3sches 4schess 4schex 4schf 4schg 2schh schi4e 3sching 4schiru 3schis 2schk sch4lag 4schle. 6schlein 4schmas 2schmö 4schmüh 2schn. 4schobj 2schox 3schö 4schöl 4schp 2schq 4schre. 4schrin sch3rom 4schron 4schrou 6schs2 sch3sk 6sch3t scht2a scht4r s2chu 4schunt 3schü 2schv 4schwaa 4schwet sch4wil 2schz 2scj 6s1cl 2sco 3s2cop 3sco4r s2cr 2scs 2scu 4s3d2 sda3me sdien4e sd4r 1se se3at. seau4 2s1e2ben seb4r 2s1echo s1echt 2s1eck se2dik 3see se1ec se2e1i4 see3ig seein2 se1er. se1erk se1erö 2s1eff sef4l 3seg se2gal se2gl seg4r 3seh seh1a se2ha4g se2han se3he se4h1ei se4hel se4herk se2hin seh1l seh3re seh3s seh3t se2hüb 2s1ei. 2s1eie 2s1eig sei3le s1ein 5s2ein. 2seinb sein4du sei3n2e sein4fo 2seing 2seinh 4seink 2seinl 2seinn 2seinr s4eins. 4seinsa 4seinsp 4seinst 2seinw 2s1eis 5s2eit 3sek 4s1e2ke s2el. se2l1a se3lad sela4g se3lam 3selb sel1ec 2selem se4lerl sel3ers 2self. s1elix 3selk sel3le se2l3ö s2els sel3sz sel3tr s4e3ma 2s1emp s2en. se4nag se2nä 3sendet 4s1endl 5seni 3senku se2no s2ens s2ent. sen3ta 2sentf 4s3entg s2enti 2s1ents 2sentw 2sentz se2n3u 3senva seo2r 4s1e2pos 3seq s4er. ser3a2d se2r3al s3ereig se4r3eim se4r3enk ser2er s1erfo s2erfr s3erfü 4ser4fül s1ergä s4ergr s1erh 5serie serk4 s3erken s1erkl 3serl. s2ern. s1ernä 4s3ernt se1rot s3eröf s2ers. 2sersa sers2t s4ert. seru2 se4r1uf se3rum se3rund 3s4erv se2sel 2sesh se3sk se3su 2se4tap se2tat s1e2th 3setz se1u2n 2s1ex se2xe 4sexp sex3t2 6s3f4 sfal6l5er sflo4 4s3g2 sges2 sgro3 2s1h 4sh. sh2a 3s2ha. sha2k 4s3han 4shc s3h2e 3shi. 3shid 4shil shi4r 4shk sh3n 4shof 3shop sho4re 3show sh4r 4shs 4sht 4s3hü 1si si3ach. si2ad si3am. sia4s 2siat sib4 5si1c 2s1ideo s2ido 3s4ie siege4s sieh1 sie4hes si3ene si1err si1f4 si2g1a 3sigh sig4n si3gnu si2g3r si2k1ab si2kak si2k1ä sik3erl si2ki si4k1l si2kr sik3s2 sik3t4 si2ku sil2br 3silo 2s1imm si3n4a 2s1ind 2s1inf sing1a sin3gl sing4le sin4gr sing3sa 2s1inh sin1i1 4s1inq 2s1ins s2ins. 4sinso 4sinst 2s1int 4s1inv 3sio 3siru 3sis si2sa si4schu si2s1e si2s1o si2s1p sis3s2 si2stu 3s2it si2tau sit3r si2tra si3tu siv1a sive3 si2vr 1sí 4s3j 2s1k2 4sk. 1skala 4skam 4skanz 4skas ska4te. 4skateg ska4tes 4skä 4skb s2kep 3s2ki. s2kif s2kig 3s2kik 4skir 3skiz sk4l 4s3klas 3s2klav 4sk4n 4skom 4skor 4skow 4skö 4sks 4sk3t 3skulp skus3 2s1l2 4sl. 3slal 4slan sla2ve s2law sl3b s5le s3li 3s4lip 4sln s3lo. slo3be s3loe s3lu 4s3m2 2s3n2 4s5na snab4 sni3er. sni3ers 4s5not 4snö 3so. so4a 2s1o2b so3et 3soft 3sog s1o2he 6sohng 2s1ohr 1sol so3la so2l1ei sol2la4 sol4ler 2so2ly 3som 3s2on son3au sone2 son3end son3sä son2s1o so3o 2s1opf 3sor. s1orc 2s1ord so2rei so3ren 2s1orga 5s2orge 2s1o2rie so2ro 3sors so4ru 3so3s2 s4os. 4s1ost 3soß 1sou so3unt 3sov 4s1o2ve 3sow 2s1ox 5soz sö2f 2s1ök s1ö2l s1ö4s sp2 2sp. 2spaa 2spak 2spala spani7er. 2spano 4spap 2s3para 1spare 2sparo 5s6parten 3sparu spa3sse spa3ssi 3s2paß 2spau s2paz s2pä 2spär 2spe. 2s3pel 4spensi spe3p4 s2pera 2spero s2perr 2spers 4spet 1s2pez 2s3pf 2spha s3phe 1spi 3s2pi4e 4s3pier4 spi2k 4spil 3spio 4spip 4spis 3s2pit 3s2piz 2spl 4spla 4splä 3s2pli s3p4lu s3pn 2spod 2spog s2poi 2spok 4spol 1spon 1spor 2s3pos s2pott 4spr. s2prac s2pran 2sprax 2spräm 4spräs 3s4prec 2spred s2pren 2spres s2prit 2sprob 2sprop 5spross 1spru 2sprüf 3sprün 2s3ps 2spt 1spuk 2spup 3spur 4sput 1spü 4spy 2s1q 4s3r4 sra4s3s srat2s srat4sc sret3 srö2s srös1c srücker6 2s1s 6ss. 4ssa ssa3bo ss2ad ss1aj s3sal s4s1alb s4s3amt s5sand s4s3ang s2sano s4sans ss2ant s4sanz s3sas ss3att 4s3s2ä 4ssb 6ssc ssch2 4ssd 4ss1ec 4ssee 4sseg s4s1ega 4sseh 4ssei sse3inf sse3in4t 4ssek 6ssendet 4s3sendu ssenmas6 4ssentz sse6r5att s2s1erö 4ss3erse ss2es 4ssesc 3ssesh sse3ta 4ssez 4ssf 4ssg 4ssh 4ssic 4ssie s2sig s4sind s4sinf s4sint 4ssio 4ssit 4ssk s3skala 4s4s3l 4ssm 4ssn 4sso ss1off ssoi4 s2s1op ss1ori s2söl 4ssp s3spe ss2pen ss2po s3spru ssquet4 4ssr 4s4s3s2 4sst sst2a s5stad ss2tar ss1te s4ste. s5stel s4sten s4stes s4stet s5steu ss2th ss2tip ss1tis ss2top s3strec ss2tur s3s2tü 4ssum ss1ums 4ssup 4ssü 4ssv 4ssw 4s3sy 4ssz 1st 6st. s4ta. 3staa 2stabb 2stabh s2tabi 2stabt 2stabz st2ac 3s2tad 4stada 4stadr 3staff 2stag 3stah 2stak 2stal. 2stale 3sta3li 2stalk st1alm st1alp 3stam st1a2mi 4stamt sta4na 3stand 4stanf 4stanl 4stann 2stanw 4stanza s2tar. s2tars 3start st1asi 3stat 2stat. 5statu s4tau. 2stauf 2staum 5staur 2staus 2stax 3stä 4stäg 4stält 4stämt s2tär 5stätt 4stäus 4stb 2st3c 4std 3ste s2tean 4stechn 4stee ste2gr ste4i 4st1eid 5s2teig 4s3teil steil4z stei4na s2t2el s3telem 5stell stel4l3ä ste4mar 4stempf ste4na 4st3ends 4stentf 4stentw 4stepi st5erbie ste4rec ste6rers st3erfü st2erg st5ergeb sterma7sse s2tern 6sterras s2ters stes3ta ste4stä 4stests s2teu 4steuf 4st3ev 4stex 4stf 2stg 4sth st3ho 5s2tic 3stie 4stief. 3stim 2stinb 2stinf 2st1ins s4tio sti2r st3i2so 2stj 2stk 4stl 4stm stma3s2 2stn 2stob 3stoc sto3d s2tode s2tof stoffen6 stof8fens 2st3om 2stope 2stopo 2stord 2storg s2tory 3stos 4stou 2stöch 2stöl 2stön 5s2tör 2stöt 4stp 2stq 3s2traf 2strag 3strah 4strai 3s2tral 4strans 3s2tras 3straß 4straum s2träf 2s3träg s2trän 4sträne 2stre. 4strech 4stred 4stref 4streg s3treib 3st4reif 4streis st3renn 2strep 2stret 2strev 2stri. 3s4tria 2strib 4strig stri2k 4strisi 2stroc 3s2trof 3s2trok st3roll stro4ma 2ströp 4ströt 3struk 2st3run 2strup 4st3s2 stsas2 sts4k 2st3t4 st2u 5s2tub 4stuc 3stud 2stue 3stuf 5stuh 2stuk 2stumr stum2s 2stumz stu2n 2stun. 2stunf 2st3uni 2stuns 2stunt 3stuö stu3re st3url 2s3turn 2st3urt 4stüch s4tück 2stür. 2stüre 2stürg 2stürs 2stv 2stw 2sty. 2stys 4st3z 1su. su1an 3su2b3 su4ba2 4subi 5su1c su2cha such4st 2s1u2f 4s1uh su1is su1it. sul2a sul2i sult2 su2mar su2mau 3s2ume su2m1el su6m5ents s3umfa s3umfe 3summ sum1o2 su2mor s2ump s3umsa s3umst su2n sunder4 sun6d5erh su4ne s1unf s3ungl 2s1uni 4sunt 3s2up sup3p4 su2ra 2s1url s1urt sus1e su2sp sus3s 2sü2b 3süc sü2d1 süden2 sü3den. 3sün 1süs4 sü3sse sü3ssi 1süß 4s3v 2s1w s3we sweh2 4swie 4swil s3wö s3wu 1s2y syl1 sym3 sy2n3 sy4na sy4nä sy5s 2s1z2 4s3za 4szä 4s3zei s2zena 5s2zene 4s3zent s2zes s2zeß s3zet s2zis sz3ta 4s3zu 4s3zw 2ß3a2 ß1ä 2ß1b2 ßbus3 2ß1c 2ß1d4 ßdie3 1ße 2ß1ec 2ß1e2g 2ß1ei ße2l1a ße2le ße2ni ße2no 2ßentz ß2ers. 2ßerse ßer3t ße2s ße2t ß1ex 2ß1f 2ß3g2 ßge2bl 2ß1h2 1ßi ßi2g1a 2ß1in ß1j 2ß1k4 2ß1l2 2ß1m 2ß1n2 ß1o2 ß1ö 2ß1p2 2ß1q ßquet2 4ß3r2 ßrus3 2ß3s2 ßsch2 ßst2 2ß1t ß2th ßts2 1ßu2 ß1uf 2ß1uh 2ß1um ß1uni ß1ü 2ß1v 2ß1w 2ß1z2 2tab. ta2b1an 2t1abb 1tabel 2taben ta4bend 2tabf 2tabg 2tabh 2tabk 1t6able 2t3abn ta2br 4tabs 2t3abt ta2bü 2tabw 2tabz 2t1ac 3tacu t1ada tadi3 2t1a2dr ta3d2s 1taf2e 2taff t1afg t1af4r 1t2ag 3tag. ta2ga ta2g1ei 4t3a4gent ta3gl t3ago tag2s tag4st tah2li tahl3sk ta3i2k tai2l ta1ins tai4r ta1ir. 1tak t3a2ka ta2kro tak2ta 3taktb 3takts 3t2aktu 2takz 3t2al. ta2la ta3lag ta3lak tal3au t1alb. t1albk 1talbu tal3d 1t4ale tal2en ta4lens tal2ga tal4leg tal4lei tal4let tal6leut tallin6s tal4lus ta2l1op tal2se 2talt 2tam ta2mer tam2ma2 tam4mi tam4mut t1ampl t1amt t1a2na 2tanb t2and tand4ar ta3ne 4tanf 2tang t2ank t3ankl 2tanl t1anm 2tanme 4t1anna t1ans t2ans. 4t3ansi 2t3ansp 2tanwa 2tanwä t2anz. t1anza 4tanzei tan6zerh t1anzu tan2z1w ta3or ta2pe. ta2pes 2tapf ta2pl 2tappa t2appe 2tarb ta4ren4s ta4r3ere 3t4ari 2tark 2t1arm 2tart tar2ta t1arti tar2to ta2ru 2t1arz ta3sa 1tasc t1asp 1tas2t ta3str 1tat. ta2ta2b ta2tan ta2tau tat1ei ta2tem ta2t1er ta2th tat3he t3atl t4atm ta2tom 1tats ta2t1um 4taud t1auf 4taufg tau3f4li 4taufn 2taufw 1taug t1auk 3taum 1taus 2taus. t1ausb tau6schr tau6schw t2ause t3ausg t1ausk 2tausl 2t3auss 4t1ausw 1tax ta3xi taxi3s 3täa tä1c 2täd 3täe 1täg 2tägy 2täh 2t1ält 2täm t1ämt t1ängs 1tänz t1äp t2är. tä2ru tä2s t2ät 2tätt 2täug 1täus 2täuß 2täx 1tà 4t3b2 tbauer4 tbe3r2e tblock5e tblocken8 tbus3 2t1c t3cha t3che tch2i tch3l t2ch1u tch1w t3cl t3cr 2t3d4 tdun2 1te2a4 te3al teamma5 te3an 3t4ebb 4t1e2ben 1t2ech te1cha 3techn te2chu 2teck teck2e te2de 1tee te1em te2en3 te1erw te2es 2teff 2t1egg teg3re 2teh 2teign teik4 1teil 2tein tein3ec t3einge t3einla 4teinn t1eis. t1eisb tei3st te2kel tek3t2 tela4 te2l3ab te2l1ac te2l1au telb4 tel3d4 te3le tel1eb tele4be te4l1ec 3telef 3teleg te4l1eh te4lein 2telem te4lerd te4leu 4t3elf. te2l1in te2lit tel3lau tel3lä tel3l2e tel6lein tel6li6st te4lost te2l1ö tel3s2k tel3ta tel3th tel3t4r te3mä te2m1ei te2min 2temo te2m1o2r 3temper 1tempo te4m1u t6en. tena2b te4n3a2d te4n3a4g te4nas te4n3au te2nä ten3äh t4enb ten3da 4t3endf t6endi 2t1endl t6endo 4t3endp ten3d4r te2n1e2b te2nef ten3ei te3n4ei. 4tenerg te2net 4t1eng. ten4gag t3engla t4enh te2ni te4n3in t4enj t2enk t2enl t4enm ten3n t2eno t2ens tens2e 4tensem t4enta t1entb 2tentd t4ente 4tentn ten4t3ri 4t3entw 4tentz t2enz ten6zerh ten3zw t1e2pi t6er. ter3ac te1raf ter3am te3ran. te3rand ter3as 4terbs 4terbt 4t3erde. te2re2b te4r3eif te2rel ter3end te4reng te4rerk terer4z 4t3erfol t4erfr 4terfül terg2 ter3ga 6ter6grei t4ergru 2t1ergu 4tergü t4eri te3ria te2rid ter3k 4terklä 2t3erlö 1term termas4 ter4mer ter4n3ar 4t3erneu t4ero t1erö 3terras ter4re. 1terro t4ers. ter3sc ter4ser terst4 t4erst. t4ersti t4erstu tert4a tert2o teru2 te4r1uf ter3za 2t1erzb t2erzu te2s tes1ac te3sä t1esel tes1er te3si te3so te3sp te4spr 3tesse. t2es2t tes3tät te4st3ei tester4 te6sterg te6sterk testes4 1tests t2et. te2tat 4tetl 3teuf te1un teu2r3a4 te2vi 1tex te1xa t1e2xe 2t1e2xi 4texp 3text 2t1exz 2t1f4 tfäs3 tfi2l 2t1g2 tger2 tgro3 t1h 4th. 2th2a 3t4ha. t2hag t3hai t2hak 3thal. 4t3hau 2t3hä 4thc 1th2e t2he. 3thea 2theb t2hec 2t3hei t4hein t2hek t2hem t4hene t4heni 3theo 2therr t2hes 3these t2heu 1thi. thi3er t2hik 2t3hil 2t3him t3hir 2thk 4th3l 4th3m 2th3n t2ho t4ho. 2t3hoc t3hof 2t3hoh t4hol. t4holo t3hor 2t3hot thou2 2thov 2t3hö 2thp 1th2r2 2ths 2thub 4thun 2thü 2thv t2hy ti2ad ti3a2m tib4 ti1ce ti3chr tiden2 ti4dend t2ie 1tief. tie2fr ti1el ti2el. tiel3a ti3e4n1 tie4rec ti2ern 1tierr 2tieß ti1et ti1eu 1tif. tif3f ti1fr t4ig ti4gerz tihi4 ti2kam ti2kar ti2kin ti2kra ti2krä tiks2 ti2kü ti2lar ti2lau ti2lei ti2lel 1tilg tille4b ti2l3ö tilt4 ti2lu ti2ma2g t2imi tim2ma2 4t1imp t2in. ti3na t1inb 4t1ind ti3n2e t1inf tin2g1a ting3l ting3s t1in1it 2t1inj tin2k1l t2ins. 4t1inse t1int ti1nu 4t1inv 3tio 1tip 3tip. ti4que. ti1rh t2is ti4scha tisch3w ti2sei ti2sp 3ti3te tium2 ti2van tive3 ti2vel ti4vene tiver2 ti4verl ti2v1o ti2v3r ti2za 2t1j 2t3k4 2t3l tl4e 3tlem tle2r3a 4t5li tli3ni 2t1m2 tmal2 tmen4t3 tmo4des t3mu 2t3n2 t5na tnes4 to4as to5a4t 1tob 2tobj tob2l t1obs to1ch t3ochs 3tocht 2tock 1tod 3tod. tode2 to2d1er tode4s1 to2d1u toi4r to3la tom1e2 2tomg 1ton to2nau to2neh 3too to2pak to2pat 1topo 2topt to1ra to2rau to4rän 2torc t1ord to2r1el t1org t3orga tor3int to2rö 1tort t1ort. to2ru t2orw to3s2 to4sk tost4 1toten to2tho tots2 3t4ou touil4 to3un tö2c 1töch 2töf 2t1ök 1tö4l 1tön t1ö4st 1töt 2t3p2 tpf4 2t1q t2r4 2tr. 1trac tra3cha t3rad. tra4dem tra4far 1trag 2trahm 3t4rai tra4lin 1tram 2t3rams 3t4ran. 2trand 1trank t1rann 1trans t3rase t3rasi tra4str 2traß 1traum 2traup traus2 1trä 2träh 3träne 2träs 2träß 2träus 2träuß 4t5re. tre4ale tre2br 2trec t3rech t4reck 2t3red 1tref 2trefe 3t4reff 2trefo 2treg t4rei. 1t4reib 2treif t3reig 2t3reih t3rein 2t3reis 2treit t3reiz 2t3rek 2t3rel t4rem t4ren. 1trend t3rent 1trep 2trepe 2trepo t4repr t4rer t4res. 1t4ret tre2t3r t5rett t4reu 2t3rev 2trez 3t4ré 2t3rh 1trib 3trieb. 3triebs 6trieg tri2er 1trigg 1trin t3rind 2tring tri3ni 3trio t4rip t3riß t4rit 1triu tri2x trizi1 1troc 4trock. t4roi tro2ke tro2mi 2t3roo t4rop tro1pe 3tropf 2troß t3röc 2tröh 2tröm 1tröp 2trö4s3s 1tröt 2truf 1trug 2truk trum2 trums1 2t3rund 1t4runk 3t4rup t3ruß tru2th trü1be trü1bu 2t3rüc trücker6 t4rüg 3trümm try1 2ts t3s2ac t2sa2d t2s1ah ts1al t4s1amt4 t2san ts3ar ts1as tsa3sse t2sau t1sä t2säh t2s1än t4schar t3sche t4schef t3schl tsch4li t4schro ts2cor t2s1e2b t3seil t4seind ts1em tse2n1 t2s1eng t3sens t2s1ent t2s1er t6s5essen t3set t4seth t2s1i2d tsing4 ts1ini t2s1ir t3skala ts3kr ts1o tso2r t1spal t1span ts1par ts4pare t1spas ts2ped t1spek ts2pi ts3ple ts2pon ts2por ts3s2 tst4 t2staf ts2tat ts2tau ts3täti t4stea t4s1tep t4sterm t4s3terr ts1tie t2s1tis t2stit t2ston t4s3trad t2strä t2s1tri ts2tro t4strop t2s1trü ts1u 1tsub t1sü 4t1t tt1ab tt2ac tta6gess tt1ak t4tals tt3ank t2tanz tt1art t2tän tt1ebe tt1eif tt1ein tt1eis tte2la tte4leb t4te4leg tte4len ttel3l ttel1o t3ter tte4rec tt2erg ttermas7s tte4sa tte4s1ä tt2häu t2t3ho t3to. t3tos ttras3s t3tro tt3rü tt2sen tts1p tt4s3tem tt4ster tt4sti ttu2 t2tuc tt2un t2tu4s ttü2 tu1alm tu3an tub2 tuba3b 1tuc tu2chi 1tue tu3en tu2ere 2tuf tuf2e tu3fen t3u2fer tuf4fel 2tuh tu2is t3u2kr tul2a 1tum t2um. t2ume 2t3umf 2t3umg 2t1umh 2t3umk 2tump 2t3umr tum2si tum2so 2t3umt 2t1umw t3umz 1tun. 2t1una 2t1und t4une 2t3unf t3unga tung6s 2tunif 2t1u2nio 1tunn 1tuns 2t3unt t1up. tu2r1a4g tu2rä tur1c tu2re. tu2rei tu2r1er tu2res tu2r1e2t turin1 1turn tu2ro tur3s tu4ru tu2sa tu4schl tu2so tu3ta 2tüb 1tüch tück2s 1tüf 1tür. tür1c 1türe 1türg 1türs 1tüten 2tütz 2t3v 4t3w twa2 twä4 twi4e 1ty 3ty. 3typ ty2pa 3tys 4t1z t2za4 tz1ag tz1al tz1ar tz1au tz1ä t3ze. t2z1ec t2z1eie t2z1eis tze4n1 tz2ene tz3ents tz1erl tz2ers t3zes1 tzes3t tz1ind t2zor tz2ö tz2th tz2tin tz1wä tz1wi tz1wu 2ua u1a2b u3a2c uad4 u1ah u1al. ua2lau u1alb u3alet u1alf ual3l ualle2 u3a2lo u1alr u1als u1al3t ua2lu u1alz u3am u1ans u3ar. uara2b u1ars ua3sa ua2th uat2i u3au uau2s u1ay u1äm u1än uäs4 u1äu 2u1b u8becken. ub3ein u3b4i ubi3os. ub2l ub3lic u2b3lu u2bop ub3rä u2b3rit ub2san ub2s1o ub2spa ubus3 u2büb 2uc uc1c u1ce4 uces3 uch1a u1cha. uch1ä u1che u2ch1ec uch1ei ucherma8s u1chi uch1il uch1in uch3l uch3m uchma6ss uch3n u2ch3r uch2so uch4spr uchst4 uch4tor uch2t3r u1chu u2chum uch3ü uch1w u1ci uck2er uck3erl u1cl 2u1d u3d2a uder2e udert4 udi3en uditi4 u2don ud3ra u3dru 2u1e u2ed ue2en u2eg u4ela ue2le ueli4 uel2la ue2mi uen1 ue2nä ue2ner uenge4 uen2gl u3e2ni ue2no uen2sa uen2zu u2ep ue2r3a ue2r1ä uer6baut uere2 ue2rec ue3reig u3eremp u3erent ue4rerg uer3g2 u3erh u3erinf u3erin4t uerma6s uer4nan uer2ne uer4ner uer3o uer2ö u3err uer3sc uer3t2 u3erum u3erunf u3erunt u3erur ue4s ue5se ue5sp ue2ta ue4tek u3fac u3fah uf1ak u3fal uf3ar uf1au u2f1ä6s u2f1ä2ß u2f1ei u2f1em u3fen. u2fent u2f1erh u4ferle uf2ern u2f1eß 2uff uffel2 uff4l uf2fro uf3l u2fob ufo2r uf1ori uf3r uf3sä uf2spo uf4ster uf2t1eb uf3ten uft3erd uft3s2 u2fum 2u1g u4gabte ug1af ug1ak ugang4 u2g1ap uga4s ug1au ug3d2 u2g1ei ugenma3 ugenmas6 u2g1erf u2g1erl ug4es ug3hu u2g1l ug3lad u4g3lo u3g2lö u4glu u2g3n ugo3 ug1or u2gö u4g3reis ug3ro u2grol ug4ro3s ug3rüs ug3sc ug3se ug3si ugsma3 ugsmas4 ug1spa ug5stä u2gü u1h uh2au uh1la uh1lä uh2li uhme4 uhr1a uh2rer uh3ri uh4rin uhrt4 uh2ru uh4rü uh1un uh1w 2ui ui2c u1ie ui1em u3ig u4ige uil4les u1im u1in. uin3n u1is. u3isch. u3ischs uisi4n ui2st u1j uk2a u3käu u1ke u1ki u1k2l ukle1i u1k4n u3ko uk2ö u1k4r uk2ta uk2t1in uk2t3r u1ku uku2s uk2ü u1l ul1ab3 ul1am ul1äm ulb4 ul2dr uld2se 2ule u2l1el ule4n ul1erf ul1er2h ul1erw ule2sa ule4s3t ule2t ul1eta u2lex ulf4 ulg4 uli2k ul1ins ul3ka ul2kn ulla2g ul2lä ul3len ul2les ulli2n ul2lö2 ulo2i ul1or ul2p1h ul2sa ul4sam uls2t 2ulta ul2tri ult3s u2lü ul2vr ulz2w u2m3a2k um1all um1anz u2m1art u2maus u2maut u2m1äh 1um3d2 um2en ument4s umer2a um1erf um1erg um1erl um1erw u5mes 1umf 1umg um1inh u2m1ins um1ir 1umk 1uml 2umm umm2a um4mess u2möl umpf4li um2pho um2p3le 1umr um4san 3umsat um2sau um2ser um2sim um2s1pe um4stem um2s1u um3t2 um2un u2m1ur 1umz un1 2un. 4una. 1unab un4al u3n2am u2n3an 4un2as un3at unau2s 1unda un4dab 1undd un3de. un4dei und3erf un2dex 1undf 2undg un2did 1undn un2dor un2d3r 4unds. und3sp un2d1um undü4 1undv 1undz u3ne une2b une2d une2h un2ei. un3ein un3eis unen2t u4n3erz unes2 1unget 1ungew 1unglü un3gn un2gr ung3ri ung4s1 un2id un3ide 1u2nif unik4 un2im uni2r 2unis un3isl u3n2it 3u2niv 2unk un2k1a2 un2kei un2kne unks2 unk4tit unk2t3r 3unku unlö2 un2n3a2d un3n2e uno4r un2os 1unr uns2 2uns. unsch5el un3se 1unsi un3sk un3sp unst1r 1unt un3ta unte4ri 2unth 2unto un3tr unt3s 2untu u1nü unvol2 unvoll3 1unw 2unz 2uo u1o2b u3of u1op u1or u3or. u3or3c u3ors u1os. uote2 u1pa u1pe2 uper1 up2fa upf2e upf1i u1pfl u3pi up4lu up2pl u1pr upt3a2 upt3erf upt3erg upt1o u1q 2ur. u1ra u2rab u3raba ura2be ural2t ural4ta u2r1a2m ur3ame u2r1ana uran4fa uran4fo u2r1ang uran4ge ur2anh u2r1an5s u2rar ur3a4ren u2r3att u2r1au 2u1rä ur1än ur3b2a urch1 ur3d2i ur1eff u2rele ure4n u4r1ep ur1erh ur1erw 2urf urf3t ur2gri uri2c u2r1im ur1ini ur3ins ur1int urk3se ur4matt 4u1ro u3rol u1rö ur3p 2urr ur3re ur2san ur2sau ur2ser urst4r ur4sw urs2ze urt2 u3ru ury5 ur2z1a ur2zä ur2zec ur2zi ur2z1o ur2z1w 2us u2s1af us4ann us5art u1sä u6schent u5schmu usch5wer u2s1ec u2s1ei u3seid u3sep use1ra u2serp u2s1ese usi3er. usi5ers. u3sig us5is. us3kl usmas2 usma5sse u1so us3oc u3soh u3sol u2s1op us1ou u1sö u1sp u2spac us3part u2s1pas u2spat u3spek us1pic u2spo us2por u2spu usse4g u4s3sel us2sen us5sende us6seni ussenma7s us2ser us3ser. uss5erfa usser6kl uss5er6su u4sset us2sez u3ssig us2sof u2stab ust3abe u3stal us2tat us2ten us2ter us2th ust2in u3stis u2s1tor u2strä u4strit u3s4trop u2s1tur u2sty u1su us2ur 2uß u2ß1u 2u1t u3ta. ut1alt ut3a2m u2t1ap u2t1ar u2t1är u3te u4t1ed ut1e4ge ut1ei. ut1eie ute2n1 u2tent uter4er u4t3er4sa ut2es ut2et u4tev u4t1ex utfi4 ut2he u2thi u2t3ho u2thu utli4n utmas2 utma5sse u3to. uto4ber uto3c u3tom ut1opf u2tops ut4or ut3rea ut3rü ut3s2a ut2s1ä ut4schl ut4schm ut4schö ut3si ut1s2p ut2s3pa utt4an ut3te ut3t4l utt1s2 utu4re utu5ru utz3eng ut2z1in ut2zo ut2z1w 2u1u2 u1ü2 u1v4 u2ve. uve3rä u1w 2u1x ux2e ux2o ux3t u1ya 2u1z uz3ot uz1we uz3z4 1üb üb1ä 2übc 2übd übe2 übe4n3 über3 ü4bet üb3l üb3r 2üc ü1che üch3l üch4s1c üch5t4e ück1er ück3eri ück4spe ü4d3a4 üden2g ü3d2ens üd1o4 üdö4 üd3r üd3s2 üdsa1 üd3t4 üdwe2 ü4f1a ü2f1ei üfer2 ü2f1erg üf2fl ü2f1i üf3l üf2to ü1g üge6lei6s ü2g3l ü2gn üg3s üh1a ü1he ü2h1ei ü2h1eng üh1erf ü2h1er2k ü2h1er2z üh1i ühl1ac üh1lam üh3l2e üh3mo üh3ne üh1o üh3r2e ühr3ei. üh1ro ühr3ta ühs2 üh3stu üh3t üh4th üht4r ü1hu üh1w ü1k2 2ül ül1a ül2c ü3l4e ülla4 üll1au ül2lei ül3ler ül4leu ül2lo ü1lu ü2ment 4ün ü2n1a ün2da ün2dr ünen3 ün2f1a ün2f1ei ün2fli ün2fr ün2g3l ünt2 ü1nu ün2za ün2zw ü1pe üpf3l ü1pi üp2pl ür1a ü2r1ei ür2fl ür2fr ür4g3en4g ü1r2o3 ür4ster ürt2h ür2zö ür2zw üs2a ü2schl ü5se üse3h üse3l ü1sp üs2s1c üss2e ü4s3sel üs3si üs4st üs2su ü2sta ü2str ü1su ü1ß 2üt ü1ta ü2t1al ü1te ü1ti üt3r üt4s1 üt2tr ü1tu ü1v ü1z 2v1ab va1c val2s 2vang 2varb vas2 v4at va2t3a4 va2tei va2t3h vatik2 va4t1in vati8ons. va2t3r vat3s4 va2t1u vat3z 2v1au vä1 2v1b 2v1d 1ve2 ve3ar ve3b ve3c ve3d ve3g ve3h ve4i 2v1ein veit4 veits1 ve3la ve4l1au ve3le ve3li vel3l ve3lo ve3ma 2ve3mu ve3nal ven2c ve3ne venen4d ve3ni ve3nö ve3nü ve3o ver1 ver3a ve3rad ve3rand ve3ras ver3b2 ver5d2 vere2 verf4 verg4 vergas6 ve3ri ve4rin ver3k vermas8sen ver3sta vert2 ver5te ver3u ve3s 2vesc 2vese ve4sh ve4s1p ves4t ve3ta vete1 ve3to ve3tr 2veü ve3v ve3x2 2v1f4 2v1g 2v1h vi3ar vi4a3t vi2c vi3de vie2h3a vi2el vi3en vie4rec vie2w1 vig2 2vii vi2l1a vi4l1e2h vi2l1in vil3l 2v1i2m vima2 vi4na vin2s 2v1int vi3sa vise4 vi3s2o vi2sp vis2u 2v1k 2v1l2 2v1m 2v1n 2v1ob vo3ga vo2gu 3vol vol2la voll7auf. vollen4 vol6l5end voller4 vol6lerw vol2li 2v1op vo2r1 vor3a vor3e vor3g vo3ri vo5rig vormen4 vorö4 3voy 2v1p v2r 2v3ra v3re v4ree 2v3ro 2v1s vs2e v3s2z 2v1t vu2et 2vumf 2v1v 2v1w 2v1z w2a 1waa wab2bl wa3che wach6stu wach4t4r waffe2 waffel3 1wag wa5ge wa2g3n wa3go 1wah wahl5ent wah4ler wah2li wai2b 1wal 2walb wal4da wa2les wal4li4n 2walm wal2ta wal2to walt4st wa3na w3anf wang4s 1wann wan6z5en6d wa2p 1war2e ware1i wart4e 1was wa3sa wa4scha wa3sche wa3schi wa3sh wass4e 1wäh 1wäl wäm3 2wäng 1wäs3 wä5sc wä4ss 2w1b2 wbu2 2w1c 2w1d we2a we2ba 4webeb we2bl web3s we2e4 weed3 we2fl 1weg we2g1a we2g3l we4gn we2g3r weg1s weg3sa 1weh we4i wei4bl 2weie weifel6d weik4 1weil wei3sc weiss3p wei4tr weit1s wel6schl wel6schr wel2t1 welt3a4 wel6t5en6d wem2ma2 wen3a4 wen2gl we3ni wen4k3ri we2r3a wer2bl 1werbu werd2 5werdens 1werdu werer2 wer2fl wer4gel we4r3io 1werk. wer2ka 1werke wer2kl wer2ku we2rö wer4sta wer2t1a wer4t3ei wer6t5erm wer2to 1wese wesen4s3 we2sp wes2t we2st1a we4st3ei we4steu we4sti we2st1o2 we2stö we2st3r we4stu 1wet wet2s wett3s 2w1ey 2w1g 2w3h 1wid wi2e wie3l2 wien2e wie4st wik2 1wil wim2ma wim4mu win4d3ec win2dr win2e 2wing win8n7er8sc win4num 1wi4r wi3s2e wi2sp 1wiss wi3st wi3th 1witzl 2w1k 2w1l 2w1m 2wn wn3s 1wo1c wo2cha woche4 1woh woh4lei 1wolf wolf4s1 wol4la wol2lä wol4ler wor3a wo2r3i wor2t3r wo4r3u wot2 1wöc wört2h 2w1p w2r w3ro 2w1s w3s2k 2w1t wti2 w2u 1wuc wuch4sc wuls2 wun2da wun4g3r wun2s 4wur. wur2fa 1wurst wus4 1wu4t1 1wüh wüs4 2w1w 2w1z x1a 1xa. 2xa2b 1x2ad 1xae xa1fl 1x2ag xa2m xand4 x2anz 1x2as xau3 xaus2 2x1b 2xc x1ce x1ch x1cl 4x1d 1xe x1e4g 2xek xe2l x1em 3x2em. xemp4 x2en xen3s2 x2er. x2ere xers2 3xes 2x3eu 2x1f 2x1g 2x1h xib4 xi1c xich2 2xid xide2 xi2d1em x1i2do xie3l xi3g xil1 xil2a xi2lo xi2lu xin3s2 x2is xi2s1e xi2s1o2 xis5s xi2su x1i2tu x1j 2x1k2 4x2l2 x3lä x3le 2x1m 2x1n x1or 4x1p xpor6ter x1q 2x1r 2x3s2 4x1t x2t1a x3ta. x3t2as xt1ä x2tän x2t1e2d x2t1ei x2tent x2t1er2f x2t3ev xtfi4 x2t1il2l xtra3b4 x2t3ran xt1s2 xt1u x3t2ur 1xu xu1a x1u2n xu2s 2xv 2x1w 2xy 3xy. 3xys x1z 2y1ab 1yac y1al. y1a2m yan2g y1ank y1ät y1b y1c2 y2chi y3chis ych3n y1d4 y1e y2ef yen4n y2ere yes2 y2es. ye4st ye2th y1f2 y1g ygi2 ygie5 yg2l y1h yhr2 y1i4 y1j y1k2 yke3n yk3s2 y1l y2l3a2m yl4ante yl5b yl3c y4le. yli4n yllo2 yllö2 yloni1 y2l1u yma2t ymp2 ym2pha ympi1 y2n1o yno4d ynt2 y1of yom2 yon4i y1ont y1os y1ou y1p ypa2 yp3an ype2 y2pf y3ph y2p1in ypo3 y4p3s y1r y3r2e y3ri yri2a yri1e y3r4o yrr2 y1s ys2an ys2c yse1 y3s2h y4s3l ysme3 ys2pa yst2 y2s1u2 y3s2z y1t2 y2te. y2tes y3to yu2r yure3 y1v y1w y1y y1z2 za2 2z3ab zab3l za3cha za3chä 2z1ad 2z1af za3ge za3gr 3z2ah zah4ner 2z3ak za3li 2z1all 2z1am z1an za3ne 2z3anf 3zani 3z2ank zan4kl 2z3anl za3no zanti1 za3ra 2zarb 2zarc za3re 2z1arm za3ro z1arti zar2tr 2z1arz z1as zast4 2z3at3 3zaub z1au2f z3aug 3zaun 2z1äc 3z2äh 2z1äm 2zängs 2z1äp z1ärg z1ärm 4z1b4 zbü1b zbübe3 2z3c 2z3d2 zdan2 zdä1 zeau3 zeaus4 2z1e2ben 2zecho ze1e 2z1eff zehe4 zehen1 zeh2l zeik4 zei3la zeile4 2z1ein zei3s2 zeist4 zei2t1a zeit5end zei4t3er zei2tr zeit3ri ze2l1a2 zelau2 ze2len ze2l1er ze2l1in zel3l2a zel4leh zel4li4n zels2 zel3sz zel3t2h zel3tr zelu2 2z1emp 5zen. ze4n3ac ze2nä zen3n ze2no zens2e zen4sem zent3s zen4z3er z2er. ze2r3a ze2re2b 2z1ergä 4z3ergeb z3erhal 2zerhö zerin4t zerk2 z2erl. 2zerlö z2ern zer4neb zer4n3ei 2z1erq zers2 2z1ersa 4z3erste 4z3erstr 3zert zert1a4 zer4t3ag zert4an zer6tere zer6terl zer4tin zer6trau 4zerwei 2z1erz 3z2erza ze2s zes2c ze3sku zessen4 zes6s5end zes2sp ze3stau ze2ß1 ze2tr 2zetts 2z1ex 2z1f4 zfäs3 2z1g2 zger2a 2z1h z2hen zhir3 3zi. zi3alo zi3ar zi2dei zid3r zie4lei zi1erh zi1es. 3zig zil2e zil3l 2z1imp zim2t3 zin2e zin3ei zin4er 2z1inf z1inh zin1it zin2sa zin4ser 4zinsuf z1int z1inv zi2o3 zi3op zirk2 zirk6s1 zis4t zistras6 zi3s2z zit2h zi2t1o2 ziv2 2z1j 2z1k4 2z1l2 2z1m2 2z3n2 2z1ob 2z1of zo2gl 2z1oh 3zol zolla2 zol3le zol2li2 zol3lu zon4ter zo2o 2z1ope z1or zo2ri zor4ne zo3se 2z1osz 2zö2f 2z1ök z1öl 2zön 2z3p4 2z1q 2z3r2 4z1s2 z3sa z3sh z3sk z3str z3sz 2z1t z2t1au z4tehe zte3str z3t2her zt3ho zt1ins zt3rec zt3s2 zu3a zu3b4 3zu4c zud4 zudi4 zu2el zu3f4 zu2g1ar zu4gent zu3gl zug4ste zug1un 2z1uhr zuh2u zu1i zu3k 2z1um. zumen2 2zumf 2zumg 2zuml 2zumr 2z1ums zun2e 2zunt zup2fi zu3r2a z1urk 2z1url 2z1urs 2z1urt zu3s2 zu3t2a zuz2 2züb zür1c 2z1v zw2 z1wac 2zwag 2zwah zwan2d1 z2wang z1war 2zwas 4zwäl 2zweg 2zweh z2weig zwei3s 2z1wel 2z1wen 2z1wer z2werg 2z1wes 2zwet 2zwir z2wit 2z1wo z1wör z1wur 2z1wü 2z1z z3z4a zze3s z3z2o zz2ö", + ["data"]=".ab1a .ab3l .abo2 .ab3ol .ab1or .ab3s2 .ab3u .ade3n .ae3 .aft2 .ag2a .ag4r .ag2u .ai2s .akt2a .al2e .al3k .al3lei .al5len .al3se .al4tei .al4tel .alter6s5 .alt1s .al2tu .ampe4 .amt2s .amt4sc .ana1c .an4a3t .an3d2 .anden6k .and4ri .an1er .ang2 .an3gli .an3go .ang4s2 .angst3 .ani2s .an3k4 .an3na .an3s2 .an4si. .an4tar .an3z2 .aos4 .ap5p6le. .ari1e .ar3k2a .ar4m3ac .ar4mun .ar2sc .ar4tan .ar4t3ei .arter4 .ar6t5erh .ar2t1r .arz2 .as6sest .as2t .ata1 .at2h .at4r .au3d .au4f3 .aufs2 .au2s1 .au6stes .auß2 .ax2 .äm3 .är6schl .ät2h .ät2s .äu3 .bahn3 .bah6ner .bal3t .baus4 .be3erb .beige4 .bel2a .be3r2a .ber2e .ber4g3a .berga6s .ber6g5e6b .ber4g3r .ber4tr .bi4os .bi2t .bit1a .boge2 .bo4s3k .bu4ser .bus3se .bussy4 .bu3ta .ce2ra .ch6 .char8mes .chi3er .dab4 .da2r1 .dar3in .dar2m1 .da4te. .da4tes .de2al .de1i .dein2 .de8ments .de3na .den4ka .den4kl .den4ko .de1o2 .de3r4en .derma3 .dermas6 .de3sk .di3el .di4en2 .dienst7a8d .do3b .do2mo .do1pe .dor2f1 .do2tr .dys3 .ebe2r1 .eh2e .ehe1i .ehe5n .ei3e2 .ei3f2e .ei3k .ei4na .einbus6 .ein3d .ei2ne2 .ein3eb .ein6erl .eins2 .ein3sp .eise4 .ei2sp .eis3s2 .ei4s1t .ei2tr .eke2 .ek3li .el2bi .el2bl .el4fei .el2fl .em3m2 .en1 .en4da .en4d3er4 .en2d3r .en4dü .en3ga .en2gl .enk2 .enn2 .ent3 .en2ta .en4tei .en7thalp .en4tio .en2t1r .ents2 .epi1 .ep3p .er4bei .er8brecht .er2bu .er4dan .erden6k .er4d3er .er1e .ere3c .er2em .erf4 .er1i .ers2 .er8stein .erster6 .er8sterb .er8stritt. .er8stritten. .ert2 .er4z3el .er4zen4 .es3p .es2st .es2t .esta2 .est6e .est3r .et2s .eu3 .eug4 .eur4 .ext4 .fäs3se .fe3la .fer4no .fi3d4 .fi4le. .fi4len .fi2s .flö8s7se. .flö8s7sen. .flö8s7ses .flu2g1 .fs4 .fu2sc .ga2me .gan4ga .gangs4 .ga4s3e .ga6sten .ga4su .ga2t .gd2 .gebe4a .geb2l .gel4b3r .gel2d1 .ge3lu .ge3m .ge5nar .ge3n4e .ge3n2o .gente4 .ge3r4a .ger2e .ge3ro .ge3s2 .glan2 .glanz3 .gla4s3t .gol6der .grif8fes .gus2 .haft3s .hal5le .halt4e .hau2t1 .he2 .he4bei .he3fe .he3le .he4r3an .he3rat .her6b5ra .he3rer .he3ri .he6r5inn .hin3u .hof1 .ho4fen .ho4met .höch2 .ia2 .il3 .im2a .ima4ge .im5m2 .in1 .ind2 .in3gl .ink2 .in3n2e .in3sk .in3t2 .inu1 .io4d .ioni1 .ire3 .is2a .it2h .iv2 .joni1 .ka2b3l .ka2i .kal2a .ka3le .ka3t2a .kat3i .ka4ti4o .ken6num .ker3s .ki4e .klang3 .ko3b .kopf1 .kor4da .kraf2 .ks4 .kus2 .la3be .lan8de8mi .le4ar .le4gas .le3n2i .lich8t7er8s .li2f .li3po .li4ve. .lo4g3in .lo2sc .los3s2 .lo2tr .lo3ver .lö4ss .lus2 .luster6 .lu4str .lut2h .ly2s3 .ma3d .ma3ge .mal4e .mas8sen. .ma4str .mat4c .matu3 .md2 .mel2a .me3ne .me3no .men8schl .men8schw .mes4sp .mi2f .mik4 .mil2z1 .mi2t1 .mm2 .na3no .na3t .näs5c .nebe4n .ner2f .ne1ro .nich2 .nicht5e .ni2e .ni3k4l .no2c .no2s .no2th .nul2 .nus2 .oa5s .ob1a .obe2 .ober5ei .ob3i2t .och3 .of2e .ohr5s .oper4 .or2a .ord4e .or3g .or3k2 .ort2 .orts3e .os3s .osta4 .oste2 .ost5end .osten8de .oste6re .ost3i .ost3r .ot1a .ou2t .ozo4 .öl3l .pab4 .part4h .pe2c .pe3la .pe3le .pe3na .pe4ste .pf4 .ph4 .poka2 .postei6 .po8steig .po4sto .po4str .ps2 .rabe4 .ra3ch4e .ra3me .ra4sp .ra4s3s .rau2m .rau8schl .räu3sc .re3ale .rebs2 .re3cha .re5insz .reis6e5i .rei6str .res2t .re4stu .ri4as .richt6e .ri4f .ro4a .ro3be .ro2e .ro2ha .ro3m .rom4a .ro2t3r .ro3tu .rö2sc .rö4ss .rös3se .ruf3s .ruh2r1 .runder6 .ru5s6ses .rü1b .rücker6 .rü4ss .sa3br .sali1 .sali3e .sami1 .sas2 .sa5sse .sau1c .sau4er .sau5er. .sä5s4 .sch4 .schaf8t7end .scheiner8 .scho7s8se. .scho7s8ses. .se2e .seein4 .se2ha .sein2 .sen4f .sen3s .se3re .se1ro .se2t1 .sha2 .si4en .si3gn .sini3 .si2te .ski1e .sour2 .spani7er. .spä5s4 .spiege8lei .st4 .stau8becken. .ste2i .steiner8k .sto4re .stras4 .stro6ma .sucher6 .sy5s .tage4s .ta3mi .tan4k3a .tan4k3l .ta3ra .tar3t2 .ta2t1h .ta2to .ta4tor .ta2t1u .te2e .te2f .tehe3 .teiler8s .tei8l7ersc .te3le .te3no .te1ra .tes4t .te6stei .te6stel .test3r .th4 .ti2a .ti2e .ti2me .ti4mes .ti3r .ti2s .tischen8 .ti8sch7end .tite4 .tode2 .to4der .todes3 .to2n .to4nat .to3nes .ton3i .to4nin .tons2 .to4pl .to2pr .to2w .tras3 .tra4ss .tri3e4s .trockenmas8 .ts4 .tse3 .tu3ra .tu3ri .turm1 .tur4ma .ub2 .ufe2 .ufer3 .ul2b3 .um3 .ume2 .umo2 .ums2 .un3a2 .un3d .une4 .un3g2 .uni2t .ur3a2d .ural4 .uran6fa .ur1c .ur1e .ur4inf .ur3o4m .ur1o2p .ur3s2 .ut2a .ut3r .ve5n2e .vol2 .vo4r .wah4l .wa2s .weg5s .weine4 .wei4ta .welter8e .welter8k .wer6ker .wer4kr .wer4tr .wetterer8 .wi4e .wor2 .wort5en6 .wur2f1 .xe3 .ya4l .zeit3s .zel4la4 .zelle4 .zel6lei .zel4li .zeug4i .zi2e .zie4l3u .zin4ka .zin4s3c .zin4st .zol2 .zuch2 .zug3l .zu4gra .zu2pf .zweigen8 .zwei8g7end a1ab aa2be aa1c a1a2ce aa2gr a1akt a1a2n a2ans a1aq 2a2ar aa2r3a aar3b aar3d aa3rea aa2rei aarf4 aar3g2 aar3k4 aart4 1aas aas1t aa2th aa2t3r aat4s1 2a3au a1ä a1b 2aba 3abad ab1alt a3b2am ab2ant ab1au ab2aut ab1ä ab2är ab2äu 2abbat 2abbin 1abd 2a3be. 2a3bec 2abee ab1eic abe3i4d ab1eil ab1ein 2ab2el abe2la abela4d abe2le 2aben. 1abent 2aber a2berd a3beri ab1er2k ab1er2r ab1er2z 4abes abe2s1e ab3esse abes2t ab1eß 2abet 2abew 1abf 1abg 3abga 1abh 2abi 4abil ab1ins ab1ir ab1it 1abk ab1l 1a2bla a3blat 1a2blä a2b3led 3ab3lei a3blem 2ablet ab3li a2blin ab4lit 2ablo 1a2blö a2blu abma3s 1abn 2abo 3a2bo. ab2of 3a2bon 4abot 2abö ab3r a4brä a2bre ab4ros 2abrö a4bs 1absc 1ab3s2p abs2t2 1abstu 1abtei 3abtr 2abu abu3g4 a2bum ab1ur 2abü 1abw 2aby 3abz 2ac. 2a3ca 1ac1c 2acci ace1 a1cem a1cen a1cet ach1a a1chal a3chari ach3as ach3au 2achb a1che a2ch1e2c ach1ei ach4ei. a2chep a4cherf ach5erfa a4ch3erh a4ch3erl a4cherö a4ch3erw 2achf 2a1chi a2chim ach3l 2ach3m ach3n a1cho a3cho. a2cho2r ach3öf 4ach3r 2achsc achs4el ach3s2i ach3skr achs4or ach3su a4cht ach4tak ach6terf ach8tersp ach6t5erw ach2t1o acht5rat ach8traum ach8träume. ach8träumen. ach6trit acht6s5al ach4tum a1chu ach1u2f ach3ü 2achv 4ach1w a2chy a1ci ackmu4 ackmus3 ack2sp acksta4 2a1cl a3co acon4n 2acu a1ç a1d 2ad. 2ada. 4adab ad2abr ad2ag adai4 ad1an 3adap 4a3d2a2r3 2adas 2adat a2d1au a3dau. 1a2dä ad1c 1add 2ade. ade2al a3dec a3dee adefi2 2adeg a3dell 4aden a3den1a ade4nat adeo2 ade1ra a2d1erk 4ades2 ade3sp ades4s 2adf 4adh 4adi adi3en adi3er. adie4sc 3adj 2adli 4admu ad2ob ado2n ado4na a2dop 2adp 2adq a2dre 2ad3rec ad3rei ad3run 2ads2 ad3sz 2ad2t1 adte2 ad4tor 1adv 2a3dy 2a1e1 ae2b a2ec ae2d4 ae2i a2ek a2el a3el. a4ela a4ele a4eli a3els ae2m ae2o3 aeop2 ae2p 3a4er2o a2es2 ae2sc ae2ta a2ew ae2x 2afa af1ab a2f1a2n a3far a2f1au 2afä a2f1än 2afe a2f1ec a4fentl a4f1ep aff4a af2f3l aff4th 2afi afi6kanz afi4kat afi2t 2af3l af1la a1f4lu 2afo a2f3oc a2ford a2f1ort 2afra af3rau af3rä af3re 2afro af3rö af4rü af3s2a af3sh af2si af2sp af2t1a af3tat af2tei af2te2l aft4erk af2t1o af2tö aft3r af2tra aft5rei af2tur a2f3ur 2afü a1g 2ag. 2aga ag1a2b ag1a2d ag1am ag1ar a2g1au ag2del ag2dr ag2du 4age. age4l3ei age4ler 2agen. age4neb a2gent 2ages age4sam age4s3in age4so ages3p ages5s ages6sen age4s3ti 3aggr a2g1id a2gim 2a2gl ag4lan ag4las ag3le a4glö 2agm ag2n ag4nat a4gnä ag4ne. ag4nu ago3b ag3rat a2g3re a2gri ag3rie ag3rin 2ags ag3sah ag4sam ag3s4eid ag2sp ag7s8porta ag2s1tr 2agt ag2th 2agu a2gund 2ah. 2a1ha ah2an ah4at a1hä 2a1he ahe1in a2h1er2h ahe3u a1h2i ahin3 ah2l3a2 ah2l1ä ah2l1ei ah2lel ahle4na ah4l3erd ah4l3erh ahl1o2 ah2lö ahl3sz ahme1i ah3mu ah4n3a ah2nä ah3nee ah2nef ahn3el ah4nerd ahner4e ahner6le ahner4n ah2nin ah2no 1a2hor ah1os ah3ös 4ahr ahr1a ah3r2e ahren6sc ahre4s3 ahr2ti ahr4tri ahr4tro ahr4tun ah2ta ah2te2l ah2t1ex ah2t3r aht1s a1hu ah1w a1hy 2ai. ai1a4 a1ia. 2aib ai2bl aid4s aids1t ai1e4 ai3en1 aif4 ai1fr a4i3g4 a3ik. ai3ke ai2lar ail3d4 ai2lei ail3g ai2lo 4ain ain2a a1ind ai5n4e ain3s ains2p 3airb ai2sa a3isch. ai5schw ai3s2e ais3sen ais5st ai2sti ait4 a3iv. a3ivl a3ivs a1j a2jat ajekt4o 2ak. 2aka. 2aka3b akab4r a2kad 2akal 2a3kam 2akan 2akar ak4at akat1a aka4tak 1akaz 4akä 2akb 2akc 2akd 2a1ke a2kef a2k1em a2kent a2kes ak2et a2keu 2a1ki ak1ins 1akku 2ak3l a1k4la ak4li 3aklö a1kna 2ako 2a1kr ak3res a3k4ri 3akro3 ak3rü 2aks ak3sh ak2t1a2b ak4tag ak3tan 2aktb ak2tel ak3ten akt2er 2aktg 2aktik 2aktis 2aktm ak2to4b ak2tö ak2t3r ak3t4ri 2aktsi 2aktsp 2aktst 2aktw a1ku 2akun a2kup 2akur 2akü 1akz 3akze a1la 2ala. 2alabo al1af al1age 2alai al1akr al1am al1ana 2aland a2lang al1anz al1app a3lar. al3arc a3lare 2al1arr a2lart ala2s al1asi al1ass a3lat. al4atm alat5t alat3z al1au al3aug a1lä a2l1äm al1än al1ärm al1äu 3albat al2bär alber4e al4berh al4b3er4w al2b1l al2boh al2bon alb3ru alb5st al4dan al2dä al4d3erl al4d3ern alde2s ald3inn al2dra al2drä alds2 2ale 4a3le. ale4ar a2l1e2b al1eck a4l1ef a2l1ei a3l2eic a4lein a2l1el 5a2lema a2l1e2mi 4a3len. alende4 al3endr a4l3ends a2leng al2enn ale2p al1epo 4aler. a2l1erb aler2e a2l1erf a2l1er2h aler4kl a2l3erl al1erm aler4mi a2l1er4r al2ers a2l1ert 3a4l3erwä 4ales a2l1e4sk a2less a4leth a2l1eu alf4r 3algi al2gli al3glo 1algo 3algor alg4r 2ali al2imb al1imm ali4nal al1ind alin4ge a2l1in2q al1ins alken1 al2klö al2kne al2kof 1alkoh alk3s2 al2lab al3la3d alla4me al2lan al2l1a2r al6later al2lä al3läu al3le. al4lec 3allee alle4gi al4leh al3lend all3erk aller4z al3les alle3se al2leu al2lid alli5er. alli7ers. al2lob al2lo2c al2lop al2lo2s al2lö2 all3öse al2luf allu4s al2lü4s al2map al3mas al4m3ast almo6de. 2alo. a2l1ob 3a2loe a2l1of 4alog alo2ga alo2gr al1ont al1ort 2alos a2l1ö al2ös 3alp. 3alpe. 1alph al2pho alrat4 al3sak al6schei al4sh al3skl al2stu al2sum al2t1ak alt3alg al2t1an al2tat al2tau 1altä alt3eis alt3elt al4temu al4t3er5f al2teu al2tid al2tin alt1op al2tö al4t3rat al2tre al2t3ri al2t3ro alt4stü a1lu alu3b4 al2u3f alu3g al1u2k a2lum al1umb a2l1ur a3lus 4aly al2zar al2zau al3zen alz4erk al2zw am2a ama2ba ama3d2 ama3g 2amah a2malg 2a3m4an 2amar ama4sta 1a2maz 2amä 4ame. a2meb 2amel am2e4n1 amen6s5pr ame3r2a amera3u a2m1erf 3a2meri ame5r2u 2ames a4mesh 2a3met 2amf a3mi. a3mie ami2k 2a3mir 2a3mis 2amit 2amk 2aml 2amm. am2mab am2ma2c 2ammal amma2n am2mar am2mas amma4sc am2maß am4ma4te ammen8ge. ammes3 am2mid ammi2e am2min am2mit am4mo2d am2m1ö ammu2 amm3unt am4mus am4mü amni1 a2mö 2ampe. 2ampen amp2f1a2 2am2ple 2ampo am3pr 4amsc am4schl 1amse am3sh 1amt. am2t1a2 am2t1ä am2tei amt3eig am2tel 2amtem am4terh am4t3ern am2t1ex am2tis am2tit am2to am4tou am2tö am2t3r am2t1u 2amtv 2amu 3a2mul 2ana. 2anab ana3c an2ad anadi1 an2ag 2a3nak an1alg ana4lin 2anam an2a3ma 2anan an4and 2anas a5nat. ana4th a5n4atm a2nato ana2tr a5nats an3aug 1a2n1äs 1anb 2anbas 2anbö 2anbu an3ch 2and. 3an3d2ac and3arm and3ei anden6ga an4d3ent and5erob ande2s an2d1ex and4sas and4seh and2so and6spar and6spas and6s5paß and2su 4andu2 an2d1ur 2ane an3ec a3nee an2ei. an3eif 3aneig a4neis 3a2n1e4k ane2l an1e2mi a2nemo aner4fa a3nerg an2erh a4nerke 4anern a4nerz. an4erze an1eth 3anex 1anf 2anf. 2anfab 3anfä an3fe 2anfi an4fj anf3le 4anfors anf5rau 2anfs an3f2u 4ang. 1anga 2anga. an2g1ar 2angas 2ange. 1angeb 1angeh an2g1ei an4g3erf an4g3er4h an4g3er4w an4g3erz 2angh 2angie ang1l an2gla ang5n ang1r ang3ra 1an3gri 4angs. ang4sto angt2 1anh 2a3ni an2i3d 4anie ani3els ani5ers. anig2 ani3ke 3a4nim a4nind ani2o an3i4on a4niso anis2t 2anj 2ank. an2kab an2k1ak an2kan an2kei 2an3ken ank5erfa an3kes 2anki an2kid an2klö an2klu ank3no an4k3opf an2kor ank1r ank3ra an4kras ank3rä an2kro 2anks2 ank3se 2ankt4 3ankü 1anl 2anlad 3anlag anma3s2 2anmo 1anmu 2ann. 1annah an2nar an3ne an4nef an4nei an4nene ann2er 2anns ann4s3p 2annt 2ano. 1an1od 2anof 2anog 2a3nol ano2la 1a2nom a3nom. 2anoo a2n1or ano2ri 2a3nos 2a1nö 2anpu 1anr 2anrö an4same an3s4ar 1an3s2ä 1ansc an3skr ans1pa ans3pon 1anspr 1anst an3s2z 2ant. ant3ar anta4re an3t2ä 1antá 3antei an3tha 2antie 3antise anton2 3antr ant3rin 1antw 2anu anu3r anu3s anus3s a1nü 1anw 2anwi an2zä 2anzb 2anzd 1anzei anz3elf anze2n 2anzes 2anzg 2anzh anzi2d an2z1i4n 2anzk 2anzm 2anzr 2anzs 2anzt 1anzü 3anzün 2anzv 2anzw an2zwi 2anzy 2ao aof4 ao3i4 a1op aopf4 a1or a1os3 aost2 a3ot. ao3t2s 2a1ö2 a1p 4ap. ap4a apa3b a2pe. a3pel a2pé a2pf ap2fa 1apfel 2apfes a3pfl a2pht 2api 2apl ap4la a3plä ap3le ap3li ap2n 3a2pos a2pot 1appro 2apr ap2so ap4ster ap3t2 2a3pu 2ar. a1ra a3ra. ar2ab 2ar3abb ar3abf ar3abt ara3d2 ar3adr ara3ge 2a2r3al a3rale a3ra3li a3ralo 2aran a2r1ang a2r1anz 2arap a4r3app 2a2rar ar2asy 4arat a2r1au a1rä ar1äs 1arb 2arb. 2arba ar2bak ar2b3at ar2bau 4arbef ar4b3ein 2arbek 2arben 2arber 4arbi 2ar2bl 2arbo 2arb1r 2arbs2 arb3se arb3sk arb3so 2arb3t2 2arbu 1ar1c 2archl 2archr ar2dau arde4i ar2dop ar2d3r ar2du 2are. a2rea are5aler a2reb4 aree2 ar1eff a2reh ar1ehr 2arei a3rei. ar1eid a3reie a3reih areim3 a2rein arein4b arein4s arein4t a2rele 4arem 4aren. aren6sem are3r2a arer2e a4r3erei a2rerg a2rer3h a2reri a2rerk a2rerl a2rert ar2erw 2ares ar2et are3u a2rev arf1r arf3ra arf2sp 4arg. ar3gan ar2gl ar4gn 2arg4o ar3g4r 2arh 2ari ar2ia a2rid ari3e2n ari3erd ari3erg arin3it ar1int a3r4io ar2ir ar4is ari2su a3riu ar2kal ar2k1ar ark3aue arker2 ar2kil 2ark3l ar4klag ar2kle ar2klo ark4lö ar2koa ar2kor ark3s2a ark2se ark3she arku2 ar2les ar3mad arm1au ar3m2ä ar2m1eg ar2m1ei arm2or ar2mum 4armü 4arn ar2nan arn2el ar3ni a1ro arob2 4aroc ar1o2d ar1of aro2fe 2a3rol aro3m a2r1op a2ror 1a2rou a2r1ö4 2arp arr1ac ar2r3ad ar2r1as ar4rek arre4n1 ar2rh 2arri ar2r3or ar3s2h ar3s2i ar3sse ar2tau 2artb ar3t2e 2artei artel6li6 2artex art2i 2arto art3r art4res ar2tri 2arts art3ske 2artuc 2arty 2aru a2r1uh ar1um a3rumm a2rü 2arv arwa2 2a3r2y 2arza ar2zau ar2zä 2arze 2arzi ar2zö 1arzt arz2t3r 2arzu ar2z1w 2asa a4s3aa as2ad a4s3af a3s2al asal2t1 as1am as3art asa2s2 asa3sse as3at asau4f a4s3aug asau2s1 as3ät a2sca a4schec a4schef a4sch3ei a6scher6g as4chi a2schm 2ascht a3schu a4schum 2asd 4a3se a4seb a4sec a4s1ef as1eie a5sen. ase4na ase4n3o asens2 asen6sem as1ent as2er as4erd ase2re aser6geb a4s3erke as4es ase2t as1eta a4sex 2asf 2ash a4s3ha as2hi as3hir 2asig a2s3i2k 2asim asin2g as1inn 2asis as3ku a4s3l a4sn 2a1so as3ob as1of a3sol a3som aso2p as1or a4soz as1p as3pe aspek6to a4spel a4s2ph as2pi as3pik as4pin as3pio a4spir a4spl 2aspr as2pra as3sa ass2a3b ass6aus. ass2e ass3ein as3sel asse3le as3ser asserma6 a4ss2i as3sin as3ski as3so as2spo as2spr as4st as5sta as5stei as5str as5stu 2asta a4stab a3stä a4s1tec as2tee ast2el a4stemp a4s3tep ast2er a4st3ese as2tex a4s2th ast2id as2to a2stoc ast3orc as4trau a2st3re ast4ren a6stritt a3stro a4strol ast5roll a4s1tub a4stuf a2stum 2a1su as2ur a3su4s3 a4sw aswa2s 1asy 3a4syl 2asys as3z aße4 aß2en3 a2ß1er aß2th 2a1t 4ata at1abe at1abr at2a1f a3ta3g at2ago a3tah ata3la a3tam at1ang at3ank at1apf at2ast at3att a2t1au at1än 4atb at2c a2teb ateien6d at1eig 3a2teli a3tell 3atemg at2en ate4na atens4 a2tep 4ater ate3r4al ate3ran at4ere atern2 ate2ru at2eu a2tew 4atha at3hag at3hal a3t2heb ath3in. 3athl a4thr at2hu at3hü 4a3ti ati4kab ati6k5erw a4tinf at2is ati2sa ati2se a4tiso atis3s ati6v5erf 3atla 4atli 3atm 4atma 4atmä at3mu 4atmus a2t1ob a3tod a3tog a3tol 3a2t4om atom1e ato2mo at1op a3tor at1ort a3tos a3tra. atra2t a2t3rau a2t3rä at3re at3rin at3rom a3t4ron at3rot at3rü at2sa at4schn at2se ats1e2h at2si ats1in at2s1o ats1p ats3tät at3ta 3attac at4tad at2ta2g at4t1ak at2ta2l at4tang at4tar at4tau at2tä 4atte. at2tec at2tei at3t2el at4temp 4at5ter attes2 at3thä 4atto at2tob at2t3rä att3s2 at3t2u at2ty2 at4typ 4atu atu2n atze4l atz3ela atz3elt at2zem at2z1er a3tzere at2z1i atz3t2 at2z1w a2u 2au. 2au1a2 2aub au2bab au2ban au2b1au au2bei aube4n au2beu au2blä au2bli au2blo au2blu aub2si aubu4s 2auc au2dr 2aue aue2b au2ere aue3rei auer3ö au5erst. au3ert au2fa auf1ak auf1an aufas2 3aufber 2aufe. 2aufeh 4aufen. 3aufent auf1er au4fer4k au2feu auff4 auf3ind 1aufla 1aufn 2aufo auf3ski auf3t2 2auft. 5aufzeic 3aufzug 1aufzü 2aug au2ga au3g2ar 4augeb 4augeh 4augel aug2er 4augl 4augr au3gu 2auh au3ha auh1u 2au1i au2is 4auj auk3t aule2s aul4les au3lü 2aum au2mal aume4n au4m3ent au2m1e2r1 aum3eri au2m1id au4mil au4mit au2m1o aumo2r aum3p2 aum3s2 au4mun 4aun au3n2a aun2e au4n3ei au2nio au2no au3nu a4unz 2aup2 2aur2 au1rh au4sag au2s1ah ausan8ne. au2sas au2sau 2ausc au6schmi 1ausd 2ause. au4s1eh 2au3sen au4s3erb au4serf au4s3erk aus3erp au4serw 1ausg au2sin au4sis 1ausl au2so aus1or au2spr 1ausr auss2 3aussag au3sse aus4se. au8ssende aus4ser aus4ses au2st2a aus3tau 2auste au4stec aus3tie aust2o au2stö aus3tri 3ausü 1ausw 1ausz auße2 a4ut au2tab au2t1äu 2autb au2t1e2l au3ten. auten4g au4t3erh aut5ero au3tet 2autg au2thy 1auto au2trö 2auts 2auu 2auv auve4 2auw 2aux 2auz auz2w 2a1ü a1v av2a a3vang ava3t2 avener4 2avi a2v3r av2s 2a1w awi3e a2wr a1x ax2am a2xans a3x2e a3xid a2xio axi2s1 2a1ya a1yeu ayma2 ay1of aysi1 ay3t a1z az4a a3za3d 3azal a3z2i az2o a3z2u az2zen az2zw ä1a 1ää 2ä1b ä2b3l äb2s äbte3 ä1ce ä1che äche1e äche4n ächenma5 ächenmas8 ä1chi äch3l ä2chr äch4sa äch2s1o äch2sp ächt4e ä1chu ä1d ä2da ä2d1ia ä2dr äd2s äd3te 2ä1e äe4k ä3eu äe2x äfe4n äf2fl äf3l äf3r äf4ro äf2s äft2 äft4s ä1g ä2g1a 1ä2gä ägd2 ä5ge ägen4e äge2r3a ä2g3l äg2n ä2g3r äg4ra äg2s äg3sta äg3str 1ä2gy äh1a 2ä1he äh1ein äher8gebn äher3t ä1hi äh1in ähl1a äh3l2e äh4l3e4be äh5ler 4ähm äh3na äh3ne 1ähnl 2ähr äh2rel äh3ri 2äh2s 2äht ä1hu äh1w 2äi ä1im ä2is ä3is. ä3isch. ä3isk ä1j ä1k äka2la äk3l ä2kle äk4li ä2k3r ä1la älbe2 äl4bl älk3 älks2 äl2l1a äl2p3 äl4schl ält2e älte1i ä1lu 2äm4a3 ämer2s ämi3en 2äml äm2ma4 ämmas2 ämoni3e 2ämp ämp7f4e äm2s ämt2e ämter3 2än. än2dr 2än2e äne2n1 2än2f3 änft2 4än3g2e änge4ra 2än2gl äng3le än2gr ängs2 äng3se 2ä3ni än3k2e än2k3l än2kr 2änn än3n4e2 2äns än4s1a än2s1c äns2e 2änz ä1on äo3s2 ä1pa 1äpfel äp2pl äp2pr äp2s1c 1äq ä2r3a4 är4af är1ä är2b3le är1c 2ärd ärde4s 2äre ä2r1ei ä2r1e2l äre2m är1emi äre2n ä2rene ä2rerh är2es är3ge ä2r1ind är1int är3ke ärm3arm ärm3at ärme1e ärm3ent ärno2 är1ob är1of är1op ä1rö är3re ärse2 är2seb är4seh ärs1er är2si är3spu 2ärt ärt4e är2th ärt4s1 ä2rü 1ärz ärz3te är2zu är2zw ä1s äs4c 2ä3s2e äse3g äse1i4 äse5ref äser4ei äse4ren äser2i ä5si ä3s2kr ä2s1p ä3s2s 2äs4s1c äss2e äss5erkr äs3sern äss5ersa äss3erw ä5sses äs4sh äs4s1t äs4t4e 1ästh ä2str ä1ß 2äßc äß1erk äß1ers ä2t3a2 2ä3te äte3a äte1e äte1i äte3l2 äte2n äteo2 äter4bl äte3se ät2et ä2th ä1ti ät1id ä1to ät1ob ät3r ät4sa äts3au ät2sä ät4schl ät4schr ät2s1i2 äts3l äts1or äts1p ät4s1t äts3te ät2tei ätte4n ät2tr ä1tu ätze3l ät2zw äu2b3l äu2br äu1c äu3d äude3 äuder2 2ä2uf 1äug äu4g3l 2äul 2äum äu2ma äum3p äumpf4 äum2s1 2ä2un äun2e äu3nu 2äu3r2 äure1 äu1s 2ä3us. 2äusc äu4schi äu4schm äu6schü äu3s2e äuse1i ä3usg ä3usk ä3usn äu2s1p äu3s2s äuss1c 1äuß äut2e äu2tr ä1v ä2vi 1äx ä1z ä3ze â1t á1n 5ba. b2aa b3a2ba 2babf 2babg ba2bl ba2br 2b1abs bach7t4e back3er back3s2 ba3d2e bade1i 2b1adel 2b1adl 2b1adm b1a2dr ba2du 2b1af 3bah bah6nene bai3d bais2 b2ak ba2ka ba2k1er ba2k1i ba2k5l ba2k3r ba2lab ba2l1ak ba3lal ba2lau baler2 ba4l3erk balk4a balke4 bal4lan balle4b bal4l3ei bal6lerg ball6erk bal4li4g bal4lo4k ballö3s 2b1am b2a3ma ba2me 4bamt ban2a 3b2and band1a ban4dal ban4dan ban4dar ban6deng ban2dr ba3n2e 2banf b1ang ban3gl ban4k1a banker4 ban2kl ban2kn ban2kr ban2ku 2banl b1anna ban2o 2b1ans b1ant 2banw b1anz ba2r3ab ba2rad bar3ast ba2rat bar3de ba2rei ba3r2en barer5ei barer4t barf4 3bars b1arz bar3zw 3b2as ba3s2a ba2sc bas2i bas4sa bas6st bas4t ba2str ba2ß1 ba4t3ent bat2o 3bau. bau3b bauer4l bauer4s bauer4w bau3fa bau1fl bau1fr bau3g2 b2auk bau3r bau3s2k bau3sta b1a2x ba1yo 3b2äc bä1ch 3b2äd 2b1äh b2äl 2bärz b2ä4s3 2bäug 4b1b bbe4n bbe4p b4be2se bb3le. bb2lö b3brec b3bru bbru2c bb2s bbu1 4b1c 2b5d4 bdä4 bdän3 bdome4 1be. 3bea be3ab be3an beat2m be3au be4au. 3beb b1ebb 1bec be1ch 2becht 2b1e2del bedi4 be1e2h bee2l be3ela bee4rei be1erh be1erl be1ert be1eta bef4 2b1eff be3g4 be2he. beh5ri bei3b 2b1eier bei1f4 bei4ge. beige4l beige4p bei3k4 bei3l2a 2b1eime be1ind be1inh bein6hal bein4hi bei3s2 bei5st beit4e beit2s beit4sk beit4sp 3bek 3bel be3lag be3las bel3d be3lec 4be2lek be2l1en bel3ere be2let bel3f bel3la belle4n3 bel3li bel3om be2lor be2löf bel3sz belt2 bel4un 1bem4 3b2em. 3b2e3ma 2b1emp 2bemul 1ben 3ben. be5nabe ben3ar be4nas be4nat be2nä4 bend3s2 b2ene be3nei be4n3end be4ners ben2eu 3beng be2nid be4nis ben3n 5benp b2ens ben4s3pa ben4spr benst4 3bensv 3bensz 2b1entb 2bentd 4benteu 2bentf ben3th ben6thei bent4r 2b1ents 2b3entw be2nu ben3un b2en3z2 be1o 2b1epi 2bepoc be1ra be2rak be2r3am be2ran bera4s berb2 berbla4 ber3d be2r1e2b be4reck be4r3eiw bere2m be4rene ber4erg ber4erw bere4sc bere2t berf4 ber4g3af ber4gal ber4gli ber4hab beri2d ber4in. be5r6inne berin4s be2ri4o ber3iss ber3ko ber3kr bermas4 berma7sse ber3n2a bern2e b1ernt be2rö4 3bers. ber5se ber3st4a ber3t2a bert2e bert2i berz2 ber3ze ber2zö 3b2es be3sa bes4abb bes2am be4sap be4sar bes2au be2sep be2s1er be2s1id bes2po bes3sa bess4e b3esst. bes3sz beste2 be6stein bester4 be6sterh be4s3tol be4st3o4r best4r be4strä be4s3tur be2sur be3s2ze 3bet be3tam be3tha be3thi bet2to be1un be1ur 3bev 3b2ew2 2b3e2x 3b2ez 2b5f4 bfal2 bflö4 bflös3 2b1g2 b5ga bgas1 bga4st bga4su bge3 bgel2e bge5n bges2 2b1h2 b5hä 1bi bi1ak bi2ar 3bib2 bibe2 biber1 bi2c bi3do bieres4 bie4str biet4s 3bietu biga1 bik2a bi2ke. bi2kes bi2kre 3bil bil4deb bi2lei 4billu bi2lu 2bimp 2b1inb bin2e bine4n b1inf bin4fo bin2g3a 2b1inh bi2n3ok bin4ol 2b1int 2b1inv bi2o3 bioi2 biri1 3bis bis2a bi3si b1iso bi2sp bis4s1c bi3sta bi2s1to bi3str bi2stu bi2stü b2it. b2ita b2ite b2iti bit4r bit2ta2 bi2tu bi3tum bi3z2 2b1j bjek4to 2b5k4 bl4 2bl. bla3b4 2b3lac b3lad b2lanc blas3er b2latt b2lau. b3laus 2b3law 2b1län b2läse 3blät b2le 3ble2a b3leb 3blec b3leg 4bleh b4lei. 2b3leid 2bleih b3lein blei3s 2bleit ble3l ble2n b3lenk b3lese 2blesu ble3sz 3blet b3leu 2blich 3blick b2lie 2blief 4blig b2lind 2b5ling4 b2lis 2blis. b2lit b3lite b2lo b4lo. 3b4loc b4loi b3los2 blo3sse 3b4lum 2blun b2lus 3blut blut1o 3blü 2b1m bmas2 4b5n2 bnas4 bni2 bnis1 bo4a bo5as b1o2b bo3ben bob3r bo1ch2 bo3d2 boe1 bo2e3i 2b1of bo3fe bo3he boh2ra boh3rer boh2u bo1is bo2lan bo2lau bol3le 3bon. bo3n2a bon2da bon2d1e bo2ne 3bons boo4l boo2ti b1op 3bor. bo1ra bor2an bo2r3as bo4rä bor2da bor2d3r bo2rei bo4rig bor3m b1ort bor4ter bor6t5rat bo4ruh bo2sc bo3se bo4s3p 3bot bote3n4e bo3th bot2so bot2st bot3t bo2xo b1oz bö2b3 2böf 2b1öl 2b1p4 bpa2g 2b1q b2r4 2br. b4ra. 2b3rad 2b4rah b4ra3k bra4ss brast4 2b3rat. brat3er4 bra6terg 2b3ratg 3brä 4bräd brä4u 2bre. 6b5rechte 2b3red 2b3ref 2breg b3reif 2brek b4rem b4ren. 2b3rent 2breo 2b3rep b4rer b4res. b3rest b4ret bret6t5en b4rez bri2da brie4fa 2b3riem b4rien bri2er b3ries 2brigk b4rina 2b3rind b4rio b4risc 2briß b3ritt brob2 2b3roh 2b3rol bro2ma b4ron 2b3rost bro2tr brot3t4 2b3rou 3b4rö b4ruc 2bruf b4rum 2b3rund bru4s brust3 bru2th 3brü 4b3rüb brü4ss 2b1s b2sad bs1amb b4samt bsas2 bsa3sse bsau2r b4s3är b3säu b5sc bsch2a b6schan b6schef b6sco b3se. bs1e2b b3sel. bse2n1 b3sen. b2s1ent bs1er bs3e4r3in b3ses b2sim bsi2t b4s3ki bs3kr b2s1of b3s2oh b3sol b4sop bso2r b2sö b3s2pi bs2pl bs2pu bss2 bst1a2b bs2t1ak bst3ank bs2t1a4s bs2tau b3stä bs1tät bst3emi bst1er b4stern bs2t1h bst3ink b2stip b3sto b4stob b4stod b4stor b3stö bs2tr b3stra b2s3trä b4s3treu bst3ro bs2tu b3stü b4stüb b2s1un b3sz bs2zep bs2zi 4b1t b3ta bta4st3r b5te b2t1h bt2i bti2s bt4r btran2 bts2 btü1 bu4chec bucher4 bu6ch5ers bu3ches bu2chi buch3s4p bu2e3 bu2f bug3 bu2gr bull3a 2bumf 2b3umk 2buml 2b3umr bun4a bun4d3er bunde4s b1une b3un3gn 2b1unh bur1c b2ure b2urg burg1a bur4gan bur4gar bur4gin bur2gr bu3r2i 2burn b3ursa burt4s bu2sa bu2sc bus3cha bu3sche bu6schei bu6sch5el busch3w bu3shi bu2si bu2s1p bu4sses bussy2 buster4 bu6s5term bu2s1tr bu2su but2a buto3re 2büb bü1c bügel3e bü3s4 2b1v 4b5w 3b2y1 bya4 byo2 by3p2 bys2 2b1z4 b5ze bzeit1 bzu1 1c2a cab4 ca3bl 3ca2c ca2e3 ca3g2 ca1h cal2a cala3b cal2f3 cal3t2 2can cana3 ca2pe car3n2 carri1 car3tr ca3s2a3 ca3t2h ca1y2 cä3 cäs2 c1b 2cc c1ce c1ch2 c2d2 c3do 2cec 1ced ce2dr ce1e 2cef ce1i ce3in 2cek 3cels cen3a ce3nu cen3un ceo2 1cer cer3a cere1 cere3u ce3r2i ce4ris ce1ro ce3s4h cet1am ce1u 1cé c1f c1g4 c2h 4ch. 2chab ch3a2b3i 2chac 2ch1a2g ch1ah 2ch1ak chan4a 3chanc chan3f ch1ang 4chanl 2chanz 1chao 2char. 1chara 3chard 3charta cha2sc chasi1 1chato 2chatt 2chatu ch5austr chau3t ch1äh ch1ärm ch1äs 1châ 2chb 6chc 2chd che3b4 ch3e4ben ch3echt ch1edi che2el 1chef 3chef. che4fer 3chefs 2chei ch1eim 4chelem che4ler 1chemi 3chemik 2chemp che4neb che4nid che2no 4chents 4chentw che2r3a 4ch3erbs 6chergeb 4cherke cher6zie ch3es2s 4ch1e2ta 2ch3e4x 1ché 2chf 2chg 2chh 1chia chi3na 4chind 3chines 2chinf 2chinh 2ch1ins 2ch1int 2ch1inv 1chip. 1chiru 2chiso 2chj 2chk 2chl4 ch2le chle2i ch3lein 4chli ch2lu 4ch2m4 2chn4 chner8ei. ch2neu 2chob cho2f ch1off chof2s ch1oh cho3l2a ch1orc cho4rei ch1ori ch2os ch3öl 2chön 3chör 2chp ch2r4 2chra ch3rad chra3g 2chre chre3s ch3rh 2chrit 3chromo 3chron ch5ros 4chs ch4stal 2cht ch2tru 2chuf 2chuh 2ch1unf 2chunm 2chunt 2chur ch1urs 2chut 2chü 2chv 2chw 1chy 2chz ci1c ci1es c1ind cins2 c1int ci2s1 1ci3t2 c1j 4c2k c4k1a cka2b ck2ad ck2ag cka2m cka4r1 ck1ä ck1ef ck1eh ck1ei cke4na cke2ra ck2ere ck3er4hö ckerk4 cker6lau ck2ern cke2ro ck1err ck2et cket2t ck1i2d ck1in ck4is ck3l ck5n ck3o4 ck3ö2 ck3r cks2al ck4spen ck3te ck3t2i ck1uh ck1um ck1up c2l2 cle4a clet2 clin2g cli2p1 clip3a clo1c clo3f 1clu clu4b c2m2 c3me c3mu 1co co1ch 3co2d2 co4de. co3di cof3f2 coi4 co1it co2ke co3la1 co2leu co3l2o com4te. comtes4 con2ne co2o coo1p co1p co1ra cor2da co4re cor3t cos4 co2te cou3si 2cp c1q 1c2r2 cra4s c3rä c4re2 2cree cre4me 2cri cros4 2cry 2c1s2 cs4f c4si cst2 4c1t cti2 cti4o2 ction5 ctur6 1c4u 2cua cu2e cu2p3 cup1e cussi4 c1w 2cx 3cy c1z 3da. da1a 2d1ab d3a2bak d2abä d2abe d3a2ben d3a2bi da3blu d3a2bo dab4ra da2bri da3brie d2ab4rü d1ac dach3a da2cho 4d3achse 2d1ad da2de da2do da2d4r d1af 2daff da1f4l dafo4n d1ag dagi4o dag2o da1h dah3l dail5 da1in 2d1air da1is da2kro dal2a 2d1a2lar dal3b2 4d1all da2lop da3lö 2d1alp d1al3t2 2dalte da1lü 3dam da2mei d1amma 4d1ammä damo3 d2amp damp7f8erf 4d1amt 3d2an. d1ana da2nan da4n4at 2danb dan4ce. d1and2 2danda d2andy 3dane 4d3anei 2danf d1ang 2danh dan2kl dan2k1o dan2kr 2danl d1ann 2danna d1a2no 2d1ans 2dantw 2danw d1anz d2anz. 2danzi 2danzü 2d1ap d2apa d2aph da2po da3pos 4dapp d3apte 2daq da4r1a dara4s 2darb2 2d3arc dar2d1e dare2 daren1 dar3g dark2a 3darl dar2m1a dar2m1i dar4mu da2r3o 3dars4 2d1art dar2th dar2tr da2ru d1arz das2 da3sh d1asp das3s dat2e2 da3tei 4d3a2tel date4n da2th 2d3atl 4datm d3ato dat2st 2d3atta 3daub 2daud dau3e2 dauer3e daue6rei 2d3au2f 2d3aug 2dauk da3unt 2d1aus dau4ss dau2ß 3daw d1ax 3däc 2d1äg 2d1äh 2d1ämt dän3a 2d1änd 2d1äp 2däq 2därz 2d1ä2u dä3us 2däx 4d1b4 dbau2c dbauch3 dbe2e dbu2c dbu3s 2dc d3ch 4d1d2 d3da d3dä d3de d3dh d5do 1de dea2d de3ar de3a2t deb4 3debü de1ch deco3 de2del de2dit 2de3e4 def4a de2fa. 2d1eff def4l deg2 degene7 de3gl deh2a dehe2 3dehn de3ho 2d1ehr d1ei 3d2eic de3i4den de3il 3d2eim 4deime dein2d de3inse de3inst dein6sta dein6sti 4d3einw de3io 2deise d4e1ism dei2sp 2dekz de2l1ac del4ade de3lak de4l3aug del3änd del3b2 del3d del1ec 3de3leg delei4g 2delek 2delem de2len deler2 deler4r 2delf. 2delfm 3delik della3d del4lan del4lar dell3au del2l1ä dell3eb del4lei del4ler del2lö2 de2l1ob de2lop del2se del2so del2s1p del3t dem2ar 2d1emb dement4 de6mentg dem5ents de3min 2d1emot 2d1emp d2emu d4en. den2am de2n1e2d de4n3end de2nep 4denerg de3n2es 4d3en4ge. de2ni denk3li deno2s deno4st dens4am den6s5cho dense2 4den4sem den6sere den6s5tau 2dentd den3te 2dentf 2dentg den3th 2dentn 2dentw 2dentz den6zers de2ob 2deol dep4l 2depoc d4er. der3af de2rak dera2n de3rand de2r3ap de1r2as de4r3asi der2bl 4d1erbs 2derdb de2r1e2b de4reck de3reie de4r3ei4s 5d4erem d4eren de4r3end 5d4erer der4erf derer3n der3ero derer4t 5d4eres de2r3eu derf4 d4erfl d3erheb d2erhü de2r3id derin4f de6rinnu derin8teg der3k2 4derklä d4erlan d2erm de1ro derö4 der3r derst2 der3sta dert7ende. derter6e dert4ra 6dertrag der8trage 3de3ru de4ruh de4rum 2d1erz. 2d1erzv d2es. de2sa de4s1ag des1ah de4s1am des3an de2s1än de2seb de4s1e2h de2sei de4s3eil 2d1esel des3elt de3sem de3s4end desen3e de3sens des3erm de2s1et de2s1in 3desk des1o de2sor de2s1p de3spe dess2 des3se des5st de6st5alt de6stant de8steige de8steins des4tex de4stit de6st5rat de4stre de2su des1un 3desw de3ta deten4t 2d1e2th 2d1etw 2d1eul deum3 de1un de1url de3us 2d1e2vid devil2 de1x2a de2xer de2xis 2dexpe 2dexpo 2d1f6 2d1g2 dga4s3tr d2ge. dger2 dge3s d2gesh dge2t3a dge4t1e 2d1h2 4dho d3hu 1di di4ap di2a3s diat4 di4ath 3dic di1ce di3chl dicht6er dick3el 4d3i2co 3dida d1ide 2didee di2den 2didy di2e di3e4d di3enb di3end die4neb diener6l di3e2ni dienst5r die2p di3ers. dies3c di3e4th 3dif 3dig dig4n dik2a dil2s1 2d1imb 2dimp din4a 2d1ind di3n2e 2d1inf 3ding 2d1inh di3ni 2d1inj 2d1ink 2d1ins 2d3int 2d1inv di2o3b dion3in dion5s2 di3ora dios2 di2osk di1p2 di3pt d1i2ra di4re. di2ren di2rin di2ris 2d1irl 2d1irr di4s1a2 2d1iso di2sp di3s4per 2d1isr dist2 di2s1to di4s3tra di4sz di2ta dite1c di4t3erl di4t3erm di4t3ers di2tin di2tob di2t3r dit3s di2t1u di5v2 diz2 2d1j d2jar 2d1k4 4d1l2 dla3g dlap4 d3le dle2ra dli4f dl3m dl3s 2d3m2 4d3n2 dni2 dnis1 dni3v do5at 2d1ob 3d2oba do1chi d1of do2fe 2d1oh do3ha doll2 dol3la d3oly 3dom do2mal do2mar domen1 do3mi do4ming 4domn do2mu do3n2a do5nan doni1 4dony 2d1ope 2d1opf do1r4a 2d1orc 2d1ord dor2f1a dor2fä dor2f1i dor2fl dor2fo dor2fr dor2f3u 2d1org d2orn 2dort dor4ter dor2tr d2os. do3se dos2k 2dosm dost1 dost3a dosten4 do3ta do2tof do3un dow2s d2o3x2 d1ö dö2d dö2f döl3 dölla3 d2ön 3d2ör dö2s1c 2d3p2 dpass3 dpol4n dpo4st1 2d1q d2r4 3d4ra. 3d4rab 4d3rad 2drahm 2d3rak 3d4ral d3ramp d3rand dran3k dra4s3s 2d3rast dra4tin 2draub 2d3rauc d4rauf 2draum 2draup 2dräd d4räh 2d3rät 2d3räu 4dre. 2d3rea d4rea. d4reas 3d4reck 2d3ref 4dreg 3d4reh dre2ha 2d3reic 3d4reie drei3s d4reiv d4rej 4drem 4d3ren d4reo 4d3rep 4d3rer 4dres. d4resc dres6sei dres6sel d4rew 2drez 2d3rh d3ri 3d4ri. d4ria d4rib 4d5ric d4rid d4rie d5rieg 3drif 4driff d4rift d4rik d4ril d4rin. 4d5rind 2drip d4risc 2drisi 2driss 2driß d4rit 2d5ritu d4rix 2d3rob d3rod 2drogg 2drohr 3d4rohu 2d3roll 2d3rose d4ross 2d3rost 2d3rot 2d3rou 2d3rov d3row drö2sc d5rub 3d4ruc 2d3rud 2d3ruh 2d5rut drü1b 3d4rüs 2d1s 4ds. ds3ab d2sad ds1al d2salk d2sall d4s1amt d2san ds3ane ds3assi dsau2 d2saut ds1än ds2äu 4dsb d4schef d4schin d3s2co d2scr d2s1e2b dse2e d2s1ef ds1ehr ds4eign d2sein d2s1emb dsen3er d2s1eng d2s1ent d2s1erf d2serh d2s1erk d2s1erl ds1err d2s1ers d2s1ert d2serz dse2t d2s1eta d2s1ev d2sex d3sha2 ds2hak d4shal d3sho d4shor d2sid d2s1im d3s2inf d3s2kal d3s2kel 4dsl d4sli d3soh d2sop dso2r ds1ori d2sö ds1pa4s3 d2s1pat d2spä d2s1pec ds2pen d4speri d2s3ph d3s2pi ds2por d6sporto d3spri d2spro ds2pu dss2 dst2 d4stabe d2stas ds3tauf d4s3täti d4stea d4stele ds2til d2s1tis d4stoch d2stod dstras4 d4stren d3s2tro dsu2m d2sun ds2zen 2d1t dta2be d3t2ac dtach3 dta2d d3t2ag dta2n dt3ane d3t2as dt2ax d3tea dte3mo dt2et d2th d4thei d3to2 d4tob dt2op d3tö dt3r dtran2 dt1s dt3sa dt5st dtt4 dt2un d3t2ur d3ty 1du du1alv du1ar du2b3li du1ce duel3la du2f 2d1ufe duf4ter duf2to duf2tr 2d1uh du1i du2in du2kr dul3art 2d1umb 2dumd 2d1u2m1e 2dumf 2dumg 4d3umk 2duml d2ump 2dumr 2d1ums d2ums. 2d1umv du2n 2d3und 2d1unf 2dungl 2d1uni dun3ke dun2kl 2dunr 2dunsi dun4st3r 2dunt 2dunw 2d3unz du1os dup4 dur2c durch3 2d1urk 2d1url 2d1urn 2d1ursa 2d1urt du4schn du4schr du4sch3w dus2t 1dü 2düb d3über 2d1v2 2d1w dwa2 dwa4r dwer3te dwe2s dwe4st1 1dy dy2l1 dym3 3dyn dy2s1 4d3z2 2e1a ea2be ea2b3l ea4br eadli4 e3a2dr ea2g ea3ga2 ea3g4l eakt2 e2akta e3akto ea2la e3alei e4alem ea4l3ent ealen4z ealer2 e3a4lerg e3alex e3a2lin eal5le eal3lö eallö3s eal1o ea2lon ea2lop e2alti2 eal3tr ea2l3u2 eam3a e2ame eam1o eams2 eam3t2 ea4na ean3a2r e3anf e2ano e3ar. ea2ra ea3rat e2are e4are. ea2r1ei ea4rene e4arer e4ares ea2ro e3arz e3a2sc e3asf easin4 ea2sp eas5s eate2 ea3te. ea3ten eater1 eat4mes eat2mu eat4mun eat3s e3at3t4 eatu2 e3aue e3auf eau2fe eau4fl e4aufo eau3n eaus3s e2av e2az e3ä4 e1b 2eba e3bak eba2p e3bän 2ebec ebe1er ebein7h eb2el ebe4ler ebe2lo ebenen3 e3ber ebe4ras ebert4 ebese2 ebe4s3eh ebe2so 2ebet ebet4s 2ebh 2ebi 2ebl eb2laß e3blä eb3le. eb3ler eb4leu e3blie eb3lo eb2lö 2ebo e2bob ebö2s 2ebr e5brau eb4rea eb2s eb6sche ebse2 ebs1in ebs1o ebs1p ebs7panne ebs3tau eb4stät ebs3t2h ebs1ti eb4stot eb3str eb4sz 2ebu e2bunt ebus3s ebu2t3 2eca 2e1ce ech1am ech1ä 2e1che ech1ei ech2en1 e6ch5erzi e1chi ech3l ech3m ech3n e2cho. ech3ö2 ech3r ech4ri echs4er echst5re ech3tab ech3t4ei ech6terh echter8ha e1chu ech1w 2echz e1ci eci2a ec4k ecke4n1 eck3ser eck4sta 2eckt 3eckty 2e1cl 2eco 2e3cr 2ect e1d ed2a ed2dr ed4e ede2al ede3n4er eden4sa eden4s3e eden4s3p edeo2 ede2r eder3a ede3rat ederer4 edert2 ed2i e3di. 2edip edma3 edmas2 e3d2o ed2ö e3drei ed2sal ed4seh ed2s1es ed2si ed2s1o ed2s1p ed2sto ed2s1tr ed2s1u edun3 edund2 e3dy3 edys2 2ee ee3a4 eeb2l ee1c ee2ce ee2cho e1eck eed3s2 ee1e2 e1eff eef4l eeg4 e1ei ee2i3e eein4se eei4sc eei3se eeis3s e2ela eel2e e3e2lek eele4n eel2ö e2e3m2a eemas3s e1emb ee3min e1emp e1en eena2g e2enä e2enc een1e e3eng ee3ni e3enk e3enl e2eno een3s een2z ee3o e2ep ee3po eer4at e1erbt e1erd ee3re2 eer1ei ee4r3en4g eer2e4s1 eer3eti e1ermä ee1ro ee1rö e1eröf eer2ös ee3r2un e1erz ee3sh ee3sp ees2t e2et. ee3t2a ee4tat ee2th eet2i ee3t4r ee2tu ee1u2 eewa4r eeweis4 e1e2x e1f e2f1ad e3fah ef1ana ef1ar e2farc ef3arm e2fat 2efä ef2äl efä5sse e2fäu 2efe e2f1e2b e3fef efe4l3ei ef1em e2femi efe2n1 3e2f1ene e2fent efer5f eferin6d efer5r efeuil4 ef2fä2 3effek 1effi ef2fl ef3flu 2efi ef1id e2f1ins efi2s 2efl ef4le e3f4lu e3flü 2e3f2o 2efr ef4reih ef3rol ef3rom ef4ru ef4rü efs2 ef3sc ef3so ef3sp ef2tan ef2tei ef2tro 2efu e2fum e1g ega2m e3g2anz egd4 e3ge egein3 ege4lan ege4l3au ege8l7ei8er ege4ler ege2lo eg2en ege4n1a ege6nero ege2ra ege5stal ege4s3to ege4s3tr ege1u 2egi e3gio 2egl e2glo e2glu e2gn eg3nä eg3ni ego1p egro5sse eg4sal egsau3g eg3se eg4sei egs2e3l eg3si egs2of egs2pe egst2 eg4sto eg2th 2e1ha eh1ach eh1ad eh2ade e3h2ah eh2al ehalt4s e3hand e2harz e3haut e1hä ehäs3 e1he eh1eff eh1ein eh1elt e4hense e4h3ente ehen4tr ehe3o 1e2hep 2eher ehe1ra e2h1er2f e2h1er2l 2e1hi eh3im ehis4 ehl1a eh1lam eh2l3au eh1lä ehl3ein eh4lent eh5l2er ehlo2 ehl1or eh2lö ehl2se 2ehm eh2mab eh4mant eh3mu eh3na eh3no 2e1ho eho2f eho2l eh3oly 2e3hö ehö4rer eh2r1a4 ehr1ä ehr1ec eh2rei eh2rel ehr6erle ehr4ern ehre3s eh4rin eh1roc ehr1of eh1rö eh2s2 eh3sa eh3se eh3sh eh3si eh3so eh3sp ehst2 eh3sta eh3sto eh3str 2eh3t2 eht3h eht4r 2e1hu e2hum eh1unf e2huni e3hur e1hü eh3üb eh1w e1hy 2ei3a2 eia4t ei2bar ei2bli ei4blu eibu2t ei4b3ute e4ic ei1ce ei2cho e2id ei2d1a ei3de ei4deis eid5erre 2eidn ei3do ei3dr ei1e eie2b eie2d ei3e2l eie2m 4ei3e2n1 eienge4 ei3e4s eie2t 4eif. ei1flo 1eifr eif3t 2eig. 2eiga eig2ar 2eigä 2eige. 2eigeb 2eigeh 4eigeno 5eigensc 4eig2er 2eiges 2eigew 2eigi 1ei2g3n ei2go ei4g3rat 2eigre 2eigrö 2eigru 2eigrü 2eigs 2eigt 2eigu 4eih ei2hum ei2kab ei2kak eik4am eik2ar eik2i eik2l ei3k4la ei3klä eik2o e2il 2eil. ei4l3ab ei2lam eila2n ei4l3ane ei4lang ei4l3anz ei2lar 2eilb eil3d4 ei4lein eile2n1 ei2let eil3f4 eilm2 ei2lob eil2ö 2eim. ei2mab ei2m1ag eim3all eim3alp eima4to ei2m1or 2eimö 2eimp eim2p4l eim3sa ei2mur e4i2n1a ei4na2d ei4nae ei4n3an ei4na4s ei4n3at ei2n3ä ein3d2e ein6derk e1indu 2eineb einen4e ei4n3en4g ei6nen6se ein5erbe ei4nerf ei4nerk ein5er6la einer6sc ei2neu ein4fiz 5einflus 5einfluß 2einfo ein4fo. ein4fos ein3g2 3einger e2ingr e2inhä ei2nie e1init ein3k4 ein6karn 3einkä e2inl ein3n2 ei2n1o4 1einri e6insa einsas6s einsa7sse 3einsat e2insc 5einschä ein6stal ein6terv 3eintö 3einträ 1einu ei3o eio2p eio2s ei1p eip2f 2eir eir2c ei3re e1irr e4is. ei2sa ei3sas ei6schwu e4ise ei4ser4g ei4s3er4l ei6s5erst ei4s3erw 1eisho ei3s2ky ei2so eis2pe e2i3s2s eisser6s 4eisto eistra6s ei2sum ei2sur 1eiswo e2it ei2t1a2b ei2tal ei2t1an ei2tap ei2tar ei4tat 2eitä ei2tän ei3tei eite4ra ei2t1h ei2tin eito2 ei4trau ei2tro eit4sa4g eit3t4 ei2t1um ei2t1ur eit3z2 eiv2 eive4 ei2zar ei2z1in 2e3j e1k 2ek. 2e3k2a 1ekd ek2e e3ke. e3ke4n e3kes e3key e3k2l ek4lo ek4n e3k2o ekor4da e3kr ek4s1p 2ekt ek5t6ante ekt3at ek2t1ä ek2te2l ekt3erf ekt3erk ek4t3er4z ekt2o ek2t3o4b 2e3ku ekur2a e3k2w 1ekz e1la el2abt el3abu el3ader el1af ela4h e2l1ak e2l1a2m el2a3mi e3lamp el1ana e4landa e2lanm e4lans e2l1ant e4lanw el1anz 2elao e2l1ap e2l1ar el3a2ri el1a4si el1asp el3aufw 2e1lä e3läd 2elbil 2elbr 2eld elda2r eld3ari eld4arm el4d3erf eld3erl elder4p elder4s eld5erst el3des elds2 4e3le. 2e3lea elea2r 2e3leb 4ele2c el1ech 1elefa 4eleh el3ehe. 2elei e6l5ei6ern e2l1ein e3leine e5leit 1elek 2eleko e2l1el 1e2lem 2e3lem. e3lema ele2mi e3lemm 2el1emp 2e3len. elen4k3l e4lense e2l1ent e3lep 2eler e3ler. eler2a el1erd e6lereig el1erf e4ler4fa e4lerfi e2lerg el1erh el1erk e2l1erl e4l3ernä eler2ö e2l1err el3eru el1erw e2l1ess e2l1e2ta ele2ti elet4ta 2el1ex e3lex. 1elf. elf2er 1elfm elf4r 1elft elgi5er. elgi5ers el3g2l elg4r e2l1id 2e3lie elif3 2elig e2lim elin3a eli3no el1ins 2elk elks2 ella5den el2lap el4larb ellar4t ella2s el3le. ell2ei ell3ein el4lel ellenen5 ell2er eller8fas eller7g ell3erh el3lie el2lil 1ellip el2lo2g el2lor el2lot ell2ö ell3sp ellu2m el2lü el3m2a elm2e elm3ein 2eln el3na 2elo e2l3oa e2lof e2lol e2lom e2lonk el1opf el1or elo2ri e3lot e3l2ov 2elö el3p4 el4s5ein el3sent el2sum el4tans el3te. elte4m el5ten. el4t3ent elter4b elter4f elt3erh elter6le 3elter4n elt5ero elter6sc elt3eth el3the elt1r elt3se 2e1lu el1uf e2l1um e2l3u2r el3use elu2t el3uto e1lü 2ely e2lya el3z2ac el2zar el4zene elz1in el2zwa 2elzy e1m e2m3a2b e2m1alk em3anf e2m1ano e2m1ans 1emanz e4m3a2sp emas2s ema3sse e3maß em1au 2e3mä em2äh 1emba 1embo 1embry em2dä emd1r em2dra 2eme e2m1e2b e2mef eme2i e2mele em2en emen6gel emen4t3h eme3r2i e2m1er2l em1erw 3e2meti e2m1i2d emi2ei e2mig emik2 em1im 2emin emi3n2a e3mind em1int 1e2mir e3misc emma3u em2mec e2moa e3mol emo3s 1empf4 em3pfl em3po em2sa em4scha em2sim em2spr ems1tr em3t2 1e2mul 3emuls emune7 e3mur e3mus 2emü emü3s2 e2na 4ena. e4na2b en3aba en3abo 4enac e4n3ack enadi4 e4naf 4enah en3ak en1al enal2a e4nalb e3nale en2alg ena3l2i e4nalk e4nalm e4nalo enal3p 4en1am ena4n e4nand en3ane e4nant e4nanz en1ap ena2pa en3are en3ark en3aro en1as ena2sc e4na4st 2enat 4e5nati e4natl enat4s e4n3att 4enatu e4nau2f en3aug e4n3aur e6nausta e4naut en1a2x en1a4z en1ä en3äb e3näi e2när en2ä3s en3äst enbu4s3 en2ce. end2ac en2dal en4dang 2endel ende4lä endermas8 en4d3es4s en2dex en2did en3d4ort end3rom end3s2l end3s2p end3sz en3d2um en3d2ü 2ene. en3e4ben en1ec e2neff ene2h en2eid e3neien e4neige 4eneigu e4nein e4neis e2n1el ene4le 2ene2m e2n1emi 2enen e4nense e4n1ent en4entr en3envi en1ep 4e3ner. en2era e2n1erd en3erei e2nerf en4erfr 1energ e2nerh e2nerk e2n1erl e4nermi e4n3ermo 4enern e4n3erne ene2ro e2n1err en1ers 4eners. e2n1ert en4ert. e2n3eru e2n1erw 2enes e3nes. e2n1e2sc e2n1esk e2n1ess en1eta e2n1eth en1eul e2n1e2v e4ne2x en3f enft2 enf2u 1engad 1engag en3g2al enge3r4a en3g2i en3gn en3g2o 1engp eng4ra eng1s2 eng3se 2eni e3ni. e3nic 4e3nie eni3er. eni3erp eni5ers. en3i2ko en3ill eni4m en1ima en1imi e2n1in e3nio eni2ö e2nir eni4sa e4n3iso e3nit2 e3niv enk3aus 3enkeli enk3erg en4k3erk en3k2ü en2nef en2nel en4ner4f enn3erg en4n3erl enn2i enni6ger 2enniv e2n3oa e2n1ob e3nobel eno2br e2nof en3oli en3olm eno2ma eno4n e2n1op e2n1o2r en2ora eno4ri 4enorm e2n1ost 4e3not eno2w 2e1nö en1ö2d en3sabb en2san ensas4s ensa5sse en5sche en2seb 1ensem en4sen3e ens3ere en3spo ens4por ens4tak enst5alt en4s3tät ens4tel en6stele en6s5test 2ensto enst2ü en2sun en3t2ag 2entan en4tanm en4tanw en3t4ark 1entd en3t2el ente2n 3entera en4terb en3tes 1entf 2entfo 1entg 3entgeg en2thi 1enthu 1enthü en2t1id 3entla 1entn en2tob entopf3 en2t1os 2entö en4t3rol 1entsc 1entso ent4sto 1entw 4entwet 3entwic 1entz en1u e2nuf e2num enu4r 2enu2t e4nuto e1nü 4enwü 2e1ny en3zare enz2äp 1enzep enz3erg en4z3erk en4zerl en4z3erm enz5ersc enzi2d enzlan4 enzo2l 1enzy e1ñ 4eo e1o2b1 eo3ben eo3bl eo3bo eo3br eo1c eoch2 eo3dr e1of eo3g2 e1oh eo3la e3o2ly e1on e3o2nat eo1o e1ope e1opf eop4r e1or e3or. eo1ra e3orb eorgi1 e3ors eort4 e3orw eos2 e3os. eo3se e1o4ste e1ou2 eo1ul e1ö2 e1p 2ep2a epa2g epas6ser 2eper e3p2f4 e5pfi eph2 1e2pid e2pig e2pik 1e2pile e3pio 1epis 2epist 1e2pit ep3le 1epoc eport4 1e2pos. ep2pa eppe3l ep2pin ep2pl ep2pr 2epr ep3sh ep2tal ept2an ep2tau 2e3pu epu2s 2e3q er1a e3ra. era2be era3ber era2c e2rach e3rad. e3radi e2radj e2r3adm e4radmi e4r3adr eraf4a era2g e1rah e1rai er3aic e3rake e1rald eral4eb er3alke e2r3all era4mat er2an. era4n4a eran3d4 e3rand. e4rangr e2ranh e2rano e1rap er3apa er3apf e2rar er3are e3rari e3ras. era2si era4sie era2sp era4s3s e1rast era2ß e4ratel e1raub e1rauc er3aue erau2f er3aug e2ra2v e1raw e2r3ax e1raz e1rä er1äf er1äh er1ä2m er1äp e2r1ä4s er1ätz 3erbarm erb2au erb2e 2erbru erb2sp er1c er3chl erch2o erd4am erda3me 1erdb 2erdec 2erdel er4d3en4g erd3erw erdeu2 1erdg 2erdy 4ere. er3e4ben e3r2ech er3echs er1eck er1edi ere4dit er1eff e2r1e2h ere4i 4e3rei. e3reib er1eig 4ereih e3reik e4r3eime e4reink er3eis. er5eisar er3eisb er3eisf er3eisr erei5str e4rek er1e2l e2rele ere3lev 2erem 4erem. er1emi ere4mis e2remp 2eren 4e3ren. e3rena eren1e e4rense e4rentn e4rents e3renz eren8z7en8d er1epe 4erer. 2ererb e4r3erfo e2rerh e2rerk e2rer2l erer5lau 4erern. e4rerne e2rer2o erer4ri er1ers 4erers. e8rersche e2rert 2ererv 2ererw 2eres 4eres. er1ess eres3sk er1eß er1eta er1eu ere4vid erf2e 4erform erf4r 4erfür er4g3are 4ergebi 3ergebn 4ergebü 4ergeha 4ergehä erg5elst 4ergeni 2ergn er2gop 4ergrem erg1s2o ergs2p e4rh 1erhab er3hag 2erhai 4erhals 2erham 2erhan 2erhas er3hei 2erher er3hu 2eri e2riat e3rib 4e3ric e4r3ico er1id 4e3rie eri3en1 erien7s e3ri3k erik4l 4e3rin. e2r1ind e2r1ini er1ink er1inl er1int er1inz e2ri2on 4eris e2riso e2risr er1ita 3eritr e3riv 2erk. 2erkaj er3ker 1erklä 2erkm 2erkre erk3t4 er2kum 2erl. 2erlag 3erlebn 4erleh 2erln er3m2 ermen4s er4m3ers er4n3alt er3ne er4nene er4nerf er4nerk 3erneue er2nob erno2r ern1os 2e1ro. e1roa er1ob ero2bl ero2br e2r1o2f e1rog e1roh e1rok e1rol er3oly e1rom er3omb 2e3ron e2r1oo er1op 2e4ro4r eror2a e1ros 1erosi e3rosit e1rou e1row er1o2x er1oz erö2d 2eröh erö4l er1ö2s er3p er4rade er3rä 2erren er3ro 2errü er3s2a ers4ana ersch4 er5schn 4ersei ers2el er5s2i er3sk ersma3s4 4ersted er6st5ers 4erstil er3swi er3sz er2t1ab er3tat er4t3erf er4t3er4g er4ter4h er4ter4k er4ters ert1h er2tho 4ertö 4ertru ert3s2e ert1s2p 2eru eruf4s e4r3uhr er1u2m1 er1und e4rundu er1up. er3ur er3use e2r3uz erü4b 3erweck er4zerk er4z3ers e1s es3ab es2abb e4sabe e3sac esa2d e3saf e4sall es1ami es2an es4and es3anf es3ant esa2ra e3sa1s2 esa3ss esa5sse esa2v es1ax esäs4 es2äu 2esb esbi5er. e3s2ce es2chi esch2l esch2n e4sco e3se. es1ebe e2s1ec es1ehr esein4s es2el ese4nal ese4neu e3senk esen3o esen3sk esen3th eser4at ese4r1u2 eses2k es3e2x 2esf 2esh es3ha es4ham es4har es3he 2esi esi1er e4s3i2k e2s1il e4s3ins e4siso es2kat e4s3ke e4s3kl e4s3ky e4s3l 2esm e4sn e2s3oa e4sob e2s1od es2oh es2opa eso2r es1ora eso3re es2ort e3sot e3s2ö 4esp e3spal es4park es2pek e4spers e4sph e3s2pi e3s2por e3s2pu 2esr 2ess. es4s1ag essali3 essau4s 1essay 2essä 2essc e4ssel e4ssent ess6ere ess4erf e4ss3erg es4serh e4sserl ess5er6la 2essk 2esso es2sof 2essp es2s1pa es2spu es4stab es4ste estab4b e4stabs esta3ge est1ak es2tan est4ap e4starb es2t1a4s e3stat es2tau e4staum es2te. este2c este4i est5eing e6st5eink e6st5einl este2l e4stele e4st3emi e4st3eng est5entr est5erha e4ster4ö e4st3erz estes2 e4st3ess e3sti e4stid e4stip estmo6de 1estn e2stod e4strad es3trak e5strec e5strick es2tu est3ums e3s2tü e3s2ty e3suh e2s1um es1ur esu4s 2e4sw e3sy e2ß1el e2ßent eße3re e2ß1erg e2ß1erl e1t e3ta. etab4 et2a2c 2e3taf 2etal etalla4 etal6lag etal6li6n et1ami e3t4an. et4at etat3r et1äh 2e3te ete2e e4t1ef e4t1ein ete3ke eten3d2 ete2o eter4hö ete1ro eter4tr ete4sp 2eth. et2ha e4t3hal e3the et2hi e4thik 3ethn et2hu e4t1i2d eti2m etin1 et1ini et2it eti2ta eti2th 2e3to e2tob e4t1o2f et4on eto4n3al etons4 e4torg 2etr et3rad e4traum et3rec e2t3res et4ros ets2c etscher7e etsch3w ets1p et1su ett1a et2ta2b et2tad et2tak ett2as et2tau et2tä et2tei ette4n1 et4th et2tö4 et2t3r et2t1um et2tur et2tü4 3e2tui e3tur etwa4r 1e2tym 2etz etze4s et2zw eu1a2 eu3b4 2euc euch4ta 2eud eudi4e 2eue eu2eb eue6r5eif eue6reis eueren4 euerer6s euerer6t eu3eri eu3erk eu3err eue3s eu2e5sc 4euf eu2fer eu2g1a euge4mi eu6gense eu3g2er eugin2 eugin4f eu4gin4g eu2gre eu2gri eug1s2 eu3h eu1id eu1in1 e4uk 1eukal eu2kä eulan2 euland3 eu3l2e eul2i 2e1um e3um. eu3m4a euma3s2 e3umb e3umf e3uml e3um2s eums1p eum3st e3umw 2eun eu2na eun2e eu4nei e3un2g eu2nio eu4nis eunk2 eun3ka eu1o2 eu1p e1up. eup2f e3upg eu4r1an eu4r3ast eura3t eu2rau eur1c e2ure euren2 eu4rens eur4er eur3f4 1euro 2eu1s4 e3usar eusch4o eu4s5k eu3sp eu3ss eust4 2eut eut2e eu5ted eut2h 3eu3tha eut2i eu3t2o eut6scha eut6schn eut6schr 2eux eu2za eu2zo eu2z1w e3ü e1v e2vak e3var 2ev2e eve5ri evie3le 2e3vor ev2s e1w ewä4 ewä6s e2we. ewei4sc ewert4 ewer3te e3wir ewi2s e3wit 2ex. 1exam ex3at 2exc 2exd e2xel ex1er 2exes e1xi 2exik e2xil e2x1in e3xio 1exis ex3l 1exp 2expu 2exs 2ext. 2ex2ta ex2tin 1extr 2extu 2extv 2exu e2xum 2e1xy ey1l2 ey2n ey3no eys2 e1z e3z2a ez2ä e2z1enn e3zi ezi2s e3z2o ez2w ez3z2 é1b é1c é1g égi2 é1h é1l2 élu2 é1m2 é1n é1o é1p é1r2 é1s é1t é1u2 é1v é1z2 è1c è1m è1r 1ën ë1t ê1p 1fa fab4 2f1ab5b fa2ben 2fabf 2fabg 2f1a2b5l 2fabn f2abr 2f1ab5s 2fabw fa4cheb fa4chel fa2ch1i fa2cho fachs2 fach3sp fa2ci fa2dan fa2del f1ader fa2di fa2dr fa3e fah6l5ent fai3b f1a2ka fa2ke f3aktio f4akto 3f2aku fa3la fa3le fal2kl falla4g fal4lei fal6lenk fall5ent fal6lerk faller6s falli4 fal6lini fal4lis fal6scha fal6schl fal6schm fal3te fal4tei fal2tr 3fam fa2mei f1amp f1amt 3f2an. fa2nar fand2a f2anf fan2ga fan2gr 2f1an3k 2fanl 4fann f1anp 2fanr 2fanw 2f1an3z 2f1a2p f2ar far2b1a far4bel far4b3er far4bin farb3l far2bo far2b3r far2b3u f3arc 3fa5ri far2r1a farre2 far4rec far4reg 2f3art 2f3arz 3fas. fa3s4a fa3sh f1assi fas2t 2f1a4str fa2ß f1aße f3at f4at. fa2to f4ats 2f1auf f3aug fau2s f1ausb faust3r 3f4av fa2xa 1fä 3fä1c fäh4rin fäh2ru f1älte 2fäq 3färb 2f1ärm 2färz fä4s fä6sser4 3fäßc fä2ßer 2f1ätz 2fäug 2fäx 4f1b4 fbau1 fber2 2f1c f3ch 2f3d4 fdien4e 1fe 3fe. featu4 f2ech fe2del fe2dr fe2e1i feein5 fe1em 2f1e2he fehle2 feh4lei f2eie f2eind 2f1eing fe3ini fe3ins. 2f1einw f1eis fek4tin fe2l3a2 fe2l1ä fel2da felde4m feld6erh fel2dr feld5ri 2fe2lek 2felem fe2l1er fe2les fel3la fel4lan fel2lä fe2l1o fel4s3oh 6fel6tern felt4r fel3tu f2em. 2femb fem4m 2femp fen3a fe2nä fend2a 4fenerg fe2ni fe2no fen3s2a fen5s2c fenst2 fen6stri f1ent fen3t2a 2f3entf f2enti 4fentla f2ento 2f3entw 4f3entz fe2nu 3fep fe2pi f2er. fe1ra fe2rab fer3a2d fe2ral fe4rang fer4ant fe4ranz fe2rau fe2r1ä 2ferd. fer3da fer3d2e3 f2ere fe2r1e2b fe2rec 3fer2ei 4f3ereig fer3eis f4erel fer3ell fe4rer4g fer4fah fer4fol ferg4 f4ergr feri2d ferie4n3 feri4on 4fer4leb f2ern. fer4nei fe2rö f4erpa f4erpf f4erpl f4erra fer4reg ferri2 f2ers. f2ert fert4r f2erz fess2e fes4t fe2sta fest3a4b fest3an fe4st3ei fe4stin fe2st1o fe2st3r 2f1e2ta 3fete fe2th fet4t3a fetti3s 2feu. feuer3ö 3few 2f1ex fe1y2 3fez 1fé 4f1f f3fa. ffa2b ffa2ce ff1a2d f3fak f3fal ff1alt ff1ans ff3ar ff4arb ffa4s ffa2t ff1au ffa4z f2f1e2b ffe2e f2f1ef f2f1ei ffe3in. f5fek ffel3l ff1e2m f2femi ff2en ff3erle f2fetz fff4 ffi3k f2fil f2fim ffi4xi ff1lag ff3le ff3li f3flü ffo2 ff1ori ff1ox f2fö f3f4rä ff3ro ffs2am ff3sch ff2s1p ffs4tau ffs3tie ffs3tut ff3stü ff3t2 ffus3s f2fy 4f3g2 fgeb2 fge3s2 fglim2 4f3h2 1fi 3fi. fi4ak fi2ar fi3at fiden2 fi2do f2ie fi2e1i fi1er2f fi2gr fi2k1as fi2kel fi2kin fi2kn fi2k1o4 fi4k3r f2il fi2l3an fil3d fi2les fil2et filg4 fi3li fi4lin fil2ip fil2ma fil2mä fil4med fil4mei fi2lo 2fimp 3f2in2a fin2e 2f1inf fing2 fings2 fi3ni f2ink fin2sp 2f1int fi2o fi3ol fi2r fi3ra fi4re fir3me fi3s4a fi4sch3a fi6schei fisch3l fisch3o fi4schr fi4sch3w fi3s2h 2f1iso fis2p fite2 fi2tin fit1o2 fi2tor five4 fi2xel fi2za 2f1j 3f2jo 4f1k4 fka4t3 f2l2 2fl. f3lad f5land f4lans f3lap f4lasc f3lats flauma4 1flä 3f4läc 4f3läd 2fläh 2f3län 2flär 2fläß 2f3läu f5le. 2f3leb f4lee 2f5lein flek3 flekt2 f3ler f4lex f3li. 3f4lim f3lind fli4ne f3ling 2f3lins 2f5lon 1f4lop flo7s8ses. 1f4loß 1f4lot flo2w f3lö 4flöf 3f4luc f3luf 1f4lug 1f4luss 1fluß f4lut flut1o f4lü f5lüd f5lüm 4f3m2 fma5che fma2d fmas2s fma3sse 4f3n2 fni2s 1fo f1ob fo2be 2fober fob2l 2f1o2f foli3 fo2na fo4nan fon3au fon3dr fo4n3in fo2nop fons2 fo2nu 2f1op 4f3org for4m3a4g for4mas for4m3ei for4min forni7er. for6schl for4sta for4sti for4t3ei for4ter5 for2t1h for2t3r fort3s2 for3tu for2u fot4r 1fö 2fö2f 2f1ök 4f1öl 4f3p4 2f1q f2r4 f3ra. frach6tr 2f3rad 2f3rah fra4m f3rand f5rap f3rat 1frau. f3rauc 2fräd 1f4rän 2fre. f3rec f3red 2fref f4rei. f3reic f4reie frei1f f4reig frei3k2 2frein 2frek 2f3rep 2frest 3f4reu 2f3ric fricht6e fri3d fri2e 2frig f4ri3k f3rip 1fris f4risc f4rist fri6ster 2f3roc 2frol 1f4ro2n fro4n1a f4rop fro2sc f3rot frös2 f3ru f4ruc f3rü 4f1s f3sac f2s1al f2sa2n fs3ane f4s3ar f2s1a4s fsa2t fs3ate f2saut fs2än f2sca f4sce f4schan f4schef f4schro f2scr f2s1e2b fse2ei f4sehr fse2n fs1en1e f2s1ent f2s1er fse2t f2s1eta f2s1i4d f3s2ky f2s1o2 f3soh f3sol fsp4 f3spann f2s1pas f2sph fs2pie f3s2pl f3s2por f2spre f2spro fs2pul fs3s2 fs2tal f2stas f3s2tat f4s3täti f2stip f2s1tis fst4r f4s3tres fs1trü f4stüte f2s1un f3sy 4f1t f2ta. ft1a2be ft1abl ft1af f3t2ag ft1ala ft1an f2t1ap ft1a2r ft3att f2t1äu f3te. ft1eck ft1edi ft1eh fte2he ft1eig ft1ein ft1eis ft1eli fte3ma ft1emi f2t1ent ft3erfü ft1erk f2t1erl f2t1erz f2t1e2ti f2t1ex f2t1h f4t3hei f2t1id f4tim f2t1in f3t2ing fto2 f2t1of fton1 ft1op f3tor. f2t3ot f3t4ran f2t3res f3treu ft4rit ft3ro ft3ruh fts1 ft2sa2 ft4sag ft4sam ft2sän fts2c ft4sche ft2se2 ft4seh ftsen1 ft2si ft2so fts3tei ft4stem ft4ster ft4stes ft3stie ft6stier ft3stri fttra4 f2tum ft1urk ft1url ftwa4 ftwa6r ft3z2 ftze3d 1fu 3fuc 3fug f2uh fuku3 fulb4 f1um1 fu2mei f2umm fund3er fun6derg fun6derh 2f1unf 2fungl 2f1u2ni fun2kl fun2ko fun2k3r fun2ku 2f1unm 2funr 2funt f2ur furch2 fu4re. 2f3url fus2 fu3sse fus6sen fu4sser fuss1p fuss1t fus4ste fu2ß1er 3fut 1fü 2füb fühl4sc fün2 fü2r fü3s2 2f1v 4f1w f1y 4f1z fz2a fzeiten6 fzei8t7end fz2ö fzu2ga fz2w 3ga. 2gabf 2gabg 2g1a2b3l gab2o g1abr gab4ri 2gabsc g2abt. 2gabtr ga3bu 2gabw 2gabz gade2r ga3d2i gadi4e ga2dr gae2 ga1fl 5gag. ga1k ga2ka ga2ku gal2a ga3laf ga2lar 2g1alau 2g1alb 2g1alg gall4e gal3lo 2g1alp 2g1alta 2g1altd g1a2lu ga2mec ga3mel gam3ma 5g4amo 2g1amt g1a2na 2ganal gan3d4 2ganf 2ganga 4gangeb gan2gr gang4sp gan2g1u 2g1ank 2ganl 2ganmu 3g2ano ga2nob 2ganr gans2 2g1ansi 2ganst 2ganw ga1ny 2g1anz ga3pe 2g1app ga1q 3gar. g2ara 2garc 3g2ard ga3ret ga3r2i 2g3arm ga3r2o 2g1arti ga3ru 2g1arz ga2s g2as. ga4s3al ga4sam gasche4 gase2 ga5se. ga4sei ga4sel ga4s1e4m ga5ses ga4set gas5s2 5g4asse. g3asses 6gassess ga5ssest ga4st3el ga3sti ga4stin gastra4 ga6stras5 gas4t3rä ga3stri ga6strom gas1tu ga3sun ga3t2a 2gatm gat4r gau1c 2g1auf 2g3aug g2auk gau5ne 2g1au4s 2g1aut ga3z 2g1äp gär3th 2gärz gä3s2 gä5st gä4u 2g3b4 gbau5s gber2 gbi2 2g1c 2gd g1da g3d2ad gda3de g2d1ak g2d1an g2d1ar g2d1au g1dä1 g2dei4 gd1els g2dent g2d1er g2d1et g2d1in g1do g2dop g1dö g1dr gd3re gd3ru gd3s2 gdt4 1ge ge3a2 ge4ate geb2a ge3ble geb4lin geb4lo gebot2 3gebü ge1ch ged4 ge1e2 ge3ec ge2es geest3 ge5fa 3gefä 4g1eff gef4l gef4r ge3fu g4eg gege2n1 gegene4 ge3g2l geg4r geher3l ge3ho 2g1eid ge4ie2 ge4ig g2eil ge1in1 ge2inf gein4h 2g1einr gein2s gein2v ge1ir geis4 2g1eise gei3sh geiss3c gei4sta geist3r 2gek. ge4lanz gelb1r gel4b3ra gelb5s gel4den gelder4 gel6derh gel6ders ge3lec ge2lef 2ge2lek 2gelem gelen1 ge4lene gel3ere ge4lerk geler3ö ge4l3ers ge2l1ev gel3f gel1i4m gel3l2a gel3le gell2i gel2ö gel3s2a gels2p gel3sz gel3ta gelt4r gel3z2 gem2 ge4ma. gem6e 4g1emp gem3s ge3mu ge3na ge4n1ac ge4nad ge4nak ge4n3al ge4nam ge4nap ge4nar ge4nat gen4aug 4genda. gend3in3 4g3endmo gen2dr gen3eid gener4f 4generg ge4n3ern gen6erwe gener4z ge2nim gen3k4 genma7sse. gen3n ge2noc gen6semb gen3sk gen3sz gen3tä 2gentf gen3t2h gen3tr 2gentw ge2nun genzma3 genzmas6 gen3zw ge1oo geo2ri g2ep4 ge3pl ge3po ge1ra ge2rab ge2rak ge2r3al ge3rann ge4rant ge4r3a2r ger2as 2gerdg ge3rem ge4rene ge4reng ge4ren4s ge4r3ent ger2er gerin4d gerin4f ger4inn gerin4t 4ger4klä g3erlas germas6s ger5me ger3no 2g1ernt ge1ro ge2rob ge1r2ö ger4sat 4g3er4seh ge3r2u g6es. 3ge3s2c ge6sche. ge2seb 4g3e4sel. ges3elt ge2s1er ge3sha ge3s2i ge3so ges2p ge3spa ges4pi gess2t gest2 gest4a gest6e ge4s3tur get2a g1etap ge2thi ge5trei get1s ge3t4u 2g1e1ul ge3unk ge1urt ge3u2t 4g1e2x 2g3f4 gfi2l 2g1g gga2t g5ge gge2ne gg2l g3gla g3glo g2g3n gg4r 2g1h 4gh. gh2a 3ghale gh2e 3g2het 3g2hie gh1l 3gh2r ghs2 g2hu gh1w gi3alo gia2s gich2 gicht1 gie3g gi2e1i gi2e3l giel2a gie5n2e gi4eno gie3res gies4 gift5s gi2gu gi2kel 2g1ill 3gime gi2me. gi4mes gi2met 2gimp 2gin2d gi3ne 2g1inf 2gin4h 2g1ins gin2sa 2g3int 2gin2v gi2ob 2giok 2g3isel git2a gitt6e gi4us 2g1j 4g3k4 gl2 4gl. 4g1lab 2g1lac 2gladu 2g1lag 2g1lam 2gland gla2s1c glast4 gla4str gla4stu 3g2laub 2g1lauf g1läd 2gländ 3gläs g1läß 2gläuf gl3b g2l4e 2g3le. 3glea 2g3leb g3lec 4g3led g3lee 2g3leg 2gleh g4leic 4g3lein gleiter8s glei4t5r g3len 4glenk 4g3ler glerei4 2gles 3gles. g3lese g2lia 2glib 3g2lid 3g2lie 4g3lieb 2glif g2lik 4glil g2lim 2glin g2lio 2glis g2lit g3lite g2liz g3lize g2loa g2lob g2loc 2g3loch g2lok g2lom g2lop 2glorb 2glos g2lot 2glöch 2glös 2glöw 2gls g1lu 2g3luf 2gluk 2g3lun g2lut 3g2lü g3lüg 2glw 3g2ly 2g1m2 gmen4tr gmi2s g1n 2gn. g2n2a g4na. 2gnac g4nad 2g5nah gn4al gna4l3er3 2gnanl 3g2nä 2gnb 2gnc 2gnd gn2e g3neh 2gn3ent gne2tr 2gnf 2gng 2gnh g2nie g2nif g4nin 2gnint 2gni2s3 gnise2 2gnk 2gnl 2gnm g2no1 3g4non g3not 2gnp 2gnr 2gns 2gnt 2gnu 3g2num. g2nü 2gnv 2gnw g2ny 2gnz go4a goa3li g1ob gobe3l 2gobj g2ob2l 2g1o2f 2gog 2g1oh2 goh3ren go1i2 gol2a gol2da gol2fr 3gon. go4nat gon2e 3gons 3g2opa gopf4 go2pos 2gopt gor2a 2g1ord 2g1org go2si go3sl go2sp 2g1osz 3goß go3t2h got6terb got6t5erg 3gou go1y gö2f g1öl 3göt 2g3p4 2g1q g2r4 g4rab gra2ba gra2bi gra4bl 2g3radl 2g3rah 2g3rak gram1 grammen6 gram8m7end gram6mer g3rand. 2gra2r grar1e gra4s3a gra4sh gra4sp gra4str 2g3raub grau3f 2graum grau3sk 2gräd gräs5c g3räu 2g5re. g4reb 2g3rec g3rede g4re2e 2g3ref gre2fr 2grege 2g3reic grei4fr 2g3reih g3rein g3reit 3g4rem 3gren 4g3renn gre3no gren6z5ei grenz3w g4rer 2grese gres6ser6 g3ret g3rev 2g3ric gri2e 2g3riem g3riese 2grig gril4la 4g3ring 4g3rinn gro2b3a gro3ber gro2bl gro2b3r 2groc 2groh 2g3rol gros4 2g3rose g4ross gro5sse. gro7ssen. gro7sser. gro7sses. g4roß g4rot 2gröh 2gruf. g4ruft 2g3ruh g3rui 2g3rum grun2g 3grup 3grus grus2s gru3sse 3gruß 2g3rut 2g3rüc grüs2 4gs g2sa gs3a2b gs3ach g3sack gsa2d gs3a2k g3s1al g4s3alb g4sall g4salm g4salt g4sama gs1amb g4samp gs3ane gs3a4p gs3a2r gs1as g3sat gs3ato gsau2g gsau4r gsa2v gs1ä g3sc g4sca g4sce gsch4 g4schef g5s2chi g5schn g4sco gs3d g2s1e2 gs2e3h g5s2eil gse4kl g3sel. g4s3ela g3seln gs3em gsen1 gs2enk g4sent g4ser g3sere gs3er1i g4se4s g4seu gsfi2l gsgene4 gs3ha g2s1i gsi2d g3sig gs3i2k g3sil g4s3io g4sis g4sita gs2ki1e gsmas8sen gs1o2 gso4b g5son g2s3op g5s4orge g5soz gs1p4 gs2pac gs4pant g5spei g3s2pek g3s2pi g5spie gs3pl g5s6port. g4s3pru gsrat4 gs3s4 g2s1tab g3stad g2staf g2s1tät gs2te. g5stein gst2el g5stell gs4tem. g4stemp gs4ten. gste2r gs4ter. gs4tere g6sterei g4sterm gst3err gs4tes. g4stest g5steu gs2thy g3s2ti gs3tie gs3tis g3sto g4stoch g4stod g4stor gs1tot gst4ra gst5reit gst4res g4s3treu gst3rit gst3ros g2stru gs1trü gs1tur gs1u gs3un gsü3s g3sy 4g1t g3te gt1h gt2hy gt2i gti2m g3to gt4r gt2se 1gu gu4ale gu1an. gu1ant gu1as gu4d3r gu2e 2gued guet2 2g1u2f 2g1uh gu3ins gu1i4s gum2e 3gumm gummi1 gun2e 2g1unf gunge2 4gungew 2gungl 2g1u2ni 2g3unk 2gunr 2gunt 3gur gure4 4g1url gur2t3h gur2tr gurt3s gu4s3a gu2sä guschi5 gus3se. gus3ses guss1o gus2sp gus4st gust3a4b gu4stap gu6stein gu6st5en6d gu3sti gu2str gu2ß1 gußt2 gu2t gut1a gu3te gu4t3er4h gut1h gut2s3p 2güb 3gür3 gü3st 2g3v 2g1w gy3n gy4na 2g3z2 gzeu4gi 2ha. hab2a hab2e hab2i h1ablu 2habn h1a2br h1abs 2habw ha4ch3en ha2cho 2hada ha2del hade2n h1adle h1a2dr ha3dri 2hae ha3el ha4far haf2e h1affä haf3f4l h2aft haf2tr haft2s hafts3p hag2a h2agg ha3ha h2ahs h2ai 3hai. h2aj 2haka ha1kl 2h2al. ha3l2al halan4c h1a2lar ha2lau hal2ba hal4bel hal4bin hal2b3r hal2bu 2hale 2halh hal2i 2halk hal4lei hal6lere haller6f hal6lerg hal4leu hal4lo4k ha3lo 4halp hal2sp hal4tal hal4tei hal2t3r hamot2 2h1amt ham3te h2an. 2hana ha2nal ha2nan han2au 2hanb h2anbe h2and han2da han4d3er han2d3r ha2nem han2f1 han6g5end han4gro hang3s han2k1 2hanl 2hano 2hanr 2hanz hao2s 2h1ap 3h2ape ha2pl ha2po ha2pr h2a3ra ha4rab 2harb 2harc h2ard har2fr h1arm. har3ma h2arme har4me. har4ne ha2rom 2hars hart4e har2th h1arti har2za h2as 2has. 2ha3sa has2c has4h3 has4sa hasser4 hass1t ha4str ha2ß1 h1aße ha2ta hat2i h3atl ha2t3r 2hats hatt2 h3attr h1audi h1aufb hau5f6lie hau3f4lo 2h1aufm h1aufs h3au3g2 h1aukt hau2sa hau4san hau2s1c h2ause hau4sel hau6s5ent hau4spa hau4spe hau4ss haus5sen6 hau4s3ti hau4sto hau4sur h2aut. hau2t1a hau2t3r ha2ve. häde2 h1äff 2häi hä2kl 2härz hä4s hä5sc hä6s5chen 2h1äst 2häug häu2s1c hä3usp 2h1b4 hba4ras hber2e 2h1c 2h3d4 hdan2 2hea he2ad he3be heb3eis he2b3l he3br he3bu he3ch2e he3chi he1cho h3echs hed2g he2dit he1e4m hee2n hee2s he1e2t h2ef. he3fab he2fan he2fau he2f1ei he3f2em hef3erm 2heff he2fid he4f3in4g he2f5le 2hefr hef4ra he2fre 3heft he2fu he3gu he2hel hei4a h4eib h1eie h1eif h1eig he2im hei4mal hei4mar hei4mei heim3p hei4mu 2hein hei4na heine2 hei4n3eb hei6nene hei4n3er h3eintr 2heio 2he1ism heis4s he1i4st h2eit heit4s1 h1eiw hekt3a he2la he3lag hel1an hel3au hel1ec he2lek h3elem he2len h2elf he3li hell2a hell3au hel4lic hel4mei he3l2or he2lö 4helt h4em. 2hema hema4s3 hem2b 1hemd 2heme2 h2e3m2i he4mia h3e4miss 1hemm 2h3emp h2en. he4n3a2 he2nä hen3ebe henen1 hen3end he4nene he4nens hen3erg he4nerm he2n1e4t 2henga hen4gag hen4kan hen4kau 2heno heno3t hen4sem hen3st2 hent2a hen3te hen4ter hen3tr h1ents 2h3entw h3entz he4n3u hen3z2 2he2o he3on he3op he3pa he3ph h1e2pi hept2 h2er. her3a2b he2rad 2herap he4r3a2r herau2 herb2 he2r1e2b he4reck her4eif 4he3reig he6reis. her7eises he2rel he4rene he6rersc he4rerw h1erfo her4fol 6hergebn 2herif herin4d herin4f he6rin6nu herin4s h1erke her4klä h5er6kran h6erlad 2herm herma3s he3ro he4r3o4b he4rof he4rop he4rot h1erör her3sta hert4 her3th her3um her4zap her6zeng 4h3erzeu her2z1w he3sa 2hese he3si he3s2p hes2t he2tap he3tä heter2 he3th het2i he3t4s he2u heu3g he3unt 3heusc he3x he1x2a 2hexp hey2 he1ye 1hè 4h1f4 hfaller6 hfan2 hfel2l3 hfi2s hflei2 2h3g4 hgas1 hga4sen 2h1h2 hhoh2 4hi. 2hia hi2ar h1iat 2hic hi1ce hich6t5er hicht6sp hi3d hid4e hi4dio 2hido hi2e hi3ens hie4rei hier3i hie4rin hiers2 hif3f4r hi2k3r hi2l3a4 hile3n2 hil2fr h2im 2hima h1imb h3i4mit h4imm h3impe hi2n hi3nak hi3nam hi3nap hi5n2as h2inde hine2i hi3nel hin2en5 h1inf h1inh 2hi3n2i hin3n2 hi3n2o3 hin2t1a 2hio hi3ob hi4on hi2p3 hi4pl hi2r hi3ra hi3re hi3ri hir2m1a hir2mi hirn1 hir4ner hir2s 1hirt 2his. his2a hi2se h1i2so hi2spa hi3tac hi2tan hi2tel hi3t2i hit1r hi2tro hit3z2e hi2v1o 2h1j 2h1k4 hkamp2 h2keu hki2n1 hklo3s 2hl hl2ag hla2gr hlam8meng hlan4d3a h1las h1lat h1laut h1lay h3läche h3läd h1läs h1läß h1läu hlb4 hl3d4 h3le. hle3a h3leb h3led hle3e h2leis h3leist hl1el h5len. hle4nas hlenen3 hl2enn h4l3entr h4lents hl2enz h3ler hle2r3a hl4ere h2lerg hler4hö hl2erk h6l3er4nä hle3run hl1erw h4lerz h3les h4lesi hlf4 hlg4 h2lie h3lied h2lif h2lim hl1ind hling4s3 h2lip h2lis h3list h2lit1 hl3l2 hlle3b hl3m2 hlma3s2 h2lo hl1ob h3loc hl1o2f h3log hl1op h4lor hlo2ra h3los. h3losi hlos4st hlo2ß1 h2lös3 hlö4ss hl4sar hl2ser hl3ska hl3s2lo hls3tie hl3str hl2su hl3t2 h3luf h3luk h3lumpe h1lüf hlz2 2h1m h3mad h3mag h3mak h3man h2mant h3mar h4marc h3mas hma3sse h3maß h3mä h4mäc h4mäh h4mäl hm2e h3me. h3med hme1e4 hmeer4s h3mein h3meist h3meld hme3le h3men hmen2s hme4ran hme4rei h3mex hmi2e h3mind h3mini h3minz h3mirr h2mo h3mop h3mot h3m2ö h4möl hm3p2 hm2s1p h2mu h3mul h3musi hmut4s 2hn h2na h3nag h3nam h4nar hn3a2te h4natt h3nau. hn1äh hn3d4 hn2e hne3b hne2e3 hn3eff hn3eig hn3ein h2nel hne4n hn4eng hne4pf h3ner hner4de hner3ei h4n3e2ro h4n3ersa hn3ex hn3f4 hnflei4 hnhof8stra8s h2nic h2nid h2nie hn1im hn1in h2nip hni4sa hnk4 hnno2 h2no2r hnra2 hn3sa hn3s2p hns2t hnsuch4 hntra4 hnts2 h2nul h2n1unf hn3z2 ho4ar ho3bern ho2b3l ho2c hoch3 hoche2 hock3t 2hod 2ho2e hoe3n ho3er ho4f1a4 ho2fä ho2fed ho2feu hof3f4a ho2f3l ho2f1o ho2f3r ho2fu 2hoi ho2l1a hol3ar 1hole ho2l1ei ho2lem hol3g4 hol3k holl4 2holy h3olym 1holz hol6zene hom2e ho2me. ho2mec ho2med h2on hond4 hon2er ho1on hoo2r 2hop h1ope ho1ra h1o2r2an ho2rau h1or3d 2hore ho4rens ho3ret 2h1org hor3ta hor4ter hort3s h1ortu h2os. ho3se2 ho4sei ho3sl ho4sla ho2str ho4ßene 2hot. ho3th 2hotr 2hot1s2 1hou hou4s 2ho2w1 h1ox ho1y2 hô1 1h2ö 2hö. hö2c 5höhe 2hö4s hös1c hös3se h3öst 2h3p2 h1q 2hr hra2b hr3ac hr3ad hr1a2g h1r4ah h1rai h1rane hr3ap hras3s h3räu hrb4 hr1c hr3d h2rec h3r2ech h3red h3ref hr3eff h2r1eh h4rei. hrei4ba hrei4br h3reic h3reif h4r3eig hr4eini h4reinl hrei3th h3rep hrer6geb hr2erh hr2erk h4rerla h6rer6leb hr2erm hrer4sa hrer5st hr2erw hr2erz h3re2s1 hres5s2 hrest2 hre2t h2r1eta h2r1eu h2rev hrg2 hrga4 hrgu4 h2ri h3ric h4rick hri4e h3riesl h3rin h4r1ind hr1int h4rist hr3l hr3m2 h3rog h3roh h1ro2l h4romat h4rome h4romi h4romo h4ron h1ropa hro4r h3rou h3rö2s hr2s1ac hr4s3and hr3sch hr2s1em hr2sen hr3sena hr2s1er hr2set hr4sh hr2sin hrs3k hrs3l hr2s1of hrst2 hr4stec hr6stele hr2su hr2tab hr2tan hr2te2l hr2th hr2top hrt3ric hrt2s hrt4ste h3ruh hr1ums h3rut h3rü h4rüb h4ry hrz2 4h1s h4s3acht h2sa2d h2s1alk h2sall h4samt h2san hs3and h2s1as h2sath h2sato h2saud h4s3aur h2saut h2säh h2säug h3sc h4schan hs2cr h3se. h2s3ec hse4e h4s1ehr h2s1eie h4seind h6seinst h3sele hse4lin hs1emi hsen5erg h2s1ent h2s1erf hs1erg h2serh h4serkl h2s1erl hs1ern hs4erne h2serö h2s1erw h2serz h2sex h3s2ext hsha2k h2s1i2d hs2im h2s1ing h3s4inni h4s1ita hs2kal h3skand hs1of h2sofe h2sop hs1org h2spac h4s3pani h2s1par h2s1pat h3spec h3spei h2sper h2sph h2spo h3spoi h2sprä h2spro hss2 h2staf hst3alt hst2an h2stau h2stäl h2stäu h4stea h4stele h4sterm hs3tier h2stin h2stit h2s1tol h2s1tor h3stö h4s3treu hstro2 h2stu h3stun h3stü h2s1u hs2ung h3sy 4h1t ht1a h2tab hta2bl h2ta2d ht2ag ht4akt. ht4akte h2tall h2talo h2talp h2talt hta2m h2ta2n ht3ane h3tank h2tap h2ta2r ht2as h2t3asi h2tasy h2t3at h3tat. h3tate h2tau h3taug h4tax ht1ä h2tär h3te. ht3e4ber ht1ec hte3cha h2t1e2d ht1eff ht1e2he h2teif h2t1eig h4t3eilz h2t1eim ht1ein h2t1eis h2t1eke ht3elas hte6l5ei. h4telek h4t3elfe h4t3elit hte4m ht1emi h2temp h3ten. ht3engl ht3enta h4tentf hter6de. hterer6s ht3erfo ht3erfü h6terfül h6tergeb ht3ergr hter6gri ht1erh hter6häl hter8höhu h6terleb h6t5erleu h6terneu ht5erspa hter8spar ht3erst h6tersta hter6tra ht3erwä ht3erze h2t1ese h2t1ess h2teta hte4th h2t1eu h3teum h3teun h4textr h2t1h h4thei h3thera h3thes h4tho h2t1i2d h3tig h2t1im h2t1i6n3 ht3ine h2t1is h3tisc hti3t4 htni2 h2t1ob hto2d1 h2t1o2f h2t3oly h2tope h2tord ht3rak h3tran ht3rand h4t3ras ht6rates ht3rau h4traub ht6raume ht3rec h3treck ht3rei h2t3res ht3ric h4t3rieg h2t3rin h3trit h2t3rol h2t3ros h2t3roß ht3röm ht3ru h2t3rü h4ts ht2sah ht2sal ht4s3a4n ht2scr ht4sein ht2sel ht4s3end ht4seng htse2r1 hts3eri htsha2 ht3s4hak hts3kr ht2s1o hts3par hts3tät ht4s3tem hts4tie ht4stip ht4s3tur ht4s3tür htt4 htti2 htu2e h2t1urs ht3z2 hu2a hu2b1a hu2bei hu4bel hu2b1en2 hu2bi hu2b3l hu4b5r hu2bu hu2fa hu2h3a hu2h1i h1uhr h1uhu hu2kä hu2k1in huk3t4 hu2l3a2 hu4lab hu2lä hule2 hu2l1eb hu2l1ei hu2lem hu4l3eng hu4lent hu2l1er hu2let hu2lid hu2l1in hul3l2 hu2lo hu2lö hul3s hu3m2a h1umh h1ums hu2n h1una h2und hun3d2e hunde3i hun2e 2hunf hung2 hun3ge hungsa4 h1uni h1unm 2hunt h1ups 2hur hur3g2 hur2t3h hu3s2a hus3h hu2so hus2s3a hus3se hus4ser4 hus2s1o hus2sp hus4st hu2ß1 hu2tab hu2ti hu2t1o hu2t3r hut2t hut4zen hut4z3er hut2zu h2ü h3über h4übs h3übu hüf2 hüft1 hühne4 2h1v hvil2 2hw2 h2wall hwe1c h1weib h1weih hweins3 hwein6sa hweis4s h2wirr 1hyd hy3dr hy2lor 1hymn h1yo hy3os 1hyp hy2pe. 2hy2t 2h1z hz2a h3z2o hzug4 h3z2w i3ad. iad2a i1adn ia3do iaf4l i2ago ia1h2 i1ai i3ak. i3ake ia2kei ia2kr i1akt i1al ia2l1a2 ial3ar ial3as ia2lä ial3b4 ial3d4 i3aleb i3alef i3alei ia3lek i3alel i3aleng i3alent i3alerb i3aler4f i3alerh i3a4lerm i3a2l1et i3alex i3a2lia i3alim i3a2lin i3al3l ial4ler iall2i i2alo ia2lon ia2lop ia2l1o2r ial3p ial3s ial3t2 ia2l3u2 ial3z2 i1am. ia3ma iampe4 i1ams i1an. i1an2a ia2nal ian3alt ia2nau i1anc i3and2 i3a2n1e2b ian2er i1ann i1ans ian2s1p i3ant i3anz ianza4 ia1o ia2op ia3p ia1q i1ar i3ar. ia2ra i2are iar3r i1as i3as. ia3sh i2asi ia1s2p ias5s iast4 i3at. i3at2h i4athe 1iatr i3ats i3au ia3un iau2s1 i2az 2iä i1ä2m i1äp i1är. i1ärs i1ät i3ä4tem iä2ti iät5s2 i1äv 4i1b ib1art i2b1auf i2b1aus i2baut ib3be ib2bli i2b1eig i2b1eis ibe4n1 i6ber6geb i4b3er4la ibe1ro i2bim i2b1in i2blad i2bleu i3blu i3b2o i2bö i2b3rau ib3ric i2b3roc ib2ser ib4ste ib2un i2b3unk i2b3unt ibus3 ibus1c 2ic i3ca ic1c ich1a2 ich6art. ich1ä i1che ich1ei ich2er icherin5 ichermas8 ichgro3 i1chi ich1l ich3le ich3li i3ch6lo ich5m ichmas4 ich3n i1cho ich3ort i2ch3r ich6sele ich2s1i ich6stie ich2tr i1chu ich1w i1ci ickt2 i1cl ic3la ic3ra i3cu i1d 2ida id2ab i3d2ac id4al id2am id1a2n i3d2ans i3d4at id1au id2ax idä1 idbu4 id2e 2i3de. i2dea 1idee id3eis 2idel idel4ä i4demul 4i3den. ide4n1o iden4se ide3ran iderin8nu ide1rö ider6reg 2i3des ide5sa ide3so ides2p 1i2di2o idi4on i4diot 2idk idni3 id2o i2dol 2idoo i2dö i2dr id4ro id2s1p idt4 1i2dy ie3a2 ie2bä ie2bl ieb3re ie2bri ie4b3rü ieb4sto ie1c ie2cho iech3t ie2d3an ie3de ie2dr ie1e2 ief3akt ie2f1an ie2far ie2fau ie2fäh iefe2m ief3f4 ief2i ie2f3l ie4fonk ief1r ie2fro ie2gl ieg5li ie3g4n ie2g3re ieg2s ieg6s3c ieg4se ieg4si ieg6s1t ie3her ie2h1in ieh3r2 i1ei ie1ind i2e2l1a iela2r ie2läs iel3d4 i2ele ie4l1e2b iel1ec iel3eid ie2lek i4elen ie4lene ie4leng ieler4e ieler6fi ieler8geb ieler6ke ieler6la ieler8lebn iel4erw ieles2 i2eli ieli2d i1ell ie2lo4b ie2lop ie6lor i2els2 iel3sz ielt2 iem2e iemis2 i1en i3en. i3ena ien1ag ien2am ie4nas i3enä i2ene ien1eb i3enec i3e2n1e4k iener6fo ien3er4g iener6la i3enex i3enf i3eng4 ienge4f ienge4z i3enh ie2nid ie2nim ie4n3in i3enj i3enk i3enla i3enle i3enm ienma3s4 i3enn i3e2no i3enö i3enp i3enr i3ens. i3ensa i3ensc i3ens2e ien3s2k i3ens2p ien6st5er ien6stop iens4tr ienst5rä i3en3sz ien4t3ar ien3te i3enth ien3tr i3enty i3env i3enw i3enz ie1o4 ie2r3a2d ier3al ier3an ie2r3ap ierb4 i3erbun ier3d i2ere ie4reck iere5ins ie4r3eis ie3r2er ierer3k ie4r3erz ierf4 ierg4 i1ergi i4eri ierk4 ierken4 ierma6ss i1ern i3ern. iern2a i2erni ie2rö ier4re. ier4s3eh ier3sei ier3sta ier3te iert2i ier3z2 2ie3s2 ie4san i2esc i2ese ie4sh ie4s3k ies3o ie4sof ie4spu iesser6g ie5sset iess3ti iest6e ie4stin ießer4g ie2t1ag ie2t1ak ie2tan ie2t1ap ie2tat ie2tau ie4tent ie4t3erh ie4t3ert i4ethe iet3her ie2t1ho ie2thy ie4tob ie2t1ö2s ie2t3ri ie2t3ru iet2se i1ett iet3zw ieu2e ie1un ie2w3u i1e2x 2if if1ab if3ange if1ar i2f3arm if4at i2f1au if1än i2fec i2f1ef ife4i if1ein if2e4n i2f1erg if1erh if2fa iffe4s if6feste if2f3l if4form if2fro iff2s iff4ste if3l if1lac if4lä iflo4 if4los i1flü if3r i1fre i2freg if4rev ifrü4 if3sa if2t3a if2ted if2t3ef if2t1ei if2te2l if2tep if4terk ifte4s if4t3esc if4th if2top if2t1r ift3ri ift1sp ifts2t ift3sz if2tur i1fy 2i1g i2ganb i2garb ig1art iga3s i2g3att igd2 i6gebrau i4gefar ige4füg 3i2gel. ige5lau i2geln ige4me ige4mis ige4na ige6nene ige4nid igen5s ige2o ige2pa ige2ra igerma3 ig5erwer ig1erz iger4ze ige4sel i2g1ess ige4tra ige4tre ige4woh i2gim i2gl ig1lau i3gle ig3lim ig4na i4gnä i3g4neu ig4no igo1p ig3rad i2g3re ig4ren igro3 i2grou ig4sal ig3sä ig4schr ig1s2o ig1sp ig2spa ig4sti ig4s1to ig2stö ig6stra6s ig4stur 2i1h i2har i3he ihe1e ih1elt ihe4n ihe3u ih3m ih3n ih3r2 ih2s ih3sp ih3sti ih1um. ih1w ii2 ii3a4 i1ie i3ig i1im i3in i1i4s i2is. ii3t i1it. i1j 1i2js 2i1k ika2ge ik1aka ikaken3 i2k1akt ik3amt i2k1ang i6kantei ikanten8n ik1art ik3att i2k1au i3kaz ik1äh i2k1än i2kär 4ike i2keb ik1ebe i2k1ed i2k1ef i2k1ei ike4l1 ike2n1 ik1en2s ik1ent ike2ra i2k1e4r2e i2k1er2f i5kerfam i2k1er2h i2ker2l i2kero i2ke3ru i2k1eta 4iki i3ki. ik1i2d i3kie ik1in i2kins i2k3l ik4län i3k4leri i3k4let ik4lim i3klu i2kne ik3nu iko3be i2k1off iko1p2 ik1or iko2ri ikot3t i2köl ik3rä ik3re i2kres ik4ris i3kro ikro3s i2krö ik3sa ik3s2z ik3ta ikt3erk ik4t3esk ik2t3re ikt2u i2k1uh i2kup i3kus i2kü i1la i2lab i2l1ac i2l1ak il1a2ma il1ang i2l1anm i2lano il2anz ilan6zer i2larb il1asp i2l1au i3laub i3l4aufb ilau2s1 i1lä1 i2lär 2ilb ilb4l il2c il5chen il2da il2dä ild3ebe il4d3en4t il3der ild4erp ildi2 ild1o il2dor il2dr 4ile il1ec ileid4 il1ein il1el i2lemb i2l1e2mi il1ent i4lentl i4lents i2l1erd iler4ei i6lereig il1erf iler4fo i2ler2g i2l1er2h i4ler4kl il1err i4lerri i3l2erz ile4th il1ex ilf2 il2f3l il2f3re ilf4s1 il2gl 2ilh 2ili ili3e4n3 iliga2 ili4g3ab ilik4 i2l1ind i4l3init il1ins i2l1ip ili1pf il3la il4lad ill2an ill4ant il2lä2 il2leg ille4ge il4lenn il3l2er 1illu il2mak il2m1ap il2m1au ilm1ei il2min il2mor 2ilo il1ob il2oh il4on il2op i2l1o2r i3lou i3lov il1ox ils3ent ils2to ilt2 il3th i1lu iluf4 i2lum i2l1ur i3lus ilü4 2ilv4 il2zar il2zau ilz3erk il2zwa imad2 ima1i im2al i2m3anh i2mans i2marc im3aren i2m1arm i2m1art im4at ima2tr imat5sc ima4tur im1aus i2maut im3b i2meg im1ein i2mej i2mek i2mele i2melf im2en i2m1er2f i2m1er2l i2m1er2z i4me3sh imes3s i2meti i2mew imhau2 i2mid im1i2de i2mim i2m1ind i2minf i2m1ins 3immatr immen1 imm3ent im6menth im2mit 1immo im4mo2d im2mö imni2 2imo i2m1ob i2m1o2p imo3re i2mö 1imp imp2fa im3pf2o imp2s im3pse 2imt imt2e im3t2i imtu2 2imu im2um im1urk 2in. ina2be in3abu in1ac i4nack in1ad i3nald inaler4 ina6lere in2alp i2n1am in2an in3an. in3ana in3ann i2narb in3att i2n3au2 inaus1 2inä i2n1äh in2är in1äs 2ind. inda2 ind2ac in2dal in2dan 2indä 2inde. 2inden ind5erke inde3sp indes4t 1index ind2i 1indik in3dö 2indr ind4ri ind3se 1indus in3d2ü 2ine in1ec i3nee i2neff in4elen ine2n1 ine3nä i4nen4zy i5ner. i4n3erbi in4erha i4ner4he i3nerk i3n3erle i6ner6leb iner4lö i4n3er4tr i3nes in2et in1eu ine3un in3f4 1infek 1infiz 1info 2inga in2g1af in2g1ag in2g1al in2gam ing1ar 2ingä 3ingeni in3g2er in4g3er4w 2in2gl in3gla ingmas4 ing4sam ings6por 1inhab 2inhar 2inhau 2inhe 2ini. in2id ini3de 2inie 2inig inig2a ini3k4r 2inis ini3se init2 i3nitz 3inkarn 1inkas in4k3ent ink4er in2kro inks1t ink4ste in3k2ü inma4le 2inn. inne4n in4ner4m in2neu in4ni2v 2innl in2nor 1innta 2ino in1od ino3e4 in3ols in1or i3no3t i2n1ou i1nö in1ö2d 2inr 2ins. ins2am in6samt. insch2 2inse. in2seb 2insed 2insen 2insk 3instal in4s3tät 4inst2e 3instit 4instra in4strü 1insuf ins3umz in2sur in3sz 2inta 2inte. 1integ in3tei 2intep 2int2h inthi1 in3ti int2o 2intö 2in3t4r 4inträ 3intrig int3s i2n1u i4nuh in3unz inu3t 4inverm invil2 i1ny2 in3z2e inzel8ler in3z2i in3z2sc inz2u in3zw i1ñ 2i1o ioa4 iob2l io1c io2d io3da io3du io3e4 i2of iof4l i2oh io1i io3k6r i3ol. i3ols i3om. io3me i3oms ion2 i3on. ion3an io2n3au ion3d2 io4nee i3ono io2nor i3on4s1 ions3a ions3el i2ony i2oo i2o1p i3o4pf i3opt i2or i3or. i3orc ior2e iore4n io1r2h i3orp i3ors i3ort 4ios i3os. io3sh i2ost ios2u i2o3sz io3t i3ot. iote3l iot4r i3ots i2ou i2ov i3ox i2oz i3oz. i1ö2k i1ön i1ös. i1ö4st i1pa ip2an i1pe i3ped i3per 2ipf2 ip5fam i3pfan ipfe2 iph2 2i1pi ipi3a ipi3el ipi3en ip4lu i2poi ip2pan ip3pe ipp1f ip4pl i1pr ip2sa ip2sei ip2sp ip2sta ip4stü ipt2a ipt2i ipt2u 2ipu 2i1q i1r4a i3ra. 2i3rad i3ras irat4 i1rä ir1äh ir2b3l ir1c ir2ch1o ir4e i3ree 2irek ire4na i3ré irg2 irg4s ir2he ir2i 2i5rig 2irk irke4n ir4kene ir2k3l irk4s3c ir3k2u irli4n ir2m1ag ir2mak irm1au ir2mä ir2m1ei irme4n1 ir2m1o2 irm4th ir2mum ir4munt 2irn ir2n3a ir4nat ir2no i3ro i1rö irpla2 ir2rei irre4l ir4reli ir2rh irs2 ir3sche ir4schl ir4schm ir4sch3r ir4sch3w ir3se3 ir3sh irt2s1t 2iru ir1u2m iru2s1 iru3te i3r2ü i1s i3sac isa2m3 i4samp i4s1amt is2ap isa2r i3sat is3att i2sau is3auf isau2g i2säh i2s1än 2isb i2sca i2sce i4schar i3s2che i4schef i4sch3e4h isch3ei ische4m i6schemi i6scher6z i4schin i5sching i2schl i2schm isch3ma i4schna i4sch3re isch3ru i6schüb i4schwa i6schwir i4schwo isch3wu i4schwü i2scr 2ise ise3a ise1e iseh2a ise3hi is4eind is2el ise3lad i6sel6ter ise2n1 ise4na is2end i4senho isen3s ise4r3ei is1erg i2serh iser4he i2s1erm i2s1es2s i3s2et i4s3etat i3s2eu 2isf 4ish 2isi isi2a i2s1i2d isi4de isik2 i2sim i3sin3g4 i4ski i4sku is3la 3islam 2isma 2ismi ismu2 is1of i3soh 1i2sol 2is4o2n1 isonen4 iso6nend isono2 i2sop is1ort 3isot i2s1ou 2isp is1pa i2spar is2pat is1pe is1pic is2por i2spro is3sa is4s1ac is4sau is3sc iss5chen is3senk isser4f issermas8 is3so is3sp iss2po is2st is3sta is4ste is3sto iss1tr is3strä is3stu is2su i2stab ist3ac is4tal i4stam ist2an i4s3tang ist4e i4stea i4s1tec iste4n istin4f ist6o ist4ra is3tras3 i2strä i2stre is5tromm i2stur is1tüm i3suf isu2m isum3p i2sü 2isy i1ß ißer4s iß3ersc i1ta it1ab. it1abs i3t2ag ital1a ital5l it1alt it1am ita3ne it1ang it3anr it1app it1a2re it1art i3tat it1au i3tauc i2tauf i2taut 4i1tä it1änd i2t1äs ität2 i1te it1eff i2t1ei it2eic i4teig i4tein i4teis 2itel ite4l1a i4telek it1emi i2temp ite2n i3ten. i4tents i2tepo i6tereig i4t3er4fo iterin6d iter6klä it2erö i8t7ersche i2t1es2k i2t1ex i3text i3thr i1ti i3tic i2t1id i3tig 1itii it1in1 i3tis i4tiso iti3sp i4tiss i3tiv iti2v5a it5le itmen2 4i1to i3to. it1ob i3toc ito3d i2t1of ito2p it2os i1tö 4i1tr i2t3rad i3tradi it3raf it3ras it3rau it3räu it3re it4ret i3trie it3rob it3rom i2t3run i2t3rut 2its it2sa its1ag it2s1e it4se2h its3e2r1 it4sh its1or it3spen it4stec it4s3tem it4sten it4s3tes it6stra6s 2itt it2teb it4temp it3ter itt5erfo itt3hä it2tob it2top it2tri itt3ric itt6schi itt4se4h itt4sei itt4sor itt4sti i1tu it1uh it1ums it2ung i2tuns ituran4 it1urg i3tus itut4 i1tü 4ity1 ityl2 2itz it2zec itz2er itz3erg it6zergr it4z3erl it2zö it2z1w 2i3u2 i4u3l ium3 iuma2 ium4se iun2 iungs3 i4up iu4r ius1t i1ü4 2i1v i2v1ad i2v1ak i2v1am iv1an i2v1ä i2veb i2v1ef iv1ei iv1elt ive4n iv1ene i2v1ent i2v1ep ive3re iv1erh iver4kl iv1erl iver3s i2v1ex ivil3l i2v1im i2v1ind iv1int i3vol ivo3re i2v1r i2vun i2v1ur i2vü 2i1w 2i1x i2xa ix2em ixt2 i1y 4i1z iz1a iz2ac i2zag i2zan i2zap i3z2as i2zau i2zä i3ze iz2ei izei3c izeit3s4 i2zele ize2n i4zener i4zentz iz1erg i4z1erl izid3 iz1ir izo2f i2zö i2zuna i2z1w i3z2wi í1l j2a jab4 jah4r3ei jahr4s ja3l jal2a ja3ne jani1 jani3t4 ja5ru jas2o jat2 2j1d4 jda3 je2a jean2s je2g jek2t3a jek4ter jek4tin jekt3o2 jektor4 jek2t3r je3na je2p je3r jer2e je2t1a je4t3h je2tin je4tor je2t3r jet3t je2t1u2 ji2v 2j1m joa3 jo2b1 job3r jo2da jo2i jol2a jong2 jo2p3 jo1r2a jor3d2 jo2sc jost2 3jou jou2l 2j1t jty1 j2u ju2b3l jude2 jugen6 jugend3 ju1i ju2k jul2i jung5s2 ju3ni ju3r jur4a jur2o ju3t2e1 2j1v 1ka 3ka. ka3ar 2k1abb kab2bl 2kabd 2k1a2ben 2kabf 2kabg 2kabh 2kabn 2k3a2bo 2k1abs 2k1abt 2kabw 2kabz ka1c kade2r 2k1adm 2k3a2dr 3kadu 2kadv ka3e ka1f4l ka1fr kaf3t2 kag2 2k1age 3kah ka1ho ka1in kaken2 ka1kl 2k1akt. 2kala. kala3b ka2l1a2d ka2lan kal3d ka4l1eh ka4lens kal3eri 3k2alk kal2k1a kal4kan kal2k3l kal3l kall2i kallö3 2k1allt ka2lop ka2l1os kals2 kal4tex kal4th ka2lu k2amt 3kana kan4al ka4n1a2s ka2nau 2kanb kan3d2 2kanda 2kandä kan2e 2kanf 2kanim kank4 2kanl 2kanom 2k1anor 2k1ans k2ans. kan4tar 6k5antenn 2k1anth ka3nu kan2um 2kanw 2k1anzu 2kanzü ka2o1 3kape ka3po 3kara 2karbe 2karc k2ard kar3d2a k1area k2arg ka3r2i kari3es k2ark 2k1arm kar2pf k2ars k2ar3ta k1arti 4kartik karu2 k2arw 3k2asc kas2e kase1i kasi1 kas2o ka2sp kas2t 2k1ast. ka3sta ka4ster 3kasu ka3sz ka2tan 3kateg k3atel ka3t2h ka2t3r kat3se 2katt4 kau4fer kau2f1o kauf6s5ag kauf4sp kauf8s7tem kauf6sti k2aus. 2k1auss 2kausw kau3t2 2kauto ka3ve 2kaz 1kä käl3 k1ä2mi kär2 2k1ärg kä2s5c käse3 kä3th 4k3b4 kbe1 kbo4n kby2 2k3c 2k3d4 ke2ben 2k1ec ke2di 2k1eff kefi2 kege2 ke2gl ke2he. ke2hen kehrer4 kehr2s kehrs3o 2k1eic 2k1eig kei2li 2k1ein kein4du kein4e k1eis 2keise keit2 ke2l1a ke3lade ke3l2ag ke4l3am ke2lä kelb4 keld4 kel3eis 2ke2lek ke2l1en ke2l1er kel3la kel7l4e kell2i ke2l1o2 ke2lö kel3sk k4elt kelt4e 2k1e2mi 2k1emp k2en. ken1a ken3au ke2nä ken3dr ke2n1e2b kenen1 ke4nene ke4nens kener4n kene4t 4ken4gag k5en6gel. ke2nim ken3in 4kenlad 4kenläd kenn2a kenn2e ke2no k2ensa 4ken4sem ken3s2i ken3s2k ken5s4te ken3sz k3en4te. ken6ten. 4kentf 2kentg ken3th 2kentl 2k1ents 2kentw 2kentz ke3ny k2en3z2 2ke1o2 2kep ke2pl k2er. ke1ra ke2ran ke2rau ke2r1ä ker4ble k2erc 4kerd ke2r1e2b ke2rec ke3reig ker3ein 4kerfah k4erfam ker2fo k3ergeb 2kergu ke6rin6nu kerin6st kerin4t k3erken k2erko k3erlau k3er4leb k6erlebe ker2na ker4nei 4k3er4neu kern5eur k1ero k2e1rod 2keros ker4reg k2ers. 2kersa kert2i ker6werb kerz2 k1erz. ker4zeu 2k1er2zi k2es. ke2s3a k2esc k1ese ke2sel kes2sa ke2t1a ket2ag kete4 ke4t1eb ke4tel 2k1e2th ket3ha ket3s ketta4s kett1h ke2tu keu6schl 2k1e2va 2k1e2x 4k3f4 2k3g2 kga4s1 kge3s2 2k1h4 k3he kho3m k3hu ki1a ki2ad ki2ag ki3ak ki3a2r ki1ch ki3dr k2ids 2kidy ki2el kie4lei kiel3o 2kiern kier2s kie4sa kie4z ki1f4l ki1f4r ki3k4 2ki3l2a 2kilä 2kim 3kin. ki2nä 4kindex 2k1indi 2k1indu 2k1inf k2ing kin2ga king3s 2kinh k2ini3 kinik2 k2inn ki3n4o kin3s 2k1inse k1inst 2k1int ki3or kio4s 3kir 2k1i2so kis2p kis5s kist2 kiv2 kive4 2kiz 2k3j 2k1k4 kkab4 kl4 4kl. 4kla. 2k1lac klan2 2kland klan3du k4lar k1last k1lauf k3laug 2k1läd k2lär k2le 4k3le. kle2br k3leg 2kleh klei2e k3leit k3lem. kle2o 2k3ler kle2ra 2k3leu kle3us 2klic k2lien k2lif 2klig 3k2lim k2lin k3lin. 3k4lina k4link k2lip k2lir k2lisc 2klist klit2s 2k3liz 2k3loc 2klok 3k4lop k3lor klos2 klo3sse klost6 2klöc 2klöf k2löst k4löt k1lu klu4b k2lud k2lug k2lum 2klux 2k1lüc 2kly 2k1m2 4kma kma2la kmas2 kma3sse k2n2 k4nac 2k5nach 2k3nad 2knah 2k3nam 2k3näp k3ne k4nec kne1e 2knes kne3tu 2knetz 2k5neu 4kney kni4e 2k3niv kno2b3l k4nol 2knorm 2knov 2k3num 1ko ko5ad ko2al kobal2 2kobj kob4s kof3f2 koffe3i kohl2e kohle3i koh3lu ko3l2a ko3le kol2k3 3kom komer3 4komn ko4mu k2on kone2 ko2nem kon3s4 kont6e ko2nu ko3on 2kop. ko1pe 2koper kopfa2 kop4fen kop6f5err ko3pte ko3r2a kor2ba kor2bl kor2br 2k1orc korder4 kor6derg ko2rel 2k1org kor2k1a kor3m kor4nac kor2n3ä kor4no2 2korpi k2os k4os. ko4sk ko2s1p 3k4ost ko2ter ko3ti kot4r kot1s2 kot4tak k1ou ko3un 3kow ko2we 2k1ox 1kö köde2 k2öf k1öl 2k1p2 2k3q k2r2 2k3rad 2k3rah k4ral kras3 kra4ss k3rats 2kraum k4raw k4raz k4räc 2kräd k4rän 2k3räum 2k5re. 2k3reak 2k3real k4reb 2k3rec 2kred. 2k3rede 2kredn 2kredu 2k3ref 2kreg 2k3reic kre1i2e4 kreier4 k3reif 2k3reih 2kreim krei6sei k3ren 2kresu 2k3rh 2krib 2k3ric 2k3ries 2krip k3risi krob4 k4roch 4k3roh k4rok k4ron k4rop kro4ss 2krot 3kroth k3rou 2kröh 2kruf 2k3run 4k1s ks3a2b k3sac ksa2k k4s1amt k2san ks3a2r ksa4s k2sau ksau2f k2sav k2säh k3s2c ksch4 k2s1e2b k2s1ec k3s2ed ks1ei ks2eid ks2eif k4seind kse2le k2s1eng k2s1ent ks1er ks2ere k2serf k2serg k2serk k2serl k2sers k2serw k2s1e2v k2sex k4s1i2d ks2im k2s1in k4s1is k3s2ke ks3kl kso2 ks4on k2sop k2s1or k2sö ks1pa k2spal k3s2pat k2spä k3spe ks2pel ks2pen k2sph ks2por ks2pul ks5s2 kst2 k2stal k4s3tanz kstat4 ks3tat. k3stäl ks4tel ks1tie k4stier k2s1tis k2stit k2s1tor k4strop k2stuc k2stum k2s1tur k2stüt k2s1u k3sul ks2zen 4k1t kt1abr kt1abs k2t1ad k3tag kt1akt k3tal kt1am k2t1an kt2and k2t1a2r kt3a4re kta3ri k2t1au kt3aug ktau2s ktä3s kt1ein k2tek k2t1ela kte3li kte4n1 k2t1ent k4tentl kten3z kte2ra kte3ran kt4ere k4t3erfo kt1erg k2t1erh k2terö kte3ru ktes2 k2tex k2t1h k2t1i2d kti2me kt3ind kt1ing kt1ini kt3inn k2tint kti2s1e k2tiso kti2st kti4ter kto3b k2t1of kto5ren. k3t4ran kt3ras k2t3rau ktro3me kt3run kt3rü kt1s kt3s4a kt3sä kt3se kts2el ktsen1 kt3si kts1o kt2sor kt3s2z ktt2 kt1ums k2tuns kt3z2 ku2al ku1c kud4r 3kug ku2h 2k1uhr kuh3s ku3la ku3l2e2 ku3l2i 2kulp kul2to kul2tr k2um. k2um4e 2kumg 2kuml kum2sp k2u3n2a kun3da kund2e kun4s kunst3 2kunt 2kunw 4k1up. kur2bl ku2rei kuri2e kuri4er 2k1urk ku2ro kurs1c kur2sp kur2st kur4ste 2k1urt4 kur3tsc kusa2r ku4schl ku2sp kus3ses 2kust kus3ta ku2su ku2ß 2kut. kut2a kuto3 1kü kü1c 3küne künf3 3kür kür2s 2k3v 2k1w k3wa 2k3z2 kze3l 3la. la3ar l1ab 3l2ab. lab2a la2bad l2abä 2labb lab2br 2labd lab2e 4la2ben 4labf 2labg 2labh 3labi l3a2bit 2la2b3l 2labn 3lab2o 4labo. la3b4ra lab4res la2bri 2labs la2bus 2labw 2labz la1ceb l4a3che lachter8f lacks2 1lad 2l1ad2a 2ladd la3de. la3d2i 2ladj 2l1adl 2ladm l1adop 2l1a2dr 3l2adu 2laf la2fa la2f1ei la2f1er laf1r laf3t4 la2fu la2ga lag3d l2ager lagerin5 4lagg la2gio lag3l la4g3n lago4 la2gob lag3str 2la3ho 3lai lai4s1t lake2 la2kin l2akk la1k4l la2kro lak3t2 2l1al la2la 3lala. 3lali 4lalt l2am. lami3t lam2m1a lammen8ge 1lammf la2mor l2amp l3ampu 2l1amt lamt4s la4mun la2na l1anal la3nan la4n4at la4nau 2la2nä 3l2and l4and. lan2da lan4dam land3au l4ande lan6derh lan6d5erw lan6d5erz lan6d5inn l4an2d3r lan3dri lan3erd laner4f 2lanf lan4gan lan6g5esc lang3s2 2lanha l2anhe 3lan2i 4lanl 2l1ann l1ano la2nof 2l1anp 2lans2 l1ansi 2lantr 2lantw 2lanw lan2z1w 3lao 2l1apf la2ph 2l1a2po lap2pl la2r1an 2larc lar1e2b la2r1ei la2rel la4rene larf4 lar3g lar3ini 4l1a2rom l1art 2lart. lart2h l3arti lart4r 3laru l2as. la2sa la4sam la4sä lasche4 4lasd la5seb la4sei la4s1e2l 2lash la2sin la4sis la2so 2la2sp 3lasser l2ast la4sta last3an la4steu la2str last3ri las3tro las3tur la2stü 1la2ß3 la3t2e 2l3a4tel la5t2i 2l3atl 2latm lat2o la2tö la2t3ra lat4ri lat2s lat3st 2lat4ta lat4tex lat4t3in lat2t3r latzer4 1laub. lauben6s5 lau2b3r laub4se laub4st lau4fin 2laufn lau2fo lau4fri 1laug lau3gl 3laun 4laun. la4us 3l2aus. 2l1ausb lau6scha 2lausd 2l1ausf 2lausg 2lausl 2lausr 2l1auss 2lausz 2lauto lau2tr la3va lave4n 1law lawa4 1l2ax la4xel l2ay lä1c 2l1ähn 1länd l1äpf 2läq lär2ma l1ärme 2lärz lä2s5c lä4s3s 2lät 2läub 2läuc 2läue 1läuf 2läug 2läx 1là 4l1b l3bac l2bant lb3a2ri lbau1c lb1ärm lbb4 lb2ei l4b3eink l4b3eise lbe4ral lberin5 lbe7s l4b1e2ta l2b1id l2b1ins lb4lad l3b2lat l3blä lb3le l2bled l2blic l3blo l3b2lö l3b2lu l2b1o2ra lb3rea lb2s lb3sa lb3se lb3si lb3sp lbs2t lbst3ac lb4ste lbst3ei lbst1u l2b1uf l3bum lbu4n lbus3s lbzei2 2l1c l3ca l3che l4chei l4chent lchermas8 l3chi lch3le lch3li l3chlo lch3n lch3r lch3s2 lch3ü lch1w l3cl l3co 4l1d ld3a2b1 ld2ac ld3ack l2daf lda2g l2d1ah lda2i l2d1ak l2d1al l2d3a4n ld1arm ld1ass l2d1au ld3au4s l3däm ld1är ld1äs ld1ät ldbus2 l3de. lde4ben l2dei ldein7 l2d1elf l2d1e2mi l2d1ems lde4na lden5erg l4dentl l3der. l4d3er4fa l6der6geb ld1erh l4der4he l3d2erl l6derlas l6derlaß l3d2ern l2d1er2p lder4tr lde3sa lde4sel l2d1es2s l2dex ldi2c l2d1id ld1i4mi l2d3ion ldo2b ld2on l2dop ldo2r l2d1ori ld2os ld2ö2 ld3r ld4ram l2dran l2dre ld5rie l3d4ris ld4ru l2drüc ld3sa ld3ska ldt4 ld3th ldt5s ld3tu l2d1ul l2d1um 1le le2ad le3ar le2as 3le3ba leben4s3 le2bl 3lebr le2b3re 2lec lech1a le2chi lech7t6e le2dr le2er lee4ret le3f2a 2l1eff lef4o le2g1ab leg1as le2gä le2gl 3leg4r 3leh 4lehe. leh3r2e 4lehs 4leht lei4ble l2eid lei3ere lei4fan lei4fei leifer6g 2l1eig lei3gl 3leih lei4hau lei3l2 leim3p 3l2ein. leinbu4 leinbus5 3l2eind lein4du l4eine lei6nerb le2inf le2ini 2leink l1einn l3einsa 2leint l2einu le2is leisch5a lei8schei lei6scho lei6sern l1eisf lei6ss5er leis3st lei4str lei4ßer l2eit lei2ta lei2to leit3s2 3leko 2lektr 2lekz 3l2ela le2le le3lei 2lelek 6leleme le3len leler2 leler4s le3les 2lelf. 2l1elfe l2eli lel3s l2em. le3mal le2mau le2m1ei 3lemes 3lemet lem1o2 le2mor 2lemp le2mu le4mun l4en. len1a len3ab le4na2d le4n3an le4n3a4t le2nä l1endp 4lendun l4endur le2n1ed 4lenerg le4neur 4leneuv len4gag len4kau len4k3lo len4klu l1enni len6sein 4len4sem len6serk len3ska len3sz 2lentg 2l1entk 4lentla 2lentn 4l3en4tro 4l3entw lent4wä 5lentwet 2lentz 2lenzy leo2f le1o4s 2lep 3lepa 3lepf 4l1e2pi 4lepoc lep4pi 3lepr l2er. l2e1ra le2rag le2r3ap le2ra4s le2rau le2r1ä le2r1e2b ler2ec l3ereig le4r3ei4m le4r3eis le2rel le4reng le4rerg le4rers le2re2t 4l3erfas 2l1erfo l2erfr l2erfü l1erg l2erga l4ergef 3lergeh 6lergen. l4erger l4erges 3l4ergew 2lergi l2ergl l2ergr lergro3 4ler4heb 4lerhol lerin4s lerk2 l2erka 2lerke l1erkl 4lerklä l4erkle l2erko ler3kr ler3l 5l6erlebe 3l4erlei 2lermä 3lerna ler4nal ler4nar 3l4erne ler4nei 2l1erö 3l2erra ler4ric l4ers. l1ersa ler4sto lert2 le2rup l4erwa ler4wer 2ler2wo 2l1erz ler2zä l3erzeu ler2zo l4es. les2am les2e le3seb lese1i 2l1esel le5s4h lesi1 le3s2k les4ki le3so le2spo lest6 leste3 lester6i 3lesu 4lesw 2lesy le2tab 2le2tap 2le2tat l1e2th le3tha 2lethi let2i letsche6 let2to2 lett1r lett1s4 le2u 4leue 3le3u2f 2l1eul le3unt 3leut l1e2vol 2lex 3lexd 3lexik le2xis 3ley 1lé 2l1f l3fah lf4at lfäs3 l2f1ec lfe1e lf3einh l2feis lf2en l4ferei lfe4rel lf1erl l3fi l3f4lä lf3led lflo7sses lf4lö l3f4lu lf3ram lf3res lf4ru lf4rü lf2spe lf2s1ti lf2su lfun2 lfur1 2l1g l3gas lga3t lgen2a lgene2 lgeräu3 l2geti l3g2i lg2lö l3go lgoa3 lg4p l3gra lg3re l3gro lgro3s lg2s lg4s3t 4l3h2 5lhi. 1li l4i1a lia2b li2ad li2am. li2ams lian2g li2ast 3lib4 libi3 li1c lich4ta lich4to 4lick li2cl li3d2a l1ido l2idy liebe4s3 lie2br 3liefer li3efl lie4n1a2 li3ene lien3t li2er lie4rei li3ern lie4s3c lie4sta lif4fes lif2fo lif3ti 3lig li4g3ers lig4n ligs2 li3ker li3k2o lik2sp lik4tau lik4ter lik2ti lik2t1o2 lik2u li3l lil2a li3m2a lima1c lima3t4 2l1imb 2limm 3limo 2limp lin2a li3nar 2lindi 2l1indu li2nef li2neh li2nep li5ner li2nes 2l1inf 2l1inh lin1it 2l1inj lin4kan lin4kar link2s li2nol l2insa 4linsel 2linsp 2linst 2linsu 2linsz 2l1int li3n2u 2l1inv 2linz li2o li4om lion5s li3o2st 3lipf 3lipt 3lis. li3s2a li3schm li4schu lis2h li3shi 3lisk 2l1isl 2l1i2so 3lison li2sp liss4 2liß lit4a l1i2tal li3t2ä l2i3t2e 3liter li1th li2t3r lit1s2 lit3se lit3sz li4tun li2tur litz4er 3liu liv2e li2vea li2ves livi3e li3vr 2lixi li4z3ä lizei3 4l3j 2l1k l3kale lk1alp l3k2an l3kap l3kar. l3ke lk1erd lke3r2e lk2l lk3lad l3k4las lk3lic l3k4lu lk2men lk4ne lk5ner lk3nu lko2f lk1ofe lkor2b lk3roc lk2s1 lk3sän lk4set lk3si lk4spe lkt2 lk2ü 4l1l lla2be l2labk l2labt l3labu ll3acht lla2de ll1aff lla3gl l2l1am lla2ma ll2ami ll2anb lla4ner l4lani l3lans. ll4anwa ll1anz l4l3appl ll1arm lla6tern l2lath l4latm l2l3att l2lau ll3aufg ll3aufk ll1au2s1 l4lausf l2la2w l2l1äm l3läs l2läu llb4 llch4 ll3d4 l2le2b ll5ebene l3lec ll1ech lle3er l2l1ef lle2gu lle2he l2leib ll1eic ll1eim l4l3eise lle2la lle2m l2l1emi l3len. lle4na ll3endl llen3dr ll3endu llen6dun l4lentf l4lents l3lep l3ler. lle2ra l3lere l6ler6eig ller4fo ller6geb l8lergene l4lergo ll3erho l4l3ermi l4l3ernt ll3ertr ll6erwei ll2es l3les. l2le2se lle4th l2leuc l3leur. ll1exe llg4 l2lieb l2lieg lli4gan l3lik lli4la l2l1ind l4linf ll1ins llin6sen l2lipo ll3k4 ll5m2 ll3n2 ll1ob l2lobe l2lo2d4 l2l1o2f llo2ge ll3ol l2lope ll1opf ll1or l6lorb llor2g l2lo2ri llo2te l2l1ou l3low ll1ox llö2g l3löh ll2säu ll2s1es ll3ska ll2spr ll4stor ll3t llt2e llt2i llti2m llt4r llts2 llu2d l2lu2me l3lung l2lu2p ll1ur llust6 l3lut l2lüc llü2d l2lü2g l3ly ll3z2 4l1m l2m3a2b l2m1ad lm1a2ge lm1aka l2m1a2m l3mana lm1apf lm1art lm3att lmä2s lm1ä4st lm1c lmd2 lm3e4dit l2m1ef l2ment l2m1e2p lmer2 l2m1erf l2m1erl l2m1erz l4messa l2m1i2d lm1ind lm1ins lm3m l2mof lm1orc lm3p2 lmpf4 lm3s2k lms2t lm3str lm3s2z lm3t4 l2mum l4munt 4ln ln2ab lna2r ln3are l3n2e lnes2 l2n1in lnus2 l1nü l1ny 1lo lo4ak 3lob. l2oba 3lobb lobe4s 2lobj l1o2bl l2obr lob4ri lo4chel 3lodr lo3dri l1ofe lo2fen lo4gh lo2gl lo2gor lo2gre lo3ha lo3h2e 4l1ohr loi4r 3lok 4l3okk lo2k3r 5loks l4ole 2l3o2ly lomä3 lo2min lo2ner lo4nin lo2n1o lo2o l1ope 2lopf lop2p1a lop2pr 2lopt lor3am lor2an lo4rä 5lorb 2l1orc 2l1ord lo3r2en 2l1org2 lori4di 2lort4 l2os. lo4sa 3lose lo4ske lo2spe lo2s1pr los3ta lo4stel lo4steu lo2s3to lo2s3t4r lo2ßu lo2t1a lo3tha loti4o lots2 2l1ov lo2ve 2lox 1lö lö2b3 2löck 2löd lö2f 2l3öfe 4lög 2l1öhr 2lök 2l1öl 2löp 3lösc 4löß 4löz 2l1p lp2ar lpar2k1 l4p1är lp2f lph4 l3phä l2phir lp1ho l3phr lpt4 l3pu 2l1q 2l3r2 lra4ss lrau2s lrebs2 lro2h lrö4 lrös3 4l1s ls3a2b l3sac l2sa2d ls2al l4s1amb l4samp l2san ls3ane l3sare ls3a2ri l3sark lsau2 lsau4m lsau4r l3s2äm lsä6s ls2äug ls1äus ls2c l4schin l4schmü l2s1e2b ls2ele ls1eli l2sent ls1er l2serf l2serg l2serh l2serk l2serl l2sers l2serw lse2t ls1eta ls3ha l2s1id l2simp ls2kal l3s4kele l4skla l4sko ls2ky lso4b l2sop l4s3ort. l3sos l3s2öl l2spac ls2pe l2s3ph l2s1pir ls2po l3spri ls2pu l3spul l2spun l4s3s2 lst2a lstab6 ls2taf l2stas l4s3tat. l4state l3stau l4s3täti l4st3erk l4s3terr l2s1tis l2stit l4stoch ls1tor l4stor. l4store l4stors l2s1trü l3suf ls1um l2s1un ls2und ls3unk 4l1t l3ta. l2tab lt1abs ltag4 lt1am l3tami ltampe4 l3t2an. ltan3d l2t1ap lt1ara ltar8beitn l3tark lt1art ltar6tik l3tartu lt1au l4tauf lt3aut lt1äh ltbau1 lt1eh lt1eig lt1ein lte3mi l3t2en lten6gel lten4sp l4tentl lt3ents lte4ral lter4fa l3t2erg l4terhe lter6ken lter4ku lter4nä lte2ro lt2erö lter4se l2t1esk l3t2est lte3sta lt2et l3tet. l2t1h lt3hag l3thas l4t3hei lthol2 l3t2hu lt1ide ltimo4 l3tin. l3tine l2tiso l3t2i3t l2t1ob l2t1o2f l2tord l2torg l2t1o2ri lto2w lt1öl l3tön lt1ös lt1öt ltra3l lt3räu lt3rec lt3rei lt3ris lt1roc lt3rol l2t3rö l2t3rus l4ts lt2se2l lt4s3ort lts1pe lt1s2ph lt4stec lt2sti lt3t lt1uh l2t1um lt2um. lturan4 lturen4 ltu2ri lu1an 4lu2b3 luba2 lub5s2 lu2dr lu2ec lu2es lu2et 1lu2f2 2l1ufe 2luff lu3fo luft1a luft3e luft3r lu2g1a lu2g1e2b lu2gei lugen1 lu2gi lug3l lu2go lu2g3r lug3se lu2gu 2l1uh lu1id. lu4ig lu1is. lul2ö lume4 2lumf 2lumg l1umh 2lumk 2luml l2ump 1lumpe lum2ph 2lumr 2l1ums lu3mu 2l1umw 2lumz 1lu2n 2l1una lund4 2l1unf 2l1uni 2lunr 2l1uns 2lunt 2lunw 4luo lu2pf l2ura lu2r1an lu2rat lu2rei 2lurg l2uri lu2ris l1urn lu2ro 2lurs l1urt lu4ru lu3sak lu2san 2luse lu2sp lus4s3a lus2s1c lus4sel lus3sen luss3er6 lus2s1o lus2s1p lus4s1t 1lust lu2sta lu2stä lu6sterl lu2st1o2 lu3str lust3re lu2s1u 4lu2ß1 lu2t1a4 lut3au lu2tä lu2t1e4g lu2tel luter2 lut3erg luter4s lu6t5ersa lu2thy 2luto lu2tob lu2t1o2f lu2top lu2t1or lu2t3r lut5schl 2lüb 3lübd lück4e2 lücker3 2lüd lüf3te lü2hel lüh1l 2l1v2 lva3 l3vl l3vo lv3r 4l3w4 lweis4s 2lx 1ly ly1a2 ly3c ly3es ly1l 2lymp 3lyn ly3no ly1o lys2 ly3t ly1u 2l1z lza2 l2z1ac l2z1ag l2zan l2z1ap l2zat lz1aus l2zäp l2zär lze2l l2zele l4z3enth l2z1ep l2z1er2h l2zerz l2z1id lzi4m lz1imi lz3l lzo2f l2zö lz3t2 l2z1u4fe lzug4s lzvol2 lz1w lz2wec l2zwu 1ma 3ma. maa2 m1ab m3a2bar m2abä 2mabb m2abe 2m3abf 2mabg 2mabh 2mabk m2abli 2mabm ma2br m2a3b4ra 2mabs 2mabt 2mabz ma3chan mach2e mach8terh mach8t7ers mach4tr ma2ci mack2s 2m1act mada2m m2adä ma2del ma3dj 2m1adm 2m1a2d4r ma4d2s ma1f4 mag2a ma2ge. ma2geb ma2gef ma2geg ma2gek ma2gep ma4ges. ma2get ma2gev ma2gew 2m1agg magi5er. magi5ers ma3gl 2magm ma3g4n 2m1ago ma3ha mahl2s ma1ho mai4s3e ma2ke. 2m1akt mal2ag mal1ak ma4lakt ma2lan ma2lau ma2lär 2mal2de m2aldi ma3le ma4leb mal2er ma4lex mali1 mali3e mal3lo mal3lö3 2mallt ma2lon ma2lop m2alp mal3t malu2 ma2l3ut 3malv ma2mid mam3m 2m1a2nal ma2nar 2m1a4n4at ma2nau 2m1anä 2manb man2ce 3man3d4 ma2net m2anf mang2 2man3ga m4angel 2m1angr m2anh 3manip 2manl m2anle 3mann 2manod man3s 2m1ansa 2mansä man4sh man2t1h 2mantr ma4n1ut 2manw 2manz m1anza ma2or ma2phr ma2po ma1q m2ara 4marag mar2an 2m3arb mar3g2 3ma1rh ma3r2i m2ark mar2kr 4mar2o maro3d 4marr mar6schl mar6schm mar6schr mar2sp mar2su 2m1arti ma3r2u m1arz m2as ma3s4a mas2e 3ma1s2p masse4n ma3sses mas6ses. mas6sest ma5sset mass1t ma3s2su 3mas2t ma2sti ma4sz ma2ta2b ma2tan ma2tä m3a2tel ma4t3erd ma4t3erz m4atme 2matmo ma2to ma4tort mat3se mat1sp matta3g matt4r mat3url 2m1au2f 3maul ma3un mau3r 2maus mau2ta m4ay ma1yo 1mä 3mäc mä3he 2m1ähn mäh1r 3män 4m1änd 2mäo 2m1äp mär1 mär2kl mär2z1 mä1t4r mäu2s1c 2m1b2 mbe2e mber2e mbe3ri mbert4 mbi3er. mb4l mble1i mb4r mbu3sc 2mc m3ch 4m1d m2dan m2d1a2s md1är mde2a m2dei mde2m m2d1emi m2d1ent mder2 m2d1erl md2ö md3ras md3s2e mdt4 m2d1um 1me me3an me3at meau2 meb4 me2ben 3mebr me1c medi3e4 me1e2m mee2n mee4r3ei 2m1eff mega3 me4gel 3meh meh6l3er mehrer4 2m1eif 2m1eig m2ei3l2 mein4da meiner6k mei6nerl 3m2einu m2eist me3lam me3l4ant me2l1au melb2 mel3d2 melde3i me2lek 2melem me2ler melet2 2melf. 3melk mel4k3ei mell2i 3melo me2lob mel2se melt4 6mel6tern 2m1e2mis 2m1emp 2m1e2mu m2en. men3ab me3nage me4n3an men3ar me4nas men3au 2m1endl menen1 4men4gag men3ge me2nim men3k4 men2on men4se. men4sem 6mensemb men4sen men4ser men4ses mensi4d men2so menst4 m4enta men4t3ak m4entei ment5eig men6t5ers 2mentn ment4sp me1o 2meou 2meö 2mepa 2m1e2pi 3m2er. me1ra mera3l mer2as me2r1e2b me4rens mer4err mer4erw 4m3er4gän merin4d merin4t 4mer4klä m4ersh mer5sm mer6stel mert4r merz6eng 3mes me2sal me2sä mes2e 4meser mes2po 2mes2sa mess3an mes6ser6g mes4s1o mes2sp mes2s1t mes1ta me2str me3su me3sze 3me2ß3 me3ta me3th meto1 me2tö me4trig met6t5en6d meu1 2m1ex me2xe 1mé 2m1f4 mfi2le 4m1g2 mgang4 mglim2 4m1h2 1mi mi1a mia2b mi2am 2m1iat mi1ä mibi1 mic1e mi1ch mi2ci mi3da mi2di. mi3dr 2midy mie3dr mi3ele mi4e3no mierer4 mie2ti mie4to mie2tr mi1f4 3mige mi3h mik1an mi3ke mi4kel mi4kens mi3k4l mi2ku 3mil mi3la milch1 mil4che mi3l2i mil3le mi3l2u 4milz m2im2a 2m1imm 2mimp min2ac mi3nak min5anze m2inde 2m1indu mi2nef miner1 mi4n3e4ri min2eu 2minfo min2ga mings2 2minh mi3ni mini3k4 mi3nod mi2nof 2m1inse m1inst mi3nu mioni1 mi1p 3mir. 3miri 3mirs 3mirw 3mirz 3mis. mi2sa mi4scha mi4schr mi4sch3w mise1 2m1i2so mis2pa mi2spe mis5sar mis4ser mis4st mi2sta mi3str 3misu mi2ß1 3mit mi2t1a mi2t1h mi2to mi2tr mi3tra mit3s2 mit5sa mit3ta mit3t2e mitte3s mi2t1u 4mitz mi3v2 2m1j 4m1k4 m3kn 4m1l2 ml3c m3le ml3f ml3k m3lo ml3p ml3s 4m1m mma3a mm3achs m2m1ak m2m1al m2mans mm1anz m2m1ap mm2app mm1art mmas4p mma2ß mm1aus m2mä4 mm1äu mmd2 m2m1e2b mme2c m2m1ef m4meh m2mei mm1ein mm3eise mme2l1a2 mme4lin mm2ene mmen6te. mmen6ten m4mentl m4ments m4mentw m2me2nü mme2r3a mme4rec mmer6geb mme2s1 mmes3a mme3sc mme4sz m2me4te m2m1eu mmga4s mmi3el mmi3m mm1inb mm1inh m2m1ins mm1int mm2is mmi3sc m4mita mmi5tw m2mo2l m2mor mm3p2 mmpf4 mms2 mm3sa mm3si mm3te m2mum mm2un mmu3r m2mus mmül2 2m3n2 m4nesi 1mo 2m1o2be 3mobi 2mobj 3m2od mo3de mo2dr m1of mo2fe 3mog 2mog. mo2g1al 3m2oh moh2a moi3r mo2k1l 2mol. mol3d 3mom mom2e 3m2on mo2nan mo2nä mon4dac mon4del mon2do mo2ner mon3s2 mont2a mon3th mo1ny 3m2o2o 2m1o1pe mo2per 2m1opf 2mopt mo1ra mor2an mor2d3a mor2dr mo2rei mor3g mor3t2 3mos mo4ska moster4 mo2sto mo3t2h mot4r mous2 2m1ox mo1y 1mö möbe2 mö2c 2mö2f 4mök 2m1öl 4m1p mpa3ne mpe2la mpe4lin mpe2n m2p1ene m2pf mpf1ef mp4f3erf mpf3erg mp6fer6ge mpf3erp mp6ferpr mp4f3err mp4f3er4z mp2f3l mpf1or mp2fr mp1haf mp1hos mpin2 m3plä mp3lei m4p3lem. m2p3len m2p3les m3pon mpor6ter mpot2 mps2 mp3sh m3pu 2m1q 2m3r4 4m1s m2san ms1as m3sat msau3e m2s1än msch2 m3se. m2s1e2d m2s1ef m2sein m2se2le mse2n m2s1ene m2sent ms1erf ms2erh mse2t ms1eti m2s1eu m2sex m2s1o2d mso2r ms1orc ms1ori m2spä m2sped m4spl ms2por m2spot m2spro ms2pu m4s3s4 m4stag m2stal m2stit m2sü m4sw m4szi 4m1t mt1ab mt1ak mta2m mt1ar mt3aug m2t1e2d m3tei. mt1ein mt1eis mt1elt mt1emi m4tenga m4t3engl m4tentf m4tentg m4t3en4tr m4tents mter2 m2t1erb m4t3erei m2t1erf m2t1erg mt1erh m2t3e2r4i m2t1erk m2t1erl mter4n m2t1ers m2t1ert m2teta m2t1eu m2t1ev m2t1h mt3ho m2t1i2d m2tim m2t1in m2t1i2r mti2s mtmen2 mt1ob mt1op m2t1öl mt1ös mtra4s3 m2t3ro m2trö m4ts mt2sa mts3chi mt3sco mt2s1e mt3send mt3s2ka mt3s4kel mts3tät mtt4 mt1um mtu3re mt3z 1mu mu1a 2m1uh mu3la 3muld 3mult 3mumi m1ums mum2s1p 3mun mundan4 mun6derf mu2ner2 4m1unf 4m3ungeb mu3ni mu4nin 4mu4niv 4munw 4munz mu4r1u2f 3mus. mu4s1a 3musc mu2s1o mu2sp mu3s4se. mu3s4ses mus4ste must4e mu2s1to mu2str mu2su muße3 mut1au mut2st 1mü 2müb 3müh mü2her mühl1a mül4len 3mün mü3s2si 3müt 2m1v mvoll1 2m1w2 mwa2 mwa4r mweg2 mwel4t3 mwu1 3my my1al 2m1z2 mzel4li mzu1 mzug4 1na 3na. 2n1ab 3naba na2bä n3abh 3nabi n3abk na2b3l na2bor na2br nab4rü 4n3abs2 na2bus 3na2c n4ac. nach1 nachen4 na5chen. n3achse nach3sp nach8t7ersc nacht8raum n1ada na3dab 3nade na3de. nadel1 na3den na2der 4n1adl 4n3adm n1a2dr 3na3e 2n1af na1fra nag2a na3ge. na2gem 4n1agg n1a2gi na3gin na3g4r 3n2ah na2h1a n4ahm 4n3ahn 4n3aho2 3nai nai2e n1aig 4n3air nai4re n2ais 2n1ak 3nakä 3nako na2kro 4nakt n2al. na2l1a2 nal3am na4lar na2lä 2n1albk n2ald nal3da nal3ei na4l3ent na6lerei na4ler4g na4lerm na4l3erw nales2 nal1et nal1ex nalg2 na2lid nal3la na2lop nal2ph nal3s n2als. nal3t2 n2alty na2lu 2naly n2am. na2mat 3name na3me. 4na2mei n4a3men 4n1a2mer na2mid na2min na3m4n 3n2amo n1amp nam2sp 2n1amt namt4s na4my n1an 4na2n4a na4nat n3a2nä 4n3anb n3and2 nan1eu 4n3anf 4n3ang 4nanh 2nani 4n3ank 4n3anl 3n2ann 4n3anna 4nano nan2o3b 4n3anp 2nanr 4n3ans 2nantr 2nanw n2anz. nanzen4 nan6zene nan6zeng nanzer4 na3ot na2per n1apfe 4napfel n3a2pr n1aq n1ar 5nar. na2r1a 2narc n2ard n2are n4are. 3nari n2ark n2arle 2narm n2aro na2rom n2arr n2ars 2nart n2arta n2arth na3r2u 3nas n4as. na4schw 4n1a2sp nas2s1c 4n1assi na2str 4na2sy nasyl2 3naß 3nat n4at. nat3au nat1ei na3ten na2t2h 4natm nat2o 4natom 5nator nat1r nat4sa nats1e na3tu n1au nauf4fr nau2fr 5naui 3n2aul 4nausb 4nausd 4nausf 4nausg 4nausl n2auso 4nausr 4n3auss 4nausw 4nausz nau3te 3nav nave4 navi5er. navi5ers 1nä 2näb 3n4äc 3näe 2n1äf 3näg nä2hi 3nähm 2n1ähn nä2hu 2n1ä2m 2n1än 2näp 2näq nä2sc n2ä6s3s 2näu 3nä1um 2n3b4 nbe2in nber2e nbu3s nby2 2n1c n2c3ab n3can n3ce4n n3ces. n3chl nch3m ncor2 n3cr n3cu 2n1d nda1f nd2ag n3dai n2d1ak n2dana n2dani n2danz nd1arr n3dat nd3att nd1au n2daut n2dax nd1äng nd1c nde4al. n2d1ede n3dee n2dei nd3elfe ndel3l ndel4sa ndels5en nde4mot nden3sk n4dentl n4dents nde3o2 n5der. n5deren nd2erh n5deri nder6läs nde4rob n4de4ros n6der6sat n3d2es nde2se ndes3s ndi2a3 nd1imm n2dof ndo4n3a n2dopt nd1or n2do2ri n2d3ott n2dö nd2ös nd4ram n2d3rat nd3rau n2d3re n2drif n2d3roc n2drod n2d3rö n2drui n2d3run nd4sene nd2spr nd3th ndt4r n2duns ndwa5re ndy3 ndys2p 1ne 3ne. ne2ap 3nea4s ne3at ne3au 4n3ebene ne2bl 2n1ebn neb4r 2nec 3neca 3nece ne2ch neck2a ne2dit 2nee neei2 ne3ein ne3eis neema4 neen2 nee1r neer2e n1ef n2ef. n2e3f2a 2nefr 2n1egg neg4l n1e2go neg4r n1ehe 2ne2he. 2nehem 2nehen2 nehe2r 3nehm 4n3ehr 2n1ei 3neia 4neic nei4dei nei4dr 4neier 3neigt 3neigu nei4la 4neing 4neinh 4neink 4neinl 4neinz 4neip neiss4 ne2ke 2n1eks nek3t2 2nekz ne2la nel3b n1e2le 4nelek 4nelem ne3len ne3lex nel2i ne3lid ne2lit 3nelk n2ell nel4la4 nel4lei neller6f nel4lif 3nel2o 3nelu 3n2em. ne3mas 4n1emb 4n3emp 2n1ems 4nemu 3nen n4en. n2en3a nen4am ne4nan ne2nä n2enb n2enc nen4dar 4n1endb 4n1endd 4n1endf n1endg 4n1endh 4n1endk n1endl 4n1endp 4n1endt 4n1endw nene2b nen3ei nene4m nenen1 ne4nene nen3erb ne2n3eu n2enf 4n1engb nen4gen 4n1engs 4n1engt n1engu nen4gun n2enh ne4n3i n2enj n2enk2 n2enm nen4nar ne2no4 nen3s4e nen3sk nen3s2p 5n2en3t2a 4n1entb 4nentd 4nentf 5n2enti 4n1entl 4nentn nen3to 5nentr 4n1ents 4n3entw 4nentz ne4n3u n2env n2enw nenz4er ne2o3b ne2oh ne2or ne2pen 2nepf 2ne2pi 2nepo ne2pos nept4 n4er. ne1ra ne2rab ne2rac ne2r3af ne2rag ne3r4al ne2ram ne2ran ne2r3ap n2erat ne6ratio ne3rato ne2rau n2erb2a 4n3erbe. 4n3erben 2nerdb ner4dig ne2r1e2b ne2rec n1erf 4nerfas 3nerfr 2nerfü 2ner3g4 3nergr n1erh 4n3erhö 3neri n2erj n1erk 5nerka n2erkö n2erli 2n1erlö nerma3 nermas4 n1ermi 2n1ernä 4n3erneu 2n1ernt n1eros n1eröf ne1rös n2ers. 2n1ersa 3nerse ner4sk 4n3ersts nert4 3nert. ne2rup 3n2erv 4nerwar 2n1erz n2es. ne2sal ne2sei ne2s1ev 2ne3sh ne3ska ne2s1of ne2s1or ne2s1pa 4n1es2si 2n1e2st3r 4nesyn 3n2eß ne2tab 2ne2tag net1ak ne2t1an 2ne2tap 2ne2tat ne2tau ne4te2l ne2th net3ha ne3ti ne4tin ne4tob net1s2 n2ett net3ta net3te net3tr 2n1e2tu net4zer net2z1i ne2u neu1c neu4ere neuer4f neuer4k neuer4r neuer4s neuer4w neu3g4 2n1eup neur2 neu2ra neu3t 3n2evi n2ew ne3wa 2n1ex ne2xi 5ney 3nez 3né 2n1f n3f2al nfalt2 n3f2ang nf4ar n3f2ä nfäs3 nfe2i n3f2en n3f2er nf2es n4fex nff4 n3fi nfi4le. nf4le nf2o nf4r nf3s2 nf2tan nf3tei nf2t3r nft2st nft4ste n2f1u 4n1g n3gabe ng1abt n2g1ac n2g1ad n2g1ak ng1a2me ng3anda ngang6st n2ganh n4ganl ng1ant ng1are n3g2ars n2g1a2v n2g1äl ng3d4 n2g1eif n2g1ein ngelb4 nge3l4ei n3g4en n5gene nge5nerw ngenmas6 ngen3s2 nge4ram n2g1erg nger4zä n3g4es nge3s2a ng3hu n2g1id ng2lad ng2läs n2glic ng4lok n3glot ngma7sse. n2gn ng3ne n4g3ni ng4nom ng2nu ng2ob n2g1op n2g1or ngo2ri n2gö n2g3rai ng4ran n2g3rat ng3roc ngro3s ng3rost ng2s1 ngs3an ng4s3au ng5schr ng4s3e4h ngs3pa ng4spar ng4stec ng3ts n2gum ngzei4t 4n3h2 nhe2r 1ni 3n2ia ni3alo ni2ar nibb4 nic4 ni1ce n1id 3n2id. ni3da ni2de 2nidea ni3dr 2n3idy n2ie nie3b ni1el nie3l2a nie4n ni3ene ni3eni nie4rei ni4erna nie4sa nie5sse ni2eu ni1fl niga2 ni2g1ab ni2g1am ni2g1an 4n3i2gel n4igen 2niget ni4gl nig3li ni2gn nig4sp nihi3 ni2kar 3nike ni2kel ni3kerh ni2ki nik3ing ni2kor ni2k3r nik3t4 3n2il ni3l2a ni3l2i nil3l 4nimp nin1 3nin. 3n2ina nin2ac ni2nal 3n2inb 2n1ind 2ninf 3n2ing ning4s 2n1inh 4n1ink2 3nino ni2nor 3n2inp 2n1ins 4ninse 4ninsu 4n1int ni3nu 4n1inv 3n2inw ni2ob ni3ok ni3ora n2ip ni4ron n1irr 3n2is ni4sam ni2san ni2sä nis3cha ni4schw ni2s1e ni3se. nis3el 4n3isol ni2som 4nisot ni2sp ni3spi nis5s4 nis3tha ni2stu ni3stun ni2s1u 2nit 3nita ni1th ni2ti 4ni4tia nit2o 3nitr nit3s nit4tec nit6tell nit6ter6g nit6t5er6k nit4tie nit4tra nitt4sa 3niu niv2 3nix 2n1j 4n1k nk1abr n2k1ac nka2ge n3kal n4kalg nk1ang nk1apf nk3art. nka3sc n2katm n2kato nk1aus n2kaut n2k1äh n2k1äp nk1ei nk2eil nke4lei n4kelem nkelma3 nkelmas6 nke4na nken4te n4k3erle nke4ros nk3ersa n3kesc nke2t nk1eti n2ketu nk1i2d n2kide nk1inh n2k1ins n4klade n3klag nk3leis n2k3len nk3les n3klin nk2lo nk4neb n2knis n2knit n2knu n2k1o4be nk1ope n2kopt nko2r nkord2 nk1ori n2k1ort n2köl nk4rab nk3rät n4kre. n2k3rel n2kren nk3rep n2krez nk3ro n2krol nk2sal nk2se nk3sen nk2so nks2ti nk3s2z nk2tak nk4terg nk4t3ern nkte3sk nkt2et nk2tin nkt1it nk2top nkt1r nkt3ric nk2tro nk2tru nkt4sen n2k1um nku2n nk1urh n2küb 2n3l2 nla3ge nle2ga nli4ne 2n1m2 n3ma n3mä nmen2s n5mi 4n1n n2nada nna2g n2nalg n2n1all nna3m n2nan nna3st n2nau n3nä n3nec nn2ei. n3nelb nne4le nne4na nn2ens nner4ei n6n5ereig nner4fü nner6geb nn4ergr nn2erh nn2erk nner4la nn2ero nne2rö4 nn3erwa nner6war nner2z nne4s1e n2ness nn2eu nn2ex nn3f nng4 n3ni nnk2 nn2o3b nn3obl nn3obs n2nof n2n1op nno2r nn1ori nn4sam nn3ser nn3s2p nnst4 nns3tat nn4stoc nn2stö nn3t2a nn2th n2n1uf n2n1unf nn1ur 1no 3no. no5at 3n2oba n2obel 2nobj no2bla n2oble 3noblo 3noblö 2n1obs nobu2 nobut3 3noby no1c noche4 noch4r 2nod no2de no2ed n1of no2fe 2noff 2n1oh 3n2ohe no2kel 2n3okk no3kr n3ole no2leu no4lig no2liv 2n3o2ly 3no3me3 no3mi 3nomp non2e n1onk n1ont 2nony no2o 3n2opa 3nopä no2per 2n1o2pi 2n1ops no3p2te 3nor. nor2a no2rad n2o3rak no3ral no3rar 2norc nor4da 3nordb nor4des nor2d5r no3r2e 2n1org 3norh 3n2orl 3norm norm2a nor3mal 3norö 3nors 2n1ort 3n2os. nos2e1 no3sh no5s2k no2sp 2nosti nost1r 2nostv nos2u no2tan no3tart no2tä not1e2i no6t5entr no2ter2 noterb3 no2tex not1h no2tho no2t3in no2t3op no2t3r not3tr 3nov 2n1o2x 3noz 2nöd 4nö2f 4n1ök 4n1öl n2ör nö4s3s 1n2öt 4n3p4 npa2ge npf4 npsy3 2n1q 6n3r2 nran2 nra4s3s nrau4ma nräu3s nrebe2 nre3sz nro2h nrö2s nrücker6 4n1s n3sabo n2sa2d n4s1a2gi n2sall n2salt ns3ane nsa2r ns2arg ns3ari n3sark nsa4s ns4ath nsau4r nsau4se n2saut ns2av ns2ax n2s1än ns2äug n2s1äus n3sche. n4schef nsch5eul n4schl. nsch2o nscht4 n3schu nsch7werd ns2cr ns1eb nse4ein ns2eh nse2ha2 nseh5ere n4seinf ns2ele ns3elem n2sem. nsen4sp n2sepo n2s1erf n2s1erg n2serh n3seri ns1erk ns1erl n4serle n4s3erne n2serö ns1ers n4sersc ns3ertr n2s1erw n2serz n4sety n2s1eu nsfi2l ns3hor ns3iden n5sim n6simp n2sini nsinn2 nsi2te nsi2tr n3s2kal n3s2kel ns2kis n3skle n3s2ky n5smara n2s1o2d ns1of n2soff ns4om n4s3ont n2sop n4s3ort. nsp4 ns2pac ns2pek ns2pel n5s4pen n4speri n2sph ns2pi n5spie n2spo n2sprä n4s3prie n2spro n2sput ns3s2 nst1ak n4stale ns4ta2n1 nst3ane ns4tar n2stas n4s3tat. n6staten n4stats ns2tau n5s2te. n4steif nst5eife nst7einhe ns4tem. ns4ten. n4stent ns4ter. nst5erge ns4tes. n5steu n5s2tic n4stilg n2stob n4stole nst5opfe ns2tor n4strac n4strad n6strieb n4strik ns4trun ns2tum nst3u2t n3suf ns2um ns1un ns2ung n2s1urs n2sut n3sy ns2zin 2n1t n3t2a3c ntak4ta ntal1a nta4lin n4t1all nta2lo nt2alp n3ta3m nt2anb nta3ne nt1ang n4tansp nt1ant n4tanza n3t2arb nt1ark n3t2arm nt1art ntar6tik nt3artu n2t1ass n2tath n3tatl n2tauf nt1äm n2t1äu nte3au nte1e nte3g6 n2t1eh n3tehe n2teig nt1ein n2t1eis nt1emo nt4en nte4na nten6te. ntera4 nte6r5eis nt4erh nt4erk nt4erm nt4ern ntern4e nt4ers nt4ert ntes2 nte3sa n2t1ess n6testri n2te2ta nteu3 nteu6eri nte3v nt1hel nt1hie n2thot n3thr nt4hu n2t5hum nt4hy nt2i ntim3p n2t3ind nt3inf nt3inh ntini1 n3t4lem ntmen2 ntmo4 ntni2 ntnis1 nto3re n2torg n4t3o4rie n2t1öl nt4ral ntras3s nt1rau nt4raum nt3rea nt3rec n3t4ree nt3reif n3trep nt4repr nt3rich n4t3rieg n2troh n3trop n2t3rü n4t1s nts2ah nts2p nts3par nt5spe nts2ti nt2sur ntt2 nttü3 ntu4re. nt3z 1nu 3nu1a nu3a2r3 nubi1 2nuc nude2 3nue nu2es nu2fe 2n1uh 3nuhi 3nui n2uk4 nu3kl n3u2kr null3eb nul4lin n2um. 2n3umb n2ume 2numf 2numg 2numl 3n2umm 4numr 2n1ums 2n1umv 2n3umz nu4n 2nuna 2n1une 3n2ung 4n3ungl 4n1uni n3unk 2nunr 2nunt 2nunv 2nunw 3nuo 2nup 2nu2r nur2i nurs2 nur2z 3nu2s nu3sc nu3se nu4si nus1p nu4ss nuss3er4 nu4s1t nu2ß1 3nut nu2t1a n3uto nu2top nu2t3r 3nuu 3nux 3nuz 2nü4b nür1c 1nüt 2n1v2 n3ver n3vl nvoran4 2n3w nwei4st 1ny. 2n1ya n2ya. 1nyh n1yo 1nyr 1nys 1nyw 4n1z n2zac n2z1a2g n2z3a2k n2zan nz3a4ne n3zani n2zar nza4s n2zat n2z1au n2zän n2zär nze4la nzel3l nzel6lig n6zenerg n3zeni n4zense n4zentl n4zents nz3erem n2z1erh nz1erl nzer4lö n5z4err nz5erste nzer6tra n3z4es nze3sk nze2t nz1eta nze3u2t n2z1id nzi2ga n2zinh n2z1ini nz1int nz1inv nz3le nzlei3 n2z1op n2zöl nzt4r nzug2s n2z1wa n2z1wä n2zwet n2zwir n2zwö n2z1wu ño1 ñor2 2o3a2 o4a3bi o4ac oa3che oa3chi o4ad oa3de oa3in o4a3ke oak5l o4a3la o4a3mi oa4n oan4a o4a3q o2a4r o2a3s 3oase oa4si oa4sp o5ass o4at oa3te o5au 2o1ä2 o1b 2ob. o3b2al obal3l ob2am ob2ar ob1auf 2o3b2ä 2obb ob2e 2obe. 2obea 2o3bec 2obef o2b3ein 2oben obe4na oben3d4 1o2ber 2o3ber. ober5eis ober3in oberin6g obe4ris 2obev 2obez 2o3b2i 3obj ob1la ob3lei 1ob3li 2oblo 2ob2lö ob2lu 2obo ob1or 2obö ob3rei 2obrü o4bs2 ob3sh ob3sk 2o3bu o4bunt obus3s 2o3bü o4büb 2oby 2oc o3ca oc1c 3occl o1ce och1a ocha2b ocha2r o1che oche4b o2ch1ec och1eh och1ei oche2l ocher4k ochi4d och3l och3m och1o ochö2f och3r ocht4 o1chu ochu2f och3u2t och1w o3ci oc4k ock5er6sc ock3sz ock3ta o1cl o3co o1ç o1d 2od2a od3ak od2dr o3de2c o3d2e3i odein3 ode4l3ag ode2n1 ode2s1e ode3sp od2et o3dex od2i 2o3dia 2odi3c 2odif 2o3dir 2odn o2don o2d1op odo4s od2ö 2odr o2dre odt4 2odu o3dy ody2m 2o1e2 oe4b oe3di oe4m oen1e oe3ri o2e3s oe4sc o2e3t2 o3et. o3ets 2ofa of1a2d of1a2g of2an of1au 2ofä o2f1e2b o2f1ec 2ofee o2f1ei 2ofem o2fent 2o3fer o4ferb 2o3f2es o2f1e2t 2ofeu of3eun of2fa4 of4fal of4fam off3erz of2f1in of2fir of2fix 1offiz of2f3l of2fo of2f3r offs2 off3sh off3si off3sp of2fu of2fü 2ofi ofi3e2i ofi3k4l 2o1fl of3le of3li of4lö 2ofo 2ofö 2o1fr of3rä of4rü ofs1 of2sa of4sam ofs2ch of2se of2si of2sp of4staf of2sto ofs2tr ofstra8ssen of2su 2oft oft2a of2tei of3th oft4r 2ofu of3ur 2o1g o2g1ab o2g1ac oga3d og1ang o2g1e2i ogel3dr oge2li ogener4 ogenmas6 ogerätein8 o2g1eth og2gl o3gh ogi2er ogin1 o2g1ini og3ins og1l og3le og2lo o3g4n ogoi3 og1o2ri og2s og3si og3s2p ogs1t 2o1ha oh1alk o1hä o1he o2h1eis o2h1er2t oh1er2z 2o1hi 2ohl ohl1a oh2la2d oh2lä oh3lec ohl1ei oh3lep ohler2 oh4lerg oh4l3erh oh4lerw oh3lo2 ohl1or ohls2 oh2lu ohm2a 1ohmi oh3mu ohn1a oh4nac oh3nee oh2ni 1ohnm oh2n1o ohn3sk 2o1ho oho2l1e ohol1o oh1o2p 2ohö oh3öl ohr3a oh2rel oh2rem ohren3s ohrer2 oh4rerg oh3ri oh4rin ohr1o oh2rol ohrt4r ohs2 oh3sa oh3t o1hu oh1w 2o1hy 2oi o1id. o3i2da o1ids o3ie o1i2m o1in o4ine oi2r o3isch. o4ische oi3se o1ism oiss2 oi4st o1i4tu 2o1j 2o1k ok2a oka3b2 o2k3ac oka3i oka2la okale2 oka6lere ok2e oki4o ok2la ok3lau ok1lä ok2li ok2o oko4pt ok2so ok2s1p ok3t2 o3ku 3okw 2ol o1la ol3abu olaf4 o2l1a2m ol1ant ol2ar o3l2a3s olast4 ol1a2v 4o1lä ol1ät ol2chr ol4d1am ol2dä ol2d1ed ol4d3eng old5ersa ol2deu ol2dim ol2d3o ol2dr 4o3le. o2l1ef ol1eie o2l1eis ol1emb oler2 ol1erk ol1er3t ol1ess ole3u2 ol1exz ol2fa ol2fem olf3ere ol2f3l olf1r ol2f3ra olft4 olgege3 olge4ne ol2gl ol2gr ol2i olie4n1 oli4er oli3k4 oli3tu 3oliv ol2kl olk3re ol2kro olks3 olk4sc olk4si oll1ac ol4la4d ol2l1ak ol4lang ol4lau ollä2 ol2läd ol3le. oll1eb ol4l1ec ol2lei oll3ein ol3lem oll3erh oller4k oll3erl oll3erw oll3ess ol2lic ol4li4st ol2lo2c ol2lo2g ol2lop ol2lö2 olls2 oll3sa oll3sp ol2lu ol3lus 4olo ol2of olo1p ol1ort olo3st ol2ov ol3s2k ol3te ol3t2h ol3ti o1lu olu2th ol2y 4o3lys ol2z1a ol3zan ol4z3ern ol2zim ol2zo ol2zw ol2zy 2om o2mab oma2bl o2m1a2ge om1alg om1all oma4n3er o2m1ang om2anr o4mante o2m1ap o2m1ar2s o2m1art omar4te o2m3a2sy omat2i o4matom o2m1au o3mä o2meb om1ebe o2m1ef o2m1ei o2mel o3meld omen5t6an o4mep omer2 om1erh o2meru om1erz omi2c3 omiet1 o3mig om1ind om1ing om1ins o2m1int om3ma om3mä om3m2e om3mu 3omn 4omo o2m3oa o2m1org om1o2ri om3pf oms2 om3sk om3t2 o2mum o4munt o3mus 2ona on3a2b on2ac ona3g o3nal on3ann onan6z5ei o2n1ap o2n3arb ona3th 4onatol onat2s o4n3at4t on2au 2onä on1äh 2onc on2dan onde8rers onderer7t ond1r on2dra on4drin ond3sk 2one on1ec o3nee o2nef o3neig on3ein on1ema one2n1 o4n3ends on2eng on1ep o3ner. on1erb o2n1erd oner4fa o2nerh on4erka on1ers o3nett on2eu on3f2 on3gl ong4le ong4r ong3s on2gue 4o3ni on2i3d onie3g oni2ga on4ik o4nikr o4nim o4nind o4ninh o4nins on3k4 3onke onli2 onli6n onlo2c onna2 onna3g on3n2an on3n2e 2ono1 o3nod o2nof ono2i o2n3oke o3nom on1ope on1orc on3ord ono3s ono3t2 onrad3 ons1a2 on2seb onsen1 onse2t on4sho onsi2d ons3ing ons3l ons1p onst2a ons3tie onst4r on3ta on2t1eb on2te2l ont5end on4t3erl on2th on4t3rat 2onuk o3nur 2onut on3v 1ony o3ny. on3z2 onze3in o1ñ oo1c ooch2 oofs2 oo2gl oo2k3l oo2kn oo2mo oo2ne o1op oop2s o1or oor3d oo4sk oo2su oo2t1a oot1ei oo2t1h oo2tr oot2s1t oot3t oo2tur 2o1ö2 2op. o1pa op3adr op1akt opa2le op1ang 2opax 2opä o1pec o1ped op1ef o1pei o1pek 2open o2pera op1erh o1pes 2opf. op2f3a op3fah op2fä o2pfe op2fem op2fin opf3la op1flü op2fo op3for 4oph2 o3phe o1pi opi5a2 opi3er. opi5ers. opie4r3u opin2 2opl op3lag o2p5le o3p2n 2opo opo2la op2pan op4pl 1oppo 2oppt 2o1pr 3o4psi op3sz 1opt4 2opte op3th o2pum 2opy 2o1q 2or. or1a 2ora. o1raa 2or3a2b o2rabb o2r3add or3adr o1r2ag o2rak 1orake o1ral oral5l o4r3alm or4alt or2am or3a2mi o1ran3d4 or4ane oran2f oran2m oran4ze or3ap 2orar o1r2as o2ratt 2orau4 orau2s oraus6wa or2av 2o1raw o1ray o3rä or1änd or1ät orb2l or1c 2orca or2ce 2ord. 2orda ord1am or2dar or2dau 2ordb ord3eng orde4s or2deu or4d3ing or2d1ir or2dit 1ordn or2do4 2ordr ord3t 2ordu 2ordw 2ore ore2a o2r1e2b o2r1eck ore2di o5ree o3ref or1eff ore2h or1ei o3rei. o3reie o3r2eif o3r2eis orems2 o3renn o3rep o2r1er o3r2ere o3r2ero ore4th o2r1eu 2orf or2fac or2far org4a org2e 2orget or3ghi 2orgia or2gl or3gla or3gle or2gn or3gne 2orgr 2orh 2o3ria 2o3r2id orid3i 4o3rie. o3rien. o6rienti o3rier o3ril or1ima ori4mi 2o3rin1 o4r1ind o4rins 2or4io o2riso 2orit 2ork ork4r ork3s 2orm or2mam or4mang or4mans orm3asp or2m1eb or4m3erf or4m3er4g or2mor orm3ord or2mum ormu4n or4muni or4munt ormvol4 ormwa5 or2n1ac or2nal or2nan or2nar or5ne. or3ni or4nin or3no 2o1ro o2r1ob or3oly oro3n2a or1ope or1opf o2ro2r o3rou or1ox 2o1rö 2orp 2orq 2orr orr4a or3r2e 2ors2 or3s4a or3sh or3si or3sk or3sz or2t1ak or2tan orta2r or2t1au or2tef orte4n or4ten5g ort3erb or4t3ere ort3erf ort3erg or4terk or4t3erl or2t3e2v or2the or2tin or4t3off or2t1o2r or2tö ort3rad or4trau or4t3räu ort3re or2t1um 2o3ru or2uf or1uh orum4s o4r3un oru2r o5rus3 o2rü or3z2e orzel5 or2zw o1s 2o3s2a os3ad osal2 o4s3ami 2osc o4s3ca osch3ar o3sche osch3le 2ose ose1e ose1in2 os2el ose2n o2s1er2k os2ex 2osh o3s2hi os4hu 2osi os2im o3sk os2kal o4ski 2os2kl 2os2ko o4skr o4sky 1osm os4mog 2os2o osol1 o2sö 2osp os1pec os3pero o3s2po 2oss os6s3ac oss3ala oss3and os4sä o6ssel o3ssem. oss5enke o3ssent oss3enz oss1ep oss3er4b osser4e osser4f o4ssi os2s1o2 os2sp oss1pa os2s1t os2su os2t ost1a o3stal. ost4art ost3aut oste2n o4s3tep o4sterd oster3e ost5erwe oster8wei ost3eur ost1h o2stid o2stin os3ton osto4s ost3ran o2st3rä ost3re ost3rot os4tru ost3uf 2osu4 os1um 2o3sy o3s4ze 2oß o2ß1el o2ß1ent o2ß1en2z oßer2 o2ß1erb o2ß1ere o2ß1erf oß1is oß1u 2o1t o2t3abi ot1ah o2t1ak o3tal o3tam ot1ant o3tark o2tarz ota4s ot1ast o2t1au o3tau. ot2ax ot1ä o2teb ote1i o4t1eib o4t1eic otei4n o4t1eis ot2el ote4l1a o3tem o4t1emi ot2em3p2 ote4na o4tentb ot1erb o4t1er2l o4t1erw ot2es ot2har o2them o2t1hi o2thr 4oti o2til o2t1i2m ot2in ot3inh o4tl otli4 ot2o oto3b4 ot3off oto2ph o2t1ö otra3c o3t4ran otra4s3 ot3rat ot4rau ot3re ot3ric ot4rig ot3rin ot3rus ot2s3at ots1o ots1p ots2pe ot3s4tra ott3akt ott3an ot2t1a2s ot2tau ot2teb ot4terh ot4ter4k ot2t1h ot2tim ott2o ot2t3r ot3t4ra ot3t4ru ot1url ouff6 ou1f4l oug2 ou4ge ou3gl o1uh ou1is. 2oul ou2le. ou2les ou4li 2o1um 2o2u2n oung5 oun4ge. oungs2 o4up 4our oure2 ou2ret ouri4e4 ourme4 our4ne. ou3sa ous2i ou2s2t o4ut ou3ti 3outp out3s2 outu4 2o1ü o1v ov2a 2ovel o3ven oviso3 2ovo 2o1w o2w3al o3wec o2wh o5wi o2wu 2ox. o1x2a 2oxe o2x1el 2oxk ox3l o1xo o2x1u 1o2xy o1yo o1z2 o3za 1ozea 2o3zen ozen4ta ozes4sc 2o3zi ozir3 ozon1a 2ozy oz3z ór3 órd2 ö1b ö3b4a öb2l ö2b3le ö2b3r ö1ch öch3l ö2chr öchs2t öch6st5ei öchst3r ö1d öde1r ödi3 1ödu ö1e 1öf öf2fa öf2fl öf3l öge3le ögen4s1 ög3l ög3r ög2s ö1he öhe4n1 öhl2e4 öhre4 öh3ri öh2s ö1hu ö3ig. ö3isch. ö1ke 1ö2k2o3 ök3r ök2s ö2l 3öl. öl1a2 öl1ei öl1em öl2f1ei ölf2er öl1in ölk4e öl2k3l öl2la2 öll1an 3ölm öl2nar öl1o2 öls2 öl3sa öl3sz öl3tu 1ölu ölz2w ö1m öm2s ön2e ö3ni önizi1 önn2e öo1 öo2ta öoti1 2öp ö1pe öpf3l ör3a2 örb2e ör2b3l ör1c ör2dr ör3dra ö2r1ec ö2r1ei ö2r1e2l ö2r1e2m öre2n ö2r1ene ö2rent ö3r2erb ö2r1er2e ö2rer2f ö2rer2g ör2erh ö2rer2l ör2err ör2erw ö3r2erz ör1ess ör2f3l ör2gl ö2rim ör2kl örn2e örner4v ör1o örpe2 örs2e ör3sk ört2e öru4 ö2r1une ö1s ö2sa 2ösc ö2sch3a ösche2 ö4sch3ei öscher4 ö6sch5erf ö6sch5eri ö2schi ö2sch1l ö2sch3m ö2schn ö2schw ös1ei ö2sein ös4en ös4es 2ösl ös2o ö2sp ö3s2s ös4s1c ös3set ös4st ös4t ö2st1a2 ös4u ö1ß ößen3 öß2ti ö1t ö2t3a öte4n1 ö2t3r öt2sc öt2tr ö1v2 ö1w ö1z öze3 özes4 1pa. 1paa p1ab p2abe pab2l pab4rü 2pabw 1pac 1p2ad pa3el pa1fr 1pag4 pa3gh pa1ho 1pak pa3ke pa1kl pak2to 3pala pala3t 3palä 3pal2e pa3l2i 1palm pal2ma pal2mä pal2m1o 2palt pal2t1a pal4tei pal2tr pa2m3a pa2nar pa4n3at pan3d pand2a pan4ds pa2neu panf4 pang4 pa4nisl pank4 2panl 2pann panne2 pan4n3eb 4pannu 1pa2no pan3sl pan3t2h 1panto 2pantr panz2 pan3ze 1pap papi2 papieren8 papie8r7end pap2pr pap2s papst1 pa1q 1para pa4r3aff par3akt pa4rant pa3rap pa2rä 2parb 1p2arc par3d parer8geb 1parf 2parfö pargel6d 1park. park3am par4kau par4kr 1parks par3m2 par3ne 1pa2ro 2parp 2parr 4parta 3partei 1parti 1partn 3party par3z pa1sp pa2spe passer4 pas6serg pas2s1p pas2t pa2ßu pat1a pat4c pa3t4e2 2patel 1pat2h 1pati 1pat4r 1pau 2p1auf pa3uni 2pausz 1pav 1pä 3päc päck3er 3päd päde2 pä2d1er 3pär 3pä4s3 pä4t1e2h pä4tent pä4tep pä4t3erb pät1h pä2to pä2tr pät5s 2p1b pbe1 2p3c 2p1d2 pda2 1pe. pe2a2 pea4r pea4s p1e2b pech1 1peda 1peel pe2en 2pef 4p1eff 1peg pege2l pei1 2peic 1peil p2eim 2peis 1peit pekt2i 1p4el 3pel. pe4l3ab pe4lai pe2l1au pe2l3ax pe2l1ä pelb2 pel3d4 3pele pe4l1e2h pe2l1er pe2let pe2leu peli2d peli4n pe4l3ink pel3inn pel4ins pel3k pel3l2a pel3lä pel3l4e pell2i pe2lob 3pels4 pel3sp pel3ta pel4zin 1pem 1pen pena2 pe4nas pe2nä pen3d2a pe4nen1 pe4ni2t pe2n1o2 pens2 3pen3si pen3so3 pen3sz pent2a 2pentw penty2 pe2nu2 pen3z 1pep pe3pi pe1ra pe2rak per2am pe2r1ä per1e2b perer4f pe3r2id 3pe3r4io 1perle 1perlh perra2 per4r3an per4rä2 per4ric per6rieg 1pers 2perse 2persi 3perso 3persp peru2 pe3run 1perü perwa4r pe3s2a pese2n 1pes5s2 pes2t pest1o pe4stop 3pet pet4r 1pé 4pf. p2f1ab p2fad p2faf pf1ai p2f1ak p4f1am pf1ans p2fa2r pf3are p2f1au 1pfä p2fär p2f1äu 4pfe. p2fef p2fei pf1eim pf1ein pf1e2m p3fen. p4fener p3fens p3fent p4f1ep pfer5a p4ferde pfer6pro pf4es p2f1et pff4 pffa3 p2f1i2d pf1inn p2f1ins pf1lam pf4lan pf4leg pf3lei pf3lo p2fob p2fom p2fo2r pf1ori pf3r pf1ra pf4rü pfs2 pf3sa pf3se pf3sl pf3sz pf3t2 pft4r p2fum 2p3g2 pgra2 1ph 4ph. phal4te p1hand 3phas p1hau phä1 3phän 4phb 2phd 2p1hei phen3d2 phe4n1e phen3s 2ph1ers 4phf 4phg p2hid phik1a phi4kan 2phk ph2l 4phm 2phn p2ho. p2hob pho2s 2phö ph2r 4phs ph3t2 2phthe phu4s phu3t 2p1hü 3p2hy 4phz p2i2a1 piab4 pia3k pi4ali pia3n piap2 pia3s pi1ce pi2e1i pi2el piel3a 1pier pie2ra pie4reb pie4rei pies4 1pig pi3gl 1pil pi3le 3pilo pil4zer pil2zw p2im 3pin. pi2nad 3ping pingen4 ping3s 3pins. 3pinse pin3s2p pi2o pi3oide pi3onu pi3os 1pip pi2pe 3pirate pi3ri 3pirin 1pis 2piso pis2t pi3sto pit2a pi3t2h pit2s pit3z2e pi2z1in 2p1j 2p1k2 pku2 1p2l2 2pl. 3pla 4p3lad p1lah pla3na p4lau pla2y1 2p3le. ple1c ple2e p4leg ple3n2 2p3ler p4leu 2plig 3p4lik p4liz plo3n 2p3lu 2p3m2 2p1n2 1p2o pob2 2po1c 3pock 3pod 3poe po2el 2poh po2i po3id. po3ids 3poin 3pol po2lan po2l1au pold2e po3li pol3lo po3lo3p pol3z2 pom2ph 2pond pont2 po1ob po2p1ak po2p1ar po2p3l po3p2t po1rau porf4 3portal por2t1h 3portio 3porto. 3portos 3portr por4tre por6tric 3posi pos3s2 pos4t po2sta po2stä post3ei po6stein po4stem post3ra po2ta pot1ar 3potä 3pote pot2h po2t3in pott1r po2t1u po3un po2w powe2 po3x pö2bl pö2c 4p1p p2pab pp1ang pp1ans ppa2p p2pat pp1au ppe3e p2p1ei ppe2l1a ppeli5ne pp2e2n1 p2p1erz p2pf4 pp1fr p2p1h pp3he pp3l p4p1lac p4plan p2p1lä p2ple pp3oh p2p1ö2 pp3p4 p2p3ra p2p5rä pp3ren p2pri pp3rol pp3rot p2p3ru p4ps2 pp3sa pp3sy ppt4 p3puc p2pul p2p1um p2punk p3pur ppyl2 p2r4 1prak pra4s3 pra5sp 1prax p4rä 1präd 1präf 1präg 1präl 3präm 1präp 3präs 1präv 2pre. 2prec 3pred 2pree1 pre2ei 2preg 1prei 3preis prei4s3c prei6sei prei4ss prei4s3t 2preiz 1prem pren4ga 2p3rer 1pres pre3sa press4e 1preß pri4e 2prig pri2l1 2pring prings4 1prinz pri2t1 priter4 prit3t4 1priv 1pro1 3prob pro3be 2proc 7prod 3prog 3proj 2pross 2proß prot2e 3proto 2prott pro3x 2prö 1prüf 1prüg 2prüh 2prün 2p1s 4ps. ps3k ps1od p2sö ps4pi pss2 pst1au p2stu 3p2sy 4psys ps2ze 2p1t pt1a pt2ab pta2g p2t3a4t p3te. p2t1e2b pt3ec pt1ef pt1ei pt1emi 4p3ten p4t1en2g p4t1ent pt1ep pt3erei pt1erw pt1erz p3tes p3tet p4teta p4t1e2ti p2t1h pt1id pti2de pt1in1 pto2mo pto4na pto2p pto2w ptpo4 pt3r p2tro pt1s2 pt3si pts4t pt1uh pt1um p3tung pt1urs p2tü4 3p2ty pt3z2 1pu pu1a pub4 2puc pu2dr 2p1uh 2puk pu2kl pu2k1o pu2lin pul2sp pul2s1t 3pulv 2pulw pum2pl 4pund pun2e pun2s 2punt 3pup 2pur pu2ra pu2rei pus2h pu3she pu5t2e 3put2s 3putz puzi3 1püf pül3l 2p1v 2p1w pwa4r 3p4y1 py3s py3t 2p1z2 qu4 quel4la que3rel quer5n que4te. 1queu 1ra. r1aa ra2ab 2raac 2raal ra3ar r2a1as r1ab ra2b1ar r2abä 1rabbi rab2b3l 2rabd ra2bei rab2er rab3erd 2rabf 2rabg 2rabh 1rabi 2rabk r2able ra2bli ra4b5lo 2ra2br 2rabs2 2rabt 2r3abw 1raby 2rabz ra2ce 2r1acet ra4cheb ra2cho 2rachs rach6t5rä ra2chu r2ack 1r2ad r4ad. rada2 ra2dac ra4d1am ra2dan 2radap 3radar ra2de4i rade5s 3radf 3radh 3radio 4radit 3rado 3radp ra4d1r rad5ri rad3t4 r2af raf3ahn raf3ar rafe2 ra2f1er raf3r rag2a ragein4 rages4 2ragg ra3g4le 4ragm ra2gn r2ago rahle4n 5r2ahm r1ahn 2ra1ho 4raht r2ai 2raic rail2l 2r3air raka3 1ra3ke 2rakk 3ra1k4l ra2kre ra2kro 2rakti 1rakü 2rakz r2al r4al. ra2la2 ra4l3ab ral1ak rala4s ra2lä ral3b4 3r4ald r4ale ra4l3end ra4lent ra4l5ern ra3lex r4ali ra2lid rali3er ra4lin4d ra4l3ing ralin6sp ralin4t 2r3alk. 2r3alm. 2ralp. 4ralpe r4als ral3su r3alt 3r4al3t2h ra2l3u 3raly ra2mei ra2mer r2ami r2amm ram4man ram6mens ram6m5ers ram4mit ram4mu 2ramn 3ramsc 2r1amt ramt4s 2ramu 2rana ran1ad ran3ade r1a2nal ra2nan ra2nar ra2nau 2ranb r2anbe r4anda r4ande ran4dep ran4d3er 3r2andi rand3s 1raner 2ranf 2ranga ran6g5e6be 3rangi r2angl rangs2 rang3sp rani3e r3a4nil ran3ka ran2kr ran2kü 4ranl 2r1anm r2anmi r2anmu 2ranna ran5ne 2r1anp 2ranr 2rans r2ans. ran4spa 4r5antei r1anth r2anto 2rantr 1ranu 2ranw r2anz. r2ap 2rapa ra2par 2rapf 2rapo ra2pok rap2pr 2r3a2pri 2r1aq r1ar r2ar1a 2rarb r2are 3r4arei raren1 rar3et rar1e2v r2arf4 ra3rie rar3in ra3ris r3a4rist 4r3arit r2ark raro2 ra2rom 2rart 2rarz rar3zw ra3s2 r4as. ra4schl ra4sk r2asm ras3si ras3sp r2ast ra4st3ei r3asth ra4sto ras3tri 2rasyl 2raß 1rat ra2t1an ra2t1ei r3a2tel ra4tid 2ratla 2ratm rat2o 2ratom rat4r r3att 2ratta 2rattr 4ratz rat3ze 4rau. 3raub. 4raue rau3e4n 2rauf rau3fä 2rau3g2 3raum rau4m3ag rau5mes rau2mi 3raup 4raur 2rausb 3raus2c 2rausd rau3se 2rausf 2rausg raus8gewä 2raush 2rausl rau2sp 2rauss raus8sche raus3tr 2rausv 2rausw rau3ße 2raut raut1r rau4tra rau4tro raut5s 1raü r2ax raxi4s r3axt r2ay ray1o r2az räch4s 3r2äd 4räf rä1fr 4räg 2räh 4räm 3rän. 3räni 3räns 2räp 2räq 2r1är r2är. rä3ra rä1ro rä2sc räse2 rä5sse rä2st 3rätse 4rätz rä2u 4räue räu2s räus2c räu7schen. 2räuss 2räuß 4räut 2räx 4r1b r2b3a2b1 r3bac rba4del rb2al r3bam r2bang r2bant rb1art r2barz rb1auf rbb2 rb1ech rbe3erf rbei3d2 rbe3inf rb3einh rbe3int r4belä rbel2o rbe3r2e rber6gin rb1erl rbe3rum rbe5sl r2bim r2binf r3bit rbit2a rbi3tu rb2la rb4la2d r2blan r8blasser r4b3last r3blat r3blau r2b3le. r3blen rb3ler r2bleu rb2lin rb2lö rb3lös rbmas3 rb2ob r2bonk rb3ras rb3rea r8b7rechts rb4sam rb2sei rb2ser rb2s1o rb4stä rbs3tri rb2su rb4sz rb2u rbü4b 2rc r1ce r1che. r1chen r1ch2i rch3l r3chlo rch3m rch3r rch4ro rchs4 rch3sp rch3t2a rchter6r rch1w r1ci r1cl r1ç 2r1d rd2ac r2daf r2d1ak r2d1a2l rd2amm rdani1 r2dann rd1ant rd1ara rd1ark r2darz rdär2 r3de. r3dee r2dei rd2ei. r2d1elb r2de2le r2delf rdels2 rdem6 rden3d2 r4dengl r4dents rde3ob rde3ono rde3r4er rderin6s r4d3ernt r3des rde3sp r2d1e2x r2d1inn rd1iri rd1ita rdo2 r2dof r3don rd1os rd3oss r2d1oz r2dö rd3rat r2drau rd4ri rd5ris rd4rö r3d4rü rd2sän rd3s2k rd3s2z rdt4 rd3ta rd3th rdt2s r2d1uk rdwa6r 1re 3re. rea2d rea6l5erw 4re2am re3at. re3ats reatu3 2reä re2b1a re2b1l reb1r reb3ra reb3so rech3ar 4rechs 2reck. 2recki 3red. 4redd 2redi re2dik 3redn 3redu re1ebe re1el re1em ree4mi re1er 3refe 4reff r2eff. 3refl 3refo 3reg rege4l3ä regene7ra 4r1egg re2hac re2h1ar re4hen4e re4h3ent re2hi reh1l4 re2h1o re3hol 3rehö reh4th re2hü r2ei. r2eib rei4bel rei4ble r2eic 2reid r2eie 4reier. rei4fei 4reifel 2reig 3reigä 3reigeh r4eigel 6reigens 3reigi 4reign 3reigru rei3l2a rei3l2i 2r1eilt 3reim reim2p r1ein 2rein2a rei3nal 2reinb rein4du rei3n4ec reinen5 2reinf rein4fe re4info 2reing 2reinh 4reinn 4r3einr 2reins 4reinsa rein6sel rein8s7tre rein4sz 2reint rein6teg re1in2v 2reinw 2reinz 4reisar 4reisb 2reisf 2reish 2reisr reister6 4reisu 2reisw reit3s2 3rek 4re2ke 4rekk 5rekn 2rekz r2el. r2ela re3lat 2relb rel2e relea4 re5lei re2lek 4relem r2elev 2relf reli1 2relit 2relix r2ell rel4lar rel4lei re3lo r2els 2relt relu2 3r2em. 2r1emb rem2da re2m1ei re5men 2remi re3mig 2rempf rems1c rem4str 2rem2u r2en. r2ena 2rena. re4nac re3nad re3nal re4n3an re2nä r1endg 3rendi ren3dr 4renerg 4rengag ren4gan 2rengp 3renh re2ni 3renm ren4nar ren6nene ren6sein rens2p 2rentd 6rentera 2rentf 3rentfo 2rentg r3enthä 2r1entl 2r1ents 2r3entw 2rentz r2enz ren6z5er6f renzer6l ren6z5er6s renzer6w ren4z3in ren2zw re2ob re3or 3repe 4re2pen 2repi re2pis 2repoc 2r1e2pos 4repp 3repu 3r2er. rera2 2r1erb 3r4erber rer2bi 2r1erd rere2 4r3ereig r1erek re2r1ep r2erer r1erf r3erfa 4rerfah 2rerfi 2rerfo r2erfr rer2fü r1erg 4r3ergeb 5rergebü r4ergen 3r4erges 2rer2go rer2gr r4ergru r1erh rer2hö re3ri re4rid r1erk rer4kan rer2ke 4r3erken 3r2erki 3r2erko r1erl 2r3er2la 5r4erlag r3erleb r2erli 2rerlö 2r1erm rer2n 2r1ernä r1erne 2r1erni 4r3erns 4r1ernt re1ro re2rob re4rosi 2r1er2ö r1erre rer4reg rer4rei r1erri 5r2ers. 2r1ersa r6erschi r2erse 2rersp rer4sta r6erstad 2rer6su r1er3t4 r2erte 2rertr r1erw rer4wac rer4wec r4erwes 2r1erz rer2zä 3r2erzy 3r2es. re2sa re4sam resche4 re4schw 3rese re4se2h res1of 3resol 3reson res2po 2ress 4resse res3sei res6s5erw res4sto 4ressu resten4 re6stent re4stra 2restu 3resu 2re2ß1 re2t1ak 2re2tap re2tau ret2e 2r1e2th re2tra re4trol re2u reu4eri reu3g2 2reul re3uni 2reur 4reuu 2reü 4r3eva 2r1evid rewa4r re2wi 2rewo 2r1e2x1 3rez 2rezi 1ré 4r1f rf1ack r3fahre r5fahrt rfall4s rfäs3 rfe2i r2fent r3f2es rff2 rffa3 rf3fe rfi4le. r4fland r3f4lä rf3lic rf4lö r3flü r2fo2b rfolg4s r5foli r4frauc rf4ru rf4rü rf2sa rf4sam rf2s1ä rf2su rf2ta rft4r rf2u rfzu3 2r1g r2g1a2d r2g1ah r2g1ak rga4ner r2g1ap r2garb rg3art. r2g1ask rgas2t rga5stes rgd2 rge4an rge2bl r2g1e2c r3gel r4gelef rge4l3er rgen4z3w r4ge4tap r2geto rgi4sel rg2lad r2glan r3glanz rgleich8s7 r2gleu r2glig r2g3lit rg2log rg2lu r2g3na r2gne r2g3ni r2g3no r2g3oa r2gob r3gog rg3op r2g1or rgö2 r2g1öd r2g3ral rg4rau r2greg r2g3res r2gret rg3rin rgro5sse r3grun rg3rüs rg3se rgs2ei rg4sel rg3s2i rg1sp rgs2pe rgs2po rgs4ti rgs2tu rg1su r1h4 2rh. r2hag 2rhah 2rhak r4haltb r3han 2rhau 2r3hä 3r2he. r3hea 2rheb 2rhef 2rhi 2rhol r3hop 2rhot 2rhöl 2rhs 2rhü 1ri ri1an ri2ano ri2ast rib2bl ri1ce ri1cha ri3chl richt8spo 3richtu ri2con ri2dau 2ride ri2d3e2l ri4dent r2i3di 2ridol rid3r 2ridy r2ie rieb6ste 4riefm rie2f3r rieg4s3 ri2e1i riein1 ri1el rie3l2a ri3els ri4enä riene2 ri3eni rie2nu ri1er. rie3r2e riere4n ri3ers. ri1eu ri2f1a ri2fä ri2fei ri2fer rif6f5end rif4fer ri2f1o ri2fr rif4ter 3rig 4riga 4r3i2gel ri4gene 4rigg 5rigj rig1l ri4glä ri3g2o3 4rigr 4rij ri2kar ri2kä ri2kin ri2kn ri4kone ri2kor 2rima ri2mag ri2me. 2rimm 4rimp rim2s ri3na r1inbe rin2c 2r1indu ri3n2e rine1i 2r1inf rin2fo 3r2infr r2ing rin2ga ring3le rin2gr ring3sp 2r1inh 2rinit 4rinj 4rink rin2kl rin2ko rin2kr 2rinl 6r5innenm 4r3inner 2r1innr r1innu 4r1in2q 2r1ins rin2si rin2so r4inspi 3r2insy 2rint 4rinte rin6tent rin4t5re 2r1inv rin2va 2rinz ri2ob r3ion ri3o2st ri2pl ri3po 4r1ir r2is ris2a ri3s4an ri4sch3o ri4schw 3risik ri3s2ko r3iso ri4s3p r3isr 3riss ris2t rist5ers ristes4 ri2st3r 3ri2ß1 r2it r3i2tal rit3ant rit2i 2ri3t4r rit1s rit4t3au rit4tei 3ritter rit6ter6f rit2to rit2t3r rit2u r1i2tum rix1 ri3xi 1rí 2r1j 4r1k rka2b3l rk1ah r2k1ak rk1all rk2am rk1are rk1asp rkauf4s r2k1äh r3kel r4kelem rke2n1 rken4er r2k1er2l rk5ersta r2k1er4w r3k2es r3ket rk1im rk4las rk4lau rk4lim r2klis rk2lo rk2lu rk4ne r2kob r3kol r3kon rk2op rk1o2ri r2kou rk2ö rk3räu r3kri rk3rin r2k3rom r2krou rk2sal rk2sei rk2sel rk2ser rk2so rk2sp rk3spi rkstati6 rk4stec rk4stoc rk2ta rk2tel rk4t3eng rk4t3erf rk4terg rk4t3erl rkt3ers rk6tersc rk4t3erw rk4t3erz rk4teta rkt2i rk2t3in rk2t1o2 rkto4b rk2t3r rk2tum rk1ums rku2n r3kup r3kus rku2sa rkus3s rku2s1t r2küb 2r1l rl2ab r3lag r5land rlan4d3i r2l1ar r2l1a2sc rlas2t r2l3aug rle2a r3lec r5lei. r3lep rl2et r3lex rlg4 r3l2i rli4ne. r3l2o rlou1 rl2ö rlös5s rls2a rl2spr rl2sto rl3t r3l2u rlus2t rlu6ster rlu4str r3ly rlz2 4r1m r2mab r2m1ad rma2la rm1ald rm1ami r2m1ank rm1anz r4m3aph r2marc r2marz r3mas rma4spe rmas3se rma5ssen rmas8sens rmat2o rm2är rm3d2 r4m3einh rme4na rm2ene r2ment r2meo rmer4fo r2m1erh r2m1erl r2m1erp r2m1erw rm2es rme3sa rme3st rmeta2 r2mide rmi6nanz rminen4 rmi6neng rm3m r4mn r2m1ob rm1o2ri rm3p2 rms2 rm3sa rm3sk rm3sta rm3t rmt2a rmu2n r4muna r2muni 2rn rna2b r3nad rn4ade r3nage r2n1all rna4n rn4and rn3ani r2nanz rna2r rn3are r4n3ari r4n1a4st r4n3att r2nau rn3aug rn3de rn3d4r r4nef rn2eid r4neif r4neis rn1ema rne2n r2n1ene rn2eng r4n1e2p r4n1erg rn4erhi rner4ke rner4ku r4n1erl r4n1ert r4n1erw r4nerz r5nes rn2e2t rnet1e rne4tem rne4ter rne4to rn2eu rne3uf r4nex rn3f rn3g2 rngene4 r2nid r2n1in r4ninf r3nit rnk2 rnn2 r3nod rn2oh r2n1op r2n1or rn1ö rnö2d rn3sa rn3s2ä rnse4ha rn3s4p rns2u rn3s2z rn3t2a rn3t2e rn1ur r1nü r1ny rnz2 r2oba 2robj 1robo ro2bo2r 2robr ro2bre 2robs ro1ch roch2a 3rock. r2o3de rod4r roe4 2roff ro3fl 4rog. ro3g2a 3rogg ro2h1in roh1l2 4rohn ro2hö 3rohr 1roi ro3in rok2l ro3le ro2liv rol4lan rolle4 roll4en rol6lerg rol6lerw rolli4n rol6lini 2roly 4rom. ro2mad ro2mal 3roman. 2romb romen3e ro2m1er 4romm 2romn 4romt r2on ro3n4ab ro2nan 3rond ro4nerb 4ronk 3ronn rons2 ron4tan ron6tend ron2t3r ron2t1u ro1ny ro1o2f rop2a 2rope 2ro2pf 1ropl 2ropt r1or ro2r3al ro2rat 2rorc ro2rel ro2ro ror3th rort4s ror2ü ro3sh ro3s2i ros2p ross1c ros4st ro3sta ros3tel ro2st1r ro2sum 4r3osz roßen2 ro4ßenk ro2ßi ro2ßu ro2tan rot3au ro2tä ro3te ro2te3i ro2t1ho ro2tru rot1s rots2o 3roul ro3unt 3rout 2ro1x 4roy rö2b3l rö2du 2rö2f 3röh 2r1ök 1röl 2röl. rö3le r1ölp 3römi r1ör r2ös. rös1c r2ö3se 1rösl 3rötu 2r1p2 r3pa r3pe rperer5 rper3in rpf4 r2pli rp4lu r3po rpo4str rp3se rps1t r4p3t r3pu 2r1q 4r1r rr2ab rra4s3s rr4at rrat2s rr1auf rr1äm rrb2 rr1c r5rega rr2ei rre2le rre2pa rrer2 r2rerh r2rerl r3res rres2t rre2ve r4rezi r3r2hen rr2hos rr4i rri3k2 rrm2 rrn3au rr2o rr3obs rro3m rro2re rr2th r3r2u r3r2ü rrz2 6r1s r3sabo r2sa2d rs2al r4samp r4s1amt rs2an rs3ana r4sanf r2s3ang rs3anm r4sanp rs3ar rs4ark r4sarm r4sch3e4b r6scherl r5schu r5schwu r5schwü r2s1ebe rse2e r2s1ef r2sein rse2n rs2end rse4ne r2sepi rs1ere r2serh rs1ers r2serz rse2t rs1eta rs2ext r3s2hav r3shir r3sho rs2hor r4shu rs2il rs2ka rs2kel rs2ki r4skir rs2kl r4skor r3s4kri r4sky rs4mog r3s4no rs4om r2sop r4s3ort. rso4s rs1ost rs2p4 r3span rspa3s r2s3ph r3spi r3spl rs4por r2spun r2sput rs3s2 rst3abl r5stad rst3ala r4stale r4stans r4stant r2stas r3stat rs2tau rs2tea rs2tee rst5eing r6st5eint r4st3emi rster2 rst4erb r6sterbt r4st3erl r4sterö r4st3erw rs2t1h rst3ing r2stip r2stit rs2tob r2s1tot r6strang r4stris rs2tu rsuch4s r3suf rs2ums rsü3s r3sy rs2zin r1ß 4r1t rt1abs r2t1a2d r2t3ae rt1akr r4t3albe rta3l2e r2t1all rtal4s3e rt1am r3t2ame rt1an r2tanw r2t1ar rt3att r4tauft rt3äh rt1änd rt1ärm r3te. rte1e2 rt1ein rt4eind r4t3einh rte2is r2telf rte3li rtel6lei rte2n1 r3ten. rte4na rten3s2 r4t3ents rten3z rteo2 rt3erei r6tereig r4ter4fa r4ter4fo rt1erh rt1erk r4t3er4la rter6mit r4t3ernä r2ter2ö rter4re rt1er4s rt4er5sp rt1erz r3tes2 rte3sk rt1he r2thel r2t1hi rt2hum r2t1id rtik2 r2t1ima rt3inf rt2is rt2it rt3m r2t1ob r3top. rto1pf rt1orc r2torg r3tork rt3rams rt3rand rtra4s3 rt3rati rt3rec rt3ris rt3rol rt3roma r3trop r2trou rt3sc rt4s1eh rts2el rt3sex rts3ing rts1o rts1pa rt1spe rt4s3tan rts4tie rt3t4 rt1umb rt2u3na r4tunt r2t1urt rtu2t r2t3ute rty1 rt3z2 1ru ru1a ru4ale ru3a2r3 rube4 rub2i ru3ches rucht3s4 rude2a ru2dr ru2et 3ruf ru2f1a ruff4 ruf2s1 ruf4ter ru2g3r 3ruhm 2r1uhr 3ruin ru3ins ru1is 2rum ruma2 4r3umd 4r3umf 4r3umg ru2mi 4r3uml 4r3umsa 4r3umw 4rumz 2r1una 2rund run4d1a runden5e run4d3er run2e runei2 4r1unf run2ga 2rungl 4r1u2ni r3unio ru4nis. run2kr 4r1unl 2r1unm 4runn 4runr r1unse 4r3unt 4runw 2rupd ru3pr 4r1ur ru2ra ru2r1e 5ruro r4us. ru2si rus2p rus3sen rus2s1p rus6st rus2t ru2tab rute4 ru2tei ru2t1el ru2t1er ru2t1o2 ru2t3r rut6scha 4ruz ru2z1w 1rü 2rüb 4rübu rü1ch rücks2 rück5sta rü2hel rüher2 rüh1l 4rümm rün3z rü3ss rü4ssi 2r1v r3ve rv2el rve4n1e rvenen4 r4ventz rve5s r3v2o rv2s 2r1w rwe4gel r3wei rwelt4s r5werk r5wert r2wo. r3woh r3wort rwun3s 4r1x 1ry 2r1ya ry2c rygi3 ry1la ry2le ry1os ry3s2t rysti1 2r1z rz2an rz3ant r2zar r2zat rz2än rzell4a r5zene rz1eng r4zents rze2p rze2ra r2z1erd r2z1erf r2z1erg rz1erk r2z1erl r2z1erw rzes2 r2z1ess rz1id rz1int rzir3 r3z2of r2z3ot rz2tan rz2th rzu4g3l r2zwä r3z2wec r2zwir 1sa 3sa. 3s2aa 2s1ab sab2ä 4sabd sa2be 3sabet sa2bit sa2bl 4sabm sa2br 4s3abs 4sacc 5s2ache sa2cho sachs2 sach3t s2ack s1ad 2s3ada sa2der 2s3adm 2s3a2dr sa4fe 4s3aff sa1f4r 3saft saf2tr 3sag sag2e 5sage. 5sagen. 4s3agent 4s1agg sag4n 4s1a2gr 3sahs 3s2ai sa3i2k1 sail4 sai4r 2s1ak sa2ka sak2e 3saki 4sakk 3sako 4sakt 3s2al. s2al2a sa2l3an sa2lar sa3lat 3s2alb sal3bl 3s2ald sa4lerk 3sali sa2l1id s1all sal3la sal4le. sallo3 3sal2o sal3or sal2se s1alt s2al3t2h 3salz 3sam s2am. s1ama 4sa2mat s2ame 4s3a2mei sa3men sa2min 5s2amm 6s3amma 4s1amn s1am3p4 4samph s2ams s1an s2an. 2sa2na san4at sa2nä 2s3anb s2an2c 3s2and san4dan san4dri sand3s sa2ner 3sang. 4sanga 2s3anh 3sani 3sanken 2s3anl 2sanm 2sa2no 2s3anp 2s3ans s4anse san4sk san3sp 4santei 4santr 4s3anw 2s3anz s4anz. s4anzt 2s1ap sa2pe s2aph sap3p 3sapr 2s1aq 2s1ar 3s4ar. 3sara 4s3arb 3s2ard 3sarg sar2ga sa3rin s2ark sa2rom s2ars 4sart sa4r1u2 s1asc 2s1a4si 2s1a2sp 4sa2sy 3saß sat2a satan2 sa4t3ant sat1ei 2s3a2tem s3ath 3sat2i 4s3atl 4satm sat2o sa4tol sa2tr sa3ts s3atta 4s3attr 3satz 5satza sat4zel sat4z3en s1au 3sau. 3sauc 3sau2e 2sauf 4s3aufb 3saug saug3le sau2gr sau3h 3saum 3saur sauri1 2saus 3saus. 4s3ausb 4sausf 4sausg sau2sp 4sauss 3sauste 4s3ausw 2sauß s1av sa2ve sa2xi sa3xo sa2y1 1säb 3s2äc 3s2äg s1äh 4s3ähn 2s1ält 2s1äm 4s3änd 4s3äp 2säq 2s1är 3s2ärg sä4s3 sä5sse 3s2ät 1säu 2säuß 4s3b4 sba4ne sbau6men sber2e sbus3 1sc 2sc. 2scab 2scac 2scaf 2scal 2scam 2scar 2scat s1ce 4s3cei 6sch. 5schaf 5s2chal sch3ana 4schanc 4schang 5schanz 4schao 4s3chara 4sch3ar5m s2chä 2schäq 2schb 2schc 2schd sch2e 4schech sche2f 6schef. 6schefi 6schefs 4sch3ei. sch6ein. 4schemp sch5erfü sch5erla 3sches 4schess 4schex 2schf 2schg 2schh schi4d schi4e 4schiru 3schis 2schk sch4lac 4schle. 6schlein 4schloc 4schlöc 4schmas 4schmed 2schmö 4schmüh 2schmy 2schn. 4schneb 4schnut 4schobj 4schorc 2schox 4schör 4schp 2schq 4schrad 4schre. 4schrin s3chris sch3rom 4schron 4schrou 6schs4 sch3sk 6sch3t scht2a scht2i scht1s s4chu 4schunt 5schü 2schv sch4web 4schweg 6schwerk 4schwet 4schwid 3schwü s5chy 2schz 2scj 6s1cl 2sco 4scoa 3s2co2p 2scs 2scu 2scy 4s1d2 sd4a sda3me sdes4 sdien4e s3do sd4r 1se se3at. seau4 seb2 5sebä 2s1e2ben 2s1echo sech6str 2s1echt 2s1eck se2dik 3see see1i2 see3ig se2el see3len se3en. see3n2e se3enp se3er. see1ra seer2e se1erf se3e2r1i se1erk se1ers see5s2 2s3eff sef4l 3s2eg s3e2gal se2gl seg4r 3seh seh1a se2hag se2hak se2hel seher4e se4herk se2h1in seh3l se4h3ö seh3ra seh3re seh5r2i seh3s se2hüb 2sei. 2s1eic 2s1eid. sei3da 4s3eifer 2s1eig 3seil s2eim s1ein 5s2ein. 2seinb seinbus6 sein4du 2sei3ne seine3i 4seinfl sein4fo 2seing 2s3einh 2seini 2seink 2seinl 2seinn sein4ne 2seinr s4eins. 4seinsc 4seinsp sein8stit sein6str 2seint 4seintr 2seinw 2s3einz 2s1eis 3s2eism 5s2eit seits1 3sek 4s1e2kel 4sekz s2el. se2l1a 3s2elb sel3d4 sel1ec se2lef 2s3e2leg 6selektr 2selem se2ler sel3ers 2self. selin4s s1e2lit 2s1elix s2ell sel3le se2lob s2els sel3sz selt2e selz2 sem2e 2s1e2mis 2s3emp s4en. se4nad se3nal se4nas sen3au se2nä s2enb 3sendet 4s1endl sen3d4r 2s1endw senen1 4senerg se4ners s2enf 5seni se2nid se2n1im sen6keli 3senku se2no se4nott se4noz s2ensa sen4s3e4h 4sensem sen4si4d s2enso senst2 sen8s7turm sent2a sen3tan sen3tä 2sentd 2sentf 4sentg 4sentn s2ento sen3tr 2s1ents 2sentw 2sentz se4n3u2 3senva sen3za sen4zer sen3zw 5seo seo2r se2pen 5seq s4er. se2r3a2d ser3al se3rand ser3äus serb2 s3erbe. serd2 se2r1e2b se3reie se4r3eim se4rein sere2m s4eren se4r3enk s4erfe s1erfo s2erfr s3erfü 4serfül ser3g2a s1ergä ser3gl s2ergr s1erh 5serie serk4 3serl. 4s3ermit s2ern. 2s1ernä s3erneu 4s3ernt sero4b s1e2ros s1erot s1erö s2ers. 2sersa ser6sehn 4ser4set se3ru se4ruh ser2um s3e4rup 3s4er3v s1erz s4es. se3s2a se2sel 2sesh se3sk s1essa sest3ri se3su 2s1e4tap se2tat 2s1e2th set2i 2s1e2tik set1s se3tun 3sety 3setz 3seuc 4s3eul se1u2n s1ex 5sex. 2sexa se2xe sex3en s2exi s2exo 4sexp sex3t4r 2sexz 6s3f4 sfal6l5er 4s3g4 sgang4 sge3s2 sgro3 2s1h 4sh. sh2a 3sha. shal4li shalt2 shalt4s 4shan 4shc sh2e 1shen 4shf sh2i 3shi. 1shid s4hig s2hip s2hi4r 4shk sh3n 4shoc 4shof 4shom 3shop sho4re 5show 4s3hö sh4r2 4shs 4sht s3hu 4s3hü 1si 3si. si3ach. sial5l sia4s 2siat 5si1c si2cha 2s1idea 2sidee 2s1ideo si3der s2i3do 2sidy 3s4ie sie2bu siege4s si3ene si1err si1f4 si2g1a si2g1ei sig4n si2g3r sigs2 si2k1ab si2kak si2kar si2k1ä si2k1el si4kens sik3erl si2k3i sikin1 si2k3n si2k3r sik3s2 3sik3t2 si2ku sil2br sil2e 3sili s1ill 3silo 2s1imm sim2st 3simu si3n4a 2s1ind 2s1inf 4sinfe sing1a sin3g4le sin2g3r sing3s2 2s1inh s1in1i1 s2ink sinner4 2s1inno 2s1inq 2s1ins 2s1int 2s1inv 3sio sirn4 2sirr 3siru 3sis si2sa si4sam si4schu si2s1e2 si2si si4sis s1i2so sis1or si2s3p sis3s2 5s2ist si4star si3sto si2stu si2su 3sit si2tal si2tau si2tra s2it2u 3siu si2va sive3 siver2 si4v3erf si2vin siv1o4 si2vor siz2 1sí 4s3j 2s1k2 4sk. sk4a 4s3kab s3kad 1skala 4skalk s3kalt 4s3kam 4skana 4s3kanä 3skanda 4skann 4skap 4s3kar 4s3kas ska4te. 4skateg ska4tes ska4to 4skau 4s3kä 4skb ske2li 4sken 3skep 4sker 4s3ket s3kh 3s2ki. 3s2kif 3s2kik s3kim s3kin s2kis. 3skiz sk4l 4s3klas 3s2klav 4s3klu 4sk4n 4skoh 4skol 4skom 4skon 3skop. sko2pr 4skos 4skow 4s3kö sk4r 4s3kra 4skro 4sks 4sk3t2 skto2 3skulp 4skun sku2s3 4skü 4skv 2s1l2 4sl. s3lab 3slal sla2ma 4slar sla2ve s2law sl3b 4s5le s3li 3s4lip 4sln slo3be s3loc s4loga 3s2low s3lu s3ly 4s3m4 sma3b4 sma3sc smas4p sme3na smi2t3 2s3n2 snab4 sni4a sni3er. sni3ers 4s5not s5ny 3so. 2s3oas 2s1o2b 3s2o3ba 4sobj 4s3obo so1ch so2di so2do so3et s1o2fe 3soft 3sog sog4l s1o2he 3sohl sohle2 2s3ohng 2s1ohr 3soi2 so3id 2s3ok 1sol 3sol. so3la so4lau 3sold 3sole so2l1ei so3li sol2la2 sol4ler so3l2o 4s3o2ly 1somm 3s2on son2a son3au sone2 son4gl son3sä son2s1o so3o s1op 2sope 2sopf 3sopr 2s1ord sore2 so2rei so2rel 2s1orga 1sorge so1rh 2s1o2rie so2ro 3sorp 3s2orti so4ru 1so3s2 3s2os. 3sosc so4sk 2sosm 2sost so4sth s1o4sz 3so3ß 2sot so3t2h 3sott soun2 sound1 so3unds so3unt 2s1out 3sov 3sow 2s1o2x 3soz s1oze 2s1ö2d 2sö2f 2s1ök 2s1öl 2s1ö4s sp2 2sp. 2spaa s2pace 2spack 2spag spa2ge 2spak 2spala 2spalä 3spalt spa2m 1span s2pan. 3spannu 2spano s2pans 3spant 2spanz 4spap 2s3para 1spare 2sparo 1sparr 5s6parten 4spartn spas2 spa3sse spa5ssi 1spat. 2spati 2spatr 2spau 3s2paz s2pä 2späd 3späh 2spär 2späs 2spe. 2speg 1spei 4spein 4spensi spe3p4 s2pera 3sperb 3s2perg s1peri 4sperle 2spero s2perr sper4ra 2spers 4spet 3s4pez 2s3pf4 4spha s2phä 3sphär s3phe 1spi 3spi4e 4s3pier spier4r spi2k 4s3pil 2s3pip 4s3pis 3s2pit 3s2piz 2spl 4spla 4s3plä 3s2pli 4s3p4lu s3pn 2spod 4spoe s2poi 2s3pok 4spol 1spon s2pons 4spoo 2spop 1spor s2pore 3s2porn 4s3pos 4spote 4spr. 3s2prac 2sprak s2pran 2sprax 2spräm s2prän 2spräs 3sprec 2spred 5s2pren 2s3pres 3spring 4sprinz s2prit 4sprob 4sprod 2sprog 4sproj 2sprop 5spross 2sprot 2sproz 3sprö 3s2pru 3sprüc 2sprüf 1sprün 2s3ps 2sp3t 2spub 2spud 1spuk 3s2pule s3pun 4spup 3spur spu4rer 1spü 2spy 2s1q 4s3r4 sra4s3s srat2s sre3cha sro2h sro3tu srö2s srücker6 2s1s 6ss. 4ssa s3saba ss3abi ssa3bo s5sack ss2ad ss4agi s2s1aj ss3alba s2sall s4samt s2sanf s4sang s4sano s4sans ss2ant s4sanz ss2ara ss2arg s3sars s2s3att ssau3e ssau4r 4s3s2ä 4ssb 6ssc s2sce ssch2 sschanker8 s2scr 4ssd sse3a 4ss1ec 4ssee sse1ec 4ssef 4sseg 4sseh sseh2a 4ssei s2sein ss4eind sse3int 4ssek 4sselek sse2lö 4ssemp 6ssendet 4s3sendu 6ssenerg ssen6kel ssenmas6 ssen6sem 4ssentl 4ssents 4ssentz ss1epe sse6ratt ss5ereig ss4ergr sser4hö sser6mit s2serö sser4öf 4ss3erse ss4eru sser6wei 4ssesc 3ssesh sses4sa 4ss3e4str 4sset sse3ta s3seth 4ssez 4ssf 4ssg 4ssh ss3hi 4ssic ss3i2ko s2simp 6ssio ss1isr 4ssit 4ssj 4ssk s3skala 4s4s3l 4ssm ssmut2 4ssn 4sso ss1off ssoi4 s3sol s4sop 4ssö 4ssp ss2pen ss2phi s3sprä s3spri ssquet4 4ssr 4s4s3s4 sssau4 4sst sst2a s5stad s6stag s3stä ss1t2e s4ste. s5stel s5s2tep s5stern s4stes s4stet s5steu sst2i sst3in ss1tis s5stop ss1tor s3s4trat s3strö s3stü 4ssum s2sumg s2sumr 4ssunt 4ssup ss2ur s3sus 4ssü 4ssv 4ssw 4s3sy 4ssz 1st 6st. 3s4ta. 5staa 5stab. 2stabb 4stabel 2stabg 2stabh 4stabit 2stabl 2stabn 2stabt 2stabz st2ac s2tad 2stada 3staff 2stag 3s2tagr 3stah 2stak 2stala sta3lak 2stalb 2stalg 3sta3l2i 2stalk st1alp st1alr 3stam st1ami stam4ma 4stampl 4stamt 2stanb 3s2tand 4stanf 6stangeh 4stanh 4stanl 4st1ann st3ansp 4stanst 3stant 4stantr 2stanw 4stanza sta3po 2st1app s2tar. sta6rens s2t2ars s4tart 2stasc sta4sie stast4 2statb 7s2tati 7statth 7statu 2stauf 5staur 2staus st1a2ve 2stax 3stäb 3städ 2stäg 2stält 2stämt 3ständ 4stäp 5s2tär 3stätt 2stäus 4stb 2st3c 4std 3ste 4steam s2tean 4stechn ste2d st1edi ste2g3r s2teh 4stehr st4ei. 4steic 4st1eid 5s4teig stei4gr 4steil s3teilc stei4na 6steinga 6steinhe stein6sp s2tel st1elb s3tele st2ell stel6l5än ste4mar ste6ment 6stemper 4stempf ste4na 4st3ends st2ens 4stentf 4stentl 4stents 4stentw 4stepi st1e2po ste2r3a s2terb 4sterbs 6stereig s2terf st3erfü st2erg s2terh s2terj s2terk sterma7sse s2tern 6sterras s2ters ster4zo ste4s1e stes3ta 4stestb 4stestn 4stests 4steta ste4tab ste4tag s2teu 4steuf st3eun st1ev 4stex s2texa 4stf 2stg 2sth st2hen st1hi st3ho st1hy st1i2d 4stief. 4stiefl 5s4tiel 5stif sti4gel st2il 3stimm 4stimma 2stimp 2st1inb 4stinf 3sting 4stinh 2stins 4stint s4tio 2stip. 4stipps sti2r st1ira st1iri st1iro 2stite 2stj 2stk 4stl 4stm stma3s2 2stn sto2bl 4stocht s2tode 3s2tof stoffen6 stof8fens 6stoffiz sto3mi 2stomn 2ston 4stona 3s2to4ne 4stonl 2stope 2stopo 2stord 2storf 2storg s2tory 4stou 4stöch 2stöl 5s2tör 2stöst 2stöt 4stp 2stq st4rade stra4fa 2strag s2trah 2strai 3s2tral 4strans 3s2tras 3straß 4straum 2sträc 2s3träg 4sträne 2stre. 4strech 2stref 2streg 4streib 5st6reif 2strep 2stret 2strev 3s4tria 2strib 4strig 4strisi 4stroc 3s2trof 3s2troh 3s2trok 4stropf 3s4tropo st4ross 4strost 3stroy 2ströp 2strub 3struk s2trum 2strun 2strup 2strut 4st3s2 stsas2 stsi4d sts4p 2st3t4 st2u 3stub 4stuch 3stud 2stue 3stuf 2stug st3uga 3stuh 2stuk 2stumo 2stumr 2stum2s s3tumsc 2stumt 2stumz 2stun. 2st3una 2stune 2stunf 2st3uni 2stuns 2stunt 3stuö stu3ra stu5re 2st3url 2s3turn 2st3urt 3s2turz 4stüch 3s2tück 3stüh 2stür. 2stüre 2stürg 2stürs 2stürw 2stütc 2stv 2stw stwor2 2sty 4sty. 4styp 4stys 2st3z2 su1an 3su2b3 su4ba 4subi su4br subs4 5su1c su2cha su2cho 3sud su2eb 2s1u2f su3fi 2s1uh 1sui su1is su1it. su2k su3l2i sum1a su2man su2mar 3s2ume su2mei su2mel sument4 su6ments su2m1et 2s3umf su2m1id su2min 3s2umm sum1o2 su2mor s2ump s1ums s3umsa 2sumse s2umsp 2s3umst 2s3umwa su2n 2s1una sunder4 sun6d5erh su4ne 4s1unf 6sungena 2s3ungl 4s1uni 2s1unm s1uns 2sunt 3sup 4supd sup3p4 su2ra sure4 su2rei su2rer 3surf 2s1urk s1url su2r1o s1urt su2s su3s2a sus1e sus3i s3u2t su3tr suz2 2sü4b 3süc sü2d1 süden4 sü3den. 1süf 3sün 1süs4 sü3sse sü3ssi 1süß 4s3v2 svoran4 2s3w swe6gers sweh2 swe5s 4swie 4swil 4swink 4swis 4swit 1s2y 2syl1 sy2lo sy2lu sym3 sy2n3 3synd sy4no 3sys 2s1z2 4s3za 4szä 4s3zei 4szel 3s2zena 3s2ze3n2e 4szent 4szer s2zes s2zeß s4zew 4s3zie s3zins 4s3zo s3zs sz3ta 4s3zu 4szü 4szw 4szy 2ß3a4 ßan1 ßat3 2ß1ä 2ß1b4 ßbus3 2ß1c 2ß1d4 1ße 2ß1e2b 2ß1ec 2ß1ef 2ß1e2g 2ß1ei 2ß1ek ße2l 2ßelek ße3lu 2ß1emp ße4n3a4 4ßenerg ße2ni ß1enke ße2no 3ß2en3te 2ßentz ße2nu 2ß1e2p 3ß2er. ßer3b ßer2ei ßer2la ße2ro 2ß1erse ßer3t ß1erw ße2s 2ß1es2s 2ß1est3r ße2t 2ß1ex 2ß1f4 2ß3g2 ßge2bl 2ß1h 1ßi ßi2g1a 2ß3i2k 2ß1il 2ß1im 2ß1in ß1j 2ß3k4 2ß1l2 2ß1m2 ßmut2 2ß3n2 2ß3o4 ß1ö4 2ß1p2 2ß1q ßquet2 4ß3r2 ßrö2 ßrus3 2ß3s4 ßsau4 ßsch2 2ß1t ßt1h ßt1in ßts2 1ßu2 ß1uf 2ß1uh 2ß1um ß2ung ß1uni 2ßunt ß1ü4 2ß1v 2ß1w 2ß3z2 2taa 2tab. 3taba ta2b3an 2t1abb 4tabd 1tabel 2tabf 2tabg 2tabh 2t3a2bit 2tabk 2tabla 1table 4tabm 2t3abn 2ta4br 4tabs t1abst 2t3abt 3tabu 4tabw 4tabz 2t1ac t2ache 3tacu t1ada 2tadd ta2der tadi3 tadi5o4 tadi4s t1adm ta2dol 2t1a2dr ta3d2s ta2er 1tafe 2tafet t1afg t1afr 1tag ta2ga ta2g1e2i 4t3agent tage2s 2t1agg ta3gl 2t1a2go tag2s1 tag4san tag4st 2tah2 3tai ta3i2k tai2l1 ta1ins tai4r ta1ir. ta1i2s 1tak 2t1a2ka ta3kes 2t1akk ta2kro 2taks tak2t1o2 t2aktu 2takz 3t2al. ta2la ta3lad ta3lag tal3au 1talbr 1talbu tald4 1tale tal2en ta4l3end tal3eng ta4l3ens taler2 ta4ler3g ta2let tal2ga tali6ene tal4l3ac tal4leg tal4lei tal4let tal6leut tal6lin6s tal4los tall2ö tall3s tal4lus 2t1alm. ta2lop ta2l1o2r t1al3ta tal3th talt4r ta2lu 2tam 3t2am. t2amen t1a2mer ta2mi tam2ma2 tam4m3er tam4mi tam4mut t1ampl 3t2ams 4t1amt t1a2na tan3ab 4tanal ta4nat 2t1a2nä tan3d4ar tan2dr ta4nerf 4tanf 2tang tan4gra 2tanh t2anho t4ani 3tanj 1t2ank tan2kl 4t3anl t1anm 2t1anna 3t2anne t1ano 2tanom t1ans t2ans. 4tansi tan4tan t4ante. 4tantei 2tantr tanu4 2tanwa 2tanwä t2anz. t1anza 4tanzei 3tanzk 3tanzr t1anzu tan2z1w tao2 ta3or t4ape ta2pes 2tapf ta2pl ta4poka t2appe ta2ra 2tarab 3tarabb ta3rak 3tar5al 2taram tar3ap ta3ras t2arau 2tarb 3tarba 3tarbek 3tarber 3tarbi 3tar3bl 2tarc 3tarchl 3tarchr t2ard ta2rel ta2r1er tar3g ta1r2h 3tari 2tark 3tark4l 3t2arko t2arl 2t1arm t2armä ta2rom 2tarot 2tart 3t2arta 3tartei tar6ter6e 3tartex 3t2arth t1arti 3t4artis tar2to tar2tr 3tarty ta2ru t1arz 2tarzt t2as. ta3s2a 1tasc 4t1asp 2t3assi 1tast ta4stem ta2sto ta3str t2asy t4at. ta2ta2b ta2tan 3tatb t4ate tat1ei t5a2tel ta2tem 1taten ta2t1er 2t3atl 2tatom 2ta2tr 1tatsa 2tatt tau2b1a 1taubh tau2bl tau2b3r tauchs4 tauch5sp 2taud t1auf 3taufe. tau3f4li 4taufm 2taufn t3au2f1o 4taufp taufs2 4taufw 1taug 4t3auge t1auk 3taum 4tauma 1taume 1taus 4t1ausb tau6scha tau6schm tau6schr tau6schw 2tausd t2aus2e 2t1ausf t3ausg t1ausk 2tausl 2tausr 2t3auss 2t5ausw 2tausz ta2van 3tax taxi3s 4t1axt 2tää 2täb tä1c 2täd t2äf 1täg 2tägy 2täh 3täle 2täll 2t1ält 2tä2m t1ämt t1ängs 1tänz 2t1äp 2täq tä4reng tä2ru 2tärz tä2s t2ät 3tätigk 4tätt 2täug 1täus 2täuß 2täx 1tà 4t3b4 tbauer4 tber2e tblocken8 tbus3 2t1c t3cha t3che tch2i tch3l t3chr t2ch1u tch1w t3cl tcor2 t3cr 4t3d4 tdar2m1 tdun2 1te2a2 te3ab tea3c te3ag 2teak te3al teamma3 te3an te3ar tea4s 3teba t4ebb 2t1e2ben t2ech 1techn te2chu 2teck t1ecu te2dit 1tee te1em teen1 te2er. te1erw te2es 3tefa 2teff 2t1egg te2hac 2tehe te2him 2t1ehr te3hu 1teic tei1fl 2teign teik4 1t2eil tei6lent teim2 2tein teinbus6 teinen4 tei6nens tein6hab t3einkü 2t1eis. t1eisb tei3sc te5isch. teit4 t1eiw tei3z te2kel 3teko tek3t4 te2la tel3ab tel1ac te3lan te4lant tel1au te2lä telb4 tel3d4 tel1ec 1telef 1teleg tel3ehr 2telem tel3eng te2ler te2leu 4t3elf. te4lim te2l1in te2lit tel3le tel6lein tel3li tel6li6st te2lob te3lom te4lost te2l1ö tel3s2k tel3ta telt4r t2ema te2man te2m1ap te2mau 2tem2bo te2m1ei te2m1er 2temg 2te2mi tem3i2m tem3ing 2teml 2temn 2te2mo tem1o2r 3temper 2tempf 1tempo tems2 te2mu te4mun t6en. ten1a2 te4nad te4n3an ten3ar te4nas te4nat ten3au te2n3ä4 ten3da t3endal tend4an 4tendap 2t5endf 2t1endl t6endo 2t5endp ten3d4r te2n1e2b te2nef te2neh ten3ei te3n4ei. tenei4d tene4m tenen1 te4n3end te4nene te4neng te4nens 4t3energ te4n3ern tenf4 t1eng. teng2a 4ten4gag t3engla te2ni te4nil ten1im te4n3in tenk4 ten3n2 te2nol te2nos te3nö 4t3ensem 1tenso tens2p t2enta t1entb 2tentd 2t3entl 2t3entn ten6tric t1ents 4t5entw 2tentz te2nu t2enz ten4z3er teo2f 2t1e2pi tept2 t4er. t4era ter3ac te2rad te1ral ter3alg te3r4ane te2r3ap 2t1erbs 2t1erbt 4t3erde. ter3d2s te2r1e2b te2rec t3ereig te5rek tere2m te4rema te4r3end te4rene te4reng te4r3ent teren5th terer3k terer6ku terer3l te4r3erp te4rers te4rerw t4erfr terg2 ter3ga 6tergebn t6ergem t6erges t6ergew ter3gl 6tergrei t4ergru 2t1ergu 2tergü t6erhall t6erhau t4erhäu t4erhei t2erhi t2erho 6terhöhu t2erhu te3ria 4terii ter3iko teri4o te2r3it teri4ta 4terklä t4erlä t4erli ter4lös termas4 1termi t2ern. ter4nar t6ernc t4ero te1rob ter4obe 2teros t1e2r1ö t4erp t4erra 3terras ter4re. t4erro t4ers. t2erse t4erst. t6erstad ter6stat t4erstä t4ersti t4erstr t4erstu t4erstü ter3t4a ter4trä t4eru2 te4r1uf te3rung t4erv 4t3erwäh ter3z2a 2t1erzb t4erzei 4terzeu ter3zw te2s t2es. tesa2k te3sä te3sc tes3eli te3ser te3si te3so te3sp tes1pe te4sper te4spr 2t1essa tes3si tes2t tes3tät 1testb tester4 te6sterg te6st5erh te6sterk te3sto tes3tra t3est3ri 1tests t1eta te4tabl 2te2tap te2tat teten3 2t1e2th te3tho 4tetl 3teuf te1u2n 2t1eup te2va te2vi tewa2s 3tewo 1tex 2texam 2t1e2xe 2t1e2xi 4texp tex4ta 2t1exz tè2 2t3f6 tfäs3 4t1g2 tga4s3er tga4su t3ge tge4nen3 tger2a tger2i tg4r tgro3 4th. 2t1h2a 3tha. 3t2hag 4thak 3thal. 3thalh t4hali 1t2hals t2han. t3hand t3hap 4t3hau 2t1hä 3thäi 4thäl 2thb 4thc 1th2e 3t4hea 2t1heb 2t1hef 2t1hei the1in 4theit t2hek 2themd 2themm t1henn 3theo t1herd thero1 2t1herr 2t1herz 4t1hess t2heu 2thf th2i 3thi. thic3k4 thi3er. 2t1hil 2t1him 2t1hin thi3nu 2t1hir 2thk 2th3l 4th3m2 thmu2 2th3n2 2t1hob tho3chr t1hof 2t1hoh t1holt 2tholz t2hon 4thops t1hose t1hot 4thote 2thou t1hov 2thö 2thp 1th2r2 2ths 2tht2 t1hu 2thub 2thuh 4t3hun 2thut 2t1hü 2thv t4ia ti3ac ti1ag tial2l ti3alo ti1a2m ti1ce ti3chr 3ticket t2id. 2tidee ti4d3en4d ti3dy 1tief. 4tiefel 1tiefl tie2fr tieg4 ti2e1i ti1el ti2el. tiel3a ti3e2n1 tie4rei tie4reu tiermas6 ti2ern 1tierr tie5sse ti1eu ti3fe tif3f ti1f4r tifter6k ti4gerz ti2git tih2 tihi4 ti2kam ti2kar tiken2 ti4kent ti3k4ere ti3kerl ti2kin ti4klu ti2kn ti2k1op tik1r ti2kra ti2krä ti4krei tiks2 ti2lar til3d ti2lei ti2lel 1tilg 3tilgu tille4b 2tillu ti2lö tilt4 ti2lu ti2ma2g tim4man tim6ma6te timmer4 tim6merg tim4mit 2timp t4ina ti3naf ti3nak ti2n3an t1ind ti5n2e tine1i 2t1inf tin2ga ting3l ting3s2 2t1inh 3tinis t1in1it t1inka tin2k1l tin2kn tin2kr t1inku t2inn ti2nor t1ins t3insa t2insä 4t3inse tin4spa tin4sum t1int 3tinte. ti3nu tin2um 4t1inv 3tio ti2osk tioxi3 1tip. ti3p4l 1tipp 3tips ti4que. 1tirad ti1rh ti4ron t2isc ti6schei tisch3l tisch3w ti2sei ti3sk t1isl t1iso ti2sp t1isr ti3s2th ti4s3tic ti2su 2t1iß t1it2a ti2tal 3ti3te 3tiu tium4s ti2van ti2vel ti4vene tiver2 ti4verh ti4verk ti4verl ti2v1o ti4v3r ti2za ti2zir 2t1j 4t3k4 2t3l2 tlan2g tl4e tlei6der t4lep tle2ra 4t5li tlings3 tli5ni tlit1 t5lö 4t1m2 tmal2 tmen8schl tmen4t5 tments4 tmo4des 2t3n4 t5na tnes4 tni3v to4as to5a4t t2oba 4tobj tob2l t1obs 1tobt to1ch 2t3ochs 1tocht 2tock tock5ent 1t4od 3tod. tod1er2 to2dun tof6f5ent tof4f3er 2toffi 2t3ohr toi4r tok4 to3le 1toler tomar4b to4mene 3tomi to2min 1tomo to2m1u to4mun 1ton to2nan ton3au tond2 to2n2eh toner6ke to2nob 2tony 3too to2pad to2pak to2pan to3pas to2pat t1ope top1hi 1topo 2to4pt t4or. tora2g to4rän t1ord t2ordi 2t3ordn t4ore to2rei to2rel to2rem to6renna 1torf tor4fan t1or3g 2torga 6t5orient torin4s tor3int to2rö 1torp t4ors 1tort 2t1ort. tor3t2a t1orth 4tortn 4tort4s to4ru to3rü to4rüb to3s2 to4s3ka tost2 to2tä 1toten to2tho 3t2ou touil2 to3un to1x tö2c 1töch 2töck 2t1ö2d 2tö2f 4t1ök 1töl 2töl. 1tön t2ör t1ö4st 1töt 2t3p4 tpf4 tpi2n 2t1q t2r4 2tr. 1trac tra3cha tra3chl 2t3rad. 2trade tra4dem 1tradi t3radie tra4fah tra4far 2traff 1t4rag tra5gen 2trahm 3t4rai 2t3rake t4rakt tral3l 1tram 3t4ran. 4trand 2trang 1trank t3rann 5t4rans 1trapp tra4sta tra4str 2traß t1raub 4traub. 4trauc t4rauf 1traum 2traup traus2 1träc 2träd 1träg 1träne 2träng 2träuc 1träum 4t5re. 2trea t3reak 2treb tre2br 2trec t3rech t4reck 3treck. 2t3red 1tref 2trefe 2trefl 2trefo 2treg t3reh t4rei. 1t4reib 2treif 2t3reig 2t3reih 2treim 2t3rein 2t3reis tre7isch. 2treit t3reiz 2trek 2t3rel t4rem t4ren. 1trend 1trenn t3rent 2trepe 2t3repo 1trepp t3repr t4rer t4res. 1tret tre2ta t4rete tret3r tre4tri 2t3rett 2t3rev t4rex 2trez 3t4ré 2t3rh 3t4rib t4rick t4rid2 1trieb trie3fr tri4ena tri2er tri4ers 2trig. tri3gl t4rik tri4ke. tri4kes 1triko 1tril 1trin t3rind 2tring tri3ni t3rinn 3trio t4rip 2triß 1triu 2t3riv tri2x trizi1 tro3b4 1troc 4trock. tro4kes trol4la 2trom. tro4men tro2mi 2tromk tro3na t4rop tro1pe 3tropf tro5sm 1trost t1rot. 2trout 4t3röc 2tröh 2tröm 1tröp 2t3rö4s3s 1tröt 1trub 2t3ruc 4truf 1trug 2truk trum2 t3rumä trums1 t3rund 1trunk 3t4rup t3russ 2t3ruß 1trut1 tru2th trü1be trü1bu 2t3rüc trücker6 t4rüg 3trümm try1 2ts 4ts. ts3ab t3sac tsa3che t4sachs t2sa2d ts1ahn t2sall t2salt t4samp t4s1amt t2san ts3ane tsa2r ts3ari t2s1a4s tsa5ssen t2sau ts2av t1sä t2säh ts1än ts1äus t2sce t4scham t6schart t3sche t4schef t3schl tsch4li t3schra t4schro t3schü ts2cor t2s1e2b tse2e t2sef tse4he. ts2eil t3seme ts1eng t3s2ens t2s1ent t2s1ep t2s1er t6s5essen tse2t ts1eta t2s1eti t2s1e2v t2sex t3sexi ts3he t2s1i2d t2s3i2k t2sim tsing4 t2sini ts1ir 4tsk t3skal ts4kele tski2 t4s3ko tsmas4s tsma5sse t1so ts1off t2sop tso2r ts1orc t2s1ori ts3ort. t3sos ts3part ts1pas ts3pate t1sped t1s2pek ts4pend ts2pi t2s3pic t4spins ts3ple ts2pon ts2por ts2put ts5s4 4tst4 t4stabe t2staf t4stale t4s3tanz t2stas t4s3tat. t4s3täti t4stee t4s1tep t4sterm t4s3terr ts1tie t3s2til t3stim t2s1tis t2stit t4stoch t2stoi t2stor t4strac t4strad t3s4traf t3strec t4stren ts4tric t4strie ts2tro2 ts2tub ts2tüm ts1u 3tsubi t2sumz ts3un t1sü tsü3s tswa2s 4t1t tt1ab tt2ac tt3achs tt1ad tt2ag tta6g5ess t4t1ah tta2ke tt2al t2tan ttan4a tt4anke t3t2ant t4t1ap tt1art tt3atr tt1äh t2tän tt1ebe tt3echs tt1eif tt1ein t2t1eis tte4l1a2 tte4l3e4b t4te4leg tte4len ttel3l ttel1o t2temu tte4na ttens2 tten6sem t4tentb tten3te t4tentf t4tents tten3z t2teo t3t4ere tt2erg tte4rik ttermas7s tter3nä tte2ro tt2erö tt4es tte4s3a tte4s3ä tte4s1o t3tess ttest4r t4teuf tt2häu tt1hi t2t1ho t2ti4d t2t3igi t2tins tt2int t2tiso t4t5la t3to. t2torg t3tos ttras3s t2trou tt3rü1 ttschi4 tts1eh tt2sen tts1p tt4s3tät tt4s3tem tt4ster tt3s2z ttu2 ttu3b t2tuc tt1uf t4tunt t2tu4s ttü2 tt3z2 3tua tu4ale tu1alm tu1alv tu3ant tub2 tuba3b 1tuc tu2chi tu1cho tudie4n3 3tue tu3en tu2ere 2tuf tuf2e tu3fen t3u2fer 3tuff tuf4fel tu2gan 3tuge 2tuh tuh4ler tu1ist t3u2kr tul2i 1tum tum2b5l 4t3umf 2t3umg 2t1umh 2t3umk 2tuml 3t2umo 2tump 2t3umr 4t3umsat 2t1umsc tum2si tum2so 2t3umt 2t1umw t3umz 1tun. 2t1una 2t1und tund2e 1tune tun2en 2t3unf t3unga 2tunif 2tu2nio 2tuniv 2t1unm 3tunn t1u2no t3uns 1tuns. 2t3unt 2t1unv 2t1up. t1upg tu2r1ag tu2ran turan4l tu2ras tu2rau tu2rä tur1c tu2r1e2b tu2rei tur3eis tu4rene tu2r1er tu4res tu2re2t tu2r3e2v tur3f4 tur3g2 tur1in1 tur4mun 1turn tu2r3o tur3s2 tu4ru tu2sa tu4schl tu2se tu2so tu3t2a tuto5 tuto3re 2tüb tü3ber. 1tüch tück2s 1tüf 2tüh 1tür. tür1c 1türe 1türg 1türs 1türw 2türz 1tütc 1tüte 2tütz 4t1v2 t3vo tvoran4 4t3w4 t5wa2 twä4 twegs2 twi4e t4wist 1ty 3ty. 2t1ya 3typ ty2p1a 3tys 2t1z t2za2 tz1ag tz3ar tz1au t2z1ä t3zäh tz1ec t2z1e2d tz1ehr t2z1eie t4z1eis tze2m tz1emi tze4n1 tz2ene tzen3ta t4zentg t4zentl t4zents tzer6gre tz1erw tz2er3z tz3erzi tzes1 tz1e2t tz1i2d tzi4m tz1imi tz1int tz1inv t2z3om t2zop tz2th tz2tin tzu2gu t2zuni tzwan4d3 tz1wä tz1wi t3zwie tz1wu 2ua u3a2b u1a2c ua2dan uad4r u1a2g u1ah u1al. u1a2l1a u1a2l1ä u1alb u1ald u3aleb u3a4lent u3aler2 ua4lerg ual3erk u3a2let u1alf u1alg u1alh u3a2lid ual3l ualle2 u1aln ua2l1o2 u1alp u1alr u1als u1al3t4 ua2lu u1alw u1alz u1am uan2a u1ans u3ar. uara2b u1ars uar4t3an ua3s2a ua2th uat2i uat2o u3au uau2s u1ay u1äm u1än uäs4 u1äu 2u1b u2barb ubb4l ube2be ube2e u2b1ehe ub1ein u2b1e2m ube4n1a uben3o ub2er u4b3erde ubert4 ub4es ub1eul u3bit ub2l ub3läu ub3lic ub3lu ub4lut u2bob u2bop u2boz u2b3rit ub4rü ub2san ubsau2 ub6s3che ub2s1o ub2sp ubst2 ub4sz ub3t2h ubu3s 2uc uc1c uch1a u1cha. uch1ä u1che uch1ec u2ched uch1ei ucherin8t ucherma8s u1chi uch3im uch1in uch3l uch3m uchma6ss uch3n uch1op u2ch3r uch4sel uch2so uch2sp uchst2 uch2ta uch3tan uch6t5erf uch6t5ert u1chu u2chum uch3ü uch1w u1ci uck3elf uck2er ucker8geb uck3i uck4sti uck3t u1cl 2u1d u3d4a uda3d ud2e ude3i4 udein7 udel3se uden1 uden3e udert4 udi3en uditi4 u3d2ob u2don ud3ra u3dru 4u1e ueb4l ue1ch u2ed ue2en4 u2eg u2eh ue2ke u2ela ue2lek ueli4 uel2la uel2lä u3eln ue2mi uen1 u3en. ue4n3a2 ue2nä u3end uene2 ue2neb ue2ner uen4gag uenge2 uenge4m uengene7 uenge4s uen2gl u3e2ni uenk4 ue2no ue2nu uen6zene uen2zu u2ep ue2r3a2 ue2r1ä uerb2 uer6baut uer3d2 uere2 ue2rec u5ereinn uer3eis uer3ela u3eremp u3e4r3ent ue3r4erb u3ererf ue4rer4g uerer4h uerer4k uerer4m ue6rersc uerer6sp ue6rerst uer3esk ue2ret u3erex uer3g2 uer4geb u3erh ueri2d ue2r1i4m u3erin4t u3erl. uerma6s u3ern uer4nan uer4nar uer4ne ue2r3o4 uer2ö uer3r u3errü uer3sc uerst6 uer3t2 u3eruh u3erum u3erunf u3erunt uer3z2 ue4s ue5se ue5sp ue2ta ue4tek ue2tik uety2 u2ev ue2x1 uf1ab u3fac u3fah u3fal ufall4 ufa2n uf3ane u2f3a2r ufa2t uf1au u2f1än u2f1ä6s u2f1ä2ß u2f1ei ufel4s3a u2f1em 4ufen u3fen. u2fent u2ferf u2f1erh u4ferla u4ferle u4ferne u2f1eß u2f1et 2uff uf3fe uffel2 uff4l uf2fro u2f1id u2fim u2f1ins uf3l u2fob ufo2r uf1ori uf3r uf5sä uf3sc uf2spo uf4stab uf4ster 2uft ufta2b uft1eb uf3ten uft3erd uft3er4g ufter4l uf3ti uf4tin uft3s2 u2fum 2u1g ug2abe u4gabte ug1a2d ug1ak u2gana u2ganb ugang4 u2gani u2gans u2gant ug1ap u2g1ar ug1au ug3d2 u3ge. u2g1ec ug1e2i u2geig u2gein uge4lob ug1emi ugene2 ugenma3 ugenmas6 u2g1erf u2g1erl u2gerr u2gerv uges2 u3ges. u2g1esk ug2et ugg2 ug2gl ug5g4t ug3hu u2g1i2d u2gim ug1in u2g1l u4glä u6gleitb u6gleitu u4glic u4glis ug3liz u4g3lo u4glu u4g3n u2gob ug3oc u3gon ug1op ug1o2r u3gos u2gö u2g3rä u2greg u4g3reis u2gres u2g3rie ug3ro ugro3s u2grou ug3rüs ugsma3 ugsmas4 ug6spe ugs4por ug3stä ugs1te ug4stur u2gum ugu6ster u2gü u1h uh2a 2u3he uhe3a uhe1e2 2uhi 2uhl uh1la uh2lar uh1lä uh4l3ent uhl3erb uh2li uhl2ö 2uhm uhme4 uhr1a uhrei4s uh2r3er5 2uh3ri uh4rin uh2r3o uh2ru uh4rü uhs4 uh3t2 u2hu 2uhü uh1w 2ui ui2a ui1ch ui2che u1idd u1ie ui1em u3ig u4ige uil4les u1im u3in. uin3n u3isch. u3ischs uis2e uisi4n ui2st ui3sta uit3s u1j uji3 uk2a uk1äh u3käu u1k2e uke2n1 u1ki u1k2l ukle1 u1k4n u2k1ob uko2m1 ukom3a uk2ö u1k4r uk2ta uk2t1el uk2t1er uk2tin uk4t3o4ri uk2t3r ukts4 uk2tum u1ku uku2s uk2ü u1l ul1am ulan2e ul2ar ula2sc ul1äm ulb4l ul4dan ul2dr uld2se 2ule u2l1el ul1emb ule4n ul1er2h ule4s1t ule2t ul1eta 2ulf4 ulg4 2uli ul1id uli2k ul1ins uli1p ul3ka ul2kn ulla2g ull1au ul2lä ul3len ul3l2i ulli2n ul2lo ul2lö2 ull3s2 ulm2e ulni2 ulo2i u2l1op u2l1or ulp1h ul2pha ul2sa ul4sam ul2s1ec ul2sei ul2ser ul2sum 2ult2a ul3tan ult3ar ul2tau ulter4m ul2tri ult3s u2lü ul2vr ulz2w 2uma. u2maa u2mab u2m1ad u2m1a2k um1all um1ang um1anz u2m1ap um1ar u2marc u2marm u2mart u2matl u2matm um1aus u2maut u2m1äh 1umd2 u3me. u2m1ef u2m1ein ume2n1e um5engel umer2a u2m1erf um1erg u3merk u2m1erl um1erw ume4s 1umf 4umfi 1umg um1ind um1inh um1ir umi2t um1ite 1umk 1uml umm4a 2umme um4mess um3mi um1ob u3mol um3ot ump2fa ump4fin umpf4li um2pho 1umr um4sam um4s3an 1umsat um2s1er um2sim um4sk um2s1pe um4stem um2sum um3t2 u2mum u2m1u2r 1umz un1 2un. 2una. 1unab 3unabh un2a3br un2ag un2al u3n2am u2n3an u2nap u2narb 2un2as un3at unau2s un2är 2und. un2da unda2b un2dän 1undd 2unde un3de. underer6 und3erf und3erö underten8 under8tend und3erz un2dex 1undf 2undg un2did un2dim 1undn undo2b un2dop un2dor 2un2d3r 4unds. 2undsc und3sp un2d1um undü4 1undv 1undz u3ne2 un3eid un3ein un2emi une4n1 unen2t une3re une3ri u4nerk u4n3erz. un2es2 unf2 un3fa unft2s un2gab un2gam un2gat 3ungena unger4e 1unget 1ungew 1ungl un2glu un2go un2gr ung3ri ung4s ungs3tr ungstra8s7 u3nic un2id un3ide 4unie 3u2nif uni3k4 un2im 1unio un2ir un3iro un3isl u3n2it 1u2niv 2unk un2k1a2 un3ker un2k1es un2ket un2kne un2ko2p un2kro unk3s2 unk4tit unk2tr unlö2 un4n1ad unn2e unne4n u2nob uno4r un2os 1unr uns2 2uns. unsch5el 1unsi un3sk un4ski un3sp uns4t unsta4g unst1r 2unsy 2unsz 1unt un3ta un3te unte4ri 2unti un3tr unt3s 2untu 3unty 2u2nu u3nuc u1nü unvol2 unvoll3 1unw 2unwä u2ny 2unz un3z2a unz2e 2uo u1o2b u3of u1op u1or u3or. uo2r3a uor3c u3oret uo2ris u3ors u1os. uote2 u1ox u1ö2d u1ök u1pa 3upd u1pe2 uper1 uperer4 up2fa upfe2 u1pfl u1p2fu u3p4i up4lu u3po 2upp up2pl u1pr upra3 u2p3ras up4t3a2 upten1 up4tene upt3erf upt3erg upt3erk upt3ers upt1o u1q 4ur. u1ra u2rab u3raba ura2be u2r1akt u2ral2t u2r1am ura4na u3rand uran6fän ur1ang uran4ge ur2anh uran5s ur1anz ur3ap u2r3ar ura4ri u3rasc ur1a4sp ura4str ur4a3te u2r1att ur1au 2u1rä ur1äl ur1ä2m ur1än ur3b2a 2urc urch1 urchas4 urcht3e ur3d2a ur3d2i ure1e ur1eff ur1eig u2rele ure2n ure4na u4ren4se u4rentn u2r1ep urer3h urer3k ur2ert u2rerw ur1eta ur2e3th ure3u 2urf ur2f3l ur2fro urf4spr urf3t ur6gense urg3inn urg1l ur2gla ur2gri uri2c ur1ide uri3en u2r1ind urin6sek urin8stin u2ri2so 2urli ur4matt ur2m1au urm2ei ur4mern urmet1 ur2mum ur2mun ur3n2e 2u1ro urob2l ur1off uroh2 uros4 urost2 2u1rö ur3p4 2urr ur3re ur2rh 3ursac ur2san ursau4 ur2s1er ur2s1of ur2spa ur2sun urt2 2urta ur4tai urt3ein ur2tro urts2c urts1t u3ru ur2z1a ur2zä ur2z1ec ur2zep ur2zi ur2z1op urzt4 ur2z1w 2us us3a2b usa2gi u4s1amb u4samt u2sang us2ann us3ark us5art usa4s us1ast us3ate u1sä u2säh u2s1äs u2sce u4schab u4schak u3sche. u4schef usch5eic u4sch3eu u3schi usch3mü u3schu usch5wer u3se. u3s2e3b u2s1ec use2ei u2s1ei u4sen4se u4sentl u3sep use4rec u2s1erl u2serp us1erw u2s1ese u2sex u2sid usi3er. usi5ers. u3sig usi4kat us1inn us3kl u4sko usmas2 usma5sse u1so us3oc us1oh u3sol u2sop us1orc us1ou u1sö u1sp u2spac us3part u2s1pas u3spec u3spek u2sph us1pic u2spo us2por u2spu usrich7 us2s3ad us2s3eb usse4g u4s3sel us2se4n us5sende us6seni us2sep us2ser us3ser. uss3erf usser4z us2sez u3s2sig uss3k us2sof us2sum u2stab u3stad u3stal us2ten us4ter ust3erl u3stis u2s1tor u2s3trä u4strit us2tum u2s1tur u1su u2sumd u2sumg u2sumz 3usus 2uß u2ß1u 2u1t 4ut. u3ta. u3taf u2t1alt ut1a2m ut2ans u2t1ap u2t1ar u2taut ut1äh u2tär ut3c u3te. u4t1e2d ut1ei. ut1eie ut1ein ut1ela ute2n1 uten2a u2tent ute4ral ute5r4er ute6ring uter3k ute4ros u3t2es ut2et u2t2ev u2t1ex utfi2 ut3hal ut3hei ut1hel u2t1hi u2t1ho u2thu u2t1id u4tigel uti2vi utli4n utmas2 utma5sse u3to. uto3c u5to3m uto1p uto3pa u2tops utor2a u2tord uto2re uto4rin 4utou u2töl 4utr ut3rea u2trou ut3rü utsau2 ut2säu ut4schl ut4schm ut4scho ut4schö ut3ser ut3s2k ut1s2p ut3sta ut3sto ut3tan ut3t4l utt1s2 utu2b u2tum utu4n u2t1une utu4re utu3ro utu5ru u4tz utze2 ut2zeh utz3eng utz2er ut2zet ut2z1in ut2zis ut2zö ut2z1w 2u1u4 uum1 uum3a2 uume2 uungsma5 uungsmas8 u1ü4 u1v4 u2ve. uve3rä u1w 2u1x ux2e ux2o ux3oe uxt4 u1y u2yo 2u1z uze2 u2z1ec u2z1ene uz2er uzo2f uz3ot uz1we uz3z2 1üb üb1ä 2übc 2übd übe2 übe3le übe4na übe3ne über1 überas4 ü4bet üb3l üb5r 2üc ü1che üch3l üch4s1c ücht4e ücke4n ück1er ück3eri ücker6ke ü4d3a4 üde2l üden2g ü3d2ens üd3o4 üdö4 üd3r üd3s2 üd3t4 üdu2 üdwe4 üe2 üeb3 ü1ei ü4f1a ü2f1ä ü2f1ei ü2fent üfer2 ü2f1erg üf2fl ü2f1i üf3l ü2fo üf3ten ü2fum ü1g üg2e üge2l1a2 üge2lä üge4lec üge6lei6s üge2lo ügen3s ü2g3l ü2gn üg3s üh3a2 ü1he ü2h1ei ü2h3e4m ü3hem. ü2h1eng ü2h1ent ü2h1erf ü2h1er2k ü2h1er2z ü2hex üh1i4 üh1lä üh2lel ühl2er üh2lö ühl4sk ühl4sta ühl4sti üh3mo üh3ne üh1o2 üh3r2e ühr3ei. ühre2n1 üh1ro ühr3ta ühs2 üh3sp üh3stu üh3t üht2a üht4r ü1hu üh1w ü1k2 ül1a ül2c ü3l2e ü4l3ef üle2r3a2 ül2la4 üll1ad üll1au ül2lei üll2er ül4leu ül2lic ül2lid ül2li2n ül2lo ül2lö ülls2 ü2lö ü1lu ü2ma ü2ment üme2ra ü2m1id ü2m1in ü2m1u 2ün ü4n3a ün2da ün2dr ü2n1erd ünf1 ünf3li ün2g3l üngs2 ünster3 ün2za ün2z1i ünzu2 ün2zun ün2zw ü1pe üpf3l ü1pi üp2pl 2ür ür1a ü2r1ei ü2r1e2l ür2f1er ür2fl ür2fr ür4g3en4g ürge4ra ürk2e ü3r2o3 ürom2 üror2 ür4ster ürte2l1 ürt2h ür2z1in ür2zö ür2z1w üs2a ü2schl ü3s2e üse1e2 üse3l2 üse4n üse3r4 ü1sp üs4s3a üs2s1c üss2e ü4s3sel üs4s3o üs4st üs2su üs4t ü2st3a ü4stei üste2n ü2str ü1su ü1ß 2üt ü1ta ü2t1al ü1te üte3m üte4n üten3s ütent4 üten3z2 üte2ra üte2r1e üterich6 üter3n ü2t1h ü1ti üt3r üt2se üt2s1t ütte4n üt2tr ü1tu üt3zen üt2zw ü1v ü1z 3va. 2v1ab vab4r va1c va1f4 va3g vag2a va4gh va2la 2valu v2an. 2vanb 2vang v2ans 2varb v1arm vas2 2v1ass va2s3to v4at va2t1a4 va4tag va2tei va4t3eng vates2 va2t3h va4tid vati3k2 va4tim va4t1in vati8ons. va4tord va4torg va2t3r vat3s2 va2t1u vat3z 2v1au vä1 2v1b 2v1c 2v1d2 1ve2 ve3an ve3ar veau3 ve3b4 ve3c ve3d ve3fa ve3g ve3h 2veig v2eil 2vein veit2 veits1 ve3la 2velan vel2ar ve4l1au v1ele ve3lei ve3l2i ve3lo vel2o1p ve3ma ve3me 2v1emp 2ve3mu ve3nal ve4nas ven2c ve3ne ve3ni ve4nin ve3nö ven5st ven4t3ag vent4sk ve3nü 2veo ve3of ve4pi ver1 ver3a ve3rad 2veral ve3rand ve3r4ane vera4s ver6bart ver3b2l ver3d2 vere2 verf4 ver3g4 vergas6 verga7sse ve3ri ve4rin ver3k vermas8sen vern2 ver4sep ver3sta vert4 ver5te ver3u4 ve3rus ve3s 2vesc 2vese ve4sh ve4s1p ves4t ve3ta vete1 vete3r ve3ti ve3tr ve3t2s 2veü ve3v ve3w 2v1f4 2v1g 2v1h vi1an vi3ar vi4a3t vi2ä vi3de 3vie vie2h1a vi2el viela2 viele2 vi2er vie4rec vie2w1 vig2 2vii v2il vi2l1a vi2lä vi4l1e2h vi2lei viler4 vi4lers vi2l1in vi2ma2 vi4na vin3d ving3 vings2 v1ins vi3sa vise4 vi3s2i vi3s2o vi2sp vis2u viv2 viz2 vize5 2v1k 2v1l4 v3le v2lie 2v1m vm2e 2v1n2 1vo 2v1ob vo2be vob4l voge2l1 vo2gu vol2a vol4la voll3ar voll7auf. vollen6 voll5end voller6t 2v1op vo2r1 vo4r3a voran8schl vor3g vo3ri vo4rie vo5rig vorm2 vormen4 vor3o vorö4 vort4 vot2a voy1 2v1p vr2 v1ra v2ree 3v2ri 2v1s2 v3sz 2v1t vue3 vu2enu vu2et 2vumf 2vumg 2vumk v1ü 2v1v 2v1w 2v1z w2a 1waa wab2bl wa3che wach8stub wach4t4r 1wack waffe2 waffel3 1wag wa5ge wage4n wa2g3n wa3go 1wah wahl5ent wah4ler wah2l1i 1wal wa2lar 2walb wal4d3a wal4din wal2dr wa2les wa3li wal4li4n wal2m1 wals2 walt1a wal6tere wal6terl wal2to wal4tur wa3na wan2d1a2 wan2dr w3anf 2wang wan3g2e wang4s 1wann wan6z5en6d wan4zer wa2p 1war2e ware1i wa5ren 1warn war4ni wart4e war2th war2za 1was wa3sa was2c wa4scha wa3sche wa3schi wa4sch3l wa4schw wa3sh wass4e2 wa3su w2ä 1wäh 1wäl wäm3 2wäng 1wäs3 wä5sc wä4ss wäss4e 2w3äu3 2w1b2 wbu2 2w1c 2w1d we2a we2b1a webe1i we2b3l we2bo we2b3r we2e2 weed3 we2fl 1weg we2g1a we4g1ei weg5ersc we4g3l we4gn we2g1o2 we4g3r weg1s weg3s2a 1weh weh4r3er4 wei2bl weib4r 2weie weifel6d wei4fre wei2gr wei3k4 1weil weinsau6 wei3sc wei2t1r weit1s wei5ze welle4 wel6schl wel6schr wel2t1 welt3a2 welte4 wel6t5en6d wel4th welt3i welt3r wem2ma2 wen3a2 wen2gl we3n2i wen2ka wen4kla wen4k3ri we2r3a2 wer5be werbe3i wer2bl werb2s 1werbu wer3d2 5werdens 1werdu werer2 wer2fl 2werg wer2ga wer6gels wer2g3o wer2gr werin2 we3rins we2ri4o 1werk. wer4k1a 1werke wer2ki wer2k3l wer2kn wer2k3o wer4k3re wer2ku we2rö wer4sta wer2ta wer2tä wert3ei wer6teig wer6t5erm wer2th wer4tin wer2t1o2 wer4tre wer4t3ri wer4tum 1we3s2e wesen4s3 we2sp wes4t we4st1a we4st3ei we5sten. we6sten6d we5stens we4steu we4sti we2st1o4 we2st3r we4stu 1wet 2wets wett3s 2w1ey 2w1f 2w1g whi2 w3ho w2i wicht4s 1wid wi2e 2wieb 1wied wie3l2 wie3n2e wie4st wik2 1wild wim2ma wim6ment wim4m3u win2a win4d3ec win3del win6d5erz 1win2d5r 4wing win2g3r win2kl win8n7er8sc win2no win4num win3s wint2 1wi4r wire3 wisch3l wi3s2e wi2sp 1wiss wiss4z wi3st wi3th 1witz. 1witzl wiz2 2w1k 2w1l 2w1m 2wn wns2a wn3sh 1wo1c wo2cha woch2e4 1woh woh4lei woh4na 1wolf wolf2s wol4la wol2lä wol4ler wor3a wor3d wo4r3i worn2 wort1a wor4tel wor6terh wor2t3r worts2 wo4r3u wor3ü wot2 1wöc wöl2fo wört2h 2w1p w2r w3re w3ro 2w1s ws2e w3s2h w3s2k w4s1u 2w1t wti2 w2u 1wuc wuch4sc wuch4st w3u2f wuls2 wul3se wund4e wung3r wung5s2 wun2s wunsch5l 4wur. wur2fa wur2f1o wur2fr wurs4 1wurst wus4 1wu2t1 1wüh 1würf 1würst wüs4 2w1w 2w1z x1a 1xa. 2xa2b 1x2ac 1x2ad 1xae xa1fl 1x2a3g2 2xal xal2l xa2m xand4 1xane 1xani x2an3t2 x2anz xa2r 1x2as xau3 xaus2 xa2z 2x1b4 x1ce x1ch x1cl 4x1d xda2 1xe 3xe. 2x1e4g 2xek xe2l 3xel. x1ele xe3lei x1em 3x2em. 2xemp x2ems x2en 3xen. xen3s2 3x2er. x2ere 2x1erl xer2la x2ern xers2 x2ers. 3xes 2x1eu 2x1ex 2x1f 2x1g 2x1h xi1c xich2 2xid xi2dan xide2 xi2dei xi2d3em x1i2do 3x2ie xie3l xi3g xi2ler xili3a xi2lo xi2l1u xim2 xin3s2 x2is xi2sa xi2s1e xi2sp xis5s2 xi3s2tä xi2su 3xit x1i4tu xive4 x1j 4x1k2 xkal2 4x2l2 x3lä x3le 2x1m 2x1n 2xod 2xoe4 x1o2r xos2 2x1ö2 4x1p xpor6ter xpor4t3r x1q x1r 2x3s2 4x1t xt1a x3ta. xta2b3 x3tan xt2ant x3tas x2t1ä x3tät xtblock5 x2t1e2d xt1ein x2t1el x2tent x2t1er2f x2t1ev xtfi2 x2t1h x2t1id xti2la x2til2l x2t1o4 xtra3b4 x2t3ran x2trau xt3rec xt3s2 x2t1um x2t1un 1xu xu1a xu2n 2xunt xu2s3 xusa2 xuss2 2xv 2x1w 3xy. x1z 2y1ab 1ya2c y2ach ya1h y1al. yan2g y1ank ya1q ya3ra y1ät y1b ybe2r y1c y2chi y3chis ych3n y1d yd4r ydri2 ydrid3 ydro3 y1e y2ec ye2d y2ef y2el2 yen4n yera2 y2ere yer2n1 y2e2s y4es. ye3s2p ye4st ye2th y1f2 y1g ygi2 ygie3 yg2l y1h y3ho yhr2 2y1i4 y1j y1k2 yke3n yk3s yl1a2 yl2a3g y1l2ak yla4l y2lam yl3ane y1lant yl4ante yl4anti yl2as ylau2 yl3c yle4 y2le. yl1em y2l1es y2l1et yli4n yl4lo2s yl2lö2 ylo1i2 yloid3 yloni1 yl2op yl1ora ym2a ym4an ym4ar ym4as ym4e ymp2 ym2pha ympi1e ynä4r yn2eu ynk2 y2n1o2 yn2oz yn3t2 yob2 y2od yoga3 yom2 yon2a y1ont y1o2pe y2ost y1ou 2y1p ypa2b3 ypa2n yp2e2 ype4r3o2 y2pf y2p1i2d y2p1in y2plo y3po3 y4p3s yp3th ypu2 y2p1um y1q y1r y3r2e y3ri yri1e yri3en y3ro yro4ste yrr2 2y1s ys2an ysch4 ys2e1 ysein2 ys1er y4s3l ysme3 ys2o ys2pi yst2e yst2h ys2tra y4stro y3s2ty ysu2 y3s2z y1t y2te. y2tes yt2h ythe1 y3to y4t3r yu2r yur2e3 y1v y1w y1y y1z2 yzer2i 2z1a2b zab3l 2z1ach za1cha za1chä zach2s 2z1a2d 2z1af za3gr 3z2ah zah3len zah4ner4 z1ak 4z3akk 2z1al 4z3ald 3zali 2z1a2m z1a2n 4z3a4n4a 2z3anb za3ne 2z3anf 2z3angs 3z2ank zan2ka z3anl 2z3anr zanti1 za4pf z1aq z1ar 3zar. 2zarb za3re 2zarm 3z2aro z2arr zar2t1r 2z1as za3st4 2z1aß z3at zat2e za2to 3zaub 2z1au2f 2z3aug 3zaun z3aur 2z1aut 2z1äc z2äh 3zähn 2z1äm z1än z1äp z1är 2z1äus 2zäuß 4z3b4 zber2e zbü1b zbübe3 2z3c 2z3d2 zdan2 zdä1 3ze. 2zea zeau3 zeaus4 2z1e2ben 2z1echo ze1e2 zeeu3 2z1eff z1e2ga zehe4 zehen1 zeh2l ze3ho zei1f4 zeik4 zeil2 zei3la zeile4 2z1ein ze3in. zeinbus6 z2e1ind zei4ne 4z3einh ze3inse ze2i3s2 3zeit zei2t1a zei4t3er zei2to zei2tr zeit3ri zek4 ze2l1a zela2d zel3a2n zelau2 ze2l1ä zel3d4 4ze2lek 4zelem ze2len ze2l1er ze2l1in 2z1e2lit zel3la zel4lab zel4l3ac zel4lar zel2lä zel4leh zel6lein zel6ler6t zeller6z zelli4n zel4lum zelm4 ze2l1o zels2 zel3sa zel3sz zel2ti zelu2 zembe2 2z1emp 5zen. ze4n1ac ze4nas zen3au ze2nä ze3n2em zenen1 4zenge. z4engl 2zengp 2zeni ze2nid zenk2 zen3n ze2n3o ze4not 4zen4sem zen4ser zens2p z2entn z1ents 2zentw 2zentz ze2nu zen4z3er zen2zw zeo4r 3z2er. zer3a ze1ral ze2rat z2ere ze5rek zer2em z2erfe z3erfül z2erga 2z1ergä 4z3ergeb z4erges z4ergl zer4gon 4zergu 3z2erhe 2z3erhö ze3ri zerin6te z2erko 3zerl. zer4lau zer4le. 4zerleb zer4len 2zerlö 3z2ern zer4nan zer4n3e4b zer4nei 2z1erö zer2öf 2z1erq 4z3erreg z2ers. 2z1er4sa zerta2 zer4t3ag zert4an zer4tau zer6tere zer6terl zer4tin zer2to 6z5ertrag zer6trau z1erwe 4zerwei z1erz zer2ze ze2s 3z2es. ze3sc zes1e zes3er ze4s3po zes2sa zessen4 zes6s5end zes4ser4 zes2sp ze3sta zes2th ze3str ze2ß1 z2et. 2zeta 2ze2th ze2tr 2zetts zeu4gem zeu2g3r 2z1eul ze1ur 2z1e2x1 2z3f4 zfäs3 zfeue2 2z3g4 zgang5 zger2a zger2s1 2z1h2 z2hen zhir3 3zi. zial5l zi3alo zi2ar zich2o zi2dei zid3r zie4ler zie2l1i zi1erh zi1es zi3ess 3zig 3z2il zil2e z2imm 2zimp zim2t3 2z1ind zin2e zin3ei 2z1inf z1inh zi4n3in zin1it 2z1inj zin4na zin4o zin2sa zin4ser 4zinsuf zi2o3 zirk2 zirk6s z1iso zi2sp zisse4 zis4t zistras6 zi3s2z zite4 zithe2 zi2t1o2 zit2u ziv2 2z1j 4z1k4 2z1l2 z3ly 2z3m2 zmas6sen zme2e 2z3n2 z3oas 2z1ob 2z1of zo2gl zog4s 2z1oh zolla2 zol3len zoller4 zol2li2 zonal2 zon3au zon5s4 zon4t3er zo2o 2z1ope 2z1o2r zo3re 3z2orn zor4ne 2z1osz 2z1ou 2z1o2z 2zö2f 2z1ök z1öl 2zöl. 3z2öll 2zöls 2zön 2z3p4 2z1q 2z3r2 2z1s2 z3sa zsau2 z3sh z3sk zspor2 4zst z3str z3sz 2z1t zta2n zt3ane z2t1au ztein1 zt3eins zt2el zte3ma z2t1ent z2t1erz z3tes zte3str zt2et zt1he z3them z3t2her zt1hi zt3ho z3thr z3thy zt3rec zt3ric zt3s zu3a zu1ä2 zub4 zubus2 3zuc zuch2e zucht3r zud4 zudi4 zu2el zu3e2r1 zue2t zu3f4 zug2em zu4gent zug2i zu3gl zu4gla zu4glö zu2go zug4ste 2z1uhr zu3hu zu1i2 zu3k zul2 2z1um. zum2a 2z1umb zumen2 2zumf 2zumg zum2i 2zumk 2zuml 2zumr 2z1ums zum2u 2zunab zun2e 2z1unem 4zunget 2zungl z1uni 2zu2nio 2zuniv 2zunr 2z1uns 2zunt zuo2 zup2fi zu3pl zu3r2a 2z1urk 2z1url 2z1urn 2z1urs 2z1urt zu3s2 zusch4 zu3t2 zut4r zut4u zut3z zuz2 2zü4b 3züc zür1c 2z1v zw2 z1wac 2zwag 4zwah 4zwap z1war 2zwa2s 2zwäs 2z1wed 2zweg 2zweh z2weig 2zweil zweiter6 2z1wel 2z1wen 2z1wer 2z1wes z2wic zwi4e 3zwing 2zwirt z2wisc 2zwiss z2wit 2z1wo z1wör z1wur 2z1wü zy1an. zy2le 2z1z z3z2a zza3b4 z4z3al zz4at zze3s z2z1id z2z1in1 zz2ö zzug4s", ["lefthyphenmin"]=1, - ["length"]=104906, - ["n"]=15624, + ["length"]=170328, + ["n"]=24631, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/patterns/mkiv/lang-fr.lua b/tex/context/patterns/mkiv/lang-fr.lua index 9ff7e42b2..3e8983588 100644 --- a/tex/context/patterns/mkiv/lang-fr.lua +++ b/tex/context/patterns/mkiv/lang-fr.lua @@ -6,13 +6,16 @@ return { ["metadata"]={ ["mnemonic"]="fr", ["source"]="hyph-fr", - ["texcomment"]="% copyright: Daniel Flipo, Bernard Gaulle 1994-2002\ + ["texcomment"]="% copyright: Daniel Flipo and Bernard Gaulle 1994-2002, Arthur Reutenauer 2016\ % title: French hyphenation patterns\ -% version: V2.12 2002/12/11\ +% version: V2.13 2016/05/12\ +% language:\ +% name: French\ +% tag: fr\ % notice: >\ % This file is part of the hyph-utf8 package.\ % See http://www.hyphenation.org for more information.\ -% license:\ +% licence:\ % name: MIT\ % url: https://opensource.org/licenses/MIT\ % text: >\ @@ -55,10 +58,10 @@ return { }, ["patterns"]={ ["characters"]="'abcdefghijklmnopqrstuvwxyzàâçèéêîïôûœ’", - ["data"]="2'2 2’2 .a4 'a4 ’a4 .â4 'â4 ’â4 ab2h .ab3réa 'ab3réa ’ab3réa ad2h a1è2dre .ae3s4ch 'ae3s4ch ’ae3s4ch 1alcool a2l1algi .amino1a2c 'amino1a2c ’amino1a2c .ana3s4tr 'ana3s4tr ’ana3s4tr 1a2nesthési .anti1a2 'anti1a2 ’anti1a2 .anti1e2 'anti1e2 ’anti1e2 .anti1é2 .anti2enne 'anti2enne ’anti2enne 'anti1é2 ’anti1é2 .anti1s2 'anti1s2 ’anti1s2 .apo2s3ta 'apo2s3ta ’apo2s3ta apo2s3tr archi1é2pis .as2ta 'as2ta ’as2ta a2s3tro 1ba 1bâ .bai2se3main 1be 1bé 1bè 1bê 4be. 4bes. 2bent. 1bi 1bî .bi1a2c .bi1a2t .bi1au .bio1a2 .bi2s1a2 .bi1u2 1b2l 4ble. 4bles. 2blent. 1bo 1bô 1b2r 4bre. 4bres. 2brent. 1bu 1bû 1by 1ç 1ca 1câ ca3ou3t2 1ce 1cé 1cè 1cê 4ce. 4ces. 2cent. ja3cent. ac3cent. é3cent. munifi3cent. réti3cent. privatdo3cent. inno3cent. es3cent. acquies4cent. is3cent. immis4cent. .ch4 1c2h 4ch. 2chb 4che. 4ches. 2chent. .chè2vre3feuille 2chg ch2l 4chle. 4chles. chlo2r3a2c chlo2r3é2t 2chm 2chn 2chp ch2r 4chre. 4chres. 2chs 2cht 2chw 1ci 1cî .ci2s1alp 1c2k 4ck. 2ckb 4cke. 4ckes. 2ckent. 2ckf 2ckg 2ck3h 2ckp 2cks 2ckt 1c2l 4cle. 4cles. 2clent. 1co 1cô co1acc co1acq co1a2d co1ap co1ar co1assoc co1assur co1au co1ax 1cœ co1é2 co1ef co1en co1ex .con4 .cons4 .contre1s2c .contre3maître co2nurb .co1o2 .co2o3lie 1c2r 4cre. 4cres. 2crent. 1cu 1cû 1cy .cul4 1d' 1d’ 1da 1dâ .dacryo1a2 d1d2h 1de 1dé 1dè 1dê 4de. 4des. 2dent. déca3dent. é3dent. cci3dent. inci3dent. confi3dent. tri3dent. dissi3dent. chien3dent. .ar3dent. impu3dent. pru3dent. .dé1a2 .dé1io .dé1o2 .dé2s .dé3s2a3cr .dés2a3m .dé3s2a3tell .dé3s2astr .dé3s2c .dé2s1é2 .dé3s2é3gr .dé3s2ensib .dé3s2ert .dé3s2exu .dé2s1i2 .dé3s2i3d .dé3s2i3gn .dé3s2i3li .dé3s2i3nen .dé3s2invo .dé3s2i3r .dé3s2ist .dé3s2o3dé .dé2s1œ .dé3s2o3l .dé3s2o3pil .dé3s2orm .dé3s2orp .dé3s2oufr .dé3s2p .dé3s2t .dé2s1u2n 3d2hal 3d2houd 1di 1dî di2s3cop .di1a2cé .di1a2cid .di1ald .di1a2mi .di1a2tom .di1e2n .di2s3h 2dlent. 1do 1dô 1d2r 4dre. 4dres. 2drent. d1s2 1du 1dû 1dy .dy2s3 .dy2s1a2 .dy2s1i2 .dy2s1o2 .dy2s1u2 .e4 'e4 ’e4 .ê4 'ê4 ’ê4 .é4 'é4 ’é4 .è4 'è4 ’è4 éd2hi 1é2drie 1é2drique 1é2lectr 1é2lément .en1a2 'en1a2 ’en1a2 1é2nerg e2n1i2vr .en1o2 'en1o2 ’en1o2 épi2s3cop épi3s4cope e2s3cop .eu2r1a2 'eu2r1a2 ’eu2r1a2 eu1s2tat extra1 extra2c extra2i 1fa 1fâ 1fe 1fé 1fè 1fê 4fe. 4fes. 2fent. 1fi 1fî 1f2l 4fle. 4fles. 2flent. 1fo 1fô 1f2r 4fre. 4fres. 2frent. f1s2 1fu 1fû 1fy 1ga 1gâ 1ge 1gé 1gè 1gê 4ge. 4ges. 2gent. ré3gent. entre3gent. indi3gent. dili3gent. intelli3gent. indul3gent. tan3gent. rin3gent. contin3gent. .ar3gent. 'ar3gent. ’ar3gent. ser3gent. ter3gent. résur3gent. 1g2ha 1g2he 1g2hi 1g2ho 1g2hy 1gi 1gî 1g2l 4gle. 4gles. 2glent. 1g2n 'a2g3nat ’a2g3nat .a2g3nat a2g3nos co2g3niti 'i2g3né ’i2g3né .i2g3né 'i2g3ni ’i2g3ni .i2g3ni .ma2g3nicide .ma2g3nificat .ma2g3num o2g3nomoni o2g3nosi .pro2g3nath pu2g3nable pu2g3nac .sta2g3n .syn2g3nath wa2g3n 4gne. 4gnes. 2gnent. 1go 1gô 1g2r 4gre. 4gres. 2grent. 1gu 1gû g1s2 4gue. 4gues. 2guent. .on3guent. 'on3guent. ’on3guent. 1gy 1ha 1hâ 1he 1hé 1hè 1hê hémi1é hémo1p2t 4he. 4hes. 1hi 1hî 1ho 1hô 1hu 1hû 1hy hypera2 hypere2 hyperé2 hyperi2 hypero2 hypers2 hype4r1 hyperu2 hypo1a2 hypo1e2 hypo1é2 hypo1i2 hypo1o2 hypo1s2 hypo1u2 .i4 'i4 ’i4 .î4 'î4 ’î4 i1algi i1arthr i1è2dre il2l cil3l rcil4l ucil4l vacil4l gil3l hil3l lil3l l3lion mil3l mil4let émil4l semil4l rmil4l armil5l capil3l papil3la papil3le papil3li papil3lom pupil3l piril3l thril3l cyril3l ibril3l pusil3l .stil3l distil3l instil3l fritil3l boutil3l vanil3lin vanil3lis vil3l avil4l chevil4l uevil4l uvil4l xil3l 1informat .in1a2 'in1a2 ’in1a2 .in2a3nit 'in2a3nit ’in2a3nit .in2augur 'in2augur ’in2augur .in1e2 'in1e2 ’in1e2 .in1é2 'in1é2 ’in1é2 .in2effab 'in2effab ’in2effab .in2é3lucta 'in2é3lucta ’in2é3lucta .in2é3narra 'in2é3narra ’in2é3narra .in2ept 'in2ept ’in2ept .in2er 'in2er ’in2er .in2exora 'in2exora ’in2exora .in1i2 'in1i2 ’in1i2 .in2i3miti 'in2i3miti ’in2i3miti .in2i3q 'in2i3q ’in2i3q .in2i3t 'in2i3t ’in2i3t .in1o2 'in1o2 ’in1o2 .in2o3cul 'in2o3cul ’in2o3cul .in2ond 'in2ond ’in2ond .in1s2tab 'in1s2tab ’in1s2tab 'inte4r3 ’inte4r3 .intera2 'intera2 ’intera2 .intere2 'intere2 ’intere2 .interé2 'interé2 ’interé2 .interi2 'interi2 ’interi2 .intero2 'intero2 ’intero2 .inte4r3 .interu2 'interu2 ’interu2 .inters2 'inters2 ’inters2 .in1u2 'in1u2 ’in1u2 .in2uit 'in2uit ’in2uit .in2u3l 'in2u3l ’in2u3l io1a2ct i1oxy i1s2tat 1j 2jk 4je. 4jes. 2jent. 1ka 1kâ 1ke 1ké 1kè 1kê 4ke. 4kes. 2kent. 1k2h 4kh. .kh4 1ki 1kî 1ko 1kô 1k2r 1ku 1kû 1ky 1la 1lâ 1là la2w3re 1le 1lé 1lè 1lê 4le. 4les. 2lent. .ta3lent. iva3lent. équiva4lent. monova3lent. polyva3lent. re3lent. .do3lent. indo3lent. inso3lent. turbu3lent. succu3lent. fécu3lent. trucu3lent. opu3lent. corpu3lent. ru3lent. sporu4lent. 1li 1lî 1lo 1lô l1s2t 1lu 1lû 1ly 1ma 1mâ .ma2c3k .macro1s2c .ma2l1a2dres .ma2l1a2dro .ma2l1aisé .ma2l1ap .ma2l1a2v .ma2l1en .ma2l1int .ma2l1oc .ma2l1o2d .ma2r1x 1me 1mé 1mè 1mê .mé2g1oh .mé2sa .mé3san .mé2s1es .mé2s1i .mé2s1u2s .méta1s2ta 4me. 4mes. â2ment. da2ment. fa2ment. amalga2ment. cla2ment. ra2ment. tempéra3ment. ta2ment. testa3ment. qua2ment. è2ment. carê2ment. diaphrag2ment. ryth2ment. ai2ment. rai3ment. abî2ment. éci2ment. vidi2ment. subli2ment. éli2ment. reli2ment. mi2ment. ani2ment. veni2ment. ri2ment. détri3ment. nutri3ment. inti2ment. esti2ment. l2ment. flam2ment. gram2ment. .gem2ment. om2ment. .com3ment. ô2ment. slalo2ment. chro2ment. to2ment. ar2ment. .sar3ment. er2ment. antifer3ment. .ser3ment. fir2ment. or2ment. as2ment. au2ment. écu2ment. fu2ment. hu2ment. fichu3ment. llu2ment. plu2ment. bou2ment. bru2ment. su2ment. tu2ment. 1mi 1mî .milli1am 1m2némo 1m2nès 1m2nési 1mo 1mô 1mœ .mono1a2 .mono1e2 .mono1é2 .mono1i2 .mono1ï2dé .mono1o2 .mono1u2 .mono1s2 mon2t3réal m1s2 1mu 1mû 1my moye2n1â2g 1na 1nâ 1ne 1né 1nè 1nê 4ne. 4nes. 2nent. réma3nent. imma3nent. perma3nent. .émi3nent. préémi3nent. proémi3nent. surémi3nent. immi3nent. conti3nent. perti3nent. absti3nent. 1ni 1nî 1no 1nô 1nœ .no2n1obs 1nu 1nû n3s2at. n3s2ats. n1x 1ny .o4 'o4 ’o4 'ô4 ’ô4 .ô4 o2b3long 1octet o1d2l o1è2dre o1ioni ombud2s3 omni1s2 o1s2tas o1s2tat o1s2téro o1s2tim o1s2tom o1s2trad o1s2tratu o1s2triction .oua1ou 'oua1ou ’oua1ou .ovi1s2c 'ovi1s2c ’ovi1s2c oxy1a2 1pa 1pâ paléo1é2 .pa2n1a2f .pa2n1a2mé .pa2n1a2ra .pa2n1is .pa2n1o2ph .pa2n1opt .pa2r1a2che .pa2r1a2chè .para1s2 .pa2r3hé 1pe 1pé 1pè 1pê 4pe. 4pes. 2pent. re3pent. .ar3pent. 'ar3pent. ’ar3pent. ser3pent. .pen2ta per3h pé2nul .pe4r .per1a2 .per1e2 .per1é2 .per1i2 .per1o2 .per1u2 pé1r2é2q .péri1os .péri1s2 .péri2s3s .péri2s3ta .péri1u2 1p2h .ph4 4ph. .phalan3s2t 4phe. 4phes. 2phent. ph2l 4phle. 4phles. 2phn photo1s2 ph2r 4phre. 4phres. 2phs 2pht 3ph2talé 3ph2tis 1pi 1pî 1p2l 4ple. 4ples. 2plent. .pluri1a 1p2né 1p2neu 1po 1pô po1astre poly1a2 poly1e2 poly1é2 poly1è2 poly1i2 poly1o2 poly1s2 poly1u2 .pon2tet .pos2t3h .pos2t1in .pos2t1o2 .pos2t3r .post1s2 1p2r 4pre. 4pres. 2prent. .pré1a2 .pré2a3la .pré2au .pré1é2 .pré1e2 .pré1i2 .pré1o2 .pré1u2 .pré1s2 .pro1é2 .pro1s2cé pro2s3tat .prou3d2h 1p2sych .psycho1a2n 1p2tèr 1p2tér 1pu .pud1d2l 1pû 1py 1q 4que. 4ques. 2quent. é3quent. élo3quent. grandilo3quent. 1ra 1râ radio1a2 1re 1ré 1rè 1rê .ré1a2 .ré2a3le .ré2a3lis .ré2a3lit .ré2aux .ré1é2 .ré1e2 .ré2el .ré2er .ré2èr .ré1i2 .ré2i3fi .ré1o2 .re1s2 .re2s3cap .re2s3cisi .re2s3ciso .re2s3cou .re2s3cri .re2s3pect .re2s3pir .re2s3plend .re2s3pons .re2s3quil .re2s3s .re2s3t .re3s4tab .re3s4tag .re3s4tand .re3s4tat .re3s4tén .re3s4tér .re3s4tim .re3s4tip .re3s4toc .re3s4top .re3s4tr .re4s5trein .re4s5trict .re4s5trin .re3s4tu .re3s4ty .réu2 .ré2uss .rétro1a2 4re. 4res. 2rent. .pa3rent. appa3rent. transpa3rent. é3rent. tor3rent. cur3rent. 1r2h 4rhe. 4rhes. 2r3heur 2r3hydr 1ri 1rî 1ro 1rô 1ru 1rû 1ry 1sa 1sâ .sch4 1s2caph 1s2clér 1s2cop 1s2ch e2s3ch i2s3ché i2s3chia i2s3chio 4sch. 4sche. 4sches. 2schs 1se 1sé 1sè 1sê sesqui1a2 4se. 4ses. 2sent. ab3sent. pré3sent. .res3sent. .seu2le .sh4 1s2h 4sh. 4she. 4shes. 2shent. 2shm 2s3hom 2shr 2shs 1si 1sî 1s2lav 1s2lov 1so 1sô 1sœ 1s2patia 1s2perm 1s2por 1s2phèr 1s2phér 1s2piel 1s2piros 1s2tandard 1s2tein stéréo1s2 1s2tigm 1s2tock 1s2tomos 1s2troph 1s2tructu 1s2tyle 1su 1sû .su2b1a2 .su3b2alt .su2b1é2 .su3b2é3r .su2b1in .su2b3limin .su2b3lin .su2b3lu sub1s2 .su2b1ur supero2 supe4r1 supers2 .su2r1a2 su3r2ah .su3r2a3t .su2r1e2 .su3r2eau .su3r2ell .su3r2et .su2r1é2 .su2r3h .su2r1i2m .su2r1inf .su2r1int .su2r1of .su2r1ox 1sy 1ta 1tâ 1tà tachy1a2 tchin3t2 1te 1té 1tè 1tê télé1e2 télé1i2 télé1o2b télé1o2p télé1s2 4te. 4tes. 2tent. .la3tent. .pa3tent. compé3tent. éni3tent. mécon3tent. omnipo3tent. ventripo3tent. équipo3tent. impo3tent. mit3tent. .th4 1t2h 4th. 4the. 4thes. thermo1s2 2t3heur 2thl 2thm 2thn th2r 4thre. 4thres. 2ths 1ti 1tî 1to 1tô 1t2r tran2s1a2 tran3s2act tran3s2ats tran2s3h tran2s1o2 tran2s3p tran2s1u2 4tre. 4tres. 2trent. .tri1a2c .tri1a2n .tri1a2t .tri1o2n t1t2l 1tu 1tû tung2s3 1ty .u4 'u4 ’u4 .û4 'û4 ’û4 uni1o2v uni1a2x u2s3tr 1va 1vâ 1ve 1vé 1vè 1vê vélo1s2ki 4ve. 4ves. 2vent. conni3vent. .sou3vent. 1vi 1vî 1vo 1vô vol2t1amp 1v2r 4vre. 4vres. 2vrent. 1vu 1vû 1vy 1wa 1we 4we. 4wes. 2went. 1wi 1wo 1wu 1w2r 2xent. .y4 'y4 ’y4 y1asth y1s2tom y1algi 1za 1ze 1zé 1zè 4ze. 4zes. 2zent. privatdo3zent. 1zi 1zo 1zu 1zy", + ["data"]="2'2 2’2 .a4 'a4 ’a4 .â4 'â4 ’â4 ab2h .ab3réa 'ab3réa ’ab3réa ad2h a1è2dre .ae3s4ch 'ae3s4ch ’ae3s4ch 1alcool '2alcool ’2alcool a2l1algi .amino1a2c 'amino1a2c ’amino1a2c .ana3s4tr 'ana3s4tr ’ana3s4tr 1a2nesthési '2a2nesthési ’2a2nesthési .anti1a2 'anti1a2 ’anti1a2 .anti1e2 'anti1e2 ’anti1e2 .anti1é2 .anti2enne 'anti2enne ’anti2enne 'anti1é2 ’anti1é2 .anti1s2 'anti1s2 ’anti1s2 .apo2s3ta 'apo2s3ta ’apo2s3ta apo2s3tr archi1é2pis .as2ta 'as2ta ’as2ta a2s3tro 1ba 1bâ .bai2se3main 1be 1bé 1bè 1bê 4be. 4bes. 2bent. 1bi 1bî .bi1a2c .bi1a2t .bi1au .bio1a2 .bi2s1a2 .bi1u2 1b2l 4ble. 4bles. 2blent. 1bo 1bô 1b2r 4bre. 4bres. 2brent. 1bu 1bû 1by 1ç 1ca 1câ ca3ou3t2 1ce 1cé 1cè 1cê 4ce. 4ces. 2cent. ja3cent. ac3cent. é3cent. munifi3cent. réti3cent. privatdo3cent. inno3cent. es3cent. acquies4cent. is3cent. immis4cent. .ch4 1c2h 4ch. 2chb 4che. 4ches. 2chent. .chè2vre3feuille 2chg ch2l 4chle. 4chles. chlo2r3a2c chlo2r3é2t 2chm 2chn 2chp ch2r 4chre. 4chres. 2chs 2cht 2chw 1ci 1cî .ci2s1alp 1c2k 4ck. 2ckb 4cke. 4ckes. 2ckent. 2ckf 2ckg 2ck3h 2ckp 2cks 2ckt 1c2l 4cle. 4cles. 2clent. 1co 1cô co1acc co1acq co1a2d co1ap co1ar co1assoc co1assur co1au co1ax 1cœ co1é2 co1ef co1en co1ex .con4 .cons4 .contre1s2c .contre3maître co2nurb .co1o2 .co2o3lie 1c2r 4cre. 4cres. 2crent. 1cu 1cû 1cy .cul4 1d' 1d’ 1da 1dâ .dacryo1a2 d1d2h 1de 1dé 1dè 1dê 4de. 4des. 2dent. déca3dent. é3dent. cci3dent. inci3dent. confi3dent. tri3dent. dissi3dent. chien3dent. .ar3dent. impu3dent. pru3dent. .dé1a2 .dé1io .dé1o2 .dé2s .dé3s2a3cr .dés2a3m .dé3s2a3tell .dé3s2astr .dé3s2c .dé2s1é2 .dé3s2é3gr .dé3s2ensib .dé3s2ert .dé3s2exu .dé2s1i2 .dé3s2i3d .dé3s2i3gn .dé3s2i3li .dé3s2i3nen .dé3s2invo .dé3s2i3r .dé3s2ist .dé3s2o3dé .dé2s1œ .dé3s2o3l .dé3s2o3pil .dé3s2orm .dé3s2orp .dé3s2oufr .dé3s2p .dé3s2t .dé2s1u2n 3d2hal 3d2houd 1di 1dî di2s3cop .di1a2cé .di1a2cid .di1ald .di1a2mi .di1a2tom .di1e2n .di2s3h 2dlent. 1do 1dô 1d2r 4dre. 4dres. 2drent. d1s2 1du 1dû 1dy .dy2s3 .dy2s1a2 .dy2s1i2 .dy2s1o2 .dy2s1u2 .e4 'e4 ’e4 .ê4 'ê4 ’ê4 .é4 'é4 ’é4 .è4 'è4 ’è4 éd2hi 1é2drie 1é2drique 1é2lectr 1é2lément .en1a2 'en1a2 ’en1a2 1é2nerg e2n1i2vr .en1o2 'en1o2 ’en1o2 épi2s3cop épi3s4cope e2s3cop .eu2r1a2 'eu2r1a2 ’eu2r1a2 eu1s2tat extra1 extra2c extra2i 1fa 1fâ 1fe 1fé 1fè 1fê 4fe. 4fes. 2fent. 1fi 1fî 1f2l 4fle. 4fles. 2flent. 1fo 1fô 1f2r 4fre. 4fres. 2frent. f1s2 1fu 1fû 1fy 1ga 1gâ 1ge 1gé 1gè 1gê 4ge. 4ges. 2gent. ré3gent. entre3gent. indi3gent. dili3gent. intelli3gent. indul3gent. tan3gent. rin3gent. contin3gent. .ar3gent. 'ar3gent. ’ar3gent. ser3gent. ter3gent. résur3gent. 1g2ha 1g2he 1g2hi 1g2ho 1g2hy 1gi 1gî 1g2l 4gle. 4gles. 2glent. 1g2n 'a2g3nat ’a2g3nat .a2g3nat a2g3nos co2g3niti 'i2g3né ’i2g3né .i2g3né 'i2g3ni ’i2g3ni .i2g3ni .ma2g3nicide .ma2g3nificat .ma2g3num o2g3nomoni o2g3nosi .pro2g3nath pu2g3nable pu2g3nac .sta2g3n .syn2g3nath wa2g3n 4gne. 4gnes. 2gnent. 1go 1gô 1g2r 4gre. 4gres. 2grent. 1gu 1gû g1s2 4gue. 4gues. 2guent. .on3guent. 'on3guent. ’on3guent. 1gy 1ha 1hâ 1he 1hé 1hè 1hê hémi1é hémo1p2t 4he. 4hes. 1hi 1hî 1ho 1hô 1hu 1hû 1hy hypera2 hypere2 hyperé2 hyperi2 hypero2 hypers2 hype4r1 hyperu2 hypo1a2 hypo1e2 hypo1é2 hypo1i2 hypo1o2 hypo1s2 hypo1u2 .i4 'i4 ’i4 .î4 'î4 ’î4 i1algi i1arthr i1è2dre il2l cil3l rcil4l ucil4l vacil4l gil3l hil3l lil3l l3lion mil3l mil4let émil4l semil4l rmil4l armil5l capil3l papil3la papil3le papil3li papil3lom pupil3l piril3l thril3l cyril3l ibril3l pusil3l .stil3l distil3l instil3l fritil3l boutil3l vanil3lin vanil3lis vil3l avil4l chevil4l uevil4l uvil4l xil3l 1informat '2informat ’2informat .in1a2 'in1a2 ’in1a2 .in2a3nit 'in2a3nit ’in2a3nit .in2augur 'in2augur ’in2augur .in1e2 'in1e2 ’in1e2 .in1é2 'in1é2 ’in1é2 .in2effab 'in2effab ’in2effab .in2é3lucta 'in2é3lucta ’in2é3lucta .in2é3narra 'in2é3narra ’in2é3narra .in2ept 'in2ept ’in2ept .in2er 'in2er ’in2er .in2exora 'in2exora ’in2exora .in1i2 'in1i2 ’in1i2 .in2i3miti 'in2i3miti ’in2i3miti .in2i3q 'in2i3q ’in2i3q .in2i3t 'in2i3t ’in2i3t .in1o2 'in1o2 ’in1o2 .in2o3cul 'in2o3cul ’in2o3cul .in2ond 'in2ond ’in2ond .in1s2tab 'in1s2tab ’in1s2tab 'inte4r3 ’inte4r3 .intera2 'intera2 ’intera2 .intere2 'intere2 ’intere2 .interé2 'interé2 ’interé2 .interi2 'interi2 ’interi2 .intero2 'intero2 ’intero2 .inte4r3 .interu2 'interu2 ’interu2 .inters2 'inters2 ’inters2 .in1u2 'in1u2 ’in1u2 .in2uit 'in2uit ’in2uit .in2u3l 'in2u3l ’in2u3l io1a2ct i1oxy i1s2tat 1j 2jk 4je. 4jes. 2jent. 1ka 1kâ 1ke 1ké 1kè 1kê 4ke. 4kes. 2kent. 1k2h 4kh. .kh4 1ki 1kî 1ko 1kô 1k2r 1ku 1kû 1ky 1la 1lâ 1là la2w3re 1le 1lé 1lè 1lê 4le. 4les. 2lent. .ta3lent. iva3lent. équiva4lent. monova3lent. polyva3lent. re3lent. .do3lent. indo3lent. inso3lent. turbu3lent. succu3lent. fécu3lent. trucu3lent. opu3lent. corpu3lent. ru3lent. sporu4lent. 1li 1lî 1lo 1lô l1s2t 1lu 1lû 1ly 1ma 1mâ .ma2c3k .macro1s2c .ma2l1a2dres .ma2l1a2dro .ma2l1aisé .ma2l1ap .ma2l1a2v .ma2l1en .ma2l1int .ma2l1oc .ma2l1o2d .ma2r1x 1me 1mé 1mè 1mê .mé2g1oh .mé2sa .mé3san .mé2s1es .mé2s1i .mé2s1u2s .méta1s2ta 4me. 4mes. â2ment. da2ment. fa2ment. amalga2ment. cla2ment. ra2ment. tempéra3ment. ta2ment. testa3ment. qua2ment. è2ment. carê2ment. diaphrag2ment. ryth2ment. ai2ment. rai3ment. abî2ment. éci2ment. vidi2ment. subli2ment. éli2ment. reli2ment. mi2ment. ani2ment. veni2ment. ri2ment. détri3ment. nutri3ment. inti2ment. esti2ment. l2ment. flam2ment. gram2ment. .gem2ment. om2ment. .com3ment. ô2ment. slalo2ment. chro2ment. to2ment. ar2ment. .sar3ment. er2ment. antifer3ment. .ser3ment. fir2ment. or2ment. as2ment. au2ment. écu2ment. fu2ment. hu2ment. fichu3ment. llu2ment. plu2ment. bou2ment. bru2ment. su2ment. tu2ment. 1mi 1mî .milli1am 1m2némo 1m2nès 1m2nési 1mo 1mô 1mœ .mono1a2 .mono1e2 .mono1é2 .mono1i2 .mono1ï2dé .mono1o2 .mono1u2 .mono1s2 mon2t3réal m1s2 1mu 1mû 1my moye2n1â2g 1na 1nâ 1ne 1né 1nè 1nê 4ne. 4nes. 2nent. réma3nent. imma3nent. perma3nent. .émi3nent. préémi3nent. proémi3nent. surémi3nent. immi3nent. conti3nent. perti3nent. absti3nent. 1ni 1nî 1no 1nô 1nœ .no2n1obs 1nu 1nû n3s2at. n3s2ats. n1x 1ny .o4 'o4 ’o4 'ô4 ’ô4 .ô4 o2b3long 1octet '2octet ’2octet o1d2l o1è2dre o1ioni ombud2s3 omni1s2 o1s2tas o1s2tat o1s2téro o1s2tim o1s2tom o1s2trad o1s2tratu o1s2triction .oua1ou 'oua1ou ’oua1ou .ovi1s2c 'ovi1s2c ’ovi1s2c oxy1a2 1pa 1pâ paléo1é2 .pa2n1a2f .pa2n1a2mé .pa2n1a2ra .pa2n1is .pa2n1o2ph .pa2n1opt .pa2r1a2che .pa2r1a2chè .para1s2 .pa2r3hé 1pe 1pé 1pè 1pê 4pe. 4pes. 2pent. re3pent. .ar3pent. 'ar3pent. ’ar3pent. ser3pent. .pen2ta per3h pé2nul .pe4r .per1a2 .per1e2 .per1é2 .per1i2 .per1o2 .per1u2 pé1r2é2q .péri1os .péri1s2 .péri2s3s .péri2s3ta .péri1u2 1p2h .ph4 4ph. .phalan3s2t 4phe. 4phes. 2phent. ph2l 4phle. 4phles. 2phn photo1s2 ph2r 4phre. 4phres. 2phs 2pht 3ph2talé 3ph2tis 1pi 1pî 1p2l 4ple. 4ples. 2plent. .pluri1a 1p2né 1p2neu 1po 1pô po1astre poly1a2 poly1e2 poly1é2 poly1è2 poly1i2 poly1o2 poly1s2 poly1u2 .pon2tet .pos2t3h .pos2t1in .pos2t1o2 .pos2t3r .post1s2 1p2r 4pre. 4pres. 2prent. .pré1a2 .pré2a3la .pré2au .pré1é2 .pré1e2 .pré1i2 .pré1o2 .pré1u2 .pré1s2 .pro1é2 .pro1s2cé pro2s3tat .prou3d2h 1p2sych .psycho1a2n 1p2tèr 1p2tér 1pu .pud1d2l 1pû 1py 1q 4que. 4ques. 2quent. é3quent. élo3quent. grandilo3quent. 1ra 1râ radio1a2 1re 1ré 1rè 1rê .ré1a2 .ré2a3le .ré2a3lis .ré2a3lit .ré2aux .ré1é2 .ré1e2 .ré2el .ré2er .ré2èr .ré1i2 .ré2i3fi .ré1o2 .re1s2 .re2s3cap .re2s3cisi .re2s3ciso .re2s3cou .re2s3cri .re2s3pect .re2s3pir .re2s3plend .re2s3pons .re2s3quil .re2s3s .re2s3t .re3s4tab .re3s4tag .re3s4tand .re3s4tat .re3s4tén .re3s4tér .re3s4tim .re3s4tip .re3s4toc .re3s4top .re3s4tr .re4s5trein .re4s5trict .re4s5trin .re3s4tu .re3s4ty .réu2 .ré2uss .rétro1a2 4re. 4res. 2rent. .pa3rent. appa3rent. transpa3rent. é3rent. tor3rent. cur3rent. 1r2h 4rhe. 4rhes. 2r3heur 2r3hydr 1ri 1rî 1ro 1rô 1ru 1rû 1ry 1sa 1sâ .sch4 1s2caph 1s2clér 1s2cop 1s2ch e2s3ch i2s3ché i2s3chia i2s3chio 4sch. 4sche. 4sches. 2schs 1se 1sé 1sè 1sê sesqui1a2 4se. 4ses. 2sent. ab3sent. pré3sent. .res3sent. .seu2le .sh4 1s2h 4sh. 4she. 4shes. 2shent. 2shm 2s3hom 2shr 2shs 1si 1sî 1s2lav 1s2lov 1so 1sô 1sœ 1s2patia 1s2perm 1s2por 1s2phèr 1s2phér 1s2piel 1s2piros 1s2tandard 1s2tein stéréo1s2 1s2tigm 1s2tock 1s2tomos 1s2troph 1s2tructu 1s2tyle 1su 1sû .su2b1a2 .su3b2alt .su2b1é2 .su3b2é3r .su2b1in .su2b3limin .su2b3lin .su2b3lu sub1s2 .su2b1ur supero2 supe4r1 supers2 .su2r1a2 su3r2ah .su3r2a3t .su2r1e2 .su3r2eau .su3r2ell .su3r2et .su2r1é2 .su2r3h .su2r1i2m .su2r1inf .su2r1int .su2r1of .su2r1ox 1sy 1ta 1tâ 1tà tachy1a2 tchin3t2 1te 1té 1tè 1tê télé1e2 télé1i2 télé1o2b télé1o2p télé1s2 4te. 4tes. 2tent. .la3tent. .pa3tent. compé3tent. éni3tent. mécon3tent. omnipo3tent. ventripo3tent. équipo3tent. impo3tent. mit3tent. .th4 1t2h 4th. 4the. 4thes. thermo1s2 2t3heur 2thl 2thm 2thn th2r 4thre. 4thres. 2ths 1ti 1tî 1to 1tô 1t2r tran2s1a2 tran3s2act tran3s2ats tran2s3h tran2s1o2 tran2s3p tran2s1u2 4tre. 4tres. 2trent. .tri1a2c .tri1a2n .tri1a2t .tri1o2n t1t2l 1tu 1tû tung2s3 1ty .u4 'u4 ’u4 .û4 'û4 ’û4 uni1o2v uni1a2x u2s3tr 1va 1vâ 1ve 1vé 1vè 1vê vélo1s2ki 4ve. 4ves. 2vent. conni3vent. .sou3vent. 1vi 1vî 1vo 1vô vol2t1amp 1v2r 4vre. 4vres. 2vrent. 1vu 1vû 1vy 1wa 1we 4we. 4wes. 2went. 1wi 1wo 1wu 1w2r 2xent. .y4 'y4 ’y4 y1asth y1s2tom y1algi 1za 1ze 1zé 1zè 4ze. 4zes. 2zent. privatdo3zent. 1zi 1zo 1zu 1zy", ["lefthyphenmin"]=1, - ["length"]=9581, - ["n"]=1208, + ["length"]=9673, + ["n"]=1216, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/patterns/mkiv/lang-la.lua b/tex/context/patterns/mkiv/lang-la.lua index 5a0e2cc93..a706c7c3e 100644 --- a/tex/context/patterns/mkiv/lang-la.lua +++ b/tex/context/patterns/mkiv/lang-la.lua @@ -6,35 +6,79 @@ return { ["metadata"]={ ["mnemonic"]="la", ["source"]="hyph-la", - ["texcomment"]="%\ -% ********** hyph-la.tex *************\ -%\ -% Copyright 1999-2014 Claudio Beccari\ -% [latin hyphenation patterns]\ -%\ -% -----------------------------------------------------------------\ -% IMPORTANT NOTICE:\ -%\ -% This program can be redistributed and/or modified under the terms\ -% of the LaTeX Project Public License Distributed from CTAN\ -% archives in directory macros/latex/base/lppl.txt; either\ -% version 1 of the License, or any later version.\ -% -----------------------------------------------------------------\ -%\ + ["texcomment"]="% title: Hyphenation patterns for modern and medieval Latin\ +% copyright: Copyright (c) 1999-2016 Claudio Beccari\ +% e-mail claudio dot beccari at gmail dot com\ +% notice: This file is part of the hyph-utf8 package.\ +% See http://www.hyphenation.org for more information.\ +% language:\ +% name: Latin\ +% tag: la\ +% version: 3.201 2016-08-28\ +% licence:\ +% - This file is available under any of the following licences:\ +% -\ +% name: MIT\ +% url: https://opensource.org/licenses/MIT\ +% text: >\ +% Permission is hereby granted, free of charge, to any person\ +% obtaining a copy of this software and associated documentation\ +% files (the “Software”), to deal in the Software without\ +% restriction, including without limitation the rights to use,\ +% copy, modify, merge, publish, distribute, sublicense, and/or sell\ +% copies of the Software, and to permit persons to whom the\ +% Software is furnished to do so, subject to the following\ +% conditions:\ +%\ +% The above copyright notice and this permission notice shall be\ +% included in all copies or substantial portions of the Software.\ +%\ +% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND,\ +% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\ +% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\ +% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\ +% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\ +% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\ +% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\ +% OTHER DEALINGS IN THE SOFTWARE.\ +% -\ +% name: LPPL\ +% version: 1\ +% or_later: true\ +% url: https://latex-project.org/lppl/\ +% changes:\ +% -\ +% date: 1999\ +% version: 1.0\ +% author: Claudio Beccari\ +% description: First public release\ +% -\ +% date: 2007-04-16\ +% version: 3.1\ +% author: Claudio Beccari\ +% -\ +% date: 2010-05-31\ +% author: Claudio Beccari\ +% description: Removal of OT1 support\ +% -\ +% date: 2010-06-01\ +% version: 3.2\ +% author: Claudio Beccari\ +% description: Removal of pattern 2'2\ +% -\ +% date: 2016-08-28\ +% version: 3.201\ +% author: Claudio Beccari\ +% description: updated header with MIT licence notice;\ +% added few missing patterns\ +%\ +% ==========================================\ % Patterns for the latin language mainly in modern spelling\ % (u when u is needed and v when v is needed); medieval spelling\ % with the ligatures \\ae and \\oe and the (uncial) lowercase `v'\ % written as a `u' is also supported; apparently there is no conflict\ % between the patterns of modern Latin and those of medieval Latin.\ %\ -%\ -% Prepared by Claudio Beccari\ -% Politecnico di Torino\ -% Torino, Italy\ -% e-mail claudio dot beccari at gmail.com\ -%\ -% \\versionnumber{3.2a} \\versiondate{2014/06/04}\ -%\ % For more information please read the babel-latin documentation.\ %\ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\ @@ -104,22 +148,18 @@ return { % Read the documentation coming with the discription of the Latin language\ % interface of Babel in order to see the shortcuts and the facilities\ % introduced in order to facilitate the insertion of \"compound word marks\"\ -% which are very useful for inserting etimological break points.\ +% which are very useful for inserting etymological break points.\ %\ % Happy Latin and multilingual typesetting!\ %\ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\ -%\ -% \\message{Latin Hyphenation Patterns Version 3.2a <2014/06/04>}\ -%\ % ", }, ["patterns"]={ ["characters"]="abcdefghijklmnopqrstuvxzæœ", - ["data"]=".a2b3l .anti1 .anti3m2n .circu2m1 .co2n1iun .di2s3cine .e2x1 .o2b3 .para1i .para1u .su2b3lu .su2b3r 2s3que. 2s3dem. 3p2sic 3p2neu æ1 œ1 a1ia a1ie a1io a1iu ae1a ae1o ae1u e1iu io1i o1ia o1ie o1io o1iu uo3u 1b 2bb 2bd b2l 2bm 2bn b2r 2bt 2bs 2b. 1c 2cc c2h2 c2l 2cm 2cn 2cq c2r 2cs 2ct 2cz 2c. 1d 2dd 2dg 2dm d2r 2ds 2dv 2d. 1f 2ff f2l 2fn f2r 2ft 2f. 1g 2gg 2gd 2gf g2l 2gm g2n g2r 2gs 2gv 2g. 1h 2hp 2ht 2h. 1j 1k 2kk k2h2 1l 2lb 2lc 2ld 2lf l3f2t 2lg 2lk 2ll 2lm 2ln 2lp 2lq 2lr 2ls 2lt 2lv 2l. 1m 2mm 2mb 2mp 2ml 2mn 2mq 2mr 2mv 2m. 1n 2nb 2nc 2nd 2nf 2ng 2nl 2nm 2nn 2np 2nq 2nr 2ns n2s3m n2s3f 2nt 2nv 2nx 2n. 1p p2h p2l 2pn 2pp p2r 2ps 2pt 2pz 2php 2pht 2p. 1qu2 1r 2rb 2rc 2rd 2rf 2rg r2h 2rl 2rm 2rn 2rp 2rq 2rr 2rs 2rt 2rv 2rz 2r. 1s2 2s3ph 2s3s 2stb 2stc 2std 2stf 2stg 2st3l 2stm 2stn 2stp 2stq 2sts 2stt 2stv 2s. 2st. 1t 2tb 2tc 2td 2tf 2tg t2h t2l t2r 2tm 2tn 2tp 2tq 2tt 2tv 2t. 1v v2l v2r 2vv 1x 2xt 2xx 2x. 1z 2z. a1ua a1ue a1ui a1uo a1uu e1ua e1ue e1ui e1uo e1uu i1ua i1ue i1ui i1uo i1uu o1ua o1ue o1ui o1uo o1uu u1ua u1ue u1ui u1uo u1uu a2l1ua a2l1ue a2l1ui a2l1uo a2l1uu e2l1ua e2l1ue e2l1ui e2l1uo e2l1uu i2l1ua i2l1ue i2l1ui i2l1uo i2l1uu o2l1ua o2l1ue o2l1ui o2l1uo o2l1uu u2l1ua u2l1ue u2l1ui u2l1uo u2l1uu a2m1ua a2m1ue a2m1ui a2m1uo a2m1uu e2m1ua e2m1ue e2m1ui e2m1uo e2m1uu i2m1ua i2m1ue i2m1ui i2m1uo i2m1uu o2m1ua o2m1ue o2m1ui o2m1uo o2m1uu u2m1ua u2m1ue u2m1ui u2m1uo u2m1uu a2n1ua a2n1ue a2n1ui a2n1uo a2n1uu e2n1ua e2n1ue e2n1ui e2n1uo e2n1uu i2n1ua i2n1ue i2n1ui i2n1uo i2n1uu o2n1ua o2n1ue o2n1ui o2n1uo o2n1uu u2n1ua u2n1ue u2n1ui u2n1uo u2n1uu a2r1ua a2r1ue a2r1ui a2r1uo a2r1uu e2r1ua e2r1ue e2r1ui e2r1uo e2r1uu i2r1ua i2r1ue i2r1ui i2r1uo i2r1uu o2r1ua o2r1ue o2r1ui o2r1uo o2r1uu u2r1ua u2r1ue u2r1ui u2r1uo u2r1uu", + ["data"]=".a2b3l .anti1 .anti3m2n .circu2m1 .co2n1iun .di2s3cine .e2x1 .o2b3 .para1i .para1u .su2b3lu .su2b3r 2s3que. 2s3dem. 3p2sic 3p2neu æ1 œ1 a1ia a1ie a1io a1iu ae1a ae1o ae1u e1iu io1i o1ia o1ie o1io o1iu uo3u 1b 2bb 2bc 2bd b2l 2bm 2bn b2r 2bt 2bs 2b. 1c 2cc c2h2 c2l 2cm 2cn 2cq c2r 2cs 2ct 2cz 2c. 1d 2dd 2dg 2dm d2r 2ds 2dv 2d. 1f 2ff f2l 2fn f2r 2ft 2f. 1g 2gg 2gd 2gf g2l 2gm g2n g2r 2gs 2gv 2g. 1h 2hp 2ht 2h. 1j 1k 2kk k2h2 1l 2lb 2lc 2ld 2lf l3f2t 2lg 2lk 2ll 2lm 2ln 2lp 2lq 2lr 2ls 2lt 2lv 2l. 1m 2mm 2mb 2mp 2ml 2mn 2mq 2mr 2mv 2m. 1n 2nb 2nc 2nd 2nf 2ng 2nl 2nm 2nn 2np 2nq 2nr 2ns n2s3m n2s3f 2nt 2nv 2nx 2n. 1p p2h p2l 2pn 2pp p2r 2ps 2pt 2pz 2php 2pht 2p. 1qu2 1r 2rb 2rc 2rd 2rf 2rg r2h 2rl 2rm 2rn 2rp 2rq 2rr 2rs 2rt 2rv 2rz 2r. 1s2 2s3ph 2s3s 2stb 2stc 2std 2stf 2stg 2st3l 2stm 2stn 2stp 2stq 2sts 2stt 2stv 2s. 2st. 1t 2tb 2tc 2td 2tf 2tg t2h t2l t2r 2tm 2tn 2tp 2tq 2tt 2tv 2t. 1v v2l v2r 2vv 1x 2xt 2xx 2x. 1z 2z. a1ua a1ue a1ui a1uo a1uu e1ua e1ue e1ui e1uo e1uu i1ua i1ue i1ui i1uo i1uu o1ua o1ue o1ui o1uo o1uu u1ua u1ue u1ui u1uo u1uu a2l1ua a2l1ue a2l1ui a2l1uo a2l1uu e2l1ua e2l1ue e2l1ui e2l1uo e2l1uu i2l1ua i2l1ue i2l1ui i2l1uo i2l1uu o2l1ua o2l1ue o2l1ui o2l1uo o2l1uu u2l1ua u2l1ue u2l1ui u2l1uo u2l1uu a2m1ua a2m1ue a2m1ui a2m1uo a2m1uu e2m1ua e2m1ue e2m1ui e2m1uo e2m1uu i2m1ua i2m1ue i2m1ui i2m1uo i2m1uu o2m1ua o2m1ue o2m1ui o2m1uo o2m1uu u2m1ua u2m1ue u2m1ui u2m1uo u2m1uu a2n1ua a2n1ue a2n1ui a2n1uo a2n1uu e2n1ua e2n1ue e2n1ui e2n1uo e2n1uu i2n1ua i2n1ue i2n1ui i2n1uo i2n1uu o2n1ua o2n1ue o2n1ui o2n1uo o2n1uu u2n1ua u2n1ue u2n1ui u2n1uo u2n1uu a2r1ua a2r1ue a2r1ui a2r1uo a2r1uu e2r1ua e2r1ue e2r1ui e2r1uo e2r1uu i2r1ua i2r1ue i2r1ui i2r1uo i2r1uu o2r1ua o2r1ue o2r1ui o2r1uo o2r1uu u2r1ua u2r1ue u2r1ui u2r1uo u2r1uu", ["lefthyphenmin"]=1, - ["length"]=1756, - ["n"]=335, + ["length"]=1760, + ["n"]=336, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/patterns/mkiv/lang-th.lua b/tex/context/patterns/mkiv/lang-th.lua index 3f54a47d3..a9b4bc420 100644 --- a/tex/context/patterns/mkiv/lang-th.lua +++ b/tex/context/patterns/mkiv/lang-th.lua @@ -6,33 +6,32 @@ return { ["metadata"]={ ["mnemonic"]="th", ["source"]="hyph-th", - ["texcomment"]="% Thai hyphenation patterns\ -%\ -% Copyright 2012-2013 Theppitak Karoonboonyanan \ -%\ -% This work may be distributed and/or modified under the\ -% conditions of the LaTeX Project Public License, either version 1.3\ -% of this license or (at your option) any later version.\ -% The latest version of this license is in\ -% http://www.latex-project.org/lppl.txt\ -% and version 1.3 or later is part of all distributions of LaTeX\ -% version 2005/12/01 or later.\ -%\ -% This work has the LPPL maintenance status `maintained'.\ -%\ -% The Current Maintainer of this work is Theppitak Karoonboonyanan.\ -%\ -% http://linux.thai.net/projects/thailatex\ -% http://linux.thai.net/svn/software/thailatex/trunk\ + ["texcomment"]="% title: Hyphenation patterns for Thai\ +% copyright: Copyright 2012-2013 Theppitak Karoonboonyanan \ +% notice: This file is part of the hyph-utf8 package.\ +% See http://www.hyphenation.org for more information.\ +% language:\ +% name: Thai\ +% tag: th\ +% licence:\ +% name: LPPL\ +% version: 1.3\ +% or_later: true\ +% status: maintained\ +% maintainer: Theppitak Karoonboonyanan\ +% url: https://latex-project.org/lppl/\ +% ==========================================\ +% https://linux.thai.net/projects/thailatex\ +% https://github.com/tlwg/thailatex\ %\ % ", }, ["patterns"]={ ["characters"]="กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮะัาำิีึืฺุูเแโใไๅ็่้๊๋์ํ๎", - ["data"]=".ชี5วั .ทัศนู5 .ที่3 .บท1 .รง4 .ราย3 .ลำ3 .สน5ท .สู3ต .ใบ3 2ก1ก ก4กม กก4ส 2ก1ข ก4ขค กข5คณ ก4ขช กข5ชา ก4ขณ ก5ขณะ ก5ขณา ก4ขบ กข5บุ ก4ขภ กข5ภั ก4ขม ก5ขมั กข5มา กข5มู กข5ลา กข5ศั ก4ขเ กข5เท กข5เว ก4ข์ ก1ค กง5บว ก1จ ก1ช 2กซ กญ5จน กฎ5หม กฎ5เก กฏ5หม ก5ดิน ก1ต ก4ตด กต5ดิ ก4ตส ก4ตเ ก1ท ก1น ก4นด ก4นธ ก1บ ก1ป กป4ร ก1พ ก1ฟ ก1ม ก4มม กม5ลา ก4มส ก4มเ กย5มุ ก3ย้ กร5กฎ ก5ร5ณั กร5ต๋ 1ก4รร กร5รา กร5ลา ก5ราค ก5รินท ก4รู กร5ไฟ กล5นค กล5บิ กล5มห ก2ว ก5วัต ก5ษณน ก3ษณะ ก5ษณา ก5ษมา ก5ษมี กษ5เท ก1ส กส4น ก4สโ ก1ห กอ5อิ กะ5ถั กะ5ผล 4กะร 1กั 1กา กา5กะ กา5ดู กา5นี กา5น้ กา5บอ กา5ฝา กา5ร่ กำ5ด้ กำ5ทอ กำ5ผล 1กิ กิ5กะ กิ4ต กิ5นี กี5รณ กี5รต กี5สถ 1กุ กุ5งอ กุ5ชิ กุ5ฎุ กุ5มุ กุ5รร กุ5ลี กุ5แห 1กู กู5ปร กู5รข กู5รม กู5ลิ ก1เ ก1แ ก1โ ก1ไ ก่5กอ ก่5บ้ ก่5ป่ ก์5ท็ ข2 ขม5หิ 4ขลา ขอ5ขม ขอ5ง้ ขอ5อภ 1ขั 1ขา ขา5ก๊ ขา5ทน ขิ5ปส ขี้1 ข่5มุ ข่5หง ข้าว3 ค1ค คช5สี คช5เช คช5เม ค4ณิ ค4ทร คท5รี คท5วอ คน5ยอ 4คนิ คป5ซู คป5ผก 3คมน คม5ฟร คม5ลอ 2คย คร5ซอ คร5นอ คร5นี คร5พน คร5ฟิ คร5มเ คร5ร้ คร5ลิ คร5หา 4ค5รัก ค5ราต คฤ5หบ คฤ5หา คฤ5โฆ คล5คู ค2ว คว5ทอ 3ควา 2คส คส5ติ คห5กร คห5นิ คห5บด คห5สถ 3คอน 3คัน 1คา คา5ปู คา5พจ คา5พย คา5รว คา5วจ คำ5ดี คำ5โอ คำ5ไก คี5รี 1คุ คุ5ณู คุ5ลี 4คุ์ คู5ปอ คู5ลอ 2ค1เ ค1โ 2ค์ ค์5จำ 1ฆา ฆา5ณั ฆี5ยก ง1ก ง4กห งกะ4ร ง4กเ ง4ก์ ง1ข ง4ขก ง4ขต ง1ค ง4คจ ง4คช ง4คญ ง4คธ ง4คบ ง4คป งค5วั ง4คศ ง4คโ งฆ5ปร งฆ5สภ งฆ5เถ งฆ5เภ ง1ง ง4งเ ง1จ ง1ฉ ง1ช ง4ชี ง1ซ ง1ด ง1ต ง1ท ง1น งบ5ดุ ง1ป ง1ผ ง1พ ง1ม ง1ย ง1ร ง1ล ง1ว ง4วเ ง1ส งส5กล งส5กุ ง4สบ ง4สพ งส5พย ง4สภ ง1ห งห5นา ง4หบ งห5บั งห5รา 1งา งา5ช้ งา5รำ งู5สว ง1เ ง1แ ง1โ ง1ไ ง่5งอ จ1จ จ4จว จ1ฉ จด5จ่ จต5จำ จต5มู จป4ก จมบ5พ 3จริ จอ5งอ 1จั 1จา จา5มร จา5มี จา5รึ จำ5ทว จำ5อว 1จิ จิ5จู จิ5ตอ จี5ดี จุ5ฑา จุ5สม จ1เ ฉ2 ฉก5ฉว ฉก4ษ ฉท5ทิ ฉร5ฉิ 1ฉั 1ฉา ฉา5ก๊ ฉา5พย ช1ช ช1ฌ ช4ฌก ช4ฌฆ ช5นีก 4ชน์ ชฟ5รอ ชฟ5โร ชร5กล ชร5ริ ชร5ฤก ชร5หล ชร5หึ ชร5อุ ชว4โ ชอง4 1ชั 1ชา ชา2ต ชา5ตร ชา5ปี ชา5มต ชา5ยต ชา5สง ชำ5งั ชิ5นี ชิ5รณ ชิ5แก ชี5ผะ ชี5ผ้ ชี5ฟอ ชี5รณ 3ชีว ชี5วน ชุ5ติ ชุ5ลด ชู5ปก ชู5ปถ ชู5ปโ ช่5อิ ช้5สอ ช้5ได ซน5ทร ซ5ราม ซล5ฟี 1ซั 1ซา ซา5ชู ซา5มู 1ซิ ซิ5ตร ซิ5ฟิ ซิ5แล ซี5ดี ซี5นี ซี5รา ซี5ริ ซี5รี ซี5ร็ ซี5ลี ซู5ซู ซู5บิ ซู5ริ ซู5ลิ ซู5ฮา ซ1เ ซ1โ ซ่5ง่ ซ่5ซ้ 1ซ่า ซ์5คล ญจ5ดุ ญ4จน ญ5จ5นท ญ5จ5นบ ญ5จนา ญจ5บร ญ5จ5มบ ญจ5รง ญจ5วี ญจ5ศี ญ4ฉน ญ1ช ญ1ญ ญประ4 1ญา ญา4ต ญ่5บ้ ฏ1ฐ ฏ4ฐบ ฏิ5ทิ ฏิ5ปท ฏิ5ปุ ฏิ5สน ฏิ5สว ฐ4ภั ฐม5ฌา ฐม5พย ฐม5ฤก 1ฐา ฐา5นี ฐุ5ชุ ฑา5มณ ฑา5สถ 3ฑูร ฒิ5สภ ฒิ5สม ณ1ฑ ณ4ฑก ณ4ฑฆ ณ4ฑน ณ5ฑนะ ณ4ฑบ ณ4ฑม ณฑ5ลา ณ4ฑส ณ5ฑสก ณฑ5สถ ณ5ฑ5สี ณฑ5โล ณ4ฑ์ ณย5รั ณ1ร ณ4วา ณสม4 ณห5พล ณห5ภู 1ณา ณา5ปี 1ณิ 1ณี ณี5สง ณู5ปโ ด1ก ด4กง ด4กด ดก5ดื ด4กเ ด4กแ ด1ข ด1ค ดง4ค ดง5ออ ด1ช ด4ชน ด5ชนะ ด1ด ด4ดเ ด1ต ด1ท ด1ป ด1พ ดร5ลิ ด3ร้ ด1ส ด4สก ด1ห 1ดั ดัส5ต 1ดา ดา5มุ ดา5รก ดา5สว ดำ5ฤษ ดิ5ทอ ดิ5ทิ ดิ4บ ดิ5วร ดิ5ศว ดี5ดี 3ดีน ดี5ฝ่ ดี5รอ ดี5ลิ ดี5วี ดี5หม ดี5หว ดู5ถู ดู5ปอ ดู5รั ดู5หม ดู5แค ด1เ ด1แ ด1โ ด้5ยิ 2ด์ ด์5สป 2ตก ตก5ร้ ต1ค 2ต1ช 2ต1ต ต4ตภ ต4ตส ต4ตโ ต5ถกะ ตถ5กิ ต3ถา ต5ถุป ต5ถุศ ตถ5เล ตทัศนูป5 2ตน ตน5ฟอ ตน5วร ต4นาธ 2ต1บ ต4บช ตบ5ชว ตป5นี ต1ภ 2ตย 4ตรก ตร5งอ ตร5จี ตร5จุ 4ตรฐ ตร5ตร ตร5ทว ตร5ผล ตร5ฝร ตร5พล ตร5รง ตร5ลด ต5ริยา ต4รู 2ตร์ ตฤ5ตี ตล5รั ต1ส ต4สค ตส5วา ตส4เ ต4สแ ตส5แต ตอ5ม่ ตะ5ใภ 1ตั 1ตา ตา5กล ตา5กว ตา5นึ ตา5ปร ตา5ปล ตา5ผิ ตา5ฟู ตา3มห ตา5มอ ตา5มะ ตา5ฬี 3ติก. ติ5จู ติ5ช่ ติ5ทิ ติ5นร ติ5บอ ติ5มศ ติ5มส ติ5มอ ติ5ยม 4ติ์ ตี5ขล ตี5คู ตี5ตื ตี5รว ตี5ลั 3ตี้. ตุ5ตถ ตุ5ทส ตุ5ป่ ตุ5มห ตุ5รก ตุ5ลั ตุ5สด ตู5ดิ ต1เ ต3แล ต1โ ต่5ถา ต่5ว่ ต่5สว ต้5ก๋ ต้5ตอ ต้5ฝุ ต๋5เต ต์5คล ต์5ฟู ต์5ศต ถ4กิ ถด5ถอ ถม5ถื ถล5ไถ ถว5ไม ถะ5ถั ถ4าธ ถา5วร ถ4ีย ถี5ลิ 3ถุน ถ่5ถอ ถ่5ถา 4ทกา ทค5ติ ทค5นี ทด5รอ ทด5ลอ ทธ5คย ท5ธชะ ทธ5ฎี ทธ5ปฏ ทธ5พร ทธ5รั ทธ5ศต ทธ5สี ทธ5อง ท5ธิก ท5ธิช ท5ธิบ ท5ธิป ท5ธิผ ท5ธิพ ท5ธิภ ท5ธิร ท5ธิฤ ท5ธิศ ท5ธิโ ทธ5เจ ทพ5ธิ ทพ5ยุ ทฟ5ลอ 2ทย ท5ยาน ทร5คต ทร5คร ทร5ชิ ทร5ธน 3ทรร ทร5สโ ทร5หว ทร5หึ 1ทรา ท5ราก 4ท5ราห 1ทรี ทว5ทห ทว5สถ ทศ5ทิ ทศ5วร ทสน5ท ทส5โก ทห5วั ทห5ฬิ 1ทั 1ทา ทา5ฐิ ทา5ฒิ ทา5นอ ทา5มร ทา5รพ ทำ5ขว ทำ5ซ้ ทำ5ท่ ทำ5โท ทิ5ฆั ทิ5ฐิ ทิ4พ ทิ5พา ทิ5วง ที5นว ที5นี ที5รา ทุ5คต ทุ5ลั ทุ5ศี 1ทู ทู5น่ ท1เ ท์5ดอ 1ธร 4ธรส 4ธรั 1ธา ธา1รณ ธิ5ฤท ธิ5ศี ธิ5สม ธี5รี ธุ5ดง ธุ5ลี ธู5ปน น1ก น4กค น4กป นก5ยู นก5รู น1ข นข5ลิ น1ค นค5ริ น1จ น4จอ นจ5อน น1ช น4ชญ น1ซ น1ด น4ดร น1ต นต5กว น5ตกะ นต5ดิ น4ตท นต5ทิ นต5ปิ น4ตภ น5ตระ น5ตรั น3ตรา น5ต5ริ นต5ฤด น3ติ น5ตุก น5ตุฏ น4ต์ นถ5ธุ นถ5รจ นท5ขี นท5นน น5ทนะ นท5ผล นท4ย น5ทรง น5ทรล น5ทรั น5ทรุ นท5ฤก น5ทลา น5ทวย น3ทอ น1ทิ น3ที นธ5กร น5ธกะ น5ธนะ น5ธุก น5ธุร น5ธุว น5ธุศ นธ5ไม น1น น4นต น4นท น4นร น1บ นบ5นอ น1ป น4ปจ นป5จู น4ปท น1พ นพ5ปฎ นพ5ศู นภ5ศู น5ยนต น3รา นฤ5คห นฤ5ปเ นฤ5เท นฤ5เบ น1ล น4ลล นว5ร่ น1ศ นษ5กร น1ส น4สซ น4สส นส5แด น4สโ น1ห นอ5กะ 3นอน 1นั 1นา นา4คร นา5ณั นา5ปร นา5รย นา5วต นา5วล นา5สณ นา5สน นา5สว นา5ฬิ 4นาะ 1นิ นิ5จู นิ5ด้ นิ5ฟอ นิ5มน นิ5ยม นิ5ยา นิ5รอ นิ5ลุ นิ5วร นิ5สง นิ5สถ นิ5สี นิ5แด นี5มี นี5มู 1นุ นุ5พย 1นู 2น1เ น1แ น1โ น1ไ น่5อี 3น้อ 1น้ำ น์5สไ บ1ก บ4กษ บกิส5 บ4กแ บ1ข บ1ค บ4คท บค5ที บ4คโ 1บดี บ1ท บบ5ฉบ บบ5ฝึ บบ5อย บ1ป บ1พ บร5มี บ1ส บ4สบ บส4เ บ1ห บอ5ดี บอ5ระ 3บอล 1บั บัพพาชนี5 1บา บาจ5ร บา4ต บา5ตอ บา2ท บา5ทา บา5ทุ บา5รน บา5รอ บา5สม บิ5ชอ บี5คิ บี5ร่ 1บุ บุค3 บุ5ตร บุ5ถุ บุ5รพ 1บู บู4ช5น บู5ติ บู5ย่ บ1เ บ1แ บ1โ บ๊5จี บ๊5เบ ปก4ส ป4จั ป4จา ปฐ5ปท ปฐ5พี ปต5ถก ปต5พล ป4ทา ป1ป ป4ปเ ปม5ด้ ป4ยุ ปร5ตอ ปร5ติ ปร5ตี ปร5ตุ ปร5ผั ปร5ษณ 1ประ ปร5แก ปร5แท ปร5ไฟ ปล5ญว ป4วา ปส4ต 1ปั 1ปา ปา5ฐก ปา5ณก ปา5นี ปา5ปิ ปาร4 ปา5รเ ปิ5ดอ ปิ5ดิ ปิ5ยภ ปิ5ยอ ปิ5หก ปี5ชี ปี5มะ ปี5ฬก ปี่3 ปุ5คล ปุ5ถุ ปู5จ๋ ปู5ติ ป1เ ป1ไ ผก5ผั ผณิ5ศ ผน5ผั ผ4นิ ผ4ยา ผล5พล ผล5ไม ผ4สา ผี5ดิ ผี5ตอ ผี5ถ้ ผี5ห่ ผ้า3 3ฝอย ฝี5มะ ฝ่5ฝั 3พจน พจ5นี พช5ฉล พช5รา พท5ริ พทัก4 พน5ทะ พ4นั พนิ4 พ1พ 2พ2ย พย5ก๊ พร5ชย พร5ซี พร5มี 1พรร พ4รู พร5ไฟ 3พฤก พฤ5ฒา พล5ทิ พล5ร่ พส5เฟ พอ5คว พอ5สม 1พั 1พา 4พาจ พา5ชน พา5นร 1พิ พิ5ถั พิ5ถี พิ5ปล พิ5รอ พิ5รี พิ5ลึ พิ5ศุ พิส5ม พี5ระ พุ5ชิ พุ5พอ พู5ทว พู5พอ พ1เ พ4เย พ่5ป๊ พ่อ3 พ้5ท้ 2พ์ พ์5ดี 1ฟั 1ฟา ฟิ4ลา ฟี5ฟ่ ฟู5ฟ่ ฟ1เ 1ฟ้ ภค5ทร ภค3ว ภช5นี 1ภั 1ภา ภา5ณก ภา5ณว ภา5รด ภา5รต ภา5รย ภา5วน ภิ5ชน ภิ5มห ภิ3ร ภิ5สม ภุ5ชง 1ภู ภู5ฏา ภู5ริ ม1ก ม4กม ม4กษ ม1ข ม4ขล ม1ค ม4คค ม4คอ มค5อิ 1มงคล มง5ฟอ ม1จ ม1ช มช4ว ม1ซ 3มณฑ มณ5ฑน มณ5บร มณ5พร มณ5เฑ มณ5เพ มด5ยอ มด5ลู ม1ต ม4ตธ ม4ติ ม4ตไ มต5ไต ม1ท 3มนตร มน5ฮั ม4นุ ม1บ มบ4พ ม1ป มป4ช มป5ฤด มป5ฤๅ ม4ป์ ม1พ ม4พก ม4พว ม1ภ มภ5กถ ม1ม ม4มเ ม4มโ มย5รา 3มรร ม3รั ม3ริ มฤ5คิ มฤ5เค มล5ทิ ม3ลิ ม3ล้ ม1ว มว5มอ ม4วล ม1ส มส4เ มห5กร ม3หน มห5ภา ม5หาญ ม5หาย มหา3ส มอ5ขว มอ5คร มอ5ดู มอ5ตำ มอ5นว มอ5นอ มอ5ระ 4มอั มะ5ถั มะ5ฝ่ มะ5ฮอ 1มั ม4ั่ 1มา มา4ก มา5ดร มา5นร มา5ป่ มา5พจ มา5มก มา5มุ มา5ม่ มา5ยณ มา5ยอ มา5ร่ มา3ว4 1มิ มิ5กภ มิ5ซร มิ5ตล มิ5ถิ มิ5น่ มิ5ฟล มิ5ลำ มิ5ลี มิ5แพ มี5ขม 3มืด 1มือ. มุ5ทะ มุ5ทั มุ5ทิ มุ5ทุ มุ5ฮั มู5ซี มู5ป่ มู5รต มู5ลิ มู5หย มู5หร มู5ฮั มู5แด มู5แผ มู5แฮ ม1เ ม1แ ม1โ ม1ไ ม4่า 3ม้า ม์5ภิ ยก5ย่ ย1กร ย4ก5ร้ ย1ค ยง5บ่ ยง5ฝ้ ยง5อย ยจ5คร ยด5ย้ ย1ต ย1ท ย1ธ ยบ5ร้ ย1ป ย1พ ย1ภ ยม5ยอ ยม5รา ยม5หา ยม5อี ย4มิ ย1ย ยย4ส ยร5ถี ย5รบั ยล5ไท ยว5ข้ ยว5จ๊ ยว5ดอ ยว5นี ยว5ย่ ยว5รั ยว5ไส ย1ศ ย1ส ย1ห ย4หฐ ยห5ฐา ย4หป ยห5ปร ยอ5บี ยอ5รม 1ยั 1ยา ยา5กฤ ยา5กว ยา5ฉุ ยา5ณม ยา5ณว ยา5ถ่ ยา5บร ยา5สล ยา5สี ยา5ฬั ยำ5ทว ยี5รา 1ยุ ยุ5คล ยุ5ตก 4ยุภ ยุ5แย ยุ5แห ยู5ถิ ยู5ฟ่ ยู5ริ ยู5ไน ย1เ ย1แ ย1โ ย์5กล ย์5ถ่ ย์5มน ย์5หน 2รก รก5ซอ รก5ซึ รก5ซ้ ร1กร รก5รา รก5ร้ รค5พว รง5พย รง5รอ รจ5ถร รณ5คด รณ5ตร รณ5ถั รณ5พฤ รณ5สถ ร5ณาญ รณู5ป 4รณ์ ร1ด ร4ดป ร4ดแ ร4ดโ ร4ดไ รด5ไอ รถ1 รถ5พย ร1ท ร4ทฤ รท5ฤด ร4ท4ว รท5วิ รธ5ขึ รธ5สร รธ5เก รน5ทุ 4รนา ร1บ ร4บค ร4บถ รบ5ถ้ ร4บม ร4บั ร4บไ รบ5ไก ร1ป ร4ปณ ร5พชา ร5พ5ชิ รพ5ทิ ร1ภ ร4ภย รม5รอ รมาว5 รม4เห ร4ยั รร4ก รร5คา รร5จถ รร5จว รร5ชิ รร5ณึ รร5ถา รร5ยง รร5ยเ รร3ล รร5หา รร5แท รร5แส รร5ไก รร5ไต รล5ออ รศ5นี รษ5ฐิ รษ5ตร ร1ส ร4สก ร4สช ร4สเ ร4สโ ร3หิ ระ1 ระ5สา ระ5หก 5รังส 3รัฐ 1รัต รา5กฏ รา5กฤ รา5กว 1ราช รา5ชู รา5ดร รา5ดว รา5ดู รา5ม่ รา5วณ รา5สง รา2ห รา5หุ รำ5งั รำ5จว ริ5กอ ริ5ซึ ริ5ตร ริ5ทึ 4ริพ ริ5มน 4ริยจ 4ริยย 4ริร ริ5แล 4ริ่ รี5คู รี5ฑา รี5ดู รี5ตร รี5ตอ รี5มู รี5รั รี5รา รี5ริ รี5ลั รี5ลิ รี5ล่ รี5สอ รี5สะ รุ5กว รุ5ขร รุ5คร รุ5ทว รุ5ธิ รุ5มุ รุ5วน 1รู รู5ที รู5นี รู5บิ รูป5ก รู5ปิ รู5มา รู5มู รู5หร 2ร1เ ร1โ ร่5กะ ร่5ตร ร่5ร่ ร่5หล ร์5กอ ร์5กี ร์5คั ร์5ดิ ร์5ติ ร์5ตู ร์5ทิ ร์5ฟอ ร์5ฟู ร์5ลี ร์5วอ ฤ4ดา ฤป4เ ฤษ5ฎี ฤห5บด ล5กนะ ลก5ลา ลก5วั ล3กอ ล4กัย ลข5คณ ลข5หม ลชี4 ลด5ระ ลด5ลิ ล4ดา ล1ต ล4ตฟ ลต5ฟอ ลบ5ตะ ลบ5มุ ลบ5ล้ ลบ5ไส ลป5ตอ ลม5งว ล3มอ 2ลย ล1ล ล4ล์ ล3วี ลว5ไห ลส5ไต ลห5กุ ลอก5ล ลอ5จี ลอ5สร ละ5ผล 1ลักษ ลา5กล ลา5นี ลา5บร ลา5ป๋ ลา5พอ ลา5มี 3ลาร ลา5รอ ลา5ร้ ลา5ฤก ลา5ส้ ลิ5ก่ ลิ5จู ลิ5ซึ ลิ5ตอ ลิ5นอ ลิ5น่ ลิ4บ ลิ5บา ลิ5ฟอ ลิ5มู ลี5ตะ 3ลีน ลี5ผล ลี5ลา ลี5วู ลุก5ร ลุก5ล ลุ5ล่ ลูก1 ลู5ซี ลู5ที ลู5มิ ลู5ลอ ลู5ออ 2ล1เ 2ล1แ ล1โ ล่5ติ ล่5ที ล่5หล ล่5ออ ล้5โพ ล์5สต ว3กร วก5ว่ ว5การ ว1ค 1วงศ วจ5ตร วจ5สอ วช5นี วด5ถ่ วด5มว วด5ยิ วด5ระ วด5ลา วด5ล้ วด5อ้ ว1ต ว4ตฉ วน5ถี วน5ท้ วน5ผส วน5รว วน5ร่ วน5อิ วน5อุ วบ5ยอ วบ5รว วบ5รั วบ5ฮา ว1ป ว1พ วม5รอ ว3มู วย5ก้ วย5จี วย5ริ วย5รื วย5ล้ วย5ไท วย5ไม วร5ธิ วร5มณ วร5มห ว4รย 1วรร4 ว4ร์ วล5ระ วส5ปอ ว1ห วอ5ชิ 1วั วัน3 วันต5 วันท4 1วา วา5ดะ วา4ต วา5ตก วา5ติ วา5นร วา5นึ วา5บร วา5มน วา5รณ วา5สนะ วา4ห วา5หน วา5หิ 1วิ วิ5กล วิ5กส วิ5คห วิ5จุ วิ5ดี วิ5ตก วิ5ตร วิ5ตี วิ5ถี 3วิท วิ5ทิ วิ5ธุ วิ5ธู วิ5ปก วิ5ปฏ วิ5ปล วิ5ปว วิภู5 วิ5มล วิ5รง วิ5วร วิ5ศร วิ5ศุ วิ5ษุ วิ5สร วิ5สฤ วิเล5 วี5คู วี5ชน วี5ดิ 1วุ ว1เ ว1แ ว1โ ว่5ห้ ว้5ชื ว้5ทุ ว้5ลา ว์5ลิ ศ1จ ศน5อุ ศพิ4 3ศรี ศ2วร ศษ5ซ้ ศษ5เก ศษ5เห 1ศั ศัก5ร 1ศา2 ศา5กา ศา5ขบ ศา5นุ ศา5ภิ ศา5รย ศา5รั ศา5ริ ศา5ลา 1ศิ ศิ5รพ ศิ5รว ศิ5ศี 1ศึ ศุ5กล ศู5ลิ ศเจ5ร ษ3ฎา ษฐ5ภค ษ5มณี ษ4มา 1ษั 1ษา ษา5คเ 1ษิ ษ์5พย สก5ลิ สก5ลึ สก5วั สก5วา ส4กา 4ส4กุ สข5บุ สง5ขล ส1ซ ส5ดิก ส5ดิน ส5ดิภ ส5ดิม สต5ทิ ส3ตรา 2สต์ สถ5วี 4สถ์ สน5ธย สน5ธิ ส5นียะ ส4นุ สนูป5 ส4ปา สพ5ติ ส2ม สม5ดุ 3สมบ สม5ผส สม5ผุ สม5ผเ สม5ยอ สม5ฤด สม5ฤต สม5หว ส5มัท ส5มัน สมุ4 สรร5ช สร5ลอ สล5บร สว4ก สว5ยม ส4วร สว5ริ ส4วา 4สวิ ส1ส สห5กร สห5กา สห5ชา สห5ธร สห5ปร สห5พั สห5ภา สห5รา สห5ศึ สอ5พล สอ5พอ สะ5ใภ 1สั สัญประ5 สัน3ถ สัม3 1สา สา5คเ 4สาธ สา5นึ สา5มน สา5มี สา5วพ สำ5ออ สำ5โร 1สิ สิ5ถิ สี5ข้ สี5ชอ สี5ดว สี5ตล สี5ตโ สี5ถ่ สี5ผึ สี5ฝุ สี5ละ สี5ลั สี5วล 1สุ สุ5กร สุ5กำ สุ5กี สุ5ขิ สุ5ขุ สุ5คต สุ5คร สุ5นี สุ5บร สุ5บิ สุ5ปร สุ5มน สุ5สง สุ5ไห 2สุ์ 1สู ส1เ ส4เฟ ส1โ ส4โก ส4โค 3ส่ว ส่5ไค ส้5กร ส้5ติ ส้5ไก 2ส์ ส์5หย ห2 2ห1ก หก5ระ หก5ล้ 5หการ หง4ส หง5สา หฤ5หร หฤ5โห หล5สะ หอ5คอ หอ5สม 1หั หา5กฐ หา5บพ หา5ปณ หา5พร หา5รื หา5ฤก หิ5รก หิ5ศว หุ5คู หู5กร หู5กว หู5หน ห้5ท่ ห้5ท้ ห้5ร้ 2ห์ ห์5กร ห์5สน ฬว5รา ฬห5บู 1ฬา ฬา5มณ ฬา5รึ อก5ซอ อก5ถล อก5รณ อก5รี อก5รู อก5ร่ อก5ฤท อก5ลว อก5ลอ อก5ลา อก5ล่ อก5ว่ อก5ใบ อค5ที อฆ5สง อง4คม อง5ถิ อง5บร อง5บิ อง5ฟอ อง5ฟุ อง5ระ อง5อุ อง5อ้ อด5ถอ อด5น่ อด5ฝา อด5ยอ อด5รั อด5อย อด5ออ อด5อุ อด5อ้ อ3ดิ อต5ดอ อต5ด็ อต5ไว อ1ท อ4ทค อท5คอ อน5ง้ อน5ดร อน5ทำ อน5ผั อน5ฝู อน5ฟิ อน5ย้ อ4นา อ4นุ1 อบ5ช้ อบ5ถา อบ5บี อบ3อ อบ5ไล อป5คอ อป5ติ อป5พร อป5พล อป4ร อป5วา อป5โล อพ5ริ อฟ5ฟิ อฟ5ฟี อฟ5ริ อฟ5ไล อ4ภั อม5ฎอ อม5ดอ อม5ถอ อม5ยิ อม5รา อม5ร่ อม5ฤต อม5หล อม5หว อม5ห้ อ5มอน อย5กอ อย5ก๋ อย5นว อย5ร่ อย5ร้ อย5อิ อ4ยา อย5ได อร5ชุ อร5มน อ3รอ อ1รั อ3รา อ1ริ อ1รี อ3ร้ อร์1 อล5จี อล5นี อล5ฟ่ อล5หม อ3ลั อ1ลิ อว5รุ อศ5กร อษ5ฐช อษ5ฐภ อส5กา อส5ติ อส5ตู อส5นี อส5พล อส5ฟอ อส5มิ อส5เฟ อส5แอ อส5ไพ อ1ห ออ5อว อะ5ธี 1อั 1อา อา5ค5เ อา5ฏา อา5ณั อา5ดุ อา5ดู อา2ต อา5ถร อา5นน อา5ปณ อา5มล อา5ย5ต อา5รด อา5รต อา5รบ อา3รย อา5ลป อา5วร อา5วี อา5สว อำ5ยว อำ5อว อิ5ชย อิ5ดะ อิ5ระ อิ5ศว อี5จู อี5ซู อี5ยิ อี5รุ อี5ลุ อี5ศว อี5หร อุ5กฤ อุ5กล อุ5คร อุ5ดม อุ5ดร อุ5ด้ อุ3ตรา อุ5ตุ อุ5ทร อุ5ทิ อุ5ทุ อุ5ธั อุ5บล อุ5บ๊ อุ5มง อุ5รพ อุ5ลก อุ5แว อู5คู อู5รา อู5ลา อ1เ อเป5ร อเสก5 อเส5ข อเห5ต อ1แ อ1โ อโร3 อ1ไ 3อ่อ อ่5อว อ่5อ่ อ่5โถ อ้5อว อ้5โถ อ้5โล ฮก5ฮา ฮก5ฮื ฮน5รี ฮฟ5วี ฮล5ดิ 3ฮอล ฮา5นอ ฮา5ป่ ฮา5ร่ ฮิ5บร ฮี5บร 3ฮื้ ฮู5ลา ฮู5ล่ ฮ1เ ฮ่5กึ ะ1ก ะ1ข ะ1ค ะ1ง ะ1จ ะ1ฉ ะ1ช ะ1ซ ะ1ด ะ1ต ะตะ4 ะ1ท ะ1น ะ1บ ะ1ป ะผี4 ะ1พ ะ1ม ะ1ย ะ1ร ะ1ล ะ1ว ะ1ส ะ1ห ะ1อ ะ1เ ะ1แ ะ1โ ะ1ไ ั2 ัก5ง่ ัก5ซ้ ัก5ตบ ัก5ผ่ ัก5ฝ่ ัก5ยอ ัก5ยิ ัก5รั ัก5ร้ ัก3ล ัก5วิ ัก5ษร ัก5อิ ัก5อี ัก5อ่ ัก5ใค ัก5ใฝ ัค5ฆิ ัค5ซี ัค5สถ ัง5ถึ ัง5ศุ ัง4ส5ว ัง5อว ัง5อุ ัง5ฮี ัจ5กล ัจ5ญะ ัจ5ถร ัจ5นึ ัจ5โจ ัช5ฎา ัช5นี ัช5พย ัช5พื ัช5รา ัช5ริ ัช5สม ัช5เร ัช5แพ ัช5โญ ัญ1 ัฏ5ทุ ัฏ5สง ัฐ5ทิ ัฐ5บร ัฐ5สภ ัฐ5เค ัณ5ฏก ัณ3ฐ ัณ5ยก ัณ5เฑ ัณ5โร ัด1 ัต5ดึ ัต5ถล ัต5ถั ัต5ถิ ัต5มณ ัต5มห ัต5รา ัต5รี ัต5ฤก ัต5ลั ัต5หล ัต5หี ัท5คี ัท5ทว ัท5ธน ัท5ธิ ัท5รา ัท5ลี ัท5ลุ ัธ5ยม ัน5ฉ่ ัน2ต ัน5ตภ ัน5ตะ ัน5ตั ัน5ตา ัน5ถธ ัน5ทึ ัน5ทุ ัน5ท่ ัน4ธ ัน5ธา ัน5ธิ ัน5ผว ัน5ฝร ัน5ฝ่ ัน5ภิ ัน5ยะ ัน5ย่ ับ1 ัป5คั ัป5ผา ัป4ร ัป5ลา ัป5หง ัป5โป ัป5โห ัพ5ยอ ัพ5ยา ัพ5โพ ัพ5โห ัฟ5ฟิ ัฟ5ริ ัม4ช ัม5ลา ัม5หม ัย5มร ัย5รุ ัล5ดี ัล5ปน ัล5ปพ ัล5ปิ ัล5ฟิ ัล5มุ ัล5ออ ัล5ไซ ัล5ไฟ ัว1 ัศ5นี ัศ5มี ัศ5เจ ัศ5ไน ัส5กา ัส5ดง ัส5ดน ัส5ดี ัส5ติ ัส5ถา ัส5ปู ัส5มั ัส5มิ ัส5ยิ ัส5รั ัส5ลิ ัส5วด ัส5วร าก5ถา าก5ฝร าก5ฝั า1กร า5กรร าก5รุ า3กอ าก5ฮอ า3กี า1ข า4ขบ าข5บู า1ค า4คจ า4คท า4คบ า4คป าค5ปร า4คพ าค5พื า4คภ า5ครี าง5บำ าง5ฝี าง5ฟิ าง5ออ าง5อิ า1จ า4จญ า4จห าจ5หา า4จอ า4จเ าช5กร าช5คร าช5คฤ าช5ทิ า5ชนะ าช5นี าช5ปะ าช5ลั าช5วโ าช5สก าช5สี าช5อง า1ชิ า3ชี าช5เป าช5เล าช5โอ า1ซ าญ5รอ า5ฏกะ าฏ5ดน า5ฏลิ าฏ5ลี า3ฏิ าฐ5กถ าณ5คด าณ5สถ าด5ผว า3ดอ า3ดิ าด5ไท าด5ไห า1ต า4ตญ า4ตภ าต4ว า1ท า4ทธ า4ทน า5ทนะ าท5บง าท5บร าท5สก าท5หล า4ท์ า1ธ า4ธน า2ธย าธ5ยม าน5ญ่ าน5ผู าน5รว าน5รั าน5ฤด าน5อว านุ1 าบ5จ้ าบ5ฉว าบ5ช้ าบ5ซึ าบ4พ าบ5รื าบ5ละ า3บิ าป5สร าป5ส่ าป5แช าพ5ถ่ าพ5ยน าพ5รั าพ5ลว าฟ5ต้ าฟ5ริ า3ฟิ า1ภ า4ภป า4ภล าภ5ลอ าม5ง่ าม4น4 าม5สก าม2ห าม5หม าม5หล าม5หา าย5กล าย5กอ าย5ขว าย5ข้ าย5ชน าย5ดิ าย5ด้ า5ยตน า5ยนธ า5ยนม าย5นอ า5ยนเ าย5บร าย5ผอ าย5ฝั าย5มุ าย5ม่ าย5รุ าย5ร้ าย5ลั าย5ล่ าย5วอ าย5อำ า3ยิ าย5ไห าร5กำ าร3ค าร5ชุ าร5ณู าร5ตร า5รทะ าร5ธุ าร5บั าร5ผจ าร5พร า5รภย า1รม าร5รา าร5ละ าร5วด าร5ว่ าร5หน า1ระ า1รั า1รา า1ริ า5ริก า5ริยะ า3รี า1รุ า1ล า4ลก า4ลค า4ลจ าล5ฎี า4ลด าล5ดี าล5ทห า4ลป าล5ปก าล5พร า4ลว า4ลส าล5อุ า4ลโ า4ล์ าว5ก่ าว5ข้ า3วดี าว5ดึ าว5นี าว5บอ าว5ยอ าว5ยื า5วรณ าว5รภ าว5รา า5ว5รี าว5รุ าว5ร้ าว5ฤก า5วอน าศ5นี า3ศร าศ5เล าษ5ดื าษ5ตร าษ5รา าษ5แก าส5กา าส5ด้ าส5ต้ าส5นี าส5ปอ าส5มห า1ห าห3ก าห5มง าฬ5โร า1อ าอนา4 า1ฮ า1เ าเม5ศ า1แ า1โ า1ไ ำ1ก ำ1ค ำท4ว ำ1น ำ1บ ำ1ป ำ1พ ำ1ม ำม5รง ำม5ลา ำ1ร ำ1ล ำ1ส ำ1ห ำ1เ ำ1แ ิก5ซี ิก5ถอ ิ1กร ิก5ร้ ิ3กฤ ิก5ล้ ิก5วา ิก5ษุ ิกิ5ส ิ1ข ิ4ขส ิข5สิ ิ1ค ิ4คต ิค5ตอ ิ4คน ิ4คหะ ิฆ5เน ิง5ชี ิง4สต ิง4ห ิง5หา ิง5ห้ ิง5อร ิจ5ศี ิช4น ิช5ลิ ิ3ชิ ิช5เช ิญ5หน ิญ5โญ ิด5ฉิ ิด5นี ิด5ผน ิด5รอ ิด5ระ ิด5ลั ิด5ออ ิด5อ่ ิต5ซู ิต5ถี ิต5ฟอ ิต5ลด ิต5ลา ิต5วส ิ1ติ ิ3ตุ ิท5ธั ิท5สน ิ3ธี ิน5งอ ิน5ฟร ิน5ยว ิน5ยอ ิน5ย้ ิน5ระ ิน5ริ ิน5ร้ ิ5นอบ ิน5อิ ิน5ฮุ ินู5ป ิบ5บิ ิบ5ผย ิบ5ยื ิบ5ระ ิบ5รี ิบ5ลั ิบ5ลิ ิบ5ล้ ิป4ก ิป5ทอ ิป5ผล ิ3ปร ิป5สต ิป5ฮอ ิป5โป ิป5โย ิ1พ ิ4พพ ิ4พโ ิพ5โส ิฟ5ฟอ ิ1ภ ิม5ฝี ิม5ลา ิ1มุ ิย5มิ ิร5ชร ิร5วด ิ1รั ิ1รา ิ1ริ ิ1รุ ิล5ปิ ิ1ลั ิ1ลา ิ1ลิ ิว5ซี ิว5ทร ิว5บิ ิว5ยอ ิว5ริ ิว5ลิ ิว5ลึ ิว5ออ ิวา5ส ิศ5พร ิศ5ร้ ิศ5เล ิศ5แพ ิษ5ณุ ิษ5ตร ิส5กร ิส5กี ิ5สตร ิส5ติ ิส5ที ิส5นี ิส5บอ ิส5รา ิส5ริ ิส5ลา ิส5ไซ ิ1ห ิหา4 ิ1อ ิ1เ ิเน4 ิ1โ ิ1ไ ี1ก ี4กต ี4กย ีก5ย่ ีก5ริ ีฆ5สร ีช5คณ ีซ5สถ ีด5ฆ่ ีต5กว ีต5ปฏ ี1ท ีท4น ีบ5รั ีบ5รุ ีบ5ร้ ี1ป ี1พ ี4พจ ีย5กถ ีย5รย ีย5รอ ีย5ระ ีย5รั ี5ยวน ีร5ณั ีล5จุ ี4วั ีวา4 ีษ5มา ีห5นา ี5หน้ ีห5บั ีห5มุ ีห5รา ี3หล ีห5โม ีห5ไส ี1อ ีอ4ร ีอา4 ี1เ ี1แ ี1โ ี1ไ ี่5ก่ ี่5ถ้ ี่5ปุ ี่5ปู ี่3ห ี่5โค ี่5โป ี้5กร ี้5จ้ ี้5ตะ ี้5ริ ี้5ลั ี้5ลุ ี๊5กร ี๋5จ้ ี๋5อ๋ ึก5ซึ ึก5ดำ ึก5ดื ึก5ยื ึก5ระ ึก5ลั ึก5ล้ ึก5ฮั ึด5ถื ึด5ฮั ึน5ทึ ืด5ฮา ือ5กล ือ5กอ ือ5กำ ือ5ข่ ือ5จ้ ือ5ชื ือ5ดำ ือ5ตร ือ5ถื ือ5นำ ือ5บิ ือ5ปล ือ5ปื ือ5ป่ ือ5พว ือ5พ่ ือ5ยน ือ5ยา ือ5รื ือ5ลา ือ5ล้ ือ5สอ ือ5สำ ือ5อี ุก5งอ ุก5ฉก ุก5ซ่ ุก5ดิ ุก5ผา ุก5รา ุก5รุ ุก5ละ ุก5ลี ุก5ล้ ุก5อี ุก5ฮื ุข5นา ุข5ปา ุข5ภั ุข5ภา ุข5ลั ุข5ศา ุข5ศึ ุข5เด ุค5ทอ ุ3คน ุง5ถุ ุจ5ลิ ุจ5หน ุช5รา ุช5เช ุญ5จน ุญ5ฤท ุญ5แจ ุฎ5ฐั ุฑ5พ่ ุณ5ค่ ุณ5ฑก ุณสม5 ุณ5หญ ุณ5หา ุณ5หิ ุณูป5 ุด5ผา ุด5ผ่ ุด5ลอ ุด5ลุ ุด5อู ุต5กว ุต5ซอ ุต5ตก ุ5ตระ ุ5ตริ ุต5ลุ ุ3ทก ุท5ธั ุ5ทริ ุท5ลุ ุท5โธ ุน5ทร ุน5ผล ุน5รอ ุบ5งิ ุบ5บิ ุบ5ผล ุบ5ยิ ุบ5อิ ุป5กร ุป5จา ุป5ถั ุป5ทา ุป5ยุ ุป3รา ุ5ปริ ุ4ปส ุป5สง ุป5สร ุป5ฮา ุป5โภ ุป5โล ุพ5พา ุพ5ภิ ุภ5ชล ุภ5เค ุม4น ุม5นุ ุม5รุ ุม5หย ุย5ช่ ุย5ฝ้ ุ1ร ุร5ข่ ุ4รค ุ4รฉ ุ4รช ุ4รท ุ4รธ ุ4รบ ุ4รพ ุ4รภ ุ5รภี ุ4รย ุ4รร ุ4รล ุ4รว ุ4รศ ุ4รส ุ4รอ ุ4รแ ุ4รโ ุล5จอ ุล5ชี ุล5ธิ ุล5มุ ุล5สต ุล5สแ ุ3ลา ุ3ลิ ุศ5โล ุษ5จี ุษ5ฎี ุษ5ปร ุ4ษย ุษ5รา ุษ5ร้ ุษ5เพ ุส5รา ุ5สละ ุส5ลิ ุส5วา ุ1ห ุห5กล ุห5นา ุ4หย ุห5ยา ุ4หเ ุห5เท ุห5เส ุ4หโ ุห5โย ุ1เ ุ1โ ุ๊5ต๊ ูก5วั ู1ช ูญ5หา ูญ5เป ูญ5เส ูด5บึ ูด5รี ูต5รู ูธ5เร ูบ5ไล ูป4ก ูป5ฌา ูป5ถ่ ูป5ทร ูป5พร ูป5ร่ ูป5แบ ูป5โฉ ูฟ5วี ู2ม ู5มิน ูร5ข่ ูร4ณ ู5รณภ ู5รณม ู5รณะ ู5รณาก ูร4พ ู5รพะ ู5รพา ูร4ม ูล5กร ูล5ค่ ู3ลั ูว5ไน ูส4ว ู1เ ู1โ ู่1 ู้1 ู๊5ตึ ู๋5กร ู๋5จี ู๋5อี เ2 เก5ยู เก5วั เก5ศว เก5อิ เค5ซอ เค5มี เค5ศว เจ5ดี เจ5นี เ4จร เจ5ลิ เจ5โต เซ5ทิ เซ5นอ เซ5รุ เซ5แค เด5บิ เด5รั เด5ลา เด5ลิ เด5ลี 2เตช เต5ปุ เต5มี เต5มู เต5ริ เต5ลุ เต5ศว เต5หะ เถ5รา เท5กร เท5คร เท5คว เท5โว เท5โศ เน4ต เน5ติ 4เนย เน5ระ เน5รั เน4ส เน5สา เน5เว เบ5ต้ เบ5บี เบ5ริ เบ5รุ เบ5ลี เป5ตอ เป5สก เป5สล เพ5ชุ เพ5ทุ เพ5สล เพ5โท เพ5ไน เฟ5อี เภ5ตร เภ5ทุ เม5ฆิ เม5ดิ เม5ลา เร5กอ เร5กะ เร5มอ เร5รว เร5วด เล5กร เล5คอ เล5ดี เล5วร เล5วู เล5หล เล5ฮุ เลิ4 เว5ก้ เว5ทิ เว5ล่ เว5ฬุ เว5ไน เส5ฉว เส5นีย์ เส5รี เส5วก เส5วน เส5แส เห5มั เห5ยง เห5ระ เห5รั เห5ศว เห5ศั เห5สั เฬ5วร เอ5กว เอ5ธิ เอ5ฬก เฮ5ละ เฮ5ลิ เฮ5โม เฮ5โร แก5วั แค5รอ แค5ริ แค5ลอ แค5ลิ แค5แต แค5แส แช5บ๊ แช5เช แซ5ยิ แด5รี แต5แต แน2 แบ4ค แ4ปร 3แพท แฟ5รี แ4ฟ้ แม2 แม5ชี แม5รี แม5เร แม่3 แอ5นะ โก4ฐ โก5ลอ โก5ลา โก5ลิ โก5วา โก5วี โก5ฮา โข5ทั โข5ภิ โข5เภ โข5โล โค5ตม โค5ติ โค5มู โค5ม่ โค5ริ โค5ลอ โค5ลั โค5ล่ โค5ออ โค5อะ โค5แท โค5ไซ โจ5ปก โฉ5เบ โช5ดึ โช5ห่ โซ5กร โซ5นี โซ5ฟิ โซ5ยู โซ5ลู โซ5สเ โญ4ช โญ5ปว โด5จี โด5นี โด5รา โด5ลิ โต5กร โต5รอ โต5รา โต5ริ โต5ลิ โท5กร โท5คอ โท5พล โท5รอ โท5แอ โธ5ทน โธ5ปก โธ5ปิ โธ5วน โธ5เฟ โน5ทุ โน5ปจ โน5รม โบ5ชุ โบ5ซอ โบ5ต้ โบ5รอ โบ5รั โบ5รา โบ5ลิ โบ5ล่ โบ5อิ โบ5ไฮ โป5กส โป5ลิ โป5แล โป5โป โป5โล โพ5ทะ โพ5ระ โพ5ลา โพ5ลิ โพ5ลี โพ5หา โพ5แท โพ5ไซ โฟ5กร โฟ5นี โภ5คิ โภ5ไค โม5ฆี โม5ดู โม5ร็ โม5หา โม5ฮั โย5ถิ โร5กะ โร5คิ โร5งั โร5ชิ โร5ธนะ โร5รา โร5ล่ โรส4 โร5สเ โร5หน โร5อี โร5ฮิ โร5แม โร5ไล โล5กร โล5กี โล5จน โล5ปุ โล5มก โล5รา โล5วะ โล5หิ โว5นอ โศ5ธน โศ5ภิ โส5กร โส5ติ โส5ธน โส5ภิ โส5ลิ โส5วร โส5หุ โส5โค โห5ฐา โห5รส โห5ระ โห5รา โห5สิ โห5ฬา โอ5คล โอ5ค็ โอ5ดี โอ5รส โอ5ละ โอ5สถ โอ5อิ โฮ5โล 3ใช้ 1ให ไก5ลา ไก5วั ไข5ข้ ไข5คว ไข5มั ไข5สั ไข5สื ไค5ศว ไช5น่ ไช5ศว ไซ5ดอ ไซ5บอ ไซ5บี ไซ5ปร ไซ5ออ ได5ฟุ ได5ฟู ได5ลิ ได5ออ ไท5ฟอ ไท5รอ ไท5แท ไป5ริ ไพ5ชย ไพ5ธอ ไพ5รั ไพ5ริ ไพ5ลิ ไพ5หา ไพ5โร ไพ5โอ ไฟ5แช ไฟ5แน ไภ5ริ ไม5ถิ ไม้1 ไล5บร ไล5บี ไว5รั ไว5อะ ไห5รณ ไห5ศว ไห5หม ไห5หล ไอ5กร ไอ5ซี ไอ5ดอ ไอ5ติ ไอ5พอ ไอ5พ็ ไอ5ศว ไอ5ศุ ไอ5ศู ไอ5ออ ไฮ1 ็ก5ซี ็จ5ขบ ็จ5สร ็ด5ลอ ็ด5อร ็ด5อึ ็น5ฉ่ ็น5ทร ็น5รอ ็น5วู ็น5อย ็น5อ้ ็บ5ด้ ็ป5ท็ ็ม5หม ่ก5ลั ่1ค ่ง5ริ ่ง5อร ่ง5อำ ่ง5อ่ ่4ฉี ่น5ง่ ่น5ฉ่ ่น5ทะ ่น5มื ่4นย ่น5ยน ่น5ย่ ่น5รม ่ม1 ่ม5พว ่ย5กะ ่ย5ฉุ ่ย5รา ่ย5ร่ ่ว5ช้ ่ว5ถึ ่ว5ยว ่ว5ไห ่อ5กร ่อ5กว ่อ5กะ ่อ5กี ่อ5ก้ ่อ5ข่ ่อ5ตร ่อ5ตะ ่อ5ต้ ่อ5ถื ่อ5บื ่อ5ผส ่อ5มว ่อ5ม่ ่อย3 ่อ5ยอ ่อ5ย่ ่อ5ร่ ่อ3ล ่อ5ว่ ่อ5สร ่อ5ฮั ่อ5ฮ่ ่า5กล ่า5ช้ ่า5ดง ่า5ด้ ่า5ฝื ่า5พร ่า5มง ่า5รึ ่า5ร้ ่าว3 ่ำ5ชอ ่ำ5ช้ ่ำ5ต้ ่ำ5ต๊ ่ำ5ไห ่1เ ่1แ ้ก5อ้ ้ง5ถ่ ้ง5ฝุ ้น5งู ้น5ฉบ ้น5ฉ่ ้น5ทะ ้น5ทุ ้น5ท้ ้น5รุ ้น5ร่ ้ม5งว ้ม5ฉุ ้ม5น้ ้ม5ยิ ้ม5ละ ้ม5ลุ ้ม5อล ้ย5กล ้ย5งช ้ย5ล่ ้ย5อ้ ้ย5ใบ ้ว5รอ ้1ห ้อ5กร ้อ5กล ้อ5คร ้อ5คู ้อ5งอ ้อ5ฉี ้อ5ดึ ้อ5ด้ ้อ5ต๊ ้อ5ถอ ้อน3 ้อ5ผ้ ้อ5ฝั ้อ5ฟื ้อ5มู ้อ5ระ ้อ5ร่ ้อ5อึ ้อ5ฮื ้า5จอ ้า5ชื ้า5ชู ้า5ช่ ้า5ช้ ้า5ดี ้า5ถิ ้า5ถึ ้า5บ่ ้า5บ้ ้า5บ๋ ้า5ปี ้า5ผา ้า5ฝร ้า3พ ้า5มุ ้า5ว่ ้า5สม ้า5สร ้า5สล ้ำ1 ้1เ ้1แ ๊ก5ซอ ๊ก5ริ ๊ก5ลุ ๊ก5ฮว ๊ง5บ๊ ๊ป5ซี ๊ย5ก่ ๋ย5อิ ๋อ5ด๋ ์ค5สเ ์ค5แล ์ต5ไท ์ท5ไท ์1บ ์1พ ์1ร ์1เ ์1แ ์1โ .ก6 .ข6 .ฃ6 .ค6 .ฅ6 .ฆ6 .ง6 .จ6 .ฉ6 .ช6 .ซ6 .ฌ6 .ญ6 .ฎ6 .ฏ6 .ฐ6 .ฑ6 .ฒ6 .ณ6 .ด6 .ต6 .ถ6 .ท6 .ธ6 .น6 .บ6 .ป6 .ผ6 .ฝ6 .พ6 .ฟ6 .ภ6 .ม6 .ย6 .ร6 .ฤ6 .ล6 .ฦ6 .ว6 .ศ6 .ษ6 .ส6 .ห6 .ฬ6 .อ6 .ฮ6 6ก. 6ข. 6ฃ. 6ค. 6ฅ. 6ฆ. 6ง. 6จ. 6ฉ. 6ช. 6ซ. 6ฌ. 6ญ. 6ฎ. 6ฏ. 6ฐ. 6ฑ. 6ฒ. 6ณ. 6ด. 6ต. 6ถ. 6ท. 6ธ. 6น. 6บ. 6ป. 6ผ. 6ฝ. 6พ. 6ฟ. 6ภ. 6ม. 6ย. 6ร. 6ล. 6ว. 6ศ. 6ษ. 6ส. 6ห. 6ฬ. 6อ. 6ฮ. 6ก์. 6ข์. 6ฃ์. 6ค์. 6ฅ์. 6ฆ์. 6ง์. 6จ์. 6ฉ์. 6ช์. 6ซ์. 6ฌ์. 6ญ์. 6ฎ์. 6ฏ์. 6ฐ์. 6ฑ์. 6ฒ์. 6ณ์. 6ด์. 6ต์. 6ถ์. 6ท์. 6ธ์. 6น์. 6บ์. 6ป์. 6ผ์. 6ฝ์. 6พ์. 6ฟ์. 6ภ์. 6ม์. 6ย์. 6ร์. 6ล์. 6ว์. 6ศ์. 6ษ์. 6ส์. 6ห์. 6ฬ์. 6อ์. 6ฮ์. 6กิ์. 6ขิ์. 6ฃิ์. 6คิ์. 6ฅิ์. 6ฆิ์. 6งิ์. 6จิ์. 6ฉิ์. 6ชิ์. 6ซิ์. 6ฌิ์. 6ญิ์. 6ฎิ์. 6ฏิ์. 6ฐิ์. 6ฑิ์. 6ฒิ์. 6ณิ์. 6ดิ์. 6ติ์. 6ถิ์. 6ทิ์. 6ธิ์. 6นิ์. 6บิ์. 6ปิ์. 6ผิ์. 6ฝิ์. 6พิ์. 6ฟิ์. 6ภิ์. 6มิ์. 6ยิ์. 6ริ์. 6ลิ์. 6วิ์. 6ศิ์. 6ษิ์. 6สิ์. 6หิ์. 6ฬิ์. 6อิ์. 6ฮิ์. 6กุ์. 6ขุ์. 6ฃุ์. 6คุ์. 6ฅุ์. 6ฆุ์. 6งุ์. 6จุ์. 6ฉุ์. 6ชุ์. 6ซุ์. 6ฌุ์. 6ญุ์. 6ฎุ์. 6ฏุ์. 6ฐุ์. 6ฑุ์. 6ฒุ์. 6ณุ์. 6ดุ์. 6ตุ์. 6ถุ์. 6ทุ์. 6ธุ์. 6นุ์. 6บุ์. 6ปุ์. 6ผุ์. 6ฝุ์. 6พุ์. 6ฟุ์. 6ภุ์. 6มุ์. 6ยุ์. 6รุ์. 6ลุ์. 6วุ์. 6ศุ์. 6ษุ์. 6สุ์. 6หุ์. 6ฬุ์. 6อุ์. 6ฮุ์. 6ะ 6า 6ๅ 6ำ7 6ิ 6ี 6ึ 6ื 6ุ 6ู แ6 โ6 5ไ6 7ใ6 6็ 6่ 6้ 6๊ 6๋ 6์ 6ํ 6ฺ 6๎ เ6ข เ6ฃ เ6ค เ6ฅ เ6ฆ เ6ง เ6จ เ6ฉ เ6ช เ6ซ เ6ฌ เ6ญ เ6ฎ เ6ฏ เ6ฐ เ6ฑ เ6ฒ เ6ณ เ6ด เ6ต เ6ถ เ6ท เ6ธ เ6น เ6บ เ6ป 7เ6ผ เ6ฝ เ6พ เ6ฟ เ6ภ เ6ม เ6ย เ6ร เ6ล เ6ว เ6ศ เ6ษ เ6ส เ6ห เ6ฬ เ6อ เ6ฮ ช6วา. ช6ไ ธ6ไน ม6ไห ส6ไต เลส7ไต ส6ไน ส6ไบ ส6ไป ส6ไล บ6ทคว ม6วก ม6วน ม6วด ม7วดี ม6วย ะม6วง ล7ชน ัต5ถุ ัต6ถุ์ 6ตร. ธา6ตุ. บุ6ตร. ค6รู ฮิบ6รู ฮีบ6รู ส6ภา ส7ภาร เส7ภา โส7ภา ผ6วา น6คร. .เห6ยง เปี่6 เขี้6 ม6ณี คาม7ณี .รม7ณี .รัม7ณี หม7ณี ง6วด ง6วน วัง7วน ง6วย มง6วง อย6อด พ6ญา จุ6รณ ฤ6ชา .ฤ6ทัย พรร6ดิ สวา6ดิ อ6ริ. จน6ที. ธค6ยา นิม6นา ย์ม6นา า7ณะ ิ7ณะ ุ7ณะ ณ7ณะ ก7ณะ ท7ณะ ล7ณะ ุษ7ณะ ฤษ7ณะ รป7ณะ หม7ณะ สม7ณะ ลว7ณะ รว7ณะ ร5ณะ ณร6สี ก6นะ ยก7นะ ค7นะ ย7นะ ภว7นะ มท7นะ รต7นะ ลว7นะ วจ7นะ วท7นะ วส7นะ ศม7นะ ภช7นะ ไช7นะ าลป7นะ รรธ7นะ สธ5นะ โสธ6นะ สว5นะ เสว6นะ สาว7นะ ัจ7นะ ัช7นะ ัฏ7นะ ัฒ7นะ ัต7นะ ัท7นะ ัป7นะ ัส7นะ ุจ7นะ อาส7นะ ุ7นะ 5ผี 7จำ 5งำ ห6งำ น7รำ ย7รำ ร7รำ โค7รำ ไพ7รำ น7ยำ ม7ยำ 5งง. ห6งง น7งก 5ชน. เ6ชน โ6ชน 5กร. ั6กร า7นะ ถ7ระ า7ยก. า7ยน. า7ฐี า7นี า7วี ป5โ ป6โย ป6โภ วิป7โย อุป7โภ ศ7นะ รร7มะ ต5ถี ุต6ถี 5บท. ส6บท 5บถ. ข6บถ ส6บถ 7ฟู 7ษุ 5ตะ. ค6ตะ ร6ตะ สร7ตะ า7มี มิ7ผ า7กิ า7กล ิ7กล. ์7กล 5นำ ห6นำ รี7ผ 7ณุ 5นี. ห6นี ฉ6นี าร6นี วีช6นี สส6นี มท6นี รม6นี น7ยิ ิ5ลี ุ5ลี า7ลี โค7ลี โม7ลี ท7ลี ร7ลี ก7ยะ ค7ยะ ป7ยะ ท7ยะ ธ7ยะ น7ยะ ษ7ยะ า7ยะ ิ7ยะ คี7ยะ ฆี7ยะ ณี7ยะ นี7ยะ รี5ยะ เปรี6ยะ มโห5 ิ7รี ี7รี ู7รี หา7รี ม7รี. น5รี. เต7รี. ช7รี. ถ7รี ภ7รี ภม7รี โม7รี ภุม7ร พ7รี. เว7รี 5ผล 5ดล. 5รส. ก6รส จ6รส โค6รส ท6รส พ6รส ด6รส 5คน. ณ7หา ฤๅ5 ฤา5 .ยี่7 า7วะ เท7พี เท7วี บรร7จ บรร7ถ บรร7พต 5ทก. 5ดร. น7ทร. า7ทร. โค7ทร. โล7ทร. โส7ทร. 7อู. 5พล. ไพร่7 5ศก. อัฐ5 อัฐ6ม อัฐ7มี ี7วี ู7วี ถ7วี. ส7วี. ฏ7วี. น7ตี ร7ตี อ7ตี า7ตี ิ7ตี ู7ตี า7สี ณ7สี ห7สี เว7สี ู7สี ิ7สี ก7สี โบ7ลา ู7ลา อจ7ลา เว7ลา บิว7ลา มข7ลา เอ7ลา ี7ลา โร7ลา โอ7ลา โซ7ลา ิ7กะ ุ7กะ อ7กะ นว7กะ ิณ7กะ เภ7กะ ัย7กะ ิย7กะ รธ7กะ ัฏ7กะ ัฒ7กะ ิช7กะ ศต7กะ มล7กะ 7ทุ. โซ6ร ธ6นู ัส7ดุ. ร7คต ดง7คต 5กง. เ6กง 7ฎก ณ7มี ว7มี ศ7มี ู7มี ี7ติ รุ7ติ สุ7ติ ฮ7ติ อร7ติ วีส7ติ ติงส7ติ คุป7ติ มุต6ติ ภัต6ติ ก7ดี ต7ดี พ7ดี ม7ดี ย7ดี ศ7ดี อ5ดี า7ดี ี7ดี ุ7ดี ุว7ดี ดิบ7ดี นัก7 กุณ5 กุณ6ฑ์ 7ซี. 5ที. จน6ที ี7รา ู7รา ์7รา ิต7รา ม7รา ย7รา .มก7รา รบ7รา ลิก7รา เห7รา. 7กฎ. 7กฏ. 5หะ ค6หะ นิค7หะ เค7หะ ท6หะ เท7หะ ู7หา ฬ7หา ค7หา เน7หา ่7หา 5มะ ร6มะ ห6มะ ต6มะ 5หู 5ดำ ส6ดำ 7คำ 5สะ ว6สะ 5ฐะ ส6ฐะ 7ธะ 5พี. ร6พี ทร7พี ปฐ7วี ิ7ดา ษ7บ ษ7ป ิ7ระ ี7ระ ู7ระ ช5ระ ิต7ระ ทห7ระ ท7ระ. ุก5ระ. สว7ระ ัส7ระ ิส7ระ เป7ระ อ7ยา. เก7ยา รร7ยา สา7วก ิ7ธิ ุท7ธิ. ิท5ธิ. .สิท6ธิ. บุริมสิท6ธิ. ไกรสิท6ธิ. ป7ธิ ขัดสมา6ธิ พยา6ธิ. 5ษี. ด6นู ิ7วะ ี7วะ ุ7วะ ี7วก ย7วะ เท7วะ ไท7วะ ัท7วะ าช7วะ ไศ7วะ 7ถะ 7ษะ 5พร. 5ผง 5ธี า7ชะ ิ7ชะ ร5ชะ ส7ชะ โอ7ชะ 5ฆะ 5ฟะ า7ฟี ิ7ถี ร7ถี 5ฮา 5ญี 5ผา 5หิ. สิน7ธพ สิน7ธุ. สิน7ธู 5ชู 5ศะ ิ7ละ ุ7ละ ู7ละ ย7ละ ด7ละ .วส7ละ อเจ7ล เต7ละ ่7ละ น7ทะ ท7ทะ ส7ทะ น7ตุ. รร6ตุ มา7ตฤ ิ7รพ า7รพ. ไก7รพ 5ศุ. า7ถา า7สพ พ7สพ ุ7ขี 7สอ. า7ดะ 5บะ. 5ยี. ห6ยี 5กี. 5หก. ง7อร. ม7อร. ี7วร ส7วร. พู7นท 5จร. โ6จร. 7ศพ. โป7ลี 7ภพ. 7นพ. 7ณพ. า7รก. ทก7รก ย7รก. ยว7รก. 5มล. ุ5บล. โล7บล. 5ชล. 5ชก. 7โพ 5ณู 7ปี. า7บี. 5ฏะ. า7ฬี 5ปะ. ฉ6ปะ ส6ปะ ู7ลู 5ตู. 5ยู. 7ฆี. ิ7จี ี7จี ุ7จี ู7จี เว7จี 5ศี. 5มน. 5ยอ. ผ6ยอ. 5สง. 7สร. 5ดก. ส6ดก 7โก. ก7ฝ า7มก. 5ซอ า7ขะ ู7ขะ ส5ขะ ร7ษา 5ภะ ศ7ภ ิ7ลก ุ7ฎี ศา5ข 5สา. ั6สา 7ซู 5ษก. ษ7ฐี 5ดม. ส6ดม ด7ลม. ส7ลม. ว7ลม. ี7ลม. 5ศล. นิ7ยต 7งู 5จะ. า7สก. โป7สก 5ยศ. 5ธก. 5กบ. 7คู. ส5มา. 5แล. 5พก. โส7ภ รร6ดิ. า7วก. น7นร. 5จอ. 5จบ. 5คบ. 5ฉล. ม7รม อบ7รม ิ7รม. ี7รม. 5ซน. 5ดอ. 5กิ. ซู7ซุ ซู7ฮก 5บส. น7รน. ตก7ลง ม7ตน ตัว7ตน ี7วง ศ7วง. แตร7วง แวด7วง า7ฑู 5หด. อบ7นบ นา7คร. ี7ฑา ู7ดู า7รภ. า7ฝ ล7รบ. ว7รบ. อ7รบ. า7รณ. น7ยง ม7ยง ุ7ยง ิ7ยง ิ7ยน หา7พน า7งิ ช7รถ. น7รถ. ส7รถ. ัน7ธร. มณ7ฑก มณ7โฑ มร7กต มร7ฑป ยอด7อก โล่ง7อก ยืด7อก ห7ห 5ทด. ว7นม. ทพ7นม. โค7นม ษ7ฎร. ิ7ปุ ิ7ปู ี7รอ. ย7ลำ อ7ลำ ้7ลำ น7ทม. ป7ทม. วก7วน อล7วน ิ7จล. ช7ญะ ี7ข ศีล7 5ธม. สม7รด สัก7วา สัป7ด สัป7ท า7สม. อ7สม. า7นล. ี7รุ ู7รุ เน7รุ ง7หล สีห7นุ 5ภร. 5จด. บ7ยก. ดิ7ศร ร7ศร อพ7ยพ ร7ชร. รส7กา ลส7กา อาจ7อง ี7มู อึง7อล ุ7ชุ ุ7สภ. เก7ชา เก7ศา ช7ตก. บ7ตก. เข7ฬะ ห7ณี อ7ปน. ย7ชม. เบื้อง7 5คะ ง7ออ. อ7ออ. เรือ7ธ เรือ7บ เลี้ยว7 5กก. เ6กก อ7ขอ. า7กอ. แด7วู บ7ยล. โฉ7เก โด7มร โต7มร 7โผ โท7โส ้7ปด. 7คี. โย7นก. โส7มม 7ฬส. ต7ถิ 7โฮ ใจ7 5ฟง ไช7โย 5พต. กรร7กศ ล7บก. ศ7ยป. า7นน. ุ7ฎา ู7ฏา า7มอ. ท7โท ุ7ทส จ่า7ร ฬ7หี า7ฒะ ธต7รฐ ท7คล. ต7ถร. ิ7ฐิ ป7ผะ พฤ7ษภ. ิ7ธุ า7ฬก. ห7สิ ฏ7ฏิ. ษ7ฏิ. ศิษ7ฎิ ษ7ฏี 5ษส. ิ7ปิ ู7ริ. ฑ7ฑุ ษ7ฏุ า7ตา ว7ตก ง7ตก เก6ตุ. ส7ตุ ลิ7บง ฮ7โ 7อุ. ิศ7รา", + ["data"]=".กัน3 .ชี5วั .ทัศนู5 .ที่3 .บท1 .รง4 .ราย3 .ลำ3 .สน5ท .สู3ต .ใบ3 2ก1ก ก4กม กก4ส 2ก1ข ก4ขค กข5คณ ก4ขช กข5ชา ก4ขณ ก5ขณะ ก5ขณา ก4ขบ กข5บุ ก4ขภ กข5ภั ก4ขม ก5ขมั กข5มา กข5มู กข5ลา กข5ศั ก4ขเ กข5เท กข5เว ก4ข์ ก1ค กง5บว ก1จ ก1ช 2กซ กญ5จน กฎ5หม กฎ5เก กฏ5หม ก5ดิน ก1ต ก4ตด กต5ดิ ก4ตส ก4ตเ ก1ท ก1น ก4นด ก4นธ ก1บ ก1ป กป4ร ก1พ ก1ฟ ก1ม ก4มม ก4มส ก4มเ กย5มุ ก3ย้ กร5กฎ ก5ร5ณั กร5ต๋ 1ก4รร กร5รา กร5ลา กร5วร ก5ราค ก5รินท ก4รู กร5ไฟ กล5นค กล5มห ก2ว ก5วัต ก5ษณน ก3ษณะ ก5ษณา ก5ษมา ก5ษมี กษ5เท ก1ส กส4น ก4สโ ก1ห กอ5อิ กะ5ถั กะ5ผล 4กะร 1กั 1กา กา5กะ กา5ดู กา5นี กา5น้ กา5บอ กา5ฝา กา5รอ กา5ร่ กำ5ด้ กำ5ทอ กำ5ผล 1กิ กิ5กะ กิ4ต กิ5นี กี5รณ กี5รต กี5สถ 1กุ กุ5งอ กุ5ชิ กุ5ฎุ กุ5มุ กุ5รร กุ5ลี กุ5แห 1กู กู5ปร กู5รข กู5รม กู5ลิ ก1เ ก1แ ก1โ ก1ไ ก่5กอ ก่5บ้ ก่5ป่ ก์5ท็ ข2 ขม5หิ 4ขลา ขอ5ขม ขอ5ง้ ขอ5อภ 1ขั 1ขา ขา5ก๊ ขา5ทน ขิ5ปส ขี้1 ข่5มุ ข่5หง ข้าว3 ค1ค ค1ช คช5สี ค4ชเ ค4ณิ ค4ทร คท5รี คท5วอ คน5ยอ 4คนิ คป5ซู คป5ผก 3คมน คม5ฟร คม5ลอ 2คย คร5ซอ คร5นอ คร5นี คร5พน คร5มเ คร5ร้ คร5ลิ คร5หา 4ค5รัก ค5ราต คฤ5หบ คฤ5หา คฤ5โฆ คล5คู ค2ว คว5ทอ 3ควา 2คส คส5ติ คห5กร คห5นิ คห5บด คห5สถ 3คอน 3คัน 1คา คา5ปู คา5พจ คา5พย คา5รว คา5วจ คำ5ดี คำ5โอ คำ5ไก 1คุ คุ5ณู คุ5ลี 4คุ์ คู5ปอ คู5ลอ 2ค1เ ค1โ 2ค์ ค์5จำ 1ฆา ฆา5ณั ฆี5ยก ง1ก ง4กห งกะ4ร ง4กเ ง4ก์ ง1ข ง4ขก ง4ขต ง1ค ง4คจ ง4คช ง5คชาติ ง4คญ ง4คธ ง4คบ ง4คป งค5วั ง4คศ ง4คโ งฆ5ปร งฆ5สภ งฆ5เถ งฆ5เภ ง1ง ง4งเ ง1จ ง1ฉ ง1ช ง4ชี ง1ซ ง1ด ง1ต ง1ท ง1น งบ5ดุ ง1ป ง1ผ ง1พ ง1ม ง1ย ง1ร ง1ล ง1ว ง4วเ ง1ส งส5กล งส5กุ ง4สบ ง4สพ งส5พย ง4สภ ง1ห งห5นา ง4หบ งห5บั งห5รา 1งา งา5ช้ งา5รำ งู5สว ง1เ ง1แ ง1โ ง1ไ ง่5งอ จ1จ จ4จว จ1ฉ จด5จ่ จต5จำ จต5มู จต5ริ จป4ก จฟ5ฟร จมบ5พ 3จริ จอ5งอ 1จั 1จา จา5มร จา5รึ จำ5ทว จำ5อว 1จิ จิ5จู จิ5ตอ จี5ดี จุ5ฑา จุ5สม จู5ปิ จ1เ ฉ2 ฉก5ฉว ฉก4ษ ฉท5ทิ ฉร5ฉิ 1ฉั 1ฉา ฉา5ก๊ ฉา5พย ช1ช ช1ฌ ช4ฌก ช4ฌฆ ชด5ช้ ช5นีก 4ชน์ ช1บ ชฟ5รอ ชฟ5โร ชร5กล ชร5ริ ชร5ฤก ชร5หล ชร5หึ ชร5อุ ช3รา ชว4โ ชอง4 1ชั 1ชา ชา2ต ชา5ตร ชา5ปี ชา5มต ชา5ยต ชา5สง ชำ5งั ชิ5นี ชิ5รณ ชิ5แก ชี5ผะ ชี5ผ้ ชี5ฟอ ชี5รณ 1ชีว ชี5วน ชุ5ติ ชุ5ลด ชู5ปก ชู5ปถ ชู5ปโ ช1เ ช่5อิ ช้5สอ ช้5ได ซก5ซอ ซน5ทร ซ5ราม ซล5ฟี 1ซั 1ซา ซา5ชู ซา5มู 1ซิ ซิ5ตร ซิ5แล ซี5ดี ซี5นี ซี5รา ซี5ริ ซี5ร็ ซี5ลี 3ซึม ซู5ซู ซู5บิ ซู5ริ ซู5ลิ ซู5ฮา ซ1เ ซ1โ ซ่5ง่ ซ่5ซ้ 1ซ่า ซ์5คล ญจ5ดุ ญ4จน ญ5จ5นท ญ5จ5นบ ญ5จนา ญจ5บร ญ5จ5มบ ญจ5รง ญจ5วี ญจ5ศี ญ4ฉน ญ1ช ญ1ญ ญประ4 1ญา ญา5ญ่ ญา4ต ญ่5บ้ ฏ1ฐ ฏ4ฐบ ฏิ5ทิ ฏิ5ปท ฏิ5ปุ ฏิ5สน ฏิ5สว ฐ4ภั ฐม5ฌา ฐม5พย ฐม5ฤก 1ฐา ฐา5นี ฐุ5ชุ ฑา5มณ ฑา5สถ 3ฑูร ฒิ5สภ ฒิ5สม ณ1ฑ ณ4ฑก ณ4ฑฆ ณ4ฑน ณ5ฑนะ ณ4ฑบ ณ4ฑม ณฑ5ลา ณ4ฑส ณ5ฑสก ณฑ5สถ ณ5ฑ5สี ณฑ5โล ณ4ฑ์ ณย5รั ณ1ร ณ4วา ณห5พล ณห5ภู 1ณา ณา5ปี ณา5วร 1ณิ 1ณี ณี5สง ณู5ปโ ด1ก ด4กง ด4กด ดก5ดื ด4กเ ด4กแ ด1ข ด1ค ดง4ค ดง5ออ ด5ชนะ ด1ด ด4ดเ ด1ต ด1ท ด1ป ด1พ ดม5คต ดร5ลิ ด4รู ด3ร้ 4ดร์ ด1ส ด4สก ดส4เ ด1ห 1ดั 1ดา ดา5มุ ดา5รก ดา5สว ดำ5ฤษ ดิ5ทอ ดิ5ทิ ดิ4บ ดิ5วร ดิ5ศว 4ดิ์ ดี5ดี 3ดีน ดี5ฝ่ ดี5รอ ดี5ลิ ดี5วี ดี5หม ดี5หว ดู5ถู ดู5ปอ ดู5รั ดู5หม ดู5แค ด1เ ด1แ ด1โ ด้5ยิ 2ด์ ด์5ปร ด์5สป 2ตก ตก5ร้ ต1ค 2ต1ช 2ต1ต ต4ตภ ต4ตส ตต5สด ต4ตโ ต5ถกะ ตถ5กิ ต3ถา ต5ถุป ต5ถุศ ตถ5เล ตทัศนูป5 2ตน ตน5ฟอ ตน5วร 2ต1บ ต4บช ตบ5ชว ตป5นี ต1ภ 2ตย 4ตรก ตร5งอ ตร5จี ตร5จุ 4ตรฐ ตร5ตร ตร5ทว ตร5ผล ตร5ฝร ตร5พล ตร5รง ตร5ลด 4ตรศ ต5ริยา ต4รู 2ตร์ ตฤ5ตี ตล5รั ตส5วา ตส4เ ตส5เซ ตส5แต ตอ5ม่ ตะ5ใภ 1ตั 1ตา ตา5กล ตา5กว ตา5นึ ตา5ปร ตา5ปล ตา5ผิ ตา5ฟู ตา3มห ตา5มอ ตา5มะ ตา5ฬี 1ติก. ติ5จู ติ5ช่ ติ5ซอ ติ5ทิ ติ5นร ติ5บอ ติ3ม ติ5ยภ ติ5ยม 4ติ์ ตี5ขล ตี5คู ตี5ตื ตี5รว ตี5ลั 3ตี้. ตุ5ตถ ตุ5ทส ตุ5ป่ ตุ5มห ตุ5รก ตุ5ลั ตุ5สด ตู5ดิ ต1เ ต3แล ต1โ ต่5ถา ต่5ว่ ต่5สว ต้5ก๋ ต้5ตอ ต้5ฝุ ต๋5เต ต์5คล ต์5ฟู ต์5ศต ถ4กิ ถด5ถอ ถม5ถื ถล5ไถ ถว5ไม ถะ5ถั ถ4าธ ถา5วร ถ4ีย ถี5ลิ 3ถุน ถ่5ถอ ถ่5ถา 4ทกา ทค5ติ ทค5นี ทด5รอ ทด5ลอ ทธ5คย ท5ธชะ ทธ5ฎี ทธ5ปฏ ทธ5พร ทธ5รั ทธ5ศต ทธ5สี ทธ5อง ท5ธิก ท5ธิช ท5ธิบ ท5ธิป ท5ธิผ ท5ธิพ ท5ธิภ ท5ธิร ท5ธิฤ ท5ธิศ ท5ธิส ท5ธิโ ทธ5เจ ทพ5ธิ ทพ5ยุ ทฟ5ลอ 2ทย ท5ยาน ทร5คต ทร5คร ทร5ธน 3ทรร ทร5สโ ทร5หว ทร5หึ 3ทรั 1ทรา ท5ราก 4ท5ราห 1ทรี ทว5ทห ทว5สถ ทศ5ทิ ทศ5วร ทสน5ท ทห5วั ทห5ฬิ 1ทั 1ทา ทา5ฐิ ทา5ฒิ ทา5นอ ทา5มต ทา5มร ทา5รพ ทำ5ขว ทำ5ซ้ ทำ5ท่ ทำ5โท ทิ5ฆั ทิ5ฐิ ทิ4พ ทิ5พา ทิ5วง ที5นว ที5นอ ที5นี ที5รา ทุ5คต ทุ5ติ ทุ5ลั ทุ5ศี 1ทู ทู5น่ ท1เ 2ท์ ท์5ดอ 1ธร 4ธรส 4ธรั 1ธา ธา5รณา ธิ5ฤท ธิ5ศี ธิ5สม ธุ5ดง ธุ5ลี ธู5ปน น1ก น4กค น4กป นก5ยู นก5รู น1ข นข5ลิ น1ค นค5ริ น1จ น4จอ นจ5อน น1ช น4ชญ น1ซ น1ด น1ต นต5กว น5ตกะ นต5ดิ น4ตท นต5ทิ นต5ปิ น4ตภ น5ตระ น5ตรั น3ตรา น5ต5ริ นต5ฤด น3ติ น5ตุก น5ตุฏ น4ต์ นถ5ธุ นถ5รจ นท5ขี นท5นน น5ทนะ นท5ผล นท4ย น5ทรง น5ทรุ นท5ฤก น5ทลา น5ทวย น3ทอ น1ทิ น3ที นธ5กร น5ธกะ น5ธนะ น5ธุก น5ธุร น5ธุว น5ธุศ นธ5ไม น1น น4นต น4นท น4นร น1บ นบ5นอ น1ป น4ปจ นป5จู น4ปท น1พ นพ5ปฎ นพ5ศู นภ5ศู น5ยนต น3รา นฤ5คห นฤ5ปเ นฤ5เท นฤ5เบ น1ล น4ลล นว5ร่ น1ศ นษ5กร น1ส นส5ฟอ นส5แด นส5แต น1ห นอ5กะ 3นอน 1นั 1นา นา4คร นา5ณั นา5ปร นา5รย นา5วต นา5วล นา5สณ นา5สน นา5สว นา5ฬิ 4นาะ 1นิ นิ5จู นิ5ด้ นิ5ฟอ นิ5มน นิ5ยม นิ5ยา นิ5รอ นิ5ลุ นิ5วร นิ5สง นิ5สถ นิ5สี นิ5แด 1นุ นุ5พย 1นู 2น1เ น1แ น1โ น1ไ น่5อี 3น้อ 1น้ำ น์5สไ บ1ก บ4กษ บกิส5 บ4กแ บ1ข บ1ค บ4คท บค5ที บ4คโ 1บดี. บ1ท บบ5ฉบ บบ5ฝึ บบ5อย บ1ป บ1พ บร5มี บ5รัด บ1ส บ4สบ บส4เ บ1ห บอ5ดี บอ5ระ 3บอล 1บั บัพพาชนี5 1บา บาจ5ร บา4ต บา5ตอ บา2ท บา5ทา บา5ทุ บา5รน บา5รอ บา5สม บิ5ก้ บิ5ชอ 3บิน บี5คิ บี5ร่ 1บุ บุค3 บุ5ตร บุ5ถุ บุ5รพ 1บู บู4ช5น บู5ติ บู5ย่ บ1เ บ1แ บ1โ บ๊5จี บ๊5เบ ปก4ส ป4จั ป4จา ปฐ5ปท ปฐ5พี ปต5ถก ปต5พล ป1ป ป4ปเ ปม5ด้ ป4ยุ ปร5ตอ ปร5ติ ปร5ตี ปร5ตุ ปร5ผั ปร5ษณ 1ประ ป5ริค ปร5แก ปร5แท ปร5ไบ ปร5ไฟ ปล5ญว ป4วา ปส4ต 1ปั 1ปา ปา5ฐก ปา5ณก ปา5นี ปา5ปิ ปาร4 ปา5รเ ปิ5ดอ ปิ5ดิ ปิ5ยภ ปิ5ยอ ปิ5หก ปี5ชี ปี5ฬก ปี่3 ปุ5คล ปุ5ถุ ปู5จ๋ ปู5ติ ป1เ ป1ไ ผก5ผั ผณิ5ศ ผน5ผั ผ4นิ ผ4ยา ผล5พล ผล5ไม ผ4สา ผี5ดิ ผี5ตอ ผี5ถ้ ผี5ห่ ผ้า3 3ฝอย ฝ่5ฝั 3พจน พจ5นี พช5ฉล พ3ติ พท5ริ พทัก4 พน5ทะ พ4นั พนิ4 พ1พ 2พ2ย พย5ก๊ พร5ชย พร5ซี พร5มี 1พรร พ4รู พร5ไฟ 3พฤก พฤ5ฒา พล5ทิ พล5ร่ พส5เฟ พอ5คว พอ5สม 1พั 1พา 4พาจ พา5ชน พา5นร 1พิ พิ5ถั พิ5ถี พิ5ปล พิ5รอ พิ5รี พิ5ลึ พิ5ศุ พิส5ม พี5ระ พุ5ชิ พุ5พอ พู5ทว พู5พอ พ1เ พ4เย พ่5ป๊ พ่อ3 พ้5ท้ 2พ์ พ์5ดี ฟซ5ติ ฟซ5ทิ ฟร5ติ ฟส5ติ ฟส5ทิ 1ฟั 1ฟา 1ฟิ ฟิ4ลา ฟี5ฟ่ ฟู5ฟ่ ฟ1เ 1ฟ้ ภค5ทร ภค3ว ภช5นี 1ภั 1ภา ภา5ณก ภา5ณว ภา5รด ภา5รต ภา5รย ภา5วน ภิ5ชน ภิ5มห ภิ3ร ภิ5สม ภี5ษม ภุ5ชง 1ภู ภู5ฏา ภู5ริ ม1ก ม4กม ม4กษ ม1ข ม4ขล ม3คร มค5อิ 1มงคล มง5ฟอ ม1จ ม1ช มช4ว ม1ซ 3มณฑ มณ5ฑน มณ5บร มณ5พร มณ5เฑ มณ5เพ มด5ชม มด5ยอ มด5ลู ม1ต ม4ตธ ม4ติ ม4ตไ มต5ไต ม1ท 3มนตร มน5ฮั ม4นุ ม1บ มบ4พ ม1ป มป4ช มป4ท มป5ฤด มป5ฤๅ ม4ป์ ม1พ ม4พก ม4พว ม1ภ มภ5กถ ม1ม ม4มเ ม4มโ มย5รา 3มรร ม3รั ม1ริ มฤ5คิ มฤ5เค มล5ทิ ม3ลา ม3ลิ ม3ล้ ม1ว มว5มอ ม4วล ม1ส มห5กร ม3หน มห5ภา ม5หาญ ม5หาย มหา3ส มอ5ขว มอ5คร มอ5ดู มอ5ตำ มอ5นว มอ5นอ มอ5ระ 4มอั มะ5ถั มะ5ฝ่ มะ5ฮอ 1มั ม4ั่ 1มา มา5ดร มา5นร มา5นอ มา5ป่ มา5พจ มา5มก มา5มุ มา5ม่ มา5ยณ มา5ยอ มา5ร่ มา3ว4 1มิ มิ5กภ มิ5ซร มิ5ตล มิ5ถิ มิ5น่ มิ5ฟล มิ5ลำ มิ5ลี มิ5แพ มี5ขม 3มืด 1มือ. มุ5ทะ มุ5ทั มุ5ทิ มุ5ทุ มุ5ฮั มู5ซี มู5ป่ มู5รต มู5ลิ มู5หย มู5หร มู5ฮั มู5แด มู5แผ มู5แฮ ม1เ ม1แ ม1โ ม1ไ ม4่า ม้ม4 3ม้า ม์5ภิ ยก5ย่ ย1กร ย4ก5ร้ ย1ค ยง5บ่ ยง5ฝ้ ยง5อย ยจ5คร ยด5ย้ ย1ต ย1ท ย1ธ ยบ5ร้ ย1ป ย1พ ย1ภ ยม5ยอ ยม5รา ยม5หา ยม5อี ย4มิ ย1ย ยย4ส ยร5ถี ย5ร4บั ยล5ไท ยว5ข้ ยว5จ๊ ยว5ดอ ย5วดี ยว5นี ยว5ย่ ยว5รั ยว5ไส ย1ศ ย1ส ย1ห ย4หฐ ยห5ฐา ย4หป ยห5ปร ยอ5บี ยอ5รม 1ยั 1ยา ยา5กฤ ยา5กว ยา5ฉุ ยา5ณม ยา5ณว ยา5ถ่ ยา5บร ยา5รช ยา5สล ยา5สี ยา5ฬั ยำ5ทว ยี5รา 1ยุ ยุ5คล ยุ5ตก 4ยุภ ยุ5แย ยุ5แห ยู5คล ยู5ถิ ยู5ฟ่ ยู5ยิ ยู5ริ ยู5ไน ย1เ ย1แ ย1โ ย์5กล ย์5ถ่ ย์5มน ย์5หน 2รก รก5ซอ รก5ซ้ ร1กร รก5รา รก5ร้ รค5พว รง5พย รง5รอ รจ5ถร ร1ช ร4ชก ร4ชช ร4ชน ร4ชย รณ5คด รณ5ตร รณ5ถั รณ5พฤ รณ5สถ ร5ณาญ รณู5ป 4รณ์ ร1ด ร4ดป ร4ดแ ร4ดโ ร4ดไ รด5ไอ รถ1 รถ5พย ร1ท ร4ทฤ รท5ฤด ร4ท4ว รท5วิ รธ5ขึ รธ5สร รธ5เก รน5ทุ 4รนา ร1บ ร4บค ร4บถ รบ5ถ้ ร4บม ร4บไ รบ5ไก ร1ป ร4ปณ ร5พชา ร5พ5ชิ รพ5ทิ ร1ภ ร4ภย รม5รอ รมาว5 รม4เห ร4ยั รร4ก รร5คา รร5จถ รร5จว รร5ณึ รร5ถา รร5ยง รร5ยเ รร3ล รร5หา รร5แท รร5แส รร5ไก รร5ไต รศ5นี รษ5ฐิ รษ5ตร ร1ส ร4สก ร4สช ร4สเ ร4ส4โ ร3หิ ระ1 ระ5สา ระ5หก 5รังส 3รัฐ 1รัต รา5กฏ รา5กฤ รา5กว 1ราช รา5ชู รา5ดร รา5ดว รา5ดู รา5ม่ รา5วณ รา5สง รา2ห รา5หุ รำ5งั รำ5จว ริ5กอ ริ5ตร ริ5ทึ 4ริพ ริ5มน 4ริยจ 4ริยย 4ริร ริ5แล 4ริ่ รี5คู รี5ฑา รี5ดู รี5ตร รี5ตอ รี5รั รี5รา รี5ริ รี5ลั รี5ลิ รี5ล่ รี5สอ รี5สะ รุ5กว รุ5ขร รุ5คร รุ5ทว รุ5ธิ รุ5มุ รุ5วน 1รู รู5ที รู5นี รู5บิ รูป5ก รู5ปิ รู5มา รู5มู รู5หร 2ร1เ ร1โ ร่5กะ ร่5ตร ร่5ร่ ร่5หล ร์5กอ ร์5กี ร์5คั ร์5ดิ ร์5ติ ร์5ตู ร์5ทิ ร์5ฟอ ร์5ฟู ร์5ลี ร์5วอ ฤ4ดา ฤป4เ ฤษ5ฎี ฤห5บด ล5กนะ ลก5ลา ลก5วั ล3กอ ล4กัย ลข5คณ ลข5หม ลชี4 ลด5ระ ลด5ลิ ล4ดา ล1ต ล4ตฟ ลต5ฟอ ลบ5ตะ ลบ5มุ ลบ5ล้ ลบ5ไส ลป5ตอ ลม5ค้ ลม5งว ล3มอ 2ลย ล1ล ล3วี ลว5ไห ลส5ไต ลห5กุ ลอก5ล ลอ5จี ลอ5สร ละ5ผล 1ลักษ ลา5กล ลา5นี ลา5บร ลา5ป๋ ลา5พอ 3ลาร ลา5รอ ลา5ร้ ลา5ฤก ลา5ส้ ลิ5กอ ลิ5ก่ ลิ5จู ลิ5ตอ ลิ5นอ ลิ5น่ ลิ5ฟอ ลิ5มู ลี5ตะ 3ลีน ลี5ผล ลี5ลา ลี5วู ลุก5ร ลุก5ล ลุ5ล่ ลูก1 ลู5ซี ลู5ที ลู3มิ ลู5ลอ ลู5ออ ลู5แบ 2ล1เ 2ล1แ ล1โ ล่5ติ ล่5ที ล่5หล ล่5ออ ล้5โพ 2ล์ ล์5สต ว3กร วก5ว่ ว5การ ว1ค 1วงศ วจ5ตร วจ5สอ วช5นี วด5ถ่ วด5มว วด5ยิ วด5ระ วด5ลา วด5ล้ วด5อ้ ว1ต ว4ตฉ วน5ถี วน5ท้ วน5ผส วน5รว วน5ร่ วน5อิ วน5อุ วบ5ยอ วบ5รว วบ5รั วบ5ฮา ว1ป ว1พ วม5รอ ว3มู วย5ก้ วย5จี วย5ริ วย5รื วย5ล้ วย5ไท วย5ไม วร5ธิ วร5มณ วร5มห ว4รย วรร4 3วรรณ ว4ร์ วล5ระ วส5ปอ ว1ห วอ5ชิ 1วั วัน3 วันต5 วันท4 1วา วา5ดะ วา4ต วา5ตก วา5ติ วา5นร วา5นึ วา5บร วา5มน วา5รณ วา5สนะ วา4ห วา5หน วา5หิ 1วิ วิ5กล วิ5กส วิ5คห วิ5จุ วิ5ดี วิ5ตก วิ5ตร วิ5ตี วิ5ถี 3วิท วิ5ทิ วิ5ธุ วิ5ธู วิ5ปก วิ5ปฏ วิ5ปล วิ5ปว วิภู5 วิ5มล วิ5รง วิ5วร วิ5ศร วิ5ศุ วิ5ษุ วิ5สร วิ5สฤ วิเล5 วี5คู วี5ชน วี5ดิ 1วุ ว1เ ว1แ ว1โ ว่5ห้ ว้5ชื ว้5ทุ ว้5ลา ว์5ลิ ศ1จ ศต5วร ศน5อุ ศพิ4 3ศรี ศษ5ซ้ ศษ5วร ศษ5เก ศษ5เห 1ศั ศัก5ร 1ศา2 ศา5กา ศา5ขบ ศา5นุ ศา5ภิ ศา5รย ศา5รั ศา5ริ ศา5ลา 1ศิ ศิ5รพ ศิ5รว ศิ5ศี 1ศึ ศุ5กล ศู5ลิ ศเจ5ร ษ3ฎา ษฐ5ภค ษ5มณี ษ4มา 1ษั 1ษา ษา5คเ 1ษิ ษ์5พย สก5ลิ สก5ลึ สก5วั สก5วา ส4กา 4ส4กุ สข5บุ สง5ขล ส1ซ สด5ชื ส4ดุ ส5ดุภ ส4ตท สต5ทิ ส3ตรา 2สต์ สถ5วี 4สถ์ สน5ธย สน5ธิ ส5นียะ ส4นุ สนูป5 ส4ปา ส2ม สม5คว สม5ดุ 3สมบ สม5ผส สม5ผุ สม5ผเ สม5ยอ สม5ฤด สม5ฤต สม5หว ส5มัท ส5มัน สมุ4 สรร5ช สร5ลอ สล5บร สว4ก สว5ยม สว5ริ ส4วา 4สวิ ส1ส สห5กร สห5กา สห5ชา สห5ธร สห5ปร สห5พั สห5ภา สห5รา สห5ศึ สอ5พล สอ5พอ สะ5ใภ 1สั สัญประ5 สัน3ถ สัม3 1สา สา5คเ 4สาธ สา5นึ สา5มน สา5วพ สำ5ออ สำ5โร 1สิ สิ5ถิ สี5ข้ สี5ชอ สี5ดว สี5ตล สี5ตโ สี5ถ่ สี5ผึ สี5ฝุ สี5ละ สี5ลั สี5วล 1สุ สุ5กร สุ5กำ สุ5กี สุ5ขิ สุ5ขุ สุ5คต สุ5คร สุ5นี สุ5บร สุ5ปร สุ5มน สุ5สง สุ5ไห 2สุ์ 1สู ส1เ ส4เฟ ส1โ ส4โค 3ส่ว ส่5ไค ส้5กร ส้5ติ ส้5ไก 2ส์ ส์5หย ห2 2ห1ก หก5ระ หก5ล้ 5หการ หง4ส หง5สา หฤ5หร หฤ5โห หล5สะ หอ5คอ หอ5สม 1หั หา5กฐ หา5บพ หา5ปณ หา5พร หา5รื หา5ฤก หา5วร หิ5รก หิ5ศว หุ5คู หู5กร หู5กว หู5หน ห้5ท่ ห้5ท้ ห้5ร้ 2ห์ ห์5กร ห์5สน ฬว5รา ฬห5บู 1ฬา ฬา5มณ ฬา5รึ อก5ซอ อก5ถล อก5รณ อก5รี อก5รู อก5ร่ อก5ฤท อก5ลว อก5ลอ อก5ลา อก5ล่ อก5ว่ อก5ใบ อค5ที อฆ5สง อง4คม อง5ถิ อง5บร อง5ฟอ อง5ฟุ อง5ระ อง5อุ อง5อ้ อด5ช่ อด5ถอ อด5น่ อด5ฝา อด5ยอ อด5รั อด5อย อด5ออ อด5อุ อด5อ้ อ3ดิ อต5ดอ อต5ด็ อต5สว อต5ไว อ1ท อ4ทค อท5คอ อน5ง้ อน5จอ อน5ทำ อน5ผั อน5ฝู อน5ย้ อ4นา อ4นุ1 อบ5ช้ อบ5ถา อบ5บี อบ3อ อบ5ไล อป5คอ อป5ติ อป5พร อป5พล อป4ร อป5วา อป5โล อพ5ริ อฟ5ฟี อฟ5ริ อฟ5โร อฟ5ไล อ4ภั อม5คล อม5ค้ อม5ฎอ อม5ดอ อม5ถอ อม5ฟอ อม5ยิ อม5รา อม5ร่ อม5ฤต อม5หล อม5หว อม5ห้ อ5มอน อย5กอ อย5ก๋ อย5นว อย5ร่ อย5ร้ อย5อิ อ4ยา อย5ได อร5มน อ3รอ อ1รั อ3รา อ1ริ อ1รี อ3ร้ อร์1 อล5จี อล5นี อล5ฟ่ อล5หม อ3ลั อ1ลิ อว5รุ อศ5กร อศ5คร อษ5ฐช อษ5ฐภ อส5กา อส5ติ อส5ตู อส5นี อส5พล อส5ฟอ อส5มิ อส5เฟ อส5แอ อส5ไพ อ1ห 3ออน ออ5อว อะ5ธี อะ5ฮั 1อั 1อา อา5ค5เ อา5ฏา อา5ณั อา5ดุ อา5ดู อา2ต อา5ถร อา5นน อา5ปณ อา5มล อา5ย5ต อา5รด อา5รต อา5รบ อา3รย อา5ลป อา5วร อา5วี อา5สว อำ5ยว อำ5อว อิ5ชย อิ5ดะ อิ5ระ อิ5ศว อี5คิ อี5จู อี5ซู อี5ยิ อี5รุ อี5ลุ อี5ศว อี5หร อุ5กฤ อุ5กล อุ5คร อุ5ดม อุ5ดร อุ5ด้ อุ3ตรา อุ5ตุ อุ5ทร อุ5ทิ อุ5ทุ อุ5ธั อุ5บล อุ5บ๊ อุ5มง อุ5รพ อุ5ลก อุ5แว อู5คู อู5มา อู5รา อู5ลา อ1เ อเป5ร อเสก5 อเส5ข อเห5ต อ1แ อ1โ อ1ไ 3อ่อ อ่5อว อ่5อ่ อ่5โถ อ้5อว อ้5โถ อ้5โล ฮก5ฮา ฮก5ฮื ฮช5แท ฮน5รี ฮฟ5วี ฮล5ดิ 3ฮอล ฮา5นอ ฮา5ป่ ฮา5ร่ ฮิ5บร ฮี5บร 3ฮื้ ฮู5ลา ฮู5ล่ ฮ1เ ฮ1โ ฮ่5กึ ะ1ก ะ1ข ะ1ค ะ1ง ะ1จ ะ1ฉ ะ1ช ะ1ซ ะ1ด ะ1ต ะตะ4 ะ1ท ะ1น ะ1บ ะ1ป ะผี4 ะ1พ ะ1ม ะ1ย ะ1ร ะ1ล ะ1ว ะ1ส ะ1ห ะ1อ ะ1เ ะ1แ ะ1โ ะ1ไ ั2 ัก5ง่ ัก5ซ้ ัก5ตบ ัก5ผ่ ัก5ฝ่ ัก5ยอ ัก5ยิ ัก5รั ัก5ร้ ัก3ล ัก5วิ ัก5ษร ัก5ษอ ัก5อิ ัก5อี ัก5อ่ ัก5ใค ัก5ใฝ ัค5ฆิ ัค5ซี ัค5สถ ัง5ถึ ัง5ศุ ัง4ส5ว ัง5อว ัง5อุ ัง5ฮี ัจ5กล ัจ5ญะ ัจ5ถร ัจ5นึ ัจ5โจ ัช5ฎา ัช5นี ัช5พย ัช5พื ัช5ริ ัช5สก ัช5สม ัช5แพ ัช5โญ ัช5โย ัญ1 ัฏ5ทุ ัฏ5สง ัฐ5ทิ ัฐ5บร ัฐ5สภ ัฐ5เค ัณ5ฏก ัณ3ฐ ัณ5ยก ัณ5เฑ ัณ5โร ัด1 ัด5รู ัต5ดึ ัต5ถล ัต5ถั ัต5ถิ ัต5มณ ัต5มห ัต5รา ัต5รี ัต5ฤก ัต5ลั ัต3ส ัต5หล ัต5หี ัท5คี ัท5ทว ัท5ธน ัท5ธิ ัท5รา ัท5ลี ัท5ลุ ัธ5ยม ัน5ฉ่ ัน2ต ัน5ตภ ัน5ตะ ัน5ตั ัน5ตา ัน5ถธ ัน5ทึ ัน5ทุ ัน4ธ ัน5ธา ัน5ธิ ัน5ผว ัน5ฝร ัน5ฝ่ ัน5ยะ ัน5ย่ ับ1 ัป5คั ัป5ผา ัป4ร ัป5ลา ัป5หง ัป5โป ัป5โห ัพ5ยอ ัพ5ยา ัพ5โพ ัพ5โห ัฟ5ริ ัม4ช ัม5หม ัย5มร ัย5รุ ัล5ดี ัล5ปน ัล5ปพ ัล5ปิ ัล5มุ ัล5ออ ัล5ไซ ัล5ไฟ ัว1 ัศ5นี ัศ5มี ัศ5เจ ัศ5ไน ัส1 ัส5กา ัส5มั ัส5มิ ัส5วา าก5ถา าก5ฝร าก5ฝั า1กร า4ก5รุ า3กอ าก5ฮอ า3กี า1ข า4ขบ าข5บู า1ค า4คจ า4คท า4คบ า4คป าค5ปร า4คพ าค5พื า4คภ า5ครี าง5บำ าง5ฝี าง5ออ าง5อิ า1จ า4จญ า4จห าจ5หา า4จอ า4จเ าช5กร าช5คร าช5คฤ าช5ทิ า5ชนะ าช5นี าช5ปะ าช5ลั าช5วโ าช5สก าช5สี าช5อง า1ชิ า3ชี าช5โอ า1ซ าญ5รอ า5ฏกะ าฏ5ดน า5ฏลิ าฏ5ลี า3ฏิ าฐ5กถ าณ5คด าณ5สถ าด5ผว า3ดอ า3ดิ าด5ไท าด5ไห า1ต า4ตญ า4ตภ าต4ว า1ท า4ทธ า4ทน า5ทนะ าท5บง าท5บร าท5สก าท5หล า1ธ า4ธน า2ธย าธ5ยม าธา1 าน5ญ่ าน5ผู าน5รว าน5รั าน5ฤด าน5อว านุ1 าบ5จ้ าบ5ฉว าบ5ช้ าบ5ซึ าบ4พ าบ5รื าบ5ละ า3บิ าป5สร าป5ส่ าป5แช าพ5ถ่ าพ5ยน าพ5รั าพ5ลว าฟ5ต้ าฟ5ริ า1ภ า4ภป า4ภล าภ5ลอ าม5คิ าม5ง่ าม4น4 าม5นิ าม5สก าม2ห าม5หม าม5หล าม5หา า3มี าย5กล าย5กอ าย5ขว าย5ข้ าย5ชน าย5ดิ าย5ด้ า5ยตน า5ยนธ า5ยนม าย5นอ า5ยนเ าย5บร าย5ผอ าย5ฝั าย5มุ าย5ม่ าย5รุ าย5ร้ าย5ลั าย5ล่ าย5วอ าย5อำ า3ยิ าย5ไห าร5กำ าร3ค า5รณะ าร5ณู าร5ตร า5รทะ าร5ธุ าร5ผจ าร5พร า5รภย า1รม าร5รา าร5ละ าร5วด าร5ว่ าร5หน า1ระ า1รั า1รา า1ริ า5ริก า5ริยะ า1รี า1รุ า1ล า4ลก า4ลค า4ลจ าล5ฎี า4ลด าล5ดี าล5ทห า4ลป าล5ปก าล5พร า4ลว า4ลส าล5อุ า4ลโ าว5ก่ าว5ข้ า3วดี าว5ดึ าว5นี าว5บอ าว5ยอ าว5ยื า5วรณ าว5รภ า5วรร าว5รา า5ว5รี าว5รุ าว5ร้ าว5ฤก า5วอน าศ5นี า3ศร าศ5เล าษ5ดื าษ5ตร าษ5รา าษ5แก าส5กา าส5คอ าส5ด้ าส5ต้ าส5นี าส5ปอ าส5มห า1ห าห3ก าห5มง าฬ5โร า1อ าอนา4 า1ฮ า1เ าเม5ศ า1แ า1โ า1ไ ำ1ก ำ1ค ำท4ว ำ1น ำ1บ ำ1ป ำ1พ ำ1ม ำม5รง ำ1ร ำ1ล ำ1ส ำ1ห ำ1เ ำ1แ ิก5ซี ิก5ถอ ิ1กร ิก5ร้ ิ3กฤ ิก5ล้ ิก5วา ิก5ษุ ิกิ5ส ิ1ข ิ4ขส ิข5สิ ิ1ค ิ4คต ิค5ตอ ิ4คน ิ4คหะ ิฆ5เน ิง5ชี ิง4สต ิง4ห ิง5หา ิง5ห้ ิง5อร ิจ5ศี ิช4น ิช5ลิ ิ3ชิ ิญ5หน ิญ5โญ ิด5ฉิ ิด5ชอ ิด5ชิ ิด5นี ิด5ผน ิด5รอ ิด5ระ ิด5ลั ิด5ออ ิด5อ่ ิต5ซู ิต5ถี ิต5ฟอ ิต5ลด ิต5ลา ิต5วส ิต5สม ิ1ติ ิ3ตุ ิท5คอ ิท5ธั ิท5สน ิ3ธี ิน5งอ ิน5ฟร ิน5ยว ิน5ยอ ิน5ย้ ิน5ระ ิน5ริ ิน5ร้ ิ5นอบ ิน5อิ ิน5ฮุ ินู5ป ิบ5บิ ิบ5ผย ิบ5ยื ิบ5ระ ิบ5รี ิบ5ลั ิบ5ลิ ิบ5ล้ ิป4ก ิป5ทอ ิป5ผล ิ3ปร ิป5สต ิป5สเ ิป5ฮอ ิป5โป ิป5โย ิ1พ ิ4พพ ิ4พโ ิพ5โส ิฟ5ฟอ ิ1ภ ิม5ฝี ิ1มุ ิย5มิ ิร5วด ิ1รั ิ1รา ิ1ริ ิ1รุ ิล5ปิ ิ1ลั ิ1ลา ิ1ลิ ิว5ซี ิว5ทร ิว5บิ ิว5ยอ ิว5ยิ ิ3วรร ิว5ริ ิว5ลิ ิว5ลึ ิวา5ส ิศ5พร ิศ5ร้ ิศ5เล ิศ5แพ ิษ5ณุ ิษ5ตร ิส5กร ิส5กี ิ5สตร ิส5ติ ิส5ต้ ิส5ที ิส5นี ิส5บอ ิส5รา ิส5ริ ิส5ลา ิส5ไซ ิ1ห ิหา4 ิ1อ ิ1เ ิเน4 ิ1โ ิ1ไ ี1ก ี4กต ี4กย ีก5ย่ ีก5ริ ีฆ5สร ีช5คณ ีซ5สถ ีด5ฆ่ ี5ดิย ีต5กว ีต5ปฏ ี1ท ีท4น ีบ5รุ ีบ5ร้ ี1ป ี1พ ี4พจ ี1ม ีย5กถ ีย5รย ีย5รอ ีย5ระ ีย5รั ี5ยวน ีย5ไต ีร5ณั ี3รี ีรี5บ ีล5จุ ี4วั ีวา4 ีษ5มา ีห5นา ี5หน้ ีห5บั ีห5มุ ีห5รา ี3หล ีห5โม ีห5ไส ี1อ ีอ4ร ีอา4 ี1เ ี1แ ี1โ ี1ไ ี่5ก่ ี่5ถ้ ี่5ปุ ี่5ปู ี่3ห ี่5โค ี่5โป ี้5กร ี้5จ้ ี้5ตะ ี้5ฟู ี้5ริ ี้5ลั ี้5ลุ ี๊5กร ี๊5ด๊ ี๊5ต่ ี๋5จ้ ี๋5อ๋ ึก5ซึ ึก5ดำ ึก5ดื ึก5ยื ึก5ระ ึก5ลั ึก5ล้ ึก5ฮั ึด5ถื ึด5ฮั ึน5ทึ ืด5ฮา ือ5กล ือ5กอ ือ5กำ ือ5ข่ ือ5จ้ ือ5ชื ือ5ดำ ือ5ตร ือ5ถื ือ5นำ ือ5ปล ือ5ปื ือ5ป่ ือ5พว ือ5พ่ ือ5ยน ือ5ยา ือ5รื ือ5ลา ือ5ล้ ือ5สอ ือ5สำ ือ5อี ุก5งอ ุก5ฉก ุก5ซ่ ุก5ดิ ุก5ผา ุก5รา ุก5รุ ุก5ละ ุก5ลี ุก5ล้ ุก5อี ุก5ฮื ุข5นา ุข5ปา ุข5ภั ุข5ภา ุข5ลั ุข5ศา ุข5ศึ ุข5เด ุค5ทอ ุ3คน ุง5ถุ ุจ5ลิ ุจ5หน ุญ5จน ุญ5ฤท ุญ5แจ ุฎ5ฐั ุฑ5พ่ ุณ5ค่ ุณ5ฑก ุณ5หญ ุณ5หา ุณ5หิ ุณูป5 ุด5ผา ุด5ผ่ ุด5ลอ ุด5ลุ ุด5อู ุต5กว ุต5ซอ ุต5ตก ุ5ตระ ุ5ตริ ุต5ลุ ุต5ส่ ุ3ทก ุท5ธั ุ5ทริ ุท5ลุ ุท5โธ ุน5ทร ุน5ผล ุน5รอ ุบ5งิ ุบ5บิ ุบ5ผล ุบ5ยิ ุบ5อิ ุป5กร ุป5จา ุป5ถั ุป5ยุ ุป3รา ุ5ปริ ุ4ปส ุป5สง ุป5สร ุป5ฮา ุป5โภ ุป5โล ุพ5พา ุพ5ภิ ุภ5ชล ุภ5เค ุม4น ุม5นุ ุม5รุ ุม5หย ุย5ช่ ุย5ฝ้ ุ1ร ุร5ข่ ุ4รค ุ4รฉ ุ4รช ุ4รท ุ4รธ ุ4รบ ุ4รพ ุ4รภ ุ5รภี ุ4รย ุ4รร ุ4รล ุ4รว ุ4รศ ุ4รส ุ4รอ ุ4รแ ุ4รโ ุล5จอ ุล5ชี ุล5ธิ ุล5มุ ุล5วร ุล5สต ุล5สแ ุ3ลา ุ3ลิ ุศ5เร ุศ5โล ุษ5จี ุษ5ฎี ุษ5ปร ุ4ษย ุษ5รา ุษ5ร้ ุษ5เพ ุส5รา ุ5สละ ุส5ลิ ุส5วา ุ1ห ุห5กล ุห5นา ุ4หย ุห5ยา ุ4หเ ุห5เท ุห5เส ุ4หโ ุห5โย ุ1เ ุ1โ ุ๊5ต๊ ูก5วั ู1ช ูญ5หา ูญ5เป ูญ5เส ูด5บึ ูด5รี ูต5รู ูธ5เร ูบ5ไล ูป4ก ูป5ฌา ูป5ถ่ ูป5ทร ูป5พร ูป5ร่ ูป5แบ ูป5โฉ ูฟ5วี ู2ม ู5มิน ูร5ข่ ูร4ณ ู5รณภ ู5รณม ู5รณะ ู5รณาก ูร4พ ู5รพะ ู5รพา ูร4ม ูล5กร ูล5ค่ ู3ลั ูว5ไน ูส4ว ู1เ ู1โ ู่1 ู้1 ู๊5ตึ ู๋5กร ู๋5จี ู๋5อี เ2 เก5ยู เก5รล เก5วั เก5ศว เก5อิ เค5ซอ เค5มี เค5ศว เจ5ดี เจ5นี เ4จร เจ5ลิ เจ5โต เจ5โร เซ5ทิ เซ5นอ เซ5รุ เซ5แค เด5บิ เด5รั เด5ลา เด5ลิ เด5ลี 2เตช เต5ปุ เต5มี เต5มู เต5ริ เต5ลุ เต5ศว เต5หะ เถ5รา เท5กร เท5คร เท5คว เท5โว เท5โศ เน4ต เน5ติ 4เนย เน5ระ เน5รั เน2ส เน5สา เน5เว เบ5ต้ เบ5บี เบ5ริ เบ5รุ เบ5ลี เป5ตอ เป5สก เป5สล เพ5ชุ เพ5ทุ เพ5สล เพ5โท เพ5ไน เฟ5อี เภ5ตร เภ5ทุ เม5ฆิ เม5ดิ เม5ลอ เม5ล่ เม4ส เม5สุ เร5กอ เร5กะ เร5มอ เร5รว เร5วด เล5กร เล5คอ เล5ดี เล5พอ เล5วร เล5วู เล5หล เล5ฮุ เลิ4 เว5ก้ เว5ทิ เว5ล่ เว5ฬุ เว5ไน เส5ฉว เส5นีย์ เส5รี เส5วก เส5วน เส5แส เห5มั เห5ยง เห5ระ เห5รั เห5ศว เห5ศั เห5สั เฬ5วร เอ5กว เอ5ธิ เอ5ฬก เฮ5ละ เฮ5ลิ แก5วั แค5รอ แค5ริ แค5ลอ แค5ลิ แค5แต แค5แส แซ5ยิ แซ5หว แด5รี แต5แต แน2 แบ4ค แบ5ริ แ4ปร 3แพท แฟ5รี แ4ฟ้ แม2 แม5กา แม5ชี แม5ริ แม5รี แม5เร แม่3 แอ5นะ โก4ฐ โก5ลอ โก5ลา โก5ลิ โก5วา โก5วี โก5ฮา โข5ทั โข5ภิ โข5เภ โข5โล โค5ตม โค5ติ โค5มู โค5ม่ โค5ริ โค5ลอ โค5ลั โค5ลี โค5ล่ โค5ออ โค5อะ โค5แท โค5ไซ โจ5ปก โจ5อี โฉ5เบ โช5ฎึ โช5ดึ โช5ห่ โซ5กร โซ5นี โซ5ยู โซ5ลู โซ5สเ โญ4ช โญ5ปว โด5จี โด5นี โด5รา โด5ลิ โต5กร โต5รอ โต5รา โต5ริ โต5ลิ โต5สเ โต5ไค โท5กร โท5คอ โท5ดอ โท5พล โท5รอ โท5แอ โธ5ทน โธ5ปก โธ5ปิ โธ5วน โธ5เฟ โน5ทุ โน5ปจ โน5รม โบ5ชุ โบ5ซอ โบ5ต้ โบ5รอ โบ5รั โบ5รา โบ5ลิ โบ5ล่ โบ5อิ โบ5ไฮ โป5กส โป5ลิ โป5แต โป5แล โป5โป โป5โล โพ5ทะ โพ5ระ โพ5ลา โพ5ลิ โพ5ลี โพ5หา โพ5แท โพ5ไซ โฟ5กร โฟ5ตอ โฟ5นี โฟ5ลิ โภ5คิ โภ5ไค โม5ฆี โม5ดู โม5ร็ โม5หา โม5ฮั โย5ถิ โร5กะ โร5คิ โร5งั โร5ธนะ โร5พล โร5ฟอ โร5ฟี โร5รา โร5ร่ โร5ล่ โรส4 โร5สเ โร5หน โร5อี โร5ฮิ โร5ฮี โร5แม โร5ไล โล5กร โล5กี โล5จน โล5ปุ โล5มก โล5รา โล5วะ โล5หิ โล5ไม โว5นอ โศ5ธน โศ5ภิ โส5กร โส5ติ โส5ธน โส5ภิ โส5รั โส5ลิ โส5หุ โส5โค โห5ฐา โห5รส โห5ระ โห5รา โห5สิ โห5ฬา โอ5คล โอ5ค็ โอ5ดี โอ5รส โอ5ละ โอ5สถ โอ5อิ 3ใช้ 1ให ไก5ลา ไก5วั ไข5ข้ ไข5คว ไข5มั ไข5สั ไข5สื ไค5ศว ไช5น่ ไช5ศว ไซ5ดอ ไซ5บอ ไซ5บี ไซ5ปร ไซ5รั ไซ5แน ได5ฟุ ได5ฟู ได5ลิ ได5ออ ไต5รี ไท5กร ไท5ฟอ ไท5รอ ไท5แท ไป5ริ ไพ5ชย ไพ5ทอ ไพ5ธอ ไพ5รั ไพ5ริ ไพ5ลิ ไพ5หา ไพ5โร ไพ5โอ ไฟ5แช ไฟ5แน ไภ5ริ ไม5ถิ ไม้1 ไล5บร ไล5บี ไว5รั ไว5อะ ไห5รณ ไห5ศว ไห5หม ไห5หล ไอ5กร ไอ5คิ ไอ5ซี ไอ5ดอ ไอ5ติ ไอ5พอ ไอ5พ็ ไอ5ศว ไอ5ศุ ไอ5ศู ไฮ1 ็ก5ซี ็จ5ขบ ็จ5สร ็ด5ลอ ็ด5อร ็ด5อึ ็น5ฉ่ ็น5รอ ็น5วู ็น5อย ็น5อ้ ็บ5ด้ ็ป5ท็ ็ม5หม ่ก5ลั ่1ค ่ง5ริ ่ง5อร ่ง5อำ ่ง5อ่ ่4ฉี ่น5ง่ ่น5ฉ่ ่น5ทะ ่น5มื ่4นย ่น5ยน ่น5ย่ ่น5รม ่ม1 ่ม5พว ่ย5กะ ่ย5ฉุ ่ย5รา ่ย5ร่ ่ว5ช้ ่ว5ถึ ่ว5ยว ่ว5ฮ้ ่ว5ไห ่อ5กร ่อ5กว ่อ5กะ ่อ5กี ่อ5ก้ ่อ5ข่ ่อ5ตร ่อ5ตะ ่อ5ต้ ่อ5ถื ่อ5บื ่อ5ผส ่อ5มว ่อ5ม่ ่อย3 ่อ5ยอ ่อ5ย่ ่อ5ร่ ่อ3ล ่อ5ว่ ่อ5สร ่อ5ฮั ่อ5ฮ่ ่า5กล ่า5ช้ ่า5ดง ่า5ด้ ่า5ฝื ่า5พร ่า5มง ่า5รึ ่า5ร้ ่าว3 ่ำ5ชอ ่ำ5ช้ ่ำ5ต้ ่ำ5ต๊ ่ำ5ไห ่1เ ่1แ ้ก5อ้ ้ง5ถ่ ้ง5ฝุ ้น5งู ้น5ฉบ ้น5ฉ่ ้น5ทะ ้น5ทุ ้น5ท้ ้น5รุ ้น5ร่ ้ม5คล ้ม5งว ้ม5ฉุ ้ม5น้ ้ม5ยิ ้ม5ละ ้ม5ลุ ้ม5อล ้ย5กล ้ย5งช ้ย5ล่ ้ย5อ้ ้ย5ใบ ้ว5รอ ้1ห ้อ5กร ้อ5กล ้อ5คร ้อ5คู ้อ5งอ ้อ5ฉี ้อ5ดึ ้อ5ด้ ้อ5ต๊ ้อ5ถอ ้อน3 ้อ5ผ้ ้อ5ฝั ้อ5ฟื ้อ5มู ้อ5ระ ้อ5ร่ ้อ5อึ ้อ5ฮื ้า5จอ ้า5ชื ้า5ชู ้า5ช่ ้า5ช้ ้า5ดี ้า5ถิ ้า5ถึ ้า5บ่ ้า5บ้ ้า5บ๋ ้า5ปี ้า5ผา ้า5ฝร ้า3พ ้า5มุ ้า5ว่ ้า5สม ้า5สร ้า5สล ้ำ1 ้1เ ้1แ ๊ก5ซอ ๊ก5ริ ๊ก5ลุ ๊ก5ฮว ๊ง5บ๊ ๊ป5ซี ๊ย5ก่ ๋ย5อิ ๋อ5ด๋ ์ค5สเ ์ค5แล ์ต5ไท ์4ทเ ์ท5ไท ์1น ์1บ ์1พ ์1ร ์1เ ์1แ ์1โ .ก6 .ข6 .ฃ6 .ค6 .ฅ6 .ฆ6 .ง6 .จ6 .ฉ6 .ช6 .ซ6 .ฌ6 .ญ6 .ฎ6 .ฏ6 .ฐ6 .ฑ6 .ฒ6 .ณ6 .ด6 .ต6 .ถ6 .ท6 .ธ6 .น6 .บ6 .ป6 .ผ6 .ฝ6 .พ6 .ฟ6 .ภ6 .ม6 .ย6 .ร6 .ฤ6 .ล6 .ฦ6 .ว6 .ศ6 .ษ6 .ส6 .ห6 .ฬ6 .อ6 .ฮ6 6ก. 6ข. 6ฃ. 6ค. 6ฅ. 6ฆ. 6ง. 6จ. 6ฉ. 6ช. 6ซ. 6ฌ. 6ญ. 6ฎ. 6ฏ. 6ฐ. 6ฑ. 6ฒ. 6ณ. 6ด. 6ต. 6ถ. 6ท. 6ธ. 6น. 6บ. 6ป. 6ผ. 6ฝ. 6พ. 6ฟ. 6ภ. 6ม. 6ย. 6ร. 6ล. 6ว. 6ศ. 6ษ. 6ส. 6ห. 6ฬ. 6อ. 6ฮ. 6ก์. 6ข์. 6ฃ์. 6ค์. 6ฅ์. 6ฆ์. 6ง์. 6จ์. 6ฉ์. 6ช์. 6ซ์. 6ฌ์. 6ญ์. 6ฎ์. 6ฏ์. 6ฐ์. 6ฑ์. 6ฒ์. 6ณ์. 6ด์. 6ต์. 6ถ์. 6ท์. 6ธ์. 6น์. 6บ์. 6ป์. 6ผ์. 6ฝ์. 6พ์. 6ฟ์. 6ภ์. 6ม์. 6ย์. 6ร์. 6ล์. 6ว์. 6ศ์. 6ษ์. 6ส์. 6ห์. 6ฬ์. 6อ์. 6ฮ์. 6กิ์. 6ขิ์. 6ฃิ์. 6คิ์. 6ฅิ์. 6ฆิ์. 6งิ์. 6จิ์. 6ฉิ์. 6ชิ์. 6ซิ์. 6ฌิ์. 6ญิ์. 6ฎิ์. 6ฏิ์. 6ฐิ์. 6ฑิ์. 6ฒิ์. 6ณิ์. 6ดิ์. 6ติ์. 6ถิ์. 6ทิ์. 6ธิ์. 6นิ์. 6บิ์. 6ปิ์. 6ผิ์. 6ฝิ์. 6พิ์. 6ฟิ์. 6ภิ์. 6มิ์. 6ยิ์. 6ริ์. 6ลิ์. 6วิ์. 6ศิ์. 6ษิ์. 6สิ์. 6หิ์. 6ฬิ์. 6อิ์. 6ฮิ์. 6กุ์. 6ขุ์. 6ฃุ์. 6คุ์. 6ฅุ์. 6ฆุ์. 6งุ์. 6จุ์. 6ฉุ์. 6ชุ์. 6ซุ์. 6ฌุ์. 6ญุ์. 6ฎุ์. 6ฏุ์. 6ฐุ์. 6ฑุ์. 6ฒุ์. 6ณุ์. 6ดุ์. 6ตุ์. 6ถุ์. 6ทุ์. 6ธุ์. 6นุ์. 6บุ์. 6ปุ์. 6ผุ์. 6ฝุ์. 6พุ์. 6ฟุ์. 6ภุ์. 6มุ์. 6ยุ์. 6รุ์. 6ลุ์. 6วุ์. 6ศุ์. 6ษุ์. 6สุ์. 6หุ์. 6ฬุ์. 6อุ์. 6ฮุ์. 6ะ 6า 6ๅ 6ำ7 6ิ 6ี 6ึ 6ื 6ุ 6ู แ6 โ6 5ไ6 7ใ6 6็ 6่ 6้ 6๊ 6๋ 6์ 6ํ 6ฺ 6๎ เ6ข เ6ฃ เ6ค เ6ฅ เ6ฆ เ6ง เ6จ เ6ฉ เ6ช เ6ซ เ6ฌ เ6ญ เ6ฎ เ6ฏ เ6ฐ เ6ฑ เ6ฒ เ6ณ เ6ด เ6ต เ6ถ เ6ท เ6ธ เ6น เ6บ เ6ป 7เ6ผ เ6ฝ เ6พ เ6ฟ เ6ภ เ6ม เ6ย เ6ร เ6ล เ6ว เ6ศ เ6ษ เ6ส เ6ห เ6ฬ เ6อ เ6ฮ ช6วา. ช6ไ ธ6ไน ม6ไห ส6ไต เลส7ไต ส6ไน ส6ไบ ส6ไป ส6ไล บ6ทคว ม6วก ม6วน ม6วด ม7วดี ม6วย ะม6วง ล7ชน ัต5ถุ ัต6ถุ์ 6ตร. ธา6ตุ. บุ6ตร. ค6รู ฮิบ6รู ฮีบ6รู ส6ภา ส7ภาร เส7ภา โส7ภา ผ6วา น6คร. .เห6ยง เปี่6 เขี้6 ม6ณี คาม7ณี .รม7ณี .รัม7ณี หม7ณี ง6วด ง6วน วัง7วน ง6วย มง6วง อย6อด พ6ญา จุ6รณ ฤ6ชา .ฤ6ทัย พรร6ดิ สวา6ดิ อ6ริ. จน6ที. ธค6ยา นิม6นา ย์ม6นา า7ณะ ิ7ณะ ุ7ณะ ณ7ณะ ก7ณะ ท7ณะ ล7ณะ ุษ7ณะ ฤษ7ณะ รป7ณะ หม7ณะ สม7ณะ ลว7ณะ รว7ณะ ร5ณะ ณร6สี ก6นะ ยก7นะ ค7นะ ย7นะ ภว7นะ มท7นะ รต7นะ ลว7นะ วจ7นะ วท7นะ วส7นะ ศม7นะ ภช7นะ ไช7นะ าลป7นะ รรธ7นะ สธ5นะ โสธ6นะ สว5นะ เสว6นะ สาว7นะ ัจ7นะ ัช7นะ ัฏ7นะ ัฒ7นะ ัต7นะ ัท7นะ ัป7นะ ัส7นะ ุจ7นะ อาส7นะ ุ7นะ 5ผี 7จำ 5งำ ห6งำ น7รำ ย7รำ ร7รำ โค7รำ ไพ7รำ น7ยำ ม7ยำ 5งง. ห6งง น7งก 5ชน. เ6ชน โ6ชน 5กร. ั6กร า7นะ ถ7ระ า7ยก. า7ยน. า7ฐี า7นี า7วี ป5โ ป6โย ป6โภ วิป7โย อุป7โภ ศ7นะ รร7มะ ต5ถี ุต6ถี 5บท. ส6บท 5บถ. ข6บถ ส6บถ 7ฟู 7ษุ 5ตะ. ค6ตะ ร6ตะ สร7ตะ มิ7ผ า7กิ า7กล ิ7กล. ์7กล 5นำ ห6นำ รี7ผ 7ณุ 5นี. ห6นี ฉ6นี าร6นี วีช6นี สส6นี มท6นี รม6นี น7ยิ ิ5ลี ุ5ลี า7ลี โม7ลี ท7ลี ร7ลี ก7ยะ ค7ยะ ป7ยะ ท7ยะ ธ7ยะ น7ยะ ษ7ยะ า7ยะ ิ7ยะ คี7ยะ ฆี7ยะ ณี7ยะ นี7ยะ รี5ยะ เปรี6ยะ มโห5 ิ7รี ู7รี หา7รี ม7รี. น5รี. เต7รี. ช7รี. ถ7รี ภ7รี ภม7รี โม7รี ภุม7ร พ7รี. เว7รี 5ผล 5ดล. 5รส. ก6รส จ6รส โค6รส ท6รส พ6รส ด6รส 5คน. ณ7หา ฤๅ5 ฤา5 .ยี่7 า7วะ เท7พี เท7วี บรร7จ บรร7ถ บรร7พต 5ทก. 5ดร. น7ทร. า7ทร. โค7ทร. โล7ทร. โส7ทร. 7อู. 5พล. ไพร่7 5ศก. อัฐ5 อัฐ6ม อัฐ7มี ี7วี ู7วี ถ7วี. ส7วี. ฏ7วี. น7ตี ร7ตี อ7ตี า7ตี ิ7ตี ู7ตี า7สี ณ7สี ห7สี เว7สี ู7สี ิ7สี ก7สี โบ7ลา ู7ลา อจ7ลา เว7ลา บิว7ลา มข7ลา เอ7ลา ี7ลา โร7ลา โอ7ลา โซ7ลา ิ7กะ ุ7กะ อ7กะ นว7กะ ิณ7กะ เภ7กะ ัย7กะ ิย7กะ รธ7กะ ัฏ7กะ ัฒ7กะ ิช7กะ ศต7กะ มล7กะ 7ทุ. โซ6ร ธ6นู ัส7ดุ. ร7คต ดง7คต 5กง. เ6กง 7ฎก ณ7มี ว7มี ศ7มี ู7มี ี7ติ รุ7ติ สุ7ติ ฮ7ติ อร7ติ วีส7ติ ติงส7ติ คุป7ติ มุต6ติ ภัต6ติ ก7ดี ต7ดี พ7ดี ม7ดี ย7ดี ศ7ดี อ5ดี า7ดี ี7ดี ุ7ดี ุว7ดี ดิบ7ดี นัก7 กุณ5 กุณ6ฑ์ 7ซี. 5ที. จน6ที ี7รา ู7รา ์7รา ิต7รา ม7รา ย7รา .มก7รา รบ7รา ลิก7รา เห7รา. 7กฎ. 7กฏ. 5หะ ค6หะ นิค7หะ เค7หะ ท6หะ เท7หะ ู7หา ฬ7หา ค7หา เน7หา ่7หา 5มะ ร6มะ ห6มะ ต6มะ 5หู 5ดำ ส6ดำ 7คำ 5สะ ว6สะ 5ฐะ ส6ฐะ 7ธะ 5พี. ร6พี ทร7พี ปฐ7วี ิ7ดา ษ7บ ษ7ป ิ7ระ ี7ระ ู7ระ ช5ระ ิต7ระ ทห7ระ ท7ระ. ุก5ระ. สว7ระ ัส7ระ ิส7ระ เป7ระ อ7ยา. เก7ยา รร7ยา สา7วก ิ7ธิ ุท7ธิ. ิท5ธิ. .สิท6ธิ. บุริมสิท6ธิ. ไกรสิท6ธิ. ป7ธิ ขัดสมา6ธิ พยา6ธิ. 5ษี. ด6นู ิ7วะ ี7วะ ุ7วะ ี7วก ย7วะ เท7วะ ไท7วะ ัท7วะ าช7วะ ไศ7วะ 7ถะ 7ษะ 5พร. 5ผง 5ธี า7ชะ ิ7ชะ ร5ชะ ส7ชะ โอ7ชะ 5ฆะ 5ฟะ า7ฟี ิ7ถี ร7ถี 5ฮา 5ญี 5ผา 5หิ. สิน7ธพ สิน7ธุ. สิน7ธู 5ชู 5ศะ ิ7ละ ุ7ละ ู7ละ ย7ละ ด7ละ .วส7ละ อเจ7ล เต7ละ ่7ละ น7ทะ ท7ทะ ส7ทะ น7ตุ. รร6ตุ มา7ตฤ ิ7รพ า7รพ. ไก7รพ 5ศุ. า7ถา า7สพ พ7สพ ุ7ขี 7สอ. า7ดะ 5บะ. 5ยี. ห6ยี 5กี. 5หก. ง7อร. ม7อร. ี7วร ส7วร. พู7นท 5จร. โ6จร. 7ศพ. โป7ลี 7ภพ. 7นพ. 7ณพ. า7รก. ทก7รก ย7รก. ยว7รก. 5มล. ุ5บล. โล7บล. 5ชล. 5ชก. 7โพ 5ณู 7ปี. า7บี. 5ฏะ. า7ฬี 5ปะ. ฉ6ปะ ส6ปะ ู7ลู 5ตู. 5ยู. 7ฆี. ิ7จี ี7จี ุ7จี ู7จี เว7จี 5ศี. 5มน. 5ยอ. ผ6ยอ. 5สง. 7สร. 5ดก. ส6ดก 7โก. ก7ฝ า7มก. 5ซอ า7ขะ ู7ขะ ส5ขะ ร7ษา 5ภะ ศ7ภ ิ7ลก ุ7ฎี ศา5ข 5สา. ั6สา 7ซู 5ษก. ษ7ฐี 5ดม. ส6ดม ด7ลม. ส7ลม. ว7ลม. ี7ลม. 5ศล. นิ7ยต 7งู 5จะ. า7สก. โป7สก 5ยศ. 5ธก. 5กบ. 7คู. ส5มา. 5แล. 5พก. โส7ภ รร6ดิ. า7วก. น7นร. 5จอ. 5จบ. 5คบ. 5ฉล. ม7รม อบ7รม ิ7รม. ี7รม. 5ซน. 5ดอ. 5กิ. ซู7ซุ ซู7ฮก 5บส. น7รน. ตก7ลง ม7ตน ตัว7ตน ี7วง ศ7วง. แตร7วง แวด7วง า7ฑู 5หด. อบ7นบ นา7คร. ี7ฑา ู7ดู า7รภ. า7ฝ ล7รบ. ว7รบ. อ7รบ. า7รณ. น7ยง ม7ยง ุ7ยง ิ7ยง ิ7ยน หา7พน า7งิ ช7รถ. น7รถ. ส7รถ. ัน7ธร. มณ7ฑก มณ7โฑ มร7กต มร7ฑป ยอด7อก โล่ง7อก ยืด7อก ห7ห 5ทด. ว7นม. ทพ7นม. โค7นม ษ7ฎร. ิ7ปุ ิ7ปู ี7รอ. ย7ลำ อ7ลำ ้7ลำ น7ทม. ป7ทม. วก7วน อล7วน ิ7จล. ช7ญะ ี7ข ศีล7 5ธม. สม7รด สัก7วา สัป7ด สัป7ท า7สม. อ7สม. า7นล. ี7รุ ู7รุ เน7รุ ง7หล สีห7นุ 5ภร. 5จด. บ7ยก. ดิ7ศร ร7ศร อพ7ยพ ร7ชร. รส7กา ลส7กา อาจ7อง ี7มู อึง7อล ุ7ชุ ุ7สภ. เก7ชา เก7ศา ช7ตก. บ7ตก. เข7ฬะ ห7ณี อ7ปน. ย7ชม. เบื้อง7 5คะ ง7ออ. อ7ออ. เรือ7ธ เรือ7บ เลี้ยว7 5กก. เ6กก อ7ขอ. า7กอ. แด7วู บ7ยล. โฉ7เก โด7มร โต7มร 7โผ โท7โส ้7ปด. 7คี. โย7นก. โส7มม 7ฬส. ต7ถิ 7โฮ ใจ7 5ฟง ไช7โย 5พต. กรร7กศ ล7บก. ศ7ยป. า7นน. ุ7ฎา ู7ฏา า7มอ. ท7โท ุ7ทส จ่า7ร ฬ7หี า7ฒะ ธต7รฐ ท7คล. ต7ถร. ิ7ฐิ ป7ผะ พฤ7ษภ. ิ7ธุ า7ฬก. ห7สิ ฏ7ฏิ. ษ7ฏิ. ศิษ7ฎิ ษ7ฏี 5ษส. ิ7ปิ ู7ริ. ฑ7ฑุ ษ7ฏุ า7ตา ว7ตก ง7ตก เก6ตุ. ส7ตุ ลิ7บง 7อุ. ิศ7รา ษ7อร ช6รา. ด7ชะ โบ7ริ ป6ทา. ล7มี ม7คด ี7สป ร7ละ ทส7ลา ส7โซ ซ7ฟี", ["lefthyphenmin"]=1, - ["length"]=53269, - ["n"]=4289, + ["length"]=53939, + ["n"]=4342, ["righthyphenmax"]=1, }, ["version"]="1.001", diff --git a/tex/context/sample/common/aesop-de.tex b/tex/context/sample/common/aesop-de.tex deleted file mode 100644 index 80a41f295..000000000 --- a/tex/context/sample/common/aesop-de.tex +++ /dev/null @@ -1,25 +0,0 @@ -% German example file from Aesop - -Der L\"owe und die M\"ucke - -Eine M\"ucke forderte mit den \"uberm\"utigsten Worten -einen L\"owen zum Zweikampf heraus: \quotation {Ich -f\"urchte dich nicht, du gro\SS es Ungeheuer}, rief sie ihm -zu, \quotation {weil du gar keine Vorz\"uge vor mir hast; -oder nenne sie mir, wenn du solche zu haben glaubst; etwa -die, da\SS\ du deinen Raub mit Krallen zerrei\SS est und -mit Z\"ahnen zermalmest? Jedes andere feige Tier, wenn es -mit einem Tapfern k\"ampft, tut dasselbe, es bei\SS t und -kratzt. Du sollst aber empfinden, da\SS\ ich st\"arker bin -als du!} Mit diesen Worten flog sie in eines seiner -Nasenl\"ocher und stach ihn so sehr, da\SS\ er sich vor -Schmerz selbst zerfleischte und sich f\"ur \"uberwunden -erkl\"arte. - -Stolz auf diesen Sieg flog die M\"ucke davon, um ihn aller -Welt auszuposaunen, \"ubersah aber das Gewebe einer Spinne -und verfing sich in demselben. Gierig umarmte die Spinne -sie und sog ihr das Heldenblut aus. Sterbend empfand die -M\"ucke ihre Nichtigkeit, indem sie, die Besiegerin des -L\"owen, einem so ver\"achtlichen Tiere, einer Spinne, -erliegen mu\SS te. diff --git a/tex/context/sample/common/cervantes-es.tex b/tex/context/sample/common/cervantes-es.tex deleted file mode 100644 index 153797023..000000000 --- a/tex/context/sample/common/cervantes-es.tex +++ /dev/null @@ -1,6 +0,0 @@ -En un lugar de la Mancha, de cuyo nombre no quiero acordar-me, no ha -mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga -antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que -carnero, salpicón las más noches, duelos y quebrantos los sábados, -lantejas los viernes, algún palomino de añadidura los domingos, -consumían las tres partes de su hacienda. diff --git a/tex/context/sample/common/khatt-ar.tex b/tex/context/sample/common/khatt-ar.tex deleted file mode 100644 index c91426411..000000000 --- a/tex/context/sample/common/khatt-ar.tex +++ /dev/null @@ -1,4 +0,0 @@ -قَالَ عَلِيُّ بْنُ أَبِي طَالِبٍ لِكَاتِبِهِ عُبَيْدِ اللّٰهِ بْنِ -أَبِي رَافِعٍ: أَلِقْ دَوَاتَكَ، وَ أَطِلْ جِلْفَةَ قَلَمِكَ، وَ فَرِّجْ -بَيْنَ السُّطُورِ، وَ قَرْمِطْ بَيْنَ الْحُرُوفِ؛ فَإِنَّ ذَلِكَ أَجْدَرُ -بِصَبَاحَةِ الْخَطِّ. diff --git a/tex/context/sample/common/khatt-en.tex b/tex/context/sample/common/khatt-en.tex deleted file mode 100644 index 52891af25..000000000 --- a/tex/context/sample/common/khatt-en.tex +++ /dev/null @@ -1,4 +0,0 @@ -ʿAlī ibn Abī Ṭālib said to his scribe ʿUbaydullāh ibn Abī Rāfiʿ: Set -down your inkwell before you, sharpen the edge of your pen, make sure -there is open space between the lines, and set your letter|-|spacing -closely. Now {\em that} is the way to make the script shine! diff --git a/tex/context/sample/common/quevedo-es.tex b/tex/context/sample/common/quevedo-es.tex deleted file mode 100644 index 166b0328f..000000000 --- a/tex/context/sample/common/quevedo-es.tex +++ /dev/null @@ -1,19 +0,0 @@ -\startlines -Un soneto me manda hacer Violante -que en mi vida me he visto en tanto aprieto; -catorce versos dicen que es soneto; -burla burlando van los tres delante. - -Yo pensé que no hallara consonante, -y estoy a la mitad de otro cuarteto; -mas si me veo en el primer terceto, -no hay cosa en los cuartetos que me espante. - -Por el primer terceto voy entrando, -y parece que entré con pie derecho, -pues fin con este verso le voy dando. - -Ya estoy en el segundo, y aun sospecho -que voy los trece versos acabando; -contad si son catorce, y está hecho. -\stoplines diff --git a/tex/context/sample/third/aesop-de.tex b/tex/context/sample/third/aesop-de.tex new file mode 100644 index 000000000..80a41f295 --- /dev/null +++ b/tex/context/sample/third/aesop-de.tex @@ -0,0 +1,25 @@ +% German example file from Aesop + +Der L\"owe und die M\"ucke + +Eine M\"ucke forderte mit den \"uberm\"utigsten Worten +einen L\"owen zum Zweikampf heraus: \quotation {Ich +f\"urchte dich nicht, du gro\SS es Ungeheuer}, rief sie ihm +zu, \quotation {weil du gar keine Vorz\"uge vor mir hast; +oder nenne sie mir, wenn du solche zu haben glaubst; etwa +die, da\SS\ du deinen Raub mit Krallen zerrei\SS est und +mit Z\"ahnen zermalmest? Jedes andere feige Tier, wenn es +mit einem Tapfern k\"ampft, tut dasselbe, es bei\SS t und +kratzt. Du sollst aber empfinden, da\SS\ ich st\"arker bin +als du!} Mit diesen Worten flog sie in eines seiner +Nasenl\"ocher und stach ihn so sehr, da\SS\ er sich vor +Schmerz selbst zerfleischte und sich f\"ur \"uberwunden +erkl\"arte. + +Stolz auf diesen Sieg flog die M\"ucke davon, um ihn aller +Welt auszuposaunen, \"ubersah aber das Gewebe einer Spinne +und verfing sich in demselben. Gierig umarmte die Spinne +sie und sog ihr das Heldenblut aus. Sterbend empfand die +M\"ucke ihre Nichtigkeit, indem sie, die Besiegerin des +L\"owen, einem so ver\"achtlichen Tiere, einer Spinne, +erliegen mu\SS te. diff --git a/tex/context/sample/third/cervantes-es.tex b/tex/context/sample/third/cervantes-es.tex new file mode 100644 index 000000000..153797023 --- /dev/null +++ b/tex/context/sample/third/cervantes-es.tex @@ -0,0 +1,6 @@ +En un lugar de la Mancha, de cuyo nombre no quiero acordar-me, no ha +mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga +antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que +carnero, salpicón las más noches, duelos y quebrantos los sábados, +lantejas los viernes, algún palomino de añadidura los domingos, +consumían las tres partes de su hacienda. diff --git a/tex/context/sample/third/khatt-ar.tex b/tex/context/sample/third/khatt-ar.tex new file mode 100644 index 000000000..c91426411 --- /dev/null +++ b/tex/context/sample/third/khatt-ar.tex @@ -0,0 +1,4 @@ +قَالَ عَلِيُّ بْنُ أَبِي طَالِبٍ لِكَاتِبِهِ عُبَيْدِ اللّٰهِ بْنِ +أَبِي رَافِعٍ: أَلِقْ دَوَاتَكَ، وَ أَطِلْ جِلْفَةَ قَلَمِكَ، وَ فَرِّجْ +بَيْنَ السُّطُورِ، وَ قَرْمِطْ بَيْنَ الْحُرُوفِ؛ فَإِنَّ ذَلِكَ أَجْدَرُ +بِصَبَاحَةِ الْخَطِّ. diff --git a/tex/context/sample/third/khatt-en.tex b/tex/context/sample/third/khatt-en.tex new file mode 100644 index 000000000..52891af25 --- /dev/null +++ b/tex/context/sample/third/khatt-en.tex @@ -0,0 +1,4 @@ +ʿAlī ibn Abī Ṭālib said to his scribe ʿUbaydullāh ibn Abī Rāfiʿ: Set +down your inkwell before you, sharpen the edge of your pen, make sure +there is open space between the lines, and set your letter|-|spacing +closely. Now {\em that} is the way to make the script shine! diff --git a/tex/context/sample/third/quevedo-es.tex b/tex/context/sample/third/quevedo-es.tex new file mode 100644 index 000000000..166b0328f --- /dev/null +++ b/tex/context/sample/third/quevedo-es.tex @@ -0,0 +1,19 @@ +\startlines +Un soneto me manda hacer Violante +que en mi vida me he visto en tanto aprieto; +catorce versos dicen que es soneto; +burla burlando van los tres delante. + +Yo pensé que no hallara consonante, +y estoy a la mitad de otro cuarteto; +mas si me veo en el primer terceto, +no hay cosa en los cuartetos que me espante. + +Por el primer terceto voy entrando, +y parece que entré con pie derecho, +pues fin con este verso le voy dando. + +Ya estoy en el segundo, y aun sospecho +que voy los trece versos acabando; +contad si son catorce, y está hecho. +\stoplines diff --git a/tex/generic/context/luatex/luatex-basics-gen.lua b/tex/generic/context/luatex/luatex-basics-gen.lua index 2be55ccea..3959ca022 100644 --- a/tex/generic/context/luatex/luatex-basics-gen.lua +++ b/tex/generic/context/luatex/luatex-basics-gen.lua @@ -7,10 +7,19 @@ if not modules then modules = { } end modules ['luat-basics-gen'] = { } if context then - texio.write_nl("fatal error: this module is not for context") os.exit() end +-- We could load a few more of the general context libraries but it would +-- not make plain / latex users more happy I guess. So, we stick to some +-- placeholders. + +local match, gmatch, gsub, lower = string.match, string.gmatch, string.gsub, string.lower +local formatters, split, format, dump = string.formatters, string.split, string.format, string.dump +local loadfile, type = loadfile, type +local setmetatable, getmetatable, collectgarbage = setmetatable, getmetatable, collectgarbage +local floor = math.floor + local dummyfunction = function() end @@ -18,13 +27,22 @@ local dummyreporter = function(c) return function(f,...) local r = texio.reporter or texio.write_nl if f then - r(c .. " : " .. string.formatters(f,...)) + r(c .. " : " .. (formatters or format)(f,...)) else r("") end end end +local dummyreport = function(c,f,...) + local r = texio.reporter or texio.write_nl + if f then + r(c .. " : " .. (formatters or format)(f,...)) + else + r("") + end +end + statistics = { register = dummyfunction, starttiming = dummyfunction, @@ -59,17 +77,18 @@ logs = { new = dummyreporter, reporter = dummyreporter, messenger = dummyreporter, - report = dummyfunction, + report = dummyreport, } callbacks = { register = function(n,f) return callback.register(n,f) end, - } -utilities = utilities or { } utilities.storage = { +utilities = utilities or { } + +utilities.storage = utilities.storage or { allocate = function(t) return t or { } end, @@ -78,6 +97,28 @@ utilities = utilities or { } utilities.storage = { end, } +utilities.parsers = utilities.parsers or { + -- these are less flexible than in context but ok + -- for generic purpose + settings_to_array = function(s) + return split(s,",") + end, + settings_to_hash = function(s) + local t = { } + for k, v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do + t[k] = v + end + return t + end, + settings_to_hash_colon_too = function(s) + local t = { } + for k, v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do + t[k] = v + end + return t + end, +} + characters = characters or { data = { } } @@ -98,17 +139,18 @@ local remapper = { pfb = "type1 fonts", -- needed for vector loading afm = "afm", enc = "enc files", + lua = "tex", } function resolvers.findfile(name,fileformat) - name = string.gsub(name,"\\","/") + name = gsub(name,"\\","/") if not fileformat or fileformat == "" then fileformat = file.suffix(name) if fileformat == "" then fileformat = "tex" end end - fileformat = string.lower(fileformat) + fileformat = lower(fileformat) fileformat = remapper[fileformat] or fileformat local found = kpse.find_file(name,fileformat) if not found or found == "" then @@ -117,13 +159,6 @@ function resolvers.findfile(name,fileformat) return found end --- function resolvers.findbinfile(name,fileformat) --- if not fileformat or fileformat == "" then --- fileformat = file.suffix(name) --- end --- return resolvers.findfile(name,(fileformat and remapper[fileformat]) or fileformat) --- end - resolvers.findbinfile = resolvers.findfile function resolvers.loadbinfile(filename,filetype) @@ -191,14 +226,14 @@ do cachepaths = "." end - cachepaths = string.split(cachepaths,os.type == "windows" and ";" or ":") + cachepaths = split(cachepaths,os.type == "windows" and ";" or ":") for i=1,#cachepaths do local cachepath = cachepaths[i] if not lfs.isdir(cachepath) then lfs.mkdirs(cachepath) -- needed for texlive and latex if lfs.isdir(cachepath) then - texio.write(string.format("(created cache path: %s)",cachepath)) + logs.report("system","creating cache path '%s'",cachepath) end end if file.is_writable(cachepath) then @@ -217,16 +252,16 @@ do end if not writable then - texio.write_nl("quiting: fix your writable cache path") + logs.report("system","no writeable cache path, quiting") os.exit() elseif #readables == 0 then - texio.write_nl("quiting: fix your readable cache path") + logs.report("system","no readable cache path, quiting") os.exit() elseif #readables == 1 and readables[1] == writable then - texio.write(string.format("(using cache: %s)",writable)) + logs.report("system","using cache '%s'",writable) else - texio.write(string.format("(using write cache: %s)",writable)) - texio.write(string.format("(using read cache: %s)",table.concat(readables, " "))) + logs.report("system","using write cache '%s'",writable) + logs.report("system","using read cache '%s'",table.concat(readables," ")) end end @@ -258,75 +293,34 @@ function caches.is_writable(path,name) return fullname and file.is_writable(fullname) end --- function caches.loaddata(paths,name) --- for i=1,#paths do --- local data = false --- local luaname, lucname = makefullname(paths[i],name) --- if lucname and not lfs.isfile(lucname) and type(caches.compile) == "function" then --- -- in case we used luatex and luajittex mixed ... lub or luc file --- texio.write(string.format("(compiling luc: %s)",lucname)) --- data = loadfile(luaname) --- if data then --- data = data() --- end --- if data then --- caches.compile(data,luaname,lucname) --- return data --- end --- end --- if lucname and lfs.isfile(lucname) then -- maybe also check for size --- texio.write(string.format("(load luc: %s)",lucname)) --- data = loadfile(lucname) --- if data then --- data = data() --- end --- if data then --- return data --- else --- texio.write(string.format("(loading failed: %s)",lucname)) --- end --- end --- if luaname and lfs.isfile(luaname) then --- texio.write(string.format("(load lua: %s)",luaname)) --- data = loadfile(luaname) --- if data then --- data = data() --- end --- if data then --- return data --- end --- end --- end --- end - function caches.loaddata(readables,name,writable) for i=1,#readables do local path = readables[i] local loader = false local luaname, lucname = makefullname(path,name) if lfs.isfile(lucname) then - texio.write(string.format("(load luc: %s)",lucname)) + logs.report("system","loading luc file '%s'",lucname) loader = loadfile(lucname) end if not loader and lfs.isfile(luaname) then -- can be different paths when we read a file database from disk local luacrap, lucname = makefullname(writable,name) - texio.write(string.format("(compiling luc: %s)",lucname)) + logs.report("system","compiling luc file '%s'",lucname) if lfs.isfile(lucname) then loader = loadfile(lucname) end caches.compile(data,luaname,lucname) if lfs.isfile(lucname) then - texio.write(string.format("(load luc: %s)",lucname)) + logs.report("system","loading luc file '%s'",lucname) loader = loadfile(lucname) else - texio.write(string.format("(loading failed: %s)",lucname)) + logs.report("system","error in loading luc file '%s'",lucname) end if not loader then - texio.write(string.format("(load lua: %s)",luaname)) + logs.report("system","loading lua file '%s'",luaname) loader = loadfile(luaname) else - texio.write(string.format("(loading failed: %s)",luaname)) + logs.report("system","error in loading lua file '%s'",luaname) end end if loader then @@ -341,42 +335,19 @@ end function caches.savedata(path,name,data) local luaname, lucname = makefullname(path,name) if luaname then - texio.write(string.format("(save: %s)",luaname)) + logs.report("system","saving lua file '%s'",luaname) table.tofile(luaname,data,true) if lucname and type(caches.compile) == "function" then os.remove(lucname) -- better be safe - texio.write(string.format("(save: %s)",lucname)) + logs.report("system","saving luc file '%s'",lucname) caches.compile(data,luaname,lucname) end end end --- According to KH os.execute is not permitted in plain/latex so there is --- no reason to use the normal context way. So the method here is slightly --- different from the one we have in context. We also use different suffixes --- as we don't want any clashes (sharing cache files is not that handy as --- context moves on faster.) --- --- Beware: serialization might fail on large files (so maybe we should pcall --- this) in which case one should limit the method to luac and enable support --- for execution. - --- function caches.compile(data,luaname,lucname) --- local d = io.loaddata(luaname) --- if not d or d == "" then --- d = table.serialize(data,true) -- slow --- end --- if d and d ~= "" then --- local f = io.open(lucname,'w') --- if f then --- local s = loadstring(d) --- if s then --- f:write(string.dump(s,true)) --- end --- f:close() --- end --- end --- end +-- The method here is slightly different from the one we have in context. We +-- also use different suffixes as we don't want any clashes (sharing cache +-- files is not that handy as context moves on faster.) function caches.compile(data,luaname,lucname) local d = io.loaddata(luaname) @@ -388,23 +359,14 @@ function caches.compile(data,luaname,lucname) if f then local s = loadstring(d) if s then - f:write(string.dump(s,true)) + f:write(dump(s,true)) end f:close() end end end --- - --- function table.setmetatableindex(t,f) --- if type(t) ~= "table" then --- f = f or t --- t = { } --- end --- setmetatable(t,{ __index = f }) --- return t --- end +-- simplfied version: function table.setmetatableindex(t,f) if type(t) ~= "table" then @@ -422,15 +384,96 @@ function table.setmetatableindex(t,f) return t end +function table.makeweak(t) + local m = getmetatable(t) + if m then + m.__mode = "v" + else + setmetatable(t,{ __mode = "v" }) + end + return t +end + -- helper for plain: arguments = { } if arg then for i=1,#arg do - local k, v = string.match(arg[i],"^%-%-([^=]+)=?(.-)$") + local k, v = match(arg[i],"^%-%-([^=]+)=?(.-)$") if k and v then arguments[k] = v end end end + +-- another one + +if not number.idiv then + function number.idiv(i,d) + return floor(i/d) -- i//d in 5.3 + end +end + +-- hook into unicode + +local u = unicode and unicode.utf8 + +if u then + + utf.lower = u.lower + utf.upper = u.upper + utf.char = u.char + utf.byte = u.byte + utf.len = u.len + + -- needed on font-* + + if lpeg.setutfcasers then + lpeg.setutfcasers(u.lower,u.upper) + end + + -- needed on font-otr + + local bytepairs = string.bytepairs + local utfchar = utf.char + local concat = table.concat + + function utf.utf16_to_utf8_be(s) + if not s then + return nil + elseif s == "" then + return "" + end + local result, r, more = { }, 0, 0 + for left, right in bytepairs(s) do + if right then + local now = 256*left + right + if more > 0 then + now = (more-0xD800)*0x400 + (now-0xDC00) + 0x10000 + more = 0 + r = r + 1 + result[r] = utfchar(now) + elseif now >= 0xD800 and now <= 0xDBFF then + more = now + else + r = r + 1 + result[r] = utfchar(now) + end + end + end + return concat(result) + end + + local characters = string.utfcharacters + + function utf.split(str) + local t, n = { }, 0 + for s in characters(str) do + n = n + 1 + t[n] = s + end + return t + end + +end diff --git a/tex/generic/context/luatex/luatex-basics-nod.lua b/tex/generic/context/luatex/luatex-basics-nod.lua index 40fb9ee4e..e22f170ef 100644 --- a/tex/generic/context/luatex/luatex-basics-nod.lua +++ b/tex/generic/context/luatex/luatex-basics-nod.lua @@ -7,12 +7,12 @@ if not modules then modules = { } end modules ['luatex-fonts-nod'] = { } if context then - texio.write_nl("fatal error: this module is not for context") os.exit() end --- Don't depend on code here as it is only needed to complement the --- font handler code. +-- Don't depend on code here as it is only needed to complement the font handler +-- code. I will move some to another namespace as I don't see other macro packages +-- use the context logic. It's a subset anyway. -- Attributes: @@ -59,11 +59,11 @@ for k, v in next, node.types() do nodecodes[k] = v nodecodes[v] = k end -for i=0,#glyphcodes do - glyphcodes[glyphcodes[i]] = i +for k, v in next, glyphcodes do + glyphcodes[v] = k end -for i=0,#disccodes do - disccodes[disccodes[i]] = i +for k, v in next, disccodes do + disccodes[v] = k end nodes.nodecodes = nodecodes @@ -74,19 +74,8 @@ local flush_node = node.flush_node local remove_node = node.remove local traverse_id = node.traverse_id -nodes.handlers.protectglyphs = node.protect_glyphs -nodes.handlers.unprotectglyphs = node.unprotect_glyphs - -local math_code = nodecodes.math -local end_of_math = node.end_of_math - -function node.end_of_math(n) - if n.id == math_code and n.subtype == 1 then - return n - else - return end_of_math(n) - end -end +nodes.handlers.protectglyphs = node.protect_glyphs -- beware: nodes! +nodes.handlers.unprotectglyphs = node.unprotect_glyphs -- beware: nodes! function nodes.remove(head, current, free_too) local t = current @@ -155,8 +144,6 @@ nodes.unset_attribute = node.unset_attribute nodes.protect_glyphs = node.protect_glyphs nodes.unprotect_glyphs = node.unprotect_glyphs ------.kerning = node.kerning ------.ligaturing = node.ligaturing nodes.mlist_to_hlist = node.mlist_to_hlist -- in generic code, at least for some time, we stay nodes, while in context @@ -178,128 +165,104 @@ nodes.tonut = tonut nuts.tonode = tonode nuts.tonut = tonut -local getfield = direct.getfield -local setfield = direct.setfield - -nuts.getfield = getfield -nuts.setfield = setfield -nuts.getnext = direct.getnext -nuts.setnext = direct.setnext -nuts.getprev = direct.getprev -nuts.setprev = direct.setprev +nuts.getattr = direct.get_attribute nuts.getboth = direct.getboth -nuts.setboth = direct.setboth -nuts.getid = direct.getid -nuts.getattr = direct.get_attribute or direct.has_attribute or getfield -nuts.setattr = setfield +nuts.getchar = direct.getchar +nuts.getcomponents = direct.getcomponents +----.getdepth = direct.getdepth +----.getdir = direct.getdir +nuts.getdirection = direct.getdirection +nuts.getdisc = direct.getdisc +nuts.getfield = direct.getfield nuts.getfont = direct.getfont -nuts.setfont = direct.setfont +----.getheight = direct.getheight +nuts.getid = direct.getid +nuts.getkern = direct.getkern +----.getleader = direct.getleader +nuts.getlist = direct.getlist +nuts.getnext = direct.getnext +nuts.getoffsets = direct.getoffsets +nuts.getprev = direct.getprev nuts.getsubtype = direct.getsubtype -nuts.setsubtype = direct.setsubtype -nuts.getchar = direct.getchar +nuts.getwidth = direct.getwidth +nuts.setattr = direct.setfield +nuts.setboth = direct.setboth nuts.setchar = direct.setchar -nuts.getdisc = direct.getdisc +nuts.setcomponents = direct.setcomponents +----.setdepth = direct.setdepth +nuts.setdir = direct.setdir +nuts.setdirection = direct.setdirection nuts.setdisc = direct.setdisc +nuts.setfield = setfield +----.setfont = direct.setfont +----.setheight = direct.setheight +nuts.setkern = direct.setkern +----.setleader = direct.setleader nuts.setlink = direct.setlink -nuts.setsplit = direct.setsplit -nuts.getlist = direct.getlist nuts.setlist = direct.setlist +nuts.setnext = direct.setnext +nuts.setoffsets = direct.setoffsets +nuts.setprev = direct.setprev +nuts.setsplit = direct.setsplit +nuts.setsubtype = direct.setsubtype +nuts.setwidth = direct.setwidth -nuts.getoffsets = direct.getoffsets or - function(n) - return getfield(n,"xoffset"), getfield(n,"yoffset") - end -nuts.setoffsets = direct.setoffsets or - function(n,x,y) - if x then setfield(n,"xoffset",x) end - if y then setfield(n,"xoffset",y) end - end - -nuts.getleader = direct.getleader or function(n) return getfield(n,"leader") end -nuts.setleader = direct.setleader or function(n,l) setfield(n,"leader",l) end -nuts.getcomponents = direct.getcomponents or function(n) return getfield(n,"components") end -nuts.setcomponents = direct.setcomponents or function(n,c) setfield(n,"components",c) end -nuts.getkern = direct.getkern or function(n) return getfield(n,"kern") end -nuts.setkern = direct.setkern or function(n,k) setfield(n,"kern",k) end -nuts.getdir = direct.getdir or function(n) return getfield(n,"dir") end -nuts.setdir = direct.setdir or function(n,d) setfield(n,"dir",d) end -nuts.getwidth = direct.getwidth or function(n) return getfield(n,"width") end -nuts.setwidth = direct.setwidth or function(n,w) return setfield(n,"width",w) end -nuts.getheight = direct.getheight or function(n) return getfield(n,"height") end -nuts.setheight = direct.setheight or function(n,h) return setfield(n,"height",h) end -nuts.getdepth = direct.getdepth or function(n) return getfield(n,"depth") end -nuts.setdepth = direct.setdepth or function(n,d) return setfield(n,"depth",d) end - -if not direct.is_glyph then - local getchar = direct.getchar - local getid = direct.getid - local getfont = direct.getfont - local glyph_code = nodes.nodecodes.glyph - function direct.is_glyph(n,f) - local id = getid(n) - if id == glyph_code then - if f and getfont(n) == f then - return getchar(n) - else - return false - end - else - return nil, id - end - end - function direct.is_char(n,f) - local id = getid(n) - if id == glyph_code then - if getsubtype(n) >= 256 then - return false - elseif f and getfont(n) == f then - return getchar(n) - else - return false - end - else - return nil, id - end - end -end - -nuts.ischar = direct.is_char nuts.is_char = direct.is_char -nuts.isglyph = direct.is_glyph nuts.is_glyph = direct.is_glyph +nuts.ischar = direct.is_char +nuts.isglyph = direct.is_glyph -nuts.insert_before = direct.insert_before -nuts.insert_after = direct.insert_after -nuts.delete = direct.delete nuts.copy = direct.copy -nuts.copy_node = direct.copy nuts.copy_list = direct.copy_list -nuts.tail = direct.tail +nuts.copy_node = direct.copy +nuts.delete = direct.delete +nuts.end_of_math = direct.end_of_math +nuts.flush = direct.flush nuts.flush_list = direct.flush_list nuts.flush_node = direct.flush_node -nuts.flush = direct.flush nuts.free = direct.free -nuts.remove = direct.remove +nuts.insert_after = direct.insert_after +nuts.insert_before = direct.insert_before nuts.is_node = direct.is_node -nuts.end_of_math = direct.end_of_math -nuts.traverse = direct.traverse -nuts.traverse_id = direct.traverse_id -nuts.traverse_char = direct.traverse_char -nuts.ligaturing = direct.ligaturing nuts.kerning = direct.kerning +nuts.ligaturing = direct.ligaturing nuts.new = direct.new +nuts.remove = direct.remove +nuts.tail = direct.tail +nuts.traverse = direct.traverse +nuts.traverse_char = direct.traverse_char +nuts.traverse_glyph = direct.traverse_glyph +nuts.traverse_id = direct.traverse_id + +-- for now + +if not nuts.getdirection then + + local getdir = direct.getdir + + function nuts.getdirection(n) + local d = getdir(n) + if d == "TLT" then return 0 + elseif d == "TRT" then return 1 + elseif d == "+TLT" then return 0, false + elseif d == "+TRT" then return 1, false + elseif d == "-TLT" then return 0, true + elseif d == "-TRT" then return 1, true + else return 0 + end + end -nuts.getprop = nuts.getattr -nuts.setprop = nuts.setattr +end -- properties as used in the (new) injector: local propertydata = direct.get_properties_table() nodes.properties = { data = propertydata } -direct.set_properties_mode(true,true) -- needed for injection - -function direct.set_properties_mode() end -- we really need the set modes +if direct.set_properties_mode then + direct.set_properties_mode(true,true) + function direct.set_properties_mode() end +end nuts.getprop = function(n,k) local p = propertydata[n] @@ -342,76 +305,6 @@ local copy_node = nuts.copy_node local glyph_code = nodes.nodecodes.glyph -function nuts.set_components(target,start,stop) - local head = getcomponents(target) - if head then - flush_list(head) - head = nil - end - if start then - setprev(start) - else - return nil - end - if stop then - setnext(stop) - end - local tail = nil - while start do - local c = getcomponents(start) - local n = getnext(start) - if c then - if head then - setlink(tail,c) - else - head = c - end - tail = find_tail(c) - setcomponents(start) - flush_node(start) - else - if head then - setlink(tail,start) - else - head = start - end - tail = start - end - start = n - end - setcomponents(target,head) - -- maybe also upgrade the subtype but we don't use it anyway - return head -end - -nuts.get_components = nuts.getcomponents - -function nuts.take_components(target) - local c = getcomponents(target) - setcomponents(target) - -- maybe also upgrade the subtype but we don't use it anyway - return c -end - -function nuts.count_components(n,marks) - local components = getcomponents(n) - if components then - if marks then - local i = 0 - for g in traverse_id(glyph_code,components) do - if not marks[getchar(g)] then - i = i + 1 - end - end - return i - else - return count(glyph_code,components) - end - else - return 0 - end -end - function nuts.copy_no_components(g,copyinjection) local components = getcomponents(g) if components then @@ -449,34 +342,22 @@ end nuts.uses_font = direct.uses_font -if not nuts.uses_font then - local getdisc = nuts.getdisc - local getfont = nuts.getfont - function nuts.uses_font(n,font) - local pre, post, replace = getdisc(n) - if pre then - -- traverse_char - for n in traverse_id(glyph_code,pre) do - if getfont(n) == font then - return true - end - end - end - if post then - for n in traverse_id(glyph_code,post) do - if getfont(n) == font then - return true - end - end - end - if replace then - for n in traverse_id(glyph_code,replace) do - if getfont(n) == font then - return true - end - end - end - return false - end -end +do + -- another poor mans substitute ... i will move these to a more protected + -- namespace .. experimental hack + + local dummy = tonut(node.new("glyph")) + + nuts.traversers = { + glyph = nuts.traverse_id(nodecodes.glyph,dummy), + glue = nuts.traverse_id(nodecodes.glue,dummy), + disc = nuts.traverse_id(nodecodes.disc,dummy), + boundary = nuts.traverse_id(nodecodes.boundary,dummy), + + char = nuts.traverse_char(dummy), + + node = nuts.traverse(dummy), + } + +end diff --git a/tex/generic/context/luatex/luatex-core.lua b/tex/generic/context/luatex/luatex-core.lua index 35005d1c8..6e1b31e96 100644 --- a/tex/generic/context/luatex/luatex-core.lua +++ b/tex/generic/context/luatex/luatex-core.lua @@ -1,18 +1,21 @@ -- luatex-core security and io overloads ........... -- if not modules then modules = { } end modules ['luatex-core'] = { --- version = 1.005, +-- version = 1.080, -- comment = 'companion to luatex', -- author = 'Hans Hagen & Luigi Scarso', -- copyright = 'LuaTeX Development Team', -- } -LUATEXCOREVERSION = 1.005 +LUATEXCOREVERSION = 1.080 -- we reflect the luatex version where changes happened -- This file overloads some Lua functions. The readline variants provide the same -- functionality as LuaTeX <= 1.04 and doing it this way permits us to keep the -- original io libraries clean. Performance is probably even a bit better now. +-- We test for functions already being defined so that we don't overload ones that +-- are provided in the startup script. + local type, next, getmetatable, require = type, next, getmetatable, require local find, gsub, format = string.find, string.gsub, string.format @@ -51,7 +54,7 @@ local function luatex_io_open(name,how) end local function luatex_io_open_readonly(name,how) - if how then + if not how then how = 'r' else how = gsub(how,'[^rb]','') @@ -171,6 +174,8 @@ if saferoption == 1 then lfs.rmdir = installdummy("lfs.rmdir") lfs.mkdir = installdummy("lfs.mkdir") + debug = nil + end if saferoption == 1 or shellescape ~= 1 then @@ -195,16 +200,20 @@ if md5 then local format = string.format local byte = string.byte - function md5.sumhexa(k) - return (gsub(sum(k), ".", function(c) - return format("%02x",byte(c)) - end)) + if not md5.sumhexa then + function md5.sumhexa(k) + return (gsub(sum(k), ".", function(c) + return format("%02x",byte(c)) + end)) + end end - function md5.sumHEXA(k) - return (gsub(sum(k), ".", function(c) - return format("%02X",byte(c)) - end)) + if not md5.sumHEXA then + function md5.sumHEXA(k) + return (gsub(sum(k), ".", function(c) + return format("%02X",byte(c)) + end)) + end end end @@ -367,6 +376,47 @@ do if not loaded.socket then loaded.socket = loaded["socket.core"] end if not loaded.mime then loaded.mime = loaded["mime.core"] end + if not loaded.lfs then loaded.lfs = lfs end + +end + +do + + local lfsattributes = lfs.attributes + local symlinkattributes = lfs.symlinkattributes + + -- these can now be done using lfs (was dead slow before) + + if not lfs.isfile then + function lfs.isfile(name) + local m = lfsattributes(name,"mode") + return m == "file" or m == "link" + end + end + + if not lfs.isdir then + function lfs.isdir(name) + local m = lfsattributes(name,"mode") + return m == "directory" + end + end + + -- shortnames have also be sort of dropped from kpse + + if not lfs.shortname then + function lfs.shortname(name) + return name + end + end + + -- now there is a target field, so ... + + if not lfs.readlink then + function lfs.readlink(name) + return symlinkattributes(name,"target") or nil + end + end + end -- so far diff --git a/tex/generic/context/luatex/luatex-fonts-def.lua b/tex/generic/context/luatex/luatex-fonts-def.lua new file mode 100644 index 000000000..883451fb5 --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-def.lua @@ -0,0 +1,98 @@ +if not modules then modules = { } end modules ['luatex-fonts-def'] = { + version = 1.001, + comment = "companion to luatex-*.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +if context then + os.exit() +end + +local fonts = fonts + +-- A bit of tuning for definitions. + +fonts.constructors.namemode = "specification" -- somehow latex needs this (changed name!) => will change into an overload + +-- tricky: we sort of bypass the parser and directly feed all into +-- the sub parser + +function fonts.definers.getspecification(str) + return "", str, "", ":", str +end + +-- the generic name parser (different from context!) + +local list = { } -- we could pass Carg but let's keep the old one + +local function issome () list.lookup = 'name' end -- xetex mode prefers name (not in context!) +local function isfile () list.lookup = 'file' end +local function isname () list.lookup = 'name' end +local function thename(s) list.name = s end +local function issub (v) list.sub = v end +local function iscrap (s) list.crap = string.lower(s) end +local function iskey (k,v) list[k] = v end +local function istrue (s) list[s] = true end +local function isfalse(s) list[s] = false end + +local P, S, R, C, Cs = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cs + +local spaces = P(" ")^0 +local namespec = Cs((P("{")/"") * (1-S("}"))^0 * (P("}")/"") + (1-S("/:("))^0) +local crapspec = spaces * P("/") * (((1-P(":"))^0)/iscrap) * spaces +local filename_1 = P("file:")/isfile * (namespec/thename) +local filename_2 = P("[") * P(true)/isfile * (((1-P("]"))^0)/thename) * P("]") +local fontname_1 = P("name:")/isname * (namespec/thename) +local fontname_2 = P(true)/issome * (namespec/thename) +local sometext = R("az","AZ","09")^1 +local somekey = R("az","AZ","09")^1 +local somevalue = (P("{")/"")*(1-P("}"))^0*(P("}")/"") + (1-S(";"))^1 +local truevalue = P("+") * spaces * (sometext/istrue) +local falsevalue = P("-") * spaces * (sometext/isfalse) +local keyvalue = (C(somekey) * spaces * P("=") * spaces * C(somevalue))/iskey +local somevalue = sometext/istrue +local subvalue = P("(") * (C(P(1-S("()"))^1)/issub) * P(")") -- for Kim +local option = spaces * (keyvalue + falsevalue + truevalue + somevalue) * spaces +local options = P(":") * spaces * (P(";")^0 * option)^0 + +local pattern = (filename_1 + filename_2 + fontname_1 + fontname_2) + * subvalue^0 * crapspec^0 * options^0 + +function fonts.definers.analyze(str,size) + local specification = fonts.definers.makespecification(str,nil,nil,nil,":",nil,size) + list = { } + lpeg.match(pattern,str) + list.crap = nil + if list.name then + specification.name = list.name + list.name = nil + end + if list.lookup then + specification.lookup = list.lookup + list.lookup = nil + end + if list.sub then + specification.sub = list.sub + list.sub = nil + end + specification.features.normal = fonts.handlers.otf.features.normalize(list) + list = nil + return specification +end + +function fonts.definers.applypostprocessors(tfmdata) + local postprocessors = tfmdata.postprocessors + if postprocessors then + for i=1,#postprocessors do + local extrahash = postprocessors[i](tfmdata) -- after scaling etc + if type(extrahash) == "string" and extrahash ~= "" then + -- e.g. a reencoding needs this + extrahash = string.gsub(lower(extrahash),"[^a-z]","-") + tfmdata.properties.fullname = format("%s-%s",tfmdata.properties.fullname,extrahash) + end + end + end + return tfmdata +end diff --git a/tex/generic/context/luatex/luatex-fonts-enc.lua b/tex/generic/context/luatex/luatex-fonts-enc.lua index c076d5947..2bc6b71bf 100644 --- a/tex/generic/context/luatex/luatex-fonts-enc.lua +++ b/tex/generic/context/luatex/luatex-fonts-enc.lua @@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['luatex-font-enc'] = { } if context then - texio.write_nl("fatal error: this module is not for context") os.exit() end @@ -19,7 +18,7 @@ encodings.known = { } setmetatable(encodings.agl, { __index = function(t,k) if k == "unicodes" then - texio.write(" ") + logs.report("fonts","loading (extended) adobe glyph list") local unicodes = dofile(resolvers.findfile("font-age.lua")) encodings.agl = { unicodes = unicodes } return unicodes diff --git a/tex/generic/context/luatex/luatex-fonts-ext.lua b/tex/generic/context/luatex/luatex-fonts-ext.lua index 15762d9ba..aee43ec4b 100644 --- a/tex/generic/context/luatex/luatex-fonts-ext.lua +++ b/tex/generic/context/luatex/luatex-fonts-ext.lua @@ -7,89 +7,54 @@ if not modules then modules = { } end modules ['luatex-fonts-ext'] = { } if context then - texio.write_nl("fatal error: this module is not for context") os.exit() end -local fonts = fonts -local otffeatures = fonts.constructors.features.otf -local getprivate = fonts.constructors.getprivate +local byte = string.byte --- A few generic extensions. +local fonts = fonts +local handlers = fonts.handlers +local otf = handlers.otf +local afm = handlers.afm +local registerotffeature = otf.features.register +local registerafmfeature = afm.features.register -local function initializeitlc(tfmdata,value) - if value then - -- the magic 40 and it formula come from Dohyun Kim but we might need another guess - local parameters = tfmdata.parameters - local italicangle = parameters.italicangle - if italicangle and italicangle ~= 0 then - local properties = tfmdata.properties - local factor = tonumber(value) or 1 - properties.hasitalics = true - properties.autoitalicamount = factor * (parameters.uwidth or 40)/2 - end - end -end +-- extra generic stuff -otffeatures.register { - name = "itlc", - description = "italic correction", - initializers = { - base = initializeitlc, - node = initializeitlc, - } -} +function fonts.loggers.onetimemessage() end --- slant and extend +-- done elsewhere +-- +-- loadmodule('font-ext-imp-italic.lua') +-- loadmodule('font-ext-imp-effect.lua') +-- loadmodule('luatex-fonts-lig.lua') -local function initializeslant(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - elseif value > 1 then - value = 1 - elseif value < -1 then - value = -1 - end - tfmdata.parameters.slantfactor = value -end +-- protrusion (simplified version) -otffeatures.register { - name = "slant", - description = "slant glyphs", - initializers = { - base = initializeslant, - node = initializeslant, - } -} - -local function initializeextend(tfmdata,value) - value = tonumber(value) - if not value then - value = 0 - elseif value > 10 then - value = 10 - elseif value < -10 then - value = -10 - end - tfmdata.parameters.extendfactor = value -end +fonts.protrusions = fonts.protrusions or { } +fonts.protrusions.setups = fonts.protrusions.setups or { } +local setups = fonts.protrusions.setups -otffeatures.register { - name = "extend", - description = "scale glyphs horizontally", - initializers = { - base = initializeextend, - node = initializeextend, - } -} +setups['default'] = { -- demo vector --- expansion and protrusion + factor = 1, + left = 1, + right = 1, -fonts.protrusions = fonts.protrusions or { } -fonts.protrusions.setups = fonts.protrusions.setups or { } + [0x002C] = { 0, 1 }, -- comma + [0x002E] = { 0, 1 }, -- period + [0x003A] = { 0, 1 }, -- colon + [0x003B] = { 0, 1 }, -- semicolon + [0x002D] = { 0, 1 }, -- hyphen + [0x2013] = { 0, 0.50 }, -- endash + [0x2014] = { 0, 0.33 }, -- emdash + [0x3001] = { 0, 1 }, -- ideographic comma 、 + [0x3002] = { 0, 1 }, -- ideographic full stop 。 + [0x060C] = { 0, 1 }, -- arabic comma ، + [0x061B] = { 0, 1 }, -- arabic semicolon ؛ + [0x06D4] = { 0, 1 }, -- arabic full stop ۔ -local setups = fonts.protrusions.setups +} local function initializeprotrusion(tfmdata,value) if value then @@ -112,7 +77,7 @@ local function initializeprotrusion(tfmdata,value) end end -otffeatures.register { +local specification = { name = "protrusion", description = "shift characters into the left and or right margin", initializers = { @@ -121,10 +86,32 @@ otffeatures.register { } } -fonts.expansions = fonts.expansions or { } -fonts.expansions.setups = fonts.expansions.setups or { } +registerotffeature(specification) +registerafmfeature(specification) -local setups = fonts.expansions.setups +-- expansion (simplified version) + +fonts.expansions = fonts.expansions or { } +fonts.expansions.setups = fonts.expansions.setups or { } +local setups = fonts.expansions.setups + +setups['default'] = { -- demo vector + + stretch = 2, + shrink = 2, + step = .5, + factor = 1, + + [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7, + [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7, + [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7, + [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, + [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, + [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, + [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, + [byte('w')] = 0.7, [byte('z')] = 0.7, + [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, +} local function initializeexpansion(tfmdata,value) if value then @@ -149,7 +136,7 @@ local function initializeexpansion(tfmdata,value) end end -otffeatures.register { +local specification = { name = "expansion", description = "apply hz optimization", initializers = { @@ -158,55 +145,20 @@ otffeatures.register { } } --- left over - -function fonts.loggers.onetimemessage() end - --- example vectors - -local byte = string.byte - -fonts.expansions.setups['default'] = { - - stretch = 2, shrink = 2, step = .5, factor = 1, - - [byte('A')] = 0.5, [byte('B')] = 0.7, [byte('C')] = 0.7, [byte('D')] = 0.5, [byte('E')] = 0.7, - [byte('F')] = 0.7, [byte('G')] = 0.5, [byte('H')] = 0.7, [byte('K')] = 0.7, [byte('M')] = 0.7, - [byte('N')] = 0.7, [byte('O')] = 0.5, [byte('P')] = 0.7, [byte('Q')] = 0.5, [byte('R')] = 0.7, - [byte('S')] = 0.7, [byte('U')] = 0.7, [byte('W')] = 0.7, [byte('Z')] = 0.7, - [byte('a')] = 0.7, [byte('b')] = 0.7, [byte('c')] = 0.7, [byte('d')] = 0.7, [byte('e')] = 0.7, - [byte('g')] = 0.7, [byte('h')] = 0.7, [byte('k')] = 0.7, [byte('m')] = 0.7, [byte('n')] = 0.7, - [byte('o')] = 0.7, [byte('p')] = 0.7, [byte('q')] = 0.7, [byte('s')] = 0.7, [byte('u')] = 0.7, - [byte('w')] = 0.7, [byte('z')] = 0.7, - [byte('2')] = 0.7, [byte('3')] = 0.7, [byte('6')] = 0.7, [byte('8')] = 0.7, [byte('9')] = 0.7, -} - -fonts.protrusions.setups['default'] = { - - factor = 1, left = 1, right = 1, - - [0x002C] = { 0, 1 }, -- comma - [0x002E] = { 0, 1 }, -- period - [0x003A] = { 0, 1 }, -- colon - [0x003B] = { 0, 1 }, -- semicolon - [0x002D] = { 0, 1 }, -- hyphen - [0x2013] = { 0, 0.50 }, -- endash - [0x2014] = { 0, 0.33 }, -- emdash - [0x3001] = { 0, 1 }, -- ideographic comma 、 - [0x3002] = { 0, 1 }, -- ideographic full stop 。 - [0x060C] = { 0, 1 }, -- arabic comma ، - [0x061B] = { 0, 1 }, -- arabic semicolon ؛ - [0x06D4] = { 0, 1 }, -- arabic full stop ۔ +registerotffeature(specification) +registerafmfeature(specification) -} +-- normalizer (generic only) --- normalizer +if not otf.features.normalize then -fonts.handlers.otf.features.normalize = function(t) - if t.rand then - t.rand = "random" + otf.features.normalize = function(t) + if t.rand then + t.rand = "random" + end + return t end - return t + end -- bonus @@ -230,6 +182,8 @@ end -- [110] = 109, -- n -- } +-- reencoding (generic only) + fonts.encodings = fonts.encodings or { } local reencodings = { } fonts.encodings.reencodings = reencodings @@ -254,7 +208,7 @@ local function specialreencode(tfmdata,value) end end -local function reencode(tfmdata,value) +local function initialize(tfmdata,value) tfmdata.postprocessors = tfmdata.postprocessors or { } table.insert(tfmdata.postprocessors, function(tfmdata) @@ -263,65 +217,28 @@ local function reencode(tfmdata,value) ) end -otffeatures.register { +registerotffeature { name = "reencode", description = "reencode characters", manipulators = { - base = reencode, - node = reencode, + base = initialize, + node = initialize, } } -local function ignore(tfmdata,key,value) +-- math stuff (generic only) + +local function initialize(tfmdata,key,value) if value then tfmdata.mathparameters = nil end end -otffeatures.register { +registerotffeature { name = "ignoremathconstants", description = "ignore math constants table", initializers = { - base = ignore, - node = ignore, - } -} - -local setmetatableindex = table.setmetatableindex - -local function additalictowidth(tfmdata,key,value) - local characters = tfmdata.characters - local additions = { } - for unicode, old_c in next, characters do - -- maybe check for math - local oldwidth = old_c.width - local olditalic = old_c.italic - if olditalic and olditalic ~= 0 then - local private = getprivate(tfmdata) - local new_c = { - width = oldwidth + olditalic, - height = old_c.height, - depth = old_c.depth, - commands = { - { "slot", 1, private }, - { "right", olditalic }, - }, - } - setmetatableindex(new_c,old_c) - characters[unicode] = new_c - additions[private] = old_c - end - end - for k, v in next, additions do - characters[k] = v - end -end - -otffeatures.register { - name = "italicwidths", - description = "add italic to width", - manipulators = { - base = additalictowidth, - -- node = additalictowidth, -- only makes sense for math + base = initialize, + node = initialize, } } diff --git a/tex/generic/context/luatex/luatex-fonts-gbn.lua b/tex/generic/context/luatex/luatex-fonts-gbn.lua new file mode 100644 index 000000000..53be41c7e --- /dev/null +++ b/tex/generic/context/luatex/luatex-fonts-gbn.lua @@ -0,0 +1,300 @@ +if not modules then modules = { } end modules ['luatex-fonts-gbn'] = { + version = 1.001, + comment = "companion to luatex-*.tex", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- generic [base|node] mode handler + +if context then + os.exit() +end + +local next = next + +local fonts = fonts +local nodes = nodes + +local nuts = nodes.nuts -- context abstraction of direct nodes + +local traverse_id = nuts.traverse_id +local flush_node = nuts.flush_node + +local glyph_code = nodes.nodecodes.glyph +local disc_code = nodes.nodecodes.disc + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local getfont = nuts.getfont +local getchar = nuts.getchar +local getid = nuts.getid +local getboth = nuts.getboth +local getprev = nuts.getprev +local getnext = nuts.getnext +local getdisc = nuts.getdisc +local setchar = nuts.setchar +local setlink = nuts.setlink +local setprev = nuts.setprev + +-- from now on we apply ligaturing and kerning here because it might interfere with complex +-- opentype discretionary handling where the base ligature pass expect some weird extra +-- pointers (which then confuse the tail slider that has some checking built in) + +local n_ligaturing = node.ligaturing +local n_kerning = node.kerning + +local d_ligaturing = nuts.ligaturing +local d_kerning = nuts.kerning + +local basemodepass = true + +local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning = nil end +local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning = nil end + +function node.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return n_ligaturing(...) +end + +function node.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return n_kerning(...) +end + +function nuts.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return d_ligaturing(...) +end + +function nuts.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return d_kerning(...) +end + +-- direct.ligaturing = nuts.ligaturing +-- direct.kerning = nuts.kerning + +function nodes.handlers.setbasemodepass(v) + basemodepass = v +end + +local function nodepass(head,groupcode,size,packtype,direction) + local fontdata = fonts.hashes.identifiers + if fontdata then + local usedfonts = { } + local basefonts = { } + local prevfont = nil + local basefont = nil + local variants = nil + local redundant = nil + local nofused = 0 + for n in traverse_id(glyph_code,head) do + local font = getfont(n) + if font ~= prevfont then + if basefont then + basefont[2] = getprev(n) + end + prevfont = font + local used = usedfonts[font] + if not used then + local tfmdata = fontdata[font] -- + if tfmdata then + local shared = tfmdata.shared -- we need to check shared, only when same features + if shared then + local processors = shared.processes + if processors and #processors > 0 then + usedfonts[font] = processors + nofused = nofused + 1 + elseif basemodepass then + basefont = { n, nil } + basefonts[#basefonts+1] = basefont + end + end + local resources = tfmdata.resources + variants = resources and resources.variants + variants = variants and next(variants) and variants or false + end + else + local tfmdata = fontdata[prevfont] + if tfmdata then + local resources = tfmdata.resources + variants = resources and resources.variants + variants = variants and next(variants) and variants or false + end + end + end + if variants then + local char = getchar(n) + if (char >= 0xFE00 and char <= 0xFE0F) or (char >= 0xE0100 and char <= 0xE01EF) then + local hash = variants[char] + if hash then + local p = getprev(n) + if p and getid(p) == glyph_code then + local variant = hash[getchar(p)] + if variant then + setchar(p,variant) + end + end + end + -- per generic user request we always remove selectors + if not redundant then + redundant = { n } + else + redundant[#redundant+1] = n + end + end + end + end + local nofbasefonts = #basefonts + if redundant then + for i=1,#redundant do + local r = redundant[i] + local p, n = getboth(r) + if r == head then + head = n + setprev(n) + else + setlink(p,n) + end + if nofbasefonts > 0 then + for i=1,nofbasefonts do + local bi = basefonts[i] + if r == bi[1] then + bi[1] = n + end + if r == bi[2] then + bi[2] = n + end + end + end + flush_node(r) + end + end + for d in traverse_id(disc_code,head) do + local _, _, r = getdisc(d) + if r then + for n in traverse_id(glyph_code,r) do + local font = getfont(n) + if font ~= prevfont then + prevfont = font + local used = usedfonts[font] + if not used then + local tfmdata = fontdata[font] -- + if tfmdata then + local shared = tfmdata.shared -- we need to check shared, only when same features + if shared then + local processors = shared.processes + if processors and #processors > 0 then + usedfonts[font] = processors + nofused = nofused + 1 + end + end + end + end + end + end + end + end + if next(usedfonts) then + for font, processors in next, usedfonts do + for i=1,#processors do + head = processors[i](head,font,0,direction,nofused) or head + end + end + end + if basemodepass and nofbasefonts > 0 then + for i=1,nofbasefonts do + local range = basefonts[i] + local start = range[1] + local stop = range[2] + if start then + local front = head == start + local prev, next + if stop then + next = getnext(stop) + start, stop = d_ligaturing(start,stop) + start, stop = d_kerning(start,stop) + else + prev = getprev(start) + start = d_ligaturing(start) + start = d_kerning(start) + end + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + if front and head ~= start then + head = start + end + end + end + end + end + return head +end + +local function basepass(head) + if basemodepass then + head = d_ligaturing(head) + head = d_kerning(head) + end + return head +end + +local protectpass = node.direct.protect_glyphs +local injectpass = nodes.injections.handler + +-- This is the only official public interface and this one can be hooked into a callback (chain) and +-- everything else can change!@ Functione being visibel doesn't mean that it's part of the api. + +function nodes.handlers.nodepass(head,...) + if head then + return tonode(nodepass(tonut(head),...)) + end +end + +function nodes.handlers.basepass(head) + if head then + return tonode(basepass(tonut(head))) + end +end + +function nodes.handlers.injectpass(head) + if head then + return tonode(injectpass(tonut(head))) + end +end + +function nodes.handlers.protectpass(head) + if head then + protectpass(tonut(head)) + return head + end +end + +function nodes.simple_font_handler(head,groupcode,size,packtype,direction) + if head then + head = tonut(head) + head = nodepass(head,groupcode,size,packtype,direction) + head = injectpass(head) + if not basemodepass then + head = basepass(head) + end + protectpass(head) + head = tonode(head) + end + return head +end diff --git a/tex/generic/context/luatex/luatex-fonts-lig.lua b/tex/generic/context/luatex/luatex-fonts-lig.lua index c5347aa19..4ce126533 100644 --- a/tex/generic/context/luatex/luatex-fonts-lig.lua +++ b/tex/generic/context/luatex/luatex-fonts-lig.lua @@ -2064,4 +2064,4 @@ fonts.handlers.otf.addfeature { ["name"]="collapse", ["prepend"]=true, ["type"]="ligature", -} \ No newline at end of file +} diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 7cfa8c61a..7d5408dca 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,15 +1,15 @@ -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 04/04/18 00:51:15 +-- merge date : 02/22/19 19:35:21 do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-lua']={ - 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" + 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" } local next,type,tonumber=next,type,tonumber LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$") @@ -17,133 +17,122 @@ LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5 LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1 LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10 if LUAVERSION<5.2 and jit then - MINORVERSION=2 - LUAVERSION=5.2 + MINORVERSION=2 + LUAVERSION=5.2 end -_LUAVERSION=LUAVERSION if not lpeg then - lpeg=require("lpeg") + lpeg=require("lpeg") end if loadstring then - local loadnormal=load - function load(first,...) - if type(first)=="string" then - return loadstring(first,...) - else - return loadnormal(first,...) - end + local loadnormal=load + function load(first,...) + if type(first)=="string" then + return loadstring(first,...) + else + return loadnormal(first,...) end + end else - loadstring=load + loadstring=load end if not ipairs then - local function iterate(a,i) - i=i+1 - local v=a[i] - if v~=nil then - return i,v - end - end - function ipairs(a) - return iterate,a,0 + local function iterate(a,i) + i=i+1 + local v=a[i] + if v~=nil then + return i,v end + end + function ipairs(a) + return iterate,a,0 + end end if not pairs then - function pairs(t) - return next,t - end + function pairs(t) + return next,t + end end if not table.unpack then - table.unpack=_G.unpack + table.unpack=_G.unpack elseif not unpack then - _G.unpack=table.unpack + _G.unpack=table.unpack end if not package.loaders then - package.loaders=package.searchers + package.loaders=package.searchers end local print,select,tostring=print,select,tostring local inspectors={} function setinspector(kind,inspector) - inspectors[kind]=inspector + inspectors[kind]=inspector end function inspect(...) - for s=1,select("#",...) do - local value=select(s,...) - if value==nil then - print("nil") - else - local done=false - local kind=type(value) - local inspector=inspectors[kind] - if inspector then - done=inspector(value) - if done then - break - end - end - for kind,inspector in next,inspectors do - done=inspector(value) - if done then - break - end - end - if not done then - print(tostring(value)) - end + for s=1,select("#",...) do + local value=select(s,...) + if value==nil then + print("nil") + else + local done=false + local kind=type(value) + local inspector=inspectors[kind] + if inspector then + done=inspector(value) + if done then + break + end + end + for kind,inspector in next,inspectors do + done=inspector(value) + if done then + break end + end + if not done then + print(tostring(value)) + end end + end end local dummy=function() end function optionalrequire(...) - local ok,result=xpcall(require,dummy,...) - if ok then - return result - end + local ok,result=xpcall(require,dummy,...) + if ok then + return result + end end if lua then - lua.mask=load([[τεχ = 1]]) and "utf" or "ascii" + lua.mask=load([[τεχ = 1]]) and "utf" or "ascii" end local flush=io.flush if flush then - local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end - local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end - local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end - local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end + local execute=os.execute if execute then function os.execute(...) flush() return execute(...) end end + local exec=os.exec if exec then function os.exec (...) flush() return exec (...) end end + local spawn=os.spawn if spawn then function os.spawn (...) flush() return spawn (...) end end + local popen=io.popen if popen then function io.popen (...) flush() return popen (...) end end end FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load if not FFISUPPORTED then - local okay;okay,ffi=pcall(require,"ffi") - FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load + local okay;okay,ffi=pcall(require,"ffi") + FFISUPPORTED=type(ffi)=="table" and ffi.os~="" and ffi.arch~="" and ffi.load end if not FFISUPPORTED then - ffi=nil + ffi=nil elseif not ffi.number then - ffi.number=tonumber -end -if not bit32 then - bit32=require("l-bit32") -end -local loaded=package.loaded -if not loaded["socket"] then loaded["socket"]=loaded["socket.core"] end -if not loaded["mime"] then loaded["mime"]=loaded["mime.core"] end -if not socket.mime then socket.mime=package.loaded["mime"] end -if not loaded["socket.mime"] then loaded["socket.mime"]=socket.mime end -if not loaded["socket.http"] then loaded["socket.http"]=socket.http end -if not loaded["socket.ftp"] then loaded["socket.ftp"]=socket.ftp end -if not loaded["socket.smtp"] then loaded["socket.smtp"]=socket.smtp end -if not loaded["socket.tp"] then loaded["socket.tp"]=socket.tp end -if not loaded["socket.url"] then loaded["socket.url"]=socket.url end + ffi.number=tonumber +end +if LUAVERSION>5.3 then + collectgarbage("generational") +end end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-lpeg']={ - 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" + 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" } lpeg=require("lpeg") local lpeg=lpeg @@ -154,7 +143,7 @@ local floor=math.floor local P,R,S,V,Ct,C,Cs,Cc,Cp,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.V,lpeg.Ct,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Cp,lpeg.Cmt local lpegtype,lpegmatch,lpegprint=lpeg.type,lpeg.match,lpeg.print if setinspector then - setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end) + setinspector("lpeg",function(v) if lpegtype(v) then lpegprint(v) return true end end) end lpeg.patterns=lpeg.patterns or {} local patterns=lpeg.patterns @@ -177,7 +166,7 @@ local underscore=P("_") local hexdigit=digit+lowercase+uppercase local hexdigits=hexdigit^1 local cr,lf,crlf=P("\r"),P("\n"),P("\r\n") -local newline=P("\r")*(P("\n")+P(true))+P("\n") +local newline=P("\r")*(P("\n")+P(true))+P("\n") local escaped=P("\\")*anything local squote=P("'") local dquote=P('"') @@ -186,9 +175,9 @@ local period=P(".") local comma=P(",") local utfbom_32_be=P('\000\000\254\255') local utfbom_32_le=P('\255\254\000\000') -local utfbom_16_be=P('\254\255') -local utfbom_16_le=P('\255\254') -local utfbom_8=P('\239\187\191') +local utfbom_16_be=P('\254\255') +local utfbom_16_le=P('\255\254') +local utfbom_8=P('\239\187\191') local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8 local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8") local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8") @@ -220,7 +209,7 @@ patterns.utf8character=utf8character patterns.validutf8=validutf8char patterns.validutf8char=validutf8char local eol=S("\n\r") -local spacer=S(" \t\f\v") +local spacer=S(" \t\f\v") local whitespace=eol+spacer local nonspacer=1-spacer local nonwhitespace=1-whitespace @@ -229,15 +218,15 @@ patterns.spacer=spacer patterns.whitespace=whitespace patterns.nonspacer=nonspacer patterns.nonwhitespace=nonwhitespace -local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) +local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) local fullstripper=whitespace^0*C((whitespace^0*nonwhitespace^1)^0) local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0)) local nospacer=Cs((whitespace^1/""+nonwhitespace^1)^0) local b_collapser=Cs(whitespace^0/""*(nonwhitespace^1+whitespace^1/" ")^0) -local e_collapser=Cs((whitespace^1*P(-1)/""+nonwhitespace^1+whitespace^1/" ")^0) +local e_collapser=Cs((whitespace^1*endofstring/""+nonwhitespace^1+whitespace^1/" ")^0) local m_collapser=Cs((nonwhitespace^1+whitespace^1/" ")^0) local b_stripper=Cs(spacer^0/""*(nonspacer^1+spacer^1/" ")^0) -local e_stripper=Cs((spacer^1*P(-1)/""+nonspacer^1+spacer^1/" ")^0) +local e_stripper=Cs((spacer^1*endofstring/""+nonspacer^1+spacer^1/" ")^0) local m_stripper=Cs((nonspacer^1+spacer^1/" ")^0) patterns.stripper=stripper patterns.fullstripper=fullstripper @@ -294,7 +283,7 @@ patterns.cpfloat=sign^-1*patterns.cpunsigned patterns.number=patterns.float+patterns.integer patterns.cnumber=patterns.cfloat+patterns.integer patterns.cpnumber=patterns.cpfloat+patterns.integer -patterns.oct=zero*octdigits +patterns.oct=zero*octdigits patterns.octal=patterns.oct patterns.HEX=zero*P("X")*(digit+uppercase)^1 patterns.hex=zero*P("x")*(digit+lowercase)^1 @@ -304,76 +293,84 @@ patterns.decafloat=sign^-1*(digit^0*period*digits+digits*period*digit^0+digits)* patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) -patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0)) -local function anywhere(pattern) - return P { P(pattern)+1*V(1) } +patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0)) +function anywhere(pattern) + return (1-P(pattern))^0*P(pattern) end lpeg.anywhere=anywhere function lpeg.instringchecker(p) - p=anywhere(p) - return function(str) - return lpegmatch(p,str) and true or false - end + p=anywhere(p) + return function(str) + return lpegmatch(p,str) and true or false + end end function lpeg.splitter(pattern,action) + if action then return (((1-P(pattern))^1)/action+1)^0 + else + return (Cs((1-P(pattern))^1)+1)^0 + end end function lpeg.tsplitter(pattern,action) + if action then return Ct((((1-P(pattern))^1)/action+1)^0) + else + return Ct((Cs((1-P(pattern))^1)+1)^0) + end end local splitters_s,splitters_m,splitters_t={},{},{} local function splitat(separator,single) - local splitter=(single and splitters_s[separator]) or splitters_m[separator] - if not splitter then - separator=P(separator) - local other=C((1-separator)^0) - if single then - local any=anything - splitter=other*(separator*C(any^0)+"") - splitters_s[separator]=splitter - else - splitter=other*(separator*other)^0 - splitters_m[separator]=splitter - end + local splitter=(single and splitters_s[separator]) or splitters_m[separator] + if not splitter then + separator=P(separator) + local other=C((1-separator)^0) + if single then + local any=anything + splitter=other*(separator*C(any^0)+"") + splitters_s[separator]=splitter + else + splitter=other*(separator*other)^0 + splitters_m[separator]=splitter end - return splitter + end + return splitter end local function tsplitat(separator) - local splitter=splitters_t[separator] - if not splitter then - splitter=Ct(splitat(separator)) - splitters_t[separator]=splitter - end - return splitter + local splitter=splitters_t[separator] + if not splitter then + splitter=Ct(splitat(separator)) + splitters_t[separator]=splitter + end + return splitter end lpeg.splitat=splitat lpeg.tsplitat=tsplitat function string.splitup(str,separator) - if not separator then - separator="," - end - return lpegmatch(splitters_m[separator] or splitat(separator),str) + if not separator then + separator="," + end + return lpegmatch(splitters_m[separator] or splitat(separator),str) end local cache={} function lpeg.split(separator,str) + local c=cache[separator] + if not c then + c=tsplitat(separator) + cache[separator]=c + end + return lpegmatch(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 + c=tsplitat(separator) + cache[separator]=c end return lpegmatch(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 } - end + else + return { str } + end end local spacing=patterns.spacer^0*newline local empty=spacing*Cc("") @@ -383,505 +380,463 @@ patterns.textline=content local linesplitter=tsplitat(newline) patterns.linesplitter=linesplitter function string.splitlines(str) - return lpegmatch(linesplitter,str) + return lpegmatch(linesplitter,str) end local cache={} function lpeg.checkedsplit(separator,str) - local c=cache[separator] - if not c then - separator=P(separator) - local other=C((1-separator)^1) - c=Ct(separator^0*other*(separator^1*other)^0) - cache[separator]=c - end - return lpegmatch(c,str) + local c=cache[separator] + if not c then + separator=P(separator) + local other=C((1-separator)^1) + c=Ct(separator^0*other*(separator^1*other)^0) + cache[separator]=c + end + return lpegmatch(c,str) end function string.checkedsplit(str,separator) - local c=cache[separator] - if not c then - separator=P(separator) - local other=C((1-separator)^1) - c=Ct(separator^0*other*(separator^1*other)^0) - cache[separator]=c - end - return lpegmatch(c,str) -end -local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end -local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end + local c=cache[separator] + if not c then + separator=P(separator) + local other=C((1-separator)^1) + c=Ct(separator^0*other*(separator^1*other)^0) + cache[separator]=c + end + return lpegmatch(c,str) +end +local function f2(s) local c1,c2=byte(s,1,2) return c1*64+c2-12416 end +local function f3(s) local c1,c2,c3=byte(s,1,3) return (c1*64+c2)*64+c3-925824 end local function f4(s) local c1,c2,c3,c4=byte(s,1,4) return ((c1*64+c2)*64+c3)*64+c4-63447168 end local utf8byte=patterns.utf8one/byte+patterns.utf8two/f2+patterns.utf8three/f3+patterns.utf8four/f4 patterns.utf8byte=utf8byte local cache={} function lpeg.stripper(str) - if type(str)=="string" then - local s=cache[str] - if not s then - s=Cs(((S(str)^1)/""+1)^0) - cache[str]=s - end - return s - else - return Cs(((str^1)/""+1)^0) + if type(str)=="string" then + local s=cache[str] + if not s then + s=Cs(((S(str)^1)/""+1)^0) + cache[str]=s end + return s + else + return Cs(((str^1)/""+1)^0) + end end local cache={} function lpeg.keeper(str) - if type(str)=="string" then - local s=cache[str] - if not s then - s=Cs((((1-S(str))^1)/""+1)^0) - cache[str]=s - end - return s - else - return Cs((((1-str)^1)/""+1)^0) + if type(str)=="string" then + local s=cache[str] + if not s then + s=Cs((((1-S(str))^1)/""+1)^0) + cache[str]=s end + return s + else + return Cs((((1-str)^1)/""+1)^0) + end end function lpeg.frontstripper(str) - return (P(str)+P(true))*Cs(anything^0) + return (P(str)+P(true))*Cs(anything^0) end function lpeg.endstripper(str) - return Cs((1-P(str)*endofstring)^0) + return Cs((1-P(str)*endofstring)^0) end function lpeg.replacer(one,two,makefunction,isutf) - local pattern - local u=isutf and utf8char or 1 - if type(one)=="table" then - local no=#one - local p=P(false) - if no==0 then - for k,v in next,one do - p=p+P(k)/v - end - pattern=Cs((p+u)^0) - elseif no==1 then - local o=one[1] - one,two=P(o[1]),o[2] - pattern=Cs((one/two+u)^0) - else - for i=1,no do - local o=one[i] - p=p+P(o[1])/o[2] - end - pattern=Cs((p+u)^0) - end + local pattern + local u=isutf and utf8char or 1 + if type(one)=="table" then + local no=#one + local p=P(false) + if no==0 then + for k,v in next,one do + p=p+P(k)/v + end + pattern=Cs((p+u)^0) + elseif no==1 then + local o=one[1] + one,two=P(o[1]),o[2] + pattern=Cs((one/two+u)^0) else - pattern=Cs((P(one)/(two or "")+u)^0) - end - if makefunction then - return function(str) - return lpegmatch(pattern,str) - end - else - return pattern + for i=1,no do + local o=one[i] + p=p+P(o[1])/o[2] + end + pattern=Cs((p+u)^0) + end + else + pattern=Cs((P(one)/(two or "")+u)^0) + end + if makefunction then + return function(str) + return lpegmatch(pattern,str) end + else + return pattern + end end function lpeg.finder(lst,makefunction,isutf) - local pattern - if type(lst)=="table" then - pattern=P(false) - if #lst==0 then - for k,v in next,lst do - pattern=pattern+P(k) - end - else - for i=1,#lst do - pattern=pattern+P(lst[i]) - end - end - else - pattern=P(lst) - end - if isutf then - pattern=((utf8char or 1)-pattern)^0*pattern - else - pattern=(1-pattern)^0*pattern - end - if makefunction then - return function(str) - return lpegmatch(pattern,str) - end + local pattern + if type(lst)=="table" then + pattern=P(false) + if #lst==0 then + for k,v in next,lst do + pattern=pattern+P(k) + end else - return pattern + for i=1,#lst do + pattern=pattern+P(lst[i]) + end + end + else + pattern=P(lst) + end + if isutf then + pattern=((utf8char or 1)-pattern)^0*pattern + else + pattern=(1-pattern)^0*pattern + end + if makefunction then + return function(str) + return lpegmatch(pattern,str) end + else + return pattern + end end local splitters_f,splitters_s={},{} function lpeg.firstofsplit(separator) - local splitter=splitters_f[separator] - if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0) - splitters_f[separator]=splitter - end - return splitter + local splitter=splitters_f[separator] + if not splitter then + local pattern=P(separator) + splitter=C((1-pattern)^0) + splitters_f[separator]=splitter + end + return splitter end function lpeg.secondofsplit(separator) - local splitter=splitters_s[separator] - if not splitter then - local pattern=P(separator) - splitter=(1-pattern)^0*pattern*C(anything^0) - splitters_s[separator]=splitter - end - return splitter + local splitter=splitters_s[separator] + if not splitter then + local pattern=P(separator) + splitter=(1-pattern)^0*pattern*C(anything^0) + splitters_s[separator]=splitter + end + return splitter end local splitters_s,splitters_p={},{} function lpeg.beforesuffix(separator) - local splitter=splitters_s[separator] - if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0)*pattern*endofstring - splitters_s[separator]=splitter - end - return splitter + local splitter=splitters_s[separator] + if not splitter then + local pattern=P(separator) + splitter=C((1-pattern)^0)*pattern*endofstring + splitters_s[separator]=splitter + end + return splitter end function lpeg.afterprefix(separator) - local splitter=splitters_p[separator] - if not splitter then - local pattern=P(separator) - splitter=pattern*C(anything^0) - splitters_p[separator]=splitter - end - return splitter + local splitter=splitters_p[separator] + if not splitter then + local pattern=P(separator) + splitter=pattern*C(anything^0) + splitters_p[separator]=splitter + end + return splitter end function lpeg.balancer(left,right) - left,right=P(left),P(right) - return P { left*((1-left-right)+V(1))^0*right } + left,right=P(left),P(right) + return P { left*((1-left-right)+V(1))^0*right } end function lpeg.counter(pattern,action) - local n=0 - local pattern=(P(pattern)/function() n=n+1 end+anything)^0 - if action then - return function(str) n=0;lpegmatch(pattern,str);action(n) end - else - return function(str) n=0;lpegmatch(pattern,str);return n end - end -end -utf=utf or (unicode and unicode.utf8) or {} -local utfcharacters=utf and utf.characters or string.utfcharacters -local utfgmatch=utf and utf.gmatch -local utfchar=utf and utf.char -lpeg.UP=lpeg.P -if utfcharacters then - function lpeg.US(str) - local p=P(false) - for uc in utfcharacters(str) do - p=p+P(uc) - end - return p - end -elseif utfgmatch then - function lpeg.US(str) - local p=P(false) - for uc in utfgmatch(str,".") do - p=p+P(uc) - end - return p - end -else - function lpeg.US(str) - local p=P(false) - local f=function(uc) - p=p+P(uc) - end - lpegmatch((utf8char/f)^0,str) - return p - end -end -local range=utf8byte*utf8byte+Cc(false) -function lpeg.UR(str,more) - local first,last - if type(str)=="number" then - first=str - last=more or first - else - first,last=lpegmatch(range,str) - if not last then - return P(str) - end - end - if first==last then - return P(str) - elseif utfchar and (last-first<8) then - local p=P(false) - for i=first,last do - p=p+P(utfchar(i)) - end - return p - else - local f=function(b) - return b>=first and b<=last - end - return utf8byte/f - end + local n=0 + local pattern=(P(pattern)/function() n=n+1 end+anything)^0 + if action then + return function(str) n=0;lpegmatch(pattern,str);action(n) end + else + return function(str) n=0;lpegmatch(pattern,str);return n end + end end function lpeg.is_lpeg(p) - return p and lpegtype(p)=="pattern" + return p and lpegtype(p)=="pattern" end function lpeg.oneof(list,...) - if type(list)~="table" then - list={ list,... } - end - local p=P(list[1]) - for l=2,#list do - p=p+P(list[l]) - end - return p + if type(list)~="table" then + list={ list,... } + end + local p=P(list[1]) + for l=2,#list do + p=p+P(list[l]) + end + return p end local sort=table.sort local function copyindexed(old) - local new={} - for i=1,#old do - new[i]=old - end - return new + local new={} + for i=1,#old do + new[i]=old + end + return new end local function sortedkeys(tab) - local keys,s={},0 - for key,_ in next,tab do - s=s+1 - keys[s]=key - end - sort(keys) - return keys + local keys,s={},0 + for key,_ in next,tab do + s=s+1 + keys[s]=key + end + sort(keys) + return keys end function lpeg.append(list,pp,delayed,checked) - local p=pp - if #list>0 then - local keys=copyindexed(list) - sort(keys) - for i=#keys,1,-1 do - local k=keys[i] - if p then - p=P(k)+p - else - p=P(k) - end - end - elseif delayed then - local keys=sortedkeys(list) + local p=pp + if #list>0 then + local keys=copyindexed(list) + sort(keys) + for i=#keys,1,-1 do + local k=keys[i] + if p then + p=P(k)+p + else + p=P(k) + end + end + elseif delayed then + local keys=sortedkeys(list) + if p then + for i=1,#keys,1 do + local k=keys[i] + local v=list[k] + p=P(k)/list+p + end + else + for i=1,#keys do + local k=keys[i] + local v=list[k] if p then - for i=1,#keys,1 do - local k=keys[i] - local v=list[k] - p=P(k)/list+p - end + p=P(k)+p else - for i=1,#keys do - local k=keys[i] - local v=list[k] - if p then - p=P(k)+p - else - p=P(k) - end - end - if p then - p=p/list - end + p=P(k) end - elseif checked then - local keys=sortedkeys(list) - for i=1,#keys do - local k=keys[i] - local v=list[k] - if p then - if k==v then - p=P(k)+p - else - p=P(k)/v+p - end - else - if k==v then - p=P(k) - else - p=P(k)/v - end - end + end + if p then + p=p/list + end + end + elseif checked then + local keys=sortedkeys(list) + for i=1,#keys do + local k=keys[i] + local v=list[k] + if p then + if k==v then + p=P(k)+p + else + p=P(k)/v+p end - else - local keys=sortedkeys(list) - for i=1,#keys do - local k=keys[i] - local v=list[k] - if p then - p=P(k)/v+p - else - p=P(k)/v - end + else + if k==v then + p=P(k) + else + p=P(k)/v end + end end - return p + else + local keys=sortedkeys(list) + for i=1,#keys do + local k=keys[i] + local v=list[k] + if p then + p=P(k)/v+p + else + p=P(k)/v + end + end + end + return p end local p_false=P(false) local p_true=P(true) local lower=utf and utf.lower or string.lower local upper=utf and utf.upper or string.upper function lpeg.setutfcasers(l,u) - lower=l or lower - upper=u or upper + lower=l or lower + upper=u or upper end local function make1(t,rest) - local p=p_false - local keys=sortedkeys(t) - for i=1,#keys do - local k=keys[i] - if k~="" then - local v=t[k] - if v==true then - p=p+P(k)*p_true - elseif v==false then - else - p=p+P(k)*make1(v,v[""]) - end - end - end - if rest then - p=p+p_true - end - return p + local p=p_false + local keys=sortedkeys(t) + for i=1,#keys do + local k=keys[i] + if k~="" then + local v=t[k] + if v==true then + p=p+P(k)*p_true + elseif v==false then + else + p=p+P(k)*make1(v,v[""]) + end + end + end + if rest then + p=p+p_true + end + return p end local function make2(t,rest) - local p=p_false - local keys=sortedkeys(t) - for i=1,#keys do - local k=keys[i] - if k~="" then - local v=t[k] - if v==true then - p=p+(P(lower(k))+P(upper(k)))*p_true - elseif v==false then - else - p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""]) - end - end - end - if rest then - p=p+p_true - end - return p -end -function lpeg.utfchartabletopattern(list,insensitive) - local tree={} - local n=#list - if n==0 then - for s in next,list do - local t=tree - local p,pk - for c in gmatch(s,".") do - if t==true then - t={ [c]=true,[""]=true } - p[pk]=t - p=t - t=false - elseif t==false then - t={ [c]=false } - p[pk]=t - p=t - t=false - else - local tc=t[c] - if not tc then - tc=false - t[c]=false - end - p=t - t=tc - end - pk=c - end - if t==false then - p[pk]=true - elseif t==true then - else - t[""]=true - end - end - else - for i=1,n do - local s=list[i] - local t=tree - local p,pk - for c in gmatch(s,".") do - if t==true then - t={ [c]=true,[""]=true } - p[pk]=t - p=t - t=false - elseif t==false then - t={ [c]=false } - p[pk]=t - p=t - t=false - else - local tc=t[c] - if not tc then - tc=false - t[c]=false - end - p=t - t=tc - end - pk=c - end - if t==false then - p[pk]=true - elseif t==true then - else - t[""]=true - end - end - end - return (insensitive and make2 or make1)(tree) + local p=p_false + local keys=sortedkeys(t) + for i=1,#keys do + local k=keys[i] + if k~="" then + local v=t[k] + if v==true then + p=p+(P(lower(k))+P(upper(k)))*p_true + elseif v==false then + else + p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""]) + end + end + end + if rest then + p=p+p_true + end + return p +end +local function utfchartabletopattern(list,insensitive) + local tree={} + local n=#list + if n==0 then + for s in next,list do + local t=tree + local p,pk + for c in gmatch(s,".") do + if t==true then + t={ [c]=true,[""]=true } + p[pk]=t + p=t + t=false + elseif t==false then + t={ [c]=false } + p[pk]=t + p=t + t=false + else + local tc=t[c] + if not tc then + tc=false + t[c]=false + end + p=t + t=tc + end + pk=c + end + if t==false then + p[pk]=true + elseif t==true then + else + t[""]=true + end + end + else + for i=1,n do + local s=list[i] + local t=tree + local p,pk + for c in gmatch(s,".") do + if t==true then + t={ [c]=true,[""]=true } + p[pk]=t + p=t + t=false + elseif t==false then + t={ [c]=false } + p[pk]=t + p=t + t=false + else + local tc=t[c] + if not tc then + tc=false + t[c]=false + end + p=t + t=tc + end + pk=c + end + if t==false then + p[pk]=true + elseif t==true then + else + t[""]=true + end + end + end + return (insensitive and make2 or make1)(tree) +end +lpeg.utfchartabletopattern=utfchartabletopattern +function lpeg.utfreplacer(list,insensitive) + local pattern=Cs((utfchartabletopattern(list,insensitive)/list+utf8character)^0) + return function(str) + return lpegmatch(pattern,str) or str + end end patterns.containseol=lpeg.finder(eol) local function nextstep(n,step,result) - local m=n%step - local d=floor(n/step) - if d>0 then - local v=V(tostring(step)) - local s=result.start - for i=1,d do - if s then - s=v*s - else - s=v - end - end - result.start=s - end - if step>1 and result.start then - local v=V(tostring(step/2)) - result[tostring(step)]=v*v - end - if step>0 then - return nextstep(m,step/2,result) - else - return result - end + local m=n%step + local d=floor(n/step) + if d>0 then + local v=V(tostring(step)) + local s=result.start + for i=1,d do + if s then + s=v*s + else + s=v + end + end + result.start=s + end + if step>1 and result.start then + local v=V(tostring(step/2)) + result[tostring(step)]=v*v + end + if step>0 then + return nextstep(m,step/2,result) + else + return result + end end function lpeg.times(pattern,n) - return P(nextstep(n,2^16,{ "start",["1"]=pattern })) -end -local trailingzeros=zero^0*-digit -local case_1=period*trailingzeros/"" -local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"") -local number=digits*(case_1+case_2) -local stripper=Cs((number+1)^0) -lpeg.patterns.stripzeros=stripper + return P(nextstep(n,2^16,{ "start",["1"]=pattern })) +end +do + local trailingzeros=zero^0*-digit + local stripper=Cs(( + digits*( + period*trailingzeros/""+period*(digit-trailingzeros)^1*(trailingzeros/"") + )+1 + )^0) + lpeg.patterns.stripzeros=stripper + local nonzero=digit-zero + local trailingzeros=zero^1*endofstring + local stripper=Cs((1-period)^0*( + period*trailingzeros/""+period*(nonzero^1+(trailingzeros/"")+zero^1)^0+endofstring + )) + lpeg.patterns.stripzero=stripper +end local byte_to_HEX={} local byte_to_hex={} local byte_to_dec={} local hex_to_byte={} for i=0,255 do - local H=format("%02X",i) - local h=format("%02x",i) - local d=format("%03i",i) - local c=char(i) - byte_to_HEX[c]=H - byte_to_hex[c]=h - byte_to_dec[c]=d - hex_to_byte[h]=c - hex_to_byte[H]=c + local H=format("%02X",i) + local h=format("%02x",i) + local d=format("%03i",i) + local c=char(i) + byte_to_HEX[c]=H + byte_to_hex[c]=h + byte_to_dec[c]=d + hex_to_byte[h]=c + hex_to_byte[H]=c end local hextobyte=P(2)/hex_to_byte local bytetoHEX=P(1)/byte_to_HEX @@ -900,32 +855,47 @@ patterns.bytestoHEX=bytestoHEX patterns.bytestohex=bytestohex patterns.bytestodec=bytestodec function string.toHEX(s) - if not s or s=="" then - return s - else - return lpegmatch(bytestoHEX,s) - end + if not s or s=="" then + return s + else + return lpegmatch(bytestoHEX,s) + end end function string.tohex(s) - if not s or s=="" then - return s - else - return lpegmatch(bytestohex,s) - end + if not s or s=="" then + return s + else + return lpegmatch(bytestohex,s) + end end function string.todec(s) - if not s or s=="" then - return s - else - return lpegmatch(bytestodec,s) - end + if not s or s=="" then + return s + else + return lpegmatch(bytestodec,s) + end end function string.tobytes(s) - if not s or s=="" then - return s - else - return lpegmatch(hextobytes,s) - end + if not s or s=="" then + return s + else + return lpegmatch(hextobytes,s) + end +end +local patterns={} +local function containsws(what) + local p=patterns[what] + if not p then + local p1=P(what)*(whitespace+endofstring)*Cc(true) + local p2=whitespace*P(p1) + p=P(p1)+P(1-p2)^0*p2+Cc(false) + patterns[what]=p + end + return p +end +lpeg.containsws=containsws +function string.containsws(str,what) + return lpegmatch(patterns[what] or containsws(what),str) end end -- closure @@ -933,11 +903,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-functions']={ - 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" + 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" } functions=functions or {} function functions.dummy() end @@ -947,11 +917,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-string']={ - 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" + 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" } local string=string local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower @@ -959,25 +929,25 @@ local lpegmatch,patterns=lpeg.match,lpeg.patterns local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote function string.unquoted(str) - return lpegmatch(unquoted,str) or str + return lpegmatch(unquoted,str) or str end function string.quoted(str) - return format("%q",str) + return format("%q",str) end function string.count(str,pattern) - local n=0 - for _ in gmatch(str,pattern) do - n=n+1 - end - return n + local n=0 + for _ in gmatch(str,pattern) do + n=n+1 + end + return n end function string.limit(str,n,sentinel) - if #str>n then - sentinel=sentinel or "..." - return sub(str,1,(n-#sentinel))..sentinel - else - return str - end + if #str>n then + sentinel=sentinel or "..." + return sub(str,1,(n-#sentinel))..sentinel + else + return str + end end local stripper=patterns.stripper local fullstripper=patterns.fullstripper @@ -985,81 +955,81 @@ local collapser=patterns.collapser local nospacer=patterns.nospacer local longtostring=patterns.longtostring function string.strip(str) - return str and lpegmatch(stripper,str) or "" + return str and lpegmatch(stripper,str) or "" end function string.fullstrip(str) - return str and lpegmatch(fullstripper,str) or "" + return str and lpegmatch(fullstripper,str) or "" end function string.collapsespaces(str) - return str and lpegmatch(collapser,str) or "" + return str and lpegmatch(collapser,str) or "" end function string.nospaces(str) - return str and lpegmatch(nospacer,str) or "" + return str and lpegmatch(nospacer,str) or "" end function string.longtostring(str) - return str and lpegmatch(longtostring,str) or "" + return str and lpegmatch(longtostring,str) or "" end local pattern=P(" ")^0*P(-1) function string.is_empty(str) - if not str or str=="" then - return true - else - return lpegmatch(pattern,str) and true or false - end + if not str or str=="" then + return true + else + return lpegmatch(pattern,str) and true or false + end end local anything=patterns.anything local allescapes=Cc("%")*S(".-+%?()[]*") -local someescapes=Cc("%")*S(".-+%()[]") -local matchescapes=Cc(".")*S("*?") +local someescapes=Cc("%")*S(".-+%()[]") +local matchescapes=Cc(".")*S("*?") local pattern_a=Cs ((allescapes+anything )^0 ) local pattern_b=Cs ((someescapes+matchescapes+anything )^0 ) local pattern_c=Cs (Cc("^")*(someescapes+matchescapes+anything )^0*Cc("$") ) function string.escapedpattern(str,simple) - return lpegmatch(simple and pattern_b or pattern_a,str) + return lpegmatch(simple and pattern_b or pattern_a,str) end function string.topattern(str,lowercase,strict) - if str=="" or type(str)~="string" then - return ".*" - elseif strict then - str=lpegmatch(pattern_c,str) - else - str=lpegmatch(pattern_b,str) - end - if lowercase then - return lower(str) - else - return str - end + if str=="" or type(str)~="string" then + return ".*" + elseif strict then + str=lpegmatch(pattern_c,str) + else + str=lpegmatch(pattern_b,str) + end + if lowercase then + return lower(str) + else + return str + end end function string.valid(str,default) - return (type(str)=="string" and str~="" and str) or default or nil + return (type(str)=="string" and str~="" and str) or default or nil end string.itself=function(s) return s end local pattern_c=Ct(C(1)^0) local pattern_b=Ct((C(1)/byte)^0) function string.totable(str,bytes) - return lpegmatch(bytes and pattern_b or pattern_c,str) + return lpegmatch(bytes and pattern_b or pattern_c,str) end local replacer=lpeg.replacer("@","%%") function string.tformat(fmt,...) - return format(lpegmatch(replacer,fmt),...) + return format(lpegmatch(replacer,fmt),...) end string.quote=string.quoted string.unquote=string.unquoted if not string.bytetable then - local limit=5000 - function string.bytetable(str) - local n=#str - if n>limit then - local t={ byte(str,1,limit) } - for i=limit+1,n do - t[i]=byte(str,i) - end - return t - else - return { byte(str,1,n) } - end + local limit=5000 + function string.bytetable(str) + local n=#str + if n>limit then + local t={ byte(str,1,limit) } + for i=limit+1,n do + t[i]=byte(str,i) + end + return t + else + return { byte(str,1,n) } end + end end end -- closure @@ -1067,163 +1037,169 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-table']={ - 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" + 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" } local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select local table,string=table,string -local concat,sort,insert,remove=table.concat,table.sort,table.insert,table.remove +local concat,sort=table.concat,table.sort local format,lower,dump=string.format,string.lower,string.dump local getmetatable,setmetatable=getmetatable,setmetatable -local getinfo=debug.getinfo local lpegmatch,patterns=lpeg.match,lpeg.patterns local floor=math.floor local stripper=patterns.stripper function table.getn(t) - return t and #t + return t and #t end function table.strip(tab) - local lst,l={},0 - for i=1,#tab do - local s=lpegmatch(stripper,tab[i]) or "" - if s=="" then - else - l=l+1 - lst[l]=s - end + local lst={} + local l=0 + for i=1,#tab do + local s=lpegmatch(stripper,tab[i]) or "" + if s=="" then + else + l=l+1 + lst[l]=s end - return lst + end + return lst 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 {} + if t then + local keys={} + local k=0 + for key in next,t do + k=k+1 + keys[k]=key end + return keys + else + return {} + end end local function compare(a,b) - local ta=type(a) - if ta=="number" then - local tb=type(b) - if ta==tb then - return a1 then - sort(srt) - end - return srt - else - return {} + if tab then + local srt={} + local s=0 + for key in next,tab do + if type(key)=="string" then + s=s+1 + srt[s]=key + end + end + if s>1 then + sort(srt) end + return srt + else + return {} + end end local function sortedindexonly(tab) - if tab then - local srt,s={},0 - for key in next,tab do - if type(key)=="number" then - s=s+1 - srt[s]=key - end - end - if s>1 then - sort(srt) - end - return srt - else - return {} + if tab then + local srt={} + local s=0 + for key in next,tab do + if type(key)=="number" then + s=s+1 + srt[s]=key + end + end + if s>1 then + sort(srt) end + return srt + else + return {} + end end local function sortedhashkeys(tab,cmp) - if tab then - local srt,s={},0 - for key in next,tab do - if key then - s=s+1 - srt[s]=key - end - end - if s>1 then - sort(srt,cmp) - end - return srt - else - return {} + if tab then + local srt={} + local s=0 + for key in next,tab do + if key then + s=s+1 + srt[s]=key + end + end + if s>1 then + sort(srt,cmp) end + return srt + else + return {} + end end function table.allkeys(t) - local keys={} - for k,v in next,t do - for k in next,v do - keys[k]=true - end + local keys={} + for k,v in next,t do + for k in next,v do + keys[k]=true end - return sortedkeys(keys) + end + return sortedkeys(keys) end table.sortedkeys=sortedkeys table.sortedhashonly=sortedhashonly @@ -1231,907 +1207,944 @@ table.sortedindexonly=sortedindexonly table.sortedhashkeys=sortedhashkeys local function nothing() end local function sortedhash(t,cmp) - if t then - local s - if cmp then - s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end) - else - s=sortedkeys(t) - end - local m=#s - if m==1 then - return next,t - elseif m>0 then - local n=0 - return function() - if n0 then + local n=0 + return function() + if n0 then - local n=0 - for _,v in next,t do - n=n+1 - if type(v)=="table" then - return nil - end - end - local haszero=rawget(t,0) - if n==nt then - local tt={} - for i=1,nt do - local v=t[i] - local tv=type(v) - if tv=="number" then - if hexify then - tt[i]=format("0x%X",v) - else - tt[i]=v - end - elseif tv=="string" then - tt[i]=format("%q",v) - elseif tv=="boolean" then - tt[i]=v and "true" or "false" - else - return nil - end - end - return tt - elseif haszero and (n==nt+1) then - local tt={} - for i=0,nt do - local v=t[i] - local tv=type(v) - if tv=="number" then - if hexify then - tt[i+1]=format("0x%X",v) - else - tt[i+1]=v - end - elseif tv=="string" then - tt[i+1]=format("%q",v) - elseif tv=="boolean" then - tt[i+1]=v and "true" or "false" - else - return nil - end - end - tt[1]="[0] = "..tt[1] - return tt + local nt=#t + if nt>0 then + local n=0 + for _,v in next,t do + n=n+1 + if type(v)=="table" then + return nil + end + end + local haszero=rawget(t,0) + if n==nt then + local tt={} + for i=1,nt do + local v=t[i] + local tv=type(v) + if tv=="number" then + if hexify then + tt[i]=format("0x%X",v) + else + tt[i]=v + end + elseif tv=="string" then + tt[i]=format("%q",v) + elseif tv=="boolean" then + tt[i]=v and "true" or "false" + else + return nil + end + end + return tt + elseif haszero and (n==nt+1) then + local tt={} + for i=0,nt do + local v=t[i] + local tv=type(v) + if tv=="number" then + if hexify then + tt[i+1]=format("0x%X",v) + else + tt[i+1]=v + end + elseif tv=="string" then + tt[i+1]=format("%q",v) + elseif tv=="boolean" then + tt[i+1]=v and "true" or "false" + else + return nil end + end + tt[1]="[0] = "..tt[1] + return tt end - return nil + end + return nil end table.is_simple_table=is_simple_table local propername=patterns.propername local function dummy() end local function do_serialize(root,name,depth,level,indexed) - if level>0 then - depth=depth.." " - if indexed then - handle(format("%s{",depth)) + if level>0 then + depth=depth.." " + if indexed then + handle(format("%s{",depth)) + else + local tn=type(name) + if tn=="number" then + if hexify then + handle(format("%s[0x%X]={",depth,name)) else - local tn=type(name) - if tn=="number" then - if hexify then - handle(format("%s[0x%X]={",depth,name)) - else - handle(format("%s[%s]={",depth,name)) - end - elseif tn=="string" then - if noquotes and not reserved[name] and lpegmatch(propername,name) then - handle(format("%s%s={",depth,name)) - else - handle(format("%s[%q]={",depth,name)) - end - elseif tn=="boolean" then - handle(format("%s[%s]={",depth,name and "true" or "false")) + handle(format("%s[%s]={",depth,name)) + end + elseif tn=="string" then + if noquotes and not reserved[name] and lpegmatch(propername,name) then + handle(format("%s%s={",depth,name)) + else + handle(format("%s[%q]={",depth,name)) + end + elseif tn=="boolean" then + handle(format("%s[%s]={",depth,name and "true" or "false")) + else + handle(format("%s{",depth)) + end + end + end + if root and next(root)~=nil then + local first=nil + local last=0 + if compact then + last=#root + for k=1,last do + if rawget(root,k)==nil then + last=k-1 + break + end + end + if last>0 then + first=1 + end + end + local sk=sortedkeys(root) + for i=1,#sk do + local k=sk[i] + local v=root[k] + local tv=type(v) + local tk=type(k) + if compact and first and tk=="number" and k>=first and k<=last then + if tv=="number" then + if hexify then + handle(format("%s 0x%X,",depth,v)) + else + handle(format("%s %s,",depth,v)) + end + elseif tv=="string" then + handle(format("%s %q,",depth,v)) + elseif tv=="table" then + if next(v)==nil then + handle(format("%s {},",depth)) + elseif inline then + local st=is_simple_table(v,hexify) + if st then + handle(format("%s { %s },",depth,concat(st,", "))) else - handle(format("%s{",depth)) + do_serialize(v,k,depth,level+1,true) end + else + do_serialize(v,k,depth,level+1,true) + end + elseif tv=="boolean" then + handle(format("%s %s,",depth,v and "true" or "false")) + elseif tv=="function" then + if functions then + handle(format('%s load(%q),',depth,dump(v))) + else + handle(format('%s "function",',depth)) + end + else + handle(format("%s %q,",depth,tostring(v))) end - end - if root and next(root)~=nil then - local first,last=nil,0 - if compact then - last=#root - for k=1,last do - if rawget(root,k)==nil then - last=k-1 - break - end + elseif k=="__p__" then + if false then + handle(format("%s __p__=nil,",depth)) + end + elseif tv=="number" then + if tk=="number" then + if hexify then + handle(format("%s [0x%X]=0x%X,",depth,k,v)) + else + handle(format("%s [%s]=%s,",depth,k,v)) + end + elseif tk=="boolean" then + if hexify then + handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v)) + else + handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + end + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + if hexify then + handle(format("%s %s=0x%X,",depth,k,v)) + else + handle(format("%s %s=%s,",depth,k,v)) + end + else + if hexify then + handle(format("%s [%q]=0x%X,",depth,k,v)) + else + handle(format("%s [%q]=%s,",depth,k,v)) + end + end + elseif tv=="string" then + if tk=="number" then + if hexify then + handle(format("%s [0x%X]=%q,",depth,k,v)) + else + handle(format("%s [%s]=%q,",depth,k,v)) + end + elseif tk=="boolean" then + handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s=%q,",depth,k,v)) + else + handle(format("%s [%q]=%q,",depth,k,v)) + end + elseif tv=="table" then + if next(v)==nil then + if tk=="number" then + if hexify then + handle(format("%s [0x%X]={},",depth,k)) + else + handle(format("%s [%s]={},",depth,k)) end - if last>0 then - first=1 + elseif tk=="boolean" then + handle(format("%s [%s]={},",depth,k and "true" or "false")) + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s={},",depth,k)) + else + handle(format("%s [%q]={},",depth,k)) + end + elseif inline then + local st=is_simple_table(v,hexify) + if st then + if tk=="number" then + if hexify then + handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", "))) + else + handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) + end + elseif tk=="boolean" then + handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s={ %s },",depth,k,concat(st,", "))) + else + handle(format("%s [%q]={ %s },",depth,k,concat(st,", "))) end + else + do_serialize(v,k,depth,level+1) + end + else + do_serialize(v,k,depth,level+1) end - local sk=sortedkeys(root) - for i=1,#sk do - local k=sk[i] - local v=root[k] - local tv=type(v) - local tk=type(k) - if compact and first and tk=="number" and k>=first and k<=last then - if tv=="number" then - if hexify then - handle(format("%s 0x%X,",depth,v)) - else - handle(format("%s %s,",depth,v)) - end - elseif tv=="string" then - handle(format("%s %q,",depth,v)) - elseif tv=="table" then - if next(v)==nil then - handle(format("%s {},",depth)) - elseif inline then - local st=is_simple_table(v,hexify) - if st then - handle(format("%s { %s },",depth,concat(st,", "))) - else - do_serialize(v,k,depth,level+1,true) - end - else - do_serialize(v,k,depth,level+1,true) - end - elseif tv=="boolean" then - handle(format("%s %s,",depth,v and "true" or "false")) - elseif tv=="function" then - if functions then - handle(format('%s load(%q),',depth,dump(v))) - else - handle(format('%s "function",',depth)) - end - else - handle(format("%s %q,",depth,tostring(v))) - end - elseif k=="__p__" then - if false then - handle(format("%s __p__=nil,",depth)) - end - elseif tv=="number" then - if tk=="number" then - if hexify then - handle(format("%s [0x%X]=0x%X,",depth,k,v)) - else - handle(format("%s [%s]=%s,",depth,k,v)) - end - elseif tk=="boolean" then - if hexify then - handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v)) - else - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) - end - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - if hexify then - handle(format("%s %s=0x%X,",depth,k,v)) - else - handle(format("%s %s=%s,",depth,k,v)) - end - else - if hexify then - handle(format("%s [%q]=0x%X,",depth,k,v)) - else - handle(format("%s [%q]=%s,",depth,k,v)) - end - end - elseif tv=="string" then - if tk=="number" then - if hexify then - handle(format("%s [0x%X]=%q,",depth,k,v)) - else - handle(format("%s [%s]=%q,",depth,k,v)) - end - elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%q,",depth,k,v)) - else - handle(format("%s [%q]=%q,",depth,k,v)) - end - elseif tv=="table" then - if next(v)==nil then - if tk=="number" then - if hexify then - handle(format("%s [0x%X]={},",depth,k)) - else - handle(format("%s [%s]={},",depth,k)) - end - elseif tk=="boolean" then - handle(format("%s [%s]={},",depth,k and "true" or "false")) - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s={},",depth,k)) - else - handle(format("%s [%q]={},",depth,k)) - end - elseif inline then - local st=is_simple_table(v,hexify) - if st then - if tk=="number" then - if hexify then - handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", "))) - else - handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) - end - elseif tk=="boolean" then - handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s={ %s },",depth,k,concat(st,", "))) - else - handle(format("%s [%q]={ %s },",depth,k,concat(st,", "))) - end - else - do_serialize(v,k,depth,level+1) - end - else - do_serialize(v,k,depth,level+1) - end - elseif tv=="boolean" then - if tk=="number" then - if hexify then - handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false")) - else - handle(format("%s [%s]=%s,",depth,k,v and "true" or "false")) - end - elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%s,",depth,k,v and "true" or "false")) - else - handle(format("%s [%q]=%s,",depth,k,v and "true" or "false")) - end - elseif tv=="function" then - if functions then - local f=getinfo(v).what=="C" and dump(dummy) or dump(v) - if tk=="number" then - if hexify then - handle(format("%s [0x%X]=load(%q),",depth,k,f)) - else - handle(format("%s [%s]=load(%q),",depth,k,f)) - end - elseif tk=="boolean" then - handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=load(%q),",depth,k,f)) - else - handle(format("%s [%q]=load(%q),",depth,k,f)) - end - end + elseif tv=="boolean" then + if tk=="number" then + if hexify then + handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false")) + else + handle(format("%s [%s]=%s,",depth,k,v and "true" or "false")) + end + elseif tk=="boolean" then + handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s=%s,",depth,k,v and "true" or "false")) + else + handle(format("%s [%q]=%s,",depth,k,v and "true" or "false")) + end + elseif tv=="function" then + if functions then + local getinfo=debug and debug.getinfo + if getinfo then + local f=getinfo(v).what=="C" and dump(dummy) or dump(v) + if tk=="number" then + if hexify then + handle(format("%s [0x%X]=load(%q),",depth,k,f)) + else + handle(format("%s [%s]=load(%q),",depth,k,f)) + end + elseif tk=="boolean" then + handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s=load(%q),",depth,k,f)) else - if tk=="number" then - if hexify then - handle(format("%s [0x%X]=%q,",depth,k,tostring(v))) - else - handle(format("%s [%s]=%q,",depth,k,tostring(v))) - end - elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) - elseif tk~="string" then - elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%q,",depth,k,tostring(v))) - else - handle(format("%s [%q]=%q,",depth,k,tostring(v))) - end + handle(format("%s [%q]=load(%q),",depth,k,f)) end + end end + else + if tk=="number" then + if hexify then + handle(format("%s [0x%X]=%q,",depth,k,tostring(v))) + else + handle(format("%s [%s]=%q,",depth,k,tostring(v))) + end + elseif tk=="boolean" then + handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) + elseif tk~="string" then + elseif noquotes and not reserved[k] and lpegmatch(propername,k) then + handle(format("%s %s=%q,",depth,k,tostring(v))) + else + handle(format("%s [%q]=%q,",depth,k,tostring(v))) + end + end end - if level>0 then - handle(format("%s},",depth)) - end + end + if level>0 then + handle(format("%s},",depth)) + end end local function serialize(_handle,root,name,specification) - local tname=type(name) - if type(specification)=="table" then - noquotes=specification.noquotes - hexify=specification.hexify - handle=_handle or specification.handle or print - functions=specification.functions - compact=specification.compact - inline=specification.inline and compact - metacheck=specification.metacheck - if functions==nil then - functions=true - end - if compact==nil then - compact=true - end - if inline==nil then - inline=compact - end - if metacheck==nil then - metacheck=true - end + local tname=type(name) + if type(specification)=="table" then + noquotes=specification.noquotes + hexify=specification.hexify + handle=_handle or specification.handle or print + functions=specification.functions + compact=specification.compact + inline=specification.inline and compact + metacheck=specification.metacheck + if functions==nil then + functions=true + end + if compact==nil then + compact=true + end + if inline==nil then + inline=compact + end + if metacheck==nil then + metacheck=true + end + else + noquotes=false + hexify=false + handle=_handle or print + compact=true + inline=true + functions=true + metacheck=true + end + if tname=="string" then + if name=="return" then + handle("return {") else - noquotes=false - hexify=false - handle=_handle or print - compact=true - inline=true - functions=true - metacheck=true - end - if tname=="string" then - if name=="return" then - handle("return {") - else - handle(name.."={") - end - elseif tname=="number" then - if hexify then - handle(format("[0x%X]={",name)) - else - handle("["..name.."]={") - end - elseif tname=="boolean" then - if name then - handle("return {") - else - handle("{") - end + handle(name.."={") + end + elseif tname=="number" then + if hexify then + handle(format("[0x%X]={",name)) else - handle("t={") + handle("["..name.."]={") end - if root then - if metacheck and getmetatable(root) then - local dummy=root._w_h_a_t_e_v_e_r_ - root._w_h_a_t_e_v_e_r_=nil - end - if next(root)~=nil then - do_serialize(root,name,"",0) - end + elseif tname=="boolean" then + if name then + handle("return {") + else + handle("{") + end + else + handle("t={") + end + if root then + if metacheck and getmetatable(root) then + local dummy=root._w_h_a_t_e_v_e_r_ + root._w_h_a_t_e_v_e_r_=nil end - handle("}") + if next(root)~=nil then + do_serialize(root,name,"",0) + end + end + handle("}") end function table.serialize(root,name,specification) - local t,n={},0 - local function flush(s) - n=n+1 - t[n]=s - end - serialize(flush,root,name,specification) - return concat(t,"\n") + local t={} + local n=0 + local function flush(s) + n=n+1 + t[n]=s + end + serialize(flush,root,name,specification) + return concat(t,"\n") end table.tohandle=serialize local maxtab=2*1024 function table.tofile(filename,root,name,specification) - local f=io.open(filename,'w') - if f then - if maxtab>1 then - local t,n={},0 - local function flush(s) - n=n+1 - t[n]=s - if n>maxtab then - f:write(concat(t,"\n"),"\n") - t,n={},0 - end - end - serialize(flush,root,name,specification) - f:write(concat(t,"\n"),"\n") - else - local function flush(s) - f:write(s,"\n") - end - serialize(flush,root,name,specification) - end - f:close() - io.flush() + local f=io.open(filename,'w') + if f then + if maxtab>1 then + local t={} + local n=0 + local function flush(s) + n=n+1 + t[n]=s + if n>maxtab then + f:write(concat(t,"\n"),"\n") + t={} + n=0 + end + end + serialize(flush,root,name,specification) + f:write(concat(t,"\n"),"\n") + else + local function flush(s) + f:write(s,"\n") + end + serialize(flush,root,name,specification) end + f:close() + io.flush() + end end local function flattened(t,f,depth) - if f==nil then - f={} - depth=0xFFFF - elseif tonumber(f) then - depth=f - f={} - elseif not depth then - depth=0xFFFF - end - for k,v in next,t do - if type(k)~="number" then - if depth>0 and type(v)=="table" then - flattened(v,f,depth-1) - else - f[#f+1]=v - end - end - end - for k=1,#t do - local v=t[k] - if depth>0 and type(v)=="table" then - flattened(v,f,depth-1) - else - f[#f+1]=v - end + if f==nil then + f={} + depth=0xFFFF + elseif tonumber(f) then + depth=f + f={} + elseif not depth then + depth=0xFFFF + end + for k,v in next,t do + if type(k)~="number" then + if depth>0 and type(v)=="table" then + flattened(v,f,depth-1) + else + f[#f+1]=v + end + end + end + for k=1,#t do + local v=t[k] + if depth>0 and type(v)=="table" then + flattened(v,f,depth-1) + else + f[#f+1]=v end - return f + end + return f end table.flattened=flattened local function collapsed(t,f,h) - if f==nil then - f={} - h={} - end - for k=1,#t do - local v=t[k] - if type(v)=="table" then - collapsed(v,f,h) - elseif not h[v] then - f[#f+1]=v - h[v]=true - end - end - return f + if f==nil then + f={} + h={} + end + for k=1,#t do + local v=t[k] + if type(v)=="table" then + collapsed(v,f,h) + elseif not h[v] then + f[#f+1]=v + h[v]=true + end + end + return f end local function collapsedhash(t,h) - if h==nil then - h={} - end - for k=1,#t do - local v=t[k] - if type(v)=="table" then - collapsedhash(v,h) - else - h[v]=true - end + if h==nil then + h={} + end + for k=1,#t do + local v=t[k] + if type(v)=="table" then + collapsedhash(v,h) + else + h[v]=true end - return h + end + return h end -table.collapsed=collapsed +table.collapsed=collapsed table.collapsedhash=collapsedhash local function unnest(t,f) - if not f then - f={} - end - for i=1,#t do - local v=t[i] - if type(v)=="table" then - if type(v[1])=="table" then - unnest(v,f) - else - f[#f+1]=v - end - else - f[#f+1]=v - end + if not f then + f={} + end + for i=1,#t do + local v=t[i] + if type(v)=="table" then + if type(v[1])=="table" then + unnest(v,f) + else + f[#f+1]=v + end + else + f[#f+1]=v end - return f + end + return f end function table.unnest(t) - return unnest(t) + return unnest(t) end local function are_equal(a,b,n,m) - if a==b then - return true - elseif a and b and #a==#b then - n=n or 1 - m=m or #a - for i=n,m do - local ai,bi=a[i],b[i] - if ai==bi then - elseif type(ai)=="table" and type(bi)=="table" then - if not are_equal(ai,bi) then - return false - end - else - return false - end + if a==b then + return true + elseif a and b and #a==#b then + if not n then + n=1 + end + if not m then + m=#a + end + for i=n,m do + local ai,bi=a[i],b[i] + if ai==bi then + elseif type(ai)=="table" and type(bi)=="table" then + if not are_equal(ai,bi) then + return false end - return true - else + else return false + end end + return true + else + return false + end end local function identical(a,b) - if a~=b then - for ka,va in next,a do - local vb=b[ka] - if va==vb then - elseif type(va)=="table" and type(vb)=="table" then - if not identical(va,vb) then - return false - end - else - return false - end - end + if a~=b then + for ka,va in next,a do + local vb=b[ka] + if va==vb then + elseif type(va)=="table" and type(vb)=="table" then + if not identical(va,vb) then + return false + end + else + return false + end end - return true + end + return true end table.identical=identical table.are_equal=are_equal local function sparse(old,nest,keeptables) - local new={} - for k,v in next,old do - if not (v=="" or v==false) then - if nest and type(v)=="table" then - v=sparse(v,nest) - if keeptables or next(v)~=nil then - new[k]=v - end - else - new[k]=v - end + local new={} + for k,v in next,old do + if not (v=="" or v==false) then + if nest and type(v)=="table" then + v=sparse(v,nest) + if keeptables or next(v)~=nil then + new[k]=v end + else + new[k]=v + end end - return new + end + return new end table.sparse=sparse function table.compact(t) - return sparse(t,true,true) + return sparse(t,true,true) end function table.contains(t,v) - if t then - for i=1,#t do - if t[i]==v then - return i - end - end + if t then + for i=1,#t do + if t[i]==v then + return i + end end - return false + end + return false end function table.count(t) - local n=0 - for k,v in next,t do - n=n+1 - end - return n + local n=0 + for k,v in next,t do + n=n+1 + end + return n end function table.swapped(t,s) - local n={} - if s then - for k,v in next,s do - n[k]=v - end + local n={} + if s then + for k,v in next,s do + n[k]=v end - for k,v in next,t do - n[v]=k - end - return n + end + for k,v in next,t do + n[v]=k + end + return n end function table.hashed(t) - for i=1,#t do - t[t[i]]=i - end - return t + for i=1,#t do + t[t[i]]=i + end + return t end function table.mirrored(t) - local n={} - for k,v in next,t do - n[v]=k - n[k]=v - end - return n + local n={} + for k,v in next,t do + n[v]=k + n[k]=v + end + return n end function table.reversed(t) - if t then - local tt,tn={},#t - if tn>0 then - local ttn=0 - for i=tn,1,-1 do - ttn=ttn+1 - tt[ttn]=t[i] - end - end - return tt - end + if t then + local tt={} + local tn=#t + if tn>0 then + local ttn=0 + for i=tn,1,-1 do + ttn=ttn+1 + tt[ttn]=t[i] + end + end + return tt + end end function table.reverse(t) - if t then - local n=#t - for i=1,floor(n/2) do - local j=n-i+1 - t[i],t[j]=t[j],t[i] - end - return t + if t then + local n=#t + local m=n+1 + for i=1,floor(n/2) do + local j=m-i + t[i],t[j]=t[j],t[i] end + return t + end end -function table.sequenced(t,sep,simple) - if not t then - return "" - end - local n=#t - local s={} - if n>0 then - for i=1,n do - s[i]=tostring(t[i]) +local function sequenced(t,sep,simple) + if not t then + return "" + elseif type(t)=="string" then + return t + end + local n=#t + local s={} + if n>0 then + for i=1,n do + local v=t[i] + if type(v)=="table" then + s[i]="{"..sequenced(v,sep,simple).."}" + else + s[i]=tostring(t[i]) + end + end + else + 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 + if type(v)=="table" then + s[n]=k.."={"..sequenced(v,sep,simple).."}" + else + s[n]=k.."="..tostring(v) + end end - else - 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 + else + n=n+1 + if type(v)=="table" then + s[n]=k.."={"..sequenced(v,sep,simple).."}" + else + s[n]=k.."="..tostring(v) end + end end - return concat(s,sep or " | ") + end + return concat(s,sep or " | ") end +table.sequenced=sequenced function table.print(t,...) - if type(t)~="table" then - print(tostring(t)) - else - serialize(print,t,...) - end + if type(t)~="table" then + print(tostring(t)) + else + serialize(print,t,...) + end end if setinspector then - setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end) + setinspector("table",function(v) if type(v)=="table" then serialize(print,v,"table") return true end end) end function table.sub(t,i,j) - return { unpack(t,i,j) } + return { unpack(t,i,j) } end function table.is_empty(t) - return not t or next(t)==nil + return not t or next(t)==nil end function table.has_one_entry(t) - return t and next(t,next(t))==nil + return t and next(t,next(t))==nil end function table.loweredkeys(t) - local l={} - for k,v in next,t do - l[lower(k)]=v - end - return l + local l={} + for k,v in next,t do + l[lower(k)]=v + end + return l end function table.unique(old) - local hash={} - local new={} - local n=0 - for i=1,#old do - local oi=old[i] - if not hash[oi] then - n=n+1 - new[n]=oi - hash[oi]=true - end - end - return new + local hash={} + local new={} + local n=0 + for i=1,#old do + local oi=old[i] + if not hash[oi] then + n=n+1 + new[n]=oi + hash[oi]=true + end + end + return new end function table.sorted(t,...) - sort(t,...) - return t + sort(t,...) + return t end function table.values(t,s) - if t then - local values,keys,v={},{},0 - for key,value in next,t do - if not keys[value] then - v=v+1 - values[v]=value - keys[k]=key - end - end - if s then - sort(values) - end - return values - else - return {} + if t then + local values={} + local keys={} + local v=0 + for key,value in next,t do + if not keys[value] then + v=v+1 + values[v]=value + keys[k]=key + end + end + if s then + sort(values) end + return values + else + return {} + end end function table.filtered(t,pattern,sort,cmp) - if t and type(pattern)=="string" then - if sort then - local s - if cmp then - s=sortedhashkeys(t,function(a,b) return cmp(t,a,b) end) - else - s=sortedkeys(t) - end - local n=0 - local m=#s - local function kv(s) - while n0 then - f:seek("set",0) - return f:read(size) - else - return "" - end + local size=f:seek("end") + if size>0 then + f:seek("set",0) + return f:read(size) + else + return "" + end end io.readall=readall function io.loaddata(filename,textmode) - local f=open(filename,(textmode and 'r') or 'rb') - if f then - local size=f:seek("end") - local data=nil - if size>0 then - f:seek("set",0) - data=f:read(size) - end - f:close() - return data + local f=open(filename,(textmode and 'r') or 'rb') + if f then + local size=f:seek("end") + local data=nil + if size>0 then + f:seek("set",0) + data=f:read(size) end + f:close() + return data + end end function io.copydata(source,target,action) - local f=open(source,"rb") - if f then - local g=open(target,"wb") - if g then - local size=f:seek("end") - if size>0 then - f:seek("set",0) - local data=f:read(size) - if action then - data=action(data) - end - if data then - g:write(data) - end - end - g:close() + local f=open(source,"rb") + if f then + local g=open(target,"wb") + if g then + local size=f:seek("end") + if size>0 then + f:seek("set",0) + local data=f:read(size) + if action then + data=action(data) + end + if data then + g:write(data) end - f:close() - flush() + end + g:close() end + f:close() + flush() + end end function io.savedata(filename,data,joiner) - local f=open(filename,"wb") - if f then - if type(data)=="table" then - f:write(concat(data,joiner or "")) - elseif type(data)=="function" then - data(f) - else - f:write(data or "") - end - f:close() - flush() - return true + local f=open(filename,"wb") + if f then + if type(data)=="table" then + f:write(concat(data,joiner or "")) + elseif type(data)=="function" then + data(f) else - return false + f:write(data or "") end + f:close() + flush() + return true + else + return false + end end if fio and fio.readline then - local readline=fio.readline - function io.loadlines(filename,n) - local f=open(filename,'r') - if not f then - elseif n then - local lines={} - for i=1,n do - local line=readline(f) - if line then - lines[i]=line - else - break - end - end - f:close() - lines=concat(lines,"\n") - if #lines>0 then - return lines - end + local readline=fio.readline + function io.loadlines(filename,n) + local f=open(filename,'r') + if not f then + elseif n then + local lines={} + for i=1,n do + local line=readline(f) + if line then + lines[i]=line else - local line=readline(f) - f:close() - if line and #line>0 then - return line - end - end + break + end + end + f:close() + lines=concat(lines,"\n") + if #lines>0 then + return lines + end + else + local line=readline(f) + f:close() + if line and #line>0 then + return line + end end + end else - function io.loadlines(filename,n) - local f=open(filename,'r') - if not f then - elseif n then - local lines={} - for i=1,n do - local line=f:read("*lines") - if line then - lines[i]=line - else - break - end - end - f:close() - lines=concat(lines,"\n") - if #lines>0 then - return lines - end + function io.loadlines(filename,n) + local f=open(filename,'r') + if not f then + elseif n then + local lines={} + for i=1,n do + local line=f:read("*lines") + if line then + lines[i]=line else - local line=f:read("*line") or "" - f:close() - if #line>0 then - return line - end - end + break + end + end + f:close() + lines=concat(lines,"\n") + if #lines>0 then + return lines + end + else + local line=f:read("*line") or "" + f:close() + if #line>0 then + return line + end end + end end function io.loadchunk(filename,n) - local f=open(filename,'rb') - if f then - local data=f:read(n or 1024) - f:close() - if #data>0 then - return data - end + local f=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=open(filename) - if f==nil then - return false - else - f:close() - return true - end + local f=open(filename) + if f==nil then + return false + else + f:close() + return true + end end function io.size(filename) - local f=open(filename) - if f==nil then - return 0 - else - local s=f:seek("end") - f:close() - return s - end + local f=open(filename) + if f==nil then + return 0 + else + local s=f:seek("end") + f:close() + return s + end end local function noflines(f) - if type(f)=="string" then - local f=open(filename) - if f then - local n=f and noflines(f) or 0 - f:close() - return n - else - return 0 - end + if type(f)=="string" then + local f=open(filename) + if f then + local n=f and noflines(f) or 0 + f:close() + return n else - local n=0 - for _ in f:lines() do - n=n+1 - end - f:seek('set',0) - return n + return 0 end + else + local n=0 + for _ in f:lines() do + n=n+1 + end + f:seek('set',0) + return n + end end io.noflines=noflines local nextchar={ - [ 4]=function(f) - return f:read(1,1,1,1) - end, - [ 2]=function(f) - return f:read(1,1) - end, - [ 1]=function(f) - return f:read(1) - end, - [-2]=function(f) - local a,b=f:read(1,1) - return b,a - end, - [-4]=function(f) - local a,b,c,d=f:read(1,1,1,1) - return d,c,b,a - end + [ 4]=function(f) + return f:read(1,1,1,1) + end, + [ 2]=function(f) + return f:read(1,1) + end, + [ 1]=function(f) + return f:read(1) + end, + [-2]=function(f) + local a,b=f:read(1,1) + return b,a + end, + [-4]=function(f) + local a,b,c,d=f:read(1,1,1,1) + return d,c,b,a + end } function io.characters(f,n) - if f then - return nextchar[n or 1],f - end + if f then + return nextchar[n or 1],f + end end local nextbyte={ - [4]=function(f) - local a,b,c,d=f:read(1,1,1,1) - if d then - return byte(a),byte(b),byte(c),byte(d) - end - end, - [3]=function(f) - local a,b,c=f:read(1,1,1) - if b then - return byte(a),byte(b),byte(c) - end - end, - [2]=function(f) - local a,b=f:read(1,1) - if b then - return byte(a),byte(b) - end - end, - [1]=function (f) - local a=f:read(1) - if a then - return byte(a) - end - end, - [-2]=function (f) - local a,b=f:read(1,1) - if b then - return byte(b),byte(a) - end - end, - [-3]=function(f) - local a,b,c=f:read(1,1,1) - if b then - return byte(c),byte(b),byte(a) - end - end, - [-4]=function(f) - local a,b,c,d=f:read(1,1,1,1) - if d then - return byte(d),byte(c),byte(b),byte(a) - end - end + [4]=function(f) + local a,b,c,d=f:read(1,1,1,1) + if d then + return byte(a),byte(b),byte(c),byte(d) + end + end, + [3]=function(f) + local a,b,c=f:read(1,1,1) + if b then + return byte(a),byte(b),byte(c) + end + end, + [2]=function(f) + local a,b=f:read(1,1) + if b then + return byte(a),byte(b) + end + end, + [1]=function (f) + local a=f:read(1) + if a then + return byte(a) + end + end, + [-2]=function (f) + local a,b=f:read(1,1) + if b then + return byte(b),byte(a) + end + end, + [-3]=function(f) + local a,b,c=f:read(1,1,1) + if b then + return byte(c),byte(b),byte(a) + end + end, + [-4]=function(f) + local a,b,c,d=f:read(1,1,1,1) + if d then + return byte(d),byte(c),byte(b),byte(a) + end + end } function io.bytes(f,n) - if f then - return nextbyte[n or 1],f - else - return nil,nil - end + if f then + return nextbyte[n or 1],f + else + return nil,nil + end end function io.ask(question,default,options) - while true do - write(question) - if options then - write(format(" [%s]",concat(options,"|"))) - end - if default then - write(format(" [%s]",default)) - end - write(format(" ")) - flush() - local answer=read() - answer=gsub(answer,"^%s*(.*)%s*$","%1") - if answer=="" and default then - return default - elseif not options then - return answer - else - for k=1,#options do - if options[k]==answer then - return answer - end - end - local pattern="^"..answer - for k=1,#options do - local v=options[k] - if find(v,pattern) then - return v - end - end + while true do + write(question) + if options then + write(format(" [%s]",concat(options,"|"))) + end + if default then + write(format(" [%s]",default)) + end + write(format(" ")) + flush() + local answer=read() + answer=gsub(answer,"^%s*(.*)%s*$","%1") + if answer=="" and default then + return default + elseif not options then + return answer + else + for k=1,#options do + if options[k]==answer then + return answer end + end + local pattern="^"..answer + for k=1,#options do + local v=options[k] + if find(v,pattern) then + return v + end + end end + end end local function readnumber(f,n,m) - if m then - f:seek("set",n) - n=m - end - if n==1 then - return byte(f:read(1)) - elseif n==2 then - local a,b=byte(f:read(2),1,2) - return 0x100*a+b - elseif n==3 then - local a,b,c=byte(f:read(3),1,3) - return 0x10000*a+0x100*b+c - elseif n==4 then - local a,b,c,d=byte(f:read(4),1,4) - return 0x1000000*a+0x10000*b+0x100*c+d - elseif n==8 then - local a,b=readnumber(f,4),readnumber(f,4) - return 0x100*a+b - elseif n==12 then - local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4) - return 0x10000*a+0x100*b+c - elseif n==-2 then - local b,a=byte(f:read(2),1,2) - return 0x100*a+b - elseif n==-3 then - local c,b,a=byte(f:read(3),1,3) - return 0x10000*a+0x100*b+c - elseif n==-4 then - local d,c,b,a=byte(f:read(4),1,4) - return 0x1000000*a+0x10000*b+0x100*c+d - elseif n==-8 then - local h,g,f,e,d,c,b,a=byte(f:read(8),1,8) - return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h - else - return 0 - end + if m then + f:seek("set",n) + n=m + end + if n==1 then + return byte(f:read(1)) + elseif n==2 then + local a,b=byte(f:read(2),1,2) + return 0x100*a+b + elseif n==3 then + local a,b,c=byte(f:read(3),1,3) + return 0x10000*a+0x100*b+c + elseif n==4 then + local a,b,c,d=byte(f:read(4),1,4) + return 0x1000000*a+0x10000*b+0x100*c+d + elseif n==8 then + local a,b=readnumber(f,4),readnumber(f,4) + return 0x100*a+b + elseif n==12 then + local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4) + return 0x10000*a+0x100*b+c + elseif n==-2 then + local b,a=byte(f:read(2),1,2) + return 0x100*a+b + elseif n==-3 then + local c,b,a=byte(f:read(3),1,3) + return 0x10000*a+0x100*b+c + elseif n==-4 then + local d,c,b,a=byte(f:read(4),1,4) + return 0x1000000*a+0x10000*b+0x100*c+d + elseif n==-8 then + local h,g,f,e,d,c,b,a=byte(f:read(8),1,8) + return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h + else + return 0 + end end io.readnumber=readnumber function io.readstring(f,n,m) - if m then - f:seek("set",n) - n=m - end - local str=gsub(f:read(n),"\000","") - return str + if m then + f:seek("set",n) + n=m + end + local str=gsub(f:read(n),"\000","") + return str end end -- closure @@ -2486,16 +2499,16 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-file']={ - 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" + 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" } file=file or {} local file=file if not lfs then - lfs=optionalrequire("lfs") + lfs=optionalrequire("lfs") end local insert,concat=table.insert,table.concat local match,find,gmatch=string.match,string.find,string.gmatch @@ -2503,24 +2516,22 @@ local lpegmatch=lpeg.match local getcurrentdir,attributes=lfs.currentdir,lfs.attributes local checkedsplit=string.checkedsplit local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct -local tricky=S("/\\")*P(-1) local attributes=lfs.attributes -if sandbox then - sandbox.redefine(lfs.isfile,"lfs.isfile") - sandbox.redefine(lfs.isdir,"lfs.isdir") -end function lfs.isdir(name) - if lpegmatch(tricky,name) then - return attributes(name,"mode")=="directory" - else - return attributes(name.."/.","mode")=="directory" - end + return attributes(name,"mode")=="directory" end function lfs.isfile(name) - return attributes(name,"mode")=="file" + local a=attributes(name,"mode") + return a=="file" or a=="link" or nil end function lfs.isfound(name) - return attributes(name,"mode")=="file" and name or nil + local a=attributes(name,"mode") + return (a=="file" or a=="link") and name or nil +end +if sandbox then + sandbox.redefine(lfs.isfile,"lfs.isfile") + sandbox.redefine(lfs.isdir,"lfs.isdir") + sandbox.redefine(lfs.isfound,"lfs.isfound") end local colon=P(":") local period=P(".") @@ -2534,27 +2545,27 @@ local name=noperiod^1 local suffix=period/""*(1-period-slashes)^1*-1 local pattern=C((1-(slashes^1*noslashes^1*-1))^1)*P(1) local function pathpart(name,default) - return name and lpegmatch(pattern,name) or default or "" + return name and lpegmatch(pattern,name) or default or "" end local pattern=(noslashes^0*slashes)^1*C(noslashes^1)*-1 local function basename(name) - return name and lpegmatch(pattern,name) or name + return name and lpegmatch(pattern,name) or name end local pattern=(noslashes^0*slashes^1)^0*Cs((1-suffix)^1)*suffix^0 local function nameonly(name) - return name and lpegmatch(pattern,name) or name + return name and lpegmatch(pattern,name) or name end local pattern=(noslashes^0*slashes)^0*(noperiod^1*period)^1*C(noperiod^1)*-1 local function suffixonly(name) - return name and lpegmatch(pattern,name) or "" + return name and lpegmatch(pattern,name) or "" end local pattern=(noslashes^0*slashes)^0*noperiod^1*((period*C(noperiod^1))^1)*-1+Cc("") local function suffixesonly(name) - if name then - return lpegmatch(pattern,name) - else - return "" - end + if name then + return lpegmatch(pattern,name) + else + return "" + end end file.pathpart=pathpart file.basename=basename @@ -2563,7 +2574,7 @@ file.suffixonly=suffixonly file.suffix=suffixonly file.suffixesonly=suffixesonly file.suffixes=suffixesonly -file.dirname=pathpart +file.dirname=pathpart file.extname=suffixonly local drive=C(R("az","AZ"))*colon local path=C((noslashes^0*slashes)^0) @@ -2579,142 +2590,142 @@ local pattern_b=path*base*suffix local pattern_c=C(drive*path)*C(base*suffix) local pattern_d=path*rest function file.splitname(str,splitdrive) - if not str then - elseif splitdrive then - return lpegmatch(pattern_a,str) - else - return lpegmatch(pattern_b,str) - end + if not str then + elseif splitdrive then + return lpegmatch(pattern_a,str) + else + return lpegmatch(pattern_b,str) + end end function file.splitbase(str) - if str then - return lpegmatch(pattern_d,str) + if str then + return lpegmatch(pattern_d,str) + else + return "",str + end +end +function file.nametotable(str,splitdrive) + if str then + local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str) + if splitdrive then + return { + path=path, + drive=drive, + subpath=subpath, + name=name, + base=base, + suffix=suffix, + } else - return "",str - end -end -function file.nametotable(str,splitdrive) - if str then - local path,drive,subpath,name,base,suffix=lpegmatch(pattern_c,str) - if splitdrive then - return { - path=path, - drive=drive, - subpath=subpath, - name=name, - base=base, - suffix=suffix, - } - else - return { - path=path, - name=name, - base=base, - suffix=suffix, - } - end + return { + path=path, + name=name, + base=base, + suffix=suffix, + } end + end end local pattern=Cs(((period*(1-period-slashes)^1*-1)/""+1)^1) function file.removesuffix(name) - return name and lpegmatch(pattern,name) + return name and lpegmatch(pattern,name) end local suffix=period/""*(1-period-slashes)^1*-1 local pattern=Cs((noslashes^0*slashes^1)^0*((1-suffix)^1))*Cs(suffix) function file.addsuffix(filename,suffix,criterium) - if not filename or not suffix or suffix=="" then - return filename - elseif criterium==true then - return filename.."."..suffix - elseif not criterium then - local n,s=lpegmatch(pattern,filename) - if not s or s=="" then - return filename.."."..suffix - else + if not filename or not suffix or suffix=="" then + return filename + elseif criterium==true then + return filename.."."..suffix + elseif not criterium then + local n,s=lpegmatch(pattern,filename) + if not s or s=="" then + return filename.."."..suffix + else + return filename + end + else + local n,s=lpegmatch(pattern,filename) + if s and s~="" then + local t=type(criterium) + if t=="table" then + for i=1,#criterium do + if s==criterium[i] then return filename + end end - else - local n,s=lpegmatch(pattern,filename) - if s and s~="" then - local t=type(criterium) - if t=="table" then - for i=1,#criterium do - if s==criterium[i] then - return filename - end - end - elseif t=="string" then - if s==criterium then - return filename - end - end + elseif t=="string" then + if s==criterium then + return filename end - return (n or filename).."."..suffix + end end + return (n or filename).."."..suffix + end end local suffix=period*(1-period-slashes)^1*-1 local pattern=Cs((1-suffix)^0) function file.replacesuffix(name,suffix) - if name and suffix and suffix~="" then - return lpegmatch(pattern,name).."."..suffix - else - return name - end + if name and suffix and suffix~="" then + return lpegmatch(pattern,name).."."..suffix + else + return name + end end local reslasher=lpeg.replacer(P("\\"),"/") function file.reslash(str) - return str and lpegmatch(reslasher,str) + return str and lpegmatch(reslasher,str) end function file.is_writable(name) - if not name then - elseif lfs.isdir(name) then - name=name.."/m_t_x_t_e_s_t.tmp" - local f=io.open(name,"wb") - if f then - f:close() - os.remove(name) - return true - end - elseif lfs.isfile(name) then - local f=io.open(name,"ab") - if f then - f:close() - return true - end - else - local f=io.open(name,"ab") - if f then - f:close() - os.remove(name) - return true - end + if not name then + elseif lfs.isdir(name) then + name=name.."/m_t_x_t_e_s_t.tmp" + local f=io.open(name,"wb") + if f then + f:close() + os.remove(name) + return true end - return false + elseif lfs.isfile(name) then + local f=io.open(name,"ab") + if f then + f:close() + return true + end + else + local f=io.open(name,"ab") + if f then + f:close() + os.remove(name) + return true + end + end + return false end local readable=P("r")*Cc(true) function file.is_readable(name) - if name then - local a=attributes(name) - return a and lpegmatch(readable,a.permissions) or false - else - return false - end + if name then + local a=attributes(name) + return a and lpegmatch(readable,a.permissions) or false + else + return false + end end file.isreadable=file.is_readable file.iswritable=file.is_writable function file.size(name) - if name then - local a=attributes(name) - return a and a.size or 0 - else - return 0 - end + if name then + local a=attributes(name) + return a and a.size or 0 + else + return 0 + end end function file.splitpath(str,separator) - return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator) + return str and checkedsplit(lpegmatch(reslasher,str),separator or io.pathseparator) end function file.joinpath(tab,separator) - return tab and concat(tab,separator or io.pathseparator) + return tab and concat(tab,separator or io.pathseparator) end local someslash=S("\\/") local stripper=Cs(P(fwslash)^0/""*reslasher) @@ -2724,30 +2735,30 @@ local hasroot=fwslash^1 local reslasher=lpeg.replacer(S("\\/"),"/") local deslasher=lpeg.replacer(S("\\/")^1,"/") function file.join(one,two,three,...) - if not two then - return one=="" and one or lpegmatch(reslasher,one) - end - if one=="" then - return lpegmatch(stripper,three and concat({ two,three,... },"/") or two) + if not two then + return one=="" and one or lpegmatch(reslasher,one) + end + if one=="" then + return lpegmatch(stripper,three and concat({ two,three,... },"/") or two) + end + if lpegmatch(isnetwork,one) then + local one=lpegmatch(reslasher,one) + local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two) + if lpegmatch(hasroot,two) then + return one..two + else + return one.."/"..two end - if lpegmatch(isnetwork,one) then - local one=lpegmatch(reslasher,one) - local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two) - if lpegmatch(hasroot,two) then - return one..two - else - return one.."/"..two - end - elseif lpegmatch(isroot,one) then - local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two) - if lpegmatch(hasroot,two) then - return two - else - return "/"..two - end + elseif lpegmatch(isroot,one) then + local two=lpegmatch(deslasher,three and concat({ two,three,... },"/") or two) + if lpegmatch(hasroot,two) then + return two else - return lpegmatch(deslasher,concat({ one,two,three,... },"/")) + return "/"..two end + else + return lpegmatch(deslasher,concat({ one,two,three,... },"/")) + end end local drivespec=R("az","AZ")^1*colon local anchors=fwslash+drivespec @@ -2757,56 +2768,56 @@ local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//") local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) local absolute=fwslash function file.collapsepath(str,anchor) - if not str then - return - end - if anchor==true and not lpegmatch(anchors,str) then - str=getcurrentdir().."/"..str - end - if str=="" or str=="." then - return "." - elseif lpegmatch(untouched,str) then - return lpegmatch(reslasher,str) - end - local starter,oldelements=lpegmatch(splitstarter,str) - local newelements={} - local i=#oldelements - while i>0 do - local element=oldelements[i] - if element=='.' then - elseif element=='..' then - local n=i-1 - while n>0 do - local element=oldelements[n] - if element~='..' and element~='.' then - oldelements[n]='.' - break - else - n=n-1 - end - end - if n<1 then - insert(newelements,1,'..') - end - elseif element~="" then - insert(newelements,1,element) - end - i=i-1 - end - if #newelements==0 then - return starter or "." - elseif starter then - return starter..concat(newelements,'/') - elseif lpegmatch(absolute,str) then - return "/"..concat(newelements,'/') - else - newelements=concat(newelements,'/') - if anchor=="." and find(str,"^%./") then - return "./"..newelements + if not str then + return + end + if anchor==true and not lpegmatch(anchors,str) then + str=getcurrentdir().."/"..str + end + if str=="" or str=="." then + return "." + elseif lpegmatch(untouched,str) then + return lpegmatch(reslasher,str) + end + local starter,oldelements=lpegmatch(splitstarter,str) + local newelements={} + local i=#oldelements + while i>0 do + local element=oldelements[i] + if element=='.' then + elseif element=='..' then + local n=i-1 + while n>0 do + local element=oldelements[n] + if element~='..' and element~='.' then + oldelements[n]='.' + break else - return newelements - end + n=n-1 + end + end + if n<1 then + insert(newelements,1,'..') + end + elseif element~="" then + insert(newelements,1,element) + end + i=i-1 + end + if #newelements==0 then + return starter or "." + elseif starter then + return starter..concat(newelements,'/') + elseif lpegmatch(absolute,str) then + return "/"..concat(newelements,'/') + else + newelements=concat(newelements,'/') + if anchor=="." and find(str,"^%./") then + return "./"..newelements + else + return newelements end + end end local validchars=R("az","09","AZ","--","..") local pattern_a=lpeg.replacer(1-validchars) @@ -2814,26 +2825,26 @@ local pattern_a=Cs((validchars+P(1)/"-")^1) local whatever=P("-")^0/"" local pattern_b=Cs(whatever*(1-whatever*-1)^1) function file.robustname(str,strict) - if str then - str=lpegmatch(pattern_a,str) or str - if strict then - return lpegmatch(pattern_b,str) or str - else - return str - end + if str then + str=lpegmatch(pattern_a,str) or str + if strict then + return lpegmatch(pattern_b,str) or str + else + return str end + end end local loaddata=io.loaddata local savedata=io.savedata file.readdata=loaddata file.savedata=savedata function file.copy(oldname,newname) - if oldname and newname then - local data=loaddata(oldname) - if data and data~="" then - savedata(newname,data) - end + if oldname and newname then + local data=loaddata(oldname) + if data and data~="" then + savedata(newname,data) end + end end local letter=R("az","AZ")+S("_-+") local separator=P("://") @@ -2842,40 +2853,44 @@ local rootbased=fwslash+letter*colon lpeg.patterns.qualified=qualified lpeg.patterns.rootbased=rootbased function file.is_qualified_path(filename) - return filename and lpegmatch(qualified,filename)~=nil + return filename and lpegmatch(qualified,filename)~=nil end function file.is_rootbased_path(filename) - return filename and lpegmatch(rootbased,filename)~=nil + return filename and lpegmatch(rootbased,filename)~=nil end function file.strip(name,dir) - if name then - local b,a=match(name,"^(.-)"..dir.."(.*)$") - return a~="" and a or name - end + if name then + local b,a=match(name,"^(.-)"..dir.."(.*)$") + return a~="" and a or name + end end function lfs.mkdirs(path) - local full="" - for sub in gmatch(path,"(/*[^\\/]+)") do - full=full..sub - lfs.mkdir(full) - end + local full="" + for sub in gmatch(path,"(/*[^\\/]+)") do + full=full..sub + lfs.mkdir(full) + end end function file.withinbase(path) - local l=0 - if not find(path,"^/") then - path="/"..path - end - for dir in gmatch(path,"/([^/]+)") do - if dir==".." then - l=l-1 - elseif dir~="." then - l=l+1 - end - if l<0 then - return false - end - end - return true + local l=0 + if not find(path,"^/") then + path="/"..path + end + for dir in gmatch(path,"/([^/]+)") do + if dir==".." then + l=l-1 + elseif dir~="." then + l=l+1 + end + if l<0 then + return false + end + end + return true +end +local symlinkattributes=lfs.symlinkattributes +function lfs.readlink(name) + return symlinkattributes(name,"target") or nil end end -- closure @@ -2883,66 +2898,66 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-boolean']={ - 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" + 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" } local type,tonumber=type,tonumber boolean=boolean or {} local boolean=boolean function boolean.tonumber(b) - if b then return 1 else return 0 end + if b then return 1 else return 0 end end function toboolean(str,tolerant) - 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 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" - end + 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 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" + end end string.toboolean=toboolean function string.booleanstring(str) - if str=="0" then - return false - elseif str=="1" then - return true - elseif str=="" then - return false - elseif str=="false" then - return false - elseif str=="true" then - return true - elseif (tonumber(str) or 0)>0 then - return true - else - return str=="yes" or str=="on" or str=="t" - end + if str=="0" then + return false + elseif str=="1" then + return true + elseif str=="" then + return false + elseif str=="false" then + return false + elseif str=="true" then + return true + 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,strict) - if type(str)=="string" then - if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then - return true - elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then - return false - end + if type(str)=="string" then + if str=="true" or str=="yes" or str=="on" or str=="t" or (not strict and str=="1") then + return true + elseif str=="false" or str=="no" or str=="off" or str=="f" or (not strict and str=="0") then + return false end - return default + end + return default end end -- closure @@ -2950,1425 +2965,765 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['l-math']={ - 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" + 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" } if not math.ceiling then - math.ceiling=math.ceil + math.ceiling=math.ceil end if not math.round then - local floor=math.floor - function math.round(x) return floor(x+0.5) end + local floor=math.floor + function math.round(x) return floor(x+0.5) end end if not math.div then - local floor=math.floor - function math.div(n,m) return floor(n/m) end + local floor=math.floor + function math.div(n,m) return floor(n/m) end end if not math.mod then - function math.mod(n,m) return n%m end + function math.mod(n,m) return n%m end end if not math.sind then - local sin,cos,tan=math.sin,math.cos,math.tan - local pipi=2*math.pi/360 - function math.sind(d) return sin(d*pipi) end - function math.cosd(d) return cos(d*pipi) end - function math.tand(d) return tan(d*pipi) end + local sin,cos,tan=math.sin,math.cos,math.tan + local pipi=2*math.pi/360 + function math.sind(d) return sin(d*pipi) end + function math.cosd(d) return cos(d*pipi) end + function math.tand(d) return tan(d*pipi) end end if not math.odd then - function math.odd (n) return n%2~=0 end - function math.even(n) return n%2==0 end + function math.odd (n) return n%2~=0 end + function math.even(n) return n%2==0 end end if not math.cosh then - local exp=math.exp - function math.cosh(x) - local xx=exp(x) - return (xx+1/xx)/2 - end - function math.sinh(x) - local xx=exp(x) - return (xx-1/xx)/2 - end - function math.tanh(x) - local xx=exp(x) - return (xx-1/xx)/(xx+1/xx) - end + local exp=math.exp + function math.cosh(x) + local xx=exp(x) + return (xx+1/xx)/2 + end + function math.sinh(x) + local xx=exp(x) + return (xx-1/xx)/2 + end + function math.tanh(x) + local xx=exp(x) + return (xx-1/xx)/(xx+1/xx) + end end if not math.pow then - function math.pow(x,y) - return x^y - end + function math.pow(x,y) + return x^y + end end if not math.atan2 then - math.atan2=math.atan + math.atan2=math.atan end if not math.ldexp then - function math.ldexp(x,e) - return x*2.0^e - end + function math.ldexp(x,e) + return x*2.0^e + end end if not math.log10 then - local log=math.log - function math.log10(x) - return log(x,10) - end + local log=math.log + function math.log10(x) + return log(x,10) + end end if not math.type then - function math.type() - return "float" - end + function math.type() + return "float" + end end if not math.tointeger then - math.mininteger=-0x4FFFFFFFFFFF - math.maxinteger=0x4FFFFFFFFFFF - local floor=math.floor - function math.tointeger(n) - local f=floor(n) - return f==n and f or nil - end + math.mininteger=-0x4FFFFFFFFFFF + math.maxinteger=0x4FFFFFFFFFFF + local floor=math.floor + function math.tointeger(n) + local f=floor(n) + return f==n and f or nil + end end if not math.ult then - local floor=math.floor - function math.tointeger(m,n) - return floor(m)0 and rep(str,n) or "" + t[k]=s + return s + end }) + s[offset]=t + return t +end +local extra,tab,start=0,0,4,0 +local nspaces=strings.newrepeater(" ") +string.nspaces=nspaces +local pattern=Carg(1)/function(t) + extra,tab,start=0,t or 7,1 + end*Cs(( + Cp()*patterns.tab/function(position) + local current=(position-start+1)+extra + local spaces=tab-(current-1)%tab + if spaces>0 then + extra=extra+spaces-1 + return nspaces[spaces] else - local floor=math.floor - 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<0x200000 then - return char( - 0xF0+floor(n/0x40000), - 0x80+(floor(n/0x1000)%0x40), - 0x80+(floor(n/0x40)%0x40), - 0x80+(n%0x40) - ) - else - return "" - end - end + return "" end - end + end+newline*Cp()/function(position) + extra,start=0,position + end+anything + )^1) +function strings.tabtospace(str,tab) + return lpegmatch(pattern,str,1,tab or 7) end -if not utf.byte then - utf.byte=string.utfvalue or (utf8 and utf8.codepoint) - if not utf.byte then - local utf8byte=patterns.utf8byte - function utf.byte(c) - return lpegmatch(utf8byte,c) - end - end +function string.utfpadding(s,n) + if not n or n==0 then + return "" + end + local l=utflen(s) + if n>0 then + return nspaces[n-l] + else + return nspaces[-n-l] + end +end +local optionalspace=spacer^0 +local nospace=optionalspace/"" +local endofline=nospace*newline +local stripend=(whitespace^1*endofstring)/"" +local normalline=(nospace*((1-optionalspace*(newline+endofstring))^1)*nospace) +local stripempty=endofline^1/"" +local normalempty=endofline^1 +local singleempty=endofline*(endofline^0/"") +local doubleempty=endofline*endofline^-1*(endofline^0/"") +local stripstart=stripempty^0 +local intospace=whitespace^1/" " +local noleading=whitespace^1/"" +local notrailing=noleading*endofstring +local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 ) +local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 ) +local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 ) +local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 ) +local p_retain_normal=Cs ((normalline+normalempty )^0 ) +local p_retain_collapse=Cs ((normalline+doubleempty )^0 ) +local p_retain_noempty=Cs ((normalline+singleempty )^0 ) +local striplinepatterns={ + ["prune"]=p_prune_normal, + ["prune and collapse"]=p_prune_collapse, + ["prune and no empty"]=p_prune_noempty, + ["prune and to space"]=p_prune_intospace, + ["retain"]=p_retain_normal, + ["retain and collapse"]=p_retain_collapse, + ["retain and no empty"]=p_retain_noempty, + ["collapse"]=patterns.collapser, +} +setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end }) +strings.striplinepatterns=striplinepatterns +function strings.striplines(str,how) + return str and lpegmatch(striplinepatterns[how],str) or str end -local utfchar,utfbyte=utf.char,utf.byte -function utf.filetype(data) - return data and lpegmatch(p_utftype,data) or "unknown" +function strings.collapse(str) + return str and lpegmatch(p_prune_intospace,str) or str 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 +strings.striplong=strings.striplines +function strings.nice(str) + str=gsub(str,"[:%-+_]+"," ") + return str +end +local n=0 +local sequenced=table.sequenced +function string.autodouble(s,sep) + if s==nil then + return '""' + end + local t=type(s) + if t=="number" then + return tostring(s) + end + if t=="table" then + return ('"'..sequenced(s,sep or ",")..'"') + end + return ('"'..tostring(s)..'"') +end +function string.autosingle(s,sep) + if s==nil then + return "''" + end + local t=type(s) + if t=="number" then + return tostring(s) + end + if t=="table" then + return ("'"..sequenced(s,sep or ",").."'") + end + return ("'"..tostring(s).."'") +end +local tracedchars={ [0]= + "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]", + "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]", + "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]", + "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]", + "[space]", +} +string.tracedchars=tracedchars +strings.tracers=tracedchars +function string.tracedchar(b) + if type(b)=="number" then + return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")") + else + local c=utfbyte(b) + return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")") + end +end +function number.signed(i) + if i>0 then + return "+",i + else + return "-",-i + end +end +local two=digit*digit +local three=two*digit +local prefix=(Carg(1)*three)^1 +local splitter=Cs ( + (((1-(three^1*period))^1+C(three))*prefix+C((1-period)^1))*(anything/""*Carg(2))*C(2) ) -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) -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 -end -local validatedutf=Cs ( - ( - patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four+P(1)/"�" - )^0 +local splitter3=Cs ( + three*prefix*endofstring+two*prefix*endofstring+digit*prefix*endofstring+three+two+digit ) -patterns.validatedutf=validatedutf -function utf.is_valid(str) - return type(str)=="string" and lpegmatch(validatedutf,str) or false -end -if not utf.len then - utf.len=string.utflength or (utf8 and utf8.len) - if not utf.len then - local n,f=0,1 - local utfcharcounter=patterns.utfbom^-1*Cmt ( - Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1, - function(_,t,d) - n=n+(t-f)/d - f=t - return true - end - )^0 - function utf.len(str) - n,f=0,1 - lpegmatch(utfcharcounter,str or "") - return n - end - end -end -utf.length=utf.len -if not utf.sub then - local utflength=utf.length - local b,e,n,first,last=0,0,0,0,0 - local function slide_zero(s,p) - n=n+1 - if n>=last then - e=p-1 - else - return p - end +patterns.formattednumber=splitter +function number.formatted(n,sep1,sep2) + if sep1==false then + if type(n)=="number" then + n=tostring(n) end - local function slide_one(s,p) - n=n+1 - if n==first then - b=p - end - if n>=last then - e=p-1 - else - return p - end + return lpegmatch(splitter3,n,1,sep2 or ".") + else + if type(n)=="number" then + n=format("%0.2f",n) end - local function slide_two(s,p) - n=n+1 - if n==first then - b=p - else - return true - end - end - local pattern_zero=Cmt(p_utf8char,slide_zero)^0 - local pattern_one=Cmt(p_utf8char,slide_one )^0 - local pattern_two=Cmt(p_utf8char,slide_two )^0 - local pattern_first=C(patterns.utf8character) - function utf.sub(str,start,stop) - if not start then - return str - end - if start==0 then - start=1 - end - if not stop then - if start<0 then - local l=utflength(str) - start=l+start - else - start=start-1 - end - b,n,first=0,0,start - lpegmatch(pattern_two,str) - if n>=first then - return sub(str,b) - else - return "" - end - end - if start<0 or stop<0 then - local l=utf.length(str) - if start<0 then - start=l+start - if start<=0 then - start=1 - else - start=start+1 - end - end - if stop<0 then - stop=l+stop - if stop==0 then - stop=1 - else - stop=stop+1 - end - end - end - if start==1 and stop==1 then - return lpegmatch(pattern_first,str) or "" - elseif start>stop then - return "" - elseif start>1 then - b,e,n,first,last=0,0,0,start-1,stop - lpegmatch(pattern_one,str) - if n>=first and e==0 then - e=#str - end - return sub(str,b,e) - else - b,e,n,last=1,0,0,stop - lpegmatch(pattern_zero,str) - if e==0 then - e=#str - end - return sub(str,b,e) - end + if sep1==true then + return lpegmatch(splitter,n,1,".",",") + elseif sep1=="." then + return lpegmatch(splitter,n,1,sep1,sep2 or ",") + elseif sep1=="," then + return lpegmatch(splitter,n,1,sep1,sep2 or ".") + else + return lpegmatch(splitter,n,1,sep1 or ",",sep2 or ".") end + end end -function utf.remapper(mapping,option,action) - local variant=type(mapping) - if variant=="table" then - action=action or mapping - if option=="dynamic" then - local pattern=false - table.setmetatablenewindex(mapping,function(t,k,v) rawset(t,k,v) pattern=false end) - return function(str) - if not str or str=="" then - return "" - else - if not pattern then - pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0) - end - return lpegmatch(pattern,str) - end - end - elseif option=="pattern" then - return Cs((tabletopattern(mapping)/action+p_utf8char)^0) - else - local pattern=Cs((tabletopattern(mapping)/action+p_utf8char)^0) - return function(str) - if not str or str=="" then - return "" - else - return lpegmatch(pattern,str) - end - end,pattern - end - elseif variant=="function" then - if option=="pattern" then - return Cs((p_utf8char/mapping+p_utf8char)^0) - else - local pattern=Cs((p_utf8char/mapping+p_utf8char)^0) - return function(str) - if not str or str=="" then - return "" - else - return lpegmatch(pattern,str) - end - end,pattern - end - else - return function(str) - return str or "" - end - end +local p=Cs( + P("-")^0*(P("0")^1/"")^0*(1-period)^0*(period*P("0")^1*endofstring/""+period^0)*P(1-P("0")^1*endofstring)^0 + ) +function number.compactfloat(n,fmt) + if n==0 then + return "0" + elseif n==1 then + return "1" + end + n=lpegmatch(p,format(fmt or "%0.3f",n)) + if n=="." or n=="" or n=="-" then + return "0" + end + return n end -function utf.replacer(t) - local r=replacer(t,false,false,true) - return function(str) - return lpegmatch(r,str) +local zero=P("0")^1/"" +local plus=P("+")/"" +local minus=P("-") +local separator=period +local trailing=zero^1*#S("eE") +local exponent=(S("eE")*(plus+Cs((minus*zero^0*endofstring)/"")+minus)*zero^0*(endofstring*Cc("0")+anything^1)) +local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent) +local pattern_b=Cs((exponent+anything)^0) +function number.sparseexponent(f,n) + if not n then + n=f + f="%e" + end + local tn=type(n) + if tn=="string" then + local m=tonumber(n) + if m then + return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m)) end + elseif tn=="number" then + return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n)) + end + return tostring(n) end -function utf.subtituter(t) - local f=finder (t) - local r=replacer(t,false,false,true) - return function(str) - local i=lpegmatch(f,str) - if not i then - return str - elseif i>#str then - return str - else - return lpegmatch(r,str) - end - end +local hf={} +local hs={} +setmetatable(hf,{ __index=function(t,k) + local v="%."..k.."f" + t[k]=v + return v +end } ) +setmetatable(hs,{ __index=function(t,k) + local v="%"..k.."s" + t[k]=v + return v +end } ) +function number.formattedfloat(n,b,a) + local s=format(hf[a],n) + local l=(b or 0)+(a or 0)+1 + if #s0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - return utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - return "" - else - return utfchar(now) - end -end -local p_utf16_to_utf8_le=C(1)*C(1)/function(right,left) - local now=256*byte(left)+byte(right) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - return utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - return "" - else - return utfchar(now) - end +local format_S=function(f) + n=n+1 + if f and f~="" then + return format("format('%%%ss',tostring(a%s))",f,n) + else + return format("tostring(a%s)",n) + end end -local p_utf32_to_utf8_be=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d) - return utfchar(256*256*256*byte(a)+256*256*byte(b)+256*byte(c)+byte(d)) +local format_right=function(f) + n=n+1 + f=tonumber(f) + if not f or f==0 then + return format("(a%s or '')",n) + elseif f>0 then + return format("utfpadding(a%s,%i)..a%s",n,f,n) + else + return format("a%s..utfpadding(a%s,%i)",n,n,f) + end end -local p_utf32_to_utf8_le=C(1)*C(1)*C(1)*C(1)/function(a,b,c,d) - return utfchar(256*256*256*byte(d)+256*256*byte(c)+256*byte(b)+byte(a)) +local format_left=function(f) + n=n+1 + f=tonumber(f) + if not f or f==0 then + return format("(a%s or '')",n) + end + if f<0 then + return format("utfpadding(a%s,%i)..a%s",n,-f,n) + else + return format("a%s..utfpadding(a%s,%i)",n,n,-f) + end end -p_utf16_to_utf8_be=P(true)/function() more=0 end*utf_16_be_getbom*Cs(p_utf16_to_utf8_be^0) -p_utf16_to_utf8_le=P(true)/function() more=0 end*utf_16_le_getbom*Cs(p_utf16_to_utf8_le^0) -p_utf32_to_utf8_be=P(true)/function() more=0 end*utf_32_be_getbom*Cs(p_utf32_to_utf8_be^0) -p_utf32_to_utf8_le=P(true)/function() more=0 end*utf_32_le_getbom*Cs(p_utf32_to_utf8_le^0) -patterns.utf16_to_utf8_be=p_utf16_to_utf8_be -patterns.utf16_to_utf8_le=p_utf16_to_utf8_le -patterns.utf32_to_utf8_be=p_utf32_to_utf8_be -patterns.utf32_to_utf8_le=p_utf32_to_utf8_le -utf16_to_utf8_be=function(s) - if s and s~="" then - return lpegmatch(p_utf16_to_utf8_be,s) - else - return s - end +local format_q=function() + n=n+1 + return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n) end -local utf16_to_utf8_be_t=function(t) - if not t then - return nil - elseif type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - for i=1,#t do - local s=t[i] - if s~="" then - t[i]=lpegmatch(p_utf16_to_utf8_be,s) - end - end - return t +local format_Q=function() + n=n+1 + return format("format('%%q',tostring(a%s))",n) end -utf16_to_utf8_le=function(s) - if s and s~="" then - return lpegmatch(p_utf16_to_utf8_le,s) - else - return s - end +local format_i=function(f) + n=n+1 + if f and f~="" then + return format("format('%%%si',a%s)",f,n) + else + return format("format('%%i',a%s)",n) + end end -local utf16_to_utf8_le_t=function(t) - if not t then - return nil - elseif type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - for i=1,#t do - local s=t[i] - if s~="" then - t[i]=lpegmatch(p_utf16_to_utf8_le,s) - end - end - return t +local format_d=format_i +local format_I=function(f) + n=n+1 + return format("format('%%s%%%si',signed(a%s))",f,n) end -utf32_to_utf8_be=function(s) - if s and s~="" then - return lpegmatch(p_utf32_to_utf8_be,s) - else - return s - end +local format_f=function(f) + n=n+1 + return format("format('%%%sf',a%s)",f,n) end -local utf32_to_utf8_be_t=function(t) - if not t then - return nil - elseif type(t)=="string" then - t=lpegmatch(utf_32_be_linesplitter,t) - end - for i=1,#t do - local s=t[i] - if s~="" then - t[i]=lpegmatch(p_utf32_to_utf8_be,s) - end - end - return t +local format_F=function(f) + n=n+1 + if not f or f=="" then + return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n) + else + return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n) + end end -utf32_to_utf8_le=function(s) - if s and s~="" then - return lpegmatch(p_utf32_to_utf8_le,s) - else - return s - end +local format_k=function(b,a) + n=n+1 + return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0) end -local utf32_to_utf8_le_t=function(t) - if not t then - return nil - elseif type(t)=="string" then - t=lpegmatch(utf_32_le_linesplitter,t) - end - for i=1,#t do - local s=t[i] - if s~="" then - t[i]=lpegmatch(p_utf32_to_utf8_le,s) - end - end - return t +local format_g=function(f) + n=n+1 + return format("format('%%%sg',a%s)",f,n) end -utf.utf16_to_utf8_le_t=utf16_to_utf8_le_t -utf.utf16_to_utf8_be_t=utf16_to_utf8_be_t -utf.utf32_to_utf8_le_t=utf32_to_utf8_le_t -utf.utf32_to_utf8_be_t=utf32_to_utf8_be_t -utf.utf16_to_utf8_le=utf16_to_utf8_le -utf.utf16_to_utf8_be=utf16_to_utf8_be -utf.utf32_to_utf8_le=utf32_to_utf8_le -utf.utf32_to_utf8_be=utf32_to_utf8_be -function utf.utf8_to_utf8_t(t) - return type(t)=="string" and lpegmatch(utflinesplitter,t) or t -end -function utf.utf16_to_utf8_t(t,endian) - return endian and utf16_to_utf8_be_t(t) or utf16_to_utf8_le_t(t) or t -end -function utf.utf32_to_utf8_t(t,endian) - return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t -end -local function little(b) - if b<0x10000 then - return char(b%256,rshift(b,8)) - else - b=b-0x10000 - local b1=rshift(b,10)+0xD800 - local b2=b%1024+0xDC00 - return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8)) - end +local format_G=function(f) + n=n+1 + return format("format('%%%sG',a%s)",f,n) end -local function big(b) - if b<0x10000 then - return char(rshift(b,8),b%256) - else - b=b-0x10000 - local b1=rshift(b,10)+0xD800 - local b2=b%1024+0xDC00 - return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256) - end +local format_e=function(f) + n=n+1 + return format("format('%%%se',a%s)",f,n) end -local l_remap=Cs((p_utf8byte/little+P(1)/"")^0) -local b_remap=Cs((p_utf8byte/big+P(1)/"")^0) -local function utf8_to_utf16_be(str,nobom) - if nobom then - return lpegmatch(b_remap,str) - else - return char(254,255)..lpegmatch(b_remap,str) - end +local format_E=function(f) + n=n+1 + return format("format('%%%sE',a%s)",f,n) end -local function utf8_to_utf16_le(str,nobom) - if nobom then - return lpegmatch(l_remap,str) - else - return char(255,254)..lpegmatch(l_remap,str) - end +local format_j=function(f) + n=n+1 + return format("sparseexponent('%%%se',a%s)",f,n) end -utf.utf8_to_utf16_be=utf8_to_utf16_be -utf.utf8_to_utf16_le=utf8_to_utf16_le -function utf.utf8_to_utf16(str,littleendian,nobom) - if littleendian then - return utf8_to_utf16_le(str,nobom) - else - return utf8_to_utf16_be(str,nobom) - end +local format_J=function(f) + n=n+1 + return format("sparseexponent('%%%sE',a%s)",f,n) end -local pattern=Cs ( - (p_utf8byte/function(unicode ) return format("0x%04X",unicode) end)*(p_utf8byte*Carg(1)/function(unicode,separator) return format("%s0x%04X",separator,unicode) end)^0 -) -function utf.tocodes(str,separator) - return lpegmatch(pattern,str,1,separator or " ") +local format_x=function(f) + n=n+1 + return format("format('%%%sx',a%s)",f,n) end -function utf.ustring(s) - return format("U+%05X",type(s)=="number" and s or utfbyte(s)) +local format_X=function(f) + n=n+1 + return format("format('%%%sX',a%s)",f,n) end -function utf.xstring(s) - return format("0x%05X",type(s)=="number" and s or utfbyte(s)) +local format_o=function(f) + n=n+1 + return format("format('%%%so',a%s)",f,n) end -function utf.toeight(str) - if not str or str=="" then - return nil - end - local utftype=lpegmatch(p_utfstricttype,str) - if utftype=="utf-8" then - return sub(str,4) - elseif utftype=="utf-16-be" then - return utf16_to_utf8_be(str) - elseif utftype=="utf-16-le" then - return utf16_to_utf8_le(str) - else - return str - end +local format_c=function() + n=n+1 + return format("utfchar(a%s)",n) end -local p_nany=p_utf8char/"" -if utfgmatch then - function utf.count(str,what) - if type(what)=="string" then - local n=0 - for _ in utfgmatch(str,what) do - n=n+1 - end - return n - else - return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str) - end - end -else - local cache={} - function utf.count(str,what) - if type(what)=="string" then - local p=cache[what] - if not p then - p=Cs((P(what)/" "+p_nany)^0) - cache[p]=p - end - return #lpegmatch(p,str) - else - return #lpegmatch(Cs((P(what)/" "+p_nany)^0),str) - end - end +local format_C=function() + n=n+1 + return format("tracedchar(a%s)",n) end -if not utf.characters then - function utf.characters(str) - return gmatch(str,".[\128-\191]*") - end - string.utfcharacters=utf.characters +local format_r=function(f) + n=n+1 + return format("format('%%%s.0f',a%s)",f,n) end -if not utf.values then - local find=string.find - local dummy=function() - end - function utf.values(str) - local n=#str - if n==0 then - return dummy - elseif n==1 then - return function() return utfbyte(str) end - else - local p=1 - return function() - local b,e=find(str,".[\128-\191]*",p) - if b then - p=e+1 - return utfbyte(sub(str,b,e)) - end - end - end - end - string.utfvalues=utf.values +local format_h=function(f) + n=n+1 + if f=="-" then + f=sub(f,2) + return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + else + return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + end end -function utf.chrlen(u) - return - (u<0x80 and 1) or - (u<0xE0 and 2) or - (u<0xF0 and 3) or - (u<0xF8 and 4) or - (u<0xFC and 5) or - (u<0xFE and 6) or 0 +local format_H=function(f) + n=n+1 + if f=="-" then + f=sub(f,2) + return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + else + return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + end end -if bit32 then - local extract=bit32.extract - local char=string.char - function unicode.toutf32string(n) - if n<=0xFF then - return - char(n).."\000\000\000" - elseif n<=0xFFFF then - return - char(extract(n,0,8))..char(extract(n,8,8)).."\000\000" - elseif n<=0xFFFFFF then - return - char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000" - else - return - char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8)) - end - end +local format_u=function(f) + n=n+1 + if f=="-" then + f=sub(f,2) + return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + else + return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + end end -local len=utf.len -local rep=rep -function string.utfpadd(s,n) - if n and n~=0 then - local l=len(s) - if n>0 then - local d=n-l - if d>0 then - return rep(c or " ",d)..s - end - else - local d=- n-l - if d>0 then - return s..rep(c or " ",d) - end - end - end - return s +local format_U=function(f) + n=n+1 + if f=="-" then + f=sub(f,2) + return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + else + return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) + end end - -end -- closure - -do -- begin closure to overcome local limits and interference - -if not modules then modules={} end modules ['util-str']={ - 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" -} -utilities=utilities or {} -utilities.strings=utilities.strings or {} -local strings=utilities.strings -local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find -local load,dump=load,string.dump -local tonumber,type,tostring,next,setmetatable=tonumber,type,tostring,next,setmetatable -local unpack,concat=table.unpack,table.concat -local unpack,concat=table.unpack,table.concat -local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc -local patterns,lpegmatch=lpeg.patterns,lpeg.match -local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len -local loadstripped=nil -local oldfashioned=LUAVERSION<5.2 -if oldfashioned then - loadstripped=function(str,shortcuts) - return load(str) - end -else - loadstripped=function(str,shortcuts) - if shortcuts then - return load(dump(load(str),true),nil,nil,shortcuts) - else - return load(dump(load(str),true)) - end - end +local format_p=function() + n=n+1 + return format("points(a%s)",n) end -if not number then number={} end -local stripper=patterns.stripzeros -local newline=patterns.newline -local endofstring=patterns.endofstring -local whitespace=patterns.whitespace -local spacer=patterns.spacer -local spaceortab=patterns.spaceortab -local function points(n) - n=tonumber(n) - return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536)) +local format_b=function() + n=n+1 + return format("basepoints(a%s)",n) end -local function basepoints(n) - n=tonumber(n) - return (not n or n==0) and "0bp" or lpegmatch(stripper,format("%.5fbp",n*(7200/7227)/65536)) +local format_t=function(f) + n=n+1 + if f and f~="" then + return format("concat(a%s,%q)",n,f) + else + return format("concat(a%s)",n) + end end -number.points=points -number.basepoints=basepoints -local rubish=spaceortab^0*newline -local anyrubish=spaceortab+newline -local anything=patterns.anything -local stripped=(spaceortab^1/"")*newline -local leading=rubish^0/"" -local trailing=(anyrubish^1*endofstring)/"" -local redundant=rubish^3/"\n" -local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0) -function strings.collapsecrlf(str) - return lpegmatch(pattern,str) +local format_T=function(f) + n=n+1 + if f and f~="" then + return format("sequenced(a%s,%q)",n,f) + else + return format("sequenced(a%s)",n) + end end -local repeaters={} -function strings.newrepeater(str,offset) - offset=offset or 0 - local s=repeaters[str] - if not s then - s={} - repeaters[str]=s - end - local t=s[offset] - if t then - return t - end - t={} - setmetatable(t,{ __index=function(t,k) - if not k then - return "" - end - local n=k+offset - local s=n>0 and rep(str,n) or "" - t[k]=s - return s - end }) - s[offset]=t - return t +local format_l=function() + n=n+1 + return format("(a%s and 'true' or 'false')",n) end -local extra,tab,start=0,0,4,0 -local nspaces=strings.newrepeater(" ") -string.nspaces=nspaces -local pattern=Carg(1)/function(t) - extra,tab,start=0,t or 7,1 - end*Cs(( - Cp()*patterns.tab/function(position) - local current=(position-start+1)+extra - local spaces=tab-(current-1)%tab - if spaces>0 then - extra=extra+spaces-1 - return nspaces[spaces] - else - return "" - end - end+newline*Cp()/function(position) - extra,start=0,position - end+patterns.anything - )^1) -function strings.tabtospace(str,tab) - return lpegmatch(pattern,str,1,tab or 7) +local format_L=function() + n=n+1 + return format("(a%s and 'TRUE' or 'FALSE')",n) end -function string.utfpadding(s,n) - if not n or n==0 then - return "" - end - local l=utflen(s) - if n>0 then - return nspaces[n-l] - else - return nspaces[-n-l] - end +local format_n=function() + n=n+1 + return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) end -local space=spacer^0 -local nospace=space/"" -local endofline=nospace*newline -local stripend=(whitespace^1*endofstring)/"" -local normalline=(nospace*((1-space*(newline+endofstring))^1)*nospace) -local stripempty=endofline^1/"" -local normalempty=endofline^1 -local singleempty=endofline*(endofline^0/"") -local doubleempty=endofline*endofline^-1*(endofline^0/"") -local stripstart=stripempty^0 -local p_prune_normal=Cs (stripstart*(stripend+normalline+normalempty )^0 ) -local p_prune_collapse=Cs (stripstart*(stripend+normalline+doubleempty )^0 ) -local p_prune_noempty=Cs (stripstart*(stripend+normalline+singleempty )^0 ) -local p_retain_normal=Cs ((normalline+normalempty )^0 ) -local p_retain_collapse=Cs ((normalline+doubleempty )^0 ) -local p_retain_noempty=Cs ((normalline+singleempty )^0 ) -local striplinepatterns={ - ["prune"]=p_prune_normal, - ["prune and collapse"]=p_prune_collapse, - ["prune and no empty"]=p_prune_noempty, - ["retain"]=p_retain_normal, - ["retain and collapse"]=p_retain_collapse, - ["retain and no empty"]=p_retain_noempty, - ["collapse"]=patterns.collapser, -} -setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end }) -strings.striplinepatterns=striplinepatterns -function strings.striplines(str,how) - return str and lpegmatch(striplinepatterns[how],str) or str -end -strings.striplong=strings.striplines -function strings.nice(str) - str=gsub(str,"[:%-+_]+"," ") - return str -end -local n=0 -local sequenced=table.sequenced -function string.autodouble(s,sep) - if s==nil then - return '""' - end - local t=type(s) - if t=="number" then - return tostring(s) - end - if t=="table" then - return ('"'..sequenced(s,sep or ",")..'"') - end - return ('"'..tostring(s)..'"') -end -function string.autosingle(s,sep) - if s==nil then - return "''" - end - local t=type(s) - if t=="number" then - return tostring(s) - end - if t=="table" then - return ("'"..sequenced(s,sep or ",").."'") - end - return ("'"..tostring(s).."'") -end -local tracedchars={ [0]= - "[null]","[soh]","[stx]","[etx]","[eot]","[enq]","[ack]","[bel]", - "[bs]","[ht]","[lf]","[vt]","[ff]","[cr]","[so]","[si]", - "[dle]","[dc1]","[dc2]","[dc3]","[dc4]","[nak]","[syn]","[etb]", - "[can]","[em]","[sub]","[esc]","[fs]","[gs]","[rs]","[us]", - "[space]", -} -string.tracedchars=tracedchars -strings.tracers=tracedchars -function string.tracedchar(b) - if type(b)=="number" then - return tracedchars[b] or (utfchar(b).." (U+"..format("%05X",b)..")") - else - local c=utfbyte(b) - return tracedchars[c] or (b.." (U+"..(c and format("%05X",c) or "?????")..")") - end -end -function number.signed(i) - if i>0 then - return "+",i - else - return "-",-i - end -end -local digit=patterns.digit -local period=patterns.period -local three=digit*digit*digit -local splitter=Cs ( - (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2) -) -patterns.formattednumber=splitter -function number.formatted(n,sep1,sep2) - local s=type(s)=="string" and n or format("%0.2f",n) - if sep1==true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1=="." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1=="," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") - else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") - end -end -local p=Cs( - P("-")^0*(P("0")^1/"")^0*(1-P("."))^0*(P(".")*P("0")^1*P(-1)/""+P(".")^0)*P(1-P("0")^1*P(-1))^0 - ) -function number.compactfloat(n,fmt) - if n==0 then - return "0" - elseif n==1 then - return "1" - end - n=lpegmatch(p,format(fmt or "%0.3f",n)) - if n=="." or n=="" or n=="-" then - return "0" - end - return n -end -local zero=P("0")^1/"" -local plus=P("+")/"" -local minus=P("-") -local separator=S(".") -local digit=R("09") -local trailing=zero^1*#S("eE") -local exponent=(S("eE")*(plus+Cs((minus*zero^0*P(-1))/"")+minus)*zero^0*(P(-1)*Cc("0")+P(1)^1)) -local pattern_a=Cs(minus^0*digit^1*(separator/""*trailing+separator*(trailing+digit)^0)*exponent) -local pattern_b=Cs((exponent+P(1))^0) -function number.sparseexponent(f,n) - if not n then - n=f - f="%e" - end - local tn=type(n) - if tn=="string" then - local m=tonumber(n) - if m then - return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,m)) - end - elseif tn=="number" then - return lpegmatch((f=="%e" or f=="%E") and pattern_a or pattern_b,format(f,n)) - end - return tostring(n) -end -local hf={} -local hs={} -setmetatable(hf,{ __index=function(t,k) - local v="%."..k.."f" - t[k]=v - return v -end } ) -setmetatable(hs,{ __index=function(t,k) - local v="%"..k.."s" - t[k]=v - return v -end } ) -function number.formattedfloat(n,b,a) - local s=format(hf[a],n) - local l=(b or 0)+(a or 0)+1 - if #s0 then - return format("utfpadding(a%s,%i)..a%s",n,f,n) - else - return format("a%s..utfpadding(a%s,%i)",n,n,f) - end -end -local format_left=function(f) - n=n+1 - f=tonumber(f) - if not f or f==0 then - return format("(a%s or '')",n) - end - if f<0 then - return format("utfpadding(a%s,%i)..a%s",n,-f,n) - else - return format("a%s..utfpadding(a%s,%i)",n,n,-f) - end -end -local format_q=function() - n=n+1 - return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n) -end -local format_Q=function() - n=n+1 - return format("format('%%q',tostring(a%s))",n) -end -local format_i=function(f) - n=n+1 - if f and f~="" then - return format("format('%%%si',a%s)",f,n) - else - return format("format('%%i',a%s)",n) - end -end -local format_d=format_i -local format_I=function(f) - n=n+1 - return format("format('%%s%%%si',signed(a%s))",f,n) -end -local format_f=function(f) - n=n+1 - return format("format('%%%sf',a%s)",f,n) -end -local format_F=function(f) - n=n+1 - if not f or f=="" then - return format("(((a%s > -0.0000000005 and a%s < 0.0000000005) and '0') or format((a%s %% 1 == 0) and '%%i' or '%%.9f',a%s))",n,n,n,n) - else - return format("format((a%s %% 1 == 0) and '%%i' or '%%%sf',a%s)",n,f,n) - end -end -local format_k=function(b,a) - n=n+1 - return format("formattedfloat(a%s,%i,%i)",n,b or 0,a or 0) -end -local format_g=function(f) - n=n+1 - return format("format('%%%sg',a%s)",f,n) -end -local format_G=function(f) - n=n+1 - return format("format('%%%sG',a%s)",f,n) -end -local format_e=function(f) - n=n+1 - return format("format('%%%se',a%s)",f,n) -end -local format_E=function(f) - n=n+1 - return format("format('%%%sE',a%s)",f,n) -end -local format_j=function(f) - n=n+1 - return format("sparseexponent('%%%se',a%s)",f,n) -end -local format_J=function(f) - n=n+1 - return format("sparseexponent('%%%sE',a%s)",f,n) -end -local format_x=function(f) - n=n+1 - return format("format('%%%sx',a%s)",f,n) -end -local format_X=function(f) - n=n+1 - return format("format('%%%sX',a%s)",f,n) -end -local format_o=function(f) - n=n+1 - return format("format('%%%so',a%s)",f,n) -end -local format_c=function() - n=n+1 - return format("utfchar(a%s)",n) -end -local format_C=function() - n=n+1 - return format("tracedchar(a%s)",n) -end -local format_r=function(f) - n=n+1 - return format("format('%%%s.0f',a%s)",f,n) -end -local format_h=function(f) - n=n+1 - if f=="-" then - f=sub(f,2) - return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - else - return format("format('0x%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - end -end -local format_H=function(f) - n=n+1 - if f=="-" then - f=sub(f,2) - return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - else - return format("format('0x%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - end -end -local format_u=function(f) - n=n+1 - if f=="-" then - f=sub(f,2) - return format("format('%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - else - return format("format('u+%%%sx',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - end -end -local format_U=function(f) - n=n+1 - if f=="-" then - f=sub(f,2) - return format("format('%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - else - return format("format('U+%%%sX',type(a%s) == 'number' and a%s or utfbyte(a%s))",f=="" and "05" or f,n,n,n) - end -end -local format_p=function() - n=n+1 - return format("points(a%s)",n) -end -local format_b=function() - n=n+1 - return format("basepoints(a%s)",n) -end -local format_t=function(f) - n=n+1 - if f and f~="" then - return format("concat(a%s,%q)",n,f) - else - return format("concat(a%s)",n) - end -end -local format_T=function(f) - n=n+1 - if f and f~="" then - return format("sequenced(a%s,%q)",n,f) - else - return format("sequenced(a%s)",n) - end -end -local format_l=function() - n=n+1 - return format("(a%s and 'true' or 'false')",n) -end -local format_L=function() - n=n+1 - return format("(a%s and 'TRUE' or 'FALSE')",n) -end -local format_N=function() - n=n+1 - return format("tostring(tonumber(a%s) or a%s)",n,n) +local format_N=function(f) + n=n+1 + if not f or f=="" then + f=".9" + end + return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) end local format_a=function(f) - n=n+1 - if f and f~="" then - return format("autosingle(a%s,%q)",n,f) - else - return format("autosingle(a%s)",n) - end + n=n+1 + if f and f~="" then + return format("autosingle(a%s,%q)",n,f) + else + return format("autosingle(a%s)",n) + end end local format_A=function(f) - n=n+1 - if f and f~="" then - return format("autodouble(a%s,%q)",n,f) - else - return format("autodouble(a%s)",n) - end + n=n+1 + if f and f~="" then + return format("autodouble(a%s,%q)",n,f) + else + return format("autodouble(a%s)",n) + end end local format_w=function(f) - n=n+1 - f=tonumber(f) - if f then - return format("nspaces[%s+a%s]",f,n) - else - return format("nspaces[a%s]",n) - end + n=n+1 + f=tonumber(f) + if f then + return format("nspaces[%s+a%s]",f,n) + else + return format("nspaces[a%s]",n) + end end local format_W=function(f) - return format("nspaces[%s]",tonumber(f) or 0) + return format("nspaces[%s]",tonumber(f) or 0) end local format_m=function(f) - n=n+1 - if not f or f=="" then - f="," - end + n=n+1 + if not f or f=="" then + f="," + end + if f=="0" then + return format([[formattednumber(a%s,false)]],n) + else return format([[formattednumber(a%s,%q,".")]],n,f) + end end local format_M=function(f) - n=n+1 - if not f or f=="" then - f="." - end + n=n+1 + if not f or f=="" then + f="." + end + if f=="0" then + return format([[formattednumber(a%s,false)]],n) + else return format([[formattednumber(a%s,%q,",")]],n,f) + end end local format_z=function(f) - n=n+(tonumber(f) or 1) - return "''" + n=n+(tonumber(f) or 1) + return "''" end local format_rest=function(s) - return format("%q",s) + return format("%q",s) end local format_extension=function(extensions,f,name) - local extension=extensions[name] or "tostring(%s)" - local f=tonumber(f) or 1 - local w=find(extension,"%.%.%.") + local extension=extensions[name] or "tostring(%s)" + local f=tonumber(f) or 1 + local w=find(extension,"%.%.%.") + if w then if f==0 then - if w then - extension=gsub(extension,"%.%.%.","") - end - return extension + extension=gsub(extension,"%.%.%.","") + return extension elseif f==1 then - if w then - extension=gsub(extension,"%.%.%.","%%s") - end - n=n+1 - local a="a"..n - return format(extension,a,a) + extension=gsub(extension,"%.%.%.","%%s") + n=n+1 + local a="a"..n + return format(extension,a,a) elseif f<0 then - local a="a"..(n+f+1) - return format(extension,a,a) + local a="a"..(n+f+1) + return format(extension,a,a) else - if w then - extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s") - end - local t={} - for i=1,f do - n=n+1 - t[i]="a"..n - end - return format(extension,unpack(t)) - end + extension=gsub(extension,"%.%.%.",rep("%%s,",f-1).."%%s") + local t={} + for i=1,f do + n=n+1 + t[i]="a"..n + end + return format(extension,unpack(t)) + end + else + extension=gsub(extension,"%%s",function() + n=n+1 + return "a"..n + end) + return extension + end end local builder=Cs { "start", - start=( - ( - P("%")/""*( - V("!") + start=( + ( + P("%")/""*( + V("!") +V("s")+V("q")+V("i")+V("d")+V("f")+V("F")+V("g")+V("G")+V("e")+V("E")+V("x")+V("X")+V("o") +V("c")+V("C")+V("S") +V("Q") ++V("n") +V("N") +V("k") +V("r")+V("h")+V("H")+V("u")+V("U")+V("p")+V("b")+V("t")+V("T")+V("l")+V("L")+V("I")+V("w") @@ -4380,160 +3735,156 @@ local builder=Cs { "start", +V("z") +V(">") +V("<") - )+V("*") - )*(P(-1)+Carg(1)) - )^0, - ["s"]=(prefix_any*P("s"))/format_s, - ["q"]=(prefix_any*P("q"))/format_q, - ["i"]=(prefix_any*P("i"))/format_i, - ["d"]=(prefix_any*P("d"))/format_d, - ["f"]=(prefix_any*P("f"))/format_f, - ["F"]=(prefix_any*P("F"))/format_F, - ["g"]=(prefix_any*P("g"))/format_g, - ["G"]=(prefix_any*P("G"))/format_G, - ["e"]=(prefix_any*P("e"))/format_e, - ["E"]=(prefix_any*P("E"))/format_E, - ["x"]=(prefix_any*P("x"))/format_x, - ["X"]=(prefix_any*P("X"))/format_X, - ["o"]=(prefix_any*P("o"))/format_o, - ["S"]=(prefix_any*P("S"))/format_S, - ["Q"]=(prefix_any*P("Q"))/format_Q, - ["N"]=(prefix_any*P("N"))/format_N, - ["k"]=(prefix_sub*P("k"))/format_k, - ["c"]=(prefix_any*P("c"))/format_c, - ["C"]=(prefix_any*P("C"))/format_C, - ["r"]=(prefix_any*P("r"))/format_r, - ["h"]=(prefix_any*P("h"))/format_h, - ["H"]=(prefix_any*P("H"))/format_H, - ["u"]=(prefix_any*P("u"))/format_u, - ["U"]=(prefix_any*P("U"))/format_U, - ["p"]=(prefix_any*P("p"))/format_p, - ["b"]=(prefix_any*P("b"))/format_b, - ["t"]=(prefix_tab*P("t"))/format_t, - ["T"]=(prefix_tab*P("T"))/format_T, - ["l"]=(prefix_any*P("l"))/format_l, - ["L"]=(prefix_any*P("L"))/format_L, - ["I"]=(prefix_any*P("I"))/format_I, - ["w"]=(prefix_any*P("w"))/format_w, - ["W"]=(prefix_any*P("W"))/format_W, - ["j"]=(prefix_any*P("j"))/format_j, - ["J"]=(prefix_any*P("J"))/format_J, - ["m"]=(prefix_tab*P("m"))/format_m, - ["M"]=(prefix_tab*P("M"))/format_M, - ["z"]=(prefix_any*P("z"))/format_z, - ["a"]=(prefix_any*P("a"))/format_a, - ["A"]=(prefix_any*P("A"))/format_A, - ["<"]=(prefix_any*P("<"))/format_left, - [">"]=(prefix_any*P(">"))/format_right, - ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, - ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest, - ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, + )+V("*") + )*(endofstring+Carg(1)) + )^0, + ["s"]=(prefix_any*P("s"))/format_s, + ["q"]=(prefix_any*P("q"))/format_q, + ["i"]=(prefix_any*P("i"))/format_i, + ["d"]=(prefix_any*P("d"))/format_d, + ["f"]=(prefix_any*P("f"))/format_f, + ["F"]=(prefix_any*P("F"))/format_F, + ["g"]=(prefix_any*P("g"))/format_g, + ["G"]=(prefix_any*P("G"))/format_G, + ["e"]=(prefix_any*P("e"))/format_e, + ["E"]=(prefix_any*P("E"))/format_E, + ["x"]=(prefix_any*P("x"))/format_x, + ["X"]=(prefix_any*P("X"))/format_X, + ["o"]=(prefix_any*P("o"))/format_o, + ["S"]=(prefix_any*P("S"))/format_S, + ["Q"]=(prefix_any*P("Q"))/format_Q, + ["n"]=(prefix_any*P("n"))/format_n, + ["N"]=(prefix_any*P("N"))/format_N, + ["k"]=(prefix_sub*P("k"))/format_k, + ["c"]=(prefix_any*P("c"))/format_c, + ["C"]=(prefix_any*P("C"))/format_C, + ["r"]=(prefix_any*P("r"))/format_r, + ["h"]=(prefix_any*P("h"))/format_h, + ["H"]=(prefix_any*P("H"))/format_H, + ["u"]=(prefix_any*P("u"))/format_u, + ["U"]=(prefix_any*P("U"))/format_U, + ["p"]=(prefix_any*P("p"))/format_p, + ["b"]=(prefix_any*P("b"))/format_b, + ["t"]=(prefix_tab*P("t"))/format_t, + ["T"]=(prefix_tab*P("T"))/format_T, + ["l"]=(prefix_any*P("l"))/format_l, + ["L"]=(prefix_any*P("L"))/format_L, + ["I"]=(prefix_any*P("I"))/format_I, + ["w"]=(prefix_any*P("w"))/format_w, + ["W"]=(prefix_any*P("W"))/format_W, + ["j"]=(prefix_any*P("j"))/format_j, + ["J"]=(prefix_any*P("J"))/format_J, + ["m"]=(prefix_any*P("m"))/format_m, + ["M"]=(prefix_any*P("M"))/format_M, + ["z"]=(prefix_any*P("z"))/format_z, + ["a"]=(prefix_any*P("a"))/format_a, + ["A"]=(prefix_any*P("A"))/format_A, + ["<"]=(prefix_any*P("<"))/format_left, + [">"]=(prefix_any*P(">"))/format_right, + ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, + ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest, + ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local xx=setmetatable({},{ __index=function(t,k) local v=format("%02x",k) t[k]=v return v end }) local XX=setmetatable({},{ __index=function(t,k) local v=format("%02X",k) t[k]=v return v end }) local preset={ - ["%02x"]=function(n) return xx[n] end, - ["%02X"]=function(n) return XX[n] end, + ["%02x"]=function(n) return xx[n] end, + ["%02X"]=function(n) return XX[n] end, } -local direct=P("%")*(S("+- .")+R("09"))^0*S("sqidfgGeExXo")*P(-1)/[[local format = string.format return function(str) return format("%0",str) end]] +local direct=P("%")*(sign+space+period+digit)^0*S("sqidfgGeExXo")*endofstring/[[local format = string.format return function(str) return format("%0",str) end]] local function make(t,str) - local f=preset[str] - if f then - return f - end - local p=lpegmatch(direct,str) - if p then - f=loadstripped(p)() + local f=preset[str] + if f then + return f + end + local p=lpegmatch(direct,str) + if p then + f=loadstripped(p)() + else + n=0 + p=lpegmatch(builder,str,1,t._connector_,t._extensions_) + if n>0 then + p=format(template,preamble,t._preamble_,arguments[n],p) + f=loadstripped(p,t._environment_)() else - n=0 - p=lpegmatch(builder,str,1,t._connector_,t._extensions_) - if n>0 then - p=format(template,preamble,t._preamble_,arguments[n],p) - f=loadstripped(p,t._environment_)() - else - f=function() return str end - end + f=function() return str end end - t[str]=f - return f + end + t[str]=f + return f end local function use(t,fmt,...) - return t[fmt](...) + return t[fmt](...) end strings.formatters={} -if oldfashioned then - function strings.formatters.new(noconcat) - local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } - setmetatable(t,{ __index=make,__call=use }) - return t - end -else - function strings.formatters.new(noconcat) - local e={} - for k,v in next,environment do - e[k]=v - end - local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_="",_environment_=e } - setmetatable(t,{ __index=make,__call=use }) - return t - end +function strings.formatters.new(noconcat) + local e={} + for k,v in next,environment do + e[k]=v + end + local t={ + _type_="formatter", + _connector_=noconcat and "," or "..", + _extensions_={}, + _preamble_="", + _environment_=e, + } + setmetatable(t,{ __index=make,__call=use }) + return t end local formatters=strings.formatters.new() string.formatters=formatters string.formatter=function(str,...) return formatters[str](...) end local function add(t,name,template,preamble) - if type(t)=="table" and t._type_=="formatter" then - t._extensions_[name]=template or "%s" - if type(preamble)=="string" then - t._preamble_=preamble.."\n"..t._preamble_ - elseif type(preamble)=="table" then - for k,v in next,preamble do - t._environment_[k]=v - end - end + if type(t)=="table" and t._type_=="formatter" then + t._extensions_[name]=template or "%s" + if type(preamble)=="string" then + t._preamble_=preamble.."\n"..t._preamble_ + elseif type(preamble)=="table" then + for k,v in next,preamble do + t._environment_[k]=v + end end + end end strings.formatters.add=add -patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) -patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) +patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+anything)^0) +patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+anything)^0) patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"')) -if oldfashioned then - add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape") - add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape") - add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape") -else - add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape }) - add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape }) - add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape }) -end +add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],{ xmlescape=lpeg.patterns.xmlescape }) +add(formatters,"tex",[[lpegmatch(texescape,%s)]],{ texescape=lpeg.patterns.texescape }) +add(formatters,"lua",[[lpegmatch(luaescape,%s)]],{ luaescape=lpeg.patterns.luaescape }) local dquote=patterns.dquote local equote=patterns.escaped+dquote/'\\"'+1 -local space=patterns.space local cquote=Cc('"') -local pattern=Cs(dquote*(equote-P(-2))^0*dquote) +local pattern=Cs(dquote*(equote-P(-2))^0*dquote) +Cs(cquote*(equote-space)^0*space*equote^0*cquote) function string.optionalquoted(str) - return lpegmatch(pattern,str) or str + return lpegmatch(pattern,str) or str end local pattern=Cs((newline/(os.newline or "\r")+1)^0) function string.replacenewlines(str) - return lpegmatch(pattern,str) + return lpegmatch(pattern,str) end function strings.newcollector() - local result,r={},0 - return - function(fmt,str,...) - r=r+1 - result[r]=str==nil and fmt or formatters[fmt](str,...) - end, - function(connector) - if result then - local str=concat(result,connector) - result,r={},0 - return str - end - end + local result,r={},0 + return + function(fmt,str,...) + r=r+1 + result[r]=str==nil and fmt or formatters[fmt](str,...) + end, + function(connector) + if result then + local str=concat(result,connector) + result,r={},0 + return str + end + end +end +local f_16_16=formatters["%0.5N"] +function number.to16dot16(n) + return f_16_16(n/65536.0) end end -- closure @@ -4541,12 +3892,13 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['util-fil']={ - 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" + 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" } +local tonumber=tonumber local byte=string.byte local char=string.char utilities=utilities or {} @@ -4554,251 +3906,280 @@ local files={} utilities.files=files local zerobased={} function files.open(filename,zb) - local f=io.open(filename,"rb") - if f then - zerobased[f]=zb or false - end - return f + local f=io.open(filename,"rb") + if f then + zerobased[f]=zb or false + end + return f end function files.close(f) - zerobased[f]=nil - f:close() + zerobased[f]=nil + f:close() end function files.size(f) - local current=f:seek() - local size=f:seek("end") - f:seek("set",current) - return size + local current=f:seek() + local size=f:seek("end") + f:seek("set",current) + return size end files.getsize=files.size function files.setposition(f,n) - if zerobased[f] then - f:seek("set",n) - else - f:seek("set",n-1) - end + if zerobased[f] then + f:seek("set",n) + else + f:seek("set",n-1) + end end function files.getposition(f) - if zerobased[f] then - return f:seek() - else - return f:seek()+1 - end + if zerobased[f] then + return f:seek() + else + return f:seek()+1 + end end function files.look(f,n,chars) - local p=f:seek() - local s=f:read(n) - f:seek("set",p) - if chars then - return s - else - return byte(s,1,#s) - end + local p=f:seek() + local s=f:read(n) + f:seek("set",p) + if chars then + return s + else + return byte(s,1,#s) + end end function files.skip(f,n) - if n==1 then - f:read(n) - else - f:seek("set",f:seek()+n) - end + if n==1 then + f:read(n) + else + f:seek("set",f:seek()+n) + end end function files.readbyte(f) - return byte(f:read(1)) + return byte(f:read(1)) end function files.readbytes(f,n) - return byte(f:read(n),1,n) + return byte(f:read(n),1,n) end function files.readbytetable(f,n) - local s=f:read(n or 1) - return { byte(s,1,#s) } + local s=f:read(n or 1) + return { byte(s,1,#s) } end function files.readchar(f) - return f:read(1) + return f:read(1) end function files.readstring(f,n) - return f:read(n or 1) + return f:read(n or 1) end -function files.readinteger1(f) - local n=byte(f:read(1)) - if n>=0x80 then - return n-0x100 - else - return n - end +function files.readinteger1(f) + local n=byte(f:read(1)) + if n>=0x80 then + return n-0x100 + else + return n + end end -files.readcardinal1=files.readbyte +files.readcardinal1=files.readbyte files.readcardinal=files.readcardinal1 files.readinteger=files.readinteger1 files.readsignedbyte=files.readinteger1 function files.readcardinal2(f) - local a,b=byte(f:read(2),1,2) - return 0x100*a+b + local a,b=byte(f:read(2),1,2) + return 0x100*a+b end function files.readcardinal2le(f) - local b,a=byte(f:read(2),1,2) - return 0x100*a+b + local b,a=byte(f:read(2),1,2) + return 0x100*a+b end function files.readinteger2(f) - local a,b=byte(f:read(2),1,2) - if a>=0x80 then - return 0x100*a+b-0x10000 - else - return 0x100*a+b - end + local a,b=byte(f:read(2),1,2) + if a>=0x80 then + return 0x100*a+b-0x10000 + else + return 0x100*a+b + end end function files.readinteger2le(f) - local b,a=byte(f:read(2),1,2) - if a>=0x80 then - return 0x100*a+b-0x10000 - else - return 0x100*a+b - end + local b,a=byte(f:read(2),1,2) + if a>=0x80 then + return 0x100*a+b-0x10000 + else + return 0x100*a+b + end end function files.readcardinal3(f) - local a,b,c=byte(f:read(3),1,3) - return 0x10000*a+0x100*b+c + local a,b,c=byte(f:read(3),1,3) + return 0x10000*a+0x100*b+c end function files.readcardinal3le(f) - local c,b,a=byte(f:read(3),1,3) - return 0x10000*a+0x100*b+c + local c,b,a=byte(f:read(3),1,3) + return 0x10000*a+0x100*b+c end function files.readinteger3(f) - local a,b,c=byte(f:read(3),1,3) - if a>=0x80 then - return 0x10000*a+0x100*b+c-0x1000000 - else - return 0x10000*a+0x100*b+c - end + local a,b,c=byte(f:read(3),1,3) + if a>=0x80 then + return 0x10000*a+0x100*b+c-0x1000000 + else + return 0x10000*a+0x100*b+c + end end function files.readinteger3le(f) - local c,b,a=byte(f:read(3),1,3) - if a>=0x80 then - return 0x10000*a+0x100*b+c-0x1000000 - else - return 0x10000*a+0x100*b+c - end + local c,b,a=byte(f:read(3),1,3) + if a>=0x80 then + return 0x10000*a+0x100*b+c-0x1000000 + else + return 0x10000*a+0x100*b+c + end end function files.readcardinal4(f) - local a,b,c,d=byte(f:read(4),1,4) - return 0x1000000*a+0x10000*b+0x100*c+d + local a,b,c,d=byte(f:read(4),1,4) + return 0x1000000*a+0x10000*b+0x100*c+d end function files.readcardinal4le(f) - local d,c,b,a=byte(f:read(4),1,4) - return 0x1000000*a+0x10000*b+0x100*c+d + local d,c,b,a=byte(f:read(4),1,4) + return 0x1000000*a+0x10000*b+0x100*c+d end function files.readinteger4(f) - local a,b,c,d=byte(f:read(4),1,4) - if a>=0x80 then - return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 - else - return 0x1000000*a+0x10000*b+0x100*c+d - end + local a,b,c,d=byte(f:read(4),1,4) + if a>=0x80 then + return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 + else + return 0x1000000*a+0x10000*b+0x100*c+d + end end function files.readinteger4le(f) - local d,c,b,a=byte(f:read(4),1,4) - if a>=0x80 then - return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 - else - return 0x1000000*a+0x10000*b+0x100*c+d - end + local d,c,b,a=byte(f:read(4),1,4) + if a>=0x80 then + return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 + else + return 0x1000000*a+0x10000*b+0x100*c+d + end end function files.readfixed2(f) - local a,b=byte(f:read(2),1,2) - if a>=0x80 then - return (a-0x100)+b/0x100 - else - return (a )+b/0x100 - end + local a,b=byte(f:read(2),1,2) + if a>=0x80 then + tonumber((a-0x100).."."..b) + else + tonumber((a ).."."..b) + end end function files.readfixed4(f) - local a,b,c,d=byte(f:read(4),1,4) - if a>=0x80 then - return (0x100*a+b-0x10000)+(0x100*c+d)/0x10000 - else - return (0x100*a+b )+(0x100*c+d)/0x10000 - end + local a,b,c,d=byte(f:read(4),1,4) + if a>=0x80 then + tonumber((0x100*a+b-0x10000).."."..(0x100*c+d)) + else + tonumber((0x100*a+b ).."."..(0x100*c+d)) + end end if bit32 then - local extract=bit32.extract - local band=bit32.band - function files.read2dot14(f) - local a,b=byte(f:read(2),1,2) - if a>=0x80 then - local n=-(0x100*a+b) - return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0)) - else - local n=0x100*a+b - return (extract(n,14,2)+(band(n,0x3FFF)/16384.0)) - end + local extract=bit32.extract + local band=bit32.band + function files.read2dot14(f) + local a,b=byte(f:read(2),1,2) + if a>=0x80 then + local n=-(0x100*a+b) + return-(extract(n,14,2)+(band(n,0x3FFF)/16384.0)) + else + local n=0x100*a+b + return (extract(n,14,2)+(band(n,0x3FFF)/16384.0)) end + end end function files.skipshort(f,n) - f:read(2*(n or 1)) + f:read(2*(n or 1)) end function files.skiplong(f,n) - f:read(4*(n or 1)) + f:read(4*(n or 1)) end if bit32 then - local rshift=bit32.rshift - function files.writecardinal2(f,n) - local a=char(n%256) - n=rshift(n,8) - local b=char(n%256) - f:write(b,a) - end -else - local floor=math.floor - function files.writecardinal2(f,n) - local a=char(n%256) - n=floor(n/256) - local b=char(n%256) - f:write(b,a) - end -end -function files.writecardinal4(f,n) + local rshift=bit32.rshift + function files.writecardinal2(f,n) local a=char(n%256) n=rshift(n,8) local b=char(n%256) - n=rshift(n,8) - local c=char(n%256) - n=rshift(n,8) - local d=char(n%256) - f:write(d,c,b,a) + f:write(b,a) + end +else + local floor=math.floor + function files.writecardinal2(f,n) + local a=char(n%256) + n=floor(n/256) + local b=char(n%256) + f:write(b,a) + end +end +function files.writecardinal4(f,n) + local a=char(n%256) + n=rshift(n,8) + local b=char(n%256) + n=rshift(n,8) + local c=char(n%256) + n=rshift(n,8) + local d=char(n%256) + f:write(d,c,b,a) end function files.writestring(f,s) - f:write(char(byte(s,1,#s))) + f:write(char(byte(s,1,#s))) end function files.writebyte(f,b) - f:write(char(b)) + f:write(char(b)) end if fio and fio.readcardinal1 then - files.readcardinal1=fio.readcardinal1 - files.readcardinal2=fio.readcardinal2 - files.readcardinal3=fio.readcardinal3 - files.readcardinal4=fio.readcardinal4 - files.readinteger1=fio.readinteger1 - files.readinteger2=fio.readinteger2 - files.readinteger3=fio.readinteger3 - files.readinteger4=fio.readinteger4 - files.readfixed2=fio.readfixed2 - files.readfixed4=fio.readfixed4 - files.read2dot14=fio.read2dot14 - files.setposition=fio.setposition - files.getposition=fio.getposition - files.readbyte=files.readcardinal1 - files.readsignedbyte=files.readinteger1 - files.readcardinal=files.readcardinal1 - files.readinteger=files.readinteger1 - local skipposition=fio.skipposition - files.skipposition=skipposition - files.readbytes=fio.readbytes - files.readbytetable=fio.readbytetable - function files.skipshort(f,n) - skipposition(f,2*(n or 1)) - end - function files.skiplong(f,n) - skipposition(f,4*(n or 1)) - end + files.readcardinal1=fio.readcardinal1 + files.readcardinal2=fio.readcardinal2 + files.readcardinal3=fio.readcardinal3 + files.readcardinal4=fio.readcardinal4 + files.readinteger1=fio.readinteger1 + files.readinteger2=fio.readinteger2 + files.readinteger3=fio.readinteger3 + files.readinteger4=fio.readinteger4 + files.readfixed2=fio.readfixed2 + files.readfixed4=fio.readfixed4 + files.read2dot14=fio.read2dot14 + files.setposition=fio.setposition + files.getposition=fio.getposition + files.readbyte=files.readcardinal1 + files.readsignedbyte=files.readinteger1 + files.readcardinal=files.readcardinal1 + files.readinteger=files.readinteger1 + local skipposition=fio.skipposition + files.skipposition=skipposition + files.readbytes=fio.readbytes + files.readbytetable=fio.readbytetable + function files.skipshort(f,n) + skipposition(f,2*(n or 1)) + end + function files.skiplong(f,n) + skipposition(f,4*(n or 1)) + end +end +if fio and fio.readcardinaltable then + files.readcardinaltable=fio.readcardinaltable + files.readintegertable=fio.readintegertable +else + local readcardinal1=files.readcardinal1 + local readcardinal2=files.readcardinal2 + local readcardinal3=files.readcardinal3 + local readcardinal4=files.readcardinal4 + function files.readcardinaltable(f,n,b) + local t={} + if b==1 then for i=1,n do t[i]=readcardinal1(f) end + elseif b==2 then for i=1,n do t[i]=readcardinal2(f) end + elseif b==3 then for i=1,n do t[i]=readcardinal3(f) end + elseif b==4 then for i=1,n do t[i]=readcardinal4(f) end end + return t + end + local readinteger1=files.readinteger1 + local readinteger2=files.readinteger2 + local readinteger3=files.readinteger3 + local readinteger4=files.readinteger4 + function files.readintegertable(f,n,b) + local t={} + if b==1 then for i=1,n do t[i]=readinteger1(f) end + elseif b==2 then for i=1,n do t[i]=readinteger2(f) end + elseif b==3 then for i=1,n do t[i]=readinteger3(f) end + elseif b==4 then for i=1,n do t[i]=readinteger4(f) end end + return t + end end end -- closure @@ -4806,287 +4187,383 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luat-basics-gen']={ - version=1.100, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.100, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end +local match,gmatch,gsub,lower=string.match,string.gmatch,string.gsub,string.lower +local formatters,split,format,dump=string.formatters,string.split,string.format,string.dump +local loadfile,type=loadfile,type +local setmetatable,getmetatable,collectgarbage=setmetatable,getmetatable,collectgarbage +local floor=math.floor local dummyfunction=function() end local dummyreporter=function(c) - return function(f,...) - local r=texio.reporter or texio.write_nl - if f then - r(c.." : "..string.formatters(f,...)) - else - r("") - end + return function(f,...) + local r=texio.reporter or texio.write_nl + if f then + r(c.." : "..(formatters or format)(f,...)) + else + r("") end + end +end +local dummyreport=function(c,f,...) + local r=texio.reporter or texio.write_nl + if f then + r(c.." : "..(formatters or format)(f,...)) + else + r("") + end end statistics={ - register=dummyfunction, - starttiming=dummyfunction, - stoptiming=dummyfunction, - elapsedtime=nil, + register=dummyfunction, + starttiming=dummyfunction, + stoptiming=dummyfunction, + elapsedtime=nil, } directives={ - register=dummyfunction, - enable=dummyfunction, - disable=dummyfunction, + register=dummyfunction, + enable=dummyfunction, + disable=dummyfunction, } trackers={ - register=dummyfunction, - enable=dummyfunction, - disable=dummyfunction, + register=dummyfunction, + enable=dummyfunction, + disable=dummyfunction, } experiments={ - register=dummyfunction, - enable=dummyfunction, - disable=dummyfunction, + register=dummyfunction, + enable=dummyfunction, + disable=dummyfunction, } storage={ - register=dummyfunction, - shared={}, + register=dummyfunction, + shared={}, } logs={ - new=dummyreporter, - reporter=dummyreporter, - messenger=dummyreporter, - report=dummyfunction, + new=dummyreporter, + reporter=dummyreporter, + messenger=dummyreporter, + report=dummyreport, } callbacks={ - register=function(n,f) - return callback.register(n,f) - end, + register=function(n,f) + return callback.register(n,f) + end, } -utilities=utilities or {} utilities.storage={ - allocate=function(t) - return t or {} - end, - mark=function(t) - return t or {} - end, +utilities=utilities or {} +utilities.storage=utilities.storage or { + allocate=function(t) + return t or {} + end, + mark=function(t) + return t or {} + end, +} +utilities.parsers=utilities.parsers or { + settings_to_array=function(s) + return split(s,",") + end, + settings_to_hash=function(s) + local t={} + for k,v in gmatch(s,"([^%s,=]+)=([^%s,]+)") do + t[k]=v + end + return t + end, + settings_to_hash_colon_too=function(s) + local t={} + for k,v in gmatch(s,"([^%s,=:]+)[=:]([^%s,]+)") do + t[k]=v + end + return t + end, } characters=characters or { - data={} + data={} } texconfig.kpse_init=true resolvers=resolvers or {} local remapper={ - otf="opentype fonts", - ttf="truetype fonts", - ttc="truetype fonts", - cid="cid maps", - cidmap="cid maps", - pfb="type1 fonts", - afm="afm", - enc="enc files", + otf="opentype fonts", + ttf="truetype fonts", + ttc="truetype fonts", + cid="cid maps", + cidmap="cid maps", + pfb="type1 fonts", + afm="afm", + enc="enc files", + lua="tex", } function resolvers.findfile(name,fileformat) - name=string.gsub(name,"\\","/") - if not fileformat or fileformat=="" then - fileformat=file.suffix(name) - if fileformat=="" then - fileformat="tex" - end - end - fileformat=string.lower(fileformat) - fileformat=remapper[fileformat] or fileformat - local found=kpse.find_file(name,fileformat) - if not found or found=="" then - found=kpse.find_file(name,"other text files") - end - return found + name=gsub(name,"\\","/") + if not fileformat or fileformat=="" then + fileformat=file.suffix(name) + if fileformat=="" then + fileformat="tex" + end + end + fileformat=lower(fileformat) + fileformat=remapper[fileformat] or fileformat + local found=kpse.find_file(name,fileformat) + if not found or found=="" then + found=kpse.find_file(name,"other text files") + end + return found end resolvers.findbinfile=resolvers.findfile function resolvers.loadbinfile(filename,filetype) - local data=io.loaddata(filename) - return true,data,#data + local data=io.loaddata(filename) + return true,data,#data end function resolvers.resolve(s) - return s + return s end function resolvers.unresolve(s) - return s + return s end caches={} local writable=nil local readables={} local usingjit=jit if not caches.namespace or caches.namespace=="" or caches.namespace=="context" then - caches.namespace='generic' + caches.namespace='generic' end do - local cachepaths=kpse.expand_var('$TEXMFCACHE') or "" - if cachepaths=="" or cachepaths=="$TEXMFCACHE" then - cachepaths=kpse.expand_var('$TEXMFVAR') or "" - end - if cachepaths=="" or cachepaths=="$TEXMFVAR" then - cachepaths=kpse.expand_var('$VARTEXMF') or "" - end - if cachepaths=="" then - local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" } - for i=1,#fallbacks do - cachepaths=os.getenv(fallbacks[i]) or "" - if cachepath~="" and lfs.isdir(cachepath) then - break - end - end - end - if cachepaths=="" then - cachepaths="." - end - cachepaths=string.split(cachepaths,os.type=="windows" and ";" or ":") - for i=1,#cachepaths do - local cachepath=cachepaths[i] - if not lfs.isdir(cachepath) then - lfs.mkdirs(cachepath) - if lfs.isdir(cachepath) then - texio.write(string.format("(created cache path: %s)",cachepath)) - end - end - if file.is_writable(cachepath) then - writable=file.join(cachepath,"luatex-cache") - lfs.mkdir(writable) - writable=file.join(writable,caches.namespace) - lfs.mkdir(writable) - break - end - end - for i=1,#cachepaths do - if file.is_readable(cachepaths[i]) then - readables[#readables+1]=file.join(cachepaths[i],"luatex-cache",caches.namespace) - end - end - if not writable then - texio.write_nl("quiting: fix your writable cache path") - os.exit() - elseif #readables==0 then - texio.write_nl("quiting: fix your readable cache path") - os.exit() - elseif #readables==1 and readables[1]==writable then - texio.write(string.format("(using cache: %s)",writable)) - else - texio.write(string.format("(using write cache: %s)",writable)) - texio.write(string.format("(using read cache: %s)",table.concat(readables," "))) - end + local cachepaths=kpse.expand_var('$TEXMFCACHE') or "" + if cachepaths=="" or cachepaths=="$TEXMFCACHE" then + cachepaths=kpse.expand_var('$TEXMFVAR') or "" + end + if cachepaths=="" or cachepaths=="$TEXMFVAR" then + cachepaths=kpse.expand_var('$VARTEXMF') or "" + end + if cachepaths=="" then + local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" } + for i=1,#fallbacks do + cachepaths=os.getenv(fallbacks[i]) or "" + if cachepath~="" and lfs.isdir(cachepath) then + break + end + end + end + if cachepaths=="" then + cachepaths="." + end + cachepaths=split(cachepaths,os.type=="windows" and ";" or ":") + for i=1,#cachepaths do + local cachepath=cachepaths[i] + if not lfs.isdir(cachepath) then + lfs.mkdirs(cachepath) + if lfs.isdir(cachepath) then + logs.report("system","creating cache path '%s'",cachepath) + end + end + if file.is_writable(cachepath) then + writable=file.join(cachepath,"luatex-cache") + lfs.mkdir(writable) + writable=file.join(writable,caches.namespace) + lfs.mkdir(writable) + break + end + end + for i=1,#cachepaths do + if file.is_readable(cachepaths[i]) then + readables[#readables+1]=file.join(cachepaths[i],"luatex-cache",caches.namespace) + end + end + if not writable then + logs.report("system","no writeable cache path, quiting") + os.exit() + elseif #readables==0 then + logs.report("system","no readable cache path, quiting") + os.exit() + elseif #readables==1 and readables[1]==writable then + logs.report("system","using cache '%s'",writable) + else + logs.report("system","using write cache '%s'",writable) + logs.report("system","using read cache '%s'",table.concat(readables," ")) + end end function caches.getwritablepath(category,subcategory) - local path=file.join(writable,category) - lfs.mkdir(path) - path=file.join(path,subcategory) - lfs.mkdir(path) - return path + local path=file.join(writable,category) + lfs.mkdir(path) + path=file.join(path,subcategory) + lfs.mkdir(path) + return path end function caches.getreadablepaths(category,subcategory) - local t={} - for i=1,#readables do - t[i]=file.join(readables[i],category,subcategory) - end - return t + local t={} + for i=1,#readables do + t[i]=file.join(readables[i],category,subcategory) + end + return t end local function makefullname(path,name) - if path and path~="" then - return file.addsuffix(file.join(path,name),"lua"),file.addsuffix(file.join(path,name),usingjit and "lub" or "luc") - end + if path and path~="" then + return file.addsuffix(file.join(path,name),"lua"),file.addsuffix(file.join(path,name),usingjit and "lub" or "luc") + end end function caches.is_writable(path,name) - local fullname=makefullname(path,name) - return fullname and file.is_writable(fullname) + local fullname=makefullname(path,name) + return fullname and file.is_writable(fullname) end function caches.loaddata(readables,name,writable) - for i=1,#readables do - local path=readables[i] - local loader=false - local luaname,lucname=makefullname(path,name) - if lfs.isfile(lucname) then - texio.write(string.format("(load luc: %s)",lucname)) - loader=loadfile(lucname) - end - if not loader and lfs.isfile(luaname) then - local luacrap,lucname=makefullname(writable,name) - texio.write(string.format("(compiling luc: %s)",lucname)) - if lfs.isfile(lucname) then - loader=loadfile(lucname) - end - caches.compile(data,luaname,lucname) - if lfs.isfile(lucname) then - texio.write(string.format("(load luc: %s)",lucname)) - loader=loadfile(lucname) - else - texio.write(string.format("(loading failed: %s)",lucname)) - end - if not loader then - texio.write(string.format("(load lua: %s)",luaname)) - loader=loadfile(luaname) - else - texio.write(string.format("(loading failed: %s)",luaname)) - end - end - if loader then - loader=loader() - collectgarbage("step") - return loader - end - end - return false + for i=1,#readables do + local path=readables[i] + local loader=false + local luaname,lucname=makefullname(path,name) + if lfs.isfile(lucname) then + logs.report("system","loading luc file '%s'",lucname) + loader=loadfile(lucname) + end + if not loader and lfs.isfile(luaname) then + local luacrap,lucname=makefullname(writable,name) + logs.report("system","compiling luc file '%s'",lucname) + if lfs.isfile(lucname) then + loader=loadfile(lucname) + end + caches.compile(data,luaname,lucname) + if lfs.isfile(lucname) then + logs.report("system","loading luc file '%s'",lucname) + loader=loadfile(lucname) + else + logs.report("system","error in loading luc file '%s'",lucname) + end + if not loader then + logs.report("system","loading lua file '%s'",luaname) + loader=loadfile(luaname) + else + logs.report("system","error in loading lua file '%s'",luaname) + end + end + if loader then + loader=loader() + collectgarbage("step") + return loader + end + end + return false end function caches.savedata(path,name,data) - local luaname,lucname=makefullname(path,name) - if luaname then - texio.write(string.format("(save: %s)",luaname)) - table.tofile(luaname,data,true) - if lucname and type(caches.compile)=="function" then - os.remove(lucname) - texio.write(string.format("(save: %s)",lucname)) - caches.compile(data,luaname,lucname) - end + local luaname,lucname=makefullname(path,name) + if luaname then + logs.report("system","saving lua file '%s'",luaname) + table.tofile(luaname,data,true) + if lucname and type(caches.compile)=="function" then + os.remove(lucname) + logs.report("system","saving luc file '%s'",lucname) + caches.compile(data,luaname,lucname) end + end end function caches.compile(data,luaname,lucname) - local d=io.loaddata(luaname) - if not d or d=="" then - d=table.serialize(data,true) - end - if d and d~="" then - local f=io.open(lucname,'wb') - if f then - local s=loadstring(d) - if s then - f:write(string.dump(s,true)) - end - f:close() - end + local d=io.loaddata(luaname) + if not d or d=="" then + d=table.serialize(data,true) + end + if d and d~="" then + local f=io.open(lucname,'wb') + if f then + local s=loadstring(d) + if s then + f:write(dump(s,true)) + end + f:close() end + end end function table.setmetatableindex(t,f) - if type(t)~="table" then - f,t=t,{} - end - local m=getmetatable(t) - if f=="table" then - f=function(t,k) local v={} t[k]=v return v end - end - if m then - m.__index=f - else - setmetatable(t,{ __index=f }) - end - return t + if type(t)~="table" then + f,t=t,{} + end + local m=getmetatable(t) + if f=="table" then + f=function(t,k) local v={} t[k]=v return v end + end + if m then + m.__index=f + else + setmetatable(t,{ __index=f }) + end + return t +end +function table.makeweak(t) + local m=getmetatable(t) + if m then + m.__mode="v" + else + setmetatable(t,{ __mode="v" }) + end + return t end arguments={} if arg then - for i=1,#arg do - local k,v=string.match(arg[i],"^%-%-([^=]+)=?(.-)$") - if k and v then - arguments[k]=v + for i=1,#arg do + local k,v=match(arg[i],"^%-%-([^=]+)=?(.-)$") + if k and v then + arguments[k]=v + end + end +end +if not number.idiv then + function number.idiv(i,d) + return floor(i/d) + end +end +local u=unicode and unicode.utf8 +if u then + utf.lower=u.lower + utf.upper=u.upper + utf.char=u.char + utf.byte=u.byte + utf.len=u.len + if lpeg.setutfcasers then + lpeg.setutfcasers(u.lower,u.upper) + end + local bytepairs=string.bytepairs + local utfchar=utf.char + local concat=table.concat + function utf.utf16_to_utf8_be(s) + if not s then + return nil + elseif s=="" then + return "" + end + local result,r,more={},0,0 + for left,right in bytepairs(s) do + if right then + local now=256*left+right + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now + else + r=r+1 + result[r]=utfchar(now) end + end end + return concat(result) + end + local characters=string.utfcharacters + function utf.split(str) + local t,n={},0 + for s in characters(str) do + n=n+1 + t[n]=s + end + return t + end end end -- closure @@ -5094,113 +4571,113 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['data-con']={ - version=1.100, - 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" + version=1.100, + 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" } local format,lower,gsub=string.format,string.lower,string.gsub -local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) -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) +local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) +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) containers=containers or {} local containers=containers containers.usecache=true local report_containers=logs.reporter("resolvers","containers") local allocated={} local mt={ - __index=function(t,k) - if k=="writable" then - local writable=caches.getwritablepath(t.category,t.subcategory) or { "." } - t.writable=writable - return writable - elseif k=="readables" then - local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." } - t.readables=readables - return readables - end - end, - __storage__=true + __index=function(t,k) + if k=="writable" then + local writable=caches.getwritablepath(t.category,t.subcategory) or { "." } + t.writable=writable + return writable + elseif k=="readables" then + local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." } + t.readables=readables + return readables + end + end, + __storage__=true } function containers.define(category,subcategory,version,enabled) - if category and subcategory then - local c=allocated[category] - if not c then - c={} - allocated[category]=c - end - local s=c[subcategory] - if not s then - s={ - category=category, - subcategory=subcategory, - storage={}, - enabled=enabled, - version=version or math.pi, - trace=false, - } - setmetatable(s,mt) - c[subcategory]=s - end - return s + if category and subcategory then + local c=allocated[category] + if not c then + c={} + allocated[category]=c + end + local s=c[subcategory] + if not s then + s={ + category=category, + subcategory=subcategory, + storage={}, + enabled=enabled, + version=version or math.pi, + trace=false, + } + setmetatable(s,mt) + c[subcategory]=s end + return s + end end function containers.is_usable(container,name) - return container.enabled and caches and caches.is_writable(container.writable,name) + return container.enabled and caches and caches.is_writable(container.writable,name) end function containers.is_valid(container,name) - if name and name~="" then - local storage=container.storage[name] - return storage and storage.cache_version==container.version - else - return false - end + if name and name~="" then + local storage=container.storage[name] + return storage and storage.cache_version==container.version + else + return false + end end function containers.read(container,name) - local storage=container.storage - local stored=storage[name] - if not stored and container.enabled and caches and containers.usecache then - stored=caches.loaddata(container.readables,name,container.writable) - if stored and stored.cache_version==container.version then - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","load",container.subcategory,name) - end - else - stored=nil - end - storage[name]=stored - elseif stored then - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","reuse",container.subcategory,name) - end + local storage=container.storage + local stored=storage[name] + if not stored and container.enabled and caches and containers.usecache then + stored=caches.loaddata(container.readables,name,container.writable) + if stored and stored.cache_version==container.version then + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","load",container.subcategory,name) + end + else + stored=nil + end + storage[name]=stored + elseif stored then + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","reuse",container.subcategory,name) end - return stored + end + return stored end function containers.write(container,name,data) - if data then - data.cache_version=container.version - if container.enabled and caches then - local unique,shared=data.unique,data.shared - data.unique,data.shared=nil,nil - caches.savedata(container.writable,name,data) - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","save",container.subcategory,name) - end - data.unique,data.shared=unique,shared - end - if trace_cache or trace_containers then - report_containers("action %a, category %a, name %a","store",container.subcategory,name) - end - container.storage[name]=data - end - return data + if data then + data.cache_version=container.version + if container.enabled and caches then + local unique,shared=data.unique,data.shared + data.unique,data.shared=nil,nil + caches.savedata(container.writable,name,data) + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","save",container.subcategory,name) + end + data.unique,data.shared=unique,shared + end + if trace_cache or trace_containers then + report_containers("action %a, category %a, name %a","store",container.subcategory,name) + end + container.storage[name]=data + end + return data end function containers.content(container,name) - return container.storage[name] + return container.storage[name] end function containers.cleanname(name) - return (gsub(lower(name),"[^%w\128-\255]+","-")) + return (gsub(lower(name),"[^%w\128-\255]+","-")) end end -- closure @@ -5208,37 +4685,37 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luatex-fonts-nod']={ - version=1.001, - comment="companion to luatex-fonts.lua", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to luatex-fonts.lua", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end if tex.attribute[0]~=0 then - texio.write_nl("log","!") - texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be") - texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special") - texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.") - texio.write_nl("log","!") - tex.attribute[0]=0 + texio.write_nl("log","!") + texio.write_nl("log","! Attribute 0 is reserved for ConTeXt's font feature management and has to be") + texio.write_nl("log","! set to zero. Also, some attributes in the range 1-255 are used for special") + texio.write_nl("log","! purposes so setting them at the TeX end might break the font handler.") + texio.write_nl("log","!") + tex.attribute[0]=0 end attributes=attributes or {} attributes.unsetvalue=-0x7FFFFFFF local numbers,last={},127 attributes.private=attributes.private or function(name) - local number=numbers[name] - if not number then - if last<255 then - last=last+1 - end - number=last - numbers[name]=number + local number=numbers[name] + if not number then + if last<255 then + last=last+1 end - return number + number=last + numbers[name]=number + end + return number end nodes={} nodes.handlers={} @@ -5246,15 +4723,15 @@ local nodecodes={} local glyphcodes=node.subtypes("glyph") local disccodes=node.subtypes("disc") for k,v in next,node.types() do - v=string.gsub(v,"_","") - nodecodes[k]=v - nodecodes[v]=k + v=string.gsub(v,"_","") + nodecodes[k]=v + nodecodes[v]=k end -for i=0,#glyphcodes do - glyphcodes[glyphcodes[i]]=i +for k,v in next,glyphcodes do + glyphcodes[v]=k end -for i=0,#disccodes do - disccodes[disccodes[i]]=i +for k,v in next,disccodes do + disccodes[v]=k end nodes.nodecodes=nodecodes nodes.glyphcodes=glyphcodes @@ -5262,32 +4739,23 @@ nodes.disccodes=disccodes local flush_node=node.flush_node local remove_node=node.remove local traverse_id=node.traverse_id -nodes.handlers.protectglyphs=node.protect_glyphs -nodes.handlers.unprotectglyphs=node.unprotect_glyphs -local math_code=nodecodes.math -local end_of_math=node.end_of_math -function node.end_of_math(n) - if n.id==math_code and n.subtype==1 then - return n - else - return end_of_math(n) - end -end +nodes.handlers.protectglyphs=node.protect_glyphs +nodes.handlers.unprotectglyphs=node.unprotect_glyphs function nodes.remove(head,current,free_too) - local t=current - head,current=remove_node(head,current) - if t then - if free_too then - flush_node(t) - t=nil - else - t.next,t.prev=nil,nil - end + local t=current + head,current=remove_node(head,current) + if t then + if free_too then + flush_node(t) + t=nil + else + t.next,t.prev=nil,nil end - return head,current,t + end + return head,current,t end function nodes.delete(head,current) - return nodes.remove(head,current,true) + return nodes.remove(head,current,true) end local getfield=node.getfield local setfield=node.setfield @@ -5338,131 +4806,99 @@ nodes.tonode=tonode nodes.tonut=tonut nuts.tonode=tonode nuts.tonut=tonut -local getfield=direct.getfield -local setfield=direct.setfield -nuts.getfield=getfield -nuts.setfield=setfield -nuts.getnext=direct.getnext -nuts.setnext=direct.setnext -nuts.getprev=direct.getprev -nuts.setprev=direct.setprev +nuts.getattr=direct.get_attribute nuts.getboth=direct.getboth -nuts.setboth=direct.setboth -nuts.getid=direct.getid -nuts.getattr=direct.get_attribute or direct.has_attribute or getfield -nuts.setattr=setfield +nuts.getchar=direct.getchar +nuts.getcomponents=direct.getcomponents +nuts.getdirection=direct.getdirection +nuts.getdisc=direct.getdisc +nuts.getfield=direct.getfield nuts.getfont=direct.getfont -nuts.setfont=direct.setfont +nuts.getid=direct.getid +nuts.getkern=direct.getkern +nuts.getlist=direct.getlist +nuts.getnext=direct.getnext +nuts.getoffsets=direct.getoffsets +nuts.getprev=direct.getprev nuts.getsubtype=direct.getsubtype -nuts.setsubtype=direct.setsubtype -nuts.getchar=direct.getchar +nuts.getwidth=direct.getwidth +nuts.setattr=direct.setfield +nuts.setboth=direct.setboth nuts.setchar=direct.setchar -nuts.getdisc=direct.getdisc +nuts.setcomponents=direct.setcomponents +nuts.setdir=direct.setdir +nuts.setdirection=direct.setdirection nuts.setdisc=direct.setdisc +nuts.setfield=setfield +nuts.setkern=direct.setkern nuts.setlink=direct.setlink -nuts.setsplit=direct.setsplit -nuts.getlist=direct.getlist nuts.setlist=direct.setlist -nuts.getoffsets=direct.getoffsets or - function(n) - return getfield(n,"xoffset"),getfield(n,"yoffset") - end -nuts.setoffsets=direct.setoffsets or - function(n,x,y) - if x then setfield(n,"xoffset",x) end - if y then setfield(n,"xoffset",y) end - end -nuts.getleader=direct.getleader or function(n) return getfield(n,"leader") end -nuts.setleader=direct.setleader or function(n,l) setfield(n,"leader",l) end -nuts.getcomponents=direct.getcomponents or function(n) return getfield(n,"components") end -nuts.setcomponents=direct.setcomponents or function(n,c) setfield(n,"components",c) end -nuts.getkern=direct.getkern or function(n) return getfield(n,"kern") end -nuts.setkern=direct.setkern or function(n,k) setfield(n,"kern",k) end -nuts.getdir=direct.getdir or function(n) return getfield(n,"dir") end -nuts.setdir=direct.setdir or function(n,d) setfield(n,"dir",d) end -nuts.getwidth=direct.getwidth or function(n) return getfield(n,"width") end -nuts.setwidth=direct.setwidth or function(n,w) return setfield(n,"width",w) end -nuts.getheight=direct.getheight or function(n) return getfield(n,"height") end -nuts.setheight=direct.setheight or function(n,h) return setfield(n,"height",h) end -nuts.getdepth=direct.getdepth or function(n) return getfield(n,"depth") end -nuts.setdepth=direct.setdepth or function(n,d) return setfield(n,"depth",d) end -if not direct.is_glyph then - local getchar=direct.getchar - local getid=direct.getid - local getfont=direct.getfont - local glyph_code=nodes.nodecodes.glyph - function direct.is_glyph(n,f) - local id=getid(n) - if id==glyph_code then - if f and getfont(n)==f then - return getchar(n) - else - return false - end - else - return nil,id - end - end - function direct.is_char(n,f) - local id=getid(n) - if id==glyph_code then - if getsubtype(n)>=256 then - return false - elseif f and getfont(n)==f then - return getchar(n) - else - return false - end - else - return nil,id - end - end -end -nuts.ischar=direct.is_char +nuts.setnext=direct.setnext +nuts.setoffsets=direct.setoffsets +nuts.setprev=direct.setprev +nuts.setsplit=direct.setsplit +nuts.setsubtype=direct.setsubtype +nuts.setwidth=direct.setwidth nuts.is_char=direct.is_char -nuts.isglyph=direct.is_glyph nuts.is_glyph=direct.is_glyph -nuts.insert_before=direct.insert_before -nuts.insert_after=direct.insert_after -nuts.delete=direct.delete +nuts.ischar=direct.is_char +nuts.isglyph=direct.is_glyph nuts.copy=direct.copy -nuts.copy_node=direct.copy nuts.copy_list=direct.copy_list -nuts.tail=direct.tail +nuts.copy_node=direct.copy +nuts.delete=direct.delete +nuts.end_of_math=direct.end_of_math +nuts.flush=direct.flush nuts.flush_list=direct.flush_list nuts.flush_node=direct.flush_node -nuts.flush=direct.flush nuts.free=direct.free -nuts.remove=direct.remove +nuts.insert_after=direct.insert_after +nuts.insert_before=direct.insert_before nuts.is_node=direct.is_node -nuts.end_of_math=direct.end_of_math -nuts.traverse=direct.traverse -nuts.traverse_id=direct.traverse_id -nuts.traverse_char=direct.traverse_char -nuts.ligaturing=direct.ligaturing nuts.kerning=direct.kerning +nuts.ligaturing=direct.ligaturing nuts.new=direct.new -nuts.getprop=nuts.getattr -nuts.setprop=nuts.setattr +nuts.remove=direct.remove +nuts.tail=direct.tail +nuts.traverse=direct.traverse +nuts.traverse_char=direct.traverse_char +nuts.traverse_glyph=direct.traverse_glyph +nuts.traverse_id=direct.traverse_id +if not nuts.getdirection then + local getdir=direct.getdir + function nuts.getdirection(n) + local d=getdir(n) + if d=="TLT" then return 0 + elseif d=="TRT" then return 1 + elseif d=="+TLT" then return 0,false + elseif d=="+TRT" then return 1,false + elseif d=="-TLT" then return 0,true + elseif d=="-TRT" then return 1,true + else return 0 + end + end +end local propertydata=direct.get_properties_table() nodes.properties={ data=propertydata } -direct.set_properties_mode(true,true) -function direct.set_properties_mode() end +if direct.set_properties_mode then + direct.set_properties_mode(true,true) + function direct.set_properties_mode() end +end nuts.getprop=function(n,k) - local p=propertydata[n] - if p then - return p[k] - end + local p=propertydata[n] + if p then + return p[k] + end end nuts.setprop=function(n,k,v) - if v then - local p=propertydata[n] - if p then - p[k]=v - else - propertydata[n]={ [k]=v } - end + if v then + local p=propertydata[n] + if p then + p[k]=v + else + propertydata[n]={ [k]=v } end + end end nodes.setprop=nodes.setproperty nodes.getprop=nodes.getproperty @@ -5480,131 +4916,49 @@ local flush_node=nuts.flush_node local traverse_id=nuts.traverse_id local copy_node=nuts.copy_node local glyph_code=nodes.nodecodes.glyph -function nuts.set_components(target,start,stop) - local head=getcomponents(target) - if head then - flush_list(head) - head=nil - end - if start then - setprev(start) - else - return nil - end - if stop then - setnext(stop) - end - local tail=nil - while start do - local c=getcomponents(start) - local n=getnext(start) - if c then - if head then - setlink(tail,c) - else - head=c - end - tail=find_tail(c) - setcomponents(start) - flush_node(start) - else - if head then - setlink(tail,start) - else - head=start - end - tail=start - end - start=n - end - setcomponents(target,head) - return head -end -nuts.get_components=nuts.getcomponents -function nuts.take_components(target) - local c=getcomponents(target) - setcomponents(target) - return c -end -function nuts.count_components(n,marks) - local components=getcomponents(n) - if components then - if marks then - local i=0 - for g in traverse_id(glyph_code,components) do - if not marks[getchar(g)] then - i=i+1 - end - end - return i - else - return count(glyph_code,components) - end - else - return 0 - end -end function nuts.copy_no_components(g,copyinjection) - local components=getcomponents(g) - if components then - setcomponents(g) - local n=copy_node(g) - if copyinjection then - copyinjection(n,g) - end - setcomponents(g,components) - return n - else - local n=copy_node(g) - if copyinjection then - copyinjection(n,g) - end - return n + local components=getcomponents(g) + if components then + setcomponents(g) + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) + end + setcomponents(g,components) + return n + else + local n=copy_node(g) + if copyinjection then + copyinjection(n,g) end + return n + end end function nuts.copy_only_glyphs(current) - local head=nil - local previous=nil - for n in traverse_id(glyph_code,current) do - n=copy_node(n) - if head then - setlink(previous,n) - else - head=n - end - previous=n + local head=nil + local previous=nil + for n in traverse_id(glyph_code,current) do + n=copy_node(n) + if head then + setlink(previous,n) + else + head=n end - return head + previous=n + end + return head end nuts.uses_font=direct.uses_font -if not nuts.uses_font then - local getdisc=nuts.getdisc - local getfont=nuts.getfont - function nuts.uses_font(n,font) - local pre,post,replace=getdisc(n) - if pre then - for n in traverse_id(glyph_code,pre) do - if getfont(n)==font then - return true - end - end - end - if post then - for n in traverse_id(glyph_code,post) do - if getfont(n)==font then - return true - end - end - end - if replace then - for n in traverse_id(glyph_code,replace) do - if getfont(n)==font then - return true - end - end - end - return false - end +do + local dummy=tonut(node.new("glyph")) + nuts.traversers={ + glyph=nuts.traverse_id(nodecodes.glyph,dummy), + glue=nuts.traverse_id(nodecodes.glue,dummy), + disc=nuts.traverse_id(nodecodes.disc,dummy), + boundary=nuts.traverse_id(nodecodes.boundary,dummy), + char=nuts.traverse_char(dummy), + node=nuts.traverse(dummy), + } end end -- closure @@ -7862,989 +7216,989 @@ characters.classifiers={ } characters.indicgroups={ ["above_mark"]={ - [2304]=true, - [2305]=true, - [2306]=true, - [2362]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2385]=true, - [2387]=true, - [2388]=true, - [2389]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2879]=true, - [3008]=true, - [3021]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3142]=true, - [3143]=true, - [3144]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3149]=true, - [3263]=true, - [3270]=true, - [3406]=true, - [43232]=true, - [43233]=true, - [43234]=true, - [43235]=true, - [43236]=true, - [43237]=true, - [43238]=true, - [43239]=true, - [43240]=true, - [43241]=true, - [43242]=true, - [43243]=true, - [43244]=true, - [43245]=true, - [43246]=true, - [43247]=true, - [43248]=true, - [43249]=true, + [2304]=true, + [2305]=true, + [2306]=true, + [2362]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2385]=true, + [2387]=true, + [2388]=true, + [2389]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2879]=true, + [3008]=true, + [3021]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3142]=true, + [3143]=true, + [3144]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3149]=true, + [3263]=true, + [3270]=true, + [3406]=true, + [43232]=true, + [43233]=true, + [43234]=true, + [43235]=true, + [43236]=true, + [43237]=true, + [43238]=true, + [43239]=true, + [43240]=true, + [43241]=true, + [43242]=true, + [43243]=true, + [43244]=true, + [43245]=true, + [43246]=true, + [43247]=true, + [43248]=true, + [43249]=true, }, ["after_half"]={}, ["after_main"]={ - [2864]=true, - [2879]=true, - [2902]=true, - [3376]=true, + [2864]=true, + [2879]=true, + [2902]=true, + [3376]=true, }, ["after_postscript"]={ - [2433]=true, - [2494]=true, - [2496]=true, - [2519]=true, - [2561]=true, - [2562]=true, - [2622]=true, - [2624]=true, - [2625]=true, - [2626]=true, - [2672]=true, - [2673]=true, - [2750]=true, - [2752]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2786]=true, - [2787]=true, - [2878]=true, - [2880]=true, - [2903]=true, - [2992]=true, - [3006]=true, - [3007]=true, - [3009]=true, - [3010]=true, - [3031]=true, - [3120]=true, - [3248]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3415]=true, + [2433]=true, + [2494]=true, + [2496]=true, + [2519]=true, + [2561]=true, + [2562]=true, + [2622]=true, + [2624]=true, + [2625]=true, + [2626]=true, + [2672]=true, + [2673]=true, + [2750]=true, + [2752]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2786]=true, + [2787]=true, + [2878]=true, + [2880]=true, + [2903]=true, + [2992]=true, + [3006]=true, + [3007]=true, + [3009]=true, + [3010]=true, + [3031]=true, + [3120]=true, + [3248]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3415]=true, }, ["after_subscript"]={ - [2366]=true, - [2368]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2402]=true, - [2403]=true, - [2480]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2530]=true, - [2531]=true, - [2544]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [3008]=true, - [3139]=true, - [3140]=true, - [3267]=true, - [3268]=true, - [3285]=true, - [3286]=true, + [2366]=true, + [2368]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2402]=true, + [2403]=true, + [2480]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2530]=true, + [2531]=true, + [2544]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [3008]=true, + [3139]=true, + [3140]=true, + [3267]=true, + [3268]=true, + [3285]=true, + [3286]=true, }, ["anudatta"]={ - [2386]=true, + [2386]=true, }, ["before_half"]={ - [2367]=true, - [2382]=true, - [2495]=true, - [2503]=true, - [2504]=true, - [2623]=true, - [2751]=true, - [2887]=true, + [2367]=true, + [2382]=true, + [2495]=true, + [2503]=true, + [2504]=true, + [2623]=true, + [2751]=true, + [2887]=true, }, ["before_main"]={ - [3014]=true, - [3015]=true, - [3016]=true, - [3398]=true, - [3399]=true, - [3400]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3398]=true, + [3399]=true, + [3400]=true, }, ["before_postscript"]={ - [2352]=true, - [2736]=true, + [2352]=true, + [2736]=true, }, ["before_subscript"]={ - [2608]=true, - [2817]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3137]=true, - [3138]=true, - [3142]=true, - [3143]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3157]=true, - [3158]=true, - [3262]=true, - [3263]=true, - [3265]=true, - [3266]=true, - [3270]=true, - [3276]=true, - [3298]=true, - [3299]=true, + [2608]=true, + [2817]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3137]=true, + [3138]=true, + [3142]=true, + [3143]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3157]=true, + [3158]=true, + [3262]=true, + [3263]=true, + [3265]=true, + [3266]=true, + [3270]=true, + [3276]=true, + [3298]=true, + [3299]=true, }, ["below_mark"]={ - [2364]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2381]=true, - [2386]=true, - [2390]=true, - [2391]=true, - [2402]=true, - [2403]=true, - [2492]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2509]=true, - [2620]=true, - [2625]=true, - [2626]=true, - [2637]=true, - [2748]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2765]=true, - [2876]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [2884]=true, - [2893]=true, - [2914]=true, - [2915]=true, - [3009]=true, - [3010]=true, - [3170]=true, - [3171]=true, - [3260]=true, - [3298]=true, - [3299]=true, - [3426]=true, - [3427]=true, + [2364]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2381]=true, + [2386]=true, + [2390]=true, + [2391]=true, + [2402]=true, + [2403]=true, + [2492]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2509]=true, + [2620]=true, + [2625]=true, + [2626]=true, + [2637]=true, + [2748]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2765]=true, + [2876]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [2884]=true, + [2893]=true, + [2914]=true, + [2915]=true, + [3009]=true, + [3010]=true, + [3170]=true, + [3171]=true, + [3260]=true, + [3298]=true, + [3299]=true, + [3426]=true, + [3427]=true, }, ["consonant"]={ - [2325]=true, - [2326]=true, - [2327]=true, - [2328]=true, - [2329]=true, - [2330]=true, - [2331]=true, - [2332]=true, - [2333]=true, - [2334]=true, - [2335]=true, - [2336]=true, - [2337]=true, - [2338]=true, - [2339]=true, - [2340]=true, - [2341]=true, - [2342]=true, - [2343]=true, - [2344]=true, - [2345]=true, - [2346]=true, - [2347]=true, - [2348]=true, - [2349]=true, - [2350]=true, - [2351]=true, - [2352]=true, - [2353]=true, - [2354]=true, - [2355]=true, - [2356]=true, - [2357]=true, - [2358]=true, - [2359]=true, - [2360]=true, - [2361]=true, - [2392]=true, - [2393]=true, - [2394]=true, - [2395]=true, - [2396]=true, - [2397]=true, - [2398]=true, - [2399]=true, - [2424]=true, - [2425]=true, - [2426]=true, - [2453]=true, - [2454]=true, - [2455]=true, - [2456]=true, - [2457]=true, - [2458]=true, - [2459]=true, - [2460]=true, - [2461]=true, - [2462]=true, - [2463]=true, - [2464]=true, - [2465]=true, - [2466]=true, - [2467]=true, - [2468]=true, - [2469]=true, - [2470]=true, - [2471]=true, - [2472]=true, - [2474]=true, - [2475]=true, - [2476]=true, - [2477]=true, - [2478]=true, - [2479]=true, - [2480]=true, - [2482]=true, - [2486]=true, - [2487]=true, - [2488]=true, - [2489]=true, - [2510]=true, - [2524]=true, - [2525]=true, - [2527]=true, - [2581]=true, - [2582]=true, - [2583]=true, - [2584]=true, - [2585]=true, - [2586]=true, - [2587]=true, - [2588]=true, - [2589]=true, - [2590]=true, - [2591]=true, - [2592]=true, - [2593]=true, - [2594]=true, - [2595]=true, - [2596]=true, - [2597]=true, - [2598]=true, - [2599]=true, - [2600]=true, - [2602]=true, - [2603]=true, - [2604]=true, - [2605]=true, - [2606]=true, - [2607]=true, - [2608]=true, - [2610]=true, - [2611]=true, - [2613]=true, - [2614]=true, - [2616]=true, - [2617]=true, - [2649]=true, - [2650]=true, - [2651]=true, - [2652]=true, - [2654]=true, - [2709]=true, - [2710]=true, - [2711]=true, - [2712]=true, - [2713]=true, - [2714]=true, - [2715]=true, - [2716]=true, - [2717]=true, - [2718]=true, - [2719]=true, - [2720]=true, - [2721]=true, - [2722]=true, - [2723]=true, - [2724]=true, - [2725]=true, - [2726]=true, - [2727]=true, - [2728]=true, - [2730]=true, - [2731]=true, - [2732]=true, - [2733]=true, - [2734]=true, - [2735]=true, - [2736]=true, - [2738]=true, - [2739]=true, - [2741]=true, - [2742]=true, - [2743]=true, - [2744]=true, - [2745]=true, - [2837]=true, - [2838]=true, - [2839]=true, - [2840]=true, - [2841]=true, - [2842]=true, - [2843]=true, - [2844]=true, - [2845]=true, - [2846]=true, - [2847]=true, - [2848]=true, - [2849]=true, - [2850]=true, - [2851]=true, - [2852]=true, - [2853]=true, - [2854]=true, - [2855]=true, - [2856]=true, - [2858]=true, - [2859]=true, - [2860]=true, - [2861]=true, - [2862]=true, - [2863]=true, - [2864]=true, - [2866]=true, - [2867]=true, - [2869]=true, - [2870]=true, - [2871]=true, - [2872]=true, - [2873]=true, - [2908]=true, - [2909]=true, - [2929]=true, - [2965]=true, - [2969]=true, - [2970]=true, - [2972]=true, - [2974]=true, - [2975]=true, - [2979]=true, - [2980]=true, - [2984]=true, - [2985]=true, - [2986]=true, - [2990]=true, - [2991]=true, - [2992]=true, - [2993]=true, - [2994]=true, - [2995]=true, - [2996]=true, - [2997]=true, - [2998]=true, - [2999]=true, - [3000]=true, - [3001]=true, - [3093]=true, - [3094]=true, - [3095]=true, - [3096]=true, - [3097]=true, - [3098]=true, - [3099]=true, - [3100]=true, - [3101]=true, - [3102]=true, - [3103]=true, - [3104]=true, - [3105]=true, - [3106]=true, - [3107]=true, - [3108]=true, - [3109]=true, - [3110]=true, - [3111]=true, - [3112]=true, - [3114]=true, - [3115]=true, - [3116]=true, - [3117]=true, - [3118]=true, - [3119]=true, - [3120]=true, - [3121]=true, - [3122]=true, - [3123]=true, - [3124]=true, - [3125]=true, - [3126]=true, - [3127]=true, - [3128]=true, - [3129]=true, - [3133]=true, - [3221]=true, - [3222]=true, - [3223]=true, - [3224]=true, - [3225]=true, - [3226]=true, - [3227]=true, - [3228]=true, - [3229]=true, - [3230]=true, - [3231]=true, - [3232]=true, - [3233]=true, - [3234]=true, - [3235]=true, - [3236]=true, - [3237]=true, - [3238]=true, - [3239]=true, - [3240]=true, - [3242]=true, - [3243]=true, - [3244]=true, - [3245]=true, - [3246]=true, - [3247]=true, - [3248]=true, - [3249]=true, - [3250]=true, - [3251]=true, - [3253]=true, - [3254]=true, - [3255]=true, - [3256]=true, - [3257]=true, - [3294]=true, - [3349]=true, - [3350]=true, - [3351]=true, - [3352]=true, - [3353]=true, - [3354]=true, - [3355]=true, - [3356]=true, - [3357]=true, - [3358]=true, - [3359]=true, - [3360]=true, - [3361]=true, - [3362]=true, - [3363]=true, - [3364]=true, - [3365]=true, - [3366]=true, - [3367]=true, - [3368]=true, - [3369]=true, - [3370]=true, - [3371]=true, - [3372]=true, - [3373]=true, - [3374]=true, - [3375]=true, - [3376]=true, - [3377]=true, - [3378]=true, - [3379]=true, - [3380]=true, - [3381]=true, - [3382]=true, - [3383]=true, - [3384]=true, - [3385]=true, - [3386]=true, + [2325]=true, + [2326]=true, + [2327]=true, + [2328]=true, + [2329]=true, + [2330]=true, + [2331]=true, + [2332]=true, + [2333]=true, + [2334]=true, + [2335]=true, + [2336]=true, + [2337]=true, + [2338]=true, + [2339]=true, + [2340]=true, + [2341]=true, + [2342]=true, + [2343]=true, + [2344]=true, + [2345]=true, + [2346]=true, + [2347]=true, + [2348]=true, + [2349]=true, + [2350]=true, + [2351]=true, + [2352]=true, + [2353]=true, + [2354]=true, + [2355]=true, + [2356]=true, + [2357]=true, + [2358]=true, + [2359]=true, + [2360]=true, + [2361]=true, + [2392]=true, + [2393]=true, + [2394]=true, + [2395]=true, + [2396]=true, + [2397]=true, + [2398]=true, + [2399]=true, + [2424]=true, + [2425]=true, + [2426]=true, + [2453]=true, + [2454]=true, + [2455]=true, + [2456]=true, + [2457]=true, + [2458]=true, + [2459]=true, + [2460]=true, + [2461]=true, + [2462]=true, + [2463]=true, + [2464]=true, + [2465]=true, + [2466]=true, + [2467]=true, + [2468]=true, + [2469]=true, + [2470]=true, + [2471]=true, + [2472]=true, + [2474]=true, + [2475]=true, + [2476]=true, + [2477]=true, + [2478]=true, + [2479]=true, + [2480]=true, + [2482]=true, + [2486]=true, + [2487]=true, + [2488]=true, + [2489]=true, + [2510]=true, + [2524]=true, + [2525]=true, + [2527]=true, + [2581]=true, + [2582]=true, + [2583]=true, + [2584]=true, + [2585]=true, + [2586]=true, + [2587]=true, + [2588]=true, + [2589]=true, + [2590]=true, + [2591]=true, + [2592]=true, + [2593]=true, + [2594]=true, + [2595]=true, + [2596]=true, + [2597]=true, + [2598]=true, + [2599]=true, + [2600]=true, + [2602]=true, + [2603]=true, + [2604]=true, + [2605]=true, + [2606]=true, + [2607]=true, + [2608]=true, + [2610]=true, + [2611]=true, + [2613]=true, + [2614]=true, + [2616]=true, + [2617]=true, + [2649]=true, + [2650]=true, + [2651]=true, + [2652]=true, + [2654]=true, + [2709]=true, + [2710]=true, + [2711]=true, + [2712]=true, + [2713]=true, + [2714]=true, + [2715]=true, + [2716]=true, + [2717]=true, + [2718]=true, + [2719]=true, + [2720]=true, + [2721]=true, + [2722]=true, + [2723]=true, + [2724]=true, + [2725]=true, + [2726]=true, + [2727]=true, + [2728]=true, + [2730]=true, + [2731]=true, + [2732]=true, + [2733]=true, + [2734]=true, + [2735]=true, + [2736]=true, + [2738]=true, + [2739]=true, + [2741]=true, + [2742]=true, + [2743]=true, + [2744]=true, + [2745]=true, + [2837]=true, + [2838]=true, + [2839]=true, + [2840]=true, + [2841]=true, + [2842]=true, + [2843]=true, + [2844]=true, + [2845]=true, + [2846]=true, + [2847]=true, + [2848]=true, + [2849]=true, + [2850]=true, + [2851]=true, + [2852]=true, + [2853]=true, + [2854]=true, + [2855]=true, + [2856]=true, + [2858]=true, + [2859]=true, + [2860]=true, + [2861]=true, + [2862]=true, + [2863]=true, + [2864]=true, + [2866]=true, + [2867]=true, + [2869]=true, + [2870]=true, + [2871]=true, + [2872]=true, + [2873]=true, + [2908]=true, + [2909]=true, + [2929]=true, + [2965]=true, + [2969]=true, + [2970]=true, + [2972]=true, + [2974]=true, + [2975]=true, + [2979]=true, + [2980]=true, + [2984]=true, + [2985]=true, + [2986]=true, + [2990]=true, + [2991]=true, + [2992]=true, + [2993]=true, + [2994]=true, + [2995]=true, + [2996]=true, + [2997]=true, + [2998]=true, + [2999]=true, + [3000]=true, + [3001]=true, + [3093]=true, + [3094]=true, + [3095]=true, + [3096]=true, + [3097]=true, + [3098]=true, + [3099]=true, + [3100]=true, + [3101]=true, + [3102]=true, + [3103]=true, + [3104]=true, + [3105]=true, + [3106]=true, + [3107]=true, + [3108]=true, + [3109]=true, + [3110]=true, + [3111]=true, + [3112]=true, + [3114]=true, + [3115]=true, + [3116]=true, + [3117]=true, + [3118]=true, + [3119]=true, + [3120]=true, + [3121]=true, + [3122]=true, + [3123]=true, + [3124]=true, + [3125]=true, + [3126]=true, + [3127]=true, + [3128]=true, + [3129]=true, + [3133]=true, + [3221]=true, + [3222]=true, + [3223]=true, + [3224]=true, + [3225]=true, + [3226]=true, + [3227]=true, + [3228]=true, + [3229]=true, + [3230]=true, + [3231]=true, + [3232]=true, + [3233]=true, + [3234]=true, + [3235]=true, + [3236]=true, + [3237]=true, + [3238]=true, + [3239]=true, + [3240]=true, + [3242]=true, + [3243]=true, + [3244]=true, + [3245]=true, + [3246]=true, + [3247]=true, + [3248]=true, + [3249]=true, + [3250]=true, + [3251]=true, + [3253]=true, + [3254]=true, + [3255]=true, + [3256]=true, + [3257]=true, + [3294]=true, + [3349]=true, + [3350]=true, + [3351]=true, + [3352]=true, + [3353]=true, + [3354]=true, + [3355]=true, + [3356]=true, + [3357]=true, + [3358]=true, + [3359]=true, + [3360]=true, + [3361]=true, + [3362]=true, + [3363]=true, + [3364]=true, + [3365]=true, + [3366]=true, + [3367]=true, + [3368]=true, + [3369]=true, + [3370]=true, + [3371]=true, + [3372]=true, + [3373]=true, + [3374]=true, + [3375]=true, + [3376]=true, + [3377]=true, + [3378]=true, + [3379]=true, + [3380]=true, + [3381]=true, + [3382]=true, + [3383]=true, + [3384]=true, + [3385]=true, + [3386]=true, }, ["dependent_vowel"]={ - [2362]=true, - [2363]=true, - [2366]=true, - [2367]=true, - [2368]=true, - [2369]=true, - [2370]=true, - [2371]=true, - [2372]=true, - [2373]=true, - [2374]=true, - [2375]=true, - [2376]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2382]=true, - [2383]=true, - [2389]=true, - [2390]=true, - [2391]=true, - [2402]=true, - [2403]=true, - [2494]=true, - [2495]=true, - [2496]=true, - [2497]=true, - [2498]=true, - [2499]=true, - [2500]=true, - [2503]=true, - [2504]=true, - [2622]=true, - [2623]=true, - [2624]=true, - [2625]=true, - [2626]=true, - [2631]=true, - [2632]=true, - [2635]=true, - [2636]=true, - [2750]=true, - [2751]=true, - [2752]=true, - [2753]=true, - [2754]=true, - [2755]=true, - [2756]=true, - [2757]=true, - [2759]=true, - [2760]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2878]=true, - [2879]=true, - [2880]=true, - [2881]=true, - [2882]=true, - [2883]=true, - [2884]=true, - [2887]=true, - [2888]=true, - [2891]=true, - [2892]=true, - [2914]=true, - [2915]=true, - [3006]=true, - [3007]=true, - [3008]=true, - [3009]=true, - [3010]=true, - [3014]=true, - [3015]=true, - [3016]=true, - [3018]=true, - [3019]=true, - [3020]=true, - [3134]=true, - [3135]=true, - [3136]=true, - [3137]=true, - [3138]=true, - [3139]=true, - [3140]=true, - [3142]=true, - [3143]=true, - [3144]=true, - [3146]=true, - [3147]=true, - [3148]=true, - [3170]=true, - [3171]=true, - [3262]=true, - [3263]=true, - [3264]=true, - [3265]=true, - [3266]=true, - [3267]=true, - [3268]=true, - [3270]=true, - [3271]=true, - [3272]=true, - [3274]=true, - [3275]=true, - [3276]=true, - [3298]=true, - [3299]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3396]=true, - [3398]=true, - [3399]=true, - [3400]=true, - [3402]=true, - [3403]=true, - [3404]=true, - [3415]=true, - [3426]=true, - [3427]=true, + [2362]=true, + [2363]=true, + [2366]=true, + [2367]=true, + [2368]=true, + [2369]=true, + [2370]=true, + [2371]=true, + [2372]=true, + [2373]=true, + [2374]=true, + [2375]=true, + [2376]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2382]=true, + [2383]=true, + [2389]=true, + [2390]=true, + [2391]=true, + [2402]=true, + [2403]=true, + [2494]=true, + [2495]=true, + [2496]=true, + [2497]=true, + [2498]=true, + [2499]=true, + [2500]=true, + [2503]=true, + [2504]=true, + [2622]=true, + [2623]=true, + [2624]=true, + [2625]=true, + [2626]=true, + [2631]=true, + [2632]=true, + [2635]=true, + [2636]=true, + [2750]=true, + [2751]=true, + [2752]=true, + [2753]=true, + [2754]=true, + [2755]=true, + [2756]=true, + [2757]=true, + [2759]=true, + [2760]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2878]=true, + [2879]=true, + [2880]=true, + [2881]=true, + [2882]=true, + [2883]=true, + [2884]=true, + [2887]=true, + [2888]=true, + [2891]=true, + [2892]=true, + [2914]=true, + [2915]=true, + [3006]=true, + [3007]=true, + [3008]=true, + [3009]=true, + [3010]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3018]=true, + [3019]=true, + [3020]=true, + [3134]=true, + [3135]=true, + [3136]=true, + [3137]=true, + [3138]=true, + [3139]=true, + [3140]=true, + [3142]=true, + [3143]=true, + [3144]=true, + [3146]=true, + [3147]=true, + [3148]=true, + [3170]=true, + [3171]=true, + [3262]=true, + [3263]=true, + [3264]=true, + [3265]=true, + [3266]=true, + [3267]=true, + [3268]=true, + [3270]=true, + [3271]=true, + [3272]=true, + [3274]=true, + [3275]=true, + [3276]=true, + [3298]=true, + [3299]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3396]=true, + [3398]=true, + [3399]=true, + [3400]=true, + [3402]=true, + [3403]=true, + [3404]=true, + [3415]=true, + [3426]=true, + [3427]=true, }, ["halant"]={ - [2381]=true, - [2509]=true, - [2637]=true, - [2765]=true, - [2893]=true, - [3021]=true, - [3149]=true, - [3277]=true, - [3405]=true, + [2381]=true, + [2509]=true, + [2637]=true, + [2765]=true, + [2893]=true, + [3021]=true, + [3149]=true, + [3277]=true, + [3405]=true, }, ["independent_vowel"]={ - [2308]=true, - [2309]=true, - [2310]=true, - [2311]=true, - [2312]=true, - [2313]=true, - [2314]=true, - [2315]=true, - [2316]=true, - [2317]=true, - [2318]=true, - [2319]=true, - [2320]=true, - [2321]=true, - [2322]=true, - [2323]=true, - [2324]=true, - [2400]=true, - [2401]=true, - [2418]=true, - [2419]=true, - [2420]=true, - [2421]=true, - [2422]=true, - [2423]=true, - [2437]=true, - [2438]=true, - [2439]=true, - [2440]=true, - [2441]=true, - [2442]=true, - [2443]=true, - [2444]=true, - [2447]=true, - [2448]=true, - [2451]=true, - [2452]=true, - [2528]=true, - [2529]=true, - [2530]=true, - [2531]=true, - [2565]=true, - [2566]=true, - [2567]=true, - [2568]=true, - [2569]=true, - [2570]=true, - [2575]=true, - [2576]=true, - [2579]=true, - [2580]=true, - [2693]=true, - [2694]=true, - [2695]=true, - [2696]=true, - [2697]=true, - [2698]=true, - [2699]=true, - [2700]=true, - [2701]=true, - [2703]=true, - [2704]=true, - [2705]=true, - [2707]=true, - [2708]=true, - [2784]=true, - [2785]=true, - [2786]=true, - [2787]=true, - [2821]=true, - [2822]=true, - [2823]=true, - [2824]=true, - [2825]=true, - [2826]=true, - [2827]=true, - [2828]=true, - [2831]=true, - [2832]=true, - [2835]=true, - [2836]=true, - [2912]=true, - [2913]=true, - [2949]=true, - [2950]=true, - [2951]=true, - [2952]=true, - [2953]=true, - [2954]=true, - [2958]=true, - [2959]=true, - [2960]=true, - [2962]=true, - [2963]=true, - [2964]=true, - [3077]=true, - [3078]=true, - [3079]=true, - [3080]=true, - [3081]=true, - [3082]=true, - [3083]=true, - [3084]=true, - [3086]=true, - [3087]=true, - [3088]=true, - [3090]=true, - [3091]=true, - [3092]=true, - [3168]=true, - [3169]=true, - [3205]=true, - [3206]=true, - [3207]=true, - [3208]=true, - [3209]=true, - [3210]=true, - [3211]=true, - [3212]=true, - [3214]=true, - [3215]=true, - [3216]=true, - [3218]=true, - [3219]=true, - [3220]=true, - [3296]=true, - [3297]=true, - [3333]=true, - [3334]=true, - [3335]=true, - [3336]=true, - [3337]=true, - [3338]=true, - [3339]=true, - [3340]=true, - [3342]=true, - [3343]=true, - [3344]=true, - [3346]=true, - [3347]=true, - [3348]=true, - [3423]=true, - [3424]=true, - [3425]=true, + [2308]=true, + [2309]=true, + [2310]=true, + [2311]=true, + [2312]=true, + [2313]=true, + [2314]=true, + [2315]=true, + [2316]=true, + [2317]=true, + [2318]=true, + [2319]=true, + [2320]=true, + [2321]=true, + [2322]=true, + [2323]=true, + [2324]=true, + [2400]=true, + [2401]=true, + [2418]=true, + [2419]=true, + [2420]=true, + [2421]=true, + [2422]=true, + [2423]=true, + [2437]=true, + [2438]=true, + [2439]=true, + [2440]=true, + [2441]=true, + [2442]=true, + [2443]=true, + [2444]=true, + [2447]=true, + [2448]=true, + [2451]=true, + [2452]=true, + [2528]=true, + [2529]=true, + [2530]=true, + [2531]=true, + [2565]=true, + [2566]=true, + [2567]=true, + [2568]=true, + [2569]=true, + [2570]=true, + [2575]=true, + [2576]=true, + [2579]=true, + [2580]=true, + [2693]=true, + [2694]=true, + [2695]=true, + [2696]=true, + [2697]=true, + [2698]=true, + [2699]=true, + [2700]=true, + [2701]=true, + [2703]=true, + [2704]=true, + [2705]=true, + [2707]=true, + [2708]=true, + [2784]=true, + [2785]=true, + [2786]=true, + [2787]=true, + [2821]=true, + [2822]=true, + [2823]=true, + [2824]=true, + [2825]=true, + [2826]=true, + [2827]=true, + [2828]=true, + [2831]=true, + [2832]=true, + [2835]=true, + [2836]=true, + [2912]=true, + [2913]=true, + [2949]=true, + [2950]=true, + [2951]=true, + [2952]=true, + [2953]=true, + [2954]=true, + [2958]=true, + [2959]=true, + [2960]=true, + [2962]=true, + [2963]=true, + [2964]=true, + [3077]=true, + [3078]=true, + [3079]=true, + [3080]=true, + [3081]=true, + [3082]=true, + [3083]=true, + [3084]=true, + [3086]=true, + [3087]=true, + [3088]=true, + [3090]=true, + [3091]=true, + [3092]=true, + [3168]=true, + [3169]=true, + [3205]=true, + [3206]=true, + [3207]=true, + [3208]=true, + [3209]=true, + [3210]=true, + [3211]=true, + [3212]=true, + [3214]=true, + [3215]=true, + [3216]=true, + [3218]=true, + [3219]=true, + [3220]=true, + [3296]=true, + [3297]=true, + [3333]=true, + [3334]=true, + [3335]=true, + [3336]=true, + [3337]=true, + [3338]=true, + [3339]=true, + [3340]=true, + [3342]=true, + [3343]=true, + [3344]=true, + [3346]=true, + [3347]=true, + [3348]=true, + [3423]=true, + [3424]=true, + [3425]=true, }, ["nukta"]={ - [2364]=true, - [2492]=true, - [2620]=true, - [2748]=true, - [2876]=true, - [3260]=true, + [2364]=true, + [2492]=true, + [2620]=true, + [2748]=true, + [2876]=true, + [3260]=true, }, ["post_mark"]={ - [2307]=true, - [2363]=true, - [2366]=true, - [2368]=true, - [2377]=true, - [2378]=true, - [2379]=true, - [2380]=true, - [2383]=true, - [2494]=true, - [2496]=true, - [2503]=true, - [2504]=true, - [2622]=true, - [2624]=true, - [2750]=true, - [2752]=true, - [2761]=true, - [2763]=true, - [2764]=true, - [2878]=true, - [2880]=true, - [3006]=true, - [3007]=true, - [3137]=true, - [3138]=true, - [3139]=true, - [3140]=true, - [3262]=true, - [3264]=true, - [3265]=true, - [3266]=true, - [3267]=true, - [3268]=true, - [3271]=true, - [3272]=true, - [3274]=true, - [3275]=true, - [3276]=true, - [3390]=true, - [3391]=true, - [3392]=true, - [3393]=true, - [3394]=true, - [3395]=true, - [3396]=true, - [3415]=true, + [2307]=true, + [2363]=true, + [2366]=true, + [2368]=true, + [2377]=true, + [2378]=true, + [2379]=true, + [2380]=true, + [2383]=true, + [2494]=true, + [2496]=true, + [2503]=true, + [2504]=true, + [2622]=true, + [2624]=true, + [2750]=true, + [2752]=true, + [2761]=true, + [2763]=true, + [2764]=true, + [2878]=true, + [2880]=true, + [3006]=true, + [3007]=true, + [3137]=true, + [3138]=true, + [3139]=true, + [3140]=true, + [3262]=true, + [3264]=true, + [3265]=true, + [3266]=true, + [3267]=true, + [3268]=true, + [3271]=true, + [3272]=true, + [3274]=true, + [3275]=true, + [3276]=true, + [3390]=true, + [3391]=true, + [3392]=true, + [3393]=true, + [3394]=true, + [3395]=true, + [3396]=true, + [3415]=true, }, ["pre_mark"]={ - [2367]=true, - [2382]=true, - [2495]=true, - [2623]=true, - [2751]=true, - [2887]=true, - [2888]=true, - [3014]=true, - [3015]=true, - [3016]=true, - [3398]=true, - [3399]=true, - [3400]=true, + [2367]=true, + [2382]=true, + [2495]=true, + [2623]=true, + [2751]=true, + [2887]=true, + [2888]=true, + [3014]=true, + [3015]=true, + [3016]=true, + [3398]=true, + [3399]=true, + [3400]=true, }, ["ra"]={ - [2352]=true, - [2480]=true, - [2608]=true, - [2736]=true, - [2864]=true, - [2992]=true, - [3120]=true, - [3248]=true, - [3376]=true, + [2352]=true, + [2480]=true, + [2608]=true, + [2736]=true, + [2864]=true, + [2992]=true, + [3120]=true, + [3248]=true, + [3376]=true, }, ["stress_tone_mark"]={ - [2385]=true, - [2386]=true, - [2387]=true, - [2388]=true, - [2507]=true, - [2508]=true, - [3277]=true, - [3405]=true, + [2385]=true, + [2386]=true, + [2387]=true, + [2388]=true, + [2507]=true, + [2508]=true, + [3277]=true, + [3405]=true, }, ["twopart_mark"]={ - [2891]={ 2887,2878 }, - [2892]={ 2887,2903 }, - [3018]={ 3014,3006 }, - [3019]={ 3015,3006 }, - [3020]={ 3014,3031 }, - [3402]={ 3398,3390 }, - [3403]={ 3399,3390 }, - [3404]={ 3398,3415 }, + [2891]={ 2887,2878 }, + [2892]={ 2887,2903 }, + [3018]={ 3014,3006 }, + [3019]={ 3015,3006 }, + [3020]={ 3014,3031 }, + [3402]={ 3398,3390 }, + [3403]={ 3399,3390 }, + [3404]={ 3398,3415 }, }, ["vowel_modifier"]={ - [2304]=true, - [2305]=true, - [2306]=true, - [2307]=true, - [3330]=true, - [3331]=true, - [43232]=true, - [43233]=true, - [43234]=true, - [43235]=true, - [43236]=true, - [43237]=true, - [43238]=true, - [43239]=true, - [43240]=true, - [43241]=true, - [43242]=true, - [43243]=true, - [43244]=true, - [43245]=true, - [43246]=true, - [43247]=true, - [43248]=true, - [43249]=true, + [2304]=true, + [2305]=true, + [2306]=true, + [2307]=true, + [3330]=true, + [3331]=true, + [43232]=true, + [43233]=true, + [43234]=true, + [43235]=true, + [43236]=true, + [43237]=true, + [43238]=true, + [43239]=true, + [43240]=true, + [43241]=true, + [43242]=true, + [43243]=true, + [43244]=true, + [43245]=true, + [43246]=true, + [43247]=true, + [43248]=true, + [43249]=true, }, } @@ -8853,42 +8207,53 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-ini']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local allocate=utilities.storage.allocate +local sortedhash=table.sortedhash fonts=fonts or {} local fonts=fonts -fonts.hashes=fonts.hashes or { identifiers=allocate() } -fonts.tables=fonts.tables or {} -fonts.helpers=fonts.helpers or {} -fonts.tracers=fonts.tracers or {} +local identifiers=allocate() +fonts.hashes=fonts.hashes or { identifiers=identifiers } +fonts.tables=fonts.tables or {} +fonts.helpers=fonts.helpers or {} +fonts.tracers=fonts.tracers or {} fonts.specifiers=fonts.specifiers or {} fonts.analyzers={} fonts.readers={} fonts.definers={ methods={} } fonts.loggers={ register=function() end } if context then - fontloader=nil + +--removed + end +fonts.privateoffsets={ + textbase=0xF0000, + textextrabase=0xFD000, + mathextrabase=0xFE000, + mathbase=0xFF000, + keepnames=false, +} end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luatex-font-mis']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end local currentfont=font.current local hashes=fonts.hashes @@ -8897,26 +8262,29 @@ local marks=hashes.marks or {} hashes.identifiers=identifiers hashes.marks=marks table.setmetatableindex(marks,function(t,k) - if k==true then - return marks[currentfont()] - else - local resources=identifiers[k].resources or {} - local marks=resources.marks or {} - t[k]=marks - return marks - end + if k==true then + return marks[currentfont()] + else + local resources=identifiers[k].resources or {} + local marks=resources.marks or {} + t[k]=marks + return marks + end end) +function font.each() + return table.sortedhash(fonts.hashes.identifiers) +end end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-con']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local next,tostring,tonumber,rawget=next,tostring,tonumber,rawget local format,match,lower,gsub,find=string.format,string.match,string.lower,string.gsub,string.find @@ -8926,8 +8294,8 @@ local derivetable=table.derive local ioflush=io.flush local round=math.round local setmetatable,getmetatable,rawget,rawset=setmetatable,getmetatable,rawget,rawset -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_scaling=false trackers.register("fonts.scaling",function(v) trace_scaling=v end) local report_defining=logs.reporter("fonts","defining") local fonts=fonts local constructors=fonts.constructors or {} @@ -8941,85 +8309,102 @@ constructors.autocleanup=true constructors.namemode="fullpath" constructors.version=1.01 constructors.cache=containers.define("fonts","constructors",constructors.version,false) -constructors.privateoffset=0xF0000 -constructors.cacheintex=true +constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 +constructors.cacheintex=true +constructors.addtounicode=true local designsizes=allocate() constructors.designsizes=designsizes local loadedfonts=allocate() constructors.loadedfonts=loadedfonts local factors={ - pt=65536.0, - bp=65781.8, + pt=65536.0, + bp=65781.8, } function constructors.setfactor(f) - constructors.factor=factors[f or 'pt'] or factors.pt + constructors.factor=factors[f or 'pt'] or factors.pt end constructors.setfactor() function constructors.scaled(scaledpoints,designsize) - if scaledpoints<0 then - local factor=constructors.factor - if designsize then - if designsize>factor then - return (- scaledpoints/1000)*designsize - else - return (- scaledpoints/1000)*designsize*factor - end - else - return (- scaledpoints/1000)*10*factor - end + if scaledpoints<0 then + local factor=constructors.factor + if designsize then + if designsize>factor then + return (- scaledpoints/1000)*designsize + else + return (- scaledpoints/1000)*designsize*factor + end else - return scaledpoints + return (- scaledpoints/1000)*10*factor end + else + return scaledpoints + end end function constructors.getprivate(tfmdata) - local properties=tfmdata.properties - local private=properties.private - properties.private=private+1 - return private + local properties=tfmdata.properties + local private=properties.private + properties.private=private+1 + return private +end +function constructors.setmathparameter(tfmdata,name,value) + local m=tfmdata.mathparameters + local c=tfmdata.MathConstants + if m then + m[name]=value + end + if c and c~=m then + c[name]=value + end +end +function constructors.getmathparameter(tfmdata,name) + local p=tfmdata.mathparameters or tfmdata.MathConstants + if p then + return p[name] + end end function constructors.cleanuptable(tfmdata) - if constructors.autocleanup and tfmdata.properties.virtualized then - for k,v in next,tfmdata.characters do - if v.commands then v.commands=nil end - end + if constructors.autocleanup and tfmdata.properties.virtualized then + for k,v in next,tfmdata.characters do + if v.commands then v.commands=nil end end + end end function constructors.calculatescale(tfmdata,scaledpoints) - local parameters=tfmdata.parameters - if scaledpoints<0 then - scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) - end - return scaledpoints,scaledpoints/(parameters.units or 1000) + local parameters=tfmdata.parameters + if scaledpoints<0 then + scaledpoints=(- scaledpoints/1000)*(tfmdata.designsize or parameters.designsize) + end + return scaledpoints,scaledpoints/(parameters.units or 1000) end local unscaled={ - ScriptPercentScaleDown=true, - ScriptScriptPercentScaleDown=true, - RadicalDegreeBottomRaisePercent=true, - NoLimitSupFactor=true, - NoLimitSubFactor=true, + ScriptPercentScaleDown=true, + ScriptScriptPercentScaleDown=true, + RadicalDegreeBottomRaisePercent=true, + NoLimitSupFactor=true, + NoLimitSubFactor=true, } function constructors.assignmathparameters(target,original) - local mathparameters=original.mathparameters - if mathparameters and next(mathparameters) then - local targetparameters=target.parameters - local targetproperties=target.properties - local targetmathparameters={} - local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor - for name,value in next,mathparameters do - if unscaled[name] then - targetmathparameters[name]=value - else - targetmathparameters[name]=value*factor - end - end - if not targetmathparameters.FractionDelimiterSize then - targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size - end - if not mathparameters.FractionDelimiterDisplayStyleSize then - targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size - end - target.mathparameters=targetmathparameters - end + local mathparameters=original.mathparameters + if mathparameters and next(mathparameters) then + local targetparameters=target.parameters + local targetproperties=target.properties + local targetmathparameters={} + local factor=targetproperties.math_is_scaled and 1 or targetparameters.factor + for name,value in next,mathparameters do + if unscaled[name] then + targetmathparameters[name]=value + else + targetmathparameters[name]=value*factor + end + end + if not targetmathparameters.FractionDelimiterSize then + targetmathparameters.FractionDelimiterSize=1.01*targetparameters.size + end + if not mathparameters.FractionDelimiterDisplayStyleSize then + targetmathparameters.FractionDelimiterDisplayStyleSize=2.40*targetparameters.size + end + target.mathparameters=targetmathparameters + end end function constructors.beforecopyingcharacters(target,original) end @@ -9029,1181 +8414,1220 @@ constructors.sharefonts=false constructors.nofsharedfonts=0 local sharednames={} function constructors.trytosharefont(target,tfmdata) - if constructors.sharefonts then - local characters=target.characters - local n=1 - local t={ target.psname } - local u=sortedkeys(characters) - for i=1,#u do - local k=u[i] - n=n+1;t[n]=k - n=n+1;t[n]=characters[k].index or k - end - local h=md5.HEX(concat(t," ")) - local s=sharednames[h] - if s then - if trace_defining then - report_defining("font %a uses backend resources of font %a",target.fullname,s) - end - target.fullname=s - constructors.nofsharedfonts=constructors.nofsharedfonts+1 - target.properties.sharedwith=s - else - sharednames[h]=target.fullname - end + if constructors.sharefonts then + local characters=target.characters + local n=1 + local t={ target.psname } + local u=sortedkeys(characters) + for i=1,#u do + local k=u[i] + n=n+1;t[n]=k + n=n+1;t[n]=characters[k].index or k + end + local h=md5.HEX(concat(t," ")) + local s=sharednames[h] + if s then + if trace_defining then + report_defining("font %a uses backend resources of font %a",target.fullname,s) + end + target.fullname=s + constructors.nofsharedfonts=constructors.nofsharedfonts+1 + target.properties.sharedwith=s + else + sharednames[h]=target.fullname end + end end local synonyms={ - exheight="x_height", - xheight="x_height", - ex="x_height", - emwidth="quad", - em="quad", - spacestretch="space_stretch", - stretch="space_stretch", - spaceshrink="space_shrink", - shrink="space_shrink", - extraspace="extra_space", - xspace="extra_space", - slantperpoint="slant", + exheight="x_height", + xheight="x_height", + ex="x_height", + emwidth="quad", + em="quad", + spacestretch="space_stretch", + stretch="space_stretch", + spaceshrink="space_shrink", + shrink="space_shrink", + extraspace="extra_space", + xspace="extra_space", + slantperpoint="slant", } function constructors.enhanceparameters(parameters) - local mt=getmetatable(parameters) - local getter=function(t,k) - if not k then - return nil - end - local s=synonyms[k] - if s then - return rawget(t,s) or (mt and mt[s]) or nil - end - if k=="spacing" then - return { - width=t.space, - stretch=t.space_stretch, - shrink=t.space_shrink, - extra=t.extra_space, - } - end - return mt and mt[k] or nil + local mt=getmetatable(parameters) + local getter=function(t,k) + if not k then + return nil end - local setter=function(t,k,v) - if not k then - return 0 - end - local s=synonyms[k] - if s then - rawset(t,s,v) - elseif k=="spacing" then - if type(v)=="table" then - rawset(t,"space",v.width or 0) - rawset(t,"space_stretch",v.stretch or 0) - rawset(t,"space_shrink",v.shrink or 0) - rawset(t,"extra_space",v.extra or 0) - end - else - rawset(t,k,v) - end + local s=synonyms[k] + if s then + return rawget(t,s) or (mt and mt[s]) or nil + end + if k=="spacing" then + return { + width=t.space, + stretch=t.space_stretch, + shrink=t.space_shrink, + extra=t.extra_space, + } + end + return mt and mt[k] or nil + end + local setter=function(t,k,v) + if not k then + return 0 + end + local s=synonyms[k] + if s then + rawset(t,s,v) + elseif k=="spacing" then + if type(v)=="table" then + rawset(t,"space",v.width or 0) + rawset(t,"space_stretch",v.stretch or 0) + rawset(t,"space_shrink",v.shrink or 0) + rawset(t,"extra_space",v.extra or 0) + end + else + rawset(t,k,v) end - setmetatable(parameters,{ - __index=getter, - __newindex=setter, - }) + end + setmetatable(parameters,{ + __index=getter, + __newindex=setter, + }) end local function mathkerns(v,vdelta) - local k={} - for i=1,#v do - local entry=v[i] - local height=entry.height - local kern=entry.kern - k[i]={ - height=height and vdelta*height or 0, - kern=kern and vdelta*kern or 0, - } - end - return k + local k={} + for i=1,#v do + local entry=v[i] + local height=entry.height + local kern=entry.kern + k[i]={ + height=height and vdelta*height or 0, + kern=kern and vdelta*kern or 0, + } + end + return k end local psfake=0 local function fixedpsname(psname,fallback) - local usedname=psname - if psname and psname~="" then - if find(psname," ",1,true) then - usedname=gsub(psname,"[%s]+","-") - else - end - elseif not fallback or fallback=="" then - psfake=psfake+1 - psname="fakename-"..psfake + local usedname=psname + if psname and psname~="" then + if find(psname," ",1,true) then + usedname=gsub(psname,"[%s]+","-") else - psname=fallback - usedname=gsub(psname,"[^a-zA-Z0-9]+","-") end - return usedname,psname~=usedname + elseif not fallback or fallback=="" then + psfake=psfake+1 + psname="fakename-"..psfake + else + psname=fallback + usedname=gsub(psname,"[^a-zA-Z0-9]+","-") + end + return usedname,psname~=usedname end function constructors.scale(tfmdata,specification) - local target={} - if tonumber(specification) then - specification={ size=specification } - end - target.specification=specification - local scaledpoints=specification.size - local relativeid=specification.relativeid - local properties=tfmdata.properties or {} - local goodies=tfmdata.goodies or {} - local resources=tfmdata.resources or {} - local descriptions=tfmdata.descriptions or {} - local characters=tfmdata.characters or {} - local changed=tfmdata.changed or {} - local shared=tfmdata.shared or {} - local parameters=tfmdata.parameters or {} - local mathparameters=tfmdata.mathparameters or {} - local targetcharacters={} - local targetdescriptions=derivetable(descriptions) - local targetparameters=derivetable(parameters) - local targetproperties=derivetable(properties) - local targetgoodies=goodies - target.characters=targetcharacters - target.descriptions=targetdescriptions - target.parameters=targetparameters - target.properties=targetproperties - target.goodies=targetgoodies - target.shared=shared - target.resources=resources - target.unscaled=tfmdata - local mathsize=tonumber(specification.mathsize) or 0 - local textsize=tonumber(specification.textsize) or scaledpoints - local forcedsize=tonumber(parameters.mathsize ) or 0 - local extrafactor=tonumber(specification.factor ) or 1 - if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then - scaledpoints=parameters.scriptpercentage*textsize/100 - elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then - scaledpoints=parameters.scriptscriptpercentage*textsize/100 - elseif forcedsize>1000 then - scaledpoints=forcedsize - else - end - targetparameters.mathsize=mathsize - targetparameters.textsize=textsize - targetparameters.forcedsize=forcedsize - targetparameters.extrafactor=extrafactor - local tounicode=fonts.mappings.tounicode - local defaultwidth=resources.defaultwidth or 0 - local defaultheight=resources.defaultheight or 0 - local defaultdepth=resources.defaultdepth or 0 - local units=parameters.units or 1000 - targetproperties.language=properties.language or "dflt" - targetproperties.script=properties.script or "dflt" - targetproperties.mode=properties.mode or "base" - local askedscaledpoints=scaledpoints - local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) - local hdelta=delta - local vdelta=delta - target.designsize=parameters.designsize - target.units=units - target.units_per_em=units - local direction=properties.direction or tfmdata.direction or 0 - target.direction=direction - properties.direction=direction - target.size=scaledpoints - target.encodingbytes=properties.encodingbytes or 1 - target.embedding=properties.embedding or "subset" - target.tounicode=1 - target.cidinfo=properties.cidinfo - target.format=properties.format - target.cache=constructors.cacheintex and "yes" or "renew" - local fontname=properties.fontname or tfmdata.fontname - local fullname=properties.fullname or tfmdata.fullname - local filename=properties.filename or tfmdata.filename - local psname=properties.psname or tfmdata.psname - local name=properties.name or tfmdata.name - local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) - target.fontname=fontname - target.fullname=fullname - target.filename=filename - target.psname=psname - target.name=name - properties.fontname=fontname - properties.fullname=fullname - properties.filename=filename - properties.psname=psname - properties.name=name - local expansion=parameters.expansion - if expansion then - target.stretch=expansion.stretch - target.shrink=expansion.shrink - target.step=expansion.step - end - local extendfactor=parameters.extendfactor or 0 - if extendfactor~=0 and extendfactor~=1 then - hdelta=hdelta*extendfactor - target.extend=extendfactor*1000 + local target={} + if tonumber(specification) then + specification={ size=specification } + end + target.specification=specification + local scaledpoints=specification.size + local relativeid=specification.relativeid + local properties=tfmdata.properties or {} + local goodies=tfmdata.goodies or {} + local resources=tfmdata.resources or {} + local descriptions=tfmdata.descriptions or {} + local characters=tfmdata.characters or {} + local changed=tfmdata.changed or {} + local shared=tfmdata.shared or {} + local parameters=tfmdata.parameters or {} + local mathparameters=tfmdata.mathparameters or {} + local targetcharacters={} + local targetdescriptions=derivetable(descriptions) + local targetparameters=derivetable(parameters) + local targetproperties=derivetable(properties) + local targetgoodies=goodies + target.characters=targetcharacters + target.descriptions=targetdescriptions + target.parameters=targetparameters + target.properties=targetproperties + target.goodies=targetgoodies + target.shared=shared + target.resources=resources + target.unscaled=tfmdata + local mathsize=tonumber(specification.mathsize) or 0 + local textsize=tonumber(specification.textsize) or scaledpoints + local forcedsize=tonumber(parameters.mathsize ) or 0 + local extrafactor=tonumber(specification.factor ) or 1 + if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then + scaledpoints=parameters.scriptpercentage*textsize/100 + elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then + scaledpoints=parameters.scriptscriptpercentage*textsize/100 + elseif forcedsize>1000 then + scaledpoints=forcedsize + else + end + targetparameters.mathsize=mathsize + targetparameters.textsize=textsize + targetparameters.forcedsize=forcedsize + targetparameters.extrafactor=extrafactor + local addtounicode=constructors.addtounicode + local tounicode=fonts.mappings.tounicode + local unknowncode=tounicode(0xFFFD) + local defaultwidth=resources.defaultwidth or 0 + local defaultheight=resources.defaultheight or 0 + local defaultdepth=resources.defaultdepth or 0 + local units=parameters.units or 1000 + targetproperties.language=properties.language or "dflt" + targetproperties.script=properties.script or "dflt" + targetproperties.mode=properties.mode or "base" + local askedscaledpoints=scaledpoints + local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) + local hdelta=delta + local vdelta=delta + target.designsize=parameters.designsize + target.units=units + target.units_per_em=units + local direction=properties.direction or tfmdata.direction or 0 + target.direction=direction + properties.direction=direction + target.size=scaledpoints + target.encodingbytes=properties.encodingbytes or 1 + target.embedding=properties.embedding or "subset" + target.tounicode=1 + target.cidinfo=properties.cidinfo + target.format=properties.format + target.cache=constructors.cacheintex and "yes" or "renew" + local fontname=properties.fontname or tfmdata.fontname + local fullname=properties.fullname or tfmdata.fullname + local filename=properties.filename or tfmdata.filename + local psname=properties.psname or tfmdata.psname + local name=properties.name or tfmdata.name + local psname,psfixed=fixedpsname(psname,fontname or fullname or file.nameonly(filename)) + target.fontname=fontname + target.fullname=fullname + target.filename=filename + target.psname=psname + target.name=name + properties.fontname=fontname + properties.fullname=fullname + properties.filename=filename + properties.psname=psname + properties.name=name + local expansion=parameters.expansion + if expansion then + target.stretch=expansion.stretch + target.shrink=expansion.shrink + target.step=expansion.step + end + local slantfactor=parameters.slantfactor or 0 + if slantfactor~=0 then + target.slant=slantfactor*1000 + else + target.slant=0 + end + local extendfactor=parameters.extendfactor or 0 + if extendfactor~=0 and extendfactor~=1 then + hdelta=hdelta*extendfactor + target.extend=extendfactor*1000 + else + target.extend=1000 + end + local squeezefactor=parameters.squeezefactor or 0 + if squeezefactor~=0 and squeezefactor~=1 then + vdelta=vdelta*squeezefactor + target.squeeze=squeezefactor*1000 + else + target.squeeze=1000 + end + local mode=parameters.mode or 0 + if mode~=0 then + target.mode=mode + end + local width=parameters.width or 0 + if width~=0 then + target.width=width*delta*1000/655360 + end + targetparameters.factor=delta + targetparameters.hfactor=hdelta + targetparameters.vfactor=vdelta + targetparameters.size=scaledpoints + targetparameters.units=units + targetparameters.scaledpoints=askedscaledpoints + targetparameters.mode=mode + targetparameters.width=width + local isvirtual=properties.virtualized or tfmdata.type=="virtual" + local hasquality=parameters.expansion or parameters.protrusion + local hasitalics=properties.hasitalics + local autoitalicamount=properties.autoitalicamount + local stackmath=not properties.nostackmath + local nonames=properties.noglyphnames + local haskerns=properties.haskerns or properties.mode=="base" + local hasligatures=properties.hasligatures or properties.mode=="base" + local realdimensions=properties.realdimensions + local writingmode=properties.writingmode or "horizontal" + local identity=properties.identity or "horizontal" + local vfonts=target.fonts + if vfonts and #vfonts>0 then + target.fonts=fastcopy(vfonts) + elseif isvirtual then + target.fonts={ { id=0 } } + end + if changed and not next(changed) then + changed=false + end + target.type=isvirtual and "virtual" or "real" + target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" + target.identity=identity=="vertical" and "vertical" or "horizontal" + target.postprocessors=tfmdata.postprocessors + local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt + local targetspace=(parameters.space or parameters[2] or 0)*hdelta + local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta + local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta + local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta + local targetquad=(parameters.quad or parameters[6] or 0)*hdelta + local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta + targetparameters.slant=targetslant + targetparameters.space=targetspace + targetparameters.space_stretch=targetspace_stretch + targetparameters.space_shrink=targetspace_shrink + targetparameters.x_height=targetx_height + targetparameters.quad=targetquad + targetparameters.extra_space=targetextra_space + local ascender=parameters.ascender + if ascender then + targetparameters.ascender=delta*ascender + end + local descender=parameters.descender + if descender then + targetparameters.descender=delta*descender + end + constructors.enhanceparameters(targetparameters) + local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0 + local scaledwidth=defaultwidth*hdelta + local scaledheight=defaultheight*vdelta + local scaleddepth=defaultdepth*vdelta + local hasmath=(properties.hasmath or next(mathparameters)) and true + if hasmath then + constructors.assignmathparameters(target,tfmdata) + properties.hasmath=true + target.nomath=false + target.MathConstants=target.mathparameters + else + properties.hasmath=false + target.nomath=true + target.mathparameters=nil + end + if hasmath then + local mathitalics=properties.mathitalics + if mathitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + else + local textitalics=properties.textitalics + if textitalics==false then + if trace_defining then + report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) + end + hasitalics=false + autoitalicamount=false + end + end + if trace_defining then + report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", + name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, + hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") + end + constructors.beforecopyingcharacters(target,tfmdata) + local sharedkerns={} + for unicode,character in next,characters do + local chr,description,index + if changed then + local c=changed[unicode] + if c and c~=unicode then + if c then + description=descriptions[c] or descriptions[unicode] or character + character=characters[c] or character + index=description.index or c + else + description=descriptions[unicode] or character + index=description.index or unicode + end + else + description=descriptions[unicode] or character + index=description.index or unicode + end else - target.extend=1000 - end - local slantfactor=parameters.slantfactor or 0 - if slantfactor~=0 then - target.slant=slantfactor*1000 + description=descriptions[unicode] or character + index=description.index or unicode + end + local width=description.width + local height=description.height + local depth=description.depth + if realdimensions then + if not height or height==0 then + local bb=description.boundingbox + local ht=bb[4] + if ht~=0 then + height=ht + end + if not depth or depth==0 then + local dp=-bb[2] + if dp~=0 then + depth=dp + end + end + elseif not depth or depth==0 then + local dp=-description.boundingbox[2] + if dp~=0 then + depth=dp + end + end + end + if width then width=hdelta*width else width=scaledwidth end + if height then height=vdelta*height else height=scaledheight end + if depth and depth~=0 then + depth=delta*depth + if nonames then + chr={ + index=index, + height=height, + depth=depth, + width=width, + } + else + chr={ + name=description.name, + index=index, + height=height, + depth=depth, + width=width, + } + end else - target.slant=0 - end - local mode=parameters.mode or 0 - if mode~=0 then - target.mode=mode - end - local width=parameters.width or 0 - if width~=0 then - target.width=width - end - targetparameters.factor=delta - targetparameters.hfactor=hdelta - targetparameters.vfactor=vdelta - targetparameters.size=scaledpoints - targetparameters.units=units - targetparameters.scaledpoints=askedscaledpoints - targetparameters.mode=mode - targetparameters.width=width - local isvirtual=properties.virtualized or tfmdata.type=="virtual" - local hasquality=parameters.expansion or parameters.protrusion - local hasitalics=properties.hasitalics - local autoitalicamount=properties.autoitalicamount - local stackmath=not properties.nostackmath - local nonames=properties.noglyphnames - local haskerns=properties.haskerns or properties.mode=="base" - local hasligatures=properties.hasligatures or properties.mode=="base" - local realdimensions=properties.realdimensions - local writingmode=properties.writingmode or "horizontal" - local identity=properties.identity or "horizontal" - local vfonts=target.fonts - if vfonts and #vfonts>0 then - target.fonts=fastcopy(vfonts) - elseif isvirtual then - target.fonts={ { id=0 } } - end - if changed and not next(changed) then - changed=false - end - target.type=isvirtual and "virtual" or "real" - target.writingmode=writingmode=="vertical" and "vertical" or "horizontal" - target.identity=identity=="vertical" and "vertical" or "horizontal" - target.postprocessors=tfmdata.postprocessors - local targetslant=(parameters.slant or parameters[1] or 0)*factors.pt - local targetspace=(parameters.space or parameters[2] or 0)*hdelta - local targetspace_stretch=(parameters.space_stretch or parameters[3] or 0)*hdelta - local targetspace_shrink=(parameters.space_shrink or parameters[4] or 0)*hdelta - local targetx_height=(parameters.x_height or parameters[5] or 0)*vdelta - local targetquad=(parameters.quad or parameters[6] or 0)*hdelta - local targetextra_space=(parameters.extra_space or parameters[7] or 0)*hdelta - targetparameters.slant=targetslant - targetparameters.space=targetspace - targetparameters.space_stretch=targetspace_stretch - targetparameters.space_shrink=targetspace_shrink - targetparameters.x_height=targetx_height - targetparameters.quad=targetquad - targetparameters.extra_space=targetextra_space - local ascender=parameters.ascender - if ascender then - targetparameters.ascender=delta*ascender - end - local descender=parameters.descender - if descender then - targetparameters.descender=delta*descender - end - constructors.enhanceparameters(targetparameters) - local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0 - local scaledwidth=defaultwidth*hdelta - local scaledheight=defaultheight*vdelta - local scaleddepth=defaultdepth*vdelta - local hasmath=(properties.hasmath or next(mathparameters)) and true - if hasmath then - constructors.assignmathparameters(target,tfmdata) - properties.hasmath=true - target.nomath=false - target.MathConstants=target.mathparameters + if nonames then + chr={ + index=index, + height=height, + width=width, + } + else + chr={ + name=description.name, + index=index, + height=height, + width=width, + } + end + end + local isunicode=description.unicode + if addtounicode then + if isunicode then + chr.unicode=isunicode + chr.tounicode=tounicode(isunicode) + else + chr.tounicode=unknowncode + end else - properties.hasmath=false - target.nomath=true - target.mathparameters=nil + if isunicode then + chr.unicode=isunicode + end + end + if hasquality then + local ve=character.expansion_factor + if ve then + chr.expansion_factor=ve*1000 + end + local vl=character.left_protruding + if vl then + chr.left_protruding=protrusionfactor*width*vl + end + local vr=character.right_protruding + if vr then + chr.right_protruding=protrusionfactor*width*vr + end end if hasmath then - local mathitalics=properties.mathitalics - if mathitalics==false then - if trace_defining then - report_defining("%s italics %s for font %a, fullname %a, filename %a","math",hasitalics and "ignored" or "disabled",name,fullname,filename) - end - hasitalics=false - autoitalicamount=false - end - else - local textitalics=properties.textitalics - if textitalics==false then - if trace_defining then - report_defining("%s italics %s for font %a, fullname %a, filename %a","text",hasitalics and "ignored" or "disabled",name,fullname,filename) - end - hasitalics=false - autoitalicamount=false - end - end - if trace_defining then - report_defining("defining tfm, name %a, fullname %a, filename %a, %spsname %a, hscale %a, vscale %a, math %a, italics %a", - name,fullname,filename,psfixed and "(fixed) " or "",psname,hdelta,vdelta, - hasmath and "enabled" or "disabled",hasitalics and "enabled" or "disabled") - end - constructors.beforecopyingcharacters(target,tfmdata) - local sharedkerns={} - for unicode,character in next,characters do - local chr,description,index - if changed then - local c=changed[unicode] - if c and c~=unicode then - if c then - description=descriptions[c] or descriptions[unicode] or character - character=characters[c] or character - index=description.index or c - else - description=descriptions[unicode] or character - index=description.index or unicode - end - else - description=descriptions[unicode] or character - index=description.index or unicode - end + local vn=character.next + if vn then + chr.next=vn + else + local vv=character.vert_variants + if vv then + local t={} + for i=1,#vv do + local vvi=vv[i] + local s=vvi["start"] or 0 + local e=vvi["end"] or 0 + local a=vvi["advance"] or 0 + t[i]={ + ["start"]=s==0 and 0 or s*vdelta, + ["end"]=e==0 and 0 or e*vdelta, + ["advance"]=a==0 and 0 or a*vdelta, + ["extender"]=vvi["extender"], + ["glyph"]=vvi["glyph"], + } + end + chr.vert_variants=t else - description=descriptions[unicode] or character - index=description.index or unicode - end - local width=description.width - local height=description.height - local depth=description.depth - if realdimensions then - if not height or height==0 then - local bb=description.boundingbox - local ht=bb[4] - if ht~=0 then - height=ht - end - if not depth or depth==0 then - local dp=-bb[2] - if dp~=0 then - depth=dp - end - end - elseif not depth or depth==0 then - local dp=-description.boundingbox[2] - if dp~=0 then - depth=dp - end - end + local hv=character.horiz_variants + if hv then + local t={} + for i=1,#hv do + local hvi=hv[i] + local s=hvi["start"] or 0 + local e=hvi["end"] or 0 + local a=hvi["advance"] or 0 + t[i]={ + ["start"]=s==0 and 0 or s*hdelta, + ["end"]=e==0 and 0 or e*hdelta, + ["advance"]=a==0 and 0 or a*hdelta, + ["extender"]=hvi["extender"], + ["glyph"]=hvi["glyph"], + } + end + chr.horiz_variants=t + end end - if width then width=hdelta*width else width=scaledwidth end - if height then height=vdelta*height else height=scaledheight end - if depth and depth~=0 then - depth=delta*depth - if nonames then - chr={ - index=index, - height=height, - depth=depth, - width=width, - } - else - chr={ - name=description.name, - index=index, - height=height, - depth=depth, - width=width, - } - end + end + local vi=character.vert_italic + if vi and vi~=0 then + chr.vert_italic=vi*hdelta + end + local va=character.accent + if va then + chr.top_accent=vdelta*va + end + if stackmath then + local mk=character.mathkerns + if mk then + local tr=mk.topright + local tl=mk.topleft + local br=mk.bottomright + local bl=mk.bottomleft + chr.mathkern={ + top_right=tr and mathkerns(tr,vdelta) or nil, + top_left=tl and mathkerns(tl,vdelta) or nil, + bottom_right=br and mathkerns(br,vdelta) or nil, + bottom_left=bl and mathkerns(bl,vdelta) or nil, + } + end + end + if hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + elseif autoitalicamount then + local vi=description.italic + if not vi then + local bb=description.boundingbox + if bb then + local vi=bb[3]-description.width+autoitalicamount + if vi>0 then + chr.italic=vi*hdelta + end else - if nonames then - chr={ - index=index, - height=height, - width=width, - } - else - chr={ - name=description.name, - index=index, - height=height, - width=width, - } - end - end - local isunicode=description.unicode - if isunicode then - chr.unicode=isunicode - chr.tounicode=tounicode(isunicode) - end - if hasquality then - local ve=character.expansion_factor - if ve then - chr.expansion_factor=ve*1000 - end - local vl=character.left_protruding - if vl then - chr.left_protruding=protrusionfactor*width*vl - end - local vr=character.right_protruding - if vr then - chr.right_protruding=protrusionfactor*width*vr - end - end - if hasmath then - local vn=character.next - if vn then - chr.next=vn - else - local vv=character.vert_variants - if vv then - local t={} - for i=1,#vv do - local vvi=vv[i] - t[i]={ - ["start"]=(vvi["start"] or 0)*vdelta, - ["end"]=(vvi["end"] or 0)*vdelta, - ["advance"]=(vvi["advance"] or 0)*vdelta, - ["extender"]=vvi["extender"], - ["glyph"]=vvi["glyph"], - } - end - chr.vert_variants=t - else - local hv=character.horiz_variants - if hv then - local t={} - for i=1,#hv do - local hvi=hv[i] - t[i]={ - ["start"]=(hvi["start"] or 0)*hdelta, - ["end"]=(hvi["end"] or 0)*hdelta, - ["advance"]=(hvi["advance"] or 0)*hdelta, - ["extender"]=hvi["extender"], - ["glyph"]=hvi["glyph"], - } - end - chr.horiz_variants=t - end - end - end - local vi=character.vert_italic - if vi and vi~=0 then - chr.vert_italic=vi*hdelta - end - local va=character.accent - if va then - chr.top_accent=vdelta*va - end - if stackmath then - local mk=character.mathkerns - if mk then - local tr,tl,br,bl=mk.topright,mk.topleft,mk.bottomright,mk.bottomleft - chr.mathkern={ - top_right=tr and mathkerns(tr,vdelta) or nil, - top_left=tl and mathkerns(tl,vdelta) or nil, - bottom_right=br and mathkerns(br,vdelta) or nil, - bottom_left=bl and mathkerns(bl,vdelta) or nil, - } - end - end - if hasitalics then - local vi=character.italic - if vi and vi~=0 then - chr.italic=vi*hdelta - end - end - elseif autoitalicamount then - local vi=description.italic - if not vi then - local bb=description.boundingbox - if bb then - local vi=bb[3]-description.width+autoitalicamount - if vi>0 then - chr.italic=vi*hdelta - end - else - end - elseif vi~=0 then - chr.italic=vi*hdelta - end - elseif hasitalics then - local vi=character.italic - if vi and vi~=0 then - chr.italic=vi*hdelta - end end - if haskerns then - local vk=character.kerns - if vk then - local s=sharedkerns[vk] - if not s then - s={} - for k,v in next,vk do s[k]=v*hdelta end - sharedkerns[vk]=s - end - chr.kerns=s - end + elseif vi~=0 then + chr.italic=vi*hdelta + end + elseif hasitalics then + local vi=character.italic + if vi and vi~=0 then + chr.italic=vi*hdelta + end + end + if haskerns then + local vk=character.kerns + if vk then + local s=sharedkerns[vk] + if not s then + s={} + for k,v in next,vk do s[k]=v*hdelta end + sharedkerns[vk]=s + end + chr.kerns=s + end + end + if hasligatures then + local vl=character.ligatures + if vl then + if true then + chr.ligatures=vl + else + local tt={} + for i,l in next,vl do + tt[i]=l + end + chr.ligatures=tt end - if hasligatures then - local vl=character.ligatures - if vl then - if true then - chr.ligatures=vl - else - local tt={} - for i,l in next,vl do - tt[i]=l - end - chr.ligatures=tt - end - end + end + end + if isvirtual then + local vc=character.commands + if vc then + local ok=false + for i=1,#vc do + local key=vc[i][1] + if key=="right" or key=="down" or key=="rule" then + ok=true + break + end end - if isvirtual then - local vc=character.commands - if vc then - local ok=false - for i=1,#vc do - local key=vc[i][1] - if key=="right" or key=="down" or key=="rule" then - ok=true - break - end - end - if ok then - local tt={} - for i=1,#vc do - local ivc=vc[i] - local key=ivc[1] - if key=="right" then - tt[i]={ key,ivc[2]*hdelta } - elseif key=="down" then - tt[i]={ key,ivc[2]*vdelta } - elseif key=="rule" then - tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta } - else - tt[i]=ivc - end - end - chr.commands=tt - else - chr.commands=vc - end - chr.index=nil + if ok then + local tt={} + for i=1,#vc do + local ivc=vc[i] + local key=ivc[1] + if key=="right" then + tt[i]={ key,ivc[2]*hdelta } + elseif key=="down" then + tt[i]={ key,ivc[2]*vdelta } + elseif key=="rule" then + tt[i]={ key,ivc[2]*vdelta,ivc[3]*hdelta } + else + tt[i]=ivc end + end + chr.commands=tt + else + chr.commands=vc end - targetcharacters[unicode]=chr + end end - properties.setitalics=hasitalics - constructors.aftercopyingcharacters(target,tfmdata) - constructors.trytosharefont(target,tfmdata) - local vfonts=target.fonts -if isvirtual or target.type=="virtual" or properties.virtualized then - properties.virtualized=true -target.type="virtual" - if not vfonts or #vfonts==0 then - target.fonts={ { id=0 } } - end - elseif vfonts then - properties.virtualized=true - target.type="virtual" - if #vfonts==0 then - target.fonts={ { id=0 } } - end + targetcharacters[unicode]=chr + end + properties.setitalics=hasitalics + constructors.aftercopyingcharacters(target,tfmdata) + constructors.trytosharefont(target,tfmdata) + local vfonts=target.fonts + if isvirtual or target.type=="virtual" or properties.virtualized then + properties.virtualized=true + target.type="virtual" + if not vfonts or #vfonts==0 then + target.fonts={ { id=0 } } end - return target + elseif vfonts then + properties.virtualized=true + target.type="virtual" + if #vfonts==0 then + target.fonts={ { id=0 } } + end + end + return target end function constructors.finalize(tfmdata) - if tfmdata.properties and tfmdata.properties.finalized then - return - end - if not tfmdata.characters then - return nil - end - if not tfmdata.goodies then - tfmdata.goodies={} - end - local parameters=tfmdata.parameters - if not parameters then - return nil - end - if not parameters.expansion then - parameters.expansion={ - stretch=tfmdata.stretch or 0, - shrink=tfmdata.shrink or 0, - step=tfmdata.step or 0, - } - end - if not parameters.size then - parameters.size=tfmdata.size - end - if not parameters.mode then - parameters.mode=0 - end - if not parameters.width then - parameters.width=0 - end - if not parameters.extendfactor then - parameters.extendfactor=tfmdata.extend or 0 - end - if not parameters.slantfactor then - parameters.slantfactor=tfmdata.slant or 0 - end - local designsize=parameters.designsize - if designsize then - parameters.minsize=tfmdata.minsize or designsize - parameters.maxsize=tfmdata.maxsize or designsize - else - designsize=factors.pt*10 - parameters.designsize=designsize - parameters.minsize=designsize - parameters.maxsize=designsize - end - parameters.minsize=tfmdata.minsize or parameters.designsize - parameters.maxsize=tfmdata.maxsize or parameters.designsize - if not parameters.units then - parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 - end - if not tfmdata.descriptions then - local descriptions={} - setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end) - tfmdata.descriptions=descriptions - end - local properties=tfmdata.properties - if not properties then - properties={} - tfmdata.properties=properties - end - if not properties.virtualized then - properties.virtualized=tfmdata.type=="virtual" - end - if not tfmdata.properties then - tfmdata.properties={ - fontname=tfmdata.fontname, - filename=tfmdata.filename, - fullname=tfmdata.fullname, - name=tfmdata.name, - psname=tfmdata.psname, - encodingbytes=tfmdata.encodingbytes or 1, - embedding=tfmdata.embedding or "subset", - tounicode=tfmdata.tounicode or 1, - cidinfo=tfmdata.cidinfo or nil, - format=tfmdata.format or "type1", - direction=tfmdata.direction or 0, - writingmode=tfmdata.writingmode or "horizontal", - identity=tfmdata.identity or "horizontal", - } - end - if not tfmdata.resources then - tfmdata.resources={} - end - if not tfmdata.shared then - tfmdata.shared={} - end - if not properties.hasmath then - properties.hasmath=not tfmdata.nomath - end - tfmdata.MathConstants=nil - tfmdata.postprocessors=nil - tfmdata.fontname=nil - tfmdata.filename=nil - tfmdata.fullname=nil - tfmdata.name=nil - tfmdata.psname=nil - tfmdata.encodingbytes=nil - tfmdata.embedding=nil - tfmdata.tounicode=nil - tfmdata.cidinfo=nil - tfmdata.format=nil - tfmdata.direction=nil - tfmdata.type=nil - tfmdata.nomath=nil - tfmdata.designsize=nil - tfmdata.size=nil - tfmdata.stretch=nil - tfmdata.shrink=nil - tfmdata.step=nil - tfmdata.extend=nil - tfmdata.slant=nil - tfmdata.mode=nil - tfmdata.width=nil - tfmdata.units=nil - tfmdata.units_per_em=nil - tfmdata.cache=nil - properties.finalized=true - return tfmdata + if tfmdata.properties and tfmdata.properties.finalized then + return + end + if not tfmdata.characters then + return nil + end + if not tfmdata.goodies then + tfmdata.goodies={} + end + local parameters=tfmdata.parameters + if not parameters then + return nil + end + if not parameters.expansion then + parameters.expansion={ + stretch=tfmdata.stretch or 0, + shrink=tfmdata.shrink or 0, + step=tfmdata.step or 0, + } + end + if not parameters.size then + parameters.size=tfmdata.size + end + if not parameters.mode then + parameters.mode=0 + end + if not parameters.width then + parameters.width=0 + end + if not parameters.slantfactor then + parameters.slantfactor=tfmdata.slant or 0 + end + if not parameters.extendfactor then + parameters.extendfactor=tfmdata.extend or 0 + end + if not parameters.squeezefactor then + parameters.squeezefactor=tfmdata.squeeze or 0 + end + local designsize=parameters.designsize + if designsize then + parameters.minsize=tfmdata.minsize or designsize + parameters.maxsize=tfmdata.maxsize or designsize + else + designsize=factors.pt*10 + parameters.designsize=designsize + parameters.minsize=designsize + parameters.maxsize=designsize + end + parameters.minsize=tfmdata.minsize or parameters.designsize + parameters.maxsize=tfmdata.maxsize or parameters.designsize + if not parameters.units then + parameters.units=tfmdata.units or tfmdata.units_per_em or 1000 + end + if not tfmdata.descriptions then + local descriptions={} + setmetatableindex(descriptions,function(t,k) local v={} t[k]=v return v end) + tfmdata.descriptions=descriptions + end + local properties=tfmdata.properties + if not properties then + properties={} + tfmdata.properties=properties + end + if not properties.virtualized then + properties.virtualized=tfmdata.type=="virtual" + end + properties.fontname=tfmdata.fontname + properties.filename=tfmdata.filename + properties.fullname=tfmdata.fullname + properties.name=tfmdata.name + properties.psname=tfmdata.psname + properties.encodingbytes=tfmdata.encodingbytes or 1 + properties.embedding=tfmdata.embedding or "subset" + properties.tounicode=tfmdata.tounicode or 1 + properties.cidinfo=tfmdata.cidinfo or nil + properties.format=tfmdata.format or "type1" + properties.direction=tfmdata.direction or 0 + properties.writingmode=tfmdata.writingmode or "horizontal" + properties.identity=tfmdata.identity or "horizontal" + properties.usedbitmap=tfmdata.usedbitmap + if not tfmdata.resources then + tfmdata.resources={} + end + if not tfmdata.shared then + tfmdata.shared={} + end + if not properties.hasmath then + properties.hasmath=not tfmdata.nomath + end + tfmdata.MathConstants=nil + tfmdata.postprocessors=nil + tfmdata.fontname=nil + tfmdata.filename=nil + tfmdata.fullname=nil + tfmdata.name=nil + tfmdata.psname=nil + tfmdata.encodingbytes=nil + tfmdata.embedding=nil + tfmdata.tounicode=nil + tfmdata.cidinfo=nil + tfmdata.format=nil + tfmdata.direction=nil + tfmdata.type=nil + tfmdata.nomath=nil + tfmdata.designsize=nil + tfmdata.size=nil + tfmdata.stretch=nil + tfmdata.shrink=nil + tfmdata.step=nil + tfmdata.slant=nil + tfmdata.extend=nil + tfmdata.squeeze=nil + tfmdata.mode=nil + tfmdata.width=nil + tfmdata.units=nil + tfmdata.units_per_em=nil + tfmdata.cache=nil + properties.finalized=true + return tfmdata end local hashmethods={} constructors.hashmethods=hashmethods function constructors.hashfeatures(specification) - local features=specification.features - if features then - local t,n={},0 - for category,list in sortedhash(features) do - if next(list) then - local hasher=hashmethods[category] - if hasher then - local hash=hasher(list) - if hash then - n=n+1 - t[n]=category..":"..hash - end - end - end - end - if n>0 then - return concat(t," & ") - end - end - return "unknown" -end -hashmethods.normal=function(list) - local s={} - local n=0 - for k,v in next,list do - if not k then - elseif k=="number" or k=="features" then - else + local features=specification.features + if features then + local t,n={},0 + for category,list in sortedhash(features) do + if next(list) then + local hasher=hashmethods[category] + if hasher then + local hash=hasher(list) + if hash then n=n+1 - s[n]=k..'='..tostring(v) + t[n]=category..":"..hash + end end + end end if n>0 then - sort(s) - return concat(s,"+") + return concat(t," & ") end + end + return "unknown" end -function constructors.hashinstance(specification,force) - local hash,size,fallbacks=specification.hash,specification.size,specification.fallbacks - if force or not hash then - hash=constructors.hashfeatures(specification) - specification.hash=hash - end - if size<1000 and designsizes[hash] then - size=round(constructors.scaled(size,designsizes[hash])) - else - size=round(size) - end - specification.size=size - if fallbacks then - return hash..' @ '..size..' @ '..fallbacks +hashmethods.normal=function(list) + local s={} + local n=0 + for k,v in next,list do + if not k then + elseif k=="number" or k=="features" then else - return hash..' @ '..size - end + n=n+1 + if type(v)=="table" then + local t={} + local m=0 + for k,v in next,v do + m=m+1 + t[m]=k..'='..tostring(v) + end + s[n]=k..'={'..concat(t,",").."}" + else + s[n]=k..'='..tostring(v) + end + end + end + if n>0 then + sort(s) + return concat(s,"+") + end +end +function constructors.hashinstance(specification,force) + local hash=specification.hash + local size=specification.size + local fallbacks=specification.fallbacks + if force or not hash then + hash=constructors.hashfeatures(specification) + specification.hash=hash + end + if size<1000 and designsizes[hash] then + size=round(constructors.scaled(size,designsizes[hash])) + else + size=round(size) + end + specification.size=size + if fallbacks then + return hash..' @ '..size..' @ '..fallbacks + else + return hash..' @ '..size + end end function constructors.setname(tfmdata,specification) - if constructors.namemode=="specification" then - local specname=specification.specification - if specname then - tfmdata.properties.name=specname - if trace_defining then - report_otf("overloaded fontname %a",specname) - end - end + if constructors.namemode=="specification" then + local specname=specification.specification + if specname then + tfmdata.properties.name=specname + if trace_defining then + report_otf("overloaded fontname %a",specname) + end end + end end function constructors.checkedfilename(data) - local foundfilename=data.foundfilename - if not foundfilename then - local askedfilename=data.filename or "" - if askedfilename~="" then - askedfilename=resolvers.resolve(askedfilename) - foundfilename=resolvers.findbinfile(askedfilename,"") or "" - if foundfilename=="" then - report_defining("source file %a is not found",askedfilename) - foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or "" - if foundfilename~="" then - report_defining("using source file %a due to cache mismatch",foundfilename) - end - end - end - data.foundfilename=foundfilename - end - return foundfilename + local foundfilename=data.foundfilename + if not foundfilename then + local askedfilename=data.filename or "" + if askedfilename~="" then + askedfilename=resolvers.resolve(askedfilename) + foundfilename=resolvers.findbinfile(askedfilename,"") or "" + if foundfilename=="" then + report_defining("source file %a is not found",askedfilename) + foundfilename=resolvers.findbinfile(file.basename(askedfilename),"") or "" + if foundfilename~="" then + report_defining("using source file %a due to cache mismatch",foundfilename) + end + end + end + data.foundfilename=foundfilename + end + return foundfilename end local formats=allocate() fonts.formats=formats setmetatableindex(formats,function(t,k) - local l=lower(k) - if rawget(t,k) then - t[k]=l - return l - end - return rawget(t,file.suffix(l)) + local l=lower(k) + if rawget(t,k) then + t[k]=l + return l + end + return rawget(t,file.suffix(l)) end) do - local function setindeed(mode,source,target,group,name,position) - local action=source[mode] - if not action then - return - end - local t=target[mode] - if not t then - report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) - os.exit() - elseif position then - insert(t,position,{ name=name,action=action }) - else - for i=1,#t do - local ti=t[i] - if ti.name==name then - ti.action=action - return - end - end - insert(t,{ name=name,action=action }) - end - end - local function set(group,name,target,source) - target=target[group] - if not target then - report_defining("fatal target error in setting feature %a, group %a",name,group) - os.exit() - end - local source=source[group] - if not source then - report_defining("fatal source error in setting feature %a, group %a",name,group) - os.exit() - end - local position=source.position - setindeed("node",source,target,group,name,position) - setindeed("base",source,target,group,name,position) - setindeed("plug",source,target,group,name,position) - end - local function register(where,specification) - local name=specification.name - if name and name~="" then - local default=specification.default - local description=specification.description - local initializers=specification.initializers - local processors=specification.processors - local manipulators=specification.manipulators - local modechecker=specification.modechecker - if default then - where.defaults[name]=default - end - if description and description~="" then - where.descriptions[name]=description - end - if initializers then - set('initializers',name,where,specification) - end - if processors then - set('processors',name,where,specification) - end - if manipulators then - set('manipulators',name,where,specification) - end - if modechecker then - where.modechecker=modechecker - end - end + local function setindeed(mode,source,target,group,name,position) + local action=source[mode] + if not action then + return end - constructors.registerfeature=register - function constructors.getfeatureaction(what,where,mode,name) - what=handlers[what].features - if what then - where=what[where] - if where then - mode=where[mode] - if mode then - for i=1,#mode do - local m=mode[i] - if m.name==name then - return m.action - end - end - end + local t=target[mode] + if not t then + report_defining("fatal error in setting feature %a, group %a, mode %a",name,group,mode) + os.exit() + elseif position then + insert(t,position,{ name=name,action=action }) + else + for i=1,#t do + local ti=t[i] + if ti.name==name then + ti.action=action + return + end + end + insert(t,{ name=name,action=action }) + end + end + local function set(group,name,target,source) + target=target[group] + if not target then + report_defining("fatal target error in setting feature %a, group %a",name,group) + os.exit() + end + local source=source[group] + if not source then + report_defining("fatal source error in setting feature %a, group %a",name,group) + os.exit() + end + local position=source.position + setindeed("node",source,target,group,name,position) + setindeed("base",source,target,group,name,position) + setindeed("plug",source,target,group,name,position) + end + local function register(where,specification) + local name=specification.name + if name and name~="" then + local default=specification.default + local description=specification.description + local initializers=specification.initializers + local processors=specification.processors + local manipulators=specification.manipulators + local modechecker=specification.modechecker + if default then + where.defaults[name]=default + end + if description and description~="" then + where.descriptions[name]=description + end + if initializers then + set('initializers',name,where,specification) + end + if processors then + set('processors',name,where,specification) + end + if manipulators then + set('manipulators',name,where,specification) + end + if modechecker then + where.modechecker=modechecker + end + end + end + constructors.registerfeature=register + function constructors.getfeatureaction(what,where,mode,name) + what=handlers[what].features + if what then + where=what[where] + if where then + mode=where[mode] + if mode then + for i=1,#mode do + local m=mode[i] + if m.name==name then + return m.action end + end end - end - local newfeatures={} - constructors.newfeatures=newfeatures - constructors.features=newfeatures - local function setnewfeatures(what) - local handler=handlers[what] - local features=handler.features - if not features then - local tables=handler.tables - local statistics=handler.statistics - features=allocate { - defaults={}, - descriptions=tables and tables.features or {}, - used=statistics and statistics.usedfeatures or {}, - initializers={ base={},node={},plug={} }, - processors={ base={},node={},plug={} }, - manipulators={ base={},node={},plug={} }, - } - features.register=function(specification) return register(features,specification) end - handler.features=features - end - return features - end - setmetatable(newfeatures,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, - }) + end + end + end + local newfeatures={} + constructors.newfeatures=newfeatures + constructors.features=newfeatures + local function setnewfeatures(what) + local handler=handlers[what] + local features=handler.features + if not features then + local tables=handler.tables + local statistics=handler.statistics + features=allocate { + defaults={}, + descriptions=tables and tables.features or {}, + used=statistics and statistics.usedfeatures or {}, + initializers={ base={},node={},plug={} }, + processors={ base={},node={},plug={} }, + manipulators={ base={},node={},plug={} }, + } + features.register=function(specification) return register(features,specification) end + handler.features=features + end + return features + end + setmetatable(newfeatures,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewfeatures(k) t[k]=v return v end, + }) end do - local newhandler={} - constructors.handlers=newhandler - constructors.newhandler=newhandler - local function setnewhandler(what) - local handler=handlers[what] - if not handler then - handler={} - handlers[what]=handler - end - return handler - end - setmetatable(newhandler,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, - }) + local newhandler={} + constructors.handlers=newhandler + constructors.newhandler=newhandler + local function setnewhandler(what) + local handler=handlers[what] + if not handler then + handler={} + handlers[what]=handler + end + return handler + end + setmetatable(newhandler,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewhandler(k) t[k]=v return v end, + }) end do - local newenhancer={} - constructors.enhancers=newenhancer - constructors.newenhancer=newenhancer - local function setnewenhancer(format) - local handler=handlers[format] - local enhancers=handler.enhancers - if not enhancers then - local actions=allocate() - local before=allocate() - local after=allocate() - local order=allocate() - local known={} - local nofsteps=0 - local patches={ before=before,after=after } - local trace=false - local report=logs.reporter("fonts",format.." enhancing") - trackers.register(format..".loading",function(v) trace=v end) - local function enhance(name,data,filename,raw) - local enhancer=actions[name] - if enhancer then - if trace then - report("apply enhancement %a to file %a",name,filename) - ioflush() - end - enhancer(data,filename,raw) - else - end - end - local function apply(data,filename,raw) - local basename=file.basename(lower(filename)) - if trace then - report("%s enhancing file %a","start",filename) - end - ioflush() - for e=1,nofsteps do - local enhancer=order[e] - local b=before[enhancer] - if b then - for pattern,action in next,b do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - enhance(enhancer,data,filename,raw) - local a=after[enhancer] - if a then - for pattern,action in next,a do - if find(basename,pattern) then - action(data,filename,raw) - end - end - end - ioflush() - end - if trace then - report("%s enhancing file %a","stop",filename) - end - ioflush() + local newenhancer={} + constructors.enhancers=newenhancer + constructors.newenhancer=newenhancer + local function setnewenhancer(format) + local handler=handlers[format] + local enhancers=handler.enhancers + if not enhancers then + local actions=allocate() + local before=allocate() + local after=allocate() + local order=allocate() + local known={} + local nofsteps=0 + local patches={ before=before,after=after } + local trace=false + local report=logs.reporter("fonts",format.." enhancing") + trackers.register(format..".loading",function(v) trace=v end) + local function enhance(name,data,filename,raw) + local enhancer=actions[name] + if enhancer then + if trace then + report("apply enhancement %a to file %a",name,filename) + ioflush() + end + enhancer(data,filename,raw) + else + end + end + local function apply(data,filename,raw) + local basename=file.basename(lower(filename)) + if trace then + report("%s enhancing file %a","start",filename) + end + ioflush() + for e=1,nofsteps do + local enhancer=order[e] + local b=before[enhancer] + if b then + for pattern,action in next,b do + if find(basename,pattern) then + action(data,filename,raw) + end end - local function register(what,action) - if action then - if actions[what] then - else - nofsteps=nofsteps+1 - order[nofsteps]=what - known[what]=nofsteps - end - actions[what]=action - else - report("bad enhancer %a",what) - end + end + enhance(enhancer,data,filename,raw) + local a=after[enhancer] + if a then + for pattern,action in next,a do + if find(basename,pattern) then + action(data,filename,raw) + end end - local function patch(what,where,pattern,action) - local pw=patches[what] - if pw then - local ww=pw[where] - if ww then - ww[pattern]=action - else - pw[where]={ [pattern]=action } - if not known[where] then - nofsteps=nofsteps+1 - order[nofsteps]=where - known[where]=nofsteps - end - end - end + end + ioflush() + end + if trace then + report("%s enhancing file %a","stop",filename) + end + ioflush() + end + local function register(what,action) + if action then + if actions[what] then + else + nofsteps=nofsteps+1 + order[nofsteps]=what + known[what]=nofsteps + end + actions[what]=action + else + report("bad enhancer %a",what) + end + end + local function patch(what,where,pattern,action) + local pw=patches[what] + if pw then + local ww=pw[where] + if ww then + ww[pattern]=action + else + pw[where]={ [pattern]=action } + if not known[where] then + nofsteps=nofsteps+1 + order[nofsteps]=where + known[where]=nofsteps end - enhancers={ - register=register, - apply=apply, - patch=patch, - report=report, - patches={ - register=patch, - report=report, - }, - } - handler.enhancers=enhancers + end end - return enhancers + end + enhancers={ + register=register, + apply=apply, + patch=patch, + report=report, + patches={ + register=patch, + report=report, + }, + } + handler.enhancers=enhancers end - setmetatable(newenhancer,{ - __call=function(t,k) local v=t[k] return v end, - __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, - }) + return enhancers + end + setmetatable(newenhancer,{ + __call=function(t,k) local v=t[k] return v end, + __index=function(t,k) local v=setnewenhancer(k) t[k]=v return v end, + }) end function constructors.checkedfeatures(what,features) - local defaults=handlers[what].features.defaults - if features and next(features) then - features=fastcopy(features) - for key,value in next,defaults do - if features[key]==nil then - features[key]=value - end - end - return features - else - return fastcopy(defaults) - end + local defaults=handlers[what].features.defaults + if features and next(features) then + features=fastcopy(features) + for key,value in next,defaults do + if features[key]==nil then + features[key]=value + end + end + return features + else + return fastcopy(defaults) + end end function constructors.initializefeatures(what,tfmdata,features,trace,report) - if features and next(features) then - local properties=tfmdata.properties or {} - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatmodechecker=whatfeatures.modechecker - local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" - properties.mode=mode - features.mode=mode - local done={} - while true do - local redo=false - local initializers=whatfeatures.initializers[mode] - if initializers then - for i=1,#initializers do - local step=initializers[i] - local feature=step.name - local value=features[feature] - if not value then - elseif done[feature] then - else - local action=step.action - if trace then - report("initializing feature %a to %a for mode %a for font %a",feature, - value,mode,tfmdata.properties.fullname) - end - action(tfmdata,value,features) - if mode~=properties.mode or mode~=features.mode then - if whatmodechecker then - properties.mode=whatmodechecker(tfmdata,features,properties.mode) - features.mode=properties.mode - end - if mode~=properties.mode then - mode=properties.mode - redo=true - end - end - done[feature]=true - end - if redo then - break - end - end - if not redo then - break - end - else - break + if features and next(features) then + local properties=tfmdata.properties or {} + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatmodechecker=whatfeatures.modechecker + local mode=properties.mode or (whatmodechecker and whatmodechecker(tfmdata,features,features.mode)) or features.mode or "base" + properties.mode=mode + features.mode=mode + local done={} + while true do + local redo=false + local initializers=whatfeatures.initializers[mode] + if initializers then + for i=1,#initializers do + local step=initializers[i] + local feature=step.name + local value=features[feature] + if not value then + elseif done[feature] then + else + local action=step.action + if trace then + report("initializing feature %a to %a for mode %a for font %a",feature, + value,mode,tfmdata.properties.fullname) + end + action(tfmdata,value,features) + if mode~=properties.mode or mode~=features.mode then + if whatmodechecker then + properties.mode=whatmodechecker(tfmdata,features,properties.mode) + features.mode=properties.mode + end + if mode~=properties.mode then + mode=properties.mode + redo=true + end end + done[feature]=true + end + if redo then + break + end end - properties.mode=mode - return true - else - return false + if not redo then + break + end + else + break + end end + properties.mode=mode + return true + else + return false + end end function constructors.collectprocessors(what,tfmdata,features,trace,report) - local processes,nofprocesses={},0 - if features and next(features) then - local properties=tfmdata.properties - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatprocessors=whatfeatures.processors - local mode=properties.mode - local processors=whatprocessors[mode] - if processors then - for i=1,#processors do - local step=processors[i] - local feature=step.name - if features[feature] then - local action=step.action - if trace then - report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) - end - if action then - nofprocesses=nofprocesses+1 - processes[nofprocesses]=action - end - end - end - elseif trace then - report("no feature processors for mode %a for font %a",mode,properties.fullname) + local processes={} + local nofprocesses=0 + if features and next(features) then + local properties=tfmdata.properties + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatprocessors=whatfeatures.processors + local mode=properties.mode + local processors=whatprocessors[mode] + if processors then + for i=1,#processors do + local step=processors[i] + local feature=step.name + if features[feature] then + local action=step.action + if trace then + report("installing feature processor %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) + end + if action then + nofprocesses=nofprocesses+1 + processes[nofprocesses]=action + end end + end + elseif trace then + report("no feature processors for mode %a for font %a",mode,properties.fullname) end - return processes + end + return processes end function constructors.applymanipulators(what,tfmdata,features,trace,report) - if features and next(features) then - local properties=tfmdata.properties - local whathandler=handlers[what] - local whatfeatures=whathandler.features - local whatmanipulators=whatfeatures.manipulators - local mode=properties.mode - local manipulators=whatmanipulators[mode] - if manipulators then - for i=1,#manipulators do - local step=manipulators[i] - local feature=step.name - local value=features[feature] - if value then - local action=step.action - if trace then - report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) - end - if action then - action(tfmdata,feature,value) - end - end - end + if features and next(features) then + local properties=tfmdata.properties + local whathandler=handlers[what] + local whatfeatures=whathandler.features + local whatmanipulators=whatfeatures.manipulators + local mode=properties.mode + local manipulators=whatmanipulators[mode] + if manipulators then + for i=1,#manipulators do + local step=manipulators[i] + local feature=step.name + local value=features[feature] + if value then + local action=step.action + if trace then + report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) + end + if action then + action(tfmdata,feature,value) + end end + end end + end end function constructors.addcoreunicodes(unicodes) - if not unicodes then - unicodes={} - end - unicodes.space=0x0020 - unicodes.hyphen=0x002D - unicodes.zwj=0x200D - unicodes.zwnj=0x200C - return unicodes + if not unicodes then + unicodes={} + end + unicodes.space=0x0020 + unicodes.hyphen=0x002D + unicodes.zwj=0x200D + unicodes.zwnj=0x200C + return unicodes end end -- closure @@ -10211,15 +9635,15 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luatex-font-enc']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end local fonts=fonts local encodings={} @@ -10227,55 +9651,55 @@ fonts.encodings=encodings encodings.agl={} encodings.known={} setmetatable(encodings.agl,{ __index=function(t,k) - if k=="unicodes" then - texio.write(" ") - local unicodes=dofile(resolvers.findfile("font-age.lua")) - encodings.agl={ unicodes=unicodes } - return unicodes - else - return nil - end + if k=="unicodes" then + logs.report("fonts","loading (extended) adobe glyph list") + local unicodes=dofile(resolvers.findfile("font-age.lua")) + encodings.agl={ unicodes=unicodes } + return unicodes + else + return nil + end end }) encodings.cache=containers.define("fonts","enc",encodings.version,true) function encodings.load(filename) - local name=file.removesuffix(filename) - local data=containers.read(encodings.cache,name) - if data then - return data - end - local vector,tag,hash,unicodes={},"",{},{} - local foundname=resolvers.findfile(filename,'enc') - if foundname and foundname~="" then - local ok,encoding,size=resolvers.loadbinfile(foundname) - if ok and encoding then - encoding=string.gsub(encoding,"%%(.-)\n","") - local unicoding=encodings.agl.unicodes - local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") - local i=0 - for ch in string.gmatch(vec,"/([%a%d%.]+)") do - if ch~=".notdef" then - vector[i]=ch - if not hash[ch] then - hash[ch]=i - else - end - local u=unicoding[ch] - if u then - unicodes[u]=i - end - end - i=i+1 - end + local name=file.removesuffix(filename) + local data=containers.read(encodings.cache,name) + if data then + return data + end + local vector,tag,hash,unicodes={},"",{},{} + local foundname=resolvers.findfile(filename,'enc') + if foundname and foundname~="" then + local ok,encoding,size=resolvers.loadbinfile(foundname) + if ok and encoding then + encoding=string.gsub(encoding,"%%(.-)\n","") + local unicoding=encodings.agl.unicodes + local tag,vec=string.match(encoding,"/(%w+)%s*%[(.*)%]%s*def") + local i=0 + for ch in string.gmatch(vec,"/([%a%d%.]+)") do + if ch~=".notdef" then + vector[i]=ch + if not hash[ch] then + hash[ch]=i + else + end + local u=unicoding[ch] + if u then + unicodes[u]=i + end end - end - local data={ - name=name, - tag=tag, - vector=vector, - hash=hash, - unicodes=unicodes - } - return containers.write(encodings.cache,name,data) + i=i+1 + end + end + end + local data={ + name=name, + tag=tag, + vector=vector, + hash=hash, + unicodes=unicodes + } + return containers.write(encodings.cache,name,data) end end -- closure @@ -10283,17 +9707,17 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-cid']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local format,match,lower=string.format,string.match,string.lower local tonumber=tonumber local P,S,R,C,V,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.match local fonts,logs,trackers=fonts,logs,trackers -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) local report_otf=logs.reporter("fonts","otf loading") local cid={} fonts.cid=cid @@ -10307,128 +9731,128 @@ local periods=period*period local name=P("/")*C((1-space)^1) local unicodes,names={},{} local function do_one(a,b) - unicodes[tonumber(a)]=tonumber(b,16) + unicodes[tonumber(a)]=tonumber(b,16) end local function do_range(a,b,c) - c=tonumber(c,16) - for i=tonumber(a),tonumber(b) do - unicodes[i]=c - c=c+1 - end + c=tonumber(c,16) + for i=tonumber(a),tonumber(b) do + unicodes[i]=c + c=c+1 + end end local function do_name(a,b) - names[tonumber(a)]=b + names[tonumber(a)]=b end local grammar=P { "start", - start=number*spaces*number*V("series"), - series=(spaces*(V("one")+V("range")+V("named")))^1, - one=(number*spaces*number)/do_one, - range=(number*periods*number*spaces*number)/do_range, - named=(number*spaces*name)/do_name + start=number*spaces*number*V("series"), + series=(spaces*(V("one")+V("range")+V("named")))^1, + one=(number*spaces*number)/do_one, + range=(number*periods*number*spaces*number)/do_range, + named=(number*spaces*name)/do_name } local function loadcidfile(filename) - local data=io.loaddata(filename) - if data then - unicodes,names={},{} - lpegmatch(grammar,data) - local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$") - return { - supplement=supplement, - registry=registry, - ordering=ordering, - filename=filename, - unicodes=unicodes, - names=names, - } - end + local data=io.loaddata(filename) + if data then + unicodes,names={},{} + lpegmatch(grammar,data) + local supplement,registry,ordering=match(filename,"^(.-)%-(.-)%-()%.(.-)$") + return { + supplement=supplement, + registry=registry, + ordering=ordering, + filename=filename, + unicodes=unicodes, + names=names, + } + end end cid.loadfile=loadcidfile local template="%s-%s-%s.cidmap" local function locate(registry,ordering,supplement) - local filename=format(template,registry,ordering,supplement) - local hashname=lower(filename) - local found=cidmap[hashname] - if not found then + local filename=format(template,registry,ordering,supplement) + local hashname=lower(filename) + local found=cidmap[hashname] + if not found then + if trace_loading then + report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename) + end + local fullname=resolvers.findfile(filename,'cid') or "" + if fullname~="" then + found=loadcidfile(fullname) + if found then if trace_loading then - report_otf("checking cidmap, registry %a, ordering %a, supplement %a, filename %a",registry,ordering,supplement,filename) - end - local fullname=resolvers.findfile(filename,'cid') or "" - if fullname~="" then - found=loadcidfile(fullname) - if found then - if trace_loading then - report_otf("using cidmap file %a",filename) - end - cidmap[hashname]=found - found.usedname=file.basename(filename) - end + report_otf("using cidmap file %a",filename) end + cidmap[hashname]=found + found.usedname=file.basename(filename) + end end - return found + end + return found end function cid.getmap(specification) - if not specification then - report_otf("invalid cidinfo specification, table expected") - return - end - local registry=specification.registry - local ordering=specification.ordering - local supplement=specification.supplement - local filename=format(registry,ordering,supplement) - local lowername=lower(filename) - local found=cidmap[lowername] - if found then - return found - end - if ordering=="Identity" then - local found={ - supplement=supplement, - registry=registry, - ordering=ordering, - filename=filename, - unicodes={}, - names={}, - } - cidmap[lowername]=found - return found - end - if trace_loading then - report_otf("cidmap needed, registry %a, ordering %a, supplement %a",registry,ordering,supplement) - end - found=locate(registry,ordering,supplement) - if not found then - local supnum=tonumber(supplement) - local cidnum=nil - if supnum0 then - for s=supnum-1,0,-1 do - local c=locate(registry,ordering,s) - if c then - found,cidnum=c,s - break - end - end + end + end + if not found and supnum>0 then + for s=supnum-1,0,-1 do + local c=locate(registry,ordering,s) + if c then + found,cidnum=c,s + break end - registry=lower(registry) - ordering=lower(ordering) - if found and cidnum>0 then - for s=0,cidnum-1 do - local filename=format(template,registry,ordering,s) - if not cidmap[filename] then - cidmap[filename]=found - end - end + end + end + registry=lower(registry) + ordering=lower(ordering) + if found and cidnum>0 then + for s=0,cidnum-1 do + local filename=format(template,registry,ordering,s) + if not cidmap[filename] then + cidmap[filename]=found end + end end - return found + end + return found end end -- closure @@ -10436,11 +9860,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-map']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local tonumber,next,type=tonumber,next,type local match,format,find,concat,gsub,lower=string.match,string.format,string.find,table.concat,string.gsub,string.lower @@ -10448,10 +9872,10 @@ local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.m local formatters=string.formatters local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys local rshift=bit32.rshift -local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) -local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) +local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end) +local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end) local report_fonts=logs.reporter("fonts","loading") -local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) +local force_ligatures=false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures=v end) local fonts=fonts or {} local mappings=fonts.mappings or {} fonts.mappings=mappings @@ -10462,74 +9886,82 @@ local hexsix=(hex*hex*hex^-4)/function(s) return tonumber(s,16) end local dec=(R("09")^1)/tonumber local period=P(".") local unicode=(P("uni")+P("UNI"))*(hexfour*(period+P(-1))*Cc(false)+Ct(hexfour^1)*Cc(true)) -local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) +local ucode=(P("u")+P("U") )*(hexsix*(period+P(-1))*Cc(false)+Ct(hexsix^1)*Cc(true)) local index=P("index")*dec*Cc(false) local parser=unicode+ucode+index local parsers={} local function makenameparser(str) - if not str or str=="" then - return parser - else - local p=parsers[str] - if not p then - p=P(str)*period*dec*Cc(false) - parsers[str]=p - end - return p + if not str or str=="" then + return parser + else + local p=parsers[str] + if not p then + p=P(str)*period*dec*Cc(false) + parsers[str]=p end + return p + end end local f_single=formatters["%04X"] local f_double=formatters["%04X%04X"] local function tounicode16(unicode) - if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then - return f_single(unicode) - else - unicode=unicode-0x10000 - return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) - end + if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then + return f_single(unicode) + else + unicode=unicode-0x10000 + return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) + end end local function tounicode16sequence(unicodes) - local t={} - for l=1,#unicodes do - local u=unicodes[l] - if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then - t[l]=f_single(u) - else - u=u-0x10000 - t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00) - end - end - return concat(t) -end -local function tounicode(unicode) - if type(unicode)=="table" then - local t={} - for l=1,#unicode do - local u=unicode[l] - if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then - t[l]=f_single(u) - else - u=u-0x10000 - t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00) - end - end - return concat(t) - else - if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then - return f_single(unicode) - else - unicode=unicode-0x10000 - return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00) - end - end + local t={} + for l=1,#unicodes do + local u=unicodes[l] + if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then + t[l]=f_single(u) + else + u=u-0x10000 + t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00) + end + end + return concat(t) +end +local unknown=f_single(0xFFFD) +local hash={} +local conc={} +table.setmetatableindex(hash,function(t,k) + if k<0xD7FF or (k>0xDFFF and k<=0xFFFF) then + v=f_single(k) + else + local k=k-0x10000 + v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00) + end + t[k]=v + return v +end) +local function tounicode(k) + if type(k)=="table" then + local n=#k + for l=1,n do + conc[l]=hash[k[l]] + end + return concat(conc,"",1,n) + elseif k>=0x00E000 and k<=0x00F8FF then + return unknown + elseif k>=0x0F0000 and k<=0x0FFFFF then + return unknown + elseif k>=0x100000 and k<=0x10FFFF then + return unknown + else + return hash[k] + end end local function fromunicode16(str) - if #str==4 then - return tonumber(str,16) - else - local l,r=match(str,"(....)(....)") - return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00 - end + if #str==4 then + return tonumber(str,16) + else + local l,r=match(str,"(....)(....)") + return 0x10000+(tonumber(l,16)-0xD800)*0x400+tonumber(r,16)-0xDC00 + end end mappings.makenameparser=makenameparser mappings.tounicode=tounicode @@ -10540,272 +9972,277 @@ local ligseparator=P("_") local varseparator=P(".") local namesplitter=Ct(C((1-ligseparator-varseparator)^1)*(ligseparator*C((1-ligseparator-varseparator)^1))^0) do - local overloads={ - IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, - ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, - ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, - fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, - fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, - ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, - ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, - fj={ name="f_j",unicode={ 0x66,0x6A } }, - fk={ name="f_k",unicode={ 0x66,0x6B } }, - } - local o=allocate {} - for k,v in next,overloads do - local name=v.name - local mess=v.mess - if name then - o[name]=v - end - if mess then - o[mess]=v - end - o[k]=v + local overloads={ + IJ={ name="I_J",unicode={ 0x49,0x4A },mess=0x0132 }, + ij={ name="i_j",unicode={ 0x69,0x6A },mess=0x0133 }, + ff={ name="f_f",unicode={ 0x66,0x66 },mess=0xFB00 }, + fi={ name="f_i",unicode={ 0x66,0x69 },mess=0xFB01 }, + fl={ name="f_l",unicode={ 0x66,0x6C },mess=0xFB02 }, + ffi={ name="f_f_i",unicode={ 0x66,0x66,0x69 },mess=0xFB03 }, + ffl={ name="f_f_l",unicode={ 0x66,0x66,0x6C },mess=0xFB04 }, + fj={ name="f_j",unicode={ 0x66,0x6A } }, + fk={ name="f_k",unicode={ 0x66,0x6B } }, + } + local o=allocate {} + for k,v in next,overloads do + local name=v.name + local mess=v.mess + if name then + o[name]=v end - mappings.overloads=o + if mess then + o[mess]=v + end + o[k]=v + end + mappings.overloads=o end function mappings.addtounicode(data,filename,checklookups,forceligatures) - local resources=data.resources - local unicodes=resources.unicodes - if not unicodes then - if trace_mapping then - report_fonts("no unicode list, quitting tounicode for %a",filename) - end - return + local resources=data.resources + local unicodes=resources.unicodes + if not unicodes then + if trace_mapping then + report_fonts("no unicode list, quitting tounicode for %a",filename) end - local properties=data.properties - local descriptions=data.descriptions - local overloads=mappings.overloads - unicodes['space']=unicodes['space'] or 32 - unicodes['hyphen']=unicodes['hyphen'] or 45 - unicodes['zwj']=unicodes['zwj'] or 0x200D - unicodes['zwnj']=unicodes['zwnj'] or 0x200C - local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 - local unicodevector=fonts.encodings.agl.unicodes or {} - local contextvector=fonts.encodings.agl.ctxcodes or {} - local missing={} - local nofmissing=0 - local oparser=nil - local cidnames=nil - local cidcodes=nil - local cidinfo=properties.cidinfo - local usedmap=cidinfo and fonts.cid.getmap(cidinfo) - local uparser=makenameparser() - if usedmap then - oparser=usedmap and makenameparser(cidinfo.ordering) - cidnames=usedmap.names - cidcodes=usedmap.unicodes - end - local ns=0 - local nl=0 - local dlist=sortedkeys(descriptions) - for i=1,#dlist do - local du=dlist[i] - local glyph=descriptions[du] - local name=glyph.name - if name then - local overload=overloads[name] or overloads[du] - if overload then - glyph.unicode=overload.unicode - else - local gu=glyph.unicode - if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then - local unicode=unicodevector[name] or contextvector[name] + return + end + local properties=data.properties + local descriptions=data.descriptions + local overloads=mappings.overloads + unicodes['space']=unicodes['space'] or 32 + unicodes['hyphen']=unicodes['hyphen'] or 45 + unicodes['zwj']=unicodes['zwj'] or 0x200D + unicodes['zwnj']=unicodes['zwnj'] or 0x200C + local private=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 + local unicodevector=fonts.encodings.agl.unicodes or {} + local contextvector=fonts.encodings.agl.ctxcodes or {} + local missing={} + local nofmissing=0 + local oparser=nil + local cidnames=nil + local cidcodes=nil + local cidinfo=properties.cidinfo + local usedmap=cidinfo and fonts.cid.getmap(cidinfo) + local uparser=makenameparser() + if usedmap then + oparser=usedmap and makenameparser(cidinfo.ordering) + cidnames=usedmap.names + cidcodes=usedmap.unicodes + end + local ns=0 + local nl=0 + local dlist=sortedkeys(descriptions) + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name + if name then + local overload=overloads[name] or overloads[du] + if overload then + glyph.unicode=overload.unicode + else + local gu=glyph.unicode + if not gu or gu==-1 or du>=private or (du>=0xE000 and du<=0xF8FF) or du==0xFFFE or du==0xFFFF then + local unicode=unicodevector[name] or contextvector[name] + if unicode then + glyph.unicode=unicode + ns=ns+1 + end + if (not unicode) and usedmap then + local foundindex=lpegmatch(oparser,name) + if foundindex then + unicode=cidcodes[foundindex] + if unicode then + glyph.unicode=unicode + ns=ns+1 + else + local reference=cidnames[foundindex] + if reference then + local foundindex=lpegmatch(oparser,reference) + if foundindex then + unicode=cidcodes[foundindex] if unicode then - glyph.unicode=unicode - ns=ns+1 - end - if (not unicode) and usedmap then - local foundindex=lpegmatch(oparser,name) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - else - local reference=cidnames[foundindex] - if reference then - local foundindex=lpegmatch(oparser,reference) - if foundindex then - unicode=cidcodes[foundindex] - if unicode then - glyph.unicode=unicode - ns=ns+1 - end - end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,reference) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else - ns=ns+1 - unicode=foundcodes - end - end - end - end - end - end - end - if not unicode or unicode=="" then - local split=lpegmatch(namesplitter,name) - local nsplit=split and #split or 0 - if nsplit==0 then - elseif nsplit==1 then - local base=split[1] - local u=unicodes[base] or unicodevector[base] or contextvector[name] - if not u then - elseif type(u)=="table" then - if u[1]=private then - break - end - n=n+1 - t[n]=u[1] - else - if u>=private then - break - end - n=n+1 - t[n]=u - end - end - if n>0 then - if n==1 then - unicode=t[1] - else - unicode=t - end - glyph.unicode=unicode - end - end + glyph.unicode=unicode + ns=ns+1 + end + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,reference) + if foundcodes then + glyph.unicode=foundcodes + if multiple then nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end end - if not unicode or unicode=="" then - local foundcodes,multiple=lpegmatch(uparser,name) - if foundcodes then - glyph.unicode=foundcodes - if multiple then - nl=nl+1 - unicode=true - else - ns=ns+1 - unicode=foundcodes - end - end - end - local r=overloads[unicode] - if r then - unicode=r.unicode - glyph.unicode=unicode - end - if not unicode then - missing[du]=true - nofmissing=nofmissing+1 - end + end end + end end - else - local overload=overloads[du] - if overload then - glyph.unicode=overload.unicode - end - end - end - if type(checklookups)=="function" then - checklookups(data,missing,nofmissing) - end - local unicoded=0 - local collected=fonts.handlers.otf.readers.getcomponents(data) - local function resolve(glyph,u) - local n=#u - for i=1,n do - if u[i]>private then - n=0 - break - end - end - if n>0 then - if n>1 then - glyph.unicode=u + end + if not unicode or unicode=="" then + local split=lpegmatch(namesplitter,name) + local nsplit=split and #split or 0 + if nsplit==0 then + elseif nsplit==1 then + local base=split[1] + local u=unicodes[base] or unicodevector[base] or contextvector[name] + if not u then + elseif type(u)=="table" then + if u[1]=private or (du>=0xE000 and du<=0xF8FF) then - local u=collected[du] - if u then - resolve(descriptions[du],u) + local t={} + local n=0 + for l=1,nsplit do + local base=split[l] + local u=unicodes[base] or unicodevector[base] or contextvector[name] + if not u then + break + elseif type(u)=="table" then + if u[1]>=private then + break + end + n=n+1 + t[n]=u[1] + else + if u>=private then + break + end + n=n+1 + t[n]=u end - end - end - else - for i=1,#dlist do - local du=dlist[i] - if du>=private or (du>=0xE000 and du<=0xF8FF) then - local glyph=descriptions[du] - if glyph.class=="ligature" and not glyph.unicode then - local u=collected[du] - if u then - resolve(glyph,u) - end + end + if n>0 then + if n==1 then + unicode=t[1] + else + unicode=t end + glyph.unicode=unicode + end + end + nl=nl+1 + end + if not unicode or unicode=="" then + local foundcodes,multiple=lpegmatch(uparser,name) + if foundcodes then + glyph.unicode=foundcodes + if multiple then + nl=nl+1 + unicode=true + else + ns=ns+1 + unicode=foundcodes + end end + end + local r=overloads[unicode] + if r then + unicode=r.unicode + glyph.unicode=unicode + end + if not unicode then + missing[du]=true + nofmissing=nofmissing+1 + end + else end + end + else + local overload=overloads[du] + if overload then + glyph.unicode=overload.unicode + elseif not glyph.unicode then + missing[du]=true + nofmissing=nofmissing+1 + end + end + end + if type(checklookups)=="function" then + checklookups(data,missing,nofmissing) + end + local unicoded=0 + local collected=fonts.handlers.otf.readers.getcomponents(data) + local function resolve(glyph,u) + local n=#u + for i=1,n do + if u[i]>private then + n=0 + break + end end - if trace_mapping and unicoded>0 then - report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) + if n>0 then + if n>1 then + glyph.unicode=u + else + glyph.unicode=u[1] + end + unicoded=unicoded+1 + end + end + if not collected then + elseif forceligatures or force_ligatures then + for i=1,#dlist do + local du=dlist[i] + if du>=private or (du>=0xE000 and du<=0xF8FF) then + local u=collected[du] + if u then + resolve(descriptions[du],u) + end + end end - if trace_mapping then - for i=1,#dlist do - local du=dlist[i] - local glyph=descriptions[du] - local name=glyph.name or "-" - local index=glyph.index or 0 - local unicode=glyph.unicode - if unicode then - if type(unicode)=="table" then - local unicodes={} - for i=1,#unicode do - unicodes[i]=formatters("%U",unicode[i]) - end - report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) - else - report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) - end - else - report_fonts("internal slot %U, name %a, unicode %U",index,name,du) - end + else + for i=1,#dlist do + local du=dlist[i] + if du>=private or (du>=0xE000 and du<=0xF8FF) then + local glyph=descriptions[du] + if glyph.class=="ligature" and not glyph.unicode then + local u=collected[du] + if u then + resolve(glyph,u) + end end + end end - if trace_loading and (ns>0 or nl>0) then - report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns) + end + if trace_mapping and unicoded>0 then + report_fonts("%n ligature tounicode mappings deduced from gsub ligature features",unicoded) + end + if trace_mapping then + for i=1,#dlist do + local du=dlist[i] + local glyph=descriptions[du] + local name=glyph.name or "-" + local index=glyph.index or 0 + local unicode=glyph.unicode + if unicode then + if type(unicode)=="table" then + local unicodes={} + for i=1,#unicode do + unicodes[i]=formatters("%U",unicode[i]) + end + report_fonts("internal slot %U, name %a, unicode %U, tounicode % t",index,name,du,unicodes) + else + report_fonts("internal slot %U, name %a, unicode %U, tounicode %U",index,name,du,unicode) + end + else + report_fonts("internal slot %U, name %a, unicode %U",index,name,du) + end end + end + if trace_loading and (ns>0 or nl>0) then + report_fonts("%s tounicode entries added, ligatures %s",nl+ns,ns) + end end end -- closure @@ -10813,15 +10250,15 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luatex-fonts-syn']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end local fonts=fonts fonts.names=fonts.names or {} @@ -10832,217 +10269,173 @@ local data=nil local loaded=false local fileformats={ "lua","tex","other text files" } function fonts.names.reportmissingbase() - texio.write("") - fonts.names.reportmissingbase=nil + logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple") + fonts.names.reportmissingbase=nil end function fonts.names.reportmissingname() - texio.write("") - fonts.names.reportmissingname=nil + logs.report("fonts","unknown font in font database, run: mtxrun --script fonts --reload --simple") + fonts.names.reportmissingname=nil end function fonts.names.resolve(name,sub) - if not loaded then - local basename=fonts.names.basename - if basename and basename~="" then - data=containers.read(fonts.names.cache,basename) - if not data then - basename=file.addsuffix(basename,"lua") - for i=1,#fileformats do - local format=fileformats[i] - local foundname=resolvers.findfile(basename,format) or "" - if foundname~="" then - data=dofile(foundname) - texio.write("") - break - end - end - end - end - loaded=true - end - if type(data)=="table" and data.version==fonts.names.version then - local condensed=string.gsub(string.lower(name),"[^%a%d]","") - local found=data.mappings and data.mappings[condensed] - if found then - local fontname,filename,subfont=found[1],found[2],found[3] - if subfont then - return filename,fontname - else - return filename,false - end - elseif fonts.names.reportmissingname then - fonts.names.reportmissingname() - return name,false + if not loaded then + local basename=fonts.names.basename + if basename and basename~="" then + data=containers.read(fonts.names.cache,basename) + if not data then + basename=file.addsuffix(basename,"lua") + for i=1,#fileformats do + local format=fileformats[i] + local foundname=resolvers.findfile(basename,format) or "" + if foundname~="" then + data=dofile(foundname) + logs.report("fonts","font database '%s' loaded",foundname) + break + end end - elseif fonts.names.reportmissingbase then - fonts.names.reportmissingbase() + end end + loaded=true + end + if type(data)=="table" and data.version==fonts.names.version then + local condensed=string.gsub(string.lower(name),"[^%a%d]","") + local found=data.mappings and data.mappings[condensed] + if found then + local fontname,filename,subfont=found[1],found[2],found[3] + if subfont then + return filename,fontname + else + return filename,false + end + elseif fonts.names.reportmissingname then + fonts.names.reportmissingname() + return name,false + end + elseif fonts.names.reportmissingbase then + fonts.names.reportmissingbase() + end end fonts.names.resolvespec=fonts.names.resolve -function fonts.names.getfilename(askedname,suffix) - return "" +function fonts.names.getfilename(askedname,suffix) + return "" end function fonts.names.ignoredfile(filename) - return false + return false end end -- closure do -- begin closure to overcome local limits and interference -if not modules then modules={} end modules ['font-oti']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" +if not modules then modules={} end modules ['font-vfc']={ + version=1.001, + comment="companion to font-ini.mkiv and hand-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } -local lower=string.lower +local select,type=select,type +local insert=table.insert local fonts=fonts -local constructors=fonts.constructors -local otf=constructors.handlers.otf -local otffeatures=constructors.features.otf -local registerotffeature=otffeatures.register -local otftables=otf.tables or {} -otf.tables=otftables -local allocate=utilities.storage.allocate -registerotffeature { - name="features", - description="initialization of feature handler", - default=true, -} -local function setmode(tfmdata,value) - if value then - tfmdata.properties.mode=lower(value) - end -end -otf.modeinitializer=setmode -local function setlanguage(tfmdata,value) - if value then - local cleanvalue=lower(value) - local languages=otftables and otftables.languages - local properties=tfmdata.properties - if not languages then - properties.language=cleanvalue - elseif languages[value] then - properties.language=cleanvalue - else - properties.language="dflt" - end +local helpers=fonts.helpers +local setmetatableindex=table.setmetatableindex +local makeweak=table.makeweak +local push={ "push" } +local pop={ "pop" } +local dummy={ "comment" } +function helpers.prependcommands(commands,...) + insert(commands,1,push) + for i=select("#",...),1,-1 do + local s=(select(i,...)) + if s then + insert(commands,1,s) end + end + insert(commands,pop) + return commands end -local function setscript(tfmdata,value) - if value then - local cleanvalue=lower(value) - local scripts=otftables and otftables.scripts - local properties=tfmdata.properties - if not scripts then - properties.script=cleanvalue - elseif scripts[value] then - properties.script=cleanvalue - else - properties.script="dflt" - end +function helpers.appendcommands(commands,...) + insert(commands,1,push) + insert(commands,pop) + for i=1,select("#",...) do + local s=(select(i,...)) + if s then + insert(commands,s) end + end + return commands end -registerotffeature { - name="mode", - description="mode", - initializers={ - base=setmode, - node=setmode, - plug=setmode, - } -} -registerotffeature { - name="language", - description="language", - initializers={ - base=setlanguage, - node=setlanguage, - plug=setlanguage, - } -} -registerotffeature { - name="script", - description="script", - initializers={ - base=setscript, - node=setscript, - plug=setscript, - } -} -otftables.featuretypes=allocate { - gpos_single="position", - gpos_pair="position", - gpos_cursive="position", - gpos_mark2base="position", - gpos_mark2ligature="position", - gpos_mark2mark="position", - gpos_context="position", - gpos_contextchain="position", - gsub_single="substitution", - gsub_multiple="substitution", - gsub_alternate="substitution", - gsub_ligature="substitution", - gsub_context="substitution", - gsub_contextchain="substitution", - gsub_reversecontextchain="substitution", - gsub_reversesub="substitution", -} -function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts) - if featuretype=="position" then - local default=scripts.dflt - if default then - if autoscript=="position" or autoscript==true then - return default - else - report_otf("script feature %s not applied, enable default positioning") - end - else - end - elseif featuretype=="substitution" then - local default=scripts.dflt - if default then - if autoscript=="substitution" or autoscript==true then - return default - end - end +function helpers.prependcommandtable(commands,t) + insert(commands,1,push) + for i=#t,1,-1 do + local s=t[i] + if s then + insert(commands,1,s) end + end + insert(commands,pop) + return commands end -function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) - if featuretype=="position" then - local default=languages.dflt - if default then - if autolanguage=="position" or autolanguage==true then - return default - else - report_otf("language feature %s not applied, enable default positioning") - end - else - end - elseif featuretype=="substitution" then - local default=languages.dflt - if default then - if autolanguage=="substitution" or autolanguage==true then - return default - end - end +function helpers.appendcommandtable(commands,t) + insert(commands,1,push) + insert(commands,pop) + for i=1,#t do + local s=t[i] + if s then + insert(commands,s) end + end + return commands end +local char=setmetatableindex(function(t,k) + local v={ "slot",0,k } + t[k]=v + return v +end) +local right=setmetatableindex(function(t,k) + local v={ "right",k } + t[k]=v + return v +end) +local left=setmetatableindex(function(t,k) + local v={ "right",-k } + t[k]=v + return v +end) +local down=setmetatableindex(function(t,k) + local v={ "down",k } + t[k]=v + return v +end) +local up=setmetatableindex(function(t,k) + local v={ "down",-k } + t[k]=v + return v +end) +helpers.commands=utilities.storage.allocate { + char=char, + right=right, + left=left, + down=down, + up=up, + push=push, + pop=pop, + dummy=dummy, +} end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-otr']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local next,type,tonumber=next,type,tonumber local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub +local fullstrip=string.fullstrip local floor,round=math.floor,math.round local P,R,S,C,Cs,Cc,Ct,Carg,Cmt=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg,lpeg.Cmt local lpegmatch=lpeg.match @@ -11063,7 +10456,7 @@ local otf=handlers.otf or {} handlers.otf=otf local readers=otf.readers or {} otf.readers=readers -local streamreader=utilities.files +local streamreader=utilities.files local streamwriter=utilities.files readers.streamreader=streamreader readers.streamwriter=streamwriter @@ -11073,1729 +10466,2986 @@ local setposition=streamreader.setposition local skipshort=streamreader.skipshort local readbytes=streamreader.readbytes local readstring=streamreader.readstring -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readuint=streamreader.readcardinal3 +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readuint=streamreader.readcardinal3 local readulong=streamreader.readcardinal4 -local readshort=streamreader.readinteger2 -local readlong=streamreader.readinteger4 +local readshort=streamreader.readinteger2 +local readlong=streamreader.readinteger4 local readfixed=streamreader.readfixed4 -local read2dot14=streamreader.read2dot14 -local readfword=readshort -local readufword=readushort +local read2dot14=streamreader.read2dot14 +local readfword=readshort +local readufword=readushort local readoffset=readushort +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable function streamreader.readtag(f) + return lower(stripstring(readstring(f,4))) +end +local short=2 +local ushort=2 +local ulong=4 +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + openfile=streamreader.open + closefile=streamreader.close + setposition=streamreader.setposition + skipshort=streamreader.skipshort + readbytes=streamreader.readbytes + readstring=streamreader.readstring + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readuint=streamreader.readcardinal3 + readulong=streamreader.readcardinal4 + readshort=streamreader.readinteger2 + readlong=streamreader.readinteger4 + readfixed=streamreader.readfixed4 + read2dot14=streamreader.read2dot14 + readfword=readshort + readufword=readushort + readoffset=readushort + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable + function streamreader.readtag(f) return lower(stripstring(readstring(f,4))) -end + end +end) local function readlongdatetime(f) - local a,b,c,d,e,f,g,h=readbytes(f,8) - return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h + local a,b,c,d,e,f,g,h=readbytes(f,8) + return 0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h end local tableversion=0.004 readers.tableversion=tableversion local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 local reservednames={ [0]="copyright", - "family", - "subfamily", - "uniqueid", - "fullname", - "version", - "postscriptname", - "trademark", - "manufacturer", - "designer", - "description", - "vendorurl", - "designerurl", - "license", - "licenseurl", - "reserved", - "typographicfamily", - "typographicsubfamily", - "compatiblefullname", - "sampletext", - "cidfindfontname", - "wwsfamily", - "wwssubfamily", - "lightbackgroundpalette", - "darkbackgroundpalette", - "variationspostscriptnameprefix", + "family", + "subfamily", + "uniqueid", + "fullname", + "version", + "postscriptname", + "trademark", + "manufacturer", + "designer", + "description", + "vendorurl", + "designerurl", + "license", + "licenseurl", + "reserved", + "typographicfamily", + "typographicsubfamily", + "compatiblefullname", + "sampletext", + "cidfindfontname", + "wwsfamily", + "wwssubfamily", + "lightbackgroundpalette", + "darkbackgroundpalette", + "variationspostscriptnameprefix", } local platforms={ [0]="unicode", - "macintosh", - "iso", - "windows", - "custom", + "macintosh", + "iso", + "windows", + "custom", } local encodings={ - unicode={ [0]="unicode 1.0 semantics", - "unicode 1.1 semantics", - "iso/iec 10646", - "unicode 2.0 bmp", - "unicode 2.0 full", - "unicode variation sequences", - "unicode full repertoire", - }, - macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian", - "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada", - "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian", - "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi", - "uninterpreted", - }, - iso={ [0]="7-bit ascii", - "iso 10646", - "iso 8859-1", - }, - windows={ [0]="symbol", - "unicode bmp", - "shiftjis", - "prc", - "big5", - "wansung", - "johab", - "reserved 7", - "reserved 8", - "reserved 9", - "unicode ucs-4", - }, - custom={ - } + unicode={ [0]="unicode 1.0 semantics", + "unicode 1.1 semantics", + "iso/iec 10646", + "unicode 2.0 bmp", + "unicode 2.0 full", + "unicode variation sequences", + "unicode full repertoire", + }, + macintosh={ [0]="roman","japanese","chinese (traditional)","korean","arabic","hebrew","greek","russian", + "rsymbol","devanagari","gurmukhi","gujarati","oriya","bengali","tamil","telugu","kannada", + "malayalam","sinhalese","burmese","khmer","thai","laotian","georgian","armenian", + "chinese (simplified)","tibetan","mongolian","geez","slavic","vietnamese","sindhi", + "uninterpreted", + }, + iso={ [0]="7-bit ascii", + "iso 10646", + "iso 8859-1", + }, + windows={ [0]="symbol", + "unicode bmp", + "shiftjis", + "prc", + "big5", + "wansung", + "johab", + "reserved 7", + "reserved 8", + "reserved 9", + "unicode ucs-4", + }, + custom={ + } } local decoders={ - unicode={}, - macintosh={}, - iso={}, - windows={ - ["unicode semantics"]=utf16_to_utf8_be, - ["unicode bmp"]=utf16_to_utf8_be, - ["unicode full"]=utf16_to_utf8_be, - ["unicode 1.0 semantics"]=utf16_to_utf8_be, - ["unicode 1.1 semantics"]=utf16_to_utf8_be, - ["unicode 2.0 bmp"]=utf16_to_utf8_be, - ["unicode 2.0 full"]=utf16_to_utf8_be, - ["unicode variation sequences"]=utf16_to_utf8_be, - ["unicode full repertoire"]=utf16_to_utf8_be, - }, - custom={}, + unicode={}, + macintosh={}, + iso={}, + windows={ + ["unicode semantics"]=utf16_to_utf8_be, + ["unicode bmp"]=utf16_to_utf8_be, + ["unicode full"]=utf16_to_utf8_be, + ["unicode 1.0 semantics"]=utf16_to_utf8_be, + ["unicode 1.1 semantics"]=utf16_to_utf8_be, + ["unicode 2.0 bmp"]=utf16_to_utf8_be, + ["unicode 2.0 full"]=utf16_to_utf8_be, + ["unicode variation sequences"]=utf16_to_utf8_be, + ["unicode full repertoire"]=utf16_to_utf8_be, + }, + custom={}, } local languages={ - unicode={ - [ 0]="english", - }, - macintosh={ - [ 0]="english", - }, - iso={}, - windows={ - [0x0409]="english - united states", - }, - custom={}, + unicode={ + [ 0]="english", + }, + macintosh={ + [ 0]="english", + }, + iso={}, + windows={ + [0x0409]="english - united states", + }, + custom={}, } local standardromanencoding={ [0]= - "notdef",".null","nonmarkingreturn","space","exclam","quotedbl", - "numbersign","dollar","percent","ampersand","quotesingle","parenleft", - "parenright","asterisk","plus","comma","hyphen","period","slash", - "zero","one","two","three","four","five","six","seven","eight", - "nine","colon","semicolon","less","equal","greater","question","at", - "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", - "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft", - "backslash","bracketright","asciicircum","underscore","grave","a","b", - "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", - "r","s","t","u","v","w","x","y","z","braceleft","bar", - "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute", - "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex", - "adieresis","atilde","aring","ccedilla","eacute","egrave", - "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis", - "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute", - "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling", - "section","bullet","paragraph","germandbls","registered","copyright", - "trademark","acute","dieresis","notequal","AE","Oslash","infinity", - "plusminus","lessequal","greaterequal","yen","mu","partialdiff", - "summation","product","pi","integral","ordfeminine","ordmasculine", - "Omega","ae","oslash","questiondown","exclamdown","logicalnot", - "radical","florin","approxequal","Delta","guillemotleft", - "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", - "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright", - "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis", - "fraction","currency","guilsinglleft","guilsinglright","fi","fl", - "daggerdbl","periodcentered","quotesinglbase","quotedblbase", - "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", - "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex", - "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi", - "circumflex","tilde","macron","breve","dotaccent","ring","cedilla", - "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron", - "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn", - "thorn","minus","multiply","onesuperior","twosuperior","threesuperior", - "onehalf","onequarter","threequarters","franc","Gbreve","gbreve", - "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron", - "dcroat", + "notdef",".null","nonmarkingreturn","space","exclam","quotedbl", + "numbersign","dollar","percent","ampersand","quotesingle","parenleft", + "parenright","asterisk","plus","comma","hyphen","period","slash", + "zero","one","two","three","four","five","six","seven","eight", + "nine","colon","semicolon","less","equal","greater","question","at", + "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O", + "P","Q","R","S","T","U","V","W","X","Y","Z","bracketleft", + "backslash","bracketright","asciicircum","underscore","grave","a","b", + "c","d","e","f","g","h","i","j","k","l","m","n","o","p","q", + "r","s","t","u","v","w","x","y","z","braceleft","bar", + "braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute", + "Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex", + "adieresis","atilde","aring","ccedilla","eacute","egrave", + "ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis", + "ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute", + "ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling", + "section","bullet","paragraph","germandbls","registered","copyright", + "trademark","acute","dieresis","notequal","AE","Oslash","infinity", + "plusminus","lessequal","greaterequal","yen","mu","partialdiff", + "summation","product","pi","integral","ordfeminine","ordmasculine", + "Omega","ae","oslash","questiondown","exclamdown","logicalnot", + "radical","florin","approxequal","Delta","guillemotleft", + "guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde", + "Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright", + "quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis", + "fraction","currency","guilsinglleft","guilsinglright","fi","fl", + "daggerdbl","periodcentered","quotesinglbase","quotedblbase", + "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex", + "apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi", + "circumflex","tilde","macron","breve","dotaccent","ring","cedilla", + "hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron", + "Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn", + "thorn","minus","multiply","onesuperior","twosuperior","threesuperior", + "onehalf","onequarter","threequarters","franc","Gbreve","gbreve", + "Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron", + "dcroat", } local weights={ - [100]="thin", - [200]="extralight", - [300]="light", - [400]="normal", - [500]="medium", - [600]="semibold", - [700]="bold", - [800]="extrabold", - [900]="black", + [100]="thin", + [200]="extralight", + [300]="light", + [400]="normal", + [500]="medium", + [600]="semibold", + [700]="bold", + [800]="extrabold", + [900]="black", } local widths={ - [1]="ultracondensed", - [2]="extracondensed", - [3]="condensed", - [4]="semicondensed", - [5]="normal", - [6]="semiexpanded", - [7]="expanded", - [8]="extraexpanded", - [9]="ultraexpanded", + [1]="ultracondensed", + [2]="extracondensed", + [3]="condensed", + [4]="semicondensed", + [5]="normal", + [6]="semiexpanded", + [7]="expanded", + [8]="extraexpanded", + [9]="ultraexpanded", } setmetatableindex(weights,function(t,k) - local r=floor((k+50)/100)*100 - local v=(r>900 and "black") or rawget(t,r) or "normal" - return v + local r=floor((k+50)/100)*100 + local v=(r>900 and "black") or rawget(t,r) or "normal" + return v end) setmetatableindex(widths,function(t,k) - return "normal" + return "normal" end) local panoseweights={ - [ 0]="normal", - [ 1]="normal", - [ 2]="verylight", - [ 3]="light", - [ 4]="thin", - [ 5]="book", - [ 6]="medium", - [ 7]="demi", - [ 8]="bold", - [ 9]="heavy", - [10]="black", + [ 0]="normal", + [ 1]="normal", + [ 2]="verylight", + [ 3]="light", + [ 4]="thin", + [ 5]="book", + [ 6]="medium", + [ 7]="demi", + [ 8]="bold", + [ 9]="heavy", + [10]="black", } local panosewidths={ - [ 0]="normal", - [ 1]="normal", - [ 2]="normal", - [ 3]="normal", - [ 4]="normal", - [ 5]="expanded", - [ 6]="condensed", - [ 7]="veryexpanded", - [ 8]="verycondensed", - [ 9]="monospaced", + [ 0]="normal", + [ 1]="normal", + [ 2]="normal", + [ 3]="normal", + [ 4]="normal", + [ 5]="expanded", + [ 6]="condensed", + [ 7]="veryexpanded", + [ 8]="verycondensed", + [ 9]="monospaced", } local helpers={} readers.helpers=helpers local function gotodatatable(f,fontdata,tag,criterium) - if criterium and f then - local datatable=fontdata.tables[tag] - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - return tableoffset - end + if criterium and f then + local tables=fontdata.tables + if tables then + local datatable=tables[tag] + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + return tableoffset + end + else + report("no tables") end + end end local function reportskippedtable(f,fontdata,tag,criterium) - if criterium and f then - local datatable=fontdata.tables[tag] - if datatable then - report("loading of table %a skipped",tag) - end + if criterium and f then + local tables=fontdata.tables + if tables then + local datatable=tables[tag] + if datatable then + report("loading of table %a skipped",tag) + end + else + report("no tables") end + end end local function setvariabledata(fontdata,tag,data) - local variabledata=fontdata.variabledata - if variabledata then - variabledata[tag]=data - else - fontdata.variabledata={ [tag]=data } - end + local variabledata=fontdata.variabledata + if variabledata then + variabledata[tag]=data + else + fontdata.variabledata={ [tag]=data } + end end helpers.gotodatatable=gotodatatable helpers.setvariabledata=setvariabledata helpers.reportskippedtable=reportskippedtable local platformnames={ - postscriptname=true, - fullname=true, - family=true, - subfamily=true, - typographicfamily=true, - typographicsubfamily=true, - compatiblefullname=true, + postscriptname=true, + fullname=true, + family=true, + subfamily=true, + typographicfamily=true, + typographicsubfamily=true, + compatiblefullname=true, +} +local platformextras={ + uniqueid=true, + version=true, + copyright=true, + license=true, + licenseurl=true, + manufacturer=true, + vendorurl=true, } function readers.name(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"name",true) - if tableoffset then - local format=readushort(f) - local nofnames=readushort(f) - local offset=readushort(f) - local start=tableoffset+offset - local namelists={ - unicode={}, - windows={}, - macintosh={}, - } - for i=1,nofnames do - local platform=platforms[readushort(f)] - if platform then - local namelist=namelists[platform] - if namelist then - local encoding=readushort(f) - local language=readushort(f) - local encodings=encodings[platform] - local languages=languages[platform] - if encodings and languages then - local encoding=encodings[encoding] - local language=languages[language] - if encoding and language then - local index=readushort(f) - local name=reservednames[index] - namelist[#namelist+1]={ - platform=platform, - encoding=encoding, - language=language, - name=name, - index=index, - length=readushort(f), - offset=start+readushort(f), - } - else - skipshort(f,3) - end - else - skipshort(f,3) - end - else - skipshort(f,5) - end + local tableoffset=gotodatatable(f,fontdata,"name",true) + if tableoffset then + local format=readushort(f) + local nofnames=readushort(f) + local offset=readushort(f) + local start=tableoffset+offset + local namelists={ + unicode={}, + windows={}, + macintosh={}, + } + for i=1,nofnames do + local platform=platforms[readushort(f)] + if platform then + local namelist=namelists[platform] + if namelist then + local encoding=readushort(f) + local language=readushort(f) + local encodings=encodings[platform] + local languages=languages[platform] + if encodings and languages then + local encoding=encodings[encoding] + local language=languages[language] + if encoding and language then + local index=readushort(f) + local name=reservednames[index] + namelist[#namelist+1]={ + platform=platform, + encoding=encoding, + language=language, + name=name, + index=index, + length=readushort(f), + offset=start+readushort(f), + } else - skipshort(f,5) - end - end - local names={} - local done={} - local extras={} - local function filter(platform,e,l) - local namelist=namelists[platform] - for i=1,#namelist do - local name=namelist[i] - local nametag=name.name - local index=name.index - if not done[nametag or i] then - local encoding=name.encoding - local language=name.language - if (not e or encoding==e) and (not l or language==l) then - setposition(f,name.offset) - local content=readstring(f,name.length) - local decoder=decoders[platform] - if decoder then - decoder=decoder[encoding] - end - if decoder then - content=decoder(content) - end - if nametag then - names[nametag]={ - content=content, - platform=platform, - encoding=encoding, - language=language, - } - end - extras[index]=content - done[nametag or i]=true - end - end + skipshort(f,3) end + else + skipshort(f,3) + end + else + skipshort(f,5) end - filter("windows","unicode bmp","english - united states") - filter("macintosh","roman","english") - filter("windows") - filter("macintosh") - filter("unicode") - fontdata.names=names - fontdata.extras=extras - if specification.platformnames then - local collected={} - for platform,namelist in next,namelists do - local filtered=false - for i=1,#namelist do - local entry=namelist[i] - local name=entry.name - if platformnames[name] then - setposition(f,entry.offset) - local content=readstring(f,entry.length) - local encoding=entry.encoding - local decoder=decoders[platform] - if decoder then - decoder=decoder[encoding] - end - if decoder then - content=decoder(content) - end - if filtered then - filtered[name]=content - else - filtered={ [name]=content } - end - end - end - if filtered then - collected[platform]=filtered - end + else + skipshort(f,5) + end + end + local names={} + local done={} + local extras={} + local function decoded(platform,encoding,content) + local decoder=decoders[platform] + if decoder then + decoder=decoder[encoding] + end + if decoder then + return decoder(content) + else + return content + end + end + local function filter(platform,e,l) + local namelist=namelists[platform] + for i=1,#namelist do + local name=namelist[i] + local nametag=name.name + local index=name.index + if not done[nametag or i] then + local encoding=name.encoding + local language=name.language + if (not e or encoding==e) and (not l or language==l) then + setposition(f,name.offset) + local content=decoded(platform,encoding,readstring(f,name.length)) + if nametag then + names[nametag]={ + content=content, + platform=platform, + encoding=encoding, + language=language, + } + end + extras[index]=content + done[nametag or i]=true + end + end + end + end + filter("windows","unicode bmp","english - united states") + filter("macintosh","roman","english") + filter("windows") + filter("macintosh") + filter("unicode") + fontdata.names=names + fontdata.extras=extras + if specification.platformnames then + local collected={} + local platformextras=specification.platformextras and platformextras + for platform,namelist in next,namelists do + local filtered=false + for i=1,#namelist do + local entry=namelist[i] + local name=entry.name + if platformnames[name] or (platformextras and platformextras[name]) then + setposition(f,entry.offset) + local content=decoded(platform,entry.encoding,readstring(f,entry.length)) + if filtered then + filtered[name]=content + else + filtered={ [name]=content } end - fontdata.platformnames=collected + end end - else - fontdata.names={} + if filtered then + collected[platform]=filtered + end + end + fontdata.platformnames=collected end + else + fontdata.names={} + end end local validutf=lpeg.patterns.validutf8 local function getname(fontdata,key) - local names=fontdata.names - if names then - local value=names[key] - if value then - local content=value.content - return lpegmatch(validutf,content) and content or nil - end + local names=fontdata.names + if names then + local value=names[key] + if value then + local content=value.content + return lpegmatch(validutf,content) and content or nil end + end end readers["os/2"]=function(f,fontdata) - local tableoffset=gotodatatable(f,fontdata,"os/2",true) - if tableoffset then - local version=readushort(f) - local windowsmetrics={ - version=version, - averagewidth=readshort(f), - weightclass=readushort(f), - widthclass=readushort(f), - fstype=readushort(f), - subscriptxsize=readshort(f), - subscriptysize=readshort(f), - subscriptxoffset=readshort(f), - subscriptyoffset=readshort(f), - superscriptxsize=readshort(f), - superscriptysize=readshort(f), - superscriptxoffset=readshort(f), - superscriptyoffset=readshort(f), - strikeoutsize=readshort(f), - strikeoutpos=readshort(f), - familyclass=readshort(f), - panose={ readbytes(f,10) }, - unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) }, - vendor=readstring(f,4), - fsselection=readushort(f), - firstcharindex=readushort(f), - lastcharindex=readushort(f), - typoascender=readshort(f), - typodescender=readshort(f), - typolinegap=readshort(f), - winascent=readushort(f), - windescent=readushort(f), - } - if version>=1 then - windowsmetrics.codepageranges={ readulong(f),readulong(f) } - end - if version>=3 then - windowsmetrics.xheight=readshort(f) - windowsmetrics.capheight=readshort(f) - windowsmetrics.defaultchar=readushort(f) - windowsmetrics.breakchar=readushort(f) - end - windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass] - windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass] - windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]] - windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]] - fontdata.windowsmetrics=windowsmetrics - else - fontdata.windowsmetrics={} - end + local tableoffset=gotodatatable(f,fontdata,"os/2",true) + if tableoffset then + local version=readushort(f) + local windowsmetrics={ + version=version, + averagewidth=readshort(f), + weightclass=readushort(f), + widthclass=readushort(f), + fstype=readushort(f), + subscriptxsize=readshort(f), + subscriptysize=readshort(f), + subscriptxoffset=readshort(f), + subscriptyoffset=readshort(f), + superscriptxsize=readshort(f), + superscriptysize=readshort(f), + superscriptxoffset=readshort(f), + superscriptyoffset=readshort(f), + strikeoutsize=readshort(f), + strikeoutpos=readshort(f), + familyclass=readshort(f), + panose={ readbytes(f,10) }, + unicoderanges={ readulong(f),readulong(f),readulong(f),readulong(f) }, + vendor=readstring(f,4), + fsselection=readushort(f), + firstcharindex=readushort(f), + lastcharindex=readushort(f), + typoascender=readshort(f), + typodescender=readshort(f), + typolinegap=readshort(f), + winascent=readushort(f), + windescent=readushort(f), + } + if version>=1 then + windowsmetrics.codepageranges={ readulong(f),readulong(f) } + end + if version>=2 then + windowsmetrics.xheight=readshort(f) + windowsmetrics.capheight=readshort(f) + windowsmetrics.defaultchar=readushort(f) + windowsmetrics.breakchar=readushort(f) + end + windowsmetrics.weight=windowsmetrics.weightclass and weights[windowsmetrics.weightclass] + windowsmetrics.width=windowsmetrics.widthclass and widths [windowsmetrics.widthclass] + windowsmetrics.panoseweight=panoseweights[windowsmetrics.panose[3]] + windowsmetrics.panosewidth=panosewidths [windowsmetrics.panose[4]] + fontdata.windowsmetrics=windowsmetrics + else + fontdata.windowsmetrics={} + end end readers.head=function(f,fontdata) - local tableoffset=gotodatatable(f,fontdata,"head",true) - if tableoffset then - local fontheader={ - version=readfixed(f), - revision=readfixed(f), - checksum=readulong(f), - magic=readulong(f), - flags=readushort(f), - units=readushort(f), - created=readlongdatetime(f), - modified=readlongdatetime(f), - xmin=readshort(f), - ymin=readshort(f), - xmax=readshort(f), - ymax=readshort(f), - macstyle=readushort(f), - smallpixels=readushort(f), - directionhint=readshort(f), - indextolocformat=readshort(f), - glyphformat=readshort(f), - } - fontdata.fontheader=fontheader - else - fontdata.fontheader={} - end - fontdata.nofglyphs=0 + local tableoffset=gotodatatable(f,fontdata,"head",true) + if tableoffset then + local version=readulong(f) + local fontversion=readulong(f) + local fontheader={ + version=version, + fontversion=number.to16dot16(fontversion), + fontversionnumber=fontversion, + checksum=readushort(f)*0x10000+readushort(f), + magic=readulong(f), + flags=readushort(f), + units=readushort(f), + created=readlongdatetime(f), + modified=readlongdatetime(f), + xmin=readshort(f), + ymin=readshort(f), + xmax=readshort(f), + ymax=readshort(f), + macstyle=readushort(f), + smallpixels=readushort(f), + directionhint=readshort(f), + indextolocformat=readshort(f), + glyphformat=readshort(f), + } + fontdata.fontheader=fontheader + else + fontdata.fontheader={} + end + fontdata.nofglyphs=0 end readers.hhea=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) - if tableoffset then - fontdata.horizontalheader={ - version=readfixed(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvancewidth=readufword(f), - minleftsidebearing=readfword(f), - minrightsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofmetrics=readushort(f), - } - else - fontdata.horizontalheader={ - nofmetrics=0, - } - end + local tableoffset=gotodatatable(f,fontdata,"hhea",specification.details) + if tableoffset then + fontdata.horizontalheader={ + version=readulong(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvancewidth=readufword(f), + minleftsidebearing=readfword(f), + minrightsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.horizontalheader={ + nofmetrics=0, + } + end end readers.vhea=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) - if tableoffset then - fontdata.verticalheader={ - version=readfixed(f), - ascender=readfword(f), - descender=readfword(f), - linegap=readfword(f), - maxadvanceheight=readufword(f), - mintopsidebearing=readfword(f), - minbottomsidebearing=readfword(f), - maxextent=readfword(f), - caretsloperise=readshort(f), - caretsloperun=readshort(f), - caretoffset=readshort(f), - reserved_1=readshort(f), - reserved_2=readshort(f), - reserved_3=readshort(f), - reserved_4=readshort(f), - metricdataformat=readshort(f), - nofmetrics=readushort(f), - } - else - fontdata.verticalheader={ - nofmetrics=0, - } - end + local tableoffset=gotodatatable(f,fontdata,"vhea",specification.details) + if tableoffset then + fontdata.verticalheader={ + version=readulong(f), + ascender=readfword(f), + descender=readfword(f), + linegap=readfword(f), + maxadvanceheight=readufword(f), + mintopsidebearing=readfword(f), + minbottomsidebearing=readfword(f), + maxextent=readfword(f), + caretsloperise=readshort(f), + caretsloperun=readshort(f), + caretoffset=readshort(f), + reserved_1=readshort(f), + reserved_2=readshort(f), + reserved_3=readshort(f), + reserved_4=readshort(f), + metricdataformat=readshort(f), + nofmetrics=readushort(f), + } + else + fontdata.verticalheader={ + nofmetrics=0, + } + end end readers.maxp=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) - if tableoffset then - local version=readfixed(f) - local nofglyphs=readushort(f) - fontdata.nofglyphs=nofglyphs - if version==0.5 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - } - elseif version==1.0 then - fontdata.maximumprofile={ - version=version, - nofglyphs=nofglyphs, - points=readushort(f), - contours=readushort(f), - compositepoints=readushort(f), - compositecontours=readushort(f), - zones=readushort(f), - twilightpoints=readushort(f), - storage=readushort(f), - functiondefs=readushort(f), - instructiondefs=readushort(f), - stackelements=readushort(f), - sizeofinstructions=readushort(f), - componentelements=readushort(f), - componentdepth=readushort(f), - } - else - fontdata.maximumprofile={ - version=version, - nofglyphs=0, - } - end + local tableoffset=gotodatatable(f,fontdata,"maxp",specification.details) + if tableoffset then + local version=readulong(f) + local nofglyphs=readushort(f) + fontdata.nofglyphs=nofglyphs + if version==0x00005000 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + } + elseif version==0x00010000 then + fontdata.maximumprofile={ + version=version, + nofglyphs=nofglyphs, + points=readushort(f), + contours=readushort(f), + compositepoints=readushort(f), + compositecontours=readushort(f), + zones=readushort(f), + twilightpoints=readushort(f), + storage=readushort(f), + functiondefs=readushort(f), + instructiondefs=readushort(f), + stackelements=readushort(f), + sizeofinstructions=readushort(f), + componentelements=readushort(f), + componentdepth=readushort(f), + } + else + fontdata.maximumprofile={ + version=version, + nofglyphs=0, + } end + end end readers.hmtx=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) - if tableoffset then - local horizontalheader=fontdata.horizontalheader - local nofmetrics=horizontalheader.nofmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local width=0 - local leftsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - width=readshort(f) - leftsidebearing=readshort(f) - if width~=0 then - glyph.width=width - end - end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if width~=0 then - glyph.width=width - end - end - end + local tableoffset=gotodatatable(f,fontdata,"hmtx",specification.glyphs) + if tableoffset then + local horizontalheader=fontdata.horizontalheader + local nofmetrics=horizontalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local width=0 + local leftsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + width=readshort(f) + leftsidebearing=readshort(f) + if width~=0 then + glyph.width=width + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if width~=0 then + glyph.width=width + end + end + end end readers.vmtx=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) - if tableoffset then - local verticalheader=fontdata.verticalheader - local nofmetrics=verticalheader.nofmetrics - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local vheight=0 - local vdefault=verticalheader.ascender+verticalheader.descender - local topsidebearing=0 - for i=0,nofmetrics-1 do - local glyph=glyphs[i] - vheight=readshort(f) - topsidebearing=readshort(f) - if vheight~=0 and vheight~=vdefault then - glyph.vheight=vheight - end - end - for i=nofmetrics,nofglyphs-1 do - local glyph=glyphs[i] - if vheight~=0 and vheight~=vdefault then - glyph.vheight=vheight - end - end - end + local tableoffset=gotodatatable(f,fontdata,"vmtx",specification.glyphs) + if tableoffset then + local verticalheader=fontdata.verticalheader + local nofmetrics=verticalheader.nofmetrics + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local vheight=0 + local vdefault=verticalheader.ascender+verticalheader.descender + local topsidebearing=0 + for i=0,nofmetrics-1 do + local glyph=glyphs[i] + vheight=readshort(f) + topsidebearing=readshort(f) + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight + end + end + for i=nofmetrics,nofglyphs-1 do + local glyph=glyphs[i] + if vheight~=0 and vheight~=vdefault then + glyph.vheight=vheight + end + end + end end readers.vorg=function(f,fontdata,specification) - reportskippedtable(f,fontdata,"vorg",specification.glyphs) + reportskippedtable(f,fontdata,"vorg",specification.glyphs) end readers.post=function(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"post",true) - if tableoffset then - local version=readfixed(f) - fontdata.postscript={ - version=version, - italicangle=round(1000*readfixed(f))/1000, - underlineposition=readfword(f), - underlinethickness=readfword(f), - monospaced=readulong(f), - minmemtype42=readulong(f), - maxmemtype42=readulong(f), - minmemtype1=readulong(f), - maxmemtype1=readulong(f), - } - if not specification.glyphs then - elseif version==1.0 then - for index=0,#standardromanencoding do - glyphs[index].name=standardromanencoding[index] - end - elseif version==2.0 then - local glyphs=fontdata.glyphs - local nofglyphs=readushort(f) - local indices={} - local names={} - local maxnames=0 - for i=0,nofglyphs-1 do - local nameindex=readushort(f) - if nameindex>=258 then - maxnames=maxnames+1 - nameindex=nameindex-257 - indices[nameindex]=i - else - glyphs[i].name=standardromanencoding[nameindex] - end - end - for i=1,maxnames do - local mapping=indices[i] - if not mapping then - report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") - break - else - local length=readbyte(f) - if length>0 then - glyphs[mapping].name=readstring(f,length) - else - report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow") - break - end - end - end - elseif version==2.5 then - elseif version==3.0 then + local tableoffset=gotodatatable(f,fontdata,"post",true) + if tableoffset then + local version=readulong(f) + fontdata.postscript={ + version=version, + italicangle=round(1000*readfixed(f))/1000, + underlineposition=readfword(f), + underlinethickness=readfword(f), + monospaced=readulong(f), + minmemtype42=readulong(f), + maxmemtype42=readulong(f), + minmemtype1=readulong(f), + maxmemtype1=readulong(f), + } + if not specification.glyphs then + elseif version==0x00010000 then + for index=0,#standardromanencoding do + glyphs[index].name=standardromanencoding[index] + end + elseif version==0x00020000 then + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local indices={} + local names={} + local maxnames=0 + for i=0,nofglyphs-1 do + local nameindex=readushort(f) + if nameindex>=258 then + maxnames=maxnames+1 + nameindex=nameindex-257 + indices[nameindex]=i + else + glyphs[i].name=standardromanencoding[nameindex] + end + end + for i=1,maxnames do + local mapping=indices[i] + if not mapping then + report("quit post name fetching at %a of %a: %s",i,maxnames,"no index") + break + else + local length=readbyte(f) + if length>0 then + glyphs[mapping].name=readstring(f,length) + else + report("quit post name fetching at %a of %a: %s",i,maxnames,"overflow") + break + end end - else - fontdata.postscript={} + end end + else + fontdata.postscript={} + end end readers.cff=function(f,fontdata,specification) - reportskippedtable(f,fontdata,"cff",specification.glyphs) + reportskippedtable(f,fontdata,"cff",specification.glyphs) end local formatreaders={} local duplicatestoo=true local sequence={ - { 3,1,4 }, - { 3,10,12 }, - { 0,3,4 }, - { 0,1,4 }, - { 0,0,6 }, - { 3,0,6 }, - { 0,5,14 }, + { 3,1,4 }, + { 3,10,12 }, + { 0,3,4 }, + { 0,1,4 }, + { 0,0,6 }, + { 3,0,6 }, + { 0,5,14 }, { 0,4,12 }, - { 3,10,13 }, + { 3,10,13 }, } local supported={} for i=1,#sequence do - local si=sequence[i] - local sp,se,sf=si[1],si[2],si[3] - local p=supported[sp] - if not p then - p={} - supported[sp]=p - end - local e=p[se] - if not e then - e={} - p[se]=e - end - e[sf]=true + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + local p=supported[sp] + if not p then + p={} + supported[sp]=p + end + local e=p[se] + if not e then + e={} + p[se]=e + end + e[sf]=true end formatreaders[4]=function(f,fontdata,offset) - setposition(f,offset+2) - local length=readushort(f) - local language=readushort(f) - local nofsegments=readushort(f)/2 - skipshort(f,3) - local endchars={} - local startchars={} - local deltas={} - local offsets={} - local indices={} - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofdone=0 - for i=1,nofsegments do - endchars[i]=readushort(f) - end - local reserved=readushort(f) - for i=1,nofsegments do - startchars[i]=readushort(f) - end - for i=1,nofsegments do - deltas[i]=readshort(f) - end - for i=1,nofsegments do - offsets[i]=readushort(f) - end - local size=(length-2*2-5*2-4*2*nofsegments)/2 - for i=1,size-1 do - indices[i]=readushort(f) - end - for segment=1,nofsegments do - local startchar=startchars[segment] - local endchar=endchars[segment] - local offset=offsets[segment] - local delta=deltas[segment] - if startchar==0xFFFF and endchar==0xFFFF then - elseif startchar==0xFFFF and offset==0 then - elseif offset==0xFFFF then - elseif offset==0 then - if trace_cmap_detail then - report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) - end - for unicode=startchar,endchar do - local index=(unicode+delta)%65536 - if index and index>0 then - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - if duplicatestoo then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - else - report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name) - end - end - if not mapping[index] then - mapping[index]=unicode - end - end + setposition(f,offset+2) + local length=readushort(f) + local language=readushort(f) + local nofsegments=readushort(f)/2 + skipshort(f,3) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofdone=0 + local endchars=readcardinaltable(f,nofsegments,ushort) + local reserved=readushort(f) + local startchars=readcardinaltable(f,nofsegments,ushort) + local deltas=readcardinaltable(f,nofsegments,ushort) + local offsets=readcardinaltable(f,nofsegments,ushort) + local size=(length-2*2-5*2-4*2*nofsegments)/2 + local indices=readcardinaltable(f,size-1,ushort) + for segment=1,nofsegments do + local startchar=startchars[segment] + local endchar=endchars[segment] + local offset=offsets[segment] + local delta=deltas[segment] + if startchar==0xFFFF and endchar==0xFFFF then + elseif startchar==0xFFFF and offset==0 then + elseif offset==0xFFFF then + elseif offset==0 then + if trace_cmap_detail then + report("format 4.%i segment %2i from %C upto %C at index %H",1,segment,startchar,endchar,(startchar+delta)%65536) + end + for unicode=startchar,endchar do + local index=(unicode+delta)%65536 + if index and index>0 then + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + if duplicatestoo then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } end + else + report("duplicate case 1: %C %04i %s",unicode,index,glyphs[index].name) + end end - else - local shift=(segment-nofsegments+offset/2)-startchar - if trace_cmap_detail then - report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) - end - for unicode=startchar,endchar do - local slot=shift+unicode - local index=indices[slot] - if index and index>0 then - index=(index+delta)%65536 - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - if duplicatestoo then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - else - report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name) - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - end + if not mapping[index] then + mapping[index]=unicode end + end end - end - return nofdone -end -formatreaders[6]=function(f,fontdata,offset) - setposition(f,offset) - local format=readushort(f) - local length=readushort(f) - local language=readushort(f) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local start=readushort(f) - local count=readushort(f) - local stop=start+count-1 - local nofdone=0 - if trace_cmap_detail then - report("format 6 from %C to %C",2,start,stop) - end - for unicode=start,stop do - local index=readushort(f) - if index>0 then - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - end - if not mapping[index] then - mapping[index]=unicode + end + else + local shift=(segment-nofsegments+offset/2)-startchar + if trace_cmap_detail then + report("format 4.%i segment %2i from %C upto %C at index %H",0,segment,startchar,endchar,(startchar+delta)%65536) + end + for unicode=startchar,endchar do + local slot=shift+unicode + local index=indices[slot] + if index and index>0 then + index=(index+delta)%65536 + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + if duplicatestoo then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } end + else + report("duplicate case 2: %C %04i %s",unicode,index,glyphs[index].name) + end + end + if not mapping[index] then + mapping[index]=unicode end + end end + end end - return nofdone + end + return nofdone +end +formatreaders[6]=function(f,fontdata,offset) + setposition(f,offset) + local format=readushort(f) + local length=readushort(f) + local language=readushort(f) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local start=readushort(f) + local count=readushort(f) + local stop=start+count-1 + local nofdone=0 + if trace_cmap_detail then + report("format 6 from %C to %C",2,start,stop) + end + for unicode=start,stop do + local index=readushort(f) + if index>0 then + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + end + if not mapping[index] then + mapping[index]=unicode + end + end + end + end + return nofdone end formatreaders[12]=function(f,fontdata,offset) - setposition(f,offset+2+2+4+4) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofgroups=readulong(f) - local nofdone=0 - for i=1,nofgroups do - local first=readulong(f) - local last=readulong(f) - local index=readulong(f) - if trace_cmap_detail then - report("format 12 from %C to %C starts at index %i",first,last,index) - end - for unicode=first,last do - local glyph=glyphs[index] - if glyph then - local gu=glyph.unicode - if not gu then - glyph.unicode=unicode - nofdone=nofdone+1 - elseif gu~=unicode then - local d=duplicates[gu] - if d then - d[unicode]=true - else - duplicates[gu]={ [unicode]=true } - end - end - if not mapping[index] then - mapping[index]=unicode - end - end - index=index+1 + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if trace_cmap_detail then + report("format 12 from %C to %C starts at index %i",first,last,index) + end + for unicode=first,last do + local glyph=glyphs[index] + if glyph then + local gu=glyph.unicode + if not gu then + glyph.unicode=unicode + nofdone=nofdone+1 + elseif gu~=unicode then + local d=duplicates[gu] + if d then + d[unicode]=true + else + duplicates[gu]={ [unicode]=true } + end end + if not mapping[index] then + mapping[index]=unicode + end + end + index=index+1 end - return nofdone + end + return nofdone end formatreaders[13]=function(f,fontdata,offset) - setposition(f,offset+2+2+4+4) - local mapping=fontdata.mapping - local glyphs=fontdata.glyphs - local duplicates=fontdata.duplicates - local nofgroups=readulong(f) - local nofdone=0 - for i=1,nofgroups do - local first=readulong(f) - local last=readulong(f) - local index=readulong(f) - if first=privateoffset then - local limit=privateoffset-1 - report("format 13 from %C to %C pruned to %C",first,last,limit) - last=limit - end - for unicode=first,last do - list[unicode]=true - end - nofdone=nofdone+last-first+1 - else - report("format 13 from %C to %C ignored",first,last) - end + setposition(f,offset+2+2+4+4) + local mapping=fontdata.mapping + local glyphs=fontdata.glyphs + local duplicates=fontdata.duplicates + local nofgroups=readulong(f) + local nofdone=0 + for i=1,nofgroups do + local first=readulong(f) + local last=readulong(f) + local index=readulong(f) + if first=privateoffset then + local limit=privateoffset-1 + report("format 13 from %C to %C pruned to %C",first,last,limit) + last=limit + end + for unicode=first,last do + list[unicode]=true + end + nofdone=nofdone+last-first+1 + else + report("format 13 from %C to %C ignored",first,last) end - return nofdone + end + return nofdone end formatreaders[14]=function(f,fontdata,offset) - if offset and offset~=0 then - setposition(f,offset) - local format=readushort(f) - local length=readulong(f) - local nofrecords=readulong(f) - local records={} - local variants={} - local nofdone=0 - fontdata.variants=variants - for i=1,nofrecords do - records[i]={ - selector=readuint(f), - default=readulong(f), - other=readulong(f), - } - end - for i=1,nofrecords do - local record=records[i] - local selector=record.selector - local default=record.default - local other=record.other - local other=record.other - if other~=0 then - setposition(f,offset+other) - local mapping={} - local count=readulong(f) - for i=1,count do - mapping[readuint(f)]=readushort(f) - end - nofdone=nofdone+count - variants[selector]=mapping - end - end - return nofdone - else - return 0 + if offset and offset~=0 then + setposition(f,offset) + local format=readushort(f) + local length=readulong(f) + local nofrecords=readulong(f) + local records={} + local variants={} + local nofdone=0 + fontdata.variants=variants + for i=1,nofrecords do + records[i]={ + selector=readuint(f), + default=readulong(f), + other=readulong(f), + } + end + for i=1,nofrecords do + local record=records[i] + local selector=record.selector + local default=record.default + local other=record.other + local other=record.other + if other~=0 then + setposition(f,offset+other) + local mapping={} + local count=readulong(f) + for i=1,count do + mapping[readuint(f)]=readushort(f) + end + nofdone=nofdone+count + variants[selector]=mapping + end end + return nofdone + else + return 0 + end end local function checkcmap(f,fontdata,records,platform,encoding,format) - local data=records[platform] - if not data then - return 0 - end - data=data[encoding] - if not data then - return 0 - end - data=data[format] - if not data then - return 0 - end - local reader=formatreaders[format] - if not reader then - return 0 - end - local p=platforms[platform] - local e=encodings[p] - local n=reader(f,fontdata,data) or 0 - if trace_cmap then - report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n) - end - return n + local data=records[platform] + if not data then + return 0 + end + data=data[encoding] + if not data then + return 0 + end + data=data[format] + if not data then + return 0 + end + local reader=formatreaders[format] + if not reader then + return 0 + end + local p=platforms[platform] + local e=encodings[p] + local n=reader(f,fontdata,data) or 0 + if trace_cmap then + report("cmap checked: platform %i (%s), encoding %i (%s), format %i, new unicodes %i",platform,p,encoding,e and e[encoding] or "?",format,n) + end + return n end function readers.cmap(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) - if tableoffset then - local version=readushort(f) - local noftables=readushort(f) - local records={} - local unicodecid=false - local variantcid=false - local variants={} - local duplicates=fontdata.duplicates or {} - fontdata.duplicates=duplicates - for i=1,noftables do - local platform=readushort(f) - local encoding=readushort(f) - local offset=readulong(f) - local record=records[platform] - if not record then - records[platform]={ - [encoding]={ - offsets={ offset }, - formats={}, - } - } - else - local subtables=record[encoding] - if not subtables then - record[encoding]={ - offsets={ offset }, - formats={}, - } - else - local offsets=subtables.offsets - offsets[#offsets+1]=offset - end - end + local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + local records={} + local unicodecid=false + local variantcid=false + local variants={} + local duplicates=fontdata.duplicates or {} + fontdata.duplicates=duplicates + for i=1,noftables do + local platform=readushort(f) + local encoding=readushort(f) + local offset=readulong(f) + local record=records[platform] + if not record then + records[platform]={ + [encoding]={ + offsets={ offset }, + formats={}, + } + } + else + local subtables=record[encoding] + if not subtables then + record[encoding]={ + offsets={ offset }, + formats={}, + } + else + local offsets=subtables.offsets + offsets[#offsets+1]=offset + end + end + end + if trace_cmap then + report("found cmaps:") + end + for platform,record in sortedhash(records) do + local p=platforms[platform] + local e=encodings[p] + local sp=supported[platform] + local ps=p or "?" + if trace_cmap then + if sp then + report(" platform %i: %s",platform,ps) + else + report(" platform %i: %s (unsupported)",platform,ps) end + end + for encoding,subtables in sortedhash(record) do + local se=sp and sp[encoding] + local es=e and e[encoding] or "?" if trace_cmap then - report("found cmaps:") - end - for platform,record in sortedhash(records) do - local p=platforms[platform] - local e=encodings[p] - local sp=supported[platform] - local ps=p or "?" - if trace_cmap then - if sp then - report(" platform %i: %s",platform,ps) - else - report(" platform %i: %s (unsupported)",platform,ps) - end - end - for encoding,subtables in sortedhash(record) do - local se=sp and sp[encoding] - local es=e and e[encoding] or "?" - if trace_cmap then - if se then - report(" encoding %i: %s",encoding,es) - else - report(" encoding %i: %s (unsupported)",encoding,es) - end - end - local offsets=subtables.offsets - local formats=subtables.formats - for i=1,#offsets do - local offset=tableoffset+offsets[i] - setposition(f,offset) - formats[readushort(f)]=offset - end - record[encoding]=formats - if trace_cmap then - local list=sortedkeys(formats) - for i=1,#list do - if not (se and se[list[i]]) then - list[i]=list[i].." (unsupported)" - end - end - report(" formats: % t",list) - end - end + if se then + report(" encoding %i: %s",encoding,es) + else + report(" encoding %i: %s (unsupported)",encoding,es) + end end - local ok=false - for i=1,#sequence do - local si=sequence[i] - local sp,se,sf=si[1],si[2],si[3] - if checkcmap(f,fontdata,records,sp,se,sf)>0 then - ok=true - end + local offsets=subtables.offsets + local formats=subtables.formats + for i=1,#offsets do + local offset=tableoffset+offsets[i] + setposition(f,offset) + formats[readushort(f)]=offset end - if not ok then - report("no useable unicode cmap found") + record[encoding]=formats + if trace_cmap then + local list=sortedkeys(formats) + for i=1,#list do + if not (se and se[list[i]]) then + list[i]=list[i].." (unsupported)" + end + end + report(" formats: % t",list) end - fontdata.cidmaps={ - version=version, - noftables=noftables, - records=records, - } - else - fontdata.cidmaps={} + end + end + local ok=false + for i=1,#sequence do + local si=sequence[i] + local sp,se,sf=si[1],si[2],si[3] + if checkcmap(f,fontdata,records,sp,se,sf)>0 then + ok=true + end + end + if not ok then + report("no useable unicode cmap found") end + fontdata.cidmaps={ + version=version, + noftables=noftables, + records=records, + } + else + fontdata.cidmaps={} + end end function readers.loca(f,fontdata,specification) - reportskippedtable(f,fontdata,"loca",specification.glyphs) + reportskippedtable(f,fontdata,"loca",specification.glyphs) end function readers.glyf(f,fontdata,specification) - reportskippedtable(f,fontdata,"glyf",specification.glyphs) + reportskippedtable(f,fontdata,"glyf",specification.glyphs) end function readers.colr(f,fontdata,specification) - reportskippedtable(f,fontdata,"colr",specification.glyphs) + reportskippedtable(f,fontdata,"colr",specification.glyphs) end function readers.cpal(f,fontdata,specification) - reportskippedtable(f,fontdata,"cpal",specification.glyphs) + reportskippedtable(f,fontdata,"cpal",specification.glyphs) end function readers.svg(f,fontdata,specification) - reportskippedtable(f,fontdata,"svg",specification.glyphs) + reportskippedtable(f,fontdata,"svg",specification.glyphs) end function readers.sbix(f,fontdata,specification) - reportskippedtable(f,fontdata,"sbix",specification.glyphs) + reportskippedtable(f,fontdata,"sbix",specification.glyphs) end function readers.cbdt(f,fontdata,specification) - reportskippedtable(f,fontdata,"cbdt",specification.glyphs) + reportskippedtable(f,fontdata,"cbdt",specification.glyphs) end function readers.cblc(f,fontdata,specification) - reportskippedtable(f,fontdata,"cblc",specification.glyphs) + reportskippedtable(f,fontdata,"cblc",specification.glyphs) end function readers.ebdt(f,fontdata,specification) - reportskippedtable(f,fontdata,"ebdt",specification.glyphs) + reportskippedtable(f,fontdata,"ebdt",specification.glyphs) end function readers.ebsc(f,fontdata,specification) - reportskippedtable(f,fontdata,"ebsc",specification.glyphs) + reportskippedtable(f,fontdata,"ebsc",specification.glyphs) end function readers.eblc(f,fontdata,specification) - reportskippedtable(f,fontdata,"eblc",specification.glyphs) + reportskippedtable(f,fontdata,"eblc",specification.glyphs) end function readers.kern(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) - if tableoffset then - local version=readushort(f) - local noftables=readushort(f) - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - local kerns={} - local glyphs=fontdata.glyphs - for i=1,nofpairs do - local left=readushort(f) - local right=readushort(f) - local kern=readfword(f) - local glyph=glyphs[left] - local kerns=glyph.kerns - if kerns then - kerns[right]=kern - else - glyph.kerns={ [right]=kern } - end - end - elseif format==2 then - report("todo: kern classes") - else - report("todo: kerns") - end + local tableoffset=gotodatatable(f,fontdata,"kern",specification.kerns) + if tableoffset then + local version=readushort(f) + local noftables=readushort(f) + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + local kerns={} + local glyphs=fontdata.glyphs + for i=1,nofpairs do + local left=readushort(f) + local right=readushort(f) + local kern=readfword(f) + local glyph=glyphs[left] + local kerns=glyph.kerns + if kerns then + kerns[right]=kern + else + glyph.kerns={ [right]=kern } + end end + elseif format==2 then + report("todo: kern classes") + else + report("todo: kerns") + end end + end end function readers.gdef(f,fontdata,specification) - reportskippedtable(f,fontdata,"gdef",specification.details) + reportskippedtable(f,fontdata,"gdef",specification.details) end function readers.gsub(f,fontdata,specification) - reportskippedtable(f,fontdata,"gsub",specification.details) + reportskippedtable(f,fontdata,"gsub",specification.details) end function readers.gpos(f,fontdata,specification) - reportskippedtable(f,fontdata,"gpos",specification.details) + reportskippedtable(f,fontdata,"gpos",specification.details) end function readers.math(f,fontdata,specification) - reportskippedtable(f,fontdata,"math",specification.details) + reportskippedtable(f,fontdata,"math",specification.details) end local function getinfo(maindata,sub,platformnames,rawfamilynames,metricstoo,instancenames) - local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata - local names=fontdata.names - local info=nil - if names then - local metrics=fontdata.windowsmetrics or {} - local postscript=fontdata.postscript or {} - local fontheader=fontdata.fontheader or {} - local cffinfo=fontdata.cffinfo or {} - local filename=fontdata.filename - local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) - local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) - local fontname=getname(fontdata,"postscriptname") - local fullname=getname(fontdata,"fullname") - local family=getname(fontdata,"family") - local subfamily=getname(fontdata,"subfamily") - local familyname=getname(fontdata,"typographicfamily") - local subfamilyname=getname(fontdata,"typographicsubfamily") - local compatiblename=getname(fontdata,"compatiblefullname") - if rawfamilynames then - else - if not familyname then familyname=family end - if not subfamilyname then subfamilyname=subfamily end - end - if platformnames then - platformnames=fontdata.platformnames - end - if instancenames then - local variabledata=fontdata.variabledata - if variabledata then - local instances=variabledata and variabledata.instances - if instances then - instancenames={} - for i=1,#instances do - instancenames[i]=lower(stripstring(instances[i].subfamily)) - end - else - instancenames=nil - end - else - instancenames=nil - end - end - info={ - subfontindex=fontdata.subfontindex or sub or 0, - version=getname(fontdata,"version"), - fontname=fontname, - fullname=fullname, - family=family, - subfamily=subfamily, - familyname=familyname, - subfamilyname=subfamilyname, - compatiblename=compatiblename, - weight=weight and lower(weight), - width=width and lower(width), - pfmweight=metrics.weightclass or 400, - pfmwidth=metrics.widthclass or 5, - panosewidth=metrics.panosewidth, - panoseweight=metrics.panoseweight, - italicangle=postscript.italicangle or 0, - units=fontheader.units or 0, - designsize=fontdata.designsize, - minsize=fontdata.minsize, - maxsize=fontdata.maxsize, - monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", - averagewidth=metrics.averagewidth, - xheight=metrics.xheight, - capheight=metrics.capheight, - ascender=metrics.typoascender, - descender=metrics.typodescender, - platformnames=platformnames or nil, - instancenames=instancenames or nil, - } - if metricstoo then - local keys={ - "version", - "ascender","descender","linegap", - "maxadvancewidth","maxadvanceheight","maxextent", - "minbottomsidebearing","mintopsidebearing", - } - local h=fontdata.horizontalheader or {} - local v=fontdata.verticalheader or {} - if h then - local th={} - local tv={} - for i=1,#keys do - local key=keys[i] - th[key]=h[key] or 0 - tv[key]=v[key] or 0 - end - info.horizontalmetrics=th - info.verticalmetrics=tv - end - end - elseif n then - info={ - filename=fontdata.filename, - comment="there is no info for subfont "..n, - } + local fontdata=sub and maindata.subfonts and maindata.subfonts[sub] or maindata + local names=fontdata.names + local info=nil + if names then + local metrics=fontdata.windowsmetrics or {} + local postscript=fontdata.postscript or {} + local fontheader=fontdata.fontheader or {} + local cffinfo=fontdata.cffinfo or {} + local filename=fontdata.filename + local weight=getname(fontdata,"weight") or (cffinfo and cffinfo.weight) or (metrics and metrics.weight) + local width=getname(fontdata,"width") or (cffinfo and cffinfo.width ) or (metrics and metrics.width ) + local fontname=getname(fontdata,"postscriptname") + local fullname=getname(fontdata,"fullname") + local family=getname(fontdata,"family") + local subfamily=getname(fontdata,"subfamily") + local familyname=getname(fontdata,"typographicfamily") + local subfamilyname=getname(fontdata,"typographicsubfamily") + local compatiblename=getname(fontdata,"compatiblefullname") + if rawfamilynames then else - info={ - filename=fontdata.filename, - comment="there is no info", - } - end - return info + if not familyname then familyname=family end + if not subfamilyname then subfamilyname=subfamily end + end + if platformnames then + platformnames=fontdata.platformnames + end + if instancenames then + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata and variabledata.instances + if instances then + instancenames={} + for i=1,#instances do + instancenames[i]=lower(stripstring(instances[i].subfamily)) + end + else + instancenames=nil + end + else + instancenames=nil + end + end + info={ + subfontindex=fontdata.subfontindex or sub or 0, + version=getname(fontdata,"version"), + fontname=fontname, + fullname=fullname, + family=family, + subfamily=subfamily, + familyname=familyname, + subfamilyname=subfamilyname, + compatiblename=compatiblename, + weight=weight and lower(weight), + width=width and lower(width), + pfmweight=metrics.weightclass or 400, + pfmwidth=metrics.widthclass or 5, + panosewidth=metrics.panosewidth, + panoseweight=metrics.panoseweight, + italicangle=postscript.italicangle or 0, + units=fontheader.units or 0, + designsize=fontdata.designsize, + minsize=fontdata.minsize, + maxsize=fontdata.maxsize, + boundingbox=fontheader and { fontheader.xmin or 0,fontheader.ymin or 0,fontheader.xmax or 0,fontheader.ymax or 0 } or nil, + monospaced=(tonumber(postscript.monospaced or 0)>0) or metrics.panosewidth=="monospaced", + averagewidth=metrics.averagewidth, + xheight=metrics.xheight, + capheight=metrics.capheight or fontdata.maxy, + ascender=metrics.typoascender, + descender=metrics.typodescender, + platformnames=platformnames or nil, + instancenames=instancenames or nil, + tableoffsets=fontdata.tableoffsets, + } + if metricstoo then + local keys={ + "version", + "ascender","descender","linegap", + "maxadvancewidth","maxadvanceheight","maxextent", + "minbottomsidebearing","mintopsidebearing", + } + local h=fontdata.horizontalheader or {} + local v=fontdata.verticalheader or {} + if h then + local th={} + local tv={} + for i=1,#keys do + local key=keys[i] + th[key]=h[key] or 0 + tv[key]=v[key] or 0 + end + info.horizontalmetrics=th + info.verticalmetrics=tv + end + end + elseif n then + info={ + filename=fontdata.filename, + comment="there is no info for subfont "..n, + } + else + info={ + filename=fontdata.filename, + comment="there is no info", + } + end + return info end local function loadtables(f,specification,offset) - if offset then - setposition(f,offset) - end - local tables={} - local basename=file.basename(specification.filename) - local filesize=specification.filesize - local filetime=specification.filetime - local fontdata={ - filename=basename, - filesize=filesize, - filetime=filetime, - version=readstring(f,4), - noftables=readushort(f), - searchrange=readushort(f), - entryselector=readushort(f), - rangeshift=readushort(f), - tables=tables, - foundtables=false, + if offset then + setposition(f,offset) + end + local tables={} + local basename=file.basename(specification.filename) + local filesize=specification.filesize + local filetime=specification.filetime + local fontdata={ + filename=basename, + filesize=filesize, + filetime=filetime, + version=readstring(f,4), + noftables=readushort(f), + searchrange=readushort(f), + entryselector=readushort(f), + rangeshift=readushort(f), + tables=tables, + foundtables=false, + } + for i=1,fontdata.noftables do + local tag=lower(stripstring(readstring(f,4))) + local checksum=readushort(f)*0x10000+readushort(f) + local offset=readulong(f) + local length=readulong(f) + if offset+length>filesize then + report("bad %a table in file %a",tag,basename) + end + tables[tag]={ + checksum=checksum, + offset=offset, + length=length, } - for i=1,fontdata.noftables do - local tag=lower(stripstring(readstring(f,4))) - local checksum=readulong(f) - local offset=readulong(f) - local length=readulong(f) - if offset+length>filesize then - report("bad %a table in file %a",tag,basename) - end - tables[tag]={ - checksum=checksum, - offset=offset, - length=length, - } - end - fontdata.foundtables=sortedkeys(tables) - if tables.cff or tables.cff2 then - fontdata.format="opentype" - else - fontdata.format="truetype" - end - return fontdata + end + fontdata.foundtables=sortedkeys(tables) + if tables.cff or tables.cff2 then + fontdata.format="opentype" + else + fontdata.format="truetype" + end + return fontdata,tables end local function prepareglyps(fontdata) - local glyphs=setmetatableindex(function(t,k) - local v={ - index=k, - } - t[k]=v - return v - end) - fontdata.glyphs=glyphs - fontdata.mapping={} + local glyphs=setmetatableindex(function(t,k) + local v={ + index=k, + } + t[k]=v + return v + end) + fontdata.glyphs=glyphs + fontdata.mapping={} end local function readtable(tag,f,fontdata,specification,...) - local reader=readers[tag] - if reader then - reader(f,fontdata,specification,...) - end + local reader=readers[tag] + if reader then + reader(f,fontdata,specification,...) + end end local variablefonts_supported=(context and true) or (logs and logs.application and true) or false local function readdata(f,offset,specification) - local fontdata=loadtables(f,specification,offset) - if specification.glyphs then - prepareglyps(fontdata) - end - if not variablefonts_supported then - specification.instance=nil - specification.variable=nil - specification.factors=nil - end - fontdata.temporary={} - readtable("name",f,fontdata,specification) - local askedname=specification.askedname - if askedname then - local fullname=getname(fontdata,"fullname") or "" - local cleanname=gsub(askedname,"[^a-zA-Z0-9]","") - local foundname=gsub(fullname,"[^a-zA-Z0-9]","") - if lower(cleanname)~=lower(foundname) then - return - end - end - readtable("stat",f,fontdata,specification) - readtable("avar",f,fontdata,specification) - readtable("fvar",f,fontdata,specification) - if variablefonts_supported then - local variabledata=fontdata.variabledata - if variabledata then - local instances=variabledata.instances - local axis=variabledata.axis - if axis and (not instances or #instances==0) then - instances={} - variabledata.instances=instances - local function add(n,subfamily,value) - local values={} - for i=1,#axis do - local a=axis[i] - values[i]={ - axis=a.tag, - value=i==n and value or a.default, - } - end - instances[#instances+1]={ - subfamily=subfamily, - values=values, - } - end - for i=1,#axis do - local a=axis[i] - local tag=a.tag - add(i,"default"..tag,a.default) - add(i,"minimum"..tag,a.minimum) - add(i,"maximum"..tag,a.maximum) - end - end + local fontdata,tables=loadtables(f,specification,offset) + if specification.glyphs then + prepareglyps(fontdata) + end + if not variablefonts_supported then + specification.instance=nil + specification.variable=nil + specification.factors=nil + end + fontdata.temporary={} + readtable("name",f,fontdata,specification) + local askedname=specification.askedname + if askedname then + local fullname=getname(fontdata,"fullname") or "" + local cleanname=gsub(askedname,"[^a-zA-Z0-9]","") + local foundname=gsub(fullname,"[^a-zA-Z0-9]","") + if lower(cleanname)~=lower(foundname) then + return + end + end + readtable("stat",f,fontdata,specification) + readtable("avar",f,fontdata,specification) + readtable("fvar",f,fontdata,specification) + if variablefonts_supported then + local variabledata=fontdata.variabledata + if variabledata then + local instances=variabledata.instances + local axis=variabledata.axis + if axis and (not instances or #instances==0) then + instances={} + variabledata.instances=instances + local function add(n,subfamily,value) + local values={} + for i=1,#axis do + local a=axis[i] + values[i]={ + axis=a.tag, + value=i==n and value or a.default, + } + end + instances[#instances+1]={ + subfamily=subfamily, + values=values, + } end - if not specification.factors then - local instance=specification.instance - if type(instance)=="string" then - local factors=helpers.getfactors(fontdata,instance) - if factors then - specification.factors=factors - fontdata.factors=factors - fontdata.instance=instance - report("user instance: %s, factors: % t",instance,factors) - else - report("user instance: %s, bad factors",instance) - end - end - end - if not fontdata.factors then - if fontdata.variabledata then - local factors=helpers.getfactors(fontdata,true) - if factors then - specification.factors=factors - fontdata.factors=factors - end - else - end + for i=1,#axis do + local a=axis[i] + local tag=a.tag + add(i,"default"..tag,a.default) + add(i,"minimum"..tag,a.minimum) + add(i,"maximum"..tag,a.maximum) + end + end + end + if not specification.factors then + local instance=specification.instance + if type(instance)=="string" then + local factors=helpers.getfactors(fontdata,instance) + if factors then + specification.factors=factors + fontdata.factors=factors + fontdata.instance=instance + report("user instance: %s, factors: % t",instance,factors) + else + report("user instance: %s, bad factors",instance) end + end end - readtable("os/2",f,fontdata,specification) - readtable("head",f,fontdata,specification) - readtable("maxp",f,fontdata,specification) - readtable("hhea",f,fontdata,specification) - readtable("vhea",f,fontdata,specification) - readtable("hmtx",f,fontdata,specification) - readtable("vmtx",f,fontdata,specification) - readtable("vorg",f,fontdata,specification) - readtable("post",f,fontdata,specification) - readtable("mvar",f,fontdata,specification) - readtable("hvar",f,fontdata,specification) - readtable("vvar",f,fontdata,specification) - readtable("gdef",f,fontdata,specification) - readtable("cff",f,fontdata,specification) - readtable("cff2",f,fontdata,specification) - readtable("cmap",f,fontdata,specification) - readtable("loca",f,fontdata,specification) - readtable("glyf",f,fontdata,specification) - readtable("colr",f,fontdata,specification) - readtable("cpal",f,fontdata,specification) - readtable("svg",f,fontdata,specification) - readtable("sbix",f,fontdata,specification) - readtable("cbdt",f,fontdata,specification) - readtable("cblc",f,fontdata,specification) - readtable("ebdt",f,fontdata,specification) - readtable("eblc",f,fontdata,specification) - readtable("kern",f,fontdata,specification) - readtable("gsub",f,fontdata,specification) - readtable("gpos",f,fontdata,specification) - readtable("math",f,fontdata,specification) - fontdata.locations=nil - fontdata.tables=nil - fontdata.cidmaps=nil - fontdata.dictionaries=nil - return fontdata + if not fontdata.factors then + if fontdata.variabledata then + local factors=helpers.getfactors(fontdata,true) + if factors then + specification.factors=factors + fontdata.factors=factors + end + else + end + end + end + readtable("os/2",f,fontdata,specification) + readtable("head",f,fontdata,specification) + readtable("maxp",f,fontdata,specification) + readtable("hhea",f,fontdata,specification) + readtable("vhea",f,fontdata,specification) + readtable("hmtx",f,fontdata,specification) + readtable("vmtx",f,fontdata,specification) + readtable("vorg",f,fontdata,specification) + readtable("post",f,fontdata,specification) + readtable("mvar",f,fontdata,specification) + readtable("hvar",f,fontdata,specification) + readtable("vvar",f,fontdata,specification) + readtable("gdef",f,fontdata,specification) + readtable("cff",f,fontdata,specification) + readtable("cff2",f,fontdata,specification) + readtable("cmap",f,fontdata,specification) + readtable("loca",f,fontdata,specification) + readtable("glyf",f,fontdata,specification) + readtable("colr",f,fontdata,specification) + readtable("cpal",f,fontdata,specification) + readtable("svg",f,fontdata,specification) + readtable("sbix",f,fontdata,specification) + readtable("cbdt",f,fontdata,specification) + readtable("cblc",f,fontdata,specification) + readtable("ebdt",f,fontdata,specification) + readtable("eblc",f,fontdata,specification) + readtable("kern",f,fontdata,specification) + readtable("gsub",f,fontdata,specification) + readtable("gpos",f,fontdata,specification) + readtable("math",f,fontdata,specification) + fontdata.locations=nil + fontdata.cidmaps=nil + fontdata.dictionaries=nil + if specification.tableoffsets then + fontdata.tableoffsets=tables + setmetatableindex(tables,{ + version=fontdata.version, + noftables=fontdata.noftables, + searchrange=fontdata.searchrange, + entryselector=fontdata.entryselector, + rangeshift=fontdata.rangeshift, + }) + end + return fontdata end local function loadfontdata(specification) - local filename=specification.filename - local fileattr=lfs.attributes(filename) - local filesize=fileattr and fileattr.size or 0 - local filetime=fileattr and fileattr.modification or 0 - local f=openfile(filename,true) - if not f then - report("unable to open %a",filename) - elseif filesize==0 then - report("empty file %a",filename) - closefile(f) - else - specification.filesize=filesize - specification.filetime=filetime - local version=readstring(f,4) - local fontdata=nil - if version=="OTTO" or version=="true" or version=="\0\1\0\0" then - fontdata=readdata(f,0,specification) - elseif version=="ttcf" then - local subfont=tonumber(specification.subfont) - local offsets={} - local ttcversion=readulong(f) - local nofsubfonts=readulong(f) - for i=1,nofsubfonts do - offsets[i]=readulong(f) - end - if subfont then - if subfont>=1 and subfont<=nofsubfonts then - fontdata=readdata(f,offsets[subfont],specification) - else - report("no subfont %a in file %a",subfont,filename) - end - else - subfont=specification.subfont - if type(subfont)=="string" and subfont~="" then - specification.askedname=subfont - for i=1,nofsubfonts do - fontdata=readdata(f,offsets[i],specification) - if fontdata then - fontdata.subfontindex=i - report("subfont named %a has index %a",subfont,i) - break - end - end - if not fontdata then - report("no subfont named %a",subfont) - end - else - local subfonts={} - fontdata={ - filename=filename, - filesize=filesize, - filetime=filetime, - version=version, - subfonts=subfonts, - ttcversion=ttcversion, - nofsubfonts=nofsubfonts, - } - for i=1,nofsubfonts do - subfonts[i]=readdata(f,offsets[i],specification) - end - end + local filename=specification.filename + local fileattr=lfs.attributes(filename) + local filesize=fileattr and fileattr.size or 0 + local filetime=fileattr and fileattr.modification or 0 + local f=openfile(filename,true) + if not f then + report("unable to open %a",filename) + elseif filesize==0 then + report("empty file %a",filename) + closefile(f) + else + specification.filesize=filesize + specification.filetime=filetime + local version=readstring(f,4) + local fontdata=nil + if version=="OTTO" or version=="true" or version=="\0\1\0\0" then + fontdata=readdata(f,0,specification) + elseif version=="ttcf" then + local subfont=tonumber(specification.subfont) + local ttcversion=readulong(f) + local nofsubfonts=readulong(f) + local offsets=readcardinaltable(f,nofsubfonts,ulong) + if subfont then + if subfont>=1 and subfont<=nofsubfonts then + fontdata=readdata(f,offsets[subfont],specification) + else + report("no subfont %a in file %a",subfont,filename) + end + else + subfont=specification.subfont + if type(subfont)=="string" and subfont~="" then + specification.askedname=subfont + for i=1,nofsubfonts do + fontdata=readdata(f,offsets[i],specification) + if fontdata then + fontdata.subfontindex=i + report("subfont named %a has index %a",subfont,i) + break end + end + if not fontdata then + report("no subfont named %a",subfont) + end else - report("unknown version %a in file %a",version,filename) + local subfonts={} + fontdata={ + filename=filename, + filesize=filesize, + filetime=filetime, + version=version, + subfonts=subfonts, + ttcversion=ttcversion, + nofsubfonts=nofsubfonts, + } + for i=1,nofsubfonts do + subfonts[i]=readdata(f,offsets[i],specification) + end end - closefile(f) - return fontdata or {} + end + else + report("unknown version %a in file %a",version,filename) end + closefile(f) + return fontdata or {} + end end local function loadfont(specification,n,instance) - if type(specification)=="string" then - specification={ - filename=specification, - info=true, - details=true, - glyphs=true, - shapes=true, - kerns=true, - variable=true, - globalkerns=true, - lookups=true, - subfont=n or true, - tounicode=false, - instance=instance - } - end - if specification.shapes or specification.lookups or specification.kerns then - specification.glyphs=true - end - if specification.glyphs then - specification.details=true - end - if specification.details then - specification.info=true - end - if specification.platformnames then - specification.platformnames=true - end - if specification.instance or instance then - specification.variable=true - specification.instance=specification.instance or instance - end - local function message(str) - report("fatal error in file %a: %s\n%s",specification.filename,str,debug.traceback()) - end - local ok,result=xpcall(loadfontdata,message,specification) - if ok then - return result - end + if type(specification)=="string" then + specification={ + filename=specification, + info=true, + details=true, + glyphs=true, + shapes=true, + kerns=true, + variable=true, + globalkerns=true, + lookups=true, + subfont=n or true, + tounicode=false, + instance=instance + } + end + if specification.shapes or specification.lookups or specification.kerns then + specification.glyphs=true + end + if specification.glyphs then + specification.details=true + end + if specification.details then + specification.info=true + end + if specification.platformnames then + specification.platformnames=true + end + if specification.instance or instance then + specification.variable=true + specification.instance=specification.instance or instance + end + local function message(str) + report("fatal error in file %a: %s\n%s",specification.filename,str,debug and debug.traceback()) + end + local ok,result=xpcall(loadfontdata,message,specification) + if ok then + return result + end end function readers.loadshapes(filename,n,instance,streams) - local fontdata=loadfont { - filename=filename, - shapes=true, - streams=streams, - variable=true, - subfont=n, - instance=instance, - } - if fontdata then - for k,v in next,fontdata.glyphs do - v.class=nil - v.index=nil - v.math=nil - end + local fontdata=loadfont { + filename=filename, + shapes=true, + streams=streams, + variable=true, + subfont=n, + instance=instance, + } + if fontdata then + for k,v in next,fontdata.glyphs do + v.class=nil + v.index=nil + v.math=nil end - return fontdata and { - filename=filename, - format=fontdata.format, - glyphs=fontdata.glyphs, - units=fontdata.fontheader.units, - } or { - filename=filename, - format="unknown", - glyphs={}, - units=0, - } + local names=fontdata.names + if names then + for k,v in next,names do + names[k]=fullstrip(v.content) + end + end + end + return fontdata and { + filename=filename, + format=fontdata.format, + glyphs=fontdata.glyphs, + units=fontdata.fontheader.units, + cffinfo=fontdata.cffinfo, + fontheader=fontdata.fontheader, + horizontalheader=fontdata.horizontalheader, + verticalheader=fontdata.verticalheader, + maximumprofile=fontdata.maximumprofile, + names=fontdata.names, + postscript=fontdata.postscript, + } or { + filename=filename, + format="unknown", + glyphs={}, + units=0, + } end function readers.loadfont(filename,n,instance) - local fontdata=loadfont { + local fontdata=loadfont { + filename=filename, + glyphs=true, + shapes=false, + lookups=true, + variable=true, + subfont=n, + instance=instance, + } + if fontdata then + return { + tableversion=tableversion, + creator="context mkiv", + size=fontdata.filesize, + time=fontdata.filetime, + glyphs=fontdata.glyphs, + descriptions=fontdata.descriptions, + format=fontdata.format, + goodies={}, + metadata=getinfo(fontdata,n,false,false,true,true), + properties={ + hasitalics=fontdata.hasitalics or false, + maxcolorclass=fontdata.maxcolorclass, + hascolor=fontdata.hascolor or false, + instance=fontdata.instance, + factors=fontdata.factors, + }, + resources={ filename=filename, - glyphs=true, - shapes=false, - lookups=true, - variable=true, - subfont=n, - instance=instance, + private=privateoffset, + duplicates=fontdata.duplicates or {}, + features=fontdata.features or {}, + sublookups=fontdata.sublookups or {}, + marks=fontdata.marks or {}, + markclasses=fontdata.markclasses or {}, + marksets=fontdata.marksets or {}, + sequences=fontdata.sequences or {}, + variants=fontdata.variants, + version=getname(fontdata,"version"), + cidinfo=fontdata.cidinfo, + mathconstants=fontdata.mathconstants, + colorpalettes=fontdata.colorpalettes, + svgshapes=fontdata.svgshapes, + pngshapes=fontdata.pngshapes, + variabledata=fontdata.variabledata, + foundtables=fontdata.foundtables, + }, } - if fontdata then - return { - tableversion=tableversion, - creator="context mkiv", - size=fontdata.filesize, - time=fontdata.filetime, - glyphs=fontdata.glyphs, - descriptions=fontdata.descriptions, - format=fontdata.format, - goodies={}, - metadata=getinfo(fontdata,n,false,false,true,true), - properties={ - hasitalics=fontdata.hasitalics or false, - maxcolorclass=fontdata.maxcolorclass, - hascolor=fontdata.hascolor or false, - instance=fontdata.instance, - factors=fontdata.factors, - }, - resources={ - filename=filename, - private=privateoffset, - duplicates=fontdata.duplicates or {}, - features=fontdata.features or {}, - sublookups=fontdata.sublookups or {}, - marks=fontdata.marks or {}, - markclasses=fontdata.markclasses or {}, - marksets=fontdata.marksets or {}, - sequences=fontdata.sequences or {}, - variants=fontdata.variants, - version=getname(fontdata,"version"), - cidinfo=fontdata.cidinfo, - mathconstants=fontdata.mathconstants, - colorpalettes=fontdata.colorpalettes, - svgshapes=fontdata.svgshapes, - sbixshapes=fontdata.sbixshapes, - variabledata=fontdata.variabledata, - foundtables=fontdata.foundtables, - }, - } - end + end end function readers.getinfo(filename,specification) - local subfont=nil - local platformnames=false - local rawfamilynames=false - local instancenames=true - if type(specification)=="table" then - subfont=tonumber(specification.subfont) - platformnames=specification.platformnames - rawfamilynames=specification.rawfamilynames + local subfont=nil + local platformnames=false + local rawfamilynames=false + local instancenames=true + local tableoffsets=false + if type(specification)=="table" then + subfont=tonumber(specification.subfont) + platformnames=specification.platformnames + rawfamilynames=specification.rawfamilynames + tableoffsets=specification.tableoffsets + else + subfont=tonumber(specification) + end + local fontdata=loadfont { + filename=filename, + details=true, + platformnames=platformnames, + instancenames=true, + tableoffsets=tableoffsets, + } + if fontdata then + local subfonts=fontdata.subfonts + if not subfonts then + return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) + elseif not subfont then + local info={} + for i=1,#subfonts do + info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) + end + return info + elseif subfont>=1 and subfont<=#subfonts then + return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) else - subfont=tonumber(specification) - end - local fontdata=loadfont { + return { filename=filename, - details=true, - platformnames=platformnames, - instancenames=true, - } - if fontdata then - local subfonts=fontdata.subfonts - if not subfonts then - return getinfo(fontdata,nil,platformnames,rawfamilynames,false,instancenames) - elseif not subfont then - local info={} - for i=1,#subfonts do - info[i]=getinfo(fontdata,i,platformnames,rawfamilynames,false,instancenames) - end - return info - elseif subfont>=1 and subfont<=#subfonts then - return getinfo(fontdata,subfont,platformnames,rawfamilynames,false,instancenames) - else - return { - filename=filename, - comment="there is no subfont "..subfont.." in this file" - } - end - else - return { - filename=filename, - comment="the file cannot be opened for reading", - } + comment="there is no subfont "..subfont.." in this file" + } end + else + return { + filename=filename, + comment="the file cannot be opened for reading", + } + end end function readers.rehash(fontdata,hashmethod) - report("the %a helper is not yet implemented","rehash") + report("the %a helper is not yet implemented","rehash") end function readers.checkhash(fontdata) - report("the %a helper is not yet implemented","checkhash") + report("the %a helper is not yet implemented","checkhash") end function readers.pack(fontdata,hashmethod) - report("the %a helper is not yet implemented","pack") + report("the %a helper is not yet implemented","pack") end function readers.unpack(fontdata) - report("the %a helper is not yet implemented","unpack") + report("the %a helper is not yet implemented","unpack") end function readers.expand(fontdata) - report("the %a helper is not yet implemented","unpack") + report("the %a helper is not yet implemented","unpack") end function readers.compact(fontdata) - report("the %a helper is not yet implemented","compact") + report("the %a helper is not yet implemented","compact") end local extenders={} function readers.registerextender(extender) - extenders[#extenders+1]=extender + extenders[#extenders+1]=extender end function readers.extend(fontdata) - for i=1,#extenders do - local extender=extenders[i] - local name=extender.name or "unknown" - local action=extender.action - if action then - action(fontdata) + for i=1,#extenders do + local extender=extenders[i] + local name=extender.name or "unknown" + local action=extender.action + if action then + action(fontdata) + end + end +end + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-oti']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lower=string.lower +local fonts=fonts +local constructors=fonts.constructors +local otf=constructors.handlers.otf +local otffeatures=constructors.features.otf +local registerotffeature=otffeatures.register +local otftables=otf.tables or {} +otf.tables=otftables +local allocate=utilities.storage.allocate +registerotffeature { + name="features", + description="initialization of feature handler", + default=true, +} +local function setmode(tfmdata,value) + if value then + tfmdata.properties.mode=lower(value) + end +end +otf.modeinitializer=setmode +local function setlanguage(tfmdata,value) + if value then + local cleanvalue=lower(value) + local languages=otftables and otftables.languages + local properties=tfmdata.properties + if not languages then + properties.language=cleanvalue + elseif languages[value] then + properties.language=cleanvalue + else + properties.language="dflt" + end + end +end +local function setscript(tfmdata,value) + if value then + local cleanvalue=lower(value) + local scripts=otftables and otftables.scripts + local properties=tfmdata.properties + if not scripts then + properties.script=cleanvalue + elseif scripts[value] then + properties.script=cleanvalue + else + properties.script="dflt" + end + end +end +registerotffeature { + name="mode", + description="mode", + initializers={ + base=setmode, + node=setmode, + plug=setmode, + } +} +registerotffeature { + name="language", + description="language", + initializers={ + base=setlanguage, + node=setlanguage, + plug=setlanguage, + } +} +registerotffeature { + name="script", + description="script", + initializers={ + base=setscript, + node=setscript, + plug=setscript, + } +} +otftables.featuretypes=allocate { + gpos_single="position", + gpos_pair="position", + gpos_cursive="position", + gpos_mark2base="position", + gpos_mark2ligature="position", + gpos_mark2mark="position", + gpos_context="position", + gpos_contextchain="position", + gsub_single="substitution", + gsub_multiple="substitution", + gsub_alternate="substitution", + gsub_ligature="substitution", + gsub_context="substitution", + gsub_contextchain="substitution", + gsub_reversecontextchain="substitution", + gsub_reversesub="substitution", +} +function otffeatures.checkeddefaultscript(featuretype,autoscript,scripts) + if featuretype=="position" then + local default=scripts.dflt + if default then + if autoscript=="position" or autoscript==true then + return default + else + report_otf("script feature %s not applied, enable default positioning") + end + else + end + elseif featuretype=="substitution" then + local default=scripts.dflt + if default then + if autoscript=="substitution" or autoscript==true then + return default + end + end + end +end +function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) + if featuretype=="position" then + local default=languages.dflt + if default then + if autolanguage=="position" or autolanguage==true then + return default + else + report_otf("language feature %s not applied, enable default positioning") + end + else + end + elseif featuretype=="substitution" then + local default=languages.dflt + if default then + if autolanguage=="substitution" or autolanguage==true then + return default + end + end + end +end + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ["font-ott"]={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", +} +local type,next,tonumber,tostring,rawget,rawset=type,next,tonumber,tostring,rawget,rawset +local gsub,lower,format,match,gmatch,find=string.gsub,string.lower,string.format,string.match,string.gmatch,string.find +local sequenced=table.sequenced +local is_boolean=string.is_boolean +local setmetatableindex=table.setmetatableindex +local setmetatablenewindex=table.setmetatablenewindex +local allocate=utilities.storage.allocate +local fonts=fonts +local otf=fonts.handlers.otf +local otffeatures=otf.features +local tables=otf.tables or {} +otf.tables=tables +local statistics=otf.statistics or {} +otf.statistics=statistics +local scripts=allocate { + ["arab"]="arabic", + ["armi"]="imperial aramaic", + ["armn"]="armenian", + ["avst"]="avestan", + ["bali"]="balinese", + ["bamu"]="bamum", + ["batk"]="batak", + ["beng"]="bengali", + ["bng2"]="bengali variant 2", + ["bopo"]="bopomofo", + ["brah"]="brahmi", + ["brai"]="braille", + ["bugi"]="buginese", + ["buhd"]="buhid", + ["byzm"]="byzantine music", + ["cakm"]="chakma", + ["cans"]="canadian syllabics", + ["cari"]="carian", + ["cham"]="cham", + ["cher"]="cherokee", + ["copt"]="coptic", + ["cprt"]="cypriot syllabary", + ["cyrl"]="cyrillic", + ["deva"]="devanagari", + ["dev2"]="devanagari variant 2", + ["dsrt"]="deseret", + ["egyp"]="egyptian heiroglyphs", + ["ethi"]="ethiopic", + ["geor"]="georgian", + ["glag"]="glagolitic", + ["goth"]="gothic", + ["grek"]="greek", + ["gujr"]="gujarati", + ["gjr2"]="gujarati variant 2", + ["guru"]="gurmukhi", + ["gur2"]="gurmukhi variant 2", + ["hang"]="hangul", + ["hani"]="cjk ideographic", + ["hano"]="hanunoo", + ["hebr"]="hebrew", + ["ital"]="old italic", + ["jamo"]="hangul jamo", + ["java"]="javanese", + ["kali"]="kayah li", + ["kana"]="hiragana and katakana", + ["khar"]="kharosthi", + ["khmr"]="khmer", + ["knda"]="kannada", + ["knd2"]="kannada variant 2", + ["kthi"]="kaithi", + ["lana"]="tai tham", + ["lao" ]="lao", + ["latn"]="latin", + ["lepc"]="lepcha", + ["limb"]="limbu", + ["linb"]="linear b", + ["lisu"]="lisu", + ["lyci"]="lycian", + ["lydi"]="lydian", + ["mand"]="mandaic and mandaean", + ["math"]="mathematical alphanumeric symbols", + ["merc"]="meroitic cursive", + ["mero"]="meroitic hieroglyphs", + ["mlym"]="malayalam", + ["mlm2"]="malayalam variant 2", + ["mong"]="mongolian", + ["mtei"]="meitei Mayek", + ["musc"]="musical symbols", + ["mym2"]="myanmar variant 2", + ["mymr"]="myanmar", + ["nko" ]='n"ko', + ["ogam"]="ogham", + ["olck"]="ol chiki", + ["orkh"]="old turkic and orkhon runic", + ["orya"]="oriya", + ["ory2"]="odia variant 2", + ["osma"]="osmanya", + ["phag"]="phags-pa", + ["phli"]="inscriptional pahlavi", + ["phnx"]="phoenician", + ["prti"]="inscriptional parthian", + ["rjng"]="rejang", + ["runr"]="runic", + ["samr"]="samaritan", + ["sarb"]="old south arabian", + ["saur"]="saurashtra", + ["shaw"]="shavian", + ["shrd"]="sharada", + ["sinh"]="sinhala", + ["sora"]="sora sompeng", + ["sund"]="sundanese", + ["sylo"]="syloti nagri", + ["syrc"]="syriac", + ["tagb"]="tagbanwa", + ["takr"]="takri", + ["tale"]="tai le", + ["talu"]="tai lu", + ["taml"]="tamil", + ["tavt"]="tai viet", + ["telu"]="telugu", + ["tel2"]="telugu variant 2", + ["tfng"]="tifinagh", + ["tglg"]="tagalog", + ["thaa"]="thaana", + ["thai"]="thai", + ["tibt"]="tibetan", + ["tml2"]="tamil variant 2", + ["ugar"]="ugaritic cuneiform", + ["vai" ]="vai", + ["xpeo"]="old persian cuneiform", + ["xsux"]="sumero-akkadian cuneiform", + ["yi" ]="yi", +} +local languages=allocate { + ["aba" ]="abaza", + ["abk" ]="abkhazian", + ["ach" ]="acholi", + ["acr" ]="achi", + ["ady" ]="adyghe", + ["afk" ]="afrikaans", + ["afr" ]="afar", + ["agw" ]="agaw", + ["aio" ]="aiton", + ["aka" ]="akan", + ["als" ]="alsatian", + ["alt" ]="altai", + ["amh" ]="amharic", + ["ang" ]="anglo-saxon", + ["apph"]="phonetic transcription—americanist conventions", + ["ara" ]="arabic", + ["arg" ]="aragonese", + ["ari" ]="aari", + ["ark" ]="rakhine", + ["asm" ]="assamese", + ["ast" ]="asturian", + ["ath" ]="athapaskan", + ["avr" ]="avar", + ["awa" ]="awadhi", + ["aym" ]="aymara", + ["azb" ]="torki", + ["aze" ]="azerbaijani", + ["bad" ]="badaga", + ["bad0"]="banda", + ["bag" ]="baghelkhandi", + ["bal" ]="balkar", + ["ban" ]="balinese", + ["bar" ]="bavarian", + ["bau" ]="baulé", + ["bbc" ]="batak toba", + ["bbr" ]="berber", + ["bch" ]="bench", + ["bcr" ]="bible cree", + ["bdy" ]="bandjalang", + ["bel" ]="belarussian", + ["bem" ]="bemba", + ["ben" ]="bengali", + ["bgc" ]="haryanvi", + ["bgq" ]="bagri", + ["bgr" ]="bulgarian", + ["bhi" ]="bhili", + ["bho" ]="bhojpuri", + ["bik" ]="bikol", + ["bil" ]="bilen", + ["bis" ]="bislama", + ["bjj" ]="kanauji", + ["bkf" ]="blackfoot", + ["bli" ]="baluchi", + ["blk" ]="pa'o karen", + ["bln" ]="balante", + ["blt" ]="balti", + ["bmb" ]="bambara (bamanankan)", + ["bml" ]="bamileke", + ["bos" ]="bosnian", + ["bpy" ]="bishnupriya manipuri", + ["bre" ]="breton", + ["brh" ]="brahui", + ["bri" ]="braj bhasha", + ["brm" ]="burmese", + ["brx" ]="bodo", + ["bsh" ]="bashkir", + ["bti" ]="beti", + ["bts" ]="batak simalungun", + ["bug" ]="bugis", + ["cak" ]="kaqchikel", + ["cat" ]="catalan", + ["cbk" ]="zamboanga chavacano", + ["ceb" ]="cebuano", + ["cgg" ]="chiga", + ["cha" ]="chamorro", + ["che" ]="chechen", + ["chg" ]="chaha gurage", + ["chh" ]="chattisgarhi", + ["chi" ]="chichewa (chewa, nyanja)", + ["chk" ]="chukchi", + ["chk0"]="chuukese", + ["cho" ]="choctaw", + ["chp" ]="chipewyan", + ["chr" ]="cherokee", + ["chu" ]="chuvash", + ["chy" ]="cheyenne", + ["cmr" ]="comorian", + ["cop" ]="coptic", + ["cor" ]="cornish", + ["cos" ]="corsican", + ["cpp" ]="creoles", + ["cre" ]="cree", + ["crr" ]="carrier", + ["crt" ]="crimean tatar", + ["csb" ]="kashubian", + ["csl" ]="church slavonic", + ["csy" ]="czech", + ["ctg" ]="chittagonian", + ["cuk" ]="san blas kuna", + ["dan" ]="danish", + ["dar" ]="dargwa", + ["dax" ]="dayi", + ["dcr" ]="woods cree", + ["deu" ]="german", + ["dgo" ]="dogri", + ["dgr" ]="dogri", + ["dhg" ]="dhangu", + ["dhv" ]="divehi (dhivehi, maldivian)", + ["diq" ]="dimli", + ["div" ]="divehi (dhivehi, maldivian)", + ["djr" ]="zarma", + ["djr0"]="djambarrpuyngu", + ["dng" ]="dangme", + ["dnj" ]="dan", + ["dnk" ]="dinka", + ["dri" ]="dari", + ["duj" ]="dhuwal", + ["dun" ]="dungan", + ["dzn" ]="dzongkha", + ["ebi" ]="ebira", + ["ecr" ]="eastern cree", + ["edo" ]="edo", + ["efi" ]="efik", + ["ell" ]="greek", + ["emk" ]="eastern maninkakan", + ["eng" ]="english", + ["erz" ]="erzya", + ["esp" ]="spanish", + ["esu" ]="central yupik", + ["eti" ]="estonian", + ["euq" ]="basque", + ["evk" ]="evenki", + ["evn" ]="even", + ["ewe" ]="ewe", + ["fan" ]="french antillean", + ["fan0"]=" fang", + ["far" ]="persian", + ["fat" ]="fanti", + ["fin" ]="finnish", + ["fji" ]="fijian", + ["fle" ]="dutch (flemish)", + ["fne" ]="forest nenets", + ["fon" ]="fon", + ["fos" ]="faroese", + ["fra" ]="french", + ["frc" ]="cajun french", + ["fri" ]="frisian", + ["frl" ]="friulian", + ["frp" ]="arpitan", + ["fta" ]="futa", + ["ful" ]="fulah", + ["fuv" ]="nigerian fulfulde", + ["gad" ]="ga", + ["gae" ]="scottish gaelic (gaelic)", + ["gag" ]="gagauz", + ["gal" ]="galician", + ["gar" ]="garshuni", + ["gaw" ]="garhwali", + ["gez" ]="ge'ez", + ["gih" ]="githabul", + ["gil" ]="gilyak", + ["gil0"]="kiribati (gilbertese)", + ["gkp" ]="kpelle (guinea)", + ["glk" ]="gilaki", + ["gmz" ]="gumuz", + ["gnn" ]="gumatj", + ["gog" ]="gogo", + ["gon" ]="gondi", + ["grn" ]="greenlandic", + ["gro" ]="garo", + ["gua" ]="guarani", + ["guc" ]="wayuu", + ["guf" ]="gupapuyngu", + ["guj" ]="gujarati", + ["guz" ]="gusii", + ["hai" ]="haitian (haitian creole)", + ["hal" ]="halam", + ["har" ]="harauti", + ["hau" ]="hausa", + ["haw" ]="hawaiian", + ["hay" ]="haya", + ["haz" ]="hazaragi", + ["hbn" ]="hammer-banna", + ["her" ]="herero", + ["hil" ]="hiligaynon", + ["hin" ]="hindi", + ["hma" ]="high mari", + ["hmn" ]="hmong", + ["hmo" ]="hiri motu", + ["hnd" ]="hindko", + ["ho" ]="ho", + ["hri" ]="harari", + ["hrv" ]="croatian", + ["hun" ]="hungarian", + ["hye" ]="armenian", + ["hye0"]="armenian east", + ["iba" ]="iban", + ["ibb" ]="ibibio", + ["ibo" ]="igbo", + ["ido" ]="ido", + ["ijo" ]="ijo languages", + ["ile" ]="interlingue", + ["ilo" ]="ilokano", + ["ina" ]="interlingua", + ["ind" ]="indonesian", + ["ing" ]="ingush", + ["inu" ]="inuktitut", + ["ipk" ]="inupiat", + ["ipph"]="phonetic transcription—ipa conventions", + ["iri" ]="irish", + ["irt" ]="irish traditional", + ["isl" ]="icelandic", + ["ism" ]="inari sami", + ["ita" ]="italian", + ["iwr" ]="hebrew", + ["jam" ]="jamaican creole", + ["jan" ]="japanese", + ["jav" ]="javanese", + ["jbo" ]="lojban", + ["jii" ]="yiddish", + ["jud" ]="ladino", + ["jul" ]="jula", + ["kab" ]="kabardian", + ["kab0"]="kabyle", + ["kac" ]="kachchi", + ["kal" ]="kalenjin", + ["kan" ]="kannada", + ["kar" ]="karachay", + ["kat" ]="georgian", + ["kaz" ]="kazakh", + ["kde" ]="makonde", + ["kea" ]="kabuverdianu (crioulo)", + ["keb" ]="kebena", + ["kek" ]="kekchi", + ["kge" ]="khutsuri georgian", + ["kha" ]="khakass", + ["khk" ]="khanty-kazim", + ["khm" ]="khmer", + ["khs" ]="khanty-shurishkar", + ["kht" ]="khamti shan", + ["khv" ]="khanty-vakhi", + ["khw" ]="khowar", + ["kik" ]="kikuyu (gikuyu)", + ["kir" ]="kirghiz (kyrgyz)", + ["kis" ]="kisii", + ["kiu" ]="kirmanjki", + ["kjd" ]="southern kiwai", + ["kjp" ]="eastern pwo karen", + ["kjz" ]="bumthangkha", + ["kkn" ]="kokni", + ["klm" ]="kalmyk", + ["kmb" ]="kamba", + ["kmn" ]="kumaoni", + ["kmo" ]="komo", + ["kms" ]="komso", + ["knr" ]="kanuri", + ["kod" ]="kodagu", + ["koh" ]="korean old hangul", + ["kok" ]="konkani", + ["kom" ]="komi", + ["kon" ]="kikongo", + ["kon0"]="kongo", + ["kop" ]="komi-permyak", + ["kor" ]="korean", + ["kos" ]="kosraean", + ["koz" ]="komi-zyrian", + ["kpl" ]="kpelle", + ["kri" ]="krio", + ["krk" ]="karakalpak", + ["krl" ]="karelian", + ["krm" ]="karaim", + ["krn" ]="karen", + ["krt" ]="koorete", + ["ksh" ]="kashmiri", + ["ksh0"]="ripuarian", + ["ksi" ]="khasi", + ["ksm" ]="kildin sami", + ["ksw" ]="s’gaw karen", + ["kua" ]="kuanyama", + ["kui" ]="kui", + ["kul" ]="kulvi", + ["kum" ]="kumyk", + ["kur" ]="kurdish", + ["kuu" ]="kurukh", + ["kuy" ]="kuy", + ["kyk" ]="koryak", + ["kyu" ]="western kayah", + ["lad" ]="ladin", + ["lah" ]="lahuli", + ["lak" ]="lak", + ["lam" ]="lambani", + ["lao" ]="lao", + ["lat" ]="latin", + ["laz" ]="laz", + ["lcr" ]="l-cree", + ["ldk" ]="ladakhi", + ["lez" ]="lezgi", + ["lij" ]="ligurian", + ["lim" ]="limburgish", + ["lin" ]="lingala", + ["lis" ]="lisu", + ["ljp" ]="lampung", + ["lki" ]="laki", + ["lma" ]="low mari", + ["lmb" ]="limbu", + ["lmo" ]="lombard", + ["lmw" ]="lomwe", + ["lom" ]="loma", + ["lrc" ]="luri", + ["lsb" ]="lower sorbian", + ["lsm" ]="lule sami", + ["lth" ]="lithuanian", + ["ltz" ]="luxembourgish", + ["lua" ]="luba-lulua", + ["lub" ]="luba-katanga", + ["lug" ]="ganda", + ["luh" ]="luyia", + ["luo" ]="luo", + ["lvi" ]="latvian", + ["mad" ]="madura", + ["mag" ]="magahi", + ["mah" ]="marshallese", + ["maj" ]="majang", + ["mak" ]="makhuwa", + ["mal" ]="malayalam reformed", + ["mam" ]="mam", + ["man" ]="mansi", + ["map" ]="mapudungun", + ["mar" ]="marathi", + ["maw" ]="marwari", + ["mbn" ]="mbundu", + ["mch" ]="manchu", + ["mcr" ]="moose cree", + ["mde" ]="mende", + ["mdr" ]="mandar", + ["men" ]="me'en", + ["mer" ]="meru", + ["mfa" ]="pattani malay", + ["mfe" ]="morisyen", + ["min" ]="minangkabau", + ["miz" ]="mizo", + ["mkd" ]="macedonian", + ["mkr" ]="makasar", + ["mkw" ]="kituba", + ["mle" ]="male", + ["mlg" ]="malagasy", + ["mln" ]="malinke", + ["mly" ]="malay", + ["mnd" ]="mandinka", + ["mng" ]="mongolian", + ["mni" ]="manipuri", + ["mnk" ]="maninka", + ["mnx" ]="manx", + ["moh" ]="mohawk", + ["mok" ]="moksha", + ["mol" ]="moldavian", + ["mon" ]="mon", + ["mor" ]="moroccan", + ["mos" ]="mossi", + ["mri" ]="maori", + ["mth" ]="maithili", + ["mts" ]="maltese", + ["mun" ]="mundari", + ["mus" ]="muscogee", + ["mwl" ]="mirandese", + ["mww" ]="hmong daw", + ["myn" ]="mayan", + ["mzn" ]="mazanderani", + ["nag" ]="naga-assamese", + ["nah" ]="nahuatl", + ["nan" ]="nanai", + ["nap" ]="neapolitan", + ["nas" ]="naskapi", + ["nau" ]="nauruan", + ["nav" ]="navajo", + ["ncr" ]="n-cree", + ["ndb" ]="ndebele", + ["ndc" ]="ndau", + ["ndg" ]="ndonga", + ["nds" ]="low saxon", + ["nep" ]="nepali", + ["new" ]="newari", + ["nga" ]="ngbaka", + ["ngr" ]="nagari", + ["nhc" ]="norway house cree", + ["nis" ]="nisi", + ["niu" ]="niuean", + ["nkl" ]="nyankole", + ["nko" ]="n'ko", + ["nld" ]="dutch", + ["noe" ]="nimadi", + ["nog" ]="nogai", + ["nor" ]="norwegian", + ["nov" ]="novial", + ["nsm" ]="northern sami", + ["nso" ]="sotho, northern", + ["nta" ]="northern tai", + ["nto" ]="esperanto", + ["nym" ]="nyamwezi", + ["nyn" ]="norwegian nynorsk", + ["oci" ]="occitan", + ["ocr" ]="oji-cree", + ["ojb" ]="ojibway", + ["ori" ]="odia", + ["oro" ]="oromo", + ["oss" ]="ossetian", + ["paa" ]="palestinian aramaic", + ["pag" ]="pangasinan", + ["pal" ]="pali", + ["pam" ]="pampangan", + ["pan" ]="punjabi", + ["pap" ]="palpa", + ["pap0"]="papiamentu", + ["pas" ]="pashto", + ["pau" ]="palauan", + ["pcc" ]="bouyei", + ["pcd" ]="picard", + ["pdc" ]="pennsylvania german", + ["pgr" ]="polytonic greek", + ["phk" ]="phake", + ["pih" ]="norfolk", + ["pil" ]="filipino", + ["plg" ]="palaung", + ["plk" ]="polish", + ["pms" ]="piemontese", + ["pnb" ]="western panjabi", + ["poh" ]="pocomchi", + ["pon" ]="pohnpeian", + ["pro" ]="provencal", + ["ptg" ]="portuguese", + ["pwo" ]="western pwo karen", + ["qin" ]="chin", + ["quc" ]="k’iche’", + ["quh" ]="quechua (bolivia)", + ["quz" ]="quechua", + ["qvi" ]="quechua (ecuador)", + ["qwh" ]="quechua (peru)", + ["raj" ]="rajasthani", + ["rar" ]="rarotongan", + ["rbu" ]="russian buriat", + ["rcr" ]="r-cree", + ["rej" ]="rejang", + ["ria" ]="riang", + ["rif" ]="tarifit", + ["rit" ]="ritarungo", + ["rkw" ]="arakwal", + ["rms" ]="romansh", + ["rmy" ]="vlax romani", + ["rom" ]="romanian", + ["roy" ]="romany", + ["rsy" ]="rusyn", + ["rtm" ]="rotuman", + ["rua" ]="kinyarwanda", + ["run" ]="rundi", + ["rup" ]="aromanian", + ["rus" ]="russian", + ["sad" ]="sadri", + ["san" ]="sanskrit", + ["sas" ]="sasak", + ["sat" ]="santali", + ["say" ]="sayisi", + ["scn" ]="sicilian", + ["sco" ]="scots", + ["sek" ]="sekota", + ["sel" ]="selkup", + ["sga" ]="old irish", + ["sgo" ]="sango", + ["sgs" ]="samogitian", + ["shi" ]="tachelhit", + ["shn" ]="shan", + ["sib" ]="sibe", + ["sid" ]="sidamo", + ["sig" ]="silte gurage", + ["sks" ]="skolt sami", + ["sky" ]="slovak", + ["sla" ]="slavey", + ["slv" ]="slovenian", + ["sml" ]="somali", + ["smo" ]="samoan", + ["sna" ]="sena", + ["sna0"]="shona", + ["snd" ]="sindhi", + ["snh" ]="sinhala (sinhalese)", + ["snk" ]="soninke", + ["sog" ]="sodo gurage", + ["sop" ]="songe", + ["sot" ]="sotho, southern", + ["sqi" ]="albanian", + ["srb" ]="serbian", + ["srd" ]="sardinian", + ["srk" ]="saraiki", + ["srr" ]="serer", + ["ssl" ]="south slavey", + ["ssm" ]="southern sami", + ["stq" ]="saterland frisian", + ["suk" ]="sukuma", + ["sun" ]="sundanese", + ["sur" ]="suri", + ["sva" ]="svan", + ["sve" ]="swedish", + ["swa" ]="swadaya aramaic", + ["swk" ]="swahili", + ["swz" ]="swati", + ["sxt" ]="sutu", + ["sxu" ]="upper saxon", + ["syl" ]="sylheti", + ["syr" ]="syriac", + ["szl" ]="silesian", + ["tab" ]="tabasaran", + ["taj" ]="tajiki", + ["tam" ]="tamil", + ["tat" ]="tatar", + ["tcr" ]="th-cree", + ["tdd" ]="dehong dai", + ["tel" ]="telugu", + ["tet" ]="tetum", + ["tgl" ]="tagalog", + ["tgn" ]="tongan", + ["tgr" ]="tigre", + ["tgy" ]="tigrinya", + ["tha" ]="thai", + ["tht" ]="tahitian", + ["tib" ]="tibetan", + ["tiv" ]="tiv", + ["tkm" ]="turkmen", + ["tmh" ]="tamashek", + ["tmn" ]="temne", + ["tna" ]="tswana", + ["tne" ]="tundra nenets", + ["tng" ]="tonga", + ["tod" ]="todo", + ["tod0"]="toma", + ["tpi" ]="tok pisin", + ["trk" ]="turkish", + ["tsg" ]="tsonga", + ["tsj" ]="tshangla", + ["tua" ]="turoyo aramaic", + ["tul" ]="tulu", + ["tuv" ]="tuvin", + ["tvl" ]="tuvalu", + ["twi" ]="twi", + ["tyz" ]="tày", + ["tzm" ]="tamazight", + ["tzo" ]="tzotzil", + ["udm" ]="udmurt", + ["ukr" ]="ukrainian", + ["umb" ]="umbundu", + ["urd" ]="urdu", + ["usb" ]="upper sorbian", + ["uyg" ]="uyghur", + ["uzb" ]="uzbek", + ["vec" ]="venetian", + ["ven" ]="venda", + ["vit" ]="vietnamese", + ["vol" ]="volapük", + ["vro" ]="võro", + ["wa" ]="wa", + ["wag" ]="wagdi", + ["war" ]="waray-waray", + ["wcr" ]="west-cree", + ["wel" ]="welsh", + ["wlf" ]="wolof", + ["wln" ]="walloon", + ["xbd" ]="lü", + ["xhs" ]="xhosa", + ["xjb" ]="minjangbal", + ["xkf" ]="khengkha", + ["xog" ]="soga", + ["xpe" ]="kpelle (liberia)", + ["yak" ]="sakha", + ["yao" ]="yao", + ["yap" ]="yapese", + ["yba" ]="yoruba", + ["ycr" ]="y-cree", + ["yic" ]="yi classic", + ["yim" ]="yi modern", + ["zea" ]="zealandic", + ["zgh" ]="standard morrocan tamazigh", + ["zha" ]="zhuang", + ["zhh" ]="chinese, hong kong sar", + ["zhp" ]="chinese phonetic", + ["zhs" ]="chinese simplified", + ["zht" ]="chinese traditional", + ["znd" ]="zande", + ["zul" ]="zulu", + ["zza" ]="zazaki", +} +local features=allocate { + ["aalt"]="access all alternates", + ["abvf"]="above-base forms", + ["abvm"]="above-base mark positioning", + ["abvs"]="above-base substitutions", + ["afrc"]="alternative fractions", + ["akhn"]="akhands", + ["blwf"]="below-base forms", + ["blwm"]="below-base mark positioning", + ["blws"]="below-base substitutions", + ["c2pc"]="petite capitals from capitals", + ["c2sc"]="small capitals from capitals", + ["calt"]="contextual alternates", + ["case"]="case-sensitive forms", + ["ccmp"]="glyph composition/decomposition", + ["cfar"]="conjunct form after ro", + ["cjct"]="conjunct forms", + ["clig"]="contextual ligatures", + ["cpct"]="centered cjk punctuation", + ["cpsp"]="capital spacing", + ["cswh"]="contextual swash", + ["curs"]="cursive positioning", + ["dflt"]="default processing", + ["dist"]="distances", + ["dlig"]="discretionary ligatures", + ["dnom"]="denominators", + ["dtls"]="dotless forms", + ["expt"]="expert forms", + ["falt"]="final glyph alternates", + ["fin2"]="terminal forms #2", + ["fin3"]="terminal forms #3", + ["fina"]="terminal forms", + ["flac"]="flattened accents over capitals", + ["frac"]="fractions", + ["fwid"]="full width", + ["half"]="half forms", + ["haln"]="halant forms", + ["halt"]="alternate half width", + ["hist"]="historical forms", + ["hkna"]="horizontal kana alternates", + ["hlig"]="historical ligatures", + ["hngl"]="hangul", + ["hojo"]="hojo kanji forms", + ["hwid"]="half width", + ["init"]="initial forms", + ["isol"]="isolated forms", + ["ital"]="italics", + ["jalt"]="justification alternatives", + ["jp04"]="jis2004 forms", + ["jp78"]="jis78 forms", + ["jp83"]="jis83 forms", + ["jp90"]="jis90 forms", + ["kern"]="kerning", + ["lfbd"]="left bounds", + ["liga"]="standard ligatures", + ["ljmo"]="leading jamo forms", + ["lnum"]="lining figures", + ["locl"]="localized forms", + ["ltra"]="left-to-right alternates", + ["ltrm"]="left-to-right mirrored forms", + ["mark"]="mark positioning", + ["med2"]="medial forms #2", + ["medi"]="medial forms", + ["mgrk"]="mathematical greek", + ["mkmk"]="mark to mark positioning", + ["mset"]="mark positioning via substitution", + ["nalt"]="alternate annotation forms", + ["nlck"]="nlc kanji forms", + ["nukt"]="nukta forms", + ["numr"]="numerators", + ["onum"]="old style figures", + ["opbd"]="optical bounds", + ["ordn"]="ordinals", + ["ornm"]="ornaments", + ["palt"]="proportional alternate width", + ["pcap"]="petite capitals", + ["pkna"]="proportional kana", + ["pnum"]="proportional figures", + ["pref"]="pre-base forms", + ["pres"]="pre-base substitutions", + ["pstf"]="post-base forms", + ["psts"]="post-base substitutions", + ["pwid"]="proportional widths", + ["qwid"]="quarter widths", + ["rand"]="randomize", + ["rclt"]="required contextual alternates", + ["rkrf"]="rakar forms", + ["rlig"]="required ligatures", + ["rphf"]="reph form", + ["rtbd"]="right bounds", + ["rtla"]="right-to-left alternates", + ["rtlm"]="right to left mirrored forms", + ["rvrn"]="required variation alternates", + ["ruby"]="ruby notation forms", + ["salt"]="stylistic alternates", + ["sinf"]="scientific inferiors", + ["size"]="optical size", + ["smcp"]="small capitals", + ["smpl"]="simplified forms", + ["ssty"]="script style", + ["stch"]="stretching glyph decomposition", + ["subs"]="subscript", + ["sups"]="superscript", + ["swsh"]="swash", + ["titl"]="titling", + ["tjmo"]="trailing jamo forms", + ["tnam"]="traditional name forms", + ["tnum"]="tabular figures", + ["trad"]="traditional forms", + ["twid"]="third widths", + ["unic"]="unicase", + ["valt"]="alternate vertical metrics", + ["vatu"]="vattu variants", + ["vert"]="vertical writing", + ["vhal"]="alternate vertical half metrics", + ["vjmo"]="vowel jamo forms", + ["vkna"]="vertical kana alternates", + ["vkrn"]="vertical kerning", + ["vpal"]="proportional alternate vertical metrics", + ["vrt2"]="vertical rotation", + ["zero"]="slashed zero", + ["trep"]="traditional tex replacements", + ["tlig"]="traditional tex ligatures", + ["ss.."]="stylistic set ..", + ["cv.."]="character variant ..", + ["js.."]="justification ..", + ["dv.."]="devanagari ..", + ["ml.."]="malayalam ..", +} +local baselines=allocate { + ["hang"]="hanging baseline", + ["icfb"]="ideographic character face bottom edge baseline", + ["icft"]="ideographic character face tope edige baseline", + ["ideo"]="ideographic em-box bottom edge baseline", + ["idtp"]="ideographic em-box top edge baseline", + ["math"]="mathematical centered baseline", + ["romn"]="roman baseline" +} +tables.scripts=scripts +tables.languages=languages +tables.features=features +tables.baselines=baselines +local acceptscripts=true directives.register("otf.acceptscripts",function(v) acceptscripts=v end) +local acceptlanguages=true directives.register("otf.acceptlanguages",function(v) acceptlanguages=v end) +local report_checks=logs.reporter("fonts","checks") +if otffeatures.features then + for k,v in next,otffeatures.features do + features[k]=v + end + otffeatures.features=features +end +local function swapped(h) + local r={} + for k,v in next,h do + r[gsub(v,"[^a-z0-9]","")]=k + end + return r +end +local verbosescripts=allocate(swapped(scripts )) +local verboselanguages=allocate(swapped(languages)) +local verbosefeatures=allocate(swapped(features )) +local verbosebaselines=allocate(swapped(baselines)) +local function resolve(t,k) + if k then + k=gsub(lower(k),"[^a-z0-9]","") + local v=rawget(t,k) + if v then + return v + end + end +end +setmetatableindex(verbosescripts,resolve) +setmetatableindex(verboselanguages,resolve) +setmetatableindex(verbosefeatures,resolve) +setmetatableindex(verbosebaselines,resolve) +setmetatableindex(scripts,function(t,k) + if k then + k=lower(k) + if k=="dflt" then + return k + end + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + v=rawget(t,v) + if v then + return v + elseif acceptscripts then + report_checks("registering extra script %a",k) + rawset(t,k,k) + return k + end + end + return "dflt" +end) +setmetatableindex(languages,function(t,k) + if k then + k=lower(k) + if k=="dflt" then + return k + end + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + v=rawget(t,v) + if v then + return v + elseif acceptlanguages then + report_checks("registering extra language %a",k) + rawset(t,k,k) + return k + end + end + return "dflt" +end) +if setmetatablenewindex then + setmetatablenewindex(languages,"ignore") + setmetatablenewindex(scripts,"ignore") + setmetatablenewindex(baselines,"ignore") +end +local function resolve(t,k) + if k then + k=lower(k) + local v=rawget(t,k) + if v then + return v + end + k=gsub(k," ","") + local v=rawget(t,k) + if v then + return v + end + local tag,dd=match(k,"(..)(%d+)") + if tag and dd then + local v=rawget(t,tag) + if v then + return v + else + local v=rawget(t,tag.."..") + if v then + return (gsub(v,"%.%.",tonumber(dd))) + end + end + end + end + return k +end +setmetatableindex(features,resolve) +local function assign(t,k,v) + if k and v then + v=lower(v) + rawset(t,k,v) + end +end +if setmetatablenewindex then + setmetatablenewindex(features,assign) +end +local checkers={ + rand=function(v) + return v==true and "random" or v + end +} +if not storage then + return +end +local usedfeatures=statistics.usedfeatures or {} +statistics.usedfeatures=usedfeatures +table.setmetatableindex(usedfeatures,function(t,k) if k then local v={} t[k]=v return v end end) +storage.register("fonts/otf/usedfeatures",usedfeatures,"fonts.handlers.otf.statistics.usedfeatures" ) +local normalizedaxis=otf.readers.helpers.normalizedaxis or function(s) return s end +function otffeatures.normalize(features,wrap) + if features then + local h={} + for key,value in next,features do + local k=lower(key) + if k=="language" then + local v=gsub(lower(value),"[^a-z0-9]","") + h.language=rawget(verboselanguages,v) or (languages[v] and v) or "dflt" + elseif k=="script" then + local v=gsub(lower(value),"[^a-z0-9]","") + h.script=rawget(verbosescripts,v) or (scripts[v] and v) or "dflt" + elseif k=="axis" then + h[k]=normalizedaxis(value) + if not callbacks.supported.glyph_stream_provider then + h.variableshapes=true + end + else + local uk=usedfeatures[key] + local uv=uk[value] + if uv then + else + uv=tonumber(value) + if uv then + elseif type(value)=="string" then + local b=is_boolean(value) + if type(b)=="nil" then + if wrap and find(value,",") then + uv="{"..lower(value).."}" + else + uv=lower(value) + end + else + uv=b + end + elseif type(value)=="table" then + uv=sequenced(t,",") + else + uv=value + end + if not rawget(features,k) then + k=rawget(verbosefeatures,k) or k + end + local c=checkers[k] + if c then + uv=c(uv) or vc + end + uk[value]=uv end + h[k]=uv + end end + return h + end end end -- closure @@ -12803,30 +13453,43 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-cff']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } -local next,type,tonumber=next,type,tonumber +local next,type,tonumber,rawget=next,type,tonumber,rawget local byte,char,gmatch=string.byte,string.char,string.gmatch -local concat,remove=table.concat,table.remove +local concat,remove,unpack=table.concat,table.remove,table.unpack local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct local lpegmatch=lpeg.match local formatters=string.formatters local bytetable=string.bytetable +local idiv=number.idiv +local rshift,band,extract=bit32.rshift,bit32.band,bit32.extract local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local readstring=streamreader.readstring -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readuint=streamreader.readcardinal3 -local readulong=streamreader.readcardinal4 +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readuint=streamreader.readcardinal3 +local readulong=streamreader.readcardinal4 local setposition=streamreader.setposition local getposition=streamreader.getposition local readbytetable=streamreader.readbytetable +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + readstring=streamreader.readstring + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readuint=streamreader.readcardinal3 + readulong=streamreader.readcardinal4 + setposition=streamreader.setposition + getposition=streamreader.getposition + readbytetable=streamreader.readbytetable +end) local setmetatableindex=table.setmetatableindex local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) local report=logs.reporter("otf reader","cff") @@ -12838,1818 +13501,1973 @@ local parseprivates local startparsing local stopparsing local defaultstrings={ [0]= - ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", - "ampersand","quoteright","parenleft","parenright","asterisk","plus", - "comma","hyphen","period","slash","zero","one","two","three","four", - "five","six","seven","eight","nine","colon","semicolon","less", - "equal","greater","question","at","A","B","C","D","E","F","G","H", - "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", - "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", - "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", - "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", - "z","braceleft","bar","braceright","asciitilde","exclamdown","cent", - "sterling","fraction","yen","florin","section","currency", - "quotesingle","quotedblleft","guillemotleft","guilsinglleft", - "guilsinglright","fi","fl","endash","dagger","daggerdbl", - "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase", - "quotedblright","guillemotright","ellipsis","perthousand","questiondown", - "grave","acute","circumflex","tilde","macron","breve","dotaccent", - "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash", - "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae", - "dotlessi","lslash","oslash","oe","germandbls","onesuperior", - "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn", - "onequarter","divide","brokenbar","degree","thorn","threequarters", - "twosuperior","registered","minus","eth","multiply","threesuperior", - "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring", - "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave", - "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute", - "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute", - "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron", - "aacute","acircumflex","adieresis","agrave","aring","atilde", - "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute", - "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex", - "odieresis","ograve","otilde","scaron","uacute","ucircumflex", - "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall", - "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall", - "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader", - "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle", - "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle", - "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior", - "threequartersemdash","periodsuperior","questionsmall","asuperior", - "bsuperior","centsuperior","dsuperior","esuperior","isuperior", - "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior", - "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior", - "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall", - "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall", - "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall", - "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall", - "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah", - "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall", - "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall", - "Dotaccentsmall","Macronsmall","figuredash","hypheninferior", - "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth", - "threeeighths","fiveeighths","seveneighths","onethird","twothirds", - "zerosuperior","foursuperior","fivesuperior","sixsuperior", - "sevensuperior","eightsuperior","ninesuperior","zeroinferior", - "oneinferior","twoinferior","threeinferior","fourinferior", - "fiveinferior","sixinferior","seveninferior","eightinferior", - "nineinferior","centinferior","dollarinferior","periodinferior", - "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall", - "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall", - "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall", - "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall", - "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall", - "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall", - "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall", - "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", - "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", + ".notdef","space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde","exclamdown","cent", + "sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl","endash","dagger","daggerdbl", + "periodcentered","paragraph","bullet","quotesinglbase","quotedblbase", + "quotedblright","guillemotright","ellipsis","perthousand","questiondown", + "grave","acute","circumflex","tilde","macron","breve","dotaccent", + "dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash", + "AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae", + "dotlessi","lslash","oslash","oe","germandbls","onesuperior", + "logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn", + "onequarter","divide","brokenbar","degree","thorn","threequarters", + "twosuperior","registered","minus","eth","multiply","threesuperior", + "copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring", + "Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute", + "Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute", + "Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron", + "aacute","acircumflex","adieresis","agrave","aring","atilde", + "ccedilla","eacute","ecircumflex","edieresis","egrave","iacute", + "icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex", + "odieresis","ograve","otilde","scaron","uacute","ucircumflex", + "udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall", + "Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall", + "Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader", + "onedotenleader","zerooldstyle","oneoldstyle","twooldstyle", + "threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle", + "sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior", + "threequartersemdash","periodsuperior","questionsmall","asuperior", + "bsuperior","centsuperior","dsuperior","esuperior","isuperior", + "lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior", + "tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior", + "Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall", + "Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall", + "Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall", + "Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall", + "Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah", + "Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall", + "Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall", + "Dotaccentsmall","Macronsmall","figuredash","hypheninferior", + "Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth", + "threeeighths","fiveeighths","seveneighths","onethird","twothirds", + "zerosuperior","foursuperior","fivesuperior","sixsuperior", + "sevensuperior","eightsuperior","ninesuperior","zeroinferior", + "oneinferior","twoinferior","threeinferior","fourinferior", + "fiveinferior","sixinferior","seveninferior","eightinferior", + "nineinferior","centinferior","dollarinferior","periodinferior", + "commainferior","Agravesmall","Aacutesmall","Acircumflexsmall", + "Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall", + "Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall", + "Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall", + "Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall", + "Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall", + "Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall", + "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", + "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", } local cffreaders={ - readbyte, - readushort, - readuint, - readulong, + readbyte, + readushort, + readuint, + readulong, } local function readheader(f) - local offset=getposition(f) - local major=readbyte(f) - local header={ - offset=offset, - major=major, - minor=readbyte(f), - size=readbyte(f), - } - if major==1 then - header.dsize=readbyte(f) - elseif major==2 then - header.dsize=readushort(f) - else - end - setposition(f,offset+header.size) - return header + local offset=getposition(f) + local major=readbyte(f) + local header={ + offset=offset, + major=major, + minor=readbyte(f), + size=readbyte(f), + } + if major==1 then + header.dsize=readbyte(f) + elseif major==2 then + header.dsize=readushort(f) + else + end + setposition(f,offset+header.size) + return header end local function readlengths(f,longcount) - local count=longcount and readulong(f) or readushort(f) - if count==0 then - return {} - end - local osize=readbyte(f) - local read=cffreaders[osize] - if not read then - report("bad offset size: %i",osize) - return {} - end - local lengths={} - local previous=read(f) - for i=1,count do - local offset=read(f) - local length=offset-previous - if length<0 then - report("bad offset: %i",length) - length=0 - end - lengths[i]=length - previous=offset - end - return lengths + local count=longcount and readulong(f) or readushort(f) + if count==0 then + return {} + end + local osize=readbyte(f) + local read=cffreaders[osize] + if not read then + report("bad offset size: %i",osize) + return {} + end + local lengths={} + local previous=read(f) + for i=1,count do + local offset=read(f) + local length=offset-previous + if length<0 then + report("bad offset: %i",length) + length=0 + end + lengths[i]=length + previous=offset + end + return lengths end local function readfontnames(f) - local names=readlengths(f) - for i=1,#names do - names[i]=readstring(f,names[i]) - end - return names + local names=readlengths(f) + for i=1,#names do + names[i]=readstring(f,names[i]) + end + return names end local function readtopdictionaries(f) - local dictionaries=readlengths(f) - for i=1,#dictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - return dictionaries + local dictionaries=readlengths(f) + for i=1,#dictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + return dictionaries end local function readstrings(f) - local lengths=readlengths(f) - local strings=setmetatableindex({},defaultstrings) - local index=#defaultstrings - for i=1,#lengths do - index=index+1 - strings[index]=readstring(f,lengths[i]) - end - return strings + local lengths=readlengths(f) + local strings=setmetatableindex({},defaultstrings) + local index=#defaultstrings + for i=1,#lengths do + index=index+1 + strings[index]=readstring(f,lengths[i]) + end + return strings end do - local stack={} - local top=0 - local result={} - local strings={} - local p_single=P("\00")/function() - result.version=strings[stack[top]] or "unset" - top=0 - end+P("\01")/function() - result.notice=strings[stack[top]] or "unset" - top=0 - end+P("\02")/function() - result.fullname=strings[stack[top]] or "unset" - top=0 - end+P("\03")/function() - result.familyname=strings[stack[top]] or "unset" - top=0 - end+P("\04")/function() - result.weight=strings[stack[top]] or "unset" - top=0 - end+P("\05")/function() - result.fontbbox={ unpack(stack,1,4) } - top=0 - end -+P("\13")/function() - result.uniqueid=stack[top] - top=0 - end+P("\14")/function() - result.xuid=concat(stack,"",1,top) - top=0 - end+P("\15")/function() - result.charset=stack[top] - top=0 - end+P("\16")/function() - result.encoding=stack[top] - top=0 - end+P("\17")/function() - result.charstrings=stack[top] - top=0 - end+P("\18")/function() - result.private={ - size=stack[top-1], - offset=stack[top], - } - top=0 - end+P("\19")/function() - result.subroutines=stack[top] - top=0 - end+P("\20")/function() - result.defaultwidthx=stack[top] - top=0 - end+P("\21")/function() - result.nominalwidthx=stack[top] - top=0 - end -+P("\24")/function() - result.vstore=stack[top] - top=0 - end+P("\25")/function() - result.maxstack=stack[top] - top=0 - end - local p_double=P("\12")*( - P("\00")/function() - result.copyright=stack[top] - top=0 - end+P("\01")/function() - result.monospaced=stack[top]==1 and true or false - top=0 - end+P("\02")/function() - result.italicangle=stack[top] - top=0 - end+P("\03")/function() - result.underlineposition=stack[top] - top=0 - end+P("\04")/function() - result.underlinethickness=stack[top] - top=0 - end+P("\05")/function() - result.painttype=stack[top] - top=0 - end+P("\06")/function() - result.charstringtype=stack[top] - top=0 - end+P("\07")/function() - result.fontmatrix={ unpack(stack,1,6) } - top=0 - end+P("\08")/function() - result.strokewidth=stack[top] - top=0 - end+P("\20")/function() - result.syntheticbase=stack[top] - top=0 - end+P("\21")/function() - result.postscript=strings[stack[top]] or "unset" - top=0 - end+P("\22")/function() - result.basefontname=strings[stack[top]] or "unset" - top=0 - end+P("\21")/function() - result.basefontblend=stack[top] - top=0 - end+P("\30")/function() - result.cid.registry=strings[stack[top-2]] or "unset" - result.cid.ordering=strings[stack[top-1]] or "unset" - result.cid.supplement=stack[top] - top=0 - end+P("\31")/function() - result.cid.fontversion=stack[top] - top=0 - end+P("\32")/function() - result.cid.fontrevision=stack[top] - top=0 - end+P("\33")/function() - result.cid.fonttype=stack[top] - top=0 - end+P("\34")/function() - result.cid.count=stack[top] - top=0 - end+P("\35")/function() - result.cid.uidbase=stack[top] - top=0 - end+P("\36")/function() - result.cid.fdarray=stack[top] - top=0 - end+P("\37")/function() - result.cid.fdselect=stack[top] - top=0 - end+P("\38")/function() - result.cid.fontname=strings[stack[top]] or "unset" - top=0 - end - ) - local p_last=P("\x0F")/"0"+P("\x1F")/"1"+P("\x2F")/"2"+P("\x3F")/"3"+P("\x4F")/"4"+P("\x5F")/"5"+P("\x6F")/"6"+P("\x7F")/"7"+P("\x8F")/"8"+P("\x9F")/"9"+P("\xAF")/""+P("\xBF")/""+P("\xCF")/""+P("\xDF")/""+P("\xEF")/""+R("\xF0\xFF")/"" - local remap={ - ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0", - ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="0.",["\x1B"]="0E",["\x1C"]="0E-",["\x1D"]="0",["\x1E"]="0-",["\x1F"]="0", - ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="0.",["\x2B"]="0E",["\x2C"]="0E-",["\x2D"]="0",["\x2E"]="0-",["\x2F"]="0", - ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="0.",["\x3B"]="0E",["\x3C"]="0E-",["\x3D"]="0",["\x3E"]="0-",["\x3F"]="0", - ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="0.",["\x4B"]="0E",["\x4C"]="0E-",["\x4D"]="0",["\x4E"]="0-",["\x4F"]="0", - ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="0.",["\x5B"]="0E",["\x5C"]="0E-",["\x5D"]="0",["\x5E"]="0-",["\x5F"]="0", - ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="0.",["\x6B"]="0E",["\x6C"]="0E-",["\x6D"]="0",["\x6E"]="0-",["\x6F"]="0", - ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="0.",["\x7B"]="0E",["\x7C"]="0E-",["\x7D"]="0",["\x7E"]="0-",["\x7F"]="0", - ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="0.",["\x8B"]="0E",["\x8C"]="0E-",["\x8D"]="0",["\x8E"]="0-",["\x8F"]="0", - ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="0.",["\x9B"]="0E",["\x9C"]="0E-",["\x9D"]="0",["\x9E"]="0-",["\x9F"]="0", - ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".", - ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E", - ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-", - ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-", - } - local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0+p_last)/function(n) - top=top+1 - stack[top]=tonumber(n) or 0 - end - local p_byte=C(R("\32\246"))/function(b0) - top=top+1 - stack[top]=byte(b0)-139 - end - local p_positive=C(R("\247\250"))*C(1)/function(b0,b1) - top=top+1 - stack[top]=(byte(b0)-247)*256+byte(b1)+108 + local stack={} + local top=0 + local result={} + local strings={} + local p_single=P("\00")/function() + result.version=strings[stack[top]] or "unset" + top=0 + end+P("\01")/function() + result.notice=strings[stack[top]] or "unset" + top=0 + end+P("\02")/function() + result.fullname=strings[stack[top]] or "unset" + top=0 + end+P("\03")/function() + result.familyname=strings[stack[top]] or "unset" + top=0 + end+P("\04")/function() + result.weight=strings[stack[top]] or "unset" + top=0 + end+P("\05")/function() + result.fontbbox={ unpack(stack,1,4) } + top=0 + end+P("\06")/function() + result.bluevalues={ unpack(stack,1,top) } + top=0 + end+P("\07")/function() + result.otherblues={ unpack(stack,1,top) } + top=0 + end+P("\08")/function() + result.familyblues={ unpack(stack,1,top) } + top=0 + end+P("\09")/function() + result.familyotherblues={ unpack(stack,1,top) } + top=0 + end+P("\10")/function() + result.strhw=stack[top] + top=0 + end+P("\11")/function() + result.strvw=stack[top] + top=0 + end+P("\13")/function() + result.uniqueid=stack[top] + top=0 + end+P("\14")/function() + result.xuid=concat(stack,"",1,top) + top=0 + end+P("\15")/function() + result.charset=stack[top] + top=0 + end+P("\16")/function() + result.encoding=stack[top] + top=0 + end+P("\17")/function() + result.charstrings=stack[top] + top=0 + end+P("\18")/function() + result.private={ + size=stack[top-1], + offset=stack[top], + } + top=0 + end+P("\19")/function() + result.subroutines=stack[top] + top=0 + end+P("\20")/function() + result.defaultwidthx=stack[top] + top=0 + end+P("\21")/function() + result.nominalwidthx=stack[top] + top=0 end - local p_negative=C(R("\251\254"))*C(1)/function(b0,b1) - top=top+1 - stack[top]=-(byte(b0)-251)*256-byte(b1)-108 ++P("\24")/function() + result.vstore=stack[top] + top=0 + end+P("\25")/function() + result.maxstack=stack[top] + top=0 + end + local p_double=P("\12")*( + P("\00")/function() + result.copyright=stack[top] + top=0 + end+P("\01")/function() + result.monospaced=stack[top]==1 and true or false + top=0 + end+P("\02")/function() + result.italicangle=stack[top] + top=0 + end+P("\03")/function() + result.underlineposition=stack[top] + top=0 + end+P("\04")/function() + result.underlinethickness=stack[top] + top=0 + end+P("\05")/function() + result.painttype=stack[top] + top=0 + end+P("\06")/function() + result.charstringtype=stack[top] + top=0 + end+P("\07")/function() + result.fontmatrix={ unpack(stack,1,6) } + top=0 + end+P("\08")/function() + result.strokewidth=stack[top] + top=0 + end+P("\09")/function() + result.bluescale=stack[top] + top=0 + end+P("\10")/function() + result.bluesnap=stack[top] + top=0 + end+P("\11")/function() + result.bluefuzz=stack[top] + top=0 + end+P("\12")/function() + result.stemsnaph={ unpack(stack,1,top) } + top=0 + end+P("\13")/function() + result.stemsnapv={ unpack(stack,1,top) } + top=0 + end+P("\20")/function() + result.syntheticbase=stack[top] + top=0 + end+P("\21")/function() + result.postscript=strings[stack[top]] or "unset" + top=0 + end+P("\22")/function() + result.basefontname=strings[stack[top]] or "unset" + top=0 + end+P("\21")/function() + result.basefontblend=stack[top] + top=0 + end+P("\30")/function() + result.cid.registry=strings[stack[top-2]] or "unset" + result.cid.ordering=strings[stack[top-1]] or "unset" + result.cid.supplement=stack[top] + top=0 + end+P("\31")/function() + result.cid.fontversion=stack[top] + top=0 + end+P("\32")/function() + result.cid.fontrevision=stack[top] + top=0 + end+P("\33")/function() + result.cid.fonttype=stack[top] + top=0 + end+P("\34")/function() + result.cid.count=stack[top] + top=0 + end+P("\35")/function() + result.cid.uidbase=stack[top] + top=0 + end+P("\36")/function() + result.cid.fdarray=stack[top] + top=0 + end+P("\37")/function() + result.cid.fdselect=stack[top] + top=0 + end+P("\38")/function() + result.cid.fontname=strings[stack[top]] or "unset" + top=0 + end + ) + local remap={ + ["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0", + ["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1", + ["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2", + ["\x30"]="30",["\x31"]="31",["\x32"]="32",["\x33"]="33",["\x34"]="34",["\x35"]="35",["\x36"]="36",["\x37"]="37",["\x38"]="38",["\x39"]="39",["\x3A"]="3.",["\x3B"]="3E",["\x3C"]="3E-",["\x3D"]="3",["\x3E"]="3-",["\x3F"]="3", + ["\x40"]="40",["\x41"]="41",["\x42"]="42",["\x43"]="43",["\x44"]="44",["\x45"]="45",["\x46"]="46",["\x47"]="47",["\x48"]="48",["\x49"]="49",["\x4A"]="4.",["\x4B"]="4E",["\x4C"]="4E-",["\x4D"]="4",["\x4E"]="4-",["\x4F"]="4", + ["\x50"]="50",["\x51"]="51",["\x52"]="52",["\x53"]="53",["\x54"]="54",["\x55"]="55",["\x56"]="56",["\x57"]="57",["\x58"]="58",["\x59"]="59",["\x5A"]="5.",["\x5B"]="5E",["\x5C"]="5E-",["\x5D"]="5",["\x5E"]="5-",["\x5F"]="5", + ["\x60"]="60",["\x61"]="61",["\x62"]="62",["\x63"]="63",["\x64"]="64",["\x65"]="65",["\x66"]="66",["\x67"]="67",["\x68"]="68",["\x69"]="69",["\x6A"]="6.",["\x6B"]="6E",["\x6C"]="6E-",["\x6D"]="6",["\x6E"]="6-",["\x6F"]="6", + ["\x70"]="70",["\x71"]="71",["\x72"]="72",["\x73"]="73",["\x74"]="74",["\x75"]="75",["\x76"]="76",["\x77"]="77",["\x78"]="78",["\x79"]="79",["\x7A"]="7.",["\x7B"]="7E",["\x7C"]="7E-",["\x7D"]="7",["\x7E"]="7-",["\x7F"]="7", + ["\x80"]="80",["\x81"]="81",["\x82"]="82",["\x83"]="83",["\x84"]="84",["\x85"]="85",["\x86"]="86",["\x87"]="87",["\x88"]="88",["\x89"]="89",["\x8A"]="8.",["\x8B"]="8E",["\x8C"]="8E-",["\x8D"]="8",["\x8E"]="8-",["\x8F"]="8", + ["\x90"]="90",["\x91"]="91",["\x92"]="92",["\x93"]="93",["\x94"]="94",["\x95"]="95",["\x96"]="96",["\x97"]="97",["\x98"]="98",["\x99"]="99",["\x9A"]="9.",["\x9B"]="9E",["\x9C"]="9E-",["\x9D"]="9",["\x9E"]="9-",["\x9F"]="9", + ["\xA0"]=".0",["\xA1"]=".1",["\xA2"]=".2",["\xA3"]=".3",["\xA4"]=".4",["\xA5"]=".5",["\xA6"]=".6",["\xA7"]=".7",["\xA8"]=".8",["\xA9"]=".9",["\xAA"]="..",["\xAB"]=".E",["\xAC"]=".E-",["\xAD"]=".",["\xAE"]=".-",["\xAF"]=".", + ["\xB0"]="E0",["\xB1"]="E1",["\xB2"]="E2",["\xB3"]="E3",["\xB4"]="E4",["\xB5"]="E5",["\xB6"]="E6",["\xB7"]="E7",["\xB8"]="E8",["\xB9"]="E9",["\xBA"]="E.",["\xBB"]="EE",["\xBC"]="EE-",["\xBD"]="E",["\xBE"]="E-",["\xBF"]="E", + ["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-", + ["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-", + } + local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF") + local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n) + top=top+1 + stack[top]=tonumber(n) or 0 + end + local p_byte=C(R("\32\246"))/function(b0) + top=top+1 + stack[top]=byte(b0)-139 + end + local p_positive=C(R("\247\250"))*C(1)/function(b0,b1) + top=top+1 + stack[top]=(byte(b0)-247)*256+byte(b1)+108 + end + local p_negative=C(R("\251\254"))*C(1)/function(b0,b1) + top=top+1 + stack[top]=-(byte(b0)-251)*256-byte(b1)-108 + end + local p_short=P("\28")*C(1)*C(1)/function(b1,b2) + top=top+1 + local n=0x100*byte(b1)+byte(b2) + if n>=0x8000 then + stack[top]=n-0xFFFF-1 + else + stack[top]=n + end + end + local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4) + top=top+1 + local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4) + if n>=0x8000000 then + stack[top]=n-0xFFFFFFFF-1 + else + stack[top]=n + end + end + local p_unsupported=P(1)/function(detail) + top=0 + end + local p_dictionary=( + p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported + )^1 + parsedictionaries=function(data,dictionaries,what) + stack={} + strings=data.strings + for i=1,#dictionaries do + top=0 + result=what=="cff" and { + monospaced=false, + italicangle=0, + underlineposition=-100, + underlinethickness=50, + painttype=0, + charstringtype=2, + fontmatrix={ 0.001,0,0,0.001,0,0 }, + fontbbox={ 0,0,0,0 }, + strokewidth=0, + charset=0, + encoding=0, + cid={ + fontversion=0, + fontrevision=0, + fonttype=0, + count=8720, + } + } or { + charstringtype=2, + charset=0, + vstore=0, + cid={ + }, + } + lpegmatch(p_dictionary,dictionaries[i]) + dictionaries[i]=result + end + result={} + top=0 + stack={} + end + parseprivates=function(data,dictionaries) + stack={} + strings=data.strings + for i=1,#dictionaries do + local private=dictionaries[i].private + if private and private.data then + top=0 + result={ + forcebold=false, + languagegroup=0, + expansionfactor=0.06, + initialrandomseed=0, + subroutines=0, + defaultwidthx=0, + nominalwidthx=0, + cid={ + }, + } + lpegmatch(p_dictionary,private.data) + private.data=result + end + end + result={} + top=0 + stack={} + end + local x=0 + local y=0 + local width=false + local r=0 + local stems=0 + local globalbias=0 + local localbias=0 + local nominalwidth=0 + local defaultwidth=0 + local charset=false + local globals=false + local locals=false + local depth=1 + local xmin=0 + local xmax=0 + local ymin=0 + local ymax=0 + local checked=false + local keepcurve=false + local version=2 + local regions=false + local nofregions=0 + local region=false + local factors=false + local axis=false + local vsindex=0 + local function showstate(where) + report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) + end + local function showvalue(where,value,showstack) + if showstack then + report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top) + else + report("%w%-10s : %s",depth*2,where,tostring(value)) end - local p_short=P("\28")*C(1)*C(1)/function(b1,b2) - top=top+1 - local n=0x100*byte(b1)+byte(b2) - if n>=0x8000 then - stack[top]=n-0xFFFF-1 - else - stack[top]=n - end + end + local function xymoveto() + if keepcurve then + r=r+1 + result[r]={ x,y,"m" } end - local p_long=P("\29")*C(1)*C(1)*C(1)*C(1)/function(b1,b2,b3,b4) - top=top+1 - local n=0x1000000*byte(b1)+0x10000*byte(b2)+0x100*byte(b3)+byte(b4) - if n>=0x8000000 then - stack[top]=n-0xFFFFFFFF-1 + if checked then + if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("rmoveto") + end + x=x+stack[top-1] + y=y+stack[top] + top=0 + xymoveto() + end + local function hmoveto() + if not width then + if top>1 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("hmoveto") + end + x=x+stack[top] + top=0 + xmoveto() + end + local function vmoveto() + if not width then + if top>1 then + width=stack[1] + if trace_charstrings then + showvalue("backtrack width",width) + end + else + width=true + end + end + if trace_charstrings then + showstate("vmoveto") + end + y=y+stack[top] + top=0 + ymoveto() + end + local function rlineto() + if trace_charstrings then + showstate("rlineto") + end + for i=1,top,2 do + x=x+stack[i] + y=y+stack[i+1] + xylineto() + end + top=0 + end + local function hlineto() + if trace_charstrings then + showstate("hlineto") + end + if top==1 then + x=x+stack[1] + xlineto() + else + local swap=true + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false else - stack[top]=n + y=y+stack[i] + ylineto() + swap=true end + end end - local p_unsupported=P(1)/function(detail) - top=0 + top=0 + end + local function vlineto() + if trace_charstrings then + showstate("vlineto") end - local p_dictionary=( - p_byte+p_positive+p_negative+p_short+p_long+p_nibbles+p_single+p_double+p_unsupported - )^1 - parsedictionaries=function(data,dictionaries,what) - stack={} - strings=data.strings - for i=1,#dictionaries do - top=0 - result=what=="cff" and { - monospaced=false, - italicangle=0, - underlineposition=-100, - underlinethickness=50, - painttype=0, - charstringtype=2, - fontmatrix={ 0.001,0,0,0.001,0,0 }, - fontbbox={ 0,0,0,0 }, - strokewidth=0, - charset=0, - encoding=0, - cid={ - fontversion=0, - fontrevision=0, - fonttype=0, - count=8720, - } - } or { - charstringtype=2, - charset=0, - vstore=0, - cid={ - }, - } - lpegmatch(p_dictionary,dictionaries[i]) - dictionaries[i]=result - end - result={} - top=0 - stack={} - end - parseprivates=function(data,dictionaries) - stack={} - strings=data.strings - for i=1,#dictionaries do - local private=dictionaries[i].private - if private and private.data then - top=0 - result={ - forcebold=false, - languagegroup=0, - expansionfactor=0.06, - initialrandomseed=0, - subroutines=0, - defaultwidthx=0, - nominalwidthx=0, - cid={ - }, - } - lpegmatch(p_dictionary,private.data) - private.data=result - end - end - result={} - top=0 - stack={} - end - local x=0 - local y=0 - local width=false - local r=0 - local stems=0 - local globalbias=0 - local localbias=0 - local nominalwidth=0 - local defaultwidth=0 - local charset=false - local globals=false - local locals=false - local depth=1 - local xmin=0 - local xmax=0 - local ymin=0 - local ymax=0 - local checked=false - local keepcurve=false - local version=2 - local regions=false - local nofregions=0 - local region=false - local factors=false - local axis=false - local vsindex=0 - local function showstate(where) - report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) - end - local function showvalue(where,value,showstack) - if showstack then - report("%w%-10s : %s : [%s] n=%i",depth*2,where,tostring(value),concat(stack," ",1,top),top) - else - report("%w%-10s : %s",depth*2,where,tostring(value)) - end - end - local function xymoveto() - if keepcurve then - r=r+1 - result[r]={ x,y,"m" } - end - if checked then - if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then - xmax=x - elseif xymax then - ymax=y - elseif yxmax then xmax=x elseif xymax then ymax=y elseif yxmax then - xmax=x - elseif xymax then - ymax=y - elseif yxmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("rmoveto") - end - x=x+stack[top-1] - y=y+stack[top] - top=0 - xymoveto() - end - local function hmoveto() - if not width then - if top>1 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("hmoveto") - end - x=x+stack[top] - top=0 - xmoveto() - end - local function vmoveto() - if not width then - if top>1 then - width=stack[1] - if trace_charstrings then - showvalue("backtrack width",width) - end - else - width=true - end - end - if trace_charstrings then - showstate("vmoveto") - end - y=y+stack[top] - top=0 - ymoveto() - end - local function rlineto() - if trace_charstrings then - showstate("rlineto") - end - for i=1,top,2 do - x=x+stack[i] - y=y+stack[i+1] - xylineto() - end - top=0 - end - local function hlineto() - if trace_charstrings then - showstate("hlineto") - end - if top==1 then - x=x+stack[1] - xlineto() + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 + end + local function rrcurveto() + if trace_charstrings then + showstate("rrcurveto") + end + for i=1,top,6 do + local ax=x+stack[i] + local ay=y+stack[i+1] + local bx=ax+stack[i+2] + local by=ay+stack[i+3] + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function hhcurveto() + if trace_charstrings then + showstate("hhcurveto") + end + local s=1 + if top%2~=0 then + y=y+stack[1] + s=2 + end + for i=s,top,4 do + local ax=x+stack[i] + local ay=y + local bx=ax+stack[i+1] + local by=ay+stack[i+2] + x=bx+stack[i+3] + y=by + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function vvcurveto() + if trace_charstrings then + showstate("vvcurveto") + end + local s=1 + local d=0 + if top%2~=0 then + d=stack[1] + s=2 + end + for i=s,top,4 do + local ax=x+d + local ay=y+stack[i] + local bx=ax+stack[i+1] + local by=ay+stack[i+2] + x=bx + y=by+stack[i+3] + xycurveto(ax,ay,bx,by,x,y) + d=0 + end + top=0 + end + local function xxcurveto(swap) + local last=top%4~=0 and stack[top] + if last then + top=top-1 + end + for i=1,top,4 do + local ax,ay,bx,by + if swap then + ax=x+stack[i] + ay=y + bx=ax+stack[i+1] + by=ay+stack[i+2] + y=by+stack[i+3] + if last and i+3==top then + x=bx+last else - local swap=true - for i=1,top do - if swap then - x=x+stack[i] - xlineto() - swap=false - else - y=y+stack[i] - ylineto() - swap=true - end - end - end - top=0 - end - local function vlineto() - if trace_charstrings then - showstate("vlineto") - end - if top==1 then - y=y+stack[1] - ylineto() + x=bx + end + swap=false + else + ax=x + ay=y+stack[i] + bx=ax+stack[i+1] + by=ay+stack[i+2] + x=bx+stack[i+3] + if last and i+3==top then + y=by+last else - local swap=false - for i=1,top do - if swap then - x=x+stack[i] - xlineto() - swap=false - else - y=y+stack[i] - ylineto() - swap=true - end - end - end - top=0 - end - local function rrcurveto() + y=by + end + swap=true + end + xycurveto(ax,ay,bx,by,x,y) + end + top=0 + end + local function hvcurveto() + if trace_charstrings then + showstate("hvcurveto") + end + xxcurveto(true) + end + local function vhcurveto() + if trace_charstrings then + showstate("vhcurveto") + end + xxcurveto(false) + end + local function rcurveline() + if trace_charstrings then + showstate("rcurveline") + end + for i=1,top-2,6 do + local ax=x+stack[i] + local ay=y+stack[i+1] + local bx=ax+stack[i+2] + local by=ay+stack[i+3] + x=bx+stack[i+4] + y=by+stack[i+5] + xycurveto(ax,ay,bx,by,x,y) + end + x=x+stack[top-1] + y=y+stack[top] + xylineto() + top=0 + end + local function rlinecurve() + if trace_charstrings then + showstate("rlinecurve") + end + if top>6 then + for i=1,top-6,2 do + x=x+stack[i] + y=y+stack[i+1] + xylineto() + end + end + local ax=x+stack[top-5] + local ay=y+stack[top-4] + local bx=ax+stack[top-3] + local by=ay+stack[top-2] + x=bx+stack[top-1] + y=by+stack[top] + xycurveto(ax,ay,bx,by,x,y) + top=0 + end + local function flex() + if trace_charstrings then + showstate("flex") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by+stack[6] + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[7] + local dy=cy+stack[8] + local ex=dx+stack[9] + local ey=dy+stack[10] + x=ex+stack[11] + y=ey+stack[12] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function hflex() + if trace_charstrings then + showstate("hflex") + end + local ax=x+stack[1] + local ay=y + local bx=ax+stack[2] + local by=ay+stack[3] + local cx=bx+stack[4] + local cy=by + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[5] + local dy=by + local ex=dx+stack[6] + local ey=y + x=ex+stack[7] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function hflex1() + if trace_charstrings then + showstate("hflex1") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[6] + local dy=by + local ex=dx+stack[7] + local ey=dy+stack[8] + x=ex+stack[9] + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function flex1() + if trace_charstrings then + showstate("flex1") + end + local ax=x+stack[1] + local ay=y+stack[2] + local bx=ax+stack[3] + local by=ay+stack[4] + local cx=bx+stack[5] + local cy=by+stack[6] + xycurveto(ax,ay,bx,by,cx,cy) + local dx=cx+stack[7] + local dy=cy+stack[8] + local ex=dx+stack[9] + local ey=dy+stack[10] + if abs(ex-x)>abs(ey-y) then + x=ex+stack[11] + else + y=ey+stack[11] + end + xycurveto(dx,dy,ex,ey,x,y) + top=0 + end + local function getstem() + if top==0 then + elseif top%2~=0 then + if width then + remove(stack,1) + else + width=remove(stack,1) if trace_charstrings then - showstate("rrcurveto") - end - for i=1,top,6 do - local ax=x+stack[i] - local ay=y+stack[i+1] - local bx=ax+stack[i+2] - local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function hhcurveto() + showvalue("width",width) + end + end + top=top-1 + end + if trace_charstrings then + showstate("stem") + end + stems=stems+idiv(top,2) + top=0 + end + local function getmask() + if top==0 then + elseif top%2~=0 then + if width then + remove(stack,1) + else + width=remove(stack,1) if trace_charstrings then - showstate("hhcurveto") - end - local s=1 - if top%2~=0 then - y=y+stack[1] - s=2 - end - for i=s,top,4 do - local ax=x+stack[i] - local ay=y - local bx=ax+stack[i+1] - local by=ay+stack[i+2] - x=bx+stack[i+3] - y=by - xycurveto(ax,ay,bx,by,x,y) + showvalue("width",width) end - top=0 + end + top=top-1 end - local function vvcurveto() - if trace_charstrings then - showstate("vvcurveto") - end - local s=1 - local d=0 - if top%2~=0 then - d=stack[1] - s=2 - end - for i=s,top,4 do - local ax=x+d - local ay=y+stack[i] - local bx=ax+stack[i+1] - local by=ay+stack[i+2] - x=bx - y=by+stack[i+3] - xycurveto(ax,ay,bx,by,x,y) - d=0 - end - top=0 + if trace_charstrings then + showstate(operator==19 and "hintmark" or "cntrmask") end - local function xxcurveto(swap) - local last=top%4~=0 and stack[top] - if last then - top=top-1 - end - for i=1,top,4 do - local ax,ay,bx,by - if swap then - ax=x+stack[i] - ay=y - bx=ax+stack[i+1] - by=ay+stack[i+2] - y=by+stack[i+3] - if last and i+3==top then - x=bx+last - else - x=bx - end - swap=false + stems=stems+idiv(top,2) + top=0 + if stems==0 then + elseif stems<=8 then + return 1 + else + return idiv(stems+7,8) + end + end + local function unsupported(t) + if trace_charstrings then + showstate("unsupported "..t) + end + top=0 + end + local function unsupportedsub(t) + if trace_charstrings then + showstate("unsupported sub "..t) + end + top=0 + end + local function getstem3() + if trace_charstrings then + showstate("stem3") + end + top=0 + end + local function divide() + if version==1 then + local d=stack[top] + top=top-1 + stack[top]=stack[top]/d + end + end + local function closepath() + if version==1 then + if trace_charstrings then + showstate("closepath") + end + end + top=0 + end + local function hsbw() + if version==1 then + if trace_charstrings then + showstate("hsbw") + end + width=stack[top] + end + top=0 + end + local function seac() + if version==1 then + if trace_charstrings then + showstate("seac") + end + end + top=0 + end + local function sbw() + if version==1 then + if trace_charstrings then + showstate("sbw") + end + width=stack[top-1] + end + top=0 + end + local function callothersubr() + if version==1 then + if trace_charstrings then + showstate("callothersubr (unsupported)") + end + end + top=0 + end + local function pop() + if version==1 then + if trace_charstrings then + showstate("pop (unsupported)") + end + top=top+1 + stack[top]=0 + else + top=0 + end + end + local function setcurrentpoint() + if version==1 then + if trace_charstrings then + showstate("pop (unsupported)") + end + x=x+stack[top-1] + y=y+stack[top] + end + top=0 + end + local reginit=false + local function updateregions(n) + if regions then + local current=regions[n] or regions[1] + nofregions=#current + if axis and n~=reginit then + factors={} + for i=1,nofregions do + local region=current[i] + local s=1 + for j=1,#axis do + local f=axis[j] + local r=region[j] + local start=r.start + local peak=r.peak + local stop=r.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) else - ax=x - ay=y+stack[i] - bx=ax+stack[i+1] - by=ay+stack[i+2] - x=bx+stack[i+3] - if last and i+3==top then - y=by+last - else - y=by - end - swap=true end - xycurveto(ax,ay,bx,by,x,y) - end - top=0 - end - local function hvcurveto() - if trace_charstrings then - showstate("hvcurveto") - end - xxcurveto(true) - end - local function vhcurveto() - if trace_charstrings then - showstate("vhcurveto") + end + factors[i]=s + end + end + end + reginit=n + end + local function setvsindex() + local vsindex=stack[top] + if trace_charstrings then + showstate(formatters["vsindex %i"](vsindex)) + end + updateregions(vsindex) + top=top-1 + end + local function blend() + local n=stack[top] + top=top-1 + if axis then + if trace_charstrings then + local t=top-nofregions*n + local m=t-n + for i=1,n do + local k=m+i + local d=m+n+(i-1)*nofregions + local old=stack[k] + local new=old + for r=1,nofregions do + new=new+stack[d+r]*factors[r] + end + stack[k]=new + showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) + end + top=t + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=v + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=v + d=d+nofregions end - xxcurveto(false) + end + else end - local function rcurveline() - if trace_charstrings then - showstate("rcurveline") - end - for i=1,top-2,6 do - local ax=x+stack[i] - local ay=y+stack[i+1] - local bx=ax+stack[i+2] - local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] - xycurveto(ax,ay,bx,by,x,y) - end - x=x+stack[top-1] - y=y+stack[top] - xylineto() - top=0 + end + local actions={ [0]=unsupported, + getstem, + unsupported, + getstem, + vmoveto, + rlineto, + hlineto, + vlineto, + rrcurveto, + unsupported, + unsupported, + unsupported, + unsupported, + hsbw, + unsupported, + setvsindex, + blend, + unsupported, + getstem, + getmask, + getmask, + rmoveto, + hmoveto, + getstem, + rcurveline, + rlinecurve, + vvcurveto, + hhcurveto, + unsupported, + unsupported, + vhcurveto, + hvcurveto, + } + local subactions={ + [000]=dotsection, + [001]=getstem3, + [002]=getstem3, + [006]=seac, + [007]=sbw, + [012]=divide, + [016]=callothersubr, + [017]=pop, + [033]=setcurrentpoint, + [034]=hflex, + [035]=flex, + [036]=hflex1, + [037]=flex1, + } + local chars=setmetatableindex(function (t,k) + local v=char(k) + t[k]=v + return v + end) + local c_endchar=chars[14] + local encode={} + setmetatableindex(encode,function(t,i) + for i=-2048,-1130 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + for i=-1131,-108 do + local v=0xFB00-i-108 + t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) + end + for i=-107,107 do + t[i]=chars[i+139] + end + for i=108,1131 do + local v=0xF700+i-108 + t[i]=char(extract(v,8,8),extract(v,0,8)) + end + for i=1132,2048 do + t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) + end + setmetatableindex(encode,function(t,k) + local r=round(k) + local v=rawget(t,r) + if v then + return v + end + local v1=floor(k) + local v2=floor((k-v1)*0x10000) + return char(255,extract(v1,8,8),extract(v1,0,8),extract(v2,8,8),extract(v2,0,8)) + end) + return t[i] + end) + readers.cffencoder=encode + local function p_setvsindex() + local vsindex=stack[top] + updateregions(vsindex) + top=top-1 + end + local function p_blend() + local n=stack[top] + top=top-1 + if not axis then + elseif n==1 then + top=top-nofregions + local v=stack[top] + for r=1,nofregions do + v=v+stack[top+r]*factors[r] + end + stack[top]=round(v) + else + top=top-nofregions*n + local d=top + local k=top-n + for i=1,n do + k=k+1 + local v=stack[k] + for r=1,nofregions do + v=v+stack[d+r]*factors[r] + end + stack[k]=round(v) + d=d+nofregions + end + end + end + local function p_getstem() + local n=0 + if top%2~=0 then + n=1 end - local function rlinecurve() - if trace_charstrings then - showstate("rlinecurve") - end - if top>6 then - for i=1,top-6,2 do - x=x+stack[i] - y=y+stack[i+1] - xylineto() - end - end - local ax=x+stack[top-5] - local ay=y+stack[top-4] - local bx=ax+stack[top-3] - local by=ay+stack[top-2] - x=bx+stack[top-1] - y=by+stack[top] - xycurveto(ax,ay,bx,by,x,y) - top=0 + if top>n then + stems=stems+idiv(top-n,2) end - local function flex() - if trace_charstrings then - showstate("flex") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by+stack[6] - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[7] - local dy=cy+stack[8] - local ex=dx+stack[9] - local ey=dy+stack[10] - x=ex+stack[11] - y=ey+stack[12] - xycurveto(dx,dy,ex,ey,x,y) - top=0 + end + local function p_getmask() + local n=0 + if top%2~=0 then + n=1 end - local function hflex() - if trace_charstrings then - showstate("hflex") - end - local ax=x+stack[1] - local ay=y - local bx=ax+stack[2] - local by=ay+stack[3] - local cx=bx+stack[4] - local cy=by - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[5] - local dy=by - local ex=dx+stack[6] - local ey=y - x=ex+stack[7] - xycurveto(dx,dy,ex,ey,x,y) - top=0 + if top>n then + stems=stems+idiv(top-n,2) end - local function hflex1() - if trace_charstrings then - showstate("hflex1") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[6] - local dy=by - local ex=dx+stack[7] - local ey=dy+stack[8] - x=ex+stack[9] - xycurveto(dx,dy,ex,ey,x,y) + if stems==0 then + return 0 + elseif stems<=8 then + return 1 + else + return idiv(stems+7,8) + end + end + local process + local function call(scope,list,bias) + depth=depth+1 + if top==0 then + showstate(formatters["unknown %s call"](scope)) + top=0 + else + local index=stack[top]+bias + top=top-1 + if trace_charstrings then + showvalue(scope,index,true) + end + local tab=list[index] + if tab then + process(tab) + else + showstate(formatters["unknown %s call %i"](scope,index)) top=0 + end end - local function flex1() - if trace_charstrings then - showstate("flex1") - end - local ax=x+stack[1] - local ay=y+stack[2] - local bx=ax+stack[3] - local by=ay+stack[4] - local cx=bx+stack[5] - local cy=by+stack[6] - xycurveto(ax,ay,bx,by,cx,cy) - local dx=cx+stack[7] - local dy=cy+stack[8] - local ex=dx+stack[9] - local ey=dy+stack[10] - if abs(ex-x)>abs(ey-y) then - x=ex+stack[11] + depth=depth-1 + end + local justpass=false + process=function(tab) + local i=1 + local n=#tab + while i<=n do + local t=tab[i] + if t>=32 then + top=top+1 + if t<=246 then + stack[top]=t-139 + i=i+1 + elseif t<=250 then + stack[top]=t*256-63124+tab[i+1] + i=i+2 + elseif t<=254 then + stack[top]=-t*256+64148-tab[i+1] + i=i+2 else - y=ey+stack[11] - end - xycurveto(dx,dy,ex,ey,x,y) - top=0 - end - local function getstem() - if top==0 then - elseif top%2~=0 then - if width then - remove(stack,1) - else - width=remove(stack,1) - if trace_charstrings then - showvalue("width",width) - end - end - top=top-1 - end - if trace_charstrings then - showstate("stem") - end - stems=stems+top/2 - top=0 - end - local function getmask() - if top==0 then - elseif top%2~=0 then - if width then - remove(stack,1) - else - width=remove(stack,1) - if trace_charstrings then - showvalue("width",width) - end - end - top=top-1 - end - if trace_charstrings then - showstate(operator==19 and "hintmark" or "cntrmask") + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF + else + stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF + end + i=i+5 end - stems=stems+top/2 - top=0 - if stems==0 then - elseif stems<=8 then - return 1 + elseif t==28 then + top=top+1 + local n=0x100*tab[i+1]+tab[i+2] + if n>=0x8000 then + stack[top]=n-0x10000 else - return floor((stems+7)/8) + stack[top]=n end - end - local function unsupported(t) + i=i+3 + elseif t==11 then if trace_charstrings then - showstate("unsupported "..t) + showstate("return") end - top=0 - end - local function unsupportedsub(t) - if trace_charstrings then - showstate("unsupported sub "..t) + return + elseif t==10 then + call("local",locals,localbias) + i=i+1 + elseif t==14 then + if width then + elseif top>0 then + width=stack[1] + if trace_charstrings then + showvalue("width",width) + end + else + width=true end - top=0 - end - local function getstem3() if trace_charstrings then - showstate("stem3") - end - top=0 - end - local function divide() - if version==1 then - local d=stack[top] - top=top-1 - stack[top]=stack[top]/d - end - end - local function closepath() - if version==1 then - if trace_charstrings then - showstate("closepath") - end - end - top=0 - end - local function hsbw() - if version==1 then - if trace_charstrings then - showstate("dotsection") - end - width=stack[top] + showstate("endchar") end - top=0 - end - local function seac() - if version==1 then - if trace_charstrings then - showstate("seac") + return + elseif t==29 then + call("global",globals,globalbias) + i=i+1 + elseif t==12 then + i=i+1 + local t=tab[i] + if justpass then + if t>=34 or t<=37 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] end - end - top=0 - end - local function sbw() - if version==1 then - if trace_charstrings then - showstate("sbw") + r=r+1;result[r]=chars[12] + r=r+1;result[r]=chars[t] + top=0 + else + local a=subactions[t] + if a then + a(t) + else + top=0 end - width=stack[top-1] - end - top=0 - end - local function callothersubr() - if version==1 then + end + else + local a=subactions[t] + if a then + a(t) + else if trace_charstrings then - showstate("callothersubr (unsupported)") + showvalue("",t) end + top=0 + end end - top=0 - end - local function pop() - if version==1 then - if trace_charstrings then - showstate("pop (unsupported)") + i=i+1 + elseif justpass then + if t==15 then + p_setvsindex() + i=i+1 + elseif t==16 then + local s=p_blend() or 0 + i=i+s+1 + elseif t==1 or t==3 or t==18 or operation==23 then + p_getstem() +if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] end - top=top+1 - stack[top]=0 - else top=0 - end - end - local function setcurrentpoint() - if version==1 then - if trace_charstrings then - showstate("pop (unsupported)") + end + r=r+1;result[r]=chars[t] +else + top=0 +end + i=i+1 + elseif t==19 or t==20 then + local s=p_getmask() or 0 +if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] end - x=x+stack[top-1] - y=y+stack[top] - end - top=0 - end - local reginit=false - local function updateregions(n) - if regions then - local current=regions[n] or regions[1] - nofregions=#current - if axis and n~=reginit then - factors={} - for i=1,nofregions do - local region=current[i] - local s=1 - for j=1,#axis do - local f=axis[j] - local r=region[j] - local start=r.start - local peak=r.peak - local stop=r.stop - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - factors[i]=s - end + top=0 + end + r=r+1;result[r]=chars[t] + for j=1,s do + i=i+1 + r=r+1;result[r]=chars[tab[i]] + end +else + i=i+s + top=0 +end + i=i+1 + elseif t==9 then + top=0 + i=i+1 + elseif t==13 then + local s=hsbw() or 0 + i=i+s+1 + else + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] end + top=0 + end + r=r+1;result[r]=chars[t] + i=i+1 end - reginit=n - end - local function setvsindex() - local vsindex=stack[top] - if trace_charstrings then - showstate(formatters["vsindex %i"](vsindex)) - end - updateregions(vsindex) - top=top-1 - end - local function blend() - local n=stack[top] - top=top-1 - if axis then - if trace_charstrings then - local t=top-nofregions*n - local m=t-n - for i=1,n do - local k=m+i - local d=m+n+(i-1)*nofregions - local old=stack[k] - local new=old - for r=1,nofregions do - new=new+stack[d+r]*factors[r] - end - stack[k]=new - showstate(formatters["blend %i of %i: %s -> %s"](i,n,old,new)) - end - top=t - elseif n==1 then - top=top-nofregions - local v=stack[top] - for r=1,nofregions do - v=v+stack[top+r]*factors[r] - end - stack[top]=v - else - top=top-nofregions*n - local d=top - local k=top-n - for i=1,n do - k=k+1 - local v=stack[k] - for r=1,nofregions do - v=v+stack[d+r]*factors[r] - end - stack[k]=v - d=d+nofregions - end - end + else + local a=actions[t] + if a then + local s=a(t) + if s then + i=i+s+1 + else + i=i+1 + end else - end - end - local actions={ [0]=unsupported, - getstem, - unsupported, - getstem, - vmoveto, - rlineto, - hlineto, - vlineto, - rrcurveto, - unsupported, - unsupported, - unsupported, - unsupported, - hsbw, - unsupported, - setvsindex, - blend, - unsupported, - getstem, - getmask, - getmask, - rmoveto, - hmoveto, - getstem, - rcurveline, - rlinecurve, - vvcurveto, - hhcurveto, - unsupported, - unsupported, - vhcurveto, - hvcurveto, + if trace_charstrings then + showvalue("",t) + end + top=0 + i=i+1 + end + end + end + end + local function setbias(globals,locals) + local g=#globals + local l=#locals + return + ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, + ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 + end + local function processshape(tab,index) + if not tab then + glyphs[index]={ + boundingbox={ 0,0,0,0 }, + width=0, + name=charset and charset[index] or nil, + } + return + end + tab=bytetable(tab) + x=0 + y=0 + width=false + r=0 + top=0 + stems=0 + result={} + xmin=0 + xmax=0 + ymin=0 + ymax=0 + checked=false + if trace_charstrings then + report("glyph: %i",index) + report("data : % t",tab) + end + if regions then + updateregions(vsindex) + end + process(tab) + local boundingbox={ + round(xmin), + round(ymin), + round(xmax), + round(ymax), } - local subactions={ - [000]=dotsection, - [001]=getstem3, - [002]=getstem3, - [006]=seac, - [007]=sbw, - [012]=divide, - [016]=callothersubr, - [017]=pop, - [033]=setcurrentpoint, - [034]=hflex, - [035]=flex, - [036]=hflex1, - [037]=flex1, - } - local c_endchar=char(14) - local passon do - local rshift=bit32.rshift - local band=bit32.band - local round=math.round - local encode=table.setmetatableindex(function(t,i) - for i=-2048,-1130 do - t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - for i=-1131,-108 do - local v=0xFB00-i-108 - t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) - end - for i=-107,107 do - t[i]=char(i+139) - end - for i=108,1131 do - local v=0xF700+i-108 - t[i]=char(band(rshift(v,8),0xFF),band(v,0xFF)) - end - for i=1132,2048 do - t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF)) - end - return t[i] - end) - local function setvsindex() - local vsindex=stack[top] - updateregions(vsindex) - top=top-1 - end - local function blend() - local n=stack[top] - top=top-1 - if not axis then - elseif n==1 then - top=top-nofregions - local v=stack[top] - for r=1,nofregions do - v=v+stack[top+r]*factors[r] - end - stack[top]=round(v) - else - top=top-nofregions*n - local d=top - local k=top-n - for i=1,n do - k=k+1 - local v=stack[k] - for r=1,nofregions do - v=v+stack[d+r]*factors[r] - end - stack[k]=round(v) - d=d+nofregions - end - end - end - passon=function(operation) - if operation==15 then - setvsindex() - elseif operation==16 then - blend() - else - for i=1,top do - r=r+1 - result[r]=encode[stack[i]] - end - r=r+1 - result[r]=char(operation) - top=0 - end - end - end - local process - local function call(scope,list,bias) - depth=depth+1 - if top==0 then - showstate(formatters["unknown %s call"](scope)) - top=0 - else - local index=stack[top]+bias - top=top-1 - if trace_charstrings then - showvalue(scope,index,true) - end - local tab=list[index] - if tab then - process(tab) - else - showstate(formatters["unknown %s call %i"](scope,index)) - top=0 - end - end - depth=depth-1 - end - local justpass=false - process=function(tab) - local i=1 - local n=#tab - while i<=n do - local t=tab[i] - if t>=32 then - top=top+1 - if t<=246 then - stack[top]=t-139 - i=i+1 - elseif t<=250 then - stack[top]=t*256-63124+tab[i+1] - i=i+2 - elseif t<=254 then - stack[top]=-t*256+64148-tab[i+1] - i=i+2 - else - local n=0x100*tab[i+1]+tab[i+2] - if n>=0x8000 then - stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF - else - stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF - end - i=i+5 - end - elseif t==28 then - top=top+1 - local n=0x100*tab[i+1]+tab[i+2] - if n>=0x8000 then - stack[top]=n-0x10000 - else - stack[top]=n - end - i=i+3 - elseif t==11 then - if trace_charstrings then - showstate("return") - end - return - elseif t==10 then - call("local",locals,localbias) - i=i+1 - elseif t==14 then - if width then - elseif top>0 then - width=stack[1] - if trace_charstrings then - showvalue("width",width) - end - else - width=true - end - if trace_charstrings then - showstate("endchar") - end - return - elseif t==29 then - call("global",globals,globalbias) - i=i+1 - elseif t==12 then - i=i+1 - local t=tab[i] - local a=subactions[t] - if a then - a(t) - else - if trace_charstrings then - showvalue("",t) - end - top=0 - end - i=i+1 - elseif justpass then - passon(t) - i=i+1 - else - local a=actions[t] - if a then - local s=a(t) - if s then - i=i+s+1 - else - i=i+1 - end - else - if trace_charstrings then - showvalue("",t) - end - top=0 - i=i+1 - end - end - end - end - local function setbias(globals,locals) - if version==1 then - return - false, - false - else - local g,l=#globals,#locals - return - ((g<1240 and 107) or (g<33900 and 1131) or 32768)+1, - ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 - end - end - local function processshape(tab,index) - tab=bytetable(tab) - x=0 - y=0 - width=false - r=0 - top=0 - stems=0 - result={} - xmin=0 - xmax=0 - ymin=0 - ymax=0 - checked=false - if trace_charstrings then - report("glyph: %i",index) - report("data : % t",tab) - end - if regions then - updateregions(vsindex) - end - process(tab) - local boundingbox={ - round(xmin), - round(ymin), - round(xmax), - round(ymax), - } - if width==true or width==false then - width=defaultwidth - else - width=nominalwidth+width - end - local glyph=glyphs[index] - if justpass then - r=r+1 - result[r]=c_endchar - local stream=concat(result) - if glyph then - glyph.stream=stream - else - glyphs[index]={ stream=stream } - end - elseif glyph then - glyph.segments=keepcurve~=false and result or nil - glyph.boundingbox=boundingbox - if not glyph.width then - glyph.width=width - end - if charset and not glyph.name then - glyph.name=charset[index] - end - elseif keepcurve then - glyphs[index]={ - segments=result, - boundingbox=boundingbox, - width=width, - name=charset and charset[index] or nil, - } - else - glyphs[index]={ - boundingbox=boundingbox, - width=width, - name=charset and charset[index] or nil, - } - end - if trace_charstrings then - report("width : %s",tostring(width)) - report("boundingbox: % t",boundingbox) - end - end - startparsing=function(fontdata,data,streams) - reginit=false - axis=false - regions=data.regions - justpass=streams==true - if regions then - regions={ regions } - axis=data.factors or false - end - end - stopparsing=function(fontdata,data) - stack={} - glyphs=false - result={} - top=0 - locals=false - globals=false - strings=false - end - local function setwidths(private) - if not private then - return 0,0 - end - local privatedata=private.data - if not privatedata then - return 0,0 - end - return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 - end - parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams) - local dictionary=data.dictionaries[1] - local charstrings=dictionary.charstrings - keepcurve=doshapes - version=tversion - strings=data.strings - globals=data.routines or {} - locals=dictionary.subroutines or {} - charset=dictionary.charset - vsindex=dictionary.vsindex or 0 - glyphs=glphs or {} - globalbias,localbias=setbias(globals,locals) - nominalwidth,defaultwidth=setwidths(dictionary.private) - startparsing(fontdata,data,streams) - for index=1,#charstrings do - processshape(charstrings[index],index-1) - charstrings[index]=nil - end - stopparsing(fontdata,data) - return glyphs - end - parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion) - keepcurve=doshapes - version=tversion - strings=data.strings - globals=data.routines or {} - locals=dictionary.subroutines or {} - charset=false - vsindex=dictionary.vsindex or 0 - glyphs=glphs or {} - globalbias,localbias=setbias(globals,locals) - nominalwidth,defaultwidth=setwidths(dictionary.private) - processshape(tab,index-1) - end + if width==true or width==false then + width=defaultwidth + else + width=nominalwidth+width + end + local glyph=glyphs[index] + if justpass then + r=r+1 + result[r]=c_endchar + local stream=concat(result) + if glyph then + glyph.stream=stream + else + glyphs[index]={ stream=stream } + end + elseif glyph then + glyph.segments=keepcurve~=false and result or nil + glyph.boundingbox=boundingbox + if not glyph.width then + glyph.width=width + end + if charset and not glyph.name then + glyph.name=charset[index] + end + elseif keepcurve then + glyphs[index]={ + segments=result, + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + else + glyphs[index]={ + boundingbox=boundingbox, + width=width, + name=charset and charset[index] or nil, + } + end + if trace_charstrings then + report("width : %s",tostring(width)) + report("boundingbox: % t",boundingbox) + end + end + startparsing=function(fontdata,data,streams) + reginit=false + axis=false + regions=data.regions + justpass=streams==true + if regions then + regions={ regions } + axis=data.factors or false + end + end + stopparsing=function(fontdata,data) + stack={} + glyphs=false + result={} + top=0 + locals=false + globals=false + strings=false + end + local function setwidths(private) + if not private then + return 0,0 + end + local privatedata=private.data + if not privatedata then + return 0,0 + end + return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0 + end + parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams) + local dictionary=data.dictionaries[1] + local charstrings=dictionary.charstrings + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=dictionary.charset + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + globalbias,localbias=setbias(globals,locals) + nominalwidth,defaultwidth=setwidths(dictionary.private) + if charstrings then + startparsing(fontdata,data,streams) + for index=1,#charstrings do + processshape(charstrings[index],index-1) + end + stopparsing(fontdata,data) + else + report("no charstrings") + end + return glyphs + end + parsecharstring=function(fontdata,data,dictionary,tab,glphs,index,doshapes,tversion,streams) + keepcurve=doshapes + version=tversion + strings=data.strings + globals=data.routines or {} + locals=dictionary.subroutines or {} + charset=false + vsindex=dictionary.vsindex or 0 + glyphs=glphs or {} + justpass=streams==true + globalbias,localbias=setbias(globals,locals) + nominalwidth,defaultwidth=setwidths(dictionary.private) + processshape(tab,index-1) + end end local function readglobals(f,data) - local routines=readlengths(f) - for i=1,#routines do - routines[i]=readbytetable(f,routines[i]) - end - data.routines=routines + local routines=readlengths(f) + for i=1,#routines do + routines[i]=readbytetable(f,routines[i]) + end + data.routines=routines end local function readencodings(f,data) - data.encodings={} + data.encodings={} end local function readcharsets(f,data,dictionary) - local header=data.header - local strings=data.strings - local nofglyphs=data.nofglyphs - local charsetoffset=dictionary.charset - if charsetoffset and charsetoffset~=0 then - setposition(f,header.offset+charsetoffset) - local format=readbyte(f) - local charset={ [0]=".notdef" } - dictionary.charset=charset - if format==0 then - for i=1,nofglyphs do - charset[i]=strings[readushort(f)] - end - elseif format==1 or format==2 then - local readcount=format==1 and readbyte or readushort - local i=1 - while i<=nofglyphs do - local sid=readushort(f) - local n=readcount(f) - for s=sid,sid+n do - charset[i]=strings[s] - i=i+1 - if i>nofglyphs then - break - end - end - end - else - report("cff parser: unsupported charset format %a",format) + local header=data.header + local strings=data.strings + local nofglyphs=data.nofglyphs + local charsetoffset=dictionary.charset + if charsetoffset and charsetoffset~=0 then + setposition(f,header.offset+charsetoffset) + local format=readbyte(f) + local charset={ [0]=".notdef" } + dictionary.charset=charset + if format==0 then + for i=1,nofglyphs do + charset[i]=strings[readushort(f)] + end + elseif format==1 or format==2 then + local readcount=format==1 and readbyte or readushort + local i=1 + while i<=nofglyphs do + local sid=readushort(f) + local n=readcount(f) + for s=sid,sid+n do + charset[i]=strings[s] + i=i+1 + if i>nofglyphs then + break + end end + end else - dictionary.nocharset=true - dictionary.charset=nil + report("cff parser: unsupported charset format %a",format) end + else + dictionary.nocharset=true + dictionary.charset=nil + end end local function readprivates(f,data) - local header=data.header - local dictionaries=data.dictionaries - local private=dictionaries[1].private - if private then - setposition(f,header.offset+private.offset) - private.data=readstring(f,private.size) - end + local header=data.header + local dictionaries=data.dictionaries + local private=dictionaries[1].private + if private then + setposition(f,header.offset+private.offset) + private.data=readstring(f,private.size) + end end local function readlocals(f,data,dictionary) - local header=data.header - local private=dictionary.private - if private then - local subroutineoffset=private.data.subroutines - if subroutineoffset~=0 then - setposition(f,header.offset+private.offset+subroutineoffset) - local subroutines=readlengths(f) - for i=1,#subroutines do - subroutines[i]=readbytetable(f,subroutines[i]) - end - dictionary.subroutines=subroutines - private.data.subroutines=nil - else - dictionary.subroutines={} - end + local header=data.header + local private=dictionary.private + if private then + local subroutineoffset=private.data.subroutines + if subroutineoffset~=0 then + setposition(f,header.offset+private.offset+subroutineoffset) + local subroutines=readlengths(f) + for i=1,#subroutines do + subroutines[i]=readbytetable(f,subroutines[i]) + end + dictionary.subroutines=subroutines + private.data.subroutines=nil else - dictionary.subroutines={} + dictionary.subroutines={} end + else + dictionary.subroutines={} + end end local function readcharstrings(f,data,what) - local header=data.header - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local stringtype=dictionary.charstringtype - local offset=dictionary.charstrings - if type(offset)~="number" then - elseif stringtype==2 then - setposition(f,header.offset+offset) - local charstrings=readlengths(f,what=="cff2") - local nofglyphs=#charstrings - for i=1,nofglyphs do - charstrings[i]=readstring(f,charstrings[i]) - end - data.nofglyphs=nofglyphs - dictionary.charstrings=charstrings - else - report("unsupported charstr type %i",stringtype) - data.nofglyphs=0 - dictionary.charstrings={} - end + local header=data.header + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local stringtype=dictionary.charstringtype + local offset=dictionary.charstrings + if type(offset)~="number" then + elseif stringtype==2 then + setposition(f,header.offset+offset) + local charstrings=readlengths(f,what=="cff2") + local nofglyphs=#charstrings + for i=1,nofglyphs do + charstrings[i]=readstring(f,charstrings[i]) + end + data.nofglyphs=nofglyphs + dictionary.charstrings=charstrings + else + report("unsupported charstr type %i",stringtype) + data.nofglyphs=0 + dictionary.charstrings={} + end end local function readcidprivates(f,data) - local header=data.header - local dictionaries=data.dictionaries[1].cid.dictionaries - for i=1,#dictionaries do - local dictionary=dictionaries[i] - local private=dictionary.private - if private then - setposition(f,header.offset+private.offset) - private.data=readstring(f,private.size) - end + local header=data.header + local dictionaries=data.dictionaries[1].cid.dictionaries + for i=1,#dictionaries do + local dictionary=dictionaries[i] + local private=dictionary.private + if private then + setposition(f,header.offset+private.offset) + private.data=readstring(f,private.size) end - parseprivates(data,dictionaries) + end + parseprivates(data,dictionaries) end readers.parsecharstrings=parsecharstrings local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams) - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - readglobals(f,data) - readcharstrings(f,data,version) - if version=="cff2" then - dictionary.charset=nil - else - readencodings(f,data) - readcharsets(f,data,dictionary) - end - readprivates(f,data) - parseprivates(data,data.dictionaries) - readlocals(f,data,dictionary) - startparsing(fontdata,data,streams) - parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) - stopparsing(fontdata,data) + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + readglobals(f,data) + readcharstrings(f,data,version) + if version=="cff2" then + dictionary.charset=nil + else + readencodings(f,data) + readcharsets(f,data,dictionary) + end + readprivates(f,data) + parseprivates(data,data.dictionaries) + readlocals(f,data,dictionary) + startparsing(fontdata,data,streams) + parsecharstrings(fontdata,data,glyphs,doshapes,version,streams) + stopparsing(fontdata,data) end local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams) - local header=data.header - local dictionaries=data.dictionaries - local dictionary=dictionaries[1] - local cid=dictionary.cid - local cidselect=cid and cid.fdselect - readglobals(f,data) - readcharstrings(f,data,version) - if version~="cff2" then - readencodings(f,data) - end - local charstrings=dictionary.charstrings - local fdindex={} - local nofglyphs=data.nofglyphs - local maxindex=-1 - setposition(f,header.offset+cidselect) - local format=readbyte(f) - if format==1 then - for i=0,nofglyphs do - local index=readbyte(i) - fdindex[i]=index - if index>maxindex then - maxindex=index - end - end - elseif format==3 then - local nofranges=readushort(f) - local first=readushort(f) - local index=readbyte(f) - while true do - local last=readushort(f) - if index>maxindex then - maxindex=index - end - for i=first,last do - fdindex[i]=index - end - if last>=nofglyphs then - break - else - first=last+1 - index=readbyte(f) - end - end + local header=data.header + local dictionaries=data.dictionaries + local dictionary=dictionaries[1] + local cid=dictionary.cid + local cidselect=cid and cid.fdselect + readglobals(f,data) + readcharstrings(f,data,version) + if version~="cff2" then + readencodings(f,data) + end + local charstrings=dictionary.charstrings + local fdindex={} + local nofglyphs=data.nofglyphs + local maxindex=-1 + setposition(f,header.offset+cidselect) + local format=readbyte(f) + if format==1 then + for i=0,nofglyphs do + local index=readbyte(f) + fdindex[i]=index + if index>maxindex then + maxindex=index + end + end + elseif format==3 then + local nofranges=readushort(f) + local first=readushort(f) + local index=readbyte(f) + while true do + local last=readushort(f) + if index>maxindex then + maxindex=index + end + for i=first,last do + fdindex[i]=index + end + if last>=nofglyphs then + break + else + first=last+1 + index=readbyte(f) + end + end + else + end + if maxindex>=0 then + local cidarray=cid.fdarray + if cidarray then + setposition(f,header.offset+cidarray) + local dictionaries=readlengths(f) + for i=1,#dictionaries do + dictionaries[i]=readstring(f,dictionaries[i]) + end + parsedictionaries(data,dictionaries) + cid.dictionaries=dictionaries + readcidprivates(f,data) + for i=1,#dictionaries do + readlocals(f,data,dictionaries[i]) + end + startparsing(fontdata,data,streams) + for i=1,#charstrings do + parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version,streams) + end + stopparsing(fontdata,data) else + report("no cid array") end - if maxindex>=0 then - local cidarray=cid.fdarray - setposition(f,header.offset+cidarray) - local dictionaries=readlengths(f) - for i=1,#dictionaries do - dictionaries[i]=readstring(f,dictionaries[i]) - end - parsedictionaries(data,dictionaries) - cid.dictionaries=dictionaries - readcidprivates(f,data) - for i=1,#dictionaries do - readlocals(f,data,dictionaries[i]) - end - startparsing(fontdata,data,streams) - for i=1,#charstrings do - parsecharstring(fontdata,data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) - charstrings[i]=nil - end - stopparsing(fontdata,data) - end + end end local gotodatatable=readers.helpers.gotodatatable local function cleanup(data,dictionaries) end function readers.cff(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cff",specification.details) - if tableoffset then - local header=readheader(f) - if header.major~=1 then - report("only version %s is supported for table %a",1,"cff") - return - end - local glyphs=fontdata.glyphs - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,dictionaries,"cff") - local dic=dictionaries[1] - local cid=dic.cid - fontdata.cffinfo={ - familynamename=dic.familyname, - fullname=dic.fullname, - boundingbox=dic.boundingbox, - weight=dic.weight, - italicangle=dic.italicangle, - underlineposition=dic.underlineposition, - underlinethickness=dic.underlinethickness, - monospaced=dic.monospaced, - } - fontdata.cidinfo=cid and { - registry=cid.registry, - ordering=cid.ordering, - supplement=cid.supplement, - } - if specification.glyphs then - local all=specification.shapes or false - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff") - else - readnoselect(f,fontdata,data,glyphs,all,"cff") - end - end - cleanup(data,dictionaries) + local tableoffset=gotodatatable(f,fontdata,"cff",specification.details or specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return end + local glyphs=fontdata.glyphs + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff") + local dic=dictionaries[1] + local cid=dic.cid + local cffinfo={ + familyname=dic.familyname, + fullname=dic.fullname, + boundingbox=dic.boundingbox, + weight=dic.weight, + italicangle=dic.italicangle, + underlineposition=dic.underlineposition, + underlinethickness=dic.underlinethickness, + defaultwidth=dic.defaultwidthx, + nominalwidth=dic.nominalwidthx, + monospaced=dic.monospaced, + } + fontdata.cidinfo=cid and { + registry=cid.registry, + ordering=cid.ordering, + supplement=cid.supplement, + } + fontdata.cffinfo=cffinfo + local all=specification.shapes or specification.streams or false + if specification.glyphs or all then + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff",specification.streams) + end + end + local private=dic.private + if private then + local data=private.data + if type(data)=="table" then + cffinfo.defaultwidth=data.defaultwidth or cffinfo.defaultwidth + cffinfo.nominalwidth=data.nominalwidth or cffinfo.nominalwidth + cffinfo.bluevalues=data.bluevalues + cffinfo.otherblues=data.otherblues + cffinfo.familyblues=data.familyblues + cffinfo.familyotherblues=data.familyotherblues + cffinfo.bluescale=data.bluescale + cffinfo.blueshift=data.blueshift + cffinfo.bluefuzz=data.bluefuzz + cffinfo.stdhw=data.stdhw + cffinfo.stdvw=data.stdvw + end + end + cleanup(data,dictionaries) + end end function readers.cff2(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) - if tableoffset then - local header=readheader(f) - if header.major~=2 then - report("only version %s is supported for table %a",2,"cff2") - return - end - local glyphs=fontdata.glyphs - local dictionaries={ readstring(f,header.dsize) } - local data={ - header=header, - dictionaries=dictionaries, - nofglyphs=fontdata.nofglyphs, - } - parsedictionaries(data,dictionaries,"cff2") - local offset=dictionaries[1].vstore - if offset>0 then - local storeoffset=dictionaries[1].vstore+data.header.offset+2 - local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) - data.regions=regions - data.deltas=deltas - else - data.regions={} - data.deltas={} - end - data.factors=specification.factors - local cid=data.dictionaries[1].cid - local all=specification.shapes or false - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) - else - readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) - end - cleanup(data,dictionaries) + local tableoffset=gotodatatable(f,fontdata,"cff2",specification.glyphs) + if tableoffset then + local header=readheader(f) + if header.major~=2 then + report("only version %s is supported for table %a",2,"cff2") + return + end + local glyphs=fontdata.glyphs + local dictionaries={ readstring(f,header.dsize) } + local data={ + header=header, + dictionaries=dictionaries, + nofglyphs=fontdata.nofglyphs, + } + parsedictionaries(data,dictionaries,"cff2") + local offset=dictionaries[1].vstore + if offset>0 then + local storeoffset=dictionaries[1].vstore+data.header.offset+2 + local regions,deltas=readers.helpers.readvariationdata(f,storeoffset,factors) + data.regions=regions + data.deltas=deltas + else + data.regions={} + data.deltas={} + end + data.factors=specification.factors + local cid=data.dictionaries[1].cid + local all=specification.shapes or specification.streams or false + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) + else + readnoselect(f,fontdata,data,glyphs,all,"cff2",specification.streams) end + cleanup(data,dictionaries) + end end function readers.cffcheck(filename) - local f=io.open(filename,"rb") - if f then - local fontdata={ - glyphs={}, - } - local header=readheader(f) - if header.major~=1 then - report("only version %s is supported for table %a",1,"cff") - return - end - local names=readfontnames(f) - local dictionaries=readtopdictionaries(f) - local strings=readstrings(f) - local glyphs={} - local data={ - header=header, - names=names, - dictionaries=dictionaries, - strings=strings, - glyphs=glyphs, - nofglyphs=4, - } - parsedictionaries(data,dictionaries,"cff") - local cid=data.dictionaries[1].cid - if cid and cid.fdselect then - readfdselect(f,fontdata,data,glyphs,false) - else - readnoselect(f,fontdata,data,glyphs,false) - end - return data + local f=io.open(filename,"rb") + if f then + local fontdata={ + glyphs={}, + } + local header=readheader(f) + if header.major~=1 then + report("only version %s is supported for table %a",1,"cff") + return + end + local names=readfontnames(f) + local dictionaries=readtopdictionaries(f) + local strings=readstrings(f) + local glyphs={} + local data={ + header=header, + names=names, + dictionaries=dictionaries, + strings=strings, + glyphs=glyphs, + nofglyphs=0, + } + parsedictionaries(data,dictionaries,"cff") + local cid=data.dictionaries[1].cid + if cid and cid.fdselect then + readfdselect(f,fontdata,data,glyphs,false) + else + readnoselect(f,fontdata,data,glyphs,false) end + return data + end end end -- closure @@ -14657,17 +15475,19 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-ttf']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local next,type,unpack=next,type,unpack local band,rshift=bit32.band,bit32.rshift local sqrt,round=math.sqrt,math.round -local char=string.char +local char,rep=string.char,string.rep local concat=table.concat +local idiv=number.idiv +local setmetatableindex=table.setmetatableindex local report=logs.reporter("otf reader","ttf") local trace_deltas=false local readers=fonts.handlers.otf.readers @@ -14675,1054 +15495,1144 @@ local streamreader=readers.streamreader local setposition=streamreader.setposition local getposition=streamreader.getposition local skipbytes=streamreader.skip -local readbyte=streamreader.readcardinal1 -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 -local readchar=streamreader.readinteger1 -local readshort=streamreader.readinteger2 -local read2dot14=streamreader.read2dot14 +local readbyte=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 +local readchar=streamreader.readinteger1 +local readshort=streamreader.readinteger2 +local read2dot14=streamreader.read2dot14 local readinteger=streamreader.readinteger1 +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + setposition=streamreader.setposition + getposition=streamreader.getposition + skipbytes=streamreader.skip + readbyte=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readulong=streamreader.readcardinal4 + readchar=streamreader.readinteger1 + readshort=streamreader.readinteger2 + read2dot14=streamreader.read2dot14 + readinteger=streamreader.readinteger1 + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable +end) +local short=2 +local ushort=2 +local ulong=4 local helpers=readers.helpers local gotodatatable=helpers.gotodatatable local function mergecomposites(glyphs,shapes) - local function merge(index,shape,components) - local contours={} - local points={} - local nofcontours=0 - local nofpoints=0 - local offset=0 - local deltas=shape.deltas - for i=1,#components do - local component=components[i] - local subindex=component.index - local subshape=shapes[subindex] - local subcontours=subshape.contours - local subpoints=subshape.points - if not subcontours then - local subcomponents=subshape.components - if subcomponents then - subcontours,subpoints=merge(subindex,subshape,subcomponents) - end - end - if subpoints then - local matrix=component.matrix - local xscale=matrix[1] - local xrotate=matrix[2] - local yrotate=matrix[3] - local yscale=matrix[4] - local xoffset=matrix[5] - local yoffset=matrix[6] - for i=1,#subpoints do - local p=subpoints[i] - local x=p[1] - local y=p[2] - nofpoints=nofpoints+1 - points[nofpoints]={ - xscale*x+xrotate*y+xoffset, - yscale*y+yrotate*x+yoffset, - p[3] - } - end - for i=1,#subcontours do - nofcontours=nofcontours+1 - contours[nofcontours]=offset+subcontours[i] - end - offset=offset+#subpoints - else - report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) - end + local function merge(index,shape,components) + local contours={} + local points={} + local nofcontours=0 + local nofpoints=0 + local offset=0 + local deltas=shape.deltas + for i=1,#components do + local component=components[i] + local subindex=component.index + local subshape=shapes[subindex] + local subcontours=subshape.contours + local subpoints=subshape.points + if not subcontours then + local subcomponents=subshape.components + if subcomponents then + subcontours,subpoints=merge(subindex,subshape,subcomponents) + end + end + if subpoints then + local matrix=component.matrix + local xscale=matrix[1] + local xrotate=matrix[2] + local yrotate=matrix[3] + local yscale=matrix[4] + local xoffset=matrix[5] + local yoffset=matrix[6] + local count=#subpoints + if xscale==1 and yscale==1 and xrotate==0 and yrotate==0 then + for i=1,count do + local p=subpoints[i] + nofpoints=nofpoints+1 + points[nofpoints]={ + p[1]+xoffset, + p[2]+yoffset, + p[3] + } + end + else + for i=1,count do + local p=subpoints[i] + local x=p[1] + local y=p[2] + nofpoints=nofpoints+1 + points[nofpoints]={ + xscale*x+xrotate*y+xoffset, + yscale*y+yrotate*x+yoffset, + p[3] + } + end end - shape.points=points - shape.contours=contours - shape.components=nil - return contours,points - end - for index=1,#glyphs do - local shape=shapes[index] - if shape then - local components=shape.components - if components then - merge(index,shape,components) - end + local subcount=#subcontours + if subcount==1 then + nofcontours=nofcontours+1 + contours[nofcontours]=offset+subcontours[1] + else + for i=1,#subcontours do + nofcontours=nofcontours+1 + contours[nofcontours]=offset+subcontours[i] + end end - end -end -local function readnothing(f,nofcontours) - return { - type="nothing", - } + offset=offset+count + else + report("missing contours composite %s, component %s of %s, glyph %s",index,i,#components,subindex) + end + end + shape.points=points + shape.contours=contours + shape.components=nil + return contours,points + end + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local components=shape.components + if components then + merge(index,shape,components) + end + end + end +end +local function readnothing(f) + return { + type="nothing", + } end local function curveto(m_x,m_y,l_x,l_y,r_x,r_y) - return - l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), - r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), - r_x,r_y,"c" + return + l_x+2/3*(m_x-l_x),l_y+2/3*(m_y-l_y), + r_x+2/3*(m_x-r_x),r_y+2/3*(m_y-r_y), + r_x,r_y,"c" end local function applyaxis(glyph,shape,deltas,dowidth) - local points=shape.points - if points then - local nofpoints=#points - local h=nofpoints+2 - local l=nofpoints+1 - local dw=0 - local dl=0 - for i=1,#deltas do - local deltaset=deltas[i] - local xvalues=deltaset.xvalues - local yvalues=deltaset.yvalues - local dpoints=deltaset.points - local factor=deltaset.factor - if dpoints then - local nofdpoints=#dpoints - for i=1,nofdpoints do - local d=dpoints[i] - local p=points[d] - if p then - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y - end - end - elseif dowidth then - if d==h then - local x=xvalues[i] - if x then - dw=dw+factor*x - end - elseif d==l then - local x=xvalues[i] - if x then - dl=dl+factor*x - end - end - end - end - else - for i=1,nofpoints do - local p=points[i] - if xvalues then - local x=xvalues[i] - if x and x~=0 then - p[1]=p[1]+factor*x - end - end - if yvalues then - local y=yvalues[i] - if y and y~=0 then - p[2]=p[2]+factor*y - end - end - end - if dowidth then - local x=xvalues[h] - if x then - dw=dw+factor*x - end - local x=xvalues[l] - if x then - dl=dl+factor*x - end - end + local points=shape.points + if points then + local nofpoints=#points + local h=nofpoints+2 + local l=nofpoints+1 + local dw=0 + local dl=0 + for i=1,#deltas do + local deltaset=deltas[i] + local xvalues=deltaset.xvalues + local yvalues=deltaset.yvalues + local dpoints=deltaset.points + local factor=deltaset.factor + if dpoints then + local nofdpoints=#dpoints + for i=1,nofdpoints do + local d=dpoints[i] + local p=points[d] + if p then + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y + end + end + elseif dowidth then + if d==h then + local x=xvalues[i] + if x then + dw=dw+factor*x + end + elseif d==l then + local x=xvalues[i] + if x then + dl=dl+factor*x + end + end + end + end + else + for i=1,nofpoints do + local p=points[i] + if xvalues then + local x=xvalues[i] + if x and x~=0 then + p[1]=p[1]+factor*x + end + end + if yvalues then + local y=yvalues[i] + if y and y~=0 then + p[2]=p[2]+factor*y end + end end if dowidth then - local width=glyph.width or 0 - glyph.width=width+dw-dl + local x=xvalues[h] + if x then + dw=dw+factor*x + end + local x=xvalues[l] + if x then + dl=dl+factor*x + end end - else - report("no points for glyph %a",glyph.name) + end + end + if dowidth then + local width=glyph.width or 0 + glyph.width=width+dw-dl end + else + report("no points for glyph %a",glyph.name) + end end local quadratic=false -local function contours2outlines_normal(glyphs,shapes) - for index=1,#glyphs do - local shape=shapes[index] - if shape then - local glyph=glyphs[index] - local contours=shape.contours - local points=shape.points - if contours then - local nofcontours=#contours - local segments={} - local nofsegments=0 - glyph.segments=segments - if nofcontours>0 then - local px,py=0,0 - local first=1 - for i=1,nofcontours do - local last=contours[i] - if last>=first then - local first_pt=points[first] - local first_on=first_pt[3] - if first==last then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - else - local first_on=first_pt[3] - local last_pt=points[last] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt - else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } - end - control_pt=first_pt - end - local x,y=first_pt[1],first_pt[2] - if not done then - xmin,ymin,xmax,ymax=x,y,x,y - done=true - end - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"m" } - if not quadratic then - px,py=x,y - end - local previous_pt=first_pt - for i=first,last do - local current_pt=points[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then - local x,y=current_pt[1],current_pt[2] - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"l" } - if not quadratic then - px,py=x,y - end - else - control_pt=current_pt - end - elseif current_on then - local x1,y1=control_pt[1],control_pt[2] - local x2,y2=current_pt[1],current_pt[2] - nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - control_pt=false - else - local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2 - local x1,y1=control_pt[1],control_pt[2] - nofsegments=nofsegments+1 - if quadratic then - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - control_pt=current_pt - end - previous_pt=current_pt - end - if first_pt==last_pt then - else - nofsegments=nofsegments+1 - local x2,y2=first_pt[1],first_pt[2] - if not control_pt then - segments[nofsegments]={ x2,y2,"l" } - elseif quadratic then - local x1,y1=control_pt[1],control_pt[2] - segments[nofsegments]={ x1,y1,x2,y2,"q" } - else - local x1,y1=control_pt[1],control_pt[2] - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - end - end - first=last+1 +local function contours2outlines_normal(glyphs,shapes) + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments={} + local nofsegments=0 + glyph.segments=segments + if nofcontours>0 then + local px=0 + local py=0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt + end + local x=first_pt[1] + local y=first_pt[2] + if not done then + xmin=x + ymin=y + xmax=x + ymax=y + done=true + end + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + if not quadratic then + px=x + py=y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x,y=current_pt[1],current_pt[2] + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + if not quadratic then + px,py=x,y + end + else + control_pt=current_pt + end + elseif current_on then + local x1=control_pt[1] + local y1=control_pt[2] + local x2=current_pt[1] + local y2=current_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + control_pt=false + else + local x2=(previous_pt[1]+current_pt[1])/2 + local y2=(previous_pt[2]+current_pt[2])/2 + local x1=control_pt[1] + local y1=control_pt[2] + nofsegments=nofsegments+1 + if quadratic then + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + else + nofsegments=nofsegments+1 + local x2=first_pt[1] + local y2=first_pt[2] + if not control_pt then + segments[nofsegments]={ x2,y2,"l" } + elseif quadratic then + local x1=control_pt[1] + local y1=control_pt[2] + segments[nofsegments]={ x1,y1,x2,y2,"q" } + else + local x1=control_pt[1] + local y1=control_pt[2] + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end end + end end + first=last+1 + end end + end end + end end local function contours2outlines_shaped(glyphs,shapes,keepcurve) - for index=1,#glyphs do - local shape=shapes[index] - if shape then - local glyph=glyphs[index] - local contours=shape.contours - local points=shape.points - if contours then - local nofcontours=#contours - local segments=keepcurve and {} or nil - local nofsegments=0 + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local glyph=glyphs[index] + local contours=shape.contours + local points=shape.points + if contours then + local nofcontours=#contours + local segments=keepcurve and {} or nil + local nofsegments=0 + if keepcurve then + glyph.segments=segments + end + if nofcontours>0 then + local xmin,ymin,xmax,ymax,done=0,0,0,0,false + local px,py=0,0 + local first=1 + for i=1,nofcontours do + local last=contours[i] + if last>=first then + local first_pt=points[first] + local first_on=first_pt[3] + if first==last then if keepcurve then - glyph.segments=segments + first_pt[3]="m" + nofsegments=nofsegments+1 + segments[nofsegments]=first_pt + end + else + local first_on=first_pt[3] + local last_pt=points[last] + local last_on=last_pt[3] + local start=1 + local control_pt=false + if first_on then + start=2 + else + if last_on then + first_pt=last_pt + else + first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } + end + control_pt=first_pt + end + local x=first_pt[1] + local y=first_pt[2] + if not done then + xmin,ymin,xmax,ymax=x,y,x,y + done=true + else + if xxmax then xmax=x end + if yymax then ymax=y end end - if nofcontours>0 then - local xmin,ymin,xmax,ymax,done=0,0,0,0,false - local px,py=0,0 - local first=1 - for i=1,nofcontours do - local last=contours[i] - if last>=first then - local first_pt=points[first] - local first_on=first_pt[3] - if first==last then - if keepcurve then - first_pt[3]="m" - nofsegments=nofsegments+1 - segments[nofsegments]=first_pt - end - else - local first_on=first_pt[3] - local last_pt=points[last] - local last_on=last_pt[3] - local start=1 - local control_pt=false - if first_on then - start=2 - else - if last_on then - first_pt=last_pt - else - first_pt={ (first_pt[1]+last_pt[1])/2,(first_pt[2]+last_pt[2])/2,false } - end - control_pt=first_pt - end - local x,y=first_pt[1],first_pt[2] - if not done then - xmin,ymin,xmax,ymax=x,y,x,y - done=true - else - if xxmax then xmax=x end - if yymax then ymax=y end - end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"m" } - end - if not quadratic then - px,py=x,y - end - local previous_pt=first_pt - for i=first,last do - local current_pt=points[i] - local current_on=current_pt[3] - local previous_on=previous_pt[3] - if previous_on then - if current_on then - local x,y=current_pt[1],current_pt[2] - if xxmax then xmax=x end - if yymax then ymax=y end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x,y,"l" } - end - if not quadratic then - px,py=x,y - end - else - control_pt=current_pt - end - elseif current_on then - local x1,y1=control_pt[1],control_pt[2] - local x2,y2=current_pt[1],current_pt[2] - if quadratic then - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - control_pt=false - else - local x2,y2=(previous_pt[1]+current_pt[1])/2,(previous_pt[2]+current_pt[2])/2 - local x1,y1=control_pt[1],control_pt[2] - if quadratic then - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - control_pt=current_pt - end - previous_pt=current_pt - end - if first_pt==last_pt then - elseif not control_pt then - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ first_pt[1],first_pt[2],"l" } - end - else - local x1,y1=control_pt[1],control_pt[2] - local x2,y2=first_pt[1],first_pt[2] - if x1xmax then xmax=x1 end - if y1ymax then ymax=y1 end - if quadratic then - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,"q" } - end - else - x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) - if x2xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if pxxmax then xmax=px end - if pyymax then ymax=py end - if keepcurve then - nofsegments=nofsegments+1 - segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } - end - end - end - end - end - first=last+1 - end - glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"m" } + end + if not quadratic then + px=x + py=y + end + local previous_pt=first_pt + for i=first,last do + local current_pt=points[i] + local current_on=current_pt[3] + local previous_on=previous_pt[3] + if previous_on then + if current_on then + local x=current_pt[1] + local y=current_pt[2] + if xxmax then xmax=x end + if yymax then ymax=y end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x,y,"l" } + end + if not quadratic then + px=x + py=y + end + else + control_pt=current_pt + end + elseif current_on then + local x1=control_pt[1] + local y1=control_pt[2] + local x2=current_pt[1] + local y2=current_pt[2] + if quadratic then + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=false + else + local x2=(previous_pt[1]+current_pt[1])/2 + local y2=(previous_pt[2]+current_pt[2])/2 + local x1=control_pt[1] + local y1=control_pt[2] + if quadratic then + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end + control_pt=current_pt + end + previous_pt=current_pt + end + if first_pt==last_pt then + elseif not control_pt then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ first_pt[1],first_pt[2],"l" } + end + else + local x1=control_pt[1] + local y1=control_pt[2] + local x2=first_pt[1] + local y2=first_pt[2] + if x1xmax then xmax=x1 end + if y1ymax then ymax=y1 end + if quadratic then + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,"q" } + end + else + x1,y1,x2,y2,px,py=curveto(x1,y1,px,py,x2,y2) + if x2xmax then xmax=x2 end + if y2ymax then ymax=y2 end + if pxxmax then xmax=px end + if pyymax then ymax=py end + if keepcurve then + nofsegments=nofsegments+1 + segments[nofsegments]={ x1,y1,x2,y2,px,py,"c" } + end + end end + end end + first=last+1 + end + glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) } end + end end + end end local c_zero=char(0) local s_zero=char(0,0) local function toushort(n) - return char(band(rshift(n,8),0xFF),band(n,0xFF)) + return char(band(rshift(n,8),0xFF),band(n,0xFF)) end local function toshort(n) - if n<0 then - n=n+0x10000 - end - return char(band(rshift(n,8),0xFF),band(n,0xFF)) + if n<0 then + n=n+0x10000 + end + return char(band(rshift(n,8),0xFF),band(n,0xFF)) end +local chars=setmetatableindex(function(t,k) + for i=0,255 do local v=char(i) t[i]=v end return t[k] +end) local function repackpoints(glyphs,shapes) - local noboundingbox={ 0,0,0,0 } - local result={} - for index=1,#glyphs do - local shape=shapes[index] - if shape then - local r=0 - local glyph=glyphs[index] - if false then + local noboundingbox={ 0,0,0,0 } + local result={} + local xpoints={} + local ypoints={} + for index=0,#glyphs-1 do + local shape=shapes[index] + if shape then + local r=0 + local glyph=glyphs[index] + local contours=shape.contours + local nofcontours=contours and #contours or 0 + local boundingbox=glyph.boundingbox or noboundingbox + r=r+1 result[r]=toshort(nofcontours) + r=r+1 result[r]=toshort(boundingbox[1]) + r=r+1 result[r]=toshort(boundingbox[2]) + r=r+1 result[r]=toshort(boundingbox[3]) + r=r+1 result[r]=toshort(boundingbox[4]) + if nofcontours>0 then + for i=1,nofcontours do + r=r+1 result[r]=toshort(contours[i]-1) + end + r=r+1 result[r]=s_zero + local points=shape.points + local currentx=0 + local currenty=0 + local x=0 + local y=0 + local lastflag=nil + local nofflags=0 + for i=1,#points do + local pt=points[i] + local px=pt[1] + local py=pt[2] + local fl=pt[3] and 0x01 or 0x00 + if px==currentx then + fl=fl+0x10 + else + local dx=round(px-currentx) + x=x+1 + if dx<-255 or dx>255 then + xpoints[x]=toshort(dx) + elseif dx<0 then + fl=fl+0x02 + xpoints[x]=chars[-dx] + elseif dx>0 then + fl=fl+0x12 + xpoints[x]=chars[dx] else - local contours=shape.contours - local nofcontours=contours and #contours or 0 - local boundingbox=glyph.boundingbox or noboundingbox - r=r+1 result[r]=toshort(nofcontours) - r=r+1 result[r]=toshort(boundingbox[1]) - r=r+1 result[r]=toshort(boundingbox[2]) - r=r+1 result[r]=toshort(boundingbox[3]) - r=r+1 result[r]=toshort(boundingbox[4]) - if nofcontours>0 then - for i=1,nofcontours do - r=r+1 result[r]=toshort(contours[i]-1) - end - r=r+1 result[r]=s_zero - local points=shape.points - local currentx=0 - local currenty=0 - local xpoints={} - local ypoints={} - local x=0 - local y=0 - local lastflag=nil - local nofflags=0 - for i=1,#points do - local pt=points[i] - local px=pt[1] - local py=pt[2] - local fl=pt[3] and 0x01 or 0x00 - if px==currentx then - fl=fl+0x10 - else - local dx=round(px-currentx) - if dx<-255 or dx>255 then - x=x+1 xpoints[x]=toshort(dx) - elseif dx<0 then - fl=fl+0x02 - x=x+1 xpoints[x]=char(-dx) - elseif dx>0 then - fl=fl+0x12 - x=x+1 xpoints[x]=char(dx) - else - fl=fl+0x02 - x=x+1 xpoints[x]=c_zero - end - end - if py==currenty then - fl=fl+0x20 - else - local dy=round(py-currenty) - if dy<-255 or dy>255 then - y=y+1 ypoints[y]=toshort(dy) - elseif dy<0 then - fl=fl+0x04 - y=y+1 ypoints[y]=char(-dy) - elseif dy>0 then - fl=fl+0x24 - y=y+1 ypoints[y]=char(dy) - else - fl=fl+0x04 - y=y+1 ypoints[y]=c_zero - end - end - currentx=px - currenty=py - if lastflag==fl then - nofflags=nofflags+1 - else - if nofflags==1 then - r=r+1 result[r]=char(lastflag) - elseif nofflags==2 then - r=r+1 result[r]=char(lastflag,lastflag) - elseif nofflags>2 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - end - nofflags=1 - lastflag=fl - end - end - if nofflags==1 then - r=r+1 result[r]=char(lastflag) - elseif nofflags==2 then - r=r+1 result[r]=char(lastflag,lastflag) - elseif nofflags>2 then - lastflag=lastflag+0x08 - r=r+1 result[r]=char(lastflag,nofflags-1) - end - r=r+1 result[r]=concat(xpoints) - r=r+1 result[r]=concat(ypoints) - end + fl=fl+0x02 + xpoints[x]=c_zero + end + end + if py==currenty then + fl=fl+0x20 + else + local dy=round(py-currenty) + y=y+1 + if dy<-255 or dy>255 then + ypoints[y]=toshort(dy) + elseif dy<0 then + fl=fl+0x04 + ypoints[y]=chars[-dy] + elseif dy>0 then + fl=fl+0x24 + ypoints[y]=chars[dy] + else + fl=fl+0x04 + ypoints[y]=c_zero end - glyph.stream=concat(result,"",1,r) + end + currentx=px + currenty=py + if lastflag==fl then + nofflags=nofflags+1 + else + if nofflags==1 then + r=r+1 result[r]=chars[lastflag] + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + nofflags=1 + lastflag=fl + end + end + if nofflags==1 then + r=r+1 result[r]=chars[lastflag] + elseif nofflags==2 then + r=r+1 result[r]=char(lastflag,lastflag) + elseif nofflags>2 then + lastflag=lastflag+0x08 + r=r+1 result[r]=char(lastflag,nofflags-1) + end + r=r+1 result[r]=concat(xpoints,"",1,x) + r=r+1 result[r]=concat(ypoints,"",1,y) + end + local stream=concat(result,"",1,r) + local length=#stream + local padding=idiv(length+3,4)*4-length + if padding>0 then + if padding==1 then + padding="\0" + elseif padding==2 then + padding="\0\0" else + padding="\0\0\0" end + padding=stream..padding + end + glyph.stream=stream end + end end +local flags={} local function readglyph(f,nofcontours) - local points={} - local contours={} - local instructions={} - local flags={} - for i=1,nofcontours do - contours[i]=readshort(f)+1 - end - local nofpoints=contours[nofcontours] - local nofinstructions=readushort(f) - skipbytes(f,nofinstructions) - local i=1 - while i<=nofpoints do - local flag=readbyte(f) + local points={} + local contours={} + for i=1,nofcontours do + contours[i]=readshort(f)+1 + end + local nofpoints=contours[nofcontours] + local nofinstructions=readushort(f) + skipbytes(f,nofinstructions) + local i=1 + while i<=nofpoints do + local flag=readbyte(f) + flags[i]=flag + if band(flag,0x08)~=0 then + local n=readbyte(f) + if n==1 then + i=i+1 flags[i]=flag - if band(flag,0x08)~=0 then - for j=1,readbyte(f) do - i=i+1 - flags[i]=flag - end - end - i=i+1 - end - local x=0 - for i=1,nofpoints do - local flag=flags[i] - local short=band(flag,0x02)~=0 - local same=band(flag,0x10)~=0 - if short then - if same then - x=x+readbyte(f) - else - x=x-readbyte(f) - end - elseif same then - else - x=x+readshort(f) - end - points[i]={ x,0,band(flag,0x01)~=0 } - end - local y=0 - for i=1,nofpoints do - local flag=flags[i] - local short=band(flag,0x04)~=0 - local same=band(flag,0x20)~=0 - if short then - if same then - y=y+readbyte(f) - else - y=y-readbyte(f) - end - elseif same then - else - y=y+readshort(f) - end - points[i][2]=y + else + for j=1,n do + i=i+1 + flags[i]=flag + end + end + end + i=i+1 + end + local x=0 + for i=1,nofpoints do + local flag=flags[i] + if band(flag,0x02)~=0 then + if band(flag,0x10)~=0 then + x=x+readbyte(f) + else + x=x-readbyte(f) + end + elseif band(flag,0x10)~=0 then + else + x=x+readshort(f) + end + points[i]={ x,0,band(flag,0x01)~=0 } + end + local y=0 + for i=1,nofpoints do + local flag=flags[i] + if band(flag,0x04)~=0 then + if band(flag,0x20)~=0 then + y=y+readbyte(f) + else + y=y-readbyte(f) + end + elseif band(flag,0x20)~=0 then + else + y=y+readshort(f) end - return { - type="glyph", - points=points, - contours=contours, - nofpoints=nofpoints, - } + points[i][2]=y + end + return { + type="glyph", + points=points, + contours=contours, + nofpoints=nofpoints, + } end local function readcomposite(f) - local components={} - local nofcomponents=0 - local instructions=false - while true do - local flags=readushort(f) - local index=readushort(f) - local f_xyarg=band(flags,0x0002)~=0 - local f_offset=band(flags,0x0800)~=0 - local xscale=1 - local xrotate=0 - local yrotate=0 - local yscale=1 - local xoffset=0 - local yoffset=0 - local base=false - local reference=false - if f_xyarg then - if band(flags,0x0001)~=0 then - xoffset=readshort(f) - yoffset=readshort(f) - else - xoffset=readchar(f) - yoffset=readchar(f) - end - else - if band(flags,0x0001)~=0 then - base=readshort(f) - reference=readshort(f) - else - base=readchar(f) - reference=readchar(f) - end - end - if band(flags,0x0008)~=0 then - xscale=read2dot14(f) - yscale=xscale - if f_xyarg and f_offset then - xoffset=xoffset*xscale - yoffset=yoffset*yscale - end - elseif band(flags,0x0040)~=0 then - xscale=read2dot14(f) - yscale=read2dot14(f) - if f_xyarg and f_offset then - xoffset=xoffset*xscale - yoffset=yoffset*yscale - end - elseif band(flags,0x0080)~=0 then - xscale=read2dot14(f) - xrotate=read2dot14(f) - yrotate=read2dot14(f) - yscale=read2dot14(f) - if f_xyarg and f_offset then - xoffset=xoffset*sqrt(xscale^2+xrotate^2) - yoffset=yoffset*sqrt(yrotate^2+yscale^2) - end - end - nofcomponents=nofcomponents+1 - components[nofcomponents]={ - index=index, - usemine=band(flags,0x0200)~=0, - round=band(flags,0x0006)~=0, - base=base, - reference=reference, - matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset }, - } - if band(flags,0x0100)~=0 then - instructions=true - end - if not band(flags,0x0020)~=0 then - break - end - end - return { - type="composite", - components=components, + local components={} + local nofcomponents=0 + local instructions=false + while true do + local flags=readushort(f) + local index=readushort(f) + local f_xyarg=band(flags,0x0002)~=0 + local f_offset=band(flags,0x0800)~=0 + local xscale=1 + local xrotate=0 + local yrotate=0 + local yscale=1 + local xoffset=0 + local yoffset=0 + local base=false + local reference=false + if f_xyarg then + if band(flags,0x0001)~=0 then + xoffset=readshort(f) + yoffset=readshort(f) + else + xoffset=readchar(f) + yoffset=readchar(f) + end + else + if band(flags,0x0001)~=0 then + base=readshort(f) + reference=readshort(f) + else + base=readchar(f) + reference=readchar(f) + end + end + if band(flags,0x0008)~=0 then + xscale=read2dot14(f) + yscale=xscale + if f_xyarg and f_offset then + xoffset=xoffset*xscale + yoffset=yoffset*yscale + end + elseif band(flags,0x0040)~=0 then + xscale=read2dot14(f) + yscale=read2dot14(f) + if f_xyarg and f_offset then + xoffset=xoffset*xscale + yoffset=yoffset*yscale + end + elseif band(flags,0x0080)~=0 then + xscale=read2dot14(f) + xrotate=read2dot14(f) + yrotate=read2dot14(f) + yscale=read2dot14(f) + if f_xyarg and f_offset then + xoffset=xoffset*sqrt(xscale^2+xrotate^2) + yoffset=yoffset*sqrt(yrotate^2+yscale^2) + end + end + nofcomponents=nofcomponents+1 + components[nofcomponents]={ + index=index, + usemine=band(flags,0x0200)~=0, + round=band(flags,0x0006)~=0, + base=base, + reference=reference, + matrix={ xscale,xrotate,yrotate,yscale,xoffset,yoffset }, } + if band(flags,0x0100)~=0 then + instructions=true + end + if band(flags,0x0020)==0 then + break + end + end + return { + type="composite", + components=components, + } end function readers.loca(f,fontdata,specification) - if specification.glyphs then - local datatable=fontdata.tables.loca - if datatable then - local offset=fontdata.tables.glyf.offset - local format=fontdata.fontheader.indextolocformat - local locations={} - setposition(f,datatable.offset) - if format==1 then - local nofglyphs=datatable.length/4-2 - for i=0,nofglyphs do - locations[i]=offset+readulong(f) - end - fontdata.nofglyphs=nofglyphs - else - local nofglyphs=datatable.length/2-2 - for i=0,nofglyphs do - locations[i]=offset+readushort(f)*2 - end - fontdata.nofglyphs=nofglyphs - end - fontdata.locations=locations + if specification.glyphs then + local datatable=fontdata.tables.loca + if datatable then + local offset=fontdata.tables.glyf.offset + local format=fontdata.fontheader.indextolocformat + local profile=fontdata.maximumprofile + local nofglyphs=profile and profile.nofglyphs + local locations={} + setposition(f,datatable.offset) + if format==1 then + if not nofglyphs then + nofglyphs=idiv(datatable.length,4)-1 + end + for i=0,nofglyphs do + locations[i]=offset+readulong(f) + end + fontdata.nofglyphs=nofglyphs + else + if not nofglyphs then + nofglyphs=idiv(datatable.length,2)-1 end + for i=0,nofglyphs do + locations[i]=offset+readushort(f)*2 + end + end + fontdata.nofglyphs=nofglyphs + fontdata.locations=locations end + end end function readers.glyf(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) - if tableoffset then - local locations=fontdata.locations - if locations then - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs - local filesize=fontdata.filesize - local nothing={ 0,0,0,0 } - local shapes={} - local loadshapes=specification.shapes or specification.instance - for index=0,nofglyphs do - local location=locations[index] - if location>=filesize then - report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) - fontdata.nofglyphs=index-1 - fontdata.badfont=true - break - elseif location>0 then - setposition(f,location) - local nofcontours=readshort(f) - glyphs[index].boundingbox={ - readshort(f), - readshort(f), - readshort(f), - readshort(f), - } - if not loadshapes then - elseif nofcontours==0 then - shapes[index]=readnothing(f,nofcontours) - elseif nofcontours>0 then - shapes[index]=readglyph(f,nofcontours) - else - shapes[index]=readcomposite(f,nofcontours) - end - else - if loadshapes then - shapes[index]={} - end - glyphs[index].boundingbox=nothing - end - end - if loadshapes then - if readers.gvar then - readers.gvar(f,fontdata,specification,glyphs,shapes) - end - mergecomposites(glyphs,shapes) - if specification.instance then - if specification.streams then - repackpoints(glyphs,shapes) - else - contours2outlines_shaped(glyphs,shapes,specification.shapes) - end - elseif specification.shapes then - contours2outlines_normal(glyphs,shapes) - end - end + local tableoffset=gotodatatable(f,fontdata,"glyf",specification.glyphs) + if tableoffset then + local locations=fontdata.locations + if locations then + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs + local filesize=fontdata.filesize + local nothing={ 0,0,0,0 } + local shapes={} + local loadshapes=specification.shapes or specification.instance or specification.streams + for index=0,nofglyphs-1 do + local location=locations[index] + local length=locations[index+1]-location + if location>=filesize then + report("discarding %s glyphs due to glyph location bug",nofglyphs-index+1) + fontdata.nofglyphs=index-1 + fontdata.badfont=true + break + elseif length>0 then + setposition(f,location) + local nofcontours=readshort(f) + glyphs[index].boundingbox={ + readshort(f), + readshort(f), + readshort(f), + readshort(f), + } + if not loadshapes then + elseif nofcontours==0 then + shapes[index]=readnothing(f) + elseif nofcontours>0 then + shapes[index]=readglyph(f,nofcontours) + else + shapes[index]=readcomposite(f,nofcontours) + end + else + if loadshapes then + shapes[index]=readnothing(f) + end + glyphs[index].boundingbox=nothing + end + end + if loadshapes then + if readers.gvar then + readers.gvar(f,fontdata,specification,glyphs,shapes) + end + mergecomposites(glyphs,shapes) + if specification.instance then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_shaped(glyphs,shapes,specification.shapes) + end + elseif specification.shapes then + if specification.streams then + repackpoints(glyphs,shapes) + else + contours2outlines_normal(glyphs,shapes) + end + elseif specification.streams then + repackpoints(glyphs,shapes) end + end end + end end local function readtuplerecord(f,nofaxis) - local record={} - for i=1,nofaxis do - record[i]=read2dot14(f) - end - return record + local record={} + for i=1,nofaxis do + record[i]=read2dot14(f) + end + return record end local function readpoints(f) - local count=readbyte(f) - if count==0 then - return nil,0 + local count=readbyte(f) + if count==0 then + return nil,0 + else + if count<128 then + elseif band(count,0x80)~=0 then + count=band(count,0x7F)*256+readbyte(f) else - if count<128 then - elseif band(count,0x80)~=0 then - count=band(count,0x7F)*256+readbyte(f) - else - end - local points={} - local p=0 - local n=1 - while p0 do - local control=readbyte(f) + local deltas={} + local p=0 + local z=0 + while nofpoints>0 do + local control=readbyte(f) if not control then - break + break end - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - z=z+runlength - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - if z>0 then - for i=1,z do - p=p+1 - deltas[p]=0 - end - z=0 - end - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - end - if p>0 then - return deltas + local allzero=band(control,0x80)~=0 + local runlength=band(control,0x3F)+1 + if allzero then + z=z+runlength else - end + local runreader=band(control,0x40)~=0 and readshort or readinteger + if z>0 then + for i=1,z do + p=p+1 + deltas[p]=0 + end + z=0 + end + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength + end + if p>0 then + return deltas + else + end end local function readdeltas(f,nofpoints) - local deltas={} - local p=0 - while nofpoints>0 do - local control=readbyte(f) - if control then - local allzero=band(control,0x80)~=0 - local runlength=band(control,0x3F)+1 - if allzero then - for i=1,runlength do - p=p+1 - deltas[p]=0 - end - else - local runreader=band(control,0x40)~=0 and readshort or readinteger - for i=1,runlength do - p=p+1 - deltas[p]=runreader(f) - end - end - nofpoints=nofpoints-runlength - else - break - end - end - if p>0 then - return deltas + local deltas={} + local p=0 + while nofpoints>0 do + local control=readbyte(f) + if control then + local allzero=band(control,0x80)~=0 + local runlength=band(control,0x3F)+1 + if allzero then + for i=1,runlength do + p=p+1 + deltas[p]=0 + end + else + local runreader=band(control,0x40)~=0 and readshort or readinteger + for i=1,runlength do + p=p+1 + deltas[p]=runreader(f) + end + end + nofpoints=nofpoints-runlength else + break end + end + if p>0 then + return deltas + else + end end function readers.gvar(f,fontdata,specification,glyphdata,shapedata) - local instance=specification.instance - if not instance then - return - end - local factors=specification.factors - if not factors then - return - end - local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) - if tableoffset then - local version=readulong(f) - local nofaxis=readushort(f) - local noftuples=readushort(f) - local tupleoffset=tableoffset+readulong(f) - local nofglyphs=readushort(f) - local flags=readushort(f) - local dataoffset=tableoffset+readulong(f) - local data={} - local tuples={} - local glyphdata=fontdata.glyphs - local dowidth=not fontdata.variabledata.hvarwidths - if band(flags,0x0001)~=0 then - for i=1,nofglyphs+1 do - data[i]=dataoffset+readulong(f) - end + local instance=specification.instance + if not instance then + return + end + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"gvar",specification.variable or specification.shapes) + if tableoffset then + local version=readulong(f) + local nofaxis=readushort(f) + local noftuples=readushort(f) + local tupleoffset=tableoffset+readulong(f) + local nofglyphs=readushort(f) + local flags=readushort(f) + local dataoffset=tableoffset+readulong(f) + local data={} + local tuples={} + local glyphdata=fontdata.glyphs + local dowidth=not fontdata.variabledata.hvarwidths + if band(flags,0x0001)~=0 then + for i=1,nofglyphs+1 do + data[i]=dataoffset+readulong(f) + end + else + for i=1,nofglyphs+1 do + data[i]=dataoffset+2*readushort(f) + end + end + if noftuples>0 then + setposition(f,tupleoffset) + for i=1,noftuples do + tuples[i]=readtuplerecord(f,nofaxis) + end + end + local nextoffset=false + local startoffset=data[1] + for i=1,nofglyphs do + nextoffset=data[i+1] + local glyph=glyphdata[i-1] + local name=trace_deltas and glyph.name + if startoffset==nextoffset then + if name then + report("no deltas for glyph %a",name) + end + else + local shape=shapedata[i-1] + if not shape then + if name then + report("no shape for glyph %a",name) + end else - for i=1,nofglyphs+1 do - data[i]=dataoffset+2*readushort(f) + lastoffset=startoffset + setposition(f,startoffset) + local flags=readushort(f) + local count=band(flags,0x0FFF) + local offset=startoffset+readushort(f) + local deltas={} + local allpoints=(shape.nofpoints or 0) + local shared=false + local nofshared=0 + if band(flags,0x8000)~=0 then + local current=getposition(f) + setposition(f,offset) + shared,nofshared=readpoints(f) + offset=getposition(f) + setposition(f,current) + end + for j=1,count do + local size=readushort(f) + local flags=readushort(f) + local index=band(flags,0x0FFF) + local haspeak=band(flags,0x8000)~=0 + local intermediate=band(flags,0x4000)~=0 + local private=band(flags,0x2000)~=0 + local peak=nil + local start=nil + local stop=nil + local xvalues=nil + local yvalues=nil + local points=shared + local nofpoints=nofshared + if haspeak then + peak=readtuplerecord(f,nofaxis) + else + if index+1>#tuples then + report("error, bad tuple index",index) + end + peak=tuples[index+1] end - end - if noftuples>0 then - setposition(f,tupleoffset) - for i=1,noftuples do - tuples[i]=readtuplerecord(f,nofaxis) + if intermediate then + start=readtuplerecord(f,nofaxis) + stop=readtuplerecord(f,nofaxis) end - end - local nextoffset=false - local startoffset=data[1] - for i=1,nofglyphs do - nextoffset=data[i+1] - local glyph=glyphdata[i-1] - local name=trace_deltas and glyph.name - if startoffset==nextoffset then - if name then - report("no deltas for glyph %a",name) - end + if size>0 then + local current=getposition(f) + setposition(f,offset) + if private then + points,nofpoints=readpoints(f) + end + if nofpoints==0 then + nofpoints=allpoints+4 + end + if nofpoints>0 then + xvalues=readdeltas(f,nofpoints) + yvalues=readdeltas(f,nofpoints) + end + offset=offset+size + setposition(f,current) + end + if not xvalues and not yvalues then + points=nil + end + local s=1 + for i=1,nofaxis do + local f=factors[i] + local peak=peak and peak [i] or 0 + local start=start and start[i] or (peak<0 and peak or 0) + local stop=stop and stop [i] or (peak>0 and peak or 0) + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end + end + if s==0 then + if name then + report("no deltas applied for glyph %a",name) + end else - local shape=shapedata[i-1] - if not shape then - if name then - report("no shape for glyph %a",name) - end - else - lastoffset=startoffset - setposition(f,startoffset) - local flags=readushort(f) - local count=band(flags,0x0FFF) - local offset=startoffset+readushort(f) - local deltas={} - local allpoints=(shape.nofpoints or 0) - local shared=false - local nofshared=0 - if band(flags,0x8000)~=0 then - local current=getposition(f) - setposition(f,offset) - shared,nofshared=readpoints(f) - offset=getposition(f) - setposition(f,current) - end - for j=1,count do - local size=readushort(f) - local flags=readushort(f) - local index=band(flags,0x0FFF) - local haspeak=band(flags,0x8000)~=0 - local intermediate=band(flags,0x4000)~=0 - local private=band(flags,0x2000)~=0 - local peak=nil - local start=nil - local stop=nil - local xvalues=nil - local yvalues=nil - local points=shared - local nofpoints=nofshared - if haspeak then - peak=readtuplerecord(f,nofaxis) - else - if index+1>#tuples then - report("error, bad tuple index",index) - end - peak=tuples[index+1] - end - if intermediate then - start=readtuplerecord(f,nofaxis) - stop=readtuplerecord(f,nofaxis) - end - if size>0 then - local current=getposition(f) - setposition(f,offset) - if private then - points,nofpoints=readpoints(f) - end - if nofpoints==0 then - nofpoints=allpoints+4 - end - if nofpoints>0 then - xvalues=readdeltas(f,nofpoints) - yvalues=readdeltas(f,nofpoints) - end - offset=offset+size - setposition(f,current) - end - if not xvalues and not yvalues then - points=nil - end - local s=1 - for i=1,nofaxis do - local f=factors[i] - local peak=peak and peak [i] or 0 - local start=start and start[i] or (peak<0 and peak or 0) - local stop=stop and stop [i] or (peak>0 and peak or 0) - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - if s==0 then - if name then - report("no deltas applied for glyph %a",name) - end - else - deltas[#deltas+1]={ - factor=s, - points=points, - xvalues=xvalues, - yvalues=yvalues, - } - end - end - if shape.type=="glyph" then - applyaxis(glyph,shape,deltas,dowidth) - else - shape.deltas=deltas - end - end + deltas[#deltas+1]={ + factor=s, + points=points, + xvalues=xvalues, + yvalues=yvalues, + } end - startoffset=nextoffset + end + if shape.type=="glyph" then + applyaxis(glyph,shape,deltas,dowidth) + else + shape.deltas=deltas + end end + end + startoffset=nextoffset end + end end end -- closure @@ -15730,13 +16640,13 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-dsp']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } -local next,type=next,type +local next,type,tonumber=next,type,tonumber local band=bit32.band local extract=bit32.extract local bor=bit32.bor @@ -15753,20 +16663,22 @@ local reversed=table.reversed local sort=table.sort local insert=table.insert local round=math.round -local lpegmatch=lpeg.match +local settings_to_hash=utilities.parsers.settings_to_hash_colon_too local setmetatableindex=table.setmetatableindex local formatters=string.formatters local sortedkeys=table.sortedkeys local sortedhash=table.sortedhash +local sequenced=table.sequenced local report=logs.reporter("otf reader") local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local setposition=streamreader.setposition local getposition=streamreader.getposition -local readushort=streamreader.readcardinal2 -local readulong=streamreader.readcardinal4 +local readuinteger=streamreader.readcardinal1 +local readushort=streamreader.readcardinal2 +local readulong=streamreader.readcardinal4 local readinteger=streamreader.readinteger1 -local readshort=streamreader.readinteger2 +local readshort=streamreader.readinteger2 local readstring=streamreader.readstring local readtag=streamreader.readtag local readbytes=streamreader.readbytes @@ -15774,9 +16686,36 @@ local readfixed=streamreader.readfixed4 local read2dot14=streamreader.read2dot14 local skipshort=streamreader.skipshort local skipbytes=streamreader.skip -local readfword=readshort local readbytetable=streamreader.readbytetable local readbyte=streamreader.readbyte +local readcardinaltable=streamreader.readcardinaltable +local readintegertable=streamreader.readintegertable +local readfword=readshort +local short=2 +local ushort=2 +local ulong=4 +directives.register("fonts.streamreader",function() + streamreader=utilities.streams + setposition=streamreader.setposition + getposition=streamreader.getposition + readuinteger=streamreader.readcardinal1 + readushort=streamreader.readcardinal2 + readulong=streamreader.readcardinal4 + readinteger=streamreader.readinteger1 + readshort=streamreader.readinteger2 + readstring=streamreader.readstring + readtag=streamreader.readtag + readbytes=streamreader.readbytes + readfixed=streamreader.readfixed4 + read2dot14=streamreader.read2dot14 + skipshort=streamreader.skipshort + skipbytes=streamreader.skip + readbytetable=streamreader.readbytetable + readbyte=streamreader.readbyte + readcardinaltable=streamreader.readcardinaltable + readintegertable=streamreader.readintegertable + readfword=readshort +end) local gsubhandlers={} local gposhandlers={} readers.gsubhandlers=gsubhandlers @@ -15784,5014 +16723,5417 @@ readers.gposhandlers=gposhandlers local helpers=readers.helpers local gotodatatable=helpers.gotodatatable local setvariabledata=helpers.setvariabledata -local lookupidoffset=-1 +local lookupidoffset=-1 local classes={ - "base", - "ligature", - "mark", - "component", + "base", + "ligature", + "mark", + "component", } local gsubtypes={ - "single", - "multiple", - "alternate", - "ligature", - "context", - "chainedcontext", - "extension", - "reversechainedcontextsingle", + "single", + "multiple", + "alternate", + "ligature", + "context", + "chainedcontext", + "extension", + "reversechainedcontextsingle", } local gpostypes={ - "single", - "pair", - "cursive", - "marktobase", - "marktoligature", - "marktomark", - "context", - "chainedcontext", - "extension", + "single", + "pair", + "cursive", + "marktobase", + "marktoligature", + "marktomark", + "context", + "chainedcontext", + "extension", } local chaindirections={ - context=0, - chainedcontext=1, - reversechainedcontextsingle=-1, + context=0, + chainedcontext=1, + reversechainedcontextsingle=-1, } local function setmetrics(data,where,tag,d) - local w=data[where] - if w then - local v=w[tag] - if v then - w[tag]=v+d - end + local w=data[where] + if w then + local v=w[tag] + if v then + w[tag]=v+d end + end end local variabletags={ - hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, - hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, - hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, - hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, - hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, - vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, - vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, - vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, - xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, - cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, - sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, - sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, - sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, - sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, - spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, - spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, - spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, - spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, - strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, - stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, - unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, - undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, + hasc=function(data,d) setmetrics(data,"windowsmetrics","typoascender",d) end, + hdsc=function(data,d) setmetrics(data,"windowsmetrics","typodescender",d) end, + hlgp=function(data,d) setmetrics(data,"windowsmetrics","typolinegap",d) end, + hcla=function(data,d) setmetrics(data,"windowsmetrics","winascent",d) end, + hcld=function(data,d) setmetrics(data,"windowsmetrics","windescent",d) end, + vasc=function(data,d) setmetrics(data,"vhea not done","ascent",d) end, + vdsc=function(data,d) setmetrics(data,"vhea not done","descent",d) end, + vlgp=function(data,d) setmetrics(data,"vhea not done","linegap",d) end, + xhgt=function(data,d) setmetrics(data,"windowsmetrics","xheight",d) end, + cpht=function(data,d) setmetrics(data,"windowsmetrics","capheight",d) end, + sbxs=function(data,d) setmetrics(data,"windowsmetrics","subscriptxsize",d) end, + sbys=function(data,d) setmetrics(data,"windowsmetrics","subscriptysize",d) end, + sbxo=function(data,d) setmetrics(data,"windowsmetrics","subscriptxoffset",d) end, + sbyo=function(data,d) setmetrics(data,"windowsmetrics","subscriptyoffset",d) end, + spxs=function(data,d) setmetrics(data,"windowsmetrics","superscriptxsize",d) end, + spys=function(data,d) setmetrics(data,"windowsmetrics","superscriptysize",d) end, + spxo=function(data,d) setmetrics(data,"windowsmetrics","superscriptxoffset",d) end, + spyo=function(data,d) setmetrics(data,"windowsmetrics","superscriptyoffset",d) end, + strs=function(data,d) setmetrics(data,"windowsmetrics","strikeoutsize",d) end, + stro=function(data,d) setmetrics(data,"windowsmetrics","strikeoutpos",d) end, + unds=function(data,d) setmetrics(data,"postscript","underlineposition",d) end, + undo=function(data,d) setmetrics(data,"postscript","underlinethickness",d) end, } local read_cardinal={ - streamreader.readcardinal1, - streamreader.readcardinal2, - streamreader.readcardinal3, - streamreader.readcardinal4, + streamreader.readcardinal1, + streamreader.readcardinal2, + streamreader.readcardinal3, + streamreader.readcardinal4, } local read_integer={ - streamreader.readinteger1, - streamreader.readinteger2, - streamreader.readinteger3, - streamreader.readinteger4, + streamreader.readinteger1, + streamreader.readinteger2, + streamreader.readinteger3, + streamreader.readinteger4, } local lookupnames={ - gsub={ - single="gsub_single", - multiple="gsub_multiple", - alternate="gsub_alternate", - ligature="gsub_ligature", - context="gsub_context", - chainedcontext="gsub_contextchain", - reversechainedcontextsingle="gsub_reversecontextchain", - }, - gpos={ - single="gpos_single", - pair="gpos_pair", - cursive="gpos_cursive", - marktobase="gpos_mark2base", - marktoligature="gpos_mark2ligature", - marktomark="gpos_mark2mark", - context="gpos_context", - chainedcontext="gpos_contextchain", - } + gsub={ + single="gsub_single", + multiple="gsub_multiple", + alternate="gsub_alternate", + ligature="gsub_ligature", + context="gsub_context", + chainedcontext="gsub_contextchain", + reversechainedcontextsingle="gsub_reversecontextchain", + }, + gpos={ + single="gpos_single", + pair="gpos_pair", + cursive="gpos_cursive", + marktobase="gpos_mark2base", + marktoligature="gpos_mark2ligature", + marktomark="gpos_mark2mark", + context="gpos_context", + chainedcontext="gpos_contextchain", + } } local lookupflags=setmetatableindex(function(t,k) - local v={ - band(k,0x0008)~=0 and true or false, - band(k,0x0004)~=0 and true or false, - band(k,0x0002)~=0 and true or false, - band(k,0x0001)~=0 and true or false, - } - t[k]=v - return v + local v={ + band(k,0x0008)~=0 and true or false, + band(k,0x0004)~=0 and true or false, + band(k,0x0002)~=0 and true or false, + band(k,0x0001)~=0 and true or false, + } + t[k]=v + return v end) -local pattern=lpeg.Cf ( - lpeg.Ct("")*lpeg.Cg ( - lpeg.C((lpeg.R("az","09")+lpeg.P(" "))^1)*lpeg.S(" :=")*(lpeg.patterns.number/tonumber)*lpeg.S(" ,")^0 - )^1,rawset -) +local function axistofactors(str) + local t=settings_to_hash(str) + for k,v in next,t do + t[k]=tonumber(v) or v + end + return t +end local hash=table.setmetatableindex(function(t,k) - local v=lpegmatch(pattern,k) - local t={} - for k,v in sortedhash(v) do - t[#t+1]=k.."="..v - end - v=concat(t,",") - t[k]=v - return v + local v=sequenced(axistofactors(k),",") + t[k]=v + return v end) helpers.normalizedaxishash=hash local cleanname=fonts.names and fonts.names.cleanname or function(name) - return name and (gsub(lower(name),"[^%a%d]","")) or nil + return name and (gsub(lower(name),"[^%a%d]","")) or nil end helpers.cleanname=cleanname function helpers.normalizedaxis(str) - return hash[str] or str -end -local function axistofactors(str) - return lpegmatch(pattern,str) + return hash[str] or str end local function getaxisscale(segments,minimum,default,maximum,user) - if not minimum or not default or not maximum then - return false - end - if usermaximum then - user=maximum - end - if userdefault then - default=(user-default)/(maximum-default) - else - default=0 - end - if not segments then + if not minimum or not default or not maximum then + return false + end + if usermaximum then + user=maximum + end + if userdefault then + default=(user-default)/(maximum-default) + else + default=0 + end + if not segments then + return default + end + local e + for i=1,#segments do + local s=segments[i] + if type(s)~="number" then + report("using default axis scale") + return default + elseif s[1]>=default then + if s[2]==default then return default - end - local e - for i=1,#segments do - local s=segments[i] - if type(s)~="number" then - report("using default axis scale") - return default - elseif s[1]>=default then - if s[2]==default then - return default - else - e=i - break - end - end - end - if e then - local b=segments[e-1] - local e=segments[e] - return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) - else - return false - end + else + e=i + break + end + end + end + if e then + local b=segments[e-1] + local e=segments[e] + return b[2]+(e[2]-b[2])*(default-b[1])/(e[1]-b[1]) + else + return false + end end local function getfactors(data,instancespec) + if instancespec==true then + elseif type(instancespec)~="string" or instancespec=="" then + return + end + local variabledata=data.variabledata + if not variabledata then + return + end + local instances=variabledata.instances + local axis=variabledata.axis + local segments=variabledata.segments + if instances and axis then + local values if instancespec==true then - elseif type(instancespec)~="string" or instancespec=="" then - return - end - local variabledata=data.variabledata - if not variabledata then - return - end - local instances=variabledata.instances - local axis=variabledata.axis - local segments=variabledata.segments - if instances and axis then - local values - if instancespec==true then - values={} - for i=1,#axis do - values[i]={ - value=axis[i].default, - } - end - else - for i=1,#instances do - local instance=instances[i] - if cleanname(instance.subfamily)==instancespec then - values=instance.values - break - end - end - end - if values then - local factors={} - for i=1,#axis do - local a=axis[i] - factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) - end - return factors - end - local values=axistofactors(hash[instancespec] or instancespec) - if values then - local factors={} - for i=1,#axis do - local a=axis[i] - local d=a.default - factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) - end - return factors - end - end + values={} + for i=1,#axis do + values[i]={ + value=axis[i].default, + } + end + else + for i=1,#instances do + local instance=instances[i] + if cleanname(instance.subfamily)==instancespec then + values=instance.values + break + end + end + end + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + factors[i]=getaxisscale(segments,a.minimum,a.default,a.maximum,values[i].value) + end + return factors + end + local values=axistofactors(hash[instancespec] or instancespec) + if values then + local factors={} + for i=1,#axis do + local a=axis[i] + local d=a.default + factors[i]=getaxisscale(segments,a.minimum,d,a.maximum,values[a.name or a.tag] or d) + end + return factors + end + end end local function getscales(regions,factors) - local scales={} - for i=1,#regions do - local region=regions[i] - local s=1 - for j=1,#region do - local axis=region[j] - local f=factors[j] - local start=axis.start - local peak=axis.peak - local stop=axis.stop - if start>peak or peak>stop then - elseif start<0 and stop>0 and peak~=0 then - elseif peak==0 then - elseif fstop then - s=0 - break - elseif fpeak then - s=s*(stop-f)/(stop-peak) - else - end - end - scales[i]=s + local scales={} + for i=1,#regions do + local region=regions[i] + local s=1 + for j=1,#region do + local axis=region[j] + local f=factors[j] + local start=axis.start + local peak=axis.peak + local stop=axis.stop + if start>peak or peak>stop then + elseif start<0 and stop>0 and peak~=0 then + elseif peak==0 then + elseif fstop then + s=0 + break + elseif fpeak then + s=s*(stop-f)/(stop-peak) + else + end end - return scales + scales[i]=s + end + return scales end helpers.getaxisscale=getaxisscale helpers.getfactors=getfactors helpers.getscales=getscales helpers.axistofactors=axistofactors local function readvariationdata(f,storeoffset,factors) - local position=getposition(f) - setposition(f,storeoffset) - local format=readushort(f) - local regionoffset=storeoffset+readulong(f) - local nofdeltadata=readushort(f) - local deltadata={} + local position=getposition(f) + setposition(f,storeoffset) + local format=readushort(f) + local regionoffset=storeoffset+readulong(f) + local nofdeltadata=readushort(f) + local deltadata=readcardinaltable(f,nofdeltadata,ulong) + setposition(f,regionoffset) + local nofaxis=readushort(f) + local nofregions=readushort(f) + local regions={} + for i=1,nofregions do + local t={} + for i=1,nofaxis do + t[i]={ + start=read2dot14(f), + peak=read2dot14(f), + stop=read2dot14(f), + } + end + regions[i]=t + end + if factors then for i=1,nofdeltadata do - deltadata[i]=readulong(f) - end - setposition(f,regionoffset) - local nofaxis=readushort(f) - local nofregions=readushort(f) - local regions={} - for i=1,nofregions do - local t={} - for i=1,nofaxis do - t[i]={ - start=read2dot14(f), - peak=read2dot14(f), - stop=read2dot14(f), - } - end - regions[i]=t - end - if factors then - for i=1,nofdeltadata do - setposition(f,storeoffset+deltadata[i]) - local nofdeltasets=readushort(f) - local nofshorts=readushort(f) - local nofregions=readushort(f) - local usedregions={} - local deltas={} - for i=1,nofregions do - usedregions[i]=regions[readushort(f)+1] - end - for i=1,nofdeltasets do - local t={} - for i=1,nofshorts do - t[i]=readshort(f) - end - for i=nofshorts+1,nofregions do - t[i]=readinteger(f) - end - deltas[i]=t - end - deltadata[i]={ - regions=usedregions, - deltas=deltas, - scales=factors and getscales(usedregions,factors) or nil, - } - end - end - setposition(f,position) - return regions,deltadata + setposition(f,storeoffset+deltadata[i]) + local nofdeltasets=readushort(f) + local nofshorts=readushort(f) + local nofregions=readushort(f) + local usedregions={} + local deltas={} + for i=1,nofregions do + usedregions[i]=regions[readushort(f)+1] + end + for i=1,nofdeltasets do + local t=readintegertable(f,nofshorts,short) + for i=nofshorts+1,nofregions do + t[i]=readinteger(f) + end + deltas[i]=t + end + deltadata[i]={ + regions=usedregions, + deltas=deltas, + scales=factors and getscales(usedregions,factors) or nil, + } + end + end + setposition(f,position) + return regions,deltadata end helpers.readvariationdata=readvariationdata local function readcoverage(f,offset,simple) - setposition(f,offset) - local coverageformat=readushort(f) + setposition(f,offset) + local coverageformat=readushort(f) + if coverageformat==1 then + local nofcoverage=readushort(f) + if simple then + if nofcoverage==1 then + return { readushort(f) } + elseif nofcoverage==2 then + return { readushort(f),readushort(f) } + else + return readcardinaltable(f,nofcoverage,ushort) + end + elseif nofcoverage==1 then + return { [readushort(f)]=0 } + elseif nofcoverage==2 then + return { [readushort(f)]=0,[readushort(f)]=1 } + else + local coverage={} + for i=0,nofcoverage-1 do + coverage[readushort(f)]=i + end + return coverage + end + elseif coverageformat==2 then + local nofranges=readushort(f) local coverage={} - if coverageformat==1 then - local nofcoverage=readushort(f) - if simple then - for i=1,nofcoverage do - coverage[i]=readushort(f) - end - else - for i=0,nofcoverage-1 do - coverage[readushort(f)]=i - end - end - elseif coverageformat==2 then - local nofranges=readushort(f) - local n=simple and 1 or 0 - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local coverindex=readushort(f) - if simple then - for i=firstindex,lastindex do - coverage[n]=i - n=n+1 - end - else - for i=firstindex,lastindex do - coverage[i]=n - n=n+1 - end - end - end - else - report("unknown coverage format %a ",coverageformat) + local n=simple and 1 or 0 + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local coverindex=readushort(f) + if simple then + for i=firstindex,lastindex do + coverage[n]=i + n=n+1 + end + else + for i=firstindex,lastindex do + coverage[i]=n + n=n+1 + end + end end return coverage + else + report("unknown coverage format %a ",coverageformat) + return {} + end end local function readclassdef(f,offset,preset) - setposition(f,offset) - local classdefformat=readushort(f) - local classdef={} - if type(preset)=="number" then - for k=0,preset-1 do - classdef[k]=1 - end - end - if classdefformat==1 then - local index=readushort(f) - local nofclassdef=readushort(f) - for i=1,nofclassdef do - classdef[index]=readushort(f)+1 - index=index+1 - end - elseif classdefformat==2 then - local nofranges=readushort(f) - local n=0 - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=readushort(f)+1 - for i=firstindex,lastindex do - classdef[i]=class - end - end - else - report("unknown classdef format %a ",classdefformat) - end - if type(preset)=="table" then - for k in next,preset do - if not classdef[k] then - classdef[k]=1 - end - end - end - return classdef + setposition(f,offset) + local classdefformat=readushort(f) + local classdef={} + if type(preset)=="number" then + for k=0,preset-1 do + classdef[k]=1 + end + end + if classdefformat==1 then + local index=readushort(f) + local nofclassdef=readushort(f) + for i=1,nofclassdef do + classdef[index]=readushort(f)+1 + index=index+1 + end + elseif classdefformat==2 then + local nofranges=readushort(f) + local n=0 + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=readushort(f)+1 + for i=firstindex,lastindex do + classdef[i]=class + end + end + else + report("unknown classdef format %a ",classdefformat) + end + if type(preset)=="table" then + for k in next,preset do + if not classdef[k] then + classdef[k]=1 + end + end + end + return classdef end local function classtocoverage(defs) - if defs then - local list={} - for index,class in next,defs do - local c=list[class] - if c then - c[#c+1]=index - else - list[class]={ index } - end - end - return list - end + if defs then + local list={} + for index,class in next,defs do + local c=list[class] + if c then + c[#c+1]=index + else + list[class]={ index } + end + end + return list + end end local skips={ [0]=0, - 1, - 1, - 2, - 1, - 2, - 2, - 3, - 2, - 2, - 3, - 2, - 3, - 3, - 4, + 1, + 1, + 2, + 1, + 2, + 2, + 3, + 2, + 2, + 3, + 2, + 3, + 3, + 4, } local function readvariation(f,offset) - local p=getposition(f) - setposition(f,offset) - local outer=readushort(f) - local inner=readushort(f) - local format=readushort(f) - setposition(f,p) - if format==0x8000 then - return outer,inner - end + local p=getposition(f) + setposition(f,offset) + local outer=readushort(f) + local inner=readushort(f) + local format=readushort(f) + setposition(f,p) + if format==0x8000 then + return outer,inner + end end local function readposition(f,format,mainoffset,getdelta) - if format==0 then - return false - end - if format==0x04 then - local h=readshort(f) - if h==0 then - return true - else - return { 0,0,h,0 } - end - end - if format==0x05 then - local x=readshort(f) - local h=readshort(f) - if x==0 and h==0 then - return true - else - return { x,0,h,0 } - end + if format==0 then + return false + end + if format==0x04 then + local h=readshort(f) + if h==0 then + return true + else + return { 0,0,h,0 } end - if format==0x44 then - local h=readshort(f) - if getdelta then - local d=readshort(f) - if d>0 then - local outer,inner=readvariation(f,mainoffset+d) - if outer then - h=h+getdelta(outer,inner) - end - end - else - skipshort(f,1) - end - if h==0 then - return true - else - return { 0,0,h,0 } - end - end - local x=band(format,0x1)~=0 and readshort(f) or 0 - local y=band(format,0x2)~=0 and readshort(f) or 0 - local h=band(format,0x4)~=0 and readshort(f) or 0 - local v=band(format,0x8)~=0 and readshort(f) or 0 - if format>=0x10 then - local X=band(format,0x10)~=0 and skipshort(f) or 0 - local Y=band(format,0x20)~=0 and skipshort(f) or 0 - local H=band(format,0x40)~=0 and skipshort(f) or 0 - local V=band(format,0x80)~=0 and skipshort(f) or 0 - local s=skips[extract(format,4,4)] - if s>0 then - skipshort(f,s) - end - if getdelta then - if X>0 then - local outer,inner=readvariation(f,mainoffset+X) - if outer then - x=x+getdelta(outer,inner) - end - end - if Y>0 then - local outer,inner=readvariation(f,mainoffset+Y) - if outer then - y=y+getdelta(outer,inner) - end - end - if H>0 then - local outer,inner=readvariation(f,mainoffset+H) - if outer then - h=h+getdelta(outer,inner) - end - end - if V>0 then - local outer,inner=readvariation(f,mainoffset+V) - if outer then - v=v+getdelta(outer,inner) - end - end - end - return { x,y,h,v } - elseif x==0 and y==0 and h==0 and v==0 then - return true + end + if format==0x05 then + local x=readshort(f) + local h=readshort(f) + if x==0 and h==0 then + return true + else + return { x,0,h,0 } + end + end + if format==0x44 then + local h=readshort(f) + if getdelta then + local d=readshort(f) + if d>0 then + local outer,inner=readvariation(f,mainoffset+d) + if outer then + h=h+getdelta(outer,inner) + end + end else - return { x,y,h,v } + skipshort(f,1) end + if h==0 then + return true + else + return { 0,0,h,0 } + end + end + local x=band(format,0x1)~=0 and readshort(f) or 0 + local y=band(format,0x2)~=0 and readshort(f) or 0 + local h=band(format,0x4)~=0 and readshort(f) or 0 + local v=band(format,0x8)~=0 and readshort(f) or 0 + if format>=0x10 then + local X=band(format,0x10)~=0 and skipshort(f) or 0 + local Y=band(format,0x20)~=0 and skipshort(f) or 0 + local H=band(format,0x40)~=0 and skipshort(f) or 0 + local V=band(format,0x80)~=0 and skipshort(f) or 0 + local s=skips[extract(format,4,4)] + if s>0 then + skipshort(f,s) + end + if getdelta then + if X>0 then + local outer,inner=readvariation(f,mainoffset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,mainoffset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end + if H>0 then + local outer,inner=readvariation(f,mainoffset+H) + if outer then + h=h+getdelta(outer,inner) + end + end + if V>0 then + local outer,inner=readvariation(f,mainoffset+V) + if outer then + v=v+getdelta(outer,inner) + end + end + end + return { x,y,h,v } + elseif x==0 and y==0 and h==0 and v==0 then + return true + else + return { x,y,h,v } + end end local function readanchor(f,offset,getdelta) - if not offset or offset==0 then - return nil - end - setposition(f,offset) - local format=readshort(f) - local x=readshort(f) - local y=readshort(f) - if format==3 then - if getdelta then - local X=readshort(f) - local Y=readshort(f) - if X>0 then - local outer,inner=readvariation(f,offset+X) - if outer then - x=x+getdelta(outer,inner) - end - end - if Y>0 then - local outer,inner=readvariation(f,offset+Y) - if outer then - y=y+getdelta(outer,inner) - end - end - else - skipshort(f,2) - end - return { x,y } + if not offset or offset==0 then + return nil + end + setposition(f,offset) + local format=readshort(f) + local x=readshort(f) + local y=readshort(f) + if format==3 then + if getdelta then + local X=readshort(f) + local Y=readshort(f) + if X>0 then + local outer,inner=readvariation(f,offset+X) + if outer then + x=x+getdelta(outer,inner) + end + end + if Y>0 then + local outer,inner=readvariation(f,offset+Y) + if outer then + y=y+getdelta(outer,inner) + end + end else - return { x,y } + skipshort(f,2) end + return { x,y } + else + return { x,y } + end end local function readfirst(f,offset) - if offset then - setposition(f,offset) - end - return { readushort(f) } + if offset then + setposition(f,offset) + end + return { readushort(f) } end -local function readarray(f,offset,first) - if offset then - setposition(f,offset) - end - local n=readushort(f) - if first then - local t={ first } - for i=2,n do - t[i]=readushort(f) - end - return t,n - elseif n>0 then - local t={} - for i=1,n do - t[i]=readushort(f) - end - return t,n - end +function readarray(f,offset) + if offset then + setposition(f,offset) + end + local n=readushort(f) + if n==1 then + return { readushort(f) },1 + elseif n>0 then + return readcardinaltable(f,n,ushort),n + end end local function readcoveragearray(f,offset,t,simple) - if not t then - return nil - end - local n=#t - if n==0 then - return nil - end - for i=1,n do - t[i]=readcoverage(f,offset+t[i],simple) - end - return t + if not t then + return nil + end + local n=#t + if n==0 then + return nil + end + for i=1,n do + t[i]=readcoverage(f,offset+t[i],simple) + end + return t end local function covered(subset,all) - local used,u - for i=1,#subset do - local s=subset[i] - if all[s] then - if used then - u=u+1 - used[u]=s - else - u=1 - used={ s } - end - end - end - return used + local used,u + for i=1,#subset do + local s=subset[i] + if all[s] then + if used then + u=u+1 + used[u]=s + else + u=1 + used={ s } + end + end + end + return used end local function readlookuparray(f,noflookups,nofcurrent) - local lookups={} - if noflookups>0 then - local length=0 - for i=1,noflookups do - local index=readushort(f)+1 - if index>length then - length=index - end - local lookup=readushort(f)+1 - local list=lookups[index] - if list then - list[#list+1]=lookup - else - lookups[index]={ lookup } - end - end - for index=1,length do - if not lookups[index] then - lookups[index]=false - end - end - end - return lookups + local lookups={} + if noflookups>0 then + local length=0 + for i=1,noflookups do + local index=readushort(f)+1 + if index>length then + length=index + end + local lookup=readushort(f)+1 + local list=lookups[index] + if list then + list[#list+1]=lookup + else + lookups[index]={ lookup } + end + end + for index=1,length do + if not lookups[index] then + lookups[index]=false + end + end + end + return lookups end local function unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage,true) - for i=1,#subclasssets do - local offset=subclasssets[i] - if offset>0 then - local firstcoverage=coverage[i] - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofcurrent=readushort(f) - local noflookups=readushort(f) - local current={ { firstcoverage } } - for i=2,nofcurrent do - current[i]={ readushort(f) } - end - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - current=current, - lookups=lookups - } - end - end - end - else - report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage,true) + for i=1,#subclasssets do + local offset=subclasssets[i] + if offset>0 then + local firstcoverage=coverage[i] + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofcurrent=readushort(f) + local noflookups=readushort(f) + local current={ { firstcoverage } } + for i=2,nofcurrent do + current[i]={ readushort(f) } + end + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + current=current, + lookups=lookups + } + end end - return { - format="glyphs", - rules=rules, - } - elseif subtype==2 then - local coverage=readushort(f) - local currentclassdef=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage) - currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) - local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) - for class=1,#subclasssets do - local offset=subclasssets[class] - if offset>0 then - local firstcoverage=currentclasses[class] - if firstcoverage then - firstcoverage=covered(firstcoverage,coverage) - if firstcoverage then - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofcurrent=readushort(f) - local noflookups=readushort(f) - local current={ firstcoverage } - for i=2,nofcurrent do - current[i]=currentclasses[readushort(f)+1] - end - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - current=current, - lookups=lookups - } - end - else - report("no coverage") - end - else - report("no coverage class") - end - end + end + else + report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + end + return { + format="glyphs", + rules=rules, + } + elseif subtype==2 then + local coverage=readushort(f) + local currentclassdef=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage) + currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) + for class=1,#subclasssets do + local offset=subclasssets[class] + if offset>0 then + local firstcoverage=currentclasses[class] + if firstcoverage then + firstcoverage=covered(firstcoverage,coverage) + if firstcoverage then + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofcurrent=readushort(f) + local noflookups=readushort(f) + local current={ firstcoverage } + for i=2,nofcurrent do + current[i]=currentclasses[readushort(f)+1] + end + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + current=current, + lookups=lookups + } + end + else + report("no coverage") end - else - report("empty subclassset in %a subtype %i","unchainedcontext",subtype) + else + report("no coverage class") + end end - return { - format="class", - rules=rules, - } - elseif subtype==3 then - local current=readarray(f) - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,#current) - current=readcoveragearray(f,tableoffset,current,true) - return { - format="coverage", - rules={ - { - current=current, - lookups=lookups, - } - } - } + end else - report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what) + report("empty subclassset in %a subtype %i","unchainedcontext",subtype) end + return { + format="class", + rules=rules, + } + elseif subtype==3 then + local nofglyphs=readushort(f) + local noflookups=readushort(f) + local current=readcardinaltable(f,nofglyphs,ushort) + local lookups=readlookuparray(f,noflookups,#current) + current=readcoveragearray(f,tableoffset,current,true) + return { + format="coverage", + rules={ + { + current=current, + lookups=lookups, + } + } + } + else + report("unsupported subtype %a in %a %s",subtype,"unchainedcontext",what) + end end local function chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - coverage=readcoverage(f,tableoffset+coverage,true) - for i=1,#subclasssets do - local offset=subclasssets[i] - if offset>0 then - local firstcoverage=coverage[i] - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofbefore=readushort(f) - local before - if nofbefore>0 then - before={} - for i=1,nofbefore do - before[i]={ readushort(f) } - end - end - local nofcurrent=readushort(f) - local current={ { firstcoverage } } - for i=2,nofcurrent do - current[i]={ readushort(f) } - end - local nofafter=readushort(f) - local after - if nofafter>0 then - after={} - for i=1,nofafter do - after[i]={ readushort(f) } - end - end - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - before=before, - current=current, - after=after, - lookups=lookups, - } - end - end + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + coverage=readcoverage(f,tableoffset+coverage,true) + for i=1,#subclasssets do + local offset=subclasssets[i] + if offset>0 then + local firstcoverage=coverage[i] + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofbefore=readushort(f) + local before + if nofbefore>0 then + before={} + for i=1,nofbefore do + before[i]={ readushort(f) } + end end - else - report("empty subclassset in %a subtype %i","chainedcontext",subtype) - end - return { - format="glyphs", - rules=rules, - } - elseif subtype==2 then - local coverage=readushort(f) - local beforeclassdef=readushort(f) - local currentclassdef=readushort(f) - local afterclassdef=readushort(f) - local subclasssets=readarray(f) - local rules={} - if subclasssets then - local coverage=readcoverage(f,tableoffset+coverage) - local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) - local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) - local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) - local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) - local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) - local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) - for class=1,#subclasssets do - local offset=subclasssets[class] - if offset>0 then - local firstcoverage=currentclasses[class] - if firstcoverage then - firstcoverage=covered(firstcoverage,coverage) - if firstcoverage then - local rulesoffset=tableoffset+offset - local subclassrules=readarray(f,rulesoffset) - for rule=1,#subclassrules do - setposition(f,rulesoffset+subclassrules[rule]) - local nofbefore=readushort(f) - local before - if nofbefore>0 then - before={} - for i=1,nofbefore do - before[i]=beforeclasses[readushort(f)+1] - end - end - local nofcurrent=readushort(f) - local current={ firstcoverage } - for i=2,nofcurrent do - current[i]=currentclasses[readushort(f)+1] - end - local nofafter=readushort(f) - local after - if nofafter>0 then - after={} - for i=1,nofafter do - after[i]=afterclasses[readushort(f)+1] - end - end - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,nofcurrent) - rules[#rules+1]={ - before=before, - current=current, - after=after, - lookups=lookups, - } - end - else - report("no coverage") - end - else - report("class is not covered") - end - end + local nofcurrent=readushort(f) + local current={ { firstcoverage } } + for i=2,nofcurrent do + current[i]={ readushort(f) } + end + local nofafter=readushort(f) + local after + if nofafter>0 then + after={} + for i=1,nofafter do + after[i]={ readushort(f) } + end end - else - report("empty subclassset in %a subtype %i","chainedcontext",subtype) + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + before=before, + current=current, + after=after, + lookups=lookups, + } + end end - return { - format="class", - rules=rules, - } - elseif subtype==3 then - local before=readarray(f) - local current=readarray(f) - local after=readarray(f) - local noflookups=readushort(f) - local lookups=readlookuparray(f,noflookups,#current) - before=readcoveragearray(f,tableoffset,before,true) - current=readcoveragearray(f,tableoffset,current,true) - after=readcoveragearray(f,tableoffset,after,true) - return { - format="coverage", - rules={ - { - before=before, - current=current, - after=after, - lookups=lookups, + end + else + report("empty subclassset in %a subtype %i","chainedcontext",subtype) + end + return { + format="glyphs", + rules=rules, + } + elseif subtype==2 then + local coverage=readushort(f) + local beforeclassdef=readushort(f) + local currentclassdef=readushort(f) + local afterclassdef=readushort(f) + local subclasssets=readarray(f) + local rules={} + if subclasssets then + local coverage=readcoverage(f,tableoffset+coverage) + local beforeclassdef=readclassdef(f,tableoffset+beforeclassdef,nofglyphs) + local currentclassdef=readclassdef(f,tableoffset+currentclassdef,coverage) + local afterclassdef=readclassdef(f,tableoffset+afterclassdef,nofglyphs) + local beforeclasses=classtocoverage(beforeclassdef,fontdata.glyphs) + local currentclasses=classtocoverage(currentclassdef,fontdata.glyphs) + local afterclasses=classtocoverage(afterclassdef,fontdata.glyphs) + for class=1,#subclasssets do + local offset=subclasssets[class] + if offset>0 then + local firstcoverage=currentclasses[class] + if firstcoverage then + firstcoverage=covered(firstcoverage,coverage) + if firstcoverage then + local rulesoffset=tableoffset+offset + local subclassrules=readarray(f,rulesoffset) + for rule=1,#subclassrules do + setposition(f,rulesoffset+subclassrules[rule]) + local nofbefore=readushort(f) + local before + if nofbefore>0 then + before={} + for i=1,nofbefore do + before[i]=beforeclasses[readushort(f)+1] + end + end + local nofcurrent=readushort(f) + local current={ firstcoverage } + for i=2,nofcurrent do + current[i]=currentclasses[readushort(f)+1] + end + local nofafter=readushort(f) + local after + if nofafter>0 then + after={} + for i=1,nofafter do + after[i]=afterclasses[readushort(f)+1] + end + end + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,nofcurrent) + rules[#rules+1]={ + before=before, + current=current, + after=after, + lookups=lookups, } - } - } + end + else + report("no coverage") + end + else + report("class is not covered") + end + end + end else - report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what) + report("empty subclassset in %a subtype %i","chainedcontext",subtype) end + return { + format="class", + rules=rules, + } + elseif subtype==3 then + local before=readarray(f) + local current=readarray(f) + local after=readarray(f) + local noflookups=readushort(f) + local lookups=readlookuparray(f,noflookups,#current) + before=readcoveragearray(f,tableoffset,before,true) + current=readcoveragearray(f,tableoffset,current,true) + after=readcoveragearray(f,tableoffset,after,true) + return { + format="coverage", + rules={ + { + before=before, + current=current, + after=after, + lookups=lookups, + } + } + } + else + report("unsupported subtype %a in %a %s",subtype,"chainedcontext",what) + end end local function extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,types,handlers,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local lookuptype=types[readushort(f)] - local faroffset=readulong(f) - local handler=handlers[lookuptype] - if handler then - return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype - else - report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension") - end + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local lookuptype=types[readushort(f)] + local faroffset=readulong(f) + local handler=handlers[lookuptype] + if handler then + return handler(f,fontdata,lookupid,tableoffset+faroffset,0,glyphs,nofglyphs),lookuptype else - report("unsupported subtype %a in %s %s",subtype,what,"extension") + report("no handler for lookuptype %a subtype %a in %s %s",lookuptype,subtype,what,"extension") end + else + report("unsupported subtype %a in %s %s",subtype,what,"extension") + end end function gsubhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local delta=readshort(f) - local coverage=readcoverage(f,tableoffset+coverage) - for index in next,coverage do - local newindex=index+delta - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=newindex - end - end - return { - coverage=coverage - } - elseif subtype==2 then - local coverage=readushort(f) - local nofreplacements=readushort(f) - local replacements={} - for i=1,nofreplacements do - replacements[i]=readushort(f) - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - newindex=newindex+1 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=replacements[newindex] - end - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,"single") + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local delta=readshort(f) + local coverage=readcoverage(f,tableoffset+coverage) + for index in next,coverage do + local newindex=(index+delta)%65536 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=newindex + end end + return { + coverage=coverage + } + elseif subtype==2 then + local coverage=readushort(f) + local nofreplacements=readushort(f) + local replacements=readcardinaltable(f,nofreplacements,ushort) + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + newindex=newindex+1 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)","single",subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=replacements[newindex] + end + end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,"single") + end end local function sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,what) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local nofsequence=readushort(f) - local sequences={} - for i=1,nofsequence do - sequences[i]=readushort(f) - end - for i=1,nofsequence do - setposition(f,tableoffset+sequences[i]) - local n=readushort(f) - local s={} - for i=1,n do - s[i]=readushort(f) - end - sequences[i]=s - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - newindex=newindex+1 - if index>nofglyphs or newindex>nofglyphs then - report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs) - coverage[index]=nil - else - coverage[index]=sequences[newindex] - end - end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,what) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local nofsequence=readushort(f) + local sequences=readcardinaltable(f,nofsequence,ushort) + for i=1,nofsequence do + setposition(f,tableoffset+sequences[i]) + sequences[i]=readcardinaltable(f,readushort(f),ushort) + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + newindex=newindex+1 + if index>nofglyphs or newindex>nofglyphs then + report("invalid index in %s format %i: %i -> %i (max %i)",what,subtype,index,newindex,nofglyphs) + coverage[index]=nil + else + coverage[index]=sequences[newindex] + end end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,what) + end end function gsubhandlers.multiple(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple") + return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"multiple") end function gsubhandlers.alternate(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate") + return sethandler(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"alternate") end function gsubhandlers.ligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local coverage=readushort(f) - local nofsets=readushort(f) - local ligatures={} - for i=1,nofsets do - ligatures[i]=readushort(f) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local coverage=readushort(f) + local nofsets=readushort(f) + local ligatures=readcardinaltable(f,nofsets,ushort) + for i=1,nofsets do + local offset=lookupoffset+offset+ligatures[i] + setposition(f,offset) + local n=readushort(f) + if n==1 then + ligatures[i]={ offset+readushort(f) } + else + local l={} + for i=1,n do + l[i]=offset+readushort(f) end - for i=1,nofsets do - local offset=lookupoffset+offset+ligatures[i] - setposition(f,offset) - local n=readushort(f) - local l={} - for i=1,n do - l[i]=offset+readushort(f) - end - ligatures[i]=l - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - local hash={} - local ligatures=ligatures[newindex+1] - for i=1,#ligatures do - local offset=ligatures[i] - setposition(f,offset) - local lig=readushort(f) - local cnt=readushort(f) - local hsh=hash - for i=2,cnt do - local c=readushort(f) - local h=hsh[c] - if not h then - h={} - hsh[c]=h - end - hsh=h - end - hsh.ligature=lig - end - coverage[index]=hash + ligatures[i]=l + end + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + local hash={} + local ligatures=ligatures[newindex+1] + for i=1,#ligatures do + local offset=ligatures[i] + setposition(f,offset) + local lig=readushort(f) + local cnt=readushort(f) + local hsh=hash + for i=2,cnt do + local c=readushort(f) + local h=hsh[c] + if not h then + h={} + hsh[c]=h + end + hsh=h end - return { - coverage=coverage - } - else - report("unsupported subtype %a in %a substitution",subtype,"ligature") + hsh.ligature=lig + end + coverage[index]=hash end + return { + coverage=coverage + } + else + report("unsupported subtype %a in %a substitution",subtype,"ligature") + end end function gsubhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context" + return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"context" end function gsubhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext" + return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"substitution"),"chainedcontext" end function gsubhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution") + return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gsubtypes,gsubhandlers,"substitution") end function gsubhandlers.reversechainedcontextsingle(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - if subtype==1 then - local current=readfirst(f) - local before=readarray(f) - local after=readarray(f) - local replacements=readarray(f) - current=readcoveragearray(f,tableoffset,current,true) - before=readcoveragearray(f,tableoffset,before,true) - after=readcoveragearray(f,tableoffset,after,true) - return { - format="reversecoverage", - rules={ - { - before=before, - current=current, - after=after, - replacements=replacements, - } - } - },"reversechainedcontextsingle" - else - report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") - end + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + if subtype==1 then + local current=readfirst(f) + local before=readarray(f) + local after=readarray(f) + local replacements=readarray(f) + current=readcoveragearray(f,tableoffset,current,true) + before=readcoveragearray(f,tableoffset,before,true) + after=readcoveragearray(f,tableoffset,after,true) + return { + format="reversecoverage", + rules={ + { + before=before, + current=current, + after=after, + replacements=replacements, + } + } + },"reversechainedcontextsingle" + else + report("unsupported subtype %a in %a substitution",subtype,"reversechainedcontextsingle") + end end local function readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) - local done={} - for i=1,#sets do - local offset=sets[i] - local reused=done[offset] - if not reused then - offset=tableoffset+offset - setposition(f,offset) - local n=readushort(f) - reused={} - for i=1,n do - reused[i]={ - readushort(f), - readposition(f,format1,offset,getdelta), - readposition(f,format2,offset,getdelta), - } - end - done[offset]=reused - end - sets[i]=reused + local done={} + for i=1,#sets do + local offset=sets[i] + local reused=done[offset] + if not reused then + offset=tableoffset+offset + setposition(f,offset) + local n=readushort(f) + reused={} + for i=1,n do + reused[i]={ + readushort(f), + readposition(f,format1,offset,getdelta), + readposition(f,format2,offset,getdelta), + } + end + done[offset]=reused end - return sets + sets[i]=reused + end + return sets end local function readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,mainoffset,getdelta) - local classlist1={} - for i=1,nofclasses1 do - local classlist2={} - classlist1[i]=classlist2 - for j=1,nofclasses2 do - local one=readposition(f,format1,mainoffset,getdelta) - local two=readposition(f,format2,mainoffset,getdelta) - if one or two then - classlist2[j]={ one,two } - else - classlist2[j]=false - end - end - end - return classlist1 + local classlist1={} + for i=1,nofclasses1 do + local classlist2={} + classlist1[i]=classlist2 + for j=1,nofclasses2 do + local one=readposition(f,format1,mainoffset,getdelta) + local two=readposition(f,format2,mainoffset,getdelta) + if one or two then + classlist2[j]={ one,two } + else + classlist2[j]=false + end + end + end + return classlist1 end function gposhandlers.single(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=readushort(f) - local format=readushort(f) - local value=readposition(f,format,tableoffset,getdelta) - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - coverage[index]=value - end - return { - format="single", - coverage=coverage, - } - elseif subtype==2 then - local coverage=readushort(f) - local format=readushort(f) - local nofvalues=readushort(f) - local values={} - for i=1,nofvalues do - values[i]=readposition(f,format,tableoffset,getdelta) - end - local coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - coverage[index]=values[newindex+1] - end - return { - format="single", - coverage=coverage, - } - else - report("unsupported subtype %a in %a positioning",subtype,"single") + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=readushort(f) + local format=readushort(f) + local value=readposition(f,format,tableoffset,getdelta) + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + coverage[index]=value end -end -function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=readushort(f) - local format1=readushort(f) - local format2=readushort(f) - local sets=readarray(f) - sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) - coverage=readcoverage(f,tableoffset+coverage) - for index,newindex in next,coverage do - local set=sets[newindex+1] - local hash={} - for i=1,#set do - local value=set[i] - if value then - local other=value[1] - local first=value[2] - local second=value[3] - if first or second then - hash[other]={ first,second or nil } - else - hash[other]=nil - end - end - end - coverage[index]=hash + return { + format="single", + coverage=coverage, + } + elseif subtype==2 then + local coverage=readushort(f) + local format=readushort(f) + local nofvalues=readushort(f) + local values={} + for i=1,nofvalues do + values[i]=readposition(f,format,tableoffset,getdelta) + end + local coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + coverage[index]=values[newindex+1] + end + return { + format="single", + coverage=coverage, + } + else + report("unsupported subtype %a in %a positioning",subtype,"single") + end +end +function gposhandlers.pair(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=readushort(f) + local format1=readushort(f) + local format2=readushort(f) + local sets=readarray(f) + sets=readpairsets(f,tableoffset,sets,format1,format2,mainoffset,getdelta) + coverage=readcoverage(f,tableoffset+coverage) + for index,newindex in next,coverage do + local set=sets[newindex+1] + local hash={} + for i=1,#set do + local value=set[i] + if value then + local other=value[1] + local first=value[2] + local second=value[3] + if first or second then + hash[other]={ first,second or nil } + else + hash[other]=nil + end end - return { - format="pair", - coverage=coverage, - } - elseif subtype==2 then - local coverage=readushort(f) - local format1=readushort(f) - local format2=readushort(f) - local classdef1=readushort(f) - local classdef2=readushort(f) - local nofclasses1=readushort(f) - local nofclasses2=readushort(f) - local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) - coverage=readcoverage(f,tableoffset+coverage) - classdef1=readclassdef(f,tableoffset+classdef1,coverage) - classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) - local usedcoverage={} - for g1,c1 in next,classdef1 do - if coverage[g1] then - local l1=classlist[c1] - if l1 then - local hash={} - for paired,class in next,classdef2 do - local offsets=l1[class] - if offsets then - local first=offsets[1] - local second=offsets[2] - if first or second then - hash[paired]={ first,second or nil } - else - end - end - end - usedcoverage[g1]=hash - end + end + coverage[index]=hash + end + return { + format="pair", + coverage=coverage, + } + elseif subtype==2 then + local coverage=readushort(f) + local format1=readushort(f) + local format2=readushort(f) + local classdef1=readushort(f) + local classdef2=readushort(f) + local nofclasses1=readushort(f) + local nofclasses2=readushort(f) + local classlist=readpairclasssets(f,nofclasses1,nofclasses2,format1,format2,tableoffset,getdelta) + coverage=readcoverage(f,tableoffset+coverage) + classdef1=readclassdef(f,tableoffset+classdef1,coverage) + classdef2=readclassdef(f,tableoffset+classdef2,nofglyphs) + local usedcoverage={} + for g1,c1 in next,classdef1 do + if coverage[g1] then + local l1=classlist[c1] + if l1 then + local hash={} + for paired,class in next,classdef2 do + local offsets=l1[class] + if offsets then + local first=offsets[1] + local second=offsets[2] + if first or second then + hash[paired]={ first,second or nil } + else + end end + end + usedcoverage[g1]=hash end - return { - format="pair", - coverage=usedcoverage, - } - elseif subtype==3 then - report("yet unsupported subtype %a in %a positioning",subtype,"pair") - else - report("unsupported subtype %a in %a positioning",subtype,"pair") + end end + return { + format="pair", + coverage=usedcoverage, + } + elseif subtype==3 then + report("yet unsupported subtype %a in %a positioning",subtype,"pair") + else + report("unsupported subtype %a in %a positioning",subtype,"pair") + end end function gposhandlers.cursive(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local coverage=tableoffset+readushort(f) - local nofrecords=readushort(f) - local records={} - for i=1,nofrecords do - local entry=readushort(f) - local exit=readushort(f) - records[i]={ - entry~=0 and (tableoffset+entry) or false, - exit~=0 and (tableoffset+exit ) or nil, - } - end - local cc=(fontdata.temporary.cursivecount or 0)+1 - fontdata.temporary.cursivecount=cc - cc="cc-"..cc - coverage=readcoverage(f,coverage) - for i=1,nofrecords do - local r=records[i] - records[i]={ - cc, - readanchor(f,r[1],getdelta) or false, - readanchor(f,r[2],getdelta) or nil, - } - end - for index,newindex in next,coverage do - coverage[index]=records[newindex+1] - end - return { - coverage=coverage, - } - else - report("unsupported subtype %a in %a positioning",subtype,"cursive") + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local coverage=tableoffset+readushort(f) + local nofrecords=readushort(f) + local records={} + for i=1,nofrecords do + local entry=readushort(f) + local exit=readushort(f) + records[i]={ + entry~=0 and (tableoffset+entry) or false, + exit~=0 and (tableoffset+exit ) or nil, + } + end + local cc=(fontdata.temporary.cursivecount or 0)+1 + fontdata.temporary.cursivecount=cc + cc="cc-"..cc + coverage=readcoverage(f,coverage) + for i=1,nofrecords do + local r=records[i] + records[i]={ + cc, + readanchor(f,r[1],getdelta) or false, + readanchor(f,r[2],getdelta) or nil, + } + end + for index,newindex in next,coverage do + coverage[index]=records[newindex+1] end + return { + coverage=coverage, + } + else + report("unsupported subtype %a in %a positioning",subtype,"cursive") + end end local function handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,ligature) - local tableoffset=lookupoffset+offset - setposition(f,tableoffset) - local subtype=readushort(f) - local getdelta=fontdata.temporary.getdelta - if subtype==1 then - local markcoverage=tableoffset+readushort(f) - local basecoverage=tableoffset+readushort(f) - local nofclasses=readushort(f) - local markoffset=tableoffset+readushort(f) - local baseoffset=tableoffset+readushort(f) - local markcoverage=readcoverage(f,markcoverage) - local basecoverage=readcoverage(f,basecoverage,true) - setposition(f,markoffset) - local markclasses={} - local nofmarkclasses=readushort(f) - local lastanchor=fontdata.lastanchor or 0 - local usedanchors={} - for i=1,nofmarkclasses do - local class=readushort(f)+1 - local offset=readushort(f) - if offset==0 then - markclasses[i]=false - else - markclasses[i]={ class,markoffset+offset } - end - usedanchors[class]=true - end - for i=1,nofmarkclasses do - local mc=markclasses[i] - if mc then - mc[2]=readanchor(f,mc[2],getdelta) - end - end - setposition(f,baseoffset) - local nofbaserecords=readushort(f) - local baserecords={} - if ligature then - for i=1,nofbaserecords do - local offset=readushort(f) - if offset==0 then - baserecords[i]=false - else - baserecords[i]=baseoffset+offset - end - end - for i=1,nofbaserecords do - local recordoffset=baserecords[i] - if recordoffset then - setposition(f,recordoffset) - local nofcomponents=readushort(f) - local components={} - for i=1,nofcomponents do - local classes={} - for i=1,nofclasses do - local offset=readushort(f) - if offset~=0 then - classes[i]=recordoffset+offset - else - classes[i]=false - end - end - components[i]=classes - end - baserecords[i]=components - end - end - local baseclasses={} - for i=1,nofclasses do - baseclasses[i]={} - end - for i=1,nofbaserecords do - local components=baserecords[i] - if components then - local b=basecoverage[i] - for c=1,#components do - local classes=components[c] - if classes then - for i=1,nofclasses do - local anchor=readanchor(f,classes[i],getdelta) - local bclass=baseclasses[i] - local bentry=bclass[b] - if bentry then - bentry[c]=anchor - else - bclass[b]={ [c]=anchor } - end - end - end - end - end - end - for index,newindex in next,markcoverage do - markcoverage[index]=markclasses[newindex+1] or nil - end - return { - format="ligature", - baseclasses=baseclasses, - coverage=markcoverage, - } + local tableoffset=lookupoffset+offset + setposition(f,tableoffset) + local subtype=readushort(f) + local getdelta=fontdata.temporary.getdelta + if subtype==1 then + local markcoverage=tableoffset+readushort(f) + local basecoverage=tableoffset+readushort(f) + local nofclasses=readushort(f) + local markoffset=tableoffset+readushort(f) + local baseoffset=tableoffset+readushort(f) + local markcoverage=readcoverage(f,markcoverage) + local basecoverage=readcoverage(f,basecoverage,true) + setposition(f,markoffset) + local markclasses={} + local nofmarkclasses=readushort(f) + local lastanchor=fontdata.lastanchor or 0 + local usedanchors={} + for i=1,nofmarkclasses do + local class=readushort(f)+1 + local offset=readushort(f) + if offset==0 then + markclasses[i]=false + else + markclasses[i]={ class,markoffset+offset } + end + usedanchors[class]=true + end + for i=1,nofmarkclasses do + local mc=markclasses[i] + if mc then + mc[2]=readanchor(f,mc[2],getdelta) + end + end + setposition(f,baseoffset) + local nofbaserecords=readushort(f) + local baserecords={} + if ligature then + for i=1,nofbaserecords do + local offset=readushort(f) + if offset==0 then + baserecords[i]=false else - for i=1,nofbaserecords do - local r={} - for j=1,nofclasses do - local offset=readushort(f) - if offset==0 then - r[j]=false - else - r[j]=baseoffset+offset - end - end - baserecords[i]=r - end - local baseclasses={} + baserecords[i]=baseoffset+offset + end + end + for i=1,nofbaserecords do + local recordoffset=baserecords[i] + if recordoffset then + setposition(f,recordoffset) + local nofcomponents=readushort(f) + local components={} + for i=1,nofcomponents do + local classes={} for i=1,nofclasses do - baseclasses[i]={} + local offset=readushort(f) + if offset~=0 then + classes[i]=recordoffset+offset + else + classes[i]=false + end end - for i=1,nofbaserecords do - local r=baserecords[i] - local b=basecoverage[i] - for j=1,nofclasses do - baseclasses[j][b]=readanchor(f,r[j],getdelta) + components[i]=classes + end + baserecords[i]=components + end + end + local baseclasses={} + for i=1,nofclasses do + baseclasses[i]={} + end + for i=1,nofbaserecords do + local components=baserecords[i] + if components then + local b=basecoverage[i] + for c=1,#components do + local classes=components[c] + if classes then + for i=1,nofclasses do + local anchor=readanchor(f,classes[i],getdelta) + local bclass=baseclasses[i] + local bentry=bclass[b] + if bentry then + bentry[c]=anchor + else + bclass[b]={ [c]=anchor } end + end end - for index,newindex in next,markcoverage do - markcoverage[index]=markclasses[newindex+1] or nil - end - return { - format="base", - baseclasses=baseclasses, - coverage=markcoverage, - } + end end + end + for index,newindex in next,markcoverage do + markcoverage[index]=markclasses[newindex+1] or nil + end + return { + format="ligature", + baseclasses=baseclasses, + coverage=markcoverage, + } else - report("unsupported subtype %a in",subtype) - end + for i=1,nofbaserecords do + local r={} + for j=1,nofclasses do + local offset=readushort(f) + if offset==0 then + r[j]=false + else + r[j]=baseoffset+offset + end + end + baserecords[i]=r + end + local baseclasses={} + for i=1,nofclasses do + baseclasses[i]={} + end + for i=1,nofbaserecords do + local r=baserecords[i] + local b=basecoverage[i] + for j=1,nofclasses do + baseclasses[j][b]=readanchor(f,r[j],getdelta) + end + end + for index,newindex in next,markcoverage do + markcoverage[index]=markclasses[newindex+1] or nil + end + return { + format="base", + baseclasses=baseclasses, + coverage=markcoverage, + } + end + else + report("unsupported subtype %a in",subtype) + end end function gposhandlers.marktobase(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) end function gposhandlers.marktoligature(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,true) end function gposhandlers.marktomark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) + return handlemark(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) end function gposhandlers.context(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context" + return unchainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"context" end function gposhandlers.chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext" + return chainedcontext(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,"positioning"),"chainedcontext" end function gposhandlers.extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs) - return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning") + return extension(f,fontdata,lookupid,lookupoffset,offset,glyphs,nofglyphs,gpostypes,gposhandlers,"positioning") end do - local plugins={} - function plugins.size(f,fontdata,tableoffset,feature) - if fontdata.designsize then + local plugins={} + function plugins.size(f,fontdata,tableoffset,feature) + if fontdata.designsize then + else + local function check(offset) + setposition(f,offset) + local designsize=readushort(f) + if designsize>0 then + local fontstyleid=readushort(f) + local guimenuid=readushort(f) + local minsize=readushort(f) + local maxsize=readushort(f) + if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then + minsize=designsize + maxsize=designsize + end + if designsize>=minsize and designsize<=maxsize then + return minsize,maxsize,designsize + end + end + end + local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) + if not designsize then + minsize,maxsize,designsize=check(tableoffset+feature.parameters) + if designsize then + report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") else - local function check(offset) - setposition(f,offset) - local designsize=readushort(f) - if designsize>0 then - local fontstyleid=readushort(f) - local guimenuid=readushort(f) - local minsize=readushort(f) - local maxsize=readushort(f) - if minsize==0 and maxsize==0 and fontstyleid==0 and guimenuid==0 then - minsize=designsize - maxsize=designsize - end - if designsize>=minsize and designsize<=maxsize then - return minsize,maxsize,designsize - end + report("bad size feature in %a,",fontdata.filename or "?") + end + end + if designsize then + fontdata.minsize=minsize + fontdata.maxsize=maxsize + fontdata.designsize=designsize + end + end + end + local function reorderfeatures(fontdata,scripts,features) + local scriptlangs={} + local featurehash={} + local featureorder={} + for script,languages in next,scripts do + for language,record in next,languages do + local hash={} + local list=record.featureindices + for k=1,#list do + local index=list[k] + local feature=features[index] + local lookups=feature.lookups + local tag=feature.tag + if tag then + hash[tag]=true + end + if lookups then + for i=1,#lookups do + local lookup=lookups[i] + local o=featureorder[lookup] + if o then + local okay=true + for i=1,#o do + if o[i]==tag then + okay=false + break + end end - end - local minsize,maxsize,designsize=check(tableoffset+feature.offset+feature.parameters) - if not designsize then - minsize,maxsize,designsize=check(tableoffset+feature.parameters) - if designsize then - report("bad size feature in %a, falling back to wrong offset",fontdata.filename or "?") - else - report("bad size feature in %a,",fontdata.filename or "?") + if okay then + o[#o+1]=tag end - end - if designsize then - fontdata.minsize=minsize - fontdata.maxsize=maxsize - fontdata.designsize=designsize - end - end - end - local function reorderfeatures(fontdata,scripts,features) - local scriptlangs={} - local featurehash={} - local featureorder={} - for script,languages in next,scripts do - for language,record in next,languages do - local hash={} - local list=record.featureindices - for k=1,#list do - local index=list[k] - local feature=features[index] - local lookups=feature.lookups - local tag=feature.tag - if tag then - hash[tag]=true - end - if lookups then - for i=1,#lookups do - local lookup=lookups[i] - local o=featureorder[lookup] - if o then - local okay=true - for i=1,#o do - if o[i]==tag then - okay=false - break - end - end - if okay then - o[#o+1]=tag - end - else - featureorder[lookup]={ tag } - end - local f=featurehash[lookup] - if f then - local h=f[tag] - if h then - local s=h[script] - if s then - s[language]=true - else - h[script]={ [language]=true } - end - else - f[tag]={ [script]={ [language]=true } } - end - else - featurehash[lookup]={ [tag]={ [script]={ [language]=true } } } - end - local h=scriptlangs[tag] - if h then - local s=h[script] - if s then - s[language]=true - else - h[script]={ [language]=true } - end - else - scriptlangs[tag]={ [script]={ [language]=true } } - end - end - end + else + featureorder[lookup]={ tag } + end + local f=featurehash[lookup] + if f then + local h=f[tag] + if h then + local s=h[script] + if s then + s[language]=true + else + h[script]={ [language]=true } + end + else + f[tag]={ [script]={ [language]=true } } end - end - end - return scriptlangs,featurehash,featureorder - end - local function readscriplan(f,fontdata,scriptoffset) - setposition(f,scriptoffset) - local nofscripts=readushort(f) - local scripts={} - for i=1,nofscripts do - scripts[readtag(f)]=scriptoffset+readushort(f) - end - local languagesystems=setmetatableindex("table") - for script,offset in next,scripts do - setposition(f,offset) - local defaultoffset=readushort(f) - local noflanguages=readushort(f) - local languages={} - if defaultoffset>0 then - languages.dflt=languagesystems[offset+defaultoffset] - end - for i=1,noflanguages do - local language=readtag(f) - local offset=offset+readushort(f) - languages[language]=languagesystems[offset] - end - scripts[script]=languages - end - for offset,usedfeatures in next,languagesystems do - if offset>0 then - setposition(f,offset) - local featureindices={} - usedfeatures.featureindices=featureindices - usedfeatures.lookuporder=readushort(f) - usedfeatures.requiredindex=readushort(f) - local noffeatures=readushort(f) - for i=1,noffeatures do - featureindices[i]=readushort(f)+1 + else + featurehash[lookup]={ [tag]={ [script]={ [language]=true } } } + end + local h=scriptlangs[tag] + if h then + local s=h[script] + if s then + s[language]=true + else + h[script]={ [language]=true } end + else + scriptlangs[tag]={ [script]={ [language]=true } } + end end + end end - return scripts - end - local function readfeatures(f,fontdata,featureoffset) - setposition(f,featureoffset) - local features={} + end + end + return scriptlangs,featurehash,featureorder + end + local function readscriplan(f,fontdata,scriptoffset) + setposition(f,scriptoffset) + local nofscripts=readushort(f) + local scripts={} + for i=1,nofscripts do + scripts[readtag(f)]=scriptoffset+readushort(f) + end + local languagesystems=setmetatableindex("table") + for script,offset in next,scripts do + setposition(f,offset) + local defaultoffset=readushort(f) + local noflanguages=readushort(f) + local languages={} + if defaultoffset>0 then + languages.dflt=languagesystems[offset+defaultoffset] + end + for i=1,noflanguages do + local language=readtag(f) + local offset=offset+readushort(f) + languages[language]=languagesystems[offset] + end + scripts[script]=languages + end + for offset,usedfeatures in next,languagesystems do + if offset>0 then + setposition(f,offset) + local featureindices={} + usedfeatures.featureindices=featureindices + usedfeatures.lookuporder=readushort(f) + usedfeatures.requiredindex=readushort(f) local noffeatures=readushort(f) for i=1,noffeatures do - features[i]={ - tag=readtag(f), - offset=readushort(f) - } - end - for i=1,noffeatures do - local feature=features[i] - local offset=featureoffset+feature.offset - setposition(f,offset) - local parameters=readushort(f) - local noflookups=readushort(f) - if noflookups>0 then - local lookups={} - feature.lookups=lookups - for j=1,noflookups do - lookups[j]=readushort(f)+1 - end + featureindices[i]=readushort(f)+1 + end + end + end + return scripts + end + local function readfeatures(f,fontdata,featureoffset) + setposition(f,featureoffset) + local features={} + local noffeatures=readushort(f) + for i=1,noffeatures do + features[i]={ + tag=readtag(f), + offset=readushort(f) + } + end + for i=1,noffeatures do + local feature=features[i] + local offset=featureoffset+feature.offset + setposition(f,offset) + local parameters=readushort(f) + local noflookups=readushort(f) + if noflookups>0 then + local lookups=readcardinaltable(f,noflookups,ushort) + feature.lookups=lookups + for j=1,noflookups do + lookups[j]=lookups[j]+1 + end + end + if parameters>0 then + feature.parameters=parameters + local plugin=plugins[feature.tag] + if plugin then + plugin(f,fontdata,featureoffset,feature) + end + end + end + return features + end + local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + setposition(f,lookupoffset) + local noflookups=readushort(f) + local lookups=readcardinaltable(f,noflookups,ushort) + for lookupid=1,noflookups do + local offset=lookups[lookupid] + setposition(f,lookupoffset+offset) + local subtables={} + local typebits=readushort(f) + local flagbits=readushort(f) + local lookuptype=lookuptypes[typebits] + local lookupflags=lookupflags[flagbits] + local nofsubtables=readushort(f) + for j=1,nofsubtables do + subtables[j]=offset+readushort(f) + end + local markclass=band(flagbits,0x0010)~=0 + if markclass then + markclass=readushort(f) + end + local markset=rshift(flagbits,8) + if markset>0 then + markclass=markset + end + lookups[lookupid]={ + type=lookuptype, + flags=lookupflags, + name=lookupid, + subtables=subtables, + markclass=markclass, + features=featurehash[lookupid], + order=featureorder[lookupid], + } + end + return lookups + end + local f_lookupname=formatters["%s_%s_%s"] + local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + local sequences=fontdata.sequences or {} + local sublookuplist=fontdata.sublookups or {} + fontdata.sequences=sequences + fontdata.sublookups=sublookuplist + local nofsublookups=#sublookuplist + local nofsequences=#sequences + local lastsublookup=nofsublookups + local lastsequence=nofsequences + local lookupnames=lookupnames[what] + local sublookuphash={} + local sublookupcheck={} + local glyphs=fontdata.glyphs + local nofglyphs=fontdata.nofglyphs or #glyphs + local noflookups=#lookups + local lookupprefix=sub(what,2,2) + local usedlookups=false + for lookupid=1,noflookups do + local lookup=lookups[lookupid] + local lookuptype=lookup.type + local subtables=lookup.subtables + local features=lookup.features + local handler=lookuphandlers[lookuptype] + if handler then + local nofsubtables=#subtables + local order=lookup.order + local flags=lookup.flags + if flags[1] then flags[1]="mark" end + if flags[2] then flags[2]="ligature" end + if flags[3] then flags[3]="base" end + local markclass=lookup.markclass + if nofsubtables>0 then + local steps={} + local nofsteps=0 + local oldtype=nil + for s=1,nofsubtables do + local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs) + if lt then + lookuptype=lt + if oldtype and lt~=oldtype then + report("messy %s lookup type %a and %a",what,lookuptype,oldtype) + end + oldtype=lookuptype end - if parameters>0 then - feature.parameters=parameters - local plugin=plugins[feature.tag] - if plugin then - plugin(f,fontdata,featureoffset,feature) + if not step then + report("unsupported %s lookup type %a",what,lookuptype) + else + nofsteps=nofsteps+1 + steps[nofsteps]=step + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before + local current=rule.current + local after=rule.after + local replacements=rule.replacements + if before then + for i=1,#before do + before[i]=tohash(before[i]) + end + rule.before=reversed(before) + end + if current then + if replacements then + local first=current[1] + local hash={} + local repl={} + for i=1,#first do + local c=first[i] + hash[c]=true + repl[c]=replacements[i] + end + rule.current={ hash } + rule.replacements=repl + else + for i=1,#current do + current[i]=tohash(current[i]) + end + end + else + end + if after then + for i=1,#after do + after[i]=tohash(after[i]) + end + end + if usedlookups then + local lookups=rule.lookups + if lookups then + for k,v in next,lookups do + if v then + for k,v in next,v do + usedlookups[v]=usedlookups[v]+1 + end + end + end + end + end end + end end - end - return features - end - local function readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - setposition(f,lookupoffset) - local lookups={} - local noflookups=readushort(f) - for i=1,noflookups do - lookups[i]=readushort(f) - end - for lookupid=1,noflookups do - local offset=lookups[lookupid] - setposition(f,lookupoffset+offset) - local subtables={} - local typebits=readushort(f) - local flagbits=readushort(f) - local lookuptype=lookuptypes[typebits] - local lookupflags=lookupflags[flagbits] - local nofsubtables=readushort(f) - for j=1,nofsubtables do - subtables[j]=offset+readushort(f) - end - local markclass=band(flagbits,0x0010)~=0 - if markclass then - markclass=readushort(f) - end - local markset=rshift(flagbits,8) - if markset>0 then - markclass=markset - end - lookups[lookupid]={ - type=lookuptype, - flags=lookupflags, - name=lookupid, - subtables=subtables, - markclass=markclass, - features=featurehash[lookupid], - order=featureorder[lookupid], + end + if nofsteps~=nofsubtables then + report("bogus subtables removed in %s lookup type %a",what,lookuptype) + end + lookuptype=lookupnames[lookuptype] or lookuptype + if features then + nofsequences=nofsequences+1 + local l={ + index=nofsequences, + name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset), + steps=steps, + nofsteps=nofsteps, + type=lookuptype, + markclass=markclass or nil, + flags=flags, + order=order, + features=features, } - end - return lookups - end - local f_lookupname=formatters["%s_%s_%s"] - local function resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) - local sequences=fontdata.sequences or {} - local sublookuplist=fontdata.sublookups or {} - fontdata.sequences=sequences - fontdata.sublookups=sublookuplist - local nofsublookups=#sublookuplist - local nofsequences=#sequences - local lastsublookup=nofsublookups - local lastsequence=nofsequences - local lookupnames=lookupnames[what] - local sublookuphash={} - local sublookupcheck={} - local glyphs=fontdata.glyphs - local nofglyphs=fontdata.nofglyphs or #glyphs - local noflookups=#lookups - local lookupprefix=sub(what,2,2) - local usedlookups=false - for lookupid=1,noflookups do - local lookup=lookups[lookupid] - local lookuptype=lookup.type - local subtables=lookup.subtables - local features=lookup.features - local handler=lookuphandlers[lookuptype] - if handler then - local nofsubtables=#subtables - local order=lookup.order - local flags=lookup.flags - if flags[1] then flags[1]="mark" end - if flags[2] then flags[2]="ligature" end - if flags[3] then flags[3]="base" end - local markclass=lookup.markclass - if nofsubtables>0 then - local steps={} - local nofsteps=0 - local oldtype=nil - for s=1,nofsubtables do - local step,lt=handler(f,fontdata,lookupid,lookupoffset,subtables[s],glyphs,nofglyphs) - if lt then - lookuptype=lt - if oldtype and lt~=oldtype then - report("messy %s lookup type %a and %a",what,lookuptype,oldtype) - end - oldtype=lookuptype - end - if not step then - report("unsupported %s lookup type %a",what,lookuptype) + sequences[nofsequences]=l + lookup.done=l + else + nofsublookups=nofsublookups+1 + local l={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset), + steps=steps, + nofsteps=nofsteps, + type=lookuptype, + markclass=markclass or nil, + flags=flags, + } + sublookuplist[nofsublookups]=l + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=0 + lookup.done=l + end + else + report("no subtables for lookup %a",lookupid) + end + else + report("no handler for lookup %a with type %a",lookupid,lookuptype) + end + end + if usedlookups then + report("used %s lookups: % t",what,sortedkeys(usedlookups)) + end + local reported={} + local function report_issue(i,what,sequence,kind) + local name=sequence.name + if not reported[name] then + report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) + reported[name]=true + end + end + for i=lastsequence+1,nofsequences do + local sequence=sequences[i] + local steps=sequence.steps + for i=1,#steps do + local step=steps[i] + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local rlookups=rule.lookups + if not rlookups then + report_issue(i,what,sequence,"no") + elseif not next(rlookups) then + rule.lookups=nil + else + local length=#rlookups + for index=1,length do + local lookuplist=rlookups[index] + if lookuplist then + local length=#lookuplist + local found={} + local noffound=0 + for index=1,length do + local lookupid=lookuplist[index] + if lookupid then + local h=sublookuphash[lookupid] + if not h then + local lookup=lookups[lookupid] + if lookup then + local d=lookup.done + if d then + nofsublookups=nofsublookups+1 + local l={ + index=nofsublookups, + name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), + derived=true, + steps=d.steps, + nofsteps=d.nofsteps, + type=d.lookuptype or "gsub_single", + markclass=d.markclass or nil, + flags=d.flags, + } + sublookuplist[nofsublookups]=copy(l) + sublookuphash[lookupid]=nofsublookups + sublookupcheck[lookupid]=1 + h=nofsublookups + else + report_issue(i,what,sequence,"missing") + rule.lookups=nil + break + end else - nofsteps=nofsteps+1 - steps[nofsteps]=step - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before - local current=rule.current - local after=rule.after - local replacements=rule.replacements - if before then - for i=1,#before do - before[i]=tohash(before[i]) - end - rule.before=reversed(before) - end - if current then - if replacements then - local first=current[1] - local hash={} - local repl={} - for i=1,#first do - local c=first[i] - hash[c]=true - repl[c]=replacements[i] - end - rule.current={ hash } - rule.replacements=repl - else - for i=1,#current do - current[i]=tohash(current[i]) - end - end - else - end - if after then - for i=1,#after do - after[i]=tohash(after[i]) - end - end - if usedlookups then - local lookups=rule.lookups - if lookups then - for k,v in next,lookups do - if v then - for k,v in next,v do - usedlookups[v]=usedlookups[v]+1 - end - end - end - end - end - end - end - end - end - if nofsteps~=nofsubtables then - report("bogus subtables removed in %s lookup type %a",what,lookuptype) - end - lookuptype=lookupnames[lookuptype] or lookuptype - if features then - nofsequences=nofsequences+1 - local l={ - index=nofsequences, - name=f_lookupname(lookupprefix,"s",lookupid+lookupidoffset), - steps=steps, - nofsteps=nofsteps, - type=lookuptype, - markclass=markclass or nil, - flags=flags, - order=order, - features=features, - } - sequences[nofsequences]=l - lookup.done=l - else - nofsublookups=nofsublookups+1 - local l={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"l",lookupid+lookupidoffset), - steps=steps, - nofsteps=nofsteps, - type=lookuptype, - markclass=markclass or nil, - flags=flags, - } - sublookuplist[nofsublookups]=l - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=0 - lookup.done=l - end + report_issue(i,what,sequence,"bad") + rule.lookups=nil + break + end + else + sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 + end + if h then + noffound=noffound+1 + found[noffound]=h + end + end + end + rlookups[index]=noffound>0 and found or false else - report("no subtables for lookup %a",lookupid) + rlookups[index]=false end - else - report("no handler for lookup %a with type %a",lookupid,lookuptype) + end end + end end - if usedlookups then - report("used %s lookups: % t",what,sortedkeys(usedlookups)) + end + end + for i,n in sortedhash(sublookupcheck) do + local l=lookups[i] + local t=l.type + if n==0 and t~="extension" then + local d=l.done + report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) + end + end + end + local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + setposition(f,variationsoffset) + local version=readulong(f) + local nofrecords=readulong(f) + local records={} + for i=1,nofrecords do + records[i]={ + conditions=readulong(f), + substitutions=readulong(f), + } + end + for i=1,nofrecords do + local record=records[i] + local offset=record.conditions + if offset==0 then + record.condition=nil + record.matchtype="always" + else + local offset=variationsoffset+offset + setposition(f,offset) + local nofconditions=readushort(f) + local conditions={} + for i=1,nofconditions do + conditions[i]=offset+readulong(f) + end + record.conditions=conditions + record.matchtype="condition" + end + end + for i=1,nofrecords do + local record=records[i] + if record.matchtype=="condition" then + local conditions=record.conditions + for i=1,#conditions do + setposition(f,conditions[i]) + conditions[i]={ + format=readushort(f), + axis=readushort(f), + minvalue=read2dot14(f), + maxvalue=read2dot14(f), + } + end + end + end + for i=1,nofrecords do + local record=records[i] + local offset=record.substitutions + if offset==0 then + record.substitutions={} + else + setposition(f,variationsoffset+offset) + local version=readulong(f) + local nofsubstitutions=readushort(f) + local substitutions={} + for i=1,nofsubstitutions do + substitutions[readushort(f)]=readulong(f) + end + for index,alternates in sortedhash(substitutions) do + if index==0 then + record.substitutions=false + else + local tableoffset=variationsoffset+offset+alternates + setposition(f,tableoffset) + local parameters=readulong(f) + local noflookups=readushort(f) + local lookups=readcardinaltable(f,noflookups,ushort) + record.substitutions=lookups + end end - local reported={} - local function report_issue(i,what,sequence,kind) - local name=sequence.name - if not reported[name] then - report("rule %i in %s lookup %a has %s lookups",i,what,name,kind) - reported[name]=true - end + end + end + setvariabledata(fontdata,"features",records) + end + local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) + local tableoffset=gotodatatable(f,fontdata,what,true) + if tableoffset then + local version=readulong(f) + local scriptoffset=tableoffset+readushort(f) + local featureoffset=tableoffset+readushort(f) + local lookupoffset=tableoffset+readushort(f) + local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 + if not scriptoffset then + return + end + local scripts=readscriplan(f,fontdata,scriptoffset) + local features=readfeatures(f,fontdata,featureoffset) + local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) + if fontdata.features then + fontdata.features[what]=scriptlangs + else + fontdata.features={ [what]=scriptlangs } + end + if not lookupstoo then + return + end + local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) + if lookups then + resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + end + if variationsoffset>0 then + loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + end + end + end + local function checkkerns(f,fontdata,specification) + local datatable=fontdata.tables.kern + if not datatable then + return + end + local features=fontdata.features + local gposfeatures=features and features.gpos + local name + if not gposfeatures or not gposfeatures.kern then + name="kern" + elseif specification.globalkerns then + name="globalkern" + else + report("ignoring global kern table, using gpos kern feature") + return + end + setposition(f,datatable.offset) + local version=readushort(f) + local noftables=readushort(f) + if noftables>1 then + report("adding global kern table as gpos feature %a",name) + local kerns=setmetatableindex("table") + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + for i=1,nofpairs do + kerns[readushort(f)][readushort(f)]=readfword(f) + end + elseif format==2 then + else end - for i=lastsequence+1,nofsequences do - local sequence=sequences[i] - local steps=sequence.steps - for i=1,#steps do - local step=steps[i] - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local rlookups=rule.lookups - if not rlookups then - report_issue(i,what,sequence,"no") - elseif not next(rlookups) then - report_issue(i,what,sequence,"empty") - rule.lookups=nil - else - local length=#rlookups - for index=1,length do - local lookuplist=rlookups[index] - if lookuplist then - local length=#lookuplist - local found={} - local noffound=0 - for index=1,length do - local lookupid=lookuplist[index] - if lookupid then - local h=sublookuphash[lookupid] - if not h then - local lookup=lookups[lookupid] - if lookup then - local d=lookup.done - if d then - nofsublookups=nofsublookups+1 - local l={ - index=nofsublookups, - name=f_lookupname(lookupprefix,"d",lookupid+lookupidoffset), - derived=true, - steps=d.steps, - nofsteps=d.nofsteps, - type=d.lookuptype or "gsub_single", - markclass=d.markclass or nil, - flags=d.flags, - } - sublookuplist[nofsublookups]=copy(l) - sublookuphash[lookupid]=nofsublookups - sublookupcheck[lookupid]=1 - h=nofsublookups - else - report_issue(i,what,sequence,"missing") - rule.lookups=nil - break - end - else - report_issue(i,what,sequence,"bad") - rule.lookups=nil - break - end - else - sublookupcheck[lookupid]=sublookupcheck[lookupid]+1 - end - if h then - noffound=noffound+1 - found[noffound]=h - end - end - end - rlookups[index]=noffound>0 and found or false - else - rlookups[index]=false - end - end - end - end - end - end + end + local feature={ dflt={ dflt=true } } + if not features then + fontdata.features={ gpos={ [name]=feature } } + elseif not gposfeatures then + fontdata.features.gpos={ [name]=feature } + else + gposfeatures[name]=feature + end + local sequences=fontdata.sequences + if not sequences then + sequences={} + fontdata.sequences=sequences + end + local nofsequences=#sequences+1 + sequences[nofsequences]={ + index=nofsequences, + name=name, + steps={ + { + coverage=kerns, + format="kern", + }, + }, + nofsteps=1, + type="gpos_pair", + flags={ false,false,false,false }, + order={ name }, + features={ [name]=feature }, + } + else + report("ignoring empty kern table of feature %a",name) + end + end + function readers.gsub(f,fontdata,specification) + if specification.details then + readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups) + end + end + function readers.gpos(f,fontdata,specification) + if specification.details then + readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups) + if specification.lookups then + checkkerns(f,fontdata,specification) + end + end + end +end +function readers.gdef(f,fontdata,specification) + if not specification.glyphs then + return + end + local datatable=fontdata.tables.gdef + if datatable then + local tableoffset=datatable.offset + setposition(f,tableoffset) + local version=readulong(f) + local classoffset=readushort(f) + local attachmentoffset=readushort(f) + local ligaturecarets=readushort(f) + local markclassoffset=readushort(f) + local marksetsoffset=version>=0x00010002 and readushort(f) or 0 + local varsetsoffset=version>=0x00010003 and readulong(f) or 0 + local glyphs=fontdata.glyphs + local marks={} + local markclasses=setmetatableindex("table") + local marksets=setmetatableindex("table") + fontdata.marks=marks + fontdata.markclasses=markclasses + fontdata.marksets=marksets + if classoffset~=0 then + setposition(f,tableoffset+classoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + local class=classes[readushort(f)] + if class=="mark" then + marks[index]=true + end + glyphs[index].class=class end - for i,n in sortedhash(sublookupcheck) do - local l=lookups[i] - local t=l.type - if n==0 and t~="extension" then - local d=l.done - report("%s lookup %s of type %a is not used",what,d and d.name or l.name,t) + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=classes[readushort(f)] + if class then + for index=firstindex,lastindex do + glyphs[index].class=class + if class=="mark" then + marks[index]=true + end end + end end + end end - local function loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) - setposition(f,variationsoffset) - local version=readulong(f) - local nofrecords=readulong(f) - local records={} - for i=1,nofrecords do - records[i]={ - conditions=readulong(f), - substitutions=readulong(f), - } + if markclassoffset~=0 then + setposition(f,tableoffset+markclassoffset) + local classformat=readushort(f) + if classformat==1 then + local firstindex=readushort(f) + local lastindex=firstindex+readushort(f)-1 + for index=firstindex,lastindex do + markclasses[readushort(f)][index]=true end - for i=1,nofrecords do - local record=records[i] - local offset=record.conditions - if offset==0 then - record.condition=nil - record.matchtype="always" - else - setposition(f,variationsoffset+offset) - local nofconditions=readushort(f) - local conditions={} - for i=1,nofconditions do - conditions[i]=variationsoffset+offset+readulong(f) - end - record.conditions=conditions - record.matchtype="condition" - end - end - for i=1,nofrecords do - local record=records[i] - if record.matchtype=="condition" then - local conditions=record.conditions - for i=1,#conditions do - setposition(f,conditions[i]) - conditions[i]={ - format=readushort(f), - axis=readushort(f), - minvalue=read2dot14(f), - maxvalue=read2dot14(f), - } + elseif classformat==2 then + local nofranges=readushort(f) + for i=1,nofranges do + local firstindex=readushort(f) + local lastindex=readushort(f) + local class=markclasses[readushort(f)] + for index=firstindex,lastindex do + class[index]=true + end + end + end + end + if marksetsoffset~=0 then + marksetsoffset=tableoffset+marksetsoffset + setposition(f,marksetsoffset) + local format=readushort(f) + if format==1 then + local nofsets=readushort(f) + local sets=readcardinaltable(f,nofsets,ulong) + for i=1,nofsets do + local offset=sets[i] + if offset~=0 then + marksets[i]=readcoverage(f,marksetsoffset+offset) + end + end + end + end + local factors=specification.factors + if (specification.variable or factors) and varsetsoffset~=0 then + local regions,deltas=readvariationdata(f,tableoffset+varsetsoffset,factors) + if factors then + fontdata.temporary.getdelta=function(outer,inner) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + local di=d[i] + if di then + dd=dd+scales[i]*di + else + break end + end + return round(dd) end + end + return 0 end - for i=1,nofrecords do - local record=records[i] - local offset=record.substitutions - if offset==0 then - record.substitutions={} + end + end + end +end +local function readmathvalue(f) + local v=readshort(f) + skipshort(f,1) + return v +end +local function readmathconstants(f,fontdata,offset) + setposition(f,offset) + fontdata.mathconstants={ + ScriptPercentScaleDown=readshort(f), + ScriptScriptPercentScaleDown=readshort(f), + DelimitedSubFormulaMinHeight=readushort(f), + DisplayOperatorMinHeight=readushort(f), + MathLeading=readmathvalue(f), + AxisHeight=readmathvalue(f), + AccentBaseHeight=readmathvalue(f), + FlattenedAccentBaseHeight=readmathvalue(f), + SubscriptShiftDown=readmathvalue(f), + SubscriptTopMax=readmathvalue(f), + SubscriptBaselineDropMin=readmathvalue(f), + SuperscriptShiftUp=readmathvalue(f), + SuperscriptShiftUpCramped=readmathvalue(f), + SuperscriptBottomMin=readmathvalue(f), + SuperscriptBaselineDropMax=readmathvalue(f), + SubSuperscriptGapMin=readmathvalue(f), + SuperscriptBottomMaxWithSubscript=readmathvalue(f), + SpaceAfterScript=readmathvalue(f), + UpperLimitGapMin=readmathvalue(f), + UpperLimitBaselineRiseMin=readmathvalue(f), + LowerLimitGapMin=readmathvalue(f), + LowerLimitBaselineDropMin=readmathvalue(f), + StackTopShiftUp=readmathvalue(f), + StackTopDisplayStyleShiftUp=readmathvalue(f), + StackBottomShiftDown=readmathvalue(f), + StackBottomDisplayStyleShiftDown=readmathvalue(f), + StackGapMin=readmathvalue(f), + StackDisplayStyleGapMin=readmathvalue(f), + StretchStackTopShiftUp=readmathvalue(f), + StretchStackBottomShiftDown=readmathvalue(f), + StretchStackGapAboveMin=readmathvalue(f), + StretchStackGapBelowMin=readmathvalue(f), + FractionNumeratorShiftUp=readmathvalue(f), + FractionNumeratorDisplayStyleShiftUp=readmathvalue(f), + FractionDenominatorShiftDown=readmathvalue(f), + FractionDenominatorDisplayStyleShiftDown=readmathvalue(f), + FractionNumeratorGapMin=readmathvalue(f), + FractionNumeratorDisplayStyleGapMin=readmathvalue(f), + FractionRuleThickness=readmathvalue(f), + FractionDenominatorGapMin=readmathvalue(f), + FractionDenominatorDisplayStyleGapMin=readmathvalue(f), + SkewedFractionHorizontalGap=readmathvalue(f), + SkewedFractionVerticalGap=readmathvalue(f), + OverbarVerticalGap=readmathvalue(f), + OverbarRuleThickness=readmathvalue(f), + OverbarExtraAscender=readmathvalue(f), + UnderbarVerticalGap=readmathvalue(f), + UnderbarRuleThickness=readmathvalue(f), + UnderbarExtraDescender=readmathvalue(f), + RadicalVerticalGap=readmathvalue(f), + RadicalDisplayStyleVerticalGap=readmathvalue(f), + RadicalRuleThickness=readmathvalue(f), + RadicalExtraAscender=readmathvalue(f), + RadicalKernBeforeDegree=readmathvalue(f), + RadicalKernAfterDegree=readmathvalue(f), + RadicalDegreeBottomRaisePercent=readshort(f), + } +end +local function readmathglyphinfo(f,fontdata,offset) + setposition(f,offset) + local italics=readushort(f) + local accents=readushort(f) + local extensions=readushort(f) + local kerns=readushort(f) + local glyphs=fontdata.glyphs + if italics~=0 then + setposition(f,offset+italics) + local coverage=readushort(f) + local nofglyphs=readushort(f) + coverage=readcoverage(f,offset+italics+coverage,true) + setposition(f,offset+italics+4) + for i=1,nofglyphs do + local italic=readmathvalue(f) + if italic~=0 then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if not math then + glyph.math={ italic=italic } + else + math.italic=italic + end + end + end + fontdata.hasitalics=true + end + if accents~=0 then + setposition(f,offset+accents) + local coverage=readushort(f) + local nofglyphs=readushort(f) + coverage=readcoverage(f,offset+accents+coverage,true) + setposition(f,offset+accents+4) + for i=1,nofglyphs do + local accent=readmathvalue(f) + if accent~=0 then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if not math then + glyph.math={ accent=accent } + else + math.accent=accent + end + end + end + end + if extensions~=0 then + setposition(f,offset+extensions) + end + if kerns~=0 then + local kernoffset=offset+kerns + setposition(f,kernoffset) + local coverage=readushort(f) + local nofglyphs=readushort(f) + if nofglyphs>0 then + local function get(offset) + setposition(f,kernoffset+offset) + local n=readushort(f) + if n==0 then + local k=readmathvalue(f) + if k==0 then + else + return { { kern=k } } + end + else + local l={} + for i=1,n do + l[i]={ height=readmathvalue(f) } + end + for i=1,n do + l[i].kern=readmathvalue(f) + end + l[n+1]={ kern=readmathvalue(f) } + return l + end + end + local kernsets={} + for i=1,nofglyphs do + local topright=readushort(f) + local topleft=readushort(f) + local bottomright=readushort(f) + local bottomleft=readushort(f) + kernsets[i]={ + topright=topright~=0 and topright or nil, + topleft=topleft~=0 and topleft or nil, + bottomright=bottomright~=0 and bottomright or nil, + bottomleft=bottomleft~=0 and bottomleft or nil, + } + end + coverage=readcoverage(f,kernoffset+coverage,true) + for i=1,nofglyphs do + local kernset=kernsets[i] + if next(kernset) then + local k=kernset.topright if k then kernset.topright=get(k) end + local k=kernset.topleft if k then kernset.topleft=get(k) end + local k=kernset.bottomright if k then kernset.bottomright=get(k) end + local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end + if next(kernset) then + local glyph=glyphs[coverage[i]] + local math=glyph.math + if math then + math.kerns=kernset else - setposition(f,variationsoffset+offset) - local version=readulong(f) - local nofsubstitutions=readushort(f) - local substitutions={} - for i=1,nofsubstitutions do - substitutions[readushort(f)]=readulong(f) - end - for index,alternates in sortedhash(substitutions) do - if index==0 then - record.substitutions=false - else - local tableoffset=variationsoffset+offset+alternates - setposition(f,tableoffset) - local parameters=readulong(f) - local noflookups=readushort(f) - local lookups={} - for i=1,noflookups do - lookups[i]=readushort(f) - end - record.substitutions=lookups - end - end + glyph.math={ kerns=kernset } end + end end - setvariabledata(fontdata,"features",records) - end - local function readscripts(f,fontdata,what,lookuptypes,lookuphandlers,lookupstoo) - local tableoffset=gotodatatable(f,fontdata,what,true) - if tableoffset then - local version=readulong(f) - local scriptoffset=tableoffset+readushort(f) - local featureoffset=tableoffset+readushort(f) - local lookupoffset=tableoffset+readushort(f) - local variationsoffset=version>0x00010000 and (tableoffset+readulong(f)) or 0 - if not scriptoffset then - return - end - local scripts=readscriplan(f,fontdata,scriptoffset) - local features=readfeatures(f,fontdata,featureoffset) - local scriptlangs,featurehash,featureorder=reorderfeatures(fontdata,scripts,features) - if fontdata.features then - fontdata.features[what]=scriptlangs + end + end + end +end +local function readmathvariants(f,fontdata,offset) + setposition(f,offset) + local glyphs=fontdata.glyphs + local minoverlap=readushort(f) + local vcoverage=readushort(f) + local hcoverage=readushort(f) + local vnofglyphs=readushort(f) + local hnofglyphs=readushort(f) + local vconstruction=readcardinaltable(f,vnofglyphs,ushort) + local hconstruction=readcardinaltable(f,hnofglyphs,ushort) + fontdata.mathconstants.MinConnectorOverlap=minoverlap + local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic) + if coverage~=0 and nofglyphs>0 then + local coverage=readcoverage(f,offset+coverage,true) + for i=1,nofglyphs do + local c=construction[i] + if c~=0 then + local index=coverage[i] + local glyph=glyphs[index] + local math=glyph.math + setposition(f,offset+c) + local assembly=readushort(f) + local nofvariants=readushort(f) + if nofvariants>0 then + local variants,v=nil,0 + for i=1,nofvariants do + local variant=readushort(f) + if variant==index then + elseif variants then + v=v+1 + variants[v]=variant + else + v=1 + variants={ variant } + end + skipshort(f) + end + if not variants then + elseif not math then + math={ [kvariants]=variants } + glyph.math=math else - fontdata.features={ [what]=scriptlangs } + math[kvariants]=variants end - if not lookupstoo then - return + end + if assembly~=0 then + setposition(f,offset+c+assembly) + local italic=readmathvalue(f) + local nofparts=readushort(f) + local parts={} + for i=1,nofparts do + local p={ + glyph=readushort(f), + start=readushort(f), + ["end"]=readushort(f), + advance=readushort(f), + } + local flags=readushort(f) + if band(flags,0x0001)~=0 then + p.extender=1 + end + parts[i]=p end - local lookups=readlookups(f,lookupoffset,lookuptypes,featurehash,featureorder) - if lookups then - resolvelookups(f,lookupoffset,fontdata,lookups,lookuptypes,lookuphandlers,what,tableoffset) + if not math then + math={ + [kparts]=parts + } + glyph.math=math + else + math[kparts]=parts end - if variationsoffset>0 then - loadvariations(f,fontdata,variationsoffset,lookuptypes,featurehash,featureorder) + if italic and italic~=0 then + math[kitalic]=italic end + end end + end end - local function checkkerns(f,fontdata,specification) - local datatable=fontdata.tables.kern - if not datatable then - return - end - local features=fontdata.features - local gposfeatures=features and features.gpos - local name - if not gposfeatures or not gposfeatures.kern then - name="kern" - elseif specification.globalkerns then - name="globalkern" - else - report("ignoring global kern table using gpos kern feature") - return - end - setposition(f,datatable.offset) - local version=readushort(f) - local noftables=readushort(f) - if noftables>1 then - report("adding global kern table as gpos feature %a",name) - local kerns=setmetatableindex("table") - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - for i=1,nofpairs do - kerns[readushort(f)][readushort(f)]=readfword(f) - end - elseif format==2 then - else - end - end - local feature={ dflt={ dflt=true } } - if not features then - fontdata.features={ gpos={ [name]=feature } } - elseif not gposfeatures then - fontdata.features.gpos={ [name]=feature } - else - gposfeatures[name]=feature - end - local sequences=fontdata.sequences - if not sequences then - sequences={} - fontdata.sequences=sequences - end - local nofsequences=#sequences+1 - sequences[nofsequences]={ - index=nofsequences, - name=name, - steps={ - { - coverage=kerns, - format="kern", - }, - }, - nofsteps=1, - type="gpos_pair", - flags={ false,false,false,false }, - order={ name }, - features={ [name]=feature }, - } - else - report("ignoring empty kern table of feature %a",name) - end + end + get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic") + get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") +end +function readers.math(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) + if tableoffset then + local version=readulong(f) + local constants=readushort(f) + local glyphinfo=readushort(f) + local variants=readushort(f) + if constants==0 then + report("the math table of %a has no constants",fontdata.filename) + else + readmathconstants(f,fontdata,tableoffset+constants) end - function readers.gsub(f,fontdata,specification) - if specification.details then - readscripts(f,fontdata,"gsub",gsubtypes,gsubhandlers,specification.lookups) - end + if glyphinfo~=0 then + readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) end - function readers.gpos(f,fontdata,specification) - if specification.details then - readscripts(f,fontdata,"gpos",gpostypes,gposhandlers,specification.lookups) - if specification.lookups then - checkkerns(f,fontdata,specification) - end - end + if variants~=0 then + readmathvariants(f,fontdata,tableoffset+variants) end + end end -function readers.gdef(f,fontdata,specification) - if not specification.glyphs then - return +function readers.colr(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) + if tableoffset then + local version=readushort(f) + if version~=0 then + report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) + return end - local datatable=fontdata.tables.gdef - if datatable then - local tableoffset=datatable.offset - setposition(f,tableoffset) - local version=readulong(f) - local classoffset=readushort(f) - local attachmentoffset=readushort(f) - local ligaturecarets=readushort(f) - local markclassoffset=readushort(f) - local marksetsoffset=version>=0x00010002 and readushort(f) or 0 - local varsetsoffset=version>=0x00010003 and readulong(f) or 0 - local glyphs=fontdata.glyphs - local marks={} - local markclasses=setmetatableindex("table") - local marksets=setmetatableindex("table") - fontdata.marks=marks - fontdata.markclasses=markclasses - fontdata.marksets=marksets - if classoffset~=0 then - setposition(f,tableoffset+classoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - local class=classes[readushort(f)] - if class=="mark" then - marks[index]=true - end - glyphs[index].class=class - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=classes[readushort(f)] - if class then - for index=firstindex,lastindex do - glyphs[index].class=class - if class=="mark" then - marks[index]=true - end - end - end - end + if not fontdata.tables.cpal then + report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") + fontdata.colorpalettes={} + end + local glyphs=fontdata.glyphs + local nofglyphs=readushort(f) + local baseoffset=readulong(f) + local layeroffset=readulong(f) + local noflayers=readushort(f) + local layerrecords={} + local maxclass=0 + setposition(f,tableoffset+layeroffset) + for i=1,noflayers do + local slot=readushort(f) + local class=readushort(f) + if class<0xFFFF then + class=class+1 + if class>maxclass then + maxclass=class + end + end + layerrecords[i]={ + slot=slot, + class=class, + } + end + fontdata.maxcolorclass=maxclass + setposition(f,tableoffset+baseoffset) + for i=0,nofglyphs-1 do + local glyphindex=readushort(f) + local firstlayer=readushort(f) + local noflayers=readushort(f) + local t={} + for i=1,noflayers do + t[i]=layerrecords[firstlayer+i] + end + glyphs[glyphindex].colors=t + end + end + fontdata.hascolor=true +end +function readers.cpal(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) + if tableoffset then + local version=readushort(f) + local nofpaletteentries=readushort(f) + local nofpalettes=readushort(f) + local nofcolorrecords=readushort(f) + local firstcoloroffset=readulong(f) + local colorrecords={} + local palettes=readcardinaltable(f,nofpalettes,ushort) + if version==1 then + local palettettypesoffset=readulong(f) + local palettelabelsoffset=readulong(f) + local paletteentryoffset=readulong(f) + end + setposition(f,tableoffset+firstcoloroffset) + for i=1,nofcolorrecords do + local b,g,r,a=readbytes(f,4) + colorrecords[i]={ + r,g,b,a~=255 and a or nil, + } + end + for i=1,nofpalettes do + local p={} + local o=palettes[i] + for j=1,nofpaletteentries do + p[j]=colorrecords[o+j] + end + palettes[i]=p + end + fontdata.colorpalettes=palettes + end +end +function readers.svg(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) + if tableoffset then + local version=readushort(f) + local glyphs=fontdata.glyphs + local indexoffset=tableoffset+readulong(f) + local reserved=readulong(f) + setposition(f,indexoffset) + local nofentries=readushort(f) + local entries={} + for i=1,nofentries do + entries[i]={ + first=readushort(f), + last=readushort(f), + offset=indexoffset+readulong(f), + length=readulong(f), + } + end + for i=1,nofentries do + local entry=entries[i] + setposition(f,entry.offset) + entries[i]={ + first=entry.first, + last=entry.last, + data=readstring(f,entry.length) + } + end + fontdata.svgshapes=entries + end + fontdata.hascolor=true +end +function readers.sbix(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) + if tableoffset then + local version=readushort(f) + local flags=readushort(f) + local nofstrikes=readulong(f) + local strikes={} + local nofglyphs=fontdata.nofglyphs + for i=1,nofstrikes do + strikes[i]=readulong(f) + end + local shapes={} + local done=0 + for i=1,nofstrikes do + local strikeoffset=strikes[i]+tableoffset + setposition(f,strikeoffset) + strikes[i]={ + ppem=readushort(f), + ppi=readushort(f), + offset=strikeoffset + } + end + sort(strikes,function(a,b) + if b.ppem==a.ppem then + return b.ppi0 then + setposition(f,strikeoffset+glyphoffset) + shapes[i]={ + x=readshort(f), + y=readshort(f), + tag=readtag(f), + data=readstring(f,datasize-8), + ppem=strikeppem, + ppi=strikeppi, + } + done=done+1 + if done==nofglyphs then + break end + end end - if markclassoffset~=0 then - setposition(f,tableoffset+markclassoffset) - local classformat=readushort(f) - if classformat==1 then - local firstindex=readushort(f) - local lastindex=firstindex+readushort(f)-1 - for index=firstindex,lastindex do - markclasses[readushort(f)][index]=true - end - elseif classformat==2 then - local nofranges=readushort(f) - for i=1,nofranges do - local firstindex=readushort(f) - local lastindex=readushort(f) - local class=markclasses[readushort(f)] - for index=firstindex,lastindex do - class[index]=true - end - end - end + glyphoffset=nextoffset + end + end + fontdata.pngshapes=shapes + end +end +do + local function getmetrics(f) + return { + ascender=readinteger(f), + descender=readinteger(f), + widthmax=readuinteger(f), + caretslopedumerator=readinteger(f), + caretslopedenominator=readinteger(f), + caretoffset=readinteger(f), + minorigin=readinteger(f), + minadvance=readinteger(f), + maxbefore=readinteger(f), + minafter=readinteger(f), + pad1=readinteger(f), + pad2=readinteger(f), + } + end + local function getbigmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + horiBearingX=readinteger(f), + horiBearingY=readinteger(f), + horiAdvance=readuinteger(f), + vertBearingX=readinteger(f), + vertBearingY=readinteger(f), + vertAdvance=readuinteger(f), + } + end + local function getsmallmetrics(f) + return { + height=readuinteger(f), + width=readuinteger(f), + bearingX=readinteger(f), + bearingY=readinteger(f), + advance=readuinteger(f), + } + end + function readers.cblc(f,fontdata,specification) + local ctdttableoffset=gotodatatable(f,fontdata,"cbdt",specification.glyphs) + if not ctdttableoffset then + return + end + local cblctableoffset=gotodatatable(f,fontdata,"cblc",specification.glyphs) + if cblctableoffset then + local majorversion=readushort(f) + local minorversion=readushort(f) + local nofsizetables=readulong(f) + local sizetables={} + local shapes={} + local subtables={} + for i=1,nofsizetables do + sizetables[i]={ + subtables=readulong(f), + indexsize=readulong(f), + nofsubtables=readulong(f), + colorref=readulong(f), + hormetrics=getmetrics(f), + vermetrics=getmetrics(f), + firstindex=readushort(f), + lastindex=readushort(f), + ppemx=readbyte(f), + ppemy=readbyte(f), + bitdepth=readbyte(f), + flags=readbyte(f), + } + end + sort(sizetables,function(a,b) + if b.ppemx==a.ppemx then + return b.bitdepth=lastto then + else + values[#values+1]={ f,t } + lastfrom,lastto=f,t + end + end + nofvalues=#values + if nofvalues>2 then + local some=values[1] + if some[1]==-1 and some[2]==-1 then + some=values[nofvalues] + if some[1]==1 and some[2]==1 then + for i=2,nofvalues-1 do + some=values[i] + if some[1]==0 and some[2]==0 then + return values + end + end + end + end + end + return false + end + local version=readulong(f) + local reserved=readushort(f) + local nofaxis=readushort(f) + local segments={} + for i=1,nofaxis do + segments[i]=collect() + end + setvariabledata(fontdata,"segments",segments) + end end -local function readmathglyphinfo(f,fontdata,offset) - setposition(f,offset) - local italics=readushort(f) - local accents=readushort(f) - local extensions=readushort(f) - local kerns=readushort(f) +function readers.fvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"fvar",true) + if tableoffset then + local version=readulong(f) + local offsettoaxis=tableoffset+readushort(f) + local reserved=skipshort(f) + local nofaxis=readushort(f) + local sizeofaxis=readushort(f) + local nofinstances=readushort(f) + local sizeofinstances=readushort(f) + local extras=fontdata.extras + local axis={} + local instances={} + setposition(f,offsettoaxis) + for i=1,nofaxis do + axis[i]={ + tag=readtag(f), + minimum=readfixed(f), + default=readfixed(f), + maximum=readfixed(f), + flags=readushort(f), + name=lower(extras[readushort(f)] or "bad name"), + } + local n=sizeofaxis-20 + if n>0 then + skipbytes(f,n) + elseif n<0 then + end + end + local nofbytes=2+2+2+nofaxis*4 + local readpsname=nofbytes<=sizeofinstances + local skippable=sizeofinstances-nofbytes + for i=1,nofinstances do + local subfamid=readushort(f) + local flags=readushort(f) + local values={} + for i=1,nofaxis do + values[i]={ + axis=axis[i].tag, + value=readfixed(f), + } + end + local psnameid=readpsname and readushort(f) or 0xFFFF + if subfamid==2 or subfamid==17 then + elseif subfamid==0xFFFF then + subfamid=nil + elseif subfamid<=256 or subfamid>=32768 then + subfamid=nil + end + if psnameid==6 then + elseif psnameid==0xFFFF then + psnameid=nil + elseif psnameid<=256 or psnameid>=32768 then + psnameid=nil + end + instances[i]={ + subfamily=extras[subfamid], + psname=psnameid and extras[psnameid] or nil, + values=values, + } + if skippable>0 then + skipbytes(f,skippable) + end + end + setvariabledata(fontdata,"axis",axis) + setvariabledata(fontdata,"instances",instances) + end +end +function readers.hvar(f,fontdata,specification) + local factors=specification.factors + if not factors then + return + end + local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) + if not tableoffset then + return + end + local version=readulong(f) + local variationoffset=tableoffset+readulong(f) + local advanceoffset=tableoffset+readulong(f) + local lsboffset=tableoffset+readulong(f) + local rsboffset=tableoffset+readulong(f) + local regions={} + local variations={} + local innerindex={} + local outerindex={} + if variationoffset>0 then + regions,deltas=readvariationdata(f,variationoffset,factors) + end + if not regions then + return + end + if advanceoffset>0 then + setposition(f,advanceoffset) + local format=readushort(f) + local mapcount=readushort(f) + local entrysize=rshift(band(format,0x0030),4)+1 + local nofinnerbits=band(format,0x000F)+1 + local innermask=lshift(1,nofinnerbits)-1 + local readcardinal=read_cardinal[entrysize] + for i=0,mapcount-1 do + local mapdata=readcardinal(f) + outerindex[i]=rshift(mapdata,nofinnerbits) + innerindex[i]=band(mapdata,innermask) + end + setvariabledata(fontdata,"hvarwidths",true) local glyphs=fontdata.glyphs - if italics~=0 then - setposition(f,offset+italics) - local coverage=readushort(f) - local nofglyphs=readushort(f) - coverage=readcoverage(f,offset+italics+coverage,true) - setposition(f,offset+italics+4) - for i=1,nofglyphs do - local italic=readmathvalue(f) - if italic~=0 then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if not math then - glyph.math={ italic=italic } + for i=0,fontdata.nofglyphs-1 do + local glyph=glyphs[i] + local width=glyph.width + if width then + local outer=outerindex[i] or 0 + local inner=innerindex[i] or i + if outer and inner then + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local deltaw=0 + for i=1,#scales do + local di=d[i] + if di then + deltaw=deltaw+scales[i]*di else - math.italic=italic + break end + end + glyph.width=width+round(deltaw) end + end end - fontdata.hasitalics=true + end end - if accents~=0 then - setposition(f,offset+accents) - local coverage=readushort(f) - local nofglyphs=readushort(f) - coverage=readcoverage(f,offset+accents+coverage,true) - setposition(f,offset+accents+4) - for i=1,nofglyphs do - local accent=readmathvalue(f) - if accent~=0 then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if not math then - glyph.math={ accent=accent } - else - math.accent=accent - end + end +end +function readers.vvar(f,fontdata,specification) + if not specification.variable then + return + end +end +function readers.mvar(f,fontdata,specification) + local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) + if tableoffset then + local version=readulong(f) + local reserved=skipshort(f,1) + local recordsize=readushort(f) + local nofrecords=readushort(f) + local offsettostore=tableoffset+readushort(f) + local dimensions={} + local factors=specification.factors + if factors then + local regions,deltas=readvariationdata(f,offsettostore,factors) + for i=1,nofrecords do + local tag=readtag(f) + local var=variabletags[tag] + if var then + local outer=readushort(f) + local inner=readushort(f) + local delta=deltas[outer+1] + if delta then + local d=delta.deltas[inner+1] + if d then + local scales=delta.scales + local dd=0 + for i=1,#scales do + dd=dd+scales[i]*d[i] + end + var(fontdata,round(dd)) end + end + else + skipshort(f,2) end + if recordsize>8 then + skipbytes(recordsize-8) + end + end + end + end +end + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-oup']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type=next,type +local P,R,S=lpeg.P,lpeg.R,lpeg.S +local lpegmatch=lpeg.match +local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack +local formatters=string.formatters +local sortedkeys=table.sortedkeys +local sortedhash=table.sortedhash +local tohash=table.tohash +local setmetatableindex=table.setmetatableindex +local report_error=logs.reporter("otf reader","error") +local report_markwidth=logs.reporter("otf reader","markwidth") +local report_cleanup=logs.reporter("otf reader","cleanup") +local report_optimizations=logs.reporter("otf reader","merges") +local report_unicodes=logs.reporter("otf reader","unicodes") +local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end) +local trace_cleanup=false trackers.register("otf.cleanups",function(v) trace_cleanups=v end) +local trace_optimizations=false trackers.register("otf.optimizations",function(v) trace_optimizations=v end) +local trace_unicodes=false trackers.register("otf.unicodes",function(v) trace_unicodes=v end) +local readers=fonts.handlers.otf.readers +local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 +local f_private=formatters["P%05X"] +local f_unicode=formatters["U%05X"] +local f_index=formatters["I%05X"] +local f_character_y=formatters["%C"] +local f_character_n=formatters["[ %C ]"] +local check_duplicates=true +local check_soft_hyphen=true +directives.register("otf.checksofthyphen",function(v) + check_soft_hyphen=v +end) +local function replaced(list,index,replacement) + if type(list)=="number" then + return replacement + elseif type(replacement)=="table" then + local t={} + local n=index-1 + for i=1,n do + t[i]=list[i] end - if extensions~=0 then - setposition(f,offset+extensions) + for i=1,#replacement do + n=n+1 + t[n]=replacement[i] end - if kerns~=0 then - local kernoffset=offset+kerns - setposition(f,kernoffset) - local coverage=readushort(f) - local nofglyphs=readushort(f) - if nofglyphs>0 then - local function get(offset) - setposition(f,kernoffset+offset) - local n=readushort(f) - if n==0 then - local k=readmathvalue(f) - if k==0 then + for i=index+1,#list do + n=n+1 + t[n]=list[i] + end + else + list[index]=replacement + return list + end +end +local function unifyresources(fontdata,indices) + local descriptions=fontdata.descriptions + local resources=fontdata.resources + if not descriptions or not resources then + return + end + local nofindices=#indices + local variants=fontdata.resources.variants + if variants then + for selector,unicodes in next,variants do + for unicode,index in next,unicodes do + unicodes[unicode]=indices[index] + end + end + end + local function remark(marks) + if marks then + local newmarks={} + for k,v in next,marks do + local u=indices[k] + if u then + newmarks[u]=v + elseif trace_optimizations then + report_optimizations("discarding mark %i",k) + end + end + return newmarks + end + end + local marks=resources.marks + if marks then + resources.marks=remark(marks) + end + local markclasses=resources.markclasses + if markclasses then + for class,marks in next,markclasses do + markclasses[class]=remark(marks) + end + end + local marksets=resources.marksets + if marksets then + for class,marks in next,marksets do + marksets[class]=remark(marks) + end + end + local done={} + local duplicates=check_duplicates and resources.duplicates + if duplicates and not next(duplicates) then + duplicates=false + end + local function recover(cover) + for i=1,#cover do + local c=cover[i] + if not done[c] then + local t={} + for k,v in next,c do + local ug=indices[k] + if ug then + t[ug]=v + else + report_error("case %i, bad index in unifying %s: %s of %s",1,"coverage",k,nofindices) + end + end + cover[i]=t + done[c]=d + end + end + end + local function recursed(c,kind) + local t={} + for g,d in next,c do + if type(d)=="table" then + local ug=indices[g] + if ug then + t[ug]=recursed(d,kind) + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g,nofindices) + end + else + t[g]=indices[d] + end + end + return t + end + local function unifythem(sequences) + if not sequences then + return + end + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gsub_single" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + local ud1=indices[d1] + if ud1 then + t1[ug1]=ud1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=ud1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",3,kind,d1,nofindices) + end else - return { { kern=k } } + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) end + end else - local l={} - for i=1,n do - l[i]={ height=readmathvalue(f) } - end - for i=1,n do - l[i].kern=readmathvalue(f) + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=indices[d1] + else + report_error("fuzzy case %i in unifying %s: %i",2,kind,g1) end - l[n+1]={ kern=readmathvalue(f) } - return l + end end + done[c]=t1 + end + step.coverage=t1 end - local kernsets={} - for i=1,nofglyphs do - local topright=readushort(f) - local topleft=readushort(f) - local bottomright=readushort(f) - local bottomleft=readushort(f) - kernsets[i]={ - topright=topright~=0 and topright or nil, - topleft=topleft~=0 and topleft or nil, - bottomright=bottomright~=0 and bottomright or nil, - bottomleft=bottomleft~=0 and bottomleft or nil, - } - end - coverage=readcoverage(f,kernoffset+coverage,true) - for i=1,nofglyphs do - local kernset=kernsets[i] - if next(kernset) then - local k=kernset.topright if k then kernset.topright=get(k) end - local k=kernset.topleft if k then kernset.topleft=get(k) end - local k=kernset.bottomright if k then kernset.bottomright=get(k) end - local k=kernset.bottomleft if k then kernset.bottomleft=get(k) end - if next(kernset) then - local glyph=glyphs[coverage[i]] - local math=glyph.math - if math then - math.kerns=kernset + elseif kind=="gpos_pair" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + local t2=done[d1] + if not t2 then + t2={} + for g2,d2 in next,d1 do + local ug2=indices[g2] + if ug2 then + t2[ug2]=d2 else - glyph.math={ kerns=kernset } + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g2,nofindices,nofindices) end + end + done[d1]=t2 end + t1[ug1]=t2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) + end end + done[c]=t1 + end + step.coverage=t1 end - end - end -end -local function readmathvariants(f,fontdata,offset) - setposition(f,offset) - local glyphs=fontdata.glyphs - local minoverlap=readushort(f) - local vcoverage=readushort(f) - local hcoverage=readushort(f) - local vnofglyphs=readushort(f) - local hnofglyphs=readushort(f) - local vconstruction={} - local hconstruction={} - for i=1,vnofglyphs do - vconstruction[i]=readushort(f) - end - for i=1,hnofglyphs do - hconstruction[i]=readushort(f) - end - fontdata.mathconstants.MinConnectorOverlap=minoverlap - local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic) - if coverage~=0 and nofglyphs>0 then - local coverage=readcoverage(f,offset+coverage,true) - for i=1,nofglyphs do - local c=construction[i] - if c~=0 then - local index=coverage[i] - local glyph=glyphs[index] - local math=glyph.math - setposition(f,offset+c) - local assembly=readushort(f) - local nofvariants=readushort(f) - if nofvariants>0 then - local variants,v=nil,0 - for i=1,nofvariants do - local variant=readushort(f) - if variant==index then - elseif variants then - v=v+1 - variants[v]=variant - else - v=1 - variants={ variant } - end - skipshort(f) - end - if not variants then - elseif not math then - math={ [kvariants]=variants } - glyph.math=math - else - math[kvariants]=variants - end + elseif kind=="gsub_ligature" then + local c=step.coverage + if c then + step.coverage=recursed(c,kind) + end + elseif kind=="gsub_alternate" or kind=="gsub_multiple" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + for i=1,#d1 do + local d1i=d1[i] + local d1u=indices[d1i] + if d1u then + d1[i]=d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,i,d1i,nofindices) + end + end + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=copy(d1) + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) end - if assembly~=0 then - setposition(f,offset+c+assembly) - local italic=readmathvalue(f) - local nofparts=readushort(f) - local parts={} - for i=1,nofparts do - local p={ - glyph=readushort(f), - start=readushort(f), - ["end"]=readushort(f), - advance=readushort(f), - } - local flags=readushort(f) - if band(flags,0x0001)~=0 then - p.extender=1 - end - parts[i]=p - end - if not math then - math={ - [kparts]=parts - } - glyph.math=math - else - math[kparts]=parts - end - if italic and italic~=0 then - math[kitalic]=italic - end + end + else + for g1,d1 in next,c do + for i=1,#d1 do + local d1i=d1[i] + local d1u=indices[d1i] + if d1u then + d1[i]=d1u + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,d1i,nofindices) + end + end + t1[indices[g1]]=d1 + end + end + done[c]=t1 + end + step.coverage=t1 + end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + if duplicates then + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + local dg1=duplicates[ug1] + if dg1 then + for u in next,dg1 do + t1[u]=d1 + end + end + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + else + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) end + end end + done[c]=t1 + end + step.coverage=t1 end - end - end - get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic") - get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic") -end -function readers.math(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs) - if tableoffset then - local version=readulong(f) - local constants=readushort(f) - local glyphinfo=readushort(f) - local variants=readushort(f) - if constants==0 then - report("the math table of %a has no constants",fontdata.filename) - else - readmathconstants(f,fontdata,tableoffset+constants) - end - if glyphinfo~=0 then - readmathglyphinfo(f,fontdata,tableoffset+glyphinfo) - end - if variants~=0 then - readmathvariants(f,fontdata,tableoffset+variants) - end - end -end -function readers.colr(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs) - if tableoffset then - local version=readushort(f) - if version~=0 then - report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename) - return - end - if not fontdata.tables.cpal then - report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal") - fontdata.colorpalettes={} - end - local glyphs=fontdata.glyphs - local nofglyphs=readushort(f) - local baseoffset=readulong(f) - local layeroffset=readulong(f) - local noflayers=readushort(f) - local layerrecords={} - local maxclass=0 - setposition(f,tableoffset+layeroffset) - for i=1,noflayers do - local slot=readushort(f) - local class=readushort(f) - if class<0xFFFF then - class=class+1 - if class>maxclass then - maxclass=class - end - end - layerrecords[i]={ - slot=slot, - class=class, - } - end - fontdata.maxcolorclass=maxclass - setposition(f,tableoffset+baseoffset) - for i=0,nofglyphs-1 do - local glyphindex=readushort(f) - local firstlayer=readushort(f) - local noflayers=readushort(f) - local t={} - for i=1,noflayers do - t[i]=layerrecords[firstlayer+i] - end - glyphs[glyphindex].colors=t - end - end - fontdata.hascolor=true -end -function readers.cpal(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"cpal",specification.glyphs) - if tableoffset then - local version=readushort(f) - local nofpaletteentries=readushort(f) - local nofpalettes=readushort(f) - local nofcolorrecords=readushort(f) - local firstcoloroffset=readulong(f) - local colorrecords={} - local palettes={} - for i=1,nofpalettes do - palettes[i]=readushort(f) - end - if version==1 then - local palettettypesoffset=readulong(f) - local palettelabelsoffset=readulong(f) - local paletteentryoffset=readulong(f) - end - setposition(f,tableoffset+firstcoloroffset) - for i=1,nofcolorrecords do - local b,g,r,a=readbytes(f,4) - colorrecords[i]={ - r,g,b,a~=255 and a or nil, - } - end - for i=1,nofpalettes do - local p={} - local o=palettes[i] - for j=1,nofpaletteentries do - p[j]=colorrecords[o+j] + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then + local c=step.coverage + if c then + local t1=done[c] + if not t1 then + t1={} + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",1,kind,g1,nofindices) + end + end + done[c]=t1 + end + step.coverage=t1 end - palettes[i]=p - end - fontdata.colorpalettes=palettes - end -end -function readers.svg(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) - if tableoffset then - local version=readushort(f) - local glyphs=fontdata.glyphs - local indexoffset=tableoffset+readulong(f) - local reserved=readulong(f) - setposition(f,indexoffset) - local nofentries=readushort(f) - local entries={} - for i=1,nofentries do - entries[i]={ - first=readushort(f), - last=readushort(f), - offset=indexoffset+readulong(f), - length=readulong(f), - } - end - for i=1,nofentries do - local entry=entries[i] - setposition(f,entry.offset) - entries[i]={ - first=entry.first, - last=entry.last, - data=readstring(f,entry.length) - } - end - fontdata.svgshapes=entries - end - fontdata.hascolor=true -end -function readers.sbix(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"sbix",specification.glyphs) - if tableoffset then - local version=readushort(f) - local flags=readushort(f) - local nofstrikes=readulong(f) - local strikes={} - local nofglyphs=fontdata.nofglyphs - for i=1,nofstrikes do - strikes[i]=readulong(f) - end - local shapes={} - local done=0 - for i=1,nofstrikes do - local strikeoffset=strikes[i]+tableoffset - setposition(f,strikeoffset) - strikes[i]={ - ppem=readushort(f), - ppi=readushort(f), - offset=strikeoffset - } + local c=step.baseclasses + if c then + local t1=done[c] + if not t1 then + for g1,d1 in next,c do + local t2=done[d1] + if not t2 then + t2={} + for g2,d2 in next,d1 do + local ug2=indices[g2] + if ug2 then + t2[ug2]=d2 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g2,nofindices) + end + end + done[d1]=t2 + end + c[g1]=t2 + end + done[c]=c + end end - sort(strikes,function(a,b) - if b.ppem==a.ppem then - return b.ppi0 then - setposition(f,strikeoffset+glyphoffset) - shapes[i]={ - x=readshort(f), - y=readshort(f), - tag=readtag(f), - data=readstring(f,datasize-8), - ppem=strikeppem, - ppi=strikeppi, - } - done=done+1 - if done==nofglyphs then - break - end - end + for g1,d1 in next,c do + local ug1=indices[g1] + if ug1 then + t1[ug1]=d1 + else + report_error("case %i, bad index in unifying %s: %s of %s",2,kind,g1,nofindices) end - glyphoffset=nextoffset + end end + done[c]=t1 + end + step.coverage=t1 end - fontdata.sbixshapes=shapes - end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before if before then recover(before) end + local after=rule.after if after then recover(after) end + local current=rule.current if current then recover(current) end + local replacements=rule.replacements + if replacements then + if not done[replacements] then + local r={} + for k,v in next,replacements do + r[indices[k]]=indices[v] + end + rule.replacements=r + done[replacements]=r + end + end + end + end + end + end + end + end + unifythem(resources.sequences) + unifythem(resources.sublookups) end -function readers.stat(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"stat",true) - if tableoffset then - local extras=fontdata.extras - local version=readulong(f) - local axissize=readushort(f) - local nofaxis=readushort(f) - local axisoffset=readulong(f) - local nofvalues=readushort(f) - local valuesoffset=readulong(f) - local fallbackname=extras[readushort(f)] - local axis={} - local values={} - setposition(f,tableoffset+axisoffset) - for i=1,nofaxis do - local tag=readtag(f) - axis[i]={ - tag=tag, - name=lower(extras[readushort(f)] or tag), - ordering=readushort(f), - variants={} - } +local function copyduplicates(fontdata) + if check_duplicates then + local descriptions=fontdata.descriptions + local resources=fontdata.resources + local duplicates=resources.duplicates + if check_soft_hyphen then + local ds=descriptions[0xAD] + if not ds or ds.width==0 then + if ds then + descriptions[0xAD]=nil + if trace_unicodes then + report_unicodes("patching soft hyphen") + end + else + if trace_unicodes then + report_unicodes("adding soft hyphen") + end end - setposition(f,tableoffset+valuesoffset) - for i=1,nofvalues do - values[i]=readushort(f) + if not duplicates then + duplicates={} + resources.duplicates=duplicates end - for i=1,nofvalues do - setposition(f,tableoffset+valuesoffset+values[i]) - local format=readushort(f) - local index=readushort(f)+1 - local flags=readushort(f) - local name=lower(extras[readushort(f)] or "no name") - local value=readfixed(f) - local variant - if format==1 then - variant={ - flags=flags, - name=name, - value=value, - } - elseif format==2 then - variant={ - flags=flags, - name=name, - value=value, - minimum=readfixed(f), - maximum=readfixed(f), - } - elseif format==3 then - variant={ - flags=flags, - name=name, - value=value, - link=readfixed(f), - } + local dh=duplicates[0x2D] + if dh then + dh[#dh+1]={ [0xAD]=true } + else + duplicates[0x2D]={ [0xAD]=true } + end + end + end + if duplicates then + for u,d in next,duplicates do + local du=descriptions[u] + if du then + local t={ f_character_y(u),"@",f_index(du.index),"->" } + local n=0 + local m=25 + for u in next,d do + if descriptions[u] then + if n=lastto then - else - values[#values+1]={ f,t } - lastfrom,lastto=f,t - end +local ignore={ + ["notdef"]=true, + [".notdef"]=true, + ["null"]=true, + [".null"]=true, + ["nonmarkingreturn"]=true, +} +local function checklookups(fontdata,missing,nofmissing) + local descriptions=fontdata.descriptions + local resources=fontdata.resources + if missing and nofmissing and nofmissing<=0 then + return + end + local singles={} + local alternates={} + local ligatures={} + if not missing then + missing={} + nofmissing=0 + for u,d in next,descriptions do + if not d.unicode then + nofmissing=nofmissing+1 + missing[u]=true + end + end + end + local function collectthem(sequences) + if not sequences then + return + end + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gsub_single" then + local c=step.coverage + if c then + singles[#singles+1]=c end - nofvalues=#values - if nofvalues>2 then - local some=values[1] - if some[1]==-1 and some[2]==-1 then - some=values[nofvalues] - if some[1]==1 and some[2]==1 then - for i=2,nofvalues-1 do - some=values[i] - if some[1]==0 and some[2]==0 then - return values - end - end - end - end + elseif kind=="gsub_alternate" then + local c=step.coverage + if c then + alternates[#alternates+1]=c end - return false + elseif kind=="gsub_ligature" then + local c=step.coverage + if c then + ligatures[#ligatures+1]=c + end + end end - local majorversion=readushort(f) - local minorversion=readushort(f) - local reserved=readushort(f) - local nofaxis=readushort(f) - local segments={} - for i=1,nofaxis do - segments[i]=collect() + end + end + end + collectthem(resources.sequences) + collectthem(resources.sublookups) + local loops=0 + while true do + loops=loops+1 + local old=nofmissing + for i=1,#singles do + local c=singles[i] + for g1,g2 in next,c do + if missing[g1] then + local u2=descriptions[g2].unicode + if u2 then + missing[g1]=false + descriptions[g1].unicode=u2 + nofmissing=nofmissing-1 + end + end + if missing[g2] then + local u1=descriptions[g1].unicode + if u1 then + missing[g2]=false + descriptions[g2].unicode=u1 + nofmissing=nofmissing-1 + end end - setvariabledata(fontdata,"segments",segments) + end end -end -function readers.fvar(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"fvar",true) - if tableoffset then - local version=readulong(f) - local offsettoaxis=tableoffset+readushort(f) - local reserved=skipshort(f) - local nofaxis=readushort(f) - local sizeofaxis=readushort(f) - local nofinstances=readushort(f) - local sizeofinstances=readushort(f) - local extras=fontdata.extras - local axis={} - local instances={} - setposition(f,offsettoaxis) - for i=1,nofaxis do - axis[i]={ - tag=readtag(f), - minimum=readfixed(f), - default=readfixed(f), - maximum=readfixed(f), - flags=readushort(f), - name=lower(extras[readushort(f)] or "bad name"), - } - local n=sizeofaxis-20 - if n>0 then - skipbytes(f,n) - elseif n<0 then - end - end - local nofbytes=2+2+2+nofaxis*4 - local readpsname=nofbytes<=sizeofinstances - local skippable=sizeofinstances-nofbytes - for i=1,nofinstances do - local subfamid=readushort(f) - local flags=readushort(f) - local values={} - for i=1,nofaxis do - values[i]={ - axis=axis[i].tag, - value=readfixed(f), - } + for i=1,#alternates do + local c=alternates[i] + for g1,d1 in next,c do + if missing[g1] then + for i=1,#d1 do + local g2=d1[i] + local u2=descriptions[g2].unicode + if u2 then + missing[g1]=false + descriptions[g1].unicode=u2 + nofmissing=nofmissing-1 end - local psnameid=readpsname and readushort(f) or 0xFFFF - if subfamid==2 or subfamid==17 then - elseif subfamid==0xFFFF then - subfamid=nil - elseif subfamid<=256 or subfamid>=32768 then - subfamid=nil - end - if psnameid==6 then - elseif psnameid==0xFFFF then - psnameid=nil - elseif psnameid<=256 or psnameid>=32768 then - psnameid=nil - end - instances[i]={ - subfamily=extras[subfamid], - psname=psnameid and extras[psnameid] or nil, - values=values, - } - if skippable>0 then - skipbytes(f,skippable) + end + end + if not missing[g1] then + for i=1,#d1 do + local g2=d1[i] + if missing[g2] then + local u1=descriptions[g1].unicode + if u1 then + missing[g2]=false + descriptions[g2].unicode=u1 + nofmissing=nofmissing-1 + end end + end end - setvariabledata(fontdata,"axis",axis) - setvariabledata(fontdata,"instances",instances) - end -end -function readers.hvar(f,fontdata,specification) - local factors=specification.factors - if not factors then - return - end - local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable) - if not tableoffset then - return - end - local version=readulong(f) - local variationoffset=tableoffset+readulong(f) - local advanceoffset=tableoffset+readulong(f) - local lsboffset=tableoffset+readulong(f) - local rsboffset=tableoffset+readulong(f) - local regions={} - local variations={} - local innerindex={} - local outerindex={} - if variationoffset>0 then - regions,deltas=readvariationdata(f,variationoffset,factors) - end - if not regions then - return - end - if advanceoffset>0 then - setposition(f,advanceoffset) - local format=readushort(f) - local mapcount=readushort(f) - local entrysize=rshift(band(format,0x0030),4)+1 - local nofinnerbits=band(format,0x000F)+1 - local innermask=lshift(1,nofinnerbits)-1 - local readcardinal=read_cardinal[entrysize] - for i=0,mapcount-1 do - local mapdata=readcardinal(f) - outerindex[i]=rshift(mapdata,nofinnerbits) - innerindex[i]=band(mapdata,innermask) - end - setvariabledata(fontdata,"hvarwidths",true) - local glyphs=fontdata.glyphs - for i=0,fontdata.nofglyphs-1 do - local glyph=glyphs[i] - local width=glyph.width - if width then - local outer=outerindex[i] or 0 - local inner=innerindex[i] or i - if outer and inner then - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local deltaw=0 - for i=1,#scales do - local di=d[i] - if di then - deltaw=deltaw+scales[i]*di - else - break - end - end - glyph.width=width+round(deltaw) - end - end - end + end + end + if nofmissing<=0 then + if trace_unicodes then + report_unicodes("all missings done in %s loops",loops) + end + return + elseif old==nofmissing then + break + end + end + local t,n + local function recursed(c) + for g,d in next,c do + if g~="ligature" then + local u=descriptions[g].unicode + if u then + n=n+1 + t[n]=u + recursed(d) + n=n-1 + end + elseif missing[d] then + local l={} + local m=0 + for i=1,n do + local u=t[i] + if type(u)=="table" then + for i=1,#u do + m=m+1 + l[m]=u[i] end + else + m=m+1 + l[m]=u + end end + missing[d]=false + descriptions[d].unicode=l + nofmissing=nofmissing-1 + end end -end -function readers.vvar(f,fontdata,specification) - if not specification.variable then + end + if nofmissing>0 then + t={} + n=0 + local loops=0 + while true do + loops=loops+1 + local old=nofmissing + for i=1,#ligatures do + recursed(ligatures[i]) + end + if nofmissing<=0 then + if trace_unicodes then + report_unicodes("all missings done in %s loops",loops) + end return + elseif old==nofmissing then + break + end end -end -function readers.mvar(f,fontdata,specification) - local tableoffset=gotodatatable(f,fontdata,"mvar",specification.variable) - if tableoffset then - local version=readulong(f) - local reserved=skipshort(f,1) - local recordsize=readushort(f) - local nofrecords=readushort(f) - local offsettostore=tableoffset+readushort(f) - local dimensions={} - local factors=specification.factors - if factors then - local regions,deltas=readvariationdata(f,offsettostore,factors) - for i=1,nofrecords do - local tag=readtag(f) - local var=variabletags[tag] - if var then - local outer=readushort(f) - local inner=readushort(f) - local delta=deltas[outer+1] - if delta then - local d=delta.deltas[inner+1] - if d then - local scales=delta.scales - local dd=0 - for i=1,#scales do - dd=dd+scales[i]*d[i] - end - var(fontdata,round(dd)) - end - end - else - skipshort(f,2) - end - if recordsize>8 then - skipbytes(recordsize-8) - end - end + t=nil + n=0 + end + if trace_unicodes and nofmissing>0 then + local done={} + for i,r in next,missing do + if r then + local data=descriptions[i] + local name=data and data.name or f_index(i) + if not ignore[name] then + done[name]=true end + end end + if next(done) then + report_unicodes("not unicoded: % t",sortedkeys(done)) + end + end end - -end -- closure - -do -- begin closure to overcome local limits and interference - -if not modules then modules={} end modules ['font-oup']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" -} -local next,type=next,type -local P,R,S=lpeg.P,lpeg.R,lpeg.S -local lpegmatch=lpeg.match -local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack -local formatters=string.formatters -local sortedkeys=table.sortedkeys -local sortedhash=table.sortedhash -local tohash=table.tohash -local setmetatableindex=table.setmetatableindex -local report=logs.reporter("otf reader") -local trace_markwidth=false trackers.register("otf.markwidth",function(v) trace_markwidth=v end) -local readers=fonts.handlers.otf.readers -local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 -local f_private=formatters["P%05X"] -local f_unicode=formatters["U%05X"] -local f_index=formatters["I%05X"] -local f_character_y=formatters["%C"] -local f_character_n=formatters["[ %C ]"] -local check_duplicates=true -local check_soft_hyphen=true -directives.register("otf.checksofthyphen",function(v) - check_soft_hyphen=v -end) -local function replaced(list,index,replacement) - if type(list)=="number" then - return replacement - elseif type(replacement)=="table" then - local t={} - local n=index-1 - for i=1,n do - t[i]=list[i] - end - for i=1,#replacement do - n=n+1 - t[n]=replacement[i] +local function unifymissing(fontdata) + if not fonts.mappings then + require("font-map") + require("font-agl") + end + local unicodes={} + local resources=fontdata.resources + resources.unicodes=unicodes + for unicode,d in next,fontdata.descriptions do + if unicode=firstprivate then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + elseif descriptions[unicode] then + unicode=private + local name=glyph.name or f_private(unicode) + indices[index]=name + names[name]=unicode + private=private+1 + else + local name=glyph.name or f_unicode(unicode) + indices[index]=name + names[name]=unicode + end + descriptions[unicode]=glyph + end + elseif trace_unicodes then + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=firstprivate then + local name=glyph.name + if name then + report_unicodes("moving glyph %a indexed %05X from private %U to %U ",name,index,unicode,private) + else + report_unicodes("moving glyph indexed %05X from private %U to %U ",index,unicode,private) end - for i=index+1,#list do - n=n+1 - t[n]=list[i] + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name + if name then + report_unicodes("keeping private unicode %U for glyph %a indexed %05X",unicode,name,index) + else + report_unicodes("keeping private unicode %U for glyph indexed %05X",unicode,index) end - else - list[index]=replacement - return list - end -end -local function unifyresources(fontdata,indices) - local descriptions=fontdata.descriptions - local resources=fontdata.resources - if not descriptions or not resources then - return - end - local variants=fontdata.resources.variants - if variants then - for selector,unicodes in next,variants do - for unicode,index in next,unicodes do - unicodes[unicode]=indices[index] - end + indices[index]=unicode + elseif descriptions[unicode] then + local name=glyph.name + if name then + report_unicodes("assigning duplicate unicode %U to %U for glyph %a indexed %05X ",unicode,private,name,index) + else + report_unicodes("assigning duplicate unicode %U to %U for glyph indexed %05X ",unicode,private,index) end + unicode=private + indices[index]=unicode + private=private+1 + else + indices[index]=unicode + end + descriptions[unicode]=glyph end - local function remark(marks) - if marks then - local newmarks={} - for k,v in next,marks do - local u=indices[k] - if u then - newmarks[u]=v - else - report("discarding mark %i",k) - end - end - return newmarks + else + for index=1,#glyphs do + local glyph=glyphs[index] + local unicode=glyph.unicode + if not unicode then + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=firstprivate then + local name=glyph.name + unicode=private + indices[index]=unicode + private=private+1 + elseif unicode>=puafirst and unicode<=pualast then + local name=glyph.name + indices[index]=unicode + elseif descriptions[unicode] then + local name=glyph.name + unicode=private + indices[index]=unicode + private=private+1 + else + indices[index]=unicode + end + descriptions[unicode]=glyph + end + end + for index=1,#glyphs do + local math=glyphs[index].math + if math then + local list=math.vparts + if list then + for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end + end + local list=math.hparts + if list then + for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end + end + local list=math.vvariants + if list then + for i=1,#list do list[i]=indices[list[i]] end + end + local list=math.hvariants + if list then + for i=1,#list do list[i]=indices[list[i]] end + end + end + end + local colorpalettes=resources.colorpalettes + if colorpalettes then + for index=1,#glyphs do + local colors=glyphs[index].colors + if colors then + for i=1,#colors do + local c=colors[i] + c.slot=indices[c.slot] + end + end + end + end + fontdata.private=private + fontdata.glyphs=nil + fontdata.names=names + fontdata.descriptions=descriptions + fontdata.hashmethod=hashmethod + return indices,names +end +local p_crappyname do + local p_hex=R("af","AF","09") + local p_digit=R("09") + local p_done=S("._-")^0+P(-1) + local p_alpha=R("az","AZ") + local p_ALPHA=R("AZ") + p_crappyname=( + lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1 ++lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1 ++lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1 ++p_digit*p_hex^3+p_alpha*p_digit^1 ++P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1 + )*p_done +end +local forcekeep=false +directives.register("otf.keepnames",function(v) + report_cleanup("keeping weird glyph names, expect larger files and more memory usage") + forcekeep=v +end) +local function stripredundant(fontdata) + local descriptions=fontdata.descriptions + if descriptions then + local n=0 + local c=0 + if (not context and fonts.privateoffsets.keepnames) or forcekeep then + for unicode,d in next,descriptions do + if d.class=="base" then + d.class=nil + c=c+1 + end + end + else + for unicode,d in next,descriptions do + local name=d.name + if name and lpegmatch(p_crappyname,name) then + d.name=nil + n=n+1 end - end - local marks=resources.marks - if marks then - resources.marks=remark(marks) - end - local markclasses=resources.markclasses - if markclasses then - for class,marks in next,markclasses do - markclasses[class]=remark(marks) + if d.class=="base" then + d.class=nil + c=c+1 end + end end - local marksets=resources.marksets - if marksets then - for class,marks in next,marksets do - marksets[class]=remark(marks) - end + if trace_cleanup then + if n>0 then + report_cleanup("%s bogus names removed (verbose unicode)",n) + end + if c>0 then + report_cleanup("%s base class tags removed (default is base)",c) + end end - local done={} - local duplicates=check_duplicates and resources.duplicates - if duplicates and not next(duplicates) then - duplicates=false - end - local function recover(cover) - for i=1,#cover do - local c=cover[i] - if not done[c] then - local t={} + end +end +readers.stripredundant=stripredundant +function readers.getcomponents(fontdata) + local resources=fontdata.resources + if resources then + local sequences=resources.sequences + if sequences then + local collected={} + for i=1,#sequences do + local sequence=sequences[i] + if sequence.type=="gsub_ligature" then + local steps=sequence.steps + if steps then + local l={} + local function traverse(p,k,v) + if k=="ligature" then + collected[v]={ unpack(l) } + else + insert(l,k) + for k,vv in next,v do + traverse(p,k,vv) + end + remove(l) + end + end + for i=1,#steps do + local c=steps[i].coverage + if c then for k,v in next,c do - t[indices[k]]=v + traverse(k,k,v) end - cover[i]=t - done[c]=d - end - end - end - local function recursed(c) - local t={} - for g,d in next,c do - if type(d)=="table" then - t[indices[g]]=recursed(d) - else - t[g]=indices[d] + end end + end end - return t - end - local function unifythem(sequences) - if not sequences then - return - end - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gsub_single" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - local ud1=indices[d1] - t1[ug1]=ud1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=ud1 - end - end - end - else - for g1,d1 in next,c do - t1[indices[g1]]=indices[d1] - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_pair" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - for g1,d1 in next,c do - local t2=done[d1] - if not t2 then - t2={} - for g2,d2 in next,d1 do - t2[indices[g2]]=d2 - end - done[d1]=t2 - end - t1[indices[g1]]=t2 - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gsub_ligature" then - local c=step.coverage - if c then - step.coverage=recursed(c) - end - elseif kind=="gsub_alternate" or kind=="gsub_multiple" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - for i=1,#d1 do - d1[i]=indices[d1[i]] - end - local ug1=indices[g1] - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=copy(d1) - end - end - end - else - for g1,d1 in next,c do - for i=1,#d1 do - d1[i]=indices[d1[i]] - end - t1[indices[g1]]=d1 - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" or kind=="gpos_mark2ligature" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - for g1,d1 in next,c do - t1[indices[g1]]=d1 - end - done[c]=t1 - end - step.coverage=t1 - end - local c=step.baseclasses - if c then - local t1=done[c] - if not t1 then - for g1,d1 in next,c do - local t2=done[d1] - if not t2 then - t2={} - for g2,d2 in next,d1 do - t2[indices[g2]]=d2 - end - done[d1]=t2 - end - c[g1]=t2 - end - done[c]=c - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=d1 - end - end - end - else - for g1,d1 in next,c do - t1[indices[g1]]=d1 - end - end - done[c]=t1 - end - step.coverage=t1 - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - local t1=done[c] - if not t1 then - t1={} - if duplicates then - for g1,d1 in next,c do - local ug1=indices[g1] - t1[ug1]=d1 - local dg1=duplicates[ug1] - if dg1 then - for u in next,dg1 do - t1[u]=copy(d1) - end - end - end - else - for g1,d1 in next,c do - t1[indices[g1]]=d1 - end - end - done[c]=t1 - end - step.coverage=t1 - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before if before then recover(before) end - local after=rule.after if after then recover(after) end - local current=rule.current if current then recover(current) end - local replacements=rule.replacements - if replacements then - if not done[replacements] then - local r={} - for k,v in next,replacements do - r[indices[k]]=indices[v] - end - rule.replacements=r - done[replacements]=r - end - end - end - end + end + if next(collected) then + while true do + local done=false + for k,v in next,collected do + for i=1,#v do + local vi=v[i] + if vi==k then + collected[k]=nil + break + else + local c=collected[vi] + if c then + done=true + local t={} + local n=i-1 + for j=1,n do + t[j]=v[j] + end + for j=1,#c do + n=n+1 + t[n]=c[j] + end + for j=i+1,#v do + n=n+1 + t[n]=v[j] + end + collected[k]=t + break end + end end + end + if not done then + break + end end + return collected + end end - unifythem(resources.sequences) - unifythem(resources.sublookups) + end end -local function copyduplicates(fontdata) - if check_duplicates then - local descriptions=fontdata.descriptions - local resources=fontdata.resources - local duplicates=resources.duplicates - if check_soft_hyphen then - local ds=descriptions[0xAD] - if not ds or ds.width==0 then - if ds then - descriptions[0xAD]=nil - report("patching soft hyphen") - else - report("adding soft hyphen") - end - if not duplicates then - duplicates={} - resources.duplicates=duplicates - end - local dh=duplicates[0x2D] - if dh then - dh[#dh+1]={ [0xAD]=true } - else - duplicates[0x2D]={ [0xAD]=true } - end - end - end - if duplicates then - for u,d in next,duplicates do - local du=descriptions[u] - if du then - local t={ f_character_y(u),"@",f_index(du.index),"->" } - local n=0 - local m=25 - for u in next,d do - if descriptions[u] then - if n"..tabstr_normal(v) + elseif v==true then + s[n]=k.."+" + elseif v then + s[n]=k.."="..v + else + s[n]=k.."-" end - local singles={} - local alternates={} - local ligatures={} - if not missing then - missing={} - nofmissing=0 - for u,d in next,descriptions do - if not d.unicode then - nofmissing=nofmissing+1 - missing[u]=true - end + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +local function tabstr_flat(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + s[n]=k.."="..v + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +local function tabstr_mixed(t) + local s={} + local n=#t + if n==0 then + return "" + elseif n==1 then + local k=t[1] + if k==true then + return "++" + elseif k==false then + return "--" + else + return tostring(k) + end + else + for i=1,n do + local k=t[i] + if k==true then + s[i]="++" + elseif k==false then + s[i]="--" + else + s[i]=k + end + end + return concat(s,",") + end +end +local function tabstr_boolean(t) + local s={} + local n=0 + for k,v in next,t do + n=n+1 + if v then + s[n]=k.."+" + else + s[n]=k.."-" + end + end + if n==0 then + return "" + elseif n==1 then + return s[1] + else + sort(s) + return concat(s,",") + end +end +function readers.pack(data) + if data then + local h,t,c={},{},{} + local hh,tt,cc={},{},{} + local nt,ntt=0,0 + local function pack_normal(v) + local tag=tabstr_normal(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_normal_cc(v) + local tag=tabstr_normal(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + v[1]=0 + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_flat(v) + local tag=tabstr_flat(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_indexed(v) + local tag=concat(v," ") + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_mixed(v) + local tag=tabstr_mixed(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_boolean(v) + local tag=tabstr_boolean(v) + local ht=h[tag] + if ht then + c[ht]=c[ht]+1 + return ht + else + nt=nt+1 + t[nt]=v + h[tag]=nt + c[nt]=1 + return nt + end + end + local function pack_final(v) + if c[v]<=criterium then + return t[v] + else + local hv=hh[v] + if hv then + return hv + else + ntt=ntt+1 + tt[ntt]=t[v] + hh[v]=ntt + cc[ntt]=c[v] + return ntt + end + end + end + local function pack_final_cc(v) + if c[v]<=criterium then + return t[v] + else + local hv=hh[v] + if hv then + return hv + else + ntt=ntt+1 + tt[ntt]=t[v] + hh[v]=ntt + cc[ntt]=c[v] + return ntt end + end end - local function collectthem(sequences) - if not sequences then - return + local function success(stage,pass) + if nt==0 then + if trace_loading or trace_packing then + report_otf("pack quality: nothing to pack") end - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gsub_single" then - local c=step.coverage - if c then - singles[#singles+1]=c - end - elseif kind=="gsub_alternate" then - local c=step.coverage - if c then - alternates[#alternates+1]=c - end - elseif kind=="gsub_ligature" then - local c=step.coverage - if c then - ligatures[#ligatures+1]=c - end - end - end + return false + elseif nt>=threshold then + local one=0 + local two=0 + local rest=0 + if pass==1 then + for k,v in next,c do + if v==1 then + one=one+1 + elseif v==2 then + two=two+1 + else + rest=rest+1 + end + end + else + for k,v in next,cc do + if v>20 then + rest=rest+1 + elseif v>10 then + two=two+1 + else + one=one+1 end + end + data.tables=tt + end + if trace_loading or trace_packing then + report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", + stage,pass,one+two+rest,one,two,rest,criterium) end + return true + else + if trace_loading or trace_packing then + report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", + stage,pass,nt,threshold) + end + return false + end end - collectthem(resources.sequences) - collectthem(resources.sublookups) - local loops=0 - while true do - loops=loops+1 - local old=nofmissing - for i=1,#singles do - local c=singles[i] - for g1,g2 in next,c do - if missing[g1] then - local u2=descriptions[g2].unicode - if u2 then - missing[g1]=false - descriptions[g1].unicode=u2 - nofmissing=nofmissing-1 - end - end - if missing[g2] then - local u1=descriptions[g1].unicode - if u1 then - missing[g2]=false - descriptions[g2].unicode=u1 - nofmissing=nofmissing-1 - end - end + local function packers(pass) + if pass==1 then + return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc + else + return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc + end + end + local resources=data.resources + local sequences=resources.sequences + local sublookups=resources.sublookups + local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata + local chardata=characters and characters.data + local descriptions=data.descriptions or data.glyphs + if not descriptions then + return + end + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 1, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + for unicode,description in next,descriptions do + local boundingbox=description.boundingbox + if boundingbox then + description.boundingbox=pack_indexed(boundingbox) + end + local math=description.math + if math then + local kerns=math.kerns + if kerns then + for tag,kern in next,kerns do + kerns[tag]=pack_normal(kern) end + end end - for i=1,#alternates do - local c=alternates[i] - for g1,d1 in next,c do - if missing[g1] then - for i=1,#d1 do - local g2=d1[i] - local u2=descriptions[g2].unicode - if u2 then - missing[g1]=false - descriptions[g1].unicode=u2 - nofmissing=nofmissing-1 - end + end + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local order=sequence.order + local features=sequence.features + local flags=sequence.flags + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end + local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end + end + end + else + for g1,d1 in next,c do + c[g1]=pack_normal(d1) end + end end - if not missing[g1] then - for i=1,#d1 do - local g2=d1[i] - if missing[g2] then - local u1=descriptions[g1].unicode - if u1 then - missing[g2]=false - descriptions[g2].unicode=u1 - nofmissing=nofmissing-1 - end - end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + if step.format=="single" then + for g1,d1 in next,c do + if d1 and d1~=true then + c[g1]=pack_indexed(d1) + end + end + else + step.coverage=pack_normal(c) + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + local f=d1[2] if f then d1[2]=pack_indexed(f) end + local s=d1[3] if s then d1[3]=pack_indexed(s) end + end + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_indexed(d2) end + end end - end - end - if nofmissing<=0 then - report("all done in %s loops",loops) - return - elseif old==nofmissing then - break - end - end - local t,n - local function recursed(c) - for g,d in next,c do - if g~="ligature" then - local u=descriptions[g].unicode - if u then - n=n+1 - t[n]=u - recursed(d) - n=n-1 + local c=step.coverage + if c then + for g1,d1 in next,c do + d1[2]=pack_indexed(d1[2]) + end end - elseif missing[d] then - local l={} - local m=0 - for i=1,n do - local u=t[i] - if type(u)=="table" then - for i=1,#u do - m=m+1 - l[m]=u[i] - end - else - m=m+1 - l[m]=u + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + for g3,d3 in next,d2 do + d2[g3]=pack_indexed(d3) + end end + end end - missing[d]=false - descriptions[d].unicode=l - nofmissing=nofmissing-1 + local c=step.coverage + if c then + for g1,d1 in next,c do + d1[2]=pack_indexed(d1[2]) + end + end + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end + local r=rule.replacements if r then rule.replacements=pack_flat (r) end + end + end end - end - end - if nofmissing>0 then - t={} - n=0 - local loops=0 - while true do - loops=loops+1 - local old=nofmissing - for i=1,#ligatures do - recursed(ligatures[i]) - end - if nofmissing<=0 then - report("all done in %s loops",loops) - return - elseif old==nofmissing then - break + end + if order then + sequence.order=pack_indexed(order) + end + if features then + for script,feature in next,features do + features[script]=pack_normal(feature) end - end - t=nil - n=0 - end - if nofmissing>0 then - local done={} - for i,r in next,missing do - if r then - local data=descriptions[i] - local name=data and data.name or f_index(i) - if not ignore[name] then - done[name]=true - end + end + if flags then + sequence.flags=pack_normal(flags) + end end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) + end + if features then + for k,list in next,features do + for feature,spec in next,list do + list[feature]=pack_normal(spec) + end end - if next(done) then - report("not unicoded: % t",sortedkeys(done)) + end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + p[j]=pack_indexed(p[j]) + end end - end -end -local function unifymissing(fontdata) - if not fonts.mappings then - require("font-map") - require("font-agl") - end - local unicodes={} - local resources=fontdata.resources - resources.unicodes=unicodes - for unicode,d in next,fontdata.descriptions do - if unicode0 then + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 2, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + for unicode,description in next,descriptions do + local math=description.math + if math then + local kerns=math.kerns + if kerns then + math.kerns=pack_normal(kerns) end + end end - end - local colorpalettes=resources.colorpalettes - if colorpalettes then - for index=1,#glyphs do - local colors=glyphs[index].colors - if colors then - for i=1,#colors do - local c=colors[i] - c.slot=indices[c.slot] + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_normal(d2) + end + end + end + end + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + d1[g2]=pack_normal(d2) + end + end + end end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local r=rule.before if r then rule.before=pack_normal(r) end + local r=rule.after if r then rule.after=pack_normal(r) end + local r=rule.current if r then rule.current=pack_normal(r) end + end + end + end end - end - end - fontdata.private=private - fontdata.glyphs=nil - fontdata.names=names - fontdata.descriptions=descriptions - fontdata.hashmethod=hashmethod - return indices,names -end -local p_bogusname=( - (P("uni")+P("UNI")+P("Uni")+P("U")+P("u"))*S("Xx")^0*R("09","AF")^1+(P("identity")+P("Identity")+P("IDENTITY"))*R("09","AF")^1+(P("index")+P("Index")+P("INDEX"))*R("09")^1 -)*P(-1) -local function stripredundant(fontdata) - local descriptions=fontdata.descriptions - if descriptions then - local n=0 - local c=0 - for unicode,d in next,descriptions do - local name=d.name - if name and lpegmatch(p_bogusname,name) then - d.name=nil - n=n+1 - end - if d.class=="base" then - d.class=nil - c=c+1 + if features then + sequence.features=pack_normal(features) end + end end - if n>0 then - report("%s bogus names removed (verbose unicode)",n) + if sequences then + packthem(sequences) end - if c>0 then - report("%s base class tags removed (default is base)",c) + if sublookups then + packthem(sublookups) end - end -end -function readers.getcomponents(fontdata) - local resources=fontdata.resources - if resources then - local sequences=resources.sequences - if sequences then - local collected={} - for i=1,#sequences do - local sequence=sequences[i] - if sequence.type=="gsub_ligature" then - local steps=sequence.steps - if steps then - local l={} - local function traverse(p,k,v) - if k=="ligature" then - collected[v]={ unpack(l) } - else - insert(l,k) - for k,vv in next,v do - traverse(p,k,vv) - end - remove(l) - end - end - for i=1,#steps do - local coverage=steps[i].coverage - if coverage then - for k,v in next,coverage do - traverse(k,k,v) - end - end - end - end - end + if variable then + local function unpackdeltas(main) + if main then + local regions=main.regions + if regions then + main.regions=pack_normal(regions) + end end - if next(collected) then - while true do - local done=false - for k,v in next,collected do - for i=1,#v do - local vi=v[i] - if vi==k then - collected[k]=nil - break - else - local c=collected[vi] - if c then - done=true - local t={} - local n=i-1 - for j=1,n do - t[j]=v[j] - end - for j=1,#c do - n=n+1 - t[n]=c[j] - end - for j=i+1,#v do - n=n+1 - t[n]=v[j] - end - collected[k]=t - break - end - end - end - end - if not done then - break - end + end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end + end + for pass=1,2 do + if trace_packing then + report_otf("start packing: stage 3, pass %s",pass) + end + local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) + local function packthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local features=sequence.features + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + c[g1]=pack_normal(d1) + end + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + c[g1]=pack_normal_cc(d1) + end + end end - return collected + end end + end + end + if sequences then + packthem(sequences) + end + if sublookups then + packthem(sublookups) end + end end + end end -readers.unifymissing=unifymissing -function readers.rehash(fontdata,hashmethod) - if not (fontdata and fontdata.glyphs) then - return - end - if hashmethod=="indices" then - fontdata.hashmethod="indices" - elseif hashmethod=="names" then - fontdata.hashmethod="names" - local indices=unifyglyphs(fontdata,true) - unifyresources(fontdata,indices) - copyduplicates(fontdata) - unifymissing(fontdata) - else - fontdata.hashmethod="unicodes" - local indices=unifyglyphs(fontdata) - unifyresources(fontdata,indices) - copyduplicates(fontdata) - unifymissing(fontdata) - stripredundant(fontdata) - end -end -function readers.checkhash(fontdata) - local hashmethod=fontdata.hashmethod - if hashmethod=="unicodes" then - fontdata.names=nil - elseif hashmethod=="names" and fontdata.names then - unifyresources(fontdata,fontdata.names) - copyduplicates(fontdata) - fontdata.hashmethod="unicodes" - fontdata.names=nil - else - readers.rehash(fontdata,"unicodes") - end -end -function readers.addunicodetable(fontdata) - local resources=fontdata.resources - local unicodes=resources.unicodes - if not unicodes then - local descriptions=fontdata.descriptions - if descriptions then - unicodes={} - resources.unicodes=unicodes - for u,d in next,descriptions do - local n=d.name - if n then - unicodes[n]=u - end - end - end - end -end -local concat,sort=table.concat,table.sort -local next,type,tostring=next,type,tostring -local criterium=1 -local threshold=0 -local trace_packing=false trackers.register("otf.packing",function(v) trace_packing=v end) -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) -local report_otf=logs.reporter("fonts","otf loading") -local function tabstr_normal(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - if type(v)=="table" then - s[n]=k..">"..tabstr_normal(v) - elseif v==true then - s[n]=k.."+" - elseif v then - s[n]=k.."="..v - else - s[n]=k.."-" - end - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -local function tabstr_flat(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - s[n]=k.."="..v - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") - end -end -local function tabstr_mixed(t) - local s={} - local n=#t - if n==0 then - return "" - elseif n==1 then - local k=t[1] - if k==true then - return "++" - elseif k==false then - return "--" - else - return tostring(k) - end - else - for i=1,n do - local k=t[i] - if k==true then - s[i]="++" - elseif k==false then - s[i]="--" - else - s[i]=k - end - end - return concat(s,",") - end -end -local function tabstr_boolean(t) - local s={} - local n=0 - for k,v in next,t do - n=n+1 - if v then - s[n]=k.."+" - else - s[n]=k.."-" - end - end - if n==0 then - return "" - elseif n==1 then - return s[1] - else - sort(s) - return concat(s,",") +local unpacked_mt={ + __index=function(t,k) + t[k]=false + return k end -end -function readers.pack(data) - if data then - local h,t,c={},{},{} - local hh,tt,cc={},{},{} - local nt,ntt=0,0 - local function pack_normal(v) - local tag=tabstr_normal(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_normal_cc(v) - local tag=tabstr_normal(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - v[1]=0 - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_flat(v) - local tag=tabstr_flat(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_indexed(v) - local tag=concat(v," ") - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_mixed(v) - local tag=tabstr_mixed(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_boolean(v) - local tag=tabstr_boolean(v) - local ht=h[tag] - if ht then - c[ht]=c[ht]+1 - return ht - else - nt=nt+1 - t[nt]=v - h[tag]=nt - c[nt]=1 - return nt - end - end - local function pack_final(v) - if c[v]<=criterium then - return t[v] - else - local hv=hh[v] - if hv then - return hv - else - ntt=ntt+1 - tt[ntt]=t[v] - hh[v]=ntt - cc[ntt]=c[v] - return ntt - end - end - end - local function pack_final_cc(v) - if c[v]<=criterium then - return t[v] - else - local hv=hh[v] - if hv then - return hv - else - ntt=ntt+1 - tt[ntt]=t[v] - hh[v]=ntt - cc[ntt]=c[v] - return ntt - end +} +function readers.unpack(data) + if data then + local tables=data.tables + if tables then + local resources=data.resources + local descriptions=data.descriptions or data.glyphs + local sequences=resources.sequences + local sublookups=resources.sublookups + local features=resources.features + local palettes=resources.colorpalettes + local variable=resources.variabledata + local unpacked={} + setmetatable(unpacked,unpacked_mt) + for unicode,description in next,descriptions do + local tv=tables[description.boundingbox] + if tv then + description.boundingbox=tv + end + local math=description.math + if math then + local kerns=math.kerns + if kerns then + local tm=tables[kerns] + if tm then + math.kerns=tm + kerns=unpacked[tm] end - end - local function success(stage,pass) - if nt==0 then - if trace_loading or trace_packing then - report_otf("pack quality: nothing to pack") - end - return false - elseif nt>=threshold then - local one,two,rest=0,0,0 - if pass==1 then - for k,v in next,c do - if v==1 then - one=one+1 - elseif v==2 then - two=two+1 - else - rest=rest+1 - end - end - else - for k,v in next,cc do - if v>20 then - rest=rest+1 - elseif v>10 then - two=two+1 - else - one=one+1 - end - end - data.tables=tt - end - if trace_loading or trace_packing then - report_otf("pack quality: stage %s, pass %s, %s packed, 1-10:%s, 11-20:%s, rest:%s (criterium: %s)", - stage,pass,one+two+rest,one,two,rest,criterium) - end - return true - else - if trace_loading or trace_packing then - report_otf("pack quality: stage %s, pass %s, %s packed, aborting pack (threshold: %s)", - stage,pass,nt,threshold) + if kerns then + for k,kern in next,kerns do + local tv=tables[kern] + if tv then + kerns[k]=tv end - return false + end end + end end - local function packers(pass) - if pass==1 then - return pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc - else - return pack_final,pack_final,pack_final,pack_final,pack_final,pack_final_cc - end - end - local resources=data.resources - local sequences=resources.sequences - local sublookups=resources.sublookups - local features=resources.features - local palettes=resources.colorpalettes - local variable=resources.variabledata - local chardata=characters and characters.data - local descriptions=data.descriptions or data.glyphs - if not descriptions then - return - end - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 1, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - for unicode,description in next,descriptions do - local boundingbox=description.boundingbox - if boundingbox then - description.boundingbox=pack_indexed(boundingbox) - end - local math=description.math - if math then - local kerns=math.kerns - if kerns then - for tag,kern in next,kerns do - kerns[tag]=pack_normal(kern) - end - end - end + end + local function unpackthem(sequences) + for i=1,#sequences do + local sequence=sequences[i] + local kind=sequence.type + local steps=sequence.steps + local order=sequence.order + local features=sequence.features + local flags=sequence.flags + local markclass=sequence.markclass + if features then + local tv=tables[features] + if tv then + sequence.features=tv + features=tv + end + for script,feature in next,features do + local tv=tables[feature] + if tv then + features[script]=tv + end end - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local order=sequence.order - local features=sequence.features - local flags=sequence.flags - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local f=d2[1] if f and f~=true then d2[1]=pack_indexed(f) end - local s=d2[2] if s and s~=true then d2[2]=pack_indexed(s) end - end - end - else - for g1,d1 in next,c do - c[g1]=pack_normal(d1) - end - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - if step.format=="single" then - for g1,d1 in next,c do - if d1 and d1~=true then - c[g1]=pack_indexed(d1) - end - end - else - step.coverage=pack_normal(c) - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - local f=d1[2] if f then d1[2]=pack_indexed(f) end - local s=d1[3] if s then d1[3]=pack_indexed(s) end - end - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_indexed(d2) - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - d1[2]=pack_indexed(d1[2]) - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - for g3,d3 in next,d2 do - d2[g3]=pack_indexed(d3) - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - d1[2]=pack_indexed(d1[2]) - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local r=rule.before if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.after if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.current if r then for i=1,#r do r[i]=pack_boolean(r[i]) end end - local r=rule.replacements if r then rule.replacements=pack_flat (r) end - end - end - end - end - if order then - sequence.order=pack_indexed(order) - end - if features then - for script,feature in next,features do - features[script]=pack_normal(feature) + end + if steps then + for i=1,#steps do + local step=steps[i] + if kind=="gpos_pair" then + local c=step.coverage + if c then + if step.format=="pair" then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + d1=tv + end + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d1[g2]=tv + d2=tv end + local f=tables[d2[1]] if f then d2[1]=f end + local s=tables[d2[2]] if s then d2[2]=s end + end end - if flags then - sequence.flags=pack_normal(flags) - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - if features then - for k,list in next,features do - for feature,spec in next,list do - list[feature]=pack_normal(spec) - end - end - end - if palettes then - for i=1,#palettes do - local p=palettes[i] - for j=1,#p do - p[j]=pack_indexed(p[j]) + else + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + end end + end end - end - if variable then - local instances=variable.instances - if instances then - for i=1,#instances do - local v=instances[i].values - for j=1,#v do - v[j]=pack_normal(v[j]) - end + elseif kind=="gpos_single" then + local c=step.coverage + if c then + if step.format=="single" then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + c[g1]=tv + end + end + else + local tv=tables[c] + if tv then + step.coverage=tv + end + end + end + elseif kind=="gpos_cursive" then + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1] + if tv then + d1=tv + c[g1]=d1 + end + local f=tables[d1[2]] if f then d1[2]=f end + local s=tables[d1[3]] if s then d1[3]=s end + end + end + elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d1[g2]=tv + end end + end end - local function packdeltas(main) - if main then - local deltas=main.deltas - if deltas then - for i=1,#deltas do - local di=deltas[i] - local d=di.deltas - for j=1,#d do - d[j]=pack_indexed(d[j]) - end - di.regions=pack_indexed(di.regions) - end - end - local regions=main.regions - if regions then - for i=1,#regions do - local r=regions[i] - for j=1,#r do - r[j]=pack_normal(r[j]) - end - end - end + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1[2]] + if tv then + d1[2]=tv end + end end - packdeltas(variable.global) - packdeltas(variable.horizontal) - packdeltas(variable.vertical) - packdeltas(variable.metrics) - end - if not success(1,pass) then - return - end - end - if nt>0 then - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 2, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - for unicode,description in next,descriptions do - local math=description.math - if math then - local kerns=math.kerns - if kerns then - math.kerns=pack_normal(kerns) + elseif kind=="gpos_mark2ligature" then + local c=step.baseclasses + if c then + for g1,d1 in next,c do + for g2,d2 in next,d1 do + local tv=tables[d2] + if tv then + d2=tv + d1[g2]=d2 + end + for g3,d3 in next,d2 do + local tv=tables[d2[g3]] + if tv then + d2[g3]=tv end + end end + end end - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_normal(d2) - end - end - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - d1[g2]=pack_normal(d2) - end - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local r=rule.before if r then rule.before=pack_normal(r) end - local r=rule.after if r then rule.after=pack_normal(r) end - local r=rule.current if r then rule.current=pack_normal(r) end - end - end - end - end - if features then - sequence.features=pack_normal(features) - end + local c=step.coverage + if c then + for g1,d1 in next,c do + local tv=tables[d1[2]] + if tv then + d1[2]=tv end + end end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end - if variable then - local function unpackdeltas(main) - if main then - local regions=main.regions - if regions then - main.regions=pack_normal(regions) - end - end - end - unpackdeltas(variable.global) - unpackdeltas(variable.horizontal) - unpackdeltas(variable.vertical) - unpackdeltas(variable.metrics) + end + local rules=step.rules + if rules then + for i=1,#rules do + local rule=rules[i] + local before=rule.before + if before then + local tv=tables[before] + if tv then + rule.before=tv + before=tv + end + for i=1,#before do + local tv=tables[before[i]] + if tv then + before[i]=tv + end + end + end + local after=rule.after + if after then + local tv=tables[after] + if tv then + rule.after=tv + after=tv + end + for i=1,#after do + local tv=tables[after[i]] + if tv then + after[i]=tv + end + end + end + local current=rule.current + if current then + local tv=tables[current] + if tv then + rule.current=tv + current=tv + end + for i=1,#current do + local tv=tables[current[i]] + if tv then + current[i]=tv + end + end + end + local replacements=rule.replacements + if replacements then + local tv=tables[replacements] + if tv then + rule.replacements=tv + end + end end + end end - for pass=1,2 do - if trace_packing then - report_otf("start packing: stage 3, pass %s",pass) - end - local pack_normal,pack_indexed,pack_flat,pack_boolean,pack_mixed,pack_normal_cc=packers(pass) - local function packthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local features=sequence.features - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - c[g1]=pack_normal(d1) - end - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - c[g1]=pack_normal_cc(d1) - end - end - end - end - end - end - end - if sequences then - packthem(sequences) - end - if sublookups then - packthem(sublookups) - end + end + if order then + local tv=tables[order] + if tv then + sequence.order=tv end - end - end -end -local unpacked_mt={ - __index=function(t,k) - t[k]=false - return k - end -} -function readers.unpack(data) - if data then - local tables=data.tables - if tables then - local resources=data.resources - local descriptions=data.descriptions or data.glyphs - local sequences=resources.sequences - local sublookups=resources.sublookups - local features=resources.features - local palettes=resources.colorpalettes - local variable=resources.variabledata - local unpacked={} - setmetatable(unpacked,unpacked_mt) - for unicode,description in next,descriptions do - local tv=tables[description.boundingbox] - if tv then - description.boundingbox=tv - end - local math=description.math - if math then - local kerns=math.kerns - if kerns then - local tm=tables[kerns] - if tm then - math.kerns=tm - kerns=unpacked[tm] - end - if kerns then - for k,kern in next,kerns do - local tv=tables[kern] - if tv then - kerns[k]=tv - end - end - end - end - end + end + if flags then + local tv=tables[flags] + if tv then + sequence.flags=tv end - local function unpackthem(sequences) - for i=1,#sequences do - local sequence=sequences[i] - local kind=sequence.type - local steps=sequence.steps - local order=sequence.order - local features=sequence.features - local flags=sequence.flags - local markclass=sequence.markclass - if features then - local tv=tables[features] - if tv then - sequence.features=tv - features=tv - end - for script,feature in next,features do - local tv=tables[feature] - if tv then - features[script]=tv - end - end - end - if steps then - for i=1,#steps do - local step=steps[i] - if kind=="gpos_pair" then - local c=step.coverage - if c then - if step.format=="pair" then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - d1=tv - end - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d1[g2]=tv - d2=tv - end - local f=tables[d2[1]] if f then d2[1]=f end - local s=tables[d2[2]] if s then d2[2]=s end - end - end - else - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - end - end - end - end - elseif kind=="gpos_single" then - local c=step.coverage - if c then - if step.format=="single" then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - c[g1]=tv - end - end - else - local tv=tables[c] - if tv then - step.coverage=tv - end - end - end - elseif kind=="gpos_cursive" then - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1] - if tv then - d1=tv - c[g1]=d1 - end - local f=tables[d1[2]] if f then d1[2]=f end - local s=tables[d1[3]] if s then d1[3]=s end - end - end - elseif kind=="gpos_mark2base" or kind=="gpos_mark2mark" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d1[g2]=tv - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1[2]] - if tv then - d1[2]=tv - end - end - end - elseif kind=="gpos_mark2ligature" then - local c=step.baseclasses - if c then - for g1,d1 in next,c do - for g2,d2 in next,d1 do - local tv=tables[d2] - if tv then - d2=tv - d1[g2]=d2 - end - for g3,d3 in next,d2 do - local tv=tables[d2[g3]] - if tv then - d2[g3]=tv - end - end - end - end - end - local c=step.coverage - if c then - for g1,d1 in next,c do - local tv=tables[d1[2]] - if tv then - d1[2]=tv - end - end - end - end - local rules=step.rules - if rules then - for i=1,#rules do - local rule=rules[i] - local before=rule.before - if before then - local tv=tables[before] - if tv then - rule.before=tv - before=tv - end - for i=1,#before do - local tv=tables[before[i]] - if tv then - before[i]=tv - end - end - end - local after=rule.after - if after then - local tv=tables[after] - if tv then - rule.after=tv - after=tv - end - for i=1,#after do - local tv=tables[after[i]] - if tv then - after[i]=tv - end - end - end - local current=rule.current - if current then - local tv=tables[current] - if tv then - rule.current=tv - current=tv - end - for i=1,#current do - local tv=tables[current[i]] - if tv then - current[i]=tv - end - end - end - local replacements=rule.replacements - if replacements then - local tv=tables[replacements] - if tv then - rule.replacements=tv - end - end - end - end - end - end - if order then - local tv=tables[order] - if tv then - sequence.order=tv - end - end - if flags then - local tv=tables[flags] - if tv then - sequence.flags=tv - end - end - end + end end - if sequences then - unpackthem(sequences) + end + if sequences then + unpackthem(sequences) + end + if sublookups then + unpackthem(sublookups) + end + if features then + for k,list in next,features do + for feature,spec in next,list do + local tv=tables[spec] + if tv then + list[feature]=tv end - if sublookups then - unpackthem(sublookups) + end + end + end + if palettes then + for i=1,#palettes do + local p=palettes[i] + for j=1,#p do + local tv=tables[p[j]] + if tv then + p[j]=tv end - if features then - for k,list in next,features do - for feature,spec in next,list do - local tv=tables[spec] - if tv then - list[feature]=tv - end - end - end + end + end + end + if variable then + local instances=variable.instances + if instances then + for i=1,#instances do + local v=instances[i].values + for j=1,#v do + local tv=tables[v[j]] + if tv then + v[j]=tv + end end - if palettes then - for i=1,#palettes do - local p=palettes[i] - for j=1,#p do - local tv=tables[p[j]] - if tv then - p[j]=tv - end - end + end + end + local function unpackdeltas(main) + if main then + local deltas=main.deltas + if deltas then + for i=1,#deltas do + local di=deltas[i] + local d=di.deltas + local r=di.regions + for j=1,#d do + local tv=tables[d[j]] + if tv then + d[j]=tv + end + end + local tv=di.regions + if tv then + di.regions=tv end + end end - if variable then - local instances=variable.instances - if instances then - for i=1,#instances do - local v=instances[i].values - for j=1,#v do - local tv=tables[v[j]] - if tv then - v[j]=tv - end - end - end - end - local function unpackdeltas(main) - if main then - local deltas=main.deltas - if deltas then - for i=1,#deltas do - local di=deltas[i] - local d=di.deltas - local r=di.regions - for j=1,#d do - local tv=tables[d[j]] - if tv then - d[j]=tv - end - end - local tv=di.regions - if tv then - di.regions=tv - end - end - end - local regions=main.regions - if regions then - local tv=tables[regions] - if tv then - main.regions=tv - regions=tv - end - for i=1,#regions do - local r=regions[i] - for j=1,#r do - local tv=tables[r[j]] - if tv then - r[j]=tv - end - end - end - end - end + local regions=main.regions + if regions then + local tv=tables[regions] + if tv then + main.regions=tv + regions=tv + end + for i=1,#regions do + local r=regions[i] + for j=1,#r do + local tv=tables[r[j]] + if tv then + r[j]=tv + end end - unpackdeltas(variable.global) - unpackdeltas(variable.horizontal) - unpackdeltas(variable.vertical) - unpackdeltas(variable.metrics) + end end - data.tables=nil + end end + unpackdeltas(variable.global) + unpackdeltas(variable.horizontal) + unpackdeltas(variable.vertical) + unpackdeltas(variable.metrics) + end + data.tables=nil end + end end local mt={ - __index=function(t,k) - if k=="height" then - local ht=t.boundingbox[4] - return ht<0 and 0 or ht - elseif k=="depth" then - local dp=-t.boundingbox[2] - return dp<0 and 0 or dp - elseif k=="width" then - return 0 - elseif k=="name" then - return forcenotdef and ".notdef" - end - end + __index=function(t,k) + if k=="height" then + local ht=t.boundingbox[4] + return ht<0 and 0 or ht + elseif k=="depth" then + local dp=-t.boundingbox[2] + return dp<0 and 0 or dp + elseif k=="width" then + return 0 + elseif k=="name" then + return forcenotdef and ".notdef" + end + end } local function sameformat(sequence,steps,first,nofsteps,kind) - return true + return true end local function mergesteps_1(lookup,strict) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if strict then - local f=first.format - for i=2,nofsteps do - if steps[i].format~=f then - report("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) - return 0 - end - end - end - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - local target=first.coverage + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if strict then + local f=first.format for i=2,nofsteps do - for k,v in next,steps[i].coverage do - if not target[k] then - target[k]=v - end + if steps[i].format~=f then + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) end - end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 + return 0 + end + end + end + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + if not target[k] then + target[k]=v + end + end + end + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 end local function mergesteps_2(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - if strict then - local f=first.format - for i=2,nofsteps do - if steps[i].format~=f then - report("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) - return 0 - end - end - end - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - local target=first.coverage + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if strict then + local f=first.format for i=2,nofsteps do - for k,v in next,steps[i].coverage do - local tk=target[k] - if tk then - for kk,vv in next,v do - if tk[kk]==nil then - tk[kk]=vv - end - end - else - target[k]=v + if steps[i].format~=f then + if trace_optimizations then + report_optimizations("not merging %a steps of %a lookup %a, different formats",nofsteps,lookup.type,lookup.name) + end + return 0 + end + end + end + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + for kk,vv in next,v do + if tk[kk]==nil then + tk[kk]=vv end + end + else + target[k]=v end + end end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 end local function mergesteps_3(lookup,strict) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - local coverage={} - for i=1,nofsteps do - for k,v in next,steps[i].coverage do - local tk=coverage[k] - if tk then - report("quitting merge due to multiple checks") - return nofsteps - else - coverage[k]=v - end - end - end - local first=steps[1] - local baseclasses={} - for i=1,nofsteps do - local offset=i*10 - local step=steps[i] - for k,v in sortedhash(step.baseclasses) do - baseclasses[offset+k]=v - end - for k,v in next,step.coverage do - v[1]=offset+v[1] - end - end - first.baseclasses=baseclasses - first.coverage=coverage - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 + local steps=lookup.steps + local nofsteps=lookup.nofsteps + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local coverage={} + for i=1,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=coverage[k] + if tk then + if trace_optimizations then + report_optimizations("quitting merge due to multiple checks") + end + return nofsteps + else + coverage[k]=v + end + end + end + end + local first=steps[1] + local baseclasses={} + for i=1,nofsteps do + local offset=i*10 + local step=steps[i] + for k,v in sortedhash(step.baseclasses) do + baseclasses[offset+k]=v + end + for k,v in next,step.coverage do + v[1]=offset+v[1] + end + end + first.baseclasses=baseclasses + first.coverage=coverage + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 end local function nested(old,new) - for k,v in next,old do - if k=="ligature" then - if not new.ligature then - new.ligature=v - end + for k,v in next,old do + if k=="ligature" then + if not new.ligature then + new.ligature=v + end + else + local n=new[k] + if n then + nested(v,n) + else + new[k]=v + end + end + end +end +local function mergesteps_4(lookup) + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + nested(v,tk) else - local n=new[k] - if n then - nested(v,n) - else - new[k]=v - end + target[k]=v end + end end -end -local function mergesteps_4(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - local target=first.coverage - for i=2,nofsteps do - for k,v in next,steps[i].coverage do - local tk=target[k] - if tk then - nested(v,tk) - else - target[k]=v - end - end - end - lookup.nofsteps=1 - lookup.steps={ first } - return nofsteps-1 + end + lookup.nofsteps=1 + lookup.steps={ first } + return nofsteps-1 end local function mergesteps_5(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local first=steps[1] - report("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) - local target=first.coverage - local hash=nil - for k,v in next,target do - hash=v[1] - break - end - for i=2,nofsteps do - for k,v in next,steps[i].coverage do - local tk=target[k] - if tk then - if not tk[2] then - tk[2]=v[2] - end - if not tk[3] then - tk[3]=v[3] - end - else - target[k]=v - v[1]=hash - end + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local first=steps[1] + if trace_optimizations then + report_optimizations("merging %a steps of %a lookup %a",nofsteps,lookup.type,lookup.name) + end + local target=first.coverage + local hash=nil + for k,v in next,target do + hash=v[1] + break + end + for i=2,nofsteps do + local c=steps[i].coverage + if c then + for k,v in next,c do + local tk=target[k] + if tk then + if not tk[2] then + tk[2]=v[2] + end + if not tk[3] then + tk[3]=v[3] + end + else + target[k]=v + v[1]=hash end + end end - lookup.nofsteps=1 - lookup.merged=true - lookup.steps={ first } - return nofsteps-1 + end + lookup.nofsteps=1 + lookup.merged=true + lookup.steps={ first } + return nofsteps-1 end local function checkkerns(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local kerned=0 - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=step.coverage - local kerns=true - for g1,d1 in next,coverage do - if d1==true then - elseif not d1 then - elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then - kerns=false - break - end - end - if kerns then - report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) - local c={} - for g1,d1 in next,coverage do - if d1 and d1~=true then - c[g1]=d1[3] - end - end - step.coverage=c - step.format="move" - kerned=kerned+1 - end + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local kerned=0 + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=step.coverage + local kerns=true + for g1,d1 in next,coverage do + if d1==true then + elseif not d1 then + elseif d1[1]~=0 or d1[2]~=0 or d1[4]~=0 then + kerns=false + break + end + end + if kerns then + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end + local c={} + for g1,d1 in next,coverage do + if d1 and d1~=true then + c[g1]=d1[3] + end end + step.coverage=c + step.format="move" + kerned=kerned+1 + end end - return kerned + end + return kerned end local function checkpairs(lookup) - local steps=lookup.steps - local nofsteps=lookup.nofsteps - local kerned=0 - local function onlykerns(step) - local coverage=step.coverage - for g1,d1 in next,coverage do - for g2,d2 in next,d1 do - if d2[2] then - return false - else - local v=d2[1] - if v==true then - elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then - return false - end - end - end + local steps=lookup.steps + local nofsteps=lookup.nofsteps + local kerned=0 + local function onlykerns(step) + local coverage=step.coverage + for g1,d1 in next,coverage do + for g2,d2 in next,d1 do + if d2[2] then + return false + else + local v=d2[1] + if v==true then + elseif v and (v[1]~=0 or v[2]~=0 or v[4]~=0) then + return false + end end - return coverage + end end - for i=1,nofsteps do - local step=steps[i] - if step.format=="pair" then - local coverage=onlykerns(step) - if coverage then - report("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) - for g1,d1 in next,coverage do - local d={} - for g2,d2 in next,d1 do - local v=d2[1] - if v==true then - elseif v then - d[g2]=v[3] - end - end - coverage[g1]=d - end - step.format="move" - kerned=kerned+1 + return coverage + end + for i=1,nofsteps do + local step=steps[i] + if step.format=="pair" then + local coverage=onlykerns(step) + if coverage then + if trace_optimizations then + report_optimizations("turning pairs of step %a of %a lookup %a into kerns",i,lookup.type,lookup.name) + end + for g1,d1 in next,coverage do + local d={} + for g2,d2 in next,d1 do + local v=d2[1] + if v==true then + elseif v then + d[g2]=v[3] end + end + coverage[g1]=d end + step.format="move" + kerned=kerned+1 + end end - return kerned + end + return kerned end local compact_pairs=true local compact_singles=true @@ -20814,331 +22156,333 @@ directives.register("otf.merge.ligatures",function(v) merge_ligatures=v end) directives.register("otf.merge.cursives",function(v) merge_cursives=v end) directives.register("otf.merge.marks",function(v) merge_marks=v end) function readers.compact(data) - if not data or data.compacted then - return - else - data.compacted=true - end - local resources=data.resources - local merged=0 - local kerned=0 - local allsteps=0 - local function compact(what) - local lookups=resources[what] - if lookups then - for i=1,#lookups do - local lookup=lookups[i] - local nofsteps=lookup.nofsteps - local kind=lookup.type - allsteps=allsteps+nofsteps - if nofsteps>1 then - local merg=merged - if kind=="gsub_single" then - if merge_substitutions then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_alternate" then - if merge_alternates then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_multiple" then - if merge_multiples then - merged=merged+mergesteps_1(lookup) - end - elseif kind=="gsub_ligature" then - if merge_ligatures then - merged=merged+mergesteps_4(lookup) - end - elseif kind=="gpos_single" then - if merge_singles then - merged=merged+mergesteps_1(lookup,true) - end - if compact_singles then - kerned=kerned+checkkerns(lookup) - end - elseif kind=="gpos_pair" then - if merge_pairs then - merged=merged+mergesteps_2(lookup) - end - if compact_pairs then - kerned=kerned+checkpairs(lookup) - end - elseif kind=="gpos_cursive" then - if merge_cursives then - merged=merged+mergesteps_5(lookup) - end - elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then - if merge_marks then - merged=merged+mergesteps_3(lookup) - end - end - if merg~=merged then - lookup.merged=true - end - elseif nofsteps==1 then - local kern=kerned - if kind=="gpos_single" then - if compact_singles then - kerned=kerned+checkkerns(lookup) - end - elseif kind=="gpos_pair" then - if compact_pairs then - kerned=kerned+checkpairs(lookup) - end - end - if kern~=kerned then - end - end + if not data or data.compacted then + return + else + data.compacted=true + end + local resources=data.resources + local merged=0 + local kerned=0 + local allsteps=0 + local function compact(what) + local lookups=resources[what] + if lookups then + for i=1,#lookups do + local lookup=lookups[i] + local nofsteps=lookup.nofsteps + local kind=lookup.type + allsteps=allsteps+nofsteps + if nofsteps>1 then + local merg=merged + if kind=="gsub_single" then + if merge_substitutions then + merged=merged+mergesteps_1(lookup) end - else - report("no lookups in %a",what) + elseif kind=="gsub_alternate" then + if merge_alternates then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_multiple" then + if merge_multiples then + merged=merged+mergesteps_1(lookup) + end + elseif kind=="gsub_ligature" then + if merge_ligatures then + merged=merged+mergesteps_4(lookup) + end + elseif kind=="gpos_single" then + if merge_singles then + merged=merged+mergesteps_1(lookup,true) + end + if compact_singles then + kerned=kerned+checkkerns(lookup) + end + elseif kind=="gpos_pair" then + if merge_pairs then + merged=merged+mergesteps_2(lookup) + end + if compact_pairs then + kerned=kerned+checkpairs(lookup) + end + elseif kind=="gpos_cursive" then + if merge_cursives then + merged=merged+mergesteps_5(lookup) + end + elseif kind=="gpos_mark2mark" or kind=="gpos_mark2base" or kind=="gpos_mark2ligature" then + if merge_marks then + merged=merged+mergesteps_3(lookup) + end + end + if merg~=merged then + lookup.merged=true + end + elseif nofsteps==1 then + local kern=kerned + if kind=="gpos_single" then + if compact_singles then + kerned=kerned+checkkerns(lookup) + end + elseif kind=="gpos_pair" then + if compact_pairs then + kerned=kerned+checkpairs(lookup) + end + end + if kern~=kerned then + end end + end + elseif trace_optimizations then + report_optimizations("no lookups in %a",what) end - compact("sequences") - compact("sublookups") + end + compact("sequences") + compact("sublookups") + if trace_optimizations then if merged>0 then - report("%i steps of %i removed due to merging",merged,allsteps) + report_optimizations("%i steps of %i removed due to merging",merged,allsteps) end if kerned>0 then - report("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) + report_optimizations("%i steps of %i steps turned from pairs into kerns",kerned,allsteps) end + end end local function mergesteps(t,k) - if k=="merged" then - local merged={} - for i=1,#t do - local step=t[i] - local coverage=step.coverage - for k in next,coverage do - local m=merged[k] - if m then - m[2]=i - else - merged[k]={ i,i } - end - end + if k=="merged" then + local merged={} + for i=1,#t do + local step=t[i] + local coverage=step.coverage + for k in next,coverage do + local m=merged[k] + if m then + m[2]=i + else + merged[k]={ i,i } end - t.merged=merged - return merged + end end + t.merged=merged + return merged + end end local function checkmerge(sequence) - local steps=sequence.steps - if steps then - setmetatableindex(steps,mergesteps) - end + local steps=sequence.steps + if steps then + setmetatableindex(steps,mergesteps) + end end local function checkflags(sequence,resources) - if not sequence.skiphash then - local flags=sequence.flags - if flags then - local skipmark=flags[1] - local skipligature=flags[2] - local skipbase=flags[3] - local markclass=sequence.markclass - local skipsome=skipmark or skipligature or skipbase or markclass or false - if skipsome then - sequence.skiphash=setmetatableindex(function(t,k) - local c=resources.classes[k] - local v=c==skipmark - or (markclass and c=="mark" and not markclass[k]) - or c==skipligature - or c==skipbase - or false - t[k]=v - return v - end) - else - sequence.skiphash=false - end - else - sequence.skiphash=false - end + if not sequence.skiphash then + local flags=sequence.flags + if flags then + local skipmark=flags[1] + local skipligature=flags[2] + local skipbase=flags[3] + local markclass=sequence.markclass + local skipsome=skipmark or skipligature or skipbase or markclass or false + if skipsome then + sequence.skiphash=setmetatableindex(function(t,k) + local c=resources.classes[k] + local v=c==skipmark + or (markclass and c=="mark" and not markclass[k]) + or c==skipligature + or c==skipbase + or false + t[k]=v + return v + end) + else + sequence.skiphash=false + end + else + sequence.skiphash=false end + end end local function checksteps(sequence) - local steps=sequence.steps - if steps then - for i=1,#steps do - steps[i].index=i - end + local steps=sequence.steps + if steps then + for i=1,#steps do + steps[i].index=i end + end end if fonts.helpers then - fonts.helpers.checkmerge=checkmerge - fonts.helpers.checkflags=checkflags - fonts.helpers.checksteps=checksteps + fonts.helpers.checkmerge=checkmerge + fonts.helpers.checkflags=checkflags + fonts.helpers.checksteps=checksteps end function readers.expand(data) - if not data or data.expanded then - return - else - data.expanded=true + if not data or data.expanded then + return + else + data.expanded=true + end + local resources=data.resources + local sublookups=resources.sublookups + local sequences=resources.sequences + local markclasses=resources.markclasses + local descriptions=data.descriptions + if descriptions then + local defaultwidth=resources.defaultwidth or 0 + local defaultheight=resources.defaultheight or 0 + local defaultdepth=resources.defaultdepth or 0 + local basename=trace_markwidth and file.basename(resources.filename) + for u,d in next,descriptions do + local bb=d.boundingbox + local wd=d.width + if not wd then + d.width=defaultwidth + elseif trace_markwidth and wd~=0 and d.class=="mark" then + report_markwidth("mark %a with width %b found in %a",d.name or "",wd,basename) + end + if bb then + local ht=bb[4] + local dp=-bb[2] + if ht==0 or ht<0 then + else + d.height=ht + end + if dp==0 or dp<0 then + else + d.depth=dp + end + end end - local resources=data.resources - local sublookups=resources.sublookups - local sequences=resources.sequences - local markclasses=resources.markclasses - local descriptions=data.descriptions - if descriptions then - local defaultwidth=resources.defaultwidth or 0 - local defaultheight=resources.defaultheight or 0 - local defaultdepth=resources.defaultdepth or 0 - local basename=trace_markwidth and file.basename(resources.filename) - for u,d in next,descriptions do - local bb=d.boundingbox - local wd=d.width - if not wd then - d.width=defaultwidth - elseif trace_markwidth and wd~=0 and d.class=="mark" then - report("mark %a with width %b found in %a",d.name or "",wd,basename) - end - if bb then - local ht=bb[4] - local dp=-bb[2] - if ht==0 or ht<0 then - else - d.height=ht + end + local function expandlookups(sequences) + if sequences then + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps then + local nofsteps=sequence.nofsteps + local kind=sequence.type + local markclass=sequence.markclass + if markclass then + if not markclasses then + report_warning("missing markclasses") + sequence.markclass=false + else + sequence.markclass=markclasses[markclass] + end + end + for i=1,nofsteps do + local step=steps[i] + local baseclasses=step.baseclasses + if baseclasses then + local coverage=step.coverage + for k,v in next,coverage do + v[1]=baseclasses[v[1]] + end + elseif kind=="gpos_cursive" then + local coverage=step.coverage + for k,v in next,coverage do + v[1]=coverage + end + end + local rules=step.rules + if rules then + local rulehash={ n=0 } + local rulesize=0 + local coverage={} + local lookuptype=sequence.type + local nofrules=#rules + step.coverage=coverage + for currentrule=1,nofrules do + local rule=rules[currentrule] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end end - if dp==0 or dp<0 then - else - d.depth=dp + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] end - end - end - end - local function expandlookups(sequences) - if sequences then - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps then - local nofsteps=sequence.nofsteps - local kind=sequence.type - local markclass=sequence.markclass - if markclass then - if not markclasses then - report_warning("missing markclasses") - sequence.markclass=false + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups then + for i=1,#lookups do + local lookups=lookups[i] + if lookups then + for k,v in next,lookups do + local lookup=sublookups[v] + if lookup then + lookups[k]=lookup + if not subtype then + subtype=lookup.type + end else - sequence.markclass=markclasses[markclass] - end - end - for i=1,nofsteps do - local step=steps[i] - local baseclasses=step.baseclasses - if baseclasses then - local coverage=step.coverage - for k,v in next,coverage do - v[1]=baseclasses[v[1]] - end - elseif kind=="gpos_cursive" then - local coverage=step.coverage - for k,v in next,coverage do - v[1]=coverage - end - end - local rules=step.rules - if rules then - local rulehash={ n=0 } - local rulesize=0 - local coverage={} - local lookuptype=sequence.type - local nofrules=#rules - step.coverage=coverage - for currentrule=1,nofrules do - local rule=rules[currentrule] - local current=rule.current - local before=rule.before - local after=rule.after - local replacements=rule.replacements or false - local sequence={} - local nofsequences=0 - if before then - for n=1,#before do - nofsequences=nofsequences+1 - sequence[nofsequences]=before[n] - end - end - local start=nofsequences+1 - for n=1,#current do - nofsequences=nofsequences+1 - sequence[nofsequences]=current[n] - end - local stop=nofsequences - if after then - for n=1,#after do - nofsequences=nofsequences+1 - sequence[nofsequences]=after[n] - end - end - local lookups=rule.lookups or false - local subtype=nil - if lookups then - for i=1,#lookups do - local lookups=lookups[i] - if lookups then - for k,v in next,lookups do - local lookup=sublookups[v] - if lookup then - lookups[k]=lookup - if not subtype then - subtype=lookup.type - end - else - end - end - end - end - end - if sequence[1] then - sequence.n=#sequence - local ruledata={ - currentrule, - lookuptype, - sequence, - start, - stop, - lookups, - replacements, - subtype, - } - rulesize=rulesize+1 - rulehash[rulesize]=ruledata - rulehash.n=rulesize - if true then - for unic in next,sequence[start] do - local cu=coverage[unic] - if cu then - local n=#cu+1 - cu[n]=ruledata - cu.n=n - else - coverage[unic]={ ruledata,n=1 } - end - end - else - for unic in next,sequence[start] do - local cu=coverage[unic] - if cu then - else - coverage[unic]=rulehash - end - end - end - end - end end - end - checkmerge(sequence) - checkflags(sequence,resources) - checksteps(sequence) + end + end + end + end + if sequence[1] then + sequence.n=#sequence + local ruledata={ + currentrule, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + rulesize=rulesize+1 + rulehash[rulesize]=ruledata + rulehash.n=rulesize + if true then + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + local n=#cu+1 + cu[n]=ruledata + cu.n=n + else + coverage[unic]={ ruledata,n=1 } + end + end + else + for unic in next,sequence[start] do + local cu=coverage[unic] + if cu then + else + coverage[unic]=rulehash + end + end + end end + end end + end + checkmerge(sequence) + checkflags(sequence,resources) + checksteps(sequence) end + end end - expandlookups(sequences) - expandlookups(sublookups) + end + expandlookups(sequences) + expandlookups(sublookups) end end -- closure @@ -21146,11 +22490,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-otl']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", } local lower=string.lower local type,next,tonumber,tostring,unpack=type,next,tonumber,tostring,unpack @@ -21165,19 +22509,19 @@ local starttiming=statistics.starttiming local stoptiming=statistics.stoptiming local elapsedtime=statistics.elapsedtime local findbinfile=resolvers.findbinfile -local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) -local trace_features=false registertracker("otf.features",function(v) trace_features=v end) -local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end) +local trace_loading=false registertracker("otf.loading",function(v) trace_loading=v end) +local trace_features=false registertracker("otf.features",function(v) trace_features=v end) +local trace_defining=false registertracker("fonts.defining",function(v) trace_defining=v end) local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.103 +otf.version=3.107 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) -otf.sbixcache=containers.define("fonts","sbix",otf.version,true) +otf.pngcache=containers.define("fonts","png",otf.version,true) otf.pdfcache=containers.define("fonts","pdf",otf.version,true) otf.svgenabled=false -otf.sbixenabled=false +otf.pngenabled=false local otfreaders=otf.readers local hashes=fonts.hashes local definers=fonts.definers @@ -21188,7 +22532,7 @@ local registerotffeature=otffeatures.register local otfenhancers=constructors.enhancers.otf local registerotfenhancer=otfenhancers.register local forceload=false -local cleanup=0 +local cleanup=0 local syncspace=true local forcenotdef=false local privateoffset=fonts.constructors and fonts.constructors.privateoffset or 0xF0000 @@ -21209,638 +22553,641 @@ local threshold=100 local tracememory=false registertracker("fonts.otf.loader.memory",function(v) tracememory=v end) if not checkmemory then - local collectgarbage=collectgarbage - checkmemory=function(previous,threshold) - local current=collectgarbage("count") - if previous then - local checked=(threshold or 64)*1024 - if current-previous>checked then - collectgarbage("collect") - current=collectgarbage("count") - end - end - return current - end + local collectgarbage=collectgarbage + checkmemory=function(previous,threshold) + local current=collectgarbage("count") + if previous then + local checked=(threshold or 64)*1024 + if current-previous>checked then + collectgarbage("collect") + current=collectgarbage("count") + end + end + return current + end end function otf.load(filename,sub,instance) - local base=file.basename(file.removesuffix(filename)) - local name=file.removesuffix(base) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - if sub=="" then - sub=false - end - local hash=name - if sub then - hash=hash.."-"..sub - end - if instance then - hash=hash.."-"..instance - end - hash=containers.cleanname(hash) - local data=containers.read(otf.cache,hash) - local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion - if forceload then - report_otf("forced reload of %a due to hard coded flag",filename) - reload=true - end - if reload then - report_otf("loading %a, hash %a",filename,hash) - starttiming(otfreaders) - data=otfreaders.loadfont(filename,sub or 1,instance) - if data then - local used=checkmemory() - local resources=data.resources - local svgshapes=resources.svgshapes - local sbixshapes=resources.sbixshapes - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - if svgshapes then - resources.svgshapes=nil - if otf.svgenabled then - local timestamp=os.date() - containers.write(otf.svgcache,hash,{ - svgshapes=svgshapes, - timestamp=timestamp, - }) - data.properties.svg={ - hash=hash, - timestamp=timestamp, - } - end - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - end - if sbixshapes then - resources.sbixshapes=nil - if otf.sbixenabled then - local timestamp=os.date() - containers.write(otf.sbixcache,hash,{ - sbixshapes=sbixshapes, - timestamp=timestamp, - }) - data.properties.sbix={ - hash=hash, - timestamp=timestamp, - } - end - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - end - otfreaders.compact(data) - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - otfreaders.rehash(data,"unicodes") - otfreaders.addunicodetable(data) - otfreaders.extend(data) - if cleanup==0 then - checkmemory(used,threshold,tracememory) - end - otfreaders.pack(data) - report_otf("loading done") - report_otf("saving %a in cache",filename) - data=containers.write(otf.cache,hash,data) - if cleanup>1 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - stoptiming(otfreaders) - if elapsedtime then - report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) - end - if cleanup>3 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end - data=containers.read(otf.cache,hash) - if cleanup>2 then - collectgarbage("collect") - else - checkmemory(used,threshold,tracememory) - end + local base=file.basename(file.removesuffix(filename)) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if sub=="" then + sub=false + end + local hash=name + if sub then + hash=hash.."-"..sub + end + if instance then + hash=hash.."-"..instance + end + hash=containers.cleanname(hash) + local data=containers.read(otf.cache,hash) + local reload=not data or data.size~=size or data.time~=time or data.tableversion~=otfreaders.tableversion + if forceload then + report_otf("forced reload of %a due to hard coded flag",filename) + reload=true + end + if reload then + report_otf("loading %a, hash %a",filename,hash) + starttiming(otfreaders,true) + data=otfreaders.loadfont(filename,sub or 1,instance) + if data then + local used=checkmemory() + local resources=data.resources + local svgshapes=resources.svgshapes + local pngshapes=resources.pngshapes + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + if svgshapes then + resources.svgshapes=nil + if otf.svgenabled then + local timestamp=os.date() + containers.write(otf.svgcache,hash,{ + svgshapes=svgshapes, + timestamp=timestamp, + }) + data.properties.svg={ + hash=hash, + timestamp=timestamp, + } + end + if cleanup>1 then + collectgarbage("collect") else - data=nil - report_otf("loading failed due to read error") - end + checkmemory(used,threshold,tracememory) + end + end + if pngshapes then + resources.pngshapes=nil + if otf.pngenabled then + local timestamp=os.date() + containers.write(otf.pngcache,hash,{ + pngshapes=pngshapes, + timestamp=timestamp, + }) + data.properties.png={ + hash=hash, + timestamp=timestamp, + } + end + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + end + otfreaders.compact(data) + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.rehash(data,"unicodes") + otfreaders.addunicodetable(data) + otfreaders.extend(data) + if cleanup==0 then + checkmemory(used,threshold,tracememory) + end + otfreaders.pack(data) + report_otf("loading done") + report_otf("saving %a in cache",filename) + data=containers.write(otf.cache,hash,data) + if cleanup>1 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + stoptiming(otfreaders) + if elapsedtime then + report_otf("loading, optimizing, packing and caching time %s",elapsedtime(otfreaders)) + end + if cleanup>3 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + data=containers.read(otf.cache,hash) + if cleanup>2 then + collectgarbage("collect") + else + checkmemory(used,threshold,tracememory) + end + else + stoptiming(otfreaders) + data=nil + report_otf("loading failed due to read error") end - if data then - if trace_defining then - report_otf("loading from cache using hash %a",hash) - end - otfreaders.unpack(data) - otfreaders.expand(data) - otfreaders.addunicodetable(data) - otfenhancers.apply(data,filename,data) - if applyruntimefixes then - applyruntimefixes(filename,data) - end - data.metadata.math=data.resources.mathconstants - local classes=data.resources.classes - if not classes then - local descriptions=data.descriptions - classes=setmetatableindex(function(t,k) - local d=descriptions[k] - local v=(d and d.class or "base") or false - t[k]=v - return v - end) - data.resources.classes=classes - end + end + if data then + if trace_defining then + report_otf("loading from cache using hash %a",hash) + end + otfreaders.unpack(data) + otfreaders.expand(data) + otfreaders.addunicodetable(data) + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end + data.metadata.math=data.resources.mathconstants + local classes=data.resources.classes + if not classes then + local descriptions=data.descriptions + classes=setmetatableindex(function(t,k) + local d=descriptions[k] + local v=(d and d.class or "base") or false + t[k]=v + return v + end) + data.resources.classes=classes end - return data + end + return data end function otf.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) - if okay then - return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) - else - return {} - end + local okay=constructors.initializefeatures("otf",tfmdata,features,trace_features,report_otf) + if okay then + return constructors.collectprocessors("otf",tfmdata,features,trace_features,report_otf) + else + return {} + end end local function copytotfm(data,cache_id) - if data then - local metadata=data.metadata - local properties=derivetable(data.properties) - local descriptions=derivetable(data.descriptions) - local goodies=derivetable(data.goodies) - local characters={} - local parameters={} - local mathparameters={} - local resources=data.resources - local unicodes=resources.unicodes - local spaceunits=500 - local spacer="space" - local designsize=metadata.designsize or 100 - local minsize=metadata.minsize or designsize - local maxsize=metadata.maxsize or designsize - local mathspecs=metadata.math - if designsize==0 then - designsize=100 - minsize=100 - maxsize=100 - end - if mathspecs then - for name,value in next,mathspecs do - mathparameters[name]=value - end - end - for unicode in next,data.descriptions do - characters[unicode]={} - end - if mathspecs then - for unicode,character in next,characters do - local d=descriptions[unicode] - local m=d.math - if m then - local italic=m.italic - local vitalic=m.vitalic - local variants=m.hvariants - local parts=m.hparts - if variants then - local c=character - for i=1,#variants do - local un=variants[i] - c.next=un - c=characters[un] - end - c.horiz_variants=parts - elseif parts then - character.horiz_variants=parts - italic=m.hitalic - end - local variants=m.vvariants - local parts=m.vparts - if variants then - local c=character - for i=1,#variants do - local un=variants[i] - c.next=un - c=characters[un] - end - c.vert_variants=parts - elseif parts then - character.vert_variants=parts - end - if italic and italic~=0 then - character.italic=italic - end - if vitalic and vitalic~=0 then - character.vert_italic=vitalic - end - local accent=m.accent - if accent then - character.accent=accent - end - local kerns=m.kerns - if kerns then - character.mathkerns=kerns - end - end - end - end - local filename=constructors.checkedfilename(resources) - local fontname=metadata.fontname - local fullname=metadata.fullname or fontname - local psname=fontname or fullname - local units=metadata.units or 1000 - if units==0 then - units=1000 - metadata.units=1000 - report_otf("changing %a units to %a",0,units) - end - local monospaced=metadata.monospaced - local charwidth=metadata.averagewidth - local charxheight=metadata.xheight - local italicangle=metadata.italicangle - local hasitalics=metadata.hasitalics - properties.monospaced=monospaced - properties.hasitalics=hasitalics - parameters.italicangle=italicangle - parameters.charwidth=charwidth - parameters.charxheight=charxheight - local space=0x0020 - local emdash=0x2014 - if monospaced then - if descriptions[space] then - spaceunits,spacer=descriptions[space].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width,"emdash" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - else - if descriptions[space] then - spaceunits,spacer=descriptions[space].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width/2,"emdash/2" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - end - spaceunits=tonumber(spaceunits) or units/2 - parameters.slant=0 - parameters.space=spaceunits - parameters.space_stretch=1*units/2 - parameters.space_shrink=1*units/3 - parameters.x_height=2*units/5 - parameters.quad=units - if spaceunits<2*units/5 then - end - if italicangle and italicangle~=0 then - parameters.italicangle=italicangle - parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.tan(italicangle*math.pi/180) - end - if monospaced then - parameters.space_stretch=0 - parameters.space_shrink=0 - elseif syncspace then - parameters.space_stretch=spaceunits/2 - parameters.space_shrink=spaceunits/3 - end - parameters.extra_space=parameters.space_shrink - if charxheight then - parameters.x_height=charxheight - else - local x=0x0078 - if x then - local x=descriptions[x] - if x then - parameters.x_height=x.height - end - end + if data then + local metadata=data.metadata + local properties=derivetable(data.properties) + local descriptions=derivetable(data.descriptions) + local goodies=derivetable(data.goodies) + local characters={} + local parameters={} + local mathparameters={} + local resources=data.resources + local unicodes=resources.unicodes + local spaceunits=500 + local spacer="space" + local designsize=metadata.designsize or 100 + local minsize=metadata.minsize or designsize + local maxsize=metadata.maxsize or designsize + local mathspecs=metadata.math + if designsize==0 then + designsize=100 + minsize=100 + maxsize=100 + end + if mathspecs then + for name,value in next,mathspecs do + mathparameters[name]=value + end + end + for unicode in next,data.descriptions do + characters[unicode]={} + end + if mathspecs then + for unicode,character in next,characters do + local d=descriptions[unicode] + local m=d.math + if m then + local italic=m.italic + local vitalic=m.vitalic + local variants=m.hvariants + local parts=m.hparts + if variants then + local c=character + for i=1,#variants do + local un=variants[i] + c.next=un + c=characters[un] + end + c.horiz_variants=parts + elseif parts then + character.horiz_variants=parts + italic=m.hitalic + end + local variants=m.vvariants + local parts=m.vparts + if variants then + local c=character + for i=1,#variants do + local un=variants[i] + c.next=un + c=characters[un] + end + c.vert_variants=parts + elseif parts then + character.vert_variants=parts + end + if italic and italic~=0 then + character.italic=italic + end + if vitalic and vitalic~=0 then + character.vert_italic=vitalic + end + local accent=m.accent + if accent then + character.accent=accent + end + local kerns=m.kerns + if kerns then + character.mathkerns=kerns + end end - parameters.designsize=(designsize/10)*65536 - parameters.minsize=(minsize/10)*65536 - parameters.maxsize=(maxsize/10)*65536 - parameters.ascender=abs(metadata.ascender or 0) - parameters.descender=abs(metadata.descender or 0) - parameters.units=units - properties.space=spacer - properties.encodingbytes=2 - properties.format=data.format or formats.otf - properties.noglyphnames=true - properties.filename=filename - properties.fontname=fontname - properties.fullname=fullname - properties.psname=psname - properties.name=filename or fullname - properties.private=properties.private or data.private or privateoffset - return { - characters=characters, - descriptions=descriptions, - parameters=parameters, - mathparameters=mathparameters, - resources=resources, - properties=properties, - goodies=goodies, - } - end + end + end + local filename=constructors.checkedfilename(resources) + local fontname=metadata.fontname + local fullname=metadata.fullname or fontname + local psname=fontname or fullname + local subfont=metadata.subfontindex + local units=metadata.units or 1000 + if units==0 then + units=1000 + metadata.units=1000 + report_otf("changing %a units to %a",0,units) + end + local monospaced=metadata.monospaced + local charwidth=metadata.averagewidth + local charxheight=metadata.xheight + local italicangle=metadata.italicangle + local hasitalics=metadata.hasitalics + properties.monospaced=monospaced + properties.hasitalics=hasitalics + parameters.italicangle=italicangle + parameters.charwidth=charwidth + parameters.charxheight=charxheight + local space=0x0020 + local emdash=0x2014 + if monospaced then + if descriptions[space] then + spaceunits,spacer=descriptions[space].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width,"emdash" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + else + if descriptions[space] then + spaceunits,spacer=descriptions[space].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width/2,"emdash/2" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + end + spaceunits=tonumber(spaceunits) or units/2 + parameters.slant=0 + parameters.space=spaceunits + parameters.space_stretch=1*units/2 + parameters.space_shrink=1*units/3 + parameters.x_height=2*units/5 + parameters.quad=units + if spaceunits<2*units/5 then + end + if italicangle and italicangle~=0 then + parameters.italicangle=italicangle + parameters.italicfactor=math.cos(math.rad(90+italicangle)) + parameters.slant=- math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.space_stretch=0 + parameters.space_shrink=0 + elseif syncspace then + parameters.space_stretch=spaceunits/2 + parameters.space_shrink=spaceunits/3 + end + parameters.extra_space=parameters.space_shrink + if charxheight then + parameters.x_height=charxheight + else + local x=0x0078 + if x then + local x=descriptions[x] + if x then + parameters.x_height=x.height + end + end + end + parameters.designsize=(designsize/10)*65536 + parameters.minsize=(minsize/10)*65536 + parameters.maxsize=(maxsize/10)*65536 + parameters.ascender=abs(metadata.ascender or 0) + parameters.descender=abs(metadata.descender or 0) + parameters.units=units + properties.space=spacer + properties.encodingbytes=2 + properties.format=data.format or formats.otf + properties.noglyphnames=true + properties.filename=filename + properties.fontname=fontname + properties.fullname=fullname + properties.psname=psname + properties.name=filename or fullname + properties.subfont=subfont + properties.private=properties.private or data.private or privateoffset + return { + characters=characters, + descriptions=descriptions, + parameters=parameters, + mathparameters=mathparameters, + resources=resources, + properties=properties, + goodies=goodies, + } + end end local converters={ - woff={ - cachename="webfonts", - action=otf.readers.woff2otf, - } + woff={ + cachename="webfonts", + action=otf.readers.woff2otf, + } } local function checkconversion(specification) - local filename=specification.filename - local converter=converters[lower(file.suffix(filename))] - if converter then - local base=file.basename(filename) - local name=file.removesuffix(base) - local attr=lfs.attributes(filename) - local size=attr and attr.size or 0 - local time=attr and attr.modification or 0 - if size>0 then - local cleanname=containers.cleanname(name) - local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) - if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then - report_otf("caching font %a in %a",filename,cachename) - converter.action(filename,cachename) - lfs.touch(cachename,time,time) - end - specification.filename=cachename - end + local filename=specification.filename + local converter=converters[lower(file.suffix(filename))] + if converter then + local base=file.basename(filename) + local name=file.removesuffix(base) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + if size>0 then + local cleanname=containers.cleanname(name) + local cachename=caches.setfirstwritablefile(cleanname,converter.cachename) + if not io.exists(cachename) or (time~=lfs.attributes(cachename).modification) then + report_otf("caching font %a in %a",filename,cachename) + converter.action(filename,cachename) + lfs.touch(cachename,time,time) + end + specification.filename=cachename end + end end local function otftotfm(specification) - local cache_id=specification.hash - local tfmdata=containers.read(constructors.cache,cache_id) - if not tfmdata then - checkconversion(specification) - local name=specification.name - local sub=specification.sub - local subindex=specification.subindex - local filename=specification.filename - local features=specification.features.normal - local instance=specification.instance or (features and features.axis) - local rawdata=otf.load(filename,sub,instance) - if rawdata and next(rawdata) then - local descriptions=rawdata.descriptions - rawdata.lookuphash={} - tfmdata=copytotfm(rawdata,cache_id) - if tfmdata and next(tfmdata) then - local features=constructors.checkedfeatures("otf",features) - local shared=tfmdata.shared - if not shared then - shared={} - tfmdata.shared=shared - end - shared.rawdata=rawdata - shared.dynamics={} - tfmdata.changed={} - shared.features=features - shared.processes=otf.setfeatures(tfmdata,features) - end + local cache_id=specification.hash + local tfmdata=containers.read(constructors.cache,cache_id) + if not tfmdata then + checkconversion(specification) + local name=specification.name + local sub=specification.sub + local subindex=specification.subindex + local filename=specification.filename + local features=specification.features.normal + local instance=specification.instance or (features and features.axis) + local rawdata=otf.load(filename,sub,instance) + if rawdata and next(rawdata) then + local descriptions=rawdata.descriptions + rawdata.lookuphash={} + tfmdata=copytotfm(rawdata,cache_id) + if tfmdata and next(tfmdata) then + local features=constructors.checkedfeatures("otf",features) + local shared=tfmdata.shared + if not shared then + shared={} + tfmdata.shared=shared end - containers.write(constructors.cache,cache_id,tfmdata) + shared.rawdata=rawdata + shared.dynamics={} + tfmdata.changed={} + shared.features=features + shared.processes=otf.setfeatures(tfmdata,features) + end end - return tfmdata + containers.write(constructors.cache,cache_id,tfmdata) + end + return tfmdata end local function read_from_otf(specification) - local tfmdata=otftotfm(specification) - if tfmdata then - tfmdata.properties.name=specification.name - tfmdata.properties.sub=specification.sub - tfmdata=constructors.scale(tfmdata,specification) - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) - constructors.setname(tfmdata,specification) - fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) - end - return tfmdata + local tfmdata=otftotfm(specification) + if tfmdata then + tfmdata.properties.name=specification.name + tfmdata.properties.sub=specification.sub + tfmdata=constructors.scale(tfmdata,specification) + local allfeatures=tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("otf",tfmdata,allfeatures,trace_features,report_otf) + constructors.setname(tfmdata,specification) + fonts.loggers.register(tfmdata,file.suffix(specification.filename),specification) + end + return tfmdata end local function checkmathsize(tfmdata,mathsize) - local mathdata=tfmdata.shared.rawdata.metadata.math - local mathsize=tonumber(mathsize) - if mathdata then - local parameters=tfmdata.parameters - parameters.scriptpercentage=mathdata.ScriptPercentScaleDown - parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown - parameters.mathsize=mathsize - end + local mathdata=tfmdata.shared.rawdata.metadata.math + local mathsize=tonumber(mathsize) + if mathdata then + local parameters=tfmdata.parameters + parameters.scriptpercentage=mathdata.ScriptPercentScaleDown + parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown + parameters.mathsize=mathsize + end end registerotffeature { - name="mathsize", - description="apply mathsize specified in the font", - initializers={ - base=checkmathsize, - node=checkmathsize, - } + name="mathsize", + description="apply mathsize specified in the font", + initializers={ + base=checkmathsize, + node=checkmathsize, + } } function otf.collectlookups(rawdata,kind,script,language) - if not kind then - return - end - if not script then - script=default - end - if not language then - language=default - end - local lookupcache=rawdata.lookupcache - if not lookupcache then - lookupcache={} - rawdata.lookupcache=lookupcache - end - local kindlookup=lookupcache[kind] - if not kindlookup then - kindlookup={} - lookupcache[kind]=kindlookup - end - local scriptlookup=kindlookup[script] - if not scriptlookup then - scriptlookup={} - kindlookup[script]=scriptlookup - end - local languagelookup=scriptlookup[language] - if not languagelookup then - local sequences=rawdata.resources.sequences - local featuremap={} - local featurelist={} - if sequences then - for s=1,#sequences do - local sequence=sequences[s] - local features=sequence.features - if features then - features=features[kind] - if features then - features=features[script] or features[wildcard] - if features then - features=features[language] or features[wildcard] - if features then - if not featuremap[sequence] then - featuremap[sequence]=true - featurelist[#featurelist+1]=sequence - end - end - end - end + if not kind then + return + end + if not script then + script=default + end + if not language then + language=default + end + local lookupcache=rawdata.lookupcache + if not lookupcache then + lookupcache={} + rawdata.lookupcache=lookupcache + end + local kindlookup=lookupcache[kind] + if not kindlookup then + kindlookup={} + lookupcache[kind]=kindlookup + end + local scriptlookup=kindlookup[script] + if not scriptlookup then + scriptlookup={} + kindlookup[script]=scriptlookup + end + local languagelookup=scriptlookup[language] + if not languagelookup then + local sequences=rawdata.resources.sequences + local featuremap={} + local featurelist={} + if sequences then + for s=1,#sequences do + local sequence=sequences[s] + local features=sequence.features + if features then + features=features[kind] + if features then + features=features[script] or features[wildcard] + if features then + features=features[language] or features[wildcard] + if features then + if not featuremap[sequence] then + featuremap[sequence]=true + featurelist[#featurelist+1]=sequence end + end end - if #featurelist==0 then - featuremap,featurelist=false,false - end - else - featuremap,featurelist=false,false + end end - languagelookup={ featuremap,featurelist } - scriptlookup[language]=languagelookup + end + if #featurelist==0 then + featuremap,featurelist=false,false + end + else + featuremap,featurelist=false,false end - return unpack(languagelookup) + languagelookup={ featuremap,featurelist } + scriptlookup[language]=languagelookup + end + return unpack(languagelookup) end local function getgsub(tfmdata,k,kind,value) - local shared=tfmdata.shared - local rawdata=shared and shared.rawdata - if rawdata then - local sequences=rawdata.resources.sequences - if sequences then - local properties=tfmdata.properties - local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) - if validlookups then - for i=1,#lookuplist do - local lookup=lookuplist[i] - local steps=lookup.steps - local nofsteps=lookup.nofsteps - for i=1,nofsteps do - local coverage=steps[i].coverage - if coverage then - local found=coverage[k] - if found then - return found,lookup.type - end - end - end - end + local shared=tfmdata.shared + local rawdata=shared and shared.rawdata + if rawdata then + local sequences=rawdata.resources.sequences + if sequences then + local properties=tfmdata.properties + local validlookups,lookuplist=otf.collectlookups(rawdata,kind,properties.script,properties.language) + if validlookups then + for i=1,#lookuplist do + local lookup=lookuplist[i] + local steps=lookup.steps + local nofsteps=lookup.nofsteps + for i=1,nofsteps do + local coverage=steps[i].coverage + if coverage then + local found=coverage[k] + if found then + return found,lookup.type + end end + end end + end end + end end otf.getgsub=getgsub function otf.getsubstitution(tfmdata,k,kind,value) - local found,kind=getgsub(tfmdata,k,kind,value) - if not found then - elseif kind=="gsub_single" then - return found - elseif kind=="gsub_alternate" then - local choice=tonumber(value) or 1 - return found[choice] or found[1] or k - end - return k + local found,kind=getgsub(tfmdata,k,kind,value) + if not found then + elseif kind=="gsub_single" then + return found + elseif kind=="gsub_alternate" then + local choice=tonumber(value) or 1 + return found[choice] or found[1] or k + end + return k end otf.getalternate=otf.getsubstitution function otf.getmultiple(tfmdata,k,kind) - local found,kind=getgsub(tfmdata,k,kind) - if found and kind=="gsub_multiple" then - return found - end - return { k } + local found,kind=getgsub(tfmdata,k,kind) + if found and kind=="gsub_multiple" then + return found + end + return { k } end function otf.getkern(tfmdata,left,right,kind) - local kerns=getgsub(tfmdata,left,kind or "kern",true) - if kerns then - local found=kerns[right] - local kind=type(found) - if kind=="table" then - found=found[1][3] - elseif kind~="number" then - found=false - end - if found then - return found*tfmdata.parameters.factor - end + local kerns=getgsub(tfmdata,left,kind or "kern",true) + if kerns then + local found=kerns[right] + local kind=type(found) + if kind=="table" then + found=found[1][3] + elseif kind~="number" then + found=false end - return 0 + if found then + return found*tfmdata.parameters.factor + end + end + return 0 end local function check_otf(forced,specification,suffix) - local name=specification.name - if forced then - name=specification.forcedname - end - local fullname=findbinfile(name,suffix) or "" - if fullname=="" then - fullname=fonts.names.getfilename(name,suffix) or "" - end - if fullname~="" and not fonts.names.ignoredfile(fullname) then - specification.filename=fullname - return read_from_otf(specification) - end + local name=specification.name + if forced then + name=specification.forcedname + end + local fullname=findbinfile(name,suffix) or "" + if fullname=="" then + fullname=fonts.names.getfilename(name,suffix) or "" + end + if fullname~="" and not fonts.names.ignoredfile(fullname) then + specification.filename=fullname + return read_from_otf(specification) + end end local function opentypereader(specification,suffix) - local forced=specification.forced or "" - if formats[forced] then - return check_otf(true,specification,forced) - else - return check_otf(false,specification,suffix) - end + local forced=specification.forced or "" + if formats[forced] then + return check_otf(true,specification,forced) + else + return check_otf(false,specification,suffix) + end end readers.opentype=opentypereader function readers.otf(specification) return opentypereader(specification,"otf") end function readers.ttf(specification) return opentypereader(specification,"ttf") end function readers.ttc(specification) return opentypereader(specification,"ttf") end function readers.woff(specification) - checkconversion(specification) - opentypereader(specification,"") + checkconversion(specification) + opentypereader(specification,"") end function otf.scriptandlanguage(tfmdata,attr) - local properties=tfmdata.properties - return properties.script or "dflt",properties.language or "dflt" + local properties=tfmdata.properties + return properties.script or "dflt",properties.language or "dflt" end local function justset(coverage,unicode,replacement) - coverage[unicode]=replacement + coverage[unicode]=replacement end otf.coverup={ - stepkey="steps", - actions={ - chainsubstitution=justset, - chainposition=justset, - substitution=justset, - alternate=justset, - multiple=justset, - kern=justset, - pair=justset, - single=justset, - ligature=function(coverage,unicode,ligature) - local first=ligature[1] - local tree=coverage[first] - if not tree then - tree={} - coverage[first]=tree - end - for i=2,#ligature do - local l=ligature[i] - local t=tree[l] - if not t then - t={} - tree[l]=t - end - tree=t - end - tree.ligature=unicode - end, - }, - register=function(coverage,featuretype,format) - return { - format=format, - coverage=coverage, - } - end + stepkey="steps", + actions={ + chainsubstitution=justset, + chainposition=justset, + substitution=justset, + alternate=justset, + multiple=justset, + kern=justset, + pair=justset, + single=justset, + ligature=function(coverage,unicode,ligature) + local first=ligature[1] + local tree=coverage[first] + if not tree then + tree={} + coverage[first]=tree + end + for i=2,#ligature do + local l=ligature[i] + local t=tree[l] + if not t then + t={} + tree[l]=t + end + tree=t + end + tree.ligature=unicode + end, + }, + register=function(coverage,featuretype,format) + return { + format=format, + coverage=coverage, + } + end } end -- closure @@ -21848,23 +23195,23 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-oto']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local concat,unpack=table.concat,table.unpack local insert,remove=table.insert,table.remove local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget -local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) -local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) -local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) -local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end) -local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end) -local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end) -local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end) +local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) +local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) +local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) +local trace_alternatives=false trackers.register("otf.alternatives",function(v) trace_alternatives=v end) +local trace_ligatures=false trackers.register("otf.ligatures",function(v) trace_ligatures=v end) +local trace_kerns=false trackers.register("otf.kerns",function(v) trace_kerns=v end) +local trace_preparing=false trackers.register("otf.preparing",function(v) trace_preparing=v end) local report_prepare=logs.reporter("fonts","otf prepare") local fonts=fonts local otf=fonts.handlers.otf @@ -21879,416 +23226,427 @@ local f_unicode=formatters["%U"] local f_uniname=formatters["%U (%s)"] local f_unilist=formatters["% t (% t)"] local function gref(descriptions,n) - if type(n)=="number" then - local name=descriptions[n].name - if name then - return f_uniname(n,name) - else - return f_unicode(n) - end - elseif n then - local num,nam,j={},{},0 - for i=1,#n do - local ni=n[i] - if tonumber(ni) then - j=j+1 - local di=descriptions[ni] - num[j]=f_unicode(ni) - nam[j]=di and di.name or "-" - end - end - return f_unilist(num,nam) + if type(n)=="number" then + local name=descriptions[n].name + if name then + return f_uniname(n,name) else - return "" - end + return f_unicode(n) + end + elseif n then + local num={} + local nam={} + local j=0 + for i=1,#n do + local ni=n[i] + if tonumber(ni) then + j=j+1 + local di=descriptions[ni] + num[j]=f_unicode(ni) + nam[j]=di and di.name or "-" + end + end + return f_unilist(num,nam) + else + return "" + end end local function cref(feature,sequence) - return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name) + return formatters["feature %a, type %a, chain lookup %a"](feature,sequence.type,sequence.name) end local function report_substitution(feature,sequence,descriptions,unicode,substitution) - if unicode==substitution then - report_prepare("%s: base substitution %s maps onto itself", - cref(feature,sequence), - gref(descriptions,unicode)) - else - report_prepare("%s: base substitution %s => %S", - cref(feature,sequence), - gref(descriptions,unicode), - gref(descriptions,substitution)) - end + if unicode==substitution then + report_prepare("%s: base substitution %s maps onto itself", + cref(feature,sequence), + gref(descriptions,unicode)) + else + report_prepare("%s: base substitution %s => %S", + cref(feature,sequence), + gref(descriptions,unicode), + gref(descriptions,substitution)) + end end local function report_alternate(feature,sequence,descriptions,unicode,replacement,value,comment) - if unicode==replacement then - report_prepare("%s: base alternate %s maps onto itself", - cref(feature,sequence), - gref(descriptions,unicode)) - else - report_prepare("%s: base alternate %s => %s (%S => %S)", - cref(feature,sequence), - gref(descriptions,unicode), - replacement and gref(descriptions,replacement), - value, - comment) - end + if unicode==replacement then + report_prepare("%s: base alternate %s maps onto itself", + cref(feature,sequence), + gref(descriptions,unicode)) + else + report_prepare("%s: base alternate %s => %s (%S => %S)", + cref(feature,sequence), + gref(descriptions,unicode), + replacement and gref(descriptions,replacement), + value, + comment) + end end local function report_ligature(feature,sequence,descriptions,unicode,ligature) - report_prepare("%s: base ligature %s => %S", - cref(feature,sequence), - gref(descriptions,ligature), - gref(descriptions,unicode)) + report_prepare("%s: base ligature %s => %S", + cref(feature,sequence), + gref(descriptions,ligature), + gref(descriptions,unicode)) end local function report_kern(feature,sequence,descriptions,unicode,otherunicode,value) - report_prepare("%s: base kern %s + %s => %S", - cref(feature,sequence), - gref(descriptions,unicode), - gref(descriptions,otherunicode), - value) + report_prepare("%s: base kern %s + %s => %S", + cref(feature,sequence), + gref(descriptions,unicode), + gref(descriptions,otherunicode), + value) end local basehash,basehashes,applied={},1,{} local function registerbasehash(tfmdata) - local properties=tfmdata.properties - local hash=concat(applied," ") - local base=basehash[hash] - if not base then - basehashes=basehashes+1 - base=basehashes - basehash[hash]=base - end - properties.basehash=base - properties.fullname=(properties.fullname or properties.name).."-"..base - applied={} + local properties=tfmdata.properties + local hash=concat(applied," ") + local base=basehash[hash] + if not base then + basehashes=basehashes+1 + base=basehashes + basehash[hash]=base + end + properties.basehash=base + properties.fullname=(properties.fullname or properties.name).."-"..base + applied={} end local function registerbasefeature(feature,value) - applied[#applied+1]=feature.."="..tostring(value) + applied[#applied+1]=feature.."="..tostring(value) end local function makefake(tfmdata,name,present) - local private=getprivate(tfmdata) - local character={ intermediate=true,ligatures={} } - resources.unicodes[name]=private - tfmdata.characters[private]=character - tfmdata.descriptions[private]={ name=name } - present[name]=private - return character + local private=getprivate(tfmdata) + local character={ intermediate=true,ligatures={} } + resources.unicodes[name]=private + tfmdata.characters[private]=character + tfmdata.descriptions[private]={ name=name } + present[name]=private + return character end local function make_1(present,tree,name) - for k,v in next,tree do - if k=="ligature" then - present[name]=v - else - make_1(present,v,name.."_"..k) - end + for k,v in next,tree do + if k=="ligature" then + present[name]=v + else + make_1(present,v,name.."_"..k) end + end end local function make_2(present,tfmdata,characters,tree,name,preceding,unicode,done) - for k,v in next,tree do - if k=="ligature" then - local character=characters[preceding] - if not character then - if trace_baseinit then - report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding) - end - character=makefake(tfmdata,name,present) - end - local ligatures=character.ligatures - if ligatures then - ligatures[unicode]={ char=v } - else - character.ligatures={ [unicode]={ char=v } } - end - if done then - local d=done[name] - if not d then - done[name]={ "dummy",v } - else - d[#d+1]=v - end - end + for k,v in next,tree do + if k=="ligature" then + local character=characters[preceding] + if not character then + if trace_baseinit then + report_prepare("weird ligature in lookup %a, current %C, preceding %C",sequence.name,v,preceding) + end + character=makefake(tfmdata,name,present) + end + local ligatures=character.ligatures + if ligatures then + ligatures[unicode]={ char=v } + else + character.ligatures={ [unicode]={ char=v } } + end + if done then + local d=done[name] + if not d then + done[name]={ "dummy",v } else - local code=present[name] or unicode - local name=name.."_"..k - make_2(present,tfmdata,characters,v,name,code,k,done) + d[#d+1]=v end + end + else + local code=present[name] or unicode + local name=name.."_"..k + make_2(present,tfmdata,characters,v,name,code,k,done) end + end end local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local resources=tfmdata.resources - local changed=tfmdata.changed - local ligatures={} - local alternate=tonumber(value) or true and 1 - local defaultalt=otf.defaultbasealternate - local trace_singles=trace_baseinit and trace_singles - local trace_alternatives=trace_baseinit and trace_alternatives - local trace_ligatures=trace_baseinit and trace_ligatures - if not changed then - changed={} - tfmdata.changed=changed - end - for i=1,#lookuplist do - local sequence=lookuplist[i] - local steps=sequence.steps - local kind=sequence.type - if kind=="gsub_single" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - if unicode~=data then - changed[unicode]=data - end - if trace_singles then - report_substitution(feature,sequence,descriptions,unicode,data) - end - end + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local resources=tfmdata.resources + local changed=tfmdata.changed + local ligatures={} + local alternate=tonumber(value) or true and 1 + local defaultalt=otf.defaultbasealternate + local trace_singles=trace_baseinit and trace_singles + local trace_alternatives=trace_baseinit and trace_alternatives + local trace_ligatures=trace_baseinit and trace_ligatures + if not changed then + changed={} + tfmdata.changed=changed + end + for i=1,#lookuplist do + local sequence=lookuplist[i] + local steps=sequence.steps + local kind=sequence.type + if kind=="gsub_single" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + if unicode~=data then + changed[unicode]=data + end + if trace_singles then + report_substitution(feature,sequence,descriptions,unicode,data) + end + end + end + elseif kind=="gsub_alternate" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + local replacement=data[alternate] + if replacement then + if unicode~=replacement then + changed[unicode]=replacement end - elseif kind=="gsub_alternate" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - local replacement=data[alternate] - if replacement then - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal") - end - elseif defaultalt=="first" then - replacement=data[1] - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) - end - elseif defaultalt=="last" then - replacement=data[#data] - if unicode~=replacement then - changed[unicode]=replacement - end - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) - end - else - if trace_alternatives then - report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown") - end - end - end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal") end - elseif kind=="gsub_ligature" then - for i=1,#steps do - for unicode,data in next,steps[i].coverage do - ligatures[#ligatures+1]={ unicode,data,"" } - if trace_ligatures then - report_ligature(feature,sequence,descriptions,unicode,data) - end - end + elseif defaultalt=="first" then + replacement=data[1] + if unicode~=replacement then + changed[unicode]=replacement end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) + end + elseif defaultalt=="last" then + replacement=data[#data] + if unicode~=replacement then + changed[unicode]=replacement + end + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt) + end + else + if trace_alternatives then + report_alternate(feature,sequence,descriptions,unicode,replacement,value,"unknown") + end + end end - end - local nofligatures=#ligatures - if nofligatures>0 then - local characters=tfmdata.characters - local present={} - local done=trace_baseinit and trace_ligatures and {} - for i=1,nofligatures do - local ligature=ligatures[i] - local unicode,tree=ligature[1],ligature[2] - make_1(present,tree,"ctx_"..unicode) - end - for i=1,nofligatures do - local ligature=ligatures[i] - local unicode,tree,lookupname=ligature[1],ligature[2],ligature[3] - make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) + end + elseif kind=="gsub_ligature" then + for i=1,#steps do + for unicode,data in next,steps[i].coverage do + ligatures[#ligatures+1]={ unicode,data,"" } + if trace_ligatures then + report_ligature(feature,sequence,descriptions,unicode,data) + end end + end end + end + local nofligatures=#ligatures + if nofligatures>0 then + local characters=tfmdata.characters + local present={} + local done=trace_baseinit and trace_ligatures and {} + for i=1,nofligatures do + local ligature=ligatures[i] + local unicode=ligature[1] + local tree=ligature[2] + make_1(present,tree,"ctx_"..unicode) + end + for i=1,nofligatures do + local ligature=ligatures[i] + local unicode=ligature[1] + local tree=ligature[2] + local lookupname=ligature[3] + make_2(present,tfmdata,characters,tree,"ctx_"..unicode,unicode,unicode,done,sequence) + end + end end local function preparepositionings(tfmdata,feature,value,validlookups,lookuplist) - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local resources=tfmdata.resources - local properties=tfmdata.properties - local traceindeed=trace_baseinit and trace_kerns - for i=1,#lookuplist do - local sequence=lookuplist[i] - local steps=sequence.steps - local kind=sequence.type - local format=sequence.format - if kind=="gpos_pair" then - for i=1,#steps do - local step=steps[i] - local format=step.format - if format=="kern" or format=="move" then - for unicode,data in next,steps[i].coverage do - local character=characters[unicode] - local kerns=character.kerns - if not kerns then - kerns={} - character.kerns=kerns - end - if traceindeed then - for otherunicode,kern in next,data do - if not kerns[otherunicode] and kern~=0 then - kerns[otherunicode]=kern - report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) - end - end - else - for otherunicode,kern in next,data do - if not kerns[otherunicode] and kern~=0 then - kerns[otherunicode]=kern - end - end - end - end + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local resources=tfmdata.resources + local properties=tfmdata.properties + local traceindeed=trace_baseinit and trace_kerns + for i=1,#lookuplist do + local sequence=lookuplist[i] + local steps=sequence.steps + local kind=sequence.type + local format=sequence.format + if kind=="gpos_pair" then + for i=1,#steps do + local step=steps[i] + local format=step.format + if format=="kern" or format=="move" then + for unicode,data in next,steps[i].coverage do + local character=characters[unicode] + local kerns=character.kerns + if not kerns then + kerns={} + character.kerns=kerns + end + if traceindeed then + for otherunicode,kern in next,data do + if not kerns[otherunicode] and kern~=0 then + kerns[otherunicode]=kern + report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) + end + end + else + for otherunicode,kern in next,data do + if not kerns[otherunicode] and kern~=0 then + kerns[otherunicode]=kern + end + end + end + end + else + for unicode,data in next,steps[i].coverage do + local character=characters[unicode] + local kerns=character.kerns + for otherunicode,kern in next,data do + local other=kern[2] + if other==true or (not other and not (kerns and kerns[otherunicode])) then + local kern=kern[1] + if kern==true then + elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then else - for unicode,data in next,steps[i].coverage do - local character=characters[unicode] - local kerns=character.kerns - for otherunicode,kern in next,data do - local other=kern[2] - if other==true or (not other and not (kerns and kerns[otherunicode])) then - local kern=kern[1] - if kern==true then - elseif kern[1]~=0 or kern[2]~=0 or kern[4]~=0 then - else - kern=kern[3] - if kern~=0 then - if kerns then - kerns[otherunicode]=kern - else - kerns={ [otherunicode]=kern } - character.kerns=kerns - end - if traceindeed then - report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) - end - end - end - end - end + kern=kern[3] + if kern~=0 then + if kerns then + kerns[otherunicode]=kern + else + kerns={ [otherunicode]=kern } + character.kerns=kerns end + if traceindeed then + report_kern(feature,sequence,descriptions,unicode,otherunicode,kern) + end + end end + end end + end end + end end + end end local function initializehashes(tfmdata) end local function checkmathreplacements(tfmdata,fullname,fixitalics) - if tfmdata.mathparameters then - local characters=tfmdata.characters - local changed=tfmdata.changed - if next(changed) then - if trace_preparing or trace_baseinit then - report_prepare("checking math replacements for %a",fullname) - end - for unicode,replacement in next,changed do - local u=characters[unicode] - local r=characters[replacement] - local n=u.next - local v=u.vert_variants - local h=u.horiz_variants - if fixitalics then - local ui=u.italic - if ui and not r.italic then - if trace_preparing then - report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) - end - r.italic=ui - end - end - if n and not r.next then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) - end - r.next=n - end - if v and not r.vert_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) - end - r.vert_variants=v - end - if h and not r.horiz_variants then - if trace_preparing then - report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) - end - r.horiz_variants=h - end + if tfmdata.mathparameters then + local characters=tfmdata.characters + local changed=tfmdata.changed + if next(changed) then + if trace_preparing or trace_baseinit then + report_prepare("checking math replacements for %a",fullname) + end + for unicode,replacement in next,changed do + local u=characters[unicode] + local r=characters[replacement] + if u and r then + local n=u.next + local v=u.vert_variants + local h=u.horiz_variants + if fixitalics then + local ui=u.italic + if ui and not r.italic then + if trace_preparing then + report_prepare("using %i units of italic correction from %C for %U",ui,unicode,replacement) + end + r.italic=ui + end + end + if n and not r.next then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","incremental step",unicode,replacement) end + r.next=n + end + if v and not r.vert_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","vertical variants",unicode,replacement) + end + r.vert_variants=v + end + if h and not r.horiz_variants then + if trace_preparing then + report_prepare("forcing %s for %C substituted by %U","horizontal variants",unicode,replacement) + end + r.horiz_variants=h + end + else + if trace_preparing then + report_prepare("error replacing %C by %U",unicode,replacement) + end end + end end + end end local function featuresinitializer(tfmdata,value) - if true then - local starttime=trace_preparing and os.clock() - local features=tfmdata.shared.features - local fullname=tfmdata.properties.fullname or "?" - if features then - initializehashes(tfmdata) - local collectlookups=otf.collectlookups - local rawdata=tfmdata.shared.rawdata - local properties=tfmdata.properties - local script=properties.script - local language=properties.language - local rawresources=rawdata.resources - local rawfeatures=rawresources and rawresources.features - local basesubstitutions=rawfeatures and rawfeatures.gsub - local basepositionings=rawfeatures and rawfeatures.gpos - local substitutionsdone=false - local positioningsdone=false - if basesubstitutions or basepositionings then - local sequences=tfmdata.resources.sequences - for s=1,#sequences do - local sequence=sequences[s] - local sfeatures=sequence.features - if sfeatures then - local order=sequence.order - if order then - for i=1,#order do - local feature=order[i] - local value=features[feature] - if value then - local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) - if not validlookups then - elseif basesubstitutions and basesubstitutions[feature] then - if trace_preparing then - report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value) - end - preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - substitutionsdone=true - elseif basepositionings and basepositionings[feature] then - if trace_preparing then - report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value) - end - preparepositionings(tfmdata,feature,value,validlookups,lookuplist) - registerbasefeature(feature,value) - positioningsdone=true - end - end - end - end + if true then + local starttime=trace_preparing and os.clock() + local features=tfmdata.shared.features + local fullname=tfmdata.properties.fullname or "?" + if features then + initializehashes(tfmdata) + local collectlookups=otf.collectlookups + local rawdata=tfmdata.shared.rawdata + local properties=tfmdata.properties + local script=properties.script + local language=properties.language + local rawresources=rawdata.resources + local rawfeatures=rawresources and rawresources.features + local basesubstitutions=rawfeatures and rawfeatures.gsub + local basepositionings=rawfeatures and rawfeatures.gpos + local substitutionsdone=false + local positioningsdone=false + if basesubstitutions or basepositionings then + local sequences=tfmdata.resources.sequences + for s=1,#sequences do + local sequence=sequences[s] + local sfeatures=sequence.features + if sfeatures then + local order=sequence.order + if order then + for i=1,#order do + local feature=order[i] + local value=features[feature] + if value then + local validlookups,lookuplist=collectlookups(rawdata,feature,script,language) + if not validlookups then + elseif basesubstitutions and basesubstitutions[feature] then + if trace_preparing then + report_prepare("filtering base %s feature %a for %a with value %a","sub",feature,fullname,value) + end + preparesubstitutions(tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + substitutionsdone=true + elseif basepositionings and basepositionings[feature] then + if trace_preparing then + report_prepare("filtering base %a feature %a for %a with value %a","pos",feature,fullname,value) end + preparepositionings(tfmdata,feature,value,validlookups,lookuplist) + registerbasefeature(feature,value) + positioningsdone=true + end end + end end - if substitutionsdone then - checkmathreplacements(tfmdata,fullname,features.fixitalics) - end - registerbasehash(tfmdata) - end - if trace_preparing then - report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) + end end + end + if substitutionsdone then + checkmathreplacements(tfmdata,fullname,features.fixitalics) + end + registerbasehash(tfmdata) + end + if trace_preparing then + report_prepare("preparation time is %0.3f seconds for %a",os.clock()-starttime,fullname) end + end end registerotffeature { - name="features", - description="features", - default=true, - initializers={ - base=featuresinitializer, - } + name="features", + description="features", + default=true, + initializers={ + base=featuresinitializer, + } } otf.basemodeinitializer=featuresinitializer @@ -22297,21 +23655,21 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-otj']={ - version=1.001, - comment="companion to font-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", + version=1.001, + comment="companion to font-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", } if not nodes.properties then return end local next,rawget,tonumber=next,rawget,tonumber local fastcopy=table.fastcopy local registertracker=trackers.register local registerdirective=directives.register -local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) -local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) -local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) -local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) +local trace_injections=false registertracker("fonts.injections",function(v) trace_injections=v end) +local trace_marks=false registertracker("fonts.injections.marks",function(v) trace_marks=v end) +local trace_cursive=false registertracker("fonts.injections.cursive",function(v) trace_cursive=v end) +local trace_spaces=false registertracker("fonts.injections.spaces",function(v) trace_spaces=v end) local report_injections=logs.reporter("fonts","injections") local report_spaces=logs.reporter("fonts","spaces") local attributes,nodes,node=attributes,nodes,node @@ -22350,37 +23708,39 @@ local setkern=nuts.setkern local setlink=nuts.setlink local setwidth=nuts.setwidth local getwidth=nuts.getwidth -local traverse_id=nuts.traverse_id -local traverse_char=nuts.traverse_char +local nextchar=nuts.traversers.char +local nextglue=nuts.traversers.glue local insert_node_before=nuts.insert_before local insert_node_after=nuts.insert_after local properties=nodes.properties.data -local fontkern=nuts.pool and nuts.pool.fontkern +local fontkern=nuts.pool and nuts.pool.fontkern local italickern=nuts.pool and nuts.pool.italickern local useitalickerns=false directives.register("fonts.injections.useitalics",function(v) - if v then - report_injections("using italics for space kerns (tracing only)") - end - useitalickerns=v + if v then + report_injections("using italics for space kerns (tracing only)") + end + useitalickerns=v end) do if not fontkern then - local thekern=nuts.new("kern",0) - local setkern=nuts.setkern - local copy_node=nuts.copy_node - fontkern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end - local thekern=nuts.new("kern",3) - local setkern=nuts.setkern - local copy_node=nuts.copy_node - italickern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end + local thekern=nuts.new("kern",0) + local setkern=nuts.setkern + local copy_node=nuts.copy_node + fontkern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end +end end +do if not italickern then + local thekern=nuts.new("kern",3) + local setkern=nuts.setkern + local copy_node=nuts.copy_node + italickern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end end end function injections.installnewkern() end local nofregisteredkerns=0 @@ -22389,1372 +23749,1357 @@ local nofregisteredmarks=0 local nofregisteredcursives=0 local keepregisteredcounts=false function injections.keepcounts() - keepregisteredcounts=true + keepregisteredcounts=true end function injections.resetcounts() - nofregisteredkerns=0 - nofregisteredpositions=0 - nofregisteredmarks=0 - nofregisteredcursives=0 - keepregisteredcounts=false + nofregisteredkerns=0 + nofregisteredpositions=0 + nofregisteredmarks=0 + nofregisteredcursives=0 + keepregisteredcounts=false end function injections.reset(n) - local p=rawget(properties,n) - if p then - p.injections=false - else - properties[n]=false - end + local p=rawget(properties,n) + if p then + p.injections=false + else + properties[n]=false + end end function injections.copy(target,source) - local sp=rawget(properties,source) - if sp then - local tp=rawget(properties,target) - local si=sp.injections - if si then - si=fastcopy(si) - if tp then - tp.injections=si - else - properties[target]={ - injections=si, - } - end - elseif tp then - tp.injections=false - else - properties[target]={ injections={} } - end + local sp=rawget(properties,source) + if sp then + local tp=rawget(properties,target) + local si=sp.injections + if si then + si=fastcopy(si) + if tp then + tp.injections=si + else + properties[target]={ + injections=si, + } + end + elseif tp then + tp.injections=false else - local tp=rawget(properties,target) - if tp then - tp.injections=false - else - properties[target]=false - end + properties[target]={ injections={} } + end + else + local tp=rawget(properties,target) + if tp then + tp.injections=false + else + properties[target]=false end + end end function injections.setligaindex(n,index) - local p=rawget(properties,n) - if p then - local i=p.injections - if i then - i.ligaindex=index - else - p.injections={ - ligaindex=index - } - end + local p=rawget(properties,n) + if p then + local i=p.injections + if i then + i.ligaindex=index else - properties[n]={ - injections={ - ligaindex=index - } - } - end + p.injections={ + ligaindex=index + } + end + else + properties[n]={ + injections={ + ligaindex=index + } + } + end end function injections.getligaindex(n,default) - local p=rawget(properties,n) - if p then - local i=p.injections - if i then - return i.ligaindex or default - end + local p=rawget(properties,n) + if p then + local i=p.injections + if i then + return i.ligaindex or default end - return default + end + return default end function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmnext,r2lflag) - local dx=factor*(exit[1]-entry[1]) - local dy=-factor*(exit[2]-entry[2]) - local ws=tfmstart.width - local wn=tfmnext.width - nofregisteredcursives=nofregisteredcursives+1 - if rlmode<0 then - dx=-(dx+wn) + local dx=factor*(exit[1]-entry[1]) + local dy=-factor*(exit[2]-entry[2]) + local ws=tfmstart.width + local wn=tfmnext.width + nofregisteredcursives=nofregisteredcursives+1 + if rlmode<0 then + dx=-(dx+wn) + else + dx=dx-ws + end + if dx==0 then + dx=0 + end + local p=rawget(properties,start) + if p then + local i=p.injections + if i then + i.cursiveanchor=true else - dx=dx-ws - end - if dx==0 then - dx=0 - end - local p=rawget(properties,start) - if p then - local i=p.injections + p.injections={ + cursiveanchor=true, + } + end + else + properties[start]={ + injections={ + cursiveanchor=true, + }, + } + end + local p=rawget(properties,nxt) + if p then + local i=p.injections + if i then + i.cursivex=dx + i.cursivey=dy + else + p.injections={ + cursivex=dx, + cursivey=dy, + } + end + else + properties[nxt]={ + injections={ + cursivex=dx, + cursivey=dy, + }, + } + end + return dx,dy,nofregisteredcursives +end +function injections.setposition(kind,current,factor,rlmode,spec,injection) + local x=factor*(spec[1] or 0) + local y=factor*(spec[2] or 0) + local w=factor*(spec[3] or 0) + local h=factor*(spec[4] or 0) + if x~=0 or w~=0 or y~=0 or h~=0 then + local yoffset=y-h + local leftkern=x + local rightkern=w-x + if leftkern~=0 or rightkern~=0 or yoffset~=0 then + nofregisteredpositions=nofregisteredpositions+1 + if rlmode and rlmode<0 then + leftkern,rightkern=rightkern,leftkern + end + if not injection then + injection="injections" + end + local p=rawget(properties,current) + if p then + local i=p[injection] if i then - i.cursiveanchor=true + if leftkern~=0 then + i.leftkern=(i.leftkern or 0)+leftkern + end + if rightkern~=0 then + i.rightkern=(i.rightkern or 0)+rightkern + end + if yoffset~=0 then + i.yoffset=(i.yoffset or 0)+yoffset + end + elseif leftkern~=0 or rightkern~=0 then + p[injection]={ + leftkern=leftkern, + rightkern=rightkern, + yoffset=yoffset, + } else - p.injections={ - cursiveanchor=true, - } - end - else - properties[start]={ - injections={ - cursiveanchor=true, - }, + p[injection]={ + yoffset=yoffset, + } + end + elseif leftkern~=0 or rightkern~=0 then + properties[current]={ + [injection]={ + leftkern=leftkern, + rightkern=rightkern, + yoffset=yoffset, + }, } + else + properties[current]={ + [injection]={ + yoffset=yoffset, + }, + } + end + return x,y,w,h,nofregisteredpositions + end + end + return x,y,w,h +end +function injections.setkern(current,factor,rlmode,x,injection) + local dx=factor*x + if dx~=0 then + nofregisteredkerns=nofregisteredkerns+1 + local p=rawget(properties,current) + if not injection then + injection="injections" end - local p=rawget(properties,nxt) if p then - local i=p.injections - if i then - i.cursivex=dx - i.cursivey=dy - else - p.injections={ - cursivex=dx, - cursivey=dy, - } - end - else - properties[nxt]={ - injections={ - cursivex=dx, - cursivey=dy, - }, + local i=p[injection] + if i then + i.leftkern=dx+(i.leftkern or 0) + else + p[injection]={ + leftkern=dx, } + end + else + properties[current]={ + [injection]={ + leftkern=dx, + }, + } end - return dx,dy,nofregisteredcursives -end -function injections.setposition(kind,current,factor,rlmode,spec,injection) - local x=factor*spec[1] - local y=factor*spec[2] - local w=factor*spec[3] - local h=factor*spec[4] - if x~=0 or w~=0 or y~=0 or h~=0 then - local yoffset=y-h - local leftkern=x - local rightkern=w-x - if leftkern~=0 or rightkern~=0 or yoffset~=0 then - nofregisteredpositions=nofregisteredpositions+1 - if rlmode and rlmode<0 then - leftkern,rightkern=rightkern,leftkern - end - if not injection then - injection="injections" - end - local p=rawget(properties,current) - if p then - local i=p[injection] - if i then - if leftkern~=0 then - i.leftkern=(i.leftkern or 0)+leftkern - end - if rightkern~=0 then - i.rightkern=(i.rightkern or 0)+rightkern - end - if yoffset~=0 then - i.yoffset=(i.yoffset or 0)+yoffset - end - elseif leftkern~=0 or rightkern~=0 then - p[injection]={ - leftkern=leftkern, - rightkern=rightkern, - yoffset=yoffset, - } - else - p[injection]={ - yoffset=yoffset, - } - end - elseif leftkern~=0 or rightkern~=0 then - properties[current]={ - [injection]={ - leftkern=leftkern, - rightkern=rightkern, - yoffset=yoffset, - }, - } - else - properties[current]={ - [injection]={ - yoffset=yoffset, - }, - } - end - return x,y,w,h,nofregisteredpositions - end - end - return x,y,w,h -end -function injections.setkern(current,factor,rlmode,x,injection) - local dx=factor*x - if dx~=0 then - nofregisteredkerns=nofregisteredkerns+1 - local p=rawget(properties,current) - if not injection then - injection="injections" - end - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) - else - p[injection]={ - leftkern=dx, - } - end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } - end - return dx,nofregisteredkerns - else - return 0,0 - end + return dx,nofregisteredkerns + else + return 0,0 + end end function injections.setmove(current,factor,rlmode,x,injection) - local dx=factor*x - if dx~=0 then - nofregisteredkerns=nofregisteredkerns+1 - local p=rawget(properties,current) - if not injection then - injection="injections" - end - if rlmode and rlmode<0 then - if p then - local i=p[injection] - if i then - i.rightkern=dx+(i.rightkern or 0) - else - p[injection]={ - rightkern=dx, - } - end - else - properties[current]={ - [injection]={ - rightkern=dx, - }, - } - end + local dx=factor*x + if dx~=0 then + nofregisteredkerns=nofregisteredkerns+1 + local p=rawget(properties,current) + if not injection then + injection="injections" + end + if rlmode and rlmode<0 then + if p then + local i=p[injection] + if i then + i.rightkern=dx+(i.rightkern or 0) else - if p then - local i=p[injection] - if i then - i.leftkern=dx+(i.leftkern or 0) - else - p[injection]={ - leftkern=dx, - } - end - else - properties[current]={ - [injection]={ - leftkern=dx, - }, - } - end - end - return dx,nofregisteredkerns + p[injection]={ + rightkern=dx, + } + end + else + properties[current]={ + [injection]={ + rightkern=dx, + }, + } + end else - return 0,0 - end -end -function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) - local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) - nofregisteredmarks=nofregisteredmarks+1 - if rlmode>=0 then - dx=tfmbase.width-dx - end - local p=rawget(properties,start) - if p then - local i=p.injections + if p then + local i=p[injection] if i then - if i.markmark then - else - if dx~=0 then - i.markx=dx - end - if y~=0 then - i.marky=dy - end - if rlmode then - i.markdir=rlmode - end - i.markbase=nofregisteredmarks - i.markbasenode=base - i.markmark=mkmk - i.checkmark=checkmark - end + i.leftkern=dx+(i.leftkern or 0) else - p.injections={ - markx=dx, - marky=dy, - markdir=rlmode or 0, - markbase=nofregisteredmarks, - markbasenode=base, - markmark=mkmk, - checkmark=checkmark, - } - end - else - properties[start]={ - injections={ - markx=dx, - marky=dy, - markdir=rlmode or 0, - markbase=nofregisteredmarks, - markbasenode=base, - markmark=mkmk, - checkmark=checkmark, - }, + p[injection]={ + leftkern=dx, + } + end + else + properties[current]={ + [injection]={ + leftkern=dx, + }, } + end end - return dx,dy,nofregisteredmarks + return dx,nofregisteredkerns + else + return 0,0 + end +end +function injections.setmark(start,base,factor,rlmode,ba,ma,tfmbase,mkmk,checkmark) + local dx=factor*(ba[1]-ma[1]) + local dy=factor*(ba[2]-ma[2]) + nofregisteredmarks=nofregisteredmarks+1 + if rlmode>=0 then + dx=tfmbase.width-dx + end + local p=rawget(properties,start) + if p then + local i=p.injections + if i then + if i.markmark then + else + i.markx=dx + i.marky=dy + i.markdir=rlmode or 0 + i.markbase=nofregisteredmarks + i.markbasenode=base + i.markmark=mkmk + i.checkmark=checkmark + end + else + p.injections={ + markx=dx, + marky=dy, + markdir=rlmode or 0, + markbase=nofregisteredmarks, + markbasenode=base, + markmark=mkmk, + checkmark=checkmark, + } + end + else + properties[start]={ + injections={ + markx=dx, + marky=dy, + markdir=rlmode or 0, + markbase=nofregisteredmarks, + markbasenode=base, + markmark=mkmk, + checkmark=checkmark, + }, + } + end + return dx,dy,nofregisteredmarks end local function dir(n) - return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" + return (n and n<0 and "r-to-l") or (n and n>0 and "l-to-r") or "unset" end local function showchar(n,nested) - local char=getchar(n) - report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char) + local char=getchar(n) + report_injections("%wfont %s, char %U, glyph %c",nested and 2 or 0,getfont(n),char,char) end local function show(n,what,nested,symbol) - if n then - local p=rawget(properties,n) - if p then - local i=p[what] - if i then - local leftkern=i.leftkern or 0 - local rightkern=i.rightkern or 0 - local yoffset=i.yoffset or 0 - local markx=i.markx or 0 - local marky=i.marky or 0 - local markdir=i.markdir or 0 - local markbase=i.markbase or 0 - local cursivex=i.cursivex or 0 - local cursivey=i.cursivey or 0 - local ligaindex=i.ligaindex or 0 - local cursbase=i.cursiveanchor - local margin=nested and 4 or 2 - if rightkern~=0 or yoffset~=0 then - report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) - elseif leftkern~=0 then - report_injections("%w%s kern: dx %p",margin,symbol,leftkern) - end - if markx~=0 or marky~=0 or markbase~=0 then - report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no") - end - if cursivex~=0 or cursivey~=0 then - if cursbase then - report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey) - else - report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey) - end - elseif cursbase then - report_injections("%w%s curs: base",margin,symbol) - end - if ligaindex~=0 then - report_injections("%w%s liga: index %i",margin,symbol,ligaindex) - end - end + if n then + local p=rawget(properties,n) + if p then + local i=p[what] + if i then + local leftkern=i.leftkern or 0 + local rightkern=i.rightkern or 0 + local yoffset=i.yoffset or 0 + local markx=i.markx or 0 + local marky=i.marky or 0 + local markdir=i.markdir or 0 + local markbase=i.markbase or 0 + local cursivex=i.cursivex or 0 + local cursivey=i.cursivey or 0 + local ligaindex=i.ligaindex or 0 + local cursbase=i.cursiveanchor + local margin=nested and 4 or 2 + if rightkern~=0 or yoffset~=0 then + report_injections("%w%s pair: lx %p, rx %p, dy %p",margin,symbol,leftkern,rightkern,yoffset) + elseif leftkern~=0 then + report_injections("%w%s kern: dx %p",margin,symbol,leftkern) + end + if markx~=0 or marky~=0 or markbase~=0 then + report_injections("%w%s mark: dx %p, dy %p, dir %s, base %s",margin,symbol,markx,marky,markdir,markbase~=0 and "yes" or "no") + end + if cursivex~=0 or cursivey~=0 then + if cursbase then + report_injections("%w%s curs: base dx %p, dy %p",margin,symbol,cursivex,cursivey) + else + report_injections("%w%s curs: dx %p, dy %p",margin,symbol,cursivex,cursivey) + end + elseif cursbase then + report_injections("%w%s curs: base",margin,symbol) end + if ligaindex~=0 then + report_injections("%w%s liga: index %i",margin,symbol,ligaindex) + end + end end + end end local function showsub(n,what,where) - report_injections("begin subrun: %s",where) - for n in traverse_char(n) do - showchar(n,where) - show(n,what,where," ") - end - report_injections("end subrun") + report_injections("begin subrun: %s",where) + for n in nextchar,n do + showchar(n,where) + show(n,what,where," ") + end + report_injections("end subrun") end local function trace(head,where) - report_injections() - report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered", - where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives) - local n=head - while n do - local id=getid(n) - if id==glyph_code then - showchar(n) - show(n,"injections",false," ") - show(n,"preinjections",false,"<") - show(n,"postinjections",false,">") - show(n,"replaceinjections",false,"=") - show(n,"emptyinjections",false,"*") - elseif id==disc_code then - local pre,post,replace=getdisc(n) - if pre then - showsub(pre,"preinjections","pre") - end - if post then - showsub(post,"postinjections","post") - end - if replace then - showsub(replace,"replaceinjections","replace") - end - show(n,"emptyinjections",false,"*") - end - n=getnext(n) - end - report_injections("end run") + report_injections() + report_injections("begin run %s: %s kerns, %s positions, %s marks and %s cursives registered", + where or "",nofregisteredkerns,nofregisteredpositions,nofregisteredmarks,nofregisteredcursives) + local n=head + while n do + local id=getid(n) + if id==glyph_code then + showchar(n) + show(n,"injections",false," ") + show(n,"preinjections",false,"<") + show(n,"postinjections",false,">") + show(n,"replaceinjections",false,"=") + show(n,"emptyinjections",false,"*") + elseif id==disc_code then + local pre,post,replace=getdisc(n) + if pre then + showsub(pre,"preinjections","pre") + end + if post then + showsub(post,"postinjections","post") + end + if replace then + showsub(replace,"replaceinjections","replace") + end + show(n,"emptyinjections",false,"*") + end + n=getnext(n) + end + report_injections("end run") end local function show_result(head) - local current=head - local skipping=false - while current do - local id=getid(current) - if id==glyph_code then - local w=getwidth(current) - local x,y=getoffsets(current) - report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) - skipping=false - elseif id==kern_code then - report_injections("kern: %p",getkern(current)) - skipping=false - elseif not skipping then - report_injections() - skipping=true - end - current=getnext(current) - end - report_injections() + local current=head + local skipping=false + while current do + local id=getid(current) + if id==glyph_code then + local w=getwidth(current) + local x,y=getoffsets(current) + report_injections("char: %C, width %p, xoffset %p, yoffset %p",getchar(current),w,x,y) + skipping=false + elseif id==kern_code then + report_injections("kern: %p",getkern(current)) + skipping=false + elseif not skipping then + report_injections() + skipping=true + end + current=getnext(current) + end + report_injections() end local function inject_kerns_only(head,where) - head=tonut(head) - if trace_injections then - trace(head,"kerns") - end - local current=head - local prev=nil - local next=nil - local prevdisc=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setfield(prev,"replace",fontkern(leftkern)) - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end + if trace_injections then + trace(head,"kerns") + end + local current=head + local prev=nil + local next=nil + local prevdisc=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end end - prevdisc=nil - elseif char==false then - prevdisc=nil - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in traverse_char(pre) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - end - end - end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end end - if post then - for n in traverse_char(post) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - end - end - end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end end - if replace then - for n in traverse_char(replace) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - end - end - end + end + if done then + setdisc(prevdisc,pre,post,replace) + end + end + end + prevdisc=nil + elseif char==false then + prevdisc=nil + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end end - if done then - setdisc(current,pre,post,replace) + end + end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end end - prevdisc=current - else - prevdisc=nil + end end - prev=current - current=next - end - if keepregisteredcounts then - keepregisteredcounts=false + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevdisc=current else - nofregisteredkerns=0 - end - if trace_injections then - show_result(head) + prevdisc=nil end - return tonode(head),true + prev=current + current=next + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredkerns=0 + end + if trace_injections then + show_result(head) + end + return head end local function inject_positions_only(head,where) - head=tonut(head) - if trace_injections then - trace(head,"positions") - end - local current=head - local prev=nil - local next=nil - local prevdisc=nil - local prevglyph=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(current,false,yoffset) - end - local leftkern=i.leftkern - local rightkern=i.rightkern - if leftkern and leftkern~=0 then - if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if rightkern and rightkern~=0 then - insert_node_after(head,current,fontkern(rightkern)) - end - else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - setfield(next,"replace",fontkern(rightkern)) - end - end - end - end - end - if prevdisc then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setfield(prev,"replace",fontkern(leftkern)) - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - prevdisc=nil - prevglyph=current - elseif char==false then - prevdisc=nil - prevglyph=current - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in traverse_char(pre) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(pre,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if post then - for n in traverse_char(post) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(post,n,fontkern(rightkern)) - done=true - end - end - end - end - end - if replace then - for n in traverse_char(replace) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(replace,n,fontkern(rightkern)) - done=true - end - end - end - end + if trace_injections then + trace(head,"positions") + end + local current=head + local prev=nil + local next=nil + local prevdisc=nil + local prevglyph=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + local leftkern=i.leftkern + local rightkern=i.rightkern + if leftkern and leftkern~=0 then + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + else + head=insert_node_before(head,current,fontkern(leftkern)) end - if prevglyph then - if pre then - local p=rawget(properties,prevglyph) - if p then - local i=p.preinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - pre=insert_node_before(pre,pre,fontkern(rightkern)) - done=true - end - end - end - end + end + if rightkern and rightkern~=0 then + insert_node_after(head,current,fontkern(rightkern)) + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then if replace then - local p=rawget(properties,prevglyph) - if p then - local i=p.replaceinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - replace=insert_node_before(replace,replace,fontkern(rightkern)) - done=true - end - end - end + else + replace=fontkern(rightkern) + done=true end + end end - if done then - setdisc(current,pre,post,replace) - end - prevglyph=nil - prevdisc=current - else - prevglyph=nil - prevdisc=nil + end end - prev=current - current=next - end - if keepregisteredcounts then - keepregisteredcounts=false - else - nofregisteredpositions=0 - end - if trace_injections then - show_result(head) - end - return tonode(head),true -end -local function showoffset(n,flag) - local x,y=getoffsets(n) - if x~=0 or y~=0 then - setcolor(n,"darkgray") - end -end -local function inject_everything(head,where) - head=tonut(head) - if trace_injections then - trace(head,"everything") - end - local hascursives=nofregisteredcursives>0 - local hasmarks=nofregisteredmarks>0 - local current=head - local last=nil - local prev=nil - local next=nil - local prevdisc=nil - local prevglyph=nil - local pre=nil - local post=nil - local replace=nil - local pretail=nil - local posttail=nil - local replacetail=nil - local cursiveanchor=nil - local minc=0 - local maxc=0 - local glyphs={} - local marks={} - local nofmarks=0 - local function processmark(p,n,pn) - local px,py=getoffsets(p) - local nx,ny=getoffsets(n) - local ox=0 - local rightkern=nil - local pp=rawget(properties,p) - if pp then - pp=pp.injections - if pp then - rightkern=pp.rightkern - end - end - local markdir=pn.markdir - if rightkern then - ox=px-(pn.markx or 0)-rightkern - if markdir and markdir<0 then - if not pn.markmark then - ox=ox+(pn.leftkern or 0) - end - else - if false then - local leftkern=pp.leftkern - if leftkern then - ox=ox-leftkern - end - end + if prevdisc then + local done=false + if post then + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true + end end - else - ox=px-(pn.markx or 0) - if markdir and markdir<0 then - if not pn.markmark then - local leftkern=pn.leftkern - if leftkern then - ox=ox+leftkern - end - end + end + if replace then + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true + end end - if pn.checkmark then - local wn=getwidth(n) - if wn and wn~=0 then - wn=wn/2 - if trace_injections then - report_injections("correcting non zero width mark %C",getchar(n)) - end - insert_node_before(n,n,fontkern(-wn)) - insert_node_after(n,n,fontkern(-wn)) - end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true + end end + end + if done then + setdisc(prevdisc,pre,post,replace) + end end - local oy=ny+py+(pn.marky or 0) - if not pn.markmark then - local yoffset=pn.yoffset - if yoffset then - oy=oy+yoffset + end + prevdisc=nil + prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(pre,n,fontkern(rightkern)) + done=true + end end + end end - setoffsets(n,ox,oy) - if trace_marks then - showoffset(n,true) - end + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(post,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(replace,n,fontkern(rightkern)) + done=true + end + end + end + end + end + if prevglyph then + if pre then + local p=rawget(properties,prevglyph) + if p then + local i=p.preinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + pre=insert_node_before(pre,pre,fontkern(rightkern)) + done=true + end + end + end + end + if replace then + local p=rawget(properties,prevglyph) + if p then + local i=p.replaceinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + replace=insert_node_before(replace,replace,fontkern(rightkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevglyph=nil + prevdisc=current + else + prevglyph=nil + prevdisc=nil end - while current do - local next=getnext(current) - local char,id=ischar(current) - if char then - local p=rawget(properties,current) - if p then - local i=p.injections - if i then - local pm=i.markbasenode - if pm then - nofmarks=nofmarks+1 - marks[nofmarks]=current - else - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(current,false,yoffset) - end - if hascursives then - local cursivex=i.cursivex - if cursivex then - if cursiveanchor then - if cursivex~=0 then - i.leftkern=(i.leftkern or 0)+cursivex - end - if maxc==0 then - minc=1 - maxc=1 - glyphs[1]=cursiveanchor - else - maxc=maxc+1 - glyphs[maxc]=cursiveanchor - end - properties[cursiveanchor].cursivedy=i.cursivey - last=current - else - maxc=0 - end - elseif maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - cursiveanchor=nil - end - if i.cursiveanchor then - cursiveanchor=current - else - if maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) - end - end - maxc=0 - end - cursiveanchor=nil - end - end - local leftkern=i.leftkern - local rightkern=i.rightkern - if leftkern and leftkern~=0 then - if rightkern and leftkern==-rightkern then - setoffsets(current,leftkern,false) - rightkern=0 - else - head=insert_node_before(head,current,fontkern(leftkern)) - end - end - if rightkern and rightkern~=0 then - insert_node_after(head,current,fontkern(rightkern)) - end - end + prev=current + current=next + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredpositions=0 + end + if trace_injections then + show_result(head) + end + return head +end +local function showoffset(n,flag) + local x,y=getoffsets(n) + if x~=0 or y~=0 then + setcolor(n,"darkgray") + end +end +local function inject_everything(head,where) + if trace_injections then + trace(head,"everything") + end + local hascursives=nofregisteredcursives>0 + local hasmarks=nofregisteredmarks>0 + local current=head + local last=nil + local prev=nil + local next=nil + local prevdisc=nil + local prevglyph=nil + local pre=nil + local post=nil + local replace=nil + local pretail=nil + local posttail=nil + local replacetail=nil + local cursiveanchor=nil + local minc=0 + local maxc=0 + local glyphs={} + local marks={} + local nofmarks=0 + local function processmark(p,n,pn) + local px,py=getoffsets(p) + local nx,ny=getoffsets(n) + local ox=0 + local rightkern=nil + local pp=rawget(properties,p) + if pp then + pp=pp.injections + if pp then + rightkern=pp.rightkern + end + end + local markdir=pn.markdir + if rightkern then + ox=px-(pn.markx or 0)-rightkern + if markdir and markdir<0 then + if not pn.markmark then + ox=ox+(pn.leftkern or 0) + end + else + if false then + local leftkern=pp.leftkern + if leftkern then + ox=ox-leftkern + end + end + end + else + ox=px-(pn.markx or 0) + if markdir and markdir<0 then + if not pn.markmark then + local leftkern=pn.leftkern + if leftkern then + ox=ox+leftkern + end + end + end + if pn.checkmark then + local wn=getwidth(n) + if wn and wn~=0 then + wn=wn/2 + if trace_injections then + report_injections("correcting non zero width mark %C",getchar(n)) + end + insert_node_before(n,n,fontkern(-wn)) + insert_node_after(n,n,fontkern(-wn)) + end + end + end + local oy=ny+py+(pn.marky or 0) + if not pn.markmark then + local yoffset=pn.yoffset + if yoffset then + oy=oy+yoffset + end + end + setoffsets(n,ox,oy) + if trace_marks then + showoffset(n,true) + end + end + while current do + local next=getnext(current) + local char,id=ischar(current) + if char then + local p=rawget(properties,current) + if p then + local i=p.injections + if i then + local pm=i.markbasenode + if pm then + nofmarks=nofmarks+1 + marks[nofmarks]=current + else + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(current,false,yoffset) + end + if hascursives then + local cursivex=i.cursivex + if cursivex then + if cursiveanchor then + if cursivex~=0 then + i.leftkern=(i.leftkern or 0)+cursivex + end + if maxc==0 then + minc=1 + maxc=1 + glyphs[1]=cursiveanchor + else + maxc=maxc+1 + glyphs[maxc]=cursiveanchor + end + properties[cursiveanchor].cursivedy=i.cursivey + last=current else - local i=p.emptyinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - if next and getid(next)==disc_code then - if replace then - else - setfield(next,"replace",fontkern(rightkern)) - end - end - end - end - end - if prevdisc then - if p then - local done=false - if post then - local i=p.postinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(posttail,fontkern(leftkern)) - done=true - end - end - end - if replace then - local i=p.replaceinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setlink(replacetail,fontkern(leftkern)) - done=true - end - end - else - local i=p.emptyinjections - if i then - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - setfield(prev,"replace",fontkern(leftkern)) - end - end - end - if done then - setdisc(prevdisc,pre,post,replace) - end - end - end - else - if hascursives and maxc>0 then - local nx,ny=getoffsets(current) - for i=maxc,minc,-1 do - local ti=glyphs[i] - ny=ny+properties[ti].cursivedy - local xi,yi=getoffsets(ti) - setoffsets(ti,xi,yi+ny) - end - maxc=0 - cursiveanchor=nil - end + maxc=0 + end + elseif maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + cursiveanchor=nil + end + if i.cursiveanchor then + cursiveanchor=current + else + if maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + maxc=0 + end + cursiveanchor=nil + end end - prevdisc=nil - prevglyph=current - elseif char==false then - prevdisc=nil - prevglyph=current - elseif id==disc_code then - pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) - local done=false - if pre then - for n in traverse_char(pre) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.preinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - pre=insert_node_before(pre,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(pre,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end + local leftkern=i.leftkern + local rightkern=i.rightkern + if leftkern and leftkern~=0 then + if rightkern and leftkern==-rightkern then + setoffsets(current,leftkern,false) + rightkern=0 + else + head=insert_node_before(head,current,fontkern(leftkern)) + end + end + if rightkern and rightkern~=0 then + insert_node_after(head,current,fontkern(rightkern)) + end + end + else + local i=p.emptyinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + if next and getid(next)==disc_code then + if replace then + else + replace=fontkern(rightkern) + done=true end + end end + end + end + if prevdisc then + if p then + local done=false if post then - for n in traverse_char(post) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.postinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - post=insert_node_before(post,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(post,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end + local i=p.postinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(posttail,fontkern(leftkern)) + done=true end + end end if replace then - for n in traverse_char(replace) do - local p=rawget(properties,n) - if p then - local i=p.injections or p.replaceinjections - if i then - local yoffset=i.yoffset - if yoffset and yoffset~=0 then - setoffsets(n,false,yoffset) - end - local leftkern=i.leftkern - if leftkern and leftkern~=0 then - replace=insert_node_before(replace,n,fontkern(leftkern)) - done=true - end - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - insert_node_after(replace,n,fontkern(rightkern)) - done=true - end - if hasmarks then - local pm=i.markbasenode - if pm then - processmark(pm,n,i) - end - end - end - end - end - end - if prevglyph then - if pre then - local p=rawget(properties,prevglyph) - if p then - local i=p.preinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - pre=insert_node_before(pre,pre,fontkern(rightkern)) - done=true - end - end - end + local i=p.replaceinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + setlink(replacetail,fontkern(leftkern)) + done=true end - if replace then - local p=rawget(properties,prevglyph) - if p then - local i=p.replaceinjections - if i then - local rightkern=i.rightkern - if rightkern and rightkern~=0 then - replace=insert_node_before(replace,replace,fontkern(rightkern)) - done=true - end - end - end + end + else + local i=p.emptyinjections + if i then + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=fontkern(leftkern) + done=true end + end end if done then - setdisc(current,pre,post,replace) + setdisc(prevdisc,pre,post,replace) end - prevglyph=nil - prevdisc=current - else - prevglyph=nil - prevdisc=nil + end end - prev=current - current=next - end - if hascursives and maxc>0 then - local nx,ny=getoffsets(last) - for i=maxc,minc,-1 do + else + if hascursives and maxc>0 then + local nx,ny=getoffsets(current) + for i=maxc,minc,-1 do local ti=glyphs[i] ny=ny+properties[ti].cursivedy - setoffsets(ti,false,ny) - if trace_cursive then - showoffset(ti) + local xi,yi=getoffsets(ti) + setoffsets(ti,xi,yi+ny) + end + maxc=0 + cursiveanchor=nil + end + end + prevdisc=nil + prevglyph=current + elseif char==false then + prevdisc=nil + prevglyph=current + elseif id==disc_code then + pre,post,replace,pretail,posttail,replacetail=getdisc(current,true) + local done=false + if pre then + for n in nextchar,pre do + local p=rawget(properties,n) + if p then + local i=p.injections or p.preinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + pre=insert_node_before(pre,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(pre,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end end + end end - end - if nofmarks>0 then - for i=1,nofmarks do - local m=marks[i] - local p=rawget(properties,m) - local i=p.injections - local b=i.markbasenode - processmark(b,m,i) + end + if post then + for n in nextchar,post do + local p=rawget(properties,n) + if p then + local i=p.injections or p.postinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + post=insert_node_before(post,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(post,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end end - elseif hasmarks then - end - if keepregisteredcounts then - keepregisteredcounts=false + end + if replace then + for n in nextchar,replace do + local p=rawget(properties,n) + if p then + local i=p.injections or p.replaceinjections + if i then + local yoffset=i.yoffset + if yoffset and yoffset~=0 then + setoffsets(n,false,yoffset) + end + local leftkern=i.leftkern + if leftkern and leftkern~=0 then + replace=insert_node_before(replace,n,fontkern(leftkern)) + done=true + end + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + insert_node_after(replace,n,fontkern(rightkern)) + done=true + end + if hasmarks then + local pm=i.markbasenode + if pm then + processmark(pm,n,i) + end + end + end + end + end + end + if prevglyph then + if pre then + local p=rawget(properties,prevglyph) + if p then + local i=p.preinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + pre=insert_node_before(pre,pre,fontkern(rightkern)) + done=true + end + end + end + end + if replace then + local p=rawget(properties,prevglyph) + if p then + local i=p.replaceinjections + if i then + local rightkern=i.rightkern + if rightkern and rightkern~=0 then + replace=insert_node_before(replace,replace,fontkern(rightkern)) + done=true + end + end + end + end + end + if done then + setdisc(current,pre,post,replace) + end + prevglyph=nil + prevdisc=current else - nofregisteredkerns=0 - nofregisteredpositions=0 - nofregisteredmarks=0 - nofregisteredcursives=0 - end - if trace_injections then - show_result(head) - end - return tonode(head),true + prevglyph=nil + prevdisc=nil + end + prev=current + current=next + end + if hascursives and maxc>0 then + local nx,ny=getoffsets(last) + for i=maxc,minc,-1 do + local ti=glyphs[i] + ny=ny+properties[ti].cursivedy + setoffsets(ti,false,ny) + if trace_cursive then + showoffset(ti) + end + end + end + if nofmarks>0 then + for i=1,nofmarks do + local m=marks[i] + local p=rawget(properties,m) + local i=p.injections + local b=i.markbasenode + processmark(b,m,i) + end + elseif hasmarks then + end + if keepregisteredcounts then + keepregisteredcounts=false + else + nofregisteredkerns=0 + nofregisteredpositions=0 + nofregisteredmarks=0 + nofregisteredcursives=0 + end + if trace_injections then + show_result(head) + end + return head end local triggers=false function nodes.injections.setspacekerns(font,sequence) - if triggers then - triggers[font]=sequence - else - triggers={ [font]=sequence } - end + if triggers then + triggers[font]=sequence + else + triggers={ [font]=sequence } + end end local getthreshold if context then - local threshold=1 - local parameters=fonts.hashes.parameters - directives.register("otf.threshold",function(v) threshold=tonumber(v) or 1 end) - getthreshold=function(font) - local p=parameters[font] - local f=p.factor - local s=p.spacing - local t=threshold*(s and s.width or p.space or 0)-2 - return t>0 and t or 0,f - end + +--removed + else - injections.threshold=0 - getthreshold=function(font) - local p=fontdata[font].parameters - local f=p.factor - local s=p.spacing - local t=injections.threshold*(s and s.width or p.space or 0)-2 - return t>0 and t or 0,f - end + injections.threshold=0 + getthreshold=function(font) + local p=fontdata[font].parameters + local f=p.factor + local s=p.spacing + local t=injections.threshold*(s and s.width or p.space or 0)-2 + return t>0 and t or 0,f + end end injections.getthreshold=getthreshold function injections.isspace(n,threshold,id) - if (id or getid(n))==glue_code then - local w=getwidth(n) - if threshold and w>threshold then - return 32 - end + if (id or getid(n))==glue_code then + local w=getwidth(n) + if threshold and w>threshold then + return 32 end + end end local getspaceboth=getboth function injections.installgetspaceboth(gb) - getspaceboth=gb or getboth + getspaceboth=gb or getboth end local function injectspaces(head) - if not triggers then - return head,false - end - local lastfont=nil - local spacekerns=nil - local leftkerns=nil - local rightkerns=nil - local factor=0 - local threshold=0 - local leftkern=false - local rightkern=false - local nuthead=tonut(head) - local function updatefont(font,trig) - leftkerns=trig.left - rightkerns=trig.right - lastfont=font - threshold, - factor=getthreshold(font) - end - for n in traverse_id(glue_code,nuthead) do - local prev,next=getspaceboth(n) - local prevchar=prev and ischar(prev) - local nextchar=next and ischar(next) - if nextchar then - local font=getfont(next) - local trig=triggers[font] - if trig then - if lastfont~=font then - updatefont(font,trig) - end - if rightkerns then - rightkern=rightkerns[nextchar] - end - end - end - if prevchar then - local font=getfont(prev) - local trig=triggers[font] - if trig then - if lastfont~=font then - updatefont(font,trig) - end - if leftkerns then - leftkern=leftkerns[prevchar] - end + if not triggers then + return head + end + local lastfont=nil + local spacekerns=nil + local leftkerns=nil + local rightkerns=nil + local factor=0 + local threshold=0 + local leftkern=false + local rightkern=false + local function updatefont(font,trig) + leftkerns=trig.left + rightkerns=trig.right + lastfont=font + threshold, + factor=getthreshold(font) + end + for n in nextglue,head do + local prev,next=getspaceboth(n) + local prevchar=prev and ischar(prev) + local nextchar=next and ischar(next) + if nextchar then + local font=getfont(next) + local trig=triggers[font] + if trig then + if lastfont~=font then + updatefont(font,trig) + end + if rightkerns then + rightkern=rightkerns[nextchar] + end + end + end + if prevchar then + local font=getfont(prev) + local trig=triggers[font] + if trig then + if lastfont~=font then + updatefont(font,trig) + end + if leftkerns then + leftkern=leftkerns[prevchar] + end + end + end + if leftkern then + local old=getwidth(n) + if old>threshold then + if rightkern then + if useitalickerns then + local lnew=leftkern*factor + local rnew=rightkern*factor + if trace_spaces then + report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) + end + head=insert_node_before(head,n,italickern(lnew)) + insert_node_after(head,n,italickern(rnew)) + else + local new=old+(leftkern+rightkern)*factor + if trace_spaces then + report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) end - end - if leftkern then - local old=getwidth(n) - if old>threshold then - if rightkern then - if useitalickerns then - local lnew=leftkern*factor - local rnew=rightkern*factor - if trace_spaces then - report_spaces("%C [%p + %p + %p] %C",prevchar,lnew,old,rnew,nextchar) - end - local h=insert_node_before(nuthead,n,italickern(lnew)) - if h==nuthead then - head=tonode(h) - nuthead=h - end - insert_node_after(nuthead,n,italickern(rnew)) - else - local new=old+(leftkern+rightkern)*factor - if trace_spaces then - report_spaces("%C [%p -> %p] %C",prevchar,old,new,nextchar) - end - setwidth(n,new) - end - rightkern=false - else - if useitalickerns then - local new=leftkern*factor - if trace_spaces then - report_spaces("%C [%p + %p]",prevchar,old,new) - end - insert_node_after(nuthead,n,italickern(new)) - else - local new=old+leftkern*factor - if trace_spaces then - report_spaces("%C [%p -> %p]",prevchar,old,new) - end - setwidth(n,new) - end - end + setwidth(n,new) + end + rightkern=false + else + if useitalickerns then + local new=leftkern*factor + if trace_spaces then + report_spaces("%C [%p + %p]",prevchar,old,new) end - leftkern=false - elseif rightkern then - local old=getwidth(n) - if old>threshold then - if useitalickerns then - local new=rightkern*factor - if trace_spaces then - report_spaces("%C [%p + %p]",nextchar,old,new) - end - insert_node_after(nuthead,n,italickern(new)) - else - local new=old+rightkern*factor - if trace_spaces then - report_spaces("[%p -> %p] %C",nextchar,old,new) - end - setwidth(n,new) - end + insert_node_after(head,n,italickern(new)) + else + local new=old+leftkern*factor + if trace_spaces then + report_spaces("%C [%p -> %p]",prevchar,old,new) end - rightkern=false + setwidth(n,new) + end + end + end + leftkern=false + elseif rightkern then + local old=getwidth(n) + if old>threshold then + if useitalickerns then + local new=rightkern*factor + if trace_spaces then + report_spaces("%C [%p + %p]",nextchar,old,new) + end + insert_node_after(head,n,italickern(new)) + else + local new=old+rightkern*factor + if trace_spaces then + report_spaces("[%p -> %p] %C",nextchar,old,new) + end + setwidth(n,new) end + end + rightkern=false end - triggers=false - return head,true + end + triggers=false + return head end function injections.handler(head,where) - if triggers then - head=injectspaces(head) + if triggers then + head=injectspaces(head) + end + if nofregisteredmarks>0 or nofregisteredcursives>0 then + if trace_injections then + report_injections("injection variant %a","everything") end - if nofregisteredmarks>0 or nofregisteredcursives>0 then - if trace_injections then - report_injections("injection variant %a","everything") - end - return inject_everything(head,where) - elseif nofregisteredpositions>0 then - if trace_injections then - report_injections("injection variant %a","positions") - end - return inject_positions_only(head,where) - elseif nofregisteredkerns>0 then - if trace_injections then - report_injections("injection variant %a","kerns") - end - return inject_kerns_only(head,where) - else - return head,false + return inject_everything(head,where) + elseif nofregisteredpositions>0 then + if trace_injections then + report_injections("injection variant %a","positions") end + return inject_positions_only(head,where) + elseif nofregisteredkerns>0 then + if trace_injections then + report_injections("injection variant %a","kerns") + end + return inject_kerns_only(head,where) + else + return head + end end end -- closure @@ -23762,11 +25107,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-ota']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local type=type if not trackers then trackers={ register=function() end } end @@ -23786,11 +25131,9 @@ local getprev=nuts.getprev local getprev=nuts.getprev local getprop=nuts.getprop local setprop=nuts.setprop -local getfont=nuts.getfont local getsubtype=nuts.getsubtype local getchar=nuts.getchar local ischar=nuts.is_char -local traverse_id=nuts.traverse_id local end_of_math=nuts.end_of_math local nodecodes=nodes.nodecodes local disc_code=nodecodes.disc @@ -23800,342 +25143,342 @@ local categories=characters and characters.categories or {} local chardata=characters and characters.data local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register -local s_init=1 local s_rphf=7 -local s_medi=2 local s_half=8 -local s_fina=3 local s_pref=9 -local s_isol=4 local s_blwf=10 -local s_mark=5 local s_pstf=11 +local s_init=1 local s_rphf=7 +local s_medi=2 local s_half=8 +local s_fina=3 local s_pref=9 +local s_isol=4 local s_blwf=10 +local s_mark=5 local s_pstf=11 local s_rest=6 local states=allocate { - init=s_init, - medi=s_medi, - med2=s_medi, - fina=s_fina, - fin2=s_fina, - fin3=s_fina, - isol=s_isol, - mark=s_mark, - rest=s_rest, - rphf=s_rphf, - half=s_half, - pref=s_pref, - blwf=s_blwf, - pstf=s_pstf, + init=s_init, + medi=s_medi, + med2=s_medi, + fina=s_fina, + fin2=s_fina, + fin3=s_fina, + isol=s_isol, + mark=s_mark, + rest=s_rest, + rphf=s_rphf, + half=s_half, + pref=s_pref, + blwf=s_blwf, + pstf=s_pstf, } local features=allocate { - init=s_init, - medi=s_medi, - med2=s_medi, - fina=s_fina, - fin2=s_fina, - fin3=s_fina, - isol=s_isol, - rphf=s_rphf, - half=s_half, - pref=s_pref, - blwf=s_blwf, - pstf=s_pstf, + init=s_init, + medi=s_medi, + med2=s_medi, + fina=s_fina, + fin2=s_fina, + fin3=s_fina, + isol=s_isol, + rphf=s_rphf, + half=s_half, + pref=s_pref, + blwf=s_blwf, + pstf=s_pstf, } analyzers.states=states analyzers.features=features analyzers.useunicodemarks=false function analyzers.setstate(head,font) - local useunicodemarks=analyzers.useunicodemarks - local tfmdata=fontdata[font] - local descriptions=tfmdata.descriptions - local first,last,current,n,done=nil,nil,head,0,false - current=tonut(current) - while current do - local char,id=ischar(current,font) - if char and not getprop(current,a_state) then - done=true - local d=descriptions[char] - if d then - if d.class=="mark" then - done=true - setprop(current,a_state,s_mark) - elseif useunicodemarks and categories[char]=="mn" then - done=true - setprop(current,a_state,s_mark) - elseif n==0 then - first,last,n=current,current,1 - setprop(current,a_state,s_init) - else - last,n=current,n+1 - setprop(current,a_state,s_medi) - end - else - if first and first==last then - setprop(last,a_state,s_isol) - elseif last then - setprop(last,a_state,s_fina) - end - first,last,n=nil,nil,0 - end - elseif char==false then - if first and first==last then - setprop(last,a_state,s_isol) - elseif last then - setprop(last,a_state,s_fina) - end - first,last,n=nil,nil,0 - if id==math_code then - current=end_of_math(current) - end - elseif id==disc_code then - setprop(current,a_state,s_medi) - last=current - else - if first and first==last then - setprop(last,a_state,s_isol) - elseif last then - setprop(last,a_state,s_fina) - end - first,last,n=nil,nil,0 - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if first and first==last then + local useunicodemarks=analyzers.useunicodemarks + local tfmdata=fontdata[font] + local descriptions=tfmdata.descriptions + local first,last,current,n,done=nil,nil,head,0,false + current=tonut(current) + while current do + local char,id=ischar(current,font) + if char and not getprop(current,a_state) then + done=true + local d=descriptions[char] + if d then + if d.class=="mark" then + done=true + setprop(current,a_state,s_mark) + elseif useunicodemarks and categories[char]=="mn" then + done=true + setprop(current,a_state,s_mark) + elseif n==0 then + first,last,n=current,current,1 + setprop(current,a_state,s_init) + else + last,n=current,n+1 + setprop(current,a_state,s_medi) + end + else + if first and first==last then + setprop(last,a_state,s_isol) + elseif last then + setprop(last,a_state,s_fina) + end + first,last,n=nil,nil,0 + end + elseif char==false then + if first and first==last then setprop(last,a_state,s_isol) - elseif last then + elseif last then setprop(last,a_state,s_fina) - end - return head,done + end + first,last,n=nil,nil,0 + if id==math_code then + current=end_of_math(current) + end + elseif id==disc_code then + setprop(current,a_state,s_medi) + last=current + else + if first and first==last then + setprop(last,a_state,s_isol) + elseif last then + setprop(last,a_state,s_fina) + end + first,last,n=nil,nil,0 + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if first and first==last then + setprop(last,a_state,s_isol) + elseif last then + setprop(last,a_state,s_fina) + end + return head,done end local function analyzeinitializer(tfmdata,value) - local script,language=otf.scriptandlanguage(tfmdata) - local action=initializers[script] - if not action then - elseif type(action)=="function" then - return action(tfmdata,value) - else - local action=action[language] - if action then - return action(tfmdata,value) - end + local script,language=otf.scriptandlanguage(tfmdata) + local action=initializers[script] + if not action then + elseif type(action)=="function" then + return action(tfmdata,value) + else + local action=action[language] + if action then + return action(tfmdata,value) end + end end local function analyzeprocessor(head,font,attr) - local tfmdata=fontdata[font] - local script,language=otf.scriptandlanguage(tfmdata,attr) - local action=methods[script] - if not action then - elseif type(action)=="function" then - return action(head,font,attr) - else - action=action[language] - if action then - return action(head,font,attr) - end + local tfmdata=fontdata[font] + local script,language=otf.scriptandlanguage(tfmdata,attr) + local action=methods[script] + if not action then + elseif type(action)=="function" then + return action(head,font,attr) + else + action=action[language] + if action then + return action(head,font,attr) end - return head,false + end + return head,false end registerotffeature { - name="analyze", - description="analysis of character classes", - default=true, - initializers={ - node=analyzeinitializer, - }, - processors={ - position=1, - node=analyzeprocessor, - } + name="analyze", + description="analysis of character classes", + default=true, + initializers={ + node=analyzeinitializer, + }, + processors={ + position=1, + node=analyzeprocessor, + } } methods.latn=analyzers.setstate local arab_warned={} local function warning(current,what) - local char=getchar(current) - if not arab_warned[char] then - log.report("analyze","arab: character %C has no %a class",char,what) - arab_warned[char]=true - end + local char=getchar(current) + if not arab_warned[char] then + log.report("analyze","arab: character %C has no %a class",char,what) + arab_warned[char]=true + end end local mappers=allocate { - l=s_init, - d=s_medi, - c=s_medi, - r=s_fina, - u=s_isol, + l=s_init, + d=s_medi, + c=s_medi, + r=s_fina, + u=s_isol, } local classifiers=characters.classifiers if not classifiers then - local f_arabic,l_arabic=characters.blockrange("arabic") - local f_syriac,l_syriac=characters.blockrange("syriac") - local f_mandiac,l_mandiac=characters.blockrange("mandiac") - local f_nko,l_nko=characters.blockrange("nko") - local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") - classifiers=table.setmetatableindex(function(t,k) - if type(k)=="number" then - local c=chardata[k] - local v=false - if c then - local arabic=c.arabic - if arabic then - v=mappers[arabic] - if not v then - log.report("analyze","error in mapping arabic %C",k) - v=false - end - elseif (k>=f_arabic and k<=l_arabic) or - (k>=f_syriac and k<=l_syriac) or - (k>=f_mandiac and k<=l_mandiac) or - (k>=f_nko and k<=l_nko) or - (k>=f_ext_a and k<=l_ext_a) then - if categories[k]=="mn" then - v=s_mark - else - v=s_rest - end - end - end - t[k]=v - return v + local f_arabic,l_arabic=characters.blockrange("arabic") + local f_syriac,l_syriac=characters.blockrange("syriac") + local f_mandiac,l_mandiac=characters.blockrange("mandiac") + local f_nko,l_nko=characters.blockrange("nko") + local f_ext_a,l_ext_a=characters.blockrange("arabicextendeda") + classifiers=table.setmetatableindex(function(t,k) + if type(k)=="number" then + local c=chardata[k] + local v=false + if c then + local arabic=c.arabic + if arabic then + v=mappers[arabic] + if not v then + log.report("analyze","error in mapping arabic %C",k) + v=false + end + elseif (k>=f_arabic and k<=l_arabic) or + (k>=f_syriac and k<=l_syriac) or + (k>=f_mandiac and k<=l_mandiac) or + (k>=f_nko and k<=l_nko) or + (k>=f_ext_a and k<=l_ext_a) then + if categories[k]=="mn" then + v=s_mark + else + v=s_rest + end end - end) - characters.classifiers=classifiers + end + t[k]=v + return v + end + end) + characters.classifiers=classifiers end function methods.arab(head,font,attr) - local first,last=nil,nil - local c_first,c_last=nil,nil - local current,done=head,false - current=tonut(current) - while current do - local char,id=ischar(current,font) - if char and not getprop(current,a_state) then - done=true - local classifier=classifiers[char] - if not classifier then - if last then - if c_last==s_medi or c_last==s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first=nil - end - elseif classifier==s_mark then - setprop(current,a_state,s_mark) - elseif classifier==s_isol then - if last then - if c_last==s_medi or c_last==s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first=nil - end - setprop(current,a_state,s_isol) - elseif classifier==s_medi then - if first then - last=current - c_last=classifier - setprop(current,a_state,s_medi) - else - setprop(current,a_state,s_init) - first=current - c_first=classifier - end - elseif classifier==s_fina then - if last then - if getprop(last,a_state)~=s_init then - setprop(last,a_state,s_medi) - end - setprop(current,a_state,s_fina) - first,last=nil,nil - elseif first then - setprop(current,a_state,s_fina) - first=nil - else - setprop(current,a_state,s_isol) - end - else - setprop(current,a_state,s_rest) - if last then - if c_last==s_medi or c_last==s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first=nil - end - end - else - if last then - if c_last==s_medi or c_last==s_fina then - setprop(last,a_state,s_fina) - else - warning(last,"fina") - setprop(last,a_state,s_error) - end - first,last=nil,nil - elseif first then - if c_first==s_medi or c_first==s_fina then - setprop(first,a_state,s_isol) - else - warning(first,"isol") - setprop(first,a_state,s_error) - end - first=nil - end - if id==math_code then - current=end_of_math(current) - end - end - current=getnext(current) - end - if last then - if c_last==s_medi or c_last==s_fina then + local first,last,c_first,c_last + local current=head + local done=false + current=tonut(current) + while current do + local char,id=ischar(current,font) + if char and not getprop(current,a_state) then + done=true + local classifier=classifiers[char] + if not classifier then + if last then + if c_last==s_medi or c_last==s_fina then setprop(last,a_state,s_fina) - else + else warning(last,"fina") setprop(last,a_state,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first=nil end - elseif first then - if c_first==s_medi or c_first==s_fina then + elseif classifier==s_mark then + setprop(current,a_state,s_mark) + elseif classifier==s_isol then + if last then + if c_last==s_medi or c_last==s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first=nil + end + setprop(current,a_state,s_isol) + elseif classifier==s_medi then + if first then + last=current + c_last=classifier + setprop(current,a_state,s_medi) + else + setprop(current,a_state,s_init) + first=current + c_first=classifier + end + elseif classifier==s_fina then + if last then + if getprop(last,a_state)~=s_init then + setprop(last,a_state,s_medi) + end + setprop(current,a_state,s_fina) + first,last=nil,nil + elseif first then + setprop(current,a_state,s_fina) + first=nil else + setprop(current,a_state,s_isol) + end + else + setprop(current,a_state,s_rest) + if last then + if c_last==s_medi or c_last==s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setprop(first,a_state,s_isol) + else warning(first,"isol") setprop(first,a_state,s_error) + end + first=nil + end + end + else + if last then + if c_last==s_medi or c_last==s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) end + first,last=nil,nil + elseif first then + if c_first==s_medi or c_first==s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) + end + first=nil + end + if id==math_code then + current=end_of_math(current) + end + end + current=getnext(current) + end + if last then + if c_last==s_medi or c_last==s_fina then + setprop(last,a_state,s_fina) + else + warning(last,"fina") + setprop(last,a_state,s_error) + end + elseif first then + if c_first==s_medi or c_first==s_fina then + setprop(first,a_state,s_isol) + else + warning(first,"isol") + setprop(first,a_state,s_error) end - return head,done + end + return head,done end methods.syrc=methods.arab methods.mand=methods.arab methods.nko=methods.arab directives.register("otf.analyze.useunicodemarks",function(v) - analyzers.useunicodemarks=v + analyzers.useunicodemarks=v end) end -- closure @@ -24143,11 +25486,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-ots']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", } local type,next,tonumber=type,next,tonumber local random=math.random @@ -24161,31 +25504,31 @@ local attributes=attributes local fonts=fonts local otf=fonts.handlers.otf local tracers=nodes.tracers -local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) -local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) -local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) -local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end) -local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end) -local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end) -local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end) -local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end) -local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) -local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) -local trace_details=false registertracker("otf.details",function(v) trace_details=v end) -local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) -local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) -local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) -local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end) -local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) -local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) -local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) +local trace_singles=false registertracker("otf.singles",function(v) trace_singles=v end) +local trace_multiples=false registertracker("otf.multiples",function(v) trace_multiples=v end) +local trace_alternatives=false registertracker("otf.alternatives",function(v) trace_alternatives=v end) +local trace_ligatures=false registertracker("otf.ligatures",function(v) trace_ligatures=v end) +local trace_contexts=false registertracker("otf.contexts",function(v) trace_contexts=v end) +local trace_marks=false registertracker("otf.marks",function(v) trace_marks=v end) +local trace_kerns=false registertracker("otf.kerns",function(v) trace_kerns=v end) +local trace_cursive=false registertracker("otf.cursive",function(v) trace_cursive=v end) +local trace_preparing=false registertracker("otf.preparing",function(v) trace_preparing=v end) +local trace_bugs=false registertracker("otf.bugs",function(v) trace_bugs=v end) +local trace_details=false registertracker("otf.details",function(v) trace_details=v end) +local trace_steps=false registertracker("otf.steps",function(v) trace_steps=v end) +local trace_skips=false registertracker("otf.skips",function(v) trace_skips=v end) +local trace_plugins=false registertracker("otf.plugins",function(v) trace_plugins=v end) +local trace_chains=false registertracker("otf.chains",function(v) trace_chains=v end) +local trace_kernruns=false registertracker("otf.kernruns",function(v) trace_kernruns=v end) +local trace_compruns=false registertracker("otf.compruns",function(v) trace_compruns=v end) +local trace_testruns=false registertracker("otf.testruns",function(v) trace_testruns=v end) local forcediscretionaries=false local forcepairadvance=false directives.register("otf.forcediscretionaries",function(v) - forcediscretionaries=v + forcediscretionaries=v end) directives.register("otf.forcepairadvance",function(v) - forcepairadvance=v + forcepairadvance=v end) local report_direct=logs.reporter("fonts","otf direct") local report_subchain=logs.reporter("fonts","otf subchain") @@ -24199,8 +25542,6 @@ registertracker("otf.actions","otf.substitutions","otf.positions") registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") local nuts=nodes.nuts -local tonode=nuts.tonode -local tonut=nuts.tonut local getfield=nuts.getfield local getnext=nuts.getnext local setnext=nuts.setnext @@ -24213,7 +25554,6 @@ local getattr=nuts.getattr local setattr=nuts.setattr local getprop=nuts.getprop local setprop=nuts.setprop -local getfont=nuts.getfont local getsubtype=nuts.getsubtype local setsubtype=nuts.setsubtype local getchar=nuts.getchar @@ -24223,9 +25563,9 @@ local setdisc=nuts.setdisc local setlink=nuts.setlink local getcomponents=nuts.getcomponents local setcomponents=nuts.setcomponents -local getdir=nuts.getdir local getwidth=nuts.getwidth local ischar=nuts.is_char +local isglyph=nuts.isglyph local usesfont=nuts.uses_font local insert_node_after=nuts.insert_after local copy_node=nuts.copy @@ -24235,14 +25575,9 @@ local find_node_tail=nuts.tail local flush_node_list=nuts.flush_list local flush_node=nuts.flush_node local end_of_math=nuts.end_of_math -local traverse_nodes=nuts.traverse -local set_components=nuts.set_components -local take_components=nuts.take_components -local count_components=nuts.count_components -local copy_no_components=nuts.copy_no_components -local copy_only_glyphs=nuts.copy_only_glyphs local setmetatable=setmetatable local setmetatableindex=table.setmetatableindex +local nextnode=nuts.traversers.node local nodecodes=nodes.nodecodes local glyphcodes=nodes.glyphcodes local disccodes=nodes.disccodes @@ -24252,8 +25587,8 @@ local disc_code=nodecodes.disc local math_code=nodecodes.math local dir_code=nodecodes.dir local localpar_code=nodecodes.localpar -local discretionary_code=disccodes.discretionary -local ligature_code=glyphcodes.ligature +local discretionarydisc_code=disccodes.discretionary +local ligatureglyph_code=glyphcodes.ligature local a_state=attributes.private('state') local a_noligature=attributes.private("noligature") local injections=nodes.injections @@ -24292,2135 +25627,2180 @@ local notmatchreplace={} local handlers={} local isspace=injections.isspace local getthreshold=injections.getthreshold -local checkstep=(tracers and tracers.steppers.check) or function() end +local checkstep=(tracers and tracers.steppers.check) or function() end local registerstep=(tracers and tracers.steppers.register) or function() end -local registermessage=(tracers and tracers.steppers.message) or function() end +local registermessage=(tracers and tracers.steppers.message) or function() end local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return end - report_direct(...) + end + report_direct(...) end local function logwarning(...) - report_direct(...) -end -local gref do - local f_unicode=formatters["U+%X"] - local f_uniname=formatters["U+%X (%s)"] - local f_unilist=formatters["% t"] - gref=function(n) - if type(n)=="number" then - local description=descriptions[n] - local name=description and description.name - if name then - return f_uniname(n,name) - else - return f_unicode(n) - end - elseif n then - local t={} - for i=1,#n do - local ni=n[i] - if tonumber(ni) then - local di=descriptions[ni] - local nn=di and di.name - if nn then - t[#t+1]=f_uniname(ni,nn) - else - t[#t+1]=f_unicode(ni) - end - end - end - return f_unilist(t) - else - return "" + report_direct(...) +end +local gref do + local f_unicode=formatters["U+%X"] + local f_uniname=formatters["U+%X (%s)"] + local f_unilist=formatters["% t"] + gref=function(n) + if type(n)=="number" then + local description=descriptions[n] + local name=description and description.name + if name then + return f_uniname(n,name) + else + return f_unicode(n) + end + elseif n then + local t={} + for i=1,#n do + local ni=n[i] + if tonumber(ni) then + local di=descriptions[ni] + local nn=di and di.name + if nn then + t[#t+1]=f_uniname(ni,nn) + else + t[#t+1]=f_unicode(ni) + end end + end + return f_unilist(t) + else + return "" end + end end local function cref(dataset,sequence,index) - if not dataset then - return "no valid dataset" - end - local merged=sequence.merged and "merged " or "" - if index then - return formatters["feature %a, type %a, %schain lookup %a, index %a"]( - dataset[4],sequence.type,merged,sequence.name,index) - else - return formatters["feature %a, type %a, %schain lookup %a"]( - dataset[4],sequence.type,merged,sequence.name) - end + if not dataset then + return "no valid dataset" + end + local merged=sequence.merged and "merged " or "" + if index then + return formatters["feature %a, type %a, %schain lookup %a, index %a"]( + dataset[4],sequence.type,merged,sequence.name,index) + else + return formatters["feature %a, type %a, %schain lookup %a"]( + dataset[4],sequence.type,merged,sequence.name) + end end local function pref(dataset,sequence) - return formatters["feature %a, type %a, %slookup %a"]( - dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name) + return formatters["feature %a, type %a, %slookup %a"]( + dataset[4],sequence.type,sequence.merged and "merged " or "",sequence.name) end local function mref(rlmode) - if not rlmode or rlmode>=0 then - return "l2r" - else - return "r2l" - end + if not rlmode or rlmode>=0 then + return "l2r" + else + return "r2l" + end end local function flattendisk(head,disc) - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local prev,next=getboth(disc) - local ishead=head==disc - setdisc(disc) - flush_node(disc) - if pre then - flush_node_list(pre) - end - if post then - flush_node_list(post) - end - if ishead then - if replace then - if next then - setlink(replacetail,next) - end - return replace,replace - elseif next then - return next,next - else - end - else - if replace then - if next then - setlink(replacetail,next) - end - setlink(prev,replace) - return head,replace - else - setlink(prev,next) - return head,next - end - end -end -local function appenddisc(disc,list) - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local posthead=list - local replacehead=copy_node_list(list) - if post then - setlink(posttail,posthead) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prev,next=getboth(disc) + local ishead=head==disc + setdisc(disc) + flush_node(disc) + if pre then + flush_node_list(pre) + end + if post then + flush_node_list(post) + end + if ishead then + if replace then + if next then + setlink(replacetail,next) + end + return replace,replace + elseif next then + return next,next else - post=posthead end + else if replace then - setlink(replacetail,replacehead) + if next then + setlink(replacetail,next) + end + setlink(prev,replace) + return head,replace else - replace=replacehead + setlink(prev,next) + return head,next end - setdisc(disc,pre,post,replace) + end +end +local function appenddisc(disc,list) + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local posthead=list + local replacehead=copy_node_list(list) + if post then + setlink(posttail,posthead) + else + post=posthead + end + if replace then + setlink(replacetail,replacehead) + else + replace=replacehead + end + setdisc(disc,pre,post,replace) end -local take_components=getcomponents +local copy_no_components=nuts.copy_no_components +local copy_only_glyphs=nuts.copy_only_glyphs local set_components=setcomponents +local take_components=getcomponents local function count_components(start,marks) - if getid(start)~=glyph_code then - return 0 - elseif getsubtype(start)==ligature_code then - local i=0 - local components=getcomponents(start) - while components do - i=i+count_components(components,marks) - components=getnext(components) - end - return i - elseif not marks[getchar(start)] then - return 1 - else - return 0 - end + local char=isglyph(start) + if char then + if getsubtype(start)==ligatureglyph_code then + local i=0 + local components=getcomponents(start) + while components do + i=i+count_components(components,marks) + components=getnext(components) + end + return i + elseif not marks[char] then + return 1 + end + end + return 0 end local function markstoligature(head,start,stop,char) - if start==stop and getchar(start)==char then - return head,start - else - local prev=getprev(start) - local next=getnext(stop) - setprev(start) - setnext(stop) - local base=copy_no_components(start,copyinjection) - if head==start then - head=base - end - resetinjection(base) - setchar(base,char) - setsubtype(base,ligature_code) - set_components(base,start) - setlink(prev,base,next) - return head,base - end -end -local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) - if getattr(start,a_noligature)==1 then - return head,start - end - if start==stop and getchar(start)==char then - resetinjection(start) - setchar(start,char) - return head,start - end + if start==stop and getchar(start)==char then + return head,start + else local prev=getprev(start) local next=getnext(stop) - local comp=start setprev(start) setnext(stop) local base=copy_no_components(start,copyinjection) - if start==head then - head=base + if head==start then + head=base end resetinjection(base) setchar(base,char) - setsubtype(base,ligature_code) - set_components(base,comp) + setsubtype(base,ligatureglyph_code) + set_components(base,start) setlink(prev,base,next) - if not discfound then - local deletemarks=not skiphash or hasmarks - local components=start - local baseindex=0 - local componentindex=0 - local head=base - local current=base - while start do - local char=getchar(start) - if not marks[char] then - baseindex=baseindex+componentindex - componentindex=count_components(start,marks) - elseif not deletemarks then - setligaindex(start,baseindex+getligaindex(start,componentindex)) - if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) - end - local n=copy_node(start) - copyinjection(n,start) - head,current=insert_node_after(head,current,n) - elseif trace_marks then - logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char)) - end - start=getnext(start) + return head,base + end +end +local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) + if getattr(start,a_noligature)==1 then + return head,start + end + if start==stop and getchar(start)==char then + resetinjection(start) + setchar(start,char) + return head,start + end + local prev=getprev(start) + local next=getnext(stop) + local comp=start + setprev(start) + setnext(stop) + local base=copy_no_components(start,copyinjection) + if start==head then + head=base + end + resetinjection(base) + setchar(base,char) + setsubtype(base,ligatureglyph_code) + set_components(base,comp) + setlink(prev,base,next) + if not discfound then + local deletemarks=not skiphash or hasmarks + local components=start + local baseindex=0 + local componentindex=0 + local head=base + local current=base + while start do + local char=getchar(start) + if not marks[char] then + baseindex=baseindex+componentindex + componentindex=count_components(start,marks) + elseif not deletemarks then + setligaindex(start,baseindex+getligaindex(start,componentindex)) + if trace_marks then + logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) end - local start=getnext(current) - while start do - local char=ischar(start) - if char then - if marks[char] then - setligaindex(start,baseindex+getligaindex(start,componentindex)) - if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) - end - start=getnext(start) - else - break - end - else - break - end + local n=copy_node(start) + copyinjection(n,start) + head,current=insert_node_after(head,current,n) + elseif trace_marks then + logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char)) + end + start=getnext(start) + end + local start=getnext(current) + while start do + local char=ischar(start) + if char then + if marks[char] then + setligaindex(start,baseindex+getligaindex(start,componentindex)) + if trace_marks then + logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start)) + end + start=getnext(start) + else + break end - else - local discprev,discnext=getboth(discfound) - if discprev and discnext then - local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) - if not replace then - local prev=getprev(base) - local comp=take_components(base) - local copied=copy_only_glyphs(comp) - if pre then - setlink(discprev,pre) - else - setnext(discprev) - end - pre=comp - if post then - setlink(posttail,discnext) - setprev(post) - else - post=discnext - setprev(discnext) - end - setlink(prev,discfound,next) - setboth(base) - set_components(base,copied) - replace=base - if forcediscretionaries then - setdisc(discfound,pre,post,replace,discretionary_code) - else - setdisc(discfound,pre,post,replace) - end - base=prev - end + else + break + end + end + else + local discprev,discnext=getboth(discfound) + if discprev and discnext then + local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true) + if not replace then + local prev=getprev(base) + local comp=take_components(base) + local copied=copy_only_glyphs(comp) + if pre then + setlink(discprev,pre) + else + setnext(discprev) + end + pre=comp + if post then + setlink(posttail,discnext) + setprev(post) + else + post=discnext + setprev(discnext) + end + setlink(prev,discfound,next) + setboth(base) + set_components(base,copied) + replace=base + if forcediscretionaries then + setdisc(discfound,pre,post,replace,discretionarydisc_code) + else + setdisc(discfound,pre,post,replace) end + base=prev + end end - return head,base + end + return head,base end -local function multiple_glyphs(head,start,multiple,skiphash,what) - local nofmultiples=#multiple - if nofmultiples>0 then - resetinjection(start) - setchar(start,multiple[1]) - if nofmultiples>1 then - local sn=getnext(start) - for k=2,nofmultiples do - local n=copy_node(start) - resetinjection(n) - setchar(n,multiple[k]) - insert_node_after(head,start,n) - start=n - end - if what==true then - elseif what>1 then - local m=multiple[nofmultiples] - for i=2,what do - local n=copy_node(start) - resetinjection(n) - setchar(n,m) - insert_node_after(head,start,n) - start=n - end - end - end - return head,start,true - else - if trace_multiples then - logprocess("no multiple for %s",gref(getchar(start))) - end - return head,start,false +local function multiple_glyphs(head,start,multiple,skiphash,what,stop) + local nofmultiples=#multiple + if nofmultiples>0 then + resetinjection(start) + setchar(start,multiple[1]) + if nofmultiples>1 then + local sn=getnext(start) + for k=2,nofmultiples do + local n=copy_node(start) + resetinjection(n) + setchar(n,multiple[k]) + insert_node_after(head,start,n) + start=n + end + if what==true then + elseif what>1 then + local m=multiple[nofmultiples] + for i=2,what do + local n=copy_node(start) + resetinjection(n) + setchar(n,m) + insert_node_after(head,start,n) + start=n + end + end end + return head,start,true + else + if trace_multiples then + logprocess("no multiple for %s",gref(getchar(start))) + end + return head,start,false + end end local function get_alternative_glyph(start,alternatives,value) - local n=#alternatives - if n==1 then - return alternatives[1],trace_alternatives and "1 (only one present)" - elseif value=="random" then - local r=getrandom and getrandom("glyph",1,n) or random(1,n) - return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) - elseif value=="first" then - return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) - elseif value=="last" then - return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) - end - value=value==true and 1 or tonumber(value) - if type(value)~="number" then - return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) - end - if value>n then - local defaultalt=otf.defaultnodealternate - if defaultalt=="first" then - return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) - elseif defaultalt=="last" then - return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) - else - return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") - end - elseif value==0 then - return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") - elseif value<1 then - return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) + local n=#alternatives + if n==1 then + return alternatives[1],trace_alternatives and "1 (only one present)" + elseif value=="random" then + local r=getrandom and getrandom("glyph",1,n) or random(1,n) + return alternatives[r],trace_alternatives and formatters["value %a, taking %a"](value,r) + elseif value=="first" then + return alternatives[1],trace_alternatives and formatters["value %a, taking %a"](value,1) + elseif value=="last" then + return alternatives[n],trace_alternatives and formatters["value %a, taking %a"](value,n) + end + value=value==true and 1 or tonumber(value) + if type(value)~="number" then + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + end + if value>n then + local defaultalt=otf.defaultnodealternate + if defaultalt=="first" then + return alternatives[n],trace_alternatives and formatters["invalid value %s, taking %a"](value,1) + elseif defaultalt=="last" then + return alternatives[1],trace_alternatives and formatters["invalid value %s, taking %a"](value,n) else - return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) + return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end + elseif value==0 then + return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + elseif value<1 then + return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) + else + return alternatives[value],trace_alternatives and formatters["value %a, taking %a"](value,value) + end end function handlers.gsub_single(head,start,dataset,sequence,replacement) - if trace_singles then - logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement)) - end - resetinjection(start) - setchar(start,replacement) - return head,start,true + if trace_singles then + logprocess("%s: replacing %s by single %s",pref(dataset,sequence),gref(getchar(start)),gref(replacement)) + end + resetinjection(start) + setchar(start,replacement) + return head,start,true end function handlers.gsub_alternate(head,start,dataset,sequence,alternative) - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local choice,comment=get_alternative_glyph(start,alternative,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment) - end + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local choice,comment=get_alternative_glyph(start,alternative,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(dataset,sequence),gref(getchar(start)),gref(choice),comment) end - return head,start,true + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",pref(dataset,sequence),value,gref(getchar(start)),comment) + end + end + return head,start,true end function handlers.gsub_multiple(head,start,dataset,sequence,multiple,rlmode,skiphash) - if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) - end - return multiple_glyphs(head,start,multiple,skiphash,dataset[1]) + if trace_multiples then + logprocess("%s: replacing %s by multiple %s",pref(dataset,sequence),gref(getchar(start)),gref(multiple)) + end + return multiple_glyphs(head,start,multiple,skiphash,dataset[1]) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skiphash) - local current=getnext(start) - if not current then - return head,start,false,nil + local current=getnext(start) + if not current then + return head,start,false,nil + end + local stop=nil + local startchar=getchar(start) + if skiphash and skiphash[startchar] then + while current do + local char=ischar(current,currentfont) + if char then + local lg=ligature[char] + if lg then + stop=current + ligature=lg + current=getnext(current) + else + break + end + else + break + end end - local stop=nil - local startchar=getchar(start) - if skiphash and skiphash[startchar] then - while current do - local char=ischar(current,currentfont) - if char then - local lg=ligature[char] - if lg then - stop=current - ligature=lg - current=getnext(current) - else - break - end - else - break - end + if stop then + local lig=ligature.ligature + if lig then + if trace_ligatures then + local stopchar=getchar(stop) + head,start=markstoligature(head,start,stop,lig) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start))) + else + head,start=markstoligature(head,start,stop,lig) end - if stop then - local lig=ligature.ligature - if lig then - if trace_ligatures then - local stopchar=getchar(stop) - head,start=markstoligature(head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(getchar(start))) - else - head,start=markstoligature(head,start,stop,lig) - end - return head,start,true,false - else + return head,start,true,false + else + end + end + else + local discfound=false + local hasmarks=marks[startchar] + while current do + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + current=getnext(current) + else + local lg=ligature[char] + if lg then + if marks[char] then + hasmarks=true end + stop=current + ligature=lg + current=getnext(current) + else + break + end end - else - local discfound=false - local lastdisc=nil - local hasmarks=marks[startchar] - while current do - local char,id=ischar(current,currentfont) - if char then - if skiphash and skiphash[char] then - current=getnext(current) - else - local lg=ligature[char] - if lg then - if not discfound and lastdisc then - discfound=lastdisc - lastdisc=nil - end - if marks[char] then - hasmarks=true - end - stop=current - ligature=lg - current=getnext(current) - else - break - end - end - elseif char==false then - break - elseif id==disc_code then - local replace=getfield(current,"replace") - if replace then - while replace do - local char,id=ischar(replace,currentfont) - if char then - local lg=ligature[char] - if lg then - if marks[char] then - hasmarks=true - end - ligature=lg - replace=getnext(replace) - else - return head,start,false,false - end - else - return head,start,false,false - end - end - stop=current - end - lastdisc=current - current=getnext(current) - else - break - end + elseif char==false then + break + elseif id==disc_code then + discfound=current + break + else + break + end + end + if discfound then + local pre,post,replace=getdisc(discfound) + local match + if replace then + local char=ischar(replace,currentfont) + if char and ligature[char] then + match=true + end + end + if not match and pre then + local char=ischar(pre,currentfont) + if char and ligature[char] then + match=true + end + end + if not match and not pre or not replace then + local n=getnext(discfound) + local char=ischar(n,currentfont) + if char and ligature[char] then + match=true + end + end + if match then + local ishead=head==start + local prev=getprev(start) + if stop then + setnext(stop) + local tail=getprev(stop) + local copy=copy_node_list(start) + local liat=find_node_tail(copy) + if pre then + setlink(liat,pre) + end + if replace then + setlink(tail,replace) + end + pre=copy + replace=start + else + setnext(start) + local copy=copy_node(start) + if pre then + setlink(copy,pre) + end + if replace then + setlink(start,replace) + end + pre=copy + replace=start end - local lig=ligature.ligature - if lig then - if stop then - if trace_ligatures then - local stopchar=getchar(stop) - head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) - else - head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,discfound,hasmarks) - end - else - resetinjection(start) - setchar(start,lig) - if trace_ligatures then - logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) - end - end - return head,start,true,discfound + setdisc(discfound,pre,post,replace) + if prev then + setlink(prev,discfound) + else + setprev(discfound) + head=discfound + end + start=discfound + return head,start,true,true + end + end + local lig=ligature.ligature + if lig then + if stop then + if trace_ligatures then + local stopchar=getchar(stop) + head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(dataset,sequence),gref(startchar),gref(stopchar),gref(lig)) else + head,start=toligature(head,start,stop,lig,dataset,sequence,skiphash,false,hasmarks) end + else + resetinjection(start) + setchar(start,lig) + if trace_ligatures then + logprocess("%s: replacing %s by (no real) ligature %s case 3",pref(dataset,sequence),gref(startchar),gref(lig)) + end + end + return head,start,true,false + else end - return head,start,false,discfound + end + return head,start,false,false end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar=getchar(start) - local format=step.format - if format=="single" or type(kerns)=="table" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) - end + local startchar=getchar(start) + local format=step.format + if format=="single" or type(kerns)=="table" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) end - return head,start,true + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end + end + return head,start,true end function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext=getnext(start) - if not snext then - return head,start,false - else - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=step.format - if format=="pair" then - local a,b=krn[1],krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end - end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") - end - return head,start,true - else - break - end - end - else - break + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break + end + local format=step.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) + if trace_kerns then + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") end + return head,start,true + else + break + end end - return head,start,false + else + break + end end + return head,start,false + end end function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", - pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - elseif trace_bugs then - logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar)) - end - elseif trace_bugs then - logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", + pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true elseif trace_bugs then - logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2) + logwarning("%s: mark %s is not anchored to %s",pref(dataset,sequence),gref(markchar),gref(basechar)) end + elseif trace_bugs then + logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),1) + end elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + logwarning("%s: nothing preceding, case %i",pref(dataset,sequence),2) end - return head,start,false + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false end function handlers.gpos_mark2ligature(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", - pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy) - end - return head,start,true - else - if trace_bugs then - logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index) - end - end - end - elseif trace_bugs then - onetimemessage(currentfont,basechar,"no base anchors",report_fonts) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1) + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) + end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false + end + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, index %s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", + pref(dataset,sequence),index,bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true + else + if trace_bugs then + logwarning("%s: no matching anchors for mark %s and baselig %s with index %a",pref(dataset,sequence),gref(markchar),gref(basechar),index) + end end + end elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2) + onetimemessage(currentfont,basechar,"no base anchors",report_fonts) end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),1) + end elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + logwarning("%s: prev node is no char, case %i",pref(dataset,sequence),2) end - return head,start,false + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false end function handlers.gpos_mark2mark(head,start,dataset,sequence,markanchors,rlmode,skiphash) - local markchar=getchar(start) - if marks[markchar] then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break - end - end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", - pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end + local markchar=getchar(start) + if marks[markchar] then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end + end + end + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", + pref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) + end + return head,start,true end - elseif trace_bugs then - logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end end - return head,start,false + elseif trace_bugs then + logwarning("%s: mark %s is no mark",pref(dataset,sequence),gref(markchar)) + end + return head,start,false end function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,skiphash,step) - local startchar=getchar(start) - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt=getnext(start) - while nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) - else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local r2lflag=sequence.flags[4] - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) - end - return head,start,true - end - end - end - break + local startchar=getchar(start) + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local r2lflag=sequence.flags[4] + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) + end + return head,start,true end + end end + break + end end - return head,start,false + end + return head,start,false end local chainprocs={} local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return end - report_subchain(...) + end + report_subchain(...) end local logwarning=report_subchain local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return end - report_chain(...) + end + report_chain(...) end local logwarning=report_chain local function reversesub(head,start,stop,dataset,sequence,replacements,rlmode,skiphash) - local char=getchar(start) - local replacement=replacements[char] - if replacement then - if trace_singles then - logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement)) - end - resetinjection(start) - setchar(start,replacement) - return head,start,true - else - return head,start,false + local char=getchar(start) + local replacement=replacements[char] + if replacement then + if trace_singles then + logprocess("%s: single reverse replacement of %s by %s",cref(dataset,sequence),gref(char),gref(replacement)) end + resetinjection(start) + setchar(start,replacement) + return head,start,true + else + return head,start,false + end end chainprocs.reversesub=reversesub local function reportzerosteps(dataset,sequence) - logwarning("%s: no steps",cref(dataset,sequence)) + logwarning("%s: no steps",cref(dataset,sequence)) end local function reportmoresteps(dataset,sequence) - logwarning("%s: more than 1 step",cref(dataset,sequence)) + logwarning("%s: more than 1 step",cref(dataset,sequence)) end local function getmapping(dataset,sequence,currentlookup) - local steps=currentlookup.steps - local nofsteps=currentlookup.nofsteps - if nofsteps==0 then - reportzerosteps(dataset,sequence) - currentlookup.mapping=false - return false - else - if nofsteps>1 then - reportmoresteps(dataset,sequence) - end - local mapping=steps[1].coverage - currentlookup.mapping=mapping - currentlookup.format=steps[1].format - return mapping + local steps=currentlookup.steps + local nofsteps=currentlookup.nofsteps + if nofsteps==0 then + reportzerosteps(dataset,sequence) + currentlookup.mapping=false + return false + else + if nofsteps>1 then + reportmoresteps(dataset,sequence) end + local mapping=steps[1].coverage + currentlookup.mapping=mapping + currentlookup.format=steps[1].format + return mapping + end +end +function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if trace_chains then + logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start))) + end + head,start=remove_node(head,start,true) + return head,getprev(start),true end function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local replacement=mapping[currentchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) - end - else - if trace_singles then - logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) - end - resetinjection(current) - setchar(current,replacement) - end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) - end + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local current=start + while current do + local currentchar=ischar(current) + if currentchar then + local replacement=mapping[currentchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no single for %s",cref(dataset,sequence,chainindex),gref(currentchar)) + end + else + if trace_singles then + logprocess("%s: replacing single %s by %s",cref(dataset,sequence,chainindex),gref(currentchar),gref(replacement)) + end + resetinjection(current) + setchar(current,replacement) end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) + end end - return head,start,false + end + return head,start,false end function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local kind=dataset[4] - local what=dataset[1] - local value=what==true and tfmdata.shared.features[kind] or what - local current=start - while current do - local currentchar=ischar(current) - if currentchar then - local alternatives=mapping[currentchar] - if alternatives then - local choice,comment=get_alternative_glyph(current,alternatives,value) - if choice then - if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment) - end - resetinjection(start) - setchar(start,choice) - else - if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment) - end - end - end - return head,start,true - elseif currentchar==false then - break - elseif current==stop then - break - else - current=getnext(current) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local kind=dataset[4] + local what=dataset[1] + local value=what==true and tfmdata.shared.features[kind] or what + local current=start + while current do + local currentchar=ischar(current) + if currentchar then + local alternatives=mapping[currentchar] + if alternatives then + local choice,comment=get_alternative_glyph(current,alternatives,value) + if choice then + if trace_alternatives then + logprocess("%s: replacing %s by alternative %a to %s, %s",cref(dataset,sequence),gref(currentchar),choice,gref(choice),comment) + end + resetinjection(start) + setchar(start,choice) + else + if trace_alternatives then + logwarning("%s: no variant %a for %s, %s",cref(dataset,sequence),value,gref(currentchar),comment) end + end end + return head,start,true + elseif currentchar==false then + break + elseif current==stop then + break + else + current=getnext(current) + end end - return head,start,false + end + return head,start,false end function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local replacement=mapping[startchar] + if not replacement or replacement=="" then + if trace_bugs then + logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) + end + else + if trace_multiples then + logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + end + return multiple_glyphs(head,start,replacement,skiphash,dataset[1],stop) end - if mapping then - local startchar=getchar(start) - local replacement=mapping[startchar] - if not replacement or replacement=="" then - if trace_bugs then - logwarning("%s: no multiple for %s",cref(dataset,sequence),gref(startchar)) - end + end + return head,start,false +end +function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local ligatures=mapping[startchar] + if not ligatures then + if trace_bugs then + logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) + end + else + local hasmarks=marks[startchar] + local current=getnext(start) + local discfound=false + local last=stop + local nofreplacements=1 + while current do + local id=getid(current) + if id==disc_code then + if not discfound then + discfound=current + end + if current==stop then + break + else + current=getnext(current) + end else - if trace_multiples then - logprocess("%s: replacing %s by multiple characters %s",cref(dataset,sequence),gref(startchar),gref(replacement)) + local schar=getchar(current) + if skiphash and skiphash[schar] then + current=getnext(current) + else + local lg=ligatures[schar] + if lg then + ligatures=lg + last=current + nofreplacements=nofreplacements+1 + if marks[char] then + hasmarks=true + end + if current==stop then + break + else + current=getnext(current) + end + else + break end - return multiple_glyphs(head,start,replacement,skiphash,dataset[1]) + end + end + end + local ligature=ligatures.ligature + if ligature then + if chainindex then + stop=last + end + if trace_ligatures then + if start==stop then + logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) + else + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) + end + end + head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks) + return head,start,true,nofreplacements,discfound + elseif trace_bugs then + if start==stop then + logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) + else + logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) end + end end - return head,start,false + end + return head,start,false,0,false end -function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local ligatures=mapping[startchar] - if not ligatures then - if trace_bugs then - logwarning("%s: no ligatures starting with %s",cref(dataset,sequence,chainindex),gref(startchar)) - end - else - local hasmarks=marks[startchar] - local current=getnext(start) - local discfound=false - local last=stop - local nofreplacements=1 - while current do - local id=getid(current) - if id==disc_code then - if not discfound then - discfound=current - end - if current==stop then - break - else - current=getnext(current) - end - else - local schar=getchar(current) - if skiphash and skiphash[schar] then - current=getnext(current) - else - local lg=ligatures[schar] - if lg then - ligatures=lg - last=current - nofreplacements=nofreplacements+1 - if marks[char] then - hasmarks=true - end - if current==stop then - break - else - current=getnext(current) - end - else - break - end - end - end - end - local ligature=ligatures.ligature - if ligature then - if chainindex then - stop=last - end - if trace_ligatures then - if start==stop then - logprocess("%s: replacing character %s by ligature %s case 3",cref(dataset,sequence,chainindex),gref(startchar),gref(ligature)) - else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop)),gref(ligature)) - end - end - head,start=toligature(head,start,stop,ligature,dataset,sequence,skiphash,discfound,hasmarks) - return head,start,true,nofreplacements,discfound - elseif trace_bugs then - if start==stop then - logwarning("%s: replacing character %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar)) - else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(dataset,sequence,chainindex),gref(startchar),gref(getchar(stop))) - end - end +function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local format=currentlookup.format + if format=="single" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end + end + return head,start,true end - return head,start,false,0,false + end + return head,start,false end -function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then +function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then + break + end + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break + end local format=currentlookup.format - if format=="single" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) + if trace_kerns then + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + end + return head,start,true + else + break end - return head,start,true + end end + end end - return head,start,false + end + return head,start,false end -function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break +function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break end - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=currentlookup.format - if format=="pair" then - local a,b=krn[1],krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end - end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) - end - return head,start,true - else - break - end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) end + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) + end + return head,start,false end + end end - end - end - return head,start,false -end -function chainprocs.gpos_mark2base(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",pref(dataset,sequence),gref(markchar),2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", - cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basechar %s => (%p,%p)", + cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) end - elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + return head,start,true + end end + elseif trace_bugs then + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),1) + end elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) + logwarning("%s: prev node is no char, case %i",cref(dataset,sequence),2) end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - return head,start,false + end + return head,start,false end function chainprocs.gpos_mark2ligature(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + if base then + local basechar=ischar(base,currentfont) + if basechar then + if marks[basechar] then + while base do + base=getprev(base) if base then - local basechar=ischar(base,currentfont) - if basechar then - if marks[basechar] then - while base do - base=getprev(base) - if base then - local basechar=ischar(base,currentfont) - if basechar then - if not marks[basechar] then - break - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) - end - return head,start,false - end - else - if trace_bugs then - logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) - end - return head,start,false - end - end - end - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local index=getligaindex(start) - ba=ba[index] - if ba then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", - cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy) - end - return head,start,true - end - end - end - elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) + local basechar=ischar(base,currentfont) + if basechar then + if not marks[basechar] then + break + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,1) end - elseif trace_bugs then - logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) + return head,start,false + end + else + if trace_bugs then + logwarning("%s: no base for mark %s, case %i",cref(dataset,sequence),markchar,2) + end + return head,start,false end - elseif trace_bugs then - logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + end + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local index=getligaindex(start) + ba=ba[index] + if ba then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],false,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to baselig %s at index %s => (%p,%p)", + cref(dataset,sequence),a or bound,gref(markchar),gref(basechar),index,dx,dy) + end + return head,start,true + end + end end + elseif trace_bugs then + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),1) + end elseif trace_bugs then - logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) + logwarning("%s, prev node is no char, case %i",cref(dataset,sequence),2) end + elseif trace_bugs then + logwarning("%s, mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s, mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - return head,start,false + end + return head,start,false end function chainprocs.gpos_mark2mark(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local markchar=getchar(start) - if marks[markchar] then - local markanchors=mapping[markchar] - if markanchors then - local base=getprev(start) - local slc=getligaindex(start) - if slc then - while base do - local blc=getligaindex(base) - if blc and blc~=slc then - base=getprev(base) - else - break - end - end - end - if base then - local basechar=ischar(base,currentfont) - if basechar then - local ba=markanchors[1][basechar] - if ba then - local ma=markanchors[2] - if ma then - local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) - if trace_marks then - logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", - cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) - end - return head,start,true - end - end - elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) - end - elseif trace_bugs then - logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local markchar=getchar(start) + if marks[markchar] then + local markanchors=mapping[markchar] + if markanchors then + local base=getprev(start) + local slc=getligaindex(start) + if slc then + while base do + local blc=getligaindex(base) + if blc and blc~=slc then + base=getprev(base) + else + break + end + end + end + if base then + local basechar=ischar(base,currentfont) + if basechar then + local ba=markanchors[1][basechar] + if ba then + local ma=markanchors[2] + if ma then + local dx,dy,bound=setmark(start,base,factor,rlmode,ba,ma,characters[basechar],true,checkmarks) + if trace_marks then + logprocess("%s, bound %s, anchoring mark %s to basemark %s => (%p,%p)", + cref(dataset,sequence),bound,gref(markchar),gref(basechar),dx,dy) end - elseif trace_bugs then - logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + return head,start,true + end end + elseif trace_bugs then + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),1) + end elseif trace_bugs then - logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) + logwarning("%s: prev node is no mark, case %i",cref(dataset,sequence),2) end + elseif trace_bugs then + logwarning("%s: mark %s has no anchors",cref(dataset,sequence),gref(markchar)) + end + elseif trace_bugs then + logwarning("%s: mark %s is no mark",cref(dataset,sequence),gref(markchar)) end - return head,start,false + end + return head,start,false end function chainprocs.gpos_cursive(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local exitanchors=mapping[startchar] - if exitanchors then - if marks[startchar] then - if trace_cursive then - logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) - end - else - local nxt=getnext(start) - while nxt do - local nextchar=ischar(nxt,currentfont) - if not nextchar then - break - elseif marks[nextchar] then - nxt=getnext(nxt) - else - local exit=exitanchors[3] - if exit then - local entry=exitanchors[1][nextchar] - if entry then - entry=entry[2] - if entry then - local r2lflag=sequence.flags[4] - local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) - if trace_cursive then - logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) - end - return head,start,true - end - end - elseif trace_bugs then - onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) - end - break - end + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local exitanchors=mapping[startchar] + if exitanchors then + if marks[startchar] then + if trace_cursive then + logprocess("%s: ignoring cursive for mark %s",pref(dataset,sequence),gref(startchar)) + end + else + local nxt=getnext(start) + while nxt do + local nextchar=ischar(nxt,currentfont) + if not nextchar then + break + elseif marks[nextchar] then + nxt=getnext(nxt) + else + local exit=exitanchors[3] + if exit then + local entry=exitanchors[1][nextchar] + if entry then + entry=entry[2] + if entry then + local r2lflag=sequence.flags[4] + local dx,dy,bound=setcursive(start,nxt,factor,rlmode,exit,entry,characters[startchar],characters[nextchar],r2lflag) + if trace_cursive then + logprocess("%s: moving %s to %s cursive (%p,%p) using bound %s in %s mode",pref(dataset,sequence),gref(startchar),gref(nextchar),dx,dy,bound,mref(rlmode)) + end + return head,start,true end + end + elseif trace_bugs then + onetimemessage(currentfont,startchar,"no entry anchors",report_fonts) end - elseif trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) + break + end end + end + elseif trace_cursive and trace_details then + logprocess("%s, cursive %s is already done",pref(dataset,sequence),gref(getchar(start)),alreadydone) end - return head,start,false + end + return head,start,false end local function show_skip(dataset,sequence,char,ck,class) - logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) + logwarning("%s: skipping char %s, class %a, rule %a, lookuptype %a",cref(dataset,sequence),gref(char),class,ck[1],ck[8] or ck[2]) end local userkern=nuts.pool and nuts.pool.newkern do if not userkern then - local thekern=nuts.new("kern",1) - local setkern=nuts.setkern - userkern=function(k) - local n=copy_node(thekern) - setkern(n,k) - return n - end + local thekern=nuts.new("kern",1) + local setkern=nuts.setkern + userkern=function(k) + local n=copy_node(thekern) + setkern(n,k) + return n + end end end local function checked(head) - local current=head - while current do - if getid(current)==glue_code then - local kern=userkern(getwidth(current)) - if head==current then - local next=getnext(current) - if next then - setlink(kern,next) - end - flush_node(current) - head=kern - current=next - else - local prev,next=getboth(current) - setlink(prev,kern,next) - flush_node(current) - current=next - end - else - current=getnext(current) + local current=head + while current do + if getid(current)==glue_code then + local kern=userkern(getwidth(current)) + if head==current then + local next=getnext(current) + if next then + setlink(kern,next) end + flush_node(current) + head=kern + current=next + else + local prev,next=getboth(current) + setlink(prev,kern,next) + flush_node(current) + current=next + end + else + current=getnext(current) end - return head + end + return head end local function setdiscchecked(d,pre,post,replace) - if pre then pre=checked(pre) end - if post then post=checked(post) end - if replace then replace=checked(replace) end - setdisc(d,pre,post,replace) + if pre then pre=checked(pre) end + if post then post=checked(post) end + if replace then replace=checked(replace) end + setdisc(d,pre,post,replace) end local noflags={ false,false,false,false } local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) - local size=ck[5]-ck[4]+1 - local chainlookups=ck[6] - local done=false - if chainlookups then - if size==1 then - local chainlookup=chainlookups[1] - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local chainkind=chainstep.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok - head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash) - if ok then - done=true - end - else - logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) - end + local size=ck[5]-ck[4]+1 + local chainlookups=ck[6] + local done=false + if chainlookups then + if size==1 then + local chainlookup=chainlookups[1] + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok + head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash) + if ok then + done=true + end + else + logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind) + end + end + else + local i=1 + local laststart=start + local nofchainlookups=#chainlookups + while start do + if skiphash then + while start do + local char=ischar(start,currentfont) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else + break + end + else + break end - else - local i=1 - local laststart=start - local nofchainlookups=#chainlookups - while start do - if skiphash then - while start do - local char=ischar(start,currentfont) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - break - end - else - break - end - end - end - local chainlookup=chainlookups[i] - if chainlookup then - for j=1,#chainlookup do - local chainstep=chainlookup[j] - local chainkind=chainstep.type - local chainproc=chainprocs[chainkind] - if chainproc then - local ok,n - head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i) - if ok then - done=true - if n and n>1 and i+n>nofchainlookups then - i=size - break - end - end - else - logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) - end - end - end - i=i+1 - if i>size or not start then - break - elseif start then - laststart=start - start=getnext(start) + end + end + local chainlookup=chainlookups[i] + if chainlookup then + for j=1,#chainlookup do + local chainstep=chainlookup[j] + local chainkind=chainstep.type + local chainproc=chainprocs[chainkind] + if chainproc then + local ok,n + head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i) + if ok then + done=true + if n and n>1 and i+n>nofchainlookups then + i=size + break end + end + else + logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind) end - if not start then - start=laststart - end - end - else - local replacements=ck[7] - if replacements then - head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash) + end else - done=true - if trace_contexts then - logprocess("%s: skipping match",cref(dataset,sequence)) - end end + i=i+1 + if i>size or not start then + break + elseif start then + laststart=start + start=getnext(start) + end + end + if not start then + start=laststart + end + end + else + local replacements=ck[7] + if replacements then + head,start,done=reversesub(head,start,last,dataset,sequence,replacements,rlmode,skiphash) + else + done=true + if trace_contexts then + logprocess("%s: skipping match",cref(dataset,sequence)) + end end - return head,start,done + end + return head,start,done end local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) - if not start then - return head,start,false - end - local startishead=start==head - local seq=ck[3] - local f=ck[4] - local l=ck[5] - local s=#seq - local done=false - local sweepnode=sweepnode - local sweeptype=sweeptype - local sweepoverflow=false - local keepdisc=not sweepnode - local lookaheaddisc=nil - local backtrackdisc=nil - local current=start - local last=start - local prev=getprev(start) - local hasglue=false - local i=f - while i<=l do - local id=getid(current) - if id==glyph_code then - i=i+1 - last=current - current=getnext(current) - elseif id==glue_code then - i=i+1 - last=current - current=getnext(current) - hasglue=true - elseif id==disc_code then - if keepdisc then - keepdisc=false - lookaheaddisc=current - local replace=getfield(current,"replace") - if not replace then - sweepoverflow=true - sweepnode=current - current=getnext(current) - else - while replace and i<=l do - if getid(replace)==glyph_code then - i=i+1 - end - replace=getnext(replace) - end - current=getnext(replace) - end - last=current - else - head,current=flattendisk(head,current) - end + if not start then + return head,start,false + end + local startishead=start==head + local seq=ck[3] + local f=ck[4] + local l=ck[5] + local s=#seq + local done=false + local sweepnode=sweepnode + local sweeptype=sweeptype + local sweepoverflow=false + local keepdisc=not sweepnode + local lookaheaddisc=nil + local backtrackdisc=nil + local current=start + local last=start + local prev=getprev(start) + local hasglue=false + local i=f + while i<=l do + local id=getid(current) + if id==glyph_code then + i=i+1 + last=current + current=getnext(current) + elseif id==glue_code then + i=i+1 + last=current + current=getnext(current) + hasglue=true + elseif id==disc_code then + if keepdisc then + keepdisc=false + lookaheaddisc=current + local replace=getfield(current,"replace") + if not replace then + sweepoverflow=true + sweepnode=current + current=getnext(current) else - last=current - current=getnext(current) + while replace and i<=l do + if getid(replace)==glyph_code then + i=i+1 + end + replace=getnext(replace) + end + current=getnext(replace) end - if current then - elseif sweepoverflow then - break - elseif sweeptype=="post" or sweeptype=="replace" then - current=getnext(sweepnode) - if current then - sweeptype=nil - sweepoverflow=true - else - break + last=current + else + head,current=flattendisk(head,current) + end + else + last=current + current=getnext(current) + end + if current then + elseif sweepoverflow then + break + elseif sweeptype=="post" or sweeptype=="replace" then + current=getnext(sweepnode) + if current then + sweeptype=nil + sweepoverflow=true + else + break + end + else + break + end + end + if sweepoverflow then + local prev=current and getprev(current) + if not current or prev~=sweepnode then + local head=getnext(sweepnode) + local tail=nil + if prev then + tail=prev + setprev(current,sweepnode) + else + tail=find_node_tail(head) + end + setnext(sweepnode,current) + setprev(head) + setnext(tail) + appenddisc(sweepnode,head) + end + end + if l1 then + local current=prev + local i=f + local t=sweeptype=="pre" or sweeptype=="replace" + if not current and t and current==checkdisk then + current=getprev(sweepnode) + end + while current and i>1 do + local id=getid(current) + if id==glyph_code then + i=i-1 + elseif id==glue_code then + i=i-1 + hasglue=true + elseif id==disc_code then + if keepdisc then + keepdisc=false + if notmatchpost[current]~=notmatchreplace[current] then + backtrackdisc=current + end + local replace=getfield(current,"replace") + while replace and i>1 do + if getid(replace)==glyph_code then + i=i-1 end - end + replace=getnext(replace) + end + elseif notmatchpost[current]~=notmatchreplace[current] then + head,current=flattendisk(head,current) + end + end + current=getprev(current) + if t and current==checkdisk then + current=getprev(sweepnode) + end + end + end + local done=false + if lookaheaddisc then + local cf=start + local cl=getprev(lookaheaddisc) + local cprev=getprev(start) + local insertedmarks=0 + while cprev do + local char=ischar(cf,currentfont) + if char and marks[char] then + insertedmarks=insertedmarks+1 + cf=cprev + startishead=cf==head + cprev=getprev(cprev) + else + break + end end - if f>1 then - local current=prev - local i=f - local t=sweeptype=="pre" or sweeptype=="replace" - if not current and t and current==checkdisk then - current=getprev(sweepnode) - end - while current and i>1 do - local id=getid(current) - if id==glyph_code then - i=i-1 - elseif id==glue_code then - i=i-1 - hasglue=true - elseif id==disc_code then - if keepdisc then - keepdisc=false - if notmatchpost[current]~=notmatchreplace[current] then - backtrackdisc=current - end - local replace=getfield(current,"replace") - while replace and i>1 do - if getid(replace)==glyph_code then - i=i-1 - end - replace=getnext(replace) - end - elseif notmatchpost[current]~=notmatchreplace[current] then - head,current=flattendisk(head,current) - end - end - current=getprev(current) - if t and current==checkdisk then - current=getprev(sweepnode) - end - end + setlink(cprev,lookaheaddisc) + setprev(cf) + setnext(cl) + if startishead then + head=lookaheaddisc end - local done=false - if lookaheaddisc then - local cf=start - local cl=getprev(lookaheaddisc) - local cprev=getprev(start) - local insertedmarks=0 - while cprev do - local char=ischar(cf,currentfont) - if char and marks[char] then - insertedmarks=insertedmarks+1 - cf=cprev - startishead=cf==head - cprev=getprev(cprev) - else - break - end - end - setlink(cprev,lookaheaddisc) - setprev(cf) - setnext(cl) - if startishead then - head=lookaheaddisc - end - local pre,post,replace=getdisc(lookaheaddisc) - local new=copy_node_list(cf) - local cnew=new - if pre then - setlink(find_node_tail(cf),pre) - end - if replace then - local tail=find_node_tail(new) - setlink(tail,replace) - end - for i=1,insertedmarks do - cnew=getnext(cnew) - end - cl=start - local clast=cnew - for i=f,l do - cl=getnext(cl) - clast=getnext(clast) - end - if not notmatchpre[lookaheaddisc] then - local ok=false - cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end - end - if not notmatchreplace[lookaheaddisc] then - local ok=false - new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true - end + local pre,post,replace=getdisc(lookaheaddisc) + local new=copy_node_list(cf) + local cnew=new + if pre then + setlink(find_node_tail(cf),pre) + end + if replace then + local tail=find_node_tail(new) + setlink(tail,replace) + end + for i=1,insertedmarks do + cnew=getnext(cnew) + end + cl=start + local clast=cnew + for i=f,l do + cl=getnext(cl) + clast=getnext(clast) + end + if not notmatchpre[lookaheaddisc] then + local ok=false + cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if not notmatchreplace[lookaheaddisc] then + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if hasglue then + setdiscchecked(lookaheaddisc,cf,post,new) + else + setdisc(lookaheaddisc,cf,post,new) + end + start=getprev(lookaheaddisc) + sweephead[cf]=getnext(clast) or false + sweephead[new]=getnext(cl) or false + elseif backtrackdisc then + local cf=getnext(backtrackdisc) + local cl=start + local cnext=getnext(start) + local insertedmarks=0 + while cnext do + local char=ischar(cnext,currentfont) + if char and marks[char] then + insertedmarks=insertedmarks+1 + cl=cnext + cnext=getnext(cnext) + else + break + end + end + setlink(backtrackdisc,cnext) + setprev(cf) + setnext(cl) + local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true) + local new=copy_node_list(cf) + local cnew=find_node_tail(new) + for i=1,insertedmarks do + cnew=getprev(cnew) + end + local clast=cnew + for i=f,l do + clast=getnext(clast) + end + if not notmatchpost[backtrackdisc] then + local ok=false + cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if not notmatchreplace[backtrackdisc] then + local ok=false + new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + if post then + setlink(posttail,cf) + else + post=cf + end + if replace then + setlink(replacetail,new) + else + replace=new + end + if hasglue then + setdiscchecked(backtrackdisc,pre,post,replace) + else + setdisc(backtrackdisc,pre,post,replace) + end + start=getprev(backtrackdisc) + sweephead[post]=getnext(clast) or false + sweephead[replace]=getnext(last) or false + else + local ok=false + head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) + if ok then + done=true + end + end + return head,start,done +end +local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode) + local rule=ck[1] + local lookuptype=ck[8] or ck[2] + local nofseq=#ck[3] + local first=ck[4] + local last=ck[5] + local char=getchar(start) + logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping", + cref(dataset,sequence),rule,match and "matches" or "nomatch", + gref(char),first-1,last-first+1,nofseq-last,lookuptype, + discseen and "" or "no ",sweepnode and "" or "not ") +end +local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) + local sweepnode=sweepnode + local sweeptype=sweeptype + local postreplace + local prereplace + local checkdisc + local discseen + if sweeptype then + if sweeptype=="replace" then + postreplace=true + prereplace=true + else + postreplace=sweeptype=="post" + prereplace=sweeptype=="pre" + end + checkdisc=getprev(head) + end + local currentfont=currentfont + local skipped + local startprev, + startnext=getboth(start) + local done + local nofcontexts=contexts.n + local startchar=nofcontext==1 or ischar(start,currentfont) + for k=1,nofcontexts do + local ck=contexts[k] + local seq=ck[3] + local f=ck[4] + if not startchar or not seq[f][startchar] then + goto next + end + local s=seq.n + local l=ck[5] + local current=start + local last=start + if l>f then + local discfound + local n=f+1 + last=startnext + while n<=l do + if postreplace and not last then + last=getnext(sweepnode) + sweeptype=nil end - if hasglue then - setdiscchecked(lookaheaddisc,cf,post,new) - else - setdisc(lookaheaddisc,cf,post,new) - end - start=getprev(lookaheaddisc) - sweephead[cf]=getnext(clast) or false - sweephead[new]=getnext(cl) or false - elseif backtrackdisc then - local cf=getnext(backtrackdisc) - local cl=start - local cnext=getnext(start) - local insertedmarks=0 - while cnext do - local char=ischar(cnext,currentfont) - if char and marks[char] then - insertedmarks=insertedmarks+1 - cl=cnext - cnext=getnext(cnext) - else + if last then + local char,id=ischar(last,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + last=getnext(last) + elseif seq[n][char] then + if nl then + break + end + pre=getnext(pre) + else + notmatchpre[last]=true + break + end + end + else + notmatchpre[last]=true end - end - if not notmatchreplace[backtrackdisc] then - local ok=false - new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>l then + break + end + replace=getnext(replace) + else + notmatchreplace[last]=true + if notmatchpre[last] then + goto next + else + break + end + end + end + if notmatchpre[last] then + goto next + end end - end - if post then - setlink(posttail,cf) - else - post=cf - end - if replace then - setlink(replacetail,new) - else - replace=new - end - if hasglue then - setdiscchecked(backtrackdisc,pre,post,replace) + last=getnext(last) + else + goto next + end else - setdisc(backtrackdisc,pre,post,replace) - end - start=getprev(backtrackdisc) - sweephead[post]=getnext(clast) or false - sweephead[replace]=getnext(last) or false - else - local ok=false - head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck) - if ok then - done=true + goto next end + end end - return head,start,done -end -local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode) - local rule=ck[1] - local lookuptype=ck[8] or ck[2] - local nofseq=#ck[3] - local first=ck[4] - local last=ck[5] - local char=getchar(start) - logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping", - cref(dataset,sequence),rule,match and "matches" or "nomatch", - gref(char),first-1,last-first+1,nofseq-last,lookuptype, - discseen and "" or "no ",sweepnode and "" or "not ") -end -local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash) - local sweepnode=sweepnode - local sweeptype=sweeptype - local postreplace - local prereplace - local checkdisc - local discseen - if sweeptype then - if sweeptype=="replace" then - postreplace=true - prereplace=true - else - postreplace=sweeptype=="post" - prereplace=sweeptype=="pre" - end - checkdisc=getprev(head) - end - local currentfont=currentfont - local skipped - local startprev, - startnext=getboth(start) - local done - local nofcontexts=contexts.n - local startchar=nofcontext==1 or ischar(start,currentfont) - for k=1,nofcontexts do - local ck=contexts[k] - local seq=ck[3] - local f=ck[4] - if not startchar or not seq[f][startchar] then - goto next + if f>1 then + if startprev then + local prev=startprev + if prereplace and prev==checkdisc then + prev=getprev(sweepnode) end - local s=seq.n - local l=ck[5] - local current=start - local last=start - if l>f then - local discfound - local n=f+1 - last=startnext - while n<=l do - if postreplace and not last then - last=getnext(sweepnode) - sweeptype=nil + if prev then + local discfound + local n=f-1 + while n>=1 do + if prev then + local char,id=ischar(prev,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) + end + prev=getprev(prev) + elseif seq[n][char] then + if n>1 then + prev=getprev(prev) + end + n=n-1 + elseif discfound then + notmatchreplace[discfound]=true + if notmatchpost[discfound] then + goto next + else + break + end + else + goto next + end + elseif char==false then + if discfound then + notmatchreplace[discfound]=true + if notmatchpost[discfound] then + goto next + end + else + goto next end - if last then - local char,id=ischar(last,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - last=getnext(last) - elseif seq[n][char] then - if n=1 then + notmatchpost[prev]=true + end + else + notmatchpost[prev]=true + end + if replace then + while replacetail do + if seq[n][getchar(replacetail)] then + n=n-1 + if replacetail==replace or n<1 then + break else - goto next + replacetail=getprev(replacetail) end - elseif id==disc_code then - discseen=true - discfound=last - notmatchpre[last]=nil - notmatchpost[last]=true - notmatchreplace[last]=nil - local pre,post,replace=getdisc(last) - if pre then - local n=n - while pre do - if seq[n][getchar(pre)] then - n=n+1 - if n>l then - break - end - pre=getnext(pre) - else - notmatchpre[last]=true - break - end - end + else + notmatchreplace[prev]=true + if notmatchpost[prev] then + goto next else - notmatchpre[last]=true + break end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>l then - break - end - replace=getnext(replace) - else - notmatchreplace[last]=true - if notmatchpre[last] then - goto next - else - break - end - end - end - if notmatchpre[last] then - goto next - end - end - last=getnext(last) - else - goto next + end end + else + end + end + prev=getprev(prev) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[prev]) or sn[0xFFFC] then + n=n-1 + prev=getprev(prev) else - goto next + goto next end + elseif seq[n][0xFFFC] then + n=n-1 + prev=getprev(prev) + else + goto next + end + else + goto next end - end - if f>1 then - if startprev then - local prev=startprev - if prereplace and prev==checkdisc then - prev=getprev(sweepnode) + end + else + goto next + end + else + goto next + end + end + if s>l then + local current=last and getnext(last) + if not current and postreplace then + current=getnext(sweepnode) + end + if current then + local discfound + local n=l+1 + while n<=s do + if current then + local char,id=ischar(current,currentfont) + if char then + if skiphash and skiphash[char] then + skipped=true + if trace_skips then + show_skip(dataset,sequence,char,ck,classes[char]) end - if prev then - local discfound - local n=f-1 - while n>=1 do - if prev then - local char,id=ischar(prev,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - prev=getprev(prev) - elseif seq[n][char] then - if n>1 then - prev=getprev(prev) - end - n=n-1 - elseif discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - else - break - end - else - goto next - end - elseif char==false then - if discfound then - notmatchreplace[discfound]=true - if notmatchpost[discfound] then - goto next - end - else - goto next - end - break - elseif id==disc_code then - discseen=true - discfound=prev - notmatchpre[prev]=true - notmatchpost[prev]=nil - notmatchreplace[prev]=nil - local pre,post,replace,pretail,posttail,replacetail=getdisc(prev,true) - if pre~=start and post~=start and replace~=start then - if post then - local n=n - while posttail do - if seq[n][getchar(posttail)] then - n=n-1 - if posttail==post or n<1 then - break - else - posttail=getprev(posttail) - end - else - notmatchpost[prev]=true - break - end - end - if n>=1 then - notmatchpost[prev]=true - end - else - notmatchpost[prev]=true - end - if replace then - while replacetail do - if seq[n][getchar(replacetail)] then - n=n-1 - if replacetail==replace or n<1 then - break - else - replacetail=getprev(replacetail) - end - else - notmatchreplace[prev]=true - if notmatchpost[prev] then - goto next - else - break - end - end - end - else - notmatchreplace[prev]=true - end - end - prev=getprev(prev) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[prev]) or sn[0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next - end - elseif seq[n][0xFFFC] then - n=n-1 - prev=getprev(prev) - else - goto next - end - else - goto next - end - end + current=getnext(current) + elseif seq[n][char] then + if nl then - local current=last and getnext(last) - if not current and postreplace then - current=getnext(sweepnode) - end - if current then - local discfound - local n=l+1 - while n<=s do - if current then - local char,id=ischar(current,currentfont) - if char then - if skiphash and skiphash[char] then - skipped=true - if trace_skips then - show_skip(dataset,sequence,char,ck,classes[char]) - end - current=getnext(current) - elseif seq[n][char] then - if ns then - break - else - pre=getnext(pre) - end - else - notmatchpre[current]=true - break - end - end - if n<=s then - notmatchpre[current]=true - end - else - notmatchpre[current]=true - end - if replace then - while replace do - if seq[n][getchar(replace)] then - n=n+1 - if n>s then - break - else - replace=getnext(replace) - end - else - notmatchreplace[current]=true - if notmatchpre[current] then - goto next - else - break - end - end - end - else - notmatchreplace[current]=true - end - current=getnext(current) - elseif id==glue_code then - local sn=seq[n] - if (sn[32] and spaces[current]) or sn[0xFFFC] then - n=n+1 - current=getnext(current) - else - goto next - end - elseif seq[n][0xFFFC] then - n=n+1 - current=getnext(current) - else - goto next - end + end + elseif char==false then + if discfound then + notmatchreplace[discfound]=true + if notmatchpre[discfound] then + goto next + else + break + end + else + goto next + end + elseif id==disc_code then + discseen=true + discfound=current + notmatchpre[current]=nil + notmatchpost[current]=true + notmatchreplace[current]=nil + local pre,post,replace=getdisc(current) + if pre then + local n=n + while pre do + if seq[n][getchar(pre)] then + n=n+1 + if n>s then + break else - goto next + pre=getnext(pre) end + else + notmatchpre[current]=true + break + end end - else + if n<=s then + notmatchpre[current]=true + end + else + notmatchpre[current]=true + end + if replace then + while replace do + if seq[n][getchar(replace)] then + n=n+1 + if n>s then + break + else + replace=getnext(replace) + end + else + notmatchreplace[current]=true + if notmatchpre[current] then + goto next + else + break + end + end + end + else + end + current=getnext(current) + elseif id==glue_code then + local sn=seq[n] + if (sn[32] and spaces[current]) or sn[0xFFFC] then + n=n+1 + current=getnext(current) + else goto next + end + elseif seq[n][0xFFFC] then + n=n+1 + current=getnext(current) + else + goto next end + else + goto next + end end - if trace_contexts then - chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode) - end - if discseen or sweepnode then - head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck) - else - head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck) - end - if done then - break - end - ::next:: + else + goto next + end end - if discseen then - notmatchpre={} - notmatchpost={} - notmatchreplace={} + if trace_contexts then + chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode) end - return head,start,done + if discseen or sweepnode then + head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck) + else + head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck) + end + if done then + break + end + ::next:: + end + if discseen then + notmatchpre={} + notmatchpost={} + notmatchreplace={} + end + return head,start,done end handlers.gsub_context=handle_contextchain handlers.gsub_contextchain=handle_contextchain @@ -26428,17 +27808,17 @@ handlers.gsub_reversecontextchain=handle_contextchain handlers.gpos_contextchain=handle_contextchain handlers.gpos_context=handle_contextchain local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash) - local steps=currentlookup.steps - local nofsteps=currentlookup.nofsteps - if nofsteps>1 then - reportmoresteps(dataset,sequence) - end - local l=steps[1].coverage[getchar(start)] - if l then - return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash) - else - return head,start,false - end + local steps=currentlookup.steps + local nofsteps=currentlookup.nofsteps + if nofsteps>1 then + reportmoresteps(dataset,sequence) + end + local l=steps[1].coverage[getchar(start)] + if l then + return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash) + else + return head,start,false + end end chainprocs.gsub_context=chained_contextchain chainprocs.gsub_contextchain=chained_contextchain @@ -26449,1259 +27829,1270 @@ local missing=setmetatableindex("table") local logwarning=report_process local resolved={} local function logprocess(...) - if trace_steps then - registermessage(...) - if trace_steps=="silent" then - return - end + if trace_steps then + registermessage(...) + if trace_steps=="silent" then + return end - report_process(...) + end + report_process(...) end local sequencelists=setmetatableindex(function(t,font) - local sequences=fontdata[font].resources.sequences - if not sequences or not next(sequences) then - sequences=false - end - t[font]=sequences - return sequences + local sequences=fontdata[font].resources.sequences + if not sequences or not next(sequences) then + sequences=false + end + t[font]=sequences + return sequences end) do - local autofeatures=fonts.analyzers.features - local featuretypes=otf.tables.featuretypes - local defaultscript=otf.features.checkeddefaultscript - local defaultlanguage=otf.features.checkeddefaultlanguage - local wildcard="*" - local default="dflt" - local function initialize(sequence,script,language,enabled,autoscript,autolanguage) - local features=sequence.features - if features then - local order=sequence.order - if order then - local featuretype=featuretypes[sequence.type or "unknown"] - for i=1,#order do - local kind=order[i] - local valid=enabled[kind] - if valid then - local scripts=features[kind] - local languages=scripts and ( - scripts[script] or - scripts[wildcard] or - (autoscript and defaultscript(featuretype,autoscript,scripts)) - ) - local enabled=languages and ( - languages[language] or - languages[wildcard] or - (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) - ) - if enabled then - return { valid,autofeatures[kind] or false,sequence,kind } - end - end - end - else + local autofeatures=fonts.analyzers.features + local featuretypes=otf.tables.featuretypes + local defaultscript=otf.features.checkeddefaultscript + local defaultlanguage=otf.features.checkeddefaultlanguage + local wildcard="*" + local default="dflt" + local function initialize(sequence,script,language,enabled,autoscript,autolanguage) + local features=sequence.features + if features then + local order=sequence.order + if order then + local featuretype=featuretypes[sequence.type or "unknown"] + for i=1,#order do + local kind=order[i] + local valid=enabled[kind] + if valid then + local scripts=features[kind] + local languages=scripts and ( + scripts[script] or + scripts[wildcard] or + (autoscript and defaultscript(featuretype,autoscript,scripts)) + ) + local enabled=languages and ( + languages[language] or + languages[wildcard] or + (autolanguage and defaultlanguage(featuretype,autolanguage,languages)) + ) + if enabled then + return { valid,autofeatures[kind] or false,sequence,kind } end + end end - return false + else + end end - function otf.dataset(tfmdata,font) - local shared=tfmdata.shared - local properties=tfmdata.properties - local language=properties.language or "dflt" - local script=properties.script or "dflt" - local enabled=shared.features - local autoscript=enabled and enabled.autoscript - local autolanguage=enabled and enabled.autolanguage - local res=resolved[font] - if not res then - res={} - resolved[font]=res - end - local rs=res[script] - if not rs then - rs={} - res[script]=rs - end - local rl=rs[language] - if not rl then - rl={ - } - rs[language]=rl - local sequences=tfmdata.resources.sequences - if sequences then - for s=1,#sequences do - local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) - if v then - rl[#rl+1]=v - end - end - end + return false + end + function otf.dataset(tfmdata,font) + local shared=tfmdata.shared + local properties=tfmdata.properties + local language=properties.language or "dflt" + local script=properties.script or "dflt" + local enabled=shared.features + local autoscript=enabled and enabled.autoscript + local autolanguage=enabled and enabled.autolanguage + local res=resolved[font] + if not res then + res={} + resolved[font]=res + end + local rs=res[script] + if not rs then + rs={} + res[script]=rs + end + local rl=rs[language] + if not rl then + rl={ + } + rs[language]=rl + local sequences=tfmdata.resources.sequences + if sequences then + for s=1,#sequences do + local v=enabled and initialize(sequences[s],script,language,enabled,autoscript,autolanguage) + if v then + rl[#rl+1]=v + end end - return rl + end end + return rl + end end local function report_disc(what,n) - report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) + report_run("%s: %s > %s",what,n,languages.serializediscretionary(n)) end local function kernrun(disc,k_run,font,attr,...) - if trace_kernruns then - report_disc("kern",disc) - end - local prev,next=getboth(disc) - local nextstart=next - local done=false - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local prevmarks=prev - while prevmarks do - local char=ischar(prevmarks,font) - if char and marks[char] then - prevmarks=getprev(prevmarks) - else - break - end + if trace_kernruns then + report_disc("kern",disc) + end + local prev,next=getboth(disc) + local nextstart=next + local done=false + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local prevmarks=prev + while prevmarks do + local char=ischar(prevmarks,font) + if char and marks[char] then + prevmarks=getprev(prevmarks) + else + break + end + end + if prev and not ischar(prev,font) then + prev=false + end + if next and not ischar(next,font) then + next=false + end + if pre then + if k_run(pre,"injections",nil,font,attr,...) then + done=true + end + if prev then + setlink(prev,pre) + if k_run(prevmarks,"preinjections",pre,font,attr,...) then + done=true + end + setprev(pre) + setlink(prev,disc) + end + end + if post then + if k_run(post,"injections",nil,font,attr,...) then + done=true + end + if next then + setlink(posttail,next) + if k_run(posttail,"postinjections",next,font,attr,...) then + done=true + end + setnext(posttail) + setlink(disc,next) + end + end + if replace then + if k_run(replace,"injections",nil,font,attr,...) then + done=true + end + if prev then + setlink(prev,replace) + if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then + done=true + end + setprev(replace) + setlink(prev,disc) + end + if next then + setlink(replacetail,next) + if k_run(replacetail,"replaceinjections",next,font,attr,...) then + done=true + end + setnext(replacetail) + setlink(disc,next) + end + elseif prev and next then + setlink(prev,next) + if k_run(prevmarks,"emptyinjections",next,font,attr,...) then + done=true + end + setlink(prev,disc,next) + end + if done and trace_testruns then + report_disc("done",disc) + end + return nextstart,done +end +local function comprun(disc,c_run,...) + if trace_compruns then + report_disc("comp",disc) + end + local pre,post,replace=getdisc(disc) + local renewed=false + if pre then + sweepnode=disc + sweeptype="pre" + local new,done=c_run(pre,...) + if done then + pre=new + renewed=true + end + end + if post then + sweepnode=disc + sweeptype="post" + local new,done=c_run(post,...) + if done then + post=new + renewed=true + end + end + if replace then + sweepnode=disc + sweeptype="replace" + local new,done=c_run(replace,...) + if done then + replace=new + renewed=true + end + end + sweepnode=nil + sweeptype=nil + if renewed then + if trace_testruns then + report_disc("done",disc) end - if prev and not ischar(prev,font) then - prev=false + setdisc(disc,pre,post,replace) + end + return getnext(disc),renewed +end +local function testrun(disc,t_run,c_run,...) + if trace_testruns then + report_disc("test",disc) + end + local prev,next=getboth(disc) + if not next then + return + end + local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) + local renewed=false + if (post or replace) and prev then + if post then + setlink(posttail,next) + else + post=next end - if next and not ischar(next,font) then - next=false + if replace then + setlink(replacetail,next) + else + replace=next + end + local d_post=t_run(post,next,...) + local d_replace=t_run(replace,next,...) + if d_post>0 or d_replace>0 then + local d=d_replace>d_post and d_replace or d_post + local head=getnext(disc) + local tail=head + for i=2,d do + local nx=getnext(tail) + local id=getid(nx) + if id==disc_code then + head,tail=flattendisk(head,nx) + elseif id==glyph_code then + tail=nx + else + break + end + end + next=getnext(tail) + setnext(tail) + setprev(head) + local new=copy_node_list(head) + if posttail then + setlink(posttail,head) + else + post=head + end + if replacetail then + setlink(replacetail,new) + else + replace=new + end + else + if posttail then + setnext(posttail) + else + post=nil + end + if replacetail then + setnext(replacetail) + else + replace=nil + end + end + setlink(disc,next) + end + if trace_testruns then + report_disc("more",disc) + end + if pre then + sweepnode=disc + sweeptype="pre" + local new,ok=c_run(pre,...) + if ok then + pre=new + renewed=true + end + end + if post then + sweepnode=disc + sweeptype="post" + local new,ok=c_run(post,...) + if ok then + post=new + renewed=true + end + end + if replace then + sweepnode=disc + sweeptype="replace" + local new,ok=c_run(replace,...) + if ok then + replace=new + renewed=true end - if pre then - if k_run(pre,"injections",nil,font,attr,...) then - done=true - end - if prev then - setlink(prev,pre) - if k_run(prevmarks,"preinjections",pre,font,attr,...) then - done=true - end - setprev(pre) - setlink(prev,disc) - end + end + sweepnode=nil + sweeptype=nil + if renewed then + setdisc(disc,pre,post,replace) + if trace_testruns then + report_disc("done",disc) end - if post then - if k_run(post,"injections",nil,font,attr,...) then + end + return getnext(disc),renewed +end +local nesting=0 +local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + local done=false + local sweep=sweephead[head] + if sweep then + start=sweep + sweephead[head]=false + else + start=head + end + while start do + local char,id=ischar(start,font) + if char then + local a + if attr then + a=getattr(start,0) + end + if not a or (a==attr) then + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then done=true + end end - if next then - setlink(posttail,next) - if k_run(posttail,"postinjections",next,font,attr,...) then - done=true - end - setnext(posttail) - setlink(disc,next) + if start then + start=getnext(start) end + else + start=getnext(start) + end + elseif char==false then + return head,done + elseif sweep then + return head,done + else + start=getnext(start) end - if replace then - if k_run(replace,"injections",nil,font,attr,...) then - done=true - end - if prev then - setlink(prev,replace) - if k_run(prevmarks,"replaceinjections",replace,font,attr,...) then - done=true + end + return head,done +end +local function t_run_single(start,stop,font,attr,lookupcache) + local lastd=nil + while start~=stop do + local char=ischar(start,font) + if char then + local a + if attr then + a=getattr(start,0) + end + local startnext=getnext(start) + if not a or (a==attr) then + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil end - setprev(replace) - setlink(prev,disc) - end - if next then - setlink(replacetail,next) - if k_run(replacetail,"replaceinjections",next,font,attr,...) then - done=true + end + local l=nil + local d=0 + while s do + local char=ischar(s,font) + if char then + local lg=lookupmatch[char] + if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end + l=lg + s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end + else + break + end + else + break end - setnext(replacetail) - setlink(disc,next) - end - elseif prev and next then - setlink(prev,next) - if k_run(prevmarks,"emptyinjections",next,font,attr,...) then - done=true + end + if l and l.ligature then + lastd=d + end + else end - setlink(prev,disc,next) - end - if done and trace_testruns then - report_disc("done",disc) + else + end + if lastd then + return lastd + end + start=startnext + else + break end - return nextstart,done + end + return 0 end -local function comprun(disc,c_run,...) - if trace_compruns then - report_disc("comp",disc) - end - local pre,post,replace=getdisc(disc) - local renewed=false - if pre then - sweepnode=disc - sweeptype="pre" - local new,done=c_run(pre,...) - if done then - pre=new - renewed=true - end - end - if post then - sweepnode=disc - sweeptype="post" - local new,done=c_run(post,...) - if done then - post=new - renewed=true +local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + local a + if attr then + a=getattr(sub,0) + end + if not a or (a==attr) then + for n in nextnode,sub do + if n==last then + break + end + local char=ischar(n) + if char then + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) + if ok then + return true + end end + end end - if replace then - sweepnode=disc - sweeptype="replace" - local new,done=c_run(replace,...) - if done then - replace=new - renewed=true + end +end +local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + local done=false + local sweep=sweephead[head] + if sweep then + start=sweep + sweephead[head]=false + else + start=head + end + while start do + local char=ischar(start,font) + if char then + local a + if attr then + a=getattr(start,0) + end + if not a or (a==attr) then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + done=true + break + elseif not start then + break + end + end end - end - sweepnode=nil - sweeptype=nil - if renewed then - if trace_testruns then - report_disc("done",disc) + if start then + start=getnext(start) end - setdisc(disc,pre,post,replace) + else + start=getnext(start) + end + elseif char==false then + return head,done + elseif sweep then + return head,done + else + start=getnext(start) end - return getnext(disc),renewed + end + return head,done end -local function testrun(disc,t_run,c_run,...) - if trace_testruns then - report_disc("test",disc) - end - local prev,next=getboth(disc) - if not next then - return - end - local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true) - local renewed=false - if (post or replace) and prev then - if post then - setlink(posttail,next) - else - post=next - end - if replace then - setlink(replacetail,next) - else - replace=next - end - local d_post=t_run(post,next,...) - local d_replace=t_run(replace,next,...) - if d_post>0 or d_replace>0 then - local d=d_replace>d_post and d_replace or d_post - local head=getnext(disc) - local tail=head - for i=1,d do - local nx=getnext(tail) - local id=getid(nx) - if id==disc_code then - head,tail=flattendisk(head,nx) - elseif id==glyph_code then - tail=nx +local function t_run_multiple(start,stop,font,attr,steps,nofsteps) + local lastd=nil + while start~=stop do + local char=ischar(start,font) + if char then + local a + if attr then + a=getattr(start,0) + end + local startnext=getnext(start) + if not a or (a==attr) then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local s=startnext + local ss=nil + local sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end + local l=nil + local d=0 + while s do + local char=ischar(s) + if char then + local lg=lookupmatch[char] + if lg then + if sstop then + d=1 + elseif d>0 then + d=d+1 + end + l=lg + s=getnext(s) + sstop=s==stop + if not s then + s=ss + ss=nil + end + while getid(s)==disc_code do + ss=getnext(s) + s=getfield(s,"replace") + if not s then + s=ss + ss=nil + end + end else - break + break end + else + break + end end - next=getnext(tail) - setnext(tail) - setprev(head) - local new=copy_node_list(head) - if posttail then - setlink(posttail,head) - else - post=head - end - if replacetail then - setlink(replacetail,new) - else - replace=new - end - else - if posttail then - setnext(posttail) - else - post=nil - end - if replacetail then - setnext(replacetail) - else - replace=nil + if l and l.ligature then + lastd=d end + end end - setlink(disc,next) - end - if trace_testruns then - report_disc("more",disc) - end - if pre then - sweepnode=disc - sweeptype="pre" - local new,ok=c_run(pre,...) - if ok then - pre=new - renewed=true - end - end - if post then - sweepnode=disc - sweeptype="post" - local new,ok=c_run(post,...) - if ok then - post=new - renewed=true - end - end - if replace then - sweepnode=disc - sweeptype="replace" - local new,ok=c_run(replace,...) - if ok then - replace=new - renewed=true - end + else + end + if lastd then + return lastd + end + start=startnext + else + break end - sweepnode=nil - sweeptype=nil - if renewed then - setdisc(disc,pre,post,replace) - if trace_testruns then - report_disc("done",disc) + end + return 0 +end +local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + local a + if attr then + a=getattr(sub,0) + end + if not a or (a==attr) then + for n in nextnode,sub do + if n==last then + break + end + local char=ischar(n) + if char then + for i=1,nofsteps do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) + if ok then + return true + end + end end + end end - return getnext(disc),renewed + end end -local nesting=0 -local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local done=false - local sweep=sweephead[head] - if sweep then - start=sweep - sweephead[head]=false +local txtdirstate,pardirstate do + local getdirection=nuts.getdirection + local lefttoright=0 + local righttoleft=1 + txtdirstate=function(start,stack,top,rlparmode) + local dir,pop=getdirection(start) + if pop then + if top==1 then + return 0,rlparmode + else + top=top-1 + if stack[top]==righttoleft then + return top,-1 + else + return top,1 + end + end + elseif dir==lefttoright then + top=top+1 + stack[top]=lefttoright + return top,1 + elseif dir==righttoleft then + top=top+1 + stack[top]=righttoleft + return top,-1 else - start=head + return top,rlparmode + end + end + pardirstate=function(start) + local dir=getdirection(start) + if dir==lefttoright then + return 1,1 + elseif dir==righttoleft then + return -1,-1 + elseif dir=="TLT" then + return 1,1 + elseif dir=="TRT" then + return -1,-1 + else + return 0,0 end - while start do - local char,id=ischar(start,font) - if char then - local a - if attr then + end +end +otf.helpers=otf.helpers or {} +otf.helpers.txtdirstate=txtdirstate +otf.helpers.pardirstate=pardirstate +do + local fastdisc=true + local testdics=false + directives.register("otf.fastdisc",function(v) fastdisc=v end) + local otfdataset=nil + local getfastdisc={ __index=function(t,k) + local v=usesfont(k,currentfont) + t[k]=v + return v + end } + local getfastspace={ __index=function(t,k) + local v=isspace(k,threshold) or false + t[k]=v + return v + end } + function otf.featuresprocessor(head,font,attr,direction,n) + local sequences=sequencelists[font] + nesting=nesting+1 + if nesting==1 then + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if not otfdataset then + otfdataset=otf.dataset + end + discs=fastdisc and n and n>1 and setmetatable({},getfastdisc) + spaces=setmetatable({},getfastspace) + elseif currentfont~=font then + report_warning("nested call with a different font, level %s, quitting",nesting) + nesting=nesting-1 + return head,false + end + if trace_steps then + checkstep(head) + end + local initialrl=0 + if getid(head)==localpar_code and getsubtype(head)==0 then + initialrl=pardirstate(head) + elseif direction==1 or direction=="TRT" then + initialrl=-1 + end + local datasets=otfdataset(tfmdata,font,attr) + local dirstack={ nil } + sweephead={} + for s=1,#datasets do + local dataset=datasets[s] + local attribute=dataset[2] + local sequence=dataset[3] + local rlparmode=initialrl + local topstack=0 + local typ=sequence.type + local gpossing=typ=="gpos_single" or typ=="gpos_pair" + local forcetestrun=typ=="gsub_ligature" + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local skiphash=sequence.skiphash + if not steps then + local h,ok=handler(head,dataset,sequence,initialrl,font,attr) + if h and h~=head then + head=h + end + elseif typ=="gsub_reversecontextchain" then + local start=find_node_tail(head) + local rlmode=0 + local merged=steps.merged + while start do + local char=ischar(start,font) + if char then + local m=merged[char] + if m then + local a + if attr then a=getattr(start,0) - end - if not a or (a==attr) then - local lookupmatch=lookupcache[char] - if lookupmatch then + end + if not a or (a==attr) then + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then local ok head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) if ok then - done=true + break end + end end if start then - start=getnext(start) + start=getprev(start) end + else + start=getprev(start) + end else - start=getnext(start) + start=getprev(start) end - elseif char==false then - return head,done - elseif sweep then - return head,done - else - start=getnext(start) + else + start=getprev(start) + end end - end - return head,done -end -local function t_run_single(start,stop,font,attr,lookupcache) - local lastd=nil - while start~=stop do - local char=ischar(start,font) - if char then - local a - if attr then - a=getattr(start,0) - end - local startnext=getnext(start) - if not a or (a==attr) then + else + local start=head + local rlmode=initialrl + if nofsteps==1 then + local step=steps[1] + local lookupcache=step.coverage + while start do + local char,id=ischar(start,font) + if char then + if skiphash and skiphash[char] then + start=getnext(start) + else local lookupmatch=lookupcache[char] if lookupmatch then - local s=startnext - local ss=nil - local sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getfield(s,"replace") - if not s then - s=ss - ss=nil - end - end - local l=nil - local d=0 - while s do - local char=ischar(s,font) - if char then - local lg=lookupmatch[char] - if lg then - if sstop then - d=1 - elseif d>0 then - d=d+1 - end - l=lg - s=getnext(s) - sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getfield(s,"replace") - if not s then - s=ss - ss=nil - end - end - else - break - end - else - break - end - end - if l and l.ligature then - lastd=d - end + local a + if attr then + if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then + a=true + end + elseif not attribute or getprop(start,a_state)==attribute then + a=true + end + if a then + local ok,df + head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + elseif start then + start=getnext(start) + end + else + start=getnext(start) + end + else + start=getnext(start) + end + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==disc_code then + if not discs or discs[start]==true then + local ok + if gpossing then + start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) + elseif forcetestrun then + start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) else + start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) end + else + start=getnext(start) + end + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) else + start=getnext(start) end - if lastd then - return lastd - end - start=startnext + end else - break - end - end - return 0 -end -local function k_run_single(sub,injection,last,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - local a - if attr then - a=getattr(sub,0) - end - if not a or (a==attr) then - for n in traverse_nodes(sub) do - if n==last then - break - end - local char=ischar(n) + local merged=steps.merged + while start do + local char,id=ischar(start,font) if char then - local lookupmatch=lookupcache[char] - if lookupmatch then - local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) - if ok then - return true - end - end - end - end - end -end -local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local done=false - local sweep=sweephead[head] - if sweep then - start=sweep - sweephead[head]=false - else - start=head - end - while start do - local char=ischar(start,font) - if char then - local a - if attr then - a=getattr(start,0) - end - if not a or (a==attr) then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - break + if skiphash and skiphash[char] then + start=getnext(start) + else + local m=merged[char] + if m then + local a + if attr then + if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then + a=true + end + elseif not attribute or getprop(start,a_state)==attribute then + a=true + end + if a then + local ok,df + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + head,start,ok,df=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if df then + break + elseif ok then + break elseif not start then - break + break end + end end - end - if start then + if df then + elseif start then + start=getnext(start) + end + else start=getnext(start) + end + else + start=getnext(start) end - else + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==disc_code then + if not discs or discs[start]==true then + local ok + if gpossing then + start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + elseif forcetestrun then + start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + else + start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) + end + else start=getnext(start) + end + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) end - elseif char==false then - return head,done - elseif sweep then - return head,done - else - start=getnext(start) + end end + end + if trace_steps then + registerstep(head) + end end - return head,done -end -local function t_run_multiple(start,stop,font,attr,steps,nofsteps) - local lastd=nil - while start~=stop do - local char=ischar(start,font) - if char then - local a - if attr then - a=getattr(start,0) - end - local startnext=getnext(start) - if not a or (a==attr) then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local s=startnext - local ss=nil - local sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getfield(s,"replace") - if not s then - s=ss - ss=nil - end - end - local l=nil - local d=0 - while s do - local char=ischar(s) - if char then - local lg=lookupmatch[char] - if lg then - if sstop then - d=1 - elseif d>0 then - d=d+1 - end - l=lg - s=getnext(s) - sstop=s==stop - if not s then - s=ss - ss=nil - end - while getid(s)==disc_code do - ss=getnext(s) - s=getfield(s,"replace") - if not s then - s=ss - ss=nil - end - end - else - break - end - else - break - end - end - if l and l.ligature then - lastd=d - end - end + nesting=nesting-1 + return head + end + function otf.datasetpositionprocessor(head,font,direction,dataset) + currentfont=font + tfmdata=fontdata[font] + descriptions=tfmdata.descriptions + characters=tfmdata.characters + local resources=tfmdata.resources + marks=resources.marks + classes=resources.classes + threshold, + factor=getthreshold(font) + checkmarks=tfmdata.properties.checkmarks + if type(dataset)=="number" then + dataset=otfdataset(tfmdata,font,0)[dataset] + end + local sequence=dataset[3] + local typ=sequence.type + local handler=handlers[typ] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local done=false + local dirstack={ nil } + local start=head + local initialrl=(direction==1 or direction=="TRT") and -1 or 0 + local rlmode=initialrl + local rlparmode=initialrl + local topstack=0 + local merged=steps.merged + local position=0 + while start do + local char,id=ischar(start,font) + if char then + position=position+1 + local m=merged[char] + if m then + if skiphash and skiphash[char] then + start=getnext(start) + else + for i=m[1],m[2] do + local step=steps[i] + local lookupcache=step.coverage + local lookupmatch=lookupcache[char] + if lookupmatch then + local ok + head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) + if ok then + break + elseif not start then + break end - else + end end - if lastd then - return lastd + if start then + start=getnext(start) end - start=startnext + end else - break - end + start=getnext(start) + end + elseif char==false or id==glue_code then + start=getnext(start) + elseif id==math_code then + start=getnext(end_of_math(start)) + elseif id==dir_code then + topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) + start=getnext(start) + else + start=getnext(start) + end end - return 0 + return head + end end -local function k_run_multiple(sub,injection,last,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - local a - if attr then - a=getattr(sub,0) - end - if not a or (a==attr) then - for n in traverse_nodes(sub) do - if n==last then - break - end - local char=ischar(n) - if char then - for i=1,nofsteps do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local h,d,ok=handler(sub,n,dataset,sequence,lookupmatch,rlmode,skiphash,step,injection) - if ok then - return true - end - end - end - end - end - end +local plugins={} +otf.plugins=plugins +local report=logs.reporter("fonts") +function otf.registerplugin(name,f) + if type(name)=="string" and type(f)=="function" then + plugins[name]={ name,f } + report() + report("plugin %a has been loaded, please be aware of possible side effects",name) + report() + if logs.pushtarget then + logs.pushtarget("log") + end + report("Plugins are not officially supported unless stated otherwise. This is because") + report("they bypass the regular font handling and therefore some features in ConTeXt") + report("(especially those related to fonts) might not work as expected or might not work") + report("at all. Some plugins are for testing and development only and might change") + report("whenever we feel the need for it.") + report() + if logs.poptarget then + logs.poptarget() + end + end end -local function txtdirstate(start,stack,top,rlparmode) - local nxt=getnext(start) - local dir=getdir(start) - if dir=="+TRT" then - top=top+1 - stack[top]=dir - return nxt,top,-1 - elseif dir=="+TLT" then - top=top+1 - stack[top]=dir - return nxt,top,1 - elseif dir=="-TRT" or dir=="-TLT" then - if top==1 then - return nxt,0,rlparmode - else - top=top-1 - if stack[top]=="+TRT" then - return nxt,top,-1 - else - return nxt,top,1 - end - end - else - return nxt,top,rlparmode - end -end -local function pardirstate(start) - local nxt=getnext(start) - local dir=getdir(start) - if dir=="TLT" then - return nxt,1,1 - elseif dir=="TRT" then - return nxt,-1,-1 - else - return nxt,0,0 - end -end -otf.helpers=otf.helpers or {} -otf.helpers.txtdirstate=txtdirstate -otf.helpers.pardirstate=pardirstate -do - local fastdisc=true - local testdics=false - directives.register("otf.fastdisc",function(v) fastdisc=v end) - local otfdataset=nil - local getfastdisc={ __index=function(t,k) - local v=usesfont(k,currentfont) - t[k]=v - return v - end } - local getfastspace={ __index=function(t,k) - local v=isspace(k,threshold) or false - t[k]=v - return v - end } - function otf.featuresprocessor(head,font,attr,direction,n) - local sequences=sequencelists[font] - nesting=nesting+1 - if nesting==1 then - currentfont=font - tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - local resources=tfmdata.resources - marks=resources.marks - classes=resources.classes - threshold, - factor=getthreshold(font) - checkmarks=tfmdata.properties.checkmarks - if not otfdataset then - otfdataset=otf.dataset - end - discs=fastdisc and n and n>1 and setmetatable({},getfastdisc) - spaces=setmetatable({},getfastspace) - elseif currentfont~=font then - report_warning("nested call with a different font, level %s, quitting",nesting) - nesting=nesting-1 - return head,false - end - local head=tonut(head) - if trace_steps then - checkstep(head) - end - local initialrl=direction=="TRT" and -1 or 0 - local done=false - local datasets=otfdataset(tfmdata,font,attr) - local dirstack={} - sweephead={} - for s=1,#datasets do - local dataset=datasets[s] - local attribute=dataset[2] - local sequence=dataset[3] - local rlparmode=initialrl - local topstack=0 - local typ=sequence.type - local gpossing=typ=="gpos_single" or typ=="gpos_pair" - local forcetestrun=typ=="gsub_ligature" - local handler=handlers[typ] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local skiphash=sequence.skiphash - if not steps then - local h,ok=handler(head,dataset,sequence,initialrl,font,attr) - if ok then - done=true - end - if h and h~=head then - head=h - end - elseif typ=="gsub_reversecontextchain" then - local start=find_node_tail(head) - local rlmode=0 - local merged=steps.merged - while start do - local char=ischar(start,font) - if char then - local m=merged[char] - if m then - local a - if attr then - a=getattr(start,0) - end - if not a or (a==attr) then - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - break - end - end - end - if start then - start=getprev(start) - end - else - start=getprev(start) - end - else - start=getprev(start) - end - else - start=getprev(start) - end - end - else - local start=head - local rlmode=initialrl - if nofsteps==1 then - local step=steps[1] - local lookupcache=step.coverage - while start do - local char,id=ischar(start,font) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - local lookupmatch=lookupcache[char] - if lookupmatch then - local a - if attr then - if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then - a=true - end - elseif not attribute or getprop(start,a_state)==attribute then - a=true - end - if a then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - end - if start then - start=getnext(start) - end - else - start=getnext(start) - end - else - start=getnext(start) - end - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==disc_code then - if not discs or discs[start]==true then - local ok - if gpossing then - start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - elseif forcetestrun then - start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - else - start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler) - end - if ok then - done=true - end - else - start=getnext(start) - end - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - start,topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - elseif id==localpar_code then - start,rlparmode,rlmode=pardirstate(start) - else - start=getnext(start) - end - end - else - local merged=steps.merged - while start do - local char,id=ischar(start,font) - if char then - if skiphash and skiphash[char] then - start=getnext(start) - else - local m=merged[char] - if m then - local a - if attr then - if getattr(start,0)==attr and (not attribute or getprop(start,a_state)==attribute) then - a=true - end - elseif not attribute or getprop(start,a_state)==attribute then - a=true - end - if a then - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - done=true - break - elseif not start then - break - end - end - end - if start then - start=getnext(start) - end - else - start=getnext(start) - end - else - start=getnext(start) - end - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==disc_code then - if not discs or discs[start]==true then - local ok - if gpossing then - start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - elseif forcetestrun then - start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - else - start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler) - end - if ok then - done=true - end - else - start=getnext(start) - end - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - start,topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - elseif id==localpar_code then - start,rlparmode,rlmode=pardirstate(start) - else - start=getnext(start) - end - end - end - end - if trace_steps then - registerstep(head) - end - end - nesting=nesting-1 - head=tonode(head) - return head,done - end - function otf.datasetpositionprocessor(head,font,direction,dataset) - currentfont=font - tfmdata=fontdata[font] - descriptions=tfmdata.descriptions - characters=tfmdata.characters - local resources=tfmdata.resources - marks=resources.marks - classes=resources.classes - threshold, - factor=getthreshold(font) - checkmarks=tfmdata.properties.checkmarks - if type(dataset)=="number" then - dataset=otfdataset(tfmdata,font,0)[dataset] - end - local sequence=dataset[3] - local typ=sequence.type - local handler=handlers[typ] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local head=tonut(head) - local done=false - local dirstack={} - local start=head - local initialrl=direction=="TRT" and -1 or 0 - local rlmode=initialrl - local rlparmode=initialrl - local topstack=0 - local merged=steps.merged - local position=0 - while start do - local char,id=ischar(start,font) - if char then - position=position+1 - local m=merged[char] - if m then - if skiphash and skiphash[char] then - start=getnext(start) - else - for i=m[1],m[2] do - local step=steps[i] - local lookupcache=step.coverage - local lookupmatch=lookupcache[char] - if lookupmatch then - local ok - head,start,ok=handler(head,start,dataset,sequence,lookupmatch,rlmode,skiphash,step) - if ok then - break - elseif not start then - break - end - end - end - if start then - start=getnext(start) - end - end - else - start=getnext(start) - end - elseif char==false or id==glue_code then - start=getnext(start) - elseif id==math_code then - start=getnext(end_of_math(start)) - elseif id==dir_code then - start,topstack,rlmode=txtdirstate(start,dirstack,topstack,rlparmode) - elseif id==localpar_code then - start,rlparmode,rlmode=pardirstate(start) - else - start=getnext(start) - end - end - return tonode(head) - end -end -local plugins={} -otf.plugins=plugins -function otf.registerplugin(name,f) - if type(name)=="string" and type(f)=="function" then - plugins[name]={ name,f } - end -end -function otf.plugininitializer(tfmdata,value) - if type(value)=="string" then - tfmdata.shared.plugin=plugins[value] - end +function otf.plugininitializer(tfmdata,value) + if type(value)=="string" then + tfmdata.shared.plugin=plugins[value] + end end function otf.pluginprocessor(head,font,attr,direction) - local s=fontdata[font].shared - local p=s and s.plugin - if p then - if trace_plugins then - report_process("applying plugin %a",p[1]) - end - return p[2](head,font,attr,direction) - else - return head,false - end + local s=fontdata[font].shared + local p=s and s.plugin + if p then + if trace_plugins then + report_process("applying plugin %a",p[1]) + end + return p[2](head,font,attr,direction) + else + return head,false + end end function otf.featuresinitializer(tfmdata,value) end registerotffeature { - name="features", - description="features", - default=true, - initializers={ - position=1, - node=otf.featuresinitializer, - plug=otf.plugininitializer, - }, - processors={ - node=otf.featuresprocessor, - plug=otf.pluginprocessor, - } + name="features", + description="features", + default=true, + initializers={ + position=1, + node=otf.featuresinitializer, + plug=otf.plugininitializer, + }, + processors={ + node=otf.featuresprocessor, + plug=otf.pluginprocessor, + } } otf.handlers=handlers local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end local tag="kern" if fontfeatures then - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local features=fontfeatures[font] - local enabled=features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head,enabled - end + function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) + local features=fontfeatures[font] + local enabled=features and features.spacekern and features[tag] + if enabled then + setspacekerns(font,sequence) + end + return head,enabled + end else - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local shared=fontdata[font].shared - local features=shared and shared.features - local enabled=features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head,enabled + function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) + local shared=fontdata[font].shared + local features=shared and shared.features + local enabled=features and features.spacekern and features[tag] + if enabled then + setspacekerns(font,sequence) end + return head,enabled + end end local function hasspacekerns(data) - local resources=data.resources - local sequences=resources.sequences - local validgpos=resources.features.gpos - if validgpos and sequences then - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps and sequence.features[tag] then - local kind=sequence.type - if kind=="gpos_pair" or kind=="gpos_single" then - for i=1,#steps do - local step=steps[i] - local coverage=step.coverage - local rules=step.rules - if rules then - elseif not coverage then - elseif kind=="gpos_single" then - elseif kind=="gpos_pair" then - local format=step.format - if format=="move" or format=="kern" then - local kerns=coverage[32] - if kerns then - return true - end - for k,v in next,coverage do - if v[32] then - return true - end - end - elseif format=="pair" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - local one=v[1] - if one and one~=true then - return true - end - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - local one=kern[1] - if one and one~=true then - return true - end - end - end - end - end + local resources=data.resources + local sequences=resources.sequences + local validgpos=resources.features.gpos + if validgpos and sequences then + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps and sequence.features[tag] then + local kind=sequence.type + if kind=="gpos_pair" or kind=="gpos_single" then + for i=1,#steps do + local step=steps[i] + local coverage=step.coverage + local rules=step.rules + if rules then + elseif not coverage then + elseif kind=="gpos_single" then + elseif kind=="gpos_pair" then + local format=step.format + if format=="move" or format=="kern" then + local kerns=coverage[32] + if kerns then + return true + end + for k,v in next,coverage do + if v[32] then + return true + end + end + elseif format=="pair" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + local one=v[1] + if one and one~=true then + return true + end + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + local one=kern[1] + if one and one~=true then + return true end + end end + end end + end end + end end - return false + end + return false end otf.readers.registerextender { - name="spacekerns", - action=function(data) - data.properties.hasspacekerns=hasspacekerns(data) - end + name="spacekerns", + action=function(data) + data.properties.hasspacekerns=hasspacekerns(data) + end } local function spaceinitializer(tfmdata,value) - local resources=tfmdata.resources - local spacekerns=resources and resources.spacekerns - if value and spacekerns==nil then - local rawdata=tfmdata.shared and tfmdata.shared.rawdata - local properties=rawdata.properties - if properties and properties.hasspacekerns then - local sequences=resources.sequences - local validgpos=resources.features.gpos - if validgpos and sequences then - local left={} - local right={} - local last=0 - local feat=nil - for i=1,#sequences do - local sequence=sequences[i] - local steps=sequence.steps - if steps then - local kern=sequence.features[tag] - if kern then - local kind=sequence.type - if kind=="gpos_pair" or kind=="gpos_single" then - if feat then - for script,languages in next,kern do - local f=feat[script] - if f then - for l in next,languages do - f[l]=true - end - else - feat[script]=languages - end - end - else - feat=kern - end - for i=1,#steps do - local step=steps[i] - local coverage=step.coverage - local rules=step.rules - if rules then - elseif not coverage then - elseif kind=="gpos_single" then - elseif kind=="gpos_pair" then - local format=step.format - if format=="move" or format=="kern" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - right[k]=v - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - left[k]=kern - end - end - elseif format=="pair" then - local kerns=coverage[32] - if kerns then - for k,v in next,kerns do - local one=v[1] - if one and one~=true then - right[k]=one[3] - end - end - end - for k,v in next,coverage do - local kern=v[32] - if kern then - local one=kern[1] - if one and one~=true then - left[k]=one[3] - end - end - end - end - end - end - last=i - end - else - end + local resources=tfmdata.resources + local spacekerns=resources and resources.spacekerns + if value and spacekerns==nil then + local rawdata=tfmdata.shared and tfmdata.shared.rawdata + local properties=rawdata.properties + if properties and properties.hasspacekerns then + local sequences=resources.sequences + local validgpos=resources.features.gpos + if validgpos and sequences then + local left={} + local right={} + local last=0 + local feat=nil + for i=1,#sequences do + local sequence=sequences[i] + local steps=sequence.steps + if steps then + local kern=sequence.features[tag] + if kern then + local kind=sequence.type + if kind=="gpos_pair" or kind=="gpos_single" then + if feat then + for script,languages in next,kern do + local f=feat[script] + if f then + for l in next,languages do + f[l]=true + end + else + feat[script]=languages end + end + else + feat=kern end - left=next(left) and left or false - right=next(right) and right or false - if left or right then - spacekerns={ - left=left, - right=right, - } - if last>0 then - local triggersequence={ - features={ [tag]=feat or { dflt={ dflt=true,} } }, - flags=noflags, - name="trigger_space_kerns", - order={ tag }, - type="trigger_space_kerns", - left=left, - right=right, - } - insert(sequences,last,triggersequence) + for i=1,#steps do + local step=steps[i] + local coverage=step.coverage + local rules=step.rules + if rules then + elseif not coverage then + elseif kind=="gpos_single" then + elseif kind=="gpos_pair" then + local format=step.format + if format=="move" or format=="kern" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + right[k]=v + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + left[k]=kern + end + end + elseif format=="pair" then + local kerns=coverage[32] + if kerns then + for k,v in next,kerns do + local one=v[1] + if one and one~=true then + right[k]=one[3] + end + end + end + for k,v in next,coverage do + local kern=v[32] + if kern then + local one=kern[1] + if one and one~=true then + left[k]=one[3] + end + end + end end + end end + last=i + end + else end + end + end + left=next(left) and left or false + right=next(right) and right or false + if left or right then + spacekerns={ + left=left, + right=right, + } + if last>0 then + local triggersequence={ + features={ [tag]=feat or { dflt={ dflt=true,} } }, + flags=noflags, + name="trigger_space_kerns", + order={ tag }, + type="trigger_space_kerns", + left=left, + right=right, + } + insert(sequences,last,triggersequence) + end end - resources.spacekerns=spacekerns + end end - return spacekerns + resources.spacekerns=spacekerns + end + return spacekerns end registerotffeature { - name="spacekern", - description="space kern injection", - default=true, - initializers={ - node=spaceinitializer, - }, + name="spacekern", + description="space kern injection", + default=true, + initializers={ + node=spaceinitializer, + }, } local function markinitializer(tfmdata,value) - local properties=tfmdata.properties - properties.checkmarks=value + local properties=tfmdata.properties + properties.checkmarks=value end registerotffeature { - name="checkmarks", - description="check mark widths", - default=true, - initializers={ - node=markinitializer, - }, + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, } end -- closure @@ -27709,17 +29100,17 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-osd']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE", - copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Kai Eigner, TAT Zetwerk / Hans Hagen, PRAGMA ADE", + copyright="TAT Zetwerk / PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local insert,imerge,copy=table.insert,table.imerge,table.copy local next,type=next,type local report=logs.reporter("otf","devanagari") -fonts=fonts or {} -fonts.analyzers=fonts.analyzers or {} +fonts=fonts or {} +fonts.analyzers=fonts.analyzers or {} fonts.analyzers.methods=fonts.analyzers.methods or { node={ otf={} } } local otf=fonts.handlers.otf local handlers=otf.handlers @@ -27727,8 +29118,6 @@ local methods=fonts.analyzers.methods local otffeatures=fonts.constructors.features.otf local registerotffeature=otffeatures.register local nuts=nodes.nuts -local tonode=nuts.tonode -local tonut=nuts.tonut local getnext=nuts.getnext local getprev=nuts.getprev local getboth=nuts.getboth @@ -27765,113 +29154,110 @@ local s_blwf=states.blwf local s_pstf=states.pstf local replace_all_nbsp=nil replace_all_nbsp=function(head) - replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head) - return head - end - return replace_all_nbsp(head) + replace_all_nbsp=typesetters and typesetters.characters and typesetters.characters.replacenbspaces or function(head) + return head + end + return replace_all_nbsp(head) end -local xprocesscharacters=nil +local processcharacters=nil if context then - xprocesscharacters=function(head,font) - xprocesscharacters=nodes.handlers.characters - return xprocesscharacters(head,font) - end + +--removed + else - xprocesscharacters=function(head,font) - xprocesscharacters=nodes.handlers.nodepass - return xprocesscharacters(head,font) + function processcharacters(head,font) + local processors=fontdata[font].shared.processes + for i=1,#processors do + head=processors[i](head,font,0) end -end -local function processcharacters(head,font) - return tonut(xprocesscharacters(tonode(head))) + return head + end end local indicgroups=characters and characters.indicgroups if not indicgroups and characters then - local indic={ - c={}, - i={}, - d={}, - m={}, - s={}, - o={}, - } - local indicmarks={ - l={}, - t={}, - b={}, - r={}, - s={}, - } - local indicclasses={ - nukta={}, - halant={}, - ra={}, - anudatta={}, - } - local indicorders={ - bp={}, - ap={}, - bs={}, - as={}, - bh={}, - ah={}, - bm={}, - am={}, - } - for k,v in next,characters.data do - local i=v.indic - if i then - indic[i][k]=true - i=v.indicmark - if i then - if i=="s" then - local s=v.specials - indicmarks[i][k]={ s[2],s[3] } - else - indicmarks[i][k]=true - end - end - i=v.indicclass - if i then - indicclasses[i][k]=true - end - i=v.indicorder - if i then - indicorders[i][k]=true - end - end - end - indicgroups={ - consonant=indic.c, - independent_vowel=indic.i, - dependent_vowel=indic.d, - vowel_modifier=indic.m, - stress_tone_mark=indic.s, - pre_mark=indicmarks.l, - above_mark=indicmarks.t, - below_mark=indicmarks.b, - post_mark=indicmarks.r, - twopart_mark=indicmarks.s, - nukta=indicclasses.nukta, - halant=indicclasses.halant, - ra=indicclasses.ra, - anudatta=indicclasses.anudatta, - before_postscript=indicorders.bp, - after_postscript=indicorders.ap, - before_half=indicorders.bh, - after_half=indicorders.ah, - before_subscript=indicorders.bs, - after_subscript=indicorders.as, - before_main=indicorders.bm, - after_main=indicorders.am, - } - indic=nil - indicmarks=nil - indicclasses=nil - indicorders=nil - characters.indicgroups=indicgroups -else - indicgroups=table.setmetatableindex("table") + local indic={ + c={}, + i={}, + d={}, + m={}, + s={}, + o={}, + } + local indicmarks={ + l={}, + t={}, + b={}, + r={}, + s={}, + } + local indicclasses={ + nukta={}, + halant={}, + ra={}, + anudatta={}, + } + local indicorders={ + bp={}, + ap={}, + bs={}, + as={}, + bh={}, + ah={}, + bm={}, + am={}, + } + for k,v in next,characters.data do + local i=v.indic + if i then + indic[i][k]=true + i=v.indicmark + if i then + if i=="s" then + local s=v.specials + indicmarks[i][k]={ s[2],s[3] } + else + indicmarks[i][k]=true + end + end + i=v.indicclass + if i then + indicclasses[i][k]=true + end + i=v.indicorder + if i then + indicorders[i][k]=true + end + end + end + indicgroups={ + consonant=indic.c, + independent_vowel=indic.i, + dependent_vowel=indic.d, + vowel_modifier=indic.m, + stress_tone_mark=indic.s, + pre_mark=indicmarks.l, + above_mark=indicmarks.t, + below_mark=indicmarks.b, + post_mark=indicmarks.r, + twopart_mark=indicmarks.s, + nukta=indicclasses.nukta, + halant=indicclasses.halant, + ra=indicclasses.ra, + anudatta=indicclasses.anudatta, + before_postscript=indicorders.bp, + after_postscript=indicorders.ap, + before_half=indicorders.bh, + after_half=indicorders.ah, + before_subscript=indicorders.bs, + after_subscript=indicorders.as, + before_main=indicorders.bm, + after_main=indicorders.am, + } + indic=nil + indicmarks=nil + indicclasses=nil + indicorders=nil + characters.indicgroups=indicgroups end local consonant=indicgroups.consonant local independent_vowel=indicgroups.independent_vowel @@ -27896,1175 +29282,1176 @@ local after_subscript=indicgroups.after_subscript local before_main=indicgroups.before_main local after_main=indicgroups.after_main local mark_four=table.merged ( - pre_mark, - above_mark, - below_mark, - post_mark + pre_mark, + above_mark, + below_mark, + post_mark ) local mark_above_below_post=table.merged ( - above_mark, - below_mark, - post_mark + above_mark, + below_mark, + post_mark ) local zw_char={ - [c_zwnj]=true, - [c_zwj ]=true, + [c_zwnj]=true, + [c_zwj ]=true, } local dflt_true={ - dflt=true + dflt=true } local two_defaults={ - dev2=dflt_true, + dev2=dflt_true, } local one_defaults={ - dev2=dflt_true, - deva=dflt_true, + dev2=dflt_true, + deva=dflt_true, } local false_flags={ false,false,false,false } local sequence_reorder_matras={ - features={ dv01=two_defaults }, - flags=false_flags, - name="dv01_reorder_matras", - order={ "dv01" }, - type="devanagari_reorder_matras", - nofsteps=1, - steps={ - { - coverage=pre_mark, - } + features={ dv01=two_defaults }, + flags=false_flags, + name="dv01_reorder_matras", + order={ "dv01" }, + type="devanagari_reorder_matras", + nofsteps=1, + steps={ + { + coverage=pre_mark, } + } } local sequence_reorder_reph={ - features={ dv02=two_defaults }, - flags=false_flags, - name="dv02_reorder_reph", - order={ "dv02" }, - type="devanagari_reorder_reph", - nofsteps=1, - steps={ - { - coverage={}, - } + features={ dv02=two_defaults }, + flags=false_flags, + name="dv02_reorder_reph", + order={ "dv02" }, + type="devanagari_reorder_reph", + nofsteps=1, + steps={ + { + coverage={}, } + } } local sequence_reorder_pre_base_reordering_consonants={ - features={ dv03=two_defaults }, - flags=false_flags, - name="dv03_reorder_pre_base_reordering_consonants", - order={ "dv03" }, - type="devanagari_reorder_pre_base_reordering_consonants", - nofsteps=1, - steps={ - { - coverage={}, - } + features={ dv03=two_defaults }, + flags=false_flags, + name="dv03_reorder_pre_base_reordering_consonants", + order={ "dv03" }, + type="devanagari_reorder_pre_base_reordering_consonants", + nofsteps=1, + steps={ + { + coverage={}, } + } } local sequence_remove_joiners={ - features={ dv04=one_defaults }, - flags=false_flags, - name="dv04_remove_joiners", - order={ "dv04" }, - type="devanagari_remove_joiners", - nofsteps=1, - steps={ - { - coverage=zw_char, - }, - } + features={ dv04=one_defaults }, + flags=false_flags, + name="dv04_remove_joiners", + order={ "dv04" }, + type="devanagari_remove_joiners", + nofsteps=1, + steps={ + { + coverage=zw_char, + }, + } } local basic_shaping_forms={ - init=true, - abvs=true, - akhn=true, - blwf=true, - calt=true, - cjct=true, - half=true, - haln=true, - nukt=true, - pref=true, - pres=true, - pstf=true, - psts=true, - rkrf=true, - rphf=true, - vatu=true, + akhn=true, + blwf=true, + cjct=true, + half=true, + nukt=true, + pref=true, + pstf=true, + rkrf=true, + rphf=true, + vatu=true, } local valid={ - abvs=true, - akhn=true, - blwf=true, - calt=true, - cjct=true, - half=true, - haln=true, - nukt=true, - pref=true, - pres=true, - pstf=true, - psts=true, - rkrf=true, - rphf=true, - vatu=true, - pres=true, - abvs=true, - blws=true, - psts=true, - haln=true, - calt=true, + abvs=true, + akhn=true, + blwf=true, + calt=true, + cjct=true, + half=true, + haln=true, + nukt=true, + pref=true, + pres=true, + pstf=true, + psts=true, + rkrf=true, + rphf=true, + vatu=true, + pres=true, + abvs=true, + blws=true, + psts=true, + haln=true, + calt=true, } local scripts={} local scripts_one={ "deva","mlym","beng","gujr","guru","knda","orya","taml","telu" } local scripts_two={ "dev2","mlm2","bng2","gjr2","gur2","knd2","ory2","tml2","tel2" } local nofscripts=#scripts_one for i=1,nofscripts do - local one=scripts_one[i] - local two=scripts_two[i] - scripts[one]=true - scripts[two]=true - two_defaults[one]=dflt_true - one_defaults[one]=dflt_true - one_defaults[two]=dflt_true + local one=scripts_one[i] + local two=scripts_two[i] + scripts[one]=true + scripts[two]=true + two_defaults[one]=dflt_true + one_defaults[one]=dflt_true + one_defaults[two]=dflt_true end local function valid_one(s) for i=1,nofscripts do if s[scripts_one[i]] then return true end end end local function valid_two(s) for i=1,nofscripts do if s[scripts_two[i]] then return true end end end local function initializedevanagi(tfmdata) - local script,language=otf.scriptandlanguage(tfmdata,attr) - if scripts[script] then - local resources=tfmdata.resources - local devanagari=resources.devanagari - if not devanagari then - report("adding devanagari features to font") - local gsubfeatures=resources.features.gsub - local sequences=resources.sequences - local sharedfeatures=tfmdata.shared.features - local lastmatch=0 - for s=1,#sequences do - local features=sequences[s].features - if features then - for k,v in next,features do - if basic_shaping_forms[k] then - lastmatch=s - end - end + local script,language=otf.scriptandlanguage(tfmdata,attr) + if scripts[script] then + local resources=tfmdata.resources + local devanagari=resources.devanagari + if not devanagari then + report("adding devanagari features to font") + local gsubfeatures=resources.features.gsub + local sequences=resources.sequences + local sharedfeatures=tfmdata.shared.features + local lastmatch=0 + for s=1,#sequences do + local features=sequences[s].features + if features then + for k,v in next,features do + if basic_shaping_forms[k] then + lastmatch=s + end + end + end + end + local insertindex=lastmatch+1 + gsubfeatures["dv01"]=two_defaults + gsubfeatures["dv02"]=two_defaults + gsubfeatures["dv03"]=two_defaults + gsubfeatures["dv04"]=one_defaults + local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants) + local reorder_reph=copy(sequence_reorder_reph) + local reorder_matras=copy(sequence_reorder_matras) + local remove_joiners=copy(sequence_remove_joiners) + insert(sequences,insertindex,reorder_pre_base_reordering_consonants) + insert(sequences,insertindex,reorder_reph) + insert(sequences,insertindex,reorder_matras) + insert(sequences,insertindex,remove_joiners) + local blwfcache={} + local seqsubset={} + local rephstep={ + coverage={} + } + local devanagari={ + reph=false, + vattu=false, + blwfcache=blwfcache, + seqsubset=seqsubset, + reorderreph=rephstep, + } + reorder_reph.steps={ rephstep } + local pre_base_reordering_consonants={} + reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants + resources.devanagari=devanagari + for s=1,#sequences do + local sequence=sequences[s] + local steps=sequence.steps + local nofsteps=sequence.nofsteps + local features=sequence.features + local has_rphf=features.rphf + local has_blwf=features.blwf + if has_rphf and has_rphf.deva then + devanagari.reph=true + elseif has_blwf and has_blwf.deva then + devanagari.vattu=true + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,coverage do + if not blwfcache[k] then + blwfcache[k]=v end + end end - local insertindex=lastmatch+1 - gsubfeatures["dv01"]=two_defaults - gsubfeatures["dv02"]=two_defaults - gsubfeatures["dv03"]=two_defaults - gsubfeatures["dv04"]=one_defaults - local reorder_pre_base_reordering_consonants=copy(sequence_reorder_pre_base_reordering_consonants) - local reorder_reph=copy(sequence_reorder_reph) - local reorder_matras=copy(sequence_reorder_matras) - local remove_joiners=copy(sequence_remove_joiners) - insert(sequences,insertindex,reorder_pre_base_reordering_consonants) - insert(sequences,insertindex,reorder_reph) - insert(sequences,insertindex,reorder_matras) - insert(sequences,insertindex,remove_joiners) - local blwfcache={} - local seqsubset={} - local rephstep={ - coverage={} - } - local devanagari={ - reph=false, - vattu=false, - blwfcache=blwfcache, - seqsubset=seqsubset, - reorderreph=rephstep, - } - reorder_reph.steps={ rephstep } - local pre_base_reordering_consonants={} - reorder_pre_base_reordering_consonants.steps[1].coverage=pre_base_reordering_consonants - resources.devanagari=devanagari - for s=1,#sequences do - local sequence=sequences[s] - local steps=sequence.steps - local nofsteps=sequence.nofsteps - local features=sequence.features - local has_rphf=features.rphf - local has_blwf=features.blwf - if has_rphf and has_rphf.deva then - devanagari.reph=true - elseif has_blwf and has_blwf.deva then - devanagari.vattu=true - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,coverage do - if not blwfcache[k] then - blwfcache[k]=v - end - end - end + end + end + for kind,spec in next,features do + if valid[kind] and valid_two(spec)then + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + local reph=false + if kind=="rphf" then + for k,v in next,ra do + local r=coverage[k] + if r then + local h=false + for k,v in next,halant do + local h=r[k] + if h then + reph=h.ligature or false + break + end + end + if reph then + break + end end + end end - for kind,spec in next,features do - if valid[kind] and valid_two(spec)then - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - local reph=false - if kind=="rphf" then - for k,v in next,ra do - local r=coverage[k] - if r then - local h=false - for k,v in next,halant do - local h=r[k] - if h then - reph=h.ligature or false - break - end - end - if reph then - break - end - end - end - end -if reph then - seqsubset[#seqsubset+1]={ kind,coverage,reph } -end - end - end + seqsubset[#seqsubset+1]={ kind,coverage,reph } + end + end + end + if kind=="pref" then + local steps=sequence.steps + local nofsteps=sequence.nofsteps + for i=1,nofsteps do + local step=steps[i] + local coverage=step.coverage + if coverage then + for k,v in next,halant do + local h=coverage[k] + if h then + local found=false + for k,v in next,h do + found=v and v.ligature + if found then + pre_base_reordering_consonants[k]=found + break + end end - if kind=="pref" then - local steps=sequence.steps - local nofsteps=sequence.nofsteps - for i=1,nofsteps do - local step=steps[i] - local coverage=step.coverage - if coverage then - for k,v in next,halant do - local h=coverage[k] - if h then - local found=false - for k,v in next,h do - found=v and v.ligature - if found then - pre_base_reordering_consonants[k]=found - break - end - end - if found then - break - end - end - end - end - end + if found then + break end + end end + end end - if script=="deva" then - sharedfeatures["dv04"]=true - elseif script=="dev2" then - sharedfeatures["dv01"]=true - sharedfeatures["dv02"]=true - sharedfeatures["dv03"]=true - sharedfeatures["dv04"]=true - elseif script=="mlym" then - sharedfeatures["pstf"]=true - elseif script=="mlm2" then - sharedfeatures["pstf"]=true - sharedfeatures["pref"]=true - sharedfeatures["dv03"]=true - gsubfeatures ["dv03"]=two_defaults - insert(sequences,insertindex,sequence_reorder_pre_base_reordering_consonants) - elseif script=="taml" then - sharedfeatures["dv04"]=true -sharedfeatures["pstf"]=true - elseif script=="tml2" then - else - report("todo: enable the right features for script %a",script) - end + end end + end + if script=="deva" then + sharedfeatures["dv04"]=true + elseif script=="dev2" then + sharedfeatures["dv01"]=true + sharedfeatures["dv02"]=true + sharedfeatures["dv03"]=true + sharedfeatures["dv04"]=true + elseif script=="mlym" then + sharedfeatures["pstf"]=true + elseif script=="mlm2" then + sharedfeatures["pstf"]=true + sharedfeatures["pref"]=true + sharedfeatures["dv03"]=true + gsubfeatures ["dv03"]=two_defaults + insert(sequences,insertindex,sequence_reorder_pre_base_reordering_consonants) + elseif script=="taml" then + sharedfeatures["dv04"]=true +sharedfeatures["pstf"]=true + elseif script=="tml2" then + else + report("todo: enable the right features for script %a",script) + end end + end end registerotffeature { - name="devanagari", - description="inject additional features", - default=true, - initializers={ - node=initializedevanagi, - }, + name="devanagari", + description="inject additional features", + default=true, + initializers={ + node=initializedevanagi, + }, } +local show_syntax_errors=false +local function inject_syntax_error(head,current,char) + local signal=copy_node(current) + copyinjection(signal,current) + if pre_mark[char] then + setchar(signal,dotted_circle) + else + setchar(current,dotted_circle) + end + return insert_node_after(head,current,signal) +end local function initialize_one(font,attr) - local tfmdata=fontdata[font] - local datasets=otf.dataset(tfmdata,font,attr) - local devanagaridata=datasets.devanagari - if not devanagaridata then - devanagaridata={ - reph=false, - vattu=false, - blwfcache={}, - } - datasets.devanagari=devanagaridata - local resources=tfmdata.resources - local devanagari=resources.devanagari - for s=1,#datasets do - local dataset=datasets[s] - if dataset and dataset[1] then - local kind=dataset[4] - if kind=="rphf" then - devanagaridata.reph=true - elseif kind=="blwf" then - devanagaridata.vattu=true - devanagaridata.blwfcache=devanagari.blwfcache - end - end + local tfmdata=fontdata[font] + local datasets=otf.dataset(tfmdata,font,attr) + local devanagaridata=datasets.devanagari + if not devanagaridata then + devanagaridata={ + reph=false, + vattu=false, + blwfcache={}, + } + datasets.devanagari=devanagaridata + local resources=tfmdata.resources + local devanagari=resources.devanagari + for s=1,#datasets do + local dataset=datasets[s] + if dataset and dataset[1] then + local kind=dataset[4] + if kind=="rphf" then + devanagaridata.reph=true + elseif kind=="blwf" then + devanagaridata.vattu=true + devanagaridata.blwfcache=devanagari.blwfcache end + end end - return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache + end + return devanagaridata.reph,devanagaridata.vattu,devanagaridata.blwfcache end local function reorder_one(head,start,stop,font,attr,nbspaces) - local reph,vattu,blwfcache=initialize_one(font,attr) - local current=start - local n=getnext(start) - local base=nil - local firstcons=nil - local lastcons=nil - local basefound=false - if reph and ra[getchar(start)] and halant[getchar(n)] then - if n==stop then - return head,stop,nbspaces - end - if getchar(getnext(n))==c_zwj then - current=start - else - current=getnext(n) - setprop(start,a_state,s_rphf) - end - end - if getchar(current)==c_nbsp then - if current==stop then - stop=getprev(stop) - head=remove_node(head,current) - flush_node(current) - return head,stop,nbspaces - else - nbspaces=nbspaces+1 - base=current - firstcons=current - lastcons=current - current=getnext(current) - if current~=stop then - local char=getchar(current) - if nukta[char] then - current=getnext(current) - char=getchar(current) - end - if char==c_zwj and current~=stop then - local next=getnext(current) - if next~=stop and halant[getchar(next)] then - current=next - next=getnext(current) - local tmp=next and getnext(next) or nil - local changestop=next==stop - local tempcurrent=copy_node(next) - copyinjection(tempcurrent,next) - local nextcurrent=copy_node(current) - copyinjection(nextcurrent,current) - setlink(tempcurrent,nextcurrent) - setprop(tempcurrent,a_state,s_blwf) - tempcurrent=processcharacters(tempcurrent,font) - setprop(tempcurrent,a_state,unsetvalue) - if getchar(next)==getchar(tempcurrent) then - flush_list(tempcurrent) - local n=copy_node(current) - copyinjection(n,current) - setchar(current,dotted_circle) - head=insert_node_after(head,current,n) - else - setchar(current,getchar(tempcurrent)) - local freenode=getnext(current) - setlink(current,tmp) - flush_node(freenode) - flush_list(tempcurrent) - if changestop then - stop=current - end - end - end - end - end - end - end - while not basefound do + local reph,vattu,blwfcache=initialize_one(font,attr) + local current=start + local n=getnext(start) + local base=nil + local firstcons=nil + local lastcons=nil + local basefound=false + if reph and ra[getchar(start)] and halant[getchar(n)] then + if n==stop then + return head,stop,nbspaces + end + if getchar(getnext(n))==c_zwj then + current=start + else + current=getnext(n) + setprop(start,a_state,s_rphf) + end + end + if getchar(current)==c_nbsp then + if current==stop then + stop=getprev(stop) + head=remove_node(head,current) + flush_node(current) + return head,stop,nbspaces + else + nbspaces=nbspaces+1 + base=current + firstcons=current + lastcons=current + current=getnext(current) + if current~=stop then local char=getchar(current) - if consonant[char] then - setprop(current,a_state,s_half) - if not firstcons then - firstcons=current - end - lastcons=current - if not base then - base=current - elseif blwfcache[char] then - setprop(current,a_state,s_blwf) + if nukta[char] then + current=getnext(current) + char=getchar(current) + end + if char==c_zwj and current~=stop then + local next=getnext(current) + if next~=stop and halant[getchar(next)] then + current=next + next=getnext(current) + local tmp=next and getnext(next) or nil + local changestop=next==stop + local tempcurrent=copy_node(next) + copyinjection(tempcurrent,next) + local nextcurrent=copy_node(current) + copyinjection(nextcurrent,current) + setlink(tempcurrent,nextcurrent) + setprop(tempcurrent,a_state,s_blwf) + tempcurrent=processcharacters(tempcurrent,font) + setprop(tempcurrent,a_state,unsetvalue) + if getchar(next)==getchar(tempcurrent) then + flush_list(tempcurrent) + if show_syntax_errors then + head,current=inject_syntax_error(head,current,char) + end else - base=current + setchar(current,getchar(tempcurrent)) + local freenode=getnext(current) + setlink(current,tmp) + flush_node(freenode) + flush_list(tempcurrent) + if changestop then + stop=current + end end + end end - basefound=current==stop - current=getnext(current) + end end - if base~=lastcons then - local np=base - local n=getnext(base) - local ch=getchar(n) - if nukta[ch] then - np=n + end + while not basefound do + local char=getchar(current) + if consonant[char] then + setprop(current,a_state,s_half) + if not firstcons then + firstcons=current + end + lastcons=current + if not base then + base=current + elseif blwfcache[char] then + setprop(current,a_state,s_blwf) + else + base=current + end + end + basefound=current==stop + current=getnext(current) + end + if base~=lastcons then + local np=base + local n=getnext(base) + local ch=getchar(n) + if nukta[ch] then + np=n + n=getnext(n) + ch=getchar(n) + end + if halant[ch] then + if lastcons~=stop then + local ln=getnext(lastcons) + if nukta[getchar(ln)] then + lastcons=ln + end + end + local nn=getnext(n) + local ln=getnext(lastcons) + setlink(np,nn) + setnext(lastcons,n) + if ln then + setprev(ln,n) + end + setnext(n,ln) + setprev(n,lastcons) + if lastcons==stop then + stop=n + end + end + end + n=getnext(start) + if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then + local matra=base + if base~=stop then + local next=getnext(base) + if dependent_vowel[getchar(next)] then + matra=next + end + end + local sp=getprev(start) + local nn=getnext(n) + local mn=getnext(matra) + setlink(sp,nn) + setlink(matra,start) + setlink(n,mn) + if head==start then + head=nn + end + start=nn + if matra==stop then + stop=n + end + end + local current=start + while current~=stop do + local next=getnext(current) + if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then + setprop(current,a_state,unsetvalue) + end + current=next + end + if base~=stop and getprop(base,a_state) then + local next=getnext(base) + if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then + setprop(base,a_state,unsetvalue) + end + end + local current,allreordered,moved=start,false,{ [base]=true } + local a,b,p,bn=base,base,base,getnext(base) + if base~=stop and nukta[getchar(bn)] then + a,b,p=bn,bn,bn + end + while not allreordered do + local c=current + local n=getnext(current) + local l=nil + if c~=stop then + local ch=getchar(n) + if nukta[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop then + if halant[ch] then + c=n + n=getnext(n) + ch=getchar(n) + end + while c~=stop and dependent_vowel[ch] do + c=n + n=getnext(n) + ch=getchar(n) + end + if c~=stop then + if vowel_modifier[ch] then + c=n n=getnext(n) ch=getchar(n) + end + if c~=stop and stress_tone_mark[ch] then + c=n + n=getnext(n) + end end - if halant[ch] then - if lastcons~=stop then - local ln=getnext(lastcons) - if nukta[getchar(ln)] then - lastcons=ln - end - end - local nn=getnext(n) - local ln=getnext(lastcons) - setlink(np,nn) - setnext(lastcons,n) - if ln then - setprev(ln,n) - end - setnext(n,ln) - setprev(n,lastcons) - if lastcons==stop then - stop=n - end - end + end end - n=getnext(start) - if n~=stop and ra[getchar(start)] and halant[getchar(n)] and not zw_char[getchar(getnext(n))] then - local matra=base - if base~=stop then - local next=getnext(base) - if dependent_vowel[getchar(next)] then - matra=next - end + local bp=getprev(firstcons) + local cn=getnext(current) + local last=getnext(c) + while cn~=last do + if pre_mark[getchar(cn)] then + if bp then + setnext(bp,cn) end - local sp=getprev(start) - local nn=getnext(n) - local mn=getnext(matra) - setlink(sp,nn) - setlink(matra,start) - setlink(n,mn) - if head==start then - head=nn + local prev,next=getboth(cn) + if next then + setprev(next,prev) end - start=nn - if matra==stop then - stop=n + setnext(prev,next) + if cn==stop then + stop=prev end - end - local current=start - while current~=stop do - local next=getnext(current) - if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then - setprop(current,a_state,unsetvalue) + setprev(cn,bp) + setlink(cn,firstcons) + if firstcons==start then + if head==start then + head=cn + end + start=cn end - current=next - end - if base~=stop and getprop(base,a_state) then - local next=getnext(base) - if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then - setprop(base,a_state,unsetvalue) + break + end + cn=getnext(cn) + end + allreordered=c==stop + current=getnext(c) + end + if reph or vattu then + local current,cns=start,nil + while current~=stop do + local c=current + local n=getnext(current) + if ra[getchar(current)] and halant[getchar(n)] then + c=n + n=getnext(n) + local b,bn=base,base + while bn~=stop do + local next=getnext(bn) + if dependent_vowel[getchar(next)] then + b=next + end + bn=next end - end - local current,allreordered,moved=start,false,{ [base]=true } - local a,b,p,bn=base,base,base,getnext(base) - if base~=stop and nukta[getchar(bn)] then - a,b,p=bn,bn,bn - end - while not allreordered do - local c=current - local n=getnext(current) - local l=nil - if c~=stop then - local ch=getchar(n) - if nukta[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop then - if halant[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - while c~=stop and dependent_vowel[ch] do - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop then - if vowel_modifier[ch] then - c=n - n=getnext(n) - ch=getchar(n) - end - if c~=stop and stress_tone_mark[ch] then - c=n - n=getnext(n) - end - end + if getprop(current,a_state)==s_rphf then + if b~=current then + if current==start then + if head==start then + head=n + end + start=n end - end - local bp=getprev(firstcons) - local cn=getnext(current) - local last=getnext(c) - while cn~=last do - if pre_mark[getchar(cn)] then - if bp then - setnext(bp,cn) - end - local prev,next=getboth(cn) - if next then - setprev(next,prev) - end - setnext(prev,next) - if cn==stop then - stop=prev - end - setprev(cn,bp) - setlink(cn,firstcons) - if firstcons==start then - if head==start then - head=cn - end - start=cn - end - break + if b==stop then + stop=c end - cn=getnext(cn) + local prev=getprev(current) + setlink(prev,n) + local next=getnext(b) + setlink(c,next) + setlink(b,current) + end + elseif cns and getnext(cns)~=current then + local cp=getprev(current) + local cnsn=getnext(cns) + setlink(cp,n) + setlink(cns,current) + setlink(c,cnsn) + if c==stop then + stop=cp + break + end + current=getprev(n) end - allreordered=c==stop - current=getnext(c) - end - if reph or vattu then - local current,cns=start,nil - while current~=stop do - local c=current - local n=getnext(current) - if ra[getchar(current)] and halant[getchar(n)] then - c=n - n=getnext(n) - local b,bn=base,base - while bn~=stop do - local next=getnext(bn) - if dependent_vowel[getchar(next)] then - b=next - end - bn=next - end - if getprop(current,a_state)==s_rphf then - if b~=current then - if current==start then - if head==start then - head=n - end - start=n - end - if b==stop then - stop=c - end - local prev=getprev(current) - setlink(prev,n) - local next=getnext(b) - setlink(c,next) - setlink(b,current) - end - elseif cns and getnext(cns)~=current then - local cp=getprev(current) - local cnsn=getnext(cns) - setlink(cp,n) - setlink(cns,current) - setlink(c,cnsn) - if c==stop then - stop=cp - break - end - current=getprev(n) - end - else - local char=getchar(current) - if consonant[char] then - cns=current - local next=getnext(cns) - if halant[getchar(next)] then - cns=next - end - elseif char==c_nbsp then - nbspaces=nbspaces+1 - cns=current - local next=getnext(cns) - if halant[getchar(next)] then - cns=next - end - end - end - current=getnext(current) + else + local char=getchar(current) + if consonant[char] then + cns=current + local next=getnext(cns) + if halant[getchar(next)] then + cns=next + end + elseif char==c_nbsp then + nbspaces=nbspaces+1 + cns=current + local next=getnext(cns) + if halant[getchar(next)] then + cns=next + end end + end + current=getnext(current) end - if getchar(base)==c_nbsp then - nbspaces=nbspaces-1 - head=remove_node(head,base) - flush_node(base) - end - return head,stop,nbspaces + end + if getchar(base)==c_nbsp then + nbspaces=nbspaces-1 + head=remove_node(head,base) + flush_node(base) + end + return head,stop,nbspaces end function handlers.devanagari_reorder_matras(head,start) - local current=start - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - local next=getnext(current) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] and not getprop(current,a_state) then - if next then - local char=ischar(next,startfont) - if char and zw_char[char] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - local startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - start=startnext - break - end - else - break + local current=start + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + local next=getnext(current) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] and not getprop(current,a_state) then + if next then + local char=ischar(next,startfont) + if char and zw_char[char] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end end - current=next + local startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + start=startnext + break + end + else + break end - return head,start,true + current=next + end + return head,start,true end function handlers.devanagari_reorder_reph(head,start) - local current=getnext(start) - local startnext=nil - local startprev=nil - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - ::step_1:: - ::step_2:: - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if halant[char] and not getprop(current,a_state) then - local next=getnext(current) - if next then - local nextchar=ischar(next,startfont) - if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - end - end - startnext=getnext(start) - head=remove_node(head,start) - setlink(start,next) - setlink(current,start) - start=startnext - startattr=getprop(start,a_syllabe) - break - end - current=getnext(current) - else - break + local current=getnext(start) + local startnext=nil + local startprev=nil + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + ::step_1:: + ::step_2:: + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if halant[char] and not getprop(current,a_state) then + local next=getnext(current) + if next then + local nextchar=ischar(next,startfont) + if nextchar and zw_char[nextchar] and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + end end + startnext=getnext(start) + head=remove_node(head,start) + setlink(start,next) + setlink(current,start) + start=startnext + startattr=getprop(start,a_syllabe) + break + end + current=getnext(current) + else + break end - ::step_3:: - ::step_4:: - if not startnext then - current=getnext(start) - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if getprop(current,a_state)==s_pstf then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(current),start) - setlink(start,current) - start=startnext - startattr=getprop(start,a_syllabe) - break - end - current=getnext(current) - else - break - end + end + ::step_3:: + ::step_4:: + if not startnext then + current=getnext(start) + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if getprop(current,a_state)==s_pstf then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(current),start) + setlink(start,current) + start=startnext + startattr=getprop(start,a_syllabe) + break end + current=getnext(current) + else + break + end end - ::step_5:: - if not startnext then - current=getnext(start) - local c=nil - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if not c and mark_above_below_post[char] and after_subscript[char] then - c=current - end - current=getnext(current) - else - break - end - end - if c then - startnext=getnext(start) - head=remove_node(head,start) - setlink(getprev(c),start) - setlink(start,c) - start=startnext - startattr=getprop(start,a_syllabe) + end + ::step_5:: + if not startnext then + current=getnext(start) + local c=nil + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if not c and mark_above_below_post[char] and not after_subscript[char] then + c=current end + current=getnext(current) + else + break + end + end + if c then + startnext=getnext(start) + head=remove_node(head,start) + setlink(getprev(c),start) + setlink(start,c) + start=startnext + startattr=getprop(start,a_syllabe) + end + end + ::step_6:: + if not startnext then + current=start + local next=getnext(current) + while next do + local nextchar=ischar(next,startfont) + if nextchar and getprop(next,a_syllabe)==startattr then + current=next + next=getnext(current) + else + break + end end - ::step_6:: - if not startnext then - current=start - local next=getnext(current) - while next do - local nextchar=ischar(next,startfont) - if nextchar and getprop(next,a_syllabe)==startattr then - current=next - next=getnext(current) - else - break - end - end - if start~=current then - startnext=getnext(start) - head=remove_node(head,start) - setlink(start,getnext(current)) - setlink(current,start) - start=startnext - end + if start~=current then + startnext=getnext(start) + head=remove_node(head,start) + setlink(start,getnext(current)) + setlink(current,start) + start=startnext end - return head,start,true + end + return head,start,true end function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start) - local current=start - local startnext=nil - local startprev=nil - local startfont=getfont(start) - local startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - local next=getnext(current) - if halant[char] and not getprop(current,a_state) then - if next then - local nextchar=ischar(next,startfont) - if nextchar and getprop(next,a_syllabe)==startattr then - if nextchar==c_zwnj or nextchar==c_zwj then - current=next - next=getnext(current) - end - end - end - startnext=getnext(start) - removenode(start,start) - setlink(start,next) - setlink(current,start) - start=startnext - break + local current=start + local startnext=nil + local startprev=nil + local startfont=getfont(start) + local startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + local next=getnext(current) + if halant[char] and not getprop(current,a_state) then + if next then + local nextchar=ischar(next,startfont) + if nextchar and getprop(next,a_syllabe)==startattr then + if nextchar==c_zwnj or nextchar==c_zwj then + current=next + next=getnext(current) end - current=next - else - break + end end + startnext=getnext(start) + removenode(start,start) + setlink(start,next) + setlink(current,start) + start=startnext + break + end + current=next + else + break end - if not startnext then - current=getnext(start) - startattr=getprop(start,a_syllabe) - while current do - local char=ischar(current,startfont) - if char and getprop(current,a_syllabe)==startattr then - if not consonant[char] and getprop(current,a_state) then - startnext=getnext(start) - removenode(start,start) - setlink(getprev(current),start) - setlink(start,current) - start=startnext - break - end - current=getnext(current) - else - break - end + end + if not startnext then + current=getnext(start) + startattr=getprop(start,a_syllabe) + while current do + local char=ischar(current,startfont) + if char and getprop(current,a_syllabe)==startattr then + if not consonant[char] and getprop(current,a_state) then + startnext=getnext(start) + removenode(start,start) + setlink(getprev(current),start) + setlink(start,current) + start=startnext + break end + current=getnext(current) + else + break + end end - return head,start,true + end + return head,start,true end function handlers.devanagari_remove_joiners(head,start,kind,lookupname,replacement) - local stop=getnext(start) - local font=getfont(start) - local last=start - while stop do - local char=ischar(stop,font) - if char and (char==c_zwnj or char==c_zwj) then - last=stop - stop=getnext(stop) - else - break - end - end - local prev=getprev(start) - if stop then - setnext(last) - setlink(prev,stop) - elseif prev then - setnext(prev) - end - if head==start then - head=stop - end - flush_list(start) - return head,stop,true + local stop=getnext(start) + local font=getfont(start) + local last=start + while stop do + local char=ischar(stop,font) + if char and (char==c_zwnj or char==c_zwj) then + last=stop + stop=getnext(stop) + else + break + end + end + local prev=getprev(start) + if stop then + setnext(last) + setlink(prev,stop) + elseif prev then + setnext(prev) + end + if head==start then + head=stop + end + flush_list(start) + return head,stop,true end local function initialize_two(font,attr) - local devanagari=fontdata[font].resources.devanagari - if devanagari then - return devanagari.seqsubset or {},devanagari.reorderreph or {} - else - return {},{} - end + local devanagari=fontdata[font].resources.devanagari + if devanagari then + return devanagari.seqsubset or {},devanagari.reorderreph or {} + else + return {},{} + end end local function reorder_two(head,start,stop,font,attr,nbspaces) - local seqsubset,reorderreph=initialize_two(font,attr) - local reph=false - local halfpos=nil - local basepos=nil - local subpos=nil - local postpos=nil - local locl={} - for i=1,#seqsubset do - local subset=seqsubset[i] - local kind=subset[1] - local lookupcache=subset[2] - if kind=="rphf" then - reph=subset[3] - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=locl[current] or getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - local n=locl[next] or getchar(next) - if found[n] then - local afternext=next~=stop and getnext(next) - if afternext and zw_char[getchar(afternext)] then - current=afternext - elseif current==start then - setprop(current,a_state,s_rphf) - current=next - else - current=next - end - end - end - end - current=getnext(current) - end - elseif kind=="pref" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=locl[current] or getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - local n=locl[next] or getchar(next) - if found[n] then - setprop(current,a_state,s_pref) - setprop(next,a_state,s_pref) - current=next - end - end - end - current=getnext(current) - end - elseif kind=="half" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=locl[current] or getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - local n=locl[next] or getchar(next) - if found[n] then - if next~=stop and getchar(getnext(next))==c_zwnj then - current=next - else - setprop(current,a_state,s_half) - if not halfpos then - halfpos=current - end - end - current=getnext(current) - end - end - end - current=getnext(current) - end - elseif kind=="blwf" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=locl[current] or getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - local n=locl[next] or getchar(next) - if found[n] then - setprop(current,a_state,s_blwf) - setprop(next,a_state,s_blwf) - current=next - subpos=current - end - end - end - current=getnext(current) - end - elseif kind=="pstf" then - local current=start - local last=getnext(stop) - while current~=last do - if current~=stop then - local c=locl[current] or getchar(current) - local found=lookupcache[c] - if found then - local next=getnext(current) - local n=locl[next] or getchar(next) - if found[n] then - setprop(current,a_state,s_pstf) - setprop(next,a_state,s_pstf) - current=next - postpos=current - end - end - end - current=getnext(current) + local seqsubset,reorderreph=initialize_two(font,attr) + local reph=false + local halfpos=nil + local basepos=nil + local subpos=nil + local postpos=nil + local locl={} + for i=1,#seqsubset do + local subset=seqsubset[i] + local kind=subset[1] + local lookupcache=subset[2] + if kind=="rphf" then + reph=subset[3] + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=locl[current] or getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + local n=locl[next] or getchar(next) + if found[n] then + local afternext=next~=stop and getnext(next) + if afternext and zw_char[getchar(afternext)] then + current=afternext + elseif current==start then + setprop(current,a_state,s_rphf) + current=next + else + current=next + end end + end end - end - reorderreph.coverage={ [reph]=true } - local current,base,firstcons=start,nil,nil - if getprop(start,a_state)==s_rphf then - current=getnext(getnext(start)) - end - if current~=getnext(stop) and getchar(current)==c_nbsp then - if current==stop then - stop=getprev(stop) - head=remove_node(head,current) - flush_node(current) - return head,stop,nbspaces - else - nbspaces=nbspaces+1 - base=current - current=getnext(current) - if current~=stop then - local char=getchar(current) - if nukta[char] then - current=getnext(current) - char=getchar(current) - end - if char==c_zwj then - local next=getnext(current) - if current~=stop and next~=stop and halant[getchar(next)] then - current=next - next=getnext(current) - local tmp=getnext(next) - local changestop=next==stop - setnext(next) - setprop(current,a_state,s_pref) - current=processcharacters(current,font) - setprop(current,a_state,s_blwf) - current=processcharacters(current,font) - setprop(current,a_state,s_pstf) - current=processcharacters(current,font) - setprop(current,a_state,unsetvalue) - if halant[getchar(current)] then - setnext(getnext(current),tmp) - local nc=copy_node(current) - copyinjection(nc,current) - setchar(current,dotted_circle) - head=insert_node_after(head,current,nc) - else - setnext(current,tmp) - if changestop then - stop=current - end - end - end - end + current=getnext(current) + end + elseif kind=="pref" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=locl[current] or getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + local n=locl[next] or getchar(next) + if found[n] then + setprop(current,a_state,s_pref) + setprop(next,a_state,s_pref) + current=next end + end end - else - local last=getnext(stop) - while current~=last do + current=getnext(current) + end + elseif kind=="half" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=locl[current] or getchar(current) + local found=lookupcache[c] + if found then local next=getnext(current) - if consonant[getchar(current)] then - if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then - if not firstcons then - firstcons=current - end - local a=getprop(current,a_state) - if not (a==s_pref or a==s_blwf or a==s_pstf) then - base=current - end + local n=locl[next] or getchar(next) + if found[n] then + if next~=stop and getchar(getnext(next))==c_zwnj then + current=next + else + setprop(current,a_state,s_half) + if not halfpos then + halfpos=current end + end + current=getnext(current) end - current=next - end - if not base then - base=firstcons - end - end - if not base then - if getprop(start,a_state)==s_rphf then - setprop(start,a_state,unsetvalue) + end end - return head,stop,nbspaces - else - if getprop(base,a_state) then - setprop(base,a_state,unsetvalue) + current=getnext(current) + end + elseif kind=="blwf" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=locl[current] or getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + local n=locl[next] or getchar(next) + if found[n] then + setprop(current,a_state,s_blwf) + setprop(next,a_state,s_blwf) + current=next + subpos=current + end + end end - basepos=base - end - if not halfpos then - halfpos=base - end - if not subpos then - subpos=base - end - if not postpos then - postpos=subpos or base - end - local moved={} - local current=start - local last=getnext(stop) - while current~=last do - local char,target,cn=locl[current] or getchar(current),nil,getnext(current) - local tpm=twopart_mark[char] - if tpm then - local extra=copy_node(current) - copyinjection(extra,current) - char=tpm[1] - setchar(current,char) - setchar(extra,tpm[2]) - head=insert_node_after(head,current,extra) - end - if not moved[current] and dependent_vowel[char] then - if pre_mark[char] then - moved[current]=true - local prev,next=getboth(current) - setlink(prev,next) - if current==stop then - stop=getprev(current) - end - if halfpos==start then - if head==start then - head=current - end - start=current - end - setlink(getprev(halfpos),current) - setlink(current,halfpos) - halfpos=current - elseif above_mark[char] then - target=basepos - if subpos==basepos then - subpos=current - end - if postpos==basepos then - postpos=current - end - basepos=current - elseif below_mark[char] then - target=subpos - if postpos==subpos then - postpos=current - end - subpos=current - elseif post_mark[char] then - target=postpos - postpos=current - end - if mark_above_below_post[char] then - local prev=getprev(current) - if prev~=target then - local next=getnext(current) - setlink(prev,next) - if current==stop then - stop=prev - end - setlink(current,getnext(target)) - setlink(target,current) - end + current=getnext(current) + end + elseif kind=="pstf" then + local current=start + local last=getnext(stop) + while current~=last do + if current~=stop then + local c=locl[current] or getchar(current) + local found=lookupcache[c] + if found then + local next=getnext(current) + local n=locl[next] or getchar(next) + if found[n] then + setprop(current,a_state,s_pstf) + setprop(next,a_state,s_pstf) + current=next + postpos=current end + end end - current=cn - end - local current,c=start,nil - while current~=stop do + current=getnext(current) + end + end + end + reorderreph.coverage={ [reph]=true } + local current,base,firstcons=start,nil,nil + if getprop(start,a_state)==s_rphf then + current=getnext(getnext(start)) + end + if current~=getnext(stop) and getchar(current)==c_nbsp then + if current==stop then + stop=getprev(stop) + head=remove_node(head,current) + flush_node(current) + return head,stop,nbspaces + else + nbspaces=nbspaces+1 + base=current + current=getnext(current) + if current~=stop then local char=getchar(current) - if halant[char] or stress_tone_mark[char] then - if not c then - c=current - end - else - c=nil + if nukta[char] then + current=getnext(current) + char=getchar(current) end - local next=getnext(current) - if c and nukta[getchar(next)] then - if head==c then - head=next - end - if stop==next then + if char==c_zwj then + local next=getnext(current) + if current~=stop and next~=stop and halant[getchar(next)] then + current=next + next=getnext(current) + local tmp=getnext(next) + local changestop=next==stop + setnext(next) + setprop(current,a_state,s_pref) + current=processcharacters(current,font) + setprop(current,a_state,s_blwf) + current=processcharacters(current,font) + setprop(current,a_state,s_pstf) + current=processcharacters(current,font) + setprop(current,a_state,unsetvalue) + if halant[getchar(current)] then + setnext(getnext(current),tmp) + if show_syntax_errors then + head,current=inject_syntax_error(head,current,char) + end + else + setnext(current,tmp) + if changestop then stop=current + end end - setlink(getprev(c),next) - local nextnext=getnext(next) - setnext(current,nextnext) - local nextnextnext=getnext(nextnext) - if nextnextnext then - setprev(nextnextnext,current) - end - setlink(nextnext,c) + end end - if stop==current then break end - current=getnext(current) + end end - if getchar(base)==c_nbsp then - if base==stop then - stop=getprev(stop) + else + local last=getnext(stop) + while current~=last do + local next=getnext(current) + if consonant[getchar(current)] then + if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then + if not firstcons then + firstcons=current + end + local a=getprop(current,a_state) + if not (a==s_pref or a==s_blwf or a==s_pstf) then + base=current + end end - nbspaces=nbspaces-1 - head=remove_node(head,base) - flush_node(base) + end + current=next + end + if not base then + base=firstcons + end + end + if not base then + if getprop(start,a_state)==s_rphf then + setprop(start,a_state,unsetvalue) end return head,stop,nbspaces + else + if getprop(base,a_state) then + setprop(base,a_state,unsetvalue) + end + basepos=base + end + if not halfpos then + halfpos=base + end + if not subpos then + subpos=base + end + if not postpos then + postpos=subpos or base + end + local moved={} + local current=start + local last=getnext(stop) + while current~=last do + local char,target,cn=locl[current] or getchar(current),nil,getnext(current) + local tpm=twopart_mark[char] + if tpm then + local extra=copy_node(current) + copyinjection(extra,current) + char=tpm[1] + setchar(current,char) + setchar(extra,tpm[2]) + head=insert_node_after(head,current,extra) + end + if not moved[current] and dependent_vowel[char] then + if pre_mark[char] then + moved[current]=true + local prev,next=getboth(current) + setlink(prev,next) + if current==stop then + stop=getprev(current) + end + if halfpos==start then + if head==start then + head=current + end + start=current + end + setlink(getprev(halfpos),current) + setlink(current,halfpos) + halfpos=current + elseif above_mark[char] then + target=basepos + if subpos==basepos then + subpos=current + end + if postpos==basepos then + postpos=current + end + basepos=current + elseif below_mark[char] then + target=subpos + if postpos==subpos then + postpos=current + end + subpos=current + elseif post_mark[char] then + target=postpos + postpos=current + end + if mark_above_below_post[char] then + local prev=getprev(current) + if prev~=target then + local next=getnext(current) + setlink(prev,next) + if current==stop then + stop=prev + end + setlink(current,getnext(target)) + setlink(target,current) + end + end + end + current=cn + end + local current,c=start,nil + while current~=stop do + local char=getchar(current) + if halant[char] or stress_tone_mark[char] then + if not c then + c=current + end + else + c=nil + end + local next=getnext(current) + if c and nukta[getchar(next)] then + if head==c then + head=next + end + if stop==next then + stop=current + end + setlink(getprev(c),next) + local nextnext=getnext(next) + setnext(current,nextnext) + local nextnextnext=getnext(nextnext) + if nextnextnext then + setprev(nextnextnext,current) + end + setlink(nextnext,c) + end + if stop==current then break end + current=getnext(current) + end + if getchar(base)==c_nbsp then + if base==stop then + stop=getprev(stop) + end + nbspaces=nbspaces-1 + head=remove_node(head,base) + flush_node(base) + end + return head,stop,nbspaces end local separator={} imerge(separator,consonant) @@ -29072,585 +30459,572 @@ imerge(separator,independent_vowel) imerge(separator,dependent_vowel) imerge(separator,vowel_modifier) imerge(separator,stress_tone_mark) -for k,v in next,nukta do separator[k]=true end +for k,v in next,nukta do separator[k]=true end for k,v in next,halant do separator[k]=true end local function analyze_next_chars_one(c,font,variant) - local n=getnext(c) - if not n then - return c - end - if variant==1 then - local v=ischar(n,font) - if v and nukta[v] then - n=getnext(n) - if n then - v=ischar(n,font) - end - end - if n and v then - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv then - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv then - if vv==c_zwj and consonant[vvv] then - c=nnn - elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then - local nnnn=getnext(nnn) - if nnnn then - local vvvv=ischar(nnnn,font) - if vvvv and consonant[vvvv] then - c=nnnn - end - end - end - end - end + local n=getnext(c) + if not n then + return c + end + if variant==1 then + local v=ischar(n,font) + if v and nukta[v] then + n=getnext(n) + if n then + v=ischar(n,font) + end + end + if n and v then + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv then + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv then + if vv==c_zwj and consonant[vvv] then + c=nnn + elseif (vv==c_zwnj or vv==c_zwj) and halant[vvv] then + local nnnn=getnext(nnn) + if nnnn then + local vvvv=ischar(nnnn,font) + if vvvv and consonant[vvvv] then + c=nnnn + end end + end end + end end - elseif variant==2 then - local v=ischar(n,font) - if v and nukta[v] then - c=n - end - n=getnext(c) - if n then - v=ischar(n,font) - if v then - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv and zw_char[v] then - n=nn - v=vv - nn=getnext(nn) - vv=nn and ischar(nn,font) - end - if vv and halant[v] and consonant[vv] then - c=nn - end - end - end + end + end + elseif variant==2 then + local v=ischar(n,font) + if v and nukta[v] then + c=n + end + n=getnext(c) + if n then + v=ischar(n,font) + if v then + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv and zw_char[v] then + n=nn + v=vv + nn=getnext(nn) + vv=nn and ischar(nn,font) + end + if vv and halant[v] and consonant[vv] then + c=nn + end end + end end - local n=getnext(c) + end + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if not v then + return c + end + if dependent_vowel[v] then + c=getnext(c) + n=getnext(c) if not n then - return c + return c end - local v=ischar(n,font) + v=ischar(n,font) if not v then - return c + return c end - if dependent_vowel[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + end + if nukta[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c end - if nukta[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + v=ischar(n,font) + if not v then + return c end - if halant[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + end + if halant[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c end - if vowel_modifier[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + v=ischar(n,font) + if not v then + return c end - if stress_tone_mark[v] then - c=getnext(c) - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + end + if vowel_modifier[v] then + c=getnext(c) + n=getnext(c) + if not n then + return c end - if stress_tone_mark[v] then - return n - else - return c + v=ischar(n,font) + if not v then + return c end -end -local function analyze_next_chars_two(c,font) - local n=getnext(c) + end + if stress_tone_mark[v] then + c=getnext(c) + n=getnext(c) if not n then - return c + return c end - local v=ischar(n,font) - if v and nukta[v] then - c=n + v=ischar(n,font) + if not v then + return c end - n=c - while true do + end + if stress_tone_mark[v] then + return n + else + return c + end +end +local function analyze_next_chars_two(c,font) + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if v and nukta[v] then + c=n + end + n=c + while true do + local nn=getnext(n) + if nn then + local vv=ischar(nn,font) + if vv then + if halant[vv] then + n=nn + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and zw_char[vvv] then + n=nnn + end + end + elseif vv==c_zwnj or vv==c_zwj then + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and halant[vvv] then + n=nnn + end + end + else + break + end local nn=getnext(n) if nn then - local vv=ischar(nn,font) - if vv then - if halant[vv] then - n=nn - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and zw_char[vvv] then - n=nnn - end - end - elseif vv==c_zwnj or vv==c_zwj then - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and halant[vvv] then - n=nnn - end - end - else - break - end - local nn=getnext(n) - if nn then - local vv=ischar(nn,font) - if vv and consonant[vv] then - n=nn - local nnn=getnext(nn) - if nnn then - local vvv=ischar(nnn,font) - if vvv and nukta[vvv] then - n=nnn - end - end - c=n - else - break - end - else - break - end - else - break + local vv=ischar(nn,font) + if vv and consonant[vv] then + n=nn + local nnn=getnext(nn) + if nnn then + local vvv=ischar(nnn,font) + if vvv and nukta[vvv] then + n=nnn + end end - else + c=n + else break + end + else + break end + else + break + end + else + break end - if not c then - return + end + if not c then + return + end + local n=getnext(c) + if not n then + return c + end + local v=ischar(n,font) + if not v then + return c + end + if anudatta[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c end - local n=getnext(c) + end + if halant[v] then + c=n + n=getnext(c) if not n then - return c + return c end - local v=ischar(n,font) + v=ischar(n,font) if not v then + return c + end + if v==c_zwnj or v==c_zwj then + c=n + n=getnext(c) + if not n then return c + end + v=ischar(n,font) + if not v then + return c + end end - if anudatta[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + else + if dependent_vowel[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if nukta[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end end if halant[v] then - c=n - n=getnext(c) - if not n then - return c + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + end + if vowel_modifier[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + c=n + n=getnext(c) + if not n then + return c + end + v=ischar(n,font) + if not v then + return c + end + end + if stress_tone_mark[v] then + return n + else + return c + end +end +local function method_one(head,font,attr) + local current=head + local start=true + local done=false + local nbspaces=0 + while current do + local char=ischar(current,font) + if char then + done=true + local syllablestart=current + local syllableend=nil + local c=current + local n=getnext(c) + local first=char + if n and ra[first] then + local second=ischar(n,font) + if second and halant[second] then + local n=getnext(n) + if n then + local third=ischar(n,font) + if third then + c=n + first=third + end + end end - v=ischar(n,font) - if not v then - return c + end + local standalone=first==c_nbsp + if standalone then + local prev=getprev(current) + if prev then + local prevchar=ischar(prev,font) + if not prevchar then + elseif not separator[prevchar] then + else + standalone=false + end + else end - if v==c_zwnj or v==c_zwj then - c=n - n=getnext(c) + end + if standalone then + local syllableend=analyze_next_chars_one(c,font,2) + current=getnext(syllableend) + if syllablestart~=syllableend then + head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) + current=getnext(current) + end + else + if consonant[char] then + local prevc=true + while prevc do + prevc=false + local n=getnext(current) if not n then - return c + break end - v=ischar(n,font) + local v=ischar(n,font) if not v then - return c + break end - end - else - if dependent_vowel[v] then - c=n - n=getnext(c) - if not n then - return c + if nukta[v] then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end end - v=ischar(n,font) - if not v then - return c + if halant[v] then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + if v==c_zwnj or v==c_zwj then + n=getnext(n) + if not n then + break + end + v=ischar(n,font) + if not v then + break + end + end + if consonant[v] then + prevc=true + current=n + end end - end - if nukta[v] then - c=n - n=getnext(c) - if not n then - return c + end + local n=getnext(current) + if n then + local v=ischar(n,font) + if v and nukta[v] then + current=n + n=getnext(current) end - v=ischar(n,font) + end + syllableend=current + current=n + if current then + local v=ischar(current,font) if not v then - return c + elseif halant[v] then + local n=getnext(current) + if n then + local v=ischar(n,font) + if v and zw_char[v] then + syllableend=n + current=getnext(n) + else + syllableend=current + current=n + end + else + syllableend=current + current=n + end + else + if dependent_vowel[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and vowel_modifier[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and stress_tone_mark[v] then + syllableend=current + current=getnext(current) + end end - end - if halant[v] then - c=n - n=getnext(c) - if not n then - return c + end + if syllablestart~=syllableend then + head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) + current=getnext(current) + end + elseif independent_vowel[char] then + syllableend=current + current=getnext(current) + if current then + local v=ischar(current,font) + if v then + if vowel_modifier[v] then + syllableend=current + current=getnext(current) + v=ischar(current,font) + end + if v and stress_tone_mark[v] then + syllableend=current + current=getnext(current) + end end - v=ischar(n,font) - if not v then - return c + end + else + if show_syntax_errors then + local mark=mark_four[char] + if mark then + head,current=inject_syntax_error(head,current,char) end + end + current=getnext(current) end + end + else + current=getnext(current) end - if vowel_modifier[v] then - c=n - n=getnext(c) - if not n then - return c + start=false + end + if nbspaces>0 then + head=replace_all_nbsp(head) + end + return head,done +end +local function method_two(head,font,attr) + local current=head + local start=true + local done=false + local syllabe=0 + local nbspaces=0 + while current do + local syllablestart=nil + local syllableend=nil + local char=ischar(current,font) + if char then + done=true + syllablestart=current + local c=current + local n=getnext(current) + if n and ra[char] then + local nextchar=ischar(n,font) + if nextchar and halant[nextchar] then + local n=getnext(n) + if n then + local nextnextchar=ischar(n,font) + if nextnextchar then + c=n + char=nextnextchar + end + end end - v=ischar(n,font) - if not v then - return c + end + if independent_vowel[char] then + current=analyze_next_chars_one(c,font,1) + syllableend=current + else + local standalone=char==c_nbsp + if standalone then + nbspaces=nbspaces+1 + local p=getprev(current) + if not p then + elseif ischar(p,font) then + elseif not separator[getchar(p)] then + else + standalone=false + end end + if standalone then + current=analyze_next_chars_one(c,font,2) + syllableend=current + elseif consonant[getchar(current)] then + current=analyze_next_chars_two(current,font) + syllableend=current + end + end + end + if syllableend then + syllabe=syllabe+1 + local c=syllablestart + local n=getnext(syllableend) + while c~=n do + setprop(c,a_syllabe,syllabe) + c=getnext(c) + end end - if stress_tone_mark[v] then - c=n - n=getnext(c) - if not n then - return c - end - v=ischar(n,font) - if not v then - return c - end + if syllableend and syllablestart~=syllableend then + head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces) end - if stress_tone_mark[v] then - return n - else - return c + if not syllableend and show_syntax_errors then + local char=ischar(current,font) + if char and not getprop(current,a_state) then + local mark=mark_four[char] + if mark then + head,current=inject_syntax_error(head,current,char) + end + end end + start=false + current=getnext(current) + end + if nbspaces>0 then + head=replace_all_nbsp(head) + end + return head,done end -local show_syntax_errors=false -local function inject_syntax_error(head,current,char) - local signal=copy_node(current) - copyinjection(signal,current) - if pre_mark[char] then - setchar(signal,dotted_circle) - else - setchar(current,dotted_circle) - end - return insert_node_after(head,current,signal) -end -local function method_one(head,font,attr) - head=tonut(head) - local current=head - local start=true - local done=false - local nbspaces=0 - while current do - local char=ischar(current,font) - if char then - done=true - local syllablestart=current - local syllableend=nil - local c=current - local n=getnext(c) - local first=char - if n and ra[first] then - local second=ischar(n,font) - if second and halant[second] then - local n=getnext(n) - if n then - local third=ischar(n,font) - if third then - c=n - first=third - end - end - end - end - local standalone=first==c_nbsp - if standalone then - local prev=getprev(current) - if prev then - local prevchar=ischar(prev,font) - if not prevchar then - elseif not separator[prevchar] then - else - standalone=false - end - else - end - end - if standalone then - local syllableend=analyze_next_chars_one(c,font,2) - current=getnext(syllableend) - if syllablestart~=syllableend then - head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) - current=getnext(current) - end - else - if consonant[char] then - local prevc=true - while prevc do - prevc=false - local n=getnext(current) - if not n then - break - end - local v=ischar(n,font) - if not v then - break - end - if nukta[v] then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - end - if halant[v] then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - if v==c_zwnj or v==c_zwj then - n=getnext(n) - if not n then - break - end - v=ischar(n,font) - if not v then - break - end - end - if consonant[v] then - prevc=true - current=n - end - end - end - local n=getnext(current) - if n then - local v=ischar(n,font) - if v and nukta[v] then - current=n - n=getnext(current) - end - end - syllableend=current - current=n - if current then - local v=ischar(current,font) - if not v then - elseif halant[v] then - local n=getnext(current) - if n then - local v=ischar(n,font) - if v and zw_char[v] then - syllableend=n - current=getnext(n) - else - syllableend=current - current=n - end - else - syllableend=current - current=n - end - else - if dependent_vowel[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and vowel_modifier[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and stress_tone_mark[v] then - syllableend=current - current=getnext(current) - end - end - end - if syllablestart~=syllableend then - head,current,nbspaces=reorder_one(head,syllablestart,syllableend,font,attr,nbspaces) - current=getnext(current) - end - elseif independent_vowel[char] then - syllableend=current - current=getnext(current) - if current then - local v=ischar(current,font) - if v then - if vowel_modifier[v] then - syllableend=current - current=getnext(current) - v=ischar(current,font) - end - if v and stress_tone_mark[v] then - syllableend=current - current=getnext(current) - end - end - end - else - if show_syntax_errors then - local mark=mark_four[char] - if mark then - head,current=inject_syntax_error(head,current,char) - end - end - current=getnext(current) - end - end - else - current=getnext(current) - end - start=false - end - if nbspaces>0 then - head=replace_all_nbsp(head) - end - return tonode(head),done -end -local function method_two(head,font,attr) - head=tonut(head) - local current=head - local start=true - local done=false - local syllabe=0 - local nbspaces=0 - while current do - local syllablestart=nil - local syllableend=nil - local char=ischar(current,font) - if char then - done=true - syllablestart=current - local c=current - local n=getnext(current) - if n and ra[char] then - local nextchar=ischar(n,font) - if nextchar and halant[nextchar] then - local n=getnext(n) - if n then - local nextnextchar=ischar(n,font) - if nextnextchar then - c=n - char=nextnextchar - end - end - end - end - if independent_vowel[char] then - current=analyze_next_chars_one(c,font,1) - syllableend=current - else - local standalone=char==c_nbsp - if standalone then - nbspaces=nbspaces+1 - local p=getprev(current) - if not p then - elseif ischar(p,font) then - elseif not separator[getchar(p)] then - else - standalone=false - end - end - if standalone then - current=analyze_next_chars_one(c,font,2) - syllableend=current - elseif consonant[getchar(current)] then - current=analyze_next_chars_two(current,font) - syllableend=current - end - end - end - if syllableend then - syllabe=syllabe+1 - local c=syllablestart - local n=getnext(syllableend) - while c~=n do - setprop(c,a_syllabe,syllabe) - c=getnext(c) - end - end - if syllableend and syllablestart~=syllableend then - head,current,nbspaces=reorder_two(head,syllablestart,syllableend,font,attr,nbspaces) - end - if not syllableend and show_syntax_errors then - local char=ischar(current,font) - if char and not getprop(current,a_state) then - local mark=mark_four[char] - if mark then - head,current=inject_syntax_error(head,current,char) - end - end - end - start=false - current=getnext(current) - end - if nbspaces>0 then - head=replace_all_nbsp(head) - end - return tonode(head),done -end -for i=1,nofscripts do - methods[scripts_one[i]]=method_one - methods[scripts_two[i]]=method_two +for i=1,nofscripts do + methods[scripts_one[i]]=method_one + methods[scripts_two[i]]=method_two end end -- closure @@ -29658,11 +31032,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-ocl']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local tostring,tonumber,next=tostring,tonumber,next local round,max=math.round,math.round @@ -29670,450 +31044,450 @@ local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash local setmetatableindex=table.setmetatableindex local formatters=string.formatters local tounicode=fonts.mappings.tounicode +local helpers=fonts.helpers +local charcommand=helpers.commands.char +local rightcommand=helpers.commands.right +local leftcommand=helpers.commands.left +local downcommand=helpers.commands.down local otf=fonts.handlers.otf local f_color=formatters["%.3f %.3f %.3f rg"] local f_gray=formatters["%.3f g"] if context then - local startactualtext=nil - local stopactualtext=nil - function otf.getactualtext(s) - if not startactualtext then - startactualtext=backends.codeinjections.startunicodetoactualtextdirect - stopactualtext=backends.codeinjections.stopunicodetoactualtextdirect - end - return startactualtext(s),stopactualtext() - end + +--removed + else - local tounicode=fonts.mappings.tounicode16 - function otf.getactualtext(s) - return - "/Span << /ActualText >> BDC", - "EMC" - end + local tounicode=fonts.mappings.tounicode16 + function otf.getactualtext(s) + return + "/Span << /ActualText >> BDC", + "EMC" + end end local sharedpalettes={} local hash=setmetatableindex(function(t,k) - local v={ "pdf","direct",k } - t[k]=v - return v + local v={ "pdf","direct",k } + t[k]=v + return v end) if context then - local colors=attributes.list[attributes.private('color')] or {} - local transparencies=attributes.list[attributes.private('transparency')] or {} - function otf.registerpalette(name,values) - sharedpalettes[name]=values - for i=1,#values do - local v=values[i] - local c=nil - local t=nil - if type(v)=="table" then - c=colors.register(name,"rgb", - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - ) - else - c=colors[v] - t=transparencies[v] - end - if c and t then - values[i]=hash[lpdf.color(1,c).." "..lpdf.transparency(t)] - elseif c then - values[i]=hash[lpdf.color(1,c)] - elseif t then - values[i]=hash[lpdf.color(1,t)] - end - end - end + +--removed + else - function otf.registerpalette(name,values) - sharedpalettes[name]=values - for i=1,#values do - local v=values[i] - values[i]=hash[f_color( - max(round((v.r or 0)*255),255)/255, - max(round((v.g or 0)*255),255)/255, - max(round((v.b or 0)*255),255)/255 - )] - end - end + function otf.registerpalette(name,values) + sharedpalettes[name]=values + for i=1,#values do + local v=values[i] + if v then + values[i]=hash[f_color( + max(round((v.r or 0)*255),255)/255, + max(round((v.g or 0)*255),255)/255, + max(round((v.b or 0)*255),255)/255 + )] + end + end + end end local function convert(t,k) - local v={} - for i=1,#k do - local p=k[i] - local r,g,b=p[1],p[2],p[3] - if r==g and g==b then - v[i]=hash[f_gray(r/255)] - else - v[i]=hash[f_color(r/255,g/255,b/255)] - end + local v={} + for i=1,#k do + local p=k[i] + local r,g,b=p[1],p[2],p[3] + if r==g and g==b then + v[i]=hash[f_gray(r/255)] + else + v[i]=hash[f_color(r/255,g/255,b/255)] end - t[k]=v - return v + end + t[k]=v + return v end local start={ "pdf","mode","font" } local push={ "pdf","page","q" } local pop={ "pdf","page","Q" } -if not LUATEXFUNCTIONALITY or LUATEXFUNCTIONALITY<6472 then - start={ "nop" } -end -local function initializecolr(tfmdata,kind,value) - if value then - local resources=tfmdata.resources - local palettes=resources.colorpalettes - if palettes then - local converted=resources.converted - if not converted then - converted=setmetatableindex(convert) - resources.converted=converted - end - local colorvalues=sharedpalettes[value] or converted[palettes[tonumber(value) or 1] or palettes[1]] or {} - local classes=#colorvalues - if classes==0 then - return - end - local characters=tfmdata.characters - local descriptions=tfmdata.descriptions - local properties=tfmdata.properties - properties.virtualized=true - tfmdata.fonts={ - { id=0 } +local function initialize(tfmdata,kind,value) + if value then + local resources=tfmdata.resources + local palettes=resources.colorpalettes + if palettes then + local converted=resources.converted + if not converted then + converted=setmetatableindex(convert) + resources.converted=converted + end + local colorvalues=sharedpalettes[value] + local default=false + if colorvalues then + default=colorvalues[#colorvalues] + else + colorvalues=converted[palettes[tonumber(value) or 1] or palettes[1]] or {} + end + local classes=#colorvalues + if classes==0 then + return + end + local characters=tfmdata.characters + local descriptions=tfmdata.descriptions + local properties=tfmdata.properties + properties.virtualized=true + tfmdata.fonts={ + { id=0 } + } + local getactualtext=otf.getactualtext + local b,e=getactualtext(tounicode(0xFFFD)) + local actualb={ "pdf","page",b } + local actuale={ "pdf","page",e } + for unicode,character in next,characters do + local description=descriptions[unicode] + if description then + local colorlist=description.colors + if colorlist then + local u=description.unicode or characters[unicode].unicode + local w=character.width or 0 + local s=#colorlist + local goback=w~=0 and leftcommand[w] or nil + local t={ + start, + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) } } - local widths=setmetatableindex(function(t,k) - local v={ "right",-k } - t[k]=v - return v - end) - local getactualtext=otf.getactualtext - local default=colorvalues[#colorvalues] - local b,e=getactualtext(tounicode(0xFFFD)) - local actualb={ "pdf","page",b } - local actuale={ "pdf","page",e } - local cache=setmetatableindex(function(t,k) - local v={ "char",k } - t[k]=v - return v - end) - for unicode,character in next,characters do - local description=descriptions[unicode] - if description then - local colorlist=description.colors - if colorlist then - local u=description.unicode or characters[unicode].unicode - local w=character.width or 0 - local s=#colorlist - local goback=w~=0 and widths[w] or nil - local t={ - start, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) } - } - local n=2 - local l=nil - local f=false - for i=1,s do - local entry=colorlist[i] - local v=colorvalues[entry.class] or default - if v and l~=v then - if f then - n=n+1 t[n]=pop - end - n=n+1 t[n]=push - f=true - n=n+1 t[n]=v - l=v - end - n=n+1 t[n]=cache[entry.slot] - if s>1 and i1 and i temp-otf-svg-shape.log","w") - end - end - function otfsvg.topdf(svgshapes) - local pdfshapes={} - local inkscape=runner() - if inkscape then - local nofshapes=#svgshapes - local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] - local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] - local f_convert=formatters["%s --export-pdf=%s\n"] - local filterglyph=otfsvg.filterglyph - local nofdone=0 - report_svg("processing %i svg containers",nofshapes) - statistics.starttiming() - for i=1,nofshapes do - local entry=svgshapes[i] - for index=entry.first,entry.last do - local data=filterglyph(entry,index) - if data and data~="" then - local svgfile=f_svgfile(index) - local pdffile=f_pdffile(index) - savedata(svgfile,data) - inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index]=true - nofdone=nofdone+1 - if nofdone%100==0 then - report_svg("%i shapes processed",nofdone) - end - end - end - end - inkscape:write("quit\n") - inkscape:close() - report_svg("processing %i pdf results",nofshapes) - for index in next,pdfshapes do - local svgfile=f_svgfile(index) - local pdffile=f_pdffile(index) - pdfshapes[index]=loaddata(pdffile) - remove(svgfile) - remove(pdffile) - end - statistics.stoptiming() - if statistics.elapsedseconds then - report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") + local report_svg=logs.reporter("fonts","svg conversion") + local loaddata=io.loaddata + local savedata=io.savedata + local remove=os.remove + if context and xml.convert then + local xmlconvert=xml.convert + local xmlfirst=xml.first + function otfsvg.filterglyph(entry,index) + local svg=xmlconvert(entry.data) + local root=svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']") + local data=root and tostring(root) + return data + end + else + function otfsvg.filterglyph(entry,index) + return entry.data + end + end + local runner=sandbox and sandbox.registerrunner { + name="otfsvg", + program="inkscape", + method="pipeto", + template="--shell > temp-otf-svg-shape.log", + reporter=report_svg, + } + if not runner then + runner=function() + return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + end + end + function otfsvg.topdf(svgshapes) + local pdfshapes={} + local inkscape=runner() + if inkscape then + local nofshapes=#svgshapes + local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert=formatters["%s --export-pdf=%s\n"] + local filterglyph=otfsvg.filterglyph + local nofdone=0 + report_svg("processing %i svg containers",nofshapes) + statistics.starttiming() + for i=1,nofshapes do + local entry=svgshapes[i] + for index=entry.first,entry.last do + local data=filterglyph(entry,index) + if data and data~="" then + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + savedata(svgfile,data) + inkscape:write(f_convert(svgfile,pdffile)) + pdfshapes[index]=true + nofdone=nofdone+1 + if nofdone%100==0 then + report_svg("%i shapes processed",nofdone) end + end end - return pdfshapes + end + inkscape:write("quit\n") + inkscape:close() + report_svg("processing %i pdf results",nofshapes) + for index in next,pdfshapes do + local svgfile=f_svgfile(index) + local pdffile=f_pdffile(index) + pdfshapes[index]=loaddata(pdffile) + remove(svgfile) + remove(pdffile) + end + statistics.stoptiming() + if statistics.elapsedseconds then + report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") + end end + return pdfshapes + end end local function initializesvg(tfmdata,kind,value) - if value and otf.svgenabled then - local svg=tfmdata.properties.svg - local hash=svg and svg.hash - local timestamp=svg and svg.timestamp - if not hash then - return - end - local pdffile=containers.read(otf.pdfcache,hash) - local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then - local svgfile=containers.read(otf.svgcache,hash) - local svgshapes=svgfile and svgfile.svgshapes - pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {} - containers.write(otf.pdfcache,hash,{ - pdfshapes=pdfshapes, - timestamp=timestamp, - }) - end - pdftovirtual(tfmdata,pdfshapes,"svg") - end + if value and otf.svgenabled then + local svg=tfmdata.properties.svg + local hash=svg and svg.hash + local timestamp=svg and svg.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp then + local svgfile=containers.read(otf.svgcache,hash) + local svgshapes=svgfile and svgfile.svgshapes + pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"svg") + end end fonts.handlers.otf.features.register { - name="svg", - description="svg glyphs", - manipulators={ - base=initializesvg, - node=initializesvg, - } + name="svg", + description="svg glyphs", + manipulators={ + base=initializesvg, + node=initializesvg, + } } -local otfsbix=otf.sbix or {} -otf.sbix=otfsbix -otf.sbixenabled=true +local otfpng=otf.png or {} +otf.png=otfpng +otf.pngenabled=true do - local report_sbix=logs.reporter("fonts","sbix conversion") - local loaddata=io.loaddata - local savedata=io.savedata - local remove=os.remove - local runner=sandbox and sandbox.registerrunner { - name="otfsbix", - program="gm", - template="convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log", - } - if not runner then - runner=function() - return os.execute("gm convert -quality 100 temp-otf-sbix-shape.sbix temp-otf-sbix-shape.pdf > temp-otf-svg-shape.log") - end - end - function otfsbix.topdf(sbixshapes) - local pdfshapes={} - local sbixfile="temp-otf-sbix-shape.sbix" - local pdffile="temp-otf-sbix-shape.pdf" - local nofdone=0 - local indices=sortedkeys(sbixshapes) - local nofindices=#indices - report_sbix("processing %i sbix containers",nofindices) - statistics.starttiming() - for i=1,nofindices do - local index=indices[i] - local entry=sbixshapes[index] - local data=entry.data - local x=entry.x - local y=entry.y - savedata(sbixfile,data) - runner() - pdfshapes[index]={ - x=x~=0 and x or nil, - y=y~=0 and y or nil, - data=loaddata(pdffile), - } - nofdone=nofdone+1 - if nofdone%100==0 then - report_sbix("%i shapes processed",nofdone) - end - end - report_sbix("processing %i pdf results",nofindices) - remove(sbixfile) - remove(pdffile) - statistics.stoptiming() - if statistics.elapsedseconds then - report_sbix("sbix conversion time %s",statistics.elapsedseconds() or "-") - end - return pdfshapes - end -end -local function initializesbix(tfmdata,kind,value) - if value and otf.sbixenabled then - local sbix=tfmdata.properties.sbix - local hash=sbix and sbix.hash - local timestamp=sbix and sbix.timestamp - if not hash then - return - end - local pdffile=containers.read(otf.pdfcache,hash) - local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then - local sbixfile=containers.read(otf.sbixcache,hash) - local sbixshapes=sbixfile and sbixfile.sbixshapes - pdfshapes=sbixshapes and otfsbix.topdf(sbixshapes) or {} - containers.write(otf.pdfcache,hash,{ - pdfshapes=pdfshapes, - timestamp=timestamp, - }) - end - pdftovirtual(tfmdata,pdfshapes,"sbix") - end + local report_png=logs.reporter("fonts","png conversion") + local loaddata=io.loaddata + local savedata=io.savedata + local remove=os.remove + local runner=sandbox and sandbox.registerrunner { + name="otfpng", + program="gm", + template="convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log", + } + if not runner then + runner=function() + return os.execute("gm convert -quality 100 temp-otf-png-shape.png temp-otf-png-shape.pdf > temp-otf-svg-shape.log") + end + end + function otfpng.topdf(pngshapes) + local pdfshapes={} + local pngfile="temp-otf-png-shape.png" + local pdffile="temp-otf-png-shape.pdf" + local nofdone=0 + local indices=sortedkeys(pngshapes) + local nofindices=#indices + report_png("processing %i png containers",nofindices) + statistics.starttiming() + for i=1,nofindices do + local index=indices[i] + local entry=pngshapes[index] + local data=entry.data + local x=entry.x + local y=entry.y + savedata(pngfile,data) + runner() + pdfshapes[index]={ + x=x~=0 and x or nil, + y=y~=0 and y or nil, + data=loaddata(pdffile), + } + nofdone=nofdone+1 + if nofdone%100==0 then + report_png("%i shapes processed",nofdone) + end + end + report_png("processing %i pdf results",nofindices) + remove(pngfile) + remove(pdffile) + statistics.stoptiming() + if statistics.elapsedseconds then + report_png("png conversion time %s",statistics.elapsedseconds() or "-") + end + return pdfshapes + end +end +local function initializepng(tfmdata,kind,value) + if value and otf.pngenabled then + local png=tfmdata.properties.png + local hash=png and png.hash + local timestamp=png and png.timestamp + if not hash then + return + end + local pdffile=containers.read(otf.pdfcache,hash) + local pdfshapes=pdffile and pdffile.pdfshapes + if not pdfshapes or pdffile.timestamp~=timestamp then + local pngfile=containers.read(otf.pngcache,hash) + local pngshapes=pngfile and pngfile.pngshapes + pdfshapes=pngshapes and otfpng.topdf(pngshapes) or {} + containers.write(otf.pdfcache,hash,{ + pdfshapes=pdfshapes, + timestamp=timestamp, + }) + end + pdftovirtual(tfmdata,pdfshapes,"png") + end end fonts.handlers.otf.features.register { - name="sbix", - description="sbix glyphs", - manipulators={ - base=initializesbix, - node=initializesbix, - } + name="sbix", + description="sbix glyphs", + manipulators={ + base=initializepng, + node=initializepng, + } +} +fonts.handlers.otf.features.register { + name="cblc", + description="cblc glyphs", + manipulators={ + base=initializepng, + node=initializepng, + } } end -- closure @@ -30121,19 +31495,18 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-otc']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } -local format,insert,sortedkeys,tohash=string.format,table.insert,table.sortedkeys,table.tohash -local type,next=type,next +local insert,sortedkeys,sortedhash,tohash=table.insert,table.sortedkeys,table.sortedhash,table.tohash +local type,next,tonumber=type,next,tonumber local lpegmatch=lpeg.match -local utfbyte,utflen,utfsplit=utf.byte,utf.len,utf.split -local match=string.match +local utfbyte,utflen=utf.byte,utf.len local sortedhash=table.sortedhash -local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) +local trace_loading=false trackers.register("otf.loading",function(v) trace_loading=v end) local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf @@ -30143,922 +31516,742 @@ local checkmerge=fonts.helpers.checkmerge local checkflags=fonts.helpers.checkflags local checksteps=fonts.helpers.checksteps local normalized={ - substitution="substitution", - single="substitution", - ligature="ligature", - alternate="alternate", - multiple="multiple", - kern="kern", - pair="pair", - single="single", - chainsubstitution="chainsubstitution", - chainposition="chainposition", + substitution="substitution", + single="substitution", + ligature="ligature", + alternate="alternate", + multiple="multiple", + kern="kern", + pair="pair", + single="single", + chainsubstitution="chainsubstitution", + chainposition="chainposition", } local types={ - substitution="gsub_single", - ligature="gsub_ligature", - alternate="gsub_alternate", - multiple="gsub_multiple", - kern="gpos_pair", - pair="gpos_pair", - single="gpos_single", - chainsubstitution="gsub_contextchain", - chainposition="gpos_contextchain", + substitution="gsub_single", + ligature="gsub_ligature", + alternate="gsub_alternate", + multiple="gsub_multiple", + kern="gpos_pair", + pair="gpos_pair", + single="gpos_single", + chainsubstitution="gsub_contextchain", + chainposition="gpos_contextchain", } local names={ - gsub_single="gsub", - gsub_multiple="gsub", - gsub_alternate="gsub", - gsub_ligature="gsub", - gsub_context="gsub", - gsub_contextchain="gsub", - gsub_reversecontextchain="gsub", - gpos_single="gpos", - gpos_pair="gpos", - gpos_cursive="gpos", - gpos_mark2base="gpos", - gpos_mark2ligature="gpos", - gpos_mark2mark="gpos", - gpos_context="gpos", - gpos_contextchain="gpos", + gsub_single="gsub", + gsub_multiple="gsub", + gsub_alternate="gsub", + gsub_ligature="gsub", + gsub_context="gsub", + gsub_contextchain="gsub", + gsub_reversecontextchain="gsub", + gpos_single="gpos", + gpos_pair="gpos", + gpos_cursive="gpos", + gpos_mark2base="gpos", + gpos_mark2ligature="gpos", + gpos_mark2mark="gpos", + gpos_context="gpos", + gpos_contextchain="gpos", } setmetatableindex(types,function(t,k) t[k]=k return k end) local everywhere={ ["*"]={ ["*"]=true } } local noflags={ false,false,false,false } local function getrange(sequences,category) - local count=#sequences - local first=nil - local last=nil - for i=1,count do - local t=sequences[i].type - if t and names[t]==category then - if not first then - first=i - end - last=i - end - end - return first or 1,last or count + local count=#sequences + local first=nil + local last=nil + for i=1,count do + local t=sequences[i].type + if t and names[t]==category then + if not first then + first=i + end + last=i + end + end + return first or 1,last or count end local function validspecification(specification,name) - local dataset=specification.dataset - if dataset then - elseif specification[1] then - dataset=specification - specification={ dataset=dataset } - else - dataset={ { data=specification.data } } - specification.data=nil - specification.dataset=dataset - end - local first=dataset[1] - if first then - first=first.data - end - if not first then - report_otf("invalid feature specification, no dataset") - return - end - if type(name)~="string" then - name=specification.name or first.name - end - if type(name)~="string" then - report_otf("invalid feature specification, no name") - return - end - local n=#dataset - if n>0 then - for i=1,n do - setmetatableindex(dataset[i],specification) - end - return specification,name + local dataset=specification.dataset + if dataset then + elseif specification[1] then + dataset=specification + specification={ dataset=dataset } + else + dataset={ { data=specification.data } } + specification.data=nil + specification.dataset=dataset + end + local first=dataset[1] + if first then + first=first.data + end + if not first then + report_otf("invalid feature specification, no dataset") + return + end + if type(name)~="string" then + name=specification.name or first.name + end + if type(name)~="string" then + report_otf("invalid feature specification, no name") + return + end + local n=#dataset + if n>0 then + for i=1,n do + setmetatableindex(dataset[i],specification) end + return specification,name + end end local function addfeature(data,feature,specifications) - if not specifications then - report_otf("missing specification") - return - end - local descriptions=data.descriptions - local resources=data.resources - local features=resources.features - local sequences=resources.sequences - if not features or not sequences then - report_otf("missing specification") - return - end - local alreadydone=resources.alreadydone - if not alreadydone then - alreadydone={} - resources.alreadydone=alreadydone - end - if alreadydone[specifications] then - return - else - alreadydone[specifications]=true - end - local fontfeatures=resources.features or everywhere - local unicodes=resources.unicodes - local splitter=lpeg.splitter(" ",unicodes) - local done=0 - local skip=0 - local aglunicodes=false - local specifications=validspecification(specifications,feature) - if not specifications then - return - end - local function tounicode(code) - if not code then - return + if not specifications then + report_otf("missing specification") + return + end + local descriptions=data.descriptions + local resources=data.resources + local features=resources.features + local sequences=resources.sequences + if not features or not sequences then + report_otf("missing specification") + return + end + local alreadydone=resources.alreadydone + if not alreadydone then + alreadydone={} + resources.alreadydone=alreadydone + end + if alreadydone[specifications] then + return + else + alreadydone[specifications]=true + end + local fontfeatures=resources.features or everywhere + local unicodes=resources.unicodes + local splitter=lpeg.splitter(" ",unicodes) + local done=0 + local skip=0 + local aglunicodes=false + local specifications=validspecification(specifications,feature) + if not specifications then + return + end + local p=lpeg.P("P")*(lpeg.patterns.hexdigit^1/function(s) return tonumber(s,16) end)*lpeg.P(-1) + local function tounicode(code) + if not code then + return + end + if type(code)=="number" then + return code + end + local u=unicodes[code] + if u then + return u + end + if utflen(code)==1 then + u=utfbyte(code) + if u then + return u + end + end + local u=lpegmatch(p,code) + if u then + return u + end + if not aglunicodes then + aglunicodes=fonts.encodings.agl.unicodes + end + local u=aglunicodes[code] + if u then + return u + end + end + local coverup=otf.coverup + local coveractions=coverup.actions + local stepkey=coverup.stepkey + local register=coverup.register + local function prepare_substitution(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(replacement)=="table" then + replacement=replacement[1] + end + replacement=tounicode(replacement) + if replacement and descriptions[replacement] then + cover(coverage,unicode,replacement) + done=done+1 + else + skip=skip+1 end - if type(code)=="number" then - return code + end + end + return coverage + end + local function prepare_alternate(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + for i=1,#replacement do + local u=tounicode(replacement[i]) + r[i]=(nocheck or descriptions[u]) and u or unicode end - local u=unicodes[code] + cover(coverage,unicode,r) + done=done+1 + else + local u=tounicode(replacement) if u then - return u + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 end - if utflen(code)==1 then - u=utfbyte(code) - if u then - return u - end - end - if not aglunicodes then - aglunicodes=fonts.encodings.agl.unicodes - end - return aglunicodes[code] - end - local coverup=otf.coverup - local coveractions=coverup.actions - local stepkey=coverup.stepkey - local register=coverup.register - local function prepare_substitution(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - else - if type(replacement)=="table" then - replacement=replacement[1] - end - replacement=tounicode(replacement) - if replacement and descriptions[replacement] then - cover(coverage,unicode,replacement) - done=done+1 - else - skip=skip+1 - end - end + end + end + return coverage + end + local function prepare_multiple(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + elseif type(replacement)=="table" then + local r={} + local n=0 + for i=1,#replacement do + local u=tounicode(replacement[i]) + if nocheck or descriptions[u] then + n=n+1 + r[n]=u + end end - return coverage - end - local function prepare_alternate(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - elseif type(replacement)=="table" then - local r={} - for i=1,#replacement do - local u=tounicode(replacement[i]) - r[i]=(nocheck or descriptions[u]) and u or unicode - end - cover(coverage,unicode,r) - done=done+1 - else - local u=tounicode(replacement) - if u then - cover(coverage,unicode,{ u }) - done=done+1 - else - skip=skip+1 - end - end + if n>0 then + cover(coverage,unicode,r) + done=done+1 + else + skip=skip+1 end - return coverage - end - local function prepare_multiple(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - elseif type(replacement)=="table" then - local r,n={},0 - for i=1,#replacement do - local u=tounicode(replacement[i]) - if nocheck or descriptions[u] then - n=n+1 - r[n]=u - end - end - if n>0 then - cover(coverage,unicode,r) - done=done+1 - else - skip=skip+1 - end - else - local u=tounicode(replacement) - if u then - cover(coverage,unicode,{ u }) - done=done+1 - else - skip=skip+1 - end - end + else + local u=tounicode(replacement) + if u then + cover(coverage,unicode,{ u }) + done=done+1 + else + skip=skip+1 end - return coverage + end end - local function prepare_ligature(list,featuretype,nocheck) - local coverage={} - local cover=coveractions[featuretype] - for code,ligature in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if not nocheck and not description then - skip=skip+1 - else - if type(ligature)=="string" then - ligature={ lpegmatch(splitter,ligature) } - end - local present=true - for i=1,#ligature do - local l=ligature[i] - local u=tounicode(l) - if nocheck or descriptions[u] then - ligature[i]=u - else - present=false - break - end - end - if present then - cover(coverage,unicode,ligature) - done=done+1 - else - skip=skip+1 - end - end + return coverage + end + local function prepare_ligature(list,featuretype,nocheck) + local coverage={} + local cover=coveractions[featuretype] + for code,ligature in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if not nocheck and not description then + skip=skip+1 + else + if type(ligature)=="string" then + ligature={ lpegmatch(splitter,ligature) } + end + local present=true + for i=1,#ligature do + local l=ligature[i] + local u=tounicode(l) + if nocheck or descriptions[u] then + ligature[i]=u + else + present=false + break + end end - return coverage - end - local function resetspacekerns() - data.properties.hasspacekerns=true - data.resources .spacekerns=nil - end - local function prepare_kern(list,featuretype) - local coverage={} - local cover=coveractions[featuretype] - local isspace=false - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if description and type(replacement)=="table" then - local r={} - for k,v in next,replacement do - local u=tounicode(k) - if u then - r[u]=v - if u==32 then - isspace=true - end - end - end - if next(r) then - cover(coverage,unicode,r) - done=done+1 - if unicode==32 then - isspace=true - end - else - skip=skip+1 - end - else - skip=skip+1 - end - end - if isspace then - resetspacekerns() - end - return coverage - end - local function prepare_pair(list,featuretype) - local coverage={} - local cover=coveractions[featuretype] - if cover then - for code,replacement in next,list do - local unicode=tounicode(code) - local description=descriptions[unicode] - if description and type(replacement)=="table" then - local r={} - for k,v in next,replacement do - local u=tounicode(k) - if u then - r[u]=v - if u==32 then - isspace=true - end - end - end - if next(r) then - cover(coverage,unicode,r) - done=done+1 - if unicode==32 then - isspace=true - end - else - skip=skip+1 - end - else - skip=skip+1 - end - end - if isspace then - resetspacekerns() - end + if present then + cover(coverage,unicode,ligature) + done=done+1 else - report_otf("unknown cover type %a",featuretype) + skip=skip+1 end - return coverage + end end - local prepare_single=prepare_pair - local function prepare_chain(list,featuretype,sublookups) - local rules=list.rules - local coverage={} - if rules then - local rulehash={} - local rulesize=0 - local lookuptype=types[featuretype] - for nofrules=1,#rules do - local rule=rules[nofrules] - local current=rule.current - local before=rule.before - local after=rule.after - local replacements=rule.replacements or false - local sequence={} - local nofsequences=0 - if before then - for n=1,#before do - nofsequences=nofsequences+1 - sequence[nofsequences]=before[n] - end - end - local start=nofsequences+1 - for n=1,#current do - nofsequences=nofsequences+1 - sequence[nofsequences]=current[n] - end - local stop=nofsequences - if after then - for n=1,#after do - nofsequences=nofsequences+1 - sequence[nofsequences]=after[n] - end - end - local lookups=rule.lookups or false - local subtype=nil - if lookups and sublookups then - for k,v in sortedhash(lookups) do - local t=type(v) - if t=="table" then - for i=1,#v do - local vi=v[i] - if type(vi)~="table" then - v[i]={ vi } - end - end - elseif t=="number" then - local lookup=sublookups[v] - if lookup then - lookups[k]={ lookup } - if not subtype then - subtype=lookup.type - end - else - lookups[k]=false - end - else - lookups[k]=false - end - end - end - if nofsequences>0 then - local hashed={} - for i=1,nofsequences do - local t={} - local s=sequence[i] - for i=1,#s do - local u=tounicode(s[i]) - if u then - t[u]=true - end - end - hashed[i]=t - end - sequence=hashed - rulesize=rulesize+1 - rulehash[rulesize]={ - nofrules, - lookuptype, - sequence, - start, - stop, - lookups, - replacements, - subtype, - } - for unic in sortedhash(sequence[start]) do - local cu=coverage[unic] - if not cu then - coverage[unic]=rulehash - end - end - sequence.n=nofsequences - end + return coverage + end + local function resetspacekerns() + data.properties.hasspacekerns=true + data.resources .spacekerns=nil + end + local function prepare_kern(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + local isspace=false + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true end - rulehash.n=rulesize + end end - return coverage + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true + end + else + skip=skip+1 + end + else + skip=skip+1 + end end - local dataset=specifications.dataset - local function report(name,category,position,first,last,sequences) - report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", - name,category,position,first,last,1,#sequences) + if isspace then + resetspacekerns() end - local function inject(specification,sequences,sequence,first,last,category,name) - local position=specification.position or false - if not position then - position=specification.prepend - if position==true then - if trace_loading then - report(name,category,first,first,last,sequences) - end - insert(sequences,first,sequence) - return + return coverage + end + local function prepare_pair(list,featuretype) + local coverage={} + local cover=coveractions[featuretype] + if cover then + for code,replacement in next,list do + local unicode=tounicode(code) + local description=descriptions[unicode] + if description and type(replacement)=="table" then + local r={} + for k,v in next,replacement do + local u=tounicode(k) + if u then + r[u]=v + if u==32 then + isspace=true + end end - end - if not position then - position=specification.append - if position==true then - if trace_loading then - report(name,category,last+1,first,last,sequences) - end - insert(sequences,last+1,sequence) - return + end + if next(r) then + cover(coverage,unicode,r) + done=done+1 + if unicode==32 then + isspace=true end + else + skip=skip+1 + end + else + skip=skip+1 end - local kind=type(position) - if kind=="string" then - local index=false - for i=first,last do - local s=sequences[i] - local f=s.features - if f then - for k in sortedhash(f) do - if k==position then - index=i - break - end - end - if index then - break - end + end + if isspace then + resetspacekerns() + end + else + report_otf("unknown cover type %a",featuretype) + end + return coverage + end + local prepare_single=prepare_pair + local function prepare_chain(list,featuretype,sublookups) + local rules=list.rules + local coverage={} + if rules then + local rulehash={} + local rulesize=0 + local lookuptype=types[featuretype] + for nofrules=1,#rules do + local rule=rules[nofrules] + local current=rule.current + local before=rule.before + local after=rule.after + local replacements=rule.replacements or false + local sequence={} + local nofsequences=0 + if before then + for n=1,#before do + nofsequences=nofsequences+1 + sequence[nofsequences]=before[n] + end + end + local start=nofsequences+1 + for n=1,#current do + nofsequences=nofsequences+1 + sequence[nofsequences]=current[n] + end + local stop=nofsequences + if after then + for n=1,#after do + nofsequences=nofsequences+1 + sequence[nofsequences]=after[n] + end + end + local lookups=rule.lookups or false + local subtype=nil + if lookups and sublookups then + for k,v in sortedhash(lookups) do + local t=type(v) + if t=="table" then + for i=1,#v do + local vi=v[i] + if type(vi)~="table" then + v[i]={ vi } end - end - if index then - position=index + end + elseif t=="number" then + local lookup=sublookups[v] + if lookup then + lookups[k]={ lookup } + if not subtype then + subtype=lookup.type + end + elseif v==0 then + lookups[k]={ { type="gsub_remove" } } + else + lookups[k]=false + end else - position=last+1 - end - elseif kind=="number" then - if position<0 then - position=last-position+1 + lookups[k]=false end - if position>last then - position=last+1 - elseif position0 then + local hashed={} + for i=1,nofsequences do + local t={} + local s=sequence[i] + for i=1,#s do + local u=tounicode(s[i]) + if u then + t[u]=true + end end - if nofsteps>0 then - for k,v in next,askedfeatures do - if v[1] then - askedfeatures[k]=tohash(v) - end - end - if featureflags[1] then featureflags[1]="mark" end - if featureflags[2] then featureflags[2]="ligature" end - if featureflags[3] then featureflags[3]="base" end - local steptype=types[featuretype] - local sequence={ - chain=featurechain, - features={ [feature]=askedfeatures }, - flags=featureflags, - name=feature, - order=featureorder, - [stepkey]=steps, - nofsteps=nofsteps, - type=steptype, - } - checkflags(sequence,resources) - checkmerge(sequence) - checksteps(sequence) - local first,last=getrange(sequences,category) - inject(specification,sequences,sequence,first,last,category,feature) - local features=fontfeatures[category] - if not features then - features={} - fontfeatures[category]=features - end - local k=features[feature] - if not k then - k={} - features[feature]=k - end - for script,languages in next,askedfeatures do - local kk=k[script] - if not kk then - kk={} - k[script]=kk - end - for language,value in next,languages do - kk[language]=value - end - end + hashed[i]=t + end + sequence=hashed + rulesize=rulesize+1 + rulehash[rulesize]={ + nofrules, + lookuptype, + sequence, + start, + stop, + lookups, + replacements, + subtype, + } + for unic in sortedhash(sequence[start]) do + local cu=coverage[unic] + if not cu then + coverage[unic]=rulehash end + end + sequence.n=nofsequences end + end + rulehash.n=rulesize end - if trace_loading then - report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) - end -end -otf.enhancers.addfeature=addfeature -local extrafeatures={} -local knownfeatures={} -function otf.addfeature(name,specification) - if type(name)=="table" then - specification=name - end - if type(specification)~="table" then - report_otf("invalid feature specification, no valid table") + return coverage + end + local dataset=specifications.dataset + local function report(name,category,position,first,last,sequences) + report_otf("injecting name %a of category %a at position %i in [%i,%i] of [%i,%i]", + name,category,position,first,last,1,#sequences) + end + local function inject(specification,sequences,sequence,first,last,category,name) + local position=specification.position or false + if not position then + position=specification.prepend + if position==true then + if trace_loading then + report(name,category,first,first,last,sequences) + end + insert(sequences,first,sequence) return + end end - specification,name=validspecification(specification,name) - if name and specification then - local slot=knownfeatures[name] - if not slot then - slot=#extrafeatures+1 - knownfeatures[name]=slot - elseif specification.overload==false then - slot=#extrafeatures+1 - knownfeatures[name]=slot - else + if not position then + position=specification.append + if position==true then + if trace_loading then + report(name,category,last+1,first,last,sequences) end - specification.name=name - extrafeatures[slot]=specification - end -end -local function enhance(data,filename,raw) - for slot=1,#extrafeatures do - local specification=extrafeatures[slot] - addfeature(data,specification.name,specification) - end -end -otf.enhancers.enhance=enhance -otf.enhancers.register("check extra features",enhance) -local tlig={ - [0x2013]={ 0x002D,0x002D }, - [0x2014]={ 0x002D,0x002D,0x002D }, -} -local tlig_specification={ - type="ligature", - features=everywhere, - data=tlig, - order={ "tlig" }, - flags=noflags, - prepend=true, -} -otf.addfeature("tlig",tlig_specification) -registerotffeature { - name='tlig', - description='tex ligatures', -} -local trep={ - [0x0027]=0x2019, -} -local trep_specification={ - type="substitution", - features=everywhere, - data=trep, - order={ "trep" }, - flags=noflags, - prepend=true, -} -otf.addfeature("trep",trep_specification) -registerotffeature { - name='trep', - description='tex replacements', -} -local anum_arabic={ - [0x0030]=0x0660, - [0x0031]=0x0661, - [0x0032]=0x0662, - [0x0033]=0x0663, - [0x0034]=0x0664, - [0x0035]=0x0665, - [0x0036]=0x0666, - [0x0037]=0x0667, - [0x0038]=0x0668, - [0x0039]=0x0669, -} -local anum_persian={ - [0x0030]=0x06F0, - [0x0031]=0x06F1, - [0x0032]=0x06F2, - [0x0033]=0x06F3, - [0x0034]=0x06F4, - [0x0035]=0x06F5, - [0x0036]=0x06F6, - [0x0037]=0x06F7, - [0x0038]=0x06F8, - [0x0039]=0x06F9, -} -local function valid(data) - local features=data.resources.features - if features then - for k,v in next,features do - for k,v in next,v do - if v.arab then - return true - end + insert(sequences,last+1,sequence) + return + end + end + local kind=type(position) + if kind=="string" then + local index=false + for i=first,last do + local s=sequences[i] + local f=s.features + if f then + for k in sortedhash(f) do + if k==position then + index=i + break end + end + if index then + break + end end + end + if index then + position=index + else + position=last+1 + end + elseif kind=="number" then + if position<0 then + position=last-position+1 + end + if position>last then + position=last+1 + elseif position1 then - local one=current[1] - local two=current[2] - lookups[one]={ one,zwjchar } - local one={ one } - local two={ two } - local new=#protect+1 - protect[new]={ - before=before, - current={ one,two }, - after=after, - lookups={ 1 }, - } - revert[new]={ - current={ one,zwj }, - after={ two }, - lookups={ 1 }, - } + report_otf("not registering feature %a, unknown category",feature) + return + end + if coverage and next(coverage) then + nofsteps=nofsteps+1 + steps[nofsteps]=register(coverage,featuretype,format,feature,nofsteps,descriptions,resources) + end + end + if nofsteps>0 then + for k,v in next,askedfeatures do + if v[1] then + askedfeatures[k]=tohash(v) + end end + if featureflags[1] then featureflags[1]="mark" end + if featureflags[2] then featureflags[2]="ligature" end + if featureflags[3] then featureflags[3]="base" end + local steptype=types[featuretype] + local sequence={ + chain=featurechain, + features={ [feature]=askedfeatures }, + flags=featureflags, + name=feature, + order=featureorder, + [stepkey]=steps, + nofsteps=nofsteps, + type=steptype, + } + checkflags(sequence,resources) + checkmerge(sequence) + checksteps(sequence) + local first,last=getrange(sequences,category) + inject(specification,sequences,sequence,first,last,category,feature) + local features=fontfeatures[category] + if not features then + features={} + fontfeatures[category]=features + end + local k=features[feature] + if not k then + k={} + features[feature]=k + end + for script,languages in next,askedfeatures do + local kk=k[script] + if not kk then + kk={} + k[script]=kk + end + for language,value in next,languages do + kk[language]=value + end + end + end end + end + if trace_loading then + report_otf("registering feature %a, affected glyphs %a, skipped glyphs %a",feature,done,skip) + end end -otf.helpers.blockligatures=blockligatures -if context then - interfaces.implement { - name="blockligatures", - arguments="string", - actions=blockligatures, - } +otf.enhancers.addfeature=addfeature +local extrafeatures={} +local knownfeatures={} +function otf.addfeature(name,specification) + if type(name)=="table" then + specification=name + end + if type(specification)~="table" then + report_otf("invalid feature specification, no valid table") + return + end + specification,name=validspecification(specification,name) + if name and specification then + local slot=knownfeatures[name] + if not slot then + slot=#extrafeatures+1 + knownfeatures[name]=slot + elseif specification.overload==false then + slot=#extrafeatures+1 + knownfeatures[name]=slot + else + end + specification.name=name + extrafeatures[slot]=specification + end +end +local function enhance(data,filename,raw) + for slot=1,#extrafeatures do + local specification=extrafeatures[slot] + addfeature(data,specification.name,specification) + end end +otf.enhancers.enhance=enhance +otf.enhancers.register("check extra features",enhance) end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-onr']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset @@ -31066,10 +32259,10 @@ local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.s local char,byte,sub=string.char,string.byte,string.sub local abs=math.abs local bxor,rshift=bit32.bxor,bit32.rshift -local P,S,R,Cmt,C,Ct,Cs,Carg,Cf,Cg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg +local P,S,R,V,Cmt,C,Ct,Cs,Carg,Cf,Cg,Cc=lpeg.P,lpeg.S,lpeg.R,lpeg.V,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cf,lpeg.Cg,lpeg.Cc local lpegmatch,patterns=lpeg.match,lpeg.patterns -local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) -local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) +local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) +local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) local report_afm=logs.reporter("fonts","afm loading") local report_pfb=logs.reporter("fonts","pfb loading") local handlers=fonts.handlers @@ -31080,161 +32273,180 @@ afm.readers=readers afm.version=1.513 local get_indexes,get_shapes do - local decrypt - do - local r,c1,c2,n=0,0,0,0 - local function step(c) - local cipher=byte(c) - local plain=bxor(cipher,rshift(r,8)) - r=((cipher+r)*c1+c2)%65536 - return char(plain) - end - decrypt=function(binary,initial,seed) - r,c1,c2,n=initial,52845,22719,seed - binary=gsub(binary,".",step) - return sub(binary,n+1) - end - end - local charstrings=P("/CharStrings") - local subroutines=P("/Subrs") - local encoding=P("/Encoding") - local dup=P("dup") - local put=P("put") - local array=P("array") - local name=P("/")*C((R("az","AZ","09")+S("-_."))^1) - local digits=R("09")^1 - local cardinal=digits/tonumber - local spaces=P(" ")^1 - local spacing=patterns.whitespace^0 - local routines,vector,chars,n,m - local initialize=function(str,position,size) - n=0 - m=size - return position+1 - end - local setroutine=function(str,position,index,size,filename) - local forward=position+tonumber(size) - local stream=decrypt(sub(str,position+1,forward),4330,4) - routines[index]={ byte(stream,1,#stream) } - return forward - end - local setvector=function(str,position,name,size,filename) - local forward=position+tonumber(size) - if n>=m then - return #str - elseif forward<#str then - if n==0 and name~=".notdef" then - report_pfb("reserving .notdef at index 0 in %a",filename) - n=n+1 - end - vector[n]=name - n=n+1 - return forward - else - return #str - end - end - local setshapes=function(str,position,name,size,filename) - local forward=position+tonumber(size) - local stream=sub(str,position+1,forward) - if n>m then - return #str - elseif forward<#str then - if n==0 and name~=".notdef" then - report_pfb("reserving .notdef at index 0 in %a",filename) - n=n+1 - end - vector[n]=name - n=n+1 - chars [n]=decrypt(stream,4330,4) - return forward - else - return #str - end - end - local p_rd=spacing*(P("RD")+P("-|")) - local p_np=spacing*(P("NP")+P("|")) - local p_nd=spacing*(P("ND")+P("|")) - local p_filterroutines= - (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+P(1))^1 - local p_filtershapes= - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1 - local p_filternames=Ct ( - (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1 - ) - local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( - Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 + local decrypt + do + local r,c1,c2,n=0,0,0,0 + local function step(c) + local cipher=byte(c) + local plain=bxor(cipher,rshift(r,8)) + r=((cipher+r)*c1+c2)%65536 + return char(plain) + end + decrypt=function(binary,initial,seed) + r,c1,c2,n=initial,52845,22719,seed + binary=gsub(binary,".",step) + return sub(binary,n+1) + end + end + local charstrings=P("/CharStrings") + local subroutines=P("/Subrs") + local encoding=P("/Encoding") + local dup=P("dup") + local put=P("put") + local array=P("array") + local name=P("/")*C((R("az","AZ","09")+S("-_."))^1) + local digits=R("09")^1 + local cardinal=digits/tonumber + local spaces=P(" ")^1 + local spacing=patterns.whitespace^0 + local routines,vector,chars,n,m + local initialize=function(str,position,size) + n=0 + m=size + return position+1 + end + local setroutine=function(str,position,index,size,filename) + if routines[index] then + return false + end + local forward=position+size + local stream=decrypt(sub(str,position+1,forward),4330,4) + routines[index]={ byte(stream,1,#stream) } + n=n+1 + if n>=m then + return #str + end + return forward+1 + end + local setvector=function(str,position,name,size,filename) + local forward=position+tonumber(size) + if n>=m then + return #str + elseif forward<#str then + if n==0 and name~=".notdef" then + report_pfb("reserving .notdef at index 0 in %a",filename) + n=n+1 + end + vector[n]=name + n=n+1 + return forward + else + return #str + end + end + local setshapes=function(str,position,name,size,filename) + local forward=position+tonumber(size) + local stream=sub(str,position+1,forward) + if n>m then + return #str + elseif forward<#str then + if n==0 and name~=".notdef" then + report_pfb("reserving .notdef at index 0 in %a",filename) + n=n+1 + end + vector[n]=name + n=n+1 + chars [n]=decrypt(stream,4330,4) + return forward + else + return #str + end + end + local p_rd=spacing*(P("RD")+P("-|")) + local p_np=spacing*(P("NP")+P("|")) + local p_nd=spacing*(P("ND")+P("|")) + local p_filterroutines= + (1-subroutines)^0*subroutines*spaces*Cmt(cardinal,initialize)*(Cmt(cardinal*spaces*cardinal*p_rd*Carg(1),setroutine)*p_np+(1-p_nd))^1 + local p_filtershapes= + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*p_rd*Carg(1),setshapes)*p_nd+P(1))^1 + local p_filternames=Ct ( + (1-charstrings)^0*charstrings*spaces*Cmt(cardinal,initialize)*(Cmt(name*spaces*cardinal*Carg(1),setvector)+P(1))^1 + ) + local p_filterencoding=(1-encoding)^0*encoding*spaces*digits*spaces*array*(1-dup)^0*Cf( + Ct("")*Cg(spacing*dup*spaces*cardinal*spaces*name*spaces*put)^1 ,rawset) - local function loadpfbvector(filename,shapestoo) - local data=io.loaddata(resolvers.findfile(filename)) - if not data then - report_pfb("no data in %a",filename) - return - end - if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then - report_pfb("no font in %a",filename) - return - end - local ascii,binary=match(data,"(.*)eexec%s+......(.*)") - if not binary then - report_pfb("no binary data in %a",filename) - return - end - binary=decrypt(binary,55665,4) - local names={} - local encoding=lpegmatch(p_filterencoding,ascii) - local glyphs={} - routines,vector,chars={},{},{} - if shapestoo then - lpegmatch(p_filterroutines,binary,1,filename) - lpegmatch(p_filtershapes,binary,1,filename) - local data={ - dictionaries={ - { - charstrings=chars, - charset=vector, - subroutines=routines, - } - }, - } - fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,true) + local key=spacing*P("/")*R("az","AZ") + local str=spacing*Cs { (P("(")/"")*((1-P("\\(")-P("\\)")-S("()"))+V(1))^0*(P(")")/"") } + local num=spacing*(R("09")+S("+-."))^1/tonumber + local arr=spacing*Ct (S("[{")*(num)^0*spacing*S("]}")) + local boo=spacing*(P("true")*Cc(true)+P("false")*Cc(false)) + local nam=spacing*P("/")*Cs(R("az","AZ")^1) + local p_filtermetadata=( + P("/")*Carg(1)*(( + C("version")*str+C("Copyright")*str+C("Notice")*str+C("FullName")*str+C("FamilyName")*str+C("Weight")*str+C("ItalicAngle")*num+C("isFixedPitch")*boo+C("UnderlinePosition")*num+C("UnderlineThickness")*num+C("FontName")*nam+C("FontMatrix")*arr+C("FontBBox")*arr + ) )/function(t,k,v) t[lower(k)]=v end+P(1) + )^0*Carg(1) + local function loadpfbvector(filename,shapestoo,streams) + local data=io.loaddata(resolvers.findfile(filename)) + if not data then + report_pfb("no data in %a",filename) + return + end + if not (find(data,"!PS-AdobeFont-",1,true) or find(data,"%!FontType1",1,true)) then + report_pfb("no font in %a",filename) + return + end + local ascii,binary=match(data,"(.*)eexec%s+......(.*)") + if not binary then + report_pfb("no binary data in %a",filename) + return + end + binary=decrypt(binary,55665,4) + local names={} + local encoding=lpegmatch(p_filterencoding,ascii) + local metadata=lpegmatch(p_filtermetadata,ascii,1,{}) + local glyphs={} + routines,vector,chars={},{},{} + if shapestoo or streams then + lpegmatch(p_filterroutines,binary,1,filename) + lpegmatch(p_filtershapes,binary,1,filename) + local data={ + dictionaries={ + { + charstrings=chars, + charset=vector, + subroutines=routines, + } + }, + } + fonts.handlers.otf.readers.parsecharstrings(false,data,glyphs,true,"cff",streams) + else + lpegmatch(p_filternames,binary,1,filename) + end + names=vector + routines,vector,chars=nil,nil,nil + return names,encoding,glyphs,metadata + end + local pfb=handlers.pfb or {} + handlers.pfb=pfb + pfb.loadvector=loadpfbvector + get_indexes=function(data,pfbname) + local vector=loadpfbvector(pfbname) + if vector then + local characters=data.characters + if trace_loading then + report_afm("getting index data from %a",pfbname) + end + for index=0,#vector do + local name=vector[index] + local char=characters[name] + if char then + if trace_indexing then + report_afm("glyph %a has index %a",name,index) + end + char.index=index else - lpegmatch(p_filternames,binary,1,filename) - end - names=vector - routines,vector,chars=nil,nil,nil - return names,encoding,glyphs - end - local pfb=handlers.pfb or {} - handlers.pfb=pfb - pfb.loadvector=loadpfbvector - get_indexes=function(data,pfbname) - local vector=loadpfbvector(pfbname) - if vector then - local characters=data.characters - if trace_loading then - report_afm("getting index data from %a",pfbname) - end - for index=0,#vector do - local name=vector[index] - local char=characters[name] - if char then - if trace_indexing then - report_afm("glyph %a has index %a",name,index) - end - char.index=index - else - if trace_indexing then - report_afm("glyph %a has index %a but no data",name,index) - end - end - end + if trace_indexing then + report_afm("glyph %a has index %a but no data",name,index) + end end + end end - get_shapes=function(pfbname) - local vector,encoding,glyphs=loadpfbvector(pfbname,true) - return glyphs - end + end + get_shapes=function(pfbname) + local vector,encoding,glyphs=loadpfbvector(pfbname,true) + return glyphs + end end local spacer=patterns.spacer local whitespace=patterns.whitespace @@ -31249,74 +32461,74 @@ local semicolon=spacing*P(";") local plus=spacing*P("plus")*number local minus=spacing*P("minus")*number local function addkernpair(data,one,two,value) - local chr=data.characters[one] - if chr then - local kerns=chr.kerns - if kerns then - kerns[two]=tonumber(value) - else - chr.kerns={ [two]=tonumber(value) } - end + local chr=data.characters[one] + if chr then + local kerns=chr.kerns + if kerns then + kerns[two]=tonumber(value) + else + chr.kerns={ [two]=tonumber(value) } end + end end local p_kernpair=(fontdata*P("KPX")*name*name*number)/addkernpair local chr=false local ind=0 local function start(data,version) - data.metadata.afmversion=version - ind=0 - chr={} + data.metadata.afmversion=version + ind=0 + chr={} end local function stop() - ind=0 - chr=false + ind=0 + chr=false end local function setindex(i) - if i<0 then - ind=ind+1 - else - ind=i - end - chr={ - index=ind - } + if i<0 then + ind=ind+1 + else + ind=i + end + chr={ + index=ind + } end local function setwidth(width) - chr.width=width + chr.width=width end local function setname(data,name) - data.characters[name]=chr + data.characters[name]=chr end local function setboundingbox(boundingbox) - chr.boundingbox=boundingbox + chr.boundingbox=boundingbox end local function setligature(plus,becomes) - local ligatures=chr.ligatures - if ligatures then - ligatures[plus]=becomes - else - chr.ligatures={ [plus]=becomes } - end + local ligatures=chr.ligatures + if ligatures then + ligatures[plus]=becomes + else + chr.ligatures={ [plus]=becomes } + end end local p_charmetric=(( - P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature - )*semicolon )^1 + P("C")*number/setindex+P("WX")*number/setwidth+P("N")*fontdata*name/setname+P("B")*Ct((number)^4)/setboundingbox+P("L")*(name)^2/setligature + )*semicolon )^1 local p_charmetrics=P("StartCharMetrics")*number*(p_charmetric+(1-P("EndCharMetrics")))^0*P("EndCharMetrics") -local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" ) -local function set_1(data,key,a) data.metadata[lower(key)]=a end -local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end +local p_kernpairs=P("StartKernPairs")*number*(p_kernpair+(1-P("EndKernPairs" )))^0*P("EndKernPairs" ) +local function set_1(data,key,a) data.metadata[lower(key)]=a end +local function set_2(data,key,a,b) data.metadata[lower(key)]={ a,b } end local function set_3(data,key,a,b,c) data.metadata[lower(key)]={ a,b,c } end local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName"))/lower)*words/function(data,key,value) - data.metadata[key]=value - end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value) - data.metadata[key]=value - end+fontdata*P("IsFixedPitch")*name/function(data,pitch) - data.metadata.monospaced=toboolean(pitch,true) - end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox) - data.metadata.boundingbox=boundingbox - end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value) - data.metadata[key]=value - end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 + data.metadata[key]=value + end+fontdata*((P("Weight")+P("Version"))/lower)*name/function(data,key,value) + data.metadata[key]=value + end+fontdata*P("IsFixedPitch")*name/function(data,pitch) + data.metadata.monospaced=toboolean(pitch,true) + end+fontdata*P("FontBBox")*Ct(number^4)/function(data,boundingbox) + data.metadata.boundingbox=boundingbox + end+fontdata*((P("CharWidth")+P("CapHeight")+P("XHeight")+P("Descender")+P("Ascender")+P("ItalicAngle"))/lower)*number/function(data,key,value) + data.metadata[key]=value + end+P("Comment")*spacing*(P(false)+(fontdata*C("DESIGNSIZE")*number*rest)/set_1 +(fontdata*C("TFM designsize")*number*rest)/set_1+(fontdata*C("DesignSize")*number*rest)/set_1+(fontdata*C("CODINGSCHEME")*words*rest)/set_1 +(fontdata*C("CHECKSUM")*number*words*rest)/set_1 +(fontdata*C("SPACE")*number*plus*minus*rest)/set_3 @@ -31330,78 +32542,78 @@ local p_parameters=P(false)+fontdata*((P("FontName")+P("FullName")+P("FamilyName +(fontdata*C("SUBDROP")*number*rest)/set_1 +(fontdata*C("DELIM")*number*number*rest)/set_2 +(fontdata*C("AXISHEIGHT")*number*rest)/set_1 - ) + ) local fullparser=(P("StartFontMetrics")*fontdata*name/start )*(p_charmetrics+p_kernpairs+p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) local infoparser=(P("StartFontMetrics")*fontdata*name/start )*(p_parameters+(1-P("EndFontMetrics")) )^0*(P("EndFontMetrics")/stop ) local function read(filename,parser) - local afmblob=io.loaddata(filename) - if afmblob then - local data={ - resources={ - filename=resolvers.unresolve(filename), - version=afm.version, - creator="context mkiv", - }, - properties={ - hasitalics=false, - }, - goodies={}, - metadata={ - filename=file.removesuffix(file.basename(filename)) - }, - characters={ - }, - descriptions={ - }, - } - if trace_loading then - report_afm("parsing afm file %a",filename) - end - lpegmatch(parser,afmblob,1,data) - return data - else - if trace_loading then - report_afm("no valid afm file %a",filename) - end - return nil + local afmblob=io.loaddata(filename) + if afmblob then + local data={ + resources={ + filename=resolvers.unresolve(filename), + version=afm.version, + creator="context mkiv", + }, + properties={ + hasitalics=false, + }, + goodies={}, + metadata={ + filename=file.removesuffix(file.basename(filename)) + }, + characters={ + }, + descriptions={ + }, + } + if trace_loading then + report_afm("parsing afm file %a",filename) + end + lpegmatch(parser,afmblob,1,data) + return data + else + if trace_loading then + report_afm("no valid afm file %a",filename) end + return nil + end end function readers.loadfont(afmname,pfbname) - local data=read(resolvers.findfile(afmname),fullparser) - if data then - if not pfbname or pfbname=="" then - pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) - end - if pfbname and pfbname~="" then - data.resources.filename=resolvers.unresolve(pfbname) - get_indexes(data,pfbname) - return data - else - report_afm("no pfb file for %a",afmname) - end + local data=read(resolvers.findfile(afmname),fullparser) + if data then + if not pfbname or pfbname=="" then + pfbname=resolvers.findfile(file.replacesuffix(file.nameonly(afmname),"pfb")) + end + if pfbname and pfbname~="" then + data.resources.filename=resolvers.unresolve(pfbname) + get_indexes(data,pfbname) + return data + else + report_afm("no pfb file for %a",afmname) end + end end function readers.loadshapes(filename) - local fullname=resolvers.findfile(filename) or "" - if fullname=="" then - return { - filename="not found: "..filename, - glyphs={} - } - else - return { - filename=fullname, - format="opentype", - glyphs=get_shapes(fullname) or {}, - units=1000, - } - end + local fullname=resolvers.findfile(filename) or "" + if fullname=="" then + return { + filename="not found: "..filename, + glyphs={} + } + else + return { + filename=fullname, + format="opentype", + glyphs=get_shapes(fullname) or {}, + units=1000, + } + end end function readers.getinfo(filename) - local data=read(resolvers.findfile(filename),infoparser) - if data then - return data.metadata - end + local data=read(resolvers.findfile(filename),infoparser) + if data then + return data.metadata + end end end -- closure @@ -31409,11 +32621,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-one']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local fonts,logs,trackers,containers,resolvers=fonts,logs,trackers,containers,resolvers local next,type,tonumber,rawget=next,type,tonumber,rawget @@ -31422,10 +32634,10 @@ local abs=math.abs local P,S,R,Cmt,C,Ct,Cs,Carg=lpeg.P,lpeg.S,lpeg.R,lpeg.Cmt,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg local lpegmatch,patterns=lpeg.match,lpeg.patterns local sortedhash=table.sortedhash -local trace_features=false trackers.register("afm.features",function(v) trace_features=v end) -local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) -local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_features=false trackers.register("afm.features",function(v) trace_features=v end) +local trace_indexing=false trackers.register("afm.indexing",function(v) trace_indexing=v end) +local trace_loading=false trackers.register("afm.loading",function(v) trace_loading=v end) +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) local report_afm=logs.reporter("fonts","afm loading") local setmetatableindex=table.setmetatableindex local derivetable=table.derive @@ -31446,657 +32658,662 @@ local registerafmenhancer=afmenhancers.register afm.version=1.513 afm.cache=containers.define("fonts","one",afm.version,true) afm.autoprefixed=true -afm.helpdata={} +afm.helpdata={} afm.syncspace=true local overloads=fonts.mappings.overloads local applyruntimefixes=fonts.treatments and fonts.treatments.applyfixes function afm.load(filename) - filename=resolvers.findfile(filename,'afm') or "" - if filename~="" and not fonts.names.ignoredfile(filename) then - local name=file.removesuffix(file.basename(filename)) - local data=containers.read(afm.cache,name) - local attr=lfs.attributes(filename) - local size,time=attr.size or 0,attr.modification or 0 - local pfbfile=file.replacesuffix(name,"pfb") - local pfbname=resolvers.findfile(pfbfile,"pfb") or "" - if pfbname=="" then - pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or "" - end - local pfbsize,pfbtime=0,0 - if pfbname~="" then - local attr=lfs.attributes(pfbname) - pfbsize=attr.size or 0 - pfbtime=attr.modification or 0 - end - if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then - report_afm("reading %a",filename) - data=afm.readers.loadfont(filename,pfbname) - if data then - afmenhancers.apply(data,filename) - fonts.mappings.addtounicode(data,filename) - otfreaders.pack(data) - data.size=size - data.time=time - data.pfbsize=pfbsize - data.pfbtime=pfbtime - report_afm("saving %a in cache",name) - data=containers.write(afm.cache,name,data) - data=containers.read(afm.cache,name) - end - end - if data then - otfreaders.unpack(data) - otfreaders.expand(data) - otfreaders.addunicodetable(data) - otfenhancers.apply(data,filename,data) - if applyruntimefixes then - applyruntimefixes(filename,data) - end - end - return data + filename=resolvers.findfile(filename,'afm') or "" + if filename~="" and not fonts.names.ignoredfile(filename) then + local name=file.removesuffix(file.basename(filename)) + local data=containers.read(afm.cache,name) + local attr=lfs.attributes(filename) + local size=attr and attr.size or 0 + local time=attr and attr.modification or 0 + local pfbfile=file.replacesuffix(name,"pfb") + local pfbname=resolvers.findfile(pfbfile,"pfb") or "" + if pfbname=="" then + pfbname=resolvers.findfile(file.basename(pfbfile),"pfb") or "" + end + local pfbsize=0 + local pfbtime=0 + if pfbname~="" then + local attr=lfs.attributes(pfbname) + pfbsize=attr.size or 0 + pfbtime=attr.modification or 0 + end + if not data or data.size~=size or data.time~=time or data.pfbsize~=pfbsize or data.pfbtime~=pfbtime then + report_afm("reading %a",filename) + data=afm.readers.loadfont(filename,pfbname) + if data then + afmenhancers.apply(data,filename) + fonts.mappings.addtounicode(data,filename) + otfreaders.stripredundant(data) + otfreaders.pack(data) + data.size=size + data.time=time + data.pfbsize=pfbsize + data.pfbtime=pfbtime + report_afm("saving %a in cache",name) + data=containers.write(afm.cache,name,data) + data=containers.read(afm.cache,name) + end + end + if data then + otfreaders.unpack(data) + otfreaders.expand(data) + otfreaders.addunicodetable(data) + otfenhancers.apply(data,filename,data) + if applyruntimefixes then + applyruntimefixes(filename,data) + end end + return data + end end local uparser=fonts.mappings.makenameparser() local function enhance_unify_names(data,filename) - local unicodevector=fonts.encodings.agl.unicodes - local unicodes={} - local names={} - local private=data.private or privateoffset - local descriptions=data.descriptions - for name,blob in sortedhash(data.characters) do - local code=unicodevector[name] - if not code then - code=lpegmatch(uparser,name) - if type(code)~="number" then - code=private - private=private+1 - report_afm("assigning private slot %U for unknown glyph name %a",code,name) - end - end - local index=blob.index - unicodes[name]=code - names[name]=index - blob.name=name - descriptions[code]={ - boundingbox=blob.boundingbox, - width=blob.width, - kerns=blob.kerns, - index=index, - name=name, - } - end - for unicode,description in next,descriptions do - local kerns=description.kerns - if kerns then - local krn={} - for name,kern in next,kerns do - local unicode=unicodes[name] - if unicode then - krn[unicode]=kern - else - end - end - description.kerns=krn + local unicodevector=fonts.encodings.agl.unicodes + local unicodes={} + local names={} + local private=data.private or privateoffset + local descriptions=data.descriptions + for name,blob in sortedhash(data.characters) do + local code=unicodevector[name] + if not code then + code=lpegmatch(uparser,name) + if type(code)~="number" then + code=private + private=private+1 + report_afm("assigning private slot %U for unknown glyph name %a",code,name) + end + end + local index=blob.index + unicodes[name]=code + names[name]=index + blob.name=name + descriptions[code]={ + boundingbox=blob.boundingbox, + width=blob.width, + kerns=blob.kerns, + index=index, + name=name, + } + end + for unicode,description in next,descriptions do + local kerns=description.kerns + if kerns then + local krn={} + for name,kern in next,kerns do + local unicode=unicodes[name] + if unicode then + krn[unicode]=kern + else end + end + description.kerns=krn end - data.characters=nil - data.private=private - local resources=data.resources - local filename=resources.filename or file.removesuffix(file.basename(filename)) - resources.filename=resolvers.unresolve(filename) - resources.unicodes=unicodes - resources.marks={} + end + data.characters=nil + data.private=private + local resources=data.resources + local filename=resources.filename or file.removesuffix(file.basename(filename)) + resources.filename=resolvers.unresolve(filename) + resources.unicodes=unicodes + resources.marks={} end local everywhere={ ["*"]={ ["*"]=true } } local noflags={ false,false,false,false } local function enhance_normalize_features(data) - local ligatures=setmetatableindex("table") - local kerns=setmetatableindex("table") - local extrakerns=setmetatableindex("table") - for u,c in next,data.descriptions do - local l=c.ligatures - local k=c.kerns - local e=c.extrakerns - if l then - ligatures[u]=l - for u,v in next,l do - l[u]={ ligature=v } - end - c.ligatures=nil - end - if k then - kerns[u]=k - for u,v in next,k do - k[u]=v - end - c.kerns=nil - end - if e then - extrakerns[u]=e - for u,v in next,e do - e[u]=v - end - c.extrakerns=nil - end + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local extrakerns=setmetatableindex("table") + for u,c in next,data.descriptions do + local l=c.ligatures + local k=c.kerns + local e=c.extrakerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil end - local features={ - gpos={}, - gsub={}, + if e then + extrakerns[u]=e + for u,v in next,e do + e[u]=v + end + c.extrakerns=nil + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, } - local sequences={ + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, } - if next(ligatures) then - features.gsub.liga=everywhere - data.properties.hasligatures=true - sequences[#sequences+1]={ - features={ - liga=everywhere, - }, - flags=noflags, - name="s_s_0", - nofsteps=1, - order={ "liga" }, - type="gsub_ligature", - steps={ - { - coverage=ligatures, - }, - }, - } - end - if next(kerns) then - features.gpos.kern=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - kern=everywhere, - }, - flags=noflags, - name="p_s_0", - nofsteps=1, - order={ "kern" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=kerns, - }, - }, - } - end - if next(extrakerns) then - features.gpos.extrakerns=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - extrakerns=everywhere, - }, - flags=noflags, - name="p_s_1", - nofsteps=1, - order={ "extrakerns" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=extrakerns, - }, - }, - } - end - data.resources.features=features - data.resources.sequences=sequences + end + if next(extrakerns) then + features.gpos.extrakerns=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + extrakerns=everywhere, + }, + flags=noflags, + name="p_s_1", + nofsteps=1, + order={ "extrakerns" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=extrakerns, + }, + }, + } + end + data.resources.features=features + data.resources.sequences=sequences end local function enhance_fix_names(data) - for k,v in next,data.descriptions do - local n=v.name - local r=overloads[n] - if r then - local name=r.name - if trace_indexing then - report_afm("renaming characters %a to %a",n,name) - end - v.name=name - v.unicode=r.unicode - end - end + for k,v in next,data.descriptions do + local n=v.name + local r=overloads[n] + if r then + local name=r.name + if trace_indexing then + report_afm("renaming characters %a to %a",n,name) + end + v.name=name + v.unicode=r.unicode + end + end end local addthem=function(rawdata,ligatures) - if ligatures then - local descriptions=rawdata.descriptions - local resources=rawdata.resources - local unicodes=resources.unicodes - for ligname,ligdata in next,ligatures do - local one=descriptions[unicodes[ligname]] - if one then - for _,pair in next,ligdata do - local two,three=unicodes[pair[1]],unicodes[pair[2]] - if two and three then - local ol=one.ligatures - if ol then - if not ol[two] then - ol[two]=three - end - else - one.ligatures={ [two]=three } - end - end - end + if ligatures then + local descriptions=rawdata.descriptions + local resources=rawdata.resources + local unicodes=resources.unicodes + for ligname,ligdata in next,ligatures do + local one=descriptions[unicodes[ligname]] + if one then + for _,pair in next,ligdata do + local two=unicodes[pair[1]] + local three=unicodes[pair[2]] + if two and three then + local ol=one.ligatures + if ol then + if not ol[two] then + ol[two]=three + end + else + one.ligatures={ [two]=three } end + end end + end end + end end local function enhance_add_ligatures(rawdata) - addthem(rawdata,afm.helpdata.ligatures) + addthem(rawdata,afm.helpdata.ligatures) end local function enhance_add_extra_kerns(rawdata) - local descriptions=rawdata.descriptions - local resources=rawdata.resources - local unicodes=resources.unicodes - local function do_it_left(what) - if what then - for unicode,description in next,descriptions do - local kerns=description.kerns - if kerns then - local extrakerns - for complex,simple in next,what do - complex=unicodes[complex] - simple=unicodes[simple] - if complex and simple then - local ks=kerns[simple] - if ks and not kerns[complex] then - if extrakerns then - extrakerns[complex]=ks - else - extrakerns={ [complex]=ks } - end - end - end - end - if extrakerns then - description.extrakerns=extrakerns - end - end - end - end - end - local function do_it_copy(what) - if what then - for complex,simple in next,what do - complex=unicodes[complex] - simple=unicodes[simple] - if complex and simple then - local complexdescription=descriptions[complex] - if complexdescription then - local simpledescription=descriptions[complex] - if simpledescription then - local extrakerns - local kerns=simpledescription.kerns - if kerns then - for unicode,kern in next,kerns do - if extrakerns then - extrakerns[unicode]=kern - else - extrakerns={ [unicode]=kern } - end - end - end - local extrakerns=simpledescription.extrakerns - if extrakerns then - for unicode,kern in next,extrakerns do - if extrakerns then - extrakerns[unicode]=kern - else - extrakerns={ [unicode]=kern } - end - end - end - if extrakerns then - complexdescription.extrakerns=extrakerns - end - end - end + local descriptions=rawdata.descriptions + local resources=rawdata.resources + local unicodes=resources.unicodes + local function do_it_left(what) + if what then + for unicode,description in next,descriptions do + local kerns=description.kerns + if kerns then + local extrakerns + for complex,simple in next,what do + complex=unicodes[complex] + simple=unicodes[simple] + if complex and simple then + local ks=kerns[simple] + if ks and not kerns[complex] then + if extrakerns then + extrakerns[complex]=ks + else + extrakerns={ [complex]=ks } end + end end + end + if extrakerns then + description.extrakerns=extrakerns + end end - end - do_it_left(afm.helpdata.leftkerned) - do_it_left(afm.helpdata.bothkerned) - do_it_copy(afm.helpdata.bothkerned) - do_it_copy(afm.helpdata.rightkerned) -end -local function adddimensions(data) - if data then - for unicode,description in next,data.descriptions do - local bb=description.boundingbox - if bb then - local ht,dp=bb[4],-bb[2] - if ht==0 or ht<0 then - else - description.height=ht + end + end + end + local function do_it_copy(what) + if what then + for complex,simple in next,what do + complex=unicodes[complex] + simple=unicodes[simple] + if complex and simple then + local complexdescription=descriptions[complex] + if complexdescription then + local simpledescription=descriptions[complex] + if simpledescription then + local extrakerns + local kerns=simpledescription.kerns + if kerns then + for unicode,kern in next,kerns do + if extrakerns then + extrakerns[unicode]=kern + else + extrakerns={ [unicode]=kern } + end end - if dp==0 or dp<0 then - else - description.depth=dp + end + local extrakerns=simpledescription.extrakerns + if extrakerns then + for unicode,kern in next,extrakerns do + if extrakerns then + extrakerns[unicode]=kern + else + extrakerns={ [unicode]=kern } + end end + end + if extrakerns then + complexdescription.extrakerns=extrakerns + end end + end end + end end + end + do_it_left(afm.helpdata.leftkerned) + do_it_left(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.bothkerned) + do_it_copy(afm.helpdata.rightkerned) end -local function copytotfm(data) - if data and data.descriptions then - local metadata=data.metadata - local resources=data.resources - local properties=derivetable(data.properties) - local descriptions=derivetable(data.descriptions) - local goodies=derivetable(data.goodies) - local characters={} - local parameters={} - local unicodes=resources.unicodes - for unicode,description in next,data.descriptions do - characters[unicode]={} - end - local filename=constructors.checkedfilename(resources) - local fontname=metadata.fontname or metadata.fullname - local fullname=metadata.fullname or metadata.fontname - local endash=0x0020 - local emdash=0x2014 - local spacer="space" - local spaceunits=500 - local monospaced=metadata.monospaced - local charwidth=metadata.charwidth - local italicangle=metadata.italicangle - local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight - properties.monospaced=monospaced - parameters.italicangle=italicangle - parameters.charwidth=charwidth - parameters.charxheight=charxheight - if properties.monospaced then - if descriptions[endash] then - spaceunits,spacer=descriptions[endash].width,"space" - end - if not spaceunits and descriptions[emdash] then - spaceunits,spacer=descriptions[emdash].width,"emdash" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - else - if descriptions[endash] then - spaceunits,spacer=descriptions[endash].width,"space" - end - if not spaceunits and charwidth then - spaceunits,spacer=charwidth,"charwidth" - end - end - spaceunits=tonumber(spaceunits) - if spaceunits<200 then - end - parameters.slant=0 - parameters.space=spaceunits - parameters.space_stretch=500 - parameters.space_shrink=333 - parameters.x_height=400 - parameters.quad=1000 - if italicangle and italicangle~=0 then - parameters.italicangle=italicangle - parameters.italicfactor=math.cos(math.rad(90+italicangle)) - parameters.slant=- math.tan(italicangle*math.pi/180) - end - if monospaced then - parameters.space_stretch=0 - parameters.space_shrink=0 - elseif afm.syncspace then - parameters.space_stretch=spaceunits/2 - parameters.space_shrink=spaceunits/3 - end - parameters.extra_space=parameters.space_shrink - if charxheight then - parameters.x_height=charxheight +local function adddimensions(data) + if data then + for unicode,description in next,data.descriptions do + local bb=description.boundingbox + if bb then + local ht=bb[4] + local dp=-bb[2] + if ht==0 or ht<0 then else - local x=0x0078 - if x then - local x=descriptions[x] - if x then - parameters.x_height=x.height - end - end + description.height=ht end - if metadata.sup then - local dummy={ 0,0,0 } - parameters[ 1]=metadata.designsize or 0 - parameters[ 2]=metadata.checksum or 0 - parameters[ 3], - parameters[ 4], - parameters[ 5]=unpack(metadata.space or dummy) - parameters[ 6]=metadata.quad or 0 - parameters[ 7]=metadata.extraspace or 0 - parameters[ 8], - parameters[ 9], - parameters[10]=unpack(metadata.num or dummy) - parameters[11], - parameters[12]=unpack(metadata.denom or dummy) - parameters[13], - parameters[14], - parameters[15]=unpack(metadata.sup or dummy) - parameters[16], - parameters[17]=unpack(metadata.sub or dummy) - parameters[18]=metadata.supdrop or 0 - parameters[19]=metadata.subdrop or 0 - parameters[20], - parameters[21]=unpack(metadata.delim or dummy) - parameters[22]=metadata.axisheight or 0 - end - parameters.designsize=(metadata.designsize or 10)*65536 - parameters.ascender=abs(metadata.ascender or 0) - parameters.descender=abs(metadata.descender or 0) - parameters.units=1000 - properties.spacer=spacer - properties.encodingbytes=2 - properties.format=fonts.formats[filename] or "type1" - properties.filename=filename - properties.fontname=fontname - properties.fullname=fullname - properties.psname=fullname - properties.name=filename or fullname or fontname - properties.private=properties.private or data.private or privateoffset - if next(characters) then - return { - characters=characters, - descriptions=descriptions, - parameters=parameters, - resources=resources, - properties=properties, - goodies=goodies, - } + if dp==0 or dp<0 then + else + description.depth=dp end + end end - return nil + end end -function afm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) - if okay then - return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) +local function copytotfm(data) + if data and data.descriptions then + local metadata=data.metadata + local resources=data.resources + local properties=derivetable(data.properties) + local descriptions=derivetable(data.descriptions) + local goodies=derivetable(data.goodies) + local characters={} + local parameters={} + local unicodes=resources.unicodes + for unicode,description in next,data.descriptions do + characters[unicode]={} + end + local filename=constructors.checkedfilename(resources) + local fontname=metadata.fontname or metadata.fullname + local fullname=metadata.fullname or metadata.fontname + local endash=0x0020 + local emdash=0x2014 + local spacer="space" + local spaceunits=500 + local monospaced=metadata.monospaced + local charwidth=metadata.charwidth + local italicangle=metadata.italicangle + local charxheight=metadata.xheight and metadata.xheight>0 and metadata.xheight + properties.monospaced=monospaced + parameters.italicangle=italicangle + parameters.charwidth=charwidth + parameters.charxheight=charxheight + if properties.monospaced then + if descriptions[endash] then + spaceunits,spacer=descriptions[endash].width,"space" + end + if not spaceunits and descriptions[emdash] then + spaceunits,spacer=descriptions[emdash].width,"emdash" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end else - return {} - end + if descriptions[endash] then + spaceunits,spacer=descriptions[endash].width,"space" + end + if not spaceunits and charwidth then + spaceunits,spacer=charwidth,"charwidth" + end + end + spaceunits=tonumber(spaceunits) + if spaceunits<200 then + end + parameters.slant=0 + parameters.space=spaceunits + parameters.space_stretch=500 + parameters.space_shrink=333 + parameters.x_height=400 + parameters.quad=1000 + if italicangle and italicangle~=0 then + parameters.italicangle=italicangle + parameters.italicfactor=math.cos(math.rad(90+italicangle)) + parameters.slant=- math.tan(italicangle*math.pi/180) + end + if monospaced then + parameters.space_stretch=0 + parameters.space_shrink=0 + elseif afm.syncspace then + parameters.space_stretch=spaceunits/2 + parameters.space_shrink=spaceunits/3 + end + parameters.extra_space=parameters.space_shrink + if charxheight then + parameters.x_height=charxheight + else + local x=0x0078 + if x then + local x=descriptions[x] + if x then + parameters.x_height=x.height + end + end + end + if metadata.sup then + local dummy={ 0,0,0 } + parameters[ 1]=metadata.designsize or 0 + parameters[ 2]=metadata.checksum or 0 + parameters[ 3], + parameters[ 4], + parameters[ 5]=unpack(metadata.space or dummy) + parameters[ 6]=metadata.quad or 0 + parameters[ 7]=metadata.extraspace or 0 + parameters[ 8], + parameters[ 9], + parameters[10]=unpack(metadata.num or dummy) + parameters[11], + parameters[12]=unpack(metadata.denom or dummy) + parameters[13], + parameters[14], + parameters[15]=unpack(metadata.sup or dummy) + parameters[16], + parameters[17]=unpack(metadata.sub or dummy) + parameters[18]=metadata.supdrop or 0 + parameters[19]=metadata.subdrop or 0 + parameters[20], + parameters[21]=unpack(metadata.delim or dummy) + parameters[22]=metadata.axisheight or 0 + end + parameters.designsize=(metadata.designsize or 10)*65536 + parameters.ascender=abs(metadata.ascender or 0) + parameters.descender=abs(metadata.descender or 0) + parameters.units=1000 + properties.spacer=spacer + properties.encodingbytes=2 + properties.format=fonts.formats[filename] or "type1" + properties.filename=filename + properties.fontname=fontname + properties.fullname=fullname + properties.psname=fullname + properties.name=filename or fullname or fontname + properties.private=properties.private or data.private or privateoffset + if next(characters) then + return { + characters=characters, + descriptions=descriptions, + parameters=parameters, + resources=resources, + properties=properties, + goodies=goodies, + } + end + end + return nil +end +function afm.setfeatures(tfmdata,features) + local okay=constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm) + if okay then + return constructors.collectprocessors("afm",tfmdata,features,trace_features,report_afm) + else + return {} + end end local function addtables(data) - local resources=data.resources - local lookuptags=resources.lookuptags - local unicodes=resources.unicodes - if not lookuptags then - lookuptags={} - resources.lookuptags=lookuptags - end - setmetatableindex(lookuptags,function(t,k) - local v=type(k)=="number" and ("lookup "..k) or k - t[k]=v - return v + local resources=data.resources + local lookuptags=resources.lookuptags + local unicodes=resources.unicodes + if not lookuptags then + lookuptags={} + resources.lookuptags=lookuptags + end + setmetatableindex(lookuptags,function(t,k) + local v=type(k)=="number" and ("lookup "..k) or k + t[k]=v + return v + end) + if not unicodes then + unicodes={} + resources.unicodes=unicodes + setmetatableindex(unicodes,function(t,k) + setmetatableindex(unicodes,nil) + for u,d in next,data.descriptions do + local n=d.name + if n then + t[n]=u + end + end + return rawget(t,k) end) - if not unicodes then - unicodes={} - resources.unicodes=unicodes - setmetatableindex(unicodes,function(t,k) - setmetatableindex(unicodes,nil) - for u,d in next,data.descriptions do - local n=d.name - if n then - t[n]=u - end - end - return rawget(t,k) - end) - end - constructors.addcoreunicodes(unicodes) + end + constructors.addcoreunicodes(unicodes) end local function afmtotfm(specification) - local afmname=specification.filename or specification.name - if specification.forced=="afm" or specification.format=="afm" then - if trace_loading then - report_afm("forcing afm format for %a",afmname) - end - else - local tfmname=findbinfile(afmname,"ofm") or "" - if tfmname~="" then - if trace_loading then - report_afm("fallback from afm to tfm for %a",afmname) - end - return - end - end - if afmname~="" then - local features=constructors.checkedfeatures("afm",specification.features.normal) - specification.features.normal=features - constructors.hashinstance(specification,true) - specification=definers.resolve(specification) - local cache_id=specification.hash - local tfmdata=containers.read(constructors.cache,cache_id) - if not tfmdata then - local rawdata=afm.load(afmname) - if rawdata and next(rawdata) then - addtables(rawdata) - adddimensions(rawdata) - tfmdata=copytotfm(rawdata) - if tfmdata and next(tfmdata) then - local shared=tfmdata.shared - if not shared then - shared={} - tfmdata.shared=shared - end - shared.rawdata=rawdata - shared.dynamics={} - tfmdata.changed={} - shared.features=features - shared.processes=afm.setfeatures(tfmdata,features) - end - elseif trace_loading then - report_afm("no (valid) afm file found with name %a",afmname) - end - tfmdata=containers.write(constructors.cache,cache_id,tfmdata) + local afmname=specification.filename or specification.name + if specification.forced=="afm" or specification.format=="afm" then + if trace_loading then + report_afm("forcing afm format for %a",afmname) + end + else + local tfmname=findbinfile(afmname,"ofm") or "" + if tfmname~="" then + if trace_loading then + report_afm("fallback from afm to tfm for %a",afmname) + end + return + end + end + if afmname~="" then + local features=constructors.checkedfeatures("afm",specification.features.normal) + specification.features.normal=features + constructors.hashinstance(specification,true) + specification=definers.resolve(specification) + local cache_id=specification.hash + local tfmdata=containers.read(constructors.cache,cache_id) + if not tfmdata then + local rawdata=afm.load(afmname) + if rawdata and next(rawdata) then + addtables(rawdata) + adddimensions(rawdata) + tfmdata=copytotfm(rawdata) + if tfmdata and next(tfmdata) then + local shared=tfmdata.shared + if not shared then + shared={} + tfmdata.shared=shared + end + shared.rawdata=rawdata + shared.dynamics={} + tfmdata.changed={} + shared.features=features + shared.processes=afm.setfeatures(tfmdata,features) end - return tfmdata + elseif trace_loading then + report_afm("no (valid) afm file found with name %a",afmname) + end + tfmdata=containers.write(constructors.cache,cache_id,tfmdata) end + return tfmdata + end end local function read_from_afm(specification) - local tfmdata=afmtotfm(specification) - if tfmdata then - tfmdata.properties.name=specification.name - tfmdata=constructors.scale(tfmdata,specification) - local allfeatures=tfmdata.shared.features or specification.features.normal - constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) - fonts.loggers.register(tfmdata,'afm',specification) - end - return tfmdata + local tfmdata=afmtotfm(specification) + if tfmdata then + tfmdata.properties.name=specification.name + tfmdata=constructors.scale(tfmdata,specification) + local allfeatures=tfmdata.shared.features or specification.features.normal + constructors.applymanipulators("afm",tfmdata,allfeatures,trace_features,report_afm) + fonts.loggers.register(tfmdata,'afm',specification) + end + return tfmdata end registerafmfeature { - name="mode", - description="mode", - initializers={ - base=otf.modeinitializer, - node=otf.modeinitializer, - } + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } } registerafmfeature { - name="features", - description="features", - default=true, - initializers={ - node=otf.nodemodeinitializer, - base=otf.basemodeinitializer, - }, - processors={ - node=otf.featuresprocessor, - } + name="features", + description="features", + default=true, + initializers={ + node=otf.nodemodeinitializer, + base=otf.basemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } } fonts.formats.afm="type1" fonts.formats.pfb="type1" local function check_afm(specification,fullname) - local foundname=findbinfile(fullname,'afm') or "" - if foundname=="" then - foundname=fonts.names.getfilename(fullname,"afm") or "" - end - if foundname=="" and afm.autoprefixed then - local encoding,shortname=match(fullname,"^(.-)%-(.*)$") - if encoding and shortname and fonts.encodings.known[encoding] then - shortname=findbinfile(shortname,'afm') or "" - if shortname~="" then - foundname=shortname - if trace_defining then - report_afm("stripping encoding prefix from filename %a",afmname) - end - end + local foundname=findbinfile(fullname,'afm') or "" + if foundname=="" then + foundname=fonts.names.getfilename(fullname,"afm") or "" + end + if foundname=="" and afm.autoprefixed then + local encoding,shortname=match(fullname,"^(.-)%-(.*)$") + if encoding and shortname and fonts.encodings.known[encoding] then + shortname=findbinfile(shortname,'afm') or "" + if shortname~="" then + foundname=shortname + if trace_defining then + report_afm("stripping encoding prefix from filename %a",afmname) end + end end - if foundname~="" then - specification.filename=foundname - specification.format="afm" - return read_from_afm(specification) - end + end + if foundname~="" then + specification.filename=foundname + specification.format="afm" + return read_from_afm(specification) + end end function readers.afm(specification,method) - local fullname=specification.filename or "" - local tfmdata=nil - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - tfmdata=check_afm(specification,specification.name.."."..forced) - end - if not tfmdata then - local check_tfm=readers.check_tfm - method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" - if method=="tfm" then - tfmdata=check_tfm(specification,specification.name) - elseif method=="afm" then - tfmdata=check_afm(specification,specification.name) - elseif method=="tfm or afm" then - tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name) - else - tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name) - end - end - else - tfmdata=check_afm(specification,fullname) + local fullname=specification.filename or "" + local tfmdata=nil + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + tfmdata=check_afm(specification,specification.name.."."..forced) end - return tfmdata + if not tfmdata then + local check_tfm=readers.check_tfm + method=(check_tfm and (method or definers.method or "afm or tfm")) or "afm" + if method=="tfm" then + tfmdata=check_tfm(specification,specification.name) + elseif method=="afm" then + tfmdata=check_afm(specification,specification.name) + elseif method=="tfm or afm" then + tfmdata=check_tfm(specification,specification.name) or check_afm(specification,specification.name) + else + tfmdata=check_afm(specification,specification.name) or check_tfm(specification,specification.name) + end + end + else + tfmdata=check_afm(specification,fullname) + end + return tfmdata end function readers.pfb(specification,method) - local original=specification.specification - if trace_defining then - report_afm("using afm reader for %a",original) - end - specification.forced="afm" - local function swap(name) - local value=specification[swap] - if value then - specification[swap]=gsub("%.pfb",".afm",1) - end + local original=specification.specification + if trace_defining then + report_afm("using afm reader for %a",original) + end + specification.forced="afm" + local function swap(name) + local value=specification[swap] + if value then + specification[swap]=gsub("%.pfb",".afm",1) end - swap("filename") - swap("fullname") - swap("forcedname") - swap("specification") - return readers.afm(specification,method) + end + swap("filename") + swap("fullname") + swap("forcedname") + swap("specification") + return readers.afm(specification,method) end registerafmenhancer("unify names",enhance_unify_names) registerafmenhancer("add ligatures",enhance_add_ligatures) @@ -32110,168 +33327,168 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-afk']={ - version=1.001, - comment="companion to font-lib.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files", - dataonly=true, + version=1.001, + comment="companion to font-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files", + dataonly=true, } local allocate=utilities.storage.allocate fonts.handlers.afm.helpdata={ - ligatures=allocate { - ['f']={ - { 'f','ff' }, - { 'i','fi' }, - { 'l','fl' }, - }, - ['ff']={ - { 'i','ffi' } - }, - ['fi']={ - { 'i','fii' } - }, - ['fl']={ - { 'i','fli' } - }, - ['s']={ - { 't','st' } - }, - ['i']={ - { 'j','ij' } - }, + ligatures=allocate { + ['f']={ + { 'f','ff' }, + { 'i','fi' }, + { 'l','fl' }, }, - texligatures=allocate { - ['quoteleft']={ - { 'quoteleft','quotedblleft' } - }, - ['quoteright']={ - { 'quoteright','quotedblright' } - }, - ['hyphen']={ - { 'hyphen','endash' } - }, - ['endash']={ - { 'hyphen','emdash' } - } + ['ff']={ + { 'i','ffi' } }, - leftkerned=allocate { - AEligature="A",aeligature="a", - OEligature="O",oeligature="o", - IJligature="I",ijligature="i", - AE="A",ae="a", - OE="O",oe="o", - IJ="I",ij="i", - Ssharp="S",ssharp="s", + ['fi']={ + { 'i','fii' } }, - rightkerned=allocate { - AEligature="E",aeligature="e", - OEligature="E",oeligature="e", - IJligature="J",ijligature="j", - AE="E",ae="e", - OE="E",oe="e", - IJ="J",ij="j", - Ssharp="S",ssharp="s", + ['fl']={ + { 'i','fli' } }, - bothkerned=allocate { - Acircumflex="A",acircumflex="a", - Ccircumflex="C",ccircumflex="c", - Ecircumflex="E",ecircumflex="e", - Gcircumflex="G",gcircumflex="g", - Hcircumflex="H",hcircumflex="h", - Icircumflex="I",icircumflex="i", - Jcircumflex="J",jcircumflex="j", - Ocircumflex="O",ocircumflex="o", - Scircumflex="S",scircumflex="s", - Ucircumflex="U",ucircumflex="u", - Wcircumflex="W",wcircumflex="w", - Ycircumflex="Y",ycircumflex="y", - Agrave="A",agrave="a", - Egrave="E",egrave="e", - Igrave="I",igrave="i", - Ograve="O",ograve="o", - Ugrave="U",ugrave="u", - Ygrave="Y",ygrave="y", - Atilde="A",atilde="a", - Itilde="I",itilde="i", - Otilde="O",otilde="o", - Utilde="U",utilde="u", - Ntilde="N",ntilde="n", - Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a", - Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e", - Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i", - Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o", - Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u", - Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y", - Aacute="A",aacute="a", - Cacute="C",cacute="c", - Eacute="E",eacute="e", - Iacute="I",iacute="i", - Lacute="L",lacute="l", - Nacute="N",nacute="n", - Oacute="O",oacute="o", - Racute="R",racute="r", - Sacute="S",sacute="s", - Uacute="U",uacute="u", - Yacute="Y",yacute="y", - Zacute="Z",zacute="z", - Dstroke="D",dstroke="d", - Hstroke="H",hstroke="h", - Tstroke="T",tstroke="t", - Cdotaccent="C",cdotaccent="c", - Edotaccent="E",edotaccent="e", - Gdotaccent="G",gdotaccent="g", - Idotaccent="I",idotaccent="i", - Zdotaccent="Z",zdotaccent="z", - Amacron="A",amacron="a", - Emacron="E",emacron="e", - Imacron="I",imacron="i", - Omacron="O",omacron="o", - Umacron="U",umacron="u", - Ccedilla="C",ccedilla="c", - Kcedilla="K",kcedilla="k", - Lcedilla="L",lcedilla="l", - Ncedilla="N",ncedilla="n", - Rcedilla="R",rcedilla="r", - Scedilla="S",scedilla="s", - Tcedilla="T",tcedilla="t", - Ohungarumlaut="O",ohungarumlaut="o", - Uhungarumlaut="U",uhungarumlaut="u", - Aogonek="A",aogonek="a", - Eogonek="E",eogonek="e", - Iogonek="I",iogonek="i", - Uogonek="U",uogonek="u", - Aring="A",aring="a", - Uring="U",uring="u", - Abreve="A",abreve="a", - Ebreve="E",ebreve="e", - Gbreve="G",gbreve="g", - Ibreve="I",ibreve="i", - Obreve="O",obreve="o", - Ubreve="U",ubreve="u", - Ccaron="C",ccaron="c", - Dcaron="D",dcaron="d", - Ecaron="E",ecaron="e", - Lcaron="L",lcaron="l", - Ncaron="N",ncaron="n", - Rcaron="R",rcaron="r", - Scaron="S",scaron="s", - Tcaron="T",tcaron="t", - Zcaron="Z",zcaron="z", - dotlessI="I",dotlessi="i", - dotlessJ="J",dotlessj="j", - AEligature="AE",aeligature="ae",AE="AE",ae="ae", - OEligature="OE",oeligature="oe",OE="OE",oe="oe", - IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij", - Lstroke="L",lstroke="l",Lslash="L",lslash="l", - Ostroke="O",ostroke="o",Oslash="O",oslash="o", - Ssharp="SS",ssharp="ss", - Aumlaut="A",aumlaut="a", - Eumlaut="E",eumlaut="e", - Iumlaut="I",iumlaut="i", - Oumlaut="O",oumlaut="o", - Uumlaut="U",uumlaut="u", + ['s']={ + { 't','st' } + }, + ['i']={ + { 'j','ij' } + }, + }, + texligatures=allocate { + ['quoteleft']={ + { 'quoteleft','quotedblleft' } + }, + ['quoteright']={ + { 'quoteright','quotedblright' } + }, + ['hyphen']={ + { 'hyphen','endash' } + }, + ['endash']={ + { 'hyphen','emdash' } } + }, + leftkerned=allocate { + AEligature="A",aeligature="a", + OEligature="O",oeligature="o", + IJligature="I",ijligature="i", + AE="A",ae="a", + OE="O",oe="o", + IJ="I",ij="i", + Ssharp="S",ssharp="s", + }, + rightkerned=allocate { + AEligature="E",aeligature="e", + OEligature="E",oeligature="e", + IJligature="J",ijligature="j", + AE="E",ae="e", + OE="E",oe="e", + IJ="J",ij="j", + Ssharp="S",ssharp="s", + }, + bothkerned=allocate { + Acircumflex="A",acircumflex="a", + Ccircumflex="C",ccircumflex="c", + Ecircumflex="E",ecircumflex="e", + Gcircumflex="G",gcircumflex="g", + Hcircumflex="H",hcircumflex="h", + Icircumflex="I",icircumflex="i", + Jcircumflex="J",jcircumflex="j", + Ocircumflex="O",ocircumflex="o", + Scircumflex="S",scircumflex="s", + Ucircumflex="U",ucircumflex="u", + Wcircumflex="W",wcircumflex="w", + Ycircumflex="Y",ycircumflex="y", + Agrave="A",agrave="a", + Egrave="E",egrave="e", + Igrave="I",igrave="i", + Ograve="O",ograve="o", + Ugrave="U",ugrave="u", + Ygrave="Y",ygrave="y", + Atilde="A",atilde="a", + Itilde="I",itilde="i", + Otilde="O",otilde="o", + Utilde="U",utilde="u", + Ntilde="N",ntilde="n", + Adiaeresis="A",adiaeresis="a",Adieresis="A",adieresis="a", + Ediaeresis="E",ediaeresis="e",Edieresis="E",edieresis="e", + Idiaeresis="I",idiaeresis="i",Idieresis="I",idieresis="i", + Odiaeresis="O",odiaeresis="o",Odieresis="O",odieresis="o", + Udiaeresis="U",udiaeresis="u",Udieresis="U",udieresis="u", + Ydiaeresis="Y",ydiaeresis="y",Ydieresis="Y",ydieresis="y", + Aacute="A",aacute="a", + Cacute="C",cacute="c", + Eacute="E",eacute="e", + Iacute="I",iacute="i", + Lacute="L",lacute="l", + Nacute="N",nacute="n", + Oacute="O",oacute="o", + Racute="R",racute="r", + Sacute="S",sacute="s", + Uacute="U",uacute="u", + Yacute="Y",yacute="y", + Zacute="Z",zacute="z", + Dstroke="D",dstroke="d", + Hstroke="H",hstroke="h", + Tstroke="T",tstroke="t", + Cdotaccent="C",cdotaccent="c", + Edotaccent="E",edotaccent="e", + Gdotaccent="G",gdotaccent="g", + Idotaccent="I",idotaccent="i", + Zdotaccent="Z",zdotaccent="z", + Amacron="A",amacron="a", + Emacron="E",emacron="e", + Imacron="I",imacron="i", + Omacron="O",omacron="o", + Umacron="U",umacron="u", + Ccedilla="C",ccedilla="c", + Kcedilla="K",kcedilla="k", + Lcedilla="L",lcedilla="l", + Ncedilla="N",ncedilla="n", + Rcedilla="R",rcedilla="r", + Scedilla="S",scedilla="s", + Tcedilla="T",tcedilla="t", + Ohungarumlaut="O",ohungarumlaut="o", + Uhungarumlaut="U",uhungarumlaut="u", + Aogonek="A",aogonek="a", + Eogonek="E",eogonek="e", + Iogonek="I",iogonek="i", + Uogonek="U",uogonek="u", + Aring="A",aring="a", + Uring="U",uring="u", + Abreve="A",abreve="a", + Ebreve="E",ebreve="e", + Gbreve="G",gbreve="g", + Ibreve="I",ibreve="i", + Obreve="O",obreve="o", + Ubreve="U",ubreve="u", + Ccaron="C",ccaron="c", + Dcaron="D",dcaron="d", + Ecaron="E",ecaron="e", + Lcaron="L",lcaron="l", + Ncaron="N",ncaron="n", + Rcaron="R",rcaron="r", + Scaron="S",scaron="s", + Tcaron="T",tcaron="t", + Zcaron="Z",zcaron="z", + dotlessI="I",dotlessi="i", + dotlessJ="J",dotlessj="j", + AEligature="AE",aeligature="ae",AE="AE",ae="ae", + OEligature="OE",oeligature="oe",OE="OE",oe="oe", + IJligature="IJ",ijligature="ij",IJ="IJ",ij="ij", + Lstroke="L",lstroke="l",Lslash="L",lslash="l", + Ostroke="O",ostroke="o",Oslash="O",oslash="o", + Ssharp="SS",ssharp="ss", + Aumlaut="A",aumlaut="a", + Eumlaut="E",eumlaut="e", + Iumlaut="I",iumlaut="i", + Oumlaut="O",oumlaut="o", + Uumlaut="U",uumlaut="u", + } } end -- closure @@ -32279,23 +33496,25 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-tfm']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local next,type=next,type local match,format=string.match,string.format local concat,sortedhash=table.concat,table.sortedhash -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) -local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) +local idiv=number.idiv +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_features=false trackers.register("tfm.features",function(v) trace_features=v end) local report_defining=logs.reporter("fonts","defining") local report_tfm=logs.reporter("fonts","tfm loading") local findbinfile=resolvers.findbinfile local setmetatableindex=table.setmetatableindex local fonts=fonts local handlers=fonts.handlers +local helpers=fonts.helpers local readers=fonts.readers local constructors=fonts.constructors local encodings=fonts.encodings @@ -32309,319 +33528,363 @@ local tfmfeatures=constructors.features.tfm local registertfmfeature=tfmfeatures.register local tfmenhancers=constructors.enhancers.tfm local registertfmenhancer=tfmenhancers.register +local charcommand=helpers.commands.char constructors.resolvevirtualtoo=false fonts.formats.tfm="type1" fonts.formats.ofm="type1" function tfm.setfeatures(tfmdata,features) - local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) - if okay then - return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) - else - return {} - end + local okay=constructors.initializefeatures("tfm",tfmdata,features,trace_features,report_tfm) + if okay then + return constructors.collectprocessors("tfm",tfmdata,features,trace_features,report_tfm) + else + return {} + end end local depth={} -local function read_from_tfm(specification) +local read_from_tfm,check_tfm do + local tfmreaders=context and tfm.readers + local loadtfmvf=tfmreaders and tfmreaders.loadtfmvf + local loadtfm=font.read_tfm + local loadvf=font.read_vf + directives.register("fonts.tfm.builtin",function(v) + loadtfmvf=tfmreaders and tfmreaders.loadtfmvf + if v and loadtfm then + loadtfmvf=false + end + end) + read_from_tfm=function(specification) local filename=specification.filename local size=specification.size depth[filename]=(depth[filename] or 0)+1 if trace_defining then - report_defining("loading tfm file %a at size %s",filename,size) + report_defining("loading tfm file %a at size %s",filename,size) + end + local tfmdata + if loadtfmvf then + tfmdata=loadtfmvf(filename,size) + else + tfmdata=loadtfm(filename,size) end - local tfmdata=font.read_tfm(filename,size) if tfmdata then - local features=specification.features and specification.features.normal or {} - local features=constructors.checkedfeatures("tfm",features) - specification.features.normal=features - local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) - if newtfmdata then - tfmdata=newtfmdata - end - local resources=tfmdata.resources or {} - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - local shared=tfmdata.shared or {} - shared.features=features - shared.resources=resources - properties.name=tfmdata.name - properties.fontname=tfmdata.fontname - properties.psname=tfmdata.psname - properties.fullname=tfmdata.fullname - properties.filename=specification.filename - properties.format=fonts.formats.tfm - tfmdata.properties=properties - tfmdata.resources=resources - tfmdata.parameters=parameters - tfmdata.shared=shared - shared.rawdata={ resources=resources } - shared.features=features - if newtfmdata then - if not resources.marks then - resources.marks={} - end - if not resources.sequences then - resources.sequences={} - end - if not resources.features then - resources.features={ - gsub={}, - gpos={}, - } - end - if not tfmdata.changed then - tfmdata.changed={} - end - if not tfmdata.descriptions then - tfmdata.descriptions=tfmdata.characters - end - otf.readers.addunicodetable(tfmdata) - tfmenhancers.apply(tfmdata,filename) - constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) - otf.readers.unifymissing(tfmdata) - fonts.mappings.addtounicode(tfmdata,filename) - tfmdata.tounicode=1 - local tounicode=fonts.mappings.tounicode - for unicode,v in next,tfmdata.characters do - local u=v.unicode - if u then - v.tounicode=tounicode(u) + local features=specification.features and specification.features.normal or {} + local features=constructors.checkedfeatures("tfm",features) + specification.features.normal=features + local newtfmdata=(depth[filename]==1) and tfm.reencode(tfmdata,specification) + if newtfmdata then + tfmdata=newtfmdata + end + local resources=tfmdata.resources or {} + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + local shared=tfmdata.shared or {} + shared.features=features + shared.resources=resources + properties.name=tfmdata.name + properties.fontname=tfmdata.fontname + properties.psname=tfmdata.psname + properties.fullname=tfmdata.fullname + properties.filename=specification.filename + properties.format=tfmdata.format or fonts.formats.tfm + properties.usedbitmap=tfmdata.usedbitmap + tfmdata.properties=properties + tfmdata.resources=resources + tfmdata.parameters=parameters + tfmdata.shared=shared + shared.rawdata={ resources=resources } + shared.features=features + if newtfmdata then + if not resources.marks then + resources.marks={} + end + if not resources.sequences then + resources.sequences={} + end + if not resources.features then + resources.features={ + gsub={}, + gpos={}, + } + end + if not tfmdata.changed then + tfmdata.changed={} + end + if not tfmdata.descriptions then + tfmdata.descriptions=tfmdata.characters + end + otf.readers.addunicodetable(tfmdata) + tfmenhancers.apply(tfmdata,filename) + constructors.applymanipulators("tfm",tfmdata,features,trace_features,report_tfm) + otf.readers.unifymissing(tfmdata) + fonts.mappings.addtounicode(tfmdata,filename) + tfmdata.tounicode=1 + local tounicode=fonts.mappings.tounicode + for unicode,v in next,tfmdata.characters do + local u=v.unicode + if u then + v.tounicode=tounicode(u) + end + end + if tfmdata.usedbitmap then + tfm.addtounicode(tfmdata) + end + end + shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil + if size<0 then + size=idiv(65536*-size,100) + end + parameters.factor=1 + parameters.units=1000 + parameters.size=size + parameters.slant=parameters.slant or parameters[1] or 0 + parameters.space=parameters.space or parameters[2] or 0 + parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 + parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 + parameters.x_height=parameters.x_height or parameters[5] or 0 + parameters.quad=parameters.quad or parameters[6] or 0 + parameters.extra_space=parameters.extra_space or parameters[7] or 0 + constructors.enhanceparameters(parameters) + properties.private=properties.private or tfmdata.private or privateoffset + if newtfmdata then + elseif loadtfmvf then + local fonts=tfmdata.fonts + if fonts then + for i=1,#fonts do + local font=fonts[i] + local id=font.id + if not id then + local name=font.name + local size=font.size + if name and size then + local data,id=constructors.readanddefine(name,size) + if id then + font.id=id + font.name=nil + font.size=nil end + end end - if tfmdata.usedbitmap then - tfm.addtounicode(tfmdata) - end - end - shared.processes=next(features) and tfm.setfeatures(tfmdata,features) or nil - parameters.factor=1 - parameters.size=size - parameters.slant=parameters.slant or parameters[1] or 0 - parameters.space=parameters.space or parameters[2] or 0 - parameters.space_stretch=parameters.space_stretch or parameters[3] or 0 - parameters.space_shrink=parameters.space_shrink or parameters[4] or 0 - parameters.x_height=parameters.x_height or parameters[5] or 0 - parameters.quad=parameters.quad or parameters[6] or 0 - parameters.extra_space=parameters.extra_space or parameters[7] or 0 - constructors.enhanceparameters(parameters) - properties.private=properties.private or tfmdata.private or privateoffset - if newtfmdata then - elseif constructors.resolvevirtualtoo then - fonts.loggers.register(tfmdata,file.suffix(filename),specification) - local vfname=findbinfile(specification.name,'ovf') - if vfname and vfname~="" then - local vfdata=font.read_vf(vfname,size) - if vfdata then - local chars=tfmdata.characters - for k,v in next,vfdata.characters do - chars[k].commands=v.commands - end - properties.virtualized=true - tfmdata.fonts=vfdata.fonts - tfmdata.type="virtual" - local fontlist=vfdata.fonts - local name=file.nameonly(filename) - for i=1,#fontlist do - local n=fontlist[i].name - local s=fontlist[i].size - local d=depth[filename] - s=constructors.scaled(s,vfdata.designsize) - if d>tfm.maxnestingdepth then - report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) - fontlist[i]={ id=0 } - elseif (d>1) and (s>tfm.maxnestingsize) then - report_defining("virtual font %a exceeds size %s",n,s) - fontlist[i]={ id=0 } - else - local t,id=fonts.constructors.readanddefine(n,s) - fontlist[i]={ id=id } - end - end - end + end + end + elseif constructors.resolvevirtualtoo then + fonts.loggers.register(tfmdata,file.suffix(filename),specification) + local vfname=findbinfile(specification.name,'ovf') + if vfname and vfname~="" then + local vfdata=loadvf(vfname,size) + if vfdata then + local chars=tfmdata.characters + for k,v in next,vfdata.characters do + chars[k].commands=v.commands + end + properties.virtualized=true + tfmdata.fonts=vfdata.fonts + tfmdata.type="virtual" + local fontlist=vfdata.fonts + local name=file.nameonly(filename) + for i=1,#fontlist do + local n=fontlist[i].name + local s=fontlist[i].size + local d=depth[filename] + s=constructors.scaled(s,vfdata.designsize) + if d>tfm.maxnestingdepth then + report_defining("too deeply nested virtual font %a with size %a, max nesting depth %s",n,s,tfm.maxnestingdepth) + fontlist[i]={ id=0 } + elseif (d>1) and (s>tfm.maxnestingsize) then + report_defining("virtual font %a exceeds size %s",n,s) + fontlist[i]={ id=0 } + else + local t,id=constructors.readanddefine(n,s) + fontlist[i]={ id=id } + end end + end end - properties.haskerns=true - properties.hasligatures=true - resources.unicodes={} - resources.lookuptags={} - depth[filename]=depth[filename]-1 - return tfmdata + end + properties.haskerns=true + properties.hasligatures=true + properties.hasitalics=true + resources.unicodes={} + resources.lookuptags={} + depth[filename]=depth[filename]-1 + return tfmdata else - depth[filename]=depth[filename]-1 + depth[filename]=depth[filename]-1 end -end -local function check_tfm(specification,fullname) + end + check_tfm=function(specification,fullname) local foundname=findbinfile(fullname,'tfm') or "" if foundname=="" then - foundname=findbinfile(fullname,'ofm') or "" + foundname=findbinfile(fullname,'ofm') or "" end if foundname=="" then - foundname=fonts.names.getfilename(fullname,"tfm") or "" + foundname=fonts.names.getfilename(fullname,"tfm") or "" end if foundname~="" then - specification.filename=foundname - specification.format="ofm" - return read_from_tfm(specification) + specification.filename=foundname + specification.format="ofm" + return read_from_tfm(specification) elseif trace_defining then - report_defining("loading tfm with name %a fails",specification.name) + report_defining("loading tfm with name %a fails",specification.name) end + end end readers.check_tfm=check_tfm function readers.tfm(specification) - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name end - return check_tfm(specification,fullname) + end + return check_tfm(specification,fullname) end readers.ofm=readers.tfm do - local outfiles={} - local tfmcache=table.setmetatableindex(function(t,tfmdata) - local id=font.define(tfmdata) - t[tfmdata]=id - return id - end) - local encdone=table.setmetatableindex("table") - function tfm.reencode(tfmdata,specification) - local features=specification.features - if not features then - return + local outfiles={} + local tfmcache=table.setmetatableindex(function(t,tfmdata) + local id=font.define(tfmdata) + t[tfmdata]=id + return id + end) + local encdone=table.setmetatableindex("table") + function tfm.reencode(tfmdata,specification) + local features=specification.features + if not features then + return + end + local features=features.normal + if not features then + return + end + local tfmfile=file.basename(tfmdata.name) + local encfile=features.reencode + local pfbfile=features.pfbfile + local bitmap=features.bitmap + if not encfile then + return + end + local pfbfile=outfiles[tfmfile] + if pfbfile==nil then + if bitmap then + pfbfile=false + elseif type(pfbfile)~="string" then + pfbfile=tfmfile + end + if type(pfbfile)=="string" then + pfbfile=file.addsuffix(pfbfile,"pfb") + report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) + else + report_tfm("using bitmap shapes for %a",tfmfile) + pfbfile=false + end + outfiles[tfmfile]=pfbfile + end + local encoding=false + local vector=false + if type(pfbfile)=="string" then + local pfb=constructors.handlers.pfb + if pfb and pfb.loadvector then + local v,e=pfb.loadvector(pfbfile) + if v then + vector=v end - local features=features.normal - if not features then - return - end - local tfmfile=file.basename(tfmdata.name) - local encfile=features.reencode - local pfbfile=features.pfbfile - local bitmap=features.bitmap - if not encfile then - return - end - local pfbfile=outfiles[tfmfile] - if pfbfile==nil then - if bitmap then - pfbfile=false - elseif type(pfbfile)~="string" then - pfbfile=tfmfile - end - if type(pfbfile)=="string" then - pfbfile=file.addsuffix(pfbfile,"pfb") - report_tfm("using type1 shapes from %a for %a",pfbfile,tfmfile) - else - report_tfm("using bitmap shapes for %a",tfmfile) - pfbfile=false - end - outfiles[tfmfile]=pfbfile - end - local encoding=false - local vector=false - if type(pfbfile)=="string" then - local pfb=fonts.constructors.handlers.pfb - if pfb and pfb.loadvector then - local v,e=pfb.loadvector(pfbfile) - if v then - vector=v - end - if e then - encoding=e - end - end + if e then + encoding=e end - if type(encfile)=="string" and encfile~="auto" then - encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) - if encoding then - encoding=encoding.vector - end - end - if not encoding then - report_tfm("bad encoding for %a, quitting",tfmfile) - return - end - local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes - local virtualid=tfmcache[tfmdata] - local tfmdata=table.copy(tfmdata) - local characters={} - local originals=tfmdata.characters - local indices={} - local parentfont={ "font",1 } - local private=tfmdata or fonts.constructors.privateoffset - local reported=encdone[tfmfile][encfile] - local backmap=vector and table.swapped(vector) - local done={} - for index,name in sortedhash(encoding) do - local unicode=unicoding[name] - local original=originals[index] - if original then - if unicode then - original.unicode=unicode - else - unicode=private - private=private+1 - if not reported then - report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) - end - end - characters[unicode]=original - indices[index]=unicode - original.name=name - if backmap then - original.index=backmap[name] - else - original.commands={ parentfont,{ "char",index } } - original.oindex=index - end - done[name]=true - elseif not done[name] then - report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) - end + end + end + if type(encfile)=="string" and encfile~="auto" then + encoding=fonts.encodings.load(file.addsuffix(encfile,"enc")) + if encoding then + encoding=encoding.vector + end + end + if not encoding then + report_tfm("bad encoding for %a, quitting",tfmfile) + return + end + local unicoding=fonts.encodings.agl and fonts.encodings.agl.unicodes + local virtualid=tfmcache[tfmdata] + local tfmdata=table.copy(tfmdata) + local characters={} + local originals=tfmdata.characters + local indices={} + local parentfont={ "font",1 } + local private=tfmdata.privateoffset or constructors.privateoffset + local reported=encdone[tfmfile][encfile] + local backmap=vector and table.swapped(vector) + local done={} + for index,name in sortedhash(encoding) do + local unicode=unicoding[name] + local original=originals[index] + if original then + if unicode then + original.unicode=unicode + else + unicode=private + private=private+1 + if not reported then + report_tfm("glyph %a in font %a with encoding %a gets unicode %U",name,tfmfile,encfile,unicode) + end end - encdone[tfmfile][encfile]=true - for k,v in next,characters do - local kerns=v.kerns - if kerns then - local t={} - for k,v in next,kerns do - local i=indices[k] - if i then - t[i]=v - end - end - v.kerns=next(t) and t or nil - end - local ligatures=v.ligatures - if ligatures then - local t={} - for k,v in next,ligatures do - local i=indices[k] - if i then - t[i]=v - v.char=indices[v.char] - end - end - v.ligatures=next(t) and t or nil - end + characters[unicode]=original + indices[index]=unicode + original.name=name + if backmap then + original.index=backmap[name] + else + original.commands={ parentfont,charcommand[index] } + original.oindex=index + end + done[name]=true + elseif not done[name] then + report_tfm("bad index %a in font %a with name %a",index,tfmfile,name) + end + end + encdone[tfmfile][encfile]=true + for k,v in next,characters do + local kerns=v.kerns + if kerns then + local t={} + for k,v in next,kerns do + local i=indices[k] + if i then + t[i]=v + end end - tfmdata.fonts={ { id=virtualid } } - tfmdata.characters=characters - tfmdata.fullname=tfmdata.fullname or tfmdata.name - tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) - tfmdata.filename=pfbfile - tfmdata.encodingbytes=2 - tfmdata.format="type1" - tfmdata.tounicode=1 - tfmdata.embedding="subset" - tfmdata.usedbitmap=bitmap and virtualid - tfmdata.private=private - return tfmdata - end + v.kerns=next(t) and t or nil + end + local ligatures=v.ligatures + if ligatures then + local t={} + for k,v in next,ligatures do + local i=indices[k] + if i then + t[i]=v + v.char=indices[v.char] + end + end + v.ligatures=next(t) and t or nil + end + end + tfmdata.fonts={ { id=virtualid } } + tfmdata.characters=characters + tfmdata.fullname=tfmdata.fullname or tfmdata.name + tfmdata.psname=file.nameonly(pfbfile or tfmdata.name) + tfmdata.filename=pfbfile + tfmdata.encodingbytes=2 + tfmdata.format="type1" + tfmdata.tounicode=1 + tfmdata.embedding="subset" + tfmdata.usedbitmap=bitmap and virtualid + tfmdata.private=private + return tfmdata + end end do - local template=[[ + local template=[[ /CIDInit /ProcSet findresource begin 12 dict begin begincmap @@ -32639,150 +33902,145 @@ CMapName currentdict /CMap defineresource pop end end end ]] - local flushstreamobject=lpdf and lpdf.flushstreamobject - local setfontattributes=pdf.setfontattributes - if flushstreamobject then - else - flushstreamobject=function(data) - return pdf.obj { - immediate=true, - type="stream", - string=data, - } - end - end - if not setfontattributes then - setfontattributes=function(id,data) - print(format("your luatex is too old so no tounicode bitmap font%i",id)) - end - end - function tfm.addtounicode(tfmdata) - local id=tfmdata.usedbitmap - local map={} - local char={} - for k,v in next,tfmdata.characters do - local index=v.oindex - local tounicode=v.tounicode - if index and tounicode then - map[index]=tounicode - end - end - for k,v in sortedhash(map) do - char[#char+1]=format("<%02X> <%s>",k,v) - end - char=concat(char,"\n") - local stream=format(template,id,id,#char,char) - local reference=flushstreamobject(stream,nil,true) - setfontattributes(id,format("/ToUnicode %i 0 R",reference)) - end + local flushstreamobject=lpdf and lpdf.flushstreamobject + local setfontattributes=lpdf and lpdf.setfontattributes + if not flushstreamobject then + flushstreamobject=function(data) + return pdf.obj { immediate=true,type="stream",string=data } + end + end + if not setfontattributes then + setfontattributes=function(id,data) + return pdf.setfontattributes(id,data) + end + end + function tfm.addtounicode(tfmdata) + local id=tfmdata.usedbitmap + local map={} + local char={} + for k,v in next,tfmdata.characters do + local index=v.oindex + local tounicode=v.tounicode + if index and tounicode then + map[index]=tounicode + end + end + for k,v in sortedhash(map) do + char[#char+1]=format("<%02X> <%s>",k,v) + end + char=concat(char,"\n") + local stream=format(template,id,id,#char,char) + local reference=flushstreamobject(stream,nil,true) + setfontattributes(id,format("/ToUnicode %i 0 R",reference)) + end end do - local everywhere={ ["*"]={ ["*"]=true } } - local noflags={ false,false,false,false } - local function enhance_normalize_features(data) - local ligatures=setmetatableindex("table") - local kerns=setmetatableindex("table") - local characters=data.characters - for u,c in next,characters do - local l=c.ligatures - local k=c.kerns - if l then - ligatures[u]=l - for u,v in next,l do - l[u]={ ligature=v.char } - end - c.ligatures=nil - end - if k then - kerns[u]=k - for u,v in next,k do - k[u]=v - end - c.kerns=nil - end - end - for u,l in next,ligatures do - for k,v in next,l do - local vl=v.ligature - local dl=ligatures[vl] - if dl then - for kk,vv in next,dl do - v[kk]=vv - end - end - end - end - local features={ - gpos={}, - gsub={}, - } - local sequences={ - } - if next(ligatures) then - features.gsub.liga=everywhere - data.properties.hasligatures=true - sequences[#sequences+1]={ - features={ - liga=everywhere, - }, - flags=noflags, - name="s_s_0", - nofsteps=1, - order={ "liga" }, - type="gsub_ligature", - steps={ - { - coverage=ligatures, - }, - }, - } - end - if next(kerns) then - features.gpos.kern=everywhere - data.properties.haskerns=true - sequences[#sequences+1]={ - features={ - kern=everywhere, - }, - flags=noflags, - name="p_s_0", - nofsteps=1, - order={ "kern" }, - type="gpos_pair", - steps={ - { - format="kern", - coverage=kerns, - }, - }, - } + local everywhere={ ["*"]={ ["*"]=true } } + local noflags={ false,false,false,false } + local function enhance_normalize_features(data) + local ligatures=setmetatableindex("table") + local kerns=setmetatableindex("table") + local characters=data.characters + for u,c in next,characters do + local l=c.ligatures + local k=c.kerns + if l then + ligatures[u]=l + for u,v in next,l do + l[u]={ ligature=v.char } + end + c.ligatures=nil + end + if k then + kerns[u]=k + for u,v in next,k do + k[u]=v + end + c.kerns=nil + end + end + for u,l in next,ligatures do + for k,v in next,l do + local vl=v.ligature + local dl=ligatures[vl] + if dl then + for kk,vv in next,dl do + v[kk]=vv + end end - data.resources.features=features - data.resources.sequences=sequences - data.shared.resources=data.shared.resources or resources + end + end + local features={ + gpos={}, + gsub={}, + } + local sequences={ + } + if next(ligatures) then + features.gsub.liga=everywhere + data.properties.hasligatures=true + sequences[#sequences+1]={ + features={ + liga=everywhere, + }, + flags=noflags, + name="s_s_0", + nofsteps=1, + order={ "liga" }, + type="gsub_ligature", + steps={ + { + coverage=ligatures, + }, + }, + } + end + if next(kerns) then + features.gpos.kern=everywhere + data.properties.haskerns=true + sequences[#sequences+1]={ + features={ + kern=everywhere, + }, + flags=noflags, + name="p_s_0", + nofsteps=1, + order={ "kern" }, + type="gpos_pair", + steps={ + { + format="kern", + coverage=kerns, + }, + }, + } end - registertfmenhancer("normalize features",enhance_normalize_features) - registertfmenhancer("check extra features",otfenhancers.enhance) + data.resources.features=features + data.resources.sequences=sequences + data.shared.resources=data.shared.resources or resources + end + registertfmenhancer("normalize features",enhance_normalize_features) + registertfmenhancer("check extra features",otfenhancers.enhance) end registertfmfeature { - name="mode", - description="mode", - initializers={ - base=otf.modeinitializer, - node=otf.modeinitializer, - } + name="mode", + description="mode", + initializers={ + base=otf.modeinitializer, + node=otf.modeinitializer, + } } registertfmfeature { - name="features", - description="features", - default=true, - initializers={ - base=otf.basemodeinitializer, - node=otf.nodemodeinitializer, - }, - processors={ - node=otf.featuresprocessor, - } + name="features", + description="features", + default=true, + initializers={ + base=otf.basemodeinitializer, + node=otf.nodemodeinitializer, + }, + processors={ + node=otf.featuresprocessor, + } } end -- closure @@ -32790,41 +34048,41 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-lua']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } -local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) +local trace_defining=false trackers.register("fonts.defining",function(v) trace_defining=v end) local report_lua=logs.reporter("fonts","lua loading") local fonts=fonts local readers=fonts.readers fonts.formats.lua="lua" local function check_lua(specification,fullname) - local fullname=resolvers.findfile(fullname) or "" - if fullname~="" then - local loader=loadfile(fullname) - loader=loader and loader() - return loader and loader(specification) - end + local fullname=resolvers.findfile(fullname) or "" + if fullname~="" then + local loader=loadfile(fullname) + loader=loader and loader() + return loader and loader(specification) + end end readers.check_lua=check_lua function readers.lua(specification) - local original=specification.specification - if trace_defining then - report_lua("using lua reader for %a",original) - end - local fullname=specification.filename or "" - if fullname=="" then - local forced=specification.forced or "" - if forced~="" then - fullname=specification.name.."."..forced - else - fullname=specification.name - end + local original=specification.specification + if trace_defining then + report_lua("using lua reader for %a",original) + end + local fullname=specification.filename or "" + if fullname=="" then + local forced=specification.forced or "" + if forced~="" then + fullname=specification.name.."."..forced + else + fullname=specification.name end - return check_lua(specification,fullname) + end + return check_lua(specification,fullname) end end -- closure @@ -32832,11 +34090,11 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['font-def']={ - version=1.001, - comment="companion to font-ini.mkiv", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } local lower,gsub=string.lower,string.gsub local tostring,next=tostring,next @@ -32845,8 +34103,8 @@ local suffixonly,removesuffix,basename=file.suffix,file.removesuffix,file.basena local formatters=string.formatters local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys local allocate=utilities.storage.allocate -local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) -local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) +local trace_defining=false trackers .register("fonts.defining",function(v) trace_defining=v end) +local directive_embedall=false directives.register("fonts.embedall",function(v) directive_embedall=v end) trackers.register("fonts.loading","fonts.defining","otf.loading","afm.loading","tfm.loading") local report_defining=logs.reporter("fonts","defining") local fonts=fonts @@ -32865,368 +34123,331 @@ local lastdefined=nil local loadedfonts=constructors.loadedfonts local designsizes=constructors.designsizes local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end -local splitter,splitspecifiers=nil,"" -local P,C,S,Cc=lpeg.P,lpeg.C,lpeg.S,lpeg.Cc -local left=P("(") -local right=P(")") -local colon=P(":") -local space=P(" ") -definers.defaultlookup="file" -local prefixpattern=P(false) -local function addspecifier(symbol) - splitspecifiers=splitspecifiers..symbol - local method=S(splitspecifiers) - local lookup=C(prefixpattern)*colon - local sub=left*C(P(1-left-right-method)^1)*right - local specification=C(method)*C(P(1)^1) - local name=C((1-sub-specification)^1) - splitter=P((lookup+Cc(""))*name*(sub+Cc(""))*(specification+Cc(""))) -end -local function addlookup(str,default) - prefixpattern=prefixpattern+P(str) -end -definers.addlookup=addlookup -addlookup("file") -addlookup("name") -addlookup("spec") -local function getspecification(str) - return lpegmatch(splitter,str or "") -end -definers.getspecification=getspecification -function definers.registersplit(symbol,action,verbosename) - addspecifier(symbol) - variants[symbol]=action - if verbosename then - variants[verbosename]=action - end -end local function makespecification(specification,lookup,name,sub,method,detail,size) - size=size or 655360 - if not lookup or lookup=="" then - lookup=definers.defaultlookup - end - if trace_defining then - report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a", - specification,lookup,name,sub,method,detail) - end - local t={ - lookup=lookup, - specification=specification, - size=size, - name=name, - sub=sub, - method=method, - detail=detail, - resolved="", - forced="", - features={}, - } - return t + size=size or 655360 + if not lookup or lookup=="" then + lookup=definers.defaultlookup + end + if trace_defining then + report_defining("specification %a, lookup %a, name %a, sub %a, method %a, detail %a", + specification,lookup,name,sub,method,detail) + end + local t={ + lookup=lookup, + specification=specification, + size=size, + name=name, + sub=sub, + method=method, + detail=detail, + resolved="", + forced="", + features={}, + } + return t end definers.makespecification=makespecification -function definers.analyze(specification,size) - local lookup,name,sub,method,detail=getspecification(specification or "") - return makespecification(specification,lookup,name,sub,method,detail,size) +if context then + +--removed + end definers.resolvers=definers.resolvers or {} local resolvers=definers.resolvers function resolvers.file(specification) - local name=resolvefile(specification.name) - local suffix=lower(suffixonly(name)) - if fonts.formats[suffix] then - specification.forced=suffix - specification.forcedname=name - specification.name=removesuffix(name) - else - specification.name=name - end + local name=resolvefile(specification.name) + local suffix=lower(suffixonly(name)) + if fonts.formats[suffix] then + specification.forced=suffix + specification.forcedname=name + specification.name=removesuffix(name) + else + specification.name=name + end end function resolvers.name(specification) - local resolve=fonts.names.resolve - if resolve then - local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) - if resolved then - specification.resolved=resolved - specification.sub=sub - specification.subindex=subindex - if instance then - specification.instance=instance - local features=specification.features - if not features then - features={} - specification.features=features - end - local normal=features.normal - if not normal then - normal={} - features.normal=normal - end - normal.instance=instance - if not callbacks.supported.glyph_stream_provider then - normal.variableshapes=true - end - end - local suffix=lower(suffixonly(resolved)) - if fonts.formats[suffix] then - specification.forced=suffix - specification.forcedname=resolved - specification.name=removesuffix(resolved) - else - specification.name=resolved - end - end - else - resolvers.file(specification) + local resolve=fonts.names.resolve + if resolve then + local resolved,sub,subindex,instance=resolve(specification.name,specification.sub,specification) + if resolved then + specification.resolved=resolved + specification.sub=sub + specification.subindex=subindex + if instance then + specification.instance=instance + local features=specification.features + if not features then + features={} + specification.features=features + end + local normal=features.normal + if not normal then + normal={} + features.normal=normal + end + normal.instance=instance + end + local suffix=lower(suffixonly(resolved)) + if fonts.formats[suffix] then + specification.forced=suffix + specification.forcedname=resolved + specification.name=removesuffix(resolved) + else + specification.name=resolved + end end + else + resolvers.file(specification) + end end function resolvers.spec(specification) - local resolvespec=fonts.names.resolvespec - if resolvespec then - local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) - if resolved then - specification.resolved=resolved - specification.sub=sub - specification.subindex=subindex - specification.forced=lower(suffixonly(resolved)) - specification.forcedname=resolved - specification.name=removesuffix(resolved) - end - else - resolvers.name(specification) - end + local resolvespec=fonts.names.resolvespec + if resolvespec then + local resolved,sub,subindex=resolvespec(specification.name,specification.sub,specification) + if resolved then + specification.resolved=resolved + specification.sub=sub + specification.subindex=subindex + specification.forced=lower(suffixonly(resolved)) + specification.forcedname=resolved + specification.name=removesuffix(resolved) + end + else + resolvers.name(specification) + end end function definers.resolve(specification) - if not specification.resolved or specification.resolved=="" then - local r=resolvers[specification.lookup] - if r then - r(specification) - end - end - if specification.forced=="" then - specification.forced=nil - specification.forcedname=nil - end - specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification)) - if specification.sub and specification.sub~="" then - specification.hash=specification.sub..' @ '..specification.hash - end - return specification + if not specification.resolved or specification.resolved=="" then + local r=resolvers[specification.lookup] + if r then + r(specification) + end + end + if specification.forced=="" then + specification.forced=nil + specification.forcedname=nil + end + specification.hash=lower(specification.name..' @ '..constructors.hashfeatures(specification)) + if specification.sub and specification.sub~="" then + specification.hash=specification.sub..' @ '..specification.hash + end + return specification end function definers.applypostprocessors(tfmdata) - local postprocessors=tfmdata.postprocessors - if postprocessors then - local properties=tfmdata.properties - for i=1,#postprocessors do - local extrahash=postprocessors[i](tfmdata) - if type(extrahash)=="string" and extrahash~="" then - extrahash=gsub(lower(extrahash),"[^a-z]","-") - properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) - end - end + local postprocessors=tfmdata.postprocessors + if postprocessors then + local properties=tfmdata.properties + for i=1,#postprocessors do + local extrahash=postprocessors[i](tfmdata) + if type(extrahash)=="string" and extrahash~="" then + extrahash=gsub(lower(extrahash),"[^a-z]","-") + properties.fullname=formatters["%s-%s"](properties.fullname,extrahash) + end end - return tfmdata + end + return tfmdata end local function checkembedding(tfmdata) - local properties=tfmdata.properties - local embedding - if directive_embedall then - embedding="full" - elseif properties and properties.filename and constructors.dontembed[properties.filename] then - embedding="no" - else - embedding="subset" - end - if properties then - properties.embedding=embedding - else - tfmdata.properties={ embedding=embedding } - end - tfmdata.embedding=embedding + local properties=tfmdata.properties + local embedding + if directive_embedall then + embedding="full" + elseif properties and properties.filename and constructors.dontembed[properties.filename] then + embedding="no" + else + embedding="subset" + end + if properties then + properties.embedding=embedding + else + tfmdata.properties={ embedding=embedding } + end + tfmdata.embedding=embedding end local function checkfeatures(tfmdata) - local resources=tfmdata.resources - local shared=tfmdata.shared - if resources and shared then - local features=resources.features - local usedfeatures=shared.features - if features and usedfeatures then - local usedlanguage=usedfeatures.language or "dflt" - local usedscript=usedfeatures.script or "dflt" - local function check(what) - if what then - local foundlanguages={} - for feature,scripts in next,what do - if usedscript=="auto" or scripts["*"] then - elseif not scripts[usedscript] then - else - for script,languages in next,scripts do - if languages["*"] then - elseif not languages[usedlanguage] then - report_defining("font %!font:name!, feature %a, script %a, no language %a", - tfmdata,feature,script,usedlanguage) - end - end - end - for script,languages in next,scripts do - for language in next,languages do - foundlanguages[language]=true - end - end - end - if false then - foundlanguages["*"]=nil - foundlanguages=sortedkeys(foundlanguages) - for feature,scripts in sortedhash(what) do - for script,languages in next,scripts do - if not languages["*"] then - for i=1,#foundlanguages do - local language=foundlanguages[i] - if not languages[language] then - report_defining("font %!font:name!, feature %a, script %a, no language %a", - tfmdata,feature,script,language) - end - end - end - end - end - end + local resources=tfmdata.resources + local shared=tfmdata.shared + if resources and shared then + local features=resources.features + local usedfeatures=shared.features + if features and usedfeatures then + local usedlanguage=usedfeatures.language or "dflt" + local usedscript=usedfeatures.script or "dflt" + local function check(what) + if what then + local foundlanguages={} + for feature,scripts in next,what do + if usedscript=="auto" or scripts["*"] then + elseif not scripts[usedscript] then + else + for script,languages in next,scripts do + if languages["*"] then + elseif context and not languages[usedlanguage] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,usedlanguage) end + end end - check(features.gsub) - check(features.gpos) - end - end -end -function definers.loadfont(specification) - local hash=constructors.hashinstance(specification) - local tfmdata=loadedfonts[hash] - if not tfmdata then - local forced=specification.forced or "" - if forced~="" then - local reader=readers[lower(forced)] - tfmdata=reader and reader(specification) - if not tfmdata then - report_defining("forced type %a of %a not found",forced,specification.name) + for script,languages in next,scripts do + for language in next,languages do + foundlanguages[language]=true + end end - else - local sequence=readers.sequence - for s=1,#sequence do - local reader=sequence[s] - if readers[reader] then - if trace_defining then - report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename) - end - tfmdata=readers[reader](specification) - if tfmdata then - break - else - specification.filename=nil - end + end + if false then + foundlanguages["*"]=nil + foundlanguages=sortedkeys(foundlanguages) + for feature,scripts in sortedhash(what) do + for script,languages in next,scripts do + if not languages["*"] then + for i=1,#foundlanguages do + local language=foundlanguages[i] + if context and not languages[language] then + report_defining("font %!font:name!, feature %a, script %a, no language %a", + tfmdata,feature,script,language) + end + end end + end end + end end - if tfmdata then - tfmdata=definers.applypostprocessors(tfmdata) - checkembedding(tfmdata) - loadedfonts[hash]=tfmdata - designsizes[specification.hash]=tfmdata.parameters.designsize - checkfeatures(tfmdata) - end + end + check(features.gsub) + check(features.gpos) end - if not tfmdata then - report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup) + end +end +function definers.loadfont(specification) + local hash=constructors.hashinstance(specification) + local tfmdata=loadedfonts[hash] + if not tfmdata then + local forced=specification.forced or "" + if forced~="" then + local reader=readers[lower(forced)] + tfmdata=reader and reader(specification) + if not tfmdata then + report_defining("forced type %a of %a not found",forced,specification.name) + end + else + local sequence=readers.sequence + for s=1,#sequence do + local reader=sequence[s] + if readers[reader] then + if trace_defining then + report_defining("trying (reader sequence driven) type %a for %a with file %a",reader,specification.name,specification.filename) + end + tfmdata=readers[reader](specification) + if tfmdata then + break + else + specification.filename=nil + end + end + end end - return tfmdata + if tfmdata then + tfmdata=definers.applypostprocessors(tfmdata) + checkembedding(tfmdata) + loadedfonts[hash]=tfmdata + designsizes[specification.hash]=tfmdata.parameters.designsize + checkfeatures(tfmdata) + end + end + if not tfmdata then + report_defining("font with asked name %a is not found using lookup %a",specification.name,specification.lookup) + end + return tfmdata end function constructors.readanddefine(name,size) - local specification=definers.analyze(name,size) - local method=specification.method - if method and variants[method] then - specification=variants[method](specification) - end - specification=definers.resolve(specification) - local hash=constructors.hashinstance(specification) - local id=definers.registered(hash) - if not id then - local tfmdata=definers.loadfont(specification) - if tfmdata then - tfmdata.properties.hash=hash - id=font.define(tfmdata) - definers.register(tfmdata,id) - else - id=0 - end + local specification=definers.analyze(name,size) + local method=specification.method + if method and variants[method] then + specification=variants[method](specification) + end + specification=definers.resolve(specification) + local hash=constructors.hashinstance(specification) + local id=definers.registered(hash) + if not id then + local tfmdata=definers.loadfont(specification) + if tfmdata then + tfmdata.properties.hash=hash + id=font.define(tfmdata) + definers.register(tfmdata,id) + else + id=0 end - return fontdata[id],id + end + return fontdata[id],id end function definers.current() - return lastdefined + return lastdefined end function definers.registered(hash) - local id=internalized[hash] - return id,id and fontdata[id] + local id=internalized[hash] + return id,id and fontdata[id] end function definers.register(tfmdata,id) - if tfmdata and id then - local hash=tfmdata.properties.hash - if not hash then - report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?") - elseif not internalized[hash] then - internalized[hash]=id - if trace_defining then - report_defining("registering font, id %s, hash %a",id,hash) - end - fontdata[id]=tfmdata - end - end + if tfmdata and id then + local hash=tfmdata.properties.hash + if not hash then + report_defining("registering font, id %a, name %a, invalid hash",id,tfmdata.properties.filename or "?") + elseif not internalized[hash] then + internalized[hash]=id + if trace_defining then + report_defining("registering font, id %s, hash %a",id,hash) + end + fontdata[id]=tfmdata + end + end end function definers.read(specification,size,id) - statistics.starttiming(fonts) - if type(specification)=="string" then - specification=definers.analyze(specification,size) - end - local method=specification.method - if method and variants[method] then - specification=variants[method](specification) + statistics.starttiming(fonts) + if type(specification)=="string" then + specification=definers.analyze(specification,size) + end + local method=specification.method + if method and variants[method] then + specification=variants[method](specification) + end + specification=definers.resolve(specification) + local hash=constructors.hashinstance(specification) + local tfmdata=definers.registered(hash) + if tfmdata then + if trace_defining then + report_defining("already hashed: %s",hash) end - specification=definers.resolve(specification) - local hash=constructors.hashinstance(specification) - local tfmdata=definers.registered(hash) + else + tfmdata=definers.loadfont(specification) if tfmdata then - if trace_defining then - report_defining("already hashed: %s",hash) - end + if trace_defining then + report_defining("loaded and hashed: %s",hash) + end + tfmdata.properties.hash=hash + if id then + definers.register(tfmdata,id) + end else - tfmdata=definers.loadfont(specification) - if tfmdata then - if trace_defining then - report_defining("loaded and hashed: %s",hash) - end - tfmdata.properties.hash=hash - if id then - definers.register(tfmdata,id) - end - else - if trace_defining then - report_defining("not loaded and hashed: %s",hash) - end - end - end - lastdefined=tfmdata or id - if not tfmdata then - report_defining("unknown font %a, loading aborted",specification.name) - elseif trace_defining and type(tfmdata)=="table" then - local properties=tfmdata.properties or {} - local parameters=tfmdata.parameters or {} - report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", - properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes, - properties.encodingname,properties.fullname,basename(properties.filename)) - end - statistics.stoptiming(fonts) - return tfmdata + if trace_defining then + report_defining("not loaded and hashed: %s",hash) + end + end + end + lastdefined=tfmdata or id + if not tfmdata then + report_defining("unknown font %a, loading aborted",specification.name) + elseif trace_defining and type(tfmdata)=="table" then + local properties=tfmdata.properties or {} + local parameters=tfmdata.parameters or {} + report_defining("using %a font with id %a, name %a, size %a, bytes %a, encoding %a, fullname %a, filename %a", + properties.format or "unknown",id or "-",properties.name,parameters.size,properties.encodingbytes, + properties.encodingname,properties.fullname,basename(properties.filename)) + end + statistics.stoptiming(fonts) + return tfmdata end function font.getfont(id) - return fontdata[id] + return fontdata[id] end callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") @@ -33235,81 +34456,83 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luatex-fonts-def']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end local fonts=fonts fonts.constructors.namemode="specification" function fonts.definers.getspecification(str) - return "",str,"",":",str -end -local list={} -local function issome () list.lookup='name' end -local function isfile () list.lookup='file' end -local function isname () list.lookup='name' end -local function thename(s) list.name=s end -local function issub (v) list.sub=v end -local function iscrap (s) list.crap=string.lower(s) end -local function iskey (k,v) list[k]=v end -local function istrue (s) list[s]=true end -local function isfalse(s) list[s]=false end -local P,S,R,C=lpeg.P,lpeg.S,lpeg.R,lpeg.C + return "",str,"",":",str +end +local list={} +local function issome () list.lookup='name' end +local function isfile () list.lookup='file' end +local function isname () list.lookup='name' end +local function thename(s) list.name=s end +local function issub (v) list.sub=v end +local function iscrap (s) list.crap=string.lower(s) end +local function iskey (k,v) list[k]=v end +local function istrue (s) list[s]=true end +local function isfalse(s) list[s]=false end +local P,S,R,C,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.Cs local spaces=P(" ")^0 -local namespec=(1-S("/:("))^0 +local namespec=Cs((P("{")/"")*(1-S("}"))^0*(P("}")/"")+(1-S("/:("))^0) local crapspec=spaces*P("/")*(((1-P(":"))^0)/iscrap)*spaces local filename_1=P("file:")/isfile*(namespec/thename) -local filename_2=P("[")*P(true)/isname*(((1-P("]"))^0)/thename)*P("]") +local filename_2=P("[")*P(true)/isfile*(((1-P("]"))^0)/thename)*P("]") local fontname_1=P("name:")/isname*(namespec/thename) local fontname_2=P(true)/issome*(namespec/thename) -local sometext=(R("az","AZ","09")+S("+-.{}"))^1 +local sometext=R("az","AZ","09")^1 +local somekey=R("az","AZ","09")^1 +local somevalue=(P("{")/"")*(1-P("}"))^0*(P("}")/"")+(1-S(";"))^1 local truevalue=P("+")*spaces*(sometext/istrue) local falsevalue=P("-")*spaces*(sometext/isfalse) -local keyvalue=(C(sometext)*spaces*P("=")*spaces*C(sometext))/iskey +local keyvalue=(C(somekey)*spaces*P("=")*spaces*C(somevalue))/iskey local somevalue=sometext/istrue local subvalue=P("(")*(C(P(1-S("()"))^1)/issub)*P(")") local option=spaces*(keyvalue+falsevalue+truevalue+somevalue)*spaces local options=P(":")*spaces*(P(";")^0*option)^0 local pattern=(filename_1+filename_2+fontname_1+fontname_2)*subvalue^0*crapspec^0*options^0 -local function colonized(specification) - list={} - lpeg.match(pattern,specification.specification) - list.crap=nil - if list.name then - specification.name=list.name - list.name=nil - end - if list.lookup then - specification.lookup=list.lookup - list.lookup=nil - end - if list.sub then - specification.sub=list.sub - list.sub=nil - end - specification.features.normal=fonts.handlers.otf.features.normalize(list) - return specification -end -fonts.definers.registersplit(":",colonized,"cryptic") -fonts.definers.registersplit("",colonized,"more cryptic") +function fonts.definers.analyze(str,size) + local specification=fonts.definers.makespecification(str,nil,nil,nil,":",nil,size) + list={} + lpeg.match(pattern,str) + list.crap=nil + if list.name then + specification.name=list.name + list.name=nil + end + if list.lookup then + specification.lookup=list.lookup + list.lookup=nil + end + if list.sub then + specification.sub=list.sub + list.sub=nil + end + specification.features.normal=fonts.handlers.otf.features.normalize(list) + list=nil + return specification +end function fonts.definers.applypostprocessors(tfmdata) - local postprocessors=tfmdata.postprocessors - if postprocessors then - for i=1,#postprocessors do - local extrahash=postprocessors[i](tfmdata) - if type(extrahash)=="string" and extrahash~="" then - extrahash=string.gsub(lower(extrahash),"[^a-z]","-") - tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash) - end - end - end - return tfmdata + local postprocessors=tfmdata.postprocessors + if postprocessors then + for i=1,#postprocessors do + local extrahash=postprocessors[i](tfmdata) + if type(extrahash)=="string" and extrahash~="" then + extrahash=string.gsub(lower(extrahash),"[^a-z]","-") + tfmdata.properties.fullname=format("%s-%s",tfmdata.properties.fullname,extrahash) + end + end + end + return tfmdata end end -- closure @@ -33317,267 +34540,861 @@ end -- closure do -- begin closure to overcome local limits and interference if not modules then modules={} end modules ['luatex-fonts-ext']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end +local byte=string.byte local fonts=fonts -local otffeatures=fonts.constructors.features.otf -local getprivate=fonts.constructors.getprivate -local function initializeitlc(tfmdata,value) - if value then - local parameters=tfmdata.parameters - local italicangle=parameters.italicangle - if italicangle and italicangle~=0 then - local properties=tfmdata.properties - local factor=tonumber(value) or 1 - properties.hasitalics=true - properties.autoitalicamount=factor*(parameters.uwidth or 40)/2 - end - end -end -otffeatures.register { - name="itlc", - description="italic correction", - initializers={ - base=initializeitlc, - node=initializeitlc, - } -} -local function initializeslant(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>1 then - value=1 - elseif value<-1 then - value=-1 - end - tfmdata.parameters.slantfactor=value -end -otffeatures.register { - name="slant", - description="slant glyphs", - initializers={ - base=initializeslant, - node=initializeslant, - } -} -local function initializeextend(tfmdata,value) - value=tonumber(value) - if not value then - value=0 - elseif value>10 then - value=10 - elseif value<-10 then - value=-10 - end - tfmdata.parameters.extendfactor=value -end -otffeatures.register { - name="extend", - description="scale glyphs horizontally", - initializers={ - base=initializeextend, - node=initializeextend, - } -} -fonts.protrusions=fonts.protrusions or {} +local handlers=fonts.handlers +local otf=handlers.otf +local afm=handlers.afm +local registerotffeature=otf.features.register +local registerafmfeature=afm.features.register +function fonts.loggers.onetimemessage() end +fonts.protrusions=fonts.protrusions or {} fonts.protrusions.setups=fonts.protrusions.setups or {} local setups=fonts.protrusions.setups +setups['default']={ + factor=1, + left=1, + right=1, + [0x002C]={ 0,1 }, + [0x002E]={ 0,1 }, + [0x003A]={ 0,1 }, + [0x003B]={ 0,1 }, + [0x002D]={ 0,1 }, + [0x2013]={ 0,0.50 }, + [0x2014]={ 0,0.33 }, + [0x3001]={ 0,1 }, + [0x3002]={ 0,1 }, + [0x060C]={ 0,1 }, + [0x061B]={ 0,1 }, + [0x06D4]={ 0,1 }, +} local function initializeprotrusion(tfmdata,value) - if value then - local setup=setups[value] - if setup then - local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1 - local emwidth=tfmdata.parameters.quad - tfmdata.parameters.protrusion={ - auto=true, - } - for i,chr in next,tfmdata.characters do - local v,pl,pr=setup[i],nil,nil - if v then - pl,pr=v[1],v[2] - end - if pl and pl~=0 then chr.left_protruding=left*pl*factor end - if pr and pr~=0 then chr.right_protruding=right*pr*factor end - end + if value then + local setup=setups[value] + if setup then + local factor,left,right=setup.factor or 1,setup.left or 1,setup.right or 1 + local emwidth=tfmdata.parameters.quad + tfmdata.parameters.protrusion={ + auto=true, + } + for i,chr in next,tfmdata.characters do + local v,pl,pr=setup[i],nil,nil + if v then + pl,pr=v[1],v[2] end + if pl and pl~=0 then chr.left_protruding=left*pl*factor end + if pr and pr~=0 then chr.right_protruding=right*pr*factor end + end end + end end -otffeatures.register { - name="protrusion", - description="shift characters into the left and or right margin", - initializers={ - base=initializeprotrusion, - node=initializeprotrusion, - } +local specification={ + name="protrusion", + description="shift characters into the left and or right margin", + initializers={ + base=initializeprotrusion, + node=initializeprotrusion, + } } -fonts.expansions=fonts.expansions or {} +registerotffeature(specification) +registerafmfeature(specification) +fonts.expansions=fonts.expansions or {} fonts.expansions.setups=fonts.expansions.setups or {} local setups=fonts.expansions.setups +setups['default']={ + stretch=2, + shrink=2, + step=.5, + factor=1, + [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7, + [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7, + [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7, + [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7, + [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7, + [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7, + [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7, + [byte('w')]=0.7,[byte('z')]=0.7, + [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7, +} local function initializeexpansion(tfmdata,value) - if value then - local setup=setups[value] - if setup then - local factor=setup.factor or 1 - tfmdata.parameters.expansion={ - stretch=10*(setup.stretch or 0), - shrink=10*(setup.shrink or 0), - step=10*(setup.step or 0), - auto=true, - } - for i,chr in next,tfmdata.characters do - local v=setup[i] - if v and v~=0 then - chr.expansion_factor=v*factor - else - chr.expansion_factor=factor - end - end + if value then + local setup=setups[value] + if setup then + local factor=setup.factor or 1 + tfmdata.parameters.expansion={ + stretch=10*(setup.stretch or 0), + shrink=10*(setup.shrink or 0), + step=10*(setup.step or 0), + auto=true, + } + for i,chr in next,tfmdata.characters do + local v=setup[i] + if v and v~=0 then + chr.expansion_factor=v*factor + else + chr.expansion_factor=factor end + end end + end end -otffeatures.register { - name="expansion", - description="apply hz optimization", - initializers={ - base=initializeexpansion, - node=initializeexpansion, - } -} -function fonts.loggers.onetimemessage() end -local byte=string.byte -fonts.expansions.setups['default']={ - stretch=2,shrink=2,step=.5,factor=1, - [byte('A')]=0.5,[byte('B')]=0.7,[byte('C')]=0.7,[byte('D')]=0.5,[byte('E')]=0.7, - [byte('F')]=0.7,[byte('G')]=0.5,[byte('H')]=0.7,[byte('K')]=0.7,[byte('M')]=0.7, - [byte('N')]=0.7,[byte('O')]=0.5,[byte('P')]=0.7,[byte('Q')]=0.5,[byte('R')]=0.7, - [byte('S')]=0.7,[byte('U')]=0.7,[byte('W')]=0.7,[byte('Z')]=0.7, - [byte('a')]=0.7,[byte('b')]=0.7,[byte('c')]=0.7,[byte('d')]=0.7,[byte('e')]=0.7, - [byte('g')]=0.7,[byte('h')]=0.7,[byte('k')]=0.7,[byte('m')]=0.7,[byte('n')]=0.7, - [byte('o')]=0.7,[byte('p')]=0.7,[byte('q')]=0.7,[byte('s')]=0.7,[byte('u')]=0.7, - [byte('w')]=0.7,[byte('z')]=0.7, - [byte('2')]=0.7,[byte('3')]=0.7,[byte('6')]=0.7,[byte('8')]=0.7,[byte('9')]=0.7, -} -fonts.protrusions.setups['default']={ - factor=1,left=1,right=1, - [0x002C]={ 0,1 }, - [0x002E]={ 0,1 }, - [0x003A]={ 0,1 }, - [0x003B]={ 0,1 }, - [0x002D]={ 0,1 }, - [0x2013]={ 0,0.50 }, - [0x2014]={ 0,0.33 }, - [0x3001]={ 0,1 }, - [0x3002]={ 0,1 }, - [0x060C]={ 0,1 }, - [0x061B]={ 0,1 }, - [0x06D4]={ 0,1 }, +local specification={ + name="expansion", + description="apply hz optimization", + initializers={ + base=initializeexpansion, + node=initializeexpansion, + } } -fonts.handlers.otf.features.normalize=function(t) +registerotffeature(specification) +registerafmfeature(specification) +if not otf.features.normalize then + otf.features.normalize=function(t) if t.rand then - t.rand="random" + t.rand="random" end return t + end end function fonts.helpers.nametoslot(name) - local t=type(name) - if t=="string" then - local tfmdata=fonts.hashes.identifiers[currentfont()] - local shared=tfmdata and tfmdata.shared - local fntdata=shared and shared.rawdata - return fntdata and fntdata.resources.unicodes[name] - elseif t=="number" then - return n - end + local t=type(name) + if t=="string" then + local tfmdata=fonts.hashes.identifiers[currentfont()] + local shared=tfmdata and tfmdata.shared + local fntdata=shared and shared.rawdata + return fntdata and fntdata.resources.unicodes[name] + elseif t=="number" then + return n + end end fonts.encodings=fonts.encodings or {} local reencodings={} fonts.encodings.reencodings=reencodings local function specialreencode(tfmdata,value) - local encoding=value and reencodings[value] - if encoding then - local temp={} - local char=tfmdata.characters - for k,v in next,encoding do - temp[k]=char[v] - end - for k,v in next,temp do - char[k]=temp[k] - end - return string.format("reencoded:%s",value) + local encoding=value and reencodings[value] + if encoding then + local temp={} + local char=tfmdata.characters + for k,v in next,encoding do + temp[k]=char[v] + end + for k,v in next,temp do + char[k]=temp[k] + end + return string.format("reencoded:%s",value) + end +end +local function initialize(tfmdata,value) + tfmdata.postprocessors=tfmdata.postprocessors or {} + table.insert(tfmdata.postprocessors, + function(tfmdata) + return specialreencode(tfmdata,value) end + ) +end +registerotffeature { + name="reencode", + description="reencode characters", + manipulators={ + base=initialize, + node=initialize, + } +} +local function initialize(tfmdata,key,value) + if value then + tfmdata.mathparameters=nil + end end -local function reencode(tfmdata,value) - tfmdata.postprocessors=tfmdata.postprocessors or {} - table.insert(tfmdata.postprocessors, - function(tfmdata) - return specialreencode(tfmdata,value) +registerotffeature { + name="ignoremathconstants", + description="ignore math constants table", + initializers={ + base=initialize, + node=initialize, + } +} + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-imp-tex']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next=next +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local addotffeature=otf.addfeature +local specification={ + type="ligature", + order={ "tlig" }, + prepend=true, + data={ + [0x2013]={ 0x002D,0x002D }, + [0x2014]={ 0x002D,0x002D,0x002D }, + }, +} +addotffeature("tlig",specification) +registerotffeature { + name="tlig", + description="tex ligatures", +} +local specification={ + type="substitution", + order={ "trep" }, + prepend=true, + data={ + [0x0027]=0x2019, + }, +} +addotffeature("trep",specification) +registerotffeature { + name="trep", + description="tex replacements", +} +local anum_arabic={ + [0x0030]=0x0660, + [0x0031]=0x0661, + [0x0032]=0x0662, + [0x0033]=0x0663, + [0x0034]=0x0664, + [0x0035]=0x0665, + [0x0036]=0x0666, + [0x0037]=0x0667, + [0x0038]=0x0668, + [0x0039]=0x0669, +} +local anum_persian={ + [0x0030]=0x06F0, + [0x0031]=0x06F1, + [0x0032]=0x06F2, + [0x0033]=0x06F3, + [0x0034]=0x06F4, + [0x0035]=0x06F5, + [0x0036]=0x06F6, + [0x0037]=0x06F7, + [0x0038]=0x06F8, + [0x0039]=0x06F9, +} +local function valid(data) + local features=data.resources.features + if features then + for k,v in next,features do + for k,v in next,v do + if v.arab then + return true end - ) + end + end + end end -otffeatures.register { - name="reencode", - description="reencode characters", - manipulators={ - base=reencode, - node=reencode, - } +local specification={ + { + type="substitution", + features={ arab={ urd=true,dflt=true } }, + order={ "anum" }, + data=anum_arabic, + valid=valid, + }, + { + type="substitution", + features={ arab={ urd=true } }, + order={ "anum" }, + data=anum_persian, + valid=valid, + }, } -local function ignore(tfmdata,key,value) - if value then - tfmdata.mathparameters=nil +addotffeature("anum",specification) +registerotffeature { + name="anum", + description="arabic digits", +} + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-imp-ligatures']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local lpegmatch=lpeg.match +local utfsplit=utf.split +local settings_to_array=utilities.parsers.settings_to_array +local fonts=fonts +local otf=fonts.handlers.otf +local registerotffeature=otf.features.register +local addotffeature=otf.addfeature +local lookups={} +local protect={} +local revert={} +local zwjchar=0x200C +local zwj={ zwjchar } +addotffeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + prepend=true, + future=true, + lookups={ + { + type="multiple", + data=lookups, + }, + }, + data={ + rules=protect, + } +} +addotffeature { + name="blockligatures", + type="chainsubstitution", + nocheck=true, + append=true, + overload=false, + lookups={ + { + type="ligature", + data=lookups, + }, + }, + data={ + rules=revert, + } +} +registerotffeature { + name='blockligatures', + description='block certain ligatures', +} +local splitter=lpeg.splitat(":") +local function blockligatures(str) + local t=settings_to_array(str) + for i=1,#t do + local ti=t[i] + local before,current,after=lpegmatch(splitter,ti) + if current and after then + if before then + before=utfsplit(before) + for i=1,#before do + before[i]={ before[i] } + end + end + if current then + current=utfsplit(current) + end + if after then + after=utfsplit(after) + for i=1,#after do + after[i]={ after[i] } + end + end + else + before=nil + current=utfsplit(ti) + after=nil + end + if #current>1 then + local one=current[1] + local two=current[2] + lookups[one]={ one,zwjchar } + local one={ one } + local two={ two } + local new=#protect+1 + protect[new]={ + before=before, + current={ one,two }, + after=after, + lookups={ 1 }, + } + revert[new]={ + current={ one,zwj }, + after={ two }, + lookups={ 1 }, + } + end + end +end +otf.helpers.blockligatures=blockligatures +if context then + +--removed + +end + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-imp-italics']={ + version=1.001, + comment="companion to font-ini.mkiv and hand-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next=next +local fonts=fonts +local handlers=fonts.handlers +local registerotffeature=handlers.otf.features.register +local registerafmfeature=handlers.afm.features.register +local function initialize(tfmdata,key,value) + for unicode,character in next,tfmdata.characters do + local olditalic=character.italic + if olditalic and olditalic~=0 then + character.width=character.width+olditalic + character.italic=0 + end + end +end +local specification={ + name="italicwidths", + description="add italic to width", + manipulators={ + base=initialize, + node=initialize, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initialize(tfmdata,value) + if value then + local parameters=tfmdata.parameters + local italicangle=parameters.italicangle + if italicangle and italicangle~=0 then + local properties=tfmdata.properties + local factor=tonumber(value) or 1 + properties.hasitalics=true + properties.autoitalicamount=factor*(parameters.uwidth or 40)/2 + end + end +end +local specification={ + name="itlc", + description="italic correction", + initializers={ + base=initialize, + node=initialize, + } +} +registerotffeature(specification) +registerafmfeature(specification) +if context then + +--removed + +end +if context then + local letter=characters.is_letter + local always=true + local function collapseitalics(tfmdata,key,value) + local threshold=value==true and 100 or tonumber(value) + if threshold and threshold>0 then + if threshold>100 then + threshold=100 + end + for unicode,data in next,tfmdata.characters do + if always or letter[unicode] or letter[data.unicode] then + local italic=data.italic + if italic and italic~=0 then + local width=data.width + if width and width~=0 then + local delta=threshold*italic/100 + data.width=width+delta + data.italic=italic-delta + end + end + end + end end + end + local dimensions_specification={ + name="collapseitalics", + description="collapse italics", + manipulators={ + base=collapseitalics, + node=collapseitalics, + } + } + registerotffeature(dimensions_specification) + registerafmfeature(dimensions_specification) end -otffeatures.register { - name="ignoremathconstants", - description="ignore math constants table", - initializers={ - base=ignore, - node=ignore, + +end -- closure + +do -- begin closure to overcome local limits and interference + +if not modules then modules={} end modules ['font-imp-effects']={ + version=1.001, + comment="companion to font-ini.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local next,type,tonumber=next,type,tonumber +local is_boolean=string.is_boolean +local fonts=fonts +local handlers=fonts.handlers +local registerotffeature=handlers.otf.features.register +local registerafmfeature=handlers.afm.features.register +local settings_to_hash=utilities.parsers.settings_to_hash_colon_too +local helpers=fonts.helpers +local prependcommands=helpers.prependcommands +local charcommand=helpers.commands.char +local leftcommand=helpers.commands.left +local rightcommand=helpers.commands.right +local upcommand=helpers.commands.up +local downcommand=helpers.commands.down +local dummycommand=helpers.commands.dummy +local report_effect=logs.reporter("fonts","effect") +local report_slant=logs.reporter("fonts","slant") +local report_extend=logs.reporter("fonts","extend") +local report_squeeze=logs.reporter("fonts","squeeze") +local trace=false +trackers.register("fonts.effect",function(v) trace=v end) +trackers.register("fonts.slant",function(v) trace=v end) +trackers.register("fonts.extend",function(v) trace=v end) +trackers.register("fonts.squeeze",function(v) trace=v end) +local function initializeslant(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>1 then + value=1 + elseif value<-1 then + value=-1 + end + if trace then + report_slant("applying %0.3f",value) + end + tfmdata.parameters.slantfactor=value +end +local specification={ + name="slant", + description="slant glyphs", + initializers={ + base=initializeslant, + node=initializeslant, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializeextend(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>10 then + value=10 + elseif value<-10 then + value=-10 + end + if trace then + report_extend("applying %0.3f",value) + end + tfmdata.parameters.extendfactor=value +end +local specification={ + name="extend", + description="scale glyphs horizontally", + initializers={ + base=initializeextend, + node=initializeextend, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializesqueeze(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + elseif value>10 then + value=10 + elseif value<-10 then + value=-10 + end + if trace then + report_squeeze("applying %0.3f",value) + end + tfmdata.parameters.squeezefactor=value +end +local specification={ + name="squeeze", + description="scale glyphs vertically", + initializers={ + base=initializesqueeze, + node=initializesqueeze, + } +} +registerotffeature(specification) +registerafmfeature(specification) +local effects={ + inner=0, + normal=0, + outer=1, + outline=1, + both=2, + hidden=3, +} +local function initializeeffect(tfmdata,value) + local spec + if type(value)=="number" then + spec={ width=value } + else + spec=settings_to_hash(value) + end + local effect=spec.effect or "both" + local width=tonumber(spec.width) or 0 + local mode=effects[effect] + if not mode then + report_effect("invalid effect %a",effect) + elseif width==0 and mode==0 then + report_effect("invalid width %a for effect %a",width,effect) + else + local parameters=tfmdata.parameters + local properties=tfmdata.properties + parameters.mode=mode + parameters.width=width*1000 + if is_boolean(spec.auto)==true then + local squeeze=1-width/20 + local average=(1-squeeze)*width*100 + spec.squeeze=squeeze + spec.extend=1+width/2 + spec.wdelta=average + spec.hdelta=average/2 + spec.ddelta=average/2 + spec.vshift=average/2 + end + local factor=tonumber(spec.factor) or 0 + local hfactor=tonumber(spec.hfactor) or factor + local vfactor=tonumber(spec.vfactor) or factor + local delta=tonumber(spec.delta) or 1 + local wdelta=tonumber(spec.wdelta) or delta + local hdelta=tonumber(spec.hdelta) or delta + local ddelta=tonumber(spec.ddelta) or hdelta + local vshift=tonumber(spec.vshift) or 0 + local slant=spec.slant + local extend=spec.extend + local squeeze=spec.squeeze + if slant then + initializeslant(tfmdata,slant) + end + if extend then + initializeextend(tfmdata,extend) + end + if squeeze then + initializesqueeze(tfmdata,squeeze) + end + properties.effect={ + effect=effect, + width=width, + factor=factor, + hfactor=hfactor, + vfactor=vfactor, + wdelta=wdelta, + hdelta=hdelta, + ddelta=ddelta, + vshift=vshift, + slant=tfmdata.parameters.slantfactor, + extend=tfmdata.parameters.extendfactor, + squeeze=tfmdata.parameters.squeezefactor, } + end +end +local rules={ + "RadicalRuleThickness", + "OverbarRuleThickness", + "FractionRuleThickness", + "UnderbarRuleThickness", } -local setmetatableindex=table.setmetatableindex -local function additalictowidth(tfmdata,key,value) +local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dx) + end + end + end +end +local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + local function wdpatch(char) + if wsnap~=0 then + char.width=char.width+wdelta/2 + end + end + local function htpatch(char) + if hsnap~=0 then + local height=char.height + if height then + char.height=char.height+2*dy + end + end + end + local character=characters[0x221A] + if character and character.next then + local char=character + local next=character.next + wdpatch(char) + htpatch(char) + while next do + char=characters[next] + wdpatch(char) + htpatch(char) + next=char.next + end + if char then + local v=char.vert_variants + if v then + local top=v[#v] + if top then + local char=characters[top.glyph] + htpatch(char) + end + end + end + end +end +local function manipulateeffect(tfmdata) + local effect=tfmdata.properties.effect + if effect then local characters=tfmdata.characters - local additions={} - for unicode,old_c in next,characters do - local oldwidth=old_c.width - local olditalic=old_c.italic - if olditalic and olditalic~=0 then - local private=getprivate(tfmdata) - local new_c={ - width=oldwidth+olditalic, - height=old_c.height, - depth=old_c.depth, - commands={ - { "slot",1,private }, - { "right",olditalic }, - }, + local parameters=tfmdata.parameters + local mathparameters=tfmdata.mathparameters + local multiplier=effect.width*100 + local factor=parameters.factor + local hfactor=parameters.hfactor + local vfactor=parameters.vfactor + local wdelta=effect.wdelta*hfactor*multiplier + local hdelta=effect.hdelta*vfactor*multiplier + local ddelta=effect.ddelta*vfactor*multiplier + local vshift=effect.vshift*vfactor*multiplier + local squeeze=effect.squeeze + local hshift=wdelta/2 + local dx=multiplier*vfactor + local dy=vshift + local factor=(1+effect.factor)*factor + local hfactor=(1+effect.hfactor)*hfactor + local vfactor=(1+effect.vfactor)*vfactor + local vshift=vshift~=0 and upcommand[vshift] or false + for unicode,character in next,characters do + local oldwidth=character.width + local oldheight=character.height + local olddepth=character.depth + if oldwidth and oldwidth>0 then + character.width=oldwidth+wdelta + local commands=character.commands + local hshift=rightcommand[hshift] + if vshift then + if commands then + prependcommands (commands, + hshift, + vshift + ) + else + character.commands={ + hshift, + vshift, + charcommand[unicode] + } + end + else + if commands then + prependcommands (commands, + hshift + ) + else + character.commands={ + hshift, + charcommand[unicode] } - setmetatableindex(new_c,old_c) - characters[unicode]=new_c - additions[private]=old_c + end end - end - for k,v in next,additions do - characters[k]=v - end -end -otffeatures.register { - name="italicwidths", - description="add italic to width", - manipulators={ - base=additalictowidth, - } + end + if oldheight and oldheight>0 then + character.height=oldheight+hdelta + end + if olddepth and olddepth>0 then + character.depth=olddepth+ddelta + end + end + if mathparameters then + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + end + parameters.factor=factor + parameters.hfactor=hfactor + parameters.vfactor=vfactor + if trace then + report_effect("applying") + report_effect(" effect : %s",effect.effect) + report_effect(" width : %s => %s",effect.width,multiplier) + report_effect(" factor : %s => %s",effect.factor,factor ) + report_effect(" hfactor : %s => %s",effect.hfactor,hfactor) + report_effect(" vfactor : %s => %s",effect.vfactor,vfactor) + report_effect(" wdelta : %s => %s",effect.wdelta,wdelta) + report_effect(" hdelta : %s => %s",effect.hdelta,hdelta) + report_effect(" ddelta : %s => %s",effect.ddelta,ddelta) + end + end +end +local specification={ + name="effect", + description="apply effects to glyphs", + initializers={ + base=initializeeffect, + node=initializeeffect, + }, + manipulators={ + base=manipulateeffect, + node=manipulateeffect, + }, +} +registerotffeature(specification) +registerafmfeature(specification) +local function initializeoutline(tfmdata,value) + value=tonumber(value) + if not value then + value=0 + else + value=tonumber(value) or 0 + end + local parameters=tfmdata.parameters + local properties=tfmdata.properties + parameters.mode=effects.outline + parameters.width=value*1000 + properties.effect={ + effect=effect, + width=width, + } +end +local specification={ + name="outline", + description="outline glyphs", + initializers={ + base=initializeoutline, + node=initializeoutline, + } } +registerotffeature(specification) +registerafmfeature(specification) end -- closure @@ -33586,2083 +35403,2084 @@ do -- begin closure to overcome local limits and interference fonts.handlers.otf.addfeature { ["dataset"]={ - { - ["data"]={ - ["À"]={ "A","̀" }, - ["Á"]={ "A","́" }, - ["Â"]={ "A","̂" }, - ["Ã"]={ "A","̃" }, - ["Ä"]={ "A","̈" }, - ["Å"]={ "A","̊" }, - ["Ç"]={ "C","̧" }, - ["È"]={ "E","̀" }, - ["É"]={ "E","́" }, - ["Ê"]={ "E","̂" }, - ["Ë"]={ "E","̈" }, - ["Ì"]={ "I","̀" }, - ["Í"]={ "I","́" }, - ["Î"]={ "I","̂" }, - ["Ï"]={ "I","̈" }, - ["Ñ"]={ "N","̃" }, - ["Ò"]={ "O","̀" }, - ["Ó"]={ "O","́" }, - ["Ô"]={ "O","̂" }, - ["Õ"]={ "O","̃" }, - ["Ö"]={ "O","̈" }, - ["Ù"]={ "U","̀" }, - ["Ú"]={ "U","́" }, - ["Û"]={ "U","̂" }, - ["Ü"]={ "U","̈" }, - ["Ý"]={ "Y","́" }, - ["à"]={ "a","̀" }, - ["á"]={ "a","́" }, - ["â"]={ "a","̂" }, - ["ã"]={ "a","̃" }, - ["ä"]={ "a","̈" }, - ["å"]={ "a","̊" }, - ["ç"]={ "c","̧" }, - ["è"]={ "e","̀" }, - ["é"]={ "e","́" }, - ["ê"]={ "e","̂" }, - ["ë"]={ "e","̈" }, - ["ì"]={ "i","̀" }, - ["í"]={ "i","́" }, - ["î"]={ "i","̂" }, - ["ï"]={ "i","̈" }, - ["ñ"]={ "n","̃" }, - ["ò"]={ "o","̀" }, - ["ó"]={ "o","́" }, - ["ô"]={ "o","̂" }, - ["õ"]={ "o","̃" }, - ["ö"]={ "o","̈" }, - ["ù"]={ "u","̀" }, - ["ú"]={ "u","́" }, - ["û"]={ "u","̂" }, - ["ü"]={ "u","̈" }, - ["ý"]={ "y","́" }, - ["ÿ"]={ "y","̈" }, - ["Ā"]={ "A","̄" }, - ["ā"]={ "a","̄" }, - ["Ă"]={ "A","̆" }, - ["ă"]={ "a","̆" }, - ["Ą"]={ "A","̨" }, - ["ą"]={ "a","̨" }, - ["Ć"]={ "C","́" }, - ["ć"]={ "c","́" }, - ["Ĉ"]={ "C","̂" }, - ["ĉ"]={ "c","̂" }, - ["Ċ"]={ "C","̇" }, - ["ċ"]={ "c","̇" }, - ["Č"]={ "C","̌" }, - ["č"]={ "c","̌" }, - ["Ď"]={ "D","̌" }, - ["ď"]={ "d","̌" }, - ["Ē"]={ "E","̄" }, - ["ē"]={ "e","̄" }, - ["Ĕ"]={ "E","̆" }, - ["ĕ"]={ "e","̆" }, - ["Ė"]={ "E","̇" }, - ["ė"]={ "e","̇" }, - ["Ę"]={ "E","̨" }, - ["ę"]={ "e","̨" }, - ["Ě"]={ "E","̌" }, - ["ě"]={ "e","̌" }, - ["Ĝ"]={ "G","̂" }, - ["ĝ"]={ "g","̂" }, - ["Ğ"]={ "G","̆" }, - ["ğ"]={ "g","̆" }, - ["Ġ"]={ "G","̇" }, - ["ġ"]={ "g","̇" }, - ["Ģ"]={ "G","̧" }, - ["ģ"]={ "g","̧" }, - ["Ĥ"]={ "H","̂" }, - ["ĥ"]={ "h","̂" }, - ["Ĩ"]={ "I","̃" }, - ["ĩ"]={ "i","̃" }, - ["Ī"]={ "I","̄" }, - ["ī"]={ "i","̄" }, - ["Ĭ"]={ "I","̆" }, - ["ĭ"]={ "i","̆" }, - ["Į"]={ "I","̨" }, - ["į"]={ "i","̨" }, - ["İ"]={ "I","̇" }, - ["Ĵ"]={ "J","̂" }, - ["ĵ"]={ "j","̂" }, - ["Ķ"]={ "K","̧" }, - ["ķ"]={ "k","̧" }, - ["Ĺ"]={ "L","́" }, - ["ĺ"]={ "l","́" }, - ["Ļ"]={ "L","̧" }, - ["ļ"]={ "l","̧" }, - ["Ľ"]={ "L","̌" }, - ["ľ"]={ "l","̌" }, - ["Ń"]={ "N","́" }, - ["ń"]={ "n","́" }, - ["Ņ"]={ "N","̧" }, - ["ņ"]={ "n","̧" }, - ["Ň"]={ "N","̌" }, - ["ň"]={ "n","̌" }, - ["Ō"]={ "O","̄" }, - ["ō"]={ "o","̄" }, - ["Ŏ"]={ "O","̆" }, - ["ŏ"]={ "o","̆" }, - ["Ő"]={ "O","̋" }, - ["ő"]={ "o","̋" }, - ["Ŕ"]={ "R","́" }, - ["ŕ"]={ "r","́" }, - ["Ŗ"]={ "R","̧" }, - ["ŗ"]={ "r","̧" }, - ["Ř"]={ "R","̌" }, - ["ř"]={ "r","̌" }, - ["Ś"]={ "S","́" }, - ["ś"]={ "s","́" }, - ["Ŝ"]={ "S","̂" }, - ["ŝ"]={ "s","̂" }, - ["Ş"]={ "S","̧" }, - ["ş"]={ "s","̧" }, - ["Š"]={ "S","̌" }, - ["š"]={ "s","̌" }, - ["Ţ"]={ "T","̧" }, - ["ţ"]={ "t","̧" }, - ["Ť"]={ "T","̌" }, - ["ť"]={ "t","̌" }, - ["Ũ"]={ "U","̃" }, - ["ũ"]={ "u","̃" }, - ["Ū"]={ "U","̄" }, - ["ū"]={ "u","̄" }, - ["Ŭ"]={ "U","̆" }, - ["ŭ"]={ "u","̆" }, - ["Ů"]={ "U","̊" }, - ["ů"]={ "u","̊" }, - ["Ű"]={ "U","̋" }, - ["ű"]={ "u","̋" }, - ["Ų"]={ "U","̨" }, - ["ų"]={ "u","̨" }, - ["Ŵ"]={ "W","̂" }, - ["ŵ"]={ "w","̂" }, - ["Ŷ"]={ "Y","̂" }, - ["ŷ"]={ "y","̂" }, - ["Ÿ"]={ "Y","̈" }, - ["Ź"]={ "Z","́" }, - ["ź"]={ "z","́" }, - ["Ż"]={ "Z","̇" }, - ["ż"]={ "z","̇" }, - ["Ž"]={ "Z","̌" }, - ["ž"]={ "z","̌" }, - ["Ơ"]={ "O","̛" }, - ["ơ"]={ "o","̛" }, - ["Ư"]={ "U","̛" }, - ["ư"]={ "u","̛" }, - ["Ǎ"]={ "A","̌" }, - ["ǎ"]={ "a","̌" }, - ["Ǐ"]={ "I","̌" }, - ["ǐ"]={ "i","̌" }, - ["Ǒ"]={ "O","̌" }, - ["ǒ"]={ "o","̌" }, - ["Ǔ"]={ "U","̌" }, - ["ǔ"]={ "u","̌" }, - ["Ǖ"]={ "Ü","̄" }, - ["ǖ"]={ "ü","̄" }, - ["Ǘ"]={ "Ü","́" }, - ["ǘ"]={ "ü","́" }, - ["Ǚ"]={ "Ü","̌" }, - ["ǚ"]={ "ü","̌" }, - ["Ǜ"]={ "Ü","̀" }, - ["ǜ"]={ "ü","̀" }, - ["Ǟ"]={ "Ä","̄" }, - ["ǟ"]={ "ä","̄" }, - ["Ǡ"]={ "Ȧ","̄" }, - ["ǡ"]={ "ȧ","̄" }, - ["Ǣ"]={ "Æ","̄" }, - ["ǣ"]={ "æ","̄" }, - ["Ǧ"]={ "G","̌" }, - ["ǧ"]={ "g","̌" }, - ["Ǩ"]={ "K","̌" }, - ["ǩ"]={ "k","̌" }, - ["Ǫ"]={ "O","̨" }, - ["ǫ"]={ "o","̨" }, - ["Ǭ"]={ "Ǫ","̄" }, - ["ǭ"]={ "ǫ","̄" }, - ["Ǯ"]={ "Ʒ","̌" }, - ["ǯ"]={ "ʒ","̌" }, - ["ǰ"]={ "j","̌" }, - ["Ǵ"]={ "G","́" }, - ["ǵ"]={ "g","́" }, - ["Ǹ"]={ "N","̀" }, - ["ǹ"]={ "n","̀" }, - ["Ǻ"]={ "Å","́" }, - ["ǻ"]={ "å","́" }, - ["Ǽ"]={ "Æ","́" }, - ["ǽ"]={ "æ","́" }, - ["Ǿ"]={ "Ø","́" }, - ["ǿ"]={ "ø","́" }, - ["Ȁ"]={ "A","̏" }, - ["ȁ"]={ "a","̏" }, - ["Ȃ"]={ "A","̑" }, - ["ȃ"]={ "a","̑" }, - ["Ȅ"]={ "E","̏" }, - ["ȅ"]={ "e","̏" }, - ["Ȇ"]={ "E","̑" }, - ["ȇ"]={ "e","̑" }, - ["Ȉ"]={ "I","̏" }, - ["ȉ"]={ "i","̏" }, - ["Ȋ"]={ "I","̑" }, - ["ȋ"]={ "i","̑" }, - ["Ȍ"]={ "O","̏" }, - ["ȍ"]={ "o","̏" }, - ["Ȏ"]={ "O","̑" }, - ["ȏ"]={ "o","̑" }, - ["Ȑ"]={ "R","̏" }, - ["ȑ"]={ "r","̏" }, - ["Ȓ"]={ "R","̑" }, - ["ȓ"]={ "r","̑" }, - ["Ȕ"]={ "U","̏" }, - ["ȕ"]={ "u","̏" }, - ["Ȗ"]={ "U","̑" }, - ["ȗ"]={ "u","̑" }, - ["Ș"]={ "S","̦" }, - ["ș"]={ "s","̦" }, - ["Ț"]={ "T","̦" }, - ["ț"]={ "t","̦" }, - ["Ȟ"]={ "H","̌" }, - ["ȟ"]={ "h","̌" }, - ["Ȧ"]={ "A","̇" }, - ["ȧ"]={ "a","̇" }, - ["Ȩ"]={ "E","̧" }, - ["ȩ"]={ "e","̧" }, - ["Ȫ"]={ "Ö","̄" }, - ["ȫ"]={ "ö","̄" }, - ["Ȭ"]={ "Õ","̄" }, - ["ȭ"]={ "õ","̄" }, - ["Ȯ"]={ "O","̇" }, - ["ȯ"]={ "o","̇" }, - ["Ȱ"]={ "Ȯ","̄" }, - ["ȱ"]={ "ȯ","̄" }, - ["Ȳ"]={ "Y","̄" }, - ["ȳ"]={ "y","̄" }, - ["̈́"]={ "̈","́" }, - ["΅"]={ "¨","́" }, - ["Ά"]={ "Α","́" }, - ["Έ"]={ "Ε","́" }, - ["Ή"]={ "Η","́" }, - ["Ί"]={ "Ι","́" }, - ["Ό"]={ "Ο","́" }, - ["Ύ"]={ "Υ","́" }, - ["Ώ"]={ "Ω","́" }, - ["ΐ"]={ "ϊ","́" }, - ["Ϊ"]={ "Ι","̈" }, - ["Ϋ"]={ "Υ","̈" }, - ["ά"]={ "α","́" }, - ["έ"]={ "ε","́" }, - ["ή"]={ "η","́" }, - ["ί"]={ "ι","́" }, - ["ΰ"]={ "ϋ","́" }, - ["ϊ"]={ "ι","̈" }, - ["ϋ"]={ "υ","̈" }, - ["ό"]={ "ο","́" }, - ["ύ"]={ "υ","́" }, - ["ώ"]={ "ω","́" }, - ["ϓ"]={ "ϒ","́" }, - ["ϔ"]={ "ϒ","̈" }, - ["Ѐ"]={ "Е","̀" }, - ["Ё"]={ "Е","̈" }, - ["Ѓ"]={ "Г","́" }, - ["Ї"]={ "І","̈" }, - ["Ќ"]={ "К","́" }, - ["Ѝ"]={ "И","̀" }, - ["Ў"]={ "У","̆" }, - ["Й"]={ "И","̆" }, - ["й"]={ "и","̆" }, - ["ѐ"]={ "е","̀" }, - ["ё"]={ "е","̈" }, - ["ѓ"]={ "г","́" }, - ["ї"]={ "і","̈" }, - ["ќ"]={ "к","́" }, - ["ѝ"]={ "и","̀" }, - ["ў"]={ "у","̆" }, - ["Ѷ"]={ "Ѵ","̏" }, - ["ѷ"]={ "ѵ","̏" }, - ["Ӂ"]={ "Ж","̆" }, - ["ӂ"]={ "ж","̆" }, - ["Ӑ"]={ "А","̆" }, - ["ӑ"]={ "а","̆" }, - ["Ӓ"]={ "А","̈" }, - ["ӓ"]={ "а","̈" }, - ["Ӗ"]={ "Е","̆" }, - ["ӗ"]={ "е","̆" }, - ["Ӛ"]={ "Ә","̈" }, - ["ӛ"]={ "ә","̈" }, - ["Ӝ"]={ "Ж","̈" }, - ["ӝ"]={ "ж","̈" }, - ["Ӟ"]={ "З","̈" }, - ["ӟ"]={ "з","̈" }, - ["Ӣ"]={ "И","̄" }, - ["ӣ"]={ "и","̄" }, - ["Ӥ"]={ "И","̈" }, - ["ӥ"]={ "и","̈" }, - ["Ӧ"]={ "О","̈" }, - ["ӧ"]={ "о","̈" }, - ["Ӫ"]={ "Ө","̈" }, - ["ӫ"]={ "ө","̈" }, - ["Ӭ"]={ "Э","̈" }, - ["ӭ"]={ "э","̈" }, - ["Ӯ"]={ "У","̄" }, - ["ӯ"]={ "у","̄" }, - ["Ӱ"]={ "У","̈" }, - ["ӱ"]={ "у","̈" }, - ["Ӳ"]={ "У","̋" }, - ["ӳ"]={ "у","̋" }, - ["Ӵ"]={ "Ч","̈" }, - ["ӵ"]={ "ч","̈" }, - ["Ӹ"]={ "Ы","̈" }, - ["ӹ"]={ "ы","̈" }, - ["آ"]={ "ا","ٓ" }, - ["أ"]={ "ا","ٔ" }, - ["ؤ"]={ "و","ٔ" }, - ["إ"]={ "ا","ٕ" }, - ["ئ"]={ "ي","ٔ" }, - ["ۀ"]={ "ە","ٔ" }, - ["ۂ"]={ "ہ","ٔ" }, - ["ۓ"]={ "ے","ٔ" }, - ["ऩ"]={ "न","़" }, - ["ऱ"]={ "र","़" }, - ["ऴ"]={ "ळ","़" }, - ["क़"]={ "क","़" }, - ["ख़"]={ "ख","़" }, - ["ग़"]={ "ग","़" }, - ["ज़"]={ "ज","़" }, - ["ड़"]={ "ड","़" }, - ["ढ़"]={ "ढ","़" }, - ["फ़"]={ "फ","़" }, - ["य़"]={ "य","़" }, - ["ো"]={ "ে","া" }, - ["ৌ"]={ "ে","ৗ" }, - ["ড়"]={ "ড","়" }, - ["ঢ়"]={ "ঢ","়" }, - ["য়"]={ "য","়" }, - ["ਲ਼"]={ "ਲ","਼" }, - ["ਸ਼"]={ "ਸ","਼" }, - ["ਖ਼"]={ "ਖ","਼" }, - ["ਗ਼"]={ "ਗ","਼" }, - ["ਜ਼"]={ "ਜ","਼" }, - ["ਫ਼"]={ "ਫ","਼" }, - ["ୈ"]={ "େ","ୖ" }, - ["ୋ"]={ "େ","ା" }, - ["ୌ"]={ "େ","ୗ" }, - ["ଡ଼"]={ "ଡ","଼" }, - ["ଢ଼"]={ "ଢ","଼" }, - ["ஔ"]={ "ஒ","ௗ" }, - ["ொ"]={ "ெ","ா" }, - ["ோ"]={ "ே","ா" }, - ["ௌ"]={ "ெ","ௗ" }, - ["ై"]={ "ె","ౖ" }, - ["ೀ"]={ "ಿ","ೕ" }, - ["ೇ"]={ "ೆ","ೕ" }, - ["ೈ"]={ "ೆ","ೖ" }, - ["ೊ"]={ "ೆ","ೂ" }, - ["ೋ"]={ "ೊ","ೕ" }, - ["ൊ"]={ "െ","ാ" }, - ["ോ"]={ "േ","ാ" }, - ["ൌ"]={ "െ","ൗ" }, - ["ේ"]={ "ෙ","්" }, - ["ො"]={ "ෙ","ා" }, - ["ෝ"]={ "ො","්" }, - ["ෞ"]={ "ෙ","ෟ" }, - ["གྷ"]={ "ག","ྷ" }, - ["ཌྷ"]={ "ཌ","ྷ" }, - ["དྷ"]={ "ད","ྷ" }, - ["བྷ"]={ "བ","ྷ" }, - ["ཛྷ"]={ "ཛ","ྷ" }, - ["ཀྵ"]={ "ཀ","ྵ" }, - ["ཱི"]={ "ཱ","ི" }, - ["ཱུ"]={ "ཱ","ུ" }, - ["ྲྀ"]={ "ྲ","ྀ" }, - ["ླྀ"]={ "ླ","ྀ" }, - ["ཱྀ"]={ "ཱ","ྀ" }, - ["ྒྷ"]={ "ྒ","ྷ" }, - ["ྜྷ"]={ "ྜ","ྷ" }, - ["ྡྷ"]={ "ྡ","ྷ" }, - ["ྦྷ"]={ "ྦ","ྷ" }, - ["ྫྷ"]={ "ྫ","ྷ" }, - ["ྐྵ"]={ "ྐ","ྵ" }, - ["ဦ"]={ "ဥ","ီ" }, - ["ᬆ"]={ "ᬅ","ᬵ" }, - ["ᬈ"]={ "ᬇ","ᬵ" }, - ["ᬊ"]={ "ᬉ","ᬵ" }, - ["ᬌ"]={ "ᬋ","ᬵ" }, - ["ᬎ"]={ "ᬍ","ᬵ" }, - ["ᬒ"]={ "ᬑ","ᬵ" }, - ["ᬻ"]={ "ᬺ","ᬵ" }, - ["ᬽ"]={ "ᬼ","ᬵ" }, - ["ᭀ"]={ "ᬾ","ᬵ" }, - ["ᭁ"]={ "ᬿ","ᬵ" }, - ["ᭃ"]={ "ᭂ","ᬵ" }, - ["Ḁ"]={ "A","̥" }, - ["ḁ"]={ "a","̥" }, - ["Ḃ"]={ "B","̇" }, - ["ḃ"]={ "b","̇" }, - ["Ḅ"]={ "B","̣" }, - ["ḅ"]={ "b","̣" }, - ["Ḇ"]={ "B","̱" }, - ["ḇ"]={ "b","̱" }, - ["Ḉ"]={ "Ç","́" }, - ["ḉ"]={ "ç","́" }, - ["Ḋ"]={ "D","̇" }, - ["ḋ"]={ "d","̇" }, - ["Ḍ"]={ "D","̣" }, - ["ḍ"]={ "d","̣" }, - ["Ḏ"]={ "D","̱" }, - ["ḏ"]={ "d","̱" }, - ["Ḑ"]={ "D","̧" }, - ["ḑ"]={ "d","̧" }, - ["Ḓ"]={ "D","̭" }, - ["ḓ"]={ "d","̭" }, - ["Ḕ"]={ "Ē","̀" }, - ["ḕ"]={ "ē","̀" }, - ["Ḗ"]={ "Ē","́" }, - ["ḗ"]={ "ē","́" }, - ["Ḙ"]={ "E","̭" }, - ["ḙ"]={ "e","̭" }, - ["Ḛ"]={ "E","̰" }, - ["ḛ"]={ "e","̰" }, - ["Ḝ"]={ "Ȩ","̆" }, - ["ḝ"]={ "ȩ","̆" }, - ["Ḟ"]={ "F","̇" }, - ["ḟ"]={ "f","̇" }, - ["Ḡ"]={ "G","̄" }, - ["ḡ"]={ "g","̄" }, - ["Ḣ"]={ "H","̇" }, - ["ḣ"]={ "h","̇" }, - ["Ḥ"]={ "H","̣" }, - ["ḥ"]={ "h","̣" }, - ["Ḧ"]={ "H","̈" }, - ["ḧ"]={ "h","̈" }, - ["Ḩ"]={ "H","̧" }, - ["ḩ"]={ "h","̧" }, - ["Ḫ"]={ "H","̮" }, - ["ḫ"]={ "h","̮" }, - ["Ḭ"]={ "I","̰" }, - ["ḭ"]={ "i","̰" }, - ["Ḯ"]={ "Ï","́" }, - ["ḯ"]={ "ï","́" }, - ["Ḱ"]={ "K","́" }, - ["ḱ"]={ "k","́" }, - ["Ḳ"]={ "K","̣" }, - ["ḳ"]={ "k","̣" }, - ["Ḵ"]={ "K","̱" }, - ["ḵ"]={ "k","̱" }, - ["Ḷ"]={ "L","̣" }, - ["ḷ"]={ "l","̣" }, - ["Ḹ"]={ "Ḷ","̄" }, - ["ḹ"]={ "ḷ","̄" }, - ["Ḻ"]={ "L","̱" }, - ["ḻ"]={ "l","̱" }, - ["Ḽ"]={ "L","̭" }, - ["ḽ"]={ "l","̭" }, - ["Ḿ"]={ "M","́" }, - ["ḿ"]={ "m","́" }, - ["Ṁ"]={ "M","̇" }, - ["ṁ"]={ "m","̇" }, - ["Ṃ"]={ "M","̣" }, - ["ṃ"]={ "m","̣" }, - ["Ṅ"]={ "N","̇" }, - ["ṅ"]={ "n","̇" }, - ["Ṇ"]={ "N","̣" }, - ["ṇ"]={ "n","̣" }, - ["Ṉ"]={ "N","̱" }, - ["ṉ"]={ "n","̱" }, - ["Ṋ"]={ "N","̭" }, - ["ṋ"]={ "n","̭" }, - ["Ṍ"]={ "Õ","́" }, - ["ṍ"]={ "õ","́" }, - ["Ṏ"]={ "Õ","̈" }, - ["ṏ"]={ "õ","̈" }, - ["Ṑ"]={ "Ō","̀" }, - ["ṑ"]={ "ō","̀" }, - ["Ṓ"]={ "Ō","́" }, - ["ṓ"]={ "ō","́" }, - ["Ṕ"]={ "P","́" }, - ["ṕ"]={ "p","́" }, - ["Ṗ"]={ "P","̇" }, - ["ṗ"]={ "p","̇" }, - ["Ṙ"]={ "R","̇" }, - ["ṙ"]={ "r","̇" }, - ["Ṛ"]={ "R","̣" }, - ["ṛ"]={ "r","̣" }, - ["Ṝ"]={ "Ṛ","̄" }, - ["ṝ"]={ "ṛ","̄" }, - ["Ṟ"]={ "R","̱" }, - ["ṟ"]={ "r","̱" }, - ["Ṡ"]={ "S","̇" }, - ["ṡ"]={ "s","̇" }, - ["Ṣ"]={ "S","̣" }, - ["ṣ"]={ "s","̣" }, - ["Ṥ"]={ "Ś","̇" }, - ["ṥ"]={ "ś","̇" }, - ["Ṧ"]={ "Š","̇" }, - ["ṧ"]={ "š","̇" }, - ["Ṩ"]={ "Ṣ","̇" }, - ["ṩ"]={ "ṣ","̇" }, - ["Ṫ"]={ "T","̇" }, - ["ṫ"]={ "t","̇" }, - ["Ṭ"]={ "T","̣" }, - ["ṭ"]={ "t","̣" }, - ["Ṯ"]={ "T","̱" }, - ["ṯ"]={ "t","̱" }, - ["Ṱ"]={ "T","̭" }, - ["ṱ"]={ "t","̭" }, - ["Ṳ"]={ "U","̤" }, - ["ṳ"]={ "u","̤" }, - ["Ṵ"]={ "U","̰" }, - ["ṵ"]={ "u","̰" }, - ["Ṷ"]={ "U","̭" }, - ["ṷ"]={ "u","̭" }, - ["Ṹ"]={ "Ũ","́" }, - ["ṹ"]={ "ũ","́" }, - ["Ṻ"]={ "Ū","̈" }, - ["ṻ"]={ "ū","̈" }, - ["Ṽ"]={ "V","̃" }, - ["ṽ"]={ "v","̃" }, - ["Ṿ"]={ "V","̣" }, - ["ṿ"]={ "v","̣" }, - ["Ẁ"]={ "W","̀" }, - ["ẁ"]={ "w","̀" }, - ["Ẃ"]={ "W","́" }, - ["ẃ"]={ "w","́" }, - ["Ẅ"]={ "W","̈" }, - ["ẅ"]={ "w","̈" }, - ["Ẇ"]={ "W","̇" }, - ["ẇ"]={ "w","̇" }, - ["Ẉ"]={ "W","̣" }, - ["ẉ"]={ "w","̣" }, - ["Ẋ"]={ "X","̇" }, - ["ẋ"]={ "x","̇" }, - ["Ẍ"]={ "X","̈" }, - ["ẍ"]={ "x","̈" }, - ["Ẏ"]={ "Y","̇" }, - ["ẏ"]={ "y","̇" }, - ["Ẑ"]={ "Z","̂" }, - ["ẑ"]={ "z","̂" }, - ["Ẓ"]={ "Z","̣" }, - ["ẓ"]={ "z","̣" }, - ["Ẕ"]={ "Z","̱" }, - ["ẕ"]={ "z","̱" }, - ["ẖ"]={ "h","̱" }, - ["ẗ"]={ "t","̈" }, - ["ẘ"]={ "w","̊" }, - ["ẙ"]={ "y","̊" }, - ["ẛ"]={ "ſ","̇" }, - ["Ạ"]={ "A","̣" }, - ["ạ"]={ "a","̣" }, - ["Ả"]={ "A","̉" }, - ["ả"]={ "a","̉" }, - ["Ấ"]={ "Â","́" }, - ["ấ"]={ "â","́" }, - ["Ầ"]={ "Â","̀" }, - ["ầ"]={ "â","̀" }, - ["Ẩ"]={ "Â","̉" }, - ["ẩ"]={ "â","̉" }, - ["Ẫ"]={ "Â","̃" }, - ["ẫ"]={ "â","̃" }, - ["Ậ"]={ "Ạ","̂" }, - ["ậ"]={ "ạ","̂" }, - ["Ắ"]={ "Ă","́" }, - ["ắ"]={ "ă","́" }, - ["Ằ"]={ "Ă","̀" }, - ["ằ"]={ "ă","̀" }, - ["Ẳ"]={ "Ă","̉" }, - ["ẳ"]={ "ă","̉" }, - ["Ẵ"]={ "Ă","̃" }, - ["ẵ"]={ "ă","̃" }, - ["Ặ"]={ "Ạ","̆" }, - ["ặ"]={ "ạ","̆" }, - ["Ẹ"]={ "E","̣" }, - ["ẹ"]={ "e","̣" }, - ["Ẻ"]={ "E","̉" }, - ["ẻ"]={ "e","̉" }, - ["Ẽ"]={ "E","̃" }, - ["ẽ"]={ "e","̃" }, - ["Ế"]={ "Ê","́" }, - ["ế"]={ "ê","́" }, - ["Ề"]={ "Ê","̀" }, - ["ề"]={ "ê","̀" }, - ["Ể"]={ "Ê","̉" }, - ["ể"]={ "ê","̉" }, - ["Ễ"]={ "Ê","̃" }, - ["ễ"]={ "ê","̃" }, - ["Ệ"]={ "Ẹ","̂" }, - ["ệ"]={ "ẹ","̂" }, - ["Ỉ"]={ "I","̉" }, - ["ỉ"]={ "i","̉" }, - ["Ị"]={ "I","̣" }, - ["ị"]={ "i","̣" }, - ["Ọ"]={ "O","̣" }, - ["ọ"]={ "o","̣" }, - ["Ỏ"]={ "O","̉" }, - ["ỏ"]={ "o","̉" }, - ["Ố"]={ "Ô","́" }, - ["ố"]={ "ô","́" }, - ["Ồ"]={ "Ô","̀" }, - ["ồ"]={ "ô","̀" }, - ["Ổ"]={ "Ô","̉" }, - ["ổ"]={ "ô","̉" }, - ["Ỗ"]={ "Ô","̃" }, - ["ỗ"]={ "ô","̃" }, - ["Ộ"]={ "Ọ","̂" }, - ["ộ"]={ "ọ","̂" }, - ["Ớ"]={ "Ơ","́" }, - ["ớ"]={ "ơ","́" }, - ["Ờ"]={ "Ơ","̀" }, - ["ờ"]={ "ơ","̀" }, - ["Ở"]={ "Ơ","̉" }, - ["ở"]={ "ơ","̉" }, - ["Ỡ"]={ "Ơ","̃" }, - ["ỡ"]={ "ơ","̃" }, - ["Ợ"]={ "Ơ","̣" }, - ["ợ"]={ "ơ","̣" }, - ["Ụ"]={ "U","̣" }, - ["ụ"]={ "u","̣" }, - ["Ủ"]={ "U","̉" }, - ["ủ"]={ "u","̉" }, - ["Ứ"]={ "Ư","́" }, - ["ứ"]={ "ư","́" }, - ["Ừ"]={ "Ư","̀" }, - ["ừ"]={ "ư","̀" }, - ["Ử"]={ "Ư","̉" }, - ["ử"]={ "ư","̉" }, - ["Ữ"]={ "Ư","̃" }, - ["ữ"]={ "ư","̃" }, - ["Ự"]={ "Ư","̣" }, - ["ự"]={ "ư","̣" }, - ["Ỳ"]={ "Y","̀" }, - ["ỳ"]={ "y","̀" }, - ["Ỵ"]={ "Y","̣" }, - ["ỵ"]={ "y","̣" }, - ["Ỷ"]={ "Y","̉" }, - ["ỷ"]={ "y","̉" }, - ["Ỹ"]={ "Y","̃" }, - ["ỹ"]={ "y","̃" }, - ["ἀ"]={ "α","̓" }, - ["ἁ"]={ "α","̔" }, - ["ἂ"]={ "ἀ","̀" }, - ["ἃ"]={ "ἁ","̀" }, - ["ἄ"]={ "ἀ","́" }, - ["ἅ"]={ "ἁ","́" }, - ["ἆ"]={ "ἀ","͂" }, - ["ἇ"]={ "ἁ","͂" }, - ["Ἀ"]={ "Α","̓" }, - ["Ἁ"]={ "Α","̔" }, - ["Ἂ"]={ "Ἀ","̀" }, - ["Ἃ"]={ "Ἁ","̀" }, - ["Ἄ"]={ "Ἀ","́" }, - ["Ἅ"]={ "Ἁ","́" }, - ["Ἆ"]={ "Ἀ","͂" }, - ["Ἇ"]={ "Ἁ","͂" }, - ["ἐ"]={ "ε","̓" }, - ["ἑ"]={ "ε","̔" }, - ["ἒ"]={ "ἐ","̀" }, - ["ἓ"]={ "ἑ","̀" }, - ["ἔ"]={ "ἐ","́" }, - ["ἕ"]={ "ἑ","́" }, - ["Ἐ"]={ "Ε","̓" }, - ["Ἑ"]={ "Ε","̔" }, - ["Ἒ"]={ "Ἐ","̀" }, - ["Ἓ"]={ "Ἑ","̀" }, - ["Ἔ"]={ "Ἐ","́" }, - ["Ἕ"]={ "Ἑ","́" }, - ["ἠ"]={ "η","̓" }, - ["ἡ"]={ "η","̔" }, - ["ἢ"]={ "ἠ","̀" }, - ["ἣ"]={ "ἡ","̀" }, - ["ἤ"]={ "ἠ","́" }, - ["ἥ"]={ "ἡ","́" }, - ["ἦ"]={ "ἠ","͂" }, - ["ἧ"]={ "ἡ","͂" }, - ["Ἠ"]={ "Η","̓" }, - ["Ἡ"]={ "Η","̔" }, - ["Ἢ"]={ "Ἠ","̀" }, - ["Ἣ"]={ "Ἡ","̀" }, - ["Ἤ"]={ "Ἠ","́" }, - ["Ἥ"]={ "Ἡ","́" }, - ["Ἦ"]={ "Ἠ","͂" }, - ["Ἧ"]={ "Ἡ","͂" }, - ["ἰ"]={ "ι","̓" }, - ["ἱ"]={ "ι","̔" }, - ["ἲ"]={ "ἰ","̀" }, - ["ἳ"]={ "ἱ","̀" }, - ["ἴ"]={ "ἰ","́" }, - ["ἵ"]={ "ἱ","́" }, - ["ἶ"]={ "ἰ","͂" }, - ["ἷ"]={ "ἱ","͂" }, - ["Ἰ"]={ "Ι","̓" }, - ["Ἱ"]={ "Ι","̔" }, - ["Ἲ"]={ "Ἰ","̀" }, - ["Ἳ"]={ "Ἱ","̀" }, - ["Ἴ"]={ "Ἰ","́" }, - ["Ἵ"]={ "Ἱ","́" }, - ["Ἶ"]={ "Ἰ","͂" }, - ["Ἷ"]={ "Ἱ","͂" }, - ["ὀ"]={ "ο","̓" }, - ["ὁ"]={ "ο","̔" }, - ["ὂ"]={ "ὀ","̀" }, - ["ὃ"]={ "ὁ","̀" }, - ["ὄ"]={ "ὀ","́" }, - ["ὅ"]={ "ὁ","́" }, - ["Ὀ"]={ "Ο","̓" }, - ["Ὁ"]={ "Ο","̔" }, - ["Ὂ"]={ "Ὀ","̀" }, - ["Ὃ"]={ "Ὁ","̀" }, - ["Ὄ"]={ "Ὀ","́" }, - ["Ὅ"]={ "Ὁ","́" }, - ["ὐ"]={ "υ","̓" }, - ["ὑ"]={ "υ","̔" }, - ["ὒ"]={ "ὐ","̀" }, - ["ὓ"]={ "ὑ","̀" }, - ["ὔ"]={ "ὐ","́" }, - ["ὕ"]={ "ὑ","́" }, - ["ὖ"]={ "ὐ","͂" }, - ["ὗ"]={ "ὑ","͂" }, - ["Ὑ"]={ "Υ","̔" }, - ["Ὓ"]={ "Ὑ","̀" }, - ["Ὕ"]={ "Ὑ","́" }, - ["Ὗ"]={ "Ὑ","͂" }, - ["ὠ"]={ "ω","̓" }, - ["ὡ"]={ "ω","̔" }, - ["ὢ"]={ "ὠ","̀" }, - ["ὣ"]={ "ὡ","̀" }, - ["ὤ"]={ "ὠ","́" }, - ["ὥ"]={ "ὡ","́" }, - ["ὦ"]={ "ὠ","͂" }, - ["ὧ"]={ "ὡ","͂" }, - ["Ὠ"]={ "Ω","̓" }, - ["Ὡ"]={ "Ω","̔" }, - ["Ὢ"]={ "Ὠ","̀" }, - ["Ὣ"]={ "Ὡ","̀" }, - ["Ὤ"]={ "Ὠ","́" }, - ["Ὥ"]={ "Ὡ","́" }, - ["Ὦ"]={ "Ὠ","͂" }, - ["Ὧ"]={ "Ὡ","͂" }, - ["ὰ"]={ "α","̀" }, - ["ὲ"]={ "ε","̀" }, - ["ὴ"]={ "η","̀" }, - ["ὶ"]={ "ι","̀" }, - ["ὸ"]={ "ο","̀" }, - ["ὺ"]={ "υ","̀" }, - ["ὼ"]={ "ω","̀" }, - ["ᾀ"]={ "ἀ","ͅ" }, - ["ᾁ"]={ "ἁ","ͅ" }, - ["ᾂ"]={ "ἂ","ͅ" }, - ["ᾃ"]={ "ἃ","ͅ" }, - ["ᾄ"]={ "ἄ","ͅ" }, - ["ᾅ"]={ "ἅ","ͅ" }, - ["ᾆ"]={ "ἆ","ͅ" }, - ["ᾇ"]={ "ἇ","ͅ" }, - ["ᾈ"]={ "Ἀ","ͅ" }, - ["ᾉ"]={ "Ἁ","ͅ" }, - ["ᾊ"]={ "Ἂ","ͅ" }, - ["ᾋ"]={ "Ἃ","ͅ" }, - ["ᾌ"]={ "Ἄ","ͅ" }, - ["ᾍ"]={ "Ἅ","ͅ" }, - ["ᾎ"]={ "Ἆ","ͅ" }, - ["ᾏ"]={ "Ἇ","ͅ" }, - ["ᾐ"]={ "ἠ","ͅ" }, - ["ᾑ"]={ "ἡ","ͅ" }, - ["ᾒ"]={ "ἢ","ͅ" }, - ["ᾓ"]={ "ἣ","ͅ" }, - ["ᾔ"]={ "ἤ","ͅ" }, - ["ᾕ"]={ "ἥ","ͅ" }, - ["ᾖ"]={ "ἦ","ͅ" }, - ["ᾗ"]={ "ἧ","ͅ" }, - ["ᾘ"]={ "Ἠ","ͅ" }, - ["ᾙ"]={ "Ἡ","ͅ" }, - ["ᾚ"]={ "Ἢ","ͅ" }, - ["ᾛ"]={ "Ἣ","ͅ" }, - ["ᾜ"]={ "Ἤ","ͅ" }, - ["ᾝ"]={ "Ἥ","ͅ" }, - ["ᾞ"]={ "Ἦ","ͅ" }, - ["ᾟ"]={ "Ἧ","ͅ" }, - ["ᾠ"]={ "ὠ","ͅ" }, - ["ᾡ"]={ "ὡ","ͅ" }, - ["ᾢ"]={ "ὢ","ͅ" }, - ["ᾣ"]={ "ὣ","ͅ" }, - ["ᾤ"]={ "ὤ","ͅ" }, - ["ᾥ"]={ "ὥ","ͅ" }, - ["ᾦ"]={ "ὦ","ͅ" }, - ["ᾧ"]={ "ὧ","ͅ" }, - ["ᾨ"]={ "Ὠ","ͅ" }, - ["ᾩ"]={ "Ὡ","ͅ" }, - ["ᾪ"]={ "Ὢ","ͅ" }, - ["ᾫ"]={ "Ὣ","ͅ" }, - ["ᾬ"]={ "Ὤ","ͅ" }, - ["ᾭ"]={ "Ὥ","ͅ" }, - ["ᾮ"]={ "Ὦ","ͅ" }, - ["ᾯ"]={ "Ὧ","ͅ" }, - ["ᾰ"]={ "α","̆" }, - ["ᾱ"]={ "α","̄" }, - ["ᾲ"]={ "ὰ","ͅ" }, - ["ᾳ"]={ "α","ͅ" }, - ["ᾴ"]={ "ά","ͅ" }, - ["ᾶ"]={ "α","͂" }, - ["ᾷ"]={ "ᾶ","ͅ" }, - ["Ᾰ"]={ "Α","̆" }, - ["Ᾱ"]={ "Α","̄" }, - ["Ὰ"]={ "Α","̀" }, - ["ᾼ"]={ "Α","ͅ" }, - ["῁"]={ "¨","͂" }, - ["ῂ"]={ "ὴ","ͅ" }, - ["ῃ"]={ "η","ͅ" }, - ["ῄ"]={ "ή","ͅ" }, - ["ῆ"]={ "η","͂" }, - ["ῇ"]={ "ῆ","ͅ" }, - ["Ὲ"]={ "Ε","̀" }, - ["Ὴ"]={ "Η","̀" }, - ["ῌ"]={ "Η","ͅ" }, - ["῍"]={ "᾿","̀" }, - ["῎"]={ "᾿","́" }, - ["῏"]={ "᾿","͂" }, - ["ῐ"]={ "ι","̆" }, - ["ῑ"]={ "ι","̄" }, - ["ῒ"]={ "ϊ","̀" }, - ["ῖ"]={ "ι","͂" }, - ["ῗ"]={ "ϊ","͂" }, - ["Ῐ"]={ "Ι","̆" }, - ["Ῑ"]={ "Ι","̄" }, - ["Ὶ"]={ "Ι","̀" }, - ["῝"]={ "῾","̀" }, - ["῞"]={ "῾","́" }, - ["῟"]={ "῾","͂" }, - ["ῠ"]={ "υ","̆" }, - ["ῡ"]={ "υ","̄" }, - ["ῢ"]={ "ϋ","̀" }, - ["ῤ"]={ "ρ","̓" }, - ["ῥ"]={ "ρ","̔" }, - ["ῦ"]={ "υ","͂" }, - ["ῧ"]={ "ϋ","͂" }, - ["Ῠ"]={ "Υ","̆" }, - ["Ῡ"]={ "Υ","̄" }, - ["Ὺ"]={ "Υ","̀" }, - ["Ῥ"]={ "Ρ","̔" }, - ["῭"]={ "¨","̀" }, - ["ῲ"]={ "ὼ","ͅ" }, - ["ῳ"]={ "ω","ͅ" }, - ["ῴ"]={ "ώ","ͅ" }, - ["ῶ"]={ "ω","͂" }, - ["ῷ"]={ "ῶ","ͅ" }, - ["Ὸ"]={ "Ο","̀" }, - ["Ὼ"]={ "Ω","̀" }, - ["ῼ"]={ "Ω","ͅ" }, - ["↚"]={ "←","̸" }, - ["↛"]={ "→","̸" }, - ["↮"]={ "↔","̸" }, - ["⇍"]={ "⇐","̸" }, - ["⇎"]={ "⇔","̸" }, - ["⇏"]={ "⇒","̸" }, - ["∄"]={ "∃","̸" }, - ["∉"]={ "∈","̸" }, - ["∌"]={ "∋","̸" }, - ["∤"]={ "∣","̸" }, - ["∦"]={ "∥","̸" }, - ["≁"]={ "∼","̸" }, - ["≄"]={ "≃","̸" }, - ["≇"]={ "≅","̸" }, - ["≉"]={ "≈","̸" }, - ["≠"]={ "=","̸" }, - ["≢"]={ "≡","̸" }, - ["≭"]={ "≍","̸" }, - ["≮"]={ "<","̸" }, - ["≯"]={ ">","̸" }, - ["≰"]={ "≤","̸" }, - ["≱"]={ "≥","̸" }, - ["≴"]={ "≲","̸" }, - ["≵"]={ "≳","̸" }, - ["≸"]={ "≶","̸" }, - ["≹"]={ "≷","̸" }, - ["⊀"]={ "≺","̸" }, - ["⊁"]={ "≻","̸" }, - ["⊄"]={ "⊂","̸" }, - ["⊅"]={ "⊃","̸" }, - ["⊈"]={ "⊆","̸" }, - ["⊉"]={ "⊇","̸" }, - ["⊬"]={ "⊢","̸" }, - ["⊭"]={ "⊨","̸" }, - ["⊮"]={ "⊩","̸" }, - ["⊯"]={ "⊫","̸" }, - ["⋠"]={ "≼","̸" }, - ["⋡"]={ "≽","̸" }, - ["⋢"]={ "⊑","̸" }, - ["⋣"]={ "⊒","̸" }, - ["⋪"]={ "⊲","̸" }, - ["⋫"]={ "⊳","̸" }, - ["⋬"]={ "⊴","̸" }, - ["⋭"]={ "⊵","̸" }, - ["⫝̸"]={ "⫝","̸" }, - ["が"]={ "か","゙" }, - ["ぎ"]={ "き","゙" }, - ["ぐ"]={ "く","゙" }, - ["げ"]={ "け","゙" }, - ["ご"]={ "こ","゙" }, - ["ざ"]={ "さ","゙" }, - ["じ"]={ "し","゙" }, - ["ず"]={ "す","゙" }, - ["ぜ"]={ "せ","゙" }, - ["ぞ"]={ "そ","゙" }, - ["だ"]={ "た","゙" }, - ["ぢ"]={ "ち","゙" }, - ["づ"]={ "つ","゙" }, - ["で"]={ "て","゙" }, - ["ど"]={ "と","゙" }, - ["ば"]={ "は","゙" }, - ["ぱ"]={ "は","゚" }, - ["び"]={ "ひ","゙" }, - ["ぴ"]={ "ひ","゚" }, - ["ぶ"]={ "ふ","゙" }, - ["ぷ"]={ "ふ","゚" }, - ["べ"]={ "へ","゙" }, - ["ぺ"]={ "へ","゚" }, - ["ぼ"]={ "ほ","゙" }, - ["ぽ"]={ "ほ","゚" }, - ["ゔ"]={ "う","゙" }, - ["ゞ"]={ "ゝ","゙" }, - ["ガ"]={ "カ","゙" }, - ["ギ"]={ "キ","゙" }, - ["グ"]={ "ク","゙" }, - ["ゲ"]={ "ケ","゙" }, - ["ゴ"]={ "コ","゙" }, - ["ザ"]={ "サ","゙" }, - ["ジ"]={ "シ","゙" }, - ["ズ"]={ "ス","゙" }, - ["ゼ"]={ "セ","゙" }, - ["ゾ"]={ "ソ","゙" }, - ["ダ"]={ "タ","゙" }, - ["ヂ"]={ "チ","゙" }, - ["ヅ"]={ "ツ","゙" }, - ["デ"]={ "テ","゙" }, - ["ド"]={ "ト","゙" }, - ["バ"]={ "ハ","゙" }, - ["パ"]={ "ハ","゚" }, - ["ビ"]={ "ヒ","゙" }, - ["ピ"]={ "ヒ","゚" }, - ["ブ"]={ "フ","゙" }, - ["プ"]={ "フ","゚" }, - ["ベ"]={ "ヘ","゙" }, - ["ペ"]={ "ヘ","゚" }, - ["ボ"]={ "ホ","゙" }, - ["ポ"]={ "ホ","゚" }, - ["ヴ"]={ "ウ","゙" }, - ["ヷ"]={ "ワ","゙" }, - ["ヸ"]={ "ヰ","゙" }, - ["ヹ"]={ "ヱ","゙" }, - ["ヺ"]={ "ヲ","゙" }, - ["ヾ"]={ "ヽ","゙" }, - ["יִ"]={ "י","ִ" }, - ["ײַ"]={ "ײ","ַ" }, - ["שׁ"]={ "ש","ׁ" }, - ["שׂ"]={ "ש","ׂ" }, - ["שּׁ"]={ "שּ","ׁ" }, - ["שּׂ"]={ "שּ","ׂ" }, - ["אַ"]={ "א","ַ" }, - ["אָ"]={ "א","ָ" }, - ["אּ"]={ "א","ּ" }, - ["בּ"]={ "ב","ּ" }, - ["גּ"]={ "ג","ּ" }, - ["דּ"]={ "ד","ּ" }, - ["הּ"]={ "ה","ּ" }, - ["וּ"]={ "ו","ּ" }, - ["זּ"]={ "ז","ּ" }, - ["טּ"]={ "ט","ּ" }, - ["יּ"]={ "י","ּ" }, - ["ךּ"]={ "ך","ּ" }, - ["כּ"]={ "כ","ּ" }, - ["לּ"]={ "ל","ּ" }, - ["מּ"]={ "מ","ּ" }, - ["נּ"]={ "נ","ּ" }, - ["סּ"]={ "ס","ּ" }, - ["ףּ"]={ "ף","ּ" }, - ["פּ"]={ "פ","ּ" }, - ["צּ"]={ "צ","ּ" }, - ["קּ"]={ "ק","ּ" }, - ["רּ"]={ "ר","ּ" }, - ["שּ"]={ "ש","ּ" }, - ["תּ"]={ "ת","ּ" }, - ["וֹ"]={ "ו","ֹ" }, - ["בֿ"]={ "ב","ֿ" }, - ["כֿ"]={ "כ","ֿ" }, - ["פֿ"]={ "פ","ֿ" }, - ["𑂚"]={ "𑂙","𑂺" }, - ["𑂜"]={ "𑂛","𑂺" }, - ["𑂫"]={ "𑂥","𑂺" }, - ["𑄮"]={ "𑄱","𑄧" }, - ["𑄯"]={ "𑄲","𑄧" }, - ["𑍋"]={ "𑍇","𑌾" }, - ["𑍌"]={ "𑍇","𑍗" }, - ["𑒻"]={ "𑒹","𑒺" }, - ["𑒼"]={ "𑒹","𑒰" }, - ["𑒾"]={ "𑒹","𑒽" }, - ["𑖺"]={ "𑖸","𑖯" }, - ["𑖻"]={ "𑖹","𑖯" }, - ["𝅗𝅥"]={ "𝅗","𝅥" }, - ["𝅘𝅥"]={ "𝅘","𝅥" }, - ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, - ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, - ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, - ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, - ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, - ["𝆹𝅥"]={ "𝆹","𝅥" }, - ["𝆺𝅥"]={ "𝆺","𝅥" }, - ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, - ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, - ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, - ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, }, - }, - { - ["data"]={ - ["À"]={ "A","̀" }, - ["Á"]={ "A","́" }, - ["Â"]={ "A","̂" }, - ["Ã"]={ "A","̃" }, - ["Ä"]={ "A","̈" }, - ["Å"]={ "A","̊" }, - ["Ç"]={ "C","̧" }, - ["È"]={ "E","̀" }, - ["É"]={ "E","́" }, - ["Ê"]={ "E","̂" }, - ["Ë"]={ "E","̈" }, - ["Ì"]={ "I","̀" }, - ["Í"]={ "I","́" }, - ["Î"]={ "I","̂" }, - ["Ï"]={ "I","̈" }, - ["Ñ"]={ "N","̃" }, - ["Ò"]={ "O","̀" }, - ["Ó"]={ "O","́" }, - ["Ô"]={ "O","̂" }, - ["Õ"]={ "O","̃" }, - ["Ö"]={ "O","̈" }, - ["Ù"]={ "U","̀" }, - ["Ú"]={ "U","́" }, - ["Û"]={ "U","̂" }, - ["Ü"]={ "U","̈" }, - ["Ý"]={ "Y","́" }, - ["à"]={ "a","̀" }, - ["á"]={ "a","́" }, - ["â"]={ "a","̂" }, - ["ã"]={ "a","̃" }, - ["ä"]={ "a","̈" }, - ["å"]={ "a","̊" }, - ["ç"]={ "c","̧" }, - ["è"]={ "e","̀" }, - ["é"]={ "e","́" }, - ["ê"]={ "e","̂" }, - ["ë"]={ "e","̈" }, - ["ì"]={ "i","̀" }, - ["í"]={ "i","́" }, - ["î"]={ "i","̂" }, - ["ï"]={ "i","̈" }, - ["ñ"]={ "n","̃" }, - ["ò"]={ "o","̀" }, - ["ó"]={ "o","́" }, - ["ô"]={ "o","̂" }, - ["õ"]={ "o","̃" }, - ["ö"]={ "o","̈" }, - ["ù"]={ "u","̀" }, - ["ú"]={ "u","́" }, - ["û"]={ "u","̂" }, - ["ü"]={ "u","̈" }, - ["ý"]={ "y","́" }, - ["ÿ"]={ "y","̈" }, - ["Ā"]={ "A","̄" }, - ["ā"]={ "a","̄" }, - ["Ă"]={ "A","̆" }, - ["ă"]={ "a","̆" }, - ["Ą"]={ "A","̨" }, - ["ą"]={ "a","̨" }, - ["Ć"]={ "C","́" }, - ["ć"]={ "c","́" }, - ["Ĉ"]={ "C","̂" }, - ["ĉ"]={ "c","̂" }, - ["Ċ"]={ "C","̇" }, - ["ċ"]={ "c","̇" }, - ["Č"]={ "C","̌" }, - ["č"]={ "c","̌" }, - ["Ď"]={ "D","̌" }, - ["ď"]={ "d","̌" }, - ["Ē"]={ "E","̄" }, - ["ē"]={ "e","̄" }, - ["Ĕ"]={ "E","̆" }, - ["ĕ"]={ "e","̆" }, - ["Ė"]={ "E","̇" }, - ["ė"]={ "e","̇" }, - ["Ę"]={ "E","̨" }, - ["ę"]={ "e","̨" }, - ["Ě"]={ "E","̌" }, - ["ě"]={ "e","̌" }, - ["Ĝ"]={ "G","̂" }, - ["ĝ"]={ "g","̂" }, - ["Ğ"]={ "G","̆" }, - ["ğ"]={ "g","̆" }, - ["Ġ"]={ "G","̇" }, - ["ġ"]={ "g","̇" }, - ["Ģ"]={ "G","̧" }, - ["ģ"]={ "g","̧" }, - ["Ĥ"]={ "H","̂" }, - ["ĥ"]={ "h","̂" }, - ["Ĩ"]={ "I","̃" }, - ["ĩ"]={ "i","̃" }, - ["Ī"]={ "I","̄" }, - ["ī"]={ "i","̄" }, - ["Ĭ"]={ "I","̆" }, - ["ĭ"]={ "i","̆" }, - ["Į"]={ "I","̨" }, - ["į"]={ "i","̨" }, - ["İ"]={ "I","̇" }, - ["Ĵ"]={ "J","̂" }, - ["ĵ"]={ "j","̂" }, - ["Ķ"]={ "K","̧" }, - ["ķ"]={ "k","̧" }, - ["Ĺ"]={ "L","́" }, - ["ĺ"]={ "l","́" }, - ["Ļ"]={ "L","̧" }, - ["ļ"]={ "l","̧" }, - ["Ľ"]={ "L","̌" }, - ["ľ"]={ "l","̌" }, - ["Ń"]={ "N","́" }, - ["ń"]={ "n","́" }, - ["Ņ"]={ "N","̧" }, - ["ņ"]={ "n","̧" }, - ["Ň"]={ "N","̌" }, - ["ň"]={ "n","̌" }, - ["Ō"]={ "O","̄" }, - ["ō"]={ "o","̄" }, - ["Ŏ"]={ "O","̆" }, - ["ŏ"]={ "o","̆" }, - ["Ő"]={ "O","̋" }, - ["ő"]={ "o","̋" }, - ["Ŕ"]={ "R","́" }, - ["ŕ"]={ "r","́" }, - ["Ŗ"]={ "R","̧" }, - ["ŗ"]={ "r","̧" }, - ["Ř"]={ "R","̌" }, - ["ř"]={ "r","̌" }, - ["Ś"]={ "S","́" }, - ["ś"]={ "s","́" }, - ["Ŝ"]={ "S","̂" }, - ["ŝ"]={ "s","̂" }, - ["Ş"]={ "S","̧" }, - ["ş"]={ "s","̧" }, - ["Š"]={ "S","̌" }, - ["š"]={ "s","̌" }, - ["Ţ"]={ "T","̧" }, - ["ţ"]={ "t","̧" }, - ["Ť"]={ "T","̌" }, - ["ť"]={ "t","̌" }, - ["Ũ"]={ "U","̃" }, - ["ũ"]={ "u","̃" }, - ["Ū"]={ "U","̄" }, - ["ū"]={ "u","̄" }, - ["Ŭ"]={ "U","̆" }, - ["ŭ"]={ "u","̆" }, - ["Ů"]={ "U","̊" }, - ["ů"]={ "u","̊" }, - ["Ű"]={ "U","̋" }, - ["ű"]={ "u","̋" }, - ["Ų"]={ "U","̨" }, - ["ų"]={ "u","̨" }, - ["Ŵ"]={ "W","̂" }, - ["ŵ"]={ "w","̂" }, - ["Ŷ"]={ "Y","̂" }, - ["ŷ"]={ "y","̂" }, - ["Ÿ"]={ "Y","̈" }, - ["Ź"]={ "Z","́" }, - ["ź"]={ "z","́" }, - ["Ż"]={ "Z","̇" }, - ["ż"]={ "z","̇" }, - ["Ž"]={ "Z","̌" }, - ["ž"]={ "z","̌" }, - ["Ơ"]={ "O","̛" }, - ["ơ"]={ "o","̛" }, - ["Ư"]={ "U","̛" }, - ["ư"]={ "u","̛" }, - ["Ǎ"]={ "A","̌" }, - ["ǎ"]={ "a","̌" }, - ["Ǐ"]={ "I","̌" }, - ["ǐ"]={ "i","̌" }, - ["Ǒ"]={ "O","̌" }, - ["ǒ"]={ "o","̌" }, - ["Ǔ"]={ "U","̌" }, - ["ǔ"]={ "u","̌" }, - ["Ǖ"]={ "Ü","̄" }, - ["ǖ"]={ "ü","̄" }, - ["Ǘ"]={ "Ü","́" }, - ["ǘ"]={ "ü","́" }, - ["Ǚ"]={ "Ü","̌" }, - ["ǚ"]={ "ü","̌" }, - ["Ǜ"]={ "Ü","̀" }, - ["ǜ"]={ "ü","̀" }, - ["Ǟ"]={ "Ä","̄" }, - ["ǟ"]={ "ä","̄" }, - ["Ǡ"]={ "Ȧ","̄" }, - ["ǡ"]={ "ȧ","̄" }, - ["Ǣ"]={ "Æ","̄" }, - ["ǣ"]={ "æ","̄" }, - ["Ǧ"]={ "G","̌" }, - ["ǧ"]={ "g","̌" }, - ["Ǩ"]={ "K","̌" }, - ["ǩ"]={ "k","̌" }, - ["Ǫ"]={ "O","̨" }, - ["ǫ"]={ "o","̨" }, - ["Ǭ"]={ "Ǫ","̄" }, - ["ǭ"]={ "ǫ","̄" }, - ["Ǯ"]={ "Ʒ","̌" }, - ["ǯ"]={ "ʒ","̌" }, - ["ǰ"]={ "j","̌" }, - ["Ǵ"]={ "G","́" }, - ["ǵ"]={ "g","́" }, - ["Ǹ"]={ "N","̀" }, - ["ǹ"]={ "n","̀" }, - ["Ǻ"]={ "Å","́" }, - ["ǻ"]={ "å","́" }, - ["Ǽ"]={ "Æ","́" }, - ["ǽ"]={ "æ","́" }, - ["Ǿ"]={ "Ø","́" }, - ["ǿ"]={ "ø","́" }, - ["Ȁ"]={ "A","̏" }, - ["ȁ"]={ "a","̏" }, - ["Ȃ"]={ "A","̑" }, - ["ȃ"]={ "a","̑" }, - ["Ȅ"]={ "E","̏" }, - ["ȅ"]={ "e","̏" }, - ["Ȇ"]={ "E","̑" }, - ["ȇ"]={ "e","̑" }, - ["Ȉ"]={ "I","̏" }, - ["ȉ"]={ "i","̏" }, - ["Ȋ"]={ "I","̑" }, - ["ȋ"]={ "i","̑" }, - ["Ȍ"]={ "O","̏" }, - ["ȍ"]={ "o","̏" }, - ["Ȏ"]={ "O","̑" }, - ["ȏ"]={ "o","̑" }, - ["Ȑ"]={ "R","̏" }, - ["ȑ"]={ "r","̏" }, - ["Ȓ"]={ "R","̑" }, - ["ȓ"]={ "r","̑" }, - ["Ȕ"]={ "U","̏" }, - ["ȕ"]={ "u","̏" }, - ["Ȗ"]={ "U","̑" }, - ["ȗ"]={ "u","̑" }, - ["Ș"]={ "S","̦" }, - ["ș"]={ "s","̦" }, - ["Ț"]={ "T","̦" }, - ["ț"]={ "t","̦" }, - ["Ȟ"]={ "H","̌" }, - ["ȟ"]={ "h","̌" }, - ["Ȧ"]={ "A","̇" }, - ["ȧ"]={ "a","̇" }, - ["Ȩ"]={ "E","̧" }, - ["ȩ"]={ "e","̧" }, - ["Ȫ"]={ "Ö","̄" }, - ["ȫ"]={ "ö","̄" }, - ["Ȭ"]={ "Õ","̄" }, - ["ȭ"]={ "õ","̄" }, - ["Ȯ"]={ "O","̇" }, - ["ȯ"]={ "o","̇" }, - ["Ȱ"]={ "Ȯ","̄" }, - ["ȱ"]={ "ȯ","̄" }, - ["Ȳ"]={ "Y","̄" }, - ["ȳ"]={ "y","̄" }, - ["̈́"]={ "̈","́" }, - ["΅"]={ "¨","́" }, - ["Ά"]={ "Α","́" }, - ["Έ"]={ "Ε","́" }, - ["Ή"]={ "Η","́" }, - ["Ί"]={ "Ι","́" }, - ["Ό"]={ "Ο","́" }, - ["Ύ"]={ "Υ","́" }, - ["Ώ"]={ "Ω","́" }, - ["ΐ"]={ "ϊ","́" }, - ["Ϊ"]={ "Ι","̈" }, - ["Ϋ"]={ "Υ","̈" }, - ["ά"]={ "α","́" }, - ["έ"]={ "ε","́" }, - ["ή"]={ "η","́" }, - ["ί"]={ "ι","́" }, - ["ΰ"]={ "ϋ","́" }, - ["ϊ"]={ "ι","̈" }, - ["ϋ"]={ "υ","̈" }, - ["ό"]={ "ο","́" }, - ["ύ"]={ "υ","́" }, - ["ώ"]={ "ω","́" }, - ["ϓ"]={ "ϒ","́" }, - ["ϔ"]={ "ϒ","̈" }, - ["Ѐ"]={ "Е","̀" }, - ["Ё"]={ "Е","̈" }, - ["Ѓ"]={ "Г","́" }, - ["Ї"]={ "І","̈" }, - ["Ќ"]={ "К","́" }, - ["Ѝ"]={ "И","̀" }, - ["Ў"]={ "У","̆" }, - ["Й"]={ "И","̆" }, - ["й"]={ "и","̆" }, - ["ѐ"]={ "е","̀" }, - ["ё"]={ "е","̈" }, - ["ѓ"]={ "г","́" }, - ["ї"]={ "і","̈" }, - ["ќ"]={ "к","́" }, - ["ѝ"]={ "и","̀" }, - ["ў"]={ "у","̆" }, - ["Ѷ"]={ "Ѵ","̏" }, - ["ѷ"]={ "ѵ","̏" }, - ["Ӂ"]={ "Ж","̆" }, - ["ӂ"]={ "ж","̆" }, - ["Ӑ"]={ "А","̆" }, - ["ӑ"]={ "а","̆" }, - ["Ӓ"]={ "А","̈" }, - ["ӓ"]={ "а","̈" }, - ["Ӗ"]={ "Е","̆" }, - ["ӗ"]={ "е","̆" }, - ["Ӛ"]={ "Ә","̈" }, - ["ӛ"]={ "ә","̈" }, - ["Ӝ"]={ "Ж","̈" }, - ["ӝ"]={ "ж","̈" }, - ["Ӟ"]={ "З","̈" }, - ["ӟ"]={ "з","̈" }, - ["Ӣ"]={ "И","̄" }, - ["ӣ"]={ "и","̄" }, - ["Ӥ"]={ "И","̈" }, - ["ӥ"]={ "и","̈" }, - ["Ӧ"]={ "О","̈" }, - ["ӧ"]={ "о","̈" }, - ["Ӫ"]={ "Ө","̈" }, - ["ӫ"]={ "ө","̈" }, - ["Ӭ"]={ "Э","̈" }, - ["ӭ"]={ "э","̈" }, - ["Ӯ"]={ "У","̄" }, - ["ӯ"]={ "у","̄" }, - ["Ӱ"]={ "У","̈" }, - ["ӱ"]={ "у","̈" }, - ["Ӳ"]={ "У","̋" }, - ["ӳ"]={ "у","̋" }, - ["Ӵ"]={ "Ч","̈" }, - ["ӵ"]={ "ч","̈" }, - ["Ӹ"]={ "Ы","̈" }, - ["ӹ"]={ "ы","̈" }, - ["آ"]={ "ا","ٓ" }, - ["أ"]={ "ا","ٔ" }, - ["ؤ"]={ "و","ٔ" }, - ["إ"]={ "ا","ٕ" }, - ["ئ"]={ "ي","ٔ" }, - ["ۀ"]={ "ە","ٔ" }, - ["ۂ"]={ "ہ","ٔ" }, - ["ۓ"]={ "ے","ٔ" }, - ["ऩ"]={ "न","़" }, - ["ऱ"]={ "र","़" }, - ["ऴ"]={ "ळ","़" }, - ["क़"]={ "क","़" }, - ["ख़"]={ "ख","़" }, - ["ग़"]={ "ग","़" }, - ["ज़"]={ "ज","़" }, - ["ड़"]={ "ड","़" }, - ["ढ़"]={ "ढ","़" }, - ["फ़"]={ "फ","़" }, - ["य़"]={ "य","़" }, - ["ো"]={ "ে","া" }, - ["ৌ"]={ "ে","ৗ" }, - ["ড়"]={ "ড","়" }, - ["ঢ়"]={ "ঢ","়" }, - ["য়"]={ "য","়" }, - ["ਲ਼"]={ "ਲ","਼" }, - ["ਸ਼"]={ "ਸ","਼" }, - ["ਖ਼"]={ "ਖ","਼" }, - ["ਗ਼"]={ "ਗ","਼" }, - ["ਜ਼"]={ "ਜ","਼" }, - ["ਫ਼"]={ "ਫ","਼" }, - ["ୈ"]={ "େ","ୖ" }, - ["ୋ"]={ "େ","ା" }, - ["ୌ"]={ "େ","ୗ" }, - ["ଡ଼"]={ "ଡ","଼" }, - ["ଢ଼"]={ "ଢ","଼" }, - ["ஔ"]={ "ஒ","ௗ" }, - ["ொ"]={ "ெ","ா" }, - ["ோ"]={ "ே","ா" }, - ["ௌ"]={ "ெ","ௗ" }, - ["ై"]={ "ె","ౖ" }, - ["ೀ"]={ "ಿ","ೕ" }, - ["ೇ"]={ "ೆ","ೕ" }, - ["ೈ"]={ "ೆ","ೖ" }, - ["ೊ"]={ "ೆ","ೂ" }, - ["ೋ"]={ "ೊ","ೕ" }, - ["ൊ"]={ "െ","ാ" }, - ["ോ"]={ "േ","ാ" }, - ["ൌ"]={ "െ","ൗ" }, - ["ේ"]={ "ෙ","්" }, - ["ො"]={ "ෙ","ා" }, - ["ෝ"]={ "ො","්" }, - ["ෞ"]={ "ෙ","ෟ" }, - ["གྷ"]={ "ག","ྷ" }, - ["ཌྷ"]={ "ཌ","ྷ" }, - ["དྷ"]={ "ད","ྷ" }, - ["བྷ"]={ "བ","ྷ" }, - ["ཛྷ"]={ "ཛ","ྷ" }, - ["ཀྵ"]={ "ཀ","ྵ" }, - ["ཱི"]={ "ཱ","ི" }, - ["ཱུ"]={ "ཱ","ུ" }, - ["ྲྀ"]={ "ྲ","ྀ" }, - ["ླྀ"]={ "ླ","ྀ" }, - ["ཱྀ"]={ "ཱ","ྀ" }, - ["ྒྷ"]={ "ྒ","ྷ" }, - ["ྜྷ"]={ "ྜ","ྷ" }, - ["ྡྷ"]={ "ྡ","ྷ" }, - ["ྦྷ"]={ "ྦ","ྷ" }, - ["ྫྷ"]={ "ྫ","ྷ" }, - ["ྐྵ"]={ "ྐ","ྵ" }, - ["ဦ"]={ "ဥ","ီ" }, - ["ᬆ"]={ "ᬅ","ᬵ" }, - ["ᬈ"]={ "ᬇ","ᬵ" }, - ["ᬊ"]={ "ᬉ","ᬵ" }, - ["ᬌ"]={ "ᬋ","ᬵ" }, - ["ᬎ"]={ "ᬍ","ᬵ" }, - ["ᬒ"]={ "ᬑ","ᬵ" }, - ["ᬻ"]={ "ᬺ","ᬵ" }, - ["ᬽ"]={ "ᬼ","ᬵ" }, - ["ᭀ"]={ "ᬾ","ᬵ" }, - ["ᭁ"]={ "ᬿ","ᬵ" }, - ["ᭃ"]={ "ᭂ","ᬵ" }, - ["Ḁ"]={ "A","̥" }, - ["ḁ"]={ "a","̥" }, - ["Ḃ"]={ "B","̇" }, - ["ḃ"]={ "b","̇" }, - ["Ḅ"]={ "B","̣" }, - ["ḅ"]={ "b","̣" }, - ["Ḇ"]={ "B","̱" }, - ["ḇ"]={ "b","̱" }, - ["Ḉ"]={ "Ç","́" }, - ["ḉ"]={ "ç","́" }, - ["Ḋ"]={ "D","̇" }, - ["ḋ"]={ "d","̇" }, - ["Ḍ"]={ "D","̣" }, - ["ḍ"]={ "d","̣" }, - ["Ḏ"]={ "D","̱" }, - ["ḏ"]={ "d","̱" }, - ["Ḑ"]={ "D","̧" }, - ["ḑ"]={ "d","̧" }, - ["Ḓ"]={ "D","̭" }, - ["ḓ"]={ "d","̭" }, - ["Ḕ"]={ "Ē","̀" }, - ["ḕ"]={ "ē","̀" }, - ["Ḗ"]={ "Ē","́" }, - ["ḗ"]={ "ē","́" }, - ["Ḙ"]={ "E","̭" }, - ["ḙ"]={ "e","̭" }, - ["Ḛ"]={ "E","̰" }, - ["ḛ"]={ "e","̰" }, - ["Ḝ"]={ "Ȩ","̆" }, - ["ḝ"]={ "ȩ","̆" }, - ["Ḟ"]={ "F","̇" }, - ["ḟ"]={ "f","̇" }, - ["Ḡ"]={ "G","̄" }, - ["ḡ"]={ "g","̄" }, - ["Ḣ"]={ "H","̇" }, - ["ḣ"]={ "h","̇" }, - ["Ḥ"]={ "H","̣" }, - ["ḥ"]={ "h","̣" }, - ["Ḧ"]={ "H","̈" }, - ["ḧ"]={ "h","̈" }, - ["Ḩ"]={ "H","̧" }, - ["ḩ"]={ "h","̧" }, - ["Ḫ"]={ "H","̮" }, - ["ḫ"]={ "h","̮" }, - ["Ḭ"]={ "I","̰" }, - ["ḭ"]={ "i","̰" }, - ["Ḯ"]={ "Ï","́" }, - ["ḯ"]={ "ï","́" }, - ["Ḱ"]={ "K","́" }, - ["ḱ"]={ "k","́" }, - ["Ḳ"]={ "K","̣" }, - ["ḳ"]={ "k","̣" }, - ["Ḵ"]={ "K","̱" }, - ["ḵ"]={ "k","̱" }, - ["Ḷ"]={ "L","̣" }, - ["ḷ"]={ "l","̣" }, - ["Ḹ"]={ "Ḷ","̄" }, - ["ḹ"]={ "ḷ","̄" }, - ["Ḻ"]={ "L","̱" }, - ["ḻ"]={ "l","̱" }, - ["Ḽ"]={ "L","̭" }, - ["ḽ"]={ "l","̭" }, - ["Ḿ"]={ "M","́" }, - ["ḿ"]={ "m","́" }, - ["Ṁ"]={ "M","̇" }, - ["ṁ"]={ "m","̇" }, - ["Ṃ"]={ "M","̣" }, - ["ṃ"]={ "m","̣" }, - ["Ṅ"]={ "N","̇" }, - ["ṅ"]={ "n","̇" }, - ["Ṇ"]={ "N","̣" }, - ["ṇ"]={ "n","̣" }, - ["Ṉ"]={ "N","̱" }, - ["ṉ"]={ "n","̱" }, - ["Ṋ"]={ "N","̭" }, - ["ṋ"]={ "n","̭" }, - ["Ṍ"]={ "Õ","́" }, - ["ṍ"]={ "õ","́" }, - ["Ṏ"]={ "Õ","̈" }, - ["ṏ"]={ "õ","̈" }, - ["Ṑ"]={ "Ō","̀" }, - ["ṑ"]={ "ō","̀" }, - ["Ṓ"]={ "Ō","́" }, - ["ṓ"]={ "ō","́" }, - ["Ṕ"]={ "P","́" }, - ["ṕ"]={ "p","́" }, - ["Ṗ"]={ "P","̇" }, - ["ṗ"]={ "p","̇" }, - ["Ṙ"]={ "R","̇" }, - ["ṙ"]={ "r","̇" }, - ["Ṛ"]={ "R","̣" }, - ["ṛ"]={ "r","̣" }, - ["Ṝ"]={ "Ṛ","̄" }, - ["ṝ"]={ "ṛ","̄" }, - ["Ṟ"]={ "R","̱" }, - ["ṟ"]={ "r","̱" }, - ["Ṡ"]={ "S","̇" }, - ["ṡ"]={ "s","̇" }, - ["Ṣ"]={ "S","̣" }, - ["ṣ"]={ "s","̣" }, - ["Ṥ"]={ "Ś","̇" }, - ["ṥ"]={ "ś","̇" }, - ["Ṧ"]={ "Š","̇" }, - ["ṧ"]={ "š","̇" }, - ["Ṩ"]={ "Ṣ","̇" }, - ["ṩ"]={ "ṣ","̇" }, - ["Ṫ"]={ "T","̇" }, - ["ṫ"]={ "t","̇" }, - ["Ṭ"]={ "T","̣" }, - ["ṭ"]={ "t","̣" }, - ["Ṯ"]={ "T","̱" }, - ["ṯ"]={ "t","̱" }, - ["Ṱ"]={ "T","̭" }, - ["ṱ"]={ "t","̭" }, - ["Ṳ"]={ "U","̤" }, - ["ṳ"]={ "u","̤" }, - ["Ṵ"]={ "U","̰" }, - ["ṵ"]={ "u","̰" }, - ["Ṷ"]={ "U","̭" }, - ["ṷ"]={ "u","̭" }, - ["Ṹ"]={ "Ũ","́" }, - ["ṹ"]={ "ũ","́" }, - ["Ṻ"]={ "Ū","̈" }, - ["ṻ"]={ "ū","̈" }, - ["Ṽ"]={ "V","̃" }, - ["ṽ"]={ "v","̃" }, - ["Ṿ"]={ "V","̣" }, - ["ṿ"]={ "v","̣" }, - ["Ẁ"]={ "W","̀" }, - ["ẁ"]={ "w","̀" }, - ["Ẃ"]={ "W","́" }, - ["ẃ"]={ "w","́" }, - ["Ẅ"]={ "W","̈" }, - ["ẅ"]={ "w","̈" }, - ["Ẇ"]={ "W","̇" }, - ["ẇ"]={ "w","̇" }, - ["Ẉ"]={ "W","̣" }, - ["ẉ"]={ "w","̣" }, - ["Ẋ"]={ "X","̇" }, - ["ẋ"]={ "x","̇" }, - ["Ẍ"]={ "X","̈" }, - ["ẍ"]={ "x","̈" }, - ["Ẏ"]={ "Y","̇" }, - ["ẏ"]={ "y","̇" }, - ["Ẑ"]={ "Z","̂" }, - ["ẑ"]={ "z","̂" }, - ["Ẓ"]={ "Z","̣" }, - ["ẓ"]={ "z","̣" }, - ["Ẕ"]={ "Z","̱" }, - ["ẕ"]={ "z","̱" }, - ["ẖ"]={ "h","̱" }, - ["ẗ"]={ "t","̈" }, - ["ẘ"]={ "w","̊" }, - ["ẙ"]={ "y","̊" }, - ["ẛ"]={ "ſ","̇" }, - ["Ạ"]={ "A","̣" }, - ["ạ"]={ "a","̣" }, - ["Ả"]={ "A","̉" }, - ["ả"]={ "a","̉" }, - ["Ấ"]={ "Â","́" }, - ["ấ"]={ "â","́" }, - ["Ầ"]={ "Â","̀" }, - ["ầ"]={ "â","̀" }, - ["Ẩ"]={ "Â","̉" }, - ["ẩ"]={ "â","̉" }, - ["Ẫ"]={ "Â","̃" }, - ["ẫ"]={ "â","̃" }, - ["Ậ"]={ "Ạ","̂" }, - ["ậ"]={ "ạ","̂" }, - ["Ắ"]={ "Ă","́" }, - ["ắ"]={ "ă","́" }, - ["Ằ"]={ "Ă","̀" }, - ["ằ"]={ "ă","̀" }, - ["Ẳ"]={ "Ă","̉" }, - ["ẳ"]={ "ă","̉" }, - ["Ẵ"]={ "Ă","̃" }, - ["ẵ"]={ "ă","̃" }, - ["Ặ"]={ "Ạ","̆" }, - ["ặ"]={ "ạ","̆" }, - ["Ẹ"]={ "E","̣" }, - ["ẹ"]={ "e","̣" }, - ["Ẻ"]={ "E","̉" }, - ["ẻ"]={ "e","̉" }, - ["Ẽ"]={ "E","̃" }, - ["ẽ"]={ "e","̃" }, - ["Ế"]={ "Ê","́" }, - ["ế"]={ "ê","́" }, - ["Ề"]={ "Ê","̀" }, - ["ề"]={ "ê","̀" }, - ["Ể"]={ "Ê","̉" }, - ["ể"]={ "ê","̉" }, - ["Ễ"]={ "Ê","̃" }, - ["ễ"]={ "ê","̃" }, - ["Ệ"]={ "Ẹ","̂" }, - ["ệ"]={ "ẹ","̂" }, - ["Ỉ"]={ "I","̉" }, - ["ỉ"]={ "i","̉" }, - ["Ị"]={ "I","̣" }, - ["ị"]={ "i","̣" }, - ["Ọ"]={ "O","̣" }, - ["ọ"]={ "o","̣" }, - ["Ỏ"]={ "O","̉" }, - ["ỏ"]={ "o","̉" }, - ["Ố"]={ "Ô","́" }, - ["ố"]={ "ô","́" }, - ["Ồ"]={ "Ô","̀" }, - ["ồ"]={ "ô","̀" }, - ["Ổ"]={ "Ô","̉" }, - ["ổ"]={ "ô","̉" }, - ["Ỗ"]={ "Ô","̃" }, - ["ỗ"]={ "ô","̃" }, - ["Ộ"]={ "Ọ","̂" }, - ["ộ"]={ "ọ","̂" }, - ["Ớ"]={ "Ơ","́" }, - ["ớ"]={ "ơ","́" }, - ["Ờ"]={ "Ơ","̀" }, - ["ờ"]={ "ơ","̀" }, - ["Ở"]={ "Ơ","̉" }, - ["ở"]={ "ơ","̉" }, - ["Ỡ"]={ "Ơ","̃" }, - ["ỡ"]={ "ơ","̃" }, - ["Ợ"]={ "Ơ","̣" }, - ["ợ"]={ "ơ","̣" }, - ["Ụ"]={ "U","̣" }, - ["ụ"]={ "u","̣" }, - ["Ủ"]={ "U","̉" }, - ["ủ"]={ "u","̉" }, - ["Ứ"]={ "Ư","́" }, - ["ứ"]={ "ư","́" }, - ["Ừ"]={ "Ư","̀" }, - ["ừ"]={ "ư","̀" }, - ["Ử"]={ "Ư","̉" }, - ["ử"]={ "ư","̉" }, - ["Ữ"]={ "Ư","̃" }, - ["ữ"]={ "ư","̃" }, - ["Ự"]={ "Ư","̣" }, - ["ự"]={ "ư","̣" }, - ["Ỳ"]={ "Y","̀" }, - ["ỳ"]={ "y","̀" }, - ["Ỵ"]={ "Y","̣" }, - ["ỵ"]={ "y","̣" }, - ["Ỷ"]={ "Y","̉" }, - ["ỷ"]={ "y","̉" }, - ["Ỹ"]={ "Y","̃" }, - ["ỹ"]={ "y","̃" }, - ["ἀ"]={ "α","̓" }, - ["ἁ"]={ "α","̔" }, - ["ἂ"]={ "ἀ","̀" }, - ["ἃ"]={ "ἁ","̀" }, - ["ἄ"]={ "ἀ","́" }, - ["ἅ"]={ "ἁ","́" }, - ["ἆ"]={ "ἀ","͂" }, - ["ἇ"]={ "ἁ","͂" }, - ["Ἀ"]={ "Α","̓" }, - ["Ἁ"]={ "Α","̔" }, - ["Ἂ"]={ "Ἀ","̀" }, - ["Ἃ"]={ "Ἁ","̀" }, - ["Ἄ"]={ "Ἀ","́" }, - ["Ἅ"]={ "Ἁ","́" }, - ["Ἆ"]={ "Ἀ","͂" }, - ["Ἇ"]={ "Ἁ","͂" }, - ["ἐ"]={ "ε","̓" }, - ["ἑ"]={ "ε","̔" }, - ["ἒ"]={ "ἐ","̀" }, - ["ἓ"]={ "ἑ","̀" }, - ["ἔ"]={ "ἐ","́" }, - ["ἕ"]={ "ἑ","́" }, - ["Ἐ"]={ "Ε","̓" }, - ["Ἑ"]={ "Ε","̔" }, - ["Ἒ"]={ "Ἐ","̀" }, - ["Ἓ"]={ "Ἑ","̀" }, - ["Ἔ"]={ "Ἐ","́" }, - ["Ἕ"]={ "Ἑ","́" }, - ["ἠ"]={ "η","̓" }, - ["ἡ"]={ "η","̔" }, - ["ἢ"]={ "ἠ","̀" }, - ["ἣ"]={ "ἡ","̀" }, - ["ἤ"]={ "ἠ","́" }, - ["ἥ"]={ "ἡ","́" }, - ["ἦ"]={ "ἠ","͂" }, - ["ἧ"]={ "ἡ","͂" }, - ["Ἠ"]={ "Η","̓" }, - ["Ἡ"]={ "Η","̔" }, - ["Ἢ"]={ "Ἠ","̀" }, - ["Ἣ"]={ "Ἡ","̀" }, - ["Ἤ"]={ "Ἠ","́" }, - ["Ἥ"]={ "Ἡ","́" }, - ["Ἦ"]={ "Ἠ","͂" }, - ["Ἧ"]={ "Ἡ","͂" }, - ["ἰ"]={ "ι","̓" }, - ["ἱ"]={ "ι","̔" }, - ["ἲ"]={ "ἰ","̀" }, - ["ἳ"]={ "ἱ","̀" }, - ["ἴ"]={ "ἰ","́" }, - ["ἵ"]={ "ἱ","́" }, - ["ἶ"]={ "ἰ","͂" }, - ["ἷ"]={ "ἱ","͂" }, - ["Ἰ"]={ "Ι","̓" }, - ["Ἱ"]={ "Ι","̔" }, - ["Ἲ"]={ "Ἰ","̀" }, - ["Ἳ"]={ "Ἱ","̀" }, - ["Ἴ"]={ "Ἰ","́" }, - ["Ἵ"]={ "Ἱ","́" }, - ["Ἶ"]={ "Ἰ","͂" }, - ["Ἷ"]={ "Ἱ","͂" }, - ["ὀ"]={ "ο","̓" }, - ["ὁ"]={ "ο","̔" }, - ["ὂ"]={ "ὀ","̀" }, - ["ὃ"]={ "ὁ","̀" }, - ["ὄ"]={ "ὀ","́" }, - ["ὅ"]={ "ὁ","́" }, - ["Ὀ"]={ "Ο","̓" }, - ["Ὁ"]={ "Ο","̔" }, - ["Ὂ"]={ "Ὀ","̀" }, - ["Ὃ"]={ "Ὁ","̀" }, - ["Ὄ"]={ "Ὀ","́" }, - ["Ὅ"]={ "Ὁ","́" }, - ["ὐ"]={ "υ","̓" }, - ["ὑ"]={ "υ","̔" }, - ["ὒ"]={ "ὐ","̀" }, - ["ὓ"]={ "ὑ","̀" }, - ["ὔ"]={ "ὐ","́" }, - ["ὕ"]={ "ὑ","́" }, - ["ὖ"]={ "ὐ","͂" }, - ["ὗ"]={ "ὑ","͂" }, - ["Ὑ"]={ "Υ","̔" }, - ["Ὓ"]={ "Ὑ","̀" }, - ["Ὕ"]={ "Ὑ","́" }, - ["Ὗ"]={ "Ὑ","͂" }, - ["ὠ"]={ "ω","̓" }, - ["ὡ"]={ "ω","̔" }, - ["ὢ"]={ "ὠ","̀" }, - ["ὣ"]={ "ὡ","̀" }, - ["ὤ"]={ "ὠ","́" }, - ["ὥ"]={ "ὡ","́" }, - ["ὦ"]={ "ὠ","͂" }, - ["ὧ"]={ "ὡ","͂" }, - ["Ὠ"]={ "Ω","̓" }, - ["Ὡ"]={ "Ω","̔" }, - ["Ὢ"]={ "Ὠ","̀" }, - ["Ὣ"]={ "Ὡ","̀" }, - ["Ὤ"]={ "Ὠ","́" }, - ["Ὥ"]={ "Ὡ","́" }, - ["Ὦ"]={ "Ὠ","͂" }, - ["Ὧ"]={ "Ὡ","͂" }, - ["ὰ"]={ "α","̀" }, - ["ὲ"]={ "ε","̀" }, - ["ὴ"]={ "η","̀" }, - ["ὶ"]={ "ι","̀" }, - ["ὸ"]={ "ο","̀" }, - ["ὺ"]={ "υ","̀" }, - ["ὼ"]={ "ω","̀" }, - ["ᾀ"]={ "ἀ","ͅ" }, - ["ᾁ"]={ "ἁ","ͅ" }, - ["ᾂ"]={ "ἂ","ͅ" }, - ["ᾃ"]={ "ἃ","ͅ" }, - ["ᾄ"]={ "ἄ","ͅ" }, - ["ᾅ"]={ "ἅ","ͅ" }, - ["ᾆ"]={ "ἆ","ͅ" }, - ["ᾇ"]={ "ἇ","ͅ" }, - ["ᾈ"]={ "Ἀ","ͅ" }, - ["ᾉ"]={ "Ἁ","ͅ" }, - ["ᾊ"]={ "Ἂ","ͅ" }, - ["ᾋ"]={ "Ἃ","ͅ" }, - ["ᾌ"]={ "Ἄ","ͅ" }, - ["ᾍ"]={ "Ἅ","ͅ" }, - ["ᾎ"]={ "Ἆ","ͅ" }, - ["ᾏ"]={ "Ἇ","ͅ" }, - ["ᾐ"]={ "ἠ","ͅ" }, - ["ᾑ"]={ "ἡ","ͅ" }, - ["ᾒ"]={ "ἢ","ͅ" }, - ["ᾓ"]={ "ἣ","ͅ" }, - ["ᾔ"]={ "ἤ","ͅ" }, - ["ᾕ"]={ "ἥ","ͅ" }, - ["ᾖ"]={ "ἦ","ͅ" }, - ["ᾗ"]={ "ἧ","ͅ" }, - ["ᾘ"]={ "Ἠ","ͅ" }, - ["ᾙ"]={ "Ἡ","ͅ" }, - ["ᾚ"]={ "Ἢ","ͅ" }, - ["ᾛ"]={ "Ἣ","ͅ" }, - ["ᾜ"]={ "Ἤ","ͅ" }, - ["ᾝ"]={ "Ἥ","ͅ" }, - ["ᾞ"]={ "Ἦ","ͅ" }, - ["ᾟ"]={ "Ἧ","ͅ" }, - ["ᾠ"]={ "ὠ","ͅ" }, - ["ᾡ"]={ "ὡ","ͅ" }, - ["ᾢ"]={ "ὢ","ͅ" }, - ["ᾣ"]={ "ὣ","ͅ" }, - ["ᾤ"]={ "ὤ","ͅ" }, - ["ᾥ"]={ "ὥ","ͅ" }, - ["ᾦ"]={ "ὦ","ͅ" }, - ["ᾧ"]={ "ὧ","ͅ" }, - ["ᾨ"]={ "Ὠ","ͅ" }, - ["ᾩ"]={ "Ὡ","ͅ" }, - ["ᾪ"]={ "Ὢ","ͅ" }, - ["ᾫ"]={ "Ὣ","ͅ" }, - ["ᾬ"]={ "Ὤ","ͅ" }, - ["ᾭ"]={ "Ὥ","ͅ" }, - ["ᾮ"]={ "Ὦ","ͅ" }, - ["ᾯ"]={ "Ὧ","ͅ" }, - ["ᾰ"]={ "α","̆" }, - ["ᾱ"]={ "α","̄" }, - ["ᾲ"]={ "ὰ","ͅ" }, - ["ᾳ"]={ "α","ͅ" }, - ["ᾴ"]={ "ά","ͅ" }, - ["ᾶ"]={ "α","͂" }, - ["ᾷ"]={ "ᾶ","ͅ" }, - ["Ᾰ"]={ "Α","̆" }, - ["Ᾱ"]={ "Α","̄" }, - ["Ὰ"]={ "Α","̀" }, - ["ᾼ"]={ "Α","ͅ" }, - ["῁"]={ "¨","͂" }, - ["ῂ"]={ "ὴ","ͅ" }, - ["ῃ"]={ "η","ͅ" }, - ["ῄ"]={ "ή","ͅ" }, - ["ῆ"]={ "η","͂" }, - ["ῇ"]={ "ῆ","ͅ" }, - ["Ὲ"]={ "Ε","̀" }, - ["Ὴ"]={ "Η","̀" }, - ["ῌ"]={ "Η","ͅ" }, - ["῍"]={ "᾿","̀" }, - ["῎"]={ "᾿","́" }, - ["῏"]={ "᾿","͂" }, - ["ῐ"]={ "ι","̆" }, - ["ῑ"]={ "ι","̄" }, - ["ῒ"]={ "ϊ","̀" }, - ["ῖ"]={ "ι","͂" }, - ["ῗ"]={ "ϊ","͂" }, - ["Ῐ"]={ "Ι","̆" }, - ["Ῑ"]={ "Ι","̄" }, - ["Ὶ"]={ "Ι","̀" }, - ["῝"]={ "῾","̀" }, - ["῞"]={ "῾","́" }, - ["῟"]={ "῾","͂" }, - ["ῠ"]={ "υ","̆" }, - ["ῡ"]={ "υ","̄" }, - ["ῢ"]={ "ϋ","̀" }, - ["ῤ"]={ "ρ","̓" }, - ["ῥ"]={ "ρ","̔" }, - ["ῦ"]={ "υ","͂" }, - ["ῧ"]={ "ϋ","͂" }, - ["Ῠ"]={ "Υ","̆" }, - ["Ῡ"]={ "Υ","̄" }, - ["Ὺ"]={ "Υ","̀" }, - ["Ῥ"]={ "Ρ","̔" }, - ["῭"]={ "¨","̀" }, - ["ῲ"]={ "ὼ","ͅ" }, - ["ῳ"]={ "ω","ͅ" }, - ["ῴ"]={ "ώ","ͅ" }, - ["ῶ"]={ "ω","͂" }, - ["ῷ"]={ "ῶ","ͅ" }, - ["Ὸ"]={ "Ο","̀" }, - ["Ὼ"]={ "Ω","̀" }, - ["ῼ"]={ "Ω","ͅ" }, - ["↚"]={ "←","̸" }, - ["↛"]={ "→","̸" }, - ["↮"]={ "↔","̸" }, - ["⇍"]={ "⇐","̸" }, - ["⇎"]={ "⇔","̸" }, - ["⇏"]={ "⇒","̸" }, - ["∄"]={ "∃","̸" }, - ["∉"]={ "∈","̸" }, - ["∌"]={ "∋","̸" }, - ["∤"]={ "∣","̸" }, - ["∦"]={ "∥","̸" }, - ["≁"]={ "∼","̸" }, - ["≄"]={ "≃","̸" }, - ["≇"]={ "≅","̸" }, - ["≉"]={ "≈","̸" }, - ["≠"]={ "=","̸" }, - ["≢"]={ "≡","̸" }, - ["≭"]={ "≍","̸" }, - ["≮"]={ "<","̸" }, - ["≯"]={ ">","̸" }, - ["≰"]={ "≤","̸" }, - ["≱"]={ "≥","̸" }, - ["≴"]={ "≲","̸" }, - ["≵"]={ "≳","̸" }, - ["≸"]={ "≶","̸" }, - ["≹"]={ "≷","̸" }, - ["⊀"]={ "≺","̸" }, - ["⊁"]={ "≻","̸" }, - ["⊄"]={ "⊂","̸" }, - ["⊅"]={ "⊃","̸" }, - ["⊈"]={ "⊆","̸" }, - ["⊉"]={ "⊇","̸" }, - ["⊬"]={ "⊢","̸" }, - ["⊭"]={ "⊨","̸" }, - ["⊮"]={ "⊩","̸" }, - ["⊯"]={ "⊫","̸" }, - ["⋠"]={ "≼","̸" }, - ["⋡"]={ "≽","̸" }, - ["⋢"]={ "⊑","̸" }, - ["⋣"]={ "⊒","̸" }, - ["⋪"]={ "⊲","̸" }, - ["⋫"]={ "⊳","̸" }, - ["⋬"]={ "⊴","̸" }, - ["⋭"]={ "⊵","̸" }, - ["⫝̸"]={ "⫝","̸" }, - ["が"]={ "か","゙" }, - ["ぎ"]={ "き","゙" }, - ["ぐ"]={ "く","゙" }, - ["げ"]={ "け","゙" }, - ["ご"]={ "こ","゙" }, - ["ざ"]={ "さ","゙" }, - ["じ"]={ "し","゙" }, - ["ず"]={ "す","゙" }, - ["ぜ"]={ "せ","゙" }, - ["ぞ"]={ "そ","゙" }, - ["だ"]={ "た","゙" }, - ["ぢ"]={ "ち","゙" }, - ["づ"]={ "つ","゙" }, - ["で"]={ "て","゙" }, - ["ど"]={ "と","゙" }, - ["ば"]={ "は","゙" }, - ["ぱ"]={ "は","゚" }, - ["び"]={ "ひ","゙" }, - ["ぴ"]={ "ひ","゚" }, - ["ぶ"]={ "ふ","゙" }, - ["ぷ"]={ "ふ","゚" }, - ["べ"]={ "へ","゙" }, - ["ぺ"]={ "へ","゚" }, - ["ぼ"]={ "ほ","゙" }, - ["ぽ"]={ "ほ","゚" }, - ["ゔ"]={ "う","゙" }, - ["ゞ"]={ "ゝ","゙" }, - ["ガ"]={ "カ","゙" }, - ["ギ"]={ "キ","゙" }, - ["グ"]={ "ク","゙" }, - ["ゲ"]={ "ケ","゙" }, - ["ゴ"]={ "コ","゙" }, - ["ザ"]={ "サ","゙" }, - ["ジ"]={ "シ","゙" }, - ["ズ"]={ "ス","゙" }, - ["ゼ"]={ "セ","゙" }, - ["ゾ"]={ "ソ","゙" }, - ["ダ"]={ "タ","゙" }, - ["ヂ"]={ "チ","゙" }, - ["ヅ"]={ "ツ","゙" }, - ["デ"]={ "テ","゙" }, - ["ド"]={ "ト","゙" }, - ["バ"]={ "ハ","゙" }, - ["パ"]={ "ハ","゚" }, - ["ビ"]={ "ヒ","゙" }, - ["ピ"]={ "ヒ","゚" }, - ["ブ"]={ "フ","゙" }, - ["プ"]={ "フ","゚" }, - ["ベ"]={ "ヘ","゙" }, - ["ペ"]={ "ヘ","゚" }, - ["ボ"]={ "ホ","゙" }, - ["ポ"]={ "ホ","゚" }, - ["ヴ"]={ "ウ","゙" }, - ["ヷ"]={ "ワ","゙" }, - ["ヸ"]={ "ヰ","゙" }, - ["ヹ"]={ "ヱ","゙" }, - ["ヺ"]={ "ヲ","゙" }, - ["ヾ"]={ "ヽ","゙" }, - ["יִ"]={ "י","ִ" }, - ["ײַ"]={ "ײ","ַ" }, - ["שׁ"]={ "ש","ׁ" }, - ["שׂ"]={ "ש","ׂ" }, - ["שּׁ"]={ "שּ","ׁ" }, - ["שּׂ"]={ "שּ","ׂ" }, - ["אַ"]={ "א","ַ" }, - ["אָ"]={ "א","ָ" }, - ["אּ"]={ "א","ּ" }, - ["בּ"]={ "ב","ּ" }, - ["גּ"]={ "ג","ּ" }, - ["דּ"]={ "ד","ּ" }, - ["הּ"]={ "ה","ּ" }, - ["וּ"]={ "ו","ּ" }, - ["זּ"]={ "ז","ּ" }, - ["טּ"]={ "ט","ּ" }, - ["יּ"]={ "י","ּ" }, - ["ךּ"]={ "ך","ּ" }, - ["כּ"]={ "כ","ּ" }, - ["לּ"]={ "ל","ּ" }, - ["מּ"]={ "מ","ּ" }, - ["נּ"]={ "נ","ּ" }, - ["סּ"]={ "ס","ּ" }, - ["ףּ"]={ "ף","ּ" }, - ["פּ"]={ "פ","ּ" }, - ["צּ"]={ "צ","ּ" }, - ["קּ"]={ "ק","ּ" }, - ["רּ"]={ "ר","ּ" }, - ["שּ"]={ "ש","ּ" }, - ["תּ"]={ "ת","ּ" }, - ["וֹ"]={ "ו","ֹ" }, - ["בֿ"]={ "ב","ֿ" }, - ["כֿ"]={ "כ","ֿ" }, - ["פֿ"]={ "פ","ֿ" }, - ["𑂚"]={ "𑂙","𑂺" }, - ["𑂜"]={ "𑂛","𑂺" }, - ["𑂫"]={ "𑂥","𑂺" }, - ["𑄮"]={ "𑄱","𑄧" }, - ["𑄯"]={ "𑄲","𑄧" }, - ["𑍋"]={ "𑍇","𑌾" }, - ["𑍌"]={ "𑍇","𑍗" }, - ["𑒻"]={ "𑒹","𑒺" }, - ["𑒼"]={ "𑒹","𑒰" }, - ["𑒾"]={ "𑒹","𑒽" }, - ["𑖺"]={ "𑖸","𑖯" }, - ["𑖻"]={ "𑖹","𑖯" }, - ["𝅗𝅥"]={ "𝅗","𝅥" }, - ["𝅘𝅥"]={ "𝅘","𝅥" }, - ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, - ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, - ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, - ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, - ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, - ["𝆹𝅥"]={ "𝆹","𝅥" }, - ["𝆺𝅥"]={ "𝆺","𝅥" }, - ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, - ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, - ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, - ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + { + ["data"]={ + ["À"]={ "A","̀" }, + ["Á"]={ "A","́" }, + ["Â"]={ "A","̂" }, + ["Ã"]={ "A","̃" }, + ["Ä"]={ "A","̈" }, + ["Å"]={ "A","̊" }, + ["Ç"]={ "C","̧" }, + ["È"]={ "E","̀" }, + ["É"]={ "E","́" }, + ["Ê"]={ "E","̂" }, + ["Ë"]={ "E","̈" }, + ["Ì"]={ "I","̀" }, + ["Í"]={ "I","́" }, + ["Î"]={ "I","̂" }, + ["Ï"]={ "I","̈" }, + ["Ñ"]={ "N","̃" }, + ["Ò"]={ "O","̀" }, + ["Ó"]={ "O","́" }, + ["Ô"]={ "O","̂" }, + ["Õ"]={ "O","̃" }, + ["Ö"]={ "O","̈" }, + ["Ù"]={ "U","̀" }, + ["Ú"]={ "U","́" }, + ["Û"]={ "U","̂" }, + ["Ü"]={ "U","̈" }, + ["Ý"]={ "Y","́" }, + ["à"]={ "a","̀" }, + ["á"]={ "a","́" }, + ["â"]={ "a","̂" }, + ["ã"]={ "a","̃" }, + ["ä"]={ "a","̈" }, + ["å"]={ "a","̊" }, + ["ç"]={ "c","̧" }, + ["è"]={ "e","̀" }, + ["é"]={ "e","́" }, + ["ê"]={ "e","̂" }, + ["ë"]={ "e","̈" }, + ["ì"]={ "i","̀" }, + ["í"]={ "i","́" }, + ["î"]={ "i","̂" }, + ["ï"]={ "i","̈" }, + ["ñ"]={ "n","̃" }, + ["ò"]={ "o","̀" }, + ["ó"]={ "o","́" }, + ["ô"]={ "o","̂" }, + ["õ"]={ "o","̃" }, + ["ö"]={ "o","̈" }, + ["ù"]={ "u","̀" }, + ["ú"]={ "u","́" }, + ["û"]={ "u","̂" }, + ["ü"]={ "u","̈" }, + ["ý"]={ "y","́" }, + ["ÿ"]={ "y","̈" }, + ["Ā"]={ "A","̄" }, + ["ā"]={ "a","̄" }, + ["Ă"]={ "A","̆" }, + ["ă"]={ "a","̆" }, + ["Ą"]={ "A","̨" }, + ["ą"]={ "a","̨" }, + ["Ć"]={ "C","́" }, + ["ć"]={ "c","́" }, + ["Ĉ"]={ "C","̂" }, + ["ĉ"]={ "c","̂" }, + ["Ċ"]={ "C","̇" }, + ["ċ"]={ "c","̇" }, + ["Č"]={ "C","̌" }, + ["č"]={ "c","̌" }, + ["Ď"]={ "D","̌" }, + ["ď"]={ "d","̌" }, + ["Ē"]={ "E","̄" }, + ["ē"]={ "e","̄" }, + ["Ĕ"]={ "E","̆" }, + ["ĕ"]={ "e","̆" }, + ["Ė"]={ "E","̇" }, + ["ė"]={ "e","̇" }, + ["Ę"]={ "E","̨" }, + ["ę"]={ "e","̨" }, + ["Ě"]={ "E","̌" }, + ["ě"]={ "e","̌" }, + ["Ĝ"]={ "G","̂" }, + ["ĝ"]={ "g","̂" }, + ["Ğ"]={ "G","̆" }, + ["ğ"]={ "g","̆" }, + ["Ġ"]={ "G","̇" }, + ["ġ"]={ "g","̇" }, + ["Ģ"]={ "G","̧" }, + ["ģ"]={ "g","̧" }, + ["Ĥ"]={ "H","̂" }, + ["ĥ"]={ "h","̂" }, + ["Ĩ"]={ "I","̃" }, + ["ĩ"]={ "i","̃" }, + ["Ī"]={ "I","̄" }, + ["ī"]={ "i","̄" }, + ["Ĭ"]={ "I","̆" }, + ["ĭ"]={ "i","̆" }, + ["Į"]={ "I","̨" }, + ["į"]={ "i","̨" }, + ["İ"]={ "I","̇" }, + ["Ĵ"]={ "J","̂" }, + ["ĵ"]={ "j","̂" }, + ["Ķ"]={ "K","̧" }, + ["ķ"]={ "k","̧" }, + ["Ĺ"]={ "L","́" }, + ["ĺ"]={ "l","́" }, + ["Ļ"]={ "L","̧" }, + ["ļ"]={ "l","̧" }, + ["Ľ"]={ "L","̌" }, + ["ľ"]={ "l","̌" }, + ["Ń"]={ "N","́" }, + ["ń"]={ "n","́" }, + ["Ņ"]={ "N","̧" }, + ["ņ"]={ "n","̧" }, + ["Ň"]={ "N","̌" }, + ["ň"]={ "n","̌" }, + ["Ō"]={ "O","̄" }, + ["ō"]={ "o","̄" }, + ["Ŏ"]={ "O","̆" }, + ["ŏ"]={ "o","̆" }, + ["Ő"]={ "O","̋" }, + ["ő"]={ "o","̋" }, + ["Ŕ"]={ "R","́" }, + ["ŕ"]={ "r","́" }, + ["Ŗ"]={ "R","̧" }, + ["ŗ"]={ "r","̧" }, + ["Ř"]={ "R","̌" }, + ["ř"]={ "r","̌" }, + ["Ś"]={ "S","́" }, + ["ś"]={ "s","́" }, + ["Ŝ"]={ "S","̂" }, + ["ŝ"]={ "s","̂" }, + ["Ş"]={ "S","̧" }, + ["ş"]={ "s","̧" }, + ["Š"]={ "S","̌" }, + ["š"]={ "s","̌" }, + ["Ţ"]={ "T","̧" }, + ["ţ"]={ "t","̧" }, + ["Ť"]={ "T","̌" }, + ["ť"]={ "t","̌" }, + ["Ũ"]={ "U","̃" }, + ["ũ"]={ "u","̃" }, + ["Ū"]={ "U","̄" }, + ["ū"]={ "u","̄" }, + ["Ŭ"]={ "U","̆" }, + ["ŭ"]={ "u","̆" }, + ["Ů"]={ "U","̊" }, + ["ů"]={ "u","̊" }, + ["Ű"]={ "U","̋" }, + ["ű"]={ "u","̋" }, + ["Ų"]={ "U","̨" }, + ["ų"]={ "u","̨" }, + ["Ŵ"]={ "W","̂" }, + ["ŵ"]={ "w","̂" }, + ["Ŷ"]={ "Y","̂" }, + ["ŷ"]={ "y","̂" }, + ["Ÿ"]={ "Y","̈" }, + ["Ź"]={ "Z","́" }, + ["ź"]={ "z","́" }, + ["Ż"]={ "Z","̇" }, + ["ż"]={ "z","̇" }, + ["Ž"]={ "Z","̌" }, + ["ž"]={ "z","̌" }, + ["Ơ"]={ "O","̛" }, + ["ơ"]={ "o","̛" }, + ["Ư"]={ "U","̛" }, + ["ư"]={ "u","̛" }, + ["Ǎ"]={ "A","̌" }, + ["ǎ"]={ "a","̌" }, + ["Ǐ"]={ "I","̌" }, + ["ǐ"]={ "i","̌" }, + ["Ǒ"]={ "O","̌" }, + ["ǒ"]={ "o","̌" }, + ["Ǔ"]={ "U","̌" }, + ["ǔ"]={ "u","̌" }, + ["Ǖ"]={ "Ü","̄" }, + ["ǖ"]={ "ü","̄" }, + ["Ǘ"]={ "Ü","́" }, + ["ǘ"]={ "ü","́" }, + ["Ǚ"]={ "Ü","̌" }, + ["ǚ"]={ "ü","̌" }, + ["Ǜ"]={ "Ü","̀" }, + ["ǜ"]={ "ü","̀" }, + ["Ǟ"]={ "Ä","̄" }, + ["ǟ"]={ "ä","̄" }, + ["Ǡ"]={ "Ȧ","̄" }, + ["ǡ"]={ "ȧ","̄" }, + ["Ǣ"]={ "Æ","̄" }, + ["ǣ"]={ "æ","̄" }, + ["Ǧ"]={ "G","̌" }, + ["ǧ"]={ "g","̌" }, + ["Ǩ"]={ "K","̌" }, + ["ǩ"]={ "k","̌" }, + ["Ǫ"]={ "O","̨" }, + ["ǫ"]={ "o","̨" }, + ["Ǭ"]={ "Ǫ","̄" }, + ["ǭ"]={ "ǫ","̄" }, + ["Ǯ"]={ "Ʒ","̌" }, + ["ǯ"]={ "ʒ","̌" }, + ["ǰ"]={ "j","̌" }, + ["Ǵ"]={ "G","́" }, + ["ǵ"]={ "g","́" }, + ["Ǹ"]={ "N","̀" }, + ["ǹ"]={ "n","̀" }, + ["Ǻ"]={ "Å","́" }, + ["ǻ"]={ "å","́" }, + ["Ǽ"]={ "Æ","́" }, + ["ǽ"]={ "æ","́" }, + ["Ǿ"]={ "Ø","́" }, + ["ǿ"]={ "ø","́" }, + ["Ȁ"]={ "A","̏" }, + ["ȁ"]={ "a","̏" }, + ["Ȃ"]={ "A","̑" }, + ["ȃ"]={ "a","̑" }, + ["Ȅ"]={ "E","̏" }, + ["ȅ"]={ "e","̏" }, + ["Ȇ"]={ "E","̑" }, + ["ȇ"]={ "e","̑" }, + ["Ȉ"]={ "I","̏" }, + ["ȉ"]={ "i","̏" }, + ["Ȋ"]={ "I","̑" }, + ["ȋ"]={ "i","̑" }, + ["Ȍ"]={ "O","̏" }, + ["ȍ"]={ "o","̏" }, + ["Ȏ"]={ "O","̑" }, + ["ȏ"]={ "o","̑" }, + ["Ȑ"]={ "R","̏" }, + ["ȑ"]={ "r","̏" }, + ["Ȓ"]={ "R","̑" }, + ["ȓ"]={ "r","̑" }, + ["Ȕ"]={ "U","̏" }, + ["ȕ"]={ "u","̏" }, + ["Ȗ"]={ "U","̑" }, + ["ȗ"]={ "u","̑" }, + ["Ș"]={ "S","̦" }, + ["ș"]={ "s","̦" }, + ["Ț"]={ "T","̦" }, + ["ț"]={ "t","̦" }, + ["Ȟ"]={ "H","̌" }, + ["ȟ"]={ "h","̌" }, + ["Ȧ"]={ "A","̇" }, + ["ȧ"]={ "a","̇" }, + ["Ȩ"]={ "E","̧" }, + ["ȩ"]={ "e","̧" }, + ["Ȫ"]={ "Ö","̄" }, + ["ȫ"]={ "ö","̄" }, + ["Ȭ"]={ "Õ","̄" }, + ["ȭ"]={ "õ","̄" }, + ["Ȯ"]={ "O","̇" }, + ["ȯ"]={ "o","̇" }, + ["Ȱ"]={ "Ȯ","̄" }, + ["ȱ"]={ "ȯ","̄" }, + ["Ȳ"]={ "Y","̄" }, + ["ȳ"]={ "y","̄" }, + ["̈́"]={ "̈","́" }, + ["΅"]={ "¨","́" }, + ["Ά"]={ "Α","́" }, + ["Έ"]={ "Ε","́" }, + ["Ή"]={ "Η","́" }, + ["Ί"]={ "Ι","́" }, + ["Ό"]={ "Ο","́" }, + ["Ύ"]={ "Υ","́" }, + ["Ώ"]={ "Ω","́" }, + ["ΐ"]={ "ϊ","́" }, + ["Ϊ"]={ "Ι","̈" }, + ["Ϋ"]={ "Υ","̈" }, + ["ά"]={ "α","́" }, + ["έ"]={ "ε","́" }, + ["ή"]={ "η","́" }, + ["ί"]={ "ι","́" }, + ["ΰ"]={ "ϋ","́" }, + ["ϊ"]={ "ι","̈" }, + ["ϋ"]={ "υ","̈" }, + ["ό"]={ "ο","́" }, + ["ύ"]={ "υ","́" }, + ["ώ"]={ "ω","́" }, + ["ϓ"]={ "ϒ","́" }, + ["ϔ"]={ "ϒ","̈" }, + ["Ѐ"]={ "Е","̀" }, + ["Ё"]={ "Е","̈" }, + ["Ѓ"]={ "Г","́" }, + ["Ї"]={ "І","̈" }, + ["Ќ"]={ "К","́" }, + ["Ѝ"]={ "И","̀" }, + ["Ў"]={ "У","̆" }, + ["Й"]={ "И","̆" }, + ["й"]={ "и","̆" }, + ["ѐ"]={ "е","̀" }, + ["ё"]={ "е","̈" }, + ["ѓ"]={ "г","́" }, + ["ї"]={ "і","̈" }, + ["ќ"]={ "к","́" }, + ["ѝ"]={ "и","̀" }, + ["ў"]={ "у","̆" }, + ["Ѷ"]={ "Ѵ","̏" }, + ["ѷ"]={ "ѵ","̏" }, + ["Ӂ"]={ "Ж","̆" }, + ["ӂ"]={ "ж","̆" }, + ["Ӑ"]={ "А","̆" }, + ["ӑ"]={ "а","̆" }, + ["Ӓ"]={ "А","̈" }, + ["ӓ"]={ "а","̈" }, + ["Ӗ"]={ "Е","̆" }, + ["ӗ"]={ "е","̆" }, + ["Ӛ"]={ "Ә","̈" }, + ["ӛ"]={ "ә","̈" }, + ["Ӝ"]={ "Ж","̈" }, + ["ӝ"]={ "ж","̈" }, + ["Ӟ"]={ "З","̈" }, + ["ӟ"]={ "з","̈" }, + ["Ӣ"]={ "И","̄" }, + ["ӣ"]={ "и","̄" }, + ["Ӥ"]={ "И","̈" }, + ["ӥ"]={ "и","̈" }, + ["Ӧ"]={ "О","̈" }, + ["ӧ"]={ "о","̈" }, + ["Ӫ"]={ "Ө","̈" }, + ["ӫ"]={ "ө","̈" }, + ["Ӭ"]={ "Э","̈" }, + ["ӭ"]={ "э","̈" }, + ["Ӯ"]={ "У","̄" }, + ["ӯ"]={ "у","̄" }, + ["Ӱ"]={ "У","̈" }, + ["ӱ"]={ "у","̈" }, + ["Ӳ"]={ "У","̋" }, + ["ӳ"]={ "у","̋" }, + ["Ӵ"]={ "Ч","̈" }, + ["ӵ"]={ "ч","̈" }, + ["Ӹ"]={ "Ы","̈" }, + ["ӹ"]={ "ы","̈" }, + ["آ"]={ "ا","ٓ" }, + ["أ"]={ "ا","ٔ" }, + ["ؤ"]={ "و","ٔ" }, + ["إ"]={ "ا","ٕ" }, + ["ئ"]={ "ي","ٔ" }, + ["ۀ"]={ "ە","ٔ" }, + ["ۂ"]={ "ہ","ٔ" }, + ["ۓ"]={ "ے","ٔ" }, + ["ऩ"]={ "न","़" }, + ["ऱ"]={ "र","़" }, + ["ऴ"]={ "ळ","़" }, + ["क़"]={ "क","़" }, + ["ख़"]={ "ख","़" }, + ["ग़"]={ "ग","़" }, + ["ज़"]={ "ज","़" }, + ["ड़"]={ "ड","़" }, + ["ढ़"]={ "ढ","़" }, + ["फ़"]={ "फ","़" }, + ["य़"]={ "य","़" }, + ["ো"]={ "ে","া" }, + ["ৌ"]={ "ে","ৗ" }, + ["ড়"]={ "ড","়" }, + ["ঢ়"]={ "ঢ","়" }, + ["য়"]={ "য","়" }, + ["ਲ਼"]={ "ਲ","਼" }, + ["ਸ਼"]={ "ਸ","਼" }, + ["ਖ਼"]={ "ਖ","਼" }, + ["ਗ਼"]={ "ਗ","਼" }, + ["ਜ਼"]={ "ਜ","਼" }, + ["ਫ਼"]={ "ਫ","਼" }, + ["ୈ"]={ "େ","ୖ" }, + ["ୋ"]={ "େ","ା" }, + ["ୌ"]={ "େ","ୗ" }, + ["ଡ଼"]={ "ଡ","଼" }, + ["ଢ଼"]={ "ଢ","଼" }, + ["ஔ"]={ "ஒ","ௗ" }, + ["ொ"]={ "ெ","ா" }, + ["ோ"]={ "ே","ா" }, + ["ௌ"]={ "ெ","ௗ" }, + ["ై"]={ "ె","ౖ" }, + ["ೀ"]={ "ಿ","ೕ" }, + ["ೇ"]={ "ೆ","ೕ" }, + ["ೈ"]={ "ೆ","ೖ" }, + ["ೊ"]={ "ೆ","ೂ" }, + ["ೋ"]={ "ೊ","ೕ" }, + ["ൊ"]={ "െ","ാ" }, + ["ോ"]={ "േ","ാ" }, + ["ൌ"]={ "െ","ൗ" }, + ["ේ"]={ "ෙ","්" }, + ["ො"]={ "ෙ","ා" }, + ["ෝ"]={ "ො","්" }, + ["ෞ"]={ "ෙ","ෟ" }, + ["གྷ"]={ "ག","ྷ" }, + ["ཌྷ"]={ "ཌ","ྷ" }, + ["དྷ"]={ "ད","ྷ" }, + ["བྷ"]={ "བ","ྷ" }, + ["ཛྷ"]={ "ཛ","ྷ" }, + ["ཀྵ"]={ "ཀ","ྵ" }, + ["ཱི"]={ "ཱ","ི" }, + ["ཱུ"]={ "ཱ","ུ" }, + ["ྲྀ"]={ "ྲ","ྀ" }, + ["ླྀ"]={ "ླ","ྀ" }, + ["ཱྀ"]={ "ཱ","ྀ" }, + ["ྒྷ"]={ "ྒ","ྷ" }, + ["ྜྷ"]={ "ྜ","ྷ" }, + ["ྡྷ"]={ "ྡ","ྷ" }, + ["ྦྷ"]={ "ྦ","ྷ" }, + ["ྫྷ"]={ "ྫ","ྷ" }, + ["ྐྵ"]={ "ྐ","ྵ" }, + ["ဦ"]={ "ဥ","ီ" }, + ["ᬆ"]={ "ᬅ","ᬵ" }, + ["ᬈ"]={ "ᬇ","ᬵ" }, + ["ᬊ"]={ "ᬉ","ᬵ" }, + ["ᬌ"]={ "ᬋ","ᬵ" }, + ["ᬎ"]={ "ᬍ","ᬵ" }, + ["ᬒ"]={ "ᬑ","ᬵ" }, + ["ᬻ"]={ "ᬺ","ᬵ" }, + ["ᬽ"]={ "ᬼ","ᬵ" }, + ["ᭀ"]={ "ᬾ","ᬵ" }, + ["ᭁ"]={ "ᬿ","ᬵ" }, + ["ᭃ"]={ "ᭂ","ᬵ" }, + ["Ḁ"]={ "A","̥" }, + ["ḁ"]={ "a","̥" }, + ["Ḃ"]={ "B","̇" }, + ["ḃ"]={ "b","̇" }, + ["Ḅ"]={ "B","̣" }, + ["ḅ"]={ "b","̣" }, + ["Ḇ"]={ "B","̱" }, + ["ḇ"]={ "b","̱" }, + ["Ḉ"]={ "Ç","́" }, + ["ḉ"]={ "ç","́" }, + ["Ḋ"]={ "D","̇" }, + ["ḋ"]={ "d","̇" }, + ["Ḍ"]={ "D","̣" }, + ["ḍ"]={ "d","̣" }, + ["Ḏ"]={ "D","̱" }, + ["ḏ"]={ "d","̱" }, + ["Ḑ"]={ "D","̧" }, + ["ḑ"]={ "d","̧" }, + ["Ḓ"]={ "D","̭" }, + ["ḓ"]={ "d","̭" }, + ["Ḕ"]={ "Ē","̀" }, + ["ḕ"]={ "ē","̀" }, + ["Ḗ"]={ "Ē","́" }, + ["ḗ"]={ "ē","́" }, + ["Ḙ"]={ "E","̭" }, + ["ḙ"]={ "e","̭" }, + ["Ḛ"]={ "E","̰" }, + ["ḛ"]={ "e","̰" }, + ["Ḝ"]={ "Ȩ","̆" }, + ["ḝ"]={ "ȩ","̆" }, + ["Ḟ"]={ "F","̇" }, + ["ḟ"]={ "f","̇" }, + ["Ḡ"]={ "G","̄" }, + ["ḡ"]={ "g","̄" }, + ["Ḣ"]={ "H","̇" }, + ["ḣ"]={ "h","̇" }, + ["Ḥ"]={ "H","̣" }, + ["ḥ"]={ "h","̣" }, + ["Ḧ"]={ "H","̈" }, + ["ḧ"]={ "h","̈" }, + ["Ḩ"]={ "H","̧" }, + ["ḩ"]={ "h","̧" }, + ["Ḫ"]={ "H","̮" }, + ["ḫ"]={ "h","̮" }, + ["Ḭ"]={ "I","̰" }, + ["ḭ"]={ "i","̰" }, + ["Ḯ"]={ "Ï","́" }, + ["ḯ"]={ "ï","́" }, + ["Ḱ"]={ "K","́" }, + ["ḱ"]={ "k","́" }, + ["Ḳ"]={ "K","̣" }, + ["ḳ"]={ "k","̣" }, + ["Ḵ"]={ "K","̱" }, + ["ḵ"]={ "k","̱" }, + ["Ḷ"]={ "L","̣" }, + ["ḷ"]={ "l","̣" }, + ["Ḹ"]={ "Ḷ","̄" }, + ["ḹ"]={ "ḷ","̄" }, + ["Ḻ"]={ "L","̱" }, + ["ḻ"]={ "l","̱" }, + ["Ḽ"]={ "L","̭" }, + ["ḽ"]={ "l","̭" }, + ["Ḿ"]={ "M","́" }, + ["ḿ"]={ "m","́" }, + ["Ṁ"]={ "M","̇" }, + ["ṁ"]={ "m","̇" }, + ["Ṃ"]={ "M","̣" }, + ["ṃ"]={ "m","̣" }, + ["Ṅ"]={ "N","̇" }, + ["ṅ"]={ "n","̇" }, + ["Ṇ"]={ "N","̣" }, + ["ṇ"]={ "n","̣" }, + ["Ṉ"]={ "N","̱" }, + ["ṉ"]={ "n","̱" }, + ["Ṋ"]={ "N","̭" }, + ["ṋ"]={ "n","̭" }, + ["Ṍ"]={ "Õ","́" }, + ["ṍ"]={ "õ","́" }, + ["Ṏ"]={ "Õ","̈" }, + ["ṏ"]={ "õ","̈" }, + ["Ṑ"]={ "Ō","̀" }, + ["ṑ"]={ "ō","̀" }, + ["Ṓ"]={ "Ō","́" }, + ["ṓ"]={ "ō","́" }, + ["Ṕ"]={ "P","́" }, + ["ṕ"]={ "p","́" }, + ["Ṗ"]={ "P","̇" }, + ["ṗ"]={ "p","̇" }, + ["Ṙ"]={ "R","̇" }, + ["ṙ"]={ "r","̇" }, + ["Ṛ"]={ "R","̣" }, + ["ṛ"]={ "r","̣" }, + ["Ṝ"]={ "Ṛ","̄" }, + ["ṝ"]={ "ṛ","̄" }, + ["Ṟ"]={ "R","̱" }, + ["ṟ"]={ "r","̱" }, + ["Ṡ"]={ "S","̇" }, + ["ṡ"]={ "s","̇" }, + ["Ṣ"]={ "S","̣" }, + ["ṣ"]={ "s","̣" }, + ["Ṥ"]={ "Ś","̇" }, + ["ṥ"]={ "ś","̇" }, + ["Ṧ"]={ "Š","̇" }, + ["ṧ"]={ "š","̇" }, + ["Ṩ"]={ "Ṣ","̇" }, + ["ṩ"]={ "ṣ","̇" }, + ["Ṫ"]={ "T","̇" }, + ["ṫ"]={ "t","̇" }, + ["Ṭ"]={ "T","̣" }, + ["ṭ"]={ "t","̣" }, + ["Ṯ"]={ "T","̱" }, + ["ṯ"]={ "t","̱" }, + ["Ṱ"]={ "T","̭" }, + ["ṱ"]={ "t","̭" }, + ["Ṳ"]={ "U","̤" }, + ["ṳ"]={ "u","̤" }, + ["Ṵ"]={ "U","̰" }, + ["ṵ"]={ "u","̰" }, + ["Ṷ"]={ "U","̭" }, + ["ṷ"]={ "u","̭" }, + ["Ṹ"]={ "Ũ","́" }, + ["ṹ"]={ "ũ","́" }, + ["Ṻ"]={ "Ū","̈" }, + ["ṻ"]={ "ū","̈" }, + ["Ṽ"]={ "V","̃" }, + ["ṽ"]={ "v","̃" }, + ["Ṿ"]={ "V","̣" }, + ["ṿ"]={ "v","̣" }, + ["Ẁ"]={ "W","̀" }, + ["ẁ"]={ "w","̀" }, + ["Ẃ"]={ "W","́" }, + ["ẃ"]={ "w","́" }, + ["Ẅ"]={ "W","̈" }, + ["ẅ"]={ "w","̈" }, + ["Ẇ"]={ "W","̇" }, + ["ẇ"]={ "w","̇" }, + ["Ẉ"]={ "W","̣" }, + ["ẉ"]={ "w","̣" }, + ["Ẋ"]={ "X","̇" }, + ["ẋ"]={ "x","̇" }, + ["Ẍ"]={ "X","̈" }, + ["ẍ"]={ "x","̈" }, + ["Ẏ"]={ "Y","̇" }, + ["ẏ"]={ "y","̇" }, + ["Ẑ"]={ "Z","̂" }, + ["ẑ"]={ "z","̂" }, + ["Ẓ"]={ "Z","̣" }, + ["ẓ"]={ "z","̣" }, + ["Ẕ"]={ "Z","̱" }, + ["ẕ"]={ "z","̱" }, + ["ẖ"]={ "h","̱" }, + ["ẗ"]={ "t","̈" }, + ["ẘ"]={ "w","̊" }, + ["ẙ"]={ "y","̊" }, + ["ẛ"]={ "ſ","̇" }, + ["Ạ"]={ "A","̣" }, + ["ạ"]={ "a","̣" }, + ["Ả"]={ "A","̉" }, + ["ả"]={ "a","̉" }, + ["Ấ"]={ "Â","́" }, + ["ấ"]={ "â","́" }, + ["Ầ"]={ "Â","̀" }, + ["ầ"]={ "â","̀" }, + ["Ẩ"]={ "Â","̉" }, + ["ẩ"]={ "â","̉" }, + ["Ẫ"]={ "Â","̃" }, + ["ẫ"]={ "â","̃" }, + ["Ậ"]={ "Ạ","̂" }, + ["ậ"]={ "ạ","̂" }, + ["Ắ"]={ "Ă","́" }, + ["ắ"]={ "ă","́" }, + ["Ằ"]={ "Ă","̀" }, + ["ằ"]={ "ă","̀" }, + ["Ẳ"]={ "Ă","̉" }, + ["ẳ"]={ "ă","̉" }, + ["Ẵ"]={ "Ă","̃" }, + ["ẵ"]={ "ă","̃" }, + ["Ặ"]={ "Ạ","̆" }, + ["ặ"]={ "ạ","̆" }, + ["Ẹ"]={ "E","̣" }, + ["ẹ"]={ "e","̣" }, + ["Ẻ"]={ "E","̉" }, + ["ẻ"]={ "e","̉" }, + ["Ẽ"]={ "E","̃" }, + ["ẽ"]={ "e","̃" }, + ["Ế"]={ "Ê","́" }, + ["ế"]={ "ê","́" }, + ["Ề"]={ "Ê","̀" }, + ["ề"]={ "ê","̀" }, + ["Ể"]={ "Ê","̉" }, + ["ể"]={ "ê","̉" }, + ["Ễ"]={ "Ê","̃" }, + ["ễ"]={ "ê","̃" }, + ["Ệ"]={ "Ẹ","̂" }, + ["ệ"]={ "ẹ","̂" }, + ["Ỉ"]={ "I","̉" }, + ["ỉ"]={ "i","̉" }, + ["Ị"]={ "I","̣" }, + ["ị"]={ "i","̣" }, + ["Ọ"]={ "O","̣" }, + ["ọ"]={ "o","̣" }, + ["Ỏ"]={ "O","̉" }, + ["ỏ"]={ "o","̉" }, + ["Ố"]={ "Ô","́" }, + ["ố"]={ "ô","́" }, + ["Ồ"]={ "Ô","̀" }, + ["ồ"]={ "ô","̀" }, + ["Ổ"]={ "Ô","̉" }, + ["ổ"]={ "ô","̉" }, + ["Ỗ"]={ "Ô","̃" }, + ["ỗ"]={ "ô","̃" }, + ["Ộ"]={ "Ọ","̂" }, + ["ộ"]={ "ọ","̂" }, + ["Ớ"]={ "Ơ","́" }, + ["ớ"]={ "ơ","́" }, + ["Ờ"]={ "Ơ","̀" }, + ["ờ"]={ "ơ","̀" }, + ["Ở"]={ "Ơ","̉" }, + ["ở"]={ "ơ","̉" }, + ["Ỡ"]={ "Ơ","̃" }, + ["ỡ"]={ "ơ","̃" }, + ["Ợ"]={ "Ơ","̣" }, + ["ợ"]={ "ơ","̣" }, + ["Ụ"]={ "U","̣" }, + ["ụ"]={ "u","̣" }, + ["Ủ"]={ "U","̉" }, + ["ủ"]={ "u","̉" }, + ["Ứ"]={ "Ư","́" }, + ["ứ"]={ "ư","́" }, + ["Ừ"]={ "Ư","̀" }, + ["ừ"]={ "ư","̀" }, + ["Ử"]={ "Ư","̉" }, + ["ử"]={ "ư","̉" }, + ["Ữ"]={ "Ư","̃" }, + ["ữ"]={ "ư","̃" }, + ["Ự"]={ "Ư","̣" }, + ["ự"]={ "ư","̣" }, + ["Ỳ"]={ "Y","̀" }, + ["ỳ"]={ "y","̀" }, + ["Ỵ"]={ "Y","̣" }, + ["ỵ"]={ "y","̣" }, + ["Ỷ"]={ "Y","̉" }, + ["ỷ"]={ "y","̉" }, + ["Ỹ"]={ "Y","̃" }, + ["ỹ"]={ "y","̃" }, + ["ἀ"]={ "α","̓" }, + ["ἁ"]={ "α","̔" }, + ["ἂ"]={ "ἀ","̀" }, + ["ἃ"]={ "ἁ","̀" }, + ["ἄ"]={ "ἀ","́" }, + ["ἅ"]={ "ἁ","́" }, + ["ἆ"]={ "ἀ","͂" }, + ["ἇ"]={ "ἁ","͂" }, + ["Ἀ"]={ "Α","̓" }, + ["Ἁ"]={ "Α","̔" }, + ["Ἂ"]={ "Ἀ","̀" }, + ["Ἃ"]={ "Ἁ","̀" }, + ["Ἄ"]={ "Ἀ","́" }, + ["Ἅ"]={ "Ἁ","́" }, + ["Ἆ"]={ "Ἀ","͂" }, + ["Ἇ"]={ "Ἁ","͂" }, + ["ἐ"]={ "ε","̓" }, + ["ἑ"]={ "ε","̔" }, + ["ἒ"]={ "ἐ","̀" }, + ["ἓ"]={ "ἑ","̀" }, + ["ἔ"]={ "ἐ","́" }, + ["ἕ"]={ "ἑ","́" }, + ["Ἐ"]={ "Ε","̓" }, + ["Ἑ"]={ "Ε","̔" }, + ["Ἒ"]={ "Ἐ","̀" }, + ["Ἓ"]={ "Ἑ","̀" }, + ["Ἔ"]={ "Ἐ","́" }, + ["Ἕ"]={ "Ἑ","́" }, + ["ἠ"]={ "η","̓" }, + ["ἡ"]={ "η","̔" }, + ["ἢ"]={ "ἠ","̀" }, + ["ἣ"]={ "ἡ","̀" }, + ["ἤ"]={ "ἠ","́" }, + ["ἥ"]={ "ἡ","́" }, + ["ἦ"]={ "ἠ","͂" }, + ["ἧ"]={ "ἡ","͂" }, + ["Ἠ"]={ "Η","̓" }, + ["Ἡ"]={ "Η","̔" }, + ["Ἢ"]={ "Ἠ","̀" }, + ["Ἣ"]={ "Ἡ","̀" }, + ["Ἤ"]={ "Ἠ","́" }, + ["Ἥ"]={ "Ἡ","́" }, + ["Ἦ"]={ "Ἠ","͂" }, + ["Ἧ"]={ "Ἡ","͂" }, + ["ἰ"]={ "ι","̓" }, + ["ἱ"]={ "ι","̔" }, + ["ἲ"]={ "ἰ","̀" }, + ["ἳ"]={ "ἱ","̀" }, + ["ἴ"]={ "ἰ","́" }, + ["ἵ"]={ "ἱ","́" }, + ["ἶ"]={ "ἰ","͂" }, + ["ἷ"]={ "ἱ","͂" }, + ["Ἰ"]={ "Ι","̓" }, + ["Ἱ"]={ "Ι","̔" }, + ["Ἲ"]={ "Ἰ","̀" }, + ["Ἳ"]={ "Ἱ","̀" }, + ["Ἴ"]={ "Ἰ","́" }, + ["Ἵ"]={ "Ἱ","́" }, + ["Ἶ"]={ "Ἰ","͂" }, + ["Ἷ"]={ "Ἱ","͂" }, + ["ὀ"]={ "ο","̓" }, + ["ὁ"]={ "ο","̔" }, + ["ὂ"]={ "ὀ","̀" }, + ["ὃ"]={ "ὁ","̀" }, + ["ὄ"]={ "ὀ","́" }, + ["ὅ"]={ "ὁ","́" }, + ["Ὀ"]={ "Ο","̓" }, + ["Ὁ"]={ "Ο","̔" }, + ["Ὂ"]={ "Ὀ","̀" }, + ["Ὃ"]={ "Ὁ","̀" }, + ["Ὄ"]={ "Ὀ","́" }, + ["Ὅ"]={ "Ὁ","́" }, + ["ὐ"]={ "υ","̓" }, + ["ὑ"]={ "υ","̔" }, + ["ὒ"]={ "ὐ","̀" }, + ["ὓ"]={ "ὑ","̀" }, + ["ὔ"]={ "ὐ","́" }, + ["ὕ"]={ "ὑ","́" }, + ["ὖ"]={ "ὐ","͂" }, + ["ὗ"]={ "ὑ","͂" }, + ["Ὑ"]={ "Υ","̔" }, + ["Ὓ"]={ "Ὑ","̀" }, + ["Ὕ"]={ "Ὑ","́" }, + ["Ὗ"]={ "Ὑ","͂" }, + ["ὠ"]={ "ω","̓" }, + ["ὡ"]={ "ω","̔" }, + ["ὢ"]={ "ὠ","̀" }, + ["ὣ"]={ "ὡ","̀" }, + ["ὤ"]={ "ὠ","́" }, + ["ὥ"]={ "ὡ","́" }, + ["ὦ"]={ "ὠ","͂" }, + ["ὧ"]={ "ὡ","͂" }, + ["Ὠ"]={ "Ω","̓" }, + ["Ὡ"]={ "Ω","̔" }, + ["Ὢ"]={ "Ὠ","̀" }, + ["Ὣ"]={ "Ὡ","̀" }, + ["Ὤ"]={ "Ὠ","́" }, + ["Ὥ"]={ "Ὡ","́" }, + ["Ὦ"]={ "Ὠ","͂" }, + ["Ὧ"]={ "Ὡ","͂" }, + ["ὰ"]={ "α","̀" }, + ["ὲ"]={ "ε","̀" }, + ["ὴ"]={ "η","̀" }, + ["ὶ"]={ "ι","̀" }, + ["ὸ"]={ "ο","̀" }, + ["ὺ"]={ "υ","̀" }, + ["ὼ"]={ "ω","̀" }, + ["ᾀ"]={ "ἀ","ͅ" }, + ["ᾁ"]={ "ἁ","ͅ" }, + ["ᾂ"]={ "ἂ","ͅ" }, + ["ᾃ"]={ "ἃ","ͅ" }, + ["ᾄ"]={ "ἄ","ͅ" }, + ["ᾅ"]={ "ἅ","ͅ" }, + ["ᾆ"]={ "ἆ","ͅ" }, + ["ᾇ"]={ "ἇ","ͅ" }, + ["ᾈ"]={ "Ἀ","ͅ" }, + ["ᾉ"]={ "Ἁ","ͅ" }, + ["ᾊ"]={ "Ἂ","ͅ" }, + ["ᾋ"]={ "Ἃ","ͅ" }, + ["ᾌ"]={ "Ἄ","ͅ" }, + ["ᾍ"]={ "Ἅ","ͅ" }, + ["ᾎ"]={ "Ἆ","ͅ" }, + ["ᾏ"]={ "Ἇ","ͅ" }, + ["ᾐ"]={ "ἠ","ͅ" }, + ["ᾑ"]={ "ἡ","ͅ" }, + ["ᾒ"]={ "ἢ","ͅ" }, + ["ᾓ"]={ "ἣ","ͅ" }, + ["ᾔ"]={ "ἤ","ͅ" }, + ["ᾕ"]={ "ἥ","ͅ" }, + ["ᾖ"]={ "ἦ","ͅ" }, + ["ᾗ"]={ "ἧ","ͅ" }, + ["ᾘ"]={ "Ἠ","ͅ" }, + ["ᾙ"]={ "Ἡ","ͅ" }, + ["ᾚ"]={ "Ἢ","ͅ" }, + ["ᾛ"]={ "Ἣ","ͅ" }, + ["ᾜ"]={ "Ἤ","ͅ" }, + ["ᾝ"]={ "Ἥ","ͅ" }, + ["ᾞ"]={ "Ἦ","ͅ" }, + ["ᾟ"]={ "Ἧ","ͅ" }, + ["ᾠ"]={ "ὠ","ͅ" }, + ["ᾡ"]={ "ὡ","ͅ" }, + ["ᾢ"]={ "ὢ","ͅ" }, + ["ᾣ"]={ "ὣ","ͅ" }, + ["ᾤ"]={ "ὤ","ͅ" }, + ["ᾥ"]={ "ὥ","ͅ" }, + ["ᾦ"]={ "ὦ","ͅ" }, + ["ᾧ"]={ "ὧ","ͅ" }, + ["ᾨ"]={ "Ὠ","ͅ" }, + ["ᾩ"]={ "Ὡ","ͅ" }, + ["ᾪ"]={ "Ὢ","ͅ" }, + ["ᾫ"]={ "Ὣ","ͅ" }, + ["ᾬ"]={ "Ὤ","ͅ" }, + ["ᾭ"]={ "Ὥ","ͅ" }, + ["ᾮ"]={ "Ὦ","ͅ" }, + ["ᾯ"]={ "Ὧ","ͅ" }, + ["ᾰ"]={ "α","̆" }, + ["ᾱ"]={ "α","̄" }, + ["ᾲ"]={ "ὰ","ͅ" }, + ["ᾳ"]={ "α","ͅ" }, + ["ᾴ"]={ "ά","ͅ" }, + ["ᾶ"]={ "α","͂" }, + ["ᾷ"]={ "ᾶ","ͅ" }, + ["Ᾰ"]={ "Α","̆" }, + ["Ᾱ"]={ "Α","̄" }, + ["Ὰ"]={ "Α","̀" }, + ["ᾼ"]={ "Α","ͅ" }, + ["῁"]={ "¨","͂" }, + ["ῂ"]={ "ὴ","ͅ" }, + ["ῃ"]={ "η","ͅ" }, + ["ῄ"]={ "ή","ͅ" }, + ["ῆ"]={ "η","͂" }, + ["ῇ"]={ "ῆ","ͅ" }, + ["Ὲ"]={ "Ε","̀" }, + ["Ὴ"]={ "Η","̀" }, + ["ῌ"]={ "Η","ͅ" }, + ["῍"]={ "᾿","̀" }, + ["῎"]={ "᾿","́" }, + ["῏"]={ "᾿","͂" }, + ["ῐ"]={ "ι","̆" }, + ["ῑ"]={ "ι","̄" }, + ["ῒ"]={ "ϊ","̀" }, + ["ῖ"]={ "ι","͂" }, + ["ῗ"]={ "ϊ","͂" }, + ["Ῐ"]={ "Ι","̆" }, + ["Ῑ"]={ "Ι","̄" }, + ["Ὶ"]={ "Ι","̀" }, + ["῝"]={ "῾","̀" }, + ["῞"]={ "῾","́" }, + ["῟"]={ "῾","͂" }, + ["ῠ"]={ "υ","̆" }, + ["ῡ"]={ "υ","̄" }, + ["ῢ"]={ "ϋ","̀" }, + ["ῤ"]={ "ρ","̓" }, + ["ῥ"]={ "ρ","̔" }, + ["ῦ"]={ "υ","͂" }, + ["ῧ"]={ "ϋ","͂" }, + ["Ῠ"]={ "Υ","̆" }, + ["Ῡ"]={ "Υ","̄" }, + ["Ὺ"]={ "Υ","̀" }, + ["Ῥ"]={ "Ρ","̔" }, + ["῭"]={ "¨","̀" }, + ["ῲ"]={ "ὼ","ͅ" }, + ["ῳ"]={ "ω","ͅ" }, + ["ῴ"]={ "ώ","ͅ" }, + ["ῶ"]={ "ω","͂" }, + ["ῷ"]={ "ῶ","ͅ" }, + ["Ὸ"]={ "Ο","̀" }, + ["Ὼ"]={ "Ω","̀" }, + ["ῼ"]={ "Ω","ͅ" }, + ["↚"]={ "←","̸" }, + ["↛"]={ "→","̸" }, + ["↮"]={ "↔","̸" }, + ["⇍"]={ "⇐","̸" }, + ["⇎"]={ "⇔","̸" }, + ["⇏"]={ "⇒","̸" }, + ["∄"]={ "∃","̸" }, + ["∉"]={ "∈","̸" }, + ["∌"]={ "∋","̸" }, + ["∤"]={ "∣","̸" }, + ["∦"]={ "∥","̸" }, + ["≁"]={ "∼","̸" }, + ["≄"]={ "≃","̸" }, + ["≇"]={ "≅","̸" }, + ["≉"]={ "≈","̸" }, + ["≠"]={ "=","̸" }, + ["≢"]={ "≡","̸" }, + ["≭"]={ "≍","̸" }, + ["≮"]={ "<","̸" }, + ["≯"]={ ">","̸" }, + ["≰"]={ "≤","̸" }, + ["≱"]={ "≥","̸" }, + ["≴"]={ "≲","̸" }, + ["≵"]={ "≳","̸" }, + ["≸"]={ "≶","̸" }, + ["≹"]={ "≷","̸" }, + ["⊀"]={ "≺","̸" }, + ["⊁"]={ "≻","̸" }, + ["⊄"]={ "⊂","̸" }, + ["⊅"]={ "⊃","̸" }, + ["⊈"]={ "⊆","̸" }, + ["⊉"]={ "⊇","̸" }, + ["⊬"]={ "⊢","̸" }, + ["⊭"]={ "⊨","̸" }, + ["⊮"]={ "⊩","̸" }, + ["⊯"]={ "⊫","̸" }, + ["⋠"]={ "≼","̸" }, + ["⋡"]={ "≽","̸" }, + ["⋢"]={ "⊑","̸" }, + ["⋣"]={ "⊒","̸" }, + ["⋪"]={ "⊲","̸" }, + ["⋫"]={ "⊳","̸" }, + ["⋬"]={ "⊴","̸" }, + ["⋭"]={ "⊵","̸" }, + ["⫝̸"]={ "⫝","̸" }, + ["が"]={ "か","゙" }, + ["ぎ"]={ "き","゙" }, + ["ぐ"]={ "く","゙" }, + ["げ"]={ "け","゙" }, + ["ご"]={ "こ","゙" }, + ["ざ"]={ "さ","゙" }, + ["じ"]={ "し","゙" }, + ["ず"]={ "す","゙" }, + ["ぜ"]={ "せ","゙" }, + ["ぞ"]={ "そ","゙" }, + ["だ"]={ "た","゙" }, + ["ぢ"]={ "ち","゙" }, + ["づ"]={ "つ","゙" }, + ["で"]={ "て","゙" }, + ["ど"]={ "と","゙" }, + ["ば"]={ "は","゙" }, + ["ぱ"]={ "は","゚" }, + ["び"]={ "ひ","゙" }, + ["ぴ"]={ "ひ","゚" }, + ["ぶ"]={ "ふ","゙" }, + ["ぷ"]={ "ふ","゚" }, + ["べ"]={ "へ","゙" }, + ["ぺ"]={ "へ","゚" }, + ["ぼ"]={ "ほ","゙" }, + ["ぽ"]={ "ほ","゚" }, + ["ゔ"]={ "う","゙" }, + ["ゞ"]={ "ゝ","゙" }, + ["ガ"]={ "カ","゙" }, + ["ギ"]={ "キ","゙" }, + ["グ"]={ "ク","゙" }, + ["ゲ"]={ "ケ","゙" }, + ["ゴ"]={ "コ","゙" }, + ["ザ"]={ "サ","゙" }, + ["ジ"]={ "シ","゙" }, + ["ズ"]={ "ス","゙" }, + ["ゼ"]={ "セ","゙" }, + ["ゾ"]={ "ソ","゙" }, + ["ダ"]={ "タ","゙" }, + ["ヂ"]={ "チ","゙" }, + ["ヅ"]={ "ツ","゙" }, + ["デ"]={ "テ","゙" }, + ["ド"]={ "ト","゙" }, + ["バ"]={ "ハ","゙" }, + ["パ"]={ "ハ","゚" }, + ["ビ"]={ "ヒ","゙" }, + ["ピ"]={ "ヒ","゚" }, + ["ブ"]={ "フ","゙" }, + ["プ"]={ "フ","゚" }, + ["ベ"]={ "ヘ","゙" }, + ["ペ"]={ "ヘ","゚" }, + ["ボ"]={ "ホ","゙" }, + ["ポ"]={ "ホ","゚" }, + ["ヴ"]={ "ウ","゙" }, + ["ヷ"]={ "ワ","゙" }, + ["ヸ"]={ "ヰ","゙" }, + ["ヹ"]={ "ヱ","゙" }, + ["ヺ"]={ "ヲ","゙" }, + ["ヾ"]={ "ヽ","゙" }, + ["יִ"]={ "י","ִ" }, + ["ײַ"]={ "ײ","ַ" }, + ["שׁ"]={ "ש","ׁ" }, + ["שׂ"]={ "ש","ׂ" }, + ["שּׁ"]={ "שּ","ׁ" }, + ["שּׂ"]={ "שּ","ׂ" }, + ["אַ"]={ "א","ַ" }, + ["אָ"]={ "א","ָ" }, + ["אּ"]={ "א","ּ" }, + ["בּ"]={ "ב","ּ" }, + ["גּ"]={ "ג","ּ" }, + ["דּ"]={ "ד","ּ" }, + ["הּ"]={ "ה","ּ" }, + ["וּ"]={ "ו","ּ" }, + ["זּ"]={ "ז","ּ" }, + ["טּ"]={ "ט","ּ" }, + ["יּ"]={ "י","ּ" }, + ["ךּ"]={ "ך","ּ" }, + ["כּ"]={ "כ","ּ" }, + ["לּ"]={ "ל","ּ" }, + ["מּ"]={ "מ","ּ" }, + ["נּ"]={ "נ","ּ" }, + ["סּ"]={ "ס","ּ" }, + ["ףּ"]={ "ף","ּ" }, + ["פּ"]={ "פ","ּ" }, + ["צּ"]={ "צ","ּ" }, + ["קּ"]={ "ק","ּ" }, + ["רּ"]={ "ר","ּ" }, + ["שּ"]={ "ש","ּ" }, + ["תּ"]={ "ת","ּ" }, + ["וֹ"]={ "ו","ֹ" }, + ["בֿ"]={ "ב","ֿ" }, + ["כֿ"]={ "כ","ֿ" }, + ["פֿ"]={ "פ","ֿ" }, + ["𑂚"]={ "𑂙","𑂺" }, + ["𑂜"]={ "𑂛","𑂺" }, + ["𑂫"]={ "𑂥","𑂺" }, + ["𑄮"]={ "𑄱","𑄧" }, + ["𑄯"]={ "𑄲","𑄧" }, + ["𑍋"]={ "𑍇","𑌾" }, + ["𑍌"]={ "𑍇","𑍗" }, + ["𑒻"]={ "𑒹","𑒺" }, + ["𑒼"]={ "𑒹","𑒰" }, + ["𑒾"]={ "𑒹","𑒽" }, + ["𑖺"]={ "𑖸","𑖯" }, + ["𑖻"]={ "𑖹","𑖯" }, + ["𝅗𝅥"]={ "𝅗","𝅥" }, + ["𝅘𝅥"]={ "𝅘","𝅥" }, + ["𝅘𝅥𝅮"]={ "𝅘𝅥","𝅮" }, + ["𝅘𝅥𝅯"]={ "𝅘𝅥","𝅯" }, + ["𝅘𝅥𝅰"]={ "𝅘𝅥","𝅰" }, + ["𝅘𝅥𝅱"]={ "𝅘𝅥","𝅱" }, + ["𝅘𝅥𝅲"]={ "𝅘𝅥","𝅲" }, + ["𝆹𝅥"]={ "𝆹","𝅥" }, + ["𝆺𝅥"]={ "𝆺","𝅥" }, + ["𝆹𝅥𝅮"]={ "𝆹𝅥","𝅮" }, + ["𝆺𝅥𝅮"]={ "𝆺𝅥","𝅮" }, + ["𝆹𝅥𝅯"]={ "𝆹𝅥","𝅯" }, + ["𝆺𝅥𝅯"]={ "𝆺𝅥","𝅯" }, + }, }, }, - }, ["name"]="collapse", ["prepend"]=true, ["type"]="ligature", } + end -- closure do -- begin closure to overcome local limits and interference -if not modules then modules={} end modules ['font-gbn']={ - version=1.001, - comment="companion to luatex-*.tex", - author="Hans Hagen, PRAGMA-ADE, Hasselt NL", - copyright="PRAGMA ADE / ConTeXt Development Team", - license="see context related readme files" +if not modules then modules={} end modules ['luatex-fonts-gbn']={ + version=1.001, + comment="companion to luatex-*.tex", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" } if context then - texio.write_nl("fatal error: this module is not for context") - os.exit() +--removed + end local next=next local fonts=fonts @@ -35686,207 +37504,235 @@ local setlink=nuts.setlink local setprev=nuts.setprev local n_ligaturing=node.ligaturing local n_kerning=node.kerning -local ligaturing=nuts.ligaturing -local kerning=nuts.kerning +local d_ligaturing=nuts.ligaturing +local d_kerning=nuts.kerning local basemodepass=true -local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning=nil end -local function k_warning() texio.write_nl("warning: node.kerning called directly") k_warning=nil end +local function l_warning() logs.report("fonts","don't call 'node.ligaturing' directly") l_warning=nil end +local function k_warning() logs.report("fonts","don't call 'node.kerning' directly") k_warning=nil end function node.ligaturing(...) - if basemodepass and l_warning then - l_warning() - end - return n_ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return n_ligaturing(...) end function node.kerning(...) - if basemodepass and k_warning then - k_warning() - end - return n_kerning(...) + if basemodepass and k_warning then + k_warning() + end + return n_kerning(...) +end +function nuts.ligaturing(...) + if basemodepass and l_warning then + l_warning() + end + return d_ligaturing(...) +end +function nuts.kerning(...) + if basemodepass and k_warning then + k_warning() + end + return d_kerning(...) end function nodes.handlers.setbasemodepass(v) - basemodepass=v -end -function nodes.handlers.nodepass(head,groupcode,size,packtype,direction) - local fontdata=fonts.hashes.identifiers - if fontdata then - local nuthead=tonut(head) - local usedfonts={} - local basefonts={} - local prevfont=nil - local basefont=nil - local variants=nil - local redundant=nil - local nofused=0 - for n in traverse_id(glyph_code,nuthead) do - local font=getfont(n) - if font~=prevfont then - if basefont then - basefont[2]=getprev(n) - end - prevfont=font - local used=usedfonts[font] - if not used then - local tfmdata=fontdata[font] - if tfmdata then - local shared=tfmdata.shared - if shared then - local processors=shared.processes - if processors and #processors>0 then - usedfonts[font]=processors - nofused=nofused+1 - elseif basemodepass then - basefont={ n,nil } - basefonts[#basefonts+1]=basefont - end - end - local resources=tfmdata.resources - variants=resources and resources.variants - variants=variants and next(variants) and variants or false - end - else - local tfmdata=fontdata[prevfont] - if tfmdata then - local resources=tfmdata.resources - variants=resources and resources.variants - variants=variants and next(variants) and variants or false - end - end - end - if variants then - local char=getchar(n) - if char>=0xFE00 and (char<=0xFE0F or (char>=0xE0100 and char<=0xE01EF)) then - local hash=variants[char] - if hash then - local p=getprev(n) - if p and getid(p)==glyph_code then - local variant=hash[getchar(p)] - if variant then - setchar(p,variant) - end - end - end - if not redundant then - redundant={ n } - else - redundant[#redundant+1]=n - end - end + basemodepass=v +end +local function nodepass(head,groupcode,size,packtype,direction) + local fontdata=fonts.hashes.identifiers + if fontdata then + local usedfonts={} + local basefonts={} + local prevfont=nil + local basefont=nil + local variants=nil + local redundant=nil + local nofused=0 + for n in traverse_id(glyph_code,head) do + local font=getfont(n) + if font~=prevfont then + if basefont then + basefont[2]=getprev(n) + end + prevfont=font + local used=usedfonts[font] + if not used then + local tfmdata=fontdata[font] + if tfmdata then + local shared=tfmdata.shared + if shared then + local processors=shared.processes + if processors and #processors>0 then + usedfonts[font]=processors + nofused=nofused+1 + elseif basemodepass then + basefont={ n,nil } + basefonts[#basefonts+1]=basefont + end end + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end + else + local tfmdata=fontdata[prevfont] + if tfmdata then + local resources=tfmdata.resources + variants=resources and resources.variants + variants=variants and next(variants) and variants or false + end end - local nofbasefonts=#basefonts - if redundant then - for i=1,#redundant do - local r=redundant[i] - local p,n=getboth(r) - if r==nuthead then - nuthead=n - setprev(n) - else - setlink(p,n) - end - if nofbasefonts>0 then - for i=1,nofbasefonts do - local bi=basefonts[i] - if r==bi[1] then - bi[1]=n - end - if r==bi[2] then - bi[2]=n - end - end - end - flush_node(r) - end - end - for d in traverse_id(disc_code,nuthead) do - local _,_,r=getdisc(d) - if r then - for n in traverse_id(glyph_code,r) do - local font=getfont(n) - if font~=prevfont then - prevfont=font - local used=usedfonts[font] - if not used then - local tfmdata=fontdata[font] - if tfmdata then - local shared=tfmdata.shared - if shared then - local processors=shared.processes - if processors and #processors>0 then - usedfonts[font]=processors - nofused=nofused+1 - end - end - end - end - end - end + end + if variants then + local char=getchar(n) + if (char>=0xFE00 and char<=0xFE0F) or (char>=0xE0100 and char<=0xE01EF) then + local hash=variants[char] + if hash then + local p=getprev(n) + if p and getid(p)==glyph_code then + local variant=hash[getchar(p)] + if variant then + setchar(p,variant) + end end + end + if not redundant then + redundant={ n } + else + redundant[#redundant+1]=n + end end - if next(usedfonts) then - for font,processors in next,usedfonts do - for i=1,#processors do - head=processors[i](head,font,0,direction,nofused) or head - end + end + end + local nofbasefonts=#basefonts + if redundant then + for i=1,#redundant do + local r=redundant[i] + local p,n=getboth(r) + if r==head then + head=n + setprev(n) + else + setlink(p,n) + end + if nofbasefonts>0 then + for i=1,nofbasefonts do + local bi=basefonts[i] + if r==bi[1] then + bi[1]=n end + if r==bi[2] then + bi[2]=n + end + end end - if basemodepass and nofbasefonts>0 then - for i=1,nofbasefonts do - local range=basefonts[i] - local start=range[1] - local stop=range[2] - if start then - local front=nuthead==start - local prev,next - if stop then - next=getnext(stop) - start,stop=ligaturing(start,stop) - start,stop=kerning(start,stop) - else - prev=getprev(start) - start=ligaturing(start) - start=kerning(start) - end - if prev then - setlink(prev,start) - end - if next then - setlink(stop,next) - end - if front and nuthead~=start then - head=tonode(start) - end + flush_node(r) + end + end + for d in traverse_id(disc_code,head) do + local _,_,r=getdisc(d) + if r then + for n in traverse_id(glyph_code,r) do + local font=getfont(n) + if font~=prevfont then + prevfont=font + local used=usedfonts[font] + if not used then + local tfmdata=fontdata[font] + if tfmdata then + local shared=tfmdata.shared + if shared then + local processors=shared.processes + if processors and #processors>0 then + usedfonts[font]=processors + nofused=nofused+1 + end end + end end + end end - return head,true - else - return head,false + end + end + if next(usedfonts) then + for font,processors in next,usedfonts do + for i=1,#processors do + head=processors[i](head,font,0,direction,nofused) or head + end + end + end + if basemodepass and nofbasefonts>0 then + for i=1,nofbasefonts do + local range=basefonts[i] + local start=range[1] + local stop=range[2] + if start then + local front=head==start + local prev,next + if stop then + next=getnext(stop) + start,stop=d_ligaturing(start,stop) + start,stop=d_kerning(start,stop) + else + prev=getprev(start) + start=d_ligaturing(start) + start=d_kerning(start) + end + if prev then + setlink(prev,start) + end + if next then + setlink(stop,next) + end + if front and head~=start then + head=start + end + end + end end + end + return head end -function nodes.handlers.basepass(head) - if basemodepass then - head=n_ligaturing(head) - head=n_kerning(head) - end - return head,true +local function basepass(head) + if basemodepass then + head=d_ligaturing(head) + head=d_kerning(head) + end + return head end -local nodepass=nodes.handlers.nodepass -local basepass=nodes.handlers.basepass +local protectpass=node.direct.protect_glyphs local injectpass=nodes.injections.handler -local protectpass=nodes.handlers.protectglyphs +function nodes.handlers.nodepass(head,...) + if head then + return tonode(nodepass(tonut(head),...)) + end +end +function nodes.handlers.basepass(head) + if head then + return tonode(basepass(tonut(head))) + end +end +function nodes.handlers.injectpass(head) + if head then + return tonode(injectpass(tonut(head))) + end +end +function nodes.handlers.protectpass(head) + if head then + protectpass(tonut(head)) + return head + end +end function nodes.simple_font_handler(head,groupcode,size,packtype,direction) - if head then - head=nodepass(head,groupcode,size,packtype,direction) - head=injectpass(head) - if not basemodepass then - head=basepass(head) - end - protectpass(head) - return head,true - else - return head,false - end + if head then + head=tonut(head) + head=nodepass(head,groupcode,size,packtype,direction) + head=injectpass(head) + if not basemodepass then + head=basepass(head) + end + protectpass(head) + head=tonode(head) + end + return head end end -- closure diff --git a/tex/generic/context/luatex/luatex-fonts-mis.lua b/tex/generic/context/luatex/luatex-fonts-mis.lua index 02a5b60db..b472b86dd 100644 --- a/tex/generic/context/luatex/luatex-fonts-mis.lua +++ b/tex/generic/context/luatex/luatex-fonts-mis.lua @@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['luatex-font-mis'] = { } if context then - texio.write_nl("fatal error: this module is not for context") os.exit() end @@ -30,3 +29,7 @@ table.setmetatableindex(marks,function(t,k) return marks end end) + +function font.each() + return table.sortedhash(fonts.hashes.identifiers) +end diff --git a/tex/generic/context/luatex/luatex-fonts-syn.lua b/tex/generic/context/luatex/luatex-fonts-syn.lua index 376fd05fb..2ec075434 100644 --- a/tex/generic/context/luatex/luatex-fonts-syn.lua +++ b/tex/generic/context/luatex/luatex-fonts-syn.lua @@ -7,7 +7,6 @@ if not modules then modules = { } end modules ['luatex-fonts-syn'] = { } if context then - texio.write_nl("fatal error: this module is not for context") os.exit() end @@ -46,12 +45,12 @@ local loaded = false local fileformats = { "lua", "tex", "other text files" } function fonts.names.reportmissingbase() - texio.write("") + logs.report("fonts","missing font database, run: mtxrun --script fonts --reload --simple") fonts.names.reportmissingbase = nil end function fonts.names.reportmissingname() - texio.write("") + logs.report("fonts","unknown font in font database, run: mtxrun --script fonts --reload --simple") fonts.names.reportmissingname = nil end @@ -67,7 +66,7 @@ function fonts.names.resolve(name,sub) local foundname = resolvers.findfile(basename,format) or "" if foundname ~= "" then data = dofile(foundname) - texio.write("") + logs.report("fonts","font database '%s' loaded",foundname) break end end diff --git a/tex/generic/context/luatex/luatex-fonts.lua b/tex/generic/context/luatex/luatex-fonts.lua index 5806debd2..69908dfcc 100644 --- a/tex/generic/context/luatex/luatex-fonts.lua +++ b/tex/generic/context/luatex/luatex-fonts.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['luatex-fonts'] = { -- A merged file is generated with: -- --- mtxrun --script package --merge ./luatex-fonts.lua +-- mtxrun --script package --merge --stripcontext luatex-fonts.lua -- -- A needed resource file is made by: -- @@ -44,7 +44,7 @@ if not modules then modules = { } end modules ['luatex-fonts'] = { -- and interferences between mechanisms between macro packages. We use the rendering in context -- and luatex-plain as reference for issues. -utf = utf or unicode.utf8 +utf = utf or (unicode and unicode.utf8) or { } -- We have some (global) hooks (for latex): @@ -67,7 +67,7 @@ end if not generic_context.push_namespaces then function generic_context.push_namespaces() - texio.write(" ") + -- logs.report("system","push namespace") local normalglobal = { } for k, v in next, _G do normalglobal[k] = v @@ -77,7 +77,7 @@ if not generic_context.push_namespaces then function generic_context.pop_namespaces(normalglobal,isolate) if normalglobal then - texio.write(" ") + -- logs.report("system","pop namespace") for k, v in next, _G do if not normalglobal[k] then generic_context[k] = v @@ -92,7 +92,7 @@ if not generic_context.push_namespaces then -- just to be sure: setmetatable(generic_context,_G) else - texio.write(" ") + logs.report("system","fatal error: invalid pop of generic_context") os.exit() end end @@ -119,9 +119,26 @@ local starttime = os.gettimeofday() -- kpse.set_program_name("luatex") +-- One can define texio.reporter as alternative terminal/log writer. That's as far +-- as I want to go with this. + local ctxkpse = nil local verbose = true +if not logs or not logs.report then + if not logs then + logs = { } + end + function logs.report(c,f,...) + local r = texio.reporter or texio.write_nl + if f then + r(c .. " : " .. string.format(f,...)) + else + r("") + end + end +end + local function loadmodule(name,continue) local foundname = kpse.find_file(name,"tex") or "" if not foundname then @@ -132,12 +149,12 @@ local function loadmodule(name,continue) end if foundname == "" then if not continue then - texio.write_nl(string.format(" ",name)) + logs.report("system","unable to locate file '%s'",name) os.exit() end else if verbose then - texio.write(string.format(" <%s>",foundname)) -- no file.basename yet + logs.report("system","loading '%s'",foundname) -- no file.basename yet end dofile(foundname) end @@ -169,13 +186,16 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then else - -- The following helpers are a bit overkill but I don't want to mess up context code for the - -- sake of general generality. Around version 1.0 there will be an official api defined. + -- The following helpers are a bit overkill but I don't want to mess up + -- context code for the sake of general generality. Around version 1.0 + -- there will be an official api defined. -- - -- So, I will strip these libraries and see what is really needed so that we don't have this - -- overhead in the generic modules. The next section is only there for the packager, so stick - -- to using luatex-fonts with luatex-fonts-merged.lua and forget about the rest. The following - -- list might change without prior notice (for instance because we shuffled code around). + -- So, I will strip these libraries and see what is really needed so that + -- we don't have this overhead in the generic modules. The next section + -- is only there for the packager, so stick to using luatex-fonts with + -- luatex-fonts-merged.lua and forget about the rest. The following list + -- might change without prior notice (for instance because we shuffled + -- code around). loadmodule("l-lua.lua") loadmodule("l-lpeg.lua") @@ -186,25 +206,25 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule("l-file.lua") loadmodule("l-boolean.lua") loadmodule("l-math.lua") - loadmodule("l-unicode.lua") -- A few slightly higher level support modules: loadmodule("util-str.lua") loadmodule("util-fil.lua") - -- The following modules contain code that is either not used at all outside context or will - -- fail when enabled due to lack of other modules. + -- The following modules contain code that is either not used at all + -- outside context or will fail when enabled due to lack of other + -- modules. - -- First we load a few helper modules. This is about the miminum needed to let the font modules - -- do their work. Don't depend on their functions as we might strip them in future versions of - -- this generic variant. + -- First we load a few helper modules. This is about the miminum needed + -- to let the font modules do their work. Don't depend on their functions + -- as we might strip them in future versions of this generic variant. loadmodule('luatex-basics-gen.lua') loadmodule('data-con.lua') - -- We do need some basic node support. The code in there is not for general use as it might - -- change. + -- We do need some basic node support. The code in there is not for + -- general use as it might change. loadmodule('luatex-basics-nod.lua') @@ -212,27 +232,36 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('luatex-basics-chr.lua') - -- Now come the font modules that deal with traditional tex fonts as well as open type fonts. + -- Now come the font modules that deal with traditional tex fonts as well + -- as open type fonts. -- - -- The font database file (if used at all) must be put someplace visible for kpse and is not - -- shared with context. The mtx-fonts script can be used to generate this file (using the - -- --reload --force --simple option). + -- The font database file (if used at all) must be put someplace visible + -- for kpse and is not shared with context. The mtx-fonts script can be + -- used to generate this file (using the --reload --force --simple option). loadmodule('font-ini.lua') loadmodule('luatex-fonts-mis.lua') loadmodule('font-con.lua') - loadmodule('luatex-fonts-enc.lua') -- will load font-age on demand + loadmodule('luatex-fonts-enc.lua') loadmodule('font-cid.lua') - loadmodule('font-map.lua') -- for loading lum file (will be stripped) + loadmodule('font-map.lua') - -- We use a bit simpler database because using the context one demands loading more helper - -- code and although it is more flexible (more ways to resolve and so) it will never be - -- uses in plain/latex anyway, so let's stick to a simple approach. + -- We use a bit simpler database because using the context one demands + -- loading more helper code and although it is more flexible (more ways + -- to resolve and so) it will never be uses in plain/latex anyway, so + -- let's stick to a simple approach. loadmodule('luatex-fonts-syn.lua') - loadmodule('font-oti.lua') + -- We need some helpers. + + loadmodule('font-vfc.lua') + + -- This is the bulk of opentype code. + loadmodule('font-otr.lua') + loadmodule('font-oti.lua') + loadmodule('font-ott.lua') loadmodule('font-cff.lua') loadmodule('font-ttf.lua') loadmodule('font-dsp.lua') @@ -243,31 +272,41 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then loadmodule('font-ota.lua') loadmodule('font-ots.lua') loadmodule('font-osd.lua') - loadmodule('font-ocl.lua') -- svg needs 0.97 (for fix in memstreams) + loadmodule('font-ocl.lua') loadmodule('font-otc.lua') - -- type one code + -- The code for type one fonts. - loadmodule('font-onr.lua') -- was font-afm.lua - loadmodule('font-one.lua') -- was font-afm.lua + loadmodule('font-onr.lua') + loadmodule('font-one.lua') loadmodule('font-afk.lua') - -- traditional code + -- And for traditional TeX fonts. loadmodule('font-tfm.lua') - -- common code + -- Some common code. loadmodule('font-lua.lua') loadmodule('font-def.lua') - loadmodule('font-xtx.lua') -- xetex compatible specifiers (plain/latex only) - loadmodule('luatex-fonts-ext.lua') -- some extensions - loadmodule('luatex-fonts-lig.lua') -- and another one - -- We need to plug into a callback and the following module implements the handlers. Actual - -- plugging in happens later. + -- We support xetex compatible specifiers (plain/latex only). + + loadmodule('luatex-fonts-def.lua') -- was font-xtx.lua + + -- Here come some additional features. + + loadmodule('luatex-fonts-ext.lua') + loadmodule('font-imp-tex.lua') + loadmodule('font-imp-ligatures.lua') + loadmodule('font-imp-italics.lua') + loadmodule('font-imp-effects.lua') + loadmodule('luatex-fonts-lig.lua') + + -- We need to plug into a callback and the following module implements the + -- handlers. Actual plugging in happens later. - loadmodule('font-gbn.lua') + loadmodule('luatex-fonts-gbn.lua') end @@ -305,6 +344,6 @@ end -- We're done. -texio.write(string.format(" ", os.gettimeofday()-starttime)) +logs.report("system","luatex-fonts.lua loaded in %0.3f seconds", os.gettimeofday()-starttime) generic_context.pop_namespaces(whatever) diff --git a/tex/generic/context/luatex/luatex-languages.lua b/tex/generic/context/luatex/luatex-languages.lua index cecd60c13..825089802 100644 --- a/tex/generic/context/luatex/luatex-languages.lua +++ b/tex/generic/context/luatex/luatex-languages.lua @@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['luatex-languages'] = { license = "see context related readme files" } +if context then + os.exit() +end + -- We borrow from ConTeXt. languages = languages or { } @@ -17,19 +21,18 @@ function languages.loadpatterns(tag) loaded[tag] = 0 local filename = kpse.find_file("lang-" .. tag .. ".lua") if not filename or filename == "" then - texio.write("") + logs.report("languages","unknown language file for '%s'",tag) else local whatever = loadfile(filename) if type(whatever) == "function" then whatever = whatever() if type(whatever) == "table" then - texio.write("") + logs.report("languages","loading language file for '%s'",tag) local characters = whatever.patterns.characters or "" local patterns = whatever.patterns.data or "" local exceptions = whatever.exceptions.data or "" for b in string.utfvalues(characters) do - -- what about uppercase --- lang.sethjcode(b,b) + -- lang.sethjcode(b,b) tex.setlccode(b,b) end local language = lang.new() @@ -37,11 +40,11 @@ function languages.loadpatterns(tag) lang.hyphenation(language, exceptions) loaded[tag] = lang.id(language) else - texio.write("") + logs.report("languages","invalid language table for '%s'",tag) os.exit() end else - texio.write("") + logs.report("languages","invalid language file for '%s'",tag) os.exit() end end diff --git a/tex/generic/context/luatex/luatex-mplib.lua b/tex/generic/context/luatex/luatex-mplib.lua index c610fca57..c251d88c3 100644 --- a/tex/generic/context/luatex/luatex-mplib.lua +++ b/tex/generic/context/luatex/luatex-mplib.lua @@ -82,7 +82,11 @@ else --ldx]]-- metapost.report = metapost.report or function(...) - texio.write(format("",format(...))) + if logs.report then + logs.report("metapost",...) + else + texio.write(format("",format(...))) + end end --[[ldx-- diff --git a/tex/generic/context/luatex/luatex-pdf.tex b/tex/generic/context/luatex/luatex-pdf.tex index b698285e3..569f8664f 100644 --- a/tex/generic/context/luatex/luatex-pdf.tex +++ b/tex/generic/context/luatex/luatex-pdf.tex @@ -123,6 +123,7 @@ \xdef\pdfcompresslevel {\pdfvariable compresslevel} \xdef\pdfobjcompresslevel {\pdfvariable objcompresslevel} + %xdef\pdfrecompress {\pdfvariable recompress} \xdef\pdfdecimaldigits {\pdfvariable decimaldigits} \xdef\pdfgamma {\pdfvariable gamma} \xdef\pdfimageresolution {\pdfvariable imageresolution} @@ -134,6 +135,8 @@ \xdef\pdfinclusioncopyfonts {\pdfvariable inclusioncopyfonts} \xdef\pdfinclusionerrorlevel {\pdfvariable inclusionerrorlevel} \xdef\pdfgentounicode {\pdfvariable gentounicode} + \xdef\pdfomitcidset {\pdfvariable omitcidset} + \xdef\pdfomitcharset {\pdfvariable omitcharset} \xdef\pdfpagebox {\pdfvariable pagebox} \xdef\pdfmajorversion {\pdfvariable majorversion} \xdef\pdfminorversion {\pdfvariable minorversion} @@ -165,6 +168,7 @@ \global\pdfcompresslevel 9 \global\pdfobjcompresslevel 1 + %global\pdfrecompress 0 \global\pdfdecimaldigits 4 \global\pdfgamma 1000 \global\pdfimageresolution 72 @@ -176,6 +180,8 @@ \global\pdfinclusioncopyfonts 0 \global\pdfinclusionerrorlevel 0 \global\pdfgentounicode 0 + % \global\pdfomitcidset 0 + % \global\pdfomitcharset 0 \global\pdfpagebox 0 % \global\pdfmajorversion 1 \global\pdfminorversion 4 diff --git a/tex/generic/context/luatex/luatex-swiglib.lua b/tex/generic/context/luatex/luatex-swiglib.lua index cbb6798c3..41ac91837 100644 --- a/tex/generic/context/luatex/luatex-swiglib.lua +++ b/tex/generic/context/luatex/luatex-swiglib.lua @@ -16,7 +16,7 @@ function requireswiglib(required,version) if library then return library else - local full = string.gsub(required,"%.","/" + local full = string.gsub(required,"%.","/") local path = file.pathpart(full) local name = file.nameonly(full) .. libsuffix local list = kpse.show_path("clua") diff --git a/tex/generic/context/luatex/luatex-test.tex b/tex/generic/context/luatex/luatex-test.tex index 2aa4f22d9..ec4093d78 100644 --- a/tex/generic/context/luatex/luatex-test.tex +++ b/tex/generic/context/luatex/luatex-test.tex @@ -143,7 +143,19 @@ $\sin{x}$ \crapa Test\par \crapb Test\par - \mine Zomaar een eindje fiets! En dan weer terug. + \mine Zomaar een eindje fietsen! En dan weer terug. + +\egroup + +\bgroup + + \font\boldera=lmroman10-regular:mode=node;liga=yes;kern=yes; + \font\bolderb=lmroman10-regular:mode=node;liga=yes;kern=yes;effect=0.1; + \font\bolderc=lmroman10-regular:mode=node;liga=yes;kern=yes;effect={width=0.1,auto=yes}; + + \boldera Just a line. \par + \bolderb Just a line. \par + \bolderc Just a line. \par \egroup -- cgit v1.2.3